PageSourceSearch

https://assets.getmyboat.com/journal/static/js/getmyboat.9f558db65831.js

js getmyboat.com collected 2026-09-24 17:20:41 UTC 10,168 bytes, 358 lines download raw bytes

1$(document).ready(function () {
2  var service = new google.maps.places.AutocompleteService();
3  $("form.navbar-search").submit(function (e) {
4    if (e.preventDefault) e.preventDefault();
5    return false;
6  });
7  $("#destination-search").typeahead(
8    {
9      hint: false,
10      highlight: true,
11      minLength: 2,
12      async: true,
13      displayKey: "description",
14    },
15    {
16      source: function (query, sync, async) {
17        if (query) {
18          var matches = [];
19          service.getPlacePredictions(
20            {
21              input: query,
22            },
23            function (predictions, status) {
24              if (status == google.maps.places.PlacesServiceStatus.OK) {
25                predictions.forEach(function (prediction) {
26                  if (
27                    prediction.types.length === 1 &&
28                    prediction.types.includes("establishment")
29                  )
30                    return;
31                  matches.push(prediction);
32                });
33                async(matches);
34              }
35            }
36          );
37        }
38      },
39      templates: {
40        suggestion: function (data) {
41          return "<span>" + data.description + "</span>";
42        },
43      },
44      displayKey: "label",
45    }
46  );
47  $("#destination-search").bind("typeahead:selected", function (e, data) {
48    $.get(
49      "/api/v4/boats/search/?place_id=" + data.place_id,
50      function (data) {
51        window.top.location.href = data.search_route;
52      },
53      "json"
54    );
55  });
56});
57
58$(document).ready(function () {
59  $.get("/api/v4/auth/user/", function (data, status) {
60    if (status == "success" && data && data.pk) {
61      $("#user-name").text(data.first_name + " " + data.last_name);
62      if (data.photo_url) $("#user-avatar").attr("src", data.photo_url);
63      $("#user-menu").toggle(true);
64    }
65  });
66  $("#share-copy").click(function () {
67    setTimeout(function () {
68      $("#share-link").select();
69      document.execCommand("copy");
70    }, 100);
71  });
72  $("#share-link").click(function (e) {
73    $(this).select();
74    document.execCommand("copy");
75  });
76
77  // Trip categories
78  var view = $("div.scroll");
79  var tileSize = 209;
80  var tileScroll = tileSize * 2;
81  var count = $("div.trip-categories ul li").length;
82  var sliderLimit = "-" + count * tileSize;
83
84  view.css("width", Math.abs(sliderLimit + 20 + "px"));
85
86  $(".arrow-right", $("div.trip-categories")).click(function () {
87    var sliderEnd = "-" + (count * tileSize - $("div.trip-categories").width());
88    var currentPosition = parseInt(view.css("left"));
89
90    if (currentPosition < sliderEnd) {
91      view.stop(false, true).animate({ left: 0 }, { duration: 400 });
92      $(".arrow-left", $("div.trip-categories")).hide();
93    } else if (currentPosition >= sliderLimit) {
94      view
95        .stop(false, true)
96        .animate({ left: "-=" + tileScroll + "px" }, { duration: 400 });
97      $(".arrow-left", $("div.trip-categories")).show();
98      if (currentPosition - tileScroll <= sliderEnd) {
99        $(this).hide();
100      }
101    }
102  });
103
104  $(".arrow-left", $("div.trip-categories"))
105    .click(function () {
106      var sliderEnd =
107        "-" + (count * tileSize - $("div.trip-categories").width());
108      var currentPosition = parseInt(view.css("left"));
109
110      if (currentPosition < 0) {
111        view
112          .stop(false, true)
113          .animate({ left: "+=" + tileScroll + "px" }, { duration: 400 });
114        $(".arrow-right", $("div.trip-categories")).show();
115        if (currentPosition + tileScroll < 0) {
116          $(this).show();
117        } else {
118          $(this).hide();
119        }
120      } else {
121        $(this).hide();
122      }
123    })
124    .hide();
125
126  $("a", $("div.post-content")).click(function (e) {
127    if (
128      $(this).attr("href").indexOf(".getmyboat.com") == -1 &&
129      $(this).attr("href").charAt(0) != "#"
130    ) {
131      window.open($(this).attr("href"), "_blank");
132      e.preventDefault();
133      return false;
134    }
135  });
136});
137
138$(document).ready(function () {
139  // Single listings
140  $("div.listing", $("div.listing-single")).each(function (i, el) {
141    var id = $(el).data("listing-id");
142    $.getJSON("/api/v4/boats/" + id + "/?strip_tags=true", function (data) {
143      drawSingleListing(el, data);
144    });
145  });
146
147  // Multi listings
148  var listing_ids = [];
149  $("div.listing", $("div.listing-multiple")).each(function (i, el) {
150    listing_ids.push("boat_ids[]=" + $(el).data("listing-id"));
151  });
152  if (listing_ids.length == 0) return;
153  $.getJSON(
154    "/api/v4/boats/many/?strip_tags=true&" + listing_ids.join("&"),
155    function (data) {
156      var container = $("div.listing-multiple");
157      $.each(data, function (i, listing) {
158        var el = $(
159          'div.listing[data-listing-id="' + listing.id + '"]',
160          container
161        );
162        drawMultipleListings(el, listing);
163      });
164    }
165  );
166});
167
168$(document).ready(function () {
169  const INITIAL_LANDING_PAGE_KEY = 'initial_landing_page';
170
171  if (!localStorage.getItem(INITIAL_LANDING_PAGE_KEY)) {
172    const initialLandingPage = createInitialLandingPage({
173      location: window.location,
174      referrer: document.referrer.toLowerCase(),
175    });
176    try {
177      window.localStorage.setItem(INITIAL_LANDING_PAGE_KEY, JSON.stringify(initialLandingPage));
178    } catch (e) {
179      // Fail silently
180    }
181  }
182});
183
184function standardiseImageSize(url) {
185  let urlObj = new URL(url);
186  urlObj.searchParams.delete('w');
187  urlObj.searchParams.delete('h');
188  urlObj.searchParams.set('w', '210');
189  urlObj.searchParams.set('h', '136');
190  urlObj.searchParams.set('fit', 'clamp');
191  urlObj.searchParams.set('crop', 'edges');
192  return urlObj.toString();
193}
194
195function drawMultipleListings(el, data) {
196  var headline = $('<h6 class="headline"></h6>').append(
197    $('<a target="_blank" href="/trips/' + data.id + '/"></a>').text(
198      data.headline
199    )
200  );
201  // Location
202  var location = $('<span class="location"></span>');
203  location.text(
204    `${data.category_string} in ${data.city} - ${data.capacity} guests`
205  );
206
207  // Photo
208  var photo = $(
209    '<div class = "photo"><a target="_blank" href="/trips/' +
210      data.id +
211      '/"><img src="' +
212      standardiseImageSize(data.photo_url) +
213      '" alt="' +
214      data.headline +
215      '"/></a></div>'
216  );
217
218  var price = $("<div class='price'></div>").append(
219    $("<span class='amount' ></span>").text(
220      `${
221        data.search_price_nested.symbol
222      }
222${data.search_price_nested.price.toLocaleString()}`
223    ),
224    $('<span class="label"></span>').text(data.prices[0].price_unit)
225  );
226
227  var wrapped = $('<div class="wrapper">').append(photo);
228
229  // Combine elements
230  $(el).append(wrapped, location, headline, price);
231}
232
233function drawListingStars(el, rating) {
234  var stars = "";
235  var avg = Math.ceil(rating);
236  for (var i = 1; i < 6; i++) {
237    if (i <= rating) stars += '<span class="gold">☆</span>';
238    else stars += "<span>☆</span>";
239  }
240  $(el).append($(stars));
241}
242
243function drawSingleListing(el, data) {
244  var headline = $('<h3 class="headline"></h3>').append(
245    $('<a target="_blank" href="/trips/' + data.id + '/"></a>').text(
246      data.headline
247    )
248  );
249
250  Location;
251  var location_breadcrumbs = [];
252  if (data.country)
253    location_breadcrumbs.push(
254      $('<span class="country"></span>').text(data.country)
255    );
256  if (data.state)
257    location_breadcrumbs.push(
258      $('<span class="state"></span>').text(data.state)
259    );
260  if (data.city)
261    location_breadcrumbs.push($('<span class="city"></span>').text(data.city));
262  var location = $('<div class="location"></div>').append(data.headline);
263
264  // Rating
265  var rating = $('<div class="rating"></div>');
266  if (data.review_average) drawListingStars(rating, data.review_average);
267
268  // Avatar
269  var avatar = $(
270    '<a href="/trips/' +
271      data.id +
272      '/"><img class="avatar" src="' +
273      data.user_details.photo_url +
274      '" /></a>'
275  );
276  var badge = $('<div class="badge"></div>').append(avatar);
277
278  // User info
279  var user_rating_name = $('<div class="info"></div>').append(
280    rating,
281    $('<h5 class="name"></h5>').text(data.user_details.first_name)
282  );
283  if (data.user_details.is_super_owner)
284    user_rating_name.append(
285      $(
286        '<span class="super-owner">Super Owner <img src="/static/img/[email protected]" /></span>'
287      )
288    );
289
290  var user_info = $('<div class="user"></div>').append(badge, user_rating_name);
291
292  // Price
293  var price = $('<div class="price-detail"></div>').append(
294    $('<span class="currency"></span>').text(data.search_price_nested.currency),
295    $('<span class="amount"></span>').text(
296      data.search_price_nested.formatted.replace(
297        data.search_price_nested.currency,
298        ""
299      )
300    ),
301    $('<span class="label"></span>').text(data.search_price_nested.label)
302  );
303  var price_info = $('<div class="price">').append(
304    $('<span class="from">From</span>'),
305    price
306  );
307
308  // Combine user info + price
309  var info_wrap = $('<div class="details"></div>').append(
310    user_info,
311    price_info
312  );
313
314  // Photos
315  var photo_list = [];
316  $.each(
317    data.photos.slice(0, photo_list.length > 3 ? photo_list.length : 3),
318    function (i, photo) {
319      photo_list.push(
320        $(
321          '<div class="photo"><a target="_blank" href="/trips/' +
322            data.id +
323            '/"><img src="' +
324            photo.url +
325            '" alt="' +
326            data.headline +
327            '"/></a></div>'
328        )
329      );
330    }
331  );
332  var photos = $('<div class="photos"></div>').append(photo_list);
333
334  // Combine elements
335  $(el).append(photos, location, headline, info_wrap);
336}
337
338function createInitialLandingPage({location, referrer}) {
339  const utmParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_content', 'utm_term'];
340  const urlParams = new URLSearchParams(location.search);
341  const hrefWithoutSearch = location.href.split('?')[0];
342  const gclid = urlParams.get('gclid') || undefined;
343
344  const utmValues = {};
345  utmParams.forEach((param) => {
346    const value = urlParams.get(param);
347    if (value) {
348      utmValues[param] = value;
349    }
350  });
351
352  return {
353    url: hrefWithoutSearch,
354    referrer,
355    gclid,
356    utmValues,
357  };
358}

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.