Jump to content

Bad, terrible or simply funny code examples

Can't fit the entire contents of JQuery into a post, sorry.

 

What's wrong with jQuery?

Link to comment
Share on other sites

Link to post
Share on other sites

What's wrong with jQuery?

There's nothing wrong with jQuery; it's a tool to manipulate the DOM and that's what it does.

 

My personal problem with it is 'newbie' developers starting out in web development tend to see it as the be all and end all of JavaScript on the web. They never actually learn 'vanilla JavaScript,' understand how jQuery does the magic it does, or even what the DOM is.

Link to comment
Share on other sites

Link to post
Share on other sites

Can't fit the entire contents of JQuery into a post, sorry.

<script src="http://code.jquery.com/jquery-latest.min.js"></script>

Problem solved!

I am good at computer

Spoiler

Motherboard: Gigabyte G1 sniper 3 | CPU: Intel 3770k @5.1Ghz | RAM: 32Gb G.Skill Ripjaws X @1600Mhz | Graphics card: EVGA 980 Ti SC | HDD: Seagate barracuda 3298534883327.74B + Samsung OEM 5400rpm drive + Seatgate barracude 2TB | PSU: Cougar CMX 1200w | CPU cooler: Custom loop

Link to comment
Share on other sites

Link to post
Share on other sites

What's wrong with jQuery?

 

 

There's nothing wrong with jQuery; it's a tool to manipulate the DOM and that's what it does.

 

My personal problem with it is 'newbie' developers starting out in web development tend to see it as the be all and end all of JavaScript on the web. They never actually learn 'vanilla JavaScript,' understand how jQuery does the magic it does, or even what the DOM is.

 

 

I tend to stay out of the programming forum for reasons like this. I don't like getting into arguments.

 

There are so many problems with jquery I can't even think of them all off the top of my head. Plus its late, I'm tired and I have actual work to do, so I'm sorry if this doesn't make any sense.

 

I will outlay some of my concerns with it, and I'm going to keep this extremely brief.

 

First off you have to understand the client-side components of a web page, which I'm sure most of you do. Nevertheless, they are:

 

  • Markup ([x]HTML): Simply describes the page structure and identifies page elements for what they are not what they look like. Things like <center> tags and style attributes should nearly never need to be used. Just a logical markup for the page. (nearly no-one gets this bit right, and HTML5 has blurred the line here). But for instance, you should be able to nearly completely change the layout and appearance of a page without touching the HTML.
  • Stylesheet (CSS): Rules for what the page looks like, of course
  • Scripting (JS): Useful for some enhancements and added functionality. But is NOT what you use to define what the site looks like. The website should be fully functional without Javascript enabled. 

So a simplistic explanation of the closest thing to the Model-View-Controller pattern as it applies to websites. Separation of style from content from scripting is key. So if we take Javascript for what it is - a useful tool to provide some enhancements for your website - the problems with jQuery are more evident, mainly because it's bloated as all hell.

 

 

1. Jquery is essentially a bastardized version of Javascript itself. It almost completely changes the syntax of the language, and the reasons newbs use it instead of learning vanilla JS is because if they ask for help anywhere on the internet, the reply from "experts" is "use jQuery". And thus begins an endless loop. 

2. It's not coded well, and it doesn't actually provide a great deal of useful functionality in things where Javascript falls short - such as cross browser compatibility. For the most part it's fixing problems that don't exist while causing a whole heap of its own.

3. Man is it bloated. This is not acceptable in web development where your websites content and loading time is the most important thing. I'll use an example from my own recent life. I was building a website for a medium sized enterprise and needed a lightbox functionality for an image gallery. I had been out of the game for a few years,  so was just "fuck it, I'll get jQuery to do it". Then I saw the size, and my jaw dropped. COMPRESSED, with the jQuery core, dependency plugin and the lightbox plugin itself, the filesize was 250KB!!!!!!!!!!!! Not freaking acceptable, by any stretch of the imagination. Most people (and yes, most!) do not have access to high speed internet connections. 250KB is a shit tonne. It is the job of the web developer to make the website work for as many people as possible, not go "nah, most people won't notice it". That's lazy, and bullshit. It's the client who does all of the work processing Javascript, so you respect the people viewing the site. For the record, I was able to replicate the lightbox exactly (with many improvements, such as looking really awesome on phones and improved keyboard navigation) in about 3.8KB of Javascript, and an additional 1KB of CSS.

4. The CDN barely gets around this problem. I've reloaded Jquery twice today. And yea, it's noticeable.

5. yea, big sites use it. Big sites usually have content that people will do anything to get at (Google, Wikipedia, Facebook) and they will put up with being dicked around. But for your average person's website...people will just click out of it if it takes to long to load.

 

That's just the problems associated with bloat. I am uncomfortable, and find it unethical, to serve viewers of my website more than what is necessary for something that doesn't add anything crucial to the website. I haven't read the code itself in a couple of months so would need to refresh myself, but it would take me several days to write out the problem list.

 

 

PRACTICAL uses of jQuery would only be somewhere where you use pretty much all of its features....so essentially only in a full blown web app. 

 

As you might have figured, I hate code bloat, but I put up with it to some degree in desktop programming, since it's all done on user hardware - but for websites its all done on a users internet. And users mostly have shit Internet with data caps, low speeds and the like. Everything should also be compatible with everything - new browsers, old browsers, screen readers, any screen resolution. And jQuery just makes that an even bigger problem.

 

Use a small function library in Javascript instead. I have one written I should really get around to publishing.

Link to comment
Share on other sites

Link to post
Share on other sites

PRACTICAL uses of jQuery would only be somewhere where you use pretty much all of its features....so essentially only in a full blown web app. 

 

 

This. Exactly this is what I thought. I made a couple of webapps/websites with jQuery, they all where a pain in the *rse. If you use a lot of the "features" of jquery it is fine. But if you only use a couple its a waste and if you want to do something that isn't officially in jQuery its a freeeeaking pain in the *rse :)

 

If you're just building a website you can use a online websitebuilder or an adobe program instead, it makes the same kind of html mess :)

Just my 2 cents ;)

Build log "Whiplash" : http://linustechtips.com/main/topic/158477-the-hero/

Whiplash: 4790k@4,4Ghz|Maximus VII Hero|4x4Gb Red/Black HyperX fury 1866Mhz|R9 290 Tri-X|Modded 450D|Sleeved cables on a M12II evo 850W|M500 480Gb| BenQ XL2411T@144Hz

Laptop: 4700MQ|16Gb@1600Mhz|Quadro 1100M|1080P|128Gb SSD|500Gb 7200RPM hdd

Link to comment
Share on other sites

Link to post
Share on other sites

-snip-

 

-snip-

 

I must agree with the majority of these points. It's all about the correct tool for the correct job and in the correct situation. It's also refreshing to see someone else being highly committed to and enthusiastic about doing things the right way and really caring about their work; separation of concerns, good clean architecture and actively thinking/caring about the end user.

The single biggest problem in communication is the illusion that it has taken place.

Link to comment
Share on other sites

Link to post
Share on other sites

I tend to stay out of the programming forum for reasons like this. I don't like getting into arguments.

 

There are so many problems with jquery I can't even think of them all off the top of my head. Plus its late, I'm tired and I have actual work to do, so I'm sorry if this doesn't make any sense.

 

I will outlay some of my concerns with it, and I'm going to keep this extremely brief.

 

First off you have to understand the client-side components of a web page, which I'm sure most of you do. Nevertheless, they are:

 

  • Markup ([x]HTML): Simply describes the page structure and identifies page elements for what they are not what they look like. Things like <center> tags and style attributes should nearly never need to be used. Just a logical markup for the page. (nearly no-one gets this bit right, and HTML5 has blurred the line here). But for instance, you should be able to nearly completely change the layout and appearance of a page without touching the HTML.
  • Stylesheet (CSS): Rules for what the page looks like, of course
  • Scripting (JS): Useful for some enhancements and added functionality. But is NOT what you use to define what the site looks like. The website should be fully functional without Javascript enabled. 

So a simplistic explanation of the closest thing to the Model-View-Controller pattern as it applies to websites. Separation of style from content from scripting is key. So if we take Javascript for what it is - a useful tool to provide some enhancements for your website - the problems with jQuery are more evident, mainly because it's bloated as all hell.

 

 

1. Jquery is essentially a bastardized version of Javascript itself. It almost completely changes the syntax of the language, and the reasons newbs use it instead of learning vanilla JS is because if they ask for help anywhere on the internet, the reply from "experts" is "use jQuery". And thus begins an endless loop. 

2. It's not coded well, and it doesn't actually provide a great deal of useful functionality in things where Javascript falls short - such as cross browser compatibility. For the most part it's fixing problems that don't exist while causing a whole heap of its own.

3. Man is it bloated. This is not acceptable in web development where your websites content and loading time is the most important thing. I'll use an example from my own recent life. I was building a website for a medium sized enterprise and needed a lightbox functionality for an image gallery. I had been out of the game for a few years,  so was just "fuck it, I'll get jQuery to do it". Then I saw the size, and my jaw dropped. COMPRESSED, with the jQuery core, dependency plugin and the lightbox plugin itself, the filesize was 250KB!!!!!!!!!!!! Not freaking acceptable, by any stretch of the imagination. Most people (and yes, most!) do not have access to high speed internet connections. 250KB is a shit tonne. It is the job of the web developer to make the website work for as many people as possible, not go "nah, most people won't notice it". That's lazy, and bullshit. It's the client who does all of the work processing Javascript, so you respect the people viewing the site. For the record, I was able to replicate the lightbox exactly (with many improvements, such as looking really awesome on phones and improved keyboard navigation) in about 3.8KB of Javascript, and an additional 1KB of CSS.

4. The CDN barely gets around this problem. I've reloaded Jquery twice today. And yea, it's noticeable.

5. yea, big sites use it. Big sites usually have content that people will do anything to get at (Google, Wikipedia, Facebook) and they will put up with being dicked around. But for your average person's website...people will just click out of it if it takes to long to load.

 

That's just the problems associated with bloat. I am uncomfortable, and find it unethical, to serve viewers of my website more than what is necessary for something that doesn't add anything crucial to the website. I haven't read the code itself in a couple of months so would need to refresh myself, but it would take me several days to write out the problem list.

 

 

PRACTICAL uses of jQuery would only be somewhere where you use pretty much all of its features....so essentially only in a full blown web app. 

 

As you might have figured, I hate code bloat, but I put up with it to some degree in desktop programming, since it's all done on user hardware - but for websites its all done on a users internet. And users mostly have shit Internet with data caps, low speeds and the like. Everything should also be compatible with everything - new browsers, old browsers, screen readers, any screen resolution. And jQuery just makes that an even bigger problem.

 

Use a small function library in Javascript instead. I have one written I should really get around to publishing.

 

Okay. I am by no means a professional web developer so I rarely have to think in such detail about this kind of thing. Would something like Dojo or Mootools be more acceptable do you think or are they just the same problem?

 

I agree, though. jQuery is great because it allows less experienced people to have an easier time doing more complicated things which facilitates creativity and content creation and what not... that's what abstraction is all about, albeit at a cost of efficiency and performance. However, yes, a professional front-end developer really ought to be using bespoke JavaScript code in order to make the site as efficient and high performing as possible.... since that's their job. They shouldn't really half-arse it with jQuery.

Link to comment
Share on other sites

Link to post
Share on other sites

 

I never used it, but looks interesting. Will give it a look, thanks. :P

 

EDIT: To stay on-topic. Here's something that I encounter a lot, and that makes me cringe a little.

if(condition) return true;else return false;

noob here, why does that make you cringe?

Link to comment
Share on other sites

Link to post
Share on other sites

noob here, why does that make you cringe?

I don't know about him but I hate when people don't put brackets around things even when it's one line and imo putting the returns on the same line like that just makes it harder to read in order to save 2 whole key presses.

1474412270.2748842

Link to comment
Share on other sites

Link to post
Share on other sites

I don't know about him but I hate when people don't put brackets around things even when it's one line and imo putting the returns on the same line like that just makes it harder to read in order to save 2 whole key presses.

that's funny, i cry a little bit every time i see a waste of brackets for a single instruction

i also like the instruction on the same line as the if statement, in certain cases, like

int f(int a, int b){          if(a == 0) return 4;          if(b > 5) return 3;          if(a == b) return 9;          if(a == -b) return 42;}int fib(int n){          if(n < 2) return n;          return fib(n - 1) + fib(n - 2);}

noob here, why does that make you cringe?

well, that code returns true if the condition is true, and returns false if the condition is false. so, as you can see, it just returns the value of the condition

if(condition)          return true;else          return false;// is exactly equivalent toreturn condition;
Link to comment
Share on other sites

Link to post
Share on other sites

that's funny, i cry a little bit every time i see a waste of brackets for a single instruction

It seems like a language thing, from my experience programmers who started with C/C++ style languages are no bracket people while Java/C#/Python type languages are bracket people.

 

i also like the instruction on the same line as the if statement, in certain cases, like

I can understand it for giant lists of things and certain situations like in OpenGL having a vertex position and texCoord on the same line so each line is all the data for a single vertex. Though for things like returns I'd probably still put in brackets.

1474412270.2748842

Link to comment
Share on other sites

Link to post
Share on other sites

 

that's funny, i cry a little bit every time i see a waste of brackets for a single instruction

i also like the instruction on the same line as the if statement, in certain cases, like

int f(int a, int b){          if(a == 0) return 4;          if(b > 5) return 3;          if(a == b) return 9;          if(a == -b) return 42;}int fib(int n){          if(n < 2) return n;          return fib(n - 1) + fib(n - 2);}

well, that code returns true if the condition is true, and returns false if the condition is false. so, as you can see, it just returns the value of the condition

if(condition)          return true;else          return false;// is exactly equivalent toreturn condition;

ohh I see. Thanks

Link to comment
Share on other sites

Link to post
Share on other sites

It seems like a language thing, from my experience programmers who started with C/C++ style languages are no bracket people while Java/C#/Python type languages are bracket people.

that sounds true to me, in fact i started with C, and the more i get into C++, the worse my one-lineness gets

 

and it's really about the language, i'm thinking of the constructor initialization list in C++

a code i'm working on lately has various segments of code like this

class foo{          private:                    int a, b, c, d;          public:                    foo(int a, int b, int c, int d): a{a}, b{b}, c{c}, d{d} {}                    // or even                    foo(int a, int b, int c, int d): a{a}, b{b}, c{c}, d{d} { singleFunctionCall(); }};

i still didn't decide if it's beautiful or terrible, but i very much like it so far

Link to comment
Share on other sites

Link to post
Share on other sites

I think I saw this in an old teksyndicate the tek or something

stop(); // Hammer Time!
Link to comment
Share on other sites

Link to post
Share on other sites


a , img {

border: none;

outline: none

}

Link to comment
Share on other sites

Link to post
Share on other sites

I don't know about him but I hate when people don't put brackets around things even when it's one line and imo putting the returns on the same line like that just makes it harder to read in order to save 2 whole key presses.

 

 

that's funny, i cry a little bit every time i see a waste of brackets for a single instruction

i also like the instruction on the same line as the if statement, in certain cases...

 

This is indeed an interesting subject. My own stance on this has changed twice over the years. I originally learned in the Allman style (with C & C++) and spent my early years using it. I turned from this a little later on and become quite an evangelist of same line conditionals, returns and so fourth. But what is ironic is that I have now since come full circle and returned to using it again!

 

There were a number of reasons driving me to do so, among the foremost of which being; readability, maintainability and just being safe about things. When debugging production grade code, having stuff on the same line makes it orders of magnitude more difficult to just see what is going on and also trying to follow the process flow, something that is simply compounded when dealing with multiple threads. I say being safe about things in relation to bracketing everything, even simple single liners... it's easy for less experienced (and even experienced) developers to just miss the indentation on conditionals and etcetera and introduce a bug. We had a long discussion about all of this a while ago and all of the other developers on my team were also aligned with the gist of these arguments plus we took to using tools like StyleCop to enforce consistency.

 

Yes there's also a flip side argument against this, specifically in relation to using TDD; you catch the silly mistakes naturally... but still why risk it and why make the code so compacted and difficult to follow that it just looks like it's been (forgive me for being so blunt) farted all over the page.

 

 

I can understand it for giant lists of things and certain situations like in OpenGL having a vertex position and texCoord on the same line so each line is all the data for a single vertex. Though for things like returns I'd probably still put in brackets.

 

Be careful here, there's a very justified school of thought (which I follow) that says when you end up needing 'giant lists of things' and feel the need to try to compactify the code down by reducing readability in order to give the illusion that it's smaller and more concise than it really is, then your doing something fundamentally wrong with your architecture. Read more about Code Smells.

 

 

that sounds true to me, in fact i started with C, and the more i get into C++, the worse my one-lineness gets

 

and it's really about the language, i'm thinking of the constructor initialization list in C++

a code i'm working on lately has various segments of code like this

class foo{

private:

int a, b, c, d;

public:

foo(int a, int b, int c, int d): a{a}, b{b}, c{c}, d{d} {}

// or even

foo(int a, int b, int c, int d): a{a}, b{b}, c{c}, d{d} { singleFunctionCall(); }

};

i still didn't decide if it's beautiful or terrible, but i very much like it so far

 

 

Yes I can see your point. I am also currently of the opinion that it is a good thing. I have certainly been using it in production code.

The single biggest problem in communication is the illusion that it has taken place.

Link to comment
Share on other sites

Link to post
Share on other sites

-snip-

-snip-

another reason i oneline code is when i think it's not important

 

example:

i'm personally terrible with error handling, i think it kind of breaks the flow of the code, but it's needed for the program not to crash horribly, so i do it indeed

the point is that if i have to consider an edge case which does not make the program "progress", then let me just waste one line for it

 

this way you make the code more compact, the majority of the lines you're looking at are "interesting", contain the logic for the progression

 

with that said, i'm learning kind of in a bad way, and i sadly never had the pleasure to work with/for an experienced programmer who knows how to maintain a large code base, so my style is pretty much going with a trial and error type of progression

Link to comment
Share on other sites

Link to post
Share on other sites

Two other features I really don't like or believe in: The Region Directive and the GoTo Statement.

 

Nothing quite like coming upon a class containing over 5k (yes thousand) lines and finding multiple #regions, often in methods spanning 200+ lines. Then as one steps on the landmines... I mean expands the regions being shot in the face...  er greeted by GoTos as well as Reentrancy! Just no... such a thing simply should not exist.

 

There should be absolutely no justification, need, desire or otherwise to use either of these two features ever.

The single biggest problem in communication is the illusion that it has taken place.

Link to comment
Share on other sites

Link to post
Share on other sites

if(condition) return true;else return false; 

noob here, why does that make you cringe?

 

*sniped

Link to comment
Share on other sites

Link to post
Share on other sites

Two other features I really don't like or believe in: The Region Directive and the GoTo Statement.

 

Nothing quite like coming upon a class containing over 5k (yes thousand) lines and finding multiple #regions, often in methods spanning 200+ lines. Then as one steps on the landmines... I mean expands the regions being shot in the face...  er greeted by GoTos as well as Reentrancy! Just no... such a thing simply should not exist.

 

There should be absolutely no justification, need, desire or otherwise to use either of these two features ever.

 

I'm not particularly a fan of gotos either... but I've colleagues at work who say there are legitimate use cases.

 

For example, they say if you have a function with an enumerated set of return values (indicating either success or error type - we encounter these cases a lot in our driver stack) you might not want to just return immediately if you encounter an error... you may need to do some clean up/memory management. So you set the return value and then jump to the end of the function where the clean up occurs before returning.

I don't like gotos because they are dangerous and horrible when not used properly, but I have to concede that in this case it's really fair enough.

Link to comment
Share on other sites

Link to post
Share on other sites

the GoTo Statement.

 

There should be absolutely no justification, need, desire or otherwise to use either of these two features ever.

I used to think that until Problem Solving #1 and I used the CUDA sample project and saw how they used goto. Using it for freeing memory and returning the error makes total sense instead of copying and pasting the same dealloc code over and over for 20 different error blocks.

 

cudaError_t calcDeletablePrimes(int *a, unsigned int size){    int *dev_a = 0;    cudaError_t cudaStatus;    // Choose which GPU to run on, change this on a multi-GPU system.    cudaStatus = cudaSetDevice(0);    if (cudaStatus != cudaSuccess) {        fprintf(stderr, "cudaSetDevice failed!  Do you have a CUDA-capable GPU installed?");        goto Error;    }    cudaStatus = cudaMalloc((void**)&dev_a, size * sizeof(int));    if (cudaStatus != cudaSuccess) {        fprintf(stderr, "cudaMalloc failed!");        goto Error;    }    // Copy input vectors from host memory to GPU buffers.    cudaStatus = cudaMemcpy(dev_a, a, size * sizeof(int), cudaMemcpyHostToDevice);    if (cudaStatus != cudaSuccess) {        fprintf(stderr, "cudaMemcpy failed!");        goto Error;    }    // Launch a kernel on the GPU with one thread for each element.    int threadsPerBlock = 256;    int blocksPerGrid =(size + threadsPerBlock - 1) / threadsPerBlock;    deletablePrimes<<<blocksPerGrid, threadsPerBlock>>>(dev_a, size);    // Check for any errors launching the kernel    cudaStatus = cudaGetLastError();    if (cudaStatus != cudaSuccess) {        fprintf(stderr, "addKernel launch failed: %s\n", cudaGetErrorString(cudaStatus));        goto Error;    }        // cudaDeviceSynchronize waits for the kernel to finish, and returns    // any errors encountered during the launch.    cudaStatus = cudaDeviceSynchronize();    if (cudaStatus != cudaSuccess) {        fprintf(stderr, "cudaDeviceSynchronize returned error code %d after launching addKernel!\n", cudaStatus);        goto Error;    }    // Copy output vector from GPU buffer to host memory.    cudaStatus = cudaMemcpy(a, dev_a, size * sizeof(int), cudaMemcpyDeviceToHost);    if (cudaStatus != cudaSuccess) {        fprintf(stderr, "cudaMemcpy failed!");        goto Error;    }Error:    cudaFree(dev_a);        return cudaStatus;} 

1474412270.2748842

Link to comment
Share on other sites

Link to post
Share on other sites

I used to think that until Problem Solving #1 and I used the CUDA sample project and saw how they used goto. Using it for freeing memory and returning the error makes total sense instead of copying and pasting the same dealloc code over and over for 20 different error blocks.

 

 

Yup. We've got that kind of structure littered throughout our code. I really can't think of any better way of doing it.

cudaError_t calcDeletablePrimes(int *a, unsigned int size){    int *dev_a = 0;    cudaError_t cudaStatus;    // Choose which GPU to run on, change this on a multi-GPU system.    cudaStatus = cudaSetDevice(0);    if (cudaStatus != cudaSuccess) {        fprintf(stderr, "cudaSetDevice failed!  Do you have a CUDA-capable GPU installed?");        goto Error;    }    cudaStatus = cudaMalloc((void**)&dev_a, size * sizeof(int));    if (cudaStatus != cudaSuccess) {        fprintf(stderr, "cudaMalloc failed!");        goto Error;    }    // Copy input vectors from host memory to GPU buffers.    cudaStatus = cudaMemcpy(dev_a, a, size * sizeof(int), cudaMemcpyHostToDevice);    if (cudaStatus != cudaSuccess) {        fprintf(stderr, "cudaMemcpy failed!");        goto Error;    }    // Launch a kernel on the GPU with one thread for each element.    int threadsPerBlock = 256;    int blocksPerGrid =(size + threadsPerBlock - 1) / threadsPerBlock;    deletablePrimes<<<blocksPerGrid, threadsPerBlock>>>(dev_a, size);    // Check for any errors launching the kernel    cudaStatus = cudaGetLastError();    if (cudaStatus != cudaSuccess) {        fprintf(stderr, "addKernel launch failed: %s\n", cudaGetErrorString(cudaStatus));        goto Error;    }        // cudaDeviceSynchronize waits for the kernel to finish, and returns    // any errors encountered during the launch.    cudaStatus = cudaDeviceSynchronize();    if (cudaStatus != cudaSuccess) {        fprintf(stderr, "cudaDeviceSynchronize returned error code %d after launching addKernel!\n", cudaStatus);        goto Error;    }    // Copy output vector from GPU buffer to host memory.    cudaStatus = cudaMemcpy(a, dev_a, size * sizeof(int), cudaMemcpyDeviceToHost);    if (cudaStatus != cudaSuccess) {        fprintf(stderr, "cudaMemcpy failed!");        goto Error;    }Error:    cudaFree(dev_a);        return cudaStatus;} 
Link to comment
Share on other sites

Link to post
Share on other sites

-snip-

 

-snip-

 

Okay, maybe... maybe in that specific case. It still hurts to look at/imagine though.

The single biggest problem in communication is the illusion that it has taken place.

Link to comment
Share on other sites

Link to post
Share on other sites

Okay, maybe... maybe in that specific case. It still hurts to look at/imagine though.

 

I agree with you there. I still don't like it! :P

Link to comment
Share on other sites

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×