@ifc-lite/viewer 1.17.3 → 1.17.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +39 -30
- package/.turbo/turbo-typecheck.log +1 -1
- package/CHANGELOG.md +15 -0
- package/DESKTOP_CONTRACT_VERSION +1 -0
- package/dist/assets/arrow-CZ5kQ26f.js +20 -0
- package/dist/assets/basketViewActivator-BmnNtVfZ.js +1 -0
- package/dist/assets/{bcf-D5-QWGO9.js → bcf-DOG9_WPX.js} +1 -1
- package/dist/assets/{browser-CKs-FY1P.js → browser-C5TFR7sH.js} +1 -1
- package/dist/assets/cesium-ADbP7waU.css +1 -0
- package/dist/assets/cesium-DUOzBlqv.js +17817 -0
- package/dist/assets/{exporters-C_6J153K.js → exporters-ChAtBmlj.js} +2225 -1754
- package/dist/assets/geometry.worker-BQ0rzNo-.js +1 -0
- package/dist/assets/ifc-lite_bg-BX4E7TX8.wasm +0 -0
- package/dist/assets/{index-jhBr1wbn.js → index-Co8E2-FE.js} +28959 -24612
- package/dist/assets/index-DckuDqlv.css +1 -0
- package/dist/assets/{maplibre-gl-BpvwNKKy.js → maplibre-gl-CGLcoNXc.js} +1 -1
- package/dist/assets/native-bridge-BRvbckFQ.js +429 -0
- package/dist/assets/{sandbox-B79eavQ3.js → sandbox-DZiNLNMk.js} +5 -5
- package/dist/assets/{server-client-D3bUPJJc.js → server-client-BV8zHZ7Y.js} +4 -4
- package/dist/assets/tauri-core-stub-D8Fa-u43.js +1 -0
- package/dist/assets/tauri-dialog-stub-r7Wksg7o.js +1 -0
- package/dist/assets/tauri-fs-stub-BdeRC7aK.js +1 -0
- package/dist/assets/wasm-bridge-g01g7T9b.js +1 -0
- package/dist/assets/{zip-B-jFFAGa.js → zip-DBEtpeu6.js} +3 -3
- package/dist/cesium/Assets/IAU2006_XYS/IAU2006_XYS_0.json +1 -0
- package/dist/cesium/Assets/IAU2006_XYS/IAU2006_XYS_1.json +1 -0
- package/dist/cesium/Assets/IAU2006_XYS/IAU2006_XYS_10.json +1 -0
- package/dist/cesium/Assets/IAU2006_XYS/IAU2006_XYS_11.json +1 -0
- package/dist/cesium/Assets/IAU2006_XYS/IAU2006_XYS_12.json +1 -0
- package/dist/cesium/Assets/IAU2006_XYS/IAU2006_XYS_13.json +1 -0
- package/dist/cesium/Assets/IAU2006_XYS/IAU2006_XYS_14.json +1 -0
- package/dist/cesium/Assets/IAU2006_XYS/IAU2006_XYS_15.json +1 -0
- package/dist/cesium/Assets/IAU2006_XYS/IAU2006_XYS_16.json +1 -0
- package/dist/cesium/Assets/IAU2006_XYS/IAU2006_XYS_17.json +1 -0
- package/dist/cesium/Assets/IAU2006_XYS/IAU2006_XYS_18.json +1 -0
- package/dist/cesium/Assets/IAU2006_XYS/IAU2006_XYS_19.json +1 -0
- package/dist/cesium/Assets/IAU2006_XYS/IAU2006_XYS_2.json +1 -0
- package/dist/cesium/Assets/IAU2006_XYS/IAU2006_XYS_20.json +1 -0
- package/dist/cesium/Assets/IAU2006_XYS/IAU2006_XYS_21.json +1 -0
- package/dist/cesium/Assets/IAU2006_XYS/IAU2006_XYS_22.json +1 -0
- package/dist/cesium/Assets/IAU2006_XYS/IAU2006_XYS_23.json +1 -0
- package/dist/cesium/Assets/IAU2006_XYS/IAU2006_XYS_24.json +1 -0
- package/dist/cesium/Assets/IAU2006_XYS/IAU2006_XYS_25.json +1 -0
- package/dist/cesium/Assets/IAU2006_XYS/IAU2006_XYS_26.json +1 -0
- package/dist/cesium/Assets/IAU2006_XYS/IAU2006_XYS_27.json +1 -0
- package/dist/cesium/Assets/IAU2006_XYS/IAU2006_XYS_3.json +1 -0
- package/dist/cesium/Assets/IAU2006_XYS/IAU2006_XYS_4.json +1 -0
- package/dist/cesium/Assets/IAU2006_XYS/IAU2006_XYS_5.json +1 -0
- package/dist/cesium/Assets/IAU2006_XYS/IAU2006_XYS_6.json +1 -0
- package/dist/cesium/Assets/IAU2006_XYS/IAU2006_XYS_7.json +1 -0
- package/dist/cesium/Assets/IAU2006_XYS/IAU2006_XYS_8.json +1 -0
- package/dist/cesium/Assets/IAU2006_XYS/IAU2006_XYS_9.json +1 -0
- package/dist/cesium/Assets/Images/bing_maps_credit.png +0 -0
- package/dist/cesium/Assets/Images/cesium_credit.png +0 -0
- package/dist/cesium/Assets/Images/google_earth_credit.png +0 -0
- package/dist/cesium/Assets/Images/ion-credit.png +0 -0
- package/dist/cesium/Assets/Textures/LensFlare/DirtMask.jpg +0 -0
- package/dist/cesium/Assets/Textures/LensFlare/StarBurst.jpg +0 -0
- package/dist/cesium/Assets/Textures/NaturalEarthII/0/0/0.jpg +0 -0
- package/dist/cesium/Assets/Textures/NaturalEarthII/0/1/0.jpg +0 -0
- package/dist/cesium/Assets/Textures/NaturalEarthII/1/0/0.jpg +0 -0
- package/dist/cesium/Assets/Textures/NaturalEarthII/1/0/1.jpg +0 -0
- package/dist/cesium/Assets/Textures/NaturalEarthII/1/1/0.jpg +0 -0
- package/dist/cesium/Assets/Textures/NaturalEarthII/1/1/1.jpg +0 -0
- package/dist/cesium/Assets/Textures/NaturalEarthII/1/2/0.jpg +0 -0
- package/dist/cesium/Assets/Textures/NaturalEarthII/1/2/1.jpg +0 -0
- package/dist/cesium/Assets/Textures/NaturalEarthII/1/3/0.jpg +0 -0
- package/dist/cesium/Assets/Textures/NaturalEarthII/1/3/1.jpg +0 -0
- package/dist/cesium/Assets/Textures/NaturalEarthII/2/0/0.jpg +0 -0
- package/dist/cesium/Assets/Textures/NaturalEarthII/2/0/1.jpg +0 -0
- package/dist/cesium/Assets/Textures/NaturalEarthII/2/0/2.jpg +0 -0
- package/dist/cesium/Assets/Textures/NaturalEarthII/2/0/3.jpg +0 -0
- package/dist/cesium/Assets/Textures/NaturalEarthII/2/1/0.jpg +0 -0
- package/dist/cesium/Assets/Textures/NaturalEarthII/2/1/1.jpg +0 -0
- package/dist/cesium/Assets/Textures/NaturalEarthII/2/1/2.jpg +0 -0
- package/dist/cesium/Assets/Textures/NaturalEarthII/2/1/3.jpg +0 -0
- package/dist/cesium/Assets/Textures/NaturalEarthII/2/2/0.jpg +0 -0
- package/dist/cesium/Assets/Textures/NaturalEarthII/2/2/1.jpg +0 -0
- package/dist/cesium/Assets/Textures/NaturalEarthII/2/2/2.jpg +0 -0
- package/dist/cesium/Assets/Textures/NaturalEarthII/2/2/3.jpg +0 -0
- package/dist/cesium/Assets/Textures/NaturalEarthII/2/3/0.jpg +0 -0
- package/dist/cesium/Assets/Textures/NaturalEarthII/2/3/1.jpg +0 -0
- package/dist/cesium/Assets/Textures/NaturalEarthII/2/3/2.jpg +0 -0
- package/dist/cesium/Assets/Textures/NaturalEarthII/2/3/3.jpg +0 -0
- package/dist/cesium/Assets/Textures/NaturalEarthII/2/4/0.jpg +0 -0
- package/dist/cesium/Assets/Textures/NaturalEarthII/2/4/1.jpg +0 -0
- package/dist/cesium/Assets/Textures/NaturalEarthII/2/4/2.jpg +0 -0
- package/dist/cesium/Assets/Textures/NaturalEarthII/2/4/3.jpg +0 -0
- package/dist/cesium/Assets/Textures/NaturalEarthII/2/5/0.jpg +0 -0
- package/dist/cesium/Assets/Textures/NaturalEarthII/2/5/1.jpg +0 -0
- package/dist/cesium/Assets/Textures/NaturalEarthII/2/5/2.jpg +0 -0
- package/dist/cesium/Assets/Textures/NaturalEarthII/2/5/3.jpg +0 -0
- package/dist/cesium/Assets/Textures/NaturalEarthII/2/6/0.jpg +0 -0
- package/dist/cesium/Assets/Textures/NaturalEarthII/2/6/1.jpg +0 -0
- package/dist/cesium/Assets/Textures/NaturalEarthII/2/6/2.jpg +0 -0
- package/dist/cesium/Assets/Textures/NaturalEarthII/2/6/3.jpg +0 -0
- package/dist/cesium/Assets/Textures/NaturalEarthII/2/7/0.jpg +0 -0
- package/dist/cesium/Assets/Textures/NaturalEarthII/2/7/1.jpg +0 -0
- package/dist/cesium/Assets/Textures/NaturalEarthII/2/7/2.jpg +0 -0
- package/dist/cesium/Assets/Textures/NaturalEarthII/2/7/3.jpg +0 -0
- package/dist/cesium/Assets/Textures/NaturalEarthII/tilemapresource.xml +14 -0
- package/dist/cesium/Assets/Textures/SkyBox/tycho2t3_80_mx.jpg +0 -0
- package/dist/cesium/Assets/Textures/SkyBox/tycho2t3_80_my.jpg +0 -0
- package/dist/cesium/Assets/Textures/SkyBox/tycho2t3_80_mz.jpg +0 -0
- package/dist/cesium/Assets/Textures/SkyBox/tycho2t3_80_px.jpg +0 -0
- package/dist/cesium/Assets/Textures/SkyBox/tycho2t3_80_py.jpg +0 -0
- package/dist/cesium/Assets/Textures/SkyBox/tycho2t3_80_pz.jpg +0 -0
- package/dist/cesium/Assets/Textures/maki/airfield.png +0 -0
- package/dist/cesium/Assets/Textures/maki/airport.png +0 -0
- package/dist/cesium/Assets/Textures/maki/alcohol-shop.png +0 -0
- package/dist/cesium/Assets/Textures/maki/america-football.png +0 -0
- package/dist/cesium/Assets/Textures/maki/art-gallery.png +0 -0
- package/dist/cesium/Assets/Textures/maki/bakery.png +0 -0
- package/dist/cesium/Assets/Textures/maki/bank.png +0 -0
- package/dist/cesium/Assets/Textures/maki/bar.png +0 -0
- package/dist/cesium/Assets/Textures/maki/baseball.png +0 -0
- package/dist/cesium/Assets/Textures/maki/basketball.png +0 -0
- package/dist/cesium/Assets/Textures/maki/beer.png +0 -0
- package/dist/cesium/Assets/Textures/maki/bicycle.png +0 -0
- package/dist/cesium/Assets/Textures/maki/building.png +0 -0
- package/dist/cesium/Assets/Textures/maki/bus.png +0 -0
- package/dist/cesium/Assets/Textures/maki/cafe.png +0 -0
- package/dist/cesium/Assets/Textures/maki/camera.png +0 -0
- package/dist/cesium/Assets/Textures/maki/campsite.png +0 -0
- package/dist/cesium/Assets/Textures/maki/car.png +0 -0
- package/dist/cesium/Assets/Textures/maki/cemetery.png +0 -0
- package/dist/cesium/Assets/Textures/maki/cesium.png +0 -0
- package/dist/cesium/Assets/Textures/maki/chemist.png +0 -0
- package/dist/cesium/Assets/Textures/maki/cinema.png +0 -0
- package/dist/cesium/Assets/Textures/maki/circle-stroked.png +0 -0
- package/dist/cesium/Assets/Textures/maki/circle.png +0 -0
- package/dist/cesium/Assets/Textures/maki/city.png +0 -0
- package/dist/cesium/Assets/Textures/maki/clothing-store.png +0 -0
- package/dist/cesium/Assets/Textures/maki/college.png +0 -0
- package/dist/cesium/Assets/Textures/maki/commercial.png +0 -0
- package/dist/cesium/Assets/Textures/maki/cricket.png +0 -0
- package/dist/cesium/Assets/Textures/maki/cross.png +0 -0
- package/dist/cesium/Assets/Textures/maki/dam.png +0 -0
- package/dist/cesium/Assets/Textures/maki/danger.png +0 -0
- package/dist/cesium/Assets/Textures/maki/disability.png +0 -0
- package/dist/cesium/Assets/Textures/maki/dog-park.png +0 -0
- package/dist/cesium/Assets/Textures/maki/embassy.png +0 -0
- package/dist/cesium/Assets/Textures/maki/emergency-telephone.png +0 -0
- package/dist/cesium/Assets/Textures/maki/entrance.png +0 -0
- package/dist/cesium/Assets/Textures/maki/farm.png +0 -0
- package/dist/cesium/Assets/Textures/maki/fast-food.png +0 -0
- package/dist/cesium/Assets/Textures/maki/ferry.png +0 -0
- package/dist/cesium/Assets/Textures/maki/fire-station.png +0 -0
- package/dist/cesium/Assets/Textures/maki/fuel.png +0 -0
- package/dist/cesium/Assets/Textures/maki/garden.png +0 -0
- package/dist/cesium/Assets/Textures/maki/gift.png +0 -0
- package/dist/cesium/Assets/Textures/maki/golf.png +0 -0
- package/dist/cesium/Assets/Textures/maki/grocery.png +0 -0
- package/dist/cesium/Assets/Textures/maki/hairdresser.png +0 -0
- package/dist/cesium/Assets/Textures/maki/harbor.png +0 -0
- package/dist/cesium/Assets/Textures/maki/heart.png +0 -0
- package/dist/cesium/Assets/Textures/maki/heliport.png +0 -0
- package/dist/cesium/Assets/Textures/maki/hospital.png +0 -0
- package/dist/cesium/Assets/Textures/maki/ice-cream.png +0 -0
- package/dist/cesium/Assets/Textures/maki/industrial.png +0 -0
- package/dist/cesium/Assets/Textures/maki/land-use.png +0 -0
- package/dist/cesium/Assets/Textures/maki/laundry.png +0 -0
- package/dist/cesium/Assets/Textures/maki/library.png +0 -0
- package/dist/cesium/Assets/Textures/maki/lighthouse.png +0 -0
- package/dist/cesium/Assets/Textures/maki/lodging.png +0 -0
- package/dist/cesium/Assets/Textures/maki/logging.png +0 -0
- package/dist/cesium/Assets/Textures/maki/london-underground.png +0 -0
- package/dist/cesium/Assets/Textures/maki/marker-stroked.png +0 -0
- package/dist/cesium/Assets/Textures/maki/marker.png +0 -0
- package/dist/cesium/Assets/Textures/maki/minefield.png +0 -0
- package/dist/cesium/Assets/Textures/maki/mobilephone.png +0 -0
- package/dist/cesium/Assets/Textures/maki/monument.png +0 -0
- package/dist/cesium/Assets/Textures/maki/museum.png +0 -0
- package/dist/cesium/Assets/Textures/maki/music.png +0 -0
- package/dist/cesium/Assets/Textures/maki/oil-well.png +0 -0
- package/dist/cesium/Assets/Textures/maki/park.png +0 -0
- package/dist/cesium/Assets/Textures/maki/park2.png +0 -0
- package/dist/cesium/Assets/Textures/maki/parking-garage.png +0 -0
- package/dist/cesium/Assets/Textures/maki/parking.png +0 -0
- package/dist/cesium/Assets/Textures/maki/pharmacy.png +0 -0
- package/dist/cesium/Assets/Textures/maki/pitch.png +0 -0
- package/dist/cesium/Assets/Textures/maki/place-of-worship.png +0 -0
- package/dist/cesium/Assets/Textures/maki/playground.png +0 -0
- package/dist/cesium/Assets/Textures/maki/police.png +0 -0
- package/dist/cesium/Assets/Textures/maki/polling-place.png +0 -0
- package/dist/cesium/Assets/Textures/maki/post.png +0 -0
- package/dist/cesium/Assets/Textures/maki/prison.png +0 -0
- package/dist/cesium/Assets/Textures/maki/rail-above.png +0 -0
- package/dist/cesium/Assets/Textures/maki/rail-light.png +0 -0
- package/dist/cesium/Assets/Textures/maki/rail-metro.png +0 -0
- package/dist/cesium/Assets/Textures/maki/rail-underground.png +0 -0
- package/dist/cesium/Assets/Textures/maki/rail.png +0 -0
- package/dist/cesium/Assets/Textures/maki/religious-christian.png +0 -0
- package/dist/cesium/Assets/Textures/maki/religious-jewish.png +0 -0
- package/dist/cesium/Assets/Textures/maki/religious-muslim.png +0 -0
- package/dist/cesium/Assets/Textures/maki/restaurant.png +0 -0
- package/dist/cesium/Assets/Textures/maki/roadblock.png +0 -0
- package/dist/cesium/Assets/Textures/maki/rocket.png +0 -0
- package/dist/cesium/Assets/Textures/maki/school.png +0 -0
- package/dist/cesium/Assets/Textures/maki/scooter.png +0 -0
- package/dist/cesium/Assets/Textures/maki/shop.png +0 -0
- package/dist/cesium/Assets/Textures/maki/skiing.png +0 -0
- package/dist/cesium/Assets/Textures/maki/slaughterhouse.png +0 -0
- package/dist/cesium/Assets/Textures/maki/soccer.png +0 -0
- package/dist/cesium/Assets/Textures/maki/square-stroked.png +0 -0
- package/dist/cesium/Assets/Textures/maki/square.png +0 -0
- package/dist/cesium/Assets/Textures/maki/star-stroked.png +0 -0
- package/dist/cesium/Assets/Textures/maki/star.png +0 -0
- package/dist/cesium/Assets/Textures/maki/suitcase.png +0 -0
- package/dist/cesium/Assets/Textures/maki/swimming.png +0 -0
- package/dist/cesium/Assets/Textures/maki/telephone.png +0 -0
- package/dist/cesium/Assets/Textures/maki/tennis.png +0 -0
- package/dist/cesium/Assets/Textures/maki/theatre.png +0 -0
- package/dist/cesium/Assets/Textures/maki/toilets.png +0 -0
- package/dist/cesium/Assets/Textures/maki/town-hall.png +0 -0
- package/dist/cesium/Assets/Textures/maki/town.png +0 -0
- package/dist/cesium/Assets/Textures/maki/triangle-stroked.png +0 -0
- package/dist/cesium/Assets/Textures/maki/triangle.png +0 -0
- package/dist/cesium/Assets/Textures/maki/village.png +0 -0
- package/dist/cesium/Assets/Textures/maki/warehouse.png +0 -0
- package/dist/cesium/Assets/Textures/maki/waste-basket.png +0 -0
- package/dist/cesium/Assets/Textures/maki/water.png +0 -0
- package/dist/cesium/Assets/Textures/maki/wetland.png +0 -0
- package/dist/cesium/Assets/Textures/maki/zoo.png +0 -0
- package/dist/cesium/Assets/Textures/moonSmall.jpg +0 -0
- package/dist/cesium/Assets/Textures/pin.svg +1 -0
- package/dist/cesium/Assets/Textures/waterNormals.jpg +0 -0
- package/dist/cesium/Assets/Textures/waterNormalsSmall.jpg +0 -0
- package/dist/cesium/Assets/approximateTerrainHeights.json +1 -0
- package/dist/cesium/ThirdParty/Workers/package.json +1 -0
- package/dist/cesium/ThirdParty/Workers/zip-web-worker.js +1 -0
- package/dist/cesium/ThirdParty/basis_transcoder.wasm +0 -0
- package/dist/cesium/ThirdParty/draco_decoder.wasm +0 -0
- package/dist/cesium/ThirdParty/google-earth-dbroot-parser.js +1 -0
- package/dist/cesium/ThirdParty/wasm_splats_bg.wasm +0 -0
- package/dist/cesium/ThirdParty/zip-module.wasm +0 -0
- package/dist/cesium/Widgets/Animation/Animation.css +127 -0
- package/dist/cesium/Widgets/Animation/lighter.css +70 -0
- package/dist/cesium/Widgets/BaseLayerPicker/BaseLayerPicker.css +108 -0
- package/dist/cesium/Widgets/BaseLayerPicker/lighter.css +22 -0
- package/dist/cesium/Widgets/Cesium3DTilesInspector/Cesium3DTilesInspector.css +102 -0
- package/dist/cesium/Widgets/CesiumInspector/CesiumInspector.css +113 -0
- package/dist/cesium/Widgets/CesiumWidget/CesiumWidget.css +119 -0
- package/dist/cesium/Widgets/CesiumWidget/lighter.css +14 -0
- package/dist/cesium/Widgets/FullscreenButton/FullscreenButton.css +8 -0
- package/dist/cesium/Widgets/Geocoder/Geocoder.css +70 -0
- package/dist/cesium/Widgets/Geocoder/lighter.css +17 -0
- package/dist/cesium/Widgets/I3SBuildingSceneLayerExplorer/I3SBuildingSceneLayerExplorer.css +27 -0
- package/dist/cesium/Widgets/Images/ImageryProviders/ArcGisMapServiceWorldHillshade.png +0 -0
- package/dist/cesium/Widgets/Images/ImageryProviders/ArcGisMapServiceWorldImagery.png +0 -0
- package/dist/cesium/Widgets/Images/ImageryProviders/ArcGisMapServiceWorldOcean.png +0 -0
- package/dist/cesium/Widgets/Images/ImageryProviders/azureAerial.png +0 -0
- package/dist/cesium/Widgets/Images/ImageryProviders/azureRoads.png +0 -0
- package/dist/cesium/Widgets/Images/ImageryProviders/bingAerial.png +0 -0
- package/dist/cesium/Widgets/Images/ImageryProviders/bingAerialLabels.png +0 -0
- package/dist/cesium/Widgets/Images/ImageryProviders/bingRoads.png +0 -0
- package/dist/cesium/Widgets/Images/ImageryProviders/blueMarble.png +0 -0
- package/dist/cesium/Widgets/Images/ImageryProviders/earthAtNight.png +0 -0
- package/dist/cesium/Widgets/Images/ImageryProviders/googleContour.png +0 -0
- package/dist/cesium/Widgets/Images/ImageryProviders/googleRoadmap.png +0 -0
- package/dist/cesium/Widgets/Images/ImageryProviders/googleSatellite.png +0 -0
- package/dist/cesium/Widgets/Images/ImageryProviders/googleSatelliteLabels.png +0 -0
- package/dist/cesium/Widgets/Images/ImageryProviders/mapQuestOpenStreetMap.png +0 -0
- package/dist/cesium/Widgets/Images/ImageryProviders/mapboxSatellite.png +0 -0
- package/dist/cesium/Widgets/Images/ImageryProviders/mapboxStreets.png +0 -0
- package/dist/cesium/Widgets/Images/ImageryProviders/mapboxTerrain.png +0 -0
- package/dist/cesium/Widgets/Images/ImageryProviders/naturalEarthII.png +0 -0
- package/dist/cesium/Widgets/Images/ImageryProviders/openStreetMap.png +0 -0
- package/dist/cesium/Widgets/Images/ImageryProviders/sentinel-2.png +0 -0
- package/dist/cesium/Widgets/Images/ImageryProviders/stadiaAlidadeSmooth.png +0 -0
- package/dist/cesium/Widgets/Images/ImageryProviders/stadiaAlidadeSmoothDark.png +0 -0
- package/dist/cesium/Widgets/Images/ImageryProviders/stamenToner.png +0 -0
- package/dist/cesium/Widgets/Images/ImageryProviders/stamenWatercolor.png +0 -0
- package/dist/cesium/Widgets/Images/NavigationHelp/Mouse.svg +84 -0
- package/dist/cesium/Widgets/Images/NavigationHelp/MouseLeft.svg +76 -0
- package/dist/cesium/Widgets/Images/NavigationHelp/MouseMiddle.svg +76 -0
- package/dist/cesium/Widgets/Images/NavigationHelp/MouseRight.svg +76 -0
- package/dist/cesium/Widgets/Images/NavigationHelp/Touch.svg +120 -0
- package/dist/cesium/Widgets/Images/NavigationHelp/TouchDrag.svg +129 -0
- package/dist/cesium/Widgets/Images/NavigationHelp/TouchRotate.svg +76 -0
- package/dist/cesium/Widgets/Images/NavigationHelp/TouchTilt.svg +135 -0
- package/dist/cesium/Widgets/Images/NavigationHelp/TouchZoom.svg +74 -0
- package/dist/cesium/Widgets/Images/TerrainProviders/CesiumWorldTerrain.png +0 -0
- package/dist/cesium/Widgets/Images/TerrainProviders/Ellipsoid.png +0 -0
- package/dist/cesium/Widgets/Images/TimelineIcons.png +0 -0
- package/dist/cesium/Widgets/Images/info-loading.gif +0 -0
- package/dist/cesium/Widgets/InfoBox/InfoBox.css +92 -0
- package/dist/cesium/Widgets/InfoBox/InfoBoxDescription.css +178 -0
- package/dist/cesium/Widgets/NavigationHelpButton/NavigationHelpButton.css +93 -0
- package/dist/cesium/Widgets/NavigationHelpButton/lighter.css +38 -0
- package/dist/cesium/Widgets/PerformanceWatchdog/PerformanceWatchdog.css +15 -0
- package/dist/cesium/Widgets/ProjectionPicker/ProjectionPicker.css +38 -0
- package/dist/cesium/Widgets/SceneModePicker/SceneModePicker.css +56 -0
- package/dist/cesium/Widgets/SelectionIndicator/SelectionIndicator.css +20 -0
- package/dist/cesium/Widgets/Timeline/Timeline.css +103 -0
- package/dist/cesium/Widgets/Timeline/lighter.css +23 -0
- package/dist/cesium/Widgets/VRButton/VRButton.css +8 -0
- package/dist/cesium/Widgets/Viewer/Viewer.css +107 -0
- package/dist/cesium/Widgets/VoxelInspector/VoxelInspector.css +16 -0
- package/dist/cesium/Widgets/lighter.css +237 -0
- package/dist/cesium/Widgets/lighterShared.css +46 -0
- package/dist/cesium/Widgets/shared.css +103 -0
- package/dist/cesium/Widgets/widgets.css +1342 -0
- package/dist/cesium/Workers/chunk-23ZQ2IVV.js +29 -0
- package/dist/cesium/Workers/chunk-2EQO3Q56.js +26 -0
- package/dist/cesium/Workers/chunk-2MJIIVP4.js +26 -0
- package/dist/cesium/Workers/chunk-2TE5NTVD.js +26 -0
- package/dist/cesium/Workers/chunk-2ZBHLJST.js +26 -0
- package/dist/cesium/Workers/chunk-5TJMAQVL.js +26 -0
- package/dist/cesium/Workers/chunk-6BD4U3VO.js +26 -0
- package/dist/cesium/Workers/chunk-7TVGLKQF.js +26 -0
- package/dist/cesium/Workers/chunk-BTSYJ5XU.js +26 -0
- package/dist/cesium/Workers/chunk-BXMEEOCS.js +63 -0
- package/dist/cesium/Workers/chunk-BYLCY7GP.js +29 -0
- package/dist/cesium/Workers/chunk-CTHM3W6I.js +26 -0
- package/dist/cesium/Workers/chunk-CUUSNIVQ.js +26 -0
- package/dist/cesium/Workers/chunk-E3JOOS3S.js +26 -0
- package/dist/cesium/Workers/chunk-E7KYDCM5.js +26 -0
- package/dist/cesium/Workers/chunk-EDVBB7SS.js +27 -0
- package/dist/cesium/Workers/chunk-EFBN7QNX.js +26 -0
- package/dist/cesium/Workers/chunk-EQ4YRVWL.js +26 -0
- package/dist/cesium/Workers/chunk-F6PRE7D6.js +26 -0
- package/dist/cesium/Workers/chunk-FC4ZZ65J.js +26 -0
- package/dist/cesium/Workers/chunk-FFBVWF2L.js +26 -0
- package/dist/cesium/Workers/chunk-GBAA6GVX.js +26 -0
- package/dist/cesium/Workers/chunk-ICALLYLG.js +26 -0
- package/dist/cesium/Workers/chunk-ILRYTWTP.js +26 -0
- package/dist/cesium/Workers/chunk-IRNLBSEJ.js +26 -0
- package/dist/cesium/Workers/chunk-IX4VMHEV.js +26 -0
- package/dist/cesium/Workers/chunk-L6QHHACZ.js +26 -0
- package/dist/cesium/Workers/chunk-LI2ZSORM.js +26 -0
- package/dist/cesium/Workers/chunk-LSLE2RL4.js +26 -0
- package/dist/cesium/Workers/chunk-M4HLDBCG.js +26 -0
- package/dist/cesium/Workers/chunk-MJHHSGEH.js +26 -0
- package/dist/cesium/Workers/chunk-NMVKML6W.js +26 -0
- package/dist/cesium/Workers/chunk-OCWJRAXS.js +26 -0
- package/dist/cesium/Workers/chunk-OIRKANTH.js +26 -0
- package/dist/cesium/Workers/chunk-OIT7J4IC.js +26 -0
- package/dist/cesium/Workers/chunk-OLZ3FYUM.js +26 -0
- package/dist/cesium/Workers/chunk-Q5BPHJQF.js +26 -0
- package/dist/cesium/Workers/chunk-QFM5DCMQ.js +26 -0
- package/dist/cesium/Workers/chunk-QKUIYMGC.js +28 -0
- package/dist/cesium/Workers/chunk-S44JILQT.js +26 -0
- package/dist/cesium/Workers/chunk-SLT4J352.js +26 -0
- package/dist/cesium/Workers/chunk-SQMIIXB7.js +26 -0
- package/dist/cesium/Workers/chunk-TJ4XLGBQ.js +26 -0
- package/dist/cesium/Workers/chunk-TNSUQXWK.js +27 -0
- package/dist/cesium/Workers/chunk-UBOGZS7F.js +26 -0
- package/dist/cesium/Workers/chunk-V3OSTMM6.js +26 -0
- package/dist/cesium/Workers/chunk-V7QEYVP3.js +26 -0
- package/dist/cesium/Workers/chunk-VUKYSU4H.js +26 -0
- package/dist/cesium/Workers/chunk-W37FE5GR.js +26 -0
- package/dist/cesium/Workers/chunk-WBOV35NL.js +26 -0
- package/dist/cesium/Workers/chunk-WPMZLB3Y.js +26 -0
- package/dist/cesium/Workers/chunk-WWWZVEEH.js +26 -0
- package/dist/cesium/Workers/chunk-XFIQ5DEQ.js +28 -0
- package/dist/cesium/Workers/chunk-XQHLGIO7.js +26 -0
- package/dist/cesium/Workers/chunk-XUSCFAVF.js +26 -0
- package/dist/cesium/Workers/chunk-YP7I5QBZ.js +26 -0
- package/dist/cesium/Workers/chunk-Z3QF2EHT.js +26 -0
- package/dist/cesium/Workers/combineGeometry.js +26 -0
- package/dist/cesium/Workers/createBoxGeometry.js +26 -0
- package/dist/cesium/Workers/createBoxOutlineGeometry.js +26 -0
- package/dist/cesium/Workers/createCircleGeometry.js +26 -0
- package/dist/cesium/Workers/createCircleOutlineGeometry.js +26 -0
- package/dist/cesium/Workers/createCoplanarPolygonGeometry.js +26 -0
- package/dist/cesium/Workers/createCoplanarPolygonOutlineGeometry.js +26 -0
- package/dist/cesium/Workers/createCorridorGeometry.js +26 -0
- package/dist/cesium/Workers/createCorridorOutlineGeometry.js +26 -0
- package/dist/cesium/Workers/createCylinderGeometry.js +26 -0
- package/dist/cesium/Workers/createCylinderOutlineGeometry.js +26 -0
- package/dist/cesium/Workers/createEllipseGeometry.js +26 -0
- package/dist/cesium/Workers/createEllipseOutlineGeometry.js +26 -0
- package/dist/cesium/Workers/createEllipsoidGeometry.js +26 -0
- package/dist/cesium/Workers/createEllipsoidOutlineGeometry.js +26 -0
- package/dist/cesium/Workers/createFrustumGeometry.js +26 -0
- package/dist/cesium/Workers/createFrustumOutlineGeometry.js +26 -0
- package/dist/cesium/Workers/createGeometry.js +26 -0
- package/dist/cesium/Workers/createGroundPolylineGeometry.js +26 -0
- package/dist/cesium/Workers/createPlaneGeometry.js +26 -0
- package/dist/cesium/Workers/createPlaneOutlineGeometry.js +26 -0
- package/dist/cesium/Workers/createPolygonGeometry.js +26 -0
- package/dist/cesium/Workers/createPolygonOutlineGeometry.js +26 -0
- package/dist/cesium/Workers/createPolylineGeometry.js +26 -0
- package/dist/cesium/Workers/createPolylineVolumeGeometry.js +26 -0
- package/dist/cesium/Workers/createPolylineVolumeOutlineGeometry.js +26 -0
- package/dist/cesium/Workers/createRectangleGeometry.js +26 -0
- package/dist/cesium/Workers/createRectangleOutlineGeometry.js +26 -0
- package/dist/cesium/Workers/createSimplePolylineGeometry.js +26 -0
- package/dist/cesium/Workers/createSphereGeometry.js +26 -0
- package/dist/cesium/Workers/createSphereOutlineGeometry.js +26 -0
- package/dist/cesium/Workers/createTaskProcessorWorker.js +26 -0
- package/dist/cesium/Workers/createVectorTileClampedPolylines.js +26 -0
- package/dist/cesium/Workers/createVectorTileGeometries.js +26 -0
- package/dist/cesium/Workers/createVectorTilePoints.js +26 -0
- package/dist/cesium/Workers/createVectorTilePolygons.js +26 -0
- package/dist/cesium/Workers/createVectorTilePolylines.js +26 -0
- package/dist/cesium/Workers/createVerticesFromCesium3DTilesTerrain.js +26 -0
- package/dist/cesium/Workers/createVerticesFromGoogleEarthEnterpriseBuffer.js +26 -0
- package/dist/cesium/Workers/createVerticesFromHeightmap.js +26 -0
- package/dist/cesium/Workers/createVerticesFromQuantizedTerrainMesh.js +26 -0
- package/dist/cesium/Workers/createWallGeometry.js +26 -0
- package/dist/cesium/Workers/createWallOutlineGeometry.js +26 -0
- package/dist/cesium/Workers/decodeDraco.js +26 -0
- package/dist/cesium/Workers/decodeGoogleEarthEnterprisePacket.js +26 -0
- package/dist/cesium/Workers/decodeI3S.js +26 -0
- package/dist/cesium/Workers/gaussianSplatSorter.js +26 -0
- package/dist/cesium/Workers/gaussianSplatTextureGenerator.js +26 -0
- package/dist/cesium/Workers/incrementallyBuildTerrainPicker.js +26 -0
- package/dist/cesium/Workers/transcodeKTX2.js +56 -0
- package/dist/cesium/Workers/transferTypedArrayTest.js +26 -0
- package/dist/cesium/Workers/upsampleQuantizedTerrainMesh.js +26 -0
- package/dist/cesium/Workers/upsampleVerticesFromCesium3DTilesTerrain.js +26 -0
- package/dist/index.html +10 -8
- package/package.json +15 -12
- package/src/App.tsx +1 -17
- package/src/components/viewer/BCFPanel.tsx +46 -4
- package/src/components/viewer/CesiumOverlay.tsx +672 -0
- package/src/components/viewer/CesiumSettingsDialog.tsx +100 -0
- package/src/components/viewer/ChatPanel.tsx +54 -16
- package/src/components/viewer/CommandPalette.tsx +6 -1
- package/src/components/viewer/DesktopEntitlementBanner.tsx +74 -0
- package/src/components/viewer/ExportChangesButton.tsx +6 -1
- package/src/components/viewer/ExportDialog.tsx +22 -6
- package/src/components/viewer/HierarchyPanel.tsx +196 -0
- package/src/components/viewer/IDSPanel.tsx +52 -3
- package/src/components/viewer/KeyboardShortcutsDialog.tsx +1 -1
- package/src/components/viewer/MainToolbar.tsx +353 -27
- package/src/components/viewer/PropertiesPanel.tsx +218 -79
- package/src/components/viewer/ScriptPanel.tsx +34 -8
- package/src/components/viewer/SettingsPage.tsx +430 -0
- package/src/components/viewer/StatusBar.tsx +17 -1
- package/src/components/viewer/UpgradePage.tsx +6 -4
- package/src/components/viewer/ViewerLayout.tsx +47 -6
- package/src/components/viewer/Viewport.tsx +49 -8
- package/src/components/viewer/ViewportContainer.tsx +280 -28
- package/src/components/viewer/ViewportOverlays.tsx +129 -27
- package/src/components/viewer/properties/GeoreferencingPanel.tsx +117 -5
- package/src/components/viewer/properties/LocationMap.tsx +458 -17
- package/src/components/viewer/selectionHandlers.ts +4 -3
- package/src/components/viewer/useAnimationLoop.ts +4 -0
- package/src/components/viewer/useGeometryStreaming.ts +127 -40
- package/src/components/viewer/useMouseControls.ts +4 -1
- package/src/hooks/ingest/viewerModelIngest.ts +275 -0
- package/src/hooks/useIDS.ts +1 -1
- package/src/hooks/useIfc.ts +7 -1
- package/src/hooks/useIfcCache.ts +28 -15
- package/src/hooks/useIfcFederation.ts +57 -225
- package/src/hooks/useIfcLoader.ts +1656 -130
- package/src/hooks/useIfcServer.ts +0 -69
- package/src/lib/desktop/ClerkDesktopEntitlementSync.tsx +175 -0
- package/src/lib/desktop/desktopEntitlementEvents.ts +39 -0
- package/src/lib/desktop-entitlement.ts +45 -0
- package/src/lib/desktop-product.ts +124 -0
- package/src/lib/geo/cesium-bridge.ts +310 -0
- package/src/lib/geo/reproject.ts +151 -25
- package/src/lib/recent-files.ts +2 -1
- package/src/services/analysis-extensions.ts +125 -0
- package/src/services/app-navigation.ts +13 -0
- package/src/services/bsdd.ts +53 -4
- package/src/services/cacheService.ts +1 -1
- package/src/services/desktop-cache.ts +43 -0
- package/src/services/desktop-export.ts +77 -0
- package/src/services/desktop-harness.ts +196 -0
- package/src/services/desktop-logger.ts +20 -0
- package/src/services/desktop-native-metadata.ts +207 -0
- package/src/services/desktop-panel-actions.ts +43 -0
- package/src/services/desktop-preferences.ts +44 -0
- package/src/services/file-dialog.ts +147 -0
- package/src/services/tauri-core-stub.ts +7 -0
- package/src/services/tauri-dialog-stub.ts +7 -0
- package/src/services/tauri-fs-stub.ts +7 -0
- package/src/store/index.ts +40 -2
- package/src/store/slices/cesiumSlice.ts +122 -0
- package/src/store/slices/chatSlice.ts +5 -1
- package/src/store/slices/dataSlice.ts +139 -28
- package/src/store/slices/desktopEntitlementSlice.ts +86 -0
- package/src/store/slices/loadingSlice.ts +14 -2
- package/src/store/slices/modelSlice.ts +58 -3
- package/src/store/types.ts +96 -2
- package/src/store.ts +1 -1
- package/src/utils/desktopModelSnapshot.ts +358 -0
- package/src/utils/ifcConfig.ts +6 -1
- package/src/utils/nativeSpatialDataStore.ts +250 -0
- package/src/utils/serverDataModel.ts +4 -0
- package/src/utils/spatialHierarchy.ts +10 -11
- package/vite.config.ts +24 -0
- package/dist/assets/arrow-DJf2ErbF.js +0 -20
- package/dist/assets/basketViewActivator-aojwdomq.js +0 -1
- package/dist/assets/desktop-cache-oPzaWXYE.js +0 -1
- package/dist/assets/geometry.worker-Nz9_YIqh.js +0 -1
- package/dist/assets/ifc-lite_bg-eSkBTizQ.wasm +0 -0
- package/dist/assets/index-pbE7itQS.css +0 -1
- package/dist/assets/native-bridge-DSIyEYXG.js +0 -113
- package/dist/assets/wasm-bridge-B0J07fZZ.js +0 -1
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
3
3
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
|
4
4
|
|
|
5
|
-
import React, { useRef, useCallback, useEffect, useMemo } from 'react';
|
|
5
|
+
import React, { useRef, useCallback, useEffect, useMemo, useSyncExternalStore } from 'react';
|
|
6
6
|
import {
|
|
7
7
|
FolderOpen,
|
|
8
8
|
Download,
|
|
@@ -37,6 +37,8 @@ import {
|
|
|
37
37
|
Layout,
|
|
38
38
|
LayoutTemplate,
|
|
39
39
|
FileCode2,
|
|
40
|
+
Globe2,
|
|
41
|
+
Settings,
|
|
40
42
|
} from 'lucide-react';
|
|
41
43
|
import { Button } from '@/components/ui/button';
|
|
42
44
|
import { Separator } from '@/components/ui/separator';
|
|
@@ -64,13 +66,30 @@ import { ExportDialog } from './ExportDialog';
|
|
|
64
66
|
import { BulkPropertyEditor } from './BulkPropertyEditor';
|
|
65
67
|
import { DataConnector } from './DataConnector';
|
|
66
68
|
import { ExportChangesButton } from './ExportChangesButton';
|
|
69
|
+
// CesiumSettingsDialog removed — settings now shown as overlay on Cesium viewer
|
|
67
70
|
import { useFloorplanView } from '@/hooks/useFloorplanView';
|
|
71
|
+
import { buildDesktopUpgradeUrl, hasDesktopFeatureAccess, type DesktopFeature } from '@/lib/desktop-product';
|
|
68
72
|
import { recordRecentFiles, cacheFileBlobs } from '@/lib/recent-files';
|
|
69
73
|
import { ThemeSwitch } from './ThemeSwitch';
|
|
70
74
|
import { toast } from '@/components/ui/toast';
|
|
75
|
+
import { navigateToPath } from '@/services/app-navigation';
|
|
76
|
+
import { getStartupHarnessRequest, setActiveHarnessRequest, tryClaimStartupHarnessRequest } from '@/services/desktop-harness';
|
|
77
|
+
import { logToDesktopTerminal } from '@/services/desktop-logger';
|
|
78
|
+
import { openIfcFileDialog, type NativeFileHandle } from '@/services/file-dialog';
|
|
79
|
+
import { isTauri } from '@/lib/platform';
|
|
80
|
+
import {
|
|
81
|
+
closeActiveAnalysisExtension,
|
|
82
|
+
getAnalysisExtensionsSnapshot,
|
|
83
|
+
openAnalysisExtension,
|
|
84
|
+
subscribeAnalysisExtensions,
|
|
85
|
+
} from '@/services/analysis-extensions';
|
|
71
86
|
|
|
72
87
|
type Tool = 'select' | 'walk' | 'measure' | 'section';
|
|
73
|
-
type WorkspacePanel = 'script' | 'list' | 'bcf' | 'ids' | 'lens';
|
|
88
|
+
type WorkspacePanel = 'script' | 'list' | 'bcf' | 'ids' | 'lens' | string;
|
|
89
|
+
|
|
90
|
+
function isNativeFileHandle(file: File | NativeFileHandle): file is NativeFileHandle {
|
|
91
|
+
return typeof (file as NativeFileHandle).path === 'string';
|
|
92
|
+
}
|
|
74
93
|
|
|
75
94
|
// #region FIX: Move ToolButton OUTSIDE MainToolbar to prevent recreation on every render
|
|
76
95
|
// This fixes Radix UI Tooltip's asChild prop becoming stale during re-renders
|
|
@@ -148,18 +167,109 @@ interface MainToolbarProps {
|
|
|
148
167
|
export function MainToolbar({ onShowShortcuts }: MainToolbarProps = {} as MainToolbarProps) {
|
|
149
168
|
const fileInputRef = useRef<HTMLInputElement>(null);
|
|
150
169
|
const addModelInputRef = useRef<HTMLInputElement>(null);
|
|
151
|
-
const {
|
|
170
|
+
const {
|
|
171
|
+
loadFile,
|
|
172
|
+
loading,
|
|
173
|
+
progress,
|
|
174
|
+
geometryProgress,
|
|
175
|
+
metadataProgress,
|
|
176
|
+
geometryResult,
|
|
177
|
+
ifcDataStore,
|
|
178
|
+
models,
|
|
179
|
+
clearAllModels,
|
|
180
|
+
loadFilesSequentially,
|
|
181
|
+
loadFederatedIfcx,
|
|
182
|
+
addIfcxOverlays,
|
|
183
|
+
addModel,
|
|
184
|
+
} = useIfc();
|
|
152
185
|
|
|
153
186
|
// Listen for programmatic file-load requests (from command palette recent files)
|
|
154
187
|
useEffect(() => {
|
|
155
188
|
const handler = (e: Event) => {
|
|
156
|
-
const file = (e as CustomEvent<File>).detail;
|
|
157
|
-
if (file)
|
|
189
|
+
const file = (e as CustomEvent<File | NativeFileHandle>).detail;
|
|
190
|
+
if (file) {
|
|
191
|
+
recordRecentFiles([isNativeFileHandle(file)
|
|
192
|
+
? { name: file.name, size: file.size, path: file.path, modifiedMs: file.modifiedMs ?? null }
|
|
193
|
+
: { name: file.name, size: file.size }]);
|
|
194
|
+
void loadFile(file);
|
|
195
|
+
}
|
|
158
196
|
};
|
|
159
197
|
window.addEventListener('ifc-lite:load-file', handler);
|
|
160
198
|
return () => window.removeEventListener('ifc-lite:load-file', handler);
|
|
161
199
|
}, [loadFile]);
|
|
162
200
|
|
|
201
|
+
useEffect(() => {
|
|
202
|
+
let cancelled = false;
|
|
203
|
+
const sleep = (ms: number) => new Promise((resolve) => globalThis.setTimeout(resolve, ms));
|
|
204
|
+
|
|
205
|
+
const waitForViewerToSettle = async (label: string) => {
|
|
206
|
+
const timeoutMs = 120_000;
|
|
207
|
+
const pollMs = 100;
|
|
208
|
+
const start = performance.now();
|
|
209
|
+
while (!cancelled) {
|
|
210
|
+
const state = useViewerStore.getState();
|
|
211
|
+
const meshCount = state.geometryResult?.meshes.length ?? 0;
|
|
212
|
+
if (!state.loading && meshCount > 0) {
|
|
213
|
+
void logToDesktopTerminal(
|
|
214
|
+
'info',
|
|
215
|
+
`[DesktopHarness] ${label} settled: loading=${state.loading} meshes=${meshCount} progress=${state.progress?.phase ?? 'none'}`
|
|
216
|
+
);
|
|
217
|
+
return;
|
|
218
|
+
}
|
|
219
|
+
if (performance.now() - start >= timeoutMs) {
|
|
220
|
+
throw new Error(`[DesktopHarness] Timed out waiting for ${label} to settle`);
|
|
221
|
+
}
|
|
222
|
+
await sleep(pollMs);
|
|
223
|
+
}
|
|
224
|
+
};
|
|
225
|
+
|
|
226
|
+
void (async () => {
|
|
227
|
+
void logToDesktopTerminal('info', '[DesktopHarness] MainToolbar startup harness effect running');
|
|
228
|
+
const request = await getStartupHarnessRequest();
|
|
229
|
+
if (!request || cancelled) {
|
|
230
|
+
void logToDesktopTerminal(
|
|
231
|
+
'info',
|
|
232
|
+
`[DesktopHarness] No startup harness request available (cancelled=${cancelled})`
|
|
233
|
+
);
|
|
234
|
+
return;
|
|
235
|
+
}
|
|
236
|
+
if (!tryClaimStartupHarnessRequest(request)) {
|
|
237
|
+
void logToDesktopTerminal('info', `[DesktopHarness] Startup harness request already claimed for ${request.file.path}`);
|
|
238
|
+
return;
|
|
239
|
+
}
|
|
240
|
+
void logToDesktopTerminal('info', `[DesktopHarness] Claimed startup harness request for ${request.file.path}`);
|
|
241
|
+
console.log(`[DesktopHarness] Auto-loading startup file: ${request.file.path}`);
|
|
242
|
+
if (!request.replaceFile) {
|
|
243
|
+
void logToDesktopTerminal('info', `[DesktopHarness] Calling loadFile for ${request.file.path}`);
|
|
244
|
+
await loadFile(request.file);
|
|
245
|
+
return;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
void logToDesktopTerminal(
|
|
249
|
+
'info',
|
|
250
|
+
`[DesktopHarness] Running replacement sequence first=${request.file.path} second=${request.replaceFile.path}`
|
|
251
|
+
);
|
|
252
|
+
setActiveHarnessRequest(null);
|
|
253
|
+
await loadFile(request.file);
|
|
254
|
+
await waitForViewerToSettle(`first load ${request.file.name}`);
|
|
255
|
+
if (cancelled) {
|
|
256
|
+
return;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
setActiveHarnessRequest({
|
|
260
|
+
...request,
|
|
261
|
+
file: request.replaceFile,
|
|
262
|
+
replaceFile: undefined,
|
|
263
|
+
});
|
|
264
|
+
void logToDesktopTerminal('info', `[DesktopHarness] Calling replacement loadFile for ${request.replaceFile.path}`);
|
|
265
|
+
await loadFile(request.replaceFile);
|
|
266
|
+
})();
|
|
267
|
+
|
|
268
|
+
return () => {
|
|
269
|
+
cancelled = true;
|
|
270
|
+
};
|
|
271
|
+
}, [loadFile]);
|
|
272
|
+
|
|
163
273
|
// Floorplan view
|
|
164
274
|
const { availableStoreys, activateFloorplan } = useFloorplanView();
|
|
165
275
|
|
|
@@ -195,6 +305,29 @@ export function MainToolbar({ onShowShortcuts }: MainToolbarProps = {} as MainTo
|
|
|
195
305
|
const setLensPanelVisible = useViewerStore((state) => state.setLensPanelVisible);
|
|
196
306
|
const scriptPanelVisible = useViewerStore((state) => state.scriptPanelVisible);
|
|
197
307
|
const setScriptPanelVisible = useViewerStore((state) => state.setScriptPanelVisible);
|
|
308
|
+
// Cesium 3D overlay state
|
|
309
|
+
const cesiumEnabled = useViewerStore((state) => state.cesiumEnabled);
|
|
310
|
+
const toggleCesium = useViewerStore((state) => state.toggleCesium);
|
|
311
|
+
const storeModels = useViewerStore((state) => state.models);
|
|
312
|
+
const desktopEntitlement = useViewerStore((state) => state.desktopEntitlement);
|
|
313
|
+
const analysisExtensionState = useSyncExternalStore(
|
|
314
|
+
subscribeAnalysisExtensions,
|
|
315
|
+
getAnalysisExtensionsSnapshot,
|
|
316
|
+
getAnalysisExtensionsSnapshot,
|
|
317
|
+
);
|
|
318
|
+
const activeAnalysisExtension = useMemo(
|
|
319
|
+
() => analysisExtensionState.extensions.find((extension) => extension.id === analysisExtensionState.activeId) ?? null,
|
|
320
|
+
[analysisExtensionState.activeId, analysisExtensionState.extensions],
|
|
321
|
+
);
|
|
322
|
+
const rightAnalysisExtensions = useMemo(
|
|
323
|
+
() => analysisExtensionState.extensions.filter((extension) => (extension.placement ?? 'right') === 'right'),
|
|
324
|
+
[analysisExtensionState.extensions],
|
|
325
|
+
);
|
|
326
|
+
const bottomAnalysisExtensions = useMemo(
|
|
327
|
+
() => analysisExtensionState.extensions.filter((extension) => (extension.placement ?? 'right') === 'bottom'),
|
|
328
|
+
[analysisExtensionState.extensions],
|
|
329
|
+
);
|
|
330
|
+
const desktopShell = isTauri();
|
|
198
331
|
|
|
199
332
|
// Check which type geometries exist across ALL loaded models (federation-aware).
|
|
200
333
|
// PERF: Use meshes.length as dep proxy instead of full geometryResult, and
|
|
@@ -361,7 +494,23 @@ export function MainToolbar({ onShowShortcuts }: MainToolbarProps = {} as MainTo
|
|
|
361
494
|
goHomeFromStore();
|
|
362
495
|
}, []);
|
|
363
496
|
|
|
497
|
+
const promptDesktopUpgrade = useCallback((featureLabel: string) => {
|
|
498
|
+
toast.info(`${featureLabel} is available with Desktop Pro`);
|
|
499
|
+
navigateToPath(buildDesktopUpgradeUrl());
|
|
500
|
+
}, []);
|
|
501
|
+
|
|
502
|
+
const requireDesktopFeature = useCallback((feature: DesktopFeature, label: string) => {
|
|
503
|
+
if (hasDesktopFeatureAccess(desktopEntitlement, feature)) {
|
|
504
|
+
return true;
|
|
505
|
+
}
|
|
506
|
+
promptDesktopUpgrade(label);
|
|
507
|
+
return false;
|
|
508
|
+
}, [desktopEntitlement, promptDesktopUpgrade]);
|
|
509
|
+
|
|
364
510
|
const handleToggleBottomPanel = useCallback((panel: 'script' | 'list') => {
|
|
511
|
+
if (activeAnalysisExtension?.placement === 'bottom') {
|
|
512
|
+
closeActiveAnalysisExtension();
|
|
513
|
+
}
|
|
365
514
|
const isScriptPanel = panel === 'script';
|
|
366
515
|
const nextScriptVisible = isScriptPanel ? !scriptPanelVisible : false;
|
|
367
516
|
const nextListVisible = isScriptPanel ? false : !listPanelVisible;
|
|
@@ -372,9 +521,19 @@ export function MainToolbar({ onShowShortcuts }: MainToolbarProps = {} as MainTo
|
|
|
372
521
|
if (nextScriptVisible || nextListVisible) {
|
|
373
522
|
setRightPanelCollapsed(false);
|
|
374
523
|
}
|
|
375
|
-
}, [listPanelVisible, scriptPanelVisible, setListPanelVisible, setRightPanelCollapsed, setScriptPanelVisible]);
|
|
524
|
+
}, [activeAnalysisExtension?.placement, listPanelVisible, scriptPanelVisible, setListPanelVisible, setRightPanelCollapsed, setScriptPanelVisible]);
|
|
376
525
|
|
|
377
526
|
const handleToggleRightPanel = useCallback((panel: 'bcf' | 'ids' | 'lens') => {
|
|
527
|
+
if (activeAnalysisExtension?.placement !== 'bottom') {
|
|
528
|
+
closeActiveAnalysisExtension();
|
|
529
|
+
}
|
|
530
|
+
if (panel === 'bcf' && !requireDesktopFeature('bcf_issue_management', 'BCF issue management')) {
|
|
531
|
+
return;
|
|
532
|
+
}
|
|
533
|
+
if (panel === 'ids' && !requireDesktopFeature('ids_validation', 'IDS validation')) {
|
|
534
|
+
return;
|
|
535
|
+
}
|
|
536
|
+
|
|
378
537
|
const nextBcfVisible = panel === 'bcf' ? !bcfPanelVisible : false;
|
|
379
538
|
const nextIdsVisible = panel === 'ids' ? !idsPanelVisible : false;
|
|
380
539
|
const nextLensVisible = panel === 'lens' ? !lensPanelVisible : false;
|
|
@@ -387,13 +546,53 @@ export function MainToolbar({ onShowShortcuts }: MainToolbarProps = {} as MainTo
|
|
|
387
546
|
setRightPanelCollapsed(false);
|
|
388
547
|
}
|
|
389
548
|
}, [
|
|
549
|
+
activeAnalysisExtension?.placement,
|
|
390
550
|
bcfPanelVisible,
|
|
391
551
|
idsPanelVisible,
|
|
392
552
|
lensPanelVisible,
|
|
553
|
+
requireDesktopFeature,
|
|
554
|
+
setBcfPanelVisible,
|
|
555
|
+
setIdsPanelVisible,
|
|
556
|
+
setLensPanelVisible,
|
|
557
|
+
setRightPanelCollapsed,
|
|
558
|
+
]);
|
|
559
|
+
|
|
560
|
+
const handleToggleAnalysisExtension = useCallback((id: string) => {
|
|
561
|
+
const extension = analysisExtensionState.extensions.find((candidate) => candidate.id === id);
|
|
562
|
+
if (!extension) {
|
|
563
|
+
return;
|
|
564
|
+
}
|
|
565
|
+
|
|
566
|
+
if (analysisExtensionState.activeId === id) {
|
|
567
|
+
closeActiveAnalysisExtension();
|
|
568
|
+
return;
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
const opened = openAnalysisExtension(id);
|
|
572
|
+
if (!opened) {
|
|
573
|
+
return;
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
if ((extension.placement ?? 'right') === 'bottom') {
|
|
577
|
+
setScriptPanelVisible(false);
|
|
578
|
+
setListPanelVisible(false);
|
|
579
|
+
setRightPanelCollapsed(false);
|
|
580
|
+
return;
|
|
581
|
+
}
|
|
582
|
+
|
|
583
|
+
setBcfPanelVisible(false);
|
|
584
|
+
setIdsPanelVisible(false);
|
|
585
|
+
setLensPanelVisible(false);
|
|
586
|
+
setRightPanelCollapsed(false);
|
|
587
|
+
}, [
|
|
588
|
+
analysisExtensionState.activeId,
|
|
589
|
+
analysisExtensionState.extensions,
|
|
393
590
|
setBcfPanelVisible,
|
|
394
591
|
setIdsPanelVisible,
|
|
395
592
|
setLensPanelVisible,
|
|
593
|
+
setListPanelVisible,
|
|
396
594
|
setRightPanelCollapsed,
|
|
595
|
+
setScriptPanelVisible,
|
|
397
596
|
]);
|
|
398
597
|
|
|
399
598
|
const activeWorkspacePanels = useMemo(() => {
|
|
@@ -403,8 +602,16 @@ export function MainToolbar({ onShowShortcuts }: MainToolbarProps = {} as MainTo
|
|
|
403
602
|
if (bcfPanelVisible) panels.add('bcf');
|
|
404
603
|
if (idsPanelVisible) panels.add('ids');
|
|
405
604
|
if (lensPanelVisible) panels.add('lens');
|
|
605
|
+
if (analysisExtensionState.activeId) panels.add(analysisExtensionState.activeId);
|
|
406
606
|
return panels;
|
|
407
|
-
}, [
|
|
607
|
+
}, [
|
|
608
|
+
analysisExtensionState.activeId,
|
|
609
|
+
bcfPanelVisible,
|
|
610
|
+
idsPanelVisible,
|
|
611
|
+
lensPanelVisible,
|
|
612
|
+
listPanelVisible,
|
|
613
|
+
scriptPanelVisible,
|
|
614
|
+
]);
|
|
408
615
|
|
|
409
616
|
const workspacePanelLabel = useMemo(() => {
|
|
410
617
|
if (activeWorkspacePanels.size === 0) return null;
|
|
@@ -413,10 +620,12 @@ export function MainToolbar({ onShowShortcuts }: MainToolbarProps = {} as MainTo
|
|
|
413
620
|
if (activeWorkspacePanels.has('list')) return 'Lists';
|
|
414
621
|
if (activeWorkspacePanels.has('bcf')) return 'BCF Issues';
|
|
415
622
|
if (activeWorkspacePanels.has('ids')) return 'IDS Validation';
|
|
416
|
-
return 'Lens Rules';
|
|
417
|
-
|
|
623
|
+
if (activeWorkspacePanels.has('lens')) return 'Lens Rules';
|
|
624
|
+
return activeAnalysisExtension?.label ?? 'Analysis';
|
|
625
|
+
}, [activeAnalysisExtension?.label, activeWorkspacePanels]);
|
|
418
626
|
|
|
419
627
|
const handleExportGLB = useCallback(() => {
|
|
628
|
+
if (!requireDesktopFeature('exports', 'Exports')) return;
|
|
420
629
|
if (!geometryResult) return;
|
|
421
630
|
try {
|
|
422
631
|
const exporter = new GLTFExporter(geometryResult);
|
|
@@ -433,9 +642,10 @@ export function MainToolbar({ onShowShortcuts }: MainToolbarProps = {} as MainTo
|
|
|
433
642
|
console.error('Export failed:', err);
|
|
434
643
|
toast.error(`GLB export failed: ${err instanceof Error ? err.message : 'Unknown error'}`);
|
|
435
644
|
}
|
|
436
|
-
}, [geometryResult]);
|
|
645
|
+
}, [geometryResult, requireDesktopFeature]);
|
|
437
646
|
|
|
438
647
|
const handleScreenshot = useCallback(() => {
|
|
648
|
+
if (!requireDesktopFeature('exports', 'Exports')) return;
|
|
439
649
|
const canvas = document.querySelector('canvas');
|
|
440
650
|
if (!canvas) return;
|
|
441
651
|
try {
|
|
@@ -449,9 +659,10 @@ export function MainToolbar({ onShowShortcuts }: MainToolbarProps = {} as MainTo
|
|
|
449
659
|
console.error('Screenshot failed:', err);
|
|
450
660
|
toast.error('Screenshot failed');
|
|
451
661
|
}
|
|
452
|
-
}, []);
|
|
662
|
+
}, [requireDesktopFeature]);
|
|
453
663
|
|
|
454
664
|
const handleExportCSV = useCallback((type: 'entities' | 'properties' | 'quantities' | 'spatial') => {
|
|
665
|
+
if (!requireDesktopFeature('exports', 'Exports')) return;
|
|
455
666
|
if (!ifcDataStore) return;
|
|
456
667
|
try {
|
|
457
668
|
const exporter = new CSVExporter(ifcDataStore);
|
|
@@ -489,9 +700,10 @@ export function MainToolbar({ onShowShortcuts }: MainToolbarProps = {} as MainTo
|
|
|
489
700
|
console.error('CSV export failed:', err);
|
|
490
701
|
toast.error(`CSV export failed: ${err instanceof Error ? err.message : 'Unknown error'}`);
|
|
491
702
|
}
|
|
492
|
-
}, [ifcDataStore]);
|
|
703
|
+
}, [ifcDataStore, requireDesktopFeature]);
|
|
493
704
|
|
|
494
705
|
const handleExportJSON = useCallback(() => {
|
|
706
|
+
if (!requireDesktopFeature('exports', 'Exports')) return;
|
|
495
707
|
if (!ifcDataStore) return;
|
|
496
708
|
try {
|
|
497
709
|
const entities: Record<string, unknown>[] = [];
|
|
@@ -519,7 +731,7 @@ export function MainToolbar({ onShowShortcuts }: MainToolbarProps = {} as MainTo
|
|
|
519
731
|
console.error('JSON export failed:', err);
|
|
520
732
|
toast.error(`JSON export failed: ${err instanceof Error ? err.message : 'Unknown error'}`);
|
|
521
733
|
}
|
|
522
|
-
}, [ifcDataStore]);
|
|
734
|
+
}, [ifcDataStore, requireDesktopFeature]);
|
|
523
735
|
|
|
524
736
|
return (
|
|
525
737
|
<div className="flex items-center gap-1 px-2 h-12 border-b bg-white dark:bg-black border-zinc-200 dark:border-zinc-800 relative z-50">
|
|
@@ -547,9 +759,25 @@ export function MainToolbar({ onShowShortcuts }: MainToolbarProps = {} as MainTo
|
|
|
547
759
|
<Button
|
|
548
760
|
variant="ghost"
|
|
549
761
|
size="icon-sm"
|
|
550
|
-
onClick={(e) => {
|
|
762
|
+
onClick={async (e) => {
|
|
551
763
|
// Blur button to close tooltip before opening file dialog
|
|
552
764
|
(e.currentTarget as HTMLButtonElement).blur();
|
|
765
|
+
|
|
766
|
+
void logToDesktopTerminal('info', '[MainToolbar] Open file button clicked');
|
|
767
|
+
const file = await openIfcFileDialog();
|
|
768
|
+
if (file) {
|
|
769
|
+
void logToDesktopTerminal('info', `[MainToolbar] Native dialog selected ${file.path}`);
|
|
770
|
+
recordRecentFiles([{
|
|
771
|
+
name: file.name,
|
|
772
|
+
size: file.size,
|
|
773
|
+
path: file.path,
|
|
774
|
+
modifiedMs: file.modifiedMs ?? null,
|
|
775
|
+
}]);
|
|
776
|
+
void loadFile(file);
|
|
777
|
+
return;
|
|
778
|
+
}
|
|
779
|
+
|
|
780
|
+
void logToDesktopTerminal('info', '[MainToolbar] Falling back to browser file input');
|
|
553
781
|
fileInputRef.current?.click();
|
|
554
782
|
}}
|
|
555
783
|
disabled={loading}
|
|
@@ -592,14 +820,21 @@ export function MainToolbar({ onShowShortcuts }: MainToolbarProps = {} as MainTo
|
|
|
592
820
|
</Button>
|
|
593
821
|
</DropdownMenuTrigger>
|
|
594
822
|
<DropdownMenuContent>
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
<
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
823
|
+
{hasDesktopFeatureAccess(desktopEntitlement, 'exports') ? (
|
|
824
|
+
<ExportDialog
|
|
825
|
+
trigger={
|
|
826
|
+
<DropdownMenuItem onSelect={(e) => e.preventDefault()}>
|
|
827
|
+
<FileText className="h-4 w-4 mr-2" />
|
|
828
|
+
Export IFC (with changes)
|
|
829
|
+
</DropdownMenuItem>
|
|
830
|
+
}
|
|
831
|
+
/>
|
|
832
|
+
) : (
|
|
833
|
+
<DropdownMenuItem onClick={() => promptDesktopUpgrade('Exports')}>
|
|
834
|
+
<FileText className="h-4 w-4 mr-2" />
|
|
835
|
+
Export IFC (with changes)
|
|
836
|
+
</DropdownMenuItem>
|
|
837
|
+
)}
|
|
603
838
|
<DropdownMenuSeparator />
|
|
604
839
|
<DropdownMenuItem onClick={handleExportGLB}>
|
|
605
840
|
<Download className="h-4 w-4 mr-2" />
|
|
@@ -676,7 +911,9 @@ export function MainToolbar({ onShowShortcuts }: MainToolbarProps = {} as MainTo
|
|
|
676
911
|
</DropdownMenu>
|
|
677
912
|
|
|
678
913
|
{/* Export Changes Button - shows when there are pending mutations */}
|
|
679
|
-
|
|
914
|
+
{hasDesktopFeatureAccess(desktopEntitlement, 'exports') ? (
|
|
915
|
+
<ExportChangesButton />
|
|
916
|
+
) : null}
|
|
680
917
|
|
|
681
918
|
{/* ── Panels ── */}
|
|
682
919
|
<DropdownMenu>
|
|
@@ -732,6 +969,42 @@ export function MainToolbar({ onShowShortcuts }: MainToolbarProps = {} as MainTo
|
|
|
732
969
|
<Palette className="h-4 w-4 mr-2" />
|
|
733
970
|
Lens Rules
|
|
734
971
|
</DropdownMenuCheckboxItem>
|
|
972
|
+
{rightAnalysisExtensions.length > 0 && (
|
|
973
|
+
<>
|
|
974
|
+
<DropdownMenuSeparator />
|
|
975
|
+
{rightAnalysisExtensions.map((extension) => {
|
|
976
|
+
const Icon = extension.icon;
|
|
977
|
+
return (
|
|
978
|
+
<DropdownMenuCheckboxItem
|
|
979
|
+
key={extension.id}
|
|
980
|
+
checked={activeWorkspacePanels.has(extension.id)}
|
|
981
|
+
onCheckedChange={() => handleToggleAnalysisExtension(extension.id)}
|
|
982
|
+
>
|
|
983
|
+
<Icon className="h-4 w-4 mr-2" />
|
|
984
|
+
{extension.label}
|
|
985
|
+
</DropdownMenuCheckboxItem>
|
|
986
|
+
);
|
|
987
|
+
})}
|
|
988
|
+
</>
|
|
989
|
+
)}
|
|
990
|
+
{bottomAnalysisExtensions.length > 0 && (
|
|
991
|
+
<>
|
|
992
|
+
<DropdownMenuSeparator />
|
|
993
|
+
{bottomAnalysisExtensions.map((extension) => {
|
|
994
|
+
const Icon = extension.icon;
|
|
995
|
+
return (
|
|
996
|
+
<DropdownMenuCheckboxItem
|
|
997
|
+
key={extension.id}
|
|
998
|
+
checked={activeWorkspacePanels.has(extension.id)}
|
|
999
|
+
onCheckedChange={() => handleToggleAnalysisExtension(extension.id)}
|
|
1000
|
+
>
|
|
1001
|
+
<Icon className="h-4 w-4 mr-2" />
|
|
1002
|
+
{extension.label}
|
|
1003
|
+
</DropdownMenuCheckboxItem>
|
|
1004
|
+
);
|
|
1005
|
+
})}
|
|
1006
|
+
</>
|
|
1007
|
+
)}
|
|
735
1008
|
</DropdownMenuContent>
|
|
736
1009
|
</DropdownMenu>
|
|
737
1010
|
|
|
@@ -884,6 +1157,32 @@ export function MainToolbar({ onShowShortcuts }: MainToolbarProps = {} as MainTo
|
|
|
884
1157
|
</TooltipContent>
|
|
885
1158
|
</Tooltip>
|
|
886
1159
|
|
|
1160
|
+
{/* Cesium 3D Context toggle + settings */}
|
|
1161
|
+
{hasModelsLoaded && (
|
|
1162
|
+
<div className="flex items-center">
|
|
1163
|
+
<Tooltip>
|
|
1164
|
+
<TooltipTrigger asChild>
|
|
1165
|
+
<Button
|
|
1166
|
+
variant={cesiumEnabled ? 'default' : 'ghost'}
|
|
1167
|
+
size="icon-sm"
|
|
1168
|
+
aria-label={cesiumEnabled ? 'Hide 3D World Context (Cesium)' : 'Show 3D World Context (Cesium)'}
|
|
1169
|
+
aria-pressed={cesiumEnabled}
|
|
1170
|
+
onClick={(e) => {
|
|
1171
|
+
(e.currentTarget as HTMLButtonElement).blur();
|
|
1172
|
+
toggleCesium();
|
|
1173
|
+
}}
|
|
1174
|
+
className={cn(cesiumEnabled && 'bg-teal-600 text-white hover:bg-teal-700')}
|
|
1175
|
+
>
|
|
1176
|
+
<Globe2 className="h-4 w-4" />
|
|
1177
|
+
</Button>
|
|
1178
|
+
</TooltipTrigger>
|
|
1179
|
+
<TooltipContent>
|
|
1180
|
+
{cesiumEnabled ? 'Hide' : 'Show'} 3D World Context (Cesium)
|
|
1181
|
+
</TooltipContent>
|
|
1182
|
+
</Tooltip>
|
|
1183
|
+
</div>
|
|
1184
|
+
)}
|
|
1185
|
+
|
|
887
1186
|
{/* Hover Tooltips toggle */}
|
|
888
1187
|
<Tooltip>
|
|
889
1188
|
<TooltipTrigger asChild>
|
|
@@ -946,11 +1245,22 @@ export function MainToolbar({ onShowShortcuts }: MainToolbarProps = {} as MainTo
|
|
|
946
1245
|
<div className="flex-1" />
|
|
947
1246
|
|
|
948
1247
|
{/* Loading Progress */}
|
|
949
|
-
{loading && progress && (
|
|
1248
|
+
{loading && (geometryProgress || metadataProgress || progress) && (
|
|
950
1249
|
<div className="flex items-center gap-2 mr-4">
|
|
951
|
-
<span className="text-xs text-muted-foreground">
|
|
952
|
-
|
|
953
|
-
|
|
1250
|
+
<span className="text-xs text-muted-foreground">
|
|
1251
|
+
{(geometryProgress ?? metadataProgress ?? progress)?.phase}
|
|
1252
|
+
{geometryProgress && metadataProgress ? ` | ${metadataProgress.phase}` : ''}
|
|
1253
|
+
</span>
|
|
1254
|
+
{(geometryProgress ?? metadataProgress ?? progress)?.indeterminate ? (
|
|
1255
|
+
<Loader2 className="h-3.5 w-3.5 animate-spin text-muted-foreground" />
|
|
1256
|
+
) : (
|
|
1257
|
+
<>
|
|
1258
|
+
<Progress value={(geometryProgress ?? metadataProgress ?? progress)?.percent ?? 0} className="w-32 h-2" />
|
|
1259
|
+
<span className="text-xs text-muted-foreground">
|
|
1260
|
+
{Math.round((geometryProgress ?? metadataProgress ?? progress)?.percent ?? 0)}%
|
|
1261
|
+
</span>
|
|
1262
|
+
</>
|
|
1263
|
+
)}
|
|
954
1264
|
</div>
|
|
955
1265
|
)}
|
|
956
1266
|
|
|
@@ -961,6 +1271,22 @@ export function MainToolbar({ onShowShortcuts }: MainToolbarProps = {} as MainTo
|
|
|
961
1271
|
|
|
962
1272
|
{/* Right Side Actions */}
|
|
963
1273
|
<div className="flex items-center gap-2 ml-2 pl-2 border-l border-zinc-200 dark:border-zinc-700/60">
|
|
1274
|
+
{desktopShell ? (
|
|
1275
|
+
<Tooltip>
|
|
1276
|
+
<TooltipTrigger asChild>
|
|
1277
|
+
<Button
|
|
1278
|
+
variant="ghost"
|
|
1279
|
+
size="icon"
|
|
1280
|
+
className="rounded-full"
|
|
1281
|
+
onClick={() => navigateToPath('/settings')}
|
|
1282
|
+
>
|
|
1283
|
+
<Settings className="!h-[20px] !w-[20px]" />
|
|
1284
|
+
</Button>
|
|
1285
|
+
</TooltipTrigger>
|
|
1286
|
+
<TooltipContent>Settings</TooltipContent>
|
|
1287
|
+
</Tooltip>
|
|
1288
|
+
) : null}
|
|
1289
|
+
|
|
964
1290
|
<Tooltip>
|
|
965
1291
|
<TooltipTrigger asChild>
|
|
966
1292
|
<div>
|