perkiset

...well, not entirely against

Ajax

 , but at least you checked out the thread...  Applause

People are overusing it, misusing it, don't understand it and are putting themselves at functional and security risk because they are deploying stuff they really don't understand. I'm going to endeavor to help with that.

AJAX

  of course stands for Asynchronous

Javascript

  and XML. Purists will tell you that the notion is multiple, lightweight requests running to the server to handle requests in an event-driven or asynchronous way that does not stop the natural flow of a website. Although I do not argue that this is one possibility, in many applications this style of coding is actually contrary to efficiency and in fact contrary to the way that a user would expect an application to operate.

This is, of course, the real rub:

Ajax

  can be a parlour trick, or a set of pasted-in snippets by n00bs intending to impress surfers, or it can be a functional outline for a method of converting a browser into the fascia for applications. Personally, I have given up anything that is OS or GUI specific. My only link to users now (via a GUI anyway) is browsers. I started this personal restriction in about 2000, but I had built all of my interfaces using a page-to-page methodology. My stuff always works in every browser I can get my hands on, which sometimes mean I am a slow adopter, but it also means that my stuff can be used by anyone on the web today. About 18 months ago I came to the conclusion that browsers were ready for

Ajax

  and so was I. I jumped in 100% feet first and have not looked back. People will tell you it is a different way of thinking: You need Ruby on Rails to do it. Baloney. It is to complicated, you need a handling framework - like the Java components. Bullshit. In this set of posts I will distill

Ajax

  down to the most simple elements and how to make them work, and additionally show some of the stuff that I think makes it so great, and in fact, one of the waves of the future.

First, let me address "Asynchronicity." It is an obvious plus when a website can make calls to a server inline with the users interaction to gain data and "help them out." One common demonstration of this is the "City/State/Zip" example, where you enter a zip and the city and state automatically come up, or perhaps you enter a state and all the possible cities come up to make sure you enter the right city/state/zip combination. There are times however when this is really a nuisance because the user does not necessarily know that something is going on, and the hiccup or delay in page response is seen as a problem rather than simply a

net

 work delay, which it most often is.

I assert that one of the most powerful things available is actually serialized or "blocking" operations – functions where the user understands clearly what is going on – functions that might take a moment but that the user has an investment in both getting done and knowing the progress of things. IMO, the most powerful part of

AJAX

  is not the trickiness of asynchronous server requests, but in fact making a web page behave more like an application - and therefore, sometimes, stopping the user in his/her tracks is the best way to go.

The second component,

Javascript

 , is the most correct yet misused portion of

Ajax

 . My travels around forums find people using the server to do almost all of the work - and the

javascript

  part for them is simply displaying results. I've seen huge forms, validated completely at the server rather than locally. In my opinion, the serious

Ajax

 xer should consider

Javascript

  a primary language and behave as if the entire application must be written in it. When this mindset takes hold, all of a sudden the appropriate time to "call home to the server" becomes abundantly clear and prodigeous back-and-forth packets drop out of the picture. I’ll address more

Javascript

  in a while.

The part I least like about

Ajax

  is the XML part. Not because I don’t like XML, in fact, the vast majority of intra-system communication is XML. It’s easy, RELATIVELY light (I’ll probably catch some flame for that one) and text editable. The part I don’t like is the rigidity of using this data structure, when at times it is the worst tool for the job. I’ll explain more in my next several posts.

What I’m going to post over the next several days is a series of images & code from one of my back-end frameworks, with graphical and design elements that I look forward to spurring discussion. I use a variety of techniques to get the job done, and I will certainly be flamed by some that would see consistency for the sake of consistency as superior to a Best Tool For The Job mindset. I look forward to debating it. The only tool I have not really employed in my current workings is iFrames because, to my thinking, I can do a superior job with an XMLHTTP requestor… but given cross-domain issues and HTTPS issues (see the other thread related to the 12030 error) there is DEFINITELY a place at the table for any iFrame experts to take their best shot at it.

I’ll hopefully get to my first example, Modal Operations, aka “Stay off the keyboard you dumbfish because I’m busy doing something” this evening. Don't be shy if you want to post right in line with my dissertations.

/p

nutballs

good brief overview.

I agree (i think thats what you were saying) that

AJAX

  is mostly used "just because" and in alot of situations makes little to no sense. especially when they put all the processing onto the server, and just use the

ajax

  as a display method. If i wanted a display system, i would use flash...

the whole reason i have yet to get into

ajax

  is because i SUCK at JS. I dont know why. for some reason, every time i try to take a stab at JS any deeper than copy-paste snippets, i get all screwed up and stuck. If i was just using

ajax

  for what most sites do, which is display, without putting much processing onto the client, it wouldnt be a problem.

But my reason for ever even being remotely interested in

ajax

  is to be able to build apps that put as much of the processing onto the client. its just my lack of enthusiasm wins out... lol

perkiset

quote author=nutballs link=topic=155.msg899#msg899 date=1178248411

I agree (i think thats what you were saying) that

AJAX

  is mostly used "just because" and in alot of situations makes little to no sense. especially when they put all the processing onto the server, and just use the

ajax

  as a display method. If i wanted a display system, i would use flash...

Yup - that's where I'm at. A great tool in the hands of morons, essentially.


quote author=nutballs link=topic=155.msg899#msg899 date=1178248411

the whole reason i have yet to get into

ajax

  is because i SUCK at JS. I dont know why. for some reason, every time i try to take a stab at JS any deeper than copy-paste snippets, i get all screwed up and stuck. If i was just using

ajax

  for what most sites do, which is display, without putting much processing onto the client, it wouldnt be a problem.

IMO you are far from the minority.

Javascript

  is a klunky, persnikety and idiosyncratic language. There was much howling and rending of shirts when I began

learn

 ing  it. However once you get the rhythm I think you might find it more normal than first imagined - although both the object/class framework of the language is funky and variable scoping is particularly weird. I think if you follow my posts here I can help you avoid a lot of the headaches and ruined shirts Applause


quote author=nutballs link=topic=155.msg899#msg899 date=1178248411

But my reason for ever even being remotely interested in

ajax

  is to be able to build apps that put as much of the processing onto the client. its just my lack of enthusiasm wins out... lol

Another thing I think I can help with. I've been pushing REALLY HARD to make this stuff work, and I believe I will be able to spin your gears and tickle your curiosity a bit. With a coder like you, I wager that is all it will take.

That and a bottle of Ibuprofen.

/p

perkiset

There are times when you will want to change something major on a page – perhaps even the entire notion of what the user is currently working on. It is important to let the user know that things are really changing and not to touch anything while you’re busy. It is even better if you can MAKE SURE that they don’t touch anything while you’re working. This is particularly important if what you’re about to do is (potentially) going to take a moment to get done.

So my first example here is a whole-page blocker – a completely modal screen. While this is up I can do anything I want. What’s also important, is that I am training my user how to behave and interact with my software. I also want to “drape upon myself” familiar notions to decrease the amount of time it will take for them to “Get It.”

It is fair to say that this is not strictly an

AJAX

  function, however I think that much of the problem is that people are focused on the technology of the data transfer, rather than what it does/doesn’t do for our users and as such, it is important to focus on the things that make this technology more familiar to them – and at the same time, more transparent.

( I've posted images in 2 successive posts after this one. )
In the first image, you can see a squished up version of a control center and contact management console for one of PH & my clients. When they click something like the “List Manager” button, I need to let them know that it might be as long as a couple seconds before I can set that up… so I lock them out completely, as can be seen in the second image.

This little bit of trickery is accomplished with the following technique:
I have a 300 x 300 px gif where every other dot is a 6a6a6a gray and every other dot is transparent. I have a div called screen that is display:none. When I need to obscure the screen, I get the size of the current page, then style the screen dive to be the same size, put its upper left corner at 0,0 and z-index at 10 – in front of everything else on the page. The screen.gif is the background of the div (repeated both x and y), I put a completely transparent gif as the content of the div and stretch it to the same dimensions. I then construct a little table and put the One Moment Please message in it, with a z-index of 20 so that it is even on top of the screen.

Why 300x300? Originally I had used a 2x2 because it was plenty. But some IE systems tiled it really slowly and you could see the screen spreading across the application - looked like hell. So I use a bigger one - it is still a really small gif, file-size-wise.

There are two interesting effects from this technique: A, it does a nifty job of obscuring but not hiding the screen – as I work behind it, the screen still changes. Looks great. B – the transparent gif on top of the screen gif and z-indexed on top of everything else stops the user from clicking on anything behind it. Presto, instant modality, even though it really isn’t.

There are a couple steps to pulling this off. First, I have a 1x1 gif at the bottom right hand side of my pages – actually my pages are a table, so I have a top-left 1x1 and a bottom-right 1x1 that, using the getElementTop and getElementBottom (in the

Javascript

  Code Repository) I can use to get the outside dimensions of the current page. Then styling the div WOULD be easy, except that IE and everyone else uses different styling nomenclature, so I’ll show you both. I will post a browser resilient stylizer in the code repository tomorrow. Unseen here is that the screen div has the background-image, z-index etc already set up in a < style > section at the top of the HTML page.

Here is a function that demonstrates screening the page. This function takes advantage of a table class I wrote – because table construction between IE and, again, everyone else is screwy. Actually that is where I keep my browser agnostic styling code, so I’ll just post the whole thing tomorrow.


function leavePage(elemName)
{
// Build the screen...
var screen = document.getElementById('screen');
var bottom = getElementTop(document.getElementById(‘bottomright’));
var right = getElementLeft(document.getElementById(‘bottomright’));
screen.style.top = '0px';
screen.style.left = '0px';
screen.style.height = bottom + 'px';
screen.style.width = right + 'px';

// Show the please wait...
var tObj = new tableManager(25, 0, 2, '150px');
var temp = tObj.newRow();
tObj.attribute(temp, 'bgcolor', '#ffa0a0');
var temp = tObj.newTextCell('One moment please...');
tObj.attribute(temp, 'align', 'center', 'class', 'arial s14 bold bk', 'nowrap', 'nowrap');

// Attach please wait...
var bodyArr = document.getElementsByTagName('body');
var temp = tObj.addTableTo(bodyArr[0]);
temp.style.position = 'absolute';
temp.style.top = ((bottom / 2) - 50) + 'px';
temp.style.left = ((right / 2) - 75) + 'px';
tObj.attribute(temp, 'id', 'leavePageTable');

return true;
}


Wrapping up: This was not technically an example of

Ajax

 . But I think it’s an example of how to begin to implement real world techniques into an application that makes use of

Ajax

 .

Tomorrow or so, I’ll post about things that are not quite as modal, but no less important about how we tell the user that something is going on. I think I’ll call it, “Server Interaction” aka, “Look at the pretty blinking lights”

Till then,
/p

perkiset

Example 1: the application how it normally looks (identifying marks obscurred intentionally)

perkiset

Example 2: Same app, after the "List Manager" button has been pressed and I have obscurred the screen while I work

thedarkness

Very cool perk, keep 'em coming. I'm thinking you're going to "fast track" me nicely  Applause

Got a couple of major form validation projects coming up soon and I reckon

AJAX

  is the way to go.

Cheers,
td

KaptainKrayola

Very cool thread Perk.  The Kaptain has yet to dive into

AJAX

  simply because he hasn't been presented with a project that he felt required

AJAX

  to make it work.  Things would have been cool in some of the projects but nothing to get him off his ass and

learn

 ing .  The Kaptain also hates

JavaScript

  for the most part so that doesn't help.  HOWEVER with the way this thread is going you may just get him interested enough to give it a whirl.

Applause

nutballs

darkness, you got it. The simplest "real usage of

Ajax

 , at least in my mind, is client/server form validation without moving off page. In a traditional client side validation, you would use JS to check the relevant fields for validity. If you want to make a change to the validations, you would need to update the JS. normally not a problem, but let say for argument sake that you need to validate something that could have changed since you started filling out the form, such as inventory levels of an order... Traditional client side wouldnt work. Serverside validation of course would, but forces you as a programmer, to have to receive all the data of the form, then if not valid, reload the entire form, populating it with all the existing value the user entered, plus alert them to the problem.

with

ajax

 , you would just check the relevant field values, sending them to the server, test them, then respond to the client with yeay or nay, even as the person types it in, or once they tab off the field.

this example perk gives of user manipulation and steering, and the form validation

asp

 ects are the two most driving reasons for me to eventually get on the

Ajax

  bandwagon.

thedarkness

Perk, could I ask that you start some threads on the x-browser issues of

AJAX

  and how you personally handle them , as well as the recommended course of action. Cross browser issues are my major concern about heavy utilization of

javascript

  be it

AJAX

  or otherwise. Can you lay my concerns to rest Dr. Perky?

Cheers,
td

perkiset

@ Nuts & TD re. Form Validation - you're right on the mark. I'm working on a page right now that follows up the modal one, but I'll switch gears to validation next, as well as some more advanced demonstrations of JS - I think that's a hot direction.

@ Nuts - the question you are asking relates DIRECTLY to a site you and I are working on - specifically dates and availability... capeesh? Load the page, select Aug 24 - Aug 30th and watch availability on the left side... you'll see what I mean. Alternately, scroll the calendar up and down - I don't load those until you've selected a a room type and then I load the availability... (Sorry everyone else for the abstraction, not ready to go public with that yet) - I think that is a perfect example of what you are asking...

@ TD re. cross browser - I test everything in Safari, FF and IE currently, and sometimes I go Opera and Camino just for giggles. I don't stand for non-cross-browser stuff, so the things I'm posting in the code repository are all cross browser compliant. The only trouble I've been having is with IE6 over SSL - but given my latest experiments I think I've got it by the tail at least... I'll post my precise findings when I am complete. But all that being said, yes of course - I'll start some threads specifically about the cross browsershitties I have found and workarounds.

But the

net

 

-net

 : Once I got over a couple issues like how the DOM is constructed in the Mozilla line as opposed to the IE line (specifically with tables) then I was off to the races. I'd be happy to do this because it was a FishER to get past at first. Or perhaps I'm just slow and stupid - we'll never know now Applause

/p

nutballs

quote author=perkiset link=topic=155.msg971#msg971 date=1178386062

@ Nuts - the question you are asking relates DIRECTLY to a site you and I are working on - specifically dates and availability... capeesh? Load the page, select Aug 24 - Aug 30th and watch availability on the left side... you'll see what I mean. Alternately, scroll the calendar up and down - I don't load those until you've selected a a room type and then I load the availability... (Sorry everyone else for the abstraction, not ready to go public with that yet) - I think that is a perfect example of what you are asking...


yea, i know. thats actually specifically what I thought of as an example of what I meant. but couldnt figure out how to mention it without mentioning it.

perkiset

No need to mention that I mentioned what you wouldn't mention.  Applause

In my article + 1 (the one just off what I'm polishing off now) I will use a completely different example, but it will demonstrate that concept quite handily I think.

/p

perkiset

Teach

 ing the user when to keep his hands to himself


There are times when complete blocking is inappropriate, but we still want to let the user know that <something> is going on and that they should be patient. In some cases a simple animated gif is enough, in some cases a progress bar is the way to go. This is particularly true of longer

AJAX

  requests… but even in the case of quick data pulls, if it’s going to affect the user in one way or another, it is most proper to tell them. For example: I hate it when I go to a forum using SMF (like this one does) and when I click to go somewhere it fires off a quick

AJAX

  call to see if there is any mail waiting for me. This should be quick, but if it’s not then I think something’s wrong with the site.

Here is an image of one of my current favorite systems – a list manager. This manages the master list and subset lists of < the client’s > database.

[localimage]/forum/graphics/lm1.jpg[/localimage]

There’s a lot that happens in this system, and I’ll go over more of it in future posts. But for now, I want to demonstrate two ways that I tell the user that I’m busy. The first thing is the little LED looking graphics at the upper left hand corner. I spent a lot of time doing work with phone systems and I became very fond of blinking LEDs and I carry that over here. As you can see in the image, the green “light” is on be default. There’s nothing that the user needs be concerned with. As soon as they hit something where they are sending a request to me, I replace that top left corner graphic with this one:

[localimage]/forum/graphics/lm3.gif[/localimage]

… then when I’m idle set it back to…

[localimage]/forum/graphics/lm2.gif[/localimage]

The

net

  result, of course, is that the user quickly

learn

 s that when the LEDs are blinking, the

mac

 hine is busy ie., keep your hands to yourself. This has been marvelously effective in my back-office apps, but I needed a little different approach for public surfers, so I now often use something like this:

[localimage]/forum/graphics/lm5.gif[/localimage]

… which yes, is a scoff of the

Mac

  “I’m Busy” image, but does the trick nicely.

I keep a count of

ajax

  requestors that are busy – if the number from 0 to greater than 0 then I turn the blinker on… if the number changes from greater than 0 to 0 I turn it off. In this way I can easily tell the user that I am busy. This form is a stock element in my arsenal – I just use different content in the middle and call a different

ajax

  handling

PHP

  script for functionality, but the blinkness of the form comes with this class.

The code for changing an image is as simple as:

led_Off  = new Image();
ledOff.src = ‘/graphics/blinker_off.gif’;
led_On  = new Image();
ledOn.src = ‘/graphics/blinker_on.gif’;

… then I need the actual image in the page…

<img id=”LED” src=”/graphics/blinker_off.gif” height=”16” width=”32”>

… and then I shift it as I get busy…

document.getElementById(‘LED’).src = led_On.gif;

The code I use to track business of a page is in the

Javascript

  Code Repository, the Transmit State class.

The classic GUI OS mechanism for showing how long something will take is the status bar. This is a bit more tricky, but not too tough in

Ajax

 . Here is an image of a fairly lengthy process running in the list manager (a reindex):

[localimage]/forum/graphics/lm4.jpg[/localimage]

Here is the technique:

HTML:
I have a table div that has a border, plus a div in the middle that has a background color (green) that I adjust the width of as I update my progress.

Server: My process writes to a file this exactly: [number completed] | [number to do] so it’s like 50|100. Since it is the only process that can wirte to this file I am not worried about race conditions or anything. A WAY better way to do this is to cache the variable (APC) - I just haven't implemented this yet.

Client: I fire off an

ajax

  request to start the process on the client, then as soon as it comes back I start firing off update requests. The update request simply gets the status number (50|100) – no XML or anything. The client then parses the return value – if the first and second numbers are equal (or the response comes back empty) then I am done and I move on… if not, then I divide the two and calculate the size of the colored DIV on the screen. My update requests are fired 10ms after I get the response from the previous one – XMLHTTPRequest does not like you to fire off a new request while you are in the handler of another one.

In my next installment I will discuss my primary argument for when to send XML and when to send formatted text. I will also be looking at more cooperative processing ie., where to put the processing burden based on the needs of the application and the desires of the surfer.

thedarkness

quote author=perkiset link=topic=155.msg1035#msg1035 date=1178580826


Server: My process writes to a file this exactly: [number completed] | [number to do] so it’s like 50|100. Since it is the only process that can wirte to this file


How are you assuring this perk, semaphore maybe? How would you achieve this using APC?

BTW, found this whilst foraging for

PEAR

 s....
http://

pear

 .

php

 

.net

 /manual/en/package.caching.cache-lite.intro.

php

 
Interesting read, especially the bit about cache polution and the security ramifications. I'm interested in opinions, I'd test it out if I had any websites that pulled decent traffic  Applause Most of my servers are powered by little furry guys running on circular treadmills  Applause

Rockin' stuff as usual perk, keep 'em coming.

Cheers,
td

m0nkeymafia

Great post perk, I have a curve ball or two to throw in the mix though

JS validation:
I believe JS validation should be a supplement to server end, in that its there merely to catch simple mistakes.  The core and grunt should be done on the server.  Why? Because it means some punk cant turn off his

javascript

  and bypass your security measures. Any

ajax

  requests should only be done because the validation you require cannot be done simply in JS.  And when you submit the form it should still be validated server side.  It is the only way to prevent dodgeyness.

Perk I think you under-estimate the power of XML within the

AJAX

  framework.
Say for example you have an XML document, created dynamically server side, that lists all online members, their nick names, IP addresses and what not.

What I would do is create a number XSL stylesheets to parse the document into various xhtml fragments.  For example with this one XML document [and call to the server] you could list all members online.  Sort by username, ascending, descending, ip address, blah blah [you can sort them with about 1-2 lines of JS once you wrote the XSL].  You can also count how many people are online, how many people are online with attribute A being true.

The power this gives you is amazing, seriously.  If you do

ajax

 , then

learn

  XSL, its possibly the best thing ive

learn

 t in the past year.  With the example I gave, it means you can change any part of the display process without changing the backend.  XSL is also extremely maintainable, much more so than JS and of course its functionality doesnt vary between browsers, so you have less hassle that way.

Oh and

PHP

  has an XSL parser too, so the XSL stylesheets you write for

ajax

  will parse exactly the same in

PHP

 ...oh yes...OH YES...so this means that if someone has JS turned off, with literally no extra leg work you can output the content with

php

  [page refresh required obviously].  So not only do you have an extremely flexible framework, highly maintainable, which looks cool and is faster than doing it any other way.  You also cater for people with JS turned off [or incompatible browsers] with no extra cost to you.

So guys...XSL? Do it? DOOO IT  Applause

thedarkness

How are you working out reliably that the browser has

javascript

  disabled? Thanks for the skinny on XSL, well worth a look.

Cheers,
td

perkiset

quote author=thedarkness link=topic=155.msg1041#msg1041 date=1178617792

quote author=perkiset link=topic=155.msg1035#msg1035 date=1178580826


Server: My process writes to a file this exactly: [number completed] | [number to do] so it’s like 50|100. Since it is the only process that can wirte to this file


How are you assuring this perk, semaphore maybe? How would you achieve this using APC?

Hey TD -

Sorry man, I thought for sure I had responded to that... the file I write is named from the sessionID. But you are correct, and in fact that's where my new stuff is going, that it's all kept in a variable in APC doing the same for more speedieness.
To your oether point though, I am worried about cache pollution and fragmentation. Gonna have to watch that for quite a while and see if it pisses me off at all.

/p

perkiset

quote author=m0nkeymafia link=topic=155.msg1638#msg1638 date=1179746019

JS validation:
I believe JS validation should be a supplement to server end, in that its there merely to catch simple mistakes.  The core and grunt should be done on the server.  Why? Because it means some punk cant turn off his

javascript

  and bypass your security measures. Any

ajax

  requests should only be done because the validation you require cannot be done simply in JS.  And when you submit the form it should still be validated server side.  It is the only way to prevent dodgeyness.

Absolutely correct MM, and I'm not throwing server side away... I am simply going the 100% opposite direction of people that ONLY put validation on the server. Taking just a few extra steps on the client keeps a lot of traffic down... of course, you'll still get boneheads trying to break you ergo you must protect your service, but if you have a lot of real traffic and can completely cleanse the form data before it goes upstream it means a lighter load on the server.


quote author=m0nkeymafia link=topic=155.msg1638#msg1638 date=1179746019

Perk I think you under-estimate the power of XML within the

AJAX

  framework.
Say for example you have an XML document, created dynamically server side, that lists all online members, their nick names, IP addresses and what not.

What I would do is create a number XSL stylesheets to parse the document into various xhtml fragments.  For example with this one XML document [and call to the server] you could list all members online.  Sort by username, ascending, descending, ip address, blah blah [you can sort them with about 1-2 lines of JS once you wrote the XSL].  You can also count how many people are online, how many people are online with attribute A being true.

The power this gives you is amazing, seriously.  If you do

ajax

 , then

learn

  XSL, its possibly the best thing ive

learn

 t in the past year.  With the example I gave, it means you can change any part of the display process without changing the backend.  XSL is also extremely maintainable, much more so than JS and of course its functionality doesnt vary between browsers, so you have less hassle that way.
[ clip ]
So guys...XSL? Do it? DOOO IT  Applause

Really important part of that puzzle MM: If you know XSL. I do not and have yet had the time to even look at it. From what I read, you are 100% correct that I'ma bonehead for not putting it in my toolbox... perhaps you could help us out here because I am certain that I'm not the minority... Howz about you monkey around a bit with a quick

tutor

 ial to kick off a board...?

m0nkeymafia

No probs perk ill whip one up
P.s. im not sure how im comin across, i like to rock the boat in terms of techniques, but not having a "pop" if you get me Applause

thedarkness

lol, you'll find most of us are not very "delicate". We spend a lot of our time in "flame fest alley"  Applause  Applause

Cheers,
td

nutballs

In order to be able to rock a boat, there must be a boat. the problem with this group is we tend to blow up our own boats, and sink them, so we gave up on boats. I personally have just gone the jesus route, and

learn

 ed to walk on water. but thats me.

though im guessing there is eventually going to be a bunch of tender softies sooner or later on here.

m0nkeymafia

What you mean you cant already walk on water?
j00 sux0r

perkiset

My personal solve is simply to spend more time with the little man in the boat.

Nice chap, prone to being excitable. Can be a little cold at first, but really warms up if you just spend a little time with him. Very likely to let you spend more time in the boat if you get him on your side.

Yikes... cold shower time.
/p

m0nkeymafia

Perk sounds like you had some good times with that man in that boat  Applause

perkiset

Story of my life pal  Applause

Frightening, talking about that stuff and looking at your avatar thought actually  Applause


Perkiset's Place Home   Politics @ Perkiset's