@zonetrix/viewer 2.8.1 → 2.9.0

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.
@@ -0,0 +1,30 @@
1
+ import { Database } from 'firebase/database';
2
+ /**
3
+ * Initialize the Firebase database instance for the viewer
4
+ * This should be called by the host application after Firebase is initialized
5
+ *
6
+ * @example
7
+ * ```tsx
8
+ * import { initializeApp } from 'firebase/app';
9
+ * import { getDatabase } from 'firebase/database';
10
+ * import { initializeFirebaseForViewer } from '@zonetrix/viewer';
11
+ *
12
+ * const app = initializeApp(firebaseConfig);
13
+ * const db = getDatabase(app);
14
+ * initializeFirebaseForViewer(db);
15
+ * ```
16
+ */
17
+ export declare function initializeFirebaseForViewer(database: Database): void;
18
+ /**
19
+ * Get the Firebase database instance
20
+ * @throws Error if Firebase hasn't been initialized
21
+ */
22
+ export declare function getFirebaseDatabase(): Database;
23
+ /**
24
+ * Check if Firebase has been initialized for the viewer
25
+ */
26
+ export declare function isFirebaseInitialized(): boolean;
27
+ /**
28
+ * Clear the Firebase database instance (useful for testing)
29
+ */
30
+ export declare function clearFirebaseInstance(): void;
@@ -0,0 +1,41 @@
1
+ import { SeatMapConfig } from '../types';
2
+ export interface UseFirebaseConfigOptions {
3
+ /** The seat map ID to load */
4
+ seatMapId: string | null;
5
+ /** Whether loading is enabled (default: true) */
6
+ enabled?: boolean;
7
+ /** Subscribe to design changes in real-time (default: false) */
8
+ subscribeToChanges?: boolean;
9
+ /** Callback when config loads or changes */
10
+ onConfigLoad?: (config: SeatMapConfig) => void;
11
+ /** Callback on error */
12
+ onError?: (error: Error) => void;
13
+ }
14
+ export interface UseFirebaseConfigResult {
15
+ /** The loaded configuration */
16
+ config: SeatMapConfig | null;
17
+ /** Whether loading is in progress */
18
+ loading: boolean;
19
+ /** Any error that occurred */
20
+ error: Error | null;
21
+ /** Manually refetch the config */
22
+ refetch: () => Promise<void>;
23
+ }
24
+ /**
25
+ * Load seat map configuration from Firebase
26
+ *
27
+ * @example
28
+ * ```tsx
29
+ * // One-time load
30
+ * const { config, loading, error } = useFirebaseConfig({
31
+ * seatMapId: '123',
32
+ * });
33
+ *
34
+ * // With real-time design updates (for admin/editor preview)
35
+ * const { config } = useFirebaseConfig({
36
+ * seatMapId: '123',
37
+ * subscribeToChanges: true,
38
+ * });
39
+ * ```
40
+ */
41
+ export declare function useFirebaseConfig(options: UseFirebaseConfigOptions): UseFirebaseConfigResult;
@@ -0,0 +1,43 @@
1
+ import { FirebaseSeatStates } from '@zonetrix/shared';
2
+ export interface UseFirebaseSeatStatesOptions {
3
+ /** The seat map ID to subscribe to */
4
+ seatMapId: string | null;
5
+ /** Whether the subscription is enabled (default: true) */
6
+ enabled?: boolean;
7
+ /** Callback when states change */
8
+ onStateChange?: (states: FirebaseSeatStates) => void;
9
+ /** Callback on error */
10
+ onError?: (error: Error) => void;
11
+ }
12
+ export interface UseFirebaseSeatStatesResult {
13
+ /** Current seat states map */
14
+ states: FirebaseSeatStates | null;
15
+ /** Whether initial load is in progress */
16
+ loading: boolean;
17
+ /** Any error that occurred */
18
+ error: Error | null;
19
+ /** Timestamp of last update */
20
+ lastUpdated: number | null;
21
+ /** Derived arrays for SeatMapViewer props */
22
+ reservedSeats: string[];
23
+ unavailableSeats: string[];
24
+ }
25
+ /**
26
+ * Subscribe to real-time seat state updates from Firebase
27
+ *
28
+ * @example
29
+ * ```tsx
30
+ * const { reservedSeats, unavailableSeats, loading } = useFirebaseSeatStates({
31
+ * seatMapId: '123',
32
+ * });
33
+ *
34
+ * return (
35
+ * <SeatMapViewer
36
+ * config={config}
37
+ * reservedSeats={reservedSeats}
38
+ * unavailableSeats={unavailableSeats}
39
+ * />
40
+ * );
41
+ * ```
42
+ */
43
+ export declare function useFirebaseSeatStates(options: UseFirebaseSeatStatesOptions): UseFirebaseSeatStatesResult;
@@ -0,0 +1,66 @@
1
+ import { SeatMapConfig } from '../types';
2
+ import { FirebaseSeatStates } from '@zonetrix/shared';
3
+ export interface UseRealtimeSeatMapOptions {
4
+ /** The seat map ID to load and subscribe to */
5
+ seatMapId: string | null;
6
+ /** Whether the hook is enabled (default: true) */
7
+ enabled?: boolean;
8
+ /** Subscribe to design changes in real-time (default: false) */
9
+ subscribeToDesignChanges?: boolean;
10
+ /** Callback when config loads */
11
+ onConfigLoad?: (config: SeatMapConfig) => void;
12
+ /** Callback when seat states change */
13
+ onStateChange?: (states: FirebaseSeatStates) => void;
14
+ /** Callback on any error */
15
+ onError?: (error: Error) => void;
16
+ }
17
+ export interface UseRealtimeSeatMapResult {
18
+ /** The seat map configuration */
19
+ config: SeatMapConfig | null;
20
+ /** Whether initial loading is in progress */
21
+ loading: boolean;
22
+ /** Any error that occurred */
23
+ error: Error | null;
24
+ /** Array of reserved seat IDs (for SeatMapViewer props) */
25
+ reservedSeats: string[];
26
+ /** Array of unavailable seat IDs (for SeatMapViewer props) */
27
+ unavailableSeats: string[];
28
+ /** Raw seat states map */
29
+ seatStates: FirebaseSeatStates | null;
30
+ /** Timestamp of last state update */
31
+ lastUpdated: number | null;
32
+ /** Manually refetch the config */
33
+ refetch: () => Promise<void>;
34
+ }
35
+ /**
36
+ * Combined hook for loading config and subscribing to real-time seat states
37
+ *
38
+ * @example
39
+ * ```tsx
40
+ * import { useRealtimeSeatMap, SeatMapViewer } from '@zonetrix/viewer';
41
+ *
42
+ * function BookingPage({ seatMapId }) {
43
+ * const {
44
+ * config,
45
+ * reservedSeats,
46
+ * unavailableSeats,
47
+ * loading,
48
+ * error
49
+ * } = useRealtimeSeatMap({ seatMapId });
50
+ *
51
+ * if (loading) return <LoadingSpinner />;
52
+ * if (error) return <ErrorMessage error={error} />;
53
+ * if (!config) return null;
54
+ *
55
+ * return (
56
+ * <SeatMapViewer
57
+ * config={config}
58
+ * reservedSeats={reservedSeats}
59
+ * unavailableSeats={unavailableSeats}
60
+ * onSeatSelect={handleSeatSelect}
61
+ * />
62
+ * );
63
+ * }
64
+ * ```
65
+ */
66
+ export declare function useRealtimeSeatMap(options: UseRealtimeSeatMapOptions): UseRealtimeSeatMapResult;
package/dist/index.d.ts CHANGED
@@ -5,3 +5,10 @@ export { DEFAULT_COLORS } from './types';
5
5
  export { useConfigFetcher } from './hooks/useConfigFetcher';
6
6
  export { useContainerSize } from './hooks/useContainerSize';
7
7
  export { useTouchGestures } from './hooks/useTouchGestures';
8
+ export { useFirebaseSeatStates } from './hooks/useFirebaseSeatStates';
9
+ export type { UseFirebaseSeatStatesOptions, UseFirebaseSeatStatesResult } from './hooks/useFirebaseSeatStates';
10
+ export { useFirebaseConfig } from './hooks/useFirebaseConfig';
11
+ export type { UseFirebaseConfigOptions, UseFirebaseConfigResult } from './hooks/useFirebaseConfig';
12
+ export { useRealtimeSeatMap } from './hooks/useRealtimeSeatMap';
13
+ export type { UseRealtimeSeatMapOptions, UseRealtimeSeatMapResult } from './hooks/useRealtimeSeatMap';
14
+ export { initializeFirebaseForViewer, isFirebaseInitialized, clearFirebaseInstance, } from './firebase/client';
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const o=require("react/jsx-runtime"),e=require("react"),I=require("react-konva");function gt(n){const[r,u]=e.useState(null),[i,m]=e.useState(!1),[y,f]=e.useState(null),v=async()=>{if(n){m(!0),f(null);try{const b=await fetch(n);if(!b.ok)throw new Error(`Failed to fetch config: ${b.statusText}`);const a=await b.json();u(a)}catch(b){const a=b instanceof Error?b:new Error("Unknown error occurred");f(a),console.error("Failed to fetch seat map config:",a)}finally{m(!1)}}};return e.useEffect(()=>{v()},[n]),{config:r,loading:i,error:y,refetch:v}}function yt(n){const[r,u]=e.useState({width:0,height:0});return e.useEffect(()=>{const i=n.current;if(!i)return;const{width:m,height:y}=i.getBoundingClientRect();m>0&&y>0&&u({width:m,height:y});const f=new ResizeObserver(v=>{const b=v[0];if(!b)return;const{width:a,height:s}=b.contentRect;a>0&&s>0&&u(g=>g.width===a&&g.height===s?g:{width:a,height:s})});return f.observe(i),()=>{f.disconnect()}},[n]),r}function xt(n,r){return Math.sqrt(Math.pow(r.x-n.x,2)+Math.pow(r.y-n.y,2))}function pt(n,r){return{x:(n.x+r.x)/2,y:(n.y+r.y)/2}}function bt(n,r){const u=e.useRef(null),i=e.useRef(null),m=e.useRef(1);e.useEffect(()=>{const y=n.current;if(!y||!r.enabled)return;const f=y.container(),v=s=>{if(s.touches.length===2){s.preventDefault();const g={x:s.touches[0].clientX,y:s.touches[0].clientY},h={x:s.touches[1].clientX,y:s.touches[1].clientY};u.current=xt(g,h),i.current=pt(g,h),m.current=r.currentScale}},b=s=>{if(s.touches.length!==2)return;s.preventDefault();const g={x:s.touches[0].clientX,y:s.touches[0].clientY},h={x:s.touches[1].clientX,y:s.touches[1].clientY},M=xt(g,h),C=pt(g,h);if(u.current!==null&&i.current!==null){const R=M/u.current,D=Math.min(Math.max(r.currentScale*R,r.minScale),r.maxScale),V=f.getBoundingClientRect(),_=C.x-V.left,G=C.y-V.top,U=r.currentScale,P={x:(_-r.currentPosition.x)/U,y:(G-r.currentPosition.y)/U},W=C.x-i.current.x,ot=C.y-i.current.y,it={x:_-P.x*D+W,y:G-P.y*D+ot};r.onScaleChange(D,it),u.current=M,i.current=C}},a=s=>{s.touches.length<2&&(u.current=null,i.current=null)};return f.addEventListener("touchstart",v,{passive:!1}),f.addEventListener("touchmove",b,{passive:!1}),f.addEventListener("touchend",a),()=>{f.removeEventListener("touchstart",v),f.removeEventListener("touchmove",b),f.removeEventListener("touchend",a)}},[n,r])}const mt={canvasBackground:"#1a1a1a",stageColor:"#808080",seatAvailable:"#2C2B30",seatReserved:"#FCEA00",seatSelected:"#3A7DE5",seatUnavailable:"#6b7280",seatHidden:"#4a4a4a",gridLines:"#404040",currency:"KD"},St=e.memo(({seat:n,state:r,colors:u,onClick:i,onMouseEnter:m,onMouseLeave:y})=>{const b={available:u.seatAvailable,reserved:u.seatReserved,selected:u.seatSelected,unavailable:u.seatUnavailable,hidden:u.seatHidden}[r],a=r==="available"||r==="selected",s=e.useCallback(()=>{a&&i(n)},[n,i,a]),g=e.useCallback(C=>{m(n,C);const R=C.target.getStage();R&&a&&(R.container().style.cursor="pointer")},[n,m,a]),h=e.useCallback(C=>{y();const R=C.target.getStage();R&&(R.container().style.cursor="grab")},[y]),M={x:n.position.x,y:n.position.y,fill:b,stroke:"#ffffff",strokeWidth:1,onClick:s,onTap:s,onMouseEnter:g,onMouseLeave:h};return n.shape==="circle"?o.jsx(I.Circle,{...M,radius:12}):o.jsx(I.Rect,{...M,width:24,height:24,offsetX:12,offsetY:12,cornerRadius:n.shape==="square"?0:4})});St.displayName="ViewerSeat";const vt=e.memo(({stage:n,stageColor:r})=>{const u=y=>({stage:"🎭",table:"⬜",wall:"▬",barrier:"🛡️","dj-booth":"🎵",bar:"🍷","entry-exit":"🚪",custom:"➕"})[y||"stage"]||"🎭",i=n.config.color||r,m=u(n.config.objectType);return o.jsxs(I.Group,{x:n.position.x,y:n.position.y,rotation:n.config.rotation||0,children:[o.jsx(I.Rect,{width:n.config.width,height:n.config.height,fill:i+"80",stroke:"#ffffff",strokeWidth:2,cornerRadius:10}),o.jsx(I.Text,{text:m,x:0,y:0,width:n.config.width,height:n.config.height*.4,fontSize:32,fill:"#ffffff",align:"center",verticalAlign:"middle"}),o.jsx(I.Text,{text:n.config.label,x:0,y:n.config.height*.4,width:n.config.width,height:n.config.height*.6,fontSize:20,fontStyle:"bold",fill:"#ffffff",align:"center",verticalAlign:"middle"})]})});vt.displayName="ViewerStage";const wt=e.memo(({floors:n,currentFloorId:r,onFloorChange:u,showAllOption:i,allLabel:m,position:y,className:f})=>{const v=e.useMemo(()=>[...n].sort((h,M)=>h.order-M.order),[n]),a={position:"absolute",display:"flex",alignItems:"center",gap:"8px",padding:"8px 12px",backgroundColor:"rgba(26, 26, 26, 0.95)",borderRadius:"8px",margin:"12px",zIndex:10,...{"top-left":{top:0,left:0},"top-right":{top:0,right:0},"bottom-left":{bottom:0,left:0},"bottom-right":{bottom:0,right:0}}[y]},s={padding:"10px 16px",fontSize:"14px",fontWeight:500,border:"1px solid #444",borderRadius:"6px",backgroundColor:"transparent",color:"#fff",cursor:"pointer",transition:"all 0.2s ease",minHeight:"44px",touchAction:"manipulation"},g={...s,backgroundColor:"#3A7DE5",borderColor:"#3A7DE5"};return o.jsxs("div",{className:f,style:a,children:[i&&o.jsx("button",{type:"button",onClick:()=>u(null),style:r===null?g:s,children:m}),v.map(h=>o.jsx("button",{type:"button",onClick:()=>u(h.id),style:r===h.id?g:s,children:h.name},h.id))]})});wt.displayName="FloorSelectorBar";const Ct=e.memo(({scale:n,minScale:r,maxScale:u,onZoomIn:i,onZoomOut:m,position:y,className:f})=>{const b={position:"absolute",display:"flex",flexDirection:"column",gap:"4px",padding:"8px",backgroundColor:"rgba(26, 26, 26, 0.95)",borderRadius:"8px",margin:"12px",zIndex:10,...{"top-left":{top:0,left:0},"top-right":{top:0,right:0},"bottom-left":{bottom:0,left:0},"bottom-right":{bottom:0,right:0}}[y]},a={width:"44px",height:"44px",minWidth:"44px",minHeight:"44px",fontSize:"22px",fontWeight:"bold",border:"1px solid #444",borderRadius:"6px",backgroundColor:"transparent",color:"#fff",cursor:"pointer",display:"flex",alignItems:"center",justifyContent:"center",transition:"all 0.2s ease",touchAction:"manipulation"},s={...a,opacity:.4,cursor:"not-allowed"},g=n<u,h=n>r;return o.jsxs("div",{className:f,style:b,children:[o.jsx("button",{type:"button",onClick:i,disabled:!g,style:g?a:s,title:"Zoom In",children:"+"}),o.jsx("button",{type:"button",onClick:m,disabled:!h,style:h?a:s,title:"Zoom Out",children:"−"})]})});Ct.displayName="ZoomControls";const jt=e.memo(({visible:n,x:r,y:u,seat:i,currency:m,state:y})=>{if(!n||!i)return null;const f=i.seatNumber||(i.rowLabel&&i.columnLabel?`${i.rowLabel}-${i.columnLabel}`:"N/A"),v={position:"fixed",left:`${r+15}px`,top:`${u+15}px`,zIndex:1e3,pointerEvents:"none"},b={backgroundColor:"rgba(26, 26, 26, 0.95)",color:"#fff",border:"1px solid #444",borderRadius:"8px",padding:"8px 12px",fontSize:"13px",boxShadow:"0 4px 12px rgba(0, 0, 0, 0.3)",minWidth:"140px"},a={color:"#9ca3af",marginRight:"4px"},s={fontWeight:600},g={color:"#4ade80",fontWeight:600},h={fontSize:"11px",color:"#6b7280",textTransform:"capitalize",marginTop:"4px"};return o.jsx("div",{style:v,children:o.jsxs("div",{style:b,children:[i.sectionName&&o.jsxs("div",{style:{marginBottom:"4px"},children:[o.jsx("span",{style:a,children:"Section:"}),o.jsx("span",{style:{...s,color:"#3b82f6"},children:i.sectionName})]}),o.jsxs("div",{style:{marginBottom:"4px"},children:[o.jsx("span",{style:a,children:"Seat:"}),o.jsx("span",{style:s,children:f})]}),i.price!==void 0&&i.price>0&&y==="available"&&o.jsxs("div",{style:{marginBottom:"4px"},children:[o.jsx("span",{style:a,children:"Price:"}),o.jsxs("span",{style:g,children:[m," ",i.price.toFixed(2)]})]}),o.jsxs("div",{style:h,children:["Status: ",y]})]})})});jt.displayName="SeatTooltip";const Kt=({config:n,configUrl:r,floorId:u,onFloorChange:i,reservedSeats:m=[],unavailableSeats:y=[],selectedSeats:f,onSeatSelect:v,onSeatDeselect:b,onSelectionChange:a,colorOverrides:s,showTooltip:g=!0,zoomEnabled:h=!0,className:M="",onConfigLoad:C,onError:R,showFloorSelector:D,floorSelectorPosition:V="top-left",floorSelectorClassName:_,showAllFloorsOption:G=!0,allFloorsLabel:U="All",fitToView:P=!0,fitPadding:W=40,showZoomControls:ot=!0,zoomControlsPosition:it="bottom-right",zoomControlsClassName:Mt,minZoom:ut,maxZoom:N=3,zoomStep:K=.25,touchEnabled:kt=!0})=>{const st=e.useRef(null),ht=e.useRef(null),w=yt(ht),[X,dt]=e.useState(new Set),[j,A]=e.useState(1),[k,T]=e.useState({x:0,y:0}),[Rt,Et]=e.useState(null),[It,Nt]=e.useState(1),Z=e.useRef({width:0,height:0}),[z,ft]=e.useState({visible:!1,x:0,y:0,seat:null,state:"available"}),{config:Lt,loading:Tt,error:B}=gt(r),l=n||Lt,rt=u!==void 0,E=rt?u||null:Rt,J=f!==void 0,Dt=e.useCallback(t=>{rt||Et(t),i?.(t)},[rt,i]),ct=l?.floors||[],Xt=D!==void 0?D:ct.length>1,Q=e.useMemo(()=>l?{...l.colors,...s}:{...mt,...s},[l,s]),Y=e.useMemo(()=>{if(!l)return[];let t=l.seats.filter(c=>c.state!=="hidden");return E&&(t=t.filter(c=>c.floorId===E||!c.floorId&&E==="floor_default")),t},[l,E]),tt=e.useMemo(()=>l?.stages?E?l.stages.filter(t=>t.floorId===E||!t.floorId&&E==="floor_default"):l.stages:[],[l,E]),L=e.useMemo(()=>{if(!l||Y.length===0&&tt.length===0)return null;const t=12;let c=1/0,x=1/0,d=-1/0,p=-1/0;return Y.forEach(S=>{c=Math.min(c,S.position.x-t),x=Math.min(x,S.position.y-t),d=Math.max(d,S.position.x+t),p=Math.max(p,S.position.y+t)}),tt.forEach(S=>{c=Math.min(c,S.position.x),x=Math.min(x,S.position.y),d=Math.max(d,S.position.x+(S.config?.width||200)),p=Math.max(p,S.position.y+(S.config?.height||100))}),{minX:c,minY:x,maxX:d,maxY:p,width:d-c,height:p-x}},[l,Y,tt]);e.useEffect(()=>{if(!P||!l||!L||w.width===0||w.height===0)return;const t=Math.abs(w.width-Z.current.width),c=Math.abs(w.height-Z.current.height);if(!(Z.current.width===0)&&t<10&&c<10)return;Z.current=w;const d=w.width,p=w.height,S=d-W*2,q=p-W*2,et=S/L.width,lt=q/L.height,nt=Math.min(et,lt,N),Ht=L.minX+L.width/2,qt=L.minY+L.height/2,Vt=d/2,_t=p/2,Gt=Vt-Ht*nt,Ut=_t-qt*nt;A(nt),T({x:Gt,y:Ut}),Nt(nt)},[P,l,L,W,N,w,E]);const O=e.useMemo(()=>{const t=new Set(m),c=new Set(y);return{reserved:t,unavailable:c}},[m,y]),at=e.useMemo(()=>f?new Set(f):null,[f]),$=e.useCallback(t=>{const c=t.id,x=t.seatNumber||"";return O.unavailable.has(c)||O.unavailable.has(x)?"unavailable":O.reserved.has(c)||O.reserved.has(x)?"reserved":X.has(c)?"selected":t.state},[O,X]);e.useEffect(()=>{l&&C&&C(l)},[l,C]),e.useEffect(()=>{B&&R&&R(B)},[B,R]),e.useEffect(()=>{J&&at&&dt(at)},[J,at]);const Yt=e.useCallback(t=>{const c=$(t);if(c!=="available"&&c!=="selected")return;const x=X.has(t.id);J||dt(d=>{const p=new Set(d);return x?p.delete(t.id):p.add(t.id),p}),x?b?.(t):(v?.(t),v||console.log("Seat selected:",t))},[$,X,J,v,b]),H=e.useMemo(()=>l?Y.filter(t=>X.has(t.id)):[],[Y,X]);e.useEffect(()=>{a?.(H)},[H,a]);const F=ut!==void 0?ut:It,Ft=e.useCallback(()=>{if(!h)return;const t=Math.min(j+K,N);if(t!==j){const c=w.width||l?.canvas.width||800,x=w.height||l?.canvas.height||600,d=c/2,p=x/2,S={x:(d-k.x)/j,y:(p-k.y)/j};A(t),T({x:d-S.x*t,y:p-S.y*t})}},[h,j,K,N,w,l,k]),Pt=e.useCallback(()=>{if(!h)return;const t=Math.max(j-K,F);if(t!==j){const c=w.width||l?.canvas.width||800,x=w.height||l?.canvas.height||600,d=c/2,p=x/2,S={x:(d-k.x)/j,y:(p-k.y)/j};A(t),T({x:d-S.x*t,y:p-S.y*t})}},[h,j,K,F,w,l,k]),Wt=e.useCallback(t=>{T({x:t.target.x(),y:t.target.y()})},[]),At=e.useCallback(t=>{if(!h)return;t.evt.preventDefault();const c=st.current;if(!c)return;const x=c.scaleX(),d=c.getPointerPosition();if(!d)return;const p=1.1,S=t.evt.deltaY>0?x/p:x*p,q=Math.min(Math.max(S,F),N),et={x:(d.x-k.x)/x,y:(d.y-k.y)/x},lt={x:d.x-et.x*q,y:d.y-et.y*q};A(q),T(lt)},[h,k,F,N]);bt(st,{enabled:kt&&h,minScale:F,maxScale:N,currentScale:j,currentPosition:k,onScaleChange:(t,c)=>{A(t),T(c)},onPositionChange:t=>{T(t)}});const zt=e.useCallback((t,c)=>{if(!g)return;const x=c.target.getStage();if(!x)return;const d=x.getPointerPosition();if(!d)return;const p=x.container().getBoundingClientRect();ft({visible:!0,x:p.left+d.x,y:p.top+d.y,seat:t,state:$(t)})},[g,$]),Bt=e.useCallback(()=>{ft(t=>({...t,visible:!1}))},[]);if(Tt)return o.jsx("div",{className:`flex items-center justify-center h-full ${M}`,children:o.jsx("p",{children:"Loading seat map..."})});if(B)return o.jsx("div",{className:`flex items-center justify-center h-full ${M}`,children:o.jsxs("p",{className:"text-red-500",children:["Error loading seat map: ",B.message]})});if(!l)return o.jsx("div",{className:`flex items-center justify-center h-full ${M}`,children:o.jsx("p",{children:"No configuration provided"})});const Ot=w.width||l.canvas.width,$t=w.height||l.canvas.height;return o.jsxs("div",{ref:ht,className:`relative ${M}`,style:{width:"100%",height:"100%"},children:[Xt&&ct.length>0&&o.jsx(wt,{floors:ct,currentFloorId:E,onFloorChange:Dt,showAllOption:G,allLabel:U,position:V,className:_}),o.jsxs(I.Stage,{ref:st,width:Ot,height:$t,scaleX:j,scaleY:j,x:k.x,y:k.y,draggable:!0,onDragEnd:Wt,onWheel:At,style:{backgroundColor:l.canvas.backgroundColor,cursor:"grab"},children:[o.jsx(I.Layer,{listening:!1,children:tt.map(t=>o.jsx(vt,{stage:t,stageColor:Q.stageColor},t.id))}),o.jsx(I.Layer,{children:Y.map(t=>o.jsx(St,{seat:t,state:$(t),colors:Q,onClick:Yt,onMouseEnter:zt,onMouseLeave:Bt},t.id))})]}),g&&o.jsx(jt,{visible:z.visible,x:z.x,y:z.y,seat:z.seat,currency:Q.currency,state:z.state}),ot&&h&&o.jsx(Ct,{scale:j,minScale:F,maxScale:N,onZoomIn:Ft,onZoomOut:Pt,position:it,className:Mt}),H.length>0&&o.jsxs("div",{className:"absolute top-4 right-4 bg-white dark:bg-gray-800 p-4 rounded shadow-lg",children:[o.jsxs("h3",{className:"font-semibold mb-2",children:["Selected Seats (",H.length,")"]}),o.jsx("div",{className:"max-h-48 overflow-y-auto space-y-1",children:H.map(t=>o.jsxs("div",{className:"text-sm",children:[t.seatNumber,t.price&&` - ${Q.currency} ${t.price.toFixed(2)}`]},t.id))})]})]})};exports.DEFAULT_COLORS=mt;exports.SeatMapViewer=Kt;exports.useConfigFetcher=gt;exports.useContainerSize=yt;exports.useTouchGestures=bt;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const r=require("react/jsx-runtime"),t=require("react"),T=require("react-konva"),Y=require("firebase/database"),nt=require("@zonetrix/shared");function we(n){const[s,c]=t.useState(null),[o,g]=t.useState(!1),[p,d]=t.useState(null),m=async()=>{if(n){g(!0),d(null);try{const h=await fetch(n);if(!h.ok)throw new Error(`Failed to fetch config: ${h.statusText}`);const a=await h.json();c(a)}catch(h){const a=h instanceof Error?h:new Error("Unknown error occurred");d(a),console.error("Failed to fetch seat map config:",a)}finally{g(!1)}}};return t.useEffect(()=>{m()},[n]),{config:s,loading:o,error:p,refetch:m}}function Ce(n){const[s,c]=t.useState({width:0,height:0});return t.useEffect(()=>{const o=n.current;if(!o)return;const{width:g,height:p}=o.getBoundingClientRect();g>0&&p>0&&c({width:g,height:p});const d=new ResizeObserver(m=>{const h=m[0];if(!h)return;const{width:a,height:i}=h.contentRect;a>0&&i>0&&c(f=>f.width===a&&f.height===i?f:{width:a,height:i})});return d.observe(o),()=>{d.disconnect()}},[n]),s}function me(n,s){return Math.sqrt(Math.pow(s.x-n.x,2)+Math.pow(s.y-n.y,2))}function ve(n,s){return{x:(n.x+s.x)/2,y:(n.y+s.y)/2}}function je(n,s){const c=t.useRef(null),o=t.useRef(null),g=t.useRef(1);t.useEffect(()=>{const p=n.current;if(!p||!s.enabled)return;const d=p.container(),m=i=>{if(i.touches.length===2){i.preventDefault();const f={x:i.touches[0].clientX,y:i.touches[0].clientY},l={x:i.touches[1].clientX,y:i.touches[1].clientY};c.current=me(f,l),o.current=ve(f,l),g.current=s.currentScale}},h=i=>{if(i.touches.length!==2)return;i.preventDefault();const f={x:i.touches[0].clientX,y:i.touches[0].clientY},l={x:i.touches[1].clientX,y:i.touches[1].clientY},C=me(f,l),v=ve(f,l);if(c.current!==null&&o.current!==null){const j=C/c.current,F=Math.min(Math.max(s.currentScale*j,s.minScale),s.maxScale),R=d.getBoundingClientRect(),M=v.x-R.left,L=v.y-R.top,P=s.currentScale,W={x:(M-s.currentPosition.x)/P,y:(L-s.currentPosition.y)/P},A=v.x-o.current.x,N=v.y-o.current.y,ne={x:M-W.x*F+A,y:L-W.y*F+N};s.onScaleChange(F,ne),c.current=C,o.current=v}},a=i=>{i.touches.length<2&&(c.current=null,o.current=null)};return d.addEventListener("touchstart",m,{passive:!1}),d.addEventListener("touchmove",h,{passive:!1}),d.addEventListener("touchend",a),()=>{d.removeEventListener("touchstart",m),d.removeEventListener("touchmove",h),d.removeEventListener("touchend",a)}},[n,s])}const Me={canvasBackground:"#1a1a1a",stageColor:"#808080",seatAvailable:"#2C2B30",seatReserved:"#FCEA00",seatSelected:"#3A7DE5",seatUnavailable:"#6b7280",seatHidden:"#4a4a4a",gridLines:"#404040",currency:"KD"},Ee=t.memo(({seat:n,state:s,colors:c,onClick:o,onMouseEnter:g,onMouseLeave:p})=>{const h={available:c.seatAvailable,reserved:c.seatReserved,selected:c.seatSelected,unavailable:c.seatUnavailable,hidden:c.seatHidden}[s],a=s==="available"||s==="selected",i=t.useCallback(()=>{a&&o(n)},[n,o,a]),f=t.useCallback(v=>{g(n,v);const j=v.target.getStage();j&&a&&(j.container().style.cursor="pointer")},[n,g,a]),l=t.useCallback(v=>{p();const j=v.target.getStage();j&&(j.container().style.cursor="grab")},[p]),C={x:n.position.x,y:n.position.y,fill:h,stroke:"#ffffff",strokeWidth:1,onClick:i,onTap:i,onMouseEnter:f,onMouseLeave:l};return n.shape==="circle"?r.jsx(T.Circle,{...C,radius:12}):r.jsx(T.Rect,{...C,width:24,height:24,offsetX:12,offsetY:12,cornerRadius:n.shape==="square"?0:4})});Ee.displayName="ViewerSeat";const Fe=t.memo(({stage:n,stageColor:s})=>{const c=p=>({stage:"🎭",table:"⬜",wall:"▬",barrier:"🛡️","dj-booth":"🎵",bar:"🍷","entry-exit":"🚪",custom:"➕"})[p||"stage"]||"🎭",o=n.config.color||s,g=c(n.config.objectType);return r.jsxs(T.Group,{x:n.position.x,y:n.position.y,rotation:n.config.rotation||0,children:[r.jsx(T.Rect,{width:n.config.width,height:n.config.height,fill:o+"80",stroke:"#ffffff",strokeWidth:2,cornerRadius:10}),r.jsx(T.Text,{text:g,x:0,y:0,width:n.config.width,height:n.config.height*.4,fontSize:32,fill:"#ffffff",align:"center",verticalAlign:"middle"}),r.jsx(T.Text,{text:n.config.label,x:0,y:n.config.height*.4,width:n.config.width,height:n.config.height*.6,fontSize:20,fontStyle:"bold",fill:"#ffffff",align:"center",verticalAlign:"middle"})]})});Fe.displayName="ViewerStage";const Re=t.memo(({floors:n,currentFloorId:s,onFloorChange:c,showAllOption:o,allLabel:g,position:p,className:d})=>{const m=t.useMemo(()=>[...n].sort((l,C)=>l.order-C.order),[n]),a={position:"absolute",display:"flex",alignItems:"center",gap:"8px",padding:"8px 12px",backgroundColor:"rgba(26, 26, 26, 0.95)",borderRadius:"8px",margin:"12px",zIndex:10,...{"top-left":{top:0,left:0},"top-right":{top:0,right:0},"bottom-left":{bottom:0,left:0},"bottom-right":{bottom:0,right:0}}[p]},i={padding:"10px 16px",fontSize:"14px",fontWeight:500,border:"1px solid #444",borderRadius:"6px",backgroundColor:"transparent",color:"#fff",cursor:"pointer",transition:"all 0.2s ease",minHeight:"44px",touchAction:"manipulation"},f={...i,backgroundColor:"#3A7DE5",borderColor:"#3A7DE5"};return r.jsxs("div",{className:d,style:a,children:[o&&r.jsx("button",{type:"button",onClick:()=>c(null),style:s===null?f:i,children:g}),m.map(l=>r.jsx("button",{type:"button",onClick:()=>c(l.id),style:s===l.id?f:i,children:l.name},l.id))]})});Re.displayName="FloorSelectorBar";const ke=t.memo(({scale:n,minScale:s,maxScale:c,onZoomIn:o,onZoomOut:g,position:p,className:d})=>{const h={position:"absolute",display:"flex",flexDirection:"column",gap:"4px",padding:"8px",backgroundColor:"rgba(26, 26, 26, 0.95)",borderRadius:"8px",margin:"12px",zIndex:10,...{"top-left":{top:0,left:0},"top-right":{top:0,right:0},"bottom-left":{bottom:0,left:0},"bottom-right":{bottom:0,right:0}}[p]},a={width:"44px",height:"44px",minWidth:"44px",minHeight:"44px",fontSize:"22px",fontWeight:"bold",border:"1px solid #444",borderRadius:"6px",backgroundColor:"transparent",color:"#fff",cursor:"pointer",display:"flex",alignItems:"center",justifyContent:"center",transition:"all 0.2s ease",touchAction:"manipulation"},i={...a,opacity:.4,cursor:"not-allowed"},f=n<c,l=n>s;return r.jsxs("div",{className:d,style:h,children:[r.jsx("button",{type:"button",onClick:o,disabled:!f,style:f?a:i,title:"Zoom In",children:"+"}),r.jsx("button",{type:"button",onClick:g,disabled:!l,style:l?a:i,title:"Zoom Out",children:"−"})]})});ke.displayName="ZoomControls";const Ie=t.memo(({visible:n,x:s,y:c,seat:o,currency:g,state:p})=>{if(!n||!o)return null;const d=o.seatNumber||(o.rowLabel&&o.columnLabel?`${o.rowLabel}-${o.columnLabel}`:"N/A"),m={position:"fixed",left:`${s+15}px`,top:`${c+15}px`,zIndex:1e3,pointerEvents:"none"},h={backgroundColor:"rgba(26, 26, 26, 0.95)",color:"#fff",border:"1px solid #444",borderRadius:"8px",padding:"8px 12px",fontSize:"13px",boxShadow:"0 4px 12px rgba(0, 0, 0, 0.3)",minWidth:"140px"},a={color:"#9ca3af",marginRight:"4px"},i={fontWeight:600},f={color:"#4ade80",fontWeight:600},l={fontSize:"11px",color:"#6b7280",textTransform:"capitalize",marginTop:"4px"};return r.jsx("div",{style:m,children:r.jsxs("div",{style:h,children:[o.sectionName&&r.jsxs("div",{style:{marginBottom:"4px"},children:[r.jsx("span",{style:a,children:"Section:"}),r.jsx("span",{style:{...i,color:"#3b82f6"},children:o.sectionName})]}),r.jsxs("div",{style:{marginBottom:"4px"},children:[r.jsx("span",{style:a,children:"Seat:"}),r.jsx("span",{style:i,children:d})]}),o.price!==void 0&&o.price>0&&p==="available"&&r.jsxs("div",{style:{marginBottom:"4px"},children:[r.jsx("span",{style:a,children:"Price:"}),r.jsxs("span",{style:f,children:[g," ",o.price.toFixed(2)]})]}),r.jsxs("div",{style:l,children:["Status: ",p]})]})})});Ie.displayName="SeatTooltip";const st=({config:n,configUrl:s,floorId:c,onFloorChange:o,reservedSeats:g=[],unavailableSeats:p=[],selectedSeats:d,onSeatSelect:m,onSeatDeselect:h,onSelectionChange:a,colorOverrides:i,showTooltip:f=!0,zoomEnabled:l=!0,className:C="",onConfigLoad:v,onError:j,showFloorSelector:F,floorSelectorPosition:R="top-left",floorSelectorClassName:M,showAllFloorsOption:L=!0,allFloorsLabel:P="All",fitToView:W=!0,fitPadding:A=40,showZoomControls:N=!0,zoomControlsPosition:ne="bottom-right",zoomControlsClassName:U,minZoom:q,maxZoom:D=3,zoomStep:$=.25,touchEnabled:se=!0})=>{const de=t.useRef(null),be=t.useRef(null),E=Ce(be),[V,Se]=t.useState(new Set),[k,_]=t.useState(1),[I,B]=t.useState({x:0,y:0}),[ze,Te]=t.useState(null),[Ne,Xe]=t.useState(1),oe=t.useRef({width:0,height:0}),[G,ye]=t.useState({visible:!1,x:0,y:0,seat:null,state:"available"}),{config:Ye,loading:Pe,error:K}=we(s),x=n||Ye,he=c!==void 0,z=he?c||null:ze,ie=d!==void 0,We=t.useCallback(e=>{he||Te(e),o?.(e)},[he,o]),fe=x?.floors||[],Ae=F!==void 0?F:fe.length>1,re=t.useMemo(()=>x?{...x.colors,...i}:{...Me,...i},[x,i]),O=t.useMemo(()=>{if(!x)return[];let e=x.seats.filter(u=>u.state!=="hidden");return z&&(e=e.filter(u=>u.floorId===z||!u.floorId&&z==="floor_default")),e},[x,z]),ae=t.useMemo(()=>x?.stages?z?x.stages.filter(e=>e.floorId===z||!e.floorId&&z==="floor_default"):x.stages:[],[x,z]),X=t.useMemo(()=>{if(!x||O.length===0&&ae.length===0)return null;const e=12;let u=1/0,S=1/0,b=-1/0,y=-1/0;return O.forEach(w=>{u=Math.min(u,w.position.x-e),S=Math.min(S,w.position.y-e),b=Math.max(b,w.position.x+e),y=Math.max(y,w.position.y+e)}),ae.forEach(w=>{u=Math.min(u,w.position.x),S=Math.min(S,w.position.y),b=Math.max(b,w.position.x+(w.config?.width||200)),y=Math.max(y,w.position.y+(w.config?.height||100))}),{minX:u,minY:S,maxX:b,maxY:y,width:b-u,height:y-S}},[x,O,ae]);t.useEffect(()=>{if(!W||!x||!X||E.width===0||E.height===0)return;const e=Math.abs(E.width-oe.current.width),u=Math.abs(E.height-oe.current.height);if(!(oe.current.width===0)&&e<10&&u<10)return;oe.current=E;const b=E.width,y=E.height,w=b-A*2,ee=y-A*2,ce=w/X.width,pe=ee/X.height,le=Math.min(ce,pe,D),Ke=X.minX+X.width/2,Ze=X.minY+X.height/2,Je=b/2,Qe=y/2,et=Je-Ke*le,tt=Qe-Ze*le;_(le),B({x:et,y:tt}),Xe(le)},[W,x,X,A,D,E,z]);const Z=t.useMemo(()=>{const e=new Set(g),u=new Set(p);return{reserved:e,unavailable:u}},[g,p]),ge=t.useMemo(()=>d?new Set(d):null,[d]),J=t.useCallback(e=>{const u=e.id,S=e.seatNumber||"";return Z.unavailable.has(u)||Z.unavailable.has(S)?"unavailable":Z.reserved.has(u)||Z.reserved.has(S)?"reserved":V.has(u)?"selected":e.state},[Z,V]);t.useEffect(()=>{x&&v&&v(x)},[x,v]),t.useEffect(()=>{K&&j&&j(K)},[K,j]),t.useEffect(()=>{ie&&ge&&Se(ge)},[ie,ge]);const $e=t.useCallback(e=>{const u=J(e);if(u!=="available"&&u!=="selected")return;const S=V.has(e.id);ie||Se(b=>{const y=new Set(b);return S?y.delete(e.id):y.add(e.id),y}),S?h?.(e):(m?.(e),m||console.log("Seat selected:",e))},[J,V,ie,m,h]),Q=t.useMemo(()=>x?O.filter(e=>V.has(e.id)):[],[O,V]);t.useEffect(()=>{a?.(Q)},[Q,a]);const H=q!==void 0?q:Ne,Be=t.useCallback(()=>{if(!l)return;const e=Math.min(k+$,D);if(e!==k){const u=E.width||x?.canvas.width||800,S=E.height||x?.canvas.height||600,b=u/2,y=S/2,w={x:(b-I.x)/k,y:(y-I.y)/k};_(e),B({x:b-w.x*e,y:y-w.y*e})}},[l,k,$,D,E,x,I]),Ve=t.useCallback(()=>{if(!l)return;const e=Math.max(k-$,H);if(e!==k){const u=E.width||x?.canvas.width||800,S=E.height||x?.canvas.height||600,b=u/2,y=S/2,w={x:(b-I.x)/k,y:(y-I.y)/k};_(e),B({x:b-w.x*e,y:y-w.y*e})}},[l,k,$,H,E,x,I]),Oe=t.useCallback(e=>{B({x:e.target.x(),y:e.target.y()})},[]),He=t.useCallback(e=>{if(!l)return;e.evt.preventDefault();const u=de.current;if(!u)return;const S=u.scaleX(),b=u.getPointerPosition();if(!b)return;const y=1.1,w=e.evt.deltaY>0?S/y:S*y,ee=Math.min(Math.max(w,H),D),ce={x:(b.x-I.x)/S,y:(b.y-I.y)/S},pe={x:b.x-ce.x*ee,y:b.y-ce.y*ee};_(ee),B(pe)},[l,I,H,D]);je(de,{enabled:se&&l,minScale:H,maxScale:D,currentScale:k,currentPosition:I,onScaleChange:(e,u)=>{_(e),B(u)},onPositionChange:e=>{B(e)}});const Ue=t.useCallback((e,u)=>{if(!f)return;const S=u.target.getStage();if(!S)return;const b=S.getPointerPosition();if(!b)return;const y=S.container().getBoundingClientRect();ye({visible:!0,x:y.left+b.x,y:y.top+b.y,seat:e,state:J(e)})},[f,J]),qe=t.useCallback(()=>{ye(e=>({...e,visible:!1}))},[]);if(Pe)return r.jsx("div",{className:`flex items-center justify-center h-full ${C}`,children:r.jsx("p",{children:"Loading seat map..."})});if(K)return r.jsx("div",{className:`flex items-center justify-center h-full ${C}`,children:r.jsxs("p",{className:"text-red-500",children:["Error loading seat map: ",K.message]})});if(!x)return r.jsx("div",{className:`flex items-center justify-center h-full ${C}`,children:r.jsx("p",{children:"No configuration provided"})});const _e=E.width||x.canvas.width,Ge=E.height||x.canvas.height;return r.jsxs("div",{ref:be,className:`relative ${C}`,style:{width:"100%",height:"100%"},children:[Ae&&fe.length>0&&r.jsx(Re,{floors:fe,currentFloorId:z,onFloorChange:We,showAllOption:L,allLabel:P,position:R,className:M}),r.jsxs(T.Stage,{ref:de,width:_e,height:Ge,scaleX:k,scaleY:k,x:I.x,y:I.y,draggable:!0,onDragEnd:Oe,onWheel:He,style:{backgroundColor:x.canvas.backgroundColor,cursor:"grab"},children:[r.jsx(T.Layer,{listening:!1,children:ae.map(e=>r.jsx(Fe,{stage:e,stageColor:re.stageColor},e.id))}),r.jsx(T.Layer,{children:O.map(e=>r.jsx(Ee,{seat:e,state:J(e),colors:re,onClick:$e,onMouseEnter:Ue,onMouseLeave:qe},e.id))})]}),f&&r.jsx(Ie,{visible:G.visible,x:G.x,y:G.y,seat:G.seat,currency:re.currency,state:G.state}),N&&l&&r.jsx(ke,{scale:k,minScale:H,maxScale:D,onZoomIn:Be,onZoomOut:Ve,position:ne,className:U}),Q.length>0&&r.jsxs("div",{className:"absolute top-4 right-4 bg-white dark:bg-gray-800 p-4 rounded shadow-lg",children:[r.jsxs("h3",{className:"font-semibold mb-2",children:["Selected Seats (",Q.length,")"]}),r.jsx("div",{className:"max-h-48 overflow-y-auto space-y-1",children:Q.map(e=>r.jsxs("div",{className:"text-sm",children:[e.seatNumber,e.price&&` - ${re.currency} ${e.price.toFixed(2)}`]},e.id))})]})]})};let te=null;function ot(n){te=n}function xe(){if(!te)throw new Error("Firebase database not initialized. Call initializeFirebaseForViewer(db) first.");return te}function ue(){return te!==null}function it(){te=null}function Le(n){const{seatMapId:s,enabled:c=!0,onStateChange:o,onError:g}=n,[p,d]=t.useState(null),[m,h]=t.useState(!0),[a,i]=t.useState(null),[f,l]=t.useState(null),[C,v]=t.useState([]),[j,F]=t.useState([]),R=t.useRef(o),M=t.useRef(g);return R.current=o,M.current=g,t.useEffect(()=>{if(!c||!s){h(!1);return}if(!ue()){h(!1),i(new Error("Firebase not initialized. Call initializeFirebaseForViewer first."));return}const L=xe(),P=Y.ref(L,`seat_states/${s}`);h(!0),i(null);const W=N=>{const U=N.val()||{};d(U),h(!1),l(Date.now());const q=[],D=[];Object.entries(U).forEach(([$,se])=>{se==="reserved"?q.push($):se==="unavailable"&&D.push($)}),v(q),F(D),R.current?.(U)},A=N=>{i(N),h(!1),M.current?.(N)};return Y.onValue(P,W,A),()=>{Y.off(P)}},[s,c]),{states:p,loading:m,error:a,lastUpdated:f,reservedSeats:C,unavailableSeats:j}}function De(n){const{seatMapId:s,enabled:c=!0,subscribeToChanges:o=!1,onConfigLoad:g,onError:p}=n,[d,m]=t.useState(null),[h,a]=t.useState(!0),[i,f]=t.useState(null),l=t.useRef(g),C=t.useRef(p);l.current=g,C.current=p;const v=t.useCallback(async()=>{if(!s)return;if(!ue()){f(new Error("Firebase not initialized. Call initializeFirebaseForViewer first.")),a(!1);return}const j=xe(),F=Y.ref(j,`seatmaps/${s}`);try{a(!0),f(null);const M=(await Y.get(F)).val();if(M){const L=nt.fromFirebaseSeatMap(M);m(L),l.current?.(L)}else f(new Error(`Seat map ${s} not found in Firebase`))}catch(R){const M=R instanceof Error?R:new Error("Unknown error");f(M),C.current?.(M)}finally{a(!1)}},[s]);return t.useEffect(()=>{if(!c||!s){a(!1);return}if(v(),o&&ue()){const j=xe(),F=Y.ref(j,`seatmaps/${s}/meta/updated_at`);let R=!0;const M=L=>{if(R){R=!1;return}L.exists()&&v()};return Y.onValue(F,M),()=>{Y.off(F)}}},[s,c,o,v]),{config:d,loading:h,error:i,refetch:v}}function rt(n){const{seatMapId:s,enabled:c=!0,subscribeToDesignChanges:o=!1,onConfigLoad:g,onStateChange:p,onError:d}=n,{config:m,loading:h,error:a,refetch:i}=De({seatMapId:s,enabled:c,subscribeToChanges:o,onConfigLoad:g,onError:d}),{states:f,loading:l,error:C,lastUpdated:v,reservedSeats:j,unavailableSeats:F}=Le({seatMapId:s,enabled:c,onStateChange:p,onError:d});return{config:m,loading:h||l,error:a||C,reservedSeats:j,unavailableSeats:F,seatStates:f,lastUpdated:v,refetch:i}}exports.DEFAULT_COLORS=Me;exports.SeatMapViewer=st;exports.clearFirebaseInstance=it;exports.initializeFirebaseForViewer=ot;exports.isFirebaseInitialized=ue;exports.useConfigFetcher=we;exports.useContainerSize=Ce;exports.useFirebaseConfig=De;exports.useFirebaseSeatStates=Le;exports.useRealtimeSeatMap=rt;exports.useTouchGestures=je;