var MapVm = function() {
    var self = this;

    this.map = new google.maps.Map(document.getElementById('map'));

    this.markers = [];

    this.streetViewService = new google.maps.StreetViewService();

    this.initMap = function() {
        this.map.setOptions({
            center: {lat: 39.95, lng: -75.166667}, // philly {lat: 39.95, lng: -75.166667} ****** st louis {lat: 38.637791, lng: -90.278778}
            zoom: 16,
            styles: mapData.mapStyles,
            fullscreenControl: false,
            gestureHandling: 'greedy',
            mapTypeControl: false,
            minZoom: 13
        });

        google.maps.event.addListenerOnce(this.map, 'tilesloaded', function(){ 
            self.loadData();
        });

        // Make sure the marker property is cleared if the infowindow is closed.
        this.map.addListener('click', function() {            
            if (viewModel.info.placeName()) {
                viewModel.info.clearInfo();
                viewModel.info.show(false);
            }
        });
    };

    this.loadData = function() {
        var self = this;

        var baseUrl = 'https://mapservices.nps.gov/arcgis/rest/services/cultural_resources/nrhp_locations/MapServer/0/';
        var queryStr = 'query?outFields=RESNAME%2C+NRIS_Refnum&returnGeometry=true&f=json&geometry=';
        var bounds = this.map.getBounds();
        var extent = bounds.getSouthWest().lng() + ',' + bounds.getSouthWest().lat() + ',' +
            bounds.getNorthEast().lng() + ',' + bounds.getNorthEast().lat();
        var request = baseUrl + queryStr + extent;

        $.getJSON(request, function(data) {
            console.log(data.features.length + ' features loaded');
            data.features.forEach(function(place) {
                var i = viewModel.list.placeList.push( new Place(place) ) - 1;
                self.addMarker(viewModel.list.placeList()[i]);
            });
        });
    };

    this.makeIcon = function(color) {
        return {
                path: google.maps.SymbolPath.CIRCLE,
                scale: 7,
                fillOpacity: 0.7,
                fillColor: color,
                strokeWeight: 0
        };
    };
    
    this.addMarker = function(place) {

        var title = place.title;
        var id = place.id;
        var position = {};
        position.lat = place.location.lat;
        position.lng = place.location.lng;
        
        var marker = new google.maps.Marker({
            position: position,
            title: title,
            id: id,
            icon: this.makeIcon(place.color())
        });

        // When the user clicks, open an infowindow TODO
        marker.addListener('click', function() {
            viewModel.info.populate(this);
        });

        marker.addListener('mouseover', function() {
            self.highlightMarker(this);
        });

        marker.addListener('mouseout', function() {
            self.clearHighlight(this);
        });

        this.markers.push(marker);
        marker.setMap(this.map);
    };

    this.highlightMarker = function(marker) {
        marker.setIcon( {
                path: google.maps.SymbolPath.CIRCLE,
                scale: 10,
                fillOpacity: 0.7,
                fillColor: 'yellow',
                strokeWeight: 0.5
        } );
    };

    this.clearHighlight = function(marker) {
        marker.setIcon( this.makeIcon(marker.color) );
    };

};
@@ -133,16 +133,69 @@
  = %5B%5D;%0A%0A
+    this.infowindow = new google.maps.InfoWindow();%0A%0A
     this
@@ -2656,65 +2656,8 @@
 );%0A%0A
-        // When the user clicks, open an infowindow TODO%0A
     
@@ -3300,11 +3300,9 @@
 ht: 
-0.5
+1
 %0A   
@@ -3307,24 +3307,117 @@
        %7D );%0A
+        self.infowindow.setContent(marker.title);%0A        self.infowindow.open(map, marker);%0A
     %7D;%0A%0A    
@@ -3508,22 +3508,55 @@
 r.color) );%0A
+        self.infowindow.close();%0A
     %7D;%0A%0A%7D;

Add info windows on hover event