forgecad 0.10.0 → 0.10.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/assets/{AdminPage-DwYHz72L.js → AdminPage-DcCnj0qo.js} +1 -1
- package/dist/assets/{BenchmarkPage-a9_f-1US.js → BenchmarkPage-BVEpJSVk.js} +1 -1
- package/dist/assets/{BlogPage-DodHpvmf.js → BlogPage-DHaGP50_.js} +1 -1
- package/dist/assets/{DocsPage-B5LePEuj.js → DocsPage-CDoxHkz8.js} +33 -2
- package/dist/assets/{EditorApp-QXsAISLR.js → EditorApp-BJ0Dloyh.js} +174 -35
- package/dist/assets/{EmbedViewer-DdEHGUMU.js → EmbedViewer-CRKZbY0y.js} +2 -2
- package/dist/assets/{LandingPageProofDriven-yhhOodbf.js → LandingPageProofDriven-BxHkYRE7.js} +1 -1
- package/dist/assets/{LegalPage-5RbKRGYK.js → LegalPage-B-u6FrVv.js} +1 -1
- package/dist/assets/{PricingPage-E3Rma7aV.js → PricingPage-CzpZ6-Ce.js} +1 -1
- package/dist/assets/{SettingsPage-BJZcM97j.js → SettingsPage-CIZSSAd0.js} +1 -1
- package/dist/assets/{app-CE3sYcV7.css → app-CjsbDlb7.css} +143 -0
- package/dist/assets/{app-DSYrDg0V.js → app-DaTMg3nH.js} +612 -120
- package/dist/assets/cli/{render-ZMHR9HkV.js → render-DPf4AYJK.js} +38 -16
- package/dist/assets/{evalWorker-DbNs7Dkp.js → evalWorker-CjZZWRWW.js} +1428 -1038
- package/dist/assets/{jointPose-DO6mnXn_.js → jointPose-DzQOViQH.js} +1 -1
- package/dist/assets/{manifold-BGlQBBH9.js → manifold-BYlzU521.js} +1 -1
- package/dist/assets/{manifold-fy2MV7K1.js → manifold-DgXo0T5P.js} +2 -2
- package/dist/assets/{manifold-BU-tJwQh.js → manifold-K1SkarlQ.js} +1 -1
- package/dist/assets/{reportWorker-DO6hcQbh.js → reportWorker-B9nWwSrB.js} +1402 -1012
- package/dist/assets/{scalar-sampling-budget-o90NSNmF.js → scalar-sampling-budget-prBw_s8t.js} +2139 -1749
- package/dist/cli/render.html +1 -1
- package/dist/docs/index.html +2 -2
- package/dist/docs-raw/CLI.md +18 -3
- package/dist/docs-raw/generated/assembly.md +70 -5
- package/dist/docs-raw/generated/concepts.md +16 -2
- package/dist/docs-raw/generated/core.md +9 -2
- package/dist/docs-raw/generated/lib.md +1 -1
- package/dist/docs-raw/generated/output.md +14 -43
- package/dist/docs-raw/generated/runtime-names.md +4 -4
- package/dist/docs-raw/guides/simready-quickstart.md +171 -0
- package/dist/docs-raw/simulation-workflow.md +273 -0
- package/dist/index.html +2 -2
- package/dist/sitemap.xml +25 -13
- package/dist-cli/{check-compiler-JTVBITCR.js → check-compiler-II7NLPAB.js} +1 -1
- package/dist-cli/{check-query-propagation-3FFLSMVN.js → check-query-propagation-7462TR3R.js} +1 -1
- package/dist-cli/{chunk-OAN5T4XD.js → chunk-UWTJCGXF.js} +1455 -722
- package/dist-cli/forgecad.js +2994 -529
- package/dist-skill/CONTEXT.md +94 -55
- package/dist-skill/docs/API/core/concepts.md +1 -1
- package/dist-skill/docs/CLI.md +18 -3
- package/dist-skill/docs/generated/assembly.md +66 -5
- package/dist-skill/docs/generated/core.md +9 -2
- package/dist-skill/docs/generated/lib.md +1 -1
- package/dist-skill/docs/generated/output.md +14 -43
- package/dist-skill/docs/generated/runtime-names.md +4 -4
- package/examples/robotics/README.md +46 -0
- package/examples/robotics/scout-cam-rover-simready/README.md +119 -0
- package/examples/robotics/scout-cam-rover-simready/lib/dims.js +140 -0
- package/examples/robotics/scout-cam-rover-simready/main.forge.js +343 -0
- package/examples/robotics/scout-cam-rover-simready/parts/body.forge.js +304 -0
- package/examples/robotics/scout-cam-rover-simready/parts/chassis.forge.js +320 -0
- package/examples/robotics/scout-cam-rover-simready/parts/hardware.forge.js +21 -0
- package/examples/robotics/scout-cam-rover-simready/parts/turret.forge.js +70 -0
- package/examples/robotics/scout-cam-rover-simready/parts/wheel.forge.js +116 -0
- package/examples/robotics/simready-asset-crate.forge.js +79 -0
- package/examples/robotics/simready-diff-drive-rover.forge.js +141 -0
- package/examples/robotics/simready-parallel-gripper.forge.js +102 -0
- package/package.json +1 -1
|
@@ -4,7 +4,7 @@ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { en
|
|
|
4
4
|
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
5
5
|
var _a2;
|
|
6
6
|
import { c as create, j as jsxRuntimeExports, r as reactExports, a as createWithEqualityFn, R as React, T as Tb, s as schedulerExports, b as clientExports, d as reactDomExports, u as useParams, e as useSearchParams, f as useNavigate, L as Link, g as useLocation, B as BrowserRouter, h as Routes, i as Route, N as Navigate } from "./vendor-react-6j1Kke-Y.js";
|
|
7
|
-
import { _ as __vitePreload, z as zipSync, s as strToU8, W as WebGLRenderer, R as Raycaster, O as OrthographicCamera$1, P as PerspectiveCamera$1, S as Scene, a as PCFSoftShadowMap, V as VSMShadowMap, b as PCFShadowMap, B as BasicShadowMap, C as ColorManagement, L as LinearSRGBColorSpace, c as SRGBColorSpace, N as NoToneMapping, A as ACESFilmicToneMapping, d as Layers, e as Color, f as RGBAFormat, U as UnsignedByteType, g as Vector3, h as Vector2, i as Clock, T as THREE, D as DoubleSide, j as REVISION, M as Mesh, I as IcosahedronGeometry, k as ShaderMaterial, l as Spherical, Q as Quaternion, m as MOUSE, n as TOUCH, o as Ray, p as Plane, q as DataTextureLoader, H as HalfFloatType, F as FloatType, r as DataUtils, t as LinearFilter, u as RedFormat, v as InstancedBufferGeometry, w as Float32BufferAttribute, x as InstancedInterleavedBuffer, y as InterleavedBufferAttribute, E as WireframeGeometry, G as Box3, J as Sphere, K as UniformsUtils, X as UniformsLib, Y as Vector4, Z as Line3, $ as Matrix4, a0 as MathUtils, a1 as Uniform, a2 as WebGLRenderTarget, a3 as DepthTexture, a4 as BackSide, a5 as ClampToEdgeWrapping, a6 as PlaneGeometry, a7 as UVMapping, a8 as DataTexture, a9 as Texture, aa as MeshBasicMaterial, ab as IntType, ac as ShortType, ad as ByteType, ae as UnsignedIntType, af as Loader, ag as LoadingManager, ah as LinearMipMapLinearFilter, ai as FileLoader, aj as NoBlending, ak as CubeReflectionMapping, al as EquirectangularReflectionMapping, am as CubeTextureLoader, an as WebGLCubeRenderTarget, ao as ConstraintSketch, ap as setSketchPlacement3D, aq as Sketch, ar as PROFILE_BACKEND_MARKER, as as FrozenShape, at as setShapeCompilePlan, au as hasAnyPorts, av as setShapePortsInternal, aw as markShapePortsUsed, ax as setParamOverrides, ay as resolveForgeRenderStyle, az as DEFAULT_ACTIVE_BACKEND, aA as isConstraintSketch, aB as updateConstraintValue, aC as linearizeMultiObjectSteps, aD as getShapeCompilePlan, aE as SCAN_PROXY_GRANULARITY_DEFAULT, aF as publishSolverWasmRunDebug, aG as resolveForgeQualityPreset, aH as SCAN_PROXY_MATRIX_GRANULARITY_MAX, aI as findJointAnimationClip, aJ as resolveJointAnimation, aK as resolveJointViewValues, aL as resolveImportPath, aM as resolveScanProxyGranularity, aN as BufferGeometry, aO as LineBasicMaterial, aP as Line$1, aQ as LineDashedMaterial, aR as DepthStencilFormat, aS as UnsignedInt248Type, aT as MeshNormalMaterial, aU as NearestFilter, aV as BasicDepthPacking, aW as EventDispatcher$1, aX as NoColorSpace, aY as FrontSide, aZ as Material, a_ as AlwaysDepth, a$ as BufferAttribute, b0 as CanvasTexture, b1 as Object3D, b2 as FogExp2, b3 as Fog, b4 as AmbientLight, b5 as HemisphereLight, b6 as SpotLight, b7 as PointLight, b8 as DirectionalLight, b9 as heatPointsForSide, ba as COMPARISON_COLORS, bb as comparisonHeatDepthTest, bc as comparisonHeatEdgeOpacity, bd as comparisonHeatPatchOpacity, be as shapeToGeometry, bf as buildComparisonHeatPatchGeometry, bg as EdgesGeometry, bh as buildShapeFromCompilePlan, bi as buildVisibleHistoryStacks, bj as sketchToSvg, bk as sketchToDxf, bl as runScript, bm as MeshPhysicalMaterial, bn as LineSegments, bo as findDesignTraceNodeForConstructionStep, bp as formatDesignTraceAnchor, bq as waitForAnimationFrame, br as selectBuildLedgerNodes, bs as worldAuthorPlaneToLocal, bt as scanProxySourceBytes, bu as disposeScanProxyGeometry, bv as scanProxyGeometryFromPayload, bw as AdditiveBlending, bx as geometryWithVisibleVertexColors, by as getRenderStylePreset, bz as SCAN_RENDER_COLORS, bA as NormalBlending, bB as scanMaterialShellColor, bC as ZEBRA_STRIPE_SOFTNESS, bD as ZEBRA_STRIPE_SCALE, bE as ZEBRA_LIGHT_COLOR, bF as ZEBRA_DARK_COLOR, bG as ZEBRA_ACCENT_COLOR, bH as ZEBRA_STRIPE_FRAGMENT_SHADER, bI as ZEBRA_STRIPE_VERTEX_SHADER, bJ as SCAN_PROXY_LAYER_STYLES, bK as scanMaterialLayerStyles, bL as SURFACE_FIELD_FRAGMENT_SHADER, bM as SURFACE_FIELD_VERTEX_SHADER, bN as WORLD_UP, bO as CatmullRomCurve3, bP as TubeGeometry, bQ as THICKNESS_GRADIENT_COLORS, bR as ROUGHNESS_COLORS, bS as DEFAULT_ROUGHNESS_INSPECTION_OPTIONS, bT as PERFORMANCE_SAMPLE_INTERVAL_SEC, bU as formatPerformanceCount, bV as NON_TEXT_INPUT_TYPES, bW as MeshStandardMaterial, bX as compileSdfNode3, bY as buildSdfRaymarchFragmentShader, bZ as SDF_RAYMARCH_PROXY_VERTEX_SHADER, b_ as Shape, b$ as ShapeGeometry, c0 as ShaderLib, c1 as CylinderGeometry, c2 as VIEWPORT_CAMERA_STORAGE_KEY, c3 as parseViewportCameraState, c4 as createResolvedExplodeConfig, c5 as explodeBoundsCenter, c6 as explodeMergeBounds, c7 as resolveExplodeDirective, c8 as computeExplodeMotion, c9 as getSketchWorldMatrix, ca as explodeAdd, cb as hasExplodeOverride, cc as resolveExplodeLocalFanDirection, cd as explodeMul, ce as explodeLeafFanStage, cf as normalizeCutPlane, cg as toClippingPlane, ch as isObjectExcludedFromCutPlane, ci as getShapePorts, cj as getShapeUsedPorts, ck as DEFAULT_VIEW_CONFIG, cl as SECTION_EXPLORER_PLANE_NAME, cm as ZERO_OFFSET, cn as scanProxyGridForBounds, co as IDENTITY_MATRIX$2, cp as OBJECT_CONTEXT_MENU_MARGIN, cq as OBJECT_CONTEXT_MENU_WIDTH, cr as OBJECT_CONTEXT_MENU_HEIGHT, cs as getKernelFaceNameForTriangle, ct as triangleSoupFromMeshes, cu as compareTriangleSoups, cv as buildGeometryComparisonPointCloud, cw as aabbOverlaps, cx as aabbOverlapVolume, cy as DEFAULT_COLLISION_INSPECTION_OPTIONS, cz as resolveScalarSceneSampleBudget, cA as FOCUS_MODE_DIM_OPACITY, cB as comparisonCandidateContextOpacity, cC as Matrix3, cD as initKernel, cE as initSolverWasm } from "./scalar-sampling-budget-
|
|
7
|
+
import { _ as __vitePreload, z as zipSync, s as strToU8, W as WebGLRenderer, R as Raycaster, O as OrthographicCamera$1, P as PerspectiveCamera$1, S as Scene, a as PCFSoftShadowMap, V as VSMShadowMap, b as PCFShadowMap, B as BasicShadowMap, C as ColorManagement, L as LinearSRGBColorSpace, c as SRGBColorSpace, N as NoToneMapping, A as ACESFilmicToneMapping, d as Layers, e as Color, f as RGBAFormat, U as UnsignedByteType, g as Vector3, h as Vector2, i as Clock, T as THREE, D as DoubleSide, j as REVISION, M as Mesh, I as IcosahedronGeometry, k as ShaderMaterial, l as Spherical, Q as Quaternion, m as MOUSE, n as TOUCH, o as Ray, p as Plane, q as DataTextureLoader, H as HalfFloatType, F as FloatType, r as DataUtils, t as LinearFilter, u as RedFormat, v as InstancedBufferGeometry, w as Float32BufferAttribute, x as InstancedInterleavedBuffer, y as InterleavedBufferAttribute, E as WireframeGeometry, G as Box3, J as Sphere, K as UniformsUtils, X as UniformsLib, Y as Vector4, Z as Line3, $ as Matrix4, a0 as MathUtils, a1 as Uniform, a2 as WebGLRenderTarget, a3 as DepthTexture, a4 as BackSide, a5 as ClampToEdgeWrapping, a6 as PlaneGeometry, a7 as UVMapping, a8 as DataTexture, a9 as Texture, aa as MeshBasicMaterial, ab as IntType, ac as ShortType, ad as ByteType, ae as UnsignedIntType, af as Loader, ag as LoadingManager, ah as LinearMipMapLinearFilter, ai as FileLoader, aj as NoBlending, ak as CubeReflectionMapping, al as EquirectangularReflectionMapping, am as CubeTextureLoader, an as WebGLCubeRenderTarget, ao as ConstraintSketch, ap as setSketchPlacement3D, aq as Sketch, ar as PROFILE_BACKEND_MARKER, as as FrozenShape, at as setShapeCompilePlan, au as hasAnyPorts, av as setShapePortsInternal, aw as markShapePortsUsed, ax as setParamOverrides, ay as resolveForgeRenderStyle, az as DEFAULT_ACTIVE_BACKEND, aA as isConstraintSketch, aB as updateConstraintValue, aC as linearizeMultiObjectSteps, aD as getShapeCompilePlan, aE as SCAN_PROXY_GRANULARITY_DEFAULT, aF as publishSolverWasmRunDebug, aG as resolveForgeQualityPreset, aH as SCAN_PROXY_MATRIX_GRANULARITY_MAX, aI as findJointAnimationClip, aJ as resolveJointAnimation, aK as resolveJointViewValues, aL as resolveImportPath, aM as resolveScanProxyGranularity, aN as BufferGeometry, aO as LineBasicMaterial, aP as Line$1, aQ as LineDashedMaterial, aR as DepthStencilFormat, aS as UnsignedInt248Type, aT as MeshNormalMaterial, aU as NearestFilter, aV as BasicDepthPacking, aW as EventDispatcher$1, aX as NoColorSpace, aY as FrontSide, aZ as Material, a_ as AlwaysDepth, a$ as BufferAttribute, b0 as CanvasTexture, b1 as Object3D, b2 as FogExp2, b3 as Fog, b4 as AmbientLight, b5 as HemisphereLight, b6 as SpotLight, b7 as PointLight, b8 as DirectionalLight, b9 as heatPointsForSide, ba as COMPARISON_COLORS, bb as comparisonHeatDepthTest, bc as comparisonHeatEdgeOpacity, bd as comparisonHeatPatchOpacity, be as shapeToGeometry, bf as buildComparisonHeatPatchGeometry, bg as EdgesGeometry, bh as buildShapeFromCompilePlan, bi as buildVisibleHistoryStacks, bj as sketchToSvg, bk as sketchToDxf, bl as runScript, bm as MeshPhysicalMaterial, bn as LineSegments, bo as findDesignTraceNodeForConstructionStep, bp as formatDesignTraceAnchor, bq as waitForAnimationFrame, br as selectBuildLedgerNodes, bs as worldAuthorPlaneToLocal, bt as scanProxySourceBytes, bu as disposeScanProxyGeometry, bv as scanProxyGeometryFromPayload, bw as AdditiveBlending, bx as geometryWithVisibleVertexColors, by as getRenderStylePreset, bz as SCAN_RENDER_COLORS, bA as NormalBlending, bB as scanMaterialShellColor, bC as ZEBRA_STRIPE_SOFTNESS, bD as ZEBRA_STRIPE_SCALE, bE as ZEBRA_LIGHT_COLOR, bF as ZEBRA_DARK_COLOR, bG as ZEBRA_ACCENT_COLOR, bH as ZEBRA_STRIPE_FRAGMENT_SHADER, bI as ZEBRA_STRIPE_VERTEX_SHADER, bJ as SCAN_PROXY_LAYER_STYLES, bK as scanMaterialLayerStyles, bL as SURFACE_FIELD_FRAGMENT_SHADER, bM as SURFACE_FIELD_VERTEX_SHADER, bN as WORLD_UP, bO as CatmullRomCurve3, bP as TubeGeometry, bQ as THICKNESS_GRADIENT_COLORS, bR as ROUGHNESS_COLORS, bS as DEFAULT_ROUGHNESS_INSPECTION_OPTIONS, bT as PERFORMANCE_SAMPLE_INTERVAL_SEC, bU as formatPerformanceCount, bV as NON_TEXT_INPUT_TYPES, bW as MeshStandardMaterial, bX as compileSdfNode3, bY as buildSdfRaymarchFragmentShader, bZ as SDF_RAYMARCH_PROXY_VERTEX_SHADER, b_ as Shape, b$ as ShapeGeometry, c0 as ShaderLib, c1 as CylinderGeometry, c2 as VIEWPORT_CAMERA_STORAGE_KEY, c3 as parseViewportCameraState, c4 as createResolvedExplodeConfig, c5 as explodeBoundsCenter, c6 as explodeMergeBounds, c7 as resolveExplodeDirective, c8 as computeExplodeMotion, c9 as getSketchWorldMatrix, ca as explodeAdd, cb as hasExplodeOverride, cc as resolveExplodeLocalFanDirection, cd as explodeMul, ce as explodeLeafFanStage, cf as normalizeCutPlane, cg as toClippingPlane, ch as isObjectExcludedFromCutPlane, ci as getShapePorts, cj as getShapeUsedPorts, ck as DEFAULT_VIEW_CONFIG, cl as SECTION_EXPLORER_PLANE_NAME, cm as ZERO_OFFSET, cn as scanProxyGridForBounds, co as IDENTITY_MATRIX$2, cp as OBJECT_CONTEXT_MENU_MARGIN, cq as OBJECT_CONTEXT_MENU_WIDTH, cr as OBJECT_CONTEXT_MENU_HEIGHT, cs as getKernelFaceNameForTriangle, ct as triangleSoupFromMeshes, cu as compareTriangleSoups, cv as buildGeometryComparisonPointCloud, cw as aabbOverlaps, cx as aabbOverlapVolume, cy as DEFAULT_COLLISION_INSPECTION_OPTIONS, cz as resolveScalarSceneSampleBudget, cA as FOCUS_MODE_DIM_OPACITY, cB as comparisonCandidateContextOpacity, cC as Matrix3, cD as initKernel, cE as initSolverWasm } from "./scalar-sampling-budget-prBw_s8t.js";
|
|
8
8
|
function getCsrfToken() {
|
|
9
9
|
const match = document.cookie.match(/(?:^|;\s*)fc-csrf-token=([^;]+)/);
|
|
10
10
|
return match == null ? void 0 : match[1];
|
|
@@ -15753,7 +15753,7 @@ function computeServerSnapshot$1(state2, serverFiles, serverFolders, sharedModel
|
|
|
15753
15753
|
const isMeshHash = startupHashFile && MESH_EXTS.some((ext) => startupHashFile.toLowerCase().endsWith(ext));
|
|
15754
15754
|
const isBinaryHash = startupHashFile && BINARY_IMPORT_EXTS.some((ext) => startupHashFile.toLowerCase().endsWith(ext));
|
|
15755
15755
|
const meshPreviewFile = isMeshHash && startupHashFile && nextFiles[startupHashFile] !== void 0 ? startupHashFile : null;
|
|
15756
|
-
const newActiveFile = sharedBundle2 ? sharedBundle2.entry : sharedModel2 ? sharedModel2.filename : startupHashFile && !isBinaryHash && nextFiles[startupHashFile] !== void 0 ? startupHashFile : initialFile && nextFiles[initialFile] !== void 0 ? initialFile : activeFile && nextFiles[activeFile] ? activeFile : findPreferredEntryFile(availableFiles) || availableFiles.find((n) => n.endsWith(".js")) || availableFiles[0];
|
|
15756
|
+
const newActiveFile = sharedBundle2 ? sharedBundle2.entry : sharedModel2 ? sharedModel2.filename : startupHashFile && !isBinaryHash && nextFiles[startupHashFile] !== void 0 ? startupHashFile : initialFile && nextFiles[initialFile] !== void 0 ? initialFile : activeFile && nextFiles[activeFile] !== void 0 ? activeFile : findPreferredEntryFile(availableFiles) || availableFiles.find((n) => n.endsWith(".js")) || availableFiles[0] || "";
|
|
15757
15757
|
const nextDirty = Object.keys(nextFiles).some((p2) => nextSaved[p2] !== nextFiles[p2]);
|
|
15758
15758
|
const nextObjectSettingsByFile = Object.fromEntries(Object.entries(objectSettingsByFile).filter(([f2]) => f2 in nextFiles));
|
|
15759
15759
|
return {
|
|
@@ -15798,7 +15798,7 @@ function computeServerFileDelete$1(state2, filename) {
|
|
|
15798
15798
|
const newFolders = /* @__PURE__ */ new Set();
|
|
15799
15799
|
Object.keys(nextFiles).forEach((p2) => collectParentPaths(p2).forEach((f2) => newFolders.add(f2)));
|
|
15800
15800
|
const availableFiles = Object.keys(nextFiles);
|
|
15801
|
-
const newActiveFile = activeFile === filename ? findPreferredEntryFile(availableFiles) || availableFiles.find((n) => n.endsWith(".js")) || availableFiles[0] : activeFile;
|
|
15801
|
+
const newActiveFile = activeFile === filename ? findPreferredEntryFile(availableFiles) || availableFiles.find((n) => n.endsWith(".js")) || availableFiles[0] || "" : activeFile;
|
|
15802
15802
|
const nextObjectSettingsByFile = Object.fromEntries(Object.entries(objectSettingsByFile).filter(([f2]) => f2 in nextFiles));
|
|
15803
15803
|
return {
|
|
15804
15804
|
files: nextFiles,
|
|
@@ -15841,7 +15841,7 @@ const CRASH_COOLDOWN_MS = 2e3;
|
|
|
15841
15841
|
class EvalWorkerClient {
|
|
15842
15842
|
constructor(workerFactory = () => new Worker(new URL(
|
|
15843
15843
|
/* @vite-ignore */
|
|
15844
|
-
"/assets/evalWorker-
|
|
15844
|
+
"/assets/evalWorker-CjZZWRWW.js",
|
|
15845
15845
|
import.meta.url
|
|
15846
15846
|
), { type: "module" })) {
|
|
15847
15847
|
__publicField(this, "worker", null);
|
|
@@ -16332,6 +16332,7 @@ function projectTextFileTemplate(path) {
|
|
|
16332
16332
|
return "";
|
|
16333
16333
|
}
|
|
16334
16334
|
function monacoLanguageForProjectFile(path) {
|
|
16335
|
+
if (!path) return "plaintext";
|
|
16335
16336
|
const lower = path.toLowerCase();
|
|
16336
16337
|
if (lower.endsWith(".md")) return "markdown";
|
|
16337
16338
|
if (lower.endsWith(".json")) return "json";
|
|
@@ -16344,6 +16345,7 @@ function monacoLanguageForProjectFile(path) {
|
|
|
16344
16345
|
return "plaintext";
|
|
16345
16346
|
}
|
|
16346
16347
|
function highlightLanguageForProjectFile(path) {
|
|
16348
|
+
if (!path) return null;
|
|
16347
16349
|
const lower = path.toLowerCase();
|
|
16348
16350
|
if (lower.endsWith(".md")) return "markdown";
|
|
16349
16351
|
if (lower.endsWith(".json")) return "json";
|
|
@@ -17064,7 +17066,12 @@ const INITIAL_FOLDERS = collectInitialFolders(INITIAL_FILES);
|
|
|
17064
17066
|
const getActiveFileFromHash = () => {
|
|
17065
17067
|
const hash = window.location.hash.slice(1);
|
|
17066
17068
|
if (hash.startsWith("code/") || hash.startsWith("bundle/")) return null;
|
|
17067
|
-
|
|
17069
|
+
if (!hash) return null;
|
|
17070
|
+
try {
|
|
17071
|
+
return decodeURIComponent(hash);
|
|
17072
|
+
} catch {
|
|
17073
|
+
return hash;
|
|
17074
|
+
}
|
|
17068
17075
|
};
|
|
17069
17076
|
const STARTUP_HASH_FILE = getActiveFileFromHash();
|
|
17070
17077
|
const sharedModel = decodeSharedHash(window.location.hash);
|
|
@@ -17523,7 +17530,7 @@ const initialActive = (() => {
|
|
|
17523
17530
|
}
|
|
17524
17531
|
const names = Object.keys(INITIAL_FILES);
|
|
17525
17532
|
const fallback = findPreferredEntryFile(names) || names.find((n) => n.endsWith(".js")) || names[0];
|
|
17526
|
-
return fallback;
|
|
17533
|
+
return fallback || "";
|
|
17527
17534
|
})();
|
|
17528
17535
|
const INITIAL_SAVED = {};
|
|
17529
17536
|
const MAX_RECENT_FILES = 200;
|
|
@@ -17606,6 +17613,19 @@ function isScalarInspectChannel(channel) {
|
|
|
17606
17613
|
function shouldUseScanRenderStyle(channel, displayMode) {
|
|
17607
17614
|
return isScalarInspectChannel(channel) && displayMode === "scan";
|
|
17608
17615
|
}
|
|
17616
|
+
function recordViewCommandDebug(command) {
|
|
17617
|
+
if (typeof window === "undefined") return;
|
|
17618
|
+
if (window.localStorage.getItem("forgecad:debugCamera") !== "1") return;
|
|
17619
|
+
const entry = {
|
|
17620
|
+
id: command.id,
|
|
17621
|
+
type: command.type,
|
|
17622
|
+
view: command.view,
|
|
17623
|
+
targetId: command.targetId,
|
|
17624
|
+
camera: command.camera
|
|
17625
|
+
};
|
|
17626
|
+
window.__forgecadViewCommandDebug = [...window.__forgecadViewCommandDebug ?? [], entry].slice(-50);
|
|
17627
|
+
console.debug("[forgecad view-command]", entry);
|
|
17628
|
+
}
|
|
17609
17629
|
const initialViewPreferences = readViewPreferences();
|
|
17610
17630
|
const initialInspectChannel = resolveInitialViewInspectChannel(initialViewPreferences.inspectChannel);
|
|
17611
17631
|
const initialInspectDisplayMode = resolveInspectDisplayMode(initialViewPreferences.inspectDisplayMode);
|
|
@@ -18068,7 +18088,7 @@ const useForgeStore = create((set, get) => ({
|
|
|
18068
18088
|
}
|
|
18069
18089
|
},
|
|
18070
18090
|
dirty: false,
|
|
18071
|
-
filesLoading:
|
|
18091
|
+
filesLoading: false,
|
|
18072
18092
|
fileHandle: null,
|
|
18073
18093
|
setFileHandle: (fileHandle) => set({ fileHandle }),
|
|
18074
18094
|
result: null,
|
|
@@ -18657,6 +18677,7 @@ const useForgeStore = create((set, get) => ({
|
|
|
18657
18677
|
},
|
|
18658
18678
|
gridEnabled: initialViewPreferences.gridEnabled ?? true,
|
|
18659
18679
|
axesVisible: initialViewPreferences.axesVisible ?? true,
|
|
18680
|
+
viewCubeVisible: initialViewPreferences.viewCubeVisible ?? true,
|
|
18660
18681
|
gridSize: initialViewPreferences.gridSize ?? 10,
|
|
18661
18682
|
setGridEnabled: (enabled) => {
|
|
18662
18683
|
writeViewPreferences({ gridEnabled: enabled });
|
|
@@ -18666,6 +18687,10 @@ const useForgeStore = create((set, get) => ({
|
|
|
18666
18687
|
writeViewPreferences({ axesVisible: visible });
|
|
18667
18688
|
set({ axesVisible: visible });
|
|
18668
18689
|
},
|
|
18690
|
+
setViewCubeVisible: (visible) => {
|
|
18691
|
+
writeViewPreferences({ viewCubeVisible: visible });
|
|
18692
|
+
set({ viewCubeVisible: visible });
|
|
18693
|
+
},
|
|
18669
18694
|
setGridSize: (size) => {
|
|
18670
18695
|
writeViewPreferences({ gridSize: size });
|
|
18671
18696
|
set({ gridSize: size });
|
|
@@ -19002,7 +19027,11 @@ const useForgeStore = create((set, get) => ({
|
|
|
19002
19027
|
set({ objectPickSyncEnabled: enabled });
|
|
19003
19028
|
},
|
|
19004
19029
|
viewCommand: null,
|
|
19005
|
-
requestViewCommand: (command) =>
|
|
19030
|
+
requestViewCommand: (command) => {
|
|
19031
|
+
const viewCommand = { ...command, id: Date.now() };
|
|
19032
|
+
recordViewCommandDebug(viewCommand);
|
|
19033
|
+
set({ viewCommand });
|
|
19034
|
+
},
|
|
19006
19035
|
clearViewCommand: () => set({ viewCommand: null }),
|
|
19007
19036
|
viewportCameraState: null,
|
|
19008
19037
|
setViewportCameraState: (state2) => set({ viewportCameraState: state2 }),
|
|
@@ -19396,6 +19425,12 @@ const useForgeStore = create((set, get) => ({
|
|
|
19396
19425
|
writeViewPreferences({ fileExplorerOpen: nextFileExplorerOpen });
|
|
19397
19426
|
return { fileExplorerOpen: nextFileExplorerOpen };
|
|
19398
19427
|
}),
|
|
19428
|
+
codeEditorOpen: initialViewPreferences.codeEditorOpen ?? true,
|
|
19429
|
+
toggleCodeEditor: () => set((s) => {
|
|
19430
|
+
const nextCodeEditorOpen = !s.codeEditorOpen;
|
|
19431
|
+
writeViewPreferences({ codeEditorOpen: nextCodeEditorOpen });
|
|
19432
|
+
return { codeEditorOpen: nextCodeEditorOpen };
|
|
19433
|
+
}),
|
|
19399
19434
|
viewPanelOpen: initialViewPreferences.viewPanelOpen ?? true,
|
|
19400
19435
|
toggleViewPanel: () => set((s) => {
|
|
19401
19436
|
const nextViewPanelOpen = !s.viewPanelOpen;
|
|
@@ -19500,10 +19535,13 @@ const useForgeStore = create((set, get) => ({
|
|
|
19500
19535
|
openAISkill: () => set({ aiSkillOpen: true }),
|
|
19501
19536
|
closeAISkill: () => set({ aiSkillOpen: false }),
|
|
19502
19537
|
editorNavigate: null,
|
|
19503
|
-
requestEditorNavigate: (line) =>
|
|
19504
|
-
|
|
19505
|
-
|
|
19506
|
-
|
|
19538
|
+
requestEditorNavigate: (line) => {
|
|
19539
|
+
writeViewPreferences({ codeEditorOpen: true });
|
|
19540
|
+
set((s) => {
|
|
19541
|
+
var _a3;
|
|
19542
|
+
return { codeEditorOpen: true, editorNavigate: { line, id: (((_a3 = s.editorNavigate) == null ? void 0 : _a3.id) ?? 0) + 1 } };
|
|
19543
|
+
});
|
|
19544
|
+
},
|
|
19507
19545
|
clearEditorNavigate: () => set({ editorNavigate: null }),
|
|
19508
19546
|
disableRunCache: initialViewPreferences.disableRunCache ?? false,
|
|
19509
19547
|
setDisableRunCache: (disabled) => {
|
|
@@ -30134,7 +30172,7 @@ function generateReportInWorker(options) {
|
|
|
30134
30172
|
return new Promise((resolve2, reject) => {
|
|
30135
30173
|
const worker = new Worker(new URL(
|
|
30136
30174
|
/* @vite-ignore */
|
|
30137
|
-
"/assets/reportWorker-
|
|
30175
|
+
"/assets/reportWorker-B9nWwSrB.js",
|
|
30138
30176
|
import.meta.url
|
|
30139
30177
|
), { type: "module" });
|
|
30140
30178
|
const cleanup = () => {
|
|
@@ -40846,6 +40884,37 @@ function ZoomIndicatorPanel({ mmPerPx }) {
|
|
|
40846
40884
|
}
|
|
40847
40885
|
);
|
|
40848
40886
|
}
|
|
40887
|
+
function roundDebugNumber(value) {
|
|
40888
|
+
return Number.isFinite(value) ? Math.round(value * 1e3) / 1e3 : value;
|
|
40889
|
+
}
|
|
40890
|
+
function vectorTuple(vector) {
|
|
40891
|
+
return [roundDebugNumber(vector.x), roundDebugNumber(vector.y), roundDebugNumber(vector.z)];
|
|
40892
|
+
}
|
|
40893
|
+
function snapshotViewportCamera(camera, target) {
|
|
40894
|
+
const ortho = camera;
|
|
40895
|
+
const perspective = camera;
|
|
40896
|
+
const isOrtho = ortho.isOrthographicCamera === true;
|
|
40897
|
+
return {
|
|
40898
|
+
position: vectorTuple(camera.position),
|
|
40899
|
+
target: target ? vectorTuple(target) : null,
|
|
40900
|
+
up: vectorTuple(camera.up),
|
|
40901
|
+
projection: isOrtho ? "orthographic" : "perspective",
|
|
40902
|
+
fov: isOrtho ? void 0 : roundDebugNumber(perspective.fov),
|
|
40903
|
+
zoom: isOrtho ? roundDebugNumber(ortho.zoom) : void 0
|
|
40904
|
+
};
|
|
40905
|
+
}
|
|
40906
|
+
function recordViewportCameraDebug(entry) {
|
|
40907
|
+
if (typeof window === "undefined") return;
|
|
40908
|
+
if (window.localStorage.getItem("forgecad:debugCamera") !== "1") return;
|
|
40909
|
+
window.__forgecadCameraDebug = [...window.__forgecadCameraDebug ?? [], entry].slice(-50);
|
|
40910
|
+
console.debug("[forgecad camera]", entry);
|
|
40911
|
+
}
|
|
40912
|
+
function recordViewportCameraLifecycleDebug(entry) {
|
|
40913
|
+
if (typeof window === "undefined") return;
|
|
40914
|
+
if (window.localStorage.getItem("forgecad:debugCamera") !== "1") return;
|
|
40915
|
+
window.__forgecadCameraLifecycleDebug = [...window.__forgecadCameraLifecycleDebug ?? [], entry].slice(-50);
|
|
40916
|
+
console.debug("[forgecad view-controller]", entry);
|
|
40917
|
+
}
|
|
40849
40918
|
const readPersistedViewportCameraState = () => {
|
|
40850
40919
|
if (typeof window === "undefined") return null;
|
|
40851
40920
|
try {
|
|
@@ -40869,19 +40938,117 @@ const resolveHoverObjectName = (name, knownFileNames) => {
|
|
|
40869
40938
|
if (knownFileNames.has(trimmed)) return null;
|
|
40870
40939
|
return trimmed;
|
|
40871
40940
|
};
|
|
40941
|
+
const SNAP_VIEW_DIRECTIONS = {
|
|
40942
|
+
front: new Vector3(0, -1, 0),
|
|
40943
|
+
back: new Vector3(0, 1, 0),
|
|
40944
|
+
right: new Vector3(1, 0, 0),
|
|
40945
|
+
left: new Vector3(-1, 0, 0),
|
|
40946
|
+
top: new Vector3(0, 0, 1),
|
|
40947
|
+
bottom: new Vector3(0, 0, -1),
|
|
40948
|
+
iso: new Vector3(1, -1, 1)
|
|
40949
|
+
};
|
|
40950
|
+
const DEFAULT_CAMERA_UP = new Vector3(0, 0, 1);
|
|
40951
|
+
const SNAP_VIEW_UP = {
|
|
40952
|
+
top: new Vector3(0, 1, 0),
|
|
40953
|
+
bottom: new Vector3(0, -1, 0)
|
|
40954
|
+
};
|
|
40955
|
+
function isFiniteVector$1(vector) {
|
|
40956
|
+
return Number.isFinite(vector.x) && Number.isFinite(vector.y) && Number.isFinite(vector.z);
|
|
40957
|
+
}
|
|
40958
|
+
function computeBoundsFraming(bounds) {
|
|
40959
|
+
if (bounds.isEmpty()) return null;
|
|
40960
|
+
const target = new Vector3();
|
|
40961
|
+
bounds.getCenter(target);
|
|
40962
|
+
const size = new Vector3();
|
|
40963
|
+
bounds.getSize(size);
|
|
40964
|
+
if (!isFiniteVector$1(target) || !isFiniteVector$1(size)) return null;
|
|
40965
|
+
const reach = Math.max(size.x, size.y, size.z, 1);
|
|
40966
|
+
if (!Number.isFinite(reach) || reach <= 0) return null;
|
|
40967
|
+
return { target, size, reach };
|
|
40968
|
+
}
|
|
40969
|
+
function snapViewDirection(view2) {
|
|
40970
|
+
return SNAP_VIEW_DIRECTIONS[view2 ?? "iso"].clone().normalize();
|
|
40971
|
+
}
|
|
40972
|
+
function snapViewUp(view2) {
|
|
40973
|
+
return (SNAP_VIEW_UP[view2 ?? "iso"] ?? DEFAULT_CAMERA_UP).clone();
|
|
40974
|
+
}
|
|
40975
|
+
function computeSnapOrbitPose({
|
|
40976
|
+
position,
|
|
40977
|
+
target,
|
|
40978
|
+
up,
|
|
40979
|
+
view: view2
|
|
40980
|
+
}) {
|
|
40981
|
+
if (!isFiniteVector$1(position) || !isFiniteVector$1(target) || !isFiniteVector$1(up)) return null;
|
|
40982
|
+
const distance = position.distanceTo(target);
|
|
40983
|
+
if (!Number.isFinite(distance) || distance <= 1e-6) return null;
|
|
40984
|
+
const nextPosition = target.clone().add(snapViewDirection(view2).multiplyScalar(distance));
|
|
40985
|
+
if (!isFiniteVector$1(nextPosition)) return null;
|
|
40986
|
+
return {
|
|
40987
|
+
position: nextPosition,
|
|
40988
|
+
target: target.clone(),
|
|
40989
|
+
up: up.clone()
|
|
40990
|
+
};
|
|
40991
|
+
}
|
|
40992
|
+
function ActiveCameraBridge({ onCameraChange }) {
|
|
40993
|
+
const camera = useThree((state2) => state2.camera);
|
|
40994
|
+
reactExports.useEffect(() => {
|
|
40995
|
+
onCameraChange(camera);
|
|
40996
|
+
recordViewportCameraLifecycleDebug({
|
|
40997
|
+
path: "active-camera",
|
|
40998
|
+
snapshot: snapshotViewportCamera(camera, null)
|
|
40999
|
+
});
|
|
41000
|
+
}, [camera, onCameraChange]);
|
|
41001
|
+
reactExports.useEffect(() => {
|
|
41002
|
+
return () => {
|
|
41003
|
+
onCameraChange(null);
|
|
41004
|
+
recordViewportCameraLifecycleDebug({ path: "active-camera-cleared" });
|
|
41005
|
+
};
|
|
41006
|
+
}, [onCameraChange]);
|
|
41007
|
+
return null;
|
|
41008
|
+
}
|
|
40872
41009
|
function ViewController({
|
|
41010
|
+
camera,
|
|
40873
41011
|
controlsRef,
|
|
40874
|
-
|
|
41012
|
+
viewportRef,
|
|
40875
41013
|
objects,
|
|
40876
41014
|
objectMatrices,
|
|
40877
41015
|
fallbackBounds,
|
|
40878
41016
|
settings,
|
|
40879
|
-
focusedObjectIds
|
|
40880
|
-
clearCommand
|
|
41017
|
+
focusedObjectIds
|
|
40881
41018
|
}) {
|
|
40882
|
-
const
|
|
41019
|
+
const command = useForgeStore((s) => s.viewCommand);
|
|
41020
|
+
const clearCommand = useForgeStore((s) => s.clearViewCommand);
|
|
41021
|
+
const getActiveCamera = reactExports.useCallback(() => {
|
|
41022
|
+
var _a3;
|
|
41023
|
+
return camera ?? ((_a3 = controlsRef.current) == null ? void 0 : _a3.object) ?? null;
|
|
41024
|
+
}, [camera, controlsRef]);
|
|
41025
|
+
reactExports.useEffect(() => {
|
|
41026
|
+
recordViewportCameraLifecycleDebug({ path: "mounted" });
|
|
41027
|
+
return () => {
|
|
41028
|
+
recordViewportCameraLifecycleDebug({ path: "unmounted" });
|
|
41029
|
+
};
|
|
41030
|
+
}, []);
|
|
40883
41031
|
reactExports.useEffect(() => {
|
|
41032
|
+
var _a3;
|
|
40884
41033
|
if (!command) return;
|
|
41034
|
+
const activeCamera = getActiveCamera();
|
|
41035
|
+
if (!activeCamera) {
|
|
41036
|
+
recordViewportCameraLifecycleDebug({ path: "command-no-camera" });
|
|
41037
|
+
return;
|
|
41038
|
+
}
|
|
41039
|
+
recordViewportCameraLifecycleDebug({
|
|
41040
|
+
path: "command-change",
|
|
41041
|
+
snapshot: snapshotViewportCamera(activeCamera, ((_a3 = controlsRef.current) == null ? void 0 : _a3.target) ?? null)
|
|
41042
|
+
});
|
|
41043
|
+
}, [command, controlsRef, getActiveCamera]);
|
|
41044
|
+
reactExports.useEffect(() => {
|
|
41045
|
+
var _a3;
|
|
41046
|
+
if (!command) return;
|
|
41047
|
+
const camera2 = getActiveCamera();
|
|
41048
|
+
if (!camera2) {
|
|
41049
|
+
recordViewportCameraLifecycleDebug({ path: "command-no-camera-handler" });
|
|
41050
|
+
return;
|
|
41051
|
+
}
|
|
40885
41052
|
if (command.type === "sceneCamera") return;
|
|
40886
41053
|
if (command.type === "camera") {
|
|
40887
41054
|
const state2 = command.camera;
|
|
@@ -40889,17 +41056,17 @@ function ViewController({
|
|
|
40889
41056
|
clearCommand();
|
|
40890
41057
|
return;
|
|
40891
41058
|
}
|
|
40892
|
-
|
|
40893
|
-
|
|
40894
|
-
if ("fov" in
|
|
40895
|
-
|
|
41059
|
+
camera2.position.set(state2.position[0], state2.position[1], state2.position[2]);
|
|
41060
|
+
camera2.up.set(state2.up[0], state2.up[1], state2.up[2]);
|
|
41061
|
+
if ("fov" in camera2 && state2.fov !== void 0) {
|
|
41062
|
+
camera2.fov = state2.fov;
|
|
40896
41063
|
}
|
|
40897
|
-
if (
|
|
40898
|
-
|
|
41064
|
+
if (camera2.isOrthographicCamera && state2.orthoZoom !== void 0) {
|
|
41065
|
+
camera2.zoom = state2.orthoZoom;
|
|
40899
41066
|
}
|
|
40900
|
-
|
|
40901
|
-
if ("updateProjectionMatrix" in
|
|
40902
|
-
|
|
41067
|
+
camera2.lookAt(state2.target[0], state2.target[1], state2.target[2]);
|
|
41068
|
+
if ("updateProjectionMatrix" in camera2) {
|
|
41069
|
+
camera2.updateProjectionMatrix();
|
|
40903
41070
|
}
|
|
40904
41071
|
const controls2 = controlsRef.current;
|
|
40905
41072
|
if (controls2) {
|
|
@@ -40909,9 +41076,43 @@ function ViewController({
|
|
|
40909
41076
|
clearCommand();
|
|
40910
41077
|
return;
|
|
40911
41078
|
}
|
|
41079
|
+
const controls = controlsRef.current;
|
|
41080
|
+
const commandSnapshot = snapshotViewportCamera(camera2, (controls == null ? void 0 : controls.target) ?? null);
|
|
41081
|
+
recordViewportCameraDebug({
|
|
41082
|
+
path: "received",
|
|
41083
|
+
command: { type: command.type, view: command.view, targetId: command.targetId },
|
|
41084
|
+
before: commandSnapshot,
|
|
41085
|
+
after: commandSnapshot
|
|
41086
|
+
});
|
|
41087
|
+
if (command.type === "snap" && controls) {
|
|
41088
|
+
const before2 = commandSnapshot;
|
|
41089
|
+
const snapPose = computeSnapOrbitPose({
|
|
41090
|
+
position: camera2.position,
|
|
41091
|
+
target: controls.target,
|
|
41092
|
+
up: camera2.up,
|
|
41093
|
+
view: command.view
|
|
41094
|
+
});
|
|
41095
|
+
if (snapPose) {
|
|
41096
|
+
camera2.position.copy(snapPose.position);
|
|
41097
|
+
camera2.up.copy(snapPose.up);
|
|
41098
|
+
if ("updateProjectionMatrix" in camera2) {
|
|
41099
|
+
camera2.updateProjectionMatrix();
|
|
41100
|
+
}
|
|
41101
|
+
controls.target.copy(snapPose.target);
|
|
41102
|
+
controls.update();
|
|
41103
|
+
recordViewportCameraDebug({
|
|
41104
|
+
path: "snap-orbit",
|
|
41105
|
+
command: { type: command.type, view: command.view, targetId: command.targetId },
|
|
41106
|
+
before: before2,
|
|
41107
|
+
after: snapshotViewportCamera(camera2, controls.target)
|
|
41108
|
+
});
|
|
41109
|
+
clearCommand();
|
|
41110
|
+
return;
|
|
41111
|
+
}
|
|
41112
|
+
}
|
|
40912
41113
|
const visibleObjects = objects.filter((obj) => {
|
|
40913
|
-
var
|
|
40914
|
-
return ((
|
|
41114
|
+
var _a4;
|
|
41115
|
+
return ((_a4 = settings[obj.id]) == null ? void 0 : _a4.visible) !== false;
|
|
40915
41116
|
});
|
|
40916
41117
|
const focusedIdSet = new Set(focusedObjectIds);
|
|
40917
41118
|
const focusedVisibleObjects = focusedIdSet.size > 0 ? visibleObjects.filter((obj) => focusedIdSet.has(obj.id)) : [];
|
|
@@ -40920,46 +41121,34 @@ function ViewController({
|
|
|
40920
41121
|
const canUseFallbackBounds = !command.targetId && !useFocusedScope;
|
|
40921
41122
|
const bounds = computeSceneBounds(targetObjects, objectMatrices) ?? (canUseFallbackBounds ? fallbackBounds : null);
|
|
40922
41123
|
if (!bounds) {
|
|
41124
|
+
recordViewportCameraDebug({
|
|
41125
|
+
path: "no-bounds",
|
|
41126
|
+
command: { type: command.type, view: command.view, targetId: command.targetId },
|
|
41127
|
+
before: commandSnapshot,
|
|
41128
|
+
after: snapshotViewportCamera(camera2, (controls == null ? void 0 : controls.target) ?? null)
|
|
41129
|
+
});
|
|
40923
41130
|
clearCommand();
|
|
40924
41131
|
return;
|
|
40925
41132
|
}
|
|
40926
|
-
const
|
|
40927
|
-
|
|
40928
|
-
|
|
40929
|
-
|
|
40930
|
-
|
|
40931
|
-
|
|
40932
|
-
|
|
40933
|
-
|
|
40934
|
-
const maxDim = Math.max(sizeVec.x, sizeVec.y, sizeVec.z, 1);
|
|
40935
|
-
const snapUsesScopedCenter = command.type === "snap" && useFocusedScope;
|
|
40936
|
-
const target = command.type === "snap" && !snapUsesScopedCenter ? new Vector3(0, 0, 0) : center;
|
|
40937
|
-
const maxReach = command.type === "snap" && !snapUsesScopedCenter ? Math.max(sizeVec.x / 2 + Math.abs(center.x), sizeVec.y / 2 + Math.abs(center.y), sizeVec.z / 2 + Math.abs(center.z)) * 2 : maxDim;
|
|
40938
|
-
if (!Number.isFinite(target.x) || !Number.isFinite(target.y) || !Number.isFinite(target.z) || !Number.isFinite(maxReach) || maxReach <= 0) {
|
|
41133
|
+
const framing = computeBoundsFraming(bounds);
|
|
41134
|
+
if (!framing) {
|
|
41135
|
+
recordViewportCameraDebug({
|
|
41136
|
+
path: "invalid-bounds",
|
|
41137
|
+
command: { type: command.type, view: command.view, targetId: command.targetId },
|
|
41138
|
+
before: commandSnapshot,
|
|
41139
|
+
after: snapshotViewportCamera(camera2, (controls == null ? void 0 : controls.target) ?? null)
|
|
41140
|
+
});
|
|
40939
41141
|
clearCommand();
|
|
40940
41142
|
return;
|
|
40941
41143
|
}
|
|
40942
|
-
const
|
|
41144
|
+
const { target, reach: maxReach } = framing;
|
|
41145
|
+
const before = snapshotViewportCamera(camera2, (controls == null ? void 0 : controls.target) ?? null);
|
|
40943
41146
|
const camDir = new Vector3();
|
|
40944
41147
|
if (command.type === "snap") {
|
|
40945
|
-
|
|
40946
|
-
|
|
40947
|
-
back: new Vector3(0, 1, 0),
|
|
40948
|
-
right: new Vector3(1, 0, 0),
|
|
40949
|
-
left: new Vector3(-1, 0, 0),
|
|
40950
|
-
top: new Vector3(0, 0, 1),
|
|
40951
|
-
bottom: new Vector3(0, 0, -1),
|
|
40952
|
-
iso: new Vector3(1, -1, 1)
|
|
40953
|
-
};
|
|
40954
|
-
const upMap = {
|
|
40955
|
-
top: new Vector3(0, 1, 0),
|
|
40956
|
-
bottom: new Vector3(0, -1, 0)
|
|
40957
|
-
};
|
|
40958
|
-
camDir.copy(viewMap[command.view ?? "iso"]).normalize();
|
|
40959
|
-
const up = upMap[command.view ?? ""] ?? new Vector3(0, 0, 1);
|
|
40960
|
-
camera.up.copy(up);
|
|
41148
|
+
camDir.copy(snapViewDirection(command.view));
|
|
41149
|
+
camera2.up.copy(snapViewUp(command.view));
|
|
40961
41150
|
} else if (controls) {
|
|
40962
|
-
camDir.subVectors(
|
|
41151
|
+
camDir.subVectors(camera2.position, controls.target).normalize();
|
|
40963
41152
|
if (camDir.lengthSq() === 0) camDir.set(1, 1, 1).normalize();
|
|
40964
41153
|
} else {
|
|
40965
41154
|
camDir.set(1, 1, 1).normalize();
|
|
@@ -40968,10 +41157,13 @@ function ViewController({
|
|
|
40968
41157
|
clearCommand();
|
|
40969
41158
|
return;
|
|
40970
41159
|
}
|
|
40971
|
-
const isOrtho =
|
|
41160
|
+
const isOrtho = camera2.isOrthographicCamera;
|
|
41161
|
+
const viewportRect = (_a3 = viewportRef.current) == null ? void 0 : _a3.getBoundingClientRect();
|
|
41162
|
+
const viewportWidth = (viewportRect == null ? void 0 : viewportRect.width) ?? 800;
|
|
41163
|
+
const viewportHeight = (viewportRect == null ? void 0 : viewportRect.height) ?? 600;
|
|
40972
41164
|
if (isOrtho) {
|
|
40973
|
-
const ortho =
|
|
40974
|
-
const zoom = Math.min(
|
|
41165
|
+
const ortho = camera2;
|
|
41166
|
+
const zoom = Math.min(viewportWidth, viewportHeight) / maxReach / 2.2;
|
|
40975
41167
|
if (!Number.isFinite(zoom) || zoom <= 0) {
|
|
40976
41168
|
clearCommand();
|
|
40977
41169
|
return;
|
|
@@ -40985,7 +41177,7 @@ function ViewController({
|
|
|
40985
41177
|
ortho.position.copy(nextPosition);
|
|
40986
41178
|
ortho.updateProjectionMatrix();
|
|
40987
41179
|
} else {
|
|
40988
|
-
const persp =
|
|
41180
|
+
const persp = camera2;
|
|
40989
41181
|
const dist = maxReach / (2 * Math.tan(persp.fov * Math.PI / 360)) * 1.4;
|
|
40990
41182
|
if (!Number.isFinite(dist) || dist <= 0) {
|
|
40991
41183
|
clearCommand();
|
|
@@ -41003,21 +41195,26 @@ function ViewController({
|
|
|
41003
41195
|
controls.target.copy(target);
|
|
41004
41196
|
controls.update();
|
|
41005
41197
|
} else {
|
|
41006
|
-
|
|
41198
|
+
camera2.lookAt(target);
|
|
41007
41199
|
}
|
|
41200
|
+
recordViewportCameraDebug({
|
|
41201
|
+
path: command.type === "snap" ? "snap-framing-fallback" : "framing",
|
|
41202
|
+
command: { type: command.type, view: command.view, targetId: command.targetId },
|
|
41203
|
+
before,
|
|
41204
|
+
after: snapshotViewportCamera(camera2, (controls == null ? void 0 : controls.target) ?? null)
|
|
41205
|
+
});
|
|
41008
41206
|
clearCommand();
|
|
41009
41207
|
}, [
|
|
41010
|
-
camera,
|
|
41011
41208
|
clearCommand,
|
|
41012
41209
|
command,
|
|
41013
41210
|
controlsRef,
|
|
41014
41211
|
fallbackBounds,
|
|
41015
41212
|
focusedObjectIds,
|
|
41213
|
+
getActiveCamera,
|
|
41016
41214
|
objectMatrices,
|
|
41017
41215
|
objects,
|
|
41018
41216
|
settings,
|
|
41019
|
-
|
|
41020
|
-
size.width
|
|
41217
|
+
viewportRef
|
|
41021
41218
|
]);
|
|
41022
41219
|
return null;
|
|
41023
41220
|
}
|
|
@@ -41151,6 +41348,293 @@ function ViewPersistence({
|
|
|
41151
41348
|
}, [camera, controlsRef, isSketchOnly, projectionMode, setViewportCameraState]);
|
|
41152
41349
|
return null;
|
|
41153
41350
|
}
|
|
41351
|
+
const CUBE_SIZE = 116;
|
|
41352
|
+
const CUBE_CENTER = CUBE_SIZE / 2;
|
|
41353
|
+
const CUBE_SCALE = 26;
|
|
41354
|
+
const DEFAULT_CAMERA_STATE = {
|
|
41355
|
+
position: [120, 80, 120],
|
|
41356
|
+
target: [0, 0, 0],
|
|
41357
|
+
up: [0, 0, 1]
|
|
41358
|
+
};
|
|
41359
|
+
const FACE_DEFS = [
|
|
41360
|
+
{
|
|
41361
|
+
view: "right",
|
|
41362
|
+
label: "RIGHT",
|
|
41363
|
+
normal: new Vector3(1, 0, 0),
|
|
41364
|
+
corners: [new Vector3(1, -1, -1), new Vector3(1, 1, -1), new Vector3(1, 1, 1), new Vector3(1, -1, 1)]
|
|
41365
|
+
},
|
|
41366
|
+
{
|
|
41367
|
+
view: "left",
|
|
41368
|
+
label: "LEFT",
|
|
41369
|
+
normal: new Vector3(-1, 0, 0),
|
|
41370
|
+
corners: [new Vector3(-1, 1, -1), new Vector3(-1, -1, -1), new Vector3(-1, -1, 1), new Vector3(-1, 1, 1)]
|
|
41371
|
+
},
|
|
41372
|
+
{
|
|
41373
|
+
view: "back",
|
|
41374
|
+
label: "BACK",
|
|
41375
|
+
normal: new Vector3(0, 1, 0),
|
|
41376
|
+
corners: [new Vector3(1, 1, -1), new Vector3(-1, 1, -1), new Vector3(-1, 1, 1), new Vector3(1, 1, 1)]
|
|
41377
|
+
},
|
|
41378
|
+
{
|
|
41379
|
+
view: "front",
|
|
41380
|
+
label: "FRONT",
|
|
41381
|
+
normal: new Vector3(0, -1, 0),
|
|
41382
|
+
corners: [new Vector3(-1, -1, -1), new Vector3(1, -1, -1), new Vector3(1, -1, 1), new Vector3(-1, -1, 1)]
|
|
41383
|
+
},
|
|
41384
|
+
{
|
|
41385
|
+
view: "top",
|
|
41386
|
+
label: "TOP",
|
|
41387
|
+
normal: new Vector3(0, 0, 1),
|
|
41388
|
+
corners: [new Vector3(-1, -1, 1), new Vector3(1, -1, 1), new Vector3(1, 1, 1), new Vector3(-1, 1, 1)]
|
|
41389
|
+
},
|
|
41390
|
+
{
|
|
41391
|
+
view: "bottom",
|
|
41392
|
+
label: "BOTTOM",
|
|
41393
|
+
normal: new Vector3(0, 0, -1),
|
|
41394
|
+
corners: [new Vector3(-1, 1, -1), new Vector3(1, 1, -1), new Vector3(1, -1, -1), new Vector3(-1, -1, -1)]
|
|
41395
|
+
}
|
|
41396
|
+
];
|
|
41397
|
+
const SNAP_VIEWS = /* @__PURE__ */ new Set(["front", "back", "left", "right", "top", "bottom", "iso"]);
|
|
41398
|
+
function vectorFromTuple(tuple) {
|
|
41399
|
+
return new Vector3(tuple[0], tuple[1], tuple[2]);
|
|
41400
|
+
}
|
|
41401
|
+
function normalizedOr(vector, fallback) {
|
|
41402
|
+
return Number.isFinite(vector.x) && Number.isFinite(vector.y) && Number.isFinite(vector.z) && vector.lengthSq() > 1e-10 ? vector.clone().normalize() : fallback.clone().normalize();
|
|
41403
|
+
}
|
|
41404
|
+
function buildViewBasisFromCameraState(cameraState) {
|
|
41405
|
+
const position = vectorFromTuple(cameraState.position);
|
|
41406
|
+
const target = vectorFromTuple(cameraState.target);
|
|
41407
|
+
const up = normalizedOr(vectorFromTuple(cameraState.up), new Vector3(0, 0, 1));
|
|
41408
|
+
const viewer = normalizedOr(position.clone().sub(target), new Vector3(1, -1, 1));
|
|
41409
|
+
const forward = viewer.clone().negate();
|
|
41410
|
+
let right = forward.clone().cross(up);
|
|
41411
|
+
if (right.lengthSq() <= 1e-10) {
|
|
41412
|
+
right = Math.abs(forward.z) > 0.9 ? new Vector3(1, 0, 0) : forward.clone().cross(new Vector3(0, 0, 1));
|
|
41413
|
+
}
|
|
41414
|
+
right.normalize();
|
|
41415
|
+
const screenUp = normalizedOr(right.clone().cross(forward), new Vector3(0, 0, 1));
|
|
41416
|
+
return { viewer, right, screenUp };
|
|
41417
|
+
}
|
|
41418
|
+
const DEFAULT_VIEW_BASIS = buildViewBasisFromCameraState(DEFAULT_CAMERA_STATE);
|
|
41419
|
+
function buildViewBasisFromLiveCamera(camera) {
|
|
41420
|
+
camera.updateMatrixWorld();
|
|
41421
|
+
const quaternion = camera.getWorldQuaternion(new Quaternion());
|
|
41422
|
+
const viewer = normalizedOr(new Vector3(0, 0, 1).applyQuaternion(quaternion), DEFAULT_VIEW_BASIS.viewer);
|
|
41423
|
+
const right = normalizedOr(new Vector3(1, 0, 0).applyQuaternion(quaternion), DEFAULT_VIEW_BASIS.right);
|
|
41424
|
+
const screenUp = normalizedOr(new Vector3(0, 1, 0).applyQuaternion(quaternion), DEFAULT_VIEW_BASIS.screenUp);
|
|
41425
|
+
return { viewer, right, screenUp };
|
|
41426
|
+
}
|
|
41427
|
+
function faceFill(brightness) {
|
|
41428
|
+
const litPercent = Math.round(42 + brightness * 46);
|
|
41429
|
+
return `color-mix(in srgb, var(--fc-view-cube-face-lit) ${litPercent}%, var(--fc-view-cube-face-dim))`;
|
|
41430
|
+
}
|
|
41431
|
+
function projectVector(vector, right, screenUp, viewer) {
|
|
41432
|
+
return {
|
|
41433
|
+
x: CUBE_CENTER + vector.dot(right) * CUBE_SCALE,
|
|
41434
|
+
y: CUBE_CENTER - vector.dot(screenUp) * CUBE_SCALE,
|
|
41435
|
+
depth: vector.dot(viewer)
|
|
41436
|
+
};
|
|
41437
|
+
}
|
|
41438
|
+
function polygonPoints(points) {
|
|
41439
|
+
return points.map((point) => `${point.x.toFixed(1)},${point.y.toFixed(1)}`).join(" ");
|
|
41440
|
+
}
|
|
41441
|
+
function snapViewFromEventTarget(target) {
|
|
41442
|
+
var _a3;
|
|
41443
|
+
if (!(target instanceof Element)) return null;
|
|
41444
|
+
const view2 = (_a3 = target.closest(".fc-view-cube-face")) == null ? void 0 : _a3.dataset.view;
|
|
41445
|
+
return view2 && SNAP_VIEWS.has(view2) ? view2 : null;
|
|
41446
|
+
}
|
|
41447
|
+
function cameraRightVector(camera) {
|
|
41448
|
+
return buildViewBasisFromLiveCamera(camera).right;
|
|
41449
|
+
}
|
|
41450
|
+
function rotateCameraFromDrag(camera, controls, drag, clientX, clientY) {
|
|
41451
|
+
const dx = clientX - drag.startX;
|
|
41452
|
+
const dy = clientY - drag.startY;
|
|
41453
|
+
if (Math.hypot(dx, dy) > 3) drag.moved = true;
|
|
41454
|
+
const sensitivity = 8e-3;
|
|
41455
|
+
const startOffset = drag.startPosition.clone().sub(drag.target);
|
|
41456
|
+
const yaw = new Quaternion().setFromAxisAngle(drag.up, -dx * sensitivity);
|
|
41457
|
+
const pitchAxis = drag.right.clone().applyQuaternion(yaw).normalize();
|
|
41458
|
+
const pitch = new Quaternion().setFromAxisAngle(pitchAxis, -dy * sensitivity);
|
|
41459
|
+
const nextOffset = startOffset.applyQuaternion(yaw).applyQuaternion(pitch);
|
|
41460
|
+
camera.position.copy(drag.target).add(nextOffset);
|
|
41461
|
+
camera.up.copy(drag.up);
|
|
41462
|
+
controls.target.copy(drag.target);
|
|
41463
|
+
if ("updateProjectionMatrix" in camera) {
|
|
41464
|
+
camera.updateProjectionMatrix();
|
|
41465
|
+
}
|
|
41466
|
+
controls.update();
|
|
41467
|
+
}
|
|
41468
|
+
function ViewCube({ camera, controlsRef, onSnap }) {
|
|
41469
|
+
const [viewBasis, setViewBasis] = reactExports.useState(null);
|
|
41470
|
+
const [dragging, setDragging] = reactExports.useState(false);
|
|
41471
|
+
const [pressedView, setPressedView] = reactExports.useState(null);
|
|
41472
|
+
const dragInfoRef = reactExports.useRef(null);
|
|
41473
|
+
const pressedTimeoutRef = reactExports.useRef(null);
|
|
41474
|
+
const getLiveCamera = reactExports.useCallback(() => {
|
|
41475
|
+
var _a3;
|
|
41476
|
+
return camera ?? ((_a3 = controlsRef.current) == null ? void 0 : _a3.object) ?? null;
|
|
41477
|
+
}, [camera, controlsRef]);
|
|
41478
|
+
const triggerSnap = reactExports.useCallback(
|
|
41479
|
+
(view2) => {
|
|
41480
|
+
setPressedView(view2);
|
|
41481
|
+
if (pressedTimeoutRef.current !== null) {
|
|
41482
|
+
window.clearTimeout(pressedTimeoutRef.current);
|
|
41483
|
+
}
|
|
41484
|
+
pressedTimeoutRef.current = window.setTimeout(() => {
|
|
41485
|
+
pressedTimeoutRef.current = null;
|
|
41486
|
+
setPressedView(null);
|
|
41487
|
+
}, 180);
|
|
41488
|
+
onSnap(view2);
|
|
41489
|
+
},
|
|
41490
|
+
[onSnap]
|
|
41491
|
+
);
|
|
41492
|
+
const syncCameraState = reactExports.useCallback(() => {
|
|
41493
|
+
const controls = controlsRef.current;
|
|
41494
|
+
const liveCamera = getLiveCamera();
|
|
41495
|
+
if (!liveCamera || !controls) return;
|
|
41496
|
+
setViewBasis(buildViewBasisFromLiveCamera(liveCamera));
|
|
41497
|
+
}, [controlsRef, getLiveCamera]);
|
|
41498
|
+
reactExports.useEffect(() => {
|
|
41499
|
+
let disposed = false;
|
|
41500
|
+
let retryFrame = 0;
|
|
41501
|
+
let controls = null;
|
|
41502
|
+
const attach2 = () => {
|
|
41503
|
+
if (disposed) return;
|
|
41504
|
+
controls = controlsRef.current;
|
|
41505
|
+
if (!getLiveCamera() || !controls) {
|
|
41506
|
+
retryFrame = window.requestAnimationFrame(attach2);
|
|
41507
|
+
return;
|
|
41508
|
+
}
|
|
41509
|
+
syncCameraState();
|
|
41510
|
+
controls.addEventListener("change", syncCameraState);
|
|
41511
|
+
};
|
|
41512
|
+
attach2();
|
|
41513
|
+
return () => {
|
|
41514
|
+
disposed = true;
|
|
41515
|
+
if (retryFrame) window.cancelAnimationFrame(retryFrame);
|
|
41516
|
+
controls == null ? void 0 : controls.removeEventListener("change", syncCameraState);
|
|
41517
|
+
};
|
|
41518
|
+
}, [controlsRef, getLiveCamera, syncCameraState]);
|
|
41519
|
+
reactExports.useEffect(() => {
|
|
41520
|
+
return () => {
|
|
41521
|
+
if (pressedTimeoutRef.current !== null) {
|
|
41522
|
+
window.clearTimeout(pressedTimeoutRef.current);
|
|
41523
|
+
}
|
|
41524
|
+
};
|
|
41525
|
+
}, []);
|
|
41526
|
+
const faces = reactExports.useMemo(() => {
|
|
41527
|
+
const { viewer, right, screenUp } = viewBasis ?? DEFAULT_VIEW_BASIS;
|
|
41528
|
+
const projectedFaces = FACE_DEFS.map((face) => {
|
|
41529
|
+
const visibility = face.normal.dot(viewer);
|
|
41530
|
+
if (visibility <= 0.02) return null;
|
|
41531
|
+
const points = face.corners.map((corner) => projectVector(corner, right, screenUp, viewer));
|
|
41532
|
+
const center = projectVector(face.normal, right, screenUp, viewer);
|
|
41533
|
+
const depth = points.reduce((sum, point) => sum + point.depth, 0) / points.length;
|
|
41534
|
+
return {
|
|
41535
|
+
view: face.view,
|
|
41536
|
+
label: face.label,
|
|
41537
|
+
points,
|
|
41538
|
+
center,
|
|
41539
|
+
depth,
|
|
41540
|
+
brightness: MathUtils.clamp(visibility, 0, 1)
|
|
41541
|
+
};
|
|
41542
|
+
}).filter((face) => face !== null).sort((a2, b2) => a2.depth - b2.depth);
|
|
41543
|
+
return projectedFaces;
|
|
41544
|
+
}, [viewBasis]);
|
|
41545
|
+
const handlePointerDown = reactExports.useCallback(
|
|
41546
|
+
(event) => {
|
|
41547
|
+
if (event.button !== 0) return;
|
|
41548
|
+
const liveCamera = getLiveCamera();
|
|
41549
|
+
const clickView = snapViewFromEventTarget(event.target);
|
|
41550
|
+
const controls = controlsRef.current;
|
|
41551
|
+
if (!clickView && (!liveCamera || !controls)) return;
|
|
41552
|
+
const target = (controls == null ? void 0 : controls.target.clone()) ?? new Vector3();
|
|
41553
|
+
const up = liveCamera ? normalizedOr(liveCamera.up, new Vector3(0, 0, 1)) : new Vector3(0, 0, 1);
|
|
41554
|
+
dragInfoRef.current = {
|
|
41555
|
+
pointerId: event.pointerId,
|
|
41556
|
+
startX: event.clientX,
|
|
41557
|
+
startY: event.clientY,
|
|
41558
|
+
startPosition: (liveCamera == null ? void 0 : liveCamera.position.clone()) ?? new Vector3(),
|
|
41559
|
+
target,
|
|
41560
|
+
up,
|
|
41561
|
+
right: liveCamera && controls ? cameraRightVector(liveCamera) : new Vector3(1, 0, 0),
|
|
41562
|
+
moved: false,
|
|
41563
|
+
clickView
|
|
41564
|
+
};
|
|
41565
|
+
event.currentTarget.setPointerCapture(event.pointerId);
|
|
41566
|
+
setDragging(true);
|
|
41567
|
+
},
|
|
41568
|
+
[controlsRef, getLiveCamera]
|
|
41569
|
+
);
|
|
41570
|
+
const handlePointerMove = reactExports.useCallback(
|
|
41571
|
+
(event) => {
|
|
41572
|
+
const drag = dragInfoRef.current;
|
|
41573
|
+
if (!drag || drag.pointerId !== event.pointerId) return;
|
|
41574
|
+
if (Math.hypot(event.clientX - drag.startX, event.clientY - drag.startY) > 3) {
|
|
41575
|
+
drag.moved = true;
|
|
41576
|
+
}
|
|
41577
|
+
const controls = controlsRef.current;
|
|
41578
|
+
const liveCamera = getLiveCamera();
|
|
41579
|
+
if (!liveCamera || !controls) return;
|
|
41580
|
+
event.preventDefault();
|
|
41581
|
+
rotateCameraFromDrag(liveCamera, controls, drag, event.clientX, event.clientY);
|
|
41582
|
+
syncCameraState();
|
|
41583
|
+
},
|
|
41584
|
+
[controlsRef, getLiveCamera, syncCameraState]
|
|
41585
|
+
);
|
|
41586
|
+
const finishPointerDrag = reactExports.useCallback(
|
|
41587
|
+
(event) => {
|
|
41588
|
+
const drag = dragInfoRef.current;
|
|
41589
|
+
if (!drag || drag.pointerId !== event.pointerId) return;
|
|
41590
|
+
dragInfoRef.current = null;
|
|
41591
|
+
event.currentTarget.releasePointerCapture(event.pointerId);
|
|
41592
|
+
setDragging(false);
|
|
41593
|
+
if (!drag.moved && drag.clickView) {
|
|
41594
|
+
triggerSnap(drag.clickView);
|
|
41595
|
+
}
|
|
41596
|
+
},
|
|
41597
|
+
[triggerSnap]
|
|
41598
|
+
);
|
|
41599
|
+
const handleFaceKeyDown = reactExports.useCallback(
|
|
41600
|
+
(event, view2) => {
|
|
41601
|
+
if (event.key !== "Enter" && event.key !== " ") return;
|
|
41602
|
+
event.preventDefault();
|
|
41603
|
+
triggerSnap(view2);
|
|
41604
|
+
},
|
|
41605
|
+
[triggerSnap]
|
|
41606
|
+
);
|
|
41607
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
41608
|
+
"div",
|
|
41609
|
+
{
|
|
41610
|
+
className: `fc-view-cube${dragging ? " dragging" : ""}`,
|
|
41611
|
+
"aria-label": "View cube",
|
|
41612
|
+
onPointerDown: handlePointerDown,
|
|
41613
|
+
onPointerMove: handlePointerMove,
|
|
41614
|
+
onPointerUp: finishPointerDrag,
|
|
41615
|
+
onPointerCancel: finishPointerDrag,
|
|
41616
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsxs("svg", { className: "fc-view-cube-svg", viewBox: `0 0 ${CUBE_SIZE} ${CUBE_SIZE}`, role: "img", "aria-label": "Viewport orientation", children: [
|
|
41617
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("defs", { children: /* @__PURE__ */ jsxRuntimeExports.jsx("filter", { id: "fc-view-cube-shadow", x: "-20%", y: "-20%", width: "140%", height: "140%", children: /* @__PURE__ */ jsxRuntimeExports.jsx("feDropShadow", { dx: "0", dy: "2", stdDeviation: "2", floodColor: "#07101a", floodOpacity: "0.28" }) }) }),
|
|
41618
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("g", { filter: "url(#fc-view-cube-shadow)", children: faces.map((face) => /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
41619
|
+
"g",
|
|
41620
|
+
{
|
|
41621
|
+
className: `fc-view-cube-face${pressedView === face.view ? " active" : ""}`,
|
|
41622
|
+
role: "button",
|
|
41623
|
+
tabIndex: 0,
|
|
41624
|
+
"data-view": face.view,
|
|
41625
|
+
"aria-label": `View ${face.label.toLowerCase()}`,
|
|
41626
|
+
onKeyDown: (event) => handleFaceKeyDown(event, face.view),
|
|
41627
|
+
children: [
|
|
41628
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("polygon", { points: polygonPoints(face.points), fill: faceFill(face.brightness) }),
|
|
41629
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("text", { x: face.center.x, y: face.center.y, className: "fc-view-cube-face-label", children: face.label })
|
|
41630
|
+
]
|
|
41631
|
+
},
|
|
41632
|
+
face.view
|
|
41633
|
+
)) })
|
|
41634
|
+
] })
|
|
41635
|
+
}
|
|
41636
|
+
);
|
|
41637
|
+
}
|
|
41154
41638
|
const FLAG_DEFINITIONS = {
|
|
41155
41639
|
drawMode: {
|
|
41156
41640
|
label: "Draw Mode (interactive sketch editor)",
|
|
@@ -41763,6 +42247,7 @@ function useViewportState() {
|
|
|
41763
42247
|
const projectionMode = useForgeStore((s) => s.projectionMode);
|
|
41764
42248
|
const gridEnabled = useForgeStore((s) => s.gridEnabled);
|
|
41765
42249
|
const axesVisible = useForgeStore((s) => s.axesVisible);
|
|
42250
|
+
const viewCubeVisible = useForgeStore((s) => s.viewCubeVisible);
|
|
41766
42251
|
const gridSize = useForgeStore((s) => s.gridSize);
|
|
41767
42252
|
const showPerformanceInfo = useForgeStore((s) => s.showPerformanceInfo);
|
|
41768
42253
|
const objectSettings = useForgeStore((s) => s.objectSettings);
|
|
@@ -41776,9 +42261,7 @@ function useViewportState() {
|
|
|
41776
42261
|
const clearFocusedObject = useForgeStore((s) => s.clearFocusedObject);
|
|
41777
42262
|
const objectPickSyncEnabled = useForgeStore((s) => s.objectPickSyncEnabled);
|
|
41778
42263
|
const explodeAmount = useForgeStore((s) => s.explodeAmount);
|
|
41779
|
-
const viewCommand = useForgeStore((s) => s.viewCommand);
|
|
41780
42264
|
const requestViewCommand = useForgeStore((s) => s.requestViewCommand);
|
|
41781
|
-
const clearViewCommand = useForgeStore((s) => s.clearViewCommand);
|
|
41782
42265
|
const jointValues = useForgeStore((s) => s.jointValues);
|
|
41783
42266
|
const jointAnimationClip = useForgeStore((s) => s.jointAnimationClip);
|
|
41784
42267
|
const jointAnimationProgress = useForgeStore((s) => s.jointAnimationProgress);
|
|
@@ -42156,6 +42639,7 @@ function useViewportState() {
|
|
|
42156
42639
|
projectionMode,
|
|
42157
42640
|
gridEnabled,
|
|
42158
42641
|
axesVisible,
|
|
42642
|
+
viewCubeVisible,
|
|
42159
42643
|
gridSize,
|
|
42160
42644
|
showPerformanceInfo,
|
|
42161
42645
|
objectSettings,
|
|
@@ -42169,9 +42653,7 @@ function useViewportState() {
|
|
|
42169
42653
|
clearFocusedObject,
|
|
42170
42654
|
objectPickSyncEnabled,
|
|
42171
42655
|
explodeAmount,
|
|
42172
|
-
viewCommand,
|
|
42173
42656
|
requestViewCommand,
|
|
42174
|
-
clearViewCommand,
|
|
42175
42657
|
jointValues,
|
|
42176
42658
|
jointAnimationClip,
|
|
42177
42659
|
jointAnimationProgress,
|
|
@@ -44876,6 +45358,7 @@ function Viewport() {
|
|
|
44876
45358
|
projectionMode,
|
|
44877
45359
|
gridEnabled,
|
|
44878
45360
|
axesVisible,
|
|
45361
|
+
viewCubeVisible,
|
|
44879
45362
|
gridSize,
|
|
44880
45363
|
showPerformanceInfo,
|
|
44881
45364
|
objectSettings,
|
|
@@ -44888,9 +45371,7 @@ function Viewport() {
|
|
|
44888
45371
|
focusObject,
|
|
44889
45372
|
clearFocusedObject,
|
|
44890
45373
|
objectPickSyncEnabled,
|
|
44891
|
-
viewCommand,
|
|
44892
45374
|
requestViewCommand,
|
|
44893
|
-
clearViewCommand,
|
|
44894
45375
|
lengthUnit,
|
|
44895
45376
|
constructionGhost,
|
|
44896
45377
|
objects,
|
|
@@ -44961,10 +45442,17 @@ function Viewport() {
|
|
|
44961
45442
|
const vRulerRef = reactExports.useRef(null);
|
|
44962
45443
|
const adaptiveGrid = useAdaptiveGrid(zoomMmPerPx, isSketchOnly && gridEnabled);
|
|
44963
45444
|
const controlsRef = reactExports.useRef(null);
|
|
45445
|
+
const [activeCanvasCamera, setActiveCanvasCamera] = reactExports.useState(null);
|
|
44964
45446
|
const initialFitRequestedRef = reactExports.useRef(false);
|
|
44965
45447
|
const prevPreviewFileRef = reactExports.useRef(void 0);
|
|
44966
45448
|
const containerRef = reactExports.useRef(null);
|
|
44967
45449
|
const contextMenuRef = reactExports.useRef(null);
|
|
45450
|
+
const handleActiveCameraChange = reactExports.useCallback((camera) => {
|
|
45451
|
+
setActiveCanvasCamera(camera);
|
|
45452
|
+
}, []);
|
|
45453
|
+
const handleCanvasCreated = reactExports.useCallback((state22) => {
|
|
45454
|
+
setActiveCanvasCamera(state22.camera);
|
|
45455
|
+
}, []);
|
|
44968
45456
|
const t2 = themes[themeName];
|
|
44969
45457
|
const renderStylePreset = reactExports.useMemo(() => getRenderStylePreset(renderStyle), [renderStyle]);
|
|
44970
45458
|
const effectiveSceneConfig = reactExports.useMemo(
|
|
@@ -45325,7 +45813,9 @@ function Viewport() {
|
|
|
45325
45813
|
raycaster: { params: { Line: { threshold: 0.5 } } },
|
|
45326
45814
|
camera: { up: [0, 0, 1] },
|
|
45327
45815
|
onPointerMissed: handleViewportPointerMissed,
|
|
45816
|
+
onCreated: handleCanvasCreated,
|
|
45328
45817
|
children: [
|
|
45818
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(ActiveCameraBridge, { onCameraChange: handleActiveCameraChange }),
|
|
45329
45819
|
/* @__PURE__ */ jsxRuntimeExports.jsxs(reactExports.Suspense, { fallback: null, children: [
|
|
45330
45820
|
projectionMode === "orthographic" ? /* @__PURE__ */ jsxRuntimeExports.jsx(OrthographicCamera, { makeDefault: true, position: [120, 80, 120], zoom: 2, near: -5e4, far: 5e4, up: [0, 0, 1] }) : /* @__PURE__ */ jsxRuntimeExports.jsx(PerspectiveCamera, { makeDefault: true, position: [120, 80, 120], fov: 45, near: 0.1, far: 1e5, up: [0, 0, 1] }),
|
|
45331
45821
|
((_d = effectiveSceneConfig == null ? void 0 : effectiveSceneConfig.postProcessing) == null ? void 0 : _d.toneMappingExposure) === void 0 && /* @__PURE__ */ jsxRuntimeExports.jsx(RenderStyleExposure, { exposure: renderStylePreset.toneMappingExposure }),
|
|
@@ -45639,23 +46129,24 @@ function Viewport() {
|
|
|
45639
46129
|
/* @__PURE__ */ jsxRuntimeExports.jsx(ViewportRecordingBridge, { controlsRef }),
|
|
45640
46130
|
historyMode && /* @__PURE__ */ jsxRuntimeExports.jsx(HistoryRecorderBridge, {}),
|
|
45641
46131
|
/* @__PURE__ */ jsxRuntimeExports.jsx(TrajectoryRecorderBridge, { controlsRef })
|
|
45642
|
-
] })
|
|
45643
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
45644
|
-
ViewController,
|
|
45645
|
-
{
|
|
45646
|
-
controlsRef,
|
|
45647
|
-
command: viewCommand,
|
|
45648
|
-
objects,
|
|
45649
|
-
objectMatrices,
|
|
45650
|
-
fallbackBounds: rigInspectActive ? rigInspectionBounds : null,
|
|
45651
|
-
settings: objectSettings,
|
|
45652
|
-
focusedObjectIds,
|
|
45653
|
-
clearCommand: clearViewCommand
|
|
45654
|
-
}
|
|
45655
|
-
)
|
|
46132
|
+
] })
|
|
45656
46133
|
]
|
|
45657
46134
|
}
|
|
45658
46135
|
),
|
|
46136
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
46137
|
+
ViewController,
|
|
46138
|
+
{
|
|
46139
|
+
camera: activeCanvasCamera,
|
|
46140
|
+
controlsRef,
|
|
46141
|
+
viewportRef: containerRef,
|
|
46142
|
+
objects,
|
|
46143
|
+
objectMatrices,
|
|
46144
|
+
fallbackBounds: rigInspectActive ? rigInspectionBounds : null,
|
|
46145
|
+
settings: objectSettings,
|
|
46146
|
+
focusedObjectIds
|
|
46147
|
+
}
|
|
46148
|
+
),
|
|
46149
|
+
viewCubeVisible && !isSketchOnly && /* @__PURE__ */ jsxRuntimeExports.jsx(ViewCube, { camera: activeCanvasCamera, controlsRef, onSnap: (view2) => requestViewCommand({ type: "snap", view: view2 }) }),
|
|
45659
46150
|
(() => {
|
|
45660
46151
|
const toolpathObj = objects.find((o2) => o2.toolpath && o2.toolpath.segments.length > 0);
|
|
45661
46152
|
if (!(toolpathObj == null ? void 0 : toolpathObj.toolpath)) return null;
|
|
@@ -46211,7 +46702,7 @@ function Viewport() {
|
|
|
46211
46702
|
}
|
|
46212
46703
|
);
|
|
46213
46704
|
}
|
|
46214
|
-
const EditorApp$1 = reactExports.lazy(() => __vitePreload(() => import("./EditorApp-
|
|
46705
|
+
const EditorApp$1 = reactExports.lazy(() => __vitePreload(() => import("./EditorApp-BJ0Dloyh.js"), true ? __vite__mapDeps([0]) : void 0).then((m2) => ({ default: m2.EditorApp })));
|
|
46215
46706
|
const PENDING_SHARE_COPY_KEY = "fc-pending-share-copy";
|
|
46216
46707
|
function storePendingShareCopy(shareId) {
|
|
46217
46708
|
sessionStorage.setItem(PENDING_SHARE_COPY_KEY, shareId);
|
|
@@ -46400,7 +46891,7 @@ const PublishedModelPage$1 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Objec
|
|
|
46400
46891
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
46401
46892
|
const siteUrl = "https://forgecad.io";
|
|
46402
46893
|
const defaultImage = "https://forgecad.io/brand/social-card.png";
|
|
46403
|
-
const pages$1 = [{ "path": "/", "title": "ForgeCAD - AI-Native CAD for Manufacturable Models", "description": "ForgeCAD turns prompts, JavaScript, and product ideas into editable parametric CAD with agent validation, manufacturing feedback, and STEP/STL exports.", "priority": "1.0", "changefreq": "weekly" }, { "path": "/docs", "title": "ForgeCAD Documentation - AI-Native Parametric CAD", "description": "Learn ForgeCAD's JavaScript CAD API, agent workflow, validation loop, exports, assemblies, sketches, and manufacturing-ready model checks.", "priority": "0.8", "changefreq": "weekly" }, { "path": "/docs/ai-native-cad", "title": "AI-Native CAD Workflow - ForgeCAD", "description": "How ForgeCAD supports AI-driven CAD: editable code, validation evidence, manufacturing feedback, and parallel product idea iteration.", "priority": "0.9", "changefreq": "weekly" }, { "path": "/docs/ai-usage", "title": "AI CAD Agent Setup - ForgeCAD", "description": "Set up Codex, Claude Code, OpenCode, or another agent to build, validate, inspect, export, and publish ForgeCAD models.", "priority": "0.8", "changefreq": "weekly" }, { "path": "/docs/cli", "title": "ForgeCAD CLI - Validate, Inspect, Export, Publish", "description": "Use the ForgeCAD CLI to run .forge.js models, render evidence, inspect manufacturability, export STEP/STL/3MF, and sync projects.", "priority": "0.7", "changefreq": "weekly" }, { "path": "/docs/skills/forgecad-make-a-model", "title": "AI CAD Model-Making Skill - ForgeCAD", "description": "A workflow for AI agents to create manufacture-realistic ForgeCAD models with validation, renders, inspection evidence, and exports.", "priority": "0.7", "changefreq": "weekly" }, { "path": "/benchmark", "title": "ForgeCAD Benchmark - AI CAD Model Generation", "description": "Benchmark AI agents generating real ForgeCAD models with executable code, visual evidence, validation output, and geometry checks.", "priority": "0.7", "changefreq": "weekly" }, { "path": "/blog", "title": "ForgeCAD Blog - AI-Native CAD and Manufacturing Workflows", "description": "Product notes, tutorials, examples, and technical updates on AI-native CAD, parametric modeling, validation, and manufacturing exports.", "priority": "0.6", "changefreq": "weekly" }, { "path": "/pricing", "title": "ForgeCAD Pricing", "description": "ForgeCAD plans for browser CAD, local CLI workflows, AI agent model generation, project publishing, and commercial use.", "priority": "0.5", "changefreq": "monthly" }, { "path": "/terms", "title": "ForgeCAD Terms of Service", "description": "Terms for ForgeCAD accounts, projects, hosted services, CLI use, commercial use, automation, and AI-assisted workflows.", "priority": "0.3", "changefreq": "yearly" }, { "path": "/privacy", "title": "ForgeCAD Privacy Policy", "description": "How ForgeCAD handles account, project, billing, analytics, and service data for the website, CLI, and hosted app.", "priority": "0.3", "changefreq": "yearly" }, { "path": "/license", "title": "ForgeCAD Software License", "description": "ForgeCAD license terms for Free, Pro, Enterprise, embedded, backend, local CLI, and AI workflow usage.", "priority": "0.3", "changefreq": "yearly" }];
|
|
46894
|
+
const pages$1 = [{ "path": "/", "title": "ForgeCAD - AI-Native CAD for Manufacturable Models", "description": "ForgeCAD turns prompts, JavaScript, and product ideas into editable parametric CAD with agent validation, manufacturing feedback, and STEP/STL exports.", "priority": "1.0", "changefreq": "weekly" }, { "path": "/docs", "title": "ForgeCAD Documentation - AI-Native Parametric CAD", "description": "Learn ForgeCAD's JavaScript CAD API, agent workflow, validation loop, exports, assemblies, sketches, and manufacturing-ready model checks.", "priority": "0.8", "changefreq": "weekly" }, { "path": "/docs/ai-native-cad", "title": "AI-Native CAD Workflow - ForgeCAD", "description": "How ForgeCAD supports AI-driven CAD: editable code, validation evidence, manufacturing feedback, and parallel product idea iteration.", "priority": "0.9", "changefreq": "weekly" }, { "path": "/docs/ai-usage", "title": "AI CAD Agent Setup - ForgeCAD", "description": "Set up Codex, Claude Code, OpenCode, or another agent to build, validate, inspect, export, and publish ForgeCAD models.", "priority": "0.8", "changefreq": "weekly" }, { "path": "/docs/cli", "title": "ForgeCAD CLI - Validate, Inspect, Export, Publish", "description": "Use the ForgeCAD CLI to run .forge.js models, render evidence, inspect manufacturability, export STEP/STL/3MF, and sync projects.", "priority": "0.7", "changefreq": "weekly" }, { "path": "/docs/simready-quickstart", "title": "ForgeCAD SimReady Quickstart - Source-Authored Simulation Metadata", "description": "Author ForgeCAD assemblies with physical bodies, materials, colliders, joints, controllers, offline SimReady checks, and simulator exports.", "priority": "0.8", "changefreq": "weekly" }, { "path": "/docs/simulation-workflow", "title": "ForgeCAD Simulation Workflow - MuJoCo, Gym, and Isaac Lab Handoff", "description": "Take a ForgeCAD robot through MJCF export, MuJoCo playback, Gymnasium training, force-push interaction tests, and Isaac Lab integration planning.", "priority": "0.8", "changefreq": "weekly" }, { "path": "/docs/skills/forgecad-make-a-model", "title": "AI CAD Model-Making Skill - ForgeCAD", "description": "A workflow for AI agents to create manufacture-realistic ForgeCAD models with validation, renders, inspection evidence, and exports.", "priority": "0.7", "changefreq": "weekly" }, { "path": "/benchmark", "title": "ForgeCAD Benchmark - AI CAD Model Generation", "description": "Benchmark AI agents generating real ForgeCAD models with executable code, visual evidence, validation output, and geometry checks.", "priority": "0.7", "changefreq": "weekly" }, { "path": "/blog", "title": "ForgeCAD Blog - AI-Native CAD and Manufacturing Workflows", "description": "Product notes, tutorials, examples, and technical updates on AI-native CAD, parametric modeling, validation, and manufacturing exports.", "priority": "0.6", "changefreq": "weekly" }, { "path": "/pricing", "title": "ForgeCAD Pricing", "description": "ForgeCAD plans for browser CAD, local CLI workflows, AI agent model generation, project publishing, and commercial use.", "priority": "0.5", "changefreq": "monthly" }, { "path": "/terms", "title": "ForgeCAD Terms of Service", "description": "Terms for ForgeCAD accounts, projects, hosted services, CLI use, commercial use, automation, and AI-assisted workflows.", "priority": "0.3", "changefreq": "yearly" }, { "path": "/privacy", "title": "ForgeCAD Privacy Policy", "description": "How ForgeCAD handles account, project, billing, analytics, and service data for the website, CLI, and hosted app.", "priority": "0.3", "changefreq": "yearly" }, { "path": "/license", "title": "ForgeCAD Software License", "description": "ForgeCAD license terms for Free, Pro, Enterprise, embedded, backend, local CLI, and AI workflow usage.", "priority": "0.3", "changefreq": "yearly" }];
|
|
46404
46895
|
const seoConfig = {
|
|
46405
46896
|
siteUrl,
|
|
46406
46897
|
defaultImage,
|
|
@@ -46477,17 +46968,17 @@ function SeoMetadata() {
|
|
|
46477
46968
|
}, [location.pathname]);
|
|
46478
46969
|
return null;
|
|
46479
46970
|
}
|
|
46480
|
-
reactExports.lazy(() => __vitePreload(() => import("./LandingPageProofDriven-
|
|
46481
|
-
const DocsPage = reactExports.lazy(() => __vitePreload(() => import("./DocsPage-
|
|
46482
|
-
reactExports.lazy(() => __vitePreload(() => import("./BlogPage-
|
|
46483
|
-
reactExports.lazy(() => __vitePreload(() => import("./BenchmarkPage-
|
|
46484
|
-
reactExports.lazy(() => __vitePreload(() => import("./AdminPage-
|
|
46971
|
+
reactExports.lazy(() => __vitePreload(() => import("./LandingPageProofDriven-BxHkYRE7.js"), true ? __vite__mapDeps([1]) : void 0).then((m2) => ({ default: m2.LandingPageProofDriven })));
|
|
46972
|
+
const DocsPage = reactExports.lazy(() => __vitePreload(() => import("./DocsPage-CDoxHkz8.js"), true ? [] : void 0).then((m2) => ({ default: m2.DocsPage })));
|
|
46973
|
+
reactExports.lazy(() => __vitePreload(() => import("./BlogPage-DHaGP50_.js"), true ? [] : void 0).then((m2) => ({ default: m2.BlogPage })));
|
|
46974
|
+
reactExports.lazy(() => __vitePreload(() => import("./BenchmarkPage-BVEpJSVk.js"), true ? __vite__mapDeps([1,2]) : void 0).then((m2) => ({ default: m2.BenchmarkPage })));
|
|
46975
|
+
reactExports.lazy(() => __vitePreload(() => import("./AdminPage-DcCnj0qo.js"), true ? [] : void 0).then((m2) => ({ default: m2.AdminPage })));
|
|
46485
46976
|
reactExports.lazy(() => __vitePreload(() => Promise.resolve().then(() => PublishedModelPage$1), true ? void 0 : void 0).then((m2) => ({ default: m2.PublishedModelPage })));
|
|
46486
|
-
reactExports.lazy(() => __vitePreload(() => import("./SettingsPage-
|
|
46487
|
-
reactExports.lazy(() => __vitePreload(() => import("./PricingPage-
|
|
46488
|
-
reactExports.lazy(() => __vitePreload(() => import("./LegalPage-
|
|
46489
|
-
const EditorApp = reactExports.lazy(() => __vitePreload(() => import("./EditorApp-
|
|
46490
|
-
const EmbedViewer = reactExports.lazy(() => __vitePreload(() => import("./EmbedViewer-
|
|
46977
|
+
reactExports.lazy(() => __vitePreload(() => import("./SettingsPage-CIZSSAd0.js"), true ? [] : void 0).then((m2) => ({ default: m2.SettingsPage })));
|
|
46978
|
+
reactExports.lazy(() => __vitePreload(() => import("./PricingPage-CzpZ6-Ce.js"), true ? __vite__mapDeps([1,3]) : void 0).then((m2) => ({ default: m2.PricingPage })));
|
|
46979
|
+
reactExports.lazy(() => __vitePreload(() => import("./LegalPage-B-u6FrVv.js"), true ? __vite__mapDeps([1,4]) : void 0).then((m2) => ({ default: m2.LegalPage })));
|
|
46980
|
+
const EditorApp = reactExports.lazy(() => __vitePreload(() => import("./EditorApp-BJ0Dloyh.js"), true ? __vite__mapDeps([0]) : void 0).then((m2) => ({ default: m2.EditorApp })));
|
|
46981
|
+
const EmbedViewer = reactExports.lazy(() => __vitePreload(() => import("./EmbedViewer-CRKZbY0y.js"), true ? [] : void 0).then((m2) => ({ default: m2.EmbedViewer })));
|
|
46491
46982
|
const embedMode = isEmbedMode() && !window.location.pathname.startsWith("/m/");
|
|
46492
46983
|
const EDITABLE_CRASH_FILE = /\.(?:forge\.js|[cm]?[jt]sx?|json|md|txt|svg|dxf)$/i;
|
|
46493
46984
|
function firstMeaningfulLine(text) {
|
|
@@ -46745,11 +47236,12 @@ export {
|
|
|
46745
47236
|
hasProjectTextFileExtension as a6,
|
|
46746
47237
|
expandBoundsByTransformedAabb as a7,
|
|
46747
47238
|
Canvas as a8,
|
|
46748
|
-
|
|
46749
|
-
|
|
46750
|
-
|
|
46751
|
-
|
|
46752
|
-
|
|
47239
|
+
ActiveCameraBridge as a9,
|
|
47240
|
+
storePendingShareCopy as aA,
|
|
47241
|
+
buildShareUrl as aB,
|
|
47242
|
+
share as aC,
|
|
47243
|
+
PerspectiveCamera as aa,
|
|
47244
|
+
ControlsInteractionBridge as ab,
|
|
46753
47245
|
SceneConfigurator as ac,
|
|
46754
47246
|
LocalEnvironment as ad,
|
|
46755
47247
|
ForgeObject as ae,
|
|
@@ -46758,22 +47250,22 @@ export {
|
|
|
46758
47250
|
OrbitControls2 as ah,
|
|
46759
47251
|
TOUCH_GESTURES_3D as ai,
|
|
46760
47252
|
MOUSE_BUTTONS_3D as aj,
|
|
46761
|
-
|
|
46762
|
-
|
|
46763
|
-
|
|
46764
|
-
|
|
46765
|
-
|
|
46766
|
-
|
|
46767
|
-
|
|
46768
|
-
|
|
46769
|
-
|
|
46770
|
-
|
|
46771
|
-
|
|
46772
|
-
|
|
46773
|
-
|
|
46774
|
-
|
|
46775
|
-
|
|
46776
|
-
|
|
47253
|
+
ViewController as ak,
|
|
47254
|
+
ModelJourneyBar as al,
|
|
47255
|
+
useJointAnimationLoop as am,
|
|
47256
|
+
computeJointNodeMatrices as an,
|
|
47257
|
+
computeObjectJointMatrices as ao,
|
|
47258
|
+
readLastActiveFileForUser as ap,
|
|
47259
|
+
ToastContainer as aq,
|
|
47260
|
+
isMobile as ar,
|
|
47261
|
+
useFeatureFlag as as,
|
|
47262
|
+
decodeSharedHash as at,
|
|
47263
|
+
decodeSharedBundle as au,
|
|
47264
|
+
getExternalUrl as av,
|
|
47265
|
+
getGistId as aw,
|
|
47266
|
+
Viewport as ax,
|
|
47267
|
+
shouldBlockBrowserShortcut as ay,
|
|
47268
|
+
useDrawStore as az,
|
|
46777
47269
|
authFetch as b,
|
|
46778
47270
|
authApi as c,
|
|
46779
47271
|
showToast as d,
|