<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">
/* Reverse Router */
const _rr = {
  "ObjectsList": {
    "search": function() { return __reverse_route("ObjectsList", "search", arguments, [{"mname":"search","cname":"ObjectsList","path":"\/a-vendre","args":[{"source":"fixed","name":"lang","value":"fr","constraint":"string"},{"source":"fixed","value":18745,"constraint":"integer"}]},{"mname":"search","cname":"ObjectsList","path":"\/a-louer","args":[{"source":"fixed","name":"lang","value":"fr","constraint":"string"},{"source":"fixed","value":18747,"constraint":"integer"}]},{"method":"GET","holes":{"id":{"pattern":"[^\/]+","canBeRefined":true},"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/ol\/#id#","cname":"ObjectsList","mname":"search","args":[{"source":"hole","name":"lang","constraint":null},{"source":"hole","name":"id","constraint":null}]}]); },
    "first": function() { return __reverse_route("ObjectsList", "first", arguments, [{"method":"GET","holes":{"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/o","cname":"ObjectsList","mname":"first","args":[{"source":"hole","name":"lang","constraint":null}]}]); },
    "all": function() { return __reverse_route("ObjectsList", "all", arguments, [{"method":"GET","holes":{"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/o\/all","cname":"ObjectsList","mname":"all","args":[{"source":"hole","name":"lang","constraint":null}]}]); },
    "redirectToIdent": function() { return __reverse_route("ObjectsList", "redirectToIdent", arguments, [{"method":"GET","holes":{"ident":{"pattern":"[^\/]+","canBeRefined":true},"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/#ident#","cname":"ObjectsList","mname":"redirectToIdent","args":[{"source":"hole","name":"lang","constraint":null},{"source":"hole","name":"ident","constraint":null}]}]); },
  },
  "Cms": {
    "page": function() { return __reverse_route("Cms", "page", arguments, [{"mname":"page","cname":"Cms","path":"\/fr","args":[{"source":"fixed","name":"lang","value":"fr","constraint":"string"},{"source":"ignored","value":"accueil","constraint":"string"},{"source":"fixed","value":18743,"constraint":"integer"}]},{"method":"GET","holes":{"pretty":{"pattern":"[^\/]+","canBeRefined":true},"id":{"pattern":"[^\/]+","canBeRefined":true},"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/c\/#pretty#-#id#","cname":"Cms","mname":"page","args":[{"source":"hole","name":"lang","constraint":null},{"source":"hole","name":"pretty","constraint":null},{"source":"hole","name":"id","constraint":"int"}]}]); },
    "subPage": function() { return __reverse_route("Cms", "subPage", arguments, [{"method":"GET","holes":{"pretty":{"pattern":"[^\/]+","canBeRefined":true},"id":{"pattern":"[^\/]+","canBeRefined":true},"sid":{"pattern":"[^\/]+","canBeRefined":true},"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/c\/#pretty#-#id#\/#sid#","cname":"Cms","mname":"subPage","args":[{"source":"hole","name":"lang","constraint":null},{"source":"hole","name":"pretty","constraint":null},{"source":"hole","name":"id","constraint":"int"},{"source":"hole","name":"sid","constraint":"int"}]}]); },
    "popup": function() { return __reverse_route("Cms", "popup", arguments, [{"method":"GET","holes":{"id":{"pattern":"[^\/]+","canBeRefined":true},"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/a\/c\/popup\/#id#","cname":"Cms","mname":"popup","args":[{"source":"hole","name":"lang","constraint":null},{"source":"hole","name":"id","constraint":"int"}]}]); },
  },
  "Main": {
    "negotiateLanguage": function() { return __reverse_route("Main", "negotiateLanguage", arguments, [{"method":"GET","holes":[],"path":"\/","cname":"Main","mname":"negotiateLanguage","args":[]}]); },
    "landing": function() { return __reverse_route("Main", "landing", arguments, [{"method":"GET","holes":{"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#","cname":"Main","mname":"landing","args":[{"source":"hole","name":"lang","constraint":null}]}]); },
    "error404": function() { return __reverse_route("Main", "error404", arguments, [{"method":"GET","holes":{"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/error404","cname":"Main","mname":"error404","args":[{"source":"hole","name":"lang","constraint":null}]}]); },
    "deactivated": function() { return __reverse_route("Main", "deactivated", arguments, [{"method":"GET","holes":{"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/deactivated","cname":"Main","mname":"deactivated","args":[{"source":"hole","name":"lang","constraint":null}]}]); },
  },
  "ShortUrl": {
    "handle": function() { return __reverse_route("ShortUrl", "handle", arguments, [{"method":"GET","holes":{"ident":{"pattern":"[0-9a-z]+","canBeRefined":false}},"path":"\/#ident#","cname":"ShortUrl","mname":"handle","args":[{"source":"hole","name":"ident","constraint":null}]}]); },
  },
  "Login": {
    "login": function() { return __reverse_route("Login", "login", arguments, [{"method":"GET","holes":{"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/login","cname":"Login","mname":"login","args":[{"source":"hole","name":"lang","constraint":null}]}]); },
    "loginPopup": function() { return __reverse_route("Login", "loginPopup", arguments, [{"method":"GET","holes":{"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/a\/login","cname":"Login","mname":"loginPopup","args":[{"source":"hole","name":"lang","constraint":null}]}]); },
    "loginAuto": function() { return __reverse_route("Login", "loginAuto", arguments, [{"method":"GET","holes":{"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/login\/auto","cname":"Login","mname":"loginAuto","args":[{"source":"hole","name":"lang","constraint":null}]},{"method":"GET","holes":{"user_id":{"pattern":"[^\/]+","canBeRefined":true},"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/login\/auto\/#user_id#","cname":"Login","mname":"loginAuto","args":[{"source":"hole","name":"lang","constraint":null},{"source":"hole","name":"user_id","constraint":null}]}]); },
    "authorize": function() { return __reverse_route("Login", "authorize", arguments, [{"method":"GET","holes":{"tok":{"pattern":"[^\/]+","canBeRefined":true},"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/login\/authorize\/#tok#","cname":"Login","mname":"authorize","args":[{"source":"hole","name":"lang","constraint":null},{"source":"hole","name":"tok","constraint":null}]}]); },
    "loginWithIDP": function() { return __reverse_route("Login", "loginWithIDP", arguments, [{"method":"GET","holes":{"id":{"pattern":"[^\/]+","canBeRefined":true},"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/a\/loginwith\/#id#","cname":"Login","mname":"loginWithIDP","args":[{"source":"hole","name":"lang","constraint":null},{"source":"hole","name":"id","constraint":null}]}]); },
    "oauthCallback": function() { return __reverse_route("Login", "oauthCallback", arguments, [{"method":"GET","holes":[],"path":"\/oauth\/callback","cname":"Login","mname":"oauthCallback","args":[]}]); },
    "logout": function() { return __reverse_route("Login", "logout", arguments, [{"method":"GET","holes":{"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/logout","cname":"Login","mname":"logout","args":[{"source":"hole","name":"lang","constraint":null}]}]); },
    "loginDo": function() { return __reverse_route("Login", "loginDo", arguments, [{"method":"POST","holes":{"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/a\/login","cname":"Login","mname":"loginDo","args":[{"source":"hole","name":"lang","constraint":null}]}]); },
  },
  "Demo": {
    "chooserPopup": function() { return __reverse_route("Demo", "chooserPopup", arguments, [{"method":"GET","holes":{"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/a\/demo\/chooser","cname":"Demo","mname":"chooserPopup","args":[{"source":"hole","name":"lang","constraint":null}]}]); },
    "chooser": function() { return __reverse_route("Demo", "chooser", arguments, [{"method":"GET","holes":{"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/demo\/chooser","cname":"Demo","mname":"chooser","args":[{"source":"hole","name":"lang","constraint":null}]}]); },
  },
  "Maintenance": {
    "index": function() { return __reverse_route("Maintenance", "index", arguments, [{"method":"GET","holes":{"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/maintenance","cname":"Maintenance","mname":"index","args":[{"source":"hole","name":"lang","constraint":null}]}]); },
    "project_archived": function() { return __reverse_route("Maintenance", "project_archived", arguments, [{"method":"GET","holes":{"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/p\/archived","cname":"Maintenance","mname":"project_archived","args":[{"source":"hole","name":"lang","constraint":null}]}]); },
  },
  "Information": {
    "contact": function() { return __reverse_route("Information", "contact", arguments, [{"method":"GET","holes":{"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/contact","cname":"Information","mname":"contact","args":[{"source":"hole","name":"lang","constraint":null}]}]); },
    "terms": function() { return __reverse_route("Information", "terms", arguments, [{"method":"GET","holes":{"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/terms","cname":"Information","mname":"terms","args":[{"source":"hole","name":"lang","constraint":null}]}]); },
    "cookies": function() { return __reverse_route("Information", "cookies", arguments, [{"method":"GET","holes":{"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/cookies","cname":"Information","mname":"cookies","args":[{"source":"hole","name":"lang","constraint":null}]}]); },
    "presentation": function() { return __reverse_route("Information", "presentation", arguments, [{"method":"GET","holes":{"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/presentation","cname":"Information","mname":"presentation","args":[{"source":"hole","name":"lang","constraint":null}]}]); },
  },
  "Blog": {
    "index": function() { return __reverse_route("Blog", "index", arguments, [{"method":"GET","holes":{"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/blog","cname":"Blog","mname":"index","args":[{"source":"hole","name":"lang","constraint":null}]},{"method":"GET","holes":{"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/blog\/index","cname":"Blog","mname":"index","args":[{"source":"hole","name":"lang","constraint":null}]}]); },
    "all": function() { return __reverse_route("Blog", "all", arguments, [{"method":"GET","holes":{"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/blog\/all","cname":"Blog","mname":"all","args":[{"source":"hole","name":"lang","constraint":null}]}]); },
    "article": function() { return __reverse_route("Blog", "article", arguments, [{"method":"GET","holes":{"ym":{"pattern":"[^\/]+","canBeRefined":true},"title":{"pattern":"[^\/]+","canBeRefined":true},"id":{"pattern":"[^\/]+","canBeRefined":true},"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/blog\/#ym#\/#title#-#id#","cname":"Blog","mname":"article","args":[{"source":"hole","name":"lang","constraint":null},{"source":"hole","name":"ym","constraint":null},{"source":"hole","name":"id","constraint":"int"},{"source":"hole","name":"title","constraint":null}]}]); },
  },
  "Jobs": {
    "index": function() { return __reverse_route("Jobs", "index", arguments, [{"method":"GET","holes":{"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/jobs","cname":"Jobs","mname":"index","args":[{"source":"hole","name":"lang","constraint":null}]}]); },
  },
  "Objects": {
    "details": function() { return __reverse_route("Objects", "details", arguments, [{"method":"GET","holes":{"pretty":{"pattern":"[^\/]+","canBeRefined":true},"id":{"pattern":"[^\/]+","canBeRefined":true},"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/o\/#pretty#-#id#","cname":"Objects","mname":"details","args":[{"source":"hole","name":"lang","constraint":null},{"source":"hole","name":"pretty","constraint":null},{"source":"hole","name":"id","constraint":"int"}]}]); },
    "search": function() { return __reverse_route("Objects", "search", arguments, [{"method":"GET","holes":{"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/o\/search","cname":"Objects","mname":"search","args":[{"source":"hole","name":"lang","constraint":null}]}]); },
    "energyEfficiency": function() { return __reverse_route("Objects", "energyEfficiency", arguments, [{"method":"GET","holes":{"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/o\/energy_efficiency.svg","cname":"Objects","mname":"energyEfficiency","args":[{"source":"hole","name":"lang","constraint":null},{"source":"param","name":"global","constraint":null},{"source":"param","name":"envelope","constraint":null}]}]); },
    "references": function() { return __reverse_route("Objects", "references", arguments, [{"method":"GET","holes":{"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/o\/references","cname":"Objects","mname":"references","args":[{"source":"hole","name":"lang","constraint":null}]}]); },
    "edit": function() { return __reverse_route("Objects", "edit", arguments, [{"method":"GET","holes":{"id":{"pattern":"[^\/]+","canBeRefined":true},"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/o\/edit\/#id#","cname":"Objects","mname":"edit","args":[{"source":"hole","name":"lang","constraint":null},{"source":"hole","name":"id","constraint":null}]}]); },
    "video": function() { return __reverse_route("Objects", "video", arguments, [{"method":"GET","holes":{"id":{"pattern":"[^\/]+","canBeRefined":true},"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/o\/video\/#id#","cname":"Objects","mname":"video","args":[{"source":"hole","name":"lang","constraint":null},{"source":"hole","name":"id","constraint":null}]}]); },
    "virtualTour": function() { return __reverse_route("Objects", "virtualTour", arguments, [{"method":"GET","holes":{"id":{"pattern":"[^\/]+","canBeRefined":true},"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/o\/virtual\/#id#","cname":"Objects","mname":"virtualTour","args":[{"source":"hole","name":"lang","constraint":null},{"source":"hole","name":"id","constraint":null}]}]); },
    "similarObjects": function() { return __reverse_route("Objects", "similarObjects", arguments, [{"method":"GET","holes":{"id":{"pattern":"[^\/]+","canBeRefined":true},"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/o\/similar\/#id#","cname":"Objects","mname":"similarObjects","args":[{"source":"hole","name":"lang","constraint":null},{"source":"hole","name":"id","constraint":null}]}]); },
    "mandatoryVisitPopup": function() { return __reverse_route("Objects", "mandatoryVisitPopup", arguments, [{"method":"GET","holes":{"id":{"pattern":"[^\/]+","canBeRefined":true},"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/o\/mandatoryvisit\/#id#","cname":"Objects","mname":"mandatoryVisitPopup","args":[{"source":"hole","name":"lang","constraint":null},{"source":"hole","name":"id","constraint":null}]}]); },
    "ajaxTableContent": function() { return __reverse_route("Objects", "ajaxTableContent", arguments, [{"method":"GET","holes":{"oid":{"pattern":"[^\/]+","canBeRefined":true},"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/a\/o\/table\/#oid#","cname":"Objects","mname":"ajaxTableContent","args":[{"source":"hole","name":"lang","constraint":null},{"source":"hole","name":"oid","constraint":null}]}]); },
    "ajaxPopupContent": function() { return __reverse_route("Objects", "ajaxPopupContent", arguments, [{"method":"GET","holes":{"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/a\/o\/popup","cname":"Objects","mname":"ajaxPopupContent","args":[{"source":"hole","name":"lang","constraint":null}]}]); },
    "ajaxSearchList": function() { return __reverse_route("Objects", "ajaxSearchList", arguments, [{"method":"GET","holes":{"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/a\/o\/search\/list","cname":"Objects","mname":"ajaxSearchList","args":[{"source":"hole","name":"lang","constraint":null}]}]); },
    "ajaxSearchMap": function() { return __reverse_route("Objects", "ajaxSearchMap", arguments, [{"method":"GET","holes":{"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/a\/o\/search\/map","cname":"Objects","mname":"ajaxSearchMap","args":[{"source":"hole","name":"lang","constraint":null}]}]); },
    "ajaxSearchCount": function() { return __reverse_route("Objects", "ajaxSearchCount", arguments, [{"method":"GET","holes":{"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/a\/o\/search\/count","cname":"Objects","mname":"ajaxSearchCount","args":[{"source":"hole","name":"lang","constraint":null}]}]); },
    "ajaxSearchBoth": function() { return __reverse_route("Objects", "ajaxSearchBoth", arguments, [{"method":"GET","holes":{"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/a\/o\/search","cname":"Objects","mname":"ajaxSearchBoth","args":[{"source":"hole","name":"lang","constraint":null}]}]); },
    "editDo": function() { return __reverse_route("Objects", "editDo", arguments, [{"method":"POST","holes":{"id":{"pattern":"[^\/]+","canBeRefined":true},"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/o\/edit\/#id#","cname":"Objects","mname":"editDo","args":[{"source":"hole","name":"lang","constraint":null},{"source":"hole","name":"id","constraint":null}]}]); },
    "mandatoryVisitPopupDo": function() { return __reverse_route("Objects", "mandatoryVisitPopupDo", arguments, [{"method":"POST","holes":{"id":{"pattern":"[^\/]+","canBeRefined":true},"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/o\/mandatoryvisit\/#id#","cname":"Objects","mname":"mandatoryVisitPopupDo","args":[{"source":"hole","name":"lang","constraint":null},{"source":"hole","name":"id","constraint":null}]}]); },
    "mandatoryVisitCodePopupDo": function() { return __reverse_route("Objects", "mandatoryVisitCodePopupDo", arguments, [{"method":"POST","holes":{"id":{"pattern":"[^\/]+","canBeRefined":true},"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/o\/mandatoryvisitcode\/#id#","cname":"Objects","mname":"mandatoryVisitCodePopupDo","args":[{"source":"hole","name":"lang","constraint":null},{"source":"hole","name":"id","constraint":null}]}]); },
    "reportProblem": function() { return __reverse_route("Objects", "reportProblem", arguments, [{"method":"POST","holes":{"id":{"pattern":"[^\/]+","canBeRefined":true},"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/a\/o\/report\/#id#","cname":"Objects","mname":"reportProblem","args":[{"source":"hole","name":"lang","constraint":null},{"source":"hole","name":"id","constraint":"int"}]}]); },
  },
  "Pdf": {
    "dossier": function() { return __reverse_route("Pdf", "dossier", arguments, [{"method":"GET","holes":{"pretty":{"pattern":"[^\/]+","canBeRefined":true},"id":{"pattern":"[^\/]+","canBeRefined":true},"file":{"pattern":"[^\/]+","canBeRefined":true},"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/pdf\/#pretty#-#id#\/#file#","cname":"Pdf","mname":"dossier","args":[{"source":"hole","name":"lang","constraint":null},{"source":"hole","name":"pretty","constraint":null},{"source":"hole","name":"id","constraint":"int"},{"source":"hole","name":"file","constraint":null}]},{"method":"GET","holes":{"pretty":{"pattern":"[^\/]+","canBeRefined":true},"id":{"pattern":"[^\/]+","canBeRefined":true},"file":{"pattern":"[^\/]+","canBeRefined":true},"pdfConfId":{"pattern":"[^\/]+","canBeRefined":true},"hash":{"pattern":"[^\/]+","canBeRefined":true},"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/pdf\/#pretty#-#id#\/#file#\/#pdfConfId#\/#hash#","cname":"Pdf","mname":"dossier","args":[{"source":"hole","name":"lang","constraint":null},{"source":"hole","name":"pretty","constraint":null},{"source":"hole","name":"id","constraint":"int"},{"source":"hole","name":"file","constraint":null},{"source":"hole","name":"pdfConfId","constraint":"int"},{"source":"hole","name":"hash","constraint":"string"}]}]); },
    "generateThumbnail": function() { return __reverse_route("Pdf", "generateThumbnail", arguments, [{"method":"GET","holes":{"fid":{"pattern":"[^\/]+","canBeRefined":true},"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/pdf\/document\/thumbnail\/#fid#","cname":"Pdf","mname":"generateThumbnail","args":[{"source":"hole","name":"lang","constraint":null},{"source":"hole","name":"fid","constraint":null}]}]); },
    "splitDocument": function() { return __reverse_route("Pdf", "splitDocument", arguments, [{"method":"POST","holes":{"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/pdf\/document\/split","cname":"Pdf","mname":"splitDocument","args":[{"source":"hole","name":"lang","constraint":null}]}]); },
  },
  "Financing": {
    "simulation": function() { return __reverse_route("Financing", "simulation", arguments, [{"method":"GET","holes":{"id":{"pattern":"[^\/]+","canBeRefined":true},"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/financing\/#id#","cname":"Financing","mname":"simulation","args":[{"source":"hole","name":"lang","constraint":null},{"source":"hole","name":"id","constraint":"int"}]}]); },
  },
  "Reservation": {
    "reservation": function() { return __reverse_route("Reservation", "reservation", arguments, [{"method":"GET","holes":{"id":{"pattern":"[^\/]+","canBeRefined":true},"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/o\/reservation\/#id#","cname":"Reservation","mname":"reservation","args":[{"source":"hole","name":"lang","constraint":null},{"source":"hole","name":"id","constraint":null}]}]); },
    "ajaxReservationPeriod": function() { return __reverse_route("Reservation", "ajaxReservationPeriod", arguments, [{"method":"POST","holes":{"id":{"pattern":"[^\/]+","canBeRefined":true},"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/o\/reservation\/period\/#id#","cname":"Reservation","mname":"ajaxReservationPeriod","args":[{"source":"hole","name":"lang","constraint":null},{"source":"hole","name":"id","constraint":null}]}]); },
    "ajaxBookingPeriod": function() { return __reverse_route("Reservation", "ajaxBookingPeriod", arguments, [{"method":"POST","holes":{"id":{"pattern":"[^\/]+","canBeRefined":true},"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/o\/reservation\/booking\/#id#","cname":"Reservation","mname":"ajaxBookingPeriod","args":[{"source":"hole","name":"lang","constraint":null},{"source":"hole","name":"id","constraint":null}]}]); },
  },
  "Projects": {
    "table": function() { return __reverse_route("Projects", "table", arguments, [{"method":"GET","holes":{"id":{"pattern":"[^\/]+","canBeRefined":true},"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/p\/table\/#id#","cname":"Projects","mname":"table","args":[{"source":"hole","name":"lang","constraint":null},{"source":"hole","name":"id","constraint":null}]}]); },
    "ajaxTable": function() { return __reverse_route("Projects", "ajaxTable", arguments, [{"method":"GET","holes":{"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/a\/p\/table","cname":"Projects","mname":"ajaxTable","args":[{"source":"hole","name":"lang","constraint":null}]}]); },
  },
  "Favorites": {
    "list": function() { return __reverse_route("Favorites", "list", arguments, [{"method":"GET","holes":{"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/favorites","cname":"Favorites","mname":"list","args":[{"source":"hole","name":"lang","constraint":null}]}]); },
    "update": function() { return __reverse_route("Favorites", "update", arguments, [{"method":"POST","holes":{"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/favorites\/update","cname":"Favorites","mname":"update","args":[{"source":"hole","name":"lang","constraint":null}]}]); },
  },
  "StaticContent": {
    "page": function() { return __reverse_route("StaticContent", "page", arguments, [{"method":"GET","holes":{"ident":{"pattern":"[^\/]+","canBeRefined":true},"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/s\/#ident#","cname":"StaticContent","mname":"page","args":[{"source":"hole","name":"lang","constraint":null},{"source":"hole","name":"ident","constraint":null}]}]); },
  },
  "Search": {
    "localities": function() { return __reverse_route("Search", "localities", arguments, [{"method":"GET","holes":{"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/a\/search\/localities","cname":"Search","mname":"localities","args":[{"source":"hole","name":"lang","constraint":null},{"source":"param","name":"q","constraint":null}]}]); },
    "regions": function() { return __reverse_route("Search", "regions", arguments, [{"method":"GET","holes":{"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/a\/search\/regions","cname":"Search","mname":"regions","args":[{"source":"hole","name":"lang","constraint":null},{"source":"param","name":"q","constraint":null}]}]); },
    "objectLocation": function() { return __reverse_route("Search", "objectLocation", arguments, [{"method":"GET","holes":{"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/a\/search\/object\/location","cname":"Search","mname":"objectLocation","args":[{"source":"hole","name":"lang","constraint":null},{"source":"param","name":"q","constraint":null}]}]); },
    "agencyLocation": function() { return __reverse_route("Search", "agencyLocation", arguments, [{"method":"GET","holes":{"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/a\/search\/agency\/location","cname":"Search","mname":"agencyLocation","args":[{"source":"hole","name":"lang","constraint":null},{"source":"param","name":"q","constraint":null}]}]); },
    "objectReference": function() { return __reverse_route("Search", "objectReference", arguments, [{"method":"GET","holes":{"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/a\/search\/object\/reference","cname":"Search","mname":"objectReference","args":[{"source":"hole","name":"lang","constraint":null},{"source":"param","name":"q","constraint":null}]}]); },
    "geolocate": function() { return __reverse_route("Search", "geolocate", arguments, [{"method":"GET","holes":{"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/search\/geolocate","cname":"Search","mname":"geolocate","args":[{"source":"hole","name":"lang","constraint":null}]}]); },
  },
  "Fe1Urls": {
    "opinion": function() { return __reverse_route("Fe1Urls", "opinion", arguments, [{"method":"GET","holes":{"id":{"pattern":"[^\/]+","canBeRefined":true},"authhash":{"pattern":"[^\/]+","canBeRefined":true},"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/main\/opinion\/#id#\/#authhash#","cname":"Fe1Urls","mname":"opinion","args":[{"source":"hole","name":"lang","constraint":null},{"source":"hole","name":"id","constraint":null},{"source":"hole","name":"authhash","constraint":null}]}]); },
    "objectPreview": function() { return __reverse_route("Fe1Urls", "objectPreview", arguments, [{"method":"GET","holes":{"lang":{"pattern":"[a-z]{2}","canBeRefined":false},"id":{"pattern":"[0-9]+","canBeRefined":false}},"path":"\/#lang#\/objects\/detail\/#id#","cname":"Fe1Urls","mname":"objectPreview","args":[{"source":"hole","name":"lang","constraint":null},{"source":"hole","name":"id","constraint":null},{"source":"param","name":"authhash","constraint":null}]},{"method":"GET","holes":{"pretty":{"pattern":"[^\/]+","canBeRefined":true},"lang":{"pattern":"[a-z]{2}","canBeRefined":false},"id":{"pattern":"[0-9]+","canBeRefined":false}},"path":"\/#lang#\/objects\/detail\/#id#\/#pretty#","cname":"Fe1Urls","mname":"objectPreview","args":[{"source":"hole","name":"lang","constraint":null},{"source":"hole","name":"id","constraint":null},{"source":"param","name":"authhash","constraint":null}]},{"method":"GET","holes":{"pretty":{"pattern":"[^\/]+","canBeRefined":true},"lang":{"pattern":"[a-z]{2}","canBeRefined":false},"id":{"pattern":"[0-9]+","canBeRefined":false}},"path":"\/#lang#\/#pretty#\/#id#","cname":"Fe1Urls","mname":"objectPreview","args":[{"source":"hole","name":"lang","constraint":null},{"source":"hole","name":"id","constraint":null},{"source":"param","name":"authhash","constraint":null}]}]); },
    "projectPreview": function() { return __reverse_route("Fe1Urls", "projectPreview", arguments, [{"method":"GET","holes":{"lang":{"pattern":"[a-z]{2}","canBeRefined":false},"id":{"pattern":"[0-9]+","canBeRefined":false}},"path":"\/#lang#\/projects\/detail\/#id#","cname":"Fe1Urls","mname":"projectPreview","args":[{"source":"hole","name":"lang","constraint":null},{"source":"hole","name":"id","constraint":null},{"source":"param","name":"authhash","constraint":null}]},{"method":"GET","holes":{"pretty":{"pattern":"[^\/]+","canBeRefined":true},"lang":{"pattern":"[a-z]{2}","canBeRefined":false},"id":{"pattern":"[0-9]+","canBeRefined":false}},"path":"\/#lang#\/projects\/detail\/#id#\/#pretty#","cname":"Fe1Urls","mname":"projectPreview","args":[{"source":"hole","name":"lang","constraint":null},{"source":"hole","name":"id","constraint":null},{"source":"param","name":"authhash","constraint":null}]}]); },
    "objectPdfClient": function() { return __reverse_route("Fe1Urls", "objectPdfClient", arguments, [{"method":"GET","holes":{"file":{"pattern":"[^\/]+","canBeRefined":true},"token":{"pattern":"[^\/]+","canBeRefined":true},"lang":{"pattern":"[a-z]{2}","canBeRefined":false},"idob":{"pattern":"[0-9]+","canBeRefined":false},"idcl":{"pattern":"[0-9]+","canBeRefined":false}},"path":"\/#lang#\/pdf\/dossier\/#idob#\/#file#\/#idcl#\/#token#","cname":"Fe1Urls","mname":"objectPdfClient","args":[{"source":"hole","name":"lang","constraint":null},{"source":"hole","name":"idob","constraint":null},{"source":"hole","name":"file","constraint":null},{"source":"hole","name":"idcl","constraint":null},{"source":"hole","name":"token","constraint":null}]},{"method":"GET","holes":{"file":{"pattern":"[^\/]+","canBeRefined":true},"token":{"pattern":"[^\/]+","canBeRefined":true},"hash":{"pattern":"[^\/]+","canBeRefined":true},"lang":{"pattern":"[a-z]{2}","canBeRefined":false},"idob":{"pattern":"[0-9]+","canBeRefined":false},"idcl":{"pattern":"[0-9]+","canBeRefined":false},"pdfConfId":{"pattern":"[0-9]+","canBeRefined":false}},"path":"\/#lang#\/pdf\/dossier\/#idob#\/#file#\/#idcl#\/#token#\/#pdfConfId#\/#hash#","cname":"Fe1Urls","mname":"objectPdfClient","args":[{"source":"hole","name":"lang","constraint":null},{"source":"hole","name":"idob","constraint":null},{"source":"hole","name":"file","constraint":null},{"source":"hole","name":"idcl","constraint":null},{"source":"hole","name":"token","constraint":null},{"source":"hole","name":"pdfConfId","constraint":null},{"source":"hole","name":"hash","constraint":null}]}]); },
    "objectPdf": function() { return __reverse_route("Fe1Urls", "objectPdf", arguments, [{"method":"GET","holes":{"file":{"pattern":"[^\/]+","canBeRefined":true},"lang":{"pattern":"[a-z]{2}","canBeRefined":false},"idob":{"pattern":"[0-9]+","canBeRefined":false}},"path":"\/#lang#\/pdf\/dossier\/#idob#\/#file#","cname":"Fe1Urls","mname":"objectPdf","args":[{"source":"hole","name":"lang","constraint":null},{"source":"hole","name":"idob","constraint":null},{"source":"hole","name":"file","constraint":null}]}]); },
    "requestDocumentation": function() { return __reverse_route("Fe1Urls", "requestDocumentation", arguments, [{"method":"GET","holes":{"token":{"pattern":"[^\/]+","canBeRefined":true},"lang":{"pattern":"[a-z]{2}","canBeRefined":false},"idcl":{"pattern":"[0-9]+","canBeRefined":false},"idob":{"pattern":"[0-9]+","canBeRefined":false}},"path":"\/#lang#\/newsletters\/request_documentation\/#idcl#\/#token#\/#idob#","cname":"Fe1Urls","mname":"requestDocumentation","args":[{"source":"hole","name":"lang","constraint":null},{"source":"hole","name":"idcl","constraint":null},{"source":"hole","name":"token","constraint":null},{"source":"hole","name":"idob","constraint":null}]}]); },
    "criteriaModify": function() { return __reverse_route("Fe1Urls", "criteriaModify", arguments, [{"method":"GET","holes":{"id":{"pattern":"[^\/]+","canBeRefined":true},"token":{"pattern":"[^\/]+","canBeRefined":true},"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/newsletters\/modify\/#id#\/#token#","cname":"Fe1Urls","mname":"criteriaModify","args":[{"source":"hole","name":"lang","constraint":null},{"source":"hole","name":"id","constraint":null},{"source":"hole","name":"token","constraint":null}]}]); },
    "criteriaSave": function() { return __reverse_route("Fe1Urls", "criteriaSave", arguments, [{"method":"GET","holes":{"id":{"pattern":"[^\/]+","canBeRefined":true},"token":{"pattern":"[^\/]+","canBeRefined":true},"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/newsletters\/savecriteria\/#id#\/#token#","cname":"Fe1Urls","mname":"criteriaSave","args":[{"source":"hole","name":"lang","constraint":null},{"source":"hole","name":"id","constraint":null},{"source":"hole","name":"token","constraint":null}]}]); },
    "criteriaArchive": function() { return __reverse_route("Fe1Urls", "criteriaArchive", arguments, [{"method":"GET","holes":{"id":{"pattern":"[^\/]+","canBeRefined":true},"token":{"pattern":"[^\/]+","canBeRefined":true},"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/newsletters\/getmearchived\/#id#\/#token#","cname":"Fe1Urls","mname":"criteriaArchive","args":[{"source":"hole","name":"lang","constraint":null},{"source":"hole","name":"id","constraint":null},{"source":"hole","name":"token","constraint":null}]}]); },
    "unsubscribe": function() { return __reverse_route("Fe1Urls", "unsubscribe", arguments, [{"method":"GET","holes":{"id":{"pattern":"[^\/]+","canBeRefined":true},"nl":{"pattern":"[^\/]+","canBeRefined":true},"token":{"pattern":"[^\/]+","canBeRefined":true},"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/newsletters\/unsubscribe\/#id#\/#nl#\/#token#","cname":"Fe1Urls","mname":"unsubscribe","args":[{"source":"hole","name":"lang","constraint":null},{"source":"hole","name":"id","constraint":null},{"source":"hole","name":"nl","constraint":null},{"source":"hole","name":"token","constraint":null}]}]); },
    "manageSubscriptions": function() { return __reverse_route("Fe1Urls", "manageSubscriptions", arguments, [{"method":"GET","holes":{"id":{"pattern":"[^\/]+","canBeRefined":true},"token":{"pattern":"[^\/]+","canBeRefined":true},"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/newsletters\/manage_subscriptions\/#id#\/#token#","cname":"Fe1Urls","mname":"manageSubscriptions","args":[{"source":"hole","name":"lang","constraint":null},{"source":"hole","name":"id","constraint":null},{"source":"hole","name":"token","constraint":null}]}]); },
    "unsubscribeBulletin": function() { return __reverse_route("Fe1Urls", "unsubscribeBulletin", arguments, [{"method":"GET","holes":{"id":{"pattern":"[^\/]+","canBeRefined":true},"nl":{"pattern":"[^\/]+","canBeRefined":true},"token":{"pattern":"[^\/]+","canBeRefined":true},"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/newsletters\/unsubscribe_bulletin\/#id#\/#nl#\/#token#","cname":"Fe1Urls","mname":"unsubscribeBulletin","args":[{"source":"hole","name":"lang","constraint":null},{"source":"hole","name":"id","constraint":null},{"source":"hole","name":"nl","constraint":null},{"source":"hole","name":"token","constraint":null}]}]); },
    "agencyPropositions": function() { return __reverse_route("Fe1Urls", "agencyPropositions", arguments, [{"method":"GET","holes":{"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/users\/agencypropositions","cname":"Fe1Urls","mname":"agencyPropositions","args":[{"source":"hole","name":"lang","constraint":null},{"source":"param","name":"authhash","constraint":null},{"source":"param","name":"exclude","constraint":null}]}]); },
    "virtualTour": function() { return __reverse_route("Fe1Urls", "virtualTour", arguments, [{"method":"GET","holes":{"lang":{"pattern":"[a-z]{2}","canBeRefined":false},"idob":{"pattern":"[0-9]+","canBeRefined":false},"idlink":{"pattern":"[0-9]+","canBeRefined":false}},"path":"\/#lang#\/virtualtour\/index\/#idob#\/#idlink#","cname":"Fe1Urls","mname":"virtualTour","args":[{"source":"hole","name":"lang","constraint":null},{"source":"hole","name":"idlink","constraint":null},{"source":"param","name":"authhash","constraint":null}]}]); },
    "video": function() { return __reverse_route("Fe1Urls", "video", arguments, [{"method":"GET","holes":{"lang":{"pattern":"[a-z]{2}","canBeRefined":false},"idob":{"pattern":"[0-9]+","canBeRefined":false},"idlink":{"pattern":"[0-9]+","canBeRefined":false}},"path":"\/#lang#\/video\/index\/#idob#\/#idlink#","cname":"Fe1Urls","mname":"video","args":[{"source":"hole","name":"lang","constraint":null},{"source":"hole","name":"idlink","constraint":null},{"source":"param","name":"authhash","constraint":null}]}]); },
    "profile": function() { return __reverse_route("Fe1Urls", "profile", arguments, [{"method":"GET","holes":{"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/users\/profile","cname":"Fe1Urls","mname":"profile","args":[{"source":"hole","name":"lang","constraint":null}]}]); },
  },
  "Opinion": {
    "opinion": function() { return __reverse_route("Opinion", "opinion", arguments, [{"method":"GET","holes":{"id":{"pattern":"[^\/]+","canBeRefined":true},"authhash":{"pattern":"[^\/]+","canBeRefined":true},"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/opinion\/#id#\/#authhash#","cname":"Opinion","mname":"opinion","args":[{"source":"hole","name":"lang","constraint":null},{"source":"hole","name":"id","constraint":null},{"source":"hole","name":"authhash","constraint":null}]}]); },
    "confirmation": function() { return __reverse_route("Opinion", "confirmation", arguments, [{"method":"GET","holes":{"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/opinion\/confirmation","cname":"Opinion","mname":"confirmation","args":[{"source":"hole","name":"lang","constraint":null}]}]); },
    "opinionDo": function() { return __reverse_route("Opinion", "opinionDo", arguments, [{"method":"POST","holes":{"id":{"pattern":"[^\/]+","canBeRefined":true},"authhash":{"pattern":"[^\/]+","canBeRefined":true},"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/opinion\/#id#\/#authhash#","cname":"Opinion","mname":"opinionDo","args":[{"source":"hole","name":"lang","constraint":null},{"source":"hole","name":"id","constraint":null},{"source":"hole","name":"authhash","constraint":null}]}]); },
  },
  "User": {
    "activation": function() { return __reverse_route("User", "activation", arguments, [{"method":"GET","holes":{"token":{"pattern":"[^\/]+","canBeRefined":true},"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/user\/activation\/#token#","cname":"User","mname":"activation","args":[{"source":"hole","name":"lang","constraint":null},{"source":"hole","name":"token","constraint":null}]}]); },
    "welcome": function() { return __reverse_route("User", "welcome", arguments, [{"method":"GET","holes":{"token":{"pattern":"[^\/]+","canBeRefined":true},"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/user\/welcome\/#token#","cname":"User","mname":"welcome","args":[{"source":"hole","name":"lang","constraint":null},{"source":"hole","name":"token","constraint":null}]}]); },
    "forgotten": function() { return __reverse_route("User", "forgotten", arguments, [{"method":"GET","holes":{"token":{"pattern":"[^\/]+","canBeRefined":true},"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/user\/forgotten\/#token#","cname":"User","mname":"forgotten","args":[{"source":"hole","name":"lang","constraint":null},{"source":"hole","name":"token","constraint":null}]}]); },
    "terms": function() { return __reverse_route("User", "terms", arguments, [{"method":"GET","holes":{"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/users\/profile\/terms","cname":"User","mname":"terms","args":[{"source":"hole","name":"lang","constraint":null}]}]); },
    "activationAuto": function() { return __reverse_route("User", "activationAuto", arguments, [{"method":"GET","holes":{"token":{"pattern":"[^\/]+","canBeRefined":true},"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/user\/activation\/auto\/#token#","cname":"User","mname":"activationAuto","args":[{"source":"hole","name":"lang","constraint":null},{"source":"hole","name":"token","constraint":null}]}]); },
    "criterias": function() { return __reverse_route("User", "criterias", arguments, [{"method":"GET","holes":{"token":{"pattern":"[^\/]+","canBeRefined":true},"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/user\/search_criterias\/#token#","cname":"User","mname":"criterias","args":[{"source":"hole","name":"lang","constraint":null},{"source":"hole","name":"token","constraint":null}]}]); },
    "forgot": function() { return __reverse_route("User", "forgot", arguments, [{"method":"GET","holes":{"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/user\/forgot","cname":"User","mname":"forgot","args":[{"source":"hole","name":"lang","constraint":null}]}]); },
    "registerDo": function() { return __reverse_route("User", "registerDo", arguments, [{"method":"POST","holes":{"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/user\/register","cname":"User","mname":"registerDo","args":[{"source":"hole","name":"lang","constraint":null}]}]); },
    "registrationSave": function() { return __reverse_route("User", "registrationSave", arguments, [{"method":"POST","holes":{"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/user\/register\/save","cname":"User","mname":"registrationSave","args":[{"source":"hole","name":"lang","constraint":null}]}]); },
    "validatePassword": function() { return __reverse_route("User", "validatePassword", arguments, [{"method":"POST","holes":{"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/user\/validatePassword","cname":"User","mname":"validatePassword","args":[{"source":"hole","name":"lang","constraint":null}]}]); },
    "activationDo": function() { return __reverse_route("User", "activationDo", arguments, [{"method":"POST","holes":{"token":{"pattern":"[^\/]+","canBeRefined":true},"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/user\/activation\/#token#","cname":"User","mname":"activationDo","args":[{"source":"hole","name":"lang","constraint":null},{"source":"hole","name":"token","constraint":null}]}]); },
    "welcomeDo": function() { return __reverse_route("User", "welcomeDo", arguments, [{"method":"POST","holes":{"token":{"pattern":"[^\/]+","canBeRefined":true},"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/user\/welcome\/#token#","cname":"User","mname":"welcomeDo","args":[{"source":"hole","name":"lang","constraint":null},{"source":"hole","name":"token","constraint":null}]}]); },
    "forgottenDo": function() { return __reverse_route("User", "forgottenDo", arguments, [{"method":"POST","holes":{"token":{"pattern":"[^\/]+","canBeRefined":true},"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/user\/forgotten\/#token#","cname":"User","mname":"forgottenDo","args":[{"source":"hole","name":"lang","constraint":null},{"source":"hole","name":"token","constraint":null}]}]); },
    "termsDo": function() { return __reverse_route("User", "termsDo", arguments, [{"method":"POST","holes":{"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/users\/profile\/terms","cname":"User","mname":"termsDo","args":[{"source":"hole","name":"lang","constraint":null}]}]); },
    "criteriasDo": function() { return __reverse_route("User", "criteriasDo", arguments, [{"method":"POST","holes":{"token":{"pattern":"[^\/]+","canBeRefined":true},"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/user\/search_criterias\/#token#","cname":"User","mname":"criteriasDo","args":[{"source":"hole","name":"lang","constraint":null},{"source":"hole","name":"token","constraint":null}]}]); },
    "forgotDo": function() { return __reverse_route("User", "forgotDo", arguments, [{"method":"POST","holes":{"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/user\/forgot","cname":"User","mname":"forgotDo","args":[{"source":"hole","name":"lang","constraint":null}]}]); },
  },
  "UserAuth": {
    "profile": function() { return __reverse_route("UserAuth", "profile", arguments, [{"method":"GET","holes":{"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/user\/profile","cname":"UserAuth","mname":"profile","args":[{"source":"hole","name":"lang","constraint":null}]}]); },
    "criterias": function() { return __reverse_route("UserAuth", "criterias", arguments, [{"method":"GET","holes":{"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/user\/criterias","cname":"UserAuth","mname":"criterias","args":[{"source":"hole","name":"lang","constraint":null}]}]); },
    "selectionExclude": function() { return __reverse_route("UserAuth", "selectionExclude", arguments, [{"method":"GET","holes":{"selected":{"pattern":"[^\/]+","canBeRefined":true},"exclude":{"pattern":"[^\/]+","canBeRefined":true},"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/user\/selection\/#selected#\/#exclude#","cname":"UserAuth","mname":"selectionExclude","args":[{"source":"hole","name":"lang","constraint":null},{"source":"hole","name":"selected","constraint":null},{"source":"hole","name":"exclude","constraint":null}]}]); },
    "selection": function() { return __reverse_route("UserAuth", "selection", arguments, [{"method":"GET","holes":{"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/user\/selection","cname":"UserAuth","mname":"selection","args":[{"source":"hole","name":"lang","constraint":null}]},{"method":"GET","holes":{"id":{"pattern":"[^\/]+","canBeRefined":true},"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/user\/selection\/#id#","cname":"UserAuth","mname":"selection","args":[{"source":"hole","name":"lang","constraint":null},{"source":"hole","name":"id","constraint":null}]}]); },
    "subscribe": function() { return __reverse_route("UserAuth", "subscribe", arguments, [{"method":"GET","holes":{"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/user\/subscribe","cname":"UserAuth","mname":"subscribe","args":[{"source":"hole","name":"lang","constraint":null}]}]); },
    "newsletters": function() { return __reverse_route("UserAuth", "newsletters", arguments, [{"method":"GET","holes":{"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/user\/newsletters","cname":"UserAuth","mname":"newsletters","args":[{"source":"hole","name":"lang","constraint":null}]}]); },
    "archiveAccount": function() { return __reverse_route("UserAuth", "archiveAccount", arguments, [{"method":"GET","holes":{"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/user\/archive","cname":"UserAuth","mname":"archiveAccount","args":[{"source":"hole","name":"lang","constraint":null}]}]); },
    "financing": function() { return __reverse_route("UserAuth", "financing", arguments, [{"method":"GET","holes":{"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/user\/financing","cname":"UserAuth","mname":"financing","args":[{"source":"hole","name":"lang","constraint":null}]}]); },
    "askConsent": function() { return __reverse_route("UserAuth", "askConsent", arguments, [{"method":"GET","holes":{"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/user\/consent","cname":"UserAuth","mname":"askConsent","args":[{"source":"hole","name":"lang","constraint":null}]}]); },
    "askConsentRefuse": function() { return __reverse_route("UserAuth", "askConsentRefuse", arguments, [{"method":"GET","holes":{"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/user\/consent\/refuse","cname":"UserAuth","mname":"askConsentRefuse","args":[{"source":"hole","name":"lang","constraint":null}]}]); },
    "profileSave": function() { return __reverse_route("UserAuth", "profileSave", arguments, [{"method":"POST","holes":{"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/user\/profile\/save","cname":"UserAuth","mname":"profileSave","args":[{"source":"hole","name":"lang","constraint":null}]}]); },
    "criteriasSave": function() { return __reverse_route("UserAuth", "criteriasSave", arguments, [{"method":"POST","holes":{"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/user\/criterias","cname":"UserAuth","mname":"criteriasSave","args":[{"source":"hole","name":"lang","constraint":null}]}]); },
    "criteriasDelete": function() { return __reverse_route("UserAuth", "criteriasDelete", arguments, [{"method":"POST","holes":{"id":{"pattern":"[^\/]+","canBeRefined":true},"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/user\/criterias\/delete\/#id#","cname":"UserAuth","mname":"criteriasDelete","args":[{"source":"hole","name":"lang","constraint":null},{"source":"hole","name":"id","constraint":null}]}]); },
    "newslettersSave": function() { return __reverse_route("UserAuth", "newslettersSave", arguments, [{"method":"POST","holes":{"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/user\/newsletters","cname":"UserAuth","mname":"newslettersSave","args":[{"source":"hole","name":"lang","constraint":null}]}]); },
    "profileDataProtectionRequest": function() { return __reverse_route("UserAuth", "profileDataProtectionRequest", arguments, [{"method":"POST","holes":{"type_id":{"pattern":"[^\/]+","canBeRefined":true},"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/user\/profile_request\/#type_id#","cname":"UserAuth","mname":"profileDataProtectionRequest","args":[{"source":"hole","name":"lang","constraint":null},{"source":"hole","name":"type_id","constraint":null}]}]); },
    "askConsentDo": function() { return __reverse_route("UserAuth", "askConsentDo", arguments, [{"method":"POST","holes":{"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/user\/consent","cname":"UserAuth","mname":"askConsentDo","args":[{"source":"hole","name":"lang","constraint":null}]}]); },
  },
  "Messenger": {
    "show": function() { return __reverse_route("Messenger", "show", arguments, [{"method":"GET","holes":{"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/user\/messenger","cname":"Messenger","mname":"show","args":[{"source":"hole","name":"lang","constraint":null}]}]); },
    "object": function() { return __reverse_route("Messenger", "object", arguments, [{"method":"GET","holes":{"id":{"pattern":"[^\/]+","canBeRefined":true},"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/user\/messenger\/object\/#id#","cname":"Messenger","mname":"object","args":[{"source":"hole","name":"lang","constraint":null},{"source":"hole","name":"id","constraint":null}]}]); },
    "conversation": function() { return __reverse_route("Messenger", "conversation", arguments, [{"method":"GET","holes":{"id":{"pattern":"[^\/]+","canBeRefined":true},"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/user\/messenger\/c\/#id#","cname":"Messenger","mname":"conversation","args":[{"source":"hole","name":"lang","constraint":null},{"source":"hole","name":"id","constraint":null}]}]); },
    "loadOlderMessages": function() { return __reverse_route("Messenger", "loadOlderMessages", arguments, [{"method":"GET","holes":{"id":{"pattern":"[^\/]+","canBeRefined":true},"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/user\/messenger\/c\/#id#\/older","cname":"Messenger","mname":"loadOlderMessages","args":[{"source":"hole","name":"lang","constraint":null},{"source":"hole","name":"id","constraint":null}]}]); },
    "loadNewerMessages": function() { return __reverse_route("Messenger", "loadNewerMessages", arguments, [{"method":"GET","holes":{"id":{"pattern":"[^\/]+","canBeRefined":true},"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/user\/messenger\/c\/#id#\/newer","cname":"Messenger","mname":"loadNewerMessages","args":[{"source":"hole","name":"lang","constraint":null},{"source":"hole","name":"id","constraint":null}]}]); },
    "sendMessage": function() { return __reverse_route("Messenger", "sendMessage", arguments, [{"method":"POST","holes":{"id":{"pattern":"[^\/]+","canBeRefined":true},"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/user\/messenger\/c\/#id#\/send","cname":"Messenger","mname":"sendMessage","args":[{"source":"hole","name":"lang","constraint":null},{"source":"hole","name":"id","constraint":null}]}]); },
    "markAsRead": function() { return __reverse_route("Messenger", "markAsRead", arguments, [{"method":"POST","holes":{"id":{"pattern":"[^\/]+","canBeRefined":true},"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/user\/messenger\/c\/#id#\/read","cname":"Messenger","mname":"markAsRead","args":[{"source":"hole","name":"lang","constraint":null},{"source":"hole","name":"id","constraint":null}]}]); },
    "uploadFile": function() { return __reverse_route("Messenger", "uploadFile", arguments, [{"method":"POST","holes":{"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/user\/messenger\/upload","cname":"Messenger","mname":"uploadFile","args":[{"source":"hole","name":"lang","constraint":null}]}]); },
    "deleteFile": function() { return __reverse_route("Messenger", "deleteFile", arguments, [{"method":"POST","holes":{"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/user\/messenger\/delete","cname":"Messenger","mname":"deleteFile","args":[{"source":"hole","name":"lang","constraint":null}]}]); },
  },
  "Owner": {
    "objects": function() { return __reverse_route("Owner", "objects", arguments, [{"method":"GET","holes":{"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/owner\/objects","cname":"Owner","mname":"objects","args":[{"source":"hole","name":"lang","constraint":null}]}]); },
    "details": function() { return __reverse_route("Owner", "details", arguments, [{"method":"GET","holes":{"id":{"pattern":"[^\/]+","canBeRefined":true},"tab":{"pattern":"[^\/]+","canBeRefined":true},"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/owner\/details\/#id#\/#tab#","cname":"Owner","mname":"details","args":[{"source":"hole","name":"lang","constraint":null},{"source":"hole","name":"id","constraint":"int"},{"source":"hole","name":"tab","constraint":null}]}]); },
    "reportData": function() { return __reverse_route("Owner", "reportData", arguments, [{"method":"GET","holes":{"id":{"pattern":"[^\/]+","canBeRefined":true},"type":{"pattern":"[^\/]+","canBeRefined":true},"page":{"pattern":"[^\/]+","canBeRefined":true},"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/owner\/data\/#id#\/#type#\/#page#","cname":"Owner","mname":"reportData","args":[{"source":"hole","name":"lang","constraint":null},{"source":"hole","name":"id","constraint":"int"},{"source":"hole","name":"type","constraint":null},{"source":"hole","name":"page","constraint":null}]}]); },
    "reportGraph": function() { return __reverse_route("Owner", "reportGraph", arguments, [{"method":"GET","holes":{"id":{"pattern":"[^\/]+","canBeRefined":true},"type":{"pattern":"[^\/]+","canBeRefined":true},"value":{"pattern":"[^\/]+","canBeRefined":true},"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/owner\/graph\/#id#\/#type#\/#value#","cname":"Owner","mname":"reportGraph","args":[{"source":"hole","name":"lang","constraint":null},{"source":"hole","name":"id","constraint":"int"},{"source":"hole","name":"type","constraint":null},{"source":"hole","name":"value","constraint":null}]}]); },
  },
  "AdminAuth": {
    "profile": function() { return __reverse_route("AdminAuth", "profile", arguments, [{"method":"GET","holes":{"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/admin\/profile","cname":"AdminAuth","mname":"profile","args":[{"source":"hole","name":"lang","constraint":null}]}]); },
  },
  "DigiRent": {
    "dossiers": function() { return __reverse_route("DigiRent", "dossiers", arguments, [{"method":"GET","holes":{"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/digirent\/dossiers","cname":"DigiRent","mname":"dossiers","args":[{"source":"hole","name":"lang","constraint":null}]}]); },
    "applyForObject": function() { return __reverse_route("DigiRent", "applyForObject", arguments, [{"method":"GET","holes":{"object_id":{"pattern":"[^\/]+","canBeRefined":true},"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/digirent\/object\/#object_id#","cname":"DigiRent","mname":"applyForObject","args":[{"source":"hole","name":"lang","constraint":null},{"source":"hole","name":"object_id","constraint":null}]}]); },
    "dossier": function() { return __reverse_route("DigiRent", "dossier", arguments, [{"method":"GET","holes":{"did":{"pattern":"[^\/]+","canBeRefined":true},"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/digirent\/app\/#did#","cname":"DigiRent","mname":"dossier","args":[{"source":"hole","name":"lang","constraint":null},{"source":"hole","name":"did","constraint":null}]}]); },
    "dossierStepTenants": function() { return __reverse_route("DigiRent", "dossierStepTenants", arguments, [{"method":"GET","holes":{"did":{"pattern":"[^\/]+","canBeRefined":true},"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/digirent\/app\/#did#\/tenants","cname":"DigiRent","mname":"dossierStepTenants","args":[{"source":"hole","name":"lang","constraint":null},{"source":"hole","name":"did","constraint":null}]}]); },
    "dossierStepGuarantors": function() { return __reverse_route("DigiRent", "dossierStepGuarantors", arguments, [{"method":"GET","holes":{"did":{"pattern":"[^\/]+","canBeRefined":true},"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/digirent\/app\/#did#\/guarantors","cname":"DigiRent","mname":"dossierStepGuarantors","args":[{"source":"hole","name":"lang","constraint":null},{"source":"hole","name":"did","constraint":null}]}]); },
    "dossierStepGeneral": function() { return __reverse_route("DigiRent", "dossierStepGeneral", arguments, [{"method":"GET","holes":{"did":{"pattern":"[^\/]+","canBeRefined":true},"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/digirent\/app\/#did#\/general","cname":"DigiRent","mname":"dossierStepGeneral","args":[{"source":"hole","name":"lang","constraint":null},{"source":"hole","name":"did","constraint":null}]}]); },
    "dossierStepFiles": function() { return __reverse_route("DigiRent", "dossierStepFiles", arguments, [{"method":"GET","holes":{"did":{"pattern":"[^\/]+","canBeRefined":true},"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/digirent\/app\/#did#\/files","cname":"DigiRent","mname":"dossierStepFiles","args":[{"source":"hole","name":"lang","constraint":null},{"source":"hole","name":"did","constraint":null}]}]); },
    "dossierTenantsAdd": function() { return __reverse_route("DigiRent", "dossierTenantsAdd", arguments, [{"method":"GET","holes":{"did":{"pattern":"[^\/]+","canBeRefined":true},"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/digirent\/app\/#did#\/tenants\/add","cname":"DigiRent","mname":"dossierTenantsAdd","args":[{"source":"hole","name":"lang","constraint":null},{"source":"hole","name":"did","constraint":null}]}]); },
    "dossierTenantsDelete": function() { return __reverse_route("DigiRent", "dossierTenantsDelete", arguments, [{"method":"GET","holes":{"did":{"pattern":"[^\/]+","canBeRefined":true},"tid":{"pattern":"[^\/]+","canBeRefined":true},"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/digirent\/app\/#did#\/tenants\/delete\/#tid#","cname":"DigiRent","mname":"dossierTenantsDelete","args":[{"source":"hole","name":"lang","constraint":null},{"source":"hole","name":"did","constraint":null},{"source":"hole","name":"tid","constraint":null}]}]); },
    "dossierGuarantorsAdd": function() { return __reverse_route("DigiRent", "dossierGuarantorsAdd", arguments, [{"method":"GET","holes":{"did":{"pattern":"[^\/]+","canBeRefined":true},"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/digirent\/app\/#did#\/guarantors\/add","cname":"DigiRent","mname":"dossierGuarantorsAdd","args":[{"source":"hole","name":"lang","constraint":null},{"source":"hole","name":"did","constraint":null}]}]); },
    "dossierGuarantorsDelete": function() { return __reverse_route("DigiRent", "dossierGuarantorsDelete", arguments, [{"method":"GET","holes":{"did":{"pattern":"[^\/]+","canBeRefined":true},"gid":{"pattern":"[^\/]+","canBeRefined":true},"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/digirent\/app\/#did#\/guarantors\/delete\/#gid#","cname":"DigiRent","mname":"dossierGuarantorsDelete","args":[{"source":"hole","name":"lang","constraint":null},{"source":"hole","name":"did","constraint":null},{"source":"hole","name":"gid","constraint":null}]}]); },
    "dossierWithdrawRequest": function() { return __reverse_route("DigiRent", "dossierWithdrawRequest", arguments, [{"method":"GET","holes":{"did":{"pattern":"[^\/]+","canBeRefined":true},"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/digirent\/app\/#did#\/withdraw","cname":"DigiRent","mname":"dossierWithdrawRequest","args":[{"source":"hole","name":"lang","constraint":null},{"source":"hole","name":"did","constraint":null}]}]); },
    "dossierDelete": function() { return __reverse_route("DigiRent", "dossierDelete", arguments, [{"method":"GET","holes":{"did":{"pattern":"[^\/]+","canBeRefined":true},"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/digirent\/app\/#did#\/delete","cname":"DigiRent","mname":"dossierDelete","args":[{"source":"hole","name":"lang","constraint":null},{"source":"hole","name":"did","constraint":null}]}]); },
    "ajaxValidateAllForms": function() { return __reverse_route("DigiRent", "ajaxValidateAllForms", arguments, [{"method":"GET","holes":{"did":{"pattern":"[^\/]+","canBeRefined":true},"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/digirent\/app\/#did#\/forms\/validate","cname":"DigiRent","mname":"ajaxValidateAllForms","args":[{"source":"hole","name":"lang","constraint":null},{"source":"hole","name":"did","constraint":null}]}]); },
    "qrcode": function() { return __reverse_route("DigiRent", "qrcode", arguments, [{"method":"GET","holes":{"did":{"pattern":"[^\/]+","canBeRefined":true},"step":{"pattern":"[^\/]+","canBeRefined":true},"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/digirent\/qrcode\/#did#\/#step#","cname":"DigiRent","mname":"qrcode","args":[{"source":"hole","name":"lang","constraint":null},{"source":"hole","name":"did","constraint":null},{"source":"hole","name":"step","constraint":null}]}]); },
    "modalConditions": function() { return __reverse_route("DigiRent", "modalConditions", arguments, [{"method":"GET","holes":{"did":{"pattern":"[^\/]+","canBeRefined":true},"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/digirent\/modal\/conditions\/#did#","cname":"DigiRent","mname":"modalConditions","args":[{"source":"hole","name":"lang","constraint":null},{"source":"hole","name":"did","constraint":null}]}]); },
    "guaranteeOrder": function() { return __reverse_route("DigiRent", "guaranteeOrder", arguments, [{"method":"GET","holes":{"ident":{"pattern":"[^\/]+","canBeRefined":true},"did":{"pattern":"[^\/]+","canBeRefined":true},"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/digirent\/guarantee\/#ident#\/#did#","cname":"DigiRent","mname":"guaranteeOrder","args":[{"source":"hole","name":"lang","constraint":null},{"source":"hole","name":"ident","constraint":null},{"source":"hole","name":"did","constraint":null}]}]); },
    "dossierSave": function() { return __reverse_route("DigiRent", "dossierSave", arguments, [{"method":"POST","holes":{"did":{"pattern":"[^\/]+","canBeRefined":true},"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/digirent\/app\/#did#","cname":"DigiRent","mname":"dossierSave","args":[{"source":"hole","name":"lang","constraint":null},{"source":"hole","name":"did","constraint":null}]}]); },
    "dossierFileUpload": function() { return __reverse_route("DigiRent", "dossierFileUpload", arguments, [{"method":"POST","holes":{"did":{"pattern":"[^\/]+","canBeRefined":true},"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/digirent\/app\/#did#\/files\/upload","cname":"DigiRent","mname":"dossierFileUpload","args":[{"source":"hole","name":"lang","constraint":null},{"source":"hole","name":"did","constraint":null}]}]); },
    "dossierFileDelete": function() { return __reverse_route("DigiRent", "dossierFileDelete", arguments, [{"method":"POST","holes":{"did":{"pattern":"[^\/]+","canBeRefined":true},"fid":{"pattern":"[^\/]+","canBeRefined":true},"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/digirent\/app\/#did#\/files\/delete\/#fid#","cname":"DigiRent","mname":"dossierFileDelete","args":[{"source":"hole","name":"lang","constraint":null},{"source":"hole","name":"did","constraint":null},{"source":"hole","name":"fid","constraint":null}]}]); },
    "dossierSubmitRequest": function() { return __reverse_route("DigiRent", "dossierSubmitRequest", arguments, [{"method":"POST","holes":{"did":{"pattern":"[^\/]+","canBeRefined":true},"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/digirent\/app\/#did#\/request","cname":"DigiRent","mname":"dossierSubmitRequest","args":[{"source":"hole","name":"lang","constraint":null},{"source":"hole","name":"did","constraint":null}]}]); },
    "modalConditionsDo": function() { return __reverse_route("DigiRent", "modalConditionsDo", arguments, [{"method":"POST","holes":{"did":{"pattern":"[^\/]+","canBeRefined":true},"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/digirent\/modal\/conditions\/#did#","cname":"DigiRent","mname":"modalConditionsDo","args":[{"source":"hole","name":"lang","constraint":null},{"source":"hole","name":"did","constraint":null}]}]); },
    "modalDebtExtractDo": function() { return __reverse_route("DigiRent", "modalDebtExtractDo", arguments, [{"method":"POST","holes":{"did":{"pattern":"[^\/]+","canBeRefined":true},"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/digirent\/modal\/debtextract\/#did#","cname":"DigiRent","mname":"modalDebtExtractDo","args":[{"source":"hole","name":"lang","constraint":null},{"source":"hole","name":"did","constraint":null}]}]); },
    "guaranteeOrderDo": function() { return __reverse_route("DigiRent", "guaranteeOrderDo", arguments, [{"method":"POST","holes":{"ident":{"pattern":"[^\/]+","canBeRefined":true},"did":{"pattern":"[^\/]+","canBeRefined":true},"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/digirent\/guarantee\/#ident#\/#did#","cname":"DigiRent","mname":"guaranteeOrderDo","args":[{"source":"hole","name":"lang","constraint":null},{"source":"hole","name":"ident","constraint":null},{"source":"hole","name":"did","constraint":null}]}]); },
    "setFilesTypesPopup": function() { return __reverse_route("DigiRent", "setFilesTypesPopup", arguments, [{"method":"POST","holes":{"did":{"pattern":"[^\/]+","canBeRefined":true},"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/digirent\/files\/set_types\/#did#","cname":"DigiRent","mname":"setFilesTypesPopup","args":[{"source":"hole","name":"lang","constraint":null},{"source":"hole","name":"did","constraint":null}]}]); },
    "setFilesTypesPopupDo": function() { return __reverse_route("DigiRent", "setFilesTypesPopupDo", arguments, [{"method":"POST","holes":{"did":{"pattern":"[^\/]+","canBeRefined":true},"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/digirent\/files\/set_types_do\/#did#","cname":"DigiRent","mname":"setFilesTypesPopupDo","args":[{"source":"hole","name":"lang","constraint":null},{"source":"hole","name":"did","constraint":null}]}]); },
  },
  "CachedResources": {
    "sitemap": function() { return __reverse_route("CachedResources", "sitemap", arguments, [{"method":"GET","holes":[],"path":"\/sitemap.xml","cname":"CachedResources","mname":"sitemap","args":[]}]); },
    "sitemapLang": function() { return __reverse_route("CachedResources", "sitemapLang", arguments, [{"method":"GET","holes":{"lang":{"pattern":"[^\/]+","canBeRefined":true}},"path":"\/sitemap_#lang#.xml","cname":"CachedResources","mname":"sitemapLang","args":[{"source":"hole","name":"lang","constraint":null}]}]); },
    "robots": function() { return __reverse_route("CachedResources", "robots", arguments, [{"method":"GET","holes":[],"path":"\/robots.txt","cname":"CachedResources","mname":"robots","args":[]}]); },
    "css": function() { return __reverse_route("CachedResources", "css", arguments, [{"method":"GET","holes":{"file":{"pattern":"[^\/]+","canBeRefined":true}},"path":"\/cache\/#file#\/website.css","cname":"CachedResources","mname":"css","args":[{"source":"hole","name":"file","constraint":null}]}]); },
    "js": function() { return __reverse_route("CachedResources", "js", arguments, [{"method":"GET","holes":{"file":{"pattern":"[^\/]+","canBeRefined":true}},"path":"\/cache\/#file#\/website.js","cname":"CachedResources","mname":"js","args":[{"source":"hole","name":"file","constraint":null}]}]); },
    "unknown": function() { return __reverse_route("CachedResources", "unknown", arguments, [{"method":"GET","holes":{"file":{"pattern":".+","canBeRefined":true}},"path":"\/cache\/#file#","cname":"CachedResources","mname":"unknown","args":[{"source":"hole","name":"file","constraint":null}]}]); },
  },
  "Resources": {
    "file": function() { return __reverse_route("Resources", "file", arguments, [{"method":"GET","holes":[],"path":"\/favicon.ico","cname":"Resources","mname":"file","args":[{"source":"fixed","value":"favicon.ico","constraint":"string"}]},{"method":"GET","holes":{"file":{"pattern":".+","canBeRefined":true}},"path":"\/resources\/#file#","cname":"Resources","mname":"file","args":[{"source":"hole","name":"file","constraint":null}]}]); },
    "accountFile": function() { return __reverse_route("Resources", "accountFile", arguments, [{"method":"GET","holes":{"account":{"pattern":"[^\/]+","canBeRefined":true},"file":{"pattern":".+","canBeRefined":true}},"path":"\/file\/#account#\/#file#","cname":"Resources","mname":"accountFile","args":[{"source":"hole","name":"account","constraint":"int"},{"source":"hole","name":"file","constraint":null}]}]); },
    "globalFile": function() { return __reverse_route("Resources", "globalFile", arguments, [{"method":"GET","holes":{"file":{"pattern":".+","canBeRefined":true}},"path":"\/global\/#file#","cname":"Resources","mname":"globalFile","args":[{"source":"hole","name":"file","constraint":null}]}]); },
  },
  "Analytics": {
    "object_click": function() { return __reverse_route("Analytics", "object_click", arguments, [{"method":"GET","holes":{"id":{"pattern":"[^\/]+","canBeRefined":true},"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/analytics\/object_click\/#id#","cname":"Analytics","mname":"object_click","args":[{"source":"hole","name":"lang","constraint":null},{"source":"hole","name":"id","constraint":"int"}]},{"method":"GET","holes":{"id":{"pattern":"[^\/]+","canBeRefined":true},"authhash":{"pattern":"[^\/]+","canBeRefined":true},"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/analytics\/object_click\/#id#\/#authhash#","cname":"Analytics","mname":"object_click","args":[{"source":"hole","name":"lang","constraint":null},{"source":"hole","name":"id","constraint":"int"},{"source":"hole","name":"authhash","constraint":"string"}]}]); },
  },
  "Rss": {
    "index": function() { return __reverse_route("Rss", "index", arguments, [{"method":"GET","holes":{"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/rss","cname":"Rss","mname":"index","args":[{"source":"hole","name":"lang","constraint":null}]},{"method":"GET","holes":{"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/rss\/index","cname":"Rss","mname":"index","args":[{"source":"hole","name":"lang","constraint":null}]}]); },
    "sale": function() { return __reverse_route("Rss", "sale", arguments, [{"method":"GET","holes":{"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/rss\/sale","cname":"Rss","mname":"sale","args":[{"source":"hole","name":"lang","constraint":null}]}]); },
    "rent": function() { return __reverse_route("Rss", "rent", arguments, [{"method":"GET","holes":{"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/rss\/rent","cname":"Rss","mname":"rent","args":[{"source":"hole","name":"lang","constraint":null}]}]); },
    "details": function() { return __reverse_route("Rss", "details", arguments, [{"method":"GET","holes":{"lang":{"pattern":"[a-z]{2}","canBeRefined":false},"idob":{"pattern":"[0-9]+","canBeRefined":false}},"path":"\/#lang#\/rss\/details\/#idob#","cname":"Rss","mname":"details","args":[{"source":"hole","name":"lang","constraint":null},{"source":"hole","name":"idob","constraint":null}]}]); },
  },
  "Dataroom": {
    "manage": function() { return __reverse_route("Dataroom", "manage", arguments, [{"method":"GET","holes":{"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/user\/dataroom","cname":"Dataroom","mname":"manage","args":[{"source":"hole","name":"lang","constraint":null}]}]); },
    "openLink": function() { return __reverse_route("Dataroom", "openLink", arguments, [{"method":"GET","holes":{"pretty":{"pattern":"[^\/]+","canBeRefined":true},"lang":{"pattern":"[a-z]{2}","canBeRefined":false},"id":{"pattern":"[0-9]+","canBeRefined":false}},"path":"\/#lang#\/user\/dataroom\/#id#-#pretty#","cname":"Dataroom","mname":"openLink","args":[{"source":"hole","name":"lang","constraint":null},{"source":"hole","name":"id","constraint":null},{"source":"hole","name":"pretty","constraint":null}]}]); },
    "auto": function() { return __reverse_route("Dataroom", "auto", arguments, [{"method":"GET","holes":{"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/user\/dataroom\/auto","cname":"Dataroom","mname":"auto","args":[{"source":"hole","name":"lang","constraint":null}]}]); },
    "download": function() { return __reverse_route("Dataroom", "download", arguments, [{"method":"GET","holes":{"id":{"pattern":"[^\/]+","canBeRefined":true},"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/user\/dataroom\/download\/#id#","cname":"Dataroom","mname":"download","args":[{"source":"hole","name":"lang","constraint":null},{"source":"hole","name":"id","constraint":"int"}]}]); },
    "openFile": function() { return __reverse_route("Dataroom", "openFile", arguments, [{"method":"GET","holes":{"id":{"pattern":"[^\/]+","canBeRefined":true},"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/user\/dataroom\/open-file\/#id#","cname":"Dataroom","mname":"openFile","args":[{"source":"hole","name":"lang","constraint":null},{"source":"hole","name":"id","constraint":"int"}]}]); },
    "unsubscribe": function() { return __reverse_route("Dataroom", "unsubscribe", arguments, [{"method":"GET","holes":{"pretty":{"pattern":"[^\/]+","canBeRefined":true},"lang":{"pattern":"[a-z]{2}","canBeRefined":false},"sid":{"pattern":"[0-9]+","canBeRefined":false}},"path":"\/#lang#\/user\/dataroom\/unsubscribe\/#sid#-#pretty#","cname":"Dataroom","mname":"unsubscribe","args":[{"source":"hole","name":"lang","constraint":null},{"source":"hole","name":"sid","constraint":null},{"source":"hole","name":"pretty","constraint":null}]}]); },
    "unsubscribeAll": function() { return __reverse_route("Dataroom", "unsubscribeAll", arguments, [{"method":"GET","holes":{"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/user\/dataroom\/unsubscribe-all","cname":"Dataroom","mname":"unsubscribeAll","args":[{"source":"hole","name":"lang","constraint":null}]}]); },
    "upload": function() { return __reverse_route("Dataroom", "upload", arguments, [{"method":"POST","holes":{"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/user\/dataroom\/upload","cname":"Dataroom","mname":"upload","args":[{"source":"hole","name":"lang","constraint":null}]}]); },
    "delete": function() { return __reverse_route("Dataroom", "delete", arguments, [{"method":"POST","holes":{"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/user\/dataroom\/delete","cname":"Dataroom","mname":"delete","args":[{"source":"hole","name":"lang","constraint":null}]}]); },
  },
  "DataroomConditions": {
    "show": function() { return __reverse_route("DataroomConditions", "show", arguments, [{"method":"GET","holes":{"folderId":{"pattern":"[^\/]+","canBeRefined":true},"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/dataroom\/#folderId#\/conditions\/show","cname":"DataroomConditions","mname":"show","args":[{"source":"hole","name":"lang","constraint":null},{"source":"hole","name":"folderId","constraint":"int"}]}]); },
    "preview": function() { return __reverse_route("DataroomConditions", "preview", arguments, [{"method":"GET","holes":{"lang":{"pattern":"[a-z]{2}","canBeRefined":false},"idcond":{"pattern":"[0-9]+","canBeRefined":false}},"path":"\/#lang#\/dataroom\/conditions\/preview\/#idcond#","cname":"DataroomConditions","mname":"preview","args":[{"source":"hole","name":"lang","constraint":null},{"source":"hole","name":"idcond","constraint":null}]}]); },
    "showBeforeDownload": function() { return __reverse_route("DataroomConditions", "showBeforeDownload", arguments, [{"method":"GET","holes":{"folderId":{"pattern":"[^\/]+","canBeRefined":true},"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/dataroom\/#folderId#\/download\/conditions\/show","cname":"DataroomConditions","mname":"showBeforeDownload","args":[{"source":"hole","name":"lang","constraint":null},{"source":"hole","name":"folderId","constraint":"int"}]}]); },
    "accept": function() { return __reverse_route("DataroomConditions", "accept", arguments, [{"method":"POST","holes":{"folderId":{"pattern":"[^\/]+","canBeRefined":true},"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/dataroom\/#folderId#\/conditions\/accept","cname":"DataroomConditions","mname":"accept","args":[{"source":"hole","name":"lang","constraint":null},{"source":"hole","name":"folderId","constraint":"int"}]}]); },
  },
  "ReservationRequests": {
    "fromObject": function() { return __reverse_route("ReservationRequests", "fromObject", arguments, [{"method":"POST","holes":{"id":{"pattern":"[^\/]+","canBeRefined":true},"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/o\/reservation\/object\/#id#","cname":"ReservationRequests","mname":"fromObject","args":[{"source":"hole","name":"lang","constraint":null},{"source":"hole","name":"id","constraint":null}]}]); },
  },
  "ContactRequests": {
    "fromObject": function() { return __reverse_route("ContactRequests", "fromObject", arguments, [{"method":"POST","holes":{"id":{"pattern":"[^\/]+","canBeRefined":true},"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/a\/contact\/object\/#id#","cname":"ContactRequests","mname":"fromObject","args":[{"source":"hole","name":"lang","constraint":null},{"source":"hole","name":"id","constraint":"int"}]}]); },
    "fromGeneral": function() { return __reverse_route("ContactRequests", "fromGeneral", arguments, [{"method":"POST","holes":{"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/a\/contact\/general","cname":"ContactRequests","mname":"fromGeneral","args":[{"source":"hole","name":"lang","constraint":null}]}]); },
    "fromCmsPage": function() { return __reverse_route("ContactRequests", "fromCmsPage", arguments, [{"method":"POST","holes":{"id":{"pattern":"[^\/]+","canBeRefined":true},"comp_id":{"pattern":"[^\/]+","canBeRefined":true},"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/a\/contact\/cms\/#id#\/#comp_id#","cname":"ContactRequests","mname":"fromCmsPage","args":[{"source":"hole","name":"lang","constraint":null},{"source":"hole","name":"id","constraint":"int"},{"source":"hole","name":"comp_id","constraint":"int"}]}]); },
  },
  "VisitRequests": {
    "fromObject": function() { return __reverse_route("VisitRequests", "fromObject", arguments, [{"method":"POST","holes":{"id":{"pattern":"[^\/]+","canBeRefined":true},"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/a\/visit\/object\/#id#","cname":"VisitRequests","mname":"fromObject","args":[{"source":"hole","name":"lang","constraint":null},{"source":"hole","name":"id","constraint":"int"}]}]); },
  },
  "FinancingContactRequests": {
    "fromObject": function() { return __reverse_route("FinancingContactRequests", "fromObject", arguments, [{"method":"POST","holes":{"id":{"pattern":"[^\/]+","canBeRefined":true},"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/a\/financingcontact\/object\/#id#","cname":"FinancingContactRequests","mname":"fromObject","args":[{"source":"hole","name":"lang","constraint":null},{"source":"hole","name":"id","constraint":"int"}]}]); },
    "fromGeneral": function() { return __reverse_route("FinancingContactRequests", "fromGeneral", arguments, [{"method":"POST","holes":{"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/a\/financingcontact\/general","cname":"FinancingContactRequests","mname":"fromGeneral","args":[{"source":"hole","name":"lang","constraint":null}]}]); },
  },
  "ContactRequestsOwner": {
    "fromObject": function() { return __reverse_route("ContactRequestsOwner", "fromObject", arguments, [{"method":"POST","holes":{"id":{"pattern":"[^\/]+","canBeRefined":true},"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/a\/contactowner\/object\/#id#","cname":"ContactRequestsOwner","mname":"fromObject","args":[{"source":"hole","name":"lang","constraint":null},{"source":"hole","name":"id","constraint":"int"}]}]); },
    "fromGeneral": function() { return __reverse_route("ContactRequestsOwner", "fromGeneral", arguments, [{"method":"POST","holes":{"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/a\/contactowner\/general","cname":"ContactRequestsOwner","mname":"fromGeneral","args":[{"source":"hole","name":"lang","constraint":null}]}]); },
    "fromCmsPage": function() { return __reverse_route("ContactRequestsOwner", "fromCmsPage", arguments, [{"method":"POST","holes":{"id":{"pattern":"[^\/]+","canBeRefined":true},"comp_id":{"pattern":"[^\/]+","canBeRefined":true},"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/a\/contactowner\/cms\/#id#\/#comp_id#","cname":"ContactRequestsOwner","mname":"fromCmsPage","args":[{"source":"hole","name":"lang","constraint":null},{"source":"hole","name":"id","constraint":"int"},{"source":"hole","name":"comp_id","constraint":"int"}]}]); },
  },
  "Prospection": {
    "submit": function() { return __reverse_route("Prospection", "submit", arguments, [{"method":"POST","holes":{"comp_id":{"pattern":"[^\/]+","canBeRefined":true},"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/prospection\/submit\/#comp_id#","cname":"Prospection","mname":"submit","args":[{"source":"hole","name":"lang","constraint":null},{"source":"hole","name":"comp_id","constraint":null}]}]); },
    "upload": function() { return __reverse_route("Prospection", "upload", arguments, [{"method":"POST","holes":{"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/prospection\/upload","cname":"Prospection","mname":"upload","args":[{"source":"hole","name":"lang","constraint":null}]}]); },
  },
  "MortgageRequests": {
    "submit": function() { return __reverse_route("MortgageRequests", "submit", arguments, [{"method":"POST","holes":{"comp_id":{"pattern":"[^\/]+","canBeRefined":true},"lang":{"pattern":"[a-z]{2}","canBeRefined":false}},"path":"\/#lang#\/mortgage\/submit\/#comp_id#","cname":"MortgageRequests","mname":"submit","args":[{"source":"hole","name":"lang","constraint":null},{"source":"hole","name":"comp_id","constraint":null}]}]); },
  },
};

/* /websites/base/js/components/swiper.js */
/*--------------- Swiper carousel ---------------*/
//default params are for mobile view first (0px -&gt; next breakpoint / global if param isn't redefined) -&gt; use breakpoint to adapt for desktop.
var swiperOptBase = {
    centeredSlides: true,
    slidesPerView: 1,
    spaceBetween: 0,

    preloadImages: false,
    lazy: {
        loadPrevNext: true,
    },
    watchSlidesProgress: true,
    loop: true,
    speed: 400,
    grabCursor: true,

    //init nav/dots
    navigation: {
        nextEl: '.swiper-button-next',
        prevEl: '.swiper-button-prev',
    },
    pagination: {
        el: '.swiper-pagination',
        type: 'bullets',
        clickable: true,
    },
    //use this param if breakpoints exist
    hideNavigation: false,
    hidePagination: false,

    autoplay: {
        delay: 4000,
        disableOnInteraction: false,
    },
    activeAutoplay: true,
    firstSlide: true,

    externalPagination: true,
    externalNavigation: true,

    breakpoints: {
        0: {
            slidesPerView: 1,
            spaceBetween: 0,
            hidePagination: true,
            activeAutoplay: false,
            watchSlidesProgress: false,
        },
        670: {
            slidesPerView: 2,
            spaceBetween: 1,
            hidePagination: false,
            activeAutoplay: true,
            watchSlidesProgress: true,
        },
    },
};

var swiperOptObjList = extendOptions(swiperOptBase, {
    grabCursor: false,
    watchSlidesProgress: false,
    pagination: false,
    autoplay: false,
    activeAutoplay:false,
    allowTouchMove: false,
    breakpoints: {},
});

var swiperOptObjDetail = extendOptions(swiperOptBase, {
    watchSlidesVisibility: true,
    spaceBetween: 1,
    breakpoints: {
        0: {
            slidesPerView: "auto",
            hidePagination: true,
            activeAutoplay: false,
        },
        670: {
            slidesPerView: 2,
            hidePagination: false,
            activeAutoplay: true,
        },
    }
});

var swiperOptObjDetailUnique = extendOptions(swiperOptBase, {
    grabCursor: false,
    loop: false,
    watchSlidesProgress: false,
    pagination: false,
    navigation: false,
    activeAutoplay:false,
    allowTouchMove: false,
    hideNavigation: true,
    hidePagination: true,
    breakpoints: {},
});

var swiperOptObjDetailProject = extendOptions(swiperOptObjDetail, {});
var swiperOptObjDetailProjectUnique = extendOptions(swiperOptObjDetailUnique, {});

var swiperOptObjMapPopup = extendOptions(swiperOptBase, {
    grabCursor: false,
    pagination: false,
    watchSlidesProgress: false,
    autoplay: false,
    activeAutoplay:false,
    allowTouchMove: false,
    autoHeight: false,
    externalPagination: false,
    externalNavigation: false,
    breakpoints: {},
});

var swiperOptBanner = extendOptions(swiperOptBase, {
    effect: 'fade',
    fadeEffect: {
        crossFade: true
    },
    autoplay: {
        delay: 5000,
    },
    speed: 5000,
    pagination: false,
    navigation: false,
    watchSlidesProgress: false,

    allowTouchMove: false,
    breakpoints: {},
});

var swiperOptThumbs = extendOptions(swiperOptBase, {
    spaceBetween: 5,
    loop:false,
    centeredSlides: false,
    autoplay: false,
    hideNavigation: true,
    hidePagination: true,
    activeAutoplay:false,
    slideToClickedSlide: true,
    grabCursor: true,
    allowTouchMove: true,
    centerInsufficientSlides: true,
    breakpoints: {
        0: {
            slidesPerView: 5,
            hideNavigation: false,
        },
        670: {
            slidesPerView: 8,
            hideNavigation: false,
        },
        1050: {
            slidesPerView: 'all',
            hideNavigation: true,
        }
    },
});

var swiperCmsOptBase = {
    centeredSlides: true,
    loop: true,
    slidesPerView: 4,
    speed: 400,
    externalPagination: true,
    externalNavigation: true,
    hideNavigation: false,
    hidePagination: false,
    watchSlidesProgress: true,
    autoHeight:false,
    preloadImages: false,
    lazy: {
        loadPrevNext: true,
    },
};

var swiperCmsOptBase0 = extendOptions(swiperCmsOptBase, {
    slidesPerView: "auto",
    watchSlidesVisibility: true,
    loop: false,
    centeredSlides: false,
    rewind: true,
    preloadImages: true,
    lazy: false,
});

var swiperCmsOptBase1 = extendOptions(swiperCmsOptBase, {
    slidesPerView: 1,
    spaceBetween: 0,
    autoHeight: true,
    watchSlidesProgress: false,
});

var swiperCmsOptBase2 = extendOptions(swiperCmsOptBase, {
    breakpoints: {
        0: {
            slidesPerView: 1,
            spaceBetween: 0,
            autoHeight: true,
            watchSlidesProgress: false,
        },
        670: {
            slidesPerView: 2,
            autoHeight: false,
            watchSlidesProgress: true,
        }
    }
});

var swiperCmsOptBase3 = extendOptions(swiperCmsOptBase, {
    breakpoints: {
        0: {
            slidesPerView: 1,
            spaceBetween: 0,
            autoHeight: true,
            watchSlidesProgress: false,
        },
        670: {
            slidesPerView: 2,
            autoHeight: false,
            watchSlidesProgress: true,
        },
        1050: {
            slidesPerView: 3,
            autoHeight: false,
        }
    }
});

var swiperCmsOptBase4 = extendOptions(swiperCmsOptBase, {
    breakpoints: {
        0: {
            slidesPerView: 1,
            spaceBetween: 0,
            autoHeight: true,
            watchSlidesProgress: false,
        },
        670: {
            slidesPerView: 2,
            autoHeight: false,
            watchSlidesProgress: true,
        },
        1050: {
            slidesPerView: 2,
            autoHeight: false,
        },
        1200: {
            slidesPerView: 4,
            autoHeight: false,
        }
    }
});

var swiperCmsOptBase5 = extendOptions(swiperCmsOptBase, {
    breakpoints: {
        0: {
            slidesPerView: 1,
            spaceBetween: 0,
            autoHeight: true,
            watchSlidesProgress: false,
        },
        670: {
            slidesPerView: 2,
            autoHeight: false,
            watchSlidesProgress: true,
        },
        1050: {
            slidesPerView: 2,
            autoHeight: false,
        },
        1200: {
            slidesPerView: 4,
            autoHeight: false,
        },
        1350: {
            slidesPerView: 5,
            autoHeight: false,
        }
    }
});

function swiperAction(target, action) {
    if (action == "next") {
        target.slideNext();
    } else if (action == "prev") {
        target.slidePrev();
    }
}

function externalNavDots(swiper, isCMS) {
    var element = $(swiper.el);
    var parent = $(swiper.el.parentElement);
    if (swiper.params.externalNavigation) {
        $(swiper.navigation.prevEl).appendTo(parent);
        $(swiper.navigation.nextEl).appendTo(parent);
        element.addClass('externalNavigation');
    }
    if (swiper.params.externalPagination) {
        $(swiper.pagination.el).appendTo(parent);
        element.addClass('externalPagination');
    }
}

function checkAutoplay(s) {
    if (!s.params.firstSlide &amp;&amp; s.params.activeAutoplay) {
        if (!s.autoplay.running) {
            s.autoplay.start(); 
        }
    } else {
        if (s.autoplay.running) {
            s.autoplay.stop();
        }
    }
}

function firstDrag (s) {
    s.params.firstSlide = false;
    checkAutoplay(s);
}

function breakpointsChange(swiper, breakpointParams) {
    calcSwiperHeight(swiper);
    setPictureSize(swiper);
}

function initSwiper(s, isCMS) {
    var swiper_element = $(s.el);
    externalNavDots(s, isCMS);
    if (!isCMS) {
        s.on('sliderFirstMove', firstDrag);
        s.autoplay.stop();
        if (s.navigation.nextEl !== undefined &amp;&amp; s.navigation.nextEl !== null) {
            s.navigation.nextEl.onclick = function () {
                s.params.firstSlide = false;
                checkAutoplay(s);
            };
        }
        if (s.navigation.prevEl !== undefined &amp;&amp; s.navigation.prevEl !== null) {
            s.navigation.prevEl.onclick = function () {
                s.params.firstSlide = false;
                checkAutoplay(s);
            };
        }
        
        if (['swiperOptObjDetail', "swiperOptObjDetailUnique"].includes($(s.el).attr("data-base-options-swiper"))) {
            s.on('breakpoint', breakpointsChange);
        }
    }
    responsiveSwiperParams(s);

    var swiper_parent = swiper_element.parents('a');
    if (swiper_parent.length) {
        $('.swiper-button-nav', swiper_parent).on('click', function(e) {
            e.preventDefault();
            e.stopPropagation();
        });
    } else if (swiper_element.is('[data-haspopup]')) {
        magnificPopup(swiper_element, extendOptions(mpOptGallery, {
            delegate: '.item:not(.swiper-slide-duplicate)[href]',
        }, swiper_element, 'mp'));
    }
}

function responsiveSwiperParams(swiper, isCMS) {  
    var swiper_element = $(swiper.el);
    var swiper_container = swiper_element.parents('.swiper-container').first();
    if (!swiper.params.autoHeight) {
        $('.swiper-wrapper', swiper_element).css({height:""});
        swiper_element.removeClass('swiper-autoheight');
    } else {
        swiper_element.addClass('swiper-autoheight');
    }
    if (swiper.params.hidePagination) {
        swiper_container.find('.swiper-pagination').first().addClass('hide');
    } else {
        swiper_container.find('.swiper-pagination').first().removeClass('hide');
    }
    if (swiper.params.hideNavigation) {
        swiper_container.find('.swiper-button-prev').first().addClass('hide');
        swiper_container.find('.swiper-button-next').first().addClass('hide');
    } else {
        swiper_container.find('.swiper-button-prev').first().removeClass('hide');
        swiper_container.find('.swiper-button-next').first().removeClass('hide');
    }
    if (isCMS == false) {
        if (['swiperOptObjDetail', "swiperOptObjDetailUnique"].includes($(swiper.el).attr("data-base-options-swiper"))) {
            calcSwiperHeight(swiper);
            setPictureSize(swiper);
        }
        if (swiper.params.thumbsMode == 'all') {
            swiper_container.addClass('swiper-all');
        } else {
            swiper_container.removeClass('swiper-all');
        }
        checkAutoplay(swiper);
    }
}

function swiperCarousel(target, options, isCMS) {
    if (target.length) {
        var myswiper = new Swiper(target[0], options);
        
        initSwiper(myswiper, isCMS);

        $(window).resize(function() {
            responsiveSwiperParams(myswiper, isCMS);
        });
        responsiveSwiperParams(myswiper, isCMS);
        myswiper.update();
    }
}

function setPictureSize(s) {
    var swiper_el = $(s.el);
    var media = $('img, .slider_external_embed', swiper_el);
    media.each(function() {
        var ratio = $(this).attr('data-ratio');
        if (ratio == undefined) {
            ratio = 16/9;
        }
        if (s.params.slidesPerView == 'auto') {
            var w = swiper_el.height() * ratio;
            if (Math.round(w) != Math.round($(this).width())) {
                $(this).css({width:w+'px'}); 
            }
        } else {
            $(this).css({width:''}); 
        }
    });
}

function calcSwiperHeight(s) {
    var slidesPerView = s.params.slidesPerView;
    if (slidesPerView != 'auto') {
        $(s.el).removeClass('swiper-autowidth');
        var centered = s.params.centeredSlides;
        if (centered &amp;&amp; slidesPerView &gt; 1 &amp;&amp; slidesPerView % 2 != 0) {
            slidesPerView--;
        }
        var width = $(s.el).width();
        var height = (width / slidesPerView) / 1.77; //ratio 16/9
        
        if (!hasExplicitHeight($(s.el))) { //keep css height value if a it is set
            $(s.el).css({height:height+'px'});
        }
    } else {
        $(s.el).addClass('swiper-autowidth');
        $(s.el).css({height:''});
    }
}

function hasExplicitHeight(element) {
    var clone = element.clone();
    clone.html('');
    clone.css({height: ''});
    clone.css('visibility', 'hidden');
    clone.css('position', 'absolute');
    clone.insertAfter(element);
    var hasExplicitHeight = element.css('height') === clone.css('height');
    clone.remove();
    return hasExplicitHeight;
};
/* /websites/base/js/functions.js */
function touchScreenHandlers() {
    (function($) {
        // Detect touch support
        $.support.touch = 'ontouchend' in document;
        // Ignore browsers without touch support
        if (!$.support.touch) {
            return;
        }
        var mouseProto = $.ui.mouse.prototype,
            _mouseInit = mouseProto._mouseInit,
            touchHandled;

        function simulateMouseEvent(event, simulatedType) { //use this function to simulate mouse event
            // Ignore multi-touch events
            if (event.originalEvent.touches.length &gt; 1) {
                return;
            }
            event.preventDefault(); //use this to prevent scrolling during ui use

            var touch = event.originalEvent.changedTouches[0],
                simulatedEvent = document.createEvent('MouseEvents');
            // Initialize the simulated mouse event using the touch event's coordinates
            simulatedEvent.initMouseEvent(
                simulatedType, // type
                true, // bubbles                    
                true, // cancelable                 
                window, // view                       
                1, // detail                     
                touch.screenX, // screenX                    
                touch.screenY, // screenY                    
                touch.clientX, // clientX                    
                touch.clientY, // clientY                    
                false, // ctrlKey                    
                false, // altKey                     
                false, // shiftKey                   
                false, // metaKey                    
                0, // button                     
                null // relatedTarget              
            );

            // Dispatch the simulated event to the target element
            event.target.dispatchEvent(simulatedEvent);
        }
        mouseProto._touchStart = function(event) {
            var self = this;
            // Ignore the event if another widget is already being handled
            if (touchHandled || !self._mouseCapture(event.originalEvent.changedTouches[0])) {
                return;
            }
            // Set the flag to prevent other widgets from inheriting the touch event
            touchHandled = true;
            // Track movement to determine if interaction was a click
            self._touchMoved = false;
            // Simulate the mouseover event
            simulateMouseEvent(event, 'mouseover');
            // Simulate the mousemove event
            simulateMouseEvent(event, 'mousemove');
            // Simulate the mousedown event
            simulateMouseEvent(event, 'mousedown');
        };

        mouseProto._touchMove = function(event) {
            // Ignore event if not handled
            if (!touchHandled) {
                return;
            }
            // Interaction was not a click
            this._touchMoved = true;
            // Simulate the mousemove event
            simulateMouseEvent(event, 'mousemove');
        };
        mouseProto._touchEnd = function(event) {
            // Ignore event if not handled
            if (!touchHandled) {
                return;
            }
            // Simulate the mouseup event
            simulateMouseEvent(event, 'mouseup');
            // Simulate the mouseout event
            simulateMouseEvent(event, 'mouseout');
            // If the touch interaction did not move, it should trigger a click
            if (!this._touchMoved) {
                // Simulate the click event
                simulateMouseEvent(event, 'click');
            }
            // Unset the flag to allow other widgets to inherit the touch event
            touchHandled = false;
        };
        mouseProto._mouseInit = function() {
            var self = this;
            // Delegate the touch handlers to the widget's element
            self.element
                .on('touchstart', $.proxy(self, '_touchStart'))
                .on('touchmove', $.proxy(self, '_touchMove'))
                .on('touchend', $.proxy(self, '_touchEnd'));

            // Call the original $.ui.mouse init method
            _mouseInit.call(self);
        };
    })(jQuery);
}

function startLoading(target) {
    if (!target.children('.js_loader').length) {
        target.append($('body &gt; .js_loader').clone());
    }
    target.addClass('onloading');
}

function endLoading(target) {
    target.removeClass('onloading');
}

function displayMessages(target, messages) {
    if (!target.find('.messages').length) {
        target.prepend('&lt;div class="messages"&gt;&lt;/div&gt;');
    }

    $(".messages", target).html("");

    for (var i = 0; i &lt; messages.length; i++) {
        var m = messages[i];

        var d = $('&lt;div class="message ' + m.type + '_message"&gt;&lt;/div&gt;');
        d.html(m.message);

        $(".messages", target).append(d);
    }
}

function displayGlobalMessages(messages) {
    const gm = $(".global_messages");
    gm.find(".message").remove();

    for (var i = messages.length - 1; i &gt;= 0; i--) {
        var m = messages[i];

        var d = $('&lt;div class="message ' + m.type + '_message"&gt;&lt;/div&gt;');
        d.html(m.message);

        gm.prepend(d);
    }
    if (messages.length &gt; 0) {
        gm.removeClass('hide');
        setTimeout(function() {
            gm.addClass('hide');
        }, 10000);
    }
}

function loadFormErrors(form, errors) {
    clearFormErrors(form);

    for (field in errors) {
        var f = $("div.row[data-field$='" + field + "'], div.row_group[data-field$='" + field + "']", form);
        $("label.form_error_msg", f).html(errors[field]);
        f.removeClass("success");
        f.addClass("error");
    }

    // scroll to first field with error
    var errorDiv = $('.row.error', form).first();
    if (errorDiv.length &amp;&amp; !isInViewport(errorDiv[0])) {
        goTo(errorDiv, 600, 'swing');
    }
}

function clearFormErrors(form) {
    $("div.row.error, div.row_group.error", form).each(function() {
        $(this).removeClass("error");
    });
}

function strEndsWith(str, suffix) {
    return str.indexOf(suffix, str.length - suffix.length) !== -1;
}

function getFormValues(form) {
    var params = {};
    $("textarea, select, input", form).each(function() {
        var type = $(this).attr('type');

        if ((type == 'radio' || type == 'checkbox') &amp;&amp; !$(this).prop("checked")) {
            return;
        }

        var v = $(this).val();
        var name = $(this).attr('name');

        if (!name) {
            return;
        }

        if (Array.isArray(v) &amp;&amp; v.length === 0) {
            return;
        }

        if (strEndsWith(name, '[]')) {
            name = name.substring(0, name.length - 2);

            if ((name in params) &amp;&amp; Array.isArray(params[name])) {
                params[name].push(v)
            } else {
                params[name] = [v]
            }
        } else {
            params[name] = v;
        }
    });

    return params;
}

function sendAjaxForm(form, opts, cb) {
    var params = getFormValues(form)

    $.ajax({
        type: opts.method || form.attr("method"),
        data: params,
        url:  opts.url || form.attr("action"),
        success: function (data) {
            cb(true, data);
            if (!data.success) {
                var el = $(".error", form).first();
                if (el.length &amp;&amp; !el.is(":hidden") &amp;&amp; !isInViewport(el[0])) {
                    goTo(el, 600, 'swing');
                }
            }
        },
        error: function() { cb(false) },
    });
}

function validateForm(form) {
    // Check for required fields
    return true;
}

var __reverse_route = function(c, m, args, routes) {
    loopRoutes: for (ri in routes) {
        const r = routes[ri];
        var uri = r.path;
        var params = {};

        if (args.length != r.args.length) {
            var sig = [];
            for (i in r.args) {
                sig.push(r.args[i].name);
            }
            console.error("Invalid argument count for " + c + "." + m + "(" + sig.join(", ") + "): got " + args.length);
            return;
        }

        for (i in r.args) {
            var p = r.args[i];
            var v = args[i];

            if (p.constraint == "int") {
                if ((typeof v) === 'string') {
                    if (!isNaN(v)) {
                        v = parseInt(v);
                    } else {
                        console.error("Parameter " + p.name + " has not an int value: ", v);
                        return;
                    }
                } else if ((typeof v) !== 'int' &amp;&amp; v !== null) {
                    console.error("Parameter " + p.name + " has not an int value: ", v);
                    return;
                }
            } else if (p.constraint == "string") {
                if ((v !== null) &amp;&amp; (typeof v) !== "string") {
                    console.error("Parameter " + p.name + " has not an string value: ", v);
                    return;
                }
            }

            if (p.source === 'hole') {
                var h = r.holes[p.name];

                uri = uri.replace("#" + p.name + "#", v)
            } else if (p.source === 'param') {
                params[p.name] = v;
            } else if (p.source === 'fixed') {
                if (v != p.value) {
                    continue loopRoutes;
                }
            }

        }

        var esc = encodeURIComponent;
        var query = Object.keys(params)
            .map(function(k) { return esc(k) + '=' + esc(params[k]) })
            .join('&amp;');

        if (query != '') {
            return uri + "?" + query
        } else {
            return uri
        }
    }
}


/*----- Formatted Prices -----*/
function displayFormattedPrice(mainInput, checkNumber) {
    var formattedInputJquery = $('#' + mainInput.attr('data-formattedprice'));
    var formattedInput = document.getElementById(mainInput.attr('data-formattedprice'));
    var mainPriceValue = mainInput.val();
    var isFloat = mainInput.attr('step') ? true : false;
    var decimalPlaces = 0;
    if (mainInput.attr('step')) {
        var step = mainInput.attr('step').split('.');
        decimalPlaces = step[1].length;
    }
    if (checkNumber) {
        if (!$.isNumeric(mainPriceValue)) {
            mainPriceValue = '';
        } else {
            mainPriceValue = mainPriceValue.replace(/^0+/, "");
            if (mainPriceValue == '') {
                mainPriceValue = 0;
            }
            mainInput.val(mainPriceValue);
        }
    }
    if (mainPriceValue === '' || mainPriceValue === 0 || mainPriceValue == undefined) {
        formattedInputJquery.val(mainPriceValue);
    } else {
        var priceCursorPos = false;
        var oldFormattedPrice = formattedInputJquery.val();
        var newFormattedPrice = getFormattedPrice(mainPriceValue, isFloat, decimalPlaces);
        if (formattedInputJquery.is(':focus')) {
            priceCursorPos = formattedInput.selectionStart;
            priceCursorPos += (newFormattedPrice.length - oldFormattedPrice.length);
            if (priceCursorPos &lt; 0) {
                priceCursorPos = 0;
            }
        }
        formattedInputJquery.val(newFormattedPrice);
        if (priceCursorPos !== false) {
            formattedInput.setSelectionRange(priceCursorPos, priceCursorPos);
        }
    }
    checkInputStatus(formattedInputJquery);
}

function formattedPrice(formattedInput, checkNumber) {
    var targetId = formattedInput.attr('data-formatprice');
    var mainInput = $('#' + targetId);
    mainInput.val(formattedInput.val().replace(/'/g, ''));
    displayFormattedPrice(mainInput, checkNumber);
}

/*---- Format Price -----*/
function getFormattedPrice(value, isFloat, decimalPlaces) {
    var position = 0;
    var decimal = '';
    var counter = 0;
    var ret = '';
    var i;

    position = value.indexOf('.');

    if (position &gt; 0) {
        decimal = value.substr(position + 1);
        value = value.substr(0, position);
    }

    for (i = value.length - 1; i &gt;= 0; i--) {
        if (value.charAt(i) == parseInt(value.charAt(i)) + '') {
            if (counter % 3 == 0 &amp;&amp; counter != 0) {
                ret = '\'' + ret;
            }
            ret = parseInt(value.charAt(i)) + ret;
            counter++;
        }
    }

    if (isFloat &amp;&amp; (parseInt(decimal) || position &gt; 0)) {
        if (decimal.length &gt; decimalPlaces) {
            decimal = decimal.substr(0, decimalPlaces);
        }
        ret += '.' + decimal;
    }

    return ret;
}


 /*----- Arrow top -----*/ 
 var BacktoTopDisplay = false;
 var windowHeight = $(window).height();
 $(window).scroll( function(){
     displayArrowTop();
      $('#back_to_top').addClass('active');
 });
 $('#back_to_top').click(function(){ 
     $('html, body').stop().animate({scrollTop:0}, 500); 
 }); 

/*back_to_top Display*/
var displayArrowTop = function() {
    windowHeight = $(window).height();

     if ($('body').height() &gt; windowHeight &amp;&amp; $(window).scrollTop() &gt; 100) { 
      if (!BacktoTopDisplay) { 
        $('#back_to_top').stop(true, true).fadeIn(); 
        BacktoTopDisplay = true; 
      } 
    } else { 
      if (BacktoTopDisplay) { 
        $('#back_to_top').stop(true, true).fadeOut(); 
        BacktoTopDisplay = false; 
      } 
    } 
}

/*---- Better Format Price -----*/
function formatPrice(value, isFloat, decimalPlaces, currency) {
    var position = 0;
    var decimal  = '';
    var counter  = 0;
    var ret      = '';
    var i;
    var suffix = '';
        
    position = value.indexOf('.');
    currency = currency || 'CHF';
    
    if (position &gt; 0) {
        decimal = value.substr(position + 1);
        value   = value.substr(0, position);
    }

    for (i = value.length - 1; i &gt;= 0; i--) {
        if (value.charAt(i) == parseInt(value.charAt(i)) + '') {
            if (counter % 3 == 0 &amp;&amp; counter != 0) {
                ret = '\'' + ret;
            }
            ret = parseInt(value.charAt(i)) + ret;
            counter++;
        }
    }

    if (isFloat &amp;&amp; (parseInt(decimal) || position &gt; 0)) {
        if (decimal.length &gt; decimalPlaces) {
            decimal = decimal.substr(0, decimalPlaces);
        } else if (decimal.length &lt; decimalPlaces) {
            decimal += '0'.repeat(decimalPlaces - decimal.length);
        }
        ret += '.' + decimal;
    } else {
        suffix = '.-';
    }

    return currency + ' ' + ret + suffix;
}

/* ----- Initialization Date Picker ----- */
function initDatePicker(input) {

    var v;
    var startDate = undefined;
    var isRange = false;
    var startDateRange = undefined;
    var maxDate = undefined;
    var minDate = undefined;
    var allowEmpty = false;
    var view = undefined;
    var minView = undefined;

    if (v = input.attr('data-startdate')) {
        startDate = new Date(v);
    }

    if (v = input.attr('data-mindate')) {
        minDate = new Date(v);
    }

    if (v = input.attr('data-maxdate')) {
        maxDate = new Date(v);
    }

    if (input.attr('data-range')) {
        isRange = true;
        startDateRange = [
            new Date($(input.attr("data-alt-field") + "_from").val()),
            new Date($(input.attr("data-alt-field") + "_to").val()),
        ];
    }

    if (input.attr('data-only-month-year') == 1) {
        view = 'months';
        minView = 'months';
        startDate = new Date();
    }

    allowEmpty = true;

    var inputDate = input.datepicker({
        startDate: startDate,
        maxDate: maxDate,
        minDate: minDate,
        view: view,
        minView: minView,

        clearButton: true,

        onSelect: function(formattedDate, date, inst) {
            if (isRange) {
                var altFrom = $($(inst.el).attr("data-alt-field") + "_from");
                var altTo = $($(inst.el).attr("data-alt-field") + "_to");

                if (date.length &gt;= 1) {
                    altFrom.val(formatDate(date[0]));
                }
                if (date.length &gt;= 2) {
                    altTo.val(formatDate(date[1]));
                }

                $(altTo).change();
            } else {
                var alt = $(inst.el).attr("data-alt-field");

                if (alt) {
                    $(alt).change();
                }
            }

            if ($(inst.el).val().length) {
                $(inst.el).trigger('change');

            }

            $(inst.el).removeClass('input_error');
        }
    }).data('datepicker');

    input.addClass('datepicker-initialized');

    if (!allowEmpty) {
        if (startDate) {
            inputDate.selectDate(startDate);
        } else if (startDateRange) {
            inputDate.selectDate(startDateRange);
        }
    }

    var oldValue = input.val();

    input.on('keyup', function(e) {
        var value = input.val();
        var inputTag = this;

        if (value != oldValue) {
            oldValue = value;

            if (value.length &gt; 0) {
                if (isRange) {
                    var sep = input.attr('data-multiple-dates-separator')
                    var dates = value.split(sep).map(parseDate);

                    if (dates[0] &amp;&amp; dates[1]) {
                        inputDate.hide();

                        inputDate.date = dates[0];
                        inputDate.selectDate(dates);
                    } else if (dates[0]) {
                        inputDate.hide();

                        inputDate.date = dates[0];
                        inputDate.selectDate(dates[0]);
                    } else {
                        input.addClass('input_error');
                    }
                } else {
                    var date = parseDate(value);

                    if (date) {
                        inputDate.hide();

                        inputDate.date = date;
                        inputDate.selectDate(date);

                        input.removeClass('input_error');

                        var caretPos = inputTag.selectionStart;
                        inputTag.setSelectionRange(caretPos, caretPos);
                    } else {
                        input.addClass('input_error');
                    }
                }
            } else {
                input.removeClass('input_error');
            }
        }
    });
}

function formatDate(d) {
    var month = '' + (d.getMonth() + 1),
        day = '' + d.getDate(),
        year = d.getFullYear();

    if (month.length &lt; 2)
        month = '0' + month;
    if (day.length &lt; 2)
        day = '0' + day;

    return [year, month, day].join('-');
}

function parseDate(str) {
    var r = str.match(/^(\d{1,2})\.(\d{1,2})\.(\d{4})(\s+(\d{1,2}):(\d{1,2}))?/)

    if (r &amp;&amp; parseInt(r[2]) &gt; 0) {
        var y = parseInt(r[3]);
        var m = parseInt(r[2]);
        var d = parseInt(r[1]);

        if (y &gt; 999 &amp;&amp; m &gt; 0 &amp;&amp; d &gt; 0) {
            if (r[4]) {
                return new Date(y, m - 1, d, parseInt(r[5]), parseInt(r[6]));
            } else {
                return new Date(y, m - 1, d);
            }
        }
    }

    return null;
}




/*--------------- Extend options ---------------*/
function extendOptions(base, options, target, prefix) {

    if (target != undefined) {
        if (target.is('[data-base-options-' + prefix + ']')) {
            base = window[target.attr('data-base-options-' + prefix)];
        }
        if (target.is('[data-auto-popup]')) {
            options['mainClass'] = 'auto-popup';
        }
        $.each(target.data(), function(name, value) {
            if (name.indexOf(prefix) == 0) { // if start by prefix
                var key = name.replace(prefix, '');
                var key = key.substr(0, 1).toLowerCase() + key.substr(1); // name of data atribut must be writed with - between word instead of uppercase.
                options[key] = value;
            }
        });
    }

    var extended = $.extend({}, base, options);

    return extended;
}




/*--------------- Popups ---------------*/
var mpOptBase = {
    type: 'image',
    mainClass: 'mfp-fade',
};

var mpOptGallery = extendOptions(mpOptBase, {
    delegate: 'a',
    gallery: {
        enabled: true
    },
});

var mpOptIframe = {
    type: 'iframe',
};

var mpOptYoutube = {
    type: 'iframe',
};

var mpOptLogin = {
    type: 'ajax',
    preloader: false,
    focus: '#login_user',
    callbacks: {
        ajaxContentAdded: function() {
            loadScripts($('.mfp-content'));
        }
    }
};

var mpOptObject = {
    type: 'ajax',
    preloader: false,
    // focus: '#login_user',
    callbacks: {
        ajaxContentAdded: function() {
            loadScripts($('.mfp-content'));
        }
    }
};

var mpOptPopup = {
    type: 'ajax',
    preloader: false,
    callbacks: {
        ajaxContentAdded: function() {
            loadScripts($('.mfp-content'));
        },
    }
};

var mapOptBase = {
    theme:           "osm_bright",
    allowScrollZoom: false,
    clusterPoints:   false,
    onBoundsChange:  undefined,
    markers:         {},
    boundsPadding: {top: 100, bottom:100, left: 100, right: 100},
};

function magnificPopup(target, options) {
    if (target.length) {
        target.magnificPopup(options);
    }
}

function Pictures(target, options) {
    if (target.is('[data-haspopup=true]')) {
        magnificPopup(target);
    }
}

/* ----- Multiselect ----- */
function updateMultiSelect(multiselect) {
    var totalCheck = multiselect.find('input[type=checkbox]:not(.not_counted), input[type=radio]:not(.not_counted)').filter(':not(.hide)');
    var limit = Number(multiselect.attr('data-limitdisplayed'));
    var defaultLabel = multiselect.attr('data-defaultlabel');
    var labelItem = multiselect.attr('data-labelitem');
    var selectTitle = multiselect.find('.multiselect_title');
    var count = 0;
    var text = '';

    totalCheck.each(function() {
        var check = $(this);
        if (check.is(':checked')) {
            count++;
            if (count &lt;= limit) {
                if (text != '') {
                    text += ', ';
                }
                text += check.parents('.multiselect_item').find('.label_text').html();
            } else {
                text = false;
            }
        }
    });

    if (count == 0 &amp;&amp; !multiselect.hasClass('check_all_in_title')) {
        text = defaultLabel;
        multiselect.removeClass('not_empty');
        selectTitle.addClass('placeholder');
    } else {
        if (!text) {
            text = count + ' / ' + totalCheck.length + labelItem;
        }
        multiselect.addClass('not_empty');
        selectTitle.removeClass('placeholder');
    }

    if (multiselect.hasClass('check_all_in_title')) {
        selectTitle.find('.check_all_counter').html('(' + text + ')');
    } else {
        selectTitle.html(text);
    }

    if (multiselect.hasClass('select_box')) {
        multiselect.siblings('.multiselect_cb').prop('checked', false);
    }
}

function getMultiselectValue(multiselect) {
    var values = [];

    multiselect.find('input[type=checkbox]:checked').each(function() {
        values.push($(this).val());
    });

    return values;
}

function setMultiselectValue(multiselect, toSet) {
    var previous = getMultiselectValue(multiselect);

    $.each(toSet, function(i, e) {
        var i = previous.indexOf(e);
        if (i &gt; -1) {
            previous.splice(i, 1);
        } else {
            checkMultiselectValue(multiselect, e);
        }
    });

    $.each(previous, function(i, e) {
        uncheckMultiselectValue(multiselect, e);
    });
}

function checkMultiselectValue(multiselect, value) {
    multiselect.find('input[type=checkbox][value="' + value + '"]').each(function() {
        $(this).prop('checked', true);
    });
}

function uncheckMultiselectValue(multiselect, value) {
    multiselect.find('input[type=checkbox][value="' + value + '"]').each(function() {
        $(this).prop('checked', false);
    });
}

function onMultiselectUpdate(multiselect, cb) {
    $('.multiselect_content input[type=checkbox], .multiselect_content input[type=radio]', multiselect).on('change', function() {
        cb(getMultiselectValue(multiselect));
    });
}

function getSelectValue(multiselect) {
    var selected = multiselect.find('input[type=radio]:checked')
    return selected.val();
}

function setSelectValue (multiselect, value) {
    multiselect.find(
        'input[type=radio][value="' + value + '"],' +
        'input[type=checkbox][data-highlight="' + value + '"]'
    ).each(function () {
        $(this).prop('checked', true);
    });

    multiselect.find(
        'input[type=radio][value!="' + value + '"],' +
        'input[type=checkbox][data-highlight!="' + value + '"]'
    ).each(function () {
        $(this).prop('checked', false);
    });
    updateMultiSelect(multiselect);
}

function unsetSelectValues (multiselect) {
    multiselect.find(
        'input[type=radio],' +
        'input[type=checkbox]'
    ).each(function () {
        $(this).prop('checked', false);
    });
    updateMultiSelect(multiselect);
}

function onSelectUpdate(multiselect, cb) {
    $('.multiselect_content input[type=checkbox], .multiselect_content input[type=radio]', multiselect).on('change', function() {
        cb(getSelectValue(multiselect));
    });
}

$('body').click(function(e) {
    var target = $(e.target);
    var msTarget = false;
    if (target.is('.multiselect_box')) {
        msTarget = target;
    } else if (target.parents('.multiselect_box').length) {
        msTarget = target.parents('.multiselect_box');
    } else if (target.is('.multiselect_cb')) {
        msTarget = target.siblings('.multiselect_box');
    } else if (target.is('label')) {
        msTarget = target.siblings('.multiselect_box');
    }
    if (msTarget) {
        msTarget.addClass('targeted');
    }
    $('.multiselect_box').each(function() {
        var ms = $(this);
        if (!ms.hasClass('targeted')) {
            ms.siblings('.multiselect_cb').prop('checked', false);
        } else {
            ms.removeClass('targeted');
        }
    });
});

/* ----- Favorite button ----- */
function toggleFavorite(button) {
    function updateFavoriteCounter(n) {
        var favCounters = $('.favorites_count');
        favCounters.each(function() {
            var favCounter = $(this);
            favCounter.text(n);
            var tab = favCounter.parents('.tab');
            if (n) {
                favCounter.removeClass('hide');
            } else {
                if (!tab.length) {
                    favCounter.addClass('hide');
                }
            }
            if (tab.length) {
                tab.click(function() {
                    window.location.href = $('.favorites_count', $(this)).attr('data-alt-link');
                });
            }
        });
    }

    button.click(function(e) {
        e.preventDefault();
        e.stopPropagation();
        var favButton = $(this);
        if (favButton.is('[data-object-id]')) {
            var object_id = favButton.attr('data-object-id');
        } else {
            var object_id = favButton.closest('[data-object-id]').attr('data-object-id');
        }
        var fav_btns = $("[data-object-id=" + object_id + "] .favorite_button, .favorite_button[data-object-id=" + object_id + "]");

        var add = !favButton.hasClass('favorite_on');

        $.post({
            data: {
                object_id: object_id,
                add: add ? 1 : 0,
            },
            url: _rr.Favorites.update(lang),
            success: function(data) {
                if (data.success) {
                    if (data.on) {
                        fav_btns.removeClass('favorite_off').addClass('favorite_on');
                    } else {
                        fav_btns.removeClass('favorite_on').addClass('favorite_off');
                    }

                    updateFavoriteCounter(data.counter);
                } else {
                    // TODO, display error?
                }
            },
        });
    });
}

/* ----- Visit contact display ----- */
function displayVisit(trigger) {
    if (trigger.length) {
        trigger.click(function() {
            $(this).hide();
            $(this).parents('.visit_box').find('.hide_visit_content').fadeIn(500);
        });
    }
}

/* ----- Price charges/costs display ----- */
function displayCosts(trigger) {
    if (trigger.length &amp;&amp; ($('.price_table tr.costs').length &gt; 0)) {
        trigger.click(function() {
            $(this).children('svg').hide();
            $(this).parent('.price').addClass('price_detailed');
            $('.price_table').fadeIn(500);
        });
    }
}


/* ----- Overlib ----- */
function initOverlibs(parent) {
    if (!$('#overlib').length) {
        $('footer').after('&lt;div id="overlib"&gt;&lt;/div&gt;');
    }
    if (!isTouchScreenDevice) {
        $(parent).on('mouseenter', '[data-overlib]', function() {
            overlib($(this).attr('data-overlib'), $(this).attr('data-overlibmaxwidth'), $(this).attr('data-overlibclass'));
        }).on('mouseleave', '[data-overlib]', function() {
            closeOverlib();
        });

        $(parent).on('mousemove', '[data-overlib]', function(event) {
            moveOverlib(event, $(this));        
        });
    } else {
        $('[data-overlib][data-overlibmobile=true]', parent).on('click', function() {
            if (!$('#overlib').is(':visible')) {
                overlib($(this).attr('data-overlib'), $(this).attr('data-overlibmaxwidth'), $(this).attr('data-overlibclass'));
            } else {
                closeOverlib();
            }
        });
        $(window).scroll(function() {
            closeOverlib();
        });
    }
}

function overlib(content, maxWidth, oclass) {
    if (content != '' &amp;&amp; content != ' ' &amp;&amp; content != false) {
        var o = $('#overlib');
        o.css({ 'maxWidth': maxWidth });
        o.html('&lt;div class="overlib_content ' + oclass + '"&gt;' + content.replace(/\\/g, '') + '&lt;/div&gt;').addClass('displayed');
    }
}

function moveOverlib(event, origin) {
    var o = $('#overlib');
    if (event.pageX + o.outerWidth() &gt;= $(window).width()) {
        o.css({ marginLeft: -o.width() - 15 });
    } else {
        o.css({ marginLeft: 15 });
    }
    if (parent != undefined &amp;&amp; origin.is('[data-overlibposition]')) {
        var olPos = origin.attr('data-overlibposition').split('-');
        o.stop(true, true);
        if (olPos.indexOf("top") != -1) {
            o.css({ top: event.pageY - $(window).scrollTop() - o.outerHeight() - 22 });
        } else {
            o.css({ top: event.pageY - $(window).scrollTop() });
        }
        if (olPos.indexOf("left") != -1) {
            o.css({ left: event.pageX - o.outerWidth() - 22 });
        } else {
            o.css({ left: event.pageX });
        }
    } else {
        o.stop(true, true).css({ left: event.pageX, top: event.pageY - $(window).scrollTop() });
    }
}

function closeOverlib() {
    $('#overlib').html('').removeClass('displayed');
}

/*--------------- Navigation menu mobile ---------------*/
function navigationScrollTs(header, navMobile) {
    if (header.outerHeight() + navMobile.outerHeight() + navMobile.position().top &gt; $(window).height()) {
        header.addClass('header_not_fixed');
        if ($('.fakeheader').length) {
            $('.fakeheader').addClass('header_not_fixed');
        }
        $('html, body').stop(true, true).scrollTop(0);
    }
}

function navigationSlide(target) {
    var header = target.parents('header');
    var navMobile = $('nav', header);
    if (target.length) {

        target.click(function() {
            if (!navMobile.is(':visible')) {
                navMobile.slideDown(function() {
                    navigationScrollTs(header, navMobile);
                });
                header.addClass('menu_open');
                $('body').addClass('body_menu_open');
                $('.menu_button .cross').addClass('open');
            } else {
                navMobile.slideUp();
                header.removeClass('menu_open').removeClass('header_not_fixed');
                if ($('.fakeheader').length) {
                    $('.fakeheader').removeClass('header_not_fixed');
                }
                $('body').removeClass('body_menu_open');
                $('.menu_button .cross').removeClass('open');
            }
        });
    }
}


/*--------------- Mobile filter ---------------*/
function mobileFilter(target) {
    var filterMobile = target.siblings('.filter_container');
    target.click(function() {
        if (!filterMobile.is(':visible')) {
            filterMobile.stop(true, true).slideDown(500);
            $('.show_filter').addClass('hide');
            $('.hide_filter').removeClass('hide');
            $('body').addClass('open_mobile_filter');
        } else {
            filterMobile.stop(true, true).slideUp(500);
            $('.show_filter').removeClass('hide');
            $('.hide_filter').addClass('hide');
            $('body').removeClass('open_mobile_filter');
        }
    });
}

/*--------------- Accordion ---------------*/
var initAccordion = function(targets, parent) {
    if ($(targets, parent).length) {
        $('.accordion_title', $(targets, parent)).click(function() {
            var accordion = $(this).parents(targets);
            if (accordion.hasClass('disabled')) {
                return;
            }

            if (accordion.hasClass('open')) {
                accordion.find('.accordion_content').stop(true, true).slideUp(250, function() {
                    accordion.removeClass('open').removeClass('open_default');
                });
            } else {
                var initialScrollTop = $(window).scrollTop();
                var openAccordeon = accordion.siblings(targets + '.open');
                var hOpenContent = openAccordeon.find('.accordion_content').innerHeight();
                openAccordeon.find('.accordion_content').stop(true, true).slideUp(0, function() {
                    openAccordeon.removeClass('open').removeClass('open_default');
                });

                var scrollTop = initialScrollTop - hOpenContent; 
                if (scrollTop &gt; 0 &amp;&amp; openAccordeon.length &amp;&amp; accordion.offset().top &gt; openAccordeon.offset().top &amp;&amp; !isIntegration) {
                    $(window).scrollTop(scrollTop);
                }
                if ($(window).scrollTop() + $(window).height() == $(document).height()) {
                    $(window).scrollTop($(window).scrollTop()-1); //to avoid accordeon opening in top direction
                }
                accordion.addClass('open');
                accordion.find('.accordion_content').stop(true, true).slideDown(250);
            }
        });
    }
}


/*------ Anchors ------*/

function goTo(el, speed, easing, anchorMargin) {
    var inAnimationScroll = false;
    var header = $('header');
        
    if ((typeof el) === 'string') {
        el = $(el);
    }

    // default
    if (typeof(anchorMargin) == 'undefined') {
        anchorMargin = 0;
    }
    // in case of floating header
    if (header.hasClass('header_scrollup') || header.hasClass('header_fixed')) {
        anchorMargin = header.outerHeight();
    }


    if (el.length &amp;&amp; !el.is(":hidden")) {
        inAnimationScroll = true;

        $('html,body').stop(true, true).animate({ scrollTop: el.offset().top - anchorMargin }, speed, easing, function() {
            inAnimationScroll = false;
        });
    }
}

function stickTop(el, topMargin) {
    var header = $('header');
        
    // default
    if (typeof(anchorMargin) == 'undefined') {
        anchorMargin = 0;
    }
    if(header.hasClass('scrollDown') &amp;&amp; $('#header_top .inner_content .nav_mobile').is(':hidden')){
        topMargin = 0;
    // in case of floating header
    }else if (header.hasClass('header_scrollup') || header.hasClass('header_fixed')) {
        topMargin = Math.round(header.outerHeight());
    }else{
        topMargin = 0;
    }

    el.attr('style', `top:` + topMargin+'px');
}

function anchorScroll(parent) {
    $('a[href^="#"]', parent).on('click', function() {
        var url = $(this).attr('href');
        var id = url.substr(url.indexOf("#"));
        if (id.length &gt; 1) {
            goTo(id, 600, 'swing');
        }
    });
}

if (!isIntegration &amp;&amp; window.location.hash != '') {
    if (!window.location.hash.includes('immomig:')) {
        goTo(window.location.hash, 10, 'swing');
    }
}


/* ----- Hide/display header on scroll ----- */
//TODO : Create config option to allow us decide if we want this function for custom website or not
var oldScrollTop = 0;
var currentScrollTop = 0;

function headerScrollPos(header) {
    var scroll = $(window).scrollTop();
    var headerHeight = header.height();

    currentScrollTop = scroll;

    if (header.hasClass('header_scrollup') &amp;&amp; !header.hasClass('header_not_fixed')) {
        if (currentScrollTop &gt; oldScrollTop &amp;&amp; scroll &gt; headerHeight) {
            header.addClass("scrollDown").removeClass("scrollUp");
        } else if (currentScrollTop &lt;= oldScrollTop &amp;&amp; !(scroll &lt;= headerHeight)) {
            header.removeClass("scrollDown").addClass("scrollUp");
        } else if (scroll &lt;= headerHeight) {
            header.removeClass("scrollUp").removeClass("scrollDown");
        }
    }

    oldScrollTop = currentScrollTop;
}

var setRealHeaderHeight;

function setHeaderHeight(header) {
    var fakeHeader = $('.fakeheader', header.parent());
    if (fakeHeader.length &gt; 0) {
        fakeHeader.css({height: header.height()+'px',  minHeight: header.height()+'px'});
    }
}
function addFakeHeader(header) {
    if (!header.hasClass('nofakeheader')) {
        $('&lt;div class="fakeheader" style="height:'+header.height()+'px; min-height:'+header.height()+'px;"&gt;&lt;/div&gt;').insertBefore(header);
        header.removeClass('fakeheader_loading');
    }
}

function headerScroll(header) {
    if (header.hasClass('header_scrollup')) {
        $(window).scroll(function() {
            headerScrollPos(header);
        });
    }

    if (header.hasClass('header_scrollup') || header.hasClass('header_fixed')) {
        addFakeHeader(header);
        $(window).resize(function() {
            headerScrollPos(header);
            setHeaderHeight(header);
        });
    }
}


/* ----- Switch Element ----- */
function switchElement(targets, state, callback) {
    targets.each(function() {
        var target = $(this);
        if (!target.hasClass(state)) {
            target.addClass(state);
        } else {
            target.removeClass(state);
        }
        if (callback != undefined) {
            eval(callback);
        }
    });
}


/* ----- Open Form on detail page ----- */
function openForm(button, target) {
    if (target.hasClass('hide')) {
        target.removeClass('hide');
        button.addClass('form_opened');
    }

    var object = button.attr("data-object");

    if(target.hasClass('project_table_contact')){
        var projects_object_id = target.find('form').children('[name=projects_object_id]');
        
        if(projects_object_id.length == 0){
            target.find('form').append('&lt;input type="hidden" name="projects_object_id" value="' + object + '" /&gt;');
        }
        else{
            projects_object_id.val(button.attr("data-object"));
        }
    }

    var ms = target.find("[data-field='objects'] .multiselect_box");

    if(target.find("[data-field='visit_objects']").length) {
        ms = target.find("[data-field='visit_objects'] .multiselect_box");
    }
    if(target.find("[data-field='contact_objects']").length) {
        ms = target.find("[data-field='contact_objects'] .multiselect_box");
    }

    if (object &amp;&amp; ms.length) {

        setMultiselectValue(ms, [object]);

        updateMultiSelect(ms);
    }

    goTo(target, 600, 'swing');
}



/* ----- From/To inputs min/max management ----- */
function fromToInputsMin(input) {
    if (input.is(':checked')) { // Only process checked inputs with a valid value
        let inputName = input.attr('name');
        let isFrom = inputName.includes('from');
        let isTo = inputName.includes('to');

        let inputTarget;

        if (isFrom) {
            inputTarget = $('[name=' + inputName.replace('from', 'to') + ']');
        } else if (isTo) {
            inputTarget = $('[name=' + inputName.replace('to', 'from') + ']');
        }
        
        if (inputTarget.length) {
            var inputValue = input.val() === '' ? NaN : Number(input.val()); // Treat empty as NaN
    
            inputTarget.each(function() {
                var iTarget = $(this);
                var iTDisplay = iTarget.parents('.multiselect_item').length ? iTarget.parents('.multiselect_item') : iTarget;
                var targetValue = iTarget.val() === '' ? NaN : Number(iTarget.val()); // Treat empty as NaN
    
                if (isNaN(inputValue) || isNaN(targetValue)) {
                    // If either input is "any" (""), remove all restrictions
                    iTDisplay.removeClass('higher_than_selected_max lower_than_selected_min');
                    return;
                }
    
                if (isFrom) {
                    if (targetValue &lt; inputValue) {
                        if (iTarget.is(':checked')) {
                            iTarget.prop('checked', false).change();
                        }
                        iTDisplay.addClass('lower_than_selected_min');
                    } else {
                        iTDisplay.removeClass('lower_than_selected_min');
                    }
                } else if (isTo) {
                    if (targetValue &gt; inputValue) {
                        if (iTarget.is(':checked')) {
                            iTarget.prop('checked', false).change();
                        }
                        iTDisplay.addClass('higher_than_selected_max');
                    } else {
                        iTDisplay.removeClass('higher_than_selected_max');
                    }
                }
            });
        }
    }
}



/* ----- CMS Links ----- */
function cmsLinks(links) {
    if (links.length) {
        links.click(function(e) {
            e.stopPropagation();
        });
    }
}



/* ----- Sliders ----- */
function updateSliderValues(sliderId, steps, limitedMax) { /* check if input has already values defined and update the slider */
    if($.type(steps) == 'string'){
        steps = JSON.parse(steps);
    }
    var handlers = $('.slider_handler[data-slider=' + sliderId + ']'),
        values = $('.slider_value[data-slider=' + sliderId + ']'),
        valuesParent = values.parents('.slider_values'),
        handlerSteps = { "from": 0, "to": steps.length - 1 };

    handlers.each(function() {
        var slider = $(this),
            step = slider.attr('data-slider-step');
        if (step != undefined) {
            handlerSteps[slider.attr('data-slider-handler')] = Number(step);
        }
    });

    values.each(function() {
        var value = $(this),
            type = value.attr('data-slider-value')
        step = handlerSteps[type];

        if (step != undefined) {
            value.html(steps[step]['text']);
        }

        /* Show/hide "and more" for maximum value */
        if (type == 'to' &amp;&amp; !limitedMax) {
            if (step == steps.length - 1) {
                $('.slider_and_more[data-slider=' + sliderId + ']').removeClass('hide');
            } else {
                $('.slider_and_more[data-slider=' + sliderId + ']').addClass('hide');
            }
        }
    });

    /* Add/remove unchanged state on values */
    if (handlerSteps['from'] == 0 &amp;&amp; handlerSteps['to'] == steps.length - 1) {
        valuesParent.addClass('unchanged');
    } else {
        valuesParent.removeClass('unchanged');
    }
}

function checkSlidersInput(input, sliderId, steps, stepPercent, limitedMax) { /* check if input has already values defined and update the slider */
    var iVal = Number(input.val()),
        type = input.attr('data-slider-input'),
        value = $('.slider_value[data-slider-value=' + type + '][data-slider=' + sliderId + ']')
    sParent = input.parents('.slider_js');

    if($.type(steps) == 'string'){
        steps = JSON.parse(steps);
    }

    if (iVal != '' || (iVal == 0)) {
        var closest = 0,
            closestStep;
        $.each(steps, function(index, value) {
            var v = value['value'];
            if (Math.abs(iVal - closest) &gt; Math.abs(iVal - v)) {
                closest = v;
                closestStep = index;
            }
        });

        if (closestStep == steps.length - 1 &amp;&amp; !limitedMax) {
            var inputVal = ''; /* if there is no top limit */
        } else {
            var inputVal = closest;
        }
        if (inputVal == 0) {
            var inputVal = ''; /* if 0 = empty */
        }

        input.val(inputVal);

        var handler = $('.slider_handler[data-slider-handler=' + type + '][data-slider=' + sliderId + ']', sParent);
        var sFull = $('.slider_full', sParent);

        if($('.slider_handler[data-slider-handler=from][data-slider=' + sliderId + ']', sParent).length == 0 &amp;&amp; (iVal == 0)) {
            closestStep = 0;
            
            if (inputVal == 0) {
                var inputVal = iVal; 
            }

            input.val(inputVal);
        } 

        handler.css({ 'left': (closestStep * stepPercent) + '%' }).attr('data-slider-step', closestStep);

        if (type == 'from') {
            sFull.css({ 'left': (closestStep * stepPercent) + '%' });
        } else {
            sFull.css({ 'right': (100 - (closestStep * stepPercent)) + '%' });
        }

        updateSliderValues(sliderId, steps, limitedMax);
    }
}

function resetSliderValues(sliderId, steps){
    if($.type(steps) == 'string'){
        steps = JSON.parse(steps);
    }
    var handlerFrom = $('.slider_handler[data-slider-handler=from][data-slider=' + sliderId + ']');
    var handlerTo = $('.slider_handler[data-slider-handler=to][data-slider=' + sliderId + ']');

    var sFull = $('div.slider[data-slider=' + sliderId + ']').find('.slider_full');
    handlerFrom.css({ 'left': '0%' }).attr('data-slider-step', 0);
    handlerTo.css({ 'left': '100%' }).attr('data-slider-step', steps.length - 1);

    sFull.css({ 'left': '0%' });
    sFull.css({ 'right': '0%' });

    $('.slider_value[data-slider-value=from][data-slider=' + sliderId + ']').text('0');
}

function initSliderHandlers(handler, sliderId, steps, stepPercent, limitedMax) {
    var sParent = handler.parents('.slider_js'),
        sHandlers = handler.parents('.slider_handlers'),
        type = handler.attr('data-slider-handler'),
        sFull = $('.slider_full', sParent),
        posPercent = undefined,
        step = undefined,
        input = $('input[data-slider-input=' + type + '][data-slider=' + sliderId + ']', sParent);

    /* sibling handler */
    var sibling = handler.siblings('.slider_handler');
    if (sibling.length) {
        var siblingPosPercent = undefined,
            siblingStep = undefined,
            siblingInput = input.siblings('input[data-slider-input]');
    }

    handler.draggable({
        containment: 'parent',
        axis: "x",
        // grid: [ steps.length, 0],
        drag: function(event, ui) {
            posPercent = ui.position.left * 100 / sHandlers.width();
            step = Math.round(posPercent / stepPercent);
            handler.attr('data-slider-step', step);

            if (type == 'from') {
                sFull.css({ 'left': ui.position.left });

                if (sibling.length &amp;&amp; sibling.position().left &lt; ui.position.left) { /* move the sibling handler if the position is not possible */
                    sibling.css({ left: posPercent + '%' });
                    sFull.css({ 'right': (100 - posPercent) + '%' });
                    sibling.attr('data-slider-step', step);
                    siblingStep = step;
                }
            } else {
                sFull.css({ 'right': (sHandlers.width() - ui.position.left) });

                if (sibling.length &amp;&amp; sibling.position().left &gt; ui.position.left) { /* move the sibling handler if the position is not possible */
                    sibling.css({ left: posPercent + '%' });
                    sFull.css({ 'left': posPercent + '%' });
                    sibling.attr('data-slider-step', step);
                    siblingStep = step;
                }
            }

            updateSliderValues(sliderId, steps, limitedMax);
        },
        stop: function(event, ui) {
            if (sibling.length &amp;&amp; siblingStep != undefined) { /* define the sibling handler value if it has moved */
                if (siblingStep == steps.length - 1 &amp;&amp; !limitedMax) {
                    var inputVal = ''; /* if there is no top limit */
                } else {
                    var inputVal = steps[siblingStep]['value'];
                }
                if (inputVal == 0) {
                    var inputVal = ''; /* if 0 = empty */
                }
                siblingInput.val(inputVal);
            }

            if (step == steps.length - 1 &amp;&amp; !limitedMax) {
                var inputVal = (input.attr('name').indexOf('_from') &gt; 0) ? steps[step]['value'] : ''; /* if there is no top limit */
            } else {
                var inputVal = steps[step]['value'];
            }
            if (inputVal == 0) {
                var inputVal = ''; /* if 0 = empty */
            }
            input.val(inputVal).change(); /* pass the value to the hidden input and submit the form */

            if (step == 0) { /* snap to the left border if first step */
                posPercent = 0;
            } else if (step == steps.length - 1) { /* snap to the right border if last step */
                posPercent = 100;
            }

            $(this).css({ left: posPercent + '%' }); /* transform values in % for responsive design */
            if (type == 'from') {
                sFull.css({ 'left': posPercent + '%' });
            } else {
                sFull.css({ 'right': (100 - posPercent) + '%' });
            }

            updateSliderValues(sliderId, steps, limitedMax);
        }
    });
}

function sliders(sliders) {
    if (sliders.length) {
        sliders.each(function() {
            var slider = $(this),
                steps = eval(slider.attr('data-slider-steps')),
                stepPercent = 100 / (steps.length - 1),
                sliderId = slider.attr('data-slider'),
                inputs = $('input[data-slider-input][data-slider=' + sliderId + ']', slider),
                limitedMax = Number($('.slider_js[data-slider=' + sliderId + ']').attr('data-slider-limited-max'));

            inputs.each(function() {
                checkSlidersInput($(this), sliderId, steps, stepPercent, limitedMax);
            });

            var handlers = $('.slider_handler[data-slider=' + sliderId + ']', slider);
            handlers.each(function() {
                initSliderHandlers($(this), sliderId, steps, stepPercent, limitedMax);
            });
        });
    }
}


/*--------------- Infinite scroll ---------------*/
function infiniteScroll(target, onLoad) {
    var loadData = function () {
        var viewBottom = $(window).scrollTop() + $(window).height();
        var targetBottom = target.offset().top + target.outerHeight();

        if (viewBottom &gt;= targetBottom) {
            if (!target.children('.infinite_loader').length) {
                target.append('&lt;div class="infinite_loader"&gt;&lt;/div&gt;');
            }
            var loadingBox = $('.infinite_loader', target);
            if (!loadingBox.hasClass('onloading')) {
                startLoading(loadingBox);
                onLoad(target, function () {
                    loadingBox.removeClass('onloading');
                    mapCtrlPosition($('.search_results_list_and_map #results_map'));
                });
            }
        }
    };

    var $button = target.find('button').first();

    $button.on('click', function () {
        $button.addClass('hide');
        loadData();
    });

    if (!$button.length) {
        $(window).scroll(function () {
            if (target.attr('data-active') === '1') {
                loadData();
            }
        });
    }
}



/*--------------- Map toggle ---------------*/
function mapToggle(mtButton, os) {
    if (mtButton.length) {
        mtButton.on('click', function() {
            var section_object_search_results = mtButton.parents('#search_results');
            var navId = section_object_search_results.attr('data-nav-id');
            var search_results = mtButton.parents('.search_results_list_and_map');
            var section_tool = mtButton.parents('.section_tools');
            if (search_results.hasClass('closed_map')) {
                search_results.removeClass('closed_map').addClass('open_map');
                section_tool.removeClass('closed_map').addClass('open_map');
                window.dispatchEvent(new Event('resize'));
                os.search({
                    load: "map",
                });

                createCookie('mapState-' + navId, 'open', 3600 * 24 * 365);
            } else {
                search_results.addClass('closed_map').removeClass('open_map');
                section_tool.addClass('closed_map').removeClass('open_map');

                createCookie('mapState-' + navId, 'closed', 3600 * 24 * 365);
            }
        });
    }
}



/*--------------- Map position, scroll in split search ---------------*/
var mapMarginScroll = 0;

function calcMapMarginScroll() {
    if ($('header').hasClass('header_fixed')) {
        mapMarginScroll = getHeaderHeightForMapReloadPosition($('body')[0]);
    }
}

window.addEventListener('scroll', calcMapMarginScroll);
window.addEventListener('resize', calcMapMarginScroll);

function mapPosition(map) {
    var mapParentPos = map.parent().offset().top;

    var scroll = $(window).scrollTop() + mapMarginScroll;
    var _height = 'calc(100vh - ' + mapMarginScroll + 'px)';
    if (scroll &gt; mapParentPos) {
        map.addClass('fixed').css({ top: mapMarginScroll, height: _height });
    } else {
        map.removeClass('fixed').css({ top: 0, height: '100vh' });
    }
}

function mapCtrlPosition(map) {
    if (map.length) {
        var scroll = $(window).scrollTop() ;
        var mapCtrl = $('.maplibregl-ctrl-group', map);
        var mapCopyright = $('.maplibregl-ctrl-attrib', map);
        var mapCtrlParent = mapCtrl.parent();
        var mapCtrlParentPos = mapCtrlParent.offset();
        if (mapCtrlParent.is('[class*=maplibregl-ctrl-top]')) {
            var headerBottomPos = $('header').offset().top + $('header').outerHeight();
            if (headerBottomPos &gt; mapCtrlParentPos.top) {
                mapCtrl.css({ top: headerBottomPos - scroll });
                mapCopyright.css({ top: headerBottomPos - scroll });
            } else {
                mapCtrl.css({ top: 0 });
                mapCopyright.css({ top: 0 });
            }
        } else if (mapCtrlParent.is('[class*=maplibregl-ctrl-bottom]')) {
            var scrollBottom = scroll + $(window).height();
            var footerPos = $('footer').offset().top;
            var mapCtrlParentPosBottom = mapCtrlParentPos.top + mapCtrlParent.outerHeight();

            var scrollDiff = mapCtrlParentPosBottom - scrollBottom;
            var footerDiff = scrollBottom - footerPos;
            var marginDiff = Math.max(scrollDiff, footerDiff);
            if (marginDiff &lt; 0) {
                marginDiff = 0;
            }

            mapCtrl.css({ bottom: marginDiff });
            mapCopyright.css({ bottom: marginDiff });
        }
    }
}



/* ----- Tabs show/hide ----- */
function tabs(tabs) {
    if (tabs.length) {
        tabs.each(function() {
            var tab = $(this);
            if (tab.is('.select_box')) {
                var tabOptions = tab.find('input[type=radio]');
                tabOptions.on('change click', function() {
                    var tabVal = '';
                    tabOptions.each(function() {
                        var t = $(this);
                        if (t.is(':checked')) {
                            tabVal = t.val();
                        }
                    });

                    target = $(tab.attr('data-tab-content') + tabVal);
                    target.siblings().addClass('hide');
                    target.removeClass('hide');
                });

            } else if (tab.is('.filter_box')) {
                var target = $(tab.attr('data-tab-content'));
                var button = tab.find('button.edit');
                button.on('click', function() {
                    tab.siblings('.filter_box').removeClass('selected');
                    tab.addClass('selected');
                    target.siblings().addClass('hide');
                    target.removeClass('hide');

                    showHidePriceWrapper();
                });
            } else {
                var target = $(tab.attr('data-tab-content'));
                tab.on('click', function() {
                    tab.siblings('.tab').removeClass('selected');
                    tab.addClass('selected');
                    target.siblings().addClass('hide');
                    target.removeClass('hide');
                    history.replaceState(null, null, ' ');

                    showHidePriceWrapper();
                });
            }
        });
    }
}


/* ----- Highlights for selects/multiselects ----- */
function selectHighlightsFromOriginal(original) {
    var hls = original.parents('.multiselect_content').find('input[data-highlight]');
    hls.prop('checked', false);

    var hl = original.parents('.multiselect_content').find('input[data-highlight="' + original.attr('value') + '"]');
    if (hl.length) {
        if (original.is(':checked')) {
            hl.prop('checked', 'checked');
        } else {
            hl.prop('checked', false);
        }
    }
}

function selectHighlights(parent) {
    var targets = $('input[data-highlight]', parent);
    if (targets.length) {
        targets.each(function() {
            var highlight = $(this);
            highlight.on('click', function() {
                var hl = $(this);
                var hls = hl.parents('.multiselect_content').find('input[data-highlight]:not([data-highlight=' + hl.attr('data-highlight') + '])');
                var or = hl.parents('.multiselect_content').find('input[value=' + hl.attr('data-highlight') + ']');

                hls.prop('checked', false);
                if (hl.is(':checked')) {
                    or.prop('checked', 'checked').change();
                } else {
                    or.prop('checked', false).change();
                }
            });
        });

        $('.multiselect_with_highlight input:not([data-highlight])', parent).on('click', function() {
            selectHighlightsFromOriginal($(this));
        });

        $('.multiselect_with_highlight input:not([data-highlight]):checked', parent).each(function() {
            selectHighlightsFromOriginal($(this));
        });
    }
}


/* ----- Selects/multiselects max height ----- */
function adaptSelectMaxHeight(targets) {
    targets.each(function() {
        var msc = $(this);
        if (msc.is(':visible')) {
            var mscTop = msc.offset().top;
            // var mscHeight = msc.offset().top;
            var wHeight = $(window).height();
            var wScroll = $(window).scrollTop();
            var mscMaxHeight = (wScroll + wHeight) - (mscTop) - 10;
            if (mscMaxHeight &gt;= 150) {
                msc.css({ maxHeight: mscMaxHeight });
            } else {
                msc.css({ maxHeight: 150 });
            }
        }
    });
}

function selectMaxHeight(targets) {
    if (targets.length) {
        adaptSelectMaxHeight(targets);

        $(window).scroll(function() {
            adaptSelectMaxHeight(targets);
        });

        $(window).resize(function() {
            adaptSelectMaxHeight(targets);
        });

        targets.each(function() {
            var msc = $(this);
            msc.parents('.multiselect_box').siblings('.multiselect_cb').on('click change', function() {
                adaptSelectMaxHeight(msc);
            });
        });
    }
}


function getTopMargin() {
    var topMargin = $('header').outerHeight();

    if (topMargin &gt; 200){
        topMargin = 120;
    }

    return topMargin;
}

/* ----- Project table ----- */
function projectTable(parent) {
    targets = $('.project_table', parent);
    if (targets.length) {
        targets.each(function() {
            var table = $(this);
            var rows = $('.project_table_row', table);
            rows.on('click', function() {
                var row = $(this);
                var id = row.attr('data-project-table-row');
                var rowContent = row.siblings('[data-project-table-content=' + id + ']');
                if (Number(table.attr('data-only-one-row-open')) == 1) {
                    row.siblings('.project_table_content').addClass('hide');
                    row.siblings('.project_table_row').removeClass('opened');
                }
                if (row.hasClass('opened')) {
                    row.removeClass('opened');
                    rowContent.addClass('hide');
                } else {
                    row.addClass('opened');
                    rowContent.removeClass('hide').addClass('onLoading');

                    if (!row.attr("data-loaded")) {

                        var td = rowContent.find("td");
                        startLoading(td);

                        $.get(_rr.Objects.ajaxTableContent(lang, id), function(res) {
                            if (res.success) {
                                td.html(res.html);
                                rowContent.removeClass('onLoading');
                                loadScripts(td)
                                row.attr("data-loaded", 1);
                            } else {
                                console.error(res);
                            }
                        });
                    }

                    if (Number(table.attr('data-only-one-row-open')) == 1) { /* debug if only one row open bug */
                        var topMargin = getTopMargin();
                        goTo('#' + row.attr('id'), 600, 'swing', topMargin);
                    }
                }
            });
        });

        var hash = window.location.hash;
        if (hash.indexOf('project_id_') != -1) {
            $(hash).click();
        }
    }

    var local_targets = targets;
    // we need to adapt colspan of cell containing detail of object if user resizes window
    $(window).resize(function () {
        adaptCellColspan(local_targets);
    });
    adaptCellColspan(local_targets);

    function adaptCellColspan(local_targets) {
        if (local_targets.length) {
            local_targets.each(function () {
                var table = $(this);
                var numberOfVisibleColumns = table.find('thead td:not(:hidden)').length;
                table.find('.project_table_content td').attr('colspan', numberOfVisibleColumns);
            });
        }
    }
}



/* ----- Placeholder effect compatible with all browsers ----- */
function checkInputStatus(input) {
    if (input.is(':focus')) {
        input.addClass('focus');
    } else {
        input.removeClass('focus')
    }

    var inputVal = input.val();
    if (inputVal != '' &amp;&amp; inputVal != undefined) {
        input.addClass('not_empty');
        input.removeClass('empty');
    } else {
        input.removeClass('not_empty')
        input.addClass('empty');
    }
}

function inputStatus(parent) {
    var inputs = $('input, textarea', parent);

    inputs.each(function() {
        checkInputStatus($(this));
    });

    inputs.on('focus blur keydown click change', function() {
        checkInputStatus($(this));
    });
}


/* ----- JS links ----- */
function jsLinks(targets) {
    targets.each(function() {
        $(this).click(function() {
            window.location.href = $(this).attr('data-link');
        });
    });
}

function stopProp(targets) {
    targets.each(function() {
        $(this).click(function(e) {
            e.stopPropagation();
            e.preventDefault();
        });
    });
}



/* ----- Global scripts loader and extension for custom websites ----- */
var _scriptsLoaded = false;
var _scriptsLoaders = [];

function registerScriptLoader(f) {
    _scriptsLoaders.push(f);

    if (_scriptsLoaded) {
        f($("html"));
    }
}

var _lazyLoaded  = false;
var _lazyLoaders = [];

function lazyLoad(el, loader) {
    if (!isIntegration) {
        if (isInViewport(el) || _lazyLoaded) {
            loader();
        } else {
            _lazyLoaders.push(loader);
        }
    } else {
        loader();
    }
}

$(function() {
    var lazyLoaded = function() {
        _lazyLoaded = true;

        for (i in _lazyLoaders) {
            _lazyLoaders[i]();
        }

        document.removeEventListener('scroll', lazyLoaded);
        document.removeEventListener('click',  lazyLoaded);
    };

    document.addEventListener('scroll', lazyLoaded);
    document.addEventListener('click',  lazyLoaded);
});

function loadScripts(parent, firstLoad = false) {
    _scriptsLoaded = true;

    $('.preload', parent).removeClass('preload');

    for (i in _scriptsLoaders) {
        _scriptsLoaders[i](parent);
    }

    /* ----- Multiselects ----- */
    $('div.multiselect_box', parent).each(function() {
        updateMultiSelect($(this));
    }).on('change', function(e) {
        updateMultiSelect($(this));
    });
    $('div.multiselect_box input[type=checkbox], div.multiselect_box input[type=radio]', parent).on('change', function() {
        updateMultiSelect($(this).parents('.multiselect_box'));
    });

    /* ----- Overlib ----- */
    if ($('[data-overlib]', parent).length) {
        initOverlibs(parent);
    }


    /*----- Formatted price -----*/
    $('input[data-formatprice]', parent).on('input change', function() {
        formattedPrice($(this), false);
    });

    $('input[data-formatprice]', parent).on('blur', function() {
        formattedPrice($(this), true);
    });

    $('input[data-formattedprice]', parent).each(function() {
        displayFormattedPrice($(this), true);
    });

    $('input[data-formattedprice]', parent).change(function() {
        displayFormattedPrice($(this), true);
    });



    /* ----- From/To inputs min/max management ----- */
    $('input[name*=from]', parent).change(function() {
        fromToInputsMin($(this));
    });
    $('input[name*=from]:checked', parent).each(function() {
        fromToInputsMin($(this));
    });

    $('input[name*=to]', parent).change(function () {
        fromToInputsMin($(this));
    });
    $('input[name*=to]:checked', parent).each(function() {
        fromToInputsMin($(this));
    });


    /* ----- Sliders ----- */
    sliders($('.slider_js', parent));


    /* ----- Highlights for selects/multiselects ----- */
    selectHighlights(parent);


    /* ----- Selects/multiselects max height ----- */
    selectMaxHeight($('.multiselect_content', parent));


    /* ----- Add scroll effect to anchor ----- */
    anchorScroll(parent);

    /* ----- Placeholder effect compatible with all browsers ----- */
    inputStatus(parent);


    /* ----- Cms Links ----- */
    cmsLinks($('.cms_link a', parent));


    /* ----- Project table ----- */
    projectTable(parent);

    /* ----- JS links ----- */
    jsLinks($('[data-link]', parent));
    stopProp($('.stop_propagation', parent));

    launchNumberAnimation(parent);


    /* ----- Magnific popup ----- */
    $('.magnific-popup, .magnific_popup_parent a, .magnific_popup_gallery', parent).each(function() {
        var mp = $(this);
        if (mp.is('[href]')) {
            var mpOpt = mpOptBase;
        } else {
            var mpOpt = mpOptGallery;
        }
        magnificPopup(mp, extendOptions(mpOpt, {}, mp, 'mp'));
    });

    $('.magnific_popup_link a, [data-magnific-popup-link]', parent).each(function() {
        var mp = $(this);
        var mpOpt = mpOptPopup;
        magnificPopup(mp, extendOptions(mpOpt, {}, mp, 'mp'));
    });

    toggleFavorite($('.favorite_button', parent));

    headerScroll($('header', parent));

    mobileFilter($('.filter_button_mobile', parent));

    navigationSlide($('.nav_mobile', parent));

    initAccordion('.accordion_box, .cms_accordion', parent);

    displayVisit($('.display_visit', parent));

    displayCosts($('.display_costs', parent));


    /* ----- Switch Element ----- */
    $('[data-switch-target]', parent).click(function() {
        switchElement(eval($(this).attr('data-switch-target')), $(this).attr('data-switch-state'), $(this).attr('data-switch-callback'));
    });


    /* ----- Open Form on detail page ----- */
    $('.openform_button', parent).click(function() {
        $('section.visit_form', parent).addClass('hide');
        $('div.global_messages').addClass('hide');

        $.magnificPopup.close();

        openForm($(this), eval($(this).attr('data-open-target')));
    });

    $('.openvisitform_button', parent).click(function() {
        $('section.contact_form').addClass('hide');
        $('div.global_messages').addClass('hide');

        $.magnificPopup.close();
        
        openForm($(this), eval($(this).attr('data-open-target')));
    });

    $('.openfinancingcontactform_button', parent).click(function() {
        $('div.financing_contact_form_box').removeClass('hide');
        $('div.global_messages').addClass('hide');

        $.magnificPopup.close();
        
        openForm($(this), eval($(this).attr('data-open-target')));
    });


    /* ----- Tabs show/hide ----- */
    tabs($('[data-tab-content]', parent));



    /* ----- DatePicker ----- */
    $('[data-datepicker]', parent).each(function () {
        initDatePicker($(this));

        if (isTouchScreenDevice) { /* Avoid to open keyboard on iphone because there is not enough place for see keyboard and datepicker at the same time. */
            $(this).attr("readonly", "true");
        }
    });

    displayObjListSwiper(parent);
}

function onInputChange(inputs, cb) {
    inputs.each(function() {
        var typingTimer;
        var doneTypingInterval = 500;
        var $this = $(this);

        $this.on('keyup', function() {
            clearTimeout(typingTimer);
            typingTimer = setTimeout(function() { cb($this) }, doneTypingInterval);
        });

        $this.on('keydown', function() {
            clearTimeout(typingTimer);
        });
    });
}

function onFormChange(form, cb) {

    onInputChange($("input[type='text']:not(.autocomplete)", form), cb);

    $("select, input:not(.multiselect_cb):not(.autocomplete)", form).change(function() {
        var input = $(this);
        if (!input.is(':focus') || !input.is('[type=text]')) {
            cb(input);
        }
    });
}

function getFormFields(form) {
    var params = {};
    $("select, input[type='hidden'], input[type='date'], input[type='text'], input[type='number'], input[type='checkbox']:checked, input[type='radio']:checked", form).each(function() {
        if ($(this).hasClass('autocomplete') || $(this).hasClass('no_search')) {
            return;
        }

        var v = $(this).val();

        var name = $(this).attr('name');

        if (v === "" || (Array.isArray(v) &amp;&amp; v.length === 0) || !name) {
            return;
        }

        if (name.endsWith('[]')) {
            name = name.substring(0, name.length - 2);

            if (name in params) {
                params[name].push(v)
            } else {
                params[name] = [v]
            }
        } else {
            params[name] = v;
        }

    });

    return params;
}

var additionalParams = extendOptions(additionalParams,
    {}
);

function feObjectsSearch(form, options) {
    options = $.extend({
        el: form,
        title: undefined,
        total: undefined,
        list: undefined,
        map: undefined,
        scroll: undefined,
        fitBounds: true,
    }, options)

    var xhrs = {
        "list_and_map": null,
        "list": null,
        "map": null,
    };

    var lastTotal = options.total;

    var search = this;

    this.options = options;

    this.getSearchParams = function() {
        var baseParams = getFormFields(form);
        if (options.list) {
            if(options.list.el) {
                baseParams.style = options.list.el.attr("data-list-style");
            } else {
                baseParams.style = options.list.attr("data-list-style");
            }
        }
        return baseParams;
    }

    this.loadResultsTitle = function(title, res) {
        title.html(res.title);
    }

    this.updateHtmlPageTitle = function (res) {
        if (!res.title) {
            return;
        }

        var $htmlPageTitle = $('title');

        var originTitle = $htmlPageTitle.attr('data-title-origin');
        if (!originTitle) {
            return;
        }

        var searchTitle = res.title.replace(/(&lt;([^&gt;]+)&gt;)/ig, '');
        $htmlPageTitle.html(searchTitle + ' | ' + originTitle);
    }

    this.loadResultsList = function (list, res) {
        var el = list.el;
        if (!el) {
            el = list;
        }

        var scroll = el.find('.infinite_scroll, .infinite_scroll_by_button');

        if (scroll.length &amp;&amp; res.pagination) {
            var dataUrl = '';
            if (res.pagination.nexts.length &gt; 0) {
                dataUrl = res.pagination.nexts[0].url;
            }

            scroll.attr('data-url', dataUrl);
            scroll.attr('data-active', dataUrl ? '1' : '0');

            var $button = scroll.find('button').first();
            if ($button.length) {
                if (dataUrl) {
                    $button.removeClass('hide');
                } else {
                    $button.addClass('hide');
                }
            }
        }

        el.children(".objects_list").replaceWith(res.list);

        if (res.pagination &amp;&amp; 'html' in res.pagination) {
            el.children('.pagination').replaceWith(res.pagination.html);
            loadManualPagination(el);
        }
        loadScripts(el.children(".objects_list"));
    }

    this.loadResultsMap = function(map, res) {
        // Sometimes res.map does not exist if there is no need to reload the map
        if(map.instance) {
            map.instance.setMarkers(res.map.markers, res.map.bounds, this.options.fitBounds);
        }

        if(res.total &gt; 1000) {
            $('#see_more_objects_message').show();
        } else {
            $('#see_more_objects_message').hide();
        }
    }

    this.onResults = function(res) {
        updateLocationPreviewFilter();

        if (this.options.title) {
            this.updateHtmlPageTitle(res);
            this.loadResultsTitle(this.options.title, res);
        }

        if ('total' in res) {
            lastTotal = res.total;
            this.options.el.attr('data-items', res.total);
        }
        
        if (('list' in res) &amp;&amp; this.options.list) {
            this.loadResultsList(this.options.list, res);
        }

        if (('map' in res) &amp;&amp; this.options.map) {
            this.loadResultsMap(this.options.map, res);
        }
    }

    this.onError = function(msg) {
        console.error(msg);
    }

    this.setUrl = function(url) {
        this.options.url = url;
    }

    this.setMap = function(map) {
        this.options.map.instance = map;
    }

    this.search = function(opts) {
        opts = $.extend({
            rewriteUrl: true,
            load: "list_and_map",
            fitBounds: true,
            from: undefined,
        }, opts);

        opts = extendOptions(opts)
        this.options.fitBounds = opts.fitBounds;

        console.log("Searching with", opts)

        var params    = $.extend({}, this.getSearchParams(), additionalParams);
        var urlParams = $.extend({}, params);

        delete urlParams.pagination_type;
        delete urlParams.page_size;
        delete urlParams.from;
        delete urlParams.page;
        delete urlParams.radius_to;
        
        delete params.page;

        params.load = opts.load;
        params.total = opts.load === 'list_total' ? true : lastTotal;
        
        // TODO: check ? 
        if (urlParams.location != null &amp;&amp; params.radius_to != null) {
            var radiusInd = urlParams.location.indexOf('+');
            if (radiusInd != -1) {
                var location = urlParams.location.substring(0, radiusInd);
                urlParams.location = location + '+' + params.radius_to;
                params.location = location + '+' + params.radius_to;
            } else {
                urlParams.location += '+' + params.radius_to;
                params.location += '+' + params.radius_to;
            }
        }

        if (opts.rewriteUrl) {
            history.replaceState(null, "", "?" + $.param(urlParams));
        }

        // update menu languages
        $("input[name='languages']").each(function(){
            var data_link = $(this).attr('data-link');
            data_link = data_link.split('?')[0];
            data_link = data_link + "?" + $.param(urlParams);
            $(this).attr('data-link', data_link);
        });

        //kill xhr call if one is running. avoid multiple search call
        let aborts = [];
        if (opts.load == "list_and_map") {
            aborts = ['list_and_map', 'list', 'map'];
        } else {
            aborts = [opts.load];
        }

        aborts.forEach((e) =&gt; {
            if (xhrs[e]) {
                xhrs[e].abort();
                xhrs[e] = null;
            }
        })

        var target = [];
        if (opts.load == 'map') {
            target.push(options.map.el.find('.map_canvas'));
        } else if (['list', 'list_total'].includes(opts.load)) {
            target.push(options.list.el);
        } else {
            target.push(options.map.el.find('.map_canvas'));
            target.push(options.list.el);
        }
        target.forEach((t) =&gt; {
            startLoading(t);
        });

        if (opts.from == 'filters') {
            startLoadingObjectsSearchTitle(options.title);
        }
        
        xhrs[opts.load] = $.get({
            url: this.options.url,
            data: params,
            success: function(res) {
                if (res.success) {
                    search.onResults(res);
                } else {
                    search.onError("Error fetching results");
                }
            },
            error: function(e) {
                if (e.statusText != 'abort') {
                    search.onError("Error making request");
                }
            },
            complete: function() {
                xhrs[opts.load] = null;

                target.forEach((t) =&gt; {
                    endLoading(t);
                });
                endLoading(options.title);
            },
        });
    }

    this.countResults = function(opts) {
        opts = $.extend({
            success:  function(res) {},
            error:    function(err) {},
            complete: function(res) {},
        }, opts);

        var params    = $.extend({}, this.getSearchParams());
        delete params.page;
        params.load = "count";

        xhrs["count"] = $.get({
            url: this.options.url,
            data: params,
            success: function(res) {
                if (res.success) {
                    opts.success(res);
                }
            },
            error: function(e) {
                if (e.statusText != 'abort') {
                    // noop
                    opts.error(e);
                }
            },
            complete: function() {
                xhrs["count"] = null;

                opts.complete();
            },
        });
    }
}

function startLoadingObjectsSearchTitle(title) {
}

function updateLocationPreviewFilter() {
}

function initSearchField(el, opts) {
    if (!('url' in opts)) {
        console.error("Missing opts.url");
        return;
    }

    if (!('multiple' in opts)) {
        opts.multiple = false;
    }

    if ('radius' in opts) {
        var radius = $(el).parents('.filter_part_location').find('.filter_part_radius');
        var location = $(el).siblings('[name="location"]').val();
        if (!location) {
            hideRadiusFilter();
        } else {
            showRadiusFilter();
        }
    } else {
        var radius = null;
    }

    if (!('onSelect' in opts)) {
        if (opts.multiple) {
            opts.onSelect = function(el, item, event) {};
        } else {
            opts.onSelect = function(el, item, event) {
                $(el.attr('data-field-value') + '_search').val("");

                var v = $(el.attr('data-field-value'));

                if (v.val() !== item.v) {
                    v.val(item.v);
                    v.change();
                }

                if (radius) {
                    showRadiusFilter();
                } else {
                    hideRadiusFilter();
                }
            };
        }
    }

    if (!('onLoading' in opts)) {
        opts.onLoading = function(f) {
            startLoading($(f).parents('.input'));
        };
    }
    if (!('onLoaded' in opts)) {
        opts.onLoaded = function(f) {
            endLoading($(f).parents('.input'));
        };
    }

    var ac = $(el).on("keydown", function(event) {
        if (event.keyCode === $.ui.keyCode.TAB &amp;&amp; $(this).autocomplete("instance").menu.active) {
            event.preventDefault();
        }
    }).autocomplete({
        source: function (request, response) {
            startLoading($(el).parent());
            $(el.attr('data-field-value') + '_search').val(request.term);

            var url = opts.url.replace("%25q", encodeURIComponent(request.term));

            var params = {};

            // If %q not found in url, we inject it within parameter 'q'
            if (url == opts.url) {
                params.q = request.term;
            }

            if ('params' in opts) {
                for (var v in opts.params) {
                    params[v] = opts.params[v];
                }
            }

            if (opts.onLoading) {
                opts.onLoading(el)
            }

            $.getJSON(url, params, function (res) {
                if (opts.onLoaded) {
                    opts.onLoaded(el)
                }
                if (res.success) {
                    response(res.results)
                }
            });
        },
        open: function(event, ui) {
            if($(el.attr('data-field-value') + '_search').val() == ''){
                resetValue();
            }
        },
        select: function(event, ui) {
            opts.onSelect($(el), ui.item, event)
            if (opts.multiple &amp;&amp; ui.item) {
                ui.item.value = '';
            }
        },
        response: function(event, ui) {
            endLoading($(el).parent());
            jQuery.ui.autocomplete.prototype._resizeMenu = function() {
                var ul = this.menu.element;
                var uiWidth = this.element.outerWidth();
                var uiWidthStep = Math.ceil(uiWidth / 200) * 200;
                ul.outerWidth(uiWidth);
                ul.attr('data-uiwidth', uiWidthStep);
            }
        },
    }).autocomplete("instance");

    ac._renderItem = function(ul, item) {

        var cls = '';
        if (('type' in item) &amp;&amp; item.type == 'notfound') {
            cls = 'ui-state-disabled';
        }

        var content = (('html' in item) ? item.html : item.label);
        var res = $('&lt;li class="ui-menu-item ' + cls + '"&gt;')
            .append('&lt;div tabindex="-1" class="ui-menu-item-wrapper"&gt;' + content + '&lt;/div&gt;')
            .appendTo(ul);

        return res;
    };

    ac._renderMenu = function(ul, items) {
        $.each(items, function(index, item) {
            ac._renderItemData(ul, item);
        });

        loadScripts(ul);
    }


    onInputChange($(el), function() {
        if ($(el).val() == '') {
            resetValue();
        }
    });

    function resetValue() {
        var v = $($(el).attr('data-field-value'));

        if (v.val() != '') {
            v.val('');
            v.change();
        }
        hideRadiusFilter();
    }

    function showRadiusFilter() {
        if(radius == null){
            return;
        }
        radius.removeClass('hide');
        radius.parents('form').addClass('radius_visible');
    }

    function hideRadiusFilter() {
        if(radius == null){
            return;
        }
        radius.addClass('hide');
        radius.parents('form').removeClass('radius_visible');
    }
}

function feMultiAutocomplete(el, options) {

    options = $.extend({}, options)

    var ma = this;

    ma.values = [];

    var input = el.find('.autocomplete_multiple_real_input input[type="text"]');

    var fakeInput = el.find('.input_autocomplete_multiple');

    input.on('focus', function() {
        fakeInput.addClass('focus');
    });


    input.on('blur', function() {
        fakeInput.removeClass('focus');
    });

    input.keydown(function(e) {
        if ((e.which == 8 || e.which == 46) &amp;&amp; $(this).val() == '') {
            ma.values.pop();
            ma.onUpdate();
            if (ma.values.length == 0) {
                fakeInput.removeClass('not_empty');
            }
        }
    });

    $(".autocomplete_result", el).each(function() {
        ma.values.push({
            value: $(this).attr('data-value'),
            html: $(this).html(),
        });
    });


    this.onUpdate = function() {
        el.find(".autocomplete_result").remove();
        var ri = el.find(".autocomplete_multiple_real_input")
        var values = [];

        ma.values.map(function(e) {
            var r = $('&lt;span class="autocomplete_result"&gt;' + e.html + '&lt;span class="remove"&gt;&lt;/span&gt;&lt;/span&gt;')
            r.attr('data-value', e.value)

            r.click(function () {
                ri.find('input.autocomplete').focus();
            });

            r.find(".remove").click(function() {
                ma.remove(e.value);
                if (fakeInput.hasClass('focus')) {
                    input.focus();
                }
            });

            values.push(e.value);

            r.insertBefore(ri);

            fakeInput.addClass('not_empty');
        });

        var field = $(ri.attr('data-field-value'))
        var value = values.join(',');

        var nbrElements = values.length;
        var nbrLimitDisplayed = Number(fakeInput.attr('data-limit-displayed'));

        if (nbrElements &gt; nbrLimitDisplayed) {
            fakeInput.addClass('display_limited');
        } else {
            fakeInput.removeClass('display_limited');
        }

        el.find('.nbr_elements').html(nbrElements);

        if (field.val() != value) {
            field.val(value);
            field.change();
        }
    }

    this.add = function(v, html) {
        var i = ma.values.findIndex(function(e) {
            return e.value === v;
        });

        if (i &lt; 0) {
            ma.values.push({
                value: v,
                html: html,
            });

            ma.onUpdate();
        }
    }

    this.remove = function(v) {
        ma.values = ma.values.filter(function(e) {
            return e.value !== v;
        });

        ma.onUpdate();

        if (ma.values.length == 0) {
            fakeInput.removeClass('not_empty');
        }
    }

    this.clear = function() {
        ma.values = [];
        ma.onUpdate();
    };

    if (ma.values.length) {
        ma.onUpdate();
    }
}

function createCookie(name, value, maxlife) {
    var expires;

    if (maxlife) {
        var date = new Date();
        date.setTime(date.getTime() + (maxlife * 1000));
        expires = "; expires=" + date.toGMTString();
    } else {
        expires = "";
    }
    document.cookie = encodeURIComponent(name) + "=" + encodeURIComponent(value) + expires + "; path=/";
}

function readCookie(name) {
    var nameEQ = name + "=";
    var ca = document.cookie.split(';');
    for(var i=0;i &lt; ca.length;i++) {
        var c = ca[i];
        while (c.charAt(0)==' ') c = c.substring(1,c.length);
        if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
    }
    return null;
}

function submitAjaxForm(form, opts) {

    if (!opts) {
        opts = {};
    }

    opts = $.extend({
        messagesTarget: undefined,
        url: undefined,
    }, opts)

    if (validateForm(form)) {
        startLoading(form);

        if ('onSubmit' in opts) {
            opts.onSubmit();
        }

        sendAjaxForm(form, opts, function(success, res) {
            if (success) {
                if (res.require_captcha == true) {
                    $('.row_recaptcha').parent().removeClass('hide');
                }

                if ('messages' in res) {
                    if ('onMessages' in opts) {
                        opts.onMessages(res)
                    } else {
                        if (!opts.messagesTarget) {
                            displayGlobalMessages(res.messages)
                        } else {
                            displayMessages(opts.messagesTarget, res.messages)
                        }
                    }
                }

                if (res.success) {
                    clearFormErrors(form);
                    submitGtagEvents(form);

                    if ('onSuccess' in opts) {
                        opts.onSuccess(res)
                    } else {
                        var form_hide = form.closest(".hide_form");
                        if (form_hide.length) {
                            form_hide.addClass("hide");
                        }

                        if (res.redirect) {
                            setTimeout(function () {
                                window.location = res.redirect;
                            }, 2000);
                        } else {
                            endLoading(form);
                        }
                    }

                } else {
                    loadFormErrors(form, res.errors);

                    if (typeof window.resetCaptchas === 'function') {
                        window.resetCaptchas(form)
                    }

                    if ('onError' in opts) {
                        opts.onError(res)
                    }
                    endLoading(form);
                }
            } else {
                console.error("Request failed", res);
                if (typeof resetRecaptchas === 'function') {
                    resetRecaptchas(form)
                }

                if ('onError' in opts) {
                    opts.onError(res)
                }
            }

            if ('onEnd' in opts) {
                opts.onEnd(res);
            } else {
                if (res &amp;&amp; !res.redirect) {
                    endLoading(form);
                }
            }
        });
    }

    return false;
}

function submitGtagEvents(form) {
}
function prospectionGtagEvents(step) {
}

function enableDisplaysToggles(parent) {

    function updateTargets() {
        var allTargets = [];

        $(".displays_toggle", parent).each(function() {
            var dt = $(this);

            var targets = dt.closest(dt.attr('data-displays-within')).find(dt.attr('data-displays'));
            var checked = dt.prop("checked");

            targets.each(function() {
                var found = false;
                var target = $(this);

                for (var i = 0; i &lt; allTargets.length; i++) {
                    if (allTargets[i][0][0] === target[0]) {
                        allTargets[i][1] = allTargets[i][1] || checked;
                        found = true;
                        break;
                    }
                }
                if (!found) {
                    allTargets.push([target, checked]);
                }
            });
        });

        for (var i = 0; i &lt; allTargets.length; i++) {
            if (allTargets[i][1]) {
                allTargets[i][0].removeClass('hide');
            } else {
                allTargets[i][0].addClass('hide');
            }
        }
    }

    updateTargets();

    $(".displays_toggle", parent).each(function() {
        if ($(this).attr('type') == 'radio') {
            // We need to get all radios of the same name
            // This makes sure that when deselecting a radio by selecting
            // another, the change event still gets triggered
            $("input[name='" + $(this).attr('name') + "']").change(function() {
                updateTargets();
            });
        } else {
            $(this).change(function() {
                updateTargets();
            })
        }
    });
}

function enableRequiresToggles(parent) {

    var requiredClass = 'row_required';

    function updateTargets() {

        var allTargets = [];

        $(".requires_toggle", parent).each(function() {
            var dt = $(this);

            var targets = dt.closest(dt.attr('data-requires-within')).find(dt.attr('data-requires'));
            var checked = dt.prop("checked");

            targets.each(function() {
                var found = false;
                var target = $(this);

                for (var i = 0; i &lt; allTargets.length; i++) {
                    if (allTargets[i][0][0] === target[0]) {
                        allTargets[i][1] = allTargets[i][1] || checked;
                        found = true;
                        break;
                    }
                }
                if (!found) {
                    allTargets.push([target, checked]);
                }
            });

        });

        for (var i = 0; i &lt; allTargets.length; i++) {
            var elem = allTargets[i][0];
            if (allTargets[i][1]) {
                elem.addClass(requiredClass);
                if (elem.find('.required_field').length &lt; 1) {
                    elem.find('.placeholder').append(' ' + '&lt;span class="required_field"&gt;*&lt;/span&gt;');
                }
            } else {
                elem.removeClass(requiredClass);
                elem.find('.required_field').remove();
            }
        }
    }

    updateTargets();

    $(".requires_toggle", parent).each(function() {
        if ($(this).attr('type') == 'radio') {
            $("input[name='" + $(this).attr('name') + "']").change(function() {
                updateTargets();
            });
        } else {
            $(this).change(function() {
                updateTargets();
            })
        }
    });
}


function loadManualPagination(el) {
    $(".pagination_manual &gt; li &gt; a", el).click(function(e) {
        e.preventDefault();

        startLoading(el);

        $.get($(this).attr("href"), function(res) {

            // Situation before:
            //   &lt;.cms_objects_list&gt;&lt;.objects_list&gt;&lt;res1 /&gt;&lt;res2 /&gt;...&lt;/.objects_list&gt;&lt;loader /&gt;&lt;/.cms_objects_list&gt;
            //
            // AJAX call returns res.list with:
            //   &lt;list&gt;&lt;res5 /&gt;&lt;res6 /&gt;...&lt;/list&gt;
            if(el.find('.pagination').length &gt; 1) {
                el.html(res.pagination.html + res.list + res.pagination.html);
            } else {
                el.html(res.list + res.pagination.html);
            }


            loadManualPagination(el);

            loadScripts(el);

            endLoading(el);
            
            if (el.parents('div[data-scroll-target=filters]').length &amp;&amp; (filters_el = el.parents('#search_results').siblings('.objects_filters')).length) {
                el = filters_el;
            }
            if (isIntegration) {
                globalEvent(null, 'scrollTop', { 'offset' : el.offset().top });
            } else {
                goTo(el, 600, 'swing');
            }
        })
    });
}

function showHidePriceWrapper(){
    var selectedDeal = $('div.user_criterias_filter:visible').find('[name=user_criterias_deal]:checked').val();

    if(selectedDeal == undefined) {
        selectedDeal = $('.user_criterias_form').find('[name=user_criterias_deal]:checked').val();
    }
    if(selectedDeal === 'RENT'){
        $('.price_period_wrapper').show();

        if($('.price_rent_wrapper').children().length &gt; 0){
            $('.price_sale_wrapper').hide();
            $('.price_rent_wrapper').show();
        }

        var slider = $('.user_criterias_filter:visible .price_rent_wrapper').find('.slider_js');
        if(slider.length &gt; 0){
            resetSliderValues(slider.attr('data-slider'), slider.attr('data-slider-steps'));
            sliders(slider);
        }
    }
    else{
        $('.price_period_wrapper').hide();

        if($('.price_rent_wrapper').children().length &gt; 0){
            $('.price_rent_wrapper').hide();
            $('.price_sale_wrapper').show();
        }
    }
}

function refresh_cms_agencies(parent) {
    let cms_agencies = $('.cms_agency_infos', parent);
    if (cms_agencies.length) {
        cms_agencies.each(function() {
            $(this).toggleClass('reduced', $(this).parent().width() &lt; 400)
        });
    }
}

//Check if the element is visible in the viewport
$.fn.isInViewport = function() {
    var elementTop = $(this).offset().top;
    var elementBottom = elementTop + $(this).outerHeight();

    var viewportTop = $(window).scrollTop();
    var viewportBottom = viewportTop + $(window).height();

    return elementBottom &gt; viewportTop &amp;&amp; elementTop &lt; viewportBottom;
};

function isInViewport(el) {
    var elementTop     = el.getBoundingClientRect().top;
    var elementBottom  = el.getBoundingClientRect().bottom;

    var viewportTop    = document.body.scrollTop;
    var viewportBottom = document.body.scrollTop + window.innerHeight;

    return elementBottom &gt; viewportTop &amp;&amp; elementTop &lt; viewportBottom;
}

$.fn.isCompletelyInViewport = function() {
    var elementTop = $(this).offset().top;
    var elementBottom = elementTop + $(this).outerHeight();

    var viewportTop = $(window).scrollTop();
    var viewportBottom = viewportTop + $(window).height();

    return elementTop &gt; viewportTop &amp;&amp; elementBottom &lt; viewportBottom;
};

function validateEmail(email) {
    var mailformat = /^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/;
    if (email.match(mailformat)) {
        return true;
    } else {
        return false;
    }
}

function validatePhone(phone) {
    var clean = phone.replace(/\D/g,'');
    var onlyNumbers = clean.match(/^[0-9]+$/);
    if (onlyNumbers &amp;&amp; clean.length &gt; 9) {
        return true;
    } else {
        return false;
    }
}

function updateTabAlert(el, opts = {}) {

    let pin    = el.find(".notification");
    let before = 0;

    if (pin.length == 0) {
        pin = $('&lt;span class="notification"&gt;&lt;/span&gt;');
        el.prepend(pin);
    } else {
        before = parseInt(pin.text());
    }

    let after = before;

    if (opts.set !== undefined) {
        after = opts.set;
    } else if(opts.diff !== undefined) {
        after = before + opts.diff;
    }

    if (after &lt; 0) {
        after = 0;
    }

    pin.text(after);

    if (after &gt; 0) {
        pin.removeClass('hide');
    } else {
        pin.addClass('hide');
    }
}

function updateMenuAlert(el, opts = {}) {

    let pin    = el.find(".notification");
    let before = 0;

    if (pin.length == 0) {
        pin = $('&lt;span class="notification"&gt;&lt;/span&gt;');
        el.append(pin);
    } else {
        before = parseInt(pin.text());
    }

    let after = before;

    if (opts.set !== undefined) {
        after = opts.set;
    } else if(opts.diff !== undefined) {
        after = before + opts.diff;
    }

    if (after &lt; 0) {
        after = 0;
    }

    pin.text(after);

    if (after &gt; 0) {
        pin.removeClass('hide');
    } else {
        pin.addClass('hide');
    }

    if (after != before) {
        if (!el.hasClass('login_icon')) {
            updateMenuAlert($(".menu_login.menu_top_part .login_icon"), {
                diff: after - before,
            })
        }
    }
}

var isIntegration = ((self.parent &amp;&amp; !(self.parent === self)) &amp;&amp; (self.parent.frames.length != 0));

function globalEvent(el, type, data) {
    // if it's an integration, we send the data to the parent website via postMessage
    //  otherwise we trigger some jquery event

    if (isIntegration) {
        var message = {
            type: type,
            data: data
        };

        window.top.postMessage(message, '*');
    } else {
        el.trigger(type, data);
    }
}

//normal foreach but for json object
function forEachObject(someObj, callback) {
    Object.entries(someObj).forEach((entry, ...rest) =&gt;
      callback(entry[0], entry[1], ...rest)
    )
}

function displayObjListSwiper(parent) {

}

function toArray (val) {
    if (Array.isArray(val)) {
        return val;
    } else {
        return [val];
    }
}

function checkConstraints(el, parentSelector = '') {
    var v = getValueFromInput(el);
    var constraints = triggerFields[el.attr('data-trigger-constraints')];
    for (var i = 0; i &lt; constraints.length; i++) {
        var constraint = constraints[i];
        var constraintMatch = false;
        switch (constraint.condition) {
            case 'empty':
                constraintMatch = v.length &lt; 1 || v === null;
                break;
            case 'notEmpty':
                if (Array.isArray(v)) {
                    constraintMatch = v.length &gt; 0 &amp;&amp; v !== null;
                } else {
                    constraintMatch = v !== 0 &amp;&amp; v !== null;
                }
                break;
            case 'in':
                v = toArray(v);
                v.every((val) =&gt; {
                    constraintMatch = constraint.arguments.includes(val);
                    if (constraintMatch) {
                        return false;
                    }
                    return true;
                });
                break;
            case 'notIn':
                if (v === null) {
                    constraintMatch = false;
                } else {
                    v = toArray(v);
                    v.every((val) =&gt; {
                        constraintMatch = !constraint.arguments.includes(val);
                        if (constraintMatch) {
                            return false;
                        }
                        return true;
                    });
                }
                break;
            case 'greaterThan':
                constraintMatch = v &gt; constraint.arguments;
                break;
            case 'greaterEqualThan':
                constraintMatch = v &gt;= constraint.arguments;
                break;
            case 'lowerThan':
                constraintMatch = v &lt; constraint.arguments;
                break;
            case 'lowerEqualThan':
                constraintMatch = v &lt;= constraint.arguments;
                break;
            default:
                break;
        }

        if (constraint.action == 'display' &amp;&amp; !constraintMatch) {
            hideElement(constraint.el);
        }

        if (constraint.action == 'display' &amp;&amp; constraintMatch) {
            displayElement(constraint.el);
        }

        if (constraint.action == 'require' &amp;&amp; constraintMatch) {
            requireElement(constraint.el);
        }

        if (constraint.action == 'require' &amp;&amp; !constraintMatch) {
            optionalElement(constraint.el);
        }
    }

    hideSectionWithHiddenElements(el.parents(parentSelector));
}

var updateFilterTimeout;

function hideSectionWithHiddenElements(parent) {};

function displayElement(el) {
    el.removeClass('hide');
    var section = el.parents('.form_part');
    section.removeClass('hide');
}

function unsetMultiSelectValues(multiselect) {
    multiselect.find('input[type=checkbox]').each(function() {
        $(this).prop('checked', false);
    });
    updateMultiSelect(multiselect);
}

function hideElement(el) {
    var find = false;
    el.addClass('hide');
    el.removeClass('success error');

    //reset multiselect;
    el.find('.multiselect_box').each(function(i,e) {
        unsetSelectValues($(e));
        unsetMultiSelectValues($(e));
        $(e).change();
        find = true;
    });

    //reset slider inputs;
    var sliders = el.find('.slider_js');
    sliders.each(function (e) {
        var slider = $(this);
        var sliderId = slider.attr('data-slider');
        var inputs = $('input[data-slider-input][data-slider=' + sliderId + ']', slider);
        inputs.val('');
        resetSliderValues(slider.attr('data-slider'), slider.attr('data-slider-steps'));
        updateSliderValues(slider.attr('data-slider'), slider.attr('data-slider-steps'), Number($('.slider_js[data-slider=' + sliderId + ']').attr('data-slider-limited-max')));
        inputs.change();
        find = true;
    });

    //autocomplete text 
    el.find('.filter_element_autocomplete').each(function(i,e) { 
        $(this).find('input').each(function (i, e) {
            $(e).val('').change();
        });
        find = true;
    });

    //reset other inputs
    if (!find) {
        el.find('input').each(function(i,e) {
            var type = $(e).attr('type');

            if (type == 'text' || type == 'tel') {
                $(e).val('').change();
            } else if (type == 'radio' || type == 'checkbox') {
                $(e).prop('checked', false).change();
            }
            
            // Remove validation state
            $(e).closest(".row_group").removeClass("success error");
        });
    }
}

function requireElement(el) {
    el.addClass('row_required');
    var l = $('.row_required:first .required_field', el).clone();
    el.find('label').append(l);
}

function optionalElement(el) {
    if (el.attr('data-default-required') == '0') {
        el.removeClass('row_required error');
        el.find('label .required_field').remove();
    }
}

function getValueFromInput(el) {
    var values = [];
    var inputName = el.attr('data-trigger-constraints');
    var checkedElements = el.find('input[name*="'+inputName+'"]:checked');
    checkedElements.each(function() {
        var val = $(this).val().split(',');
        if (Array.isArray(val) &amp;&amp; val.length &gt; 1) {
            if (isNumber(val[0])) {
                values = values.concat($(this).val().split(',').map(Number));
            } else {
                values = values.concat($(this).val().split(',').map(String));
            }
        } else {
            if (isNumber($(this).val())) {
                values.push(parseInt($(this).val()));
            } else {
                values.push($(this).val());
            }
        }
    });
    
    if (checkedElements.length &lt; 1) {
        var v = el.find('input[name*="'+inputName+'"]').val();

        if (isNumber(v)) {
            v = parseInt(v);
        }

        if (isNull(v)) {
            v = null;
        }

        if (typeof v == 'undefined') {
            return null;
        }

        return v;
    }

    return values;
}

function isNumber(n) { 
    return !isNaN(parseFloat(n)) &amp;&amp; !isNaN(n - 0);
}

function isNull(v) {
    return (v === 'NULL' || v === '' || v === null);
}
var ajaxVar;

function callAjax (url, data, type, abortPrev, extOpts) {
    if (type === undefined || !type) {
        type = 'get';
    }

    var opts = {
        url: url,
        data: data,
        type: type,
        beforeSend: function () {
            if (abortPrev &amp;&amp; ajaxVar !== null) {
                ajaxVar.abort();
            }
        },
    };

    ajaxVar = $.ajax($.extend(opts, extOpts));

    return ajaxVar;
}

function updateMultivaluedField(form, fieldName) {
    const $vaultInput = form.find(`input.${fieldName}_formatted`),
        $rows = form.find(`[data-field*="${fieldName}"]`);

    $vaultInput.val('');

    let values = [];

    $rows.each(function() {
        values.push($(this).find('input:not([type="hidden"])').val());
    });

    $vaultInput.val(values.join(','));
}

function generateMultivaluedField($controlInput, fieldName, fieldType = 'text', count = null) {
    const $firstRow = $('.row_' + fieldName).first(),
        $form = $controlInput.parents('form'),
        $vaultInput = $form.find(`input.${fieldName}_formatted`),
        name = $vaultInput.attr('name');

    if (isNull(count)) {
        count = $controlInput.val();

        $vaultInput.val('');
    }

    const vaultVal = $vaultInput.val() == '' ? '' : $vaultInput.val().split(',');

    if(count &gt; 0) {
        $firstRow.removeClass('hide');
        $form.find('.row_' + fieldName).remove();
    } else {
        $firstRow.addClass('hide');
        $firstRow.attr('data-field', name);
        $form.find('.row_' + fieldName).not(':first').remove();
    }

    for (let i = 0; i &lt; count; i++) {
        let $newRow = $firstRow.clone(),
            val = vaultVal ? vaultVal[i] : '',
            newName = name + '_' + i;

        $newRow.removeClass('success')
        $newRow.find('input[type="text"]').removeClass('not_empty')
        $newRow.find('input[type="text"]').addClass('empty')
        $newRow.find('input[type="hidden"]').attr('name', newName)
        $newRow.find('input[type="hidden"]').attr('id', newName)
        $newRow.find('input[type="text"]').attr('name', newName + '_formatted')
        $newRow.find('input[type="text"]').attr('id', newName + '_formatted')
        $newRow.find('input[type="text"]').attr('data-alt-field', newName)
        $newRow.find('label').attr('for', newName + '_formatted')
        $newRow.find('div.form_error_msg_box label').attr('for', newName)

        let $label = $newRow.find('label.placeholder'),
            $spanOptional = $label.find('.optional_field').clone();

        if($label &amp;&amp; $label.html()) {
            $label.find('.optional_field').remove();

            let labelHTML = $label.html().replace(/\d+/g, '') + ' ' + (i + 1);

            $label.html(labelHTML);
        }

        if ($spanOptional) {
            $label.text($label.text() + ' ');
            $label.append($spanOptional);
        }

        if (vaultVal != '' &amp;&amp; val) {
            $newRow.find('input[type="hidden"]').val(val)
            $newRow.find('input[type="text"]').val(val)
            $newRow.find('input[type="text"]').addClass('not_empty')
            $newRow.attr('data-field', newName)
        } else {
            $newRow.find('input[type="hidden"]').val('')
            $newRow.find('input[type="text"]').val('')
            $newRow.attr('data-field', name)
        }

        if (fieldType === 'date') {
            const date =  vaultVal != '' &amp;&amp; val ? new Date(parseDate(val)) : new Date();

            $newRow.find('input[type="text"]').attr('data-startdate', formatDate(date))
        }

        if ($form.find('.row_' + fieldName).length &gt; 0) {
            $newRow.insertAfter($form.find('.row_' + fieldName).last());
        } else {
            $newRow.insertAfter($controlInput.parents('.row'));
        }

        if (fieldType === 'date') {
            initDatePicker($newRow.find('input.datepicker-initialized.empty'));
        }

        $newRow.on('change', 'input', function() {
            setTimeout(() =&gt; {
                validateInput($(this));
            }, 100);

            if($(this).val() != '') {
                $(this).removeClass('empty').addClass('not_empty');
                $newRow.attr('data-field', newName)
            } else {
                $newRow.attr('data-field', name)
            }

            updateMultivaluedField($form, fieldName);
        });
    }
}

function animateKeyNumber(keyNumber) {
    countDone = 0;
    var contentNum = $('.cms_text_content span', keyNumber, parent);
    var cNumber = parseFloat(contentNum.text());
    var decimals = cNumber.toString().split(".")[1];

    var duration = keyNumber.attr('data-duration');
    var reverse = keyNumber.attr('data-reverse');

    if (decimals == undefined){
        var numDec = 0;
    } else {
        var numDec = decimals.length;
    }

    var from = 0;
    var to = contentNum.text();

    if(reverse == 1) {
        from = contentNum.text();
        to = 0;
    }

    $(window).on('load scroll', function() { 
        var elementTop = keyNumber.offset().top;
        var elementBottom = elementTop + keyNumber.outerHeight();
      
        var viewportTop = $(window).scrollTop();
        var viewportBottom = viewportTop + $(window).height();
        if( elementBottom &gt; viewportTop &amp;&amp; elementTop &lt; viewportBottom &amp;&amp; !keyNumber.hasClass('counted')){
            if($.isNumeric(cNumber)){
                contentNum.prop('Counter',from).animate({
                    Counter: to
                }, {
                    duration: duration * 1000,
                    easing: 'easeOutSine',
                    step: function (now) {
                        if (Number.isInteger(cNumber)){
                            contentNum.text(Math.ceil(now));
                        } else {
                            contentNum.text(now.toFixed(numDec));    
                        }
                    }
                    
                });
            }
            keyNumber.addClass('counted');
        }
    });
}
function launchNumberAnimation(parent){
    if ($('.container_counter', parent).length){
        $( ".container_counter", parent ).each(function() {
            animateKeyNumber($(this), parent);
        });
    }
}

function getCookie(name) {
    let cookieArr = document.cookie.split(";");

    for(let i = 0; i &lt; cookieArr.length; i++) {
        let cookiePair = cookieArr[i].split("=");

        if(name === cookiePair[0].trim()) {
            return decodeURIComponent(cookiePair[1]);
        }
    }
    return null;
}

function debounce(func, delay) {
    let timer;
    return function(...args) {
        const context = this;
        clearTimeout(timer);
        timer = setTimeout(() =&gt; {
            func.apply(context, args);
        }, delay);
    };
}

function threeDotsText(parent, isMapOpen) {
    const windowWidth = $(window).width();

    // Check if the passed parent is a single item or a container
    const thumbnailItems = $(parent).hasClass('box_object_thumbnail_item') ? $(parent) : $('.box_object_thumbnail_item', parent);
    const horizontalItems = $(parent).hasClass('box_object_horizontal_item') ? $(parent) : $('.box_object_horizontal_item', parent);

    // Process thumbnail items if they exist
    if (thumbnailItems.length) {
        thumbnailItems.each(function () {
            resetObjectCardAttributes($(this));
        });
        thumbnailItems.each(function () {
            processObjectCard($(this), 'thumbnail');
        });
    }

    // Process horizontal items if they exist
    if (horizontalItems.length) {
        horizontalItems.each(function () {
            resetObjectCardAttributes($(this));
        });

        if (isMapOpen) {
            // Process items with map open
            horizontalItems.each(function () {
                if (windowWidth &lt;= 1800) {
                    processObjectCard($(this), 'thumbnail');
                } else {
                    processObjectCard($(this), 'horizontal');
                }
            });
        } else {
            // Process itmes with map closed
            horizontalItems.each(function () {
                if (windowWidth &lt;= 900) {
                    processObjectCard($(this), 'thumbnail');
                } else {
                    processObjectCard($(this), 'horizontal');
                }
            });
        }
    }
}

function resetObjectCardAttributes($item) {
    const $titleDescription = $item.find('.title_and_description_wrapper');
    const $boxBody = $item.find('.box_body');

    updateTitleDescriptionClass($titleDescription, 'initial-height');
    $boxBody.attr('style', `max-height: unset`);
}

function processObjectCard($item, type) {
    const $boxBody = $item.find('.box_body');
    const $topInfos = $item.find('.top_infos');
    const $titleDescription = $item.find('.title_and_description_wrapper');
    const $title = $item.find('.title');
    const $description = $item.find('.description');
    const $premiumSection = $item.find('.advertiser_details_wrapper');
    
    // Calculate common elements' height
    const topInfosHeight = getElementHeight($topInfos);
    const titleHeight = getElementHeight($title);
    const premiumSectionHeight = getElementHeight($premiumSection);
    const { paddingTop, paddingBottom } = getElementTopBottomPadding($boxBody);
    
    // Get description's line height
    const descriptionLineHeight = $description.length ? parseFloat($description.css('line-height')) : 0;
    
    if (type === 'thumbnail') {
        const boxBodyHeight = getElementHeight($boxBody);
        const titleDescriptionHeight = getElementHeight($titleDescription);
        
        // Calculate available space for thumbnail items
        const availableSpace = boxBodyHeight - paddingTop - topInfosHeight - paddingBottom - premiumSectionHeight;
        
        if (availableSpace &gt; titleDescriptionHeight) {
            // The title description container has space to grow so expand it
            updateTitleDescriptionClass($titleDescription, 'full-height');
        }
        
        const descriptionMaxLines = availableSpace &gt; 0 &amp;&amp; descriptionLineHeight &gt; 0 ? Math.floor((availableSpace - titleHeight) / descriptionLineHeight) : 0;
        
        applyDescriptionStyles($description, descriptionLineHeight, descriptionMaxLines);
        updateTitleDescriptionClass($titleDescription, 'min-content');
        
    } else if (type === 'horizontal') {
        const $pictureGroup = $item.find('.box_picture_group');
        const pictureGroupHeight = getElementHeight($pictureGroup);
        
        if ($boxBody.length) {
            $boxBody.attr('style', `max-height: ${pictureGroupHeight}px`);
        }
        
        // Calculate available space for horizontal items
        const availableSpace = pictureGroupHeight - paddingTop - topInfosHeight - titleHeight - paddingBottom - premiumSectionHeight;
        
        // Calculate maximum lines 
        const descriptionMaxLines = availableSpace &gt; 0 &amp;&amp; descriptionLineHeight &gt; 0 ? Math.floor(availableSpace / descriptionLineHeight) : 0;
        
        applyDescriptionStyles($description, descriptionLineHeight, descriptionMaxLines);
        updateTitleDescriptionClass($titleDescription, 'min-content');
    }
}

function applyDescriptionStyles($el, lineHeight, maxLines) {
    if ($el.length) {
        $el.attr('style', `-webkit-line-clamp: ${maxLines}; line-clamp: ${maxLines}; height: 100%; max-height: ${lineHeight * maxLines}px`)
    }
}

function updateTitleDescriptionClass($element, newClass) {
    $element.removeClass('initial-height min-content full-height').addClass(newClass);
}

function getElementHeight($el) {
    return $el.length ? $el.innerHeight() : 0;
}

function getElementTopBottomPadding($el) {
    if ($el.length) {
        const styles = getComputedStyle($el[0]);
        return {
            paddingTop: parseFloat(styles.paddingTop) || 0,
            paddingBottom: parseFloat(styles.paddingBottom) || 0
        };
    }
    return { paddingTop: 0, paddingBottom: 0}
}

function handleThreeDotsText(parent) {
    const isMapOpen = checkIsMapOpen();
    threeDotsText(parent, isMapOpen);
}

function checkIsMapOpen() {
    // Check the cookies to know if the map is open
    const navId = $('#search_results').attr('data-nav-id');
    const mapState = getCookie('mapState-' + navId);

    if (mapState === 'open') {
        return true
    } else if (mapState === 'closed') {
        return false
    } else {
        return false
    }
}

var updatePreviewFilters = function(pv, filter, targetedFilters) {
    var preview = '';
    targetedFilters.each(function(){
        var cb = $(this);
        
        if (cb.is(':checked')) {
            var prefix = cb.parents('.filter_element').attr('data-preview-prefix') ?? '';
            if (preview != '') {
                preview += ', ';
            }
            if (cb.parent().hasClass('select_default_value')) {
                preview += '';
            } else {
                preview += '&lt;span class="prefix"&gt;' + prefix + '&lt;/span&gt; ' + cb.siblings('.label_text').html();
            }
        }
        $(cb).on('click', function () {
            $(this).parents('.cms_objects_filter .filter_fields').find('input.filter_display').prop('checked', false);
        })
    });

    if (targetedFilters.length &amp;&amp; preview != '') {
        pv.html(preview).removeClass('hide');
        pv.parents('.filter_preview').removeClass('hide');
    } else {
        pv.html('').addClass('hide');
        if (pv.parents('.filter_preview').length &amp;&amp; pv.siblings('hide').length) {
            pv.parents('.filter_preview').addClass('hide');
        }
    }
}

var previewFilters = function(target) {
    if (target.length) {
        target.each(function(){
            var pv = $(this);
            var filter = pv.attr('data-filter-preview');
            var targetedFilters = $('input[type=radio]:not([type=hidden])', pv.parents('.filter_part').find('.filter_fields'));
            
            pv.each(function(){
                updatePreviewFilters($(this), filter, targetedFilters);
            });

            targetedFilters.on('click change keyup', function(){
                updatePreviewFilters(pv, filter, targetedFilters);
            });
        });
    }
}
/* /websites/base/js/base.js */
/* Global variables used by various functions */
var lang = document.getElementsByTagName("html")[0].getAttribute("lang");

var isIntegration = ((self.parent &amp;&amp; !(self.parent === self)) &amp;&amp; (self.parent.frames.length != 0));
var triggerFields = [];

var isTouchScreenDevice = false;
var timeoutIframeSendContentSize = null;

try {
    document.createEvent("TouchEvent");
    isTouchScreenDevice = true;
} catch (e) { }


registerScriptLoader(function (parent) {
    $('.login_popup_login_content form:not(.oak_forgot_login_form), .login_content .login_box form', parent).submit(function(e) {
        e.preventDefault();

        var form = $(this);
        var loginBox = form.closest('.login_box');

        var messagesTarget = $('.global_messages', parent);
        if (loginBox.find('.login_popup_messages_content .popup_part').length) {
            messagesTarget = loginBox.find('.login_popup_messages_content .popup_part');
        }
        var isInPopup = $('.login_popup_wrapper', parent).length &gt; 0;
        
        submitAjaxForm(form, {
            onMessages: function (res) {
                if (res.messages.length) {
                    messagesTarget.removeClass('hide');
                    displayMessages(messagesTarget, res.messages);

                    loginBox.addClass('messages_box');
                }
            },
            onSuccess: function (res) {
                if (res.redirect) {
                    if (res.redirect.indexOf('.pdf') !== -1 &amp;&amp; isInPopup) {
                        // open pdf in new tab after login

                        var pdf_content = $('.login_popup_pdf_download_content', parent);
                        

                        pdf_content.find(".messages p").html(res.message);
                        pdf_content.find(".messages a").attr("href", res.redirect);

                        pdf_content.find(".messages a").click(function (){
                            $.magnificPopup.close();
                            
                            if (res.redirect) {
                                setTimeout(function () {
                                    location.reload();
                                }, 1000);
                            }
                        });

                        $('.login_popup_login_content', parent).remove();
                        pdf_content.show();
                    } else {
                        location.href = res.redirect;
                    }
                } else {
                    location.reload();
                }
            },
            onError: function(res) {
                $("#login_password", form).val("");
            }
        });
    });

    $('.register_form_box .button[type="submit"]', parent).on('click', function(){
        window.location.hash = '';
    });

    $('.login_popup_register_content form, .login_popup_forgot_content form', parent).submit(function(e) {
        e.preventDefault();

        var form = $(this);
        var loginBox = form.closest('.login_box');

        submitAjaxForm(form, {
            onMessages: function(res) {
                if (res.messages.length) {
                    displayMessages(loginBox.find('.login_popup_messages_content .messages'), res.messages);

                    loginBox.addClass('messages_box');
                }
            },
            onSuccess: function (res) {
                if (res.redirect) {
                    location.href = res.redirect;
                } else {
                    location.reload();
                }
            },
        });
    });
    $(".user_activation_form_wrapper .forgot_password", parent).click(function(){
        if ($('.login_popup_forgot', parent).is(':hidden') || $('.login_popup_forgot', parent).hasClass('hide')) {
            $('.login_popup_forgot', parent).removeClass('hide');
        } else {
            $('.login_popup_forgot', parent).addClass('hide');
        }
    });

    $("form.user_forgotten_form", parent).submit(function(e) {
        e.preventDefault();
        var form = $(this);

        submitAjaxForm($(this), {
            onSuccess: function(res) {
                window.location = _rr.UserAuth.profile(lang)
            },
        });

        return false;
    });

    $("form.terms_form", parent).submit(function(e) {
        e.preventDefault();

        submitAjaxForm($(this), {
            onSuccess: function (res) {
                window.location.reload();
            }
        });
        
        return false;
    });

    $('form.user_profile_form', parent).submit(function (e) {
        e.preventDefault();
        
        submitAjaxForm($(this), {
            onSuccess: function (res) {
                setTimeout(function () {
                    window.location.reload();
                }, 2000);
            }
        });
        
        return false;
    });

    $('form.mandatory_visit_form', parent).submit(function (e) {
        e.preventDefault();
        
        submitAjaxForm($(this), {
            onSuccess: function (res) {
                $.magnificPopup.close();
                
                if (res.redirect) {
                    setTimeout(function () {
                        window.location = res.redirect;
                    }, 2000);
                }
            }
        });
        
        return false;
    });

    $("form.ajax_form", parent).submit(function(e) {
        e.preventDefault();
        var form = $(this);
        if (form.is('.contact_form, .visit_form, .mortgage_form, .concierge_report_form')) {
            var messagesTarget = form.siblings('.messages').length &gt; 0 ? form.siblings('.messages') : undefined;
        } else {
            var messagesTarget = undefined;
        }

        submitAjaxForm($(this), {
            messagesTarget: messagesTarget,
            onSuccess: function(res) {
                var form_hide = form.closest(".hide_form");
                if (form_hide.length) {
                    form_hide.addClass("hide");
                }

                if (res.redirect) {
                    setTimeout(function () {
                        window.location = res.redirect;
                    }, 2000);
                } else {

                    goTo(form_hide, 600, 'swing');
                }
            }
        });

        return false;
    });

    $("a.pdf_button_login", parent).click(function() {
        $("a.login_icon.magnific-popup").attr('open-pdf', 1);
        $("a.login_icon.magnific-popup").magnificPopup('open');
    });

    enableDisplaysToggles(parent);
    enableRequiresToggles(parent);


    $('.object_edit_form form', parent).submit(function(e) {
        e.preventDefault();

        var form = $(this);

        submitAjaxForm(form, {
            onSuccess: function(res) {
                setTimeout(function() {
                    $("a.magnific-popup").magnificPopup('close');
                }, 1000);
            },
        });
    });

    $('input[type=checkbox].checkall_element', parent).click(function(){
        var multiselect = $(this).attr('data-checklimit');
        var prop = $(this).prop('checked');

        $(multiselect).find('input[type=checkbox]').prop('checked', prop);
    });

    $('.multiselect_box', parent).each(function(){
        var multiselect = $(this);
        if(multiselect.find('.checkall_element').length &gt; 0){
            multiselect.find('input[type=checkbox]').each(function(){
                $(this).change(function(){
                    if($(this).prop('checked') == false){
                        multiselect.find('.checkall_element').prop('checked', false);
                    }
                });
            });
        }
    });

    // Show/hide password
    $(".toggle-password", parent).click(function() {
        var input = $(this).parent().find("input[type='password']");
        if (input.attr("type") == "password") {
            input.attr("type", "text");
            $(this).removeClass('show_password_icon');
            $(this).addClass('hide_password_icon');

        } else {
            var input = $(this).parent().find("input[type='text']");
            input.attr("type", "password");
            $(this).addClass('show_password_icon');
            $(this).removeClass('hide_password_icon');
        }
    });

    setTimeout(function() {
        $(".global_messages", parent).addClass('hide');
    }, 10000);

    // Cookies popup
    $('a.cookies_popup_close', parent).click(function(){
        var allow_cookies = $('input[name=allow_cookies]:checked', parent).val();

        createCookie('cookies_popup', allow_cookies, 3600 * 24 * 365);
        location.reload();
    });
    $('a.modify_cookies_button', parent).click(function(){
        createCookie('cookies_popup', null, null);
        location.reload();
    });

    var searchParams = new URLSearchParams(window.location.search);
    var objectId = searchParams.get('object_id');
    var $infiniteScroll = $('.infinite_scroll', parent);
    var scrolled = $infiniteScroll.attr('data-scrolled');
    var infiniteScrollActive = $infiniteScroll.attr('data-active');
    var timeout = infiniteScrollActive ? 800 : 0;
    if (objectId &amp;&amp; (scrolled !== '1')) {
        setTimeout(function () {
            goTo('article[data-object-id=' + objectId + ']', 600, 'swing');
        }, timeout);
    }

    // check list style
    $('.section.section_object', parent).each(function () {
        var self = $(this);
        var selectedView;

        if (self.attr('data-nav-id')) {
            selectedView = readCookie('view-' + self.attr('data-nav-id'));
        } else {
            selectedView = readCookie('view-' + self.attr('data-component-id'));
        }

        if (!selectedView) {
            var resultsList = $(".search_results_list .list_container", parent);
            selectedView = resultsList.attr('data-list-style');
        }

        let forceSearch = true;
        if(objectId) {
            forceSearch = false;
        }

        self.find('.search_tools [data-list-style="' + selectedView + '"]').trigger('click', {'forceSearch': forceSearch});
    });

    $('a.box_inner_link[data-type="object_link"]', parent).on('click', function(e){
        var removeObjectsQueryString = $('input[name="objects_remove_query_string"]').val() ?? 0;
        if (removeObjectsQueryString == 1) {
            // normal click process
        } else {
            e.preventDefault();
            var href = $(this).attr("href");
            var page = $('input[type="hidden"][name="page"]').val();
            var target = $(this).attr("target");
    
            if(!target) {
                target = '_self';
            }
            
            if(!page){
                page = 1;
            }
            
            var delimiter = '&amp;';
            if (href.indexOf('?') &lt; 0) {
                delimiter = '?';
            }
            
            if(!window.open(href + delimiter + 'page=' + page, target)) {
                location.href = href + delimiter + 'page=' + page;
            }
        }
    });

    // disable images right click
    $('body:not(.enable_right_click)').on('contextmenu', 'img, picture, div.slider_external_embed, div.virtual_thumbnail, figure img, video', function(e){
        return false;
    });

    refresh_cms_agencies(parent);
    
    $(window).on('resize', function() {
        refresh_cms_agencies(parent);
    });

    prepareLazySwiper(parent);
    recursiveSwiper(parent);
    customSwiper(parent);
      
    if (isIntegration &amp;&amp; $('body', parent).length) {
        var pathname = location.pathname;
        if ($('.overrideFragment_with_params', parent).length) {
            pathname += window.location.search;
        }
        globalEvent(null, 'overrideFragment', { 'pathname' : pathname, 'enabled' : $('.overrideFragment', parent).length});

        // listener from host message
        window.addEventListener("message", listenMessage, false);

        var sendSizeToParentWindow = function (e) {
            clearTimeout(timeoutIframeSendContentSize);
            globalEvent(null, 'contentSize', {
                'width' : $('body').innerWidth(),
                'height': $('body').innerHeight(),
            });
        };

        if ('IntersectionObserver' in window) {
            var resizeObserver = new ResizeObserver(sendSizeToParentWindow);
            resizeObserver.observe(document.getElementById("global"));
        } else {
            $(window).on('resize', sendSizeToParentWindow);
        }
    }

    // get all fields with constraints and group them by conditional field
    $('[data-filter-constraints]', parent).each(function (i, el) {
        var $this = $(el);
        var constraints = JSON.parse($this.attr('data-filter-constraints'));
        if (constraints) {
            for (var i = 0; i &lt; constraints.length; i++) {
                var c = constraints[i];
                var key = c.condition_filter;
                if (typeof triggerFields[key] == 'undefined') {
                    triggerFields[key] = [];
                }
                c.el = $this;
                triggerFields[key].push(c);
                $('[data-filter-ident$="'+c.condition_filter+'"]', parent).attr('data-trigger-constraints', key);
            }
        }
    });

    $('.objects_filters [data-trigger-constraints]', parent).each(function () {
        checkConstraints($(this));
    });

    var constraints = $('.objects_filters [data-trigger-constraints]', parent);
    constraints.each(function () {
        var name = $(this).attr('data-trigger-constraints');
        $('.objects_filters [data-trigger-constraints] input[name*="'+name+'"]').on('change', function (e) {
            checkConstraints($(this).parents('[data-trigger-constraints]'));
        });
    });

    // Mandatory visit popup form
    $('form.mandatory_visit_form', parent).find('.row_visit_date').addClass('hide');
    $('form.mandatory_visit_form', parent).find('.row_visit_with').addClass('hide');

    $('form.mandatory_visit_form [name=already_visited]', parent).change(function() {
        let val = $(this).val();

        if(val == 1) {
            $('form.mandatory_visit_form', parent).find('.button_visit').addClass('hide');
            $('form.mandatory_visit_form', parent).find('.button_continue').removeClass('hide');
            $('form.mandatory_visit_form', parent).find('.row_visit_date').removeClass('hide');
            $('form.mandatory_visit_form', parent).find('.row_visit_with').removeClass('hide');
        } else {
            $('form.mandatory_visit_form', parent).find('.button_visit').removeClass('hide');

            if(!$('form.mandatory_visit_form', parent).find('.row_visit_date').hasClass('hide')) {
                $('form.mandatory_visit_form', parent).find('.row_visit_date').addClass('hide');
            }
            if(!$('form.mandatory_visit_form', parent).find('.row_visit_with').hasClass('hide')) {
                $('form.mandatory_visit_form', parent).find('.row_visit_with').addClass('hide');
            }
            if(!$('form.mandatory_visit_form', parent).find('.button_continue').hasClass('hide')) {
                $('form.mandatory_visit_form', parent).find('.button_continue').addClass('hide');
            }
        }
    });

    $('form.mandatory_visit_code_form .mandatory_visit_no_code', parent).click(function() {
        $('form.mandatory_visit_code_form').addClass('hide');
        $('.mandatory_visit_form').removeClass('hide');
    });

    $('form.mandatory_visit_code_form', parent).submit(function (e) {
        e.preventDefault();

        var form = $(this);
        var messagesTarget = form.find('.messages');
        var loginBox = form.closest('.login_box');

        submitAjaxForm($(this), {
            onMessages: function (res) {
                if (res.messages.length) {
                    messagesTarget.removeClass('hide');
                    displayMessages(messagesTarget, res.messages);

                    loginBox.addClass('messages_box');
                }
            },
            onSuccess: function (res) {
                $.magnificPopup.close();
                
                if (res.success) {
                    window.location = res.redirect;
                }
            }
        });
        
        return false;
    });
    // alert button redirections
    $('.create_alert', parent).on('click', function(){
        var user = $(this).attr("data-user");
        var alert_url_params = "?alert=1&amp;";

        if(location.search == false) {
            if($('.nav_item.sale').hasClass('selected')){
                var deal = 'sale';
            }
            if($('.nav_item.rent').hasClass('selected')){
                var deal = 'rent';
            }
            alert_url_params += "deal=" + deal;
        }
        if(user == 'user') {
            $(this).attr('href', _rr.UserAuth.criterias(lang) + alert_url_params  + location.search.replace('?', '') );
        } else {
            $(this).attr('href', _rr.Login.loginPopup(lang) + alert_url_params + location.search.replace('?', ''));
        }
    });

    profileManageMenu(parent);

    archivePopup(parent);

    mapReloadButtonPosition(parent);

    $('.filter_tab.tab ', parent).click(function () {
        var selected_tab = $(this).attr("data-tab-content");    
        createCookie('filter_tab_selected', selected_tab, 3600 * 24 * 365);
        setTimeout(() =&gt; {
            handleThreeDotsText(parent);
        }, 0);
    });

    $('.filter_tab.tab ', parent).each(function () {
        if ($('.filter_tab.selected').length &gt; 0) {
            return false;
        }

        selected_tab = readCookie('filter_tab_selected');
        if (selected_tab == null) {
            selected_tab = '.user_selection_list_0';
        }
        $(this).siblings('.tab').removeClass('selected');
        $('[data-tab-content="' + selected_tab + '"]').addClass('selected');
        $(selected_tab).removeClass('hide');
        $(selected_tab).siblings('.user_result_list').addClass('hide')
    });
});

function mapReloadButtonPosition(parent) {
    let _parent = parent[0];
    const header = _parent.querySelector('header');
    const fixed_map_header =  _parent.querySelector('.fixed_map_top_container');
    const map =  _parent.querySelector('#results_map');

    if (fixed_map_header) {
        const initialMargin = parseInt(getComputedStyle(fixed_map_header).top);
        const checkIntersection = () =&gt; {
                if (header) {
                    const headerHeight = getHeaderHeightForMapReloadPosition(_parent);
                    const mapRect = map.getBoundingClientRect();
                    if (header.classList.contains('scrollUp')) {
                        if (headerHeight &gt; mapRect.top) {
                            const diff = headerHeight - mapRect.top + initialMargin;
                            fixed_map_header.style.top = diff+'px';
                        } else {
                            fixed_map_header.style.top = initialMargin + 'px';
                        }
                    } else {
                        fixed_map_header.style.top = initialMargin + 'px';
                    }
                }
        };
    
        window.addEventListener('scroll', checkIntersection);
        window.addEventListener('resize', checkIntersection);
    }
}

function getHeaderHeightForMapReloadPosition (parent) {
    return parent.querySelector('header').getBoundingClientRect().height;
} 

function archivePopup(parent) {
    $('.user_archive_button').magnificPopup({
        type:'inline',
        midClick: true
    });
    $('#archive_confirm_popup .user_archive_button_negative', parent).on('click', function () {
        $(this).parents('#archive_confirm_popup').magnificPopup('close');
    });
}

function profileManageMenu(parent) {
    const $itemsWithSubmenu = $('.profile_manage_menu .menu_item.with_submenu', parent);

    $itemsWithSubmenu.on('click', function () {
        const $submenu = $(this).next('.submenu');
        const marginTop = $(this).height() * (-1);
        const marginLeft = $(this).width() + 10;

        $submenu.css('margin-top', marginTop + 'px');
        $submenu.css('margin-left', marginLeft + 'px');
        $submenu.show();
    });

    $(parent).click(function(event) {
        const $submenu = $('.profile_manage_menu .submenu');

        $submenu.click(function(event) {
            event.stopPropagation();
        });

        if (!$(event.target).closest($submenu).length
            &amp;&amp; !$(event.target).is($itemsWithSubmenu)
        ) {
            $submenu.hide();
        }
    });

    $('.submenu_item_button').magnificPopup({
        type:'inline',
        midClick: true
    });

    $('.profile_manage_menu_popup .button_negative', parent).on('click', function () {
        $(this).parents('.profile_manage_menu_popup').magnificPopup('close');
        $('.profile_manage_menu .submenu').hide();
    });

    $(
        '#profile_request_data_download_confirm_popup .button_positive, ' +
        '#profile_request_data_delete_confirm_popup .button_positive',
        parent
    ).on('click', function () {
        $.post({
            url: _rr.UserAuth.profileDataProtectionRequest($(this).data('lang'), $(this).data('type_id')),
            success: function() {
                location.reload();
            },
        });
    });
}

jQuery.cachedScript = function( url, options ) {
 
    // Allow user to set any option except for dataType, cache, and url
    options = $.extend( options || {}, {
      dataType: "script",
      cache: true,
      url: url
    });
   
    // Use $.ajax() since it is more flexible than $.getScript
    // Return the jqXHR object so we can chain callbacks
    return jQuery.ajax( options );
};

function listenMessage(msg) {
    if (typeof msg.data == 'object' &amp;&amp; 'type' in msg.data) {
        var data = msg.data.data;
        var type = msg.data.type;

        if (type == 'viewportSize') {
            window.dataHost = data;
            if (data.event == 'resize') {
                $('.mfp-wrap', $('body')).resize();
            }
        } else if (type == 'hostUrl') {
            window.dataHostUrl = data.url;
            $("input[name=profile_integration_parent]").val(window.dataHostUrl)
        }
    }
}

function prepareLazySwiper(parent) {
    $('.swiper', parent).each(function() {
        swiper = $(this);
        var img = $('img', swiper);
        img.each(function () {
            if (window[swiper.attr('data-base-options-swiper')]['lazy'] == false) {
                $(this).attr('srcset', $(this).attr('data-srcset')).removeAttr('data-srcset');
                $(this).attr('src', $(this).attr('data-src')).removeAttr('data-src');
                $(this).removeClass('swiper-lazy');
                $(this).parent().find('.swiper-lazy-preloader').remove();
            }
            if ($(this).is('[href]')) {
                $(this).parent().attr('href', $(this).attr('href'));
                $(this).removeAttr('href');
                $(this).parent().addClass('item');
                $(this).removeClass('item');
            }
        });
    });
}

function recursiveSwiper(parent) {
    $('.swiper:not(.swiper_custom)', parent).each(function () {
        var $this = $(this);
        if ($this.hasClass('swiper-initialized') || $this.parents('.swiper_custom').length) {
            return;
        }

        // hack (swiper)
        // Freeze/unfreeze lazy loading of images for nested sliders.
        // If we don't do this, not all images in the nested sliders will be processed correctly.
        // see t214962#15

        // freeze
        $('.swiper .swiper-slide img', $this).each(function () {
            var $self = $(this);
            if ($self.hasClass('swiper-lazy')) {
                $self.addClass('swiper-lazy-hold');
                $self.removeClass('swiper-lazy');
            }
        });

        setupSwiper($this, $this.hasClass('swiper_cms'));

        // unfreeze
        $('.swiper .swiper-slide img', $this).each(function () {
            var $self = $(this);
            if ($self.hasClass('swiper-lazy-hold')) {
                $self.addClass('swiper-lazy');
                $self.removeClass('swiper-lazy-hold');
            }
        });

        if ($this.find('.swiper').length &gt; 0) {
            recursiveSwiper($this);
        }
    });
}

function customSwiper(parent) {
    var thumbs = $('.swiper_thumbs', parent);
    if (thumbs.length) {
        thumbs.each(function () {
            var nb_slides = parseInt($(this).attr('data-nslides'));
            var swiperOptionsName = $(this).attr('data-base-options-swiper');
            var swiperOptions = window[swiperOptionsName];
            var options = {};
            if (swiperOptions['slidesPerView'] !== undefined &amp;&amp; swiperOptions['slidesPerView'] == 'all') {
                options['slidesPerView'] = nb_slides;
                options['thumbsMode'] = 'all';
            } else {
                options['thumbsMode'] = 'slider';
            }
            if (swiperOptions['breakpoints'] !== undefined) {
                Object.assign(options, {
                    breakpoints: swiperOptions['breakpoints']
                });
                forEachObject(options['breakpoints'], (key, value) =&gt; {
                    if (value['slidesPerView'] == 'all') {
                        value['slidesPerView'] = nb_slides;
                        value['thumbsMode'] = 'all';
                    } else {
                        value['thumbsMode'] = 'slider';
                    }
                });
            }

            swiperCarousel($(this), extendOptions(swiperOptThumbs, options, $(this), 'swiper'), false);
        });
    }

    if ($('.detail_page_banner, .picture_slider', parent).length) {
        $('.detail_page_banner, .picture_slider', parent).each(function () {
            var swiper_el = $(this).find('.swiper_pictures_slider');
            if(swiper_el.length) {
                var options = {};
                var swiper_thumbs_el = $(this).find('.swiper_thumbs');
                if (swiper_thumbs_el.length) {
                    var swiper_thumbs = swiper_thumbs_el[0].swiper;
                    options = {
                        thumbs: {
                            swiper: swiper_thumbs,
                        }
                    };
                }
                swiperCarousel(swiper_el, extendOptions(swiperOptBase, options, swiper_el, 'swiper'), false);
            }
        });
    }
}

/* ----- Swiper Carousel ----- */
function setupSwiper (swiper, isCMS) {
    if (isCMS) {
        var baseOptName = swiper.attr('data-base-options-swiper');
        var addOpt = swiper.data();
        var autoPlay = swiper.attr('data-swiper-autoplay');
        var pauseMouseHover = swiper.attr('data-swiper-autoplay-hover-pause');

        if (pauseMouseHover == null){
            pauseMouseHover = false;
        }
        if (baseOptName == null){
            baseOptName = "swiperCmsOptBase";
        };
        var effectiveOptName = baseOptName;
        var effectiveOpt = window[effectiveOptName];

        var options = {};
        $.each(addOpt, function (key, val) {
            if (key == 'swiperDots') {
                if (val == 1) {
                    var opt_el = effectiveOpt.pagination?.el ?? '.swiper-cms-pagination';
                    var opt_type = effectiveOpt.pagination?.type ?? 'bullets';
                    var opt_clickable = effectiveOpt.pagination?.clickable ?? true;
                    options.pagination = {
                        el: opt_el,
                        type: opt_type,
                        clickable: opt_clickable,
                    };
                } else {
                    if (effectiveOpt['pagination'] !== undefined) {
                        options.pagination = {};
                    }
                }
            } else if (key == 'swiperNav' &amp;&amp; val == 1) {
                options.navigation = {
                    nextEl: swiper.children('.swiper-cms-button-next')[0],
                    prevEl: swiper.children('.swiper-cms-button-prev')[0]
                };
            } else if (key == 'swiperMouseDrag' &amp;&amp; val == 0){
                options.allowTouchMove = false;
            } else if (effectiveOpt['slidesPerView'] == 1 &amp;&amp; val == 'fade'){
                options.effect = 'fade';
                options.fadeEffect = {
                    crossFade: true
                };
            } else if (key == 'swiperAutoplayTimeout' &amp;&amp; autoPlay == 1){
                options.autoplay = {
                    delay: val,
                    disableOnInteraction: false,
                    pauseOnMouseEnter: pauseMouseHover
                };
            } else if (key == 'swiperMargin'){
                options.spaceBetween = effectiveOpt['spaceBetween'] !== undefined ? effectiveOpt['spaceBetween'] : val;
                if (effectiveOpt['breakpoints'] !== undefined) {
                    options.breakpoints = JSON.parse(JSON.stringify(effectiveOpt['breakpoints']));
                    forEachObject(options.breakpoints, (key, value) =&gt;
                        value.spaceBetween = value.spaceBetween !== undefined ? value.spaceBetween : val
                    );
                }
            } else if (key == 'swiperAlignment'){
                var isCentered = true;
                if (val == 'left') {
                    isCentered = false;
                }
                options.centeredSlides = isCentered;
            } else if (key == 'swiperLoop'){
                var isLoop = false;
                var isRewind = false
                if (val == 'loop') {
                    isLoop = true;
                } else if (val == 'rewind') {
                    isRewind = true;
                }
                options.loop = isLoop;
                options.rewind = isRewind;
            }
        });
        swiperCarousel(swiper, extendOptions(effectiveOpt, options), isCMS);
    } else {
        swiperCarousel(swiper, extendOptions(swiperOptBase, {}, swiper, 'swiper'), isCMS);
    }
}

/*----- Main function -----*/
$(function() {


    $("button.delete_filter").click(function(e) {
        e.preventDefault();

        var btn = $(this);

        startLoading(btn.closest("form"));

        $.post({
            url: _rr.UserAuth.criteriasDelete(lang, btn.attr("data-criteria")),
            success: function(data) {
                window.location.reload()
            },
        });

    });

    $("form.potential_object_form").each(function() {
        var form = $(this);

        initSearchField($("input.autocomplete", form), {
            url: _rr.Search.localities(lang, '%q'),
        });
    });


    $("form.user_criterias_form").each(function() {
        var form = $(this);

        $("input.cat_cb", form).change(function() {
            if($(this).is(":checked")) {
                if(!$(this).parent().find(".row.row_subcat").hasClass("no_error")) {
                    $(this).parent().find(".row.row_subcat").addClass("no_error")
                } 
            } else {
                var defaultLabel = $(this).parent().find('.multiselect_box').attr('data-defaultlabel');
                var selectTitle = $(this).parent().find('.multiselect_title');
                $(this).parent().find("input[name='user_criterias_categories[]']").prop('checked', false);
                selectTitle.html(defaultLabel);
            }
        });

        $(".row_locations_included, .row_locations_excluded", form).each(function() {
            var row = $(this);

            var list = row.next();

            $(".results_list .remove", list).click(function() {
                $(this).closest("li").remove();
            });

            $(".input_radius input", row).on('change', function () {
                if ($(this).val() &lt; 0) {
                    $(this).val(0);
                }
            })

            $(".button_ajax_add_list", row).click(function(e) {
                e.preventDefault();

                var text = $("input.autocomplete", row).val();
                var id = $($("input.autocomplete", row).attr("data-field-value")).val();
                var radius = parseInt($(".input_radius input", row).val());

                if (isNaN(radius) || radius &lt; 0) {
                    radius = 0;
                }

                // checking if a locality exists to avoid being displayed twice
                let can_add = true;
                let pattern = parseInt(id)
                let input_name = $("li.results_list_template", list).find("input[data-tpl='location']").attr('name');
                let result_list = $(this).parents('.form_part').find('.results_list').find("input[name='" + input_name + "']");
                if (pattern != id) {
                    pattern += '_';
                }
                $.each(result_list, function (key, input) {
                    let inp_val = $(input).val();
                    if ((pattern != id &amp;&amp; inp_val &amp;&amp; inp_val.indexOf(pattern) === 0) || inp_val == pattern
                        || (pattern == id &amp;&amp; parseInt(inp_val) != inp_val &amp;&amp; inp_val.split('_').includes(id))) {
                        can_add = false;
                        return false;
                    }
                });
                if (id &amp;&amp; radius &gt;= 0 &amp;&amp; can_add) {
                    var tpl = $("li.results_list_template", list);

                    var entry = tpl.clone(true);
                    entry.removeClass("results_list_template");

                    $("input[data-tpl='location']", entry).val(id);
                    $("input[data-tpl='radius']", entry).val(radius);

                    $("span[data-tpl='text']", entry).html(text);
                    if (radius == 0) {
                        $("span.location_radius", entry).html("");
                    } else {
                        $("span[data-tpl='radius_text']", entry).text(radius);
                    }

                    entry.insertBefore(tpl)
                }

            });

            initSearchField($("input.autocomplete", row), {
                url: _rr.Search.localities(lang, '%q'),
            });

        });

        form.submit(function(e) {
            e.preventDefault();

            var deal = form.find('[name=user_criterias_deal]:checked').val();
            if(deal === 'RENT'){
                if(form.find('input[name=user_criterias_price_rent_from]').length &gt; 0){
                    form.find('input[name=user_criterias_price_from]').val(form.find('input[name=user_criterias_price_rent_from]').val());
                    form.find('input[name=user_criterias_price_to]').val(form.find('input[name=user_criterias_price_rent_to]').val());
                }
            }

            var row_location_include = $(".row_locations_included", form);
            if($($("input.autocomplete", row_location_include).attr("data-field-value")).val()) {
                let autocomplete_val = $($("input.autocomplete", row_location_include).attr("data-field-value")).val();
                let includes = $($("input[name='user_criterias_locations_included_loc[]']", form));
                let click = true;
                $.each(includes, function(key, value){
                    if ($(value).val() == autocomplete_val){
                        click = false;
                    }
                });
                if (click) {
                    $("button.button_ajax_add_list", row_location_include).trigger("click");
                }
            }

            var row_location_exclude = $(".row_locations_excluded", form);
            if($($("input.autocomplete", row_location_exclude).attr("data-field-value")).val()) {
                let autocomplete_val = $($("input.autocomplete", row_location_exclude).attr("data-field-value")).val();
                let excludes = $($("input[name='user_criterias_locations_excluded_loc[]']", form));
                let click = true;
                $.each(excludes, function(key, value){
                    if ($(value).val() == autocomplete_val){
                        click = false;
                    }
                });
                if (click) {
                    $("button.button_ajax_add_list", row_location_exclude).trigger("click");
                }
            }

            submitAjaxForm($(this), {
                onSuccess: function(res) {
                    if (res.refresh) {
                        window.location.reload()
                    } else if (res.redirect !== undefined) {
                        setTimeout(function () {
                            window.location.href = res.redirect;
                        }, 1000);
                    }
                },
            });

            return false;
        });

    });

    showHidePriceWrapper();

    $('div.user_criterias_filter_choice').find("input[type=radio]").change(function(){
        showHidePriceWrapper();
    });
    $('[name=user_criterias_deal]').change(function(){
        showHidePriceWrapper();
    });

    $("form.user_activation_form").submit(function(e) {
        e.preventDefault();
        var form = $(this);

        submitAjaxForm($(this), {
            onSuccess: function(res) {
                if (res.redirect !== undefined) {
                    window.location = res.redirect;
                } else {
                    window.location = _rr.UserAuth.criterias(lang)
                }
            },
        });

        return false;
    });

    $(".menu_currencies input[name='currency']").change(function() {
        createCookie('fe2_currency', $(this).val(), 3600 * 24 * 365);
        window.location.reload();
    });


    // Implement object search functionnalities
    $(".scope_objects_search, .scope_objectslist_search, .cms_objects_filter, .scope_objectslist_all, .scope_projects_table, .scope_objectslist_publisher").each(function() {
        $("form.objects_filters").each(function () {
            var filters = $(this);

            $("[name='radius_to']", filters).each(function() {
                var self = $(this);
                var radius; /* = 0; */
                var location;
    
                if(self.prop("tagName").toLowerCase() == 'input') {
                    self.change(function () {
                        radius = self.val();
                        location = $("input[name=location]", filters).val().split("+");
                        $("input[name=location]", filters).val(location[0] + "+" + radius)
                    });
                } else {
                    self.find("input[type='radio']").change(function () {
                        radius = $(this).val();
                        location = $("input[name=location]", filters).val().split("+");
                        $("input[name=location]", filters).val(location[0] + "+" + radius)
                    });
                }
            });

            $(".filter_part_location .filter_element_autocomplete input[type='text']", filters).each(function () {
                initSearchField($(this), {
                    url: _rr.Search.objectLocation(lang, '%q'),
                    radius: $('.filter_part_radius', filters),
                });
    
                $(this).blur(function () {
                    let location = $("input[name=location]", filters);
                    let location_search = $("input[name=location_search]", filters);

                    if(location.val() == "" || (location_search.val() != "")) {
                        $(this).val("");
                    } 
                });
    
                $("input[name=location]", filters).change(function () {
                    let radius;
                    radius = $("input[name='radius_to']", filters).val();
                    if (!radius) {
                        radius = $("input[type='radio'][name$='radius_to']:checked", filters).val();
                    }
                    let location = $("input[name=location]", filters).val().split("+");
                    if(radius) {
                        $(this).val(location[0] + "+" + radius)
                    } else {
                        $(this).val(location[0] + "+" + 0)
                    }
                })
            });
    
            $(".filter_part_reference .filter_element_autocomplete input[type='text']", filters).each(function() {
                initSearchField($(this), {
                    url: _rr.Search.objectReference(lang, '%q'),
                });
            });
    
            $(".filter_part_location .filter_element_autocomplete_multiple", filters).each(function() {
                var ma = new feMultiAutocomplete($(this), {
    
                });
    
                initSearchField($("input[type='text']", $(this)), {
                    url: _rr.Search.objectLocation(lang, '%q'),
                    multiple: true,
                    onSelect: function(el, i) {
                        ma.add(i.v, i.label);
                    }
                });
            });
    
            var isEventBound = false;
    
            $('.filter_tools .toggle', filters).click(function(e) {    
                e.preventDefault();
    
                var tools = $(this).closest('.filter_list');
    
                if ($('.filter_group_advanced_close', tools).hasClass('hide')) {
                    $('.filter_group_advanced_open', tools).addClass('hide');
                    $('.filter_group_advanced_close, .filter_group_advanced', tools).removeClass('hide');
    
                    if (!isEventBound) {
                        $(document).on('click', function(event) {
                            if (!$(event.target).closest('.filter_list').length) {
                                $('.filter_group_advanced_open', tools).removeClass('hide');
                                $('.filter_group_advanced_close, .filter_group_advanced', tools).addClass('hide');
                                $(document).off('click'); // Remove the event after it triggers
                                isEventBound = false;
                            }
                        });
                        isEventBound = true;
                    }
                } else {
                    $('.filter_group_advanced_open', tools).removeClass('hide');
                    $('.filter_group_advanced_close, .filter_group_advanced', tools).addClass('hide');
                }
            });
        })
    });    

    $(".scope_objects_search, .scope_objectslist_search, .scope_objectslist_all, .scope_objectslist_publisher").each(function () {
        var filtersAdvanced = $("form.objects_filters_advanced");
        var filters = filtersAdvanced;
        if (!filters.length) {
            filters = $("form.objects_filters");
        }

        var searchMode = filtersAdvanced.length ? 'onSubmit' : 'onChange'
        var map;
        const container = $(this);
        const sr = $("[data-search-results], #search_results", container);
        const navId = sr.data('nav-id');
        const resultsMap = $(".search_results_map", sr);
        const resultsList = $(".search_results_list .list_container", sr);
        
        const title      = $(".search_results_title", container);
        const listOrMap  = $(".search_results_list_or_map", sr);
        const listAndMap = $(".search_results_list_and_map", sr);
        const mapOnly    = $(".search_results_map_only", sr);

        $(".search_tools .sort_dropdown", container).each(function () {
            $("select, input:not(.multiselect_cb):not(.autocomplete)", $(this)).change(function () {
                // Mirror to the in-form hidden field sort
                $("input[name='sort']", filters).val($(this).val()).change();
            });
        });

        var initMapOnLoad = (resultsMap.length &amp;&amp; (!listOrMap.length || listOrMap.hasClass("show_map")));

        var os = new feObjectsSearch(filters, {
            el: sr,
            url: _rr.Objects.ajaxSearchBoth(lang),
            list: {
                el: resultsList,
                url: _rr.Objects.ajaxSearchList(lang),
            },
            map: {
                el: resultsMap,
                url: _rr.Objects.ajaxSearchMap(lang),
            },
            title: title,
            total: parseInt($(".total", title).first().text()),
        })

        function initMap() {
            if (map) {
                return;
            }

            var mc = resultsMap.find('.map_canvas');
            var style = mc.attr('data-popup-style');

            // Load filter bounds
            map = new feMap(mc, {
                markers: {
                    radius: 'hover',
                    popup: {
                        html: function (m, cb) {
                            $.get({
                                url: _rr.Objects.ajaxPopupContent(lang),
                                data: {
                                    ids: m.ids.join(','),
                                    offsets: m.offsets.join(','),
                                    s: map.search,
                                    from: map.from,
                                    style: style,
                                },
                                success: function (r) {
                                    if (r.success) {
                                        cb(r.html)
                                    }
                                }
                            })
                        }
                    },
                }
            });

            if (listAndMap.length) {
                map.mb.on('load', function() {
                    mapPosition(mc);
                    mapCtrlPosition(mc);
                    $(window).on('scroll resize', function() {
                        mapPosition(mc);
                        mapCtrlPosition(mc);
                    });
                });

                mapToggle($('.map_toggle', sr.parent()), os);
            }

            os.setMap(map);

            if (resultsList.length) {
                registerScriptLoader(function () {
                    $("article.box_object_item", resultsList).off( "mouseenter mouseleave" );
                    $("article.box_object_item", resultsList).hover(function () {
                        map.highlightMarkers([parseInt($(this).attr('data-object-id'))], true);
                    }, function () {
                        map.highlightMarkers([parseInt($(this).attr('data-object-id'))], false);
                    });
                });
            }

            map.mb.resize();
        }

        if (initMapOnLoad) {
            initMap();

            os.search({
                rewriteUrl: false,
                load: "map",
            })
        }

        // if map manual reloading is set to true, do not reload map
        var resultsListReload = false;
        if (resultsMap.attr('data-reloading') == 'automatic') {
            resultsListReload = true;
        }

        
        if (searchMode === 'onChange') {
            onFormChange(filters, function (f) {
                if (!f.hasClass('no_search')) {
                    if (f.attr("name") == "sort") {
                        os.search({
                            load: "list",
                        });
                    } else {
                        
                        let load = "all";
    
                        if (listOrMap.length) {
                            if (listOrMap.hasClass("show_map")) {
                                load = "map";
                            } else {
                                load = "list_total";
                            }
                        } else {
                            if (mapOnly.length) {
                                load = "map";
                            }
                        }
    
                        os.search({
                            load: load,
                            from: 'filters',
                    });
                    }
                }
            });
        } else if (searchMode === 'onSubmit') {
            onFormChange(filters, function (f) {
                if (!f.hasClass('no_search') &amp;&amp; f.attr("name") == "sort") {
                    os.search({
                        load: "list",
                    });
                }
            });

            filtersAdvanced.on('submit', function (event) { 
                event.preventDefault();
                let load = "all";
    
                if (listOrMap.length) {
                    if (listOrMap.hasClass("show_map")) {
                        load = "map";
                    } else {
                        load = "list_total";
                    }
                } else {
                    if (mapOnly.length) {
                        load = "map";
                    }
                }
    
                os.search({
                    load: load,
                    from: 'filters',
                });
            })
        }

    


        // on button click, reload map
        $(".map_reload .button", sr).click(function () {
            var boundsFilter = $("form.objects_filters input[name='map_bounds']");

            boundsFilter.each(function () {
                var input = $(this);

                var b  = map.mb.getBounds();
                var ne = b.getNorthEast();
                var sw = b.getSouthWest();

                if (!resultsMap.parent().hasClass('closed_map') &amp;&amp; resultsMap.is(':visible')) {
                    input.val(ne.lat + ":" + ne.lng + ";" + sw.lat + ":" + sw.lng);
                    os.search({
                        load: "all",
                        fitBounds: false
                    });
                }
            });
        });

        //container as parent instead of sr because list-style is out of search_result on some templates.
        $(".search_tools [data-list-style]", container).click(function (event, extraParams) {
            const oldStyle = resultsList.attr("data-list-style");
            const newStyle = $(this).attr("data-list-style");

            createCookie('view-' + navId, newStyle, 3600 * 24 * 365);
            resultsList.attr('data-list-style', newStyle);

            $(this).parent().find('[data-list-style]').each(function () {
                $(this).removeClass('selected');
                $('[data-list-style=' + newStyle + ']').addClass('selected');
            })

            let searchType = 'list_total';
            if (oldStyle != newStyle) {

                if (newStyle == "map") {
                    searchType = 'map';
                    initMap();
                    listOrMap.addClass("show_map")
                    map.mb.resize();
                } else {
                    listOrMap.removeClass("show_map");
                }

                if ($('.infinite_scroll, .infinite_scroll_by_button', container).length &gt; 0) {
                    $('.infinite_scroll, .infinite_scroll_by_button', container).attr('data-active', 0);
                }

                os.search({
                    load: searchType,
                });
            }
        })


        /*
        if (map &amp;&amp; resultsListReload) {
            var boundsFilter = $("form.objects_filters input[name='map_bounds']");

            boundsFilter.each(function () {
                var input = $(this);

                map.onBoundsChange(function (ne, sw) {

                    if (!resultsMap.parent().hasClass('closed_map') &amp;&amp; resultsMap.is(':visible')) {
                        input.val(ne.lat + ":" + ne.lng + ";" + sw.lat + ":" + sw.lng);
                        os.search();
                    }
                });

            });

            if (boundsFilter.length) {
                map.autoZoom = false;
            }
        }
        */

        // Load infinite scroll behavior
        $('.infinite_scroll, .infinite_scroll_by_button', sr).each(function () {
            infiniteScroll($(this), function (loader, done) {
                $.get(loader.attr("data-url"), { 'fs': 0 }, function (res) {
                    loader.attr("data-scrolled", "1");

                    // Situation before:
                    //   &lt;list_container&gt;&lt;list&gt;&lt;res1 /&gt;&lt;res2 /&gt;...&lt;/list&gt;&lt;loader /&gt;&lt;/list_container&gt;
                    //
                    // AJAX call returns res.list with:
                    //   &lt;list&gt;&lt;res5 /&gt;&lt;res6 /&gt;...&lt;/list&gt;
                    //
                    // 1) append &lt;res5 /&gt;&lt;res6 /&gt;  to end of 'list_container &gt; list'
                    //
                    var results = $(res.list).children();
                    loader.prev().append(results);
                    loadScripts(results);

                    // results.hover(function () {
                    //     map.highlightMarkers([parseInt($(this).attr('data-object-id'))], true);
                    // }, function () {
                    //     map.highlightMarkers([parseInt($(this).attr('data-object-id'))], false);
                    // });

                    // 2) update &lt;loader /&gt; attributes
                    //

                    var dataUrl = '';
                    if (res.pagination.nexts.length &gt; 0) {
                        dataUrl = res.pagination.nexts[0].url;
                    }

                    loader.attr('data-url', dataUrl);
                    loader.attr('data-active', dataUrl ? '1' : '0');

                    var $button = loader.find('button').first();
                    if ($button.length) {
                        if (dataUrl) {
                            $button.removeClass('hide');
                        } else {
                            $button.addClass('hide');
                        }
                    }

                    done();
                })
            });
        });

        function ajaxPagination(el) {
            $(".pagination_manual &gt; li &gt; a", el).click(function (e) {
                e.preventDefault();

                startLoading(el);

                $.get($(this).attr("href"), function (res) {

                    // Situation before:
                    //   &lt;list_container&gt;&lt;list&gt;&lt;res1 /&gt;&lt;res2 /&gt;...&lt;/list&gt;&lt;pagination /&gt;&lt;/list_container&gt;
                    //
                    // AJAX call returns res.list with:
                    //   &lt;list&gt;&lt;res5 /&gt;&lt;res6 /&gt;...&lt;/list&gt;&lt;pagination /&gt;
                    //
                    if(el.find('.pagination').length &gt; 1) {
                        el.html(res.pagination.html + res.list + res.pagination.html);
                    } else {
                        el.html(res.list + res.pagination.html);
                    }

                    ajaxPagination(el);

                    loadScripts(el);

                    endLoading(el);

                    // console.log($("article.box_object_item", res.list));
                    // $("article.box_object_item", res.list).each(function () {
                    //     $(this).hover(function () {
                    //         map.highlightMarkers([parseInt($(this).attr('data-object-id'))], true);
                    //     }, function () {
                    //         map.highlightMarkers([parseInt($(this).attr('data-object-id'))], false);
                    //     });
                    // });

                    $('input[type="hidden"][name="page"]').val(res.pagination.page);

                    if (el.parents('div[data-scroll-target=filters]').length &amp;&amp; (filters_el = el.parents('#search_results').siblings('.objects_filters')).length) {
                        el = filters_el;
                    }

                    if (isIntegration) {
                        globalEvent(null, 'scrollTop', { 'offset' : el.offset().top });
                    } else {
                        goTo(el, 600, 'swing');
                    }
                })
            });
        }

        ajaxPagination($(".list_container", sr));
    });

    $(".cms_objects_list").each(function() {
        var filters = $("form.objects_filters");
        var map;

        var sr = $("[data-search-results], #search_results", $(this));
        var navId = sr.data('nav-id');
        var resultsMap = $(".search_results_map", sr);
        var resultsList = $(".search_results_list .list_container", sr);
        var list = resultsList.length ? resultsList : null;

        $(".search_tools .sort_dropdown").each(function() {
            $("select, input:not(.multiselect_cb):not(.autocomplete)", $(this)).change(function() {
                // Mirror to the in-form hidden field sort
                $("input[name='sort']", filters).val($(this).val()).change();

            });
        });

        if (resultsMap.length) {
            var mc = resultsMap.find('.map_canvas');
            var style = mc.attr('data-popup-style');

            function initMap() {
                if (map) {
                    return;
                }
                map = new feMap(mc, {
                    // bounds: bounds,
                    markers: {
                        radius: 'hover',
                        popup: {
                            html: function(m, cb) {
                                $.get({
                                    url: _rr.Objects.ajaxPopupContent(lang),
                                    data: {
                                        ids: m.ids.join(','),
                                        offsets: m.offsets.join(','),
                                        s: map.search,
                                        from: map.from,
                                        style: style,
                                    },
                                    success: function(r) {
                                        if (r.success) {
                                            cb(r.html)
                                        }
                                    }
                                })
                            }
                        },
                    }
                });

                startLoading(mc);
                $.get({
                    url: resultsMap.attr('data-init-url'),
                    success: function(res) {
                        if (res.success) {
                            map.setMarkers(res.map.markers, res.map.bounds);
                            map.search = res.map.search;
                            map.from = res.map.from;
                        }
                    },
                    complete: function() {
                        endLoading(mc);
                    },
                });
                map.mb.resize();
            }
        }

        if (resultsMap.length &amp;&amp; !resultsList.length) {
            initMap();
        }

        let container = sr;
        $(".search_tools [data-list-style]", container).click(function () {
            const newStyle = $(this).attr("data-list-style");

            var componentId = $(container).attr('data-component-id');
            createCookie('view-' + componentId, newStyle, 3600 * 24 * 365);

            if (list.attr("data-list-style") != newStyle) {
                $(this).parent().find('[data-list-style]').each(function () {
                    if ($(this).attr('data-list-style') != newStyle) {
                        $(this).removeClass('selected');
                    } else {
                        $(this).addClass('selected');
                    }
                })
                list.attr("data-list-style", newStyle);
                if (newStyle == "map") {
                    list.closest(".search_results_list_or_map").addClass("show_map")
                    initMap();
                } else {
                    list.closest(".search_results_list_or_map").removeClass("show_map");
                }
            }
        });

        function initAjaxPagination(el) {
            $(".pagination_manual &gt; li &gt; a", el).click(function(e) {
                e.preventDefault();

                startLoading(el);

                $.get($(this).attr("href"), function(res) {

                    // Situation before:
                    //   &lt;list_container&gt;&lt;list&gt;&lt;res1 /&gt;&lt;res2 /&gt;...&lt;/list&gt;&lt;pagination /&gt;&lt;/list_container&gt;
                    //
                    // AJAX call returns res.list with:
                    //   &lt;list&gt;&lt;res5 /&gt;&lt;res6 /&gt;...&lt;/list&gt;&lt;pagination /&gt;
                    //
                    if(el.find('.pagination').length &gt; 1) {
                        el.html(res.pagination.html + res.list + res.pagination.html);
                    } else {
                        el.html(res.list + res.pagination.html);
                    }

                    initAjaxPagination(el);

                    loadScripts(el);

                    // $("article.box_object_item", res).hover(function () {
                    //     map.highlightMarkers([parseInt($(this).attr('data-object-id'))], true);
                    // }, function () {
                    //     map.highlightMarkers([parseInt($(this).attr('data-object-id'))], false);
                    // });

                    endLoading(el);

                    $('input[type="hidden"][name="page"]').val(res.pagination.page);

                    goTo(el, 600, 'swing');
                })
            });
        }

        initAjaxPagination($(".list_container", sr));
    })

    $(".scope_projects_table").each(function () {
        var filters = $("form.objects_filters");

        var pt = $("#project_table")
        var table = $("#detail_project_table", pt)

        // $(".search_tools .sort_dropdown").each(function () {
        //     $("select, input:not(.multiselect_cb):not(.autocomplete)", $(this)).change(function () {
        //         // Mirror to the in-form hidden field sort
        //         $("input[name='sort']", filters).val($(this).val()).change();

        //     });
        // });


        var url = _rr.Projects.ajaxTable(lang);
        var opts = {
            url: url,
            load: 'list',
            list: {
                el : pt,
                url : url,
            },
            title: $(".search_results_title"),
            loaderTarget: pt,
            scroll: true,
        }

        var os = new feObjectsSearch(filters, opts)


        onFormChange(filters, function (f) {
            if (!f.hasClass('no_search')) {
                os.search(opts);
            }
        });

    });

    $(".scope_main_landing").each(function() {
        $(".filter_part_location .filter_element_autocomplete input[type='text']").each(function() {
            initSearchField($(this), {
                url: _rr.Search.objectLocation(lang, '%q'),
            });
        });

        $(".filter_part_reference .filter_element_autocomplete input[type='text']").each(function() {
            initSearchField($(this), {
                url: _rr.Search.objectReference(lang, '%q'),
            });
        });

        $(".filter_part_location .filter_element_autocomplete_multiple").each(function() {
            var ma = new feMultiAutocomplete($(this), {

            });

            initSearchField($("input[type='text']", $(this)), {
                url: _rr.Search.objectLocation(lang, '%q'),
                multiple: true,
                onSelect: function(el, i) {
                    ma.add(i.v, i.label);
                }
            });
        });
    })

    loadScripts($("html"), true);

    // Fragment actions
    if (window.location.hash) {
        if (window.location.hash.substring(0, 7) == '#login-') {
            $("a.login_icon.magnific-popup").magnificPopup('open');
        }
    }
    window.onhashchange = function(evt){
        if (window.location.hash.substring(0, 7) == '#login-') {
            $("a.login_icon.magnific-popup").magnificPopup('open');
        }
    }

    $(".global_messages &gt; .close_messages").click(function() {
        $(this).closest('.global_messages').addClass('hide');
    });

    $('[data-load-more-target]').on('click', function(e) {
        e.preventDefault();
        var $this = $(this);
        var target = $($this.data('load-more-target'));
        $.ajax({
            type: 'GET',
            url: $this.attr('href'),
            success: function(data) {
                if (data.success) {
                    target.append(data.html);
                    $this.attr('href', data.href);
                    if (!data.more) {
                        $this.addClass('hide');
                    }
                }
            },
            error: function() {
                console.log('error...');
            }
        });
    });

    if (isTouchScreenDevice) {
        touchScreenHandlers();
    }

    if (isIntegration) {
        globalEvent(null, 'initScrollTop', { 'offset' : 0});
    }

    //auto popup load
    if($('[data-auto-popup]').length &gt; 0) {
        let $autoPopup = $('[data-auto-popup]');
        let cookiesLife = $autoPopup.data('auto-popup');
        let popupId = $autoPopup.data('popup-id');
        $autoPopup.click();

        createCookie('auto_popup_'+popupId, 'showed', cookiesLife);
    }

    // search widget
    $('.cms_objects_filter [data-filter-ident="deal"]').each(function() {
        let deal = $(this).find('input[name="deal[]"]');
        deal.change(function() {
            var selectedDeal = $("input[name='deal[]']:checked").map(function(){return $(this).val();}).get();

            if(selectedDeal.length == 1 &amp;&amp; ($.inArray('SALE', selectedDeal) !== -1)) {
                $(this).parents('form').attr('action', _rr.ObjectsList.redirectToIdent(lang, 'sale'));
            } else if(selectedDeal.length == 1 &amp;&amp; ($.inArray('RENT', selectedDeal) !== -1)) {
                $(this).parents('form').attr('action', _rr.ObjectsList.redirectToIdent(lang, 'rent'));
            } else {
                $(this).parents('form').attr('action', _rr.ObjectsList.redirectToIdent(lang, 'search'));
            }
        });
    });

    $("input[type=number].numeric").on('keydown', function(event) {
        return ((event.keyCode == 69 || (event.keyCode == 107) || (event.keyCode == 109) || (event.keyCode == 110) || (event.keyCode == 189) || (event.keyCode == 190) || (event.keyCode == 171) || (event.keyCode == 187)) ? false : true)
    });
});

if (isTouchScreenDevice) {
    (function($) {
        // Detect touch support
        $.support.touch = 'ontouchend' in document;
        // Ignore browsers without touch support
        if (!$.support.touch) {
            return;
        }
        var mouseProto = $.ui.mouse.prototype,
            _mouseInit = mouseProto._mouseInit,
            touchHandled;

        function simulateMouseEvent(event, simulatedType) { //use this function to simulate mouse event
            // Ignore multi-touch events
            if (event.originalEvent.touches.length &gt; 1) {
                return;
            }
            event.preventDefault(); //use this to prevent scrolling during ui use

            var touch = event.originalEvent.changedTouches[0],
                simulatedEvent = document.createEvent('MouseEvents');
            // Initialize the simulated mouse event using the touch event's coordinates
            simulatedEvent.initMouseEvent(
                simulatedType, // type
                true, // bubbles                    
                true, // cancelable                 
                window, // view                       
                1, // detail                     
                touch.screenX, // screenX                    
                touch.screenY, // screenY                    
                touch.clientX, // clientX                    
                touch.clientY, // clientY                    
                false, // ctrlKey                    
                false, // altKey                     
                false, // shiftKey                   
                false, // metaKey                    
                0, // button                     
                null // relatedTarget              
            );

            // Dispatch the simulated event to the target element
            event.target.dispatchEvent(simulatedEvent);
        }
        mouseProto._touchStart = function(event) {
            var self = this;
            // Ignore the event if another widget is already being handled
            if (touchHandled || !self._mouseCapture(event.originalEvent.changedTouches[0])) {
                return;
            }
            // Set the flag to prevent other widgets from inheriting the touch event
            touchHandled = true;
            // Track movement to determine if interaction was a click
            self._touchMoved = false;
            // Simulate the mouseover event
            simulateMouseEvent(event, 'mouseover');
            // Simulate the mousemove event
            simulateMouseEvent(event, 'mousemove');
            // Simulate the mousedown event
            simulateMouseEvent(event, 'mousedown');
        };

        mouseProto._touchMove = function(event) {
            // Ignore event if not handled
            if (!touchHandled) {
                return;
            }
            // Interaction was not a click
            this._touchMoved = true;
            // Simulate the mousemove event
            simulateMouseEvent(event, 'mousemove');
        };
        mouseProto._touchEnd = function(event) {
            // Ignore event if not handled
            if (!touchHandled) {
                return;
            }
            // Simulate the mouseup event
            simulateMouseEvent(event, 'mouseup');
            // Simulate the mouseout event
            simulateMouseEvent(event, 'mouseout');
            // If the touch interaction did not move, it should trigger a click
            if (!this._touchMoved) {
                // Simulate the click event
                simulateMouseEvent(event, 'click');
            }
            // Unset the flag to allow other widgets to inherit the touch event
            touchHandled = false;
        };
        mouseProto._mouseInit = function() {
            var self = this;
            // Delegate the touch handlers to the widget's element
            self.element
                .on('touchstart', $.proxy(self, '_touchStart'))
                .on('touchmove', $.proxy(self, '_touchMove'))
                .on('touchend', $.proxy(self, '_touchEnd'));

            // Call the original $.ui.mouse init method
            _mouseInit.call(self);
        };
    })(jQuery);
}

registerScriptLoader(function(parent) {

    $(".lazy", parent).each(function() {
        var el = this;

        if (el.hasAttribute('data-src') &amp;&amp; !el.hasAttribute('src')) {
            lazyLoad(el, function() {
                el.setAttribute('src', el.getAttribute('data-src'));
            })
        }
    });

    $(".map_objects_details .map_canvas", parent).each(function() {
        var canvas = $(this);

        lazyLoad(this, function() {
            new feMap(canvas);
        });
    });

    $(".cms_map .map_canvas, .cms_project_map .map_canvas", parent).each(function() {
        var canvas = $(this);

        lazyLoad(this, function() {
            new feMap(canvas);
        });
    });

    $(".user_selection_map .map_canvas", parent).each(function() {
        var style = $(this).attr('data-popup-style');
        var map = new feMap($(this), {
            // allow hidden position to have a popup on radius hover
            markers: {
                radius: 'hover',
                popup: {
                    html: function(m, cb) {
                        $.get({
                            url: _rr.Objects.ajaxPopupContent(lang),
                            data: {
                                ids: m.ids.join(','),
                                offsets: m.offsets.join(','),
                                s: map.search,
                                from: map.from,
                                style: style,
                            },
                            success: function(r) {
                                if (r.success) {
                                    cb(r.html)
                                }
                            }
                        })
                    }
                },
            }
        });
    });

    if ($('.section_accordion_form', parent).length) {
        stickTop($('.accordion_title', parent));
        $(window).scroll(function() {
            stickTop($('.accordion_title', parent));
        });
    }

    if ($('.anchors', parent).length) {
        titleElements = '.cms_banner h1, .cms_banner h2, .cms_section h1, .cms_section h2';
        if ('IntersectionObserver' in window) {
            const observer = new IntersectionObserver((items) =&gt; {
                items.forEach((item) =&gt; {
                    if (item.isIntersecting) {
                        var datatitle = $(item.target).attr('data-title');
                        setActiveAnchor(datatitle, parent);
                    }
                });
            }, {
                threshold: 1,
            });

            $(titleElements, parent).each(function() {
                observer.observe(this);
            });
        } else {
            $(window).on('resize scroll', function () {
                changeActiveAnchor(titleElements, parent);
            });
        }
    }

});


function changeActiveAnchor(titleElements, parent) {
    if ($('.firstanchor', parent).length) {
        $('.firstanchor', parent).removeClass('firstanchor');
    } else {
        $(titleElements, parent).each(function() {
            if ($(this).isInViewport()) {
                var datatitle = $(this).attr('data-title');
                setActiveAnchor(datatitle, parent);
            }
        });
    }
}

function setActiveAnchor(datatitle, parent) {
    $('.anchors a[data-title="' + datatitle + '"]', parent).addClass("activeanchor");
    if ($('.activeanchor', parent).length &gt; 1) {
        $('.activeanchor', parent).removeClass("activeanchor");
        $('.anchors a[data-title="' + datatitle + '"]', parent).addClass("activeanchor");
    }
}


$(document).ready(function () {
    // First we get the viewport height and we multiple it by 1% to get a value for a vh unit
    let vh = window.innerHeight * 0.01;
    // Then we set the value in the --vh custom property to the root of the document
    document.documentElement.style.setProperty('--vh', `${vh}px`);

    window.addEventListener('resize', () =&gt; {
        // We execute the same script as before
        let vh = window.innerHeight * 0.01;
        document.documentElement.style.setProperty('--vh', `${vh}px`);
    });

    $("#similar_objects_wrapper").each(function() {
        var wrapper = $(this);

        lazyLoad(this, function() {
            callAjax(_rr.Objects.similarObjects(lang, wrapper.attr('data-object-id'))).then(function(data) {
                wrapper.html(data);
                loadScripts(wrapper);
            });
        });
    });
    
});
/* /websites/base/js/components/recaptcha_v2.js */
let _captchasToLoad = [];
let _captchasLoaded = false;

// Called from external captcha library when JS lib is loaded
window.onloadCaptchaCallback = function () {

    _captchasLoaded = true;

    _captchasToLoad.forEach((cb) =&gt; {
        cb();
    });

    _captchasToLoad = [];

}

// Called from forms when resetting values
window.resetCaptchas = function (parent) {
    if (_captchasLoaded) {
        parent[0].querySelectorAll(".g-recaptcha").forEach((el) =&gt; {
            grecaptcha.reset(el.getAttribute("data-id"))
        })
    }
}


registerScriptLoader((parent) =&gt; {
    
    parent[0].querySelectorAll(".g-recaptcha").forEach((el) =&gt; {
        const theme = el.getAttribute("data-theme");

        function loadCaptcha() {
            var id = grecaptcha.render(el, {
                theme: theme,
                callback: function(response) {
                    el.parentNode.querySelector("input.g-recaptcha-response").value = response;
                },
            });

            el.setAttribute("data-id", id);
        }

        if (_captchasLoaded) {
            loadCaptcha();
        } else {
            _captchasToLoad.push(loadCaptcha);
        }
    })
})
/* /websites/base/js/components/prospection.js */
function feProspectionForm(form, options) {
    options = $.extend({}, options);

    const Direction = {
        NEXT: "next",
        PREV: "prev",
    }

    var pf = this;

    var nSteps = $(".steps_content", form).children().length

    var map = new feMap($("[data-prospection-map]", form), {
        autoZoom: 'always',
        minZoom: 'never',
    });

    this.geolocate = function() {
        var url = _rr.Search.geolocate(lang);

        var fields = {
            address: form.find('input[name="prospection_object_address"]').val(),
            npa: form.find('input[name="prospection_object_postalcode"]').val(),
            city: form.find('input[name="prospection_object_location"]').val(),
        };

        if (fields.npa &amp;&amp; fields.city) {
            var location = Object.values(fields).join(", ");

            $.getJSON(url, { address: location }, function(res) {
                if (res.success) {
                    $(map.mb._container).find(".marker").remove(); // clear all previous markers
                    map.setMarkers(
                        [{
                            coords: { lat: res.lat, lng: res.lng },
                            onDragEnd: function(marker) {
                                var coords = marker.getLngLat();

                                form.find('input[name="prospection_object_lat"]').val(coords.lat);
                                form.find('input[name="prospection_object_lng"]').val(coords.lng);
                            },
                        }]
                    );
                    form.find('input[name="prospection_object_lat"]').val(res.lat);
                    form.find('input[name="prospection_object_lng"]').val(res.lng);
                } else {
                    map.setMarkers([], false);
                }
            });
        }
    }

    this.goTo = function(target, direction) {
        direction = direction || Direction.NEXT;
        
        var active = $('.step_active[data-step]', form);
        active.addClass('step_animated');
        var final = $('[data-step=' + target + ']').hasClass('step_final');
        setTimeout(function() {
            active.removeClass('step_animated');
        }, 500);

        $('.step_bullet', form).each(function() {
            var bullet = $(this);
            var step = bullet.attr('data-step-bullet');

            if (step == target) {
                bullet.addClass('active_bullet');
                $('[data-step=' + step + ']', form).addClass('step_active');
            } else {
                bullet.removeClass('active_bullet');
                $('[data-step=' + step + ']', form).removeClass('step_active');
                map.resize;
                map.update;
            }

            if (step &lt; target) {
                bullet.addClass('done_bullet');
                $('[data-step=' + step + ']', form).addClass('step_done');
            } else {
                bullet.removeClass('done_bullet');
                $('[data-step=' + step + ']', form).removeClass('step_done');
            }
        });

        var actions = form.find('.steps_actions');

        if (target == nSteps || final) {
            $('.button_next', actions).addClass('hide');
            $('.button_send', actions).removeClass('hide');
            $('.button_save_and_continue', actions).addClass('hide');
        } else if (target == 1) {
            // First step is activated by clicking the categories/subcategories
            $('.button_next', actions).addClass('hide');
        } else {
            displayHideButtons(actions, target);
        }

        if (target == 1) {
            $('.button_prev', actions).addClass('hide');
        } else {
            $('.button_prev', actions).removeClass('hide');
        }

        pf.focusFirstInput(target);

        //check if the step contains visible fields. Otherwise it skip the step
        var active = $('.step_active', form);
        if($('.row', active).length &gt; 0 &amp;&amp; ($('.row', active).length == $('.row.hide', active).length)) {
            if(direction == Direction.PREV) {
                this.goTo(target-1, Direction.PREV);
            } else {
                if(target+1 &lt;= nSteps) {
                    this.goTo(target+1);
                }
            }
        }
        map.mb.resize();

        prospectionGtagEvents(target);
        globalEvent(active, 'prospectionGoTo', {step: target});
    }

    this.focusFirstInput = function(target) {
        var slide = $('[data-step=' + target + ']', form);
        var first = slide.find('input, textarea').filter(':visible:first');
        if (first.length) {
            setTimeout(function() {
                first.trigger('focus');
            }, 600); // wait for end of css transition
        }
    }

    this.initTabindex = function() {
        $('input, select, textarea', form).attr('tabindex', -1);
        $('input, textarea', form).filter(':not([type="hidden"])').each(function(index, el) {
            var $el = $(el);
            var parent = $el.parents('.prospection_form_box');
            var step = parent.attr('data-step');
            $el.attr('tabindex', step * 1000 + index);
        });

        $('.button_prev').attr('tabindex', 10000);
        $('.button_next').attr('tabindex', 10001);
    }

    this.validateForm = function(el) {
        /*
        var f = $("div.row[data-field='"+field+"'], div.row_group[data-field='"+field+"']", form);
        $("label.form_error_msg", f).html(errors[field]);
        f.addClass("error");
        */
        var hasError = false;

        $(".row_required.row[data-field],.row_required.row_group[data-field]", el).each(function() {
            var f = $(this);
            var hasValue = false;

            $("textarea, select, input", f).each(function() {
                var type = $(this).attr('type');

                if ((type == 'radio' || type == 'checkbox') &amp;&amp; !$(this).prop("checked")) {
                    return;
                }

                var v = $(this).val();
                var name = $(this).attr('name');

                if (!name) {
                    return;
                }

                if (v === "" || (Array.isArray(v) &amp;&amp; v.length === 0)) {
                    return;
                }

                hasValue = true;
            });

            if (!hasValue) {
                hasError = true;
                f.addClass('error');
            } else {
                f.removeClass('error');
            }
        });

        return !hasError;
    }

    this.goToFirstError = function() {
        var minStep = 999;

        $(".row.error[data-field],.row_group.error[data-field]", form).each(function() {
            var step = Number($(this).closest('[data-step]').attr('data-step'));

            minStep = Math.min(step, minStep)
        });

        if (minStep &gt; 0 &amp;&amp; minStep &lt; nSteps) {
            this.goTo(minStep);
        }
    }

    this.formSubmitted = function() {
        feProspectionFormSubmit(pf, form);
    }

    this.initForm = function() {
        // Create bullets
        for (var i = 1; i &lt;= nSteps; i++) {
            let el = $('&lt;div class="step_bullet"&gt;&lt;span class="step_text"&gt;' + i + '&lt;/span&gt;&lt;/div&gt;');
            el.attr('data-step-bullet', i);

            if (i == 1) {
                el.addClass('active_bullet done_bullet');
            }

            $(".steps_bullets", form).append(el);
        }

        $('.button_next, .button_prev, .button_send', form).on('click', function(e) {
            e.preventDefault();

            var step = Number($('.active_bullet', form).attr('data-step-bullet'));
            var stepContent = $('.steps_content &gt; [data-step="' + step + '"]', form);

            if ($(this).hasClass('button_next')) {
                var step = Number($('.active_bullet', form).attr('data-step-bullet'));
                var stepContent = $('.steps_content &gt; [data-step="' + step + '"]', form);

                if (pf.validateForm(stepContent)) {
                    globalEvent(form, 'prospectionBeforeNext', { step: step });
                    pf.goTo(step + 1);
                }
            } else if ($(this).hasClass('button_send')) {
                var btn = $(this);
                var save_and_continue = btn.hasClass('button_save_and_continue');
                if (pf.validateForm(stepContent)) {
                    submitAjaxForm(form, {
                        onError: function() {
                            pf.goToFirstError();
                            globalEvent(form, 'prospectionSubmitForm', {success: false});
                        },
                        onSuccess: function(res) {
                            $('[name="object_id"]', form).val(res['object_id']);
                            $('[name="user_id"]', form).val(res['user_id']);
                            globalEvent(form, 'prospectionSubmitForm', {success: true});
                            pf.formSubmitted();
                            if(save_and_continue) {
                                form.siblings('.messages').empty();
                            } 
                            if(!save_and_continue &amp;&amp; form.hasClass('hide_form') ) {
                                form.addClass('hide');
                            }
                        },
                        messagesTarget: form.siblings('.messages'),
                    });
                }
            } else {
                pf.goTo(step - 1, Direction.PREV);
            }
            if (!isIntegration) {
                setTimeout(function() { // wait for end of css transition
                    goTo(form, 400, 'swing'); //scroll function
                }, 500);
            }
        });

        pf.goTo(1);

        // Register changes
        form.find('.prospection_form_box.location input').on('change', function() {
            if ($(this).val()) {
                pf.geolocate();
            }
        });

        // update geolocation if focus on the first input; only once (equivalent to the "load" event)
        form.find('.prospection_form_box.location input').first().one('focus', function () {
            var $this = $(this);
            if ($this.val()) {
                $this.trigger('change');
            }
        });

        // trigger button next
        form.find('.prospection_form_box.location input').on('keypress', function(event) {
            var keycode = (event.keyCode ? event.keyCode : event.which);
            if(keycode == '13'){
                event.preventDefault();
                form.find('.button.button_next').trigger('click');
            }
        });

        onInputChange($('.row[data-field="prospection_object_address"] input', form), function(elem) {
            if (elem.val()) {
                pf.geolocate();
            }
        });

        onInputChange($('.row[data-field="object_address"] input', form), function(elem) {
            if (elem.val()) {
                pf.geolocate();
            }
        });

        $(".row_object_category_id input").each(function() {
            var input = $(this)
            var label = input.siblings("label");

            var requires = input.attr('data-requires').split(/\s*,\s*/).find(function(req) {
                return req.includes('subcategory_id');
            });

            if (requires) {
                //scroll to subcategory
                input.click(function () {
                    if (!isIntegration) {
                        goTo($('.subcategory', form), 400, 'swing'); //scroll function
                    }
                });

                $(requires + " input").each(function() {
                    var label = $(this).siblings("label");

                    label.click(function() {
                        pf.goTo(2);
                        if (!isIntegration) {
                            setTimeout(function() { // wait for end of css transition
                                goTo(form, 400, 'swing'); //scroll function
                            }, 500);
                        }
                    });
                });
            } else {
                // No subcategory, go to next step
                label.click(function() {
                    pf.goTo(2);
                    if (!isIntegration) {
                        setTimeout(function() { // wait for end of css transition
                            goTo(form, 400, 'swing'); //scroll function
                        }, 500);
                    }
                });
            }
        });

        // set tabindex for each text input
        pf.initTabindex();
    }

    /* Init */
    this.initForm();
}

function feProspectionFormSubmit(pf, form) {
    
}

function displayHideButtons(actions, target) {
    $('.button_next', actions).removeClass('hide');
    $('.button_send', actions).addClass('hide');
}

registerScriptLoader(function(parent) {

    $("form.prospection_form", parent).each(function() {
        var pf = new feProspectionForm($(this));
    })


    $('[data-field="object_house_subcategory_id"] [type="radio"], [data-field="object_appartment_subcategory_id"] [type="radio"]', parent).on('change', function() {
        $('.prospection_form_inner').addClass('visible');

        // as subcategory is required, we need to force unselected radio of other list to be checked
        var siblingsRow = $(this).parents('.row').siblings('.row.hide');
        var selectedRadio = siblingsRow.find('[type="radio"]:checked');

        if (selectedRadio.length &lt; 1) {
            siblingsRow.find('[type="radio"]:first').prop('checked', true);
        }
    });

    $('.prospection_form_box.location, .prospection_form_box.contact').each(function() {
        var parent = $(this);

        var zipCityWrapper = $('.autocomplete_zip_city', parent);
        var countryWrapper = $('[data-field$="country"]');

        var zipInput = $('input:first', zipCityWrapper);
        var cityInput = $('input:last', zipCityWrapper);

        var countryId = $('input[type="radio"]:checked', countryWrapper).val();
        parent.data('country_id', countryId);

        var posteInput = $('input[name="prospection_object_poste"]', parent);

        var isf = function(parent) {
            initSearchField(zipInput, {
                url: _rr.Search.localities(lang, '%q'),
                params: {
                    country_id: parent.data('country_id'),
                },
                onSelect: function(el, item) {
                    setTimeout(function() {
                        el.val(item.postalcode).change();
                    }, 1);
                    cityInput.val(item.city).change();
                    $('input[type="radio"][value="' + item.country_id + '"]', parent).prop('checked', true).change();
                    if (posteInput.length) {
                        posteInput.val(item.id);
                    }
                }
            });
        }

        isf(parent);

        $('input[type="radio"]', countryWrapper).on('change', function(e) {
            parent.data('country_id', $(this).val());
            isf(parent);
        });
    });
})

function CachedLocation () {
    // private properties

    var locationValue;

    // public methods

    this.set = function (value) {
        locationValue = JSON.stringify(value);
    };

    this.get = function () {
        return locationValue ? JSON.parse(locationValue) : null;
    };
}

function getLocationObj ($stepContent) {
    var location = {};
    location.postalcode = $stepContent.find('[name="prospection_object_postalcode"]').val();
    location.location = $stepContent.find('[name="prospection_object_location"]').val();
    location.address = $stepContent.find('[name="prospection_object_address"]').val();
    var $selectBox = $stepContent.find('[data-field="prospection_object_country"] &gt; .multiselect_box');
    location.country = getSelectValue($selectBox);

    return location;
}

$(function () {
    var cachedLocation = new CachedLocation();
    var $form = $('form.prospection_form');
    $form.on('prospectionBeforeNext', function (event, data) {
        var $stepContent = $('.steps_content &gt; [data-step="' + data.step + '"]', $form);
        if ($stepContent.hasClass('location')) {
            var locationObj = getLocationObj($stepContent);
            cachedLocation.set(locationObj);
        }
    });
});

/* /websites/base/js/components/map.js */
var initialInit = 0;

function feMap(canvas, options) {

    if (typeof maplibregl === 'undefined') {
        return;
    }

    options = $.extend({
        center:                { lng: canvas.attr('data-center-lng'), lat: canvas.attr('data-center-lat') },
        zoom:                  canvas.attr('data-zoom'),
        bounds:                undefined,
        autoZoom:              canvas.attr('data-autozoom'),
        maxZoom:               canvas.attr('data-maxzoom'),
        minZoom:               canvas.attr('data-minzoom'),
        paddingBoundaryTop:    Number(canvas.attr('data-padding-t-boundary')),
        paddingBoundaryBottom: Number(canvas.attr('data-padding-b-boundary')),
    }, options);

    options = extendOptions(mapOptBase, options, canvas, 'map');

    options.markers = $.extend({
        popup:  {},
        radius: "init", // "init"/"hover" Display radiuses as radiuses immediately, or on hover
    }, options.markers);
    
    const popupOnHighlight = canvas.is('[data-infobox-on-highlight]');
    const mapboxConfig = JSON.parse(canvas.attr('data-mapbox'));
    const markerImage = canvas.attr('data-marker-image');
    const markerImageHighlight = canvas.attr('data-marker-image-highlight');
    const markerImageHighlightDark = canvas.attr('data-marker-image-highlight-dark');
    const popupConfig = mapboxConfig['popup'];
    const markerConfig = mapboxConfig['marker'];
    const clusterConfig = mapboxConfig['cluster'];

    var map = this;
    map.search = null;
    map.from   = null;

    map.autoZoom = options.autoZoom;

    map.mb = new maplibregl.Map({
        container: canvas[0],
        style: _rr.Resources.file('plugins/stadiamaps/themes/'+options.theme+'.json'),
        center: options.center,
        zoom: options.zoom,
        bounds: options.bounds,
        localIdeographFontFamily: "'Noto Sans', 'Noto Sans CJK SC', sans-serif"
    });

    var container = canvas.closest(".map_container");
    var hoveredStateId = null;
    var radiusStateId = null;
    var radiusZoom = 13;

    var popup_sec = 350;
    var popupFeatureID = null;
    var markerHoveredArea = {
        'marker' : false,
        'radius' : false,
        'popup' : false,
    }

    var closePopupActions = function() {
        if (!markerHoveredArea['marker'] &amp;&amp; !markerHoveredArea['radius'] &amp;&amp; !markerHoveredArea['popup']) {
            resetHoverState();
            resetRadiusState();
            popup.remove();
        }
    }

    map.inPopup = false;
    map.displayPopup = true;
    map.markers = [];

    var timeoutpopup = null;

    const popup = new maplibregl.Popup({
        closeButton: isTouchScreenDevice,
        closeOnClick: false,
        closeOnMove: true,
        maxWidth: popupConfig['max-width'],
        className: isTouchScreenDevice ? 'touchscreen' : ''
    });

    var points = {
        "type": "FeatureCollection",
        "features": [],
    };
    var circles = {
        "type": "FeatureCollection",
        "features": [],
    };
    var circlesHover = {
        "type": "FeatureCollection",
        "features": [],
    };
    var highlights = {
        "type": "FeatureCollection",
        "features": [],
    };

    var cluster_step = [
        'step',
        ['get', 'point_count'],
    ];
    var steps = clusterConfig['steps'];
    steps.forEach((step) =&gt; {
        if (step != 0) {
            cluster_step.push(step);
        }
    });

    map.mb.on('load', async function() {

        /********* MARKER SOURCES ********/
        //when hovering a marker, if the real position is not exact, show a circle of the area.
        map.mb.addSource('circles_hover_src', {
            type: "geojson",
            data: {
                "type": "FeatureCollection",
                "features": [],
            },
        });
        //show an area instead of a precise marker position (used in the detail of an object for example)
        map.mb.addSource('circles_src', {
            type: "geojson",
            data: {
                "type": "FeatureCollection",
                "features": [],
            },
        });
        //show the marker with an highlighted style, separated to markers source to be able to show the highlighted marker on top of the others.
        map.mb.addSource('highlights_src', {
            type: "geojson",
            data: {
                "type": "FeatureCollection",
                "features": [],
            },
        });
        //markers
        map.mb.addSource('markers', {
            type: 'geojson',
            data: {
                "type": "FeatureCollection",
                "features": [],
            },
            generateId: true,
            cluster: clusterConfig['enabled'],
            clusterMaxZoom: 14, // Max zoom to cluster points on
            clusterRadius: 30, // Radius of each cluster when clustering points
            clusterProperties: { //add number to cluster if marker contain multiple objects
                "sum": [
                    "+", ["get", "objects"]
                ]
            },
        });
        /********* END MARKER SOURCES ********/

        /********* LOAD MARKER IMAGE ********/
        //default marker in 'symbol' mode
        let marker_image = await map.mb.loadImage(markerImage);
        map.mb.addImage('marker_custom', marker_image.data);

        if (markerConfig['mode'] == 'symbol' &amp;&amp; markerConfig['highlight']['custom_symbol']) {
            //if dark theme, we must add marker_highlight_dark.png in the customer folder
            var imageHighlight = markerImageHighlight;
            if (options.theme == 'alidade_smooth_dark') {
                imageHighlight = markerImageHighlightDark;
            }
            //highlighted marker in 'symbol' mode
            let marker_hh_image = await map.mb.loadImage(imageHighlight);
            map.mb.addImage('marker_custom_highlight', marker_hh_image.data);
        }
        /********* END LOAD MARKER IMAGE ********/

        /********* DEFINE LAYERS ********/
        //layer for circle area marker
        map.mb.addLayer({
            "id":     "circles",
            "source": "circles_src",
            "type":   "circle",
            "paint": {
                "circle-radius": 
                     ['interpolate', ['exponential', 2], ['zoom'],
                            0, 0,
                            20, ['number', ['get', 'radius']],
                          ],
                "circle-opacity": 0.3,
                "circle-color": canvas.attr('data-radius-color'),
            }
        });
        //layer for circle area on hovered marker that doesn't have an exact position
        map.mb.addLayer({
            "id":     "circles_hover",
            "source": "circles_hover_src",
            "type":   "circle",
            "paint": {
                "circle-radius": [
                    'interpolate', ['exponential', 2], ['zoom'],
                        0, 0,
                        20, ['number', ['get', 'radius']],
                    ],
                'circle-opacity': [
                    'step', ['zoom'],
                    0,
                    radiusZoom, 
                    0.3
                ],
                "circle-color":  canvas.attr('data-radius-color-hover'),
            }
        });

        //layer for cluster (multiple objects that explode on zoom)
        map.mb.addLayer({
            id: 'clusters',
            type: 'circle',
            source: 'markers',
            filter: ['has', 'point_count'],
            paint: {
                'circle-color': [
                    'case',
                    ['boolean', ['feature-state', 'hover'], false],
                    clusterConfig['hover']['background'],
                    clusterConfig['default']['background'],
                ],
                'circle-radius': cluster_step,
                'circle-stroke-width': clusterConfig['default']['border']['width'],
                'circle-stroke-color': [
                    'case',
                    ['boolean', ['feature-state', 'hover'], false],
                    clusterConfig['hover']['border']['color'],
                    clusterConfig['default']['border']['color'],
                ]
            }
        });

        //layer for number inside the cluster (number of objects inside the cluster)
        map.mb.addLayer({
            id: 'cluster-count',
            type: 'symbol',
            source: 'markers',
            filter: ['has', 'point_count'],
            layout: {
                'text-allow-overlap' : true,
                'text-field': ['get', 'sum'],
                'text-font':  clusterConfig['text']['font'],
                'text-size': clusterConfig['text']['size']
            },
            paint: {
                'text-color': [
                    'case',
                    ['boolean', ['feature-state', 'hover'], false],
                    clusterConfig['hover']['text']['color'],
                    clusterConfig['default']['text']['color'],
                ]
            }
        });

        let unclustered_targets = ['unclustered-point'];

        //filter : show marker that are not in cluster and depend of the config show marker that doesn't have multiple object on the same position
        let unclusterFilter = ['!', ['has', 'point_count']];
        if (markerConfig['multiple_as_cluster'] &amp;&amp; clusterConfig['enabled']) {
            unclusterFilter = ['all', ['!', ['has', 'point_count']], ['&lt;=', ['get', 'objects'], 1]];
        }
        var unclusterOptions = {
            id: 'unclustered-point',
            type: markerConfig['mode'],
            source: 'markers',
            filter: unclusterFilter
        }
        var highlightsOptions = {
            id: 'highlights',
            type: markerConfig['mode'],
            source: 'highlights_src',
        }

        if (markerConfig['mode'] == 'symbol') {
            unclusterOptions['layout'] = {
                'icon-image': 'marker_custom',
                'icon-size': markerConfig['size'],
                'icon-allow-overlap': true,
                'icon-anchor': 'bottom',
            };
            unclusterOptions['paint'] = {
                'icon-opacity': [
                    'case',
                    ['boolean', ['feature-state', 'radius'], false], 
                    0,
                    1
                ]
            };

            highlightsOptions['layout'] = {
                'icon-image':  (markerConfig['mode'] == 'symbol' &amp;&amp; markerConfig['highlight']['custom_symbol']) ? 'marker_custom_highlight' : 'marker_custom',
                'icon-size': markerConfig['size'],
                'icon-allow-overlap': true,
                'icon-anchor': 'bottom',
            };
        } else if (markerConfig['mode'] == 'circle') {
            unclusterOptions['paint'] = {
                'circle-color': [
                    'case',
                    ['boolean', ['feature-state', 'hover'], false],
                    ['get', 'color_background_hover'],
                    ['get', 'color_background'],
                ],
                'circle-radius': markerConfig['size'],
                'circle-stroke-width': markerConfig['default']['border']['width'],
                'circle-stroke-color': [
                    'case',
                    ['boolean', ['feature-state', 'hover'], false],
                    ['get', 'color_border_hover'],
                    ['get', 'color_border'],
                ],
                'circle-opacity': [
                    'case',
                    ['boolean', ['feature-state', 'radius'], false], 
                    0,
                    1
                ],
                'circle-stroke-opacity': [
                    'case',
                    ['boolean', ['feature-state', 'radius'], false], 
                    0,
                    1
                ]
            };

            highlightsOptions['paint'] = {
                'circle-radius': markerConfig['size'],
                'circle-color': ['get', 'color_background'],
                'circle-stroke-width': markerConfig['highlight']['border']['width'],
                'circle-stroke-color': ['get', 'color_border'],
                'circle-opacity': [
                    'step',
                    ['zoom'],
                    1,
                    radiusZoom,
                    ["case", ["==", ["get", "hasRadius"], false], 1, 0],
                ],
                'circle-stroke-opacity': [
                    'step',
                    ['zoom'],
                    1,
                    radiusZoom,
                    ["case", ["==", ["get", "hasRadius"], false], 1, 0],
                ],
            };
        }

        map.mb.addLayer(unclusterOptions);

        //show marker that is not in cluster but contain more than one object at the same position to display it as a small cluster (only style not the behaviour)
        if (markerConfig['multiple_as_cluster'] &amp;&amp; clusterConfig['enabled']) {
            var unclusterMultipleOptions = {
                id: 'unclustered-multiple-point',
                type: 'circle',
                source: 'markers',
                filter: ['all', ['!', ['has', 'point_count']], ['&gt;=', ['get', 'objects'], 2]],
                paint: {
                    'circle-color': [
                        'case',
                        ['boolean', ['feature-state', 'hover'], false],
                        clusterConfig['hover']['background'],
                        clusterConfig['default']['background'],
                    ],
                    'circle-radius': 12,
                    'circle-stroke-width': clusterConfig['default']['border']['width'],
                    'circle-stroke-color': [
                        'case',
                        ['boolean', ['feature-state', 'hover'], false],
                        clusterConfig['hover']['border']['color'],
                        clusterConfig['default']['border']['color'],
                    ],
                    'circle-opacity': [
                        'case',
                        ['boolean', ['feature-state', 'radius'], false], 
                        0,
                        1
                    ],
                    'circle-stroke-opacity': [
                        'case',
                        ['boolean', ['feature-state', 'radius'], false], 
                        0,
                        1
                    ]
                },
            }
            var unclusterMultipleSymbolOptions = {
                id: 'unclustered-multiuple-point-count',
                type: 'symbol',
                source: 'markers',
                minZoom: 0,
                maxZoom: 24,
                filter: ['all', ['!', ['has', 'point_count']], ['&gt;=', ['get', 'objects'], 2]],
                layout: {
                    'text-allow-overlap' : false,
                    'text-field': ['get', 'objects'],
                    'text-font':  ['Stadia Bold'],
                    'text-size' : 13,
                },
                paint : {
                    'text-color': [
                        'case',
                        ['boolean', ['feature-state', 'hover'], false],
                        clusterConfig['hover']['text']['color'],
                        clusterConfig['default']['text']['color'],
                    ],
                    'text-opacity': [
                        'case',
                        ['boolean', ['feature-state', 'radius'], false], 
                        0,
                        1
                    ]
                }
            }
            map.mb.addLayer(unclusterMultipleOptions);
            map.mb.addLayer(unclusterMultipleSymbolOptions);
            unclustered_targets.push('unclustered-multiple-point');
        }

        map.mb.addLayer(highlightsOptions);

        //move highlight on top of others layouts
        map.mb.moveLayer('highlights'); 
        /********* END LAYERS ********/

        /********* EVENTS ON MAP / MARKER *********/
        //inspect a cluster on click
        map.mb.on('click', 'clusters', async (e) =&gt; {
            const features = map.mb.queryRenderedFeatures(e.point, {
                layers: ['clusters']
            });
            const clusterId = features[0].properties.cluster_id;
            const zoom = await map.mb.getSource('markers').getClusterExpansionZoom(clusterId);

            map.mb.easeTo({
                center: features[0].geometry.coordinates, zoom
            });
        });
        map.mb.on('mousemove', 'clusters', (e) =&gt; {
            if (e.features.length &gt; 0) {
                setHoverState(e.features[0].id);
            }
        });
        map.mb.on('mouseleave', 'clusters', () =&gt; {
            resetHoverState();
        });
        map.mb.on('mouseenter', 'circles_hover', () =&gt; {
            markerHoveredArea['radius'] = true;
        });
        map.mb.on('mousemove', 'circles_hover', () =&gt; {
            markerHoveredArea['radius'] = true;
        });
        map.mb.on('mouseleave', 'circles_hover', () =&gt; {
            markerHoveredArea['radius'] = false;
            timeoutpopup = setTimeout(closePopupActions, popup_sec);
        });

        unclustered_targets.forEach(function (uncluster_item) {
            // When the user moves their mouse over the state-fill layer, we'll update the
            // feature state for the feature under the mouse.
            map.mb.on('mousemove', uncluster_item, (e) =&gt; {
                if (e.features.length &gt; 0) {
                    markerHoveredArea['marker'] = true;
                    setHoverState(e.features[0].id);
                }
            });

            var eventType = isTouchScreenDevice ? 'click' : 'mouseenter';
            map.mb.on(eventType, uncluster_item, (e) =&gt; {
                markerHoveredArea['marker'] = true;
                map.mb.getCanvas().style.cursor = 'pointer';

                const coordinates = e.features[0].geometry.coordinates.slice();
                const marker = JSON.parse(e.features[0].properties.marker);
                    
                // Ensure that if the map is zoomed out such that multiple
                // copies of the feature are visible, the popup appears
                // over the copy being pointed to.
                while (Math.abs(e.lngLat.lng - coordinates[0]) &gt; 180) {
                    coordinates[0] += e.lngLat.lng &gt; coordinates[0] ? 360 : -360;
                }

                showRadius(marker);
                setRadiusState(e.features[0]);
                if (!popup.isOpen() || popup.isOpen() &amp;&amp; popupFeatureID != e.features[0].id) {
                    popupFeatureID = e.features[0].id;
                    openPopup(marker, coordinates);
                }
            });

            map.mb.on('mouseleave', uncluster_item, () =&gt; {
                markerHoveredArea['marker'] = false;
                timeoutpopup = setTimeout(closePopupActions, popup_sec);
            });
        });
        /********* END EVENTS ON MAP / MARKER *********/

        // disable focus on navigation controls
        if (container.find('.maplibregl-ctrl button').length) {
            container.find('.maplibregl-ctrl button').attr('tabindex', '-1');
        }
    });

    /********* FUNCTIONS *********/

    //open the mapbox popup
    function openPopup(marker, coordinates) {
        if ('html' in marker) {
            popup
            .setLngLat(coordinates)
            .setHTML(marker.html)
            .on('open', initMaboxPopop)
            .addTo(map.mb);
        } else if (callback = options.markers.popup.html) {
            if (map.displayPopup) {
                callback(marker, function(html) {
                    popup
                    .setLngLat(coordinates)
                    .setHTML(html)
                    .on('open', initMaboxPopop)
                    .addTo(map.mb);
                });
            }
        }
    }

    //add a circle area in the related source only if the marker doesn't have an exact position
    function showRadius(marker) {
        resetRadiusState();
        if (options.markers.radius == 'hover' &amp;&amp; 'radius' in marker &amp;&amp; marker.radius != null) {
            circlesHover.features = [{
                type: "Feature",
                geometry: {
                    type: "Point",
                    coordinates: [marker.coords.lng, marker.coords.lat],
                },
                properties: {
                    radius: metersToPixelsAtMaxZoom(marker.radius, marker.coords.lat)
                },
            }];

            map.mb.getSource('circles_hover_src').setData(circlesHover);
        }
    }

    //add a marker to highlight the selected marker under some condition
    function showHighlight(marker) {
        //add a properties to know if we need to hide the highlight marker when a circle area is displayed
        var hasRadiusHover = false;
        if (options.markers.radius == 'hover' &amp;&amp; 'radius' in marker &amp;&amp; marker.radius != null) {
            hasRadiusHover = true;
        }

        //we want to highlight marker that is not in a cluster otherwise we let the default behaviour of the cluster 
        if (marker.objects &lt;= 1 || (marker.objects &gt; 1 &amp;&amp; !markerConfig['multiple_as_cluster'] &amp;&amp; !clusterConfig['enabled'])) {
            highlights.features = [{
                type: "Feature",
                geometry: {
                    type: "Point",
                    coordinates: [marker.coords.lng, marker.coords.lat],
                },
                properties: {
                    hasRadius: hasRadiusHover,
                    color_border: marker.color_highlight.border,
                    color_background: marker.color_highlight.background, 
                }
            }];
            map.mb.getSource('highlights_src').setData(highlights);
        }
    }

    /********* END FUNCTIONS *********/

    /********* FEATURE STATES **************/
    function resetHoverState() {
        if (hoveredStateId !== null) {
            map.mb.setFeatureState(
                { source: 'markers', id: hoveredStateId },
                { hover: false }
            );
        }
        hoveredStateId = null;
    }

    function setHoverState(id) {
        if (hoveredStateId !== null) {
            map.mb.setFeatureState(
                { source: 'markers', id: hoveredStateId },
                { hover: false }
            );
        }
        hoveredStateId = id;
        map.mb.setFeatureState(
            { source: 'markers', id: hoveredStateId },
            { hover: true }
        );
    }

    function resetRadiusState() {
        if (radiusStateId !== null) {
            map.mb.setFeatureState(
                { source: 'markers', id: radiusStateId },
                { radius: false }
            );
        }
        radiusStateId = null;

        circlesHover.features = [];
        if (map.mb._loaded) {
            map.mb.getSource('circles_hover_src').setData(circlesHover);
        }
    }

    function setRadiusState(feature) {
        if (radiusStateId !== null) {
            map.mb.setFeatureState(
                { source: 'markers', id: radiusStateId },
                { radius: false }
            );
        }

        if (map.mb.getZoom() &gt;= radiusZoom &amp;&amp; feature.properties.exact == false) {
            radiusStateId = feature.id;
            map.mb.setFeatureState(
                { source: 'markers', id: radiusStateId },
                { radius: true }
            );
        }
    }

    /********* END FEATURE STATES **************/

    function initMaboxPopop(e) {
        var popupEl = $(e.target._content);
        popupEl.parent().addClass('infobox infobox-mapbox');
        loadScripts(popupEl);

        var swiperEl = popupEl.find('.swiper');
        if (swiperEl.length){
            var external_nav = $('.swiper_external_nav[data-swiper-action]', popupEl);
            var s = swiperEl[0].swiper;

            external_nav.on('click', function() {
                 swiperAction(s, $(this).attr('data-swiper-action'));
            });
        }
        popupEl.on('mouseenter', function () {
            markerHoveredArea['popup'] = true;
        });
        popupEl.on('mouseleave', function () {
            markerHoveredArea['popup'] = false;
            timeoutpopup = setTimeout(closePopupActions, popup_sec);
        });
        document.activeElement.blur();
    }

    map.mb.on("dragstart", event =&gt; {
        if (isTouchScreenDevice) {
            const isTwoFingerTouch = event.originalEvent.touches.length &gt;= 2;
            if (!isTwoFingerTouch) {
                map.mb.dragPan.disable();
            }
        }
    });

    map.mb.on("touchstart", event =&gt; {
        if (isTouchScreenDevice) {
            const isTwoFingerTouch = event.originalEvent.touches.length &gt;= 2;
            if (isTwoFingerTouch) {
                map.mb.dragPan.enable();
            }
        }
    });

    if (!options.allowScrollZoom) {
        map.mb.scrollZoom.disable();
    }

    var controlPos = canvas.attr('data-control-position');
    if (controlPos == undefined) {
        controlPos = 'top-right';
    }
    map.mb.addControl(new maplibregl.NavigationControl(), controlPos);

    this.markers = [];

    this.whenLoaded = function(f) {
        if (map.mb.loaded()) {
            f();
        } else {
            map.mb.on('load', f);
        }
    }
    this.whenIdleOnce = function(f) {
        if (isMapIdle(map.mb)) {
            f();
        } else {
            map.mb.once('idle', f);
        }
    }

    function isMapIdle(map) {
        const sourcesLoaded = Object.keys(map.style.sourceCaches).every((sourceId) =&gt;
            map.isSourceLoaded(sourceId)
        );
        return map.loaded() &amp;&amp; sourcesLoaded;
    }

    function  metersToPixelsAtMaxZoom(meters, latitude) {
        return meters / 0.075 / Math.cos(latitude * Math.PI / 180)
    }

    this.setMarkers = function (markers, bounds, fitBounds = true) {
        var loaded = false;

        if (bounds) {
            bounds = new maplibregl.LngLatBounds(
                new maplibregl.LngLat(bounds.sw.lng, bounds.sw.lat),
                new maplibregl.LngLat(bounds.ne.lng, bounds.ne.lat)
            );
        }

        points.features = [];
        circles.features = [];

        markers.forEach(function(m) {

            if (map.autoZoom != 'never' &amp;&amp; m.coords &amp;&amp; !bounds) {
                if((map.autoZoom == 'always' || map.autoZoom == 'init') &amp;&amp; initialInit == 0){
                        bounds = new maplibregl.LngLatBounds(m.coords, m.coords);
                }
            }

            //marker as circle area (not exact position)
            if (options.markers.radius == 'init' &amp;&amp; ('radius' in m) &amp;&amp; m.radius &gt; 0) {
                circles.features.push({
                    type: "Feature",
                    geometry: {
                        type: "Point",
                        coordinates: [m.coords.lng, m.coords.lat],
                    },
                    properties: {
                        radius: metersToPixelsAtMaxZoom(m.radius, m.coords.lat)
                    },
                });
            } else {
                if (m.color == undefined) {
                    m.color = {
                        'background' : markerConfig['default']['background'],
                        'border' : markerConfig['default']['border']['color'],
                    };
                    m.color_hover = {
                        'background' : markerConfig['hover']['background'],
                        'border' : markerConfig['hover']['border']['color'],
                    };
                }

                if ('onDragEnd' in m || 'label' in m || m.isHTML || mapboxConfig['force_html_marker']) {//HTML marker
                    var markerEl = document.createElement('div');
                    
                    if (('exact' in m) &amp;&amp; !m.exact) {
                        markerEl.className = 'marker vague';
                    } else {
                        markerEl.className = 'marker';
                    }
                    markerEl.className += ' no_svg';

                    if ('className' in m) {
                        markerEl.className += ' '+m.className;
                    }

                    if (m.label) {
                        markerEl.innerHTML = ' '+m.label;
                    }

                    markerEl.addEventListener('mouseenter', () =&gt; {
                        openPopup(m, m.coords);
                    });
                    markerEl.addEventListener('mouseleave', () =&gt; {
                        popup.remove();
                    });

                    var marker = new maplibregl.Marker({element: markerEl}).setLngLat(m.coords);
                    if (m.onDragEnd) {
                        marker.setDraggable(true);

                        marker.on('dragend', function() {
                            m.onDragEnd(marker);
                        });
                    }
                    marker.addTo(map.mb);
                } else { //layer marker
                    var nbObjects = m.objects == undefined ? 1 : m.objects;
                    points.features.push({
                        type: "Feature",
                        geometry: {
                            type: "Point",
                            coordinates: [m.coords.lng, m.coords.lat],
                        },
                        properties: {
                            marker: m,
                            ids: m.ids,
                            color_background: m.color.background,
                            color_background_hover: m.color_hover.background, 
                            color_border: m.color.border,
                            color_border_hover: m.color_hover.border, 
                            objects: nbObjects,
                            exact: m.exact
                        },
                    });
                }
            }
        });

        var boundsPadding = Object.assign({}, options.boundsPadding);

        var scrollTop = $(window).scrollTop();
        var mapPosTop = canvas.offset().top;

        if (canvas.parents('.search_results_list_and_map').length &amp;&amp; canvas.attr('data-padding-b-bounds-dyn') != undefined) {
            var paddingBottom = mapPosTop - scrollTop;
            var isVisibleEnough = (mapPosTop &lt; $(window).height()/2);
            if (paddingBottom &gt; 0 &amp;&amp; isVisibleEnough) {
                boundsPadding['bottom'] +=  paddingBottom;
            }
        }

        map.whenIdleOnce(function() {
            map.mb.getSource('circles_src').setData(circles);
            map.mb.getSource('circles_hover_src').setData(circlesHover);
            map.mb.getSource('markers').setData(points);
        });

        map.whenLoaded(function() {
            if (bounds &amp;&amp; map.autoZoom != 'never') {
                if ((map.autoZoom == 'always' || map.autoZoom == 'init') &amp;&amp; initialInit == 0 &amp;&amp; fitBounds) {
                    map.mb.fitBounds(bounds, {
                        padding: boundsPadding,
                        maxZoom: options.maxZoom,
                    });

                    map.mb.once('idle', function() {
                        loaded = true;
                    });
                }
            }
        });
    }

    //function called when highlight to determine if are in a cluster / marker and if we need to open the popup
    function checkIds(ids, feature, cluster) {
        var featureID = null;
        if (feature._vectorTileFeature) {
            featureID = feature._vectorTileFeature.id;
        } else {
            featureID = cluster._vectorTileFeature.id;
        }
        var match = false;
        $(ids).each(function (k, id) {
            if (feature.properties.ids.includes(id)) {
                setHoverState(featureID);
                if (cluster == null) {
                    const coordinates = feature.geometry.coordinates.slice();
                    const marker = JSON.parse(feature.properties.marker);
                    if (popupOnHighlight) {
                        if (!popup.isOpen() || popup.isOpen() &amp;&amp; popupFeatureID != featureID) {
                            popupFeatureID = featureID;
                            openPopup(marker, coordinates);
                        }
                    }

                    showHighlight(marker);
                    showRadius(marker);
                    setRadiusState(feature);
                }
                match = true;
                return false;
            }
        });

        return match;
    }

    this.highlightMarkers = function(ids, active) {

        circlesHover.features = [];
        highlights.features = [];

        clearTimeout(timeoutpopup);
        popup.remove();

        resetRadiusState();
        resetHoverState();

        if (map.mb._loaded) {
            map.mb.getSource('highlights_src').setData(highlights);
        }

        if (active) {
            $(map.mb.querySourceFeatures('markers')).each(function (k, f) {
                if (f.properties.cluster) {
                    map.mb.getSource('markers').getClusterLeaves(f.properties.cluster_id, f.properties.point_count, 0, callback = function(error, features) {
                        $(features).each(function (k, cf) {
                            if (checkIds(ids, cf, f)) {
                                return false;
                            }
                        });
                    });
                } else {
                    if (checkIds(ids, f, null)) {
                        return false;
                    }
                }
            });
        }

        map.whenLoaded(function() {
            map.mb.getSource('circles_hover_src').setData(circlesHover);
            map.mb.getSource('highlights_src').setData(highlights);
        });
    }

    this.onBoundsChange = function(cb) {
        map.mb.on('moveend', function() {
            var b  = map.mb.getBounds();
            var ne = b.getNorthEast();
            var sw = b.getSouthWest();
            cb({
                lat: ne.lat,
                lng: ne.lng,
            }, {
                lat: sw.lat,
                lng: sw.lng,
            });
        });
    }


    var from = undefined;
    var initMarkers = [];

    $(".map_markers &gt; .map_marker", container).each(function() {
        var el = $(this);

        var marker = {
            coords: {
                lat: parseFloat(el.attr("data-lat")),
                lng: parseFloat(el.attr("data-lng")),
            },
            el: el,
        }
        if (el.attr('data-exact')) {
            marker.exact = el.attr('data-exact');
        }
        if (el.attr('data-radius')) {
            marker.radius = el.attr('data-radius');
        }
        if (el.attr('data-url')) {
            marker.url = el.attr('data-url');
        }
        if (el.attr('data-html')) {
            marker.html = el.attr('data-html');
        } else if (el.html() != '') {
            marker.html = el.html();
        }
        if (el.attr('data-class')) {
            marker.className = el.attr('data-class');
        }
        if (el.attr('data-ids')) {
            marker.ids = el.attr('data-ids').split(',');
        }
        if (el.attr('data-offsets')) {
            marker.offsets = el.attr('data-offsets').split(',');
        }
        if (el.attr('data-label')) {
            marker.label = el.attr('data-label');
        }
        if (el.parents('.cms_map[data-mode]').length || el.attr('data-marker-mode') == 'html') {
            marker.isHTML = true;
        }

        initMarkers.push(marker);
    });

    if (initMarkers.length) {
        this.setMarkers(initMarkers);
    }
}

$("div.theme_swither a").click(function(){
    var theme = $(this).attr("data-theme");
    createCookie('mapTheme', theme, 3600 * 24 * 365);
    window.location.reload();
});
</pre></body></html>