@ahrowe/ui 0.41.2 → 0.42.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.
- package/dist/cjs-types/common/floorPlan/floorPlan.graph.d.ts +10 -3
- package/dist/cjs-types/common/floorPlan/floorPlan.plan.d.ts +5 -0
- package/dist/cjs-types/common/floorPlan/floorPlan.rooms.d.ts +6 -2
- package/dist/cjs-types/common/floorPlan/floorPlan.snap.d.ts +1 -3
- package/dist/cjs-types/common/floorPlan/index.d.ts +1 -3
- package/dist/cjs-types/common/planCanvas/planCanvas.types.d.ts +1 -1
- package/dist/cjs-types/common/roomDrawer/roomDrawer.types.d.ts +29 -8
- package/dist/cjs-types/common/roomViewer/roomViewer.types.d.ts +4 -2
- package/dist/esm/common/floorPlan/floorPlan.faces.mjs +1 -1
- package/dist/esm/common/floorPlan/floorPlan.faces.mjs.map +1 -1
- package/dist/esm/common/floorPlan/floorPlan.geometry.mjs +1 -1
- package/dist/esm/common/floorPlan/floorPlan.geometry.mjs.map +1 -1
- package/dist/esm/common/floorPlan/floorPlan.graph.mjs +1 -1
- package/dist/esm/common/floorPlan/floorPlan.graph.mjs.map +1 -1
- package/dist/esm/common/floorPlan/floorPlan.hit.mjs +1 -1
- package/dist/esm/common/floorPlan/floorPlan.hit.mjs.map +1 -1
- package/dist/esm/common/floorPlan/floorPlan.json.mjs +1 -1
- package/dist/esm/common/floorPlan/floorPlan.json.mjs.map +1 -1
- package/dist/esm/common/floorPlan/floorPlan.mesh.mjs +1 -1
- package/dist/esm/common/floorPlan/floorPlan.mesh.mjs.map +1 -1
- package/dist/esm/common/floorPlan/floorPlan.path.mjs +1 -1
- package/dist/esm/common/floorPlan/floorPlan.path.mjs.map +1 -1
- package/dist/esm/common/floorPlan/floorPlan.plan.mjs +1 -1
- package/dist/esm/common/floorPlan/floorPlan.plan.mjs.map +1 -1
- package/dist/esm/common/floorPlan/floorPlan.rooms.mjs +1 -1
- package/dist/esm/common/floorPlan/floorPlan.rooms.mjs.map +1 -1
- package/dist/esm/common/floorPlan/floorPlan.snap.mjs +1 -1
- package/dist/esm/common/floorPlan/floorPlan.snap.mjs.map +1 -1
- package/dist/esm/common/floorPlan/floorPlan.triangulate.mjs +1 -1
- package/dist/esm/common/floorPlan/floorPlan.triangulate.mjs.map +1 -1
- package/dist/esm/common/floorPlan/floorPlan.types.mjs +1 -1
- package/dist/esm/common/floorPlan/floorPlan.types.mjs.map +1 -1
- package/dist/esm/common/planCanvas/planCanvas.mjs +1 -1
- package/dist/esm/common/planCanvas/planCanvas.mjs.map +1 -1
- package/dist/esm/common/roomDrawer/roomDrawer.mjs +1 -1
- package/dist/esm/common/roomDrawer/roomDrawer.mjs.map +1 -1
- package/dist/esm/common/roomViewer/roomViewer.mjs +1 -1
- package/dist/esm/common/roomViewer/roomViewer.mjs.map +1 -1
- package/dist/esm/floor-plan.mjs +1 -0
- package/dist/esm/index.mjs +1 -1
- package/dist/floor-plan.cjs +1 -0
- package/dist/floorPlan-DLe5XAx6.cjs +2 -0
- package/dist/floorPlan-DLe5XAx6.cjs.map +1 -0
- package/dist/index.cjs +3 -3
- package/dist/index.cjs.map +1 -1
- package/dist/types/common/floorPlan/floorPlan.graph.d.ts +10 -3
- package/dist/types/common/floorPlan/floorPlan.plan.d.ts +5 -0
- package/dist/types/common/floorPlan/floorPlan.rooms.d.ts +6 -2
- package/dist/types/common/floorPlan/floorPlan.snap.d.ts +1 -3
- package/dist/types/common/floorPlan/index.d.ts +1 -3
- package/dist/types/common/planCanvas/planCanvas.types.d.ts +1 -1
- package/dist/types/common/roomDrawer/roomDrawer.types.d.ts +29 -8
- package/dist/types/common/roomViewer/roomViewer.types.d.ts +4 -2
- package/docs/CLAUDE.md +3 -1
- package/docs/FloorPlan.md +18 -14
- package/docs/RoomDrawer.md +42 -13
- package/docs/RoomViewer.md +1 -14
- package/package.json +18 -1
- package/dist/cjs-types/common/floorPlan/legacySvg.d.ts +0 -27
- package/dist/esm/common/floorPlan/legacySvg.mjs +0 -2
- package/dist/esm/common/floorPlan/legacySvg.mjs.map +0 -1
- package/dist/types/common/floorPlan/legacySvg.d.ts +0 -27
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use client";import{useComponentDefaults as e}from"../configProvider/useComponentDefaults.mjs";import{
|
|
1
|
+
"use client";import{useComponentDefaults as e}from"../configProvider/useComponentDefaults.mjs";import{useLabels as t}from"../configProvider/useLabels.mjs";import{renderIcon as n}from"../utils/renderIcon.mjs";import{floorBounds as r,getFloor as i}from"../floorPlan/floorPlan.plan.mjs";import{derivePlan as a}from"../floorPlan/floorPlan.rooms.mjs";import{clientToWorld as ee}from"../floorPlan/floorPlan.snap.mjs";import o from"../planCanvas/planCanvas.mjs";import s from"./roomViewer.module.mjs";import{useCallback as c,useEffect as l,useId as te,useImperativeHandle as ne,useMemo as u,useRef as d,useState as f}from"react";import p from"classnames";import{faExpand as re,faMagnifyingGlassMinus as ie,faMagnifyingGlassPlus as ae}from"@fortawesome/free-solid-svg-icons";import{jsx as m,jsxs as h}from"react/jsx-runtime";var g=.002,_=4,oe=4;function se(e){let t=e/1e6;return`${t<10?t.toFixed(1):Math.round(t)} m²`}var ce={floors:`Floors`,zoomIn:`Zoom in`,zoomOut:`Zoom out`,fit:`Fit to view`,empty:`Nothing to show`,unnamedRoom:`Unnamed room`,selectedRoom:(e,t)=>`${e} selected, ${t}`,noRoomSelected:`No room selected`};function v(v){let{ref:le,plan:y,activeFloorId:b,defaultActiveFloorId:ue,onFloorChange:x,selectedRoomId:S,defaultSelectedRoomId:de=null,onSelect:C,hoveredRoomId:w,onHoverChange:fe,view:T,defaultView:pe,onViewChange:me,interactive:E=!0,pannable:D=!0,fitOnMount:he=!0,showFloorBar:ge=!0,showViewControls:_e=!0,showGrid:ve=!1,showRoomLabels:ye=!0,showOpeningSymbols:be=!0,getRoomColor:xe,renderRoomLabel:Se,getRoomLabel:Ce,formatArea:O=se,height:we=360,emptyState:Te,labels:Ee,icons:k,className:De,style:Oe,classNames:A,styles:j,"aria-label":M,...ke}=e(`RoomViewer`,v),N=t(`RoomViewer`,Ee,ce),P=d(null),F=d(null),Ae=te().replace(/:/g,``),I=y?.floors??[],[je,Me]=f(ue),Ne=b??je??I[0]?.id,L=u(()=>y?i(y,Ne)??i(y):null,[y,Ne]),R=c(e=>{b===void 0&&Me(e),x?.(e)},[b,x]),z=u(()=>L?a(L).rooms:[],[L]),[Pe,Fe]=f(de),B=S===void 0?Pe:S,[Ie,Le]=f(null),V=w===void 0?Ie:w,H=c(e=>{S===void 0&&Fe(e);let t=e?z.find(t=>t.roomId===e)??null:null;C?.(e,t,L?.id??``)},[S,z,C,L?.id]),Re=c(e=>{w===void 0&&Le(e),fe?.(e)},[w,fe]),ze=(()=>{let e=B?z.find(e=>e.roomId===B):void 0;return e?N.selectedRoom(e.meta?.name||N.unnamedRoom,O(e.area)):N.noRoomSelected})(),[Be,Ve]=f(pe??{x:0,y:0,zoom:.05}),U=T??Be,W=d(U);W.current=U;let G=c(e=>{T===void 0&&Ve(e),me?.(e)},[T,me]),K=d(!1),[q,He]=f({width:800,height:360});l(()=>{let e=P.current;if(!e)return;let t=()=>{let t=e.getBoundingClientRect();t.width>0&&t.height>0&&He({width:Math.round(t.width),height:Math.round(t.height)})},n=new ResizeObserver(t);return n.observe(e),t(),()=>n.disconnect()},[]);let J=c((e={})=>{let t=e.padding??24,n=L?r(L):null;if(!n||n.width<=0||n.height<=0){G({x:-1e3,y:-1e3,zoom:.05});return}let i=Math.max(g,Math.min(_,Math.min((q.width-t*2)/n.width,(q.height-t*2)/n.height)));G({x:n.minX-(q.width/i-n.width)/2,y:n.minY-(q.height/i-n.height)/2,zoom:i})},[L,q.width,q.height,G]);l(()=>{he&&!K.current&&(!L||q.width<=0||Object.keys(L.nodes).length===0||J())},[he,L,q.width,q.height,J]);let Y=c((e,t)=>{K.current=!0;let n=W.current,r=Math.max(g,Math.min(_,n.zoom*e));if(r===n.zoom)return;let i=t?.x??q.width/2,a=t?.y??q.height/2;G({x:n.x+i/n.zoom-i/r,y:n.y+a/n.zoom-a/r,zoom:r})},[G,q.width,q.height]),X=d(new Map),Z=d(null),Q=d(null),Ue=c(e=>{if(D){if(X.current.set(e.pointerId,{x:e.clientX,y:e.clientY}),X.current.size===2){let[e,t]=[...X.current.values()];Q.current={dist:Math.hypot(t.x-e.x,t.y-e.y),view:W.current,mid:{x:(e.x+t.x)/2,y:(e.y+t.y)/2}},Z.current=null;return}Z.current={startClient:{x:e.clientX,y:e.clientY},startView:W.current,moved:!1}}},[D]),We=c(e=>{X.current.has(e.pointerId)&&X.current.set(e.pointerId,{x:e.clientX,y:e.clientY});let t=Q.current;if(t&&X.current.size>=2){let[e,n]=[...X.current.values()],r=Math.hypot(n.x-e.x,n.y-e.y);if(t.dist<=0)return;let i=Math.max(g,Math.min(_,t.view.zoom*(r/t.dist))),a=P.current?.getBoundingClientRect()??{left:0,top:0},o={x:(e.x+n.x)/2,y:(e.y+n.y)/2};K.current=!0;let s=ee(t.mid.x,t.mid.y,a,t.view);G({x:s.x-(o.x-a.left)/i,y:s.y-(o.y-a.top)/i,zoom:i});return}let n=Z.current;if(!n)return;let r=e.clientX-n.startClient.x,i=e.clientY-n.startClient.y;!n.moved&&Math.hypot(r,i)<=oe||(n.moved||e.currentTarget.setPointerCapture?.(e.pointerId),n.moved=!0,K.current=!0,G({x:n.startView.x-r/n.startView.zoom,y:n.startView.y-i/n.startView.zoom,zoom:n.startView.zoom}))},[G]),Ge=c(e=>{X.current.delete(e.pointerId),X.current.size<2&&(Q.current=null),Z.current=null},[]);l(()=>{let e=P.current;if(!e||!D)return;let t=t=>{t.preventDefault();let n=e.getBoundingClientRect();Y(t.deltaY<0?1.1:1/1.1,{x:t.clientX-n.left,y:t.clientY-n.top})};return e.addEventListener(`wheel`,t,{passive:!1}),()=>e.removeEventListener(`wheel`,t)},[D,Y]),ne(le,()=>({fitToContent:J,getView:()=>W.current,setView:G,zoomBy:e=>Y(e),select:H,getFloorId:()=>L?.id??null,setFloorId:R,getSvgElement:()=>F.current}),[J,G,Y,H,L?.id,R]);let Ke=u(()=>B?[{type:`room`,id:B}]:[],[B]),qe=u(()=>V?{type:`room`,id:V}:null,[V]),$=!L||Object.keys(L.walls).length===0;return h(`div`,{...ke,className:p(s.roomViewer,De,A?.root),style:{...Oe,...j?.root},"aria-label":M??`Floor plan`,children:[ge&&I.length>1&&m(`div`,{className:p(s.roomViewerFloorBar,A?.floorBar),style:j?.floorBar,role:`tablist`,"aria-label":N.floors,children:[...I].reverse().map(e=>m(`button`,{type:`button`,role:`tab`,className:p(s.roomViewerFloorTab,e.id===L?.id&&s.roomViewerFloorTabActive,A?.floorTab),style:j?.floorTab,"aria-selected":e.id===L?.id,onClick:()=>R(e.id),children:e.label},e.id))}),h(`div`,{ref:P,className:p(s.roomViewerCanvasWrapper,D&&s.roomViewerCanvasWrapperPannable,A?.canvasWrapper),style:{height:we,...j?.canvasWrapper},onPointerDown:Ue,onPointerMove:We,onPointerUp:Ge,onPointerCancel:Ge,children:[$?m(`div`,{className:p(s.roomViewerEmpty,A?.empty),style:j?.empty,children:Te??N.empty}):m(o,{ref:F,floor:L,rooms:z,view:U,size:q,selection:Ke,hovered:qe,interactiveRooms:E,showGrid:ve,showRoomLabels:ye,showOpeningSymbols:be,getRoomColor:xe,renderRoomLabel:Se,getRoomLabel:Ce??((e,{area:t})=>`${e?.name||N.unnamedRoom}, ${O(t)}`),formatArea:O,onRoomActivate:E?e=>H(e):void 0,onBackgroundActivate:E?()=>H(null):void 0,onHoverChange:E?e=>Re(e?.type===`room`?e.id:null):void 0,classNames:{canvas:A?.canvas,grid:A?.grid,rooms:A?.rooms,roomFill:A?.roomFill,roomLabel:A?.roomLabel,walls:A?.walls,wallBody:A?.wallBody,openings:A?.openings,opening:A?.opening},styles:{canvas:j?.canvas,grid:j?.grid,rooms:j?.rooms,roomFill:j?.roomFill,roomLabel:j?.roomLabel,walls:j?.walls,wallBody:j?.wallBody,openings:j?.openings,opening:j?.opening},"aria-label":M??`Floor plan`}),_e&&!$&&h(`div`,{className:p(s.roomViewerViewControls,A?.viewControls),style:j?.viewControls,children:[m(`button`,{type:`button`,className:p(s.roomViewerViewButton,A?.viewButton),style:j?.viewButton,title:N.zoomOut,"aria-label":N.zoomOut,onClick:()=>Y(1/1.2),children:n(k?.zoomOut??ie)}),m(`button`,{type:`button`,className:p(s.roomViewerViewButton,A?.viewButton),style:j?.viewButton,title:N.fit,"aria-label":N.fit,onClick:()=>{K.current=!1,J()},children:n(k?.fit??re)}),m(`button`,{type:`button`,className:p(s.roomViewerViewButton,A?.viewButton),style:j?.viewButton,title:N.zoomIn,"aria-label":N.zoomIn,onClick:()=>Y(1.2),children:n(k?.zoomIn??ae)})]})]}),m(`div`,{id:Ae,className:s.roomViewerLive,role:`status`,"aria-live":`polite`,children:ze})]})}export{v as default};
|
|
2
2
|
//# sourceMappingURL=roomViewer.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"roomViewer.mjs","names":[],"sources":["../../../../package/common/roomViewer/roomViewer.tsx"],"sourcesContent":["import { useCallback, useEffect, useImperativeHandle, useId, useMemo, useRef, useState } from 'react';\nimport type { PointerEvent as ReactPointerEvent } from 'react';\nimport cx from 'classnames';\nimport { faExpand, faMagnifyingGlassMinus, faMagnifyingGlassPlus } from '@fortawesome/free-solid-svg-icons';\n\nimport { useComponentDefaults } from '../configProvider';\nimport {\n clientToWorld,\n derivePlan,\n floorBounds,\n getFloor,\n type PlanFloor,\n type PlanSelection,\n type PlanView,\n} from '../floorPlan';\nimport PlanCanvas from '../planCanvas';\nimport { renderIcon } from '../utils/renderIcon';\nimport type { RoomViewerProps } from './roomViewer.types';\nimport styles from './roomViewer.module.pcss';\n\nconst MIN_ZOOM = 0.002;\nconst MAX_ZOOM = 4;\n/** Past this many pixels a press is a pan rather than a click on a room. */\nconst PAN_THRESHOLD_PX = 4;\n\nfunction formatAreaDefault(areaMm2: number): string {\n const m2 = areaMm2 / 1e6;\n return `${m2 < 10 ? m2.toFixed(1) : Math.round(m2)} m²`;\n}\n\n/**\n * Read-only view of a floor plan.\n *\n * It renders the same `planCanvas` the drawer does, from the same `FloorPlan`, so the\n * two cannot drift apart. Selection and hover are React state rather than classes pushed\n * onto DOM nodes, which is what lets them be controlled from outside.\n */\nfunction RoomViewer(props: RoomViewerProps) {\n const {\n ref,\n plan,\n activeFloorId,\n defaultActiveFloorId,\n onFloorChange,\n selectedRoomId,\n defaultSelectedRoomId = null,\n onSelect,\n hoveredRoomId,\n onHoverChange,\n view,\n defaultView,\n onViewChange,\n interactive = true,\n pannable = true,\n fitOnMount = true,\n showFloorBar = true,\n showViewControls = true,\n showGrid = false,\n showRoomLabels = true,\n showOpeningSymbols = true,\n getRoomColor,\n renderRoomLabel,\n getRoomLabel,\n formatArea = formatAreaDefault,\n height = 360,\n emptyState,\n labels,\n icons,\n className,\n style,\n classNames,\n styles: slotStyles,\n 'aria-label': ariaLabel,\n ...rest\n } = useComponentDefaults('RoomViewer', props);\n\n const wrapperRef = useRef<HTMLDivElement>(null);\n const svgRef = useRef<SVGSVGElement>(null);\n const liveId = useId().replace(/:/g, '');\n\n const floors = plan?.floors ?? [];\n\n // ─── Floor ────────────────────────────────────────────────────────────────────\n\n const [floorIdState, setFloorIdState] = useState<string | undefined>(defaultActiveFloorId);\n const currentFloorId = activeFloorId ?? floorIdState ?? floors[0]?.id;\n const floor: PlanFloor | null = useMemo(\n () => (plan ? (getFloor(plan, currentFloorId) ?? getFloor(plan)) : null),\n [plan, currentFloorId],\n );\n\n const selectFloor = useCallback(\n (nextId: string) => {\n if (activeFloorId === undefined) setFloorIdState(nextId);\n onFloorChange?.(nextId);\n },\n [activeFloorId, onFloorChange],\n );\n\n const rooms = useMemo(() => (floor ? derivePlan(floor).rooms : []), [floor]);\n\n // ─── Selection and hover ──────────────────────────────────────────────────────\n\n const [selectedState, setSelectedState] = useState<string | null>(defaultSelectedRoomId);\n const selected = selectedRoomId !== undefined ? selectedRoomId : selectedState;\n\n const [hoveredState, setHoveredState] = useState<string | null>(null);\n const hovered = hoveredRoomId !== undefined ? hoveredRoomId : hoveredState;\n\n const selectRoom = useCallback(\n (roomId: string | null) => {\n if (selectedRoomId === undefined) setSelectedState(roomId);\n const room = roomId ? (rooms.find((r) => r.roomId === roomId) ?? null) : null;\n onSelect?.(roomId, room, floor?.id ?? '');\n },\n [selectedRoomId, rooms, onSelect, floor?.id],\n );\n\n const setHovered = useCallback(\n (roomId: string | null) => {\n if (hoveredRoomId === undefined) setHoveredState(roomId);\n onHoverChange?.(roomId);\n },\n [hoveredRoomId, onHoverChange],\n );\n\n // A selection made by clicking a shape is silent to a screen reader, so it is\n // announced separately rather than relying on focus landing somewhere useful.\n const announcement = (() => {\n const room = selected ? rooms.find((r) => r.roomId === selected) : undefined;\n if (!room) return labels?.noRoomSelected ?? 'No room selected';\n const name = room.meta?.name || 'Unnamed room';\n return (labels?.selectedRoom ?? '{name} selected, {area}')\n .replace('{name}', name)\n .replace('{area}', formatArea(room.area));\n })();\n\n // ─── View ─────────────────────────────────────────────────────────────────────\n\n const [viewState, setViewState] = useState<PlanView>(defaultView ?? { x: 0, y: 0, zoom: 0.05 });\n const currentView = view ?? viewState;\n const viewRef = useRef(currentView);\n viewRef.current = currentView;\n\n const applyView = useCallback(\n (next: PlanView) => {\n if (view === undefined) setViewState(next);\n onViewChange?.(next);\n },\n [view, onViewChange],\n );\n\n const userMovedRef = useRef(false);\n const [size, setSize] = useState({ width: 800, height: 360 });\n useEffect(() => {\n const element = wrapperRef.current;\n if (!element) return;\n const measure = () => {\n const rect = element.getBoundingClientRect();\n if (rect.width > 0 && rect.height > 0) {\n setSize({ width: Math.round(rect.width), height: Math.round(rect.height) });\n }\n };\n const observer = new ResizeObserver(measure);\n observer.observe(element);\n measure();\n return () => observer.disconnect();\n }, []);\n\n const fitToContent = useCallback(\n (options: { padding?: number } = {}) => {\n const padding = options.padding ?? 24;\n const bounds = floor ? floorBounds(floor) : null;\n if (!bounds || bounds.width <= 0 || bounds.height <= 0) {\n applyView({ x: -1000, y: -1000, zoom: 0.05 });\n return;\n }\n const zoom = Math.max(\n MIN_ZOOM,\n Math.min(\n MAX_ZOOM,\n Math.min((size.width - padding * 2) / bounds.width, (size.height - padding * 2) / bounds.height),\n ),\n );\n applyView({\n x: bounds.minX - (size.width / zoom - bounds.width) / 2,\n y: bounds.minY - (size.height / zoom - bounds.height) / 2,\n zoom,\n });\n },\n [floor, size.width, size.height, applyView],\n );\n\n /**\n * Refit on anything that changes what \"fitted\" means — the floor, and the canvas size,\n * which is not known until the element has been measured. The moment the viewer pans or\n * zooms, the view is theirs and we stop touching it.\n */\n useEffect(() => {\n if (!fitOnMount || userMovedRef.current) return;\n if (!floor || size.width <= 0 || Object.keys(floor.nodes).length === 0) return;\n fitToContent();\n }, [fitOnMount, floor, size.width, size.height, fitToContent]);\n\n const zoomBy = useCallback(\n (factor: number, centre?: { x: number; y: number }) => {\n userMovedRef.current = true;\n const v = viewRef.current;\n const next = Math.max(MIN_ZOOM, Math.min(MAX_ZOOM, v.zoom * factor));\n if (next === v.zoom) return;\n const cx0 = centre?.x ?? size.width / 2;\n const cy0 = centre?.y ?? size.height / 2;\n // Keep the world point under the cursor where it is.\n applyView({\n x: v.x + cx0 / v.zoom - cx0 / next,\n y: v.y + cy0 / v.zoom - cy0 / next,\n zoom: next,\n });\n },\n [applyView, size.width, size.height],\n );\n\n // ─── Pan and pinch ────────────────────────────────────────────────────────────\n\n const pointersRef = useRef(new Map<number, { x: number; y: number }>());\n const panRef = useRef<{ startClient: { x: number; y: number }; startView: PlanView; moved: boolean } | null>(null);\n const pinchRef = useRef<{ dist: number; view: PlanView; mid: { x: number; y: number } } | null>(null);\n\n const handlePointerDown = useCallback(\n (event: ReactPointerEvent<HTMLDivElement>) => {\n if (!pannable) return;\n pointersRef.current.set(event.pointerId, { x: event.clientX, y: event.clientY });\n // Deliberately NOT capturing the pointer yet. While a capture is active the click\n // is dispatched to the capturing element instead of the shape under the cursor, so\n // capturing here would mean a room could never be clicked. The capture is taken in\n // the move handler, once the press has actually turned into a pan.\n if (pointersRef.current.size === 2) {\n const [p1, p2] = [...pointersRef.current.values()];\n pinchRef.current = {\n dist: Math.hypot(p2.x - p1.x, p2.y - p1.y),\n view: viewRef.current,\n mid: { x: (p1.x + p2.x) / 2, y: (p1.y + p2.y) / 2 },\n };\n panRef.current = null;\n return;\n }\n panRef.current = {\n startClient: { x: event.clientX, y: event.clientY },\n startView: viewRef.current,\n moved: false,\n };\n },\n [pannable],\n );\n\n const handlePointerMove = useCallback(\n (event: ReactPointerEvent<HTMLDivElement>) => {\n if (pointersRef.current.has(event.pointerId)) {\n pointersRef.current.set(event.pointerId, { x: event.clientX, y: event.clientY });\n }\n\n const pinch = pinchRef.current;\n if (pinch && pointersRef.current.size >= 2) {\n const [p1, p2] = [...pointersRef.current.values()];\n const now = Math.hypot(p2.x - p1.x, p2.y - p1.y);\n if (pinch.dist <= 0) return;\n const zoom = Math.max(MIN_ZOOM, Math.min(MAX_ZOOM, pinch.view.zoom * (now / pinch.dist)));\n const rect = wrapperRef.current?.getBoundingClientRect() ?? { left: 0, top: 0 };\n const mid = { x: (p1.x + p2.x) / 2, y: (p1.y + p2.y) / 2 };\n userMovedRef.current = true;\n const worldMid = clientToWorld(pinch.mid.x, pinch.mid.y, rect, pinch.view);\n applyView({\n x: worldMid.x - (mid.x - rect.left) / zoom,\n y: worldMid.y - (mid.y - rect.top) / zoom,\n zoom,\n });\n return;\n }\n\n const pan = panRef.current;\n if (!pan) return;\n const dx = event.clientX - pan.startClient.x;\n const dy = event.clientY - pan.startClient.y;\n if (!pan.moved && Math.hypot(dx, dy) <= PAN_THRESHOLD_PX) return;\n if (!pan.moved) {\n (event.currentTarget as HTMLElement).setPointerCapture?.(event.pointerId);\n }\n pan.moved = true;\n userMovedRef.current = true;\n applyView({\n x: pan.startView.x - dx / pan.startView.zoom,\n y: pan.startView.y - dy / pan.startView.zoom,\n zoom: pan.startView.zoom,\n });\n },\n [applyView],\n );\n\n const handlePointerUp = useCallback((event: ReactPointerEvent<HTMLDivElement>) => {\n pointersRef.current.delete(event.pointerId);\n if (pointersRef.current.size < 2) pinchRef.current = null;\n panRef.current = null;\n }, []);\n\n // React's onWheel is passive, so it cannot preventDefault and the page scrolls instead.\n useEffect(() => {\n const element = wrapperRef.current;\n if (!element || !pannable) return;\n const onWheel = (event: WheelEvent) => {\n event.preventDefault();\n const rect = element.getBoundingClientRect();\n zoomBy(event.deltaY < 0 ? 1.1 : 1 / 1.1, {\n x: event.clientX - rect.left,\n y: event.clientY - rect.top,\n });\n };\n element.addEventListener('wheel', onWheel, { passive: false });\n return () => element.removeEventListener('wheel', onWheel);\n }, [pannable, zoomBy]);\n\n // ─── Handle ───────────────────────────────────────────────────────────────────\n\n useImperativeHandle(\n ref,\n () => ({\n fitToContent,\n getView: () => viewRef.current,\n setView: applyView,\n zoomBy: (factor: number) => zoomBy(factor),\n select: selectRoom,\n getFloorId: () => floor?.id ?? null,\n setFloorId: selectFloor,\n getSvgElement: () => svgRef.current,\n }),\n [fitToContent, applyView, zoomBy, selectRoom, floor?.id, selectFloor],\n );\n\n // ─── Render ───────────────────────────────────────────────────────────────────\n\n const selection: readonly PlanSelection[] = useMemo(\n () => (selected ? [{ type: 'room', id: selected } as PlanSelection] : []),\n [selected],\n );\n const hoveredSelection: PlanSelection | null = useMemo(\n () => (hovered ? { type: 'room', id: hovered } : null),\n [hovered],\n );\n\n const isEmpty = !floor || Object.keys(floor.walls).length === 0;\n\n return (\n <div\n {...rest}\n className={cx(styles.roomViewer, className, classNames?.root)}\n style={{ ...style, ...slotStyles?.root }}\n aria-label={ariaLabel ?? 'Floor plan'}\n >\n {showFloorBar && floors.length > 1 && (\n <div\n className={cx(styles.roomViewerFloorBar, classNames?.floorBar)}\n style={slotStyles?.floorBar}\n role='tablist'\n aria-label={labels?.floors ?? 'Floors'}\n >\n {/* Top storey first, the way a building reads in section. */}\n {[...floors].reverse().map((f) => (\n <button\n key={f.id}\n type='button'\n role='tab'\n className={cx(\n styles.roomViewerFloorTab,\n f.id === floor?.id && styles.roomViewerFloorTabActive,\n classNames?.floorTab,\n )}\n style={slotStyles?.floorTab}\n aria-selected={f.id === floor?.id}\n onClick={() => selectFloor(f.id)}\n >\n {f.label}\n </button>\n ))}\n </div>\n )}\n\n <div\n ref={wrapperRef}\n className={cx(\n styles.roomViewerCanvasWrapper,\n pannable && styles.roomViewerCanvasWrapperPannable,\n classNames?.canvasWrapper,\n )}\n style={{ height, ...slotStyles?.canvasWrapper }}\n onPointerDown={handlePointerDown}\n onPointerMove={handlePointerMove}\n onPointerUp={handlePointerUp}\n onPointerCancel={handlePointerUp}\n >\n {isEmpty ? (\n <div className={cx(styles.roomViewerEmpty, classNames?.empty)} style={slotStyles?.empty}>\n {emptyState ?? labels?.empty ?? 'Nothing to show'}\n </div>\n ) : (\n <PlanCanvas\n ref={svgRef}\n floor={floor}\n rooms={rooms}\n view={currentView}\n size={size}\n selection={selection}\n hovered={hoveredSelection}\n interactiveRooms={interactive}\n showGrid={showGrid}\n showRoomLabels={showRoomLabels}\n showOpeningSymbols={showOpeningSymbols}\n getRoomColor={getRoomColor}\n renderRoomLabel={renderRoomLabel}\n getRoomLabel={getRoomLabel}\n formatArea={formatArea}\n onRoomActivate={interactive ? (roomId) => selectRoom(roomId) : undefined}\n onBackgroundActivate={interactive ? () => selectRoom(null) : undefined}\n onHoverChange={interactive ? (target) => setHovered(target?.type === 'room' ? target.id : null) : undefined}\n classNames={{\n canvas: classNames?.canvas,\n grid: classNames?.grid,\n rooms: classNames?.rooms,\n roomFill: classNames?.roomFill,\n roomLabel: classNames?.roomLabel,\n walls: classNames?.walls,\n wallBody: classNames?.wallBody,\n openings: classNames?.openings,\n opening: classNames?.opening,\n }}\n styles={{\n canvas: slotStyles?.canvas,\n grid: slotStyles?.grid,\n rooms: slotStyles?.rooms,\n roomFill: slotStyles?.roomFill,\n roomLabel: slotStyles?.roomLabel,\n walls: slotStyles?.walls,\n wallBody: slotStyles?.wallBody,\n openings: slotStyles?.openings,\n opening: slotStyles?.opening,\n }}\n aria-label={ariaLabel ?? 'Floor plan'}\n />\n )}\n\n {showViewControls && !isEmpty && (\n <div className={cx(styles.roomViewerViewControls, classNames?.viewControls)} style={slotStyles?.viewControls}>\n <button\n type='button'\n className={cx(styles.roomViewerViewButton, classNames?.viewButton)}\n style={slotStyles?.viewButton}\n title={labels?.zoomOut ?? 'Zoom out'}\n aria-label={labels?.zoomOut ?? 'Zoom out'}\n onClick={() => zoomBy(1 / 1.2)}\n >\n {renderIcon(icons?.zoomOut ?? faMagnifyingGlassMinus)}\n </button>\n <button\n type='button'\n className={cx(styles.roomViewerViewButton, classNames?.viewButton)}\n style={slotStyles?.viewButton}\n title={labels?.fit ?? 'Fit to view'}\n aria-label={labels?.fit ?? 'Fit to view'}\n onClick={() => {\n userMovedRef.current = false;\n fitToContent();\n }}\n >\n {renderIcon(icons?.fit ?? faExpand)}\n </button>\n <button\n type='button'\n className={cx(styles.roomViewerViewButton, classNames?.viewButton)}\n style={slotStyles?.viewButton}\n title={labels?.zoomIn ?? 'Zoom in'}\n aria-label={labels?.zoomIn ?? 'Zoom in'}\n onClick={() => zoomBy(1.2)}\n >\n {renderIcon(icons?.zoomIn ?? faMagnifyingGlassPlus)}\n </button>\n </div>\n )}\n </div>\n\n <div id={liveId} className={styles.roomViewerLive} role='status' aria-live='polite'>\n {announcement}\n </div>\n </div>\n );\n}\n\nexport default RoomViewer;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"roomViewer.mjs","names":[],"sources":["../../../../package/common/roomViewer/roomViewer.tsx"],"sourcesContent":["import { useCallback, useEffect, useImperativeHandle, useId, useMemo, useRef, useState } from 'react';\nimport type { PointerEvent as ReactPointerEvent } from 'react';\nimport cx from 'classnames';\nimport { faExpand, faMagnifyingGlassMinus, faMagnifyingGlassPlus } from '@fortawesome/free-solid-svg-icons';\n\nimport { useComponentDefaults, useLabels } from '../configProvider';\nimport {\n clientToWorld,\n derivePlan,\n floorBounds,\n getFloor,\n type PlanFloor,\n type PlanSelection,\n type PlanView,\n} from '../floorPlan';\nimport PlanCanvas from '../planCanvas';\nimport { renderIcon } from '../utils/renderIcon';\nimport type { RoomViewerLabels, RoomViewerProps } from './roomViewer.types';\nimport styles from './roomViewer.module.pcss';\n\nconst MIN_ZOOM = 0.002;\nconst MAX_ZOOM = 4;\n/** Past this many pixels a press is a pan rather than a click on a room. */\nconst PAN_THRESHOLD_PX = 4;\n\nfunction formatAreaDefault(areaMm2: number): string {\n const m2 = areaMm2 / 1e6;\n return `${m2 < 10 ? m2.toFixed(1) : Math.round(m2)} m²`;\n}\n\nconst DEFAULT_LABELS: Required<RoomViewerLabels> = {\n floors: 'Floors',\n zoomIn: 'Zoom in',\n zoomOut: 'Zoom out',\n fit: 'Fit to view',\n empty: 'Nothing to show',\n unnamedRoom: 'Unnamed room',\n selectedRoom: (name, area) => `${name} selected, ${area}`,\n noRoomSelected: 'No room selected',\n};\n\n/**\n * Read-only view of a floor plan.\n *\n * It renders the same `planCanvas` the drawer does, from the same `FloorPlan`, so the\n * two cannot drift apart. Selection and hover are React state rather than classes pushed\n * onto DOM nodes, which is what lets them be controlled from outside.\n */\nfunction RoomViewer(props: RoomViewerProps) {\n const {\n ref,\n plan,\n activeFloorId,\n defaultActiveFloorId,\n onFloorChange,\n selectedRoomId,\n defaultSelectedRoomId = null,\n onSelect,\n hoveredRoomId,\n onHoverChange,\n view,\n defaultView,\n onViewChange,\n interactive = true,\n pannable = true,\n fitOnMount = true,\n showFloorBar = true,\n showViewControls = true,\n showGrid = false,\n showRoomLabels = true,\n showOpeningSymbols = true,\n getRoomColor,\n renderRoomLabel,\n getRoomLabel,\n formatArea = formatAreaDefault,\n height = 360,\n emptyState,\n labels,\n icons,\n className,\n style,\n classNames,\n styles: slotStyles,\n 'aria-label': ariaLabel,\n ...rest\n } = useComponentDefaults('RoomViewer', props);\n const text = useLabels('RoomViewer', labels, DEFAULT_LABELS);\n\n const wrapperRef = useRef<HTMLDivElement>(null);\n const svgRef = useRef<SVGSVGElement>(null);\n const liveId = useId().replace(/:/g, '');\n\n const floors = plan?.floors ?? [];\n\n // ─── Floor ────────────────────────────────────────────────────────────────────\n\n const [floorIdState, setFloorIdState] = useState<string | undefined>(defaultActiveFloorId);\n const currentFloorId = activeFloorId ?? floorIdState ?? floors[0]?.id;\n const floor: PlanFloor | null = useMemo(\n () => (plan ? (getFloor(plan, currentFloorId) ?? getFloor(plan)) : null),\n [plan, currentFloorId],\n );\n\n const selectFloor = useCallback(\n (nextId: string) => {\n if (activeFloorId === undefined) setFloorIdState(nextId);\n onFloorChange?.(nextId);\n },\n [activeFloorId, onFloorChange],\n );\n\n const rooms = useMemo(() => (floor ? derivePlan(floor).rooms : []), [floor]);\n\n // ─── Selection and hover ──────────────────────────────────────────────────────\n\n const [selectedState, setSelectedState] = useState<string | null>(defaultSelectedRoomId);\n const selected = selectedRoomId !== undefined ? selectedRoomId : selectedState;\n\n const [hoveredState, setHoveredState] = useState<string | null>(null);\n const hovered = hoveredRoomId !== undefined ? hoveredRoomId : hoveredState;\n\n const selectRoom = useCallback(\n (roomId: string | null) => {\n if (selectedRoomId === undefined) setSelectedState(roomId);\n const room = roomId ? (rooms.find((r) => r.roomId === roomId) ?? null) : null;\n onSelect?.(roomId, room, floor?.id ?? '');\n },\n [selectedRoomId, rooms, onSelect, floor?.id],\n );\n\n const setHovered = useCallback(\n (roomId: string | null) => {\n if (hoveredRoomId === undefined) setHoveredState(roomId);\n onHoverChange?.(roomId);\n },\n [hoveredRoomId, onHoverChange],\n );\n\n // A selection made by clicking a shape is silent to a screen reader, so it is\n // announced separately rather than relying on focus landing somewhere useful.\n const announcement = (() => {\n const room = selected ? rooms.find((r) => r.roomId === selected) : undefined;\n if (!room) return text.noRoomSelected;\n return text.selectedRoom(room.meta?.name || text.unnamedRoom, formatArea(room.area));\n })();\n\n // ─── View ─────────────────────────────────────────────────────────────────────\n\n const [viewState, setViewState] = useState<PlanView>(defaultView ?? { x: 0, y: 0, zoom: 0.05 });\n const currentView = view ?? viewState;\n const viewRef = useRef(currentView);\n viewRef.current = currentView;\n\n const applyView = useCallback(\n (next: PlanView) => {\n if (view === undefined) setViewState(next);\n onViewChange?.(next);\n },\n [view, onViewChange],\n );\n\n const userMovedRef = useRef(false);\n const [size, setSize] = useState({ width: 800, height: 360 });\n useEffect(() => {\n const element = wrapperRef.current;\n if (!element) return;\n const measure = () => {\n const rect = element.getBoundingClientRect();\n if (rect.width > 0 && rect.height > 0) {\n setSize({ width: Math.round(rect.width), height: Math.round(rect.height) });\n }\n };\n const observer = new ResizeObserver(measure);\n observer.observe(element);\n measure();\n return () => observer.disconnect();\n }, []);\n\n const fitToContent = useCallback(\n (options: { padding?: number } = {}) => {\n const padding = options.padding ?? 24;\n const bounds = floor ? floorBounds(floor) : null;\n if (!bounds || bounds.width <= 0 || bounds.height <= 0) {\n applyView({ x: -1000, y: -1000, zoom: 0.05 });\n return;\n }\n const zoom = Math.max(\n MIN_ZOOM,\n Math.min(\n MAX_ZOOM,\n Math.min((size.width - padding * 2) / bounds.width, (size.height - padding * 2) / bounds.height),\n ),\n );\n applyView({\n x: bounds.minX - (size.width / zoom - bounds.width) / 2,\n y: bounds.minY - (size.height / zoom - bounds.height) / 2,\n zoom,\n });\n },\n [floor, size.width, size.height, applyView],\n );\n\n /**\n * Refit on anything that changes what \"fitted\" means — the floor, and the canvas size,\n * which is not known until the element has been measured. The moment the viewer pans or\n * zooms, the view is theirs and we stop touching it.\n */\n useEffect(() => {\n if (!fitOnMount || userMovedRef.current) return;\n if (!floor || size.width <= 0 || Object.keys(floor.nodes).length === 0) return;\n fitToContent();\n }, [fitOnMount, floor, size.width, size.height, fitToContent]);\n\n const zoomBy = useCallback(\n (factor: number, centre?: { x: number; y: number }) => {\n userMovedRef.current = true;\n const v = viewRef.current;\n const next = Math.max(MIN_ZOOM, Math.min(MAX_ZOOM, v.zoom * factor));\n if (next === v.zoom) return;\n const cx0 = centre?.x ?? size.width / 2;\n const cy0 = centre?.y ?? size.height / 2;\n // Keep the world point under the cursor where it is.\n applyView({\n x: v.x + cx0 / v.zoom - cx0 / next,\n y: v.y + cy0 / v.zoom - cy0 / next,\n zoom: next,\n });\n },\n [applyView, size.width, size.height],\n );\n\n // ─── Pan and pinch ────────────────────────────────────────────────────────────\n\n const pointersRef = useRef(new Map<number, { x: number; y: number }>());\n const panRef = useRef<{ startClient: { x: number; y: number }; startView: PlanView; moved: boolean } | null>(null);\n const pinchRef = useRef<{ dist: number; view: PlanView; mid: { x: number; y: number } } | null>(null);\n\n const handlePointerDown = useCallback(\n (event: ReactPointerEvent<HTMLDivElement>) => {\n if (!pannable) return;\n pointersRef.current.set(event.pointerId, { x: event.clientX, y: event.clientY });\n // Deliberately NOT capturing the pointer yet. While a capture is active the click\n // is dispatched to the capturing element instead of the shape under the cursor, so\n // capturing here would mean a room could never be clicked. The capture is taken in\n // the move handler, once the press has actually turned into a pan.\n if (pointersRef.current.size === 2) {\n const [p1, p2] = [...pointersRef.current.values()];\n pinchRef.current = {\n dist: Math.hypot(p2.x - p1.x, p2.y - p1.y),\n view: viewRef.current,\n mid: { x: (p1.x + p2.x) / 2, y: (p1.y + p2.y) / 2 },\n };\n panRef.current = null;\n return;\n }\n panRef.current = {\n startClient: { x: event.clientX, y: event.clientY },\n startView: viewRef.current,\n moved: false,\n };\n },\n [pannable],\n );\n\n const handlePointerMove = useCallback(\n (event: ReactPointerEvent<HTMLDivElement>) => {\n if (pointersRef.current.has(event.pointerId)) {\n pointersRef.current.set(event.pointerId, { x: event.clientX, y: event.clientY });\n }\n\n const pinch = pinchRef.current;\n if (pinch && pointersRef.current.size >= 2) {\n const [p1, p2] = [...pointersRef.current.values()];\n const now = Math.hypot(p2.x - p1.x, p2.y - p1.y);\n if (pinch.dist <= 0) return;\n const zoom = Math.max(MIN_ZOOM, Math.min(MAX_ZOOM, pinch.view.zoom * (now / pinch.dist)));\n const rect = wrapperRef.current?.getBoundingClientRect() ?? { left: 0, top: 0 };\n const mid = { x: (p1.x + p2.x) / 2, y: (p1.y + p2.y) / 2 };\n userMovedRef.current = true;\n const worldMid = clientToWorld(pinch.mid.x, pinch.mid.y, rect, pinch.view);\n applyView({\n x: worldMid.x - (mid.x - rect.left) / zoom,\n y: worldMid.y - (mid.y - rect.top) / zoom,\n zoom,\n });\n return;\n }\n\n const pan = panRef.current;\n if (!pan) return;\n const dx = event.clientX - pan.startClient.x;\n const dy = event.clientY - pan.startClient.y;\n if (!pan.moved && Math.hypot(dx, dy) <= PAN_THRESHOLD_PX) return;\n if (!pan.moved) {\n (event.currentTarget as HTMLElement).setPointerCapture?.(event.pointerId);\n }\n pan.moved = true;\n userMovedRef.current = true;\n applyView({\n x: pan.startView.x - dx / pan.startView.zoom,\n y: pan.startView.y - dy / pan.startView.zoom,\n zoom: pan.startView.zoom,\n });\n },\n [applyView],\n );\n\n const handlePointerUp = useCallback((event: ReactPointerEvent<HTMLDivElement>) => {\n pointersRef.current.delete(event.pointerId);\n if (pointersRef.current.size < 2) pinchRef.current = null;\n panRef.current = null;\n }, []);\n\n // React's onWheel is passive, so it cannot preventDefault and the page scrolls instead.\n useEffect(() => {\n const element = wrapperRef.current;\n if (!element || !pannable) return;\n const onWheel = (event: WheelEvent) => {\n event.preventDefault();\n const rect = element.getBoundingClientRect();\n zoomBy(event.deltaY < 0 ? 1.1 : 1 / 1.1, {\n x: event.clientX - rect.left,\n y: event.clientY - rect.top,\n });\n };\n element.addEventListener('wheel', onWheel, { passive: false });\n return () => element.removeEventListener('wheel', onWheel);\n }, [pannable, zoomBy]);\n\n // ─── Handle ───────────────────────────────────────────────────────────────────\n\n useImperativeHandle(\n ref,\n () => ({\n fitToContent,\n getView: () => viewRef.current,\n setView: applyView,\n zoomBy: (factor: number) => zoomBy(factor),\n select: selectRoom,\n getFloorId: () => floor?.id ?? null,\n setFloorId: selectFloor,\n getSvgElement: () => svgRef.current,\n }),\n [fitToContent, applyView, zoomBy, selectRoom, floor?.id, selectFloor],\n );\n\n // ─── Render ───────────────────────────────────────────────────────────────────\n\n const selection: readonly PlanSelection[] = useMemo(\n () => (selected ? [{ type: 'room', id: selected } as PlanSelection] : []),\n [selected],\n );\n const hoveredSelection: PlanSelection | null = useMemo(\n () => (hovered ? { type: 'room', id: hovered } : null),\n [hovered],\n );\n\n const isEmpty = !floor || Object.keys(floor.walls).length === 0;\n\n return (\n <div\n {...rest}\n className={cx(styles.roomViewer, className, classNames?.root)}\n style={{ ...style, ...slotStyles?.root }}\n aria-label={ariaLabel ?? 'Floor plan'}\n >\n {showFloorBar && floors.length > 1 && (\n <div\n className={cx(styles.roomViewerFloorBar, classNames?.floorBar)}\n style={slotStyles?.floorBar}\n role='tablist'\n aria-label={text.floors}\n >\n {/* Top storey first, the way a building reads in section. */}\n {[...floors].reverse().map((f) => (\n <button\n key={f.id}\n type='button'\n role='tab'\n className={cx(\n styles.roomViewerFloorTab,\n f.id === floor?.id && styles.roomViewerFloorTabActive,\n classNames?.floorTab,\n )}\n style={slotStyles?.floorTab}\n aria-selected={f.id === floor?.id}\n onClick={() => selectFloor(f.id)}\n >\n {f.label}\n </button>\n ))}\n </div>\n )}\n\n <div\n ref={wrapperRef}\n className={cx(\n styles.roomViewerCanvasWrapper,\n pannable && styles.roomViewerCanvasWrapperPannable,\n classNames?.canvasWrapper,\n )}\n style={{ height, ...slotStyles?.canvasWrapper }}\n onPointerDown={handlePointerDown}\n onPointerMove={handlePointerMove}\n onPointerUp={handlePointerUp}\n onPointerCancel={handlePointerUp}\n >\n {isEmpty ? (\n <div className={cx(styles.roomViewerEmpty, classNames?.empty)} style={slotStyles?.empty}>\n {emptyState ?? text.empty}\n </div>\n ) : (\n <PlanCanvas\n ref={svgRef}\n floor={floor}\n rooms={rooms}\n view={currentView}\n size={size}\n selection={selection}\n hovered={hoveredSelection}\n interactiveRooms={interactive}\n showGrid={showGrid}\n showRoomLabels={showRoomLabels}\n showOpeningSymbols={showOpeningSymbols}\n getRoomColor={getRoomColor}\n renderRoomLabel={renderRoomLabel}\n getRoomLabel={\n getRoomLabel ?? ((room, { area }) => `${room?.name || text.unnamedRoom}, ${formatArea(area)}`)\n }\n formatArea={formatArea}\n onRoomActivate={interactive ? (roomId) => selectRoom(roomId) : undefined}\n onBackgroundActivate={interactive ? () => selectRoom(null) : undefined}\n onHoverChange={interactive ? (target) => setHovered(target?.type === 'room' ? target.id : null) : undefined}\n classNames={{\n canvas: classNames?.canvas,\n grid: classNames?.grid,\n rooms: classNames?.rooms,\n roomFill: classNames?.roomFill,\n roomLabel: classNames?.roomLabel,\n walls: classNames?.walls,\n wallBody: classNames?.wallBody,\n openings: classNames?.openings,\n opening: classNames?.opening,\n }}\n styles={{\n canvas: slotStyles?.canvas,\n grid: slotStyles?.grid,\n rooms: slotStyles?.rooms,\n roomFill: slotStyles?.roomFill,\n roomLabel: slotStyles?.roomLabel,\n walls: slotStyles?.walls,\n wallBody: slotStyles?.wallBody,\n openings: slotStyles?.openings,\n opening: slotStyles?.opening,\n }}\n aria-label={ariaLabel ?? 'Floor plan'}\n />\n )}\n\n {showViewControls && !isEmpty && (\n <div className={cx(styles.roomViewerViewControls, classNames?.viewControls)} style={slotStyles?.viewControls}>\n <button\n type='button'\n className={cx(styles.roomViewerViewButton, classNames?.viewButton)}\n style={slotStyles?.viewButton}\n title={text.zoomOut}\n aria-label={text.zoomOut}\n onClick={() => zoomBy(1 / 1.2)}\n >\n {renderIcon(icons?.zoomOut ?? faMagnifyingGlassMinus)}\n </button>\n <button\n type='button'\n className={cx(styles.roomViewerViewButton, classNames?.viewButton)}\n style={slotStyles?.viewButton}\n title={text.fit}\n aria-label={text.fit}\n onClick={() => {\n userMovedRef.current = false;\n fitToContent();\n }}\n >\n {renderIcon(icons?.fit ?? faExpand)}\n </button>\n <button\n type='button'\n className={cx(styles.roomViewerViewButton, classNames?.viewButton)}\n style={slotStyles?.viewButton}\n title={text.zoomIn}\n aria-label={text.zoomIn}\n onClick={() => zoomBy(1.2)}\n >\n {renderIcon(icons?.zoomIn ?? faMagnifyingGlassPlus)}\n </button>\n </div>\n )}\n </div>\n\n <div id={liveId} className={styles.roomViewerLive} role='status' aria-live='polite'>\n {announcement}\n </div>\n </div>\n );\n}\n\nexport default RoomViewer;\n"],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{DoorSwing as e,OpeningKind as t,PlanIssueKind as n,PlanUnitSystem as r,WallType as i}from"./common/floorPlan/floorPlan.types.mjs";import{MIN_OPENING_WIDTH as a,MIN_WALL_LENGTH as o}from"./common/floorPlan/floorPlan.geometry.mjs";import{DEFAULT_WALL_ATTRS as s,addOpening as c,addRect as l,addWall as u,cleanupPlan as d,detachWall as f,dissolveNode as p,mergeNodes as m,moveNode as h,removeOpening as g,removeWall as _,scalePlan as v,splitWall as y,transformPlan as b,updateOpening as x,validatePlan as S,wallLength as C,weldShortWalls as w}from"./common/floorPlan/floorPlan.graph.mjs";import{MIN_FLOOR_HEIGHT as T,addFloor as E,duplicateFloor as D,emptyFloor as O,emptyFloorPlan as k,floorBelow as A,floorBounds as j,floorIndex as M,getFloor as N,moveFloor as P,removeFloor as F,renameFloor as I,setFloor as L,setFloorHeight as R,updateFloor as z}from"./common/floorPlan/floorPlan.plan.mjs";import{deriveFaces as B,nodeDegrees as V}from"./common/floorPlan/floorPlan.faces.mjs";import{commitDerivation as H,derivePlan as U,pruneUnmatchedRooms as W,roomAtPoint as G}from"./common/floorPlan/floorPlan.rooms.mjs";import{buildWallPaths as K,openingGeometry as q,wallCentrelineSpans as J}from"./common/floorPlan/floorPlan.path.mjs";import{HIT_PX as Y,HIT_PX_COARSE as X,hitTest as Z,selectionsEqual as Q,worldTolerances as $}from"./common/floorPlan/floorPlan.hit.mjs";import{DEFAULT_SNAP_OPTIONS as ee,SnapKind as te,clientToWorld as ne,resolveSnap as re}from"./common/floorPlan/floorPlan.snap.mjs";import{PLAN_FORMAT_VERSION as ie,planFromJson as ae,planToJson as oe}from"./common/floorPlan/floorPlan.json.mjs";import{buildPlanMesh as se}from"./common/floorPlan/floorPlan.mesh.mjs";export{ee as DEFAULT_SNAP_OPTIONS,s as DEFAULT_WALL_ATTRS,e as DoorSwing,Y as HIT_PX,X as HIT_PX_COARSE,T as MIN_FLOOR_HEIGHT,a as MIN_OPENING_WIDTH,o as MIN_WALL_LENGTH,t as OpeningKind,ie as PLAN_FORMAT_VERSION,n as PlanIssueKind,r as PlanUnitSystem,te as SnapKind,i as WallType,E as addFloor,c as addOpening,l as addRect,u as addWall,se as buildPlanMesh,K as buildWallPaths,d as cleanupPlan,ne as clientToWorld,H as commitDerivation,B as deriveFaces,U as derivePlan,f as detachWall,p as dissolveNode,D as duplicateFloor,O as emptyFloor,k as emptyFloorPlan,A as floorBelow,j as floorBounds,M as floorIndex,N as getFloor,Z as hitTest,m as mergeNodes,P as moveFloor,h as moveNode,V as nodeDegrees,q as openingGeometry,ae as planFromJson,oe as planToJson,W as pruneUnmatchedRooms,F as removeFloor,g as removeOpening,_ as removeWall,I as renameFloor,re as resolveSnap,G as roomAtPoint,v as scalePlan,Q as selectionsEqual,L as setFloor,R as setFloorHeight,y as splitWall,b as transformPlan,z as updateFloor,x as updateOpening,S as validatePlan,J as wallCentrelineSpans,C as wallLength,w as weldShortWalls,$ as worldTolerances};
|
package/dist/esm/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use client";import{AccordionStyleType as e}from"./common/accordion/accordion.types.mjs";import t from"./common/configProvider/configProvider.mjs";import{useComponentDefaults as n}from"./common/configProvider/useComponentDefaults.mjs";import{useLabels as r}from"./common/configProvider/useLabels.mjs";import{usePresentationDefault as i}from"./common/configProvider/usePresentationDefault.mjs";import{Presentation as a}from"./common/configProvider/presentation.types.mjs";import o from"./common/accordion/accordion.mjs";import s from"./common/loading/spinnerLoading/index.mjs";import{ButtonSize as c,ButtonStyleType as l,ButtonType as u}from"./common/button/button.types.mjs";import d from"./common/ripple/ripple.mjs";import f from"./common/button/button.mjs";import p from"./common/actionButtons/actionButtons.mjs";import m from"./common/interactableDiv/index.mjs";import h from"./common/actionIcon/actionIcon.mjs";import g from"./common/scrollbarProvider/index.mjs";import{defaultTheme as _}from"./common/themeProvider/defaultTheme.mjs";import v from"./common/themeProvider/themeProvider.mjs";import{lightTheme as y}from"./common/themeProvider/lightTheme.mjs";import b from"./common/bodyEnd/bodyEnd.mjs";import x from"./common/hooks/useMediaQuery.mjs";import S from"./common/hooks/useCoarsePointer.mjs";import{useSwipeDismiss as C}from"./common/hooks/useSwipeDismiss.mjs";import{showToast as w}from"./common/toast/toastService.mjs";import T from"./common/ahroweProvider/ahroweProvider.mjs";import{AlertStyleType as E}from"./common/alert/alert.types.mjs";import D from"./common/alert/alert.mjs";import O from"./common/animatedLogo/animatedLogo.mjs";import{AnimatedTextUnit as k,AnimatedTextVariant as A}from"./common/animatedText/animatedText.types.mjs";import j from"./common/animatedText/animatedText.mjs";import{BadgePosition as M,BadgeStyleType as N}from"./common/badge/badge.types.mjs";import P from"./common/badge/badge.mjs";import F from"./common/avatar/avatar.mjs";import I from"./common/avatar/avatarGroup.mjs";import{PopoverAlign as L,PopoverPlacement as R,PopoverTrigger as z}from"./common/popover/popover.types.mjs";import{tabbablesIn as B}from"./common/hooks/useFocusBoundary.mjs";import{useVisualViewportSize as V}from"./common/hooks/useVisualViewportSize.mjs";import{useOverlay as H}from"./common/hooks/useOverlay.mjs";import U from"./common/popover/popover.mjs";import W from"./common/breadcrumb/breadcrumb.mjs";import{ButtonGroupOrientation as G}from"./common/buttonGroup/buttonGroup.types.mjs";import K from"./common/buttonGroup/buttonGroup.mjs";import{dateToDay as q,dateToTime as J,dayTimeToDate as Y,dayToDate as X}from"./common/utils/day.mjs";import{CalendarView as Z}from"./common/calendar/calendar.types.mjs";import Q from"./common/optionPicker/optionPicker.mjs";import $ from"./common/calendar/calendar.mjs";import{CardStyleType as ee}from"./common/card/card.types.mjs";import te from"./common/card/Card.mjs";import ne from"./common/card/CardHeader.mjs";import re from"./common/card/CardMedia.mjs";import ie from"./common/card/CardContent.mjs";import ae from"./common/card/CardActions.mjs";import oe from"./common/carousel/carousel.mjs";import se from"./common/checkbox/checkbox.mjs";import{ChipStyleType as ce}from"./common/chip/chip.types.mjs";import le from"./common/chip/chip.mjs";import ue from"./common/chip/chipContainer.mjs";import de from"./common/tooltip/tooltip.mjs";import{InputIconPosition as fe,InputType as pe}from"./common/input/input.types.mjs";import me from"./common/input/input.mjs";import he from"./common/colorPicker/colorPicker.mjs";import{useScrollEdges as ge}from"./common/hooks/useScrollEdges.mjs";import _e from"./common/modal/modal.mjs";import ve,{formatHotkey as ye}from"./common/hooks/useHotkeys.mjs";import{isMenuAction as be,isMenuHeading as xe,isMenuSeparator as Se}from"./common/menu/menu.types.mjs";import Ce from"./common/commandPalette/commandPalette.mjs";import we from"./common/confirmModal/confirmModal.mjs";import Te from"./common/hooks/useClipboard.mjs";import Ee from"./common/copyButton/copyButton.mjs";import{getLocale as De,mapLocale as Oe,setLocale as ke}from"./services/localization.mjs";import Ae from"./common/dropdown/dropdown.mjs";import je from"./common/datePicker/datePicker.mjs";import{DividerOrientation as Me,DividerTextPosition as Ne}from"./common/divider/divider.types.mjs";import Pe from"./common/divider/divider.mjs";import Fe from"./common/drawer/drawer.mjs";import{DropZoneReturnType as Ie,DropZoneStatus as Le}from"./common/dropZone/dropZone.types.mjs";import Re from"./common/dropZone/dropZone.mjs";import ze from"./common/emptyState/emptyState.mjs";import Be from"./common/errorBoundary/errorBoundary.mjs";import Ve from"./common/fab/fab.mjs";import He from"./common/flip/flip.mjs";import{DoorSwing as Ue,OpeningKind as We,PlanIssueKind as Ge,PlanUnitSystem as Ke,WallType as qe}from"./common/floorPlan/floorPlan.types.mjs";import{MIN_OPENING_WIDTH as Je,MIN_WALL_LENGTH as Ye}from"./common/floorPlan/floorPlan.geometry.mjs";import{DEFAULT_WALL_ATTRS as Xe,addOpening as Ze,addRect as Qe,addWall as $e,cleanupPlan as et,detachWall as tt,dissolveNode as nt,mergeNodes as rt,moveNode as it,removeOpening as at,removeWall as ot,scalePlan as st,splitWall as ct,transformPlan as lt,updateOpening as ut,validatePlan as dt,wallLength as ft,weldShortWalls as pt}from"./common/floorPlan/floorPlan.graph.mjs";import{MIN_FLOOR_HEIGHT as mt,addFloor as ht,duplicateFloor as gt,emptyFloor as _t,emptyFloorPlan as vt,floorBelow as yt,floorBounds as bt,floorIndex as xt,getFloor as St,moveFloor as Ct,removeFloor as wt,renameFloor as Tt,setFloor as Et,setFloorHeight as Dt,updateFloor as Ot}from"./common/floorPlan/floorPlan.plan.mjs";import{deriveFaces as kt,nodeDegrees as At}from"./common/floorPlan/floorPlan.faces.mjs";import{commitDerivation as jt,derivePlan as Mt,pruneUnmatchedRooms as Nt,roomAtPoint as Pt}from"./common/floorPlan/floorPlan.rooms.mjs";import{buildWallPaths as Ft,openingGeometry as It,wallCentrelineSpans as Lt}from"./common/floorPlan/floorPlan.path.mjs";import{HIT_PX as Rt,HIT_PX_COARSE as zt,hitTest as Bt,selectionsEqual as Vt,worldTolerances as Ht}from"./common/floorPlan/floorPlan.hit.mjs";import{DEFAULT_SNAP_OPTIONS as Ut,SnapKind as Wt,clientToWorld as Gt,resolveSnap as Kt,screenScale as qt}from"./common/floorPlan/floorPlan.snap.mjs";import{PLAN_FORMAT_VERSION as Jt,planFromJson as Yt,planToJson as Xt}from"./common/floorPlan/floorPlan.json.mjs";import{buildPlanMesh as Zt}from"./common/floorPlan/floorPlan.mesh.mjs";import{planFromLegacySvg as Qt}from"./common/floorPlan/legacySvg.mjs";import $t from"./common/iconPicker/iconPicker.mjs";import en from"./common/idleManager/idleManager.mjs";import tn from"./common/inputDropdown/inputDropdown.mjs";import nn from"./common/kanbanBoard/KanbanColumn.mjs";import rn from"./common/kanbanBoard/KanbanBoard.mjs";import an from"./common/searchInput/searchInput.mjs";import on from"./common/klipyPicker/klipyPicker.mjs";import sn from"./common/menu/menu.mjs";import{menuHotkeys as cn}from"./common/menu/menuHotkeys.mjs";import ln from"./common/multiSelect/multiSelect.mjs";import un from"./common/numberInput/index.mjs";import{OtpInputCharset as dn}from"./common/otpInput/otpInput.types.mjs";import fn from"./common/otpInput/otpInput.mjs";import pn from"./common/overscroll/overscroll.mjs";import mn from"./common/pagination/pagination.mjs";import hn from"./common/progressBar/progressBar.mjs";import{RadioGroupOrientation as gn}from"./common/radioGroup/radioGroup.types.mjs";import _n from"./common/radioGroup/radioGroup.mjs";import vn from"./common/rating/rating.mjs";import yn from"./common/revealLens/revealLens.mjs";import bn from"./common/roomDrawer/roomDrawer.mjs";import xn from"./common/roomViewer/roomViewer.mjs";import{ScrollFadeAxis as Sn}from"./common/scrollFade/scrollFade.types.mjs";import Cn from"./common/scrollFade/scrollFade.mjs";import{SectionHeaderSize as wn}from"./common/sectionHeader/sectionHeader.types.mjs";import Tn from"./common/sectionHeader/sectionHeader.mjs";import{SkeletonAnimation as En,SkeletonVariant as Dn}from"./common/skeleton/skeleton.types.mjs";import On from"./common/skeleton/skeleton.mjs";import kn from"./common/slider/slider.mjs";import An from"./common/splitButton/splitButton.mjs";import{StepperAlignment as jn,StepperCollapse as Mn,StepperLabelPlacement as Nn,StepperStyleType as Pn}from"./common/stepper/stepper.types.mjs";import Fn from"./common/stepper/stepper.mjs";import In from"./common/sticky/sticky.mjs";import Ln from"./common/switch/switch.mjs";import Rn from"./common/tabHeader/tabHeader.mjs";import zn from"./common/textarea/textarea.mjs";import{useTheme as Bn}from"./common/themeProvider/useTheme.mjs";import Vn,{TiltGroupContext as Hn,useTiltGroup as Un}from"./common/tiltGroup/tiltGroup.mjs";import{defaultTiltEasing as Wn}from"./common/tilt/tiltMath.mjs";import Gn from"./common/tilt/tilt.mjs";import Kn from"./common/timeInput/timeInput.mjs";import{TimelineAlignment as qn,TimelineItemStatus as Jn}from"./common/timeline/timeline.types.mjs";import Yn from"./common/timeline/timeline.mjs";import Xn from"./common/timer/timer.mjs";import Zn from"./common/virtualList/virtualList.mjs";import{flattenTree as Qn}from"./common/tree/flattenTree.mjs";import $n from"./common/tree/tree.mjs";import{WeatherType as er}from"./common/weatherIcon/weatherIcon.types.mjs";import tr from"./common/weatherIcon/weatherIcon.mjs";import nr from"./common/wizard/wizard.mjs";import rr from"./services/formValidation/FormValidatorGroupWithForm.mjs";import ir from"./services/formValidation/validatableComponent.mjs";import{useFormValidatorGroup as ar}from"./services/formValidation/useFormValidatorGroup.mjs";import{FormValidator as or,Validators as sr,useFormValidator as cr}from"./services/formValidation/index.mjs";import{hasEightPasswordChars as lr,hasOnePasswordDigit as ur,hasOnePasswordLetter as dr,isBic as fr,isDate as pr,isDay as mr,isEmail as hr,isISODate as gr,isNumber as _r,isPassword as vr,isURL as yr}from"@ahrowe/form-validation";export{o as Accordion,e as AccordionStyleType,p as ActionButtons,h as ActionIcon,T as AhroweProvider,D as Alert,E as AlertStyleType,O as AnimatedLogo,j as AnimatedText,k as AnimatedTextUnit,A as AnimatedTextVariant,F as Avatar,I as AvatarGroup,P as Badge,M as BadgePosition,N as BadgeStyleType,b as BodyEnd,W as Breadcrumb,f as Button,K as ButtonGroup,G as ButtonGroupOrientation,c as ButtonSize,l as ButtonStyleType,u as ButtonType,$ as Calendar,Z as CalendarView,te as Card,ae as CardActions,ie as CardContent,ne as CardHeader,re as CardMedia,ee as CardStyleType,oe as Carousel,se as Checkbox,le as Chip,ue as ChipContainer,ce as ChipStyleType,he as ColorPicker,Ce as CommandPalette,t as ConfigProvider,we as ConfirmModal,Ee as CopyButton,Ut as DEFAULT_SNAP_OPTIONS,Xe as DEFAULT_WALL_ATTRS,je as DatePicker,Pe as Divider,Me as DividerOrientation,Ne as DividerTextPosition,Ue as DoorSwing,Fe as Drawer,Re as DropZone,Ie as DropZoneReturnType,Le as DropZoneStatus,Ae as Dropdown,ze as EmptyState,Be as ErrorBoundary,Ve as Fab,He as Flip,or as FormValidator,rr as FormValidatorGroup,Rt as HIT_PX,zt as HIT_PX_COARSE,$t as IconPicker,en as IdleManager,me as Input,tn as InputDropdown,fe as InputIconPosition,pe as InputType,m as InteractableDiv,rn as KanbanBoard,nn as KanbanColumn,on as KlipyPicker,mt as MIN_FLOOR_HEIGHT,Je as MIN_OPENING_WIDTH,Ye as MIN_WALL_LENGTH,sn as Menu,_e as Modal,ln as MultiSelect,un as NumberInput,We as OpeningKind,Q as OptionPicker,fn as OtpInput,dn as OtpInputCharset,pn as Overscroll,Jt as PLAN_FORMAT_VERSION,mn as Pagination,Ge as PlanIssueKind,Ke as PlanUnitSystem,U as Popover,L as PopoverAlign,R as PopoverPlacement,z as PopoverTrigger,a as Presentation,hn as ProgressBar,_n as RadioGroup,gn as RadioGroupOrientation,vn as Rating,yn as RevealLens,d as Ripple,bn as RoomDrawer,xn as RoomViewer,Cn as ScrollFade,Sn as ScrollFadeAxis,g as ScrollbarProvider,an as SearchInput,Tn as SectionHeader,wn as SectionHeaderSize,On as Skeleton,En as SkeletonAnimation,Dn as SkeletonVariant,kn as Slider,Wt as SnapKind,s as SpinnerLoading,An as SplitButton,Fn as Stepper,jn as StepperAlignment,Mn as StepperCollapse,Nn as StepperLabelPlacement,Pn as StepperStyleType,In as Sticky,Ln as Switch,Rn as TabHeader,zn as Textarea,v as ThemeProvider,Gn as Tilt,Vn as TiltGroup,Hn as TiltGroupContext,Kn as TimeInput,Yn as Timeline,qn as TimelineAlignment,Jn as TimelineItemStatus,Xn as Timer,de as Tooltip,$n as Tree,ir as ValidatableComponent,sr as Validators,Zn as VirtualList,qe as WallType,tr as WeatherIcon,er as WeatherType,nr as Wizard,ht as addFloor,Ze as addOpening,Qe as addRect,$e as addWall,Zt as buildPlanMesh,Ft as buildWallPaths,et as cleanupPlan,Gt as clientToWorld,jt as commitDerivation,q as dateToDay,J as dateToTime,Y as dayTimeToDate,X as dayToDate,_ as defaultTheme,Wn as defaultTiltEasing,kt as deriveFaces,Mt as derivePlan,tt as detachWall,nt as dissolveNode,gt as duplicateFloor,_t as emptyFloor,vt as emptyFloorPlan,Qn as flattenTree,yt as floorBelow,bt as floorBounds,xt as floorIndex,ye as formatHotkey,St as getFloor,De as getLocale,lr as hasEightPasswordChars,ur as hasOnePasswordDigit,dr as hasOnePasswordLetter,Bt as hitTest,fr as isBic,pr as isDate,mr as isDay,hr as isEmail,gr as isISODate,be as isMenuAction,xe as isMenuHeading,Se as isMenuSeparator,_r as isNumber,vr as isPassword,yr as isURL,y as lightTheme,Oe as mapLocale,cn as menuHotkeys,rt as mergeNodes,Ct as moveFloor,it as moveNode,At as nodeDegrees,It as openingGeometry,Yt as planFromJson,Qt as planFromLegacySvg,Xt as planToJson,Nt as pruneUnmatchedRooms,wt as removeFloor,at as removeOpening,ot as removeWall,Tt as renameFloor,Kt as resolveSnap,Pt as roomAtPoint,st as scalePlan,qt as screenScale,Vt as selectionsEqual,Et as setFloor,Dt as setFloorHeight,ke as setLocale,w as showToast,ct as splitWall,B as tabbablesIn,lt as transformPlan,Ot as updateFloor,ut as updateOpening,Te as useClipboard,S as useCoarsePointer,n as useComponentDefaults,cr as useFormValidator,ar as useFormValidatorGroup,ve as useHotkeys,r as useLabels,x as useMediaQuery,H as useOverlay,i as usePresentationDefault,ge as useScrollEdges,C as useSwipeDismiss,Bn as useTheme,Un as useTiltGroup,V as useVisualViewportSize,dt as validatePlan,Lt as wallCentrelineSpans,ft as wallLength,pt as weldShortWalls,Ht as worldTolerances};
|
|
1
|
+
"use client";import{AccordionStyleType as e}from"./common/accordion/accordion.types.mjs";import t from"./common/configProvider/configProvider.mjs";import{useComponentDefaults as n}from"./common/configProvider/useComponentDefaults.mjs";import{useLabels as r}from"./common/configProvider/useLabels.mjs";import{usePresentationDefault as i}from"./common/configProvider/usePresentationDefault.mjs";import{Presentation as a}from"./common/configProvider/presentation.types.mjs";import o from"./common/accordion/accordion.mjs";import s from"./common/loading/spinnerLoading/index.mjs";import{ButtonSize as c,ButtonStyleType as l,ButtonType as u}from"./common/button/button.types.mjs";import d from"./common/ripple/ripple.mjs";import f from"./common/button/button.mjs";import p from"./common/actionButtons/actionButtons.mjs";import m from"./common/interactableDiv/index.mjs";import h from"./common/actionIcon/actionIcon.mjs";import g from"./common/scrollbarProvider/index.mjs";import{defaultTheme as _}from"./common/themeProvider/defaultTheme.mjs";import v from"./common/themeProvider/themeProvider.mjs";import{lightTheme as y}from"./common/themeProvider/lightTheme.mjs";import b from"./common/bodyEnd/bodyEnd.mjs";import x from"./common/hooks/useMediaQuery.mjs";import S from"./common/hooks/useCoarsePointer.mjs";import{useSwipeDismiss as C}from"./common/hooks/useSwipeDismiss.mjs";import{showToast as w}from"./common/toast/toastService.mjs";import T from"./common/ahroweProvider/ahroweProvider.mjs";import{AlertStyleType as E}from"./common/alert/alert.types.mjs";import D from"./common/alert/alert.mjs";import O from"./common/animatedLogo/animatedLogo.mjs";import{AnimatedTextUnit as k,AnimatedTextVariant as A}from"./common/animatedText/animatedText.types.mjs";import j from"./common/animatedText/animatedText.mjs";import{BadgePosition as M,BadgeStyleType as N}from"./common/badge/badge.types.mjs";import P from"./common/badge/badge.mjs";import F from"./common/avatar/avatar.mjs";import I from"./common/avatar/avatarGroup.mjs";import{PopoverAlign as L,PopoverPlacement as R,PopoverTrigger as z}from"./common/popover/popover.types.mjs";import{tabbablesIn as B}from"./common/hooks/useFocusBoundary.mjs";import{useVisualViewportSize as V}from"./common/hooks/useVisualViewportSize.mjs";import{useOverlay as H}from"./common/hooks/useOverlay.mjs";import U from"./common/popover/popover.mjs";import W from"./common/breadcrumb/breadcrumb.mjs";import{ButtonGroupOrientation as G}from"./common/buttonGroup/buttonGroup.types.mjs";import K from"./common/buttonGroup/buttonGroup.mjs";import{dateToDay as q,dateToTime as J,dayTimeToDate as Y,dayToDate as X}from"./common/utils/day.mjs";import{CalendarView as Z}from"./common/calendar/calendar.types.mjs";import Q from"./common/optionPicker/optionPicker.mjs";import $ from"./common/calendar/calendar.mjs";import{CardStyleType as ee}from"./common/card/card.types.mjs";import te from"./common/card/Card.mjs";import ne from"./common/card/CardHeader.mjs";import re from"./common/card/CardMedia.mjs";import ie from"./common/card/CardContent.mjs";import ae from"./common/card/CardActions.mjs";import oe from"./common/carousel/carousel.mjs";import se from"./common/checkbox/checkbox.mjs";import{ChipStyleType as ce}from"./common/chip/chip.types.mjs";import le from"./common/chip/chip.mjs";import ue from"./common/chip/chipContainer.mjs";import de from"./common/tooltip/tooltip.mjs";import{InputIconPosition as fe,InputType as pe}from"./common/input/input.types.mjs";import me from"./common/input/input.mjs";import he from"./common/colorPicker/colorPicker.mjs";import{useScrollEdges as ge}from"./common/hooks/useScrollEdges.mjs";import _e from"./common/modal/modal.mjs";import ve,{formatHotkey as ye}from"./common/hooks/useHotkeys.mjs";import{isMenuAction as be,isMenuHeading as xe,isMenuSeparator as Se}from"./common/menu/menu.types.mjs";import Ce from"./common/commandPalette/commandPalette.mjs";import we from"./common/confirmModal/confirmModal.mjs";import Te from"./common/hooks/useClipboard.mjs";import Ee from"./common/copyButton/copyButton.mjs";import{getLocale as De,mapLocale as Oe,setLocale as ke}from"./services/localization.mjs";import Ae from"./common/dropdown/dropdown.mjs";import je from"./common/datePicker/datePicker.mjs";import{DividerOrientation as Me,DividerTextPosition as Ne}from"./common/divider/divider.types.mjs";import Pe from"./common/divider/divider.mjs";import Fe from"./common/drawer/drawer.mjs";import{DropZoneReturnType as Ie,DropZoneStatus as Le}from"./common/dropZone/dropZone.types.mjs";import Re from"./common/dropZone/dropZone.mjs";import ze from"./common/emptyState/emptyState.mjs";import Be from"./common/errorBoundary/errorBoundary.mjs";import Ve from"./common/fab/fab.mjs";import He from"./common/flip/flip.mjs";import{DoorSwing as Ue,OpeningKind as We,PlanIssueKind as Ge,PlanUnitSystem as Ke,WallType as qe}from"./common/floorPlan/floorPlan.types.mjs";import{MIN_OPENING_WIDTH as Je,MIN_WALL_LENGTH as Ye}from"./common/floorPlan/floorPlan.geometry.mjs";import{DEFAULT_WALL_ATTRS as Xe,addOpening as Ze,addRect as Qe,addWall as $e,cleanupPlan as et,detachWall as tt,dissolveNode as nt,mergeNodes as rt,moveNode as it,removeOpening as at,removeWall as ot,scalePlan as st,splitWall as ct,transformPlan as lt,updateOpening as ut,validatePlan as dt,wallLength as ft,weldShortWalls as pt}from"./common/floorPlan/floorPlan.graph.mjs";import{MIN_FLOOR_HEIGHT as mt,addFloor as ht,duplicateFloor as gt,emptyFloor as _t,emptyFloorPlan as vt,floorBelow as yt,floorBounds as bt,floorIndex as xt,getFloor as St,moveFloor as Ct,removeFloor as wt,renameFloor as Tt,setFloor as Et,setFloorHeight as Dt,updateFloor as Ot}from"./common/floorPlan/floorPlan.plan.mjs";import{deriveFaces as kt,nodeDegrees as At}from"./common/floorPlan/floorPlan.faces.mjs";import{commitDerivation as jt,derivePlan as Mt,pruneUnmatchedRooms as Nt,roomAtPoint as Pt}from"./common/floorPlan/floorPlan.rooms.mjs";import{buildWallPaths as Ft,openingGeometry as It,wallCentrelineSpans as Lt}from"./common/floorPlan/floorPlan.path.mjs";import{HIT_PX as Rt,HIT_PX_COARSE as zt,hitTest as Bt,selectionsEqual as Vt,worldTolerances as Ht}from"./common/floorPlan/floorPlan.hit.mjs";import{DEFAULT_SNAP_OPTIONS as Ut,SnapKind as Wt,clientToWorld as Gt,resolveSnap as Kt}from"./common/floorPlan/floorPlan.snap.mjs";import{PLAN_FORMAT_VERSION as qt,planFromJson as Jt,planToJson as Yt}from"./common/floorPlan/floorPlan.json.mjs";import{buildPlanMesh as Xt}from"./common/floorPlan/floorPlan.mesh.mjs";import Zt from"./common/iconPicker/iconPicker.mjs";import Qt from"./common/idleManager/idleManager.mjs";import $t from"./common/inputDropdown/inputDropdown.mjs";import en from"./common/kanbanBoard/KanbanColumn.mjs";import tn from"./common/kanbanBoard/KanbanBoard.mjs";import nn from"./common/searchInput/searchInput.mjs";import rn from"./common/klipyPicker/klipyPicker.mjs";import an from"./common/menu/menu.mjs";import{menuHotkeys as on}from"./common/menu/menuHotkeys.mjs";import sn from"./common/multiSelect/multiSelect.mjs";import cn from"./common/numberInput/index.mjs";import{OtpInputCharset as ln}from"./common/otpInput/otpInput.types.mjs";import un from"./common/otpInput/otpInput.mjs";import dn from"./common/overscroll/overscroll.mjs";import fn from"./common/pagination/pagination.mjs";import pn from"./common/progressBar/progressBar.mjs";import{RadioGroupOrientation as mn}from"./common/radioGroup/radioGroup.types.mjs";import hn from"./common/radioGroup/radioGroup.mjs";import gn from"./common/rating/rating.mjs";import _n from"./common/revealLens/revealLens.mjs";import vn from"./common/roomDrawer/roomDrawer.mjs";import yn from"./common/roomViewer/roomViewer.mjs";import{ScrollFadeAxis as bn}from"./common/scrollFade/scrollFade.types.mjs";import xn from"./common/scrollFade/scrollFade.mjs";import{SectionHeaderSize as Sn}from"./common/sectionHeader/sectionHeader.types.mjs";import Cn from"./common/sectionHeader/sectionHeader.mjs";import{SkeletonAnimation as wn,SkeletonVariant as Tn}from"./common/skeleton/skeleton.types.mjs";import En from"./common/skeleton/skeleton.mjs";import Dn from"./common/slider/slider.mjs";import On from"./common/splitButton/splitButton.mjs";import{StepperAlignment as kn,StepperCollapse as An,StepperLabelPlacement as jn,StepperStyleType as Mn}from"./common/stepper/stepper.types.mjs";import Nn from"./common/stepper/stepper.mjs";import Pn from"./common/sticky/sticky.mjs";import Fn from"./common/switch/switch.mjs";import In from"./common/tabHeader/tabHeader.mjs";import Ln from"./common/textarea/textarea.mjs";import{useTheme as Rn}from"./common/themeProvider/useTheme.mjs";import zn,{TiltGroupContext as Bn,useTiltGroup as Vn}from"./common/tiltGroup/tiltGroup.mjs";import{defaultTiltEasing as Hn}from"./common/tilt/tiltMath.mjs";import Un from"./common/tilt/tilt.mjs";import Wn from"./common/timeInput/timeInput.mjs";import{TimelineAlignment as Gn,TimelineItemStatus as Kn}from"./common/timeline/timeline.types.mjs";import qn from"./common/timeline/timeline.mjs";import Jn from"./common/timer/timer.mjs";import Yn from"./common/virtualList/virtualList.mjs";import{flattenTree as Xn}from"./common/tree/flattenTree.mjs";import Zn from"./common/tree/tree.mjs";import{WeatherType as Qn}from"./common/weatherIcon/weatherIcon.types.mjs";import $n from"./common/weatherIcon/weatherIcon.mjs";import er from"./common/wizard/wizard.mjs";import tr from"./services/formValidation/FormValidatorGroupWithForm.mjs";import nr from"./services/formValidation/validatableComponent.mjs";import{useFormValidatorGroup as rr}from"./services/formValidation/useFormValidatorGroup.mjs";import{FormValidator as ir,Validators as ar,useFormValidator as or}from"./services/formValidation/index.mjs";import{hasEightPasswordChars as sr,hasOnePasswordDigit as cr,hasOnePasswordLetter as lr,isBic as ur,isDate as dr,isDay as fr,isEmail as pr,isISODate as mr,isNumber as hr,isPassword as gr,isURL as _r}from"@ahrowe/form-validation";export{o as Accordion,e as AccordionStyleType,p as ActionButtons,h as ActionIcon,T as AhroweProvider,D as Alert,E as AlertStyleType,O as AnimatedLogo,j as AnimatedText,k as AnimatedTextUnit,A as AnimatedTextVariant,F as Avatar,I as AvatarGroup,P as Badge,M as BadgePosition,N as BadgeStyleType,b as BodyEnd,W as Breadcrumb,f as Button,K as ButtonGroup,G as ButtonGroupOrientation,c as ButtonSize,l as ButtonStyleType,u as ButtonType,$ as Calendar,Z as CalendarView,te as Card,ae as CardActions,ie as CardContent,ne as CardHeader,re as CardMedia,ee as CardStyleType,oe as Carousel,se as Checkbox,le as Chip,ue as ChipContainer,ce as ChipStyleType,he as ColorPicker,Ce as CommandPalette,t as ConfigProvider,we as ConfirmModal,Ee as CopyButton,Ut as DEFAULT_SNAP_OPTIONS,Xe as DEFAULT_WALL_ATTRS,je as DatePicker,Pe as Divider,Me as DividerOrientation,Ne as DividerTextPosition,Ue as DoorSwing,Fe as Drawer,Re as DropZone,Ie as DropZoneReturnType,Le as DropZoneStatus,Ae as Dropdown,ze as EmptyState,Be as ErrorBoundary,Ve as Fab,He as Flip,ir as FormValidator,tr as FormValidatorGroup,Rt as HIT_PX,zt as HIT_PX_COARSE,Zt as IconPicker,Qt as IdleManager,me as Input,$t as InputDropdown,fe as InputIconPosition,pe as InputType,m as InteractableDiv,tn as KanbanBoard,en as KanbanColumn,rn as KlipyPicker,mt as MIN_FLOOR_HEIGHT,Je as MIN_OPENING_WIDTH,Ye as MIN_WALL_LENGTH,an as Menu,_e as Modal,sn as MultiSelect,cn as NumberInput,We as OpeningKind,Q as OptionPicker,un as OtpInput,ln as OtpInputCharset,dn as Overscroll,qt as PLAN_FORMAT_VERSION,fn as Pagination,Ge as PlanIssueKind,Ke as PlanUnitSystem,U as Popover,L as PopoverAlign,R as PopoverPlacement,z as PopoverTrigger,a as Presentation,pn as ProgressBar,hn as RadioGroup,mn as RadioGroupOrientation,gn as Rating,_n as RevealLens,d as Ripple,vn as RoomDrawer,yn as RoomViewer,xn as ScrollFade,bn as ScrollFadeAxis,g as ScrollbarProvider,nn as SearchInput,Cn as SectionHeader,Sn as SectionHeaderSize,En as Skeleton,wn as SkeletonAnimation,Tn as SkeletonVariant,Dn as Slider,Wt as SnapKind,s as SpinnerLoading,On as SplitButton,Nn as Stepper,kn as StepperAlignment,An as StepperCollapse,jn as StepperLabelPlacement,Mn as StepperStyleType,Pn as Sticky,Fn as Switch,In as TabHeader,Ln as Textarea,v as ThemeProvider,Un as Tilt,zn as TiltGroup,Bn as TiltGroupContext,Wn as TimeInput,qn as Timeline,Gn as TimelineAlignment,Kn as TimelineItemStatus,Jn as Timer,de as Tooltip,Zn as Tree,nr as ValidatableComponent,ar as Validators,Yn as VirtualList,qe as WallType,$n as WeatherIcon,Qn as WeatherType,er as Wizard,ht as addFloor,Ze as addOpening,Qe as addRect,$e as addWall,Xt as buildPlanMesh,Ft as buildWallPaths,et as cleanupPlan,Gt as clientToWorld,jt as commitDerivation,q as dateToDay,J as dateToTime,Y as dayTimeToDate,X as dayToDate,_ as defaultTheme,Hn as defaultTiltEasing,kt as deriveFaces,Mt as derivePlan,tt as detachWall,nt as dissolveNode,gt as duplicateFloor,_t as emptyFloor,vt as emptyFloorPlan,Xn as flattenTree,yt as floorBelow,bt as floorBounds,xt as floorIndex,ye as formatHotkey,St as getFloor,De as getLocale,sr as hasEightPasswordChars,cr as hasOnePasswordDigit,lr as hasOnePasswordLetter,Bt as hitTest,ur as isBic,dr as isDate,fr as isDay,pr as isEmail,mr as isISODate,be as isMenuAction,xe as isMenuHeading,Se as isMenuSeparator,hr as isNumber,gr as isPassword,_r as isURL,y as lightTheme,Oe as mapLocale,on as menuHotkeys,rt as mergeNodes,Ct as moveFloor,it as moveNode,At as nodeDegrees,It as openingGeometry,Jt as planFromJson,Yt as planToJson,Nt as pruneUnmatchedRooms,wt as removeFloor,at as removeOpening,ot as removeWall,Tt as renameFloor,Kt as resolveSnap,Pt as roomAtPoint,st as scalePlan,Vt as selectionsEqual,Et as setFloor,Dt as setFloorHeight,ke as setLocale,w as showToast,ct as splitWall,B as tabbablesIn,lt as transformPlan,Ot as updateFloor,ut as updateOpening,Te as useClipboard,S as useCoarsePointer,n as useComponentDefaults,or as useFormValidator,rr as useFormValidatorGroup,ve as useHotkeys,r as useLabels,x as useMediaQuery,H as useOverlay,i as usePresentationDefault,ge as useScrollEdges,C as useSwipeDismiss,Rn as useTheme,Vn as useTiltGroup,V as useVisualViewportSize,dt as validatePlan,Lt as wallCentrelineSpans,ft as wallLength,pt as weldShortWalls,Ht as worldTolerances};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./floorPlan-DLe5XAx6.cjs");exports.DEFAULT_SNAP_OPTIONS=e.a,exports.DEFAULT_WALL_ATTRS=e.R,exports.DoorSwing=e.at,exports.HIT_PX=e.l,exports.HIT_PX_COARSE=e.u,exports.MIN_FLOOR_HEIGHT=e.C,exports.MIN_OPENING_WIDTH=e.nt,exports.MIN_WALL_LENGTH=e.rt,exports.OpeningKind=e.ot,exports.PLAN_FORMAT_VERSION=e.n,exports.PlanIssueKind=e.st,exports.PlanUnitSystem=e.ct,exports.SnapKind=e.o,exports.WallType=e.lt,exports.addFloor=e.w,exports.addOpening=e.z,exports.addRect=e.B,exports.addWall=e.V,exports.buildPlanMesh=e.t,exports.buildWallPaths=e.m,exports.cleanupPlan=e.H,exports.clientToWorld=e.s,exports.commitDerivation=e._,exports.deriveFaces=e.x,exports.derivePlan=e.v,exports.detachWall=e.U,exports.dissolveNode=e.W,exports.duplicateFloor=e.T,exports.emptyFloor=e.E,exports.emptyFloorPlan=e.D,exports.floorBelow=e.O,exports.floorBounds=e.k,exports.floorIndex=e.A,exports.getFloor=e.j,exports.hitTest=e.d,exports.mergeNodes=e.G,exports.moveFloor=e.M,exports.moveNode=e.K,exports.nodeDegrees=e.S,exports.openingGeometry=e.h,exports.planFromJson=e.r,exports.planToJson=e.i,exports.pruneUnmatchedRooms=e.y,exports.removeFloor=e.N,exports.removeOpening=e.q,exports.removeWall=e.J,exports.renameFloor=e.P,exports.resolveSnap=e.c,exports.roomAtPoint=e.b,exports.scalePlan=e.Y,exports.selectionsEqual=e.f,exports.setFloor=e.F,exports.setFloorHeight=e.I,exports.splitWall=e.X,exports.transformPlan=e.Z,exports.updateFloor=e.L,exports.updateOpening=e.Q,exports.validatePlan=e.$,exports.wallCentrelineSpans=e.g,exports.wallLength=e.et,exports.weldShortWalls=e.tt,exports.worldTolerances=e.p;
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
var e=function(e){return e.Metric=`metric`,e.Imperial=`imperial`,e}({}),t=function(e){return e.Exterior=`exterior`,e.Interior=`interior`,e.Partition=`partition`,e.Virtual=`virtual`,e}({}),n=function(e){return e.Door=`door`,e.Window=`window`,e.Archway=`archway`,e.Gap=`gap`,e}({}),r=function(e){return e.None=`none`,e.StartLeft=`startLeft`,e.StartRight=`startRight`,e.EndLeft=`endLeft`,e.EndRight=`endRight`,e.Double=`double`,e.Sliding=`sliding`,e}({}),i=function(e){return e.ZeroLengthWall=`zeroLengthWall`,e.SelfLoopWall=`selfLoopWall`,e.DuplicateWall=`duplicateWall`,e.CoincidentNodes=`coincidentNodes`,e.UnsplitCrossing=`unsplitCrossing`,e.UnsplitNodeOnWall=`unsplitNodeOnWall`,e.OverlappingWalls=`overlappingWalls`,e.OrphanNode=`orphanNode`,e.DanglingOpening=`danglingOpening`,e.UnmatchedRoom=`unmatchedRoom`,e.OpeningDropped=`openingDropped`,e}({}),a=10,o=100;function s(e,t){return Math.hypot(e.x-t.x,e.y-t.y)}function c(e,t,n){return(t.x-e.x)*(n.y-e.y)-(t.y-e.y)*(n.x-e.x)}function l(e,t,n){let r=n.x-t.x,i=n.y-t.y,a=r*r+i*i;if(a===0)return{dist:s(e,t),t:0,point:{x:t.x,y:t.y}};let o=((e.x-t.x)*r+(e.y-t.y)*i)/a,c=o<0?0:o>1?1:o,l={x:t.x+c*r,y:t.y+c*i};return{dist:s(e,l),t:c,point:l}}function u(e,t,n){return l(e,t,n).point}function d(e,t,n,r,i=1){let a=s(e,t),o=s(n,r);if(a<1e-9||o<1e-9)return{kind:`none`};let l=t.x-e.x,u=t.y-e.y,d=r.x-n.x,f=r.y-n.y,p=l*f-u*d,m=Math.abs(c(e,t,n))/a,h=Math.abs(c(e,t,r))/a;if(Math.abs(p)<1e-12||m<i&&h<i){if(m>=i||h>=i)return{kind:`none`};let t=l*l+u*u,o=((n.x-e.x)*l+(n.y-e.y)*u)/t,s=((r.x-e.x)*l+(r.y-e.y)*u)/t,c=Math.min(o,s),d=Math.max(o,s),f=i/a;return d<f||c>1-f||Math.min(d,1)-Math.max(c,0)<f?{kind:`collinearDisjoint`}:{kind:`collinearOverlap`}}let g=((n.x-e.x)*f-(n.y-e.y)*d)/p,_=((n.x-e.x)*u-(n.y-e.y)*l)/p,v=i/a,y=i/o;if(g<-v||g>1+v||_<-y||_>1+y)return{kind:`none`};let b={x:e.x+g*l,y:e.y+g*u},x=g<=v||g>=1-v,S=_<=y||_>=1-y;return x||S?{kind:`touch`,t:g,s:_,point:b}:{kind:`proper`,t:g,s:_,point:b}}function f(e){let t=e.length;if(t<3)return 0;let n=0;for(let r=0,i=t-1;r<t;i=r++)n+=e[i].x*e[r].y-e[r].x*e[i].y;return n/2}function p(e){let t=e.length;if(t<2)return 0;let n=0;for(let r=0,i=t-1;r<t;i=r++)n+=s(e[i],e[r]);return n}function m(e){let t=e.length;if(t===0)return{x:0,y:0};if(t<3)return{x:e.reduce((e,t)=>e+t.x,0)/t,y:e.reduce((e,t)=>e+t.y,0)/t};let n=0,r=0,i=0;for(let a=0,o=t-1;a<t;o=a++){let t=e[o].x*e[a].y-e[a].x*e[o].y;n+=t,r+=(e[o].x+e[a].x)*t,i+=(e[o].y+e[a].y)*t}return Math.abs(n)<1e-9?{x:e.reduce((e,t)=>e+t.x,0)/t,y:e.reduce((e,t)=>e+t.y,0)/t}:{x:r/(3*n),y:i/(3*n)}}function h(e,t){let n=!1;for(let r=0,i=t.length-1;r<t.length;i=r++){let a=t[r].x,o=t[r].y,s=t[i].x,c=t[i].y;o>e.y!=c>e.y&&e.x<(s-a)*(e.y-o)/(c-o)+a&&(n=!n)}return n}function g(e,t,n=[]){if(!h(e,t))return!1;for(let t of n)if(h(e,t))return!1;return!0}function _(e,t=[]){if(e.length===0)return{x:0,y:0};let n=m(e);if(g(n,e,t))return n;let r=1/0,i=-1/0;for(let t of e)t.y<r&&(r=t.y),t.y>i&&(i=t.y);if(!Number.isFinite(r)||i-r<1e-9)return n;let a=[e,...t],o=null;for(let e=1;e<=7;e++){let t=r+(i-r)*e/8,n=[];for(let e of a)for(let r=0,i=e.length-1;r<e.length;i=r++){let a=e[i],o=e[r];a.y>t!=o.y>t&&n.push(a.x+(t-a.y)*(o.x-a.x)/(o.y-a.y))}n.sort((e,t)=>e-t);for(let e=0;e+1<n.length;e+=2){let r=n[e+1]-n[e];r>2&&(!o||r>o.width)&&(o={point:{x:(n[e]+n[e+1])/2,y:t},width:r})}}return o?o.point:n}function v(e){let t=e.slice(),n=!0;for(;n&&t.length>3;){n=!1;let e=[],r=t.length;for(let i=0;i<r;i++){let a=t[(i-1+r)%r],o=t[(i+1)%r];if(s(a,o)<1){n=!0;continue}e.push(t[i])}n&&(t=e.filter((t,n)=>s(t,e[(n+1)%e.length])>=1))}return t}function y(e){if(e.length===0)return null;let t=1/0,n=1/0,r=-1/0,i=-1/0;for(let a of e)a.x<t&&(t=a.x),a.y<n&&(n=a.y),a.x>r&&(r=a.x),a.y>i&&(i=a.y);return{minX:t,minY:n,maxX:r,maxY:i}}var b=0;function x(e){return b+=1,`${e}_${typeof crypto<`u`&&typeof crypto.randomUUID==`function`?crypto.randomUUID().slice(0,8):Math.random().toString(36).slice(2,10)}${b.toString(36)}`}function S(e,t,n){let r=e(t);for(let i=t+1;n.has(r)&&i<=t+n.size;i++)r=e(i);return r}function C(e){return{...e,nodes:{...e.nodes},walls:{...e.walls},openings:{...e.openings},rooms:{...e.rooms}}}function w(e,t,n={}){return{kind:e,message:t,...n}}function T(e,t){let n=e.nodes[t.a],r=e.nodes[t.b];return!n||!r?0:s(n,r)}function E(e,t){return Object.values(e.walls).filter(e=>e.a===t||e.b===t)}function D(e,t,n){for(let r of Object.values(e.walls))if(r.a===t&&r.b===n||r.a===n&&r.b===t)return r;return null}var O=250;function ee(e,t){return`${Math.round(e/O)}|${Math.round(t/O)}`}function te(e){let t=new Map;for(let n of Object.values(e.nodes)){let e=ee(n.x,n.y),r=t.get(e);r?r.push(n):t.set(e,[n])}return t}function ne(e,t,n){let r=te(e),i=Math.round(t.x/O),a=Math.round(t.y/O),o=null,c=n,l=Math.max(1,Math.ceil(n/O));for(let e=-l;e<=l;e++)for(let n=-l;n<=l;n++)for(let l of r.get(`${i+e}|${a+n}`)??[]){let e=s(t,l);e<=c&&(o=l,c=e)}return o}function re(e,t,n,r){let i=null;for(let a of Object.values(e.walls)){if(r?.has(a.id))continue;let o=e.nodes[a.a],s=e.nodes[a.b];if(!o||!s)continue;let c=l(t,o,s);c.dist<=n&&(!i||c.dist<i.dist)&&(i={wall:a,t:c.t,point:c.point,dist:c.dist})}return i}function k(e,t,n){let r=e.walls[t];if(!r)return{floor:e,result:{nodeId:``,wallIds:null,droppedOpeningIds:[]},issues:[]};let a=e.nodes[r.a],o=e.nodes[r.b];if(!a||!o)return{floor:e,result:{nodeId:``,wallIds:null,droppedOpeningIds:[]},issues:[]};let c=s(a,o),l=u(typeof n==`number`?{x:a.x+(o.x-a.x)*n,y:a.y+(o.y-a.y)*n}:n,a,o),d=s(a,l);if(d<10)return{floor:e,result:{nodeId:r.a,wallIds:null,droppedOpeningIds:[]},issues:[]};if(c-d<10)return{floor:e,result:{nodeId:r.b,wallIds:null,droppedOpeningIds:[]},issues:[]};let f=C(e),p=x(`n`);f.nodes[p]={id:p,x:l.x,y:l.y};let m=x(`w`),h=x(`w`),g={thickness:r.thickness,type:r.type,height:r.height,baseHeight:r.baseHeight};f.walls[m]={...g,id:m,a:r.a,b:p},f.walls[h]={...g,id:h,a:p,b:r.b},delete f.walls[t];let _=[],v=[];for(let n of Object.values(e.openings)){if(n.wallId!==t)continue;let e=n.offset<=d,r=e?m:h,a=e?d:c-d,o=e?n.offset:n.offset-d,s=Math.min(n.width,a-2,o*2,(a-o)*2);if(s<100){delete f.openings[n.id],_.push(n.id),v.push(w(i.OpeningDropped,`An opening was removed: the wall it sat on became too short for it.`,{openingIds:[n.id],wallIds:[t]}));continue}f.openings[n.id]={...n,wallId:r,offset:o,width:s}}return{floor:f,result:{nodeId:p,wallIds:[m,h],droppedOpeningIds:_},issues:v}}function A(e,t,n){let r=ne(e,t,n);if(r)return{floor:e,result:{nodeId:r.id,createdNode:!1,splitWallId:null},issues:[]};let i=re(e,t,n);if(i){let t=k(e,i.wall.id,i.point);if(t.result.nodeId)return{floor:t.floor,result:{nodeId:t.result.nodeId,createdNode:t.result.wallIds!==null,splitWallId:t.result.wallIds?i.wall.id:null},issues:t.issues}}let a=C(e),o=x(`n`);return a.nodes[o]={id:o,x:t.x,y:t.y},{floor:a,result:{nodeId:o,createdNode:!0,splitWallId:null},issues:[]}}var j={thickness:200,type:t.Interior};function ie(e,t,n,r=j,a=1){let o=[];if(s(t,n)<10)return{floor:e,result:{wallIds:[],nodeIds:[]},issues:o};let c=A(e,t,a),u=c.floor;o.push(...c.issues);let f=A(u,n,a);u=f.floor,o.push(...f.issues);let p=c.result.nodeId,m=f.result.nodeId;if(p===m)return{floor:e,result:{wallIds:[],nodeIds:[]},issues:o};let h=u.nodes[p],g=u.nodes[m],_=s(h,g);if(_<10)return{floor:e,result:{wallIds:[],nodeIds:[]},issues:o};let v=[{t:0,nodeId:p},{t:1,nodeId:m}],y=new Map,b=[],S=e=>l(e,h,g).t;for(let e of Object.values(u.walls)){let t=u.nodes[e.a],n=u.nodes[e.b];if(!t||!n)continue;let r=d(h,g,t,n,a);if(r.kind===`collinearOverlap`){let e=S(t),r=S(n);b.push([Math.min(e,r),Math.max(e,r)]);for(let[i,a]of[[t,e],[n,r]])a*_>10&&(1-a)*_>10&&v.push({t:a,nodeId:i.id});continue}if(r.kind===`proper`&&r.t!==void 0&&r.s!==void 0){let t=y.get(e.id);t?t.push(r.s):y.set(e.id,[r.s]),v.push({t:r.t,nodeId:null,pending:{wallId:e.id,s:r.s}});continue}if(r.kind===`touch`&&r.t!==void 0&&r.s!==void 0){let e=r.s<=.5?t:n,i=S(e);l(e,h,g).dist<=a&&i*_>10&&(1-i)*_>10&&v.push({t:i,nodeId:e.id})}}for(let e of Object.values(u.nodes)){if(e.id===p||e.id===m)continue;let t=l(e,h,g);t.dist>a||t.t*_<=10||(1-t.t)*_<=10||v.push({t:t.t,nodeId:e.id})}for(let[t,n]of y){let r=[...n].sort((e,t)=>t-e),i=t,a=new Set(r);for(let n of r){let r=u.walls[i];if(!r)break;let s=u.nodes[r.a],c=u.nodes[r.b];if(!s||!c)break;let l=e.walls[t],d=u.nodes[l?.a??r.a]??s,f=u.nodes[l?.b??r.b]??c,p={x:d.x+(f.x-d.x)*n,y:d.y+(f.y-d.y)*n},m=k(u,i,p);u=m.floor,o.push(...m.issues),a.delete(n);for(let e of v)e.pending&&e.pending.wallId===t&&e.pending.s===n&&(e.nodeId=m.result.nodeId,e.pending=void 0);if(m.result.wallIds){let[e,t]=m.result.wallIds,r=Math.max(...a,-1);i=r>=0&&r>n?t:e}}}let C=v.filter(e=>!!e.nodeId);C.sort((e,t)=>e.t-t.t);let T=[];for(let e of C){let t=T[T.length-1];if(!t){T.push(e);continue}if(t.nodeId!==e.nodeId){if((e.t-t.t)*_<10){e.t>=1-1e-9&&(T[T.length-1]=e);continue}T.push(e)}}let E=[];for(let e=0;e+1<T.length;e++){let t=T[e],n=T[e+1],i=(t.t+n.t)/2;if(b.some(([e,t])=>i>e+1e-9&&i<t-1e-9)||D(u,t.nodeId,n.nodeId))continue;let a=u.nodes[t.nodeId],o=u.nodes[n.nodeId];if(!a||!o||s(a,o)<10)continue;let c=x(`w`);u={...u,walls:{...u.walls,[c]:{...r,id:c,a:t.nodeId,b:n.nodeId}}},E.push(c)}return E.length===0&&b.length>0&&o.push(w(i.DuplicateWall,`A wall already covers that span, so nothing was added.`)),{floor:u,result:{wallIds:E,nodeIds:T.map(e=>e.nodeId)},issues:o}}function ae(e,t,n,r=j,i=1){let a=Math.min(t.x,n.x),o=Math.max(t.x,n.x),s=Math.min(t.y,n.y),c=Math.max(t.y,n.y);if(o-a<10||c-s<10)return{floor:e,result:{wallIds:[]},issues:[]};let l=[{x:a,y:s},{x:o,y:s},{x:o,y:c},{x:a,y:c}],u=e,d=[],f=[];for(let e=0;e<4;e++){let t=ie(u,l[e],l[(e+1)%4],r,i);u=t.floor,d.push(...t.result.wallIds),f.push(...t.issues)}return{floor:u,result:{wallIds:d},issues:f}}function oe(e,t,n){if(t===n||!e.nodes[t]||!e.nodes[n])return{floor:e,result:{removedWallIds:[]},issues:[]};let r=C(e),a=[],o=[];for(let e of Object.values(r.walls))e.a===n&&(r.walls[e.id]={...r.walls[e.id],a:t}),e.b===n&&(r.walls[e.id]={...r.walls[e.id],b:t});for(let e of Object.values(r.walls))if(e.a===e.b){delete r.walls[e.id],a.push(e.id);for(let t of Object.values(r.openings))t.wallId===e.id&&delete r.openings[t.id]}let s=new Map;for(let e of Object.values(r.walls)){let t=e.a<e.b?`${e.a}|${e.b}`:`${e.b}|${e.a}`,n=s.get(t);if(!n){s.set(t,e);continue}let c=e.thickness>=n.thickness?e:n,l=c===e?n:e;for(let e of Object.values(r.openings))e.wallId===l.id&&(r.openings[e.id]={...e,wallId:c.id});delete r.walls[l.id],a.push(l.id),s.set(t,c),o.push(w(i.DuplicateWall,`Two walls became the same wall and were merged.`,{wallIds:[c.id,l.id]}))}return delete r.nodes[n],{floor:r,result:{removedWallIds:a},issues:o}}function M(e,t,n={}){let{force:r=!1}=n,a=e.nodes[t];if(!a)return{floor:e,result:null,issues:[]};let o=E(e,t);if(o.length!==2)return{floor:e,result:null,issues:[]};let[l,u]=o,d=l.thickness===u.thickness&&l.type===u.type&&l.height===u.height&&l.baseHeight===u.baseHeight;if(!d&&!r)return{floor:e,result:null,issues:[]};let f=l.a===t?l.b:l.a,p=u.a===t?u.b:u.a;if(f===p)return{floor:e,result:null,issues:[]};let m=e.nodes[f],h=e.nodes[p];if(!m||!h)return{floor:e,result:null,issues:[]};let g=s(m,h);if(g<10||!r&&Math.abs(c(m,h,a))/g>Math.max(1,g*1e-4))return{floor:e,result:null,issues:[]};let _=!d&&l.thickness<u.thickness?u:l,v=C(e),y=x(`w`);v.walls[y]={id:y,a:f,b:p,thickness:_.thickness,type:_.type,height:_.height,baseHeight:_.baseHeight};let b=s(m,a),S=s(a,h),D=b+S>0?g/(b+S):1,O=[];for(let n of Object.values(e.openings)){if(n.wallId!==l.id&&n.wallId!==u.id)continue;let r=n.wallId===l.id,a=r?l:u,o=a.a===t,s=T(e,a),c=o?n.offset:s-n.offset,d=(r?b-c:b+c)*D,f=Math.min(n.width*D,g-2);if(f<100){O.push(w(i.OpeningDropped,`An opening was removed: the wall it sat on became too short for it.`,{openingIds:[n.id],wallIds:[a.id]})),delete v.openings[n.id];continue}v.openings[n.id]={...n,wallId:y,width:f,offset:Math.min(Math.max(d,f/2),g-f/2)}}return delete v.walls[l.id],delete v.walls[u.id],delete v.nodes[t],{floor:v,result:{wallId:y},issues:O}}function se(e,t,n){let r=e.walls[t];if(!r||r.a===r.b||Math.hypot(n.x,n.y)<10)return{floor:e,result:null,issues:[]};let i=[r.a,r.b],a=[r.a,r.b],o=[null,null],s=[],c=[],l=e;i.forEach((i,s)=>{let c=e.nodes[i];if(!c)return;let u={x:c.x+n.x,y:c.y+n.y},d=E(e,i).filter(e=>e.id!==t);if(d.length===0){let e=C(l);e.nodes[i]={...e.nodes[i],x:u.x,y:u.y},l=e;return}let f=A(l,u,1);l=f.floor,a[s]=f.result.nodeId,o[s]=d.length===1?d[0]:r});let u=C(l);u.walls[t]={...u.walls[t],a:a[0],b:a[1]},l=u,i.forEach((e,t)=>{let n=o[t],r=l.nodes[e],i=l.nodes[a[t]];if(!n||!r||!i)return;let u=ie(l,r,i,{thickness:n.thickness,type:n.type,height:n.height,baseHeight:n.baseHeight});l=u.floor,s.push(...u.result.wallIds),c.push(...u.issues)});let d=[];return i.forEach((e,t)=>{if(a[t]===e)return;let n=M(l,e);n.result&&(l=n.floor,d.push(e),c.push(...n.issues))}),{floor:l,result:{nodeIds:a,connectorIds:s,dissolvedNodeIds:d},issues:c}}function ce(e,t=10){let n=e,r=[],i=[];for(let a=Object.keys(e.walls).length;a>0;a--){let e=Object.values(n.walls).find(e=>{if(e.a===e.b)return!1;let r=n.nodes[e.a],i=n.nodes[e.b];return r&&i&&s(r,i)<t});if(!e)break;let a=E(n,e.b).length>E(n,e.a).length?e.b:e.a,o=oe(n,a,a===e.a?e.b:e.a);if(o.floor===n)break;n=o.floor,r.push(e.id),i.push(...o.issues)}return{floor:n,result:{weldedWallIds:r},issues:i}}function le(e,t,n={}){let{pruneOrphanNodes:r=!0,dissolveCollinear:i=!0}=n,a=e.walls[t];if(!a)return{floor:e,result:{removedNodeIds:[],dissolvedWallIds:[]},issues:[]};let o=C(e);delete o.walls[t];for(let e of Object.values(o.openings))e.wallId===t&&delete o.openings[e.id];let s=[],c=[],l=[];for(let e of[a.a,a.b]){let t=E(o,e).length;if(t===0&&r)delete o.nodes[e],s.push(e);else if(t===2&&i){let t=M(o,e);t.result&&(o=t.floor,c.push(t.result.wallId),s.push(e),l.push(...t.issues))}}return{floor:o,result:{removedNodeIds:s,dissolvedWallIds:c},issues:l}}function ue(e,t,n){let r=e.nodes[t];if(!r)return{floor:e,result:void 0,issues:[]};let i=C(e);return i.nodes[t]={...r,x:n.x,y:n.y},{floor:i,result:void 0,issues:[]}}function de(e,t,n){let r=C(e);for(let i of Object.values(e.nodes))r.nodes[i.id]={...i,x:i.x+t,y:i.y+n};for(let i of Object.values(e.rooms))r.rooms[i.id]={...i,anchor:{x:i.anchor.x+t,y:i.anchor.y+n}};return r}function fe(e,t){let n=C(e);for(let r of Object.values(e.nodes))n.nodes[r.id]={...r,x:r.x*t,y:r.y*t};for(let r of Object.values(e.walls))n.walls[r.id]={...r,thickness:r.thickness*t,height:r.height===void 0?void 0:r.height*t,baseHeight:r.baseHeight===void 0?void 0:r.baseHeight*t};for(let r of Object.values(e.openings))n.openings[r.id]={...r,offset:r.offset*t,width:r.width*t,sill:r.sill*t,head:r.head*t};for(let r of Object.values(e.rooms))n.rooms[r.id]={...r,anchor:{x:r.anchor.x*t,y:r.anchor.y*t},area:r.area*t*t};return n}function pe(e,t){let n=e.walls[t.wallId];if(!n)return{floor:e,result:{openingId:null},issues:[]};let r=T(e,n),a=Math.min(t.width,r-2);if(a<100)return{floor:e,result:{openingId:null},issues:[w(i.OpeningDropped,`That wall is too short for an opening.`,{wallIds:[n.id]})]};let o=Math.min(Math.max(t.offset,a/2),r-a/2),s=C(e),c=x(`o`);return s.openings[c]={...t,id:c,offset:o,width:a},{floor:s,result:{openingId:c},issues:[]}}function me(e,t,n){let r=e.openings[t];if(!r)return{floor:e,result:void 0,issues:[]};let i=e.walls[r.wallId];if(!i)return{floor:e,result:void 0,issues:[]};let a=T(e,i),o={...r,...n},s=Math.min(Math.max(o.width,100),Math.max(a-2,100)),c=Math.min(Math.max(o.offset,s/2),Math.max(a-s/2,s/2)),l=C(e);return l.openings[t]={...o,width:s,offset:c},{floor:l,result:void 0,issues:[]}}function he(e,t){if(!e.openings[t])return{floor:e,result:void 0,issues:[]};let n=C(e);return delete n.openings[t],{floor:n,result:void 0,issues:[]}}function ge(e){let t=[],n=Object.values(e.walls);for(let r of n){let n=e.nodes[r.a],a=e.nodes[r.b];if(r.a===r.b){t.push(w(i.SelfLoopWall,`A wall starts and ends at the same node.`,{wallIds:[r.id]}));continue}if(!n||!a){t.push(w(i.ZeroLengthWall,`A wall references a missing node.`,{wallIds:[r.id]}));continue}s(n,a)<10&&t.push(w(i.ZeroLengthWall,`A wall is shorter than the minimum length.`,{wallIds:[r.id]}))}let r=new Map;for(let e of n){let n=e.a<e.b?`${e.a}|${e.b}`:`${e.b}|${e.a}`,a=r.get(n);a?t.push(w(i.DuplicateWall,`Two walls connect the same pair of nodes.`,{wallIds:[a,e.id]})):r.set(n,e.id)}let a=Object.values(e.nodes);for(let e=0;e<a.length;e++)for(let n=e+1;n<a.length;n++)s(a[e],a[n])<1&&t.push(w(i.CoincidentNodes,`Two nodes occupy the same position.`,{nodeIds:[a[e].id,a[n].id]}));for(let r=0;r<n.length;r++)for(let a=r+1;a<n.length;a++){let o=n[r],s=n[a],c=e.nodes[o.a],l=e.nodes[o.b],u=e.nodes[s.a],f=e.nodes[s.b];if(!c||!l||!u||!f)continue;let p=d(c,l,u,f);p.kind===`proper`?t.push(w(i.UnsplitCrossing,`Two walls cross with no node at the intersection.`,{wallIds:[o.id,s.id]})):p.kind===`collinearOverlap`&&t.push(w(i.OverlappingWalls,`Two walls overlap along the same line.`,{wallIds:[o.id,s.id]}))}for(let r of n){let n=e.nodes[r.a],o=e.nodes[r.b];if(n&&o)for(let e of a){if(e.id===r.a||e.id===r.b)continue;let a=l(e,n,o);a.dist<1&&a.t>0&&a.t<1&&t.push(w(i.UnsplitNodeOnWall,`A node sits on a wall that was never split there.`,{wallIds:[r.id],nodeIds:[e.id]}))}}for(let n of Object.values(e.openings))e.walls[n.wallId]||t.push(w(i.DanglingOpening,`An opening references a wall that no longer exists.`,{openingIds:[n.id]}));let o=new Set;for(let e of n)o.add(e.a),o.add(e.b);for(let e of a)o.has(e.id)||t.push(w(i.OrphanNode,`A node has no walls.`,{nodeIds:[e.id]}));return t}function _e(e){let t=[],n=ce(e),r=C(n.floor);for(let e of n.result.weldedWallIds)t.push(w(i.ZeroLengthWall,`Welded the two ends of a wall with no length.`,{wallIds:[e]}));for(let e of Object.values(r.walls)){let n=r.nodes[e.a],a=r.nodes[e.b];(e.a===e.b||!n||!a||s(n,a)<10)&&(delete r.walls[e.id],t.push(w(i.ZeroLengthWall,`Removed a degenerate wall.`,{wallIds:[e.id]})))}let a=new Map;for(let e of Object.values(r.walls)){let n=e.a<e.b?`${e.a}|${e.b}`:`${e.b}|${e.a}`,o=a.get(n);if(!o){a.set(n,e);continue}let s=e.thickness>=o.thickness?e:o,c=s===e?o:e;for(let e of Object.values(r.openings))e.wallId===c.id&&(r.openings[e.id]={...e,wallId:s.id});delete r.walls[c.id],a.set(n,s),t.push(w(i.DuplicateWall,`Removed a duplicate wall.`,{wallIds:[c.id]}))}for(let e of Object.values(r.openings))r.walls[e.wallId]||(delete r.openings[e.id],t.push(w(i.DanglingOpening,`Removed an opening with no wall.`,{openingIds:[e.id]})));let o=new Set;for(let e of Object.values(r.walls))o.add(e.a),o.add(e.b);for(let e of Object.values(r.nodes))o.has(e.id)||(delete r.nodes[e.id],t.push(w(i.OrphanNode,`Removed a node with no walls.`,{nodeIds:[e.id]})));return{floor:r,result:t,issues:t}}function N(e={}){return{id:e.floorId??x(`f`),label:e.floorLabel??`Ground floor`,elevation:0,height:e.height??2500,nodes:{},walls:{},openings:{},rooms:{}}}function ve(t={}){return{id:t.id??x(`plan`),name:t.name,version:1,unitSystem:t.unitSystem??e.Metric,floors:[N(t)],revision:0}}function P(e,t){return t?e.floors.find(e=>e.id===t)??null:e.floors[0]??null}function ye(e,t,n){let r=P(e,t);if(!r)return{plan:e,floor:N(),result:void 0,issues:[]};let i=n(r);return i.floor===r?{...i,plan:e}:{...i,plan:{...e,floors:e.floors.map(e=>e.id===r.id?i.floor:e),revision:e.revision+1}}}function be(e,t){let n=e.floors.some(e=>e.id===t.id);return{...e,floors:n?e.floors.map(e=>e.id===t.id?t:e):[...e.floors,t],revision:e.revision+1}}function F(e,t){return e.floors.findIndex(e=>e.id===t)}function xe(e,t){let n=F(e,t);return n>0?e.floors[n-1]:null}var Se=e=>`Floor ${e}`;function Ce(e,t={}){let n=e.floors[0]?.elevation??0,r=Math.max(0,Math.min(t.index??e.floors.length,e.floors.length)),i=e.floors[r-1],a={...N({height:t.height??i?.height??2500}),id:t.id??x(`f`),label:t.label??S(t.nameFor??Se,e.floors.length+1,new Set(e.floors.map(e=>e.label))),elevation:i?i.elevation+i.height:0},o=[...e.floors.slice(0,r),a,...e.floors.slice(r)];return{plan:{...e,floors:I(o,n),revision:e.revision+1},floor:a}}function we(e,t){if(e.floors.length<=1)return e;let n=e.floors[0].elevation,r=e.floors.filter(e=>e.id!==t);return r.length===e.floors.length?e:{...e,floors:I(r,n),revision:e.revision+1}}function Te(e,t,n={}){let r=P(e,t);if(!r)return{plan:e,floor:null};let i=new Map(Object.keys(r.nodes).map(e=>[e,x(`n`)])),a=new Map(Object.keys(r.walls).map(e=>[e,x(`w`)])),o={...r,id:x(`f`),label:n.label??`${r.label} copy`,nodes:{},walls:{},openings:{},rooms:{}};for(let e of Object.values(r.nodes)){let t=i.get(e.id);o.nodes[t]={...e,id:t}}for(let e of Object.values(r.walls)){let t=a.get(e.id);o.walls[t]={...e,id:t,a:i.get(e.a),b:i.get(e.b)}}for(let e of Object.values(r.openings)){let t=a.get(e.wallId);if(!t)continue;let n=x(`o`);o.openings[n]={...e,id:n,wallId:t}}for(let e of Object.values(r.rooms)){let t=x(`r`);o.rooms[t]={...e,id:t,anchor:{...e.anchor},wallIds:e.wallIds.map(e=>a.get(e)).filter(e=>!!e)}}let s=e.floors[0].elevation,c=F(e,t)+1,l=[...e.floors.slice(0,c),o,...e.floors.slice(c)];return{plan:{...e,floors:I(l,s),revision:e.revision+1},floor:o}}var Ee=500;function De(e,t,n){let r=P(e,t),i=Math.max(500,Math.round(n));if(!r||r.height===i)return e;let a=e.floors[0].elevation,o=e.floors.map(e=>e.id===r.id?{...e,height:i}:e);return{...e,floors:I(o,a),revision:e.revision+1}}function Oe(e,t,n){let r=P(e,t);return!r||r.label===n?e:be(e,{...r,label:n})}function ke(e,t,n){let r=F(e,t),i=Math.max(0,Math.min(n,e.floors.length-1));if(r<0||r===i)return e;let a=e.floors[0].elevation,o=[...e.floors],[s]=o.splice(r,1);return o.splice(i,0,s),{...e,floors:I(o,a),revision:e.revision+1}}function I(e,t){let n=t;return e.map(e=>{let t=e.elevation===n?e:{...e,elevation:n};return n+=e.height,t})}function Ae(e){let t=y(Object.values(e.nodes).map(e=>({x:e.x,y:e.y})));if(!t)return null;let n=0;for(let t of Object.values(e.walls))t.thickness>n&&(n=t.thickness);let r=n/2,i=t.minX-r,a=t.minY-r,o=t.maxX+r,s=t.maxY+r;return{minX:i,minY:a,maxX:o,maxY:s,width:o-i,height:s-a}}function je(e){return Object.values(e.walls).filter(t=>{if(t.a===t.b)return!1;let n=e.nodes[t.a],r=e.nodes[t.b];return!n||!r?!1:s(n,r)>=10})}function Me(e){let t=je(e),n=Array(t.length*2);for(let e=0;e<t.length;e++){let r=t[e];n[2*e]={wallId:r.id,from:r.a,to:r.b},n[2*e+1]={wallId:r.id,from:r.b,to:r.a}}let r=t=>e.nodes[t],i=new Map;for(let e=0;e<n.length;e++){let t=i.get(n[e].from);t?t.push(e):i.set(n[e].from,[e])}let a=e=>{let t=r(n[e].from),i=r(n[e].to);return Math.atan2(i.y-t.y,i.x-t.x)};for(let e of i.values())e.sort((e,t)=>{let r=a(e),i=a(t);if(r!==i)return r-i;let o=n[e].wallId,s=n[t].wallId;return o===s?e-t:o<s?-1:1});let o=new Int32Array(n.length);for(let e of i.values())for(let t=0;t<e.length;t++)o[e[t]]=t;return{darts:n,outgoing:i,ringIndex:o,nodeOf:r}}function Ne(e,t){let n=e.outgoing.get(e.darts[t].to);return!n||n.length===0?t^1:n[(e.ringIndex[t^1]-1+n.length)%n.length]}function Pe(e){let t=new Uint8Array(e.darts.length),n=[];for(let r=0;r<e.darts.length;r++){if(t[r])continue;let i=[],a=r,o=0;do if(t[a]=1,i.push(a),a=Ne(e,a),++o>e.darts.length+1)break;while(a!==r&&!t[a]);n.push(i)}return n}function Fe(e){let t=new Map,n=e=>{let n=e;for(;t.get(n)!==n;)n=t.get(n)??n;let r=e;for(;t.get(r)!==n;){let e=t.get(r)??n;t.set(r,n),r=e}return n};for(let n of e.outgoing.keys())t.set(n,n);for(let r=0;r<e.darts.length;r+=2){let i=n(e.darts[r].from),a=n(e.darts[r].to);i!==a&&t.set(i,a)}let r=new Map;for(let t of e.outgoing.keys())r.set(t,n(t));return r}function Ie(e,t){return t.map(t=>{let n=e.nodeOf(e.darts[t].from);return{x:n.x,y:n.y}})}function Le(e,t){let n=``;for(let r of t){let t=`${e.darts[r].wallId}>${e.darts[r].from}`;(n===``||t<n)&&(n=t)}return`f:${n}`}function Re(e){let t=Me(e);if(t.darts.length===0)return[];let n=Fe(t),r=Pe(t),i=[],a=new Map;for(let e of r){let r=Ie(t,e),o=f(r),s=n.get(t.darts[e[0]].from)??``;o>100?i.push({face:{id:Le(t,e),outer:r,holes:[],area:o,perimeter:p(r),wallIds:e.map(e=>t.darts[e].wallId),nodeIds:e.map(e=>t.darts[e].from)},component:s,outerArea:o}):o<-100&&a.set(s,r)}for(let[e,t]of a){let n=Math.abs(f(t));if(n<=100)continue;let r=_(t),a=null;for(let t of i)t.component!==e&&(t.outerArea<=n||h(r,t.face.outer)&&(!a||t.outerArea<a.outerArea)&&(a=t));a&&a.face.holes.push(t)}for(let e of i){let t=e.outerArea;for(let n of e.face.holes)t-=Math.abs(f(n));e.face.area=t}return i.map(e=>e.face)}function ze(e){let t=new Map;for(let n of je(e))t.set(n.a,(t.get(n.a)??0)+1),t.set(n.b,(t.get(n.b)??0)+1);return t}var L={boundary:2,anchor:1,area:.25};function Be(e,t){if(e.size===0&&t.size===0)return 0;let n=0;for(let r of e)t.has(r)&&(n+=1);let r=e.size+t.size-n;return r===0?0:n/r}function Ve(e,t,n){let r=Be(new Set(e.wallIds),n),i=+!!g(e.anchor,t.outer,t.holes),a=e.area>0&&t.area>0?Math.min(e.area,t.area)/Math.max(e.area,t.area):0;return L.boundary*r+L.anchor*i+L.area*a}function R(e){let t=Re(e),n=[],r=Object.values(e.rooms),a=t.map(e=>new Set(e.wallIds)),o=[];for(let e=0;e<r.length;e++)for(let n=0;n<t.length;n++){let i=Ve(r[e],t[n],a[n]);i>.15&&o.push({roomIndex:e,faceIndex:n,score:i})}o.sort((e,n)=>{if(n.score!==e.score)return n.score-e.score;let i=r[e.roomIndex].seq-r[n.roomIndex].seq;return i===0?t[e.faceIndex].id<t[n.faceIndex].id?-1:1:i});let s=Array(r.length).fill(!1),c=Array(t.length).fill(-1);for(let e of o)s[e.roomIndex]||c[e.faceIndex]===-1&&(s[e.roomIndex]=!0,c[e.faceIndex]=e.roomIndex);let l={...e.rooms},u=t.map((e,t)=>{let n=_(e.outer,e.holes),i=c[t];if(i===-1)return{...e,roomId:null,meta:null,anchor:n};let a=r[i],o=a.anchorPinned?a.anchor:n,s={...a,anchor:o,wallIds:[...new Set(e.wallIds)],area:e.area};return l[a.id]=s,{...e,roomId:a.id,meta:s,anchor:o}});for(let e=0;e<r.length;e++)s[e]||n.push({kind:i.UnmatchedRoom,message:`"${r[e].name}" is not currently enclosed by any walls.`,roomIds:[r[e].id]});return{floor:{...e,rooms:l},rooms:u,issues:n}}var He=0,Ue=e=>`Room ${e}`;function We(e,t={}){let{rooms:n,floor:r}=R(e),i={...r.rooms},a=[],o=t.nameFor??Ue,s=new Set(Object.values(i).map(e=>e.name));for(let e of n){if(e.roomId)continue;He+=1;let t=S(t=>o(t,e),Object.keys(i).length+1,s);s.add(t);let n={id:x(`r`),name:t,anchor:e.anchor,anchorPinned:!1,seq:He,wallIds:[...new Set(e.wallIds)],area:e.area};i[n.id]=n,a.push(n)}return{floor:{...r,rooms:i},created:a}}function Ge(e){let{rooms:t}=R(e),n=new Set(t.map(e=>e.roomId).filter(Boolean)),r={},i=[];for(let t of Object.values(e.rooms))n.has(t.id)?r[t.id]=t:i.push(t.id);return{floor:{...e,rooms:r},removed:i}}function Ke(e,t){let n=null;for(let r of e)g(t,r.outer,r.holes)&&(!n||r.area<n.area)&&(n=r);return n}var z=1e-6;function qe(e,t,n){return{x:e.x+(t.x-e.x)*n,y:e.y+(t.y-e.y)*n}}function B(e){return Number.isInteger(e)?String(e):e.toFixed(3).replace(/\.?0+$/,``)}function Je(e,t){return Math.abs(e.x-t.x)<.001&&Math.abs(e.y-t.y)<.001}function V(e,t){let n=e.nodes[t.a],r=e.nodes[t.b];if(!n||!r)return[];let i=s(n,r);if(i<z)return[];let a=[];for(let n of Object.values(e.openings)){if(n.wallId!==t.id)continue;let e=n.width/2,r=Math.max(0,n.offset-e),o=Math.min(i,n.offset+e);o>r&&a.push([r,o])}if(a.length===0)return[[0,i]];a.sort((e,t)=>e[0]-t[0]);let o=[a[0]];for(let e=1;e<a.length;e++){let t=o[o.length-1];a[e][0]<=t[1]?t[1]=Math.max(t[1],a[e][1]):o.push(a[e])}let c=[],l=0;for(let[e,t]of o)e-l>z&&c.push([l,e]),l=t;return i-l>z&&c.push([l,i]),c}function Ye(e,t){let n=e.walls[t.wallId];if(!n)return null;let r=e.nodes[n.a],i=e.nodes[n.b];if(!r||!i)return null;let a=s(r,i);if(a<z)return null;let o={x:(i.x-r.x)/a,y:(i.y-r.y)/a},c={x:-o.y,y:o.x},l=Math.min(t.width/2,a/2),u=Math.min(Math.max(t.offset,l),a-l),d={x:r.x+o.x*u,y:r.y+o.y*u};return{centre:d,dir:o,normal:c,p1:{x:d.x-o.x*l,y:d.y-o.y*l},p2:{x:d.x+o.x*l,y:d.y+o.y*l}}}function Xe(e,t,n){let r=new Map(t.map(e=>[e.id,e])),i=new Map;for(let e of t)for(let t of[e.a,e.b]){let n=i.get(t);n?n.push(e):i.set(t,[e])}let a=e=>{if((n.get(e)??0)!==2)return null;let t=i.get(e);return!t||t.length!==2?null:t},o=new Set,s=[],c=(e,t)=>e.a===t?e.b:e.a;for(let e of t){if(o.has(e.id))continue;let t=e,n=e.a,i=new Set([e.id]);for(;;){let e=a(n);if(!e)break;let r=e[0].id===t.id?e[1]:e[0];if(i.has(r.id))break;i.add(r.id),t=r,n=c(r,n)}let l=[],u=t,d=n;for(;!o.has(u.id);){o.add(u.id);let e=c(u,d);l.push({wall:u,from:d,to:e});let t=a(e);if(!t)break;let n=t[0].id===u.id?t[1]:t[0];if(o.has(n.id)||(u=n,d=e,!r.has(u.id)))break}l.length>0&&s.push(l)}return s}function Ze(e,t,n){let r=new Map,i=(e,t)=>{let n=r.get(e);n?n.push(t):r.set(e,[t])};for(let n of t){let t=e.nodes[n.a],r=e.nodes[n.b],a=s(t,r);if(a<z)continue;let o=V(e,n);if(o.length===0)continue;let c={x:(r.x-t.x)/a,y:(r.y-t.y)/a},l=o[0],u=o[o.length-1];i(n.a,{wall:n,dir:c,angle:Math.atan2(c.y,c.x),reach:l[0]<z?l[1]:0}),i(n.b,{wall:n,dir:{x:-c.x,y:-c.y},angle:Math.atan2(-c.y,-c.x),reach:u[1]>a-z?a-u[0]:0})}let a=[],o=Math.PI*2;for(let[t,i]of r){if(i.length<2||(n.get(t)??0)===2&&i.length===2&&i[0].wall.thickness===i[1].wall.thickness)continue;i.sort((e,t)=>e.angle-t.angle);let r=0,s=-1;for(let e=0;e<i.length;e++){let t=i[(e+1)%i.length],n=e===i.length-1?t.angle+o-i[e].angle:t.angle-i[e].angle;n>s&&(s=n,r=e)}if(s<=Math.PI+z)continue;let c=i[r],l=i[(r+1)%i.length],u=Math.min(c.wall.thickness,l.wall.thickness),d=Math.min(u/2,c.reach),f=Math.min(u/2,l.reach);if(d<z||f<z)continue;let p=e.nodes[t];a.push({thickness:u,d:`M ${B(p.x+c.dir.x*d)},${B(p.y+c.dir.y*d)} L ${B(p.x)},${B(p.y)} L ${B(p.x+l.dir.x*f)},${B(p.y+l.dir.y*f)}`})}return a}function Qe(e,t={}){let{wallIds:n,capFreeEnds:r=!0,capThicknessSteps:i=!0}=t,a=Object.values(e.walls).filter(t=>{if(n&&!n.has(t.id))return!1;let r=e.nodes[t.a],i=e.nodes[t.b];return r&&i&&s(r,i)>z&&t.a!==t.b});if(a.length===0)return{groups:[],caps:[]};let o=ze(e),c=[],l=new Map;for(let e of a){let t=l.get(e.thickness);t?t.push(e):l.set(e.thickness,[e])}let u=new Map,d=(e,t)=>{let n=u.get(e);n?n.push(t):u.set(e,[t])};for(let[t,n]of l)for(let r of Xe(e,n,o)){let n=[],i=()=>{n.length>=2&&d(t,n.map((e,t)=>`${t===0?`M`:`L`} ${B(e.x)},${B(e.y)}`).join(` `)),n=[]};for(let t of r){let r=e.nodes[t.from],a=e.nodes[t.to],o=s(r,a);if(o<z)continue;let c=V(e,t.wall);t.from!==t.wall.a&&(c=c.map(([e,t])=>[o-t,o-e]).reverse());for(let[e,t]of c){let s=qe(r,a,e/o),c=qe(r,a,t/o);n.length>0&&Je(n[n.length-1],s)?n.push(c):(i(),n=[s,c])}(c.length===0||c[c.length-1][1]<o-z)&&i()}let a=r[0],o=r[r.length-1];a.from===o.to&&n.length>=3&&Je(n[0],n[n.length-1])?(d(t,`${n.slice(0,-1).map((e,t)=>`${t===0?`M`:`L`} ${B(e.x)},${B(e.y)}`).join(` `)} Z`),n=[]):i()}for(let t of Ze(e,a,o))d(t.thickness,t.d);let f=(t,n,r)=>{let i=e.nodes[t.a],a=e.nodes[t.b],o=s(i,a);if(o<z)return;let l={x:(a.x-i.x)/o,y:(a.y-i.y)/o},u={x:-l.y,y:l.x},d={x:i.x+l.x*n,y:i.y+l.y*n},f=t.thickness/2;c.push({a:{x:d.x-u.x*f,y:d.y-u.y*f},b:{x:d.x+u.x*f,y:d.y+u.y*f},reason:r,wallId:t.id})};for(let t of a){let n=e.nodes[t.a],i=e.nodes[t.b],a=s(n,i);for(let[n,i]of V(e,t))n>z?f(t,n,`jamb`):r&&(o.get(t.a)??0)===1&&f(t,0,`freeEnd`),i<a-z?f(t,i,`jamb`):r&&(o.get(t.b)??0)===1&&f(t,a,`freeEnd`)}if(i){let t=new Map;for(let e of a)for(let n of[e.a,e.b]){let r=t.get(n);r?r.push(e):t.set(n,[e])}for(let[n,r]of t){if(r.length!==2)continue;let[t,i]=r;if(t.thickness===i.thickness)continue;let a=t.thickness>=i.thickness?t:i;f(a,a.a===n?0:s(e.nodes[a.a],e.nodes[a.b]),`thicknessStep`)}}return{groups:[...u.entries()].sort((e,t)=>e[0]-t[0]).map(([e,t])=>({thickness:e,d:t.join(` `)})),caps:c}}var $e={node:10,opening:9,wall:8},et={node:18,opening:16,wall:14};function tt(e,t){let n=t>0?t:1;return{node:e.node/n,opening:e.opening/n,wall:e.wall/n}}function nt(e,t,n,r,i={}){let a=e=>!i.accept||i.accept.includes(e),o=e=>i.excludeIds?.has(e)??!1;if(a(`node`)){let t=null;for(let i of Object.values(e.nodes)){if(o(i.id))continue;let e=s(n,i);e<=r.node&&(!t||e<t.d)&&(t={id:i.id,d:e})}if(t)return{type:`node`,id:t.id}}if(a(`opening`)){let t=null;for(let i of Object.values(e.openings)){if(o(i.id))continue;let a=Ye(e,i);if(!a)continue;let s=l(n,a.p1,a.p2).dist;s<=r.opening&&(!t||s<t.d)&&(t={id:i.id,d:s})}if(t)return{type:`opening`,id:t.id}}if(a(`wall`)){let t=null;for(let i of Object.values(e.walls)){if(o(i.id))continue;let a=e.nodes[i.a],s=e.nodes[i.b];if(!a||!s)continue;let c=Math.max(r.wall,i.thickness/2),u=l(n,a,s).dist;u<=c&&(!t||u<t.d)&&(t={id:i.id,d:u})}if(t)return{type:`wall`,id:t.id}}if(a(`room`)){let e=Ke(t,n);if(e?.roomId&&!o(e.roomId))return{type:`room`,id:e.roomId}}return null}function rt(e,t){return e===t?!0:!e||!t?!1:e.type===t.type&&e.id===t.id}var it=function(e){return e.None=`none`,e.Node=`node`,e.Wall=`wall`,e.Intersection=`intersection`,e.Extension=`extension`,e.Alignment=`alignment`,e.Angle=`angle`,e.Grid=`grid`,e}({}),at={enabled:[`node`,`intersection`,`wall`,`angle`,`extension`,`alignment`,`grid`],gridSize:100,angleStepDeg:0,toleranceScreenPx:10,nodeToleranceScreenPx:12};function ot(e,t,n,r){return{x:r.x+(e-n.left)/r.zoom,y:r.y+(t-n.top)/r.zoom}}function H(e,t){let n=e.x-t.point.x,r=e.y-t.point.y;return Math.abs(n*t.dir.y-r*t.dir.x)}function st(e,t){let n=e.x-t.point.x,r=e.y-t.point.y,i=n*t.dir.x+r*t.dir.y;return{x:t.point.x+t.dir.x*i,y:t.point.y+t.dir.y*i}}function ct(e,t){let n=e.dir.x*t.dir.y-e.dir.y*t.dir.x;if(Math.abs(n)<1e-9)return null;let r=t.point.x-e.point.x,i=t.point.y-e.point.y,a=(r*t.dir.y-i*t.dir.x)/n;return{x:e.point.x+e.dir.x*a,y:e.point.y+e.dir.y*a}}function lt(e,t){let n=Math.abs(e.dir.x*t.dir.x+e.dir.y*t.dir.y);return Math.acos(Math.min(1,n))}function U(e,t){return t>0?Math.round(e/t)*t:e}function ut(e,t){let n={...at,...t.options},r=new Set(n.enabled),i=e=>{if(!t.origin)return e;let n=e.point.x-t.origin.x,r=e.point.y-t.origin.y;return{...e,angle:Math.atan2(r,n),distance:Math.hypot(n,r)}};if(r.size===0)return i({point:e,kind:`none`,guides:[]});let a=n.toleranceScreenPx*t.pxToWorld,o=(n.nodeToleranceScreenPx??n.toleranceScreenPx)*t.pxToWorld,{floor:c}=t,f=(()=>{if(!r.has(`angle`)||!t.origin||n.angleStepDeg<=0)return null;let i=n.angleStepDeg*Math.PI/180,a=Math.atan2(e.y-t.origin.y,e.x-t.origin.x),o=[{angle:0,relativeTo:`world`}];t.referenceAngle!==void 0&&o.push({angle:t.referenceAngle,relativeTo:`reference`});let s=null;for(let n of o){let r=n.angle+Math.round((a-n.angle)/i)*i,o={x:Math.cos(r),y:Math.sin(r)},c={kind:`angle`,point:t.origin,dir:o,residual:0,relativeTo:n.relativeTo};c.residual=H(e,c),(!s||c.residual<s.residual)&&(s=c)}return s})(),p=e=>!f||H(e,f)<=a;if(r.has(`node`)){let n=null;for(let r of Object.values(c.nodes)){if(t.excludeNodeIds?.has(r.id))continue;let i=s(e,r);i<=o&&p(r)&&(!n||i<n.d)&&(n={id:r.id,point:{x:r.x,y:r.y},d:i})}if(n)return i({point:n.point,kind:`node`,nodeId:n.id,guides:[]})}let m=Object.values(c.walls).filter(e=>!t.excludeWallIds?.has(e.id));if(r.has(`intersection`)){let t=null;for(let n=0;n<m.length;n++)for(let r=n+1;r<m.length;r++){let i=c.nodes[m[n].a],o=c.nodes[m[n].b],l=c.nodes[m[r].a],u=c.nodes[m[r].b];if(!i||!o||!l||!u)continue;let f=d(i,o,l,u);if(!f.point)continue;let h=s(e,f.point);h<=a&&p(f.point)&&(!t||h<t.d)&&(t={point:f.point,d:h})}if(t)return i({point:t.point,kind:`intersection`,guides:[]})}if(r.has(`wall`)){let t=null;for(let n of m){let r=c.nodes[n.a],i=c.nodes[n.b];if(!r||!i)continue;let o=l(e,r,i);o.dist<=a&&p(o.point)&&(!t||o.dist<t.d)&&(t={wallId:n.id,point:u(e,r,i),t:o.t,d:o.dist})}if(t)return i({point:t.point,kind:`wall`,wallId:t.wallId,t:t.t,guides:[]})}let h=[];if(r.has(`extension`)){let t=null;for(let n of m){let r=c.nodes[n.a],i=c.nodes[n.b];if(!r||!i)continue;let o=s(r,i);if(o<1e-6)continue;let u={x:(i.x-r.x)/o,y:(i.y-r.y)/o},d={kind:`extension`,point:{x:r.x,y:r.y},dir:u,residual:0};d.residual=H(e,d);let f=l(e,r,i).dist<=a;d.residual<=a&&!f&&(!t||d.residual<t.residual)&&(t=d)}t&&h.push(t)}if(r.has(`alignment`)){let n=null,r=null;for(let i of Object.values(c.nodes)){if(t.excludeNodeIds?.has(i.id))continue;let o=Math.abs(e.x-i.x);o<=a&&(!n||o<n.residual)&&(n={kind:`alignment`,point:{x:i.x,y:i.y},dir:{x:0,y:1},residual:o});let s=Math.abs(e.y-i.y);s<=a&&(!r||s<r.residual)&&(r={kind:`alignment`,point:{x:i.x,y:i.y},dir:{x:1,y:0},residual:s})}n&&h.push(n),r&&h.push(r)}let g=(e,t)=>({kind:e.kind,a:{x:t.x-e.dir.x*1e5,y:t.y-e.dir.y*1e5},b:{x:t.x+e.dir.x*1e5,y:t.y+e.dir.y*1e5},infinite:!0});if(f){let t=h.filter(e=>e.residual<=a&<(f,e)>15*Math.PI/180).sort((e,t)=>e.residual-t.residual)[0];if(t){let n=ct(f,t);if(n&&s(n,e)<=a*4)return i({point:n,kind:`angle`,guides:[g(f,n),g(t,n)],angleRelativeTo:f.relativeTo})}let o=st(e,f);if(r.has(`grid`)&&n.gridSize>0){let e=U((o.x-f.point.x)*f.dir.x+(o.y-f.point.y)*f.dir.y,n.gridSize);o={x:f.point.x+f.dir.x*e,y:f.point.y+f.dir.y*e}}return i({point:o,kind:`angle`,guides:[g(f,o)],angleRelativeTo:f.relativeTo})}if(h.length>=2){let[t,n]=[...h].sort((e,t)=>e.residual-t.residual),r=ct(t,n);if(r&<(t,n)>15*Math.PI/180&&s(r,e)<=a*2)return i({point:r,kind:`intersection`,guides:[g(t,r),g(n,r)]})}if(h.length>=1){let t=[...h].sort((e,t)=>e.residual-t.residual)[0],a=st(e,t);if(r.has(`grid`)&&n.gridSize>0){let e=U((a.x-t.point.x)*t.dir.x+(a.y-t.point.y)*t.dir.y,n.gridSize);a={x:t.point.x+t.dir.x*e,y:t.point.y+t.dir.y*e}}return i({point:a,kind:t.kind,guides:[g(t,a)],angleRelativeTo:t.relativeTo})}return r.has(`grid`)&&n.gridSize>0?i({point:{x:U(e.x,n.gridSize),y:U(e.y,n.gridSize)},kind:`grid`,guides:[]}):i({point:e,kind:`none`,guides:[]})}var dt=1;function ft(e,t={}){return JSON.stringify(e,null,t.pretty===!1?void 0:2)}function W(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function G(e,t){let n=typeof e==`string`?Number(e):e;return typeof n==`number`&&Number.isFinite(n)?n:t}function K(e,t){return typeof e==`string`?e:t}function pt(e,t){return typeof e==`boolean`?e:t}function q(e,t,n){return typeof e==`string`&&t.includes(e)?e:n}function mt(e,t){return W(e)?{x:G(e.x,t.x),y:G(e.y,t.y)}:t}function J(e){return Array.isArray(e)?e:W(e)?Object.values(e):[]}function Y(e){let t={};for(let n of e)t[n.id]=n;return t}function ht(e,i,a){let o=`floor ${i+1}`,s=W(e)?e:{};W(e)||a.push(`${o} was not an object, so it was read as empty`);let c=N();c.id=K(s.id,c.id),c.label=K(s.label,c.label),c.elevation=G(s.elevation,0),c.height=G(s.height,c.height);let l=[];for(let e of J(s.nodes))W(e)&&typeof e.id==`string`&&l.push({id:e.id,x:G(e.x,0),y:G(e.y,0)});c.nodes=Y(l);let u=[],d=0;for(let e of J(s.walls)){if(!W(e)||typeof e.id!=`string`)continue;let n=K(e.a,``),r=K(e.b,``);if(!c.nodes[n]||!c.nodes[r]||n===r){d+=1;continue}u.push({id:e.id,a:n,b:r,thickness:Math.max(1,G(e.thickness,100)),height:e.height===void 0?void 0:G(e.height,0),baseHeight:e.baseHeight===void 0?void 0:G(e.baseHeight,0),type:q(e.type,Object.values(t),t.Interior)})}c.walls=Y(u),d>0&&a.push(`${o}: dropped ${d} wall(s) whose corners were missing`);let f=[],p=0;for(let e of J(s.openings)){if(!W(e)||typeof e.id!=`string`)continue;let t=K(e.wallId,``);if(!c.walls[t]){p+=1;continue}f.push({id:e.id,wallId:t,kind:q(e.kind,Object.values(n),n.Door),offset:G(e.offset,0),width:Math.max(1,G(e.width,800)),sill:G(e.sill,0),head:G(e.head,2100),swing:e.swing===void 0?void 0:q(e.swing,Object.values(r),r.StartLeft)})}c.openings=Y(f),p>0&&a.push(`${o}: dropped ${p} opening(s) with no wall to sit in`);let m=[];for(let e of J(s.rooms))W(e)&&typeof e.id==`string`&&m.push({id:e.id,name:K(e.name,``),colour:typeof e.colour==`string`?e.colour:void 0,usage:typeof e.usage==`string`?e.usage:void 0,anchor:mt(e.anchor,{x:0,y:0}),anchorPinned:pt(e.anchorPinned,!1),seq:G(e.seq,m.length),wallIds:Array.isArray(e.wallIds)?e.wallIds.filter(e=>typeof e==`string`&&!!c.walls[e]):[],area:G(e.area,0)});c.rooms=Y(m);let h=_e(c);return h.result.length>0&&a.push(`${o}: repaired ${h.result.length} inconsistency(ies) in the geometry`),h.floor}function gt(t){let n=[],r;try{r=JSON.parse(t)}catch(e){return{plan:null,issues:[`Not valid JSON: ${e.message}`]}}if(!W(r))return{plan:null,issues:[`Not a floor plan: expected an object`]};if(r.version!==void 0&&r.version!==1)return{plan:null,issues:[`Plan format version ${String(r.version)} is not supported (this build reads version 1)`]};r.version===void 0&&n.push(`No format version, read as version 1`);let i=Array.isArray(r.floors)?r.floors:[];if(i.length===0){if(r.floors!==void 0)n.push(`No floors in the file, started an empty one`);else return{plan:null,issues:["Not a floor plan: no `floors`"]}}let a=(i.length>0?i:[void 0]).map((e,t)=>ht(e,t,n));return{plan:{id:K(r.id,x(`plan`)),name:typeof r.name==`string`?r.name:void 0,version:1,unitSystem:q(r.unitSystem,Object.values(e),e.Metric),floors:a,revision:G(r.revision,0)+1},issues:n}}var X=1e-9;function Z(e,t,n){return(t.x-e.x)*(n.y-e.y)-(t.y-e.y)*(n.x-e.x)}function _t(e,t){return Math.abs(e.x-t.x)<X&&Math.abs(e.y-t.y)<X}function vt(e,t,n,r){let i=Z(e,t,n),a=Z(e,n,r),o=Z(e,r,t);return!((i<-1e-9||a<-1e-9||o<-1e-9)&&(i>X||a>X||o>X))}function yt(e,t){let n=e.slice(),r=t.filter(e=>e.length>=3).map(e=>({ring:e,index:e.reduce((t,n,r)=>n.x>e[t].x?r:t,0)})).sort((e,t)=>t.ring[t.index].x-e.ring[e.index].x);for(let e of r){let t=e.ring[e.index],r=-1,i=1/0;for(let a=0;a<n.length;a++){if(n[a].x<t.x)continue;let o=(n[a].x-t.x)**2+(n[a].y-t.y)**2;o<i&&bt(t,n[a],n,e.ring)&&(i=o,r=a)}if(r<0)for(let e=0;e<n.length;e++){let a=(n[e].x-t.x)**2+(n[e].y-t.y)**2;a<i&&(i=a,r=e)}let a=[];for(let t=0;t<=e.ring.length;t++)a.push(e.ring[(e.index+t)%e.ring.length]);n=[...n.slice(0,r+1),...a,...n.slice(r)]}return n}function bt(e,t,n,r){for(let i of[n,r])for(let n=0;n<i.length;n++){let r=i[n],a=i[(n+1)%i.length];if(r===e||a===e||r===t||a===t)continue;let o=Z(e,t,r),s=Z(e,t,a),c=Z(r,a,e),l=Z(r,a,t);if(o*s<0&&c*l<0)return!1}return!0}function xt(e,t=[]){let n=v(e);if(n.length<3)return{vertices:[],indices:[]};let r=yt(n,t.map(e=>v(e)).filter(e=>e.length>=3)),i=f(r)<0?r.slice().reverse():r.slice(),a=i.map((e,t)=>t),o=[],s=a.length*a.length;for(;a.length>3&&s-->0;){let e=!1;for(let t=0;t<a.length;t++){let n=a[(t+a.length-1)%a.length],r=a[t],s=a[(t+1)%a.length],c=i[n],l=i[r],u=i[s];if(Z(c,l,u)<=X)continue;let d=!1;for(let e of a){if(e===n||e===r||e===s)continue;let t=i[e];if(!(_t(t,c)||_t(t,l)||_t(t,u))&&vt(t,c,l,u)){d=!0;break}}if(!d){o.push(n,r,s),a.splice(t,1),e=!0;break}}if(!e)break}return a.length===3&&o.push(a[0],a[1],a[2]),{vertices:i,indices:o}}var Q=1e-6,St=1,Ct=class{constructor(){this.positions=[],this.normals=[],this.indices=[]}triangle(e,t,n){let r=t[0]-e[0],i=t[1]-e[1],a=t[2]-e[2],o=n[0]-e[0],s=n[1]-e[1],c=n[2]-e[2],l=i*c-a*s,u=a*o-r*c,d=r*s-i*o,f=Math.hypot(l,u,d);if(f<Q)return;l/=f,u/=f,d/=f;let p=this.positions.length/3;for(let r of[e,t,n])this.positions.push(r[0],r[1],r[2]);for(let e=0;e<3;e++)this.normals.push(l,u,d);this.indices.push(p,p+1,p+2)}quad(e,t,n,r){this.triangle(e,t,n),this.triangle(e,n,r)}};function wt(e){let t=new Map;for(let n of Object.values(e.walls))for(let e of[n.a,n.b]){let r=t.get(e);r?r.push(n):t.set(e,[n])}return t}var Tt=4;function Et(e,t,n,r){let i=r.get(n);if(!i||i.length!==2)return null;let a=i[0].id===t.id?i[1]:i[0];if(a.thickness!==t.thickness)return null;let o=e.nodes[n],s=e.nodes[t.a===n?t.b:t.a],c=e.nodes[a.a===n?a.b:a.a];if(!o||!s||!c)return null;let l=Dt(s,o),u=Dt(o,c);if(!l||!u)return null;let d=l.x*u.x+l.y*u.y;if(d<-.999999)return null;let f={x:-l.y,y:l.x},p={x:-u.y,y:u.x},m=1+d,h={x:(f.x+p.x)/m,y:(f.y+p.y)/m};return Math.hypot(h.x,h.y)>Tt?null:t.b===n?h:{x:-h.x,y:-h.y}}function Dt(e,t){let n=s(e,t);return n<Q?null:{x:(t.x-e.x)/n,y:(t.y-e.y)/n}}function Ot(e,t,n,r,i){let a=e.nodes[t.a],o=e.nodes[t.b];if(!a||!o)return null;let c=s(a,o);if(c<Q||r-n<Q)return null;let l=Dt(a,o),u=t.thickness/2,d={x:-l.y*u,y:l.x*u},f={x:a.x+l.x*n,y:a.y+l.y*n},p={x:a.x+l.x*r,y:a.y+l.y*r},m=n<Q?Et(e,t,t.a,i):null,h=r>c-Q?Et(e,t,t.b,i):null,g=(e,t,n)=>t?{x:e.x+t.x*u*n,y:e.y+t.y*u*n}:{x:e.x+d.x*n,y:e.y+d.y*n};return[g(f,m,1),g(p,h,1),g(p,h,-1),g(f,m,-1)]}function $(e,t,n,r){if(r-n<Q)return;let i=t.map(e=>[e.x,n,e.y]),a=t.map(e=>[e.x,r,e.y]),o=0;for(let e=0;e<t.length;e++){let n=t[e],r=t[(e+1)%t.length];o+=n.x*r.y-r.x*n.y}let s=o<0;for(let n=0;n<t.length;n++){let r=(n+1)%t.length;s?e.quad(i[n],i[r],a[r],a[n]):e.quad(i[r],i[n],a[n],a[r])}for(let n=1;n+1<t.length;n++)s?(e.triangle(a[0],a[n],a[n+1]),e.triangle(i[0],i[n+1],i[n])):(e.triangle(a[0],a[n+1],a[n]),e.triangle(i[0],i[n],i[n+1]))}function kt(e,t,n){return Object.values(e.openings).filter(e=>e.wallId===t.id).filter(e=>e.offset+e.width/2>Q&&e.offset-e.width/2<n-Q).sort((e,t)=>e.offset-t.offset)}function At(e,t={}){let{wallHeight:n,includeFloorSlab:r=!0,slabThickness:i=200,applyElevation:a=!0}=t,o=new Ct,c=[],l=a?e.elevation:0,u=r?i+St:0,d=wt(e),f=o.indices.length;for(let t of Object.values(e.walls)){let r=e.nodes[t.a],i=e.nodes[t.b];if(!r||!i)continue;let a=s(r,i);if(a<Q)continue;let c=l+(t.baseHeight??0)-u,f=c+(t.height??n??e.height);if(f-c<Q)continue;let p=kt(e,t,a);if(p.length===0){let n=Ot(e,t,0,a,d);n&&$(o,n,c,f);continue}for(let[n,r]of V(e,t)){let i=Ot(e,t,n,r,d);i&&$(o,i,c,f)}for(let n of p){let r=Ot(e,t,Math.max(0,n.offset-n.width/2),Math.min(a,n.offset+n.width/2),d);if(!r)continue;let i=c+Math.max(0,n.sill),s=c+Math.max(0,n.head);i>c+Q&&$(o,r,c,Math.min(i,f)),s<f-Q&&$(o,r,Math.max(s,c),f)}}if(o.indices.length>f&&c.push({part:`wall`,start:f,count:o.indices.length-f}),r){let t=o.indices.length;for(let t of R(e).rooms){let{vertices:e,indices:n}=xt(t.outer,t.holes);if(n.length===0)continue;let r=l,a=l-i;for(let t=0;t<n.length;t+=3){let i=[e[n[t]],e[n[t+1]],e[n[t+2]]],s=i.map(e=>[e.x,r,e.y]),c=i.map(e=>[e.x,a,e.y]);o.triangle(s[0],s[2],s[1]),o.triangle(c[0],c[1],c[2])}for(let e of[t.outer,...t.holes])for(let t=0;t<e.length;t++){let n=e[t],i=e[(t+1)%e.length];o.quad([n.x,a,n.y],[n.x,r,n.y],[i.x,r,i.y],[i.x,a,i.y])}}o.indices.length>t&&c.push({part:`floor`,start:t,count:o.indices.length-t})}return{positions:new Float32Array(o.positions),normals:new Float32Array(o.normals),indices:new Uint32Array(o.indices),groups:c}}Object.defineProperty(exports,"$",{enumerable:!0,get:function(){return ge}}),Object.defineProperty(exports,"A",{enumerable:!0,get:function(){return F}}),Object.defineProperty(exports,"B",{enumerable:!0,get:function(){return ae}}),Object.defineProperty(exports,"C",{enumerable:!0,get:function(){return Ee}}),Object.defineProperty(exports,"D",{enumerable:!0,get:function(){return ve}}),Object.defineProperty(exports,"E",{enumerable:!0,get:function(){return N}}),Object.defineProperty(exports,"F",{enumerable:!0,get:function(){return be}}),Object.defineProperty(exports,"G",{enumerable:!0,get:function(){return oe}}),Object.defineProperty(exports,"H",{enumerable:!0,get:function(){return _e}}),Object.defineProperty(exports,"I",{enumerable:!0,get:function(){return De}}),Object.defineProperty(exports,"J",{enumerable:!0,get:function(){return le}}),Object.defineProperty(exports,"K",{enumerable:!0,get:function(){return ue}}),Object.defineProperty(exports,"L",{enumerable:!0,get:function(){return ye}}),Object.defineProperty(exports,"M",{enumerable:!0,get:function(){return ke}}),Object.defineProperty(exports,"N",{enumerable:!0,get:function(){return we}}),Object.defineProperty(exports,"O",{enumerable:!0,get:function(){return xe}}),Object.defineProperty(exports,"P",{enumerable:!0,get:function(){return Oe}}),Object.defineProperty(exports,"Q",{enumerable:!0,get:function(){return me}}),Object.defineProperty(exports,"R",{enumerable:!0,get:function(){return j}}),Object.defineProperty(exports,"S",{enumerable:!0,get:function(){return ze}}),Object.defineProperty(exports,"T",{enumerable:!0,get:function(){return Te}}),Object.defineProperty(exports,"U",{enumerable:!0,get:function(){return se}}),Object.defineProperty(exports,"V",{enumerable:!0,get:function(){return ie}}),Object.defineProperty(exports,"W",{enumerable:!0,get:function(){return M}}),Object.defineProperty(exports,"X",{enumerable:!0,get:function(){return k}}),Object.defineProperty(exports,"Y",{enumerable:!0,get:function(){return fe}}),Object.defineProperty(exports,"Z",{enumerable:!0,get:function(){return de}}),Object.defineProperty(exports,"_",{enumerable:!0,get:function(){return We}}),Object.defineProperty(exports,"a",{enumerable:!0,get:function(){return at}}),Object.defineProperty(exports,"at",{enumerable:!0,get:function(){return r}}),Object.defineProperty(exports,"b",{enumerable:!0,get:function(){return Ke}}),Object.defineProperty(exports,"c",{enumerable:!0,get:function(){return ut}}),Object.defineProperty(exports,"ct",{enumerable:!0,get:function(){return e}}),Object.defineProperty(exports,"d",{enumerable:!0,get:function(){return nt}}),Object.defineProperty(exports,"et",{enumerable:!0,get:function(){return T}}),Object.defineProperty(exports,"f",{enumerable:!0,get:function(){return rt}}),Object.defineProperty(exports,"g",{enumerable:!0,get:function(){return V}}),Object.defineProperty(exports,"h",{enumerable:!0,get:function(){return Ye}}),Object.defineProperty(exports,"i",{enumerable:!0,get:function(){return ft}}),Object.defineProperty(exports,"it",{enumerable:!0,get:function(){return l}}),Object.defineProperty(exports,"j",{enumerable:!0,get:function(){return P}}),Object.defineProperty(exports,"k",{enumerable:!0,get:function(){return Ae}}),Object.defineProperty(exports,"l",{enumerable:!0,get:function(){return $e}}),Object.defineProperty(exports,"lt",{enumerable:!0,get:function(){return t}}),Object.defineProperty(exports,"m",{enumerable:!0,get:function(){return Qe}}),Object.defineProperty(exports,"n",{enumerable:!0,get:function(){return dt}}),Object.defineProperty(exports,"nt",{enumerable:!0,get:function(){return o}}),Object.defineProperty(exports,"o",{enumerable:!0,get:function(){return it}}),Object.defineProperty(exports,"ot",{enumerable:!0,get:function(){return n}}),Object.defineProperty(exports,"p",{enumerable:!0,get:function(){return tt}}),Object.defineProperty(exports,"q",{enumerable:!0,get:function(){return he}}),Object.defineProperty(exports,"r",{enumerable:!0,get:function(){return gt}}),Object.defineProperty(exports,"rt",{enumerable:!0,get:function(){return a}}),Object.defineProperty(exports,"s",{enumerable:!0,get:function(){return ot}}),Object.defineProperty(exports,"st",{enumerable:!0,get:function(){return i}}),Object.defineProperty(exports,"t",{enumerable:!0,get:function(){return At}}),Object.defineProperty(exports,"tt",{enumerable:!0,get:function(){return ce}}),Object.defineProperty(exports,"u",{enumerable:!0,get:function(){return et}}),Object.defineProperty(exports,"v",{enumerable:!0,get:function(){return R}}),Object.defineProperty(exports,"w",{enumerable:!0,get:function(){return Ce}}),Object.defineProperty(exports,"x",{enumerable:!0,get:function(){return Re}}),Object.defineProperty(exports,"y",{enumerable:!0,get:function(){return Ge}}),Object.defineProperty(exports,"z",{enumerable:!0,get:function(){return pe}});
|
|
2
|
+
//# sourceMappingURL=floorPlan-DLe5XAx6.cjs.map
|