atriusmaps-node-sdk 3.3.196 → 3.3.225

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