Using Google Map's New Features for Flash

Using Google Maps’ New Features for Flash

After such a positive response to my first tutorial Implement a Map Using the Google Map API for Flash I decided to write a second. Since that first tut the Google Map API has been updated, allowing developers to (amongst other things) add 3D viewing to maps. This is a great feature and during this tutorial I’ll explain how to use it.

Also, lots of people requested an explanation for adding custom markers; that’s the second thing we’ll discuss here today.

Step 1: Download The SDK Component

I won’t build further on our previous map because we need to download the new Google Map Component. There is no way to use the component from my previous tutorial as that one does not support the 3D functions. So… go to http://code.google.com/intl/nl/apis/maps/documentation/flash/

Step 2: Install the SDK Component

We need to install the SDK component to use it in Flash. To do so, navigate to the location where you saved the Google Maps SDK Component and find the non-Flex version of the interface library. In my case this is (lib/map_1_18.swc). Now copy the “map_1_18.swc” file.

Step 3: Folders

Afterwards, if you have Flash currently open, quit the application and search for this folder:

  • (Windows) C:\Program Files\Adobe\Adobe Flash CS3 (or your Flash version)\en (or your language)\Configuration\Components
  • (Mac OS X) Macintosh HD/Applications/Adobe Flash CS3 (or your Flash version)/Configuration/Components

Inside that folder create a new folder named “google” and Paste the “map_1_18.swc” file inside it. Flash is now set up to
support the Google Maps API for Flash.

Step 4: The Google Map API Key

Ok we have the component now but before we can get to work we still need a Google Map API Key to get our map working online. A Google Map API Key is free and you can get one here:

http://code.google.com/intl/nl/apis/maps/documentation/flash/

.

Step 5: Sign Up

Clicking the “Sign up for a Google Maps API Key” link brings us to the next page where we can generate our personal API Key. Scroll down the page, agree with the terms and conditions (you could read these too if you’re really interested) and add the url of the website where you want to use the application (you will need a different API Key for every domain where you want to place a map). After that, click “Generate API Key”.

Step 6: Save It!

Now you’ll see your personal API Key for the selected domain. Copy the API Key and paste or save it somewhere as we’ll need it very soon.

Step 7: New ActionScript 3.0 File

OK, the boring work is done, now we can start with the fun stuff! Let’s dive into Flash and create a new ActionScript 3.0 file, default stage size (550 x 400).

Step 8: Save It

I prefer to start off by saving the file. While I’m working I really like to Hit “Ctrl+S” all the time, so go ahead hit
“Ctrl+S” or click “File > Save” in the menu. Save it to the location you want and name it whatever you want. I will name it
“google_map”.

Step 9: The GoogleMapsLibrary

Open the Components panel “Ctrl+F7″ or click Window > Components in the menu. Drag the GoogleMapsLibrary into your library.

Step 10: The Actions Layer

To keep organized I like to rename the first layer to “actions”.

Step 11: Import

With the actions layer selected open the actions panel (hit “F9″ or click “Window > Actions”) and add these lines of code:

		import com.google.maps.LatLng;
        import com.google.maps.Map;
        import com.google.maps.Map3D;
        import com.google.maps.MapEvent;
        import com.google.maps.MapType;
        import com.google.maps.View;
        import com.google.maps.geom.Attitude;
	

Step 12: Create the Map

Now we’ll create our first function. First we want to declare our Map variable:

    	// Variables
        var map:Map3D;
    

Now we can add our function that we will call to add the main map on the stage:

    	// Function that adds the map on stage
        function add_map()
        {
			map = new Map3D();
    		map.key = "YOUR_API_KEY_HERE";
            map.setSize(new Point(stage.stageWidth, stage.stageHeight));
    		map.addEventListener(MapEvent.MAP_READY, onMapReady);
    		this.addChild(map);
		}
    

OK, as you can see we added an eventlistener that will fire once our map is loaded, so lets also create that function:

    	// Function that will fire once map is created
		function onMapReady(event:MapEvent):void
		{
		    map.setCenter(new LatLng(50.899197766773284, 4.486040573103489), 13);
			map.setAttitude(new Attitude(20,30,0));
		}
    

Here we’ve set the map to center. This function has 3 values and will define the location where the map will open. The
values are like this “map.setCenter(new LatLng(latitude, longitude), zoom);”. Then we define the view mode;
as we are using the new 3D map I will use the Perspective view. If you like a normal map view you can change this value to
“View.VIEWMODE_2D”.

Then we set the Attitude. This will define how we view the map. In this case we will add a little Perspective view to it and
turn the map a little to create a nicer view angle. You can play around with these values a bit and see what you like best.

OK, it’s time for a first check! What do we have so far? Well, nothing yet! We first need to call our function to create the
map! Let’s add this line of code just under our variables:

        // Variables
        var map:Map3D;

        // Call the function to create the map
        add_map();
    

There we go! Now just test your movie “Ctrl+Enter” or click Control > Test Movie in the menu…

Step 13: The Navigation Tools

Yes! We have a map zoomed in on Brussels Airport! Isn’t that great?! Perhaps not… Let’s take a look at what we have here. We have the map and we can drag the map around. So what we need next are tools to navigate around the map, zoom in and out on the map. Let’s start with those navigation tools first!

First of all let’s import 3 extra classes; add these lines under the other import code in our script:

    	import com.google.maps.controls.NavigationControl;
    	import com.google.maps.controls.MapTypeControl;
    	import com.google.maps.controls.OverviewMapControl;
    

No go to the onMapReady() function and add these 3 lines of code under the other lines:

    	map.addControl(new MapTypeControl());
    	map.addControl(new OverviewMapControl());
    	map.addControl(new NavigationControl());
    

Here we’re adding the map type controls, so now we can change the map type. Then we add a map overview control to the right bottom of our map. And we add the map navigation tools. This is our full source code as it should look right now:

    	import com.google.maps.LatLng;
		import com.google.maps.Map;
		import com.google.maps.Map3D;
		import com.google.maps.MapEvent;
		import com.google.maps.MapType;
		import com.google.maps.View;
		import com.google.maps.geom.Attitude;
		import com.google.maps.controls.NavigationControl;
		import com.google.maps.controls.MapTypeControl;
		import com.google.maps.controls.OverviewMapControl;

		// Variables
		var map:Map3D;

		// Call the function to create the map
		add_map();

		// Function that adds the map on stage
		function add_map()
		{
			map = new Map3D();
    		map.key = 'YOUR_API_KEY_HERE';
			map.setSize(new Point(stage.stageWidth, stage.stageHeight));
    		map.addEventListener(MapEvent.MAP_READY, onMapReady);
    		this.addChild(map);
		}

		// Function that will fire once map is created
		function onMapReady(event:MapEvent):void
		{
			map.setCenter(new LatLng(50.899197766773284, 4.486040573103489), 13);
			map.viewMode = View.VIEWMODE_PERSPECTIVE;
			map.setAttitude(new Attitude(20,40,0));
			map.addControl(new MapTypeControl());
    		map.addControl(new OverviewMapControl());
    		map.addControl(new NavigationControl());
		}
    

Go ahead and test your movie again. You can see that you can move around the map very easily now with these funky looking new
controls!

Step 14: A Bar Without Beer

I think it’s time to move on to the markers part; a map without markers is like a bar without beer isn’t it? No silly stuff this time! Let’s move to the Custom markers straight away!

We want to place our custom markers onto the map with information that will be stored in an external XML file. Let’s begin by creating a custom marker, then we’ll create the XML file and after that we’ll load it into Flash.

Step 15: Creating the Custom Marker

I’m not much of a designer so I think you’ll be able to create a much cooler marker than I have! Thats why I’m not going spend too much time on this. Just draw a few circles, put them on top of each other, select everything, hit F8, select movieClip, name it “marker_mc” and select Export For Actionscript. Hit “OK”.

As I mentioned before, I hope you will create a cooler and better looking marker than this! Just draw your own marker and
covert it to a moviclip as explained above.

Once you’ve created the movieclip it will appear in your library. You can then delete it from the stage as we will import it using
ActionScript (that’s why you had to select the option “Export For ActionScript”). In our library we now have 2 items; the
GoogleMapsLibrary and our marker_mc.

Step 16: The XML file

OK, here we are. We have a map and (in your case) a very good looking marker! Now let’s create the XML file. Open your favorite code editor, create this file and save it as locations.xml.

<?xml version="1.0" encoding="utf-8"?>
 <map_xml>

  <location>
   <lat>50.899197766773284</lat>
   <lon>4.486040573103489</lon>
   <name_tip>Brussels</name_tip>
   <title_tip><![CDATA[Brussels]]></title_tip>
   <content_tip><![CDATA[Brussels Airport.]]></content_tip>
  </location>

  <location>
   <lat>49.004024443647324</lat>
   <lon>2.571113562006575</lon>
   <name_tip>Paris</name_tip>
   <title_tip><![CDATA[Paris]]></title_tip>
   <content_tip><![CDATA[Paris Airport.]]></content_tip>
  </location>

  <location>
   <lat>51.4699229971675</lat>
   <lon>-0.45367874251784013</lon>
   <name_tip>London</name_tip>
   <title_tip><![CDATA[London]]></title_tip>
   <content_tip><![CDATA[London Airport.]]></content_tip>
  </location>

 </map_xml>

Step 17: Loading the XML

We need to get the XML data into our flash movie. To do so we need to create a new function that will load our xml. Add
this piece of code to the bottom of the script. Inside our onMapReady() function we call this new load_xml() function. Once our map is ready we will start loading the xml.

        // Function that will load the xml
    	function loadXML(e:Event):void
        {
	        XML.ignoreWhitespace = true;
	        var map_xml:XML = new XML(e.target.data);
        }

        function load_xml()
        {
			var xmlLoader:URLLoader = new URLLoader();
			xmlLoader.addEventListener(Event.COMPLETE, loadXML);
			xmlLoader.load(new URLRequest("locations.xml"));
		}
    

Step 18: Loop Through the Locations

As we have 3 locations in our XML file we’ll need to create a “For” loop and store all the data in some Arrays. Inside our
loadXML() function we add this piece of code to create the For loop:

    	for (var i:Number = 0; i < map_xml.location.length(); i++)
        {
		    trace(map_xml.location[i].title_tip);
	    }
    

If we test our movie now we can see our movie outputs the xml data. Now let’s work with it.

Step 19: Create the Variables

Next we have to create some variables to store our data loaded from the XML file. Inside our For loop we add these variables:

    	var latlng:LatLng = new LatLng(map_xml.location[i].lat, map_xml.location[i].lon);
		var tip = map_xml.location[i].name_tip;
		var myTitle:String = map_xml.location[i].title_tip;
		var myContent:String = map_xml.location[i].content_tip;
    

You can delete the “trace()” line we used before as we know things are working.

Step 20: Adding the Markers on the Map

Now that we have all of our xml data stored in variables we can get over to load our markers onto the map. First we add some extra classes to our code. Add this piece of code under the other classes:

    	import com.google.maps.overlays.*;
		import com.google.maps.InfoWindowOptions;
        import com.google.maps.MapMouseEvent;
    

Create a new function called createMarker(). We want to add this function just before our loadXML() function.

    	// Add Markers On The Map
        function createMarker(latlng:LatLng, number:Number, tip, myTitle, myContent):Marker
        {
            var i:Marker = new Marker(
									  latlng,
									  new MarkerOptions({
                                                             hasShadow: true,
				                                             tooltip: ""+tip
                                                       })
									 );
            return i;
        }
    

We can call the createMarker() function for every marker we need to add to the map, so inside our For Loop we add this line of code:

    	map.addOverlay(createMarker(latlng, i, tip, myTitle, myContent));
    

If you test the movie now you can see that we have markers on our map on the locations we specified in our xml file! That’s great, but we didn’t create that great custom marker for nothing did we? We’ll remove those standard markers and add our custom markers.

Step 21: Add Custom Marker

First we need to create our custom marker object. Add this code into the createMarker() function, above the rest of the code:

    	// create Custom marker object
        var markerPin:marker_mc = new marker_mc();
        // If your marker is to big you can scale it down here
	    markerPin.width = 20;
	    markerPin.height = 20;
    

Afterwards, we’ll go to the next piece of code where we have to add a line to the markerOptions. Search for this piece of code:

    	new MarkerOptions({
                               hasShadow: true,
				               tooltip: ""+tip
                         })
    

and change it to:

    	new MarkerOptions({
                               hasShadow: true,
                               icon: this.addChild(markerPin),
				               tooltip: ""+tip
                         })
    

Ok! Test your movie and check the result!

Step 22: Moving On

OK, what’s next? The Info windows! When we click our marker we need to get the information we added to our XML file.Before we add the information windows I just want to remove that ugly yellow line around our map, have you noticed already? When you focus on the map it shows a yellow line around it. I personally really don’t like that, so let’s remove it. Just add this line of code under our variables section:

    	// No focus line
        stage.stageFocusRect = false;
    

Ok thats done! Let’s add Info windows. Add a little more code to our createMarker() function:

    	i.addEventListener(MapMouseEvent.CLICK, function(event:MapMouseEvent):void
        {
            map.openInfoWindow(event.latLng, new InfoWindowOptions({
                                                                        titleHTML: ""+myTitle,
                                                                        contentHTML: ""+myContent
                                                                   }));

		});
    

This is what our createMarker() function now looks like:

    	function createMarker(latlng:LatLng, number:Number, tip, myTitle, myContent):Marker
		{
			// create Custom marker object
			var markerPin:marker_mc = new marker_mc();
			// If your marker is to big you can scale it down here
			markerPin.width = 20;
			markerPin.height = 20;

			var i:Marker = new Marker(
							  		latlng,
							  		new MarkerOptions({
														    hasShadow: true,
															icon: this.addChild(markerPin),
				            		                        tooltip: ""+tip
                    		                           })
									 );
			i.addEventListener(MapMouseEvent.CLICK, function(event:MapMouseEvent):void
    		{
				map.openInfoWindow(event.latLng, new InfoWindowOptions({
																	       titleHTML: ""+myTitle,
                    		                                               contentHTML: ""+myContent
            		                                                  }));

    		});
			return i;
		}
    

Test your movie and you will now have info windows too.

Step 23: Complete Code

Well thats it! Congratulations, you just created a Google Map With 3D navigation and Custom markers! Very good job! Let’s have a
final look at our code:

    	import com.google.maps.LatLng;
import com.google.maps.Map;
import com.google.maps.Map3D;
import com.google.maps.MapEvent;
import com.google.maps.MapType;
import com.google.maps.View;
import com.google.maps.geom.Attitude;
import com.google.maps.controls.NavigationControl;
import com.google.maps.controls.MapTypeControl;
import com.google.maps.controls.OverviewMapControl;
import com.google.maps.overlays.*;
import com.google.maps.InfoWindowOptions;
import com.google.maps.MapMouseEvent; 

// Variables
var map:Map3D;

// No focus line
stage.stageFocusRect = false; 

// Call the function to create the map
add_map();

// Function that adds the map on stage
function add_map()
{
	map = new Map3D();
    map.key = 'YOUR_API_KEY_HERE';
	map.setSize(new Point(stage.stageWidth, stage.stageHeight));
    map.addEventListener(MapEvent.MAP_READY, onMapReady);
    this.addChild(map);
}

// Function that will fire once map is created
function onMapReady(event:MapEvent):void
{
	map.setCenter(new LatLng(50.899197766773284, 4.486040573103489), 13);
	map.viewMode = View.VIEWMODE_PERSPECTIVE;
	map.setAttitude(new Attitude(20,40,0));
	map.addControl(new MapTypeControl());
    map.addControl(new OverviewMapControl());
    map.addControl(new NavigationControl());

	// Load the xml
	load_xml();
}

// Add Markers On The Map
function createMarker(latlng:LatLng, number:Number, tip, myTitle, myContent):Marker
{
	// create Custom marker object
	var markerPin:marker_mc = new marker_mc();
	// If your marker is to big you can scale it down here
	markerPin.width = 20;
	markerPin.height = 20;

	var i:Marker = new Marker(
							  latlng,
							  new MarkerOptions({
												    hasShadow: true,
													icon: this.addChild(markerPin),
				                                    tooltip: ""+tip
                                               })
							 );
	i.addEventListener(MapMouseEvent.CLICK, function(event:MapMouseEvent):void
    {
		map.openInfoWindow(event.latLng, new InfoWindowOptions({
															       titleHTML: ""+myTitle,
                                                                   contentHTML: ""+myContent
                                                              }));

    });
	return i;
}

// Function that will load the xml
function loadXML(e:Event):void
{
	XML.ignoreWhitespace = true;
    var map_xml:XML = new XML(e.target.data);
	for (var i:Number = 0; i < map_xml.location.length(); i++)
	{
		var latlng:LatLng = new LatLng(map_xml.location[i].lat, map_xml.location[i].lon);
		var tip = map_xml.location[i].name_tip;
		var myTitle:String = map_xml.location[i].title_tip;
		var myContent:String = map_xml.location[i].content_tip;

		map.addOverlay(createMarker(latlng, i, tip, myTitle, myContent));
	}
}

function load_xml()
{
	var xmlLoader:URLLoader = new URLLoader();
	xmlLoader.addEventListener(Event.COMPLETE, loadXML);
	xmlLoader.load(new URLRequest("locations.xml"));
}
    

Conclusion

You can use this map on your website, edit the locations as you want, it’s up to you. Go ahead and experiment, if you have any cool results be sure to share them with us.

I hope you liked this tutorial, thanks for reading!

Niels Musschoot is tunafish on Activeden
Add Comment

Discussion 48 Comments

  1. reno says:

    Now that is very useful

  2. André says:

    Just what i was needing!!!
    THANKS!!!!

  3. App Sheriff says:

    Love this tip man…. I already started this project…looks like a lengthy work.

  4. Cool, I’m working something similar with some AIR features check this link http://www.pelicanresort.com/labs/mapa.html

    • emad says:

      Hey buddy i can borrows your map, but everytime i want to run my swf file, flash player says, its unsafe to run this file… i changed the security settings but it still wont work, what should i do?

  5. Juan says:

    Hi, so i cant use the Google Maps API local?

    I want to use it in a flash projector, is there something i can do?

    Thanks.

  6. andrea says:

    Both these tutorials have been great!!
    Do you have any tips on getting images into the info window?
    Thanks

    • Andrea if you can use the xml load your image as html code like this:

      <![CDATA[Donec ac turpis vel odio adipiscing semper. Maecenas dolor lectus, lobortis nec faucibus in, sodales in justo. Aliquam erat volutpat. In quis sem ipsum. Nulla ac nibh ac dui condimentum posuere id sed enim.]]>

  7. Graveto says:

    Thank you for the great tut. Here my result:
    http://annettes.alfahosting.org/MLI/?page_id=257

  8. Thanks for this great tutorial. One problem though, the 3D view doesn’t seem to work.
    I can adjust pitch, roll, yaw all I want but the image remains 2D.
    I have exactly copied the example!
    No idea what’s happening!

  9. Oh wait I see the mistake : in the tutorial above point 13 the line “map.viewMode = View.VIEWMODE_PERSPECTIVE; ” is missing. Later in the code the line suddenly appears and then the 3D view is working.
    Cheers!

  10. mina says:

    great tut. Can you show me how to embed video on the infor box. thanks very much.

  11. jmarreros says:

    In Flash CS4 (mac), you have to find this path, in order to paste the component

    Applications/Adobe Flash CS4/Common/Configuration/Components

    Thanks for this useful tutorial.

  12. Jerry says:

    Demo link broken. API key failed.

  13. hmm – nice, but the demo isn;t working here

  14. Lorenz says:

    Nice tutorial..thanx..

  15. awesome tutorial Neils. there are some problems with 3D but I’ve solve it.

  16. Man… That a owe ones..

  17. Cool! I can wait any longer to implement this, thanks!..
    Btw, the demo isn’t working, i’ve got an error message: “Initialization failed: please check the API key,
    swf location, version and network availability.”
    Whats happening?
    I’m waiting for your next post :) Thankyou

  18. Vasco Silva says:

    Great tutorial.

    One question- It’s possible to insert a xml image galerie or other movie clips inside the infoWindow ?

    • Roy says:

      I will like to get some info from that as well. I was wondering if the flash GoogleMaps is more advanced as the Java GoogleMaps. In the infowindow i would also like to insert pictures and video’s imported via xml.

      I hope someone can help us with this.

  19. Ankit says:

    Hi,

    Thank you so much for the wonderful tutorial.

    I wan to know one thing here for website we can get the API Key. But if i want to run it in my local system then what should i need to do each time i can’t render the FLA file i want some solution…. like if i open swf file it should work. is that possible?

  20. B Long says:

    Works perfectly. I’m not that advanced in flash and i was able to create a custom map. Thanks

  21. Vasco Silva says:

    Hi, how can I add different markers?

  22. Apelsin says:

    Hi,

    Thank you for the wonderful tutorial, works perfectly.

    How can I add two different markers in the same map? Example: One square marker and other circle marker?

    • Erick says:

      The best thing to do would be to add the icon via your xml document, and pull them from an xmlList

      so your xml doc would have something like this:

      89.3647352
      -90.4848484
      images/google/icon1.png
      ………

      95.46573
      -90.4848484
      images/google/icon2.png
      ……….

      ..

      so in AS create a new xml and xmlList

      xml :XML = new XML(e.target.data);
      xmlList:XMLList = new XMLList(xml.children();)

      and the for loop would look something like this

      for(var i:int = 0; i < xmlList.length(); i++)
      {
      //pull that damn icon!
      var icons:Bitmap = xmlList[i].icon as Bitmap
      //and expirement
      }

      ..actually this is just an idea . :-P

  23. magron says:

    looks like the API key from demo is broken again : /
    best regards!!

  24. James says:

    I am trying to add interactive maps to my web site, I am currently running the 2d verision from the previous tutorial. I was playing with this 3D tutorial and was trying to figure out how to get this to load different map markers/xml’s.. I am not a programmer but can manipulate code somewhat, so I am stuck.
    ie.
    Load places.xml (show marker “marker_places)
    Load food.xml (show marker “marker_food)
    Load ramp.xml (showmarker “marker_ramp)
    Load fish.xml (showmarker :marker_fish)

    also is there anyway to link right from the marker?

    any help woud be greately appreciated; jwjennison@yahoo.com

  25. brandon says:

    Thanks for the great tutorial. Does anyone know how to add the google street view-eye level street view
    in flash? Any help would be appreciated.
    Brandon

  26. josefina venegas says:

    Hello: Thanks a lot!

    I appreciate this example, i would like to see some, showing only one marker since a list like a data grid one by one using an xml, that can be posible?

  27. Victor says:

    Hi, excellent tutorial!

    I’m kind of a newbie on this, but is it possible to add a preloader to the map?

    tnx!

  28. Andrew says:

    I would really like to add the street view. Has anybody done this yet?

  29. Jon says:

    Hey man, this is a great tutorial! Thanks so much for sharing your experience using the API. I had a quick question though. I got to step 20 “Adding the Markers on the Map” and I’m getting 2 errors:

    1) For this line:
    – map.addOverlay(createMarker(latlng, i, tip, myTitle, myContent));
    I am getting the error:
    – 1067: Implicit coercion of a value of type Marker to an unrelated type com.google.maps.interfaces:IOverlay.

  30. Jon says:

    Looks like i got cut off. So the second error I’m receiving is at this line:
    – var i:Marker = new Marker(latlng, new MarkerOptions({hasShadow:true, tooltip:”"+tip}));
    I’m getting the error:
    – 1136: Incorrect number of arguments. Expected 0.

  31. fatih says:

    google as2 flash maps pleass

  32. gowtham says:

    HI this is a great tutorial ! and pls help me how to put kmz file in to google 3d maps,

    • Ali says:

      Hi !
      Nice tut ,Actually I want to make my country as a default location means when I compile the fla then my country’s location should be showed.Can somebody please help me ?

  33. Chronodevis says:

    Good morning
    You can set the xml file also the size of the map
    map.setSize(new Point(stage.stageWidth, stage.stageHeight));
    instead of using the default size?
    thanks

  34. Carl says:

    Just what I’ve been searching for! Thanks Niels for making this tut!

  35. michael says:

    can this script handle Google steertview

  36. emad says:

    hi
    my flash player 10 wont play the swf, it says becuse its unsafe… i changed the security settings but it wont be open
    what should i do?

  37. makii says:

    Hi,

    Great tutorial thx! Can I add a sidebar like this one shown on the google api page:

    http://gmaps-samples-flash.googlecode.com/svn/trunk/demos/SidebarOnMap/SidebarOnMap.html

  38. Elise says:

    Excellent tutorial :-)
    is there anyone who can tell me how I can change font size and maybe color?

Add a Comment

To add a code snippet to your comment, please wrap your code like so: <pre name="code" class="html">YOUR CODE</pre>. You can replace the class name with "js," "css," "sql," or "php." If there are any "<" or ">" within your code, please search and replace them with: &lt; and &gt; respectively.