SitePoint Sponsor

User Tag List

Page 1 of 2 12 LastLast
Results 1 to 25 of 34
  1. #1
    Non-Member
    Join Date
    May 2012
    Posts
    14
    Mentioned
    1 Post(s)
    Tagged
    0 Thread(s)

    Object oriented programming in javascript

    Is object oriented programming in javascript used?

  2. #2
    Programming Since 1978 silver trophybronze trophy felgall's Avatar
    Join Date
    Sep 2005
    Location
    Sydney, NSW, Australia
    Posts
    16,834
    Mentioned
    25 Post(s)
    Tagged
    1 Thread(s)
    Yes but only by those who don't realise that prototyping is far more powerful.

    If you use object oriented processing in JavaScript you are only using a small fraction of what the language is capable of.
    Stephen J Chapman

    javascriptexample.net, Book Reviews, follow me on Twitter
    HTML Help, CSS Help, JavaScript Help, PHP/mySQL Help, blog
    <input name="html5" type="text" required pattern="^$">

  3. #3
    SitePoint Wizard bronze trophy Jeff Mott's Avatar
    Join Date
    Jul 2009
    Posts
    1,276
    Mentioned
    18 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by felgall View Post
    Yes but only by those who don't realise that prototyping is far more powerful.
    Prototyping isn't object oriented?
    "First make it work. Then make it better."

  4. #4
    Community Advisor bronze trophy
    fretburner's Avatar
    Join Date
    Apr 2013
    Location
    Brazil
    Posts
    1,411
    Mentioned
    45 Post(s)
    Tagged
    12 Thread(s)
    Object oriented programming is just a technique, the same way that procedural programming is. You can write procedural or OO code in JS, just as you can with PHP, Python or Ruby.

    One important way that JS differs from those other languages is that it uses prototypal inheritance rather than classical (i.e. class-based) inheritance. As felgall alluded to, prototypal inheritance is more powerful than classical inheritance, although it is possible to emulate classic inheritance in JS.

  5. #5
    Programming Since 1978 silver trophybronze trophy felgall's Avatar
    Join Date
    Sep 2005
    Location
    Sydney, NSW, Australia
    Posts
    16,834
    Mentioned
    25 Post(s)
    Tagged
    1 Thread(s)
    Quote Originally Posted by Jeff Mott View Post
    Prototyping isn't object oriented?
    No it isn't. Prototyping has approximately the same relationship to object oriented that object oriented has to procedural. Just as object oriented is far more powerful in many ways than procedural, prototyping is far more poweful than object oriented.

    While you can write procedural or object oriented code in JavaScript, if you limit yourself to using those then you are missing out on the really powerful parts of javaScript.
    Stephen J Chapman

    javascriptexample.net, Book Reviews, follow me on Twitter
    HTML Help, CSS Help, JavaScript Help, PHP/mySQL Help, blog
    <input name="html5" type="text" required pattern="^$">

  6. #6
    SitePoint Wizard bronze trophy Jeff Mott's Avatar
    Join Date
    Jul 2009
    Posts
    1,276
    Mentioned
    18 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by felgall View Post
    No it isn't. Prototyping has approximately the same relationship to object oriented that object oriented has to procedural. Just as object oriented is far more powerful in many ways than procedural, prototyping is far more poweful than object oriented.

    While you can write procedural or object oriented code in JavaScript, if you limit yourself to using those then you are missing out on the really powerful parts of javaScript.
    OK. Well, actually, JavaScript is indeed object oriented, and "prototyping" is an object oriented design pattern. Where JS differs from languages like Java or C++ is in how they create new objects (based on a class blueprint vs based on a prototypical instance) and how they implement inheritance (classes inheriting from other classes vs objects inheriting from other objects via the "prototype chain"). But all of these behaviors nonetheless fall under the object oriented umbrella (software using a collection of interacting objects, where an object is a data structure with state and behavior bundled together).

    Perhaps you'd like to clarify with code examples how you distinguish writing "prototyping" code vs writing object oriented code.
    "First make it work. Then make it better."

  7. #7
    SitePoint Member
    Join Date
    Nov 2013
    Location
    London, UK
    Posts
    6
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Well it depends.. If you like OOP then you have to use it.

  8. #8
    Non-Member
    Join Date
    Feb 2012
    Posts
    892
    Mentioned
    10 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by codeweaver View Post
    Is object oriented programming in javascript used?
    There's little consensus about what OOP means when comparing programming languages. It's the same thing with browser sniffing. The browser is IE but it sends out a FF user agent string. Perhaps being more specific about the features you're after would help spawn more productive answers.

    Anyway, to the best of my knowledge, JS is best called "object based". This is to say that JS doesn't have specific mechanisms for classes which are found in a form or another in other languages. But this doesn't mean that JS can't emulate those patterns or even came up with some patterns of its own. Also, because JS is so flexible, a lot of patterns emerged and are still emerging.

    Some patterns try to emulate OOP from Java or Ruby, for example. Others give different interpretation for the prototypal pattern in JS. In the end, for every feature like encapsulation, inheritance, there are a number of patterns. All you need to do is to make an educated choice given a specific problem.

  9. #9
    Patience... bronze trophy solidcodes's Avatar
    Join Date
    Jul 2006
    Location
    Philippines
    Posts
    936
    Mentioned
    3 Post(s)
    Tagged
    0 Thread(s)
    @felgall ;

    Isn't it prototyping is just part of OOP?
    Because as far as I know prototyping is just like extending the class?
    Please correct me if I'm wrong.

    Also can you give a sample demonstration codes showing it's POWER ?

    Thanks in advance felgall.
    Quality codes are optimized and tested...
    Click here for inspiration..

  10. #10
    Non-Member
    Join Date
    Feb 2012
    Posts
    892
    Mentioned
    10 Post(s)
    Tagged
    0 Thread(s)
    Prototyping in JavaScript is a a reference chain, a reference tree. It's an easy way to get objects to share properties. This saves memory.

    The problem is that if the reference tree grows too deep, then there are performance penalties.

    So, the new wave JavaScript is "favor composition over inheritance". This keeps the reference tree shallow, permits objects to share properties, which save memory and doesn't have a negative impact on performance.

    The simple rule is if the prototype chain is more than two-three levels deep, use composition instead, even if it means loosing the prototype mechanism on the way.

  11. #11
    SitePoint Wizard bronze trophy Jeff Mott's Avatar
    Join Date
    Jul 2009
    Posts
    1,276
    Mentioned
    18 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by myty View Post
    The problem is that if the reference tree grows too deep, then there are performance penalties.

    ...

    The simple rule is if the prototype chain is more than two-three levels deep, use composition instead, even if it means loosing the prototype mechanism on the way.
    I've wondered myself what we should consider the prototype chain limit to be. I've never actually bothered to measure the performance differences before. So I googled around and found that someone has already set up a jsperf test.

    Most browsers seem to have comparable speeds, except for the latest Chrome, which blows them all out of the water.

    The latest Firefox and IE10 show similar patterns. Calling a function directly is moderately faster (10-15% or so), but calling a function through any of 1, 2, 3, or 4 prototype levels seems to take roughly the same amount of time.

    Chrome's results are downright weird. Calling a function from any prototype level was actually faster than calling the function directly.

    Most browsers, and especially Chrome, are slipping in so many and various kinds of optimizations that it's getting harder to look at a line of code and be able to predict how it'll perform.

    EDIT: This other jsperf test, on the other hand, has an almost identical setup, yet produces very different results.

    EDIT EDIT: Actually, that second test has a bug in it. z.prototype = new z should have been z.prototype = new y. After I made that change, then the results started looking more like the first jsperf test.
    "First make it work. Then make it better."

  12. #12
    PHP Guru lampcms.com's Avatar
    Join Date
    Jan 2009
    Posts
    921
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    JavaScript clearly has the basic features of object oriented programming.
    You can create objects that encapsulate data and objects can have methods that can manipulate object's data.
    Objects can inherit properties and methods from other objects through prototype link.
    You can use instanceof operator to check in objects is instance or a known type.

    It does not have many of the more advanced features found in pure object oriented languages like Java for example.
    It does not have reflection, it does not have support for annotations, does not have support for declaring type of variable and to require types for parameters, which is a very important part of most object oriented languages, even in php there is support for 'type hinting' which helps writing more resilient programs.
    Until recently there was no way to make properties private (yes through closure tricks it was always possible), but not there is Object.defineProperty() which is a very ugly way to declare properties of other objects but at least you can make a read-only property now.
    But originally JavaScript was designed to be run in the browser and to support just basic manipulation of html, even before the DOM model was finalized. It was also designed to be easy to learn, the idea was that a non-programmer can quickly learn to do basic things with JavaScript.

    Now that JavaScript is popular server-side language it certanly shows all the limitations that I mentioned, but nevertheless it still works pretty well in node.js and because of original goal to be very easy to learn, it looks like Node.js popularity is growing very fast.
    My project: Open source Q&A
    (similar to StackOverflow)
    powered by php+MongoDB
    Source on github, collaborators welcome!

  13. #13
    Non-Member
    Join Date
    Feb 2012
    Posts
    892
    Mentioned
    10 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by lampcms.com View Post
    Until recently there was no way to make properties private (yes through closure tricks it was always possible), but not there is Object.defineProperty() which is a very ugly way to declare properties of other objects but at least you can make a read-only property now.
    Since in JavaScript functions define scope, then depending on the inheritance pattern, actually there are more ways to make private members: in the constructor function or with IIFE (closures).

    And if you're talking about access modifiers, then read-only (writable: false) is not the equivalent for private, enumerable: false is.

  14. #14
    I solve practical problems. bronze trophy
    Michael Morris's Avatar
    Join Date
    Jan 2008
    Location
    Knoxville TN
    Posts
    2,034
    Mentioned
    65 Post(s)
    Tagged
    0 Thread(s)
    Possible isn't the same as intuitive. You can create private members of a JS class, but its not intuitive. Far from.

    Javascript is object oriented. It consists of Objects, supports Encapsulation, allows for Polymorphism. These are the basic properties of an object oriented language. Unlike the unrelated Java language, or C++, Javascript uses prototypical inheritance as has already been pointed out up thread. Why? Because you can do that in a purely interpreted language. Since both Java and C++ require compilation, they cannot ever follow prototypical inheritance patterns because those patterns require the language to be able to apply Just In Time compiling.

    While this leads to a very flexible and powerful language (albeit a bit sparse, though newer versions of the EMCA script standard do support "protected" and similar keywords) it does mean it will never be able to outperform it's compiled cousins.

    While we are on the subject, PHP occupies a weird worst-of-both-worlds middle ground. While it's interpreted, that interpretation is by file rather than by line as with Javascript. As a result, PHP has all the limits of a compiled language with all of the limits of an interpreted one, and none of the advantages of either unless byte code caching is employed.

  15. #15
    PHP Guru lampcms.com's Avatar
    Join Date
    Jan 2009
    Posts
    921
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Michael Morris View Post
    Since both Java and C++ require compilation, they cannot ever follow prototypical inheritance patterns .
    Are there any other languages that have prototypal inheritance? I mean other than JavaScript?
    My project: Open source Q&A
    (similar to StackOverflow)
    powered by php+MongoDB
    Source on github, collaborators welcome!

  16. #16
    Non-Member
    Join Date
    Feb 2012
    Posts
    892
    Mentioned
    10 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Michael Morris View Post
    You can create private members of a JS class, but its not intuitive. Far from.
    That's the thing: you don't have classes in JavaScript. Newer ECMAScript try to change that, but only as syntactic sugar. Sure, you can emulate classes, but the ones that emulate classes in JavaScript are the ones coming from Java or C++, that can't wrap their heads around prototype-based programming.

    Quote Originally Posted by Michael Morris View Post
    Javascript is object oriented. It consists of Objects, supports Encapsulation.
    There is no out-of-the-box support for encapsulation as in "restricted access to object's member", but it does support encapsulation as in "an object has method properties too". Newer ECMAScript try to change that.

    Quote Originally Posted by Michael Morris View Post
    These are the basic properties of an object oriented language. Unlike the unrelated Java language, or C++, Javascript uses prototypical inheritance as has already been pointed out up thread.
    I wouldn't say this is true. JavaScript is classless, even with newer syntactic sugar. It doesn't use class constructors to instantiate new objects, it uses object cloning to build new objects that inherit from other objects. JavaScript inheritance is by delegation (prototype). JavaScript inheritance is by concatenation.

    Quote Originally Posted by Michael Morris View Post
    Since both Java and C++ require compilation, they cannot ever follow prototypical inheritance patterns because those patterns require the language to be able to apply Just In Time compiling.
    I'm not sure how you fit JIT into all this. I'm pretty sure you can delegate or concatenate in Java or C++ for prototype patterns. I'm pretty sure you can copy or clone instances in Java and C++.

    Also, C++ doesn't JIT. In fact, Java used JIT trying to prove it outperforms C++, which is pretty lame. C++ compiles to native. This means a platform specific optimization as close to the metal as possible. JIT produces a bytecode, which is a platform-free general optimization.

    Quote Originally Posted by Michael Morris View Post
    While this leads to a very flexible and powerful language (albeit a bit sparse, though newer versions of the EMCA script standard do support "protected" and similar keywords) it does mean it will never be able to outperform it's compiled cousins.
    Yes, and this is true for Perl, Python, Ruby etcetera. What's the point?



    Quote Originally Posted by lampcms.com View Post
    Are there any other languages that have prototypal inheritance? I mean other than JavaScript?
    Yes. Lua, Object LISP. Also, using extensions, Perl, TCL, Python.

  17. #17
    SitePoint Wizard bronze trophy Jeff Mott's Avatar
    Join Date
    Jul 2009
    Posts
    1,276
    Mentioned
    18 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by myty View Post
    ...it uses object cloning to build new objects that inherit from other objects.
    Everything you said is great. I want to add just one little nuance, mostly because I've heard this terminology occasionally used elsewhere as well. I don't think "clone" is the right word to describe how JavaScript creates objects. Whether we're speaking in casual conversation or programming jargon, the word "clone" means an exact and **independent** copy. The "independent" part is important, because we don't get that feature from the way JavaScript creates objects. The new object will still be affected by changes to the original.

    Code JavaScript:
    var original = {
        name: 'foo'
    };
     
    var isThisAClone = Object.create(original);
     
    // it's an exact copy
    console.log(isThisAClone.name); // foo
     
    // but...
    original.name = 'bar';
     
    // it's not independent of the original
    console.log(isThisAClone.name); // bar
    "First make it work. Then make it better."

  18. #18
    Non-Member
    Join Date
    Feb 2012
    Posts
    892
    Mentioned
    10 Post(s)
    Tagged
    0 Thread(s)
    I believe it is.

    The nuance is more detailed inside the cloning mechanism, the inheritance method.

    You want to shallow copy object methods (delegation) and you want to deep copy object state. Though there are cases where you want to deep copy everything and decouple objects completely.

    It's the terminology used in many libraries, with the nuances I mentioned above:
    - http://lodash.com/docs#clone
    - http://lodash.com/docs#cloneDeep
    - http://underscorejs.org/#clone

    If you want a better word for it, then extend is another one used in many libraries, though it has slightly different functionality:
    - http://lodash.com/docs#assign
    - http://underscorejs.org/#extend

    What I believe to be a point of confusion is how objects are always passed by reference in JavaScript. So, copy or clone, the result is the same when it comes to complex types. You need to specify deep to make things clear.

  19. #19
    SitePoint Wizard bronze trophy Jeff Mott's Avatar
    Join Date
    Jul 2009
    Posts
    1,276
    Mentioned
    18 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by myty View Post
    You want to shallow copy object methods (delegation) and you want to deep copy object state. Though there are cases where you want to deep copy everything and decouple objects completely.
    And yet, Object.create doesn't do any copying of any kind -- neither shallow nor deep. That's why changing even just primitive values of the original affects the "clone".

    Quote Originally Posted by myty View Post
    It's the terminology used in many libraries, with the nuances I mentioned above:
    - http://lodash.com/docs#clone
    - http://lodash.com/docs#cloneDeep
    - http://underscorejs.org/#clone
    But none of those clone implementations use Object.create or the prototype chain to produce the result. Probably because that wouldn't give us the behavior that we would expect of a clone.

    Quote Originally Posted by myty View Post
    What I believe to be a point of confusion is how objects are always passed by reference in JavaScript. So, copy or clone, the result is the same when it comes to complex types. You need to specify deep to make things clear.
    Not a point of confusion. Not even primitive values are copied. That's why changing a primitive value of the original still affects the clone.

    Quote Originally Posted by myty View Post
    If you want a better word for it, then extend is another one used in many libraries, though it has slightly different functionality:
    - http://lodash.com/docs#assign
    - http://underscorejs.org/#extend
    Probably the least ambiguous is to say that x inherits from y, because JavaScript does inheritance only one way, and we know what behaviors that implies. It probably shouldn't be ambiguous to say that x extends y or that we extended y to produce x, but alas some libraries implement extend as a "mix in".
    "First make it work. Then make it better."

  20. #20
    I solve practical problems. bronze trophy
    Michael Morris's Avatar
    Join Date
    Jan 2008
    Location
    Knoxville TN
    Posts
    2,034
    Mentioned
    65 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by myty View Post
    That's the thing: you don't have classes in JavaScript.
    True. You have prototypes. And everything in javascript is an object. Even the functions are objects.

    "class"ical inheritance
    "prototyp"ical inheritance

    They are two different things. Javascript doesn't have classes because it doesn't need them. You can emulate classes in the prototypical paradigm if you want to because it is much, much more powerful.

    Newer ECMAScript try to change that, but only as syntactic sugar. Sure, you can emulate classes, but the ones that emulate classes in JavaScript are the ones coming from Java or C++, that can't wrap their heads around prototype-based programming.
    Or the ones that feel the language needs that functionality. I know I once did. Now, I'm not so sure if it needs it.

    There is no out-of-the-box support for encapsulation as in "restricted access to object's member", but it does support encapsulation as in "an object has method properties too". Newer ECMAScript try to change that.
    Actually, there is - but it isn't intuitive. It involves exploiting how scope works in js.


    I'm not sure how you fit JIT into all this. I'm pretty sure you can delegate or concatenate in Java or C++ for prototype patterns. I'm pretty sure you can copy or clone instances in Java and C++.
    There are no prototype patterns possible in Java or C++ because these languages cannot (well, probably more accurate to say should not - buffer overflowing is a key exploit concept) arbitrarily execute data as code.

    Javascript allows you to compose wholly new blocks of executable code on the fly. This just isn't possible in Java, C, or any other compiled language, precisely because they are compiled languages.

    Also, C++ doesn't JIT. In fact, Java used JIT trying to prove it outperforms C++, which is pretty lame. C++ compiles to native. This means a platform specific optimization as close to the metal as possible. JIT produces a bytecode, which is a platform-free general optimization.
    Java doesn't JIT code in the manner that a JS interpreter does. The bytecode of compiled Java runs on a specialized java virtual machine. You can run C code for a 68000 processor on an x86 machine with a virtual machine - hell you can run assembler for older processors on a virtual machine if you want. This is how MAME, BZSNES and the myriad other emulators out there work.

    But Java doesn't allow you to recompile the byte code at run time in any meaningful way. JavaScript does. JavaScript pays the price for this trick though - it's hella slower than Java or C.

  21. #21
    Non-Member
    Join Date
    Feb 2012
    Posts
    892
    Mentioned
    10 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Jeff Mott View Post
    And yet, Object.create doesn't do any copying of any kind -- neither shallow nor deep. That's why changing even just primitive values of the original affects the "clone".
    [...]
    Not a point of confusion. Not even primitive values are copied. That's why changing a primitive value of the original still affects the clone.
    Object.create creates a new object, builds a prototype, all that screams reference. So, I'm not sure how you'd expect referenced primitive values in the prototype to be treated otherwise...? Maybe you're making a confusion about passing values and prototype values.

    And to be clear, Object.create does make a shallow copy. That's why it's useless for creating object state.


    Quote Originally Posted by Jeff Mott View Post
    But none of those clone implementations use Object.create or the prototype chain to produce the result. Probably because that wouldn't give us the behavior that we would expect of a clone.
    I'm not sure what you expect me to respond here. I never mentioned Object.create...

  22. #22
    Non-Member
    Join Date
    Feb 2012
    Posts
    892
    Mentioned
    10 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Michael Morris View Post
    True. You have prototypes. And everything in javascript is an object. Even the functions are objects.
    Almost everything is an object in JavaScript. Primitive types are not objects: strings, numbers, booleans. However, and this is where this almost comes from:
    - a wrapper object is created for these primitive values if there is a native method call on them;
    - even if the wrapper object is created, it's temporary, so it can't be used to attach properties to primitive values.


    Quote Originally Posted by Michael Morris View Post
    Actually, there is - but it isn't intuitive. It involves exploiting how scope works in js.
    Yes, but it's not out of the box. The module pattern, the revealing pattern are not out-of the-box solutions. There will be out-of-the-box support along with ECMAScript 6 which introduces classes sugar and the private keyword.


    Quote Originally Posted by Michael Morris View Post
    There are no prototype patterns possible in Java or C++ because these languages cannot (well, probably more accurate to say should not - buffer overflowing is a key exploit concept) arbitrarily execute data as code.
    There is a prototype design pattern used in Java, which involves the clone concept, overwritten or not.


    Quote Originally Posted by Michael Morris View Post
    But Java doesn't allow you to recompile the byte code at run time in any meaningful way. JavaScript does. JavaScript pays the price for this trick though - it's hella slower than Java or C.
    Actually, Java does precisely this with JIT. JIT takes bytecode and tries to improve performance by compiling it to native code **at run time**. But that's the theory. In practice JIT returns both compiled to native and bytecode, because compiling it all to native would result in worse performance, not better.

    And JavaScript may or may not produce bytecode. It could be directly translated to native code.

  23. #23
    SitePoint Wizard bronze trophy Jeff Mott's Avatar
    Join Date
    Jul 2009
    Posts
    1,276
    Mentioned
    18 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by myty View Post
    Object.create creates a new object, builds a prototype, all that screams reference. So, I'm not sure how you'd expect referenced primitive values in the prototype to be treated otherwise...?
    I don't expect them to be treated differently. The point is this isn't a clone.

    To re-clarify, this is what I've been responding to:

    " [JavaScript] uses object cloning to build new objects that inherit from other objects."

    But when we build a new object that inherits from another object (aka Object.create), that's not a clone we created. A clone is expected to be independent of the original (aka deep copy). But not only does Object.create not deep copy, it doesn't even shallow copy. There's no copying of any kind. That's why changing even primitive values in the original affects the new object. And that's why this isn't a clone operation.
    "First make it work. Then make it better."

  24. #24
    Non-Member
    Join Date
    Feb 2012
    Posts
    892
    Mentioned
    10 Post(s)
    Tagged
    0 Thread(s)
    I believe you're not understanding this quite well, object property vs. parameter or variable with a primitive value.

    Object.create does a shallow copy for the properties, not for the values. If the property happens to be a primitive values, it's still a property, it's not a primitive value.

    Changing the properties that are primitive values are universal because they belong in an object, and an object, as a whole, is shallow copied with Object.create.


    Also, you're hanging on too much on the strict meaning of the clone word. You could be thinking the same thing about the word prototype...

  25. #25
    SitePoint Addict bronze trophy
    Join Date
    Apr 2013
    Location
    Ithaca
    Posts
    351
    Mentioned
    6 Post(s)
    Tagged
    1 Thread(s)
    Prototyping definitely is object oriented, there's no doubt about it. There have always been debates of whether class or prototype based languages are more object oriented than the other, its really up for your own interpretation. Still, not everyone gets used to Javascript's OOP as its significantly different from what most of us were taught about object oriented programming in the very first place. Once a habit, its difficult to change. Its not javascript's fault though.


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •