@ifc-lite/viewer 1.25.2 → 1.26.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.
Files changed (57) hide show
  1. package/.turbo/turbo-build.log +30 -27
  2. package/CHANGELOG.md +81 -0
  3. package/dist/assets/{basketViewActivator-CTgyKI3U.js → basketViewActivator-ZpTYWE3K.js} +6 -6
  4. package/dist/assets/{bcf-7jQby1qi.js → bcf-Ctcu_Sc2.js} +5 -5
  5. package/dist/assets/{deflate-Cfp9t1Df.js → deflate-Cnx0il6E.js} +1 -1
  6. package/dist/assets/{exporters-DfSvJPi4.js → exporters-DSq76AVM.js} +272 -245
  7. package/dist/assets/geometry.worker-0Q9qEa6p.js +1 -0
  8. package/dist/assets/{geotiff-xZoE8BkO.js → geotiff-A5UjhI6L.js} +10 -10
  9. package/dist/assets/{ids-Cu73hD0Y.js → ids-DiLcGTer.js} +21 -21
  10. package/dist/assets/{ifc-lite_bg-ksLBP5cA.wasm → ifc-lite_bg-CEZnhM2e.wasm} +0 -0
  11. package/dist/assets/index-B9Ug2EqU.css +1 -0
  12. package/dist/assets/{index-WSbA5iy6.js → index-BAH8IJVR.js} +35946 -33456
  13. package/dist/assets/{jpeg-DhwFEbqb.js → jpeg-BzSkwo5D.js} +1 -1
  14. package/dist/assets/{lerc-Dz6BXOVb.js → lerc-Cg2Rz-D5.js} +1 -1
  15. package/dist/assets/{lzw-C9z0fG2o.js → lzw-BBPPLW-0.js} +1 -1
  16. package/dist/assets/{native-bridge-RvDmzO-2.js → native-bridge-CPojOeGE.js} +1 -1
  17. package/dist/assets/{packbits-jfwifz7C.js → packbits-yLSpjW-V.js} +1 -1
  18. package/dist/assets/{parser.worker-C594dWxH.js → parser.worker-8md211IW.js} +2 -2
  19. package/dist/assets/raw-BQrAgxwT.js +1 -0
  20. package/dist/assets/{sandbox-DDSZ7rek.js → sandbox-CsRXlgCO.js} +4102 -2658
  21. package/dist/assets/{server-client-Ctk8_Bof.js → server-client-Bk4c1CPO.js} +1 -1
  22. package/dist/assets/{webimage-XFHVyVtC.js → webimage-YafxjjGr.js} +1 -1
  23. package/dist/assets/{zstd-3q5qcl5V.js → zstd-CkSLOiuu.js} +1 -1
  24. package/dist/index.html +7 -7
  25. package/package.json +7 -6
  26. package/src/components/extensions/FlavorDialog.tsx +18 -2
  27. package/src/components/extensions/FlavorListView.tsx +12 -3
  28. package/src/components/viewer/ClashBcfExportDialog.tsx +271 -0
  29. package/src/components/viewer/ClashPanel.tsx +370 -0
  30. package/src/components/viewer/ClashSettingsDialog.tsx +407 -0
  31. package/src/components/viewer/CommandPalette.tsx +14 -15
  32. package/src/components/viewer/MainToolbar.tsx +155 -175
  33. package/src/components/viewer/ViewerLayout.tsx +5 -0
  34. package/src/components/viewer/Viewport.tsx +49 -9
  35. package/src/components/viewer/ViewportContainer.tsx +45 -3
  36. package/src/components/viewer/bcf/BCFOverlay.tsx +5 -4
  37. package/src/components/viewer/useGeometryStreaming.ts +21 -1
  38. package/src/hooks/ingest/streamCleanup.test.ts +41 -0
  39. package/src/hooks/ingest/streamCleanup.ts +45 -0
  40. package/src/hooks/ingest/viewerModelIngest.ts +64 -42
  41. package/src/hooks/ingest/watchedGeometryStream.test.ts +78 -0
  42. package/src/hooks/ingest/watchedGeometryStream.ts +76 -0
  43. package/src/hooks/useAlignmentLines3D.ts +164 -0
  44. package/src/hooks/useClash.ts +420 -0
  45. package/src/hooks/useIfcFederation.ts +16 -2
  46. package/src/hooks/useIfcLoader.ts +5 -7
  47. package/src/lib/clash/persistence.ts +308 -0
  48. package/src/lib/geo/effective-georef.test.ts +66 -0
  49. package/src/services/extensions/host.ts +13 -0
  50. package/src/store/constants.ts +33 -25
  51. package/src/store/index.ts +29 -8
  52. package/src/store/slices/clashSlice.ts +251 -0
  53. package/src/store/slices/visibilitySlice.test.ts +23 -5
  54. package/src/store/slices/visibilitySlice.ts +18 -8
  55. package/dist/assets/geometry.worker-Cyn5BybV.js +0 -1
  56. package/dist/assets/index-Bws3UAkj.css +0 -1
  57. package/dist/assets/raw-R2QfzPAR.js +0 -1
@@ -1,5 +1,5 @@
1
1
 
2
- > @ifc-lite/viewer@1.25.2 build /home/runner/work/ifc-lite/ifc-lite/apps/viewer
2
+ > @ifc-lite/viewer@1.26.0 build /home/runner/work/ifc-lite/ifc-lite/apps/viewer
3
3
  > vite build
4
4
 
5
5
  vite v7.3.3 building client environment for production...
@@ -8,7 +8,6 @@ transforming...
8
8
  [plugin vite:resolve] Module "node:fs" has been externalized for browser compatibility, imported by "/home/runner/work/ifc-lite/ifc-lite/node_modules/.pnpm/@anthropic-ai+sdk@0.96.0_zod@4.4.3/node_modules/@anthropic-ai/sdk/lib/credentials/types.mjs". See https://vite.dev/guide/troubleshooting.html#module-externalized-for-browser-compatibility for more details.
9
9
  [plugin vite:resolve] Module "node:path" has been externalized for browser compatibility, imported by "/home/runner/work/ifc-lite/ifc-lite/node_modules/.pnpm/@anthropic-ai+sdk@0.96.0_zod@4.4.3/node_modules/@anthropic-ai/sdk/lib/credentials/types.mjs". See https://vite.dev/guide/troubleshooting.html#module-externalized-for-browser-compatibility for more details.
10
10
  [plugin vite:resolve] Module "node:fs" has been externalized for browser compatibility, imported by "/home/runner/work/ifc-lite/ifc-lite/node_modules/.pnpm/@anthropic-ai+sdk@0.96.0_zod@4.4.3/node_modules/@anthropic-ai/sdk/lib/credentials/credential-chain.mjs". See https://vite.dev/guide/troubleshooting.html#module-externalized-for-browser-compatibility for more details.
11
- [plugin vite:resolve] Module "node:fs" has been externalized for browser compatibility, imported by "/home/runner/work/ifc-lite/ifc-lite/node_modules/.pnpm/@anthropic-ai+sdk@0.96.0_zod@4.4.3/node_modules/@anthropic-ai/sdk/lib/credentials/identity-token.mjs". See https://vite.dev/guide/troubleshooting.html#module-externalized-for-browser-compatibility for more details.
12
11
  [plugin vite:resolve] Module "node:fs" has been externalized for browser compatibility, imported by "/home/runner/work/ifc-lite/ifc-lite/node_modules/.pnpm/@anthropic-ai+sdk@0.96.0_zod@4.4.3/node_modules/@anthropic-ai/sdk/core/credentials.mjs". See https://vite.dev/guide/troubleshooting.html#module-externalized-for-browser-compatibility for more details.
13
12
  [plugin vite:resolve] Module "node:path" has been externalized for browser compatibility, imported by "/home/runner/work/ifc-lite/ifc-lite/node_modules/.pnpm/@anthropic-ai+sdk@0.96.0_zod@4.4.3/node_modules/@anthropic-ai/sdk/core/credentials.mjs". See https://vite.dev/guide/troubleshooting.html#module-externalized-for-browser-compatibility for more details.
14
13
  [plugin vite:resolve] Module "node:fs" has been externalized for browser compatibility, imported by "/home/runner/work/ifc-lite/ifc-lite/node_modules/.pnpm/@anthropic-ai+sdk@0.96.0_zod@4.4.3/node_modules/@anthropic-ai/sdk/core/credentials.mjs". See https://vite.dev/guide/troubleshooting.html#module-externalized-for-browser-compatibility for more details.
@@ -16,11 +15,15 @@ transforming...
16
15
  [plugin vite:resolve] Module "node:path" has been externalized for browser compatibility, imported by "/home/runner/work/ifc-lite/ifc-lite/node_modules/.pnpm/@anthropic-ai+sdk@0.96.0_zod@4.4.3/node_modules/@anthropic-ai/sdk/core/credentials.mjs". See https://vite.dev/guide/troubleshooting.html#module-externalized-for-browser-compatibility for more details.
17
16
  [plugin vite:resolve] Module "node:fs" has been externalized for browser compatibility, imported by "/home/runner/work/ifc-lite/ifc-lite/node_modules/.pnpm/@anthropic-ai+sdk@0.96.0_zod@4.4.3/node_modules/@anthropic-ai/sdk/core/credentials.mjs". See https://vite.dev/guide/troubleshooting.html#module-externalized-for-browser-compatibility for more details.
18
17
  [plugin vite:resolve] Module "node:path" has been externalized for browser compatibility, imported by "/home/runner/work/ifc-lite/ifc-lite/node_modules/.pnpm/@anthropic-ai+sdk@0.96.0_zod@4.4.3/node_modules/@anthropic-ai/sdk/core/credentials.mjs". See https://vite.dev/guide/troubleshooting.html#module-externalized-for-browser-compatibility for more details.
18
+ [plugin vite:resolve] Module "node:fs" has been externalized for browser compatibility, imported by "/home/runner/work/ifc-lite/ifc-lite/node_modules/.pnpm/@anthropic-ai+sdk@0.96.0_zod@4.4.3/node_modules/@anthropic-ai/sdk/lib/credentials/identity-token.mjs". See https://vite.dev/guide/troubleshooting.html#module-externalized-for-browser-compatibility for more details.
19
19
  [plugin vite:resolve] Module "node:fs" has been externalized for browser compatibility, imported by "/home/runner/work/ifc-lite/ifc-lite/node_modules/.pnpm/@anthropic-ai+sdk@0.96.0_zod@4.4.3/node_modules/@anthropic-ai/sdk/lib/credentials/user-oauth.mjs". See https://vite.dev/guide/troubleshooting.html#module-externalized-for-browser-compatibility for more details.
20
- ✓ 4994 modules transformed.
20
+ ✓ 5027 modules transformed.
21
21
  rendering chunks...
22
22
  [plugin vite:reporter]
23
- (!) /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/store.ts is dynamically imported by /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/services/extensions/host.ts but also statically imported by /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/extensions/ExtensionDockHost.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/extensions/ExtensionToolbarSlot.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/extensions/ExtensionsPanel.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/extensions/FlavorDialog.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/extensions/IdeasPanel.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/extensions/PrivacyPanel.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/extensions/RepairQueuePanel.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/AddElementPanel.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/BCFPanel.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/BasepointOverlay.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/BasketPresentationDock.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/BulkPropertyEditor.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/CesiumOverlay.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/CesiumPlacementEditor.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/ChatPanel.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/CommandPalette.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/DataConnector.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/DesktopEntitlementBanner.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/DeviationPanel.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/DrawingSettingsPanel.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/EntityContextMenu.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/ExportChangesButton.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/ExportDialog.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/GLBExportDialog.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/GeometryEditCard.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/HierarchyPanel.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/HoverTooltip.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/LensPanel.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/MainToolbar.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/MergeLayersBanner.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/MobileToolbar.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/PointCloudClasses.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/PointCloudPanel.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/PropertiesPanel.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/PropertyEditor.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/ScriptPanel.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/SearchInline.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/SearchModal.filter.builder.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/SearchModal.filter.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/SearchModal.text.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/SearchModal.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/Section2DPanel.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/SettingsPage.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/SheetSetupPanel.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/StatusBar.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/ThemeSwitch.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/TitleBlockEditor.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/ToolOverlays.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/ViewerLayout.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/Viewport.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/ViewportContainer.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/ViewportOverlays.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/annotations/AnnotationLayer.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/bcf/BCFOverlay.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/chat/ExecutableCodeBlock.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/chat/ModelSelector.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/hierarchy/treeDataBuilder.ts, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/hierarchy/useHierarchyTree.ts, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/lists/ListPanel.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/lists/ListResultsTable.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/properties/BsddCard.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/properties/FederationAlignmentControls.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/properties/GeoreferencingPanel.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/properties/RawStepCard.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/properties/RawStepRow.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/properties/TaskEditCard.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/schedule/AnimationSettingsPopover.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/schedule/GanttPanel.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/schedule/GanttTimeline.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/schedule/GanttToolbar.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/schedule/GenerateScheduleDialog.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/schedule/schedule-utils.ts, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/schedule/useConstructionSequence.ts, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/schedule/useGanttBarDrag.ts, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/schedule/useGanttSelection3DHighlight.ts, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/schedule/useOverlayCompositor.ts, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/selectionHandlers.ts, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/tools/AddElementOverlay.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/tools/GizmoOverlay.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/tools/MeasurePanel.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/tools/SectionCapControls.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/tools/SectionPanel.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/tools/SectionVisualization.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/tools/SplitNumericInput.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/tools/SplitOverlay.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/tools/WallEndpointOverlay.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/useDuplicateShortcut.ts, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/useMouseControls.ts, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/usePointCloudLifecycle.ts, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/usePointCloudSync.ts, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/useRenderUpdates.ts, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/hooks/useActionLogger.ts, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/hooks/useBCF.ts, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/hooks/useDrawingGeneration.ts, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/hooks/useFloorplanView.ts, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/hooks/useForkExtension.ts, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/hooks/useIDS.ts, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/hooks/useIfc.ts, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/hooks/useIfcCache.ts, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/hooks/useIfcFederation.ts, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/hooks/useIfcLoader.ts, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/hooks/useIfcServer.ts, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/hooks/useKeyboardShortcuts.ts, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/hooks/useLens.ts, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/hooks/useLensDiscovery.ts, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/hooks/useLevelDisplayEffect.ts, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/hooks/useModelSelection.ts, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/hooks/useSearchIndex.ts, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/hooks/useSymbolicAnnotations.ts, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/hooks/useViewerSelectors.ts, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/lib/llm/context-builder.ts, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/services/desktop-export.ts, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/utils/loadingUtils.ts, dynamic import will not move module into another chunk.
23
+ (!) /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/lib/clash/persistence.ts is dynamically imported by /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/services/extensions/host.ts but also statically imported by /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/extensions/FlavorDialog.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/ClashSettingsDialog.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/store/slices/clashSlice.ts, dynamic import will not move module into another chunk.
24
+ 
25
+ [plugin vite:reporter]
26
+ (!) /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/store.ts is dynamically imported by /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/services/extensions/host.ts, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/services/extensions/host.ts but also statically imported by /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/extensions/ExtensionDockHost.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/extensions/ExtensionToolbarSlot.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/extensions/ExtensionsPanel.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/extensions/FlavorDialog.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/extensions/IdeasPanel.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/extensions/PrivacyPanel.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/extensions/RepairQueuePanel.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/AddElementPanel.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/BCFPanel.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/BasepointOverlay.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/BasketPresentationDock.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/BulkPropertyEditor.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/CesiumOverlay.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/CesiumPlacementEditor.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/ChatPanel.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/ClashSettingsDialog.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/CommandPalette.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/DataConnector.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/DesktopEntitlementBanner.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/DeviationPanel.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/DrawingSettingsPanel.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/EntityContextMenu.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/ExportChangesButton.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/ExportDialog.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/GLBExportDialog.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/GeometryEditCard.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/HierarchyPanel.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/HoverTooltip.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/LensPanel.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/MainToolbar.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/MergeLayersBanner.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/MobileToolbar.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/PointCloudClasses.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/PointCloudPanel.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/PropertiesPanel.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/PropertyEditor.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/ScriptPanel.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/SearchInline.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/SearchModal.filter.builder.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/SearchModal.filter.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/SearchModal.text.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/SearchModal.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/Section2DPanel.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/SettingsPage.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/SheetSetupPanel.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/StatusBar.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/ThemeSwitch.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/TitleBlockEditor.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/ToolOverlays.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/ViewerLayout.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/Viewport.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/ViewportContainer.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/ViewportOverlays.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/annotations/AnnotationLayer.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/bcf/BCFOverlay.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/chat/ExecutableCodeBlock.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/chat/ModelSelector.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/hierarchy/treeDataBuilder.ts, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/hierarchy/useHierarchyTree.ts, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/lists/ListPanel.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/lists/ListResultsTable.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/properties/BsddCard.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/properties/FederationAlignmentControls.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/properties/GeoreferencingPanel.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/properties/RawStepCard.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/properties/RawStepRow.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/properties/TaskEditCard.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/schedule/AnimationSettingsPopover.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/schedule/GanttPanel.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/schedule/GanttTimeline.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/schedule/GanttToolbar.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/schedule/GenerateScheduleDialog.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/schedule/schedule-utils.ts, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/schedule/useConstructionSequence.ts, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/schedule/useGanttBarDrag.ts, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/schedule/useGanttSelection3DHighlight.ts, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/schedule/useOverlayCompositor.ts, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/selectionHandlers.ts, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/tools/AddElementOverlay.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/tools/GizmoOverlay.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/tools/MeasurePanel.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/tools/SectionCapControls.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/tools/SectionPanel.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/tools/SectionVisualization.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/tools/SplitNumericInput.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/tools/SplitOverlay.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/tools/WallEndpointOverlay.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/useDuplicateShortcut.ts, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/useMouseControls.ts, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/usePointCloudLifecycle.ts, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/usePointCloudSync.ts, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/useRenderUpdates.ts, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/hooks/useActionLogger.ts, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/hooks/useAlignmentLines3D.ts, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/hooks/useBCF.ts, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/hooks/useClash.ts, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/hooks/useDrawingGeneration.ts, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/hooks/useFloorplanView.ts, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/hooks/useForkExtension.ts, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/hooks/useIDS.ts, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/hooks/useIfc.ts, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/hooks/useIfcCache.ts, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/hooks/useIfcFederation.ts, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/hooks/useIfcLoader.ts, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/hooks/useIfcServer.ts, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/hooks/useKeyboardShortcuts.ts, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/hooks/useLens.ts, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/hooks/useLensDiscovery.ts, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/hooks/useLevelDisplayEffect.ts, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/hooks/useModelSelection.ts, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/hooks/useSearchIndex.ts, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/hooks/useSymbolicAnnotations.ts, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/hooks/useViewerSelectors.ts, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/lib/llm/context-builder.ts, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/services/desktop-export.ts, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/utils/loadingUtils.ts, dynamic import will not move module into another chunk.
24
27
  
25
28
  [plugin vite:reporter]
26
29
  (!) /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/utils/ifcConfig.ts is dynamically imported by /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/utils/acquireFileBuffer.ts but also statically imported by /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/hooks/useIfcFederation.ts, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/hooks/useIfcLoader.ts, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/hooks/useIfcServer.ts, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/services/cacheService.ts, dynamic import will not move module into another chunk.
@@ -29,7 +32,7 @@ rendering chunks...
29
32
  (!) /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/services/desktop-cache.ts is dynamically imported by /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/hooks/useIfcLoader.ts, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/hooks/useIfcLoader.ts, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/hooks/useIfcLoader.ts, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/hooks/useIfcLoader.ts, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/hooks/useIfcLoader.ts, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/hooks/useIfcLoader.ts, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/services/cacheService.ts but also statically imported by /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/services/desktop-native-metadata.ts, dynamic import will not move module into another chunk.
30
33
  
31
34
  [plugin vite:reporter]
32
- (!) /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/ui/toast.tsx is dynamically imported by /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/hooks/useKeyboardShortcuts.ts but also statically imported by /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/App.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/extensions/AuditLogPanel.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/extensions/BundlePreview.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/extensions/ExtensionDockHost.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/extensions/ExtensionToolbarSlot.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/extensions/ExtensionsPanel.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/extensions/FlavorDialog.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/extensions/FlavorMergeDialog.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/extensions/IdeasPanel.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/extensions/PrivacyPanel.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/extensions/PromoteToolDialog.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/extensions/RepairQueuePanel.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/AddElementPanel.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/CesiumPlacementEditor.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/ChatPanel.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/CommandPalette.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/EntityContextMenu.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/ExportChangesButton.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/ExportDialog.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/GLBExportDialog.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/GeometryEditCard.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/MainToolbar.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/MobileToolbar.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/ScriptPanel.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/SettingsPage.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/ViewportContainer.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/chat/ByokKeyModal.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/properties/FederationAlignmentControls.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/properties/GeoreferencingPanel.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/schedule/GanttToolbar.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/selectionHandlers.ts, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/tools/SplitNumericInput.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/useDuplicateShortcut.ts, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/useGeometryStreaming.ts, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/hooks/useForkExtension.ts, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/hooks/useIfcFederation.ts, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/hooks/usePrivacyDisclosure.ts, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/hooks/useRunExtensionTests.ts, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/sdk/ExtensionHostProvider.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/services/desktop-export.ts, dynamic import will not move module into another chunk.
35
+ (!) /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/ui/toast.tsx is dynamically imported by /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/hooks/useKeyboardShortcuts.ts but also statically imported by /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/App.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/extensions/AuditLogPanel.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/extensions/BundlePreview.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/extensions/ExtensionDockHost.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/extensions/ExtensionToolbarSlot.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/extensions/ExtensionsPanel.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/extensions/FlavorDialog.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/extensions/FlavorMergeDialog.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/extensions/IdeasPanel.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/extensions/PrivacyPanel.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/extensions/PromoteToolDialog.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/extensions/RepairQueuePanel.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/AddElementPanel.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/CesiumPlacementEditor.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/ChatPanel.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/ClashBcfExportDialog.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/ClashSettingsDialog.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/CommandPalette.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/EntityContextMenu.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/ExportChangesButton.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/ExportDialog.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/GLBExportDialog.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/GeometryEditCard.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/MainToolbar.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/MobileToolbar.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/ScriptPanel.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/SettingsPage.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/ViewportContainer.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/chat/ByokKeyModal.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/properties/FederationAlignmentControls.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/properties/GeoreferencingPanel.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/schedule/GanttToolbar.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/selectionHandlers.ts, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/tools/SplitNumericInput.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/useDuplicateShortcut.ts, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/useGeometryStreaming.ts, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/hooks/useForkExtension.ts, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/hooks/useIfcFederation.ts, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/hooks/usePrivacyDisclosure.ts, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/hooks/useRunExtensionTests.ts, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/sdk/ExtensionHostProvider.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/services/desktop-export.ts, dynamic import will not move module into another chunk.
33
36
  
34
37
  [plugin vite:reporter]
35
38
  (!) /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/selectionHandlers.ts is dynamically imported by /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/hooks/useKeyboardShortcuts.ts but also statically imported by /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/tools/WallEndpointOverlay.tsx, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/useMouseControls.ts, dynamic import will not move module into another chunk.
@@ -46,61 +49,61 @@ computing gzip size...
46
49
  dist/assets/ply-source-C8jjyzxE.js  6.77 kB
47
50
  dist/assets/pcd-source-Ck0UnVDn.js  7.31 kB
48
51
  dist/assets/e57-source-CQHxE8n3.js  13.46 kB
49
- dist/assets/geometry.worker-Cyn5BybV.js  31.45 kB
52
+ dist/assets/geometry.worker-0Q9qEa6p.js  31.79 kB
50
53
  dist/assets/index-DMho-JA0.js  53.15 kB
51
54
  dist/assets/laz-perf-CFJp03W6.wasm  214.35 kB │ gzip: 73.76 kB
52
55
  dist/assets/emscripten-module-uFzwHH0Y.wasm  503.13 kB │ gzip: 234.04 kB
53
56
  dist/assets/emscripten-module-B1g2L2eS.wasm  1,027.52 kB │ gzip: 364.87 kB
54
57
  dist/assets/emscripten-module-ZrHFMo7O.wasm  1,218.63 kB │ gzip: 456.85 kB
55
58
  dist/assets/emscripten-module-DHbYPfAp.wasm  1,510.75 kB │ gzip: 497.65 kB
56
- dist/assets/parser.worker-C594dWxH.js  1,594.15 kB
57
- dist/assets/ifc-lite_bg-ksLBP5cA.wasm  1,707.59 kB │ gzip: 615.76 kB
59
+ dist/assets/parser.worker-8md211IW.js  1,594.49 kB
60
+ dist/assets/ifc-lite_bg-CEZnhM2e.wasm  1,754.65 kB │ gzip: 633.76 kB
58
61
  dist/assets/arrow2_bg-4Y7xYo54.wasm  5,000.39 kB │ gzip: 1,544.22 kB
59
62
  dist/assets/parquet_wasm_bg-DcKVfvto.wasm  6,626.29 kB │ gzip: 1,944.12 kB
60
63
  dist/assets/esbuild-CzsZLPr0.wasm 13,918.74 kB │ gzip: 3,765.48 kB
61
64
  dist/assets/cesium-ADbP7waU.css  24.30 kB │ gzip: 5.49 kB
62
- dist/assets/index-Bws3UAkj.css  258.08 kB │ gzip: 37.31 kB
65
+ dist/assets/index-B9Ug2EqU.css  258.56 kB │ gzip: 37.41 kB
63
66
  dist/assets/__vite-browser-external-B1O5LaIO.js  0.03 kB │ gzip: 0.05 kB
64
67
  dist/assets/inline-worker-BpBzlmd6.js  0.05 kB │ gzip: 0.07 kB
65
68
  dist/assets/tauri-dialog-stub-r7Wksg7o.js  0.05 kB │ gzip: 0.07 kB
66
69
  dist/assets/esbuild-FgU11_Eg.js  0.06 kB │ gzip: 0.08 kB
67
70
  dist/assets/tauri-core-stub-D8Fa-u43.js  0.11 kB │ gzip: 0.12 kB
68
71
  dist/assets/tauri-fs-stub-BdeRC7aK.js  0.13 kB │ gzip: 0.13 kB
69
- dist/assets/raw-R2QfzPAR.js  0.21 kB │ gzip: 0.18 kB
70
- dist/assets/deflate-Cfp9t1Df.js  0.28 kB │ gzip: 0.22 kB
71
- dist/assets/packbits-jfwifz7C.js  0.45 kB │ gzip: 0.32 kB
72
- dist/assets/webimage-XFHVyVtC.js  1.06 kB │ gzip: 0.60 kB
72
+ dist/assets/raw-BQrAgxwT.js  0.21 kB │ gzip: 0.18 kB
73
+ dist/assets/deflate-Cnx0il6E.js  0.28 kB │ gzip: 0.22 kB
74
+ dist/assets/packbits-yLSpjW-V.js  0.45 kB │ gzip: 0.32 kB
75
+ dist/assets/webimage-YafxjjGr.js  1.06 kB │ gzip: 0.60 kB
73
76
  dist/assets/event-B0kAzHa-.js  1.49 kB │ gzip: 0.68 kB
74
- dist/assets/lzw-C9z0fG2o.js  1.60 kB │ gzip: 0.91 kB
75
- dist/assets/basketViewActivator-CTgyKI3U.js  2.28 kB │ gzip: 0.80 kB
77
+ dist/assets/lzw-BBPPLW-0.js  1.60 kB │ gzip: 0.91 kB
78
+ dist/assets/basketViewActivator-ZpTYWE3K.js  2.28 kB │ gzip: 0.80 kB
76
79
  dist/assets/ifc-cache-BAN4vcd4.js  2.77 kB │ gzip: 0.94 kB
77
80
  dist/assets/ffi-Boa1QuFa.js  6.32 kB │ gzip: 1.00 kB
78
81
  dist/assets/emscripten-module.browser-BLJD5hhE.js  9.16 kB │ gzip: 4.19 kB
79
82
  dist/assets/lens-PYsLu_MA.js  9.37 kB │ gzip: 2.91 kB
80
- dist/assets/jpeg-DhwFEbqb.js  11.28 kB │ gzip: 4.27 kB
81
- dist/assets/native-bridge-RvDmzO-2.js  18.61 kB │ gzip: 3.76 kB
83
+ dist/assets/jpeg-BzSkwo5D.js  11.28 kB │ gzip: 4.27 kB
84
+ dist/assets/native-bridge-CPojOeGE.js  18.61 kB │ gzip: 3.76 kB
82
85
  dist/assets/pako.esm-Cram60i4.js  21.58 kB │ gzip: 7.64 kB
83
86
  dist/assets/parquet-CEXmQNRO.js  29.67 kB │ gzip: 6.89 kB
84
- dist/assets/server-client-Ctk8_Bof.js  31.43 kB │ gzip: 7.06 kB
85
- dist/assets/bcf-7jQby1qi.js  37.89 kB │ gzip: 11.39 kB
87
+ dist/assets/server-client-Bk4c1CPO.js  31.43 kB │ gzip: 7.05 kB
88
+ dist/assets/bcf-Ctcu_Sc2.js  38.06 kB │ gzip: 11.46 kB
86
89
  dist/assets/browser-DXS29_v9.js  70.26 kB │ gzip: 19.95 kB
87
90
  dist/assets/drawing-2d-C71b8Ugx.js  71.89 kB │ gzip: 21.08 kB
88
- dist/assets/zstd-3q5qcl5V.js  81.19 kB │ gzip: 32.34 kB
91
+ dist/assets/zstd-CkSLOiuu.js  81.19 kB │ gzip: 32.34 kB
89
92
  dist/assets/zip-BJqVbRkU.js  96.95 kB │ gzip: 29.94 kB
90
- dist/assets/lerc-Dz6BXOVb.js  97.20 kB │ gzip: 37.62 kB
91
- dist/assets/ids-Cu73hD0Y.js  164.18 kB │ gzip: 29.22 kB
92
- dist/assets/exporters-DfSvJPi4.js  188.05 kB │ gzip: 35.95 kB
93
+ dist/assets/lerc-Cg2Rz-D5.js  97.20 kB │ gzip: 37.62 kB
94
+ dist/assets/ids-DiLcGTer.js  164.18 kB │ gzip: 29.21 kB
95
+ dist/assets/exporters-DSq76AVM.js  189.41 kB │ gzip: 36.07 kB
93
96
  dist/assets/arrow-CXWhTnNT.js  208.86 kB │ gzip: 50.09 kB
94
- dist/assets/geotiff-xZoE8BkO.js  366.67 kB │ gzip: 118.41 kB
97
+ dist/assets/geotiff-A5UjhI6L.js  366.67 kB │ gzip: 118.40 kB
95
98
  dist/assets/three-CQBzFWY2.js  534.00 kB │ gzip: 133.77 kB
96
99
  dist/assets/maplibre-gl-Do6O5tDc.js  1,053.34 kB │ gzip: 284.74 kB
97
100
  dist/assets/epsg-index.generated-BjJrt_0S.js  4,295.95 kB │ gzip: 440.44 kB
98
101
  dist/assets/cesium-BoVuJvTC.js  4,778.78 kB │ gzip: 1,320.18 kB
99
- dist/assets/index-WSbA5iy6.js  7,511.97 kB │ gzip: 1,366.50 kB
100
- dist/assets/sandbox-DDSZ7rek.js  8,489.85 kB │ gzip: 513.90 kB
102
+ dist/assets/index-BAH8IJVR.js  7,633.13 kB │ gzip: 1,383.68 kB
103
+ dist/assets/sandbox-CsRXlgCO.js  8,537.83 kB │ gzip: 524.59 kB
101
104
  
102
105
  (!) Some chunks are larger than 6000 kB after minification. Consider:
103
106
  - Using dynamic import() to code-split the application
104
107
  - Use build.rollupOptions.output.manualChunks to improve chunking: https://rollupjs.org/configuration-options/#output-manualchunks
105
108
  - Adjust chunk size limit for this warning via build.chunkSizeWarningLimit.
106
- ✓ built in 1m 20s
109
+ ✓ built in 1m 22s
package/CHANGELOG.md CHANGED
@@ -1,5 +1,86 @@
1
1
  # @ifc-lite/viewer
2
2
 
3
+ ## 1.26.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#891](https://github.com/LTplus-AG/ifc-lite/pull/891) [`d6b8986`](https://github.com/LTplus-AG/ifc-lite/commit/d6b89866b4c058531ce0c5c7472a297adc6580a8) Thanks [@louistrue](https://github.com/louistrue)! - Add representation-agnostic clash detection.
8
+
9
+ `@ifc-lite/clash` is a new package: a source-agnostic clash core (STEP/IFCX
10
+ adapters, BVH broad phase, exact triangle-intersection narrow phase, hard /
11
+ clearance / touch classification) with a pluggable TS reference kernel and a
12
+ Rust/WASM kernel kept in lockstep by a differential test. Results group into a
13
+ _manageable_ set of BCF topics (deterministic topic GUIDs, caps-with-transparency,
14
+ framing viewpoints, A/B coloring, optional snapshots) and round-trip status back.
15
+
16
+ Surfaced through the existing tools:
17
+
18
+ - `@ifc-lite/clash` — `rulesFromPresets(presets, mode, clearance?, reportTouch?)` builds
19
+ runnable rules from any preset list (the discipline matrix is this over the built-ins),
20
+ so hosts can run a user-curated rule set.
21
+ - `@ifc-lite/viewer` — an interactive clash panel (run detection / discipline matrix /
22
+ presets, A/B highlight + camera framing, configurable settings & custom rules, a
23
+ controllable BCF export with optional rendered snapshots).
24
+ - `@ifc-lite/sdk` — a `clash` namespace (`run`, `matrix`, `group`, presets).
25
+ - `@ifc-lite/cli` — `ifc-lite clash <file>` with `--a/--b`, `--mode`, `--matrix`,
26
+ `--clearance`, `--bcf`.
27
+ - `@ifc-lite/mcp` — `clash_check` (omit selectors for a whole-model self-clash)
28
+ and `clash_matrix`.
29
+
30
+ The discipline matrix now threads a `clearance` value onto its rules, so
31
+ `--matrix --mode clearance --clearance N` (and the SDK/MCP equivalents) report
32
+ violations instead of silently dropping the override.
33
+
34
+ ### Patch Changes
35
+
36
+ - [#895](https://github.com/LTplus-AG/ifc-lite/pull/895) [`94d9116`](https://github.com/LTplus-AG/ifc-lite/commit/94d91161abc58b5804bd979d841d7475714ee5ad) Thanks [@louistrue](https://github.com/louistrue)! - Fix model federation: two models now load co-located at the correct scale
37
+ instead of one being flung ~20 km away, dwarfed, or hanging on "Processing
38
+ geometry".
39
+
40
+ **Federation alignment (the regression).** When a model has no
41
+ `IfcMapConversion` we synthesise a `source: 'siteLocation'` georeference from its
42
+ `IfcSite` `RefLatitude`/`RefLongitude`/`RefElevation` so it can still be pinned on
43
+ the location map. Since [#658](https://github.com/LTplus-AG/ifc-lite/issues/658) the federated add-model path treated that synthetic
44
+ georef as real and ran it through the projected-CRS affine alignment — but its
45
+ coordinates are geographic degrees plus a raw, un-unit-scaled site elevation, not
46
+ projected metres. For the BIMcollab ARC/STR sample (which share a site GUID but
47
+ carry `RefElevation` `0` vs `20000` mm) the height term placed the architectural
48
+ model ~20 km below the structural one. Federation alignment now requires _true_
49
+ georeferencing (`IfcMapConversion` + `IfcProjectedCRS`, via
50
+ `hasStandardGeoreferencing`); site-location-only models stay in their own local
51
+ frames where they already overlay correctly.
52
+
53
+ **Unit scale.** The streaming geometry pre-pass (`buildPrePassStreaming`)
54
+ resolved `unitScale` from a _partial_ entity index — only the rows up to the
55
+ first `IFCPROJECT`. Many real exports (Revit) place `IFCPROJECT` and its
56
+ `IFCUNITASSIGNMENT` _after_ the bulk of the geometry, so the assigned
57
+ `IFCSIUNIT` wasn't indexed yet, `decode_by_id` failed, and resolution silently
58
+ fell back to the metres default — rendering a millimetre model 1000× too large.
59
+ The pre-pass now tries the partial index first (fast path for unit-first files)
60
+ and falls back to a _complete_ index when the unit chain isn't yet decodable, so
61
+ the scale is correct regardless of entity ordering. New
62
+ `try_extract_length_unit_scale` in `ifc-lite-core` distinguishes "not yet
63
+ resolvable from this index" from a genuine metres default; covered by unit tests.
64
+
65
+ **Ingest watchdog (viewer).** The added-model ingest path
66
+ (`parseStepBufferViewerModel`) gains the same size-aware stream watchdog the
67
+ single-model loader already had, so a stalled geometry stream surfaces a
68
+ recoverable error instead of hanging forever at "Processing geometry (N meshes)".
69
+ The watchdog plus its iterator teardown are extracted into a shared
70
+ `watchedGeometryStream` / `boundedIteratorReturn` helper (used by both loaders):
71
+ the teardown is now bounded so an abandoned generator parked on the very stall
72
+ the watchdog escaped can't re-wedge cleanup and swallow the timeout error.
73
+
74
+ **Camera framing.** When a second model is added, the viewport now unions the
75
+ bounds of all visible models and refits, so federated models are framed together
76
+ instead of the camera staying on the first model.
77
+
78
+ - Updated dependencies [[`d6b8986`](https://github.com/LTplus-AG/ifc-lite/commit/d6b89866b4c058531ce0c5c7472a297adc6580a8), [`94d9116`](https://github.com/LTplus-AG/ifc-lite/commit/94d91161abc58b5804bd979d841d7475714ee5ad)]:
79
+ - @ifc-lite/clash@1.1.0
80
+ - @ifc-lite/sdk@1.17.0
81
+ - @ifc-lite/mcp@0.3.0
82
+ - @ifc-lite/wasm@2.1.1
83
+
3
84
  ## 1.25.2
4
85
 
5
86
  ### Patch Changes
@@ -1,13 +1,13 @@
1
- import { u as o, __tla as __tla_0 } from "./index-WSbA5iy6.js";
1
+ import { u as o, __tla as __tla_0 } from "./index-BAH8IJVR.js";
2
2
  import "./zip-BJqVbRkU.js";
3
3
  import "./arrow-CXWhTnNT.js";
4
- import { __tla as __tla_1 } from "./sandbox-DDSZ7rek.js";
4
+ import { __tla as __tla_1 } from "./sandbox-CsRXlgCO.js";
5
5
  import "./lens-PYsLu_MA.js";
6
6
  import "./drawing-2d-C71b8Ugx.js";
7
- import "./bcf-7jQby1qi.js";
8
- import { __tla as __tla_2 } from "./exporters-DfSvJPi4.js";
9
- import { __tla as __tla_3 } from "./server-client-Ctk8_Bof.js";
10
- import { __tla as __tla_4 } from "./ids-Cu73hD0Y.js";
7
+ import "./bcf-Ctcu_Sc2.js";
8
+ import { __tla as __tla_2 } from "./exporters-DSq76AVM.js";
9
+ import { __tla as __tla_3 } from "./server-client-Bk4c1CPO.js";
10
+ import { __tla as __tla_4 } from "./ids-DiLcGTer.js";
11
11
  import "./three-CQBzFWY2.js";
12
12
  let v;
13
13
  let __tla = Promise.all([
@@ -1,4 +1,4 @@
1
- import{J as X}from"./zip-BJqVbRkU.js";import{ag as C}from"./sandbox-DDSZ7rek.js";async function te(t){const e=await X.loadAsync(t),i=await Q(e),{projectId:o,name:n,extensions:s}=await tt(e),a=await et(e);return{version:i.versionId,projectId:o,name:n,topics:a,extensions:s}}async function Q(t){const e=t.file("bcf.version");if(!e)throw new Error("Invalid BCF file: missing bcf.version");const o=(await e.async("string")).match(/VersionId="([^"]+)"/);if(!o)throw new Error("Invalid BCF version file: could not parse VersionId");const n=o[1];return n!=="2.1"&&n!=="3.0"&&console.warn(`Unsupported BCF version: ${n}, treating as 2.1`),{versionId:n==="3.0"?"3.0":"2.1",detailedVersion:o[1]}}async function tt(t){const e=t.file("project.bcfp");if(!e)return{};const i=await e.async("string"),o=i.match(/ProjectId="([^"]+)"/),n=i.match(/<Name>([^<]+)<\/Name>/);return{projectId:o?.[1],name:n?.[1]}}async function et(t){const e=new Map,i=new Set;t.forEach(o=>{const n=o.match(/^([^/]+)\/markup\.bcf$/i);n&&i.add(n[1])});for(const o of i)try{const n=await it(t,o);n&&e.set(n.guid,n)}catch(n){console.warn(`Failed to parse topic ${o}:`,n)}return e}async function it(t,e){const i=t.file(`${e}/markup.bcf`);if(!i)return null;const o=await i.async("string"),n=o.match(/<Topic\s+Guid="([^"]+)"[^>]*>([\s\S]*?)<\/Topic>/);if(!n)return console.warn(`Invalid markup.bcf in ${e}: missing Topic element`),null;const s=n[1],a=n[2],r=o.match(/<Topic[^>]*TopicType="([^"]+)"/),c=o.match(/<Topic[^>]*TopicStatus="([^"]+)"/),l=h(a,"Title")||"Untitled",p=h(a,"Description"),f=h(a,"Priority"),m=h(a,"Index"),u=h(a,"CreationDate")||new Date().toISOString(),g=h(a,"CreationAuthor")||"Unknown",d=h(a,"ModifiedDate"),x=h(a,"ModifiedAuthor"),w=h(a,"DueDate"),b=h(a,"AssignedTo"),v=h(a,"Stage"),T=[],q=a.matchAll(/<Labels>([^<]+)<\/Labels>/g);for(const A of q)T.push(A[1]);const H=ot(a),O=nt(a),I=[],W=a.matchAll(/<RelatedTopic\s+Guid="([^"]+)"/g);for(const A of W)I.push(A[1]);const J=st(o),K=await at(t,e,o);return{guid:s,title:l,description:p,topicType:r?.[1],topicStatus:c?.[1],priority:f,index:m?parseInt(m,10):void 0,creationDate:u,creationAuthor:g,modifiedDate:d,modifiedAuthor:x,dueDate:w,assignedTo:b,stage:v,labels:T.length>0?T:void 0,bimSnippet:H,documentReferences:O.length>0?O:void 0,relatedTopics:I.length>0?I:void 0,comments:J,viewpoints:K}}function h(t,e){return t.match(new RegExp(`<${e}>([^<]*)<\\/${e}>`))?.[1]}function ot(t){const e=t.match(/<BimSnippet\s+SnippetType="([^"]+)"[^>]*>([\s\S]*?)<\/BimSnippet>/);if(!e)return;const i=e[0].match(/isExternal="([^"]+)"/),o=h(e[2],"Reference"),n=h(e[2],"ReferenceSchema");return{snippetType:e[1],isExternal:i?.[1]==="true",reference:o||"",referenceSchema:n}}function nt(t){const e=[],i=t.matchAll(/<DocumentReference[^>]*>([\s\S]*?)<\/DocumentReference>/g);for(const o of i){const n=o[0].match(/Guid="([^"]+)"/),s=o[0].match(/isExternal="([^"]+)"/),a=h(o[1],"ReferencedDocument"),r=h(o[1],"Description");a&&e.push({guid:n?.[1],isExternal:s?.[1]==="true",referencedDocument:a,description:r})}return e}function st(t){const e=[],i=t.matchAll(/<Comment\s+Guid="([^"]+)"[^>]*>([\s\S]*?)<\/Comment>/g);for(const o of i){const n=o[1],s=o[2],a=h(s,"Date")||new Date().toISOString(),r=h(s,"Author")||"Unknown",c=h(s,"Comment")||"",l=h(s,"ModifiedDate"),p=h(s,"ModifiedAuthor"),f=s.match(/<Viewpoint\s+Guid="([^"]+)"/);e.push({guid:n,date:a,author:r,comment:c,viewpointGuid:f?.[1],modifiedDate:l,modifiedAuthor:p})}return e}async function at(t,e,i){const o=[],n=new Map,s=/<Viewpoint\s+Guid="([^"]+)"[^>]*>([\s\S]*?)<\/Viewpoint>/g;for(const c of i.matchAll(s)){const l=c[1],p=c[2],f=p.match(/<Viewpoint>([^<]+)<\/Viewpoint>/),m=p.match(/<Snapshot>([^<]+)<\/Snapshot>/);n.set(l,{viewpointFile:f?.[1],snapshotFile:m?.[1]})}const a=i.matchAll(/<Viewpoint\s+Guid="([^"]+)"[^>]*\/>/g);for(const c of a)n.has(c[1])||n.set(c[1],{});const r=[];t.forEach(c=>{c.startsWith(`${e}/`)&&c.endsWith(".bcfv")&&r.push(c)});for(const c of r)try{const l=t.file(c);if(!l)continue;const p=await l.async("string"),f=ct(p);if(f){const m=n.get(f.guid);let u=null,g="png";if(m?.snapshotFile){const d=`${e}/${m.snapshotFile}`;u=t.file(d),(m.snapshotFile.toLowerCase().endsWith(".jpg")||m.snapshotFile.toLowerCase().endsWith(".jpeg"))&&(g="jpeg")}if(!u){const d=c.replace(".bcfv",""),x=d.replace(/Viewpoint_/i,"Snapshot_"),w=d.replace(/_viewpoint$/i,"_snapshot"),b=[`${x}.png`,`${w}.png`,`${d}.png`,`${e}/snapshot.png`,`${x}.jpg`,`${w}.jpg`,`${d}.jpg`,`${e}/snapshot.jpg`];for(const v of b)if(u=t.file(v),u){(v.toLowerCase().endsWith(".jpg")||v.toLowerCase().endsWith(".jpeg"))&&(g="jpeg");break}}if(u){const d=await u.async("uint8array");f.snapshotData=d,f.snapshot=`data:image/${g};base64,${U(d)}`}o.push(f)}}catch(l){console.warn(`Failed to parse viewpoint ${c}:`,l)}if(o.length===0){const c=t.file(`${e}/snapshot.png`)||t.file(`${e}/snapshot.jpg`);if(c){const l=c.name.toLowerCase().endsWith(".jpg"),p=await c.async("uint8array");o.push({guid:e,snapshot:`data:image/${l?"jpeg":"png"};base64,${U(p)}`,snapshotData:p})}}return o}function ct(t){const i=t.match(/<VisualizationInfo[^>]+Guid="([^"]+)"/)?.[1]||crypto.randomUUID?.()||`vp-${Date.now()}`,o=rt(t),n=lt(t),s=pt(t),a=mt(t),r=dt(t),c=ht(t);return{guid:i,perspectiveCamera:o,orthogonalCamera:n,components:s,lines:a.length>0?a:void 0,clippingPlanes:r.length>0?r:void 0,bitmaps:c.length>0?c:void 0}}function rt(t){const e=t.match(/<PerspectiveCamera>([\s\S]*?)<\/PerspectiveCamera>/);if(!e)return;const i=e[1],o=V(i,"CameraViewPoint"),n=M(i,"CameraDirection"),s=M(i,"CameraUpVector"),a=h(i,"FieldOfView");if(!(!o||!n||!s||!a))return{cameraViewPoint:o,cameraDirection:n,cameraUpVector:s,fieldOfView:parseFloat(a)}}function lt(t){const e=t.match(/<OrthogonalCamera>([\s\S]*?)<\/OrthogonalCamera>/);if(!e)return;const i=e[1],o=V(i,"CameraViewPoint"),n=M(i,"CameraDirection"),s=M(i,"CameraUpVector"),a=h(i,"ViewToWorldScale");if(!(!o||!n||!s||!a))return{cameraViewPoint:o,cameraDirection:n,cameraUpVector:s,viewToWorldScale:parseFloat(a)}}function V(t,e){const i=t.match(new RegExp(`<${e}>([\\s\\S]*?)<\\/${e}>`));if(!i)return;const o=h(i[1],"X"),n=h(i[1],"Y"),s=h(i[1],"Z");if(!(o===void 0||n===void 0||s===void 0))return{x:parseFloat(o),y:parseFloat(n),z:parseFloat(s)}}function M(t,e){return V(t,e)}function pt(t){const e=t.match(/<Components>([\s\S]*?)<\/Components>/);if(!e)return;const i=e[1],o=B(i,"Selection"),n=ft(i),s=ut(i);if(!(!o&&!n&&!s))return{selection:o?.length?o:void 0,visibility:n,coloring:s?.length?s:void 0}}function B(t,e){const i=t.match(new RegExp(`<${e}>([\\s\\S]*?)<\\/${e}>`));if(!i)return;const o=[],n=i[1].matchAll(/<Component[^>]*(?:\/>|>[\s\S]*?<\/Component>)/g);for(const s of n){const a=_(s[0]);a&&o.push(a)}return o.length>0?o:void 0}function _(t){const e=t.match(/IfcGuid="([^"]+)"/),i=t.match(/AuthoringToolId="([^"]+)"/),o=t.match(/OriginatingSystem="([^"]+)"/);if(!(!e&&!i))return{ifcGuid:e?.[1],authoringToolId:i?.[1],originatingSystem:o?.[1]}}function ft(t){const e=t.match(/<Visibility[^>]*>([\s\S]*?)<\/Visibility>/);if(!e)return;const o=t.match(/DefaultVisibility="([^"]+)"/)?.[1]!=="false",n=B(e[1],"Exceptions");return{defaultVisibility:o,exceptions:n}}function ut(t){const e=t.match(/<Coloring>([\s\S]*?)<\/Coloring>/);if(!e)return;const i=[],o=e[1].matchAll(/<Color\s+Color="([^"]+)"[^>]*>([\s\S]*?)<\/Color>/g);for(const n of o){const s=n[1],a=[],r=n[2].matchAll(/<Component[^>]*(?:\/>|>[\s\S]*?<\/Component>)/g);for(const c of r){const l=_(c[0]);l&&a.push(l)}a.length>0&&i.push({color:s,components:a})}return i.length>0?i:void 0}function mt(t){const e=[],i=t.match(/<Lines>([\s\S]*?)<\/Lines>/);if(!i)return e;const o=i[1].matchAll(/<Line>([\s\S]*?)<\/Line>/g);for(const n of o){const s=V(n[1],"StartPoint"),a=V(n[1],"EndPoint");s&&a&&e.push({startPoint:s,endPoint:a})}return e}function dt(t){const e=[],i=t.match(/<ClippingPlanes>([\s\S]*?)<\/ClippingPlanes>/);if(!i)return e;const o=i[1].matchAll(/<ClippingPlane>([\s\S]*?)<\/ClippingPlane>/g);for(const n of o){const s=V(n[1],"Location"),a=M(n[1],"Direction");s&&a&&e.push({location:s,direction:a})}return e}function ht(t){const e=[],i=t.match(/<Bitmaps>([\s\S]*?)<\/Bitmaps>/);if(!i)return e;const o=i[1].matchAll(/<Bitmap>([\s\S]*?)<\/Bitmap>/g);for(const n of o){const s=h(n[1],"Format")||h(n[1],"Bitmap"),a=h(n[1],"Reference"),r=V(n[1],"Location"),c=M(n[1],"Normal"),l=M(n[1],"Up"),p=h(n[1],"Height");s&&a&&r&&c&&l&&p&&e.push({format:s.toUpperCase()==="JPG"?"JPG":"PNG",reference:a,location:r,normal:c,up:l,height:parseFloat(p)})}return e}function U(t){let e="";for(let i=0;i<t.length;i++)e+=String.fromCharCode(t[i]);return btoa(e)}async function ee(t){const e=new X;gt(e,t.version),(t.projectId||t.name)&&yt(e,t);for(const[i,o]of t.topics)await xt(e,o);return e.generateAsync({type:"blob",compression:"DEFLATE",compressionOptions:{level:6}})}function gt(t,e){const i=`<?xml version="1.0" encoding="UTF-8"?>
1
+ import{J as X}from"./zip-BJqVbRkU.js";import{al as C}from"./sandbox-CsRXlgCO.js";async function te(t){const e=await X.loadAsync(t),i=await Q(e),{projectId:o,name:n,extensions:s}=await tt(e),a=await et(e);return{version:i.versionId,projectId:o,name:n,topics:a,extensions:s}}async function Q(t){const e=t.file("bcf.version");if(!e)throw new Error("Invalid BCF file: missing bcf.version");const o=(await e.async("string")).match(/VersionId="([^"]+)"/);if(!o)throw new Error("Invalid BCF version file: could not parse VersionId");const n=o[1];return n!=="2.1"&&n!=="3.0"&&console.warn(`Unsupported BCF version: ${n}, treating as 2.1`),{versionId:n==="3.0"?"3.0":"2.1",detailedVersion:o[1]}}async function tt(t){const e=t.file("project.bcfp");if(!e)return{};const i=await e.async("string"),o=i.match(/ProjectId="([^"]+)"/),n=i.match(/<Name>([^<]+)<\/Name>/);return{projectId:o?.[1],name:n?.[1]}}async function et(t){const e=new Map,i=new Set;t.forEach(o=>{const n=o.match(/^([^/]+)\/markup\.bcf$/i);n&&i.add(n[1])});for(const o of i)try{const n=await it(t,o);n&&e.set(n.guid,n)}catch(n){console.warn(`Failed to parse topic ${o}:`,n)}return e}async function it(t,e){const i=t.file(`${e}/markup.bcf`);if(!i)return null;const o=await i.async("string"),n=o.match(/<Topic\s+Guid="([^"]+)"[^>]*>([\s\S]*?)<\/Topic>/);if(!n)return console.warn(`Invalid markup.bcf in ${e}: missing Topic element`),null;const s=n[1],a=n[2],r=o.match(/<Topic[^>]*TopicType="([^"]+)"/),c=o.match(/<Topic[^>]*TopicStatus="([^"]+)"/),l=h(a,"Title")||"Untitled",p=h(a,"Description"),f=h(a,"Priority"),m=h(a,"Index"),u=h(a,"CreationDate")||new Date().toISOString(),g=h(a,"CreationAuthor")||"Unknown",d=h(a,"ModifiedDate"),x=h(a,"ModifiedAuthor"),w=h(a,"DueDate"),b=h(a,"AssignedTo"),v=h(a,"Stage"),T=[],q=a.matchAll(/<Labels>([^<]+)<\/Labels>/g);for(const A of q)T.push(A[1]);const H=ot(a),O=nt(a),I=[],W=a.matchAll(/<RelatedTopic\s+Guid="([^"]+)"/g);for(const A of W)I.push(A[1]);const J=st(o),K=await at(t,e,o);return{guid:s,title:l,description:p,topicType:r?.[1],topicStatus:c?.[1],priority:f,index:m?parseInt(m,10):void 0,creationDate:u,creationAuthor:g,modifiedDate:d,modifiedAuthor:x,dueDate:w,assignedTo:b,stage:v,labels:T.length>0?T:void 0,bimSnippet:H,documentReferences:O.length>0?O:void 0,relatedTopics:I.length>0?I:void 0,comments:J,viewpoints:K}}function h(t,e){return t.match(new RegExp(`<${e}>([^<]*)<\\/${e}>`))?.[1]}function ot(t){const e=t.match(/<BimSnippet\s+SnippetType="([^"]+)"[^>]*>([\s\S]*?)<\/BimSnippet>/);if(!e)return;const i=e[0].match(/isExternal="([^"]+)"/),o=h(e[2],"Reference"),n=h(e[2],"ReferenceSchema");return{snippetType:e[1],isExternal:i?.[1]==="true",reference:o||"",referenceSchema:n}}function nt(t){const e=[],i=t.matchAll(/<DocumentReference[^>]*>([\s\S]*?)<\/DocumentReference>/g);for(const o of i){const n=o[0].match(/Guid="([^"]+)"/),s=o[0].match(/isExternal="([^"]+)"/),a=h(o[1],"ReferencedDocument"),r=h(o[1],"Description");a&&e.push({guid:n?.[1],isExternal:s?.[1]==="true",referencedDocument:a,description:r})}return e}function st(t){const e=[],i=t.matchAll(/<Comment\s+Guid="([^"]+)"[^>]*>([\s\S]*?)<\/Comment>/g);for(const o of i){const n=o[1],s=o[2],a=h(s,"Date")||new Date().toISOString(),r=h(s,"Author")||"Unknown",c=h(s,"Comment")||"",l=h(s,"ModifiedDate"),p=h(s,"ModifiedAuthor"),f=s.match(/<Viewpoint\s+Guid="([^"]+)"/);e.push({guid:n,date:a,author:r,comment:c,viewpointGuid:f?.[1],modifiedDate:l,modifiedAuthor:p})}return e}async function at(t,e,i){const o=[],n=new Map,s=/<Viewpoint\s+Guid="([^"]+)"[^>]*>([\s\S]*?)<\/Viewpoint>/g;for(const c of i.matchAll(s)){const l=c[1],p=c[2],f=p.match(/<Viewpoint>([^<]+)<\/Viewpoint>/),m=p.match(/<Snapshot>([^<]+)<\/Snapshot>/);n.set(l,{viewpointFile:f?.[1],snapshotFile:m?.[1]})}const a=i.matchAll(/<Viewpoint\s+Guid="([^"]+)"[^>]*\/>/g);for(const c of a)n.has(c[1])||n.set(c[1],{});const r=[];t.forEach(c=>{c.startsWith(`${e}/`)&&c.endsWith(".bcfv")&&r.push(c)});for(const c of r)try{const l=t.file(c);if(!l)continue;const p=await l.async("string"),f=ct(p);if(f){const m=n.get(f.guid);let u=null,g="png";if(m?.snapshotFile){const d=`${e}/${m.snapshotFile}`;u=t.file(d),(m.snapshotFile.toLowerCase().endsWith(".jpg")||m.snapshotFile.toLowerCase().endsWith(".jpeg"))&&(g="jpeg")}if(!u){const d=c.replace(".bcfv",""),x=d.replace(/Viewpoint_/i,"Snapshot_"),w=d.replace(/_viewpoint$/i,"_snapshot"),b=[`${x}.png`,`${w}.png`,`${d}.png`,`${e}/snapshot.png`,`${x}.jpg`,`${w}.jpg`,`${d}.jpg`,`${e}/snapshot.jpg`];for(const v of b)if(u=t.file(v),u){(v.toLowerCase().endsWith(".jpg")||v.toLowerCase().endsWith(".jpeg"))&&(g="jpeg");break}}if(u){const d=await u.async("uint8array");f.snapshotData=d,f.snapshot=`data:image/${g};base64,${U(d)}`}o.push(f)}}catch(l){console.warn(`Failed to parse viewpoint ${c}:`,l)}if(o.length===0){const c=t.file(`${e}/snapshot.png`)||t.file(`${e}/snapshot.jpg`);if(c){const l=c.name.toLowerCase().endsWith(".jpg"),p=await c.async("uint8array");o.push({guid:e,snapshot:`data:image/${l?"jpeg":"png"};base64,${U(p)}`,snapshotData:p})}}return o}function ct(t){const i=t.match(/<VisualizationInfo[^>]+Guid="([^"]+)"/)?.[1]||crypto.randomUUID?.()||`vp-${Date.now()}`,o=rt(t),n=lt(t),s=pt(t),a=mt(t),r=dt(t),c=ht(t);return{guid:i,perspectiveCamera:o,orthogonalCamera:n,components:s,lines:a.length>0?a:void 0,clippingPlanes:r.length>0?r:void 0,bitmaps:c.length>0?c:void 0}}function rt(t){const e=t.match(/<PerspectiveCamera>([\s\S]*?)<\/PerspectiveCamera>/);if(!e)return;const i=e[1],o=V(i,"CameraViewPoint"),n=M(i,"CameraDirection"),s=M(i,"CameraUpVector"),a=h(i,"FieldOfView");if(!(!o||!n||!s||!a))return{cameraViewPoint:o,cameraDirection:n,cameraUpVector:s,fieldOfView:parseFloat(a)}}function lt(t){const e=t.match(/<OrthogonalCamera>([\s\S]*?)<\/OrthogonalCamera>/);if(!e)return;const i=e[1],o=V(i,"CameraViewPoint"),n=M(i,"CameraDirection"),s=M(i,"CameraUpVector"),a=h(i,"ViewToWorldScale");if(!(!o||!n||!s||!a))return{cameraViewPoint:o,cameraDirection:n,cameraUpVector:s,viewToWorldScale:parseFloat(a)}}function V(t,e){const i=t.match(new RegExp(`<${e}>([\\s\\S]*?)<\\/${e}>`));if(!i)return;const o=h(i[1],"X"),n=h(i[1],"Y"),s=h(i[1],"Z");if(!(o===void 0||n===void 0||s===void 0))return{x:parseFloat(o),y:parseFloat(n),z:parseFloat(s)}}function M(t,e){return V(t,e)}function pt(t){const e=t.match(/<Components>([\s\S]*?)<\/Components>/);if(!e)return;const i=e[1],o=B(i,"Selection"),n=ft(i),s=ut(i);if(!(!o&&!n&&!s))return{selection:o?.length?o:void 0,visibility:n,coloring:s?.length?s:void 0}}function B(t,e){const i=t.match(new RegExp(`<${e}>([\\s\\S]*?)<\\/${e}>`));if(!i)return;const o=[],n=i[1].matchAll(/<Component[^>]*(?:\/>|>[\s\S]*?<\/Component>)/g);for(const s of n){const a=_(s[0]);a&&o.push(a)}return o.length>0?o:void 0}function _(t){const e=t.match(/IfcGuid="([^"]+)"/),i=t.match(/AuthoringToolId="([^"]+)"/),o=t.match(/OriginatingSystem="([^"]+)"/);if(!(!e&&!i))return{ifcGuid:e?.[1],authoringToolId:i?.[1],originatingSystem:o?.[1]}}function ft(t){const e=t.match(/<Visibility[^>]*>([\s\S]*?)<\/Visibility>/);if(!e)return;const o=t.match(/DefaultVisibility="([^"]+)"/)?.[1]!=="false",n=B(e[1],"Exceptions");return{defaultVisibility:o,exceptions:n}}function ut(t){const e=t.match(/<Coloring>([\s\S]*?)<\/Coloring>/);if(!e)return;const i=[],o=e[1].matchAll(/<Color\s+Color="([^"]+)"[^>]*>([\s\S]*?)<\/Color>/g);for(const n of o){const s=n[1],a=[],r=n[2].matchAll(/<Component[^>]*(?:\/>|>[\s\S]*?<\/Component>)/g);for(const c of r){const l=_(c[0]);l&&a.push(l)}a.length>0&&i.push({color:s,components:a})}return i.length>0?i:void 0}function mt(t){const e=[],i=t.match(/<Lines>([\s\S]*?)<\/Lines>/);if(!i)return e;const o=i[1].matchAll(/<Line>([\s\S]*?)<\/Line>/g);for(const n of o){const s=V(n[1],"StartPoint"),a=V(n[1],"EndPoint");s&&a&&e.push({startPoint:s,endPoint:a})}return e}function dt(t){const e=[],i=t.match(/<ClippingPlanes>([\s\S]*?)<\/ClippingPlanes>/);if(!i)return e;const o=i[1].matchAll(/<ClippingPlane>([\s\S]*?)<\/ClippingPlane>/g);for(const n of o){const s=V(n[1],"Location"),a=M(n[1],"Direction");s&&a&&e.push({location:s,direction:a})}return e}function ht(t){const e=[],i=t.match(/<Bitmaps>([\s\S]*?)<\/Bitmaps>/);if(!i)return e;const o=i[1].matchAll(/<Bitmap>([\s\S]*?)<\/Bitmap>/g);for(const n of o){const s=h(n[1],"Format")||h(n[1],"Bitmap"),a=h(n[1],"Reference"),r=V(n[1],"Location"),c=M(n[1],"Normal"),l=M(n[1],"Up"),p=h(n[1],"Height");s&&a&&r&&c&&l&&p&&e.push({format:s.toUpperCase()==="JPG"?"JPG":"PNG",reference:a,location:r,normal:c,up:l,height:parseFloat(p)})}return e}function U(t){let e="";for(let i=0;i<t.length;i++)e+=String.fromCharCode(t[i]);return btoa(e)}async function ee(t){const e=new X;gt(e,t.version),(t.projectId||t.name)&&yt(e,t);for(const[i,o]of t.topics)await xt(e,o);return e.generateAsync({type:"blob",compression:"DEFLATE",compressionOptions:{level:6}})}function gt(t,e){const i=`<?xml version="1.0" encoding="UTF-8"?>
2
2
  <Version xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" VersionId="${e}">
3
3
  <DetailedVersion>${e}</DetailedVersion>
4
4
  </Version>`;t.file("bcf.version",i)}function yt(t,e){const i=e.projectId||C(),o=e.name?`
@@ -140,7 +140,7 @@ ${e}</Component>`):o+="/>",o}function St(t){let e=`
140
140
  <Z>${t.up.z}</Z>
141
141
  </Up>
142
142
  <Height>${t.height}</Height>
143
- </Bitmap>`}function y(t){return t.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&apos;")}function $(t){return{x:t.x,y:-t.z,z:t.y}}function S(t){return{x:t.x,y:t.z,z:-t.y}}function Dt(t){const e=$(t.position),i=$(t.target),o=$(t.up),n=i.x-e.x,s=i.y-e.y,a=i.z-e.z,r=Math.sqrt(n*n+s*s+a*a),c=r>1e-4?{x:n/r,y:s/r,z:a/r}:{x:0,y:1,z:0},l=Math.sqrt(o.x*o.x+o.y*o.y+o.z*o.z),p=l>1e-4?{x:o.x/l,y:o.y/l,z:o.z/l}:{x:0,y:0,z:1},f=t.fov*180/Math.PI;return{cameraViewPoint:e,cameraDirection:c,cameraUpVector:p,fieldOfView:Math.max(1,Math.min(179,f))}}function zt(t,e){const i=$(t.position),o=$(t.target),n=$(t.up),s=o.x-i.x,a=o.y-i.y,r=o.z-i.z,c=Math.sqrt(s*s+a*a+r*r),l=c>1e-4?{x:s/c,y:a/c,z:r/c}:{x:0,y:1,z:0},p=Math.sqrt(n.x*n.x+n.y*n.y+n.z*n.z),f=p>1e-4?{x:n.x/p,y:n.y/p,z:n.z/p}:{x:0,y:0,z:1};return{cameraViewPoint:i,cameraDirection:l,cameraUpVector:f,viewToWorldScale:e}}function It(t,e=10){const i={x:t.cameraViewPoint.x+t.cameraDirection.x*e,y:t.cameraViewPoint.y+t.cameraDirection.y*e,z:t.cameraViewPoint.z+t.cameraDirection.z*e},o=S(t.cameraViewPoint),n=S(i),s=S(t.cameraUpVector),a=t.fieldOfView*Math.PI/180;return{position:o,target:n,up:s,fov:a,isOrthographic:!1}}function At(t,e=10){const i={x:t.cameraViewPoint.x+t.cameraDirection.x*e,y:t.cameraViewPoint.y+t.cameraDirection.y*e,z:t.cameraViewPoint.z+t.cameraDirection.z*e},o=S(t.cameraViewPoint),n=S(i),s=S(t.cameraUpVector);return{position:o,target:n,up:s,fov:Math.PI/4,isOrthographic:!0,orthoScale:t.viewToWorldScale}}function kt(t,e){if(!t.enabled)return null;const i=t.position/100;let o,n;switch(t.axis){case"down":o={x:(e.min.x+e.max.x)/2,y:e.min.y+i*(e.max.y-e.min.y),z:(e.min.z+e.max.z)/2},n=t.flipped?{x:0,y:1,z:0}:{x:0,y:-1,z:0};break;case"front":o={x:(e.min.x+e.max.x)/2,y:(e.min.y+e.max.y)/2,z:e.min.z+i*(e.max.z-e.min.z)},n=t.flipped?{x:0,y:0,z:1}:{x:0,y:0,z:-1};break;case"side":o={x:e.min.x+i*(e.max.x-e.min.x),y:(e.min.y+e.max.y)/2,z:(e.min.z+e.max.z)/2},n=t.flipped?{x:1,y:0,z:0}:{x:-1,y:0,z:0};break}return{location:$(o),direction:$(n)}}function Gt(t,e){const i=S(t.location),o=S(t.direction),n=Math.abs(o.x),s=Math.abs(o.y),a=Math.abs(o.z);let r,c,l;if(s>=n&&s>=a){r="down";const p=e.max.y-e.min.y;c=p>0?(i.y-e.min.y)/p*100:50,l=o.y>0}else if(a>=n){r="front";const p=e.max.z-e.min.z;c=p>0?(i.z-e.min.z)/p*100:50,l=o.z>0}else{r="side";const p=e.max.x-e.min.x;c=p>0?(i.x-e.min.x)/p*100:50,l=o.x>0}return c=Math.max(0,Math.min(100,c)),{axis:r,position:c,enabled:!0,flipped:l}}function ie(t){const{camera:e,sectionPlane:i,bounds:o,snapshot:n,snapshotData:s,selectedGuids:a,hiddenGuids:r,visibleGuids:c,coloredGuids:l}=t,p={guid:C()};if(e.isOrthographic&&e.orthoScale!==void 0?p.orthogonalCamera=zt(e,e.orthoScale):p.perspectiveCamera=Dt(e),i?.enabled&&o){const d=kt(i,o);d&&(p.clippingPlanes=[d])}n&&(p.snapshot=n),s&&(p.snapshotData=s);const f=a&&a.length>0,m=r&&r.length>0,u=c&&c.length>0,g=l&&l.length>0;return(f||m||u||g)&&(p.components={},f&&(p.components.selection=a.map(d=>({ifcGuid:d}))),u?p.components.visibility={defaultVisibility:!1,exceptions:c.map(d=>({ifcGuid:d}))}:m&&(p.components.visibility={defaultVisibility:!0,exceptions:r.map(d=>({ifcGuid:d}))}),g&&(p.components.coloring=l.map(({color:d,guids:x})=>({color:d,components:x.map(w=>({ifcGuid:w}))})))),p}function oe(t,e,i=10){let o,n;t.perspectiveCamera?o=It(t.perspectiveCamera,i):t.orthogonalCamera&&(o=At(t.orthogonalCamera,i)),t.clippingPlanes&&t.clippingPlanes.length>0&&e&&(n=Gt(t.clippingPlanes[0],e));const s=[];if(t.components?.selection)for(const l of t.components.selection)l.ifcGuid&&s.push(l.ifcGuid);const a=[],r=[];if(t.components?.visibility){const{defaultVisibility:l,exceptions:p}=t.components.visibility;if(p)for(const f of p)f.ifcGuid&&(l===!1?r.push(f.ifcGuid):a.push(f.ifcGuid))}const c=[];if(t.components?.coloring)for(const l of t.components.coloring){const p=[];for(const f of l.components)f.ifcGuid&&p.push(f.ifcGuid);p.length>0&&c.push({color:l.color,guids:p})}return{camera:o,sectionPlane:n,selectedGuids:s,hiddenGuids:a,visibleGuids:r,coloredGuids:c}}function G(t){return{x:t.x,y:t.z,z:-t.y}}function Lt(t,e){const i=t.perspectiveCamera??t.orthogonalCamera;if(!i)return null;const o=G(i.cameraViewPoint),n=G(i.cameraDirection),s=Math.sqrt(n.x*n.x+n.y*n.y+n.z*n.z);if(s<1e-6)return null;const a=n.x/s,r=n.y/s,c=n.z/s;return{x:o.x+a*e,y:o.y+r*e,z:o.z+c*e}}function j(t){const e=(t.min.x+t.max.x)/2,i=(t.min.z+t.max.z)/2,o=t.max.y,n=t.max.y-t.min.y,s=Math.max(n*.3,.5);return{position:{x:e,y:o+s,z:i},connectorAnchor:{x:e,y:o,z:i}}}function Et(t,e,i){const o=t.components?.selection;if(o&&o.length>0)for(const r of o){if(!r.ifcGuid)continue;const c=e(r.ifcGuid);if(c)return{...j(c),source:"component"}}const n=t.components?.visibility;if(n&&!n.defaultVisibility&&n.exceptions&&n.exceptions.length>0)for(const r of n.exceptions){if(!r.ifcGuid)continue;const c=e(r.ifcGuid);if(c)return{...j(c),source:"component"}}const s=Lt(t,i);if(s)return{position:s,source:"camera-target"};const a=t.perspectiveCamera??t.orthogonalCamera;return a?{position:G(a.cameraViewPoint),source:"camera-position"}:null}function ne(t,e,i){const{targetDistance:o=50,statusFilter:n}=i??{},s=[];for(let a=0;a<t.length;a++){const r=t[a];if(n&&n.length>0){const p=(r.topicStatus??"").toLowerCase();if(!n.some(f=>f.toLowerCase()===p))continue}let c=null;for(const p of r.viewpoints)if(c=Et(p,e,o),c)break;if(!c)continue;const l=r.viewpoints[0];s.push({topicGuid:r.guid,position:c.position,connectorAnchor:c.connectorAnchor,title:r.title,status:r.topicStatus??"Open",priority:r.priority??"Normal",topicType:r.topicType??"Issue",commentCount:r.comments.length,hasViewpoint:r.viewpoints.length>0,snapshot:l?.snapshot,positionSource:c.source,index:r.index??a+1})}return s}const k="bcf-overlay-marker",R="bcf-overlay-connector",P="bcf-overlay-active",D="bcf-overlay-tooltip",Ft={open:"#f7768e","in progress":"#e0af68",resolved:"#9ece6a",closed:"#565f89"},Ot={open:"●","in progress":"◐",resolved:"✓",closed:"○"};class L{container;svgLayer;markerElements=new Map;connectorElements=new Map;markers=[];activeMarkerId=null;projection;unsubCamera=null;clickCallbacks=[];hoverCallbacks=[];opts;_visible=!0;_disposed=!1;constructor(e,i,o){this.projection=i,this.opts={showConnectors:o?.showConnectors??!0,showTooltips:o?.showTooltips??!0,minScale:o?.minScale??.65,maxScale:o?.maxScale??1,verticalOffset:o?.verticalOffset??36},this.container=document.createElement("div"),this.container.style.cssText="position:absolute;inset:0;pointer-events:none;overflow:hidden;z-index:20;",e.appendChild(this.container),this.svgLayer=document.createElementNS("http://www.w3.org/2000/svg","svg"),this.svgLayer.style.cssText="position:absolute;inset:0;width:100%;height:100%;pointer-events:none;overflow:visible;",this.container.appendChild(this.svgLayer),this.injectStyles(),this.unsubCamera=i.onCameraChange(()=>this.updatePositions())}setMarkers(e){this.markers=e;const i=new Set(e.map(o=>o.topicGuid));for(const[o,n]of this.markerElements)i.has(o)||(n.remove(),this.markerElements.delete(o));for(const[o,n]of this.connectorElements)i.has(o)||(n.remove(),this.connectorElements.delete(o));for(const o of e)this.markerElements.has(o.topicGuid)?this.updateMarkerContent(o):this.createMarkerElement(o);this.updatePositions()}setActiveMarker(e){if(this.activeMarkerId){const i=this.markerElements.get(this.activeMarkerId);i&&i.classList.remove(P)}if(this.activeMarkerId=e,e){const i=this.markerElements.get(e);i&&i.classList.add(P)}}setVisible(e){this._visible=e,this.container.style.display=e?"":"none"}onMarkerClick(e){return this.clickCallbacks.push(e),()=>{this.clickCallbacks=this.clickCallbacks.filter(i=>i!==e)}}onMarkerHover(e){return this.hoverCallbacks.push(e),()=>{this.hoverCallbacks=this.hoverCallbacks.filter(i=>i!==e)}}updatePositions(){if(this._disposed||!this._visible)return;const{width:e,height:i}=this.projection.getCanvasSize();if(e===0||i===0)return;const o=this.projection.getCameraPosition?.();for(const n of this.markers){const s=this.markerElements.get(n.topicGuid);if(!s)continue;const a=this.projection.projectToScreen(n.position);if(!a||a.x<-80||a.y<-80||a.x>e+80||a.y>i+80){s.style.display="none";const f=this.connectorElements.get(n.topicGuid);f&&(f.style.display="none");continue}s.style.display="";let r=1;if(o){const f=n.position.x-o.x,m=n.position.y-o.y,u=n.position.z-o.z,g=Math.sqrt(f*f+m*m+u*u),d=Math.max(0,Math.min(1,(g-20)/180));r=this.opts.maxScale+d*(this.opts.minScale-this.opts.maxScale)}const c=a.x,l=a.y;s.style.transform=`translate(${c}px, ${l}px) translate(-50%, -100%) scale(${r.toFixed(3)})`;const p=o?.6+(1-Math.max(0,Math.min(1,(Math.sqrt((n.position.x-o.x)**2+(n.position.y-o.y)**2+(n.position.z-o.z)**2)-20)/250)))*.4:1;if(s.style.opacity=p.toFixed(2),this.opts.showConnectors){const f=n.connectorAnchor??n.position,m=this.projection.projectToScreen(f);let u=this.connectorElements.get(n.topicGuid);if(u||(u=document.createElementNS("http://www.w3.org/2000/svg","line"),u.classList.add(R),this.svgLayer.appendChild(u),this.connectorElements.set(n.topicGuid,u)),!m){u.style.display="none";continue}u.style.display="";const g=this.getStatusColor(n.status);u.setAttribute("x1",String(c)),u.setAttribute("y1",String(l)),u.setAttribute("x2",String(m.x)),u.setAttribute("y2",String(m.y)),u.setAttribute("stroke",g),u.setAttribute("stroke-width","1.5"),u.setAttribute("stroke-dasharray","3 2"),u.setAttribute("stroke-opacity",String((p*.5).toFixed(2)))}}}dispose(){this._disposed=!0,this.unsubCamera&&this.unsubCamera(),this.container.remove(),this.markerElements.clear(),this.connectorElements.clear(),this.clickCallbacks=[],this.hoverCallbacks=[]}createMarkerElement(e){const i=document.createElement("div");i.className=k,i.dataset.topicGuid=e.topicGuid,this.updateMarkerInnerHTML(i,e),i.addEventListener("click",o=>{o.stopPropagation();for(const n of this.clickCallbacks)n(e.topicGuid)}),i.addEventListener("mouseenter",()=>{for(const n of this.hoverCallbacks)n(e.topicGuid);const o=i.querySelector(`.${D}`);o&&(o.style.display="")}),i.addEventListener("mouseleave",()=>{for(const n of this.hoverCallbacks)n(null);const o=i.querySelector(`.${D}`);o&&(o.style.display="none")}),e.topicGuid===this.activeMarkerId&&i.classList.add(P),this.container.appendChild(i),this.markerElements.set(e.topicGuid,i)}updateMarkerContent(e){const i=this.markerElements.get(e.topicGuid);i&&(this.updateMarkerInnerHTML(i,e),e.topicGuid===this.activeMarkerId?i.classList.add(P):i.classList.remove(P))}updateMarkerInnerHTML(e,i){const o=this.getStatusColor(i.status),n=Ot[i.status.toLowerCase()]??"●",s=i.priority?` · ${i.priority}`:"";e.innerHTML=`
143
+ </Bitmap>`}function y(t){return t.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&apos;")}function $(t){return{x:t.x,y:-t.z,z:t.y}}function S(t){return{x:t.x,y:t.z,z:-t.y}}function Dt(t){const e=$(t.position),i=$(t.target),o=$(t.up),n=i.x-e.x,s=i.y-e.y,a=i.z-e.z,r=Math.sqrt(n*n+s*s+a*a),c=r>1e-4?{x:n/r,y:s/r,z:a/r}:{x:0,y:1,z:0},l=Math.sqrt(o.x*o.x+o.y*o.y+o.z*o.z),p=l>1e-4?{x:o.x/l,y:o.y/l,z:o.z/l}:{x:0,y:0,z:1},f=t.fov*180/Math.PI;return{cameraViewPoint:e,cameraDirection:c,cameraUpVector:p,fieldOfView:Math.max(1,Math.min(179,f))}}function zt(t,e){const i=$(t.position),o=$(t.target),n=$(t.up),s=o.x-i.x,a=o.y-i.y,r=o.z-i.z,c=Math.sqrt(s*s+a*a+r*r),l=c>1e-4?{x:s/c,y:a/c,z:r/c}:{x:0,y:1,z:0},p=Math.sqrt(n.x*n.x+n.y*n.y+n.z*n.z),f=p>1e-4?{x:n.x/p,y:n.y/p,z:n.z/p}:{x:0,y:0,z:1};return{cameraViewPoint:i,cameraDirection:l,cameraUpVector:f,viewToWorldScale:e}}function It(t,e=10){const i={x:t.cameraViewPoint.x+t.cameraDirection.x*e,y:t.cameraViewPoint.y+t.cameraDirection.y*e,z:t.cameraViewPoint.z+t.cameraDirection.z*e},o=S(t.cameraViewPoint),n=S(i),s=S(t.cameraUpVector),a=t.fieldOfView*Math.PI/180;return{position:o,target:n,up:s,fov:a,isOrthographic:!1}}function At(t,e=10){const i={x:t.cameraViewPoint.x+t.cameraDirection.x*e,y:t.cameraViewPoint.y+t.cameraDirection.y*e,z:t.cameraViewPoint.z+t.cameraDirection.z*e},o=S(t.cameraViewPoint),n=S(i),s=S(t.cameraUpVector);return{position:o,target:n,up:s,fov:Math.PI/4,isOrthographic:!0,orthoScale:t.viewToWorldScale}}function Gt(t,e){if(!t.enabled)return null;const i=t.position/100;let o,n;switch(t.axis){case"down":o={x:(e.min.x+e.max.x)/2,y:e.min.y+i*(e.max.y-e.min.y),z:(e.min.z+e.max.z)/2},n=t.flipped?{x:0,y:1,z:0}:{x:0,y:-1,z:0};break;case"front":o={x:(e.min.x+e.max.x)/2,y:(e.min.y+e.max.y)/2,z:e.min.z+i*(e.max.z-e.min.z)},n=t.flipped?{x:0,y:0,z:1}:{x:0,y:0,z:-1};break;case"side":o={x:e.min.x+i*(e.max.x-e.min.x),y:(e.min.y+e.max.y)/2,z:(e.min.z+e.max.z)/2},n=t.flipped?{x:1,y:0,z:0}:{x:-1,y:0,z:0};break}return{location:$(o),direction:$(n)}}function kt(t,e){const i=S(t.location),o=S(t.direction),n=Math.abs(o.x),s=Math.abs(o.y),a=Math.abs(o.z);let r,c,l;if(s>=n&&s>=a){r="down";const p=e.max.y-e.min.y;c=p>0?(i.y-e.min.y)/p*100:50,l=o.y>0}else if(a>=n){r="front";const p=e.max.z-e.min.z;c=p>0?(i.z-e.min.z)/p*100:50,l=o.z>0}else{r="side";const p=e.max.x-e.min.x;c=p>0?(i.x-e.min.x)/p*100:50,l=o.x>0}return c=Math.max(0,Math.min(100,c)),{axis:r,position:c,enabled:!0,flipped:l}}function ie(t){const{camera:e,sectionPlane:i,bounds:o,snapshot:n,snapshotData:s,selectedGuids:a,hiddenGuids:r,visibleGuids:c,coloredGuids:l}=t,p={guid:C()};if(e.isOrthographic&&e.orthoScale!==void 0?p.orthogonalCamera=zt(e,e.orthoScale):p.perspectiveCamera=Dt(e),i?.enabled&&o){const d=Gt(i,o);d&&(p.clippingPlanes=[d])}n&&(p.snapshot=n),s&&(p.snapshotData=s);const f=a&&a.length>0,m=r&&r.length>0,u=c&&c.length>0,g=l&&l.length>0;return(f||m||u||g)&&(p.components={},f&&(p.components.selection=a.map(d=>({ifcGuid:d}))),u?p.components.visibility={defaultVisibility:!1,exceptions:c.map(d=>({ifcGuid:d}))}:m&&(p.components.visibility={defaultVisibility:!0,exceptions:r.map(d=>({ifcGuid:d}))}),g&&(p.components.coloring=l.map(({color:d,guids:x})=>({color:d,components:x.map(w=>({ifcGuid:w}))})))),p}function oe(t,e,i=10){let o,n;t.perspectiveCamera?o=It(t.perspectiveCamera,i):t.orthogonalCamera&&(o=At(t.orthogonalCamera,i)),t.clippingPlanes&&t.clippingPlanes.length>0&&e&&(n=kt(t.clippingPlanes[0],e));const s=[];if(t.components?.selection)for(const l of t.components.selection)l.ifcGuid&&s.push(l.ifcGuid);const a=[],r=[];if(t.components?.visibility){const{defaultVisibility:l,exceptions:p}=t.components.visibility;if(p)for(const f of p)f.ifcGuid&&(l===!1?r.push(f.ifcGuid):a.push(f.ifcGuid))}const c=[];if(t.components?.coloring)for(const l of t.components.coloring){const p=[];for(const f of l.components)f.ifcGuid&&p.push(f.ifcGuid);p.length>0&&c.push({color:l.color,guids:p})}return{camera:o,sectionPlane:n,selectedGuids:s,hiddenGuids:a,visibleGuids:r,coloredGuids:c}}function k(t){return{x:t.x,y:t.z,z:-t.y}}function Lt(t,e){const i=t.perspectiveCamera??t.orthogonalCamera;if(!i)return null;const o=k(i.cameraViewPoint),n=k(i.cameraDirection),s=Math.sqrt(n.x*n.x+n.y*n.y+n.z*n.z);if(s<1e-6)return null;const a=n.x/s,r=n.y/s,c=n.z/s;return{x:o.x+a*e,y:o.y+r*e,z:o.z+c*e}}function j(t){const e=(t.min.x+t.max.x)/2,i=(t.min.z+t.max.z)/2,o=t.max.y,n=t.max.y-t.min.y,s=Math.max(n*.3,.5);return{position:{x:e,y:o+s,z:i},connectorAnchor:{x:e,y:o,z:i}}}function Et(t,e,i){const o=t.components?.selection;if(o&&o.length>0)for(const r of o){if(!r.ifcGuid)continue;const c=e(r.ifcGuid);if(c)return{...j(c),source:"component"}}const n=t.components?.visibility;if(n&&!n.defaultVisibility&&n.exceptions&&n.exceptions.length>0)for(const r of n.exceptions){if(!r.ifcGuid)continue;const c=e(r.ifcGuid);if(c)return{...j(c),source:"component"}}const s=Lt(t,i);if(s)return{position:s,source:"camera-target"};const a=t.perspectiveCamera??t.orthogonalCamera;return a?{position:k(a.cameraViewPoint),source:"camera-position"}:null}function ne(t,e,i){const{targetDistance:o=50,statusFilter:n}=i??{},s=[];for(let a=0;a<t.length;a++){const r=t[a];if(n&&n.length>0){const p=(r.topicStatus??"").toLowerCase();if(!n.some(f=>f.toLowerCase()===p))continue}let c=null;for(const p of r.viewpoints)if(c=Et(p,e,o),c)break;if(!c)continue;const l=r.viewpoints[0];s.push({topicGuid:r.guid,position:c.position,connectorAnchor:c.connectorAnchor,title:r.title,status:r.topicStatus??"Open",priority:r.priority??"Normal",topicType:r.topicType??"Issue",commentCount:r.comments.length,hasViewpoint:r.viewpoints.length>0,snapshot:l?.snapshot,positionSource:c.source,index:r.index??a+1})}return s}const G="bcf-overlay-marker",R="bcf-overlay-connector",P="bcf-overlay-active",D="bcf-overlay-tooltip",Ft={open:"#f7768e","in progress":"#e0af68",resolved:"#9ece6a",closed:"#565f89"},Ot={open:"●","in progress":"◐",resolved:"✓",closed:"○"};class L{container;svgLayer;markerElements=new Map;connectorElements=new Map;markers=[];activeMarkerId=null;projection;unsubCamera=null;clickCallbacks=[];hoverCallbacks=[];opts;_visible=!0;_disposed=!1;constructor(e,i,o){this.projection=i,this.opts={showConnectors:o?.showConnectors??!0,showTooltips:o?.showTooltips??!0,minScale:o?.minScale??.65,maxScale:o?.maxScale??1,verticalOffset:o?.verticalOffset??36},this.container=document.createElement("div"),this.container.style.cssText="position:absolute;inset:0;pointer-events:none;overflow:hidden;z-index:20;",e.appendChild(this.container),this.svgLayer=document.createElementNS("http://www.w3.org/2000/svg","svg"),this.svgLayer.style.cssText="position:absolute;inset:0;width:100%;height:100%;pointer-events:none;overflow:visible;",this.container.appendChild(this.svgLayer),this.injectStyles(),this.unsubCamera=i.onCameraChange(()=>this.updatePositions())}setMarkers(e){this.markers=e;const i=new Set(e.map(o=>o.topicGuid));for(const[o,n]of this.markerElements)i.has(o)||(n.remove(),this.markerElements.delete(o));for(const[o,n]of this.connectorElements)i.has(o)||(n.remove(),this.connectorElements.delete(o));for(const o of e)this.markerElements.has(o.topicGuid)?this.updateMarkerContent(o):this.createMarkerElement(o);this.updatePositions()}setActiveMarker(e){if(this.activeMarkerId){const i=this.markerElements.get(this.activeMarkerId);i&&i.classList.remove(P)}if(this.activeMarkerId=e,e){const i=this.markerElements.get(e);i&&i.classList.add(P)}}setVisible(e){this._visible=e,this.container.style.display=e?"":"none"}onMarkerClick(e){return this.clickCallbacks.push(e),()=>{this.clickCallbacks=this.clickCallbacks.filter(i=>i!==e)}}onMarkerHover(e){return this.hoverCallbacks.push(e),()=>{this.hoverCallbacks=this.hoverCallbacks.filter(i=>i!==e)}}updatePositions(){if(this._disposed||!this._visible)return;const{width:e,height:i}=this.projection.getCanvasSize();if(e===0||i===0)return;const o=this.projection.getCameraPosition?.();for(const n of this.markers){const s=this.markerElements.get(n.topicGuid);if(!s)continue;const a=this.projection.projectToScreen(n.position);if(!a||a.x<-80||a.y<-80||a.x>e+80||a.y>i+80){s.style.display="none";const f=this.connectorElements.get(n.topicGuid);f&&(f.style.display="none");continue}s.style.display="";let r=1;if(o){const f=n.position.x-o.x,m=n.position.y-o.y,u=n.position.z-o.z,g=Math.sqrt(f*f+m*m+u*u),d=Math.max(0,Math.min(1,(g-20)/180));r=this.opts.maxScale+d*(this.opts.minScale-this.opts.maxScale)}const c=a.x,l=a.y;s.style.transform=`translate(${c}px, ${l}px) translate(-50%, -100%) scale(${r.toFixed(3)})`;const p=o?.6+(1-Math.max(0,Math.min(1,(Math.sqrt((n.position.x-o.x)**2+(n.position.y-o.y)**2+(n.position.z-o.z)**2)-20)/250)))*.4:1;if(s.style.opacity=p.toFixed(2),this.opts.showConnectors){const f=n.connectorAnchor??n.position,m=this.projection.projectToScreen(f);let u=this.connectorElements.get(n.topicGuid);if(u||(u=document.createElementNS("http://www.w3.org/2000/svg","line"),u.classList.add(R),this.svgLayer.appendChild(u),this.connectorElements.set(n.topicGuid,u)),!m){u.style.display="none";continue}u.style.display="";const g=this.getStatusColor(n.status);u.setAttribute("x1",String(c)),u.setAttribute("y1",String(l)),u.setAttribute("x2",String(m.x)),u.setAttribute("y2",String(m.y)),u.setAttribute("stroke",g),u.setAttribute("stroke-width","1.5"),u.setAttribute("stroke-dasharray","3 2"),u.setAttribute("stroke-opacity",String((p*.5).toFixed(2)))}}}dispose(){this._disposed=!0,this.unsubCamera&&this.unsubCamera(),this.container.remove(),this.markerElements.clear(),this.connectorElements.clear(),this.clickCallbacks=[],this.hoverCallbacks=[]}createMarkerElement(e){const i=document.createElement("div");i.className=G,i.dataset.topicGuid=e.topicGuid,this.updateMarkerInnerHTML(i,e),i.addEventListener("click",o=>{o.stopPropagation();for(const n of this.clickCallbacks)n(e.topicGuid)}),i.addEventListener("mouseenter",()=>{for(const n of this.hoverCallbacks)n(e.topicGuid);const o=i.querySelector(`.${D}`);o&&(o.style.display="")}),i.addEventListener("mouseleave",()=>{for(const n of this.hoverCallbacks)n(null);const o=i.querySelector(`.${D}`);o&&(o.style.display="none")}),e.topicGuid===this.activeMarkerId&&i.classList.add(P),this.container.appendChild(i),this.markerElements.set(e.topicGuid,i)}updateMarkerContent(e){const i=this.markerElements.get(e.topicGuid);i&&(this.updateMarkerInnerHTML(i,e),e.topicGuid===this.activeMarkerId?i.classList.add(P):i.classList.remove(P))}updateMarkerInnerHTML(e,i){const o=this.getStatusColor(i.status),n=Ot[i.status.toLowerCase()]??"●",s=i.priority?` · ${i.priority}`:"";e.innerHTML=`
144
144
  <div class="bcf-marker-pin" style="--marker-color:${o};">
145
145
  <span class="bcf-marker-index">${i.index}</span>
146
146
  </div>
@@ -156,7 +156,7 @@ ${e}</Component>`):o+="/>",o}function St(t){let e=`
156
156
  `}getStatusColor(e){return Ft[e.toLowerCase()]??"#7aa2f7"}escapeHtml(e){const i=document.createElement("div");return i.textContent=e,i.innerHTML}static stylesInjected=!1;injectStyles(){if(L.stylesInjected)return;L.stylesInjected=!0;const e=document.createElement("style");e.textContent=`
157
157
  /* BCF 3D Overlay Markers */
158
158
 
159
- .${k} {
159
+ .${G} {
160
160
  position: absolute;
161
161
  left: 0;
162
162
  top: 0;
@@ -182,7 +182,7 @@ ${e}</Component>`):o+="/>",o}function St(t){let e=`
182
182
  transition: transform 0.15s ease, box-shadow 0.15s ease;
183
183
  }
184
184
 
185
- .${k}:hover .bcf-marker-pin {
185
+ .${G}:hover .bcf-marker-pin {
186
186
  transform: rotate(-45deg) scale(1.2);
187
187
  box-shadow: 0 4px 16px rgba(0,0,0,0.4);
188
188
  }
@@ -278,4 +278,4 @@ Requirement: ${a.checkedDescription}${s.globalId?`
278
278
  GlobalId: ${s.globalId}`:""}`,author:i.author,topicType:i.failureTopicType,topicStatus:"Open",labels:["IDS",n.specification.name]});let l;if(s.globalId){const f=`${s.modelId}:${s.expressId}`,m=i.entityBounds?.get(f),u=i.entitySnapshots?.get(f),g=N(s.globalId,i.failureColor,m,u);c.viewpoints.push(g),l=g.guid}const p=z({author:i.author,comment:Z(a),viewpointGuid:l});c.comments.push(p),t.topics.set(c.guid,c),o++}}}function qt(t,e,i,o){const n=[];return e.passed?n.push("IDS Validation Passed — all requirements satisfied"):n.push(`IDS Validation Failure — ${i} of ${o} requirements failed`),n.push(""),n.push(`Specification: ${t.specification.name}`),t.specification.description&&n.push(`Description: ${t.specification.description}`),n.push(`Entity Type: ${e.entityType}`),e.globalId&&n.push(`GlobalId: ${e.globalId}`),e.entityName&&n.push(`Name: ${e.entityName}`),n.join(`
279
279
  `)}function Ht(t){const e=[];return e.push(`IDS Specification Failure — ${t.failedCount} of ${t.applicableCount} entities failed`),t.specification.description&&(e.push(""),e.push(t.specification.description)),e.push(""),e.push(`Applicable: ${t.applicableCount}`),e.push(`Passed: ${t.passedCount}`),e.push(`Failed: ${t.failedCount}`),e.join(`
280
280
  `)}function Z(t){const e=[];return e.push(`[${t.facetType}] ${t.checkedDescription}`),t.failureReason&&e.push(`Failure: ${t.failureReason}`),t.expectedValue&&e.push(`Expected: ${t.expectedValue}`),t.actualValue&&e.push(`Actual: ${t.actualValue}`),e.join(`
281
- `)}function Wt(t){const e=(t.min.x+t.max.x)/2,i=(t.min.y+t.max.y)/2,o=(t.min.z+t.max.z)/2,n=t.max.x-t.min.x,s=t.max.y-t.min.y,a=t.max.z-t.min.z,r=Math.max(n,s,a,.1),c=60*Math.PI/180,l=r/2/Math.tan(c/2)*1.5,p=Math.sqrt(.6*.6+.5*.5+.6*.6),f=.6/p*l,m=.5/p*l,u=.6/p*l,g=e+f,d=i+m,x=o+u,w=e-g,b=i-d,v=o-x,T=Math.sqrt(w*w+b*b+v*v);return{cameraViewPoint:{x:g,y:-x,z:d},cameraDirection:{x:w/T,y:-v/T,z:b/T},cameraUpVector:{x:0,y:0,z:1},fieldOfView:60}}function N(t,e,i,o){const n={guid:C(),components:{selection:[{ifcGuid:t}],visibility:{defaultVisibility:!1,exceptions:[{ifcGuid:t}]}}};return e&&(n.components.coloring=[{color:e,components:[{ifcGuid:t}]}]),i&&(n.perspectiveCamera=Wt(i)),o&&(n.snapshot=o),n}function Jt(t,e){const i={guid:C(),components:{selection:t.map(o=>({ifcGuid:o})),visibility:{defaultVisibility:!1,exceptions:t.map(o=>({ifcGuid:o}))}}};return e&&(i.components.coloring=[{color:e,components:t.map(o=>({ifcGuid:o}))}]),i}function ae(t){return{version:t?.version??"2.1",projectId:C(),name:t?.name,topics:new Map}}function ce(t){return{guid:C(),title:t.title,description:t.description,topicType:t.topicType??"Issue",topicStatus:t.topicStatus??"Open",priority:t.priority,creationDate:new Date().toISOString(),creationAuthor:t.author,assignedTo:t.assignedTo,dueDate:t.dueDate,labels:t.labels,comments:[],viewpoints:[]}}function re(t){return{guid:C(),date:new Date().toISOString(),author:t.author,comment:t.comment,viewpointGuid:t.viewpointGuid}}function le(t,e){t.topics.set(e.guid,e)}function pe(t,e){t.comments.push(e),t.modifiedDate=new Date().toISOString()}function fe(t,e){t.viewpoints.push(e),t.modifiedDate=new Date().toISOString()}function ue(t,e,i){t.topicStatus=e,t.modifiedDate=new Date().toISOString(),t.modifiedAuthor=i}export{L as B,pe as a,le as b,fe as c,ne as d,re as e,se as f,ae as g,ce as h,ie as i,oe as j,te as r,ue as u,ee as w};
281
+ `)}function Wt(t){const e=(t.min.x+t.max.x)/2,i=(t.min.y+t.max.y)/2,o=(t.min.z+t.max.z)/2,n=t.max.x-t.min.x,s=t.max.y-t.min.y,a=t.max.z-t.min.z,r=Math.max(n,s,a,.1),c=60*Math.PI/180,l=r/2/Math.tan(c/2)*1.5,p=Math.sqrt(.6*.6+.5*.5+.6*.6),f=.6/p*l,m=.5/p*l,u=.6/p*l,g=e+f,d=i+m,x=o+u,w=e-g,b=i-d,v=o-x,T=Math.sqrt(w*w+b*b+v*v);return{cameraViewPoint:{x:g,y:-x,z:d},cameraDirection:{x:w/T,y:-v/T,z:b/T},cameraUpVector:{x:0,y:0,z:1},fieldOfView:60}}function N(t,e,i,o){const n={guid:C(),components:{selection:[{ifcGuid:t}],visibility:{defaultVisibility:!1,exceptions:[{ifcGuid:t}]}}};return e&&(n.components.coloring=[{color:e,components:[{ifcGuid:t}]}]),i&&(n.perspectiveCamera=Wt(i)),o&&(n.snapshot=o),n}function Jt(t,e){const i={guid:C(),components:{selection:t.map(o=>({ifcGuid:o})),visibility:{defaultVisibility:!1,exceptions:t.map(o=>({ifcGuid:o}))}}};return e&&(i.components.coloring=[{color:e,components:t.map(o=>({ifcGuid:o}))}]),i}function ae(t){return{version:t?.version??"2.1",projectId:C(),name:t?.name,topics:new Map}}function ce(t){return{guid:C(),title:t.title,description:t.description,topicType:t.topicType??"Issue",topicStatus:t.topicStatus??"Open",priority:t.priority,creationDate:new Date().toISOString(),creationAuthor:t.author,assignedTo:t.assignedTo,dueDate:t.dueDate,labels:t.labels,comments:[],viewpoints:[]}}function re(t){return{guid:C(),date:new Date().toISOString(),author:t.author,comment:t.comment,viewpointGuid:t.viewpointGuid}}function le(t,e){t.topics.set(e.guid,e)}function pe(t,e){t.comments.push(e),t.modifiedDate=new Date().toISOString()}function fe(t,e){t.viewpoints.push(e),t.modifiedDate=new Date().toISOString()}function ue(t,e,i){t.topicStatus=e,t.modifiedDate=new Date().toISOString(),t.modifiedAuthor=i}function me(t,e,i,o=255){const n=s=>Math.round(Math.max(0,Math.min(255,s))).toString(16).padStart(2,"0");return`${n(o)}${n(t)}${n(e)}${n(i)}`.toUpperCase()}export{L as B,pe as a,le as b,fe as c,ne as d,re as e,se as f,ae as g,ce as h,ie as i,oe as j,te as r,me as t,ue as u,ee as w};
@@ -1 +1 @@
1
- import{i as r}from"./pako.esm-Cram60i4.js";import{B as o}from"./geotiff-xZoE8BkO.js";import"./sandbox-DDSZ7rek.js";import"./lens-PYsLu_MA.js";import"./__vite-browser-external-B1O5LaIO.js";class d extends o{decodeBlock(e){return r(new Uint8Array(e)).buffer}}export{d as default};
1
+ import{i as r}from"./pako.esm-Cram60i4.js";import{B as o}from"./geotiff-A5UjhI6L.js";import"./sandbox-CsRXlgCO.js";import"./lens-PYsLu_MA.js";import"./__vite-browser-external-B1O5LaIO.js";class d extends o{decodeBlock(e){return r(new Uint8Array(e)).buffer}}export{d as default};