Skip to main content
Deleted superfluous jsFiddle links and unused URLs, converted tabs into spaces, fixed comment alignment and removed some more fluff
Source Link
Palec
  • 13.4k
  • 8
  • 74
  • 141

This plugin plugin can still be used as simple asin an if statement like if ($(ele).exist()) { /* DO WORK */ } or using a callback.

jsFiddle

;;(function($) {
    if (!$.exist) {
        $.extend({
            exist: function() {
                var ele, cbmExist, cbmNotExist;
                if (arguments.length) {
                    for (x in arguments) {
                        switch (typeof arguments[x]) {
                            case 'function':
                                if (typeof cbmExist == "undefined") cbmExist = arguments[x];
                                else cbmNotExist = arguments[x];
                                break;
                            case 'object':
                                if (arguments[x] instanceof jQuery) ele = arguments[x];
                                else {
                                    var obj = arguments[x];
                                    for (y in obj) {
                                        if (typeof obj[y] == 'function') {
                                            if (typeof cbmExist == "undefined") cbmExist = obj[y];
                                            else cbmNotExist = obj[y];
                                        }
                                        if (typeof obj[y] == 'object' && obj[y] instanceof jQuery) ele = obj[y];
                                        if (typeof obj[y] == 'string') ele = $(obj[y]);
                                    }
                                }
                                break;
                            case 'string':
                                ele = $(arguments[x]);
                                break;
                        }
                    }
                }
                
                if (typeof cbmExist == 'function') {
                    var exist =  ele.length > 0 ? true : false;
                    if (exist) {
                        return ele.each(function(i) { cbmExist.apply(this, [exist, ele, i]); });
                    }
                    else if (typeof cbmNotExist == 'function') {
                        cbmNotExist.apply(ele, [exist, ele]);
                        return ele;
                    }
                    else {
                        if (ele.length <= 1) return ele.length > 0 ? true : false;
                        else return ele.length;
                    }
                }
                else {  
                    if (ele.length <= 1) return ele.length > 0 ? true : false; 
                    else return ele.length; 
                }
                
                return false; 
            }
        });
        $.fn.extend({
            exist: function() {
                var args = [$(this)];
                if (arguments.length) for (x in arguments) args.push(arguments[x]);
                return $.exist.apply($, args);
            }
        });
    }
})(jQuery);

You can use an if: statement,may specify one or you can create your own callback.

Keep in mind, the callback has 2 possible creationstwo callbacks.

  The second functionfirst one will fire if the element does NOT exist. Howeverexists, if you choose to set onlythe second one function, then it will only fire when the element exist. Thus the "chain" will die if the selected element does "not" exist. However, if you choose to pass only one function, it will only fire when the element exists. Thus, the chain will die if the selected element does not exist. Of course, if it does exist, the first function will fire and chainabilitythe chain will continue.

On another note, keep in mind, using a callback method helps to maintain chainability. This means the element is returned and you can continue chaining commands as with any other jQuery method!

jsFiddle Keep in mind that using the callback variant helps maintain chainability – the element is returned and you can continue chaining commands as with any other jQuery method!

if ($.exist('#eleID')) {    /*    DO WORK    */ }        //    param as STRING
if ($.exist($('#eleID'))) { /*    DO WORK    */ }        //    param as jQuery OBJECT
if ($('#eleID').exist()) {  /*    DO WORK    */ }        //    enduced on jQuery OBJECT

$.exist('#eleID', function() {            //    param is STRING && CALLBACK METHOD
    /*    DO WORK    */
    /*    This will ONLY fire if the element EXIST    */
}, function() {            //    param is STRING && CALLBACK METHOD
    /*    DO WORK    */
    /*    This will ONLY fire if the element DOES NOT EXIST    */
})

$('#eleID').exist(function() {            //    enduced on jQuery OBJECT with CALLBACK METHOD
    /*    DO WORK    */
    /*  Will  This will ONLY FIREfire IFif the element EXIST    */
})

$.exist({                        //    param is OBJECT containing 2 key|value pairs: element = STRING, callback = METHOD
    element: '#eleID',
    callback: function() {
        /*    DO WORK    */
        /*    This will ONLY fire if the element EXIST    */
    }
})

This plugin plugin can still be used as simple as if ($(ele).exist()) { /* DO WORK */ } or using a callback.

jsFiddle

;;(function($) {
    if (!$.exist) {
        $.extend({
            exist: function() {
                var ele, cbmExist, cbmNotExist;
                if (arguments.length) {
                    for (x in arguments) {
                        switch (typeof arguments[x]) {
                            case 'function':
                                if (typeof cbmExist == "undefined") cbmExist = arguments[x];
                                else cbmNotExist = arguments[x];
                                break;
                            case 'object':
                                if (arguments[x] instanceof jQuery) ele = arguments[x];
                                else {
                                    var obj = arguments[x];
                                    for (y in obj) {
                                        if (typeof obj[y] == 'function') {
                                            if (typeof cbmExist == "undefined") cbmExist = obj[y];
                                            else cbmNotExist = obj[y];
                                        }
                                        if (typeof obj[y] == 'object' && obj[y] instanceof jQuery) ele = obj[y];
                                        if (typeof obj[y] == 'string') ele = $(obj[y]);
                                    }
                                }
                                break;
                            case 'string':
                                ele = $(arguments[x]);
                                break;
                        }
                    }
                }
                
                if (typeof cbmExist == 'function') {
                    var exist =  ele.length > 0 ? true : false;
                    if (exist) {
                        return ele.each(function(i) { cbmExist.apply(this, [exist, ele, i]); });
                    }
                    else if (typeof cbmNotExist == 'function') {
                        cbmNotExist.apply(ele, [exist, ele]);
                        return ele;
                    }
                    else {
                        if (ele.length <= 1) return ele.length > 0 ? true : false;
                        else return ele.length;
                    }
                }
                else {  
                    if (ele.length <= 1) return ele.length > 0 ? true : false; 
                    else return ele.length; 
                }
                
                return false; 
            }
        });
        $.fn.extend({
            exist: function() {
                var args = [$(this)];
                if (arguments.length) for (x in arguments) args.push(arguments[x]);
                return $.exist.apply($, args);
            }
        });
    }
})(jQuery);

You can use an if: statement, or you can create your own callback.

Keep in mind, the callback has 2 possible creations.

  The second function will fire if the element does NOT exist. However, if you choose to set only one function, then it will only fire when the element exist. Thus the "chain" will die if the selected element does "not" exist. Of course, if it does exist, the first function will fire and chainability will continue.

On another note, keep in mind, using a callback method helps to maintain chainability. This means the element is returned and you can continue chaining commands as with any other jQuery method!

jsFiddle

if ($.exist('#eleID')) { /* DO WORK */ }        //  param as STRING
if ($.exist($('#eleID'))) { /*  DO WORK */ }    //  param as jQuery OBJECT
if ($('#eleID').exist()) { /*   DO WORK */ }        //  enduced on jQuery OBJECT

$.exist('#eleID', function() {          //  param is STRING && CALLBACK METHOD
    /*  DO WORK */
    /*  This will ONLY fire if the element EXIST    */
}, function() {         //  param is STRING && CALLBACK METHOD
    /*  DO WORK */
    /*  This will ONLY fire if the element DOES NOT EXIST   */
})

$('#eleID').exist(function() {          //  enduced on jQuery OBJECT with CALLBACK METHOD
    /*  DO WORK */
    /*  Will ONLY FIRE IF EXIST */
})

$.exist({                       //  param is OBJECT containing 2 key|value pairs: element = STRING, callback = METHOD
    element: '#eleID',
    callback: function() {
        /*  DO WORK */
    /*  This will ONLY fire if the element EXIST    */
    }
})

This plugin can be used in an if statement like if ($(ele).exist()) { /* DO WORK */ } or using a callback.

;;(function($) {
    if (!$.exist) {
        $.extend({
            exist: function() {
                var ele, cbmExist, cbmNotExist;
                if (arguments.length) {
                    for (x in arguments) {
                        switch (typeof arguments[x]) {
                            case 'function':
                                if (typeof cbmExist == "undefined") cbmExist = arguments[x];
                                else cbmNotExist = arguments[x];
                                break;
                            case 'object':
                                if (arguments[x] instanceof jQuery) ele = arguments[x];
                                else {
                                    var obj = arguments[x];
                                    for (y in obj) {
                                        if (typeof obj[y] == 'function') {
                                            if (typeof cbmExist == "undefined") cbmExist = obj[y];
                                            else cbmNotExist = obj[y];
                                        }
                                        if (typeof obj[y] == 'object' && obj[y] instanceof jQuery) ele = obj[y];
                                        if (typeof obj[y] == 'string') ele = $(obj[y]);
                                    }
                                }
                                break;
                            case 'string':
                                ele = $(arguments[x]);
                                break;
                        }
                    }
                }
                
                if (typeof cbmExist == 'function') {
                    var exist =  ele.length > 0 ? true : false;
                    if (exist) {
                        return ele.each(function(i) { cbmExist.apply(this, [exist, ele, i]); });
                    }
                    else if (typeof cbmNotExist == 'function') {
                        cbmNotExist.apply(ele, [exist, ele]);
                        return ele;
                    }
                    else {
                        if (ele.length <= 1) return ele.length > 0 ? true : false;
                        else return ele.length;
                    }
                }
                else {
                    if (ele.length <= 1) return ele.length > 0 ? true : false;
                    else return ele.length;
                }
                
                return false;
            }
        });
        $.fn.extend({
            exist: function() {
                var args = [$(this)];
                if (arguments.length) for (x in arguments) args.push(arguments[x]);
                return $.exist.apply($, args);
            }
        });
    }
})(jQuery);

You may specify one or two callbacks. The first one will fire if the element exists, the second one will fire if the element does not exist. However, if you choose to pass only one function, it will only fire when the element exists. Thus, the chain will die if the selected element does not exist. Of course, if it does exist, the first function will fire and the chain will continue.

Keep in mind that using the callback variant helps maintain chainability – the element is returned and you can continue chaining commands as with any other jQuery method!

if ($.exist('#eleID')) {    /*    DO WORK    */ }        //    param as STRING
if ($.exist($('#eleID'))) { /*    DO WORK    */ }        //    param as jQuery OBJECT
if ($('#eleID').exist()) {  /*    DO WORK    */ }        //    enduced on jQuery OBJECT

$.exist('#eleID', function() {            //    param is STRING && CALLBACK METHOD
    /*    DO WORK    */
    /*    This will ONLY fire if the element EXIST    */
}, function() {            //    param is STRING && CALLBACK METHOD
    /*    DO WORK    */
    /*    This will ONLY fire if the element DOES NOT EXIST    */
})

$('#eleID').exist(function() {            //    enduced on jQuery OBJECT with CALLBACK METHOD
    /*    DO WORK    */
    /*    This will ONLY fire if the element EXIST    */
})

$.exist({                        //    param is OBJECT containing 2 key|value pairs: element = STRING, callback = METHOD
    element: '#eleID',
    callback: function() {
        /*    DO WORK    */
        /*    This will ONLY fire if the element EXIST    */
    }
})
deleted 2752 characters in body
Source Link
user229044
  • 237.2k
  • 41
  • 341
  • 342

Extreme Update Oct 2, '13


Originally I made this plugin to provide a bit more acute sense than simply if ($(ele).length) { /* DO WORK */ }. Sure that is simple and easy, but I didn't like how it took me "outside" of typical "jQuery style". I really wanted a $.fn.exist() method in order to maintain readable markup. Also, the simple plugins so often previously suggested, do not account for developer error. Thus the creation of the very simple plugin found here (minified).

I soon decided to kick it up a notch and provide for more functionality in checking against developer mistakes as well as provide a bit more functionality. The thought lead me to the update on Jun 6, '13 found over here (minified). Now I've finally put together a version I really like!

This new version of theplugin plugin can still be used as simple as if ($(ele).exist()) { /* DO WORK */ }, however I found that to be or using a bit "against the grain" with jQuery typical markup stylecallback. I thought, "Why the if statement? Shouldn't that be in a callback?" Now it is! Behold, the new, bigger, stronger, callbackier $.exist() Plugin!

jsFiddle

jsFiddle

The use is extremely easy. YouYou can still use in an if: statement, or you can create your own callback. Keep

Keep in mind, the callback has 2 possible creations. You can create the call back with NO PARAMETERS such as function() {} and it will ONLY FIRE IF the element EXIST. However, if you provide a parameter, such as function(exist) {} or even function(bob) {}, then the callback will ALWAYS FIRE even if the element does NOT EXIST. In the second scenario, your parameter, no mater what you name it, becomes a BOOLEAN of wether or not the element exist.

UPDATE: After a little more personal use, I found the "parameter" setup to be a bit flawed. I've since replaced it with a better working ideal of allowing for a "second" function. The second function will fire if the element does NOT exist. However, if you choose to set only one function, then it will only fire when the element exist. Thus the "chain" will die if the selected element does "not" exist. Of course, if it does exist, the first function will fire and chainability will continue.

Minified jsFiddle

;;(function($){$.exist||($.extend({exist:function(){var a,c,d;if(arguments.length)for(x in arguments)switch(typeof arguments[x]){case "function":"undefined"==typeof c?c=arguments[x]:d=arguments[x];break;case "object":if(arguments[x]instanceof jQuery)a=arguments[x];else{var b=arguments[x];for(y in b)"function"==typeof b[y]&&("undefined"==typeof c?c=b[y]:d=b[y]),"object"==typeof b[y]&&b[y]instanceof jQuery&&(a=b[y]),"string"==typeof b[y]&&(a=$(b[y]))}break;case "string":a=$(arguments[x])}if("function"==typeof c){var e=0<a.length?!0:!1;if(e)return a.each(function(b){c.apply(this,[e,a,b])});if("function"==typeof d)return d.apply(a,[e,a]),a}return 1>=a.length?0<a.length?!0:!1:a.length}}),$.fn.extend({exist:function(){var a=[$(this)];if(arguments.length)for(x in arguments)a.push(arguments[x]);return $.exist.apply($,a)}}))})(jQuery);

NOTE: All minified versions were made using Google Closure

Extreme Update Oct 2, '13


Originally I made this plugin to provide a bit more acute sense than simply if ($(ele).length) { /* DO WORK */ }. Sure that is simple and easy, but I didn't like how it took me "outside" of typical "jQuery style". I really wanted a $.fn.exist() method in order to maintain readable markup. Also, the simple plugins so often previously suggested, do not account for developer error. Thus the creation of the very simple plugin found here (minified).

I soon decided to kick it up a notch and provide for more functionality in checking against developer mistakes as well as provide a bit more functionality. The thought lead me to the update on Jun 6, '13 found over here (minified). Now I've finally put together a version I really like!

This new version of the plugin can still be used as simple as if ($(ele).exist()) { /* DO WORK */ }, however I found that to be a bit "against the grain" with jQuery typical markup style. I thought, "Why the if statement? Shouldn't that be in a callback?" Now it is! Behold, the new, bigger, stronger, callbackier $.exist() Plugin!

jsFiddle

The use is extremely easy. You can still use in an if: statement, or you can create your own callback. Keep in mind, the callback has 2 possible creations. You can create the call back with NO PARAMETERS such as function() {} and it will ONLY FIRE IF the element EXIST. However, if you provide a parameter, such as function(exist) {} or even function(bob) {}, then the callback will ALWAYS FIRE even if the element does NOT EXIST. In the second scenario, your parameter, no mater what you name it, becomes a BOOLEAN of wether or not the element exist.

UPDATE: After a little more personal use, I found the "parameter" setup to be a bit flawed. I've since replaced it with a better working ideal of allowing for a "second" function. The second function will fire if the element does NOT exist. However, if you choose to set only one function, then it will only fire when the element exist. Thus the "chain" will die if the selected element does "not" exist. Of course, if it does exist, the first function will fire and chainability will continue.

Minified jsFiddle

;;(function($){$.exist||($.extend({exist:function(){var a,c,d;if(arguments.length)for(x in arguments)switch(typeof arguments[x]){case "function":"undefined"==typeof c?c=arguments[x]:d=arguments[x];break;case "object":if(arguments[x]instanceof jQuery)a=arguments[x];else{var b=arguments[x];for(y in b)"function"==typeof b[y]&&("undefined"==typeof c?c=b[y]:d=b[y]),"object"==typeof b[y]&&b[y]instanceof jQuery&&(a=b[y]),"string"==typeof b[y]&&(a=$(b[y]))}break;case "string":a=$(arguments[x])}if("function"==typeof c){var e=0<a.length?!0:!1;if(e)return a.each(function(b){c.apply(this,[e,a,b])});if("function"==typeof d)return d.apply(a,[e,a]),a}return 1>=a.length?0<a.length?!0:!1:a.length}}),$.fn.extend({exist:function(){var a=[$(this)];if(arguments.length)for(x in arguments)a.push(arguments[x]);return $.exist.apply($,a)}}))})(jQuery);

NOTE: All minified versions were made using Google Closure

This plugin plugin can still be used as simple as if ($(ele).exist()) { /* DO WORK */ } or using a callback.

jsFiddle

You can use an if: statement, or you can create your own callback.

Keep in mind, the callback has 2 possible creations.

The second function will fire if the element does NOT exist. However, if you choose to set only one function, then it will only fire when the element exist. Thus the "chain" will die if the selected element does "not" exist. Of course, if it does exist, the first function will fire and chainability will continue.

deleted 690 characters in body
Source Link
SpYk3HH
  • 22.5k
  • 11
  • 70
  • 81
if ($.exist('#eleID')) { /* DO WORK */ }        //  param as STRING
if ($.exist($('#eleID'))) { /*  DO WORK */ }    //  param as jQuery OBJECT
if ($('#eleID').exist()) { /*   DO WORK */ }        //  enduced on jQuery OBJECT

$.exist('#eleID', function() {          //  param is STRING && CALLBACK METHOD
    /*  DO WORK */
    /*  This will ONLY fire if the element EXIST    */
})

$('#eleID').exist(, function() {          //  enduced onparam jQueryis OBJECTSTRING with&& CALLBACK METHOD
    /*  DO WORK */
    /*  WillThis will ONLY FIREfire IFif the element DOES NOT EXIST   */
})

$('#eleID').exist({            function() {          //  param is OBJECT containing 2 key|value pairs:enduced elementon =jQuery STRING,OBJECT callbackwith =CALLBACK METHOD
    element: '#eleID',
    callback: function(exist) {
        /*  DO WORK */
    /*  Will ALWAYSONLY FIRE  IF EXIST */
    }
})

$.exist({                       //  param is OBJECT containing 2 key|value pairs: element = jQuery OBJECTSTRING, callback = METHOD
    element: $('#eleID'),
    callback: function() {
        /*  DO WORK */
    /*  Will ONLY FIRE IF EXIST */
    }
})

$.exist([                       //  param is ARRAY containing 2 key|value pairs: jQuery STRING, METHOD
    '#eleID',
    function(exist) {
        /*  DO WORK */
    /* This Willwill ONLY FIRE IF EXIST */
    }
])

//  Will only callbackfire if true'
$.exist([                       //  param is ARRAY containing 2 key|value pairs: jQuery OBJECT, METHOD
    $('#eleID'),
    function() {
        /*  DO WORK */
    /*the element WillEXIST ONLY FIRE IF EXIST */
    }
])

$.exist({ element: '#eleID' });     //  param is OBJECT containing 1 key|value pairs: element = STRING

$.exist({ element: $('#eleID') });      //  param is OBJECT containing 1 key|value pairs: element = jQuery OBJECT
if ($.exist('#eleID')) { /* DO WORK */ }        //  param as STRING
if ($.exist($('#eleID'))) { /*  DO WORK */ }    //  param as jQuery OBJECT
if ($('#eleID').exist()) { /*   DO WORK */ }        //  enduced on jQuery OBJECT

$.exist('#eleID', function() {          //  param is STRING && CALLBACK METHOD
    /*  DO WORK */
    /*  This will ONLY fire if the element EXIST    */
})

$('#eleID').exist(function() {          //  enduced on jQuery OBJECT with CALLBACK METHOD
    /*  DO WORK */
    /*  Will ONLY FIRE IF EXIST */
})

$.exist({                       //  param is OBJECT containing 2 key|value pairs: element = STRING, callback = METHOD
    element: '#eleID',
    callback: function(exist) {
        /*  DO WORK */
    /*  Will ALWAYS FIRE    */
    }
})

$.exist({                       //  param is OBJECT containing 2 key|value pairs: element = jQuery OBJECT, callback = METHOD
    element: $('#eleID'),
    callback: function() {
        /*  DO WORK */
    /*  Will ONLY FIRE IF EXIST */
    }
})

$.exist([                       //  param is ARRAY containing 2 key|value pairs: jQuery STRING, METHOD
    '#eleID',
    function(exist) {
        /*  DO WORK */
    /*  Will ONLY FIRE IF EXIST */
    }
])

//  Will only callback if true'
$.exist([                       //  param is ARRAY containing 2 key|value pairs: jQuery OBJECT, METHOD
    $('#eleID'),
    function() {
        /*  DO WORK */
    /*  Will ONLY FIRE IF EXIST */
    }
])

$.exist({ element: '#eleID' });     //  param is OBJECT containing 1 key|value pairs: element = STRING

$.exist({ element: $('#eleID') });      //  param is OBJECT containing 1 key|value pairs: element = jQuery OBJECT
if ($.exist('#eleID')) { /* DO WORK */ }        //  param as STRING
if ($.exist($('#eleID'))) { /*  DO WORK */ }    //  param as jQuery OBJECT
if ($('#eleID').exist()) { /*   DO WORK */ }        //  enduced on jQuery OBJECT

$.exist('#eleID', function() {          //  param is STRING && CALLBACK METHOD
    /*  DO WORK */
    /*  This will ONLY fire if the element EXIST    */
}, function() {         //  param is STRING && CALLBACK METHOD
    /*  DO WORK */
    /*  This will ONLY fire if the element DOES NOT EXIST   */
})

$('#eleID').exist(function() {          //  enduced on jQuery OBJECT with CALLBACK METHOD
    /*  DO WORK */
    /*  Will ONLY FIRE IF EXIST */
})

$.exist({                       //  param is OBJECT containing 2 key|value pairs: element = STRING, callback = METHOD
    element: '#eleID',
    callback: function() {
        /*  DO WORK */
    /*  This will ONLY fire if the element EXIST    */
    }
})
Please do not use user input formatting for links.
Source Link
animuson
  • 54.5k
  • 28
  • 141
  • 149
Loading
added 2 characters in body
Source Link
SpYk3HH
  • 22.5k
  • 11
  • 70
  • 81
Loading
Rollback to Revision 16
Source Link
SpYk3HH
  • 22.5k
  • 11
  • 70
  • 81
Loading
edited body
Source Link
Blue Skies
  • 3k
  • 18
  • 19
Loading
Rollback to Revision 16
Source Link
Blue Skies
  • 3k
  • 18
  • 19
Loading
It'll never be a good solution, but at least we can make it a tiny bit less terrible.
Source Link
Blue Skies
  • 3k
  • 18
  • 19
Loading
Rollback to Revision 14
Source Link
SpYk3HH
  • 22.5k
  • 11
  • 70
  • 81
Loading
FIXED implict globals that appeared in both functions
Source Link
Blue Skies
  • 3k
  • 18
  • 19
Loading
deleted 265 characters in body
Source Link
SpYk3HH
  • 22.5k
  • 11
  • 70
  • 81
Loading
added 352 characters in body; Post Made Community Wiki
Source Link
SpYk3HH
  • 22.5k
  • 11
  • 70
  • 81
Loading
added 25 characters in body
Source Link
SpYk3HH
  • 22.5k
  • 11
  • 70
  • 81
Loading
added 23 characters in body
Source Link
SpYk3HH
  • 22.5k
  • 11
  • 70
  • 81
Loading
added 205 characters in body
Source Link
SpYk3HH
  • 22.5k
  • 11
  • 70
  • 81
Loading
added 55 characters in body
Source Link
SpYk3HH
  • 22.5k
  • 11
  • 70
  • 81
Loading
Fully created plugin with new callback feature!
Source Link
SpYk3HH
  • 22.5k
  • 11
  • 70
  • 81
Loading
added 127 characters in body
Source Link
SpYk3HH
  • 22.5k
  • 11
  • 70
  • 81
Loading
Major overhaul!
Source Link
SpYk3HH
  • 22.5k
  • 11
  • 70
  • 81
Loading
Major overhaul!
Source Link
SpYk3HH
  • 22.5k
  • 11
  • 70
  • 81
Loading
added 21 characters in body
Source Link
SpYk3HH
  • 22.5k
  • 11
  • 70
  • 81
Loading
Copy edited.
Source Link
Peter Mortensen
  • 31.3k
  • 22
  • 109
  • 132
Loading
added 228 characters in body
Source Link
SpYk3HH
  • 22.5k
  • 11
  • 70
  • 81
Loading
Source Link
SpYk3HH
  • 22.5k
  • 11
  • 70
  • 81
Loading