PageSourceSearch

https://cookecitystore.com/wp-content/plugins/simply-rets/assets/js/simply-rets-client.js?ver=7.1.2

js cookecitystore.com collected 2026-10-06 13:22:15 UTC 25,027 bytes, 942 lines download raw bytes

1/**
2 *
3 * simply-rets-client.js - Copyright (c) 2014-2015 SimplyRETS
4 *
5 * This file provides the client side javascript for the
6 * SimplyRETS Wordpress plugin.
7 *
8 * License: GPLv3 (http://www.gnu.org/licenses/gpl.html)
9 *
10**/
11
12
13var $_ = jQuery; // reassign jQuery
14
15
16/* Single Listing Details Image Slider (Classic) */
17var classicGalleryToggle = function() {
18
19    $_(".sr-slider-input").click(function() {
20
21        var imgSrc = $_("input[name='slide_switch']:checked").val();
22        var imgAct = $_(".sr-slider-img-act");
23
24        imgAct.fadeOut("fast", function() {
25
26            imgAct.attr('src', imgSrc);
27            imgAct.fadeIn("fast");
28
29        });
30
31    });
32
33};
34
35
36/* Open/Close Listing Image Gallery (Classic) */
37var classicGalleryTextToggle = function() {
38
39    $_('#sr-toggle-gallery').click(function() {
40        $_('.sr-slider label').toggle(100);
41        if($_(this).text() == 'Hide photos') {
42            $_(this).text('Show more photos');
43        } else {
44            $_(this).text('Hide photos');
45        }
46    });
47
48};
49
50
51/** Hide 'Amenities' in advanced search form when "Land" is selected */
52var advSearchFormToggler = function() {
53
54    if($_('#sr-search-ptype select').val() == 'Land') {
55        $_('.sr-adv-search-amenities-wrapper').hide();
56    }
57
58    $_('#sr-search-ptype select').change(function() {
59        if($_(this).val() == 'Land') {
60            $_('.sr-adv-search-amenities-wrapper').hide();
61            $_('input[name="sr_features[]"]').each(function() {
62                $_(this).attr('checked', false);
63            });
64        } else {
65            $_('.sr-adv-search-amenities-wrapper').show();
66        }
67    });
68
69};
70
71
72
73/** [sr_listings_slider] default number of items */
74var listingSliderCarousel = function() {
75
76    $_(".sr-listing-carousel").each(function() {
77        $_(this).owlCarousel({ items: 4 })
78    });
79
80}
81
82
83var scrollToAnchor = function(aid) {
84    var aTag = $_("#"+ aid);
85    $_('html,body').animate({scrollTop: aTag.offset().top},'slow');
86}
87
88
89var buildPrettyLink = function(mlsId, address, root, vendor) {
90    return root
91         + "/listings/"
92         + mlsId + "/"
93         + address
94         + (vendor ? ("?sr_vendor=" + vendor) : "");
95}
96
97var buildUglyLink = function(mlsId, address, root, vendor) {
98    return root
99         + "?sr-listings=sr-single"
100         + "&listing_id=" + mlsId
101         + "&listing_title=" + address
102         + (vendor ? ("&sr_vendor=" + vendor) : "");
103}
104
105var normalizeListingPhotoUrl = function(url) {
106    var forceHttps = document
107        .getElementById("sr-map-search")
108        .dataset
109        .forceImageHttps
110
111    if (forceHttps) {
112        return url.replace(/^http:\/\//i, 'https://')
113    } else {
114        return url
115    }
116}
117
118
119var genMarkerPopup = function(
120    listing,
121    linkStyle,
122    siteRoot,
123    idxImg,
124    officeOnThumbnails,
125    agentOnThumbnails,
126    statusText,
127    mlsTrademark,
128    vendor
129) {
130
131    var stat  = statusText ? listing.mls.statusText : listing.mls.status;
132    var mlsText = Boolean(mlsTrademark) ? "MLS®" : "MLS"
133    var beds  = listing.property.bedrooms  || "n/a";
134    var baths = getBathroomsDisplay();
135    var style = listing.property.style     || "Res" ;
136    var type  = listing.property.type      || "Res";
137    var sqft  = listing.property.area      || "n/a";
138    var mlnum = listing.listingId          || "n/a";
139    var price = listing.listPrice          || "Unknown";
140    var addr  = listing.address.full       || "Unknown";
141    var photo = listing.photos.length > 1
142              ? normalizeListingPhotoUrl(listing.photos[0])
143              : 'https://s3-us-west-2.amazonaws.com/simplyrets/trial/properties/defprop.jpg';
144    var office = officeOnThumbnails && listing.office.name
145               ? listing.office.name
146               : ""
147    var agent = agentOnThumbnails && listing.agent.firstName
148               ? listing.agent.firstName + ' ' + listing.agent.lastName
149               : ""
150
151    var link = linkStyle === "pretty"
152             ? buildPrettyLink(listing.mlsId, listing.address.full, siteRoot, vendor)
153             : buildUglyLink(listing.mlsId, listing.address.full, siteRoot, vendor);
154
155    var markup = '' +
156       '<div class="sr-iw-inner">' +
157       '  <h4 class="sr-iw-addr">' + addr + '<small> $' + price + '</small></h4>' +
158       '  <div class="sr-iw-inner__img">' +
159       '    <a href="' + link + '">' +
160       '      <img id="sr-iw-inner__img-img" src="' + photo +'">' +
161       '    </a>' +
162       '  </div>' +
163       '  <div class="sr-iw-inner__primary">' +
164       '    <p>' + beds + ' Beds | ' + baths + ' | ' + stat + '</p>' +
165       '  </div>' +
166       '  <hr>' +
167       '  <div class="sr-iw-inner__secondary">' +
168       '    <p><strong>Price: </strong>$' + price + '</p>' +
169       '    <p><strong>' + mlsText + ' #: </strong>' + mlnum + '</p>' +
170       '    <p><strong>Area: </strong>' + sqft + '</p>' +
171       '    <p><strong>Property Type: </strong>' + type + '</p>' +
172       '    <p><strong>Property Style: </strong>' + style + '</p>' +
173       (office ? '<p><strong>Listing office: </strong>'+ office + '</p>' : '') +
174       (agent ? '<p><strong>Listing agent: </strong>'+ agent + '</p>' : '') +
175       '    <img src="' + idxImg + '"/>' +
176       '  </div>' +
177       '  <hr>' +
178       '  <div class="sr-iw-inner__view-details">' +
179       '    <a class="sr-iw-inner__details-link" href="' + link + '">View Details</a>' +
180       '  </div>' +
181       '</div>';
182
183    return markup;
184
185    function getBathroomsDisplay() {
186        if (listing.property.bathrooms) {
187            var s = listing.property.bathrooms > 1 ? "s" : "";
188            return listing.property.bathrooms + " Bath" + s;
189        } else if (listing.property.bathsFull) {
190            var s = listing.property.bathsFull > 1 ? "s" : "";
191            return listing.property.bathsFull + " Full Bath" + s;
192        } else {
193            return "n/a Baths";
194        }
195    }
196}
197
198
199var makeMapMarkers = function(
200    map,
201    listings,
202    linkStyle,
203    siteRoot,
204    idxImg,
205    officeOnThumbnails,
206    agentOnThumbnails,
207    statusText,
208    mlsTrademark,
209    vendor
210) {
211
212    var markers = [];
213    var bounds  = new google.maps.LatLngBounds();
214
215    $_.each(listings, function(idx, listing) {
216
217        var lat = listing.geo.lat,
218            lng = listing.geo.lng;
219
220        if(lat && lng) {
221
222            var bound  = new google.maps.LatLng(listing.geo.lat, listing.geo.lng);
223
224            var popup  = genMarkerPopup(
225                listing,
226                linkStyle,
227                siteRoot,
228                idxImg,
229                officeOnThumbnails,
230                agentOnThumbnails,
231                statusText,
232                mlsTrademark,
233                vendor
234            );
235
236            var window = new google.maps.InfoWindow({
237                content: popup
238            });
239
240            var marker = new google.maps.Marker({
241                position: bound,
242                map: map,
243                title: listing.address.full
244            });
245
246            marker.addListener('click', function() {
247                if(window.getMap()) {
248                    window.close(map, marker);
249                } else {
250                    window.open(map, marker);
251                }
252            });
253
254            bounds.extend(bound);
255            markers.push(marker);
256        }
257
258    });
259
260    return {
261        bounds:   bounds,
262        markers:  markers,
263    }
264
265}
266
267
268var replaceListingMarkup = function(markup) {
269    var root = $_('.sr-map-search-list-view');
270    if(root.length)
271        root.html(markup);
272}
273
274
275var updatePagination = function(that) {
276
277    var prevEl = null,
278        nextEl = null,
279        pagWrapper = $_('.sr-pagination');
280
281    if(pagWrapper.length) {
282
283        pagWrapper.empty(); // clear the current pagination elements
284
285        var prev = "<a href=\"#\">Prev</a> | ";
286        var next = "<a href=\"#\">Next</a>";
287
288        var pag;
289        if(that.offset === 0) {
290            pag = next;
291        } else {
292            pag = prev + next;
293        }
294
295        if(that.offset === 0 && that.listings.length < that.limit) {
296            pag = null;
297        }
298
299        if(that.offset > 0 && that.listings.length < that.limit) {
300            pag = prev;
301        }
302
303        pagWrapper.append(pag);
304
305        var childs = pagWrapper.children();
306        if(childs.length >= 1) {
307            $_.each(childs, function(c) {
308                if(childs[c].text === "Next") {
309                    nextEl = childs[c];
310                }
311                if(childs[c].text === "Prev") {
312                    prevEl = childs[c];
313                }
314            });
315        }
316    }
317
318    return {
319        prev: prevEl,
320        next: nextEl
321    }
322}
323
324
325function normalizeParameters(params) {
326    var obj = {}
327
328    Object.keys(params).map(function(key) {
329        if (key === "subtypetext")
330            return obj.subTypeText = params[key]
331        if (key === "exteriorfeatures")
332            return obj.exteriorFeatures = params[key]
333        if (key === "mingaragespaces")
334            return obj.minGarageSpaces = params[key]
335        if (key === "maxgaragespaces")
336            return obj.maxGarageSpaces = params[key]
337        if (key === "salesagent")
338            return obj.salesAgent = params[key]
339        if (key === "speciallistingconditions")
340            return obj.specialListingConditions = params[key]
341
342        return obj[key] = params[key]
343    })
344
345    return obj
346}
347
348var getSearchFormValues = function() {
349
350    var keyword  = $_('.sr-int-map-search-wrapper #sr-search-keywords > input[type="text"]').val(),
351        ptype    = $_('.sr-int-map-search-wrapper #sr-search-ptype select').val(),
352        minprice = $_('.sr-int-map-search-wrapper #sr-search-minprice input').val(),
353        maxprice = $_('.sr-int-map-search-wrapper #sr-search-maxprice input').val(),
354        minbeds  = $_('.sr-int-map-search-wrapper #sr-search-minbeds input').val(),
355        maxbeds  = $_('.sr-int-map-search-wrapper #sr-search-maxbeds input').val(),
356        minbaths = $_('.sr-int-map-search-wrapper #sr-search-minbaths input').val(),
357        maxbaths = $_('.sr-int-map-search-wrapper #sr-search-maxbaths input').val(),
358        sort     = $_('.sr-int-map-search-wrapper .sr-sort-wrapper select').val();
359
360    var defParamsData = document.getElementById("sr-map-search").dataset.defaultParameters
361    var defLimit = document.getElementById("sr-map-search").dataset.limit
362
363    var defParams;
364    try {
365        defParams = JSON.parse(defParamsData)
366    } catch(e) {
367        defParams = {}
368    }
369
370    // Merge the default parameters on the short-code with the
371    // user-selected parameters. If the user hasn't selected a value
372    // for an input, fallback to the default.
373    var params = Object.assign({}, normalizeParameters(defParams), {
374        q:        keyword || defParams.q,
375        type:     ptype || defParams.type,
376        sort:     sort,
377        minprice: minprice || defParams.minprice,
378        maxprice: maxprice || defParams.maxprice,
379        minbeds:  minbeds || defParams.minbeds,
380        maxbeds:  maxbeds || defParams.maxbeds,
381        minbaths: minbaths || defParams.minbaths,
382        maxbaths: maxbaths || defParams.maxbaths,
383    }, { limit: defLimit })
384
385    var query = "?";
386
387    Object.keys(params).map(function(key) {
388        var p = params[key]
389        if (!p) return
390
391        if (p.indexOf(";") !== -1) {
392            p.split(";").map(function(v) {
393                var val = encodeURIComponent(v.trim())
394                query += (key + "=" + val + "&")
395            })
396        } else {
397            var val = encodeURIComponent(p.trim())
398            query += (key + "=" + val + "&")
399        }
400    })
401
402    return query
403}
404
405
406/**
407 * Our SimplyRETSMap Class
408 * Holds some state for working with the map:
409 */
410function SimplyRETSMap() {
411
412    var vendor = document.getElementById('sr-map-search').dataset.vendor
413    var limit = document.getElementById('sr-map-search').dataset.limit
414
415    this.element    = 'sr-map-search';
416    this.bounds     = [];
417    this.markers    = [];
418    this.listings   = [];
419    this.polygon    = null;
420    this.rectangle  = null;
421    this.popup      = null;
422    this.drawCtrl   = null;
423    this.loaded     = false;
424    this.options    = { zoom: 8 }
425    this.pagination = null;
426    this.offset     = 0;
427    this.linkStyle  = 'default';
428    this.siteRoot   = window.location.href
429    this.vendor     = vendor;
430    this.limit      = limit;
431
432    this.map = new google.maps.Map(
433        document.getElementById('sr-map-search'), this.options
434    );
435
436    this.loadMsg = new google.maps.InfoWindow({
437        map: null,
438        content: "Loading..."
439    });
440
441    return this;
442}
443
444
445/**
446 * SimplyRETSMap prototype methods
447 */
448
449
450/** `rec`: google.maps.OverlayType === RECTANGLE */
451SimplyRETSMap.prototype.getRectanglePoints = function(rec) {
452
453    var latLngs = [];
454    var bounds  = new google.maps.LatLngBounds();
455
456    var b  = rec.getBounds();
457    var nE = [ b.getNorthEast().lat(), b.getNorthEast().lng() ];
458    var nW = [ b.getNorthEast().lat(), b.getSouthWest().lng() ];
459    var sE = [ b.getSouthWest().lat(), b.getNorthEast().lng() ];
460    var sW = [ b.getSouthWest().lat(), b.getSouthWest().lng() ];
461
462    $_.map([nE, nW, sE, sW], function(o) {
463        latLngs.push({
464            name: "points",
465            value: o[0] + "," + o[1]
466        });
467        bounds.extend(new google.maps.LatLng(o[0], o[1]));
468    });
469
470    this.bounds = bounds;
471    this.map.fitBounds(this.bounds);
472
473    return latLngs;
474}
475
476SimplyRETSMap.prototype.getPolygonPoints = function(polygon) {
477
478    var paths  = polygon.getPaths();
479    var points = [];
480    var bounds = new google.maps.LatLngBounds();
481
482    for (var p = 0; p < paths.getLength(); p++) {
483
484        var path = paths.getAt(p);
485
486        for (var i = 0; i < path.getLength(); i++) {
487
488            points.push(
489                [ path.getAt(i).lat(), path.getAt(i).lng() ]
490            );
491
492            bounds.extend(
493                new google.maps.LatLng(
494                    path.getAt(i).lat(), path.getAt(i).lng()
495                )
496            );
497
498        }
499    }
500
501    var latLngs = $_.map(points, function(o) {
502        return {
503            name: "points",
504            value: o[0] + "," + o[1]
505        }
506    });
507
508    this.bounds = bounds;
509    this.map.fitBounds(this.bounds);
510
511    return latLngs;
512
513}
514
515
516SimplyRETSMap.prototype.addEventListener = function(source, event, fn) {
517    return google.maps.event.addListener(source, event, fn);
518}
519
520SimplyRETSMap.prototype.searchFormValues = function() {
521    return getSearchFormValues();
522};
523
524SimplyRETSMap.prototype.clearMarkers = function() {
525    if(this.markers.length > 0)
526        this.setMapOnMarkers(null);
527}
528
529SimplyRETSMap.prototype.clearPolygon = function() {
530    if(this.polygon !== null)
531        this.setMapOnPolygon(null);
532}
533
534SimplyRETSMap.prototype.setDrawCtrlOptions = function(opts) {
535    return this.drawCtrl.setOptions(opts);
536}
537
538
539SimplyRETSMap.prototype.handlePolygonDraw = function(that, overlay) {
540
541    that.clearMarkers();
542    that.clearPolygon();
543    that.setDrawCtrlOptions({ drawingMode: null });
544
545    var pts   = that.getPolygonPoints(overlay);
546    var query = that.searchFormValues();
547
548    that.shape   = 'polygon';
549    that.polygon = overlay;
550    that.markers = [];
551
552    return {
553        points: pts,
554        query: query
555    }
556}
557
558
559SimplyRETSMap.prototype.handleRectangleDraw = function(that, overlay) {
560
561    that.clearMarkers();
562    that.clearPolygon();
563    that.setDrawCtrlOptions({ drawingMode: null });
564
565    var pts   = that.getRectanglePoints(overlay);
566    var query = that.searchFormValues();
567
568    that.shape   = "rectangle";
569    that.polygon = overlay;
570    that.markers = [];
571
572    return {
573        points: pts,
574        query: query
575    }
576}
577
578
579SimplyRETSMap.prototype.handleFormSubmit = function(e) {
580    e.preventDefault();
581
582    this.clearMarkers();
583
584    var params = this.searchFormValues();
585    var points = this.shape === "rectangle" ? this.getRectanglePoints(this.polygon)
586               : this.shape === "polygon"   ? this.getPolygonPoints(this.polygon)
587               : [];
588
589    return {
590        query:  params,
591        points: points
592    }
593
594}
595
596
597SimplyRETSMap.prototype.setMapOnMarkers = function(map) {
598
599    for(var i = 0; i < this.markers.length; i++) {
600        this.markers[i].setMap(map);
601    }
602
603    return true;
604}
605
606
607SimplyRETSMap.prototype.setMapOnPolygon = function(map) {
608
609    this.polygon.setMap(map);
610
611    return true;
612}
613
614
615SimplyRETSMap.prototype.handleRequest = function(that, data) {
616
617    // Remove data from map before request
618    that.setMapOnMarkers(null);
619    that.setLoadMsgMap(null);
620
621    // New map data, empty
622    that.bounds   = [];
623    that.listings = [];
624
625    var idxImg = document.getElementById('sr-map-search').dataset.idxImg;
626    var officeOnThumbnails = document.getElementById('sr-map-search').dataset.officeOnThumbnails;
627    var agentOnThumbnails = document.getElementById('sr-map-search').dataset.agentOnThumbnails;
628    var linkStyle = data.permalink_structure === "" ? "default" : "pretty";
629    var statusText = data.show_mls_status_text;
630    var mlsTrademark = data.show_mls_trademark_symbol;
631
632    that.siteRoot = data.site_root
633    that.linkStyle = linkStyle;
634
635    var listings = data.result.response.length > 0
636                 ? data.result.response
637                 : [];
638    var markers  = makeMapMarkers(
639        that.map,
640        listings,
641        that.linkStyle,
642        that.siteRoot,
643        idxImg,
644        officeOnThumbnails,
645        agentOnThumbnails,
646        statusText,
647        mlsTrademark,
648        that.vendor
649    );
650
651    that.bounds   = markers.bounds;
652    that.markers  = markers.markers;
653    that.listings = listings;
654
655    if(listings.length < 1)
656        that.offset = 0;
657
658    if (!this.shape) {
659        that.map.fitBounds(that.bounds);
660    }
661
662    replaceListingMarkup(data.markup);
663
664    var pagination = updatePagination(that);
665
666    that.pagination = pagination;
667
668    that.initPaginationEventHandlers(that, that.pagination);
669
670}
671
672SimplyRETSMap.prototype.initPaginationEventHandlers = function(that, pag) {
673
674    if(pag.next !== null) {
675
676        $_(pag.next).on('click', function(e) {
677
678            e.preventDefault();
679
680            var params = that.handleFormSubmit(e),
681                points = params.points,
682                query  = params.query;
683
684            that.sendRequest(points, query, 'next').done(function(data) {
685                that.handleRequest(that, data);
686            });
687
688        });
689    }
690
691    if(pag.prev !== null) {
692
693        $_(pag.prev).on('click', function(e) {
694
695            e.preventDefault();
696
697            var params = that.handleFormSubmit(e),
698                points = params.points,
699                query  = params.query;
700
701            that.sendRequest(points, query, 'prev').done(function(data) {
702                that.handleRequest(that, data);
703            });
704
705        });
706    }
707
708}
709
710
711SimplyRETSMap.prototype.setLoadMsgMap = function(map) {
712
713    if(!this.polygon && !this.rectangle) return;
714
715    this.loadMsg.setPosition(this.map.getCenter());
716    this.loadMsg.setMap(map);
717
718}
719
720
721SimplyRETSMap.prototype.sendRequest = function(points, params, paginate) {
722
723    this.setLoadMsgMap(this.map);
724
725    /** Update pagination */
726    if(paginate !== null && paginate !== undefined) {
727
728        if(paginate === "next") {
729            scrollToAnchor('sr-search-wrapper');
730            this.offset = Number(this.offset) + Number(this.limit);
731        } else if(paginate === "prev") {
732            scrollToAnchor('sr-search-wrapper');
733            this.offset = Number(this.offset) - Number(this.limit);
734        } else if (paginate === "reset") {
735            this.offset = 0
736        }
737    }
738
739    var offset = this.offset;
740    var vendor = this.vendor
741
742    /** URL Encode them all */
743    var pointsQ = $_.param(points);
744    var query = params
745              + (vendor ? ("vendor=" + vendor + "&") : "")
746              + "offset=" + offset + "&"
747              + pointsQ
748
749    var req = $_.ajax({
750        type: 'post',
751        url: sr_ajaxUrl, // defined in <head>
752        data: {
753            action: 'update_int_map_data', // server controller
754            parameters: query,
755            vendor: vendor
756        },
757    });
758
759    return req;
760
761}
762
763SimplyRETSMap.prototype.setDrawingManager = function() {
764
765    var that = this;
766
767    // Enable the drawing tools toolbar
768    var drawingManager = new google.maps.drawing.DrawingManager({
769        map: this.map,
770        drawingControl: true,
771        drawingControlOptions: {
772            position: google.maps.ControlPosition.TOP_CENTER,
773            drawingModes: [
774                google.maps.drawing.OverlayType.POLYGON,
775                google.maps.drawing.OverlayType.RECTANGLE
776            ]
777        },
778        // markerOptions: { icon: 'custom/icon/here.png' },
779        rectangleOptions: {
780            editable: true,
781            fillOpacity: 0.1,
782            fillColor: 'green',
783            strokeColor: 'green'
784        },
785        polygonOptions: {
786            editable: true,
787            fillOpacity: 0.1,
788            fillColor: 'green',
789            strokeColor: 'green'
790        },
791    });
792
793    this.drawCtrl = drawingManager;
794
795    this.addEventListener(drawingManager, 'rectanglecomplete', function(overlay) {
796        var q = that.handleRectangleDraw(that, overlay);
797
798        overlay.addListener("click", function() {
799            that.shape = null
800            that.bounds = []
801            overlay.setMap(null)
802        })
803
804        that.sendRequest(q.points, q.query).done(function(data) {
805            that.handleRequest(that, data);
806        });
807
808    });
809
810    this.addEventListener(drawingManager, 'polygoncomplete', function(overlay) {
811        var q = that.handlePolygonDraw(that, overlay);
812
813        overlay.addListener("click", function() {
814            that.shape = null
815            that.bounds = []
816            overlay.setMap(null)
817        })
818
819        that.sendRequest(q.points, q.query).done(function(data) {
820            that.handleRequest(that, data);
821        });
822
823    });
824
825    return drawingManager;
826
827};
828
829
830SimplyRETSMap.prototype.initEventListeners = function() {
831
832    var that = this;
833
834    // fetch initial listings when map is loaded
835    this.addEventListener(this.map, 'idle', function() {
836        if(!that.loaded) {
837            var query = that.searchFormValues()
838
839            that.sendRequest([], query).done(function(data) {
840                that.handleRequest(that, data);
841                that.loaded = true;
842            });
843        }
844    });
845
846
847    // Watch the search form for submission
848    $_('.sr-int-map-search-wrapper form input.submit').on('click', function(e) {
849        var params = that.handleFormSubmit(e),
850            points = params.points,
851            query  = params.query;
852
853        that.sendRequest(points, query, "reset").done(function(data) {
854            that.handleRequest(that, data);
855        });
856
857    });
858
859    return;
860
861};
862
863
864var startMap = function() {
865
866    var map = new SimplyRETSMap();
867    map.setDrawingManager();
868    map.initEventListeners();
869
870}
871
872
873$_(document).ready(function() {
874
875    classicGalleryToggle();
876    classicGalleryTextToggle();
877    advSearchFormToggler();
878    listingSliderCarousel();
879
880    if(document.getElementById('sr-map-search')) {
881
882        if(typeof google === 'object' && typeof google.maps === 'object') {
883            // google.maps exists - start map
884            startMap();
885
886        } else {
887            var key = document.getElementById('sr-map-search').dataset.apiKey;
888
889            // if google.maps doesn't exist - load it, then start map
890            var url = "https://maps.googleapis.com/maps/api/js?"
891                    + "libraries=drawing&callback=startMap"
892                    + "&key=" + key;
893
894            var script = document.createElement("script");
895
896            script.type = "text/javascript";
897            script.src = url;
898
899            document.body.appendChild(script);
900
901        }
902    }
903
904    document.querySelectorAll(".utcToLocal").forEach(function(i) {
905        i.innerText = new Date(i.innerText).toLocaleString()
906    })
907
908});
909
910/**
911 * Polyfills for browser compatibility
912 */
913
914// Object.assign polyfill for older browsers
915// See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign
916if (typeof Object.assign !== 'function') {
917    Object.defineProperty(Object, "assign", {
918        value: function assign(target, varArgs) {
919            'use strict';
920            if (target === null || target === undefined) {
921                throw new TypeError('Cannot convert undefined or null to object');
922            }
923
924            var to = Object(target);
925
926            for (var index = 1; index < arguments.length; index++) {
927                var nextSource = arguments[index];
928
929                if (nextSource !== null && nextSource !== undefined) {
930                    for (var nextKey in nextSource) {
931                        if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {
932                            to[nextKey] = nextSource[nextKey];
933                        }
934                    }
935                }
936            }
937            return to;
938        },
939        writable: true,
940        configurable: true
941    });
942}

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