forked from GNUsocial/gnu-social
		
	
		
			
	
	
		
			520 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
		
		
			
		
	
	
			520 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
|   | mxn.register('google', {	 | ||
|  | 
 | ||
|  | Mapstraction: { | ||
|  | 	 | ||
|  | 	init: function(element,api) {		 | ||
|  | 		var me = this; | ||
|  | 		if (GMap2) { | ||
|  | 			if (GBrowserIsCompatible()) { | ||
|  | 				this.maps[api] = new GMap2(element); | ||
|  | 
 | ||
|  | 				GEvent.addListener(this.maps[api], 'click', function(marker,location) { | ||
|  | 					 | ||
|  | 					if ( marker && marker.mapstraction_marker ) { | ||
|  | 						marker.mapstraction_marker.click.fire(); | ||
|  | 					} | ||
|  | 					else if ( location ) { | ||
|  | 						me.click.fire({'location': new mxn.LatLonPoint(location.y, location.x)}); | ||
|  | 					} | ||
|  | 					 | ||
|  | 					// If the user puts their own Google markers directly on the map
 | ||
|  | 					// then there is no location and this event should not fire.
 | ||
|  | 					if ( location ) { | ||
|  | 						me.clickHandler(location.y,location.x,location,me); | ||
|  | 					} | ||
|  | 				}); | ||
|  | 
 | ||
|  | 				GEvent.addListener(this.maps[api], 'moveend', function() { | ||
|  | 					me.moveendHandler(me); | ||
|  | 					me.endPan.fire(); | ||
|  | 				}); | ||
|  | 				 | ||
|  | 				GEvent.addListener(this.maps[api], 'zoomend', function() { | ||
|  | 					me.changeZoom.fire(); | ||
|  | 				}); | ||
|  | 				 | ||
|  | 				this.loaded[api] = true; | ||
|  | 				me.load.fire(); | ||
|  | 			} | ||
|  | 			else { | ||
|  | 				alert('browser not compatible with Google Maps'); | ||
|  | 			} | ||
|  | 		} | ||
|  | 		else { | ||
|  | 			alert(api + ' map script not imported'); | ||
|  | 		}	   | ||
|  | 	}, | ||
|  | 	 | ||
|  | 	applyOptions: function(){ | ||
|  | 		var map = this.maps[this.api]; | ||
|  | 		 | ||
|  | 		if(this.options.enableScrollWheelZoom){ | ||
|  | 			map.enableContinuousZoom(); | ||
|  | 			map.enableScrollWheelZoom(); | ||
|  | 		} | ||
|  | 		 | ||
|  | 		if (this.options.enableDragging) { | ||
|  | 			map.enableDragging(); | ||
|  | 		} else { | ||
|  | 			map.disableDragging(); | ||
|  | 		} | ||
|  | 		 | ||
|  | 	}, | ||
|  | 
 | ||
|  | 	resizeTo: function(width, height){	 | ||
|  | 		this.currentElement.style.width = width; | ||
|  | 		this.currentElement.style.height = height; | ||
|  | 		this.maps[this.api].checkResize();  | ||
|  | 	}, | ||
|  | 
 | ||
|  | 	addControls: function( args ) { | ||
|  | 		var map = this.maps[this.api]; | ||
|  | 	 | ||
|  | 		// remove old controls
 | ||
|  | 		if (this.controls) { | ||
|  | 			while ((ctl = this.controls.pop())) { | ||
|  | 			        // Google specific method
 | ||
|  | 				map.removeControl(ctl); | ||
|  | 			} | ||
|  | 		} else { | ||
|  |   		        this.controls = []; | ||
|  |                 } | ||
|  |                 c = this.controls; | ||
|  |   | ||
|  | 		// Google has a combined zoom and pan control.
 | ||
|  | 		if (args.zoom || args.pan) { | ||
|  | 		    if (args.zoom == 'large'){  | ||
|  |                         this.addLargeControls(); | ||
|  |                     } else { | ||
|  |                         this.addSmallControls(); | ||
|  |                     } | ||
|  | 		} | ||
|  | 
 | ||
|  | 		if (args.scale) { | ||
|  |                     this.controls.unshift(new GScaleControl()); | ||
|  | 	    	    map.addControl(this.controls[0]); | ||
|  | 		    this.addControlsArgs.scale = true; | ||
|  | 		} | ||
|  | 		 | ||
|  | 		if (args.overview) { | ||
|  |                         c.unshift(new GOverviewMapControl());  | ||
|  |                         map.addControl(c[0]); | ||
|  |     		        this.addControlsArgs.overview = true; | ||
|  | 		} | ||
|  | 		if (args.map_type) { | ||
|  |  		        this.addMapTypeControls(); | ||
|  | 		}  | ||
|  | 	}, | ||
|  | 
 | ||
|  | 	addSmallControls: function() { | ||
|  | 		var map = this.maps[this.api]; | ||
|  |                 this.controls.unshift(new GSmallMapControl()); | ||
|  | 		map.addControl(this.controls[0]); | ||
|  | 		this.addControlsArgs.zoom = 'small'; | ||
|  | 		this.addControlsArgs.pan = true; | ||
|  | 	}, | ||
|  | 
 | ||
|  | 	addLargeControls: function() { | ||
|  | 		var map = this.maps[this.api];                 | ||
|  |                 this.controls.unshift(new GLargeMapControl()); | ||
|  | 		map.addControl(this.controls[0]); | ||
|  | 		this.addControlsArgs.zoom = 'large'; | ||
|  | 		this.addControlsArgs.pan = true; | ||
|  | 	}, | ||
|  | 
 | ||
|  | 	addMapTypeControls: function() { | ||
|  | 		var map = this.maps[this.api]; | ||
|  |                 this.controls.unshift(new GMapTypeControl()); | ||
|  | 		map.addControl(this.controls[0]); | ||
|  | 		this.addControlsArgs.map_type = true; | ||
|  | 	}, | ||
|  | 
 | ||
|  | 	setCenterAndZoom: function(point, zoom) {  | ||
|  | 		var map = this.maps[this.api]; | ||
|  | 		var pt = point.toProprietary(this.api); | ||
|  | 		map.setCenter(pt, zoom);  | ||
|  | 	}, | ||
|  | 	 | ||
|  | 	addMarker: function(marker, old) { | ||
|  | 		var map = this.maps[this.api]; | ||
|  | 		var gpin = marker.toProprietary(this.api); | ||
|  | 		map.addOverlay(gpin); | ||
|  | 		 | ||
|  | 		GEvent.addListener(gpin, 'infowindowopen', function() { | ||
|  | 			marker.openInfoBubble.fire(); | ||
|  | 		}); | ||
|  | 		GEvent.addListener(gpin, 'infowindowclose', function() { | ||
|  | 			marker.closeInfoBubble.fire(); | ||
|  | 		});		 | ||
|  | 		return gpin; | ||
|  | 	}, | ||
|  | 
 | ||
|  | 	removeMarker: function(marker) { | ||
|  | 		var map = this.maps[this.api]; | ||
|  | 		map.removeOverlay(marker.proprietary_marker); | ||
|  | 	}, | ||
|  | 
 | ||
|  | 	removeAllMarkers: function() { | ||
|  | 		var map = this.maps[this.api]; | ||
|  | 		// FIXME: got a feeling this doesn't only delete markers
 | ||
|  | 		map.clearOverlays(); | ||
|  | 	}, | ||
|  | 	 | ||
|  | 	declutterMarkers: function(opts) { | ||
|  | 		throw 'Not implemented'; | ||
|  | 	}, | ||
|  | 
 | ||
|  | 	addPolyline: function(polyline, old) { | ||
|  | 		var map = this.maps[this.api]; | ||
|  | 		gpolyline = polyline.toProprietary(this.api); | ||
|  | 		map.addOverlay(gpolyline); | ||
|  | 		return gpolyline; | ||
|  | 	}, | ||
|  | 
 | ||
|  | 	removePolyline: function(polyline) { | ||
|  | 		var map = this.maps[this.api]; | ||
|  | 		map.removeOverlay(polyline.proprietary_polyline); | ||
|  | 	}, | ||
|  | 
 | ||
|  | 	getCenter: function() { | ||
|  | 		var map = this.maps[this.api]; | ||
|  | 		var pt = map.getCenter(); | ||
|  | 		var point = new mxn.LatLonPoint(pt.lat(),pt.lng()); | ||
|  | 		return point; | ||
|  | 	}, | ||
|  | 
 | ||
|  | 	setCenter: function(point, options) { | ||
|  | 		var map = this.maps[this.api]; | ||
|  | 		var pt = point.toProprietary(this.api); | ||
|  | 		if(options && options.pan) {  | ||
|  | 			map.panTo(pt);  | ||
|  | 		} | ||
|  | 		else {  | ||
|  | 			map.setCenter(pt); | ||
|  | 		} | ||
|  | 	}, | ||
|  | 
 | ||
|  | 	setZoom: function(zoom) { | ||
|  | 		var map = this.maps[this.api]; | ||
|  | 		map.setZoom(zoom);			   | ||
|  | 	}, | ||
|  | 	 | ||
|  | 	getZoom: function() { | ||
|  | 		var map = this.maps[this.api]; | ||
|  | 		return map.getZoom(); | ||
|  | 	}, | ||
|  | 
 | ||
|  | 	getZoomLevelForBoundingBox: function( bbox ) { | ||
|  | 		var map = this.maps[this.api]; | ||
|  | 		// NE and SW points from the bounding box.
 | ||
|  | 		var ne = bbox.getNorthEast(); | ||
|  | 		var sw = bbox.getSouthWest(); | ||
|  | 		var gbox = new GLatLngBounds( sw.toProprietary(this.api), ne.toProprietary(this.api) ); | ||
|  | 		var zoom = map.getBoundsZoomLevel( gbox ); | ||
|  | 		return zoom; | ||
|  | 	}, | ||
|  | 
 | ||
|  | 	setMapType: function(type) { | ||
|  | 		var map = this.maps[this.api]; | ||
|  | 		switch(type) { | ||
|  | 			case mxn.Mapstraction.ROAD: | ||
|  | 				map.setMapType(G_NORMAL_MAP); | ||
|  | 				break; | ||
|  | 			case mxn.Mapstraction.SATELLITE: | ||
|  | 				map.setMapType(G_SATELLITE_MAP); | ||
|  | 				break; | ||
|  | 			case mxn.Mapstraction.HYBRID: | ||
|  | 				map.setMapType(G_HYBRID_MAP); | ||
|  | 				break; | ||
|  | 			default: | ||
|  | 				map.setMapType(type || G_NORMAL_MAP); | ||
|  | 		}	  | ||
|  | 	}, | ||
|  | 
 | ||
|  | 	getMapType: function() { | ||
|  | 		var map = this.maps[this.api]; | ||
|  | 		var type = map.getCurrentMapType(); | ||
|  | 		switch(type) { | ||
|  | 			case G_NORMAL_MAP: | ||
|  | 				return mxn.Mapstraction.ROAD; | ||
|  | 			case G_SATELLITE_MAP: | ||
|  | 				return mxn.Mapstraction.SATELLITE; | ||
|  | 			case G_HYBRID_MAP: | ||
|  | 				return mxn.Mapstraction.HYBRID; | ||
|  | 			default: | ||
|  | 				return null; | ||
|  | 		} | ||
|  | 	}, | ||
|  | 
 | ||
|  | 	getBounds: function () { | ||
|  | 		var map = this.maps[this.api]; | ||
|  | 		var ne, sw, nw, se; | ||
|  | 		var gbox = map.getBounds(); | ||
|  | 		sw = gbox.getSouthWest(); | ||
|  | 		ne = gbox.getNorthEast(); | ||
|  | 		return new mxn.BoundingBox(sw.lat(), sw.lng(), ne.lat(), ne.lng()); | ||
|  | 	}, | ||
|  | 
 | ||
|  | 	setBounds: function(bounds){ | ||
|  | 		var map = this.maps[this.api]; | ||
|  | 		var sw = bounds.getSouthWest(); | ||
|  | 		var ne = bounds.getNorthEast(); | ||
|  | 		var gbounds = new GLatLngBounds(new GLatLng(sw.lat,sw.lon),new GLatLng(ne.lat,ne.lon)); | ||
|  | 		map.setCenter(gbounds.getCenter(), map.getBoundsZoomLevel(gbounds));  | ||
|  | 	}, | ||
|  | 
 | ||
|  | 	addImageOverlay: function(id, src, opacity, west, south, east, north, oContext) { | ||
|  | 		var map = this.maps[this.api]; | ||
|  | 		map.getPane(G_MAP_MAP_PANE).appendChild(oContext.imgElm); | ||
|  | 		this.setImageOpacity(id, opacity); | ||
|  | 		this.setImagePosition(id); | ||
|  | 		GEvent.bind(map, "zoomend", this, function() { | ||
|  | 			this.setImagePosition(id); | ||
|  | 		}); | ||
|  | 		GEvent.bind(map, "moveend", this, function() { | ||
|  | 			this.setImagePosition(id); | ||
|  | 		}); | ||
|  | 	}, | ||
|  | 
 | ||
|  | 	setImagePosition: function(id, oContext) { | ||
|  | 		var map = this.maps[this.api]; | ||
|  | 		var topLeftPoint; var bottomRightPoint; | ||
|  | 
 | ||
|  | 		topLeftPoint = map.fromLatLngToDivPixel( new GLatLng(oContext.latLng.top, oContext.latLng.left) ); | ||
|  | 		bottomRightPoint = map.fromLatLngToDivPixel( new GLatLng(oContext.latLng.bottom, oContext.latLng.right) ); | ||
|  | 		 | ||
|  | 		oContext.pixels.top = topLeftPoint.y; | ||
|  | 		oContext.pixels.left = topLeftPoint.x; | ||
|  | 		oContext.pixels.bottom = bottomRightPoint.y; | ||
|  | 		oContext.pixels.right = bottomRightPoint.x; | ||
|  | 	}, | ||
|  | 	 | ||
|  | 	addOverlay: function(url, autoCenterAndZoom) { | ||
|  | 		var map = this.maps[this.api]; | ||
|  | 		var geoXML = new GGeoXml(url); | ||
|  | 		map.addOverlay(geoXML, function() { | ||
|  | 			if(autoCenterAndZoom) { | ||
|  | 				geoXML.gotoDefaultViewport(map); | ||
|  | 			} | ||
|  | 		}); | ||
|  | 	}, | ||
|  | 
 | ||
|  | 	addTileLayer: function(tile_url, opacity, copyright_text, min_zoom, max_zoom, map_type) { | ||
|  | 		var copyright = new GCopyright(1, new GLatLngBounds(new GLatLng(-90,-180), new GLatLng(90,180)), 0, "copyleft"); | ||
|  | 		var copyrightCollection = new GCopyrightCollection(copyright_text); | ||
|  | 		copyrightCollection.addCopyright(copyright); | ||
|  | 		var tilelayers = []; | ||
|  | 		tilelayers[0] = new GTileLayer(copyrightCollection, min_zoom, max_zoom); | ||
|  | 		tilelayers[0].isPng = function() { | ||
|  | 			return true; | ||
|  | 		}; | ||
|  | 		tilelayers[0].getOpacity = function() { | ||
|  | 			return opacity; | ||
|  | 		}; | ||
|  | 		tilelayers[0].getTileUrl = function (a, b) { | ||
|  | 			url = tile_url; | ||
|  | 			url = url.replace(/\{Z\}/g,b); | ||
|  | 			url = url.replace(/\{X\}/g,a.x); | ||
|  | 			url = url.replace(/\{Y\}/g,a.y); | ||
|  | 			return url; | ||
|  | 		}; | ||
|  | 		if(map_type) { | ||
|  |             var tileLayerOverlay = new GMapType(tilelayers, new GMercatorProjection(19), copyright_text, { | ||
|  |                 errorMessage:"More "+copyright_text+" tiles coming soon" | ||
|  |             });         | ||
|  |             this.maps[this.api].addMapType(tileLayerOverlay); | ||
|  |         } else { | ||
|  |             tileLayerOverlay = new GTileLayerOverlay(tilelayers[0]); | ||
|  |             this.maps[this.api].addOverlay(tileLayerOverlay); | ||
|  |         }		 | ||
|  | 		this.tileLayers.push( [tile_url, tileLayerOverlay, true] ); | ||
|  | 		return tileLayerOverlay; | ||
|  | 	}, | ||
|  | 
 | ||
|  | 	toggleTileLayer: function(tile_url) { | ||
|  | 		for (var f=0; f<this.tileLayers.length; f++) { | ||
|  | 			if(this.tileLayers[f][0] == tile_url) { | ||
|  | 				if(this.tileLayers[f][2]) { | ||
|  | 					this.maps[this.api].removeOverlay(this.tileLayers[f][1]); | ||
|  | 					this.tileLayers[f][2] = false; | ||
|  | 				} | ||
|  | 				else { | ||
|  | 					this.maps[this.api].addOverlay(this.tileLayers[f][1]); | ||
|  | 					this.tileLayers[f][2] = true; | ||
|  | 				} | ||
|  | 			} | ||
|  | 		}	    | ||
|  | 	}, | ||
|  | 
 | ||
|  | 	getPixelRatio: function() { | ||
|  | 		var map = this.maps[this.api]; | ||
|  | 
 | ||
|  | 		var projection = G_NORMAL_MAP.getProjection(); | ||
|  | 		var centerPoint = map.getCenter(); | ||
|  | 		var zoom = map.getZoom(); | ||
|  | 		var centerPixel = projection.fromLatLngToPixel(centerPoint, zoom); | ||
|  | 		// distance is the distance in metres for 5 pixels (3-4-5 triangle)
 | ||
|  | 		var distancePoint = projection.fromPixelToLatLng(new GPoint(centerPixel.x + 3, centerPixel.y + 4), zoom); | ||
|  | 		//*1000(km to m), /5 (pythag), *2 (radius to diameter)
 | ||
|  | 		return 10000/distancePoint.distanceFrom(centerPoint); | ||
|  | 	 | ||
|  | 	}, | ||
|  | 	 | ||
|  | 	mousePosition: function(element) { | ||
|  | 		var locDisp = document.getElementById(element); | ||
|  | 		if (locDisp !== null) { | ||
|  | 			var map = this.maps[this.api]; | ||
|  | 			GEvent.addListener(map, 'mousemove', function (point) { | ||
|  | 				var loc = point.lat().toFixed(4) + ' / ' + point.lng().toFixed(4); | ||
|  | 				locDisp.innerHTML = loc; | ||
|  | 			}); | ||
|  | 			locDisp.innerHTML = '0.0000 / 0.0000'; | ||
|  | 		} | ||
|  | 	} | ||
|  | }, | ||
|  | 
 | ||
|  | LatLonPoint: { | ||
|  | 	 | ||
|  | 	toProprietary: function() { | ||
|  | 		return new GLatLng(this.lat,this.lon); | ||
|  | 	}, | ||
|  | 
 | ||
|  | 	fromProprietary: function(googlePoint) { | ||
|  | 		this.lat = googlePoint.lat(); | ||
|  | 		this.lon = googlePoint.lng(); | ||
|  | 	} | ||
|  | 	 | ||
|  | }, | ||
|  | 
 | ||
|  | Marker: { | ||
|  | 	 | ||
|  | 	toProprietary: function() { | ||
|  | 		var infoBubble, event_action, infoDiv, div; | ||
|  | 		var options = {}; | ||
|  | 		if(this.labelText){ | ||
|  | 			options.title =  this.labelText; | ||
|  | 		} | ||
|  | 		if(this.iconUrl){ | ||
|  | 			var icon = new GIcon(G_DEFAULT_ICON, this.iconUrl); | ||
|  | 			icon.printImage = icon.mozPrintImage = icon.image; | ||
|  | 			if(this.iconSize) { | ||
|  | 				icon.iconSize = new GSize(this.iconSize[0], this.iconSize[1]); | ||
|  | 				var anchor; | ||
|  | 				if(this.iconAnchor) { | ||
|  | 					anchor = new GPoint(this.iconAnchor[0], this.iconAnchor[1]); | ||
|  | 				} | ||
|  | 				else { | ||
|  | 					// FIXME: hard-coding the anchor point
 | ||
|  | 					anchor = new GPoint(this.iconSize[0]/2, this.iconSize[1]/2); | ||
|  | 				} | ||
|  | 				icon.iconAnchor = anchor; | ||
|  | 			} | ||
|  | 			if(typeof(this.iconShadowUrl) != 'undefined') { | ||
|  | 				icon.shadow = this.iconShadowUrl; | ||
|  | 				if(this.iconShadowSize) { | ||
|  | 					icon.shadowSize = new GSize(this.iconShadowSize[0], this.iconShadowSize[1]); | ||
|  | 				} | ||
|  | 			} else {  // turn off shadow
 | ||
|  |   			        icon.shadow = ''; | ||
|  |                                 icon.shadowSize = ''; | ||
|  |                         } | ||
|  | 			if(this.transparent) { | ||
|  |   			        icon.transparent = this.transparent; | ||
|  |                         } | ||
|  | 			if(this.imageMap) { | ||
|  |   			        icon.imageMap = this.imageMap; | ||
|  |                         } | ||
|  | 			options.icon = icon; | ||
|  | 		} | ||
|  | 		if(this.draggable){ | ||
|  | 			options.draggable = this.draggable; | ||
|  | 		} | ||
|  | 		var gmarker = new GMarker( this.location.toProprietary('google'),options); | ||
|  | 				 | ||
|  | 		if(this.infoBubble){ | ||
|  | 			infoBubble = this.infoBubble; | ||
|  | 			if(this.hover) { | ||
|  | 				event_action = "mouseover"; | ||
|  | 			} | ||
|  | 			else { | ||
|  | 				event_action = "click"; | ||
|  | 			} | ||
|  | 			GEvent.addListener(gmarker, event_action, function() { | ||
|  | 				gmarker.openInfoWindowHtml(infoBubble, { | ||
|  | 					maxWidth: 100 | ||
|  | 				}); | ||
|  | 			}); | ||
|  | 		} | ||
|  | 
 | ||
|  | 		if(this.hoverIconUrl){ | ||
|  | 			GEvent.addListener(gmarker, "mouseover", function() { | ||
|  | 				gmarker.setImage(this.hoverIconUrl); | ||
|  | 			}); | ||
|  | 			GEvent.addListener(gmarker, "mouseout", function() { | ||
|  | 				gmarker.setImage(this.iconUrl); | ||
|  | 			}); | ||
|  | 		} | ||
|  | 
 | ||
|  | 		if(this.infoDiv){ | ||
|  | 			infoDiv = this.infoDiv; | ||
|  | 			div = this.div; | ||
|  | 			if(this.hover) { | ||
|  | 				event_action = "mouseover"; | ||
|  | 			} | ||
|  | 			else { | ||
|  | 				event_action = "click"; | ||
|  | 			} | ||
|  | 			GEvent.addListener(gmarker, event_action, function() { | ||
|  | 				document.getElementById(div).innerHTML = infoDiv; | ||
|  | 			}); | ||
|  | 		} | ||
|  | 
 | ||
|  | 		return gmarker; | ||
|  | 	}, | ||
|  | 
 | ||
|  | 	openBubble: function() { | ||
|  | 		var gpin = this.proprietary_marker; | ||
|  | 		gpin.openInfoWindowHtml(this.infoBubble); | ||
|  | 	}, | ||
|  | 
 | ||
|  | 	hide: function() { | ||
|  | 		this.proprietary_marker.hide(); | ||
|  | 	}, | ||
|  | 
 | ||
|  | 	show: function() { | ||
|  | 		this.proprietary_marker.show(); | ||
|  | 	}, | ||
|  | 
 | ||
|  | 	update: function() { | ||
|  | 		point = new mxn.LatLonPoint(); | ||
|  | 		point.fromGoogle(this.proprietary_marker.getPoint()); | ||
|  | 		this.location = point; | ||
|  | 	} | ||
|  | 	 | ||
|  | }, | ||
|  | 
 | ||
|  | Polyline: { | ||
|  | 
 | ||
|  | 	toProprietary: function() { | ||
|  | 		var gpoints = []; | ||
|  | 		for (var i = 0,  length = this.points.length ; i< length; i++){ | ||
|  | 			gpoints.push(this.points[i].toProprietary('google')); | ||
|  | 		} | ||
|  | 		if (this.closed	|| gpoints[0].equals(gpoints[length-1])) { | ||
|  | 			return new GPolygon(gpoints, this.color, this.width, this.opacity, this.fillColor || "#5462E3", this.opacity || "0.3"); | ||
|  | 		} else { | ||
|  | 			return new GPolyline(gpoints, this.color, this.width, this.opacity); | ||
|  | 		} | ||
|  | 	}, | ||
|  | 	 | ||
|  | 	show: function() { | ||
|  | 		throw 'Not implemented'; | ||
|  | 	}, | ||
|  | 
 | ||
|  | 	hide: function() { | ||
|  | 		throw 'Not implemented'; | ||
|  | 	} | ||
|  | } | ||
|  | 
 | ||
|  | }); |