Index: /gs3-extensions/map-editor/DrawingManager/EXTRA/example 2.html
===================================================================
--- /gs3-extensions/map-editor/DrawingManager/EXTRA/example 2.html	(revision 32709)
+++ /gs3-extensions/map-editor/DrawingManager/EXTRA/example 2.html	(revision 32709)
@@ -0,0 +1,63 @@
+<!DOCTYPE html PUBLIC -//W3C//DTD XHTML 1.0 Transitional//EN http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&gt;
+<html>
+<head>
+<title>Get Latitude and Longitude Coordinates of a Polygon  Google Maps API v3</title>
+<script type=text/javascript src=https://maps.googleapis.com/maps/api/js?v=3.exp&sensor=false></script&gt;
+<script type=text/javascript>
+var bermudaTriangle;
+function initialize() {
+var myLatLng = new google.maps.LatLng(18.353135, 73.850097);
+var mapOptions = {
+zoom: 7,
+center: myLatLng,
+mapTypeId: google.maps.MapTypeId.RoadMap
+};
+
+var map = new google.maps.Map(document.getElementById(map-canvas),
+mapOptions);
+var triangleCoords = [
+
+new google.maps.LatLng(18.988116, 75.60791),
+new google.maps.LatLng(16.279608, 75.997925),
+new google.maps.LatLng(17.008859, 73.24585)
+
+];
+
+// Construct the polygon
+bermudaTriangle = new google.maps.Polygon({
+paths: triangleCoords,
+draggable: true,
+editable: true,
+strokeColor: #FF0000,
+strokeOpacity: 0.8,
+strokeWeight: 2,
+fillColor: #FF0000,
+fillOpacity: 0.35
+});
+
+bermudaTriangle.setMap(map);
+google.maps.event.addListener(bermudaTriangle, dragend, getPolygonCoords);
+google.maps.event.addListener(bermudaTriangle.getPath(), insert_at, getPolygonCoords);
+google.maps.event.addListener(bermudaTriangle.getPath(), remove_at, getPolygonCoords);
+google.maps.event.addListener(bermudaTriangle.getPath(), set_at, getPolygonCoords);
+}
+
+function getPolygonCoords() {
+var len = bermudaTriangle.getPath().getLength();
+var htmlStr = ;
+for (var i = 0; i < len; i++) {
+htmlStr += bermudaTriangle.getPath().getAt(i).toUrlValue(6) + <br>;
+}
+document.getElementById(info).innerHTML = htmlStr;
+}
+</script>
+</head>
+<body onload=initialize()>
+<div><h2>Please drag and resize the polygon to select desired area </h2></div>
+<div id=map-canvas style=height: 600px; width: auto;>
+</div>
+<div>Selected Polugon Co-ordinates are as below </div>
+<div id=info style=position: absolute; font-family: Arial; font-size: 14px;>
+</div>
+</body>
+</html>
Index: /gs3-extensions/map-editor/DrawingManager/EXTRA/example.html
===================================================================
--- /gs3-extensions/map-editor/DrawingManager/EXTRA/example.html	(revision 32709)
+++ /gs3-extensions/map-editor/DrawingManager/EXTRA/example.html	(revision 32709)
@@ -0,0 +1,233 @@
+<!DOCTYPE html>
+<html>
+    <head>
+        <meta name="viewport" content="initial-scale=1.0, user-scalable=no">
+        <meta charset="UTF-8">
+        <title>Drawing Tools</title>
+        <script type="text/javascript"
+        src="http://maps.google.com/maps/api/js?sensor=false&libraries=drawing"></script>
+        <style type="text/css">
+            #map, html, body {
+                padding: 0;
+                margin: 0;
+                width: 960px;
+                height: 700px;
+            }
+
+            #panel {
+                width: 200px;
+                font-family: Arial, sans-serif;
+                font-size: 13px;
+                float: right;
+                margin: 10px;
+            }
+
+            #color-palette {
+                clear: both;
+            }
+
+            .color-button {
+                width: 14px;
+                height: 14px;
+                font-size: 0;
+                margin: 2px;
+                float: left;
+                cursor: pointer;
+            }
+
+            #delete-button {
+                margin-top: 5px;
+            }
+        </style>
+        <script type="text/javascript">
+            var drawingManager;
+            var selectedShape;
+            var colors = ['#1E90FF', '#FF1493', '#32CD32', '#FF8C00', '#4B0082'];
+            var selectedColor;
+            var colorButtons = {};
+
+            function clearSelection () {
+                if (selectedShape) {
+                    if (selectedShape.type !== 'marker') {
+                        selectedShape.setEditable(false);
+                    }
+                    
+                    selectedShape = null;
+                }
+            }
+
+            function setSelection (shape) {
+                if (shape.type !== 'marker') {
+                    clearSelection();
+                    shape.setEditable(true);
+                    selectColor(shape.get('fillColor') || shape.get('strokeColor'));
+					
+                }
+				console.log(shape);
+                selectedShape = shape;
+				//else if (shape.type == 'marker'){
+				//clearSelection();
+				//}
+				
+            }
+
+            function deleteSelectedShape () {
+                if (selectedShape) {
+                    selectedShape.setMap(null);
+                }
+            }
+
+            function selectColor (color) {
+                selectedColor = color;
+                for (var i = 0; i < colors.length; ++i) {
+                    var currColor = colors[i];
+                    colorButtons[currColor].style.border = currColor == color ? '2px solid #789' : '2px solid #fff';
+                }
+
+                // Retrieves the current options from the drawing manager and replaces the
+                // stroke or fill color as appropriate.
+                var polylineOptions = drawingManager.get('polylineOptions');
+                polylineOptions.strokeColor = color;
+                drawingManager.set('polylineOptions', polylineOptions);
+
+                var rectangleOptions = drawingManager.get('rectangleOptions');
+                rectangleOptions.fillColor = color;
+                drawingManager.set('rectangleOptions', rectangleOptions);
+
+                var circleOptions = drawingManager.get('circleOptions');
+                circleOptions.fillColor = color;
+                drawingManager.set('circleOptions', circleOptions);
+
+                var polygonOptions = drawingManager.get('polygonOptions');
+                polygonOptions.fillColor = color;
+                drawingManager.set('polygonOptions', polygonOptions);
+            }
+
+            function setSelectedShapeColor (color) {
+                if (selectedShape) {
+                    if (selectedShape.type == google.maps.drawing.OverlayType.POLYLINE) {
+                        selectedShape.set('strokeColor', color);
+                    } else {
+                        selectedShape.set('fillColor', color);
+                    }
+                }
+            }
+
+            function makeColorButton (color) {
+                var button = document.createElement('span');
+                button.className = 'color-button';
+                button.style.backgroundColor = color;
+                google.maps.event.addDomListener(button, 'click', function () {
+                    selectColor(color);
+                    setSelectedShapeColor(color);
+                });
+
+                return button;
+            }
+
+            function buildColorPalette () {
+                var colorPalette = document.getElementById('color-palette');
+                for (var i = 0; i < colors.length; ++i) {
+                    var currColor = colors[i];
+                    var colorButton = makeColorButton(currColor);
+                    colorPalette.appendChild(colorButton);
+                    colorButtons[currColor] = colorButton;
+                }
+                selectColor(colors[0]);
+            }
+
+            function initialize () {
+                var map = new google.maps.Map(document.getElementById('map'), {
+                    zoom: 16,
+                    center: new google.maps.LatLng(52.25097, 20.97114),
+                    mapTypeId: google.maps.MapTypeId.SATELLITE,
+                    disableDefaultUI: true,
+                    zoomControl: true
+                });
+
+                var polyOptions = {
+                    strokeWeight: 0,
+                    fillOpacity: 0.45,
+                    editable: true,
+                    draggable: true
+                };
+                // Creates a drawing manager attached to the map that allows the user to draw
+                // markers, lines, and shapes.
+                drawingManager = new google.maps.drawing.DrawingManager({
+                    drawingMode: google.maps.drawing.OverlayType.POLYGON,
+                    markerOptions: {
+                        draggable: true
+                    },
+                    polylineOptions: {
+                        editable: true,
+                        draggable: true
+                    },
+                    rectangleOptions: polyOptions,
+                    circleOptions: polyOptions,
+                    polygonOptions: polyOptions,
+                    map: map
+                });
+
+                google.maps.event.addListener(drawingManager, 'overlaycomplete', function (e) {
+                    var newShape = e.overlay;
+                    
+                    newShape.type = e.type;
+                    
+                    if (e.type !== google.maps.drawing.OverlayType.MARKER) {
+                        // Switch back to non-drawing mode after drawing a shape.
+                        //drawingManager.setDrawingMode(null);
+
+                        // Add an event listener that selects the newly-drawn shape when the user
+                        // mouses down on it.
+                        google.maps.event.addListener(newShape, 'click', function (e) {
+                            if (e.vertex !== undefined) {
+                                if (newShape.type === google.maps.drawing.OverlayType.POLYGON) {
+                                    var path = newShape.getPaths().getAt(e.path);
+                                    path.removeAt(e.vertex);
+                                    if (path.length < 3) {
+                                        newShape.setMap(null);
+                                    }
+                                }
+                                if (newShape.type === google.maps.drawing.OverlayType.POLYLINE) {
+                                    var path = newShape.getPath();
+                                    path.removeAt(e.vertex);
+                                    if (path.length < 2) {
+                                        newShape.setMap(null);
+                                    }
+                                }
+                            }
+                            setSelection(newShape);
+                        });
+                        setSelection(newShape);
+                    }
+                    else {
+                        google.maps.event.addListener(newShape, 'click', function (e) {
+                            setSelection(newShape);
+                        });
+                        setSelection(newShape);
+                    }
+                });
+
+                // Clear the current selection when the drawing mode is changed, or when the
+                // map is clicked.
+                google.maps.event.addListener(drawingManager, 'drawingmode_changed', clearSelection);
+                google.maps.event.addListener(map, 'click', clearSelection);
+                google.maps.event.addDomListener(document.getElementById('delete-button'), 'click', deleteSelectedShape);
+
+                buildColorPalette();
+            }
+            google.maps.event.addDomListener(window, 'load', initialize);
+        </script>
+		<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyBzunGwIF2OwsfrOkIC_8bhh0OPGZXo52Y&libraries=drawing&callback=initMap"
+         async defer></script>
+    </head>
+    <body>
+        <div id="panel">
+            <div id="color-palette"></div>
+            <div>
+                <button id="delete-button">Delete Selected Shape</button>
+            </div>
+        </div>
+        <div id="map"></div>
+    </body>
+</html> 
Index: /gs3-extensions/map-editor/DrawingManager/EXTRA/shortcuts.js
===================================================================
--- /gs3-extensions/map-editor/DrawingManager/EXTRA/shortcuts.js	(revision 32709)
+++ /gs3-extensions/map-editor/DrawingManager/EXTRA/shortcuts.js	(revision 32709)
@@ -0,0 +1,223 @@
+/**
+ * http://www.openjs.com/scripts/events/keyboard_shortcuts/
+ * Version : 2.01.B
+ * By Binny V A
+ * License : BSD
+ */
+shortcut = {
+	'all_shortcuts':{},//All the shortcuts are stored in this array
+	'add': function(shortcut_combination,callback,opt) {
+		//Provide a set of default options
+		var default_options = {
+			'type':'keydown',
+			'propagate':false,
+			'disable_in_input':false,
+			'target':document,
+			'keycode':false
+		}
+		if(!opt) opt = default_options;
+		else {
+			for(var dfo in default_options) {
+				if(typeof opt[dfo] == 'undefined') opt[dfo] = default_options[dfo];
+			}
+		}
+
+		var ele = opt.target;
+		if(typeof opt.target == 'string') ele = document.getElementById(opt.target);
+		var ths = this;
+		shortcut_combination = shortcut_combination.toLowerCase();
+
+		//The function to be called at keypress
+		var func = function(e) {
+			e = e || window.event;
+			
+			if(opt['disable_in_input']) { //Don't enable shortcut keys in Input, Textarea fields
+				var element;
+				if(e.target) element=e.target;
+				else if(e.srcElement) element=e.srcElement;
+				if(element.nodeType==3) element=element.parentNode;
+
+				if(element.tagName == 'INPUT' || element.tagName == 'TEXTAREA') return;
+			}
+	
+			//Find Which key is pressed
+			if (e.keyCode) code = e.keyCode;
+			else if (e.which) code = e.which;
+			var character = String.fromCharCode(code).toLowerCase();
+			
+			if(code == 188) character=","; //If the user presses , when the type is onkeydown
+			if(code == 190) character="."; //If the user presses , when the type is onkeydown
+
+			var keys = shortcut_combination.split("+");
+			//Key Pressed - counts the number of valid keypresses - if it is same as the number of keys, the shortcut function is invoked
+			var kp = 0;
+			
+			//Work around for stupid Shift key bug created by using lowercase - as a result the shift+num combination was broken
+			var shift_nums = {
+				"`":"~",
+				"1":"!",
+				"2":"@",
+				"3":"#",
+				"4":"$",
+				"5":"%",
+				"6":"^",
+				"7":"&",
+				"8":"*",
+				"9":"(",
+				"0":")",
+				"-":"_",
+				"=":"+",
+				";":":",
+				"'":"\"",
+				",":"<",
+				".":">",
+				"/":"?",
+				"\\":"|"
+			}
+			//Special Keys - and their codes
+			var special_keys = {
+				'esc':27,
+				'escape':27,
+				'tab':9,
+				'space':32,
+				'return':13,
+				'enter':13,
+				'backspace':8,
+	
+				'scrolllock':145,
+				'scroll_lock':145,
+				'scroll':145,
+				'capslock':20,
+				'caps_lock':20,
+				'caps':20,
+				'numlock':144,
+				'num_lock':144,
+				'num':144,
+				
+				'pause':19,
+				'break':19,
+				
+				'insert':45,
+				'home':36,
+				'delete':46,
+				'end':35,
+				
+				'pageup':33,
+				'page_up':33,
+				'pu':33,
+	
+				'pagedown':34,
+				'page_down':34,
+				'pd':34,
+	
+				'left':37,
+				'up':38,
+				'right':39,
+				'down':40,
+	
+				'f1':112,
+				'f2':113,
+				'f3':114,
+				'f4':115,
+				'f5':116,
+				'f6':117,
+				'f7':118,
+				'f8':119,
+				'f9':120,
+				'f10':121,
+				'f11':122,
+				'f12':123
+			}
+	
+			var modifiers = { 
+				shift: { wanted:false, pressed:false},
+				ctrl : { wanted:false, pressed:false},
+				alt  : { wanted:false, pressed:false},
+				meta : { wanted:false, pressed:false}	//Meta is Mac specific
+			};
+                        
+			if(e.ctrlKey)	modifiers.ctrl.pressed = true;
+			if(e.shiftKey)	modifiers.shift.pressed = true;
+			if(e.altKey)	modifiers.alt.pressed = true;
+			if(e.metaKey)   modifiers.meta.pressed = true;
+                        
+			for(var i=0; k=keys[i],i<keys.length; i++) {
+				//Modifiers
+				if(k == 'ctrl' || k == 'control') {
+					kp++;
+					modifiers.ctrl.wanted = true;
+
+				} else if(k == 'shift') {
+					kp++;
+					modifiers.shift.wanted = true;
+
+				} else if(k == 'alt') {
+					kp++;
+					modifiers.alt.wanted = true;
+				} else if(k == 'meta') {
+					kp++;
+					modifiers.meta.wanted = true;
+				} else if(k.length > 1) { //If it is a special key
+					if(special_keys[k] == code) kp++;
+					
+				} else if(opt['keycode']) {
+					if(opt['keycode'] == code) kp++;
+
+				} else { //The special keys did not match
+					if(character == k) kp++;
+					else {
+						if(shift_nums[character] && e.shiftKey) { //Stupid Shift key bug created by using lowercase
+							character = shift_nums[character]; 
+							if(character == k) kp++;
+						}
+					}
+				}
+			}
+			
+			if(kp == keys.length && 
+						modifiers.ctrl.pressed == modifiers.ctrl.wanted &&
+						modifiers.shift.pressed == modifiers.shift.wanted &&
+						modifiers.alt.pressed == modifiers.alt.wanted &&
+						modifiers.meta.pressed == modifiers.meta.wanted) {
+				callback(e);
+	
+				if(!opt['propagate']) { //Stop the event
+					//e.cancelBubble is supported by IE - this will kill the bubbling process.
+					e.cancelBubble = true;
+					e.returnValue = false;
+	
+					//e.stopPropagation works in Firefox.
+					if (e.stopPropagation) {
+						e.stopPropagation();
+						e.preventDefault();
+					}
+					return false;
+				}
+			}
+		}
+		this.all_shortcuts[shortcut_combination] = {
+			'callback':func, 
+			'target':ele, 
+			'event': opt['type']
+		};
+		//Attach the function with the event
+		if(ele.addEventListener) ele.addEventListener(opt['type'], func, false);
+		else if(ele.attachEvent) ele.attachEvent('on'+opt['type'], func);
+		else ele['on'+opt['type']] = func;
+	},
+
+	//Remove the shortcut - just specify the shortcut and I will remove the binding
+	'remove':function(shortcut_combination) {
+		shortcut_combination = shortcut_combination.toLowerCase();
+		var binding = this.all_shortcuts[shortcut_combination];
+		delete(this.all_shortcuts[shortcut_combination])
+		if(!binding) return;
+		var type = binding['event'];
+		var ele = binding['target'];
+		var callback = binding['callback'];
+
+		if(ele.detachEvent) ele.detachEvent('on'+type, callback);
+		else if(ele.removeEventListener) ele.removeEventListener(type, callback, false);
+		else ele['on'+type] = false;
+	}
+}
Index: /gs3-extensions/map-editor/DrawingManager/checkpoints-singlefile/index backup v1.html
===================================================================
--- /gs3-extensions/map-editor/DrawingManager/checkpoints-singlefile/index backup v1.html	(revision 32709)
+++ /gs3-extensions/map-editor/DrawingManager/checkpoints-singlefile/index backup v1.html	(revision 32709)
@@ -0,0 +1,154 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <title>Drawing Tools</title>
+    <meta name="viewport" content="initial-scale=1.0, user-scalable=no">
+    <meta charset="utf-8">
+    <style>
+      /* Always set the map height explicitly to define the size of the div
+       * element that contains the map. */
+      #map {
+        height: 100%;
+      }
+      /* Optional: Makes the sample page fill the window. */
+      html, body {
+        height: 100%;
+		width: 100%;
+        margin: 0;
+        padding: 0;
+      }
+	  #buttons{
+	  float: center;
+	  padding-left: 10px;
+	  padding-top: 5px;
+	  }
+    </style>
+  </head>
+  <body>
+	<div id = "buttons">
+	<button onclick="removeLine()" accesskey="z">Delete Last</button>
+	<button onclick="deleteAllShape()" accesskey="c">Clear</button>
+	<p>Line thickness: <input type="range" min="1" max="5" value="1" class="slider" id="thicknessRange"> </p>
+	</div>
+	
+    <div id="map"></div>
+	
+    <script>
+
+	  
+		var overlays = [];
+		var drawingManager;
+		var sliderValue;
+		var slider = document.getElementById("thicknessRange");
+		var selectedShape;
+		
+		
+		slider.oninput = function() {
+		sliderValue = slider.value;
+		//console.log(slider.value);
+		console.log(sliderValue);
+		}
+		
+		//var polygonOptions = drawingManager.get('polygonOptions');
+		//polygonOptions.fillColor = '#CA4A2F';
+		//drawingManager.set('polygonOptions', polygonOptions);
+		
+      function initMap() {
+	  
+        var map = new google.maps.Map(document.getElementById('map'), {
+          center: {lat: -34.397, lng: 150.644},
+          zoom: 8
+        });
+		
+		var polyOptions = {
+		  fillColor: '#CA4A2F',
+		  strokeWeight: 1,
+		  fillOpacity: 0.4,
+		  editable: true,
+		  draggable: true,
+		  geodesic : true
+		  };
+	
+          drawingManager = new google.maps.drawing.DrawingManager({
+          drawingMode: google.maps.drawing.OverlayType.MARKER,
+          drawingControl: true,
+          drawingControlOptions: {
+            position: google.maps.ControlPosition.TOP_CENTER,
+            drawingModes: ['marker', 'circle', 'polygon', 'polyline', 'rectangle']
+          },
+          markerOptions: { draggable: true},
+          circleOptions: {
+            fillColor: '#CA4A2F',
+            fillOpacity: 0.4,
+            strokeWeight: sliderValue,
+            clickable: false,
+            editable: true,
+			draggable: true,
+            zIndex: 1
+          },
+	
+		  polylineOptions : polyOptions,
+		  polygonOptions: polyOptions,
+		  rectangleOptions: polyOptions,
+		  
+    
+          });
+ 
+        drawingManager.setMap(map);
+		
+		
+		//overlays.push(event.overlay); // store reference to added overlay
+		google.maps.event.addListener(drawingManager, 'overlaycomplete', function(event) {
+			overlays.push(event.overlay); // store reference to added overlay
+		
+		
+			var newShape = event.overlay;
+			newShape.type = event.type;
+			google.maps.event.addListener(newShape, 'click', function() {
+				setSelection(newShape);
+			});
+		});
+		
+            function clearSelection () {
+                if (selectedShape) {
+                    if (selectedShape.type !== 'marker') {
+                        selectedShape.setEditable(false);
+                    }
+                    
+                    selectedShape = null;
+                }
+            }
+
+            function setSelection (shape) {
+                if (shape.type !== 'marker') {
+                    clearSelection();
+                    shape.setEditable(true);
+                    //selectColor(shape.get('fillColor') || shape.get('strokeColor'));
+                }
+                
+                selectedShape = shape;
+            }
+
+      }
+	  
+	  
+	  
+	  
+	  	function removeLine() {
+		var lastOverlay = overlays.pop();
+		if (lastOverlay) lastOverlay.setMap(null);
+		console.log("DONE");
+		}
+		
+		function deleteAllShape() {
+		for (var i=0; i < overlays.length; i++)
+		{
+			overlays[i].setMap(null);
+		}
+		overlays = [];
+		}
+    </script>
+    <script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyBzunGwIF2OwsfrOkIC_8bhh0OPGZXo52Y&libraries=drawing&callback=initMap"
+         async defer></script>
+  </body>
+</html>
Index: /gs3-extensions/map-editor/DrawingManager/checkpoints-singlefile/index backup v10.html
===================================================================
--- /gs3-extensions/map-editor/DrawingManager/checkpoints-singlefile/index backup v10.html	(revision 32709)
+++ /gs3-extensions/map-editor/DrawingManager/checkpoints-singlefile/index backup v10.html	(revision 32709)
@@ -0,0 +1,585 @@
+<!DOCTYPE html>
+<html>
+  <head>
+	<title>Drawing Tools</title>
+	<meta name="viewport" content="initial-scale=1.0, user-scalable=no">
+	<meta charset="utf-8">
+	<style>
+	  /* Always set the map height explicitly to define the size of the div
+	   * element that contains the map. */
+	  #map {
+		height: 83%;
+		width: 90;
+		float: bottom;
+		clear: both;
+	  }
+	  /* Optional: Makes the sample page fill the window. */
+	  html, body {
+		height: 100%;
+		width: 99%;
+		margin: 0;
+		padding: 0;
+
+	  }
+	  
+	  #DeleteButtons{
+	  display: inline-block;
+	  float: left;
+	  padding-left: 10px;
+	  padding-top: 5px;
+	  width: 100%
+
+	  }
+	  
+	  #LineThickness{
+	  display: inline-block;
+	  float: left;
+	  padding-left: 10px;
+	  padding-top: 5px;
+
+	  }
+	  
+	  #ColourOpacity{
+	  display: inline-block;
+	  float: left;
+	  padding-left: 10px;
+	  padding-top: 5px;
+
+	  }
+	  
+	  #buttons3{
+	  display: inline-block;
+	  float: left;
+	  padding-left: 10px;
+	  padding-top: 5px;
+
+	  }	  
+	  
+      #FillColour {
+	  display: inline-block;
+	  float: left;
+	  padding-left: 10px;
+	  padding-top: 5px;
+	  }
+	  
+      #color-palette1 {
+      clear: both;
+      }
+	  
+      .color-buttons1 {
+      width: 14px;
+      height: 14px;
+      font-size: 0;
+      margin: 2px;
+      float: left;
+      cursor: pointer;
+      }
+
+
+	</style>
+  </head>
+  <body>
+	<div id = "DeleteButtons">
+	<button onclick="removeLine()" accesskey="z">Delete Last</button>
+	<button onclick="deleteAllShape()" accesskey="c">Clear All</button>
+	<button onclick="deleteSelectedShape()" accesskey="b">Delete Selected</button>
+	<button onclick="polygonGetPath()" accesskey="n">Get Path</button>
+	<button onclick="undoMovement()" accesskey="n">Undo</button>
+	
+	</div>
+	
+	<div id = "LineThickness">
+	<p>Line thickness: <input type="range" min="20" max="100" value="1" class="slider" id="thicknessRange"> </p>
+	<p>Value: <span id="thicknessRangeVal"></span></p>
+	</div>	
+	
+	<div id = "ColourOpacity">
+	<p>Colour opacity: <input type="range" min="10" max="100" value="40" class="slider" id="colourOpacity"> </p>
+	<p>Value: <span id="opacityRangeVal"></span></p>
+	</div>
+	
+
+
+	<div id="FillColour">
+     <p> Fill Colour:</p> <div id="color-palette1"></div> 
+	</div>
+
+	
+	
+	<div id="map"></div>
+	
+	<script>
+		var shiftKeyPressed = false;
+		var mousedDownFired = false;
+		var prevVertex = {lat:"" ,lng:""};
+		var nextVertex = {lat:"" ,lng:""};
+		var prevShape = [];
+		var nextShape = [];
+		var prevLog = [];
+		var	nextLog = [];
+		var dragged = 0;
+		var colors = ['#1E90FF', '#FF1493', '#4B0082', '#32CD32', '#FF8C00', '#000000'];
+		var selectedColor;
+		var colorButtons = {};
+	    var thicknessValue = 1;
+		var opacityValue = 0.4;
+		var polyOptions = {
+			fillColor: '#CA4A2F',
+			strokeWeight: thicknessValue,
+			fillOpacity: opacityValue,
+			editable: true,
+			draggable: true,
+			geodesic : false,
+		  };
+		  
+		 
+		var overlays = [];
+		var drawingManager;
+		var selectedShape;
+		var selectedShapes = []; 
+		
+		
+
+		//Update thickness 
+		var thicknessSlider = document.getElementById("thicknessRange");
+		var thicknessSliderOutput = document.getElementById("thicknessRangeVal");
+		thicknessSliderOutput.innerHTML = thicknessSlider.value/20;
+		
+		thicknessSlider.oninput = function() {
+			thicknessSliderOutput.innerHTML = this.value/20;
+			thicknessValue = this.value/20;
+			polyOptions.strokeWeight = thicknessValue;
+			setSelectedThickness(thicknessValue);
+		}
+		
+		//Update opacity
+		var opacitySlider = document.getElementById("colourOpacity");
+		var opacitySliderOutput = document.getElementById("opacityRangeVal");	
+		opacitySliderOutput.innerHTML =  "% " + Math.round(opacitySlider.value);
+		
+		opacitySlider.oninput = function() {
+			opacityValue = this.value/100;
+			polyOptions.fillOpacity = opacityValue;
+			opacitySliderOutput = opacityValue;
+			opacityRangeVal.innerHTML = "% " + Math.round( opacitySliderOutput * 100);
+			setSelectedOpacity(opacityValue);
+		}
+
+	
+		////////////////////////////////////////////////////////////////////////////////////////
+        function makeColorButton (color) {
+            var button = document.createElement('span');
+            button.className = 'color-buttons1';
+            button.style.backgroundColor = color;
+            google.maps.event.addDomListener(button, 'click', function () {
+				selectColor(color);
+				setSelectedShapeColor(color);
+            });
+            return button;
+        }
+        function buildColorPalette () {
+			var colorPalette = document.getElementById('color-palette1');
+            for (var i = 0; i < colors.length; ++i) {
+                var currColor = colors[i];
+                var colorButton = makeColorButton(currColor);
+                colorPalette.appendChild(colorButton);
+                colorButtons[currColor] = colorButton;
+            }
+            selectColor(colors[0]);
+        };		
+		function selectColor (color) {
+                selectedColor = color;
+                for (var i = 0; i < colors.length; ++i) {
+                    var currColor = colors[i];
+                    colorButtons[currColor].style.border = currColor == color ? '2px solid #789' : '2px solid #fff';
+                }
+
+                // Retrieves the current options from the drawing manager and replaces the
+                // stroke or fill color as appropriate.
+                var polylineOptions = drawingManager.get('polylineOptions');
+                polylineOptions.strokeColor = color;
+                drawingManager.set('polylineOptions', polylineOptions);
+
+                var rectangleOptions = drawingManager.get('rectangleOptions');
+                rectangleOptions.fillColor = color;
+                drawingManager.set('rectangleOptions', rectangleOptions);
+
+                var circleOptions = drawingManager.get('circleOptions');
+                circleOptions.fillColor = color;
+                drawingManager.set('circleOptions', circleOptions);
+
+                var polygonOptions = drawingManager.get('polygonOptions');
+                polygonOptions.fillColor = color;
+                drawingManager.set('polygonOptions', polygonOptions);
+            }
+		
+		
+		
+		
+	  function initMap() {
+		
+		var map = new google.maps.Map(document.getElementById('map'), {
+		  center: {lat: -34.397, lng: 150.644},
+		  zoom: 3
+		});
+		
+	
+		drawingManager = new google.maps.drawing.DrawingManager({
+			drawingMode: google.maps.drawing.OverlayType.POLYGON,
+			drawingControl: true,
+			drawingControlOptions: {
+				position: google.maps.ControlPosition.TOP_CENTER,
+				drawingModes: ['marker', 'circle', 'polygon', 'polyline', 'rectangle']
+			},
+			markerOptions: { draggable: true},
+			circleOptions: polyOptions,
+			polylineOptions : polyOptions,
+			polygonOptions: polyOptions,
+			rectangleOptions: polyOptions,
+		  });
+	
+		drawingManager.setMap(map);
+		
+		
+		//overlays.push(event.overlay); // store reference to added overlay
+		google.maps.event.addListener(drawingManager, 'overlaycomplete', function (e) {
+			overlays.push(e.overlay); // store reference to added overlay
+			var newShape = e.overlay;	
+			newShape.type = e.type;
+						
+			if (e.type !== google.maps.drawing.OverlayType.MARKER) {
+			
+				// Switch back to non-drawing mode after drawing a shape.
+				//drawingManager.setDrawingMode(null);
+				
+				// Add an event listener that selects the newly-drawn shape when the user
+				// mouses down on it.
+				google.maps.event.addListener(newShape, 'click', function(e) {
+
+					vertexAndPolyDel(e,newShape);
+					mousedDownFired = false;
+					return;
+				
+				});
+				
+				google.maps.event.addListener(newShape, 'dragstart', function() {
+				console.log("Drag Start");
+					if (selectedShape){
+						var lati, lngi;
+						for(var i = 0; i < selectedShape.getPath().length; i++) {
+							lati = selectedShape.getPath().getAt(i).lat();
+							lngi = selectedShape.getPath().getAt(i).lng();
+							console.log("Vertex number",i, "'s latitude is", lati, "and longitude is", lngi);
+							prevVertex = {lat: lati, lng:lngi};
+							prevShape.push(prevVertex);							
+						}
+
+						prevLog.push(prevShape);
+						console.log(prevLog);
+						prevShape = [];
+					}
+				});				
+				
+				google.maps.event.addListener(newShape, 'dragend', function() {
+				console.log("Drag End");				
+					if (selectedShape){
+						var lati, lngi;
+						
+						for(var i = 0; i < selectedShape.getPath().length; i++) {
+							lati = selectedShape.getPath().getAt(i).lat();
+							lngi = selectedShape.getPath().getAt(i).lng();
+							console.log("Vertex number",i, "'s latitude is", lati, "and longitude is", lngi);
+							nextVertex = {lat: lati, lng:lngi};
+							nextShape.push(nextVertex);	
+						}
+						nextLog.push(nextShape);
+						console.log(nextLog);
+						nextShape = [];
+					}
+				});	
+
+				
+				//Add an event listener to select a shape if the mouse hovers over it
+				google.maps.event.addListener(newShape, 'mousedown', function(e) {
+						if(drawingManager.drawingMode == null) {
+							mousedDownFired =true;
+//							console.log("MOUSDOWN ", e);
+							
+							setSelection(newShape);							
+						}						
+					});	
+				setSelection(newShape);
+			}
+			else {
+				//cLICK EVENT IF A MARKER IS CREATED
+				google.maps.event.addListener(newShape, 'click', function (e) {
+					setSelection(newShape);
+				});
+				setSelection(newShape);
+			}
+		});
+		
+		//Deletes a vertex if clicked on it
+		function vertexAndPolyDel(e,newShape) {
+			var vertex = e.vertex;
+			if (e.vertex !== undefined) {
+				if (newShape.type === google.maps.drawing.OverlayType.POLYGON) {
+					var path = newShape.getPaths().getAt(e.path);
+					path.removeAt(e.vertex);
+					if (path.length < 3) {
+						newShape.setMap(null);
+					}
+				}
+				if (newShape.type === google.maps.drawing.OverlayType.POLYLINE) {
+					var path = newShape.getPath();
+					path.removeAt(e.vertex);						
+					if (path.length < 2) {
+						newShape.setMap(null);
+					}
+				}
+			}
+			
+			//if(mousedDownFired == false)
+			//{
+			//setSelection(newShape, vertex);
+			//mousedDownFired = false;
+			//return;
+			//}
+			}
+				
+		function clearSelection () {
+			if (selectedShape) {
+				if (selectedShape.type !== 'marker') {
+					selectedShape.setEditable(false);
+					if(shiftKeyPressed == false){
+						for (var i=0; i < selectedShapes.length; i++) {
+						selectedShapes[i].setEditable(false);
+					}
+					selectedShapes = [];
+					}
+				}
+					
+					selectedShape = null;
+			}
+		}
+		var i = 0;
+		function setSelection (shape, e) {
+//			console.log(e.getBounds);
+
+//			console.log(selectedShapes.length);
+			if (shape.type !== 'marker') {
+				if(shiftKeyPressed == false) {
+					if(e == undefined) {
+						clearSelection();	
+						shape.setEditable(true);						
+					}
+
+				}
+
+				//var shapeAlreadySelected = selectedShapes.includes(shape);
+				
+				if (selectedShapes.includes(shape)){
+					shape.setEditable(false);
+					selectedShapes.splice(shape, 1)
+				}
+				
+				else {
+					shape.setEditable(true);
+					selectedShapes.push(shape);	
+				}
+
+
+				//console.log(selectedShapes.length);
+				
+				//Send the values to be updated
+				var thi = shape.strokeWeight;
+				var opa = shape.fillOpacity;
+				var fCol = shape.fillColor;
+				var sCol = shape.strokeColor;
+				updateMenuValues(thi, opa, fCol, sCol);
+
+			}
+			else if (shape.type == 'marker') {
+				clearSelection();
+			}
+				
+			selectedShape = shape;
+		}
+		
+
+		//Clears selection if clicked on the map when shift is not presseed
+		google.maps.event.addListener(map, 'click', function() {
+			if (shiftKeyPressed == false) {
+				clearSelection();
+			}
+		});	
+		
+
+		
+		
+		//Setting drawing tool option
+		document.addEventListener('keydown', function() {
+		//if (event.code == 'KeyX' && (event.ctrlKey || event.metaKey))
+				if (event.code == 'Digit0' || event.code == 'Numpad0' || event.code == 'Backquote') {
+					//clearSelection();
+					drawingManager.setDrawingMode(null);
+				} else if (event.code == 'Digit1') {
+					drawingManager.setDrawingMode('marker');
+				} else if (event.code == 'Digit2') {
+					drawingManager.setDrawingMode('circle');
+				} else if (event.code == 'Digit3') {
+					drawingManager.setDrawingMode('polygon');
+				} else if (event.code == 'Digit4') {
+					drawingManager.setDrawingMode('polyline');
+				} else if (event.code == 'Digit5' ) {
+					drawingManager.setDrawingMode('rectangle');
+				} 
+//					console.log(event.code);
+				});
+		
+		//Sets shift as pressed
+		document.addEventListener('keydown', function() {		
+			if (event.code == 'ShiftLeft' || event.code == 'ShiftRight')
+			{
+				shiftKeyPressed = true;
+
+			}
+
+		});
+		
+		//Sets shift as unpressed		
+		document.addEventListener('keyup', function() {		
+			if (event.code == 'ShiftLeft' || event.code == 'ShiftRight')
+			{
+				shiftKeyPressed = false;
+			}
+
+		});
+		
+		
+		buildColorPalette();
+}
+		//Set selected thickness
+		function setSelectedThickness(sWeight) {
+			if (selectedShape){
+				selectedShape.set('strokeWeight', sWeight)
+			}
+			if(selectedShapes !== 0) {
+				for (var i=0; i < selectedShapes.length; i++) {
+					selectedShapes[i].set('strokeWeight', sWeight);
+				}
+			}
+		}
+		
+		//Set selected opacity
+		function setSelectedOpacity(fOpacity) {
+			if (selectedShape) {
+				selectedShape.set('fillOpacity', fOpacity)
+			}
+			if(selectedShapes !== 0) {
+				for (var i=0; i < selectedShapes.length; i++) {
+					selectedShapes[i].set('fillOpacity', fOpacity);
+				}
+			}			
+		}
+		
+
+		
+		//set selected fill colour
+        function setSelectedShapeColor (color) {
+            if (selectedShape) {
+                if (selectedShape.type == google.maps.drawing.OverlayType.POLYLINE) {
+                    selectedShape.set('strokeColor', color);
+                } else {
+                    selectedShape.set('fillColor', color);
+					selectedShape.set('strokeColor', color);
+                }
+             }
+			if(selectedShapes !== 0) {
+				for (var i=0; i < selectedShapes.length; i++) {
+					selectedShapes[i].set('fillColor', color);
+					selectedShapes[i].set('strokeColor', color);
+				}
+			}			 
+        }
+
+		
+		function updateMenuValues(thi, opa, fCol, sCol){
+		
+		//Update thickness slider and value on the settings menu
+		var thicknessSliderOutput = document.getElementById("thicknessRangeVal");
+		thicknessSliderOutput.innerHTML = thi;
+		document.getElementById("thicknessRange").value = thi*20;
+		
+		//Update the opacity slider and value on the settings menu
+		var opacitySliderOutput = document.getElementById("opacityRangeVal");
+		opacitySliderOutput.innerHTML =  "% " + opa*100;
+		document.getElementById("colourOpacity").value =  opa*100;
+		
+
+			if (drawingManager.drawingMode == null) {
+				selectColor(fCol);
+			}
+		}
+function undoMovement() {
+	if (selectedShape){
+		console.log(prevLog.length);
+		if (prevLog.length !== undefined){
+		
+			if(prevLog[(prevLog.length-1)].length !== undefined){
+	
+	
+			console.log(prevLog[(prevLog.length-1)].length)
+			var arrayLen = prevLog[(prevLog.length-1)].length;
+				for(var i = 0; i < arrayLen; i++){
+				
+					selectedShape.setPath(prevLog[i]);
+					console.log(prevLog[i]);
+					
+				}
+				prevLog.pop();
+			}
+		}
+	}
+}
+		
+function polygonGetPath() {
+	if (selectedShape){
+	var lati, lngi;
+	
+	
+	for(var i = 0; i < selectedShape.getPath().length; i++) {
+		lati = selectedShape.getPath().getAt(i).lat();
+		lngi = selectedShape.getPath().getAt(i).lng();
+		console.log("Vertex number",i, "'s latitude is", lati, "and longitude is", lngi);
+		
+		}
+	}
+
+}		
+	  
+function deleteSelectedShape () {
+	for (var i=0; i < selectedShapes.length; i++){
+		selectedShapes[i].setMap(null);
+	}
+	selectedShapes = [];
+}
+			
+function removeLine() {
+	var lastOverlay = overlays.pop();
+	if (lastOverlay) lastOverlay.setMap(null);
+	}
+		
+function deleteAllShape() {
+	for (var i=0; i < overlays.length; i++) {
+		overlays[i].setMap(null);
+		
+	}
+	overlays = [];
+}
+
+	</script>
+	<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyBzunGwIF2OwsfrOkIC_8bhh0OPGZXo52Y&libraries=drawing&callback=initMap" async defer></script>
+	<script src="shortcuts.js"></script>
+  </body>
+</html>
Index: /gs3-extensions/map-editor/DrawingManager/checkpoints-singlefile/index backup v11.html
===================================================================
--- /gs3-extensions/map-editor/DrawingManager/checkpoints-singlefile/index backup v11.html	(revision 32709)
+++ /gs3-extensions/map-editor/DrawingManager/checkpoints-singlefile/index backup v11.html	(revision 32709)
@@ -0,0 +1,619 @@
+<!DOCTYPE html>
+<html>
+  <head>
+	<title>Drawing Tools</title>
+	<meta name="viewport" content="initial-scale=1.0, user-scalable=no">
+	<meta charset="utf-8">
+	<style>
+	  /* Always set the map height explicitly to define the size of the div
+	   * element that contains the map. */
+	  #map {
+		height: 83%;
+		width: 90;
+		float: bottom;
+		clear: both;
+	  }
+	  /* Optional: Makes the sample page fill the window. */
+	  html, body {
+		height: 100%;
+		width: 99%;
+		margin: 0;
+		padding: 0;
+
+	  }
+	  
+	  #DeleteButtons{
+	  display: inline-block;
+	  float: left;
+	  padding-left: 10px;
+	  padding-top: 5px;
+	  width: 100%
+
+	  }
+	  
+	  #LineThickness{
+	  display: inline-block;
+	  float: left;
+	  padding-left: 10px;
+	  padding-top: 5px;
+
+	  }
+	  
+	  #ColourOpacity{
+	  display: inline-block;
+	  float: left;
+	  padding-left: 10px;
+	  padding-top: 5px;
+
+	  }
+	  
+	  #buttons3{
+	  display: inline-block;
+	  float: left;
+	  padding-left: 10px;
+	  padding-top: 5px;
+
+	  }	  
+	  
+      #FillColour {
+	  display: inline-block;
+	  float: left;
+	  padding-left: 10px;
+	  padding-top: 5px;
+	  }
+	  
+      #color-palette1 {
+      clear: both;
+      }
+	  
+      .color-buttons1 {
+      width: 14px;
+      height: 14px;
+      font-size: 0;
+      margin: 2px;
+      float: left;
+      cursor: pointer;
+      }
+
+
+	</style>
+  </head>
+  <body>
+	<div id = "DeleteButtons">
+	<button onclick="removeLine()" accesskey="z">Delete Last</button>
+	<button onclick="deleteAllShape()" accesskey="c">Clear All</button>
+	<button onclick="deleteSelectedShape()" accesskey="b">Delete Selected</button>
+	<button onclick="polygonGetPath()" accesskey="n">Get Path</button>
+	<button onclick="undoMovement()" accesskey="n">Undo</button>
+	<button onclick="redoMovement()" accesskey="n">Redo</button>
+	
+	</div>
+	
+	<div id = "LineThickness">
+	<p>Line thickness: <input type="range" min="20" max="100" value="1" class="slider" id="thicknessRange"> </p>
+	<p>Value: <span id="thicknessRangeVal"></span></p>
+	</div>	
+	
+	<div id = "ColourOpacity">
+	<p>Colour opacity: <input type="range" min="10" max="100" value="40" class="slider" id="colourOpacity"> </p>
+	<p>Value: <span id="opacityRangeVal"></span></p>
+	</div>
+	
+
+
+	<div id="FillColour">
+     <p> Fill Colour:</p> <div id="color-palette1"></div> 
+	</div>
+
+	
+	
+	<div id="map"></div>
+	
+	<script>
+		var redoPressed = false;
+		var undoPressed = false;
+		var shiftKeyPressed = false;
+		var mousedDownFired = false;
+		var prevVertex = {lat:"" ,lng:""};
+		var nextVertex = {lat:"" ,lng:""};
+		var prevShape = [];
+		var nextShape = [];
+		var prevLog = [];
+		var	nextLog = [];
+		var dragged = 0;
+		var colors = ['#1E90FF', '#FF1493', '#4B0082', '#32CD32', '#FF8C00', '#000000'];
+		var selectedColor;
+		var colorButtons = {};
+	    var thicknessValue = 1;
+		var opacityValue = 0.4;
+		var polyOptions = {
+			fillColor: '#CA4A2F',
+			strokeWeight: thicknessValue,
+			fillOpacity: opacityValue,
+			editable: true,
+			draggable: true,
+			geodesic : false,
+		  };
+		  
+		 
+		var overlays = [];
+		var drawingManager;
+		var selectedShape;
+		var selectedShapes = []; 
+		
+		
+
+		//Update thickness 
+		var thicknessSlider = document.getElementById("thicknessRange");
+		var thicknessSliderOutput = document.getElementById("thicknessRangeVal");
+		thicknessSliderOutput.innerHTML = thicknessSlider.value/20;
+		
+		thicknessSlider.oninput = function() {
+			thicknessSliderOutput.innerHTML = this.value/20;
+			thicknessValue = this.value/20;
+			polyOptions.strokeWeight = thicknessValue;
+			setSelectedThickness(thicknessValue);
+		}
+		
+		//Update opacity
+		var opacitySlider = document.getElementById("colourOpacity");
+		var opacitySliderOutput = document.getElementById("opacityRangeVal");	
+		opacitySliderOutput.innerHTML =  "% " + Math.round(opacitySlider.value);
+		
+		opacitySlider.oninput = function() {
+			opacityValue = this.value/100;
+			polyOptions.fillOpacity = opacityValue;
+			opacitySliderOutput = opacityValue;
+			opacityRangeVal.innerHTML = "% " + Math.round( opacitySliderOutput * 100);
+			setSelectedOpacity(opacityValue);
+		}
+
+	
+		////////////////////////////////////////////////////////////////////////////////////////
+        function makeColorButton (color) {
+            var button = document.createElement('span');
+            button.className = 'color-buttons1';
+            button.style.backgroundColor = color;
+            google.maps.event.addDomListener(button, 'click', function () {
+				selectColor(color);
+				setSelectedShapeColor(color);
+            });
+            return button;
+        }
+        function buildColorPalette () {
+			var colorPalette = document.getElementById('color-palette1');
+            for (var i = 0; i < colors.length; ++i) {
+                var currColor = colors[i];
+                var colorButton = makeColorButton(currColor);
+                colorPalette.appendChild(colorButton);
+                colorButtons[currColor] = colorButton;
+            }
+            selectColor(colors[0]);
+        };		
+		function selectColor (color) {
+                selectedColor = color;
+                for (var i = 0; i < colors.length; ++i) {
+                    var currColor = colors[i];
+                    colorButtons[currColor].style.border = currColor == color ? '2px solid #789' : '2px solid #fff';
+                }
+
+                // Retrieves the current options from the drawing manager and replaces the
+                // stroke or fill color as appropriate.
+                var polylineOptions = drawingManager.get('polylineOptions');
+                polylineOptions.strokeColor = color;
+                drawingManager.set('polylineOptions', polylineOptions);
+
+                var rectangleOptions = drawingManager.get('rectangleOptions');
+                rectangleOptions.fillColor = color;
+                drawingManager.set('rectangleOptions', rectangleOptions);
+
+                var circleOptions = drawingManager.get('circleOptions');
+                circleOptions.fillColor = color;
+                drawingManager.set('circleOptions', circleOptions);
+
+                var polygonOptions = drawingManager.get('polygonOptions');
+                polygonOptions.fillColor = color;
+                drawingManager.set('polygonOptions', polygonOptions);
+            }
+		
+		
+		
+		
+	  function initMap() {
+		
+		var map = new google.maps.Map(document.getElementById('map'), {
+		  center: {lat: -34.397, lng: 150.644},
+		  zoom: 2, 
+		  mapTypeId: 'satellite'
+		  
+		});
+		
+	
+		drawingManager = new google.maps.drawing.DrawingManager({
+			drawingMode: google.maps.drawing.OverlayType.POLYGON,
+			drawingControl: true,
+			drawingControlOptions: {
+				position: google.maps.ControlPosition.TOP_CENTER,
+				drawingModes: ['marker', 'circle', 'polygon', 'polyline', 'rectangle']
+			},
+			markerOptions: { draggable: true},
+			circleOptions: polyOptions,
+			polylineOptions : polyOptions,
+			polygonOptions: polyOptions,
+			rectangleOptions: polyOptions,
+		  });
+	
+		drawingManager.setMap(map);
+		
+		
+		//overlays.push(event.overlay); // store reference to added overlay
+		google.maps.event.addListener(drawingManager, 'overlaycomplete', function (e) {
+			overlays.push(e.overlay); // store reference to added overlay
+			var newShape = e.overlay;	
+			newShape.type = e.type;
+						
+			if (e.type !== google.maps.drawing.OverlayType.MARKER) {
+			
+				// Switch back to non-drawing mode after drawing a shape.
+				//drawingManager.setDrawingMode(null);
+				
+				// Add an event listener that selects the newly-drawn shape when the user
+				// mouses down on it.
+				google.maps.event.addListener(newShape, 'click', function(e) {
+
+					vertexAndPolyDel(e,newShape);
+					mousedDownFired = false;
+					return;
+				
+				});
+				
+				//Stores past event information
+				google.maps.event.addListener(newShape, 'dragstart', function() {
+				//console.log("Drag Start");
+					if (selectedShape){
+						var lati, lngi;
+						for(var i = 0; i < selectedShape.getPath().length; i++) {
+							lati = selectedShape.getPath().getAt(i).lat();
+							lngi = selectedShape.getPath().getAt(i).lng();
+							//console.log("Vertex number",i, "'s latitude is", lati, "and longitude is", lngi);
+							prevVertex = {lat: lati, lng:lngi};
+							prevShape.push(prevVertex);							
+						}
+
+						prevLog.push(prevShape);
+						prevShape = [];
+						nextLog = [];
+						//console.log("Prev Array Length",prevLog.length);
+						//console.log("Next Array Length",nextLog.length);
+					}
+				});				
+				
+				//Store information after the event ends
+				google.maps.event.addListener(newShape, 'dragend', function() {
+				//console.log("Drag End");				
+					if (selectedShape){
+						var lati, lngi;
+						
+						for(var i = 0; i < selectedShape.getPath().length; i++) {
+							lati = selectedShape.getPath().getAt(i).lat();
+							lngi = selectedShape.getPath().getAt(i).lng();
+							//console.log("Vertex number",i, "'s latitude is", lati, "and longitude is", lngi);
+							nextVertex = {lat: lati, lng:lngi};
+							nextShape.push(nextVertex);	
+						}
+						nextLog.push(nextShape);
+						nextShape = [];
+						//console.log("Prev Array Length",prevLog.length);
+						//console.log("Next Array Length",nextLog.length);
+					}
+				});	
+
+				
+				//Add an event listener to select a shape if the mouse hovers over it
+				google.maps.event.addListener(newShape, 'mousedown', function(e) {
+						if(drawingManager.drawingMode == null) {
+							mousedDownFired =true;
+//							console.log("MOUSDOWN ", e);
+							
+							setSelection(newShape);							
+						}						
+					});	
+				setSelection(newShape);
+			}
+			else {
+				//cLICK EVENT IF A MARKER IS CREATED
+				google.maps.event.addListener(newShape, 'click', function (e) {
+					setSelection(newShape);
+				});
+				setSelection(newShape);
+			}
+		});
+		
+		//Deletes a vertex if clicked on it
+		function vertexAndPolyDel(e,newShape) {
+			var vertex = e.vertex;
+			if (e.vertex !== undefined) {
+				if (newShape.type === google.maps.drawing.OverlayType.POLYGON) {
+					var path = newShape.getPaths().getAt(e.path);
+					path.removeAt(e.vertex);
+					if (path.length < 3) {
+						newShape.setMap(null);
+					}
+				}
+				if (newShape.type === google.maps.drawing.OverlayType.POLYLINE) {
+					var path = newShape.getPath();
+					path.removeAt(e.vertex);						
+					if (path.length < 2) {
+						newShape.setMap(null);
+					}
+				}
+			}
+			
+			//if(mousedDownFired == false)
+			//{
+			//setSelection(newShape, vertex);
+			//mousedDownFired = false;
+			//return;
+			//}
+			}
+				
+		function clearSelection () {
+			if (selectedShape) {
+				if (selectedShape.type !== 'marker') {
+					selectedShape.setEditable(false);
+					if(shiftKeyPressed == false){
+						for (var i=0; i < selectedShapes.length; i++) {
+						selectedShapes[i].setEditable(false);
+					}
+					selectedShapes = [];
+					}
+				}
+					
+					selectedShape = null;
+			}
+		}
+		var i = 0;
+		function setSelection (shape, e) {
+//			console.log(e.getBounds);
+
+//			console.log(selectedShapes.length);
+			if (shape.type !== 'marker') {
+				if(shiftKeyPressed == false) {
+					if(e == undefined) {
+						clearSelection();	
+						shape.setEditable(true);						
+					}
+
+				}
+
+				//var shapeAlreadySelected = selectedShapes.includes(shape);
+				
+				if (selectedShapes.includes(shape)){
+					shape.setEditable(false);
+					selectedShapes.splice(shape, 1)
+				}
+				
+				else {
+					shape.setEditable(true);
+					selectedShapes.push(shape);	
+				}
+
+
+				//console.log(selectedShapes.length);
+				
+				//Send the values to be updated
+				var thi = shape.strokeWeight;
+				var opa = shape.fillOpacity;
+				var fCol = shape.fillColor;
+				var sCol = shape.strokeColor;
+				updateMenuValues(thi, opa, fCol, sCol);
+
+			}
+			else if (shape.type == 'marker') {
+				clearSelection();
+			}
+				
+			selectedShape = shape;
+		}
+		
+
+		//Clears selection if clicked on the map when shift is not presseed
+		google.maps.event.addListener(map, 'click', function() {
+			if (shiftKeyPressed == false) {
+				clearSelection();
+			}
+		});	
+		
+
+		
+		
+		//Setting drawing tool option
+		document.addEventListener('keydown', function() {
+		//if (event.code == 'KeyX' && (event.ctrlKey || event.metaKey))
+				if (event.code == 'Digit0' || event.code == 'Numpad0' || event.code == 'Backquote') {
+					//clearSelection();
+					drawingManager.setDrawingMode(null);
+				} else if (event.code == 'Digit1') {
+					drawingManager.setDrawingMode('marker');
+				} else if (event.code == 'Digit2') {
+					drawingManager.setDrawingMode('circle');
+				} else if (event.code == 'Digit3') {
+					drawingManager.setDrawingMode('polygon');
+				} else if (event.code == 'Digit4') {
+					drawingManager.setDrawingMode('polyline');
+				} else if (event.code == 'Digit5' ) {
+					drawingManager.setDrawingMode('rectangle');
+				} 
+//					console.log(event.code);
+				});
+		
+		//Sets shift as pressed
+		document.addEventListener('keydown', function() {		
+			if (event.code == 'ShiftLeft' || event.code == 'ShiftRight')
+			{
+				shiftKeyPressed = true;
+
+			}
+
+		});
+		
+		//Sets shift as unpressed		
+		document.addEventListener('keyup', function() {		
+			if (event.code == 'ShiftLeft' || event.code == 'ShiftRight')
+			{
+				shiftKeyPressed = false;
+			}
+
+		});
+		
+		
+		buildColorPalette();
+}
+		//Set selected thickness
+		function setSelectedThickness(sWeight) {
+			if (selectedShape){
+				selectedShape.set('strokeWeight', sWeight)
+			}
+			if(selectedShapes !== 0) {
+				for (var i=0; i < selectedShapes.length; i++) {
+					selectedShapes[i].set('strokeWeight', sWeight);
+				}
+			}
+		}
+		
+		//Set selected opacity
+		function setSelectedOpacity(fOpacity) {
+			if (selectedShape) {
+				selectedShape.set('fillOpacity', fOpacity)
+			}
+			if(selectedShapes !== 0) {
+				for (var i=0; i < selectedShapes.length; i++) {
+					selectedShapes[i].set('fillOpacity', fOpacity);
+				}
+			}			
+		}
+		
+
+		
+		//set selected fill colour
+        function setSelectedShapeColor (color) {
+            if (selectedShape) {
+                if (selectedShape.type == google.maps.drawing.OverlayType.POLYLINE) {
+                    selectedShape.set('strokeColor', color);
+                } else {
+                    selectedShape.set('fillColor', color);
+					selectedShape.set('strokeColor', color);
+                }
+             }
+			if(selectedShapes !== 0) {
+				for (var i=0; i < selectedShapes.length; i++) {
+					selectedShapes[i].set('fillColor', color);
+					selectedShapes[i].set('strokeColor', color);
+				}
+			}			 
+        }
+
+		
+		function updateMenuValues(thi, opa, fCol, sCol){
+		
+		//Update thickness slider and value on the settings menu
+		var thicknessSliderOutput = document.getElementById("thicknessRangeVal");
+		thicknessSliderOutput.innerHTML = thi;
+		document.getElementById("thicknessRange").value = thi*20;
+		
+		//Update the opacity slider and value on the settings menu
+		var opacitySliderOutput = document.getElementById("opacityRangeVal");
+		opacitySliderOutput.innerHTML =  "% " + opa*100;
+		document.getElementById("colourOpacity").value =  opa*100;
+		
+
+			if (drawingManager.drawingMode == null) {
+				selectColor(fCol);
+			}
+		}
+function undoMovement() {
+	if (selectedShape){
+		if (prevLog.length !== 0){
+		nextLog.push(prevLog[prevLog.length-1]);
+		
+		if (redoPressed == false){
+			selectedShape.setPath(prevLog[prevLog.length-1]);
+			undoPressed = false;
+		}
+		if (redoPressed){
+			selectedShape.setPath(prevLog[prevLog.length-2]);
+		}
+
+		
+		prevLog.pop();
+		undoPressed = true;
+		
+		//console.log("Undo Array Length",prevLog.length);
+		//console.log(JSON.stringify(prevLog));	
+		//console.log(JSON.stringify(nextLog));	
+		}
+	}
+}
+		
+function redoMovement() {
+	if (selectedShape){
+		if (nextLog.length !== 0){
+		prevLog.push(nextLog[nextLog.length-1]);
+		
+		if (undoPressed == false){
+			selectedShape.setPath(nextLog[nextLog.length-1]);	
+			undoPressed = false;
+		}
+		if (undoPressed) {
+			selectedShape.setPath(nextLog[nextLog.length-2]);	
+		}
+		nextLog.pop();
+		redoPressed = true;
+		
+		//console.log("Redo Array Length",nextLog.length);
+		//console.log(JSON.stringify(prevLog));				
+		//console.log(JSON.stringify(nextLog));		
+		}
+	}	
+}		
+		
+function polygonGetPath() {
+	if (selectedShape){
+	var lati, lngi;
+	
+	
+	for(var i = 0; i < selectedShape.getPath().length; i++) {
+		lati = selectedShape.getPath().getAt(i).lat();
+		lngi = selectedShape.getPath().getAt(i).lng();
+		console.log("Vertex number",i, "'s latitude is", lati, "and longitude is", lngi);
+		
+		}
+	}
+
+}		
+	  
+function deleteSelectedShape () {
+	for (var i=0; i < selectedShapes.length; i++){
+		selectedShapes[i].setMap(null);
+	}
+	selectedShapes = [];
+}
+			
+function removeLine() {
+	var lastOverlay = overlays.pop();
+	if (lastOverlay) lastOverlay.setMap(null);
+	}
+		
+function deleteAllShape() {
+	for (var i=0; i < overlays.length; i++) {
+		overlays[i].setMap(null);
+		
+	}
+	overlays = [];
+}
+
+	</script>
+	<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyBzunGwIF2OwsfrOkIC_8bhh0OPGZXo52Y&libraries=drawing&callback=initMap" async defer></script>
+	<script src="shortcuts.js"></script>
+  </body>
+</html>
Index: /gs3-extensions/map-editor/DrawingManager/checkpoints-singlefile/index backup v12.html
===================================================================
--- /gs3-extensions/map-editor/DrawingManager/checkpoints-singlefile/index backup v12.html	(revision 32709)
+++ /gs3-extensions/map-editor/DrawingManager/checkpoints-singlefile/index backup v12.html	(revision 32709)
@@ -0,0 +1,626 @@
+<!DOCTYPE html>
+<html>
+  <head>
+	<title>Drawing Tools</title>
+	<meta name="viewport" content="initial-scale=1.0, user-scalable=no">
+	<meta charset="utf-8">
+	<style>
+	  /* Always set the map height explicitly to define the size of the div
+	   * element that contains the map. */
+	  #map {
+		height: 83%;
+		width: 90;
+		float: bottom;
+		clear: both;
+	  }
+	  /* Optional: Makes the sample page fill the window. */
+	  html, body {
+		height: 100%;
+		width: 99%;
+		margin: 0;
+		padding: 0;
+
+	  }
+	  
+	  #DeleteButtons{
+	  display: inline-block;
+	  float: left;
+	  padding-left: 10px;
+	  padding-top: 5px;
+	  width: 100%
+
+	  }
+	  
+	  #LineThickness{
+	  display: inline-block;
+	  float: left;
+	  padding-left: 10px;
+	  padding-top: 5px;
+
+	  }
+	  
+	  #ColourOpacity{
+	  display: inline-block;
+	  float: left;
+	  padding-left: 10px;
+	  padding-top: 5px;
+
+	  }
+	  
+	  #buttons3{
+	  display: inline-block;
+	  float: left;
+	  padding-left: 10px;
+	  padding-top: 5px;
+
+	  }	  
+	  
+      #FillColour {
+	  display: inline-block;
+	  float: left;
+	  padding-left: 10px;
+	  padding-top: 5px;
+	  }
+	  
+      #color-palette1 {
+      clear: both;
+      }
+	  
+      .color-buttons1 {
+      width: 14px;
+      height: 14px;
+      font-size: 0;
+      margin: 2px;
+      float: left;
+      cursor: pointer;
+      }
+
+
+	</style>
+  </head>
+  <body>
+	<div id = "DeleteButtons">
+	<button onclick="removeLine()" accesskey="z">Delete Last</button>
+	<button onclick="deleteAllShape()" accesskey="c">Clear All</button>
+	<button onclick="deleteSelectedShape()" accesskey="b">Delete Selected</button>
+	<button onclick="polygonGetPath()" accesskey="n">Get Path</button>
+	<button onclick="undoMovement()" accesskey="n">Undo</button>
+	<button onclick="redoMovement()" accesskey="n">Redo</button>
+	
+	</div>
+	
+	<div id = "LineThickness">
+	<p>Line thickness: <input type="range" min="20" max="100" value="1" class="slider" id="thicknessRange"> </p>
+	<p>Value: <span id="thicknessRangeVal"></span></p>
+	</div>	
+	
+	<div id = "ColourOpacity">
+	<p>Colour opacity: <input type="range" min="10" max="100" value="40" class="slider" id="colourOpacity"> </p>
+	<p>Value: <span id="opacityRangeVal"></span></p>
+	</div>
+	
+
+
+	<div id="FillColour">
+     <p> Fill Colour:</p> <div id="color-palette1"></div> 
+	</div>
+
+	
+	
+	<div id="map"></div>
+	
+	<script>
+		var debug = false;
+		
+		var redoPressed = false;
+		var undoPressed = false;
+		var shiftKeyPressed = false;
+		var mousedDownFired = false;
+		var prevVertex = {lat:"" ,lng:""};
+		var nextVertex = {lat:"" ,lng:""};
+		var prevShape = [];
+		var nextShape = [];
+		var prevLog = [];
+		var	nextLog = [];
+		var dragged = 0;
+		var colors = ['#1E90FF', '#FF1493', '#4B0082', '#32CD32', '#FF8C00', '#000000'];
+		var selectedColor;
+		var colorButtons = {};
+	    var thicknessValue = 1;
+		var opacityValue = 0.4;
+		var polyOptions = {
+			fillColor: '#CA4A2F',
+			strokeWeight: thicknessValue,
+			fillOpacity: opacityValue,
+			editable: true,
+			draggable: true,
+			geodesic : false,
+		  };
+		  
+		 
+		var overlays = [];
+		var drawingManager;
+		var selectedShape;
+		var selectedShapes = []; 
+		
+		
+
+		//Update thickness 
+		var thicknessSlider = document.getElementById("thicknessRange");
+		var thicknessSliderOutput = document.getElementById("thicknessRangeVal");
+		thicknessSliderOutput.innerHTML = thicknessSlider.value/20;
+		
+		thicknessSlider.oninput = function() {
+			thicknessSliderOutput.innerHTML = this.value/20;
+			thicknessValue = this.value/20;
+			polyOptions.strokeWeight = thicknessValue;
+			setSelectedThickness(thicknessValue);
+		}
+		
+		//Update opacity
+		var opacitySlider = document.getElementById("colourOpacity");
+		var opacitySliderOutput = document.getElementById("opacityRangeVal");	
+		opacitySliderOutput.innerHTML =  "% " + Math.round(opacitySlider.value);
+		
+		opacitySlider.oninput = function() {
+			opacityValue = this.value/100;
+			polyOptions.fillOpacity = opacityValue;
+			opacitySliderOutput = opacityValue;
+			opacityRangeVal.innerHTML = "% " + Math.round( opacitySliderOutput * 100);
+			setSelectedOpacity(opacityValue);
+		}
+
+	
+		////////////////////////////////////////////////////////////////////////////////////////
+        function makeColorButton (color) {
+            var button = document.createElement('span');
+            button.className = 'color-buttons1';
+            button.style.backgroundColor = color;
+            google.maps.event.addDomListener(button, 'click', function () {
+				selectColor(color);
+				setSelectedShapeColor(color);
+            });
+            return button;
+        }
+        function buildColorPalette () {
+			var colorPalette = document.getElementById('color-palette1');
+            for (var i = 0; i < colors.length; ++i) {
+                var currColor = colors[i];
+                var colorButton = makeColorButton(currColor);
+                colorPalette.appendChild(colorButton);
+                colorButtons[currColor] = colorButton;
+            }
+            selectColor(colors[0]);
+        };		
+		function selectColor (color) {
+                selectedColor = color;
+                for (var i = 0; i < colors.length; ++i) {
+                    var currColor = colors[i];
+                    colorButtons[currColor].style.border = currColor == color ? '2px solid #789' : '2px solid #fff';
+                }
+
+                // Retrieves the current options from the drawing manager and replaces the
+                // stroke or fill color as appropriate.
+                var polylineOptions = drawingManager.get('polylineOptions');
+                polylineOptions.strokeColor = color;
+                drawingManager.set('polylineOptions', polylineOptions);
+
+                var rectangleOptions = drawingManager.get('rectangleOptions');
+                rectangleOptions.fillColor = color;
+                drawingManager.set('rectangleOptions', rectangleOptions);
+
+                var circleOptions = drawingManager.get('circleOptions');
+                circleOptions.fillColor = color;
+                drawingManager.set('circleOptions', circleOptions);
+
+                var polygonOptions = drawingManager.get('polygonOptions');
+                polygonOptions.fillColor = color;
+                drawingManager.set('polygonOptions', polygonOptions);
+            }
+		
+		
+		
+		
+	  function initMap() {
+		
+		var map = new google.maps.Map(document.getElementById('map'), {
+		  center: {lat: -34.397, lng: 150.644},
+		  zoom: 2, 
+		  //mapTypeId: 'map'
+		  
+		});
+		
+	
+		drawingManager = new google.maps.drawing.DrawingManager({
+			drawingMode: google.maps.drawing.OverlayType.POLYGON,
+			drawingControl: true,
+			drawingControlOptions: {
+				position: google.maps.ControlPosition.TOP_CENTER,
+				drawingModes: ['marker', 'circle', 'polygon', 'polyline', 'rectangle']
+			},
+			markerOptions: { draggable: true},
+			circleOptions: polyOptions,
+			polylineOptions : polyOptions,
+			polygonOptions: polyOptions,
+			rectangleOptions: polyOptions,
+		  });
+	
+		drawingManager.setMap(map);
+		
+		
+		//overlays.push(event.overlay); // store reference to added overlay
+		google.maps.event.addListener(drawingManager, 'overlaycomplete', function (e) {
+			overlays.push(e.overlay); // store reference to added overlay
+			var newShape = e.overlay;	
+			newShape.type = e.type;
+						
+			if (e.type !== google.maps.drawing.OverlayType.MARKER) {
+			
+				// Switch back to non-drawing mode after drawing a shape.
+				//drawingManager.setDrawingMode(null);
+				
+				// Add an event listener that selects the newly-drawn shape when the user
+				// mouses down on it.
+				google.maps.event.addListener(newShape, 'click', function(e) {
+
+					vertexAndPolyDel(e,newShape);
+					mousedDownFired = false;
+					return;
+				
+				});
+				
+				//Stores past event information
+				google.maps.event.addListener(newShape, 'dragstart', function() {
+				//console.log("Drag Start");
+					if (selectedShape){
+						var lati, lngi;
+						for(var i = 0; i < selectedShape.getPath().length; i++) {
+							lati = selectedShape.getPath().getAt(i).lat();
+							lngi = selectedShape.getPath().getAt(i).lng();
+							//console.log("Vertex number",i, "'s latitude is", lati, "and longitude is", lngi);
+							prevVertex = {lat: lati, lng:lngi};
+							prevShape.push(prevVertex);							
+						}
+
+						prevLog.push(prevShape);
+						prevShape = [];
+						nextLog = [];
+						//console.log("Prev Array Length",prevLog.length);
+						//console.log("Next Array Length",nextLog.length);
+					}
+				});				
+				
+				//Store information after the event ends
+				google.maps.event.addListener(newShape, 'dragend', function() {
+				//console.log("Drag End");				
+					if (selectedShape){
+						var lati, lngi;
+						
+						for(var i = 0; i < selectedShape.getPath().length; i++) {
+							lati = selectedShape.getPath().getAt(i).lat();
+							lngi = selectedShape.getPath().getAt(i).lng();
+							//console.log("Vertex number",i, "'s latitude is", lati, "and longitude is", lngi);
+							nextVertex = {lat: lati, lng:lngi};
+							nextShape.push(nextVertex);	
+						}
+						nextLog.push(nextShape);
+						nextShape = [];
+						//console.log("Prev Array Length",prevLog.length);
+						//console.log("Next Array Length",nextLog.length);
+					}
+				});	
+
+				
+				//Add an event listener to select a shape if the mouse hovers over it
+				google.maps.event.addListener(newShape, 'mousedown', function(e) {
+						if(drawingManager.drawingMode == null) {
+							mousedDownFired =true;
+//							console.log("MOUSDOWN ", e);
+							
+							setSelection(newShape);							
+						}						
+					});	
+				setSelection(newShape);
+			}
+			else {
+				//cLICK EVENT IF A MARKER IS CREATED
+				google.maps.event.addListener(newShape, 'click', function (e) {
+					setSelection(newShape);
+				});
+				setSelection(newShape);
+			}
+		});
+		
+		//Deletes a vertex if clicked on it
+		function vertexAndPolyDel(e,newShape) {
+			var vertex = e.vertex;
+			if (e.vertex !== undefined) {
+				if (newShape.type === google.maps.drawing.OverlayType.POLYGON) {
+					var path = newShape.getPaths().getAt(e.path);
+					path.removeAt(e.vertex);
+					if (path.length < 3) {
+						newShape.setMap(null);
+					}
+				}
+				if (newShape.type === google.maps.drawing.OverlayType.POLYLINE) {
+					var path = newShape.getPath();
+					path.removeAt(e.vertex);						
+					if (path.length < 2) {
+						newShape.setMap(null);
+					}
+				}
+			}
+			
+			//if(mousedDownFired == false)
+			//{
+			//setSelection(newShape, vertex);
+			//mousedDownFired = false;
+			//return;
+			//}
+			}
+				
+		function clearSelection () {
+			if (selectedShape) {
+				if (selectedShape.type !== 'marker') {
+					selectedShape.setEditable(false);
+					if(shiftKeyPressed == false){
+						for (var i=0; i < selectedShapes.length; i++) {
+						selectedShapes[i].setEditable(false);
+					}
+					selectedShapes = [];
+					}
+				}
+					
+					selectedShape = null;
+			}
+		}
+		var i = 0;
+		function setSelection (shape, e) {
+			if (debug) {
+				console.log("setSelection() selectedShapes, len = " + selectedShapes.length);
+			}
+			
+			if (shape.type !== 'marker') {
+				if(shiftKeyPressed == false) {
+					if(e == undefined) {
+						clearSelection();	
+						shape.setEditable(true);						
+					}
+
+				}
+
+				//var shapeAlreadySelected = selectedShapes.includes(shape);
+				
+				if (selectedShapes.includes(shape)){
+					shape.setEditable(false);
+					selectedShapes.splice(shape, 1)
+				}
+				
+				else {
+					shape.setEditable(true);
+					selectedShapes.push(shape);	
+				}
+
+
+				//console.log(selectedShapes.length);
+				
+				//Send the values to be updated
+				var thi = shape.strokeWeight;
+				var opa = shape.fillOpacity;
+				var fCol = shape.fillColor;
+				var sCol = shape.strokeColor;
+				updateMenuValues(thi, opa, fCol, sCol);
+
+			}
+			else if (shape.type == 'marker') {
+				clearSelection();
+			}
+				
+			selectedShape = shape;
+		}
+		
+
+		//Clears selection if clicked on the map when shift is not presseed
+		google.maps.event.addListener(map, 'click', function() {
+			if (shiftKeyPressed == false) {
+				clearSelection();
+			}
+		});	
+		
+
+		
+		
+		//Setting drawing tool option
+		document.addEventListener('keydown', function() {
+		//if (event.code == 'KeyX' && (event.ctrlKey || event.metaKey))
+				if (event.code == 'Digit0' || event.code == 'Numpad0' || event.code == 'Backquote') {
+					//clearSelection();
+					drawingManager.setDrawingMode(null);
+				} else if (event.code == 'Digit1') {
+					drawingManager.setDrawingMode('marker');
+				} else if (event.code == 'Digit2') {
+					drawingManager.setDrawingMode('circle');
+				} else if (event.code == 'Digit3') {
+					drawingManager.setDrawingMode('polygon');
+				} else if (event.code == 'Digit4') {
+					drawingManager.setDrawingMode('polyline');
+				} else if (event.code == 'Digit5' ) {
+					drawingManager.setDrawingMode('rectangle');
+				} 
+//					console.log(event.code);
+				});
+		
+		//Sets shift as pressed
+		document.addEventListener('keydown', function() {		
+			if (event.code == 'ShiftLeft' || event.code == 'ShiftRight')
+			{
+				shiftKeyPressed = true;
+
+			}
+
+		});
+		
+		//Sets shift as unpressed		
+		document.addEventListener('keyup', function() {		
+			if (event.code == 'ShiftLeft' || event.code == 'ShiftRight')
+			{
+				shiftKeyPressed = false;
+			}
+
+		});
+		
+		
+		buildColorPalette();
+}
+		//Set selected thickness
+		function setSelectedThickness(sWeight) {
+			if (selectedShape){
+				selectedShape.set('strokeWeight', sWeight)
+			}
+			if(selectedShapes !== 0) {
+				for (var i=0; i < selectedShapes.length; i++) {
+					selectedShapes[i].set('strokeWeight', sWeight);
+				}
+			}
+		}
+		
+		//Set selected opacity
+		function setSelectedOpacity(fOpacity) {
+			if (selectedShape) {
+				selectedShape.set('fillOpacity', fOpacity)
+			}
+			if(selectedShapes !== 0) {
+				for (var i=0; i < selectedShapes.length; i++) {
+					selectedShapes[i].set('fillOpacity', fOpacity);
+				}
+			}			
+		}
+		
+
+		
+		//set selected fill colour
+        function setSelectedShapeColor (color) {
+            if (selectedShape) {
+                if (selectedShape.type == google.maps.drawing.OverlayType.POLYLINE) {
+                    selectedShape.set('strokeColor', color);
+                } else {
+                    selectedShape.set('fillColor', color);
+					selectedShape.set('strokeColor', color);
+                }
+             }
+			if(selectedShapes !== 0) {
+				for (var i=0; i < selectedShapes.length; i++) {
+					selectedShapes[i].set('fillColor', color);
+					selectedShapes[i].set('strokeColor', color);
+				}
+			}			 
+        }
+
+		
+		function updateMenuValues(thi, opa, fCol, sCol){
+		
+		//Update thickness slider and value on the settings menu
+		var thicknessSliderOutput = document.getElementById("thicknessRangeVal");
+		thicknessSliderOutput.innerHTML = thi;
+		document.getElementById("thicknessRange").value = thi*20;
+		
+		//Update the opacity slider and value on the settings menu
+		var opacitySliderOutput = document.getElementById("opacityRangeVal");
+		opacitySliderOutput.innerHTML =  "% " + opa*100;
+		document.getElementById("colourOpacity").value =  opa*100;
+		
+
+			if (drawingManager.drawingMode == null) {
+				selectColor(fCol);
+			}
+		}
+function undoMovement() {
+
+	var lastItem = prevLog[prevLog.length-1];
+	if (selectedShape){
+		if (prevLog.length !== 0){
+		nextLog.push(lastItem);
+		
+		if (redoPressed == false){
+			selectedShape.setPath(prevLog[prevLog.length-1]);
+			undoPressed = false;
+			console.log("Redo not pressed");
+		}
+		else {
+			selectedShape.setPath(prevLog[prevLog.length-2]);
+		}
+
+		
+		prevLog.pop();
+		undoPressed = true;
+		
+		//console.log("Undo Array Length",prevLog.length);
+		//console.log(JSON.stringify(prevLog));	
+		//console.log(JSON.stringify(nextLog));	
+		}
+	}
+}
+		
+function redoMovement() {
+	if (selectedShape){
+		if (nextLog.length > 1){
+		prevLog.push(nextLog[nextLog.length-1]);
+		
+		if (undoPressed == false){
+			selectedShape.setPath(nextLog[nextLog.length-1]);	
+			undoPressed = false;
+			console.log("Undo not pressed");
+		}
+		else {
+			selectedShape.setPath(nextLog[nextLog.length-2]);	
+		}
+		nextLog.pop();
+		redoPressed = true;
+		
+		//console.log("Redo Array Length",nextLog.length);
+		//console.log(JSON.stringify(prevLog));				
+		//console.log(JSON.stringify(nextLog));		
+		}
+	}	
+}		
+		
+function polygonGetPath() {
+	if (selectedShape){
+	var lati, lngi;
+	
+	
+	for(var i = 0; i < selectedShape.getPath().length; i++) {
+		lati = selectedShape.getPath().getAt(i).lat();
+		lngi = selectedShape.getPath().getAt(i).lng();
+		console.log("Vertex number",i, "'s latitude is", lati, "and longitude is", lngi);
+		
+		}
+	}
+
+}		
+	  
+function deleteSelectedShape () {
+	for (var i=0; i < selectedShapes.length; i++){
+		selectedShapes[i].setMap(null);
+	}
+	selectedShapes = [];
+}
+			
+function removeLine() {
+	var lastOverlay = overlays.pop();
+	if (lastOverlay) lastOverlay.setMap(null);
+	}
+		
+function deleteAllShape() {
+	for (var i=0; i < overlays.length; i++) {
+		overlays[i].setMap(null);
+		
+	}
+	overlays = [];
+}
+
+	</script>
+	<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyBzunGwIF2OwsfrOkIC_8bhh0OPGZXo52Y&libraries=drawing&callback=initMap" async defer></script>
+	<script src="shortcuts.js"></script>
+  </body>
+</html>
Index: /gs3-extensions/map-editor/DrawingManager/checkpoints-singlefile/index backup v13.html
===================================================================
--- /gs3-extensions/map-editor/DrawingManager/checkpoints-singlefile/index backup v13.html	(revision 32709)
+++ /gs3-extensions/map-editor/DrawingManager/checkpoints-singlefile/index backup v13.html	(revision 32709)
@@ -0,0 +1,631 @@
+<!DOCTYPE html>
+<html>
+  <head>
+	<title>Drawing Tools</title>
+	<meta name="viewport" content="initial-scale=1.0, user-scalable=no">
+	<meta charset="utf-8">
+	<style>
+	  /* Always set the map height explicitly to define the size of the div
+	   * element that contains the map. */
+	  #map {
+		height: 83%;
+		width: 90;
+		float: bottom;
+		clear: both;
+	  }
+	  /* Optional: Makes the sample page fill the window. */
+	  html, body {
+		height: 100%;
+		width: 99%;
+		margin: 0;
+		padding: 0;
+
+	  }
+	  
+	  #DeleteButtons{
+	  display: inline-block;
+	  float: left;
+	  padding-left: 10px;
+	  padding-top: 5px;
+	  width: 100%
+
+	  }
+	  
+	  #LineThickness{
+	  display: inline-block;
+	  float: left;
+	  padding-left: 10px;
+	  padding-top: 5px;
+
+	  }
+	  
+	  #ColourOpacity{
+	  display: inline-block;
+	  float: left;
+	  padding-left: 10px;
+	  padding-top: 5px;
+
+	  }
+	  
+	  #buttons3{
+	  display: inline-block;
+	  float: left;
+	  padding-left: 10px;
+	  padding-top: 5px;
+
+	  }	  
+	  
+      #FillColour {
+	  display: inline-block;
+	  float: left;
+	  padding-left: 10px;
+	  padding-top: 5px;
+	  }
+	  
+      #color-palette1 {
+      clear: both;
+      }
+	  
+      .color-buttons1 {
+      width: 14px;
+      height: 14px;
+      font-size: 0;
+      margin: 2px;
+      float: left;
+      cursor: pointer;
+      }
+
+
+	</style>
+  </head>
+  <body>
+	<div id = "DeleteButtons">
+	<button onclick="removeLine()" accesskey="z">Delete Last</button>
+	<button onclick="deleteAllShape()" accesskey="c">Clear All</button>
+	<button onclick="deleteSelectedShape()" accesskey="b">Delete Selected</button>
+	<button onclick="polygonGetPath()" accesskey="n">Get Path</button>
+	<button onclick="undoMovement()" accesskey="n">Undo</button>
+	<button onclick="redoMovement()" accesskey="n">Redo</button>
+	
+	</div>
+	
+	<div id = "LineThickness">
+	<p>Line thickness: <input type="range" min="20" max="100" value="1" class="slider" id="thicknessRange"> </p>
+	<p>Value: <span id="thicknessRangeVal"></span></p>
+	</div>	
+	
+	<div id = "ColourOpacity">
+	<p>Colour opacity: <input type="range" min="10" max="100" value="40" class="slider" id="colourOpacity"> </p>
+	<p>Value: <span id="opacityRangeVal"></span></p>
+	</div>
+	
+
+
+	<div id="FillColour">
+     <p> Fill Colour:</p> <div id="color-palette1"></div> 
+	</div>
+
+	
+	
+	<div id="map"></div>
+	
+	<script>
+		var debug = false;
+		
+		var redoPressed = false;
+		var undoPressed = false;
+		var shiftKeyPressed = false;
+		var mousedDownFired = false;
+		var prevVertex = {lat:"" ,lng:""};
+		var nextVertex = {lat:"" ,lng:""};
+		var prevShape = [];
+		var nextShape = [];
+		var prevLog = [];
+		var	nextLog = [];
+		var dragged = 0;
+		var colors = ['#1E90FF', '#FF1493', '#4B0082', '#32CD32', '#FF8C00', '#000000'];
+		var selectedColor;
+		var colorButtons = {};
+	    var thicknessValue = 1;
+		var opacityValue = 0.4;
+		var polyOptions = {
+			fillColor: '#CA4A2F',
+			strokeWeight: thicknessValue,
+			fillOpacity: opacityValue,
+			editable: true,
+			draggable: true,
+			geodesic : false,
+		  };
+		  
+		 
+		var overlays = [];
+		var drawingManager;
+		var selectedShape;
+		var selectedShapes = []; 
+		
+		
+
+		//Update thickness 
+		var thicknessSlider = document.getElementById("thicknessRange");
+		var thicknessSliderOutput = document.getElementById("thicknessRangeVal");
+		thicknessSliderOutput.innerHTML = thicknessSlider.value/20;
+		
+		thicknessSlider.oninput = function() {
+			thicknessSliderOutput.innerHTML = this.value/20;
+			thicknessValue = this.value/20;
+			polyOptions.strokeWeight = thicknessValue;
+			setSelectedThickness(thicknessValue);
+		}
+		
+		//Update opacity
+		var opacitySlider = document.getElementById("colourOpacity");
+		var opacitySliderOutput = document.getElementById("opacityRangeVal");	
+		opacitySliderOutput.innerHTML =  "% " + Math.round(opacitySlider.value);
+		
+		opacitySlider.oninput = function() {
+			opacityValue = this.value/100;
+			polyOptions.fillOpacity = opacityValue;
+			opacitySliderOutput = opacityValue;
+			opacityRangeVal.innerHTML = "% " + Math.round( opacitySliderOutput * 100);
+			setSelectedOpacity(opacityValue);
+		}
+
+	
+		////////////////////////////////////////////////////////////////////////////////////////
+        function makeColorButton (color) {
+            var button = document.createElement('span');
+            button.className = 'color-buttons1';
+            button.style.backgroundColor = color;
+            google.maps.event.addDomListener(button, 'click', function () {
+				selectColor(color);
+				setSelectedShapeColor(color);
+            });
+            return button;
+        }
+        function buildColorPalette () {
+			var colorPalette = document.getElementById('color-palette1');
+            for (var i = 0; i < colors.length; ++i) {
+                var currColor = colors[i];
+                var colorButton = makeColorButton(currColor);
+                colorPalette.appendChild(colorButton);
+                colorButtons[currColor] = colorButton;
+            }
+            selectColor(colors[0]);
+        };		
+		function selectColor (color) {
+                selectedColor = color;
+                for (var i = 0; i < colors.length; ++i) {
+                    var currColor = colors[i];
+                    colorButtons[currColor].style.border = currColor == color ? '2px solid #789' : '2px solid #fff';
+                }
+
+                // Retrieves the current options from the drawing manager and replaces the
+                // stroke or fill color as appropriate.
+                var polylineOptions = drawingManager.get('polylineOptions');
+                polylineOptions.strokeColor = color;
+                drawingManager.set('polylineOptions', polylineOptions);
+
+                var rectangleOptions = drawingManager.get('rectangleOptions');
+                rectangleOptions.fillColor = color;
+                drawingManager.set('rectangleOptions', rectangleOptions);
+
+                var circleOptions = drawingManager.get('circleOptions');
+                circleOptions.fillColor = color;
+                drawingManager.set('circleOptions', circleOptions);
+
+                var polygonOptions = drawingManager.get('polygonOptions');
+                polygonOptions.fillColor = color;
+                drawingManager.set('polygonOptions', polygonOptions);
+            }
+		
+		
+		
+		
+	  function initMap() {
+		
+		var map = new google.maps.Map(document.getElementById('map'), {
+		  center: {lat: -34.397, lng: 150.644},
+		  zoom: 2, 
+		  //mapTypeId: 'map'
+		  
+		});
+		
+	
+		drawingManager = new google.maps.drawing.DrawingManager({
+			drawingMode: google.maps.drawing.OverlayType.POLYGON,
+			drawingControl: true,
+			drawingControlOptions: {
+				position: google.maps.ControlPosition.TOP_CENTER,
+				drawingModes: ['marker', 'circle', 'polygon', 'polyline', 'rectangle']
+			},
+			markerOptions: { draggable: true},
+			circleOptions: polyOptions,
+			polylineOptions : polyOptions,
+			polygonOptions: polyOptions,
+			rectangleOptions: polyOptions,
+		  });
+	
+		drawingManager.setMap(map);
+		
+		
+		//overlays.push(event.overlay); // store reference to added overlay
+		google.maps.event.addListener(drawingManager, 'overlaycomplete', function (e) {
+			overlays.push(e.overlay); // store reference to added overlay
+			var newShape = e.overlay;	
+			newShape.type = e.type;
+						
+			if (e.type !== google.maps.drawing.OverlayType.MARKER) {
+			
+				// Switch back to non-drawing mode after drawing a shape.
+				//drawingManager.setDrawingMode(null);
+				
+				// Add an event listener that selects the newly-drawn shape when the user
+				// mouses down on it.
+				google.maps.event.addListener(newShape, 'click', function(e) {
+
+					vertexAndPolyDel(e,newShape);
+					mousedDownFired = false;
+					return;
+				
+				});
+				
+				//Stores past event information
+				google.maps.event.addListener(newShape, 'dragstart', function() {
+				//console.log("Drag Start");
+					if (selectedShape){
+						var lati, lngi;
+						for(var i = 0; i < selectedShape.getPath().length; i++) {
+							lati = selectedShape.getPath().getAt(i).lat();
+							lngi = selectedShape.getPath().getAt(i).lng();
+							//console.log("Vertex number",i, "'s latitude is", lati, "and longitude is", lngi);
+							prevVertex = {lat: lati, lng:lngi};
+							prevShape.push(prevVertex);							
+						}
+
+						prevLog.push(prevShape);
+						prevShape = [];
+						nextLog = [];
+						//console.log("Prev Array Length",prevLog.length);
+						//console.log("Next Array Length",nextLog.length);
+					}
+				});				
+				
+				//Store information after the event ends
+				google.maps.event.addListener(newShape, 'dragend', function() {
+				//console.log("Drag End");				
+					if (selectedShape){
+						var lati, lngi;
+						
+						for(var i = 0; i < selectedShape.getPath().length; i++) {
+							lati = selectedShape.getPath().getAt(i).lat();
+							lngi = selectedShape.getPath().getAt(i).lng();
+							//console.log("Vertex number",i, "'s latitude is", lati, "and longitude is", lngi);
+							nextVertex = {lat: lati, lng:lngi};
+							nextShape.push(nextVertex);	
+						}
+						nextLog.push(nextShape);
+						nextShape = [];
+						//console.log("Prev Array Length",prevLog.length);
+						//console.log("Next Array Length",nextLog.length);
+					}
+				});	
+
+				
+				//Add an event listener to select a shape if the mouse hovers over it
+				google.maps.event.addListener(newShape, 'mousedown', function(e) {
+						if(drawingManager.drawingMode == null) {
+							mousedDownFired =true;
+//							console.log("MOUSDOWN ", e);
+							
+							setSelection(newShape);							
+						}						
+					});	
+				setSelection(newShape);
+			}
+			else {
+				//cLICK EVENT IF A MARKER IS CREATED
+				google.maps.event.addListener(newShape, 'click', function (e) {
+					setSelection(newShape);
+				});
+				setSelection(newShape);
+			}
+		});
+		
+		//Deletes a vertex if clicked on it
+		function vertexAndPolyDel(e,newShape) {
+			var vertex = e.vertex;
+			if (e.vertex !== undefined) {
+				if (newShape.type === google.maps.drawing.OverlayType.POLYGON) {
+					var path = newShape.getPaths().getAt(e.path);
+					path.removeAt(e.vertex);
+					if (path.length < 3) {
+						newShape.setMap(null);
+					}
+				}
+				if (newShape.type === google.maps.drawing.OverlayType.POLYLINE) {
+					var path = newShape.getPath();
+					path.removeAt(e.vertex);						
+					if (path.length < 2) {
+						newShape.setMap(null);
+					}
+				}
+			}
+			
+			//if(mousedDownFired == false)
+			//{
+			//setSelection(newShape, vertex);
+			//mousedDownFired = false;
+			//return;
+			//}
+			}
+				
+		function clearSelection () {
+			if (selectedShape) {
+				if (selectedShape.type !== 'marker') {
+					selectedShape.setEditable(false);
+					if(shiftKeyPressed == false){
+						for (var i=0; i < selectedShapes.length; i++) {
+						selectedShapes[i].setEditable(false);
+					}
+					selectedShapes = [];
+					}
+				}
+					
+					selectedShape = null;
+			}
+		}
+		var i = 0;
+		function setSelection (shape, e) {
+			if (debug) {
+				console.log("setSelection() selectedShapes, len = " + selectedShapes.length);
+			}
+			
+			if (shape.type !== 'marker') {
+				if(shiftKeyPressed == false) {
+					if(e == undefined) {
+						clearSelection();	
+						shape.setEditable(true);						
+					}
+
+				}
+
+				//var shapeAlreadySelected = selectedShapes.includes(shape);
+				
+				if (selectedShapes.includes(shape)){
+					shape.setEditable(false);
+					selectedShapes.splice(shape, 1)
+				}
+				
+				else {
+					shape.setEditable(true);
+					selectedShapes.push(shape);	
+				}
+
+
+				//console.log(selectedShapes.length);
+				
+				//Send the values to be updated
+				var thi = shape.strokeWeight;
+				var opa = shape.fillOpacity;
+				var fCol = shape.fillColor;
+				var sCol = shape.strokeColor;
+				updateMenuValues(thi, opa, fCol, sCol);
+
+			}
+			else if (shape.type == 'marker') {
+				clearSelection();
+			}
+				
+			selectedShape = shape;
+		}
+		
+
+		//Clears selection if clicked on the map when shift is not presseed
+		google.maps.event.addListener(map, 'click', function() {
+			if (shiftKeyPressed == false) {
+				clearSelection();
+			}
+		});	
+		
+
+		
+		
+		//Setting drawing tool option
+		document.addEventListener('keydown', function() {
+		//if (event.code == 'KeyX' && (event.ctrlKey || event.metaKey))
+				if (event.code == 'Digit0' || event.code == 'Numpad0' || event.code == 'Backquote') {
+					//clearSelection();
+					drawingManager.setDrawingMode(null);
+				} else if (event.code == 'Digit1') {
+					drawingManager.setDrawingMode('marker');
+				} else if (event.code == 'Digit2') {
+					drawingManager.setDrawingMode('circle');
+				} else if (event.code == 'Digit3') {
+					drawingManager.setDrawingMode('polygon');
+				} else if (event.code == 'Digit4') {
+					drawingManager.setDrawingMode('polyline');
+				} else if (event.code == 'Digit5' ) {
+					drawingManager.setDrawingMode('rectangle');
+				} 
+//					console.log(event.code);
+				});
+		
+		//Sets shift as pressed
+		document.addEventListener('keydown', function() {		
+			if (event.code == 'ShiftLeft' || event.code == 'ShiftRight')
+			{
+				shiftKeyPressed = true;
+
+			}
+
+		});
+		
+		//Sets shift as unpressed		
+		document.addEventListener('keyup', function() {		
+			if (event.code == 'ShiftLeft' || event.code == 'ShiftRight')
+			{
+				shiftKeyPressed = false;
+			}
+
+		});
+		
+		
+		buildColorPalette();
+}
+		//Set selected thickness
+		function setSelectedThickness(sWeight) {
+			if (selectedShape){
+				selectedShape.set('strokeWeight', sWeight)
+			}
+			if(selectedShapes !== 0) {
+				for (var i=0; i < selectedShapes.length; i++) {
+					selectedShapes[i].set('strokeWeight', sWeight);
+				}
+			}
+		}
+		
+		//Set selected opacity
+		function setSelectedOpacity(fOpacity) {
+			if (selectedShape) {
+				selectedShape.set('fillOpacity', fOpacity)
+			}
+			if(selectedShapes !== 0) {
+				for (var i=0; i < selectedShapes.length; i++) {
+					selectedShapes[i].set('fillOpacity', fOpacity);
+				}
+			}			
+		}
+		
+
+		
+		//set selected fill colour
+        function setSelectedShapeColor (color) {
+            if (selectedShape) {
+                if (selectedShape.type == google.maps.drawing.OverlayType.POLYLINE) {
+                    selectedShape.set('strokeColor', color);
+                } else {
+                    selectedShape.set('fillColor', color);
+					selectedShape.set('strokeColor', color);
+                }
+             }
+			if(selectedShapes !== 0) {
+				for (var i=0; i < selectedShapes.length; i++) {
+					selectedShapes[i].set('fillColor', color);
+					selectedShapes[i].set('strokeColor', color);
+				}
+			}			 
+        }
+
+		
+		function updateMenuValues(thi, opa, fCol, sCol){
+		
+		//Update thickness slider and value on the settings menu
+		var thicknessSliderOutput = document.getElementById("thicknessRangeVal");
+		thicknessSliderOutput.innerHTML = thi;
+		document.getElementById("thicknessRange").value = thi*20;
+		
+		//Update the opacity slider and value on the settings menu
+		var opacitySliderOutput = document.getElementById("opacityRangeVal");
+		opacitySliderOutput.innerHTML =  "% " + opa*100;
+		document.getElementById("colourOpacity").value =  opa*100;
+		
+
+			if (drawingManager.drawingMode == null) {
+				selectColor(fCol);
+			}
+		}
+function undoMovement() {
+
+	var lastItem = prevLog[prevLog.length-1];
+	if (selectedShape){
+		if (prevLog.length !== 0){
+		nextLog.push(prevLog[prevLog.length-1]);
+		
+		if (redoPressed == false){
+			selectedShape.setPath(prevLog[prevLog.length-1]);
+			
+			console.log("Redo not pressed");
+		}
+		else {
+			selectedShape.setPath(prevLog[prevLog.length-2]);
+			console.log("Redo pressed");
+		}
+
+		undoPressed = false;
+		prevLog.pop();
+		undoPressed = true;
+		
+		//console.log("Undo Array Length",prevLog.length);
+		//console.log(JSON.stringify(prevLog));	
+		//console.log(JSON.stringify(nextLog));	
+		}
+	}
+}
+		
+function redoMovement() {
+
+	var rLastItem = prevLog[prevLog.length-1];
+	if (selectedShape){
+		if (nextLog.length > 1){
+		prevLog.push(nextLog[nextLog.length-1]);
+		
+		if (undoPressed == false){
+			selectedShape.setPath(nextLog[nextLog.length-1]);	
+			
+			console.log("Undo not pressed");
+		}
+		else {
+			selectedShape.setPath(nextLog[nextLog.length-2]);
+			console.log("Undo pressed");
+		}
+		undoPressed = false;
+		nextLog.pop();
+		redoPressed = true;
+		
+		//console.log("Redo Array Length",nextLog.length);
+		//console.log(JSON.stringify(prevLog));				
+		//console.log(JSON.stringify(nextLog));		
+		}
+	}	
+}		
+		
+function polygonGetPath() {
+	if (selectedShape){
+	var lati, lngi;
+	
+	
+	for(var i = 0; i < selectedShape.getPath().length; i++) {
+		lati = selectedShape.getPath().getAt(i).lat();
+		lngi = selectedShape.getPath().getAt(i).lng();
+		console.log("Vertex number",i, "'s latitude is", lati, "and longitude is", lngi);
+		
+		}
+	}
+
+}		
+	  
+function deleteSelectedShape () {
+	for (var i=0; i < selectedShapes.length; i++){
+		selectedShapes[i].setMap(null);
+	}
+	selectedShapes = [];
+}
+			
+function removeLine() {
+	var lastOverlay = overlays.pop();
+	if (lastOverlay) lastOverlay.setMap(null);
+	}
+		
+function deleteAllShape() {
+	for (var i=0; i < overlays.length; i++) {
+		overlays[i].setMap(null);
+		
+	}
+	overlays = [];
+}
+
+	</script>
+	<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyBzunGwIF2OwsfrOkIC_8bhh0OPGZXo52Y&libraries=drawing&callback=initMap" async defer></script>
+	<script src="shortcuts.js"></script>
+  </body>
+</html>
Index: /gs3-extensions/map-editor/DrawingManager/checkpoints-singlefile/index backup v14.html
===================================================================
--- /gs3-extensions/map-editor/DrawingManager/checkpoints-singlefile/index backup v14.html	(revision 32709)
+++ /gs3-extensions/map-editor/DrawingManager/checkpoints-singlefile/index backup v14.html	(revision 32709)
@@ -0,0 +1,668 @@
+<!DOCTYPE html>
+<html>
+  <head>
+	<title>Drawing Tools</title>
+	<meta name="viewport" content="initial-scale=1.0, user-scalable=no">
+	<meta charset="utf-8">
+	<style>
+	  /* Always set the map height explicitly to define the size of the div
+	   * element that contains the map. */
+	  #map {
+		height: 83%;
+		width: 90;
+		float: bottom;
+		clear: both;
+	  }
+	  /* Optional: Makes the sample page fill the window. */
+	  html, body {
+		height: 100%;
+		width: 99%;
+		margin: 0;
+		padding: 0;
+
+	  }
+	  
+	  #DeleteButtons{
+	  display: inline-block;
+	  float: left;
+	  padding-left: 10px;
+	  padding-top: 5px;
+	  width: 100%
+
+	  }
+	  
+	  #LineThickness{
+	  display: inline-block;
+	  float: left;
+	  padding-left: 10px;
+	  padding-top: 5px;
+
+	  }
+	  
+	  #ColourOpacity{
+	  display: inline-block;
+	  float: left;
+	  padding-left: 10px;
+	  padding-top: 5px;
+
+	  }
+	  
+	  #buttons3{
+	  display: inline-block;
+	  float: left;
+	  padding-left: 10px;
+	  padding-top: 5px;
+
+	  }	  
+	  
+      #FillColour {
+	  display: inline-block;
+	  float: left;
+	  padding-left: 10px;
+	  padding-top: 5px;
+	  }
+	  
+      #color-palette1 {
+      clear: both;
+      }
+	  
+      .color-buttons1 {
+      width: 14px;
+      height: 14px;
+      font-size: 0;
+      margin: 2px;
+      float: left;
+      cursor: pointer;
+      }
+
+
+	</style>
+  </head>
+  <body>
+	<div id = "DeleteButtons">
+	<button onclick="removeLine()" accesskey="z">Delete Last</button>
+	<button onclick="deleteAllShape()" accesskey="c">Clear All</button>
+	<button onclick="deleteSelectedShape()" accesskey="b">Delete Selected</button>
+	<button onclick="polygonGetPath()" accesskey="n">Get Path</button>
+	<button onclick="undoMovement()" accesskey="n">Undo</button>
+	<button onclick="redoMovement()" accesskey="n">Redo</button>
+	
+	</div>
+	
+	<div id = "LineThickness">
+	<p>Line thickness: <input type="range" min="20" max="100" value="1" class="slider" id="thicknessRange"> </p>
+	<p>Value: <span id="thicknessRangeVal"></span></p>
+	</div>	
+	
+	<div id = "ColourOpacity">
+	<p>Colour opacity: <input type="range" min="10" max="100" value="40" class="slider" id="colourOpacity"> </p>
+	<p>Value: <span id="opacityRangeVal"></span></p>
+	</div>
+	
+
+
+	<div id="FillColour">
+     <p> Fill Colour:</p> <div id="color-palette1"></div> 
+	</div>
+
+	
+	
+	<div id="map"></div>
+	
+	<script>
+		var debug = false;
+
+		var redoPressed = false;
+		var undoPressed = 0;
+		var shiftKeyPressed = false;
+		var mousedDownFired = false;
+
+		
+		//var coor = {east: 100, north: -50, south: 50, west:-100};
+		var prevEdge = {
+			east: "",
+			north: "",
+			south: "",
+			west: ""
+		}
+		var nextEdge = {
+			east: "",
+			north: "",
+			south: "",
+			west: ""
+		}
+		var prevVertex = {
+			lat: "",
+			lng: ""
+		};
+		var nextVertex = {
+			lat: "",
+			lng: ""
+		};
+		var prevShape = [];
+		var nextShape = [];
+		var prevLog = [];
+		var nextLog = [];
+		var dragged = 0;
+		var colors = ['#1E90FF', '#FF1493', '#4B0082', '#32CD32', '#FF8C00', '#000000'];
+		var selectedColor;
+		var colorButtons = {};
+		var thicknessValue = 1;
+		var opacityValue = 0.4;
+		var polyOptions = {
+			fillColor: '#CA4A2F',
+			strokeWeight: thicknessValue,
+			fillOpacity: opacityValue,
+			editable: true,
+			draggable: true,
+			geodesic: false,
+		};
+
+		var overlays = [];
+		var drawingManager;
+		var selectedShape;
+		var selectedShapes = [];
+		
+
+		//Update thickness
+		var thicknessSlider = document.getElementById("thicknessRange");
+		var thicknessSliderOutput = document.getElementById("thicknessRangeVal");
+		thicknessSliderOutput.innerHTML = thicknessSlider.value / 20;
+
+		thicknessSlider.oninput = function () {
+			thicknessSliderOutput.innerHTML = this.value / 20;
+			thicknessValue = this.value / 20;
+			polyOptions.strokeWeight = thicknessValue;
+			setSelectedThickness(thicknessValue);
+		}
+
+		//Update opacity
+		var opacitySlider = document.getElementById("colourOpacity");
+		var opacitySliderOutput = document.getElementById("opacityRangeVal");
+		opacitySliderOutput.innerHTML = "% " + Math.round(opacitySlider.value);
+
+		opacitySlider.oninput = function () {
+			opacityValue = this.value / 100;
+			polyOptions.fillOpacity = opacityValue;
+			opacitySliderOutput = opacityValue;
+			opacityRangeVal.innerHTML = "% " + Math.round(opacitySliderOutput * 100);
+			setSelectedOpacity(opacityValue);
+		}
+
+		////////////////////////////////////////////////////////////////////////////////////////
+		function makeColorButton(color) {
+			var button = document.createElement('span');
+			button.className = 'color-buttons1';
+			button.style.backgroundColor = color;
+			google.maps.event.addDomListener(button, 'click', function () {
+				selectColor(color);
+				setSelectedShapeColor(color);
+			});
+			return button;
+		}
+		function buildColorPalette() {
+			var colorPalette = document.getElementById('color-palette1');
+			for (var i = 0; i < colors.length; ++i) {
+				var currColor = colors[i];
+				var colorButton = makeColorButton(currColor);
+				colorPalette.appendChild(colorButton);
+				colorButtons[currColor] = colorButton;
+			}
+			selectColor(colors[0]);
+		};
+		function selectColor(color) {
+			selectedColor = color;
+			for (var i = 0; i < colors.length; ++i) {
+				var currColor = colors[i];
+				colorButtons[currColor].style.border = currColor == color ? '2px solid #789' : '2px solid #fff';
+			}
+
+			// Retrieves the current options from the drawing manager and replaces the
+			// stroke or fill color as appropriate.
+			var polylineOptions = drawingManager.get('polylineOptions');
+			polylineOptions.strokeColor = color;
+			drawingManager.set('polylineOptions', polylineOptions);
+
+			var rectangleOptions = drawingManager.get('rectangleOptions');
+			rectangleOptions.fillColor = color;
+			drawingManager.set('rectangleOptions', rectangleOptions);
+
+			var circleOptions = drawingManager.get('circleOptions');
+			circleOptions.fillColor = color;
+			drawingManager.set('circleOptions', circleOptions);
+
+			var polygonOptions = drawingManager.get('polygonOptions');
+			polygonOptions.fillColor = color;
+			drawingManager.set('polygonOptions', polygonOptions);
+		}
+
+		function initMap() {
+
+			var map = new google.maps.Map(document.getElementById('map'), {
+					center: {
+						lat: -34.397,
+						lng: 150.644
+					},
+					zoom: 2,
+					//mapTypeId: 'map'
+
+				});
+
+			drawingManager = new google.maps.drawing.DrawingManager({
+					drawingMode: google.maps.drawing.OverlayType.RECTANGLE,
+					drawingControl: true,
+					drawingControlOptions: {
+						position: google.maps.ControlPosition.TOP_CENTER,
+						drawingModes: ['marker', 'circle', 'polygon', 'polyline', 'rectangle']
+					},
+					markerOptions: {
+						draggable: true
+					},
+					circleOptions: polyOptions,
+					polylineOptions: polyOptions,
+					polygonOptions: polyOptions,
+					rectangleOptions: polyOptions,
+				});
+
+			drawingManager.setMap(map);
+
+			//overlays.push(event.overlay); // store reference to added overlay
+			google.maps.event.addListener(drawingManager, 'overlaycomplete', function (e) {
+				overlays.push(e.overlay); // store reference to added overlay
+				var newShape = e.overlay;
+				newShape.type = e.type;
+
+				if (e.type !== google.maps.drawing.OverlayType.MARKER) {
+
+					// Switch back to non-drawing mode after drawing a shape.
+					//drawingManager.setDrawingMode(null);
+
+					// Add an event listener that selects the newly-drawn shape when the user
+					// mouses down on it.
+					google.maps.event.addListener(newShape, 'click', function (e) {
+
+						vertexAndPolyDel(e, newShape);
+						mousedDownFired = false;
+						return;
+
+					});
+
+					//Stores past event information
+					google.maps.event.addListener(newShape, 'dragstart', function () {
+						//console.log("Drag Start");
+						if (selectedShape) {
+							var polyG = newShape.type === google.maps.drawing.OverlayType.POLYLINE;
+							var polyL = newShape.type === google.maps.drawing.OverlayType.POLYGON;
+							
+							if (polyL || polyG) {
+								var lati,
+								lngi;
+								for (var i = 0; i < selectedShape.getPath().length; i++) {
+									lati = selectedShape.getPath().getAt(i).lat();
+									lngi = selectedShape.getPath().getAt(i).lng();
+									//console.log("Vertex number",i, "'s latitude is", lati, "and longitude is", lngi);
+									prevVertex = {
+										lat: lati,
+										lng: lngi
+									};
+									prevShape.push(prevVertex);
+								}
+							} else {
+								//east is: ea.l
+								//north is: la.l
+								//southt is: la.j
+								//west is: ea.j
+								
+								prevEdge.east = selectedShape.getBounds().ea.l;
+								prevEdge.north = selectedShape.getBounds().la.l;
+								prevEdge.south = selectedShape.getBounds().la.j;
+								prevEdge.west = selectedShape.getBounds().ea.j;
+							
+								prevShape.push(prevEdge);
+								//console.log(prevEdge);
+								
+							}
+							
+					
+							
+							prevLog.push(prevShape);
+							console.log(JSON.stringify(prevLog));
+							prevShape = [];
+							nextLog = [];
+							//console.log("Prev Array ", prevLog);
+							//console.log("Next Array Length",nextLog.length);
+						}
+					});
+
+					//Store information after the event ends
+					google.maps.event.addListener(newShape, 'dragend', function () {
+						//console.log("Drag End");
+						if (selectedShape) {
+							var polyG = newShape.type === google.maps.drawing.OverlayType.POLYLINE;
+							var polyL = newShape.type === google.maps.drawing.OverlayType.POLYGON;
+							
+							if (polyL || polyG) {						
+								var lati,
+								lngi;
+	
+								for (var i = 0; i < selectedShape.getPath().length; i++) {
+									lati = selectedShape.getPath().getAt(i).lat();
+									lngi = selectedShape.getPath().getAt(i).lng();
+									//console.log("Vertex number",i, "'s latitude is", lati, "and longitude is", lngi);
+									nextVertex = {
+										lat: lati,
+										lng: lngi
+									};
+									nextShape.push(nextVertex);
+								}
+							} else {
+
+								nextEdge.east = selectedShape.getBounds().ea.l;
+								nextEdge.north = selectedShape.getBounds().la.l;
+								nextEdge.south = selectedShape.getBounds().la.j;
+								nextEdge.west = selectedShape.getBounds().ea.j;
+								
+								nextShape.push(nextEdge);
+							}
+							
+							nextLog.push(nextShape);
+							nextShape = [];
+							//console.log("Prev Array Length",prevLog.length);
+							//console.log("Next Array Length",nextLog.length);
+						}
+					});
+
+					//Add an event listener to select a shape if the mouse hovers over it
+					google.maps.event.addListener(newShape, 'mousedown', function (e) {
+						if (drawingManager.drawingMode == null) {
+							mousedDownFired = true;
+							//							console.log("MOUSDOWN ", e);
+
+							setSelection(newShape);
+						}
+					});
+					setSelection(newShape);
+				} else {
+					//cLICK EVENT IF A MARKER IS CREATED
+					google.maps.event.addListener(newShape, 'click', function (e) {
+						setSelection(newShape);
+					});
+					setSelection(newShape);
+				}
+			});
+
+			//Deletes a vertex if clicked on it
+			function vertexAndPolyDel(e, newShape) {
+				var vertex = e.vertex;
+				if (e.vertex !== undefined) {
+					if (newShape.type === google.maps.drawing.OverlayType.POLYGON) {
+						var path = newShape.getPaths().getAt(e.path);
+						path.removeAt(e.vertex);
+						if (path.length < 3) {
+							newShape.setMap(null);
+						}
+					}
+					if (newShape.type === google.maps.drawing.OverlayType.POLYLINE) {
+						var path = newShape.getPath();
+						path.removeAt(e.vertex);
+						if (path.length < 2) {
+							newShape.setMap(null);
+						}
+					}
+				}
+
+				//if(mousedDownFired == false)
+				//{
+				//setSelection(newShape, vertex);
+				//mousedDownFired = false;
+				//return;
+				//}
+			}
+
+			function clearSelection() {
+				if (selectedShape) {
+					if (selectedShape.type !== 'marker') {
+						selectedShape.setEditable(false);
+						if (shiftKeyPressed == false) {
+							for (var i = 0; i < selectedShapes.length; i++) {
+								selectedShapes[i].setEditable(false);
+							}
+							selectedShapes = [];
+						}
+					}
+
+					selectedShape = null;
+				}
+			}
+			var i = 0;
+			
+			//Set selection for the selected overlay
+			function setSelection(shape, e) {
+				
+
+				if (shape.type !== 'marker') {
+					if (shiftKeyPressed == false) {
+						if (e == undefined) {
+							clearSelection();
+							shape.setEditable(true);
+						}
+					}
+					if (selectedShapes.includes(shape)) {
+					
+						shape.setEditable(false);
+						const index = selectedShapes.indexOf(shape);
+						selectedShapes.splice(index, 1);	
+					} else {
+						shape.setEditable(true);
+						selectedShapes.push(shape);
+					}
+	
+					if (debug) {
+						console.log(" len = " + selectedShapes.length);
+					}
+					//Send the values to be updated
+					var thi = shape.strokeWeight;
+					var opa = shape.fillOpacity;
+					var fCol = shape.fillColor;
+					var sCol = shape.strokeColor;
+					updateMenuValues(thi, opa, fCol, sCol);
+
+				} else if (shape.type == 'marker') {
+					clearSelection();
+				}
+
+				selectedShape = shape;
+			}
+
+			//Clears selection if clicked on the map when shift is not presseed
+			google.maps.event.addListener(map, 'click', function () {
+				if (shiftKeyPressed == false) {
+					clearSelection();
+				}
+			});
+
+			//Setting drawing tool option
+			document.addEventListener('keydown', function () {
+				//if (event.code == 'KeyX' && (event.ctrlKey || event.metaKey))
+				if (event.code == 'Digit0' || event.code == 'Numpad0' || event.code == 'Backquote') {
+					//clearSelection();
+					drawingManager.setDrawingMode(null);
+				} else if (event.code == 'Digit1') {
+					drawingManager.setDrawingMode('marker');
+				} else if (event.code == 'Digit2') {
+					drawingManager.setDrawingMode('circle');
+				} else if (event.code == 'Digit3') {
+					drawingManager.setDrawingMode('polygon');
+				} else if (event.code == 'Digit4') {
+					drawingManager.setDrawingMode('polyline');
+				} else if (event.code == 'Digit5') {
+					drawingManager.setDrawingMode('rectangle');
+				}
+				//					console.log(event.code);
+			});
+
+			//Sets shift as pressed
+			document.addEventListener('keydown', function () {
+				if (event.code == 'ShiftLeft' || event.code == 'ShiftRight') {
+					shiftKeyPressed = true;
+
+				}
+
+			});
+
+			//Sets shift as unpressed
+			document.addEventListener('keyup', function () {
+				if (event.code == 'ShiftLeft' || event.code == 'ShiftRight') {
+					shiftKeyPressed = false;
+				}
+
+			});
+
+			buildColorPalette();
+		}
+		//Set selected thickness
+		function setSelectedThickness(sWeight) {
+			if (selectedShape) {
+				//selectedShape.set('strokeWeight', sWeight)
+			}
+			if (selectedShapes !== 0) {
+				for (var i = 0; i < selectedShapes.length; i++) {
+					selectedShapes[i].set('strokeWeight', sWeight);
+					console.log(selectedShapes.length);
+				}
+			}
+		}
+
+		//Set selected opacity
+		function setSelectedOpacity(fOpacity) {
+			if (selectedShape) {
+				//selectedShape.set('fillOpacity', fOpacity)
+			}
+			if (selectedShapes !== 0) {
+				for (var i = 0; i < selectedShapes.length; i++) {
+					selectedShapes[i].set('fillOpacity', fOpacity);
+				}
+			}
+		}
+
+		//set selected fill colour
+		function setSelectedShapeColor(color) {
+			if (selectedShape) {
+				//if (selectedShape.type == google.maps.drawing.OverlayType.POLYLINE) {
+				//	selectedShape.set('strokeColor', color);
+				//} else {
+				//	selectedShape.set('fillColo`r', color);
+				//	selectedShape.set('strokeColor', color);
+				//}`
+			}
+			if (selectedShapes !== 0) {
+				for (var i = 0; i < selectedShapes.length; i++) {
+					selectedShapes[i].set('fillColor', color);
+					selectedShapes[i].set('strokeColor', color);
+				}
+			}
+		}
+
+		function updateMenuValues(thi, opa, fCol, sCol) {
+
+			//Update thickness slider and value on the settings menu
+			var thicknessSliderOutput = document.getElementById("thicknessRangeVal");
+			thicknessSliderOutput.innerHTML = thi;
+			document.getElementById("thicknessRange").value = thi * 20;
+
+			//Update the opacity slider and value on the settings menu
+			var opacitySliderOutput = document.getElementById("opacityRangeVal");
+			opacitySliderOutput.innerHTML = "% " + opa * 100;
+			document.getElementById("colourOpacity").value = opa * 100;
+
+			if (drawingManager.drawingMode == null) {
+				selectColor(fCol);
+			}
+		}
+		function undoMovement() {
+
+			
+			var lastItem = prevLog[prevLog.length - 1];
+			
+			if (prevLog.length !== 0) {
+				if (prevLog[prevLog.length - 1].length > 1){
+				
+					nextLog.push(lastItem);
+					selectedShape.setPath(lastItem);
+					undoPressed = false;
+					undoPressed = 0;
+					prevLog.pop();
+					
+					console.log(prevLog);
+				} else {
+				
+					nextLog.push(lastItem[0]);
+					selectedShape.setBounds(lastItem[0]);
+					undoPressed = false;
+					undoPressed = 0;
+					prevLog.pop();
+					
+					console.log("Prev Array", prevLog);
+					//console.log(prevEdge);
+					console.log(lastItem[0]);
+					//console.log(lastItem[prevLog.length - 1]);
+				}
+			} 
+			
+
+		}
+
+		function redoMovement() {
+
+			if (selectedShape) {
+				var lastItem = nextLog[nextLog.length - 1];
+				var secondToLastItem = nextLog[nextLog.length - 2];
+
+				if (nextLog.length > 1) {
+					prevLog.push(lastItem);
+
+					if (undoPressed >= 2) {
+						selectedShape.setPath(lastItem);
+					} else {
+						selectedShape.setPath(secondToLastItem);
+						undoPressed++;
+					}
+					undoPressed = false;
+					redoPressed = true;
+					nextLog.pop();
+				}
+			}
+		}
+
+		function polygonGetPath() {
+			
+			console.log(selectedShapes.length);
+
+		}
+
+		function deleteSelectedShape() {
+			for (var i = 0; i < selectedShapes.length; i++) {
+				selectedShapes[i].setMap(null);
+			}
+			selectedShapes = [];
+		}
+
+		function removeLine() {
+			var lastOverlay = overlays.pop();
+			if (lastOverlay)
+				lastOverlay.setMap(null);
+		}
+
+		function deleteAllShape() {
+			for (var i = 0; i < overlays.length; i++) {
+				overlays[i].setMap(null);
+
+			}
+			overlays = [];
+		}
+
+	</script>
+	<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyBzunGwIF2OwsfrOkIC_8bhh0OPGZXo52Y&libraries=drawing&callback=initMap" async defer></script>
+	<script src="shortcuts.js"></script>
+  </body>
+</html>
Index: /gs3-extensions/map-editor/DrawingManager/checkpoints-singlefile/index backup v15.html
===================================================================
--- /gs3-extensions/map-editor/DrawingManager/checkpoints-singlefile/index backup v15.html	(revision 32709)
+++ /gs3-extensions/map-editor/DrawingManager/checkpoints-singlefile/index backup v15.html	(revision 32709)
@@ -0,0 +1,662 @@
+<!DOCTYPE html>
+<html>
+  <head>
+	<title>Drawing Tools</title>
+	<meta name="viewport" content="initial-scale=1.0, user-scalable=no">
+	<meta charset="utf-8">
+	<style>
+	  /* Always set the map height explicitly to define the size of the div
+	   * element that contains the map. */
+	  #map {
+		height: 83%;
+		width: 90;
+		float: bottom;
+		clear: both;
+	  }
+	  /* Optional: Makes the sample page fill the window. */
+	  html, body {
+		height: 100%;
+		width: 99%;
+		margin: 0;
+		padding: 0;
+
+	  }
+	  
+	  #DeleteButtons{
+	  display: inline-block;
+	  float: left;
+	  padding-left: 10px;
+	  padding-top: 5px;
+	  width: 100%
+
+	  }
+	  
+	  #LineThickness{
+	  display: inline-block;
+	  float: left;
+	  padding-left: 10px;
+	  padding-top: 5px;
+
+	  }
+	  
+	  #ColourOpacity{
+	  display: inline-block;
+	  float: left;
+	  padding-left: 10px;
+	  padding-top: 5px;
+
+	  }
+	  
+	  #buttons3{
+	  display: inline-block;
+	  float: left;
+	  padding-left: 10px;
+	  padding-top: 5px;
+
+	  }	  
+	  
+      #FillColour {
+	  display: inline-block;
+	  float: left;
+	  padding-left: 10px;
+	  padding-top: 5px;
+	  }
+	  
+      #color-palette1 {
+      clear: both;
+      }
+	  
+      .color-buttons1 {
+      width: 14px;
+      height: 14px;
+      font-size: 0;
+      margin: 2px;
+      float: left;
+      cursor: pointer;
+      }
+
+
+	</style>
+  </head>
+  <body>
+	<div id = "DeleteButtons">
+	<button onclick="removeLine()" accesskey="z">Delete Last</button>
+	<button onclick="deleteAllShape()" accesskey="c">Clear All</button>
+	<button onclick="deleteSelectedShape()" accesskey="b">Delete Selected</button>
+	<button onclick="polygonGetPath()" accesskey="n">Get Path</button>
+	<button onclick="undoMovement()" accesskey="n">Undo</button>
+	<button onclick="redoMovement()" accesskey="n">Redo</button>
+	
+	</div>
+	
+	<div id = "LineThickness">
+	<p>Line thickness: <input type="range" min="20" max="100" value="1" class="slider" id="thicknessRange"> </p>
+	<p>Value: <span id="thicknessRangeVal"></span></p>
+	</div>	
+	
+	<div id = "ColourOpacity">
+	<p>Colour opacity: <input type="range" min="10" max="100" value="40" class="slider" id="colourOpacity"> </p>
+	<p>Value: <span id="opacityRangeVal"></span></p>
+	</div>
+	
+
+
+	<div id="FillColour">
+     <p> Fill Colour:</p> <div id="color-palette1"></div> 
+	</div>
+
+	
+	
+	<div id="map"></div>
+	
+	<script>
+		var debug = false;
+
+		var redoPressed = false;
+		var undoPressed = 0;
+		var shiftKeyPressed = false;
+		var mousedDownFired = false;
+
+		
+		//var coor = {east: 100, north: -50, south: 50, west:-100};
+		var prevEdge = {
+			east: "",
+			north: "",
+			south: "",
+			west: ""
+		}
+		var nextEdge = {
+			east: "",
+			north: "",
+			south: "",
+			west: ""
+		}
+		var prevVertex = {
+			lat: "",
+			lng: ""
+		};
+		var nextVertex = {
+			lat: "",
+			lng: ""
+		};
+		var prevShape = [];
+		var nextShape = [];
+		var prevLog = [];
+		var nextLog = [];
+		var dragged = 0;
+		var colors = ['#1E90FF', '#FF1493', '#4B0082', '#32CD32', '#FF8C00', '#000000'];
+		var selectedColor;
+		var colorButtons = {};
+		var thicknessValue = 1;
+		var opacityValue = 0.4;
+		var polyOptions = {
+			fillColor: '#CA4A2F',
+			strokeWeight: thicknessValue,
+			fillOpacity: opacityValue,
+			editable: true,
+			draggable: true,
+			geodesic: false,
+		};
+
+		var overlays = [];
+		var drawingManager;
+		var selectedShape;
+		var selectedShapes = [];
+		
+
+		//Update thickness
+		var thicknessSlider = document.getElementById("thicknessRange");
+		var thicknessSliderOutput = document.getElementById("thicknessRangeVal");
+		thicknessSliderOutput.innerHTML = thicknessSlider.value / 20;
+
+		thicknessSlider.oninput = function () {
+			thicknessSliderOutput.innerHTML = this.value / 20;
+			thicknessValue = this.value / 20;
+			polyOptions.strokeWeight = thicknessValue;
+			setSelectedThickness(thicknessValue);
+		}
+
+		//Update opacity
+		var opacitySlider = document.getElementById("colourOpacity");
+		var opacitySliderOutput = document.getElementById("opacityRangeVal");
+		opacitySliderOutput.innerHTML = "% " + Math.round(opacitySlider.value);
+
+		opacitySlider.oninput = function () {
+			opacityValue = this.value / 100;
+			polyOptions.fillOpacity = opacityValue;
+			opacitySliderOutput = opacityValue;
+			opacityRangeVal.innerHTML = "% " + Math.round(opacitySliderOutput * 100);
+			setSelectedOpacity(opacityValue);
+		}
+
+		////////////////////////////////////////////////////////////////////////////////////////
+		function makeColorButton(color) {
+			var button = document.createElement('span');
+			button.className = 'color-buttons1';
+			button.style.backgroundColor = color;
+			google.maps.event.addDomListener(button, 'click', function () {
+				selectColor(color);
+				setSelectedShapeColor(color);
+			});
+			return button;
+		}
+		function buildColorPalette() {
+			var colorPalette = document.getElementById('color-palette1');
+			for (var i = 0; i < colors.length; ++i) {
+				var currColor = colors[i];
+				var colorButton = makeColorButton(currColor);
+				colorPalette.appendChild(colorButton);
+				colorButtons[currColor] = colorButton;
+			}
+			selectColor(colors[0]);
+		};
+		function selectColor(color) {
+			selectedColor = color;
+			for (var i = 0; i < colors.length; ++i) {
+				var currColor = colors[i];
+				colorButtons[currColor].style.border = currColor == color ? '2px solid #789' : '2px solid #fff';
+			}
+
+			// Retrieves the current options from the drawing manager and replaces the
+			// stroke or fill color as appropriate.
+			var polylineOptions = drawingManager.get('polylineOptions');
+			polylineOptions.strokeColor = color;
+			drawingManager.set('polylineOptions', polylineOptions);
+
+			var rectangleOptions = drawingManager.get('rectangleOptions');
+			rectangleOptions.fillColor = color;
+			drawingManager.set('rectangleOptions', rectangleOptions);
+
+			var circleOptions = drawingManager.get('circleOptions');
+			circleOptions.fillColor = color;
+			drawingManager.set('circleOptions', circleOptions);
+
+			var polygonOptions = drawingManager.get('polygonOptions');
+			polygonOptions.fillColor = color;
+			drawingManager.set('polygonOptions', polygonOptions);
+		}
+
+		function initMap() {
+
+			var map = new google.maps.Map(document.getElementById('map'), {
+					center: {
+						lat: -34.397,
+						lng: 150.644
+					},
+					zoom: 2,
+					//mapTypeId: 'map'
+
+				});
+
+			drawingManager = new google.maps.drawing.DrawingManager({
+					drawingMode: google.maps.drawing.OverlayType.RECTANGLE,
+					drawingControl: true,
+					drawingControlOptions: {
+						position: google.maps.ControlPosition.TOP_CENTER,
+						drawingModes: ['marker', 'circle', 'polygon', 'polyline', 'rectangle']
+					},
+					markerOptions: {
+						draggable: true
+					},
+					circleOptions: polyOptions,
+					polylineOptions: polyOptions,
+					polygonOptions: polyOptions,
+					rectangleOptions: polyOptions,
+				});
+
+			drawingManager.setMap(map);
+
+			//overlays.push(event.overlay); // store reference to added overlay
+			google.maps.event.addListener(drawingManager, 'overlaycomplete', function (e) {
+				overlays.push(e.overlay); // store reference to added overlay
+				var newShape = e.overlay;
+				newShape.type = e.type;
+
+				if (e.type !== google.maps.drawing.OverlayType.MARKER) {
+
+					// Switch back to non-drawing mode after drawing a shape.
+					//drawingManager.setDrawingMode(null);
+
+					// Add an event listener that selects the newly-drawn shape when the user
+					// mouses down on it.
+					google.maps.event.addListener(newShape, 'click', function (e) {
+
+						vertexAndPolyDel(e, newShape);
+						mousedDownFired = false;
+						return;
+
+					});
+
+					//Stores past event information
+					google.maps.event.addListener(newShape, 'dragstart', function () {
+						//console.log("Drag Start");
+						if (selectedShape) {
+							var polyG = newShape.type === google.maps.drawing.OverlayType.POLYLINE;
+							var polyL = newShape.type === google.maps.drawing.OverlayType.POLYGON;
+							
+							if (polyL || polyG) {
+								var lati,
+								lngi;
+								for (var i = 0; i < selectedShape.getPath().length; i++) {
+									lati = selectedShape.getPath().getAt(i).lat();
+									lngi = selectedShape.getPath().getAt(i).lng();
+									//console.log("Vertex number",i, "'s latitude is", lati, "and longitude is", lngi);
+									prevVertex = {
+										lat: lati,
+										lng: lngi
+									};
+									prevShape.push(prevVertex);
+								}
+							} else {
+								//east is: ea.l
+								//north is: la.l
+								//southt is: la.j
+								//west is: ea.j
+								prevEdge = {
+									east: selectedShape.getBounds().ea.l,
+									north: selectedShape.getBounds().la.l,
+									south: selectedShape.getBounds().la.j,
+									west: selectedShape.getBounds().ea.j
+								}
+							
+								
+							
+								prevShape.push(prevEdge);
+								console.log(prevShape);
+								
+							}
+							
+					
+							
+							prevLog.push(prevShape);
+							console.log(JSON.stringify(prevLog));
+							prevShape = [];
+							nextLog = [];
+							//console.log("Prev Array ", prevLog);
+							//console.log("Next Array Length",nextLog.length);
+						}
+					});
+
+					//Store information after the event ends
+					google.maps.event.addListener(newShape, 'dragend', function () {
+						//console.log("Drag End");
+						if (selectedShape) {
+							var polyG = newShape.type === google.maps.drawing.OverlayType.POLYLINE;
+							var polyL = newShape.type === google.maps.drawing.OverlayType.POLYGON;
+							
+							if (polyL || polyG) {						
+								var lati,
+								lngi;
+	
+								for (var i = 0; i < selectedShape.getPath().length; i++) {
+									lati = selectedShape.getPath().getAt(i).lat();
+									lngi = selectedShape.getPath().getAt(i).lng();
+									//console.log("Vertex number",i, "'s latitude is", lati, "and longitude is", lngi);
+									nextVertex = {
+										lat: lati,
+										lng: lngi
+									};
+									nextShape.push(nextVertex);
+								}
+							} else {
+
+								nextEdge.east = selectedShape.getBounds().ea.l;
+								nextEdge.north = selectedShape.getBounds().la.l;
+								nextEdge.south = selectedShape.getBounds().la.j;
+								nextEdge.west = selectedShape.getBounds().ea.j;
+								
+								nextShape.push(nextEdge);
+							}
+							
+							nextLog.push(nextShape);
+							nextShape = [];
+							//console.log("Prev Array Length",prevLog.length);
+							//console.log("Next Array Length",nextLog.length);
+						}
+					});
+
+					//Add an event listener to select a shape if the mouse hovers over it
+					google.maps.event.addListener(newShape, 'mousedown', function (e) {
+						if (drawingManager.drawingMode == null) {
+							mousedDownFired = true;
+							//							console.log("MOUSDOWN ", e);
+
+							setSelection(newShape);
+						}
+					});
+					setSelection(newShape);
+				} else {
+					//cLICK EVENT IF A MARKER IS CREATED
+					google.maps.event.addListener(newShape, 'click', function (e) {
+						setSelection(newShape);
+					});
+					setSelection(newShape);
+				}
+			});
+
+			//Deletes a vertex if clicked on it
+			function vertexAndPolyDel(e, newShape) {
+				var vertex = e.vertex;
+				if (e.vertex !== undefined) {
+					if (newShape.type === google.maps.drawing.OverlayType.POLYGON) {
+						var path = newShape.getPaths().getAt(e.path);
+						path.removeAt(e.vertex);
+						if (path.length < 3) {
+							newShape.setMap(null);
+						}
+					}
+					if (newShape.type === google.maps.drawing.OverlayType.POLYLINE) {
+						var path = newShape.getPath();
+						path.removeAt(e.vertex);
+						if (path.length < 2) {
+							newShape.setMap(null);
+						}
+					}
+				}
+
+				//if(mousedDownFired == false)
+				//{
+				//setSelection(newShape, vertex);
+				//mousedDownFired = false;
+				//return;
+				//}
+			}
+
+			function clearSelection() {
+				if (selectedShape) {
+					if (selectedShape.type !== 'marker') {
+						selectedShape.setEditable(false);
+						if (shiftKeyPressed == false) {
+							for (var i = 0; i < selectedShapes.length; i++) {
+								selectedShapes[i].setEditable(false);
+							}
+							selectedShapes = [];
+						}
+					}
+
+					selectedShape = null;
+				}
+			}
+			var i = 0;
+			
+			//Set selection for the selected overlay
+			function setSelection(shape, e) {
+				
+
+				if (shape.type !== 'marker') {
+					if (shiftKeyPressed == false) {
+						if (e == undefined) {
+							clearSelection();
+							shape.setEditable(true);
+						}
+					}
+					if (selectedShapes.includes(shape)) {
+					
+						shape.setEditable(false);
+						const index = selectedShapes.indexOf(shape);
+						selectedShapes.splice(index, 1);	
+					} else {
+						shape.setEditable(true);
+						selectedShapes.push(shape);
+					}
+	
+					if (debug) {
+						console.log(" len = " + selectedShapes.length);
+					}
+					//Send the values to be updated
+					var thi = shape.strokeWeight;
+					var opa = shape.fillOpacity;
+					var fCol = shape.fillColor;
+					var sCol = shape.strokeColor;
+					updateMenuValues(thi, opa, fCol, sCol);
+
+				} else if (shape.type == 'marker') {
+					clearSelection();
+				}
+
+				selectedShape = shape;
+			}
+
+			//Clears selection if clicked on the map when shift is not presseed
+			google.maps.event.addListener(map, 'click', function () {
+				if (shiftKeyPressed == false) {
+					clearSelection();
+				}
+			});
+
+			//Setting drawing tool option
+			document.addEventListener('keydown', function () {
+				//if (event.code == 'KeyX' && (event.ctrlKey || event.metaKey))
+				if (event.code == 'Digit0' || event.code == 'Numpad0' || event.code == 'Backquote') {
+					//clearSelection();
+					drawingManager.setDrawingMode(null);
+				} else if (event.code == 'Digit1') {
+					drawingManager.setDrawingMode('marker');
+				} else if (event.code == 'Digit2') {
+					drawingManager.setDrawingMode('circle');
+				} else if (event.code == 'Digit3') {
+					drawingManager.setDrawingMode('polygon');
+				} else if (event.code == 'Digit4') {
+					drawingManager.setDrawingMode('polyline');
+				} else if (event.code == 'Digit5') {
+					drawingManager.setDrawingMode('rectangle');
+				}
+				//					console.log(event.code);
+			});
+
+			//Sets shift as pressed
+			document.addEventListener('keydown', function () {
+				if (event.code == 'ShiftLeft' || event.code == 'ShiftRight') {
+					shiftKeyPressed = true;
+
+				}
+
+			});
+
+			//Sets shift as unpressed
+			document.addEventListener('keyup', function () {
+				if (event.code == 'ShiftLeft' || event.code == 'ShiftRight') {
+					shiftKeyPressed = false;
+				}
+
+			});
+
+			buildColorPalette();
+		}
+		//Set selected thickness
+		function setSelectedThickness(sWeight) {
+			if (selectedShape) {
+				//selectedShape.set('strokeWeight', sWeight)
+			}
+			if (selectedShapes !== 0) {
+				for (var i = 0; i < selectedShapes.length; i++) {
+					selectedShapes[i].set('strokeWeight', sWeight);
+					console.log(selectedShapes.length);
+				}
+			}
+		}
+
+		//Set selected opacity
+		function setSelectedOpacity(fOpacity) {
+			if (selectedShape) {
+				//selectedShape.set('fillOpacity', fOpacity)
+			}
+			if (selectedShapes !== 0) {
+				for (var i = 0; i < selectedShapes.length; i++) {
+					selectedShapes[i].set('fillOpacity', fOpacity);
+				}
+			}
+		}
+
+		//set selected fill colour
+		function setSelectedShapeColor(color) {
+			if (selectedShape) {
+				//if (selectedShape.type == google.maps.drawing.OverlayType.POLYLINE) {
+				//	selectedShape.set('strokeColor', color);
+				//} else {
+				//	selectedShape.set('fillColo`r', color);
+				//	selectedShape.set('strokeColor', color);
+				//}`
+			}
+			if (selectedShapes !== 0) {
+				for (var i = 0; i < selectedShapes.length; i++) {
+					selectedShapes[i].set('fillColor', color);
+					selectedShapes[i].set('strokeColor', color);
+				}
+			}
+		}
+
+		function updateMenuValues(thi, opa, fCol, sCol) {
+
+			//Update thickness slider and value on the settings menu
+			var thicknessSliderOutput = document.getElementById("thicknessRangeVal");
+			thicknessSliderOutput.innerHTML = thi;
+			document.getElementById("thicknessRange").value = thi * 20;
+
+			//Update the opacity slider and value on the settings menu
+			var opacitySliderOutput = document.getElementById("opacityRangeVal");
+			opacitySliderOutput.innerHTML = "% " + opa * 100;
+			document.getElementById("colourOpacity").value = opa * 100;
+
+			if (drawingManager.drawingMode == null) {
+				selectColor(fCol);
+			}
+		}
+		function undoMovement() {
+
+			var lastItem = prevLog[prevLog.length - 1];
+			if (prevLog.length !== 0) {
+				//If the array has more than one index (polygons and polylines)
+				if (prevLog[prevLog.length - 1].length > 1){
+					nextLog.push(lastItem);
+					selectedShape.setPath(lastItem);
+
+				
+				//If the array has only one index(rectangles and circles)
+				} else {
+					nextLog.push(lastItem[0]);
+					selectedShape.setBounds(lastItem[0]);
+					
+				}
+			undoPressed = false;
+			undoPressed = 0;
+			prevLog.pop();
+			} 
+			
+
+		}
+
+		function redoMovement() {
+
+			if (prevLog.length !== 0) {
+				var lastItem = nextLog[nextLog.length - 1];
+				var secondToLastItem = nextLog[nextLog.length - 2];
+
+				if (nextLog.length > 1) {
+					prevLog.push(lastItem);
+
+					if (undoPressed >= 2) {
+						selectedShape.setPath(lastItem);
+					} else {
+						selectedShape.setPath(secondToLastItem);
+						undoPressed++;
+					}
+					undoPressed = false;
+					redoPressed = true;
+					nextLog.pop();
+				}
+			}
+		}
+
+		function polygonGetPath() {
+			
+			console.log(selectedShapes.length);
+
+		}
+
+		function deleteSelectedShape() {
+			for (var i = 0; i < selectedShapes.length; i++) {
+				selectedShapes[i].setMap(null);
+			}
+			selectedShapes = [];
+		}
+
+		function removeLine() {
+			var lastOverlay = overlays.pop();
+			if (lastOverlay)
+				lastOverlay.setMap(null);
+		}
+
+		function deleteAllShape() {
+			for (var i = 0; i < overlays.length; i++) {
+				overlays[i].setMap(null);
+
+			}
+			overlays = [];
+		}
+
+	</script>
+	<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyBzunGwIF2OwsfrOkIC_8bhh0OPGZXo52Y&libraries=drawing&callback=initMap" async defer></script>
+	<script src="shortcuts.js"></script>
+  </body>
+</html>
Index: /gs3-extensions/map-editor/DrawingManager/checkpoints-singlefile/index backup v16.html
===================================================================
--- /gs3-extensions/map-editor/DrawingManager/checkpoints-singlefile/index backup v16.html	(revision 32709)
+++ /gs3-extensions/map-editor/DrawingManager/checkpoints-singlefile/index backup v16.html	(revision 32709)
@@ -0,0 +1,694 @@
+<!DOCTYPE html>
+<html>
+  <head>
+	<title>Drawing Tools</title>
+	<meta name="viewport" content="initial-scale=1.0, user-scalable=no">
+	<meta charset="utf-8">
+	<style>
+	  /* Always set the map height explicitly to define the size of the div
+	   * element that contains the map. */
+	  #map {
+		height: 83%;
+		width: 90;
+		float: bottom;
+		clear: both;
+	  }
+	  /* Optional: Makes the sample page fill the window. */
+	  html, body {
+		height: 100%;
+		width: 99%;
+		margin: 0;
+		padding: 0;
+
+	  }
+	  
+	  #DeleteButtons{
+	  display: inline-block;
+	  float: left;
+	  padding-left: 10px;
+	  padding-top: 5px;
+	  width: 100%
+
+	  }
+	  
+	  #LineThickness{
+	  display: inline-block;
+	  float: left;
+	  padding-left: 10px;
+	  padding-top: 5px;
+
+	  }
+	  
+	  #ColourOpacity{
+	  display: inline-block;
+	  float: left;
+	  padding-left: 10px;
+	  padding-top: 5px;
+
+	  }
+	  
+	  #buttons3{
+	  display: inline-block;
+	  float: left;
+	  padding-left: 10px;
+	  padding-top: 5px;
+
+	  }	  
+	  
+      #FillColour {
+	  display: inline-block;
+	  float: left;
+	  padding-left: 10px;
+	  padding-top: 5px;
+	  }
+	  
+      #color-palette1 {
+      clear: both;
+      }
+	  
+      .color-buttons1 {
+      width: 14px;
+      height: 14px;
+      font-size: 0;
+      margin: 2px;
+      float: left;
+      cursor: pointer;
+      }
+
+
+	</style>
+  </head>
+  <body>
+	<div id = "DeleteButtons">
+	<button onclick="removeLine()" accesskey="z">Delete Last</button>
+	<button onclick="deleteAllShape()" accesskey="c">Clear All</button>
+	<button onclick="deleteSelectedShape()" accesskey="b">Delete Selected</button>
+	<button onclick="polygonGetPath()" accesskey="n">Get Path</button>
+	<button onclick="undoMovement()" accesskey="n">Undo</button>
+	<button onclick="redoMovement()" accesskey="n">Redo</button>
+	
+	</div>
+	
+	<div id = "LineThickness">
+	<p>Line thickness: <input type="range" min="20" max="100" value="1" class="slider" id="thicknessRange"> </p>
+	<p>Value: <span id="thicknessRangeVal"></span></p>
+	</div>	
+	
+	<div id = "ColourOpacity">
+	<p>Colour opacity: <input type="range" min="10" max="100" value="40" class="slider" id="colourOpacity"> </p>
+	<p>Value: <span id="opacityRangeVal"></span></p>
+	</div>
+	
+
+
+	<div id="FillColour">
+     <p> Fill Colour:</p> <div id="color-palette1"></div> 
+	</div>
+
+	
+	
+	<div id="map"></div>
+	
+	<script>
+		var debug = false;
+
+		var redoPressed = false;
+		var undoPressed = 0;
+		var shiftKeyPressed = false;
+		var mousedDownFired = false;
+
+		
+		var selectedShapesLog = {
+			_selectedShapes: "",
+			_shiftKeyPressed: ""
+			
+		}
+		var prevEdge = {
+			east: "",
+			north: "",
+			south: "",
+			west: ""
+		}
+		var nextEdge = {
+			east: "",
+			north: "",
+			south: "",
+			west: ""
+		}
+		var prevVertex = {
+			lat: "",
+			lng: ""
+		};
+		var nextVertex = {
+			lat: "",
+			lng: ""
+		};
+		var prevShape = [];
+		var nextShape = [];
+		var prevLog = [];
+		var nextLog = [];
+		var dragged = 0;
+		var colors = ['#1E90FF', '#FF1493', '#4B0082', '#32CD32', '#FF8C00', '#000000'];
+		var selectedColor;
+		var colorButtons = {};
+		var thicknessValue = 1;
+		var opacityValue = 0.4;
+		var polyOptions = {
+			fillColor: '#CA4A2F',
+			strokeWeight: thicknessValue,
+			fillOpacity: opacityValue,
+			editable: true,
+			draggable: true,
+			geodesic: false,
+		};
+
+		var overlays = [];
+		var drawingManager;
+		var selectedShape;
+		var selectedShapes = [];
+		
+
+		//Update thickness
+		var thicknessSlider = document.getElementById("thicknessRange");
+		var thicknessSliderOutput = document.getElementById("thicknessRangeVal");
+		thicknessSliderOutput.innerHTML = thicknessSlider.value / 20;
+
+		thicknessSlider.oninput = function () {
+			thicknessSliderOutput.innerHTML = this.value / 20;
+			thicknessValue = this.value / 20;
+			polyOptions.strokeWeight = thicknessValue;
+			setSelectedThickness(thicknessValue);
+		}
+
+		//Update opacity
+		var opacitySlider = document.getElementById("colourOpacity");
+		var opacitySliderOutput = document.getElementById("opacityRangeVal");
+		opacitySliderOutput.innerHTML = "% " + Math.round(opacitySlider.value);
+
+		opacitySlider.oninput = function () {
+			opacityValue = this.value / 100;
+			polyOptions.fillOpacity = opacityValue;
+			opacitySliderOutput = opacityValue;
+			opacityRangeVal.innerHTML = "% " + Math.round(opacitySliderOutput * 100);
+			setSelectedOpacity(opacityValue);
+		}
+
+		////////////////////////////////////////////////////////////////////////////////////////
+		function makeColorButton(color) {
+			var button = document.createElement('span');
+			button.className = 'color-buttons1';
+			button.style.backgroundColor = color;
+			google.maps.event.addDomListener(button, 'click', function () {
+				selectColor(color);
+				setSelectedShapeColor(color);
+			});
+			return button;
+		}
+		function buildColorPalette() {
+			var colorPalette = document.getElementById('color-palette1');
+			for (var i = 0; i < colors.length; ++i) {
+				var currColor = colors[i];
+				var colorButton = makeColorButton(currColor);
+				colorPalette.appendChild(colorButton);
+				colorButtons[currColor] = colorButton;
+			}
+			selectColor(colors[0]);
+		};
+		function selectColor(color) {
+			selectedColor = color;
+			for (var i = 0; i < colors.length; ++i) {
+				var currColor = colors[i];
+				colorButtons[currColor].style.border = currColor == color ? '2px solid #789' : '2px solid #fff';
+			}
+
+			// Retrieves the current options from the drawing manager and replaces the
+			// stroke or fill color as appropriate.
+			var polylineOptions = drawingManager.get('polylineOptions');
+			polylineOptions.strokeColor = color;
+			drawingManager.set('polylineOptions', polylineOptions);
+
+			var rectangleOptions = drawingManager.get('rectangleOptions');
+			rectangleOptions.fillColor = color;
+			drawingManager.set('rectangleOptions', rectangleOptions);
+
+			var circleOptions = drawingManager.get('circleOptions');
+			circleOptions.fillColor = color;
+			drawingManager.set('circleOptions', circleOptions);
+
+			var polygonOptions = drawingManager.get('polygonOptions');
+			polygonOptions.fillColor = color;
+			drawingManager.set('polygonOptions', polygonOptions);
+		}
+
+		function initMap() {
+
+			var map = new google.maps.Map(document.getElementById('map'), {
+					center: {
+						lat: -34.397,
+						lng: 150.644
+					},
+					zoom: 2,
+					//mapTypeId: 'map'
+
+				});
+
+			drawingManager = new google.maps.drawing.DrawingManager({
+					drawingMode: google.maps.drawing.OverlayType.RECTANGLE,
+					drawingControl: true,
+					drawingControlOptions: {
+						position: google.maps.ControlPosition.TOP_CENTER,
+						drawingModes: ['marker', 'circle', 'polygon', 'polyline', 'rectangle']
+					},
+					markerOptions: {
+						draggable: true
+					},
+					circleOptions: polyOptions,
+					polylineOptions: polyOptions,
+					polygonOptions: polyOptions,
+					rectangleOptions: polyOptions,
+				});
+
+			drawingManager.setMap(map);
+
+			//overlays.push(event.overlay); // store reference to added overlay
+			google.maps.event.addListener(drawingManager, 'overlaycomplete', function (e) {
+				overlays.push(e.overlay); // store reference to added overlay
+				var newShape = e.overlay;
+				newShape.type = e.type;
+
+				if (e.type !== google.maps.drawing.OverlayType.MARKER) {
+
+					// Switch back to non-drawing mode after drawing a shape.
+					//drawingManager.setDrawingMode(null);
+
+					// Add an event listener that selects the newly-drawn shape when the user
+					// mouses down on it.
+					google.maps.event.addListener(newShape, 'click', function (e) {
+
+						vertexAndPolyDel(e, newShape);
+						mousedDownFired = false;
+						return;
+
+					});
+
+					//Stores past event information
+					google.maps.event.addListener(newShape, 'dragstart', function () {
+						//console.log("Drag Start");
+						if (selectedShape) {
+							var polyG = newShape.type === google.maps.drawing.OverlayType.POLYLINE;
+							var polyL = newShape.type === google.maps.drawing.OverlayType.POLYGON;
+							
+							if (polyL || polyG) {
+								var lati,
+								lngi;
+								for (var i = 0; i < selectedShape.getPath().length; i++) {
+									lati = selectedShape.getPath().getAt(i).lat();
+									lngi = selectedShape.getPath().getAt(i).lng();
+									//console.log("Vertex number",i, "'s latitude is", lati, "and longitude is", lngi);
+									prevVertex = {
+										lat: lati,
+										lng: lngi
+									};
+									prevShape.push(prevVertex);
+								}
+							} else {
+								//east is: ea.l
+								//north is: la.l
+								//southt is: la.j
+								//west is: ea.j
+								prevEdge = {
+									east: selectedShape.getBounds().ea.l,
+									north: selectedShape.getBounds().la.l,
+									south: selectedShape.getBounds().la.j,
+									west: selectedShape.getBounds().ea.j
+								}
+							
+								
+							
+								prevShape.push(prevEdge);
+								console.log(prevShape);
+								
+							}
+							
+					
+							
+							prevLog.push(prevShape);
+//							console.log(JSON.stringify(prevLog));
+							console.log(prevLog);
+							prevShape = [];
+							nextLog = [];
+							//console.log("Prev Array ", prevLog);
+							//console.log("Next Array Length",nextLog.length);
+						}
+					});
+
+					//Store information after the event ends
+					google.maps.event.addListener(newShape, 'dragend', function () {
+						//console.log("Drag End");
+						if (selectedShape) {
+							var polyG = newShape.type === google.maps.drawing.OverlayType.POLYLINE;
+							var polyL = newShape.type === google.maps.drawing.OverlayType.POLYGON;
+							
+							if (polyL || polyG) {						
+								var lati,
+								lngi;
+	
+								for (var i = 0; i < selectedShape.getPath().length; i++) {
+									lati = selectedShape.getPath().getAt(i).lat();
+									lngi = selectedShape.getPath().getAt(i).lng();
+									//console.log("Vertex number",i, "'s latitude is", lati, "and longitude is", lngi);
+									nextVertex = {
+										lat: lati,
+										lng: lngi
+									};
+									nextShape.push(nextVertex);
+								}
+							} else {
+
+								nextEdge.east = selectedShape.getBounds().ea.l;
+								nextEdge.north = selectedShape.getBounds().la.l;
+								nextEdge.south = selectedShape.getBounds().la.j;
+								nextEdge.west = selectedShape.getBounds().ea.j;
+								
+								nextShape.push(nextEdge);
+							}
+							
+							nextLog.push(nextShape);
+							nextShape = [];
+							//console.log("Prev Array Length",prevLog.length);
+							//console.log("Next Array Length",nextLog.length);
+						}
+					});
+
+					//Add an event listener to select a shape if the mouse hovers over it
+					google.maps.event.addListener(newShape, 'mousedown', function (e) {
+						if (drawingManager.drawingMode == null) {
+							mousedDownFired = true;
+							//							console.log("MOUSDOWN ", e);
+
+							setSelection(newShape, e);
+						}
+					});
+					setSelection(newShape, e);
+				} else {
+					//cLICK EVENT IF A MARKER IS CREATED
+					google.maps.event.addListener(newShape, 'click', function (e) {
+						setSelection(newShape, e);
+					});
+					setSelection(newShape, e);
+				}
+			});
+
+			//Deletes a vertex if clicked on it
+			function vertexAndPolyDel(e, newShape) {
+				var vertex = e.vertex;
+				
+				if (e.vertex !== undefined) {
+					if (newShape.type === google.maps.drawing.OverlayType.POLYGON) {
+						var path = newShape.getPaths().getAt(e.path);
+						path.removeAt(e.vertex);
+						if (path.length < 3) {
+							newShape.setMap(null);
+						}
+					}
+					if (newShape.type === google.maps.drawing.OverlayType.POLYLINE) {
+						var path = newShape.getPath();
+						path.removeAt(e.vertex);
+						if (path.length < 2) {
+							newShape.setMap(null);
+						}
+					}
+				}
+
+				//if(mousedDownFired == false)
+				//{
+				//setSelection(newShape, vertex);
+				//mousedDownFired = false;
+				//return;
+				//}
+			}
+
+			function clearSelection() {
+				if (selectedShape) {
+					if (selectedShape.type !== 'marker') {
+						selectedShape.setEditable(false);
+						if (shiftKeyPressed == false) {
+							for (var i = 0; i < selectedShapes.length; i++) {
+								selectedShapes[i].setEditable(false);
+							}
+							selectedShapes = [];
+						}
+					}
+
+					selectedShape = null;
+				}
+			}
+			var i = 0;
+			
+			//Set selection for the selected overlay
+			function setSelection(shape, e) {
+				if (shape.type !== 'marker') {
+					if (shiftKeyPressed == false) {
+						if (e.vertex == undefined) {
+							clearSelection();
+							shape.setEditable(true);
+						}
+					}
+					if (selectedShapes.includes(shape)) {
+					
+						//shape.setEditable(false);
+						const index = selectedShapes.indexOf(shape);
+						selectedShapes.splice(index, 1);	
+					} else {
+						shape.setEditable(true);
+						selectedShapes.push(shape);
+					}
+	
+					if (debug) {
+						console.log(" len = " + selectedShapes.length);
+					}
+					//Send the values to be updated
+					var thi = shape.strokeWeight;
+					var opa = shape.fillOpacity;
+					var fCol = shape.fillColor;
+					var sCol = shape.strokeColor;
+					updateMenuValues(thi, opa, fCol, sCol);
+
+				} else if (shape.type == 'marker') {
+					clearSelection();
+				}
+
+				selectedShape = shape;
+				
+				selectedShapesLog = {
+				_selectedShapes: selectedShapes,
+				_shiftKeyPressed: shiftKeyPressed
+				}
+				
+				//prevLog.push(selectedShapesLog);
+
+			}
+
+			//Clears selection if clicked on the map when shift is not presseed
+			google.maps.event.addListener(map, 'click', function () {
+				if (shiftKeyPressed == false) {
+					clearSelection();
+				}
+			});
+
+			//Setting drawing tool option
+			document.addEventListener('keydown', function () {
+				//if (event.code == 'KeyX' && (event.ctrlKey || event.metaKey))
+				if (event.code == 'Digit0' || event.code == 'Numpad0' || event.code == 'Backquote') {
+					//clearSelection();
+					drawingManager.setDrawingMode(null);
+				} else if (event.code == 'Digit1') {
+					drawingManager.setDrawingMode('marker');
+				} else if (event.code == 'Digit2') {
+					drawingManager.setDrawingMode('circle');
+				} else if (event.code == 'Digit3') {
+					drawingManager.setDrawingMode('polygon');
+				} else if (event.code == 'Digit4') {
+					drawingManager.setDrawingMode('polyline');
+				} else if (event.code == 'Digit5') {
+					drawingManager.setDrawingMode('rectangle');
+				}
+				//					console.log(event.code);
+			});
+
+			//Sets shift as pressed
+			document.addEventListener('keydown', function () {
+				if (event.code == 'ShiftLeft' || event.code == 'ShiftRight') {
+					shiftKeyPressed = true;
+
+				}
+
+			});
+
+			//Sets shift as unpressed
+			document.addEventListener('keyup', function () {
+				if (event.code == 'ShiftLeft' || event.code == 'ShiftRight') {
+					shiftKeyPressed = false;
+				}
+
+			});
+
+			buildColorPalette();
+		}
+		//Set selected thickness
+		function setSelectedThickness(sWeight) {
+			if (selectedShape) {
+				//selectedShape.set('strokeWeight', sWeight)
+			}
+			if (selectedShapes !== 0) {
+				for (var i = 0; i < selectedShapes.length; i++) {
+					selectedShapes[i].set('strokeWeight', sWeight);
+					//console.log(selectedShapes.length);
+				}
+			}
+		}
+
+		//Set selected opacity
+		function setSelectedOpacity(fOpacity) {
+			if (selectedShape) {
+				//selectedShape.set('fillOpacity', fOpacity)
+			}
+			if (selectedShapes !== 0) {
+				for (var i = 0; i < selectedShapes.length; i++) {
+					selectedShapes[i].set('fillOpacity', fOpacity);
+				}
+			}
+		}
+
+		//set selected fill colour
+		function setSelectedShapeColor(color) {
+			if (selectedShapes !== 0) {
+				for (var i = 0; i < selectedShapes.length; i++) {
+					selectedShapes[i].set('fillColor', color);
+					selectedShapes[i].set('strokeColor', color);
+				}
+			}
+		}
+
+		function updateMenuValues(thi, opa, fCol, sCol) {
+
+			//Update thickness slider and value on the settings menu
+			var thicknessSliderOutput = document.getElementById("thicknessRangeVal");
+			thicknessSliderOutput.innerHTML = thi;
+			document.getElementById("thicknessRange").value = thi * 20;
+
+			//Update the opacity slider and value on the settings menu
+			var opacitySliderOutput = document.getElementById("opacityRangeVal");
+			opacitySliderOutput.innerHTML = "% " + opa * 100;
+			document.getElementById("colourOpacity").value = opa * 100;
+
+			if (drawingManager.drawingMode == null) {
+				selectColor(fCol);
+			}
+		}
+		function undoMovement() {
+
+			var lastItem = prevLog[prevLog.length - 1];
+			if (prevLog.length !== 0) {
+				//If the array has more than one index (polygons and polylines)
+				if (prevLog[prevLog.length - 1].length > 1){
+					nextLog.push(lastItem);
+					selectedShape.setPath(lastItem);
+
+				
+				//If the array has only one index(rectangles and circles)
+				} else {
+					nextLog.push(lastItem);
+					selectedShape.setBounds(lastItem[0]);
+					
+				}
+			undoPressed = false;
+			undoPressed = 0;
+			prevLog.pop();
+			} 
+			
+
+		}
+
+		function redoMovement() {
+			//var overlayType = prevLog[(prevLog.length - 1)]._selectedShapes[0].type;
+			var lastItem = nextLog[nextLog.length - 1];
+			var secondToLastItem = nextLog[nextLog.length - 2];
+			var correctIndex;
+			if (undoPressed >= 2) {
+				correctIndex == lastItem;
+			} else {
+				correctIndex == secondToLastItem;
+			}
+			
+			//If the history log is not empty
+			if (nextLog.length > 1) {
+				prevLog.push(lastItem);
+
+				//If undo has been pressed
+				if (undoPressed >= 2) {
+					if (nextLog[nextLog.length - 1].length > 1){
+						selectedShape.setPath(lastItem);
+					} else {
+						selectedShape.setBounds(lastItem[0]);
+					}
+				} else {
+					if (nextLog[nextLog.length - 1].length > 1){
+						selectedShape.setPath(secondToLastItem);
+					} else {
+						selectedShape.setBounds(secondToLastItem[0]);
+					}
+					
+					undoPressed++;
+				}
+				undoPressed = false;
+				redoPressed = true;
+				nextLog.pop();
+			}
+		}
+
+		function polygonGetPath() {
+			var overlayType = prevLog[(prevLog.length - 1)]._selectedShapes[0].type;
+			//console.log(prevLog);
+			//console.log(prevLog[(prevLog.length - 1)]._selectedShapes[0].type == polygon);
+			if(prevLog[(prevLog.length - 1)]._selectedShapes){
+			console.log(prevLog[(prevLog.length - 1)]._selectedShapes[0].type);
+				if (overlayType = ("circle" || "rectangle")) {
+				console.log("It's a "+ overlayType);
+				} else if (overlayType = ("polygon" || "polyline")){
+				console.log("It's a "+ overlayType);
+				}
+				
+			}
+
+
+
+
+		}
+
+		function deleteSelectedShape() {
+			for (var i = 0; i < selectedShapes.length; i++) {
+				selectedShapes[i].setMap(null);
+			}
+			selectedShapes = [];
+		}
+
+		function removeLine() {
+			var lastOverlay = overlays.pop();
+			if (lastOverlay)
+				lastOverlay.setMap(null);
+		}
+
+		function deleteAllShape() {
+			for (var i = 0; i < overlays.length; i++) {
+				overlays[i].setMap(null);
+
+			}
+			overlays = [];
+		}
+
+	</script>
+	<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyBzunGwIF2OwsfrOkIC_8bhh0OPGZXo52Y&libraries=drawing&callback=initMap" async defer></script>
+	<script src="shortcuts.js"></script>
+  </body>
+</html>
Index: /gs3-extensions/map-editor/DrawingManager/checkpoints-singlefile/index backup v17 x.html
===================================================================
--- /gs3-extensions/map-editor/DrawingManager/checkpoints-singlefile/index backup v17 x.html	(revision 32709)
+++ /gs3-extensions/map-editor/DrawingManager/checkpoints-singlefile/index backup v17 x.html	(revision 32709)
@@ -0,0 +1,690 @@
+<!DOCTYPE html>
+<html>
+  <head>
+	<title>Drawing Tools</title>
+	<meta name="viewport" content="initial-scale=1.0, user-scalable=no">
+	<meta charset="utf-8">
+	<style>
+	  /* Always set the map height explicitly to define the size of the div
+	   * element that contains the map. */
+	  #map {
+		height: 83%;
+		width: 90;
+		float: bottom;
+		clear: both;
+	  }
+	  /* Optional: Makes the sample page fill the window. */
+	  html, body {
+		height: 100%;
+		width: 99%;
+		margin: 0;
+		padding: 0;
+
+	  }
+	  
+	  #DeleteButtons{
+	  display: inline-block;
+	  float: left;
+	  padding-left: 10px;
+	  padding-top: 5px;
+	  width: 100%
+
+	  }
+	  
+	  #LineThickness{
+	  display: inline-block;
+	  float: left;
+	  padding-left: 10px;
+	  padding-top: 5px;
+
+	  }
+	  
+	  #ColourOpacity{
+	  display: inline-block;
+	  float: left;
+	  padding-left: 10px;
+	  padding-top: 5px;
+
+	  }
+	  
+	  #buttons3{
+	  display: inline-block;
+	  float: left;
+	  padding-left: 10px;
+	  padding-top: 5px;
+
+	  }	  
+	  
+      #FillColour {
+	  display: inline-block;
+	  float: left;
+	  padding-left: 10px;
+	  padding-top: 5px;
+	  }
+	  
+      #color-palette1 {
+      clear: both;
+      }
+	  
+      .color-buttons1 {
+      width: 14px;
+      height: 14px;
+      font-size: 0;
+      margin: 2px;
+      float: left;
+      cursor: pointer;
+      }
+
+
+	</style>
+  </head>
+  <body>
+	<div id = "DeleteButtons">
+	<button onclick="removeLine()" accesskey="z">Delete Last</button>
+	<button onclick="deleteAllShape()" accesskey="c">Clear All</button>
+	<button onclick="deleteSelectedShape()" accesskey="b">Delete Selected</button>
+	<button onclick="polygonGetPath()" accesskey="n">Get Path</button>
+	<button onclick="undoMovement()" accesskey="n">Undo</button>
+	<button onclick="redoMovement()" accesskey="n">Redo</button>
+	
+	</div>
+	
+	<div id = "LineThickness">
+	<p>Line thickness: <input type="range" min="20" max="100" value="1" class="slider" id="thicknessRange"> </p>
+	<p>Value: <span id="thicknessRangeVal"></span></p>
+	</div>	
+	
+	<div id = "ColourOpacity">
+	<p>Colour opacity: <input type="range" min="10" max="100" value="40" class="slider" id="colourOpacity"> </p>
+	<p>Value: <span id="opacityRangeVal"></span></p>
+	</div>
+	
+
+
+	<div id="FillColour">
+     <p> Fill Colour:</p> <div id="color-palette1"></div> 
+	</div>
+
+	
+	
+	<div id="map"></div>
+	
+	<script>
+		var debug = false;
+
+		var redoPressed = false;
+		var undoPressed = 0;
+		var shiftKeyPressed = false;
+		var mousedDownFired = false;
+
+		var shapesarray = [];
+		var selectedShapesLog = {
+			_selectedShapes: "",
+			_shiftKeyPressed: ""
+			
+		}
+		var prevShape = {
+			eventType: "",
+			shape: ""
+		}
+		var nextEdge = {
+			east: "",
+			north: "",
+			south: "",
+			west: ""
+		}
+		var prevVertex = {
+			lat: "",
+			lng: ""
+		};
+		var nextVertex = {
+			lat: "",
+			lng: ""
+		};
+		var coor = {
+			east: "",
+			north: "",
+			south: "",
+			west : ""
+		};
+		var nextShape = [];
+		var prevLog = [];
+		var nextLog = [];
+		var dragged = 0;
+		var colors = ['#1E90FF', '#FF1493', '#4B0082', '#32CD32', '#FF8C00', '#000000'];
+		var selectedColor;
+		var colorButtons = {};
+		var thicknessValue = 1;
+		var opacityValue = 0.4;
+		var polyOptions = {
+			fillColor: '#CA4A2F',
+			strokeWeight: thicknessValue,
+			fillOpacity: opacityValue,
+			editable: true,
+			draggable: true,
+			geodesic: false,
+		};
+
+		var overlays = [];
+		var drawingManager;
+		var selectedShape;
+		var selectedShapes = [];
+		
+
+		//Update thickness
+		var thicknessSlider = document.getElementById("thicknessRange");
+		var thicknessSliderOutput = document.getElementById("thicknessRangeVal");
+		thicknessSliderOutput.innerHTML = thicknessSlider.value / 20;
+
+		thicknessSlider.oninput = function () {
+			thicknessSliderOutput.innerHTML = this.value / 20;
+			thicknessValue = this.value / 20;
+			polyOptions.strokeWeight = thicknessValue;
+			setSelectedThickness(thicknessValue);
+		}
+
+		//Update opacity
+		var opacitySlider = document.getElementById("colourOpacity");
+		var opacitySliderOutput = document.getElementById("opacityRangeVal");
+		opacitySliderOutput.innerHTML = "% " + Math.round(opacitySlider.value);
+
+		opacitySlider.oninput = function () {
+			opacityValue = this.value / 100;
+			polyOptions.fillOpacity = opacityValue;
+			opacitySliderOutput = opacityValue;
+			opacityRangeVal.innerHTML = "% " + Math.round(opacitySliderOutput * 100);
+			setSelectedOpacity(opacityValue);
+		}
+
+		////////////////////////////////////////////////////////////////////////////////////////
+		function makeColorButton(color) {
+			var button = document.createElement('span');
+			button.className = 'color-buttons1';
+			button.style.backgroundColor = color;
+			google.maps.event.addDomListener(button, 'click', function () {
+				selectColor(color);
+				setSelectedShapeColor(color);
+			});
+			return button;
+		}
+		function buildColorPalette() {
+			var colorPalette = document.getElementById('color-palette1');
+			for (var i = 0; i < colors.length; ++i) {
+				var currColor = colors[i];
+				var colorButton = makeColorButton(currColor);
+				colorPalette.appendChild(colorButton);
+				colorButtons[currColor] = colorButton;
+			}
+			selectColor(colors[0]);
+		};
+		function selectColor(color) {
+			selectedColor = color;
+			for (var i = 0; i < colors.length; ++i) {
+				var currColor = colors[i];
+				colorButtons[currColor].style.border = currColor == color ? '2px solid #789' : '2px solid #fff';
+			}
+
+			// Retrieves the current options from the drawing manager and replaces the
+			// stroke or fill color as appropriate.
+			var polylineOptions = drawingManager.get('polylineOptions');
+			polylineOptions.strokeColor = color;
+			drawingManager.set('polylineOptions', polylineOptions);
+
+			var rectangleOptions = drawingManager.get('rectangleOptions');
+			rectangleOptions.fillColor = color;
+			drawingManager.set('rectangleOptions', rectangleOptions);
+
+			var circleOptions = drawingManager.get('circleOptions');
+			circleOptions.fillColor = color;
+			drawingManager.set('circleOptions', circleOptions);
+
+			var polygonOptions = drawingManager.get('polygonOptions');
+			polygonOptions.fillColor = color;
+			drawingManager.set('polygonOptions', polygonOptions);
+		}
+
+		function initMap() {
+
+			var map = new google.maps.Map(document.getElementById('map'), {
+					center: {
+						lat: -34.397,
+						lng: 150.644
+					},
+					zoom: 2,
+					//mapTypeId: 'map'
+
+				});
+
+			drawingManager = new google.maps.drawing.DrawingManager({
+					drawingMode: google.maps.drawing.OverlayType.RECTANGLE,
+					drawingControl: true,
+					drawingControlOptions: {
+						position: google.maps.ControlPosition.TOP_CENTER,
+						drawingModes: ['marker', 'circle', 'polygon', 'polyline', 'rectangle']
+					},
+					markerOptions: {
+						draggable: true
+					},
+					circleOptions: polyOptions,
+					polylineOptions: polyOptions,
+					polygonOptions: polyOptions,
+					rectangleOptions: polyOptions,
+				});
+
+			drawingManager.setMap(map);
+
+			//overlays.push(event.overlay); // store reference to added overlay
+			google.maps.event.addListener(drawingManager, 'overlaycomplete', function (e) {
+				overlays.push(e.overlay); // store reference to added overlay
+				var newShape = e.overlay;
+				newShape.type = e.type;
+
+				if (e.type !== google.maps.drawing.OverlayType.MARKER) {
+
+					// Switch back to non-drawing mode after drawing a shape.
+					//drawingManager.setDrawingMode(null);
+
+					// Add an event listener that selects the newly-drawn shape when the user
+					// mouses down on it.
+					google.maps.event.addListener(newShape, 'click', function (e) {
+
+						vertexAndPolyDel(e, newShape);
+						mousedDownFired = false;
+						return;
+
+					});
+
+					//Stores past event information
+					google.maps.event.addListener(newShape, 'dragstart', function () {
+						
+						
+						prevShape = {
+							eventType: "dragged",
+							shape: selectedShape
+						}
+						prevLog.push(prevShape);
+						//console.log(prevShape.shape.bounds);
+						prevShape = [];
+						nextLog = [];
+						//console.log(JSON.stringify(prevLog));
+						console.log(prevLog[0].shape.getBounds());
+						
+						
+						shapesarray.push(prevLog[prevLog.length-1].shape.getBounds());
+						console.log(JSON.stringify(shapesarray));
+						console.log(shapesarray.length);
+							
+							
+					});
+
+					//Store information after the event ends
+					google.maps.event.addListener(newShape, 'dragend', function () {
+						//console.log("Drag End");
+						if (selectedShape) {
+							var polyG = newShape.type === google.maps.drawing.OverlayType.POLYLINE;
+							var polyL = newShape.type === google.maps.drawing.OverlayType.POLYGON;
+							
+							if (polyL || polyG) {						
+								var lati,
+								lngi;
+	
+								for (var i = 0; i < selectedShape.getPath().length; i++) {
+									lati = selectedShape.getPath().getAt(i).lat();
+									lngi = selectedShape.getPath().getAt(i).lng();
+									//console.log("Vertex number",i, "'s latitude is", lati, "and longitude is", lngi);
+									nextVertex = {
+										lat: lati,
+										lng: lngi
+									};
+									nextShape.push(nextVertex);
+								}
+							} else {
+
+								nextEdge.east = selectedShape.getBounds().ea.l;
+								nextEdge.north = selectedShape.getBounds().la.l;
+								nextEdge.south = selectedShape.getBounds().la.j;
+								nextEdge.west = selectedShape.getBounds().ea.j;
+								
+								nextShape.push(nextEdge);
+							}
+							
+							
+							nextLog.push(nextShape);
+							console.log(JSON.stringify(nextShape));
+							nextShape = [];
+
+						}
+					});
+
+					//Add an event listener to select a shape if the mouse hovers over it
+					google.maps.event.addListener(newShape, 'mousedown', function (e) {
+						if (drawingManager.drawingMode == null) {
+							mousedDownFired = true;
+							//							console.log("MOUSDOWN ", e);
+
+							setSelection(newShape, e);
+						}
+					});
+					setSelection(newShape, e);
+				} else {
+					//cLICK EVENT IF A MARKER IS CREATED
+					google.maps.event.addListener(newShape, 'click', function (e) {
+						setSelection(newShape, e);
+					});
+					setSelection(newShape, e);
+				}
+			});
+
+			//Deletes a vertex if clicked on it
+			function vertexAndPolyDel(e, newShape) {
+				var vertex = e.vertex;
+				
+				if (e.vertex !== undefined) {
+					if (newShape.type === google.maps.drawing.OverlayType.POLYGON) {
+						var path = newShape.getPaths().getAt(e.path);
+						path.removeAt(e.vertex);
+						if (path.length < 3) {
+							newShape.setMap(null);
+						}
+					}
+					if (newShape.type === google.maps.drawing.OverlayType.POLYLINE) {
+						var path = newShape.getPath();
+						path.removeAt(e.vertex);
+						if (path.length < 2) {
+							newShape.setMap(null);
+						}
+					}
+				}
+
+				//if(mousedDownFired == false)
+				//{
+				//setSelection(newShape, vertex);
+				//mousedDownFired = false;
+				//return;
+				//}
+			}
+
+			function clearSelection() {
+				if (selectedShape) {
+					if (selectedShape.type !== 'marker') {
+						selectedShape.setEditable(false);
+						if (shiftKeyPressed == false) {
+							for (var i = 0; i < selectedShapes.length; i++) {
+								selectedShapes[i].setEditable(false);
+							}
+							selectedShapes = [];
+						}
+					}
+
+					selectedShape = null;
+				}
+			}
+			var i = 0;
+			
+			//Set selection for the selected overlay
+			function setSelection(shape, e) {
+				if (shape.type !== 'marker') {
+					if (shiftKeyPressed == false) {
+						if (e.vertex == undefined) {
+							clearSelection();
+							shape.setEditable(true);
+						}
+					}
+					if (selectedShapes.includes(shape)) {
+					
+						//shape.setEditable(false);
+						const index = selectedShapes.indexOf(shape);
+						selectedShapes.splice(index, 1);	
+					} else {
+						shape.setEditable(true);
+						selectedShapes.push(shape);
+					}
+	
+					if (debug) {
+						console.log(" len = " + selectedShapes.length);
+					}
+					//Send the values to be updated
+					var thi = shape.strokeWeight;
+					var opa = shape.fillOpacity;
+					var fCol = shape.fillColor;
+					var sCol = shape.strokeColor;
+					updateMenuValues(thi, opa, fCol, sCol);
+
+				} else if (shape.type == 'marker') {
+					clearSelection();
+				}
+
+				selectedShape = shape;
+				
+				selectedShapesLog = {
+				_selectedShapes: selectedShapes,
+				_shiftKeyPressed: shiftKeyPressed
+				}
+				
+				//prevLog.push(selectedShapesLog);
+
+			}
+
+			//Clears selection if clicked on the map when shift is not presseed
+			google.maps.event.addListener(map, 'click', function () {
+				if (shiftKeyPressed == false) {
+					clearSelection();
+				}
+			});
+
+			//Setting drawing tool option
+			document.addEventListener('keydown', function () {
+				//if (event.code == 'KeyX' && (event.ctrlKey || event.metaKey))
+				if (event.code == 'Digit0' || event.code == 'Numpad0' || event.code == 'Backquote') {
+					//clearSelection();
+					drawingManager.setDrawingMode(null);
+				} else if (event.code == 'Digit1') {
+					drawingManager.setDrawingMode('marker');
+				} else if (event.code == 'Digit2') {
+					drawingManager.setDrawingMode('circle');
+				} else if (event.code == 'Digit3') {
+					drawingManager.setDrawingMode('polygon');
+				} else if (event.code == 'Digit4') {
+					drawingManager.setDrawingMode('polyline');
+				} else if (event.code == 'Digit5') {
+					drawingManager.setDrawingMode('rectangle');
+				}
+				//					console.log(event.code);
+			});
+
+			//Sets shift as pressed
+			document.addEventListener('keydown', function () {
+				if (event.code == 'ShiftLeft' || event.code == 'ShiftRight') {
+					shiftKeyPressed = true;
+
+				}
+
+			});
+
+			//Sets shift as unpressed
+			document.addEventListener('keyup', function () {
+				if (event.code == 'ShiftLeft' || event.code == 'ShiftRight') {
+					shiftKeyPressed = false;
+				}
+
+			});
+
+			buildColorPalette();
+		}
+		//Set selected thickness
+		function setSelectedThickness(sWeight) {
+			if (selectedShape) {
+				//selectedShape.set('strokeWeight', sWeight)
+			}
+			if (selectedShapes !== 0) {
+				for (var i = 0; i < selectedShapes.length; i++) {
+					selectedShapes[i].set('strokeWeight', sWeight);
+					//console.log(selectedShapes.length);
+				}
+			}
+		}
+
+		//Set selected opacity
+		function setSelectedOpacity(fOpacity) {
+			if (selectedShape) {
+				//selectedShape.set('fillOpacity', fOpacity)
+			}
+			if (selectedShapes !== 0) {
+				for (var i = 0; i < selectedShapes.length; i++) {
+					selectedShapes[i].set('fillOpacity', fOpacity);
+				}
+			}
+		}
+
+		//set selected fill colour
+		function setSelectedShapeColor(color) {
+			if (selectedShapes !== 0) {
+				for (var i = 0; i < selectedShapes.length; i++) {
+					selectedShapes[i].set('fillColor', color);
+					selectedShapes[i].set('strokeColor', color);
+				}
+			}
+		}
+
+		function updateMenuValues(thi, opa, fCol, sCol) {
+
+			//Update thickness slider and value on the settings menu
+			var thicknessSliderOutput = document.getElementById("thicknessRangeVal");
+			thicknessSliderOutput.innerHTML = thi;
+			document.getElementById("thicknessRange").value = thi * 20;
+
+			//Update the opacity slider and value on the settings menu
+			var opacitySliderOutput = document.getElementById("opacityRangeVal");
+			opacitySliderOutput.innerHTML = "% " + opa * 100;
+			document.getElementById("colourOpacity").value = opa * 100;
+
+			if (drawingManager.drawingMode == null) {
+				selectColor(fCol);
+			}
+		}
+		function undoMovement() {
+
+			var lastItem = prevLog[prevLog.length - 1];
+			
+			if (prevLog.length !== 0) {
+			
+				if (lastItem.eventType = "dragged") {
+					//If the array has more than one index (polygons and polylines)
+					
+					if (prevLog[prevLog.length - 1].length > 1){
+						nextLog.push(lastItem);
+						selectedShape.setPath(lastItem);
+						console.log("sneaky")
+					
+					//If the array has only one index(rectangles and circles)
+					} else {	
+						//var ovEA = lastItem.shape.getBounds().ea;
+						//var ovLA = lastItem.shape.getBounds().la;
+
+						coor = {
+							east: lastItem.shape.getBounds().ea.l,
+							north: lastItem.shape.getBounds().la.l,
+							south: lastItem.shape.getBounds().la.j,
+							west: lastItem.shape.getBounds().ea.j
+						};
+						
+						nextLog.push(lastItem);
+						console.log(coor);
+						console.log(prevLog);
+						console.log(lastItem.shape.getBounds());
+						selectedShape.setBounds(coor);
+						console.log(JSON.stringify(shapesarray));
+						//console.log(prevLog);
+					}
+				} 
+			undoPressed = false;
+			undoPressed = 0;
+			prevLog.pop();
+			} 
+			
+
+		}
+
+		function redoMovement() {
+			var overlayType = prevLog[(prevLog.length - 1)]._selectedShapes[0].type;
+			var lastItem = nextLog[nextLog.length - 1];
+			var secondToLastItem = nextLog[nextLog.length - 2];
+			var selectedIndex;
+			if (undoPressed >= 2) {
+				selectedIndex =	 lastItem;
+			} else {
+				selectedIndex = secondToLastItem;
+			}
+			console.log(selectedIndex);
+			
+			//If the history log is not empty
+			if (nextLog.length > 1) {
+				prevLog.push(lastItem);
+
+				//If undo has been pressed
+				if (undoPressed >= 2) {
+					if (nextLog[nextLog.length - 1].length > 1){
+						selectedShape.setPath(lastItem);
+					} else {
+						selectedShape.setBounds(lastItem[0]);
+					}
+				} else {
+					if (nextLog[nextLog.length - 1].length > 1){
+						selectedShape.setPath(secondToLastItem);
+					} else {
+						selectedShape.setBounds(secondToLastItem[0]);
+					}
+					
+					undoPressed++;
+				}
+				undoPressed = false;
+				redoPressed = true;
+				nextLog.pop();
+			}
+		}
+
+		function polygonGetPath() {
+			var overlayType = prevLog[(prevLog.length - 1)]._selectedShapes[0].type;
+			//console.log(prevLog);
+			//console.log(prevLog[(prevLog.length - 1)]._selectedShapes[0].type == polygon);
+			if(prevLog[(prevLog.length - 1)]._selectedShapes){
+			console.log(prevLog[(prevLog.length - 1)]._selectedShapes[0].type);
+				if (overlayType = ("circle" || "rectangle")) {
+				console.log("It's a "+ overlayType);
+				} else if (overlayType = ("polygon" || "polyline")){
+				console.log("It's a "+ overlayType);
+				}
+				
+			}
+
+
+
+
+		}
+
+		function deleteSelectedShape() {
+			for (var i = 0; i < selectedShapes.length; i++) {
+				selectedShapes[i].setMap(null);
+			}
+			selectedShapes = [];
+		}
+
+		function removeLine() {
+			var lastOverlay = overlays.pop();
+			if (lastOverlay)
+				lastOverlay.setMap(null);
+		}
+
+		function deleteAllShape() {
+			for (var i = 0; i < overlays.length; i++) {
+				overlays[i].setMap(null);
+
+			}
+			overlays = [];
+		}
+
+	</script>
+	<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyBzunGwIF2OwsfrOkIC_8bhh0OPGZXo52Y&libraries=drawing&callback=initMap" async defer></script>
+	<script src="shortcuts.js"></script>
+  </body>
+</html>
Index: /gs3-extensions/map-editor/DrawingManager/checkpoints-singlefile/index backup v18.html
===================================================================
--- /gs3-extensions/map-editor/DrawingManager/checkpoints-singlefile/index backup v18.html	(revision 32709)
+++ /gs3-extensions/map-editor/DrawingManager/checkpoints-singlefile/index backup v18.html	(revision 32709)
@@ -0,0 +1,709 @@
+<!DOCTYPE html>
+<html>
+  <head>
+	<title>Drawing Tools</title>
+	<meta name="viewport" content="initial-scale=1.0, user-scalable=no">
+	<meta charset="utf-8">
+	<style>
+	  /* Always set the map height explicitly to define the size of the div
+	   * element that contains the map. */
+	  #map {
+		height: 83%;
+		width: 90;
+		float: bottom;
+		clear: both;
+	  }
+	  /* Optional: Makes the sample page fill the window. */
+	  html, body {
+		height: 100%;
+		width: 99%;
+		margin: 0;
+		padding: 0;
+
+	  }
+	  
+	  #DeleteButtons{
+	  display: inline-block;
+	  float: left;
+	  padding-left: 10px;
+	  padding-top: 5px;
+	  width: 100%
+
+	  }
+	  
+	  #LineThickness{
+	  display: inline-block;
+	  float: left;
+	  padding-left: 10px;
+	  padding-top: 5px;
+
+	  }
+	  
+	  #ColourOpacity{
+	  display: inline-block;
+	  float: left;
+	  padding-left: 10px;
+	  padding-top: 5px;
+
+	  }
+	  
+	  #buttons3{
+	  display: inline-block;
+	  float: left;
+	  padding-left: 10px;
+	  padding-top: 5px;
+
+	  }	  
+	  
+      #FillColour {
+	  display: inline-block;
+	  float: left;
+	  padding-left: 10px;
+	  padding-top: 5px;
+	  }
+	  
+      #color-palette1 {
+      clear: both;
+      }
+	  
+      .color-buttons1 {
+      width: 14px;
+      height: 14px;
+      font-size: 0;
+      margin: 2px;
+      float: left;
+      cursor: pointer;
+      }
+
+
+	</style>
+  </head>
+  <body>
+	<div id = "DeleteButtons">
+	<button onclick="removeLine()" accesskey="z">Delete Last</button>
+	<button onclick="deleteAllShape()" accesskey="c">Clear All</button>
+	<button onclick="deleteSelectedShape()" accesskey="b">Delete Selected</button>
+	<button onclick="polygonGetPath()" accesskey="n">Get Path</button>
+	<button onclick="undoMovement()" accesskey="n">Undo</button>
+	<button onclick="redoMovement()" accesskey="n">Redo</button>
+	
+	</div>
+	
+	<div id = "LineThickness">
+	<p>Line thickness: <input type="range" min="20" max="100" value="1" class="slider" id="thicknessRange"> </p>
+	<p>Value: <span id="thicknessRangeVal"></span></p>
+	</div>	
+	
+	<div id = "ColourOpacity">
+	<p>Colour opacity: <input type="range" min="10" max="100" value="40" class="slider" id="colourOpacity"> </p>
+	<p>Value: <span id="opacityRangeVal"></span></p>
+	</div>
+	
+
+
+	<div id="FillColour">
+     <p> Fill Colour:</p> <div id="color-palette1"></div> 
+	</div>
+
+	
+	
+	<div id="map"></div>
+	
+	<script>
+		var debug = false;
+
+		var redoPressed = false;
+		var undoPressed = 0;
+		var shiftKeyPressed = false;
+		var mousedDownFired = false;
+
+		
+		var selectedShapesLog = {
+			_selectedShapes: "",
+			_shiftKeyPressed: ""
+			
+		}
+		var prevEdge = {
+			east: "",
+			north: "",
+			south: "",
+			west: ""
+		}
+		var nextEdge = {
+			east: "",
+			north: "",
+			south: "",
+			west: ""
+		}
+		var prevVertex = {
+			lat: "",
+			lng: ""
+		};
+		var nextVertex = {
+			lat: "",
+			lng: ""
+		};
+		var prevShape = [];
+		var nextShape = [];
+		var prevLog = [];
+		var nextLog = [];
+		var dragged = 0;
+		var colors = ['#1E90FF', '#FF1493', '#4B0082', '#32CD32', '#FF8C00', '#000000'];
+		var selectedColor;
+		var colorButtons = {};
+		var thicknessValue = 1;
+		var opacityValue = 0.4;
+		var polyOptions = {
+			fillColor: '#CA4A2F',
+			strokeWeight: thicknessValue,
+			fillOpacity: opacityValue,
+			editable: true,
+			draggable: true,
+			geodesic: false,
+		};
+
+		var overlays = [];
+		var drawingManager;
+		var selectedShape;
+		var selectedShapes = [];
+		
+
+		//Update thickness
+		var thicknessSlider = document.getElementById("thicknessRange");
+		var thicknessSliderOutput = document.getElementById("thicknessRangeVal");
+		thicknessSliderOutput.innerHTML = thicknessSlider.value / 20;
+
+		thicknessSlider.oninput = function () {
+			thicknessSliderOutput.innerHTML = this.value / 20;
+			thicknessValue = this.value / 20;
+			polyOptions.strokeWeight = thicknessValue;
+			setSelectedThickness(thicknessValue);
+		}
+
+		//Update opacity
+		var opacitySlider = document.getElementById("colourOpacity");
+		var opacitySliderOutput = document.getElementById("opacityRangeVal");
+		opacitySliderOutput.innerHTML = "% " + Math.round(opacitySlider.value);
+
+		opacitySlider.oninput = function () {
+			opacityValue = this.value / 100;
+			polyOptions.fillOpacity = opacityValue;
+			opacitySliderOutput = opacityValue;
+			opacityRangeVal.innerHTML = "% " + Math.round(opacitySliderOutput * 100);
+			setSelectedOpacity(opacityValue);
+		}
+
+		////////////////////////////////////////////////////////////////////////////////////////
+		function makeColorButton(color) {
+			var button = document.createElement('span');
+			button.className = 'color-buttons1';
+			button.style.backgroundColor = color;
+			google.maps.event.addDomListener(button, 'click', function () {
+				selectColor(color);
+				setSelectedShapeColor(color);
+			});
+			return button;
+		}
+		function buildColorPalette() {
+			var colorPalette = document.getElementById('color-palette1');
+			for (var i = 0; i < colors.length; ++i) {
+				var currColor = colors[i];
+				var colorButton = makeColorButton(currColor);
+				colorPalette.appendChild(colorButton);
+				colorButtons[currColor] = colorButton;
+			}
+			selectColor(colors[0]);
+		};
+		function selectColor(color) {
+			selectedColor = color;
+			for (var i = 0; i < colors.length; ++i) {
+				var currColor = colors[i];
+				colorButtons[currColor].style.border = currColor == color ? '2px solid #789' : '2px solid #fff';
+			}
+
+			// Retrieves the current options from the drawing manager and replaces the
+			// stroke or fill color as appropriate.
+			var polylineOptions = drawingManager.get('polylineOptions');
+			polylineOptions.strokeColor = color;
+			drawingManager.set('polylineOptions', polylineOptions);
+
+			var rectangleOptions = drawingManager.get('rectangleOptions');
+			rectangleOptions.fillColor = color;
+			drawingManager.set('rectangleOptions', rectangleOptions);
+
+			var circleOptions = drawingManager.get('circleOptions');
+			circleOptions.fillColor = color;
+			drawingManager.set('circleOptions', circleOptions);
+
+			var polygonOptions = drawingManager.get('polygonOptions');
+			polygonOptions.fillColor = color;
+			drawingManager.set('polygonOptions', polygonOptions);
+		}
+
+		function initMap() {
+
+			var map = new google.maps.Map(document.getElementById('map'), {
+					center: {
+						lat: -34.397,
+						lng: 150.644
+					},
+					zoom: 2,
+					//mapTypeId: 'map'
+
+				});
+
+			drawingManager = new google.maps.drawing.DrawingManager({
+					drawingMode: google.maps.drawing.OverlayType.RECTANGLE,
+					drawingControl: true,
+					drawingControlOptions: {
+						position: google.maps.ControlPosition.TOP_CENTER,
+						drawingModes: ['marker', 'circle', 'polygon', 'polyline', 'rectangle']
+					},
+					markerOptions: {
+						draggable: true
+					},
+					circleOptions: polyOptions,
+					polylineOptions: polyOptions,
+					polygonOptions: polyOptions,
+					rectangleOptions: polyOptions,
+				});
+
+			drawingManager.setMap(map);
+
+			//overlays.push(event.overlay); // store reference to added overlay
+			google.maps.event.addListener(drawingManager, 'overlaycomplete', function (e) {
+				overlays.push(e.overlay); // store reference to added overlay
+				var newShape = e.overlay;
+				newShape.type = e.type;
+
+				if (e.type !== google.maps.drawing.OverlayType.MARKER) {
+
+					// Switch back to non-drawing mode after drawing a shape.
+					//drawingManager.setDrawingMode(null);
+
+					// Add an event listener that selects the newly-drawn shape when the user
+					// mouses down on it.
+					google.maps.event.addListener(newShape, 'click', function (e) {
+
+						vertexAndPolyDel(e, newShape);
+						mousedDownFired = false;
+						return;
+
+					});
+
+					//Stores past event information
+					google.maps.event.addListener(newShape, 'dragstart', function () {
+						//console.log("Drag Start");
+						if (selectedShape) {
+							var polyG = newShape.type === google.maps.drawing.OverlayType.POLYLINE;
+							var polyL = newShape.type === google.maps.drawing.OverlayType.POLYGON;
+							
+							if (polyL || polyG) {
+							
+								var latLngi = []
+								var lati,
+								lngi;
+								for (var i = 0; i < selectedShape.getPath().length; i++) {
+									lati = selectedShape.getPath().getAt(i).lat();
+									lngi = selectedShape.getPath().getAt(i).lng();
+									//console.log("Vertex number",i, "'s latitude is", lati, "and longitude is", lngi);
+									prevVertex = {
+										lat: lati,
+										lng: lngi
+									};
+									latLngi.push(prevVertex);
+								}
+								prevShape.push("dragged", selectedShape.type, latLngi);
+
+								
+							} else {
+								//east is: ea.l
+								//north is: la.l
+								//southt is: la.j
+								//west is: ea.j
+								prevEdge = {
+									east: selectedShape.getBounds().ea.l,
+									north: selectedShape.getBounds().la.l,
+									south: selectedShape.getBounds().la.j,
+									west: selectedShape.getBounds().ea.j
+								}
+							
+								
+							
+								prevShape.push("dragged", selectedShape.type, prevEdge);
+	
+
+							}
+							
+					
+							
+							prevLog.push(prevShape);
+							prevShape = [];
+							nextLog = [];
+							console.log("drag start ", prevLog);
+						}
+					});
+
+					//Store information after the event ends
+					google.maps.event.addListener(newShape, 'dragend', function () {
+						//console.log("Drag End");
+						if (selectedShape) {
+							var polyG = newShape.type === google.maps.drawing.OverlayType.POLYLINE;
+							var polyL = newShape.type === google.maps.drawing.OverlayType.POLYGON;
+							
+							if (polyL || polyG) {
+							
+								var latLngi = []
+								var lati,
+								lngi;
+	
+								for (var i = 0; i < selectedShape.getPath().length; i++) {
+									lati = selectedShape.getPath().getAt(i).lat();
+									lngi = selectedShape.getPath().getAt(i).lng();
+									//console.log("Vertex number",i, "'s latitude is", lati, "and longitude is", lngi);
+									nextVertex = {
+										lat: lati,
+										lng: lngi
+									};
+									latLngi.push(nextVertex);
+								}
+								nextShape.push("dragged", selectedShape.type, latLngi);
+							} else {
+
+								nextEdge.east = selectedShape.getBounds().ea.l;
+								nextEdge.north = selectedShape.getBounds().la.l;
+								nextEdge.south = selectedShape.getBounds().la.j;
+								nextEdge.west = selectedShape.getBounds().ea.j;
+								
+
+								nextShape.push("dragged", selectedShape.type, nextEdge);
+							}
+							
+							nextLog.push(nextShape);
+							nextShape = [];
+							console.log("drag end ", nextLog);
+							//console.log("Next Array Length",nextLog.length);
+						}
+					});
+
+					//Add an event listener to select a shape if the mouse hovers over it
+					google.maps.event.addListener(newShape, 'mousedown', function (e) {
+						if (drawingManager.drawingMode == null) {
+							mousedDownFired = true;
+							//							console.log("MOUSDOWN ", e);
+
+							setSelection(newShape, e);
+						}
+					});
+					setSelection(newShape, e);
+				} else {
+					//cLICK EVENT IF A MARKER IS CREATED
+					google.maps.event.addListener(newShape, 'click', function (e) {
+						setSelection(newShape, e);
+					});
+					setSelection(newShape, e);
+				}
+			});
+
+			//Deletes a vertex if clicked on it
+			function vertexAndPolyDel(e, newShape) {
+				var vertex = e.vertex;
+				
+				if (e.vertex !== undefined) {
+					if (newShape.type === google.maps.drawing.OverlayType.POLYGON) {
+						var path = newShape.getPaths().getAt(e.path);
+						path.removeAt(e.vertex);
+						if (path.length < 3) {
+							newShape.setMap(null);
+						}
+					}
+					if (newShape.type === google.maps.drawing.OverlayType.POLYLINE) {
+						var path = newShape.getPath();
+						path.removeAt(e.vertex);
+						if (path.length < 2) {
+							newShape.setMap(null);
+						}
+					}
+				}
+
+				//if(mousedDownFired == false)
+				//{
+				//setSelection(newShape, vertex);
+				//mousedDownFired = false;
+				//return;
+				//}
+			}
+
+			function clearSelection() {
+				if (selectedShape) {
+					if (selectedShape.type !== 'marker') {
+						selectedShape.setEditable(false);
+						if (shiftKeyPressed == false) {
+							for (var i = 0; i < selectedShapes.length; i++) {
+								selectedShapes[i].setEditable(false);
+							}
+							selectedShapes = [];
+						}
+					}
+
+					selectedShape = null;
+				}
+			}
+			var i = 0;
+			
+			//Set selection for the selected overlay
+			function setSelection(shape, e) {
+				if (shape.type !== 'marker') {
+					if (shiftKeyPressed == false) {
+						if (e.vertex == undefined) {
+							clearSelection();
+							shape.setEditable(true);
+						}
+					}
+					if (selectedShapes.includes(shape)) {
+					
+						//shape.setEditable(false);
+						const index = selectedShapes.indexOf(shape);
+						selectedShapes.splice(index, 1);	
+					} else {
+						shape.setEditable(true);
+						selectedShapes.push(shape);
+					}
+	
+					if (debug) {
+						console.log(" len = " + selectedShapes.length);
+					}
+					//Send the values to be updated
+					var thi = shape.strokeWeight;
+					var opa = shape.fillOpacity;
+					var fCol = shape.fillColor;
+					var sCol = shape.strokeColor;
+					updateMenuValues(thi, opa, fCol, sCol);
+
+				} else if (shape.type == 'marker') {
+					clearSelection();
+				}
+
+				selectedShape = shape;
+				
+				selectedShapesLog = {
+				_selectedShapes: selectedShapes,
+				_shiftKeyPressed: shiftKeyPressed
+				}
+				
+				//prevLog.push(selectedShapesLog);
+
+			}
+
+			//Clears selection if clicked on the map when shift is not presseed
+			google.maps.event.addListener(map, 'click', function () {
+				if (shiftKeyPressed == false) {
+					clearSelection();
+					chosen = null;
+					
+				}
+			});
+
+			//Setting drawing tool option
+			document.addEventListener('keydown', function () {
+				//if (event.code == 'KeyX' && (event.ctrlKey || event.metaKey))
+				if (event.code == 'Digit0' || event.code == 'Numpad0' || event.code == 'Backquote') {
+					//clearSelection();
+					drawingManager.setDrawingMode(null);
+				} else if (event.code == 'Digit1') {
+					drawingManager.setDrawingMode('marker');
+				} else if (event.code == 'Digit2') {
+					drawingManager.setDrawingMode('circle');
+				} else if (event.code == 'Digit3') {
+					drawingManager.setDrawingMode('polygon');
+				} else if (event.code == 'Digit4') {
+					drawingManager.setDrawingMode('polyline');
+				} else if (event.code == 'Digit5') {
+					drawingManager.setDrawingMode('rectangle');
+				}
+				//					console.log(event.code);
+			});
+
+			//Sets shift as pressed
+			document.addEventListener('keydown', function () {
+				if (event.code == 'ShiftLeft' || event.code == 'ShiftRight') {
+					shiftKeyPressed = true;
+
+				}
+
+			});
+
+			//Sets shift as unpressed
+			document.addEventListener('keyup', function () {
+				if (event.code == 'ShiftLeft' || event.code == 'ShiftRight') {
+					shiftKeyPressed = false;
+				}
+
+			});
+
+			buildColorPalette();
+		}
+		//Set selected thickness
+		function setSelectedThickness(sWeight) {
+			if (selectedShape) {
+				//selectedShape.set('strokeWeight', sWeight)
+			}
+			if (selectedShapes !== 0) {
+				for (var i = 0; i < selectedShapes.length; i++) {
+					selectedShapes[i].set('strokeWeight', sWeight);
+					//console.log(selectedShapes.length);
+				}
+			}
+		}
+
+		//Set selected opacity
+		function setSelectedOpacity(fOpacity) {
+			if (selectedShape) {
+				//selectedShape.set('fillOpacity', fOpacity)
+			}
+			if (selectedShapes !== 0) {
+				for (var i = 0; i < selectedShapes.length; i++) {
+					selectedShapes[i].set('fillOpacity', fOpacity);
+				}
+			}
+		}
+
+		//set selected fill colour
+		function setSelectedShapeColor(color) {
+			if (selectedShapes !== 0) {
+				for (var i = 0; i < selectedShapes.length; i++) {
+					selectedShapes[i].set('fillColor', color);
+					selectedShapes[i].set('strokeColor', color);
+				}
+			}
+		}
+
+		function updateMenuValues(thi, opa, fCol, sCol) {
+
+			//Update thickness slider and value on the settings menu
+			var thicknessSliderOutput = document.getElementById("thicknessRangeVal");
+			thicknessSliderOutput.innerHTML = thi;
+			document.getElementById("thicknessRange").value = thi * 20;
+
+			//Update the opacity slider and value on the settings menu
+			var opacitySliderOutput = document.getElementById("opacityRangeVal");
+			opacitySliderOutput.innerHTML = "% " + opa * 100;
+			document.getElementById("colourOpacity").value = opa * 100;
+
+			if (drawingManager.drawingMode == null) {
+				selectColor(fCol);
+			}
+		}
+		function undoMovement() {
+			var lastItem = prevLog[prevLog.length - 1];
+
+			//If history array is not empty
+			if (prevLog.length !== 0) {
+				if(lastItem[0] = "dragged"){
+					//If the array has more than one index (polygons and polylines)
+					if (lastItem[1] == ("polygon") || lastItem[1] == ("polyline")) {
+						nextLog.push(lastItem);
+						console.log((prevLog));
+						selectedShape.setPath(lastItem[2]);
+						
+	
+					
+					//If the array has only one index(rectangles and circles)
+					} else {
+						nextLog.push(lastItem);
+
+						selectedShape.setBounds(lastItem[2]);
+						
+					}
+				}
+			undoPressed = false;
+			undoPressed = 0;
+			prevLog.pop();
+			} 
+			
+
+		}
+
+		function redoMovement() {
+
+			var lastItem = nextLog[nextLog.length - 1];
+			var secondToLastItem = nextLog[nextLog.length - 2];
+			var correctIndex;
+			if (undoPressed >= 2) {
+				correctIndex == lastItem;
+			} else {
+				correctIndex == secondToLastItem;
+			}
+			
+			//If the history log is not empty
+			if (nextLog.length > 1) {
+				prevLog.push(lastItem);
+
+				//If undo has been pressed
+				if (undoPressed >= 1) {
+					if (lastItem[1] == ("polygon") || lastItem[1] == ("polyline")){
+						selectedShape.setPath(lastItem[2]);
+					} else {
+						selectedShape.setBounds(lastItem[2]);
+					}
+				} else {
+					if (lastItem[1] == ("polygon") || lastItem[1] == ("polyline")){
+						selectedShape.setPath(secondToLastItem[2]);
+					} else {
+						selectedShape.setBounds(secondToLastItem[2]);
+					}
+					
+					undoPressed++;
+				}
+				undoPressed = false;
+				redoPressed = true;
+				nextLog.pop();
+				console.log(nextLog);
+			}
+		}
+
+		function polygonGetPath() {
+			var overlayType = prevLog[(prevLog.length - 1)]._selectedShapes[0].type;
+			//console.log(prevLog);
+			//console.log(prevLog[(prevLog.length - 1)]._selectedShapes[0].type == polygon);
+			if(prevLog[(prevLog.length - 1)]._selectedShapes){
+			console.log(prevLog[(prevLog.length - 1)]._selectedShapes[0].type);
+				if (overlayType = ("circle" || "rectangle")) {
+				console.log("It's a "+ overlayType);
+				} else if (overlayType = ("polygon" || "polyline")){
+				console.log("It's a "+ overlayType);
+				}
+				
+			}
+
+
+
+
+		}
+
+		function deleteSelectedShape() {
+			for (var i = 0; i < selectedShapes.length; i++) {
+				selectedShapes[i].setMap(null);
+			}
+			selectedShapes = [];
+		}
+
+		function removeLine() {
+			var lastOverlay = overlays.pop();
+			if (lastOverlay)
+				lastOverlay.setMap(null);
+		}
+
+		function deleteAllShape() {
+			for (var i = 0; i < overlays.length; i++) {
+				overlays[i].setMap(null);
+
+			}
+			overlays = [];
+		}
+
+	</script>
+	<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyBzunGwIF2OwsfrOkIC_8bhh0OPGZXo52Y&libraries=drawing&callback=initMap" async defer></script>
+	<script src="shortcuts.js"></script>
+  </body>
+</html>
Index: /gs3-extensions/map-editor/DrawingManager/checkpoints-singlefile/index backup v19.html
===================================================================
--- /gs3-extensions/map-editor/DrawingManager/checkpoints-singlefile/index backup v19.html	(revision 32709)
+++ /gs3-extensions/map-editor/DrawingManager/checkpoints-singlefile/index backup v19.html	(revision 32709)
@@ -0,0 +1,698 @@
+<!DOCTYPE html>
+<html>
+  <head>
+	<title>Drawing Tools</title>
+	<meta name="viewport" content="initial-scale=1.0, user-scalable=no">
+	<meta charset="utf-8">
+	<style>
+	  /* Always set the map height explicitly to define the size of the div
+	   * element that contains the map. */
+	  #map {
+		height: 83%;
+		width: 90;
+		float: bottom;
+		clear: both;
+	  }
+	  /* Optional: Makes the sample page fill the window. */
+	  html, body {
+		height: 100%;
+		width: 99%;
+		margin: 0;
+		padding: 0;
+
+	  }
+	  
+	  #DeleteButtons{
+	  display: inline-block;
+	  float: left;
+	  padding-left: 10px;
+	  padding-top: 5px;
+	  width: 100%
+
+	  }
+	  
+	  #LineThickness{
+	  display: inline-block;
+	  float: left;
+	  padding-left: 10px;
+	  padding-top: 5px;
+
+	  }
+	  
+	  #ColourOpacity{
+	  display: inline-block;
+	  float: left;
+	  padding-left: 10px;
+	  padding-top: 5px;
+
+	  }
+	  
+	  #buttons3{
+	  display: inline-block;
+	  float: left;
+	  padding-left: 10px;
+	  padding-top: 5px;
+
+	  }	  
+	  
+      #FillColour {
+	  display: inline-block;
+	  float: left;
+	  padding-left: 10px;
+	  padding-top: 5px;
+	  }
+	  
+      #color-palette1 {
+      clear: both;
+      }
+	  
+      .color-buttons1 {
+      width: 14px;
+      height: 14px;
+      font-size: 0;
+      margin: 2px;
+      float: left;
+      cursor: pointer;
+      }
+
+
+	</style>
+  </head>
+  <body>
+	<div id = "DeleteButtons">
+	<button onclick="deleteAllShape()" accesskey="c">Clear All</button>
+	<button onclick="deleteSelectedShape()" accesskey="b">Delete Selected</button>
+	<button onclick="polygonGetPath()" accesskey="n">Get Path</button>
+	<button onclick="undoMovement()" accesskey="n">Undo</button>
+	<button onclick="redoMovement()" accesskey="n">Redo</button>
+	
+	</div>
+	
+	<div id = "LineThickness">
+	<p>Line thickness: <input type="range" min="20" max="100" value="1" class="slider" id="thicknessRange"> </p>
+	<p>Value: <span id="thicknessRangeVal"></span></p>
+	</div>	
+	
+	<div id = "ColourOpacity">
+	<p>Colour opacity: <input type="range" min="10" max="100" value="40" class="slider" id="colourOpacity"> </p>
+	<p>Value: <span id="opacityRangeVal"></span></p>
+	</div>
+	
+
+
+	<div id="FillColour">
+     <p> Fill Colour:</p> <div id="color-palette1"></div> 
+	</div>
+
+	
+	
+	<div id="map"></div>
+	
+	<script>
+		var debug = false;
+		var redoPressed = false;
+		var undoPressed = 0;
+		var shiftKeyPressed = false;
+		var mousedDownFired = false;
+		var selectionPass = true;
+		var chosen;
+
+		var prevEdge = {
+			east: "",
+			north: "",
+			south: "",
+			west: ""
+		}
+		var nextEdge = {
+			east: "",
+			north: "",
+			south: "",
+			west: ""
+		}
+		var prevVertex = {
+			lat: "",
+			lng: ""
+		};
+		var nextVertex = {
+			lat: "",
+			lng: ""
+		};
+		var deselectedLog = []
+		var selectedShapesLog = [];
+		var prevShape = [];
+		var nextShape = [];
+		var prevLog = [];
+		var nextLog = [];
+		var dragged = 0;
+		var colors = ['#1E90FF', '#FF1493', '#4B0082', '#32CD32', '#FF8C00', '#000000'];
+		var selectedColor;
+		var colorButtons = {};
+		var thicknessValue = 1;
+		var opacityValue = 0.4;
+		var polyOptions = {
+			fillColor: '#CA4A2F',
+			strokeWeight: thicknessValue,
+			fillOpacity: opacityValue,
+			editable: true,
+			draggable: true,
+			geodesic: false,
+		};
+
+		var overlays = [];
+		var drawingManager;
+		var selectedShape;
+		var selectedShapes = [];
+		
+
+		//Update thickness
+		var thicknessSlider = document.getElementById("thicknessRange");
+		var thicknessSliderOutput = document.getElementById("thicknessRangeVal");
+		thicknessSliderOutput.innerHTML = thicknessSlider.value / 20;
+
+		thicknessSlider.oninput = function () {
+			thicknessSliderOutput.innerHTML = this.value / 20;
+			thicknessValue = this.value / 20;
+			polyOptions.strokeWeight = thicknessValue;
+			setSelectedThickness(thicknessValue);
+		}
+
+		//Update opacity
+		var opacitySlider = document.getElementById("colourOpacity");
+		var opacitySliderOutput = document.getElementById("opacityRangeVal");
+		opacitySliderOutput.innerHTML = "% " + Math.round(opacitySlider.value);
+
+		opacitySlider.oninput = function () {
+			opacityValue = this.value / 100;
+			polyOptions.fillOpacity = opacityValue;
+			opacitySliderOutput = opacityValue;
+			opacityRangeVal.innerHTML = "% " + Math.round(opacitySliderOutput * 100);
+			setSelectedOpacity(opacityValue);
+		}
+
+		////////////////////////////////////////////////////////////////////////////////////////
+		function makeColorButton(color) {
+			var button = document.createElement('span');
+			button.className = 'color-buttons1';
+			button.style.backgroundColor = color;
+			google.maps.event.addDomListener(button, 'click', function () {
+				selectColor(color);
+				setSelectedShapeColor(color);
+			});
+			return button;
+		}
+		function buildColorPalette() {
+			var colorPalette = document.getElementById('color-palette1');
+			for (var i = 0; i < colors.length; ++i) {
+				var currColor = colors[i];
+				var colorButton = makeColorButton(currColor);
+				colorPalette.appendChild(colorButton);
+				colorButtons[currColor] = colorButton;
+			}
+			selectColor(colors[0]);
+		};
+		function selectColor(color) {
+			selectedColor = color;
+			for (var i = 0; i < colors.length; ++i) {
+				var currColor = colors[i];
+				colorButtons[currColor].style.border = currColor == color ? '2px solid #789' : '2px solid #fff';
+			}
+
+			// Retrieves the current options from the drawing manager and replaces the
+			// stroke or fill color as appropriate.
+			var polylineOptions = drawingManager.get('polylineOptions');
+			polylineOptions.strokeColor = color;
+			drawingManager.set('polylineOptions', polylineOptions);
+
+			var rectangleOptions = drawingManager.get('rectangleOptions');
+			rectangleOptions.fillColor = color;
+			drawingManager.set('rectangleOptions', rectangleOptions);
+
+			var circleOptions = drawingManager.get('circleOptions');
+			circleOptions.fillColor = color;
+			drawingManager.set('circleOptions', circleOptions);
+
+			var polygonOptions = drawingManager.get('polygonOptions');
+			polygonOptions.fillColor = color;
+			drawingManager.set('polygonOptions', polygonOptions);
+		}
+
+		function initMap() {
+
+			var map = new google.maps.Map(document.getElementById('map'), {
+					center: {
+						lat: -34.397,
+						lng: 150.644
+					},
+					zoom: 2,
+					//mapTypeId: 'map'
+
+				});
+
+			drawingManager = new google.maps.drawing.DrawingManager({
+					drawingMode: google.maps.drawing.OverlayType.RECTANGLE,
+					drawingControl: true,
+					drawingControlOptions: {
+						position: google.maps.ControlPosition.TOP_CENTER,
+						drawingModes: ['marker', 'circle', 'polygon', 'polyline', 'rectangle']
+					},
+					markerOptions: {
+						draggable: true
+					},
+					circleOptions: polyOptions,
+					polylineOptions: polyOptions,
+					polygonOptions: polyOptions,
+					rectangleOptions: polyOptions,
+				});
+
+			drawingManager.setMap(map);
+
+			//overlays.push(event.overlay); // store reference to added overlay
+			google.maps.event.addListener(drawingManager, 'overlaycomplete', function (e) {
+				overlays.push(e.overlay); // store reference to added overlay
+				var newShape = e.overlay;
+				newShape.type = e.type;
+
+				if (e.type !== google.maps.drawing.OverlayType.MARKER) {
+
+					// Switch back to non-drawing mode after drawing a shape.
+					//drawingManager.setDrawingMode(null);
+
+					// Add an event listener that selects the newly-drawn shape when the user
+					// mouses down on it.
+					google.maps.event.addListener(newShape, 'click', function (e) {
+
+						vertexAndPolyDel(e, newShape);
+						mousedDownFired = false;
+						return;
+
+					});
+
+					//Stores past event information
+					google.maps.event.addListener(newShape, 'dragstart', function () {
+						//console.log("Drag Start");
+						if (selectedShape) {
+							var polyG = newShape.type === google.maps.drawing.OverlayType.POLYLINE;
+							var polyL = newShape.type === google.maps.drawing.OverlayType.POLYGON;
+							
+							if (polyL || polyG) {
+								var latLngi = []
+								var lati,
+								lngi;
+								for (var i = 0; i < selectedShape.getPath().length; i++) {
+									lati = selectedShape.getPath().getAt(i).lat();
+									lngi = selectedShape.getPath().getAt(i).lng();
+									//console.log("Vertex number",i, "'s latitude is", lati, "and longitude is", lngi);
+									prevVertex = {
+										lat: lati,
+										lng: lngi
+									};
+									latLngi.push(prevVertex);
+								}
+								prevShape.push("dragged", selectedShape.type, latLngi);	
+							} else {
+								prevEdge = {
+									east: selectedShape.getBounds().ea.l,
+									north: selectedShape.getBounds().la.l,
+									south: selectedShape.getBounds().la.j,
+									west: selectedShape.getBounds().ea.j
+								}
+								prevShape.push("dragged", selectedShape.type, prevEdge);
+							}
+							prevLog.push(prevShape);
+							prevShape = [];
+							nextLog = [];
+							chosen = selectedShape;
+						}
+					});
+
+					//Store information after the event ends
+					google.maps.event.addListener(newShape, 'dragend', function () {
+						
+						if (selectedShape) {
+							var polyG = newShape.type === google.maps.drawing.OverlayType.POLYLINE;
+							var polyL = newShape.type === google.maps.drawing.OverlayType.POLYGON;
+							
+							if (polyL || polyG) {
+							
+								var latLngi = []
+								var lati,
+								lngi;
+	
+								for (var i = 0; i < selectedShape.getPath().length; i++) {
+									lati = selectedShape.getPath().getAt(i).lat();
+									lngi = selectedShape.getPath().getAt(i).lng();
+									//console.log("Vertex number",i, "'s latitude is", lati, "and longitude is", lngi);
+									nextVertex = {
+										lat: lati,
+										lng: lngi
+									};
+									latLngi.push(nextVertex);
+								}
+								nextShape.push("dragged", selectedShape.type, latLngi);
+							} else {
+
+								nextEdge.east = selectedShape.getBounds().ea.l;
+								nextEdge.north = selectedShape.getBounds().la.l;
+								nextEdge.south = selectedShape.getBounds().la.j;
+								nextEdge.west = selectedShape.getBounds().ea.j;
+								
+
+								nextShape.push("dragged", selectedShape.type, nextEdge);
+							}
+							
+							nextLog.push(nextShape);
+							nextShape = [];
+							chosen = selectedShape;
+						}
+					});
+
+					//Add an event listener to select a shape if the mouse hovers over it
+					google.maps.event.addListener(newShape, 'mousedown', function (e) {
+						if (drawingManager.drawingMode == null) {
+							mousedDownFired = true;
+							//							console.log("MOUSDOWN ", e);
+
+							setSelection(newShape, e);
+						}
+					});
+					setSelection(newShape, e);
+				} else {
+					//cLICK EVENT IF A MARKER IS CREATED
+					google.maps.event.addListener(newShape, 'click', function (e) {
+						setSelection(newShape, e);
+					});
+					setSelection(newShape, e);
+				}
+			});
+
+			//Deletes a vertex if clicked on it
+			function vertexAndPolyDel(e, newShape) {
+				var vertex = e.vertex;
+				
+				if (e.vertex !== undefined) {
+					if (newShape.type === google.maps.drawing.OverlayType.POLYGON) {
+						var path = newShape.getPaths().getAt(e.path);
+						path.removeAt(e.vertex);
+						if (path.length < 3) {
+							newShape.setMap(null);
+						}
+					}
+					if (newShape.type === google.maps.drawing.OverlayType.POLYLINE) {
+						var path = newShape.getPath();
+						path.removeAt(e.vertex);
+						if (path.length < 2) {
+							newShape.setMap(null);
+						}
+					}
+				}
+
+				//if(mousedDownFired == false)
+				//{
+				//setSelection(newShape, vertex);
+				//mousedDownFired = false;
+				//return;
+				//}
+			}
+
+			function clearSelection() {
+				if (selectedShape) {
+					if (selectedShape.type !== 'marker') {
+						selectedShape.setEditable(false);
+						if (shiftKeyPressed == false) {
+							for (var i = 0; i < selectedShapes.length; i++) {
+								selectedShapes[i].setEditable(false);
+							}
+							selectedShapes = [];
+						}
+					}
+					selectedShape = null;
+				}
+			}
+			var i = 0;
+			
+			//Set selection for the selected overlay
+			function setSelection(shape, e) {
+				if (shape.type !== 'marker') {
+					if (shiftKeyPressed == false) {
+						if (e.vertex == undefined) {
+							clearSelection();
+							shape.setEditable(true);
+						}
+					}
+					if (selectedShapes.includes(shape)) {
+					
+						//shape.setEditable(false);
+						const index = selectedShapes.indexOf(shape);
+						selectedShapes.splice(index, 1);	
+					} else {
+						shape.setEditable(true);
+						selectedShapes.push(shape);
+					}
+	
+					if (debug) {
+						console.log(" len = " + selectedShapes.length);
+					}
+					//Send the values to be updated
+					var thi = shape.strokeWeight;
+					var opa = shape.fillOpacity;
+					var fCol = shape.fillColor;
+					var sCol = shape.strokeColor;
+					updateMenuValues(thi, opa, fCol, sCol);
+
+				} else if (shape.type == 'marker') {
+					clearSelection();
+				}
+				
+				
+				
+				selectedShape = shape;
+				
+				if (selectionPass == true){
+
+					selectedShapesLog.push("selected", shiftKeyPressed, selectedShape);
+					nextLog.push(selectedShapesLog);
+					chosen = selectedShape;
+					selectionPass = false
+				}
+				
+				var lastItem = nextLog[nextLog.length -1];
+				
+				if(chosen !== selectedShape){
+					selectedShapesLog.push("selected", shiftKeyPressed, selectedShape)
+					nextLog.push(selectedShapesLog);
+					chosen = selectedShape;
+				}
+							
+				
+					console.log(nextLog.length);
+				
+				
+				
+				//
+				console.log(nextLog);
+				selectedShapesLog = [];
+			}
+
+			//Clears selection if clicked on the map when shift is not presseed
+			google.maps.event.addListener(map, 'click', function () {
+				if (shiftKeyPressed == false) {
+					clearSelection();
+					if(chosen !== null) {
+						deselectedLog.push("deselected")
+						nextLog.push(deselectedLog);
+						deselectedLog = [];
+						chosen = null;
+						
+					}
+				}
+				console.log(nextLog);
+			});
+
+			//Setting drawing tool option
+			document.addEventListener('keydown', function () {
+				//if (event.code == 'KeyX' && (event.ctrlKey || event.metaKey))
+				if (event.code == 'Digit0' || event.code == 'Numpad0' || event.code == 'Backquote') {
+					//clearSelection();
+					drawingManager.setDrawingMode(null);
+				} else if (event.code == 'Digit1') {
+					drawingManager.setDrawingMode('marker');
+				} else if (event.code == 'Digit2') {
+					drawingManager.setDrawingMode('circle');
+				} else if (event.code == 'Digit3') {
+					drawingManager.setDrawingMode('polygon');
+				} else if (event.code == 'Digit4') {
+					drawingManager.setDrawingMode('polyline');
+				} else if (event.code == 'Digit5') {
+					drawingManager.setDrawingMode('rectangle');
+				}
+				//					console.log(event.code);
+			});
+
+			//Sets shift as pressed
+			document.addEventListener('keydown', function () {
+				if (event.code == 'ShiftLeft' || event.code == 'ShiftRight') {
+					shiftKeyPressed = true;
+
+				}
+
+			});
+
+			//Sets shift as unpressed
+			document.addEventListener('keyup', function () {
+				if (event.code == 'ShiftLeft' || event.code == 'ShiftRight') {
+					shiftKeyPressed = false;
+				}
+
+			});
+
+			buildColorPalette();
+		}
+		//Set selected thickness
+		function setSelectedThickness(sWeight) {
+			if (selectedShape) {
+				//selectedShape.set('strokeWeight', sWeight)
+			}
+			if (selectedShapes !== 0) {
+				for (var i = 0; i < selectedShapes.length; i++) {
+					selectedShapes[i].set('strokeWeight', sWeight);
+					//console.log(selectedShapes.length);
+				}
+			}
+		}
+
+		//Set selected opacity
+		function setSelectedOpacity(fOpacity) {
+			if (selectedShape) {
+				//selectedShape.set('fillOpacity', fOpacity)
+			}
+			if (selectedShapes !== 0) {
+				for (var i = 0; i < selectedShapes.length; i++) {
+					selectedShapes[i].set('fillOpacity', fOpacity);
+				}
+			}
+		}
+
+		//set selected fill colour
+		function setSelectedShapeColor(color) {
+			if (selectedShapes !== 0) {
+				for (var i = 0; i < selectedShapes.length; i++) {
+					selectedShapes[i].set('fillColor', color);
+					selectedShapes[i].set('strokeColor', color);
+				}
+			}
+		}
+
+		function updateMenuValues(thi, opa, fCol, sCol) {
+
+			//Update thickness slider and value on the settings menu
+			var thicknessSliderOutput = document.getElementById("thicknessRangeVal");
+			thicknessSliderOutput.innerHTML = thi;
+			document.getElementById("thicknessRange").value = thi * 20;
+
+			//Update the opacity slider and value on the settings menu
+			var opacitySliderOutput = document.getElementById("opacityRangeVal");
+			opacitySliderOutput.innerHTML = "% " + opa * 100;
+			document.getElementById("colourOpacity").value = opa * 100;
+
+			if (drawingManager.drawingMode == null) {
+				selectColor(fCol);
+			}
+		}
+		function undoMovement() {
+			var lastItem = prevLog[prevLog.length - 1];
+
+			//If history array is not empty
+			if (prevLog.length !== 0) {
+				if(lastItem[0] = "dragged"){
+					//If the array has more than one index (polygons and polylines)
+					if (lastItem[1] == ("polygon") || lastItem[1] == ("polyline")) {
+						nextLog.push(lastItem);
+						selectedShape.setPath(lastItem[2]);
+
+					//If the array has only one index(rectangles and circles)
+					} else {
+						nextLog.push(lastItem);
+						selectedShape.setBounds(lastItem[2]);
+					}
+				} else if (lastItem[0] = "selected") {
+					
+				} else if (lastItem[0] = "deselected" ) {
+				
+				}
+			undoPressed = false;
+			undoPressed = 0;
+			prevLog.pop();
+			} 
+			
+
+		}
+
+		function redoMovement() {
+
+			var lastItem = nextLog[nextLog.length - 1];
+			var secondToLastItem = nextLog[nextLog.length - 2];
+			var correctIndex;
+
+			if (undoPressed >= 1) {
+				correctIndex = lastItem;
+			} else {
+				correctIndex = secondToLastItem;
+				undoPressed++;
+			}
+
+			//If the history log is not empty
+			if (nextLog.length > 1) {
+				prevLog.push(lastItem);
+
+				//If undo has been pressed
+				
+					if (lastItem[1] == ("polygon") || lastItem[1] == ("polyline")){
+						selectedShape.setPath(correctIndex[2]);
+					} else {
+						selectedShape.setBounds(correctIndex[2]);
+					}
+				
+				undoPressed = false;
+				redoPressed = true;
+				nextLog.pop();
+			}
+		}
+		
+		function dragStartFunction(){
+		
+		}
+		
+		function polygonGetPath() {
+			var overlayType = prevLog[(prevLog.length - 1)]._selectedShapes[0].type;
+			//console.log(prevLog);
+			//console.log(prevLog[(prevLog.length - 1)]._selectedShapes[0].type == polygon);
+			if(prevLog[(prevLog.length - 1)]._selectedShapes){
+			console.log(prevLog[(prevLog.length - 1)]._selectedShapes[0].type);
+				if (overlayType = ("circle" || "rectangle")) {
+				console.log("It's a "+ overlayType);
+				} else if (overlayType = ("polygon" || "polyline")){
+				console.log("It's a "+ overlayType);
+				}
+			}
+		}
+
+		function deleteSelectedShape() {
+			for (var i = 0; i < selectedShapes.length; i++) {
+				selectedShapes[i].setMap(null);
+			}
+			selectedShapes = [];
+		}
+
+		function deleteAllShape() {
+			for (var i = 0; i < overlays.length; i++) {
+				overlays[i].setMap(null);
+
+			}
+			overlays = [];
+		}
+
+	</script>
+	<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyBzunGwIF2OwsfrOkIC_8bhh0OPGZXo52Y&libraries=drawing&callback=initMap" async defer></script>
+	<script src="shortcuts.js"></script>
+  </body>
+</html>
Index: /gs3-extensions/map-editor/DrawingManager/checkpoints-singlefile/index backup v2.html
===================================================================
--- /gs3-extensions/map-editor/DrawingManager/checkpoints-singlefile/index backup v2.html	(revision 32709)
+++ /gs3-extensions/map-editor/DrawingManager/checkpoints-singlefile/index backup v2.html	(revision 32709)
@@ -0,0 +1,282 @@
+<!DOCTYPE html>
+<html>
+  <head>
+	<title>Drawing Tools</title>
+	<meta name="viewport" content="initial-scale=1.0, user-scalable=no">
+	<meta charset="utf-8">
+	<style>
+	  /* Always set the map height explicitly to define the size of the div
+	   * element that contains the map. */
+	  #map {
+		height: 83%;
+		float: bottom;
+	  }
+	  /* Optional: Makes the sample page fill the window. */
+	  html, body {
+		height: 100%;
+		width: 100%;
+		margin: 0;
+		padding: 0;
+	  }
+	  #buttons{
+	  display: inline-block;
+	  float: top;
+	  padding-left: 10px;
+	  padding-top: 5px;
+	  h: 10%;
+	  }
+	  #buttons2{
+	  display: inline-block;
+	  float top
+	  padding-left: 10px;
+	  padding-top: 5px;
+	  h: 10%;
+	  }
+	  #buttons3{
+	  display: inline-block;
+	  float top
+	  padding-left: 10px;
+	  padding-top: 5px;
+	  h: 10%;
+	  }	  
+	</style>
+  </head>
+  <body>
+	<div id = "buttons">
+	<button onclick="removeLine()" accesskey="z">Delete Last</button>
+	<button onclick="deleteAllShape()" accesskey="c">Clear All</button>
+	<button onclick="deleteSelectedShape()" accesskey="c">Delete Selected</button>
+	<p>Line thickness: <input type="range" min="20" max="100" value="1" class="slider" id="thicknessRange"> </p>
+	<p>Value: <span id="thicknessRangeVal"></span></p>
+	
+	</div>
+	<div id = "buttons2">
+	<p>Colour opacity: <input type="range" min="10" max="100" value="40" class="slider" id="colourOpacity"> </p>
+	<p>Value: <span id="opacityRangeVal"></span></p>
+	</div>
+	
+	<div id = "buttons3">
+	<p> Geodesic: <input type="checkbox" id="geodesicBox" onclick="geodesicCheck()"> </p>
+	</div>
+	
+	<div id="map"></div>
+	
+	<script>
+	    var thicknessValue = 1;
+		var opacityValue = 0.4;
+		var polyOptions = {
+			fillColor: '#CA4A2F',
+			strokeWeight: thicknessValue,
+			fillOpacity: opacityValue,
+			editable: true,
+			draggable: true,
+			geodesic : false,
+			//zIndex: 1
+		  };
+		  
+		var overlays = [];
+		var drawingManager;
+		var selectedShape;
+		
+		function geodesicCheck (){
+			var checkBox = document.getElementById("geodesicBox");
+			if (checkBox.checked == true){
+				polyOptions.geodesic = true;
+			}
+			else {
+				polyOptions.geodesic = false;
+			}
+			console.log(polyOptions.geodesic);
+		}
+		//Update thickness 
+		var thicknessSlider = document.getElementById("thicknessRange");
+		var thicknessSliderOutput = document.getElementById("thicknessRangeVal");
+		thicknessSliderOutput.innerHTML = thicknessSlider.value/20;
+		
+		thicknessSlider.oninput = function() {
+			thicknessSliderOutput.innerHTML = this.value/20;
+			thicknessValue = this.value/20;
+			polyOptions.strokeWeight = thicknessValue;
+		}
+		
+		//Update opacity
+		var opacitySlider = document.getElementById("colourOpacity");
+		var opacitySliderOutput = document.getElementById("thicknessRangeVal");	
+		//opacitySliderOutput.innerHTML = opacitySlider.value/100;
+		
+		opacitySlider.oninput = function() {
+			opacityValue = this.value/100;
+			polyOptions.fillOpacity = opacityValue;
+			opacitySliderOutput = opacityValue;
+			opacityRangeVal.innerHTML = opacitySliderOutput;
+		}
+		
+		
+	  function initMap() {
+	  
+		var map = new google.maps.Map(document.getElementById('map'), {
+		  center: {lat: -34.397, lng: 150.644},
+		  zoom: 3
+		});
+		
+		//Update the strokeWeight value (NOT BEING USED NOW)
+		//document.getElementById("thicknessRange").addEventListener("mouseup", selectThickness);
+        //
+		//function selectThickness (shape) {
+		//	if  (shape.type !== 'marker') {
+		//
+		//		thicknessValue = thicknessRange.value/20;
+		//		console.log("Slider Val= ", thicknessRange.value, "Strokeweight Val= ", thicknessValue);
+		//	}
+		//}
+		//
+		//console.log(polyOptions.strokeWeight);
+		  
+
+	
+		drawingManager = new google.maps.drawing.DrawingManager({
+			drawingMode: google.maps.drawing.OverlayType.MARKER,
+			drawingControl: true,
+			drawingControlOptions: {
+				position: google.maps.ControlPosition.TOP_CENTER,
+				drawingModes: ['marker', 'circle', 'polygon', 'polyline', 'rectangle']
+			},
+			markerOptions: { draggable: true},
+			circleOptions: polyOptions,
+			polylineOptions : polyOptions,
+			polygonOptions: polyOptions,
+			rectangleOptions: polyOptions,
+		  });
+	
+		drawingManager.setMap(map);
+		
+		
+		//overlays.push(event.overlay); // store reference to added overlay
+		google.maps.event.addListener(drawingManager, 'overlaycomplete', function (e) {
+			overlays.push(e.overlay); // store reference to added overlay
+			//console.log(overlays);
+			var newShape = e.overlay;
+					
+			newShape.type = e.type;
+					console.log("e", e);
+			if (e.type !== google.maps.drawing.OverlayType.MARKER) {
+				// Switch back to non-drawing mode after drawing a shape.
+				//drawingManager.setDrawingMode(null);
+
+				// Add an event listener that selects the newly-drawn shape when the user
+				// mouses down on it.
+				google.maps.event.addListener(newShape, 'click', function(e) {
+					initialSelection(e,newShape)
+					});
+					
+				//google.maps.event.addListener(newShape, 'mouseover', function(e) {
+				//	clearSelection();
+				//	initialSelection(e,newShape)
+				//	});
+
+				//google.maps.event.addListener(newShape, 'mouseout', function(e) {
+				//	clearSelection();
+				//	});					
+					
+					
+				setSelection(newShape);
+				console.log("Reached there");
+			}
+			else {
+				google.maps.event.addListener(newShape, 'click', function (e) {
+					setSelection(newShape);
+					console.log("Reached here");
+				});
+				setSelection(newShape);
+			}
+		});
+		
+		
+		function initialSelection(e,newShape) {
+			if (e.vertex !== undefined) {
+				if (newShape.type === google.maps.drawing.OverlayType.POLYGON) {
+					var path = newShape.getPaths().getAt(e.path);
+					path.removeAt(e.vertex);
+					if (path.length < 3) {
+						newShape.setMap(null);
+					}
+				}
+				if (newShape.type === google.maps.drawing.OverlayType.POLYLINE) {
+					var path = newShape.getPath();
+					path.removeAt(e.vertex);
+					if (path.length < 2) {
+						newShape.setMap(null);
+					}
+				}
+			}
+			
+			setSelection(newShape);
+		}
+				
+		function clearSelection () {
+			if (selectedShape) {
+				if (selectedShape.type !== 'marker') {
+					selectedShape.setEditable(false);
+				}
+					
+				selectedShape = null;
+			}
+		}
+
+		function setSelection (shape) {
+			if (shape.type !== 'marker') {
+				clearSelection();
+				shape.setEditable(true);
+				//selectColor(shape.get('fillColor') || shape.get('strokeColor'));
+				//console.log(shape.get('fillColor'), thicknessValue);
+				
+				//console.log(shape);
+				//if (shape.type == 'polyline'){
+				//console.log(shape);
+				//console.log(shape.De.bounds);
+				//}
+				//else if (shape.type ==  'rectangle'){
+				//console.log(shape);
+				//console.log(shape.bounds);
+				//}
+				//else if (shape.type == 'polygon'){
+				//console.log(shape);
+				//console.log(shape.geodesic);				
+				//}
+				
+			}
+			else{
+			console.log(shape);
+			}
+				
+			selectedShape = shape;
+		} 
+		
+}
+		
+		
+	  
+function deleteSelectedShape () {
+	if (selectedShape) {
+		selectedShape.setMap(null);
+	}
+}
+			
+function removeLine() {
+	var lastOverlay = overlays.pop();
+	if (lastOverlay) lastOverlay.setMap(null);
+		console.log("DONE");
+	}
+		
+function deleteAllShape() {
+	for (var i=0; i < overlays.length; i++) {
+		overlays[i].setMap(null);
+	}
+	overlays = [];
+}
+
+	</script>
+	<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyBzunGwIF2OwsfrOkIC_8bhh0OPGZXo52Y&libraries=drawing&callback=initMap"
+		 async defer></script>
+  </body>
+</html>
Index: /gs3-extensions/map-editor/DrawingManager/checkpoints-singlefile/index backup v20.html
===================================================================
--- /gs3-extensions/map-editor/DrawingManager/checkpoints-singlefile/index backup v20.html	(revision 32709)
+++ /gs3-extensions/map-editor/DrawingManager/checkpoints-singlefile/index backup v20.html	(revision 32709)
@@ -0,0 +1,731 @@
+<!DOCTYPE html>
+<html>
+  <head>
+	<title>Drawing Tools</title>
+	<meta name="viewport" content="initial-scale=1.0, user-scalable=no">
+	<meta charset="utf-8">
+	<style>
+	  /* Always set the map height explicitly to define the size of the div
+	   * element that contains the map. */
+	  #map {
+		height: 83%;
+		width: 90;
+		float: bottom;
+		clear: both;
+	  }
+	  /* Optional: Makes the sample page fill the window. */
+	  html, body {
+		height: 100%;
+		width: 99%;
+		margin: 0;
+		padding: 0;
+
+	  }
+	  
+	  #DeleteButtons{
+	  display: inline-block;
+	  float: left;
+	  padding-left: 10px;
+	  padding-top: 5px;
+	  width: 100%
+
+	  }
+	  
+	  #LineThickness{
+	  display: inline-block;
+	  float: left;
+	  padding-left: 10px;
+	  padding-top: 5px;
+
+	  }
+	  
+	  #ColourOpacity{
+	  display: inline-block;
+	  float: left;
+	  padding-left: 10px;
+	  padding-top: 5px;
+
+	  }
+	  
+	  #buttons3{
+	  display: inline-block;
+	  float: left;
+	  padding-left: 10px;
+	  padding-top: 5px;
+
+	  }	  
+	  
+      #FillColour {
+	  display: inline-block;
+	  float: left;
+	  padding-left: 10px;
+	  padding-top: 5px;
+	  }
+	  
+      #color-palette1 {
+      clear: both;
+      }
+	  
+      .color-buttons1 {
+      width: 14px;
+      height: 14px;
+      font-size: 0;
+      margin: 2px;
+      float: left;
+      cursor: pointer;
+      }
+
+
+	</style>
+  </head>
+  <body>
+	<div id = "DeleteButtons">
+	<button onclick="deleteAllShape()" accesskey="c">Clear All</button>
+	<button onclick="deleteSelectedShape()" accesskey="b">Delete Selected</button>
+	<button onclick="polygonGetPath()" accesskey="q">Get Path</button>
+	<button onclick="undoMovement()" accesskey="n">Undo</button>
+	<button onclick="redoMovement()" accesskey="n">Redo</button>
+	
+	</div>
+	
+	<div id = "LineThickness">
+	<p>Line thickness: <input type="range" min="20" max="100" value="1" class="slider" id="thicknessRange"> </p>
+	<p>Value: <span id="thicknessRangeVal"></span></p>
+	</div>	
+	
+	<div id = "ColourOpacity">
+	<p>Colour opacity: <input type="range" min="10" max="100" value="40" class="slider" id="colourOpacity"> </p>
+	<p>Value: <span id="opacityRangeVal"></span></p>
+	</div>
+	
+
+
+	<div id="FillColour">
+     <p> Fill Colour:</p> <div id="color-palette1"></div> 
+	</div>
+
+	
+	
+	<div id="map"></div>
+	
+	<script>
+		var debug = false;
+		var redoPressed = false;
+		var undoPressed = 0;
+		var shiftKeyPressed = false;
+		var dragFired = false;
+		var selectionPass = true;
+		var chosen;
+
+		var prevEdge = {
+			east: "",
+			north: "",
+			south: "",
+			west: ""
+		}
+		var nextEdge = {
+			east: "",
+			north: "",
+			south: "",
+			west: ""
+		}
+		var prevVertex = {
+			lat: "",
+			lng: ""
+		};
+		var nextVertex = {
+			lat: "",
+			lng: ""
+		};
+		var deselectedLog = []
+		var selectedShapesLog = [];
+		var prevShape = [];
+		var nextShape = [];
+		var prevLog = [];
+		var nextLog = [];
+		var dragged = 0;
+		var colors = ['#1E90FF', '#FF1493', '#4B0082', '#32CD32', '#FF8C00', '#000000'];
+		var selectedColor;
+		var colorButtons = {};
+		var thicknessValue = 1;
+		var opacityValue = 0.4;
+		var polyOptions = {
+			fillColor: '#CA4A2F',
+			strokeWeight: thicknessValue,
+			fillOpacity: opacityValue,
+			editable: true,
+			draggable: true,
+			geodesic: false,
+		};
+
+		var overlays = [];
+		var drawingManager;
+		var selectedShape;
+		var selectedShapes = [];
+		
+
+		//Update thickness
+		var thicknessSlider = document.getElementById("thicknessRange");
+		var thicknessSliderOutput = document.getElementById("thicknessRangeVal");
+		thicknessSliderOutput.innerHTML = thicknessSlider.value / 20;
+
+		thicknessSlider.oninput = function () {
+			thicknessSliderOutput.innerHTML = this.value / 20;
+			thicknessValue = this.value / 20;
+			polyOptions.strokeWeight = thicknessValue;
+			setSelectedThickness(thicknessValue);
+		}
+
+		//Update opacity
+		var opacitySlider = document.getElementById("colourOpacity");
+		var opacitySliderOutput = document.getElementById("opacityRangeVal");
+		opacitySliderOutput.innerHTML = "% " + Math.round(opacitySlider.value);
+
+		opacitySlider.oninput = function () {
+			opacityValue = this.value / 100;
+			polyOptions.fillOpacity = opacityValue;
+			opacitySliderOutput = opacityValue;
+			opacityRangeVal.innerHTML = "% " + Math.round(opacitySliderOutput * 100);
+			setSelectedOpacity(opacityValue);
+		}
+
+		////////////////////////////////////////////////////////////////////////////////////////
+		function makeColorButton(color) {
+			var button = document.createElement('span');
+			button.className = 'color-buttons1';
+			button.style.backgroundColor = color;
+			google.maps.event.addDomListener(button, 'click', function () {
+				selectColor(color);
+				setSelectedShapeColor(color);
+			});
+			return button;
+		}
+		function buildColorPalette() {
+			var colorPalette = document.getElementById('color-palette1');
+			for (var i = 0; i < colors.length; ++i) {
+				var currColor = colors[i];
+				var colorButton = makeColorButton(currColor);
+				colorPalette.appendChild(colorButton);
+				colorButtons[currColor] = colorButton;
+			}
+			selectColor(colors[0]);
+		};
+		function selectColor(color) {
+			selectedColor = color;
+			for (var i = 0; i < colors.length; ++i) {
+				var currColor = colors[i];
+				colorButtons[currColor].style.border = currColor == color ? '2px solid #789' : '2px solid #fff';
+			}
+
+			// Retrieves the current options from the drawing manager and replaces the
+			// stroke or fill color as appropriate.
+			var polylineOptions = drawingManager.get('polylineOptions');
+			polylineOptions.strokeColor = color;
+			drawingManager.set('polylineOptions', polylineOptions);
+
+			var rectangleOptions = drawingManager.get('rectangleOptions');
+			rectangleOptions.fillColor = color;
+			drawingManager.set('rectangleOptions', rectangleOptions);
+
+			var circleOptions = drawingManager.get('circleOptions');
+			circleOptions.fillColor = color;
+			drawingManager.set('circleOptions', circleOptions);
+
+			var polygonOptions = drawingManager.get('polygonOptions');
+			polygonOptions.fillColor = color;
+			drawingManager.set('polygonOptions', polygonOptions);
+		}
+
+		function initMap() {
+
+			var map = new google.maps.Map(document.getElementById('map'), {
+					center: {
+						lat: -34.397,
+						lng: 150.644
+					},
+					zoom: 2,
+					//mapTypeId: 'map'
+
+				});
+
+			drawingManager = new google.maps.drawing.DrawingManager({
+					drawingMode: google.maps.drawing.OverlayType.RECTANGLE,
+					drawingControl: true,
+					drawingControlOptions: {
+						position: google.maps.ControlPosition.TOP_CENTER,
+						drawingModes: ['marker', 'circle', 'polygon', 'polyline', 'rectangle']
+					},
+					markerOptions: {
+						draggable: true
+					},
+					circleOptions: polyOptions,
+					polylineOptions: polyOptions,
+					polygonOptions: polyOptions,
+					rectangleOptions: polyOptions,
+				});
+
+			drawingManager.setMap(map);
+
+			//overlays.push(event.overlay); // store reference to added overlay
+			google.maps.event.addListener(drawingManager, 'overlaycomplete', function (e) {
+				overlays.push(e.overlay); // store reference to added overlay
+				var newShape = e.overlay;
+				newShape.type = e.type;
+				
+				newShapeCreated(e);
+				
+				
+				if (e.type !== google.maps.drawing.OverlayType.MARKER) {
+
+					// Switch back to non-drawing mode after drawing a shape.
+					//drawingManager.setDrawingMode(null);
+
+					// Add an event listener that selects the newly-drawn shape when the user
+					// mouses down on it.
+					google.maps.event.addListener(newShape, 'click', function (e) {
+						dragFired
+						vertexAndPolyDel(e, newShape);
+						mousedDownFired = false;
+						return;
+
+					});
+
+					//Stores past event information
+					google.maps.event.addListener(newShape, 'dragstart', function () {
+						dragStartFunction(e, newShape);
+					});
+
+					//Store information after the event ends
+					google.maps.event.addListener(newShape, 'dragend', function () {
+						dragEndFunction(e, newShape);
+					});
+
+					//Add an event listener to select a shape if the mouse hovers over it
+					google.maps.event.addListener(newShape, 'mousedown', function (e) {
+						if (drawingManager.drawingMode == null) {
+							setSelection(newShape, e);
+							dragFired = false;
+						}
+					});
+					setSelection(newShape, e);
+				} else {
+					//cLICK EVENT IF A MARKER IS CREATED
+					google.maps.event.addListener(newShape, 'click', function (e) {
+						setSelection(newShape, e);
+					});
+					setSelection(newShape, e);
+				}
+			});
+
+			//Deletes a vertex if clicked on it
+			function vertexAndPolyDel(e, newShape) {
+				var vertex = e.vertex;
+				
+				if (e.vertex !== undefined) {
+					if (newShape.type === google.maps.drawing.OverlayType.POLYGON) {
+						var path = newShape.getPaths().getAt(e.path);
+						path.removeAt(e.vertex);
+						if (path.length < 3) {
+							newShape.setMap(null);
+						}
+					}
+					if (newShape.type === google.maps.drawing.OverlayType.POLYLINE) {
+						var path = newShape.getPath();
+						path.removeAt(e.vertex);
+						if (path.length < 2) {
+							newShape.setMap(null);
+						}
+					}
+				}
+			}
+
+			function clearSelection() {
+				if (selectedShape) {
+					if (selectedShape.type !== 'marker') {
+						selectedShape.setEditable(false);
+						if (shiftKeyPressed == false) {
+							for (var i = 0; i < selectedShapes.length; i++) {
+								selectedShapes[i].setEditable(false);
+							}
+							selectedShapes = [];
+						}
+					}
+					selectedShape = null;
+				}
+			}
+			var i = 0;
+			
+			//Set selection for the selected overlay
+			function setSelection(shape, e) {
+				if (shape.type !== 'marker') {
+					if (shiftKeyPressed == false) {
+						if (e.vertex == undefined) {
+							clearSelection();
+							shape.setEditable(true);
+						}
+					}
+					if (selectedShapes.includes(shape)) {
+					
+						//shape.setEditable(false);
+						const index = selectedShapes.indexOf(shape);
+						selectedShapes.splice(index, 1);	
+					} else {
+						shape.setEditable(true);
+						selectedShapes.push(shape);
+					}
+	
+					if (debug) {
+						console.log(" len = " + selectedShapes.length);
+					}
+					//Send the values to be updated
+					var thi = shape.strokeWeight;
+					var opa = shape.fillOpacity;
+					var fCol = shape.fillColor;
+					var sCol = shape.strokeColor;
+					updateMenuValues(thi, opa, fCol, sCol);
+
+				} else if (shape.type == 'marker') {
+					clearSelection();
+				}
+				
+				
+				
+				selectedShape = shape;
+				
+				if (selectionPass == true){
+
+					selectedShapesLog.push("selected", shiftKeyPressed, selectedShape);
+					nextLog.push(selectedShapesLog);
+					chosen = selectedShape;
+					selectionPass = false
+				}
+				
+				var lastItem = nextLog[nextLog.length -1];
+				
+				if(chosen !== selectedShape){
+					if(dragFired == false){
+					selectedShapesLog.push("selected", shiftKeyPressed, selectedShape)
+					updateHistory(selectedShapesLog);
+					chosen = selectedShape;
+					}
+				}
+
+				//console.log(nextLog);
+				//console.log(prevLog);
+				selectedShapesLog = [];
+			}
+
+			//Clears selection if clicked on the map when shift is not presseed
+			google.maps.event.addListener(map, 'click', function () {
+				if (shiftKeyPressed == false) {
+					clearSelection();
+					if(chosen !== null) {
+						deselectedLog.push("deselected")
+						updateHistory(deselectedLog);
+						deselectedLog = [];
+						chosen = null;
+						
+					}
+				}
+				//console.log(nextLog);
+				//console.log(prevLog);
+			});
+
+
+			
+			
+			
+			//Setting drawing tool option
+			document.addEventListener('keydown', function () {
+				//if (event.code == 'KeyX' && (event.ctrlKey || event.metaKey))
+				if (event.code == 'Digit0' || event.code == 'Numpad0' || event.code == 'Backquote') {
+					//clearSelection();
+					drawingManager.setDrawingMode(null);
+				} else if (event.code == 'Digit1') {
+					drawingManager.setDrawingMode('marker');
+				} else if (event.code == 'Digit2') {
+					drawingManager.setDrawingMode('circle');
+				} else if (event.code == 'Digit3') {
+					drawingManager.setDrawingMode('polygon');
+				} else if (event.code == 'Digit4') {
+					drawingManager.setDrawingMode('polyline');
+				} else if (event.code == 'Digit5') {
+					drawingManager.setDrawingMode('rectangle');
+				} else if(event.code == 'KeyQ') {
+					polygonGetPath();
+				}
+				//					console.log(event.code);
+			});
+
+			//Sets shift as pressed
+			document.addEventListener('keydown', function () {
+				if (event.code == 'ShiftLeft' || event.code == 'ShiftRight') {
+					shiftKeyPressed = true;
+
+				}
+
+			});
+
+			//Sets shift as unpressed
+			document.addEventListener('keyup', function () {
+				if (event.code == 'ShiftLeft' || event.code == 'ShiftRight') {
+					shiftKeyPressed = false;
+				}
+
+			});
+
+			buildColorPalette();
+		}
+		//Set selected thickness
+		function setSelectedThickness(sWeight) {
+			if (selectedShape) {
+				//selectedShape.set('strokeWeight', sWeight)
+			}
+			if (selectedShapes !== 0) {
+				for (var i = 0; i < selectedShapes.length; i++) {
+					selectedShapes[i].set('strokeWeight', sWeight);
+					//console.log(selectedShapes.length);
+				}
+			}
+		}
+
+		//Set selected opacity
+		function setSelectedOpacity(fOpacity) {
+			if (selectedShape) {
+				//selectedShape.set('fillOpacity', fOpacity)
+			}
+			if (selectedShapes !== 0) {
+				for (var i = 0; i < selectedShapes.length; i++) {
+					selectedShapes[i].set('fillOpacity', fOpacity);
+				}
+			}
+		}
+
+		//set selected fill colour
+		function setSelectedShapeColor(color) {
+			if (selectedShapes !== 0) {
+				for (var i = 0; i < selectedShapes.length; i++) {
+					selectedShapes[i].set('fillColor', color);
+					selectedShapes[i].set('strokeColor', color);
+				}
+			}
+		}
+
+		function updateMenuValues(thi, opa, fCol, sCol) {
+
+			//Update thickness slider and value on the settings menu
+			var thicknessSliderOutput = document.getElementById("thicknessRangeVal");
+			thicknessSliderOutput.innerHTML = thi;
+			document.getElementById("thicknessRange").value = thi * 20;
+
+			//Update the opacity slider and value on the settings menu
+			var opacitySliderOutput = document.getElementById("opacityRangeVal");
+			opacitySliderOutput.innerHTML = "% " + opa * 100;
+			document.getElementById("colourOpacity").value = opa * 100;
+
+			if (drawingManager.drawingMode == null) {
+				selectColor(fCol);
+			}
+		}
+		function undoMovement() {
+			var lastItem = prevLog[prevLog.length - 1];
+
+			//If history array is not empty
+			if (prevLog.length !== 0) {
+				if(lastItem[0] = "dragStart"){
+					//If the array has more than one index (polygons and polylines)
+					if (lastItem[1] == ("polygon") || lastItem[1] == ("polyline")) {
+						nextLog.push(lastItem);
+						selectedShape.setPath(lastItem[2]);
+
+					//If the array has only one index(rectangles and circles)
+					} else {
+						nextLog.push(lastItem);
+						selectedShape.setBounds(lastItem[2]);
+					}
+				} else if (lastItem[0] = "selected") {
+					
+				} else if (lastItem[0] = "deselected" ) {
+				
+				}
+			undoPressed = false;
+			undoPressed = 0;
+			prevLog.pop();
+			} 
+			
+
+		}
+
+		function redoMovement() {
+
+			var lastItem = nextLog[nextLog.length - 1];
+			var secondToLastItem = nextLog[nextLog.length - 2];
+			var correctIndex;
+
+			if (undoPressed >= 1) {
+				correctIndex = lastItem;
+			} else {
+				correctIndex = secondToLastItem;
+				undoPressed++;
+			}
+
+			//If the history log is not empty
+			if (nextLog.length > 1) {
+				prevLog.push(lastItem);
+
+				//If undo has been pressed
+				
+					if (lastItem[1] == ("polygon") || lastItem[1] == ("polyline")){
+						selectedShape.setPath(correctIndex[2]);
+					} else {
+						selectedShape.setBounds(correctIndex[2]);
+					}
+				
+				undoPressed = false;
+				redoPressed = true;
+				nextLog.pop();
+			}
+		}
+		
+		function dragStartFunction(e, selectedShape){
+			var newShape = e.overlay;
+			newShape.type = e.type;
+			if (selectedShape) {
+				var polyG = newShape.type === google.maps.drawing.OverlayType.POLYLINE;
+				var polyL = newShape.type === google.maps.drawing.OverlayType.POLYGON;
+				
+				if (polyL || polyG) {
+					var latLngi = []
+					var lati,
+					lngi;
+					for (var i = 0; i < selectedShape.getPath().length; i++) {
+						lati = selectedShape.getPath().getAt(i).lat();
+						lngi = selectedShape.getPath().getAt(i).lng();
+						//console.log("Vertex number",i, "'s latitude is", lati, "and longitude is", lngi);
+						prevVertex = {
+							lat: lati,
+							lng: lngi
+						};
+						latLngi.push(prevVertex);
+					}
+					prevShape.push("dragStart", selectedShape.type, latLngi);	
+				} else {
+					prevEdge = {
+						east: selectedShape.getBounds().ea.l,
+						north: selectedShape.getBounds().la.l,
+						south: selectedShape.getBounds().la.j,
+						west: selectedShape.getBounds().ea.j
+					}
+					prevShape.push("dragStart", selectedShape.type, prevEdge);
+				}
+				var lastItem = nextLog[nextLog.length - 1];
+				if(lastItem[0] !== "dragEnd"){
+					prevLog.push(nextLog[nextLog.length -1]);
+				}
+				
+				prevLog.push(prevShape);
+				prevShape = [];
+				nextLog = [];
+				chosen = selectedShape;
+				dragFired = true;
+			}
+		}
+		
+		function dragEndFunction(e, newShape) {
+		
+		var newShape = e.overlay;
+		newShape.type = e.type;
+		if (selectedShape) {
+			var polyG = newShape.type === google.maps.drawing.OverlayType.POLYLINE;
+			var polyL = newShape.type === google.maps.drawing.OverlayType.POLYGON;
+			
+			if (polyL || polyG) {
+			
+				var latLngi = []
+				var lati,
+				lngi;
+	
+				for (var i = 0; i < selectedShape.getPath().length; i++) {
+					lati = selectedShape.getPath().getAt(i).lat();
+					lngi = selectedShape.getPath().getAt(i).lng();
+					//console.log("Vertex number",i, "'s latitude is", lati, "and longitude is", lngi);
+					nextVertex = {
+						lat: lati,
+						lng: lngi
+					};
+					latLngi.push(nextVertex);
+				}
+				nextShape.push("dragEnd", selectedShape.type, latLngi);
+			} else {
+
+				nextEdge.east = selectedShape.getBounds().ea.l;
+				nextEdge.north = selectedShape.getBounds().la.l;
+				nextEdge.south = selectedShape.getBounds().la.j;
+				nextEdge.west = selectedShape.getBounds().ea.j;
+				
+
+				nextShape.push("dragEnd", selectedShape.type, nextEdge);
+			}
+			
+			nextLog.push(nextShape);
+			nextShape = [];
+			chosen = selectedShape;
+			}
+		}
+		
+		function updateHistory(eventArray){
+			var lastItem = nextLog[nextLog.length - 1];
+			if(lastItem[0] !== "dragEnd"){
+				if(nextLog.length >0){
+				prevLog.push(lastItem);
+				}
+			nextLog = [];
+			nextLog.push(eventArray);
+			eventArray = [];
+			
+			}
+			
+			
+		}		
+		
+		function newShapeCreated (e) {
+			//nextLog
+		}
+		
+		function polygonGetPath() {
+			//var overlayType = prevLog[(prevLog.length - 1)]._selectedShapes[0].type;
+			////console.log(prevLog);
+			////console.log(prevLog[(prevLog.length - 1)]._selectedShapes[0].type == polygon);
+			//if(prevLog[(prevLog.length - 1)]._selectedShapes){
+			//console.log(prevLog[(prevLog.length - 1)]._selectedShapes[0].type);
+			//	if (overlayType = ("circle" || "rectangle")) {
+			//	console.log("It's a "+ overlayType);
+			//	} else if (overlayType = ("polygon" || "polyline")){
+			//	console.log("It's a "+ overlayType);
+			//	}
+			//}
+			console.log(nextLog);
+			console.log(prevLog);
+			
+		}
+
+		function deleteSelectedShape() {
+			for (var i = 0; i < selectedShapes.length; i++) {
+				selectedShapes[i].setMap(null);
+			}
+			selectedShapes = [];
+		}
+
+		function deleteAllShape() {
+			for (var i = 0; i < overlays.length; i++) {
+				overlays[i].setMap(null);
+
+			}
+			overlays = [];
+		}
+
+	</script>
+	<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyBzunGwIF2OwsfrOkIC_8bhh0OPGZXo52Y&libraries=drawing&callback=initMap" async defer></script>
+	<script src="shortcuts.js"></script>
+  </body>
+</html>
Index: /gs3-extensions/map-editor/DrawingManager/checkpoints-singlefile/index backup v21.html
===================================================================
--- /gs3-extensions/map-editor/DrawingManager/checkpoints-singlefile/index backup v21.html	(revision 32709)
+++ /gs3-extensions/map-editor/DrawingManager/checkpoints-singlefile/index backup v21.html	(revision 32709)
@@ -0,0 +1,724 @@
+<!DOCTYPE html>
+<html>
+  <head>
+	<title>Drawing Tools</title>
+	<meta name="viewport" content="initial-scale=1.0, user-scalable=no">
+	<meta charset="utf-8">
+	<style>
+	  /* Always set the map height explicitly to define the size of the div
+	   * element that contains the map. */
+	  #map {
+		height: 83%;
+		width: 90;
+		float: bottom;
+		clear: both;
+	  }
+	  /* Optional: Makes the sample page fill the window. */
+	  html, body {
+		height: 100%;
+		width: 99%;
+		margin: 0;
+		padding: 0;
+
+	  }
+	  
+	  #DeleteButtons{
+	  display: inline-block;
+	  float: left;
+	  padding-left: 10px;
+	  padding-top: 5px;
+	  width: 100%
+
+	  }
+	  
+	  #LineThickness{
+	  display: inline-block;
+	  float: left;
+	  padding-left: 10px;
+	  padding-top: 5px;
+
+	  }
+	  
+	  #ColourOpacity{
+	  display: inline-block;
+	  float: left;
+	  padding-left: 10px;
+	  padding-top: 5px;
+
+	  }
+	  
+	  #buttons3{
+	  display: inline-block;
+	  float: left;
+	  padding-left: 10px;
+	  padding-top: 5px;
+
+	  }	  
+	  
+      #FillColour {
+	  display: inline-block;
+	  float: left;
+	  padding-left: 10px;
+	  padding-top: 5px;
+	  }
+	  
+      #color-palette1 {
+      clear: both;
+      }
+	  
+      .color-buttons1 {
+      width: 14px;
+      height: 14px;
+      font-size: 0;
+      margin: 2px;
+      float: left;
+      cursor: pointer;
+      }
+
+
+	</style>
+  </head>
+  <body>
+	<div id = "DeleteButtons">
+	<button onclick="deleteAllShape()" accesskey="c">Clear All</button>
+	<button onclick="deleteSelectedShape()" accesskey="b">Delete Selected</button>
+	<button onclick="polygonGetPath()" accesskey="q">Get Path</button>
+	<button onclick="undoMovement()" accesskey="n">Undo</button>
+	<button onclick="redoMovement()" accesskey="n">Redo</button>
+	
+	</div>
+	
+	<div id = "LineThickness">
+	<p>Line thickness: <input type="range" min="20" max="100" value="1" class="slider" id="thicknessRange"> </p>
+	<p>Value: <span id="thicknessRangeVal"></span></p>
+	</div>	
+	
+	<div id = "ColourOpacity">
+	<p>Colour opacity: <input type="range" min="10" max="100" value="40" class="slider" id="colourOpacity"> </p>
+	<p>Value: <span id="opacityRangeVal"></span></p>
+	</div>
+	
+
+
+	<div id="FillColour">
+     <p> Fill Colour:</p> <div id="color-palette1"></div> 
+	</div>
+
+	
+	
+	<div id="map"></div>
+	
+	<script>
+		var debug = false;
+		var redoPressed = false;
+		var undoPressed = 0;
+		var shiftKeyPressed = false;
+		var dragFired = false;
+		var selectionPass = true;
+		var chosen;
+
+		var prevEdge = {
+			east: "",
+			north: "",
+			south: "",
+			west: ""
+		}
+		var nextEdge = {
+			east: "",
+			north: "",
+			south: "",
+			west: ""
+		}
+		var prevVertex = {
+			lat: "",
+			lng: ""
+		};
+		var nextVertex = {
+			lat: "",
+			lng: ""
+		};
+		var deselectedLog = []
+		var selectedShapesLog = [];
+		var prevShape = [];
+		var nextShape = [];
+		var prevLog = [];
+		var nextLog = [];
+		var dragged = 0;
+		var colors = ['#1E90FF', '#FF1493', '#4B0082', '#32CD32', '#FF8C00', '#000000'];
+		var selectedColor;
+		var colorButtons = {};
+		var thicknessValue = 1;
+		var opacityValue = 0.4;
+		var polyOptions = {
+			fillColor: '#CA4A2F',
+			strokeWeight: thicknessValue,
+			fillOpacity: opacityValue,
+			editable: true,
+			draggable: true,
+			geodesic: false,
+		};
+
+		var overlays = [];
+		var drawingManager;
+		var selectedShape;
+		var selectedShapes = [];
+		
+
+		//Update thickness
+		var thicknessSlider = document.getElementById("thicknessRange");
+		var thicknessSliderOutput = document.getElementById("thicknessRangeVal");
+		thicknessSliderOutput.innerHTML = thicknessSlider.value / 20;
+
+		thicknessSlider.oninput = function () {
+			thicknessSliderOutput.innerHTML = this.value / 20;
+			thicknessValue = this.value / 20;
+			polyOptions.strokeWeight = thicknessValue;
+			setSelectedThickness(thicknessValue);
+		}
+
+		//Update opacity
+		var opacitySlider = document.getElementById("colourOpacity");
+		var opacitySliderOutput = document.getElementById("opacityRangeVal");
+		opacitySliderOutput.innerHTML = "% " + Math.round(opacitySlider.value);
+
+		opacitySlider.oninput = function () {
+			opacityValue = this.value / 100;
+			polyOptions.fillOpacity = opacityValue;
+			opacitySliderOutput = opacityValue;
+			opacityRangeVal.innerHTML = "% " + Math.round(opacitySliderOutput * 100);
+			setSelectedOpacity(opacityValue);
+		}
+
+		////////////////////////////////////////////////////////////////////////////////////////
+		function makeColorButton(color) {
+			var button = document.createElement('span');
+			button.className = 'color-buttons1';
+			button.style.backgroundColor = color;
+			google.maps.event.addDomListener(button, 'click', function () {
+				selectColor(color);
+				setSelectedShapeColor(color);
+			});
+			return button;
+		}
+		function buildColorPalette() {
+			var colorPalette = document.getElementById('color-palette1');
+			for (var i = 0; i < colors.length; ++i) {
+				var currColor = colors[i];
+				var colorButton = makeColorButton(currColor);
+				colorPalette.appendChild(colorButton);
+				colorButtons[currColor] = colorButton;
+			}
+			selectColor(colors[0]);
+		};
+		function selectColor(color) {
+			selectedColor = color;
+			for (var i = 0; i < colors.length; ++i) {
+				var currColor = colors[i];
+				colorButtons[currColor].style.border = currColor == color ? '2px solid #789' : '2px solid #fff';
+			}
+
+			// Retrieves the current options from the drawing manager and replaces the
+			// stroke or fill color as appropriate.
+			var polylineOptions = drawingManager.get('polylineOptions');
+			polylineOptions.strokeColor = color;
+			drawingManager.set('polylineOptions', polylineOptions);
+
+			var rectangleOptions = drawingManager.get('rectangleOptions');
+			rectangleOptions.fillColor = color;
+			drawingManager.set('rectangleOptions', rectangleOptions);
+
+			var circleOptions = drawingManager.get('circleOptions');
+			circleOptions.fillColor = color;
+			drawingManager.set('circleOptions', circleOptions);
+
+			var polygonOptions = drawingManager.get('polygonOptions');
+			polygonOptions.fillColor = color;
+			drawingManager.set('polygonOptions', polygonOptions);
+		}
+
+		function initMap() {
+
+			var map = new google.maps.Map(document.getElementById('map'), {
+					center: {
+						lat: -34.397,
+						lng: 150.644
+					},
+					zoom: 2,
+					//mapTypeId: 'map'
+
+				});
+
+			drawingManager = new google.maps.drawing.DrawingManager({
+					drawingMode: google.maps.drawing.OverlayType.RECTANGLE,
+					drawingControl: true,
+					drawingControlOptions: {
+						position: google.maps.ControlPosition.TOP_CENTER,
+						drawingModes: ['marker', 'circle', 'polygon', 'polyline', 'rectangle']
+					},
+					markerOptions: {
+						draggable: true
+					},
+					circleOptions: polyOptions,
+					polylineOptions: polyOptions,
+					polygonOptions: polyOptions,
+					rectangleOptions: polyOptions,
+				});
+
+			drawingManager.setMap(map);
+
+			//overlays.push(event.overlay); // store reference to added overlay
+			google.maps.event.addListener(drawingManager, 'overlaycomplete', function (e) {
+				overlays.push(e.overlay); // store reference to added overlay
+				var newShape = e.overlay;
+				newShape.type = e.type;
+				
+				newShapeCreated(e);
+				
+				
+				if (e.type !== google.maps.drawing.OverlayType.MARKER) {
+
+					// Switch back to non-drawing mode after drawing a shape.
+					//drawingManager.setDrawingMode(null);
+
+					// Add an event listener that selects the newly-drawn shape when the user
+					// mouses down on it.
+					google.maps.event.addListener(newShape, 'click', function (e) {
+						
+						vertexAndPolyDel(e, newShape);
+						dragFired = false;
+						console.log("click fired");
+						return;
+
+					});
+
+					//Stores past event information
+					google.maps.event.addListener(newShape, 'dragstart', function () {
+						dragStartFunction(e, newShape);
+					});
+
+					//Store information after the event ends
+					google.maps.event.addListener(newShape, 'dragend', function () {
+						dragEndFunction(e, newShape);
+					});
+
+					//Add an event listener to select a shape if the mouse hovers over it
+					google.maps.event.addListener(newShape, 'mousedown', function (e) {
+						if (drawingManager.drawingMode == null) {
+							setSelection(newShape, e);
+							console.log("mousedown fired");
+							dragFired = false;
+						}
+					});
+					setSelection(newShape, e);
+				} else {
+					//cLICK EVENT IF A MARKER IS CREATED
+					google.maps.event.addListener(newShape, 'click', function (e) {
+						setSelection(newShape, e);
+					});
+					setSelection(newShape, e);
+				}
+			});
+
+			//Deletes a vertex if clicked on it
+			function vertexAndPolyDel(e, newShape) {
+				var vertex = e.vertex;
+				
+				if (e.vertex !== undefined) {
+					if (newShape.type === google.maps.drawing.OverlayType.POLYGON) {
+						var path = newShape.getPaths().getAt(e.path);
+						path.removeAt(e.vertex);
+						if (path.length < 3) {
+							newShape.setMap(null);
+						}
+					}
+					if (newShape.type === google.maps.drawing.OverlayType.POLYLINE) {
+						var path = newShape.getPath();
+						path.removeAt(e.vertex);
+						if (path.length < 2) {
+							newShape.setMap(null);
+						}
+					}
+				}
+			}
+
+			function clearSelection() {
+				if (selectedShape) {
+					if (selectedShape.type !== 'marker') {
+						selectedShape.setEditable(false);
+						if (shiftKeyPressed == false) {
+							for (var i = 0; i < selectedShapes.length; i++) {
+								selectedShapes[i].setEditable(false);
+							}
+							selectedShapes = [];
+						}
+					}
+					selectedShape = null;
+				}
+			}
+			var i = 0;
+			
+			//Set selection for the selected overlay
+			function setSelection(shape, e) {
+				if (shape.type !== 'marker') {
+					if (shiftKeyPressed == false) {
+						if (e.vertex == undefined) {
+							clearSelection();
+							shape.setEditable(true);
+						}
+					}
+					if (selectedShapes.includes(shape)) {
+					
+						//shape.setEditable(false);
+						const index = selectedShapes.indexOf(shape);
+						selectedShapes.splice(index, 1);	
+					} else {
+						shape.setEditable(true);
+						selectedShapes.push(shape);
+					}
+	
+					if (debug) {
+						console.log(" len = " + selectedShapes.length);
+					}
+					//Send the values to be updated
+					var thi = shape.strokeWeight;
+					var opa = shape.fillOpacity;
+					var fCol = shape.fillColor;
+					var sCol = shape.strokeColor;
+					updateMenuValues(thi, opa, fCol, sCol);
+
+				} else if (shape.type == 'marker') {
+					clearSelection();
+				}
+				
+				
+				
+				selectedShape = shape;
+				
+				if (selectionPass == true){
+
+					selectedShapesLog.push("selected", shiftKeyPressed, selectedShape);
+					nextLog.push(selectedShapesLog);
+					chosen = selectedShape;
+					selectionPass = false
+				}
+				
+				var lastItem = nextLog[nextLog.length -1];
+				
+				if(chosen !== selectedShape){
+					if(dragFired == false){
+					console.log("it comes here");
+					selectedShapesLog.push("selected", shiftKeyPressed, selectedShape)
+					updateHistory(selectedShapesLog);
+					chosen = selectedShape;
+					}
+				}
+
+				console.log(chosen);
+				//console.log(prevLog);
+				selectedShapesLog = [];
+			}
+
+			//Clears selection if clicked on the map when shift is not presseed
+			google.maps.event.addListener(map, 'click', function () {
+				if (shiftKeyPressed == false) {
+					clearSelection();
+					if(chosen !== null) {
+						deselectedLog.push("deselected")
+						updateHistory(deselectedLog);
+						deselectedLog = [];
+						chosen = null;
+						console.log("chosen wasn't null");
+						
+					}
+				}
+				console.log(chosen);
+				//console.log(prevLog);
+			});
+
+
+			
+			
+			
+			//Setting drawing tool option
+			document.addEventListener('keydown', function () {
+				//if (event.code == 'KeyX' && (event.ctrlKey || event.metaKey))
+				if (event.code == 'Digit0' || event.code == 'Numpad0' || event.code == 'Backquote') {
+					//clearSelection();
+					drawingManager.setDrawingMode(null);
+				} else if (event.code == 'Digit1') {
+					drawingManager.setDrawingMode('marker');
+				} else if (event.code == 'Digit2') {
+					drawingManager.setDrawingMode('circle');
+				} else if (event.code == 'Digit3') {
+					drawingManager.setDrawingMode('polygon');
+				} else if (event.code == 'Digit4') {
+					drawingManager.setDrawingMode('polyline');
+				} else if (event.code == 'Digit5') {
+					drawingManager.setDrawingMode('rectangle');
+				} else if(event.code == 'KeyQ') {
+					polygonGetPath();
+				}
+				//					console.log(event.code);
+			});
+
+			//Sets shift as pressed
+			document.addEventListener('keydown', function () {
+				if (event.code == 'ShiftLeft' || event.code == 'ShiftRight') {
+					shiftKeyPressed = true;
+
+				}
+
+			});
+
+			//Sets shift as unpressed
+			document.addEventListener('keyup', function () {
+				if (event.code == 'ShiftLeft' || event.code == 'ShiftRight') {
+					shiftKeyPressed = false;
+				}
+
+			});
+
+			buildColorPalette();
+		}
+		//Set selected thickness
+		function setSelectedThickness(sWeight) {
+			if (selectedShape) {
+				//selectedShape.set('strokeWeight', sWeight)
+			}
+			if (selectedShapes !== 0) {
+				for (var i = 0; i < selectedShapes.length; i++) {
+					selectedShapes[i].set('strokeWeight', sWeight);
+					//console.log(selectedShapes.length);
+				}
+			}
+		}
+
+		//Set selected opacity
+		function setSelectedOpacity(fOpacity) {
+			if (selectedShape) {
+				//selectedShape.set('fillOpacity', fOpacity)
+			}
+			if (selectedShapes !== 0) {
+				for (var i = 0; i < selectedShapes.length; i++) {
+					selectedShapes[i].set('fillOpacity', fOpacity);
+				}
+			}
+		}
+
+		//set selected fill colour
+		function setSelectedShapeColor(color) {
+			if (selectedShapes !== 0) {
+				for (var i = 0; i < selectedShapes.length; i++) {
+					selectedShapes[i].set('fillColor', color);
+					selectedShapes[i].set('strokeColor', color);
+				}
+			}
+		}
+
+		function updateMenuValues(thi, opa, fCol, sCol) {
+
+			//Update thickness slider and value on the settings menu
+			var thicknessSliderOutput = document.getElementById("thicknessRangeVal");
+			thicknessSliderOutput.innerHTML = thi;
+			document.getElementById("thicknessRange").value = thi * 20;
+
+			//Update the opacity slider and value on the settings menu
+			var opacitySliderOutput = document.getElementById("opacityRangeVal");
+			opacitySliderOutput.innerHTML = "% " + opa * 100;
+			document.getElementById("colourOpacity").value = opa * 100;
+
+			if (drawingManager.drawingMode == null) {
+				selectColor(fCol);
+			}
+		}
+		function undoMovement() {
+			var lastItem = prevLog[prevLog.length - 1];
+
+			//If history array is not empty
+			if (prevLog.length !== 0) {
+				if(lastItem[0] = "dragStart"){
+					//If the array has more than one index (polygons and polylines)
+					if (lastItem[1] == ("polygon") || lastItem[1] == ("polyline")) {
+						nextLog.push(lastItem);
+						selectedShape.setPath(lastItem[2]);
+
+					//If the array has only one index(rectangles and circles)
+					} else {
+						nextLog.push(lastItem);
+						selectedShape.setBounds(lastItem[2]);
+					}
+				} else if (lastItem[0] = "selected") {
+					
+				} else if (lastItem[0] = "deselected" ) {
+				
+				}
+			undoPressed = false;
+			undoPressed = 0;
+			prevLog.pop();
+			} 
+			
+
+		}
+
+		function redoMovement() {
+
+			var lastItem = nextLog[nextLog.length - 1];
+			var secondToLastItem = nextLog[nextLog.length - 2];
+			var correctIndex;
+
+			if (undoPressed >= 1) {
+				correctIndex = lastItem;
+			} else {
+				correctIndex = secondToLastItem;
+				undoPressed++;
+			}
+
+			//If the history log is not empty
+			if (nextLog.length > 1) {
+				prevLog.push(lastItem);
+
+				//If undo has been pressed
+				
+					if (lastItem[1] == ("polygon") || lastItem[1] == ("polyline")){
+						selectedShape.setPath(correctIndex[2]);
+					} else {
+						selectedShape.setBounds(correctIndex[2]);
+					}
+				
+				undoPressed = false;
+				redoPressed = true;
+				nextLog.pop();
+			}
+		}
+		
+		function dragStartFunction(e, selectedShape){
+			var newShape = e.overlay;
+			newShape.type = e.type;
+			if (selectedShape) {
+				var polyG = newShape.type === google.maps.drawing.OverlayType.POLYLINE;
+				var polyL = newShape.type === google.maps.drawing.OverlayType.POLYGON;
+				
+				if (polyL || polyG) {
+					var latLngi = []
+					var lati,
+					lngi;
+					for (var i = 0; i < selectedShape.getPath().length; i++) {
+						lati = selectedShape.getPath().getAt(i).lat();
+						lngi = selectedShape.getPath().getAt(i).lng();
+						//console.log("Vertex number",i, "'s latitude is", lati, "and longitude is", lngi);
+						prevVertex = {
+							lat: lati,
+							lng: lngi
+						};
+						latLngi.push(prevVertex);
+					}
+					prevShape.push("dragStart", selectedShape.type, latLngi);	
+				} else {
+					prevEdge = {
+						east: selectedShape.getBounds().ea.l,
+						north: selectedShape.getBounds().la.l,
+						south: selectedShape.getBounds().la.j,
+						west: selectedShape.getBounds().ea.j
+					}
+					prevShape.push("dragStart", selectedShape.type, prevEdge);
+				}
+				
+				var lastItem = nextLog[nextLog.length - 1];
+				if(lastItem[0] !== "dragEnd"){
+					prevLog.push(nextLog[nextLog.length -1]);
+				}
+				
+				prevLog.push(prevShape);
+				prevShape = [];
+				nextLog = [];
+				chosen = selectedShape;
+				dragFired = true;
+			}
+		}
+		
+		function dragEndFunction(e, newShape) {
+
+			var newShape = e.overlay;
+			newShape.type = e.type;
+			if (selectedShape) {
+				var polyG = newShape.type === google.maps.drawing.OverlayType.POLYLINE;
+				var polyL = newShape.type === google.maps.drawing.OverlayType.POLYGON;
+		
+				if (polyL || polyG) {
+		
+					var latLngi = []
+					var lati,
+					lngi;
+		
+					for (var i = 0; i < selectedShape.getPath().length; i++) {
+						lati = selectedShape.getPath().getAt(i).lat();
+						lngi = selectedShape.getPath().getAt(i).lng();
+						nextVertex = {
+							lat: lati,
+							lng: lngi
+						};
+						latLngi.push(nextVertex);
+					}
+					nextShape.push("dragEnd", selectedShape.type, latLngi);
+				} else {
+		
+					nextEdge.east = selectedShape.getBounds().ea.l;
+					nextEdge.north = selectedShape.getBounds().la.l;
+					nextEdge.south = selectedShape.getBounds().la.j;
+					nextEdge.west = selectedShape.getBounds().ea.j;
+		
+					nextShape.push("dragEnd", selectedShape.type, nextEdge);
+				}
+			}
+			for (var i = 0; i < prevLog.length; i++) {
+				if (prevLog[i][0] == "dragEnd") {
+					const index = i;
+					prevLog.splice(index, 1);
+				}
+			}
+			nextLog.push(nextShape);
+			nextShape = [];
+			chosen = selectedShape;
+		}
+		
+		function updateHistory(eventArray) {
+			var lastItem = nextLog[nextLog.length - 1];
+			if (nextLog.length > 0) {
+				prevLog.push(lastItem);
+			}
+			nextLog = [];
+			nextLog.push(eventArray);
+			eventArray = [];
+			dragFired = false;
+		}		
+		
+		function newShapeCreated (e) {
+			//nextLog
+		}
+		
+		function polygonGetPath() {
+			console.log(nextLog);
+			console.log(prevLog);
+			
+		}
+
+		function deleteSelectedShape() {
+			for (var i = 0; i < selectedShapes.length; i++) {
+				selectedShapes[i].setMap(null);
+			}
+			selectedShapes = [];
+		}
+
+		function deleteAllShape() {
+			for (var i = 0; i < overlays.length; i++) {
+				overlays[i].setMap(null);
+
+			}
+			overlays = [];
+		}
+
+	</script>
+	<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyBzunGwIF2OwsfrOkIC_8bhh0OPGZXo52Y&libraries=drawing&callback=initMap" async defer></script>
+	<script src="shortcuts.js"></script>
+  </body>
+</html>
Index: /gs3-extensions/map-editor/DrawingManager/checkpoints-singlefile/index backup v3.html
===================================================================
--- /gs3-extensions/map-editor/DrawingManager/checkpoints-singlefile/index backup v3.html	(revision 32709)
+++ /gs3-extensions/map-editor/DrawingManager/checkpoints-singlefile/index backup v3.html	(revision 32709)
@@ -0,0 +1,281 @@
+<!DOCTYPE html>
+<html>
+  <head>
+	<title>Drawing Tools</title>
+	<meta name="viewport" content="initial-scale=1.0, user-scalable=no">
+	<meta charset="utf-8">
+	<style>
+	  /* Always set the map height explicitly to define the size of the div
+	   * element that contains the map. */
+	  #map {
+		height: 83%;
+		float: bottom;
+	  }
+	  /* Optional: Makes the sample page fill the window. */
+	  html, body {
+		height: 100%;
+		width: 100%;
+		margin: 0;
+		padding: 0;
+	  }
+	  #buttons{
+	  display: inline-block;
+	  float: top;
+	  padding-left: 10px;
+	  padding-top: 5px;
+	  h: 10%;
+	  }
+	  #buttons2{
+	  display: inline-block;
+	  float top
+	  padding-left: 10px;
+	  padding-top: 5px;
+	  h: 10%;
+	  }
+	  #buttons3{
+	  display: inline-block;
+	  float top
+	  padding-left: 10px;
+	  padding-top: 5px;
+	  h: 10%;
+	  }	  
+	</style>
+  </head>
+  <body>
+	<div id = "buttons">
+	<button onclick="removeLine()" accesskey="z">Delete Last</button>
+	<button onclick="deleteAllShape()" accesskey="c">Clear All</button>
+	<button onclick="deleteSelectedShape()" accesskey="c">Delete Selected</button>
+	<p>Line thickness: <input type="range" min="20" max="100" value="1" class="slider" id="thicknessRange"> </p>
+	<p>Value: <span id="thicknessRangeVal"></span></p>
+	
+	</div>
+	<div id = "buttons2">
+	<p>Colour opacity: <input type="range" min="10" max="100" value="40" class="slider" id="colourOpacity"> </p>
+	<p>Value: <span id="opacityRangeVal"></span></p>
+	</div>
+	
+	<div id = "buttons3">
+	<p> Geodesic: <input type="checkbox" id="geodesicBox" onclick="geodesicCheck()"> </p>
+	</div>
+	
+	<div id="map"></div>
+	
+	<script>
+	    var thicknessValue = 1;
+		var opacityValue = 0.4;
+		var polyOptions = {
+			fillColor: '#CA4A2F',
+			strokeWeight: thicknessValue,
+			fillOpacity: opacityValue,
+			editable: true,
+			draggable: true,
+			geodesic : false,
+			//zIndex: 1
+		  };
+		  
+		var overlays = [];
+		var drawingManager;
+		var selectedShape;
+		
+		function geodesicCheck (){
+			var checkBox = document.getElementById("geodesicBox");
+			if (checkBox.checked == true){
+				polyOptions.geodesic = true;
+			}
+			else {
+				polyOptions.geodesic = false;
+			}
+			console.log(polyOptions.geodesic);
+		}
+		//Update thickness 
+		var thicknessSlider = document.getElementById("thicknessRange");
+		var thicknessSliderOutput = document.getElementById("thicknessRangeVal");
+		thicknessSliderOutput.innerHTML = thicknessSlider.value/20;
+		
+		thicknessSlider.oninput = function() {
+			thicknessSliderOutput.innerHTML = this.value/20;
+			thicknessValue = this.value/20;
+			polyOptions.strokeWeight = thicknessValue;
+		}
+		
+		//Update opacity
+		var opacitySlider = document.getElementById("colourOpacity");
+		var opacitySliderOutput = document.getElementById("thicknessRangeVal");	
+		//opacitySliderOutput.innerHTML = opacitySlider.value/100;
+		
+		opacitySlider.oninput = function() {
+			opacityValue = this.value/100;
+			polyOptions.fillOpacity = opacityValue;
+			opacitySliderOutput = opacityValue;
+			opacityRangeVal.innerHTML = opacitySliderOutput;
+		}
+		
+		
+	  function initMap() {
+	  
+		var map = new google.maps.Map(document.getElementById('map'), {
+		  center: {lat: -34.397, lng: 150.644},
+		  zoom: 3
+		});
+		
+		//Update the strokeWeight value (NOT BEING USED NOW)
+		//document.getElementById("thicknessRange").addEventListener("mouseup", selectThickness);
+        //
+		//function selectThickness (shape) {
+		//	if  (shape.type !== 'marker') {
+		//
+		//		thicknessValue = thicknessRange.value/20;
+		//		console.log("Slider Val= ", thicknessRange.value, "Strokeweight Val= ", thicknessValue);
+		//	}
+		//}
+		//
+		//console.log(polyOptions.strokeWeight);
+		  
+
+	
+		drawingManager = new google.maps.drawing.DrawingManager({
+			drawingMode: google.maps.drawing.OverlayType.RECTANGLE,
+			drawingControl: true,
+			drawingControlOptions: {
+				position: google.maps.ControlPosition.TOP_CENTER,
+				drawingModes: ['marker', 'circle', 'polygon', 'polyline', 'rectangle']
+			},
+			markerOptions: { draggable: true},
+			circleOptions: polyOptions,
+			polylineOptions : polyOptions,
+			polygonOptions: polyOptions,
+			rectangleOptions: polyOptions,
+		  });
+	
+		drawingManager.setMap(map);
+		
+		
+		//overlays.push(event.overlay); // store reference to added overlay
+		google.maps.event.addListener(drawingManager, 'overlaycomplete', function (e) {
+			overlays.push(e.overlay); // store reference to added overlay
+			//console.log(overlays);
+			var newShape = e.overlay;
+					
+			newShape.type = e.type;
+					console.log("e", e);
+			if (e.type !== google.maps.drawing.OverlayType.MARKER) {
+				// Switch back to non-drawing mode after drawing a shape.
+				//ZdrawingManager.setDrawingMode(null);
+
+				// Add an event listener that selects the newly-drawn shape when the user
+				// mouses down on it.
+				google.maps.event.addListener(newShape, 'click', function(e) {
+					initialSelection(e,newShape)
+					});
+					
+				google.maps.event.addListener(newShape, 'mouseover', function(e) {
+					clearSelection();
+					setSelection(newShape, e)
+					});
+
+				google.maps.event.addListener(newShape, 'mouseout', function(e) {
+					clearSelection();
+					});					
+					
+					
+				setSelection(newShape);
+				console.log("Reached there");
+			}
+			else {
+				google.maps.event.addListener(newShape, 'click', function (e) {
+					setSelection(newShape);
+					console.log("Reached here");
+				});
+				setSelection(newShape);
+			}
+		});
+		
+		
+		function initialSelection(e,newShape) {
+			if (e.vertex !== undefined) {
+				if (newShape.type === google.maps.drawing.OverlayType.POLYGON) {
+					var path = newShape.getPaths().getAt(e.path);
+					path.removeAt(e.vertex);
+					if (path.length < 3) {
+						newShape.setMap(null);
+					}
+				}
+				if (newShape.type === google.maps.drawing.OverlayType.POLYLINE) {
+					var path = newShape.getPath();
+					path.removeAt(e.vertex);
+					if (path.length < 2) {
+						newShape.setMap(null);
+					}
+				}
+			}
+			
+			setSelection(newShape);
+		}
+				
+		function clearSelection () {
+			if (selectedShape) {
+				if (selectedShape.type !== 'marker') {
+					selectedShape.setEditable(false);
+				}
+					
+				selectedShape = null;
+			}
+		}
+
+		function setSelection (shape) {
+			if (shape.type !== 'marker') {
+				clearSelection();
+				shape.setEditable(true);
+				//selectColor(shape.get('fillColor') || shape.get('strokeColor'));
+				//console.log(shape.get('fillColor'), thicknessValue);
+				
+				//console.log(shape);
+				//if (shape.type == 'polyline'){
+				//console.log(shape);
+				//console.log(shape.De.bounds);
+				//}
+				//else if (shape.type ==  'rectangle'){
+				//console.log(shape);
+				//console.log(shape.bounds);
+				//}
+				//else if (shape.type == 'polygon'){
+				//console.log(shape);
+				//console.log(shape.geodesic);				
+				//}
+				
+			}
+			else{
+			console.log(shape);
+			}
+				
+			selectedShape = shape;
+		} 
+}
+		
+		
+	  
+function deleteSelectedShape () {
+	if (selectedShape) {
+		selectedShape.setMap(null);
+	}
+}
+			
+function removeLine() {
+	var lastOverlay = overlays.pop();
+	if (lastOverlay) lastOverlay.setMap(null);
+		console.log("DONE");
+	}
+		
+function deleteAllShape() {
+	for (var i=0; i < overlays.length; i++) {
+		overlays[i].setMap(null);
+	}
+	overlays = [];
+}
+
+	</script>
+	<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyBzunGwIF2OwsfrOkIC_8bhh0OPGZXo52Y&libraries=drawing&callback=initMap"
+		 async defer></script>
+  </body>
+</html>
Index: /gs3-extensions/map-editor/DrawingManager/checkpoints-singlefile/index backup v4.html
===================================================================
--- /gs3-extensions/map-editor/DrawingManager/checkpoints-singlefile/index backup v4.html	(revision 32709)
+++ /gs3-extensions/map-editor/DrawingManager/checkpoints-singlefile/index backup v4.html	(revision 32709)
@@ -0,0 +1,423 @@
+<!DOCTYPE html>
+<html>
+  <head>
+	<title>Drawing Tools</title>
+	<meta name="viewport" content="initial-scale=1.0, user-scalable=no">
+	<meta charset="utf-8">
+	<style>
+	  /* Always set the map height explicitly to define the size of the div
+	   * element that contains the map. */
+	  #map {
+		height: 83%;
+		float: bottom;
+	  }
+	  /* Optional: Makes the sample page fill the window. */
+	  html, body {
+		height: 100%;
+		width: 100%;
+		margin: 0;
+		padding: 0;
+	  }
+	  #buttons{
+	  display: inline-block;
+	  float: top;
+	  padding-left: 10px;
+	  padding-top: 5px;
+	  h: 10%;
+	  }
+	  #buttons2{
+	  display: inline-block;
+	  float top
+	  padding-left: 10px;
+	  padding-top: 5px;
+	  h: 10%;
+	  }
+	  #buttons3{
+	  display: inline-block;
+	  float top;
+	  padding-left: 10px;
+	  padding-top: 5px;
+	  h: 10%;
+	  }	  
+      #panel {
+      width: 200px;
+      font-family: Arial, sans-serif;
+      font-size: 13px;
+      float: right;
+      margin: 10px;
+	  }
+      #color-palette {
+      clear: both;
+      }
+	</style>
+  </head>
+  <body>
+	<div id = "buttons">
+	<button onclick="removeLine()" accesskey="z">Delete Last</button>
+	<button onclick="deleteAllShape()" accesskey="c">Clear All</button>
+	<button onclick="deleteSelectedShape()" accesskey="c">Delete Selected</button>
+	<p>Line thickness: <input type="range" min="20" max="100" value="1" class="slider" id="thicknessRange"> </p>
+	<p>Value: <span id="thicknessRangeVal"></span></p>
+	
+	</div>
+	<div id = "buttons2">
+	<p>Colour opacity: <input type="range" min="10" max="100" value="40" class="slider" id="colourOpacity"> </p>
+	<p>Value: <span id="opacityRangeVal"></span></p>
+	</div>
+	
+	<div id = "buttons3">
+	<p> Geodesic: <input type="checkbox" name="geodesicBox" id="geodesicBox" onclick="geodesicCheck()"> </p>
+		<div id="panel">
+        <div id="color-palette"></div>
+		<p>sfgsdg</p>
+    </div>
+	</div>
+
+	<div id="map"></div>
+	
+	<script>
+		var colors = ['#1E90FF', '#FF1493', '#32CD32', '#FF8C00', '#4B0082'];
+		var selectedColor;
+		var colorButtons = {};
+        var colorButtons = {};
+	    var thicknessValue = 1;
+		var opacityValue = 0.4;
+		var polyOptions = {
+			fillColor: '#CA4A2F',
+			strokeWeight: thicknessValue,
+			fillOpacity: opacityValue,
+			editable: true,
+			draggable: true,
+			geodesic : false,
+			//zIndex: 1
+		  };
+		  
+		var overlays = [];
+		var drawingManager;
+		var selectedShape;
+		
+		function geodesicCheck (){
+			var checkBox = document.getElementById("geodesicBox");
+			if (checkBox.checked == true){
+				polyOptions.geodesic = true;
+				setGeodesic(polyOptions.geodesic);
+			}
+			else {
+				polyOptions.geodesic = false;
+				setGeodesic(polyOptions.geodesic);
+			}
+			
+			console.log(geodesic);
+		};
+		//Update thickness 
+		var thicknessSlider = document.getElementById("thicknessRange");
+		var thicknessSliderOutput = document.getElementById("thicknessRangeVal");
+		thicknessSliderOutput.innerHTML = thicknessSlider.value/20;
+		
+		thicknessSlider.oninput = function() {
+			thicknessSliderOutput.innerHTML = this.value/20;
+			thicknessValue = this.value/20;
+			polyOptions.strokeWeight = thicknessValue;
+			setSelectedThickness(thicknessValue);
+		}
+		
+		//Update opacity
+		var opacitySlider = document.getElementById("colourOpacity");
+		var opacitySliderOutput = document.getElementById("opacityRangeVal");	
+		opacitySliderOutput.innerHTML =  "% " + Math.round(opacitySlider.value);
+		
+		opacitySlider.oninput = function() {
+			opacityValue = this.value/100;
+			polyOptions.fillOpacity = opacityValue;
+			opacitySliderOutput = opacityValue;
+			opacityRangeVal.innerHTML = "% " + Math.round( opacitySliderOutput * 100);
+			setSelectedOpacity(opacityValue);
+		}
+
+		//Update the geodesic state
+		function geodesicCheck (){
+			var checkBox = document.getElementById("geodesicBox");
+			if (checkBox.checked == true){
+				polyOptions.geodesic = true;
+			}
+			else {
+				polyOptions.geodesic = false;
+			}
+		}		
+		////////////////////////////////////////////////////////////////////////////////////////
+        function makeColorButton (color) {
+            var button = document.createElement('span');
+            button.className = 'color-button';
+            button.style.backgroundColor = color;
+            google.maps.event.addDomListener(button, 'click', function () {
+				selectColor(color);
+				setSelectedShapeColor(color);
+            });
+            return button;
+        }
+        function buildColorPalette () {
+			var colorPalette = document.getElementById('color-palette');
+            for (var i = 0; i < colors.length; ++i) {
+                var currColor = colors[i];
+                var colorButton = makeColorButton(currColor);
+                colorPalette.appendChild(colorButton);
+                colorButtons[currColor] = colorButton;
+            }
+            selectColor(colors[0]);
+        };		
+		function selectColor (color) {
+                selectedColor = color;
+                for (var i = 0; i < colors.length; ++i) {
+                    var currColor = colors[i];
+                    colorButtons[currColor].style.border = currColor == color ? '2px solid #789' : '2px solid #fff';
+                }
+
+                // Retrieves the current options from the drawing manager and replaces the
+                // stroke or fill color as appropriate.
+                var polylineOptions = drawingManager.get('polylineOptions');
+                polylineOptions.strokeColor = color;
+                drawingManager.set('polylineOptions', polylineOptions);
+
+                var rectangleOptions = drawingManager.get('rectangleOptions');
+                rectangleOptions.fillColor = color;
+                drawingManager.set('rectangleOptions', rectangleOptions);
+
+                var circleOptions = drawingManager.get('circleOptions');
+                circleOptions.fillColor = color;
+                drawingManager.set('circleOptions', circleOptions);
+
+                var polygonOptions = drawingManager.get('polygonOptions');
+                polygonOptions.fillColor = color;
+                drawingManager.set('polygonOptions', polygonOptions);
+            }
+		
+		
+		
+		
+		function selectColor (color) {
+                selectedColor = color;
+                for (var i = 0; i < colors.length; ++i) {
+                    var currColor = colors[i];
+                    colorButtons[currColor].style.border = currColor == color ? '2px solid #789' : '2px solid #fff';
+                }
+
+                // Retrieves the current options from the drawing manager and replaces the
+                // stroke or fill color as appropriate.
+                var polylineOptions = drawingManager.get('polylineOptions');
+                polylineOptions.strokeColor = color;
+                drawingManager.set('polylineOptions', polylineOptions);
+
+                var rectangleOptions = drawingManager.get('rectangleOptions');
+                rectangleOptions.fillColor = color;
+                drawingManager.set('rectangleOptions', rectangleOptions);
+
+                var circleOptions = drawingManager.get('circleOptions');
+                circleOptions.fillColor = color;
+                drawingManager.set('circleOptions', circleOptions);
+
+                var polygonOptions = drawingManager.get('polygonOptions');
+                polygonOptions.fillColor = color;
+                drawingManager.set('polygonOptions', polygonOptions);
+            }
+	  function initMap() {
+	  
+		var map = new google.maps.Map(document.getElementById('map'), {
+		  center: {lat: -34.397, lng: 150.644},
+		  zoom: 3
+		});
+		
+		//Update the strokeWeight value (NOT BEING USED NOW)
+		//document.getElementById("thicknessRange").addEventListener("mouseup", selectThickness);
+        //
+		//function selectThickness (shape) {
+		//	if  (shape.type !== 'marker') {
+		//
+		//		thicknessValue = thicknessRange.value/20;
+		//		console.log("Slider Val= ", thicknessRange.value, "Strokeweight Val= ", thicknessValue);
+		//	}
+		//}
+		//
+		//console.log(polyOptions.strokeWeight);
+		  
+
+	
+		drawingManager = new google.maps.drawing.DrawingManager({
+			drawingMode: google.maps.drawing.OverlayType.RECTANGLE,
+			drawingControl: true,
+			drawingControlOptions: {
+				position: google.maps.ControlPosition.TOP_CENTER,
+				drawingModes: ['marker', 'circle', 'polygon', 'polyline', 'rectangle']
+			},
+			markerOptions: { draggable: true},
+			circleOptions: polyOptions,
+			polylineOptions : polyOptions,
+			polygonOptions: polyOptions,
+			rectangleOptions: polyOptions,
+		  });
+	
+		drawingManager.setMap(map);
+		
+		
+		//overlays.push(event.overlay); // store reference to added overlay
+		google.maps.event.addListener(drawingManager, 'overlaycomplete', function (e) {
+			overlays.push(e.overlay); // store reference to added overlay
+			//console.log(overlays);
+			var newShape = e.overlay;	
+			newShape.type = e.type;
+
+			if (e.type !== google.maps.drawing.OverlayType.MARKER) {
+				// Switch back to non-drawing mode after drawing a shape.
+				//drawingManager.setDrawingMode(null);
+				
+				
+
+				// Add an event listener that selects the newly-drawn shape when the user
+				// mouses down on it.
+				google.maps.event.addListener(newShape, 'click', function(e) {
+					vertexAndPolyDel(e,newShape);
+					});
+				
+				//Add an event listener to select a shape if the mouse hovers over it
+				google.maps.event.addListener(newShape, 'mousedown', function(e) {
+					if (selectedShape != newShape ){
+						setSelection(newShape);
+					}});
+					
+						
+					
+					
+				setSelection(newShape);
+			}
+			else {
+				google.maps.event.addListener(newShape, 'click', function (e) {
+					setSelection(newShape);
+				});
+				setSelection(newShape);
+			}
+		});
+		
+		
+		function vertexAndPolyDel(e,newShape) {
+			if (e.vertex !== undefined) {
+				if (newShape.type === google.maps.drawing.OverlayType.POLYGON) {
+					var path = newShape.getPaths().getAt(e.path);
+					path.removeAt(e.vertex);
+					if (path.length < 3) {
+						newShape.setMap(null);
+					}
+				}
+				if (newShape.type === google.maps.drawing.OverlayType.POLYLINE) {
+					var path = newShape.getPath();
+						path.removeAt(e.vertex);
+											
+					if (path.length < 2) {
+						newShape.setMap(null);
+					}
+				}
+			}
+			
+			setSelection(newShape);
+		}
+				
+		function clearSelection () {
+			if (selectedShape) {
+				if (selectedShape.type !== 'marker') {
+					selectedShape.setEditable(false);
+				}
+					
+					selectedShape = null;
+			}
+		}
+
+		function setSelection (shape) {
+			if (shape.type !== 'marker') {
+				clearSelection();
+				shape.setEditable(true);
+				
+				//Send the values to be updated
+				var thi = shape.strokeWeight;
+				var opa = shape.fillOpacity;
+				var geod = shape.geodesic;
+				updateMenuValues(thi, opa, geod);
+				
+			}
+			else if (shape.type == 'marker') {
+				clearSelection();
+			}
+				
+			selectedShape = shape;
+		} 
+		
+
+		
+}
+		//Set selected thickness
+		function setSelectedThickness(sWeight) {
+			if (selectedShape){
+			selectedShape.set('strokeWeight', sWeight)
+			}
+		}
+		
+		//Set selected opacity
+		function setSelectedOpacity(fOpacity) {
+			if (selectedShape) {
+				selectedShape.set('fillOpacity', fOpacity)
+			}
+		}
+		
+		//Set the selected geodesic state
+		var gCheckbox = document.querySelector("input[name=geodesicBox]");
+		gCheckbox.addEventListener( 'change', function() {
+		if(this.checked){
+			if (selectedShape) {
+				selectedShape.set('geodesic', true);
+			}
+		}	else{
+				selectedShape.set('geodesic', false);
+			}
+		});
+		
+		function updateMenuValues(thi, opa, geod){
+		
+		//Update thickness slider and value on the settings menu
+		var thicknessSliderOutput = document.getElementById("thicknessRangeVal");
+		thicknessSliderOutput.innerHTML = thi;
+		document.getElementById("thicknessRange").value = thi*20;
+		
+		//Update the opacity slider and value on the settings menu
+		var opacitySliderOutput = document.getElementById("opacityRangeVal");
+		opacitySliderOutput.innerHTML =  "% " + opa*100;
+		document.getElementById("colourOpacity").value =  opa*100;
+
+		
+		//Update geodesic state on the settings menu		
+		if(geod){
+			document.getElementById("geodesicBox").checked = true;
+			}else{
+			document.getElementById("geodesicBox").checked = false;
+			}
+		}
+	  
+function deleteSelectedShape () {
+	if (selectedShape) {
+		selectedShape.setMap(null);
+	}
+}
+			
+function removeLine() {
+	var lastOverlay = overlays.pop();
+	if (lastOverlay) lastOverlay.setMap(null);
+	}
+		
+function deleteAllShape() {
+	for (var i=0; i < overlays.length; i++) {
+		overlays[i].setMap(null);
+	}
+	overlays = [];
+}
+
+	</script>
+	<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyBzunGwIF2OwsfrOkIC_8bhh0OPGZXo52Y&libraries=drawing&callback=initMap"
+		 async defer></script>
+  </body>
+</html>
Index: /gs3-extensions/map-editor/DrawingManager/checkpoints-singlefile/index backup v5.html
===================================================================
--- /gs3-extensions/map-editor/DrawingManager/checkpoints-singlefile/index backup v5.html	(revision 32709)
+++ /gs3-extensions/map-editor/DrawingManager/checkpoints-singlefile/index backup v5.html	(revision 32709)
@@ -0,0 +1,481 @@
+<!DOCTYPE html>
+<html>
+  <head>
+	<title>Drawing Tools</title>
+	<meta name="viewport" content="initial-scale=1.0, user-scalable=no">
+	<meta charset="utf-8">
+	<style>
+	  /* Always set the map height explicitly to define the size of the div
+	   * element that contains the map. */
+	  #map {
+		height: 83%;
+		float: bottom;
+	  }
+	  /* Optional: Makes the sample page fill the window. */
+	  html, body {
+		height: 100%;
+		width: 100%;
+		margin: 0;
+		padding: 0;
+	  }
+	  
+	  #buttons{
+	  display: inline-block;
+	  float: top;
+	  padding-left: 10px;
+	  padding-top: 5px;
+	  h: 10%;
+	  }
+	  
+	  #buttons2{
+	  display: inline-block;
+	  float: top
+	  padding-left: 10px;
+	  padding-top: 5px;
+	  h: 10%;
+	  }
+	  
+	  #buttons3{
+	  display: inline-block;
+	  float: top;
+	  padding-left: 10px;
+	  padding-top: 5px;
+	  h: 10%;
+	  }	  
+	  
+      #panel {
+	  display: inline-block;
+      float right;
+      padding-left: 30px;
+	  }
+	  
+      #color-palette {
+      clear: both;
+      }
+	  
+      .color-button {
+      width: 14px;
+      height: 14px;
+      font-size: 0;
+      margin: 2px;
+      float: left;
+      cursor: pointer;
+      }
+
+
+	</style>
+  </head>
+  <body>
+	<div id = "buttons">
+	<button onclick="removeLine()" accesskey="z">Delete Last</button>
+	<button onclick="deleteAllShape()" accesskey="c">Clear All</button>
+	<button onclick="deleteSelectedShape()" accesskey="c">Delete Selected</button>
+	<p>Line thickness: <input type="range" min="20" max="100" value="1" class="slider" id="thicknessRange"> </p>
+	<p>Value: <span id="thicknessRangeVal"></span></p>
+	
+	</div>
+	<div id = "buttons2">
+	<p>Colour opacity: <input type="range" min="10" max="100" value="40" class="slider" id="colourOpacity"> </p>
+	<p>Value: <span id="opacityRangeVal"></span></p>
+	</div>
+	
+	<div id = "buttons3">
+	<p> Geodesic: <input type="checkbox" name="geodesicBox" id="geodesicBox" onclick="geodesicCheck()"> </p>
+
+	</div>
+
+	<div id="panel">
+        <div id="color-palette"></div>
+		<!-- <p> Black stroke: <input type="checkbox" name="blackStroke" id="blackStroke" onclick="blackStrokeCheck()"> </p> -->
+
+	</div>
+	<div id="map"></div>
+	
+	<script>
+		var colors = ['#1E90FF', '#FF1493', '#4B0082', '#32CD32', '#FF8C00', '#000000'];
+		var selectedColor;
+		var colorButtons = {};
+	    var thicknessValue = 1;
+		var opacityValue = 0.4;
+		var polyOptions = {
+			fillColor: '#CA4A2F',
+			strokeWeight: thicknessValue,
+			fillOpacity: opacityValue,
+			editable: true,
+			draggable: true,
+			geodesic : false,
+			//zIndex: 1
+		  };
+		  
+		var overlays = [];
+		var drawingManager;
+		var selectedShape;
+		
+		function geodesicCheck (){
+			var gCheckBox = document.getElementById("geodesicBox");
+			if (gCheckBox.checked == true){
+				polyOptions.geodesic = true;
+				//setGeodesic(polyOptions.geodesic);
+			}
+			else {
+				polyOptions.geodesic = false;
+				//setGeodesic(polyOptions.geodesic);
+			}
+		};
+		
+		//function blackStrokeCheck(){
+		//var sCheckBox = document.getElementById("blackStroke");
+		//	if (sCheckBox.checked == true){
+		//		polyOptions.strokeColor = '#000000';
+		//	}
+		//	else {
+		//		polyOptions.strokeColor = selectedColor;
+		//	}
+		//};
+		
+		//Update thickness 
+		var thicknessSlider = document.getElementById("thicknessRange");
+		var thicknessSliderOutput = document.getElementById("thicknessRangeVal");
+		thicknessSliderOutput.innerHTML = thicknessSlider.value/20;
+		
+		thicknessSlider.oninput = function() {
+			thicknessSliderOutput.innerHTML = this.value/20;
+			thicknessValue = this.value/20;
+			polyOptions.strokeWeight = thicknessValue;
+			setSelectedThickness(thicknessValue);
+		}
+		
+		//Update opacity
+		var opacitySlider = document.getElementById("colourOpacity");
+		var opacitySliderOutput = document.getElementById("opacityRangeVal");	
+		opacitySliderOutput.innerHTML =  "% " + Math.round(opacitySlider.value);
+		
+		opacitySlider.oninput = function() {
+			opacityValue = this.value/100;
+			polyOptions.fillOpacity = opacityValue;
+			opacitySliderOutput = opacityValue;
+			opacityRangeVal.innerHTML = "% " + Math.round( opacitySliderOutput * 100);
+			setSelectedOpacity(opacityValue);
+		}
+
+		//Update the geodesic state
+		function geodesicCheck (){
+			var checkBox = document.getElementById("geodesicBox");
+			if (checkBox.checked == true){
+				polyOptions.geodesic = true;
+			}
+			else {
+				polyOptions.geodesic = false;
+			}
+		}		
+		////////////////////////////////////////////////////////////////////////////////////////
+        function makeColorButton (color) {
+            var button = document.createElement('span');
+            button.className = 'color-button';
+            button.style.backgroundColor = color;
+            google.maps.event.addDomListener(button, 'click', function () {
+				selectColor(color);
+				setSelectedShapeColor(color);
+            });
+            return button;
+        }
+        function buildColorPalette () {
+			var colorPalette = document.getElementById('color-palette');
+            for (var i = 0; i < colors.length; ++i) {
+                var currColor = colors[i];
+                var colorButton = makeColorButton(currColor);
+                colorPalette.appendChild(colorButton);
+                colorButtons[currColor] = colorButton;
+            }
+            selectColor(colors[0]);
+        };		
+		function selectColor (color) {
+                selectedColor = color;
+                for (var i = 0; i < colors.length; ++i) {
+                    var currColor = colors[i];
+                    colorButtons[currColor].style.border = currColor == color ? '2px solid #789' : '2px solid #fff';
+                }
+
+                // Retrieves the current options from the drawing manager and replaces the
+                // stroke or fill color as appropriate.
+                var polylineOptions = drawingManager.get('polylineOptions');
+                polylineOptions.strokeColor = color;
+                drawingManager.set('polylineOptions', polylineOptions);
+
+                var rectangleOptions = drawingManager.get('rectangleOptions');
+                rectangleOptions.fillColor = color;
+                drawingManager.set('rectangleOptions', rectangleOptions);
+
+                var circleOptions = drawingManager.get('circleOptions');
+                circleOptions.fillColor = color;
+                drawingManager.set('circleOptions', circleOptions);
+
+                var polygonOptions = drawingManager.get('polygonOptions');
+                polygonOptions.fillColor = color;
+                drawingManager.set('polygonOptions', polygonOptions);
+            }
+		
+		
+		
+		
+		function selectColor (color) {
+                selectedColor = color;
+                for (var i = 0; i < colors.length; ++i) {
+                    var currColor = colors[i];
+                    colorButtons[currColor].style.border = currColor == color ? '2px solid #789' : '2px solid #fff';
+                }
+
+                // Retrieves the current options from the drawing manager and replaces the
+                // stroke or fill color as appropriate.
+                var polylineOptions = drawingManager.get('polylineOptions');
+                polylineOptions.strokeColor = color;
+                drawingManager.set('polylineOptions', polylineOptions);
+
+                var rectangleOptions = drawingManager.get('rectangleOptions');
+                rectangleOptions.fillColor = color;
+                drawingManager.set('rectangleOptions', rectangleOptions);
+
+                var circleOptions = drawingManager.get('circleOptions');
+                circleOptions.fillColor = color;
+                drawingManager.set('circleOptions', circleOptions);
+
+                var polygonOptions = drawingManager.get('polygonOptions');
+                polygonOptions.fillColor = color;
+                drawingManager.set('polygonOptions', polygonOptions);
+            }
+	  function initMap() {
+		
+		var map = new google.maps.Map(document.getElementById('map'), {
+		  center: {lat: -34.397, lng: 150.644},
+		  zoom: 3
+		});
+		
+	
+		drawingManager = new google.maps.drawing.DrawingManager({
+			drawingMode: google.maps.drawing.OverlayType.RECTANGLE,
+			drawingControl: true,
+			drawingControlOptions: {
+				position: google.maps.ControlPosition.TOP_CENTER,
+				drawingModes: ['marker', 'circle', 'polygon', 'polyline', 'rectangle']
+			},
+			markerOptions: { draggable: true},
+			circleOptions: polyOptions,
+			polylineOptions : polyOptions,
+			polygonOptions: polyOptions,
+			rectangleOptions: polyOptions,
+		  });
+	
+		drawingManager.setMap(map);
+		
+		
+		//overlays.push(event.overlay); // store reference to added overlay
+		google.maps.event.addListener(drawingManager, 'overlaycomplete', function (e) {
+			overlays.push(e.overlay); // store reference to added overlay
+			//console.log(overlays);
+			var newShape = e.overlay;	
+			newShape.type = e.type;
+
+			if (e.type !== google.maps.drawing.OverlayType.MARKER) {
+				// Switch back to non-drawing mode after drawing a shape.
+				//drawingManager.setDrawingMode(null);
+				
+				
+
+				// Add an event listener that selects the newly-drawn shape when the user
+				// mouses down on it.
+				google.maps.event.addListener(newShape, 'click', function(e) {
+					vertexAndPolyDel(e,newShape);
+					});
+				
+				//Add an event listener to select a shape if the mouse hovers over it
+				google.maps.event.addListener(newShape, 'mousedown', function(e) {
+					if (selectedShape != newShape ){
+						setSelection(newShape);
+					}});
+					
+						
+					
+					
+				setSelection(newShape);
+			}
+			else {
+				google.maps.event.addListener(newShape, 'click', function (e) {
+					setSelection(newShape);
+				});
+				setSelection(newShape);
+			}
+		});
+		
+		
+		function vertexAndPolyDel(e,newShape) {
+			if (e.vertex !== undefined) {
+				if (newShape.type === google.maps.drawing.OverlayType.POLYGON) {
+					var path = newShape.getPaths().getAt(e.path);
+					path.removeAt(e.vertex);
+					if (path.length < 3) {
+						newShape.setMap(null);
+					}
+				}
+				if (newShape.type === google.maps.drawing.OverlayType.POLYLINE) {
+					var path = newShape.getPath();
+						path.removeAt(e.vertex);
+											
+					if (path.length < 2) {
+						newShape.setMap(null);
+					}
+				}
+			}
+			
+			setSelection(newShape);
+		}
+				
+		function clearSelection () {
+			if (selectedShape) {
+				if (selectedShape.type !== 'marker') {
+					selectedShape.setEditable(false);
+				}
+					
+					selectedShape = null;
+			}
+		}
+
+		function setSelection (shape) {
+			if (shape.type !== 'marker') {
+				clearSelection();
+				shape.setEditable(true);
+				
+				//Send the values to be updated
+				var thi = shape.strokeWeight;
+				var opa = shape.fillOpacity;
+				var geod = shape.geodesic;
+				var fCol = shape.fillColor;
+				var sCol = shape.strokeColor;
+				
+				updateMenuValues(thi, opa, geod, fCol, sCol);
+				//if (shape.type !== 'polygon'){
+				//	document.getElementById("geodesicBox").disabled = true;
+				//} else if(shape.type !== 'polyline'){
+				//	document.getElementById("geodesicBox").disabled = true;
+				//}
+				//
+				//else {
+				//	document.getElementById("geodesicBox").disabled = false;
+				//	console.log("hey")
+				//}
+			}
+			else if (shape.type == 'marker') {
+				clearSelection();
+			}
+				
+			selectedShape = shape;
+		} 
+		
+
+		buildColorPalette();
+}
+		//Set selected thickness
+		function setSelectedThickness(sWeight) {
+			if (selectedShape){
+			selectedShape.set('strokeWeight', sWeight)
+			}
+		}
+		
+		//Set selected opacity
+		function setSelectedOpacity(fOpacity) {
+			if (selectedShape) {
+				selectedShape.set('fillOpacity', fOpacity)
+			}
+		}
+		
+		//Set the selected geodesic state
+		var gCheckbox = document.querySelector("input[name=geodesicBox]");
+		gCheckbox.addEventListener( 'change', function() {
+		if(this.checked){
+			if (selectedShape) {
+				selectedShape.set('geodesic', true);
+			}
+		}	else{
+				selectedShape.set('geodesic', false);
+			}
+		});
+		
+		//set selected fill colour
+        function setSelectedShapeColor (color) {
+            if (selectedShape) {
+                if (selectedShape.type == google.maps.drawing.OverlayType.POLYLINE) {
+                    selectedShape.set('strokeColor', color);
+                } else {
+                    selectedShape.set('fillColor', color);
+					
+					//var sCheckbox = document.querySelector("input[name=blackStroke]");
+					//if (sCheckbox.check){
+                    //
+					//	console.log("adaedf");
+					//	selectedShape.set('strokeColor', '#00000');
+					//} else {
+						selectedShape.set('strokeColor', color);
+					//	console.log("adaedf2");
+					//}
+                }
+             }
+        }
+		//Set stroke colour for an already created shape to black
+		//var scCheckbox = document.querySelector("input[name=blackStroke]");
+		//scCheckbox.addEventListener( 'change', function() {
+		//if(this.checked){
+		//	if (selectedShape) {
+		//		selectedShape.set('strokeColor', '#00000');
+		//		console.log(selectedShape.strokeColor);
+		//	}
+		//}	else{
+		//	if (selectedShape) {
+		//		selectedShape.set('strokeColor', selectedColor);
+		//		console.log(selectedShape.strokeColor);
+		//	}
+		//	}
+		//});
+		
+		function updateMenuValues(thi, opa, geod, fCol, sCol){
+		
+		//Update thickness slider and value on the settings menu
+		var thicknessSliderOutput = document.getElementById("thicknessRangeVal");
+		thicknessSliderOutput.innerHTML = thi;
+		document.getElementById("thicknessRange").value = thi*20;
+		
+		//Update the opacity slider and value on the settings menu
+		var opacitySliderOutput = document.getElementById("opacityRangeVal");
+		opacitySliderOutput.innerHTML =  "% " + opa*100;
+		document.getElementById("colourOpacity").value =  opa*100;
+
+		
+		//Update geodesic state on the settings menu		
+		if(geod){
+			document.getElementById("geodesicBox").checked = true;
+			}else{
+			document.getElementById("geodesicBox").checked = false;
+			}
+		}
+	  
+function deleteSelectedShape () {
+	if (selectedShape) {
+		selectedShape.setMap(null);
+	}
+}
+			
+function removeLine() {
+	var lastOverlay = overlays.pop();
+	if (lastOverlay) lastOverlay.setMap(null);
+	}
+		
+function deleteAllShape() {
+	for (var i=0; i < overlays.length; i++) {
+		overlays[i].setMap(null);
+	}
+	overlays = [];
+}
+
+	</script>
+	<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyBzunGwIF2OwsfrOkIC_8bhh0OPGZXo52Y&libraries=drawing&callback=initMap"
+		 async defer></script>
+  </body>
+</html>
Index: /gs3-extensions/map-editor/DrawingManager/checkpoints-singlefile/index backup v6.html
===================================================================
--- /gs3-extensions/map-editor/DrawingManager/checkpoints-singlefile/index backup v6.html	(revision 32709)
+++ /gs3-extensions/map-editor/DrawingManager/checkpoints-singlefile/index backup v6.html	(revision 32709)
@@ -0,0 +1,502 @@
+<!DOCTYPE html>
+<html>
+  <head>
+	<title>Drawing Tools</title>
+	<meta name="viewport" content="initial-scale=1.0, user-scalable=no">
+	<meta charset="utf-8">
+	<style>
+	  /* Always set the map height explicitly to define the size of the div
+	   * element that contains the map. */
+	  #map {
+		height: 83%;
+		float: bottom;
+	  }
+	  /* Optional: Makes the sample page fill the window. */
+	  html, body {
+		height: 100%;
+		width: 100%;
+		margin: 0;
+		padding: 0;
+	  }
+	  
+	  #buttons{
+	  display: inline-block;
+	  float: top;
+	  padding-left: 10px;
+	  padding-top: 5px;
+	  h: 10%;
+	  }
+	  
+	  #buttons2{
+	  display: inline-block;
+	  float: top
+	  padding-left: 10px;
+	  padding-top: 5px;
+	  h: 10%;
+	  }
+	  
+	  #buttons3{
+	  display: inline-block;
+	  float: top;
+	  padding-left: 10px;
+	  padding-top: 5px;
+	  h: 10%;
+	  }	  
+	  
+      #panel {
+	  display: inline-block;
+      float right;
+      padding-left: 30px;
+	  }
+	  
+      #color-palette {
+      clear: both;
+      }
+	  
+      .color-button {
+      width: 14px;
+      height: 14px;
+      font-size: 0;
+      margin: 2px;
+      float: left;
+      cursor: pointer;
+      }
+
+
+	</style>
+  </head>
+  <body>
+	<div id = "buttons">
+	<button onclick="removeLine()" accesskey="z">Delete Last</button>
+	<button onclick="deleteAllShape()" accesskey="c">Clear All</button>
+	<button onclick="deleteSelectedShape()" accesskey="c">Delete Selected</button>
+	<p>Line thickness: <input type="range" min="20" max="100" value="1" class="slider" id="thicknessRange"> </p>
+	<p>Value: <span id="thicknessRangeVal"></span></p>
+	
+	</div>
+	<div id = "buttons2">
+	<p>Colour opacity: <input type="range" min="10" max="100" value="40" class="slider" id="colourOpacity"> </p>
+	<p>Value: <span id="opacityRangeVal"></span></p>
+	</div>
+	
+	<div id = "buttons3">
+	<p> Geodesic: <input type="checkbox" name="geodesicBox" id="geodesicBox" onclick="geodesicCheck()"> </p>
+
+	</div>
+
+	<div id="panel">
+        <div id="color-palette"></div>
+		<p> Black stroke: <input type="checkbox" name="blackStroke" id="blackStroke" onclick="blackStrokeCheck()"> </p>
+
+	</div>
+	<div id="map"></div>
+	
+	<script>
+		var colors = ['#1E90FF', '#FF1493', '#4B0082', '#32CD32', '#FF8C00', '#000000'];
+		var selectedColor;
+		var colorButtons = {};
+	    var thicknessValue = 1;
+		var opacityValue = 0.4;
+		var polyOptions = {
+			fillColor: '#CA4A2F',
+			strokeWeight: thicknessValue,
+			fillOpacity: opacityValue,
+			editable: true,
+			draggable: true,
+			geodesic : false,
+			//zIndex: 1
+		  };
+		  
+		var overlays = [];
+		var drawingManager;
+		var selectedShape;
+		
+		function geodesicCheck (){
+			var gCheckBox = document.getElementById("geodesicBox");
+			if (gCheckBox.checked == true){
+				polyOptions.geodesic = true;
+				//setGeodesic(polyOptions.geodesic);
+			}
+			else {
+				polyOptions.geodesic = false;
+				//setGeodesic(polyOptions.geodesic);
+			}
+		}
+		
+		function blackStrokeCheck(){
+			var sCheckBox = document.getElementById("blackStroke");
+			// Update the line color that polyOptions uses
+			if (sCheckBox.checked){
+				polyOptions.strokeColor = '#000000';
+			}
+			else {
+				polyOptions.strokeColor = selectedColor;
+			}
+			
+			// Now see if any item is currently selected,
+			// in which case, change its line color also
+			
+			if (selectedShape) {	
+				if (sCheckBox.checked){
+					selectedShape.set('strokeColor', '#00000');
+					console.log("Updating selected strokeColor to black");
+				}
+				else {
+					selectedShape.set('strokeColor', selectedColor);
+					console.log("Updating selected strokeColor to: " + selectedShape.strokeColor);
+				}
+			}
+		}
+		
+		//Update thickness 
+		var thicknessSlider = document.getElementById("thicknessRange");
+		var thicknessSliderOutput = document.getElementById("thicknessRangeVal");
+		thicknessSliderOutput.innerHTML = thicknessSlider.value/20;
+		
+		thicknessSlider.oninput = function() {
+			thicknessSliderOutput.innerHTML = this.value/20;
+			thicknessValue = this.value/20;
+			polyOptions.strokeWeight = thicknessValue;
+			setSelectedThickness(thicknessValue);
+		}
+		
+		//Update opacity
+		var opacitySlider = document.getElementById("colourOpacity");
+		var opacitySliderOutput = document.getElementById("opacityRangeVal");	
+		opacitySliderOutput.innerHTML =  "% " + Math.round(opacitySlider.value);
+		
+		opacitySlider.oninput = function() {
+			opacityValue = this.value/100;
+			polyOptions.fillOpacity = opacityValue;
+			opacitySliderOutput = opacityValue;
+			opacityRangeVal.innerHTML = "% " + Math.round( opacitySliderOutput * 100);
+			setSelectedOpacity(opacityValue);
+		}
+
+		//Update the geodesic state
+		function geodesicCheck (){
+			var checkBox = document.getElementById("geodesicBox");
+			if (checkBox.checked == true){
+				polyOptions.geodesic = true;
+			}
+			else {
+				polyOptions.geodesic = false;
+			}
+		}		
+		////////////////////////////////////////////////////////////////////////////////////////
+        function makeColorButton (color) {
+            var button = document.createElement('span');
+            button.className = 'color-button';
+            button.style.backgroundColor = color;
+            google.maps.event.addDomListener(button, 'click', function () {
+				selectColor(color);
+				setSelectedShapeColor(color);
+            });
+            return button;
+        }
+        function buildColorPalette () {
+			var colorPalette = document.getElementById('color-palette');
+            for (var i = 0; i < colors.length; ++i) {
+                var currColor = colors[i];
+                var colorButton = makeColorButton(currColor);
+                colorPalette.appendChild(colorButton);
+                colorButtons[currColor] = colorButton;
+            }
+            selectColor(colors[0]);
+        };		
+		function selectColor (color) {
+				console.log("*** selectColor: color = " + color);
+                selectedColor = color;
+                for (var i = 0; i < colors.length; ++i) {
+                    var currColor = colors[i];
+                    colorButtons[currColor].style.border = currColor == color ? '2px solid #789' : '2px solid #fff';
+                }
+
+                // Retrieves the current options from the drawing manager and replaces the
+                // stroke or fill color as appropriate.
+                var polylineOptions = drawingManager.get('polylineOptions');
+                polylineOptions.strokeColor = color;
+                drawingManager.set('polylineOptions', polylineOptions);
+
+                var rectangleOptions = drawingManager.get('rectangleOptions');
+                rectangleOptions.fillColor = color;
+                drawingManager.set('rectangleOptions', rectangleOptions);
+
+                var circleOptions = drawingManager.get('circleOptions');
+                circleOptions.fillColor = color;
+                drawingManager.set('circleOptions', circleOptions);
+
+                var polygonOptions = drawingManager.get('polygonOptions');
+                polygonOptions.fillColor = color;
+                drawingManager.set('polygonOptions', polygonOptions);
+            }
+		
+		
+		
+		/*
+		function selectColor (color) {
+				console.log("*** selectColor 2!!!: color = " + color);
+                selectedColor = color;
+                for (var i = 0; i < colors.length; ++i) {
+                    var currColor = colors[i];
+                    colorButtons[currColor].style.border = currColor == color ? '2px solid #789' : '2px solid #fff';
+                }
+
+                // Retrieves the current options from the drawing manager and replaces the
+                // stroke or fill color as appropriate.
+                var polylineOptions = drawingManager.get('polylineOptions');
+                polylineOptions.strokeColor = color;
+                drawingManager.set('polylineOptions', polylineOptions);
+
+                var rectangleOptions = drawingManager.get('rectangleOptions');
+                rectangleOptions.fillColor = color;
+                drawingManager.set('rectangleOptions', rectangleOptions);
+
+                var circleOptions = drawingManager.get('circleOptions');
+                circleOptions.fillColor = color;
+                drawingManager.set('circleOptions', circleOptions);
+
+                var polygonOptions = drawingManager.get('polygonOptions');
+                polygonOptions.fillColor = color;
+                drawingManager.set('polygonOptions', polygonOptions);
+            }
+			*/
+			
+	  function initMap() {
+		
+		var map = new google.maps.Map(document.getElementById('map'), {
+		  center: {lat: -34.397, lng: 150.644},
+		  zoom: 3
+		});
+		
+	
+		drawingManager = new google.maps.drawing.DrawingManager({
+			drawingMode: google.maps.drawing.OverlayType.RECTANGLE,
+			drawingControl: true,
+			drawingControlOptions: {
+				position: google.maps.ControlPosition.TOP_CENTER,
+				drawingModes: ['marker', 'circle', 'polygon', 'polyline', 'rectangle']
+			},
+			markerOptions: { draggable: true},
+			circleOptions: polyOptions,
+			polylineOptions : polyOptions,
+			polygonOptions: polyOptions,
+			rectangleOptions: polyOptions,
+		  });
+	
+		drawingManager.setMap(map);
+		
+		
+		//overlays.push(event.overlay); // store reference to added overlay
+		google.maps.event.addListener(drawingManager, 'overlaycomplete', function (e) {
+			overlays.push(e.overlay); // store reference to added overlay
+			//console.log(overlays);
+			var newShape = e.overlay;	
+			newShape.type = e.type;
+
+			if (e.type !== google.maps.drawing.OverlayType.MARKER) {
+				// Switch back to non-drawing mode after drawing a shape.
+				//drawingManager.setDrawingMode(null);
+				
+				
+
+				// Add an event listener that selects the newly-drawn shape when the user
+				// mouses down on it.
+				google.maps.event.addListener(newShape, 'click', function(e) {
+					vertexAndPolyDel(e,newShape);
+					});
+				
+				//Add an event listener to select a shape if the mouse hovers over it
+				google.maps.event.addListener(newShape, 'mousedown', function(e) {
+					if (selectedShape != newShape ){
+						setSelection(newShape);
+					}});
+					
+						
+					
+					
+				setSelection(newShape);
+			}
+			else {
+				google.maps.event.addListener(newShape, 'click', function (e) {
+					setSelection(newShape);
+				});
+				setSelection(newShape);
+			}
+		});
+		
+		
+		function vertexAndPolyDel(e,newShape) {
+			if (e.vertex !== undefined) {
+				if (newShape.type === google.maps.drawing.OverlayType.POLYGON) {
+					var path = newShape.getPaths().getAt(e.path);
+					path.removeAt(e.vertex);
+					if (path.length < 3) {
+						newShape.setMap(null);
+					}
+				}
+				if (newShape.type === google.maps.drawing.OverlayType.POLYLINE) {
+					var path = newShape.getPath();
+						path.removeAt(e.vertex);
+											
+					if (path.length < 2) {
+						newShape.setMap(null);
+					}
+				}
+			}
+			
+			setSelection(newShape);
+		}
+				
+		function clearSelection () {
+			if (selectedShape) {
+				if (selectedShape.type !== 'marker') {
+					selectedShape.setEditable(false);
+				}
+					
+					selectedShape = null;
+			}
+		}
+
+		function setSelection (shape) {
+			if (shape.type !== 'marker') {
+				clearSelection();
+				shape.setEditable(true);
+				
+				//Send the values to be updated
+				var thi = shape.strokeWeight;
+				var opa = shape.fillOpacity;
+				var geod = shape.geodesic;
+				var fCol = shape.fillColor;
+				var sCol = shape.strokeColor;
+				
+				updateMenuValues(thi, opa, geod, fCol, sCol);
+				//if (shape.type !== 'polygon'){
+				//	document.getElementById("geodesicBox").disabled = true;
+				//} else if(shape.type !== 'polyline'){
+				//	document.getElementById("geodesicBox").disabled = true;
+				//}
+				//
+				//else {
+				//	document.getElementById("geodesicBox").disabled = false;
+				//	console.log("hey")
+				//}
+			}
+			else if (shape.type == 'marker') {
+				clearSelection();
+			}
+				
+			selectedShape = shape;
+		} 
+		
+
+		buildColorPalette();
+}
+		//Set selected thickness
+		function setSelectedThickness(sWeight) {
+			if (selectedShape){
+			selectedShape.set('strokeWeight', sWeight)
+			}
+		}
+		
+		//Set selected opacity
+		function setSelectedOpacity(fOpacity) {
+			if (selectedShape) {
+				selectedShape.set('fillOpacity', fOpacity)
+			}
+		}
+		
+		//Set the selected geodesic state
+		var gCheckbox = document.querySelector("input[name=geodesicBox]");
+		gCheckbox.addEventListener( 'change', function() {
+		if(this.checked){
+			if (selectedShape) {
+				selectedShape.set('geodesic', true);
+			}
+		}	else{
+				selectedShape.set('geodesic', false);
+			}
+		});
+		
+		//set selected fill colour
+        function setSelectedShapeColor (color) {
+            if (selectedShape) {
+                if (selectedShape.type == google.maps.drawing.OverlayType.POLYLINE) {
+                    selectedShape.set('strokeColor', color);
+                } else {
+                    selectedShape.set('fillColor', color);
+					
+					var sCheckbox = document.querySelector("input[name=blackStroke]");
+					if (sCheckbox.checked){
+
+						console.log("adaedf");
+						selectedShape.set('strokeColor', '#00000');
+					} else {
+						selectedShape.set('strokeColor', color);
+						console.log("adaedf2");
+					}
+                }
+             }
+        }
+		//Set stroke colour for an already created shape to black
+		/*
+		var scCheckbox = document.querySelector("input[name=blackStroke]");
+		scCheckbox.addEventListener( 'change', function() {
+		if(this.checked){
+			if (selectedShape) {
+				selectedShape.set('strokeColor', '#00000');
+				console.log(selectedShape.strokeColor);
+			}
+		}	else{
+			if (selectedShape) {
+				selectedShape.set('strokeColor', selectedColor);
+				console.log(selectedShape.strokeColor);
+			}
+			}
+		});
+		*/
+		
+		function updateMenuValues(thi, opa, geod, fCol, sCol){
+		
+		//Update thickness slider and value on the settings menu
+		var thicknessSliderOutput = document.getElementById("thicknessRangeVal");
+		thicknessSliderOutput.innerHTML = thi;
+		document.getElementById("thicknessRange").value = thi*20;
+		
+		//Update the opacity slider and value on the settings menu
+		var opacitySliderOutput = document.getElementById("opacityRangeVal");
+		opacitySliderOutput.innerHTML =  "% " + opa*100;
+		document.getElementById("colourOpacity").value =  opa*100;
+
+		
+		//Update geodesic state on the settings menu		
+		if(geod){
+			document.getElementById("geodesicBox").checked = true;
+			}else{
+			document.getElementById("geodesicBox").checked = false;
+			}
+		}
+	  
+function deleteSelectedShape () {
+	if (selectedShape) {
+		selectedShape.setMap(null);
+	}
+}
+			
+function removeLine() {
+	var lastOverlay = overlays.pop();
+	if (lastOverlay) lastOverlay.setMap(null);
+	}
+		
+function deleteAllShape() {
+	for (var i=0; i < overlays.length; i++) {
+		overlays[i].setMap(null);
+	}
+	overlays = [];
+}
+
+	</script>
+	<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyBzunGwIF2OwsfrOkIC_8bhh0OPGZXo52Y&libraries=drawing&callback=initMap"
+		 async defer></script>
+  </body>
+</html>
Index: /gs3-extensions/map-editor/DrawingManager/checkpoints-singlefile/index backup v7.html
===================================================================
--- /gs3-extensions/map-editor/DrawingManager/checkpoints-singlefile/index backup v7.html	(revision 32709)
+++ /gs3-extensions/map-editor/DrawingManager/checkpoints-singlefile/index backup v7.html	(revision 32709)
@@ -0,0 +1,397 @@
+<!DOCTYPE html>
+<html>
+  <head>
+	<title>Drawing Tools</title>
+	<meta name="viewport" content="initial-scale=1.0, user-scalable=no">
+	<meta charset="utf-8">
+	<style>
+	  /* Always set the map height explicitly to define the size of the div
+	   * element that contains the map. */
+	  #map {
+		height: 83%;
+		width: 90;
+		float: bottom;
+		clear: both;
+	  }
+	  /* Optional: Makes the sample page fill the window. */
+	  html, body {
+		height: 100%;
+		width: 99%;
+		margin: 0;
+		padding: 0;
+
+	  }
+	  
+	  #DeleteButtons{
+	  display: inline-block;
+	  float: left;
+	  padding-left: 10px;
+	  padding-top: 5px;
+	  width: 100%
+
+	  }
+	  
+	  #LineThickness{
+	  display: inline-block;
+	  float: left;
+	  padding-left: 10px;
+	  padding-top: 5px;
+
+	  }
+	  
+	  #ColourOpacity{
+	  display: inline-block;
+	  float: left;
+	  padding-left: 10px;
+	  padding-top: 5px;
+
+	  }
+	  
+	  #buttons3{
+	  display: inline-block;
+	  float: left;
+	  padding-left: 10px;
+	  padding-top: 5px;
+
+	  }	  
+	  
+      #FIllColour {
+	  display: inline-block;
+	  float: left;
+	  padding-left: 10px;
+	  padding-top: 5px;
+	  }
+	  
+      #color-palette1 {
+      clear: both;
+      }
+	  
+      .color-buttons1 {
+      width: 14px;
+      height: 14px;
+      font-size: 0;
+      margin: 2px;
+      float: left;
+      cursor: pointer;
+      }
+
+
+	</style>
+  </head>
+  <body>
+	<div id = "DeleteButtons">
+	<button onclick="removeLine()" accesskey="z">Delete Last</button>
+	<button onclick="deleteAllShape()" accesskey="c">Clear All</button>
+	<button onclick="deleteSelectedShape()" accesskey="c">Delete Selected</button>
+	
+	</div>
+	
+	<div id = "LineThickness">
+	<p>Line thickness: <input type="range" min="20" max="100" value="1" class="slider" id="thicknessRange"> </p>
+	<p>Value: <span id="thicknessRangeVal"></span></p>
+	</div>	
+	
+	<div id = "ColourOpacity">
+	<p>Colour opacity: <input type="range" min="10" max="100" value="40" class="slider" id="colourOpacity"> </p>
+	<p>Value: <span id="opacityRangeVal"></span></p>
+	</div>
+	
+
+
+	<div id="FIllColour">
+     <p> FIll Colour:</p> <div id="color-palette1"></div> 
+	</div>
+
+	
+	
+	<div id="map"></div>
+	
+	<script>
+		var colors = ['#1E90FF', '#FF1493', '#4B0082', '#32CD32', '#FF8C00', '#000000'];
+		var selectedColor;
+		var colorButtons = {};
+	    var thicknessValue = 1;
+		var opacityValue = 0.4;
+		var polyOptions = {
+			fillColor: '#CA4A2F',
+			strokeWeight: thicknessValue,
+			fillOpacity: opacityValue,
+			editable: true,
+			draggable: true,
+			geodesic : false,
+		  };
+		  
+		var overlays = [];
+		var drawingManager;
+		var selectedShape;
+		
+		
+		
+
+		//Update thickness 
+		var thicknessSlider = document.getElementById("thicknessRange");
+		var thicknessSliderOutput = document.getElementById("thicknessRangeVal");
+		thicknessSliderOutput.innerHTML = thicknessSlider.value/20;
+		
+		thicknessSlider.oninput = function() {
+			thicknessSliderOutput.innerHTML = this.value/20;
+			thicknessValue = this.value/20;
+			polyOptions.strokeWeight = thicknessValue;
+			setSelectedThickness(thicknessValue);
+		}
+		
+		//Update opacity
+		var opacitySlider = document.getElementById("colourOpacity");
+		var opacitySliderOutput = document.getElementById("opacityRangeVal");	
+		opacitySliderOutput.innerHTML =  "% " + Math.round(opacitySlider.value);
+		
+		opacitySlider.oninput = function() {
+			opacityValue = this.value/100;
+			polyOptions.fillOpacity = opacityValue;
+			opacitySliderOutput = opacityValue;
+			opacityRangeVal.innerHTML = "% " + Math.round( opacitySliderOutput * 100);
+			setSelectedOpacity(opacityValue);
+		}
+
+	
+		////////////////////////////////////////////////////////////////////////////////////////
+        function makeColorButton (color) {
+            var button = document.createElement('span');
+            button.className = 'color-buttons1';
+            button.style.backgroundColor = color;
+            google.maps.event.addDomListener(button, 'click', function () {
+				selectColor(color);
+				setSelectedShapeColor(color);
+            });
+            return button;
+        }
+        function buildColorPalette () {
+			var colorPalette = document.getElementById('color-palette1');
+            for (var i = 0; i < colors.length; ++i) {
+                var currColor = colors[i];
+                var colorButton = makeColorButton(currColor);
+                colorPalette.appendChild(colorButton);
+                colorButtons[currColor] = colorButton;
+            }
+            selectColor(colors[0]);
+        };		
+		function selectColor (color) {
+                selectedColor = color;
+                for (var i = 0; i < colors.length; ++i) {
+                    var currColor = colors[i];
+                    colorButtons[currColor].style.border = currColor == color ? '2px solid #789' : '2px solid #fff';
+                }
+
+                // Retrieves the current options from the drawing manager and replaces the
+                // stroke or fill color as appropriate.
+                var polylineOptions = drawingManager.get('polylineOptions');
+                polylineOptions.strokeColor = color;
+                drawingManager.set('polylineOptions', polylineOptions);
+
+                var rectangleOptions = drawingManager.get('rectangleOptions');
+                rectangleOptions.fillColor = color;
+                drawingManager.set('rectangleOptions', rectangleOptions);
+
+                var circleOptions = drawingManager.get('circleOptions');
+                circleOptions.fillColor = color;
+                drawingManager.set('circleOptions', circleOptions);
+
+                var polygonOptions = drawingManager.get('polygonOptions');
+                polygonOptions.fillColor = color;
+                drawingManager.set('polygonOptions', polygonOptions);
+            }
+		
+		
+		
+		
+	  function initMap() {
+		
+		var map = new google.maps.Map(document.getElementById('map'), {
+		  center: {lat: -34.397, lng: 150.644},
+		  zoom: 3
+		});
+		
+	
+		drawingManager = new google.maps.drawing.DrawingManager({
+			drawingMode: google.maps.drawing.OverlayType.RECTANGLE,
+			drawingControl: true,
+			drawingControlOptions: {
+				position: google.maps.ControlPosition.TOP_CENTER,
+				drawingModes: ['marker', 'circle', 'polygon', 'polyline', 'rectangle']
+			},
+			markerOptions: { draggable: true},
+			circleOptions: polyOptions,
+			polylineOptions : polyOptions,
+			polygonOptions: polyOptions,
+			rectangleOptions: polyOptions,
+		  });
+	
+		drawingManager.setMap(map);
+		
+		
+		//overlays.push(event.overlay); // store reference to added overlay
+		google.maps.event.addListener(drawingManager, 'overlaycomplete', function (e) {
+			overlays.push(e.overlay); // store reference to added overlay
+			//console.log(overlays);
+			var newShape = e.overlay;	
+			newShape.type = e.type;
+
+			if (e.type !== google.maps.drawing.OverlayType.MARKER) {
+				// Switch back to non-drawing mode after drawing a shape.
+				//drawingManager.setDrawingMode(null);
+				
+				
+				console.log(newShape);
+				// Add an event listener that selects the newly-drawn shape when the user
+				// mouses down on it.
+				google.maps.event.addListener(newShape, 'click', function(e) {
+					vertexAndPolyDel(e,newShape);
+					console.log("here");
+					});
+				
+				//Add an event listener to select a shape if the mouse hovers over it
+				google.maps.event.addListener(newShape, 'mousedown', function(e) {
+					if (selectedShape != newShape ){
+						setSelection(newShape);
+					}});
+					
+						
+					
+					
+				setSelection(newShape);
+			}
+			else {
+				google.maps.event.addListener(newShape, 'click', function (e) {
+					setSelection(newShape);
+					console.log("there");
+				});
+				setSelection(newShape);
+			}
+		});
+		
+		
+		function vertexAndPolyDel(e,newShape) {
+			if (e.vertex !== undefined) {
+				if (newShape.type === google.maps.drawing.OverlayType.POLYGON) {
+					var path = newShape.getPaths().getAt(e.path);
+					console.log(path);
+					path.removeAt(e.vertex);
+					if (path.length < 3) {
+						newShape.setMap(null);
+					}
+				}
+				if (newShape.type === google.maps.drawing.OverlayType.POLYLINE) {
+					var path = newShape.getPath();
+						path.removeAt(e.vertex);
+											
+					if (path.length < 2) {
+						newShape.setMap(null);
+					}
+				}
+			}
+			
+			setSelection(newShape);
+		}
+				
+		function clearSelection () {
+			if (selectedShape) {
+				if (selectedShape.type !== 'marker') {
+					selectedShape.setEditable(false);
+				}
+					
+					selectedShape = null;
+			}
+		}
+
+		function setSelection (shape) {
+			if (shape.type !== 'marker') {
+				clearSelection();
+				shape.setEditable(true);
+				
+				//Send the values to be updated
+				var thi = shape.strokeWeight;
+				var opa = shape.fillOpacity;
+				var fCol = shape.fillColor;
+				var sCol = shape.strokeColor;
+				
+				updateMenuValues(thi, opa, fCol, sCol);
+
+			}
+			else if (shape.type == 'marker') {
+				clearSelection();
+			}
+				
+			selectedShape = shape;
+		} 
+		
+
+		buildColorPalette();
+}
+		//Set selected thickness
+		function setSelectedThickness(sWeight) {
+			if (selectedShape){
+			selectedShape.set('strokeWeight', sWeight)
+			}
+		}
+		
+		//Set selected opacity
+		function setSelectedOpacity(fOpacity) {
+			if (selectedShape) {
+				selectedShape.set('fillOpacity', fOpacity)
+			}
+		}
+		
+
+		
+		//set selected fill colour
+        function setSelectedShapeColor (color) {
+            if (selectedShape) {
+                if (selectedShape.type == google.maps.drawing.OverlayType.POLYLINE) {
+                    selectedShape.set('strokeColor', color);
+                } else {
+                    selectedShape.set('fillColor', color);
+					selectedShape.set('strokeColor', color);
+
+                }
+             }
+        }
+
+		
+		function updateMenuValues(thi, opa, fCol, sCol){
+		
+		//Update thickness slider and value on the settings menu
+		var thicknessSliderOutput = document.getElementById("thicknessRangeVal");
+		thicknessSliderOutput.innerHTML = thi;
+		document.getElementById("thicknessRange").value = thi*20;
+		
+		//Update the opacity slider and value on the settings menu
+		var opacitySliderOutput = document.getElementById("opacityRangeVal");
+		opacitySliderOutput.innerHTML =  "% " + opa*100;
+		document.getElementById("colourOpacity").value =  opa*100;
+
+		}
+	  
+function deleteSelectedShape () {
+	if (selectedShape) {
+		selectedShape.setMap(null);
+	}
+}
+			
+function removeLine() {
+	var lastOverlay = overlays.pop();
+	if (lastOverlay) lastOverlay.setMap(null);
+	}
+		
+function deleteAllShape() {
+	for (var i=0; i < overlays.length; i++) {
+		overlays[i].setMap(null);
+	}
+	overlays = [];
+}
+
+	</script>
+	<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyBzunGwIF2OwsfrOkIC_8bhh0OPGZXo52Y&libraries=drawing&callback=initMap"
+		 async defer></script>
+		 
+  </body>
+</html>
Index: /gs3-extensions/map-editor/DrawingManager/checkpoints-singlefile/index backup v8.html
===================================================================
--- /gs3-extensions/map-editor/DrawingManager/checkpoints-singlefile/index backup v8.html	(revision 32709)
+++ /gs3-extensions/map-editor/DrawingManager/checkpoints-singlefile/index backup v8.html	(revision 32709)
@@ -0,0 +1,496 @@
+<!DOCTYPE html>
+<html>
+  <head>
+	<title>Drawing Tools</title>
+	<meta name="viewport" content="initial-scale=1.0, user-scalable=no">
+	<meta charset="utf-8">
+	<style>
+	  /* Always set the map height explicitly to define the size of the div
+	   * element that contains the map. */
+	  #map {
+		height: 83%;
+		width: 90;
+		float: bottom;
+		clear: both;
+	  }
+	  /* Optional: Makes the sample page fill the window. */
+	  html, body {
+		height: 100%;
+		width: 99%;
+		margin: 0;
+		padding: 0;
+
+	  }
+	  
+	  #DeleteButtons{
+	  display: inline-block;
+	  float: left;
+	  padding-left: 10px;
+	  padding-top: 5px;
+	  width: 100%
+
+	  }
+	  
+	  #LineThickness{
+	  display: inline-block;
+	  float: left;
+	  padding-left: 10px;
+	  padding-top: 5px;
+
+	  }
+	  
+	  #ColourOpacity{
+	  display: inline-block;
+	  float: left;
+	  padding-left: 10px;
+	  padding-top: 5px;
+
+	  }
+	  
+	  #buttons3{
+	  display: inline-block;
+	  float: left;
+	  padding-left: 10px;
+	  padding-top: 5px;
+
+	  }	  
+	  
+      #FillColour {
+	  display: inline-block;
+	  float: left;
+	  padding-left: 10px;
+	  padding-top: 5px;
+	  }
+	  
+      #color-palette1 {
+      clear: both;
+      }
+	  
+      .color-buttons1 {
+      width: 14px;
+      height: 14px;
+      font-size: 0;
+      margin: 2px;
+      float: left;
+      cursor: pointer;
+      }
+
+
+	</style>
+  </head>
+  <body>
+	<div id = "DeleteButtons">
+	<button onclick="removeLine()" accesskey="z">Delete Last</button>
+	<button onclick="deleteAllShape()" accesskey="c">Clear All</button>
+	<button onclick="deleteSelectedShape()" accesskey="b">Delete Selected</button>
+	<button onclick="polygonGetPath()" accesskey="n">Get Path</button>
+	
+	</div>
+	
+	<div id = "LineThickness">
+	<p>Line thickness: <input type="range" min="20" max="100" value="1" class="slider" id="thicknessRange"> </p>
+	<p>Value: <span id="thicknessRangeVal"></span></p>
+	</div>	
+	
+	<div id = "ColourOpacity">
+	<p>Colour opacity: <input type="range" min="10" max="100" value="40" class="slider" id="colourOpacity"> </p>
+	<p>Value: <span id="opacityRangeVal"></span></p>
+	</div>
+	
+
+
+	<div id="FillColour">
+     <p> Fill Colour:</p> <div id="color-palette1"></div> 
+	</div>
+
+	
+	
+	<div id="map"></div>
+	
+	<script>
+		var shiftKeyNotPressed = true;
+		var colors = ['#1E90FF', '#FF1493', '#4B0082', '#32CD32', '#FF8C00', '#000000'];
+		var selectedColor;
+		var colorButtons = {};
+	    var thicknessValue = 1;
+		var opacityValue = 0.4;
+		var polyOptions = {
+			fillColor: '#CA4A2F',
+			strokeWeight: thicknessValue,
+			fillOpacity: opacityValue,
+			editable: true,
+			draggable: true,
+			geodesic : false,
+		  };
+		  
+		 
+		var overlays = [];
+		var drawingManager;
+		var selectedShape;
+		var selectedShapes = []; 
+		
+		
+
+		//Update thickness 
+		var thicknessSlider = document.getElementById("thicknessRange");
+		var thicknessSliderOutput = document.getElementById("thicknessRangeVal");
+		thicknessSliderOutput.innerHTML = thicknessSlider.value/20;
+		
+		thicknessSlider.oninput = function() {
+			thicknessSliderOutput.innerHTML = this.value/20;
+			thicknessValue = this.value/20;
+			polyOptions.strokeWeight = thicknessValue;
+			setSelectedThickness(thicknessValue);
+		}
+		
+		//Update opacity
+		var opacitySlider = document.getElementById("colourOpacity");
+		var opacitySliderOutput = document.getElementById("opacityRangeVal");	
+		opacitySliderOutput.innerHTML =  "% " + Math.round(opacitySlider.value);
+		
+		opacitySlider.oninput = function() {
+			opacityValue = this.value/100;
+			polyOptions.fillOpacity = opacityValue;
+			opacitySliderOutput = opacityValue;
+			opacityRangeVal.innerHTML = "% " + Math.round( opacitySliderOutput * 100);
+			setSelectedOpacity(opacityValue);
+		}
+
+	
+		////////////////////////////////////////////////////////////////////////////////////////
+        function makeColorButton (color) {
+            var button = document.createElement('span');
+            button.className = 'color-buttons1';
+            button.style.backgroundColor = color;
+            google.maps.event.addDomListener(button, 'click', function () {
+				selectColor(color);
+				setSelectedShapeColor(color);
+            });
+            return button;
+        }
+        function buildColorPalette () {
+			var colorPalette = document.getElementById('color-palette1');
+            for (var i = 0; i < colors.length; ++i) {
+                var currColor = colors[i];
+                var colorButton = makeColorButton(currColor);
+                colorPalette.appendChild(colorButton);
+                colorButtons[currColor] = colorButton;
+            }
+            selectColor(colors[0]);
+        };		
+		function selectColor (color) {
+                selectedColor = color;
+                for (var i = 0; i < colors.length; ++i) {
+                    var currColor = colors[i];
+                    colorButtons[currColor].style.border = currColor == color ? '2px solid #789' : '2px solid #fff';
+                }
+
+                // Retrieves the current options from the drawing manager and replaces the
+                // stroke or fill color as appropriate.
+                var polylineOptions = drawingManager.get('polylineOptions');
+                polylineOptions.strokeColor = color;
+                drawingManager.set('polylineOptions', polylineOptions);
+
+                var rectangleOptions = drawingManager.get('rectangleOptions');
+                rectangleOptions.fillColor = color;
+                drawingManager.set('rectangleOptions', rectangleOptions);
+
+                var circleOptions = drawingManager.get('circleOptions');
+                circleOptions.fillColor = color;
+                drawingManager.set('circleOptions', circleOptions);
+
+                var polygonOptions = drawingManager.get('polygonOptions');
+                polygonOptions.fillColor = color;
+                drawingManager.set('polygonOptions', polygonOptions);
+            }
+		
+		
+		
+		
+	  function initMap() {
+		
+		var map = new google.maps.Map(document.getElementById('map'), {
+		  center: {lat: -34.397, lng: 150.644},
+		  zoom: 3
+		});
+		
+	
+		drawingManager = new google.maps.drawing.DrawingManager({
+			drawingMode: google.maps.drawing.OverlayType.RECTANGLE,
+			drawingControl: true,
+			drawingControlOptions: {
+				position: google.maps.ControlPosition.TOP_CENTER,
+				drawingModes: ['marker', 'circle', 'polygon', 'polyline', 'rectangle']
+			},
+			markerOptions: { draggable: true},
+			circleOptions: polyOptions,
+			polylineOptions : polyOptions,
+			polygonOptions: polyOptions,
+			rectangleOptions: polyOptions,
+		  });
+	
+		drawingManager.setMap(map);
+		
+		
+		//overlays.push(event.overlay); // store reference to added overlay
+		google.maps.event.addListener(drawingManager, 'overlaycomplete', function (e) {
+			overlays.push(e.overlay); // store reference to added overlay
+			//console.log(overlays);
+			var newShape = e.overlay;	
+			newShape.type = e.type;
+			
+
+			
+			if (e.type !== google.maps.drawing.OverlayType.MARKER) {
+				// Switch back to non-drawing mode after drawing a shape.
+				//drawingManager.setDrawingMode(null);
+				
+				
+
+				// Add an event listener that selects the newly-drawn shape when the user
+				// mouses down on it.
+				google.maps.event.addListener(newShape, 'click', function(e) {
+
+						vertexAndPolyDel(e,newShape);
+						console.log(drawingManager.drawingMode);
+
+					
+					});
+				
+				//Add an event listener to select a shape if the mouse hovers over it
+				google.maps.event.addListener(newShape, 'mousedown', function(e) {
+					
+						if(drawingManager.drawingMode == null) {
+							setSelection(newShape);
+							
+						}
+						
+					});
+					
+						
+					
+					
+				setSelection(newShape);
+			}
+			else {
+				google.maps.event.addListener(newShape, 'click', function (e) {
+					setSelection(newShape);
+					console.log(drawingManager.drawingMode);
+				});
+				setSelection(newShape);
+			}
+		});
+		
+		
+		function vertexAndPolyDel(e,newShape) {
+		console.log("triggered");
+			if (e.vertex !== undefined) {
+				if (newShape.type === google.maps.drawing.OverlayType.POLYGON) {
+					var path = newShape.getPaths().getAt(e.path);
+					path.removeAt(e.vertex);
+					if (path.length < 3) {
+						newShape.setMap(null);
+					}
+				}
+				if (newShape.type === google.maps.drawing.OverlayType.POLYLINE) {
+					var path = newShape.getPath();
+						path.removeAt(e.vertex);
+											
+					if (path.length < 2) {
+						newShape.setMap(null);
+					}
+				}
+			}
+//			console.log(path)
+			setSelection(newShape);
+		}
+				
+		function clearSelection () {
+			if (selectedShape) {
+				if (selectedShape.type !== 'marker') {
+					selectedShape.setEditable(false);
+					if(shiftKeyNotPressed){
+						for (var i=0; i < selectedShapes.length; i++) {
+						selectedShapes[i].setEditable(false);
+					}
+					selectedShapes = [];
+					}
+				}
+					
+					selectedShape = null;
+			}
+		}
+
+		function setSelection (shape) {
+		
+			if (shape.type !== 'marker') {
+				if(shiftKeyNotPressed) {
+					clearSelection();
+				}
+				shape.setEditable(true);
+				selectedShapes.push(shape);
+				
+				//Send the values to be updated
+				var thi = shape.strokeWeight;
+				var opa = shape.fillOpacity;
+				var fCol = shape.fillColor;
+				var sCol = shape.strokeColor;
+				
+				updateMenuValues(thi, opa, fCol, sCol);
+
+			}
+			else if (shape.type == 'marker') {
+				clearSelection();
+			}
+				
+			selectedShape = shape;
+		} 
+		
+
+		
+		google.maps.event.addListener(map, 'click', clearSelection);
+		google.maps.event.addListener(map, 'click', function()
+		{
+//		console.log(event.button);
+		clearSelection();
+		}
+		);
+		
+		
+		//Setting drawing tool option
+		document.addEventListener('keydown', function() {
+		//if (event.code == 'KeyX' && (event.ctrlKey || event.metaKey))
+				if (event.code == 'Digit0' || event.code == 'Numpad0' || event.code == 'Backquote') {
+					//clearSelection();
+					drawingManager.setDrawingMode(null);
+				} else if (event.code == 'Digit1') {
+					drawingManager.setDrawingMode('marker');
+				} else if (event.code == 'Digit2') {
+					drawingManager.setDrawingMode('circle');
+				} else if (event.code == 'Digit3') {
+					drawingManager.setDrawingMode('polygon');
+				} else if (event.code == 'Digit4') {
+					drawingManager.setDrawingMode('polyline');
+				} else if (event.code == 'Digit5' ) {
+					drawingManager.setDrawingMode('rectangle');
+				} 
+//					console.log(event.code);
+				});
+		
+		//Check if the shift key is pressed
+		document.addEventListener('keydown', function() {		
+			if (event.code == 'ShiftLeft' || event.code == 'ShiftRight')
+			{
+				shiftKeyNotPressed = false;
+			}
+
+		});
+		
+		document.addEventListener('keyup', function() {		
+			if (event.code == 'ShiftLeft' || event.code == 'ShiftRight')
+			{
+				shiftKeyNotPressed = true;
+			}
+
+		});
+		
+		
+		buildColorPalette();
+}
+		//Set selected thickness
+		function setSelectedThickness(sWeight) {
+			if (selectedShape){
+				selectedShape.set('strokeWeight', sWeight)
+			}
+			if(selectedShapes !== 0) {
+				for (var i=0; i < selectedShapes.length; i++) {
+					selectedShapes[i].set('strokeWeight', sWeight);
+				}
+			}
+		}
+		
+		//Set selected opacity
+		function setSelectedOpacity(fOpacity) {
+			if (selectedShape) {
+				selectedShape.set('fillOpacity', fOpacity)
+			}
+			if(selectedShapes !== 0) {
+				for (var i=0; i < selectedShapes.length; i++) {
+					selectedShapes[i].set('fillOpacity', fOpacity);
+				}
+			}			
+		}
+		
+
+		
+		//set selected fill colour
+        function setSelectedShapeColor (color) {
+            if (selectedShape) {
+                if (selectedShape.type == google.maps.drawing.OverlayType.POLYLINE) {
+                    selectedShape.set('strokeColor', color);
+                } else {
+                    selectedShape.set('fillColor', color);
+					selectedShape.set('strokeColor', color);
+                }
+             }
+			if(selectedShapes !== 0) {
+				for (var i=0; i < selectedShapes.length; i++) {
+					selectedShapes[i].set('fillColor', color);
+					selectedShapes[i].set('strokeColor', color);
+				}
+			}			 
+        }
+
+		
+		function updateMenuValues(thi, opa, fCol, sCol){
+		
+		//Update thickness slider and value on the settings menu
+		var thicknessSliderOutput = document.getElementById("thicknessRangeVal");
+		thicknessSliderOutput.innerHTML = thi;
+		document.getElementById("thicknessRange").value = thi*20;
+		
+		//Update the opacity slider and value on the settings menu
+		var opacitySliderOutput = document.getElementById("opacityRangeVal");
+		opacitySliderOutput.innerHTML =  "% " + opa*100;
+		document.getElementById("colourOpacity").value =  opa*100;
+		
+
+			if (drawingManager.drawingMode == null) {
+				selectColor(fCol);
+			}
+		}
+		
+		
+		
+function polygonGetPath() {
+	if (selectedShape){
+		var Psp = selectedShape.getPaths();
+		console.log(Psp);
+	}
+
+}		
+	  
+function deleteSelectedShape () {
+	if (selectedShape) {
+		selectedShape.setMap(null);
+	}
+}
+			
+function removeLine() {
+	var lastOverlay = overlays.pop();
+	if (lastOverlay) lastOverlay.setMap(null);
+	}
+		
+function deleteAllShape() {
+	for (var i=0; i < overlays.length; i++) {
+		overlays[i].setMap(null);
+		
+	}
+	overlays = [];
+}
+
+	</script>
+	<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyBzunGwIF2OwsfrOkIC_8bhh0OPGZXo52Y&libraries=drawing&callback=initMap" async defer></script>
+	<script src="shortcuts.js"></script>
+  </body>
+</html>
Index: /gs3-extensions/map-editor/DrawingManager/checkpoints-singlefile/index backup v9.html
===================================================================
--- /gs3-extensions/map-editor/DrawingManager/checkpoints-singlefile/index backup v9.html	(revision 32709)
+++ /gs3-extensions/map-editor/DrawingManager/checkpoints-singlefile/index backup v9.html	(revision 32709)
@@ -0,0 +1,522 @@
+<!DOCTYPE html>
+<html>
+  <head>
+	<title>Drawing Tools</title>
+	<meta name="viewport" content="initial-scale=1.0, user-scalable=no">
+	<meta charset="utf-8">
+	<style>
+	  /* Always set the map height explicitly to define the size of the div
+	   * element that contains the map. */
+	  #map {
+		height: 83%;
+		width: 90;
+		float: bottom;
+		clear: both;
+	  }
+	  /* Optional: Makes the sample page fill the window. */
+	  html, body {
+		height: 100%;
+		width: 99%;
+		margin: 0;
+		padding: 0;
+
+	  }
+	  
+	  #DeleteButtons{
+	  display: inline-block;
+	  float: left;
+	  padding-left: 10px;
+	  padding-top: 5px;
+	  width: 100%
+
+	  }
+	  
+	  #LineThickness{
+	  display: inline-block;
+	  float: left;
+	  padding-left: 10px;
+	  padding-top: 5px;
+
+	  }
+	  
+	  #ColourOpacity{
+	  display: inline-block;
+	  float: left;
+	  padding-left: 10px;
+	  padding-top: 5px;
+
+	  }
+	  
+	  #buttons3{
+	  display: inline-block;
+	  float: left;
+	  padding-left: 10px;
+	  padding-top: 5px;
+
+	  }	  
+	  
+      #FillColour {
+	  display: inline-block;
+	  float: left;
+	  padding-left: 10px;
+	  padding-top: 5px;
+	  }
+	  
+      #color-palette1 {
+      clear: both;
+      }
+	  
+      .color-buttons1 {
+      width: 14px;
+      height: 14px;
+      font-size: 0;
+      margin: 2px;
+      float: left;
+      cursor: pointer;
+      }
+
+
+	</style>
+  </head>
+  <body>
+	<div id = "DeleteButtons">
+	<button onclick="removeLine()" accesskey="z">Delete Last</button>
+	<button onclick="deleteAllShape()" accesskey="c">Clear All</button>
+	<button onclick="deleteSelectedShape()" accesskey="b">Delete Selected</button>
+	<button onclick="polygonGetPath()" accesskey="n">Get Path</button>
+	
+	</div>
+	
+	<div id = "LineThickness">
+	<p>Line thickness: <input type="range" min="20" max="100" value="1" class="slider" id="thicknessRange"> </p>
+	<p>Value: <span id="thicknessRangeVal"></span></p>
+	</div>	
+	
+	<div id = "ColourOpacity">
+	<p>Colour opacity: <input type="range" min="10" max="100" value="40" class="slider" id="colourOpacity"> </p>
+	<p>Value: <span id="opacityRangeVal"></span></p>
+	</div>
+	
+
+
+	<div id="FillColour">
+     <p> Fill Colour:</p> <div id="color-palette1"></div> 
+	</div>
+
+	
+	
+	<div id="map"></div>
+	
+	<script>
+		var shiftKeyPressed = false;
+		var mousedDownFired = false;
+		var colors = ['#1E90FF', '#FF1493', '#4B0082', '#32CD32', '#FF8C00', '#000000'];
+		var selectedColor;
+		var colorButtons = {};
+	    var thicknessValue = 1;
+		var opacityValue = 0.4;
+		var polyOptions = {
+			fillColor: '#CA4A2F',
+			strokeWeight: thicknessValue,
+			fillOpacity: opacityValue,
+			editable: true,
+			draggable: true,
+			geodesic : false,
+		  };
+		  
+		 
+		var overlays = [];
+		var drawingManager;
+		var selectedShape;
+		var selectedShapes = []; 
+		
+		
+
+		//Update thickness 
+		var thicknessSlider = document.getElementById("thicknessRange");
+		var thicknessSliderOutput = document.getElementById("thicknessRangeVal");
+		thicknessSliderOutput.innerHTML = thicknessSlider.value/20;
+		
+		thicknessSlider.oninput = function() {
+			thicknessSliderOutput.innerHTML = this.value/20;
+			thicknessValue = this.value/20;
+			polyOptions.strokeWeight = thicknessValue;
+			setSelectedThickness(thicknessValue);
+		}
+		
+		//Update opacity
+		var opacitySlider = document.getElementById("colourOpacity");
+		var opacitySliderOutput = document.getElementById("opacityRangeVal");	
+		opacitySliderOutput.innerHTML =  "% " + Math.round(opacitySlider.value);
+		
+		opacitySlider.oninput = function() {
+			opacityValue = this.value/100;
+			polyOptions.fillOpacity = opacityValue;
+			opacitySliderOutput = opacityValue;
+			opacityRangeVal.innerHTML = "% " + Math.round( opacitySliderOutput * 100);
+			setSelectedOpacity(opacityValue);
+		}
+
+	
+		////////////////////////////////////////////////////////////////////////////////////////
+        function makeColorButton (color) {
+            var button = document.createElement('span');
+            button.className = 'color-buttons1';
+            button.style.backgroundColor = color;
+            google.maps.event.addDomListener(button, 'click', function () {
+				selectColor(color);
+				setSelectedShapeColor(color);
+            });
+            return button;
+        }
+        function buildColorPalette () {
+			var colorPalette = document.getElementById('color-palette1');
+            for (var i = 0; i < colors.length; ++i) {
+                var currColor = colors[i];
+                var colorButton = makeColorButton(currColor);
+                colorPalette.appendChild(colorButton);
+                colorButtons[currColor] = colorButton;
+            }
+            selectColor(colors[0]);
+        };		
+		function selectColor (color) {
+                selectedColor = color;
+                for (var i = 0; i < colors.length; ++i) {
+                    var currColor = colors[i];
+                    colorButtons[currColor].style.border = currColor == color ? '2px solid #789' : '2px solid #fff';
+                }
+
+                // Retrieves the current options from the drawing manager and replaces the
+                // stroke or fill color as appropriate.
+                var polylineOptions = drawingManager.get('polylineOptions');
+                polylineOptions.strokeColor = color;
+                drawingManager.set('polylineOptions', polylineOptions);
+
+                var rectangleOptions = drawingManager.get('rectangleOptions');
+                rectangleOptions.fillColor = color;
+                drawingManager.set('rectangleOptions', rectangleOptions);
+
+                var circleOptions = drawingManager.get('circleOptions');
+                circleOptions.fillColor = color;
+                drawingManager.set('circleOptions', circleOptions);
+
+                var polygonOptions = drawingManager.get('polygonOptions');
+                polygonOptions.fillColor = color;
+                drawingManager.set('polygonOptions', polygonOptions);
+            }
+		
+		
+		
+		
+	  function initMap() {
+		
+		var map = new google.maps.Map(document.getElementById('map'), {
+		  center: {lat: -34.397, lng: 150.644},
+		  zoom: 3
+		});
+		
+	
+		drawingManager = new google.maps.drawing.DrawingManager({
+			drawingMode: google.maps.drawing.OverlayType.RECTANGLE,
+			drawingControl: true,
+			drawingControlOptions: {
+				position: google.maps.ControlPosition.TOP_CENTER,
+				drawingModes: ['marker', 'circle', 'polygon', 'polyline', 'rectangle']
+			},
+			markerOptions: { draggable: true},
+			circleOptions: polyOptions,
+			polylineOptions : polyOptions,
+			polygonOptions: polyOptions,
+			rectangleOptions: polyOptions,
+		  });
+	
+		drawingManager.setMap(map);
+		
+		
+		//overlays.push(event.overlay); // store reference to added overlay
+		google.maps.event.addListener(drawingManager, 'overlaycomplete', function (e) {
+			overlays.push(e.overlay); // store reference to added overlay
+			var newShape = e.overlay;	
+			newShape.type = e.type;
+						
+			if (e.type !== google.maps.drawing.OverlayType.MARKER) {
+			
+				// Switch back to non-drawing mode after drawing a shape.
+				//drawingManager.setDrawingMode(null);
+				
+				// Add an event listener that selects the newly-drawn shape when the user
+				// mouses down on it.
+				google.maps.event.addListener(newShape, 'click', function(e) {
+
+					vertexAndPolyDel(e,newShape);
+					mousedDownFired = false;
+					return;
+				
+				});
+				
+				google.maps.event.addListener(newShape, 'drag', function() {
+					//console.log(selectedShape);
+					console.log(selectedShapes.length);
+					if (selectedShapes.length > 1) {
+						//var xPos = selectedShape.
+						console.log(selectedShape);
+						}
+				
+				});				
+				
+				//Add an event listener to select a shape if the mouse hovers over it
+				google.maps.event.addListener(newShape, 'mousedown', function(e) {
+						if(drawingManager.drawingMode == null) {
+							mousedDownFired =true;
+//							console.log("MOUSDOWN ", e);
+							
+							setSelection(newShape);							
+						}						
+					});	
+				setSelection(newShape);
+			}
+			else {
+				//cLICK EVENT IF A MARKER IS CREATED
+				google.maps.event.addListener(newShape, 'click', function (e) {
+					setSelection(newShape);
+				});
+				setSelection(newShape);
+			}
+		});
+		
+		//Deletes a vertex if clicked on it
+		function vertexAndPolyDel(e,newShape) {
+			var vertex = e.vertex;
+			if (e.vertex !== undefined) {
+				if (newShape.type === google.maps.drawing.OverlayType.POLYGON) {
+					var path = newShape.getPaths().getAt(e.path);
+					path.removeAt(e.vertex);
+					if (path.length < 3) {
+						newShape.setMap(null);
+					}
+				}
+				if (newShape.type === google.maps.drawing.OverlayType.POLYLINE) {
+					var path = newShape.getPath();
+					path.removeAt(e.vertex);						
+					if (path.length < 2) {
+						newShape.setMap(null);
+					}
+				}
+			}
+			
+			//if(mousedDownFired == false)
+			//{
+			//setSelection(newShape, vertex);
+			//mousedDownFired = false;
+			//return;
+			//}
+			}
+				
+		function clearSelection () {
+			if (selectedShape) {
+				if (selectedShape.type !== 'marker') {
+					selectedShape.setEditable(false);
+					if(shiftKeyPressed == false){
+						for (var i=0; i < selectedShapes.length; i++) {
+						selectedShapes[i].setEditable(false);
+					}
+					selectedShapes = [];
+					}
+				}
+					
+					selectedShape = null;
+			}
+		}
+		var i = 0;
+		function setSelection (shape, e) {
+//			console.log(e);
+//			console.log(selectedShapes.length);
+			if (shape.type !== 'marker') {
+				if(shiftKeyPressed == false) {
+					if(e == undefined) {
+						clearSelection();	
+						shape.setEditable(true);						
+					}
+
+				}
+
+				//var shapeAlreadySelected = selectedShapes.includes(shape);
+				
+				if (selectedShapes.includes(shape)){
+					shape.setEditable(false);
+					selectedShapes.splice(shape, 1)
+				}
+				
+				else {
+					shape.setEditable(true);
+					selectedShapes.push(shape);	
+				}
+
+
+				console.log(selectedShapes.length);
+				
+				//Send the values to be updated
+				var thi = shape.strokeWeight;
+				var opa = shape.fillOpacity;
+				var fCol = shape.fillColor;
+				var sCol = shape.strokeColor;
+				updateMenuValues(thi, opa, fCol, sCol);
+
+			}
+			else if (shape.type == 'marker') {
+				clearSelection();
+			}
+				
+			selectedShape = shape;
+		}
+		
+
+		//Clears selection if clicked on the map when shift is not presseed
+		google.maps.event.addListener(map, 'click', function() {
+			if (shiftKeyPressed == false) {
+				clearSelection();
+			}
+		});	
+		
+
+		
+		
+		//Setting drawing tool option
+		document.addEventListener('keydown', function() {
+		//if (event.code == 'KeyX' && (event.ctrlKey || event.metaKey))
+				if (event.code == 'Digit0' || event.code == 'Numpad0' || event.code == 'Backquote') {
+					//clearSelection();
+					drawingManager.setDrawingMode(null);
+				} else if (event.code == 'Digit1') {
+					drawingManager.setDrawingMode('marker');
+				} else if (event.code == 'Digit2') {
+					drawingManager.setDrawingMode('circle');
+				} else if (event.code == 'Digit3') {
+					drawingManager.setDrawingMode('polygon');
+				} else if (event.code == 'Digit4') {
+					drawingManager.setDrawingMode('polyline');
+				} else if (event.code == 'Digit5' ) {
+					drawingManager.setDrawingMode('rectangle');
+				} 
+//					console.log(event.code);
+				});
+		
+		//Sets shift as pressed
+		document.addEventListener('keydown', function() {		
+			if (event.code == 'ShiftLeft' || event.code == 'ShiftRight')
+			{
+				shiftKeyPressed = true;
+
+			}
+
+		});
+		
+		//Sets shift as unpressed		
+		document.addEventListener('keyup', function() {		
+			if (event.code == 'ShiftLeft' || event.code == 'ShiftRight')
+			{
+				shiftKeyPressed = false;
+			}
+
+		});
+		
+		
+		buildColorPalette();
+}
+		//Set selected thickness
+		function setSelectedThickness(sWeight) {
+			if (selectedShape){
+				selectedShape.set('strokeWeight', sWeight)
+			}
+			if(selectedShapes !== 0) {
+				for (var i=0; i < selectedShapes.length; i++) {
+					selectedShapes[i].set('strokeWeight', sWeight);
+				}
+			}
+		}
+		
+		//Set selected opacity
+		function setSelectedOpacity(fOpacity) {
+			if (selectedShape) {
+				selectedShape.set('fillOpacity', fOpacity)
+			}
+			if(selectedShapes !== 0) {
+				for (var i=0; i < selectedShapes.length; i++) {
+					selectedShapes[i].set('fillOpacity', fOpacity);
+				}
+			}			
+		}
+		
+
+		
+		//set selected fill colour
+        function setSelectedShapeColor (color) {
+            if (selectedShape) {
+                if (selectedShape.type == google.maps.drawing.OverlayType.POLYLINE) {
+                    selectedShape.set('strokeColor', color);
+                } else {
+                    selectedShape.set('fillColor', color);
+					selectedShape.set('strokeColor', color);
+                }
+             }
+			if(selectedShapes !== 0) {
+				for (var i=0; i < selectedShapes.length; i++) {
+					selectedShapes[i].set('fillColor', color);
+					selectedShapes[i].set('strokeColor', color);
+				}
+			}			 
+        }
+
+		
+		function updateMenuValues(thi, opa, fCol, sCol){
+		
+		//Update thickness slider and value on the settings menu
+		var thicknessSliderOutput = document.getElementById("thicknessRangeVal");
+		thicknessSliderOutput.innerHTML = thi;
+		document.getElementById("thicknessRange").value = thi*20;
+		
+		//Update the opacity slider and value on the settings menu
+		var opacitySliderOutput = document.getElementById("opacityRangeVal");
+		opacitySliderOutput.innerHTML =  "% " + opa*100;
+		document.getElementById("colourOpacity").value =  opa*100;
+		
+
+			if (drawingManager.drawingMode == null) {
+				selectColor(fCol);
+			}
+		}
+
+		
+function polygonGetPath() {
+	if (selectedShape){
+		var Psp = selectedShape.getPaths();
+		console.log(Psp);
+	}
+
+}		
+	  
+function deleteSelectedShape () {
+	for (var i=0; i < selectedShapes.length; i++){
+		selectedShapes[i].setMap(null);
+	}
+	selectedShapes = [];
+}
+			
+function removeLine() {
+	var lastOverlay = overlays.pop();
+	if (lastOverlay) lastOverlay.setMap(null);
+	}
+		
+function deleteAllShape() {
+	for (var i=0; i < overlays.length; i++) {
+		overlays[i].setMap(null);
+		
+	}
+	overlays = [];
+}
+
+	</script>
+	<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyBzunGwIF2OwsfrOkIC_8bhh0OPGZXo52Y&libraries=drawing&callback=initMap" async defer></script>
+	<script src="shortcuts.js"></script>
+  </body>
+</html>
Index: /gs3-extensions/map-editor/DrawingManager/checkpoints-singlefile/shortcuts.js
===================================================================
--- /gs3-extensions/map-editor/DrawingManager/checkpoints-singlefile/shortcuts.js	(revision 32709)
+++ /gs3-extensions/map-editor/DrawingManager/checkpoints-singlefile/shortcuts.js	(revision 32709)
@@ -0,0 +1,223 @@
+/**
+ * http://www.openjs.com/scripts/events/keyboard_shortcuts/
+ * Version : 2.01.B
+ * By Binny V A
+ * License : BSD
+ */
+shortcut = {
+	'all_shortcuts':{},//All the shortcuts are stored in this array
+	'add': function(shortcut_combination,callback,opt) {
+		//Provide a set of default options
+		var default_options = {
+			'type':'keydown',
+			'propagate':false,
+			'disable_in_input':false,
+			'target':document,
+			'keycode':false
+		}
+		if(!opt) opt = default_options;
+		else {
+			for(var dfo in default_options) {
+				if(typeof opt[dfo] == 'undefined') opt[dfo] = default_options[dfo];
+			}
+		}
+
+		var ele = opt.target;
+		if(typeof opt.target == 'string') ele = document.getElementById(opt.target);
+		var ths = this;
+		shortcut_combination = shortcut_combination.toLowerCase();
+
+		//The function to be called at keypress
+		var func = function(e) {
+			e = e || window.event;
+			
+			if(opt['disable_in_input']) { //Don't enable shortcut keys in Input, Textarea fields
+				var element;
+				if(e.target) element=e.target;
+				else if(e.srcElement) element=e.srcElement;
+				if(element.nodeType==3) element=element.parentNode;
+
+				if(element.tagName == 'INPUT' || element.tagName == 'TEXTAREA') return;
+			}
+	
+			//Find Which key is pressed
+			if (e.keyCode) code = e.keyCode;
+			else if (e.which) code = e.which;
+			var character = String.fromCharCode(code).toLowerCase();
+			
+			if(code == 188) character=","; //If the user presses , when the type is onkeydown
+			if(code == 190) character="."; //If the user presses , when the type is onkeydown
+
+			var keys = shortcut_combination.split("+");
+			//Key Pressed - counts the number of valid keypresses - if it is same as the number of keys, the shortcut function is invoked
+			var kp = 0;
+			
+			//Work around for stupid Shift key bug created by using lowercase - as a result the shift+num combination was broken
+			var shift_nums = {
+				"`":"~",
+				"1":"!",
+				"2":"@",
+				"3":"#",
+				"4":"$",
+				"5":"%",
+				"6":"^",
+				"7":"&",
+				"8":"*",
+				"9":"(",
+				"0":")",
+				"-":"_",
+				"=":"+",
+				";":":",
+				"'":"\"",
+				",":"<",
+				".":">",
+				"/":"?",
+				"\\":"|"
+			}
+			//Special Keys - and their codes
+			var special_keys = {
+				'esc':27,
+				'escape':27,
+				'tab':9,
+				'space':32,
+				'return':13,
+				'enter':13,
+				'backspace':8,
+	
+				'scrolllock':145,
+				'scroll_lock':145,
+				'scroll':145,
+				'capslock':20,
+				'caps_lock':20,
+				'caps':20,
+				'numlock':144,
+				'num_lock':144,
+				'num':144,
+				
+				'pause':19,
+				'break':19,
+				
+				'insert':45,
+				'home':36,
+				'delete':46,
+				'end':35,
+				
+				'pageup':33,
+				'page_up':33,
+				'pu':33,
+	
+				'pagedown':34,
+				'page_down':34,
+				'pd':34,
+	
+				'left':37,
+				'up':38,
+				'right':39,
+				'down':40,
+	
+				'f1':112,
+				'f2':113,
+				'f3':114,
+				'f4':115,
+				'f5':116,
+				'f6':117,
+				'f7':118,
+				'f8':119,
+				'f9':120,
+				'f10':121,
+				'f11':122,
+				'f12':123
+			}
+	
+			var modifiers = { 
+				shift: { wanted:false, pressed:false},
+				ctrl : { wanted:false, pressed:false},
+				alt  : { wanted:false, pressed:false},
+				meta : { wanted:false, pressed:false}	//Meta is Mac specific
+			};
+                        
+			if(e.ctrlKey)	modifiers.ctrl.pressed = true;
+			if(e.shiftKey)	modifiers.shift.pressed = true;
+			if(e.altKey)	modifiers.alt.pressed = true;
+			if(e.metaKey)   modifiers.meta.pressed = true;
+                        
+			for(var i=0; k=keys[i],i<keys.length; i++) {
+				//Modifiers
+				if(k == 'ctrl' || k == 'control') {
+					kp++;
+					modifiers.ctrl.wanted = true;
+
+				} else if(k == 'shift') {
+					kp++;
+					modifiers.shift.wanted = true;
+
+				} else if(k == 'alt') {
+					kp++;
+					modifiers.alt.wanted = true;
+				} else if(k == 'meta') {
+					kp++;
+					modifiers.meta.wanted = true;
+				} else if(k.length > 1) { //If it is a special key
+					if(special_keys[k] == code) kp++;
+					
+				} else if(opt['keycode']) {
+					if(opt['keycode'] == code) kp++;
+
+				} else { //The special keys did not match
+					if(character == k) kp++;
+					else {
+						if(shift_nums[character] && e.shiftKey) { //Stupid Shift key bug created by using lowercase
+							character = shift_nums[character]; 
+							if(character == k) kp++;
+						}
+					}
+				}
+			}
+			
+			if(kp == keys.length && 
+						modifiers.ctrl.pressed == modifiers.ctrl.wanted &&
+						modifiers.shift.pressed == modifiers.shift.wanted &&
+						modifiers.alt.pressed == modifiers.alt.wanted &&
+						modifiers.meta.pressed == modifiers.meta.wanted) {
+				callback(e);
+	
+				if(!opt['propagate']) { //Stop the event
+					//e.cancelBubble is supported by IE - this will kill the bubbling process.
+					e.cancelBubble = true;
+					e.returnValue = false;
+	
+					//e.stopPropagation works in Firefox.
+					if (e.stopPropagation) {
+						e.stopPropagation();
+						e.preventDefault();
+					}
+					return false;
+				}
+			}
+		}
+		this.all_shortcuts[shortcut_combination] = {
+			'callback':func, 
+			'target':ele, 
+			'event': opt['type']
+		};
+		//Attach the function with the event
+		if(ele.addEventListener) ele.addEventListener(opt['type'], func, false);
+		else if(ele.attachEvent) ele.attachEvent('on'+opt['type'], func);
+		else ele['on'+opt['type']] = func;
+	},
+
+	//Remove the shortcut - just specify the shortcut and I will remove the binding
+	'remove':function(shortcut_combination) {
+		shortcut_combination = shortcut_combination.toLowerCase();
+		var binding = this.all_shortcuts[shortcut_combination];
+		delete(this.all_shortcuts[shortcut_combination])
+		if(!binding) return;
+		var type = binding['event'];
+		var ele = binding['target'];
+		var callback = binding['callback'];
+
+		if(ele.detachEvent) ele.detachEvent('on'+type, callback);
+		else if(ele.removeEventListener) ele.removeEventListener(type, callback, false);
+		else ele['on'+type] = false;
+	}
+}
Index: /gs3-extensions/map-editor/DrawingManager/checkpt22/index.css
===================================================================
--- /gs3-extensions/map-editor/DrawingManager/checkpt22/index.css	(revision 32709)
+++ /gs3-extensions/map-editor/DrawingManager/checkpt22/index.css	(revision 32709)
@@ -0,0 +1,70 @@
+/* Always set the map height explicitly to define the size of the div
+* element that contains the map. */
+#map {
+	height: 83%;
+	width: 90;
+	float: bottom;
+	clear: both;
+}
+
+  /* Optional: Makes the sample page fill the window. */
+  html, body {
+	height: 100%;
+	width: 99%;
+	margin: 0;
+	padding: 0;
+
+  }
+  
+  #DeleteButtons{
+  display: inline-block;
+  float: left;
+  padding-left: 10px;
+  padding-top: 5px;
+  width: 100%
+
+  }
+  
+  #LineThickness{
+  display: inline-block;
+  float: left;
+  padding-left: 10px;
+  padding-top: 5px;
+
+  }
+  
+  #ColourOpacity{
+  display: inline-block;
+  float: left;
+  padding-left: 10px;
+  padding-top: 5px;
+
+  }
+  
+  #buttons3{
+  display: inline-block;
+  float: left;
+  padding-left: 10px;
+  padding-top: 5px;
+
+  }	  
+  
+  #FillColour {
+  display: inline-block;
+  float: left;
+  padding-left: 10px;
+  padding-top: 5px;
+  }
+  
+  #color-palette1 {
+  clear: both;
+  }
+  
+  .color-buttons1 {
+  width: 14px;
+  height: 14px;
+  font-size: 0;
+  margin: 2px;
+  float: left;
+  cursor: pointer;
+  }
Index: /gs3-extensions/map-editor/DrawingManager/checkpt22/index.html
===================================================================
--- /gs3-extensions/map-editor/DrawingManager/checkpt22/index.html	(revision 32709)
+++ /gs3-extensions/map-editor/DrawingManager/checkpt22/index.html	(revision 32709)
@@ -0,0 +1,48 @@
+<!DOCTYPE html>
+<html>
+  <head>
+	<title>Drawing Tools</title>
+	<meta name="viewport" content="initial-scale=1.0, user-scalable=no">
+	<meta charset="utf-8">
+
+	<script src="https://code.jquery.com/jquery-3.3.1.js"></script>
+	<script src="index.js"></script>	
+	<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyBzunGwIF2OwsfrOkIC_8bhh0OPGZXo52Y&libraries=drawing&callback=initMap" async defer></script>
+	<script src="shortcuts.js"></script>
+	
+    <link rel="stylesheet" type="text/css" href="index.css">
+
+  </head>
+  <body>
+	<div id = "DeleteButtons">
+	<button onclick="deleteAllShape()" accesskey="c">Clear All</button>
+	<button onclick="deleteSelectedShape()" accesskey="b">Delete Selected</button>
+	<button onclick="polygonGetPath()" accesskey="q">Get Path</button>
+	<button onclick="undoMovement()" accesskey="n">Undo</button>
+	<button onclick="redoMovement()" accesskey="n">Redo</button>
+	
+	</div>
+	
+	<div id = "LineThickness">
+	<p>Line thickness: <input type="range" min="20" max="100" value="1" class="slider" id="thicknessRange"> </p>
+	<p>Value: <span id="thicknessRangeVal"></span></p>
+	</div>	
+	
+	<div id = "ColourOpacity">
+	<p>Colour opacity: <input type="range" min="10" max="100" value="40" class="slider" id="colourOpacity"> </p>
+	<p>Value: <span id="opacityRangeVal"></span></p>
+	</div>
+	
+
+
+	<div id="FillColour">
+     <p> Fill Colour:</p> <div id="color-palette1"></div> 
+	</div>
+
+	
+	
+	<div id="map"></div>
+	
+
+  </body>
+</html>
Index: /gs3-extensions/map-editor/DrawingManager/checkpt22/index.js
===================================================================
--- /gs3-extensions/map-editor/DrawingManager/checkpt22/index.js	(revision 32709)
+++ /gs3-extensions/map-editor/DrawingManager/checkpt22/index.js	(revision 32709)
@@ -0,0 +1,658 @@
+var debug = false;
+var redoPressed = false;
+var undoPressed = 0;
+var shiftKeyPressed = false;
+var dragFired = false;
+var selectionPass = true;
+var chosen;
+
+var overlays_copy_obj = {};
+
+var prevEdge = {
+	east: "",
+	north: "",
+	south: "",
+	west: ""
+}
+var nextEdge = {
+	east: "",
+	north: "",
+	south: "",
+	west: ""
+}
+var prevVertex = {
+	lat: "",
+	lng: ""
+};
+var nextVertex = {
+	lat: "",
+	lng: ""
+};
+var deselectedLog = []
+var selectedShapesLog = [];
+var prevShape = [];
+var nextShape = [];
+var prevLog = [];
+var nextLog = [];
+
+var prevOverlays = [];
+
+
+var dragged = 0;
+var colors = ['#1E90FF', '#FF1493', '#4B0082', '#32CD32', '#FF8C00', '#000000'];
+var selectedColor;
+var colorButtons = {};
+var thicknessValue = 1;
+var opacityValue = 0.4;
+var polyOptions = {
+	fillColor: '#CA4A2F',
+	strokeWeight: thicknessValue,
+	fillOpacity: opacityValue,
+	editable: true,
+	draggable: true,
+	geodesic: false,
+};
+
+var overlays = [];
+var drawingManager;
+var selectedShape;
+var selectedShapes = [];
+
+var map = null;
+
+
+$(document).ready(function() {
+	//Update thickness
+	var thicknessSlider = document.getElementById("thicknessRange");
+	var thicknessSliderOutput = document.getElementById("thicknessRangeVal");
+	thicknessSliderOutput.innerHTML = thicknessSlider.value / 20;
+
+	thicknessSlider.oninput = function () {
+		thicknessSliderOutput.innerHTML = this.value / 20;
+		thicknessValue = this.value / 20;
+		polyOptions.strokeWeight = thicknessValue;
+		setSelectedThickness(thicknessValue);
+	}
+	//Update opacity
+	var opacitySlider = document.getElementById("colourOpacity");
+	var opacitySliderOutput = document.getElementById("opacityRangeVal");
+	opacitySliderOutput.innerHTML = "% " + Math.round(opacitySlider.value);
+
+	opacitySlider.oninput = function () {
+		opacityValue = this.value / 100;
+		polyOptions.fillOpacity = opacityValue;
+		opacitySliderOutput = opacityValue;
+		opacityRangeVal.innerHTML = "% " + Math.round(opacitySliderOutput * 100);
+		setSelectedOpacity(opacityValue);
+	}
+});
+
+
+
+////////////////////////////////////////////////////////////////////////////////////////
+function makeColorButton(color) {
+	var button = document.createElement('span');
+	button.className = 'color-buttons1';
+	button.style.backgroundColor = color;
+	google.maps.event.addDomListener(button, 'click', function () {
+		selectColor(color);
+		setSelectedShapeColor(color);
+	});
+	return button;
+}
+function buildColorPalette() {
+	var colorPalette = document.getElementById('color-palette1');
+	for (var i = 0; i < colors.length; ++i) {
+		var currColor = colors[i];
+		var colorButton = makeColorButton(currColor);
+		colorPalette.appendChild(colorButton);
+		colorButtons[currColor] = colorButton;
+	}
+	selectColor(colors[0]);
+};
+function selectColor(color) {
+	selectedColor = color;
+	for (var i = 0; i < colors.length; ++i) {
+		var currColor = colors[i];
+		colorButtons[currColor].style.border = currColor == color ? '2px solid #789' : '2px solid #fff';
+	}
+
+	// Retrieves the current options from the drawing manager and replaces the
+	// stroke or fill color as appropriate.
+	var polylineOptions = drawingManager.get('polylineOptions');
+	polylineOptions.strokeColor = color;
+	drawingManager.set('polylineOptions', polylineOptions);
+
+	var rectangleOptions = drawingManager.get('rectangleOptions');
+	rectangleOptions.fillColor = color;
+	drawingManager.set('rectangleOptions', rectangleOptions);
+
+	var circleOptions = drawingManager.get('circleOptions');
+	circleOptions.fillColor = color;
+	drawingManager.set('circleOptions', circleOptions);
+
+	var polygonOptions = drawingManager.get('polygonOptions');
+	polygonOptions.fillColor = color;
+	drawingManager.set('polygonOptions', polygonOptions);
+}
+
+function initMap() {
+
+	map = new google.maps.Map(document.getElementById('map'), {
+			center: {
+				lat: -34.397,
+				lng: 150.644
+			},
+			zoom: 2,
+			//mapTypeId: 'map'
+
+		});
+
+	drawingManager = new google.maps.drawing.DrawingManager({
+			drawingMode: google.maps.drawing.OverlayType.RECTANGLE,
+			drawingControl: true,
+			drawingControlOptions: {
+				position: google.maps.ControlPosition.TOP_CENTER,
+				drawingModes: ['marker', 'circle', 'polygon', 'polyline', 'rectangle']
+			},
+			markerOptions: {
+				draggable: true
+			},
+			circleOptions: polyOptions,
+			polylineOptions: polyOptions,
+			polygonOptions: polyOptions,
+			rectangleOptions: polyOptions,
+		});
+
+	drawingManager.setMap(map);
+
+	//overlays.push(event.overlay); // store reference to added overlay
+	google.maps.event.addListener(drawingManager, 'overlaycomplete', function (e) {
+		
+		
+		overlays.push(e.overlay); // store reference to added overlay
+		var newShape = e.overlay;
+		newShape.type = e.type;
+
+		newShapeCreated(e);
+		
+		historyOverlayPush();
+		
+		if (e.type !== google.maps.drawing.OverlayType.MARKER) {
+
+			// Switch back to non-drawing mode after drawing a shape.
+			//drawingManager.setDrawingMode(null);
+
+			// Add an event listener that selects the newly-drawn shape when the user
+			// mouses down on it.
+			google.maps.event.addListener(newShape, 'click', function (e) {
+
+				vertexAndPolyDel(e, newShape);
+				dragFired = false;
+				return;
+
+			});
+
+			//Stores past event information
+			google.maps.event.addListener(newShape, 'dragstart', function () {
+				dragStartFunction(e, newShape);
+			});
+
+			//Store information after the event ends
+			google.maps.event.addListener(newShape, 'dragend', function () {
+				historyOverlayPush();
+				dragEndFunction(e, newShape);
+			});
+
+			//Add an event listener to select a shape if the mouse hovers over it
+			google.maps.event.addListener(newShape, 'mousedown', function (e) {
+				if (drawingManager.drawingMode == null) {
+					setSelection(newShape, e);
+					dragFired = false;
+				}
+			});
+			setSelection(newShape, e);
+		} else {
+			//cLICK EVENT IF A MARKER IS CREATED
+			google.maps.event.addListener(newShape, 'click', function (e) {
+				setSelection(newShape, e);
+			});
+			setSelection(newShape, e);
+		}
+	});
+
+	//Deletes a vertex if clicked on it
+	function vertexAndPolyDel(e, newShape) {
+		var vertex = e.vertex;
+
+		if (e.vertex !== undefined) {
+			if (newShape.type === google.maps.drawing.OverlayType.POLYGON) {
+				var path = newShape.getPaths().getAt(e.path);
+				path.removeAt(e.vertex);
+				if (path.length < 3) {
+					newShape.setMap(null);
+				}
+			}
+			if (newShape.type === google.maps.drawing.OverlayType.POLYLINE) {
+				var path = newShape.getPath();
+				path.removeAt(e.vertex);
+				if (path.length < 2) {
+					newShape.setMap(null);
+				}
+			}
+		}
+	}
+
+	function clearSelection() {
+		if (selectedShape) {
+			if (selectedShape.type !== 'marker') {
+				selectedShape.setEditable(false);
+				if (shiftKeyPressed == false) {
+					for (var i = 0; i < selectedShapes.length; i++) {
+						selectedShapes[i].setEditable(false);
+					}
+					selectedShapes = [];
+				}
+			}
+			selectedShape = null;
+		}
+	}
+	var i = 0;
+
+	//Set selection for the selected overlay
+	function setSelection(shape, e) {
+		if (shape.type !== 'marker') {
+			if (shiftKeyPressed == false) {
+				if (e.vertex == undefined) {
+					clearSelection();
+					shape.setEditable(true);
+				}
+			}
+			if (selectedShapes.includes(shape)) {
+
+				//shape.setEditable(false);
+				const index = selectedShapes.indexOf(shape);
+				selectedShapes.splice(index, 1);
+			} else {
+				shape.setEditable(true);
+				selectedShapes.push(shape);
+			}
+
+			if (debug) {
+				console.log(" len = " + selectedShapes.length);
+			}
+			//Send the values to be updated
+			var thi = shape.strokeWeight;
+			var opa = shape.fillOpacity;
+			var fCol = shape.fillColor;
+			var sCol = shape.strokeColor;
+			updateMenuValues(thi, opa, fCol, sCol);
+
+		} else if (shape.type == 'marker') {
+			clearSelection();
+		}
+
+		selectedShape = shape;
+
+		if (selectionPass == true) {
+
+			selectedShapesLog.push("selected", shiftKeyPressed, selectedShape);
+			nextLog.push(selectedShapesLog);
+			chosen = selectedShape;
+			selectionPass = false
+		}
+
+		var lastItem = nextLog[nextLog.length - 1];
+
+		if (chosen !== selectedShape) {
+			if (dragFired == false) {
+				selectedShapesLog.push("selected", shiftKeyPressed, selectedShape)
+				updateHistory(selectedShapesLog);
+				chosen = selectedShape;
+			}
+		}
+
+		//console.log(prevLog);
+		selectedShapesLog = [];
+	}
+
+	//Clears selection if clicked on the map when shift is not presseed
+	google.maps.event.addListener(map, 'click', function () {
+		if (shiftKeyPressed == false) {
+			clearSelection();
+			if (chosen !== null) {
+				deselectedLog.push("deselected")
+				updateHistory(deselectedLog);
+				deselectedLog = [];
+				chosen = null;
+
+			}
+		}
+	});
+
+	//Setting drawing tool option
+	document.addEventListener('keydown', function () {
+		//if (event.code == 'KeyX' && (event.ctrlKey || event.metaKey))
+		if (event.code == 'Digit0' || event.code == 'Numpad0' || event.code == 'Backquote') {
+			//clearSelection();
+			drawingManager.setDrawingMode(null);
+		} else if (event.code == 'Digit1') {
+			drawingManager.setDrawingMode('marker');
+		} else if (event.code == 'Digit2') {
+			drawingManager.setDrawingMode('circle');
+		} else if (event.code == 'Digit3') {
+			drawingManager.setDrawingMode('polygon');
+		} else if (event.code == 'Digit4') {
+			drawingManager.setDrawingMode('polyline');
+		} else if (event.code == 'Digit5') {
+			drawingManager.setDrawingMode('rectangle');
+		} else if (event.code == 'KeyQ') {
+			polygonGetPath();
+		}
+		//					console.log(event.code);
+	});
+
+	//Sets shift as pressed
+	document.addEventListener('keydown', function () {
+		if (event.code == 'ShiftLeft' || event.code == 'ShiftRight') {
+			shiftKeyPressed = true;
+
+		}
+
+	});
+
+	//Sets shift as unpressed
+	document.addEventListener('keyup', function () {
+		if (event.code == 'ShiftLeft' || event.code == 'ShiftRight') {
+			shiftKeyPressed = false;
+		}
+
+	});
+
+	buildColorPalette();
+}
+//Set selected thickness
+function setSelectedThickness(sWeight) {
+	if (selectedShape) {
+		//selectedShape.set('strokeWeight', sWeight)
+	}
+	if (selectedShapes !== 0) {
+		for (var i = 0; i < selectedShapes.length; i++) {
+			selectedShapes[i].set('strokeWeight', sWeight);
+			//console.log(selectedShapes.length);
+		}
+	}
+}
+
+//Set selected opacity
+function setSelectedOpacity(fOpacity) {
+	if (selectedShape) {
+		//selectedShape.set('fillOpacity', fOpacity)
+	}
+	if (selectedShapes !== 0) {
+		for (var i = 0; i < selectedShapes.length; i++) {
+			selectedShapes[i].set('fillOpacity', fOpacity);
+		}
+	}
+}
+
+//set selected fill colour
+function setSelectedShapeColor(color) {
+	if (selectedShapes !== 0) {
+		for (var i = 0; i < selectedShapes.length; i++) {
+			selectedShapes[i].set('fillColor', color);
+			selectedShapes[i].set('strokeColor', color);
+		}
+	}
+}
+
+function updateMenuValues(thi, opa, fCol, sCol) {
+
+	//Update thickness slider and value on the settings menu
+	var thicknessSliderOutput = document.getElementById("thicknessRangeVal");
+	thicknessSliderOutput.innerHTML = thi;
+	document.getElementById("thicknessRange").value = thi * 20;
+
+	//Update the opacity slider and value on the settings menu
+	var opacitySliderOutput = document.getElementById("opacityRangeVal");
+	opacitySliderOutput.innerHTML = "% " + opa * 100;
+	document.getElementById("colourOpacity").value = opa * 100;
+
+	if (drawingManager.drawingMode == null) {
+		selectColor(fCol);
+	}
+}
+
+function undoMovement() {
+	console.log("*** undoMovement called");
+	for (var i = 0; i < overlays.length; i++) {
+		overlays[i].setMap(null);
+
+	}
+	
+	overlays = [];
+	
+	var prev_overlay = prevOverlays.pop();
+	
+	for (var i = 0; i < prev_overlay.length; i++) {
+		overlays[i] = prev_overlay[i];
+		overlays[i].setMap(map);
+	}
+	
+}
+
+function undoMovementDragSelection() {
+	var lastItem = prevLog[prevLog.length - 1];
+
+	//If history array is not empty
+	if (prevLog.length !== 0) {
+		if (lastItem[0] = "dragStart") {
+			//If the array has more than one index (polygons and polylines)
+			if (lastItem[1] == ("polygon") || lastItem[1] == ("polyline")) {
+				nextLog.push(lastItem);
+				selectedShape.setPath(lastItem[2]);
+
+				//If the array has only one index(rectangles and circles)
+			} else {
+				nextLog.push(lastItem);
+				selectedShape.setBounds(lastItem[2]);
+			}
+		} else if (lastItem[0] = "selected") {}
+		else if (lastItem[0] = "deselected") {}
+		undoPressed = false;
+		undoPressed = 0;
+		prevLog.pop();
+	}
+
+}
+
+function redoMovement() {
+
+	var lastItem = nextLog[nextLog.length - 1];
+	var secondToLastItem = nextLog[nextLog.length - 2];
+	var correctIndex;
+
+	if (undoPressed >= 1) {
+		correctIndex = lastItem;
+	} else {
+		correctIndex = secondToLastItem;
+		undoPressed++;
+	}
+
+	//If the history log is not empty
+	if (nextLog.length > 1) {
+		prevLog.push(lastItem);
+
+		//If undo has been pressed
+
+		if (lastItem[1] == ("polygon") || lastItem[1] == ("polyline")) {
+			selectedShape.setPath(correctIndex[2]);
+		} else {
+			selectedShape.setBounds(correctIndex[2]);
+		}
+
+		undoPressed = false;
+		redoPressed = true;
+		nextLog.pop();
+	}
+}
+
+function dragStartFunction(e, selectedShape) {
+	var newShape = e.overlay;
+	newShape.type = e.type;
+	if (selectedShape) {
+		var polyG = newShape.type === google.maps.drawing.OverlayType.POLYLINE;
+		var polyL = newShape.type === google.maps.drawing.OverlayType.POLYGON;
+
+		if (polyL || polyG) {
+			var latLngi = []
+			var lati,
+			lngi;
+			for (var i = 0; i < selectedShape.getPath().length; i++) {
+				lati = selectedShape.getPath().getAt(i).lat();
+				lngi = selectedShape.getPath().getAt(i).lng();
+				//console.log("Vertex number",i, "'s latitude is", lati, "and longitude is", lngi);
+				prevVertex = {
+					lat: lati,
+					lng: lngi
+				};
+				latLngi.push(prevVertex);
+			}
+			prevShape.push("dragStart", selectedShape.type, latLngi);
+		} else {
+			prevEdge = {
+				east: selectedShape.getBounds().ea.l,
+				north: selectedShape.getBounds().la.l,
+				south: selectedShape.getBounds().la.j,
+				west: selectedShape.getBounds().ea.j
+			}
+			prevShape.push("dragStart", selectedShape.type, prevEdge);
+		}
+
+		var lastItem = nextLog[nextLog.length - 1];
+		if (lastItem[0] !== "dragEnd") {
+			prevLog.push(nextLog[nextLog.length - 1]);
+		}
+
+		prevLog.push(prevShape);
+		prevShape = [];
+		nextLog = [];
+		chosen = selectedShape;
+		dragFired = true;
+	}
+}
+
+function dragEndFunction(e, newShape) {
+
+	var newShape = e.overlay;
+	newShape.type = e.type;
+	if (selectedShape) {
+		var polyG = newShape.type === google.maps.drawing.OverlayType.POLYLINE;
+		var polyL = newShape.type === google.maps.drawing.OverlayType.POLYGON;
+
+		if (polyL || polyG) {
+
+			var latLngi = []
+			var lati,
+			lngi;
+
+			for (var i = 0; i < selectedShape.getPath().length; i++) {
+				lati = selectedShape.getPath().getAt(i).lat();
+				lngi = selectedShape.getPath().getAt(i).lng();
+				nextVertex = {
+					lat: lati,
+					lng: lngi
+				};
+				latLngi.push(nextVertex);
+			}
+			nextShape.push("dragEnd", selectedShape.type, latLngi);
+		} else {
+
+			nextEdge.east = selectedShape.getBounds().ea.l;
+			nextEdge.north = selectedShape.getBounds().la.l;
+			nextEdge.south = selectedShape.getBounds().la.j;
+			nextEdge.west = selectedShape.getBounds().ea.j;
+
+			nextShape.push("dragEnd", selectedShape.type, nextEdge);
+		}
+	}
+	for (var i = 0; i < prevLog.length; i++) {
+		if (prevLog[i][0] == "dragEnd") {
+			const index = i;
+			prevLog.splice(index, 1);
+		}
+	}
+	nextLog.push(nextShape);
+	nextShape = [];
+	chosen = selectedShape;
+}
+
+function updateHistory(eventArray) {
+	var lastItem = nextLog[nextLog.length - 1];
+	if (nextLog.length > 0) {
+		prevLog.push(lastItem);
+	}
+	nextLog = [];
+	nextLog.push(eventArray);
+	eventArray = [];
+	dragFired = false;
+
+}
+
+function newShapeCreated(e) {
+	//nextLog
+}
+
+function polygonGetPath() {
+	console.log(nextLog);
+	console.log(prevLog);
+
+}
+
+function deleteSelectedShape() {
+	for (var i = 0; i < selectedShapes.length; i++) {
+		selectedShapes[i].setMap(null);
+	}
+	selectedShapes = [];
+}
+
+function deleteAllShape() {
+	for (var i = 0; i < overlays.length; i++) {
+		overlays[i].setMap(null);
+
+	}
+	overlays = [];
+}
+
+function historyOverlayPush()
+{
+	//console.log("historyOverlayPush()");
+	//var overlays_copy = [];
+	//for (var i = 0; i<overlays.length; i++) {
+	//	overlays_copy[i] = new google.maps.Rectangle(overlays[i]);
+	//}
+	//var overlay_copy = JSON.parse(JSON.stringify(overlays));
+	//prevOverlays.push(overlays_copy); 
+	//
+	//prevOverlays.push(overlays.slice()); // shallow copy !!!
+	
+	console.log("historyOverlayPush()");
+	var overlays_copy = [];
+	for (var i = 0; i<overlays.length; i++) {
+		
+		overlays_copy[i] = overlays[i];
+		
+	}
+	overlays_copy_obj = overlays_copy;
+	console.log(overlays_copy_obj);
+	console.log(overlays);
+	console.log(prevOverlays);
+	//console.log(JSON.stringify(overlays_copy_obj));
+	
+	var overlay_copy = overlays;
+	prevOverlays.push(overlays_copy_obj); 
+	
+	//prevOverlays.push(overlays.slice()); // shallow copy !!!
+	
+	
+}
Index: /gs3-extensions/map-editor/DrawingManager/checkpt22/shortcuts.js
===================================================================
--- /gs3-extensions/map-editor/DrawingManager/checkpt22/shortcuts.js	(revision 32709)
+++ /gs3-extensions/map-editor/DrawingManager/checkpt22/shortcuts.js	(revision 32709)
@@ -0,0 +1,223 @@
+/**
+ * http://www.openjs.com/scripts/events/keyboard_shortcuts/
+ * Version : 2.01.B
+ * By Binny V A
+ * License : BSD
+ */
+shortcut = {
+	'all_shortcuts':{},//All the shortcuts are stored in this array
+	'add': function(shortcut_combination,callback,opt) {
+		//Provide a set of default options
+		var default_options = {
+			'type':'keydown',
+			'propagate':false,
+			'disable_in_input':false,
+			'target':document,
+			'keycode':false
+		}
+		if(!opt) opt = default_options;
+		else {
+			for(var dfo in default_options) {
+				if(typeof opt[dfo] == 'undefined') opt[dfo] = default_options[dfo];
+			}
+		}
+
+		var ele = opt.target;
+		if(typeof opt.target == 'string') ele = document.getElementById(opt.target);
+		var ths = this;
+		shortcut_combination = shortcut_combination.toLowerCase();
+
+		//The function to be called at keypress
+		var func = function(e) {
+			e = e || window.event;
+			
+			if(opt['disable_in_input']) { //Don't enable shortcut keys in Input, Textarea fields
+				var element;
+				if(e.target) element=e.target;
+				else if(e.srcElement) element=e.srcElement;
+				if(element.nodeType==3) element=element.parentNode;
+
+				if(element.tagName == 'INPUT' || element.tagName == 'TEXTAREA') return;
+			}
+	
+			//Find Which key is pressed
+			if (e.keyCode) code = e.keyCode;
+			else if (e.which) code = e.which;
+			var character = String.fromCharCode(code).toLowerCase();
+			
+			if(code == 188) character=","; //If the user presses , when the type is onkeydown
+			if(code == 190) character="."; //If the user presses , when the type is onkeydown
+
+			var keys = shortcut_combination.split("+");
+			//Key Pressed - counts the number of valid keypresses - if it is same as the number of keys, the shortcut function is invoked
+			var kp = 0;
+			
+			//Work around for stupid Shift key bug created by using lowercase - as a result the shift+num combination was broken
+			var shift_nums = {
+				"`":"~",
+				"1":"!",
+				"2":"@",
+				"3":"#",
+				"4":"$",
+				"5":"%",
+				"6":"^",
+				"7":"&",
+				"8":"*",
+				"9":"(",
+				"0":")",
+				"-":"_",
+				"=":"+",
+				";":":",
+				"'":"\"",
+				",":"<",
+				".":">",
+				"/":"?",
+				"\\":"|"
+			}
+			//Special Keys - and their codes
+			var special_keys = {
+				'esc':27,
+				'escape':27,
+				'tab':9,
+				'space':32,
+				'return':13,
+				'enter':13,
+				'backspace':8,
+	
+				'scrolllock':145,
+				'scroll_lock':145,
+				'scroll':145,
+				'capslock':20,
+				'caps_lock':20,
+				'caps':20,
+				'numlock':144,
+				'num_lock':144,
+				'num':144,
+				
+				'pause':19,
+				'break':19,
+				
+				'insert':45,
+				'home':36,
+				'delete':46,
+				'end':35,
+				
+				'pageup':33,
+				'page_up':33,
+				'pu':33,
+	
+				'pagedown':34,
+				'page_down':34,
+				'pd':34,
+	
+				'left':37,
+				'up':38,
+				'right':39,
+				'down':40,
+	
+				'f1':112,
+				'f2':113,
+				'f3':114,
+				'f4':115,
+				'f5':116,
+				'f6':117,
+				'f7':118,
+				'f8':119,
+				'f9':120,
+				'f10':121,
+				'f11':122,
+				'f12':123
+			}
+	
+			var modifiers = { 
+				shift: { wanted:false, pressed:false},
+				ctrl : { wanted:false, pressed:false},
+				alt  : { wanted:false, pressed:false},
+				meta : { wanted:false, pressed:false}	//Meta is Mac specific
+			};
+                        
+			if(e.ctrlKey)	modifiers.ctrl.pressed = true;
+			if(e.shiftKey)	modifiers.shift.pressed = true;
+			if(e.altKey)	modifiers.alt.pressed = true;
+			if(e.metaKey)   modifiers.meta.pressed = true;
+                        
+			for(var i=0; k=keys[i],i<keys.length; i++) {
+				//Modifiers
+				if(k == 'ctrl' || k == 'control') {
+					kp++;
+					modifiers.ctrl.wanted = true;
+
+				} else if(k == 'shift') {
+					kp++;
+					modifiers.shift.wanted = true;
+
+				} else if(k == 'alt') {
+					kp++;
+					modifiers.alt.wanted = true;
+				} else if(k == 'meta') {
+					kp++;
+					modifiers.meta.wanted = true;
+				} else if(k.length > 1) { //If it is a special key
+					if(special_keys[k] == code) kp++;
+					
+				} else if(opt['keycode']) {
+					if(opt['keycode'] == code) kp++;
+
+				} else { //The special keys did not match
+					if(character == k) kp++;
+					else {
+						if(shift_nums[character] && e.shiftKey) { //Stupid Shift key bug created by using lowercase
+							character = shift_nums[character]; 
+							if(character == k) kp++;
+						}
+					}
+				}
+			}
+			
+			if(kp == keys.length && 
+						modifiers.ctrl.pressed == modifiers.ctrl.wanted &&
+						modifiers.shift.pressed == modifiers.shift.wanted &&
+						modifiers.alt.pressed == modifiers.alt.wanted &&
+						modifiers.meta.pressed == modifiers.meta.wanted) {
+				callback(e);
+	
+				if(!opt['propagate']) { //Stop the event
+					//e.cancelBubble is supported by IE - this will kill the bubbling process.
+					e.cancelBubble = true;
+					e.returnValue = false;
+	
+					//e.stopPropagation works in Firefox.
+					if (e.stopPropagation) {
+						e.stopPropagation();
+						e.preventDefault();
+					}
+					return false;
+				}
+			}
+		}
+		this.all_shortcuts[shortcut_combination] = {
+			'callback':func, 
+			'target':ele, 
+			'event': opt['type']
+		};
+		//Attach the function with the event
+		if(ele.addEventListener) ele.addEventListener(opt['type'], func, false);
+		else if(ele.attachEvent) ele.attachEvent('on'+opt['type'], func);
+		else ele['on'+opt['type']] = func;
+	},
+
+	//Remove the shortcut - just specify the shortcut and I will remove the binding
+	'remove':function(shortcut_combination) {
+		shortcut_combination = shortcut_combination.toLowerCase();
+		var binding = this.all_shortcuts[shortcut_combination];
+		delete(this.all_shortcuts[shortcut_combination])
+		if(!binding) return;
+		var type = binding['event'];
+		var ele = binding['target'];
+		var callback = binding['callback'];
+
+		if(ele.detachEvent) ele.detachEvent('on'+type, callback);
+		else if(ele.removeEventListener) ele.removeEventListener(type, callback, false);
+		else ele['on'+type] = false;
+	}
+}
Index: /gs3-extensions/map-editor/DrawingManager/index.css
===================================================================
--- /gs3-extensions/map-editor/DrawingManager/index.css	(revision 32709)
+++ /gs3-extensions/map-editor/DrawingManager/index.css	(revision 32709)
@@ -0,0 +1,70 @@
+/* Always set the map height explicitly to define the size of the div
+* element that contains the map. */
+#map {
+	height: 83%;
+	width: 90;
+	float: bottom;
+	clear: both;
+}
+
+  /* Optional: Makes the sample page fill the window. */
+  html, body {
+	height: 100%;
+	width: 99%;
+	margin: 0;
+	padding: 0;
+
+  }
+  
+  #DeleteButtons{
+  display: inline-block;
+  float: left;
+  padding-left: 10px;
+  padding-top: 5px;
+  width: 100%
+
+  }
+  
+  #LineThickness{
+  display: inline-block;
+  float: left;
+  padding-left: 10px;
+  padding-top: 5px;
+
+  }
+  
+  #ColourOpacity{
+  display: inline-block;
+  float: left;
+  padding-left: 10px;
+  padding-top: 5px;
+
+  }
+  
+  #buttons3{
+  display: inline-block;
+  float: left;
+  padding-left: 10px;
+  padding-top: 5px;
+
+  }	  
+  
+  #FillColour {
+  display: inline-block;
+  float: left;
+  padding-left: 10px;
+  padding-top: 5px;
+  }
+  
+  #color-palette1 {
+  clear: both;
+  }
+  
+  .color-buttons1 {
+  width: 14px;
+  height: 14px;
+  font-size: 0;
+  margin: 2px;
+  float: left;
+  cursor: pointer;
+  }
Index: /gs3-extensions/map-editor/DrawingManager/index.html
===================================================================
--- /gs3-extensions/map-editor/DrawingManager/index.html	(revision 32709)
+++ /gs3-extensions/map-editor/DrawingManager/index.html	(revision 32709)
@@ -0,0 +1,47 @@
+<!DOCTYPE html>
+<html>
+  <head>
+	<title>Drawing Tools</title>
+	<meta name="viewport" content="initial-scale=1.0, user-scalable=no">
+	<meta charset="utf-8">
+
+	<script src="https://code.jquery.com/jquery-3.3.1.js"></script>
+	<script src="index.js"></script>	
+	<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyBzunGwIF2OwsfrOkIC_8bhh0OPGZXo52Y&libraries=drawing&callback=initMap" async defer></script>
+	
+    <link rel="stylesheet" type="text/css" href="index.css">
+
+  </head>
+  <body>
+	<div id = "DeleteButtons">
+	<button onclick="deleteAllShape()" accesskey="c">Clear All</button>
+	<button onclick="deleteSelectedShape()" accesskey="b">Delete Selected</button>
+	<button onclick="polygonGetPath()" accesskey="q">Get Path</button>
+	<button onclick="undoMovement()" accesskey="n">Undo</button>
+	<button onclick="redoMovement()" accesskey="n">Redo</button>
+	
+	</div>
+	
+	<div id = "LineThickness">
+	<p>Line thickness: <input type="range" min="20" max="100" value="1" class="slider" id="thicknessRange"> </p>
+	<p>Value: <span id="thicknessRangeVal"></span></p>
+	</div>	
+	
+	<div id = "ColourOpacity">
+	<p>Colour opacity: <input type="range" min="10" max="100" value="40" class="slider" id="colourOpacity"> </p>
+	<p>Value: <span id="opacityRangeVal"></span></p>
+	</div>
+	
+
+
+	<div id="FillColour">
+     <p> Fill Colour:</p> <div id="color-palette1"></div> 
+	</div>
+
+	
+	
+	<div id="map"></div>
+	
+
+  </body>
+</html>
Index: /gs3-extensions/map-editor/DrawingManager/index.js
===================================================================
--- /gs3-extensions/map-editor/DrawingManager/index.js	(revision 32709)
+++ /gs3-extensions/map-editor/DrawingManager/index.js	(revision 32709)
@@ -0,0 +1,658 @@
+var debug = false;
+var redoPressed = false;
+var undoPressed = 0;
+var shiftKeyPressed = false;
+var dragFired = false;
+var selectionPass = true;
+var chosen;
+
+var overlays_copy_obj = {};
+
+var prevEdge = {
+	east: "",
+	north: "",
+	south: "",
+	west: ""
+}
+var nextEdge = {
+	east: "",
+	north: "",
+	south: "",
+	west: ""
+}
+var prevVertex = {
+	lat: "",
+	lng: ""
+};
+var nextVertex = {
+	lat: "",
+	lng: ""
+};
+var deselectedLog = []
+var selectedShapesLog = [];
+var prevShape = [];
+var nextShape = [];
+var prevLog = [];
+var nextLog = [];
+
+var prevOverlays = [];
+
+
+var dragged = 0;
+var colors = ['#1E90FF', '#FF1493', '#4B0082', '#32CD32', '#FF8C00', '#000000'];
+var selectedColor;
+var colorButtons = {};
+var thicknessValue = 1;
+var opacityValue = 0.4;
+var polyOptions = {
+	fillColor: '#CA4A2F',
+	strokeWeight: thicknessValue,
+	fillOpacity: opacityValue,
+	editable: true,
+	draggable: true,
+	geodesic: false,
+};
+
+var overlays = [];
+var drawingManager;
+var selectedShape;
+var selectedShapes = [];
+
+var map = null;
+
+
+$(document).ready(function() {
+	//Update thickness
+	var thicknessSlider = document.getElementById("thicknessRange");
+	var thicknessSliderOutput = document.getElementById("thicknessRangeVal");
+	thicknessSliderOutput.innerHTML = thicknessSlider.value / 20;
+
+	thicknessSlider.oninput = function () {
+		thicknessSliderOutput.innerHTML = this.value / 20;
+		thicknessValue = this.value / 20;
+		polyOptions.strokeWeight = thicknessValue;
+		setSelectedThickness(thicknessValue);
+	}
+	//Update opacity
+	var opacitySlider = document.getElementById("colourOpacity");
+	var opacitySliderOutput = document.getElementById("opacityRangeVal");
+	opacitySliderOutput.innerHTML = "% " + Math.round(opacitySlider.value);
+
+	opacitySlider.oninput = function () {
+		opacityValue = this.value / 100;
+		polyOptions.fillOpacity = opacityValue;
+		opacitySliderOutput = opacityValue;
+		opacityRangeVal.innerHTML = "% " + Math.round(opacitySliderOutput * 100);
+		setSelectedOpacity(opacityValue);
+	}
+});
+
+
+
+////////////////////////////////////////////////////////////////////////////////////////
+function makeColorButton(color) {
+	var button = document.createElement('span');
+	button.className = 'color-buttons1';
+	button.style.backgroundColor = color;
+	google.maps.event.addDomListener(button, 'click', function () {
+		selectColor(color);
+		setSelectedShapeColor(color);
+	});
+	return button;
+}
+function buildColorPalette() {
+	var colorPalette = document.getElementById('color-palette1');
+	for (var i = 0; i < colors.length; ++i) {
+		var currColor = colors[i];
+		var colorButton = makeColorButton(currColor);
+		colorPalette.appendChild(colorButton);
+		colorButtons[currColor] = colorButton;
+	}
+	selectColor(colors[0]);
+};
+function selectColor(color) {
+	selectedColor = color;
+	for (var i = 0; i < colors.length; ++i) {
+		var currColor = colors[i];
+		colorButtons[currColor].style.border = currColor == color ? '2px solid #789' : '2px solid #fff';
+	}
+
+	// Retrieves the current options from the drawing manager and replaces the
+	// stroke or fill color as appropriate.
+	var polylineOptions = drawingManager.get('polylineOptions');
+	polylineOptions.strokeColor = color;
+	drawingManager.set('polylineOptions', polylineOptions);
+
+	var rectangleOptions = drawingManager.get('rectangleOptions');
+	rectangleOptions.fillColor = color;
+	drawingManager.set('rectangleOptions', rectangleOptions);
+
+	var circleOptions = drawingManager.get('circleOptions');
+	circleOptions.fillColor = color;
+	drawingManager.set('circleOptions', circleOptions);
+
+	var polygonOptions = drawingManager.get('polygonOptions');
+	polygonOptions.fillColor = color;
+	drawingManager.set('polygonOptions', polygonOptions);
+}
+
+function initMap() {
+
+	map = new google.maps.Map(document.getElementById('map'), {
+			center: {
+				lat: -34.397,
+				lng: 150.644
+			},
+			zoom: 2,
+			//mapTypeId: 'map'
+
+		});
+
+	drawingManager = new google.maps.drawing.DrawingManager({
+			drawingMode: google.maps.drawing.OverlayType.RECTANGLE,
+			drawingControl: true,
+			drawingControlOptions: {
+				position: google.maps.ControlPosition.TOP_CENTER,
+				drawingModes: ['marker', 'circle', 'polygon', 'polyline', 'rectangle']
+			},
+			markerOptions: {
+				draggable: true
+			},
+			circleOptions: polyOptions,
+			polylineOptions: polyOptions,
+			polygonOptions: polyOptions,
+			rectangleOptions: polyOptions,
+		});
+
+	drawingManager.setMap(map);
+
+	//overlays.push(event.overlay); // store reference to added overlay
+	google.maps.event.addListener(drawingManager, 'overlaycomplete', function (e) {
+		
+		
+		overlays.push(e.overlay); // store reference to added overlay
+		var newShape = e.overlay;
+		newShape.type = e.type;
+
+		newShapeCreated(e);
+		
+		historyOverlayPush();
+		
+		if (e.type !== google.maps.drawing.OverlayType.MARKER) {
+
+			// Switch back to non-drawing mode after drawing a shape.
+			//drawingManager.setDrawingMode(null);
+
+			// Add an event listener that selects the newly-drawn shape when the user
+			// mouses down on it.
+			google.maps.event.addListener(newShape, 'click', function (e) {
+
+				vertexAndPolyDel(e, newShape);
+				dragFired = false;
+				return;
+
+			});
+
+			//Stores past event information
+			google.maps.event.addListener(newShape, 'dragstart', function () {
+				dragStartFunction(e, newShape);
+			});
+
+			//Store information after the event ends
+			google.maps.event.addListener(newShape, 'dragend', function () {
+				historyOverlayPush();
+				dragEndFunction(e, newShape);
+			});
+
+			//Add an event listener to select a shape if the mouse hovers over it
+			google.maps.event.addListener(newShape, 'mousedown', function (e) {
+				if (drawingManager.drawingMode == null) {
+					setSelection(newShape, e);
+					dragFired = false;
+				}
+			});
+			setSelection(newShape, e);
+		} else {
+			//cLICK EVENT IF A MARKER IS CREATED
+			google.maps.event.addListener(newShape, 'click', function (e) {
+				setSelection(newShape, e);
+			});
+			setSelection(newShape, e);
+		}
+	});
+
+	//Deletes a vertex if clicked on it
+	function vertexAndPolyDel(e, newShape) {
+		var vertex = e.vertex;
+
+		if (e.vertex !== undefined) {
+			if (newShape.type === google.maps.drawing.OverlayType.POLYGON) {
+				var path = newShape.getPaths().getAt(e.path);
+				path.removeAt(e.vertex);
+				if (path.length < 3) {
+					newShape.setMap(null);
+				}
+			}
+			if (newShape.type === google.maps.drawing.OverlayType.POLYLINE) {
+				var path = newShape.getPath();
+				path.removeAt(e.vertex);
+				if (path.length < 2) {
+					newShape.setMap(null);
+				}
+			}
+		}
+	}
+
+	function clearSelection() {
+		if (selectedShape) {
+			if (selectedShape.type !== 'marker') {
+				selectedShape.setEditable(false);
+				if (shiftKeyPressed == false) {
+					for (var i = 0; i < selectedShapes.length; i++) {
+						selectedShapes[i].setEditable(false);
+					}
+					selectedShapes = [];
+				}
+			}
+			selectedShape = null;
+		}
+	}
+	var i = 0;
+
+	//Set selection for the selected overlay
+	function setSelection(shape, e) {
+		if (shape.type !== 'marker') {
+			if (shiftKeyPressed == false) {
+				if (e.vertex == undefined) {
+					clearSelection();
+					shape.setEditable(true);
+				}
+			}
+			if (selectedShapes.includes(shape)) {
+
+				//shape.setEditable(false);
+				const index = selectedShapes.indexOf(shape);
+				selectedShapes.splice(index, 1);
+			} else {
+				shape.setEditable(true);
+				selectedShapes.push(shape);
+			}
+
+			if (debug) {
+				console.log(" len = " + selectedShapes.length);
+			}
+			//Send the values to be updated
+			var thi = shape.strokeWeight;
+			var opa = shape.fillOpacity;
+			var fCol = shape.fillColor;
+			var sCol = shape.strokeColor;
+			updateMenuValues(thi, opa, fCol, sCol);
+
+		} else if (shape.type == 'marker') {
+			clearSelection();
+		}
+
+		selectedShape = shape;
+
+		if (selectionPass == true) {
+
+			selectedShapesLog.push("selected", shiftKeyPressed, selectedShape);
+			nextLog.push(selectedShapesLog);
+			chosen = selectedShape;
+			selectionPass = false
+		}
+
+		var lastItem = nextLog[nextLog.length - 1];
+
+		if (chosen !== selectedShape) {
+			if (dragFired == false) {
+				selectedShapesLog.push("selected", shiftKeyPressed, selectedShape)
+				updateHistory(selectedShapesLog);
+				chosen = selectedShape;
+			}
+		}
+
+		//console.log(prevLog);
+		selectedShapesLog = [];
+	}
+
+	//Clears selection if clicked on the map when shift is not presseed
+	google.maps.event.addListener(map, 'click', function () {
+		if (shiftKeyPressed == false) {
+			clearSelection();
+			if (chosen !== null) {
+				deselectedLog.push("deselected")
+				updateHistory(deselectedLog);
+				deselectedLog = [];
+				chosen = null;
+
+			}
+		}
+	});
+
+	//Setting drawing tool option
+	document.addEventListener('keydown', function () {
+		//if (event.code == 'KeyX' && (event.ctrlKey || event.metaKey))
+		if (event.code == 'Digit0' || event.code == 'Numpad0' || event.code == 'Backquote') {
+			//clearSelection();
+			drawingManager.setDrawingMode(null);
+		} else if (event.code == 'Digit1') {
+			drawingManager.setDrawingMode('marker');
+		} else if (event.code == 'Digit2') {
+			drawingManager.setDrawingMode('circle');
+		} else if (event.code == 'Digit3') {
+			drawingManager.setDrawingMode('polygon');
+		} else if (event.code == 'Digit4') {
+			drawingManager.setDrawingMode('polyline');
+		} else if (event.code == 'Digit5') {
+			drawingManager.setDrawingMode('rectangle');
+		} else if (event.code == 'KeyQ') {
+			polygonGetPath();
+		}
+		//					console.log(event.code);
+	});
+
+	//Sets shift as pressed
+	document.addEventListener('keydown', function () {
+		if (event.code == 'ShiftLeft' || event.code == 'ShiftRight') {
+			shiftKeyPressed = true;
+
+		}
+
+	});
+
+	//Sets shift as unpressed
+	document.addEventListener('keyup', function () {
+		if (event.code == 'ShiftLeft' || event.code == 'ShiftRight') {
+			shiftKeyPressed = false;
+		}
+
+	});
+
+	buildColorPalette();
+}
+//Set selected thickness
+function setSelectedThickness(sWeight) {
+	if (selectedShape) {
+		//selectedShape.set('strokeWeight', sWeight)
+	}
+	if (selectedShapes !== 0) {
+		for (var i = 0; i < selectedShapes.length; i++) {
+			selectedShapes[i].set('strokeWeight', sWeight);
+			//console.log(selectedShapes.length);
+		}
+	}
+}
+
+//Set selected opacity
+function setSelectedOpacity(fOpacity) {
+	if (selectedShape) {
+		//selectedShape.set('fillOpacity', fOpacity)
+	}
+	if (selectedShapes !== 0) {
+		for (var i = 0; i < selectedShapes.length; i++) {
+			selectedShapes[i].set('fillOpacity', fOpacity);
+		}
+	}
+}
+
+//set selected fill colour
+function setSelectedShapeColor(color) {
+	if (selectedShapes !== 0) {
+		for (var i = 0; i < selectedShapes.length; i++) {
+			selectedShapes[i].set('fillColor', color);
+			selectedShapes[i].set('strokeColor', color);
+		}
+	}
+}
+
+function updateMenuValues(thi, opa, fCol, sCol) {
+
+	//Update thickness slider and value on the settings menu
+	var thicknessSliderOutput = document.getElementById("thicknessRangeVal");
+	thicknessSliderOutput.innerHTML = thi;
+	document.getElementById("thicknessRange").value = thi * 20;
+
+	//Update the opacity slider and value on the settings menu
+	var opacitySliderOutput = document.getElementById("opacityRangeVal");
+	opacitySliderOutput.innerHTML = "% " + opa * 100;
+	document.getElementById("colourOpacity").value = opa * 100;
+
+	if (drawingManager.drawingMode == null) {
+		selectColor(fCol);
+	}
+}
+
+function undoMovement() {
+	console.log("*** undoMovement called");
+	for (var i = 0; i < overlays.length; i++) {
+		overlays[i].setMap(null);
+
+	}
+	
+	overlays = [];
+	
+	var prev_overlay = prevOverlays.pop();
+	
+	for (var i = 0; i < prev_overlay.length; i++) {
+		overlays[i] = prev_overlay[i];
+		overlays[i].setMap(map);
+	}
+	
+}
+
+function undoMovementDragSelection() {
+	var lastItem = prevLog[prevLog.length - 1];
+
+	//If history array is not empty
+	if (prevLog.length !== 0) {
+		if (lastItem[0] = "dragStart") {
+			//If the array has more than one index (polygons and polylines)
+			if (lastItem[1] == ("polygon") || lastItem[1] == ("polyline")) {
+				nextLog.push(lastItem);
+				selectedShape.setPath(lastItem[2]);
+
+				//If the array has only one index(rectangles and circles)
+			} else {
+				nextLog.push(lastItem);
+				selectedShape.setBounds(lastItem[2]);
+			}
+		} else if (lastItem[0] = "selected") {}
+		else if (lastItem[0] = "deselected") {}
+		undoPressed = false;
+		undoPressed = 0;
+		prevLog.pop();
+	}
+
+}
+
+function redoMovement() {
+
+	var lastItem = nextLog[nextLog.length - 1];
+	var secondToLastItem = nextLog[nextLog.length - 2];
+	var correctIndex;
+
+	if (undoPressed >= 1) {
+		correctIndex = lastItem;
+	} else {
+		correctIndex = secondToLastItem;
+		undoPressed++;
+	}
+
+	//If the history log is not empty
+	if (nextLog.length > 1) {
+		prevLog.push(lastItem);
+
+		//If undo has been pressed
+
+		if (lastItem[1] == ("polygon") || lastItem[1] == ("polyline")) {
+			selectedShape.setPath(correctIndex[2]);
+		} else {
+			selectedShape.setBounds(correctIndex[2]);
+		}
+
+		undoPressed = false;
+		redoPressed = true;
+		nextLog.pop();
+	}
+}
+
+function dragStartFunction(e, selectedShape) {
+	var newShape = e.overlay;
+	newShape.type = e.type;
+	if (selectedShape) {
+		var polyG = newShape.type === google.maps.drawing.OverlayType.POLYLINE;
+		var polyL = newShape.type === google.maps.drawing.OverlayType.POLYGON;
+
+		if (polyL || polyG) {
+			var latLngi = []
+			var lati,
+			lngi;
+			for (var i = 0; i < selectedShape.getPath().length; i++) {
+				lati = selectedShape.getPath().getAt(i).lat();
+				lngi = selectedShape.getPath().getAt(i).lng();
+				//console.log("Vertex number",i, "'s latitude is", lati, "and longitude is", lngi);
+				prevVertex = {
+					lat: lati,
+					lng: lngi
+				};
+				latLngi.push(prevVertex);
+			}
+			prevShape.push("dragStart", selectedShape.type, latLngi);
+		} else {
+			prevEdge = {
+				east: selectedShape.getBounds().ea.l,
+				north: selectedShape.getBounds().la.l,
+				south: selectedShape.getBounds().la.j,
+				west: selectedShape.getBounds().ea.j
+			}
+			prevShape.push("dragStart", selectedShape.type, prevEdge);
+		}
+
+		var lastItem = nextLog[nextLog.length - 1];
+		if (lastItem[0] !== "dragEnd") {
+			prevLog.push(nextLog[nextLog.length - 1]);
+		}
+
+		prevLog.push(prevShape);
+		prevShape = [];
+		nextLog = [];
+		chosen = selectedShape;
+		dragFired = true;
+	}
+}
+
+function dragEndFunction(e, newShape) {
+
+	var newShape = e.overlay;
+	newShape.type = e.type;
+	if (selectedShape) {
+		var polyG = newShape.type === google.maps.drawing.OverlayType.POLYLINE;
+		var polyL = newShape.type === google.maps.drawing.OverlayType.POLYGON;
+
+		if (polyL || polyG) {
+
+			var latLngi = []
+			var lati,
+			lngi;
+
+			for (var i = 0; i < selectedShape.getPath().length; i++) {
+				lati = selectedShape.getPath().getAt(i).lat();
+				lngi = selectedShape.getPath().getAt(i).lng();
+				nextVertex = {
+					lat: lati,
+					lng: lngi
+				};
+				latLngi.push(nextVertex);
+			}
+			nextShape.push("dragEnd", selectedShape.type, latLngi);
+		} else {
+
+			nextEdge.east = selectedShape.getBounds().ea.l;
+			nextEdge.north = selectedShape.getBounds().la.l;
+			nextEdge.south = selectedShape.getBounds().la.j;
+			nextEdge.west = selectedShape.getBounds().ea.j;
+
+			nextShape.push("dragEnd", selectedShape.type, nextEdge);
+		}
+	}
+	for (var i = 0; i < prevLog.length; i++) {
+		if (prevLog[i][0] == "dragEnd") {
+			const index = i;
+			prevLog.splice(index, 1);
+		}
+	}
+	nextLog.push(nextShape);
+	nextShape = [];
+	chosen = selectedShape;
+}
+
+function updateHistory(eventArray) {
+	var lastItem = nextLog[nextLog.length - 1];
+	if (nextLog.length > 0) {
+		prevLog.push(lastItem);
+	}
+	nextLog = [];
+	nextLog.push(eventArray);
+	eventArray = [];
+	dragFired = false;
+
+}
+
+function newShapeCreated(e) {
+	//nextLog
+}
+
+function polygonGetPath() {
+	console.log(nextLog);
+	console.log(prevLog);
+
+}
+
+function deleteSelectedShape() {
+	for (var i = 0; i < selectedShapes.length; i++) {
+		selectedShapes[i].setMap(null);
+	}
+	selectedShapes = [];
+}
+
+function deleteAllShape() {
+	for (var i = 0; i < overlays.length; i++) {
+		overlays[i].setMap(null);
+
+	}
+	overlays = [];
+}
+
+function historyOverlayPush()
+{
+	//console.log("historyOverlayPush()");
+	//var overlays_copy = [];
+	//for (var i = 0; i<overlays.length; i++) {
+	//	overlays_copy[i] = new google.maps.Rectangle(overlays[i]);
+	//}
+	//var overlay_copy = JSON.parse(JSON.stringify(overlays));
+	//prevOverlays.push(overlays_copy); 
+	//
+	//prevOverlays.push(overlays.slice()); // shallow copy !!!
+	
+	console.log("historyOverlayPush()");
+	var overlays_copy = [];
+	for (var i = 0; i<overlays.length; i++) {
+		
+		overlays_copy[i] = overlays[i];
+		
+	}
+	overlays_copy_obj = overlays_copy;
+	console.log(overlays_copy_obj);
+	console.log(overlays);
+	console.log(prevOverlays);
+	//console.log(JSON.stringify(overlays_copy_obj));
+	
+	var overlay_copy = overlays;
+	prevOverlays.push(overlays_copy_obj); 
+	
+	//prevOverlays.push(overlays.slice()); // shallow copy !!!
+	
+	
+}
Index: /gs3-extensions/map-editor/DrawingManager/notes.txt
===================================================================
--- /gs3-extensions/map-editor/DrawingManager/notes.txt	(revision 32709)
+++ /gs3-extensions/map-editor/DrawingManager/notes.txt	(revision 32709)
@@ -0,0 +1,22 @@
+All shapes = !==undefined
+White Vertices = >=0  = !==undefined
+
+Dark Vertices = undefined
+
+ClearSelection (CS): 
+1- Freezes vertices 
+2- Deselects Shape
+
+
+
+
+Prevents passage TO CS, give pass to dark vertices
+if (e.vertex !== undefined){
+clearSelection();
+
+Grants passage to CS, move white freeze dark
+if (e.vertex == undefined){
+clearSelection();
+
+
+issues: an event is being registered twice
