PageSourceSearch

https://topdowntabletop.com/shared/maps-core.js

js topdowntabletop.com collected 2026-10-08 09:15:55 UTC 4,342 bytes, 135 lines download raw bytes

1/* GENERATED FILE -- do not edit.
2 * Source: packages/shared/src/maps/pins.ts
3 * Regenerate: npm run tokens
4 *
5 * Browser twin of the map-pin module, exposed as window.TDTT.mapsCore. The
6 * drift test guards generated == emitter; the emitter matching the
7 * TypeScript is hand-verified, so change both in the same commit.
8 */
9(function () {
10  'use strict';
11
12  var MAP_DEFAULT_CATEGORY = "board_games";
13  var PENDING_TAG_LABEL = "NOT APPROVED / VERIFIED BY SHOP";
14  var VERIFIED_TAG_LABEL = "Verified by shop";
15  var SINGLE_PIN_PAD = 0.02;
16
17  function resolveMapCategory(raw) {
18    if (raw === null || raw === undefined || raw === '') return MAP_DEFAULT_CATEGORY;
19    return raw === 'all' ? null : raw;
20  }
21
22  function shopMatchesCategory(categories, category) {
23    if (category === null) return true;
24    if (!Array.isArray(categories)) return false;
25    for (var i = 0; i < categories.length; i++) {
26      if (categories[i] === category) return true;
27    }
28    return false;
29  }
30
31  function hasCoords(lat, lng) {
32    return (
33      typeof lat === 'number' && typeof lng === 'number' &&
34      isFinite(lat) && isFinite(lng) && !(lat === 0 && lng === 0)
35    );
36  }
37
38  function buildShopPins(shops, eventCounts, tags) {
39    var pins = [];
40    var unmapped = 0;
41    for (var i = 0; i < shops.length; i++) {
42      var s = shops[i];
43      if (!hasCoords(s.latitude, s.longitude)) {
44        unmapped += 1;
45        continue;
46      }
47      var shopTags = [];
48      for (var j = 0; j < tags.length; j++) {
49        var t = tags[j];
50        if (t.shopId === s.id) {
51          shopTags.push({ code: t.code, name: t.name, status: t.status, verified: t.verified });
52        }
53      }
54      var count = (eventCounts && Object.prototype.hasOwnProperty.call(eventCounts, s.id))
55        ? eventCounts[s.id]
56        : 0;
57      pins.push({
58        id: s.id, name: s.name, lat: s.latitude, lng: s.longitude,
59        eventCount: count, tournaments: shopTags
60      });
61    }
62    return { pins: pins, unmapped: unmapped };
63  }
64
65  function groupEventsIntoPins(events) {
66    var byShop = {};
67    var order = [];
68    var unmapped = 0;
69    for (var i = 0; i < events.length; i++) {
70      var ev = events[i];
71      var s = ev.shop;
72      if (!hasCoords(s.latitude, s.longitude)) {
73        unmapped += 1;
74        continue;
75      }
76      var key = s.id;
77      if (Object.prototype.hasOwnProperty.call(byShop, key)) {
78        byShop[key].eventCount += 1;
79      } else {
80        byShop[key] = {
81          id: s.id, name: s.name, lat: s.latitude, lng: s.longitude,
82          eventCount: 1, tournaments: []
83        };
84        order.push(key);
85      }
86    }
87    var pins = [];
88    for (i = 0; i < order.length; i++) pins.push(byShop[order[i]]);
89    return { pins: pins, unmapped: unmapped };
90  }
91
92  function tournamentBadge(tournaments) {
93    if (tournaments.length === 0) return null;
94    var anyVerified = false;
95    for (var i = 0; i < tournaments.length; i++) {
96      if (tournaments[i].verified) { anyVerified = true; break; }
97    }
98    return anyVerified
99      ? { label: VERIFIED_TAG_LABEL, verified: true }
100      : { label: PENDING_TAG_LABEL, verified: false };
101  }
102
103  function roundPad(n) {
104    return Math.round(n * 1e6) / 1e6;
105  }
106
107  function boundsFor(pins) {
108    if (pins.length === 0) return null;
109    var north = -Infinity, south = Infinity, east = -Infinity, west = Infinity;
110    for (var i = 0; i < pins.length; i++) {
111      var p = pins[i];
112      north = Math.max(north, p.lat);
113      south = Math.min(south, p.lat);
114      east = Math.max(east, p.lng);
115      west = Math.min(west, p.lng);
116    }
117    if (pins.length === 1) {
118      return {
119        north: roundPad(north + SINGLE_PIN_PAD),
120        south: roundPad(south - SINGLE_PIN_PAD),
121        east: roundPad(east + SINGLE_PIN_PAD),
122        west: roundPad(west - SINGLE_PIN_PAD)
123      };
124    }
125    return { north: north, south: south, east: east, west: west };
126  }
127
128  window.TDTT = window.TDTT || {};
129  window.TDTT.mapsCore = {
130    MAP_DEFAULT_CATEGORY: MAP_DEFAULT_CATEGORY, PENDING_TAG_LABEL: PENDING_TAG_LABEL,
131    VERIFIED_TAG_LABEL: VERIFIED_TAG_LABEL, resolveMapCategory: resolveMapCategory,
132    shopMatchesCategory: shopMatchesCategory, hasCoords: hasCoords, buildShopPins: buildShopPins,
133    groupEventsIntoPins: groupEventsIntoPins, tournamentBadge: tournamentBadge, boundsFor: boundsFor
134  };
135})();

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.