atriusmaps-node-sdk 3.3.897 → 3.3.899

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. package/dist/cjs/nodesdk/nodeEntry.js +36 -58
  2. package/dist/cjs/package.json.js +8 -4
  3. package/dist/cjs/plugins/clientAPI/src/clientAPI.js +8 -6
  4. package/dist/cjs/plugins/dynamicPois/src/dynamicPois.js +50 -142
  5. package/dist/cjs/plugins/dynamicPois/src/processors.js +31 -53
  6. package/dist/cjs/plugins/flightStatus/src/flightDetailsMapper.js +47 -116
  7. package/dist/cjs/plugins/flightStatus/src/flightStatus.js +48 -82
  8. package/dist/cjs/plugins/flightStatus/src/utils.js +4 -14
  9. package/dist/cjs/plugins/poiDataManager/src/poiDataManager.js +84 -154
  10. package/dist/cjs/plugins/sdkServer/src/prepareSDKConfig.js +45 -76
  11. package/dist/cjs/plugins/sdkServer/src/sdkHeadless.js +70 -79
  12. package/dist/cjs/plugins/sdkServer/src/sdkServer.js +97 -147
  13. package/dist/cjs/plugins/searchService/src/flexsearchExports/lang.js +16 -190
  14. package/dist/cjs/plugins/searchService/src/flexsearchExports/simple.js +28 -35
  15. package/dist/cjs/plugins/searchService/src/poiSearch.js +10 -21
  16. package/dist/cjs/plugins/searchService/src/searchService.js +45 -147
  17. package/dist/cjs/plugins/searchService/src/searchTypeahead.js +17 -28
  18. package/dist/cjs/plugins/searchService/src/utils.js +9 -13
  19. package/dist/cjs/plugins/venueDataLoader/src/venueDataLoader.js +148 -304
  20. package/dist/cjs/plugins/venueDataLoader/src/venueLoadingUtils.js +47 -126
  21. package/dist/cjs/plugins/wayfinder/src/findRoute.js +6 -73
  22. package/dist/cjs/plugins/wayfinder/src/minPriorityQueue.js +7 -27
  23. package/dist/cjs/plugins/wayfinder/src/navGraph.js +78 -259
  24. package/dist/cjs/plugins/wayfinder/src/navGraphDebug.js +26 -57
  25. package/dist/cjs/plugins/wayfinder/src/segmentBadges.js +25 -25
  26. package/dist/cjs/plugins/wayfinder/src/segmentBuilder.js +50 -133
  27. package/dist/cjs/plugins/wayfinder/src/segmentCategories.js +29 -29
  28. package/dist/cjs/plugins/wayfinder/src/stepBuilder.js +53 -145
  29. package/dist/cjs/plugins/wayfinder/src/wayfinder.js +105 -349
  30. package/dist/cjs/src/app.js +53 -91
  31. package/dist/cjs/src/configs/postproc-mol-url-parms.js +34 -43
  32. package/dist/cjs/src/configs/postproc-stateTracking.js +1 -19
  33. package/dist/cjs/src/controller.js +4 -26
  34. package/dist/cjs/src/debugTools.js +55 -94
  35. package/dist/cjs/src/env.js +8 -19
  36. package/dist/cjs/src/extModules/bustle.js +15 -71
  37. package/dist/cjs/src/extModules/flexapi/src/help.js +7 -22
  38. package/dist/cjs/src/extModules/flexapi/src/index.js +15 -29
  39. package/dist/cjs/src/extModules/flexapi/src/validate.js +45 -93
  40. package/dist/cjs/src/extModules/geohasher.js +13 -31
  41. package/dist/cjs/src/extModules/log.js +18 -29
  42. package/dist/cjs/src/historyManager.js +4 -6
  43. package/dist/cjs/src/utils/bounds.js +2 -4
  44. package/dist/cjs/src/utils/buildStructureLookup.js +7 -7
  45. package/dist/cjs/src/utils/configUtils.js +7 -43
  46. package/dist/cjs/src/utils/date.js +5 -17
  47. package/dist/cjs/src/utils/distance.js +2 -2
  48. package/dist/cjs/src/utils/dom.js +9 -24
  49. package/dist/cjs/src/utils/funcs.js +15 -30
  50. package/dist/cjs/src/utils/geodesy.js +24 -39
  51. package/dist/cjs/src/utils/geom.js +32 -148
  52. package/dist/cjs/src/utils/i18n.js +39 -70
  53. package/dist/cjs/src/utils/isInitialState.js +7 -13
  54. package/dist/cjs/src/utils/location.js +10 -29
  55. package/dist/cjs/src/utils/observable.js +4 -29
  56. package/dist/cjs/src/utils/rand.js +9 -80
  57. package/dist/cjs/utils/constants.js +1 -1
  58. package/dist/package.json.js +1 -1
  59. package/dist/plugins/poiDataManager/src/poiDataManager.js +1 -1
  60. package/dist/plugins/sdkServer/src/prepareSDKConfig.js +1 -1
  61. package/dist/src/utils/buildStructureLookup.js +1 -1
  62. package/dist/src/utils/date.js +1 -1
  63. package/package.json +1 -1
@@ -23,236 +23,153 @@ function _interopNamespaceDefault(e) {
23
23
 
24
24
  var R__namespace = /*#__PURE__*/_interopNamespaceDefault(R);
25
25
 
26
- const USE_AUTH_WHEN_NOT_PROD_STAGE = false; // turning this off for now (per Jessica request)
27
-
26
+ const USE_AUTH_WHEN_NOT_PROD_STAGE = false;
28
27
  async function create(app, config) {
29
- const log = app.log.sublog('venueDataLoader');
28
+ const log = app.log.sublog("venueDataLoader");
30
29
  let venueDataLoaded = new Zousan();
31
30
  let mapDataLoaded = new Zousan();
32
-
33
- const getDefaultStructureId = venueData =>
34
- venueData.defaultStructureId ||
35
- R__namespace.path(['structureOrder', 0], venueData) ||
36
- R__namespace.path(['selectorOrder', 0], venueData) ||
37
- R__namespace.pipe(R__namespace.prop('structures'), Object.values, R__namespace.path([0, 'id']))(venueData);
38
-
39
- const mergeWithProp = (prop, toAdd, o) => R__namespace.over(R__namespace.lensProp(prop), old => R__namespace.mergeRight(old || {}, toAdd), o);
40
-
41
- // This function counts the number of characters that match at the beginning of two strings.
42
- const countMatchedPrefix = (a, b) =>
43
- a.split('').reduce((max, _, i) => (a.substring(0, i + 1) === b.substring(0, i + 1) ? i : max), -1) + 1;
44
-
45
- // This function returns the venue definition for a specific language. It does this by filtering the venueList for the specified language,
46
- // sorting the results by how many characters match at the beginning of the venueId, and
47
- // returning the first one. If no venues match, undefined is returned.
48
- const getVenueDefForLang = (venueData, lang) =>
49
- Object.values(venueData.venueList)
50
- .filter(venueDef => venueDef.locale === lang) // select all the venues for the specified language
51
- .sort((a, b) => countMatchedPrefix(b.id, venueData.id) - countMatchedPrefix(a.id, venueData.id)) // sort by how many characters match at the beginning of the venueId - most first
52
- .at(0); // take the first one, which is the one that matches the most characters at the beginning of the venueId
53
-
54
- // This function determines the "base venue ID", which currently is the venue ID of the Engilsh version of the venue.
55
- // We can use the venueList to find the English version of the venue, and then return its ID.
56
- const calculateBaseVenueId = venueData => getVenueDefForLang(venueData, 'en')?.id;
57
-
31
+ const getDefaultStructureId = (venueData) => venueData.defaultStructureId || R__namespace.path(["structureOrder", 0], venueData) || R__namespace.path(["selectorOrder", 0], venueData) || R__namespace.pipe(R__namespace.prop("structures"), Object.values, R__namespace.path([0, "id"]))(venueData);
32
+ const mergeWithProp = (prop, toAdd, o) => R__namespace.over(R__namespace.lensProp(prop), (old) => R__namespace.mergeRight(old || {}, toAdd), o);
33
+ const countMatchedPrefix = (a, b) => a.split("").reduce((max, _, i) => a.substring(0, i + 1) === b.substring(0, i + 1) ? i : max, -1) + 1;
34
+ const getVenueDefForLang = (venueData, lang) => Object.values(venueData.venueList).filter((venueDef) => venueDef.locale === lang).sort((a, b) => countMatchedPrefix(b.id, venueData.id) - countMatchedPrefix(a.id, venueData.id)).at(0);
35
+ const calculateBaseVenueId = (venueData) => getVenueDefForLang(venueData, "en")?.id;
58
36
  async function loadVenueData(vConfig, languagesToTry) {
59
- // For all non-production stages, require SSO (if no assetStage defined we default to 'prod')
60
- if (
61
- vConfig.assetStage &&
62
- vConfig.assetStage !== 'prod' &&
63
- location.hostname !== 'localhost' &&
64
- USE_AUTH_WHEN_NOT_PROD_STAGE
65
- ) ;
66
-
37
+ if (vConfig.assetStage && vConfig.assetStage !== "prod" && location.hostname !== "localhost" && USE_AUTH_WHEN_NOT_PROD_STAGE) ;
67
38
  const fetchJson = venueLoadingUtils.createFetchJson();
68
39
  const fetchText = venueLoadingUtils.createFetchText();
69
-
70
40
  const venueData = await venueLoadingUtils.getVenueDataFromUrls(vConfig, fetchJson, languagesToTry);
71
-
72
41
  const { accountId, venueId } = vConfig;
73
-
74
42
  venueData.assetStage = vConfig.assetStage;
75
-
76
43
  venueData.defaultOrdinal = venueData.defaultOrdinal || getDefaultOrdinal(venueData);
77
44
  venueData.structures = venueLoadingUtils.buildStructures(venueData);
78
45
  venueData.baseVenueId = calculateBaseVenueId(venueData);
79
- venueData.getTranslatedContentPath = contentType =>
80
- `https://content.locuslabs.com/${venueData.category}/${contentType}/${venueId}/${accountId}`;
46
+ venueData.getTranslatedContentPath = (contentType) => `https://content.locuslabs.com/${venueData.category}/${contentType}/${venueId}/${accountId}`;
81
47
  venueData.fetchJson = fetchJson;
82
48
  venueData.fetchText = fetchText;
83
49
  if (app.config.debug && app.env.isBrowser) {
84
50
  window._venueData = venueData;
85
51
  }
86
-
87
52
  if (venueData.queueTypes) {
88
53
  venueData.securityQueueTypes = (() => {
89
- const secLane = venueData.queueTypes.find(qt => qt.id === 'SecurityLane');
54
+ const secLane = venueData.queueTypes.find((qt) => qt.id === "SecurityLane");
90
55
  if (secLane) {
91
- return secLane.subtypes.map(t => t.id);
56
+ return secLane.subtypes.map((t) => t.id);
92
57
  }
93
58
  return [];
94
59
  })();
95
60
  }
96
-
97
- app.bus.send('venueData/venueDataLoaded', { venueData });
98
-
61
+ app.bus.send("venueData/venueDataLoaded", { venueData });
99
62
  venueDataLoaded.resolve(venueData);
100
63
  return venueDataLoaded;
101
64
  }
102
-
103
65
  function getDefaultOrdinal(venueData) {
104
66
  const defaultStructureId = getDefaultStructureId(venueData);
105
- const defaultStructure = Object.values(venueData.structures).find(R__namespace.propEq(defaultStructureId, 'id'));
67
+ const defaultStructure = Object.values(venueData.structures).find(R__namespace.propEq(defaultStructureId, "id"));
106
68
  return defaultStructure.levels[defaultStructure.defaultLevelId].ordinal;
107
69
  }
108
-
109
70
  function notifyState(venueData) {
110
- const state = { id: 'venueDataLoader' };
71
+ const state = { id: "venueDataLoader" };
111
72
  if (venueData.id !== config.venueId) {
112
73
  state.vid = venueData.id;
113
74
  }
114
-
115
75
  state.lang = app.i18n().language;
116
-
117
- if (venueData.assetStage !== 'prod') {
76
+ if (venueData.assetStage !== "prod") {
118
77
  state.stage = venueData.assetStage;
119
78
  }
120
- app.bus.send('deepLinking/notifyState', state);
79
+ app.bus.send("deepLinking/notifyState", state);
121
80
  return venueData;
122
81
  }
123
-
124
- app.bus.on('debugTools/fileDrop', async ({ file, content }) => {
125
- if (file.type === 'application/json') {
82
+ app.bus.on("debugTools/fileDrop", async ({ file, content }) => {
83
+ if (file.type === "application/json") {
126
84
  const jsonOb = JSON.parse(content);
127
- if (jsonOb.basemap && jsonOb['basemap.venue']) {
85
+ if (jsonOb.basemap && jsonOb["basemap.venue"]) {
128
86
  return replaceTheme(JSON.parse(content));
129
- } // looks like a theme!
130
- if (jsonOb.metadata && jsonOb.metadata['mapbox:type']) {
87
+ }
88
+ if (jsonOb.metadata && jsonOb.metadata["mapbox:type"]) {
131
89
  return replaceStyle(content);
132
- } // looks like a style!
90
+ }
133
91
  }
134
92
  });
135
-
136
- // Returns true if category c1 is within category c2.
137
- // "within" here means they either are the same category
138
- // or c2 is a subcategory of c1
139
- // i.e. withinCategory("eat", "eat") = true
140
- // withinCategory("eat.coffee", "eat") = true
141
- // withinCategory("eat", "eat.coffee") = false
142
- const withinCategory = (c1, c2) => c1 === c2 || c1.indexOf(c2 + '.') === 0;
143
-
93
+ const withinCategory = (c1, c2) => c1 === c2 || c1.indexOf(c2 + ".") === 0;
144
94
  function poiMapNameXForm(poi) {
145
95
  let name = poi.name;
146
96
  if (!config.poiMapNameXForm) {
147
97
  return name;
148
- } // no transforms for me today, thanks
149
- Object.keys(config.poiMapNameXForm)
150
- .filter(c2 => withinCategory(poi.category, c2))
151
- .forEach(c2 => {
152
- const xforms = config.poiMapNameXForm[c2]; // an array of xforms
153
- xforms.forEach(xform => (name = name.replace(new RegExp(xform.replace), xform.with)));
154
- });
98
+ }
99
+ Object.keys(config.poiMapNameXForm).filter((c2) => withinCategory(poi.category, c2)).forEach((c2) => {
100
+ const xforms = config.poiMapNameXForm[c2];
101
+ xforms.forEach((xform) => name = name.replace(new RegExp(xform.replace), xform.with));
102
+ });
155
103
  return name;
156
104
  }
157
-
158
- /*
159
- This function replaces POI labels with the poi.mapLabel (if it exists).
160
- If it does not exist and the config.copyPOINamesToMap is not explicitly set
161
- to `false` - then we copy the name from poi.name (and then put it through a
162
- set of transformations)
163
- */
164
105
  async function copyPOINames(mapFeatures) {
165
106
  const newMapFeatures = { ...mapFeatures };
166
- const pois = await app.bus.get('poi/getAll');
167
-
168
- Object.values(newMapFeatures).forEach(layerArray =>
169
- layerArray
170
- .filter(f => f.properties.aiLayer === 'poi' && f.geometry.type === 'Point')
171
- .forEach(f => {
172
- const poi = pois[f.properties.id];
173
- if (!poi) {
174
- log.warn(`Unknown poi in style: ${f.properties.id}`);
175
- } else {
176
- if (poi.mapLabel) {
177
- f.properties.text = poi.mapLabel;
178
- } else if (config.copyPOINamesToMap !== false) {
179
- f.properties.text = poiMapNameXForm(poi);
180
- }
107
+ const pois = await app.bus.get("poi/getAll");
108
+ Object.values(newMapFeatures).forEach(
109
+ (layerArray) => layerArray.filter((f) => f.properties.aiLayer === "poi" && f.geometry.type === "Point").forEach((f) => {
110
+ const poi = pois[f.properties.id];
111
+ if (!poi) {
112
+ log.warn(`Unknown poi in style: ${f.properties.id}`);
113
+ } else {
114
+ if (poi.mapLabel) {
115
+ f.properties.text = poi.mapLabel;
116
+ } else if (config.copyPOINamesToMap !== false) {
117
+ f.properties.text = poiMapNameXForm(poi);
181
118
  }
182
- }),
119
+ }
120
+ })
183
121
  );
184
-
185
122
  return newMapFeatures;
186
123
  }
187
-
188
- // pass in theme object (parsed from theme file)
189
124
  function replaceTheme(mapThemeSource) {
190
- app.bus.send('map/replaceTheme', { theme: mapThemeSource });
125
+ app.bus.send("map/replaceTheme", { theme: mapThemeSource });
191
126
  }
192
-
193
127
  function replaceStyle(mapStyleSource) {
194
- app.bus.send('map/replaceStyle', { styleSrc: mapStyleSource });
128
+ app.bus.send("map/replaceStyle", { styleSrc: mapStyleSource });
195
129
  }
196
-
197
- /**
198
- * Creates list of source ids from all floor ids and venue id and fetches GeoJSON features for each id.
199
- * Returns dictionary of source id to list of GeoJson features
200
- * @returns {Promise<Object<string, Array.<GeoJson>>>}
201
- */
202
130
  async function getMapFeatures(venueData) {
203
131
  return R__namespace.pipe(
204
- R__namespace.prop('structures'),
205
- R__namespace.map(R__namespace.prop('levels')),
132
+ R__namespace.prop("structures"),
133
+ R__namespace.map(R__namespace.prop("levels")),
206
134
  R__namespace.chain(R__namespace.keys),
207
135
  // Generate list of level IDs plus the venue ID to fetch feature JSON for each
208
136
  R__namespace.prepend(venueData.id),
209
137
  // eslint-disable-next-line no-template-curly-in-string
210
- R__namespace.map(geoJsonId => venueData.files.geoJson.replace('${geoJsonId}', geoJsonId)),
138
+ R__namespace.map((geoJsonId) => venueData.files.geoJson.replace("${geoJsonId}", geoJsonId)),
211
139
  R__namespace.map(venueData.fetchJson),
212
140
  R__namespace.map(
213
- R__namespace.andThen(featureJSON => [
141
+ R__namespace.andThen((featureJSON) => [
214
142
  featureJSON.id,
215
- enrichFeaturesForLevel(featureJSON.id, featureJSON.features, venueData.id, venueData.structures),
216
- ]),
143
+ enrichFeaturesForLevel(featureJSON.id, featureJSON.features, venueData.id, venueData.structures)
144
+ ])
217
145
  ),
218
- promises => Zousan.all(promises),
219
- R__namespace.andThen(R__namespace.fromPairs),
146
+ (promises) => Zousan.all(promises),
147
+ R__namespace.andThen(R__namespace.fromPairs)
220
148
  )(venueData);
221
149
  }
222
-
223
150
  const enrichFeaturesForLevel = (levelId, features, venueId, structures) => {
224
- const structureId = levelId.replace(/-[^-]*$/, '');
225
- const ordinalId =
226
- structureId === venueId
227
- ? 'landscape-background'
228
- : `ordinal: ${structures.find(R__namespace.hasPath(['levels', levelId])).levels[levelId].ordinal}`;
229
- const enrichFeature = feature => {
230
- feature = mergeWithProp('properties', { venueId, structureId, ordinalId, levelId }, feature);
231
- feature = R__namespace.assoc('id', feature.properties.subid, feature);
151
+ const structureId = levelId.replace(/-[^-]*$/, "");
152
+ const ordinalId = structureId === venueId ? "landscape-background" : `ordinal: ${structures.find(R__namespace.hasPath(["levels", levelId])).levels[levelId].ordinal}`;
153
+ const enrichFeature = (feature) => {
154
+ feature = mergeWithProp("properties", { venueId, structureId, ordinalId, levelId }, feature);
155
+ feature = R__namespace.assoc("id", feature.properties.subid, feature);
232
156
  return feature;
233
157
  };
234
158
  return features.map(enrichFeature);
235
159
  };
236
-
237
- /**
238
- * Fetches map style, map theme, map GeoJson feature sources.
239
- * Transforms data to convenient format and sends an event venueData/mapDataLoaded with map data.
240
- */
241
- app.bus.on('venueData/loadMap', async () => {
242
- venueDataLoaded.then(async venueData => {
160
+ app.bus.on("venueData/loadMap", async () => {
161
+ venueDataLoaded.then(async (venueData) => {
243
162
  const mapStyleSource = await venueData.fetchText(venueData.files.style);
244
163
  const mapTheme = await venueData.fetchJson(venueData.files.theme);
245
164
  const badgesSpriteUrl = venueData.files.spritesheet;
246
165
  const mapGlyphsUrl = venueData.files.glyphs;
247
166
  const { id, bounds, structures, venueCenter, venueRadius, defaultOrdinal } = venueData;
248
- const mapFeatures = venueData.venueList[id].mapTokens
249
- ? { [id]: [] }
250
- : await getMapFeatures(venueData).then(copyPOINames);
167
+ const mapFeatures = venueData.venueList[id].mapTokens ? { [id]: [] } : await getMapFeatures(venueData).then(copyPOINames);
251
168
  const venueBounds = {
252
169
  n: bounds.ne.lat,
253
170
  s: bounds.sw.lat,
254
171
  e: bounds.ne.lng,
255
- w: bounds.sw.lng,
172
+ w: bounds.sw.lng
256
173
  };
257
174
  const mapData = {
258
175
  mapFeatures,
@@ -267,218 +184,152 @@ async function create(app, config) {
267
184
  venueCenter,
268
185
  venueRadius,
269
186
  accountId: config.accountId,
270
- secure: config.auth !== undefined,
271
- tileServerAuthInfo: venueData.tileServerAuthInfo, // only defined for tile maps
187
+ secure: config.auth !== void 0,
188
+ tileServerAuthInfo: venueData.tileServerAuthInfo
189
+ // only defined for tile maps
272
190
  };
273
191
  mapDataLoaded.resolve(mapData);
274
- app.bus.send('venueData/mapDataLoaded', mapData);
192
+ app.bus.send("venueData/mapDataLoaded", mapData);
275
193
  });
276
194
  });
277
-
278
- // accept when shouldDisplay is null or undefined or true
279
- const shouldDisplayPredicate = building => building.shouldDisplay == null || building.shouldDisplay;
280
-
281
- // todo check if all async events are still needed (events that sends a new event as result, like 'venueData/buildingSelectorDataLoaded')
282
- app.bus.on('venueData/loadBuildingSelectorData', () => {
283
- return venueDataLoaded.then(async venueData => {
284
- // displayable buildings with levels list ordered by ordinal desc.
195
+ const shouldDisplayPredicate = (building) => building.shouldDisplay == null || building.shouldDisplay;
196
+ app.bus.on("venueData/loadBuildingSelectorData", () => {
197
+ return venueDataLoaded.then(async (venueData) => {
285
198
  const buildings = venueData.structures.filter(shouldDisplayPredicate).map(
286
199
  R__namespace.evolve({
287
200
  // creates copy of structure with modified levels
288
- levels: R__namespace.pipe(R__namespace.values, R__namespace.sortWith([R__namespace.descend(R__namespace.prop('ordinal'))])),
289
- }),
201
+ levels: R__namespace.pipe(R__namespace.values, R__namespace.sortWith([R__namespace.descend(R__namespace.prop("ordinal"))]))
202
+ })
290
203
  );
291
-
292
- // todo order buildings using structureOrder and selectorOrder
293
- // currently structures ordering is duplicated in level selectors handlers
294
- // then we can remove structureOrder and selectorOrder from result
295
204
  const result = {
296
205
  buildings,
297
206
  structureOrder: venueData.structureOrder,
298
- selectorOrder: venueData.selectorOrder,
207
+ selectorOrder: venueData.selectorOrder
299
208
  };
300
- app.bus.send('venueData/buildingSelectorDataLoaded', result);
209
+ app.bus.send("venueData/buildingSelectorDataLoaded", result);
301
210
  return result;
302
211
  });
303
212
  });
304
-
305
- app.bus.on('venueData/normalizeCoords', ({ coords }) =>
306
- venueDataLoaded.then(venueData => venueLoadingUtils.normalizeCoords(coords, venueData.bounds)),
213
+ app.bus.on(
214
+ "venueData/normalizeCoords",
215
+ ({ coords }) => venueDataLoaded.then((venueData) => venueLoadingUtils.normalizeCoords(coords, venueData.bounds))
307
216
  );
308
-
309
217
  const noNavInfo = { edges: [], nodes: [] };
310
- app.bus.on('venueData/loadNavGraph', async () => {
311
- return venueDataLoaded.then(async venueData => {
218
+ app.bus.on("venueData/loadNavGraph", async () => {
219
+ return venueDataLoaded.then(async (venueData) => {
312
220
  const navGraphData = venueData.files.nav ? await venueData.fetchJson(venueData.files.nav) : noNavInfo;
313
221
  const navGraphOb = { navGraphData, structures: venueData.structures };
314
- app.bus.send('venueData/navGraphLoaded', navGraphOb);
222
+ app.bus.send("venueData/navGraphLoaded", navGraphOb);
315
223
  return navGraphOb;
316
224
  });
317
225
  });
318
-
319
- app.bus.on('venueData/loadPoiData', async () => {
320
- return venueDataLoaded.then(async venueData => {
321
- const poisUrl = config.useOldDataModel
322
- ? venueData.files.poisOld || venueData.files.pois
323
- : venueData.files.pois || venueData.files.poisOld;
226
+ app.bus.on("venueData/loadPoiData", async () => {
227
+ return venueDataLoaded.then(async (venueData) => {
228
+ const poisUrl = config.useOldDataModel ? venueData.files.poisOld || venueData.files.pois : venueData.files.pois || venueData.files.poisOld;
324
229
  if (poisUrl) {
325
230
  const pois = await venueData.fetchJson(poisUrl);
326
- app.bus.send('venueData/poiDataLoaded', {
231
+ app.bus.send("venueData/poiDataLoaded", {
327
232
  pois,
328
- structures: venueData.structures,
233
+ structures: venueData.structures
329
234
  });
330
235
  }
331
236
  });
332
237
  });
333
-
334
- app.bus.on('venueData/getVenueCenter', async () =>
335
- venueDataLoaded.then(async venueData => ({
238
+ app.bus.on(
239
+ "venueData/getVenueCenter",
240
+ async () => venueDataLoaded.then(async (venueData) => ({
336
241
  lat: venueData.venueCenter[0],
337
242
  lng: venueData.venueCenter[1],
338
- ordinal: 0,
339
- })),
243
+ ordinal: 0
244
+ }))
340
245
  );
341
-
342
- app.bus.on('venueData/getContentUrl', ({ type, name = '' }) =>
343
- venueDataLoaded.then(venueData => venueData.files[type] + name),
246
+ app.bus.on(
247
+ "venueData/getContentUrl",
248
+ ({ type, name = "" }) => venueDataLoaded.then((venueData) => venueData.files[type] + name)
344
249
  );
345
-
346
- app.bus.on('venueData/getFloorIdToNameMap', () =>
347
- venueDataLoaded.then(
250
+ app.bus.on(
251
+ "venueData/getFloorIdToNameMap",
252
+ () => venueDataLoaded.then(
348
253
  R__namespace.pipe(
349
- R__namespace.prop('structures'),
350
- R__namespace.map(R__namespace.prop('levels')), // get levels for each structure
351
- R__namespace.chain(R__namespace.values), // flatten structures levels into single array
352
- R__namespace.map(R__namespace.props(['id', 'name'])), // create pairs [id, name]
353
- R__namespace.fromPairs, // create map of 'id' to 'name'
354
- ),
355
- ),
254
+ R__namespace.prop("structures"),
255
+ R__namespace.map(R__namespace.prop("levels")),
256
+ // get levels for each structure
257
+ R__namespace.chain(R__namespace.values),
258
+ // flatten structures levels into single array
259
+ R__namespace.map(R__namespace.props(["id", "name"])),
260
+ // create pairs [id, name]
261
+ R__namespace.fromPairs
262
+ // create map of 'id' to 'name'
263
+ )
264
+ )
356
265
  );
357
-
358
- app.bus.on('venueData/getFloorIdName', ({ floorId }) => {
359
- return venueDataLoaded.then(async venueData => {
360
- const structure = R__namespace.pipe(R__namespace.values, R__namespace.find(R__namespace.hasPath(['levels', floorId])))(venueData.structures);
266
+ app.bus.on("venueData/getFloorIdName", ({ floorId }) => {
267
+ return venueDataLoaded.then(async (venueData) => {
268
+ const structure = R__namespace.pipe(R__namespace.values, R__namespace.find(R__namespace.hasPath(["levels", floorId])))(venueData.structures);
361
269
  if (!structure) {
362
270
  return null;
363
271
  }
364
272
  return {
365
273
  structureId: structure.id,
366
274
  structureName: structure.name,
367
- floorName: structure.levels[floorId].name,
275
+ floorName: structure.levels[floorId].name
368
276
  };
369
277
  });
370
278
  });
371
-
372
- const getVenueDataProp = (propName, defaultValue) => () =>
373
- venueDataLoaded.then(R__namespace.pipe(R__namespace.prop(propName), R__namespace.defaultTo(defaultValue)));
374
-
375
- app.bus.on('venueData/getVenueData', () => venueDataLoaded);
376
-
377
- app.bus.on('venueData/getVenueName', getVenueDataProp('name'));
378
-
379
- app.bus.on('venueData/getVenueCategory', getVenueDataProp('category'));
380
-
381
- app.bus.on('venueData/getVenueTimezone', getVenueDataProp('tz'));
382
- app.bus.on('venueData/getAccountId', () => config.accountId);
383
- app.bus.on('venueData/getVenueId', getVenueDataProp('id'));
384
-
385
- app.bus.on('venueData/getPositioningSupported', getVenueDataProp('positioningSupported'));
386
- app.bus.on('venueData/getStructures', getVenueDataProp('structures'));
387
-
388
- app.bus.on('venueData/loadNewVenue', async ({ venueId, accountId, assetStage = config.assetStage }) => {
389
- venueDataLoaded.reject(new Error('loadNewVenue called - previous loading ignored'));
390
- mapDataLoaded.reject(new Error('loadNewVenue called - previous loading ignored'));
279
+ const getVenueDataProp = (propName, defaultValue) => () => venueDataLoaded.then(R__namespace.pipe(R__namespace.prop(propName), R__namespace.defaultTo(defaultValue)));
280
+ app.bus.on("venueData/getVenueData", () => venueDataLoaded);
281
+ app.bus.on("venueData/getVenueName", getVenueDataProp("name"));
282
+ app.bus.on("venueData/getVenueCategory", getVenueDataProp("category"));
283
+ app.bus.on("venueData/getVenueTimezone", getVenueDataProp("tz"));
284
+ app.bus.on("venueData/getAccountId", () => config.accountId);
285
+ app.bus.on("venueData/getVenueId", getVenueDataProp("id"));
286
+ app.bus.on("venueData/getPositioningSupported", getVenueDataProp("positioningSupported"));
287
+ app.bus.on("venueData/getStructures", getVenueDataProp("structures"));
288
+ app.bus.on("venueData/loadNewVenue", async ({ venueId, accountId, assetStage = config.assetStage }) => {
289
+ venueDataLoaded.reject(new Error("loadNewVenue called - previous loading ignored"));
290
+ mapDataLoaded.reject(new Error("loadNewVenue called - previous loading ignored"));
391
291
  venueDataLoaded = new Zousan();
392
292
  mapDataLoaded = new Zousan();
393
293
  loadVenueData({ ...config, venueId, accountId, assetStage }, []).then(notifyState);
394
294
  });
395
-
396
- // returns a full URL to an image hosted on img.locuslabs.com, size has to be a string of format ${width}x${height}
397
- app.bus.on('venueData/getPoiImageUrl', ({ imageName, size }) => {
295
+ app.bus.on("venueData/getPoiImageUrl", ({ imageName, size }) => {
398
296
  return `https://img.locuslabs.com/resize/${config.accountId}/png/transparent/${size}contain/poi/${imageName}`;
399
297
  });
400
-
401
- // This is an utility function that returns a unique ID used to distinguish certain, installation/deployment specific parts
402
- // for now it uses venueId and accountId and is used to fix collision when storing data in localStorage
403
- app.bus.on('venueData/getDistributionId', () => {
404
- return venueDataLoaded.then(venueData => {
298
+ app.bus.on("venueData/getDistributionId", () => {
299
+ return venueDataLoaded.then((venueData) => {
405
300
  return `${venueData.baseVenueId}-${config.accountId}`;
406
301
  });
407
302
  });
408
-
409
- app.bus.on('venueData/getCustomKeywords', () =>
410
- venueDataLoaded.then(venueData => {
411
- const searchUrl = config.useOldDataModel
412
- ? venueData.files.searchOld || venueData.files.search
413
- : venueData.files.search;
303
+ app.bus.on(
304
+ "venueData/getCustomKeywords",
305
+ () => venueDataLoaded.then((venueData) => {
306
+ const searchUrl = config.useOldDataModel ? venueData.files.searchOld || venueData.files.search : venueData.files.search;
414
307
  return venueData.fetchJson(searchUrl);
415
- }),
308
+ })
416
309
  );
417
-
418
- app.bus.on('venueData/isGrabEnabled', getVenueDataProp('enableGrab'));
419
-
420
- app.bus.on('venueData/getGrabPoiIds', getVenueDataProp('grabPoiIds', []));
421
-
422
- app.bus.on('venueData/getAssetsTimestamp', getVenueDataProp('version'));
423
-
424
- app.bus.on('venueData/getTranslatedFloorId', async ({ floorId }) =>
425
- venueDataLoaded.then(venueData => getTranslatedFloorId(floorId, venueData)),
310
+ app.bus.on("venueData/isGrabEnabled", getVenueDataProp("enableGrab"));
311
+ app.bus.on("venueData/getGrabPoiIds", getVenueDataProp("grabPoiIds", []));
312
+ app.bus.on("venueData/getAssetsTimestamp", getVenueDataProp("version"));
313
+ app.bus.on(
314
+ "venueData/getTranslatedFloorId",
315
+ async ({ floorId }) => venueDataLoaded.then((venueData) => getTranslatedFloorId(floorId, venueData))
426
316
  );
427
-
428
- /**
429
- * Takes a floorId that may be from the same venue but localized differently
430
- * so it must be converted to this venue's floorId. FloorIds are of the form
431
- * <venueId>-<buildingId>-<levelId> where <venueId> has a 2-letter suffice from
432
- * its baseVenueId.
433
- *
434
- * e.g. dfw-building1-level1 -> dfwxx-building1-level1
435
- * or dfwxx-building1-level1 -> dfw-building1-level1
436
- * or dfwxx-building1-level1 -> dfwyy-building1-level1
437
- *
438
- * @param {string} floorId - The floor ID to translate.
439
- * @param {Object} venueData - The venue data object containing the baseVenueId and structures.
440
- * @returns {string} - The translated floor ID that matches the venue's baseVenue
441
- */
442
317
  function getTranslatedFloorId(floorId, venueData) {
443
318
  const allFloorIds = getAllFloorIds(venueData);
444
-
445
319
  if (allFloorIds.includes(floorId)) {
446
320
  return floorId;
447
- } // already in this venue
448
-
449
- const buildingLevel = floorId.split('-').slice(1).join('-'); // get the building-level part of the floorId
450
-
451
- // find a floor in the current venueData that matches the specified floorId with just an adjustment to the venueId portion in floorId string construct
452
- return allFloorIds.find(fid => new RegExp(`${venueData.baseVenueId}.?.?-${buildingLevel}`).test(fid));
321
+ }
322
+ const buildingLevel = floorId.split("-").slice(1).join("-");
323
+ return allFloorIds.find((fid) => new RegExp(`${venueData.baseVenueId}.?.?-${buildingLevel}`).test(fid));
453
324
  }
454
-
455
- // returns a list of all floor ids in the venue data
456
- const getAllFloorIds = venueData =>
457
- venueData.structures.reduce((floors, s) => floors.concat(Object.keys(s.levels)), []);
458
-
459
- /**
460
- * Returns object with queue types (security and immigration lanes) that are present in the venue defined in venue data.
461
- * Also adds image id for lanes with images.
462
- *
463
- * @typedef QueueType
464
- * @property {boolean} default
465
- * @property {string} defaultText
466
- * @property {string} id
467
- * @property {string} imageId
468
- *
469
- * @typedef QueueTypes
470
- * @property {QueueType[]} SecurityLane - list of security categories
471
- * @property {QueueType[]} ImmigrationLane - list of immigration categories
472
- *
473
- * @return {QueueTypes} queueTypes
474
- */
475
- app.bus.on('venueData/getQueueTypes', () => {
476
- return venueDataLoaded.then(venueData => {
477
- const lanesWithImages = ['tsapre', 'clear', 'globalEntry'];
325
+ const getAllFloorIds = (venueData) => venueData.structures.reduce((floors, s) => floors.concat(Object.keys(s.levels)), []);
326
+ app.bus.on("venueData/getQueueTypes", () => {
327
+ return venueDataLoaded.then((venueData) => {
328
+ const lanesWithImages = ["tsapre", "clear", "globalEntry"];
478
329
  if (venueData.queueTypes) {
479
330
  return venueData.queueTypes.reduce((obj, category) => {
480
331
  const { id, subtypes } = category;
481
- const typesWithImages = subtypes.map(type => {
332
+ const typesWithImages = subtypes.map((type) => {
482
333
  const imageId = lanesWithImages.includes(type.id) && `security-logo-${type.id.toLowerCase()}`;
483
334
  return { ...type, imageId };
484
335
  });
@@ -490,7 +341,6 @@ async function create(app, config) {
490
341
  }
491
342
  });
492
343
  });
493
-
494
344
  const runTest = async ({ testRoutine, reset = false, venueData = null }) => {
495
345
  if (reset || venueData) {
496
346
  venueDataLoaded = new Zousan();
@@ -499,9 +349,7 @@ async function create(app, config) {
499
349
  if (venueData) {
500
350
  venueDataLoaded = Zousan.resolve(venueData);
501
351
  }
502
-
503
352
  await testRoutine();
504
-
505
353
  let venueDataObj, mapDataObj;
506
354
  if (venueDataLoaded.v) {
507
355
  venueDataObj = await venueDataLoaded;
@@ -511,15 +359,12 @@ async function create(app, config) {
511
359
  }
512
360
  return { venueDataObj, mapDataObj };
513
361
  };
514
-
515
362
  const init = async () => {
516
- const params = new URLSearchParams(typeof window === 'undefined' ? '' : window.location.search);
517
- const lang = params.get('lang');
518
- // On first load there is no URL param for lang unless a customer has created one on purposed, in which case that languauge will be loaded in the UI and the map. If it is first load and no language is specified by the param, grab the browser's list of preferred languages. We will then try to display a map venue for their preferred languages in order if we have it.
363
+ const params = new URLSearchParams(typeof window === "undefined" ? "" : window.location.search);
364
+ const lang = params.get("lang");
519
365
  let languagesToTry = [];
520
366
  if (lang === null) {
521
- // So if it is first load
522
- languagesToTry = typeof window === 'undefined' ? [] : navigator.languages; // grab languages to use for alternate maps from the browser's list of preffered languages
367
+ languagesToTry = typeof window === "undefined" ? [] : navigator.languages;
523
368
  }
524
369
  const deepLinkProps = config.deepLinkProps || {};
525
370
  if (deepLinkProps.lang) {
@@ -527,10 +372,9 @@ async function create(app, config) {
527
372
  }
528
373
  const venueId = deepLinkProps.vid || config.venueId;
529
374
  const assetStage = config.useDynamicUrlParams && deepLinkProps.stage ? deepLinkProps.stage : config.assetStage;
530
- const accountId = deepLinkProps.accountId || (assetStage === 'alpha' ? 'A1VPTJKREFJWX5' : config.accountId);
375
+ const accountId = deepLinkProps.accountId || (assetStage === "alpha" ? "A1VPTJKREFJWX5" : config.accountId);
531
376
  loadVenueData({ ...config, venueId, accountId, assetStage }, languagesToTry).then(notifyState);
532
377
  };
533
-
534
378
  return {
535
379
  init,
536
380
  runTest,
@@ -540,8 +384,8 @@ async function create(app, config) {
540
384
  getTranslatedFloorId,
541
385
  setConfigProperty: (key, value) => {
542
386
  config[key] = value;
543
- },
544
- },
387
+ }
388
+ }
545
389
  };
546
390
  }
547
391