@expofp/floorplan
Version:
Interactive floor plan library for expos and events
2 lines (1 loc) • 18.5 kB
JavaScript
import{Fragment as T,jsx as x,jsxs as A}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{bindBoothHitTest as N}from"./components/Map/booth-by-xy";import{MAX_ROUTE_WAYPOINTS as d}from"./constants";import q from"./data";import{fpGeo as b}from"./data/fpGeo";import D from"./floorplan.loader";import{shouldLoadIntercom as H}from"./intercom";import{BoundsSchema as O,POISelectorsSchema as w,ZoomToOptionsSchema as P}from"./schemas/sdk.schemas";import{applyDeclarativeConfig as U,applyParameters as Y,applyPathway as W,initUrlRouting as X}from"./services/url-dispatch";import{destroyUrlSync as K}from"./services/url-sync";import r from"./store";import{bindDetailsEvents as Q}from"./store/details-events";import{bindRootElement as Z,destroyUiHandlers as J}from"./store/init/init-ui";import{findBooth as S,Route as v,separateExternalIds as B}from"./store/RouteStore";import{destroyGtag as _,GaEventActions as k,sendEventToGa as F,setConsentSettings as ee}from"./tools/gtag";import te from"./tools/report-error";import re,{resetTelemetry as oe}from"./tools/track-event";import{cameraToMapSettings as ie,mapSettingsToCamera as se}from"./utils/camera-map-settings";import{getStorage as C}from"./utils/entity-storage";import{getMostFrequent as ne}from"./utils/getMostFrequent";import{convertLocalToGps as ae,isValidPointCoords as y}from"./utils/gps";import{getLocales as he,hasLocale as le,setLocale as ce}from"./utils/i18n";import{mapEntity as g}from"./utils/mapEntity";const p=$("efp:api");j();export default class ue extends D{init(){U(),this.ignoreQuery||X(this.offHistory),re("load"),Z(r),r.fp=this,this.disposeDetailsEvents=Q(),this.disposeBoothHitTest=N(),ee(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,()=>{const t=this.renderTarget.getRootNode(),o=t instanceof ShadowRoot?t.host:this.renderTarget.parentElement;for(document.querySelectorAll(".expofp-floorplan-loader").forEach(s=>s.remove());o&&this.element.firstChild&&this.element.firstChild!==o;)this.element.removeChild(this.element.firstChild);this.resolveReady(),r.initialized||this.onInit?.(this),r.initialized=!0});const e=H(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(n=>typeof e=="string"?n.name===e||n.externalId===e:e.includes(n.name)||e.includes(n.externalId));if(!t?.length)return;if(typeof e=="string"){r.selectExhibitor(t[0]),r.moveToList([t[0]]);return}const o=t.flatMap(n=>n.booths.map(i=>i.layer)),s=ne(o.map(n=>n.description));s&&r.layerStore.updateVisibility(s,!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(n=>n.name).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 s=o.shift(),n=o.pop();if(o.length>d)throw new Error(`The maximum number of waypoints is ${d}.`);if(!s||!n){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(s),m(n),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(s=>!!s);if(!t.length)throw new Error("No booths found for the provided waypoints.");const o=new Map;for(const s of t){const n=s.layer?.name??"",i=o.get(n);i?i.push(s):o.set(n,[s])}return Array.from(o.values()).map(s=>({waypoints:M(s.map(n=>[n.name,{x:n.rect.center.x,y:n.rect.center.y}]))}))}selectCurrentPosition(e,t,o){const s=y(e.x)&&y(e.y),n=y(e.lng)&&y(e.lat);!s&&!n&&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(s=>s.name===t.name||s.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(i=>!i.type||!t.includes(i.type));if(o){a("setEntitiesBookmarks",`Invalid entity type: ${o.type}. Must be one of: ${t.join(", ")}.`,"EFP000702");return}const s=C("bookmarked"),n={exhibitor:{existingIds:new Set(s.exhibitors||[]),finder:i=>r.exhibitorStore.findExhibitor(i),replacer:i=>r.exhibitorStore.replaceBookmarked(i)},event:{existingIds:new Set(s.events||[]),finder:i=>r.eventStore.findByNameOrSlug(i),replacer:i=>r.eventStore.replaceBookmarked(i)},speaker:{existingIds:new Set(s.speakers||[]),finder:i=>r.speakerStore.speakers.find(h=>h.name===i||h.externalId===i||h.slug===i),replacer:i=>r.speakerStore.replaceBookmarked(i)},booth:{existingIds:new Set(s.booths||[]),finder:i=>{const h=r.boothStore.findBooth(i);return h?.exhibitors.length===0?h:void 0},replacer:i=>r.boothStore.replaceBookmarked(i)}};e.forEach(i=>{const h=n[i.type],u=i.name||i.externalId||"",l=h.finder(u);l?i.bookmarked?h.existingIds.add(l.id):h.existingIds.delete(l.id):console.warn(`Entity not found: ${i.type} with query "${u}"`)}),Object.values(n).forEach(i=>{i.replacer(Array.from(i.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(i=>!i.type||!t.includes(i.type));if(o){a("setEntitiesVisited",`Invalid entity type: ${o.type}. Must be one of: ${t.join(", ")}.`,"EFP000704");return}const s=C("visited"),n={exhibitor:{existingIds:new Set(s.exhibitors||[]),finder:i=>r.exhibitorStore.findExhibitor(i),replacer:i=>r.exhibitorStore.replaceVisited(i)},event:{existingIds:new Set(s.events||[]),finder:i=>r.eventStore.findByNameOrSlug(i),replacer:i=>r.eventStore.replaceVisited(i)}};e.forEach(i=>{const h=n[i.type],u=i.name||i.externalId||"",l=h.finder(u);l?i.visited?h.existingIds.add(l.id):h.existingIds.delete(l.id):console.warn(`Entity not found: ${i.type} with query "${u}"`)}),Object.values(n).forEach(i=>{i.replacer(Array.from(i.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:s,slug:n})=>s?.toLowerCase()===t||n?.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(),s=r.boothStore.booths.find(l=>l.slug?.toLowerCase()===o||l.externalId?.toLowerCase()===o||l.externalId?.toLowerCase()?.replace(/\s+/g,"")===o);if(s){setTimeout(()=>r.selectBooth(s),250);return}const n=r.eventStore.eventItems.find(l=>l.slug?.toLowerCase()===o||l.externalId?.toLowerCase()===o);if(n){r.selectEventItem(n,!0);return}const i=r.exhibitorStore.exhibitors.find(l=>l.slug?.toLowerCase()===o||l.externalId?.toLowerCase()===o);if(i){setTimeout(()=>r.clickExhibitor(i),250);return}const h=r.categoryStore.categories.find(l=>l.slug===t);if(h){r.selectCategory(h);return}const u=r.speakerStore.findBySlug(t);if(u){r.selectSpeaker(u,!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(ie(t.data))}getCamera(){return se(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 s=P.safeParse(t);if(!s.success){a("zoomTo",s.error.message,"EFP001601");return}const n=this.getBounds(e);n&&this.fitBounds(n,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(n=>{let i;n.externalId?i=r.boothStore.boothByExternalId.get(n.externalId):n.name&&(i=r.boothStore.boothByName.get(n.name.toLowerCase())),i?.rect&&o.push(i.rect)}),e.exhibitors?.forEach(n=>{let i;n.externalId?i=r.exhibitorStore.exhibitorByExternalId.get(n.externalId):n.name&&(i=r.exhibitorStore.exhibitorByName.get(n.name.toLowerCase())),i?.booths?.forEach(h=>{h.rect&&o.push(h.rect)})}),o.length===0)return;const s=E.fromUnion(...o);return{leftTop:{x:s.min.x,y:s.min.y},rightBottom:{x:s.max.x,y:s.max.y}}}fitBounds(e,t){if(p("fitBounds called with bounds=%O options=%O",e,t),!e){r.uiState.fitBounds();return}const o=O.safeParse(e);if(!o.success){a("fitBounds",o.error.message,"EFP001500");return}const s=P.safeParse(t);if(!s.success){a("fitBounds",s.error.message,"EFP001501");return}const n=E.fromMinMax({x:e.leftTop.x,y:e.leftTop.y},{x:e.rightBottom.x,y:e.rightBottom.y});r.uiState.moveToRect=t?.padding?n.expand(t.padding):n}getBoothRect(e){typeof e!="string"&&a("getBoothRect","A booth name must be passed.","EFP000F00");const t=S(e)?.rect;return t?c.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 ae(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}releaseResources(){window.removeEventListener("error",te),this.disposeDetailsEvents?.(),this.disposeDetailsEvents=void 0,this.disposeBoothHitTest?.(),this.disposeBoothHitTest=void 0,r.maplibreStore.dispose(),K(),J(),_(),oe(),this.root.unmount(),super.releaseResources()}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(s=>s.name===e.name||s.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(n=>n.index===e.index),s=o?.name;if(!s){a("activateFloor",`Floor at index ${e.index} does not exist.`,"EFP001203");return}if(o.active)return;this.updateLayerVisibility(s,!0);return}}showPathway(e,t){const{boothExternalIds:o,exhibitorExternalIds:s}=t?.length?B(t):{boothExternalIds:[],exhibitorExternalIds:[]};W({pathwayId:e,boothIds:o,exhibitorIds:s})}showPathwayOnly(e,t){this.activateFloor({name:t}),r.layerStore.showPathWay(e),r.uiState.setPathwayOnlyMode(!0);const o=r.layerStore.findLayer(e),s=r.layerStore.findLayer(t),n=o?.rect||o?.viewbox?o:s;if(n?.rect||n?.viewbox){const i=n.viewbox??n.rect;r.uiState.moveToRect=i.clone()}}hidePathways(){this.highlightBooths([]),r.layerStore.hidePathways(),r.uiState.setPathwayOnlyMode(!1)}showSearch(){r.selectSearch("")}changeLanguage(e){const t=e?.toLowerCase?.();if(!le(t)){a("changeLanguage",`Language "${e}" was not found. Available languages: ${he().map(o=>o.id).join(",")}`,"EFP001300");return}ce(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.`,s=`${e.endsWith(".")?e:e+"."} More information at`;let n="https://js-sdk.expofp.com/api/packages";if(t&&(n+=`#error-${t}`),console.error(`${o} ${s} ${n}`),r.fp.disableRuntimeAlerts)return;r.uiState.setGlobalErrorMessage({title:o,body:A(T,{children:[s," ",x("a",{href:n,target:"_blank",rel:"noreferrer",children:n})]})}),clearTimeout(L);const i=8e3;L=window.setTimeout(()=>{const h=async()=>{r.uiState.globalErrorMessages.length>0&&(r.uiState.popGlobalErrorMessage(),await new Promise(u=>setTimeout(u,i/2)),h())};h()},i)}class c{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,s){if(e>o){const n=e;e=o,o=n}if(t>s){const n=t;t=s,s=n}this.x1=e,this.y1=t,this.x2=o,this.y2=s}static fromBox(e){return new c(e.min.x,e.min.y,e.max.x,e.max.y)}static fromCxcywh(e,t,o,s){return new c(e-o/2,t-s/2,e+o/2,t+s/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),s=Math.max(this.y1,e.y1),n=Math.min(this.y2,e.y2);return o>=t&&n>=s}getIntersection(e){const t=Math.max(this.x1,e.x1),o=Math.min(this.x2,e.x2),s=Math.max(this.y1,e.y1),n=Math.min(this.y2,e.y2);return o>=t&&n>=s?new c(t,s,o,n):new c(0,0,0,0)}getRotated90(){return c.fromCxcywh(this.cx,this.cy,this.h,this.w)}normalize(e,t){return new c(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:c.fromCxcywh(this.cx,this.cy,this.w-e*2,this.h-t*2)}scale(e){return new c(this.x1*e,this.y1*e,this.x2*e,this.y2*e)}getArea(){return this.w*this.h}clone(){return new c(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}}