Jump to content
MakeWebGames

Basic Ajax is easy


Floydian

Recommended Posts

You're saying to yourself, no it isn't. lol

But yes it is!

I'm feeling a bit lazy, so I'm not going to blog all over this post about what's happening here. However, take these three scripts, save them and put them all in the same folder on your local web server, or your remote web host. Then load up the html file and see ajax magic happening before you eyes.

These three files are about as stripped down an ajax object can be. Enjoy!

 

Name this file: ajax_test.html

<html>
<head>
<script src="ajax.js"></script>
</head>
<body>
<div align="center">
<table>
<tr>
	<th>
	<h2>Ajax Testing</h2>
	</th>
</tr>
<tr>
	<td>
	<ul>
		[*]
		[url="javascript:js_function_1('do_1')"]Option 1[/url]

		[*]
		[url="javascript:js_function_1('do_2')"]Option 2[/url]

		[*]
		[url="javascript:js_function_1('do_3')"]Option 3[/url]

		[*]
		[url="javascript:js_function_1('do_4')"]Option 4[/url]

		[*]
		[url="javascript:js_function_1('do_5')"]Option 5[/url]

	[/list]
	</td>
</tr>
</table>

<span id="ajax_output">
All ajax output is sent here.
</span>

</div>
</body>
</html>

 

Name this file: ajax.js

// create the Ajax request object.
// This function NEVER needs to be modified.
function ajax_create() {
var ajax = false;
// initialize the object:

// Choose object type based upon what's supported:
if (window.XMLHttpRequest) {


	// IE 7, Mozilla, Safari, Firefox, Opera, most browsers:
	ajax = new XMLHttpRequest();
	return ajax

} else if (window.ActiveXObject) { // Older IE browsers

	// Create type Msxml2.XMLHTTP, if possible:
	try {
		ajax = new ActiveXObject("Msxml2.XMLHTTP");
		return ajax
	} catch (e1) { // Create the older type instead:
		try {
			ajax = new ActiveXObject("Microsoft.XMLHTTP");
			return ajax
		} catch (e2) {}
	}

}

// Send an alert if the object wasn't created.
if (!ajax) {
	alert ('Some page functionality is unavailable.');
}

}




// This function is what is called when the user clicks the link, and it uses the function above
// with the ajax1 = ajax_create() line.
function js_function_1(submission) {

ajax_object = ajax_create()
// Confirm that the object is usable:
if (ajax_object) {

	// Call the PHP script.
	// Use the GET method.
	// Pass the username in the URL.
	ajax_object.open('get', './do_ajax.php?action='+encodeURIComponent(submission));

	// Function that handles the responce:
	ajax_object.onreadystatechange = function() {
		if (ajax_object.readyState == 4 && ajax_object.status == 200) {
			handle_check()
		}
	}

	// Send the request:
	ajax_object.send(null);

} else { // Can't use Ajax!
	document.getElementById('ajax_output').innerHTML = 'Please file a bug tracker report.';
}

} // End of js_function_1() function.

// Function that handles the response from the PHP script:
function handle_check() {

// Assign the returned value to a document element:
document.getElementById('ajax_output').innerHTML = ajax_object.responseText;

} // End of the handle_check() function.

 

Name this file: do_ajax.php

<?php

function do_1() {
echo "This is the first function in the php file called by the ajax javascript.";
}

function do_2() {
echo "This is the second function in the php file called by the ajax javascript.";
}

function do_3() {
echo "This is the third function in the php file called by the ajax javascript.";
}

function do_4() {
echo "This is the fourth function in the php file called by the ajax javascript.";
}

function do_5() {
echo "This is the fifth function in the php file called by the ajax javascript.";
}

switch ($_REQUEST['action']) {
case 'do_1': do_1(); break;
case 'do_2': do_2(); break;
case 'do_3': do_3(); break;
case 'do_4': do_4(); break;
case 'do_5': do_5(); break;
}

?>
Link to comment
Share on other sites

Re: Basic Ajax is easy

I'm a bit curious. I've seen games that use ajax, and games that don't. I know for a fact that mccodes doesn't come with anything that uses ajax by default. Personally, I think ajax can be used to greatly improve the usability and user friendliness of a web page.

One of the big benefits of ajax over some other technologies like say, java, flash, and others is that ajax is essentially javascript. This means that every major browser supports ajax out of the box. It costs nothing to get started developing an ajax application. Whereas buying a flash editor can be hella expensive. There are free java editors out there, and one good one comes with the eclipse platform. However, java is considerably harder than ajax to implement, and again, requires that your users have downloaded java to their computers.

So, my curiosity is this: does ajax seem like it's something that is too difficult to implement? Do people prefer to just have static web pages? Or perhaps, maybe understanding where ajax can be of use is the problem?

Or perhaps there is no problem, and everyone understands and is using ajax already ^__^

Just wondering. I've seen many an ajax tutorial out there, and while they explain how to make an ajax request, I haven't seen one that really provides a usable example. I was hoping that my example would be something people could use right away with just a little bit of modification. Mainly the html file would have to have the header and footer content you want, and the php file would have to contain the dynamic content you wish to display.

Link to comment
Share on other sites

Re: Basic Ajax is easy

redesign of static page to work with AJAX is usually not so easy ... It's easy as long as

one wants to fetch complete static page, but splitting that page to many smaller ones and

relinking can be huge job ... Same goes for dynamic pages because one must modify most

server-side scripts in order not to pull complete page ... AJAX is elegant and works great

but for that to be easily done it's better to design with AJAX in mind from start!

Where I find AJAX very useful is reducing number of server requests ... That goes for pages

that are accessed for the first time and for already loaded pages ... First time accessed

pages can be much smaller, with less external components that browser must request to

show page properly ... On any user's click or data submit, nothing but 1 request is sent ...

Ordinary way it would be 1 request and complete .html download, than checking if external

components have been changed on server (that might be 10+ request easy) ... If we are

considering server under heavy load than using AJAX usualy means keeping server as is

instead of upgrading to better one!

Link to comment
Share on other sites

Re: Basic Ajax is easy

I have to disagree with you on some of that. You talk about static pages with one ajax object as if that's entirely limiting. You're so wrong about that.

I've done numerous pages with ajax, and one can do all sorts of things with that one object.

Consider a hall of fame. With the script I've made, each of those links could be one hall of fame list. the list would then pop up super fast with no page loads. I can think of many places where ajax is useful. Less than 25% of my game uses ajax though, and that's because it's not the end all be all.

But you're simply not accurate at all about the one object being limiting. If you pass a id field to the ajax object, you can nest ajax objects with ease.

Just thing, click on link 1, it presents you with options for link a, b and c, and also outputs an empty span with a new id, "ajax_output2"

You then click on link b, and it outputs the ajax results into that new span. All this is done with one ajax creation function, one ajax object request function, and one ajax return function. you could easily nest these ad infinitum.

Of course, if one doesn't explore this functionality, one will never discover the depth of what can be done.

I set up that simple script in two minutes, maybe one. It's so easy, how could people not use it?

Link to comment
Share on other sites

Guest Anonymous

Re: Basic Ajax is easy

Now that's interesting Floydian... I never though about ajax returning hooks for other ajax entities...

[me=Nyna]slopes off to rewrite <insert several domains>.com ... :D[/me]

Link to comment
Share on other sites

Re: Basic Ajax is easy

I've had to come up with several interesting methods of working around some of the quirks of asynchronous javascript requests.

Most of the times I load up my main ajax function with about 5 or 6 arguments, and pass 0's to them in the event that later on down the road, I might need the extra space, and editing every function call to add in the arguments is a pain.

So, each function call would be something like this:

javascript:self.ajax_function('id name of the output', 'switch: what function do we want the file to run?', 'parameter 1', 'parameter 2', 'parameter 3', 'paremeter 4')

And I can easily have a container page, and a function page, loading all my dynamic content anywhere on the container screen I want. No JSON required for this. Of course, each call to the ajax function will fill only one "portal".

And if I want more portals at once, I might do like I did with my russian roulette script that updates 4 portals at once every second. Yes this means four scripts being called, but it's a pretty lean script, and it'll be cached on the server, so it runs very smooth. Just ask the folks on coveofpirates.com and aeonsea.com where this russian roulette script resides. No this script isn't for sale lol.

 

function multi_loader() {

// note that I forget the exact syntax here (I copy a lot of javascript function names)

set_time_out('blah1', 1000)

set_time_out('blah2', 1000)

set_time_out('blah3', 1000)

set_time_out('blah4', 1000)

}

Now, I can have four things on a page updating every second.

Doing this has it's limitations. the functions are called with no arguments. so you have to make a function for each one. okay, that's not too hard. but this also means it's only good for making something update, which in russian roullete, we want to see who comes into the room, who is playing a game, and what round/ who's turn, and the status of those games.

The actual game play is handled through links like the one above. ;)

This is all based on the functions I've pasted in the first post. It's difficult to choreograph all that crap, but I'm suggesting that the basics of ajax are simple, and easy to do.

Link to comment
Share on other sites

Re: Basic Ajax is easy

 

I have to disagree with you on some of that. You talk about static pages with one ajax object as if that's entirely limiting. You're so wrong about that.

I've done numerous pages with ajax, and one can do all sorts of things with that one object.

Consider a hall of fame. With the script I've made, each of those links could be one hall of fame list. the list would then pop up super fast with no page loads. I can think of many places where ajax is useful. Less than 25% of my game uses ajax though, and that's because it's not the end all be all.

But you're simply not accurate at all about the one object being limiting. If you pass a id field to the ajax object, you can nest ajax objects with ease.

Just thing, click on link 1, it presents you with options for link a, b and c, and also outputs an empty span with a new id, "ajax_output2"

You then click on link b, and it outputs the ajax results into that new span. All this is done with one ajax creation function, one ajax object request function, and one ajax return function. you could easily nest these ad infinitum.

Of course, if one doesn't explore this functionality, one will never discover the depth of what can be done.

I set up that simple script in two minutes, maybe one. It's so easy, how could people not use it?

I'm not speaking about number of AJAX objects but about redesign of let's say 200kB text one-page

blog or AJAX-ing CMS sort of stuff ... While AJAX itself is truly easy, redesign of existing pages might

be a nightmare (my friend tried AJAX-ing his huge PHPNuke web site but gave up after 1 month)!

Link to comment
Share on other sites

Re: Basic Ajax is easy

I can certainly agree with you in that, if it isn't broke, don't fix it. That maxim has saved many a person many a gray hair. I have gone back to some older scripts of mine and added in ajax functionality to them with success though. I would definitely recommend getting experience writing simple ajax scripts first though, before really getting into it.

Link to comment
Share on other sites

  • 2 months later...

Re: Basic Ajax is easy

OK, i'm having quite a few problems with this and looking for a bit of help or to be pointed in the right direction :wink:

First off you should know im not that good with Java Script and am new to AJAX but i have got AJAX working to refresh the user stats when needed so i am learning

I've been trying to change the function js_function_1(submission)and ajax_object.open()

So that i can use it to reload the map and move the user when clicking a link, currently i and using $_GET with an example of the link being map.php?move=1&x=7&y=0 There are a number of link to move the user in which the 'x' and 'y' only change, 'move' stays as 1

Im not sure if i can add the GET info on to the file im opening with AJAX as done with a normal link as i can't get that to work .... and if that could be done, could the (submission) be changed to contain this info?

 

Any help at all would be great :-)

Link to comment
Share on other sites

Re: Basic Ajax is easy

good question Jeff

Here's how you do this. I'm going to take all of the old comments out, and comment the places where I change this function, and then explain them in a bit more detail after I show the example.

 

 

// <?php PLEASE NOTE THAT THE PHP TAGS ARE ADDED IN ONLY TO FORCE COLORIZING OF THE CODE. ;)

// Add in more parameters to the function.
function js_function_1(submission, var1, var2, var3) {

ajax_object = ajax_create()
if (ajax_object) {

               // Add on to the end of this by concatenating the new parameters you have passed.
	ajax_object.open('get', './do_ajax.php?action='+encodeURIComponent(submission)+'&var1='+encodeURIComponent(var1)+'&var2='+encodeURIComponent(var2)+'&var3='+encodeURIComponent(var3));

	ajax_object.onreadystatechange = function() {
		if (ajax_object.readyState == 4 && ajax_object.status == 200) {
			handle_check()
		}
	}

	ajax_object.send(null);

} else {
	document.getElementById('ajax_output').innerHTML = 'Please file a bug tracker report.';
}

} // End of js_function_1() function.

// ?> PLEASE NOTE THAT THE PHP TAGS ARE ADDED IN ONLY TO FORCE COLORIZING OF THE CODE. ;)

 

The first thing we have to do is make room for the function to accept more parameters besides the "submission" parameter.

function js_function_1(submission, var1, var2, var3) {

We've added in three more, in this case.

You can pass these to the function by writing your a href as follows:

Click here to move on the map.

We are only using submission, var1, and var2. In javascript, that's okay. var3 doesn't require that anything be passed to it.

____________________________________________

Now that we're passing the values we want to pass to the function, we have to submit them via an ajax object, i.e., ajax_object.open()

ajax_object.open('get', './do_ajax.php?action='+encodeURIComponent(submission)+'&var1='+encodeURIComponent(var1)+'&var2='+encodeURIComponent(var2)+'&var3='+encodeURIComponent(var3));

We've added on a few things here. encodeURIComponent is basically the same thing as PHP's url_encode(). It formats a string into an acceptable URL format.

This string could be written out a bit shorter, and perhaps it might make it more clear what is going on.

ajax_object.open('get', './do_ajax.php?action='+submission+'&var1='+var1+'&var2='+var2+'&var3='+var3);

 

We've taken out all of the encodeURIComponent functions for demonstration purposes only.

We can strip it down a bit more.

'./do_ajax.php?action=' + submission + '&var1=' + var1 + '&var2=' + var2 + '&var3=' + var3

See how we're building a URL? We can add in more variables if we need to. I think GET has a limit of 100 characters, so keep that in mind. You can do POST, but it's a bit more difficult.

Does that clear it up a bit?

Link to comment
Share on other sites

  • 3 weeks later...

Re: Basic Ajax is easy

Well one of the best tips I've ever read, and learnt myself, about AJAX is to only use it where it can actually improve the interface - do something good for the website. For example when I first learnt about Javascript 10 years ago or so, I had flying effects all over my page... then just a couple of years ago when I learnt about AJAX I had it in place everywhere - but for no real significant reason. Now I tend to use it only in "required" places, not many places where it could easily be replaced with one-way content.

Another tip of mine would be to take care of the none-Javascript clients. I know people who have plugins in their browser which disables any Javascript by default without explicity accepting a domain or address to enable Javascript. At bare minimum have a warning message, but in some cases it is possible to recreate simple effects that your Javascript carries out via other methods.. perhaps letting the user you know that if they enable Javascript there will be more functionality. Basically what we're looking at is in the <noscript> tag which many tend to forget when developing smaller websites.

A third tip would "simply" be security. Always think about the security of your scripts..

For example, I noticed the chatroom at an MMORPG (prisonstruggle.com) the other day was insecure.. because of badly written AJAX communication - between the Javascript and backend powered by PHP. Basically, the PHP script was firstly not checking for authentication, this meant if you were not logged in or banned, you could still post to chat. The worst part of this setup? The user ID to post as into the chat was sent from the Javascript to the PHP. There was some sort of "security" key at the start, which was always the same, followed by the users ID number. So, that was that.. you could post into chat as any user you wanted to without even having an account. Sure, this is only the chatroom, but what if the game developers chose to use AJAX technology at other features? Alot of insecurity due to poor development! Well done to prisonstruggle.com for since fixing this problem, but it's a perfect example of insecurity when developing AJAX applications.

Anyway, use it in the right place and AJAX can be great :)

Link to comment
Share on other sites

Re: Basic Ajax is easy

ST-Mike, there's many good points in there. I would add to it, and perhaps amend a few things.

Ajax is never required. Iframes make it possible to do most of what ajax can do. And there's always the possibility of just not having the functionality that ajax might provide. It's not absolutely necessary to warn a new user upon signing up that the username they choose is not available as soon as they type it in.

What's more important is that the form data is preserved once they submit the form. If there is an error, the data they typed in should be filled back into the form. And in that way, ajax is only a nicety.

Yeah, that could be considered nit picking ;) Like I said, just a slight amendment to what you were saying.

_______________________________

Your second tip I have an actual disagreement with.

However, I don't disagree entirely. The question one must ask themselves, should my site cater to everyone possible, at the expense of more advanced features supported by every major browser in existence for the last 6 years?

For the sake of argument, javascript is and has been supported by every major browser for a long time. People actually have to disable it. If people choose to take that route, should our site cater to that?

Ajax is entirely out of the question if you disable javascript. You probably noticed that the ajax script I provided does check if the browser supports three different means of creating an XHR Request. If none of the three will work, it alerts the user to this fact (I've never received a report of anyone getting this error). Of course that requires javascript to not be disabled.

So it boils down to what you want for your site. If you are going to cater to non javascript people, you should consider that anything that uses ajax will require that you provide a way to do the equivalent thing without ajax. This sort of thing can lead to hard to maintain websites and may not be worth it in the end. This usually means eliminating the use of ajax.

Some cases where I would want to do this would be sites intended for informational purposes where it is expected that your users will be stuck in the past. Perhaps a site dedicated Geriatrics?

It's my opinion that anyone that wants to play games online should have javascript enabled. HTML by itself is intended to be a means of text transfer, not a means for generating dynamic web pages.

One big reason people disable javascript is because they believe javascript to be a security issue. It would only be a security issue if the site you're visiting is allowing malicous users to post javascript, or if the website itself is posting malicous javascript code, and even then, browsers are very very good a keeping users safe. After all, if they can't keep their users happy and safe, they lose market share.

Beginning in FireFox 3, mozilla has disabled cross domain XHR Requests. This has been disabled in IE and Opera for some time now. There are major security concerns where websites make use of remote server javascript.

To sum all of that up, javascript is not inherently unsafe. Simply being on the internet exposes your computer to the world. Therefore, if one wants to be paranoid about it, they shouldn't be on the internet at all.

One big argument in favor of javascript is that Google and Yahoo are BIG proponents of using javascript on their pages.

Yahoo mail beta is entirely generated from javascript. Turn off javascript, and Yahoo mail beta will do nothing!

Google's gmail is ajax based and won't work without javascript.

The main area in my mind where javascript legitimately not an option in many cases is mobile phones. Newer phones do have javascript enabled browsers, but many phones can't handle javascript at all.

If you're going to make your game 100% mobile compatible, it's highly recommended that you setup a mobil subdomain and create pages designed to work well with phones.

 

To sum up what I'm saying here, suggesting to people that they should be cautioned about their use of javascript is like telling people they should be cautioned against using any sort of images because of Lynx and people that still use text only browsers...

It really isn't something people should be concerned about in conjunction with a game site. Geriatrics, perhaps, but not php powered games...

-----------------

As for the chat room example, that amounts to nothing more than an anecdotal account of one instance where someone got their stuff wrong. It has nothing really to do with ajax, at least fundamentally.

Any time you're dealing with logins, you're dealing with security. Whether your site uses ajax, or not, security is going to be a concern and people get that wrong all the time.

Some bank had millions of credit card number compromised a few days ago. Now that's a big deal there! You know banks are paying big money to have secure systems installed, and yet, they have problems too. So while I agree with most of what you've said, I think the subject matter you've brought up really doesn't apply to ajax, and the topic "Basic ajax is easy!". In other words, nothing you've said has made what I've stated in the original post any more difficult than it was before. The cautionary words really apply better to a discussion on browser security than basic entry level ajax.

Link to comment
Share on other sites

Re: Basic Ajax is easy

Yeah, I dun think there is any question that javascript is here to stay for the foreseeable future.

In fact, I think javascript is so important for web design that I'd caution anyone that wants to be a web programmer to not overlook javascript.

The worst thing about javascript though are the tutorials.

I saw one that said document.write is the chief way to output data to the screen! What a load of crap... document.write is one of the worst ways to output data to the screen!

And most tutorials completely miss the fact that javascript is an object oriented language. One tutorial said you could have strings, numbers and arrays for data types, completely missing objects!!!!

And that summarizes the state of javascript with most people: MISUNDERSTOOD

Link to comment
Share on other sites

  • 3 months later...

Re: Basic Ajax is easy

Yes, ajax is confusing. Anyone that says it wasn't confusing to them at first is either lying or is a genius.

Expanding on what BlueDevil said about AJAX being JS, which is right, ajax is built on the HMLHttpRequest object.

That is actually part of the part of the DOM (Document Object Modal). JavaScript is granted access to the DOM and thus has access to the XMLHttpRequest object.

The main technologies involved in AJAX are typically: JavaScript and XML or JSON

JSON is JavaScript, but JavaScript is not JSON. JSON stands for JavaScript Object Notation, and JSON data can be parsed using JavaScript's eval() function.

Therefore, if you use JSON instead of XML, your AJAX app is entirely DOM and JavaScript based. That would make it AJA, instead of AJAX ;)

lol

But we still call it AJAX. Old habits die hard...

Anyways, I use asynchronous JavaScript and never did get into the XML part of it.

Even the name of the XMLHttpRequest object might be due for a change, removing the XML part of it.

Okay, did I bore anyone? :P

Link to comment
Share on other sites

  • 3 weeks later...

Re: Basic Ajax is easy

I wanted to relay a bit of my own experience with AJAX....

First try to go with JSON and skip learning / using XML. XML with Javascript is a REAL pain in the butt to parse though. I started with XML and was writing more parsing routines then actually writing the meat of the game / interface.

I would look at using a javascript library, it has made coding AJAX and javascript so much easier and more importantly faster. Floydian in his other post used YUI while I've used that in the past (and still do in some places) I found it difficult to work with as it really is ever changing and VERY heavy (file size wise). This is personal preference so do some research before committing to a javascript library as they are not very interchangeable so when you start down the path of using one switching to a new one can be very costly in coding time.

I'm currently using Prototype, again personal preference and it suited my needs at the time.

Now for some shameless promotion.. With the Prototype engine, a lot of AJAX and a lot of hair pulled out we are getting ready to release a game called CyberStryke. Since it's a very graphical and interactive game we've posted a little video of the game in action which you can view here. Yes the demo is somewhat confusing we will be releasing another one soon with captions, sounds etc to better explain what is going on. It does though show how far you can push web technology with AJAX and truely become a very interactive experience for game players.

Link to comment
Share on other sites

Re: Basic Ajax is easy

Yeah, using a library makes things a lot easier, especially if you're going to do more than just load up one little thing using ajax. Once you get into building a rich web app with multiple ajax deals, a library is almost a must...

As for the page weight of yahoo modules, I'd have to disagree on that one, at least to an extent. Certainly, if one included a bunch of YUI widgets, drag drop, animation, buttons, RTE, and the list goes on and on, the page weight is going to be heavy, but if you're just going for the ajax, the page weight is low.

Combine that with YUI's dependency configurator which will allow js files to be combined into one HTTP request, and css files to be combined as well, the page weight goes down a lot.

I don't have exact stats on YUI 2.6.0 page weight for just the ajax module, but in YUI 3 beta 2, the configurator shows the exact weight of the inclues which would be:

30kb if you're using the min files/gzipped

That's basically one image. And with that you get Dom, Event, IO (ajax), and JSON modules.

Dom gives you all the Dom manipulation goodies, Event allows you to add event listeners in a cross browser way effortlessly, and the YUI global object has a bunch of other niceties that you all get for free whenever you use YUI.

I don't know the page weights for other libraries, but YUI is pretty good there. And let's not forget the tons of web sites that use YUI as well. Even cpanel makes extensive use of YUI. ;)

The Yahoo site itself makes very heavy use of YUI throught. Mail beta is almost entirely YUI, as well.

But with that said, for the person that wants the smallest page weight, you'd have to custom write all your js code, then minify it as well. Then you have to host it yourself.

And getting all the functionality of YUI 3 beta 2 with the ajax module and it's required dependencies at a page weight of 30kb min/gzipped would be a challenge for sure.

Link to comment
Share on other sites

Re: Basic Ajax is easy

Yes I used (and still do) YUI for the widget factor, specifically there ajax data table, damn it's just so nice :) Pain in the butt though to understand and work with the CSS (IMHO).

Plus, like I said, they come out with updates fast which normally is a good thing but I was bit twice now by there updates. I do like that more and more sites are using it and when it gets to a stable release (stable meaning not so many rapid updates) it'll be great as it'll be cached.

Link to comment
Share on other sites

Re: Basic Ajax is easy

Are you using FireBug?

I've found that to make styling YUI much easier than trying to read over the documentation. To be sure though, it can take a lot of work to get styles for widgets.

The good thing is, once you have a widget styled to your liking, you can use that widget anywhere on your site with the same styles, so long as your styles just override yui-skin-sam and don't use #id identifiers.

And the #id identifiers of course enable page specific styling if needed. I do spend a lot of time styling those widgets though, the first time lol.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...