PageSourceSearch

https://golijainfo.rs/wp-content/plugins/realhomes-elementor-addon/elementor/js/frontend.js?ver=2.4.1

js golijainfo.rs collected 2026-09-25 10:35:28 UTC 78,445 bytes, 1,903 lines download raw bytes

1( function ( $ ) {
2    "use strict";
3
4    const $window = $( window );
5
6    window.rheaIsRTL = function () {
7        let isRTL = false;
8        if ( document.querySelector( 'body' ).classList.contains( 'rtl' ) ) {
9            isRTL = true;
10        }
11        return isRTL;
12    }
13
14    $( document ).ready( function () {
15        /*-----------------------------------------------------------------------------------*/
16        /* Home page properties pagination
17        /*-----------------------------------------------------------------------------------*/
18        const $body = $( 'body' );
19        $body.on( 'click', '.rhea_pagination_wrapper a', function ( e ) {
20            e.preventDefault();
21
22            var thisParent = $( this ).parents( '.rhea_ele_property_ajax_target' );
23            var id         = $( thisParent ).attr( 'id' );
24            var thisLoader = $( thisParent ).find( '.rhea_svg_loader' );
25            var thisInner  = $( thisParent ).find( '.home-properties-section-inner-target' );
26            var pageNav    = $( thisParent ).find( '.rhea_pagination_wrapper a' );
27            var thisLink   = $( this );
28
29            if ( ! ( thisLink ).hasClass( 'current' ) ) {
30                var link = $( this ).attr( 'href' );
31                thisInner.fadeTo( 'slow', 0.5 );
32
33                thisLoader.slideDown( 'fast' );
34                // thisContent.fadeOut('fast', function(){
35                thisParent.load( link + ' #' + id + ' .home-properties-section-inner-target', function ( response, status, xhr ) {
36                    if ( status == 'success' ) {
37                        thisInner.fadeTo( 'fast', 1 );
38                        pageNav.removeClass( 'current' );
39                        thisLink.addClass( 'current' );
40                        thisLoader.slideUp( 'fast' );
41                        if ( typeof EREloadNewsSlider != 'undefined' && $.isFunction( EREloadNewsSlider ) ) {
42                            EREloadNewsSlider();
43                        }
44                        if ( typeof setVideoHeightElementor != 'undefined' && $.isFunction( setVideoHeightElementor ) ) {
45                            setVideoHeightElementor();
46                        }
47                        $( 'html, body' ).animate( {
48                            scrollTop : $( '#' + id ).offset().top - 32
49                        }, 1000 );
50
51                    } else {
52                        thisInner.fadeTo( 'fast', 1 );
53                        thisLoader.slideUp( 'fast' );
54                    }
55                } );
56            }
57        } );
58
59        $body.on( "click", ".rhea-ultra-properties-ajax-pagination a", function ( event ) {
60            const $this                  = $( this ),
61                  currentPageNum         = parseInt( $this.data( 'page' ) ),
62                  propertiesContainer    = $this.closest( ".rhea-ultra-properties-container" ),
63                  propertiesInner        = propertiesContainer.find( '.rhea-ultra-properties-inner-container' ),
64                  propertiesStatsWrapper = propertiesContainer.find( '.rhea-ultra-properties-top-bar-stats-wrapper' ),
65                  paginationContainer    = propertiesContainer.find( ".rhea-ultra-properties-ajax-pagination" ),
66                  paginationItems        = propertiesContainer.find( ".pagination a" ),
67                  loader                 = propertiesContainer.find( ".rhea_svg_loader" );
68
69            if ( $this.hasClass( "current" ) ) {
70                return false;
71            }
72
73            loader.slideDown();
74
75            if ( typeof propertiesMapNewData !== "undefined" ) {
76                $.ajax( {
77                    url     : ajaxurl,
78                    type    : 'post',
79                    data    : {
80                        action          : 'rhea_map_properties_data',
81                        paged           : currentPageNum,
82                        properties_args : JSON.parse( propertiesMapNewData.rheaPropertiesArgs )
83                    },
84                    success : function ( response ) {
85                        if ( response.data ) {
86                            const rheaUpdateMapData = $.Event( 'rheaUpdateMapData', {
87                                mapProperties : JSON.stringify( response.data )
88                            } );
89                            $( document ).trigger( rheaUpdateMapData );
90                        }
91                    }
92                } );
93            }
94
95            $.ajax( {
96                url     : $this.attr( 'href' ),
97                method  : 'GET',
98                success : function ( response ) {
99                    let $response = $( response );
100                    propertiesStatsWrapper.html( $response.find( ".rhea-ultra-properties-top-bar-stats-wrapper > .rhea-ultra-properties-stats" ) );
101                    paginationContainer.html( $response.find( ".rhea-ultra-properties-ajax-pagination > .pagination" ) );
102                    propertiesInner.html( $response.find( ".rhea-ultra-properties-inner-container > div" ) );
103
104                    paginationItems.removeClass( 'current' );
105                    $this.addClass( 'current' );
106
107                    loader.slideUp();
108
109                    // Scroll to the top of the properties
110                    $( 'html, body' ).animate( {
111                        scrollTop : propertiesContainer.find( '.rhea-ultra-properties-inner-container' )
112                                    .offset().top - 100
113                    }, 1000 );
114                }
115            } );
116
117            event.preventDefault();
118        } );
119
120        // Add class if div is empty
121        let rheaStatusBox = $( '.rhea-ultra-property-card-three-wrapper .rhea-ultra-status-box' );
122        if ( 0 < rheaStatusBox.length ) {
123            rheaStatusBox.each( function () {
124                if ( ! $.trim( $( this ).html() ).length ) {
125                    $( this ).addClass( 'rhea-empty-wrapper' );
126                }
127            } );
128        }
129
130        // show lightbox info on button click
131        $( 'body' ).on( 'click', '.rhea-ultra-property-card-five-popup', function () {
132
133            let thisPopUp    = $( this ).data( 'src' );
134            let galleryItems = $( thisPopUp ).find( '.rhea-gallery-item' );
135            galleryItems.each( function () {
136                let thisUlr = $( this ).data( 'bg-image' );
137                $( this ).css( 'background-image', 'url("' + thisUlr + '")' );
138            } );
139        } );
140
141        rheaEqualWidthButtons( '.rhea-equal-width-btn-1', '.rhea-equal-width-btn-2' );
142
143        let triggerAnimate = $('.rhea-trigger-animate');
144        if ( triggerAnimate.length ) {
145
146            $('body').on('mouseenter', '.rhea-trigger-animate', function () {
147                $(this).find('.rhea-animate-item').removeClass("animate-out").addClass("animate-in");
148            });
149            $('body').on('mouseleave', '.rhea-trigger-animate',function () {
150                $(this).find('.rhea-animate-item').removeClass("animate-in").addClass("animate-out");
151            });
152
153            function animateBottomOnDevices() {
154                let bodyDevice      = $body.attr( 'data-elementor-device-mode' );
155                let bottomOnDevices = $( '.bottom-on-devices' );
156
157                if ( bodyDevice !== 'desktop' && bodyDevice !== 'widescreen' ) {
158                    bottomOnDevices.removeClass( 'left span-wide' ).addClass( 'bottom' );
159                } else {
160                    bottomOnDevices.removeClass( 'bottom' ).addClass( 'left span-wide' );
161                }
162            }
163
164            animateBottomOnDevices();
165            $( window ).on( 'resize', function () {
166                animateBottomOnDevices();
167            } );
168
169        }
170
171    } );
172
173
174    /*-----------------------------------------------------------------------------------*/
175    /* Equal Width Buttons
176    /*-----------------------------------------------------------------------------------*/
177    window.rheaEqualWidthButtons = function ( btn1, btn2 ) {
178        const rheaW1 = $( btn1 ).innerWidth();
179        const rheaW2 = $( btn2 ).innerWidth();
180        if ( rheaW1 > rheaW2 ) {
181            $( btn2 ).css( 'width', rheaW1 + "px" );
182        } else {
183            $( btn1 ).css( 'width', rheaW2 + "px" );
184        }
185    }
186
187    /*-----------------------------------------------------------------------------------*/
188    /* Nav Menu Responsive Layout Management
189    /*-----------------------------------------------------------------------------------*/
190    window.rheaMenuDisplayScreen = function ( size, widgetID ) {
191        const lgMenu         = $( ".rhea-lg-menu-" + widgetID );
192        const responsiveMenu = $( ".rhea-responsive-men-" + widgetID );
193        if ( innerWidth < size ) {
194            lgMenu.hide();
195            responsiveMenu.show();
196
197        } else {
198            lgMenu.show();
199            responsiveMenu.hide();
200        }
201    }
202
203    /*-----------------------------------------------------------------------------------*/
204    /* SelectPicker Drop Down Initiation
205    /*-----------------------------------------------------------------------------------*/
206    window.rheaSelectPicker = function ( id ) {
207        if ( $().selectpicker ) {
208            $( id ).selectpicker( {
209                iconBase        : 'fas',
210                dropupAuto      : 'true',
211                width           : "100%",
212                tickIcon        : 'fa-check',
213                selectAllText   : '<span class="rhea_select_bs_buttons rhea_bs_select"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 30 30"><polygon points="22.1 9 20.4 7.3 14.1 13.9 15.8 15.6 "/><polygon points="27.3 7.3 16 19.3 9.6 12.8 7.9 14.5 16 22.7 29 9 "/><polygon points="1 14.5 9.2 22.7 10.9 21 2.7 12.8 "/></svg></span>',
214                deselectAllText : '<span class="rhea_select_bs_buttons rhea_bs_deselect"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 30 30"><style type="text/css">  \n' +
215                                  '\t.rh-st0{fill:none;stroke:#000000;stroke-width:2;stroke-miterlimit:10;}\n' +
216                                  '</style><path class="rhea_des rh-st0" d="M3.4 10.5H20c3.8 0 7 3.1 7 7v0c0 3.8-3.1 7-7 7h-6"/><polyline class="rhea_des rh-st0" points="8.4 15.5 3.4 10.5 8.4 5.5 "/></svg></span>'
217
218            } );
219        }
220    };
221
222    /*-----------------------------------------------------------------------------------*/
223    /* Search Form Widget
224    /*-----------------------------------------------------------------------------------*/
225    window.rheaSearchFields = function ( id, fieldCount, topFields, collapsedFields ) {
226
227        var divList = $( id ).find( '.rhea_prop_search__option' );
228        divList.sort( function ( a, b ) {
229            return $( a ).data( "key-position" ) - $( b ).data( "key-position" )
230        } );
231
232        $( topFields ).html( divList ).promise().done( function () {
233
234
235            var getDataTopBar = fieldCount;
236
237
238            var advanceSearch = $( topFields ).find( '.rhea_prop_search__option' );
239
240            var prePendTo = $( collapsedFields );
241
242            var i = 0;
243
244            var j = 0;
245
246            advanceSearch.each( function () {
247                if ( i < getDataTopBar + 1 ) {
248                    if ( $( this ).hasClass( 'hide-fields' ) ) {
249                        j = 2;
250                    }
251                    if ( $( this ).hasClass( 'rvr-hide-fields' ) ) {
252                        j++;
253                    }
254                }
255                i++;
256            } );
257            var advanceElements = getDataTopBar + j + 1;
258
259            if ( advanceElements > 0 ) {
260                var advanceFieldsSmart = $( topFields )
261                .find( '.rhea_prop_search__option:nth-of-type(n+' + advanceElements + ')' );
262
263                advanceFieldsSmart.detach().prependTo( prePendTo );
264
265            }
266
267        } );
268
269
270    };
271
272    window.rheaOpenSearchPopup = function ( trigger, popup ) {
273        $( trigger ).on( 'click', function () {
274            $( popup ).addClass( 'active' );
275            $( popup ).fadeIn( 'fast' );
276        } );
277        $( '.rhea-popup-close' ).on( 'click', function () {
278            $( popup ).removeClass( 'active' );
279            $( popup ).fadeOut( 'fast' );
280            $( trigger ).removeClass( 'rhea_advance_open' );
281        } )
282    }
283
284    window.rheaPropertySlider = function ( id, min, max, pos = 'before', separator = ',', currency = '$', min_searched = '', max_searched = '', step = 100 ) {
285
286        function thousandSeparator( n ) {
287            if ( typeof n === 'number' ) {
288                n += '';
289                var x   = n.split( '.' );
290                var x1  = x[0];
291                var x2  = x.length > 1 ? '.' + x[1] : '';
292                var rgx = /(\d+)(\d{3})/;
293                while ( rgx.test( x1 ) ) {
294                    x1 = x1.replace( rgx, '$1' + separator + '$2' );
295                }
296                return x1 + x2;
297            } else {
298                return n;
299            }
300        }
301
302        var getPosition = pos;
303
304        var PosBefore = '';
305        var PosAfter  = '';
306        if ( getPosition === 'before' ) {
307            PosBefore = currency;
308        } else {
309            PosAfter = currency;
310        }
311
312        var minVal = min;
313        var maxVal = max;
314        if ( min_searched !== '' ) {
315            minVal = min_searched
316        }
317        if ( max_searched !== '' ) {
318            maxVal = max_searched
319        }
320
321        $( id ).slider( {
322            range  : true,
323            min    : min,
324            max    : max,
325            step   : step,
326            values : [minVal, maxVal],
327            slide  : function ( event, ui ) {
328                // Set interval difference between min and max price slider values
329                if ( ui.values[0] >= ui.values[1] - Math.round( ui.values[1] / 10 ) ) {
330                    return false;
331                }
332
333                for ( var i = 0; i < ui.values.length; ++i ) {
334                    $( "input.rhea_slider_value[data-index=" + i + "]" ).val( ui.values[i] );
335                    $( "span.rhea_price_display[data-index=" + i + "]" )
336                    .text( PosBefore + thousandSeparator( ui.values[i] ) + PosAfter );
337
338                }
339            }
340        } );
341    };
342
343    window.rheaSearchAdvanceState = function ( buttonID, wrapperID ) {
344        $( buttonID ).on( 'click', function () {
345            $( buttonID ).toggleClass( 'rhea_advance_open' );
346            if ( $( buttonID ).hasClass( 'rhea_advance_open' ) ) {
347                $( wrapperID ).slideDown( 'normal' );
348            } else {
349                $( wrapperID ).slideUp( 'normal' );
350            }
351        } );
352
353
354    };
355
356    window.rheaFeaturesState = function ( buttonID, wrapperID ) {
357        $( buttonID ).on( 'click', function () {
358            $( buttonID ).toggleClass( 'rhea_features_open' );
359            if ( $( buttonID ).hasClass( 'rhea_features_open' ) ) {
360                $( wrapperID ).slideDown( 'normal' );
361            } else {
362                $( wrapperID ).slideUp( 'normal' );
363            }
364        } );
365
366
367    };
368
369    /*-----------------------------------------------------------------------------------*/
370    /* Search Form price change on status change
371    /*-----------------------------------------------------------------------------------*/
372    window.rheaSearchStatusChange = function ( priceOther, PriceRent, statusID, rent_status = 'for-rent' ) {
373
374        if ( '' !== rent_status ) {
375
376            var rhea_property_status_changed = function ( new_status ) {
377                var price_for_others = $( priceOther );
378                var price_for_rent   = $( PriceRent );
379
380                if ( price_for_others.length > 0 && price_for_rent.length > 0 ) {
381
382                    if ( new_status === rent_status ) {
383                        price_for_others.addClass( 'hide-fields' ).find( 'select' ).prop( 'disabled', true );
384                        price_for_rent.removeClass( 'hide-fields' ).find( 'select' ).prop( 'disabled', false );
385
386
387                    } else {
388                        price_for_rent.addClass( 'hide-fields' ).find( 'select' ).prop( 'disabled', true );
389                        price_for_others.removeClass( 'hide-fields' ).find( 'select' ).prop( 'disabled', false );
390                    }
391                }
392            };
393            $( statusID ).change( function ( e ) {
394                var selected_status = $( this ).val();
395                rhea_property_status_changed( selected_status );
396                $( '.rhea_multi_select_picker' ).selectpicker( 'refresh' );
397            } );
398
399            /* On page load ( as on search page ) */
400            var selected_status = $( statusID ).val();
401            if ( selected_status === rent_status ) {
402                rhea_property_status_changed( selected_status );
403            }
404        }
405    };
406
407    window.minMaxPriceValidation     = function ( minID, maxID ) {
408
409        /**
410         * Max and Min Price
411         * Shows red outline if min price is bigger than max price
412         */
413
414        /* for normal prices */
415        $( minID ).add( maxID ).on( 'change', function () {
416            var min_text_val = $( minID ).val();
417            var min_int_val  = ( isNaN( min_text_val ) ) ? 0 : parseInt( min_text_val );
418
419            var max_text_val = $( maxID ).val();
420            var max_int_val  = ( isNaN( max_text_val ) ) ? 0 : parseInt( max_text_val );
421
422            if ( ( min_int_val >= max_int_val ) && ( min_int_val != 0 ) && ( max_int_val != 0 ) ) {
423                $( minID ).add( maxID ).siblings( '.dropdown-toggle' ).addClass( 'rhea-error' );
424            } else {
425                $( minID ).add( maxID ).siblings( '.dropdown-toggle' ).removeClass( 'rhea-error' );
426            }
427        } );
428    };
429    window.minMaxRentPriceValidation = function ( minID, maxID ) {
430
431        /* for rent prices */
432        $( minID ).add( maxID ).on( 'change', function () {
433
434            var min_text_val = $( minID ).val();
435
436            var min_int_val = ( isNaN( min_text_val ) ) ? 0 : parseInt( min_text_val );
437
438            var max_text_val = $( maxID ).val();
439            var max_int_val  = ( isNaN( max_text_val ) ) ? 0 : parseInt( max_text_val );
440
441            if ( ( min_int_val >= max_int_val ) && ( min_int_val != 0 ) && ( max_int_val != 0 ) ) {
442                $( minID ).add( maxID ).siblings( '.dropdown-toggle' ).addClass( 'rhea-error' );
443            } else {
444                $( minID ).add( maxID ).siblings( '.dropdown-toggle' ).removeClass( 'rhea-error' );
445            }
446        } );
447    };
448
449    window.minMaxAreaValidation = function ( minID, maxID ) {
450        /**
451         * Max and Min Area
452         * To show red outline if min is bigger than max
453         */
454        $( minID ).add( maxID ).on( 'change', function ( obj, e ) {
455            var min_text_val = $( minID ).val();
456            var min_int_val  = ( isNaN( min_text_val ) ) ? 0 : parseInt( min_text_val );
457
458            var max_text_val = $( maxID ).val();
459            var max_int_val  = ( isNaN( max_text_val ) ) ? 0 : parseInt( max_text_val );
460
461            if ( ( min_int_val >= max_int_val ) && ( min_int_val != 0 ) && ( max_int_val != 0 ) ) {
462                $( minID ).add( maxID ).addClass( 'rhea-error' );
463            } else {
464                $( minID ).add( maxID ).removeClass( 'rhea-error' );
465            }
466        } );
467    };
468
469
470    /**
471     * MapBox map widget map generation
472     *
473     * @since 0.9.10
474     *
475     * */
476    window.rheaLoadMapBoxMap = function ( id, settingObj ) {
477
478        let ThisMapID       = id,
479            mapBoxContainer = document.getElementById( id );
480
481        mapBoxContainer.className = mapBoxContainer.className + ' mapbox-dl-map-wrap rhea-mapbox-wrap';
482
483        if ( typeof settingObj !== "undefined" ) {
484
485            if ( 0 < settingObj.properties.length && typeof settingObj.settings.api_key !== 'undefined' ) {
486
487                const eleMapBoxAPI         = settingObj.settings.api_key,
488                      mapBoxPropertiesData = settingObj.properties,
489                      widgetSettings       = settingObj.settings,
490                      mapBoxStyle          = widgetSettings.style,
491                      mapBoxMarkerType     = 'pin'; //widgetSettings.marker_type;
492
493                // TODO find out the proper way to implement it
494                let tileLayer = L.tileLayer( 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
495                    attribution : '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a>'
496                } );
497
498                // get map bounds
499                let mapBounds = [];
500                for ( let i = 0; i < mapBoxPropertiesData.length; i++ ) {
501                    if ( mapBoxPropertiesData[i].lat && mapBoxPropertiesData[i].lng ) {
502                        mapBounds.push( [mapBoxPropertiesData[i].lat, mapBoxPropertiesData[i].lng] );
503                    }
504                }
505
506                // Basic map
507                let mapBoxCenter = L.latLng( 27.664827, -81.515755 );	// given coordinates not going to matter 99.9% of the time but still added just in case.
508                if ( 1 === mapBounds.length ) {
509                    mapBoxCenter = L.latLng( mapBounds[0] );	// this is also not going to effect 99% of the time but just in case of one property.
510                }
511
512                L.mapbox.accessToken   = eleMapBoxAPI;
513                const mapBoxProperties = L.mapbox.map( mapBoxContainer )
514                .setView( mapBoxCenter, 12 )
515                .addLayer( L.mapbox.styleLayer( mapBoxStyle ) );
516
517                if ( 1 < mapBounds.length ) {
518                    mapBoxProperties.fitBounds( mapBounds );	// fit bounds should work only for more than one properties
519                }
520
521                let markers = new L.MarkerClusterGroup();
522
523                for ( let i = 0; i < mapBoxPropertiesData.length; i++ ) {
524                    if ( mapBoxPropertiesData[i].lat && mapBoxPropertiesData[i].lng ) {
525                        let propertyMapData = mapBoxPropertiesData[i],
526                            markerLatLng    = L.latLng( propertyMapData.lat, propertyMapData.lng ),
527                            propertyMarker,
528                            markerOptions   = {
529                                id          : propertyMapData.id,
530                                riseOnHover : true
531                            };
532
533                        // Marker icon
534                        if ( propertyMapData.title ) {
535                            markerOptions.title = propertyMapData.title;
536                        }
537
538                        // Map marker.
539                        if ( 'pin' === mapBoxMarkerType ) {
540                            let iconOptions = {
541                                iconUrl     : propertyMapData.icon,
542                                iconSize    : [42, 57],
543                                iconAnchor  : [20, 57],
544                                popupAnchor : [1, -54]
545                            };
546                            if ( propertyMapData.retinaIcon ) {
547                                iconOptions.iconRetinaUrl = propertyMapData.retinaIcon;
548                            }
549                            markerOptions.icon = L.icon( iconOptions );
550                            propertyMarker     = L.marker( markerLatLng, markerOptions );
551                        } else {
552                            propertyMarker = new L.CircleMarker( markerLatLng, {
553                                fillColor   : '#1cb2ff', //widgetSettings.marker_color,
554                                color       : '#1cb2ff', //widgetSettings.marker_color,
555                                weight      : 2,
556                                fillOpacity : 0.6,
557                                opacity     : 0.6,
558                                radius      : 25
559                            }
559 ).addTo( mapBoxProperties );
560                        }
561
562                        // Marker popup
563                        let popupContentWrapper       = document.createElement( "div" );
564                        popupContentWrapper.className = 'mapboxgl-popup-content';
565                        let popupContent              = "";
566
567                        if ( propertyMapData.thumb ) {
568                            popupContent += '<a class="mapbox-popup-thumb-link" href="' + propertyMapData.url + '"><img class="mapbox-popup-thumb" src="' + propertyMapData.thumb + '" alt="' + propertyMapData.title + '"/></a>';
569                        }
570
571                        if ( propertyMapData.title ) {
572                            popupContent += '<h5 class="mapbox-popup-title"><a class="mapbox-popup-link" href="' + propertyMapData.url + '">' + propertyMapData.title + '</a></h5>';
573                        }
574
575                        if ( propertyMapData.price ) {
576                            popupContent += '<p><span class="mapbox-popup-price">' + propertyMapData.price + '</span></p>';
577                        }
578
579                        popupContentWrapper.innerHTML = popupContent;
580
581                        propertyMarker.popupContents = popupContentWrapper;
582                        propertyMarker.id            = propertyMapData.id;
583                        propertyMarker.className     = 'mapboxgl-wrapper';
584                        propertyMarker.bindPopup( popupContentWrapper );
585
586                        markers.addLayer( propertyMarker );
587
588                    }
589                }
590                mapBoxProperties.addLayer( markers );
591                mapBoxProperties.scrollWheelZoom.disable();
592
593                /*
594                * Panning the marker to center of the visible map on "popupopen" event
595                */
596                mapBoxProperties.on( 'popupopen', function ( e ) {
597                    // find the pixel location on the map where the popup anchor is
598                    var px = mapBoxProperties.project( e.target._popup._latlng );
599                    // find the height of the popup container, divide by 2, subtract from the Y axis of marker location
600                    px.y -= e.target._popup._container.clientHeight / 2;
601                    // pan to new center
602                    mapBoxProperties.panTo( mapBoxProperties.unproject( px ), { animate : true } );
603
604                } );
605
606                /**
607                 * Function to find the marker in a cluster
608                 * @param {int} marker
609                 * @param {int} cluster
610                 * @returns
611                 */
612                function is_marker_in_cluster( marker, cluster ) {
613
614                    let length = cluster.length;
615
616                    for ( let i = 0; i < length; i++ ) {
617
618                        if ( cluster[i].id == marker ) {
619
620                            return true;
621
622                        }
623
624                    }
625
626                    return false;
627
628                }
629
630                /**
631                 * Open Popup function
632                 * @param {int} markerid
633                 */
634                function mapbox_open_popup( markerid ) {
635
636                    mapBoxProperties.eachLayer( function ( layer ) {
637
638                        // Checking if this layer is a cluster
639                        if ( typeof layer._childCount !== "undefined" ) {
640
641                            // Getting all markers in this cluster
642                            let markersincluster = layer.getAllChildMarkers();
643
644                            if ( is_marker_in_cluster( markerid, markersincluster ) ) {
645
646                                layer.spiderfy();
647
648                                markersincluster.forEach(
649                                    function ( property_marker ) {
650                                        if ( property_marker.id === parseInt( markerid ) ) {
651
652                                            property_marker.openPopup();
653
654                                        }
655                                    } );
656
657                            }
658
659                        } else {
660
661                            if ( layer.id === parseInt( markerid ) ) {
662
663                                layer.openPopup();
664
665                            }
666
667                        }
668
669                    } );
670
671                }
672
673                /**
674                 * Close Popup function
675                 * @param {int} markerid
676                 */
677                function mapbox_close_popup( markerid ) {
678
679                    mapBoxProperties.eachLayer( function ( layer ) {
680
681                        // Checking if this layer is a cluster
682                        if ( typeof layer._childCount !== "undefined" ) {
683
684                            // Getting all markers in this cluster
685                            var markersincluster = layer.getAllChildMarkers();
686
687                            if ( is_marker_in_cluster( markerid, markersincluster ) ) {
688
689                                layer.unspiderfy();
690
691                                markersincluster.forEach(
692                                    function ( property_marker ) {
693
694                                        if ( property_marker.id == parseInt( markerid ) ) {
695
696                                            layer.closePopup();
697
698                                        }
699
700                                    } );
701                            }
702
703                        } else {
704
705                            if ( layer.id == parseInt( markerid ) ) {
706
707                                layer.closePopup();
708
709                                mapBoxProperties.closePopup();
710
711                            }
712
713                        }
714
715                    } );
716
717                }
718
719                let realhomesInfoboxPopupTrigger = function () {
720
721                    $( '.rh_popup_info_map' ).each( function ( i ) {
722
723                        // Getting the Property ID for mouse events
724                        let property_ID = $( this ).attr( 'data-rh-id' ).replace( /[^\d.]/g, '' );
725
726                        $( this )
727                        .on( 'mouseenter', function () {
728                            mapbox_open_popup( property_ID );
729                        } )
730                        .on( 'mouseleave', function () {
731                            mapbox_close_popup( property_ID );
732                        } );
733
734                    } );
735
736                    return false;
737                };
738
739                let RHisMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry/i.test( navigator.userAgent ) ? true : false;
740
741                if ( ! RHisMobile ) {
742                    realhomesInfoboxPopupTrigger();
743                }
744
745            } else {
746
747                // Fallback Map
748                var fallbackLayer = L.tileLayer( 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
749                    attribution : '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
750                } );
751
752                // todo: provide an option for fallback map coordinates
753                var fallbackMapOptions = {
754                    center : [27.664827, -81.515755],
755                    zoom   : 12
756                };
757
758                var fallbackMap = L.map( ThisMapID, fallbackMapOptions );
759                fallbackMap.addLayer( fallbackLayer );
760
761            }
762
763        }
764
765    };
766
767
768    window.rheaLocationsHandler = function ( hierarchicalLocations,
769                                             locationPlaceholders,
770                                             selectBoxesIDs,
771                                             slugsInQueryParams,
772                                             selectBoxesCount,
773                                             anyValue,
774                                             multiSelect ) {
775
776        /**
777         * Following function automatically runs to initialize locations boxes
778         */
779        ( function () {
780            /* prepare select boxes */
781            prepareSelectBoxes();
782
783            let parentLocations = [];
784            for ( let selectIndex = 0; selectIndex < selectBoxesCount; selectIndex++ ) {
785                const currentSelect = $( '#' + selectBoxesIDs[selectIndex] ); /* loop's current select box */
786                const currentIsLast = ( selectBoxesCount === ( selectIndex + 1 ) ); /* check if current select box is last */
787
788                if ( selectIndex === 0 ) { /* First iteration */
789                    parentLocations = addParentLocations( currentSelect, currentIsLast );
790                } else { /* later iterations */
791                    /* If parents locations array is not empty then there could be children to add in current select box */
792                    if ( parentLocations.length > 0 ) {
793                        let currentLocations = [];
794                        const previousSelect = $( '#' + selectBoxesIDs[selectIndex - 1] );
795
796                        /* loop through all if value is "any" */
797                        if ( previousSelect.val() === anyValue ) {
798                            for ( let i = 0; i < parentLocations.length; i++ ) {
799                                let tempLocations = addChildrenLocations( currentSelect, parentLocations[i].children, '', currentIsLast );
800                                if ( tempLocations.length > 0 ) {
801                                    currentLocations = $.merge( currentLocations, tempLocations );
802                                }
803                            }
804                        } else {
805                            /* Otherwise add only children of previous selected location, It there are any. */
806                            let previousLocation = searchLocation( previousSelect.val(), hierarchicalLocations );
807                            if ( previousLocation && previousLocation.children.length > 0 ) {
808                                currentLocations = addChildrenLocations( currentSelect, previousLocation.children, '', currentIsLast );
809                            }
810                        }
811
812                        /* hook up updateChildSelect function with previous select change event */
813                        previousSelect.change( updateChildSelect );
814                        /* currentLocations variable is passed to parentLocations for code below and for next iteration */
815                        parentLocations = currentLocations;
816                    }
817                }
818
819                /* If parentLocations is empty */
820                if ( parentLocations.length === 0 ) {
821                    /* disable current select and children selects if any */
822                    disableSelect( currentSelect );
823                    /* No need for further iterations */
824                    break;
825                } else {
826                    /* Select the right option within current select based on query parameters */
827                    selectParamOption( currentSelect );
828                }
829            }   /* end of loop */
830        } )(); /* Run the function immediately after declaration */
831
832        /**
833         * Adds top level locations to given select box, If addAllChildren is true then it adds all children locations as well
834         * @param targetSelect
835         * @param addAllChildren
836         * @returns {*[]}
837         */
838        function addParentLocations( targetSelect, addAllChildren ) {
839            let addedLocations   = [];
840            let insertionCounter = 0;
841
842            /* loop through top level locations */
843            hierarchicalLocations.forEach( function ( currentLocation, index, locationsArray ) {
844                targetSelect.append( '<option value="' + currentLocation.slug + '">' + currentLocation.name + '</option>' );
845                addedLocations[insertionCounter++] = currentLocation;
846                if ( addAllChildren && currentLocation.children.length ) {
847                    addChildrenLocations( targetSelect, currentLocation.children, '- ', addAllChildren );
848                }
849            } );
850
851            return addedLocations;
852        }
853
854        /**
855         * Adds top level locations form given childrenLocations array to targetSelect box, If addAllChildren is true then it adds all children locations as well
856         * @param targetSelect
857         * @param childrenLocations
858         * @param prefix
859         * @param addAllChildren
860         * @returns {*[]}
861         */
862        function addChildrenLocations( targetSelect, childrenLocations, prefix, addAllChildren ) {
863            let addedChildrenLocations = [];
864            let insertionCounter       = 0;
865
866            /* loop through all children locations */
867            childrenLocations.forEach( function ( currentLocation, index, locationsArray ) {
868                targetSelect.append( '<option value="' + currentLocation.slug + '">' + prefix + currentLocation.name + '</option>' );
869                addedChildrenLocations[insertionCounter++] = currentLocation;
870                /* If a current location has children then add those as well */
871                if ( addAllChildren && currentLocation.children.length ) {
872                    let tempLocations = addChildrenLocations( targetSelect, currentLocation.children, prefix + '- ', addAllChildren );
873                    if ( tempLocations.length > 0 ) {
874                        /* merge newly added children locations with existing children locations array */
875                        addedChildrenLocations = $.merge( addedChildrenLocations, tempLocations );
876                    }
877                }
878            } );
879
880            return addedChildrenLocations;
881        }
882
883        /**
884         * Search a location from given locations array for given slug
885         * @param slug
886         * @param locations
887         * @returns {boolean}   location OR false if no location is found
888         */
889        function searchLocation( slug, locations ) {
890            let targetLocation = false;
891
892            for ( let index = 0; index < locations.length; index++ ) {
893                let currentLocation = locations[index];
894                if ( currentLocation.slug === slug ) {
895                    targetLocation = currentLocation;
896                    break;
897                }
898                if ( currentLocation.children.length > 0 ) {
899                    targetLocation = searchLocation( slug, currentLocation.children );
900                    if ( targetLocation ) {
901                        break;
902                    }
903                }
904            }
905
906            return targetLocation;
907        }
908
909        /**
910         * Update child select box based on change in selected value of parent select box
911         * @param event
912         */
913        function updateChildSelect( event ) {
914            let selectedSlug       = $( this ).val();
915            let currentSelectIndex = selectBoxesIDs.indexOf( $( this ).attr( 'id' ) );
916
917            /*  When "any" is selected, Also no need to run this on last select box */
918            if ( selectedSlug === anyValue && ( currentSelectIndex > -1 ) && ( currentSelectIndex < ( selectBoxesCount - 1 ) ) ) {
919                for ( let s = currentSelectIndex; s < ( selectBoxesCount - 1 ); s++ ) {
920                    /* check if child select is Last */
921                    let childSelectIsLast = ( selectBoxesCount === ( s + 2 ) );
922
923                    /* find child select box, empty it and add any options to it */
924                    let childSelect = $( '#' + selectBoxesIDs[s + 1] );
925                    childSelect.empty();
926                    addAnyOption( childSelect );
927
928                    /* loop through select options to find and add children locations into next select */
929                    let anyChildLocations = [];
930                    $( '#' + selectBoxesIDs[s] + ' > option' ).each( function () {
931                        if ( this.value !== anyValue ) {
932                            let relatedLocation = searchLocation( this.value, hierarchicalLocations );
933                            if ( relatedLocation && relatedLocation.children.length > 0 ) {
934                                let tempChildrenLocations = addChildrenLocations( childSelect, relatedLocation.children, '', childSelectIsLast );
935                                if ( tempChildrenLocations.length > 0 ) {
936                                    anyChildLocations = $.merge( anyChildLocations, tempChildrenLocations );
937                                }
938                            }
939                        }
940                    } );
941
942                    /* enable next select if options are added otherwise disable it */
943                    if ( anyChildLocations.length > 0 ) {
944                        enableSelect( childSelect );
945                    } else {
946                        disableSelect( childSelect );
947                        break;
948                    }
949
950                }   /* end of for loop */
951
952            } else {
953                /* In case of valid location selection */
954                let selectedParentLocation = searchLocation( selectedSlug, hierarchicalLocations );
955                if ( selectedParentLocation ) {
956                    let childLocations = [];
957                    for ( let childSelectIndex = currentSelectIndex + 1; childSelectIndex < selectBoxesCount; childSelectIndex++ ) {
958                        /* check if child select is Last */
959                        let childSelectIsLast = ( selectBoxesCount === ( childSelectIndex + 1 ) );
960
961                        /* find and empty child select box */
962                        let childSelect = $( '#' + selectBoxesIDs[childSelectIndex] );
963                        childSelect.empty();
964
965                        /* First iteration */
966                        if ( childLocations.length === 0 ) {
967                            if ( selectedParentLocation.children.length > 0 ) {
968                                addAnyOption( childSelect );
969                                let tempLocations = addChildrenLocations( childSelect, selectedParentLocation.children, '', childSelectIsLast );
970                                if ( tempLocations.length > 0 ) {
971                                    childLocations = tempLocations;
972                                }
973                            }
974                        } else if ( childLocations.length > 0 ) { /* 2nd and later iterations */
975                            let currentLocations = [];
976                            for ( let i = 0; i < childLocations.length; i++ ) {
977                                let tempChildLocation = childLocations[i];
978                                if ( tempChildLocation.children.length > 0 ) {
979                                    addAnyOption( childSelect );
980                                    let tempLocations = addChildrenLocations( childSelect, tempChildLocation.children, '', childSelectIsLast );
981                                    if ( tempLocations.length > 0 ) {
982                                        currentLocations = $.merge( currentLocations, tempLocations );
983                                    }
984                                }
985                            }
986                            /* If there are current locations OR none, assign current locations array to child locations*/
987                            childLocations = currentLocations;
988                        }
989
990                        if ( childLocations.length > 0 ) {
991                            enableSelect( childSelect );
992                        } else {
993                            disableSelect( childSelect );
994                            break;
995                        }
996                    } /* end of for loop */
997                }
998            }
999        }
1000
1001        /**
1002         * Adds Any value and select index based place holder text to given select box.
1003         * @param targetSelect
1004         */
1005        function addAnyOption( targetSelect ) {
1006            if ( targetSelect.has( 'option' ).length > 0 ) {
1007                return;
1008            }
1009
1010            /* current select box index */
1011            let targetSelectIndex = selectBoxesIDs.indexOf( targetSelect.attr( 'id' ) );
1012
1013            /* For location fields in search form */
1014            if ( targetSelect.parents( '.rhea_prop_search__select' )
1015            .hasClass( 'rhea_location_prop_search_' + targetSelectIndex ) ) {
1016                targetSelect.append( '<option value="' + anyValue + '" selected="selected">' + locationPlaceholders[targetSelectIndex] + '</option>' );
1017            }
1018        }
1019
1020        /**
1021         * Disable a select box and next select boxes if exists
1022         * @param targetSelect
1023         */
1024        function disableSelect( targetSelect ) {
1025            let targetSelectID = targetSelect.attr( 'id' );
1026            targetSelect.empty();
1027
1028            targetSelect.closest( '.option-bar' ).addClass( 'disabled' );
1029            if ( targetSelect.is( ':enabled' ) ) {
1030                targetSelect.prop( 'disabled', true );
1031                targetSelect.parents( '.rhea_prop_search__select' ).addClass( 'rhea_disable_parent' );
1032            }
1033
1034            let targetSelectIndex    = selectBoxesIDs.indexOf( targetSelectID );      // target select box index
1035            let nextSelectBoxesCount = selectBoxesCount - ( targetSelectIndex + 1 );
1036
1037            /* Disable next select box as well */
1038            if ( nextSelectBoxesCount > 0 ) {
1039                let nextSelect = $( '#' + selectBoxesIDs[targetSelectIndex + 1] );
1040                disableSelect( nextSelect );
1041            }
1042        }
1043
1044        /**
1045         * Enable a select box
1046         * @param targetSelect
1047         */
1048        function enableSelect( targetSelect ) {
1049            let targetSelectID = targetSelect.attr( 'id' );
1050
1051            if ( targetSelect.is( ':disabled' ) ) {
1052                targetSelect.prop( 'disabled', false );
1053            }
1054
1055            // remove class from parents
1056            targetSelect.parents( '.rhea_prop_search__select' ).map( function () {
1057                if ( $( this ).hasClass( 'rhea_disable_parent' ) ) {
1058                    $( this ).removeClass( 'rhea_disable_parent' );
1059                }
1060            } );
1061
1062            /* Remove .option-bar's disabled class */
1063            let optionWrapper = targetSelect.closest( '.option-bar' );
1064            if ( optionWrapper.hasClass( 'disabled' ) ) {
1065                optionWrapper.removeClass( 'disabled' );
1066            }
1067        }
1068
1069        /**
1070         * Mark the current value in query params as selected in related select box
1071         * @param currentSelect
1072         */
1073        function selectParamOption( currentSelect ) {
1074            if ( Object.keys( slugsInQueryParams ).length > 0 ) {
1075                let selectName = currentSelect.attr( 'name' );
1076                if ( typeof selectName !== "undefined" ) {
1077                    selectName = selectName.replace( /[\[\]]+/g, '' ); /* remove box brackets as for multi select location brackets comes with name */
1078                }
1079                if ( typeof slugsInQueryParams[selectName] !== 'undefined' ) {
1080                    let tempValue = slugsInQueryParams[selectName];
1081                    if ( Array.isArray( tempValue ) ) {
1082                        for ( let i = 0; i < tempValue.length; i++ ) {
1083                            currentSelect.find( 'option[value="' + tempValue[i] + '"]' ).prop( 'selected', true );
1084                        }
1085                    } else {
1086                        currentSelect.find( 'option[value="' + tempValue + '"]' ).prop( 'selected', true );
1087                    }
1088                }
1089            }
1090        }
1091
1092        /**
1093         * Append options with Any value or None value depending on conditions
1094         */
1095        function prepareSelectBoxes() {
1096            /* Loop through select boxes and prepare them with basic option */
1097            for ( let selectIndex = 0; selectIndex < selectBoxesCount; selectIndex++ ) {
1098                let currentSelectId = selectBoxesIDs[selectIndex];
1099                let currentSelect   = $( '#' + currentSelectId );
1100
1101                /* For location fields in search form */
1102                if ( ( multiSelect !== 'multiple' ) &&
1103                     ( currentSelect.has( 'option' ).length === 0 ) &&
1104                     ( currentSelect.parents( '.rhea_prop_search__select' )
1105                     .hasClass( 'rhea_location_prop_search_' + selectIndex ) ) ) {
1106                    addAnyOption( currentSelect );
1107                }
1108            }
1109        }
1110    };
1111
1112    var rheaLocationSuccessList = function ( data, thisParent, refreshList = false ) {
1113
1114        if ( true === refreshList ) {
1115            thisParent.find( 'option' ).not( ':selected, .none' ).remove().end();
1116        }
1117        var getSelected = $( thisParent ).val();
1118
1119
1120        jQuery.each( data, function ( index, text ) {
1121
1122            if ( getSelected ) {
1123                if ( getSelected.indexOf( text[0] ) < 0 ) {
1124                    thisParent.append(
1125                        $( '<option value="' + text[0] + '">' + text[1] + '</option>' )
1126                    );
1127                }
1128            } else {
1129                thisParent.append(
1130                    $( '<option value="' + text[0] + '">' + text[1] + '</option>' )
1131                );
1132            }
1133        } );
1134        thisParent.selectpicker( 'refresh' );
1135        $( parent ).find( 'ul.dropdown-menu li:first-of-type a' ).focus();
1136
1137        $( parent ).find( 'input' ).focus();
1138
1139    };
1140
1141    var rheaLoaderFadeIn = function ( parent ) {
1142        $( parent ).find( '.rhea-location-ajax-loader' ).fadeIn( 'fast' );
1143    };
1144
1145    var rheaLoaderFadeOut = function ( parent ) {
1146        $( parent ).find( '.rhea-location-ajax-loader' ).fadeOut( 'fast' );
1147    };
1148
1149    var rheaTriggerAjaxOnLoad = function ( parent, thisParent, ajaxurl, hideEmpty, SortAlpha, fieldValue = '' ) {
1150
1151        $.ajax( {
1152            url        : ajaxurl,
1153            dataType   : 'json',
1154            delay      : 250, // delay in ms while typing when to perform a AJAX search
1155            data       : {
1156                action          : 'rhea_get_location_options', // AJAX action for admin-ajax.php
1157                query           : fieldValue,
1158                hideemptyfields : hideEmpty,
1159                sortplpha       : SortAlpha
1160
1161            },
1162            beforeSend : rheaLoaderFadeIn( parent ),
1163            success    : function ( data ) {
1164                rheaLoaderFadeOut( parent );
1165                rheaLocationSuccessList( data, thisParent, true );
1166            }
1167        } );
1168
1169    };
1170
1171    var rheaTriggerAjaxOnScroll = function ( parent, thisParent, farmControl, ajaxurl, hideEmpty, SortAlpha, fieldValue = '' ) {
1172
1173        var paged = 2;
1174
1175        farmControl.on( 'keyup', function ( e ) {
1176            paged = 2;
1177
1178            fieldValue = $( this ).val();
1179        } );
1180
1181        var targetInner = $( parent ).find( 'div.inner' );
1182
1183        targetInner.on( 'scroll', function () {
1184            var thisInner = $( this );
1185
1186            var thisInnerHeight = thisInner.innerHeight();
1187            var getScrollIndex  = thisInner.scrollTop() + thisInnerHeight;
1188            if ( getScrollIndex >= $( this )[0].scrollHeight ) {
1189
1190
1191                $.ajax( {
1192                    url      : ajaxurl,
1193                    dataType : 'json',
1194                    delay    : 250, // delay in ms while typing when to perform a AJAX search
1195                    data     : {
1196                        action          : 'rhea_get_location_options', // AJAX action for admin-ajax.php
1197                        query           : fieldValue,
1198                        page            : paged,
1199                        hideemptyfields : hideEmpty,
1200                        sortplpha       : SortAlpha
1201                    },
1202                    // beforeSend: loaderFadeIn(),
1203                    beforeSend : rheaLoaderFadeIn( parent ),
1204                    success    : function ( data ) {
1205                        rheaLoaderFadeOut( parent );
1206                        paged++;
1207                        rheaLocationSuccessList( data, thisParent, false );
1208
1209                        if ( ! $.trim( data ) ) {
1210                            $( parent ).find( '.rhea-location-ajax-loader' ).fadeTo( "fast", 0 );
1211                        }
1212                    }
1213                } );
1214            }
1215        } );
1216    };
1217
1218    window.rheaAjaxSelect = function ( parent, id, ajaxurl, hideEmpty, SortAlpha ) {
1219        var farmControl = $( parent ).find( '.form-control' );
1220        var thisParent  = $( id );
1221        rheaTriggerAjaxOnScroll( parent, thisParent, farmControl, ajaxurl, hideEmpty, SortAlpha );
1222        rheaTriggerAjaxOnLoad( parent, thisParent, ajaxurl, hideEmpty, SortAlpha );
1223        farmControl.on( 'keyup', function ( e ) {
1224            var fieldValue = $( this ).val();
1225            fieldValue     = fieldValue.trim();
1226            var wordcounts = jQuery.trim( fieldValue ).length;
1227            $( parent ).find( '.rhea-location-ajax-loader' ).fadeTo( "fast", 1 );
1228            if ( wordcounts > 0 ) {
1229                $.ajax( {
1230                    url        : ajaxurl,
1231                    dataType   : 'json',
1232                    delay      : 250, // delay in ms while typing when to perform a AJAX search
1233                    data       : {
1234                        action          : 'rhea_get_location_options', // AJAX action for admin-ajax.php
1235                        query           : fieldValue,
1236                        hideemptyfields : hideEmpty,
1237                        sortplpha       : SortAlpha
1238                    },
1239                    beforeSend : rheaLoaderFadeIn( parent ),
1240                    success    : function ( data ) {
1241                        rheaLoaderFadeOut( parent );
1242                        thisParent.find( 'option' ).not( ':selected' ).remove().end();
1243                        // var options = [];
1244                        if ( fieldValue && data ) {
1245                            rheaLocationSuccessList( data, thisParent );
1246                        } else {
1247                            thisParent.find( 'option' ).not( ':selected' ).remove().end();
1248                            thisParent.selectpicker( 'refresh' );
1249                            $( parent ).find( 'ul.dropdown-menu li:first-of-type a' ).focus();
1250                            $( parent ).find( 'input' ).focus();
1251                        }
1252                    }
1253                } );
1254            } else {
1255                rheaTriggerAjaxOnLoad( parent, thisParent, ajaxurl, hideEmpty, SortAlpha )
1256            }
1257        } );
1258    };
1259
1260    window.searchFormAjaxKeywords = function ( id, url ) {
1261        var inputField = $( id ).find( 'input' );
1262        inputField.keyup( function () {
1263            var charCount = inputField.val().length;
1264            if ( charCount > 1 ) {
1265                $( id ).find( '.rhea-properties-data-list' ).slideDown();
1266                $( id ).find( '.rhea_sfoi_ajax_loader' ).show();
1267                $( id ).find( '.rhea-field-icon-wrapper' ).addClass( 'rhea-search-fade' )
1268                $.ajax( {
1269                    url     : url,
1270                    type    : 'POST',
1271                    data    : {
1272                        action  : 'rh_sfoi_data_fetch',
1273                        keyword : $( this ).val()
1274                    },
1275                    success : function ( data ) {
1276                        $( id ).find( '.rhea-properties-data-list' ).html( data );
1277                        $( id ).find( '.rhea_sfoi_ajax_loader' ).hide();
1278                        $( id ).find( '.rhea-field-icon-wrapper' ).removeClass( 'rhea-search-fade' )
1279
1280                    }
1281                } );
1282            } else {
1283                $( id ).find( '.rhea-properties-data-list' ).slide
1283Up();
1284            }
1285        } );
1286    }
1287
1288    window.rheaTestimonialsTwoCarousel = function ( id, itemsFluid = 4, items = 3, itemsTab = 2, itemsMob = 1, gap = 30, dots = true, rtl = false ) {
1289        if ( $().owlCarousel ) {
1290            $( id ).owlCarousel( {
1291                loop       : false,
1292                dots       : dots,
1293                nav        : false,
1294                margin     : gap,
1295                rtl        : rtl,
1296                responsive : {
1297                    0    : {
1298                        items : itemsMob
1299                    },
1300                    767  : {
1301                        items : itemsTab
1302                    },
1303                    1024 : {
1304                        items : items
1305                    },
1306                    1440 : {
1307                        items : itemsFluid
1308                    }
1309                }
1310
1311            } );
1312        }
1313    };
1314
1315    window.rheaTestimonialsThreeCarousel = function ( slide1, slide2, navSelectors, animationspeed = '600', slideshowspeed = '5000', slideShow1 = true, direction1 = 'horizontal', animation1 = 'fade', reverse1 = false, animation2 = 'fade', reverse2 = false ) {
1316        if ( $().flexslider ) {
1317            $( slide1 ).flexslider( {
1318                controlNav     : false,
1319                directionNav   : false,
1320                animationLoop  : true,
1321                slideshow      : slideShow1,
1322                direction      : direction1,
1323                animation      : animation1,
1324                reverse        : reverse1,
1325                animationSpeed : animationspeed,
1326                slideshowSpeed : slideshowspeed
1327            } );
1328
1329            $( slide2 ).flexslider( {
1330                controlNav         : false,
1331                animation          : animation2,
1332                animationLoop      : true,
1333                slideshow          : slideShow1,
1334                reverse            : reverse2,
1335                customDirectionNav : $( navSelectors ),
1336                sync               : $( slide1 ),
1337                animationSpeed     : animationspeed,
1338                slideshowSpeed     : slideshowspeed
1339            } );
1340        }
1341    };
1342
1343    window.rheaTestimonialsFourCarousel = function ( slider, navSelectors, animation = 'fade', animationSpeed = '600', reverse = false, slideshow = false, slideshowSpeed = '5000' ) {
1344        if ( $().flexslider ) {
1345            $( slider ).flexslider( {
1346                controlNav     : false,
1347                directionNav   : false,
1348                animation      : animation,
1349                animationSpeed : animationSpeed,
1350                reverse        : reverse,
1351                slideshow      : slideshow,
1352                slideshowSpeed : slideshowSpeed
1353            } );
1354
1355            $( navSelectors ).on( 'click', function ( event ) {
1356                $( slider ).flexslider( $( this ).attr( 'href' ) );
1357                event.preventDefault();
1358            } );
1359        }
1360    };
1361
1362    window.EREloadNewsSlider = function () {
1363        if ( $().flexslider ) {
1364            $( '.rhea-listing-news-slider' ).each( function () {
1365                $( this ).flexslider( {
1366                    animation  : "slide",
1367                    slideshow  : false,
1368                    controlNav : false,
1369
1370                    customDirectionNav : $( this ).next( '.rhea-news-directional-nav' ).find( 'a' )
1371                } );
1372            } );
1373        }
1374    }
1375
1376    window.ultraFeaturedSlider = function ( s1, s2 ) {
1377        var s1       = $( s1 );
1378        var s2       = $( s2 );
1379        var maxItems = 3;
1380
1381        var $sliderItemTotal = $( ".rhea-slider-item-total" );
1382
1383        s2.flexslider( {
1384            move          : 1,
1385            directionNav  : false,
1386            animation     : "slide",
1387            controlNav    : false,
1388            animationLoop : false,
1389            slideshow     : false,
1390            itemWidth     : 10,
1391            itemMargin    : 12,
1392            asNavFor      : s1,
1393            maxItems      : maxItems,
1394            minItems      : 1,
1395            start         : function ( item ) {
1396                slideCounter( item );
1397            },
1398            after         : function ( item ) {
1399                slideCounter( item );
1400            }
1401        } );
1402
1403        function slideCounter( item ) {
1404            $sliderItemTotal.text( item.count - maxItems - item.currentSlide );
1405        }
1406
1407        s1.flexslider( {
1408            smoothHeight  : true,
1409            animation     : "fade",
1410            controlNav    : false,
1411            animationLoop : false,
1412            slideshow     : false,
1413            sync          : s2
1414        } );
1415
1416
1417    }
1418
1419    window.rheaSubmitContactForm = function ( formID, btnSelector ) {
1420        if ( jQuery().validate && jQuery().ajaxSubmit ) {
1421
1422            var submitButton     = $( btnSelector ),
1423                ajaxLoader       = $( formID ).find( '.rhea-ajax-loader' ),
1424                messageContainer = $( formID ).find( '.rhea-message-container' ),
1425                errorContainer   = $( formID ).find( ".rhea-error-container" );
1426
1427            var formOptions = {
1428                beforeSubmit : function () {
1429                    submitButton.attr( 'disabled', 'disabled' );
1430                    ajaxLoader.fadeIn( 'fast' );
1431                    messageContainer.fadeOut( 'fast' );
1432                    errorContainer.fadeOut( 'fast' );
1433                },
1434                success      : function ( ajax_response, statusText, xhr, $form ) {
1435                    var response = $.parseJSON( ajax_response );
1436                    ajaxLoader.fadeOut( 'fast' );
1437                    submitButton.removeAttr( 'disabled' );
1438                    if ( response.success ) {
1439                        $form.resetForm();
1440                        messageContainer.html( response.message ).fadeIn( 'fast' );
1441
1442                        setTimeout( function () {
1443                            messageContainer.fadeOut( 'slow' )
1444                        }, 5000 );
1445
1446                        // call reset function if it exists
1447                        if ( typeof inspiryResetReCAPTCHA == 'function' ) {
1448                            inspiryResetReCAPTCHA();
1449                        }
1450
1451                        if ( typeof CFOSData !== 'undefined' ) {
1452                            setTimeout( function () {
1453                                window.location.replace( CFOSData.redirectPageUrl );
1454                            }, 1000 );
1455                        }
1456
1457                        if ( typeof contactFromData !== 'undefined' ) {
1458                            setTimeout( function () {
1459                                window.location.replace( contactFromData.redirectPageUrl );
1460                            }, 1000 );
1461                        }
1462                    } else {
1463                        errorContainer.html( response.message ).fadeIn( 'fast' );
1464                    }
1465                }
1466            };
1467
1468
1469            // Agent single page form
1470            $( formID ).validate( {
1471                errorLabelContainer : errorContainer,
1472                submitHandler       : function ( form ) {
1473                    $( form ).ajaxSubmit( formOptions );
1474                }
1475            } );
1476        }
1477    };
1478
1479    window.rheaAgentToggleV4 = function ( ID ) {
1480        let agentCard = $( ID ).find( '.rhea-v4-agent-slide' );
1481        agentCard.each( function () {
1482            let agentWrapper  = $( this ).find( '.rhea_agent_expand_trigger' );
1483            let agentExpander = $( this ).find( '.agent-detail-expander' );
1484            agentWrapper.on( 'click', function ( e ) {
1485                e.preventDefault();
1486                agentExpander.slideToggle();
1487            } );
1488        } );
1489    }
1490
1491    function isInViewport( node ) {
1492        var rect = node.getBoundingClientRect();
1493        return (
1494            ( rect.height > 0 || rect.width > 0 ) &&
1495            rect.bottom >= 0 &&
1496            rect.right >= 0 &&
1497            rect.top <= ( window.innerHeight || document.documentElement.clientHeight ) &&
1498            rect.left <= ( window.innerWidth || document.documentElement.clientWidth )
1499        )
1500    }
1501
1502    function scrollParallax( selector ) {
1503        var scrolled = jQuery( window ).scrollTop();
1504        jQuery( selector ).each( function ( index, element ) {
1505            var initY  = jQuery( this ).offset().top;
1506            var height = jQuery( this ).height();
1507            var endY   = initY + jQuery( this ).height();
1508
1509            // Check if the element is in the viewport.
1510            var visible = isInViewport( this );
1511            if ( visible ) {
1512                var diff  = scrolled - initY;
1513                var ratio = Math.round( ( diff / height ) * 100 );
1514                jQuery( this ).css( 'background-position', 'center ' + parseInt( ( ratio * 1 ) ) + 'px' )
1515            }
1516
1517        } )
1518    }
1519
1520    jQuery( '.ere_cta_parallax' ).each( function () {
1521        scrollParallax( this );
1522    } );
1523
1524    jQuery( window ).scroll( function () {
1525        jQuery( '.ere_cta_parallax' ).each( function () {
1526            scrollParallax( this );
1527        } );
1528
1529    } );
1530
1531    // Testimonials Five Carousel
1532    window.rheaTestimonialsFiveCarousel = function ( settings ) {
1533        if ( $().owlCarousel ) {
1534
1535            let carouselOptions = {
1536                items              : 1,
1537                margin             : 0,
1538                nav                : false,
1539                autoHeight         : true,
1540                loop               : settings.loop,
1541                autoplay           : settings.autoplay,
1542                autoplayTimeout    : settings.autoplaySpeed,
1543                autoplayHoverPause : true,
1544                smartSpeed         : settings.animationSpeed,
1545                dotsContainer      : settings.dots,
1546                rtl                : $( 'body' ).hasClass( 'rtl' )
1547            };
1548
1549            if ( 'fade' === settings.slideAnimation ) {
1550                carouselOptions.animateOut = 'fadeOut';
1551                carouselOptions.animateIn  = 'fadeIn';
1552            }
1553
1554            $( settings.id ).owlCarousel( carouselOptions );
1555        }
1556    };
1557
1558    // Image Carousel Widget Script.
1559    window.rheaImageCarousel = function ( settings ) {
1560        if ( $().slick ) {
1561            const imageCarouselWrap = $( settings.wrapper ),
1562                  imageCarousel     = $( settings.id );
1563
1564            imageCarousel.on( 'init', function ( event, slick, direction ) {
1565                $( event.currentTarget ).show();
1566            } );
1567
1568            imageCarousel.slick( {
1569                fade               : settings.fade,
1570                speed              : settings.speed,
1571                infinite           : settings.infinite,
1572                autoplay           : settings.autoplay,
1573                autoplaySpeed      : settings.autoplaySpeed,
1574                pauseOnHover       : settings.pauseOnHover,
1575                pauseOnInteraction : settings.pauseOnInteraction,
1576                slidesToShow       : settings.slidesToShow,
1577                slidesToScroll     : settings.slidesToScroll,
1578                rows               : 1,
1579                slidesPerRow       : 1,
1580                dots               : settings.dots,
1581                arrows             : settings.arrows,
1582                prevArrow          : imageCarouselWrap.find( '.rhea-image-carousel-button-prev' ),
1583                nextArrow          : imageCarouselWrap.find( '.rhea-image-carousel-button-next' ),
1584                vertical           : false,
1585                mobileFirst        : true,
1586                adaptiveHeight     : false,
1587                rtl                : $( 'body' ).hasClass( 'rtl' ),
1588                responsive         : [
1589                    {
1590                        breakpoint : 1025,
1591                        settings   : {
1592                            slidesToShow   : settings.slidesToShow,
1593                            slidesToScroll : settings.slidesToScroll
1594                        }
1595                    },
1596                    {
1597                        breakpoint : 768,
1598                        settings   : {
1599                            slidesToShow   : settings.slidesToShowTablet,
1600                            slidesToScroll : settings.slidesToScrollTablet
1601                        }
1602                    },
1603                    {
1604                        breakpoint : 380,
1605                        settings   : {
1606                            slidesToShow   : settings.slidesToShowMobile,
1607                            slidesToScroll : settings.slidesToScrollMobile
1608                        }
1609                    },
1610                    {
1611                        breakpoint : 0,
1612                        settings   : {
1613                            slidesToShow   : 1,
1614                            slidesToScroll : 1
1615                        }
1616                    }
1617                ]
1618            } );
1619        }
1620    };
1621
1622    // Accordion Widget Script.
1623    window.rheaAccordion = function ( id ) {
1624        $( '#' + id + ' > .rhea-accordion-title' ).on( 'click', function ( event ) {
1625            var $this = $( this );
1626
1627            if ( $this.hasClass( 'rhea-accordion-active' ) ) {
1628                $this.next( '.rhea-accordion-content' ).slideUp( 500, function () {
1629                    $this.removeClass( 'rhea-accordion-active' )
1630                } );
1631            } else {
1632                $this.siblings( '.rhea-accordion-title' ).removeClass( 'rhea-accordion-active' );
1633                $this.addClass( 'rhea-accordion-active' )
1634                .next( '.rhea-accordion-content' )
1635                .slideDown( 500 )
1636                .siblings( '.rhea-accordion-content' )
1637                .slideUp( 500 );
1638            }
1639        } );
1640    };
1641
1642    // Tabs Widget Script.
1643    window.rheaTabs = function ( id ) {
1644        const tabsContainer      = $( '#' + id );
1645        const tabsList           = tabsContainer.find( '.rhea-tabs-list li' );
1646        const tabsContentWrapper = tabsContainer.find( '.rhea-tabs-content-wrapper' );
1647        const tabsContent        = tabsContainer.find( '.rhea-tabs-content-wrapper .rhea-tabs-content' );
1648
1649        if ( tabsContent.length ) {
1650            let minHeight      = 0;
1651            let contentHeights = [];
1652
1653            tabsContent.each( function ( index ) {
1654                // Gather all content wrapper heights.
1655                contentHeights.push( $( this ).outerHeight() );
1656            } );
1657
1658            if ( contentHeights ) {
1659                // Find max value in the array and add with wrapper's space.
1660                minHeight = Math.max.apply( Math, contentHeights ) + ( tabsContentWrapper.outerHeight() - tabsContentWrapper.height() );
1661
1662                // Set container minimum height
1663                tabsContainer.css( 'min-height', minHeight );
1664            }
1665        }
1666
1667        tabsList.on( 'click', function ( event ) {
1668            const $this = $( this );
1669
1670            tabsList.removeClass( 'rhea-tabs-active' );
1671            $this.addClass( 'rhea-tabs-active' );
1672
1673            // Hide all content and show current one.
1674            tabsContent.hide().removeClass( 'rhea-tabs-active' );
1675            tabsContent.eq( $this.index() ).show().addClass( 'rhea-tabs-active' );
1676        } );
1677    };
1678
1679    // Image Gallery Widget Script.
1680    window.rheaImageGallery = function ( settings ) {
1681        if ( jQuery().isotope ) {
1682            const container      = $( settings.containerId ),
1683                  filterLinks    = $( settings.filters ),
1684                  galleryOptions = {
1685                      filter          : "*",
1686                      animationEngine : 'best-available',
1687                      itemSelector    : settings.itemSelector
1688                  };
1689
1690            if ( 'grid' === settings.layout ) {
1691                galleryOptions.layoutMode = 'fitRows';
1692            }
1693
1694            const gallery = container.isotope( galleryOptions );
1695
1696            // Re-layout
1697            gallery.isotope( 'layout' );
1698
1699            filterLinks.on( 'click', function ( event ) {
1700                filterLinks.removeClass( 'current' );
1701                $( this ).addClass( 'current' );
1702
1703                gallery.isotope( { filter : '.' + $( this ).attr( 'data-filter' ) } );
1704                event.preventDefault();
1705            } );
1706        }
1707    };
1708
1709    // Get width and height and set the width/position of Featured Properties slider nav
1710    window.rheaFeaturedNavPosition = function ( id1, id2 ) {
1711        var sliderWidth = $( id1 ).outerWidth();
1712        var slideHeight = $( id1 ).outerHeight();
1713
1714        $( id2 ).width( sliderWidth );
1715        $( id2 ).css( 'top', slideHeight );
1716    }
1717
1718    // Schedule Tour Form Widget Script.
1719    window.rheaScheduleTourForm = function ( id ) {
1720        if ( jQuery().validate && jQuery().ajaxSubmit ) {
1721
1722            const formId           = $( id ),
1723                  submitButton     = formId.find( '.rhea-stf-submit' ),
1724                  ajaxLoader       = formId.find( '.rhea-stf-ajax-loader' ),
1725                  messageContainer = formId.find( '.rhea-stf-message-container' ),
1726                  errorContainer   = formId.find( ".rhea-stf-error-container" );
1727
1728            const formOptions = {
1729                beforeSubmit : function () {
1730                    submitButton.attr( 'disabled', 'disabled' );
1731                    ajaxLoader.fadeIn( 'fast' );
1732                    messageContainer.fadeOut( 'fast' );
1733                    errorContainer.fadeOut( 'fast' );
1734                },
1735                success      : function ( ajax_response, statusText, xhr, $form ) {
1736                    var response = $.parseJSON( ajax_response );
1737                    ajaxLoader.fadeOut( 'fast' );
1738                    submitButton.removeAttr( 'disabled' );
1739                    if ( response.success ) {
1740                        $form.resetForm();
1741                        messageContainer.html( response.message ).fadeIn( 'fast' );
1742
1743                        setTimeout( function () {
1744                            messageContainer.fadeOut( 'slow' )
1745                        }, 5000 );
1746
1747                        // Call reset function if it exists.
1748                        // if (typeof inspiryResetReCAPTCHA == 'function') {
1749                        //     inspiryResetReCAPTCHA();
1750                        // }
1751                    } else {
1752                        errorContainer.html( response.message ).fadeIn( 'fast' );
1753                    }
1754                }
1755            };
1756
1757            $( id ).validate( {
1758                errorLabelContainer : errorContainer,
1759                submitHandler       : function ( form ) {
1760                    $( form ).ajaxSubmit( formOptions );
1761                }
1762            } );
1763        }
1764    };
1765
1766    if ( jQuery().isotope ) {
1767        $( '.rhea_properties_cities_wrapper.masonry' ).isotope( {
1768            itemSelector : '.rhea_property_city',
1769            //percentPosition: true,
1770            masonry : {
1771                //columnWidth: 300,
1772                horizontalOrder : true
1773            }
1774        } )
1775    }
1776
1777    /**
1778     * Enable empty values dropdown fields again on clicking the browser back button
1779     */
1780    window.onload = function ( event ) {
1781        setTimeout( function () {
1782            $( '.rhea_multi_select_picker' ).selectpicker( 'refresh' );
1783            $( '.rhea_multi_select_picker_location ' ).selectpicker( 'refresh' );
1784        }, 500 );
1785
1786    }
1787
1788
1789    /**
1790     * Hotel Services Slider
1791     */
1792
1793    window.rheaServicesSlider = function ( id ) {
1794
1795        const carousel = $( id ).find( '.rhea-service-carousel-tabs' );
1796        const slider   = $( id ).find( '.rhea-service-carousel-images' );
1797        const navPrev  = $( id ).find( '.rhea-prev-service' );
1798        const navNext  = $( id ).find( '.rhea-next-service' );
1799
1800        carousel.slick( {
1801            slidesToShow   : 4,
1802            slidesToScroll : 1,
1803            asNavFor       : slider,
1804            dots           : false,
1805            centerMode     : false,
1806            focusOnSelect  : true,
1807            prevArrow      : navPrev,
1808            nextArrow      : navNext,
1809            responsive     : [
1810                {
1811                    breakpoint : 1200,
1812                    settings   : {
1813                        slidesToShow : 3
1814                    }
1815                },
1816                {
1817                    breakpoint : 800,
1818                    settings   : {
1819                        slidesToShow : 2
1820                    }
1821                }
1822            ]
1823        } );
1824
1825        slider.slick( {
1826            slidesToShow   : 1,
1827            slidesToScroll : 1,
1828            arrows         : false,
1829            fade           : true,
1830            draggable      : false
1831        } );
1832
1833    }
1834
1835    /**
1836     * RVR guests fields counter
1837     */
1838    window.rvrGuestsFieldsCounter = function ( field, wrapper ) {
1839        const guestNumberField = $( wrapper ).find( '.rhea-guests-number' );
1840        guestNumberField.each( function () {
1841
1842            let decrement      = $( this ).find( '.minus' );
1843            let increment      = $( this ).find( '.plus' );
1844            let $input         = $( this ).find( 'input' );
1845            let currentCounter = '';
1846            let adultsRequired = false;
1847            if ( $( this ).hasClass( 'adults-field' ) ) {
1848                currentCounter = $( this ).closest( '.rhea-guests-field-dropdown-box' ).find( '.adults i' );
1849                adultsRequired = true;
1850            }
1851            if ( $( this ).hasClass( 'children-field' ) ) {
1852                currentCounter = $( this ).closest( '.rhea-guests-field-dropdown-box' ).find( '.children i' );
1853            }
1854            if ( $( this ).hasClass( 'infants-field' ) ) {
1855                currentCounter = $( this ).closest( '.rhea-guests-field-dropdown-box' ).find( '.infants i' );
1856            }
1857
1858            decrement.on( 'click', function () {
1859
1860                let count = parseInt( $input.val() ) - 1;
1861                if ( true === adultsRequired ) {
1862                    count = count < 1 ? 1 : count;
1863                } else {
1864                    count = count < 0 ? 0 : count;
1865                }
1866                $input.val( count );
1867                $input.change();
1868                currentCounter.html( count );
1869                return false;
1870            } );
1871
1872            increment.on( 'click', function () {
1873                let count = parseInt( $input.val() ) + 1;
1874                $input.val( count );
1875                $input.change();
1876                currentCounter.html( count );
1877                return false;
1878            } );
1879
1880        } );
1881
1882        $( field ).on( 'click', function () {
1883            if ( ! $( wrapper ).hasClass( 'active' ) ) {
1884                $( wrapper ).addClass( 'active' );
1885            } else {
1886                $( wrapper ).removeClass( 'active' );
1887            }
1888        } );
1889
1890        //Close guests field dropdown if click outside the wrapper
1891        $( 'body' ).on( "click", function ( e ) {
1892            const target     = $( '.rhea-guests-field-dropdown-box, .rhea-guests-field-dropdown-box *' );
1893            const targetDrop = $( '.rhea-rvr-guests-fields-wrapper' );
1894            if ( targetDrop.hasClass( 'active' ) ) {
1895                if ( $( e.target ).is( target ) === false && $( e.target ).is( targetDrop ) === false ) {
1896                    targetDrop.removeClass( "active" );
1897                }
1898            }
1899        } );
1900
1901    }
1902
1903} )( jQuery );

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.