/* Minification failed. Returning unminified contents.
(1158,13-23): run-time error JS1300: Strict-mode does not allow assignment to undefined variables: cal_single
 */
'use strict';

(function (root, _) {

  'use strict';

  // namespacing

  var namespace = {
    Models: {},
    Collections: {},
    Views: { ThreeComps: {} },
    Routers: {},
    Utils: {},
    LocalStorageAdapter: {},
    AdSlots: {}
  };

  root.Rev = _.extend(root.Rev || {}, namespace);
})(window, _);
'use strict';

(function (Rev, $, _, Backbone) {

  'use strict';

  /* extend Backbone.Events for global event aggregation
   * e.g. Rev.trigger('user:login', {id:'xxx'}) 
   *       -> Rev.on('user:login', function(id){...} or this.listenTo(Rev, 'user:login", function(id){..})
   */

  _.extend(Rev, Backbone.Events);

  $.cookie.json = true; // https://github.com/carhartl/jquery-cookie

  /*
   * handlebars style templating for underscore template engine. refer http://underscorejs.org/#template
   * usage :
   * var template = _.template("Hello {{= name }}!");
   * template({name: "Handlebars"});
   *   => "Hello Handlebars!"
   */

  _.templateSettings = {
    evaluate: /\{\{(.+?)\}\}/g,
    interpolate: /\{\{=(.+?)\}\}/g,
    escape: /\{\{-(.+?)\}\}/g
  };

  /* 
   * jquery plugin to catch event outside of specific element
   * usage : this.$('.container').outside('click', function(e){ ... });
  */
  $.fn.outside = function (ename, cb) {
    return this.each(function () {
      var $this = $(this),
          self = this;
      $(document.body).bind(ename, function tempo(e) {
        if (e.target !== self && !$.contains(self, e.target)) {
          cb.apply(self, [e]);
          if (!self.parentNode) $(document.body).unbind(ename, tempo);
        }
      });
    });
  };
})(Rev, jQuery, _, Backbone);
'use strict';

(function (Rev, $, _) {

  'use strict';

  var _oasSitePage = {
    'default': 'mobile_search_buy',
    'buy': 'mobile_search_buy',
    'rent': 'mobile_search_rent',
    'sold': 'mobile_search_sold'
  };

  var _googleRecaptchKey = "6Ldkij0UAAAAAC0fX_ASCAJbNLq7KsdsRwH14P_4";

  Rev.Config = {
    getOasAdvertSitePage: function getOasAdvertSitePage(menu) {
      return _oasSitePage[menu] || _oasSitePage['default'];
    },
    getGoogleRecaptchaKey: function getGoogleRecaptchaKey() {
      return _googleRecaptchKey;
    }
  };
})(Rev, jQuery, _);
'use strict';

(function (Rev, _, $) {

    'use strict';

    // This object is not being used as requirement has changed from displaying middle map only for QLD properties to displaying middle map for All the properties (03-29-2016)

    Rev.Utils.Address = {

        states: ['qld', 'queensland'],

        displayMiddleMap: function displayMiddleMap(address) {
            if (address && address.State && _.indexOf(this.states, address.State.toLowerCase()) >= 0) {
                return true;
            }
        }
    };
})(Rev, _, jQuery);
'use strict';

// dependencies : Rev, jquery

(function (Rev, $, _) {

  'use strict';

  var hideAfter = Rev.IsPhone ? 1000 * 2 : 1000 * 5; // hide message after 2 or 5 seconds
  var timer = null;

  var hideAllMessages = function hideAllMessages() {
    if (timer != null) clearTimeout(timer);
    timer = setTimeout(function () {
      $('.alert-message').removeClass('show');
      setTimeout(function () {
        return $('.alert-message').remove();
      }, 300);
    }, hideAfter);
  };

  Rev.Utils.showSuccessMessage = function (message) {
    var delay = 0;
    if ($('.alert-message').length) {
      $('.alert-message').removeClass('show');
      delay = 400;
    }

    setTimeout(function () {
      $('.alert-message').remove();
      var template = _.template($('#template-alert-message-success').html());
      var html = template({ message: message });
      $('body').append(html);
      setTimeout(function () {
        return $('.alert-message.success').addClass('show');
      }, 10);

      hideAllMessages();
    }, delay);
  };

  Rev.Utils.showErrorMessage = function (message) {
    var delay = 0;
    if ($('.alert-message').length) {
      $('.alert-message').removeClass('show');
      delay = 300;
    }

    setTimeout(function () {
      $('.alert-message').remove();
      var template = _.template($('#template-alert-message-error').html());
      var html = template({ message: message });
      $('body').append(html);
      setTimeout(function () {
        return $('.alert-message.error').addClass('show');
      }, 10);

      hideAllMessages();
    }, delay);
  };
})(Rev, jQuery, _);
'use strict';

// dependencies : Rev, jquery

(function (Rev, $) {

  'use strict';

  Rev.Utils.needToAskAuthAuctionAlert = function () {
    return !$.cookie('askedAuthAuctionAlert');
  };

  Rev.Utils.askAuthAuctionAlert = function (loginSuccessCallback, signupSuccessCallback, closeWindowCallback, callbackIfAlreadyAuthenticated) {

    var askedBefore = $.cookie('askedAuthAuctionAlert');

    if (!askedBefore) {

      // save cookie
      // the reason why following line is here not after if(result && !result.isAuthenticated) is 
      // sometimes cookie is not saved correctly, so, in order to avoid check if user is authenticated everytime using ajax call in that case
      // just put following line here
      $.cookie('askedAuthAuctionAlert', true, { expires: 7, path: '/' }); // 7 days

      // check if user is authenticated
      $.get('/authenticated/').done(function (result) {

        if (result && !result.isAuthenticated) {

          setTimeout(function () {
            // double check if cookie is saved because of some reason cookie is not saved correctly. In that case we just don't show it
            if ($.cookie('askedAuthAuctionAlert')) {
              if (Rev.IsPhone) {
                Rev.trigger('sidebar:toggle', {
                  loginSuccessCallback: loginSuccessCallback,
                  signupSuccessCallback: signupSuccessCallback,
                  closeWindowCallback: closeWindowCallback
                });
                Rev.trigger('login:toggle');
              } else {
                Rev.Utils.showAuthModal('login', null, null, null, loginSuccessCallback, signupSuccessCallback, closeWindowCallback);
              }
            } else {
              // this case is error because saving cookie is failed
              // so try to save cookie again then execute callback function
              $.cookie('askedAuthAuctionAlert', true, { expires: 7, path: '/' }); // 7 days
              if (closeWindowCallback) {
                closeWindowCallback();
              }
            }
          }, 100);
        } else {

          if (callbackIfAlreadyAuthenticated) {
            callbackIfAlreadyAuthenticated();
          }
        }
      });
    }
  };
})(Rev, jQuery);
'use strict';

// dependencies : Rev, jquery

(function (Rev, $) {

  'use strict';

  Rev.Utils.askSaveSearch = function () {
    // show dialog if user is authenticated, no saved searches and cookie says no asking save search before
    var askedBefore = $.cookie('askedSaveSearchBefore');

    if (!askedBefore) {
      var currentUrl = location.href;

      if (currentUrl) {
        var parsedUrlObj = Rev.Utils.parseUrl(currentUrl);

        // check if any location criteria is selected
        if (parsedUrlObj && parsedUrlObj.loc) {

          // check if user is authenticated
          $.get('/authenticated/').done(function (result) {
            if (result && result.isAuthenticated) {

              // check if there is any saved searches for this user
              $.get('/saved-searches/total/').done(function (viewAlertTotal) {
                if (viewAlertTotal && viewAlertTotal.total === 0) {

                  // save cookie
                  $.cookie('askedSaveSearchBefore', true, { expires: 10, path: '/' }); // 10 days

                  setTimeout(function () {
                    if ($('.result-page.search-result-page').is(':visible')) {

                      // double check if cookie is saved because of some reason cookie is not saved correctly. In that case we just don't show it
                      if ($.cookie('askedSaveSearchBefore')) {
                        Rev.Utils.showSaveSearchConfirmModal();
                      }
                    }
                  }, 100);
                }
              });
            }
          });
        }
      }
    }
  };
})(Rev, jQuery);
'use strict';

(function (Rev, _, $) {

  'use strict';

  Rev.Utils.Auth = {
    isUserAuthenticated: function isUserAuthenticated() {
      var dfd = $.Deferred();

      $.get('/authenticated/').done(function (result) {

        if (result && result.isAuthenticated) {
          dfd.resolve();
        } else {
          dfd.reject();
        }
      });

      return dfd.promise();
    }
  };
})(Rev, _, jQuery);
'use strict';

// dependencies : Rev, jquery

(function (Rev, $) {

    'use strict';

    Rev.Utils.confirm = function (message, okCallback, cancelCallback) {

        // remove viewAlertOptionView if exist
        if (Rev.confirmView) Rev.confirmView.remove();

        // insert view alert option modal html
        var template = _.template($('#template-confirm-modal').html());
        var html = template({ message: message || 'Are you sure?' });
        $('#rev-modal-placeholder .rev-modal-content-placeholder').html(html);

        // show backdrop
        $('#rev-modal-placeholder .rev-modal-backdrop').show();

        // open modal
        $('#rev-modal-placeholder .rev-modal-content-placeholder .confirm-modal').modal({ backdrop: false });

        Rev.confirmView = new Rev.Views.ConfirmView({
            el: '#rev-modal-placeholder .rev-modal-content-placeholder .confirm-modal',
            okCallback: okCallback,
            cancelCallback: cancelCallback
        });
    };
})(Rev, jQuery);
'use strict';

// dependencies : Rev, jquery

(function (Rev, $) {

  'use strict';

  Rev.Utils.showContactAgentModal = function (agencyId) {

    // remove email agent view if exist
    if (Rev.contactAgentView) Rev.contactAgentView.remove();

    $.getJSON('/contact/agency/contact/form/json/', { agencyId: agencyId }).done(function (result) {

      // insert email agent html
      $('#rev-modal-placeholder .rev-modal-content-placeholder').html(result.view);

      setTimeout(function () {
        // show backdrop
        $('#rev-modal-placeholder .rev-modal-backdrop').show();

        // open modal
        $('#rev-modal-placeholder .rev-modal-content-placeholder #contact-agent-modal-' + agencyId).modal({ backdrop: false });

        // create view instance for email agent modal
        Rev.contactAgentView = new Rev.Views.ContactAgentView({
          el: '#rev-modal-placeholder .rev-modal-content-placeholder #contact-agent-modal-' + agencyId
        });
      }, 300);
    });
  };
})(Rev, jQuery);
"use strict";

(function (Rev, _, $) {

    'use strict';

    Rev.Utils.Criteo = {
        pushEventHomepage: function pushEventHomepage() {
            window.criteo_q = window.criteo_q || [];
            window.criteo_q.push({ event: "setAccount", account: 27289 }, { event: "setHashedEmail", email: Rev.hashedEmailAddress }, { event: "setSiteType", type: Rev.IsPhone ? 'm' : 'd' }, { event: "viewHome" });
        },
        pushEventSearchResults: function pushEventSearchResults(listingIds) {
            window.criteo_q = window.criteo_q || [];
            window.criteo_q.push({ event: "setAccount", account: 27289 }, { event: "setHashedEmail", email: Rev.hashedEmailAddress }, { event: "setSiteType", type: Rev.IsPhone ? 'm' : 'd' }, { event: "viewList", item: _.first(listingIds, 3) });
        },
        pushDetailsPageEvent: function pushDetailsPageEvent(listingId) {

            window.criteo_q = window.criteo_q || [];
            window.criteo_q.push({ event: "setAccount", account: 27289 }, { event: "setHashedEmail", email: Rev.hashedEmailAddress }, { event: "setSiteType", type: Rev.IsPhone ? 'm' : 'd' }, { event: "viewItem", item: listingId });
        },
        pushEventAgentContact: function pushEventAgentContact(listingId) {

            var transactionId = Date.now() + "_" + listingId;

            window.criteo_q = window.criteo_q || [];
            window.criteo_q.push({ event: "setAccount", account: 27289 }, { event: "setHashedEmail", email: Rev.hashedEmailAddress }, { event: "setSiteType", type: Rev.IsPhone ? 'm' : 'd' }, {
                event: "trackTransaction",
                id: transactionId,
                item: [{ id: listingId, price: 1, quantity: 1 }]
            });
        },
        pushEventViewBasket: function pushEventViewBasket(listingId) {
            window.criteo_q = window.criteo_q || [];
            window.criteo_q.push({ event: "setAccount", account: 27289 }, { event: "setHashedEmail", email: Rev.hashedEmailAddress }, { event: "setSiteType", type: Rev.IsPhone ? 'm' : 'd' }, {
                event: "viewBasket",
                item: [{ id: listingId, price: 1, quantity: 1 }]
            });
        }
    };
})(Rev, _, jQuery);
'use strict';

// dependencies : Rev, jquery

(function (Rev, $) {

    'use strict';

    Rev.Utils.showEmailAgentModal = function (listingId, gaCategory, gaAgencyName, gaAgencyEmail, topSpotId, agencyId, gaAction) {

        // remove email agent view if exist
        if (Rev.emailAgentView) Rev.emailAgentView.remove();

        $.getJSON('/contact/agency/enquiry/form/json/', { listingId: listingId }).done(function (result) {

            // insert email agent html
            $('#rev-modal-placeholder .rev-modal-content-placeholder').html(result.view);

            if ($('.email-agent-success-no-ad').length) {
                $('.modal').addClass('no-display-post-enquiry-ad');
            }

            setTimeout(function () {
                // show backdrop
                $('#rev-modal-placeholder .rev-modal-backdrop').show();

                // open modal
                $('#rev-modal-placeholder .rev-modal-content-placeholder #email-agent-modal-' + listingId).modal({ backdrop: false });

                // create view instance for email agent modal
                Rev.emailAgentView = new Rev.Views.EmailAgentView({
                    el: '#rev-modal-placeholder .rev-modal-content-placeholder #email-agent-modal-' + listingId,
                    model: new Rev.Models.ListDetails(result.model),
                    gaCategory: gaCategory,
                    gaAgencyName: gaAgencyName,
                    gaAgencyEmail: gaAgencyEmail,
                    topSpotId: topSpotId,
                    listingId: listingId,
                    agencyId: agencyId
                });
            }, 300);
        });

        // fire ga event
        if (gaCategory) Rev.Utils.GaTracking.trackGaEvent(gaCategory, gaAction || Rev.Utils.GaTracking.Action.EmailAgent, 'Property ' + listingId);

        Rev.Utils.Criteo.pushEventViewBasket(listingId);
    };

    Rev.Utils.closeEmailAgentModal = function () {
        if (Rev.emailAgentView) Rev.emailAgentView.remove();
    };
})(Rev, jQuery);
'use strict';

// dependencies : Rev, jquery

(function (Rev, $) {

    'use strict';

    Rev.Utils.GaTracking = {
        tracGaPageview: function tracGaPageview(pathname) {
            ga('set', 'page', pathname);
            ga('send', 'pageview');

            if (Rev.EnableDebugOutput && console) {
                console.log("ga send pageview:", pathname);
            }
        },

        trackGaEvent: function trackGaEvent(category, action, label) {
            if (!ga || !category || !action) return;

            var resp;
            if (label) resp = ga('send', 'event', category, action, label);else resp = ga('send', 'event', category, action);

            if (Rev.EnableDebugOutput && console) {
                console.log("ga send event:", category, action, label, "response:", resp);
            }
        },

        trackPhoneAgent: function trackPhoneAgent(model) {
            this.trackEnquiry(model, 'phone');
        },

        trackEmailAgent: function trackEmailAgent(model) {
            this.trackEnquiry(model, 'email');
        },

        trackSoi: function trackSoi(model) {
            this.trackEnquiry(model, 'soi');
        },

        trackEnquiry: function trackEnquiry(model, enquiryType) {
            var action;
            var category;
            var label;
            var streetAddress;
            var suburb;
            var state;
            var postcode;
            var agencySeoKey;
            var tier;
            var listingType;

            if (model.has('Agencies')) {
                streetAddress = model.get('Address').StreetAddress;
                suburb = model.get('Address').Suburb;
                state = model.get('Address').State;
                postcode = model.get('Address').Postcode;
                agencySeoKey = model.get('Agencies')[0].SeoKey;
                tier = model.get('Tier') === 10 || model.get('Tier') === 20 ? "feature" : "standard";
                if (model.get('ListingEnquiryForm').ListingCategory === 0) listingType = "buy";else if (model.get('ListingEnquiryForm').ListingCategory === 1) listingType = 'rent';else if (model.get('ListingEnquiryForm').ListingCategory === 2) listingType = 'sold';
            } else {
                streetAddress = model.get('StreetAddress');
                suburb = model.get('Suburb');
                state = model.get('State');
                postcode = model.get('Postcode');
                agencySeoKey = model.get('AgencySeoKey');
                tier = model.get('Tier').toLowerCase() === "featured" || model.get('Tier').toLowerCase() === "feature" ? "feature" : "standard";
                if (model.get('ListingCategory') === 0) listingType = "buy";else if (model.get('ListingCategory') === 1) listingType = 'rent';else if (model.get('ListingCategory') === 2) listingType = 'sold';
            }

            // normal events
            if (listingType === 'buy') {
                if (enquiryType === 'phone') {
                    action = this.Action.CallEnquiryBuy;
                    category = state + "-call-enquiry-buy";
                } else if (enquiryType === 'email') {
                    action = this.Action.SendEnquiryBuy;
                    category = state + "-send-enquiry-buy";
                } else if (enquiryType === 'soi') {
                    action = this.Action.SoiEnquiryBuy;
                    category = state + "-soi-enquiry-buy";
                }
            } else if (listingType === 'rent') {
                if (enquiryType === 'phone') {
                    action = this.Action.CallEnquiryRent;
                    category = state + "-call-enquiry-rent";
                } else if (enquiryType === 'email') {
                    action = this.Action.SendEnquiryRent;
                    category = state + "-send-enquiry-rent";
                } else if (enquiryType === 'soi') {
                    action = this.Action.SoiEnquiryRent;
                    category = state + "-soi-enquiry-rent";
                }
            } else if (listingType === 'sold') {
                if (enquiryType === 'phone') {
                    action = this.Action.CallEnquirySold;
                    category = state + "-call-enquiry-sold";
                } else if (enquiryType === 'email') {
                    action = this.Action.SendEnquirySold;
                    category = state + "-send-enquiry-sold";
                }
            }

            label = suburb + "-" + state + "-" + postcode + "-" + streetAddress + "-" + model.get('Id') + "-" + agencySeoKey;

            this.trackGaEvent(this.sanitiseString(category), this.sanitiseString(action), this.sanitiseString(label));

            // upsell events
            if (listingType !== 'sold') {
                if (listingType === 'buy') {
                    if (enquiryType === 'phone') {
                        action = tier === "feature" ? this.Action.UpsellPhoneBuyFeature : this.Action.UpsellPhoneBuyStandard;
                        category = state + "-upsell-phone-buy-" + tier;
                    } else if (enquiryType === 'email') {
                        action = tier === "feature" ? this.Action.UpsellEmailBuyFeature : this.Action.UpsellEmailBuyStandard;
                        category = state + "-upsell-email-buy-" + tier;
                    } else if (enquiryType === 'soi') {
                        action = tier === "feature" ? this.Action.UpsellSoiBuyFeature : this.Action.UpsellSoiBuyStandard;
                        category = state + "-upsell-soi-buy-" + tier;
                    }
                } else if (listingType === 'rent') {
                    if (enquiryType === 'phone') {
                        action = tier === "feature" ? this.Action.UpsellPhoneRentFeature : this.Action.UpsellPhoneRentStandard;
                        category = state + "-upsell-phone-rent-" + tier;
                    } else if (enquiryType === 'email') {
                        action = tier === "feature" ? this.Action.UpsellEmailRentFeature : this.Action.UpsellEmailRentStandard;
                        category = state + "-upsell-email-rent-" + tier;
                    }
                }

                label = suburb + "-" + state + "-" + postcode;

                this.trackGaEvent(this.sanitiseString(category), this.sanitiseString(action), this.sanitiseString(label));
            }
        },
        sanitiseString: function sanitiseString(string) {
            return string.replace(/\s+/g, '-').replace(/,/g, '').toLowerCase();
        },


        // The same category, action, label as RevConsumer.Rev.Models.Tracking models
        Category: {
            Property: 'property',
            SearchResults: 'search results',
            ShortlistProperties: 'shortlist-properties',
            RecentlyViewed: 'recently-viewed',
            PropertyBuy: 'property-buy',
            PropertyRent: 'property-rent',
            PropertySold: 'property-sold',
            Shortlist: 'shortlist',
            FindAnAgent: 'find-an-agent',
            RefineSearchSavedSearches: 'refinesearch-saved-searches',
            SavedSearches: 'saved-searches',
            PreferenceCentre: 'preference-centre',
            Unsubscribe: 'unsubscribe',
            PropertyBuyPopup: 'property-buy-popup',
            PropertyRentPopup: 'property-rent-popup',
            PropertySoldPopup: 'property-sold-popup',
            HomeBuy: 'home-buy',
            HomeRent: 'home-rent',
            HomeSold: 'home-sold',
            SalesAuctionResults: 'salesauctionresults',
            AgentsHowToWin: 'agents-how-to-win',
            Property360Home: 'property-360-home',
            Property360Address: 'property-360-address',
            AgentProfile: 'agent-profile'
        },

        Action: {
            ImageGallery: 'image gallery',
            Search: 'search',
            SurroundingSuburbs: 'surrounding-suburbs',
            Price: 'price',
            Type: 'type',
            Bedrooms: 'bedrooms',
            Bathrooms: 'bathrooms',
            Carparks: 'carparks',
            SendToAgent: 'send-to-agent',
            PhoneAgent: 'phone-agent',
            InspectionTimes: 'inspection times',
            Shortlist: 'shortlist',
            RemoveShortlist: 'remove-shortlist',
            Map: 'map',
            ViewFloorplans: 'view-floorplans',
            MoreSearchOptions: 'more-search-options',
            LessSearchOptions: 'less-search-options',
            EmailAgent: 'email-agent',
            ShareViaFacebook: 'share-via-facebook',
            ShareViaTwitter: 'share-via-twitter',
            OtherPropertiesAgency: 'other-properties-agency',
            ShortlistOtherProperty: 'shortlist-other-property',
            ImageGalleryOtherProperty: 'image gallery-other-property',
            PropertiesYouMayLike: 'properties-you-may-like',
            ShortlistPropertiesYouMayLike: 'shortlist-properties-you-may-like',
            ImageGalleryPropertiesYouMayLike: 'image gallery-properties-you-may-like',
            SearchSuburb: 'search-suburb',
            SearchAgency: 'search-agency',
            MorePropertiesAgency: 'more-properties-agency',
            SaveThisSearch: 'save-this-search',
            ListView: 'list-view',
            MapView: 'map-view',
            PrintBrochure: 'print-brochure',
            ShareViaEmail: 'share-via-email',
            SendToFriend: 'send-to-friend',
            ViewVideo: 'view-video',
            EmailFrequency: 'email-frequency',
            EditSearch: 'edit-search',
            DeleteSearch: 'delete-search',
            EditPersonalDetails: 'edit-personal-details',
            EditStatus: 'edit-status',
            SubscribePromoEmails: 'subscribe-promo-emails',
            UnsubscribeAllEmails: 'unsubscribe-all-emails',
            UnsubscribeViewAlert: 'unsubscribe-view-alert',
            UnsubscribeAllViewAlerts: 'unsubscribe-all-view-alerts',
            UnsubscribeAuctionAlert: 'unsubscribe-auction-alert',
            OpenImageView: 'Open image view',
            CloseImageView: 'Close image view',
            PointsOfInterestShow: 'points-of-interest-show',
            PointsOfInterestHide: 'points-of-interest-hide',
            PointsOfInterestSettings: 'points-of-interest-settings',
            PointsOfInterestSave: 'points-of-interest-save',
            ViewSalesResults: 'view-sales-results',
            EditAlert: 'edit-alert',
            ViewAllSalesData: 'view-all-sales-data',
            RequestEmailSignature: 'request-email-signature',
            RequestFlyers: 'request-flyers',
            RequstDisplayBanners: 'request-display-banners',
            CreateEmailAlert: 'create-email-alert',
            AddAuctionAlert: 'add-auction-alert',
            SearchAddress360: 'search-address-360',
            SearchStreet360: 'search-street-360',
            SearchSuburb360: 'search-suburb-360',
            NewSearchFromAddress: 'new-search-from-address',
            OpenImageView2: 'open-image-view',
            CloseImageView2: 'close-image-view',
            ViewImageGallery: 'view-image-gallery',
            ClickIntoCurrentSaleListing: 'click-into-current-sale-listing',
            ClickIntoCurrentRentListing: 'click-into-current-rent-listing',
            ClickIntoCurrentSoldListing: 'click-into-current-sold-listing',
            ClickAllSaleRentalHistory: 'click-all-sale-rental-history',
            ClickSaleHistoryOnly: 'click-sale-history-only',
            ClickRentalHistoryOnly: 'click-rental-history-only',
            SimilarPropertiesSold: 'similar-properties-sold',
            SimilarPropertiesSale: 'similar-properties-sale',
            SimilarPropertiesRent: 'similar-properties-rent',
            ClickIntoSimilarSoldListing: 'click-into-similar-sold-listing',
            ClickIntoSimilarSaleListing: 'click-into-similar-sale-listing',
            ClickIntoSimilarRentListing: 'click-into-similar-rent-listing',
            WhatsNearbyMapCategory: 'whats-nearby-map-category',
            ClickIntoNeighbouringProperty360Address: 'click-into-neighbouring-property-360-address',
            SuburbTrendsSaleHouse: 'suburb-trends-sale-house',
            SuburbTrendsAvgDaysListedHouse: 'suburb-trends-avg-days-listed-house',
            SuburbTrendsAvgVendorDiscHouse: 'suburb-trends-avg-vendor-disc-house',
            SuburbTrendsRentalHouse: 'suburb-trends-rental-house',
            SuburbTrendsSaleUnit: 'suburb-trends-sale-unit',
            SuburbTrendsAvgDaysListedUnit: 'suburb-trends-avg-days-listed-unit',
            SuburbTrendsAvgVendorDiscUnit: 'suburb-trends-avg-vendor-disc-unit',
            SuburbTrendsRentalUnit: 'suburb-trends-rental-unit',
            ContactAgent: 'contact-agent',
            AvmTopReplaceThem: 'avm-top-replace-them',
            AvmTopClickIntoAddress: 'avm-top-click-into-address',
            AvmEstimateBeds: 'avm-estimate-beds',
            AvmEstimateBath: 'avm-estimate-bath',
            AvmEstimateCar: 'avm-estimate-car',
            AvmEstimateType: 'avm-estimate-type',
            AvmEstimateChoose: 'avm-estimate-choose',
            AvmEstimateReplace: 'avm-estimate-replace',
            AvmEstimateUpdate: 'avm-estimate-update',
            AvmEstimatePhotoGalleryOpen: 'avm-estimate-photo-gallery-open',
            AvmEstimatePhotoGalleryScroll: 'avm-estimate-photo-gallery-scroll',
            AvmEstimatePhotoScroll: 'avm-estimate-photo-scroll',
            GetYour360AppraisalClick: 'get-your-360-appraisal-click',
            Send360Appraisal: 'send-360-appraisal',
            SoiClick: 'soi-click',
            SoiClickRev: 'soi-click-rev',
            SoiClickThirdParty: 'soi-click-3rd-party',
            GetHomeLoanQuote: 'get-home-loan-quote',
            ViewHomeLoanTopClick: 'homeloan-top-click',
            ViewHomeLoanBannerClick: 'homeloan-banner',
            ViewHomeLoan360TopClick: 'homeloan-refinance-top-click',
            ViewHomeLoan360BannerClick: 'homeloan-refinance',
            ExpandComparableSales: 'expand-comparable-sales',
            ExpandServiceSeeking: 'expand-serviceseeking',
            ExpandMeetTheNeighbours: 'expand-meet-the-neighbours',
            ExpandSuburbTrends: 'expand-suburb-trends',
            ExpandListingDescriptionReadMore: 'expand-listing-description-read-more',
            AvmHowDoesThisWorkVideo: 'p360-video-how-does-this-work',
            EmailProfile: 'email-profile',
            PhoneProfile: 'phone-profile',
            CallEnquiryBuy: 'call-enquiry-buy',
            CallEnquiryRent: 'call-enquiry-rent',
            CallEnquirySold: 'call-enquiry-sold',
            SendEnquiryBuy: 'send-enquiry-buy',
            SendEnquiryRent: 'send-enquiry-rent',
            SendEnquirySold: 'send-enquiry-sold',
            SoiEnquiryBuy: 'soi-enquiry-buy',
            UpsellEmailBuyFeature: 'upsell-email-buy-feature',
            UpsellEmailBuyStandard: 'upsell-email-buy-standard',
            UpsellEmailRentFeature: 'upsell-email-rent-feature',
            UpsellEmailRentStandard: 'upsell-email-rent-standard',
            UpsellPhoneBuyFeature: 'upsell-phone-buy-feature',
            UpsellPhoneBuyStandard: 'upsell-phone-buy-standard',
            UpsellPhoneRentFeature: 'upsell-phone-rent-feature',
            UpsellPhoneRentStandard: 'upsell-phone-rent-standard',
            UpsellSoiBuyFeature: 'upsell-soi-buy-feature',
            UpsellSoiBuyStandard: 'upsell-soi-buy-standard'
        },

        Label: {
            Property: 'property ',
            Bedrooms: 'bedrooms ',
            Bathrooms: 'bathrooms ',
            Carparks: 'carparks ',
            On: 'on',
            Off: 'off',
            PriceMin: 'price-min ',
            PriceMax: 'price-max ',
            Floorplans: 'floorplans',
            Inspection: 'inspection ',
            SearchOptionsOpen: 'search options open',
            SearchOptionsClose: 'search options close',
            ShareFacebook: 'share facebook',
            ShareTwitter: 'share twitter',
            SearchSaved: 'search saved',
            ShareEmail: 'share-email',
            SendEmailToFriend: 'send email to friend',
            Subscribed: 'subscribed',
            Unsubscribed: 'unsubscribed',
            ViewVictorianSalesResults: 'view-victorian-sales-results',
            AlertEdited: 'alert edited',
            ViewAllSalesResults: 'view-all-sales-results',
            AlertSaved: 'alert saved',
            DoNotSend: 'do-not-send',
            SearchProperty360Address: 'search property 360 address'
        }
    };
})(Rev, jQuery);
'use strict';

// dependencies : Rev, jquery

(function (Rev, $) {

  'use strict';

  // return localStorage size in Megabytes

  Rev.Utils.getLocalstorageSize = function () {
    var total = 0;
    for (var x in localStorage) {
      var amount = localStorage[x].length * 2 / 1024 / 1024;
      total += amount;
      //console.log( x + " = " + amount.toFixed(2) + " MB");
    }
    //console.log( "Total: " + total.toFixed(2) + " MB");

    return total.toFixed(2);
  };
})(Rev, jQuery);
'use strict';

// dependencies : Rev, jquery

(function (Rev, $, _) {

  'use strict';

  Rev.Utils.getMarkerImageByType = function (googleTypes) {

    Rev.Models.localData.fetch();
    var localTypes = Rev.Models.localData.getPoiTypes();

    if (_.indexOf(googleTypes, 'bar') > -1 && _.indexOf(localTypes, 'bar') > -1) {
      return '/assets/content/images/map_markers/icn-bars-marker.png';
    }

    if (_.indexOf(googleTypes, 'bus_station') > -1 && _.indexOf(localTypes, 'bus_station') > -1) {
      return '/assets/content/images/map_markers/icn-bus-stations-marker.png';
    }

    if (_.indexOf(googleTypes, 'school') > -1 && _.indexOf(localTypes, 'school') > -1) {
      return '/assets/content/images/map_markers/icn-schools-marker.png';
    }

    if (_.indexOf(googleTypes, 'store') > -1 && _.indexOf(localTypes, 'store') > -1) {
      return '/assets/content/images/map_markers/icn-supermarkets-marker.png';
    }

    if (_.indexOf(googleTypes, 'train_station') > -1 && _.indexOf(localTypes, 'train_station') > -1) {
      return '/assets/content/images/map_markers/icn-train-stations-marker.png';
    }

    if (_.indexOf(googleTypes, 'park') > -1 && _.indexOf(localTypes, 'park') > -1) {
      return '/assets/content/images/map_markers/icn-parks-marker.png';
    }

    if (_.indexOf(googleTypes, 'restaurant') > -1 && _.indexOf(localTypes, 'restaurant') > -1) {
      return '/assets/content/images/map_markers/icn-restaurants-marker.png';
    }

    if (_.indexOf(googleTypes, 'university') > -1 && _.indexOf(localTypes, 'university') > -1) {
      return '/assets/content/images/map_markers/icn-uni-marker.png';
    }

    if (_.indexOf(googleTypes, 'hospital') > -1 && _.indexOf(localTypes, 'hospital') > -1) {
      return '/assets/content/images/map_markers/icn-hospital-marker.png';
    }

    if (_.indexOf(googleTypes, 'cafe') > -1 && _.indexOf(localTypes, 'cafe') > -1) {
      return '/assets/content/images/map_markers/icn-cafe-marker.png';
    }

    return '/assets/content/images/map_markers/icn-property-marker.png';
  };
})(Rev, jQuery, _);
'use strict';

// dependencies : Rev, jquery

(function (Rev, $, _) {

  'use strict';

  /* 
   * type of searchForm is ListingSearchForm 
   */

  Rev.Utils.setTargetingResultPage = function (searchForm) {

    if (!searchForm) return;

    googletag.cmd.push(function () {

      // suburb
      if (searchForm.Location) {
        var suburbs = [];
        var locations = searchForm.Location.trim().split(',');

        _.each(locations, function (location) {
          if (!location) return;
          var locationSplited = [];
          if (location.indexOf('|') > -1) {
            locationSplited = location.split('|');
          }
          if (location.indexOf('_') > -1) {
            locationSplited = location.split('_');
          }

          if (locationSplited[0] && locationSplited[1] && locationSplited[2]) {
            if (locationSplited[0].indexOf('undefined') === -1 && locationSplited[1].indexOf('undefined') === -1 && locationSplited[2].indexOf('undefined') === -1) {
              suburbs.push(locationSplited[0]);
            }
          }
        });

        if (suburbs.length > 0) {
          googletag.pubads().setTargeting('suburb2', suburbs);

          if (Rev.EnableDebugOutput && console) {
            console.log('targeting - suburb2 : ' + suburbs);
          }
        }
      }

      // keywords
      if (searchForm.Keywords) {
        var arr = searchForm.Keywords.split(',');
        var keywordsArray = arr.map(function (s) {
          return s.trim();
        });
        if (keywordsArray && keywordsArray.length > 0) {
          googletag.pubads().setTargeting('keywords', keywordsArray);

          if (Rev.EnableDebugOutput && console) {
            console.log('targeting - keywords : ' + keywordsArray);
          }
        }
      }

      // property type
      if (searchForm.PropertyTypes && searchForm.PropertyTypes.length > 0) {
        var selectedTypesObj = _.filter(searchForm.PropertyTypes, function (pt) {
          return pt.Selected;
        });
        var selectedTypes = _.pluck(selectedTypesObj, 'Text');
        if (selectedTypes && selectedTypes.length > 0) {
          googletag.pubads().setTargeting('type', selectedTypes);

          if (Rev.EnableDebugOutput && console) {
            console.log('targeting - type : ' + selectedTypes);
          }
        }
      }

      // sale min price
      if (searchForm.SearchMenuType === 0 && searchForm.SalePrice.MinValue) {
        googletag.pubads().setTargeting('minprice', searchForm.SalePrice.MinValue);

        if (Rev.EnableDebugOutput && console) {
          console.log('targeting - minprice : ' + searchForm.SalePrice.MinValue);
        }
      }

      // sale max price
      if (searchForm.SearchMenuType === 0 && searchForm.SalePrice.MaxValue) {
        googletag.pubads().setTargeting('maxprice', searchForm.SalePrice.MaxValue);

        if (Rev.EnableDebugOutput && console) {
          console.log('targeting - maxprice : ' + searchForm.SalePrice.MaxValue);
        }
      }

      // lease min price
      if (searchForm.SearchMenuType === 1 && searchForm.LeasePrice.MinValue) {
        googletag.pubads().setTargeting('minprice', searchForm.LeasePrice.MinValue);

        if (Rev.EnableDebugOutput && console) {
          console.log('targeting - minprice : ' + searchForm.LeasePrice.MinValue);
        }
      }

      // lease max price
      if (searchForm.SearchMenuType === 1 && searchForm.LeasePrice.MaxValue) {
        googletag.pubads().setTargeting('maxprice', searchForm.LeasePrice.MaxValue);

        if (Rev.EnableDebugOutput && console) {
          console.log('targeting - maxprice : ' + searchForm.LeasePrice.MaxValue);
        }
      }

      // min beds
      if (searchForm.Bedrooms && searchForm.Bedrooms.MinValue) {
        googletag.pubads().setTargeting('minbeds', searchForm.Bedrooms.MinValue);

        if (Rev.EnableDebugOutput && console) {
          console.log('targeting - minbeds : ' + searchForm.Bedrooms.MinValue);
        }
      }

      // max beds
      if (searchForm.Bedrooms && searchForm.Bedrooms.MaxValue) {
        googletag.pubads().setTargeting('maxbeds', searchForm.Bedrooms.MaxValue);

        if (Rev.EnableDebugOutput && console) {
          console.log('targeting - maxbeds : ' + searchForm.Bedrooms.MaxValue);
        }
      }

      // min bath
      if (searchForm.Bathrooms && searchForm.Bathrooms.MinValue) {
        googletag.pubads().setTargeting('minbath', searchForm.Bathrooms.MinValue);

        if (Rev.EnableDebugOutput && console) {
          console.log('targeting - minbath : ' + searchForm.Bathrooms.MinValue);
        }
      }

      // max bath
      if (searchForm.Bathrooms && searchForm.Bathrooms.MaxValue) {
        googletag.pubads().setTargeting('maxbath', searchForm.Bathrooms.MaxValue);

        if (Rev.EnableDebugOutput && console) {
          console.log('targeting - maxbath : ' + searchForm.Bathrooms.MaxValue);
        }
      }

      // search type
      if (searchForm.SearchMenuType === 0) {
        googletag.pubads().setTargeting('searchtype', 'buy');

        if (Rev.EnableDebugOutput && console) {
          console.log('targeting - searchtype : buy');
        }
      } else if (searchForm.SearchMenuType === 1) {
        googletag.pubads().setTargeting('searchtype', 'rent');

        if (Rev.EnableDebugOutput && console) {
          console.log('targeting - searchtype : rent');
        }
      } else if (searchForm.SearchMenuType === 2) {
        googletag.pubads().setTargeting('searchtype', 'sold');

        if (Rev.EnableDebugOutput && console) {
          console.log('targeting - searchtype : sold');
        }
      }
    });
  };

  // ListingDetails
  Rev.Utils.setTargetingDetailsPage = function (listing) {

    if (!listing) return;

    googletag.cmd.push(function () {

      // suburb
      if (listing.Address && listing.Address.Suburb) {
        googletag.pubads().setTargeting('suburb2', listing.Address.Suburb);

        if (Rev.EnableDebugOutput && console) {
          console.log('targeting - suburbs : ' + listing.Address.Suburb);
        }
      }

      // property type
      if (listing.PropertyTypes) {
        googletag.pubads().setTargeting('type', listing.PropertyTypes);

        if (Rev.EnableDebugOutput && console) {
          console.log('targeting - property types : ' + listing.PropertyTypes);
        }
      }

      // search type
      if (listing.Status && listing.Status.ContractType === 0) {
        googletag.pubads().setTargeting('searchtype', 'buy');

        if (Rev.EnableDebugOutput && console) {
          console.log('targeting - search type : buy');
        }
      } else if (listing.Status && listing.Status.ContractType === 1) {
        googletag.pubads().setTargeting('searchtype', 'rent');

        if (Rev.EnableDebugOutput && console) {
          console.log('targeting - search type : rent');
        }
      } else if (listing.Status && listing.Status.ContractType === 2) {
        googletag.pubads().setTargeting('searchtype', 'sold');

        if (Rev.EnableDebugOutput && console) {
          console.log('targeting - search type : sold');
        }
      }

      // bedrooms
      if (listing.NumBedrooms) {
        googletag.pubads().setTargeting('bedrooms', listing.NumBedrooms);

        if (Rev.EnableDebugOutput && console) {
          console.log('targeting - bedrooms : ' + listing.NumBedrooms);
        }
      }

      // bathrooms
      if (listing.NumBathrooms) {
        googletag.pubads().setTargeting('bathrooms', listing.NumBathrooms);

        if (Rev.EnableDebugOutput && console) {
          console.log('targeting - bathrooms : ' + listing.NumBathrooms);
        }
      }

      // price
      if (listing.Price.Price) {
        googletag.pubads().setTargeting('price', listing.Price.Price);

        if (Rev.EnableDebugOutput && console) {
          console.log('targeting - price : ' + listing.Price.Price);
        }
      }
    });
  };
})(Rev, jQuery, _);
'use strict';

(function (Rev, $) {

    'use strict';

    Rev.Utils.icsFile = {
        icsFileDownloading: function icsFileDownloading(model, index) {
            var addressText = '';
            var startDate = '';
            var endDate = '';
            var title = '';
            var location = '';
            var descriptionTitle = '';
            var descriptionchange = '';
            var uid = Rev.Utils.icsFile.uuidv4();
            if (index != undefined) {
                addressText = (model.attributes.AddressText !== undefined ? model.attributes.AddressText : model.attributes.Address.AddressText) + ' - Inspection';
                startDate = new Date(+model.attributes.InspectionData[index].StartDate.replace(/\D/g, ''));
                endDate = new Date(+model.attributes.InspectionData[index].EndDate.replace(/\D/g, ''));
                title = (model.attributes.AddressText !== undefined ? model.attributes.AddressText : model.attributes.Address.AddressText).split(',')[0].replace(/ /g, "-") + '_' + index + '_Inspection';
                descriptionTitle = 'Open for Inspection';
            } else {
                addressText = (model.attributes.AddressText !== undefined ? model.attributes.AddressText : model.attributes.Address.AddressText) + ' - Auction';
                startDate = new Date(+model.attributes.AuctionData.AuctionDate.replace(/\D/g, ''));
                endDate = new Date(startDate.getTime() + 60 * 60000);
                title = (model.attributes.AddressText !== undefined ? model.attributes.AddressText : model.attributes.Address.AddressText).split(',')[0].replace(/ /g, "-") + '_Auction';
                descriptionTitle = 'Auction';
            }

            var description = descriptionTitle + " Time\\n" + (model.attributes.AddressText !== undefined ? model.attributes.AddressText : model.attributes.Address.AddressText) + "\\nProperty Type: " + model.get('PropertyTypes') + "\, Beds: " + parseInt(model.get('NumBedrooms')) + "\, Baths:" + parseInt(model.get('NumBathrooms')) + "\, Car Spaces: " + parseInt(model.get('TotalParking')) + "\\n\\nView details: " + window.location.href;
            cal_single = ics();
            cal_single.addEvent(addressText, description, location, startDate, endDate, uid);
            cal_single.download(title);
        },
        uuidv4: function uuidv4() {
            return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
                var r = Math.random() * 16 | 0,
                    v = c == 'x' ? r : r & 0x3 | 0x8;
                return v.toString(16);
            });
        }
    };
})(Rev, jQuery);
'use strict';

// dependencies : Rev, jquery, slick.js

(function (Rev, $, _) {

  'use strict';

  Rev.Utils.initSlick = function ($el, options) {
    var defautOptions = {
      centerMode: true,
      centerPadding: '15px',
      slidesToShow: 1,
      speed: 300,
      infinite: true,
      cssEase: 'ease',
      lazyLoad: 'progressive',
      touchThreshold: 25,
      arrows: false
    };

    var options = _.extend(defautOptions, options);

    return $el.slick(options);
  };
})(Rev, jQuery, _);
"use strict";

// dependencies : Rev, jquery

(function (Rev, $) {

    'use strict';

    Rev.Utils.isElementCloseVisibleArea = function (el, bottomBuffer) {

        var bottomBuffer = bottomBuffer || 0;

        if (typeof jQuery === "function" && el instanceof jQuery) {
            el = el[0];
        }

        var rect = el.getBoundingClientRect();

        var windowHeight = $(window).height();
        var top = 0 - windowHeight * 1;
        var bottom = windowHeight * 4;

        //console.log(rect.top, rect.bottom, windowHeight);

        return {
            isClose: rect.top >= top && rect.bottom <= bottom,
            isIn: rect.top >= 0 && rect.bottom <= windowHeight,
            isPartialyIn: rect.top >= 0 && rect.top <= windowHeight || rect.bottom >= bottomBuffer && rect.bottom <= windowHeight
        };

        //return (
        //    rect.top >= top &&
        //    rect.bottom <= bottom
        //);

        //return (
        //    rect.top >= 0 &&
        //    rect.left >= 0 &&
        //    rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) && /*or $(window).height() */
        //    rect.right <= (window.innerWidth || document.documentElement.clientWidth) /*or $(window).width() */
        //);
    };
})(Rev, jQuery);
'use strict';

// dependencies : Rev

(function (Rev) {

  'use strict';

  Rev.Utils.isFirefox = function () {
    return !!navigator.userAgent.match(/firefox/i);
  };
})(Rev);
'use strict';

// dependencies : Rev

(function (Rev) {

  'use strict';

  Rev.Utils.isiPad = function () {
    var isiPad = navigator.userAgent.match(/iPad/i) != null;

    return isiPad;
  };
})(Rev);
'use strict';

// dependencies : Rev, jquery

(function (Rev, $) {

	'use strict';

	Rev.Utils.LeadTracking = {
		sendPhotoEvent: function sendPhotoEvent(listingId) {
			if (!listingId) return;

			$.post('/leadevent/photo/', { listingId: listingId }).done(function () {
				if (Rev.EnableDebugOutput && console) {
					console.log('lead tracking event fired : photo - listing id is ' + listingId);
				}
			});
		},

		sendPhoneEvent: function sendPhoneEvent(listingId) {
			if (!listingId) return;

			$.post('/leadevent/phone/', { listingId: listingId }).done(function () {
				if (Rev.EnableDebugOutput && console) {
					console.log('lead tracking event fired : phone - listing id is ' + listingId);
				}
			});
		},

		sendShortlistEvent: function sendShortlistEvent(listingId) {
			if (!listingId) return;

			$.post('/leadevent/shortlist/', { listingId: listingId }).done(function () {
				if (Rev.EnableDebugOutput && console) {
					console.log('lead tracking event fired : shortlist - listing id is ' + listingId);
				}
			});
		},

		sendPhoneAgencyEvent: function sendPhoneAgencyEvent(agencyId) {
			if (!agencyId) return;

			$.post('/leadevent/phone/agency/', { agencyId: agencyId }).done(function () {
				if (Rev.EnableDebugOutput && console) {
					console.log('lead tracking event fired : agency phone - agency id is ' + agencyId);
				}
			});
		},

		sendTopSpotClickEvent: function sendTopSpotClickEvent(listingId, topSpotId) {
			if (!listingId || !topSpotId) return;

			$.post('/leadevent/topspot/click/', { listingId: listingId, topSpotId: topSpotId }).done(function () {
				if (Rev.EnableDebugOutput && console) {
					console.log('topsopt lead tracking event fired : topspot click - listingId is ' + listingId + ' and topSpotId is ' + topSpotId);
				}
			});
		},

		sendTopSpotEmailEvent: function sendTopSpotEmailEvent(listingId, topSpotId) {
			if (!listingId || !topSpotId) return;

			$.post('/leadevent/topspot/email/', { listingId: listingId, topSpotId: topSpotId }).done(function () {
				if (Rev.EnableDebugOutput && console) {
					console.log('topsopt lead tracking event fired : email - listingId is ' + listingId + ' and topSpotId is ' + topSpotId);
				}
			});
		},

		sendTopSpotImpressionEvent: function sendTopSpotImpressionEvent(listingId, topSpotId) {
			if (!listingId || !topSpotId) return;

			$.post('/leadevent/topspot/impression/', { listingId: listingId, topSpotId: topSpotId }).done(function () {
				if (Rev.EnableDebugOutput && console) {
					console.log('topsopt lead tracking event fired : impression - listingId is ' + listingId + ' and topSpotId is ' + topSpotId);
				}
			});
		},

		sendTopSpotPhoneEvent: function sendTopSpotPhoneEvent(listingId, topSpotId) {
			if (!listingId || !topSpotId) return;

			$.post('/leadevent/topspot/phone/', { listingId: listingId, topSpotId: topSpotId }).done(function () {
				if (Rev.EnableDebugOutput && console) {
					console.log('topsopt lead tracking event fired : phone - listingId is ' + listingId + ' and topSpotId is ' + topSpotId);
				}
			});
		}
	};
})(Rev, jQuery);
"use strict";

// dependencies : Rev, jquery

(function (Rev, $) {

  'use strict';

  // include custom infobox javascript library

  var insertInfoboxScript = function insertInfoboxScript() {
    var s = document.createElement("script");
    s.type = "text/javascript";
    s.src = "/assets/vendor/google-map-infobox/infobox.js";
    $("head").append(s);
  };

  if (!window.googleMapApiLoaded) {
    window.googleMapApiLoadedCallback = function () {
      //console.log('google map api is loaded');
      Rev.isGoogleMapLoaded = true;

      insertInfoboxScript();

      if (Rev.currentCallbackForGoogleMap) {
        Rev.currentCallbackForGoogleMap();
        setTimeout(function () {
          return Rev.currentCallbackForGoogleMap = null;
        }, 300);
      }
    };
  }

  var googleMapPathAsync = '//maps.googleapis.com/maps/api/js?client=gme-realestateviewcomau&sensor=false&v=3&async=2&callback=googleMapApiLoadedCallback&libraries=places';
  var googleMapPath = '//maps.googleapis.com/maps/api/js?client=gme-realestateviewcomau&sensor=false&v=3&libraries=places';

  Rev.Utils.loadGoogleMapApi = function (callback) {
    if (!Rev.isGoogleMapLoaded) {
      Rev.currentCallbackForGoogleMap = callback;
      $.getScript(googleMapPathAsync, function () {});
    } else {
      if (callback) callback();
    }
  };

  // load google map api synchnosly
  var triedLoadingGoogleMap = false;

  Rev.Utils.loadGoogleMapApiSync = function (callback) {
    if (!triedLoadingGoogleMap) {
      triedLoadingGoogleMap = true;
      $.getScript(googleMapPath, function () {
        insertInfoboxScript();
        Rev.isGoogleMapLoaded = true;
        callback();
      });
    } else {
      var handler = setInterval(function () {
        if (Rev.isGoogleMapLoaded) {
          callback();
          clearInterval(handler);
        }
      }, 500);
    }
  };
})(Rev, jQuery);
'use strict';

// dependencies : Rev

(function (Rev, $, _) {

  'use strict';

  Rev.Utils.Loader = {
    loadTemplate: function loadTemplate() {
      var templateId;

      if (Rev.IsPhone) {
        templateId = '#template-rev-loader-phone';
      } else if (Rev.IsiPad) {
        templateId = '#template-rev-loader-ipad';
      } else {
        templateId = '#template-rev-loader';
      }

      var template = _.template($(templateId).html());
      var html = template({});
      $('body').append(html);
    },
    show: function show() {
      $('#rev-loader').addClass('show');
    },
    hide: function hide() {
      $('#rev-loader').removeClass('show');
    }
  };
})(Rev, jQuery, _);
'use strict';

(function (Rev, $) {

  'use strict';
  /**
   * Decimal adjustment of a number.
   *
   * @param {String}  type  The type of adjustment.
   * @param {Number}  value The number.
   * @param {Integer} exp   The exponent (the 10 logarithm of the adjustment base).
   * @returns {Number} The adjusted value.
   */

  function decimalAdjust(type, value, exp) {
    // If the exp is undefined or zero...
    if (typeof exp === 'undefined' || +exp === 0) {
      return Math[type](value);
    }
    value = +value;
    exp = +exp;
    // If the value is not a number or the exp is not an integer...
    if (isNaN(value) || !(typeof exp === 'number' && exp % 1 === 0)) {
      return NaN;
    }
    // Shift
    value = value.toString().split('e');
    value = Math[type](+(value[0] + 'e' + (value[1] ? +value[1] - exp : -exp)));
    // Shift back
    value = value.toString().split('e');
    return +(value[0] + 'e' + (value[1] ? +value[1] + exp : exp));
  }

  // Decimal round
  if (!Math.round10) {
    Math.round10 = function (value, exp) {
      return decimalAdjust('round', value, exp);
    };
  }
  // Decimal floor
  if (!Math.floor10) {
    Math.floor10 = function (value, exp) {
      return decimalAdjust('floor', value, exp);
    };
  }
  // Decimal ceil
  if (!Math.ceil10) {
    Math.ceil10 = function (value, exp) {
      return decimalAdjust('ceil', value, exp);
    };
  }
})(Rev, jQuery);
'use strict';

// dependencies : Rev, jquery

(function (Rev, $) {

    'use strict';

    var sendListingDetailsEvent = function sendListingDetailsEvent(model, category, action, name, value, agentId) {
        var md = new MobileDetect(window.navigator.userAgent);

        if (typeof name === "undefined" || name === null) name = '';

        if (typeof value === "undefined" || value === null) value = 0.0;

        if (model.get('Tier') === 10) model.set('Tier', "Premium");else if (model.get('Tier') === 20) model.set('Tier', "Featured");else if (model.get('Tier') === 30) model.set('Tier', "Standard");else if (model.get('Tier') === 40) model.set('Tier', "Freemium");

        var obj = {};
        obj.dimension1 = model.get('Id');
        obj.dimension2 = model.get('ListingCategoryType');
        obj.dimension3 = model.get('Tier');
        obj.dimension4 = model.get('AgencyId');
        if (typeof agentId !== "undefined") obj.dimension5 = agentId;else if (model.attributes.Agents[0].Id != null && model.attributes.Agents[0].Id != undefined) obj.dimension5 = model.attributes.Agents[0].Id;
        obj.dimension6 = model.get('State');
        obj.dimension7 = model.get('City');
        obj.dimension8 = model.get('Region');
        obj.dimension9 = model.get('Suburb');
        obj.dimension10 = md.phone() !== null ? "Mobile" : md.tablet() !== null ? "Tablet" : "Desktop";
        obj.dimension11 = model.get('NumBedrooms');
        obj.dimension12 = model.get('NumBathrooms');
        obj.dimension13 = model.get('TotalParking');
        obj.dimension14 = model.get('PropertyTypes');
        _paq.push(['trackEvent', category, action, name, value, obj]);

        if (Rev.EnableDebugOutput && console) {
            var string = "Matomo tracking event - " + category + " " + action;
            if (name !== '') string += " " + name;
            if (typeof agentId !== "undefined") string += " agent id " + agentId;
            console.log(string);
        }
    };

    var sendSearchResultsEvent = function sendSearchResultsEvent(model, category, action, name, value, agentId) {
        var md = new MobileDetect(window.navigator.userAgent);

        if (typeof name === "undefined" || name === null) name = '';

        if (typeof value === "undefined" || value === null) value = 0.0;

        if (model.get('Tier') === 10) model.set('Tier', "Premium");else if (model.get('Tier') === 20) model.set('Tier', "Featured");else if (model.get('Tier') === 30) model.set('Tier', "Standard");else if (model.get('Tier') === 40) model.set('Tier', "Freemium");

        var agency = typeof model.get('Agencies') !== "undefined" ? model.get('Agencies')[0] : null;
        var agent = agency !== null && agency.Agents !== null ? agency.Agents[0] : null;
        var address = model.get('Address');
        var listingCategory = 'Buy';
        if (model.get('ListingEnquiryForm').ListingCategory === 1) listingCategory = 'Rent';else if (model.get('ListingEnquiryForm').ListingCategory === 2) listingCategory = 'Sold';

        var obj = {};
        obj.dimension1 = model.get('Id');
        obj.dimension2 = listingCategory;
        obj.dimension3 = model.get('Tier');
        obj.dimension4 = agency.Id;
        if (typeof agentId !== "undefined") obj.dimension5 = agentId;else if (agent !== null && agent.Id != null && agent.Id != undefined) obj.dimension5 = agent.Id;
        obj.dimension6 = address.State;
        obj.dimension7 = address.City;
        obj.dimension8 = address.Region;
        obj.dimension9 = address.Suburb;
        obj.dimension10 = md.phone() !== null ? "Mobile" : md.tablet() !== null ? "Tablet" : "Desktop";
        obj.dimension11 = model.get('NumBedrooms');
        obj.dimension12 = model.get('NumBathrooms');
        obj.dimension13 = model.get('TotalParking');
        obj.dimension14 = model.get('PropertyTypes');
        _paq.push(['trackEvent', category, action, name, value, obj]);

        if (Rev.EnableDebugOutput && console) {
            var string = "Matomo tracking event - " + category + " " + action;
            if (name !== '') string += " " + name;
            if (typeof agentId !== "undefined") string += " agent id " + agentId;
            console.log(string);
        }
    };

    Rev.Utils.MatomoTracking = {

        sendEvent: function sendEvent(model, category, action, name, value, agentId) {
            if (model.has('ListingEnquiryForm')) {
                sendSearchResultsEvent(model, category, action, name, value, agentId);
            } else {
                sendListingDetailsEvent(model, category, action, name, value, agentId);
            }
        },

        Category: {
            ListingLeads: 'ListingLeads'
        },

        Action: {
            SearchResults: 'SearchResults',
            SearchResultsCarousel: 'SearchResultsCarousel',
            SearchResultsPhotoView: 'SearchResultsPhotoView',
            MapReveal: 'MapReveal',
            PhotoGallery: 'OpenPhotoGallery',
            ListingGalleryCarousel: 'ListingGalleryCarousel',
            PropertyDetailsCarousel: 'PropertyDetailsCarousel',
            FloorPlan: 'ViewFloorPlan',
            Map: 'ViewMap',
            Video: 'ViewVideo',
            VirtualTour: 'ViewVirtualTour',
            SaveShortlist: 'SaveShortlist',
            PrintBrochure: 'PrintBrochure',
            EmailAgent: 'EmailAgent',
            Share: 'Share',
            PhoneReveal: 'PhoneReveal',
            CallAgent: 'CallAgent',
            SMSAgent: 'SMSAgent',
            AgentProfile: 'ViewAgentProfile',
            AgencyProfile: 'ViewAgencyProfile',
            InspectionTimeSave: 'InspectionTimeSave',
            AuctionTimeSave: 'AuctionTimeSave',
            StatementOfInformation: 'ViewStatementOfInformation'
        },

        Name: {
            Email: 'Email',
            Facebook: 'Facebook',
            Twitter: 'Twitter'
        }
    };
})(Rev, jQuery);
'use strict';

// dependencies : Rev, jquery

(function (Rev, $) {

  'use strict';

  Rev.Utils.openSearchForm = function () {
    if ($('.result-page.search-result-page').is(':visible')) {
      // result page is shown, toggle refine search form 
      $('#layout-body').removeClass('no-show');
      Rev.trigger('refine-search:toggle');
    } else {
      // result page is hidden or no exist, toggle new search form 
      Rev.trigger('new-search:toggle');
    }
  };
})(Rev, jQuery);
'use strict';

// dependencies : Rev, jquery

(function (Rev, $) {

  'use strict';

  Rev.Utils.parseUrl = function (urlString) {
    var queryDict = {};

    if (!urlString) return queryDict;

    urlString = urlString.substring(urlString.indexOf('?') + 1);

    urlString.split("&").forEach(function (item) {
      queryDict[item.split("=")[0]] = item.split("=")[1];
    });

    return queryDict;
  };

  Rev.Utils.parseHash = function (urlString) {
    var queryDict = {};

    if (!urlString) return queryDict;

    urlString = urlString.substring(urlString.indexOf('?') + 1);

    if (urlString.substr(0, 1) === '#') {
      urlString = urlString.substr(1);
    }

    urlString.split("&").forEach(function (item) {
      queryDict[item.split("=")[0]] = item.split("=")[1];
    });

    return queryDict;
  };
})(Rev, jQuery);
'use strict';

// dependencies : Rev, jquery, slick.js

(function (Rev, $, _) {

  'use strict';

  Rev.Utils.PopupWindow = function (url, title, w, h) {
    var w = w || '473';
    var h = h || '258';
    var left, top, newWindow, dualScreenLeft, dualScreenTop;
    var win = window;

    dualScreenLeft = window.screenLeft != undefined ? window.screenLeft : screen.left;
    dualScreenTop = window.screenTop != undefined ? window.screenTop : screen.top;
    left = screen.width / 2 - w / 2 + dualScreenLeft;
    top = screen.height / 2 - h / 2 + dualScreenTop;
    newWindow = window.open(url, title, 'scrollbars=yes, width=' + w + ', height=' + h + ', top=' + top + ', left=' + left);

    if (newWindow == null || typeof newWindow == 'undefined') {
      alert('Please, turn off your pop-up blocker for the realestateVIEW.com.au');
    }

    if (window.focus) {
      newWindow.focus();
    }
  };
})(Rev, jQuery, _);
'use strict';

/* Dependencies : jquery-cookie, underscore
 */

(function (Rev, _, $) {

  'use strict';

  Rev.Utils.recentHistoryCookie = {
    maxRecentHistoryId: 5,

    expires: 1 * 10 * 3, // 30 days

    keyName: 'RecentIds',

    isExist: function isExist(listingId) {
      var ids = $.cookie(this.keyName);
      return _.indexOf(ids, listingId) > -1 ? true : false;
    },

    getRecentIds: function getRecentIds() {
      var recentIds = $.cookie(this.keyName);

      recentIds = _.uniq(recentIds);

      if (recentIds && _.isArray(recentIds) && recentIds.length > this.maxRecentHistoryId) {
        recentIds.splice(this.maxRecentHistoryId);
      }

      $.cookie(this.keyName, recentIds, { expires: this.expires, path: '/' });

      return recentIds || [];
    },

    saveRecentHistory: function saveRecentHistory(listingId) {
      var listingIds = this.getRecentIds() || [];

      if (_.indexOf(listingIds, listingId) > -1) {
        // if exist, exit
        return;
      }

      listingIds = _.uniq(listingIds);

      if (listingIds && listingIds.length > this.maxRecentHistoryId) {
        listingIds.splice(this.maxRecentHistoryId);
      }

      if (listingIds && listingIds.length == this.maxRecentHistoryId) {
        listingIds.shift();
      }

      if (_.indexOf(listingIds, listingId) < 0) {
        listingIds.push(listingId);
      }

      $.cookie(this.keyName, listingIds, { expires: this.expires, path: '/' });
      Rev.trigger('change:recentHistory', listingIds);
    }

  };
})(Rev, _, jQuery);
'use strict';

// dependencies : Rev

(function (Rev) {

  'use strict';

  Rev.Utils.removeHash = function () {
    // don't want to save url in browser entry. if you want to save it use pushState
    history.replaceState({}, document.title, window.location.pathname + window.location.search);
    //location.replace(window.location.pathname + window.location.search);
    //$(window).trigger('hashchange', {test:'test'});
  };
})(Rev);
'use strict';

// dependencies : Rev, jquery

(function (Rev, $) {

  'use strict';

  Rev.Utils.saveAuctionAlert = function (loginSuccessCallback, signupSuccessCallback, closeWindowCallback, callbackIfAlreadyAuthenticated) {

    // check if user is authenticated
    $.get('/authenticated/').done(function (result) {
      if (result && !result.isAuthenticated) {

        setTimeout(function () {
          if (Rev.IsPhone) {
            Rev.trigger('sidebar:toggle', {
              loginSuccessCallback: loginSuccessCallback,
              signupSuccessCallback: signupSuccessCallback,
              closeWindowCallback: closeWindowCallback
            });
            Rev.trigger('login:toggle');
          } else {
            Rev.Utils.showAuthModal('login', null, null, null, loginSuccessCallback, signupSuccessCallback, closeWindowCallback);
          }
        }, 100);
      } else {

        if (callbackIfAlreadyAuthenticated) {
          callbackIfAlreadyAuthenticated();
        }
      }
    });
  };
})(Rev, jQuery);
'use strict';

// dependencies : Rev, jquery

(function (Rev, $) {

  'use strict';

  Rev.Utils.saveSearch = function ($searchForm, callback) {
    $.getJSON('/authenticated/').done(function (result) {
      if (!result.isAuthenticated) {
        Rev.Utils.showAuthModal('login', null, true);
        callback();
      } else {
        $.post('/saved-searches/create/', $searchForm.serialize()).done(function (result) {
          if (result.status === 201) {
            Rev.Utils.showSuccessMessage('Search saved');
            Rev.trigger('change:saved-searches');
          } else {
            if (result.message) {
              Rev.Utils.showErrorMessage(result.message);
            } else {
              Rev.Utils.showErrorMessage('Search not saved');
            }
          }
        }).fail(function (result) {
          Rev.Utils.showErrorMessage('Search not saved');
        }).always(function () {
          callback();
        });
      }
    });
  };

  // for updating saved searchs, don't really need to check if user is authenticated or not
  Rev.Utils.updateSearch = function ($searchForm, callback) {
    $.post('/saved-searches/update/', $searchForm.serialize()).done(function (result) {
      if (result.status === 201) {
        Rev.Utils.showSuccessMessage('Search updated');
        Rev.trigger('change:saved-searches');
      } else {
        if (result.message) {
          Rev.Utils.showErrorMessage(result.message);
        } else {
          Rev.Utils.showErrorMessage('Search not updated');
        }
      }
    }).fail(function (result) {
      Rev.Utils.showErrorMessage('Search not updated');
    }).always(function () {
      callback();
    });
  };
})(Rev, jQuery);
'use strict';

// dependencies : Rev, jquery

(function (Rev, $) {

  'use strict';

  Rev.Utils.showSaveSearchConfirmModal = function () {

    if (Rev.saveSearchConfirmModalView) Rev.saveSearchConfirmModalView.remove();

    var template = _.template($('#template-save-search-confirm-modal').html());
    var html = template();

    $('#rev-modal-placeholder .rev-modal-content-placeholder').html(html);

    setTimeout(function () {
      // show backdrop
      $('#rev-modal-placeholder .rev-modal-backdrop').show();

      // open modal
      $('#rev-modal-placeholder .rev-modal-content-placeholder #save-search-confirm-modal').modal({ backdrop: false });

      // create view instance
      Rev.saveSearchConfirmModalView = new Rev.Views.SaveSearchConfirmModalView({
        el: '#rev-modal-placeholder .rev-modal-content-placeholder #save-search-confirm-modal'
      });
    }, 300);
  };
})(Rev, jQuery);
'use strict';

// dependencies : Rev, jquery

(function (Rev, $) {

  'use strict';

  Rev.Utils.enableScroll = function () {
    $('.refine-search, #layout-body, body').css('overflow-y', ''); // setting auto causes weird ui happening in iPhone : when holding down screen top area becomes gray or top/bottom area disappears
  };

  Rev.Utils.disableScroll = function () {
    $('.refine-search, #layout-body, body').css('overflow-y', 'hidden');
  };
})(Rev, jQuery);
'use strict';

// dependencies : Rev, jquery

(function (Rev, $) {

  'use strict';

  // note that this helper function is only for desktop.
  // for mobile, use following two lines together
  //    Rev.trigger('sidebar:toggle');
  //    Rev.trigger('login:toggle');
  // viewName is one of ['signup', 'login', 'forgotpassword']
  // userData object format is  { email: xxxx, firstName: zzzz }

  Rev.Utils.showAuthModal = function (viewName, isReachMaxShortlist, isTryToSaveSearch, userData, loginSuccessCallback, signupSuccessCallback, closeWindowCallback) {

    Rev.AuthLoginSuccessCallback = null;
    Rev.AuthSignupSuccessCallback = null;
    Rev.AuthCloseWindowCallback = null;

    Rev.AuthLoginSuccessCallback = loginSuccessCallback;
    Rev.AuthSignupSuccessCallback = signupSuccessCallback;
    Rev.AuthCloseWindowCallback = closeWindowCallback;

    if (Rev.authModalView) Rev.authModalView.remove();

    $.getJSON('/auth/modal/json/').done(function (result) {

      $('#rev-modal-placeholder .rev-modal-content-placeholder').html(result.view);

      setTimeout(function () {
        // show backdrop
        $('#rev-modal-placeholder .rev-modal-backdrop').show();

        // open modal
        $('#rev-modal-placeholder .rev-modal-content-placeholder #auth-views-modal').modal({ backdrop: false });

        // create view instance 
        Rev.authModalView = new Rev.Views.AuthModalView({
          el: '#rev-modal-placeholder .rev-modal-content-placeholder #auth-views-modal'
        });

        setTimeout(function () {
          if (viewName === 'signup') Rev.trigger('signup:toggle', { isReachMaxShortlist: isReachMaxShortlist, isTryToSaveSearch: isTryToSaveSearch, userData: userData });else if (viewName === 'login') Rev.trigger('login:toggle', { userData: userData });else if (viewName === 'forgotpassword') Rev.trigger('forgotpassword:toggle');else Rev.trigger('login:toggle', { userData: userData });
        }, 10);
      }, 100);
    });
  };
})(Rev, jQuery);
'use strict';

// dependencies : Rev, jquery

(function (Rev, $) {

  'use strict';

  /*
   * errors : [{Key: "Name", Value:"The name field is required"}, ... ]
   */

  Rev.Utils.showErrors = function (errors, $errorPlaceholder) {
    if (!errors) return;

    // show error message summary
    var template = _.template($('#validaion-errors-summary').html());
    var html = template({ errors: errors });
    $errorPlaceholder.show().html(html);

    // change form field style
    var $form = $errorPlaceholder.closest('form');

    $form.find('input').removeClass('error-form-field');

    _.each(errors, function (error) {
      if (error.Key) {
        $form.find('input[name="' + error.Key + '"]').addClass('error-form-field');
      }
    });
  };

  Rev.Utils.clearErrors = function ($errorPlaceholder) {
    $errorPlaceholder.html('').hide();
    var $form = $errorPlaceholder.closest('form');
    $form.find('input.error-form-field').removeClass('error-form-field');
  };
})(Rev, jQuery);
'use strict';

// dependencies : Rev, jquery

(function (Rev, $) {

      'use strict';

      Rev.Utils.showFloorplanModal = function (imageUrl) {
            // remove viewAlertOptionView if exist
            if (Rev.floorplanModalView) Rev.floorplanModalView.remove();

            // insert view alert option modal html
            var template = _.template($('#template-floorplan-modal').html());
            var html = template({ imgSrc: imageUrl });
            $('#rev-modal-placeholder .rev-modal-content-placeholder').html(html);

            // show backdrop
            $('#rev-modal-placeholder .rev-modal-backdrop').show();

            // open modal
            $('#rev-modal-placeholder .rev-modal-content-placeholder #floorplan-modal').modal({ backdrop: false });

            var heightOfViewableArea = $(window.top).height() - 100;
            var widthOfViewableArea = $(window).width() - 100;

            $('#rev-modal-placeholder #floorplan-modal .modal-dialog').height(heightOfViewableArea).width(widthOfViewableArea);

            // create view instance for view alert options modal
            Rev.floorplanModalView = new Rev.Views.FloorplanModalView({
                  el: '#rev-modal-placeholder .rev-modal-content-placeholder #floorplan-modal'
            });
      };
})(Rev, jQuery);
'use strict';

// dependencies : Rev, jquery

(function (Rev, $) {

	'use strict';

	Rev.Utils.showMapModal = function (lat, long, gaEventCategory) {

		$.post('/map-modal/').done(function (result) {

			$('#rev-modal-placeholder .rev-modal-content-placeholder').html(result);

			// show backdrop
			$('#rev-modal-placeholder .rev-modal-backdrop').show();

			// open modal
			$('#rev-modal-placeholder .rev-modal-content-placeholder #points-of-interest').modal({ backdrop: false });

			Rev.poiView = new Rev.Views.EaiaPropertyPoiView({
				el: '#rev-modal-placeholder .rev-modal-content-placeholder #points-of-interest',
				model: new Rev.Models.Item({
					GeoCoordinates: { Latitude: lat, Longitude: long },
					GaEventCategory: gaEventCategory
				})
			});
		});
	};
})(Rev, jQuery);
'use strict';

// dependencies : Rev, jquery

(function (Rev, $) {

  'use strict';

  Rev.Utils.showPhotoGalleryModal = function (title, photos, thumbnails, floorplans, floorThumbs, gaNavigationTracking, gaCloseTracking, listingCategory, displayAd, listingId, gaEventCategory, agencyName, agencyEmail, agencyId) {
    if (Rev.modalPhotoGalleryView) Rev.modalPhotoGalleryView.remove();

    $.post('/modal-photo-gallery/', {
      title: title,
      photos: photos,
      thumbnails: thumbnails,
      floorplans: floorplans,
      floorThumbs: floorThumbs,
      listingCategory: listingCategory,
      displayAd: displayAd
    }).done(function (result) {

      $('#rev-modal-placeholder .rev-modal-content-placeholder').html(result);

      setTimeout(function () {

        // open modal

        // just comment it - this makes padding-right: 17px to body tag :(
        //$('#rev-modal-placeholder .rev-modal-content-placeholder .full-photo-viewer').modal({ backdrop: false });             

        // create view instance for email agent modal
        Rev.modalPhotoGalleryView = new Rev.Views.ModalPhotoGalleryView({
          el: '#rev-modal-placeholder .rev-modal-content-placeholder .full-photo-viewer',
          model: new Rev.Models.Item({
            Title: title,
            Photos: photos,
            Thumbnails: thumbnails,
            Floorplans: floorplans,
            FloorThumbs: floorThumbs,
            GaNavigationTracking: gaNavigationTracking,
            GaCloseTracking: gaCloseTracking,
            ListingId: listingId,
            GaEventCategory: gaEventCategory,
            AgencyName: agencyName,
            AgencyEmail: agencyEmail,
            AgencyId: agencyId,
            ListingCategory: listingCategory
          })
        });
        if (photos) {
          Rev.modalPhotoGalleryView.openViewAtPhotos();
        }

        if (floorplans) {
          Rev.modalPhotoGalleryView.openViewAtFloorplans();
        }
      }, 300);
    });
  };
})(Rev, jQuery);
'use strict';

// dependencies : Rev, jquery

(function (Rev, $) {

  'use strict';

  // appraisalRequest parameter object includes following properties
  // seoSlug, shortAddress, state, suburb, postcode, fullAddress, sa1, gnafAddressId, isSponsored, sponsorAgencyName, sponsorAgencyLogo, sponsorAgencyFontColor, sponsorAgencyBackgroundColor

  Rev.Utils.showPropertyValuationModal = function (appraisalRequest) {
    if (Rev.eaiaPropertyValuationPopupView) Rev.eaiaPropertyValuationPopupView.remove();

    $.getJSON('/property-360/property-request-valuation/form/', appraisalRequest).done(function (result) {

      $('#eaia-modal-placeholder .eaia-modal-content-placeholder').html(result.view);

      setTimeout(function () {
        // show backdrop
        $('#eaia-modal-placeholder .eaia-modal-backdrop').show();

        // open modal
        $('#eaia-modal-placeholder .eaia-modal-content-placeholder #valuation-request-modal').modal({ backdrop: false });

        // create view instance for email agent modal
        Rev.eaiaPropertyValuationPopupView = new Rev.Views.EaiaPropertyValuationPopupView({
          el: '#eaia-modal-placeholder .eaia-modal-content-placeholder #valuation-request-modal',
          appraisalRequest: appraisalRequest
        });
      }, 300);
    });
  };
})(Rev, jQuery);
'use strict';

// dependencies : Rev, jquery

(function (Rev, $) {

  'use strict';

  Rev.Utils.showShareWithFriendModal = function (listingId, gaCategory) {
    if (Rev.shareWithFriendView) Rev.shareWithFriendView.remove();

    $.getJSON('/share-with-friend/form/json/', { listingId: listingId }).done(function (result) {

      $('#rev-modal-placeholder .rev-modal-content-placeholder').html(result.view);

      setTimeout(function () {
        // show backdrop
        $('#rev-modal-placeholder .rev-modal-backdrop').show();

        // open modal
        $('#rev-modal-placeholder .rev-modal-content-placeholder #share-with-friend-modal').modal({ backdrop: false });

        // create view instance for email agent modal
        Rev.shareWithFriendView = new Rev.Views.ShareWithFriendView({
          el: '#rev-modal-placeholder .rev-modal-content-placeholder #share-with-friend-modal',
          gaCategory: gaCategory
        });
      }, 300);
    });

    if (gaCategory) {
      Rev.Utils.GaTracking.trackGaEvent(gaCategory, Rev.Utils.GaTracking.Action.ShareViaEmail, Rev.Utils.GaTracking.Label.ShareEmail);
    }
  };
})(Rev, jQuery);
'use strict';

// dependencies : Rev, jquery

(function (Rev, $) {

    'use strict';

    Rev.Utils.showTooManyResultsModal = function (totalItems) {
        // rollback this popup temporarily
        return;

        var maxListings = 2500;

        if (!totalItems || totalItems && parseInt(totalItems, 10) <= maxListings) {
            return;
        }

        // remove view if exist
        if (Rev.tooManyResultsModalView) Rev.tooManyResultsModalView.remove();

        // insert modal html
        var template = _.template($('#template-too-many-results-modal').html());
        var html = template({ totalItems: totalItems.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",") });
        $('#rev-modal-placeholder .rev-modal-content-placeholder').html(html);

        // show backdrop
        $('#rev-modal-placeholder .rev-modal-backdrop').show();

        // open modal
        $('#rev-modal-placeholder .rev-modal-content-placeholder #too-many-results-modal').modal({ backdrop: false });

        // create view instance
        Rev.tooManyResultsModalView = new Rev.Views.TooManyResultsModalView({
            el: '#rev-modal-placeholder .rev-modal-content-placeholder #too-many-results-modal'
        });
    };
})(Rev, jQuery);
'use strict';

// dependencies : Rev, jquery

(function (Rev, $) {

  'use strict';

  Rev.Utils.showViewAlertOptionModal = function () {

    $.getJSON('/authenticated/').done(function (result) {
      if (!result.isAuthenticated) {
        Rev.Utils.showAuthModal('login', null, true);
      } else {
        // remove viewAlertOptionView if exist
        if (Rev.viewAlertOptionView) Rev.viewAlertOptionView.remove();

        // insert view alert option modal html
        var template = _.template($('#template-viewalert-options-modal').html());
        var html = template();
        $('#rev-modal-placeholder .rev-modal-content-placeholder').html(html);

        // show backdrop
        $('#rev-modal-placeholder .rev-modal-backdrop').show();

        // open modal
        $('#rev-modal-placeholder .rev-modal-content-placeholder #viewalert-option-modal').modal({ backdrop: false });

        // create view instance for view alert options modal
        Rev.viewAlertOptionView = new Rev.Views.ViewAlertOptionView({
          el: '#rev-modal-placeholder .rev-modal-content-placeholder #viewalert-option-modal'
        });
      }
    });
  };
})(Rev, jQuery);
'use strict';

// dependencies : Rev, jquery

(function (Rev, $) {

      'use strict';

      Rev.Utils.showYoutubeModal = function (youtubeIFrameUrl) {
            // remove viewAlertOptionView if exist
            if (Rev.youtubeVideoView) Rev.youtubeVideoView.remove();

            // insert view alert option modal html
            var template = _.template($('#template-youtube-video-modal').html());
            var html = template({ youtubeIFrameUrl: youtubeIFrameUrl });
            $('#rev-modal-placeholder .rev-modal-content-placeholder').html(html);

            // show backdrop
            $('#rev-modal-placeholder .rev-modal-backdrop').show();

            // open modal
            $('#rev-modal-placeholder .rev-modal-content-placeholder #youtube-video-modal').modal({ backdrop: false });

            // create view instance for view alert options modal
            Rev.youtubeVideoView = new Rev.Views.YoutubeVideoView({
                  el: '#rev-modal-placeholder .rev-modal-content-placeholder #youtube-video-modal'
            });
      };
})(Rev, jQuery);
'use strict';

// dependencies : Rev, jquery

(function (Rev, $) {

  'use strict';

  Rev.Utils.String = {
    numberWithCommas: function numberWithCommas(str) {
      if (!str) return '';

      return str.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
    }
  };
})(Rev, jQuery);
'use strict';

(function (Rev, Backbone) {

  'use strict';

  Rev.Models.Agency = Backbone.Model.extend({});
})(Rev, Backbone);
'use strict';

(function (Rev, Backbone) {

  'use strict';

  Rev.Models.AgencyDetails = Backbone.Model.extend({});
})(Rev, Backbone);
'use strict';

(function (Rev, Backbone) {

  'use strict';

  Rev.Models.AgencyResultsItem = Backbone.Model.extend({});
})(Rev, Backbone);
'use strict';

(function (Rev, Backbone) {

  'use strict';

  Rev.Models.AgentDetails = Backbone.Model.extend({});
})(Rev, Backbone);
'use strict';

(function (Rev, Backbone) {

  'use strict';

  Rev.Models.ListingEnquiry = Backbone.Model.extend({
    url: '/contact/agency/enquiry'
  });
})(Rev, Backbone);
'use strict';

(function (Rev, Backbone) {

  'use strict';

  Rev.Models.AvmItem = Backbone.Model.extend({});
})(Rev, Backbone);
'use strict';

(function (Rev, Backbone) {

  'use strict';

  Rev.Models.CheckboxItem = Backbone.Model.extend({
    defaults: {
      'Value': '',
      'Text': '',
      'Selected': false
    }
  });
})(Rev, Backbone);
'use strict';

(function (Rev, Backbone) {

  'use strict';

  // this model is just dummy model can be used for any views

  Rev.Models.Item = Backbone.Model.extend({});
})(Rev, Backbone);
'use strict';

(function (Rev, Backbone) {

  'use strict';

  Rev.Models.LatLng = Backbone.Model.extend({});
})(Rev, Backbone);
'use strict';

(function (Rev, Backbone) {

  'use strict';

  Rev.Models.ListDetails = Backbone.Model.extend({});
})(Rev, Backbone);
'use strict';

(function (Rev, Backbone) {

  'use strict';

  Rev.Models.ListResult = Backbone.Model.extend({});
})(Rev, Backbone);
'use strict';

(function (Rev, Backbone) {

  'use strict';

  Rev.Models.ListResultsItem = Backbone.Model.extend({});
})(Rev, Backbone);
'use strict';

(function (Rev, Backbone) {

  'use strict';

  Rev.Models.ListResultsItemHtml = Backbone.Model.extend({
    localStorage: new Backbone.LocalStorage('list-results-html'),

    defaults: {
      'id': '',
      'html': ''
    }
  });
})(Rev, Backbone);
'use strict';

(function (Rev, Backbone) {

  'use strict';

  Rev.Models.ListingBox = Backbone.Model.extend({});
})(Rev, Backbone);
'use strict';

/* Dependencies : Backbone.LocalStorage 
 * Store All the data need to be stored in localStorage
 */

(function (Rev, _, Backbone) {

  'use strict';

  Rev.Models.LocalData = Backbone.Model.extend({
    localStorage: new Backbone.LocalStorage("rev-local-data"),

    //maxShortlist : 5,

    // add more properties here as you need
    defaults: {
      id: 'rev-local-data-id', // should be always the same id, because we only update properties, NO Creating new data.
      moreFilterExpanded: false,
      recentlySearchedLocations: '',
      //recentIds: [], // array of listingId that user viewed
      recentSearches: [], // recently searched form filter, array of ListingSearchForm.cs
      poiTypes: [], // point of interest types
      recentEaiaSearch: [] // eaia search history up to 5
    },

    saveRecentEaiaSearch: function saveRecentEaiaSearch(searchItem) {
      var max = 5;
      this.fetch();
      var recentEaiaSearchItems = this.get('recentEaiaSearch');

      var isExist = _.find(recentEaiaSearchItems, function (item) {
        return item.AddressText === searchItem.AddressText;
      }) ? true : false;

      if (isExist) return;

      var recentEaiaSearch = _.clone(this.get('recentEaiaSearch')); // note that this.get('recentEaiaSearch') and push value in it will not fire change event, solution is to use _.clone()

      // check if items exceed max
      var recentEaiaSearchStartWith = _.filter(recentEaiaSearch, function (item) {
        return item.AddressText.toLowerCase().substr(0, 1) === searchItem.AddressText.toLowerCase().substr(0, 1);
      });
      if (recentEaiaSearchStartWith.length >= max) {
        // remove the first item in recentEaiaSearchStartWith from recentEaiaSearch
        var firstItem = recentEaiaSearchStartWith[0];
        var filtered = _.filter(recentEaiaSearch, function (item) {
          return item.AddressText.toLowerCase() !== firstItem.AddressText.toLowerCase();
        });
        recentEaiaSearch = filtered;
      }

      searchItem.isFromHistory = true;
      recentEaiaSearch.push(searchItem);

      this.save({ recentEaiaSearch: recentEaiaSearch });
    },

    deleteRecentEaiaSearch: function deleteRecentEaiaSearch(searchItem) {
      this.fetch();

      var recentEaiaSearch = _.clone(this.get('recentEaiaSearch'));
      var filtered = _.reject(recentEaiaSearch, function (item) {
        return item.AddressText.toLowerCase() === searchItem.AddressText.toLowerCase() && item.AddressType === searchItem.AddressType && item.SeoSlug === searchItem.SeoSlug;
      });
      this.save({ recentEaiaSearch: filtered });
    },

    saveRecentSearch: function saveRecentSearch(searchForm) {
      var max = 5;
      this.fetch();
      var recentSearches = _.clone(this.get('recentSearches')); // note that this.get('recentSearches') and push value in it will not fire change event, solution is to use _.clone()
      if (recentSearches.length >= max) {
        recentSearches.shift();
      }
      recentSearches.push(searchForm);
      this.save({ recentSearches: recentSearches });
    },

    deleteRecentSearch: function deleteRecentSearch() {
      this.save({ recentSearches: [] });
    },

    defaultPoiTypes: ['store', 'hospital', 'bar', 'cafe', 'university', 'school', 'train_station', 'bus_station', 'park', 'restaurant'],

    savePoiTypes: function savePoiTypes(types) {
      // clear first
      this.save({ poiTypes: [] });

      this.save({ poiTypes: types });
    },

    getPoiTypes: function getPoiTypes() {
      this.fetch();
      var types = this.get('poiTypes');
      if (!types || types && !types.length) {
        this.savePoiTypes(this.defaultPoiTypes);
      }

      this.fetch();
      return this.get('poiTypes');
    }

    //saveRecentId: function (listingId) {
    //  var max = 10;
    //  this.fetch();
    //  var ids = this.get('recentIds');
    //  var isExist = _.indexOf(ids, listingId) > -1 ? true : false;

    //  if (!isExist) {
    //    var listingIds = _.clone(this.get('recentIds')); // note that this.get('recentIds') and push value in it will not fire change event, solution is to use _.clone()
    //    if (listingIds.length >= max) {
    //      listingIds.splice(max); // remove items from max index
    //      listingIds.shift(); // then delete first element
    //    }
    //    listingIds.push(listingId); 
    //    this.save({ recentIds: listingIds });
    //    $.cookie('recentIds', listingIds, { expires: 1 * 7 * 10, path: '/' });
    //  }      
    //}

  });

  // instantiate it here immediately
  Rev.Models.localData = new Rev.Models.LocalData();
})(Rev, _, Backbone);
'use strict';

(function (Rev, Backbone) {

  'use strict';

  Rev.Models.Range = Backbone.Model.extend({
    defaults: {
      'MinValue': '',
      'MaxValue': ''
    }
  });
})(Rev, Backbone);
'use strict';

(function (Rev, Backbone) {

  'use strict';

  Rev.Models.SavedSearchesItem = Backbone.Model.extend({});
})(Rev, Backbone);
'use strict';

(function (Rev, Backbone) {

  'use strict';

  Rev.Models.SearchForm = Backbone.Model.extend({});
})(Rev, Backbone);
'use strict';

(function (Rev, Backbone) {

  'use strict';

  Rev.Collections.AgencyResults = Backbone.Collection.extend({
    model: Rev.Models.AgencyResultsItem
  });
})(Rev, Backbone);
'use strict';

(function (Rev, Backbone) {

  'use strict';

  Rev.Collections.CheckboxItems = Backbone.Collection.extend({
    model: Rev.Models.CheckboxItem
  });
})(Rev, Backbone);
'use strict';

(function (Rev, Backbone) {

  'use strict';
  // this collection is just dummy object can be used for any views

  Rev.Collections.Items = Backbone.Collection.extend({
    model: Rev.Models.Item
  });
})(Rev, Backbone);
'use strict';

(function (Rev, Backbone) {

  'use strict';

  Rev.Collections.LatLngItems = Backbone.Collection.extend({
    model: Rev.Models.LatLng
  });
})(Rev, Backbone);
'use strict';

(function (Rev, Backbone) {

  'use strict';

  Rev.Collections.ListResults = Backbone.Collection.extend({
    model: Rev.Models.ListResultsItem
  });
})(Rev, Backbone);
'use strict';

(function (Rev, Backbone) {

  'use strict';

  Rev.Collections.ListResultsHtml = Backbone.Collection.extend({
    model: Rev.Models.ListResultsItemHtml,

    localStorage: new Backbone.LocalStorage('list-results-html'),

    all: function all() {
      return this.filter(function (m) {
        return true;
      });
    },
    saveItem: function saveItem(id, html) {
      var model = this.get(id);
      if (model) {
        model.destroy();
      } else {
        var model = new Rev.Models.ListResultsItemHtml({ id: id, html: html });
        model.save();
        this.add(model);
      }
    },
    deleteItem: function deleteItem(id) {
      var model = this.get(id);
      if (model) model.destroy();
    }
  });

  // this collection is going to be used in entire app so create instance here immediately
  Rev.Collections.listResultsHtml = new Rev.Collections.ListResultsHtml();
})(Rev, Backbone);
'use strict';

(function (Rev, Backbone) {

  'use strict';

  Rev.Collections.SavedSearches = Backbone.Collection.extend({
    model: Rev.Models.SavedSearchesItem
  });
})(Rev, Backbone);
'use strict';

(function (Rev, $, _, Backbone) {

  'use strict';

  Rev.Views.AdvertMobileView = Backbone.View.extend({
    sitePage: Rev.Config.getOasAdvertSitePage(),

    template: _.template($('#ad-mobile').html()),

    initialize: function initialize() {
      _.bindAll(this, 'onSearchMenuChanged');
      this.listenTo(Rev, 'search:menu:changed', this.onSearchMenuChanged);

      // no need to render banner here, Razor script will render it.
      //this.render();
    },

    onSearchMenuChanged: function onSearchMenuChanged(menu) {
      this.sitePage = Rev.Config.getOasAdvertSitePage(menu);
      this.render();
    },

    render: function render() {
      this.$el.html(this.template({ sitePage: this.sitePage, randomNo: new String(Math.random()).substring(2, 11) }));
    }

  });
})(Rev, jQuery, _, Backbone);
'use strict';

(function (Rev, $, _, Backbone) {

  'use strict';

  Rev.Views.AuthModalView = Backbone.View.extend({
    el: '#auth-views-modal',

    initialize: function initialize() {
      _.bindAll(this, 'toggleLogin', 'toggleSignup', 'toggleForgotPassword', 'resetSubViews');

      this.createSubViews();

      this.listenTo(Rev, 'signup:toggle', this.toggleSignup);
      this.listenTo(Rev, 'forgotpassword:toggle', this.toggleForgotPassword);
      this.listenTo(Rev, 'login:toggle', this.toggleLogin);
    },

    events: {
      'click [data-hook="close-sidebar"]': 'toggleSidebar',
      'click [data-hook="toggle-signup"]': 'toggleSignup',
      'click [data-hook="toggle-login"]': 'toggleLogin',
      'click [data-hook="close"]': 'closeModal'
    },

    createSubViews: function createSubViews() {
      new Rev.Views.ForgotPasswordView();
      new Rev.Views.LoginView();
      new Rev.Views.SignupView();
    },
    closeModal: function closeModal(e) {
      if (e && e.preventDefault) e.preventDefault();
      $('.rev-modal-backdrop').hide();
      this.$el.modal('hide');

      if (Rev.AuthCloseWindowCallback) {
        Rev.AuthCloseWindowCallback();
        Rev.AuthCloseWindowCallback = null;
      }
    },


    toggleSignup: function toggleSignup(e) {
      var _this = this;

      if (e && e.preventDefault) e.preventDefault();
      this.resetSubViews();
      this.$('.signup-body').toggleClass('ready-to-show');

      if (e && e.userData && e.userData.email) {
        $('#signup-form [data-hook="email"]').val(e.userData.email);
      }

      if (e && e.userData && e.userData.firstName) {
        $('#signup-form [data-hook="name"]').val(e.userData.firstName);
      }

      setTimeout(function () {
        _this.$('.signup-body').toggleClass('slide-in');
        if (e && e.isReachMaxShortlist && _this.$('.signup-body').hasClass('slide-in')) {
          _this.$('.signup-body .signup-heart').show();
        }
        if (e && e.isTryToSaveSearch && _this.$('.signup-body').hasClass('slide-in')) {
          _this.$('.signup-body .signup-save-search').show();
        }
      }, 100);
    },

    toggleLogin: function toggleLogin(e) {
      var _this2 = this;

      if (e && e.preventDefault) e.preventDefault();
      this.resetSubViews();
      this.$('.login-body').toggleClass('ready-to-show');

      if (e && e.userData && e.userData.email) {
        $('#login-form [data-hook="email"]').val(e.userData.email);
      }

      setTimeout(function () {
        return _this2.$('.login-body').toggleClass('slide-in');
      }, 100);
    },

    toggleForgotPassword: function toggleForgotPassword(e) {
      var _this3 = this;

      if (e && e.preventDefault) e.preventDefault();
      this.resetSubViews();
      this.$('.forgot-password-body').toggleClass('ready-to-show');
      setTimeout(function () {
        return _this3.$('.forgot-password-body').toggleClass('slide-in');
      }, 100);
    },

    resetSubViews: function resetSubViews() {
      this.$('.account-form').removeClass('ready-to-show slide-in');
    }

  });
})(Rev, jQuery, _, Backbone);
'use strict';

(function (Rev, $, _, Backbone) {

    'use strict';

    Rev.Views.ChoiceHomeLoansView = Backbone.View.extend({

        initialize: function initialize(options) {

            this.options = options || {};

            _.bindAll(this, 'showHomeLoanEnquirySuccessMessage');

            this.homeLoanEnquiryErrorPlaceHolder = this.$('[data-hook="home-loan-validation-errors-placeholder"]');
        },

        events: {
            'click [data-hook="home-loan-reveal"]': 'onHomeloanClick',
            'click [data-hook="btn-home-loan-submit"]': 'makeHomeLoanEnquiry'
        },

        onHomeloanClick: function onHomeloanClick(e) {
            e.preventDefault();
            this.$('.home-loan-reveal').toggleClass('reveal');
        },
        makeHomeLoanEnquiry: function makeHomeLoanEnquiry(e) {
            var _this = this;

            e.preventDefault();

            var $form = this.$('[data-hook="home-loan-enquiry-form"]');
            var url = $form.attr('action');

            $(e.currentTarget).button('loading');

            $.post(url, $form.serialize()).done(function (result) {
                if (result.errors) {
                    Rev.Utils.showErrors(result.errors, _this.homeLoanEnquiryErrorPlaceHolder);
                    if (_this.scrollTop) $('html, body').animate({ scrollTop: _this.scrollTop }, 400);
                } else {
                    _this.showHomeLoanEnquirySuccessMessage();
                }
            }).fail(function (result) {
                Rev.Utils.showErrors(result.errors, _this.homeLoanEnquiryErrorPlaceHolder);
                // scroll up to show error message
                if (_this.scrollTop) $('html, body').animate({ scrollTop: _this.scrollTop }, 400);
            }).always(function () {
                _this.$('[data-hook="btn-home-loan-submit"]').button('reset');
            });
        },
        showHomeLoanEnquirySuccessMessage: function showHomeLoanEnquirySuccessMessage() {
            var firstName = this.$('[data-hook = "home-loan-enquiry-first-name"]').val();
            this.$('[data-hook="home-loan-success-title"]').text('Thanks ' + firstName);

            this.$('.home-loan-form-header').hide();
            this.$('.home-loan-form-body').hide();
            this.$('[data-hook="home-loan-success"]').fadeOut(300).fadeIn(300);
        }
    });
})(Rev, jQuery, _, Backbone);
'use strict';

// dependencies : Rev, jquery, underscore, backbone

(function (Rev, $, _, Backbone) {

	'use strict';

	Rev.Views.EmailAgentSidebarView = Backbone.View.extend({
		initialize: function initialize(options) {
			_.bindAll(this, 'showPostEnquiryConfirmation', 'makeEnquiry');

			//todo: change optoins to take full js model rather than this list of options.
			var options = options || {};

			this.agentEnquiryErrorPlaceHolder = this.$('[data-hook="email-agent-validation-errors-placeholder"]');
			this.postEnquiryAdPlaceHolder = this.$('[data-hook="post-enquiry-ad-validation-errors-placeholder"]');
		},

		events: {
			'click [data-hook="btn-email-agent-sidebar"]': 'makeEnquiry',
			'click [data-hook="btn-post-enquiry-ad-submit"]': 'submitPostEnquiryForm'
		},

		makeEnquiry: function makeEnquiry(e) {
			var _this = this;

			e.preventDefault();
			var self = this;
			var $form = self.$('[data-hook="email-agent-sidebar-form"]');
			var url = $form.attr('action');
			$(e.currentTarget).button('loading');

			$.post(url, $form.serialize()).done(function (result) {
				if (result.errors) {
					Rev.Utils.showErrors(result.errors, self.agentEnquiryErrorPlaceHolder);
					if (self.scrollTop) $('html, body').animate({ scrollTop: self.scrollTop }, 400);
				} else {
					self.showSuccessMessage();

					// WHAT IS THIS???
					if (_this.model.get('Id')) {
						Rev.Utils.Criteo.pushEventAgentContact(_this.model.get('Id'));
					}

					if (_this.model.get('GaEventCategory') && _this.model.get('AgencyName') && _this.model.get('AgencyEmail')) Rev.Utils.GaTracking.trackGaEvent(_this.model.get('GaEventCategory'), Rev.Utils.GaTracking.Action.SendToAgent, _this.model.get('AgencyName') + ' / ' + _this.model.get('AgencyEmail'));

					Rev.Utils.GaTracking.trackEmailAgent(_this.model);

					Rev.Utils.MatomoTracking.sendEvent(_this.model, Rev.Utils.MatomoTracking.Category.ListingLeads, Rev.Utils.MatomoTracking.Action.EmailAgent);
				}
			}).fail(function (result) {
				Rev.Utils.showErrors(result.errors, self.agentEnquiryErrorPlaceHolder);
				if (self.scrollTop) $('html, body').animate({ scrollTop: self.scrollTop }, 400);
			}).always(function () {
				self.$('[data-hook="btn-email-agent-sidebar"]').button('reset');
			});
		},
		submitPostEnquiryForm: function submitPostEnquiryForm(e) {
			var _this2 = this;

			e.preventDefault();

			var $form = this.$('[data-hook="post-enquiry-ad-enquiry-form"]');
			var url = $form.attr('action');

			$(e.currentTarget).button('loading');

			$.post(url, $form.serialize()).done(function (result) {
				if (result.errors) {
					_this2.$el.addClass('errors-choice-homeloan');
					Rev.Utils.showErrors(result.errors, _this2.postEnquiryAdPlaceHolder);
					if (_this2.scrollTop) $('html, body').animate({ scrollTop: _this2.scrollTop }, 400);
				} else {
					_this2.showPostEnquiryConfirmation();
				}
			}).fail(function (result) {
				_this2.$el.addClass('errors-choice-homeloan');
				Rev.Utils.showErrors(result.errors, _this2.postEnquiryAdPlaceHolder);
			}).always(function () {
				_this2.$('[data-hook="btn-post-enquiry-ad-submit"]').button('reset');
			});
		},
		showSuccessMessage: function showSuccessMessage() {
			var _this3 = this;

			var fullName = this.$('[data-hook = "enquiry-name"]').val().split(" ");
			var firstName = fullName[0];
			var lastName = fullName[1];

			// set name, email and phone value to home loan form
			this.$('[data-hook = "post-enquiry-ad-enquiry-first-name"]').val(firstName);
			this.$('[data-hook = "post-enquiry-ad-enquiry-last-name"]').val(lastName);
			this.$('[data-hook = "post-enquiry-ad-enquiry-email"]').val(this.$('[data-hook = "enquiry-email"]').val());
			this.$('[data-hook = "post-enquiry-ad-enquiry-phone"]').val(this.$('[data-hook = "enquiry-phone"]').val());

			var pos = this.$el.offset();
			var buffer = 50;
			$('body').animate({ scrollTop: pos.top - buffer });

			this.$('[data-hook="email-agent-sidebar-form"]').fadeOut(400, function () {
				_this3.$el.addClass('email-agent-success');
				_this3.$('[data-hook="email-agent-success"]').fadeIn(500);
			});
		},
		showPostEnquiryConfirmation: function showPostEnquiryConfirmation() {
			var _this4 = this;

			var fullName = this.$('[data-hook = "enquiry-name"]').val();
			this.$('[data-hook="post-enquiry-ad-success-title"]').text('Thanks ' + fullName);

			$('html, body').animate({ scrollTop: this.$el.offset().top - $('#layout-header').height() }, function () {
				_this4.$('[data-hook="email-agent-success"]').slideUp({ duration: 400, easing: 'linear' });
				_this4.$('[data-hook="post-enquiry-ad-success"]').fadeOut(300).fadeIn(300);
			});
		},
		hideSuccessaMessage: function hideSuccessaMessage() {
			this.$('[data-hook="email-agent-sidebar-form"]').show();
			this.$('[data-hook="email-agent-success"]').hide();
		}
	});
})(Rev, jQuery, _, Backbone);
'use strict';

// dependencies : Rev, jquery, underscore, backbone

(function (Rev, $, _, Backbone) {

    'use strict';

    Rev.Views.EmailAgentView = Backbone.View.extend({
        initialize: function initialize(options) {
            _.bindAll(this, 'showView', 'closeView', 'showPostEnquiryConfirmation', 'makeEnquiry');

            var options = options || {};
            this.model = options.model;
            this.gaCategory = options.gaCategory;
            this.gaAgencyName = options.gaAgencyName;
            this.gaAgencyEmail = options.gaAgencyEmail;
            this.topSpotId = options.topSpotId;
            this.listingId = options.listingId;
            this.agencyId = options.agencyId;

            this.agentEnquiryErrorPlaceHolder = this.$('[data-hook="email-agent-validation-errors-placeholder"]');
            this.postEnquiryAdPlaceHolder = this.$('[data-hook="post-enquiry-ad-validation-errors-placeholder"]');
        },

        events: {
            'click [data-hook="agent-phone-number"]': 'onPhoneAgencyClick',
            'click [data-hook="input-comments-label"]': 'showCommentsBox',
            'click [data-hook="close"]': 'closeView',
            'click [data-hook="btn-email-agent"]': 'makeEnquiry',
            'click [data-hook="btn-post-enquiry-ad-submit"]': 'submitPostEnquiryForm',
            'hidden.bs.modal': 'onModalHidden'
        },

        onPhoneAgencyClick: function onPhoneAgencyClick(e) {
            var $phoneWrapper = this.$(e.currentTarget).closest('.agent-number');
            // simply call the agent if already showen
            //if (!$phoneWrapper.hasClass('truncate')) {
            //    return;
            //}
            e.preventDefault();
            //$phoneWrapper.toggleClass('truncate');

            var phone = $phoneWrapper.attr('data-agent-phone');
            $phoneWrapper.find('a').text(phone);

            var agentId = $phoneWrapper.attr('data-agent-id');

            // fire ga event & lead event
            Rev.Utils.LeadTracking.sendPhoneEvent(this.listingId);

            Rev.Utils.GaTracking.trackGaEvent(this.gaCategory, Rev.Utils.GaTracking.Action.PhoneAgent, this.gaAgencyName + ' / ' + this.agencyId);

            Rev.Utils.GaTracking.trackPhoneAgent(this.model);

            Rev.Utils.Criteo.pushEventAgentContact(this.listingId);

            Rev.Utils.MatomoTracking.sendEvent(this.model, Rev.Utils.MatomoTracking.Category.ListingLeads, Rev.Utils.MatomoTracking.Action.PhoneReveal, null, null, agentId);
        },
        showView: function showView() {
            this.$el.modal('show');
        },
        onModalHidden: function onModalHidden(e) {
            $('body, .list-result-items').removeClass('modal-open');
        },
        closeView: function closeView(e) {
            if (e && e.preventDefault) e.preventDefault();

            $('.rev-modal-backdrop').hide();
            this.$el.modal('hide');

            // ensure removing modal-open class, sometimes onModalHidden is not fired
            $('body, .list-result-items').removeClass('modal-open');
        },
        remove: function remove() {
            this.closeView();
            this.off();
            Backbone.View.prototype.remove.apply(this, arguments); //call the superclass remove method
        },
        makeEnquiry: function makeEnquiry(e) {
            var _this = this;

            e.preventDefault();

            var self = this;

            var $form = self.$('[data-hook="email-agent-form"]');
            var url = $form.attr('action');

            $(e.currentTarget).button('loading');

            $.post(url, $form.serialize()).done(function (result) {
                if (result.errors) {
                    Rev.Utils.showErrors(result.errors, self.agentEnquiryErrorPlaceHolder);
                    if (self.scrollTop) $('html, body').animate({ scrollTop: self.scrollTop }, 400);
                } else {
                    self.showSuccessMessage();

                    // NOTE that general email lead event will be fired in AgentEnquiryController.Enquiry method

                    // trigger topspot email lead event
                    if (self.listingId && self.topSpotId) {
                        Rev.Utils.LeadTracking.sendTopSpotEmailEvent(self.listingId, self.topSpotId);
                    }

                    if (self.listingId) {
                        Rev.Utils.Criteo.pushEventAgentContact(self.listingId);
                    }

                    if (self.gaCategory && self.gaAgencyName && self.gaAgencyEmail) Rev.Utils.GaTracking.trackGaEvent(self.gaCategory, Rev.Utils.GaTracking.Action.SendToAgent, self.gaAgencyName + ' / ' + self.gaAgencyEmail);

                    Rev.Utils.GaTracking.trackEmailAgent(_this.model);

                    Rev.Utils.MatomoTracking.sendEvent(_this.model, Rev.Utils.MatomoTracking.Category.ListingLeads, Rev.Utils.MatomoTracking.Action.EmailAgent);
                }
            }).fail(function (result) {
                Rev.Utils.showErrors(result.errors, self.agentEnquiryErrorPlaceHolder);
                if (self.scrollTop) $('html, body').animate({ scrollTop: self.scrollTop }, 400);
            }).always(function () {
                self.$('[data-hook="btn-email-agent"]').button('reset');
            });
        },
        submitPostEnquiryForm: function submitPostEnquiryForm(e) {
            var _this2 = this;

            e.preventDefault();

            var $form = this.$('[data-hook="post-enquiry-ad-enquiry-form"]');
            var url = $form.attr('action');

            $(e.currentTarget).button('loading');

            $.post(url, $form.serialize()).done(function (result) {
                if (result.errors) {
                    _this2.$el.addClass('errors-choice-homeloan');
                    Rev.Utils.showErrors(result.errors, _this2.postEnquiryAdPlaceHolder);
                    if (_this2.scrollTop) $('html, body').animate({ scrollTop: _this2.scrollTop }, 400);
                } else {
                    _this2.showPostEnquiryConfirmation();
                }
            }).fail(function (result) {
                _this2.$el.addClass('errors-choice-homeloan');
                Rev.Utils.showErrors(result.errors, _this2.postEnquiryAdPlaceHolder);
                // scroll up to show error message
                if (_this2.scrollTop) $('html, body').animate({ scrollTop: _this2.scrollTop }, 400);
            }).always(function () {
                _this2.$('[data-hook="btn-post-enquiry-ad-submit"]').button('reset');
            });
        },
        showSuccessMessage: function showSuccessMessage() {
            var _this3 = this;

            var fullName = this.$('[data-hook = "enquiry-name"]').val().split(" ");
            var firstName = fullName[0];
            var lastName = fullName[1];

            this.$('.modal-agents-title').text('Thank you for your enquiry.');

            // set name, email and phone value to home loan form
            this.$('[data-hook = "post-enquiry-ad-enquiry-first-name"]').val(firstName);
            this.$('[data-hook = "post-enquiry-ad-enquiry-last-name"]').val(lastName);
            this.$('[data-hook = "post-enquiry-ad-enquiry-email"]').val(this.$('[data-hook = "enquiry-email"]').val());
            this.$('[data-hook = "post-enquiry-ad-enquiry-phone"]').val(this.$('[data-hook = "enquiry-phone"]').val());

            this.$('[data-hook="email-agent-form"]').fadeOut(400, function () {
                _this3.$el.addClass('email-agent-success');
                //$('.modal-dialog').animate({ width:  ($('[data-hook="post-enquiry-ad"]').width() || 300) + 50 }, 400, () =>
                // {
                _this3.$('[data-hook="email-agent-success"]').fadeIn(500);

                //});
            });
        },
        showPostEnquiryConfirmation: function showPostEnquiryConfirmation() {
            var _this4 = this;

            var fullName = this.$('[data-hook = "enquiry-name"]').val();
            this.$('[data-hook="post-enquiry-ad-success-title"]').text('Thanks ' + fullName);

            $('html, body').animate({ scrollTop: this.$el.offset().top - $('#layout-header').height() }, function () {
                _this4.$('[data-hook="email-agent-success"]').slideUp({ duration: 400, easing: 'linear' });
                _this4.$('[data-hook="post-enquiry-ad-success"]').fadeOut(300).fadeIn(300);
            });
        },
        hideSuccessaMessage: function hideSuccessaMessage() {
            this.$('[data-hook="email-agent-form"]').show();
            this.$('[data-hook="email-agent-success"]').hide();
        },
        showCommentsBox: function showCommentsBox(e) {
            if (e && e.preventDefault) e.preventDefault();
            this.$('[data-hook="input-comments"]').toggle().focus();
        }
    });
})(Rev, jQuery, _, Backbone);
'use strict';

(function (Rev, $, _, Backbone) {

  'use strict';

  Rev.Views.FacebookLoginRedirectView = Backbone.View.extend({
    initialize: function initialize() {
      _.bindAll(this, 'handleAccessToken', 'submitLoginFB');
      this.handleAccessToken();
    },
    handleAccessToken: function handleAccessToken() {
      var self = this;
      var hash = location.hash;
      var hashDictionary = Rev.Utils.parseHash(location.href);

      if (hashDictionary.access_token) {
        FB.getLoginStatus(function (response) {
          if (response.status === 'connected') {
            var uid = response.authResponse.userID;
            FB.api('/' + uid, function (result) {
              self.submitLoginFB(hashDictionary.access_token, uid, result.first_name, result.last_name);
            });
          }
        });
      } else {
        // error is displayed by server(Razor)
      }
    },
    submitLoginFB: function submitLoginFB(fbAccessToken, fbUid, fbFirstName, fbLastName) {
      var self = this;
      var url = self.$('form#login-form-fb').attr('action');

      var data = {};
      data["__RequestVerificationToken"] = this.$('form#login-form-fb [name="__RequestVerificationToken"]').val();
      data["fbAccessToken"] = fbAccessToken;
      data["fbUid"] = fbUid;
      data["fbFirstName"] = fbFirstName;
      data["fbLastName"] = fbLastName;

      $.post(url, data).done(function (result) {
        if (!result.errors) {
          location.href = '/';
        } else {
          Rev.Utils.showErrors(result.errors, self.$('[data-hook="validation-errors-placeholder-fb"]'));
        }
      }).fail(function (result) {
        Rev.Utils.showErrors(result.errors, self.$('[data-hook="validation-errors-placeholder-fb"]'));
      }).always(function () {});
    }
  });
})(Rev, jQuery, _, Backbone);
'use strict';

// dependencies : Rev, jquery, underscore, backbone

(function (Rev, $, _, Backbone) {

  'use strict';

  Rev.Views.FloorplanModalView = Backbone.View.extend({
    initialize: function initialize() {
      var _this = this;

      _.bindAll(this, 'closeView');

      this.$panzoom = this.$('.modal-body ').panzoom({
        minScale: 1,
        maxScale: 3,
        contain: 'invert'
      });

      this.$panzoom.parent().on('mousewheel.focal', function (e) {
        e.preventDefault();
        var delta = e.delta || e.originalEvent.wheelDelta;
        var zoomOut = delta ? delta < 0 : e.originalEvent.deltaY > 0;
        _this.$panzoom.panzoom('zoom', zoomOut, {
          increment: 0.1,
          animate: true,
          focal: e
        });
      });
    },

    events: {
      'click [data-hook="close"]': 'closeView',
      'hidden.bs.modal': 'onModalHidden'
    },

    onModalHidden: function onModalHidden(e) {
      $('.list-result-items').removeClass('modal-open');
    },
    closeView: function closeView(e) {
      if (e && e.preventDefault) e.preventDefault();

      $('.rev-modal-backdrop').hide();
      this.$el.modal('hide');
    },
    remove: function remove() {
      this.closeView();
      this.off();
      Backbone.View.prototype.remove.apply(this, arguments); //call the superclass remove method
    }
  });
})(Rev, jQuery, _, Backbone);
'use strict';

(function (Rev, $, _, Backbone) {

  'use strict';

  Rev.Views.ForgotPasswordView = Backbone.View.extend({
    el: '.forgot-password-body',

    initialize: function initialize() {},


    events: {
      'click [data-hook="close-forgot-password"]': 'toggleForgotPassword',
      'click [data-hook="submit-forgot-password-form"]': 'submitForgotPassword'
    },

    toggleForgotPassword: function toggleForgotPassword(e) {
      if (e && e.preventDefault) e.preventDefault();
      Rev.trigger('forgotpassword:toggle');
    },
    submitForgotPassword: function submitForgotPassword(e) {
      e.preventDefault();

      var self = this;
      var url = this.$('form#forgot-password-form').attr('action');

      $(e.currentTarget).button('loading');

      $.post(url, this.$('form#forgot-password-form').serialize()).done(function (result) {
        if (!result.errors) {
          self.showSuccess();
        } else {
          $('#auth-views-modal').addClass('showing-error');
          Rev.Utils.showErrors(result.errors, self.$('[data-hook="forgot-password-validation-errors-placeholder"]'));
        }
      }).fail(function (result) {
        $('#auth-views-modal').addClass('showing-error');
        Rev.Utils.showErrors(result.errors, self.$('[data-hook="forgot-password-validation-errors-placeholder"]'));
      }).always(function () {
        self.$('[data-hook="submit-forgot-password-form"]').button('reset');
      });
    },
    showSuccess: function showSuccess() {
      $('[data-hook="forgot-password-form-wrapper"]').hide();
      $('[data-hook="forgot-password-form-success"]').addClass('show');
    }
  });
})(Rev, jQuery, _, Backbone);
'use strict';

(function (Rev, $, _, Backbone) {

  'use strict';

  Rev.Views.HeaderView = Backbone.View.extend({
    el: 'nav.next',

    initialize: function initialize() {
      _.bindAll(this, 'onRecentIdsChanged', 'onShortlistChanged', 'showBackToSearchResultsButton', 'hideBackToSearchResultsButton', 'showNewSearchButton', 'hideNewSearchButton', 'onSavedSearchesChanged', 'hideSaveSearchButtons', 'logout');

      this.$('[data-toggle="tooltip"]').tooltip();

      this.showRecentHistoryNumber();
      this.onSavedSearchesChanged();

      this.pageLoading = true;

      this.listenTo(Rev, 'change:recentHistory', this.onRecentIdsChanged);
      this.listenTo(Rev, 'change:shortlist', this.onShortlistChanged);
      this.listenTo(Rev, 'change:saved-searches', this.onSavedSearchesChanged);
      this.listenTo(Rev, 'back-to-search-results-button:show', this.showBackToSearchResultsButton);
      this.listenTo(Rev, 'back-to-search-results-button:hide', this.hideBackToSearchResultsButton);
      this.listenTo(Rev, 'new-search-button:show', this.showNewSearchButton);
      this.listenTo(Rev, 'new-search-button:hide', this.hideNewSearchButton);
      this.listenTo(Rev, 'save-search-buttons:show', this.showSaveSearchButtons);
      this.listenTo(Rev, 'save-search-buttons:hide', this.hideSaveSearchButtons);
      this.listenTo(Rev, 'search-menu-type', this.activeSearchMenu);
    },


    events: {
      'click [data-hook="open-login-modal"]': 'openLoginModal',
      'click [data-hook="toggle-sidebar"]': 'toggleSidebar',
      'click [data-hook="open-signup-modal"]': 'openSignupModal',
      'click [data-hook="back-to-search-results"]': 'backToSearchResults',
      'click [data-hook="toggle-new-search-form"]': 'toggleNewSearchForm',
      'click .save-search-section [data-hook="btn-save-search"]': 'onClickSaveSearch',
      'click .save-search-section [data-hook="btn-save-viewalert"]': 'onClickSaveViewAlert',
      'click .btn-logout': 'logout'
    },

    // searchMenuType is one of 0(Buy), 1(Rent) and 2(Sold)
    activeSearchMenu: function activeSearchMenu(searchMenuType) {
      if (!searchMenuType) return;

      this.$('.navigation-links li a').removeClass('active');
      this.$('.navigation-links li[data-search-menu-type="' + searchMenuType + '"] a').addClass('active');
    },
    logout: function logout(e) {
      var _this = this;

      e.preventDefault();

      $.getJSON('/authenticated/').done(function (result) {
        if (!result.isAuthenticated) {
          location.reload(true);
        } else {
          _this.$('form[data-hook="logout"]').submit();
        }
      });
    },
    showSaveSearchButtons: function showSaveSearchButtons() {
      //this.$('.save-search-section').show();
      this.$('.save-search-section').addClass('show');
    },
    hideSaveSearchButtons: function hideSaveSearchButtons() {
      //this.$('.save-search-section').hide();
      this.$('.save-search-section').removeClass('show');
    },
    onClickSaveSearch: function onClickSaveSearch(e) {
      var _this2 = this;

      e.preventDefault();
      $(e.currentTarget).button('loading');

      Rev.Utils.saveSearch($('.result-page .refine-search form'), function () {
        _this2.$('[data-hook="btn-save-search"]').button('reset');
      });
    },
    onClickSaveViewAlert: function onClickSaveViewAlert(e) {
      e.preventDefault();
      Rev.Utils.showViewAlertOptionModal();
    },
    showNewSearchButton: function showNewSearchButton(e) {
      if (e && e.preventDefault) e.preventDefault();
      this.$('[data-hook="toggle-new-search-form"]').show();
    },
    hideNewSearchButton: function hideNewSearchButton(e) {
      if (e && e.preventDefault) e.preventDefault();
      this.$('[data-hook="toggle-new-search-form"]').hide();
    },
    toggleNewSearchForm: function toggleNewSearchForm(e) {
      e.preventDefault();
      if ($('.result-page.search-result-page').is(':visible')) {
        // result page is shown, toggle refine search form 
        Rev.trigger('refine-search:toggle');
      } else {
        // result page is hidden or no exist, toggle new search form 
        Rev.trigger('new-search:toggle');
      }
    },
    backToSearchResults: function backToSearchResults(e) {
      e.preventDefault();
      $(e.currentTarget).addClass('returning');
      var wait = Rev.Utils.isiPad() ? 300 : 0;
      setTimeout(function () {
        return history.back();
      }, wait);
      setTimeout(function () {
        return $(e.currentTarget).removeClass('returning');
      }, 5000); // back to original state anyway
      Rev.trigger('new-search:hide');
    },
    showBackToSearchResultsButton: function showBackToSearchResultsButton() {
      this.$('[data-hook="back-to-search-results"]').removeClass('hidden').removeClass('returning');
    },
    hideBackToSearchResultsButton: function hideBackToSearchResultsButton() {
      this.$('[data-hook="back-to-search-results"]').addClass('hidden').removeClass('returning');
    },
    toggleSidebar: function toggleSidebar(e) {
      e.preventDefault();
      Rev.trigger('sidebar:toggle');
    },
    openLoginModal: function openLoginModal(e) {
      e.preventDefault();

      $.getJSON('/authenticated/').done(function (result) {
        if (!result.isAuthenticated) {
          Rev.Utils.showAuthModal('login');
        } else {
          location.reload(true);
        }
      });
    },
    openSignupModal: function openSignupModal(e) {
      e.preventDefault();

      $.getJSON('/authenticated/').done(function (result) {
        if (!result.isAuthenticated) {
          Rev.Utils.showAuthModal('signup');
        } else {
          location.reload(true);
        }
      });
    },
    onRecentIdsChanged: function onRecentIdsChanged(listingIds) {
      this.$('[data-hook="recent-history-count"]').text(listingIds.length);
    },
    onShortlistChanged: function onShortlistChanged(listingIds) {
      var _this3 = this;

      setTimeout(function () {
        if (listingIds && listingIds.length > 0) {
          _this3.$('[data-hook="shortlist-count"]').text(listingIds.length).removeClass('hide');
          if (!_this3.pageLoading) {
            _this3.$('[data-hook="shortlist-count"]').addClass('flashing');
          }
          _this3.pageLoading = false;
          setTimeout(function () {
            return _this3.$('[data-hook="shortlist-count"]').removeClass('flashing');
          }, 300);
        } else {
          _this3.$('[data-hook="shortlist-count"]').addClass('hide');
        }
      }, 50);
    },
    onSavedSearchesChanged: function onSavedSearchesChanged() {
      var _this4 = this;

      $.getJSON('/saved-searches/total/').done(function (result) {
        if (result.total > 0) {
          _this4.$('[data-hook="saved-search-count"]').text(result.total).removeClass('hide').addClass('flashing');
          setTimeout(function () {
            return _this4.$('[data-hook="saved-search-count"]').removeClass('flashing');
          }, 300);
        } else {
          _this4.$('[data-hook="saved-search-count"]').addClass('hide');
        }
      });
    },


    showRecentHistoryNumber: function showRecentHistoryNumber() {
      var listingIds = Rev.Utils.recentHistoryCookie.getRecentIds();
      if (listingIds && _.isArray(listingIds)) {
        this.$('[data-hook="recent-history-count"]').text(listingIds.length);
      }
    }
  });

  new Rev.Views.HeaderView();
})(Rev, jQuery, _, Backbone);
'use strict';

(function (Rev, $, _, Backbone) {

  'use strict';

  Rev.Views.HomeArticlesView = Backbone.View.extend({
    el: '.section-articles',

    initialize: function initialize() {
      _.bindAll(this, 'afterSlick', 'disableNonCurrentArticles');

      this.slickInstance = Rev.Utils.initSlick(this.$('.article-groups'), {
        lazyLoad: null,
        variableWidth: true,
        infinite: true
      });
      this.slickInstance.on('afterChange', this.afterSlick);
      this.disableNonCurrentArticles();

      this.$('.article-groups').addClass('pull-up');
    },

    events: {
      'click [data-hook="nav-articles-left"]': 'onNavArticlesLeftClick',
      'click [data-hook="nav-articles-right"]': 'onNavArticlesRightClick'
    },

    afterSlick: function afterSlick(event, slick, currentSlide) {
      this.disableNonCurrentArticles();
    },
    disableNonCurrentArticles: function disableNonCurrentArticles() {
      this.$('.article-group.slick-slide').css({ 'pointer-events': 'none' });
      this.$('.article-group.slick-slide.slick-current.slick-active.slick-center').css({ 'pointer-events': 'all' });
    },
    onNavArticlesLeftClick: function onNavArticlesLeftClick(e) {
      e.preventDefault();
      if (this.slickInstance) {
        this.slickInstance.slick('slickPrev');
      }
    },
    onNavArticlesRightClick: function onNavArticlesRightClick(e) {
      e.preventDefault();
      if (this.slickInstance) {
        this.slickInstance.slick('slickNext');
      }
    }
  });
})(Rev, jQuery, _, Backbone);
'use strict';

// dependencies : Rev, jquery, underscore, backbone, slick.js

(function (Rev, $, _, Backbone) {

            'use strict';

            Rev.Views.ListDetailsView = Backbone.View.extend({
                        el: '.details-page',

                        initialize: function initialize() {

                                    // initialize sub views
                                    this.initSubViews();

                                    // save id for recent history
                                    Rev.Utils.recentHistoryCookie.saveRecentHistory(this.model.get('Id'));

                                    //// google advert targeting
                                    //Rev.Utils.setTargetingDetailsPage(this.model.toJSON());

                                    // generate criteo event
                                    Rev.Utils.Criteo.pushDetailsPageEvent(this.model.get('Id'));

                                    this.$(".stickyContact").stick_in_parent({ offset_top: 0 });

                                    this.listenTo(Rev, 'matomo:event:email-agent', this.sendEmailAgentMatomoEvent);
                        },


                        events: {
                                    'click [data-hook="back-to-results"]': 'openPastResults'
                        },

                        openPastResults: function openPastResults(e) {
                                    var ref = document.referrer;
                                    if (ref === "") {
                                                // no page before this one. Let the link do it's work.
                                                return;
                                    }

                                    // We can use the browser and DOM to figure out the host name of the referrer
                                    var link = document.createElement('a');
                                    link.setAttribute('href', ref);
                                    var lastHost = link.hostname; // this will be hostname of document.referrer

                                    var serverHost = window.location.hostname;

                                    if (serverHost === lastHost || lastHost.indexOf('view.com.au') >= 0) {
                                                // previous page is from our site. Go to history. 
                                                e.preventDefault();
                                                var prevPage = window.location.href;
                                                window.history.go(-1);
                                                // if the go history resulted in no change then send the user to the search page.
                                                setTimeout(function () {
                                                            if (window.location.href == prevPage) window.location.href = '/';
                                                }, 500);
                                    }
                                    // do nothing. Let the link do it's work.
                        },
                        initSubViews: function initSubViews() {
                                    this.emailAgentSidebarView = new Rev.Views.EmailAgentSidebarView({ el: '.email-agent-sidebar', model: this.model });

                                    this.listingEnquiryView = new Rev.Views.ListingEnquiryView({
                                                el: '.listing-enquiry-bottom', model: this.model
                                                //gaCategory: this.model.get('GaEventCategory'),
                                                //gaAgencyName: this.model.get('AgencyName'),
                                                //gaAgencyEmail: this.model.get('AgencyEmail'),
                                                //listingId: this.model.get('Id'),
                                                //agencyId: this.model.get('AgencyId')
                                    });

                                    this.mapView = new Rev.Views.MapView({ el: '.listing-details-map', model: this.model });

                                    var hasPocketInsights = this.model.get('AreaStatistics');
                                    if (hasPocketInsights) {
                                                this.pocketInsighsView = new Rev.Views.EaiaPropertyPocketInsightsView({ el: '.pocket-insights', model: this.model });
                                    }

                                    var hasSuburbTrends = this.model.get('LocalityTrendsHouse');
                                    if (hasSuburbTrends) {
                                                this.suburbTrendsView = new Rev.Views.EaiaPropertySuburbTrendsView({ el: '.suburb-trends', model: this.model });
                                    }

                                    this.listingInfoPhotoView = new Rev.Views.ListingInfoPhotoView({ el: '.listing-info-and-photo', model: this.model });

                                    this.listingSidebar = new Rev.Views.ListingSidebar({ el: '.listing-property-sidebar', model: this.model });

                                    this.agentFloat = new Rev.Views.AgentFloatView({ el: '.listing-agents', model: this.model });

                                    this.agentFloatButtons = new Rev.Views.AgentFloatButtonsView({ el: '.listing-agency-contact', model: this.model });

                                    this.inspectionAuctionTimes = new Rev.Views.InspectionAuctionTimesView({ el: '.listing-inspections', model: this.model });

                                    this.threeCompsView = new Rev.Views.ThreeCompsView({ el: '.three-comps .user-mode', model: this.model });
                                    if (this.model.get('IsAuthenticatedAgent') && !this.model.get('IsThreeCompsDisabled') && this.$('.three-comps .agent-mode').length) {
                                                this.threeCompsAgentView = new Rev.Views.ThreeCompsAgentView({
                                                            el: '.three-comps .agent-mode',
                                                            listingId: this.model.get('Id'),
                                                            gnafId: this.model.get('GnafId')
                                                });
                                    }

                                    //this.mortgageCalculator = new Rev.Views.MortgageCalculatorView({ el: '.mortgage-calculator' });

                                    this.otherAgencyProperties = new Rev.Views.OtherAgencyPropertiesView({
                                                el: '#OtherAgencyProperties',
                                                model: this.model,
                                                id: this.model.get('Id'),
                                                totalProperties: this.model.get('OtherAgencyPropertiesTotalProperties'),
                                                gaCategory: this.model.get('GaEventCategory'),
                                                gaLabel: this.model.get('GaEventLabel')
                                    });

                                    this.listingDescriptionView = new Rev.Views.ListingDescriptionView({ el: '.listing-property-desc', model: this.model });

                                    this.viewHomeLoansView = new Rev.Views.ViewHomeLoansView({ el: '.view-home-loans', gaCategory: this.model.get('GaEventCategory'), listingId: this.model.get('Id') });

                                    this.shortlistButtonView = new Rev.Views.ShortlistButtonView({ el: '.shortlist-button-view', model: this.model });

                                    this.schoolsView = new Rev.Views.SchoolsView({ el: '.listing-details-schools', model: this.model });
                        },
                        sendPhotoGalleryMatomoEvent: function sendPhotoGalleryMatomoEvent() {
                                    Rev.Utils.MatomoTracking.sendEvent(this.model, Rev.Utils.MatomoTracking.Category.ListingLeads, Rev.Utils.MatomoTracking.Action.ListingGalleryCarousel);
                        },
                        sendFloorplanGalleryMatomoEvent: function sendFloorplanGalleryMatomoEvent() {
                                    Rev.Utils.MatomoTracking.sendEvent(this.model, Rev.Utils.MatomoTracking.Category.ListingLeads, Rev.Utils.MatomoTracking.Action.FloorPlan);
                        },
                        sendEmailAgentMatomoEvent: function sendEmailAgentMatomoEvent(model) {
                                    Rev.Utils.MatomoTracking.sendEvent(this.model, Rev.Utils.MatomoTracking.Category.ListingLeads, Rev.Utils.MatomoTracking.Action.EmailAgent);
                        },
                        remove: function remove() {
                                    // remove sub views
                                    if (this.listingEnquiryView) this.listingEnquiryView.remove();
                                    if (this.poiView) this.poiView.remove();
                                    if (this.pocketInsighsView) this.pocketInsighsView.remove();
                                    if (this.suburbTrendsView) this.suburbTrendsView.remove();
                                    if (this.listingInfoPhotoView) this.listingInfoPhotoView.remove();
                                    if (this.agentFloat) this.agentFloat.remove();
                                    if (this.inspectionAuctionTimes) this.inspectionAuctionTimes.remove();
                                    //if (this.mortgageCalculator) this.mortgageCalculator.remove();
                                    if (this.otherAgencyProperties) this.otherAgencyProperties.remove();
                                    if (this.listingDescriptionView) this.listingDescriptionView.remove();

                                    this.off();
                                    this.stopListening();

                                    //call the superclass remove method
                                    Backbone.View.prototype.remove.apply(this, arguments);
                        }
            });
})(Rev, jQuery, _, Backbone);
'use strict';

// dependencies : Rev, jquery, underscore, Backbone

(function (Rev, $, _, Backbone) {

  'use strict';

  Rev.Views.ListResultHeaderView = Backbone.View.extend({
    initialize: function initialize(options) {
      var options = options || {};
      this.isSuburbRequired = options.isSuburbRequired;

      _.bindAll(this, 'resizeSearchSummary', 'onResize', 'toggleRefineSearch', 'updateLocationHiddenField');

      // create view for search form
      var searchFormData = this.model.get('SearchForm');
      var searchFormModel = new Rev.Models.SearchForm(searchFormData);
      this.searchFormView = new Rev.Views.SearchFormView({ el: this.$('.nav-search'), model: searchFormModel, isRefineSearch: true, isSuburbRequired: this.isSuburbRequired });

      this.$('.search-summary-inner').addClass('show');
      this.resizeSearchSummary();

      new Rev.Views.RevDropdownSortView({ el: '.dropdown-sort' });

      this.listenTo(Rev, 'change:shortlist', this.onShortlistChanged);
      this.listenTo(Rev, 'map:search:bound', this.mapSearchBoundToggle);
      this.listenTo(Rev, 'refine-search:toggle', this.toggleRefineSearch);
      this.listenTo(Rev, 'search:filter:location:changed', this.updateLocationHiddenField);

      // note that we don't have to listen following two events because the action buttons are now in .result-page. we needed to listen these events when they were in #layout-header
      //this.listenTo(Rev, 'save-search-buttons:show', this.showSaveSearchButtons);
      //this.listenTo(Rev, 'save-search-buttons:hide', this.hideSaveSearchButtons);

      $(window).on('resize', this.onResize);
    },


    events: {
      'click [data-hook="close-refine-search"]': 'onCloseRefineSearchClick',
      'click .search-summary-section': 'onSearchSummaryClick',
      'change .sorting-section [data-hook="dropdown-selected-value"]': 'onSortChange',
      'mouseenter .search-summary-section .locations': 'onLocationsMouseEnter',
      'mouseleave .search-summary-section .locations': 'onLocationsMouseLeave',
      'mouseenter .search-summary-section .property-types': 'onPropertyTypesMouseEnter',
      'mouseleave .search-summary-section .property-types': 'onPropertyTypesMouseLeave',
      'mouseenter .search-summary-section .keywords': 'onKeywordsMouseEnter',
      'mouseleave .search-summary-section .keywords': 'onKeywordsMouseLeave',
      'click .list-mode-section a': 'onListModeClick',
      'click .map-mode-section a': 'onMapModeClick',
      'click .result-header-action-buttons [data-hook="btn-save-search"]': 'onClickSaveSearch',
      'click .result-header-action-buttons [data-hook="btn-save-viewalert"]': 'onClickSaveViewAlert',
      'click [data-hook="btn-add-auction"]': 'onAddAuctionAlertClick'
    },

    //showSaveSearchButtons() {
    //  this.$('.result-header-action-buttons').addClass('show');
    //},

    //hideSaveSearchButtons() {
    //  this.$('.result-header-action-buttons').removeClass('show');
    //},


    updateLocationHiddenField: function updateLocationHiddenField(locationObject) {
      var locationString = '';
      var locations = locationObject.allItems; //this.$tagsinput.tagsinput('items');
      if (locations && locations.length) {
        var arr = _.map(locations, function (location) {
          if (location && location.Suburb && location.State && location.Postcode && location.State.toLowerCase() === "vic") {
            // filter only victoria suburbs
            return location.Suburb.toLowerCase() + '|' + location.State.toLowerCase() + '|' + location.Postcode;
          }
        });
        locationString = arr.join(',');
      }

      $('.auction-alert-append-form input[name="suburbs"]').val(locationString);

      if (locationString) {
        this.$('.auction-alert-append-form').removeClass('hide');
      } else {
        this.$('.auction-alert-append-form').addClass('hide');
      }
    },
    onAddAuctionAlertClick: function onAddAuctionAlertClick(e) {
      var _this = this;

      e.preventDefault();
      var self = this;
      $(e.currentTarget).button('loading');

      var callbackAfterSave = function callbackAfterSave() {
        setTimeout(function () {
          window.location.reload(true);
        }, 500);
      };

      var afterAuthCallback = function afterAuthCallback() {
        self.refreshAntiforgeryToken(function () {
          self.saveAuctionAlert(self.$(e.currentTarget).closest('form.auction-alert-append-form'), callbackAfterSave);
        });
      };
      var closeAuthWindowCallback = function closeAuthWindowCallback() {
        return self.$('[data-hook="btn-add-auction"]').button('reset');
      };
      var callbackIfAlreadyAuthenticated = function callbackIfAlreadyAuthenticated() {
        return self.saveAuctionAlert(_this.$(e.currentTarget).closest('form.auction-alert-append-form'));
      };

      Rev.Utils.saveAuctionAlert(afterAuthCallback, afterAuthCallback, closeAuthWindowCallback, callbackIfAlreadyAuthenticated);

      Rev.Utils.GaTracking.trackGaEvent(Rev.Utils.GaTracking.Category.SearchResults, Rev.Utils.GaTracking.Action.AddAuctionAlert, Rev.Utils.GaTracking.Label.AlertSaved);
    },
    refreshAntiforgeryToken: function refreshAntiforgeryToken(successCallback) {
      $.get('/refreshtoken/').done(function (html) {
        var tokenValue = $('<div />').html(html).find('input[type="hidden"]').val();
        $('input[name="__RequestVerificationToken"]').val(tokenValue);
        if (successCallback) successCallback();
      });
    },
    saveAuctionAlert: function saveAuctionAlert($form, callback) {
      var _this2 = this;

      var actionUrl = $form.attr('action');

      $.post(actionUrl, $form.serialize()).done(function (result) {
        if (result.errors) {
          Rev.Utils.showErrorMessage(_.pluck(result.errors, 'Value').join(', '));
        } else {
          Rev.Utils.showSuccessMessage('Auction alerts saved');
          if (callback) callback();
        }
      }).fail(function (result) {
        Rev.Utils.showErrorMessage('Auction alerts not saved');
      }).always(function () {
        _this2.$('[data-hook="btn-add-auction"]').button('reset');
      });
    },
    onClickSaveSearch: function onClickSaveSearch(e) {
      var _this3 = this;

      e.preventDefault();
      $(e.currentTarget).button('loading');

      Rev.Utils.saveSearch($('.result-page .refine-search form'), function () {
        _this3.$('[data-hook="btn-save-search"]').button('reset');
      });

      Rev.Utils.GaTracking.trackGaEvent(Rev.Utils.GaTracking.Category.SearchResults, Rev.Utils.GaTracking.Action.SaveThisSearch, Rev.Utils.GaTracking.Label.SearchSaved);
    },
    onClickSaveViewAlert: function onClickSaveViewAlert(e) {
      e.preventDefault();
      Rev.Utils.showViewAlertOptionModal();
      Rev.Utils.GaTracking.trackGaEvent(Rev.Utils.GaTracking.Category.SearchResults, Rev.Utils.GaTracking.Action.CreateEmailAlert, Rev.Utils.GaTracking.Label.AlertSaved);
    },
    onListModeClick: function onListModeClick(e) {
      Rev.Utils.GaTracking.trackGaEvent(Rev.Utils.GaTracking.Category.SearchResults, Rev.Utils.GaTracking.Action.ListView);
    },
    onMapModeClick: function onMapModeClick(e) {
      Rev.Utils.GaTracking.trackGaEvent(Rev.Utils.GaTracking.Category.SearchResults, Rev.Utils.GaTracking.Action.MapView);
    },
    onLocationsMouseEnter: function onLocationsMouseEnter(e) {
      var $locations = this.$('.search-summary-section .locations');
      if (!$locations.find('.locations-number').is(':visible')) return;
      var $tooltip = this.$('.search-summary-tooltip.locations');
      var left = $locations.width() / 2 - $tooltip.width() / 2 + $locations.offset().left;
      $tooltip.css({ 'left': left + 'px', 'opacity': '1' });
    },
    onLocationsMouseLeave: function onLocationsMouseLeave(e) {
      this.$('.search-summary-tooltip.locations').css('opacity', '0');
    },
    onPropertyTypesMouseEnter: function onPropertyTypesMouseEnter(e) {
      var $pts = this.$('.search-summary-section .property-types');
      if (!$pts.find('.property-types-number').is(':visible')) return;
      var $tooltip = this.$('.search-summary-tooltip.property-types');
      var left = $pts.width() / 2 - $tooltip.width() / 2 + $pts.offset().left;
      $tooltip.css({ 'left': left + 'px', 'opacity': '1' });
    },
    onPropertyTypesMouseLeave: function onPropertyTypesMouseLeave(e) {
      this.$('.search-summary-tooltip.property-types').css('opacity', '0');
    },
    onKeywordsMouseEnter: function onKeywordsMouseEnter(e) {
      var $kws = this.$('.search-summary-section .keywords');
      var $tooltip = this.$('.search-summary-tooltip.keywords');
      var left = $kws.width() / 2 - $tooltip.width() / 2 + $kws.offset().left;
      $tooltip.css({ 'left': left + 'px', 'opacity': '1' });
    },
    onKeywordsMouseLeave: function onKeywordsMouseLeave(e) {
      this.$('.search-summary-tooltip.keywords').css('opacity', '0');
    },
    mapSearchBoundToggle: function mapSearchBoundToggle(onff) {
      this.$('.search-summary').toggleClass('gray');
    },


    //onIssTooltipShow(e) {
    //  if (!this.resultHeaderOriginalZindex)
    //    this.resultHeaderOriginalZindex = $('.result-page .result-header.fix.open').css('z-index');
    //  var layoutHeaderZindex = $('#layout-body #layout-header.fix').css('z-index');
    //  this.$('.result-header.fix.open').css('z-index', parseInt(layoutHeaderZindex) + 1);
    //},

    //onIssTooltipHide(e) {
    //  if(this.resultHeaderOriginalZindex)
    //    this.$('.result-header.fix.open').css('z-index', this.resultHeaderOriginalZindex);
    //},

    onSortChange: function onSortChange(e) {
      Rev.trigger('sort:changed', e.currentTarget.value); // searchFormView will listen to this event
    },
    resizeSearchSummary: function resizeSearchSummary(e) {
      var searchIconWidth = this.$('.search-summary-section .icon-icon-search').outerWidth();

      // #1 reset to the original styles
      this.$('.search-summary-section .locations').css('width', 'auto');
      this.$('.search-summary-section .property-types').css('width', 'auto');
      this.$('.search-summary-section .bedrooms').css('width', 'auto');
      this.$('.search-summary-section .prices').css('width', 'auto');
      this.$('.search-summary-section .locations .locations-text').css('width', 'auto');
      this.$('.search-summary-section .property-types .property-types-text').css('width', 'auto');
      this.$('.search-summary-section .keywords .keywords-text').css('width', 'auto');

      // #2 get lengths based on each text
      var locationsInnerWidth = this.$('.search-summary-section .locations .locations-inner').width();
      var propertyTypesInnerWidth = this.$('.search-summary-section .property-types .property-types-inner').width();
      var bedroomsInnerWidth = this.$('.search-summary-section .bedrooms .bedrooms-inner').width();
      var pricesInnerWidth = this.$('.search-summary-section .prices .prices-inner').width();
      var keywordsInnerWidth = this.$('.search-summary-section .keywords .keywords-inner').width();
      var totalInnerWidth = locationsInnerWidth + propertyTypesInnerWidth + bedroomsInnerWidth + pricesInnerWidth + keywordsInnerWidth;

      var searchSummarySectionWidth = this.$('.search-summary-section').width() - searchIconWidth;

      // #3 calculate each width(percentage) based on ***-inner width
      var locationsWidth = searchSummarySectionWidth * locationsInnerWidth / totalInnerWidth;
      var propertysTypeWidth = searchSummarySectionWidth * propertyTypesInnerWidth / totalInnerWidth;
      var bedroomsWidth = searchSummarySectionWidth * bedroomsInnerWidth / totalInnerWidth;
      var pricesWidth = searchSummarySectionWidth * pricesInnerWidth / totalInnerWidth;
      var keywordsWidth = searchSummarySectionWidth * keywordsInnerWidth / totalInnerWidth;

      // #4 set actual width for each parts
      bedroomsWidth = bedroomsWidth < bedroomsInnerWidth ? bedroomsInnerWidth : bedroomsWidth;
      pricesWidth = pricesWidth < pricesInnerWidth ? pricesInnerWidth : pricesWidth;
      //this.$('.search-summary-section .bedrooms').width(bedroomsWidth);
      //this.$('.search-summary-section .prices').width(pricesWidth);

      var restWidth = searchSummarySectionWidth - (bedroomsWidth + pricesWidth);

      locationsWidth = restWidth * locationsInnerWidth / (locationsInnerWidth + propertyTypesInnerWidth) - 10; // 10 is padding of .locations
      propertysTypeWidth = restWidth * propertyTypesInnerWidth / (locationsInnerWidth + propertyTypesInnerWidth) - 10; // 10 is padding of .property-types

      //this.$('.search-summary-section .locations').width(locationsWidth - 1); // 1 is just buffer
      //this.$('.search-summary-section .property-types').width(propertysTypeWidth - 1);  
      this.$('.search-summary-section .locations').css('max-width', locationsWidth - 1); // 1 is just buffer
      this.$('.search-summary-section .property-types').css({ 'max-width': propertysTypeWidth });

      // #5 add dot dot dot at the end 
      if (this.$('.search-summary-section .locations').width() <= this.$('.search-summary-section .locations .locations-inner').width()) {

        this.$('.search-summary-section .locations .locations-text').width(this.$('.search-summary-section .locations').width() - 20); // 20 is width of total number
        this.$('.search-summary-section .locations .locations-text').removeClass('auto-width');
      } else {
        this.$('.search-summary-section .locations .locations-text').addClass('auto-width');
      }

      // add dot dot dot at the end 
      if (this.$('.search-summary-section .property-types').width() <= this.$('.search-summary-section .property-types .property-types-inner').width()) {

        this.$('.search-summary-section .property-types .property-types-text').width(this.$('.search-summary-section .property-types').width() - 20); // 20 is width of total number
        this.$('.search-summary-section .property-types .property-types-text').removeClass('auto-width');
      } else {
        this.$('.search-summary-section .property-types .property-types-text').addClass('auto-width');
      }
    },
    onResize: function onResize(e) {
      this.resizeSearchSummary();
    },
    toggleRefineSearch: function toggleRefineSearch() {
      this.$el.toggleClass('open');
      this.isRefineSearchOpen = !this.isRefineSearchOpen;
    },
    onSearchSummaryClick: function onSearchSummaryClick(e) {
      e.preventDefault();
      e.stopPropagation();
      this.toggleRefineSearch();
    },
    onCloseRefineSearchClick: function onCloseRefineSearchClick(e) {
      e.preventDefault();
      e.stopPropagation();
      this.$el.removeClass('open'); // if you need to change this code, consider fireGaEvent function of search_form_view.js
      this.isRefineSearchOpen = false;
    },
    onShortlistChanged: function onShortlistChanged(listingIds) {
      if ($('.result-page').hasClass('shortlist-page')) {
        this.$('[data-hook="total-results"]').text(listingIds.length);
      }
    },
    showShortlistStatus: function showShortlistStatus() {
      var self = this;
      $.getJSON('/authenticated/').done(function (result) {
        if (result.isAuthenticated) {
          if (!self.$el.hasClass('shortlist-page')) {
            // in shortlist page we don't have to check if this is  shortlisted or not
            self.getShortlistRemote();
          }
        }
      });
    },
    getShortlistRemote: function getShortlistRemote() {
      $.getJSON('/properties/shortlist/ids/json/').done(function (listingIds) {
        Rev.trigger('change:shortlist', listingIds);
      });
    },
    remove: function remove() {
      $(window).off("resize");

      this.searchFormView.remove();

      this.off();
      this.stopListening();

      //call the superclass remove method
      Backbone.View.prototype.remove.apply(this, arguments);
    }
  });
})(Rev, jQuery, _, Backbone);
'use strict';

// dependencies : Rev, jquery, underscore, backbone, slick.js

(function (Rev, $, _, Backbone) {

    'use strict';

    Rev.Views.ListResultsItemView = Backbone.View.extend({
        initialize: function initialize() {
            _.bindAll(this, 'afterSlick', 'onResultPageShown', 'handleOrientationChange', 'detectOrientation', 'adjustMainImageSize', 'mainPhotoImageLoad', 'adjustSideSectionImageSize', 'sidePhotoImageLoad', 'removeThisView', 'initSlick', 'resizeImage', 'getGaCategory');

            // photo swiping
            this.initSlick();

            // image resizing
            this.resizeImage();

            this.listenTo(Rev, 'result:page:shown', this.onResultPageShown);
            this.listenTo(Rev, 'list-results-item-view:remove', this.removeThisView);

            this.shortlistButtonView = new Rev.Views.ShortlistButtonView({ el: '[data-hook="listing-shortlist"][data-id="' + this.model.get('Id') + '"]', model: this.model });
        },


        events: {
            'click [data-hook="nav-photo-left"]': 'onNavPhotoLeftClick',
            'click [data-hook="nav-photo-right"]': 'onNavPhotoRightClick',
            'click [data-hook="contact-agency-email"]': 'openEmailAgentModal',
            'click [data-hook="contact-agency"]': 'contactAgency',
            'click [data-hook="contact-agency-phone-link"]': 'phoneAgent',
            'click [data-hook="open-youtube-video"]': 'onYoutubeVideoClick',
            'click [data-hook="open-virtual-tour"]': 'onVirtualTourClick',
            'click [data-hook="save-auction"]': 'saveAction',
            'click [data-hook="save-inspection"]': 'saveInspection'
        },

        onYoutubeVideoClick: function onYoutubeVideoClick(e) {
            e.preventDefault();
            e.stopPropagation();
            Rev.Utils.showYoutubeModal(this.model.get('Urls').YoutubeIFrameUrl);
        },
        contactAgency: function contactAgency(e) {},
        onVirtualTourClick: function onVirtualTourClick(e) {
            e.preventDefault();
            e.stopPropagation();

            if (!this.model.get('Urls') || !this.model.get('Urls').VirtualTourUrl) return;

            var url = this.model.get('Urls').VirtualTourUrl;
            if (url && url.indexOf('http') < 0) {
                url = 'http://' + url;
            }

            window.open(url);
        },
        saveInspection: function saveInspection(e) {
            Rev.Utils.icsFile.icsFileDownloading(this.model, 0);

            Rev.Utils.MatomoTracking.sendEvent(this.model, Rev.Utils.MatomoTracking.Category.ListingLeads, Rev.Utils.MatomoTracking.Action.InspectionTimeSave);
        },
        saveAction: function saveAction(e) {
            Rev.Utils.icsFile.icsFileDownloading(this.model);

            Rev.Utils.MatomoTracking.sendEvent(this.model, Rev.Utils.MatomoTracking.Category.ListingLeads, Rev.Utils.MatomoTracking.Action.AuctionTimeSave);
        },
        initSlick: function initSlick() {
            var self = this;

            if (self.slickInstance) {
                self.slickInstance.slick('unslick');
            }

            if (self.$('.photo-carousel').hasClass('slick-initialized')) return;

            self.slickInstance = Rev.Utils.initSlick(self.$('.photo-carousel'), {
                centerPadding: '0px',
                fade: true,
                lazyLoad: 'ondemand'
            });
            self.slickInstance.on('afterChange', self.afterSlick); //.on('swipe', this.onPhotoSwipe);
        },
        resizeImage: function resizeImage() {
            var self = this;
            self.mainImageHeights = [];
            self.sideImageHeights = [];
            self.$('.photo-carousel img').load(self.mainPhotoImageLoad);
            setTimeout(function () {
                return self.adjustSideSectionImageSize();
            }, 500); // just use setTimeout rather than image load event :)
            self.detectOrientation();
        },
        removeThisView: function removeThisView(listingId) {
            if (listingId === this.model.get('Id')) {
                //this.remove();
                this.$el.html('').height(this.viewHeight);
            }
        },


        detectOrientation: function detectOrientation() {
            this.mql = window.matchMedia("(orientation: portrait)");

            // Add a media query change listener
            this.mql.addListener(this.handleOrientationChange);
        },

        handleOrientationChange: function handleOrientationChange(m) {
            this.adjustMainImageSize();
            this.adjustSideSectionImageSize();
        },

        mainPhotoImageLoad: function mainPhotoImageLoad(event) {
            var self = this;

            // #0 fire event for .list-results-item.pull-up
            // WARNING : this event should not removed even if we have resized images by server
            //if ($('.list-results-item:not(".dummy")').first().attr('data-id') === self.$el.attr('data-id')) {
            Rev.trigger('list-results-item-view:main-photo:loaded');
            //}

            // #1 clear all image heights info
            if (self.mainImageHeights) self.mainImageHeights.length = 0;

            // #2 save all image heights info again
            self.$('.photo-carousel img').each(function (index, element) {
                if (element.src) {
                    var img = { src: '', height: '' };
                    img.src = element.src.replace(/^http:|^https:/i, '');
                    img.height = self.$(element).height();

                    if (!_.find(self.mainImageHeights, function (img) {
                        return img.src == element.src;
                    }) && img.height) {
                        // save info only when height is greater than 0 and no previous info saved
                        self.mainImageHeights.push(img);
                    }
                }
            });

            self.adjustMainImageSize();

            // store height of this listing 
            self.viewHeight = self.$el.height();
        },
        adjustMainImageSize: function adjustMainImageSize() {
            var self = this;
            if (self.mainImageHeights) {
                var containerHeight = self.$('.photo-carousel').height();

                _.each(self.mainImageHeights, function (imgInfo) {
                    if (imgInfo.height <= containerHeight) {
                        self.$('.photo-carousel img[src="' + imgInfo.src + '"]').addClass('height-priority');
                    } else {
                        self.$('.photo-carousel img[src="' + imgInfo.src + '"]').removeClass('height-priority');
                    }
                });
            }
        },


        // this function is not in use at the moment
        sidePhotoImageLoad: function sidePhotoImageLoad(event) {
            //if (this.model.get('Id') != '9182828') return;
            var self = this;

            // #1 clear all image heights info
            if (self.sideImageHeights) self.sideImageHeights.length = 0;

            // #2 save all image heights info again
            self.$('.side-section .item-img').each(function (index, element) {
                if (element.src) {
                    var img = { src: '', height: '' };
                    img.src = element.src.replace(/^http:|^https:/i, '');
                    img.height = self.$(element).height();

                    if (!_.find(self.sideImageHeights, function (img) {
                        return img.src == element.src;
                    }) && img.height) {
                        // save info only when height is greater than 0 and no previous info saved
                        self.sideImageHeights.push(img);
                    }
                }
            });

            self.adjustSideSectionImageSize();
        },
        adjustSideSectionImageSize: function adjustSideSectionImageSize() {
            var self = this;

            if (!self.$('.side-section .item-img').length) return;

            if (!this.sideImageHeight1 && self.$('.side-section .item-img').eq(0)) this.sideImageHeight1 = self.$('.side-section .item-img').eq(0).height();

            if (!this.sideImageHeight2 && self.$('.side-section .item-img').eq(1)) this.sideImageHeight2 = self.$('.side-section .item-img').eq(1).height();

            if (!this.sideImageHeight3 && self.$('.side-section .item-img').eq(2)) this.sideImageHeight3 = self.$('.side-section .item-img').eq(2).height();

            for (var i = 0; i < self.$('.side-section .item-img').length; i++) {
                var varName = 'sideImageHeight' + (i + 1).toString();
                if (this[varName]) {
                    if (this[varName] <= this.$('.side-section-item').eq(i).height()) {
                        this.$('.side-section .item-img').eq(i).addClass('height-priority');
                    } else if (this.$('.side-section .item-img').eq(i).height() >= this.$('.side-section .item-img').eq(i).width()) {
                        this.$('.side-section .item-img').eq(i).addClass('height-priority');
                    } else {
                        this.$('.side-section .item-img').eq(i).removeClass('height-priority');
                    }
                }
            }
        },
        getGaCategory: function getGaCategory() {
            if ($('.result-page').hasClass('shortlist-page')) {
                return Rev.Utils.GaTracking.Category.Shortlist;
            } else if ($('.result-page').hasClass('search-result-page')) {
                return Rev.Utils.GaTracking.Category.SearchResults;
            }
        },
        openEmailAgentModal: function openEmailAgentModal(e) {
            e.preventDefault();
            e.stopPropagation();
            Rev.Utils.showEmailAgentModal(this.model.get('Id'), this.getGaCategory(), this.model.get('Agencies')[0].Name, this.model.get('Agencies')[0].Email, null, this.model.get('Agencies')[0].Id, Rev.Utils.GaTracking.Action.ContactAgent);
        },
        phoneAgent: function phoneAgent(e) {
            e.preventDefault();
            e.stopPropagation();

            if ($('.result-page').hasClass('shortlist-page') || $('.result-page').hasClass('recent-history-page')) {
                this.$('[data-hook="contact-agency-phone-number"]').toggleClass('ready-reveal').toggleClass('reveal');
                this.$('.contact-agency-phone').toggleClass('reveal');
            } else {
                $(e.currentTarget).text(this.model.get('RevealingPhoneNumber'));
            }

            // fire ga event & lead event
            Rev.Utils.LeadTracking.sendPhoneEvent(this.model.get('Id'));

            Rev.trigger('results:ga:fire', Rev.Utils.GaTracking.Action.PhoneAgent, this.model.get('Agencies')[0].Name + ' / ' + this.model.get('Agencies')[0].Id);

            Rev.Utils.GaTracking.trackPhoneAgent(this.model);

            Rev.Utils.Criteo.pushEventAgentContact(this.model.get('Id'));

            Rev.Utils.MatomoTracking.sendEvent(this.model, Rev.Utils.MatomoTracking.Category.ListingLeads, Rev.Utils.MatomoTracking.Action.PhoneReveal);
        },
        onNavPhotoLeftClick: function onNavPhotoLeftClick(e) {
            e.preventDefault();
            e.stopPropagation();
            if (this.slickInstance) {
                this.slickInstance.slick('slickPrev');
            }
        },
        onNavPhotoRightClick: function onNavPhotoRightClick(e) {
            e.preventDefault();
            e.stopPropagation();
            if (this.slickInstance) {
                this.slickInstance.slick('slickNext');
            }
        },
        toggleAgentInfoEmailButton: function toggleAgentInfoEmailButton(isEmailAgentFormShow) {
            if (isEmailAgentFormShow) {
                this.$('[data-hook="agent-info-email"]').addClass('form-opened');
            } else {
                this.$('[data-hook="agent-info-email"]').removeClass('form-opened');
            }
        },
        onResultPageShown: function onResultPageShown() {
            var _this = this;

            if (this.slickInstance) {
                setTimeout(function () {
                    // the original code was just call 'slickGoTo' function, but it sometime did not work especially in firefox, 
                    // so I just changed to initialize all again by calling initSlick function
                    // let's see this change solve problem (2015-12-21, Jay)
                    //this.slickInstance.slick('slickGoTo', 0);
                    if (_this.$('.slick-track').width() === 0) {
                        _this.initSlick();
                    }
                }, 300);
            }
        },
        afterSlick: function afterSlick(event, slick, currentSlide) {
            this.$('[data-hook="photo-counts"]').text('(' + (currentSlide + 1) + '/' + slick.slideCount + ')');

            Rev.Utils.GaTracking.trackGaEvent(this.getGaCategory(), Rev.Utils.GaTracking.Action.ImageGallery, Rev.Utils.GaTracking.Label.Property + this.model.get('Id'));

            Rev.Utils.LeadTracking.sendPhotoEvent(this.model.get('Id'));

            Rev.Utils.MatomoTracking.sendEvent(this.model, Rev.Utils.MatomoTracking.Category.ListingLeads, Rev.Utils.MatomoTracking.Action.SearchResultsCarousel);
        },
        remove: function remove() {
            if (this.mql) {
                this.mql.removeListener(this.handlerOrientationChange);
            }

            if (this.slickInstance) {
                this.slickInstance.slick('unslick');
            }

            this.off();

            //call the superclass remove method
            Backbone.View.prototype.remove.apply(this, arguments);
        }
    });
})(Rev, jQuery, _, Backbone);
'use strict';

// dependencies : Rev, jquery, underscore, Backbone, slick.js

(function (Rev, $, _, Backbone) {

	'use strict';

	Rev.Views.ListResultListView = Backbone.View.extend({
		initialize: function initialize() {
			_.bindAll(this, 'showNextPage', 'applyAnimationOnItem', 'getAllShortlist', 'pullUpList', 'detectPullUpList');

			var itemsData = this.model.get('Items');
			this.collection = new Rev.Collections.ListResults(itemsData);

			// delete all local data of result html
			Rev.Collections.listResultsHtml.fetch();
			_.invoke(Rev.Collections.listResultsHtml.all(), 'destroy');

			this.createListResultsItemView();

			this.listenTo(this.collection, 'add', this.onCollectionAdded);
			this.listenTo(this.collection, 'remove', this.onCollectionRemoved);
			this.listenTo(Rev, 'change:shortlist', this.onShortlistChanged);
			this.listenTo(Rev, 'list-results-item-view:main-photo:loaded', this.pullUpList);
			this.listenTo(Rev, 'matomo:event:email-agent', this.sendEmailAgentMatomoEvent);
			Rev.on('result:shownext', this.showNextPage);

			//this.firstImageLoadListener();
			if ($('[data-hook="listing-item"]').first().find('.item img').length == 0) {
				this.pullUpList();
			}

			this.detectPullUpList();

			// detect user was trying to save search
			this.continueSaveSearch();

			// interim solution to get all shortlist until API supports it
			if ($('.result-page').hasClass('shortlist-page')) {
				this.getAllShortlist();
			}

			new Rev.Views.RevDropdownSortView({
				el: '.dropdown-sort'
			});

			// hide next page button and display text that user reached max page
			if (this.model.get('Pagination') && this.model.get('Pagination').MaxSearchPages === this.model.get('Pagination').CurrentPage) {
				this.$('[data-hook=btn-next-page]').hide();
				this.$('[data-hook="max-page"]').show();
				this.$('.new-search-wrapper').show();
			}

			// criteo 
			var listingdIds = this.collection.pluck('Id');
			Rev.Utils.Criteo.pushEventSearchResults(listingdIds);
		},


		events: {
			'click [data-hook=btn-next-page]': 'onNextPageClick',
			'click [data-hook=btn-join]': 'openSignupModal',
			'click [data-hook="new-search"]': 'openRefineSearch',
			'click [data-hook="btn-search-again"]': 'openRefineSearch',
			'click [data-hook="btn-save-search"]': 'onClickSaveSearch',
			'change .sorting-section [data-hook="dropdown-selected-value"]': 'onSortChange'
		},

		onSortChange: function onSortChange(e) {
			Rev.trigger('sort:changed', e.currentTarget.value); // searchFormView will listen to this event
		},
		sendEmailAgentMatomoEvent: function sendEmailAgentMatomoEvent(model) {
			Rev.Utils.MatomoTracking.sendEvent(model, Rev.Utils.MatomoTracking.Category.ListingLeads, Rev.Utils.MatomoTracking.Action.EmailAgent);
		},
		onClickSaveSearch: function onClickSaveSearch(e) {
			e.preventDefault();

			var authSuccessCallbackForSaveSearch = function authSuccessCallbackForSaveSearch() {
				localStorage.setItem('openSaveSearchWindow', true);
				setTimeout(function () {
					return location.reload(true);
				}, 100);
			};

			Rev.Utils.Auth.isUserAuthenticated().then(function () {
				Rev.Utils.showViewAlertOptionModal();
			}).fail(function () {
				Rev.Utils.showAuthModal('login', null, true, null, authSuccessCallbackForSaveSearch, authSuccessCallbackForSaveSearch);
			});

			Rev.Utils.GaTracking.trackGaEvent(Rev.Utils.GaTracking.Category.SearchResults, Rev.Utils.GaTracking.Action.SaveThisSearch, Rev.Utils.GaTracking.Label.SearchSaved);
		},
		continueSaveSearch: function continueSaveSearch() {
			var openSaveSearchWindow = localStorage.getItem('openSaveSearchWindow');
			if (openSaveSearchWindow) {
				localStorage.removeItem('openSaveSearchWindow');
				Rev.Utils.Auth.isUserAuthenticated().then(function () {
					Rev.Utils.showViewAlertOptionModal();
				}).fail(function () {

					var authSuccessCallbackForSaveSearch = function authSuccessCallbackForSaveSearch() {
						localStorage.setItem('openSaveSearchWindow', true);
						setTimeout(function () {
							return location.reload(true);
						}, 100);
					};

					Rev.Utils.showAuthModal('login', null, true, null, authSuccessCallbackForSaveSearch, authSuccessCallbackForSaveSearch);
				});
			}
		},
		detectLongTopBanner: function detectLongTopBanner() {
			var self = this;
			var trycount = 0;
			var job = setInterval(function () {
				if (self.$('[data-hook="ad-desktop-result-950-60"] iframe').length) {
					self.$('[data-hook="ad-desktop-result-950-60"]').slideDown('slow');
					clearInterval(job);
				}

				if (trycount === 10) {
					// just close after 10 times try
					clearInterval(job);
				}

				trycount++;
			}, 500);
		},
		openRefineSearch: function openRefineSearch(e) {
			e.preventDefault();
			Rev.Utils.openSearchForm();
		},
		openSignupModal: function openSignupModal(e) {
			Rev.Utils.showAuthModal('signup');
		},


		/* Note that this function does not add list item view to the parent list results view because it is already rendered by Razor.
     it just creates backbone view instance in order to handle view events in backbone way */
		createListResultsItemView: function createListResultsItemView() {
			this.collection.each(function (model) {
				new Rev.Views.ListResultsItemView({
					el: '[data-hook="listing-item"][data-id="' + model.get('Id') + '"]',
					model: model
				});

				// This photo count represents the number of photos shown per listing based on their tier
				var photoCount = 1;
				if (model.get('Tier') === 20 || model.get('Tier') === "Featured") photoCount = 3;

				Rev.Utils.MatomoTracking.sendEvent(model, Rev.Utils.MatomoTracking.Category.ListingLeads, Rev.Utils.MatomoTracking.Action.SearchResultsPhotoView, "Count", photoCount);
			});

			this.showShortlistStatus();
		},


		// just in case there is any error, we must show result page in any case
		detectPullUpList: function detectPullUpList() {
			var self = this;
			setTimeout(function () {
				if (!self.$('.listing-items').hasClass('pull-up')) self.pullUpList();
			}, 3000);
		},
		pullUpList: function pullUpList() {
			var _this = this;

			if (!this.isResultLoaded) {
				setTimeout(function () {
					return _this.$('.listing-items').addClass('pull-up');
				}, 10);
				//setTimeout(() => this.$('[data-hook="uyoung-sujin-jay-home"]').hide(), 1000);
				this.applyAnimationOnItem();
				//setTimeout(() => this.detectLongTopBanner(), 1000);
				this.isResultLoaded = true;
			}
		},


		/* 
    NOTE : we don't need this anymore because list_result_ite_view.js will fire 'list-results-item-view:main-photo:loaded' event when main photo is loaded
  */
		//firstImageLoadListener() {
		//  var self = this;

		//  if ($('.list-results-item').first().find('.item-img').length == 0) {
		//    self.pullUpList();
		//  }else{
		//    $('.list-results-item:not(".dummy")').first().find('.item-img').first().one("load", () => {
		//      self.pullUpList();
		//    }).each(function () {
		//      if (self.complete) $(self).load();
		//    });
		//  }
		//},

		applyAnimationOnItem: function applyAnimationOnItem() {
			var _this2 = this;

			var index = 0;
			var length = this.$('.listing-items .list-item-shortlist, .listing-items .list-item-recently-viewed, .btn-next-page-wrap-shortlist').length;
			if (length && length > 0) {
				var task = setInterval(function () {
					_this2.$('.listing-items .list-item-shortlist, .listing-items .list-item-recently-viewed, .btn-next-page-wrap-shortlist').eq(index).addClass('up');
					index++;
					if (index == length) clearInterval(task);
				}, 15);
			}
		},
		onNextPageClick: function onNextPageClick(e) {
			e.preventDefault();
			$(e.currentTarget).button('loading');
			var nextPageUrl = $(e.currentTarget).attr('href');

			/* set replace to true so that url will not be stored in browser history 
      and user can go back to search page from page 2 or 3 or 4 etc,,, rather than back to previous result page */
			if ($('.result-page').hasClass('search-result-page') > -1) {
				Rev.Routers.searchResultRouter.navigate(nextPageUrl, {
					trigger: true,
					replace: true
				});
			} else if ($('.result-page').hasClass('shortlist-page') > -1) {
				Rev.Routers.shortlistRouter.navigate(nextPageUrl, {
					trigger: true,
					replace: true
				});
			}
		},
		getAllShortlist: function getAllShortlist() {
			var self = this;
			var listingUrl = '/properties/shortlist/listings/json/?';
			var nextPageUrl = self.$('[data-hook=btn-next-page]').attr('href');
			var queryString = '';

			if (nextPageUrl && nextPageUrl.indexOf('?') >= 0 && nextPageUrl.length > nextPageUrl.indexOf('?') + 1) {
				queryString = nextPageUrl.substr(nextPageUrl.indexOf('?') + 1);
			}

			var ajaxUrl = listingUrl + queryString;

			if (!nextPageUrl) return;

			setTimeout(function () {
				self.showNextPage(ajaxUrl, self.getAllShortlist);
			}, 600);
		},
		showNextPage: function showNextPage(ajaxUrl, cb) {
			var self = this;

			$.getJSON(ajaxUrl).done(function (result) {
				self.$('[data-hook=btn-next-page]').button('reset');

				var view = result.view;
				var model = result.model;
				var pagination = result.pagination;
				var surroundingSuburbs = result.surroundingSuburbs;

				// #1 append view and show
				self.$('.listing-items').append(view);
				self.applyAnimationOnItem();

				// #2 add collection instances : this will cuase creating view instance in onCollectionAdded method
				_.map(model, function (item) {

					// remove listing item if it is already existing
					var existingListing = self.collection.find(function (oldItem) {
						return oldItem.get('Id') === item.Id;
					});
					if (existingListing) {
						self.$('[data-hook="listing-item"][data-id="' + item.Id + '"]').last().remove();
						console.info('duplicate listing ' + item.Id + ' is deleted');
					} else {
						self.collection.add(item);
					}
				});

				// #3 change link url for get more items button on the bottom of result page
				self.$('[data-hook=btn-next-page]').attr('href', pagination.NextPage.Url);

				// #4 hide get more button and show end of the results if it is the last page
				if (pagination.TotalPages == pagination.CurrentPage) {
					self.$('[data-hook=btn-next-page]').hide();
					self.$('[data-hook="end-of-results"]').show();
					//self.$('.new-search-wrapper').show();
					self.showSurroundingSuburbs(surroundingSuburbs);
				}

				// #4-1 hide next page button and display text that user reached max page
				if (pagination.MaxSearchPages === pagination.CurrentPage) {
					self.$('[data-hook=btn-next-page]').hide();
					self.$('[data-hook="max-page"]').show();
					//self.$('.new-search-wrapper').show();
				}

				// #5 show shortlist status
				setTimeout(function () {
					self.showShortlistStatus();
				}, 100);

				// #6 show only listings close to visible area
				Rev.trigger('list-item-view:viewport:toggle');

				// #7 execute criteo script
				var listingIds = _.pluck(model, 'Id');
				Rev.Utils.Criteo.pushEventSearchResults(listingIds);

				if (cb && pagination.CurrentPage < pagination.TotalPages) cb();
			});
		},
		showSurroundingSuburbs: function showSurroundingSuburbs(surroundingSuburbs) {
			var template = _.template($('#template-surrounding-suburbs').html());
			var html = template({
				surroundingSuburbs: surroundingSuburbs
			});
			$('[data-hook="placeholder-surrounding-suburbs"]').html(html);
		},
		onCollectionAdded: function onCollectionAdded(item) {
			// create sub view instance
			new Rev.Views.ListResultsItemView({
				el: '[data-hook="listing-item"][data-id="' + item.get('Id') + '"]',
				model: item
			});
		},
		onCollectionRemoved: function onCollectionRemoved(model, collection, options) {
			Rev.trigger('list-results-item-view:remove', model.get('Id'));
		},
		showShortlistStatus: function showShortlistStatus() {
			var self = this;
			$.getJSON('/authenticated/').done(function (result) {
				if (result.isAuthenticated) {
					if (!self.$el.hasClass('shortlist-page')) {
						// in shortlist page we don't have to check if this is  shortlisted or not
						self.getShortlistRemote();
					}
				}
			});
		},
		getShortlistRemote: function getShortlistRemote() {
			$.getJSON('/properties/shortlist/ids/json/').done(function (listingIds) {
				Rev.trigger('change:shortlist', listingIds);
			});
		},
		onShortlistChanged: function onShortlistChanged(listingIds) {
			this.$('[data-hook="shortlist-count"]').text(listingIds.length);
		},
		remove: function remove() {
			// TODO : remove sub views      

			this.off();
			this.stopListening();

			//call the superclass remove method
			Backbone.View.prototype.remove.apply(this, arguments);
		}
	});
})(Rev, jQuery, _, Backbone);
'use strict';

// dependencies : Rev, jquery, underscore, Backbone, slick.js

(function (Rev, $, _, Backbone) {

  'use strict';

  Rev.Views.ListResultMapView = Backbone.View.extend({
    initialize: function initialize() {
      var _this = this;

      _.bindAll(this, 'showListings', 'createGroupIcons', 'onMarkerClick', 'openPopup', 'openPopupGroup', 'getMarkerPoint', 'onCollectionAdd', 'onCollectionRemove', 'getNextPage', 'deleteMarker', 'zoomChanged', 'markAsClicked', 'prepareMap', 'onStreetViewVisibleChanged', 'toggleActionButtons');

      Rev.Utils.loadGoogleMapApi(function () {
        _this.prepareMap();
        _this.collection = new Rev.Collections.LatLngItems();
        _this.listenTo(_this.collection, 'add', _this.onCollectionAdd);
        _this.listenTo(_this.collection, 'remove', _this.onCollectionRemove);
        _this.listenTo(Rev, 'matomo:event:email-agent', _this.sendEmailAgentMatomoEvent);
        _this.showListings();
      });

      $('footer').toggleClass('page-footer');
      $('footer').toggleClass('map-footer');

      this.createSubViews();
    },


    events: {
      'click [data-hook="btn-search-as-move"]': 'onBtnSearchAsMoveClick'
    },

    createSubViews: function createSubViews() {
      new Rev.Views.SidebarActionsView({ el: '.result-body-map-view .sidebar-actions', listViewUrl: this.model.get('ListViewUrl') });
    },
    sendEmailAgentMatomoEvent: function sendEmailAgentMatomoEvent(model) {
      Rev.Utils.MatomoTracking.sendEvent(model, Rev.Utils.MatomoTracking.Category.ListingLeads, Rev.Utils.MatomoTracking.Action.EmailAgent);
    },
    onBtnSearchAsMoveClick: function onBtnSearchAsMoveClick(e) {
      $(e.currentTarget).toggleClass('active');
      this.isSearchAsMove = !this.isSearchAsMove;

      if (this.isSearchAsMove) {
        this.searchListingsByGeoBound();
      } else {
        Rev.trigger('search:submit');
      }

      this.toggleActionButtons();

      //Rev.trigger('map:search:bound', this.isSearchAsMove);
    },
    toggleActionButtons: function toggleActionButtons() {
      this.$('.save-searches').toggleClass('disabled');
    },
    showListings: function showListings() {
      if (this.model.get('LatLngItems') && this.model.get('LatLngItems').length > 0) {
        this.collection.set(this.model.get('LatLngItems'));
        this.createGroupIcons();
        this.map.fitBounds(this.bounds);
      } else {
        this.map.setZoom(5);
      }

      //if (parseInt(this.model.get('Pagination').CurrentPage, 10) < parseInt(this.model.get('Pagination').TotalPages, 10)) {
      //  setTimeout(() => this.getNextPage(this.model.get('Pagination').NextPage.Url.split('?')[1], this.model.get('Pagination').NextPage.Value), 500);
      //}
    },
    getNextPage: function getNextPage(nextPageUrlParam, nextPageNum) {
      if (nextPageNum >= 4) return;

      var self = this;
      $.getJSON('/map/search/listings/json/?' + nextPageUrlParam).done(function (listingResult) {
        _.each(listingResult.LatLngItems, function (item) {
          return self.collection.add(new Rev.Models.LatLng(item));
        });
        self.createGroupIcons();
        self.map.fitBounds(self.bounds);

        if (parseInt(listingResult.Pagination.CurrentPage, 10) < parseInt(listingResult.Pagination.TotalPages, 10)) {
          setTimeout(function () {
            return self.getNextPage(listingResult.Pagination.NextPage.Url.split('?')[1], listingResult.Pagination.NextPage.Value);
          }, 1000);
        }
      });
    },
    prepareMap: function prepareMap() {
      var _this2 = this;

      // icon for markers
      this.originalMarkerIconSize = Rev.Utils.isiPad() ? 18 : 12;
      this.scaledMarkerIconSize = Rev.Utils.isiPad() ? 27 : 18;

      this.markerIcon = {
        url: '/assets/content/images/map_dot-marker.png',
        scaledSize: new google.maps.Size(this.originalMarkerIconSize, this.originalMarkerIconSize)
      };

      // icon for listings have the same lat/lng
      this.markerIconGroup = {
        url: '/assets/content/images/map_dot-marker_multiple.png',
        scaledSize: new google.maps.Size(this.originalMarkerIconSize, this.originalMarkerIconSize)
      };

      var container = this.$('.map-canvas');
      if (!container) return;

      this.bounds = new google.maps.LatLngBounds();

      // center lat/lng data
      var center = new google.maps.LatLng(this.model.get('Center').Lat, this.model.get('Center').Lng);

      // map option
      var mapOptions = {
        center: center,
        zoom: 14, // suburb zoom level (note that it can be different depend on browser size, but "this.map.fitBounds()" below will zoom to show all markers
        mapTypeControl: true,
        mapTypeControlOptions: { position: google.maps.ControlPosition.BOTTOM_CENTER },
        panControl: true,
        streetViewControl: true
      };

      // create map object
      this.map = new google.maps.Map(container.get(0), mapOptions);

      // create street view
      this.panorama = this.map.getStreetView();
      this.panorama.setOptions({
        addressControlOptions: {
          position: google.maps.ControlPosition.BOTTOM_CENTER
        },
        linksControl: false,
        panControl: false,
        enableCloseButton: true
      });
      this.panorama.setVisible(false);
      this.panorama.addListener('visible_changed', this.onStreetViewVisibleChanged);

      // create views for popup
      this.popup = new Rev.Views.MapPopupView();
      this.popupGroup = new Rev.Views.MapPopupGroupView();

      // attach events on the map
      google.maps.event.addListener(this.map, 'dragstart', function () {
        _this2.popup.close();
        _this2.popupGroup.close();
      });

      google.maps.event.addListener(this.map, 'click', function () {
        _this2.popup.close();
        _this2.popupGroup.close();
      });

      google.maps.event.addListener(this.map, 'dragend', function () {
        _this2.searchListingsByGeoBound();
      });

      google.maps.event.addListener(this.map, 'zoom_changed', function () {
        _this2.zoomChanged();
      });

      // array for markers
      this.markerArray = [];
    },
    onStreetViewVisibleChanged: function onStreetViewVisibleChanged() {
      if (!this.panorama) return;

      if (this.panorama.getVisible()) {
        this.$('[data-hook="btn-search-as-move"]').hide();
        if (this.popup) this.popup.close();
        if (this.popupGroup) this.popupGroup.close();
      } else {
        this.$('[data-hook="btn-search-as-move"]').show();
      }
    },
    searchListingsByGeoBound: function searchListingsByGeoBound() {
      if (!this.isSearchAsMove) return;

      var self = this;

      $('.map-loading').addClass('fire');

      var latLngBounds = this.map.getBounds();

      var param = {
        nwlat: latLngBounds.getNorthEast().lat(),
        nwlng: latLngBounds.getSouthWest().lng(),
        selat: latLngBounds.getSouthWest().lat(),
        selng: latLngBounds.getNorthEast().lng(),
        smt: this.model.get('SearchForm').SearchMenuType
      };

      //console.log(`nw-lat:${param.nwlat}, nw-lng:${param.nwlng}, se-lat:${param.selat}, se-lng:${param.selng}`);

      $.getJSON('/map/search/listings/bound/json/', param).done(function (result) {
        self.collection.set(result.LatLngItems);
        self.createGroupIcons();
      }).always(function () {
        return $('.map-loading').removeClass('fire');
      });
    },
    onCollectionAdd: function onCollectionAdd(item, collection, options) {
      var self = this;

      if (item.get('Lat') && item.get('Lng')) {
        var LatLng = new google.maps.LatLng(item.get('Lat'), item.get('Lng'));

        // extend map bounds in order to zoom to fit all markers
        self.bounds.extend(LatLng);

        // create marker for each listing
        var marker = new google.maps.Marker({
          position: LatLng,
          map: self.map,
          icon: self.markerIcon,
          //title: item.get('ListingId') + ' ' + item.get('Lat') + ' ' + item.get('Lng'),
          listingId: item.get('ListingId')
        });

        self.markerArray.push(marker);
        //console.log('markerArray.length', self.markerArray.length);

        // attach events on marker
        google.maps.event.addListener(marker, 'click', function (e) {
          self.onMarkerClick(marker, self, e);
        });

        // attach hover events on marker only for none-ie browsers, ie has a bug with mouseover event
        if (navigator.userAgent.indexOf('MSIE') == -1 && navigator.userAgent.indexOf('Trident') == -1) {
          google.maps.event.addListener(marker, 'mouseover', function (e) {
            self.onMouseoverMarker(marker, self, e);
          });

          google.maps.event.addListener(marker, 'mouseout', function (e) {
            self.onMouseoutMarker(marker, self, e);
          });
        }
      }
    },
    onCollectionRemove: function onCollectionRemove(model, collection, options) {
      var self = this;
      var markers = _.filter(this.markerArray, function (marker) {
        if (marker.isGroupMarker) {
          return marker.listingIds.indexOf(model.get('ListingId')) > -1;
        } else {
          return marker.listingId == model.get('ListingId');
        }
      });

      _.each(markers, function (marker) {
        return self.deleteMarker(marker);
      });
    },
    deleteMarker: function deleteMarker(marker) {
      if (!marker) return;

      // remove marker from the map
      marker.setMap(null);

      // remove marker from the array
      var index = _.indexOf(this.markerArray, marker);
      if (index > -1) this.markerArray.splice(index, 1);

      //console.log('markerArray.length', this.markerArray.length);
    },
    createGroupIcons: function createGroupIcons() {
      var self = this;

      var objGroupBy = this.collection.groupBy(function (item) {
        if (item.get('ListingId') && item.get('Lat') && item.get('Lng')) {
          return item.get('Lat').toString() + item.get('Lng').toString();
        }
      });

      var filtered = _.filter(objGroupBy, function (item) {
        return item.length > 1;
      });

      _.each(filtered, function (itemGroup) {
        if (itemGroup[0].get('Lat') && itemGroup[0].get('Lng')) {
          var marker = new google.maps.Marker({
            position: new google.maps.LatLng(itemGroup[0].get('Lat'), itemGroup[0].get('Lng')),
            map: self.map,
            icon: self.markerIconGroup,
            isGroupMarker: true,
            listingIds: _.map(itemGroup, function (item) {
              return item.get('ListingId');
            })
            //title: _.map(itemGroup, (item) => `${item.get('ListingId')} ${item.get('Lat')} ${item.get('Lng')}`).join(', ')
          });

          self.markerArray.push(marker);

          // attach events on marker
          google.maps.event.addListener(marker, 'click', function (e) {
            self.onMarkerClick(marker, self, e);
          });

          // attach hover events on marker only for none-ie browsers, ie has a bug with mouseover event
          if (navigator.userAgent.indexOf('MSIE') == -1 && navigator.userAgent.indexOf('Trident') == -1) {
            //google.maps.event.addListener(marker, 'mouseover', this.onMouseoverMarker);
            google.maps.event.addListener(marker, 'mouseover', function (e) {
              self.onMouseoverMarker(marker, self, e);
            });

            google.maps.event.addListener(marker, 'mouseout', function (e) {
              self.onMouseoutMarker(marker, self, e);
            });
          }

          // delete markers that are participated in group marker
          _.each(itemGroup, function (item) {
            var singleMarker = _.find(self.markerArray, function (marker) {
              return !marker.isGroupMarker && item.get('ListingId') == marker.listingId;
            });
            self.deleteMarker(singleMarker);
          });
        }
      });
    },
    onMouseoverMarker: function onMouseoverMarker(marker, listResultMapView, e) {
      var icon = marker.getIcon();
      icon.size = icon.scaledSize = new google.maps.Size(this.scaledMarkerIconSize, this.scaledMarkerIconSize);
      marker.setIcon(icon);
    },
    onMouseoutMarker: function onMouseoutMarker(marker, listResultMapView, e) {
      var icon = marker.getIcon();
      icon.size = icon.scaledSize = new google.maps.Size(this.originalMarkerIconSize, this.originalMarkerIconSize);
      marker.setIcon(icon);
    },
    onMarkerClick: function onMarkerClick(marker, listResultMapView, e) {
      if (marker.isGroupMarker) {
        this.openPopupGroup(marker, e);
      } else {
        this.openPopup(marker, e);
      }

      this.markAsClicked(marker);
    },
    markAsClicked: function markAsClicked(marker) {
      var visitedUrl = marker.isGroupMarker ? '/assets/content/images/map_dot-marker_multiple_visited.png' : '/assets/content/images/map_dot-marker_visited.png';
      var icon = marker.getIcon();
      icon.url = visitedUrl;
      marker.setIcon(icon);
    },
    zoomChanged: function zoomChanged() {
      this.searchListingsByGeoBound();

      this.popup.close();
      this.popupGroup.close();
    },
    getMarkerPoint: function getMarkerPoint(marker) {
      var scale = Math.pow(2, this.map.getZoom());
      var nw = new google.maps.LatLng(this.map.getBounds().getNorthEast().lat(), this.map.getBounds().getSouthWest().lng());
      var worldCoordinateNW = this.map.getProjection().fromLatLngToPoint(nw);
      var worldCoordinate = this.map.getProjection().fromLatLngToPoint(marker.getPosition());
      var markerPoint = new google.maps.Point(Math.floor((worldCoordinate.x - worldCoordinateNW.x) * scale), Math.floor((worldCoordinate.y - worldCoordinateNW.y) * scale));

      return markerPoint;
    },
    openPopup: function openPopup(marker, e) {
      // #1 calcuate marker's position in pixel
      var markerPoint = this.getMarkerPoint(marker);

      // #2 prepare variables
      var distancePanTop = ''; // distance to move top direction
      var arrowX = markerPoint.x - 10;
      var popupWidth = parseInt(this.popup.$el.width(), 10);
      var popupHeight = parseInt(this.popup.$el.height(), 10);
      var canvasHeight = parseInt(this.$('.map-canvas').height(), 10);
      var canvasWidth = parseInt(this.$('.map-canvas').width(), 10);

      // left/top point of popup
      var x = markerPoint.x - popupWidth / 2;
      var y = markerPoint.y - popupHeight - 30; // - headerHeight - 20;   // 20 is just buffer      

      // if popup is located outside of viewable area to top direction
      if (y < 0) {
        var distance = y - 40;
        distancePanTop = distance;
        y = 40;
      }

      // if popup is located outside of viewable area to down direction
      //if (y + popupHeight > canvasHeight) {
      //  var distance = y + popupHeight - canvasHeight + 10 ;
      //  this.map.panBy(0, distance);
      //  y = y - distance;
      //}

      // if popup is located outside of viewable area to right direction
      if (x + popupWidth > canvasWidth) {
        var buffer = 20;
        x = canvasWidth - popupWidth - buffer;
        arrowX -= buffer - 20;
      }

      // if popup is located outside of viewable area to left direction
      if (x < 0) {
        x = 10;
      }

      this.popup.open({
        x: x,
        y: y,
        listingId: marker.listingId,
        arrowX: arrowX
      });
      this.popupGroup.close();

      if (distancePanTop) {
        this.map.panBy(0, distancePanTop);
      }
    },
    openPopupGroup: function openPopupGroup(marker, e) {
      // #0 prepare variables
      var shouldPanX = '';
      var popupWidth = parseInt(this.popupGroup.$el.width(), 10);
      var canvasWidth = parseInt(this.$('.map-canvas').width(), 10);
      var canvasHeight = parseInt(this.$('.map-canvas').height(), 10);

      // #1 calcuate marker's position in pixel
      var markerPoint = this.getMarkerPoint(marker);

      // #2 calculate x
      var x = markerPoint.x + 20; // 20 is distance between mouse pointer and x of popup

      // if popup is located outside of viewable area to right direction
      if (markerPoint.x + popupWidth + 30 > canvasWidth) {
        var distance = markerPoint.x + popupWidth - canvasWidth + 50;
        shouldPanX = distance;
        x = x - distance;
      }

      // #3 calculate y
      // #3-1 locate popup vertically middle
      var top, bottom;
      var addressHeight = 40; // height of '.map-popup-group .address'
      var listingItemsHeight = 240 * marker.listingIds.length; // 240 is height of .listing-item      
      var marginHeight = 10 * (marker.listingIds.length + 1);
      var headerHeight = parseInt($('#layout-header').outerHeight(), 10) + parseInt($('.search-summary').outerHeight(), 10);
      var arrowY = markerPoint.y + headerHeight - 18;

      if (addressHeight + listingItemsHeight + marginHeight > canvasHeight) {
        // if popup's height is taller than canvas
        top = 25;
        bottom = 20;
      } else {
        // position popup vertically middle
        top = (canvasHeight - (addressHeight + listingItemsHeight + marginHeight)) / 2;
        bottom = (canvasHeight - (addressHeight + listingItemsHeight + marginHeight)) / 2 - 1; // 1 is just buffer
      }

      // #3-2 adjust Y position if popup is too far from the marker      
      var mouseY = markerPoint.y - headerHeight;
      var yFromTopOfPopup = top + addressHeight + listingItemsHeight + marginHeight;

      if (markerPoint.y < top) {
        // this means mouse pointer position is out of popup to the top direction in Y axis
        var distance = top - markerPoint.y + 30;
        top -= distance;
        bottom += distance;
      }

      if (markerPoint.y > yFromTopOfPopup) {
        // this means mouse pointer position is out of popup to the bottom direction in Y axis
        var distance = markerPoint.y - yFromTopOfPopup + 30;
        top += distance;
        bottom -= distance;
      }

      this.popupGroup.open({
        x: x,
        top: top,
        bottom: bottom,
        listingIds: marker.listingIds,
        arrowY: arrowY
      });
      this.popup.close();

      if (shouldPanX) {
        this.map.panBy(shouldPanX, 0);
      }
    },
    resizeMap: function resizeMap() {
      if (this.map) {
        var center = this.map.getCenter();
        google.maps.event.trigger(this.map, 'resize');
        this.map.setCenter(center);
      }
    },
    remove: function remove() {
      this.popup.remove();
      this.popupGroup.remove();

      if (this.markerArray.length) {
        for (var i = 0; i < this.markerArray.length; i++) {
          this.markerArray[i].setMap(null);
        }
        this.markerArray = [];
      }

      this.off();
      this.stopListening();

      //call the superclass remove method
      Backbone.View.prototype.remove.apply(this, arguments);
    }
  });
})(Rev, jQuery, _, Backbone);
'use strict';

// dependencies : Rev, jquery, underscore, backbone, slick.js

(function (Rev, $, _, Backbone) {

  'use strict';

  Rev.Views.ListResultSidebarView = Backbone.View.extend({
    el: '.result-body-list-view .sidebar',

    initialize: function initialize() {
      _.bindAll(this, 'onResultPageShown', 'initSlick', 'afterSlick', 'sendTopSpotImpressionEvent', 'pauseAutoPlay', 'resumeAutoPlay', 'afterSwipe');

      this.initSlick();

      // trigger impression topspot lead event for the first listing
      this.sendTopSpotImpressionEvent();

      this.listenTo(Rev, 'result:page:shown', this.onResultPageShown);

      if (!Rev.IsPhone) {
        this.$(".sticky-section").sticky({ topSpacing: 70, zIndex: 1 });
      }

      this.createSubViews();

      this.$(".stickyItem").stick_in_parent({ offset_top: 80 });
    },


    impressionTriggeredListings: [],

    events: {
      'click [data-hook="move-to-details-page"]': 'onListingClick',
      'click ul.slick-dots li button': 'onDotClick',
      'mouseenter .local-expert-slider .listing': 'onMouseEnterListing',
      'mouseleave .local-expert-slider .listing': 'onMouseLeaveListing'
      // Sales team did not accept following solution
      //'sticky-start .sticky-section' : 'onStickyStart',
      //'sticky-end .sticky-section' : 'onStickyEnd'
    },

    onStickyStart: function onStickyStart() {
      this.$('.sticky-section').addClass('small');
    },
    onStickyEnd: function onStickyEnd() {
      this.$('.sticky-section').removeClass('small');
    },


    //onResultPageShown() {
    //    if (this.slickInstance) {
    //        setTimeout(() => this.slickInstance.slick('slickGoTo', 0), 100);
    //    }
    //},


    onResultPageShown: function onResultPageShown() {
      var _this = this;

      if (this.slickInstance) {
        setTimeout(function () {
          if (_this.$('.slick-track').width() === 0) {
            _this.initSlick();
          }
        }, 300);
      }
    },
    createSubViews: function createSubViews() {
      new Rev.Views.SidebarActionsView({ el: '.result-body-list-view .sidebar', listViewUrl: this.model.get('ListViewUrl') });
    },
    onMouseEnterListing: function onMouseEnterListing(e) {
      this.pauseAutoPlay(false);
    },
    onMouseLeaveListing: function onMouseLeaveListing(e) {
      // if phone number is showing, don't resume auto play
      if (!this.$('.contact-agency-phone').hasClass('reveal')) {
        this.resumeAutoPlay();
      }
    },
    onDotClick: function onDotClick(e) {
      this.pauseAutoPlay(true);
    },
    pauseAutoPlay: function pauseAutoPlay(permanentStop) {
      if (!this.permanentStop) // if permanentStop is true, don't change it
        this.permanentStop = permanentStop;

      if (this.slickInstance) {
        this.slickInstance.slick('slickPause');
      }
    },
    resumeAutoPlay: function resumeAutoPlay() {
      if (this.slickInstance && !this.permanentStop) {
        this.slickInstance.slick('slickPlay');
      }
    },
    onListingClick: function onListingClick(e) {
      // trigger topspot listing click lead event
      var listingId = this.$('.listing.slick-current.slick-active').attr('data-id');
      var topSpotId = this.$('.local-expert').attr('data-topspot-id');
      Rev.Utils.LeadTracking.sendTopSpotClickEvent(listingId, topSpotId);
    },
    initSlick: function initSlick() {
      var self = this;
      if (self.slickInstance) {
        self.slickInstance.slick('unslick');
      }

      if (self.$('.local-expert-slider').hasClass('slick-initialized')) return;

      self.slickInstance = Rev.Utils.initSlick(self.$('.local-expert-slider'), {
        centerPadding: '0px',
        fade: true,
        dots: true,
        autoplay: true,
        autoplaySpeed: 5000,
        pauseOnHover: false,
        pauseOnDotsHover: false,
        pauseOnFocus: false
      });
      self.slickInstance.on('afterChange', self.afterSlick).on('swipe', self.afterSwipe);
    },
    sendTopSpotImpressionEvent: function sendTopSpotImpressionEvent() {
      var listingId = this.$('.listing.slick-current.slick-active').attr('data-id');
      var topSpotId = this.$('.local-expert-panel').attr('data-topspot-id');

      if (listingId && topSpotId) {
        // trigger impression event only one time
        if (_.indexOf(this.impressionTriggeredListings, listingId) < 0) {
          Rev.Utils.LeadTracking.sendTopSpotImpressionEvent(listingId, topSpotId);
          this.impressionTriggeredListings.push(listingId);
        }
      }
    },
    afterSlick: function afterSlick(event, slick, currentSlide) {
      //this.$('[data-hook="photo-counts"]').text('(' + (currentSlide + 1) + '/' + slick.slideCount + ')');
      //var agencyPhone = this.$('.listing.slick-current.slick-active').attr('data-agency-phone');
      //this.$('[data-hook="contact-agency-phone-number"] span').text(agencyPhone);
      this.sendTopSpotImpressionEvent();
    },
    afterSwipe: function afterSwipe(event, slick, direction) {
      this.pauseAutoPlay(true);
    },
    remove: function remove() {
      if (this.slickInstance) {
        this.slickInstance.slick('unslick');
      }

      this.off();

      //call the superclass remove method
      Backbone.View.prototype.remove.apply(this, arguments);
    }
  });
})(Rev, jQuery, _, Backbone);
'use strict';

// dependencies : Rev, jquery, underscore, Backbone, slick.js

(function (Rev, $, _, Backbone) {

	'use strict';

	Rev.Views.ListResultsView = Backbone.View.extend({
		el: '.result-page',

		initialize: function initialize(options) {
			var options = options || {};
			this.resultViewMode = options.resultViewMode;
			this.isSuburbRequired = options.isSuburbRequired;

			_.bindAll(this, 'showView', 'hideView', 'fireGaEvent');

			// NO MORE NEED
			// create view for header region
			//this.headerView = new Rev.Views.ListResultHeaderView({el: '.nav-search', model: this.model, isSuburbRequired: this.isSuburbRequired });
			// create view for search form
			var searchFormData = this.model.get('SearchForm');
			var searchFormModel = new Rev.Models.SearchForm(searchFormData);
			this.searchFormView = new Rev.Views.SearchFormView({ el: this.$('.nav-search'), model: searchFormModel, isRefineSearch: true, isSuburbRequired: this.isSuburbRequired });

			// create view for sidebar region
			this.sidebarView = new Rev.Views.ListResultSidebarView({ model: this.model });

			if (this.resultViewMode === 'mapview') {
				// create view for map view region
				this.mapView = new Rev.Views.ListResultMapView({ el: '.result-body-map-view', model: this.model });
			} else if (!this.resultViewMode || this.resultViewMode === 'listview') {
				this.listView = new Rev.Views.ListResultListView({ el: '.result-body-list-view', model: this.model });
			}

			this.listenTo(Rev, 'result:page:show', this.showView);
			this.listenTo(Rev, 'result:page:hide', this.hideView);
			this.listenTo(Rev, 'results:ga:fire', this.fireGaEvent);

			// make top header menu active (buy, rent, sold), header_view.js will listen this event
			if (this.model.get('SearchForm') && this.model.get('SearchForm').SearchMenuTypeText) {
				Rev.trigger('search-menu-type', this.model.get('SearchForm').SearchMenuTypeText);
			}

			if (!Rev.IsPhone) {
				this.$(".nav-search").sticky({ topSpacing: 0, zIndex: 3 });
			}
		},
		fireGaEvent: function fireGaEvent(action, label) {
			var category = '';

			if (this.$el.hasClass('search-result-page')) {
				category = Rev.Utils.GaTracking.Category.SearchResults;
			} else if (this.$el.hasClass('shortlist-page')) {
				category = Rev.Utils.GaTracking.Category.Shortlist;
			}

			Rev.Utils.GaTracking.trackGaEvent(category, action, label);
		},
		onTouchstart: function onTouchstart(e) {
			this.startY = e.originalEvent.targetTouches[0].pageY; //e.pageY;
			//console.log('touch-start', this.startY);
		},
		onTouchmove: function onTouchmove(e) {
			this.endY = e.originalEvent.targetTouches[0].pageY; //e.pageY;
			//console.log('touch-move', this.endY);
		},
		onTouchend: function onTouchend(e) {
			//console.log('touch-end', e);
			var diff = this.endY - this.startY;
			//console.log(diff);

			if (diff > 0) {
				//console.log('up');
				$('#layout-body').removeClass('no-show');
			} else if (diff < 0) {
				//console.log('down');
				$('#layout-body').addClass('no-show');
			}
		},
		showView: function showView(e) {
			this.$el.show();
			Rev.trigger('result:page:shown');
		},
		hideView: function hideView(e) {
			this.$el.hide();
			Rev.trigger('result:page:hidden');
		},
		remove: function remove() {
			$(window).off('scroll');

			this.headerView.remove();
			if (this.listView) this.listView.remove();
			if (this.mapView) this.mapView.remove();

			this.off();
			this.stopListening();

			//call the superclass remove method
			Backbone.View.prototype.remove.apply(this, arguments);
		}
	});
})(Rev, jQuery, _, Backbone);
'use strict';

// dependencies : Rev, jquery, underscore, backbone, slick.js

(function (Rev, $, _, Backbone) {

  'use strict';

  Rev.Views.ListingBoxView = Backbone.View.extend({
    initialize: function initialize(options) {
      _.bindAll(this, 'onShortlistChanged', 'shortlistRemote', 'afterSlick', 'onResultPageShown', 'mainPhotoImageLoad', 'adjustMainImageSize');

      //if (this.model.get('Photos').length > 1 ) {
      this.slickInstance = Rev.Utils.initSlick(this.$('.photo-carousel'), { centerPadding: '0px', fade: true, lazyLoad: 'ondemand' });
      this.slickInstance.on('afterChange', this.afterSlick); //.on('swipe', this.onPhotoSwipe);
      //}      

      this.listenTo(Rev, 'change:shortlist', this.onShortlistChanged); // listen shortlist changed
      this.listenTo(Rev, 'result:page:shown', this.onResultPageShown);

      // image resizing
      this.mainImageHeights = [];
      this.$('.photo-carousel .item-img').load(this.mainPhotoImageLoad);
    },

    events: {
      'click [data-hook="toggle-shortlist"]': 'onToggleShortlistClick',
      'click [data-hook="nav-photo-left"]': 'onNavPhotoLeftClick',
      'click [data-hook="nav-photo-right"]': 'onNavPhotoRightClick',
      'click': 'onClickView'
    },

    getListingCategory: function getListingCategory() {
      if (this.model.get('Status').AvailabilityType === 1) {
        return Rev.Utils.GaTracking.Category.PropertySold;
      }

      if (this.model.get('Status').ContractType === 0) {
        return Rev.Utils.GaTracking.Category.PropertyBuy;
      }

      if (this.model.get('Status').ContractType === 1) {
        return Rev.Utils.GaTracking.Category.PropertyRent;
      }
    },
    onClickView: function onClickView(e) {
      if (this.$el.hasClass('agency-properties-item')) {
        Rev.Utils.GaTracking.trackGaEvent(this.getListingCategory(), Rev.Utils.GaTracking.Action.OtherPropertiesAgency, '' + Rev.Utils.GaTracking.Label.Property + this.model.get('Id'));
      } else if (this.$el.hasClass('related-item')) {
        Rev.Utils.GaTracking.trackGaEvent(this.getListingCategory(), Rev.Utils.GaTracking.Action.PropertiesYouMayLike, '' + Rev.Utils.GaTracking.Label.Property + this.model.get('Id'));
      }
    },
    mainPhotoImageLoad: function mainPhotoImageLoad(event) {
      var self = this;

      // #1 clear all image heights info
      if (self.mainImageHeights) self.mainImageHeights.length = 0;

      // #2 save all image heights info again
      self.$('.photo-carousel .item-img').each(function (index, element) {
        if (element.src) {
          var img = {};
          img.src = element.src.replace(/^http:|^https:/i, '');
          img.height = self.$(element).height();
          img.width = self.$(element).width();

          if (!_.find(self.mainImageHeights, function (img) {
            return img.src == element.src;
          }) && img.height) {
            // save info only when height is greater than 0 and no previous info saved
            self.mainImageHeights.push(img);
          }
        }
      });

      self.adjustMainImageSize();
    },
    adjustMainImageSize: function adjustMainImageSize() {
      var self = this;

      if (self.mainImageHeights) {
        var containerHeight = self.$('.photo-carousel').height();

        _.each(self.mainImageHeights, function (imgInfo) {
          if (imgInfo.height <= containerHeight || imgInfo.height >= imgInfo.width) {
            self.$('.photo-carousel .item-img[src="' + imgInfo.src + '"]').addClass('height-priority');
          } else {
            self.$('.photo-carousel .item-img[src="' + imgInfo.src + '"]').removeClass('height-priority');
          }
        });
      }
    },
    onNavPhotoLeftClick: function onNavPhotoLeftClick(e) {
      e.preventDefault();
      e.stopPropagation();
      if (this.slickInstance) {
        this.slickInstance.slick('slickPrev');
      }
    },
    onNavPhotoRightClick: function onNavPhotoRightClick(e) {
      e.preventDefault();
      e.stopPropagation();
      if (this.slickInstance) {
        this.slickInstance.slick('slickNext');
      }
    },


    onToggleShortlistClick: function onToggleShortlistClick(e) {
      var _this = this;

      if (e && e.preventDefault) e.preventDefault();
      if (e && e.stopPropagation) e.stopPropagation();

      $.getJSON('/authenticated/').done(function (result) {
        if (result.isAuthenticated) {
          _this.shortlistRemote();
        } else {
          var authSuccessCallbackForSaveSearch = function authSuccessCallbackForSaveSearch() {
            localStorage.setItem('saveListing', _this.model.get('Id'));
            setTimeout(function () {
              return location.reload(true);
            }, 100);
          };

          Rev.Utils.showAuthModal('signup', true, null, null, authSuccessCallbackForSaveSearch, authSuccessCallbackForSaveSearch);
        }
      });

      // fire ga event
      if (!this.$('[data-hook="toggle-shortlist"]').hasClass('checked')) {
        if (this.$el.hasClass('agency-properties-item')) {
          Rev.Utils.GaTracking.trackGaEvent(this.getListingCategory(), Rev.Utils.GaTracking.Action.ShortlistOtherProperty, '' + Rev.Utils.GaTracking.Label.Property + this.model.get('Id'));
        } else if (this.$el.hasClass('related-item')) {
          Rev.Utils.GaTracking.trackGaEvent(this.getListingCategory(), Rev.Utils.GaTracking.Action.ShortlistPropertiesYouMayLike, '' + Rev.Utils.GaTracking.Label.Property + this.model.get('Id'));
        }
      }
    },

    // shortlist into database
    shortlistRemote: function shortlistRemote() {
      var self = this;
      $.post('/properties/shortlist/', { listingId: self.model.get('Id') }).done(function (result) {
        if (result.status == 201) {
          // shortlisted
          Rev.trigger('change:shortlist', result.listingIds);

          // lead event for shortlist
          Rev.Utils.LeadTracking.sendShortlistEvent(self.model.get('Id'));
        } else if (result.status == 306) {
          // un-shortlisted
          Rev.trigger('change:shortlist', result.listingIds);
        } else {
          alert('Sorry, we were unable to shortlist.');
        }
      }).fail(function (result) {
        console.error(result);
        alert('Sorry, we were unable to shortlist.');
      });
    },

    onShortlistChanged: function onShortlistChanged(listingIds) {
      if (_.indexOf(listingIds, this.model.get('Id')) > -1) {
        this.$('[data-hook="toggle-shortlist"]').addClass('checked');
      } else {
        this.$('[data-hook="toggle-shortlist"]').removeClass('checked');
      }
    },

    onResultPageShown: function onResultPageShown() {
      var _this2 = this;

      if (this.slickInstance) {
        setTimeout(function () {
          return _this2.slickInstance.slick('slickGoTo', 0);
        }, 10);
      }
    },
    afterSlick: function afterSlick(event, slick, currentSlide) {
      // fire ga event
      if (!this.isGaFired) {
        if (this.$el.hasClass('agency-properties-item')) {
          Rev.Utils.GaTracking.trackGaEvent(this.getListingCategory(), Rev.Utils.GaTracking.Action.ImageGalleryOtherProperty, '' + Rev.Utils.GaTracking.Label.Property + this.model.get('Id'));
          this.isGaFired = true;
        } else if (this.$el.hasClass('related-item')) {
          Rev.Utils.GaTracking.trackGaEvent(this.getListingCategory(), Rev.Utils.GaTracking.Action.ImageGalleryPropertiesYouMayLike, '' + Rev.Utils.GaTracking.Label.Property + this.model.get('Id'));
          this.isGaFired = true;
        }
      }

      Rev.Utils.LeadTracking.sendPhotoEvent(this.model.get('Id'));
    },


    //onPhotoSwipe: function (event, slick, direction) {
    //  // fire ga event
    //  if (!this.isGaFired) {
    //    Rev.Utils.GaTracking.trackGaEvent(
    //      Rev.Utils.GaTracking.Category.Property,
    //      Rev.Utils.GaTracking.Action.ImageGallery,
    //      Rev.Utils.GaTracking.Label.Property + this.model.get('Id'));
    //    this.isGaFired = true;
    //  }

    //  // fire lead tracking event
    //  if (!this.isPhotoTrackingFired) {
    //    Rev.Utils.LeadTracking.sendPhotoEvent(this.model.get('Id'));
    //    this.isPhotoTrackingFired = true;
    //  }
    //},

    remove: function remove() {
      if (this.slickInstance) {
        this.slickInstance.slick('unslick');
      }

      this.off();

      //call the superclass remove method
      Backbone.View.prototype.remove.apply(this, arguments);
    }

  });
})(Rev, jQuery, _, Backbone);
'use strict';

// dependencies : Rev, jquery, underscore, backbone, slick.js

(function (Rev, $, _, Backbone) {

  'use strict';

  Rev.Views.ListingSidebar = Backbone.View.extend({
    el: '.listing-property-sidebar',

    initialize: function initialize() {
      this.initListeners();
    },


    events: {
      'click [data-hook="btn-print"]': 'onPrintClick',
      'click [data-hook="btn-share"]': 'onShareClick',
      'click [data-hook="share-fb"]': 'onShareFBClick',
      'click [data-hook="share-twitter"]': 'onShareTwitterClick',
      'click [data-hook="close-share-lightbox"]': 'onCloseShareLightbox',
      'click [data-hook="share-friend"]': 'onShareFriendClick',
      'click [ data-hook="contact-agency"]': 'contactAgency'
    },

    initListeners: function initListeners() {
      this.listenTo(Rev, 'photo:modal:shown', this.hideView);
      this.listenTo(Rev, 'photo:modal:hidden', this.reinitializeView);
    },
    contactAgency: function contactAgency(e) {
      Rev.Utils.MatomoTracking.sendEvent(this.model, Rev.Utils.MatomoTracking.Category.ListingLeads, Rev.Utils.MatomoTracking.Action.AgencyProfile);
    },
    onPrintClick: function onPrintClick(e) {
      e.preventDefault();
      e.stopPropagation();
      var url = this.model.get('BrochureUrl');
      window.open(url, '_blank');

      Rev.Utils.GaTracking.trackGaEvent(this.model.get('GaEventCategory'), Rev.Utils.GaTracking.Action.PrintBrochure, Rev.Utils.GaTracking.Label.Property + this.model.get('Id'));

      Rev.Utils.MatomoTracking.sendEvent(this.model, Rev.Utils.MatomoTracking.Category.ListingLeads, Rev.Utils.MatomoTracking.Action.PrintBrochure);
    },
    onShareClick: function onShareClick(e) {
      this.$('[data-hook="lightbox-share"]').toggleClass('show');
    },
    onShareFBClick: function onShareFBClick(e) {
      FB.ui({
        method: 'share',
        href: window.location.href
      }, function (response) {});

      // fire ga event
      Rev.Utils.GaTracking.trackGaEvent(this.model.get('GaEventCategory'), Rev.Utils.GaTracking.Action.ShareViaFacebook, Rev.Utils.GaTracking.Label.ShareFacebook + this.model.get('Id'));

      Rev.Utils.MatomoTracking.sendEvent(this.model, Rev.Utils.MatomoTracking.Category.ListingLeads, Rev.Utils.MatomoTracking.Action.Share, Rev.Utils.MatomoTracking.Name.Facebook);
    },
    onShareTwitterClick: function onShareTwitterClick(e) {
      var contractType = '';
      if (this.model.get('ContractType') == 0) {
        contractType = 'Sale';
      } else {
        contractType = 'Rent';
      }

      var preSelectedText = this.model.get('AddressText') + ' - ' + this.model.get('PropertyTypes') + ' For ' + contractType + ' by ' + this.model.get('AgencyName');
      var tweetUrl = 'https://twitter.com/intent/tweet?text=' + encodeURIComponent(preSelectedText) + '&url=' + encodeURIComponent(window.location.href);

      Rev.Utils.PopupWindow(tweetUrl);

      // fire ga event
      Rev.Utils.GaTracking.trackGaEvent(this.model.get('GaEventCategory'), Rev.Utils.GaTracking.Action.ShareViaTwitter, Rev.Utils.GaTracking.Label.ShareTwitter + this.model.get('Id'));

      Rev.Utils.MatomoTracking.sendEvent(this.model, Rev.Utils.MatomoTracking.Category.ListingLeads, Rev.Utils.MatomoTracking.Action.Share, Rev.Utils.MatomoTracking.Name.Twitter);
    },
    onShareFriendClick: function onShareFriendClick(e) {
      if (this.model.get('GaEventCategory')) {
        Rev.Utils.GaTracking.trackGaEvent(this.model.get('GaEventCategory'), Rev.Utils.GaTracking.Action.SendToFriend, Rev.Utils.GaTracking.Label.SendEmailToFriend);
      }

      Rev.Utils.MatomoTracking.sendEvent(this.model, Rev.Utils.MatomoTracking.Category.ListingLeads, Rev.Utils.MatomoTracking.Action.Share, Rev.Utils.MatomoTracking.Name.Email);
    },
    onCloseShareLightbox: function onCloseShareLightbox(e) {
      e.preventDefault();
      e.stopPropagation();
      this.$('[data-hook="lightbox-share"]').removeClass('show');
    },
    remove: function remove() {
      this.off();
      this.stopListening();

      //call the superclass remove method
      Backbone.View.prototype.remove.apply(this, arguments);
    }
  });
})(Rev, jQuery, _, Backbone);
'use strict';

(function (Rev, $, _, Backbone) {

  'use strict';

  Rev.Views.LoginView = Backbone.View.extend({
    el: '.login-body',

    initialize: function initialize() {
      _.bindAll(this, 'submitLoginFB');
    },


    events: {
      'click [data-hook="close-login"]': 'toggleLogin',
      'click [data-hook="submit-login-form"]': 'submitLogin',
      'click [data-hook="link-to-signup"]': 'toggleSignup',
      'click [data-hook="btn-login-fb"]': 'loginFB',
      'click [data-hook="link-to-forgot-password"]': 'toggleForgotPassword'
    },

    loginFB: function loginFB(e) {
      if (e && e.preventDefault) e.preventDefault();
      var self = this;

      if (Rev.Utils.isiPad()) {
        var appid = window.Rev.fbAppId;
        var redirectUri = encodeURI(window.location.origin + '/fb-login-redirect/');
        window.location = encodeURI('https://graph.facebook.com/v2.7/oauth/authorize?client_id=' + appid + '&scope=public_profile,email&redirect_uri=' + redirectUri + '&response_type=token');
      } else {
        FB.login(function (response) {
          FB.api('/' + response.authResponse.userID, function (result) {
            return self.submitLoginFB(response.authResponse.accessToken, response.authResponse.userID, result.first_name, result.last_name);
          });
        }, { scope: 'public_profile,email' });
      }
    },
    submitLoginFB: function submitLoginFB(fbAccessToken, fbUid, fbFirstName, fbLastName) {
      var self = this;
      var url = this.$('form#login-form-fb').attr('action');

      var data = {};
      data["__RequestVerificationToken"] = this.$('form#login-form-fb [name="__RequestVerificationToken"]').val();
      data["fbAccessToken"] = fbAccessToken;
      data["fbUid"] = fbUid;
      data["fbFirstName"] = fbFirstName;
      data["fbLastName"] = fbLastName;

      $('[data-hook="btn-login-fb"]').button('loading');

      $.post(url, data).done(function (result) {
        if (!result.errors) {
          if (Rev.AuthLoginSuccessCallback) {
            Rev.AuthLoginSuccessCallback();
            Rev.AuthLoginSuccessCallback = null;
          } else {
            if (location.href.toLowerCase().indexOf('?returnurl') > 0) {
              var returnUrl = Rev.Utils.parseUrl(location.href.toLowerCase()).returnurl;
              location.href = decodeURIComponent(returnUrl);
            } else {
              location.reload(true);
            }
          }
        } else {
          $('#auth-views-modal').addClass('showing-error');
          Rev.Utils.showErrors(result.errors, self.$('[data-hook="fb-login-validation-errors-placeholder"]'));
        }
      }).fail(function (result) {
        $('#auth-views-modal').addClass('showing-error');
        Rev.Utils.showErrors(result.errors, self.$('[data-hook="fb-login-validation-errors-placeholder"]'));
      }).always(function () {
        self.$('[data-hook="btn-login-fb"]').button('reset');
      });
    },
    toggleForgotPassword: function toggleForgotPassword(e) {
      if (e && e.preventDefault) e.preventDefault();
      Rev.trigger('forgotpassword:toggle');
    },
    toggleSignup: function toggleSignup(e) {
      if (e && e.preventDefault) e.preventDefault();
      Rev.trigger('signup:toggle');
    },
    toggleLogin: function toggleLogin(e) {
      if (e && e.preventDefault) e.preventDefault();
      Rev.trigger('login:toggle');
    },
    submitLogin: function submitLogin(e) {
      e.preventDefault();

      var self = this;
      var url = this.$('form#login-form').attr('action');

      $(e.currentTarget).button('loading');

      $.post(url, this.$('form#login-form').serialize()).done(function (result) {
        if (!result.errors) {
          if (Rev.AuthLoginSuccessCallback) {
            Rev.AuthLoginSuccessCallback();
            Rev.AuthLoginSuccessCallback = null;
          } else {
            if (location.href.indexOf('/register?') > 0 || location.href.indexOf('/register/?') > 0) {
              location.href = '/';
            } else if (location.href.toLowerCase().indexOf('?returnurl') > 0) {
              var returnUrl = Rev.Utils.parseUrl(location.href.toLowerCase()).returnurl;
              location.href = decodeURIComponent(returnUrl);
            } else {
              location.reload(true);
            }
          }
        } else {
          $('#auth-views-modal').addClass('showing-error');
          Rev.Utils.showErrors(result.errors, self.$('[data-hook="email-login-validation-errors-placeholder"]'));
        }
      }).fail(function (result) {
        $('#auth-views-modal').addClass('showing-error');
        Rev.Utils.showErrors(result.errors, self.$('[data-hook="email-login-validation-errors-placeholder"]'));
      }).always(function () {
        self.$('[data-hook="submit-login-form"]').button('reset');
      });
    }
  });
})(Rev, jQuery, _, Backbone);
'use strict';

(function (Rev, $, _, Backbone) {

  'use strict';

  Rev.Views.MapPopupGroupView = Backbone.View.extend({
    el: '.map-popup-group',

    initialize: function initialize() {
      _.bindAll(this, 'render', 'open', 'close', 'getListingData');

      this.render();
    },


    events: {
      'click [data-hook="contact-agency-email"]': 'onContactAgencyEmailClick',
      'click [data-hook="close-popup"]': 'onClosePopupClick',
      'click [data-hook="contact-agency-phone-link"]': 'onPhoneAgencyClick'
    },

    template: _.template($('#map-popup-group').html()),

    render: function render(data) {
      this.$('.content').html(this.template({ listingItems: data }));
      return this;
    },
    open: function open(options) {
      var _this = this;

      this.$('.cloud').addClass('loading');

      var locatePopup = function locatePopup() {
        //this.$el.css({ 
        //  left: options.x,  
        //  top: options.top,
        //  bottom: options.bottom
        //});

        _this.$el.css({
          '-webkit-transform': 'translateX(' + options.x + 'px)',
          '-moz-transform': 'translateX(' + options.x + 'px)',
          '-ms-transform': 'translateX(' + options.x + 'px)',
          '-o-transform': 'translateX(' + options.x + 'px)',
          'transform': 'translateX(' + options.x + 'px)',
          'top': options.top,
          'bottom': options.bottom
        });

        setTimeout(function () {
          _this.$('.popup-arrow-left').offset({ top: options.arrowY });
          _this.$('.cloud').removeClass('loading');
        }, 400);
      };

      setTimeout(function () {
        _this.$el.addClass('open');
        _this.getListingData(options.listingIds, locatePopup);
        return _this;
      }, 300);
    },
    getListingData: function getListingData(listingIds, cb) {
      var self = this;
      $.post('/json/listings/data/', { listingIds: listingIds }).done(function (result) {
        self.render(result);
        self.data = {};
        self.data.listingItems = result;
        cb();
      });
    },
    onPhoneAgencyClick: function onPhoneAgencyClick(e) {
      e.preventDefault();
      var $closestListingItem = this.$(e.currentTarget).closest('.listing-item');
      $closestListingItem.find('[data-hook="contact-agency-phone-number"]').toggleClass('reveal');
      $closestListingItem.find('.contact-agency-phone').toggleClass('reveal');
      $closestListingItem.find('.agent-profile').toggleClass('reveal');

      // fire ga event & lead event
      if ($closestListingItem.find('[data-hook="contact-agency-phone-number"]').hasClass('reveal')) {
        var listingId = $closestListingItem.attr('data-id');
        var item = _.find(this.data.listingItems, function (listing) {
          return listing.Id === listingId;
        });

        Rev.Utils.LeadTracking.sendPhoneEvent(listingId);

        Rev.Utils.GaTracking.trackGaEvent(this.getListingCategory(item.Status), Rev.Utils.GaTracking.Action.PhoneAgent, item.Agencies[0].Name + ' / ' + item.Agencies[0].Id);

        Rev.Utils.GaTracking.trackPhoneAgent(this.model);

        Rev.Utils.Criteo.pushEventAgentContact(listingId);
      }
    },
    onContactAgencyEmailClick: function onContactAgencyEmailClick(e) {
      e.stopPropagation();
      e.preventDefault();

      var listingId = $(e.currentTarget).closest('.listing-item').attr('data-id');
      var item = _.find(this.data.listingItems, function (listing) {
        return listing.Id === listingId;
      });
      Rev.Utils.showEmailAgentModal(listingId, this.getListingCategory(item.Status), item.Agencies[0].Name, item.Agencies[0].Email);
    },
    getListingCategory: function getListingCategory(status) {
      if (status.AvailabilityType === 1) {
        return Rev.Utils.GaTracking.Category.PropertySold;
      }

      if (status.ContractType === 0) {
        return Rev.Utils.GaTracking.Category.PropertyBuy;
      }

      if (status.ContractType === 1) {
        return Rev.Utils.GaTracking.Category.PropertyRent;
      }
    },
    close: function close() {
      this.$el.removeClass('open');
      return this;
    },
    onClosePopupClick: function onClosePopupClick(e) {
      this.close();
    },
    remove: function remove() {
      this.off();
      this.stopListening();

      //call the superclass remove method
      Backbone.View.prototype.remove.apply(this, arguments);
    }
  });
})(Rev, jQuery, _, Backbone);
'use strict';

(function (Rev, $, _, Backbone) {

    'use strict';

    Rev.Views.MapPopupView = Backbone.View.extend({
        el: '.map-popup',

        initialize: function initialize() {
            _.bindAll(this, 'render', 'open', 'close', 'getListingData', 'onContactAgencyEmailClick');

            this.render();
        },


        events: {
            //'click' : 'onViewClick',
            'click [data-hook="contact-agency-email"]': 'onContactAgencyEmailClick',
            'click [data-hook="close-popup"]': 'onClosePopupClick',
            'click [data-hook="contact-agency-phone-link"]': 'onPhoneAgencyClick'
        },

        template: _.template($('#map-popup').html()),

        render: function render(data) {
            this.$('.content').html(this.template(data || { Id: null }));
            return this;
        },
        open: function open(options) {
            var _this = this;

            this.$el.removeClass('transition-opacity-transform');
            this.$('.cloud').addClass('loading');

            var locatePopup = function locatePopup() {
                //this.$el.css({top: options.y, left: options.x});
                _this.$el.css({
                    '-webkit-transform': 'translate(' + options.x + 'px, ' + options.y + 'px)',
                    '-moz-transform': 'translate(' + options.x + 'px, ' + options.y + 'px)',
                    '-ms-transform': 'translate(' + options.x + 'px, ' + options.y + 'px)',
                    '-o-transform': 'translate(' + options.x + 'px, ' + options.y + 'px)',
                    'transform': 'translate(' + options.x + 'px, ' + options.y + 'px)'
                });

                setTimeout(function () {
                    _this.$('.popup-arrow-top, .popup-arrow-bottom').offset({ left: options.arrowX });
                    _this.$('.cloud').removeClass('loading');
                }, 500);
            };

            this.listingId = options.listingId;

            setTimeout(function () {
                _this.$el.addClass('open');
                _this.getListingData(options.listingId, locatePopup);
                return _this;
            }, 300);
        },
        getListingData: function getListingData(listingId, cb) {
            var _this2 = this;

            var self = this;
            $.getJSON('/json/listing/data/' + listingId + '/').done(function (result) {
                self.render(result);

                _this2.model = new Rev.Models.ListResultsItem(result);
                Rev.Utils.MatomoTracking.sendEvent(_this2.model, Rev.Utils.MatomoTracking.Category.ListingLeads, Rev.Utils.MatomoTracking.Action.MapReveal);

                self.data = {};
                self.data.status = result.Status;
                self.data.agencyName = result.Agencies[0].Name;
                self.data.agencyEmail = result.Agencies[0].Email;
                self.data.agencyPhone = result.Agencies[0].Phone;
                self.data.agencyId = result.Agencies[0].Id;

                cb();
            });
        },
        close: function close() {
            this.listingId = null;
            this.$el.addClass('transition-opacity-transform');
            this.$el.removeClass('open');
            return this;
        },
        onViewClick: function onViewClick(e) {},
        onPhoneAgencyClick: function onPhoneAgencyClick(e) {
            e.preventDefault();
            this.$('[data-hook="contact-agency-phone-number"]').toggleClass('reveal');
            this.$('.contact-agency-phone').toggleClass('reveal');
            this.$('.agent-profile').toggleClass('reveal');

            // fire ga event & lead event
            if (this.$('[data-hook="contact-agency-phone-number"]').hasClass('reveal')) {
                Rev.Utils.LeadTracking.sendPhoneEvent(this.listingId);

                Rev.Utils.MatomoTracking.sendEvent(this.model, Rev.Utils.MatomoTracking.Category.ListingLeads, Rev.Utils.MatomoTracking.Action.PhoneReveal);

                Rev.Utils.GaTracking.trackGaEvent(this.getListingCategory(), Rev.Utils.GaTracking.Action.PhoneAgent, this.data.agencyName + ' / ' + this.data.agencyId);

                Rev.Utils.GaTracking.trackPhoneAgent(this.model);

                Rev.Utils.Criteo.pushEventAgentContact(this.listingId);
            }
        },
        onContactAgencyEmailClick: function onContactAgencyEmailClick(e) {
            e.stopPropagation();
            e.preventDefault();

            Rev.Utils.showEmailAgentModal(this.listingId, this.getListingCategory(), this.data.agencyName, this.data.agencyEmail);
        },
        getListingCategory: function getListingCategory() {
            if (this.data.status.AvailabilityType === 1) {
                return Rev.Utils.GaTracking.Category.PropertySold;
            }

            if (this.data.status.ContractType === 0) {
                return Rev.Utils.GaTracking.Category.PropertyBuy;
            }

            if (this.data.status.ContractType === 1) {
                return Rev.Utils.GaTracking.Category.PropertyRent;
            }
        },
        onClosePopupClick: function onClosePopupClick(e) {
            this.close();
        },
        remove: function remove() {
            this.off();
            this.stopListening();

            //call the superclass remove method
            Backbone.View.prototype.remove.apply(this, arguments);
        }
    });
})(Rev, jQuery, _, Backbone);
'use strict';

(function (Rev, $, _, Backbone) {

    'use strict';

    Rev.Views.NavRightView = Backbone.View.extend({
        el: '#layout-nav-right',

        initialize: function initialize() {
            //_.bindAll(this, 'onShortlistChanged', 'onRecentIdsChanged', 'toggleSidebar', 'toggleSignup', 'toggleForgotPassword');
            _.bindAll(this, 'toggleSidebar');

            this.listenTo(Rev, 'sidebar:toggle', this.toggleSidebar);
            //this.listenTo(Rev, 'signup:toggle', this.toggleSignup);
            //this.listenTo(Rev, 'forgotpassword:toggle', this.toggleForgotPassword);
            //this.listenTo(Rev, 'login:toggle', this.toggleLogin);
            //this.listenTo(Rev, 'change:shortlist', this.onShortlistChanged);
            //this.listenTo(Rev, 'change:recentHistory', this.onRecentIdsChanged);
            //this.showShortlistNumber();
            //this.showRecentHistoryNumber();
        },


        events: {
            'click [data-hook="close-sidebar"]': 'toggleSidebar'
            //'click [data-hook="toggle-signup"]': 'toggleSignup',
            //'click [data-hook="toggle-login"]': 'toggleLogin'
        },

        //toggleSignup: function(e) {
        //  if (e && e.preventDefault) e.preventDefault();
        //  this.$('.signup-body').toggleClass('slide-in').scrollTop(0);
        //  this.toggleLeftBody();
        //  //$('[data-hook="close-sidebar"]').toggleClass('rotate');
        //  $('.signup-body [data-hook="close-sidebar"]').hide();
        //  setTimeout(function () {
        //    $('.signup-body [data-hook="close-sidebar"]').show();
        //  }, 280);
        //},

        //toggleLogin: function(e) {
        //  if (e && e.preventDefault) e.preventDefault();
        //  this.$('.login-body').toggleClass('slide-in').scrollTop(0);
        //  this.toggleLeftBody();
        //  //$('[data-hook="close-sidebar"]').toggleClass('rotate');
        //  $('.login-body [data-hook="close-sidebar"]').hide();
        //  setTimeout(function () {
        //    $('.login-body [data-hook="close-sidebar"]').show().toggleClass('rotate');
        //  }, 280);
        //},

        //toggleForgotPassword: function (e) {
        //  if (e && e.preventDefault) e.preventDefault();
        //  this.$('.forgot-password-body').toggleClass('slide-in').scrollTop(0);
        //  this.toggleLeftBody();
        //  //$('[data-hook="close-sidebar"]').toggleClass('rotate');
        //  $('.forgot-password-body [data-hook="close-sidebar"]').hide();
        //  setTimeout(function () {
        //    $('.forgot-password-body [data-hook="close-sidebar"]').show();
        //  }, 280);
        //},

        //toggleLeftBody: function(e){
        //  if (e && e.preventDefault) e.preventDefault();
        //  this.$('.nav-left-body').toggleClass('slide-out');
        //},

        toggleSidebar: function toggleSidebar(e) {
            if (e && e.preventDefault) e.preventDefault();

            if (!$('#layout-nav-right').hasClass('slide-in')) {
                // show sidebar
                $('#layout-nav-right').addClass('opacity-in');

                setTimeout(function () {
                    $('#layout-nav-right').addClass('slide-in');
                    $('#layout-body').addClass('slide-out');
                    $('#rev-overlay').show();

                    // clear layers behind layout-nav-left
                    $('body').css('overflow-y', 'hidden');

                    // reset
                    //this.resetSubViews();

                    Rev.trigger('sidebar:shown');
                }, 10);
            } else {
                // hide sidebar
                $('#layout-nav-right').removeClass('slide-in');
                $('#layout-body').removeClass('slide-out');
                $('#rev-overlay').hide();

                // clear layers behind layout-nav-left
                $('body').css('overflow-y', '');

                // reset 
                //this.resetSubViews();

                Rev.trigger('sidebar:hidden');

                setTimeout(function () {
                    $('#layout-nav-right').removeClass('opacity-in');
                }, 500);
            }
        }
    }

    //resetSubViews: function () {
    //  $('.nav-left-body').removeClass('slide-out');
    //  $('.signup-body').removeClass('slide-in');
    //  $('.login-body').removeClass('slide-in');
    //  $('.forgot-password-body').removeClass('slide-in');
    //},

    //showShortlistNumber: function () {
    //  var self = this;
    //  $.getJSON('/authenticated/').done(function (result) {
    //    if (result.isAuthenticated) {
    //      self.getShortlistRemote();
    //    } else {
    //      Rev.trigger('change:shortlist', Rev.Utils.shortlistCookie.getShortlist());  // list_result_item_view will listen this event and will show shortlist status
    //    }
    //  });
    //},

    //getShortlistRemote: function () {
    //  var self = this;
    //  $.getJSON('/properties/shortlist/ids/json/').done(function (listingIds) {
    //    self.onShortlistChanged(listingIds);  // Rev.trigger('change:shortlist', listingIds) is not necessary because other views don't have to know this
    //  });
    //},

    //onShortlistChanged: function (listingIds) {
    //  this.$('[data-hook="shortlist-count"]').text(listingIds.length);
    //},

    //onRecentIdsChanged: function (listingIds) {
    //  this.$('[data-hook="recent-history-count"]').text(listingIds.length);
    //},

    //showRecentHistoryNumber: function () {
    //  var listingIds = Rev.Utils.recentHistoryCookie.getRecentIds();
    //  if (listingIds && _.isArray(listingIds) && listingIds.length > 0) {
    //    this.$('[data-hook="recent-history-count"]').text(listingIds.length);
    //  }

    //}
    );

    new Rev.Views.NavRightView();
})(Rev, jQuery, _, Backbone);
'use strict';

(function (Rev, $, _, Backbone) {

  'use strict';

  Rev.Views.NewSearchFormView = Backbone.View.extend({
    initialize: function initialize() {
      _.bindAll(this, 'openView', 'hideView', 'toggleView');

      this.searchFormView = new Rev.Views.SearchFormView({ el: this.$('.new-search-form-container .search-form') });

      this.listenTo(Rev, 'new-search:open', this.openView);
      this.listenTo(Rev, 'new-search:hide', this.hideView);
      this.listenTo(Rev, 'new-search:toggle', this.toggleView);
    },


    events: {
      'click [data-hook="close-new-search"]': 'hideView'
    },

    toggleView: function toggleView(e) {
      if (e && e.preventDefault) e.preventDefault();
      this.$el.toggleClass('open');
    },
    openView: function openView(e) {
      if (e && e.preventDefault) e.preventDefault();
      if (e && e.isEditingSavedSearch) {
        this.$el.addClass('open editing-saved-search');
      } else {
        this.$el.addClass('open');
      }
    },
    hideView: function hideView(e) {
      if (e && e.preventDefault) e.preventDefault();
      this.$el.removeClass('open');
    },
    remove: function remove() {
      if (this.searchFormView) this.searchFormView.remove();

      this.off();
      this.stopListening();

      //call the superclass remove method
      Backbone.View.prototype.remove.apply(this, arguments);
    }
  });
})(Rev, jQuery, _, Backbone);
'use strict';

(function (Rev, $, _, Backbone) {

  'use strict';

  Rev.Views.RevDropdownView = Backbone.View.extend({
    el: '.rev-dropdown', // if there are more than one dropdown in the page, assign its own el

    events: {
      'click [data-hook="dropdown-option"]': 'onDropdownOptionClick'
    },

    onDropdownOptionClick: function onDropdownOptionClick(e) {
      e.preventDefault();
      var text = $(e.currentTarget).text();
      var value = $(e.currentTarget).attr('data-hook-value');
      this.$('[data-hook="dropdown-selected-value"]').val(value).change();
      this.$('[data-hook="dropdown-selected-text"]').text(text);
    }
  });
})(Rev, jQuery, _, Backbone);
'use strict';

(function (Rev, $, _, Backbone) {

  'use strict';

  Rev.Views.RevDropdownSortView = Backbone.View.extend({
    el: '.rev-dropdown-sort',

    initialize: function initialize() {},

    events: {
      'click [data-hook="dropdown-option"]': 'onDropdownOptionClick'
    },

    onDropdownOptionClick: function onDropdownOptionClick(e) {
      e.preventDefault();

      this.$('[data-hook="dropdown-option"]').removeClass('selected');
      $(e.currentTarget).addClass('selected');

      var html = $(e.currentTarget).html();
      var value = $(e.currentTarget).attr('data-hook-value');
      this.$('[data-hook="dropdown-selected-value"]').val(value).change();
      this.$('[data-hook="dropdown-selected-text"]').html(html);
    }
  });
})(Rev, jQuery, _, Backbone);
'use strict';

// dependencies : Rev, jquery, underscore, backbone

(function (Rev, $, _, Backbone) {

  'use strict';

  Rev.Views.SearchFormKeywordView = Backbone.View.extend({
    initialize: function initialize(options) {
      _.bindAll(this, 'togglePlaceholder', 'onEditSavedSearch');

      var options = options || {};
      this.baseSearchForm = options.baseSearchForm;
      this.isRefineSearch = options.isRefineSearch;

      if (this.$('[data-hook="keywords"]').val()) {
        this.$('.keywords-placeholder').hide();
      } else {
        this.$('.keywords-placeholder').show();
      }

      // why I do this crazy white class thing? because of IE you, ie you !!!
      // note this white class thing won't be needed when the search form shows the last search filters in home page
      if (this.isRefineSearch) {
        this.$('[data-hook="keywords"]').removeClass('white');
      } else {
        this.$('[data-hook="keywords"]').addClass('white');
      }

      this.listenTo(Rev, 'saved:searches:edit', this.onEditSavedSearch);
    },


    events: {
      'focus [data-hook="keywords"]': 'onKeywordsInputFocus',
      'click [data-hook="keywords"]': 'onKeywordsInputClick',
      'blur [data-hook="keywords"]': 'onKeywordsInputBlur',
      'keypress [data-hook="keywords"]': 'onKeywordsInputKeypress',
      'keyup [data-hook="keywords"]': 'onKeywordsChange'
    },

    togglePlaceholder: function togglePlaceholder() {
      if (this.$('[data-hook="keywords"]').val()) {
        this.$('.keywords-placeholder').hide();
        this.$('[data-hook="keywords"]').removeClass('white');
      } else {
        this.$('.keywords-placeholder').show();
        this.$('[data-hook="keywords"]').addClass('white');
      }
    },
    onEditSavedSearch: function onEditSavedSearch(viewAlertResult) {
      if (!viewAlertResult) return;
      this.$('[data-hook="keywords"]').val(viewAlertResult.get('Keywords'));
      this.togglePlaceholder();
    },
    onKeywordsChange: function onKeywordsChange(e) {
      this.baseSearchForm.getTotal();
    },
    onKeywordsInputFocus: function onKeywordsInputFocus(e) {
      this.$('.keywords-placeholder').hide();
      this.$('[data-hook="keywords"]').removeClass('white');
    },
    onKeywordsInputClick: function onKeywordsInputClick(e) {
      this.$('.keywords-placeholder').hide();
      this.$('[data-hook="keywords"]').removeClass('white');
    },
    onKeywordsInputBlur: function onKeywordsInputBlur(e) {
      if (!this.$('[data-hook="keywords"]').val()) this.$('.keywords-placeholder').show();
    },
    onKeywordsInputKeypress: function onKeywordsInputKeypress(e) {
      if (e.which === 13) {
        this.baseSearchForm.submitForm();
      }
    }
  });
})(Rev, jQuery, _, Backbone);
'use strict';

// dependencies : Rev, jquery, underscore, backbone

(function (Rev, $, _, Backbone) {

    'use strict';

    Rev.Views.SearchFormLocationView = Backbone.View.extend({
        initialize: function initialize(options) {
            _.bindAll(this, 'onLocationFocusOut', 'onIssCheckboxClick', 'reset', 'closeView', 'showExistingValue', 'showPlaceholder', 'hidePlaceholder', 'togglePlaceholder', 'onLocationInputKeydown', 'onEditSavedSearch', 'showLocationRequiredMessage', 'hideLocationRequiredMessage', 'getStates', 'toTitleCase');

            if (options) {
                this.isRefineSearch = options.isRefineSearch;
                this.baseSearchForm = options.baseSearchForm;
                this.isSuburbRequired = options.isSuburbRequired;
            }

            this.initialLoad = true;

            this.initializeBloodHound();
            this.initializeLocationTypeahead();

            if (this.isRefineSearch) {
                this.showExistingValue(this.model.get('Location'));
            } else {
                this.showRecentlySearchedLocations();
            }

            this.listenTo(Rev, 'refine:search:reset', this.reset);
            this.listenTo(Rev, 'saved:searches:edit', this.onEditSavedSearch);
            this.listenTo(Rev, 'location-required-message:show', this.showLocationRequiredMessage);
            this.listenTo(Rev, 'location-required-message:hide', this.hideLocationRequiredMessage);

            // outside is custom jquery plugin defined in init.js file
            this.$el.outside('click', this.onLocationFocusOut);
        },


        events: {
            'itemAdded [data-hook="location-input"]': 'onItemAdded',
            'itemRemoved [data-hook="location-input"]': 'onItemRemoved',
            //'blur .bootstrap-tagsinput' : 'onLocationFocusOut',
            'click': 'onLocationFocusIn',
            'click .search-icon': 'onLocationFocusIn',
            //'keydown .tt-input' : 'onLocationInputKeydown',
            'keypress .tt-input': 'onLocationInputKeypress',
            'mouseenter .tt-suggestion': 'onHoverSuggestion',
            'click [data-hook="cb-include-surrounding-suburbs"]': 'onIssCheckboxClick',
            'mouseover .btn-include-surrounding-suburbs-wrapper': 'onIssMouseover',
            'mouseout .btn-include-surrounding-suburbs-wrapper': 'onIssMouseout'
        },

        onEditSavedSearch: function onEditSavedSearch(viewAlertResult) {
            if (!viewAlertResult) return;

            this.$tagsinput.tagsinput('removeAll');

            if (viewAlertResult.get('SuburbsValue')) {
                this.showExistingValue(viewAlertResult.get('SuburbsValue'));
            }

            this.$('[data-hook="cb-include-surrounding-suburbs"]').prop('checked', viewAlertResult.get('SearchSurroundingSuburbs'));
        },
        onIssMouseover: function onIssMouseover(e) {
            var _this = this;

            // show tooltip
            this.$('[data-hook="pulse-tooltip"]').show();

            // hide tooltip in 5 seconds
            if (this.timer != null) clearTimeout(this.timer);
            this.timer = setTimeout(function () {
                _this.$('[data-hook="pulse-tooltip"]').hide();
            }, 5000);
        },
        onIssMouseout: function onIssMouseout(e) {
            this.$('[data-hook="pulse-tooltip"]').hide();
        },
        onIssCheckboxClick: function onIssCheckboxClick(e) {
            //e.preventDefault();
            //e.stopPropagation();

            var self = this;

            // show tooltip
            this.$('[data-hook="pulse-tooltip"]').show();

            // hide tooltip in 5 seconds
            if (this.timer != null) clearTimeout(this.timer);
            this.timer = setTimeout(function () {
                self.$('[data-hook="pulse-tooltip"]').hide();
            }, 5000);

            this.baseSearchForm.getTotal();

            // fire ga event
            if ($(e.currentTarget).is(':checked')) {
                this.baseSearchForm.fireGaEvent(Rev.Utils.GaTracking.Action.SurroundingSuburbs, Rev.Utils.GaTracking.Label.On);
            } else {
                this.baseSearchForm.fireGaEvent(Rev.Utils.GaTracking.Action.SurroundingSuburbs, Rev.Utils.GaTracking.Label.Off);
            }
        },
        onHoverSuggestion: function onHoverSuggestion(e) {
            this.$('.tt-menu-placeholder .tt-suggestion').removeClass('tt-cursor');
            this.$(e.currentTarget).addClass('tt-cursor');
        },
        getStates: function getStates(shortname) {
            var states = [{ "name": "Victoria", "shortname": "VIC" }, { "name": "New South Wales", "shortname": "NSW" }, { "name": "South Australia", "shortname": "SA" }, { "name": "Queensland", "shortname": "QLD" }, { "name": "Northern Territory", "shortname": "NT" }, { "name": "Western Australia", "shortname": "WA" }, { "name": "ACT", "shortname": "ACT" }, { "name": "Tasmania", "shortname": "TAS" }];
            var state = $.grep(states, function (v) {
                return v.shortname == shortname;
            });
            if (state.length > 0) {
                return state[0].shortname;
            }
        },
        initializeBloodHound: function initializeBloodHound() {
            this.locationSuggestions = new Bloodhound({
                //datumTokenizer: Bloodhound.tokenizers.obj.whitespace('Suburb'),
                datumTokenizer: Bloodhound.tokenizers.obj.whitespace,
                queryTokenizer: Bloodhound.tokenizers.whitespace,
                remote: {
                    url: '/location/searchV2/?searchText=%QUERY',
                    replace: function replace(url, query) {
                        var arr = query.split(',');
                        return url.replace("%QUERY", arr[arr.length - 1].trim());
                    },
                    filter: function filter(response) {
                        return $.map(response.Suburbs, function (suburb) {
                            return suburb;
                        });
                    }
                },
                limit: 10
            });

            this.locationSuggestions.initialize();

            this.regionSuggestions = new Bloodhound({
                //datumTokenizer: Bloodhound.tokenizers.obj.whitespace('Suburb'),
                datumTokenizer: Bloodhound.tokenizers.obj.whitespace,
                queryTokenizer: Bloodhound.tokenizers.whitespace,
                remote: {
                    url: '/location/searchV2/?searchText=%QUERY',
                    replace: function replace(url, query) {
                        var arr = query.split(',');
                        return url.replace("%QUERY", arr[arr.length - 1].trim());
                    },
                    filter: function filter(response) {
                        return $.map(response.Regions, function (region) {
                            return region;
                        });
                    }
                },
                limit: 10
            });

            this.regionSuggestions.initialize();
        },
        initializeLocationTypeahead: function initializeLocationTypeahead() {
            var _this2 = this;

            var suburbTemplate = _.template($('#suggestion-location-item').html());
            var regionTemplate = _.template($('#suggestion-region-item').html());
            var cityTemplate = _.template($('#suggestion-city-item').html());
            var stateTemplate = _.template($('#suggestion-state-item').html());
            var headerTemplate = _.template($('#header-location-item').html());
            var states = [{ "name": "Australian Capital Territory", "shortname": "ACT" }, { "name": "New South Wales", "shortname": "NSW" }, { "name": "Victoria", "shortname": "VIC" }, { "name": "South Australia", "shortname": "SA" }, { "name": "Tasmania", "shortname": "TAS" }, { "name": "Western Australia", "shortname": "WA" }, { "name": "Northern Territory", "shortname": "NT" }, { "name": "Queensland", "shortname": "QLD" }];
            var self = this;
            if (this.$tagsinput) {
                this.$tagsinput.off();
                this.$tagsinput.tagsinput('destroy');
            }

            this.$tagsinput = this.$('[data-hook="location-input"]');

            this.$tagsinput.tagsinput({
                maxChars: 100,
                freeInput: true, // this will be ignored if itemValue option is set
                itemValue: function itemValue(item) {
                    if (typeof item.Suburb === 'string') {
                        return item.Suburb + '|' + item.State + '|' + item.Postcode;
                    } else if (typeof item.Region === 'string') {
                        return item.Region + '|' + item.State;
                    } else if (typeof item.City === 'string') {
                        return item.City;
                    } else if (typeof item.State === 'string') {
                        return item.State;
                    }
                },
                itemText: function itemText(item) {
                    if (typeof item.Suburb === 'string') {
                        return self.toTitleCase(item.Suburb) + ', ' + item.State.toUpperCase() + ' ' + item.Postcode;
                    } else if (typeof item.Region === 'string') {
                        return item.Region + ' Region, ' + item.State;
                    } else if (typeof item.City === 'string') {
                        return item.City + ' - Greater Region';
                    } else if (typeof item.State === 'string') {
                        var state = $.grep(states, function (v) {
                            return v.shortname == item.State;
                        });
                        return state[0].name;
                    }
                },
                typeaheadjs: [{
                    limit: 10,
                    highlight: true,
                    minLength: 2,
                    hint: false,
                    menu: this.$('.tt-menu-placeholder')
                }, {
                    displayKey: 'FullName',
                    source: this.regionSuggestions.ttAdapter(),
                    templates: {
                        header: headerTemplate({ header: 'Regions' }),
                        suggestion: function suggestion(item) {
                            if (typeof item.Region === 'string') {
                                var html = regionTemplate({ city: item.City, state: item.State, region: item.Region });
                                return html;
                            } else if (typeof item.City === 'string') {
                                var html = cityTemplate({ city: item.City });
                                return html;
                            } else if (typeof item.State === 'string') {
                                var state = $.grep(states, function (v) {
                                    return v.shortname == item.State;
                                });
                                var html = stateTemplate({ state: state[0].name });
                                return html;
                            }
                        }
                    }
                }, {
                    displayKey: 'FullName',
                    source: this.locationSuggestions.ttAdapter(),
                    templates: {
                        header: headerTemplate({ header: 'Suburbs' }),
                        suggestion: function suggestion(item) {
                            var html = suburbTemplate({ suburb: item.Suburb, state: item.State, postcode: item.Postcode });
                            return html;
                        }
                    }
                }]

            });

            this.$el.on('typeahead:autocomplete', function (event, item) {
                _this2.$('.bootstrap-tagsinput  input.tt-input').typeahead('val', null);
                if (item.Suburb !== 'undefined') {
                    _this2.$tagsinput.tagsinput('add', { Suburb: item.Suburb, State: item.State, Postcode: item.Postcode });
                } else {
                    _this2.$tagsinput.tagsinput('add', { City: item.City, State: item.State, Region: item.Region });
                }
            }).on('typeahead:render', function (e, item) {
                if (item) {
                    // if it is not open and has suggestions, force open dropdown menu
                    var selectables = _this2.$('.tt-menu-placeholder:hidden .tt-dataset .tt-selectable');
                    if (selectables.length > 0) {
                        _this2.$('.tt-menu-placeholder').show();
                    }
                }
            });
        },
        reset: function reset() {
            this.$tagsinput.tagsinput('removeAll');
            Rev.Models.localData.save({ 'recentlySearchedLocations': '' });
        },
        onItemAdded: function onItemAdded(e) {
            // save locations in local storage.
            var location = e.item;
            Rev.Models.localData.save({ 'recentlySearchedLocations': this.$tagsinput.val() });
            this.togglePlaceholder();
            //Rev.trigger('search:filter:changed'); 
            Rev.trigger('search:filter:location:changed', { itemChanged: e.item, allItems: this.$tagsinput.tagsinput('items') });

            //this.initialLoad is just for avoiding call server in page load time
            if (!this.initialLoad) {
                this.baseSearchForm.getTotal();
                //this.baseSearchForm.fireGaEvent(Rev.Utils.GaTracking.Action.Search, this.$tagsinput.val().replace(/[|]/g, ' ')); // fire ga event
                if (location && location.Suburb && location.State && location.Postcode && location.Suburb.indexOf('undefined') === -1 && location.State.indexOf('undefined') === -1 && location.Postcode.indexOf('undefined') === -1) {
                    this.baseSearchForm.fireGaEvent(Rev.Utils.GaTracking.Action.Search, this.toTitleCase(location.Suburb) + ' ' + location.State.toUpperCase() + ' ' + location.Postcode); // fire ga event
                }
            }
            this.initialLoad = false;
        },
        onItemRemoved: function onItemRemoved(e) {
            // remove the location from local storage
            var location = e.item;
            if (location) {
                Rev.Models.localData.fetch();
                var reg = new RegExp(location.Suburb + '|' + location.State + '|' + location.Postcode, 'g');
                var newLoc = Rev.Models.localData.get('recentlySearchedLocations').replace(reg, '');
                if (newLoc === '||') newLoc = '';
                Rev.Models.localData.save({ 'recentlySearchedLocations': newLoc });

                this.togglePlaceholder();
                //Rev.trigger('search:filter:changed'); 
                Rev.trigger('search:filter:location:changed', { itemChanged: e.item, allItems: this.$tagsinput.tagsinput('items') });
                this.baseSearchForm.getTotal();
            }
        },
        showRecentlySearchedLocations: function showRecentlySearchedLocations() {
            var _this3 = this;

            Rev.Models.localData.fetch();
            var locations = Rev.Models.localData.get('recentlySearchedLocations').trim().split(',');

            _.each(locations, function (location) {
                if (!location) return;
                var locationSplited = [location];
                if (location.indexOf('|') > -1) locationSplited = location.split('|');
                if (location.indexOf('_') > -1) locationSplited = location.split('_');

                if (locationSplited.length === 3) {
                    _this3.$tagsinput.tagsinput('add', { Suburb: locationSplited[0], State: locationSplited[1], Postcode: locationSplited[2] });
                } else if (locationSplited.length === 2) {
                    _this3.$tagsinput.tagsinput('add', { Region: locationSplited[0], State: locationSplited[1] });
                } else if (locationSplited.length === 1) {
                    var stateFullName = _this3.getStates(locationSplited[0]);
                    if (stateFullName != undefined) {
                        _this3.$tagsinput.tagsinput('add', { State: stateFullName });
                    } else {
                        _this3.$tagsinput.tagsinput('add', { City: locationSplited[0] });
                    }
                } else {
                    Rev.Models.localData.save({ 'recentlySearchedLocations': '' });
                }
            });
            this.$('.bootstrap-tagsinput').addClass('one-line');
            this.togglePlaceholder();
        },
        showExistingValue: function showExistingValue(locationData) {
            var _this4 = this;

            //if (!this.model.get('Location')) return;
            if (!locationData) return;

            var locations = locationData.split(',');
            _.each(locations, function (location) {
                if (!location) return;
                var locationSplited = location.split('|');
                if (locationSplited.length === 3) {
                    _this4.$tagsinput.tagsinput('add', { Suburb: locationSplited[0], State: locationSplited[1], Postcode: locationSplited[2] });
                } else if (locationSplited.length === 2) {
                    _this4.$tagsinput.tagsinput('add', { Region: locationSplited[0], State: locationSplited[1] });
                } else {
                    var stateFullName = _this4.getStates(locationSplited[0]);
                    if (stateFullName != undefined) {
                        _this4.$tagsinput.tagsinput('add', { State: stateFullName });
                    } else {
                        _this4.$tagsinput.tagsinput('add', { City: locationSplited[0] });
                    }
                }
            });
            this.$('.bootstrap-tagsinput').addClass('one-line');
            this.togglePlaceholder();
        },
        onLocationFocusOut: function onLocationFocusOut(e) {
            if (e.target && e.target.attributes && e.target.attributes[0] && e.target.attributes[0].nodeName && e.target.attributes[0].nodeName === 'data-role' && e.target.attributes[0].nodeValue && e.target.attributes[0].nodeValue === 'remove') {
                return;
            }

            this.$('.bootstrap-tagsinput').addClass('one-line');
            this.togglePlaceholder();
            this.$('.tt-menu-placeholder').hide();
            if (this.$tagsinput.tagsinput('items').length > 0) {
                this.makeTTinputLarge();
            }

            this.$(".bootstrap-tagsinput").scrollTop(0);
        },
        onLocationFocusIn: function onLocationFocusIn(e) {
            this.$('.bootstrap-tagsinput').removeClass('one-line');
            this.hidePlaceholder();
            this.$('.tt-menu-placeholder').show();
            this.makeTTinputSmall();
            if (this.$tagsinput.tagsinput('items').length == 0) {
                this.$('.tt-input').removeClass('margin-left-0').addClass('margin-left-5');
            } else {
                this.$('.tt-input').removeClass('margin-left-5').addClass('margin-left-0');
            }
        },
        onLocationInputKeydown: function onLocationInputKeydown(e) {
            if (this.$tagsinput.tagsinput('items').length == 0) {
                this.$('.tt-input').removeClass('margin-left-0').addClass('margin-left-5');
            } else {
                this.$('.tt-input').removeClass('margin-left-5').addClass('margin-left-0');
            }

            this.hideLocationRequiredMessage();
        },
        onLocationInputKeypress: function onLocationInputKeypress(e) {
            var _this5 = this;

            var self = this;

            if (this.$tagsinput.tagsinput('items').length == 0) {
                this.$('.tt-input').removeClass('margin-left-0').addClass('margin-left-5');
            } else {
                this.$('.tt-input').removeClass('margin-left-5').addClass('margin-left-0');
            }

            this.hideLocationRequiredMessage();

            if (e.which == 13) {
                e.preventDefault();
                setTimeout(function () {
                    var selectables = self.$('.tt-menu-placeholder .tt-dataset .tt-selectable');
                    if (selectables.length > 0) {
                        $(selectables[0]).trigger('click'); // select top one from suggestion
                    } else {
                        if (_this5.isSuburbRequired && self.$tagsinput.tagsinput('items').length === 0) {
                            // check if user selected any suburbs
                            _this5.showLocationRequiredMessage();
                        } else {
                            self.baseSearchForm.submitForm();
                        }
                    }
                }, 500);
            }
        },
        showLocationRequiredMessage: function showLocationRequiredMessage() {
            this.$('.message-suburb-required').fadeIn();
        },
        hideLocationRequiredMessage: function hideLocationRequiredMessage() {
            this.$('.message-suburb-required').fadeOut();
        },
        togglePlaceholder: function togglePlaceholder() {
            if (this.$tagsinput.tagsinput('items') && this.$tagsinput.tagsinput('items').length > 0) {
                this.hidePlaceholder();
            } else {
                this.showPlaceholder();
            }
        },
        showPlaceholder: function showPlaceholder() {
            this.$tagsinput.tagsinput('input') && this.$tagsinput.tagsinput('input').attr('placeholder', 'Search by suburb, postcode or area');
            this.$('.tt-input').css('max-width', '280px');
        },
        hidePlaceholder: function hidePlaceholder() {
            if (this.$tagsinput.tagsinput('input').removeAttr) this.$tagsinput.tagsinput('input').removeAttr('placeholder');
        },
        makeTTinputSmall: function makeTTinputSmall() {
            //this.$('.tt-input').css('max-width','100px');
        },
        makeTTinputLarge: function makeTTinputLarge() {
            //this.$('.tt-input').css('max-width','210px');
        },
        closeView: function closeView(e) {
            if (e && e.preventDefault) e.preventDefault();

            // save locations in local storage.
            Rev.Models.localData.save({ 'recentlySearchedLocations': this.$tagsinput.val() });

            //if (this.$tagsinput.val() && this.$tagsinput.val().length > 0) {
            //  Rev.trigger('search:filter:hasValue');        
            //}

            this.$el.off('typeahead:autocomplete');
            //$(document).off('typeahead:cursorchange typeahead:select');

            //Rev.trigger('search:ga:fire', Rev.Utils.GaTracking.Action.Search, this.$tagsinput.val()); // fire ga event
        },
        toTitleCase: function toTitleCase(str) {
            return str.replace(/\w\S*/g, function (txt) {
                return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();
            });
        }
    });
})(Rev, jQuery, _, Backbone);
'use strict';

// dependencies : Rev, jquery, underscore, backbone

(function (Rev, $, _, Backbone) {

  'use strict';

  Rev.Views.SearchFormMenuTypeView = Backbone.View.extend({
    initialize: function initialize(options) {
      _.bindAll(this, 'onSearchMenuTypeClick', 'onEditSavedSearch', 'getSelectedMenuType');

      var options = options || {};
      this.baseSearchForm = options.baseSearchForm;
      this.updateUrl = options.updateUrl;

      this.listenTo(Rev, 'saved:searches:edit', this.onEditSavedSearch);
      this.listenTo(Rev, 'get:selected:menuyype', this.getSelectedMenuType);
    },


    events: {
      'click [data-hook="dropdown-selected-value"] input[type=radio]': 'onSearchMenuTypeClick',
      'shown.bs.dropdown': 'onDropdownShown'
    },

    onDropdownShown: function onDropdownShown(e) {
      var _this = this;

      $(document).one('touchend', function (e) {
        return _this.$('div.dropdown-backdrop').remove();
      }); // removing dropdown-backdrop div enable user open another dropdown menu immediately without extra tap in mobile device when opening this dropdown menu. Refer http://getbootstrap.com/javascript/#dropdowns
    },
    onSearchMenuTypeClick: function onSearchMenuTypeClick(e) {
      var isRefineSearch = this.baseSearchForm.$el.hasClass('refine-search');
      var searchMenuType = $(e.currentTarget).val();
      var searchMenuTypeText = $(e.currentTarget).siblings('span').text();

      //this.$('[data-hook="selected-rooms-text"]').dropdown('toggle'); // close dropdown menu
      //this.$('[data-hook="selected-rooms-text"] span').text(searchMenuTypeText);
      //Rev.trigger('search:menu:changed', searchMenuType.toLowerCase());      
      //this.baseSearchForm.getTotal();

      // update class name for .form-group-searchmenu-type
      //this.$el.removeClass('buy rent sold').addClass(searchMenuTypeText.toLowerCase());

      // dont't update url (https://realestateview.atlassian.net/browse/OV-827)
      // update url
      //if (this.updateUrl) {
      //  var url =  $(e.currentTarget).siblings('span').find('a').attr('href');
      //  Rev.Routers.contractTypeRouter.navigate(url, { trigger: false, replace: true});
      //}
    },
    onEditSavedSearch: function onEditSavedSearch(viewAlertResult) {
      if (!viewAlertResult) return;

      if (viewAlertResult.get('SearchMenuType') == 0) {
        this.$('[data-hook="dropdown-selected-value"] input[type=radio][value="Buy"]').trigger('click');
      } else if (viewAlertResult.get('SearchMenuType') == 1) {
        this.$('[data-hook="dropdown-selected-value"] input[type=radio][value="Rent"]').trigger('click');
      }
    },
    getSelectedMenuType: function getSelectedMenuType(callback) {
      callback(this.$('[data-hook="selected-rooms-text"] span').text().toLowerCase());
    }
  });
})(Rev, jQuery, _, Backbone);
'use strict';

// dependencies : Rev, jquery, underscore, backbone

(function (Rev, $, _, Backbone) {

  'use strict';

  Rev.Views.SearchFormPriceView = Backbone.View.extend({
    initialize: function initialize(options) {
      _.bindAll(this, 'showSelectedPrice', 'reset', 'onDoneButtonClick', 'closeView', 'onSearchMenuChanged', 'onEditSavedSearch');

      var options = options || {};
      this.baseSearchForm = options.baseSearchForm;

      this.showSelectedPriceInSearchForm();
      this.listenTo(Rev, 'refine:search:reset', this.reset);
      this.listenTo(Rev, 'filter-price-close', this.closeView);
      this.listenTo(Rev, 'search:menu:changed', this.onSearchMenuChanged);
      this.listenTo(Rev, 'saved:searches:edit', this.onEditSavedSearch);
    },


    events: {
      'click [data-hook="min-rooms-ranges"] input[type=checkbox]': 'onMinPriceItemClick',
      'click [data-hook="max-rooms-ranges"] input[type=checkbox]': 'onMaxPriceItemClick',
      'click [data-hook="btn-rooms-done"]': 'onDoneButtonClick',
      'click .dropdown-menu': 'onDropdownMenuClick',
      'shown.bs.dropdown': 'onDropdownShown'
    },

    onEditSavedSearch: function onEditSavedSearch(viewAlertResult) {
      if (!viewAlertResult) return;

      // buy
      if (viewAlertResult.get('SearchMenuType') == 0 && this.$el.attr('data-hook') === 'search-form-price-sale') {
        var minPriceVal = viewAlertResult.get('MinPrice') || '';
        var maxPriceVal = viewAlertResult.get('MaxPrice') || '';
        this.$('[data-hook="min-rooms-ranges"] input[type=checkbox][value="' + minPriceVal + '"]').prop('checked', true).click();
        this.$('[data-hook="max-rooms-ranges"] input[type=checkbox][value="' + maxPriceVal + '"]').prop('checked', true).click();
      }

      // rent
      if (viewAlertResult.get('SearchMenuType') == 1 && this.$el.attr('data-hook') === 'search-form-price-lease') {
        var minPriceVal = viewAlertResult.get('MinLeasePrice') || '';
        var maxPriceVal = viewAlertResult.get('MaxLeasePrice') || '';
        this.$('[data-hook="min-rooms-ranges"] input[type=checkbox][value="' + minPriceVal + '"]').prop('checked', true).click();
        this.$('[data-hook="max-rooms-ranges"] input[type=checkbox][value="' + maxPriceVal + '"]').prop('checked', true).click();
      }
    },
    onSearchMenuChanged: function onSearchMenuChanged(searchMenu) {
      if (searchMenu === 'buy' || searchMenu === 'sold') {
        if (this.$el.attr('data-hook') === 'search-form-price-sale') {
          this.$el.show();
        } else {
          this.$el.hide();
        }
      } else if (searchMenu == 'rent') {
        if (this.$el.attr('data-hook') === 'search-form-price-lease') {
          this.$el.show();
        } else {
          this.$el.hide();
        }
      }
    },
    onDropdownMenuClick: function onDropdownMenuClick(e) {
      e.stopPropagation(); // keep dropdown open 
    },
    onDropdownShown: function onDropdownShown(e) {
      this.$('div.dropdown-backdrop').remove();
      //$(document).one('touchend', (e) => this.$('div.dropdown-backdrop').remove()); // removing dropdown-backdrop div enable user open another dropdown menu immediately without extra tap in mobile device when opening this dropdown menu. Refer http://getbootstrap.com/javascript/#dropdowns
    },
    onMinPriceItemClick: function onMinPriceItemClick(e) {
      this.$('[data-hook="min-rooms-ranges"] input[type="checkbox"]').not(e.currentTarget).prop('checked', false);

      var checkedItems = this.$('[data-hook="min-rooms-ranges"] input[type="checkbox"]:checked');

      if (!checkedItems.length) {
        this.$('[data-hook="min-rooms-ranges"] input[type="checkbox"][value=""]').prop('checked', true);
      }

      this.showSelectedPriceInSearchForm();

      //if ($(e.currentTarget).val()) {
      //  Rev.trigger('search:filter:hasValue');
      //}

      this.baseSearchForm.getTotal();

      var minPriceVal = this.$('[data-hook="min-rooms-ranges"] input[type=checkbox]:checked').val();
      this.baseSearchForm.fireGaEvent(Rev.Utils.GaTracking.Action.Price, Rev.Utils.GaTracking.Label.PriceMin + minPriceVal); // fire ga event
    },
    onMaxPriceItemClick: function onMaxPriceItemClick(e) {
      this.$('[data-hook="max-rooms-ranges"] input[type="checkbox"]').not(e.currentTarget).prop('checked', false);

      var checkedItems = this.$('[data-hook="max-rooms-ranges"] input[type="checkbox"]:checked');

      if (!checkedItems.length) {
        this.$('[data-hook="max-rooms-ranges"] input[type="checkbox"][value=""]').prop('checked', true);
      }

      this.showSelectedPriceInSearchForm();

      //if ($(e.currentTarget).val()) {
      //  Rev.trigger('search:filter:hasValue');
      //}

      this.baseSearchForm.getTotal();

      var maxPriceVal = this.$('[data-hook="max-rooms-ranges"] input[type=checkbox]:checked').val();
      this.baseSearchForm.fireGaEvent(Rev.Utils.GaTracking.Action.Price, Rev.Utils.GaTracking.Label.PriceMax + maxPriceVal); // fire ga event
    },
    showSelectedPriceInSearchForm: function showSelectedPriceInSearchForm() {
      var minPriceText = this.$('[data-hook="min-rooms-ranges"] input[type=checkbox]:checked + span').text();
      if (!minPriceText) minPriceText = "Min $";
      var maxPriceText = this.$('[data-hook="max-rooms-ranges"] input[type=checkbox]:checked + span').text();
      if (!maxPriceText) maxPriceText = "Max $";

      var minPriceVal = this.$('[data-hook="min-rooms-ranges"] input[type=checkbox]:checked').val();
      var maxPriceVal = this.$('[data-hook="max-rooms-ranges"] input[type=checkbox]:checked').val();

      if (!minPriceVal && !maxPriceVal) {
        this.showSelectedPrice().any();
      } else if (minPriceVal && !maxPriceVal) {
        this.showSelectedPrice().onlyMin(minPriceText);
      } else if (!minPriceVal && maxPriceVal) {
        this.showSelectedPrice().onlyMax(maxPriceText);
      } else if (minPriceVal && maxPriceVal) {
        this.showSelectedPrice().between(minPriceText, maxPriceText);
      }
    },
    reset: function reset() {
      this.selectDefaultMin();
      this.selectDefaultMax();
      this.showSelectedPriceInSearchForm();
    },
    onDoneButtonClick: function onDoneButtonClick(e) {
      if (e && e.preventDefault) e.preventDefault();
      this.$el.removeClass('open');
    },
    showSelectedPrice: function showSelectedPrice() {
      var self = this,
          $container = this.$('[data-hook="selected-price-text"] > span'),
          any = function any() {
        var template = _.template($('#selected-price-any').html());
        var html = template();
        $container.html(html);
        self.$('.price-label').show();
      },
          between = function between(min, max) {
        var template = _.template($('#selected-price-between').html());
        var html = template({ minPrice: min, maxPrice: max });
        $container.html(html);
        self.togglePriceLabel();
      },
          onlyMin = function onlyMin(min) {
        var template = _.template($('#selected-price-only-min').html());
        var html = template({ minPrice: min });
        $container.html(html);
        self.$('.price-label').show();
      },
          onlyMax = function onlyMax(max) {
        var template = _.template($('#selected-price-only-max').html());
        var html = template({ maxPrice: max });
        $container.html(html);
        self.$('.price-label').show();
      };

      return {
        any: any,
        between: between,
        onlyMin: onlyMin,
        onlyMax: onlyMax
      };
    },
    togglePriceLabel: function togglePriceLabel() {
      if (window.matchMedia("(max-width: 1023px)").matches) {
        self.$('.price-label').hide();
      } else {
        self.$('.price-label').show();
      }
    },
    closeView: function closeView(e) {
      if (e && e.preventDefault) e.preventDefault();

      this.showSelectedPriceInSearchForm();
    }
  });
})(Rev, jQuery, _, Backbone);
'use strict';

// dependencies : Rev, jquery, underscore, backbone

(function (Rev, $, _, Backbone) {

  'use strict';

  Rev.Views.SearchFormPropertyTypeView = Backbone.View.extend({
    initialize: function initialize(options) {
      _.bindAll(this, 'closeView', 'onEditSavedSearch');

      var options = options || {};
      this.baseSearchForm = options.baseSearchForm;

      this.showSelectedItemsInTextbox();
      this.shouldAnyOptionChecked();

      this.listenTo(Rev, 'saved:searches:edit', this.onEditSavedSearch);
    },


    events: {
      'click .property-type-item:not(.property-type-item-any) input[type=checkbox]': 'onPropertyTypeCheck',
      'click .property-type-item-any input[type=checkbox]': 'onAnyPropertyTypeCheck',
      'click .dropdown-menu': 'onDropdownMenuClick',
      'shown.bs.dropdown': 'onDropdownShown'
    },

    onEditSavedSearch: function onEditSavedSearch(viewAlertResult) {
      if (!viewAlertResult) return;

      if (viewAlertResult.get('PropertyTypes')) {
        var propertyTypes = viewAlertResult.get('PropertyTypes');
        this.$('.property-type-item:not(.property-type-item-any) input[type=checkbox]').each(function (index, element) {
          if (propertyTypes.indexOf($(element).val()) > -1) {
            if (!$(element).prop('checked')) $(element).trigger('click');
          } else {
            if ($(element).prop('checked')) $(element).trigger('click');
          }
        });
      }
    },
    onDropdownMenuClick: function onDropdownMenuClick(e) {
      e.stopPropagation(); // keep dropdown open 
    },
    onDropdownShown: function onDropdownShown(e) {
      var _this = this;

      $(document).one('touchend', function (e) {
        return _this.$('div.dropdown-backdrop').remove();
      }); // removing dropdown-backdrop div enable user open another dropdown menu immediately without extra tap in mobile device when opening this dropdown menu. Refer http://getbootstrap.com/javascript/#dropdowns
    },
    onPropertyTypeCheck: function onPropertyTypeCheck(e) {
      var _this2 = this;

      var $currentEl = $(e.currentTarget);
      setTimeout(function () {
        return _this2.onPropertyTypeChangeHandler($currentEl);
      }, 1);
      //Rev.trigger('search:filter:changed'); 
      this.baseSearchForm.getTotal();
      if ($currentEl.is(':checked')) {
        this.baseSearchForm.fireGaEvent(Rev.Utils.GaTracking.Action.Type, $currentEl.val()); // fire ga event
      }
    },
    onAnyPropertyTypeCheck: function onAnyPropertyTypeCheck(e) {
      this.$('.property-type-item-any input[type=checkbox]').prop('checked', true);
      this.$('.property-type-item:not(.property-type-item-any) input[type=checkbox]').prop('checked', false);
      //this.$('[data-hook="property-type-input"]').val('');
      this.$('[data-hook="property-type-input"]').text('Any');
      //Rev.trigger('search:filter:changed'); 
      this.baseSearchForm.getTotal();
      if ($(e.currentTarget).is(':checked')) {
        this.baseSearchForm.fireGaEvent(Rev.Utils.GaTracking.Action.Type, ''); // fire ga event
      }
    },
    onPropertyTypeChangeHandler: function onPropertyTypeChangeHandler($checkbox) {
      this.showSelectedItemsInTextbox();
      this.shouldAnyOptionChecked();
    },
    showSelectedItemsInTextbox: function showSelectedItemsInTextbox() {
      var _this3 = this;

      var selectedTextArray = _.map(this.$('.property-type-item:not(.property-type-item-any) input[type=checkbox]:checked ~ span'), function (item) {
        return _this3.$(item).text();
      });
      var selectedText = selectedTextArray.length ? selectedTextArray.join(', ') : "Any";
      this.$('[data-hook="property-type-input"]').text(selectedText);
    },
    shouldAnyOptionChecked: function shouldAnyOptionChecked() {
      if (this.$('.property-type-item:not(.property-type-item-any) input[type=checkbox]:checked').length > 0) {
        this.$('.property-type-item-any input[type=checkbox]').prop('checked', false);
      } else {
        this.$('.property-type-item-any input[type=checkbox]').prop('checked', true);
      }
    },
    closeView: function closeView(e) {
      if (e && e.preventDefault) e.preventDefault();

      //if(this.$('.property-type-item input[type=checkbox]:checked').length) {
      //  Rev.trigger('search:filter:hasValue');        
      //}

      //Rev.trigger('search:ga:fire', Rev.Utils.GaTracking.Action.Type, this.$pttagsinput.val()); // fire ga event
      //this.baseSearchForm.fireGaEvent(Rev.Utils.GaTracking.Action.Type, $currentEl.val()); // fire ga event
    }

    /* Edit this function to reset data 
    reset() {
      var self = this;
      this.collection.each(function (item) {
        var $checkbox = self.$('.property-type-item input[type=checkbox][value=' + item.get('Value') + ']');
        $checkbox.siblings('i').removeClass('checked');
        $checkbox.siblings('span').removeClass('checked');
        self.removePropertyTypeItem(item.get('Value'), item.get('Text'));
      });
    },*/

    /* Edit this function to bind existing data
    bindCheckedItems() {
      var self = this;
      if (this.collection && this.collection.size() > 0) {
        this.collection.each(function (item) {
          if (item.get('Selected')) {
            var $cb = self.$('.property-type-item input[type=checkbox][value=' + item.get('Value') + ']');
            self.togglePropertyTypeItem($cb);
            self.addPropertyTypeItem(item.get('Value'), item.get('Text'));
          }
        });
      }
    },*/

  });
})(Rev, jQuery, _, Backbone);
'use strict';

// dependencies : Rev, jquery, underscore, backbone

(function (Rev, $, _, Backbone) {

  'use strict';

  Rev.Views.SearchFormRoomsView = Backbone.View.extend({
    initialize: function initialize(options) {
      var options = options || {};
      this.baseSearchForm = options.baseSearchForm;
      this.roomType = options.roomType;

      _.bindAll(this, 'fireGaEvent', 'onEditSavedSearch');

      this.showSelectedRoomsInSearchForm();

      this.listenTo(Rev, 'saved:searches:edit', this.onEditSavedSearch);
    },


    events: {
      'click [data-hook="min-rooms-ranges"] input[type=radio]': 'onRoomItemClick',
      'click [data-hook="max-rooms-ranges"] input[type=radio]': 'onRoomItemClick',
      'click [data-hook="btn-rooms-done"]': 'onDoneButtonClick',
      'click .dropdown-menu': 'onDropdownMenuClick',
      'shown.bs.dropdown': 'onDropdownShown'
    },

    onEditSavedSearch: function onEditSavedSearch(viewAlertResult) {
      if (!viewAlertResult) return;

      var minValue = '';

      if (this.$el.attr('data-hook') == 'range-bedrooms' && viewAlertResult.get('MinBedrooms')) {
        minValue = viewAlertResult.get('MinBedrooms');
      }

      if (this.$el.attr('data-hook') == 'range-bathrooms' && viewAlertResult.get('MinBathrooms')) {
        minValue = viewAlertResult.get('MinBathrooms');
      }

      if (this.$el.attr('data-hook') == 'range-carspaces' && viewAlertResult.get('MinParkingSpaces')) {
        minValue = viewAlertResult.get('MinParkingSpaces');
      }

      //if (minValue) {
      this.$('[data-hook="min-rooms-ranges"] input[type=radio][value="' + minValue + '"]').prop('checked', true);
      this.showSelectedRoomsInSearchForm();
      //}
    },
    onDropdownMenuClick: function onDropdownMenuClick(e) {
      e.stopPropagation(); // keep dropdown open 
    },
    onDropdownShown: function onDropdownShown(e) {
      this.$('div.dropdown-backdrop').remove();
      //$(document).one('touchend', (e) => this.$('div.dropdown-backdrop').remove()); // removing dropdown-backdrop div enable user open another dropdown menu immediately without extra tap in mobile device when opening this dropdown menu. Refer http://getbootstrap.com/javascript/#dropdowns
    },
    onDoneButtonClick: function onDoneButtonClick(e) {
      if (e && e.preventDefault) e.preventDefault();
      this.$el.removeClass('open');
    },
    onRoomItemClick: function onRoomItemClick(e) {
      this.showSelectedRoomsInSearchForm();

      //if ($(e.currentTarget).val()) {
      //  Rev.trigger('search:filter:hasValue');
      //}

      this.fireGaEvent($(e.currentTarget).val());
      this.$el.removeClass('open');

      this.baseSearchForm.getTotal();
    },
    showSelectedRoomsInSearchForm: function showSelectedRoomsInSearchForm() {
      var minPriceText = this.$('[data-hook="min-rooms-ranges"] input[type=radio]:checked + span').text();
      var minPriceVal = this.$('[data-hook="min-rooms-ranges"] input[type=radio]:checked').val();

      this.$('[data-hook="selected-rooms-text"] > span').text(minPriceText || 'Any');
    },
    fireGaEvent: function fireGaEvent(labelValue) {
      var action = '';
      var label = '';

      if (this.roomType == 'bedrooms') {
        action = Rev.Utils.GaTracking.Action.Bedrooms;
        label = Rev.Utils.GaTracking.Label.Bedrooms + labelValue;
      } else if (this.roomType == 'bathrooms') {
        action = Rev.Utils.GaTracking.Action.Bathrooms;
        label = Rev.Utils.GaTracking.Label.Bathrooms + labelValue;
      } else if (this.roomType == 'carparks') {
        action = Rev.Utils.GaTracking.Action.Carparks;
        label = Rev.Utils.GaTracking.Label.Carparks + labelValue;
      }

      this.baseSearchForm.fireGaEvent(action, label); // fire ga event
    }

    /*showSelectedRoomsInSearchForm() {
      var minPriceText = this.$('[data-hook="min-rooms-ranges"] input[type=radio]:checked + span').text();
      var maxPriceText = this.$('[data-hook="max-rooms-ranges"] input[type=radio]:checked + span').text();
        var minPriceVal = this.$('[data-hook="min-rooms-ranges"] input[type=radio]:checked').val();
      var maxPriceVal = this.$('[data-hook="max-rooms-ranges"] input[type=radio]:checked').val();
        if (!minPriceVal && !maxPriceVal) {
        this.showSelectedRooms().any();
      } else if (minPriceVal && !maxPriceVal) {
        this.showSelectedRooms().onlyMin(minPriceText);
      } else if (!minPriceVal && maxPriceVal) {
        if (maxPriceVal === '1') {
          this.showSelectedRooms().same(maxPriceText);
        }else{
          this.showSelectedRooms().between('1', maxPriceText);  // show '1' instead of not showing min value
        }
      } else if (minPriceVal && maxPriceVal) {
        if (minPriceVal === maxPriceVal) {
          this.showSelectedRooms().same(minPriceText);
        } else {
          this.showSelectedRooms().between(minPriceText, maxPriceText);
        }
      }
        Rev.trigger('search:filter:changed'); 
    },
      showSelectedRooms(){
      var
        self = this,
        $container = this.$('[data-hook="selected-rooms-text"]'),
          any = function () {
          var template = _.template($('#selected-rooms-any').html());
          var html = template();
          $container.html(html);
        },
          between = function (min, max) {
          var template = _.template($('#selected-rooms-between').html());
          var html = template({minPrice: min, maxPrice: max});
          $container.html(html);
        },
          onlyMin = function (min) {
          var template = _.template($('#selected-rooms-only-min').html());
          var html = template({ minPrice: min});
          $container.html(html);
        },
          onlyMax = function (max) {
          var template = _.template($('#selected-rooms-only-max').html());
          var html = template({ maxPrice: max });
          $container.html(html);
        },
          same = function (price) {
          var template = _.template($('#selected-rooms-same').html());
          var html = template({ price : price });
          $container.html(html);
        }
      ;
        return {
        any : any,
        between : between,
        onlyMin : onlyMin,
        onlyMax : onlyMax,
        same : same
      };
    },*/

  });
})(Rev, jQuery, _, Backbone);
'use strict';

// dependencies : Rev, jquery, underscore, backbone

(function (Rev, $, _, Backbone) {

    'use strict';

    Rev.Views.SearchFormView = Backbone.View.extend({
        initialize: function initialize(options) {
            _.bindAll(this, 'fireGaEvent', 'getTotal', 'onSearchSubmitRequested', 'submitForm', 'onEditSavedSearch', 'onSavedSearchDeleted', 'onDropdownShown');

            if (options) {
                this.isRefineSearch = options.isRefineSearch;
                this.updateUrl = options.updateUrl;
                this.isSuburbRequired = options.isSuburbRequired;
            }

            this.initializeSubViews();
            this.listenTo(Rev, 'search:ga:fire', this.fireGaEvent);
            this.listenTo(Rev, 'sort:changed', this.onSortChanged);
            this.listenTo(Rev, 'search:submit', this.onSearchSubmitRequested);
            this.listenTo(Rev, 'search:filter:changed', this.getTotal);
            this.listenTo(Rev, 'saved:searches:edit', this.onEditSavedSearch);
            this.listenTo(Rev, 'saved:searches:deleted', this.onSavedSearchDeleted);

            //this.$('.dropdown-more-filters').on('shown.bs.dropdown', this.onDropdownShown);
        },


        events: {
            'click [data-hook="btn-submit-search-filters"]': 'onClickSubmitSearch',
            'click [data-hook="btn-save-search"]': 'onClickSaveSearch',
            'click [data-hook="btn-save-viewalert"]': 'onClickSaveViewAlert',
            'click .dropdown-more-filters .dropdown-menu': 'onDropdownMenuClick',
            'shown.bs.dropdown .dropdown-more-filters': 'onDropdownShown',
            'hidden.bs.dropdown .dropdown-more-filters': 'onDropdownHidden',
            'click .filter-header .back': 'closeRefineSearch'
        },

        initializeSubViews: function initializeSubViews() {
            this.menuTypeView = new Rev.Views.SearchFormMenuTypeView({ el: this.$('.form-group-searchmenu-type'), baseSearchForm: this, updateUrl: this.updateUrl });
            this.locationView = new Rev.Views.SearchFormLocationView({ el: this.$('.search-form-location'), model: this.model, isRefineSearch: this.isRefineSearch, baseSearchForm: this, isSuburbRequired: this.isSuburbRequired });
            this.salePriceView = new Rev.Views.SearchFormPriceView({ el: this.$('[data-hook="search-form-price-sale"]'), baseSearchForm: this });
            this.leasePriceView = new Rev.Views.SearchFormPriceView({ el: this.$('[data-hook="search-form-price-lease"]'), baseSearchForm: this });

            if (this.model) {
                this.propertyTypeView = new Rev.Views.SearchFormPropertyTypeView({ el: this.$('.search-form-property-type'), collection: new Rev.Collections.CheckboxItems(this.model.get('PropertyTypes')), baseSearchForm: this });
            } else {
                this.propertyTypeView = new Rev.Views.SearchFormPropertyTypeView({ el: this.$('.search-form-property-type'), baseSearchForm: this });
            }

            this.bedroomsView = new Rev.Views.SearchFormRoomsView({ el: this.$('[data-hook="range-bedrooms"]'), roomType: 'bedrooms', baseSearchForm: this });
            this.bathroomsView = new Rev.Views.SearchFormRoomsView({ el: this.$('[data-hook="range-bathrooms"]'), roomType: 'bathrooms', baseSearchForm: this });
            this.carparksView = new Rev.Views.SearchFormRoomsView({ el: this.$('[data-hook="range-carspaces"]'), roomType: 'carparks', baseSearchForm: this });
            this.keywordView = new Rev.Views.SearchFormKeywordView({ el: this.$('.form-group.keywords'), baseSearchForm: this, isRefineSearch: this.isRefineSearch });
        },
        closeRefineSearch: function closeRefineSearch(e) {
            e.preventDefault();
            this.$('.dropdown-more-filters').removeClass('open');
            $('body').removeClass('modal-open');
        },
        onDropdownMenuClick: function onDropdownMenuClick(e) {
            e.stopPropagation(); // keep dropdown open 
        },
        onDropdownShown: function onDropdownShown(e) {
            this.$('.dropdown-backdrop').remove();

            //$(document).one('touchend', (e) => this.$('div.dropdown-backdrop').remove()); // removing dropdown-backdrop div enable user open another dropdown menu immediately without extra tap in mobile device when opening this dropdown menu. Refer http://getbootstrap.com/javascript/#dropdowns

            $('body').addClass('modal-open');
        },
        onDropdownHidden: function onDropdownHidden(e) {
            $('body').removeClass('modal-open');
        },
        onClickSaveSearch: function onClickSaveSearch(e) {
            var _this = this;

            if (e && e.preventDefault) e.preventDefault();
            $(e.currentTarget).button('loading');

            var $form = $(e.currentTarget).closest('form');

            this.fireGaEvent(Rev.Utils.GaTracking.Action.SaveThisSearch, Rev.Utils.GaTracking.Label.SearchSaved);

            if (!this.isEditingSavedSearch) {
                Rev.Utils.saveSearch($form, function () {
                    Rev.trigger('saved-searche:refresh', _this.$('[data-hook="hidden-viewalert-id"]').val());
                    _this.$('[data-hook="btn-save-search"]').button('reset');
                });
            } else {
                Rev.Utils.updateSearch($form, function () {
                    //Rev.trigger('saved-searche:refresh', this.$('[data-hook="hidden-viewalert-id"]').val());
                    //this.$('[data-hook="btn-save-search"]').button('reset'); 
                    setTimeout(function () {
                        return window.location.reload(true);
                    }, 1000);
                });
            }
        },
        onClickSaveViewAlert: function onClickSaveViewAlert(e) {
            e.preventDefault();
            Rev.Utils.showViewAlertOptionModal();
        },
        onEditSavedSearch: function onEditSavedSearch(viewAlertResult) {
            var _this2 = this;

            this.isEditingSavedSearch = true;
            this.$('[data-hook="hidden-viewalert-id"]').val(viewAlertResult.get('Id'));
            this.$('[data-hook="hidden-viewalert-frequency"]').val(viewAlertResult.get('FrequencyVal'));

            // delaying to show total results is because each sub views will show total results with no order
            setTimeout(function () {
                return _this2.getTotal();
            }, 500);
        },
        onSavedSearchDeleted: function onSavedSearchDeleted(viewAlertResult) {
            this.isEditingSavedSearch = false;
            this.$('[data-hook="hidden-viewalert-id"]').val('');
            this.$('[data-hook="hidden-viewalert-frequency"]').val('');
        },
        onSortChanged: function onSortChanged(sortValue) {
            this.$('[data-hook="hidden-sort-value"]').val(sortValue);

            // When changing sorting options, remove any auction or inspections that may be set
            this.$('[data-hook="hidden-auction-date"]').val("");
            this.$('[data-hook="hidden-inspection-date"]').val("");

            // fire submit event
            this.submitForm();
        },
        fireGaEvent: function fireGaEvent(action, label) {
            var category = 'home-';

            if (this.$el.hasClass('refine-search')) {
                category = 'refinesearch-';
            }

            var searchMenuType = this.$('[data-hook="dropdown-selected-value"] input[type=radio]:checked').val();

            if (searchMenuType) {
                searchMenuType = searchMenuType.trim();

                if (searchMenuType == 'Buy') {
                    category += 'buy';
                } else if (searchMenuType == 'Rent') {
                    category += 'rent';
                } else if (searchMenuType == 'Sold') {
                    category += 'sold';
                }
            }

            if (this.isEditingSavedSearch) {
                category = Rev.Utils.GaTracking.Category.RefineSearchSavedSearches;
            }

            // in case of refine search, check if search form is visible or not, if not, don't fire ga events
            if ((category === 'refinesearch-buy' || category === 'refinesearch-rent' || category === 'refinesearch-sold') && !$('.result-header').hasClass('open')) {
                return;
            }

            // in case of editing saved search, check if search form is visible or not, if not, don't fire ga events
            if (category === Rev.Utils.GaTracking.Category.RefineSearchSavedSearches && !$('.new-search-form').hasClass('open')) {
                return;
            }

            Rev.Utils.GaTracking.trackGaEvent(category, action, label);
        },
        submitForm: function submitForm() {
            var _this3 = this;

            // validate suburb is entered
            Rev.trigger('location-required-message:hide');
            if (!this.$('[data-hook="location-input"]').val() && this.isSuburbRequired) {
                Rev.trigger('location-required-message:show');
                return;
            } else {
                var wait = Rev.Utils.isiPad() ? 1000 : 50;
                this.$el.addClass('loading');

                var locationInput = $("#location");
                var regionsInput = $("#regions");
                var locations = locationInput.val().split(',');
                var suburbs = [];
                var regions = [];

                locations.forEach(function (item) {
                    var temp = item.split('|');
                    if ($.isNumeric(temp[temp.length - 1])) {
                        suburbs.push(item);
                    } else {
                        regions.push(item);
                    }
                });

                locationInput.val(suburbs.join(','));
                regionsInput.val(regions.join(','));

                setTimeout(function () {
                    return _this3.$('form.search-filters-form').submit();
                }, wait);
            }
        },
        onSearchSubmitRequested: function onSearchSubmitRequested() {
            this.submitForm();
        },
        onClickSubmitSearch: function onClickSubmitSearch(e) {
            this.submitForm();
        },
        getTotal: function getTotal() {
            var self = this;
            var $form = this.$('.search-filters-form');

            var locationInput = $("#location");
            var regionsInput = $("#regions");
            var locations = locationInput.val().split(',');
            var suburbs = [];
            var regions = [];

            locations.forEach(function (item) {
                if (item !== "") {
                    var temp = item.split('|');
                    if ($.isNumeric(temp[temp.length - 1])) {
                        suburbs.push(item);
                    } else {
                        regions.push(item);
                    }
                }
            });

            locationInput.val(suburbs.join(','));
            regionsInput.val(regions.join(','));
            self.$('[data-hook="btn-submit-search-filters"]').addClass('btn-submit-loading');

            // revert location search val back to default 
            locationInput.val(locations.join(','));
        },
        remove: function remove() {
            if (this.menuTypeView) this.menuTypeView.remove();
            if (this.locationView) this.locationView.remove();
            if (this.salePriceView) this.salePriceView.remove();
            if (this.leasePriceView) this.leasePriceView.remove();
            if (this.propertyTypeView) this.propertyTypeView.remove();
            if (this.bedroomsView) this.bedroomsView.remove();
            if (this.bathroomsView) this.bathroomsView.remove();
            if (this.carparksView) this.carparksView.remove();
            if (this.keywordView) this.keywordView.remove();

            this.off();
            this.stopListening();

            //call the superclass remove method
            Backbone.View.prototype.remove.apply(this, arguments);
        }
    });
})(Rev, jQuery, _, Backbone);
'use strict';

(function (Rev, $, _, Backbone) {

    'use strict';

    Rev.Views.SeoDescriptionView = Backbone.View.extend({
        initialize: function initialize(options) {
            _.bindAll(this, 'showView', 'closeView');
        },

        events: {
            'click [data-hook="quick-links-expander"]': 'showView',
            'click [data-hook="close"]': 'closeView'
        },

        closeView: function closeView(e) {
            if (e && e.preventDefault) e.preventDefault();

            $('.rev-modal-backdrop').hide();
            this.$el.modal('hide');
        },
        showView: function showView(e) {
            if (e && e.preventDefault) e.preventDefault();
            $('[data-hook="seo-description"]').hide();
        }
    });
})(Rev, jQuery, _, Backbone);
'use strict';

// dependencies : Rev, jquery, underscore, backbone

(function (Rev, $, _, Backbone) {

    'use strict';

    Rev.Views.ShareWithFriendView = Backbone.View.extend({
        initialize: function initialize(options) {
            var _this = this;

            this.options = options || {};
            this.errorPlaceHolder = this.$('[data-hook="share-with-friend-validation-errors-placeholder"]');
            setTimeout(function () {
                return _this.$('[data-hook="email-to"]').focus();
            }, 500);
        },

        events: {
            'click [data-hook="close"]': 'closeView',
            'hidden.bs.modal': 'onModalHidden',
            'click [data-hook="btn-send"]': 'onSendClick'
        },

        onModalHidden: function onModalHidden(e) {
            $('.list-result-items').removeClass('modal-open');
        },
        onSendClick: function onSendClick(e) {
            var _this2 = this;

            e.preventDefault();
            $(e.currentTarget).button('loading');

            var $form = this.$('[data-hook="share-with-friend-form"]');
            var actionUrl = $form.attr('action');
            $.post(actionUrl, $form.serialize()).done(function (result) {
                if (result.errors) {
                    Rev.Utils.showErrors(result.errors, _this2.errorPlaceHolder);
                } else {
                    _this2.showSuccessMessage();
                    setTimeout(function () {
                        return _this2.closeView();
                    }, 1000);
                }
            }).fail(function (result) {
                Rev.Utils.showErrors(result.errors, _this2.errorPlaceHolder);
            }).always(function () {
                _this2.$('[data-hook="btn-send"]').button('reset');
            });

            if (this.options.gaCategory) {
                Rev.Utils.GaTracking.trackGaEvent(this.options.gaCategory, Rev.Utils.GaTracking.Action.SendToFriend, Rev.Utils.GaTracking.Label.SendEmailToFriend);
            }
        },
        showSuccessMessage: function showSuccessMessage(message) {
            Rev.Utils.showSuccessMessage(message || 'Email sent');

            // clear error messages
            Rev.Utils.clearErrors(this.errorPlaceHolder);

            // return to display mode
            this.$('form .form-group').removeClass('editing show');
        },
        closeView: function closeView(e) {
            if (e && e.preventDefault) e.preventDefault();
            $('.rev-modal-backdrop').hide();
            this.$el.modal('hide');
        },
        remove: function remove() {
            this.closeView();
            this.off();
            Backbone.View.prototype.remove.apply(this, arguments); //call the superclass remove method
        }
    });
})(Rev, jQuery, _, Backbone);
'use strict';

var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };

(function (Rev, $, _, Backbone) {

  'use strict';

  Rev.Views.SidebarActionsView = Backbone.View.extend({
    initialize: function initialize(options) {
      this.options = _extends({}, options);

      // detect user was trying to save search
      this.continueSaveSearch();
    },


    events: {
      'click [data-hook="btn-add-auction"]': 'onAddAuctionAlertClick',
      'click [data-hook="btn-save-search"]': 'onClickSaveSearch'
    },

    onClickSaveSearch: function onClickSaveSearch(e) {
      e.preventDefault();

      var authSuccessCallbackForSaveSearch = function authSuccessCallbackForSaveSearch() {
        localStorage.setItem('openSaveSearchWindow', true);
        setTimeout(function () {
          return location.reload(true);
        }, 100);
      };

      Rev.Utils.Auth.isUserAuthenticated().then(function () {
        Rev.Utils.showViewAlertOptionModal();
      }).fail(function () {
        Rev.Utils.showAuthModal('login', null, true, null, authSuccessCallbackForSaveSearch, authSuccessCallbackForSaveSearch);
      });

      Rev.Utils.GaTracking.trackGaEvent(Rev.Utils.GaTracking.Category.SearchResults, Rev.Utils.GaTracking.Action.SaveThisSearch, Rev.Utils.GaTracking.Label.SearchSaved);
    },
    onAddAuctionAlertClick: function onAddAuctionAlertClick(e) {
      var _this = this;

      e.preventDefault();
      var self = this;
      $(e.currentTarget).button('loading');

      var callbackAfterSave = function callbackAfterSave() {
        setTimeout(function () {
          window.location.reload(true);
        }, 500);
      };

      var afterAuthCallback = function afterAuthCallback() {
        self.refreshAntiforgeryToken(function () {
          self.saveAuctionAlert(self.$(e.currentTarget).closest('form.auction-alert-append-form'), callbackAfterSave);
        });
      };
      var closeAuthWindowCallback = function closeAuthWindowCallback() {
        return self.$('[data-hook="btn-add-auction"]').button('reset');
      };
      var callbackIfAlreadyAuthenticated = function callbackIfAlreadyAuthenticated() {
        return self.saveAuctionAlert(_this.$(e.currentTarget).closest('form.auction-alert-append-form'));
      };

      Rev.Utils.saveAuctionAlert(afterAuthCallback, afterAuthCallback, closeAuthWindowCallback, callbackIfAlreadyAuthenticated);

      Rev.Utils.GaTracking.trackGaEvent(Rev.Utils.GaTracking.Category.SearchResults, Rev.Utils.GaTracking.Action.AddAuctionAlert, Rev.Utils.GaTracking.Label.AlertSaved);
    },
    continueSaveSearch: function continueSaveSearch() {
      var openSaveSearchWindow = localStorage.getItem('openSaveSearchWindow');
      if (openSaveSearchWindow) {
        localStorage.removeItem('openSaveSearchWindow');
        Rev.Utils.Auth.isUserAuthenticated().then(function () {
          Rev.Utils.showViewAlertOptionModal();
        }).fail(function () {

          var authSuccessCallbackForSaveSearch = function authSuccessCallbackForSaveSearch() {
            localStorage.setItem('openSaveSearchWindow', true);
            setTimeout(function () {
              return location.reload(true);
            }, 100);
          };

          Rev.Utils.showAuthModal('login', null, true, null, authSuccessCallbackForSaveSearch, authSuccessCallbackForSaveSearch);
        });
      }
    },
    refreshAntiforgeryToken: function refreshAntiforgeryToken(successCallback) {
      $.get('/refreshtoken/').done(function (html) {
        var tokenValue = $('<div />').html(html).find('input[type="hidden"]').val();
        $('input[name="__RequestVerificationToken"]').val(tokenValue);
        if (successCallback) successCallback();
      });
    },
    saveAuctionAlert: function saveAuctionAlert($form, callback) {
      var _this2 = this;

      var actionUrl = $form.attr('action');

      $.post(actionUrl, $form.serialize()).done(function (result) {
        if (result.errors) {
          Rev.Utils.showErrorMessage(_.pluck(result.errors, 'Value').join(', '));
        } else {
          Rev.Utils.showSuccessMessage('Auction alerts saved');
          if (callback) callback();
        }
      }).fail(function (result) {
        Rev.Utils.showErrorMessage('Auction alerts not saved');
      }).always(function () {
        _this2.$('[data-hook="btn-add-auction"]').button('reset');
      });
    }
  });
})(Rev, jQuery, _, Backbone);
'use strict';

(function (Rev, $, _, Backbone) {

    'use strict';

    Rev.Views.SignupView = Backbone.View.extend({
        el: '.signup-body',

        initialize: function initialize() {},


        events: {
            'click [data-hook="close-signup"]': 'toggleSignup',
            'click [data-hook="submit-signup-form"]': 'submitSignup',
            'click [data-hook="link-to-login"]': 'toggleLogin',
            'click [data-hook="btn-login-fb"]': 'loginFB'
        },

        loginFB: function loginFB(e) {
            if (e && e.preventDefault) e.preventDefault();
            var self = this;

            if (Rev.Utils.isiPad()) {
                var appid = window.Rev.fbAppId;
                var redirectUri = encodeURI(window.location.origin + '/fb-login-redirect');
                window.location = encodeURI('https://graph.facebook.com/oauth/authorize?client_id=' + appid + '&scope=public_profile,email&redirect_uri=' + redirectUri + '&response_type=token');
            } else {
                FB.login(function (response) {
                    FB.api('/' + response.authResponse.userID, function (result) {
                        return self.submitLoginFB(response.authResponse.accessToken, response.authResponse.userID, result.first_name, result.last_name);
                    });
                }, { scope: 'public_profile,email' });
            }
        },
        submitLoginFB: function submitLoginFB(fbAccessToken, fbUid, fbFirstName, fbLastName) {
            var self = this;
            var url = this.$('form#login-form-fb').attr('action');

            var data = {};
            data["__RequestVerificationToken"] = this.$('form#login-form-fb [name="__RequestVerificationToken"]').val();
            data["fbAccessToken"] = fbAccessToken;
            data["fbUid"] = fbUid;
            data["fbFirstName"] = fbFirstName;
            data["fbLastName"] = fbLastName;

            $('[data-hook="btn-login-fb"]').button('loading');

            $.post(url, data).done(function (result) {
                if (!result.errors) {
                    if (Rev.AuthSignupSuccessCallback) {
                        Rev.AuthSignupSuccessCallback();
                        Rev.AuthSignupSuccessCallback = null;
                    } else {
                        if (location.href.toLowerCase().indexOf('?returnurl') > 0) {
                            var returnUrl = Rev.Utils.parseUrl(location.href.toLowerCase()).returnurl;
                            location.href = decodeURIComponent(returnUrl);
                        } else {

                            // check cookie if there is return url saved
                            var returnUrl = $.cookie('return_url');

                            if (returnUrl) {
                                $.removeCookie('return_url', { path: '/' });
                                location.href = decodeURIComponent(returnUrl);
                            } else {
                                location.reload(true);
                            }
                        }
                    }
                } else {
                    $('#auth-views-modal').addClass('showing-error');
                    Rev.Utils.showErrors(result.errors, self.$('[data-hook="fb-signup-validation-errors-placeholder"]'));
                }
            }).fail(function (result) {
                $('#auth-views-modal').addClass('showing-error');
                Rev.Utils.showErrors(result.errors, self.$('[data-hook="fb-signup-validation-errors-placeholder"]'));
            }).always(function () {
                self.$('[data-hook="btn-login-fb"]').button('reset');
            });
        },
        toggleLogin: function toggleLogin(e) {
            if (e && e.preventDefault) e.preventDefault();
            Rev.trigger('login:toggle');
        },
        toggleSignup: function toggleSignup(e) {
            if (e && e.preventDefault) e.preventDefault();
            Rev.trigger('signup:toggle');
        },
        submitSignup: function submitSignup(e) {
            e.preventDefault();

            var self = this;
            var url = this.$('form#signup-form').attr('action');

            $(e.currentTarget).button('loading');
            $.post(url, this.$('form#signup-form').serialize()).done(function (result) {
                if (!result.errors) {
                    if (Rev.AuthSignupSuccessCallback) {
                        Rev.AuthSignupSuccessCallback();
                        Rev.AuthSignupSuccessCallback = null;
                    } else {
                        if (location.href.toLowerCase().indexOf('?returnurl') > 0) {
                            var returnUrl = Rev.Utils.parseUrl(location.href.toLowerCase()).returnurl;
                            location.href = decodeURIComponent(returnUrl);
                        } else {
                            // check cookie if there is return url saved
                            var returnUrl = $.cookie('return_url');

                            if (returnUrl) {
                                $.removeCookie('return_url', { path: '/' });
                                location.href = decodeURIComponent(returnUrl);
                            } else {
                                location.reload(true);
                            }
                        }
                    }
                } else {
                    $('#auth-views-modal').addClass('showing-error');
                    Rev.Utils.showErrors(result.errors, self.$('[data-hook="email-signup-validation-errors-placeholder"]'));
                }
            }).fail(function (result) {
                $('#auth-views-modal').addClass('showing-error');
                Rev.Utils.showErrors(result.errors, self.$('[data-hook="email-signup-validation-errors-placeholder"]'));
            }).always(function () {
                self.$('[data-hook="submit-signup-form"]').button('reset');
            });
        }
    });
})(Rev, jQuery, _, Backbone);
'use strict';

// dependencies : Rev, jquery, underscore, backbone

(function (Rev, $, _, Backbone) {

  'use strict';

  Rev.Views.AgencyDetailsView = Backbone.View.extend({
    el: '.details-page',

    initialize: function initialize() {
      _.bindAll(this, 'hideView', 'heroImageError');

      Rev.trigger('new-search-button:hide');
      Rev.trigger('back-to-search-results-button:hide');

      this.$('[data-hook="agency-hero-image"]').error(this.heroImageError).attr('src', this.model.get('HeroPhoto'));
    },


    events: {
      'click [data-hook="contact-agency-phone-link"]': 'onPhoneAgencyClick',
      'click [data-hook="contact-agency-email"] button, [data-hook="contact-agency-email"] a': 'openEmailAgentModal'
    },

    heroImageError: function heroImageError(instance) {
      //this.$el.addClass('no-hero-image');
      var images = ['suburb-at-dusk_v1.jpg', 'home-with-grass_v1.jpg', 'double-story-home-at-dusk_v1.jpg', 'melbourne-beach-front-with-palms_v1.jpg', 'vibrant-home-dining-room-and-deck_v1.jpg'];

      var x = Math.floor(Math.random() * 5); // randomly between 0 ~ 4
      this.$('[data-hook="agency-hero-image"]').attr('src', '/assets/content/images/' + images[x]);
      this.$('.agency-hero img').addClass('random-image');
    },
    hideView: function hideView() {
      this.$el.hide();
    },
    openEmailAgentModal: function openEmailAgentModal(e) {
      Rev.Utils.showContactAgentModal(this.model.get('Id'), null, this.model.get('AgencyName'), this.model.get('Email'));
    },
    onPhoneAgencyClick: function onPhoneAgencyClick(e) {
      //e.preventDefault();

      this.$('[data-hook="contact-agency-phone-number"]').toggleClass('reveal');
      this.$('.contact-agency-phone').toggleClass('reveal');
      this.$('.contact-agents').toggleClass('reveal');

      if (!this.agencyPhoneLeadEventFired) {
        this.agencyPhoneLeadEventFired = true;
        Rev.Utils.LeadTracking.sendPhoneAgencyEvent(this.model.get('Id'));

        // remov data-ga attribute as well to avoid ga events fire multiple times
        setTimeout(function () {
          return $(e.currentTarget).removeAttr('data-ga-event');
        }, 1000);
      }
    },
    remove: function remove() {
      $('#rev-overlay').hide();

      this.off();
      this.stopListening();

      //call the superclass remove method
      Backbone.View.prototype.remove.apply(this, arguments);
    }
  });
})(Rev, jQuery, _, Backbone);
'use strict';

// dependencies : Rev, jquery, underscore, backbone, slick.js

(function (Rev, $, _, Backbone) {

  'use strict';

  Rev.Views.AgencyResultsItemView = Backbone.View.extend({
    initialize: function initialize() {
      _.bindAll(this, 'toggleUponViewport');

      this.listenTo(Rev, 'list-item-view:viewport:toggle', this.toggleUponViewport);
    },


    events: {
      'click [data-hook="move-to-details-page"]': 'onMoveToDetailsPageClick'
    },

    toggleUponViewport: function toggleUponViewport() {
      var self = this;

      if (Rev.Utils.isElementCloseVisibleArea(self.$el).isClose) {
        // element is close to visible area - show view

        // #1 if html is existing in the DOM, do nothing
        if (self.$el.html()) return;

        // #2 get html from localstorage and insert in this view
        var listResultsItemHtmlModel = Rev.Collections.listResultsHtml.get(self.model.get('Id'));
        if (listResultsItemHtmlModel && listResultsItemHtmlModel.get('html')) {
          self.$el.html(listResultsItemHtmlModel.get('html'));
        }

        // #3 remove html stored in localstorage
        Rev.Collections.listResultsHtml.deleteItem(self.model.get('Id'));

        // #4 toggle class
        self.$el.removeClass('dummy');
      } else {
        // element is far away from visible area - remove view

        // #1 save html into localstorage
        var id = self.model.get('Id');
        var html = self.$el.html();
        if (!html) return;
        Rev.Collections.listResultsHtml.saveItem(id, html);

        // #2 remove inner html from DOM
        var viewHeight = this.$el.height();
        this.$el.html('');
        this.$el.height(viewHeight);

        // #3 toggle class
        self.$el.addClass('dummy');
      }
    },
    onMoveToDetailsPageClick: function onMoveToDetailsPageClick(e) {
      e.preventDefault();
      var url = $(e.currentTarget).attr('href');
      Rev.Routers.agencyDetailsRouter.navigate(url, { trigger: true });
    },
    remove: function remove() {
      this.off();

      //call the superclass remove method
      Backbone.View.prototype.remove.apply(this, arguments);
    }
  });
})(Rev, jQuery, _, Backbone);
'use strict';

// dependencies : Rev, jquery, underscore, Backbone, slick.js

(function (Rev, $, _, Backbone) {

  'use strict';

  Rev.Views.AgencyResultListView = Backbone.View.extend({
    initialize: function initialize() {
      _.bindAll(this, 'showNextPage');

      // delete all local data of result html
      Rev.Collections.listResultsHtml.fetch();
      _.invoke(Rev.Collections.listResultsHtml.all(), 'destroy');

      var itemsData = this.model.get('Items');
      this.collection = new Rev.Collections.AgencyResults(itemsData);

      this.createItemView();

      this.listenTo(this.collection, 'add', this.onCollectionAdded);
      this.listenTo(this.collection, 'remove', this.onCollectionRemoved);
      Rev.on('agency-result:shownext', this.showNextPage);
    },


    events: {
      'click [data-hook=btn-next-page]': 'onNextPageClick'
    },

    /* Note that this function does not add list item view to the parent list results view because it is already rendered by Razor.
       it just creates backbone view instance in order to handle view events in backbone way */
    createItemView: function createItemView() {
      this.collection.each(function (model) {
        new Rev.Views.AgencyResultsItemView({
          el: '.agency-result-item[data-id="' + model.get('Id') + '"]',
          model: model
        });
      });
    },
    onNextPageClick: function onNextPageClick(e) {
      e.preventDefault();
      $(e.currentTarget).button('loading');
      var nextPageUrl = $(e.currentTarget).attr('href');

      /* set replace to true so that url will not be stored in browser history 
         and user can go back to search page from page 2 or 3 or 4 etc,,, rather than back to previous result page */
      Rev.Routers.agencySearchResultRouter.navigate(nextPageUrl, { trigger: true, replace: true });
    },
    showNextPage: function showNextPage(ajaxUrl, cb) {
      var self = this;

      $.getJSON(ajaxUrl).done(function (result) {
        self.$('[data-hook=btn-next-page]').button('reset');

        var view = result.view;
        var model = result.model;
        var pagination = result.pagination;

        // #1 append view and show
        self.$('[data-hook=agency-result-items]').append(view);

        // #2 add collection instances : this will cuase creating view instance in onCollectionAdded method
        _.map(model, function (item) {
          self.collection.add(item);
        });

        // #3 change link url for get more items button on the bottom of result page
        self.$('[data-hook=btn-next-page]').attr('href', pagination.NextPage.Url);

        // #4 hide get more button if it is the last page
        if (pagination.TotalPages == pagination.CurrentPage) {
          self.$('[data-hook=btn-next-page]').hide();
        }

        // #5 show only listings close to visible area
        Rev.trigger('list-item-view:viewport:toggle');
      });
    },
    onCollectionAdded: function onCollectionAdded(item) {
      // create sub view instance
      new Rev.Views.AgencyResultsItemView({
        el: '.agency-result-item[data-id="' + item.get('Id') + '"]',
        model: item
      });
    },
    remove: function remove() {
      // TODO : remove sub views      

      this.off();
      this.stopListening();

      //call the superclass remove method
      Backbone.View.prototype.remove.apply(this, arguments);
    }
  });
})(Rev, jQuery, _, Backbone);
'use strict';

// dependencies : Rev, jquery, underscore, Backbone

(function (Rev, $, _, Backbone) {

  'use strict';

  Rev.Views.AgencyResultsView = Backbone.View.extend({
    initialize: function initialize(options) {
      _.bindAll(this, 'showView', 'hideView');

      this.listView = new Rev.Views.AgencyResultListView({ el: '.result-body-agency-list-view', model: this.model });

      this.listenTo(Rev, 'agency-result-page:show', this.showView);
      this.listenTo(Rev, 'agency-result-page:hide', this.hideView);

      Rev.trigger('new-search-button:hide');
      Rev.trigger('back-to-search-results-button:hide');
    },
    showView: function showView(e) {
      this.$el.show();
      Rev.trigger('agency-result-page:shown');
    },
    hideView: function hideView(e) {
      this.$el.hide();
      Rev.trigger('agency-result-page:hidden');
    },
    remove: function remove() {
      $(window).off('scroll');

      if (this.listView) this.listView.remove();

      this.off();
      this.stopListening();

      //call the superclass remove method
      Backbone.View.prototype.remove.apply(this, arguments);
    }
  });
})(Rev, jQuery, _, Backbone);
'use strict';

// dependencies : Rev, jquery, underscore, backbone

(function (Rev, $, _, Backbone) {

  'use strict';

  Rev.Views.AgencySearchFormLocationView = Backbone.View.extend({
    initialize: function initialize(options) {
      var _this = this;

      _.bindAll(this, 'closeView', 'showPlaceholder', 'hidePlaceholder', 'togglePlaceholder', 'onLocationInputKeydown');

      var options = options || {};
      this.baseSearchForm = options.baseSearchForm;

      this.initializeBloodHound();
      this.initializeLocationTypeahead();

      // I know this is ugly :( but no way to handle typeahead events with bootstrap-tagsinput with current version
      this.$el.on('typeahead:cursorchange', function () {
        return _this.makeTTinputLarge();
      }).on('typeahead:select', function () {
        return _this.makeTTinputSmall();
      });
    },


    events: {
      'itemAdded [data-hook="location-input"]': 'onItemAdded',
      'itemRemoved [data-hook="location-input"]': 'onItemRemoved',
      'blur .bootstrap-tagsinput': 'onLocationFocusOut',
      'focus .bootstrap-tagsinput': 'onLocationFocusIn',
      'keypress .tt-input': 'onLocationInputKeypress',
      'mouseenter .tt-suggestion': 'onHoverSuggestion'
    },

    onHoverSuggestion: function onHoverSuggestion(e) {
      this.$('.tt-menu-placeholder .tt-suggestion').removeClass('tt-cursor');
      this.$(e.currentTarget).addClass('tt-cursor');
    },
    initializeBloodHound: function initializeBloodHound() {
      this.locationSuggestions = new Bloodhound({
        //datumTokenizer: Bloodhound.tokenizers.obj.whitespace('Suburb'),
        datumTokenizer: Bloodhound.tokenizers.obj.whitespace,
        queryTokenizer: Bloodhound.tokenizers.whitespace,
        remote: {
          url: '/location/search/?searchText=%QUERY',
          replace: function replace(url, query) {
            var arr = query.split(',');
            return url.replace("%QUERY", arr[arr.length - 1].trim());
          }
        },
        limit: 10
      });

      this.locationSuggestions.initialize();
    },
    initializeLocationTypeahead: function initializeLocationTypeahead() {
      var _this2 = this;

      var template = _.template($('#suggestion-location-item').html());

      if (this.$tagsinput) {
        this.$tagsinput.off();
        this.$tagsinput.tagsinput('destroy');
      }

      this.$tagsinput = this.$('[data-hook="location-input"]');

      this.$tagsinput.tagsinput({
        confirmKeys: [13],
        maxChars: 100,
        freeInput: true, // this will be ignored if itemValue option is set
        itemValue: function itemValue(item) {
          return item.Suburb + '|' + item.State + '|' + item.Postcode;
        },
        itemText: function itemText(item) {
          return item.Suburb;
        },
        typeaheadjs: [{
          limit: 10,
          highlight: true,
          minLength: 3,
          hint: false,
          menu: this.$('.tt-menu-placeholder')
        }, {
          displayKey: 'FullName',
          source: this.locationSuggestions.ttAdapter(),
          templates: {
            suggestion: function suggestion(item) {
              var html = template({ suburb: item.Suburb, state: item.State, postcode: item.Postcode });
              return html;
            }
          }
        }]

      });

      this.$el.on('typeahead:autocomplete', function (event, item) {
        _this2.$('.bootstrap-tagsinput  input.tt-input').typeahead('val', null);
        _this2.$tagsinput.tagsinput('add', { Suburb: item.Suburb, State: item.State, Postcode: item.Postcode });
      });
    },
    onItemAdded: function onItemAdded(e) {
      //var oldValue = this.$('[data-hook="locationParam"]').val();
      //if (!oldValue) return;
      //var newValue = oldValue.concat(", " + e.item.Suburb);
      //this.$('[data-hook="locationParam"]').val(newValue);
      this.togglePlaceholder();
      //Rev.Utils.GaTracking.trackGaEvent(Rev.Utils.GaTracking.Category.FindAnAgent, Rev.Utils.GaTracking.Action.SearchSuburb, this.$tagsinput.val().replace(/[|]/g, ' '));

      var location = e.item;
      Rev.Utils.GaTracking.trackGaEvent(Rev.Utils.GaTracking.Category.FindAnAgent, Rev.Utils.GaTracking.Action.SearchSuburb, location.Suburb + ' ' + location.State + ' ' + location.Postcode);
    },
    onItemRemoved: function onItemRemoved(e) {
      //var oldValue = this.$('[data-hook="locationParam"]').val();
      //var location = e.item.Suburb + ", ";      
      //var newValue = oldValue.replace(location, '');
      //this.$('[data-hook="locationParam"]').val(newValue);
      //if (location) {
      //  this.togglePlaceholder();
      //}
    },
    onLocationFocusOut: function onLocationFocusOut(e) {
      this.$('.bootstrap-tagsinput').addClass('one-line');
      this.togglePlaceholder();
      this.$('.tt-menu-placeholder').hide();
      if (this.$tagsinput.tagsinput('items').length > 0) {
        this.makeTTinputLarge();
      }
    },
    onLocationFocusIn: function onLocationFocusIn(e) {
      this.$('.bootstrap-tagsinput').removeClass('one-line');
      this.hidePlaceholder();
      this.$('.tt-menu-placeholder').show();
      this.makeTTinputSmall();
      if (this.$tagsinput.tagsinput('items').length == 0) {
        this.$('.tt-input').removeClass('margin-left-0').addClass('margin-left-5');
      } else {
        this.$('.tt-input').removeClass('margin-left-5').addClass('margin-left-0');
      }
    },
    onLocationInputKeydown: function onLocationInputKeydown(e) {
      if (this.$tagsinput.tagsinput('items').length == 0) {
        this.$('.tt-input').removeClass('margin-left-0').addClass('margin-left-5');
      } else {
        this.$('.tt-input').removeClass('margin-left-5').addClass('margin-left-0');
      }
    },
    onLocationInputKeypress: function onLocationInputKeypress(e) {
      if (this.$tagsinput.tagsinput('items').length == 0) {
        this.$('.tt-input').removeClass('margin-left-0').addClass('margin-left-5');
      } else {
        this.$('.tt-input').removeClass('margin-left-5').addClass('margin-left-0');
      }

      // if no items selected and typed some text, send it to get first item in suggestions
      var text = this.$tagsinput.tagsinput('input').val();
      if (this.$tagsinput.tagsinput('items').length == 0 && text && text.length > 0) {
        this.$('[data-hook="freetext-location"]').val(text);
      } else {
        this.$('[data-hook="freetext-location"]').val('');
      }

      if (e.which == 13) {
        this.baseSearchForm.submitForm();
      }
    },
    togglePlaceholder: function togglePlaceholder() {
      if (this.$tagsinput.tagsinput('items').length > 0) {
        this.hidePlaceholder();
      } else {
        this.showPlaceholder();
      }
    },
    showPlaceholder: function showPlaceholder() {
      this.$tagsinput.tagsinput('input').attr('placeholder', 'Suburb (or postcode)');
      this.$('.tt-input').css('max-width', '280px');
    },
    hidePlaceholder: function hidePlaceholder() {
      if (this.$tagsinput.tagsinput('input').removeAttr) this.$tagsinput.tagsinput('input').removeAttr('placeholder');
    },
    makeTTinputSmall: function makeTTinputSmall() {
      //this.$('.tt-input').css('max-width','100px');
    },
    makeTTinputLarge: function makeTTinputLarge() {
      //this.$('.tt-input').css('max-width','210px');
    },
    closeView: function closeView(e) {
      if (e && e.preventDefault) e.preventDefault();

      $(document).off('typeahead:cursorchange typeahead:select typeahead:autocomplete');
    }
  });
})(Rev, jQuery, _, Backbone);
'use strict';

// dependencies : Rev, jquery, underscore, backbone

(function (Rev, $, _, Backbone) {

  'use strict';

  Rev.Views.AgencySearchFormNameView = Backbone.View.extend({
    initialize: function initialize(options) {
      _.bindAll(this, 'closeView');

      var options = options || {};
      this.baseSearchForm = options.baseSearchForm;

      this.initializeBloodHound();
      this.initializeLocationTypeahead();
    },


    events: {
      'blur .bootstrap-tagsinput': 'onLocationFocusOut',
      'focus .bootstrap-tagsinput': 'onLocationFocusIn',
      'keypress .tt-input': 'onInputKeypress',
      'mouseenter .tt-suggestion': 'onHoverSuggestion',
      'typeahead:select [data-hook="agency-name-input"]': 'onSuggestionSelect'
    },

    onSuggestionSelect: function onSuggestionSelect(e, item) {
      this.$('.tt-dataset .tt-suggestion').remove();
    },
    onHoverSuggestion: function onHoverSuggestion(e) {
      this.$('.tt-menu-placeholder .tt-suggestion').removeClass('tt-cursor');
      this.$(e.currentTarget).addClass('tt-cursor');
    },
    initializeBloodHound: function initializeBloodHound() {
      this.locationSuggestions = new Bloodhound({
        //datumTokenizer: Bloodhound.tokenizers.obj.whitespace('Suburb'),
        datumTokenizer: Bloodhound.tokenizers.obj.whitespace,
        queryTokenizer: Bloodhound.tokenizers.whitespace,
        remote: {
          url: '/agencies/suggestion/?searchText=%QUERY',
          replace: function replace(url, query) {
            return url.replace("%QUERY", encodeURIComponent(query));
          }
        },
        limit: 10
      });

      this.locationSuggestions.initialize();
    },
    initializeLocationTypeahead: function initializeLocationTypeahead() {
      var template = _.template($('#suggestion-agency-item').html());

      this.$input = this.$('[data-hook="agency-name-input"]');

      var options = {
        highlight: true,
        minLength: 3,
        hint: false,
        menu: this.$('.tt-menu-placeholder')
      };

      this.$input.typeahead(options, {
        limit: 10,
        display: 'AgencyName',
        source: this.locationSuggestions.ttAdapter(),
        templates: {
          suggestion: function suggestion(item) {
            var html = template({ agencyName: item.AgencyName });
            return html;
          }
        }
      });
    },
    onInputKeypress: function onInputKeypress(e) {
      if (e.which == 13) {
        this.baseSearchForm.submitForm();
      }
    },
    closeView: function closeView(e) {
      if (e && e.preventDefault) e.preventDefault();

      $(document).off('typeahead:cursorchange typeahead:select');
    }
  });
})(Rev, jQuery, _, Backbone);
'use strict';

// dependencies : Rev, jquery, underscore, backbone

(function (Rev, $, _, Backbone) {

  'use strict';

  Rev.Views.AgencySearchFormView = Backbone.View.extend({
    initialize: function initialize(options) {
      _.bindAll(this, 'onSearchSubmitRequested', 'submitForm');

      this.initializeSubViews();
      this.listenTo(Rev, 'search:ga:fire', this.fireGaEvent);
      this.listenTo(Rev, 'search:submit', this.onSearchSubmitRequested);
    },


    events: {
      'click [data-hook="btn-submit-agency-search"]': 'onClickSubmitSearch'
    },

    initializeSubViews: function initializeSubViews() {
      this.locationView = new Rev.Views.AgencySearchFormLocationView({ el: this.$('.search-form-agency-location'), model: this.model, baseSearchForm: this });
      this.nameView = new Rev.Views.AgencySearchFormNameView({ el: this.$('.search-form-agency-name'), model: this.model, baseSearchForm: this });
    },
    submitForm: function submitForm() {
      var _this = this;

      var wait = Rev.Utils.isiPad() ? 1000 : 50;
      this.$el.addClass('loading');
      setTimeout(function () {
        return _this.$('form#search-form-agency').submit();
      }, wait);
    },
    onSearchSubmitRequested: function onSearchSubmitRequested() {
      this.submitForm();
    },
    onClickSubmitSearch: function onClickSubmitSearch(e) {
      this.submitForm();
    },
    remove: function remove() {
      if (this.locationView) this.locationView.remove();
      if (this.nameView) this.nameView.remove();

      this.off();
      this.stopListening();

      //call the superclass remove method
      Backbone.View.prototype.remove.apply(this, arguments);
    }
  });
})(Rev, jQuery, _, Backbone);
'use strict';

// dependencies : Rev, jquery, underscore, backbone

(function (Rev, $, _, Backbone) {

    'use strict';

    Rev.Views.AgentDetailsView = Backbone.View.extend({
        el: '.agent-details',

        initialize: function initialize() {
            this.agentEnquiryErrorPlaceHolder = this.$('[data-hook="contact-agent-validation-errors-placeholder"]');

            if (Rev.IsPhone) {
                $(document).scroll(function () {
                    var y = $(this).scrollTop();

                    // Show element after user scrolls past 
                    // the top edge of its parent 
                    $('.agent-details-details-buttons').each(function () {
                        var t = $('.agent-details-contact').offset().top - 50;
                        if (y > t) {
                            $(this).fadeOut();
                        } else {
                            $(this).fadeIn();
                        }
                    });
                });
            }
        },


        events: {
            'click [data-hook="contact-agent-phone"]': 'onPhoneAgentClick',
            'click [data-hook="contact-agent-email"]': 'openEmailAgentModal',
            'click [data-hook="agent-description-read-more"]': 'expandReadMoreText',
            'click [data-hook="btn-contact-agent"]': 'makeEnquiry'
        },

        onPhoneAgentClick: function onPhoneAgentClick(e) {

            if (!Rev.IsPhone) {
                e.preventDefault();

                var phone = this.$(e.currentTarget).attr('data-agent-phone');
                this.$(e.currentTarget).text(phone);
            }

            Rev.Utils.GaTracking.trackGaEvent(Rev.Utils.GaTracking.Category.AgentProfile, Rev.Utils.GaTracking.Action.PhoneProfile, this.model.get('Name') + ' - ' + this.model.get('Id') + ' - ' + this.model.get('Agency').AgencyName + ' - ' + this.model.get('Agency').Id);
        },
        openEmailAgentModal: function openEmailAgentModal(e) {
            //e.preventDefault();
            $('html,body').animate({ scrollTop: $(".agent-details-contact").offset().top }, 'slow');
        },
        expandReadMoreText: function expandReadMoreText(e) {
            $('[data-hook=agent-description-text]').text(this.model.get('Description'));

            this.$(e.currentTarget).remove();
        },
        makeEnquiry: function makeEnquiry(e) {
            var _this = this;

            e.preventDefault();

            var $form = this.$('[data-hook="contact-agent-form"]');
            var url = $form.attr('action');

            $(e.currentTarget).button('loading');

            $.post(url, $form.serialize()).done(function (result) {
                if (result.errors) {
                    Rev.Utils.showErrors(result.errors, _this.agentEnquiryErrorPlaceHolder);
                    if (_this.scrollTop) $('html, body').animate({ scrollTop: _this.scrollTop }, 400);

                    _this.$('[data-hook="btn-contact-agent"]').button('reset');
                } else {
                    Rev.Utils.clearErrors(_this.agentEnquiryErrorPlaceHolder);
                    _this.$('[data-hook="btn-contact-agent"]').text('Enquiry Sent!');
                    _this.$('[data-hook="btn-contact-agent"]').prop('disabled', true);

                    Rev.Utils.GaTracking.trackGaEvent(Rev.Utils.GaTracking.Category.AgentProfile, Rev.Utils.GaTracking.Action.EmailProfile, _this.model.get('Name') + ' - ' + _this.model.get('Id') + ' - ' + _this.model.get('Agency').AgencyName + ' - ' + _this.model.get('Agency').Id);
                }
            }).fail(function (result) {
                Rev.Utils.showErrors(result.errors, _this.agentEnquiryErrorPlaceHolder);
                if (_this.scrollTop) $('html, body').animate({ scrollTop: _this.scrollTop }, 400);

                _this.$('[data-hook="btn-contact-agent"]').button('reset');
            }).always(function () {});

            if (this.gaCategory && this.gaAgencyName && this.gaAgencyEmail) Rev.Utils.GaTracking.trackGaEvent(this.gaCategory, Rev.Utils.GaTracking.Action.SendToAgent, this.gaAgencyName + ' / ' + this.gaAgencyEmail);

            Rev.Utils.GaTracking.trackEmailAgent(this.model);
        }
    });
})(Rev, jQuery, _, Backbone);
'use strict';

// dependencies : Rev, jquery, underscore, backbone, slick.js

(function (Rev, $, _, Backbone) {

	'use strict';

	Rev.Views.AgentFloatButtonsView = Backbone.View.extend({
		initialize: function initialize() {

			_.bindAll(this, 'onCtaButtonStickyStart');

			if (!Rev.IsPhone) {
				this.$el.sticky({ topSpacing: 50, zIndex: 10 });
			} else {
				this.$('[data-hook="contact-agency-fake"]').sticky({ topSpacing: 0, zIndex: 10 });
				this.$('[data-hook="contact-agency-fake"]').on('sticky-start', this.onCtaButtonStickyStart);
			}
		},


		events: {
			'click [data-hook="agent-phone-number"]': 'onPhoneAgencyClick',
			'click [data-hook="contact-agency-email"] a': 'openEmailAgentModal'
		},

		onCtaButtonStickyStart: function onCtaButtonStickyStart() {
			this.$('[data-hook="contact-agency-email"]').css({ 'z-index': 2, 'padding': 0 });
			this.$('[data-hook="contact-agency-email"] button').css({ 'border-radius': 0 });
		},
		onPhoneAgencyClick: function onPhoneAgencyClick(e) {
			if (!Rev.IsPhone) {
				e.preventDefault();
			}

			var phone = this.$(e.currentTarget).attr('data-agent-phone');
			this.$(e.currentTarget).find('a').find("button").text(phone);

			var agentId = this.$(e.currentTarget).attr('data-agent-id');

			// fire ga event & lead event
			Rev.Utils.LeadTracking.sendPhoneEvent(this.model.get('Id'));

			Rev.Utils.GaTracking.trackGaEvent(this.model.get('GaEventCategory'), Rev.Utils.GaTracking.Action.PhoneAgent, this.model.get('AgencyName') + ' / ' + this.model.get('AgencyId'));

			Rev.Utils.GaTracking.trackPhoneAgent(this.model);

			Rev.Utils.Criteo.pushEventAgentContact(this.model.get('Id'));

			var actionName;
			if (!Rev.IsPhone) actionName = Rev.Utils.MatomoTracking.Action.PhoneReveal;else actionName = Rev.Utils.MatomoTracking.Action.CallAgent;

			Rev.Utils.MatomoTracking.sendEvent(this.model, Rev.Utils.MatomoTracking.Category.ListingLeads, actionName, null, null, agentId);
		},
		openEmailAgentModal: function openEmailAgentModal(e) {
			e.preventDefault();

			$('html,body').animate({ scrollTop: $("#emailagent").offset().top }, 'slow');
		},
		remove: function remove() {
			Rev.Utils.closeEmailAgentModal();

			this.$('[data-hook="contact-agency-email"]').off();

			this.off();
			this.stopListening();

			//call the superclass remove method
			Backbone.View.prototype.remove.apply(this, arguments);
		}
	});
})(Rev, jQuery, _, Backbone);
'use strict';

// dependencies : Rev, jquery, underscore, backbone, slick.js

(function (Rev, $, _, Backbone) {

    'use strict';

    Rev.Views.AgentFloatView = Backbone.View.extend({
        initialize: function initialize() {},


        events: {
            'click [data-hook="agent-phone-number"]': 'onPhoneAgencyClick',
            'click [data-hook="contact-agency-email"] a': 'openEmailAgentModal',
            'click [ data-hook="contact-agent"]': 'contactAgent'
        },

        contactAgent: function contactAgent(e) {
            var agentId = this.$(e.currentTarget).attr('data-agent-id');

            Rev.Utils.MatomoTracking.sendEvent(this.model, Rev.Utils.MatomoTracking.Category.ListingLeads, Rev.Utils.MatomoTracking.Action.AgentProfile, null, null, agentId);
        },
        onPhoneAgencyClick: function onPhoneAgencyClick(e) {
            var $phoneWrapper = this.$(e.currentTarget).closest('.agent-number');

            if (!Rev.IsPhone) {
                e.preventDefault();
            }

            var phone = $phoneWrapper.attr('data-agent-phone');
            $phoneWrapper.find('a').text(phone);

            var agentId = $phoneWrapper.attr('data-agent-id');

            // fire ga event & lead event
            Rev.Utils.LeadTracking.sendPhoneEvent(this.model.get('Id'));

            Rev.Utils.GaTracking.trackGaEvent(this.model.get('GaEventCategory'), Rev.Utils.GaTracking.Action.PhoneAgent, this.model.get('AgencyName') + ' / ' + this.model.get('AgencyId'));

            Rev.Utils.GaTracking.trackPhoneAgent(this.model);

            Rev.Utils.Criteo.pushEventAgentContact(this.model.get('Id'));

            var actionName;
            if (!Rev.IsPhone) actionName = Rev.Utils.MatomoTracking.Action.PhoneReveal;else actionName = Rev.Utils.MatomoTracking.Action.CallAgent;

            Rev.Utils.MatomoTracking.sendEvent(this.model, Rev.Utils.MatomoTracking.Category.ListingLeads, actionName, null, null, agentId);
        },
        openEmailAgentModal: function openEmailAgentModal(e) {
            e.preventDefault();

            if (Rev.IsPhone) {
                $('html,body').animate({ scrollTop: $("#emailagent").offset().top }, 'slow');
            } else {
                Rev.Utils.GaTracking.trackGaEvent(this.model.get('GaEventCategory'), Rev.Utils.GaTracking.Action.EmailAgent, this.model.get('AgencyName') + ' / ' + this.model.get('AgencyId'));

                Rev.Utils.showEmailAgentModal(this.model.get('Id'), this.model.get('GaEventCategory'), this.model.get('AgencyName'), this.model.get('AgencyEmail'), null, this.model.get('AgencyId'));
            }
        },
        remove: function remove() {
            Rev.Utils.closeEmailAgentModal();

            this.$('[data-hook="contact-agency-email"]').off();

            this.off();
            this.stopListening();

            //call the superclass remove method
            Backbone.View.prototype.remove.apply(this, arguments);
        }
    });
})(Rev, jQuery, _, Backbone);
'use strict';

// dependencies : Rev, jquery, underscore, backbone

(function (Rev, $, _, Backbone) {

  'use strict';

  Rev.Views.AuctionAlertsView = Backbone.View.extend({
    initialize: function initialize(options) {
      _.bindAll(this, 'reset', 'closeView', 'showExistingValue', 'showPlaceholder', 'hidePlaceholder', 'togglePlaceholder', 'onLocationInputKeydown');

      this.errorPlaceHolder = this.$('[data-hook="auction-alert-validation-errors-placeholder"]');

      this.initializeBloodHound();
      this.initializeLocationTypeahead();

      this.showExistingValue(this.model.get('Suburbs'));
    },


    events: {
      'itemAdded [data-hook="location-input"]': 'onItemAdded',
      'itemRemoved [data-hook="location-input"]': 'onItemRemoved',
      'blur .bootstrap-tagsinput': 'onLocationFocusOut',
      'focus .bootstrap-tagsinput': 'onLocationFocusIn',
      'keypress .tt-input': 'onLocationInputKeypress',
      'mouseenter .tt-suggestion': 'onHoverSuggestion',
      'click [data-hook="btn-save-auction-alerts"]': 'onSaveAuctionAlertsClick',
      'click [data-hook="btn-stop-sending"]': 'onStopSendingClick',
      'click [data-hook="btn-signup"]': 'onBtnSignupClick'
    },

    onBtnSignupClick: function onBtnSignupClick(e) {
      if (Rev.IsPhone) {
        Rev.trigger('sidebar:toggle');
        Rev.trigger('login:toggle');
      } else {
        Rev.Utils.showAuthModal('login');
      }
    },
    onSaveAuctionAlertsClick: function onSaveAuctionAlertsClick(e) {
      var _this = this;

      e.preventDefault();
      $(e.currentTarget).button('loading');

      var $form = this.$('form');
      var actionUrl = $form.attr('action');

      $.post(actionUrl, $form.serialize()).done(function (result) {
        if (result.errors) {
          Rev.Utils.showErrorMessage(_.pluck(result.errors, 'Value').join(', '));
        } else {
          Rev.Utils.showSuccessMessage('Auction alerts saved');
          _this.updateForm(result.auctionResult);
        }
      }).fail(function (result) {
        Rev.Utils.showErrorMessage('Auction alerts not saved');
      }).always(function () {
        _this.$('[data-hook="btn-save-auction-alerts"]').button('reset');
      });
    },
    updateForm: function updateForm(auctionResult) {
      var _this2 = this;

      var $form = this.$('form#form-auction-alert');

      if (auctionResult) {
        $form.find('#Id').val(auctionResult.Id);
        $form.find('#StateShort').val(auctionResult.StateShort);

        this.$tagsinput.tagsinput('removeAll');
        if (auctionResult.Suburbs) {
          var suburbs = auctionResult.Suburbs.split(',');
          _.each(suburbs, function (location) {
            var arr = location.split('|');
            var suburb = arr[0];
            var state = arr[1];
            var postcode = arr[2];

            _this2.$tagsinput.tagsinput('add', { Suburb: suburb, State: state, Postcode: postcode });
          });
        }
      } else {
        $form.find('#Id').val('');
        $form.find('#StateShort').val('');
        this.$tagsinput.tagsinput('removeAll');
      }
    },
    onStopSendingClick: function onStopSendingClick(e) {
      var _this3 = this;

      e.preventDefault();
      $(e.currentTarget).button('loading');

      var $form = this.$('form');
      var actionUrl = '/auction-alerts/stop/';

      $.post(actionUrl, $form.serialize()).done(function (result) {
        if (result.errors) {
          Rev.Utils.showErrorMessage('Sorry, failed to stop sending emails.');
        } else {
          Rev.Utils.showSuccessMessage('Succeeded.');
          _this3.updateForm(null);
        }
      }).fail(function (result) {
        Rev.Utils.showErrorMessage('Sorry, failed to stop sending emails.');
      }).always(function () {
        _this3.$('[data-hook="btn-stop-sending"]').button('reset');
      });
    },
    showExistingValue: function showExistingValue(locationData) {
      var _this4 = this;

      if (!locationData) return;

      var locations = locationData.split(',');
      _.each(locations, function (location) {
        if (!location) return;
        var locationSplited = location.split('|');
        _this4.$tagsinput.tagsinput('add', { Suburb: locationSplited[0], State: locationSplited[1], Postcode: locationSplited[2] });
      });
      this.togglePlaceholder();
    },
    onLocationFocusOut: function onLocationFocusOut(e) {
      this.togglePlaceholder();
      this.$('.tt-menu-placeholder').hide();
    },
    onLocationFocusIn: function onLocationFocusIn(e) {
      this.$('.tt-input').removeClass('small');
      this.hidePlaceholder();
      this.$('.tt-menu-placeholder').show();
      if (this.$tagsinput.tagsinput('items').length === 0) {
        this.$('.tt-input').removeClass('margin-left-0').addClass('margin-left-5');
      } else {
        this.$('.tt-input').removeClass('margin-left-5').addClass('margin-left-0');
      }
    },
    onLocationInputKeydown: function onLocationInputKeydown(e) {
      if (this.$tagsinput.tagsinput('items').length === 0) {
        this.$('.tt-input').removeClass('margin-left-0').addClass('margin-left-5');
      } else {
        this.$('.tt-input').removeClass('margin-left-5').addClass('margin-left-0');
      }
    },
    onLocationInputKeypress: function onLocationInputKeypress(e) {
      if (this.$tagsinput.tagsinput('items').length === 0) {
        this.$('.tt-input').removeClass('margin-left-0').addClass('margin-left-5');
      } else {
        this.$('.tt-input').removeClass('margin-left-5').addClass('margin-left-0');
        this.$('.tt-input').removeClass('small');
      }

      if (e.which == 13) {
        // if no items selected and typed some text, send it to get first item in suggestions
        var text = this.$tagsinput.tagsinput('input').val();
        if (this.$tagsinput.tagsinput('items').length === 0 && text && text.length > 0) {
          this.$('[data-hook="freetext-location"]').val(text);
        }

        this.baseSearchForm.submitForm();
      }
    },
    togglePlaceholder: function togglePlaceholder() {
      if (this.$tagsinput.tagsinput('items').length > 0) {
        this.hidePlaceholder();
        this.$('.tt-input').css('width', 'auto').addClass('small');
        this.$('i.icon-icon-map-pin').hide();
      } else {
        this.showPlaceholder();
        this.$('.tt-input').removeClass('small');
        this.$('i.icon-icon-map-pin').show();
      }
    },
    showPlaceholder: function showPlaceholder() {
      this.$tagsinput.tagsinput('input').attr('placeholder', 'Enter suburb(s)');
      this.$('.tt-input').css('max-width', '280px');
    },
    hidePlaceholder: function hidePlaceholder() {
      if (this.$tagsinput.tagsinput('input').removeAttr) this.$tagsinput.tagsinput('input').removeAttr('placeholder');
    },
    onHoverSuggestion: function onHoverSuggestion(e) {
      this.$('.tt-menu-placeholder .tt-suggestion').removeClass('tt-cursor');
      this.$(e.currentTarget).addClass('tt-cursor');
    },
    reset: function reset() {
      this.$tagsinput.tagsinput('removeAll');
    },
    onItemAdded: function onItemAdded(e) {
      this.togglePlaceholder();
    },
    onItemRemoved: function onItemRemoved(e) {
      var location = e.item;
      if (location) {
        this.togglePlaceholder();
      }
    },
    initializeBloodHound: function initializeBloodHound() {
      this.locationSuggestions = new Bloodhound({
        datumTokenizer: Bloodhound.tokenizers.obj.whitespace,
        queryTokenizer: Bloodhound.tokenizers.whitespace,
        remote: {
          url: '/location/search/?onlyvic=true&searchText=%QUERY',
          replace: function replace(url, query) {
            var arr = query.split(',');
            return url.replace("%QUERY", arr[arr.length - 1].trim());
          }
        },
        limit: 10
      });

      this.locationSuggestions.initialize();
    },
    initializeLocationTypeahead: function initializeLocationTypeahead() {
      var _this5 = this;

      var template = _.template($('#suggestion-location-item').html());

      if (this.$tagsinput) {
        this.$tagsinput.off();
        this.$tagsinput.tagsinput('destroy');
      }

      this.$tagsinput = this.$('[data-hook="location-input"]');

      this.$tagsinput.tagsinput({
        maxChars: 100,
        freeInput: true, // this will be ignored if itemValue option is set
        itemValue: function itemValue(item) {
          return item.Suburb + '|' + item.State + '|' + item.Postcode;
        },
        itemText: function itemText(item) {
          return item.Suburb;
        },
        typeaheadjs: [{
          limit: 10,
          highlight: true,
          minLength: 3,
          hint: false,
          menu: this.$('.tt-menu-placeholder')
        }, {
          displayKey: 'FullName',
          source: this.locationSuggestions.ttAdapter(),
          templates: {
            suggestion: function suggestion(item) {
              var html = template({ suburb: item.Suburb, state: item.State, postcode: item.Postcode });
              return html;
            }
          }
        }]

      });

      this.$el.on('typeahead:autocomplete', function (event, item) {
        _this5.$('.bootstrap-tagsinput  input.tt-input').typeahead('val', null);
        _this5.$tagsinput.tagsinput('add', { Suburb: item.Suburb, State: item.State, Postcode: item.Postcode });
      });
    },
    closeView: function closeView(e) {
      if (e && e.preventDefault) e.preventDefault();
      $(document).off('typeahead:cursorchange typeahead:select typeahead:autocomplete');
    }
  });
})(Rev, jQuery, _, Backbone);
'use strict';

(function (Rev, $, _, Backbone) {

  'use strict';

  Rev.Views.AuctionResultHomeBannerView = Backbone.View.extend({
    initialize: function initialize() {
      _.bindAll(this, 'getSearchMenutypeCallback');
    },

    events: {
      'click [data-hook="btn-auction-result-landing-page"]': 'onAuctionResultBannerClick'
    },

    onAuctionResultBannerClick: function onAuctionResultBannerClick(e) {
      e.preventDefault();

      Rev.trigger('get:selected:menuyype', this.getSearchMenutypeCallback);
    },
    getSearchMenutypeCallback: function getSearchMenutypeCallback(menuType) {
      var self = this;

      var category = Rev.Utils.GaTracking.Category.HomeBuy;

      if (menuType === 'rent') {
        category = Rev.Utils.GaTracking.Category.HomeRent;
      }

      if (menuType === 'sold') {
        category = Rev.Utils.GaTracking.Category.HomeSold;
      }

      var action = Rev.Utils.GaTracking.Action.ViewSalesResults;
      var label = Rev.Utils.GaTracking.Label.ViewAllSalesResults;

      Rev.Utils.GaTracking.trackGaEvent(category, action, label);

      setTimeout(function () {
        var targetUrl = self.$('[data-hook="btn-auction-result-landing-page"]').attr('href');
        window.location.href = targetUrl;
      }, 100);
    }
  });
})(Rev, jQuery, _, Backbone);
'use strict';

// dependencies : Rev, jquery, underscore, backbone

(function (Rev, $, _, Backbone) {

  'use strict';

  Rev.Views.AuctionResultLandingView = Backbone.View.extend({
    initialize: function initialize() {
      _.bindAll(this, 'scrollToSearchbar', 'displayLoginPopup', 'showExistingValue', 'showPlaceholder', 'hidePlaceholder', 'togglePlaceholder', 'submitSearch', 'saveAuctionAlert', 'toggleSaveAllSuburbsForm', 'updateLocationHiddenField');

      this.initializeBloodHound();
      this.initializeLocationTypeahead();

      this.detectLongTopBanner();

      if (this.model) {
        this.displayLoginPopup();
        this.showExistingValue(this.model.get('SearchLocations'));
      }

      this.scrollToSearchbar();
    },


    events: {
      'itemAdded [data-hook="location-input"]': 'onItemAdded',
      'itemRemoved [data-hook="location-input"]': 'onItemRemoved',
      'blur .bootstrap-tagsinput': 'onLocationFocusOut',
      'focus .bootstrap-tagsinput': 'onLocationFocusIn',
      'keypress .tt-input': 'onLocationInputKeypress',
      'mouseenter .tt-suggestion': 'onHoverSuggestion',
      'click [data-hook="btn-submit-search-filters"]': 'onSearchClick',
      'click [data-hook="btn-auction-alert-append"]': 'onAddAuctionAlertClick',
      'click [data-hook="btn-edit-auction-alert"]': 'onEditAuctionAlertClick',
      'click [data-hook="btn-view-all-property-data"]': 'onViewAllPropertyDataClick'
    },

    scrollToSearchbar: function scrollToSearchbar() {
      // document.referrer ==> if user landed this page from auction result email, we don't scroll to the search form
      if (this.model.get('SearchLocations') && this.model.get('SearchLocations').length >= 1 && document.referrer) {
        $('html, body').animate({
          scrollTop: $("#auction-result-landing-content").offset().top - 70
        }, 0);
      }
    },
    displayLoginPopup: function displayLoginPopup() {
      if (this.model.get('DisplaySigninPopup')) {
        if (Rev.IsPhone) {
          Rev.trigger('sidebar:toggle');
          Rev.trigger('login:toggle', { email: this.model.get('UserEmail') });
        } else {
          Rev.Utils.showAuthModal('login', null, null, { email: this.model.get('UserEmail') });
        }
      }
    },
    detectLongTopBanner: function detectLongTopBanner() {
      var self = this;
      var trycount = 0;
      var job = setInterval(function () {
        if (self.$('[data-hook="auction-result-landing-leaderboard-ad-1"] iframe').length) {
          self.$('[data-hook="auction-result-landing-leaderboard-ad-1"]').fadeIn('slow');
          clearInterval(job);
        }

        if (trycount === 10) {
          // just close after 10 times try
          clearInterval(job);
        }

        trycount++;
      }, 1000);
    },
    onViewAllPropertyDataClick: function onViewAllPropertyDataClick(e) {
      var _this = this;

      e.preventDefault();

      Rev.Utils.GaTracking.trackGaEvent(Rev.Utils.GaTracking.Category.SalesAuctionResults, Rev.Utils.GaTracking.Action.ViewAllSalesData, Rev.Utils.GaTracking.Label.ViewAllSalesResults);

      setTimeout(function () {
        var targetUrl = _this.$(e.currentTarget).attr('href');
        if (targetUrl) {
          window.location.href = targetUrl;
        }
      }, 300);
    },
    onEditAuctionAlertClick: function onEditAuctionAlertClick(e) {
      e.preventDefault();

      Rev.Utils.GaTracking.trackGaEvent(Rev.Utils.GaTracking.Category.SalesAuctionResults, Rev.Utils.GaTracking.Action.EditAlert, Rev.Utils.GaTracking.Label.AlertEdited);

      var locations = this.$tagsinput.tagsinput('items');
      var arr = _.map(locations, function (location) {
        if (location && location.Suburb && location.State && location.Postcode) {
          return location.Suburb.toUpperCase() + '|' + location.State.toLowerCase() + '|' + location.Postcode;
        }
      });

      var locationString = arr.join(',');
      var uri = new URI(this.$(e.currentTarget).attr('href'));
      uri.addSearch('std', locationString);

      setTimeout(function () {
        return window.location.href = uri.toString();
      }, 300);
    },
    buildUriForSearch: function buildUriForSearch() {
      var uri = new URI('/sales-and-auction-results/victoria/');

      var locations = this.$tagsinput.tagsinput('items');

      if (locations && locations.length >= 1) {
        if (locations && locations.length === 1) {
          var location = locations[0];
          var startLetter = location.Suburb.substr(0, 1).toLowerCase();

          uri.segment(startLetter + '/');
          uri.segmentCoded(location.Suburb.replace(/\s+/g, '-').toLowerCase() + '-' + location.State.toLowerCase() + '-' + location.Postcode);
          uri.segment('/');
        } else if (locations && locations.length >= 2) {
          var arr = _.map(locations, function (location) {
            if (location && location.Suburb && location.State && location.Postcode) {
              return location.Suburb.toLowerCase() + '|' + location.State.toLowerCase() + '|' + location.Postcode;
            }
          });
          var locationString = arr.join(',');

          uri.addSearch('suburbs', locationString);
        }
      }

      return uri.toString();
    },


    // for "Save suburb" and "Save all suburbs" buttons
    onAddAuctionAlertClick: function onAddAuctionAlertClick(e) {
      var _this2 = this;

      e.preventDefault();
      var self = this;
      $(e.currentTarget).button('loading');

      var locations = this.$tagsinput.tagsinput('items');

      if (locations && locations.length >= 1) {
        Rev.Utils.GaTracking.trackGaEvent(Rev.Utils.GaTracking.Category.SalesAuctionResults, Rev.Utils.GaTracking.Action.SaveThisSearch, Rev.Utils.GaTracking.Label.SearchSaved);

        var urlForSearch = self.buildUriForSearch();

        var callbackAfterSave = function callbackAfterSave() {
          setTimeout(function () {
            window.location.href = urlForSearch;
          }, 500);
        };

        var afterAuthCallback = function afterAuthCallback() {
          self.refreshAntiforgeryToken(function () {
            self.saveAuctionAlert(self.$(e.currentTarget).closest('form.auction-alert-append-form'), callbackAfterSave);
          });
        };
        var closeAuthWindowCallback = function closeAuthWindowCallback() {
          return self.$('[data-hook="btn-auction-alert-append"]').button('reset');
        };
        var callbackIfAlreadyAuthenticated = function callbackIfAlreadyAuthenticated() {
          return self.saveAuctionAlert(_this2.$(e.currentTarget).closest('form.auction-alert-append-form'));
        };

        Rev.Utils.saveAuctionAlert(afterAuthCallback, afterAuthCallback, closeAuthWindowCallback, callbackIfAlreadyAuthenticated);
      } else {
        alert('Please enter suburb(s) and hit the search button before saving auction alert');
      }
    },
    refreshAntiforgeryToken: function refreshAntiforgeryToken(successCallback) {
      $.get('/refreshtoken/').done(function (html) {
        var tokenValue = $('<div />').html(html).find('input[type="hidden"]').val();
        $('input[name="__RequestVerificationToken"]').val(tokenValue);
        if (successCallback) successCallback();
      });
    },
    saveAuctionAlert: function saveAuctionAlert($form, callback) {
      var _this3 = this;

      var actionUrl = $form.attr('action');

      $.post(actionUrl, $form.serialize()).done(function (result) {
        if (result.errors) {
          Rev.Utils.showErrorMessage(_.pluck(result.errors, 'Value').join(', '));
        } else {
          Rev.Utils.showSuccessMessage('Auction alerts saved');
          if (callback) callback();
        }
      }).fail(function (result) {
        Rev.Utils.showErrorMessage('Auction alerts not saved');
      }).always(function () {
        _this3.$('[data-hook="btn-auction-alert-append"]').button('reset');
      });
    },
    submitSearch: function submitSearch() {
      this.$('[data-hook="btn-submit-search-filters"]').button('loading');
      var url = this.buildUriForSearch();
      window.location.href = url;
    },
    onSearchClick: function onSearchClick(e) {
      this.submitSearch();
    },
    showExistingValue: function showExistingValue(locationData) {
      var _this4 = this;

      if (!locationData) return;

      _.each(locationData, function (location) {
        if (!location) return;
        _this4.$tagsinput.tagsinput('add', { Suburb: location.Suburb, State: location.State, Postcode: location.Postcode });
      });
      this.togglePlaceholder();
    },
    onLocationFocusOut: function onLocationFocusOut(e) {
      this.togglePlaceholder();
      this.$('.tt-menu-placeholder').hide();
    },
    onLocationFocusIn: function onLocationFocusIn(e) {
      this.$('.tt-input').removeClass('small');
      this.hidePlaceholder();
      this.$('.tt-menu-placeholder').show();
      if (this.$tagsinput.tagsinput('items').length === 0) {
        this.$('.tt-input').removeClass('margin-left-0').addClass('margin-left-5');
      } else {
        this.$('.tt-input').removeClass('margin-left-5').addClass('margin-left-0');
      }
    },
    onLocationInputKeypress: function onLocationInputKeypress(e) {
      if (this.$tagsinput.tagsinput('items').length === 0) {
        this.$('.tt-input').removeClass('margin-left-0').addClass('margin-left-5');
      } else {
        this.$('.tt-input').removeClass('margin-left-5').addClass('margin-left-0');
        this.$('.tt-input').removeClass('small');
      }

      if (e.which == 13) {
        this.submitSearch();
      }
    },
    onItemAdded: function onItemAdded(e) {
      this.togglePlaceholder();
      this.toggleSaveAllSuburbsForm();

      var location = e.item;
      if (location && location.Suburb && location.State && location.Postcode && location.Suburb.indexOf('undefined') === -1 && location.State.indexOf('undefined') === -1 && location.Postcode.indexOf('undefined') === -1) {
        Rev.Utils.GaTracking.trackGaEvent(Rev.Utils.GaTracking.Category.SalesAuctionResults, Rev.Utils.GaTracking.Action.Search, location.Suburb + ' ' + location.State + ' ' + location.Postcode);
      }

      this.updateLocationHiddenField();
    },
    onItemRemoved: function onItemRemoved(e) {
      var location = e.item;
      if (location) {
        this.togglePlaceholder();
      }
      this.toggleSaveAllSuburbsForm();
      this.updateLocationHiddenField();
    },
    updateLocationHiddenField: function updateLocationHiddenField() {
      var locationString = '';
      var locations = this.$tagsinput.tagsinput('items');
      if (locations && locations.length) {
        var arr = _.map(locations, function (location) {
          if (location && location.Suburb && location.State && location.Postcode) {
            return location.Suburb.toLowerCase() + '|' + location.State.toLowerCase() + '|' + location.Postcode;
          }
        });
        locationString = arr.join(',');
      }

      $('.form-save-all-suburbs input[name="suburbs"]').val(locationString);
    },
    toggleSaveAllSuburbsForm: function toggleSaveAllSuburbsForm() {
      if (this.$tagsinput.tagsinput('items').length >= 1) {
        this.$('form.form-save-all-suburbs').removeClass('hide');
      } else {
        this.$('form.form-save-all-suburbs').addClass('hide');
      }
    },
    togglePlaceholder: function togglePlaceholder() {
      if (this.$tagsinput.tagsinput('items').length > 0) {
        this.hidePlaceholder();
        this.$('.tt-input').css('width', 'auto').addClass('small');
        this.$('i.icon-icon-map-pin').hide();
      } else {
        this.showPlaceholder();
        this.$('.tt-input').removeClass('small');
        this.$('i.icon-icon-map-pin').show();
      }
    },
    showPlaceholder: function showPlaceholder() {
      this.$tagsinput.tagsinput('input').attr('placeholder', 'Enter suburb(s)');
      this.$('.tt-input').css('max-width', '280px');
    },
    hidePlaceholder: function hidePlaceholder() {
      if (this.$tagsinput.tagsinput('input').removeAttr) this.$tagsinput.tagsinput('input').removeAttr('placeholder');
    },
    onHoverSuggestion: function onHoverSuggestion(e) {
      this.$('.tt-menu-placeholder .tt-suggestion').removeClass('tt-cursor');
      this.$(e.currentTarget).addClass('tt-cursor');
    },
    initializeBloodHound: function initializeBloodHound() {
      this.locationSuggestions = new Bloodhound({
        datumTokenizer: Bloodhound.tokenizers.obj.whitespace,
        queryTokenizer: Bloodhound.tokenizers.whitespace,
        remote: {
          url: '/location/search/?onlyvic=true&searchText=%QUERY',
          replace: function replace(url, query) {
            var arr = query.split(',');
            return url.replace("%QUERY", arr[arr.length - 1].trim());
          }
        },
        limit: 10
      });

      this.locationSuggestions.initialize();
    },
    initializeLocationTypeahead: function initializeLocationTypeahead() {
      var _this5 = this;

      var template = _.template($('#suggestion-location-item').html());

      if (this.$tagsinput) {
        this.$tagsinput.off();
        this.$tagsinput.tagsinput('destroy');
      }

      this.$tagsinput = this.$('[data-hook="location-input"]');

      this.$tagsinput.tagsinput({
        maxChars: 100,
        freeInput: true, // this will be ignored if itemValue option is set
        itemValue: function itemValue(item) {
          return item.Suburb + '|' + item.State + '|' + item.Postcode;
        },
        itemText: function itemText(item) {
          return item.Suburb;
        },
        typeaheadjs: [{
          limit: 10,
          highlight: true,
          minLength: 3,
          hint: false,
          menu: this.$('.tt-menu-placeholder')
        }, {
          displayKey: 'FullName',
          source: this.locationSuggestions.ttAdapter(),
          templates: {
            suggestion: function suggestion(item) {
              var html = template({ suburb: item.Suburb, state: item.State, postcode: item.Postcode });
              return html;
            }
          }
        }]

      });

      this.$el.on('typeahead:autocomplete', function (event, item) {
        _this5.$('.bootstrap-tagsinput  input.tt-input').typeahead('val', null);
        _this5.$tagsinput.tagsinput('add', { Suburb: item.Suburb, State: item.State, Postcode: item.Postcode });
      });
    }
  });
})(Rev, jQuery, _, Backbone);
'use strict';

// dependencies : Rev, jquery, underscore, backbone

(function (Rev, $, _, Backbone) {

  'use strict';

  Rev.Views.AuctionResultListView = Backbone.View.extend({
    initialize: function initialize(options) {
      _.bindAll(this, 'moveToActiveLetter');
      this.options = options || {};
      this.initAlphabetSlick();
      this.moveToActiveLetter();
    },


    events: {
      'click .btn-arrow-left': 'onArrowLeftClick',
      'click .btn-arrow-right': 'onArrowRightClick',
      'click [data-hook="toggle-auction-results"]': 'onToggleAuctionResultsClick',
      'click [data-hook="suburb-name"]': 'onSuburbNameClick',
      'click [data-hook="btn-collapse-all"]': 'onCollapseAllClick',
      'click [data-hook="btn-auction-alert-append"]': 'onAddAuctionAlertClick'
    },

    onCollapseAllClick: function onCollapseAllClick(e) {
      if (this.$(e.currentTarget).text().trim().toLowerCase() === 'collapse all') {
        this.$('.suburb-list-item').removeClass('show-list');
      } else {
        this.$('.suburb-list-item').addClass('show-list');
      }

      this.$(e.currentTarget).text(this.$(e.currentTarget).text().trim().toLowerCase() === 'collapse all' ? 'Expand all' : 'Collapse all');
      //this.$('.suburb-list-item').toggleClass('show-list');
    },
    initAlphabetSlick: function initAlphabetSlick() {
      this.slickInstance = Rev.Utils.initSlick(this.$('.alphabets'), {
        centerMode: false,
        centerPadding: 0,
        infinite: true,
        slidesToShow: 26,
        slidesToScroll: 26,
        responsive: [{
          breakpoint: 768,
          settings: {
            slidesToShow: 9,
            slidesToScroll: 9
          }
        }]
      });
    },
    moveToActiveLetter: function moveToActiveLetter(event, slick) {
      var self = this;

      var alphabets = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'];

      if (_.indexOf(alphabets, self.options.startLetter.toLowerCase()) < 9) {
        return;
      }

      setTimeout(function () {
        var idx = _.indexOf(alphabets, self.options.startLetter.toLowerCase());
        self.slickInstance.slick('slickGoTo', idx, true);
      }, 400);
    },
    onArrowLeftClick: function onArrowLeftClick(e) {
      e.preventDefault();

      if (this.slickInstance) {
        this.slickInstance.slick('slickPrev');
      }
    },
    onArrowRightClick: function onArrowRightClick(e) {
      e.preventDefault();

      if (this.slickInstance) {
        this.slickInstance.slick('slickNext');
      }
    },
    onToggleAuctionResultsClick: function onToggleAuctionResultsClick(e) {
      e.preventDefault();

      var $suburbListItem = $(e.currentTarget).closest('.suburb-list-item');
      this.toggleList($suburbListItem);
    },
    onSuburbNameClick: function onSuburbNameClick(e) {
      var $suburbListItem = $(e.currentTarget).closest('.suburb-list-item');
      this.toggleList($suburbListItem);
    },
    toggleList: function toggleList($suburbListItem) {
      $suburbListItem.toggleClass('show-list');
    },
    onAddAuctionAlertClick: function onAddAuctionAlertClick(e) {
      e.preventDefault();
      var self = this;

      $(e.currentTarget).button('loading');

      var afterAuthCallback = function afterAuthCallback() {
        self.refreshAntiforgeryToken(function () {
          self.saveAuctionAlert(self.$(e.currentTarget).closest('form.auction-alert-append-form'), setTimeout(function () {
            return window.location.reload();
          }, 500));
        });
      };
      var closeAuthWindowCallback = function closeAuthWindowCallback() {
        return self.$('[data-hook="btn-auction-alert-append"]').button('reset');
      };
      var callbackIfAlreadyAuthenticated = function callbackIfAlreadyAuthenticated() {
        return self.saveAuctionAlert(self.$(e.currentTarget).closest('form.auction-alert-append-form'));
      };

      Rev.Utils.saveAuctionAlert(afterAuthCallback, afterAuthCallback, closeAuthWindowCallback, callbackIfAlreadyAuthenticated);
    },
    refreshAntiforgeryToken: function refreshAntiforgeryToken(successCallback) {
      $.get('/refreshtoken/').done(function (html) {
        var tokenValue = $('<div />').html(html).find('input[type="hidden"]').val();
        $('input[name="__RequestVerificationToken"]').val(tokenValue);
        if (successCallback) successCallback();
      });
    },
    saveAuctionAlert: function saveAuctionAlert($form, callback) {
      var _this = this;

      var actionUrl = $form.attr('action');

      // ajax call
      $.post(actionUrl, $form.serialize()).done(function (result) {
        if (result.errors) {
          Rev.Utils.showErrorMessage(_.pluck(result.errors, 'Value').join(', '));
        } else {
          Rev.Utils.showSuccessMessage('Auction alerts saved');
          if (callback) callback();
        }
      }).fail(function (result) {
        Rev.Utils.showErrorMessage('Auction alerts not saved');
      }).always(function () {
        _this.$('[data-hook="btn-auction-alert-append"]').button('reset');
      });
    }
  });
})(Rev, jQuery, _, Backbone);
'use strict';

// dependencies : Rev, jquery, underscore, backbone

(function (Rev, $, _, Backbone) {

  'use strict';

  Rev.Views.ConfirmView = Backbone.View.extend({
    initialize: function initialize(options) {
      _.bindAll(this, 'closeView');
      var options = options || {};
      this.okCallback = options.okCallback;
      this.cancelCallback = options.caneclCallback;
    },

    events: {
      'click [data-hook="close"]': 'closeView',
      'hidden.bs.modal': 'onModalHidden',
      'click [data-hook="confirm-ok"]': 'onOkClick',
      'click [data-hook="confirm-cancel"]': 'onCancelClick'
    },

    onOkClick: function onOkClick(e) {
      if (this.okCallback && _.isFunction(this.okCallback)) {
        this.okCallback();
      }
      this.closeView();
    },
    onCancelClick: function onCancelClick(e) {
      if (this.cancelCallback && _.isFunction(this.cancelCallback)) {
        this.cancelCallback();
      }
      this.closeView();
    },
    onModalHidden: function onModalHidden(e) {
      $('.list-result-items').removeClass('modal-open');
    },
    closeView: function closeView(e) {
      if (e && e.preventDefault) e.preventDefault();

      $('.rev-modal-backdrop').hide();
      this.$el.modal('hide');
    },
    remove: function remove() {
      this.closeView();
      this.off();
      Backbone.View.prototype.remove.apply(this, arguments); //call the superclass remove method
    }
  });
})(Rev, jQuery, _, Backbone);
'use strict';

// dependencies : Rev, jquery, underscore, backbone

(function (Rev, $, _, Backbone) {

    'use strict';

    Rev.Views.ContactAgentView = Backbone.View.extend({
        initialize: function initialize(options) {
            _.bindAll(this, 'showView', 'closeView');

            var options = options || {};
            this.gaCategory = options.gaCategory;
            this.gaAgencyName = options.gaAgencyName;
            this.gaAgencyEmail = options.gaAgencyEmail;

            this.agentEnquiryErrorPlaceHolder = this.$('[data-hook="contact-agent-validation-errors-placeholder"]');
            this.postEnquiryAdPlaceHolder = this.$('[data-hook="post-enquiry-ad-validation-errors-placeholder"]');
        },

        events: {
            'click [data-hook="close"]': 'closeView',
            'click [data-hook="btn-contact-agent"]': 'makeEnquiry',
            'hidden.bs.modal': 'onModalHidden',
            'click [data-hook="btn-post-enquiry-ad-submit"]': 'submitPostEnquiryForm'
        },

        submitPostEnquiryForm: function submitPostEnquiryForm(e) {
            var _this = this;

            e.preventDefault();

            var $form = this.$('[data-hook="post-enquiry-ad-enquiry-form"]');
            var url = $form.attr('action');

            $(e.currentTarget).button('loading');

            $.post(url, $form.serialize()).done(function (result) {
                if (result.errors) {
                    Rev.Utils.showErrors(result.errors, _this.postEnquiryAdPlaceHolder);
                    if (_this.scrollTop) $('html, body').animate({ scrollTop: _this.scrollTop }, 400);
                } else {
                    _this.showPostEnquiryConfirmation();
                }
            }).fail(function (result) {
                Rev.Utils.showErrors(result.errors, _this.postEnquiryAdPlaceHolder);
                // scroll up to show error message
                if (_this.scrollTop) $('html, body').animate({ scrollTop: _this.scrollTop }, 400);
            }).always(function () {
                _this.$('[data-hook="btn-post-enquiry-ad-submit"]').button('reset');
            });
        },
        showPostEnquiryConfirmation: function showPostEnquiryConfirmation() {
            var _this2 = this;

            var fullName = this.$('[data-hook = "enquiry-name"]').val();
            this.$('[data-hook="post-enquiry-ad-success-title"]').text('Thanks ' + fullName);

            $('html, body').animate({ scrollTop: this.$el.offset().top - $('#layout-header').height() }, function () {
                _this2.$('[data-hook="email-agent-success"]').slideUp({ duration: 400, easing: 'linear' });
                _this2.$('[data-hook="post-enquiry-ad"]').fadeOut(300, function () {
                    $('[data-hook="post-enquiry-ad-success"]').fadeIn(400);
                });
            });
        },
        showView: function showView() {
            this.$el.modal('show');
        },
        onModalHidden: function onModalHidden(e) {
            $('.list-result-items').removeClass('modal-open');
        },
        closeView: function closeView(e) {
            if (e && e.preventDefault) e.preventDefault();

            $('.rev-modal-backdrop').hide();
            this.$el.modal('hide');
        },
        remove: function remove() {
            this.closeView();
            this.off();
            Backbone.View.prototype.remove.apply(this, arguments); //call the superclass remove method
        },
        makeEnquiry: function makeEnquiry(e) {
            var _this3 = this;

            e.preventDefault();

            var $form = this.$('[data-hook="contact-agent-form"]');
            var url = $form.attr('action');

            $(e.currentTarget).button('loading');

            $.post(url, $form.serialize()).done(function (result) {
                if (result.errors) {
                    Rev.Utils.showErrors(result.errors, _this3.agentEnquiryErrorPlaceHolder);
                    if (_this3.scrollTop) $('html, body').animate({ scrollTop: _this3.scrollTop }, 400);
                } else {
                    _this3.showSuccessMessage();
                }
            }).fail(function (result) {
                Rev.Utils.showErrors(result.errors, _this3.agentEnquiryErrorPlaceHolder);
                if (_this3.scrollTop) $('html, body').animate({ scrollTop: _this3.scrollTop }, 400);
            }).always(function () {
                _this3.$('[data-hook="btn-contact-agent"]').button('reset');
            });

            if (this.gaCategory && this.gaAgencyName && this.gaAgencyEmail) Rev.Utils.GaTracking.trackGaEvent(this.gaCategory, Rev.Utils.GaTracking.Action.SendToAgent, this.gaAgencyName + ' / ' + this.gaAgencyEmail);

            Rev.Utils.GaTracking.trackEmailAgent(this.model);
        },
        showSuccessMessage: function showSuccessMessage() {
            var _this4 = this;

            var fullName = this.$('[data-hook = "enquiry-name"]').val().split(" ");
            var firstName = fullName[0];
            var lastName = fullName[1];

            this.$('.agent-name-confirm').text('Thank you for your enquiry.');

            // set name, email and phone value to home loan form
            this.$('[data-hook = "post-enquiry-ad-enquiry-first-name"]').val(firstName);
            this.$('[data-hook = "post-enquiry-ad-enquiry-last-name"]').val(lastName);
            this.$('[data-hook = "post-enquiry-ad-enquiry-email"]').val(this.$('[data-hook = "enquiry-email"]').val());
            this.$('[data-hook = "post-enquiry-ad-enquiry-phone"]').val(this.$('[data-hook = "enquiry-phone"]').val());

            this.$('[data-hook="contact-agent-form"]').fadeOut(400, function () {
                _this4.$el.addClass('contact-agent-success');
                _this4.$('[data-hook="contact-agent-success"],[data-hook="post-enquiry-ad"]').fadeIn(500);
            });
        },
        hideSuccessaMessage: function hideSuccessaMessage() {
            this.$('[data-hook="contact-agent-form"]').show();
            this.$('[data-hook="contact-agent-success"]').hide();
        }
    });
})(Rev, jQuery, _, Backbone);
'use strict';

// dependencies : Rev, jquery, underscore, backbone

(function (Rev, $, _, Backbone) {

  'use strict';

  Rev.Views.ExternalSearchFormLocationView = Backbone.View.extend({
    initialize: function initialize(options) {
      _.bindAll(this, 'onIssCheckboxClick', 'reset', 'closeView', 'showPlaceholder', 'hidePlaceholder', 'togglePlaceholder', 'onLocationInputKeydown');

      if (options) {
        this.baseSearchForm = options.baseSearchForm;
      }

      this.initialLoad = true;

      this.initializeBloodHound();
      this.initializeLocationTypeahead();
      this.showRecentlySearchedLocations();

      this.listenTo(Rev, 'refine:search:reset', this.reset);
    },


    events: {
      'itemAdded [data-hook="location-input"]': 'onItemAdded',
      'itemRemoved [data-hook="location-input"]': 'onItemRemoved',
      'blur .bootstrap-tagsinput': 'onLocationFocusOut',
      'focus .bootstrap-tagsinput': 'onLocationFocusIn',
      'keypress .tt-input': 'onLocationInputKeypress',
      'mouseenter .tt-suggestion': 'onHoverSuggestion',
      'click [data-hook="cb-include-surrounding-suburbs"]': 'onIssCheckboxClick',
      'mouseover .btn-include-surrounding-suburbs-wrapper': 'onIssMouseover',
      'mouseout .btn-include-surrounding-suburbs-wrapper': 'onIssMouseout'
    },

    onIssMouseover: function onIssMouseover(e) {
      var _this = this;

      // show tooltip
      this.$('[data-hook="pulse-tooltip"]').show();

      // hide tooltip in 5 seconds
      if (this.timer != null) clearTimeout(this.timer);
      this.timer = setTimeout(function () {
        _this.$('[data-hook="pulse-tooltip"]').hide();
      }, 5000);
    },
    onIssMouseout: function onIssMouseout(e) {
      this.$('[data-hook="pulse-tooltip"]').hide();
    },
    onIssCheckboxClick: function onIssCheckboxClick(e) {
      var self = this;

      // show tooltip
      this.$('[data-hook="pulse-tooltip"]').show();

      // hide tooltip in 5 seconds
      if (this.timer != null) clearTimeout(this.timer);
      this.timer = setTimeout(function () {
        self.$('[data-hook="pulse-tooltip"]').hide();
      }, 5000);

      this.baseSearchForm.getTotal();

      // fire ga event
      if ($(e.currentTarget).is(':checked')) {
        this.baseSearchForm.fireGaEvent(Rev.Utils.GaTracking.Action.SurroundingSuburbs, Rev.Utils.GaTracking.Label.On);
      } else {
        this.baseSearchForm.fireGaEvent(Rev.Utils.GaTracking.Action.SurroundingSuburbs, Rev.Utils.GaTracking.Label.Off);
      }
    },
    onHoverSuggestion: function onHoverSuggestion(e) {
      this.$('.tt-menu-placeholder .tt-suggestion').removeClass('tt-cursor');
      this.$(e.currentTarget).addClass('tt-cursor');
    },
    initializeBloodHound: function initializeBloodHound() {
      this.locationSuggestions = new Bloodhound({
        datumTokenizer: Bloodhound.tokenizers.obj.whitespace,
        queryTokenizer: Bloodhound.tokenizers.whitespace,
        remote: {
          url: '/location/search/?searchText=%QUERY',
          replace: function replace(url, query) {
            var arr = query.split(',');
            return url.replace("%QUERY", arr[arr.length - 1].trim());
          }
        },
        limit: 10
      });

      this.locationSuggestions.initialize();
    },
    initializeLocationTypeahead: function initializeLocationTypeahead() {
      var _this2 = this;

      var template = _.template($('#suggestion-location-item').html());

      if (this.$tagsinput) {
        this.$tagsinput.off();
        this.$tagsinput.tagsinput('destroy');
      }

      this.$tagsinput = this.$('[data-hook="location-input"]');

      this.$tagsinput.tagsinput({
        maxChars: 100,
        freeInput: true, // this will be ignored if itemValue option is set
        itemValue: function itemValue(item) {
          return item.Suburb + '|' + item.State + '|' + item.Postcode;
        },
        itemText: function itemText(item) {
          return item.Suburb;
        },
        typeaheadjs: {
          limit: 2,
          options: {
            highlight: true,
            minLength: 3,
            hint: false,
            menu: this.$('.tt-menu-placeholder')
          },
          displayKey: 'FullName',
          source: this.locationSuggestions.ttAdapter(),
          templates: {
            suggestion: function suggestion(item) {
              var html = template({ suburb: item.Suburb, state: item.State, postcode: item.Postcode });
              return html;
            }
          }
        }
      });

      this.$el.on('typeahead:autocomplete', function (event, item) {
        _this2.$('.bootstrap-tagsinput  input.tt-input').typeahead('val', null);
        _this2.$tagsinput.tagsinput('add', { Suburb: item.Suburb, State: item.State, Postcode: item.Postcode });
      });
    },
    reset: function reset() {
      this.$tagsinput.tagsinput('removeAll');
      Rev.Models.localData.save({ 'recentlySearchedLocations': '' });
    },
    onItemAdded: function onItemAdded(e) {
      // save locations in local storage.
      var location = e.item;
      Rev.Models.localData.save({ 'recentlySearchedLocations': this.$tagsinput.val() });
      this.togglePlaceholder();

      //this.initialLoad is just for avoiding call server in page load time
      if (!this.initialLoad) {
        this.baseSearchForm.getTotal();
        if (location && location.Suburb && location.State && location.Postcode && location.Suburb.indexOf('undefined') === -1 && location.State.indexOf('undefined') === -1 && location.Postcode.indexOf('undefined') === -1) {
          this.baseSearchForm.fireGaEvent(Rev.Utils.GaTracking.Action.Search, location.Suburb + ' ' + location.State + ' ' + location.Postcode); // fire ga event
        }
      }
      this.initialLoad = false;
    },
    onItemRemoved: function onItemRemoved(e) {
      // remove the location from local storage
      var location = e.item;
      if (location) {
        Rev.Models.localData.fetch();
        var reg = new RegExp(location.Suburb + '|' + location.State + '|' + location.Postcode, 'g');
        var newLoc = Rev.Models.localData.get('recentlySearchedLocations').replace(reg, '');
        if (newLoc === '||') newLoc = '';
        Rev.Models.localData.save({ 'recentlySearchedLocations': newLoc });

        this.togglePlaceholder();
        this.baseSearchForm.getTotal();
      }
    },
    showRecentlySearchedLocations: function showRecentlySearchedLocations() {
      var _this3 = this;

      Rev.Models.localData.fetch();
      var locations = Rev.Models.localData.get('recentlySearchedLocations').trim().split(',');
      _.each(locations, function (location) {
        if (!location) return;
        var locationSplited = [];
        if (location.indexOf('|') > -1) locationSplited = location.split('|');
        if (location.indexOf('_') > -1) locationSplited = location.split('_');

        if (locationSplited[0] && locationSplited[1] && locationSplited[2]) {
          if (locationSplited[0].indexOf('undefined') === -1 && locationSplited[1].indexOf('undefined') === -1 && locationSplited[2].indexOf('undefined') === -1) {
            _this3.$tagsinput.tagsinput('add', { Suburb: locationSplited[0], State: locationSplited[1], Postcode: locationSplited[2] });
          } else {
            // just clear it when it has 'undefined' 
            Rev.Models.localData.save({ 'recentlySearchedLocations': '' });
          }
        }
      });
      this.$('.bootstrap-tagsinput').addClass('one-line');
      this.togglePlaceholder();
    },
    onLocationFocusOut: function onLocationFocusOut(e) {
      this.$('.bootstrap-tagsinput').addClass('one-line');
      this.togglePlaceholder();
      this.$('.tt-menu-placeholder').hide();
    },
    onLocationFocusIn: function onLocationFocusIn(e) {
      this.$('.tt-input').removeClass('small');
      this.$('.bootstrap-tagsinput').removeClass('one-line');
      this.hidePlaceholder();
      this.$('.tt-menu-placeholder').show();
      if (this.$tagsinput.tagsinput('items').length == 0) {
        this.$('.tt-input').removeClass('margin-left-0').addClass('margin-left-5');
      } else {
        this.$('.tt-input').removeClass('margin-left-5').addClass('margin-left-0');
      }
    },
    onLocationInputKeydown: function onLocationInputKeydown(e) {
      if (this.$tagsinput.tagsinput('items').length == 0) {
        this.$('.tt-input').removeClass('margin-left-0').addClass('margin-left-5');
      } else {
        this.$('.tt-input').removeClass('margin-left-5').addClass('margin-left-0');
      }
    },
    onLocationInputKeypress: function onLocationInputKeypress(e) {
      if (this.$tagsinput.tagsinput('items').length == 0) {
        this.$('.tt-input').removeClass('margin-left-0').addClass('margin-left-5');
      } else {
        this.$('.tt-input').removeClass('margin-left-5').addClass('margin-left-0');
        this.$('.tt-input').removeClass('small');
      }

      if (e.which == 13) {
        // if no items selected and typed some text, send it to get first item in suggestions
        var text = this.$tagsinput.tagsinput('input').val();
        if (this.$tagsinput.tagsinput('items').length == 0 && text && text.length > 0) {
          this.$('[data-hook="freetext-location"]').val(text);
        }

        //Rev.trigger('search:submit');        
        this.baseSearchForm.submitForm();
      }
    },
    togglePlaceholder: function togglePlaceholder() {
      if (this.$tagsinput.tagsinput('items').length > 0) {
        this.hidePlaceholder();
        this.$('.tt-input').css('width', 'auto').addClass('small');
      } else {
        this.showPlaceholder();
        this.$('.tt-input').removeClass('small');
      }
    },
    showPlaceholder: function showPlaceholder() {
      this.$tagsinput.tagsinput('input').attr('placeholder', 'Search by suburb, postcode or area');
      this.$('.tt-input').css('max-width', '270px');
    },
    hidePlaceholder: function hidePlaceholder() {
      if (this.$tagsinput.tagsinput('input').removeAttr) this.$tagsinput.tagsinput('input').removeAttr('placeholder');
    },
    closeView: function closeView(e) {
      if (e && e.preventDefault) e.preventDefault();

      // save locations in local storage.
      Rev.Models.localData.save({ 'recentlySearchedLocations': this.$tagsinput.val() });

      $(document).off('typeahead:cursorchange typeahead:select');
    }
  });
})(Rev, jQuery, _, Backbone);
'use strict';

// dependencies : Rev, jquery, underscore, backbone

(function (Rev, $, _, Backbone) {

  'use strict';

  Rev.Views.ExternalSearchFormMenuTypeView = Backbone.View.extend({
    initialize: function initialize(options) {
      _.bindAll(this, 'onSearchMenuTypeClick');

      var options = options || {};
      this.baseSearchForm = options.baseSearchForm;
    },


    events: {
      'click [data-hook="dropdown-selected-value"] input[type=radio]': 'onSearchMenuTypeClick',
      'shown.bs.dropdown': 'onDropdownShown'
    },

    onDropdownShown: function onDropdownShown(e) {
      var _this = this;

      $(document).one('touchend', function (e) {
        return _this.$('div.dropdown-backdrop').remove();
      }); // removing dropdown-backdrop div enable user open another dropdown menu immediately without extra tap in mobile device when opening this dropdown menu. Refer http://getbootstrap.com/javascript/#dropdowns
    },
    onSearchMenuTypeClick: function onSearchMenuTypeClick(e) {
      var isRefineSearch = this.baseSearchForm.$el.hasClass('refine-search');
      var searchMenuType = $(e.currentTarget).val();
      var searchMenuTypeText = $(e.currentTarget).siblings('span').text();

      //this.$('[data-hook="selected-rooms-text"]').dropdown('toggle'); // close dropdown menu
      this.$('[data-hook="selected-rooms-text"] span').text(searchMenuTypeText);
      Rev.trigger('search:menu:changed', searchMenuType.toLowerCase());
      this.baseSearchForm.getTotal();

      // update url
      if (this.updateUrl) {
        var url = $(e.currentTarget).siblings('span').find('a').attr('href');
        Rev.Routers.contractTypeRouter.navigate(url, { trigger: false, replace: true });
      }
    }
  });
})(Rev, jQuery, _, Backbone);
'use strict';

// dependencies : Rev, jquery, underscore, backbone

(function (Rev, $, _, Backbone) {

  'use strict';

  Rev.Views.ExternalSearchFormView = Backbone.View.extend({
    initialize: function initialize(options) {
      _.bindAll(this, 'fireGaEvent', 'getTotal', 'onSearchSubmitRequested', 'submitForm');

      this.initializeSubViews();
      this.listenTo(Rev, 'search:ga:fire', this.fireGaEvent);
      this.listenTo(Rev, 'search:submit', this.onSearchSubmitRequested);
      this.listenTo(Rev, 'search:filter:changed', this.getTotal);
    },


    events: {
      'click [data-hook="btn-submit-search-filters"]': 'onClickSubmitSearch'
    },

    initializeSubViews: function initializeSubViews() {
      this.menuTypeView = new Rev.Views.ExternalSearchFormMenuTypeView({ el: this.$('.form-group-searchmenu-type'), baseSearchForm: this, updateUrl: this.updateUrl });
      this.locationView = new Rev.Views.ExternalSearchFormLocationView({ el: this.$('.search-form-location'), model: this.model, isRefineSearch: this.isRefineSearch, baseSearchForm: this });
    },
    fireGaEvent: function fireGaEvent(action, label) {
      var category = 'home-';

      if (this.$el.hasClass('refine-search')) {
        category = 'refinesearch-';
      }

      var searchMenuType = this.$('[data-hook="dropdown-selected-value"] input[type=radio]:checked').val();

      if (searchMenuType) {
        searchMenuType = searchMenuType.trim();

        if (searchMenuType == 'Buy') {
          category += 'buy';
        } else if (searchMenuType == 'Rent') {
          category += 'rent';
        } else if (searchMenuType == 'Sold') {
          category += 'sold';
        }
      }

      if (this.isEditingSavedSearch) {
        category = Rev.Utils.GaTracking.Category.RefineSearchSavedSearches;
      }

      // in case of refine search, check if search form is visible or not, if not, don't fire ga events
      if ((category === 'refinesearch-buy' || category === 'refinesearch-rent' || category === 'refinesearch-sold') && !$('.result-header').hasClass('open')) {
        return;
      }

      // in case of editing saved search, check if search form is visible or not, if not, don't fire ga events
      if (category === Rev.Utils.GaTracking.Category.RefineSearchSavedSearches && !$('.new-search-form').hasClass('open')) {
        return;
      }

      Rev.Utils.GaTracking.trackGaEvent(category, action, label);
    },
    submitForm: function submitForm() {
      var _this = this;

      var wait = Rev.Utils.isiPad() ? 1000 : 50;
      this.$el.addClass('loading');
      setTimeout(function () {
        return _this.$('form').submit();
      }, wait);
    },
    onSearchSubmitRequested: function onSearchSubmitRequested() {
      this.submitForm();
    },
    onClickSubmitSearch: function onClickSubmitSearch(e) {
      this.submitForm();
    },
    getTotal: function getTotal() {
      var self = this;
      var $form = this.$('.search-form');
      var url = '/portal/search/listings/total/json/';
      var wait = 10;

      self.$('[data-hook="btn-submit-total-results"]').removeClass('show').text('');
      self.$('[data-hook="btn-submit-search-filters"]').addClass('btn-submit-loading');

      $.getJSON(url, $form.serialize()).done(function (result) {
        var total = '';
        if (result.TotalItems && parseInt(result.TotalItems, 10) > 1000) {
          total = '1000+';
        } else {
          total = Rev.Utils.String.numberWithCommas(result.TotalItems);
        }

        setTimeout(function () {
          return self.$('[data-hook="btn-submit-total-results"]').text(total).addClass('show');
        }, wait);
      }).fail(function (result) {
        // TODO : show error
      }).always(function () {
        setTimeout(function () {
          return self.$('[data-hook="btn-submit-search-filters"]').removeClass('btn-submit-loading');
        }, wait);
      });
    },
    remove: function remove() {
      if (this.menuTypeView) this.menuTypeView.remove();
      if (this.locationView) this.locationView.remove();

      this.off();
      this.stopListening();

      //call the superclass remove method
      Backbone.View.prototype.remove.apply(this, arguments);
    }
  });
})(Rev, jQuery, _, Backbone);
'use strict';

// dependencies : Rev, jquery, underscore, backbone, slick.js

(function (Rev, $, _, Backbone) {

    'use strict';

    Rev.Views.InspectionAuctionTimesView = Backbone.View.extend({

        events: {
            'click [data-hook="contact-inspection-email"]': 'openEmailAgentModal',
            'click [data-hook="save-auction"]': 'saveAction',
            'click [data-hook="save-inspection"]': 'saveInspection'
        },
        saveInspection: function saveInspection(e) {
            var index = parseInt($(e.currentTarget).attr('data-inspection-number'));
            Rev.Utils.icsFile.icsFileDownloading(this.model, index);

            Rev.Utils.MatomoTracking.sendEvent(this.model, Rev.Utils.MatomoTracking.Category.ListingLeads, Rev.Utils.MatomoTracking.Action.InspectionTimeSave);
        },
        saveAction: function saveAction(e) {
            Rev.Utils.icsFile.icsFileDownloading(this.model);

            Rev.Utils.MatomoTracking.sendEvent(this.model, Rev.Utils.MatomoTracking.Category.ListingLeads, Rev.Utils.MatomoTracking.Action.AuctionTimeSave);
        },
        openEmailAgentModal: function openEmailAgentModal(e) {
            e.preventDefault();

            if (Rev.IsPhone) {
                $('html,body').animate({ scrollTop: $("#emailagent").offset().top }, 'slow');
            } else {

                Rev.Utils.GaTracking.trackGaEvent(this.model.get('GaEventCategory'), Rev.Utils.GaTracking.Action.EmailAgent, this.model.get('AgencyName') + ' / ' + this.model.get('AgencyId'));

                Rev.Utils.showEmailAgentModal(this.model.get('Id'), this.model.get('GaEventCategory'), this.model.get('AgencyName'), this.model.get('AgencyEmail'), null, this.model.get('AgencyId'));
            }
        },
        remove: function remove() {
            this.off();
            this.stopListening();

            //call the superclass remove method
            Backbone.View.prototype.remove.apply(this, arguments);
        }
    });
})(Rev, jQuery, _, Backbone);
'use strict';

// dependencies : Rev, jquery, underscore, backbone

(function (Rev, $, _, Backbone) {

  'use strict';

  Rev.Views.JoinView = Backbone.View.extend({

    initialize: function initialize() {
      $.get('/authenticated/').done(function (result) {
        if (result && !result.isAuthenticated) {
          // save cookie so that user will return to home page after signing up. this cookie will be used in signup_view.js
          $.cookie('return_url', '//' + location.host, { expires: 1, path: '/' }); // 1 day
        }
      });
    },

    events: {
      'click [data-hook="signup-now"]': 'onSignupNowClick'
    },

    onSignupNowClick: function onSignupNowClick(e) {
      if (Rev.IsPhone) {
        Rev.trigger('sidebar:toggle');
        Rev.trigger('signup:toggle', { email: this.model.get('Email'), firstName: this.model.get('FirstName') });
      } else {
        Rev.Utils.showAuthModal('signup', false, false, { email: this.model.get('Email'), firstName: this.model.get('FirstName') });
      }
    }
  });
})(Rev, jQuery, _, Backbone);
'use strict';

// dependencies : Rev, jquery, underscore, backbone

(function (Rev, $, _, Backbone) {

    'use strict';

    Rev.Views.ListingDescriptionView = Backbone.View.extend({
        initialize: function initialize(options) {
            this.options = options || {};

            this.hasExpanded = false;
        },


        events: {
            'click .read-more a': 'toggleHideDescription'
        },

        toggleHideDescription: function toggleHideDescription(e) {
            e.preventDefault();
            $('.description-wrapper').toggleClass('truncate');

            if (!this.hasExpanded) {
                Rev.Utils.GaTracking.trackGaEvent(this.model.get('GaEventCategory'), Rev.Utils.GaTracking.Action.ExpandListingDescriptionReadMore, 'property ' + this.model.get('Id'));
                this.hasExpanded = true;

                $('#description-text').html(this.model.get('Description'));
            }
        },
        remove: function remove() {
            this.off();
            this.stopListening();

            //call the superclass remove method
            Backbone.View.prototype.remove.apply(this, arguments);
        }
    });
})(Rev, jQuery, _, Backbone);
'use strict';

// dependencies : Rev, jquery, underscore, backbone

(function (Rev, $, _, Backbone) {

    'use strict';

    Rev.Views.ListingEnquiryView = Backbone.View.extend({
        initialize: function initialize(options) {
            _.bindAll(this, 'showPostEnquiryConfirmation', 'makeEnquiry');

            //todo: change optoins to take full js model rather than this list of options.
            var options = options || {};
            //this.gaCategory = options.gaCategory;
            //this.gaAgencyName = options.gaAgencyName;
            //this.gaAgencyEmail = options.gaAgencyEmail;
            //this.topSpotId = options.topSpotId;
            //this.listingId = options.listingId;
            //this.agencyId = options.agencyId;

            //gaCategory: this.model.get('GaEventCategory'),
            //gaAgencyName: this.model.get('AgencyName'),
            //gaAgencyEmail: this.model.get('AgencyEmail'),
            //listingId: this.model.get('Id'),
            //agencyId: this.model.get('AgencyId')

            this.agentEnquiryErrorPlaceHolder = this.$('[data-hook="email-agent-validation-errors-placeholder"]');
            this.postEnquiryAdPlaceHolder = this.$('[data-hook="post-enquiry-ad-validation-errors-placeholder"]');
        },

        events: {
            'click [data-hook="agent-phone-number"]': 'onPhoneAgencyClick',
            'click [data-hook="btn-email-agent"]': 'makeEnquiry',
            'click [data-hook="btn-post-enquiry-ad-submit"]': 'submitPostEnquiryForm',
            'click [ data-hook="contact-agent"]': 'contactAgent',
            'click [ data-hook="contact-agency"]': 'contactAgency'
        },

        contactAgent: function contactAgent(e) {
            var agentId = this.$(e.currentTarget).attr('data-agent-id');

            Rev.Utils.MatomoTracking.sendEvent(this.model, Rev.Utils.MatomoTracking.Category.ListingLeads, Rev.Utils.MatomoTracking.Action.AgentProfile, null, null, agentId);
        },
        contactAgency: function contactAgency(e) {
            Rev.Utils.MatomoTracking.sendEvent(this.model, Rev.Utils.MatomoTracking.Category.ListingLeads, Rev.Utils.MatomoTracking.Action.AgencyProfile);
        },
        onPhoneAgencyClick: function onPhoneAgencyClick(e) {
            var $phoneWrapper = this.$(e.currentTarget).closest('.agent-number');

            var phone = $phoneWrapper.attr('data-agent-phone');

            if (!Rev.IsPhone) {
                $phoneWrapper.find('a').text(phone);
                e.preventDefault();
            }

            var agentId = $phoneWrapper.attr('data-agent-id');

            //fire ga event & lead event
            Rev.Utils.LeadTracking.sendPhoneEvent(this.model.get('Id'));

            Rev.Utils.GaTracking.trackGaEvent(this.model.get('GaEventCategory'), Rev.Utils.GaTracking.Action.PhoneAgent, this.model.get('AgencyName') + ' / ' + this.model.get('AgencyId'));

            Rev.Utils.GaTracking.trackPhoneAgent(this.model);

            Rev.Utils.Criteo.pushEventAgentContact(this.model.get('Id'));

            var actionName;
            if (!Rev.IsPhone) actionName = Rev.Utils.MatomoTracking.Action.PhoneReveal;else actionName = Rev.Utils.MatomoTracking.Action.CallAgent;

            Rev.Utils.MatomoTracking.sendEvent(this.model, Rev.Utils.MatomoTracking.Category.ListingLeads, actionName, null, null, agentId);
        },
        makeEnquiry: function makeEnquiry(e) {
            var _this = this;

            e.preventDefault();
            var self = this;
            var $form = self.$('[data-hook="email-agent-form"]');
            var url = $form.attr('action');
            $(e.currentTarget).button('loading');

            $.post(url, $form.serialize()).done(function (result) {
                if (result.errors) {
                    Rev.Utils.showErrors(result.errors, self.agentEnquiryErrorPlaceHolder);
                    if (self.scrollTop) $('html, body').animate({ scrollTop: self.scrollTop }, 400);
                } else {
                    self.showSuccessMessage();

                    // WHAT IS THIS???
                    if (_this.model.get('Id')) {
                        Rev.Utils.Criteo.pushEventAgentContact(_this.model.get('Id'));
                    }

                    if (_this.model.get('GaEventCategory') && _this.model.get('AgencyName') && _this.model.get('AgencyEmail')) Rev.Utils.GaTracking.trackGaEvent(_this.model.get('GaEventCategory'), Rev.Utils.GaTracking.Action.SendToAgent, _this.model.get('AgencyName') + ' / ' + _this.model.get('AgencyEmail'));

                    Rev.Utils.GaTracking.trackEmailAgent(_this.model);

                    Rev.Utils.MatomoTracking.sendEvent(_this.model, Rev.Utils.MatomoTracking.Category.ListingLeads, Rev.Utils.MatomoTracking.Action.EmailAgent);
                }
            }).fail(function (result) {
                Rev.Utils.showErrors(result.errors, self.agentEnquiryErrorPlaceHolder);
                if (self.scrollTop) $('html, body').animate({ scrollTop: self.scrollTop }, 400);
            }).always(function () {
                self.$('[data-hook="btn-email-agent"]').button('reset');
            });
        },
        submitPostEnquiryForm: function submitPostEnquiryForm(e) {
            var _this2 = this;

            e.preventDefault();

            var $form = this.$('[data-hook="post-enquiry-ad-enquiry-form"]');
            var url = $form.attr('action');

            $(e.currentTarget).button('loading');

            $.post(url, $form.serialize()).done(function (result) {
                if (result.errors) {
                    _this2.$el.addClass('errors-choice-homeloan');
                    Rev.Utils.showErrors(result.errors, _this2.postEnquiryAdPlaceHolder);
                    if (_this2.scrollTop) $('html, body').animate({ scrollTop: _this2.scrollTop }, 400);
                } else {
                    _this2.showPostEnquiryConfirmation();
                }
            }).fail(function (result) {
                _this2.$el.addClass('errors-choice-homeloan');
                Rev.Utils.showErrors(result.errors, _this2.postEnquiryAdPlaceHolder);
            }).always(function () {
                _this2.$('[data-hook="btn-post-enquiry-ad-submit"]').button('reset');
            });
        },
        showSuccessMessage: function showSuccessMessage() {
            var _this3 = this;

            var fullName = this.$('[data-hook = "enquiry-name"]').val().split(" ");
            var firstName = fullName[0];
            var lastName = fullName[1];

            // set name, email and phone value to home loan form
            this.$('[data-hook = "post-enquiry-ad-enquiry-first-name"]').val(firstName);
            this.$('[data-hook = "post-enquiry-ad-enquiry-last-name"]').val(lastName);
            this.$('[data-hook = "post-enquiry-ad-enquiry-email"]').val(this.$('[data-hook = "enquiry-email"]').val());
            this.$('[data-hook = "post-enquiry-ad-enquiry-phone"]').val(this.$('[data-hook = "enquiry-phone"]').val());

            var pos = this.$el.offset();
            var buffer = 50;
            $('body').animate({ scrollTop: pos.top - buffer });

            this.$('[data-hook="email-agent-form"]').fadeOut(400, function () {
                _this3.$el.addClass('email-agent-success');
                _this3.$('[data-hook="email-agent-success"]').fadeIn(500);
            });
        },
        showPostEnquiryConfirmation: function showPostEnquiryConfirmation() {
            var _this4 = this;

            var fullName = this.$('[data-hook = "enquiry-name"]').val();
            this.$('[data-hook="post-enquiry-ad-success-title"]').text('Thanks ' + fullName);

            $('html, body').animate({ scrollTop: this.$el.offset().top - $('#layout-header').height() }, function () {
                _this4.$('[data-hook="email-agent-success"]').slideUp({ duration: 400, easing: 'linear' });
                _this4.$('[data-hook="post-enquiry-ad-success"]').fadeOut(300).fadeIn(300);
            });
        },
        hideSuccessaMessage: function hideSuccessaMessage() {
            this.$('[data-hook="email-agent-form"]').show();
            this.$('[data-hook="email-agent-success"]').hide();
        }
    });
})(Rev, jQuery, _, Backbone);
'use strict';

// dependencies : Rev, jquery, underscore, backbone, slick.js

(function (Rev, $, _, Backbone) {

    'use strict';

    Rev.Views.ListingGalleryView = Backbone.View.extend({
        initialize: function initialize() {
            _.bindAll(this, 'afterSlick', 'handleOrientationChange', 'detectOrientation', 'adjustMainImageSize', 'mainPhotoImageLoad', 'adjustSideSectionImageSize', 'sidePhotoImageLoad', 'removeThisView', 'initSlick', 'resizeImage', 'forceShowingGallery');

            // photo swiping
            this.initSlick();

            // image resizing
            this.resizeImage();

            // show gallery when there is any error
            this.forceShowingGallery();
        },


        events: {
            'click [data-hook="nav-photo-left"]': 'onNavPhotoLeftClick',
            'click [data-hook="nav-photo-right"]': 'onNavPhotoRightClick'
        },

        forceShowingGallery: function forceShowingGallery() {
            var _this = this;

            setTimeout(function () {
                if (!_this.$el.hasClass('pull-up')) {
                    _this.$el.addClass('pull-up');
                }
            }, 3000);
        },
        initSlick: function initSlick() {
            var self = this;

            if (self.slickInstance) {
                self.slickInstance.slick('unslick');
            }

            if (self.$('.photo-carousel').hasClass('slick-initialized')) return;

            self.slickInstance = Rev.Utils.initSlick(self.$('.photo-carousel'), {
                centerPadding: '0px',
                fade: true,
                lazyLoad: 'ondemand'
            });
            self.slickInstance.on('afterChange', self.afterSlick); //.on('swipe', this.onPhotoSwipe);
        },
        resizeImage: function resizeImage() {
            var self = this;
            self.mainImageHeights = [];
            self.sideImageHeights = [];
            self.$('.photo-carousel img').load(self.mainPhotoImageLoad);
            setTimeout(function () {
                return self.adjustSideSectionImageSize();
            }, 500); // just use setTimeout rather than image load event :)
            self.detectOrientation();
        },
        removeThisView: function removeThisView(listingId) {
            if (listingId === this.model.get('Id')) {
                //this.remove();
                this.$el.html('').height(this.viewHeight);
            }
        },


        detectOrientation: function detectOrientation() {
            this.mql = window.matchMedia("(orientation: portrait)");

            // Add a media query change listener
            this.mql.addListener(this.handleOrientationChange);
        },

        handleOrientationChange: function handleOrientationChange(m) {
            this.adjustMainImageSize();
            this.adjustSideSectionImageSize();
        },

        mainPhotoImageLoad: function mainPhotoImageLoad(event) {
            var _this2 = this;

            var self = this;

            if (!this.$el.hasClass('pull-up')) setTimeout(function () {
                return _this2.$el.addClass('pull-up');
            }, 10);

            // #0 fire event for .list-results-item.pull-up
            // WARNING : this event should not removed even if we have resized images by server
            //if ($('.list-results-item:not(".dummy")').first().attr('data-id') === self.$el.attr('data-id')) {
            Rev.trigger('list-results-item-view:main-photo:loaded');
            //}

            // #1 clear all image heights info
            if (self.mainImageHeights) self.mainImageHeights.length = 0;

            // #2 save all image heights info again
            self.$('.photo-carousel img').each(function (index, element) {
                if (element.src) {
                    var img = { src: '', height: '' };
                    img.src = element.src.replace(/^http:|^https:/i, '');
                    img.height = self.$(element).height();

                    if (!_.find(self.mainImageHeights, function (img) {
                        return img.src == element.src;
                    }) && img.height) {
                        // save info only when height is greater than 0 and no previous info saved
                        self.mainImageHeights.push(img);
                    }
                }
            });

            self.adjustMainImageSize();

            // store height of this listing 
            self.viewHeight = self.$el.height();
        },
        adjustMainImageSize: function adjustMainImageSize() {
            var self = this;
            if (self.mainImageHeights) {
                var containerHeight = self.$('.photo-carousel').height();

                _.each(self.mainImageHeights, function (imgInfo) {
                    if (imgInfo.height <= containerHeight) {
                        self.$('.photo-carousel img[src="' + imgInfo.src + '"]').addClass('height-priority');
                    } else {
                        self.$('.photo-carousel img[src="' + imgInfo.src + '"]').removeClass('height-priority');
                    }
                });
            }
        },


        // this function is not in use at the moment
        sidePhotoImageLoad: function sidePhotoImageLoad(event) {
            //if (this.model.get('Id') != '9182828') return;
            var self = this;

            // #1 clear all image heights info
            if (self.sideImageHeights) self.sideImageHeights.length = 0;

            // #2 save all image heights info again
            self.$('.side-section .item-img').each(function (index, element) {
                if (element.src) {
                    var img = { src: '', height: '' };
                    img.src = element.src.replace(/^http:|^https:/i, '');
                    img.height = self.$(element).height();

                    if (!_.find(self.sideImageHeights, function (img) {
                        return img.src == element.src;
                    }) && img.height) {
                        // save info only when height is greater than 0 and no previous info saved
                        self.sideImageHeights.push(img);
                    }
                }
            });

            self.adjustSideSectionImageSize();
        },
        adjustSideSectionImageSize: function adjustSideSectionImageSize() {
            var self = this;

            if (!self.$('.side-section .item-img').length) return;

            if (!this.sideImageHeight1 && self.$('.side-section .item-img').eq(0)) this.sideImageHeight1 = self.$('.side-section .item-img').eq(0).height();

            if (!this.sideImageHeight2 && self.$('.side-section .item-img').eq(1)) this.sideImageHeight2 = self.$('.side-section .item-img').eq(1).height();

            if (!this.sideImageHeight3 && self.$('.side-section .item-img').eq(2)) this.sideImageHeight3 = self.$('.side-section .item-img').eq(2).height();

            for (var i = 0; i < self.$('.side-section .item-img').length; i++) {
                var varName = 'sideImageHeight' + (i + 1).toString();
                if (this[varName]) {
                    if (this[varName] <= this.$('.side-section-item').eq(i).height()) {
                        this.$('.side-section .item-img').eq(i).addClass('height-priority');
                    } else if (this.$('.side-section .item-img').eq(i).height() >= this.$('.side-section .item-img').eq(i).width()) {
                        this.$('.side-section .item-img').eq(i).addClass('height-priority');
                    } else {
                        this.$('.side-section .item-img').eq(i).removeClass('height-priority');
                    }
                }
            }
        },
        onNavPhotoLeftClick: function onNavPhotoLeftClick(e) {
            e.preventDefault();
            e.stopPropagation();
            if (this.slickInstance) {
                this.slickInstance.slick('slickPrev');
            }
        },
        onNavPhotoRightClick: function onNavPhotoRightClick(e) {
            e.preventDefault();
            e.stopPropagation();
            if (this.slickInstance) {
                this.slickInstance.slick('slickNext');
            }
        },
        afterSlick: function afterSlick(event, slick, currentSlide) {
            this.$('[data-hook="photo-counts"]').text('(' + (currentSlide + 1) + '/' + slick.slideCount + ')');

            // fire ga event
            if (!this.isGaFired) {
                Rev.Utils.GaTracking.trackGaEvent(this.model.get('GaEventCategory'), Rev.Utils.GaTracking.Action.ImageGallery, Rev.Utils.GaTracking.Label.Property + this.model.get('Id'));
                this.isGaFired = true;
            }

            Rev.Utils.LeadTracking.sendPhotoEvent(this.model.get('Id'));

            Rev.Utils.MatomoTracking.sendEvent(this.model, Rev.Utils.MatomoTracking.Category.ListingLeads, Rev.Utils.MatomoTracking.Action.PropertyDetailsCarousel);
        },
        remove: function remove() {
            if (this.mql) {
                this.mql.removeListener(this.handlerOrientationChange);
            }

            if (this.slickInstance) {
                this.slickInstance.slick('unslick');
            }

            this.off();

            //call the superclass remove method
            Backbone.View.prototype.remove.apply(this, arguments);
        }
    });
})(Rev, jQuery, _, Backbone);
'use strict';

// dependencies : Rev, jquery, underscore, backbone, slick.js

(function (Rev, $, _, Backbone) {

    'use strict';

    Rev.Views.ListingInfoPhotoView = Backbone.View.extend({
        el: '.listing-info-and-photo',

        initialize: function initialize() {
            this.initSubViews();
            this.initListeners();
        },


        events: {
            'click [data-hook="btn-print"]': 'onPrintClick',
            'click [data-hook="btn-share"]': 'onShareClick',
            'click [data-hook="share-fb"]': 'onShareFBClick',
            'click [data-hook="share-twitter"]': 'onShareTwitterClick',
            'click [data-hook="close-share-lightbox"]': 'onCloseShareLightbox',
            'click [data-hook="share-friend"]': 'onShareFriendClick',
            'click [data-hook="open-full-photo-viewer"]': 'onPhotoClick',
            'click [data-hook="hero-image-gallery"]': 'onPhotoClick',
            'click [data-hook="open-full-photo-viewer-to-floorplans"]': 'onFloorplanClick',
            'click [data-hook="open-youtube-video"]': 'onYoutubeVideoClick',
            'click [data-hook="open-virtual-tour"]': 'onVirtualTourClick',
            'click [data-hook="soi-multiple"]': 'onSoiClick',
            'mouseenter li.soi-multiple': 'onSoiMultipleMouseenter',
            'mouseleave li.soi-multiple': 'onSoiMultipleMouseleave',
            'click .js-soi': 'onSingleSoiClick',
            'click .js-soi-rev': 'onRevSoiClick',
            'click .js-soi-third': 'onThirdSoiClick',
            'click .js-view-home-loans-top': 'onHomeLoansTopClick',
            'click [data-hook="save-auction"]': 'saveAction',
            'click [data-hook="save-inspection"]': 'saveInspection'
        },

        initSubViews: function initSubViews() {
            var photos = this.model.get('Photos');
            if (photos) {
                this.listingGalleryView = new Rev.Views.ListingGalleryView({ el: '.listing-gallery.photos-wrapper', model: this.model });
            }
        },
        onSingleSoiClick: function onSingleSoiClick(e) {
            Rev.Utils.GaTracking.trackGaEvent(this.model.get('GaEventCategory'), Rev.Utils.GaTracking.Action.SoiClick, Rev.Utils.GaTracking.Label.Property + this.model.get('Id'));

            Rev.Utils.GaTracking.trackSoi(this.model);

            Rev.Utils.MatomoTracking.sendEvent(this.model, Rev.Utils.MatomoTracking.Category.ListingLeads, Rev.Utils.MatomoTracking.Action.StatementOfInformation);
        },
        onThirdSoiClick: function onThirdSoiClick(e) {
            Rev.Utils.GaTracking.trackGaEvent(this.model.get('GaEventCategory'), Rev.Utils.GaTracking.Action.SoiClickThirdParty, Rev.Utils.GaTracking.Label.Property + this.model.get('Id'));

            Rev.Utils.GaTracking.trackSoi(this.model);

            Rev.Utils.MatomoTracking.sendEvent(this.model, Rev.Utils.MatomoTracking.Category.ListingLeads, Rev.Utils.MatomoTracking.Action.StatementOfInformation);
        },
        isTouchDevice: function isTouchDevice() {
            return 'ontouchstart' in window // works on most browsers 
            || navigator.maxTouchPoints; // works on IE10/11 and Surface
        },
        onSoiMultipleMouseenter: function onSoiMultipleMouseenter(e) {
            console.log('mouse enter');

            if (!Modernizr.touch) {
                this.$('li.soi-multiple').addClass('open');
            }
        },
        onSoiMultipleMouseleave: function onSoiMultipleMouseleave(e) {
            console.log('mouse leave');

            if (!Modernizr.touch) {
                this.$('li.soi-multiple').removeClass('open');
            }
        },
        onSoiClick: function onSoiClick(e) {
            //e.preventDefault();

            //if (this.model.get('TotalStatementOfInformation') === 2 && this.model.get('ThreeCompBrochureUrl') && this.model.get('StatementOfInformationUrl')) {
            //  window.open(this.model.get('ThreeCompBrochureUrl'), '_blank');
            //  window.open(this.model.get('StatementOfInformationUrl'), '_blank');
            //}
        },
        onYoutubeVideoClick: function onYoutubeVideoClick(e) {
            e.preventDefault();
            e.stopPropagation();

            if (!this.model.get('YoutubeIFrameUrl')) return;

            Rev.Utils.showYoutubeModal(this.model.get('YoutubeIFrameUrl'));

            Rev.Utils.GaTracking.trackGaEvent(this.model.get('GaEventCategory'), Rev.Utils.GaTracking.Action.ViewVideo, '' + Rev.Utils.GaTracking.Label.Property + this.model.get('Id'));

            Rev.Utils.MatomoTracking.sendEvent(this.model, Rev.Utils.MatomoTracking.Category.ListingLeads, Rev.Utils.MatomoTracking.Action.Video);
        },
        onVirtualTourClick: function onVirtualTourClick(e) {
            e.preventDefault();
            e.stopPropagation();

            if (!this.model.get('VirtualTourUrl')) return;

            var url = this.model.get('VirtualTourUrl');
            if (url && url.indexOf('http') < 0) {
                url = 'http://' + url;
            }

            Rev.Utils.MatomoTracking.sendEvent(this.model, Rev.Utils.MatomoTracking.Category.ListingLeads, Rev.Utils.MatomoTracking.Action.VirtualTour);

            window.open(url);
        },
        initListeners: function initListeners() {
            this.listenTo(Rev, 'photo:modal:shown', this.hideView);
            this.listenTo(Rev, 'photo:modal:hidden', this.reinitializeView);
        },
        onPhotoClick: function onPhotoClick(e) {
            e.preventDefault();

            if (!this.model.get('Photos') || this.model.get('Photos') && !this.model.get('Photos').length) {
                return;
            }

            Rev.Utils.showPhotoGalleryModal(this.model.get('AddressText'), this.model.get('Photos'), this.model.get('PhotosSmall'), null, null, null, null, this.model.get('ListingCategory'), this.model.get('DisplayAd'), this.model.get('Id'), this.model.get('GaEventCategory'), this.model.get('AgencyName'), this.model.get('AgencyEmail'), this.model.get('AgencyId'));

            Rev.Utils.GaTracking.trackGaEvent(this.model.get('GaEventCategory'), Rev.Utils.GaTracking.Action.ViewImageGallery, '' + Rev.Utils.GaTracking.Label.Property + this.model.get('Id'));

            Rev.Utils.MatomoTracking.sendEvent(this.model, Rev.Utils.MatomoTracking.Category.ListingLeads, Rev.Utils.MatomoTracking.Action.PhotoGallery);
        },
        onFloorplanClick: function onFloorplanClick(e) {
            e.preventDefault();

            if (!this.model.get('FloorplanPhotos') || this.model.get('FloorplanPhotos') && !this.model.get('FloorplanPhotos').length) {
                return;
            }

            Rev.Utils.showPhotoGalleryModal(this.model.get('AddressText'), null, null, this.model.get('FloorplanPhotos'), this.model.get('FloorplanPhotos'), null, null, this.model.get('ListingCategory'), this.model.get('DisplayAd'), this.model.get('Id'), this.model.get('GaEventCategory'), this.model.get('AgencyName'), this.model.get('AgencyEmail'), this.model.get('AgencyId'));

            Rev.Utils.GaTracking.trackGaEvent(this.model.get('GaEventCategory'), Rev.Utils.GaTracking.Action.ViewFloorplans, '' + Rev.Utils.GaTracking.Label.Property + this.model.get('Id'));

            Rev.Utils.MatomoTracking.sendEvent(this.model, Rev.Utils.MatomoTracking.Category.ListingLeads, Rev.Utils.MatomoTracking.Action.FloorPlan);
        },
        onPrintClick: function onPrintClick(e) {
            e.preventDefault();
            e.stopPropagation();
            var url = this.model.get('BrochureUrl');
            window.open(url, '_blank');

            Rev.Utils.GaTracking.trackGaEvent(this.model.get('GaEventCategory'), Rev.Utils.GaTracking.Action.PrintBrochure, Rev.Utils.GaTracking.Label.Property + this.model.get('Id'));

            Rev.Utils.MatomoTracking.sendEvent(this.model, Rev.Utils.MatomoTracking.Category.ListingLeads, Rev.Utils.MatomoTracking.Action.PrintBrochure);
        },
        onShareClick: function onShareClick(e) {
            this.$('[data-hook="lightbox-share"]').toggleClass('show');
        },
        onShareFBClick: function onShareFBClick(e) {
            FB.ui({
                method: 'share',
                href: window.location.href
            }, function (response) {});

            // fire ga event
            Rev.Utils.GaTracking.trackGaEvent(this.model.get('GaEventCategory'), Rev.Utils.GaTracking.Action.ShareViaFacebook, Rev.Utils.GaTracking.Label.ShareFacebook + this.model.get('Id'));

            Rev.Utils.MatomoTracking.sendEvent(this.model, Rev.Utils.MatomoTracking.Category.ListingLeads, Rev.Utils.MatomoTracking.Action.Share, Rev.Utils.MatomoTracking.Name.Facebook);
        },
        onShareTwitterClick: function onShareTwitterClick(e) {
            var contractType = '';
            if (this.model.get('ContractType') == 0) {
                contractType = 'Sale';
            } else {
                contractType = 'Rent';
            }

            var preSelectedText = this.model.get('AddressText') + ' - ' + this.model.get('PropertyTypes') + ' For ' + contractType + ' by ' + this.model.get('AgencyName');
            var tweetUrl = 'https://twitter.com/intent/tweet?text=' + encodeURIComponent(preSelectedText) + '&url=' + encodeURIComponent(window.location.href);

            Rev.Utils.PopupWindow(tweetUrl);

            // fire ga event
            Rev.Utils.GaTracking.trackGaEvent(this.model.get('GaEventCategory'), Rev.Utils.GaTracking.Action.ShareViaTwitter, Rev.Utils.GaTracking.Label.ShareTwitter + this.model.get('Id'));

            Rev.Utils.MatomoTracking.sendEvent(this.model, Rev.Utils.MatomoTracking.Category.ListingLeads, Rev.Utils.MatomoTracking.Action.Share, Rev.Utils.MatomoTracking.Name.Twitter);
        },
        onShareFriendClick: function onShareFriendClick(e) {
            if (this.model.get('GaEventCategory')) {
                Rev.Utils.GaTracking.trackGaEvent(this.model.get('GaEventCategory'), Rev.Utils.GaTracking.Action.SendToFriend, Rev.Utils.GaTracking.Label.SendEmailToFriend);
            }

            Rev.Utils.MatomoTracking.sendEvent(this.model, Rev.Utils.MatomoTracking.Category.ListingLeads, Rev.Utils.MatomoTracking.Action.Share, Rev.Utils.MatomoTracking.Name.Email);
        },
        onCloseShareLightbox: function onCloseShareLightbox(e) {
            e.preventDefault();
            e.stopPropagation();
            this.$('[data-hook="lightbox-share"]').removeClass('show');
        },
        saveInspection: function saveInspection(e) {
            var index = parseInt($(e.currentTarget).attr('data-inspection-number'));
            Rev.Utils.icsFile.icsFileDownloading(this.model, index);

            Rev.Utils.MatomoTracking.sendEvent(this.model, Rev.Utils.MatomoTracking.Category.ListingLeads, Rev.Utils.MatomoTracking.Action.InspectionTimeSave);
        },
        saveAction: function saveAction(e) {
            Rev.Utils.icsFile.icsFileDownloading(this.model);

            Rev.Utils.MatomoTracking.sendEvent(this.model, Rev.Utils.MatomoTracking.Category.ListingLeads, Rev.Utils.MatomoTracking.Action.AuctionTimeSave);
        },
        remove: function remove() {
            this.off();
            this.stopListening();

            //call the superclass remove method
            Backbone.View.prototype.remove.apply(this, arguments);
        },
        onHomeLoansTopClick: function onHomeLoansTopClick(e) {
            Rev.Utils.GaTracking.trackGaEvent(this.model.get('GaEventCategory'), Rev.Utils.GaTracking.Action.ViewHomeLoanTopClick, Rev.Utils.GaTracking.Label.Property + this.model.get('Id'));
        }
    });
})(Rev, jQuery, _, Backbone);
'use strict';

// dependencies : Rev, jquery, underscore, backbone, slick.js

(function (Rev, $, _, Backbone) {

	'use strict';

	Rev.Views.MapView = Backbone.View.extend({

		initialize: function initialize(options) {
			this.options = options || {};
		},

		events: {
			'click [data-hook="open-map-modal"]': 'onOpenMapClick'
		},

		onOpenMapClick: function onOpenMapClick() {
			Rev.Utils.showMapModal(this.model.get('GeoCoordinates').Latitude, this.model.get('GeoCoordinates').Longitude, this.model.get('GaEventCategory'));

			Rev.Utils.MatomoTracking.sendEvent(this.model, Rev.Utils.MatomoTracking.Category.ListingLeads, Rev.Utils.MatomoTracking.Action.Map);
		}
	});
})(Rev, jQuery, _, Backbone);
'use strict';

// dependencies : Rev, jquery, underscore, backbone

(function (Rev, $, _, Backbone) {

    'use strict';

    Rev.Views.ModalPhotoGalleryView = Backbone.View.extend({
        initialize: function initialize(options) {
            this.options = options || {};

            _.bindAll(this, 'afterSlick', 'initSlick', 'openView', 'closeView', 'onKeydown', 'onOrientationChange');

            this.slidesToShow = 8;

            this.listenTo(Rev, 'full-photo-viewer:open', this.openViewAtPhotos);
            this.listenTo(Rev, 'full-photo-viewer:openFloorplan', this.openViewAtFloorplans);

            $(document).on('keydown', this.onKeydown);

            this.onOrientationChange();
        },


        events: {
            'click .nav-left': 'onNavLeftClick',
            'click .nav-right': 'onNavRightClick',
            'click .btn-close': 'onBtnCloseClick',
            'click .photos .photo.slick-slide.slick-current.slick-active': 'onPhotoClick',
            'click [data-hook="contact-agency-email"] ': 'openEmailAgentModal',
            'click .photos .photo.only-one-photo': 'onPhotoClick'
        },

        openEmailAgentModal: function openEmailAgentModal(e) {
            e.preventDefault();

            Rev.Utils.GaTracking.trackGaEvent(this.model.get('GaEventCategory'), Rev.Utils.GaTracking.Action.EmailAgent, this.model.get('AgencyName') + ' / ' + this.model.get('AgencyId'));

            Rev.Utils.showEmailAgentModal(this.model.get('ListingId'), this.model.get('GaEventCategory'), this.model.get('AgencyName'), this.model.get('AgencyEmail'), null, this.model.get('AgencyId'));
        },
        onOrientationChange: function onOrientationChange() {
            var self = this;
            this.mql = this.mql || window.matchMedia("(orientation: portrait)");
            this.mql.addListener(function (m) {

                self.$('.photos').css({ 'opacity': 0 });

                var current = self.slickInstance.slick('slickCurrentSlide');

                setTimeout(function () {
                    if (self.slickInstance) {
                        self.slickInstance.off('afterChange', self.afterSlick);
                        self.slickInstance.slick('unslick');
                    }

                    if (self.slickInstanceThumbs) {
                        self.slickInstanceThumbs.slick('unslick');
                    }

                    self.$('[data-hook="photo-index"]').text(current + 1);

                    setTimeout(function () {
                        self.initSlick(self.photos);

                        setTimeout(function () {
                            self.$('.photos').css({ 'opacity': 1 });
                            self.slickInstance.slick('slickGoTo', current, true);
                        }, 100);
                    }, 100);
                }, 100);
            });
        },
        onKeydown: function onKeydown(e) {
            if (e.keyCode == 37) {
                //left
                if (this.slickInstance) this.slickInstance.slick('slickPrev');
            } else if (e.keyCode == 39) {
                // right
                if (this.slickInstance) this.slickInstance.slick('slickNext');
            } else if (e.keyCode == 27 || e.keyCode == 38 || e.keyCode == 40) {
                // esc, up or down
                this.closeView();
            }
        },
        onNavLeftClick: function onNavLeftClick(e) {
            e.preventDefault();
            e.stopPropagation();
            this.$(e.currentTarget).removeClass('hover-effect');
            if (this.slickInstance) {
                this.slickInstance.slick('slickPrev');
            }
        },
        onNavRightClick: function onNavRightClick(e) {
            e.preventDefault();
            e.stopPropagation();
            this.$(e.currentTarget).removeClass('hover-effect');
            if (this.slickInstance) {
                this.slickInstance.slick('slickNext');
            }
        },
        afterSlick: function afterSlick(event, slick, currentSlide) {
            var _this = this;

            currentSlide = currentSlide ? currentSlide + 1 : 1;
            this.$('[data-hook="photo-index"]').text(currentSlide);

            // this is workaround slick.js's bug which it does not change slick-current css class properly
            setTimeout(function () {
                if (_this.totalPhotos <= _this.slidesToShow) {
                    var dataSlickIndex = _this.$('.photos:visible .slick-current.slick-active').attr('data-slick-index');
                    _this.$('.thumbs:visible .thumb.slick-slide').removeClass('slick-current');
                    _this.$('.thumbs:visible .thumb.slick-slide[data-slick-index=' + dataSlickIndex + ']').addClass('slick-current');
                }
            }, 10);

            if (this.model.get('GaNavigationTracking')) {
                var gaNavigationTracking = this.model.get('GaNavigationTracking');

                Rev.Utils.GaTracking.trackGaEvent(gaNavigationTracking.GaEventCategory, gaNavigationTracking.GaEventAction, gaNavigationTracking.GaEventLabel);
            }

            if (this.model.get('ListingId')) {
                Rev.Utils.LeadTracking.sendPhotoEvent(this.model.get('ListingId'));

                if (this.model.get('Photos')) Rev.Views.listDetailsView.sendPhotoGalleryMatomoEvent();else if (this.model.get('Floorplans')) Rev.Views.listDetailsView.sendFloorplanGalleryMatomoEvent();
            }
        },
        onPhotoClick: function onPhotoClick(e) {
            this.closeView();
        },
        openView: function openView(imageList) {
            var _this2 = this;

            $('body').addClass('modal-open');
            //$('.full-photo-viewer').fadeIn();
            this.$el.fadeIn();
            if (this.slickInstance) {
                this.slickInstance.off('afterChange', this.afterSlick);
                this.slickInstance.slick('unslick');
            }
            if (this.slickInstanceThumbs) {
                this.slickInstanceThumbs.slick('unslick');
            }
            this.$('[data-hook="photo-index"]').text('1');

            setTimeout(function () {
                _this2.totalPhotos = imageList.length + 1;
                _this2.photos = imageList;
                _this2.initSlick(imageList);
            }, 100);
        },
        openViewAtPhotos: function openViewAtPhotos() {
            this.$('#photos').removeClass('hide');
            this.$('#thumbs').removeClass('hide');
            this.$('#floorplans').addClass('hide');
            this.$('#floorplanthumbs').addClass('hide');
            this.$('[data-hook="photo-length"]').text(this.model.get('Photos').length + (this.model.get('ListingCategory') !== 1 ? 1 : 0));
            this.openView(this.model.get('Photos'));
        },
        openViewAtFloorplans: function openViewAtFloorplans() {
            this.$('#floorplans').removeClass('hide');
            this.$('#floorplanthumbs').removeClass('hide');
            this.$('#photos').addClass('hide');
            this.$('#thumbs').addClass('hide');
            this.$('[data-hook="photo-length"]').text(this.model.get('Floorplans').length);
            this.openView(this.model.get('Floorplans'));
        },
        closeView: function closeView() {
            if (this.mql) {
                this.mql.removeListener(this.onOrientationChange);
            }

            if (this.model.get('GaCloseTracking')) {
                var gaCloseTracking = this.model.get('GaCloseTracking');

                Rev.Utils.GaTracking.trackGaEvent(gaCloseTracking.GaEventCategory, gaCloseTracking.GaEventAction, gaCloseTracking.GaEventLabel);
            }

            $('body').removeClass('modal-open');
            this.$el.fadeOut();
        },
        initSlick: function initSlick(imageList) {

            this.slickInstance = Rev.Utils.initSlick(this.$('.photos:visible'), {
                lazyLoad: 'ondemand',
                fade: true,
                asNavFor: '.full-photo-viewer .thumbs:visible',
                slidesToShow: 1,
                slidesToScroll: 1,
                centerPadding: '50px'
            });
            this.slickInstance.on('afterChange', this.afterSlick);

            this.slickInstanceThumbs = Rev.Utils.initSlick(this.$('.thumbs:visible'), {
                lazyLoad: 'ondemand',
                centerPadding: '20px',
                asNavFor: '.full-photo-viewer .photos:visible',
                slidesToShow: this.slidesToShow,
                slidesToScroll: 1,
                centerMode: this.totalPhotos <= this.slidesToShow ? false : true,
                focusOnSelect: true
            });
        },
        onBtnCloseClick: function onBtnCloseClick(e) {
            e && e.preventDefault && e.preventDefault();
            this.closeView();
        }
    });
})(Rev, jQuery, _, Backbone);
'use strict';

// dependencies : Rev, jquery, underscore, backbone

(function (Rev, $, _, Backbone) {

  'use strict';

  Rev.Views.MortgageCalculatorView = Backbone.View.extend({
    initialize: function initialize(options) {
      _.bindAll(this, 'calculateMonthlyPayment', 'toNumber', 'numberWithCommas', 'calcValueChange', 'checkMinimumValues');
      this.options = options || {};
      this.checkMinimumValues();
      this.calcValueChange();
    },


    events: {
      'keyup #LoanAmount': 'onCalcKeyUp',
      'change #LoanAmount': 'onCalcChange',
      'keyup #InterestRate': 'onCalcKeyUp',
      'change #InterestRate': 'onCalcChange',
      'change #MortgageTerm': 'onCalcChange',
      'click .js-get-quote': 'onGetQuoteButtonClick'
    },

    onGetQuoteButtonClick: function onGetQuoteButtonClick(e) {
      Rev.Utils.GaTracking.trackGaEvent(Rev.Utils.GaTracking.Category.Property360Address, Rev.Utils.GaTracking.Action.GetHomeLoanQuote, 'SA1-' + this.model.get('Sa1TruncatedId') + '-' + this.model.get('SeoSlug'));
    },
    onCalcKeyUp: function onCalcKeyUp() {
      this.calcValueChange();
    },
    onCalcChange: function onCalcChange() {
      this.checkMinimumValues();
      this.calcValueChange();
    },
    calculateMonthlyPayment: function calculateMonthlyPayment(principle, yearlyRate, months) {
      var monthlyInterest = yearlyRate / 12 / 100;
      var result = principle * monthlyInterest / (1 - Math.pow(1 / (1 + monthlyInterest), months));
      return result;
    },
    toNumber: function toNumber(value) {
      return Number(value.split("-")[0].replace(/[^\d.-]/g, ''));
    },
    numberWithCommas: function numberWithCommas(x) {
      return x.toFixed(0).replace(/\B(?=(\d{3})+(?!\d))/g, ",");
    },
    calcValueChange: function calcValueChange() {
      var loanAmount = this.toNumber(this.$('#LoanAmount').val());
      var interestRate = this.toNumber(this.$('#InterestRate').val());
      var mortgageTerm = Number(this.$('#MortgageTerm').val());
      var monthlyPayment = this.calculateMonthlyPayment(loanAmount, interestRate, mortgageTerm);
      this.$('#MonthlyPayment').text(this.numberWithCommas(monthlyPayment));
    },
    checkMinimumValues: function checkMinimumValues() {
      //if (!$.isNumeric(this.$('#LoanAmount').val())) {
      //  this.$('#LoanAmount').val(500000);
      //} 

      var loanAmount = this.toNumber(this.$('#LoanAmount').val());
      if (isNaN(loanAmount) || loanAmount < 15000) {
        loanAmount = 15000;
      }
      this.$('#LoanAmount').val(this.numberWithCommas(loanAmount));

      if (this.toNumber(this.$('#InterestRate').val()) < 1) {
        this.$('#InterestRate').val("1.0");
      }
    },
    remove: function remove() {
      this.off();
      this.stopListening();

      //call the superclass remove method
      Backbone.View.prototype.remove.apply(this, arguments);
    }
  });
})(Rev, jQuery, _, Backbone);
'use strict';

// dependencies : Rev, jquery, underscore, backbone, slick.js

(function (Rev, $, _, Backbone) {

    'use strict';

    Rev.Views.OtherAgencyPropertiesView = Backbone.View.extend({
        initialize: function initialize(options) {
            this.options = options || {};
            this.id = options.id;
            this.totalProperties = options.totalProperties;
            this.gaCategory = options.gaCategory;
            this.gaLabel = options.gaLabel;
        },


        events: {
            'touchstart .properties': 'onTouchstart',
            'mousedown .properties': 'onMousedown',
            'click .nav-left': 'onNavLeftClick',
            'click .nav-right': 'onNavRightClick',
            'click [data-hook="more-agency-properties"]': 'onMoreAgencyPropertiesClick',
            'click [data-hook="view-agency"]': 'onViewAgencyClick'
            //'click [data-hook="btn-eaia-page"]' : 'onBtnEaiaPageClick'
        },

        onMoreAgencyPropertiesClick: function onMoreAgencyPropertiesClick(e) {
            this.$('.properties').addClass("show-all-listings");
            this.$(e.currentTarget).hide();
        },
        onViewAgencyClick: function onViewAgencyClick(e) {
            Rev.Utils.MatomoTracking.sendEvent(this.model, Rev.Utils.MatomoTracking.Category.ListingLeads, Rev.Utils.MatomoTracking.Action.AgencyProfile);
        },
        initSlick: function initSlick() {
            var totalProperties = this.totalProperties;

            // put center properties in center position in slides :)
            var startSlide = totalProperties ? Math.round(totalProperties / 2) : 0;
            if (startSlide >= totalProperties) startSlide = 0;

            this.slickInstance = Rev.Utils.initSlick(this.$('.properties'), {
                infinite: true,
                lazyLoad: null,
                slidesToScroll: 1,
                slidesToShow: totalProperties === 3 ? 3 : totalProperties === 1 ? 3 : 4,
                initialSlide: totalProperties === 4 ? 0 : totalProperties === 3 ? 0 : totalProperties <= 2 ? -1 : startSlide,
                centerMode: totalProperties <= 4 ? false : true,
                centerPadding: '120px',
                arrows: true,
                responsive: [
                //{
                //    breakpoint: 1600,
                //    settings: {
                //        slidesToShow: 3,
                //        initialSlide: totalProperties <= 4 ? 0 : startSlide,
                //        centerMode: totalProperties <= 4 ? false : true,
                //        centerPadding: '100px',
                //    }
                //},
                {
                    breakpoint: 1500,
                    settings: {
                        slidesToShow: totalProperties === 2 ? 2 : 3,
                        initialSlide: totalProperties === 1 ? -1 : totalProperties <= 3 ? 0 : startSlide,
                        centerMode: totalProperties <= 3 ? false : true,
                        centerPadding: '100px'
                    }
                }, {
                    breakpoint: 1100,
                    settings: {
                        slidesToShow: totalProperties === 1 ? 1 : 2,
                        initialSlide: totalProperties <= 2 ? 0 : startSlide,
                        centerMode: totalProperties <= 2 ? false : true,
                        centerPadding: '80px'
                    }
                }, {
                    breakpoint: 768,
                    settings: {
                        slidesToShow: 1,
                        initialSlide: 0,
                        centerMode: totalProperties <= 1 ? false : true,
                        centerPadding: '15px'
                    }
                }]
            });
            this.slickInstance.on('afterChange', this.afterSlick);
        },
        onBtnEaiaPageClick: function onBtnEaiaPageClick(e) {
            Rev.Utils.GaTracking.trackGaEvent(this.gaCategory, Rev.Utils.GaTracking.Action.ClickIntoNeighbouringProperty360Address, this.gaLabel);
        },
        onNavLeftClick: function onNavLeftClick(e) {
            e.preventDefault();
            e.stopPropagation();
            this.$(e.currentTarget).removeClass('hover-effect');
            if (this.slickInstance) {
                this.slickInstance.slick('slickPrev');
            }
        },
        onNavRightClick: function onNavRightClick(e) {
            e.preventDefault();
            e.stopPropagation();
            this.$(e.currentTarget).removeClass('hover-effect');
            if (this.slickInstance) {
                this.slickInstance.slick('slickNext');
            }
        },
        onTouchstart: function onTouchstart(e) {
            console.log('touch start');
            this.$('.properties').removeClass('cloudy');
        },
        onMousedown: function onMousedown(e) {
            console.log('touch start');
            this.$('.properties').removeClass('cloudy');
        },
        afterSlick: function afterSlick(event, slick, currentSlide) {
            this.$('.properties').addClass('cloudy');
            this.$('.nav-left, .nav-right').addClass('hover-effect');
        },
        remove: function remove() {
            this.off();
            this.stopListening();

            //call the superclass remove method
            Backbone.View.prototype.remove.apply(this, arguments);
        }
    });
})(Rev, jQuery, _, Backbone);
'use strict';

// dependencies : Rev, jquery, underscore, backbone

(function (Rev, $, _, Backbone) {

  'use strict';

  Rev.Views.PointOfInterestSettingsView = Backbone.View.extend({
    el: '.poi-settings-window',

    initialize: function initialize(options) {
      this.options = options || {};
      _.bindAll(this, 'displayCheckedTypes');
      this.listenTo(Rev, 'poi-settings-view:open', this.open);
    },


    events: {
      'click .save-and-return-to-map': 'onSaveAndReturnToMapClick'
    },

    render: function render() {
      var template = _.template($('#template-poi-settings').html());
      this.$el.html(template());
      return this;
    },
    open: function open() {
      var _this = this;

      this.displayCheckedTypes();
      setTimeout(function () {
        return _this.$el.show();
      }, 100);

      if (Rev.IsPhone) {
        $('body').css('overflow-y', 'hidden');
        Rev.trigger('floating-link:hide');
      } else {
        Rev.trigger('agents:photo:hide');
      }
    },
    displayCheckedTypes: function displayCheckedTypes() {
      var _this2 = this;

      Rev.Models.localData.fetch();
      var types = Rev.Models.localData.getPoiTypes();
      this.$('[name="poiType"]').prop('checked', false);
      _.each(types, function (type) {
        return _this2.$('[name="poiType"][value="' + type + '"]').prop('checked', true);
      });
    },
    onSaveAndReturnToMapClick: function onSaveAndReturnToMapClick(e) {
      $('body').css('overflow-y', 'auto');

      var checkedTypes = [];
      this.$('[name="poiType"]:checked').each(function (index, element) {
        return checkedTypes.push($(element).val());
      });
      Rev.Models.localData.savePoiTypes(checkedTypes);
      this.$el.hide();
      Rev.trigger('agents:photo:show');
      Rev.trigger('poi:show-if-enabled');
      Rev.trigger('floating-link:show');

      // ga event
      var gaLabels = [];
      this.$('input[name="poiType"]:checked').each(function (index, element) {
        return gaLabels.push($(element).attr('data-ga-event-label'));
      });
      var gaLabelsString = gaLabels.join(" / ");

      if (gaLabels.length) {
        Rev.Utils.GaTracking.trackGaEvent(this.options.gaCategory, Rev.Utils.GaTracking.Action.PointsOfInterestSave, gaLabelsString);
      }
    }
  });
})(Rev, jQuery, _, Backbone);
'use strict';

(function (Rev, $, _, Backbone) {

  'use strict';

  Rev.Views.ResetPasswordView = Backbone.View.extend({
    el: '.reset-password-page',

    initialize: function initialize() {},

    events: {
      'click [data-hook="submit-reset-password-form"]': 'submitResetPassword',
      'click [data-hook="fire-login"]': 'openLogin'
    },

    openLogin: function openLogin(e) {
      e.preventDefault();

      if (Rev.IsPhone) {
        Rev.trigger('sidebar:toggle');
        Rev.trigger('login:toggle');
      } else {
        Rev.Utils.showAuthModal('login');
      }
    },

    submitResetPassword: function submitResetPassword(e) {
      e.preventDefault();

      var self = this;
      var url = this.$('form#reset-password-form').attr('action');

      $(e.currentTarget).button('loading');

      $.post(url, this.$('form#reset-password-form').serialize()).done(function (result) {
        if (!result.errors) {
          self.showSuccess();
        } else {
          Rev.Utils.showErrors(result.errors, self.$('[data-hook="reset-password-validation-errors-placeholder"]'));
        }
      }).fail(function (result) {
        Rev.Utils.showErrors(result.errors, self.$('[data-hook="reset-password-validation-errors-placeholder"]'));
      }).always(function () {
        self.$('[data-hook="submit-reset-password-form"]').button('reset');
      });
    },

    showSuccess: function showSuccess() {
      $('[data-hook="reset-password-form-wrapper"]').hide();
      $('[data-hook="reset-password-form-success"]').addClass('show');
    }

  });
})(Rev, jQuery, _, Backbone);
'use strict';

// dependencies : Rev, jquery, underscore, Backbone

(function (Rev, $, _, Backbone) {

  'use strict';

  Rev.Views.SaveSearchConfirmModalView = Backbone.View.extend({
    initialize: function initialize() {
      _.bindAll(this, 'closeView');
    },


    events: {
      'click [data-hook="btn-save-search"]': 'onClickSaveSearch',
      'click [data-hook="close"]': 'closeView',
      'mousedown .modal-content': 'onMousedown'
    },

    onMousedown: function onMousedown(e) {
      e.preventDefault();
      e.stopPropagation();
    },
    onClickSaveSearch: function onClickSaveSearch(e) {
      var _this = this;

      $(e.currentTarget).button('loading');
      var $form;
      if (Rev.IsPhone) {
        $form = $('.search-form.refine-search form.search-filters-form');
      } else {
        $form = $('.result-page .refine-search form');
      }

      $form.find('[data-hook="hidden-viewalert-frequency"]').val('Daily');

      Rev.Utils.saveSearch($form, function () {
        $('[data-hook="btn-save-search"]').button('reset');
        _this.closeView();
      });
    },
    closeView: function closeView(e) {
      if (e && e.preventDefault) e.preventDefault();

      $('.rev-modal-backdrop').hide();
      this.$el.modal('hide');
    }
  });
})(Rev, jQuery, _, Backbone);
'use strict';

// dependencies : Rev, jquery, underscore, Backbone

(function (Rev, $, _, Backbone) {

  'use strict';

  Rev.Views.SavedSearchesItemView = Backbone.View.extend({
    initialize: function initialize() {
      _.bindAll(this, 'updateFrequencyOptionButton', 'persistEmailFrequency', 'deleteSearch');
      this.$('[data-toggle="tooltip"]').tooltip();
    },


    events: {
      'click [data-hook="saved-search-delete"]': 'onDeleteClick',
      'click [data-hook="saved-search-edit"]': 'onEditClick',
      'click [data-hook="dropdown-selected-value"] input[type=radio]': 'onEmailFrequencyClick', // this event is only fired from desktop web site
      'click [data-hook="btn-frequency"]': 'onFrequencyClick' // this event is only fired from mobile web site
    },

    updateFrequencyOptionButton: function updateFrequencyOptionButton() {
      this.$('[data-hook="btn-frequency"]').removeClass('selected');

      var val = this.$('input[data-hook="hidden-viewalert-frequency"]').val();
      if (val) {
        if (val === '2' || val === 2 || val.toLowerCase() === 'weekly') {
          this.$('[data-hook-value="weekly"]').addClass('selected');
        } else {
          this.$('[data-hook-value="daily"]').addClass('selected');
        }
      }
    },


    // event handler only for MOBILE web site
    onFrequencyClick: function onFrequencyClick(e) {
      if (e && e.preventDefault) e.preventDefault();

      var val = this.$(e.currentTarget).hasClass('selected') ? '' : this.$(e.currentTarget).attr('data-hook-value');
      this.$('input[data-hook="hidden-viewalert-frequency"]').val(val);

      this.updateFrequencyOptionButton();

      var text = val ? this.$('[data-hook="btn-frequency"].selected').attr('data-hook-description') : 'not selected';

      this.persistEmailFrequency(val, text).fail(function (result) {
        return Rev.Utils.showErrorMessage('Search not saved');
      });
    },


    // event handler only for DESKTOP web site
    onEmailFrequencyClick: function onEmailFrequencyClick(e) {
      var _this = this;

      if (e && e.preventDefault) e.preventDefault();

      var self = this;
      var val = $(e.currentTarget).val();
      var text = $(e.currentTarget).siblings('span').text();

      this.$('[data-hook="selected-rooms-text"] span').text(text);

      this.persistEmailFrequency(val, text).done(function () {
        // change style of the combobox
        if (val.toLowerCase() === 'donotsend') {
          _this.$('[data-hook="range-frequency"]').addClass('not-selected');
        } else {
          _this.$('[data-hook="range-frequency"]').removeClass('not-selected');
        }
      }).fail(function (result) {
        return Rev.Utils.showErrorMessage('Search not saved');
      }).always(function () {
        return self.$(e.currentTarget).closest('.range-rooms.open').removeClass('open');
      });
    },
    persistEmailFrequency: function persistEmailFrequency(frequencyVal, frequencyText) {
      var _this2 = this;

      var dfd = $.Deferred();

      $.post('/saved-searches/edit-frequency/', { viewAlertId: this.model.get('Id'), frequency: frequencyVal }).done(function (result) {
        if (result.status == 200) {

          // update this model
          _this2.model.set('FrequencyVal', frequencyVal);

          // show message on the top of the page
          Rev.Utils.showSuccessMessage('Search saved');

          dfd.resolve();
        } else {
          Rev.Utils.showErrorMessage('Search not saved');
          dfd.reject();
        }
      });

      Rev.Utils.GaTracking.trackGaEvent(Rev.Utils.GaTracking.Category.SavedSearches, Rev.Utils.GaTracking.Action.EmailFrequency, frequencyText);

      return dfd.promise();
    },
    onEditClick: function onEditClick(e) {
      if (e && e.preventDefault) e.preventDefault();

      if (Rev.IsPhone) {
        Rev.trigger('refine:toggle');
      } else {
        this.$('[data-toggle="tooltip"]').tooltip('hide');
        $('#layout-body').removeClass('no-show');
        Rev.trigger('new-search:open', { isEditingSavedSearch: true });
      }

      Rev.trigger('saved:searches:edit:before'); // just let search_form_view.js know we are going to edit save search so fire ga events properly
      Rev.trigger('saved:searches:edit', this.model);
      Rev.Utils.GaTracking.trackGaEvent(Rev.Utils.GaTracking.Category.SavedSearches, Rev.Utils.GaTracking.Action.EditSearch, null);
    },
    onDeleteClick: function onDeleteClick(e) {
      e.preventDefault();
      var self = this;

      Rev.Utils.confirm('Are you sure you want to delete this saved search?', this.deleteSearch);

      Rev.Utils.GaTracking.trackGaEvent(Rev.Utils.GaTracking.Category.SavedSearches, Rev.Utils.GaTracking.Action.DeleteSearch, null);
    },
    deleteSearch: function deleteSearch() {
      var _this3 = this;

      this.$('[data-hook="saved-search-delete"] i').addClass('rotate');

      $.post('/saved-searches/delete/', { viewAlertId: this.model.get('Id') }).done(function (result) {
        if (result.status == 200) {
          Rev.trigger('saved:searches:deleted', _this3.model);
          Rev.trigger('change:saved-searches');
          Rev.Utils.showSuccessMessage('Search deleted');
          _this3.$el.addClass('fadeout');
          setTimeout(function () {
            return _this3.remove();
          }, 1000);
        }
      }).fail(function (result) {
        Rev.Utils.showErrorMessage('Sorry, we were unable to remove the saved search.');
      }).always(function () {
        setTimeout(function () {
          return _this3.$('[data-hook="saved-search-delete"] i').removeClass('rotate');
        }, 300);
      });
    },
    remove: function remove() {
      this.off();
      this.stopListening();

      //call the superclass remove method
      Backbone.View.prototype.remove.apply(this, arguments);
    }
  });
})(Rev, jQuery, _, Backbone);
'use strict';

// dependencies : Rev, jquery, underscore, Backbone

(function (Rev, $, _, Backbone) {

  'use strict';

  Rev.Views.SavedSearchesView = Backbone.View.extend({
    el: '.saved-searches-page',

    initialize: function initialize() {
      _.bindAll(this, 'refreshItem');

      this.createItemView();

      this.listenTo(Rev, 'saved-searche:refresh', this.refreshItem);
    },
    createItemView: function createItemView() {
      this.collection.each(function (model) {
        new Rev.Views.SavedSearchesItemView({
          el: '.saved-search-item[data-id="' + model.get('Id') + '"]',
          model: model
        });
      });
    },
    refreshItem: function refreshItem(viewAlertId) {
      var _this = this;

      var self = this;

      $.getJSON('/saved-searches/item/json/' + viewAlertId + '/').done(function (result) {
        var model = result.model,
            view = result.view;

        if (_this.collection.length) {
          var itemToRemove = self.collection.find(function (item) {
            return item.get('Id') == viewAlertId;
          });
          self.collection.remove(itemToRemove);
        }

        // replace old view with new view
        self.$('.saved-search-item[data-id="' + viewAlertId + '"]').addClass('flash-1');

        setTimeout(function () {
          self.$('.saved-search-item[data-id="' + viewAlertId + '"]').replaceWith(view);

          // assign model to view
          new Rev.Views.SavedSearchesItemView({
            el: '.saved-search-item[data-id="' + viewAlertId + '"]',
            model: new Rev.Models.SavedSearchesItem(model)
          });
        }, 700);
      });
    },
    remove: function remove() {
      this.off();
      this.stopListening();

      //call the superclass remove method
      Backbone.View.prototype.remove.apply(this, arguments);
    }
  });
})(Rev, jQuery, _, Backbone);
'use strict';

// dependencies : Rev, jquery, underscore, backbone, slick.js

(function (Rev, $, _, Backbone) {

  'use strict';

  Rev.Views.SchoolsView = Backbone.View.extend({

    initialize: function initialize(options) {
      this.options = options || {};

      this.loadSchools();
    },

    events: {},

    loadSchools: function loadSchools() {

      if (this.model.get('GeoCoordinates') !== null) {
        $.getJSON('/schools/json/', { lat: this.model.get('GeoCoordinates').Latitude, lng: this.model.get('GeoCoordinates').Longitude, distance: "5" }).done(function (result) {

          $('.listing-details-schools').html(result.view);
        });
      }
    }
  });
})(Rev, jQuery, _, Backbone);
'use strict';

(function (Rev, $, _, Backbone) {

  'use strict';

  Rev.Views.SettingsView = Backbone.View.extend({
    el: '.settings-page',

    initialize: function initialize() {
      this.isSubscribingPromotions = true;
      this.errorPlaceHolder = this.$('[data-hook="settings-user-validation-errors-placeholder"]');
      this.unsubscribeErrorPlaceHolder = this.$('[data-hook="unsubscribe-validation-errors-placeholder"]');
      this.situationeErrorPlaceHolder = this.$('[data-hook="situation-validation-errors-placeholder"]');
    },


    events: {
      'click .btn-edit': 'onEditClick',
      'click [data-hook="btn-save-user"]': 'updateUserProfile',
      'click [data-hook="btn-cancel-user"]': 'onCancelClick',
      'click [data-hook="btn-reset-password"]': 'onResetPasswordClick',
      'click .btn-all-emails': 'onClickAllEmails',
      'click .btn-yes': 'onClickYes',
      'click .btn-no': 'onClickNo',
      'click #settings-user-situation-form [data-hook="radio-user-situation"]': 'onUserSituationClick',
      'click [data-hook="btn-promotion"]': 'onPromotionClick'
    },

    onPromotionClick: function onPromotionClick(e) {
      var _this = this;

      e.preventDefault();
      var self = this;
      var $form = this.$('#settings-user-promotion-form');
      var url = $form.attr('action');
      $('[data-hook="btn-promotion"]').button('loading');

      $.post(url, $form.serialize()).done(function (result) {
        if (result.errors) {
          Rev.Utils.showErrors(result.errors, _this.unsubscribeErrorPlaceHolder);
        } else {
          _this.toggleSubscribePromotionState();
          _this.showSuccessMessage();
        }
      }).fail(function (result) {
        Rev.Utils.showErrors(result.errors, _this.unsubscribeErrorPlaceHolder);
      }).always(function () {
        $('[data-hook="btn-promotion"]').button('reset');
      });
    },
    toggleSubscribePromotionState: function toggleSubscribePromotionState() {
      $('[data-hook="btn-promotion"]').button('reset');
      setTimeout(function () {
        var $wantSubscribe = $('input[type="hidden"][name = "wantSubscribe"]');

        if ($wantSubscribe.val().toLowerCase() == 'true') {
          // unsubscribing now, change to subscribe state
          $wantSubscribe.val(false);
          $('[data-hook="btn-promotion"] .toggle-subscribe-label').text('Unsubscribe me from ');
          Rev.Utils.GaTracking.trackGaEvent(Rev.Utils.GaTracking.Category.PreferenceCentre, Rev.Utils.GaTracking.Action.SubscribePromoEmails, Rev.Utils.GaTracking.Label.Subscribed);
        } else {
          // subscribing now, change to unsubscribe state
          $wantSubscribe.val(true);
          $('[data-hook="btn-promotion"] .toggle-subscribe-label').text('Subscribe me to ');
          Rev.Utils.GaTracking.trackGaEvent(Rev.Utils.GaTracking.Category.PreferenceCentre, Rev.Utils.GaTracking.Action.SubscribePromoEmails, Rev.Utils.GaTracking.Label.Unsubscribed);
        }
      }, 10);
    },
    onUserSituationClick: function onUserSituationClick(e) {
      var _this2 = this;

      var $form = this.$('#settings-user-situation-form');
      var url = $form.attr('action');

      $.post(url, $form.serialize()).done(function (result) {
        if (result.errors) {
          Rev.Utils.showErrors(result.errors, _this2.situationeErrorPlaceHolder);
        } else {
          _this2.showSuccessMessage();
        }
      }).fail(function (result) {
        Rev.Utils.showErrors(result.errors, _this2.situationeErrorPlaceHolder);
      });

      Rev.Utils.GaTracking.trackGaEvent(Rev.Utils.GaTracking.Category.PreferenceCentre, Rev.Utils.GaTracking.Action.EditStatus, $(e.currentTarget).next('span').text());
    },
    onClickYes: function onClickYes(e) {
      var _this3 = this;

      e.preventDefault();

      var self = this;
      var $form = this.$('#settings-user-all-emails-form');
      var url = $form.attr('action');
      $('.btn-yes').button('loading');

      $.post(url, $form.serialize()).done(function (result) {
        if (result.errors) {
          Rev.Utils.showErrors(result.errors, _this3.unsubscribeErrorPlaceHolder);
        } else {
          _this3.showSuccessMessage();
          _this3.$('.btn-all-emails-wrapper').addClass('hide');
        }
      }).fail(function (result) {
        Rev.Utils.showErrors(result.errors, _this3.unsubscribeErrorPlaceHolder);
      }).always(function () {
        $('.btn-yes').button('reset');
      });

      Rev.Utils.GaTracking.trackGaEvent(Rev.Utils.GaTracking.Category.PreferenceCentre, Rev.Utils.GaTracking.Action.UnsubscribeAllEmails, Rev.Utils.GaTracking.Label.Unsubscribed);
    },
    onClickNo: function onClickNo(e) {
      e.preventDefault();
      this.$('.btn-all-emails-wrapper').removeClass('are-you-sure');
    },
    onClickAllEmails: function onClickAllEmails(e) {
      e.preventDefault();
      this.$('.btn-all-emails-wrapper').addClass('are-you-sure');
    },
    onResetPasswordClick: function onResetPasswordClick(e) {
      e.preventDefault();
      var self = this;

      var $form = this.$('form#settings-user-form');
      var url = '/forgotpassword/';

      $(e.currentTarget).button('loading');

      $.post(url, $form.serialize()).done(function (result) {
        if (!result.errors) {
          self.showSuccessMessage('We have sent you an email with instructions to reset your password.');
        } else {
          Rev.Utils.showErrors(result.errors, self.errorPlaceHolder);
        }
      }).fail(function (result) {
        Rev.Utils.showErrors(result.errors, self.errorPlaceHolder);
      }).always(function () {
        $(e.currentTarget).button('reset');
      });
    },
    onCancelClick: function onCancelClick(e) {
      e.preventDefault();

      // clear error messages
      Rev.Utils.clearErrors(this.errorPlaceHolder);

      // return to display mode
      this.$('form .form-group').removeClass('editing show');
    },
    onEditClick: function onEditClick(e) {
      var _this4 = this;

      e.preventDefault();
      this.$('form .form-group').addClass('editing');
      setTimeout(function () {
        return _this4.$('form .form-group.editing').addClass('show');
      }, 1);

      Rev.Utils.GaTracking.trackGaEvent(Rev.Utils.GaTracking.Category.PreferenceCentre, Rev.Utils.GaTracking.Action.EditPersonalDetails, null);
    },
    updateUserProfile: function updateUserProfile(e) {
      var _this5 = this;

      e.preventDefault();

      var $form = this.$('#settings-user-form');
      var url = $form.attr('action');

      $(e.currentTarget).button('loading');

      $.post(url, $form.serialize()).done(function (result) {
        if (result.errors) {
          Rev.Utils.showErrors(result.errors, _this5.errorPlaceHolder);
        } else {
          _this5.showSuccessMessage();
          _this5.updateUserProfileUI(result.userProfile);
        }
      }).fail(function (result) {
        Rev.Utils.showErrors(result.errors, _this5.errorPlaceHolder);
      }).always(function () {
        $(e.currentTarget).button('reset');
      });
    },
    updateUserProfileUI: function updateUserProfileUI(userProfile) {
      this.$('[data-hook="full-name"]').text(userProfile.FullName);
      this.$('[data-hook="first-name"]').val(userProfile.FirstName);
      this.$('[data-hook="last-name"]').val(userProfile.LastName);
      this.$('[data-hook="phone-view"]').text(userProfile.Phone);
      this.$('[data-hook="phone"]').val(userProfile.Phone);
      this.$('[data-hook="full-address"]').text(userProfile.FullAddress);
      this.$('[data-hook="address"]').val(userProfile.Address);
      this.$('[data-hook="suburb"]').val(userProfile.Suburb);
      this.$('[data-hook="state"]').val(userProfile.State);
      this.$('[data-hook="postcode"]').val(userProfile.Postcode);
    },
    showSuccessMessage: function showSuccessMessage(message) {
      Rev.Utils.showSuccessMessage(message || 'Saved successfully');

      // clear error messages
      Rev.Utils.clearErrors(this.errorPlaceHolder);

      // return to display mode
      this.$('form .form-group').removeClass('editing show');
    }
  });
})(Rev, jQuery, _, Backbone);
'use strict';

(function (Rev, $, _, Backbone) {

				'use strict';

				Rev.Views.ShortlistButtonView = Backbone.View.extend({
								initialize: function initialize() {
												this.initShortlistIconStatus();
												this.initListeners();

												// detect user was trying to save search
												this.continueSaveListing();
								},


								events: {
												'click [data-hook="toggle-shortlist"]': 'onToggleShortlistClick'
								},

								initShortlistIconStatus: function initShortlistIconStatus() {
												var self = this;
												$.getJSON('/authenticated/').done(function (result) {
																if (result.isAuthenticated) {
																				self.getShortlistRemote();
																}
												}.bind(this));
								},
								initListeners: function initListeners() {
												// listen shortlist changed
												this.listenTo(Rev, 'change:shortlist', this.onShortlistChanged);
								},
								getShortlistRemote: function getShortlistRemote() {
												$.getJSON('/properties/shortlist/ids/json/').done(function (listingIds) {
																Rev.trigger('change:shortlist', listingIds);
												});
								},
								shortlistRemote: function shortlistRemote() {
												var self = this;
												$.post('/properties/shortlist/', { listingId: self.model.get('Id') }).done(function (result) {
																if (result.status == 201) {
																				// shortlisted
																				Rev.trigger('change:shortlist', result.listingIds);

																				// lead event for shortlist
																				Rev.Utils.LeadTracking.sendShortlistEvent(self.model.get('Id'));

																				Rev.Utils.GaTracking.trackGaEvent(self.model.get('GaEventCategory'), Rev.Utils.GaTracking.Action.Shortlist, Rev.Utils.GaTracking.Label.Property + self.model.get('Id'));

																				Rev.Utils.MatomoTracking.sendEvent(self.model, Rev.Utils.MatomoTracking.Category.ListingLeads, Rev.Utils.MatomoTracking.Action.SaveShortlist);
																} else if (result.status == 306) {
																				// un-shortlisted
																				Rev.trigger('change:shortlist', result.listingIds);
																} else {
																				alert('Sorry, we were unable to shortlist.');
																}
												}).fail(function (result) {
																console.error(result);
																alert('Sorry, we were unable to shortlist.');
												});
								},
								onShortlistChanged: function onShortlistChanged(listingIds) {
												this.$('[data-hook="toggle-shortlist"]').removeClass('checked');

												var self = this;

												listingIds.forEach(function (item) {
																self.$('[data-hook="toggle-shortlist"][data-id="' + item + '"]').addClass('checked');
												});
								},
								onToggleShortlistClick: function onToggleShortlistClick(e) {
												e.preventDefault();
												e.stopPropagation();
												$.getJSON('/authenticated/').done(function (result) {
																var _this = this;

																if (result.isAuthenticated) {
																				this.shortlistRemote();
																} else {

																				var authSuccessCallbackForSaveSearch = function authSuccessCallbackForSaveSearch() {
																								localStorage.setItem('saveListing', _this.model.get('Id'));
																								setTimeout(function () {
																												return location.reload(true);
																								}, 100);
																				};

																				if (Rev.IsPhone) {
																								var confirmed = confirm("Login or Join to save properties\nAccess your favourite properties from any device");
																								if (confirmed) {

																												Rev.trigger('sidebar:toggle', {
																																loginSuccessCallback: authSuccessCallbackForSaveSearch,
																																signupSuccessCallback: authSuccessCallbackForSaveSearch
																												});
																												Rev.trigger('login:toggle');
																								}
																				} else {
																								Rev.Utils.showAuthModal('signup', true, null, null, authSuccessCallbackForSaveSearch, authSuccessCallbackForSaveSearch);
																				}
																}
												}.bind(this));
								},
								continueSaveListing: function continueSaveListing() {
												var _this2 = this;

												var saveListing = localStorage.getItem('saveListing');
												if (saveListing) {
																localStorage.removeItem('saveListing');
																Rev.Utils.Auth.isUserAuthenticated().then(function () {
																				_this2.model.set("Id", saveListing);_this2.shortlistRemote();
																}).fail(function () {

																				var authSuccessCallbackForSaveSearch = function authSuccessCallbackForSaveSearch() {
																								localStorage.setItem('saveListing', self.model.get('Id'));
																								setTimeout(function () {
																												return location.reload(true);
																								}, 100);
																				};

																				Rev.Utils.showAuthModal('login', true, null, null, authSuccessCallbackForSaveSearch, authSuccessCallbackForSaveSearch);
																});
												}
								}
				});
})(Rev, jQuery, _, Backbone);
'use strict';

var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };

(function (Rev, $, _, Backbone) {

    'use strict';

    Rev.Views.StatementOfInformationView = Backbone.View.extend({
        initialize: function initialize(options) {
            this.options = _extends({}, options);
        },


        events: {
            'click .js-soi': 'onSingleSoiClick',
            'click .js-soi-rev': 'onRevSoiClick',
            'click .js-soi-third': 'onThirdSoiClick'
        },

        onSingleSoiClick: function onSingleSoiClick(e) {
            Rev.Utils.GaTracking.trackGaEvent(this.model.get('GaEventCategory'), Rev.Utils.GaTracking.Action.SoiClick, Rev.Utils.GaTracking.Label.Property + this.model.get('Id'));

            Rev.Utils.MatomoTracking.sendEvent(this.model, Rev.Utils.MatomoTracking.Category.ListingLeads, Rev.Utils.MatomoTracking.Action.StatementOfInformation);
        },
        onRevSoiClick: function onRevSoiClick(e) {
            Rev.Utils.GaTracking.trackGaEvent(this.model.get('GaEventCategory'), Rev.Utils.GaTracking.Action.SoiClickRev, Rev.Utils.GaTracking.Label.Property + this.model.get('Id'));

            Rev.Utils.MatomoTracking.sendEvent(this.model, Rev.Utils.MatomoTracking.Category.ListingLeads, Rev.Utils.MatomoTracking.Action.StatementOfInformation);
        },
        onThirdSoiClick: function onThirdSoiClick(e) {
            Rev.Utils.GaTracking.trackGaEvent(this.model.get('GaEventCategory'), Rev.Utils.GaTracking.Action.SoiClickThirdParty, Rev.Utils.GaTracking.Label.Property + this.model.get('Id'));

            Rev.Utils.MatomoTracking.sendEvent(this.model, Rev.Utils.MatomoTracking.Category.ListingLeads, Rev.Utils.MatomoTracking.Action.StatementOfInformation);
        }
    });
})(Rev, jQuery, _, Backbone);
'use strict';

// dependencies : Rev, jquery, underscore, backbone

(function (Rev, $, _, Backbone) {

  'use strict';

  Rev.Views.TooManyResultsModalView = Backbone.View.extend({
    initialize: function initialize() {
      _.bindAll(this, 'closeView');
    },

    events: {
      'click [data-hook="close"]': 'closeView',
      'hidden.bs.modal': 'onModalHidden',
      'click [data-hook="new-search"]': 'onNewSearchClick'
    },

    onNewSearchClick: function onNewSearchClick(e) {
      if (e && e.preventDefault) e.preventDefault();

      this.closeView();

      if (Rev.IsPhone) {
        Rev.trigger('refine:toggle');
      } else {
        Rev.trigger('refine-search:toggle');
      }
    },
    onModalHidden: function onModalHidden(e) {
      $('.list-result-items').removeClass('modal-open');
    },
    closeView: function closeView(e) {
      if (e && e.preventDefault) e.preventDefault();

      $('.rev-modal-backdrop').hide();
      this.$el.modal('hide');
    },
    remove: function remove() {
      this.closeView();
      this.off();
      Backbone.View.prototype.remove.apply(this, arguments); //call the superclass remove method
    }
  });
})(Rev, jQuery, _, Backbone);
'use strict';

// dependencies : Rev, jquery, underscore, Backbone

(function (Rev, $, _, Backbone) {

  'use strict';

  Rev.Views.UnsubscribeAuctionAlertView = Backbone.View.extend({
    el: '.unsubscribe-alert-page.auction-alert',

    events: {
      'click [data-hook="btn-unsubscribe-auction-alert"]': 'onDeleteAuctionAlertClick',
      'click [data-hook="btn-unsubscribe-all-auction-alerts"]': 'onDeleteAllAuctionAlertClick'
    },

    onDeleteAuctionAlertClick: function onDeleteAuctionAlertClick(e) {
      e.preventDefault();
      var self = this;
      $(e.currentTarget).button('loading');

      var $form = this.$('form#form-auction-alert-unsubscribe');
      var actionUrl = $form.attr('action');

      $.post(actionUrl, $form.serialize()).done(function (result) {
        if (result.status == 200) {
          Rev.Utils.showSuccessMessage('Auction results alert unsubscribed');
        }
      }).fail(function (result) {
        Rev.Utils.showErrorMessage('Sorry, we were unable to unsubscribe the auction results alert.');
      }).always(function () {
        self.$('[data-hook="btn-unsubscribe-auction-alert"]').button('reset');
      });

      Rev.Utils.GaTracking.trackGaEvent(Rev.Utils.GaTracking.Category.Unsubscribe, Rev.Utils.GaTracking.Action.UnsubscribeAuctionAlert);
    },
    onDeleteAllAuctionAlertClick: function onDeleteAllAuctionAlertClick(e) {
      e.preventDefault();
      var self = this;
      $(e.currentTarget).button('loading');

      var $form = this.$('form#form-all-auction-alert-unsubscribe');
      var actionUrl = $form.attr('action');

      $.post(actionUrl, $form.serialize()).done(function (result) {
        if (result.status == 200) {
          Rev.Utils.showSuccessMessage('Auction results alert unsubscribed');
        }
      }).fail(function (result) {
        Rev.Utils.showErrorMessage('Sorry, we were unable to unsubscribe the auction results alert.');
      }).always(function () {
        self.$('[data-hook="btn-unsubscribe-all-auction-alerts"]').button('reset');
      });
    }
  });
})(Rev, jQuery, _, Backbone);
'use strict';

// dependencies : Rev, jquery, underscore, Backbone

(function (Rev, $, _, Backbone) {

  'use strict';

  Rev.Views.UnsubscribeViewAlertView = Backbone.View.extend({
    el: '.unsubscribe-alert-page.view-alert',

    events: {
      'click [data-hook="btn-unsubscribe-view-alert"]': 'onDeleteViewAlertClick',
      'click [data-hook="btn-unsubscribe-all-view-alerts"]': 'onDeleteAllViewAlertClick'
    },

    onDeleteViewAlertClick: function onDeleteViewAlertClick(e) {
      e.preventDefault();
      var self = this;
      $(e.currentTarget).button('loading');

      var $form = this.$('form#form-view-alert-unsubscribe');
      var actionUrl = $form.attr('action');

      $.post(actionUrl, $form.serialize()).done(function (result) {
        if (result.status == 200) {
          Rev.Utils.showSuccessMessage('View Alert unsubscribed');
          self.$('[data-hook="btn-unsubscribe-view-alert"]').fadeOut('slow');
        }
      }).fail(function (result) {
        Rev.Utils.showErrorMessage('Sorry, we were unable to unsubscribe the view alert.');
      }).always(function () {
        if (self.$('[data-hook="btn-unsubscribe-view-alert"]').is(':visible')) {
          self.$('[data-hook="btn-unsubscribe-view-alert"]').button('reset');
        }
      });

      Rev.Utils.GaTracking.trackGaEvent(Rev.Utils.GaTracking.Category.Unsubscribe, Rev.Utils.GaTracking.Action.UnsubscribeViewAlert);
    },
    onDeleteAllViewAlertClick: function onDeleteAllViewAlertClick(e) {
      e.preventDefault();
      var self = this;
      $(e.currentTarget).button('loading');

      var $form = this.$('form#form-all-view-alert-unsubscribe');
      var actionUrl = $form.attr('action');

      $.post(actionUrl, $form.serialize()).done(function (result) {
        if (result.status == 200) {
          Rev.Utils.showSuccessMessage('View Alert unsubscribed');
          self.$('[data-hook="btn-unsubscribe-view-alert"]').fadeOut('slow');
          self.$('[data-hook="btn-unsubscribe-all-view-alerts"]').fadeOut('slow');
        }
      }).fail(function (result) {
        Rev.Utils.showErrorMessage('Sorry, we were unable to unsubscribe the view alert.');
      }).always(function () {
        if (self.$('[data-hook="btn-unsubscribe-all-view-alerts"]').is(':visible')) {
          self.$('[data-hook="btn-unsubscribe-all-view-alerts"]').button('reset');
        }
      });

      Rev.Utils.GaTracking.trackGaEvent(Rev.Utils.GaTracking.Category.Unsubscribe, Rev.Utils.GaTracking.Action.UnsubscribeAllViewAlerts);
    }
  });
})(Rev, jQuery, _, Backbone);
'use strict';

// dependencies : Rev, jquery, underscore, backbone

(function (Rev, $, _, Backbone) {

  'use strict';

  Rev.Views.ViewAlertOptionView = Backbone.View.extend({
    initialize: function initialize(options) {
      _.bindAll(this, 'closeView');

      var options = options || {};
    },

    events: {
      'click [data-hook="close"]': 'closeView',
      'hidden.bs.modal': 'onModalHidden',
      'click [data-hook="email-frequency-none"]': 'createViewAlertNone',
      'click [data-hook="email-frequency-daily"]': 'createViewAlertDaily',
      'click [data-hook="email-frequency-weekly"]': 'createViewAlertWeekly'
    },

    createViewAlertNone: function createViewAlertNone(e) {
      var _this = this;

      $(e.currentTarget).button('loading');
      var $form = $('.result-page .nav-search form');
      $form.find('[data-hook="hidden-viewalert-frequency"]').val('donotsend');
      Rev.Utils.saveSearch($form, function () {
        $('[data-hook="email-frequency-daily"]').button('reset');
        _this.closeView();
      });
    },
    createViewAlertDaily: function createViewAlertDaily(e) {
      var _this2 = this;

      $(e.currentTarget).button('loading');
      var $form = $('.result-page .nav-search form');
      $form.find('[data-hook="hidden-viewalert-frequency"]').val('Daily');
      Rev.Utils.saveSearch($form, function () {
        $('[data-hook="email-frequency-daily"]').button('reset');
        _this2.closeView();
      });
    },
    createViewAlertWeekly: function createViewAlertWeekly(e) {
      var _this3 = this;

      $(e.currentTarget).button('loading');
      var $form = $('.result-page .nav-search form');
      $form.find('[data-hook="hidden-viewalert-frequency"]').val('Weekly');
      Rev.Utils.saveSearch($form, function () {
        $('[data-hook="email-frequency-weekly"]').button('reset');
        _this3.closeView();
      });
    },
    onModalHidden: function onModalHidden(e) {
      $('.listing-items').removeClass('modal-open');
    },
    closeView: function closeView(e) {
      if (e && e.preventDefault) e.preventDefault();

      $('.rev-modal-backdrop').hide();
      this.$el.modal('hide');
    },
    remove: function remove() {
      this.closeView();
      this.off();
      Backbone.View.prototype.remove.apply(this, arguments); //call the superclass remove method
    }
  });
})(Rev, jQuery, _, Backbone);
'use strict';

var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };

(function (Rev, $, _, Backbone) {

  'use strict';

  Rev.Views.ViewHomeLoansView = Backbone.View.extend({
    initialize: function initialize(options) {
      this.options = _extends({}, options);
    },


    events: {
      'click .js-view-home-loans-banner': 'onHomeLoansBannerClick'
    },

    onHomeLoansBannerClick: function onHomeLoansBannerClick(e) {
      Rev.Utils.GaTracking.trackGaEvent(this.options.gaCategory, Rev.Utils.GaTracking.Action.ViewHomeLoanBannerClick, Rev.Utils.GaTracking.Label.Property + this.options.listingId);
    }
  });
})(Rev, jQuery, _, Backbone);
'use strict';

// dependencies : Rev, jquery, underscore, backbone

(function (Rev, $, _, Backbone) {

  'use strict';

  Rev.Views.YoutubeVideoView = Backbone.View.extend({
    initialize: function initialize() {
      _.bindAll(this, 'closeView');
    },

    events: {
      'click [data-hook="close"]': 'closeView',
      'hidden.bs.modal': 'onModalHidden'
    },

    onModalHidden: function onModalHidden(e) {
      $('.list-result-items').removeClass('modal-open');
    },
    closeView: function closeView(e) {
      if (e && e.preventDefault) e.preventDefault();

      $('.rev-modal-backdrop').hide();
      this.$el.modal('hide');
      this.$el.html('');
    },
    remove: function remove() {
      this.closeView();
      this.off();
      Backbone.View.prototype.remove.apply(this, arguments); //call the superclass remove method
    }
  });
})(Rev, jQuery, _, Backbone);
'use strict';

// dependencies : Rev, jquery, underscore, backbone

(function (Rev, $, _, Backbone) {

  'use strict';

  Rev.Views.EaiaPropertyDetailsView = Backbone.View.extend({
    initialize: function initialize(options) {
      this.options = options || {};

      _.bindAll(this, 'onStickyStart');

      this.initSubViews();

      this.$('.js-active-listing-banner').sticky({
        topSpacing: 0,
        zIndex: 10,
        getWidthFrom: '.property-info-and-photo'
      });
      this.$('.js-active-listing-banner').on('sticky-start', this.onStickyStart);
    },


    events: {
      'click [data-hook="btn-open-valuation-popup"]': 'openVauationRequestPopup',
      'click .active-listing-banner [data-hook="btn-active-listing"]': 'openActiveListing',
      'click .collapse-disclaimer': 'onBottomDisclaimerClick',
      'click .js-dismiss-active-listing': 'onDismissActiveListingClick'
    },

    onStickyStart: function onStickyStart() {
      this.$('.js-active-listing-banner').css({ 'width': '100%', 'left': 0, 'right': 0 });
    },
    onDismissActiveListingClick: function onDismissActiveListingClick(e) {
      e.preventDefault();
      this.$('.js-active-listing-banner').unstick();
    },
    onBottomDisclaimerClick: function onBottomDisclaimerClick(e) {
      e.preventDefault();
      this.$('.collapse-disclaimer').toggleClass('rotate');
      this.$('.show-hide-disclaimer').toggleClass('hide');
    },
    openActiveListing: function openActiveListing(e) {
      var action = '';

      if (this.model.get('TransactionStatus') === 1) {
        action = Rev.Utils.GaTracking.Action.ClickIntoCurrentSaleListing;
      }

      if (this.model.get('TransactionStatus') === 3) {
        action = Rev.Utils.GaTracking.Action.ClickIntoCurrentRentListing;
      }

      if (!action) return;

      Rev.Utils.GaTracking.trackGaEvent(Rev.Utils.GaTracking.Category.Property360Address, action, 'SA1-' + this.model.get('Sa1TruncatedId') + '-' + this.model.get('SeoSlug'));
    },
    openVauationRequestPopup: function openVauationRequestPopup(e) {
      if (e && e.preventDefault) e.preventDefault();

      var seoSlug = this.model.get('SeoSlug');
      var shortAddress = this.model.get('ShortAddress');
      var state = this.model.get('State');
      var suburb = this.model.get('Suburb');
      var postcode = this.model.get('Postcode');
      var fullAddress = this.model.get('FullAddress');
      var sa1 = this.model.get('Sa1TruncatedId');
      var gnafAddressId = this.model.get('GnafAddressId');
      var lat = this.model.get('GeoCoordinates').Latitude;
      var long = this.model.get('GeoCoordinates').Longitude;
      var isSponsored = this.model.get('Sponsor') && this.model.get('Sponsor').AgencyName ? true : false;
      var isSold = this.model.get('Sponsor') && this.model.get('Sponsor').IsSold ? true : false;
      if (this.model.get('Sponsor')) {
        var sponsorAgencyName = this.model.get('Sponsor').AgencyName;
        var sponsorAgencyLogo = this.model.get('Sponsor').LogoResultsUrl;
        var sponsorAgencyFontColor = this.model.get('Sponsor').AgencyFontColor;
        var sponsorAgencyBackgroundColor = this.model.get('Sponsor').AgencyBackgroundColor;
      }

      if (seoSlug && shortAddress && suburb && postcode && fullAddress && sa1 && gnafAddressId) {
        Rev.Utils.showPropertyValuationModal({
          seoSlug: seoSlug, shortAddress: shortAddress, state: state, suburb: suburb, postcode: postcode, fullAddress: fullAddress, sa1: sa1, gnafAddressId: gnafAddressId, lat: lat, long: long, isSponsored: isSponsored, isSold: isSold, sponsorAgencyName: sponsorAgencyName, sponsorAgencyLogo: sponsorAgencyLogo, sponsorAgencyFontColor: sponsorAgencyFontColor, sponsorAgencyBackgroundColor: sponsorAgencyBackgroundColor
        });

        Rev.Utils.GaTracking.trackGaEvent(Rev.Utils.GaTracking.Category.Property360Address, Rev.Utils.GaTracking.Action.GetYour360AppraisalClick, 'SA1-' + this.model.get('Sa1TruncatedId') + '-' + this.model.get('SeoSlug'));
      }
    },
    initSubViews: function initSubViews() {
      this.infoPhotoView = new Rev.Views.EaiaPropertyInfoPhotoView({ el: '.property-info-and-photo', model: this.model });
      this.avmView = new Rev.Views.AvmView({ el: '.avm-three-comps .user-mode', model: this.model });
      this.propertyHistoryView = new Rev.Views.EaiaPropertyHistoryView({ el: '.property-history', model: this.model });
      this.neighbourView = new Rev.Views.EaiaPropertyneighbourView({ el: '.neighbouring-properties', model: this.model });
      this.poiView = new Rev.Views.EaiaPropertyPoiView({ el: '.points-of-interest', model: this.model });
      //this.mortgageCalculator = new Rev.Views.MortgageCalculatorView({ el : '.mortgage-calculator' });
      this.pocketInsighsView = new Rev.Views.EaiaPropertyPocketInsightsView({ el: '.pocket-insights', model: this.model });
      this.suburbTrendsView = new Rev.Views.EaiaPropertySuburbTrendsView({ el: '.suburb-trends', model: this.model });
      this.viewHomeLoansView = new Rev.Views.EaiaViewHomeLoansView({ el: '.view-home-loans', gaCategory: this.model.get('GaEventCategory'), seoSlug: this.model.get('SeoSlug'), sa1Id: this.model.get('Sa1TruncatedId') });
      if (this.model.get('IsEnableEditingComparables') && !this.model.get('IsThreeCompsDisabled') && this.$('.avm-three-comps .agent-mode').length) {
        this.threeCompsAgentView = new Rev.Views.ThreeCompsAgentView({
          el: '.avm-three-comps .agent-mode',
          listingId: this.model.get('ActiveListingId'),
          gnafId: this.model.get('GnafAddressId')
        });
      }
    }
  });
})(Rev, jQuery, _, Backbone);
'use strict';

// dependencies : Rev, jquery, underscore, backbone

(function (Rev, $, _, Backbone) {

    'use strict';

    Rev.Views.EaiaPropertyInfoPhotoView = Backbone.View.extend({
        initialize: function initialize(options) {
            this.options = options || {};

            _.bindAll(this, 'detectStreetViewIsAvailable');

            this.detectStreetViewIsAvailable();
        },


        events: {
            'click [data-hook="open-full-photo-viewer"]': 'onPhotoClick',
            'click .js-replac-avm': 'scrollToAvmSection',
            'click .js-click-into-avm': 'viewAvmComp',
            'click .js-view-home-loans-top': 'onHomeLoans360TopClick'
        },

        scrollToAvmSection: function scrollToAvmSection(e) {
            e.preventDefault();

            Rev.Utils.GaTracking.trackGaEvent(Rev.Utils.GaTracking.Category.Property360Address, Rev.Utils.GaTracking.Action.AvmTopReplaceThem, 'SA1-' + this.model.get('Sa1TruncatedId') + '-' + this.model.get('SeoSlug'));

            var buffer = Rev.IsPhone ? 10 : 60;
            $('html, body').animate({ scrollTop: $(".avm-three-comps, .three-comps-p360").offset().top - buffer }, 700);
        },
        viewAvmComp: function viewAvmComp(e) {
            Rev.Utils.GaTracking.trackGaEvent(Rev.Utils.GaTracking.Category.Property360Address, Rev.Utils.GaTracking.Action.AvmTopClickIntoAddress, 'SA1-' + this.model.get('Sa1TruncatedId') + '-' + this.model.get('SeoSlug'));
        },
        onPhotoClick: function onPhotoClick(e) {
            e.preventDefault();

            if (!this.model.get('Photos') || this.model.get('Photos') && !this.model.get('Photos').length) {
                return;
            }

            Rev.Utils.showPhotoGalleryModal(this.model.get('ShortAddress'), this.model.get('Photos'), this.model.get('Photos'), null, null, { GaEventCategory: Rev.Utils.GaTracking.Category.Property360Address, GaEventAction: Rev.Utils.GaTracking.Action.ViewImageGallery, GaEventLabel: 'SA1-' + this.model.get('Sa1TruncatedId') + '-' + this.model.get('SeoSlug') }, { GaEventCategory: Rev.Utils.GaTracking.Category.Property360Address, GaEventAction: Rev.Utils.GaTracking.Action.CloseImageView2, GaEventLabel: 'SA1-' + this.model.get('Sa1TruncatedId') + '-' + this.model.get('SeoSlug') }, "P360", true);

            Rev.Utils.GaTracking.trackGaEvent(Rev.Utils.GaTracking.Category.Property360Address, Rev.Utils.GaTracking.Action.OpenImageView2, 'SA1-' + this.model.get('Sa1TruncatedId') + '-' + this.model.get('SeoSlug'));
        },
        detectStreetViewIsAvailable: function detectStreetViewIsAvailable() {
            var _this = this;

            if (this.model.get('StreetViewImageUrl')) {
                $.get(this.model.get('StreetViewImageUrl')).done(function (response) {
                    if (response && response.length <= 9136) {
                        _this.$('.photo-streetview').css('background-image', 'url(' + _this.model.get('GoogleMapImageUrl') + ')');
                    }
                });
            }
        },
        onHomeLoans360TopClick: function onHomeLoans360TopClick(e) {
            Rev.Utils.GaTracking.trackGaEvent(Rev.Utils.GaTracking.Category.Property360Address, Rev.Utils.GaTracking.Action.ViewHomeLoan360TopClick, 'SA1-' + this.model.get('Sa1TruncatedId') + '-' + this.model.get('SeoSlug'));
        }
    });
})(Rev, jQuery, _, Backbone);
'use strict';

// dependencies : Rev, jquery, underscore, backbone

(function (Rev, $, _, Backbone) {

  'use strict';

  Rev.Views.EaiaPropertyneighbourView = Backbone.View.extend({
    initialize: function initialize(options) {
      this.options = options || {};

      _.bindAll(this, 'afterSlick', 'onTouchstart', 'onMousedown', 'initSlick', 'detectStreetViewIsAvailable');

      this.initSlick();

      this.detectStreetViewIsAvailable();
    },


    events: {
      'touchstart .properties': 'onTouchstart',
      'mousedown .properties': 'onMousedown',
      'click .nav-left': 'onNavLeftClick',
      'click .nav-right': 'onNavRightClick',
      'click [data-hook="btn-eaia-page"]': 'onBtnEaiaPageClick'
    },

    detectStreetViewIsAvailable: function detectStreetViewIsAvailable() {
      var _this = this;

      var self = this;

      var noPhotoTemplate = _.template($('#template-no-image-available').html());
      var noPhotoHtml = noPhotoTemplate();

      _.each(this.model.get('NeighbouringProperties'), function (neighbour) {
        if (neighbour.TriedStreetViewImage) {
          $.get(neighbour.ImageUrl).done(function (response) {
            if (response && response.length <= 9136) {
              var $anchor = _this.$('.property-box-2[data-hook="' + neighbour.SeoSlug + '"] .photo-box a');
              $anchor.css('background-image', 'none').html(noPhotoHtml);
              $anchor.find('.no-image-available').show();
            }
          });
        }
      });
    },
    initSlick: function initSlick() {
      var totalProperties = this.model.get('NeighbouringProperties').length;

      // put center properties in center position in slides :)
      var startSlide = totalProperties ? Math.round(totalProperties / 2) : 0;
      if (startSlide >= totalProperties) startSlide = 0;

      this.slickInstance = Rev.Utils.initSlick(this.$('.properties'), {
        infinite: true,
        lazyLoad: null,
        slidesToScroll: 1,
        slidesToShow: 5,
        initialSlide: totalProperties <= 5 ? 0 : startSlide,
        centerMode: totalProperties <= 5 ? false : true,
        centerPadding: '120px',
        responsive: [{
          breakpoint: 1600,
          settings: {
            slidesToShow: 4,
            initialSlide: totalProperties <= 4 ? 0 : startSlide,
            centerMode: totalProperties <= 4 ? false : true,
            centerPadding: '100px'
          }
        }, {
          breakpoint: 1200,
          settings: {
            slidesToShow: 3,
            initialSlide: totalProperties <= 3 ? 0 : startSlide,
            centerMode: totalProperties <= 3 ? false : true,
            centerPadding: '100px'
          }
        }, {
          breakpoint: 992,
          settings: {
            slidesToShow: 2,
            initialSlide: totalProperties <= 2 ? 0 : startSlide,
            centerMode: totalProperties <= 2 ? false : true,
            centerPadding: '80px'
          }
        }, {
          breakpoint: 768,
          settings: {
            slidesToShow: 1,
            initialSlide: 0,
            centerMode: totalProperties <= 1 ? false : true,
            centerPadding: '15px'
          }
        }]
      });
      this.slickInstance.on('afterChange', this.afterSlick);
    },
    onBtnEaiaPageClick: function onBtnEaiaPageClick(e) {
      Rev.Utils.GaTracking.trackGaEvent(Rev.Utils.GaTracking.Category.Property360Address, Rev.Utils.GaTracking.Action.ClickIntoNeighbouringProperty360Address, 'SA1-' + this.model.get('Sa1TruncatedId') + '-' + this.model.get('SeoSlug'));
    },
    onNavLeftClick: function onNavLeftClick(e) {
      e.preventDefault();
      e.stopPropagation();
      this.$(e.currentTarget).removeClass('hover-effect');
      if (this.slickInstance) {
        this.slickInstance.slick('slickPrev');
      }
    },
    onNavRightClick: function onNavRightClick(e) {
      e.preventDefault();
      e.stopPropagation();
      this.$(e.currentTarget).removeClass('hover-effect');
      if (this.slickInstance) {
        this.slickInstance.slick('slickNext');
      }
    },
    onTouchstart: function onTouchstart(e) {
      console.log('touch start');
      this.$('.properties').removeClass('cloudy');
    },
    onMousedown: function onMousedown(e) {
      console.log('touch start');
      this.$('.properties').removeClass('cloudy');
    },
    afterSlick: function afterSlick(event, slick, currentSlide) {
      this.$('.properties').addClass('cloudy');
      this.$('.nav-left, .nav-right').addClass('hover-effect');
    }
  });
})(Rev, jQuery, _, Backbone);
'use strict';

// dependencies : Rev, jquery, underscore, backbone

(function (Rev, $, _, Backbone) {

  'use strict';

  Rev.Views.EaiaPropertyPocketInsightsView = Backbone.View.extend({
    initialize: function initialize(options) {
      this.options = options || {};

      _.bindAll(this, 'scrollHandler', 'detectViewIsIn', 'initTagCloud', 'drawChartAge', 'drawChartOccupancy', 'drawChartWages', 'drawChartHouseholds');

      this.drawChartAge();
      this.drawChartHouseholds();
      this.drawChartOccupancy();
      this.drawChartWages();

      this.initTagCloud();

      this.detectViewIsIn();

      this.hasExpanded = false;
    },


    events: {
      'click .age .btn-expand': 'onToggleAgeChartClick',
      'click .households .btn-expand': 'onToggleHouseholdsChartClick',
      'click .occupancy .btn-expand': 'onToggleOccupancyChartClick',
      'click .occupations .btn-expand': 'onToggleOccupationsClick',
      'click .collapse-btn': 'onCollapseClick'
    },

    onToggleOccupationsClick: function onToggleOccupationsClick(e) {
      $(e.currentTarget).find('.btn-expand').toggleClass('rotate');
      this.$('.occupations .content').slideToggle();
    },
    onToggleAgeChartClick: function onToggleAgeChartClick(e) {
      $(e.currentTarget).find('.btn-expand').toggleClass('rotate');

      var $chart = this.$('.chart-age');

      if ($chart.is(':visible')) {
        $chart.slideUp();
      } else {
        $chart.css({ 'display': 'block', 'opacity': '0' });
        this.chartAge.update();
        $chart.animate({ 'opacity': '1' });
      }
    },
    onToggleHouseholdsChartClick: function onToggleHouseholdsChartClick(e) {
      $(e.currentTarget).find('.btn-expand').toggleClass('rotate');

      var $chart = this.$('.chart-households');

      if ($chart.is(':visible')) {
        $chart.slideUp();
      } else {
        $chart.css({ 'display': 'block', 'opacity': '0' });
        this.chartHouseholds.update();
        $chart.animate({ 'opacity': '1' });
      }
    },
    onToggleOccupancyChartClick: function onToggleOccupancyChartClick(e) {
      $(e.currentTarget).find('.btn-expand').toggleClass('rotate');

      var $chart = this.$('.chart-occupancy');

      if ($chart.is(':visible')) {
        $chart.slideUp();
      } else {
        $chart.css({ 'display': 'block', 'opacity': '0' });
        this.chartOccupancy.update();
        $chart.animate({ 'opacity': '1' });
      }
    },
    initTagCloud: function initTagCloud() {
      this.words = [];

      if (this.model.get('WordClouds')) {
        this.words = _.map(this.model.get('WordClouds'), function (item) {
          return { text: item.Text, weight: item.Weight };
        });
      }

      this.$('.tag-cloud').jQCloud(this.words, {
        delay: 100,
        autoResize: true
      });
    },
    drawChartAge: function drawChartAge() {
      var self = this;
      var statistics = this.model.get('AreaStatistics');

      if (!statistics) return;

      var data = {
        labels: ['Under 18', '19 - 30', '31 - 40', '41 - 50', '50+'],
        series: [[statistics.PercentageUnder19, statistics.Percentage19To30, statistics.Percentage31To40, statistics.Percentage41To50, statistics.PercentageAbove50]]
      };

      var options = {
        axisX: {
          showGrid: false
        }
      };

      this.chartAge = new Chartist.Bar('.chart-age', data, options);

      // fix label not aligned to center in IE (all versions of IE)
      this.chartAge.on('draw', function (data) {
        if (data.type === 'label' && data.axis.units.pos === 'x') {
          if (!self.chartAge.supportsForeignObject) {
            data.element.attr({
              x: data.x + data.width / 4
            });
            var originX = data.x + data.width / 2;
            var originY = data.y + data.height / 2;
            data.element.attr({ 'transform': 'rotate(-15 ' + originX + ' ' + originY + ')' });
          }
        }
      });
    },
    drawChartHouseholds: function drawChartHouseholds() {
      var self = this;
      if (!this.model.get('AreaStatistics').Households) return;

      var households = this.model.get('AreaStatistics').Households;

      var labels = _.keys(households);
      var series = _.map(_.values(households), function (item) {
        return [item];
      }); //we need to make data format like [[9],[3],[2], [4]]

      var data = { labels: labels, series: series };

      var options = {
        height: 200,
        seriesBarDistance: labels.length >= 4 ? 35 : 48,
        horizontalBars: true,
        reverseData: true,
        chartPadding: {
          top: 0,
          right: 20,
          bottom: 20,
          left: 0
        },
        axisX: {
          showGrid: false,
          showLabel: false
        },
        axisY: {
          offset: 130,
          showGrid: false,
          scaleMinSpace: 40,
          labelOffset: {
            x: 0,
            y: 0
          }
        }
      };

      this.chartHouseholds = new Chartist.Bar('.chart-households', data, options);

      // fix label not aligned to center in IE (all versions of IE)
      this.chartHouseholds.on('draw', function (data) {
        if (data.type === 'label' && data.axis.units.pos === 'y') {
          if (!self.chartHouseholds.supportsForeignObject) {
            data.element.attr({ y: data.y - 15, x: data.x + 5 });
          }
        }
      });
    },
    drawChartOccupancy: function drawChartOccupancy() {
      var self = this;
      if (!this.model.get('AreaStatistics').Occupancy) return;

      var households = this.model.get('AreaStatistics').Occupancy;

      var labels = _.keys(households);
      var series = [_.values(households)];

      var data = { labels: labels, series: series };

      var options = {
        axisX: {
          showGrid: false
        }
      };

      this.chartOccupancy = new Chartist.Bar('.chart-occupancy', data, options);

      // fix label not aligned to center in IE (all versions of IE)
      this.chartOccupancy.on('draw', function (data) {
        if (data.type === 'label' && data.axis.units.pos === 'x') {
          if (!self.chartOccupancy.supportsForeignObject) {
            data.element.attr({ x: data.x + data.width / 5 });
            if (data.text.toLowerCase() === 'owns outright') {
              data.element.attr({ x: data.x - 5 });
            }

            var originX = data.x + data.width / 2;
            var originY = data.y + data.height / 2;
            data.element.attr({ 'transform': 'rotate(-15 ' + originX + ' ' + originY + ')' });
          }
        }
      });

      // avoid label overlapping (not a ultimate solution, but no known solution for this issue with chartist library)
      //this.chartOccupancy.on('draw', (data) => {
      //  if (data.type === 'label' && data.text === 'Renting') {
      //    data.element.attr({'dy' : data.y + 10});
      //  }
      //  if (data.type === 'label' && data.text === 'Other') {
      //    data.element.attr({'dx' : data.x + 20});
      //  }
      //});
    },
    drawChartWages: function drawChartWages() {
      var self = this;

      var data = {
        labels: this.model.get('Wages').Labels, // ['0-15k', '16-30k', '31-50k', '51-78k', '79-130k', '131-180k', '180k+'],
        series: [this.model.get('Wages').PocketValues.Values, this.model.get('Wages').SuburbValues.Values] //[[7,12,16,13,14,20,27],[14,9,12,11,18,29,16]]
      };

      var options = {
        height: 200,
        axisX: {
          showGrid: false,
          labelOffset: {
            x: 0,
            y: 10
          }
        },
        axisY: {
          position: 'end',
          scaleMinSpace: 50,
          labelOffset: {
            y: 5
          },
          labelInterpolationFnc: function labelInterpolationFnc(value) {
            return value + '%';
          }
        }
      };

      this.chartWages = new Chartist.Bar('.chart-wages', data, options);

      // show animation only when browser support SVG smil animation
      if (!Modernizr.smil) {
        // fix label not aligned to center in IE (all versions of IE)
        this.chartWages.on('draw', function (data) {
          if (data.type === 'label' && data.axis.units.pos === 'x') {
            if (!self.chartWages.supportsForeignObject) {
              data.element.attr({
                x: data.x + data.width / 3
              });
            }
          }
        });

        return;
      }

      this.chartWages.on('draw', function (data) {
        if (data.type === 'label' && data.axis.units.pos === 'x') {
          if (!self.chartWages.supportsForeignObject) {
            data.element.attr({
              x: data.x + data.width / 3
            });
          }
        }

        if (data.type === 'bar') {
          data.element.attr({
            style: 'stroke-width: 0px'
          });
          var strokeWidth = 10;

          if (data.seriesIndex === 0) {
            data.element.animate({
              y2: {
                begin: 0,
                dur: 500,
                from: data.y1,
                to: data.y2,
                easing: Chartist.Svg.Easing.easeOutSine
              },
              'stroke-width': {
                begin: 0,
                dur: 1,
                from: 1,
                to: strokeWidth,
                fill: 'freeze'
              }
            }, false);
          }

          if (data.seriesIndex === 1) {
            data.element.animate({
              y2: {
                begin: 500,
                dur: 500,
                from: data.y1,
                to: data.y2,
                easing: Chartist.Svg.Easing.easeOutSine
              },
              'stroke-width': {
                begin: 500,
                dur: 1,
                from: 0,
                to: strokeWidth,
                fill: 'freeze'
              }
            }, false);
          }
        }
      });
    },
    detectViewIsIn: function detectViewIsIn() {
      $(window).on('scroll', this.scrollHandler);
    },
    scrollHandler: function scrollHandler() {
      if (!this.didUpdateWagesChart && this.$('.wages').length && Rev.Utils.isElementCloseVisibleArea(this.$('.wages')).isIn) {
        this.chartWages.update();
        this.didUpdateWagesChart = true;
      }
      if (!this.didUpdateTagCloud && this.$('.tag-cloud').length && Rev.Utils.isElementCloseVisibleArea(this.$('.tag-cloud')).isIn) {
        this.$('.tag-cloud').length && this.$('.tag-cloud').jQCloud('update', this.words);
        this.didUpdateTagCloud = true;
      }
    },
    remove: function remove() {
      $(window).off('scroll', this.scrollHandler);

      this.off();
      this.stopListening();

      //call the superclass remove method
      Backbone.View.prototype.remove.apply(this, arguments);
    },
    onCollapseClick: function onCollapseClick(e) {
      if (!this.hasExpanded) {
        Rev.Utils.GaTracking.trackGaEvent(this.model.get('GaEventCategory'), Rev.Utils.GaTracking.Action.ExpandMeetTheNeighbours, 'property ' + this.model.get('Id'));
        this.hasExpanded = true;
      }
    }
  });
})(Rev, jQuery, _, Backbone);
'use strict';

// dependencies : Rev, jquery, underscore, backbone

(function (Rev, $, _, Backbone) {

  'use strict';

  Rev.Views.EaiaPropertyPoiView = Backbone.View.extend({
    initialize: function initialize(options) {
      this.options = options || {};
      _.bindAll(this, 'loadGoogleMapApi', 'showMap', 'mapDragEnd', 'mapZoomChanged', 'showPoiItemsByGeoBound', 'displayMarker', 'deleteMarkersOnTheMap', 'activePoiItemInPopup');

      this.loadGoogleMapApi();

      this.poiItems = new Rev.Collections.Items();
      this.listenTo(this.poiItems, 'reset', this.onPoiItemsReset);
    },


    events: {
      'click .section-main .poi-item': 'onMainSectionItemClick',
      'click .section-sub .header': 'onSubSectionHeaderClick',
      'click .section-sub .poi-item': 'onSubSectionItemClick',
      'click [data-hook="btn-close-infobox"]': 'onInfoBoxCloseClick',
      'click .map-type-controls label': 'onMapTypeClick',
      'click [data-hook="close-map-modal"]': 'onCloseMapClick'
    },

    onMapTypeClick: function onMapTypeClick(e) {
      var type = $(e.currentTarget).find('input').val();

      if (type == 'roadmap') {
        if (this.panorama) this.panorama.setVisible(false);
        if (this.marker) this.marker.setMap(this.map);
        this.map.setMapTypeId(google.maps.MapTypeId.ROADMAP);

        if (Rev.IsPhone) {
          if (this.$el.hasClass('full-screen')) {
            this.$('.btn-enlarge-map').hide();
            this.$('.btn-backtooriginsize-map').show();
          } else {
            this.$('.btn-enlarge-map').show();
            this.$('.btn-backtooriginsize-map').hide();
          }
          this.$('.btn-group-point-of-interest').removeClass('down');
        }
      } else if (type == 'satellite') {

        if (this.panorama) this.panorama.setVisible(false);
        if (this.marker) this.marker.setMap(this.map);
        this.map.setMapTypeId(google.maps.MapTypeId.SATELLITE);
      } else if (type == 'street') {
        if (!this.isStreetViewDisabled) {
          if (this.panorama) {
            if (this.marker) this.marker.setMap(this.panorama);
            this.panorama.setVisible(true);
          } else {
            var self = this;
            var container = self.$('.map-canvas');

            // check street view is available in this location
            var streetViewService = new google.maps.StreetViewService();
            streetViewService.getPanorama({ location: this.coords, radius: 100, preference: google.maps.StreetViewPreference.NEAREST }, function (data, status) {
              if (status === google.maps.StreetViewStatus.OK) {
                var heading = google.maps.geometry.spherical.computeHeading(data.location.latLng, self.coords);
                self.panorama = new google.maps.StreetViewPanorama(container.get(0));
                self.panorama.setPano(data.location.pano);
                self.panorama.setPov({
                  heading: heading,
                  pitch: 0
                });
                self.panorama.setOptions({
                  zoomControl: false,
                  linksControl: false,
                  panControl: false,
                  enableCloseButton: false
                });
                self.panorama.setVisible(true);
              } else {
                self.isStreetViewDisabled = true;
                self.$('[data-hook="label-street-view"]').addClass('disabled');

                if (Rev.IsPhone) {
                  self.$('[data-hook="label-street-view"] input').prop('disabled', true);
                } else {
                  self.$('[data-hook="label-street-view"]').attr('title', 'Sorry, no street view available in this location').tooltip().addClass('disabled');
                }
              }
            });
          }
        } else {
          var $activeLabel = $('.map-type-controls label.active');
          setTimeout(function () {
            $(e.currentTarget).removeClass('active');
            $activeLabel.addClass('active');
          }, 10);

          if (Rev.IsPhone) {
            alert('Sorry, no street view is available in this location.');
          }
        }
      }
    },
    onInfoBoxCloseClick: function onInfoBoxCloseClick(e) {
      e.preventDefault();
      if (this.infoBox) {
        this.infoBox.close();
      }
    },
    onMainSectionItemClick: function onMainSectionItemClick(e) {
      var self = this;

      this.$('.section-main, .section-sub').toggleClass('active');
      self.currentPoiType = this.$(e.currentTarget).attr('data-poi-type');
      var poiTypeText = this.$(e.currentTarget).find('.item-name').text();
      this.$('[data-hook="section-sub-header-text"]').text(poiTypeText);

      this.showPoiItemsByGeoBound();

      Rev.Utils.GaTracking.trackGaEvent(this.model.get('GaEventCategory'), Rev.Utils.GaTracking.Action.WhatsNearbyMapCategory, poiTypeText);
    },
    onSubSectionHeaderClick: function onSubSectionHeaderClick(e) {
      this.$('.section-main, .section-sub').toggleClass('active');
      this.currentPoiType = null;
      if (this.infoBox) {
        this.infoBox.close();
      }
    },
    onSubSectionItemClick: function onSubSectionItemClick(e) {
      this.$('.section-sub .content .poi-item').removeClass('active');
      this.$(e.currentTarget).addClass('active');

      // open infobox
      if (!this.markerArray || this.markerArray && !this.markerArray.length) return;
      var poiId = this.$(e.currentTarget).attr('data-poi-id');
      if (!poiId) return;
      var marker = _.find(this.markerArray, function (item) {
        return item.get('poiId') == poiId;
      });
      if (!marker) return;
      google.maps.event.trigger(marker, 'click');
      if (this.infoBox) {
        this.map.panTo(this.infoBox.getPosition());
      }
    },
    showPoiItemsByGeoBound: function showPoiItemsByGeoBound() {
      var self = this;
      if (!self.currentPoiType) return;

      self.$('.points-of-interest-layer').addClass('disabled');

      var latLngBounds = this.map.getBounds();

      var param = {
        nwlat: latLngBounds.getNorthEast().lat(),
        nwlng: latLngBounds.getSouthWest().lng(),
        selat: latLngBounds.getSouthWest().lat(),
        selng: latLngBounds.getNorthEast().lng(),
        addlat: self.coords.lat(),
        addlng: self.coords.lng(),
        poiType: this.getGooglePoiType(self.currentPoiType)
      };

      // reset poi items
      self.poiItems.reset([]);

      if (param.poiType === 'school') {
        $.getJSON('/property-360/property/poi/bound/', param).done(function (result) {
          return self.poiItems.reset(result);
        }).always(function () {
          return self.$('.points-of-interest-layer').removeClass('disabled');
        });
      } else {
        this.placeService.nearbySearch({
          location: this.coords,
          bounds: this.map.getBounds(),
          type: param.poiType
        }, function (results, status) {
          if (status === google.maps.places.PlacesServiceStatus.OK) {

            var items = _.map(results, function (item) {
              return {
                IsGooglePoi: true,
                Id: item.place_id,
                Name: item.name,
                Location: {
                  Latitude: item.geometry.location.lat(),
                  Longitude: item.geometry.location.lng()
                },
                PoiTypeText: self.currentPoiType
              };
            });

            self.poiItems.reset(items);
          }

          self.$('.points-of-interest-layer').removeClass('disabled');
        });
      }
    },
    getGooglePoiType: function getGooglePoiType(currentPoiType) {
      switch (currentPoiType) {
        case 'school':
          return 'school';
          break;
        case 'transport':
          return 'train_station';
          break;
        case 'eat':
          return 'restaurant';
          break;
        case 'shopping':
          return 'store';
          break;
        default:
          return '';
      }
    },
    onPoiItemsReset: function onPoiItemsReset(collection, options) {
      var self = this;

      console.log('collection.toJSON()', collection.toJSON());

      // update POI popup items
      var template = _.template($('#template-poi-items').html());
      self.$('.section-sub .content').html(template({ poiItems: collection.toJSON() }));

      this.deleteMarkersOnTheMap();

      // display markers on the map
      collection.each(function (item) {
        return setTimeout(function () {
          return self.displayMarker(item);
        }, 100);
      });
    },
    deleteMarkersOnTheMap: function deleteMarkersOnTheMap() {
      var self = this;
      // delete existing markers on the map
      console.log(this.markerArray);
      _.each(self.markerArray, function (marker) {
        return setTimeout(function () {
          return self.deleteMarker(marker);
        }, 100);
      });
    },
    displayMarker: function displayMarker(item) {
      var self = this;

      if (!item.get('Location').Latitude || !item.get('Location').Longitude) {
        return;
      }

      var LatLng = new google.maps.LatLng(item.get('Location').Latitude, item.get('Location').Longitude);

      // extend map bounds in order to zoom to fit all markers
      self.bounds.extend(LatLng);

      // create marker for each listing
      var marker = new google.maps.Marker({
        position: LatLng,
        map: self.map,
        animation: google.maps.Animation.BOUNCE,
        icon: self.getMarkerIcon(self.currentPoiType),
        poiId: item.get('Id'),
        poiType: item.get('PoiType')
      });

      google.maps.event.addListener(marker, 'click', function () {
        if (self.infoBox) {
          self.infoBox.close();
        }
        var template = _.template($("#template-poi-infobox").html());
        var html = '';

        if (item.get('IsGooglePoi')) {
          self.placeService.getDetails({ placeId: item.get('Id') }, function (placeDetail, status) {
            if (status == google.maps.places.PlacesServiceStatus.OK) {
              html = template({
                name: placeDetail.name,
                category: '',
                religion: '',
                telephone: placeDetail.formatted_phone_number,
                fullAddress: placeDetail.formatted_address,
                website: placeDetail.website,
                photo: placeDetail.photos && placeDetail.photos[0] ? placeDetail.photos[0].getUrl({ maxWidth: 150, maxHeight: 150 }) : null,
                poiType: item.get('PoiTypeText'),
                isGooglePoi: true
              });

              self.infoBox = new InfoBox(self.infoBoxOptions);
              self.infoBox.setContent(html);
              self.infoBox.open(self.map, marker);

              self.activePoiItemInPopup(item.get('Id'));
            }
          });
        } else {
          html = template({
            name: item.get('Name'),
            category: item.get('Category'),
            religion: item.get('Religion'),
            telephone: item.get('Telephone'),
            fullAddress: item.get('Address') + ', ' + item.get('Suburb') + ' ' + item.get('Postcode'),
            website: item.get('Website'),
            photo: null,
            poiType: item.get('PoiTypeText'),
            isGooglePoi: false
          });

          self.infoBox = new InfoBox(self.infoBoxOptions);
          self.infoBox.setContent(html);
          self.infoBox.open(self.map, marker);

          self.activePoiItemInPopup(item.get('Id'));
        }
      });

      setTimeout(function () {
        return marker.setAnimation(null);
      }, 700);

      self.markerArray.push(marker);
    },
    activePoiItemInPopup: function activePoiItemInPopup(id) {
      var self = this;
      self.$('.section-sub .poi-item').removeClass('active');
      var selector = '.section-sub .poi-item[data-poi-id="' + id + '"]';
      self.$(selector).addClass('active');
    },
    getMarkerIcon: function getMarkerIcon(poiType) {
      var url = '/assets/content/images/map_dot-marker.png';

      switch (poiType) {
        case 'school':
          url = '/assets/content/images/map_markers/map_icon_school.png';
          break;
        case 'transport':
          url = '/assets/content/images/map_markers/map_icon_transport.png';
          break;
        case 'eat':
          url = '/assets/content/images/map_markers/map_icon_eats.png';
          break;
        case 'shopping':
          url = '/assets/content/images/map_markers/map_icon_shopping.png';
          break;
      }

      return { url: url };
    },
    deleteMarker: function deleteMarker(marker) {
      if (!marker) return;

      console.log('deleteMarker');

      // remove marker from the map
      marker.setMap(null);

      // remove marker from the array
      var index = _.indexOf(this.markerArray, marker);
      if (index > -1) this.markerArray.splice(index, 1);
    },
    loadGoogleMapApi: function loadGoogleMapApi() {
      var self = this;
      Rev.Utils.loadGoogleMapApiSync(function () {
        self.showMap(self.$('.map-canvas'));
        self.$('.points-of-interest-layer').removeClass('disabled');
      });
    },
    showMap: function showMap($mapCanvas) {
      var self = this;

      var container = $mapCanvas;

      self.bounds = new google.maps.LatLngBounds();

      this.coords = new google.maps.LatLng(this.model.get('GeoCoordinates').Latitude, this.model.get('GeoCoordinates').Longitude);

      var zoomLevel = Rev.IsPhone ? 15 : 16;

      var mapOptions = {
        scrollwheel: false,
        //draggable: !("ontouchend" in document),
        center: this.coords,
        zoom: zoomLevel,
        mapTypeControl: false,
        streetViewControl: false,
        zoomControlOptions: { position: Rev.IsPhone ? google.maps.ControlPosition.RIGHT_BOTTOM : google.maps.ControlPosition.TOP_LEFT }
      };

      this.map = new google.maps.Map(container.get(0), mapOptions);

      google.maps.event.addListener(this.map, 'dragend', this.mapDragEnd);
      google.maps.event.addListener(this.map, 'zoom_changed', this.mapZoomChanged);

      this.infowindow = new google.maps.InfoWindow();
      this.poiMarkers = [];
      // array for markers
      this.markerArray = [];

      this.marker = new google.maps.Marker({
        position: this.coords,
        map: this.map,
        title: 'Map',
        icon: '/assets/content/images/map_markers/pin.png'
      });

      // create service for poi
      this.placeService = new google.maps.places.PlacesService(this.map);

      var pixelOffset = Rev.IsPhone ? new google.maps.Size(-130, -200) : new google.maps.Size(-240, -200);

      this.infoBoxOptions = {
        disableAutoPan: false,
        maxWidth: 0,
        pixelOffset: pixelOffset,
        zIndex: null,
        closeBoxURL: "",
        infoBoxClearance: new google.maps.Size(1, 1),
        isHidden: false,
        pane: "floatPane",
        enableEventPropagation: false
      };
    },
    mapDragEnd: function mapDragEnd() {
      this.showPoiItemsByGeoBound();
    },
    mapZoomChanged: function mapZoomChanged() {
      this.showPoiItemsByGeoBound();
    },
    onCloseMapClick: function onCloseMapClick() {
      $('.rev-modal-backdrop').hide();
      this.$el.modal('hide');

      $('body').removeClass('modal-open');
    },
    remove: function remove() {
      this.off();
      this.stopListening();

      //call the superclass remove method
      Backbone.View.prototype.remove.apply(this, arguments);
    }
  });
})(Rev, jQuery, _, Backbone);
'use strict';

// dependencies : Rev, jquery, underscore, backbone

(function (Rev, $, _, Backbone) {

  'use strict';

  Rev.Views.EaiaPropertyHistoryView = Backbone.View.extend({
    initialize: function initialize(options) {
      this.options = options || {};
    },


    events: {
      'click [data-hook="btn-show-more"]': 'onShowMoreClick',
      'click [data-hook="btn-history-all"]': 'onBtnHistoryAllClick',
      'click [data-hook="btn-history-sold"]': 'onBtnHistorySoldClick',
      'click [data-hook="btn-history-rented"]': 'onBtnHistoryRentedClick',
      'click [data-hook="btn-active-listing"]': 'triggerGaEventForActiveListing'
    },

    triggerGaEventForActiveListing: function triggerGaEventForActiveListing(e) {
      var action = '';

      if (this.model.get('TransactionStatus') === 1) {
        action = Rev.Utils.GaTracking.Action.ClickIntoCurrentSaleListing;
      }

      if (this.model.get('TransactionStatus') === 3) {
        action = Rev.Utils.GaTracking.Action.ClickIntoCurrentRentListing;
      }

      if (!action) return;

      Rev.Utils.GaTracking.trackGaEvent(Rev.Utils.GaTracking.Category.Property360Address, action, 'SA1-' + this.model.get('Sa1TruncatedId') + '-' + this.model.get('SeoSlug'));
    },
    onBtnHistoryAllClick: function onBtnHistoryAllClick(e) {
      if (!this.soldRentedHistoryClicked) return; // only fire ga when sold or rented clicked before

      Rev.Utils.GaTracking.trackGaEvent(Rev.Utils.GaTracking.Category.Property360Address, Rev.Utils.GaTracking.Action.ClickAllSaleRentalHistory, 'SA1-' + this.model.get('Sa1TruncatedId') + '-' + this.model.get('SeoSlug'));
    },
    onBtnHistorySoldClick: function onBtnHistorySoldClick(e) {
      this.soldRentedHistoryClicked = true;
      Rev.Utils.GaTracking.trackGaEvent(Rev.Utils.GaTracking.Category.Property360Address, Rev.Utils.GaTracking.Action.ClickSaleHistoryOnly, 'SA1-' + this.model.get('Sa1TruncatedId') + '-' + this.model.get('SeoSlug'));
    },
    onBtnHistoryRentedClick: function onBtnHistoryRentedClick(e) {
      this.soldRentedHistoryClicked = true;
      Rev.Utils.GaTracking.trackGaEvent(Rev.Utils.GaTracking.Category.Property360Address, Rev.Utils.GaTracking.Action.ClickRentalHistoryOnly, 'SA1-' + this.model.get('Sa1TruncatedId') + '-' + this.model.get('SeoSlug'));
    },
    onShowMoreClick: function onShowMoreClick(e) {
      var _this = this;

      e.preventDefault();
      this.$('.more-rows').slideDown(function () {
        return _this.$('[data-hook="btn-show-more"]').fadeOut();
      });
    }
  });
})(Rev, jQuery, _, Backbone);
'use strict';

// dependencies : Rev, jquery, underscore, backbone

(function (Rev, $, _, Backbone) {

    'use strict';

    Rev.Views.EaiaSimilarPropertiesView = Backbone.View.extend({
        initialize: function initialize(options) {
            this.options = options || {};
        },


        events: {
            'click [data-hook="btn-sold"]': 'onBtnSoldClick',
            'click [data-hook="btn-sale"]': 'onBtnSaleClick',
            'click [data-hook="btn-rent"]': 'onBtnRentClick',
            'click #similar-properties-sold .property-box [data-hook="btn-active-listing"]': 'onSoldListingClick',
            'click #similar-properties-sale .property-box [data-hook="btn-active-listing"]': 'onSaleListingClick',
            'click #similar-properties-rent .property-box [data-hook="btn-active-listing"]': 'onRentListingClick'
        },

        onSoldListingClick: function onSoldListingClick(e) {
            Rev.Utils.GaTracking.trackGaEvent(Rev.Utils.GaTracking.Category.Property360Address, Rev.Utils.GaTracking.Action.ClickIntoSimilarSoldListing, 'SA1-' + this.model.get('Sa1TruncatedId') + '-' + this.model.get('SeoSlug'));
        },
        onSaleListingClick: function onSaleListingClick(e) {
            Rev.Utils.GaTracking.trackGaEvent(Rev.Utils.GaTracking.Category.Property360Address, Rev.Utils.GaTracking.Action.ClickIntoSimilarSaleListing, 'SA1-' + this.model.get('Sa1TruncatedId') + '-' + this.model.get('SeoSlug'));
        },
        onRentListingClick: function onRentListingClick(e) {
            Rev.Utils.GaTracking.trackGaEvent(Rev.Utils.GaTracking.Category.Property360Address, Rev.Utils.GaTracking.Action.ClickIntoSimilarRentListing, 'SA1-' + this.model.get('Sa1TruncatedId') + '-' + this.model.get('SeoSlug'));
        },
        onBtnSoldClick: function onBtnSoldClick(e) {
            if (!this.saleRentClicked) return; // only fire ga when sale or rent clicked before

            Rev.Utils.GaTracking.trackGaEvent(Rev.Utils.GaTracking.Category.Property360Address, Rev.Utils.GaTracking.Action.SimilarPropertiesSold, 'SA1-' + this.model.get('Sa1TruncatedId') + '-' + this.model.get('SeoSlug'));
        },
        onBtnSaleClick: function onBtnSaleClick(e) {
            this.saleRentClicked = true;
            Rev.Utils.GaTracking.trackGaEvent(Rev.Utils.GaTracking.Category.Property360Address, Rev.Utils.GaTracking.Action.SimilarPropertiesSale, 'SA1-' + this.model.get('Sa1TruncatedId') + '-' + this.model.get('SeoSlug'));
        },
        onBtnRentClick: function onBtnRentClick(e) {
            this.saleRentClicked = true;
            Rev.Utils.GaTracking.trackGaEvent(Rev.Utils.GaTracking.Category.Property360Address, Rev.Utils.GaTracking.Action.SimilarPropertiesRent, 'SA1-' + this.model.get('Sa1TruncatedId') + '-' + this.model.get('SeoSlug'));
        }
    });
})(Rev, jQuery, _, Backbone);
'use strict';

// dependencies : Rev, jquery, underscore, backbone

(function (Rev, $, _, Backbone) {

  'use strict';

  Rev.Views.EaiaPropertySuburbTrendsView = Backbone.View.extend({
    initialize: function initialize(options) {
      this.options = options || {};
      _.bindAll(this, 'detectViewIsIn', 'updateChart', 'scrollHandler');

      if (!this.model.get('LocalityTrendsHouse') && !this.model.get('LocalityTrendsUnit')) {
        return;
      }

      this.chartData = {
        labels: this.model.get('LocalityTrendsHouse').MedianSalePrice.Labels,
        series: [this.model.get('LocalityTrendsHouse').MedianSalePrice.Series]
      };

      this.updateChart(false);

      if (this.chartData.labels.length === 0) {
        this.$('.tab-content').addClass('no-data');
      }

      this.detectViewIsIn();

      this.hasExpanded = false;
    },


    events: {
      'shown.bs.tab a[data-toggle="tab"]': 'onTabShown',
      'click .numbers a': 'onBigNumbersClick',
      'click .collapse-btn': 'onCollapseClick'
    },

    onBigNumbersClick: function onBigNumbersClick(e) {
      e.preventDefault();
      this.$('.numbers a').removeClass('active');
      this.$(e.currentTarget).addClass('active');
      this.updateChart();
    },
    onTabShown: function onTabShown(e) {
      this.updateChart();
    },
    updateChart: function updateChart() {
      var fireGaEvent = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;

      var gaAction = '';

      // activeTab can be either 'house' or 'unit'
      var activeTab = this.$('.nav.nav-tabs li.active a').attr('data-hook');

      // activeBigNumber can be 'median-sale-price', 'avg-days-listed', 'avg-vendor-discount' or 'median-rental-price'
      var activeBigNumber = this.$('.numbers a.active').attr('data-hook');

      if (activeTab === 'house') {
        this.$('[data-hook="median-sale-price-text"]').text(this.model.get('LocalityTrendsHouse').LatestMedianPrice);
        this.$('[data-hook="avg-days-listed-text"]').text(this.model.get('LocalityTrendsHouse').LatestAverageDaysOnMarket);
        this.$('[data-hook="avg-vendor-discount-text"]').text(this.model.get('LocalityTrendsHouse').LatestMedianSaleDiscount);
        this.$('[data-hook="median-rental-price-text"]').text(this.model.get('LocalityTrendsHouse').LatestMedianLease);
      }

      if (activeTab === 'unit') {
        this.$('[data-hook="median-sale-price-text"]').text(this.model.get('LocalityTrendsUnit').LatestMedianPrice);
        this.$('[data-hook="avg-days-listed-text"]').text(this.model.get('LocalityTrendsUnit').LatestAverageDaysOnMarket);
        this.$('[data-hook="avg-vendor-discount-text"]').text(this.model.get('LocalityTrendsUnit').LatestMedianSaleDiscount);
        this.$('[data-hook="median-rental-price-text"]').text(this.model.get('LocalityTrendsUnit').LatestMedianLease);
      }

      // house
      if (activeTab === 'house' && activeBigNumber === 'median-sale-price') {
        this.chartData = {
          labels: this.model.get('LocalityTrendsHouse').MedianSalePrice.Labels,
          series: [this.model.get('LocalityTrendsHouse').MedianSalePrice.Series]
        };

        gaAction = Rev.Utils.GaTracking.Action.SuburbTrendsSaleHouse;
      }

      if (activeTab === 'house' && activeBigNumber === 'avg-days-listed') {
        this.chartData = {
          labels: this.model.get('LocalityTrendsHouse').AverageDaysonMarket.Labels,
          series: [this.model.get('LocalityTrendsHouse').AverageDaysonMarket.Series]
        };

        gaAction = Rev.Utils.GaTracking.Action.SuburbTrendsAvgDaysListedHouse;
      }

      if (activeTab === 'house' && activeBigNumber === 'avg-vendor-discount') {
        this.chartData = {
          labels: this.model.get('LocalityTrendsHouse').AverageVendorDiscount.Labels,
          series: [this.model.get('LocalityTrendsHouse').AverageVendorDiscount.Series]
        };

        gaAction = Rev.Utils.GaTracking.Action.SuburbTrendsAvgVendorDiscHouse;
      }

      if (activeTab === 'house' && activeBigNumber === 'median-rental-price') {
        this.chartData = {
          labels: this.model.get('LocalityTrendsHouse').MedianRentalPrice.Labels,
          series: [this.model.get('LocalityTrendsHouse').MedianRentalPrice.Series]
        };

        gaAction = Rev.Utils.GaTracking.Action.SuburbTrendsRentalHouse;
      }

      // unit
      if (activeTab === 'unit' && activeBigNumber === 'median-sale-price') {
        this.chartData = {
          labels: this.model.get('LocalityTrendsUnit').MedianSalePrice.Labels,
          series: [this.model.get('LocalityTrendsUnit').MedianSalePrice.Series]
        };

        gaAction = Rev.Utils.GaTracking.Action.SuburbTrendsSaleUnit;
      }

      if (activeTab === 'unit' && activeBigNumber === 'avg-days-listed') {
        this.chartData = {
          labels: this.model.get('LocalityTrendsUnit').AverageDaysonMarket.Labels,
          series: [this.model.get('LocalityTrendsUnit').AverageDaysonMarket.Series]
        };

        gaAction = Rev.Utils.GaTracking.Action.SuburbTrendsAvgDaysListedUnit;
      }

      if (activeTab === 'unit' && activeBigNumber === 'avg-vendor-discount') {
        this.chartData = {
          labels: this.model.get('LocalityTrendsUnit').AverageVendorDiscount.Labels,
          series: [this.model.get('LocalityTrendsUnit').AverageVendorDiscount.Series]
        };

        gaAction = Rev.Utils.GaTracking.Action.SuburbTrendsAvgVendorDiscUnit;
      }

      if (activeTab === 'unit' && activeBigNumber === 'median-rental-price') {
        this.chartData = {
          labels: this.model.get('LocalityTrendsUnit').MedianRentalPrice.Labels,
          series: [this.model.get('LocalityTrendsUnit').MedianRentalPrice.Series]
        };

        gaAction = Rev.Utils.GaTracking.Action.SuburbTrendsRentalUnit;
      }

      if (this.chartData.labels.length === 0) {
        var noDataText = 'No vendor discount data for this suburb';

        if (activeBigNumber === 'median-sale-price') {
          noDataText = 'No median sale price for this suburb';
        } else if (activeBigNumber === 'median-rental-price') {
          noDataText = 'No median rental price for this suburb';
        } else if (activeBigNumber === 'avg-days-listed') {
          noDataText = 'No days on market data for this suburb';
        } else if (activeBigNumber === 'avg-vendor-discount') {
          noDataText = 'No vendor discount data for this suburb';
        }

        this.$('.no-data-text').text(noDataText);
        this.$('.tab-content').addClass('no-data');
      } else {
        this.$('.tab-content').removeClass('no-data');
      }

      if (this.chart) {
        if (this.$toolTip) {
          this.$toolTip.hide();
        }
        // add "high" option to avoid the top grid in chart disappeared
        var seriesNumber = this.chartData.series[0].length > 0 ? _.map(this.chartData.series[0], function (item) {
          return Number(item);
        }) : [];
        var option = seriesNumber.length > 0 ? _.extend(this.chartOptions, { high: _.max(seriesNumber) + 1 }) : this.chartOptions;
        this.chart.update(this.chartData, option);
      } else {
        this.initChart();
      }

      if (gaAction && fireGaEvent) {
        Rev.Utils.GaTracking.trackGaEvent(this.model.get('GaEventCategory'), gaAction, 'SA1-' + this.model.get('Sa1TruncatedId') + '-' + this.model.get('SeoSlug'));
      }
    },
    detectViewIsIn: function detectViewIsIn() {
      $(window).on('scroll', this.scrollHandler);
    },
    scrollHandler: function scrollHandler() {
      if (!this.didUpdateMedianPriceChart && this.$el.length && Rev.Utils.isElementCloseVisibleArea(this.$el).isIn) {
        this.updateChart(false);
        this.didUpdateMedianPriceChart = true;
      }
    },
    initChart: function initChart() {
      var _this = this;

      var self = this;

      this.chartOptions = {
        fullWidth: false,
        height: 200,
        chartPadding: {
          top: 20,
          right: 30,
          bottom: 20,
          left: 20
        },
        showLine: true,
        showPoint: true,
        axisX: {
          showGrid: true,
          labelOffset: {
            x: -13,
            y: 5
          },
          labelInterpolationFnc: function labelInterpolationFnc(value) {
            return _this.getMonthAndYear(value);
          }
        },
        axisY: {
          position: 'end',
          onlyInteger: true,
          scaleMinSpace: 30,
          labelOffset: {
            x: -5,
            y: 5
          },
          labelInterpolationFnc: function labelInterpolationFnc(value) {
            return _this.convertMoney(value);
          }
        }
      };

      // add "high" option to avoid the top grid in chart disappeared
      if (this.chartData && this.chartData.series[0]) {
        var seriesNumber = this.chartData.series[0].length > 0 ? _.map(this.chartData.series[0], function (item) {
          return Number(item);
        }) : [];
        seriesNumber.length > 0 && _.extend(this.chartOptions, { high: _.max(seriesNumber) + 1 });
      }
      this.chart = new Chartist.Line('.chart', this.chartData || null, this.chartOptions);

      this.chart.on('draw', function (data) {

        // show animation only when browser support SVG smil animation
        if (!Modernizr.smil) {
          return;
        }

        // animation
        if (data.type === 'point') {
          data.element.animate({
            y1: {
              dur: '1000ms',
              from: data.axisY.axisLength + data.axisY.gridOffset,
              to: data.y,
              easing: Chartist.Svg.Easing.easeOutQuint
            },
            y2: {
              dur: '1000ms',
              from: data.axisY.axisLength + data.axisY.gridOffset,
              to: data.y,
              easing: Chartist.Svg.Easing.easeOutQuint
            }
          });
        }

        if (data.type === 'line' || data.type === 'area') {
          data.element.animate({
            d: {
              begin: 1000 * data.index,
              dur: 1000,
              from: data.path.clone().scale(1, 0).translate(0, data.chartRect.height() + data.axisY.gridOffset).stringify(),
              to: data.path.clone().stringify(),
              easing: Chartist.Svg.Easing.easeOutQuint
            }
          });
        }
      });

      this.$chart = $('.chart');

      if (this.$toolTip) {
        this.$toolTip.remove();
      }

      this.$toolTip = this.$chart.append('<div class="tooltip"></div>').find('.tooltip').hide();

      this.$chart.on('mouseenter', '.ct-point', function (e) {
        var value = $(e.currentTarget).attr('ct:value');

        // TODO : when integrate with API, convert value properly depend what user selected
        self.$toolTip.html(_this.convertMoney(value)).show();
      });

      this.$chart.on('mouseleave', '.ct-point', function () {
        return _this.$toolTip.hide();
      });

      this.$chart.on('mousemove', function (event) {
        var left = (event.originalEvent.layerX || event.offsetX) - self.$toolTip.width() / 2 - 15;
        var top = (event.originalEvent.layerY || event.offsetY) - self.$toolTip.height() - 45;

        if (!Rev.Utils.isFirefox()) {
          left = event.offsetX - self.$toolTip.width() / 2 - 15;
          top = event.offsetY - self.$toolTip.height() - 45;
        }

        self.$toolTip.css({
          left: left,
          top: top
        });
      });

      if (Rev.IsPhone || 'ontouchend' in document) {
        this.$chart.on('click', '.ct-point', function (event) {
          if (self.timeoutHandler) {
            clearTimeout(self.timeoutHandler);
          }

          self.$toolTip.hide();

          var value = $(event.currentTarget).attr('ct:value');
          self.$toolTip.html(_this.convertMoney(value)).show();

          var left = event.offsetX - self.$toolTip.width() / 2 - 15;
          var top = event.offsetY - self.$toolTip.height() - 45;

          self.$toolTip.css({
            opacity: 1,
            left: left,
            top: top
          });

          self.timeoutHandler = setTimeout(function () {
            return self.$toolTip.hide();
          }, 3000);
        });
      }
    },
    getOnlyYear: function getOnlyYear(yyyyqq) {
      if (this.chartData.labels.length <= 8) {
        return yyyyqq;
      }

      if (yyyyqq.indexOf('Q1') >= 0) {
        return yyyyqq.substr(0, 4);
      } else {
        return '';
      }
    },
    getMonthAndYear: function getMonthAndYear(mmmyyyy) {
      if (!mmmyyyy) return '';

      return mmmyyyy.substr(0, 3) + ' ' + mmmyyyy.substr(5, 4);
    },
    convertMoney: function convertMoney(price) {
      return '$' + Rev.Utils.String.numberWithCommas(price);
    },
    remove: function remove() {
      $(window).off('scroll', this.scrollHandler);

      this.off();
      this.stopListening();

      //call the superclass remove method
      Backbone.View.prototype.remove.apply(this, arguments);
    },
    onCollapseClick: function onCollapseClick(e) {
      if (!this.hasExpanded) {
        Rev.Utils.GaTracking.trackGaEvent(this.model.get('GaEventCategory'), Rev.Utils.GaTracking.Action.ExpandSuburbTrends, 'property ' + this.model.get('Id'));
        this.hasExpanded = true;
      }
    }
  });
})(Rev, jQuery, _, Backbone);
'use strict';

// dependencies : Rev, jquery, underscore, backbone

(function (Rev, $, _, Backbone) {

    'use strict';

    Rev.Views.EaiaPropertyValuationPopupView = Backbone.View.extend({
        initialize: function initialize(options) {
            this.options = options || {};
            this.errorPlaceHolder = this.$('[data-hook="property-valuation-form-validation-errors-placeholder"]');

            this.$('input[type="hidden"][name="PageUrl"]').val(window.location.href);
        },


        events: {
            'click [data-hook="close"]': 'closeView',
            'click [data-hook="btn-send"]': 'onSendClick'
        },

        onSendClick: function onSendClick(e) {
            var _this = this;

            e.preventDefault();
            $(e.currentTarget).button('loading');
            var $form = this.$('[data-hook="property-valuation-form"]');
            var actionUrl = $form.attr('action');

            $.post(actionUrl, $form.serialize()).done(function (result) {
                if (result.errors) {
                    Rev.Utils.showErrors(result.errors, _this.errorPlaceHolder);
                    $('#eaia-modal-placeholder, .eaia-modal-content-placeholder, .valuation-request-modal').animate({ scrollTop: 0 }, "slow");
                } else {
                    Rev.Utils.GaTracking.trackGaEvent(Rev.Utils.GaTracking.Category.Property360Address, Rev.Utils.GaTracking.Action.Send360Appraisal, 'SA1-' + _this.options.appraisalRequest.sa1 + '-' + _this.options.appraisalRequest.seoSlug);

                    _paq.push(['trackEvent', 'p360', 'RequestAppraisal', 'gnafId', _this.options.appraisalRequest.gnafAddressId]);

                    _this.showSuccessMessage();
                    setTimeout(function () {
                        return _this.closeView();
                    }, 300);
                }
            }).fail(function (result) {
                Rev.Utils.showErrors(result.errors, _this.errorPlaceHolder);
                $('#eaia-modal-placeholder, .eaia-modal-content-placeholder, .valuation-request-modal').animate({ scrollTop: 0 }, "slow");
            }).always(function () {
                _this.$('[data-hook="btn-send"]').button('reset');
            });
        },
        showSuccessMessage: function showSuccessMessage(message) {
            Rev.Utils.showSuccessMessage(message || 'Your enquiry has been sent successfully.');

            // clear error messages
            Rev.Utils.clearErrors(this.errorPlaceHolder);

            // return to display mode
            this.$('form .form-group').removeClass('editing show');
        },
        closeView: function closeView(e) {
            if (e && e.preventDefault) e.preventDefault();
            $('.eaia-modal-backdrop').hide();
            this.$el.modal('hide');
        },
        remove: function remove() {
            this.closeView();
            this.off();
            Backbone.View.prototype.remove.apply(this, arguments); //call the superclass remove method
        }
    });
})(Rev, jQuery, _, Backbone);
'use strict';

// dependencies : Rev, jquery, underscore, backbone

(function (Rev, $, _, Backbone) {

  'use strict';

  Rev.Views.EaiaSearchView = Backbone.View.extend({
    initialize: function initialize(options) {
      this.options = options || {};
      this.onAddressSearchCompleteHandler = this.options.onAddressSearchCompleteHandler || this.moveToEaiaPages;

      _.bindAll(this, 'initializeBloodHound', 'recentSuggestions', 'startSearch', 'clearAddress');

      Rev.Models.localData.fetch();
      this.recentSuggestionsData = _.sortBy(Rev.Models.localData.get('recentEaiaSearch'), 'AddressText');

      this.initializeBloodHound();
      this.initializeLocationTypeahead();

      this.listenTo(Rev.Models.localData, 'change:recentEaiaSearch', this.onRecentEaiaSearchChanged);
      this.listenTo(Rev, 'property-360:search:clear', this.clearAddress);
    },


    events: {
      'keypress [data-hook="eaia-location"]': 'onLocationInputKeypress',
      'typeahead:select [data-hook="eaia-location"]': 'onSuggestionSelect',
      'typeahead:autocomplete [data-hook="eaia-location"]': 'onSuggestionAutoComplete',
      'typeahead:render [data-hook="eaia-location"]': 'onSuggestionRender',
      'click .btn-delete-history-item': 'onDeleteHistoryItemClick',
      'click [data-hook="btn-submit-eaia-search"]': 'onSearchButtonClick',
      'click [data-hook="open-3comps-video"]': 'onYoutubeVideoClick'
    },

    onYoutubeVideoClick: function onYoutubeVideoClick(e) {
      e.preventDefault();
      e.stopPropagation();
      Rev.Utils.showYoutubeModal("https://www.youtube.com/embed/SaOTsFU5q5w");
    },

    clearAddress: function clearAddress() {
      // delete user entered text
      this.$('.tt-input').val('');
      // delete real value of typeahead input
      this.$typeahead.typeahead('val', '');
    },
    onDeleteHistoryItemClick: function onDeleteHistoryItemClick(e) {
      e.preventDefault();
      e.stopPropagation();

      var self = this;

      // we need this flag because of crazy typeahead event on suggestion item
      // we cannot put event on elements inside suggestion item(.tt-suggestion)
      // e.g. when you click delete history button typeahead:select event handler executed first and then delete history button click event handler executed
      // so in order to capture only click event we need to use flag which is isDeleting 
      this.isDeleting = true;

      var $current = this.$(e.currentTarget);
      var item = {
        AddressText: $current.data('addresstext'),
        AddressType: $current.data('addresstype'),
        SeoSlug: $current.data('seoslug')
      };

      Rev.Models.localData.deleteRecentEaiaSearch(item);

      // delete user entered text
      self.$('.tt-input').val('');

      // delete item and keep suggestion dropdown open
      if (self.$('.tt-dataset-eaia-locations-recent .eaia-suggestion-item').length > 1) {
        // note that it should be 1 not zero, because it is before deleting item from suggestion dropdown
        self.$typeahead.typeahead('open');
      }

      // delete row from suggestion dropdown
      $current.closest('.eaia-suggestion-item').fadeOut('slow', function () {
        $current.closest('.eaia-suggestion-item').remove();
      });

      // fix the suggestion text comes again in textbox when there is only 1 item left in the suggestions dropbox
      if (self.$('.tt-dataset-eaia-locations-recent .eaia-suggestion-item').length === 1) {
        self.$typeahead.typeahead('val', '');
      }
    },


    // this will be executed when local data change
    onRecentEaiaSearchChanged: function onRecentEaiaSearchChanged(model) {
      this.recentSuggestionsData = _.sortBy(model.get('recentEaiaSearch'), 'AddressText');
    },
    onSuggestionRender: function onSuggestionRender(e, suggestions, isAsync, datasetname) {
      // note that suggestions parameter has only top suggestion object value not all the suggestions on dropdown. weird behavour :)
      if (suggestions) {
        if (suggestions.isFromHistory) {
          this.topSuggestionFromApi = suggestions;
        } else {
          this.topSuggestionFromHistory = suggestions;
        }
      }
    },


    // this event hadnlers will be executed when user press tab key to complete hint. this won't be fired when user select item from suggestion dropdown
    onSuggestionAutoComplete: function onSuggestionAutoComplete(e, item) {
      //this.moveToEaiaPages(item);
      this.onAddressSearchCompleteHandler(item);
    },


    // this event handlers will be executed when user select one from suggestion dropdwon by mouse or arrow key
    onSuggestionSelect: function onSuggestionSelect(e, item) {
      e.preventDefault();
      e.stopPropagation();
      var self = this;

      setTimeout(function () {
        if (self.isDeleting) {
          self.isDeleting = false;
          return;
        } else {
          //self.moveToEaiaPages(item);
          self.onAddressSearchCompleteHandler(item);
        }
      }, 100);
    },
    onSearchButtonClick: function onSearchButtonClick(e) {
      var _this = this;

      setTimeout(function () {
        return _this.startSearch();
      }, 100); // give a buffer just in case user copy and paste into input textbox
    },


    // use this event to capture enter key press 
    onLocationInputKeypress: function onLocationInputKeypress(e) {
      if (e.which == 13) {
        this.startSearch();
      }
    },
    startSearch: function startSearch() {

      $('[data-hook="btn-submit-eaia-search"]').button('loading');

      // if no items selected and typed some text, get first item in suggestions
      // remove begining/end space and replace multiple spaces with single space
      var enteredText = this.$typeahead.typeahead('val') ? this.$typeahead.typeahead('val').trim().replace(/ +/g, ' ') : null;
      var hintText = this.$('.tt-hint[data-hook="eaia-location"]').val() ? this.$('.tt-hint[data-hook="eaia-location"]').val().trim().replace(/ +/g, ' ') : null;

      // validation
      this.$('.message-location-required, .message-no-result').fadeOut();
      if (!enteredText) {
        this.$('.message-location-required').fadeIn();
      }

      if (enteredText && hintText && hintText.toLowerCase().indexOf(enteredText.toLowerCase()) >= 0) {
        this.$typeahead.typeahead('val', hintText);

        // check first if it matches with top suggestion from api
        if (this.topSuggestionFromApi && this.topSuggestionFromApi.AddressText && this.topSuggestionFromApi.AddressText.toLowerCase() === hintText.toLowerCase()) {
          this.onAddressSearchCompleteHandler(this.topSuggestionFromApi);
          return;
        }

        // also check first if it matches with top suggestion from history
        if (this.topSuggestionFromHistory && this.topSuggestionFromHistory.AddressText && this.topSuggestionFromHistory.AddressText.toLowerCase() === hintText.toLowerCase()) {
          this.onAddressSearchCompleteHandler(this.topSuggestionFromHistory);
          return;
        }
      } else if (enteredText && !hintText) {
        // this is the case user entered text and already completed hint text

        // check first if it matches with top suggestion from api
        if (this.topSuggestionFromApi && this.topSuggestionFromApi.AddressText && this.topSuggestionFromApi.AddressText.toLowerCase().indexOf(enteredText.toLowerCase()) >= 0) {
          this.onAddressSearchCompleteHandler(this.topSuggestionFromApi);
          return;
        }

        // also check first if it matches with top suggestion from history
        if (this.topSuggestionFromHistory && this.topSuggestionFromHistory.AddressText && this.topSuggestionFromHistory.AddressText.toLowerCase().indexOf(enteredText.toLowerCase()) >= 0) {
          this.onAddressSearchCompleteHandler(this.topSuggestionFromHistory);
          return;
        }

        // no result from suggestion api        
        this.$('.message-no-result').fadeIn();
        $('[data-hook="btn-submit-eaia-search"]').button('reset');
        return;
      }

      $('[data-hook="btn-submit-eaia-search"]').button('reset');
    },
    moveToEaiaPages: function moveToEaiaPages(suggestionItem) {
      if (suggestionItem && suggestionItem.DetailsPageUrl) {
        var targetUrl = suggestionItem.DetailsPageUrl;

        Rev.Models.localData.saveRecentEaiaSearch(suggestionItem);

        Rev.Utils.GaTracking.trackGaEvent(this.options.gaCategory, this.options.gaAction, Rev.Utils.GaTracking.Label.SearchProperty360Address);

        setTimeout(function () {
          return window.open(targetUrl, '_self');
        }, 50);
      }
    },
    checkSuggestionQuery: function checkSuggestionQuery(query) {
      var minLength = 4;

      // remove space, 'unit', 'lot' for min length check
      var q = query.replace(/\s+/ig, '');
      q = q.replace(/unit/ig, '');
      q = q.replace(/lot/ig, '');

      if (q.length >= minLength) {
        return true;
      }

      return false;
    },
    initializeBloodHound: function initializeBloodHound() {
      var self = this;

      this.locationSuggestions = new Bloodhound({
        datumTokenizer: Bloodhound.tokenizers.obj.whitespace,
        queryTokenizer: Bloodhound.tokenizers.whitespace,
        remote: {
          url: '/property-360/eaia-search-location/?searchText=%QUERY',
          replace: function replace(url, query) {
            var query = query ? query.trim() : null;
            var sendQuery = self.checkSuggestionQuery(query);
            if (sendQuery) {
              return url.replace("%QUERY", query);
            }
          },
          transform: function transform(response) {
            // filter if the suggestion item exists in localstorage history
            Rev.Models.localData.fetch();
            var history = Rev.Models.localData.get('recentEaiaSearch');

            if (response && history) {
              response = _.filter(response, function (item) {
                return !_.find(history, function (historyItem) {
                  return historyItem.AddressText.toLowerCase() === item.AddressText.toLowerCase();
                });
              });
            }

            return response;
          }
        }
      });

      this.locationSuggestions.initialize();
    },
    recentSuggestions: function recentSuggestions() {
      var self = this;
      return function findMatches(q, cb) {
        // an array that will be populated with substring matches
        var matches = [];

        // iterate through the pool of strings and for any string that
        // starts with `q`, add it to the `matches` array
        _.each(self.recentSuggestionsData, function (item) {
          if (item.AddressText.toLowerCase().indexOf(q.toLowerCase()) == 0) {
            matches.push(item);
          }
        });

        cb(matches);
      };
    },
    initializeLocationTypeahead: function initializeLocationTypeahead() {
      var template = _.template($('#eaia-suggestion-location-item').html());
      var templateHistory = _.template($('#eaia-suggestion-location-item-history').html());

      this.$typeahead = this.$('[data-hook="eaia-location"]').typeahead({
        minLength: 1,
        hint: true,
        highlight: true,
        autoselect: true
      }, {
        name: 'eaia-locations-recent',
        source: this.recentSuggestions(),
        limit: 5,
        display: 'AddressText',
        templates: {
          //header: '<h3 class="eaia-locations-header">From history</h3>',
          suggestion: function suggestion(item) {
            var html = templateHistory({ addressText: item.AddressText, addressTypeText: item.AddressTypeText, addressType: item.AddressType, seoSlug: item.SeoSlug });
            return html;
          }
        }
      }, {
        name: 'eaia-locations',
        source: this.locationSuggestions.ttAdapter(),
        limit: 10,
        display: 'AddressText',
        templates: {
          //header: '<h3 class="eaia-locations-header from-api">From API</h3>',
          suggestion: function suggestion(item) {
            var html = template({ addressText: item.AddressText, addressTypeText: item.AddressTypeText });
            return html;
          }
        }
      });
    }
  });
})(Rev, jQuery, _, Backbone);
'use strict';

var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };

(function (Rev, $, _, Backbone) {

  'use strict';

  Rev.Views.EaiaViewHomeLoansView = Backbone.View.extend({
    initialize: function initialize(options) {
      this.options = _extends({}, options);
    },


    events: {
      'click .js-view-home-loans-360-banner': 'onHomeLoans360BammerClick'
    },

    onHomeLoans360BammerClick: function onHomeLoans360BammerClick(e) {
      Rev.Utils.GaTracking.trackGaEvent(this.options.gaCategory, Rev.Utils.GaTracking.Action.ViewHomeLoan360BannerClick, this.options.sa1Id + ' + ' + this.options.seoSlug);
    }
  });
})(Rev, jQuery, _, Backbone);
"use strict";

var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }

function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

// dependencies : Rev, jquery, underscore, backbone

(function (Rev, $, _, Backbone) {
  var CardView = function (_React$PureComponent) {
    _inherits(CardView, _React$PureComponent);

    function CardView(props) {
      _classCallCheck(this, CardView);

      var _this = _possibleConstructorReturn(this, (CardView.__proto__ || Object.getPrototypeOf(CardView)).call(this, props));

      _this.initSlick = _this.initSlick.bind(_this);
      _this.unSlick = _this.unSlick.bind(_this);
      return _this;
    }

    _createClass(CardView, [{
      key: "shouldComponentUpdate",
      value: function shouldComponentUpdate(nextProps, nextState) {
        var currentPropsImmutable = Immutable.fromJS(this.props);
        var nextPropsImmutable = Immutable.fromJS(nextProps);
        return !currentPropsImmutable.equals(nextPropsImmutable);
      }
    }, {
      key: "componentDidMount",
      value: function componentDidMount() {
        this.initSlick();
      }
    }, {
      key: "componentWillUnmount",
      value: function componentWillUnmount() {
        this.unSlick();
      }
    }, {
      key: "componentWillUpdate",
      value: function componentWillUpdate(nextProps, nextState) {
        this.unSlick(); // unslick and slick again during update this component will fix the bug "Failed to execute 'removeChild' on 'Node': The node to be removed is not a child of this node"
      }
    }, {
      key: "componentDidUpdate",
      value: function componentDidUpdate(prevProps, prevState) {
        this.initSlick();
      }
    }, {
      key: "render",
      value: function render() {
        var _this2 = this;

        var rootClassNames = classNames("three-comps-card", {
          "three-comps-card--replace-mode": this.props.listing.IsReplaceMode,
          "three-comps-card--edit-attr-mode": this.props.listing.IsEditAttrMode,
          "three-comps-card--just-replaced": this.props.listing.justReplaced,
          "three-comps-card--just-edited": this.props.listing.justEdited,
          "three-comps-card--dummy": this.props.listing.IsDummyListing
        });

        var price = '$ -';
        if (this.props.listing.Price) {
          price = "$" + Rev.Utils.String.numberWithCommas(this.props.listing.Price);
        }

        var soldDate = '';
        if (this.props.listing.SoldDateInLocalTimeText) {
          soldDate = "Sold " + this.props.listing.SoldDateInLocalTimeText;
        }

        var beds = '-';
        if (this.props.listing.Attributes && this.props.listing.Attributes.NumberOfBedrooms) {
          beds = this.props.listing.Attributes.NumberOfBedrooms;
        }

        var baths = '-';
        if (this.props.listing.Attributes && this.props.listing.Attributes.NumberOfBathrooms) {
          baths = this.props.listing.Attributes.NumberOfBathrooms;
        }

        var carparks = '-';
        if (this.props.listing.Attributes && this.props.listing.Attributes.NumberOfParking) {
          carparks = this.props.listing.Attributes.NumberOfParking;
        }

        var landsize = '-';
        if (this.props.listing.Attributes && this.props.listing.Attributes.LandAreaSqm && this.props.listing.Attributes.DisplayLandSize) {
          landsize = this.props.listing.Attributes.LandAreaSqm;
        }

        var photos = null;
        if (this.props.listing.Photos && this.props.listing.Photos.length) {
          photos = this.props.listing.Photos.map(function (photo) {
            return React.createElement("div", { key: photo.Url,
              className: "three-comps-card__photo-box",
              style: { backgroundImage: "url(" + photo.Url + ")" },
              onClick: _this2.onPhotoClick.bind(_this2) });
          });
        } else {
          photos = React.createElement(
            "div",
            { className: "no-image-available-wrapper" },
            React.createElement(
              "div",
              { className: "no-image-available" },
              React.createElement("img", { src: "/assets/content/images/no-photo.png", className: "no-photo-image" })
            )
          );
        }

        var navPhotoButtons = null;
        if (this.props.listing.Photos && this.props.listing.Photos.length >= 2) {
          navPhotoButtons = React.createElement(
            "div",
            null,
            React.createElement("button", { className: "icon-icon-arrow-thin three-comps-card__arrow-left", onClick: this.onNavPhotoLeftClick.bind(this) }),
            React.createElement("button", { className: "icon-icon-arrow-thin three-comps-card__arrow-right", onClick: this.onNavPhotoRightClick.bind(this) })
          );
        }

        var replaceButton = null;
        if (!this.props.listing.IsReplaceMode) {
          replaceButton = React.createElement(
            "a",
            { href: "#", className: "three-comps-card__action-replace", onClick: this.onReplaceClick.bind(this), disabled: this.props.listing.IsEditAttrMode },
            React.createElement(
              "i",
              { className: "material-icons" },
              "\uE040"
            ),
            " ",
            React.createElement(
              "span",
              null,
              "Replace"
            )
          );
        }

        var doneReplaceButton = null;
        if (this.props.listing.IsReplaceMode) {
          doneReplaceButton = React.createElement(
            "a",
            { href: "#", className: "three-comps-card__action-done", onClick: this.onDoneReplaceClick.bind(this) },
            React.createElement(
              "i",
              { className: "material-icons" },
              "\uE876"
            ),
            " ",
            React.createElement(
              "span",
              null,
              "Done"
            )
          );
        }

        var deleteButton = null;
        if (this.props.listing.IsReplaceMode && !this.props.listing.IsDummyListing) {
          deleteButton = React.createElement(
            "a",
            { href: "#", className: "three-comps-card__action-delete", onClick: this.onDeleteClick.bind(this) },
            React.createElement(
              "i",
              { className: "material-icons" },
              "\uE872"
            ),
            " ",
            React.createElement(
              "span",
              null,
              "Remove"
            )
          );
        }

        var editButton = null;
        if (!this.props.listing.IsEditAttrMode) {
          editButton = React.createElement(
            "a",
            { href: "#", className: "three-comps-card__action-edit-attr",
              onClick: this.onEditAttributesClick.bind(this),
              disabled: this.props.listing.IsReplaceMode || this.props.listing.IsDummyListing },
            React.createElement(
              "i",
              { className: "material-icons" },
              "\uE254"
            ),
            React.createElement(
              "span",
              null,
              "Edit Attributes"
            )
          );
        }

        var doneEditAttrButton = null;
        if (this.props.listing.IsEditAttrMode) {
          doneEditAttrButton = React.createElement(
            "a",
            { href: "#", className: "three-comps-card__action-done", onClick: this.onDoneEditAttrClick.bind(this) },
            React.createElement(
              "i",
              { className: "material-icons" },
              "\uE876"
            ),
            " ",
            React.createElement(
              "span",
              null,
              "Done"
            )
          );
        }

        return React.createElement(
          "div",
          { className: rootClassNames },
          React.createElement(
            "div",
            { className: "three-comps-card__content" },
            React.createElement(
              "div",
              { className: "three-comps-card__photos-wrapper" },
              React.createElement(
                "div",
                { className: "three-comps-card__photos", ref: "photos" },
                photos
              ),
              navPhotoButtons
            ),
            React.createElement(
              "div",
              { className: "three-comps-card__property-info-box" },
              React.createElement(
                "div",
                { className: "three-comps-card__price" },
                React.createElement(
                  "span",
                  { className: "three-comps-card__price-text" },
                  price
                ),
                React.createElement(
                  "span",
                  { className: "three-comps-card__sold-date" },
                  soldDate
                )
              ),
              React.createElement(
                "div",
                { className: "three-comps-card__address", title: "2/218 Princess Street, Kew, VIC 3101" },
                this.props.listing.Address.AddressText
              ),
              React.createElement(
                "div",
                { className: "three-comps-card__rooms" },
                React.createElement(
                  "span",
                  null,
                  React.createElement(
                    "span",
                    { className: "three-comps-card__number" },
                    beds
                  ),
                  "Beds"
                ),
                React.createElement(
                  "span",
                  null,
                  React.createElement(
                    "span",
                    { className: "three-comps-card__number" },
                    baths
                  ),
                  "Baths"
                ),
                React.createElement(
                  "span",
                  null,
                  React.createElement(
                    "span",
                    { className: "three-comps-card__number" },
                    carparks
                  ),
                  "Car"
                ),
                React.createElement(
                  "span",
                  null,
                  React.createElement(
                    "span",
                    { className: "three-comps-card__number" },
                    landsize
                  ),
                  "sqm"
                )
              )
            ),
            React.createElement(
              "div",
              { className: "three-comps-card__action-buttons" },
              replaceButton,
              doneReplaceButton,
              deleteButton,
              editButton,
              doneEditAttrButton
            )
          )
        );
      }
    }, {
      key: "onPhotoClick",
      value: function onPhotoClick(e) {
        e.preventDefault();
        var photos = _.map(this.props.listing.Photos, function (photo) {
          return photo.Url;
        });
        Rev.Utils.showPhotoGalleryModal(this.props.listing.Address.AddressText, photos, photos);
      }
    }, {
      key: "initSlick",
      value: function initSlick() {
        if (this.props.listing.Photos && this.props.listing.Photos.length >= 2) {
          var photosEl = ReactDOM.findDOMNode(this.refs.photos);
          this.slickInstance = Rev.Utils.initSlick($(photosEl), {
            slidesToShow: 1,
            slidesToScroll: 1,
            centerPadding: '0px'
          });
        }
      }
    }, {
      key: "unSlick",
      value: function unSlick() {
        this.slickInstance && this.slickInstance.slick('unslick');
      }
    }, {
      key: "onAddListingClick",
      value: function onAddListingClick(e) {
        e.preventDefault();
        this.props.onAddListingClick(this.props.listing);
      }
    }, {
      key: "onReplaceClick",
      value: function onReplaceClick(e) {
        e.preventDefault();
        this.props.onReplaceClick(this.props.listing);
      }
    }, {
      key: "onDoneReplaceClick",
      value: function onDoneReplaceClick(e) {
        e.preventDefault();
        this.props.onDoneReplaceClick(this.props.listing);
      }
    }, {
      key: "onEditAttributesClick",
      value: function onEditAttributesClick(e) {
        e.preventDefault();
        this.props.onEditAttributesClick(this.props.listing);
      }
    }, {
      key: "onDoneEditAttrClick",
      value: function onDoneEditAttrClick(e) {
        e.preventDefault();
        this.props.onDoneEditAttrClick(this.props.listing);
      }
    }, {
      key: "onDeleteClick",
      value: function onDeleteClick(e) {
        e.preventDefault();
        this.props.onDeleteClick(this.props.listing);
      }
    }, {
      key: "onNavPhotoLeftClick",
      value: function onNavPhotoLeftClick(e) {
        e.preventDefault();
        this.slickInstance && this.slickInstance.slick('slickPrev');
      }
    }, {
      key: "onNavPhotoRightClick",
      value: function onNavPhotoRightClick(e) {
        e.preventDefault();
        this.slickInstance && this.slickInstance.slick('slickNext');
      }
    }]);

    return CardView;
  }(React.PureComponent);

  CardView.propTypes = {
    listing: React.PropTypes.object.isRequired,
    onReplaceClick: React.PropTypes.func.isRequired,
    onDoneReplaceClick: React.PropTypes.func.isRequired,
    onEditAttributesClick: React.PropTypes.func.isRequired,
    onDoneEditAttrClick: React.PropTypes.func.isRequired,
    onAddListingClick: React.PropTypes.func.isRequired,
    onDeleteClick: React.PropTypes.func.isRequired
  };


  Rev.Views.ThreeComps.CardView = CardView;
})(Rev, jQuery, _, Backbone);
"use strict";

var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }

function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

// dependencies : Rev, jquery, underscore, backbone

(function (Rev, $, _, Backbone) {
  var CardsView = function (_React$PureComponent) {
    _inherits(CardsView, _React$PureComponent);

    function CardsView(props) {
      _classCallCheck(this, CardsView);

      return _possibleConstructorReturn(this, (CardsView.__proto__ || Object.getPrototypeOf(CardsView)).call(this, props));
    }

    _createClass(CardsView, [{
      key: "render",
      value: function render() {
        var _this2 = this;

        var listings = this.props.data.map(function (listing) {
          return React.createElement(Rev.Views.ThreeComps.CardView, {
            key: listing.Address.GnafAddressId,
            listing: listing,
            onReplaceClick: _this2.props.onReplaceClick,
            onDoneReplaceClick: _this2.props.onDoneReplaceClick,
            onEditAttributesClick: _this2.props.onEditAttributesClick,
            onDoneEditAttrClick: _this2.props.onDoneEditAttrClick,
            onAddListingClick: _this2.props.onAddListingClick,
            onDeleteClick: _this2.props.onDeleteClick
          });
        });

        return React.createElement(
          "div",
          { className: "panel-body" },
          listings
        );
      }
    }]);

    return CardsView;
  }(React.PureComponent);

  CardsView.propTypes = {
    data: React.PropTypes.array,
    onReplaceClick: React.PropTypes.func.isRequired,
    onEditAttributesClick: React.PropTypes.func.isRequired,
    onAddListingClick: React.PropTypes.func.isRequired,
    onDoneReplaceClick: React.PropTypes.func.isRequired,
    onDoneEditAttrClick: React.PropTypes.func.isRequired,
    onDeleteClick: React.PropTypes.func.isRequired
  };


  Rev.Views.ThreeComps.CardsView = CardsView;
})(Rev, jQuery, _, Backbone);
"use strict";

var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };

var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }

function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

// dependencies : Rev, jquery, underscore, backbone

(function (Rev, $, _, Backbone) {
  var ConfirmCompsView = function (_React$PureComponent) {
    _inherits(ConfirmCompsView, _React$PureComponent);

    function ConfirmCompsView(props) {
      _classCallCheck(this, ConfirmCompsView);

      var _this = _possibleConstructorReturn(this, (ConfirmCompsView.__proto__ || Object.getPrototypeOf(ConfirmCompsView)).call(this, props));

      _this.state = _extends({ isOpen: false }, props);
      _this.onAreaTypeChanged = _this.onAreaTypeChanged.bind(_this);
      return _this;
    }

    _createClass(ConfirmCompsView, [{
      key: "componentWillReceiveProps",
      value: function componentWillReceiveProps(nextProps) {
        var newProps = _extends({}, this.state, nextProps);
        this.setState(newProps, this.toggleBodyScroll.bind(this));
      }
    }, {
      key: "shouldComponentUpdate",
      value: function shouldComponentUpdate(nextProps, nextState) {
        var currentStateImmutable = Immutable.fromJS(this.state);
        var nextStateImmutable = Immutable.fromJS(nextState);
        var isDifferent = !currentStateImmutable.equals(nextStateImmutable);
        return isDifferent;
      }
    }, {
      key: "render",
      value: function render() {
        var _this2 = this;

        var rootClassNames = classNames("confirm-comps", {
          "confirm-comps--open": this.props.isOpen
        });

        var popupTitle = this.props.isLessThanThreeComparables ? React.createElement(
          "span",
          null,
          "Less than 3 Comparables"
        ) : React.createElement(
          "span",
          null,
          "Confirm Comparables"
        );

        var option1 = this.props.isLessThanThreeComparables ? React.createElement(
          "span",
          null,
          "The estate agent or agent's representative reasonably believes that fewer than three comparable properties were sold within two kilometres of the property for sale in the last six months"
        ) : React.createElement(
          "span",
          null,
          "These are the three properties sold within two kilometres of the property for sale in the last six months that the estate agent or agent\u2019s representative considers to be most comparable to the property for sale"
        );

        var option2 = this.props.isLessThanThreeComparables ? React.createElement(
          "span",
          null,
          "The estate agent or agent's representative reasonably believes that fewer than three comparable properties were sold within five kilometres of the property for sale in the last 18 months"
        ) : React.createElement(
          "span",
          null,
          "These are the three properties sold within five kilometres of the property for sale in the last 18 months that the estate agent or agent\u2019s representative considers to be most comparable to the property for sale"
        );

        return React.createElement(
          "div",
          { className: rootClassNames },
          React.createElement(
            "div",
            { className: "confirm-comps__content" },
            React.createElement(
              "div",
              { className: "confirm-comps__header" },
              popupTitle,
              React.createElement(
                "span",
                { className: "btn-close", onClick: function onClick() {
                    return _this2.props.onConfirmCancelClick();
                  } },
                React.createElement(
                  "i",
                  { className: "material-icons" },
                  "\uE5CD"
                )
              )
            ),
            React.createElement(
              "div",
              { className: "confirm-comps__body" },
              React.createElement(
                "div",
                { className: "confirm-options" },
                React.createElement(
                  "div",
                  { className: "radio" },
                  React.createElement(
                    "label",
                    null,
                    React.createElement("input", { type: "radio", name: "areaType", value: "1", checked: this.state.areaType == 1, onChange: this.onAreaTypeChanged }),
                    React.createElement(
                      "i",
                      { className: "material-icons checked" },
                      "\uE39E"
                    ),
                    React.createElement(
                      "i",
                      { className: "material-icons unchecked" },
                      "\uE40C"
                    ),
                    option1
                  )
                ),
                React.createElement(
                  "div",
                  { className: "radio" },
                  React.createElement(
                    "label",
                    null,
                    React.createElement("input", { type: "radio", name: "areaType", value: "2", checked: this.state.areaType == 2, onChange: this.onAreaTypeChanged }),
                    React.createElement(
                      "i",
                      { className: "material-icons checked" },
                      "\uE39E"
                    ),
                    React.createElement(
                      "i",
                      { className: "material-icons unchecked" },
                      "\uE40C"
                    ),
                    option2
                  )
                )
              )
            ),
            React.createElement(
              "div",
              { className: "confirm-comps__footer" },
              React.createElement(
                "button",
                { className: "btn btn-primary btn-thin", onClick: function onClick() {
                    return _this2.props.onConfirmSaveClick();
                  } },
                "Save"
              ),
              React.createElement(
                "button",
                { className: "btn btn-default btn-no-border", onClick: function onClick() {
                    return _this2.props.onConfirmCancelClick();
                  } },
                "Cancel"
              )
            )
          )
        );
      }
    }, {
      key: "onAreaTypeChanged",
      value: function onAreaTypeChanged(e) {
        var _this3 = this;

        this.setState({ areaType: e.currentTarget.value }, function () {
          return _this3.props.onAreaTypeChangeHandler(_this3.state.areaType);
        });
      }
    }, {
      key: "toggleBodyScroll",
      value: function toggleBodyScroll() {
        $('body').css({ 'overflow': '' });

        if (this.state.isOpen) {
          $('body').css({ 'overflow': 'hidden' });
          $('.listing-agent-section').length && $('.listing-agent-section').hide();
        }
      }
    }]);

    return ConfirmCompsView;
  }(React.PureComponent);

  ConfirmCompsView.propTypes = {
    isOpen: React.PropTypes.bool,
    isLessThanThreeComparables: React.PropTypes.bool,
    areaType: React.PropTypes.number,
    onConfirmCancelClick: React.PropTypes.func,
    onConfirmSaveClick: React.PropTypes.func,
    onAreaTypeChangeHandler: React.PropTypes.func
  };


  Rev.Views.ThreeComps.ConfirmCompsView = ConfirmCompsView;
})(Rev, jQuery, _, Backbone);
'use strict';

var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };

var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }

function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

// dependencies : Rev, jquery, underscore, backbone

(function (Rev, $, _, Backbone) {
  var EditView = function (_React$PureComponent) {
    _inherits(EditView, _React$PureComponent);

    function EditView(props) {
      _classCallCheck(this, EditView);

      var _this = _possibleConstructorReturn(this, (EditView.__proto__ || Object.getPrototypeOf(EditView)).call(this, props));

      _this.state = _extends({
        Address: {
          AddressText: ''
        },
        Price: '',
        SoldDateInLocalTimeText: '',
        Attributes: {
          NumberOfBedrooms: '',
          NumberOfBathrooms: '',
          NumberOfParking: '',
          PropertyType: ''
        },
        OpenGallery: false
      }, props.listing);
      _this.onInputChange = _this.onInputChange.bind(_this);
      _this.onDateChanged = _this.onDateChanged.bind(_this);
      return _this;
    }

    _createClass(EditView, [{
      key: 'shouldComponentUpdate',
      value: function shouldComponentUpdate(nextProps, nextState) {
        var currentStateImmutable = Immutable.fromJS(this.state);
        var nextStateImmutable = Immutable.fromJS(nextState);
        return !currentStateImmutable.equals(nextStateImmutable);
      }
    }, {
      key: 'componentWillReceiveProps',
      value: function componentWillReceiveProps(nextProps) {
        var newProps = _extends({}, this.state, nextProps.listing);
        this.replaceNullWithEmptyString(newProps);
        this.setState(newProps);
      }
    }, {
      key: 'componentDidMount',
      value: function componentDidMount() {
        $(this.refs.soldDate).datepicker({ format: 'M d, yyyy' }).on('changeDate', this.onDateChanged);
      }
    }, {
      key: 'render',
      value: function render() {
        return React.createElement(
          'div',
          { className: 'edit-attr-view' },
          React.createElement(
            'div',
            { className: 'edit-attr-view__heading' },
            React.createElement(
              'span',
              null,
              'Edit Attributes'
            )
          ),
          React.createElement(
            'table',
            { className: 'table' },
            React.createElement(
              'thead',
              null,
              React.createElement(
                'tr',
                null,
                React.createElement(
                  'th',
                  null,
                  'Images*'
                ),
                React.createElement(
                  'th',
                  null,
                  'Address'
                ),
                React.createElement(
                  'th',
                  null,
                  'Sale Price*'
                ),
                React.createElement(
                  'th',
                  null,
                  'Sale Date*'
                ),
                React.createElement(
                  'th',
                  null,
                  'Type*'
                ),
                React.createElement(
                  'th',
                  null,
                  'Beds*'
                ),
                React.createElement(
                  'th',
                  null,
                  'Baths*'
                ),
                React.createElement(
                  'th',
                  null,
                  'Cars'
                )
              )
            ),
            React.createElement(
              'tbody',
              null,
              React.createElement(
                'tr',
                null,
                React.createElement(
                  'td',
                  { className: 'col-image' },
                  React.createElement(
                    'a',
                    { href: '#', onClick: this.onPhotoIconClick.bind(this) },
                    React.createElement(
                      'i',
                      { className: "material-icons " + (this.props.listing.Photos && this.props.listing.Photos.length >= 1 ? "" : "no-photo") },
                      '\uE439'
                    ),
                    React.createElement(
                      'span',
                      null,
                      this.props.listing.Photos && this.props.listing.Photos.length
                    )
                  )
                ),
                React.createElement(
                  'td',
                  { className: 'col-address' },
                  React.createElement(
                    'span',
                    null,
                    this.state.Address.AddressText
                  )
                ),
                React.createElement(
                  'td',
                  { className: 'col-price' },
                  React.createElement('input', { type: 'number', value: this.state.Price, name: 'Price', onChange: this.onInputChange })
                ),
                React.createElement(
                  'td',
                  { className: 'col-sold-date' },
                  React.createElement('input', { type: 'text', value: this.state.SoldDateInLocalTimeText, name: 'SoldDateInLocalTimeText', ref: 'soldDate', onChange: this.onDateChanged })
                ),
                React.createElement(
                  'td',
                  { className: 'col-property-type' },
                  React.createElement(
                    'select',
                    { value: this.state.Attributes && this.state.Attributes.PropertyType, onChange: this.onPropertyTypeChange.bind(this) },
                    React.createElement('option', { value: '' }),
                    React.createElement(
                      'option',
                      { value: 'House' },
                      'House'
                    ),
                    React.createElement(
                      'option',
                      { value: 'Unit' },
                      'Unit'
                    ),
                    React.createElement(
                      'option',
                      { value: 'Apartment' },
                      'Apartment'
                    ),
                    React.createElement(
                      'option',
                      { value: 'Studio' },
                      'Studio'
                    ),
                    React.createElement(
                      'option',
                      { value: 'Townhouse' },
                      'Townhouse'
                    ),
                    React.createElement(
                      'option',
                      { value: 'Villa' },
                      'Villa'
                    )
                  )
                ),
                React.createElement(
                  'td',
                  { className: 'col-bedrooms' },
                  React.createElement('input', { type: 'number', min: '0', max: '30', value: this.state.Attributes && this.state.Attributes.NumberOfBedrooms, onChange: this.onNumberOfBedroomsChange.bind(this), onKeyPress: this.validateNumer.bind(this) })
                ),
                React.createElement(
                  'td',
                  { className: 'col-bathrooms' },
                  React.createElement('input', { type: 'number', min: '0', max: '30', value: this.state.Attributes && this.state.Attributes.NumberOfBathrooms, onChange: this.onNumberOfBathroomsChange.bind(this), onKeyPress: this.validateNumer.bind(this) })
                ),
                React.createElement(
                  'td',
                  { className: 'col-carparks' },
                  React.createElement('input', { type: 'number', min: '0', max: '30', value: this.state.Attributes && this.state.Attributes.NumberOfParking, onChange: this.onNumberOfParkingChange.bind(this), onKeyPress: this.validateNumer.bind(this) })
                )
              )
            )
          )
        );
      }
    }, {
      key: 'replaceNullWithEmptyString',
      value: function replaceNullWithEmptyString(listing) {
        if (!listing) return;

        if (listing.Address && listing.Address.AddressText === null) listing.Address.AddressText = '';
        if (listing.Price === null) listing.Price = '';
        if (listing.SoldDateInLocalTimeText === null) listing.SoldDateInLocalTimeText = '';
        if (listing.Attributes) {
          if (listing.Attributes.NumberOfBedrooms === null) listing.Attributes.NumberOfBedrooms = '';
          if (listing.Attributes.NumberOfBathrooms === null) listing.Attributes.NumberOfBathrooms = '';
          if (listing.Attributes.NumberOfParking === null) listing.Attributes.NumberOfParking = '';
          if (listing.Attributes.PropertyType === null) listing.Attributes.PropertyType = '';
        }
      }
    }, {
      key: 'onDateChanged',
      value: function onDateChanged(e) {
        var _this2 = this;

        var dateChanged = moment(e.date).format('MMM D YYYY');
        if (this.state.SoldDateInLocalTimeText !== dateChanged) {
          this.setState({ SoldDateInLocalTimeText: dateChanged }, function () {
            return _this2.props.onAttributesChangeHandler(_this2.state);
          });
        }
      }
    }, {
      key: 'onNumberOfBedroomsChange',
      value: function onNumberOfBedroomsChange(event) {
        var _this3 = this;

        var target = event.target;
        var value = target.type === 'checkbox' ? target.checked : target.value;

        if (parseInt(value) != NaN) {
          value = parseInt(value) < 0 ? Math.abs(value) : parseInt(value) > 30 ? 30 : value;
        }

        if (this.state.Attributes.NumberOfBedrooms !== value) {
          var attributes = _extends({}, this.state.Attributes, { NumberOfBedrooms: value });
          this.setState(_extends({}, this.state, { Attributes: attributes }), function () {
            return _this3.props.onAttributesChangeHandler(_this3.state);
          });
        }
      }
    }, {
      key: 'onNumberOfBathroomsChange',
      value: function onNumberOfBathroomsChange(event) {
        var _this4 = this;

        var target = event.target;
        var value = target.type === 'checkbox' ? target.checked : target.value;

        if (parseInt(value) != NaN) {
          value = parseInt(value) < 0 ? Math.abs(value) : parseInt(value) > 30 ? 30 : value;
        }

        if (this.state.Attributes.NumberOfBathrooms !== value) {
          var attributes = _extends({}, this.state.Attributes, { NumberOfBathrooms: value });
          this.setState(_extends({}, this.state, { Attributes: attributes }), function () {
            return _this4.props.onAttributesChangeHandler(_this4.state);
          });
        }
      }
    }, {
      key: 'onNumberOfParkingChange',
      value: function onNumberOfParkingChange(event) {
        var _this5 = this;

        var target = event.target;
        var value = target.type === 'checkbox' ? target.checked : target.value;

        if (parseInt(value) != NaN) {
          value = parseInt(value) < 0 ? Math.abs(value) : parseInt(value) > 30 ? 30 : value;
        }

        if (this.state.Attributes.NumberOfParking !== value) {
          var attributes = _extends({}, this.state.Attributes, { NumberOfParking: value });
          this.setState(_extends({}, this.state, { Attributes: attributes }), function () {
            return _this5.props.onAttributesChangeHandler(_this5.state);
          });
        }
      }
    }, {
      key: 'onPropertyTypeChange',
      value: function onPropertyTypeChange(event) {
        var _this6 = this;

        var target = event.target;
        var value = target.type === 'checkbox' ? target.checked : target.value;

        if (this.state.Attributes.PropertyType !== value) {
          var attributes = _extends({}, this.state.Attributes, { PropertyType: value });
          this.setState(_extends({}, this.state, { Attributes: attributes }), function () {
            return _this6.props.onAttributesChangeHandler(_this6.state);
          });
        }
      }
    }, {
      key: 'onInputChange',
      value: function onInputChange(event) {
        var _this7 = this;

        var target = event.target;
        var value = target.type === 'checkbox' ? target.checked : target.value;
        var name = target.name;

        if (target.type === 'number' && parseInt(value) != NaN && parseInt(value) < 0) {
          value = Math.abs(value);
        }

        if (this.state[name] !== value) {
          this.setState(_defineProperty({}, name, value), function () {
            return _this7.props.onAttributesChangeHandler(_this7.state);
          });
        }
      }
    }, {
      key: 'validateNumer',
      value: function validateNumer(event) {
        return event.charCode >= 48 && event.charCode <= 57;
      }
    }, {
      key: 'onPhotoIconClick',
      value: function onPhotoIconClick(event) {
        event.preventDefault();
        this.props.onPhotoIconClick(this.props.listing);
      }
    }]);

    return EditView;
  }(React.PureComponent);

  EditView.propTypes = {
    listing: React.PropTypes.object,
    onAttributesChangeHandler: React.PropTypes.func,
    onPhotoIconClick: React.PropTypes.func
  };


  Rev.Views.ThreeComps.EditView = EditView;
})(Rev, jQuery, _, Backbone);
"use strict";

var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };

var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }

function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

// dependencies : Rev, jquery, underscore, backbone

(function (Rev, $, _, Backbone) {
  var GalleryView = function (_React$PureComponent) {
    _inherits(GalleryView, _React$PureComponent);

    function GalleryView(props) {
      _classCallCheck(this, GalleryView);

      var _this = _possibleConstructorReturn(this, (GalleryView.__proto__ || Object.getPrototypeOf(GalleryView)).call(this, props));

      _this.maxFiles = 50;
      _this.state = _extends({ isUploading: false, fileAdded: false }, props);
      _this.initializeDropzone = _this.initializeDropzone.bind(_this);
      _this.initializeSorting = _this.initializeSorting.bind(_this);
      _this.onUploadSuccess = _this.onUploadSuccess.bind(_this);
      _this.onSortUpdate = _this.onSortUpdate.bind(_this);
      _this.destroyDropzoneAndSorting = _this.destroyDropzoneAndSorting.bind(_this);
      return _this;
    }

    _createClass(GalleryView, [{
      key: "shouldComponentUpdate",
      value: function shouldComponentUpdate(nextProps, nextState) {
        var currentStateImmutable = Immutable.fromJS(this.state);
        var nextStateImmutable = Immutable.fromJS(nextState);
        var isDifferent = !currentStateImmutable.equals(nextStateImmutable);
        return isDifferent;
      }
    }, {
      key: "componentWillReceiveProps",
      value: function componentWillReceiveProps(nextProps) {
        var newProps = _extends({}, this.state, {
          fileAdded: nextProps.listing && nextProps.listing.Photos && nextProps.listing.Photos.length
        }, nextProps);
        this.setState(newProps, this.toggleBodyScroll.bind(this));
      }
    }, {
      key: "componentDidMount",
      value: function componentDidMount() {
        this.initializeDropzone();
        this.initializeSorting();
      }
    }, {
      key: "componentWillUnmount",
      value: function componentWillUnmount() {
        this.destroyDropzoneAndSorting();
      }
    }, {
      key: "componentDidUpdate",
      value: function componentDidUpdate() {
        this.initializeSorting();
      }
    }, {
      key: "render",
      value: function render() {
        var _this2 = this;

        var rootClassNames = classNames("three-comps-gallery", {
          "three-comps-gallery--open": this.state.listing && this.state.listing.openGallery,
          "three-comps-gallery--file-added": this.state.fileAdded
        });

        var addressText = null;
        if (this.props.listing && this.props.listing.Address) {
          addressText = this.props.listing.Address.AddressText;
        }

        var existingPhotos = null;
        if (this.state.listing && this.state.listing.Photos && this.state.listing.Photos.length >= 1) {
          existingPhotos = this.state.listing.Photos.map(function (photo) {
            var previewClass = classNames("dz-preview dz-processing dz-success dz-complete dz-image-preview", {
              "uploading": photo.isUploading
            });

            var previewImage = "";
            if (!photo.isUploading) {
              previewImage = React.createElement("img", { "data-dz-thumbnail": true, src: photo.Url });
            }

            return React.createElement(
              "div",
              { key: photo.Url, className: previewClass },
              React.createElement(
                "div",
                { className: "dz-image" },
                previewImage
              ),
              React.createElement(
                "a",
                { className: "dz-remove", href: "#", onClick: function onClick(e) {
                    e.preventDefault();_this2.onDeletePhotoClick(photo);
                  } },
                React.createElement(
                  "i",
                  { className: "material-icons" },
                  "\uE5CD"
                )
              ),
              React.createElement(
                "i",
                { className: "material-icons uploading-icon" },
                "\uE2C3"
              )
            );
          });
        }

        var isRemovedPhotosExist = this.state.listing && this.state.listing.removedPhotos && this.state.listing.removedPhotos.length >= 1;

        var removedPhotosDescription = null;
        if (isRemovedPhotosExist) {
          removedPhotosDescription = React.createElement(
            "div",
            { className: "removed-photos__description" },
            React.createElement(
              "h4",
              null,
              "Removed images from gallery list"
            ),
            React.createElement(
              "p",
              null,
              "To select image click on the restore icon below"
            )
          );
        }

        var removedPhotos = null;
        if (isRemovedPhotosExist) {
          removedPhotos = this.state.listing.removedPhotos.map(function (photo) {
            return React.createElement(
              "div",
              { key: photo.Url, className: "dz-preview dz-processing dz-success dz-complete dz-image-preview" },
              React.createElement(
                "div",
                { className: "dz-image" },
                React.createElement("img", { "data-dz-thumbnail": true, src: photo.Url, draggable: "false" })
              ),
              React.createElement(
                "a",
                { className: "re-use", href: "#", onClick: function onClick(e) {
                    e.preventDefault();_this2.onRedoClick(photo);
                  } },
                React.createElement(
                  "i",
                  { className: "material-icons" },
                  "\uE929"
                )
              )
            );
          });
        }

        return React.createElement(
          "div",
          { className: rootClassNames },
          React.createElement(
            "div",
            { className: "three-comps-gallery__content" },
            React.createElement(
              "div",
              { className: "three-comps-gallery__header" },
              React.createElement(
                "strong",
                null,
                "Photos"
              ),
              React.createElement(
                "span",
                null,
                addressText
              ),
              React.createElement(
                "span",
                { className: "btn-close", onClick: function onClick() {
                    return _this2.props.onGalleryCloseClick(_this2.props.listing);
                  } },
                React.createElement(
                  "i",
                  { className: "material-icons" },
                  "\uE5CD"
                )
              )
            ),
            React.createElement(
              "div",
              { className: "three-comps-gallery__body dropzone" },
              React.createElement(
                "div",
                { className: "rev-dropzone" },
                React.createElement(
                  "form",
                  { method: "post", encType: "multipart/form-data", action: "/three-comps/photo/upload/", id: "form-dropzone" },
                  React.createElement("input", { type: "hidden", name: "__RequestVerificationToken", id: "gallery-upload-token" }),
                  React.createElement("input", { type: "hidden", name: "listingId", value: this.props.listingId }),
                  React.createElement("input", { type: "hidden", name: "gnafAddressId", value: this.props.listing && this.props.listing.Address && this.props.listing.Address.GnafAddressId }),
                  React.createElement(
                    "div",
                    { className: "rev-dropzone__description" },
                    React.createElement(
                      "i",
                      { className: "material-icons" },
                      "\uE413"
                    ),
                    React.createElement(
                      "p",
                      null,
                      "Drag your photos here or ",
                      React.createElement(
                        "label",
                        { className: "rev-dropzone__input-file-label", htmlFor: "input-file" },
                        "Browse"
                      )
                    ),
                    React.createElement(
                      "p",
                      null,
                      "for an photo to upload"
                    ),
                    React.createElement(
                      "b",
                      null,
                      "max file size is 3.5MB"
                    )
                  ),
                  React.createElement(
                    "div",
                    { className: "image-preview-container dropzone-previews" },
                    existingPhotos
                  )
                )
              ),
              React.createElement(
                "div",
                { className: "removed-photos" },
                removedPhotosDescription,
                removedPhotos
              )
            ),
            React.createElement(
              "div",
              { className: "three-comps-gallery__footer" },
              React.createElement(
                "button",
                { className: classNames("btn btn-primary btn-thin", this.state.isUploading ? "disabled" : ""), onClick: this.onDoneClick.bind(this) },
                "Done"
              )
            )
          )
        );
      }
    }, {
      key: "destroyDropzoneAndSorting",
      value: function destroyDropzoneAndSorting() {
        if (this.dropzone) {
          $('.image-preview-container.dropzone-previews') && $('.image-preview-container.dropzone-previews').sortable('destroy');
          this.dropzone.destroy();
        }
      }
    }, {
      key: "initializeDropzone",
      value: function initializeDropzone() {
        Dropzone.autoDiscover = false;

        this.dropzone = new Dropzone("form#form-dropzone", {
          dictDefaultMessage: '',
          previewsContainer: '.image-preview-container',
          acceptedFiles: '.jpg,.jpeg,.png,.bmp,.gif,.exif,.tiff',
          clickable: '.rev-dropzone__input-file-label',
          maxFilesize: 3.5,
          // maxFiles: this.maxFiles, // don't use this option
          addedfile: function addedfile(file) {} // by assigning empty function, thumbnails won't be rendered twice
        });

        this.dropzone.on('addedfile', this.onAddedFile.bind(this));
        this.dropzone.on('dragover', this.onDragover.bind(this));
        this.dropzone.on('dragleave', this.onDragleave.bind(this));
        this.dropzone.on('success', this.onUploadSuccess.bind(this));
        this.dropzone.on('error', this.onError.bind(this));
        this.dropzone.on('queuecomplete', this.onQueuecomplete.bind(this));
      }
    }, {
      key: "initializeSorting",
      value: function initializeSorting() {
        $('.image-preview-container.dropzone-previews').sortable({ update: this.onSortUpdate });
      }
    }, {
      key: "onSortUpdate",
      value: function onSortUpdate(event, ui) {
        var _this3 = this;

        // photos
        var sortedPhotos = [];
        $('.image-preview-container .dz-preview').each(function (index, element) {
          var photoToAdd = _.find(_this3.state.listing.Photos, function (photo) {
            return photo.Url === $(element).find('img').attr('src');
          });
          if (photoToAdd) {
            sortedPhotos.push(photoToAdd);
          }
        });

        var newListing = _extends({}, this.state.listing, { Photos: sortedPhotos });
        this.setState(_extends({}, this.state, { listing: newListing }));
      }
    }, {
      key: "onDragover",
      value: function onDragover(event) {
        $('.rev-dropzone').addClass('rev-dropzone--dragover');
      }
    }, {
      key: "onDragleave",
      value: function onDragleave(event) {
        $('.rev-dropzone').removeClass('rev-dropzone--dragover');
      }
    }, {
      key: "onAddedFile",
      value: function onAddedFile(file) {
        this.setState({ isUploading: true });

        if (this.state.listing.Photos.length < this.maxFiles) {

          var exist = _.some(this.state.listing.Photos, function (photo) {
            return photo.fileName === file.name || photo.Url === file.name;
          });
          if (!exist) {
            var newPhoto = { Url: file.name, fileName: file.name, isUploading: true };
            var photos = [].concat(_toConsumableArray(this.state.listing.Photos), [newPhoto]);
            var newListing = _extends({}, this.state.listing, { Photos: photos });
            this.setState(_extends({}, this.state, { listing: newListing, fileAdded: newListing.Photos && newListing.Photos.length }));
          }
        } else {
          Rev.Utils.showErrorMessage("Sorry, You can only upload " + this.maxFiles + " files");
        }
      }
    }, {
      key: "onUploadSuccess",
      value: function onUploadSuccess(file) {
        var temporaryUrl = JSON.parse(file.xhr.response).TempFilePath;

        var index = _.findIndex(this.state.listing.Photos, function (photo) {
          return photo.fileName === file.name && photo.isUploading;
        });
        if (index >= 0) {
          var photos = [].concat(_toConsumableArray(this.state.listing.Photos));
          photos[index] = { Url: temporaryUrl, Source: 'Uploaded', isUploading: false };
          var newListing = _extends({}, this.state.listing, { Photos: photos });
          this.setState(_extends({}, this.state, { listing: newListing, fileAdded: newListing.Photos && newListing.Photos.length }));
        }
      }
    }, {
      key: "onError",
      value: function onError(file, errorMessage) {
        if (file && file.size && file.size / 1048576 > 3.5) {
          Rev.Utils.showErrorMessage('File size is bigger than 3.5MB.');
        } else {
          Rev.Utils.showErrorMessage('Sorry, error occured while uploading file.');
        }

        var index = _.findIndex(this.state.listing.Photos, function (photo) {
          return photo.fileName === file.name;
        });
        if (index >= 0) {
          var photos = [].concat(_toConsumableArray(this.state.listing.Photos));
          photos.splice(index, 1);
          var newListing = _extends({}, this.state.listing, { Photos: photos });
          this.setState(_extends({}, this.state, { listing: newListing, fileAdded: newListing.Photos && newListing.Photos.length }));
        }
      }
    }, {
      key: "onQueuecomplete",
      value: function onQueuecomplete() {
        this.setState({ isUploading: false });
        $('.rev-dropzone').removeClass('rev-dropzone--dragover');
      }
    }, {
      key: "onDeletePhotoClick",
      value: function onDeletePhotoClick(photo) {
        var removedPhotos = this.state.listing.removedPhotos || [];
        var newRemovedPhotos = [].concat(_toConsumableArray(removedPhotos));
        newRemovedPhotos.push(photo);
        var newPhotos = _.without(this.state.listing.Photos, photo);
        var newListing = _extends({}, this.state.listing, { Photos: newPhotos, removedPhotos: newRemovedPhotos });
        this.setState(_extends({}, this.state, { listing: newListing, fileAdded: newListing.Photos && newListing.Photos.length }));
      }
    }, {
      key: "onRedoClick",
      value: function onRedoClick(photo) {
        var removedPhotos = _.without(this.state.listing.removedPhotos, photo); //this.state.listing.removedPhotos || [];
        var photos = this.state.listing.Photos || [];
        var newPhotos = [].concat(_toConsumableArray(photos));
        newPhotos.push(photo);
        var newListing = _extends({}, this.state.listing, { Photos: newPhotos, removedPhotos: removedPhotos });
        this.setState(_extends({}, this.state, { listing: newListing, fileAdded: newListing.Photos && newListing.Photos.length }));
      }
    }, {
      key: "onDoneClick",
      value: function onDoneClick(e) {
        this.props.onGalleryDoneClick(this.state.listing);
      }
    }, {
      key: "toggleBodyScroll",
      value: function toggleBodyScroll() {
        $('body').css({ 'overflow': '' });

        if (this.state.listing && this.state.listing.openGallery) {
          $('body').css({ 'overflow': 'hidden' });
          $('.listing-agent-section').length && $('.listing-agent-section').hide();
        }
      }
    }]);

    return GalleryView;
  }(React.PureComponent);

  GalleryView.propTypes = {
    listingId: React.PropTypes.string,
    listing: React.PropTypes.object,
    onGalleryCloseClick: React.PropTypes.func,
    onGalleryDoneClick: React.PropTypes.func
  };


  Rev.Views.ThreeComps.GalleryView = GalleryView;
})(Rev, jQuery, _, Backbone);
"use strict";

var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }

function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

// dependencies : Rev, jquery, underscore, backbone

(function (Rev, $, _, Backbone) {
  var HeaderView = function (_React$PureComponent) {
    _inherits(HeaderView, _React$PureComponent);

    function HeaderView(props) {
      _classCallCheck(this, HeaderView);

      return _possibleConstructorReturn(this, (HeaderView.__proto__ || Object.getPrototypeOf(HeaderView)).call(this, props));
    }

    _createClass(HeaderView, [{
      key: "render",
      value: function render() {
        var _this2 = this;

        return React.createElement(
          "div",
          { className: "panel-heading" },
          React.createElement(
            "span",
            null,
            "Comparable Sales"
          ),
          React.createElement(
            "div",
            { className: "pull-right" },
            React.createElement(
              "button",
              { className: "btn btn-default btn-inverse btn-thin btn-edit", onClick: function onClick() {
                  return _this2.props.onEditClick();
                } },
              "Agent edit comparables"
            ),
            React.createElement(
              "button",
              { className: "btn btn-default btn-empty btn-thin btn-cancel", onClick: function onClick() {
                  return _this2.props.onCancelClick();
                } },
              "Cancel"
            ),
            React.createElement(
              "form",
              { method: "post", action: "/three-comps/save/", id: "form-save-three-comps" },
              React.createElement("input", { type: "hidden", name: "__RequestVerificationToken" }),
              React.createElement(
                "button",
                { type: "button", onClick: function onClick() {
                    return _this2.props.onSaveClick();
                  }, className: "btn btn-default btn-inverse btn-thin btn-save" },
                "Save comparables"
              )
            )
          )
        );
      }
    }]);

    return HeaderView;
  }(React.PureComponent);

  HeaderView.propTypes = {
    onEditClick: React.PropTypes.func.isRequired,
    onCancelClick: React.PropTypes.func.isRequired,
    onSaveClick: React.PropTypes.func.isRequired
  };


  Rev.Views.ThreeComps.HeaderView = HeaderView;
})(Rev, jQuery, _, Backbone);
'use strict';

var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }

function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

// dependencies : Rev, jquery, underscore, backbone

(function (Rev, $, _, Backbone) {
  var LoadingView = function (_React$PureComponent) {
    _inherits(LoadingView, _React$PureComponent);

    function LoadingView() {
      _classCallCheck(this, LoadingView);

      return _possibleConstructorReturn(this, (LoadingView.__proto__ || Object.getPrototypeOf(LoadingView)).apply(this, arguments));
    }

    _createClass(LoadingView, [{
      key: 'render',
      value: function render() {

        var loadingIcon = React.createElement(
          'div',
          { className: 'spinner-wave' },
          React.createElement('div', { className: 'spinner-wave__wave1 spinner-wave__child' }),
          React.createElement('div', { className: 'spinner-wave__wave2 spinner-wave__child' }),
          React.createElement('div', { className: 'spinner-wave__wave3 spinner-wave__child' }),
          React.createElement('div', { className: 'spinner-wave__wave4 spinner-wave__child' }),
          React.createElement('div', { className: 'spinner-wave__wave5 spinner-wave__child' })
        );

        if (this.props.loadingType === 'SUCCESS') {
          loadingIcon = React.createElement(
            'i',
            { className: 'material-icons spinner-success' },
            '\uE876'
          );
        }

        return React.createElement(
          'div',
          { className: 'loading-indicator' },
          React.createElement(
            'div',
            { className: 'loading-indicator__spinner' },
            loadingIcon,
            React.createElement(
              'h4',
              { className: 'load-text' },
              this.props.message
            )
          )
        );
      }
    }]);

    return LoadingView;
  }(React.PureComponent);

  LoadingView.propTypes = {
    loadingType: React.PropTypes.oneOf(['LOADING', 'SUCCESS']),
    message: React.PropTypes.string
  };
  LoadingView.defaultProps = {
    loadingType: 'LOADING',
    message: 'Loading...'
  };


  Rev.Views.ThreeComps.LoadingView = LoadingView;
})(Rev, jQuery, _, Backbone);
'use strict';

var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };

var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }

function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

// dependencies : Rev, jquery, underscore, backbone

(function (Rev, $, _, Backbone) {
  var PriceEstimateView = function (_React$PureComponent) {
    _inherits(PriceEstimateView, _React$PureComponent);

    function PriceEstimateView(props) {
      _classCallCheck(this, PriceEstimateView);

      var _this = _possibleConstructorReturn(this, (PriceEstimateView.__proto__ || Object.getPrototypeOf(PriceEstimateView)).call(this, props));

      _this.state = { Minimum: '', Estimated: '', Maximum: '', Type: 0 };
      _this.onInputChange = _this.onInputChange.bind(_this);
      return _this;
    }

    _createClass(PriceEstimateView, [{
      key: 'shouldComponentUpdate',
      value: function shouldComponentUpdate(nextProps, nextState) {
        var currentStateImmutable = Immutable.fromJS(this.state);
        var nextStateImmutable = Immutable.fromJS(nextState);
        return !currentStateImmutable.equals(nextStateImmutable);
      }
    }, {
      key: 'componentWillReceiveProps',
      value: function componentWillReceiveProps(nextProps) {
        var newProps = _extends({}, this.state, nextProps);
        this.setState(newProps);
      }
    }, {
      key: 'render',
      value: function render() {
        var _this2 = this;

        var priceTypeButtonClassNames = classNames("indicative-selling-price__button btn btn-primary", { "active": this.state.Type == 1 });
        var rangeTypeButtonClassNames = classNames("indicative-selling-price__button btn btn-primary", { "active": this.state.Type == 0 });

        return React.createElement(
          'div',
          { className: 'price-estimate-view' },
          React.createElement(
            'div',
            { className: 'row' },
            React.createElement(
              'div',
              { className: 'col-sm-3 col-sm-offset-1' },
              React.createElement(
                'div',
                { className: 'form-group' },
                React.createElement(
                  'label',
                  { htmlFor: 'price-low', className: 'label-price-low' },
                  'Low'
                ),
                React.createElement('input', { type: 'number', min: '0', max: '9999999999', value: this.state.Minimum, name: 'Minimum', onChange: this.onInputChange, className: 'form-control', id: 'price-low' })
              )
            ),
            React.createElement(
              'div',
              { className: 'col-sm-4' },
              React.createElement(
                'div',
                { className: 'form-group' },
                React.createElement(
                  'label',
                  { htmlFor: 'price-medium', className: 'label-price-medium' },
                  'Price Estimate'
                ),
                React.createElement('input', { type: 'number', min: '0', max: '9999999999', value: this.state.Estimated, name: 'Estimated', onChange: this.onInputChange, className: 'form-control', id: 'price-medium' })
              )
            ),
            React.createElement(
              'div',
              { className: 'col-sm-3' },
              React.createElement(
                'div',
                { className: 'form-group' },
                React.createElement(
                  'label',
                  { htmlFor: 'price-high', className: 'label-price-high' },
                  'High'
                ),
                React.createElement('input', { type: 'number', min: '0', max: '9999999999', value: this.state.Maximum, name: 'Maximum', onChange: this.onInputChange, className: 'form-control', id: 'price-high' })
              )
            )
          ),
          React.createElement(
            'h4',
            { className: 'inticative-selling-price-text' },
            'Select the Indicative Selling Price to appear on the Statement of Information:'
          ),
          React.createElement(
            'div',
            { className: 'row indicative-selling-price' },
            React.createElement(
              'div',
              { className: 'btn-group indicative-selling-price__group', 'data-toggle': 'buttons' },
              React.createElement(
                'label',
                { className: priceTypeButtonClassNames, onClick: function onClick(e) {
                    return _this2.onTypeClick(e, 1);
                  } },
                React.createElement('input', { type: 'radio', name: 'Type', value: '1', readOnly: true, checked: this.state.Type == 1 }),
                '$' + Rev.Utils.String.numberWithCommas(this.state.Estimated)
              ),
              React.createElement(
                'label',
                { className: rangeTypeButtonClassNames, onClick: function onClick(e) {
                    return _this2.onTypeClick(e, 0);
                  } },
                React.createElement('input', { type: 'radio', name: 'Type', value: '0', readOnly: true, checked: this.state.Type == 0 }),
                '$' + Rev.Utils.String.numberWithCommas(this.state.Minimum),
                ' - ',
                '$' + Rev.Utils.String.numberWithCommas(this.state.Maximum)
              )
            )
          ),
          React.createElement(
            'div',
            { className: 'estimate-note' },
            React.createElement(
              'span',
              null,
              'Above price estimates only apply when you are editing your comparable sales'
            )
          )
        );
      }
    }, {
      key: 'onTypeClick',
      value: function onTypeClick(e, type) {
        var _this3 = this;

        this.setState({ Type: type }, function () {
          return _this3.props.onEstimatePriceChangeHandler(_this3.state);
        });
      }
    }, {
      key: 'onInputChange',
      value: function onInputChange(event) {
        var _this4 = this;

        var max = 9999999999;
        var target = event.target;
        var value = target.type === 'checkbox' ? target.checked : target.value;
        var name = target.name;

        if (parseInt(value) != NaN) {
          value = parseInt(value) < 0 ? Math.abs(value) : parseInt(value) > max ? max : value;
        }

        if (value === max) return;

        if (this.state[name] !== value) {
          this.setState(_defineProperty({}, name, value), function () {
            return _this4.props.onEstimatePriceChangeHandler(_this4.state);
          });
        }
      }
    }]);

    return PriceEstimateView;
  }(React.PureComponent);

  PriceEstimateView.propTypes = {
    Minimum: React.PropTypes.number,
    Estimated: React.PropTypes.number,
    Maximum: React.PropTypes.number,
    onEstimatePriceChangeHandler: React.PropTypes.func
  };


  Rev.Views.ThreeComps.PriceEstimateView = PriceEstimateView;
})(Rev, jQuery, _, Backbone);
"use strict";

var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }

function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

// dependencies : Rev, jquery, underscore, backbone

(function (Rev, $, _, Backbone) {
  var PropertySearchView = function (_React$PureComponent) {
    _inherits(PropertySearchView, _React$PureComponent);

    function PropertySearchView(props) {
      _classCallCheck(this, PropertySearchView);

      return _possibleConstructorReturn(this, (PropertySearchView.__proto__ || Object.getPrototypeOf(PropertySearchView)).call(this, props));
    }

    _createClass(PropertySearchView, [{
      key: "componentDidMount",
      value: function componentDidMount() {
        new Rev.Views.EaiaSearchView({
          el: '.three-comps-eaia-search-form',
          onAddressSearchCompleteHandler: this.fetchPropertyInfo.bind(this)
        });
      }
    }, {
      key: "render",
      value: function render() {
        return React.createElement(
          "div",
          { className: "three-comps-eaia-search-form" },
          React.createElement(
            "div",
            { className: "form-group" },
            React.createElement("input", { type: "text", className: "form-control", "data-hook": "eaia-location", placeholder: "Search an address" }),
            React.createElement(
              "i",
              { className: "material-icons search-icon" },
              "\uE8B6"
            ),
            React.createElement(
              "a",
              { href: "#", className: "btn-close", onClick: this.onCloseClick.bind(this) },
              React.createElement(
                "i",
                { className: "material-icons close-icon" },
                "\uE5CD"
              )
            ),
            React.createElement(
              "div",
              { className: "message-location-required" },
              React.createElement(
                "div",
                { className: "message-content" },
                React.createElement(
                  "span",
                  null,
                  "Please add the full address you are looking for"
                )
              )
            ),
            React.createElement(
              "div",
              { className: "message-no-result" },
              React.createElement(
                "div",
                { className: "message-content" },
                React.createElement(
                  "span",
                  null,
                  "No matching address available"
                )
              )
            )
          )
        );
      }
    }, {
      key: "fetchPropertyInfo",
      value: function fetchPropertyInfo(suggestionItem) {
        var _this2 = this;

        var seoSlug = suggestionItem.SeoSlug;
        $.getJSON("/three-comps/candidate-listings/eaia/" + seoSlug + "/").done(function (response) {
          return _this2.props.onProperty360AddressSelected(response);
        });
      }
    }, {
      key: "onCloseClick",
      value: function onCloseClick(e) {
        e.preventDefault();
        Rev.trigger('property-360:search:clear');
      }
    }]);

    return PropertySearchView;
  }(React.PureComponent);

  PropertySearchView.propTypes = {
    onProperty360AddressSelected: React.PropTypes.func
  };


  Rev.Views.ThreeComps.PropertySearchView = PropertySearchView;
})(Rev, jQuery, _, Backbone);
'use strict';

var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }

function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

// dependencies : Rev, jquery, underscore, backbone

(function (Rev, $, _, Backbone) {
  var ReplaceItemView = function (_React$PureComponent) {
    _inherits(ReplaceItemView, _React$PureComponent);

    function ReplaceItemView(props) {
      _classCallCheck(this, ReplaceItemView);

      return _possibleConstructorReturn(this, (ReplaceItemView.__proto__ || Object.getPrototypeOf(ReplaceItemView)).call(this, props));
    }

    _createClass(ReplaceItemView, [{
      key: 'render',
      value: function render() {

        var trClassNames = classNames('candidate-listing-view', { 'active': this.props.listing.IsActive });

        var adjustedPrice = '-';
        if (this.props.listing.AdjustedPrice) {
          adjustedPrice = '$' + Rev.Utils.String.numberWithCommas(this.props.listing.AdjustedPrice);
        }

        var salePrice = '-';
        if (this.props.listing.Price) {
          salePrice = '$' + Rev.Utils.String.numberWithCommas(this.props.listing.Price);
        }

        return React.createElement(
          'tr',
          { className: trClassNames, onClick: this.onReplaceItemClickHandler.bind(this) },
          React.createElement(
            'td',
            { className: "col-image " + (this.props.listing.Photos && this.props.listing.Photos.length >= 1 ? "" : "no-photo"), onClick: this.onPhotoClick.bind(this) },
            React.createElement(
              'i',
              { className: 'material-icons' },
              '\uE3B6'
            ),
            React.createElement(
              'span',
              null,
              this.props.listing.Photos && this.props.listing.Photos.length
            )
          ),
          React.createElement(
            'td',
            null,
            this.props.listing.Address.AddressText
          ),
          React.createElement(
            'td',
            null,
            adjustedPrice
          ),
          React.createElement(
            'td',
            null,
            salePrice
          ),
          React.createElement(
            'td',
            null,
            this.props.listing.SoldDateInLocalTimeText
          ),
          React.createElement(
            'td',
            null,
            this.props.listing.Attributes && this.props.listing.Attributes.PropertyType
          ),
          React.createElement(
            'td',
            null,
            this.props.listing.Attributes && this.props.listing.Attributes.NumberOfBedrooms
          ),
          React.createElement(
            'td',
            null,
            this.props.listing.Attributes && this.props.listing.Attributes.NumberOfBathrooms
          ),
          React.createElement(
            'td',
            null,
            this.props.listing.Attributes && this.props.listing.Attributes.NumberOfParking
          )
        );
      }
    }, {
      key: 'onPhotoClick',
      value: function onPhotoClick(e) {
        e.preventDefault();
        e.stopPropagation();
        var photos = _.map(this.props.listing.Photos, function (photo) {
          return photo.Url;
        });
        if (photos && photos.length) {
          Rev.Utils.showPhotoGalleryModal(this.props.listing.Address.AddressText, photos, photos);
        }
      }
    }, {
      key: 'onReplaceItemClickHandler',
      value: function onReplaceItemClickHandler(e) {
        this.props.onReplaceItemClickHandler(this.props.listing);
      }
    }]);

    return ReplaceItemView;
  }(React.PureComponent);

  ReplaceItemView.propTypes = {
    listing: React.PropTypes.object,
    onReplaceItemClickHandler: React.PropTypes.func
  };


  Rev.Views.ThreeComps.ReplaceItemView = ReplaceItemView;
})(Rev, jQuery, _, Backbone);
"use strict";

var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }

function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

// dependencies : Rev, jquery, underscore, backbone

(function (Rev, $, _, Backbone) {
  var ReplaceView = function (_React$PureComponent) {
    _inherits(ReplaceView, _React$PureComponent);

    function ReplaceView(props) {
      _classCallCheck(this, ReplaceView);

      return _possibleConstructorReturn(this, (ReplaceView.__proto__ || Object.getPrototypeOf(ReplaceView)).call(this, props));
    }

    _createClass(ReplaceView, [{
      key: "render",
      value: function render() {
        var _this2 = this;

        var listings = this.props.data.map(function (listing) {
          return React.createElement(Rev.Views.ThreeComps.ReplaceItemView, { key: listing.Address.GnafAddressId,
            listing: listing,
            onReplaceItemClickHandler: _this2.props.onReplaceItemClickHandler });
        });

        return React.createElement(
          "div",
          { className: "replace-view" },
          React.createElement(
            "div",
            { className: "replace-view__heading" },
            React.createElement(
              "span",
              null,
              "Replace Comparable"
            )
          ),
          React.createElement(Rev.Views.ThreeComps.PropertySearchView, { onProperty360AddressSelected: this.props.onProperty360AddressSelected }),
          this.props.data.length >= 1 && React.createElement(
            "table",
            { className: "table table-hover" },
            React.createElement(
              "thead",
              null,
              React.createElement(
                "tr",
                null,
                React.createElement(
                  "th",
                  null,
                  "Images"
                ),
                React.createElement(
                  "th",
                  null,
                  "Address"
                ),
                React.createElement(
                  "th",
                  null,
                  "Adjusted Price"
                ),
                React.createElement(
                  "th",
                  null,
                  "Sale Price*"
                ),
                React.createElement(
                  "th",
                  null,
                  "Sale Date"
                ),
                React.createElement(
                  "th",
                  null,
                  "Type"
                ),
                React.createElement(
                  "th",
                  null,
                  "Beds"
                ),
                React.createElement(
                  "th",
                  null,
                  "Baths"
                ),
                React.createElement(
                  "th",
                  null,
                  "Cars"
                )
              )
            ),
            React.createElement(
              "tbody",
              null,
              listings
            )
          )
        );
      }
    }]);

    return ReplaceView;
  }(React.PureComponent);

  ReplaceView.propTypes = {
    data: React.PropTypes.array,
    onReplaceItemClickHandler: React.PropTypes.func,
    onProperty360AddressSelected: React.PropTypes.func
  };


  Rev.Views.ThreeComps.ReplaceView = ReplaceView;
})(Rev, jQuery, _, Backbone);
'use strict';

var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };

// dependencies : Rev, jquery, underscore, backbone

(function (Rev, $, _, Backbone, ReactDOM, Immutable) {

  'use strict';

  Rev.Views.ThreeCompsAgentView = Backbone.View.extend({
    initialize: function initialize(options) {
      var _this = this;

      this.listingId = options.listingId;
      this.gnafId = options.gnafId;

      _.bindAll(this, 'render', 'fetchAllData', 'onReplaceClick', 'onEditAttributesClick', 'onEditClick', 'onCancelClick', 'onSaveClick', 'onDoneReplaceClick', 'onDoneEditAttrClick', 'onReplaceItemClickHandler', 'resetToNormalUI', 'onProperty360AddressSelected', 'onAddListingClick', 'onAttributesChangeHandler', 'onEstimatePriceChangeHandler', 'showView', 'onPhotoIconClick', 'onGalleryCloseClick', 'onGalleryDoneClick', 'hideView', 'showLoadingIndicator', 'hideLoadingIndicator', 'deactivateReplaceItems', 'isValidForSaving', 'areComparablesValidForSaving', 'isValidStatement', 'onConfirmSaveClick', 'onConfirmCancelClick', 'onAreaTypeChangeHandler', 'onDeleteListingClick', 'createDummyListing');

      this.collection = new Rev.Collections.Items();
      this.candidateListings = new Rev.Collections.Items();
      this.listingModelToEdit = new Rev.Models.Item();
      this.priceEstimationModel = new Rev.Models.Item();
      this.openGallery = false;

      this.listenTo(this.collection, 'reset', this.render);
      this.listenTo(this.candidateListings, 'reset', this.render);
      this.listenTo(this.listingModelToEdit, 'change', this.render);
      this.listenTo(this.priceEstimationModel, 'change', this.render);
      this.listenTo(Rev, 'three-comps-edit-view:show', this.showView);
      this.listenTo(Rev, 'property-360:search:clear', function () {
        return _this.listingSelectedFromSearch = null;
      });

      this.$el.hide();
      this.render();

      this.loadingMessage = 'Please wait a moment while your comparable sales is processed';
      this.loadingType = 'LOADING';
    },


    events: {},

    showView: function showView() {
      var _this2 = this;

      // ensure clear all models and collections
      this.collection.reset();
      this.candidateListings.reset();
      this.listingModelToEdit.clear();
      this.priceEstimationModel.clear();

      // get all data
      this.$el.fadeIn().addClass('edit-mode');
      this.showLoadingIndicator();
      this.fetchAllData(this.listingId, this.gnafId).then(function () {
        return _this2.refreshAntiforgeryToken();
      }).always(function () {
        return _this2.hideLoadingIndicator();
      });
    },
    hideView: function hideView() {
      this.$('.three-comps-agent-view').removeClass('loading');
      this.$el.removeClass('edit-mode').fadeOut();
    },
    render: function render() {
      ReactDOM.render(React.createElement(
        'div',
        { className: 'three-comps-agent-view' },
        React.createElement(
          'div',
          { className: 'row' },
          React.createElement(
            'div',
            { className: 'panel panel-default' },
            React.createElement(Rev.Views.ThreeComps.HeaderView, { onEditClick: this.onEditClick,
              onCancelClick: this.onCancelClick,
              onSaveClick: this.onSaveClick }),
            React.createElement(Rev.Views.ThreeComps.PriceEstimateView, _extends({}, this.priceEstimationModel.toJSON(), {
              onEstimatePriceChangeHandler: this.onEstimatePriceChangeHandler })),
            React.createElement(Rev.Views.ThreeComps.CardsView, { data: this.collection.toJSON(),
              onReplaceClick: this.onReplaceClick,
              onDoneReplaceClick: this.onDoneReplaceClick,
              onEditAttributesClick: this.onEditAttributesClick,
              onDoneEditAttrClick: this.onDoneEditAttrClick,
              onAddListingClick: this.onAddListingClick,
              onDeleteClick: this.onDeleteListingClick })
          )
        ),
        React.createElement(Rev.Views.ThreeComps.ReplaceView, { data: this.candidateListings.toJSON(),
          onReplaceItemClickHandler: this.onReplaceItemClickHandler,
          onProperty360AddressSelected: this.onProperty360AddressSelected }),
        React.createElement(Rev.Views.ThreeComps.EditView, { listing: this.listingModelToEdit.toJSON(),
          onAttributesChangeHandler: this.onAttributesChangeHandler,
          onPhotoIconClick: this.onPhotoIconClick }),
        React.createElement(Rev.Views.ThreeComps.GalleryView, { listingId: this.listingId,
          listing: this.listingModelToEdit.toJSON(),
          onGalleryCloseClick: this.onGalleryCloseClick,
          onGalleryDoneClick: this.onGalleryDoneClick }),
        React.createElement(Rev.Views.ThreeComps.ConfirmCompsView, { isOpen: this.isConfirmCompsModalOpen,
          isLessThanThreeComparables: this.collection.reject(function (c) {
            return c.get('IsDummyListing');
          }).length < 3,
          areaType: this.areaType,
          onConfirmCancelClick: this.onConfirmCancelClick,
          onConfirmSaveClick: this.onConfirmSaveClick,
          onAreaTypeChangeHandler: this.onAreaTypeChangeHandler }),
        React.createElement(Rev.Views.ThreeComps.LoadingView, { message: this.loadingMessage,
          loadingType: this.loadingType })
      ), this.$el[0]);
    },
    showLoadingIndicator: function showLoadingIndicator(message, loadingType) {
      this.loadingMessage = message || 'Loading...';
      this.loadingType = loadingType || 'LOADING';
      this.render();
      this.$('.three-comps-agent-view').addClass('three-comps-agent-view--loading');
    },
    hideLoadingIndicator: function hideLoadingIndicator() {
      this.$('.three-comps-agent-view').removeClass('three-comps-agent-view--loading');
    },
    onAreaTypeChangeHandler: function onAreaTypeChangeHandler(areaType) {
      this.areaType = areaType;
    },
    onConfirmCancelClick: function onConfirmCancelClick() {
      this.isConfirmCompsModalOpen = false;
      this.render();
    },


    /**
      Persist changes
    */
    onConfirmSaveClick: function onConfirmSaveClick() {
      var _this3 = this;

      // validate all required values
      if (!this.isValidForSaving()) return;

      // close confirm modal
      this.isConfirmCompsModalOpen = false;
      this.render();

      var isSuccess = false;

      this.showLoadingIndicator('Please wait a moment while your comparable sales is processed');
      this.$('form#form-save-three-comps .btn').addClass('disabled');

      var data = {
        listingId: this.listingId,
        gnafAddressId: this.gnafId,
        initialData: this.initialData,
        selectedComparables: this.collection.toJSON(),
        selectedEstimatedPrice: this.priceEstimationModel.toJSON(),
        areaType: this.areaType,
        __RequestVerificationToken: $('form#form-save-three-comps input[name="__RequestVerificationToken"]').val()
      };

      $.post('/three-comps/save/', data).done(function (response) {
        if (response.success) {
          isSuccess = true;
          _this3.showLoadingIndicator('Your saved 3Comps will take 15 minutes before consumers will view the changes', 'SUCCESS');
          setTimeout(function () {
            return window.location.reload(true);
          }, 4000);
        } else {
          console.log('error occured', response);
          Rev.Utils.showErrorMessage(response.errorMessage || 'Sorry, error occured while saving 3comps.');
          _this3.hideLoadingIndicator();
        }
      }).fail(function (response) {
        console.log('error occured', response);
        Rev.Utils.showErrorMessage('Sorry, error occured while saving 3comps.');
        _this3.hideLoadingIndicator();
      }).always(function () {
        if (!isSuccess) {
          _this3.hideLoadingIndicator();
          _this3.$('form#form-save-three-comps .btn').removeClass('disabled');
        }
      });
    },
    onSaveClick: function onSaveClick() {
      if (!this.areComparablesValidForSaving()) return;
      this.isConfirmCompsModalOpen = true;
      this.render();
    },


    /**
     * perform validation before saving
     */

    isValidForSaving: function isValidForSaving() {
      return this.areComparablesValidForSaving() && this.isValidStatement();
    },
    areComparablesValidForSaving: function areComparablesValidForSaving() {
      if (this.priceEstimationModel == null || !this.priceEstimationModel.get('Minimum') || !this.priceEstimationModel.get('Maximum') || !this.priceEstimationModel.get('Estimated')) {
        Rev.Utils.showErrorMessage('Price estimate fields must be entered');
        return;
      }

      //if (this.collection == null || (this.collection.length !== 3 || this.collection.some(c => c.get('IsDummyListing')))) {
      //  Rev.Utils.showErrorMessage('Unable to save less than 3 comparable properties');
      //  return;
      //}

      if (this.collection.reject(function (c) {
        return c.get('IsDummyListing');
      }).some(function (c) {
        return !c.get('SoldDateInLocalTimeText') || !c.get('Price');
      })) {
        Rev.Utils.showErrorMessage('Please enter price and sold date');
        return;
      }

      var notAllowedValues = [null, undefined, 0, '0', '', ' ', '-', 'Land', 'land', 'unknown'];

      var anyListingsNoBedrooms = this.collection.reject(function (c) {
        return c.get('IsDummyListing');
      }).some(function (c) {
        return _.contains(notAllowedValues, c.get('Attributes').NumberOfBedrooms);
      });
      if (anyListingsNoBedrooms) {
        Rev.Utils.showErrorMessage('Please provide number of bedroom');
        return;
      }

      var anyListingsNoBathrooms = this.collection.reject(function (c) {
        return c.get('IsDummyListing');
      }).some(function (c) {
        return _.contains(notAllowedValues, c.get('Attributes').NumberOfBathrooms);
      });
      if (anyListingsNoBathrooms) {
        Rev.Utils.showErrorMessage('Please provide number of bathroom');
        return;
      }

      var anyListingsNoPropertyType = this.collection.reject(function (c) {
        return c.get('IsDummyListing');
      }).some(function (c) {
        return _.contains(notAllowedValues, c.get('Attributes').PropertyType);
      });
      if (anyListingsNoPropertyType) {
        Rev.Utils.showErrorMessage('Please provide property type');
        return;
      }

      return true;
    },
    isValidStatement: function isValidStatement() {
      if (!this.areaType || !(this.areaType == 1 || this.areaType == 2)) {
        Rev.Utils.showErrorMessage('Please select correct statement');
        return;
      }

      return true;
    },


    /**
      get 15 candidate listings, price estimation
    */
    fetchAllData: function fetchAllData(listingId, gnafId) {
      var _this4 = this;

      return $.getJSON('/three-comps/candidate-listings/', { listingId: listingId, gnafId: gnafId }).then(function (response) {

        _this4.priceEstimationModel.set(response.EstimatePrice);

        _.each(response.ActiveThreeCompsListings, function (listing) {
          return listing.IsEditMode = true;
        });
        _this4.collection.reset(response.ActiveThreeCompsListings);

        _this4.candidateListings.reset(response.InActiveThreeCompsListings);

        _this4.initialData = response.InitialData;

        _this4.areaType = response.AreaType;

        _this4.$('.replace-view').addClass('fade-in');
      });
    },
    refreshAntiforgeryToken: function refreshAntiforgeryToken(successCallback) {
      $.get('/refreshtoken/').done(function (html) {
        var tokenValue = $('<div />').html(html).find('input[type="hidden"]').val();
        $('input[name="__RequestVerificationToken"]').val(tokenValue);
        if (successCallback) successCallback();
      });
    },


    /**
      event handler for "Agent edit comparables" button
    */
    onEditClick: function onEditClick() {
      this.$el.addClass('edit-mode');

      var newCollection = Immutable.fromJS(this.collection.toJSON()).toJS();
      newCollection.forEach(function (listingItem) {
        return listingItem.IsEditMode = true;
      });
      this.collection.reset(newCollection);
    },


    /**
      reset UI to normal state (Read-Only state)
    */
    resetToNormalUI: function resetToNormalUI() {
      this.$el.removeClass('edit-mode replace-mode edit-attr-mode');
      this.$('.replace-view').removeClass('show fade-in');
      this.$('.edit-attr-view').removeClass('show fade-in');
    },


    /**
      reset UI to normal state (Read-Only state)
    */
    resetEditMode: function resetEditMode(listing) {
      listing.IsEditMode = false;
      listing.IsReplaceMode = false;
      listing.IsEditAttrMode = false;
      listing.IsActive = false;
      return listing;
    },


    /**
      event hadler for "Cancel" button
    */
    onCancelClick: function onCancelClick() {
      this.resetToNormalUI();
      this.hideView();
      Rev.trigger('three-comps-user-view:show');
    },


    /**
      event handler when P360 address is searched and selected
    */
    onProperty360AddressSelected: function onProperty360AddressSelected(p360Listing) {
      if (!p360Listing) return;

      // check if searched listing exist in 15 listings
      var gnafId = p360Listing.Address.GnafAddressId;
      var exist = this.collection.some(function (listingItem) {
        return listingItem.get('Address').GnafAddressId === gnafId;
      });
      if (!exist) {
        exist = !exist && this.candidateListings.some(function (listingItem) {
          return listingItem.get('Address').GnafAddressId === gnafId;
        });
      }
      if (exist) {
        Rev.Utils.showErrorMessage('There is a matching property in your list below');
        return;
      }

      p360Listing.IsFromSearch = true;
      this.listingSelectedFromSearch = p360Listing;

      this.deactivateReplaceItems();

      // let listingToBeReplaced = this.collection.find(listingItem => listingItem.get('IsReplaceMode') === true);
      // if (!listingToBeReplaced) return;
      // listingToBeReplaced = Immutable.fromJS(listingToBeReplaced.toJSON()).toJS();
      // this.resetEditMode(listingToBeReplaced);

      // let newCollection = Immutable.fromJS(this.collection.toJSON()).toJS();
      // const index = _.findIndex(newCollection, (listingItem) => listingItem.Address.GnafAddressId === listingToBeReplaced.Address.GnafAddressId);
      // p360Listing.IsFromSearch = true;
      // newCollection[index] = p360Listing;
      // this.collection.reset(newCollection);

      // Rev.Utils.showSuccessMessage('Comparable listing replaced');
      // this.$el.removeClass('replace-mode');
    },


    /**
      event handler for "Replace" button  
    */
    onReplaceClick: function onReplaceClick(listing) {
      var _this5 = this;

      this.$el.addClass('replace-mode');
      this.$('.replace-view').addClass('show');
      this.$('.edit-attr-view').removeClass('show');

      var newCollection = Immutable.fromJS(this.collection.toJSON()).toJS();
      newCollection.forEach(function (listingItem) {
        return listingItem.IsReplaceMode = listingItem.Address.GnafAddressId === listing.Address.GnafAddressId;
      });
      this.collection.reset(newCollection);

      setTimeout(function () {
        return _this5.$('.replace-view').addClass('fade-in');
      }, 100);
    },


    /**
      event handler when one of 12 candidate listings selected (clicked)
    */
    onReplaceItemClickHandler: function onReplaceItemClickHandler(listing) {
      var newCandidateListings = Immutable.fromJS(this.candidateListings.toJSON()).toJS();
      if (listing.IsActive) {
        newCandidateListings.forEach(function (listingItem) {
          return listingItem.IsActive = false;
        });
      } else {
        newCandidateListings.forEach(function (listingItem) {
          return listingItem.IsActive = listingItem.Address.GnafAddressId === listing.Address.GnafAddressId;
        });
      }
      this.candidateListings.reset(newCandidateListings);
    },


    /**
     * deactivate 12 listing items
     */
    deactivateReplaceItems: function deactivateReplaceItems() {
      var newCandidateListings = Immutable.fromJS(this.candidateListings.toJSON()).toJS();
      newCandidateListings.forEach(function (listingItem) {
        return listingItem.IsActive = false;
      });
      this.candidateListings.reset(newCandidateListings);
    },
    createDummyListing: function createDummyListing() {
      return {
        IsDummyListing: true,
        Address: { GnafAddressId: _.uniqueId('dummy_') }
      };
    },


    /**
     * delete comparable
     */
    onDeleteListingClick: function onDeleteListingClick(listing) {
      if (listing.IsDummyListing) return;

      var listingToDelete = Immutable.fromJS(listing).toJS();
      this.resetEditMode(listingToDelete);

      // add to candidate listings
      var newCandidateListings = Immutable.fromJS(this.candidateListings.toJSON()).toJS();
      if (!listingToDelete.IsFromSearch && !listingToDelete.IsDummyListing) {
        newCandidateListings.push(listingToDelete);
      }
      this.candidateListings.reset(newCandidateListings);

      // remove the listing from the collection (3 comparables)
      var newCollection = Immutable.fromJS(this.collection.toJSON()).toJS();
      var index = _.findIndex(newCollection, function (listingItem) {
        return listingItem.Address.GnafAddressId === listingToDelete.Address.GnafAddressId;
      });
      newCollection[index] = this.createDummyListing();
      this.collection.reset(newCollection);

      this.$el.removeClass('replace-mode');
    },


    /**
      - event handler for "Done (replace)" button 
      - swap listings between 3comps listings and 12 candidate listings
    */
    onDoneReplaceClick: function onDoneReplaceClick(listing) {
      var listingToBeReplaced = Immutable.fromJS(listing).toJS();
      this.resetEditMode(listingToBeReplaced);

      // selecte listing from property 360 search then look for 12 listings
      var selectedListing = this.listingSelectedFromSearch || this.candidateListings.find(function (cand) {
        return cand.get('IsActive') === true;
      });

      // clear listing selected from search
      this.listingSelectedFromSearch = null;
      Rev.trigger('property-360:search:clear');

      // if no candidate listing is selected, just reset to normal ui status
      if (!selectedListing) {
        var newCollection = Immutable.fromJS(this.collection.toJSON()).toJS();
        var index = _.findIndex(newCollection, function (listingItem) {
          return listingItem.Address.GnafAddressId === listingToBeReplaced.Address.GnafAddressId;
        });
        newCollection[index] = listingToBeReplaced;
        this.collection.reset(newCollection);
        this.$el.removeClass('replace-mode');
      } else {
        var replaceCandidateListing = Immutable.fromJS(selectedListing.toJSON ? selectedListing.toJSON() : selectedListing).toJS();
        replaceCandidateListing.justReplaced = true;

        var _newCollection = Immutable.fromJS(this.collection.toJSON()).toJS();
        var _index = _.findIndex(_newCollection, function (listingItem) {
          return listingItem.Address.GnafAddressId === listingToBeReplaced.Address.GnafAddressId;
        });
        _newCollection[_index] = replaceCandidateListing;

        var newCandidateListings = Immutable.fromJS(this.candidateListings.toJSON()).toJS();

        var indexInCandidates = _.findIndex(newCandidateListings, function (listingItem) {
          return listingItem.Address.GnafAddressId === replaceCandidateListing.Address.GnafAddressId;
        });

        // add to candidate listings EXCEPT dummy listing and listing searched from property 360
        if (indexInCandidates >= 0 && !listingToBeReplaced.IsFromSearch && !listingToBeReplaced.IsDummyListing) {
          newCandidateListings[indexInCandidates] = listingToBeReplaced;
        } else if (indexInCandidates >= 0 && (listingToBeReplaced.IsFromSearch || listingToBeReplaced.IsDummyListing)) {
          newCandidateListings.splice(indexInCandidates, 1);
        } else {
          if (!listingToBeReplaced.IsFromSearch && !listingToBeReplaced.IsDummyListing) {
            newCandidateListings.push(listingToBeReplaced);
          }
        }

        this.collection.reset(_newCollection);
        this.candidateListings.reset(newCandidateListings);

        // Rev.Utils.showSuccessMessage('Comparable listing replaced');
        this.$el.removeClass('replace-mode');
      }
    },


    /**
      - event handler for "Plus icon" 
      - Plus icon is appeared when there is no 3comps listings
    */
    onAddListingClick: function onAddListingClick(listing) {
      this.onEditClick();
      this.onReplaceClick(listing);
    },


    /**
      event handler for "Edit Attributes" button 
    */
    onEditAttributesClick: function onEditAttributesClick(listing) {
      var _this6 = this;

      this.$el.addClass('edit-attr-mode');
      this.$('.replace-view').removeClass('show');
      this.$('.edit-attr-view').addClass('show');

      var newCollection = Immutable.fromJS(this.collection.toJSON()).toJS();
      newCollection.forEach(function (listingItem) {
        listingItem.IsEditAttrMode = listingItem.Address.GnafAddressId === listing.Address.GnafAddressId;
        listingItem.justEdited = false;
      });
      this.collection.reset(newCollection);

      this.listingModelToEdit.set(listing);

      setTimeout(function () {
        return _this6.$('.edit-attr-view').addClass('fade-in');
      }, 100);
    },


    /**
      - event handler for attributes of listing change
      - this event is fired only when new value is different from previous value
    */
    onAttributesChangeHandler: function onAttributesChangeHandler(listing) {
      this.listingModelToEdit.set(listing);
    },


    /**
      event handler for "Done (edit attributes)" button
    */
    onDoneEditAttrClick: function onDoneEditAttrClick(listing) {
      var notAllowedValues = [null, undefined, 0, '0', '', ' ', '-'];

      var invalidBedrooms = _.contains(notAllowedValues, this.listingModelToEdit.get('Attributes').NumberOfBedrooms);
      if (invalidBedrooms) {
        Rev.Utils.showErrorMessage('Please provide number of bedroom');
        return;
      }

      var invalidBathrooms = _.contains(notAllowedValues, this.listingModelToEdit.get('Attributes').NumberOfBathrooms);
      if (invalidBathrooms) {
        Rev.Utils.showErrorMessage('Please provide number of bathroom');
        return;
      }

      var listingToBeEdited = Immutable.fromJS(listing).toJS();
      this.resetEditMode(listingToBeEdited);

      var newCollection = Immutable.fromJS(this.collection.toJSON()).toJS();
      var index = _.findIndex(newCollection, function (listingItem) {
        return listingItem.Address.GnafAddressId === listingToBeEdited.Address.GnafAddressId;
      });
      this.listingModelToEdit.set({ 'justEdited': true });
      newCollection[index] = this.listingModelToEdit.toJSON();
      this.collection.reset(newCollection);

      this.listingModelToEdit.clear();

      // Rev.Utils.showSuccessMessage('Comparable listing edited');
      this.$el.removeClass('edit-attr-mode');
    },


    /**
      event handler for 3 estimated price change
    */
    onEstimatePriceChangeHandler: function onEstimatePriceChangeHandler(estimatePrices) {
      this.priceEstimationModel.set(estimatePrices);
    },


    /**
      event handler for photo icon in "edit attributes" form
    */
    onPhotoIconClick: function onPhotoIconClick(listing) {
      var editingListing = Immutable.fromJS(this.listingModelToEdit.toJSON()).toJS();
      editingListing.openGallery = true;
      this.listingModelToEdit.set(editingListing);
    },
    onGalleryCloseClick: function onGalleryCloseClick(listing) {
      var editingListing = Immutable.fromJS(this.listingModelToEdit.toJSON()).toJS();
      editingListing.openGallery = false;
      this.listingModelToEdit.set(editingListing);
    },
    onGalleryDoneClick: function onGalleryDoneClick(listing) {
      this.listingModelToEdit.set(_extends({}, listing, { openGallery: false }));
    }
  });
})(Rev, jQuery, _, Backbone, ReactDOM, Immutable);
'use strict';

// dependencies : Rev, jquery, underscore, backbone

(function (Rev, $, _, Backbone, ReactDOM, Immutable) {

  'use strict';

  Rev.Views.ThreeCompsItemView = Backbone.View.extend({
    initialize: function initialize(options) {
      _.bindAll(this, 'initializeSlick');

      this.initializeSlick();

      this.listenTo(Rev, 'three-comps-user-view:show', this.initializeSlick);
    },


    events: {
      'click .three-comps-card__arrow-left': 'onNavPhotoLeftClick',
      'click .three-comps-card__arrow-right': 'onNavPhotoRightClick',
      'click .three-comps-card__photo-box': 'onPhotoClick'
    },

    onPhotoClick: function onPhotoClick(e) {
      e.preventDefault();
      var photos = this.model.get('Photos');
      Rev.Utils.showPhotoGalleryModal(this.model.get('Address'), photos, photos);
    },
    initializeSlick: function initializeSlick() {
      this.slickInstance && this.slickInstance.slick('unslick');

      if (this.model.get('Photos') && this.model.get('Photos').length >= 2) {
        this.slickInstance = Rev.Utils.initSlick(this.$('.three-comps-card__photos'), {
          slidesToShow: 1,
          slidesToScroll: 1,
          centerPadding: '0px'
        });
      }
    },
    onNavPhotoLeftClick: function onNavPhotoLeftClick(e) {
      e.preventDefault();
      $(e.currentTarget).siblings('.three-comps-card__photos').slick('slickPrev');
    },
    onNavPhotoRightClick: function onNavPhotoRightClick(e) {
      e.preventDefault();
      $(e.currentTarget).siblings('.three-comps-card__photos').slick('slickNext');
    }
  });
})(Rev, jQuery, _, Backbone, ReactDOM, Immutable);
'use strict';

// dependencies : Rev, jquery, underscore, backbone

(function (Rev, $, _, Backbone, ReactDOM, Immutable) {

  'use strict';

  Rev.Views.ThreeCompsView = Backbone.View.extend({
    initialize: function initialize(options) {

      this.listenTo(Rev, 'three-comps-user-view:show', this.showView);
      this.createSubViews();
      this.hasExpanded = false;
    },


    events: {
      'click .btn-edit': 'onEditClick',
      'click .collapse-btn': 'onCollapseClick'
    },

    showView: function showView() {
      this.$el.show();
    },
    createSubViews: function createSubViews() {
      if (this.model.get('ThreeCompsListings') && this.model.get('ThreeCompsListings').length >= 1) {
        _.each(this.model.get('ThreeCompsListings'), function (listing) {
          new Rev.Views.ThreeCompsItemView({
            el: '.three-comps-card[data-gnaf-id="' + listing.GnafAddressId + '"]',
            model: new Rev.Models.Item(listing)
          });
        });
      }
    },
    onEditClick: function onEditClick(e) {
      this.$el.hide();
      Rev.trigger('three-comps-edit-view:show');
    },
    onCollapseClick: function onCollapseClick(e) {
      if (!this.hasExpanded) {
        Rev.Utils.GaTracking.trackGaEvent(this.model.get('GaEventCategory'), Rev.Utils.GaTracking.Action.ExpandComparableSales, 'property ' + this.model.get('Id'));
        this.hasExpanded = true;
      }
    }
  });
})(Rev, jQuery, _, Backbone, ReactDOM, Immutable);
'use strict';

// dependencies : Rev, jquery, underscore, backbone

(function (Rev, $, _, Backbone) {

  'use strict';

  Rev.Views.AvmItemView = Backbone.View.extend({
    initialize: function initialize(options) {
      _.bindAll(this, 'initSlick', 'onPhotoClick', 'onReplaceClick');

      this.parentView = options.parentView;

      this.initSlick();
    },


    events: {
      'click .js-replace': 'onReplaceClick',
      'click .three-comps-card__arrow-left': 'onNavPhotoLeftClick',
      'click .three-comps-card__arrow-right': 'onNavPhotoRightClick',
      'click .three-comps-card__photo-box': 'onPhotoClick'
    },

    initSlick: function initSlick() {
      this.slickInstance && this.slickInstance.slick('unslick');

      if (this.model.get('Photos') && this.model.get('Photos').length >= 2) {
        this.slickInstance = Rev.Utils.initSlick(this.$('.three-comps-card__photos'), {
          lazyLoad: 'ondemand',
          slidesToShow: 1,
          slidesToScroll: 1,
          centerPadding: '0px'
        });
      }
    },
    onNavPhotoLeftClick: function onNavPhotoLeftClick(e) {
      e.preventDefault();

      Rev.Utils.GaTracking.trackGaEvent(Rev.Utils.GaTracking.Category.Property360Address, Rev.Utils.GaTracking.Action.AvmEstimatePhotoScroll, 'SA1-' + this.parentView.model.get('Sa1TruncatedId') + '-' + this.parentView.model.get('SeoSlug'));

      $(e.currentTarget).siblings('.three-comps-card__photos').slick('slickPrev');
    },
    onNavPhotoRightClick: function onNavPhotoRightClick(e) {
      e.preventDefault();

      Rev.Utils.GaTracking.trackGaEvent(Rev.Utils.GaTracking.Category.Property360Address, Rev.Utils.GaTracking.Action.AvmEstimatePhotoScroll, 'SA1-' + this.parentView.model.get('Sa1TruncatedId') + '-' + this.parentView.model.get('SeoSlug'));

      $(e.currentTarget).siblings('.three-comps-card__photos').slick('slickNext');
    },
    onPhotoClick: function onPhotoClick(e) {
      e.preventDefault();

      Rev.Utils.GaTracking.trackGaEvent(Rev.Utils.GaTracking.Category.Property360Address, Rev.Utils.GaTracking.Action.AvmEstimatePhotoGalleryOpen, 'SA1-' + this.parentView.model.get('Sa1TruncatedId') + '-' + this.parentView.model.get('SeoSlug'));

      var photos = this.model.get('Photos');
      Rev.Utils.showPhotoGalleryModal(this.model.get('Address'), photos, photos, null, null, { GaEventCategory: Rev.Utils.GaTracking.Category.Property360Address, GaEventAction: Rev.Utils.GaTracking.Action.AvmEstimatePhotoGalleryScroll, GaEventLabel: 'SA1-' + this.parentView.model.get('Sa1TruncatedId') + '-' + this.parentView.model.get('SeoSlug') }, null);
    },
    onReplaceClick: function onReplaceClick(e) {
      e.preventDefault();

      Rev.Utils.GaTracking.trackGaEvent(Rev.Utils.GaTracking.Category.Property360Address, Rev.Utils.GaTracking.Action.AvmEstimateReplace, 'SA1-' + this.parentView.model.get('Sa1TruncatedId') + '-' + this.parentView.model.get('SeoSlug'));

      this.parentView.replaceAvmItem(this);
    },
    remove: function remove() {
      if (this.slickInstance) {
        this.slickInstance.slick('unslick');
      }

      this.off();

      //call the superclass remove method
      Backbone.View.prototype.remove.apply(this, arguments);
    }
  });
})(Rev, jQuery, _, Backbone);
'use strict';

function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }

// dependencies : Rev, jquery, underscore, backbone

(function (Rev, $, _, Backbone) {

  'use strict';

  Rev.Views.AvmView = Backbone.View.extend({
    initialize: function initialize() {
      _.bindAll(this, 'replaceAvmItem', 'getShownGnafIds', 'updateEstimatePrice', 'updatePlayMode', 'renderTopThreeProperties', 'arePropertiesShowingSelectedByAgent', 'getPropertiesShowing', 'get15Comps', 'showUpThreeProperties', 'showView');

      this.initializeSubViews();

      this.avmCandidatesList = new Rev.Collections.Items(this.model.get('AvmProperties'));
      this.initialAvmSearchCriteriaData = this.model.get('AvmAttributesForm');

      this.updateEstimatePrice();

      this.updateAdjustedPriceLabel();

      this.listenTo(Rev, 'three-comps-user-view:show', this.showView);
    },


    events: {
      'click .js-choose': 'onChooseCompsButtonClick',
      'click .js-update': 'onUpdateClick',
      'click .js-open-attributes, .js-cancel-attributes': 'openAttributes',
      'click #disclaimer-link': 'onDisclaimerClick',
      'change .js-bed': 'onBedChange',
      'change .js-bath': 'onBathChange',
      'change .js-car': 'onCarChange',
      'change .js-property-type': 'onPropertyTypeChange',
      'click .js-agent-edit-comparables': 'onAgentEditComparablesClick',
      'click [data-hook="open-3comps-video"]': 'onYoutubeVideoClick'
    },

    initializeSubViews: function initializeSubViews() {
      var _this = this;

      _.each(this.model.get('AvmProperties'), function (listing) {
        new Rev.Views.AvmItemView({
          el: '.avm-item[data-gnaf-id="' + listing.GnafAddressId + '"]',
          model: new Rev.Models.AvmItem(listing),
          parentView: _this
        });
      });
    },


    onYoutubeVideoClick: function onYoutubeVideoClick(e) {
      e.preventDefault();
      e.stopPropagation();

      Rev.Utils.GaTracking.trackGaEvent(Rev.Utils.GaTracking.Category.Property360Address, Rev.Utils.GaTracking.Action.AvmHowDoesThisWorkVideo, 'SA1-' + this.model.get('Sa1TruncatedId') + '-' + this.model.get('SeoSlug'));

      Rev.Utils.showYoutubeModal("https://www.youtube.com/embed/SaOTsFU5q5w");
    },

    showView: function showView() {
      this.$el.show();
    },
    onAgentEditComparablesClick: function onAgentEditComparablesClick(e) {
      this.$el.hide();
      Rev.trigger('three-comps-edit-view:show');
    },
    openAttributes: function openAttributes(e) {
      e.preventDefault();
      this.$('.form-filters').toggleClass('open');
    },
    showUpThreeProperties: function showUpThreeProperties(listings, listingsOrdered) {
      var self = this;
      var sortedListings = [];

      if (listings && listingsOrdered) {

        // sort listings
        _.each(listingsOrdered, function (listingOrdered) {
          var listing = _.find(listings, function (item) {
            return item.model.GnafAddressId == listingOrdered.GnafAddressId;
          });
          sortedListings.push(listing);
        });

        _.each(sortedListings, function (listing) {
          var newModelContents = listing.model;
          var newViewContents = listing.view;

          // add html 
          self.$('.avm-three-comps-items').append(newViewContents);

          setTimeout(function () {
            var viewSelector = '.avm-item[data-gnaf-id="' + newModelContents.GnafAddressId + '"]';

            // create an instance for new view
            new Rev.Views.AvmItemView({
              el: viewSelector,
              model: new Rev.Models.AvmItem(newModelContents),
              parentView: self
            });
          }, 100);
        });
      }
    },
    renderTopThreeProperties: function renderTopThreeProperties() {
      var self = this;
      var count = 0;
      var listingsResult = [];

      // delete three properties 
      self.$('.avm-three-comps-items').fadeOut('fast', function () {
        self.$('.avm-item').remove();
        self.$('.avm-three-comps-items').css({ opacity: 0 }).show();

        // get three propeties 
        var listingsToShow = self.avmCandidatesList.filter(function (listing) {
          return listing.get('SelectedByAgent');
        });
        listingsToShow = listingsToShow.toJSON && listingsToShow.toJSON();

        if (!listingsToShow || listingsToShow.length <= 3) {
          var avmCandidatesListArray = self.avmCandidatesList.toJSON();
          var hiddenListings = _.without(avmCandidatesListArray, listingsToShow);
          listingsToShow = hiddenListings.splice(0, listingsToShow ? 3 - listingsToShow.length : 3);
        }

        _.each(listingsToShow, function (listing) {

          listing.shownToUser = true;

          $.post('/avm/get-avm-item-view/', listing).done(function (result) {

            listingsResult.push(result);

            count++;

            if (count === listingsToShow.length) {
              self.showUpThreeProperties(listingsResult, listingsToShow);
              self.$('.avm-three-comps-items').css({ opacity: 1 }).addClass('animated');
              self.updateEstimatePrice();
              self.updateAdjustedPriceLabel();
            }
          });
        });
      });
    },
    get15Comps: function get15Comps(formData) {
      var _this2 = this;

      if (!formData.PropertyType) {
        Rev.Utils.showErrorMessage('Please select property type');
        return;
      }

      this.$('.js-update, .js-choose').button('loading');

      $.post('/avm/get-avm-items/', formData).done(function (result) {
        if (result.status == 200) {
          _this2.updatePlayMode(result.data);
          _this2.renderTopThreeProperties();
        } else {
          Rev.Utils.showErrorMessage('Sorry, failed to get comparables.');
        }
      }).fail(function () {
        return Rev.Utils.showErrorMessage('Sorry, failed to get comparables.');
      }).always(function () {
        return _this2.$('.js-update, .js-choose').button('reset');
      });
    },
    onUpdateClick: function onUpdateClick(e) {
      e.preventDefault();

      Rev.Utils.GaTracking.trackGaEvent(Rev.Utils.GaTracking.Category.Property360Address, Rev.Utils.GaTracking.Action.AvmEstimateUpdate, 'SA1-' + this.model.get('Sa1TruncatedId') + '-' + this.model.get('SeoSlug'));

      var source = 'Custom';
      // if beds, baths, car, property type match initial search criteria, use initial source provided
      if (this.initialAvmSearchCriteriaData != null && this.$('.js-bed').val() == this.initialAvmSearchCriteriaData.BedSelectedOriginal && this.$('.js-bath').val() == this.initialAvmSearchCriteriaData.BathSelectedOriginal && this.$('.js-car').val() == this.initialAvmSearchCriteriaData.CarSelectedOriginal && this.$('.js-property-type').val() == this.initialAvmSearchCriteriaData.PropertyTypeSelected) {
        source = this.initialAvmSearchCriteriaData.SearchCriteriaSource;
      }

      var formData = {
        GnafAddressId: this.model.get('GnafAddressId'),
        NumberOfBedrooms: this.$('.js-bed').val(),
        NumberOfBathrooms: this.$('.js-bath').val(),
        NumberOfParking: this.$('.js-car').val(),
        PropertyType: this.$('.js-property-type').val(),
        Source: source,
        '__RequestVerificationToken': this.$('input[name="__RequestVerificationToken"]').val(),
        ListingId: this.model.get('ActiveListingId'),
        ListingPrice: this.model.get('ActiveListingPrice'),
        LandArea: this.model.get('ActiveListingLandArea') || this.model.get('PropertyAreaSize')
      };

      this.get15Comps(formData);
    },
    onChooseCompsButtonClick: function onChooseCompsButtonClick(e) {
      e.preventDefault();

      Rev.Utils.GaTracking.trackGaEvent(Rev.Utils.GaTracking.Category.Property360Address, Rev.Utils.GaTracking.Action.AvmEstimateChoose, 'SA1-' + this.model.get('Sa1TruncatedId') + '-' + this.model.get('SeoSlug'));

      var formData = {
        GnafAddressId: this.model.get('GnafAddressId'),
        NumberOfBedrooms: this.model.get('ActiveListingId') ? this.model.get('ActiveListingNumberOfBedrooms') : this.model.get('AvmAttributesForm').BedSelectedOriginal,
        NumberOfBathrooms: this.model.get('ActiveListingId') ? this.model.get('ActiveListingNumberOfBathrooms') : this.model.get('AvmAttributesForm').BathSelectedOriginal,
        NumberOfParking: this.model.get('ActiveListingId') ? this.model.get('ActiveListingNumberOfParking') : this.model.get('AvmAttributesForm').CarSelectedOriginal,
        PropertyType: this.model.get('AvmAttributesForm').PropertyTypeSelected,
        Source: this.model.get('AvmAttributesForm').SearchCriteriaSource,
        '__RequestVerificationToken': this.$('input[name="__RequestVerificationToken"]').val(),
        ListingId: this.model.get('ActiveListingId'),
        ListingPrice: this.model.get('ActiveListingPrice'),
        LandArea: this.model.get('ActiveListingLandArea') || this.model.get('PropertyAreaSize')
      };

      this.get15Comps(formData);
    },
    onDisclaimerClick: function onDisclaimerClick(e) {
      e.preventDefault();

      this.$('.avm-disclaimer').toggleClass('hide');
    },
    onBedChange: function onBedChange(e) {
      Rev.Utils.GaTracking.trackGaEvent(Rev.Utils.GaTracking.Category.Property360Address, Rev.Utils.GaTracking.Action.AvmEstimateBeds, 'SA1-' + this.model.get('Sa1TruncatedId') + '-' + this.model.get('SeoSlug'));
    },
    onBathChange: function onBathChange(e) {
      Rev.Utils.GaTracking.trackGaEvent(Rev.Utils.GaTracking.Category.Property360Address, Rev.Utils.GaTracking.Action.AvmEstimateBath, 'SA1-' + this.model.get('Sa1TruncatedId') + '-' + this.model.get('SeoSlug'));
    },
    onCarChange: function onCarChange(e) {
      Rev.Utils.GaTracking.trackGaEvent(Rev.Utils.GaTracking.Category.Property360Address, Rev.Utils.GaTracking.Action.AvmEstimateCar, 'SA1-' + this.model.get('Sa1TruncatedId') + '-' + this.model.get('SeoSlug'));
    },
    onPropertyTypeChange: function onPropertyTypeChange(e) {
      Rev.Utils.GaTracking.trackGaEvent(Rev.Utils.GaTracking.Category.Property360Address, Rev.Utils.GaTracking.Action.AvmEstimateType, 'SA1-' + this.model.get('Sa1TruncatedId') + '-' + this.model.get('SeoSlug'));
    },
    updatePlayMode: function updatePlayMode(data) {
      this.$el.addClass('replace-by-user-mode');
      this.$('.avm-item__action-replace').addClass('flash-twice');

      // if data is returned (properties match the search criteria)
      if (data && data.AvmProperties) {

        this.avmCandidatesList.reset(data.AvmProperties);
        this.avmCandidatesList.each(function (listing) {
          return listing.set({ shownToUser: false });
        });

        this.model.set({
          AvmSelectedByAgency: data.AvmSelectedByAgency,
          AvmAttributesForm: data.AvmAttributesForm,
          AvmEstimatedPrice: data.AvmEstimatedPrice
        });
      } else {
        var _model$set;

        Rev.Utils.showErrorMessage('No comparable properties available for this search criteria.');

        this.avmCandidatesList.reset([]);

        this.model.set((_model$set = {
          AvmSelectedByAgency: []
        }, _defineProperty(_model$set, 'AvmSelectedByAgency', null), _defineProperty(_model$set, 'AvmEstimatedPrice', null), _model$set));

        // manually trigger updated price
        this.updateEstimatePrice();
      }
    },
    getShownGnafIds: function getShownGnafIds() {
      var _this3 = this;

      var ids = [];
      this.$('.avm-item:visible').each(function (i, e) {
        return ids.push(_this3.$(e).attr('data-gnaf-id'));
      });
      return ids;
    },
    replaceAvmItem: function replaceAvmItem(childView) {
      var self = this;

      // if there are 3 or less avm candidates, prevent the item from being replaced and show error to user
      if (self.avmCandidatesList.length <= 3) {
        Rev.Utils.showErrorMessage('No comparable properties available');
        return;
      }

      // make replace button disabled
      self.$('.avm-item .js-replace').prop('disabled', true);

      var currentClickingListingIndex = self.$('.avm-item').index(childView.$el);

      // reset if user start clicking different one from three lisings
      if (self.currentClickingListingIndex !== currentClickingListingIndex) {
        self.avmCandidatesList.each(function (listing) {
          return listing.set({ shownToUser: false });
        });
        self.currentClickingListingIndex = currentClickingListingIndex;
      }

      // three avm items that showing
      var shownGnafIds = self.getShownGnafIds();

      // set "shownToUser" to "true" of avm items currently showing
      self.avmCandidatesList.each(function (listing) {
        if (_.contains(shownGnafIds, listing.get('GnafAddressId'))) {
          listing.set({ shownToUser: true });
        }
      });

      // if all the avm items are shown, reset all items' "shownToUser" to false so it start looping through again
      var didShowAll = self.avmCandidatesList.every(function (listing) {
        return listing.get('shownToUser');
      });
      if (didShowAll) {
        self.avmCandidatesList.every(function (listing) {
          return listing.set('shownToUser', false);
        });
      }

      var notShownListings = self.avmCandidatesList.reject(function (listing) {
        return _.contains(shownGnafIds, listing.get('GnafAddressId'));
      });

      notShownListings = _.filter(notShownListings, function (listing) {
        return !listing.get('shownToUser');
      });

      var listingToShow = notShownListings[0];

      listingToShow.set({ shownToUser: true });

      $.post('/avm/get-avm-item-view/', listingToShow.toJSON()).done(function (result) {
        var newModelContents = result.model;
        var newViewContents = result.view;

        // create an instance for new view
        setTimeout(function () {
          // replace html of old child view with new child
          childView.$el.replaceWith(newViewContents);

          // delete old child view
          childView.remove();

          var viewSelector = '.avm-item[data-gnaf-id="' + newModelContents.GnafAddressId + '"]';

          new Rev.Views.AvmItemView({
            el: viewSelector,
            model: new Rev.Models.AvmItem(newModelContents),
            parentView: self
          });
          self.$(viewSelector).addClass('animated');

          self.updateEstimatePrice();

          self.updateAdjustedPriceLabel();
        }, 100);
      }).always(function () {
        return self.$('.avm-item .js-replace').prop('disabled', false);
      });
    },
    updateEstimatePrice: function updateEstimatePrice() {
      var avg = void 0;
      var lowPrice = void 0;
      var highPrice = void 0;

      this.toggleViews();

      var arePropertiesShowingSelectedByAgent = this.arePropertiesShowingSelectedByAgent();

      // if all 3 comparables are selected by agent, just show estimated prices received from API
      if (arePropertiesShowingSelectedByAgent && this.model.get('AvmEstimatedPrice') && this.model.get('AvmEstimatedPrice').Estimated !== 0) {
        avg = this.model.get('AvmEstimatedPrice').Estimated;
        lowPrice = this.model.get('AvmEstimatedPrice').Minimum;
        highPrice = this.model.get('AvmEstimatedPrice').Maximum;
      } else {
        var prices = _.map(this.getPropertiesShowing(), function (listing) {
          return listing.get('Price');
        });
        var sum = _.reduce(prices, function (memo, num) {
          return memo + num;
        }, 0);
        avg = sum / prices.length;
        lowPrice = avg * 0.8;
        highPrice = avg * 1.2;
      }

      this.$('.js-estimate-price-min').text('$' + Rev.Utils.String.numberWithCommas(Math.round(lowPrice)));
      this.$('.js-estimate-price-estimated').text('$' + Rev.Utils.String.numberWithCommas(Math.round(avg)));
      this.$('.js-estimate-price-max').text('$' + Rev.Utils.String.numberWithCommas(Math.round(highPrice)));
    },
    updateAdjustedPriceLabel: function updateAdjustedPriceLabel() {

      var isAdjustedPrice = false;
      var properties = this.getPropertiesShowing();
      _.each(properties, function (listing) {
        if (listing.attributes.IsAdjustedPrice) {
          isAdjustedPrice = true;
        }
      });

      if (isAdjustedPrice) {
        this.$('.indicates-adjusted-price').removeClass('hide');
        this.$('.indicates-adjusted-price').addClass('visible-xs');
      } else {
        this.$('.indicates-adjusted-price').addClass('hide');
        this.$('.indicates-adjusted-price').removeClass('visible-xs');
      }
    },
    arePropertiesShowingSelectedByAgent: function arePropertiesShowingSelectedByAgent() {
      var propertiesShowing = this.getPropertiesShowing();
      var arePropertiesShowingSelectedByAgent = propertiesShowing.length && _.every(propertiesShowing, function (p) {
        return p.get('SelectedByAgent');
      });
      return arePropertiesShowingSelectedByAgent;
    },
    getPropertiesShowing: function getPropertiesShowing() {
      var ids = this.getShownGnafIds();
      var propertiesShowing = this.avmCandidatesList.filter(function (listing) {
        return _.contains(ids, listing.get('GnafAddressId'));
      });
      return propertiesShowing;
    },
    toggleViews: function toggleViews() {
      if (this.avmCandidatesList != null && this.avmCandidatesList.length > 0) {
        this.$('.price-estimate-view').removeClass('hide');
        this.$('.avm-three-comps-items').removeClass('hide');
        this.$('.avm-no-comps').addClass('hide');
      } else {
        this.$('.price-estimate-view').addClass('hide');
        this.$('.avm-three-comps-items').addClass('hide');
        this.$('.avm-no-comps').removeClass('hide');
      }
    }
  });
})(Rev, jQuery, _, Backbone);
'use strict';

(function (Rev, $, _, Backbone) {

  'use strict';

  Rev.Routers.AgencyDetailsRouter = Backbone.Router.extend({
    routes: {
      '(/)real-estate-agency/:seoSlug-:agencyId(/)': 'detailsPage',
      '(/)agencies/:agencyId(/)': 'detailsPage'
    },

    detailsPage: function detailsPage(seoSlug, agencyId) {
      var url = '/json/details/agencies/' + agencyId + '/';

      var wait = Rev.IsiPad ? 500 : 0;
      Rev.Utils.Loader.show();

      setTimeout(function () {
        $.getJSON(url).done(function (result) {
          var viewHtml = result.view;
          var data = result.model;

          // #1 clear old resource. remove details page and js instance
          if (Rev.Views.listDetailsView) Rev.Views.listDetailsView.remove();

          // #2 hide result page and append details view html
          Rev.trigger('agency-result-page:hide');
          $('#layout-content').append(viewHtml); // append details page

          // #3 create view instance
          var model = new Rev.Models.AgencyDetails(data);
          Rev.Views.listDetailsView = new Rev.Views.AgencyDetailsView({ model: model });

          // #4 scroll to the top of the page
          $("html, body").scrollTop(0);

          // #6 show 'back-to-search-results' button (ONLY FOR IPAD AND DESKTOP)
          //Rev.trigger('back-to-search-results-button:show');

          // #7 show header (ONLY FOR IPAD AND DESKTOP)
          $('#layout-body').removeClass('no-show');

          // #8 Trigger pageview for details page
          Rev.Utils.GaTracking.tracGaPageview(location.pathname);
        }).fail(function () {
          alert('error');
          Rev.Utils.Loader.hide();
        }).always(function () {
          Rev.Utils.Loader.hide();
        });
      }, wait);
    }

  });
})(Rev, jQuery, _, Backbone);
'use strict';

(function (Rev, $, _, Backbone) {

  'use strict';

  Rev.Routers.AgencySearchResultRouter = Backbone.Router.extend({
    routes: {
      '(/)portal/searchagency/*': 'resultPage',
      '(/)portal/seosearchagency/listings/json/': 'seoResultPage'
      // NOTE that following will make another side effect which show blank screen when back from details page to agency seo result page. e.g. http://localhost:3000/real-estate-agents/lj-hooker-dural/sale/
      //'(/)real-estate-agents/:agentName(/)': 'seoResultPage',
      //'(/)real-estate-agents/:agentName/:page(/)': 'seoResultPage',
      //'(/)real-estate-agents/:agentName(/)/:state(/)': 'seoResultPage',
      //'(/)real-estate-agents/:agentName(/)/:state/:page(/)': 'seoResultPage',
    },

    resultPage: function resultPage(param, test) {
      // remove details page and js instance
      if (Rev.Views.listDetailsView) Rev.Views.listDetailsView.remove();

      var listingUrl = '/portal/searchagency/listings/json/?';

      /* this case means there is no result page rendered before so render result page from scratch */
      if ($('#layout-content .result-page').length === 0) {
        //this.renderResultPage(resultPageUrl + param);
        window.location.reload(true);
        return;
      }

      if ($('#layout-content .result-page').is(':visible')) {
        Rev.trigger('agency-result:shownext', listingUrl + param);
      } else {
        this.makeResultPageVisible();
      }
    },

    seoResultPage: function seoResultPage(param, test) {
      // remove details page and js instance
      if (Rev.Views.listDetailsView) Rev.Views.listDetailsView.remove();

      var listingUrl = '/portal/seosearchagency/listings/json/?';

      /* this case means there is no result page rendered before so render result page from scratch */
      if ($('#layout-content .result-page').length === 0) {
        //this.renderResultPage(resultPageUrl + param);
        window.location.reload(true);
        return;
      }

      if ($('#layout-content .result-page').is(':visible')) {
        Rev.trigger('agency-result:shownext', listingUrl + param);
      } else {
        this.makeResultPageVisible();
      }
    },

    makeResultPageVisible: function makeResultPageVisible() {
      var self = this;

      // make sure document scrollable when returning back from details page with modal popup is open
      $('body').removeClass('modal-open');

      Rev.trigger('agency-result-page:show');
      //Rev.trigger('back-to-search-results-button:show');  // FOR DESKTOP/IPAD
      //Rev.trigger('new-search-button:hide');  // FOR DESKTOP/IPAD

      // scroll to the position where user was. scrollTopInResultPage is stored by app.js
      if (self.scrollTopInResultPage) setTimeout(function () {
        return $(window).scrollTop(self.scrollTopInResultPage);
      }, 50);

      // this codes is needed since we trigger ga pageview for details page in agency_details_router.js
      // when user returning back to result page from details page, we need to set page parameter to result page and send pageview 
      // reference : https://developers.google.com/analytics/devguides/collection/analyticsjs/single-page-applications
      Rev.Utils.GaTracking.tracGaPageview(location.pathname);
    }
  });
})(Rev, jQuery, _, Backbone);
'use strict';

(function (Rev, $, _, Backbone) {

  'use strict';

  Rev.Routers.ContractTypeRouter = Backbone.Router.extend({
    routes: {
      '(/)': 'buy',
      '(/)rental-properties(/)': 'rent',
      '(/)sold-properties(/)': 'sold'
    },

    buy: function buy() {},

    rent: function rent() {},

    sold: function sold() {}

  });
})(Rev, jQuery, _, Backbone);
'use strict';

(function (Rev, $, _, Backbone) {

  'use strict';

  Rev.Routers.RecentHistoryRouter = Backbone.Router.extend({
    routes: {
      '(/)properties/recent(/)': 'resultPage'
    },

    resultPage: function resultPage(param) {
      // remove details page and js instance
      if (Rev.Views.listDetailsView) Rev.Views.listDetailsView.remove();

      var resultPageUrl = '/properties/recent/json/?';

      /* this case means there is no result page rendered before so render result page from scratch */
      if ($('#layout-content .result-page').length === 0) {
        //this.renderResultPage(resultPageUrl + param);
        window.location.reload(true);
        return;
      }

      // otherwise we just show existing result page. 
      // there is no paging in recent history result page
      this.makeResultPageVisible();
    },

    makeResultPageVisible: function makeResultPageVisible() {
      // make sure document scrollable when returning back from details page with modal popup is open
      $('body').removeClass('modal-open');

      Rev.trigger('result:page:show');
      Rev.trigger('back-to-search-results-button:hide'); // ONLY FOR IPAD/DESKTOP SITE

      // scroll to the position where user was.
      //$(window).scrollTop(this.scrollTopInResultPage);

      // this codes is needed since we trigger ga pageview for details page in details_router.js
      // when user returning back to result page from details page, we need to set page parameter to result page and send pageview 
      // reference : https://developers.google.com/analytics/devguides/collection/analyticsjs/single-page-applications
      Rev.Utils.GaTracking.tracGaPageview(location.pathname);
    }

  });
})(Rev, jQuery, _, Backbone);
'use strict';

(function (Rev, $, _, Backbone) {

  'use strict';

  Rev.Routers.SearchResultRouter = Backbone.Router.extend({
    routes: {
      '(/)portal/search/*': 'resultPage',
      '(/)map/search/*': 'mapResultPage',
      '(/)*prefix/*path': 'listingSeoResultPage'
    },

    resultPage: function resultPage(param) {
      // remove details page and js instance
      if (Rev.Views.listDetailsView) Rev.Views.listDetailsView.remove();

      var resultPageUrl = '/portal/search/json/?';
      var listingUrl = '/portal/search/listings/json/?';

      /* this case means there is no result page rendered before so render result page from scratch */
      if ($('#layout-content .result-page').length === 0) {
        //this.renderResultPage(resultPageUrl + param);
        window.location.reload(true);
        return;
      }

      if ($('#layout-content .result-page').is(':visible')) {
        Rev.trigger('result:shownext', listingUrl + param);
      } else {
        this.makeResultPageVisible();
      }
    },

    mapResultPage: function mapResultPage(param) {
      var _this = this;

      // remove details page and js instance
      if (Rev.Views.listDetailsView) Rev.Views.listDetailsView.remove();

      /* this case means there is no result page rendered before so render result page from scratch */
      if ($('#layout-content .result-page').length === 0) {
        window.location.reload(true);
        return;
      }

      setTimeout(function () {
        if (!$('#layout-content .result-page').is(':visible')) {
          _this.makeResultPageVisible();
        }
      }, 300);
    },

    listingSeoResultPage: function listingSeoResultPage(prefix, path, queryString) {
      this.seoResultPage('/' + prefix + '/' + path, queryString);
    },

    seoResultPage: function seoResultPage(path, queryString) {
      // remove details page and js instance
      if (Rev.Views.listDetailsView) Rev.Views.listDetailsView.remove();

      var ajaxUrl = path;

      if (queryString) {
        ajaxUrl += '?' + queryString;
      }

      /* this case means there is no result page rendered before so render result page from scratch */
      if ($('#layout-content .result-page').length === 0) {
        window.location.reload(true);
        return;
      }

      if ($('#layout-content .result-page').is(':visible')) {
        Rev.trigger('result:shownext', ajaxUrl);
      } else {
        this.makeResultPageVisible();
      }
    },

    makeResultPageVisible: function makeResultPageVisible() {
      var self = this;

      // make sure document scrollable when returning back from details page with modal popup is open
      $('body').removeClass('modal-open');

      Rev.trigger('result:page:show');
      Rev.trigger('refine-search-button:show'); // FOR MOBILE
      Rev.trigger('back-to-search-results-button:show'); // FOR DESKTOP/IPAD
      Rev.trigger('new-search-button:hide'); // FOR DESKTOP/IPAD
      Rev.trigger('save-search-buttons:show'); // show save search buttons on header section, they are located in header

      // scroll to the position where user was. scrollTopInResultPage is stored by list_result_view.js or app.js
      if (self.scrollTopInResultPage) setTimeout(function () {
        return $(window).scrollTop(self.scrollTopInResultPage);
      }, 50);

      // update page title
      if (Rev.OldSearchResultPageTitle) $('head title').text(Rev.OldSearchResultPageTitle);

      // this codes is needed since we trigger ga pageview for details page in details_router.js
      // when user returning back to result page from details page, we need to set page parameter to result page and send pageview 
      // reference : https://developers.google.com/analytics/devguides/collection/analyticsjs/single-page-applications
      Rev.Utils.GaTracking.tracGaPageview(location.pathname);
    }
  });
})(Rev, jQuery, _, Backbone);
'use strict';

(function (Rev, $, _, Backbone) {

  'use strict';

  Rev.Routers.ShortlistRouter = Backbone.Router.extend({
    initialize: function initialize() {
      _.bindAll(this, 'makeResultPageVisible');
      //this.listenTo(Rev, 'onpopstate', this.makeResultPageVisible);
    },

    routes: {
      '(/)properties/shortlist/*': 'resultPage'
    },

    resultPage: function resultPage(param) {
      // remove details page and js instance
      if (Rev.Views.listDetailsView) Rev.Views.listDetailsView.remove();

      //var resultPageUrl = '/properties/shortlist/json?';
      var listingUrl = '/properties/shortlist/listings/json?';

      /* this case means there is no result page rendered before so render result page from scratch */
      if ($('#layout-content .result-page').length === 0) {
        window.location.reload(true);
        return;
      }

      if ($('#layout-content .result-page').is(':visible')) {
        Rev.trigger('result:shownext', listingUrl + param);
      } else {
        this.makeResultPageVisible();
      }
    },

    makeResultPageVisible: function makeResultPageVisible() {
      var self = this;

      // make sure document scrollable when returning back from details page with modal popup is open
      $('body').removeClass('modal-open');

      Rev.trigger('result:page:show');
      Rev.trigger('back-to-search-results-button:show'); // ONLY FOR IPAD/DESKTOP SITE

      // scroll to the position where user was.
      if (self.scrollTopInResultPage) setTimeout(function () {
        return $(window).scrollTop(self.scrollTopInResultPage);
      }, 50);

      // this codes is needed since we trigger ga pageview for details page in details_router.js
      // when user returning back to result page from details page, we need to set page parameter to result page and send pageview 
      // reference : https://developers.google.com/analytics/devguides/collection/analyticsjs/single-page-applications
      Rev.Utils.GaTracking.tracGaPageview(location.pathname);
    }

  });
})(Rev, jQuery, _, Backbone);
'use strict';

(function (Rev, $, _, Backbone) {

  'use strict';

  // disable cache in ajax

  $.ajaxSetup({ cache: false });

  // instantiate routers
  Rev.Routers.searchResultRouter = new Rev.Routers.SearchResultRouter();
  Rev.Routers.shortlistRouter = new Rev.Routers.ShortlistRouter();
  Rev.Routers.recentHistoryRouter = new Rev.Routers.RecentHistoryRouter();
  Rev.Routers.agencySearchResultRouter = new Rev.Routers.AgencySearchResultRouter();
  Rev.Routers.agencyDetailsRouter = new Rev.Routers.AgencyDetailsRouter();
  Rev.Routers.contractTypeRouter = new Rev.Routers.ContractTypeRouter();

  Backbone.history.start({ pushState: true, hashChange: false, silent: true });

  // instantiate fastclick
  $(function () {
    FastClick.attach(document.body);
  });

  // for safari iphone back button cache. 
  // http://stackoverflow.com/questions/7988967/problems-with-page-cache-in-ios-5-safari-when-navigating-back-unload-event-not
  // http://stackoverflow.com/questions/5297122/preventing-cache-on-back-button-in-safari-5
  // http://stackoverflow.com/questions/9038625/detect-if-device-is-ios
  var isIOS = /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream;
  if (isIOS) {
    window.onpageshow = function (evt) {
      // If persisted then it is in the page cache, force a reload of the page.
      if (evt.persisted) {
        document.body.style.display = "none";
        location.reload();
      }
    };
  }

  // ga tracking
  $(document).on('click', '[data-ga-event]', function (e) {
    //Parameters: category, action, label
    var params = $(this).data("ga-event").split(',');
    Rev.Utils.GaTracking.trackGaEvent.apply(this, params);
  });

  // hashChange handler
  $(window).on('hashchange', onHashChange);

  function onHashChange(e, test) {
    var oldURL = e.originalEvent.oldURL;

    if (oldURL.indexOf('#filter-location') > -1) {
      Rev.trigger('filter-location-close');
    } else if (oldURL.indexOf('#filter-property-types') > -1) {
      Rev.trigger('filter-property-types-close');
    } else if (oldURL.indexOf('#filter-price') > -1) {
      Rev.trigger('filter-price-close');
    } else if (oldURL.indexOf('#photo-modal') > -1) {
      Rev.trigger('photo:modal:close');
    } else if (oldURL.indexOf('#floorplan-modal') > -1) {
      Rev.trigger('floorplan:modal:close');
    }
  };

  //window.onpopstate = function (event) {
  //  Rev.trigger('onpopstate', { locationUrl: document.location, state: event.state });
  //};

  // event handlers for elements that is not included in specific view instance
  $(document).on('click', '#rev-overlay', function (e) {
    Rev.trigger('photo:modal:close'); // FOR PHONE
    Rev.trigger('sidebar:toggle'); // FOR DESKTOP/IPAD
  })
  // reveal text
  .on('click', '.revealable-text', function (e) {
    if (e && e.preventDefault) e.preventDefault();

    $(e.currentTarget).find('.open-text').hide();
    $(e.currentTarget).find('.closed-text').show();
  }).on('click', '.top-btn.elevator-button', function (e) {
    window.scrollTo(0, 0);
  });

  // Fix ios virtual keyboard issue (http://www.abeautifulsite.net/bootstrap-3-modals-and-the-ios-virtual-keyboard/)
  if (navigator.userAgent.match(/iPhone|iPad|iPod/i)) {
    $('.modal').on('show.bs.modal', function () {
      $(this).css({
        position: 'absolute',
        marginTop: $(window).scrollTop() + 'px',
        bottom: 'auto'
      });
      setTimeout(function () {
        $('.modal-backdrop').css({
          position: 'absolute',
          top: 0,
          left: 0,
          width: '100%',
          height: Math.max(document.body.scrollHeight, document.documentElement.scrollHeight, document.body.offsetHeight, document.documentElement.offsetHeight, document.body.clientHeight, document.documentElement.clientHeight) + 'px'
        });
      }, 0);
    });
  }

  // FOR DESKTOP/IPAD
  if (!Rev.IsPhone) {
    var opacity = '0.3';
    var img = 'view_home.jpg';
    var currentHour = new Date().getHours();
    if (5 <= currentHour && currentHour <= 6) {
      img = 'view_home.jpg';
    } else if (7 <= currentHour && currentHour <= 9) {
      img = 'view_home.jpg';
    } else if (10 <= currentHour && currentHour <= 11) {
      img = 'view_home.jpg';
    } else if (12 <= currentHour && currentHour <= 14) {
      img = 'view_home.jpg';
    } else if (15 <= currentHour && currentHour <= 17) {
      img = 'view_home.jpg';
    } else if (18 <= currentHour && currentHour <= 19) {
      img = 'view_home.jpg';
    } else if (20 <= currentHour && currentHour <= 21) {
      img = 'view_home.jpg';
    } else if (22 <= currentHour && currentHour <= 23) {
      img = 'view_home.jpg';
    } else if (0 <= currentHour && currentHour <= 4) {
      img = 'view_home.jpg';
    }

    var bgStyle = {
      //'background-image' : '-webkit-linear-gradient( rgba(0, 0, 0, ' + opacity + '), rgba(0, 0, 0, ' + opacity + ') ), url(/assets/content/images/' + img + ')',
      //'background-image' : '   -moz-linear-gradient( rgba(0, 0, 0, ' + opacity + '), rgba(0, 0, 0, ' + opacity + ') ), url(/assets/content/images/' + img + ')',
      //'background-image' : '        linear-gradient( rgba(0, 0, 0, ' + opacity + '), rgba(0, 0, 0, ' + opacity + ') ), url(/assets/content/images/' + img + ')'
      'background-image': 'url(/assets/content/images/' + img + ')'
    };
    $('.hero-bg-wrapper .bg-placeholder').css(bgStyle);
    $('.hero-bg-wrapper').css({ 'margin-top': $('#layout-header').outerHeight() });

    $('.hero-bg-wrapper .bg-placeholder').imagesLoaded({ background: true }, function () {
      $('.hero-bg-wrapper .bg-placeholder').addClass('pull-down');
    });

    //imagesLoaded('.hero-bg-wrapper img', function() {
    //  $('.hero-bg-wrapper img').addClass('pull-down');
    //});
  }

  // append loader template to the body
  Rev.Utils.Loader.loadTemplate();

  // create instance for new search form
  if ($('.new-search-form').length) {
    new Rev.Views.NewSearchFormView({ el: '.new-search-form' });
  }

  if ($('.result-page.search-result-page').is(':visible') || $('#layout-content .search-form').is(':visible') || $('#layout-content .agency-search-page').is(':visible')) {
    Rev.trigger('new-search-button:hide');
  } else {
    Rev.trigger('new-search-button:show');
  }

  // scroll event
  var timer, lastScrollTop;
  var onScroll = function onScroll() {
    if (timer != null) clearTimeout(timer);
    timer = setTimeout(function () {

      var isResultPage = $('.result-page').is(':visible');
      var isDetailsPage = $('.details-page').is(':visible');

      if (isResultPage) {
        Rev.trigger('list-item-view:viewport:toggle');
      }

      var st = $(window).scrollTop();

      if (!Rev.IsiPad) {
        $('.result-header, .new-search-form').removeClass('open');

        if (st > lastScrollTop && st > 150) {
          // downscroll, 150 is just buffer            
          $('#layout-body').addClass('no-show');
        } else {
          // upscroll            
          $('#layout-body').removeClass('no-show');
        }
        lastScrollTop = st;
      }

      if (isResultPage) {
        if ($('#layout-content .result-page.search-result-page').is(':visible')) {
          Rev.Routers.searchResultRouter.scrollTopInResultPage = st;
        } else if ($('#layout-content .result-page.shortlist-page').is(':visible')) {
          Rev.Routers.shortlistRouter.scrollTopInResultPage = st;
        } else if ($('#layout-content .result-page.recent-history-page').is(':visible')) {
          Rev.Routers.recentHistoryRouter.scrollTopInResultPage = st;
        } else if ($('#layout-content .result-page.agency-search-result-page').is(':visible')) {
          Rev.Routers.agencySearchResultRouter.scrollTopInResultPage = st;
        }
      }
    }, 100);
  };

  var isEaia = $('#layout-content > section').hasClass('eaia');

  // don't do scroll event in eaia pages
  if (!isEaia) {
    $(window).on('scroll', onScroll);
  }
})(Rev, jQuery, _, Backbone);;
