@expofp/floorplan
Version:
Interactive floor plan library for expos and events
2 lines (1 loc) • 18.1 kB
JavaScript
import{Fragment as A,jsx as x,jsxs as T}from"react/jsx-runtime";import{Box as E}from"@expofp/geometry";import{CameraSchema as I}from"@expofp/schema";import{optimizeWaypointOrder as M}from"@expofp/wayfinding";import{ErrorBoundary as R}from"@sentry/react";import $ from"debug";import{reaction as V}from"mobx";import{createRoot as z}from"react-dom/client";import{install as j}from"resize-observer";import G from"./components/Layout";import{MAX_ROUTE_WAYPOINTS as d}from"./constants";import q from"./data";import{fpGeo as b}from"./data/fpGeo";import N from"./floorplan.loader";import{shouldLoadIntercom as O}from"./intercom";import{BoundsSchema as U,POISelectorsSchema as w,ZoomToOptionsSchema as P}from"./schemas/sdk.schemas";import{applyDeclarativeConfig as H,applyParameters as Y,applyPathway as _,initUrlRouting as D}from"./services/url-dispatch";import{destroyUrlSync as W}from"./services/url-sync";import r from"./store";import{destroyUiHandlers as X}from"./store/init/init-ui";import{findBooth as S,Route as v,separateExternalIds as B}from"./store/RouteStore";import{destroyGtag as K,GaEventActions as k,sendEventToGa as F,setConsentSettings as Q}from"./tools/gtag";import Z from"./tools/report-error";import{resetGlobalVariables as J}from"./tools/reset";import ee from"./tools/track-event";import{cameraToMapSettings as te,mapSettingsToCamera as re}from"./utils/camera-map-settings";import{getStorage as C}from"./utils/entity-storage";import{convertLocalToGps as oe,isValidPointCoords as y}from"./utils/gps";import{getLocales as ie,hasLocale as se,setLocale as ne}from"./utils/i18n";import{mapEntity as g}from"./utils/mapEntity";const p=$("efp:api");j();export default class ae extends N{init(){H(),this.ignoreQuery||D(this.offHistory),ee("load"),r.fp=this,Q(this.consent),F(k.Load,""),this.root=z(this.renderTarget),this.root.render(x(R,{children:x(G,{offHistory:this.offHistory,consent:this.consent})})),F(k.Rendered,""),V(()=>r.layerStore.layersLoaded,()=>{this.resolveReady(),r.initialized||this.onInit?.(this),r.initialized=!0});const e=O(q);e&&import("./intercom/bootIntercom").then(({bootIntercom:t})=>t(e)).catch(()=>{})}selectBooth(e){if(typeof e!="string"&&!Array.isArray(e)){a("selectBooth","Parameter must be a string or an array of strings.","EFP000000");return}const t=r.boothStore.booths.filter(o=>typeof e=="string"?o.name===e||o.externalId===e:e.includes(o.name)||e.includes(o.externalId));r.selectBooth(t)}selectExhibitor(e){if(typeof e!="string"&&!Array.isArray(e)){a("selectExhibitor","Parameter must be a string or an array of strings.","EFP000100");return}if(!e?.length){r.uiState.menu=!1,r.searchStore.resetSearchBox(),r.uiState.details=null;return}const t=r.exhibitorStore.exhibitors.filter(i=>typeof e=="string"?i.name===e||i.externalId===e:e.includes(i.name)||e.includes(i.externalId));if(!t?.length)return;if(typeof e=="string"){r.selectExhibitor(t[0]),r.moveToList([t[0]]);return}const o=t.flatMap(i=>i.booths.map(s=>s.layer)),{description:n}=o.reduce((i,s)=>(i.freq[s.description]=(i.freq[s.description]||0)+1,i.freq[s.description]>i.maxCount&&(i.maxCount=i.freq[s.description],i.mostFrequent=s),i),{freq:{},mostFrequent:o[0],maxCount:0}).mostFrequent;r.layerStore.updateVisibility(n,!0),r.uiState.menu=!1,r.searchStore.resetSearchBox(),r.uiState.details=null,r.uiState.list={type:"filter",items:t,query:{key:"exhibitors",value:t.map(i=>i.externalId).join(",")}},r.moveToList()}highlightExhibitors(e){Array.isArray(e)||a("highlightExhibitors","Parameter must be an array of strings.","EFP000200"),r.boothStore.highlightedByExternalIds=[],r.exhibitorStore.highlightedByExternalIds=[...e]}highlightBooths(e){Array.isArray(e)||a("highlightBooths","Parameter must be an array of strings.","EFP000300"),r.exhibitorStore.highlightedByExternalIds=[],r.boothStore.highlightedByExternalIds=[...e]}highlightEntities(e){Array.isArray(e)||a("highlightEntities","Parameter must be an array of strings.","EFP000400");const{boothExternalIds:t,exhibitorExternalIds:o}=B(e);r.boothStore.highlightedByExternalIds=[...t],r.exhibitorStore.highlightedByExternalIds=[...o]}selectRoute(e,t){if(Array.isArray(e)){let o=[...e];const n=o.shift(),i=o.pop();if(o.length>d)throw new Error(`The maximum number of waypoints is ${d}.`);if(!n||!i){a("selectRoute","Invalid route format: When providing an array, it must include at least two points: a start and a destination.","EFP000401");return}r.routeStore.selectRoute(new v(m(n),m(i),o.map(m)));return}e||a("selectRoute","At a minimum, the starting point must be passed.","EFP000402"),r.routeStore.selectRoute(new v(m(e),m(t)))}getOptimizedRoutes(e){if(!Array.isArray(e))return a("getOptimizedRoutes","Parameter must be an array.","EFP000500"),[];if(e.length>d)throw new Error(`The maximum number of waypoints is ${d}.`);const t=e.map(m).filter(n=>!!n);if(!t.length)throw new Error("No booths found for the provided waypoints.");const o=new Map;for(const n of t){const i=n.layer?.name??"",s=o.get(i);s?s.push(n):o.set(i,[n])}return Array.from(o.values()).map(n=>({waypoints:M(n.map(i=>[i.name,{x:i.rect.center.x,y:i.rect.center.y}]))}))}selectCurrentPosition(e,t,o){const n=y(e.x)&&y(e.y),i=y(e.lng)&&y(e.lat);!n&&!i&&a("selectCurrentPosition","A point must be passed. Either (x,y) or (lat,lng) are required.","EFP000600"),r.routeStore.selectCurrentPosition(e,t,o),this.onCurrentPositionChanged?.(e)}setBookmarks(e){(!Array.isArray(e)||!e.length)&&a("setBookmarks","Parameter must be an array.","EFP000700"),e.forEach(t=>{const o=r.exhibitorStore.exhibitors.find(n=>n.name===t.name||n.externalId===t.externalId);o&&(o.bookmarked=t.bookmarked)})}setEntitiesBookmarks(e){if(!Array.isArray(e)||!e.length){a("setEntitiesBookmarks","Parameter must be an array.","EFP000701");return}const t=["exhibitor","event","speaker","booth"],o=e.find(s=>!s.type||!t.includes(s.type));if(o){a("setEntitiesBookmarks",`Invalid entity type: ${o.type}. Must be one of: ${t.join(", ")}.`,"EFP000702");return}const n=C("bookmarked"),i={exhibitor:{existingIds:new Set(n.exhibitors||[]),finder:s=>r.exhibitorStore.findExhibitor(s),replacer:s=>r.exhibitorStore.replaceBookmarked(s)},event:{existingIds:new Set(n.events||[]),finder:s=>r.eventStore.findByNameOrSlug(s),replacer:s=>r.eventStore.replaceBookmarked(s)},speaker:{existingIds:new Set(n.speakers||[]),finder:s=>r.speakerStore.speakers.find(h=>h.name===s||h.externalId===s||h.slug===s),replacer:s=>r.speakerStore.replaceBookmarked(s)},booth:{existingIds:new Set(n.booths||[]),finder:s=>{const h=r.boothStore.findBooth(s);return h?.exhibitors.length===0?h:void 0},replacer:s=>r.boothStore.replaceBookmarked(s)}};e.forEach(s=>{const h=i[s.type],c=s.name||s.externalId||"",l=h.finder(c);l?s.bookmarked?h.existingIds.add(l.id):h.existingIds.delete(l.id):console.warn(`Entity not found: ${s.type} with query "${c}"`)}),Object.values(i).forEach(s=>{s.replacer(Array.from(s.existingIds))})}setEntitiesVisited(e){if(!Array.isArray(e)||!e.length){a("setEntitiesVisited","Parameter must be an array.","EFP000703");return}const t=["exhibitor","event"],o=e.find(s=>!s.type||!t.includes(s.type));if(o){a("setEntitiesVisited",`Invalid entity type: ${o.type}. Must be one of: ${t.join(", ")}.`,"EFP000704");return}const n=C("visited"),i={exhibitor:{existingIds:new Set(n.exhibitors||[]),finder:s=>r.exhibitorStore.findExhibitor(s),replacer:s=>r.exhibitorStore.replaceVisited(s)},event:{existingIds:new Set(n.events||[]),finder:s=>r.eventStore.findByNameOrSlug(s),replacer:s=>r.eventStore.replaceVisited(s)}};e.forEach(s=>{const h=i[s.type],c=s.name||s.externalId||"",l=h.finder(c);l?s.visited?h.existingIds.add(l.id):h.existingIds.delete(l.id):console.warn(`Entity not found: ${s.type} with query "${c}"`)}),Object.values(i).forEach(s=>{s.replacer(Array.from(s.existingIds))})}setMarkers(e){if(!e||!Array.isArray(e.icons)||!Array.isArray(e.markers)){a("setMarkers","Invalid input.","EFP000800");return}r.routeStore.setMarkers(e)}selectMarker(e,t=!0){return typeof e!="string"&&a("selectMarker","The identifier must be passed.","EFP000900"),r.routeStore.selectMarker(e,t)}drawCircles(e){Array.isArray(e)||a("drawCircles","Invalid input.","EFP000A00"),r.uiState.debugCircles=e}checkRoutes(){r.routeStore.checkRoutes()}updateLayerVisibility(e,t){typeof e!="string"&&a("updateLayerVisibility","The layer name (string) must be passed.","EFP000B00"),t||a("updateLayerVisibility","Passing a false value to visible will have no effect.","EFP000B01"),r.layerStore.updateVisibility(e,t)}getCenterCoordinates(){return r.fp.getCenterCoordinates()}exhibitorsList(){return r.exhibitorStore.exhibitors.map(e=>g(e))}boothsList(){return r.boothStore.booths.map(e=>g(e))}categoriesList(){return r.categoryStore.categories.map(e=>g(e))}selectCategory(e){if(e==null||typeof e!="string"){r.searchStore.selectSearch();return}const t=e?.toLowerCase(),o=r.categoryStore.categories.find(({name:n,slug:i})=>n?.toLowerCase()===t||i?.toLowerCase()===t);if(!o){a("selectCategory",`Category ${e} not found.`,"EFP000C01");return}r.selectCategory(o)}select(e){if(typeof e!="string"){a("select","Parameter must be a string.","EFP001700");return}const t=e,o=t?.toLowerCase(),n=r.boothStore.booths.find(l=>l.slug?.toLowerCase()===o||l.externalId?.toLowerCase()===o||l.externalId?.toLowerCase()?.replace(/\s+/g,"")===o);if(n){setTimeout(()=>r.selectBooth(n),250);return}const i=r.eventStore.eventItems.find(l=>l.slug?.toLowerCase()===o||l.externalId?.toLowerCase()===o);if(i){r.selectEventItem(i,!0);return}const s=r.exhibitorStore.exhibitors.find(l=>l.slug?.toLowerCase()===o||l.externalId?.toLowerCase()===o);if(s){setTimeout(()=>r.clickExhibitor(s),250);return}const h=r.categoryStore.categories.find(l=>l.slug===t);if(h){r.selectCategory(h);return}const c=r.speakerStore.findBySlug(t);if(c){r.selectSpeaker(c,!0);return}t.includes("heatmap=true")||r.searchStore.selectSearch(t)}showList(e){const t={bookmarks:()=>r.selectBookmarks(),visited:()=>r.selectVisited(),sessions:()=>r.selectSessions(),exhibitors:()=>r.selectExhibitors(),speakers:()=>r.selectSpeakers(),tours:()=>r.selectTours(),language:()=>r.selectLanguage()},o=t[e];if(!o){a("showList",`Unknown list "${e}". Must be one of: ${Object.keys(t).join(", ")}.`,"EFP001800");return}o()}selectTour(e){if(typeof e!="string"||!e){a("selectTour","A tour id must be passed.","EFP001900");return}const t=r.toursStore.getTourById(e);t?r.toursStore.launchTour(t,t.name,t.description):(console.warn(`Route with id "${e}" not found`),r.selectTours())}openPlanner(e={}){if(typeof e!="object"||e===null){a("openPlanner","An options object must be passed.","EFP001A00");return}const t=e.from?S(e.from):null;e.fromBookmarks?r.routePlannerStore.launchFromBookmarks(t??void 0):r.routePlannerStore.launchFromSlugs(e.items??[],t??void 0)}startBuildRoute(){r.uiState.startBuildRoute()}applyParameters(e){typeof e!="string"&&a("applyParameters","A query string must be passed.","EFP000D00"),Y(e)}getVisibility(){return r.uiState.visibility}setVisibility(e){(typeof e!="object"||!Object.keys(e).length)&&a("setVisibility","The parameter must be passed.","EFP000E00"),r.uiState.setVisibility(e)}findLocation(){r.routeStore.findLocation()}zoomIn(){r.uiState.zoomIn()}zoomOut(){r.uiState.zoomOut()}switchView(){r.maplibreStore.activateMaplibre()}setCamera(e){p("setCamera called with camera=%O",e);const t=I.safeParse(e);if(!t.success){a("setCamera",t.error.message,"EFP001B00");return}r.uiState.setMapSettings(te(t.data))}getCamera(){return re(r.uiState.mapSettings)}zoomTo(e,t){p("zoomTo called with selectors=%O options=%O",e,t);const o=w.safeParse(e);if(!o.success){a("zoomTo",o.error.message,"EFP001600");return}const n=P.safeParse(t);if(!n.success){a("zoomTo",n.error.message,"EFP001601");return}const i=this.getBounds(e);i&&this.fitBounds(i,t)}getBounds(e){p("getBounds called with selectors=%O",e);const t=w.safeParse(e);if(!t.success){a("getBounds",t.error.message,"EFP001400");return}const o=[];if(e.booths?.forEach(i=>{let s;i.externalId?s=r.boothStore.boothByExternalId.get(i.externalId):i.name&&(s=r.boothStore.boothByName.get(i.name.toLowerCase())),s?.rect&&o.push(s.rect)}),e.exhibitors?.forEach(i=>{let s;i.externalId?s=r.exhibitorStore.exhibitorByExternalId.get(i.externalId):i.name&&(s=r.exhibitorStore.exhibitorByName.get(i.name.toLowerCase())),s?.booths?.forEach(h=>{h.rect&&o.push(h.rect)})}),o.length===0)return;const n=E.fromUnion(...o);return{leftTop:{x:n.min.x,y:n.min.y},rightBottom:{x:n.max.x,y:n.max.y}}}fitBounds(e,t){if(p("fitBounds called with bounds=%O options=%O",e,t),!e){r.uiState.fitBounds();return}const o=U.safeParse(e);if(!o.success){a("fitBounds",o.error.message,"EFP001500");return}const n=P.safeParse(t);if(!n.success){a("fitBounds",n.error.message,"EFP001501");return}const i=E.fromMinMax({x:e.leftTop.x,y:e.leftTop.y},{x:e.rightBottom.x,y:e.rightBottom.y});r.uiState.moveToRect=t?.padding?i.expand(t.padding):i}getBoothRect(e){typeof e!="string"&&a("getBoothRect","A booth name must be passed.","EFP000F00");const t=S(e)?.rect;return t?u.fromBox(t):void 0}convertToGeo(e,t){if(!b?.properties?.config){a("convertToGeo","The coordinates cannot be converted because the GPS configuration is not defined.","EFP001000");return}if(!e||!t){a("convertToGeo","Both coordinates must be passed.","EFP001001");return}return oe(e,t,b.properties.config)}getGeoConfig(){const e=b?.properties?.config;return e?{bearing:e.bearing??0,p0:e.p0,p1:e.p1,p2:e.p2}:null}unstable_destroy(){let e=window.__efpElement.firstChild;J(),window.removeEventListener("__efpStyleLoad",this.efpStyleLoadHandler),window.removeEventListener("error",Z),r.maplibreStore.dispose(),W(),X(),K(),this.root.unmount(),e.remove()}search(e){return typeof e!="string"&&a("search","A search string must be passed.","EFP001100"),r.fuzzySearchEngineStore.loadEngine().then(()=>(r.searchStore.selectSearch(e),r.uiState.fuzzySearchItems.map(t=>({item:g(t.item),score:t.score}))))}getFloors(){return r.layerStore.floors.map(e=>({name:e.name,shortName:e.shortName,description:e.description,active:e.active,disabled:e.disabled,index:e.index}))}activateFloor(e){if(!e?.name&&e?.index==null){a("activateFloor","Invalid floorId. It must contain either a name or an index.","EFP001200");return}const t=this.getFloors();if(e.name){const o=t.find(n=>n.name===e.name||n.shortName===e.name);if(!o){a("activateFloor",`Floor with name "${e.name}" not found.`,"EFP001201");return}if(o.active)return;this.updateLayerVisibility(o.name,!0);return}if(e.index!==null){const o=t.find(i=>i.index===e.index),n=o?.name;if(!n){a("activateFloor",`Floor at index ${e.index} does not exist.`,"EFP001203");return}if(o.active)return;this.updateLayerVisibility(n,!0);return}}showPathway(e,t){const{boothExternalIds:o,exhibitorExternalIds:n}=t?.length?B(t):{boothExternalIds:[],exhibitorExternalIds:[]};_({pathwayId:e,boothIds:o,exhibitorIds:n})}showPathwayOnly(e,t){this.activateFloor({name:t}),r.layerStore.showPathWay(e),r.uiState.setPathwayOnlyMode(!0);const o=r.layerStore.findLayer(e),n=r.layerStore.findLayer(t),i=o?.rect||o?.viewbox?o:n;if(i?.rect||i?.viewbox){const s=i.viewbox??i.rect;r.uiState.moveToRect=s.clone()}}hidePathways(){this.highlightBooths([]),r.layerStore.hidePathways(),r.uiState.setPathwayOnlyMode(!1)}showSearch(){r.selectSearch("")}changeLanguage(e){const t=e?.toLowerCase?.();if(!se(t)){a("changeLanguage",`Language "${e}" was not found. Available languages: ${ie().map(o=>o.id).join(",")}`,"EFP001300");return}ne(t)}isGpsTrackingEnabled(){return r.routeStore.gpsEnabled}setGpsTrackingEnabled(e){r.routeStore.setGpsTrackingEnabled(e)}deselectCurrentPosition(){r.routeStore.selectCurrentPosition(null,!1)}deselectRoute(){r.routeStore.selectRoute(null),r.routeStore.setOnlyAccessible(!1)}reset(){this.selectBooth(""),this.selectExhibitor(""),this.selectCategory(),this.deselectCurrentPosition(),this.deselectRoute(),this.highlightEntities([]),r.uiState.kioskData&&r.resetCameraFn?r.resetCameraFn?.():this.fitBounds()}selectAccessibleRoute(e){r.routeStore.setOnlyAccessible(!0),this.selectRoute(e)}}function m(f){return typeof f=="string"?S(f):r.routeStore.getNearestBooth(f)}let L=0;function a(f,e,t){const o=`Error calling "${f}" SDK method.`,n=`${e.endsWith(".")?e:e+"."} More information at`;let i="https://js-sdk.expofp.com/api/packages";if(t&&(i+=`#error-${t}`),console.error(`${o} ${n} ${i}`),r.fp.disableRuntimeAlerts)return;r.uiState.setGlobalErrorMessage({title:o,body:T(A,{children:[n," ",x("a",{href:i,target:"_blank",rel:"noreferrer",children:i})]})}),clearTimeout(L);const s=8e3;L=window.setTimeout(()=>{const h=async()=>{r.uiState.globalErrorMessages.length>0&&(r.uiState.popGlobalErrorMessage(),await new Promise(c=>setTimeout(c,s/2)),h())};h()},s)}class u{get h(){return Math.abs(this.y2-this.y1)}get w(){return Math.abs(this.x2-this.x1)}get cx(){return(this.x1+this.x2)/2}get cy(){return(this.y1+this.y2)/2}constructor(e,t,o,n){if(e>o){const i=e;e=o,o=i}if(t>n){const i=t;t=n,n=i}this.x1=e,this.y1=t,this.x2=o,this.y2=n}static fromBox(e){return new u(e.min.x,e.min.y,e.max.x,e.max.y)}static fromCxcywh(e,t,o,n){return new u(e-o/2,t-n/2,e+o/2,t+n/2)}contains(e){return e.x1>=this.x1&&e.x2<=this.x2&&e.y1>=this.y1&&e.y2<=this.y2}intersects(e){const t=Math.max(this.x1,e.x1),o=Math.min(this.x2,e.x2),n=Math.max(this.y1,e.y1),i=Math.min(this.y2,e.y2);return o>=t&&i>=n}getIntersection(e){const t=Math.max(this.x1,e.x1),o=Math.min(this.x2,e.x2),n=Math.max(this.y1,e.y1),i=Math.min(this.y2,e.y2);return o>=t&&i>=n?new u(t,n,o,i):new u(0,0,0,0)}getRotated90(){return u.fromCxcywh(this.cx,this.cy,this.h,this.w)}normalize(e,t){return new u(this.x1/e,this.y1/t,this.x2/e,this.y2/t)}withPadding(e,t=e){return this.w<e*2||this.h<t*2?this:u.fromCxcywh(this.cx,this.cy,this.w-e*2,this.h-t*2)}scale(e){return new u(this.x1*e,this.y1*e,this.x2*e,this.y2*e)}getArea(){return this.w*this.h}clone(){return new u(this.x1,this.y1,this.x2,this.y2)}translate(e,t){return this.x1+=e,this.x2+=e,this.y1+=t,this.y2+=t,this}equals(e){return e.x1===this.x1&&e.x2===this.x2&&e.y1===this.y1&&e.y2===this.y2}toString(){return this.x1+","+this.y1+","+this.w+","+this.h}containsPoint(e,t){return e>=this.x1&&e<=this.x2&&t>=this.y1&&t<=this.y2}}