/* * GMapEZ -- Turn specially-marked HTML into Google Maps * Copyright (C) July 2005 - May 2006 by Chris Houser <chouser@bluweb.com> * * This code is licensed under the GNU General Public License (GPL) * * If you use this code on a web page, please include on that page a * link to http://bluweb.com/chouser/gmapez/ -- this is a request, not * a requirement.  Thanks. */(function(){  var startdate = new Date();  // configuration -- if you're using your own copy of gmapez.js, you  // may want to modify these:  var overlaysPerStep = 25;  var imgBase = 'http://n01se.net/gmapez/';  function loadfunc() {    if( ! GBrowserIsCompatible() ) {      if( document.getElementsByTagName ) {        // Find all divs marked as GMapEZ        var divs = document.getElementsByTagName( 'div' );        for( var i = 0; i < divs.length; ++i ) {          var div = divs[ i ];          if( div.className.indexOf( 'GMapEZ' ) > -1 ) {            div.innerHTML =  [              "<div>This map cannot be displayed.  The site's key may be ",              "incorrect, or your browser may not compatible (see if ",              "your browser is listed ",              '<a href="http://maps.google.com/support/bin/answer.py?answer=16532">here</a>).</div>',              '<div class="firefoxref"><iframe src="http://pagead2.googlesyndication.com/cpa/ads?client=ca-pub-1237864095616304&amp;cpa_choice=CAAQyaj8zwEaCIwcWMzeycafKMu293M&amp;oe=UTF-8&amp;dt=1148266564041&amp;lmt=1148266562&amp;format=180x60_as_rimg&amp;output=html&amp;region=_google_cpa_region_&amp;cc=100&amp;u_h=1024&amp;u_w=1280&amp;u_ah=1050&amp;u_aw=1400&amp;u_cd=24&amp;u_tz=-240&amp;u_his=1&amp;u_java=true&amp;u_nplug=11&amp;u_nmime=133" marginwidth="0" marginheight="0" vspace="0" hspace="0" allowtransparency="true" frameborder="0" height="60" scrolling="no" width="180"></iframe></div>'              ].join('\n');            div.style.visibility = 'visible';            div.style.padding = '0.3em';            div.style.background = '#eee';            div.style.overflow = 'auto';          }        }      }      else {        alert( [          'Your browser is not capable of displaying',          'Google Maps on this page. Try using Firefox:',          'http://getfirefox.com/' ].join('\n') );      }      return;    }    addOnUnload( GUnload );    function GSmallMapTypeControl() {      GMapTypeControl.call( this, true );    }    GSmallMapTypeControl.prototype = new GMapTypeControl();    GSmallMapTypeControl.prototype.constructor = GSmallMapTypeControl;    window.GSmallMapTypeControl = GSmallMapTypeControl;    var CtrlTable = {      'GLargeMapControl': true,      'GSmallMapControl': true,      'GSmallZoomControl': true,      'GSmallMapTypeControl': true,      'GMapTypeControl': true,      'GScaleControl': true    };    var MapTypeTable = {      'G_MAP_TYPE' : true,      'G_SATELLITE_TYPE' : true,      'G_HYBRID_TYPE' : true,      'G_KATRINA_TYPE' : true    };    var idmarkers = {};    function markerForUrl( url ) {      var matcha = /#(.*)/.exec( url );      if( matcha )        return idmarkers[ matcha[ 1 ] ];      else        return null;    }    function wordMap( str ) {      var wmap = {};      var list = str.split(' ');      for( var j = 0; j < list.length; ++j ) {        wmap[ list[ j ] ] = true;      }      return wmap;    }    var markerOpener = {      markers: [],      addMarker: function( marker ) {        this.markers.push( marker );      },      chainOpen: function( i ) {        /*         * This is a work-around for a Google Maps bug.  If I try to open         * all the info windows at once, only the last one succeeds.         *         * Otherwise, it is equivalent to:         *   for( i = 0; i < this.markers.length; ++i )         *     this.markers[ i ].doOpen();         */        i = i || 0;        if( i < this.markers.length ) {          var onOpen = GEvent.bind(              this.markers[ i ],              "infowindowopen",              this,              function(){                GEvent.removeListener( onOpen );                this.chainOpen( i + 1 );              });          this.markers[ i ].doOpen();        }        else {          //alert('GMapEZ loadtime: ' + ( new Date() - startdate ) );        }      }    };    var laterFuncs = [];    var lastFunc = null;    function doNow() {      if( laterFuncs.length > 0 ) {        laterFuncs.shift().call();        setTimeout( doNow, 1 );      }      else {        if( lastFunc ) {          lastFunc.call();        }      }    }    function doLater( obj, func ) {      laterFuncs.push( function() { func.call( obj ); } );    }    var MiniIcon = new GIcon();    MiniIcon.shadow = "http://labs.google.com/ridefinder/images/mm_20_shadow.png";    MiniIcon.iconSize = new GSize(12, 20);    MiniIcon.shadowSize = new GSize(22, 20);    MiniIcon.iconAnchor = new GPoint(6, 20);    MiniIcon.infoWindowAnchor = new GPoint(5, 1);    function EZInfoMarker( ezmap, point, icon, title ) {      this.ezmap = ezmap;      this.point = point;      this.icon = icon;      this.title = title;      this.blowup = false;      this.tabs = [];      this.infoZoomOffset = undefined;      this.infoZoomLevel = undefined;      this.infoMapType = null;    }    EZInfoMarker.prototype = new GMarker( new GLatLng( 0, 0 ) );    EZInfoMarker.prototype.constructor = EZInfoMarker;    EZInfoMarker.prototype.initialize = function( map ) {      GMarker.call(          this,          this.point,          {            icon: this.icon,            clickable: ( this.tabs.length > 0 || this.blowup ),            title: this.title          });      GMarker.prototype.initialize.call( this, map );    };    EZInfoMarker.prototype.doOpen = function() {      var zoom = null;      if( this.tabs.length > 0 ) {        this.openInfoWindowTabs( this.tabs, {          maxWidth: this.ezmap.div.offsetWidth - 100 } );      }      else if( this.blowup ) {        if( this.infoZoomOffset != undefined )          zoom = this.ezmap.map.getZoom() + this.infoZoomOffset;        else if( this.infoZoomLevel != undefined )          zoom = this.infoZoomLevel;        if( zoom >= this.ezmap.map.getCurrentMapType().numZoomLevels )          zoom = this.ezmap.map.getCurrentMapType().numZoomLevels - 1;        else if( zoom < 0 )          zoom = 0;        this.showMapBlowup( { zoomLevel: zoom, mapType: this.infoMapType } );      }      else {        this.ezmap.map.closeInfoWindow();      }    };    function EZPolyline( color, weight, opacity ) {      this.points = [];      this.initialize = function( map ) {        GPolyline.call( this, this.points, color, weight, opacity );        GPolyline.prototype.initialize.call( this, map );      };    };    EZPolyline.prototype = new GPolyline();    EZPolyline.prototype.constructor = EZPolyline;    function EZMap( div, classes ) {      this.div = div;      this.classes = classes;      this.divData = null;      this.map = undefined;      this.mapType = undefined;      this.autoBounds = undefined;      this.center = undefined;      this.span = undefined;      this.explicitExtent = false;      this.overlayList = [];      this.loading = null;      this.bar = null;      this.maxstep = 0;      this.step = 0;      this.oi = 0;      this.initFrame();    }    EZMap.prototype.logWarning = function( str ) {      if( ! this.warningNode ) {        this.warningVis = false;        this.warningNode = document.createElement('ul');        this.warningNode.className = 'warnings';        this.div.appendChild( this.warningNode );        var warnBtn = document.createElement('button');        warnBtn.className = 'warnings';        warnBtn.innerHTML = 'Warnings...';        this.div.appendChild( warnBtn );        var ezmap = this;        warnBtn.onclick = function() { ezmap.toggleWarnings(); };      }      var li = document.createElement('li');      li.innerHTML = str;      this.warningNode.appendChild( li );    };    EZMap.prototype.toggleWarnings = function() {      this.warningVis = ! this.warningVis;      this.warningNode.style.display = this.warningVis ? 'block' : 'none';    };    EZMap.prototype.processMarkers = function( parentNode, polyline ) {      for( var node = parentNode.firstChild; node; node = node.nextSibling){        var lastOverlay = this.overlayList[ this.overlayList.length - 1 ];        switch( node.nodeName ) {        case 'A':          var textContent = node.innerHTML.replace( /<[^>]*>/g, '' );          var openThisMarker = /\bOPEN\b/.exec( textContent );          textContent = textContent.replace( /\bOPEN\b/, '' );          textContent = textContent.replace( /^\s*/, '' );          textContent = textContent.replace( /\s*$/, '' );          if( textContent == 'EXTENT' )            this.explicitExtent = true;          var matchll = /\Wll=([-.\d]*),([-.\d]*)/.exec( node.href );          if( matchll ) {            var lat = parseFloat( matchll[1] );            var lng = parseFloat( matchll[2] );            var point = new GLatLng( lat, lng );            if( polyline ) {              polyline.points.push( point );            }            if( textContent == 'EXTENT'                || ( ! this.explicitExtent && this.overlayList.length < 1 ) )            {              this.center = point;              var matchspn = /\Wspn=([-.\d]*),([-.\d]*)/.exec( node.href );              if( matchspn ) {                this.span = new GLatLng(                    parseFloat( matchspn[1] ),                    parseFloat( matchspn[2] ) );              }              var matchtype = /\Wt=(.)/.exec( node.href );              if( matchtype ) {                switch( matchtype[1] ) {                  case 'k': this.mapType = G_SATELLITE_TYPE; break;                  case 'h': this.mapType = G_HYBRID_TYPE; break;                }              }            }            if( textContent != 'EXTENT' ) {              if( ! this.autoBounds ) {                this.autoBounds = new GLatLngBounds( point, point );              }              else {                this.autoBounds.extend( point );              }              var iconmodel = G_DEFAULT_ICON;              var iconbase = 'marker';              var sym = null;              var color = 'ORANGE';              var matchcolor =                  /\b(ORANGE|PURPLE|YELLOW|GREEN|BLUE|RED|AQUA|WHITE|GRAY)\b/                  .exec( textContent );              if( matchcolor )                color = matchcolor[0];              var matchsym =                  /\b([0-9A-Za-z]|BLANK|HASH|DOLLAR|DOT|START|END)\b/                  .exec( textContent );              if( matchsym )                sym = matchsym[ 0 ];              var matchmini = /\bMINI\b/.exec( textContent );              if( matchmini ) {                iconmodel = MiniIcon;                iconbase = 'mini';                sym = 'BLANK';              }              if( sym || ! polyline ) {                var icon = new GIcon( iconmodel );                icon.image = [                  imgBase, 'iconEZ2/', iconbase, '-', color, '-',                  ( sym || 'DOT' ), '.png' ].join('');                var marker = new EZInfoMarker(                    this, point, icon, node.getAttribute('title') );                this.overlayList.push( marker );                idmarkers[ node.id || node.name ] = marker;                if( openThisMarker )                  markerOpener.addMarker( marker );              }            }          }          else {            this.logWarning( "No ll param for marker [" + node.innerHTML +              ":" + (node.id || node.name) + "]" );          }          break;        case 'DIV':          if( ! lastOverlay ) {            this.logWarning( "div block given before any markers" );            continue;          }          else {            var infoClasses = wordMap( node.className );            if( 'GMapEZ' in infoClasses ) {              // infoWindow blowup              lastOverlay.blowup = true;              var matchzoom = /ZOOMLEVEL([-+=]?)(\d+)/.exec( node.innerHTML );              if( matchzoom ) {                var num = parseInt( matchzoom[ 2 ] );                if( matchzoom[ 1 ] == '-' )                  lastOverlay.infoZoomOffset = num;                else if( matchzoom[ 1 ] == '+' )                  lastOverlay.infoZoomOffset = - num;                else                  lastOverlay.infoZoomLevel = num;              }              for( typeName in MapTypeTable ) {                if( typeName in infoClasses ) {                  lastOverlay.infoMapType = window[ typeName ];                  break;                }              }            }            else {              lastOverlay.tabs.push(                  new GInfoWindowTab( node.getAttribute('title'), node ));            }          }          break;        case 'LI':          this.processMarkers( node, polyline );          break;        case 'OL':          var params = { color: null, weight: null, opacity: null };          for( var word in wordMap( node.className ) ) {            var matchparam = /^(color|weight|opacity):(.*)$/.exec( word );            if( matchparam )              params[ matchparam[1] ] = matchparam[2];          }          if( params.color && ! /^#[0-9a-zA-Z]{6}$/.exec( params.color ) )            this.logWarning( 'Polyline color should be a 6-digit' +                ' hex color like "#123abc", not "' + params.color + '"' );          if( params.weight != null ) {            var w = parseInt( params.weight );            if( w < 1 || isNaN( w ) )              this.logWarning( 'Polyline weight should be an' +                  ' interger above 0, not "' + params.weight + '"' );            params.weight = w;          }          if( params.opacity ) {            var o = parseFloat( params.opacity );            if( o < 0 || o > 1 || isNaN( o ) )              this.logWarning( 'Polyline opacity should be ' +                  ' between 0 and 1, not "' + params.opacity + '"' );            params.opacity = o;          }          var newline = new EZPolyline(              params.color,              params.weight,              params.opacity );          this.overlayList.push( newline );          this.processMarkers( node, newline );          break;        case '#text':        case '#comment':          // ignore text and comments          break;        default:          this.logWarning( "Unknown or misplaced node " + node.nodeName );          break;        }      }    };    EZMap.prototype.onClick = function( overlay, point ) {      if( overlay && overlay.doOpen ) {        overlay.doOpen();      }      else if( point ) {        this.map.closeInfoWindow();      }    };    EZMap.prototype.nextStep = function( func ) {      if( this.maxstep > 0 ) {        this.bar.style.width = Math.round( this.step / this.maxstep * 100 ) + '%';      }      this.step += 1;      doLater( this, func );    };    EZMap.prototype.initFrame = function() {      this.divData = div.cloneNode( true );      this.div.innerHTML = '';      this.div.style.visibility = 'visible';      this.loading = document.createElement('div');      this.loading.className = 'loadprogress';      this.loading.style.marginTop = ( this.div.offsetHeight / 3 ) + 'px';      this.loading.innerHTML = '<div class="box"><div class="logo"></div><div class="trough"><div class="bar"></div></div></div>';      this.bar = this.loading.getElementsByTagName('div')[3];      this.div.appendChild( this.loading );      this.nextStep( this.initParse );    };    EZMap.prototype.initParse = function() {      this.processMarkers( this.divData );      this.divData = null;      this.map = new GMap2( this.div );      this.map.getContainer().appendChild( this.loading );      GEvent.bind( this.map, 'click', this, this.onClick );      // map type      if( this.overlayList.length > 1 && ! this.explicitExtent ) {        this.mapType = null;      }      for( typeName in MapTypeTable ) {        if( typeName in this.classes ) {          this.mapType = window[ typeName ];          break;        }      }      this.mapType = this.mapType || G_MAP_TYPE;      // center and zoom      var viewsize = new GSize( this.div.offsetWidth, this.div.offsetHeight );      var zoomLevel;      if( this.overlayList.length == 1 || this.explicitExtent ) {        if( this.span ) {          zoomLevel = this.mapType.getSpanZoomLevel(              this.center, this.span, viewsize );        }      }      else if( this.overlayList.length > 1 ) {        var sw = this.autoBounds.getSouthWest();        var ne = this.autoBounds.getNorthEast();        this.center = new GLatLng(          ( sw.lat() + ne.lat() ) / 2,          ( sw.lng() + ne.lng() ) / 2 );        zoomLevel = this.mapType.getBoundsZoomLevel( this.autoBounds, viewsize);      }      else {        this.center = new GLatLng( 41.075210, -85.130310 );        zoomLevel = 10;      }      // apply center, zoom, and map type      this.map.setCenter( this.center, zoomLevel, this.mapType );      this.maxstep = Math.floor( this.overlayList.length / overlaysPerStep ) + 2;      this.initOverlays();    };    EZMap.prototype.initOverlays = function() {      var steplimit = Math.min(this.overlayList.length, this.oi+overlaysPerStep);      for( ; this.oi < steplimit; ++this.oi ) {        this.map.addOverlay( this.overlayList[ this.oi ] );        this.overlayList[ this.oi ] = null;      }      if( this.oi < this.overlayList.length )        this.nextStep( this.initOverlays );      else        this.nextStep( this.initControls );    };    EZMap.prototype.initControls = function() {      for( var ctrl in CtrlTable ) {        if( ctrl in this.classes ) {          this.map.addControl( new window[ ctrl ]() );        }      }      this.nextStep( this.initLoading );    };    EZMap.prototype.initLoading = function() {      this.loading.parentNode.removeChild( this.loading );      this.loading = null;    };    // Find all divs marked as GMapEZ    var divs = document.getElementsByTagName( 'div' );    for( var i = 0; i < divs.length; ++i ) {      var div = divs[ i ];      var classes = wordMap( div.className );      if( 'GMapEZ' in classes ) {        new EZMap( div, classes );      }    }    lastFunc = function() {      // Find all anchor tags linking to GMapEZ markers      var anchors = document.getElementsByTagName( 'a' );      for( var mi = 0; mi < anchors.length; ++mi ) {        var marker = markerForUrl( anchors[ mi ].href );        if( marker )          GEvent.bindDom( anchors[ mi ], "click", marker, marker.doOpen );      }      // Examine current page location for a reference to a GMapEZ marker      var marker = markerForUrl( document.location );      if( marker )        markerOpener.addMarker( marker );      // Open all the markers we need to      markerOpener.chainOpen();    };    doNow();  }  function chainWindowFunc( funcname, newfunc ) {    var oldfunc = window[ funcname ];    if( oldfunc ) {      window[ funcname ] = function() { oldfunc(); newfunc(); };    }    else {      window[ funcname ] = newfunc;    }  }  window.addOnLoad   = function( func ) { chainWindowFunc( "onload",   func ); };  window.addOnUnload = function( func ) { chainWindowFunc( "onunload", func ); };  window.ez_preload = function() {    if( window.G_INCOMPAT ) {      // If the key failed to validate, cause all keys to appear valid      // and try again.      window.G_INCOMPAT = false;      window.GValidateKey = function(){ return true; }      GLoad();    }    addOnLoad( loadfunc );  }  var key = '';  var gmapversion = '2';  (function(){    var metas = document.getElementsByTagName( 'meta' );    var match;    for( var i = 0; i < metas.length; ++i ) {      match = /gmapkey:?(.*)/.exec( metas[ i ].name );      if( match ) {        if( ! match[ 1 ] ) {          key = metas[ i ].content;        }        else if( (new RegExp( match[ 1 ] )).exec( window.location.href ) ) {          key = metas[ i ].content;          break;        }      }      else if( metas[ i ].name == 'gmapversion' ) {        gmapversion = metas[ i ].content;      }    }  })();  document.write( [    '<script src="http://maps.google.com/maps?file=api&v='    + gmapversion + '&key=' + key    + '" type="text/javascript"></script>',    '<script type="text/javascript">',    '  ez_preload();',    '</script>',    '<style type="text/css">',    'div.GMapEZ {',    '  visibility: hidden;',    '  border: 1px #888 solid;',    '}',    'div.GMapEZ ul.warnings {',    '  position: absolute;',    '  top: 0;',    '  left: 0;',    '  margin: 0;',    '  padding-right: 0.5em;',    '  padding-left: 1.5em;',    '  display: none;',    '  border: 1px #888 solid;',    '  background: #fff;',    '  z-index: 100000000;',    '  text-align: left;',    '  font-family: Arial;',    '  font-size: 9pt;',    '  overflow: auto;',    '}',    'div.GMapEZ button.warnings {',    '  display: block;',    '  position: absolute;',    '  z-index: 100000000;',    '  bottom: 20px;',    '  right: 0;',    '  color: #f00;',    '}',    'div.GMapEZ .firefoxref {',    '  text-align: center;',    '  margin: 1em;',    '}',    'div.GMapEZ .loadprogress {',    '  position: relative;',    '  z-index: 100000000;',    '  text-align: center;',    '}',    'div.GMapEZ .loadprogress .box {',    '  font-family: Arial, sans-serif;',    '  background: #fff;',    '  border: 1px #bbb inset;',    '  width: 136px;',    '  height: 45px;',    '  margin: auto;',    '}',    'div.GMapEZ .loadprogress .logo {',    '  margin: 8px;',    '  margin-bottom: 0;',    '  width: 120px;',    '  height: 28px;',    "  filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" +        imgBase + "logo3.png',sizingMethod='scale');",    '}',    'div.GMapEZ .loadprogress .box > .logo {',    '  position: relative;',    '  background: url(' + imgBase + 'logo3.png) no-repeat;',    '}',    'div.GMapEZ .loadprogress .trough {',    '  margin: 8px;',    '  margin-top: -5px;',    '  background: #ccc;',    '  font-size: 1px;',    '  height: 8px;',    '  text-align: left;',    '}',    'div.GMapEZ .loadprogress .bar {',    '  height: 8px;',    '  width: 0px;',    '  background: #55a url(' + imgBase + 'progressbar.png);',    '}',    'v\\:* {',    '  behavior:url(#default#VML);',    '}',    '</style>'  ].join('\n'));})();
var map;    var gdir;    var geocoder = null;    var addressMarker;        function setDirections(fromAddress, toAddress, locale) {      gdir.load("from: " + fromAddress + " to: " + toAddress,                { "locale": locale });    }    function handleErrors(){	   if (gdir.getStatus().code == G_GEO_UNKNOWN_ADDRESS)	     alert("No corresponding geographic location could be found for one of the specified addresses. This may be due to the fact that the address is relatively new, or it may be incorrect.\nError code: " + gdir.getStatus().code);	   else if (gdir.getStatus().code == G_GEO_SERVER_ERROR)	     alert("A geocoding or directions request could not be successfully processed, yet the exact reason for the failure is not known.\n Error code: " + gdir.getStatus().code);	   	   else if (gdir.getStatus().code == G_GEO_MISSING_QUERY)	     alert("The HTTP q parameter was either missing or had no value. For geocoder requests, this means that an empty address was specified as input. For directions requests, this means that no query was specified in the input.\n Error code: " + gdir.getStatus().code);	//   else if (gdir.getStatus().code == G_UNAVAILABLE_ADDRESS)  <--- Doc bug... this is either not defined, or Doc is wrong	//     alert("The geocode for the given address or the route for the given directions query cannot be returned due to legal or contractual reasons.\n Error code: " + gdir.getStatus().code);	     	   else if (gdir.getStatus().code == G_GEO_BAD_KEY)	     alert("The given key is either invalid or does not match the domain for which it was given. \n Error code: " + gdir.getStatus().code);	   else if (gdir.getStatus().code == G_GEO_BAD_REQUEST)	     alert("A directions request could not be successfully parsed.\n Error code: " + gdir.getStatus().code);	    	   else alert("An unknown error occurred.");	   	}	function onGDirectionsLoad(){       // Use this function to access information about the latest load()      // results.      // e.g.      // document.getElementById("getStatus").innerHTML = gdir.getStatus().code;	  // and yada yada yada...	}