forgecad 0.9.16 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/assets/{AdminPage-CXvls4-J.js → AdminPage-DwYHz72L.js} +1 -1
- package/dist/assets/{BenchmarkPage-B27zk8xL.js → BenchmarkPage-a9_f-1US.js} +1 -1
- package/dist/assets/{BlogPage-CMAVvgQL.js → BlogPage-DodHpvmf.js} +1 -1
- package/dist/assets/{DocsPage-knf4I4h7.js → DocsPage-B5LePEuj.js} +8 -858
- package/dist/assets/EditorApp-QXsAISLR.js +16307 -0
- package/dist/assets/{EmbedViewer-D7ZGlFjx.js → EmbedViewer-DdEHGUMU.js} +2 -2
- package/dist/assets/{LandingPageProofDriven-CnevhTE8.js → LandingPageProofDriven-yhhOodbf.js} +1 -1
- package/dist/assets/{LegalPage-BPTUmqeg.js → LegalPage-5RbKRGYK.js} +1 -1
- package/dist/assets/{PricingPage-B0D4goG_.js → PricingPage-E3Rma7aV.js} +1 -1
- package/dist/assets/{SettingsPage-CFF-UgjI.js → SettingsPage-BJZcM97j.js} +1 -1
- package/dist/assets/{app-T0pDcSX4.js → app-DSYrDg0V.js} +733 -205
- package/dist/assets/cli/{render-C5pcIISc.js → render-ZMHR9HkV.js} +19 -46
- package/dist/assets/{constructionHistoryWorker-Ba2Hm58b.js → constructionHistoryWorker-AwMMWSxg.js} +1103 -349
- package/dist/assets/{evalWorker-vkx310U2.js → evalWorker-DbNs7Dkp.js} +3798 -1622
- package/dist/assets/{inspectWorker-BuTJDVX6.js → inspectWorker-CZsCFtQT.js} +1163 -409
- package/dist/assets/{jointPose-B_Cgedn9.js → jointPose-DO6mnXn_.js} +1 -1
- package/dist/assets/{manifold-BWgsjmAM.js → manifold-BGlQBBH9.js} +1 -1
- package/dist/assets/{manifold-rZexZI0G.js → manifold-BU-tJwQh.js} +1 -1
- package/dist/assets/{manifold-D6IFSkhH.js → manifold-fy2MV7K1.js} +2 -2
- package/dist/assets/{reportWorker-0AGij1Ru.js → reportWorker-DO6hcQbh.js} +7155 -2437
- package/dist/assets/{scalar-sampling-budget-J5cuzxT1.js → scalar-sampling-budget-o90NSNmF.js} +3940 -1742
- package/dist/assets/{scanProxyWorker-Vl4Wxa1y.js → scanProxyWorker-2GtDLk-R.js} +1 -1
- package/dist/assets/{javascript-1kQXfVaz.js → typescript-DBQ6RN5l.js} +874 -22
- package/dist/cli/render.html +1 -1
- package/dist/docs/index.html +3 -3
- package/dist/docs-raw/AI/usage.md +1 -1
- package/dist/docs-raw/CLI.md +63 -241
- package/dist/docs-raw/README.md +6 -0
- package/dist/docs-raw/component-model.md +17 -150
- package/dist/docs-raw/generated/assembly.md +139 -598
- package/dist/docs-raw/generated/concepts.md +245 -3501
- package/dist/docs-raw/generated/core.md +277 -1251
- package/dist/docs-raw/generated/curves.md +387 -1608
- package/dist/docs-raw/generated/legacy.md +162 -0
- package/dist/docs-raw/generated/lib.md +227 -85
- package/dist/docs-raw/generated/output.md +38 -73
- package/dist/docs-raw/generated/runtime-names.md +23 -23
- package/dist/docs-raw/generated/sdf.md +68 -284
- package/dist/docs-raw/generated/sheet-metal.md +68 -335
- package/dist/docs-raw/generated/sketch.md +240 -1161
- package/dist/docs-raw/generated/viewport.md +75 -316
- package/dist/docs-raw/generated/wood.md +21 -49
- package/dist/docs-raw/guides/coordinate-system.md +4 -42
- package/dist/docs-raw/guides/inspection-bundles.md +44 -442
- package/dist/docs-raw/guides/joint-design.md +18 -79
- package/dist/docs-raw/guides/positioning.md +21 -143
- package/dist/docs-raw/guides/scene-presentation.md +89 -0
- package/dist/docs-raw/skills/forgecad-3d-reconstruction.md +25 -111
- package/dist/docs-raw/skills/forgecad-blockout-model.md +20 -117
- package/dist/docs-raw/skills/forgecad-component-model.md +23 -107
- package/dist/docs-raw/skills/forgecad-high-level-spec.md +47 -155
- package/dist/docs-raw/skills/forgecad-image-replicator.md +26 -143
- package/dist/docs-raw/skills/forgecad-lld.md +19 -113
- package/dist/docs-raw/skills/forgecad-make-a-model.md +112 -532
- package/dist/docs-raw/skills/forgecad-model-grader.md +38 -108
- package/dist/docs-raw/skills/forgecad-prepare-prompt.md +24 -211
- package/dist/docs-raw/skills/forgecad-project.md +13 -131
- package/dist/docs-raw/skills/forgecad-reconstruction-benchmark.md +42 -134
- package/dist/docs-raw/skills/forgecad-render-inspect.md +27 -174
- package/dist/docs-raw/skills/forgecad-visual-spec.md +32 -112
- package/dist/docs-raw/skills/forgecad.md +19 -18
- package/dist/docs-raw/skills/index.md +2 -0
- package/dist/docs-raw/welcome.md +2 -2
- package/dist/index.html +1 -1
- package/dist/llms.txt +1 -2
- package/dist/sitemap.xml +13 -13
- package/dist-cli/{check-compiler-SYQ2PWOB.js → check-compiler-JTVBITCR.js} +1 -1
- package/dist-cli/{check-query-propagation-HIAGV62W.js → check-query-propagation-3FFLSMVN.js} +1 -1
- package/dist-cli/{chunk-SPZE3DUY.js → chunk-OAN5T4XD.js} +4412 -2212
- package/dist-cli/forgecad.js +507 -179
- package/dist-skill/CONTEXT.md +2172 -8377
- package/dist-skill/SKILL.md +15 -15
- package/dist-skill/docs/API/core/concepts.md +27 -157
- package/dist-skill/docs/CLI.md +63 -241
- package/dist-skill/docs/generated/assembly.md +138 -549
- package/dist-skill/docs/generated/core.md +277 -1251
- package/dist-skill/docs/generated/curves.md +387 -1609
- package/dist-skill/docs/generated/lib.md +227 -85
- package/dist-skill/docs/generated/output.md +38 -73
- package/dist-skill/docs/generated/runtime-names.md +16 -21
- package/dist-skill/docs/generated/sdf.md +68 -284
- package/dist-skill/docs/generated/sheet-metal.md +68 -335
- package/dist-skill/docs/generated/sketch.md +240 -1160
- package/dist-skill/docs/generated/viewport.md +75 -223
- package/dist-skill/docs/generated/wood.md +21 -49
- package/dist-skill/docs/guides/coordinate-system.md +4 -42
- package/dist-skill/docs/guides/inspection-bundles.md +44 -442
- package/dist-skill/docs/guides/joint-design.md +18 -79
- package/dist-skill/docs/guides/positioning.md +21 -143
- package/dist-skill/docs/guides/scene-presentation.md +89 -0
- package/dist-skill/docs/guides/surface-members.md +26 -0
- package/dist-skill/library/forgecad-3d-reconstruction/SKILL.md +23 -111
- package/dist-skill/library/forgecad-blockout-model/SKILL.md +18 -117
- package/dist-skill/library/forgecad-component-model/SKILL.md +21 -107
- package/dist-skill/library/forgecad-high-level-spec/SKILL.md +45 -155
- package/dist-skill/library/forgecad-image-replicator/SKILL.md +24 -143
- package/dist-skill/library/forgecad-lld/SKILL.md +17 -113
- package/dist-skill/library/forgecad-make-a-model/SKILL.md +110 -532
- package/dist-skill/library/forgecad-model-grader/SKILL.md +36 -108
- package/dist-skill/library/forgecad-prepare-prompt/SKILL.md +35 -224
- package/dist-skill/library/forgecad-prepare-prompt/references/default-profiles.md +43 -271
- package/dist-skill/library/forgecad-prepare-prompt/references/master-prompt.md +30 -99
- package/dist-skill/library/forgecad-project/SKILL.md +13 -133
- package/dist-skill/library/forgecad-reconstruction-benchmark/SKILL.md +29 -123
- package/dist-skill/library/forgecad-render-inspect/SKILL.md +25 -174
- package/dist-skill/library/forgecad-visual-spec/SKILL.md +30 -111
- package/dist-skill/website/skills/forgecad-3d-reconstruction.md +58 -0
- package/dist-skill/website/skills/forgecad-blockout-model.md +49 -0
- package/dist-skill/website/skills/forgecad-component-model.md +53 -0
- package/dist-skill/website/skills/forgecad-high-level-spec.md +101 -0
- package/dist-skill/website/skills/forgecad-image-replicator.md +63 -0
- package/dist-skill/website/skills/forgecad-lld.md +41 -0
- package/dist-skill/website/skills/forgecad-make-a-model.md +186 -0
- package/dist-skill/website/skills/forgecad-model-grader.md +82 -0
- package/dist-skill/website/skills/forgecad-prepare-prompt.md +63 -0
- package/dist-skill/website/skills/forgecad-project.md +26 -0
- package/dist-skill/website/skills/forgecad-reconstruction-benchmark.md +60 -0
- package/dist-skill/website/skills/forgecad-render-inspect.md +80 -0
- package/dist-skill/website/skills/forgecad-visual-spec.md +71 -0
- package/dist-skill/website/skills/forgecad.md +122 -0
- package/dist-skill/website/skills/index.md +26 -0
- package/examples/api/comparison-imported-sphere-candidate.forge.js +1 -1
- package/examples/api/conformal-product-ribbon.forge.js +1 -1
- package/examples/api/exact-sheet-shell-assembly.forge.js +1 -1
- package/examples/api/extrude-options.forge.js +4 -2
- package/examples/api/field-loft-drive-tip.forge.js +40 -0
- package/examples/api/guided-loft-olive-oil-bottle.forge.js +1 -1
- package/examples/api/highlight-debug.forge.js +10 -10
- package/examples/api/mesh-import-slats.forge.js +1 -1
- package/examples/api/real-product-curves.forge.js +1 -1
- package/examples/api/sculpt-box-circle-booleans.forge.js +1 -1
- package/examples/api/sdf-shapes.forge.js +2 -5
- package/examples/api/sketch-rounding-strategies.forge.js +6 -6
- package/examples/api/surface-member-bottle-cage.forge.js +3 -3
- package/examples/api/surface-member-conformal-product-ribbon.forge.js +3 -3
- package/examples/api/surface-member-razor-inlay.forge.js +1 -1
- package/examples/api/variable-sweep-test.forge.js +3 -3
- package/examples/mechanical/airplane-propeller.forge.js +74 -39
- package/examples/nurbs-surface.forge.js +1 -1
- package/examples/products/iphone.forge.js +1 -1
- package/package.json +1 -1
- package/dist/assets/EditorApp-BHMQlJ-D.js +0 -14686
- package/dist/docs-raw/guides/geometry-conventions.md +0 -52
- package/dist/docs-raw/guides/modeling-recipes.md +0 -78
- package/dist-skill/docs/guides/geometry-conventions.md +0 -52
- package/dist-skill/docs/guides/modeling-recipes.md +0 -78
- package/dist-skill/library/forgecad-visual-spec/references/prompt-template.md +0 -79
|
@@ -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
|
|
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-o90NSNmF.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];
|
|
@@ -296,6 +296,8 @@ function lookupCache(filePath, code, files, paramOverrides, assemblyState, quali
|
|
|
296
296
|
if (!entry) return null;
|
|
297
297
|
if (entry.code !== code || entry.quality !== quality || JSON.stringify(entry.paramOverrides) !== JSON.stringify(paramOverrides) || JSON.stringify(entry.assemblyState) !== JSON.stringify(assemblyState) || JSON.stringify(entry.files) !== JSON.stringify(files))
|
|
298
298
|
return null;
|
|
299
|
+
runResultCache.delete(key);
|
|
300
|
+
runResultCache.set(key, entry);
|
|
299
301
|
return entry.result;
|
|
300
302
|
}
|
|
301
303
|
function storeCache(filePath, code, files, paramOverrides, assemblyState, quality, backend, result, serialized) {
|
|
@@ -15583,7 +15585,7 @@ const movePath = (value, from, to) => {
|
|
|
15583
15585
|
if (value.startsWith(`${from}/`)) return `${to}${value.slice(from.length)}`;
|
|
15584
15586
|
return value;
|
|
15585
15587
|
};
|
|
15586
|
-
const FORGE_IMPORT_RE = /\b(?:importMesh|importStep|importSvgSketch|Import\.dxfSketch|compareWith)\s*\(\s*(?:"([^"]+)"|'([^']+)')/g;
|
|
15588
|
+
const FORGE_IMPORT_RE = /\b(?:importMesh|importStep|importSvgSketch|Import\.mesh|Import\.step|Import\.svgSketch|Import\.dxfSketch|compareWith)\s*\(\s*(?:"([^"]+)"|'([^']+)')/g;
|
|
15587
15589
|
const REQUIRE_RE = /\brequire\s*\(\s*(?:"([^"]+)"|'([^']+)')/g;
|
|
15588
15590
|
const ES_IMPORT_RE = /\bfrom\s+(?:"([^"]+)"|'([^']+)')/g;
|
|
15589
15591
|
const VIRTUAL_MODULES = /* @__PURE__ */ new Set(["forgecad", "@forge/runtime", "@forgecad/runtime"]);
|
|
@@ -15601,6 +15603,9 @@ function extractImports(code) {
|
|
|
15601
15603
|
importMesh: "forgeMesh",
|
|
15602
15604
|
importStep: "forgeMesh",
|
|
15603
15605
|
importSvgSketch: "forgeSvg",
|
|
15606
|
+
"Import.mesh": "forgeMesh",
|
|
15607
|
+
"Import.step": "forgeMesh",
|
|
15608
|
+
"Import.svgSketch": "forgeSvg",
|
|
15604
15609
|
"Import.dxfSketch": "forgeDxf",
|
|
15605
15610
|
compareWith: "compareWith"
|
|
15606
15611
|
};
|
|
@@ -15608,7 +15613,9 @@ function extractImports(code) {
|
|
|
15608
15613
|
const forgeRe = new RegExp(FORGE_IMPORT_RE.source, FORGE_IMPORT_RE.flags);
|
|
15609
15614
|
while ((m2 = forgeRe.exec(code)) !== null) {
|
|
15610
15615
|
const path = m2[1] ?? m2[2];
|
|
15611
|
-
const fn = (_a3 = m2[0].match(
|
|
15616
|
+
const fn = (_a3 = m2[0].match(
|
|
15617
|
+
/\b(importMesh|importStep|importSvgSketch|Import\.mesh|Import\.step|Import\.svgSketch|Import\.dxfSketch|compareWith)/
|
|
15618
|
+
)) == null ? void 0 : _a3[1];
|
|
15612
15619
|
add(path, kindMap[fn] ?? "forgeMesh");
|
|
15613
15620
|
}
|
|
15614
15621
|
const reqRe = new RegExp(REQUIRE_RE.source, REQUIRE_RE.flags);
|
|
@@ -15834,7 +15841,7 @@ const CRASH_COOLDOWN_MS = 2e3;
|
|
|
15834
15841
|
class EvalWorkerClient {
|
|
15835
15842
|
constructor(workerFactory = () => new Worker(new URL(
|
|
15836
15843
|
/* @vite-ignore */
|
|
15837
|
-
"/assets/evalWorker-
|
|
15844
|
+
"/assets/evalWorker-DbNs7Dkp.js",
|
|
15838
15845
|
import.meta.url
|
|
15839
15846
|
), { type: "module" })) {
|
|
15840
15847
|
__publicField(this, "worker", null);
|
|
@@ -16079,6 +16086,10 @@ class EvalWorkerClient {
|
|
|
16079
16086
|
runIrPlan(options) {
|
|
16080
16087
|
return this.startCancellableRun(options, "run-ir-plan");
|
|
16081
16088
|
}
|
|
16089
|
+
clearCaches() {
|
|
16090
|
+
var _a3;
|
|
16091
|
+
(_a3 = this.worker) == null ? void 0 : _a3.postMessage({ type: "clear-caches" });
|
|
16092
|
+
}
|
|
16082
16093
|
startCancellableRun(options, type) {
|
|
16083
16094
|
if (this.shouldReplaceWorkerForSupersedingRun()) {
|
|
16084
16095
|
this.replaceWorkerForSupersedingRun();
|
|
@@ -16271,7 +16282,89 @@ const removeParamSnapshotsForFile = (snapshotsByFile, file) => {
|
|
|
16271
16282
|
delete next[file];
|
|
16272
16283
|
return next;
|
|
16273
16284
|
};
|
|
16274
|
-
const
|
|
16285
|
+
const EDITABLE_PROJECT_TEXT_FILE_EXTS = [
|
|
16286
|
+
".forge.js",
|
|
16287
|
+
".sketch.js",
|
|
16288
|
+
".js",
|
|
16289
|
+
".mjs",
|
|
16290
|
+
".cjs",
|
|
16291
|
+
".jsx",
|
|
16292
|
+
".ts",
|
|
16293
|
+
".tsx",
|
|
16294
|
+
".json",
|
|
16295
|
+
".md",
|
|
16296
|
+
".txt",
|
|
16297
|
+
".svg",
|
|
16298
|
+
".dxf",
|
|
16299
|
+
".html",
|
|
16300
|
+
".css",
|
|
16301
|
+
".scss",
|
|
16302
|
+
".yml",
|
|
16303
|
+
".yaml",
|
|
16304
|
+
".toml",
|
|
16305
|
+
".xml",
|
|
16306
|
+
".csv",
|
|
16307
|
+
".ini"
|
|
16308
|
+
];
|
|
16309
|
+
function hasProjectTextFileExtension(path) {
|
|
16310
|
+
const lower = path.toLowerCase();
|
|
16311
|
+
return EDITABLE_PROJECT_TEXT_FILE_EXTS.some((ext) => lower.endsWith(ext));
|
|
16312
|
+
}
|
|
16313
|
+
function projectTextFileTemplate(path) {
|
|
16314
|
+
const lower = path.toLowerCase();
|
|
16315
|
+
if (lower.endsWith(".svg")) {
|
|
16316
|
+
return `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
|
|
16317
|
+
<path d="M 10 10 L 90 10 L 90 90 L 10 90 Z" fill="none" stroke="#000" stroke-width="4" />
|
|
16318
|
+
</svg>
|
|
16319
|
+
`;
|
|
16320
|
+
}
|
|
16321
|
+
if (lower.endsWith(".dxf")) {
|
|
16322
|
+
return "0\nSECTION\n2\nENTITIES\n0\nLWPOLYLINE\n8\n0\n90\n4\n70\n1\n10\n0\n20\n0\n10\n100\n20\n0\n10\n100\n20\n60\n10\n0\n20\n60\n0\nENDSEC\n0\nEOF\n";
|
|
16323
|
+
}
|
|
16324
|
+
if (lower.endsWith(".forge.js") || lower.endsWith(".sketch.js")) {
|
|
16325
|
+
return "// 3D Part\n\nreturn box(50, 30, 10);\n";
|
|
16326
|
+
}
|
|
16327
|
+
if (lower.endsWith(".js") || lower.endsWith(".mjs") || lower.endsWith(".cjs")) {
|
|
16328
|
+
return "// Shared JS utilities for ForgeCAD.\n\nexport function exampleValue() {\n return 42;\n}\n";
|
|
16329
|
+
}
|
|
16330
|
+
if (lower.endsWith(".md")) return "# Notes\n\n";
|
|
16331
|
+
if (lower.endsWith(".json")) return "{\n \n}\n";
|
|
16332
|
+
return "";
|
|
16333
|
+
}
|
|
16334
|
+
function monacoLanguageForProjectFile(path) {
|
|
16335
|
+
const lower = path.toLowerCase();
|
|
16336
|
+
if (lower.endsWith(".md")) return "markdown";
|
|
16337
|
+
if (lower.endsWith(".json")) return "json";
|
|
16338
|
+
if (lower.endsWith(".ts") || lower.endsWith(".tsx")) return "typescript";
|
|
16339
|
+
if (lower.endsWith(".js") || lower.endsWith(".mjs") || lower.endsWith(".cjs") || lower.endsWith(".jsx")) return "javascript";
|
|
16340
|
+
if (lower.endsWith(".html")) return "html";
|
|
16341
|
+
if (lower.endsWith(".css") || lower.endsWith(".scss")) return "css";
|
|
16342
|
+
if (lower.endsWith(".svg") || lower.endsWith(".xml")) return "xml";
|
|
16343
|
+
if (lower.endsWith(".yml") || lower.endsWith(".yaml")) return "yaml";
|
|
16344
|
+
return "plaintext";
|
|
16345
|
+
}
|
|
16346
|
+
function highlightLanguageForProjectFile(path) {
|
|
16347
|
+
const lower = path.toLowerCase();
|
|
16348
|
+
if (lower.endsWith(".md")) return "markdown";
|
|
16349
|
+
if (lower.endsWith(".json")) return "json";
|
|
16350
|
+
if (lower.endsWith(".ts") || lower.endsWith(".tsx")) return "typescript";
|
|
16351
|
+
if (lower.endsWith(".js") || lower.endsWith(".mjs") || lower.endsWith(".cjs") || lower.endsWith(".jsx")) return "javascript";
|
|
16352
|
+
if (lower.endsWith(".html") || lower.endsWith(".svg") || lower.endsWith(".xml")) return "xml";
|
|
16353
|
+
if (lower.endsWith(".css") || lower.endsWith(".scss")) return "css";
|
|
16354
|
+
return null;
|
|
16355
|
+
}
|
|
16356
|
+
function projectTextFileMimeType(path) {
|
|
16357
|
+
const lower = path.toLowerCase();
|
|
16358
|
+
if (lower.endsWith(".svg")) return "image/svg+xml";
|
|
16359
|
+
if (lower.endsWith(".dxf")) return "application/dxf";
|
|
16360
|
+
if (lower.endsWith(".json")) return "application/json";
|
|
16361
|
+
if (lower.endsWith(".md")) return "text/markdown";
|
|
16362
|
+
if (lower.endsWith(".html")) return "text/html";
|
|
16363
|
+
if (lower.endsWith(".css") || lower.endsWith(".scss")) return "text/css";
|
|
16364
|
+
if (lower.endsWith(".js") || lower.endsWith(".mjs") || lower.endsWith(".cjs") || lower.endsWith(".jsx")) return "text/javascript";
|
|
16365
|
+
return "text/plain";
|
|
16366
|
+
}
|
|
16367
|
+
const IMPORTABLE_PROJECT_TEXT_FILE_EXTS = EDITABLE_PROJECT_TEXT_FILE_EXTS;
|
|
16275
16368
|
const IMPORTABLE_PROJECT_MESH_FILE_EXTS = [".stl", ".obj", ".3mf"];
|
|
16276
16369
|
const IMPORTABLE_PROJECT_EXACT_FILE_EXTS = [".step", ".stp"];
|
|
16277
16370
|
const IMPORTABLE_PROJECT_BINARY_FILE_EXTS = [...IMPORTABLE_PROJECT_MESH_FILE_EXTS, ...IMPORTABLE_PROJECT_EXACT_FILE_EXTS];
|
|
@@ -16282,7 +16375,7 @@ function hasImportableExt(path, extensions) {
|
|
|
16282
16375
|
return extensions.some((ext) => lower.endsWith(ext));
|
|
16283
16376
|
}
|
|
16284
16377
|
function isImportableProjectTextFile(path) {
|
|
16285
|
-
return
|
|
16378
|
+
return hasProjectTextFileExtension(path);
|
|
16286
16379
|
}
|
|
16287
16380
|
function isImportableProjectMeshFile(path) {
|
|
16288
16381
|
return hasImportableExt(path, IMPORTABLE_PROJECT_MESH_FILE_EXTS);
|
|
@@ -16985,7 +17078,9 @@ if (sharedBundle) {
|
|
|
16985
17078
|
}
|
|
16986
17079
|
}
|
|
16987
17080
|
const LAST_ACTIVE_FILE_KEY_BASE = "fc-last-active-file";
|
|
17081
|
+
const RECENT_FILES_KEY_BASE = "fc-recent-files";
|
|
16988
17082
|
const lastActiveFileKey = () => userScopedKey(LAST_ACTIVE_FILE_KEY_BASE);
|
|
17083
|
+
const recentFilesKey = () => userScopedKey(RECENT_FILES_KEY_BASE);
|
|
16989
17084
|
const readLastActiveFileForUser = (userId) => {
|
|
16990
17085
|
try {
|
|
16991
17086
|
return localStorage.getItem(`${LAST_ACTIVE_FILE_KEY_BASE}-${userId}`);
|
|
@@ -16993,6 +17088,25 @@ const readLastActiveFileForUser = (userId) => {
|
|
|
16993
17088
|
return null;
|
|
16994
17089
|
}
|
|
16995
17090
|
};
|
|
17091
|
+
const readRecentFiles = () => {
|
|
17092
|
+
try {
|
|
17093
|
+
if (typeof localStorage === "undefined") return [];
|
|
17094
|
+
const raw = localStorage.getItem(recentFilesKey());
|
|
17095
|
+
if (!raw) return [];
|
|
17096
|
+
const parsed = JSON.parse(raw);
|
|
17097
|
+
if (!Array.isArray(parsed)) return [];
|
|
17098
|
+
return parsed.filter((value) => typeof value === "string" && value.length > 0);
|
|
17099
|
+
} catch {
|
|
17100
|
+
return [];
|
|
17101
|
+
}
|
|
17102
|
+
};
|
|
17103
|
+
const writeRecentFiles = (files) => {
|
|
17104
|
+
try {
|
|
17105
|
+
if (typeof localStorage === "undefined") return;
|
|
17106
|
+
localStorage.setItem(recentFilesKey(), JSON.stringify(files));
|
|
17107
|
+
} catch {
|
|
17108
|
+
}
|
|
17109
|
+
};
|
|
16996
17110
|
const clampJointValue = (value, min, max2) => {
|
|
16997
17111
|
let next = Number.isFinite(value) ? value : 0;
|
|
16998
17112
|
if (min !== void 0) next = Math.max(min, next);
|
|
@@ -17256,18 +17370,8 @@ const resolveThicknessColorRange = (value) => {
|
|
|
17256
17370
|
return DEFAULT_THICKNESS_COLOR_RANGE;
|
|
17257
17371
|
}
|
|
17258
17372
|
const raw = value;
|
|
17259
|
-
const min = resolveClampedNumber(
|
|
17260
|
-
|
|
17261
|
-
DEFAULT_THICKNESS_COLOR_RANGE.min,
|
|
17262
|
-
THICKNESS_COLOR_RANGE_MIN,
|
|
17263
|
-
THICKNESS_COLOR_RANGE_MAX
|
|
17264
|
-
);
|
|
17265
|
-
const max2 = resolveClampedNumber(
|
|
17266
|
-
raw.max,
|
|
17267
|
-
DEFAULT_THICKNESS_COLOR_RANGE.max,
|
|
17268
|
-
THICKNESS_COLOR_RANGE_MIN,
|
|
17269
|
-
THICKNESS_COLOR_RANGE_MAX
|
|
17270
|
-
);
|
|
17373
|
+
const min = resolveClampedNumber(raw.min, DEFAULT_THICKNESS_COLOR_RANGE.min, THICKNESS_COLOR_RANGE_MIN, THICKNESS_COLOR_RANGE_MAX);
|
|
17374
|
+
const max2 = resolveClampedNumber(raw.max, DEFAULT_THICKNESS_COLOR_RANGE.max, THICKNESS_COLOR_RANGE_MIN, THICKNESS_COLOR_RANGE_MAX);
|
|
17271
17375
|
if (max2 - min >= THICKNESS_COLOR_RANGE_MIN_SPAN) return { min, max: max2 };
|
|
17272
17376
|
const defaultSpan = DEFAULT_THICKNESS_COLOR_RANGE.max - DEFAULT_THICKNESS_COLOR_RANGE.min;
|
|
17273
17377
|
const expandedMax = Math.min(THICKNESS_COLOR_RANGE_MAX, min + defaultSpan);
|
|
@@ -17422,6 +17526,47 @@ const initialActive = (() => {
|
|
|
17422
17526
|
return fallback;
|
|
17423
17527
|
})();
|
|
17424
17528
|
const INITIAL_SAVED = {};
|
|
17529
|
+
const MAX_RECENT_FILES = 200;
|
|
17530
|
+
function touchRecentFile(recentFiles, files, file) {
|
|
17531
|
+
const availableFiles = new Set(Object.keys(files));
|
|
17532
|
+
const next = [];
|
|
17533
|
+
const seen = /* @__PURE__ */ new Set();
|
|
17534
|
+
if (file && availableFiles.has(file)) {
|
|
17535
|
+
next.push(file);
|
|
17536
|
+
seen.add(file);
|
|
17537
|
+
}
|
|
17538
|
+
for (const recentFile of recentFiles) {
|
|
17539
|
+
if (!availableFiles.has(recentFile) || seen.has(recentFile)) continue;
|
|
17540
|
+
next.push(recentFile);
|
|
17541
|
+
seen.add(recentFile);
|
|
17542
|
+
if (next.length >= MAX_RECENT_FILES) break;
|
|
17543
|
+
}
|
|
17544
|
+
return next;
|
|
17545
|
+
}
|
|
17546
|
+
function pruneRecentFiles(recentFiles, files) {
|
|
17547
|
+
return touchRecentFile(recentFiles, files, "");
|
|
17548
|
+
}
|
|
17549
|
+
function remapRecentFiles(recentFiles, files, oldPath, newPath) {
|
|
17550
|
+
const remapped = recentFiles.map((file) => movePath(file, oldPath, newPath));
|
|
17551
|
+
return pruneRecentFiles(remapped, files);
|
|
17552
|
+
}
|
|
17553
|
+
function persistRecentFiles(recentFiles) {
|
|
17554
|
+
writeRecentFiles(recentFiles);
|
|
17555
|
+
return recentFiles;
|
|
17556
|
+
}
|
|
17557
|
+
function touchAndPersistRecentFile(recentFiles, files, file) {
|
|
17558
|
+
return persistRecentFiles(touchRecentFile(recentFiles, files, file));
|
|
17559
|
+
}
|
|
17560
|
+
function pruneAndPersistRecentFiles(recentFiles, files) {
|
|
17561
|
+
return persistRecentFiles(pruneRecentFiles(recentFiles, files));
|
|
17562
|
+
}
|
|
17563
|
+
function remapAndPersistRecentFiles(recentFiles, files, oldPath, newPath) {
|
|
17564
|
+
return persistRecentFiles(remapRecentFiles(recentFiles, files, oldPath, newPath));
|
|
17565
|
+
}
|
|
17566
|
+
function readRecentFilesOrFallback(fallback) {
|
|
17567
|
+
const stored = readRecentFiles();
|
|
17568
|
+
return stored.length > 0 ? stored : fallback;
|
|
17569
|
+
}
|
|
17425
17570
|
const VIEW_INSPECT_CHANNELS = /* @__PURE__ */ new Set([
|
|
17426
17571
|
"none",
|
|
17427
17572
|
"mask",
|
|
@@ -17437,6 +17582,9 @@ const VIEW_INSPECT_CHANNELS = /* @__PURE__ */ new Set([
|
|
|
17437
17582
|
"roughness"
|
|
17438
17583
|
]);
|
|
17439
17584
|
const INSPECT_DISPLAY_MODES = /* @__PURE__ */ new Set(["heatmap", "points", "both", "scan"]);
|
|
17585
|
+
const SAVE_PICKER_TEXT_FILE_EXTS = EDITABLE_PROJECT_TEXT_FILE_EXTS.filter(
|
|
17586
|
+
(ext) => ![".forge.js", ".sketch.js", ".js", ".svg", ".dxf", ".md"].includes(ext)
|
|
17587
|
+
);
|
|
17440
17588
|
function resolveViewInspectChannel(value) {
|
|
17441
17589
|
return typeof value === "string" && VIEW_INSPECT_CHANNELS.has(value) ? value : "none";
|
|
17442
17590
|
}
|
|
@@ -17547,6 +17695,10 @@ function abortServerCompute() {
|
|
|
17547
17695
|
function canUseServerCompute() {
|
|
17548
17696
|
return true;
|
|
17549
17697
|
}
|
|
17698
|
+
function canHaveProjectImports(filename) {
|
|
17699
|
+
const lower = filename.toLowerCase();
|
|
17700
|
+
return lower.endsWith(".forge.js") || lower.endsWith(".sketch.js") || lower.endsWith(".js") || lower.endsWith(".mjs") || lower.endsWith(".cjs") || lower.endsWith(".jsx") || lower.endsWith(".ts") || lower.endsWith(".tsx");
|
|
17701
|
+
}
|
|
17550
17702
|
const PARAM_DEBOUNCE_MS = navigator.maxTouchPoints > 0 && window.innerWidth < 768 ? 250 : 80;
|
|
17551
17703
|
async function lazyLoadFileAndDeps(filename, get, set) {
|
|
17552
17704
|
if (!fileSystem.fetchFileContent) return;
|
|
@@ -17569,6 +17721,7 @@ async function lazyLoadFileAndDeps(filename, get, set) {
|
|
|
17569
17721
|
}
|
|
17570
17722
|
}
|
|
17571
17723
|
if (!content) continue;
|
|
17724
|
+
if (!canHaveProjectImports(file)) continue;
|
|
17572
17725
|
for (const ref of extractImports(content)) {
|
|
17573
17726
|
const resolved = resolveImportPath(file, ref.raw);
|
|
17574
17727
|
const matchKey = Object.keys(storeFiles).find((k2) => k2 === resolved || k2.replace(/^\.\//, "") === resolved.replace(/^\.\//, ""));
|
|
@@ -17622,6 +17775,7 @@ const useForgeStore = create((set, get) => ({
|
|
|
17622
17775
|
savedFiles: { ...INITIAL_SAVED },
|
|
17623
17776
|
folders: [...INITIAL_FOLDERS],
|
|
17624
17777
|
activeFile: initialActive,
|
|
17778
|
+
recentFiles: touchRecentFile(readRecentFiles(), INITIAL_FILES, initialActive),
|
|
17625
17779
|
setActiveFile: (name) => {
|
|
17626
17780
|
abortServerCompute();
|
|
17627
17781
|
if (name) {
|
|
@@ -17645,6 +17799,7 @@ const useForgeStore = create((set, get) => ({
|
|
|
17645
17799
|
const restored = targetPreviewFile && nextByFile[targetPreviewFile] ? nextByFile[targetPreviewFile] : {};
|
|
17646
17800
|
set({
|
|
17647
17801
|
activeFile: name,
|
|
17802
|
+
recentFiles: touchAndPersistRecentFile(get().recentFiles, files, name),
|
|
17648
17803
|
meshPreviewFile: null,
|
|
17649
17804
|
// Clear mesh preview when switching files
|
|
17650
17805
|
lastValidResult: null,
|
|
@@ -17693,15 +17848,13 @@ const useForgeStore = create((set, get) => ({
|
|
|
17693
17848
|
if (!normalized) return;
|
|
17694
17849
|
if (get().files[normalized] !== void 0) return;
|
|
17695
17850
|
if (get().folders.includes(normalized)) return;
|
|
17696
|
-
const template = normalized
|
|
17697
|
-
<path d="M 10 10 L 90 10 L 90 90 L 10 90 Z" fill="none" stroke="#000" stroke-width="4" />
|
|
17698
|
-
</svg>
|
|
17699
|
-
` : normalized.endsWith(".dxf") ? "0\nSECTION\n2\nENTITIES\n0\nLWPOLYLINE\n8\n0\n90\n4\n70\n1\n10\n0\n20\n0\n10\n100\n20\n0\n10\n100\n20\n60\n10\n0\n20\n60\n0\nENDSEC\n0\nEOF\n" : normalized.endsWith(".forge.js") ? "// 3D Part\n\nreturn box(50, 30, 10);\n" : "// Shared JS utilities for ForgeCAD.\n\nexport function exampleValue() {\n return 42;\n}\n";
|
|
17851
|
+
const template = projectTextFileTemplate(normalized);
|
|
17700
17852
|
const newFolders = Array.from(/* @__PURE__ */ new Set([...get().folders, ...collectParentPaths(normalized)])).sort();
|
|
17701
17853
|
set((s) => ({
|
|
17702
17854
|
files: { ...s.files, [normalized]: template },
|
|
17703
17855
|
savedFiles: { ...s.savedFiles, [normalized]: template },
|
|
17704
17856
|
activeFile: normalized,
|
|
17857
|
+
recentFiles: touchAndPersistRecentFile(s.recentFiles, { ...s.files, [normalized]: template }, normalized),
|
|
17705
17858
|
paramOverrides: {},
|
|
17706
17859
|
jointValues: {},
|
|
17707
17860
|
jointAnimationClip: null,
|
|
@@ -17739,6 +17892,7 @@ const useForgeStore = create((set, get) => ({
|
|
|
17739
17892
|
files: remaining,
|
|
17740
17893
|
savedFiles: remainingSaved,
|
|
17741
17894
|
activeFile: newActive,
|
|
17895
|
+
recentFiles: touchAndPersistRecentFile(get().recentFiles, remaining, newActive),
|
|
17742
17896
|
objectSettingsByFile: nextObjectSettingsByFile,
|
|
17743
17897
|
paramSnapshotsByFile: nextParamSnapshotsByFile,
|
|
17744
17898
|
paramOverrides: {},
|
|
@@ -17772,6 +17926,7 @@ const useForgeStore = create((set, get) => ({
|
|
|
17772
17926
|
files: remaining,
|
|
17773
17927
|
savedFiles: remainingSaved,
|
|
17774
17928
|
activeFile: oldName === activeFile ? normalized : activeFile,
|
|
17929
|
+
recentFiles: remapAndPersistRecentFiles(get().recentFiles, remaining, oldName, normalized),
|
|
17775
17930
|
objectSettingsByFile: nextObjectSettingsByFile,
|
|
17776
17931
|
paramSnapshotsByFile: nextParamSnapshotsByFile,
|
|
17777
17932
|
folders: Array.from(/* @__PURE__ */ new Set([...get().folders, ...collectParentPaths(normalized)])).sort()
|
|
@@ -17828,6 +17983,7 @@ const useForgeStore = create((set, get) => ({
|
|
|
17828
17983
|
savedFiles: updatedSaved,
|
|
17829
17984
|
folders: updatedFolders,
|
|
17830
17985
|
activeFile: nextActive,
|
|
17986
|
+
recentFiles: remapAndPersistRecentFiles(get().recentFiles, updatedFiles, normalizedOld, normalizedNew),
|
|
17831
17987
|
objectSettingsByFile: nextObjectSettingsByFile,
|
|
17832
17988
|
paramSnapshotsByFile: nextParamSnapshotsByFile,
|
|
17833
17989
|
paramOverrides: {},
|
|
@@ -17850,22 +18006,29 @@ const useForgeStore = create((set, get) => ({
|
|
|
17850
18006
|
const prefix = `${normalized}/`;
|
|
17851
18007
|
const remainingFiles = {};
|
|
17852
18008
|
const remainingSaved = {};
|
|
17853
|
-
const deletedFiles =
|
|
18009
|
+
const deletedFiles = /* @__PURE__ */ new Set();
|
|
17854
18010
|
for (const key of Object.keys(files)) {
|
|
17855
18011
|
if (key.startsWith(prefix)) {
|
|
17856
|
-
deletedFiles.
|
|
18012
|
+
deletedFiles.add(key);
|
|
17857
18013
|
} else {
|
|
17858
18014
|
remainingFiles[key] = files[key];
|
|
17859
18015
|
}
|
|
17860
18016
|
}
|
|
17861
18017
|
for (const key of Object.keys(savedFiles)) {
|
|
17862
|
-
if (
|
|
18018
|
+
if (key.startsWith(prefix)) {
|
|
18019
|
+
deletedFiles.add(key);
|
|
18020
|
+
} else {
|
|
17863
18021
|
remainingSaved[key] = savedFiles[key];
|
|
17864
18022
|
}
|
|
17865
18023
|
}
|
|
17866
|
-
|
|
18024
|
+
const replacementFile = Object.keys(remainingFiles).length === 0 ? "main.forge.js" : null;
|
|
18025
|
+
if (replacementFile) {
|
|
18026
|
+
const template = projectTextFileTemplate(replacementFile);
|
|
18027
|
+
remainingFiles[replacementFile] = template;
|
|
18028
|
+
remainingSaved[replacementFile] = template;
|
|
18029
|
+
}
|
|
17867
18030
|
const remainingFolders = folders.filter((f2) => f2 !== normalized && !f2.startsWith(prefix));
|
|
17868
|
-
const newActive = (activeFile == null ? void 0 : activeFile.startsWith(prefix)) ? Object.keys(remainingFiles)[0] : activeFile;
|
|
18031
|
+
const newActive = (activeFile == null ? void 0 : activeFile.startsWith(prefix)) || !activeFile ? Object.keys(remainingFiles)[0] : activeFile;
|
|
17869
18032
|
let nextObjectSettingsByFile = objectSettingsByFile;
|
|
17870
18033
|
let nextParamSnapshotsByFile = paramSnapshotsByFile;
|
|
17871
18034
|
for (const f2 of deletedFiles) {
|
|
@@ -17878,6 +18041,7 @@ const useForgeStore = create((set, get) => ({
|
|
|
17878
18041
|
savedFiles: remainingSaved,
|
|
17879
18042
|
folders: remainingFolders,
|
|
17880
18043
|
activeFile: newActive,
|
|
18044
|
+
recentFiles: touchAndPersistRecentFile(get().recentFiles, remainingFiles, newActive),
|
|
17881
18045
|
objectSettingsByFile: nextObjectSettingsByFile,
|
|
17882
18046
|
paramSnapshotsByFile: nextParamSnapshotsByFile,
|
|
17883
18047
|
paramOverrides: {},
|
|
@@ -17887,7 +18051,7 @@ const useForgeStore = create((set, get) => ({
|
|
|
17887
18051
|
jointAnimationPlaying: false,
|
|
17888
18052
|
hoveredJointName: null
|
|
17889
18053
|
});
|
|
17890
|
-
Promise.all(deletedFiles.map((f2) => fileSystem.delete(f2))).then(() => fileSystem.deleteFolder(normalized)).catch((e2) => console.error("Delete folder failed:", e2));
|
|
18054
|
+
Promise.all(Array.from(deletedFiles).map((f2) => fileSystem.delete(f2))).then(() => replacementFile ? fileSystem.save(replacementFile, remainingFiles[replacementFile]) : void 0).then(() => fileSystem.deleteFolder(normalized)).catch((e2) => console.error("Delete folder failed:", e2));
|
|
17891
18055
|
setTimeout(() => get().execute(), 0);
|
|
17892
18056
|
},
|
|
17893
18057
|
moveEntry: (oldPath, newPath) => {
|
|
@@ -18053,7 +18217,8 @@ const useForgeStore = create((set, get) => ({
|
|
|
18053
18217
|
assemblyState,
|
|
18054
18218
|
...useServer ? {} : { assemblyDisplayMode: "instanceTransforms" },
|
|
18055
18219
|
isNotebook: false,
|
|
18056
|
-
activeBackend: executionBackend
|
|
18220
|
+
activeBackend: executionBackend,
|
|
18221
|
+
disableShapeBuildCache: get().disableRunCache
|
|
18057
18222
|
};
|
|
18058
18223
|
let serialized;
|
|
18059
18224
|
if (useServer) {
|
|
@@ -19037,6 +19202,7 @@ const useForgeStore = create((set, get) => ({
|
|
|
19037
19202
|
savedFiles: { ...INITIAL_SAVED },
|
|
19038
19203
|
folders: [],
|
|
19039
19204
|
activeFile: initialActive,
|
|
19205
|
+
recentFiles: touchAndPersistRecentFile([], INITIAL_FILES, initialActive),
|
|
19040
19206
|
previewFile: initialPreviewFile,
|
|
19041
19207
|
objectSettings: getObjectSettingsForPreviewFile(initialObjectSettingsByFile, initialPreviewFile),
|
|
19042
19208
|
objectSettingsByFile: initialObjectSettingsByFile,
|
|
@@ -19077,7 +19243,9 @@ const useForgeStore = create((set, get) => ({
|
|
|
19077
19243
|
const handle = await window.showSaveFilePicker({
|
|
19078
19244
|
suggestedName: activeFile,
|
|
19079
19245
|
types: [
|
|
19080
|
-
{ description: "ForgeCAD scripts", accept: { "text/javascript": [".forge.js", ".js"] } },
|
|
19246
|
+
{ description: "ForgeCAD scripts", accept: { "text/javascript": [".forge.js", ".sketch.js", ".js"] } },
|
|
19247
|
+
{ description: "Text files", accept: { "text/plain": SAVE_PICKER_TEXT_FILE_EXTS } },
|
|
19248
|
+
{ description: "Markdown", accept: { "text/markdown": [".md"] } },
|
|
19081
19249
|
{ description: "SVG", accept: { "image/svg+xml": [".svg"] } },
|
|
19082
19250
|
{ description: "DXF", accept: { "application/dxf": [".dxf"] } }
|
|
19083
19251
|
]
|
|
@@ -19092,7 +19260,7 @@ const useForgeStore = create((set, get) => ({
|
|
|
19092
19260
|
// This assumes we are satisfied with current content being "saved"
|
|
19093
19261
|
}));
|
|
19094
19262
|
} else {
|
|
19095
|
-
const mime =
|
|
19263
|
+
const mime = projectTextFileMimeType(activeFile);
|
|
19096
19264
|
const blob = new Blob([code], { type: mime });
|
|
19097
19265
|
triggerDownload(blob, activeFile);
|
|
19098
19266
|
set((s) => ({
|
|
@@ -19111,6 +19279,7 @@ const useForgeStore = create((set, get) => ({
|
|
|
19111
19279
|
files: { ...s.files, [normalized]: text },
|
|
19112
19280
|
savedFiles: { ...s.savedFiles, [normalized]: text },
|
|
19113
19281
|
activeFile: normalized,
|
|
19282
|
+
recentFiles: touchAndPersistRecentFile(s.recentFiles, { ...s.files, [normalized]: text }, normalized),
|
|
19114
19283
|
fileHandle: null,
|
|
19115
19284
|
dirty: false,
|
|
19116
19285
|
previewFile: null,
|
|
@@ -19169,6 +19338,7 @@ const useForgeStore = create((set, get) => ({
|
|
|
19169
19338
|
return {
|
|
19170
19339
|
files: nextFiles,
|
|
19171
19340
|
activeFile: nextActive,
|
|
19341
|
+
recentFiles: touchAndPersistRecentFile(s.recentFiles, nextFiles, nextActive),
|
|
19172
19342
|
fileHandle: null,
|
|
19173
19343
|
dirty: true,
|
|
19174
19344
|
previewFile: null,
|
|
@@ -19247,9 +19417,15 @@ const useForgeStore = create((set, get) => ({
|
|
|
19247
19417
|
const prevFiles = state2.files;
|
|
19248
19418
|
const prevActiveFile = state2.activeFile;
|
|
19249
19419
|
const nextState = computeServerSnapshot(state2, serverFiles, serverFolders, sharedModel, sharedBundle, initialFile);
|
|
19250
|
-
set({ ...nextState, filesLoading: false });
|
|
19251
19420
|
const nextFiles = nextState.files;
|
|
19252
|
-
const newActiveFile = nextState.activeFile;
|
|
19421
|
+
const newActiveFile = nextState.activeFile ?? state2.activeFile;
|
|
19422
|
+
const baseRecentFiles = readRecentFilesOrFallback(state2.recentFiles);
|
|
19423
|
+
set({
|
|
19424
|
+
...nextState,
|
|
19425
|
+
activeFile: newActiveFile,
|
|
19426
|
+
recentFiles: touchAndPersistRecentFile(baseRecentFiles, nextFiles, newActiveFile),
|
|
19427
|
+
filesLoading: false
|
|
19428
|
+
});
|
|
19253
19429
|
const needsLazyLoad = newActiveFile && newActiveFile in nextFiles && nextFiles[newActiveFile] === "" && fileSystem.fetchFileContent;
|
|
19254
19430
|
postApplyServerSnapshot(
|
|
19255
19431
|
prevActiveFile,
|
|
@@ -19270,7 +19446,7 @@ const useForgeStore = create((set, get) => ({
|
|
|
19270
19446
|
const state2 = get();
|
|
19271
19447
|
const nextState = computeServerFileChange(state2, filename, content);
|
|
19272
19448
|
if (!nextState) return;
|
|
19273
|
-
set(nextState);
|
|
19449
|
+
set({ ...nextState, recentFiles: pruneAndPersistRecentFiles(state2.recentFiles, nextState.files) });
|
|
19274
19450
|
const previewFile = resolvePreviewFile(state2.activeFile, nextState.files);
|
|
19275
19451
|
if (previewFile === filename) setTimeout(() => get().execute(), 0);
|
|
19276
19452
|
},
|
|
@@ -19279,13 +19455,18 @@ const useForgeStore = create((set, get) => ({
|
|
|
19279
19455
|
const prevActiveFile = state2.activeFile;
|
|
19280
19456
|
const nextState = computeServerFileDelete(state2, filename);
|
|
19281
19457
|
if (!nextState) return;
|
|
19282
|
-
|
|
19283
|
-
|
|
19458
|
+
const newActiveFile = nextState.activeFile ?? "";
|
|
19459
|
+
set({
|
|
19460
|
+
...nextState,
|
|
19461
|
+
activeFile: newActiveFile,
|
|
19462
|
+
recentFiles: touchAndPersistRecentFile(state2.recentFiles, nextState.files, newActiveFile)
|
|
19463
|
+
});
|
|
19464
|
+
if (newActiveFile && newActiveFile !== prevActiveFile) {
|
|
19284
19465
|
set({ paramOverrides: {}, lastValidResult: null });
|
|
19285
19466
|
setParamOverrides({});
|
|
19286
|
-
window.history.replaceState(null, "", `#${
|
|
19467
|
+
window.history.replaceState(null, "", `#${newActiveFile}`);
|
|
19287
19468
|
try {
|
|
19288
|
-
localStorage.setItem(lastActiveFileKey(),
|
|
19469
|
+
localStorage.setItem(lastActiveFileKey(), newActiveFile);
|
|
19289
19470
|
} catch {
|
|
19290
19471
|
}
|
|
19291
19472
|
setTimeout(() => get().execute(), 0);
|
|
@@ -19312,6 +19493,9 @@ const useForgeStore = create((set, get) => ({
|
|
|
19312
19493
|
shareOpen: false,
|
|
19313
19494
|
openShare: () => set({ shareOpen: true }),
|
|
19314
19495
|
closeShare: () => set({ shareOpen: false }),
|
|
19496
|
+
captureOpen: false,
|
|
19497
|
+
openCapture: () => set({ captureOpen: true }),
|
|
19498
|
+
closeCapture: () => set({ captureOpen: false }),
|
|
19315
19499
|
aiSkillOpen: false,
|
|
19316
19500
|
openAISkill: () => set({ aiSkillOpen: true }),
|
|
19317
19501
|
closeAISkill: () => set({ aiSkillOpen: false }),
|
|
@@ -19324,7 +19508,10 @@ const useForgeStore = create((set, get) => ({
|
|
|
19324
19508
|
disableRunCache: initialViewPreferences.disableRunCache ?? false,
|
|
19325
19509
|
setDisableRunCache: (disabled) => {
|
|
19326
19510
|
writeViewPreferences({ disableRunCache: disabled });
|
|
19327
|
-
if (disabled)
|
|
19511
|
+
if (disabled) {
|
|
19512
|
+
clearRunResultCache();
|
|
19513
|
+
evalWorkerClient.clearCaches();
|
|
19514
|
+
}
|
|
19328
19515
|
set({ disableRunCache: disabled });
|
|
19329
19516
|
}
|
|
19330
19517
|
}));
|
|
@@ -27435,7 +27622,7 @@ function ConstructionGhostOverlay({ matrix }) {
|
|
|
27435
27622
|
class ConstructionHistoryWorkerClient {
|
|
27436
27623
|
constructor(workerFactory = () => new Worker(new URL(
|
|
27437
27624
|
/* @vite-ignore */
|
|
27438
|
-
"/assets/constructionHistoryWorker-
|
|
27625
|
+
"/assets/constructionHistoryWorker-AwMMWSxg.js",
|
|
27439
27626
|
import.meta.url
|
|
27440
27627
|
), { type: "module" })) {
|
|
27441
27628
|
__publicField(this, "worker", null);
|
|
@@ -29591,14 +29778,89 @@ ensureNotFinalized_fn = function() {
|
|
|
29591
29778
|
throw new Error("Cannot add new video or audio chunks after the file has been finalized.");
|
|
29592
29779
|
}
|
|
29593
29780
|
};
|
|
29781
|
+
const H264_HIGH_LEVEL_4_CODEC = "avc1.640028";
|
|
29782
|
+
const H264_LEVEL_4_MAX_CODED_AREA = 2097152;
|
|
29783
|
+
const H264_MACROBLOCK_SIZE = 16;
|
|
29594
29784
|
function supportsMP4Recording() {
|
|
29595
29785
|
return typeof VideoEncoder !== "undefined" && typeof VideoFrame !== "undefined";
|
|
29596
29786
|
}
|
|
29787
|
+
function evenFloor(value) {
|
|
29788
|
+
return Math.max(2, Math.floor(value) & -2);
|
|
29789
|
+
}
|
|
29790
|
+
function codedDimension(value) {
|
|
29791
|
+
return Math.ceil(value / H264_MACROBLOCK_SIZE) * H264_MACROBLOCK_SIZE;
|
|
29792
|
+
}
|
|
29793
|
+
function codedArea(width, height) {
|
|
29794
|
+
return codedDimension(width) * codedDimension(height);
|
|
29795
|
+
}
|
|
29796
|
+
function resolveCanvasBackground(canvas) {
|
|
29797
|
+
const transparent = /* @__PURE__ */ new Set(["transparent", "rgba(0, 0, 0, 0)"]);
|
|
29798
|
+
let node = canvas;
|
|
29799
|
+
while (node) {
|
|
29800
|
+
const backgroundColor = getComputedStyle(node).backgroundColor;
|
|
29801
|
+
if (backgroundColor && !transparent.has(backgroundColor)) return backgroundColor;
|
|
29802
|
+
node = node.parentElement;
|
|
29803
|
+
}
|
|
29804
|
+
return "#252526";
|
|
29805
|
+
}
|
|
29806
|
+
function fitH264Level4RecordingSize(sourceWidth, sourceHeight) {
|
|
29807
|
+
if (!Number.isFinite(sourceWidth) || !Number.isFinite(sourceHeight) || sourceWidth <= 0 || sourceHeight <= 0) {
|
|
29808
|
+
throw new Error(`Cannot record MP4 from invalid canvas size ${sourceWidth}x${sourceHeight}.`);
|
|
29809
|
+
}
|
|
29810
|
+
const evenSourceWidth = evenFloor(sourceWidth);
|
|
29811
|
+
const evenSourceHeight = evenFloor(sourceHeight);
|
|
29812
|
+
let width = evenSourceWidth;
|
|
29813
|
+
let height = evenSourceHeight;
|
|
29814
|
+
if (codedArea(width, height) > H264_LEVEL_4_MAX_CODED_AREA) {
|
|
29815
|
+
let low = 0;
|
|
29816
|
+
let high = 1;
|
|
29817
|
+
let bestWidth = 2;
|
|
29818
|
+
let bestHeight = 2;
|
|
29819
|
+
for (let i = 0; i < 32; i += 1) {
|
|
29820
|
+
const scale = (low + high) / 2;
|
|
29821
|
+
const candidateWidth = evenFloor(evenSourceWidth * scale);
|
|
29822
|
+
const candidateHeight = evenFloor(evenSourceHeight * scale);
|
|
29823
|
+
if (codedArea(candidateWidth, candidateHeight) <= H264_LEVEL_4_MAX_CODED_AREA) {
|
|
29824
|
+
bestWidth = candidateWidth;
|
|
29825
|
+
bestHeight = candidateHeight;
|
|
29826
|
+
low = scale;
|
|
29827
|
+
} else {
|
|
29828
|
+
high = scale;
|
|
29829
|
+
}
|
|
29830
|
+
}
|
|
29831
|
+
width = bestWidth;
|
|
29832
|
+
height = bestHeight;
|
|
29833
|
+
}
|
|
29834
|
+
const codedWidth = codedDimension(width);
|
|
29835
|
+
const codedHeight = codedDimension(height);
|
|
29836
|
+
if (codedWidth * codedHeight > H264_LEVEL_4_MAX_CODED_AREA) {
|
|
29837
|
+
throw new Error(`Could not fit ${sourceWidth}x${sourceHeight} into the MP4 encoder limit.`);
|
|
29838
|
+
}
|
|
29839
|
+
return {
|
|
29840
|
+
sourceWidth: evenSourceWidth,
|
|
29841
|
+
sourceHeight: evenSourceHeight,
|
|
29842
|
+
width,
|
|
29843
|
+
height,
|
|
29844
|
+
codedWidth,
|
|
29845
|
+
codedHeight,
|
|
29846
|
+
scale: Math.min(width / evenSourceWidth, height / evenSourceHeight)
|
|
29847
|
+
};
|
|
29848
|
+
}
|
|
29849
|
+
async function requireSupportedEncoderConfig(config) {
|
|
29850
|
+
if (typeof VideoEncoder.isConfigSupported !== "function") return config;
|
|
29851
|
+
const support = await VideoEncoder.isConfigSupported(config);
|
|
29852
|
+
if (!support.supported) {
|
|
29853
|
+
throw new Error(`MP4 recording is not supported at ${config.width}x${config.height} in this browser.`);
|
|
29854
|
+
}
|
|
29855
|
+
return support.config ?? config;
|
|
29856
|
+
}
|
|
29597
29857
|
class HistoryRecorder {
|
|
29598
29858
|
constructor(canvas, options) {
|
|
29599
29859
|
__publicField(this, "encoder", null);
|
|
29600
29860
|
__publicField(this, "muxer", null);
|
|
29601
29861
|
__publicField(this, "target", null);
|
|
29862
|
+
__publicField(this, "captureCanvas", null);
|
|
29863
|
+
__publicField(this, "captureContext", null);
|
|
29602
29864
|
__publicField(this, "frameCount", 0);
|
|
29603
29865
|
__publicField(this, "recording", false);
|
|
29604
29866
|
__publicField(this, "startTime", 0);
|
|
@@ -29615,37 +29877,71 @@ class HistoryRecorder {
|
|
|
29615
29877
|
/** Start recording. Must be called before captureFrame(). */
|
|
29616
29878
|
async start() {
|
|
29617
29879
|
if (this.recording) return;
|
|
29618
|
-
|
|
29619
|
-
|
|
29620
|
-
|
|
29621
|
-
|
|
29622
|
-
|
|
29623
|
-
|
|
29624
|
-
codec: "avc",
|
|
29625
|
-
width,
|
|
29626
|
-
height
|
|
29627
|
-
},
|
|
29628
|
-
fastStart: "in-memory",
|
|
29629
|
-
firstTimestampBehavior: "offset"
|
|
29630
|
-
});
|
|
29631
|
-
this.encoder = new VideoEncoder({
|
|
29632
|
-
output: (chunk, meta) => {
|
|
29633
|
-
this.muxer.addVideoChunk(chunk, meta);
|
|
29634
|
-
},
|
|
29635
|
-
error: (e2) => console.error("VideoEncoder error:", e2)
|
|
29636
|
-
});
|
|
29637
|
-
this.encoder.configure({
|
|
29638
|
-
codec: "avc1.640028",
|
|
29880
|
+
if (!supportsMP4Recording()) {
|
|
29881
|
+
throw new Error("MP4 recording requires WebCodecs VideoEncoder and VideoFrame support.");
|
|
29882
|
+
}
|
|
29883
|
+
const size = fitH264Level4RecordingSize(this.canvas.width, this.canvas.height);
|
|
29884
|
+
const config = await requireSupportedEncoderConfig({
|
|
29885
|
+
codec: H264_HIGH_LEVEL_4_CODEC,
|
|
29639
29886
|
// H.264 High Profile Level 4.0
|
|
29640
|
-
width,
|
|
29641
|
-
height,
|
|
29887
|
+
width: size.width,
|
|
29888
|
+
height: size.height,
|
|
29642
29889
|
bitrate: this.bitrate,
|
|
29643
29890
|
framerate: this.fps
|
|
29644
29891
|
});
|
|
29892
|
+
try {
|
|
29893
|
+
this.prepareCaptureSurface(size);
|
|
29894
|
+
this.target = new ArrayBufferTarget();
|
|
29895
|
+
this.muxer = new Muxer({
|
|
29896
|
+
target: this.target,
|
|
29897
|
+
video: {
|
|
29898
|
+
codec: "avc",
|
|
29899
|
+
width: size.width,
|
|
29900
|
+
height: size.height
|
|
29901
|
+
},
|
|
29902
|
+
fastStart: "in-memory",
|
|
29903
|
+
firstTimestampBehavior: "offset"
|
|
29904
|
+
});
|
|
29905
|
+
this.encoder = new VideoEncoder({
|
|
29906
|
+
output: (chunk, meta) => {
|
|
29907
|
+
this.muxer.addVideoChunk(chunk, meta);
|
|
29908
|
+
},
|
|
29909
|
+
error: (e2) => {
|
|
29910
|
+
this.recording = false;
|
|
29911
|
+
console.error("VideoEncoder error:", e2);
|
|
29912
|
+
}
|
|
29913
|
+
});
|
|
29914
|
+
this.encoder.configure(config);
|
|
29915
|
+
} catch (err) {
|
|
29916
|
+
this.abort();
|
|
29917
|
+
throw err;
|
|
29918
|
+
}
|
|
29645
29919
|
this.frameCount = 0;
|
|
29646
29920
|
this.startTime = performance.now();
|
|
29647
29921
|
this.recording = true;
|
|
29648
29922
|
}
|
|
29923
|
+
prepareCaptureSurface(size) {
|
|
29924
|
+
this.captureCanvas = null;
|
|
29925
|
+
this.captureContext = null;
|
|
29926
|
+
const captureCanvas = document.createElement("canvas");
|
|
29927
|
+
captureCanvas.width = size.width;
|
|
29928
|
+
captureCanvas.height = size.height;
|
|
29929
|
+
const captureContext = captureCanvas.getContext("2d", { alpha: false });
|
|
29930
|
+
if (!captureContext) {
|
|
29931
|
+
throw new Error("Could not create MP4 recording capture canvas.");
|
|
29932
|
+
}
|
|
29933
|
+
this.captureCanvas = captureCanvas;
|
|
29934
|
+
this.captureContext = captureContext;
|
|
29935
|
+
}
|
|
29936
|
+
frameSourceCanvas() {
|
|
29937
|
+
if (!this.captureCanvas || !this.captureContext) {
|
|
29938
|
+
throw new Error("MP4 recording capture surface is not initialized.");
|
|
29939
|
+
}
|
|
29940
|
+
this.captureContext.fillStyle = resolveCanvasBackground(this.canvas);
|
|
29941
|
+
this.captureContext.fillRect(0, 0, this.captureCanvas.width, this.captureCanvas.height);
|
|
29942
|
+
this.captureContext.drawImage(this.canvas, 0, 0, this.captureCanvas.width, this.captureCanvas.height);
|
|
29943
|
+
return this.captureCanvas;
|
|
29944
|
+
}
|
|
29649
29945
|
/**
|
|
29650
29946
|
* Capture the current canvas frame. Forces a render so the drawing buffer
|
|
29651
29947
|
* has fresh content — this avoids needing `preserveDrawingBuffer: true` on
|
|
@@ -29676,7 +29972,11 @@ class HistoryRecorder {
|
|
|
29676
29972
|
this.encodeFrame(timestampMicros);
|
|
29677
29973
|
}
|
|
29678
29974
|
encodeFrame(timestampMicros) {
|
|
29679
|
-
|
|
29975
|
+
if (!this.encoder || this.encoder.state !== "configured") {
|
|
29976
|
+
this.recording = false;
|
|
29977
|
+
return;
|
|
29978
|
+
}
|
|
29979
|
+
const frame2 = new VideoFrame(this.frameSourceCanvas(), {
|
|
29680
29980
|
timestamp: timestampMicros
|
|
29681
29981
|
});
|
|
29682
29982
|
const keyFrame = this.frameCount % (this.fps * 2) === 0;
|
|
@@ -29684,20 +29984,32 @@ class HistoryRecorder {
|
|
|
29684
29984
|
frame2.close();
|
|
29685
29985
|
this.frameCount++;
|
|
29686
29986
|
}
|
|
29987
|
+
reset() {
|
|
29988
|
+
this.encoder = null;
|
|
29989
|
+
this.muxer = null;
|
|
29990
|
+
this.target = null;
|
|
29991
|
+
this.captureCanvas = null;
|
|
29992
|
+
this.captureContext = null;
|
|
29993
|
+
this.frameCount = 0;
|
|
29994
|
+
this.startTime = 0;
|
|
29995
|
+
}
|
|
29687
29996
|
/** Stop recording and return the MP4 blob. */
|
|
29688
29997
|
async stop() {
|
|
29689
29998
|
if (!this.encoder || !this.muxer || !this.target) {
|
|
29690
29999
|
throw new Error("Not recording");
|
|
29691
30000
|
}
|
|
30001
|
+
const encoder2 = this.encoder;
|
|
30002
|
+
const muxer = this.muxer;
|
|
30003
|
+
const target = this.target;
|
|
29692
30004
|
this.recording = false;
|
|
29693
|
-
|
|
29694
|
-
|
|
29695
|
-
|
|
29696
|
-
|
|
29697
|
-
|
|
29698
|
-
|
|
29699
|
-
|
|
29700
|
-
|
|
30005
|
+
try {
|
|
30006
|
+
await encoder2.flush();
|
|
30007
|
+
if (encoder2.state !== "closed") encoder2.close();
|
|
30008
|
+
muxer.finalize();
|
|
30009
|
+
return new Blob([target.buffer], { type: "video/mp4" });
|
|
30010
|
+
} finally {
|
|
30011
|
+
this.reset();
|
|
30012
|
+
}
|
|
29701
30013
|
}
|
|
29702
30014
|
/** Abort recording without producing output. */
|
|
29703
30015
|
abort() {
|
|
@@ -29709,10 +30021,7 @@ class HistoryRecorder {
|
|
|
29709
30021
|
} catch {
|
|
29710
30022
|
}
|
|
29711
30023
|
}
|
|
29712
|
-
this.
|
|
29713
|
-
this.muxer = null;
|
|
29714
|
-
this.target = null;
|
|
29715
|
-
this.frameCount = 0;
|
|
30024
|
+
this.reset();
|
|
29716
30025
|
}
|
|
29717
30026
|
}
|
|
29718
30027
|
let registeredStart$2 = null;
|
|
@@ -29768,6 +30077,12 @@ function HistoryRecorderBridge() {
|
|
|
29768
30077
|
requestAnimationFrame(() => {
|
|
29769
30078
|
useForgeStore.getState().setHistoryPlaying(true);
|
|
29770
30079
|
});
|
|
30080
|
+
}).catch((err) => {
|
|
30081
|
+
recorderRef.current = null;
|
|
30082
|
+
state2.setHistoryRecording(false);
|
|
30083
|
+
state2.setHistoryPlaying(false);
|
|
30084
|
+
showToast("Recording failed", "error");
|
|
30085
|
+
console.error("History recording failed:", err);
|
|
29771
30086
|
});
|
|
29772
30087
|
}, [gl]);
|
|
29773
30088
|
const stop = reactExports.useCallback(async () => {
|
|
@@ -29819,7 +30134,7 @@ function generateReportInWorker(options) {
|
|
|
29819
30134
|
return new Promise((resolve2, reject) => {
|
|
29820
30135
|
const worker = new Worker(new URL(
|
|
29821
30136
|
/* @vite-ignore */
|
|
29822
|
-
"/assets/reportWorker-
|
|
30137
|
+
"/assets/reportWorker-DO6hcQbh.js",
|
|
29823
30138
|
import.meta.url
|
|
29824
30139
|
), { type: "module" });
|
|
29825
30140
|
const cleanup = () => {
|
|
@@ -30502,9 +30817,13 @@ function buildSketchExportArtifacts(format, stem, runResult) {
|
|
|
30502
30817
|
});
|
|
30503
30818
|
}
|
|
30504
30819
|
let orbitVideoExporter = null;
|
|
30820
|
+
let viewportImageExporter = null;
|
|
30505
30821
|
function registerOrbitVideoExporter(exporter) {
|
|
30506
30822
|
orbitVideoExporter = exporter;
|
|
30507
30823
|
}
|
|
30824
|
+
function registerViewportImageExporter(exporter) {
|
|
30825
|
+
viewportImageExporter = exporter;
|
|
30826
|
+
}
|
|
30508
30827
|
function rerunActiveScriptForQuality(quality) {
|
|
30509
30828
|
const { files, activeFile, paramOverrides } = useForgeStore.getState();
|
|
30510
30829
|
const assemblyState = resolveAssemblyStateForExport();
|
|
@@ -30630,6 +30949,23 @@ async function exportOrbitVideoFromStore(preferredStem, options) {
|
|
|
30630
30949
|
const ext = blob.type === "video/mp4" ? "mp4" : "gif";
|
|
30631
30950
|
triggerDownload(blob, `${stem}.orbit.${ext}`);
|
|
30632
30951
|
}
|
|
30952
|
+
async function captureViewportImageBlobFromStore(options) {
|
|
30953
|
+
if (!viewportImageExporter) {
|
|
30954
|
+
throw new Error("Viewport is not ready for image capture. Try again in a moment.");
|
|
30955
|
+
}
|
|
30956
|
+
const { activeFile, theme } = useForgeStore.getState();
|
|
30957
|
+
return viewportImageExporter({
|
|
30958
|
+
title: deriveExportStem(activeFile),
|
|
30959
|
+
themeName: theme,
|
|
30960
|
+
...options ?? {}
|
|
30961
|
+
});
|
|
30962
|
+
}
|
|
30963
|
+
async function exportViewportImageFromStore(preferredStem, options) {
|
|
30964
|
+
const { activeFile } = useForgeStore.getState();
|
|
30965
|
+
const stem = sanitizeExportStem(deriveExportStem(activeFile));
|
|
30966
|
+
const blob = await captureViewportImageBlobFromStore(options);
|
|
30967
|
+
triggerDownload(blob, `${stem}.png`);
|
|
30968
|
+
}
|
|
30633
30969
|
function exportSketchFromStore(format, preferredStem) {
|
|
30634
30970
|
const { result, activeFile } = useForgeStore.getState();
|
|
30635
30971
|
const stem = sanitizeExportStem(preferredStem ?? deriveExportStem(activeFile));
|
|
@@ -30890,6 +31226,11 @@ function ViewportRecordingBridge({ controlsRef }) {
|
|
|
30890
31226
|
frameIntervalRef.current = 1e3 / TARGET_FPS;
|
|
30891
31227
|
void recorder.start().then(() => {
|
|
30892
31228
|
useForgeStore.getState().setAnimationRecording(true);
|
|
31229
|
+
}).catch((err) => {
|
|
31230
|
+
recorderRef.current = null;
|
|
31231
|
+
useForgeStore.getState().setAnimationRecording(false);
|
|
31232
|
+
showToast("Recording failed", "error");
|
|
31233
|
+
console.error("Viewport recording failed:", err);
|
|
30893
31234
|
});
|
|
30894
31235
|
}, [gl, snapshotOrbitTarget]);
|
|
30895
31236
|
const stop = reactExports.useCallback(async () => {
|
|
@@ -31725,6 +32066,14 @@ function TrajectoryRecorderBridge({ controlsRef }) {
|
|
|
31725
32066
|
state2.setTrajectoryProgress(0);
|
|
31726
32067
|
void recorder.start().then(() => {
|
|
31727
32068
|
state2.setTrajectoryRecording(true);
|
|
32069
|
+
}).catch((err) => {
|
|
32070
|
+
recorderRef.current = null;
|
|
32071
|
+
trajectoryRef.current = null;
|
|
32072
|
+
lastFrameRef.current = 0;
|
|
32073
|
+
manualStartRef.current = 0;
|
|
32074
|
+
state2.setTrajectoryRecording(false);
|
|
32075
|
+
showToast("Recording failed", "error");
|
|
32076
|
+
console.error("Trajectory recording failed:", err);
|
|
31728
32077
|
});
|
|
31729
32078
|
}, [gl]);
|
|
31730
32079
|
const stop = reactExports.useCallback(async () => {
|
|
@@ -32681,6 +33030,164 @@ function OrbitExporterBridge({ controlsRef }) {
|
|
|
32681
33030
|
}, [exportOrbitVideo]);
|
|
32682
33031
|
return null;
|
|
32683
33032
|
}
|
|
33033
|
+
function clampDimension(value, fallback) {
|
|
33034
|
+
const numeric = Number.isFinite(value) ? value : fallback;
|
|
33035
|
+
return Math.max(96, Math.min(4096, Math.round(numeric ?? 96)));
|
|
33036
|
+
}
|
|
33037
|
+
function computeFrameLayout(width, height, includeFrame) {
|
|
33038
|
+
if (!includeFrame) return { x: 0, y: 0, width, height, headerHeight: 0, pad: 0 };
|
|
33039
|
+
const pad = Math.max(14, Math.round(Math.min(width, height) * 0.035));
|
|
33040
|
+
const headerHeight = Math.max(50, Math.min(96, Math.round(height * 0.105)));
|
|
33041
|
+
return {
|
|
33042
|
+
x: pad,
|
|
33043
|
+
y: headerHeight,
|
|
33044
|
+
width: Math.max(1, width - pad * 2),
|
|
33045
|
+
height: Math.max(1, height - headerHeight - pad),
|
|
33046
|
+
headerHeight,
|
|
33047
|
+
pad
|
|
33048
|
+
};
|
|
33049
|
+
}
|
|
33050
|
+
function cssVar(name, fallback) {
|
|
33051
|
+
if (typeof document === "undefined") return fallback;
|
|
33052
|
+
const value = getComputedStyle(document.documentElement).getPropertyValue(name).trim();
|
|
33053
|
+
return value || fallback;
|
|
33054
|
+
}
|
|
33055
|
+
function canvasBlob(canvas) {
|
|
33056
|
+
return new Promise((resolve2, reject) => {
|
|
33057
|
+
canvas.toBlob((blob) => blob ? resolve2(blob) : reject(new Error("Could not encode PNG capture.")), "image/png");
|
|
33058
|
+
});
|
|
33059
|
+
}
|
|
33060
|
+
function drawCorner(ctx, x, y, dx, dy, size) {
|
|
33061
|
+
ctx.beginPath();
|
|
33062
|
+
ctx.moveTo(x, y + dy * size);
|
|
33063
|
+
ctx.lineTo(x, y);
|
|
33064
|
+
ctx.lineTo(x + dx * size, y);
|
|
33065
|
+
ctx.stroke();
|
|
33066
|
+
}
|
|
33067
|
+
function composeFrame(source, outputWidth, outputHeight, layout, options) {
|
|
33068
|
+
var _a3;
|
|
33069
|
+
const canvas = document.createElement("canvas");
|
|
33070
|
+
canvas.width = outputWidth;
|
|
33071
|
+
canvas.height = outputHeight;
|
|
33072
|
+
const ctx = canvas.getContext("2d");
|
|
33073
|
+
if (!ctx) throw new Error("Could not create PNG capture context.");
|
|
33074
|
+
const bg = cssVar("--fc-bg", "#02070a");
|
|
33075
|
+
const surface = cssVar("--fc-bgSurface", "#0a2028");
|
|
33076
|
+
const border = cssVar("--fc-border", "#165363");
|
|
33077
|
+
const accent = cssVar("--fc-accent", "#36e8ff");
|
|
33078
|
+
const text = cssVar("--fc-text", "#d9fbff");
|
|
33079
|
+
const muted = cssVar("--fc-textMuted", "#8ebdc6");
|
|
33080
|
+
const dim = cssVar("--fc-textDim", "#4e7078");
|
|
33081
|
+
const title = ((_a3 = options.title) == null ? void 0 : _a3.trim()) || "ForgeCAD model";
|
|
33082
|
+
const themeLabel = options.themeName ? `${options.themeName} theme` : "current theme";
|
|
33083
|
+
ctx.fillStyle = bg;
|
|
33084
|
+
ctx.fillRect(0, 0, outputWidth, outputHeight);
|
|
33085
|
+
ctx.fillStyle = surface;
|
|
33086
|
+
ctx.fillRect(0, 0, outputWidth, layout.headerHeight);
|
|
33087
|
+
ctx.strokeStyle = border;
|
|
33088
|
+
ctx.lineWidth = Math.max(1, Math.round(outputWidth / 900));
|
|
33089
|
+
ctx.strokeRect(layout.x - 1, layout.y - 1, layout.width + 2, layout.height + 2);
|
|
33090
|
+
ctx.drawImage(source, layout.x, layout.y, layout.width, layout.height);
|
|
33091
|
+
ctx.strokeStyle = accent;
|
|
33092
|
+
ctx.globalAlpha = 0.85;
|
|
33093
|
+
ctx.beginPath();
|
|
33094
|
+
ctx.moveTo(layout.pad, layout.headerHeight - 1);
|
|
33095
|
+
ctx.lineTo(outputWidth - layout.pad, layout.headerHeight - 1);
|
|
33096
|
+
ctx.stroke();
|
|
33097
|
+
const corner = Math.max(18, Math.min(42, Math.round(Math.min(outputWidth, outputHeight) * 0.035)));
|
|
33098
|
+
drawCorner(ctx, layout.pad, layout.y, 1, 1, corner);
|
|
33099
|
+
drawCorner(ctx, outputWidth - layout.pad, layout.y, -1, 1, corner);
|
|
33100
|
+
drawCorner(ctx, layout.pad, outputHeight - layout.pad, 1, -1, corner);
|
|
33101
|
+
drawCorner(ctx, outputWidth - layout.pad, outputHeight - layout.pad, -1, -1, corner);
|
|
33102
|
+
ctx.globalAlpha = 1;
|
|
33103
|
+
const mono = "ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace";
|
|
33104
|
+
ctx.fillStyle = accent;
|
|
33105
|
+
ctx.font = `700 ${Math.max(11, Math.round(outputHeight * 0.012))}px ${mono}`;
|
|
33106
|
+
ctx.fillText("FORGECAD CAPTURE", layout.pad, Math.round(layout.headerHeight * 0.35));
|
|
33107
|
+
ctx.fillStyle = text;
|
|
33108
|
+
ctx.font = `700 ${Math.max(16, Math.round(outputHeight * 0.021))}px Inter, system-ui, sans-serif`;
|
|
33109
|
+
ctx.fillText(title.slice(0, 64), layout.pad, Math.round(layout.headerHeight * 0.72));
|
|
33110
|
+
ctx.fillStyle = muted;
|
|
33111
|
+
ctx.font = `500 ${Math.max(11, Math.round(outputHeight * 0.012))}px ${mono}`;
|
|
33112
|
+
ctx.textAlign = "right";
|
|
33113
|
+
ctx.fillText(`${outputWidth}x${outputHeight}`, outputWidth - layout.pad, Math.round(layout.headerHeight * 0.35));
|
|
33114
|
+
ctx.fillStyle = dim;
|
|
33115
|
+
ctx.fillText(themeLabel, outputWidth - layout.pad, Math.round(layout.headerHeight * 0.72));
|
|
33116
|
+
ctx.textAlign = "left";
|
|
33117
|
+
return canvas;
|
|
33118
|
+
}
|
|
33119
|
+
function copyRenderedCanvas(source, width, height) {
|
|
33120
|
+
const canvas = document.createElement("canvas");
|
|
33121
|
+
canvas.width = width;
|
|
33122
|
+
canvas.height = height;
|
|
33123
|
+
const ctx = canvas.getContext("2d");
|
|
33124
|
+
if (!ctx) throw new Error("Could not create PNG capture context.");
|
|
33125
|
+
ctx.drawImage(source, 0, 0, width, height);
|
|
33126
|
+
return canvas;
|
|
33127
|
+
}
|
|
33128
|
+
function withCameraAspect(camera, width, height, render) {
|
|
33129
|
+
if (camera instanceof PerspectiveCamera$1) {
|
|
33130
|
+
const previousAspect = camera.aspect;
|
|
33131
|
+
camera.aspect = width / height;
|
|
33132
|
+
camera.updateProjectionMatrix();
|
|
33133
|
+
try {
|
|
33134
|
+
render();
|
|
33135
|
+
} finally {
|
|
33136
|
+
camera.aspect = previousAspect;
|
|
33137
|
+
camera.updateProjectionMatrix();
|
|
33138
|
+
}
|
|
33139
|
+
return;
|
|
33140
|
+
}
|
|
33141
|
+
if (camera instanceof OrthographicCamera$1) {
|
|
33142
|
+
const previous = { left: camera.left, right: camera.right, top: camera.top, bottom: camera.bottom };
|
|
33143
|
+
const midX = (camera.left + camera.right) / 2;
|
|
33144
|
+
const halfHeight = (camera.top - camera.bottom) / 2;
|
|
33145
|
+
const halfWidth = halfHeight * (width / height);
|
|
33146
|
+
camera.left = midX - halfWidth;
|
|
33147
|
+
camera.right = midX + halfWidth;
|
|
33148
|
+
camera.updateProjectionMatrix();
|
|
33149
|
+
try {
|
|
33150
|
+
render();
|
|
33151
|
+
} finally {
|
|
33152
|
+
Object.assign(camera, previous);
|
|
33153
|
+
camera.updateProjectionMatrix();
|
|
33154
|
+
}
|
|
33155
|
+
return;
|
|
33156
|
+
}
|
|
33157
|
+
render();
|
|
33158
|
+
}
|
|
33159
|
+
function ViewportImageCaptureBridge() {
|
|
33160
|
+
const { camera, gl, scene } = useThree();
|
|
33161
|
+
const capture = reactExports.useCallback(
|
|
33162
|
+
async (options) => {
|
|
33163
|
+
const currentSize = gl.getSize(new Vector2());
|
|
33164
|
+
const outputWidth = clampDimension(options == null ? void 0 : options.width, currentSize.x);
|
|
33165
|
+
const outputHeight = clampDimension(options == null ? void 0 : options.height, currentSize.y);
|
|
33166
|
+
const layout = computeFrameLayout(outputWidth, outputHeight, (options == null ? void 0 : options.includeFrame) ?? true);
|
|
33167
|
+
const previousSize = currentSize.clone();
|
|
33168
|
+
const previousPixelRatio = gl.getPixelRatio();
|
|
33169
|
+
try {
|
|
33170
|
+
await waitForAnimationFrame();
|
|
33171
|
+
gl.setPixelRatio(1);
|
|
33172
|
+
gl.setSize(layout.width, layout.height, false);
|
|
33173
|
+
withCameraAspect(camera, layout.width, layout.height, () => gl.render(scene, camera));
|
|
33174
|
+
const rendered = copyRenderedCanvas(gl.domElement, layout.width, layout.height);
|
|
33175
|
+
const finalCanvas = (options == null ? void 0 : options.includeFrame) === false ? rendered : composeFrame(rendered, outputWidth, outputHeight, layout, options ?? {});
|
|
33176
|
+
return await canvasBlob(finalCanvas);
|
|
33177
|
+
} finally {
|
|
33178
|
+
gl.setPixelRatio(previousPixelRatio);
|
|
33179
|
+
gl.setSize(previousSize.x, previousSize.y, false);
|
|
33180
|
+
gl.render(scene, camera);
|
|
33181
|
+
}
|
|
33182
|
+
},
|
|
33183
|
+
[camera, gl, scene]
|
|
33184
|
+
);
|
|
33185
|
+
reactExports.useEffect(() => {
|
|
33186
|
+
registerViewportImageExporter(capture);
|
|
33187
|
+
return () => registerViewportImageExporter(null);
|
|
33188
|
+
}, [capture]);
|
|
33189
|
+
return null;
|
|
33190
|
+
}
|
|
32684
33191
|
const DEBUG_HL_DEFAULT_COLOR = "#ff00ff";
|
|
32685
33192
|
const DEBUG_HL_DEFAULT_POINT_SIZE = 3;
|
|
32686
33193
|
const DEBUG_HL_DEFAULT_PLANE_SIZE = 50;
|
|
@@ -33676,7 +34183,7 @@ function SectionCapPreview({
|
|
|
33676
34183
|
class ScanProxyWorkerClient {
|
|
33677
34184
|
constructor(workerFactory = () => new Worker(new URL(
|
|
33678
34185
|
/* @vite-ignore */
|
|
33679
|
-
"/assets/scanProxyWorker-
|
|
34186
|
+
"/assets/scanProxyWorker-2GtDLk-R.js",
|
|
33680
34187
|
import.meta.url
|
|
33681
34188
|
), { type: "module" })) {
|
|
33682
34189
|
__publicField(this, "worker", null);
|
|
@@ -34191,20 +34698,34 @@ function ScanProxyLayer({
|
|
|
34191
34698
|
fillOpacity,
|
|
34192
34699
|
wireOpacity,
|
|
34193
34700
|
clippingPlanes,
|
|
34194
|
-
|
|
34701
|
+
volumeFill = false,
|
|
34702
|
+
showWire = true,
|
|
34195
34703
|
analysisGeometry
|
|
34196
34704
|
}) {
|
|
34197
34705
|
const fillGeometry = analysisGeometry ?? geometry;
|
|
34198
34706
|
if (!geometry || !fillGeometry) return null;
|
|
34199
34707
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
34200
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("mesh", { geometry: fillGeometry, raycast: () => null, children:
|
|
34708
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("mesh", { geometry: fillGeometry, raycast: () => null, children: volumeFill ? /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
34201
34709
|
"meshBasicMaterial",
|
|
34202
34710
|
{
|
|
34203
|
-
|
|
34711
|
+
color: color2,
|
|
34204
34712
|
transparent: true,
|
|
34205
|
-
opacity: fillOpacity,
|
|
34713
|
+
opacity: Math.min(0.1, fillOpacity * 0.2),
|
|
34206
34714
|
side: DoubleSide,
|
|
34207
34715
|
depthWrite: false,
|
|
34716
|
+
blending: AdditiveBlending,
|
|
34717
|
+
toneMapped: false,
|
|
34718
|
+
clippingPlanes
|
|
34719
|
+
}
|
|
34720
|
+
) : analysisGeometry ? /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
34721
|
+
"meshBasicMaterial",
|
|
34722
|
+
{
|
|
34723
|
+
vertexColors: true,
|
|
34724
|
+
opacity: fillOpacity,
|
|
34725
|
+
side: DoubleSide,
|
|
34726
|
+
alphaHash: true,
|
|
34727
|
+
alphaToCoverage: true,
|
|
34728
|
+
depthWrite: true,
|
|
34208
34729
|
toneMapped: false,
|
|
34209
34730
|
clippingPlanes
|
|
34210
34731
|
}
|
|
@@ -34212,41 +34733,40 @@ function ScanProxyLayer({
|
|
|
34212
34733
|
"meshBasicMaterial",
|
|
34213
34734
|
{
|
|
34214
34735
|
color: color2,
|
|
34215
|
-
transparent: true,
|
|
34216
34736
|
opacity: fillOpacity,
|
|
34217
34737
|
side: DoubleSide,
|
|
34218
|
-
|
|
34738
|
+
alphaHash: true,
|
|
34739
|
+
alphaToCoverage: true,
|
|
34740
|
+
depthWrite: true,
|
|
34219
34741
|
toneMapped: false,
|
|
34220
34742
|
clippingPlanes
|
|
34221
34743
|
}
|
|
34222
34744
|
) }),
|
|
34223
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("mesh", { geometry, raycast: () => null, children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
34745
|
+
showWire && /* @__PURE__ */ jsxRuntimeExports.jsx("mesh", { geometry, raycast: () => null, children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
34224
34746
|
"meshBasicMaterial",
|
|
34225
34747
|
{
|
|
34226
34748
|
color: color2,
|
|
34227
|
-
transparent: true,
|
|
34228
34749
|
opacity: wireOpacity,
|
|
34229
34750
|
wireframe: true,
|
|
34230
34751
|
side: DoubleSide,
|
|
34231
|
-
|
|
34232
|
-
|
|
34752
|
+
alphaHash: true,
|
|
34753
|
+
alphaToCoverage: true,
|
|
34754
|
+
depthWrite: true,
|
|
34233
34755
|
toneMapped: false,
|
|
34234
34756
|
clippingPlanes
|
|
34235
34757
|
}
|
|
34236
34758
|
) })
|
|
34237
34759
|
] });
|
|
34238
34760
|
}
|
|
34239
|
-
function objectColorScanLayerStyles(color2) {
|
|
34240
|
-
return SCAN_PROXY_LAYER_STYLES.map((layer) => ({ ...layer, color: color2 }));
|
|
34241
|
-
}
|
|
34242
34761
|
function ScanProxyVolume({
|
|
34243
34762
|
proxy,
|
|
34244
34763
|
clippingPlanes,
|
|
34245
34764
|
objectColor,
|
|
34765
|
+
volumeFill = false,
|
|
34766
|
+
showWire = true,
|
|
34246
34767
|
analysisGeometries
|
|
34247
34768
|
}) {
|
|
34248
|
-
const layers = objectColor ?
|
|
34249
|
-
const additiveWire = objectColor === void 0;
|
|
34769
|
+
const layers = reactExports.useMemo(() => objectColor ? scanMaterialLayerStyles(objectColor) : SCAN_PROXY_LAYER_STYLES, [objectColor]);
|
|
34250
34770
|
return /* @__PURE__ */ jsxRuntimeExports.jsx("group", { userData: { scanProxyTelemetry: proxy.telemetry }, children: layers.map((layer) => {
|
|
34251
34771
|
const analysisGeometry = (analysisGeometries == null ? void 0 : analysisGeometries[layer.material]) ?? null;
|
|
34252
34772
|
const fillOpacity = analysisGeometry ? Math.max(layer.fillOpacity, 0.78) : layer.fillOpacity;
|
|
@@ -34257,7 +34777,8 @@ function ScanProxyVolume({
|
|
|
34257
34777
|
geometry: proxy.geometries[layer.material],
|
|
34258
34778
|
analysisGeometry,
|
|
34259
34779
|
clippingPlanes,
|
|
34260
|
-
|
|
34780
|
+
volumeFill,
|
|
34781
|
+
showWire,
|
|
34261
34782
|
...layer,
|
|
34262
34783
|
fillOpacity,
|
|
34263
34784
|
wireOpacity
|
|
@@ -34574,32 +35095,28 @@ function ForgeObject({
|
|
|
34574
35095
|
) }),
|
|
34575
35096
|
edgesGeo && /* @__PURE__ */ jsxRuntimeExports.jsx("lineSegments", { geometry: edgesGeo, raycast: () => null, children: /* @__PURE__ */ jsxRuntimeExports.jsx("lineBasicMaterial", { color: "#d7e1eb", transparent: true, opacity: 0.36, depthWrite: false, clippingPlanes: effectiveClippingPlanes }) })
|
|
34576
35097
|
] }),
|
|
34577
|
-
showScanRenderStyle && (scanProxy ? /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
34578
|
-
|
|
34579
|
-
|
|
34580
|
-
|
|
34581
|
-
|
|
34582
|
-
|
|
34583
|
-
|
|
34584
|
-
|
|
34585
|
-
|
|
34586
|
-
|
|
34587
|
-
|
|
34588
|
-
|
|
34589
|
-
|
|
34590
|
-
|
|
34591
|
-
|
|
34592
|
-
|
|
34593
|
-
|
|
34594
|
-
|
|
34595
|
-
|
|
34596
|
-
|
|
34597
|
-
|
|
34598
|
-
|
|
34599
|
-
clippingPlanes: effectiveClippingPlanes
|
|
34600
|
-
}
|
|
34601
|
-
) })
|
|
34602
|
-
] })),
|
|
35098
|
+
showScanRenderStyle && (scanProxy ? /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
35099
|
+
ScanProxyVolume,
|
|
35100
|
+
{
|
|
35101
|
+
proxy: scanProxy,
|
|
35102
|
+
clippingPlanes: effectiveClippingPlanes,
|
|
35103
|
+
objectColor: settings.color,
|
|
35104
|
+
volumeFill: true,
|
|
35105
|
+
showWire: false
|
|
35106
|
+
}
|
|
35107
|
+
) : showScanFallbackMesh && /* @__PURE__ */ jsxRuntimeExports.jsx("mesh", { geometry: solidGeo, raycast: () => null, children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
35108
|
+
"meshBasicMaterial",
|
|
35109
|
+
{
|
|
35110
|
+
color: scanMaterialShellColor(settings.color),
|
|
35111
|
+
transparent: true,
|
|
35112
|
+
opacity: 0.08,
|
|
35113
|
+
side: DoubleSide,
|
|
35114
|
+
depthWrite: false,
|
|
35115
|
+
blending: AdditiveBlending,
|
|
35116
|
+
toneMapped: false,
|
|
35117
|
+
clippingPlanes: effectiveClippingPlanes
|
|
35118
|
+
}
|
|
35119
|
+
) })),
|
|
34603
35120
|
showMatrixRenderStyle && (scanProxy ? /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
34604
35121
|
MatrixGlyphVolume,
|
|
34605
35122
|
{
|
|
@@ -43120,7 +43637,7 @@ function directCadKindForPath(path) {
|
|
|
43120
43637
|
return null;
|
|
43121
43638
|
}
|
|
43122
43639
|
function directCadReferenceCode(path, kind) {
|
|
43123
|
-
const fn = kind === "step" ? "
|
|
43640
|
+
const fn = kind === "step" ? "Import.step" : "Import.mesh";
|
|
43124
43641
|
const name = basename(path);
|
|
43125
43642
|
return [`const imported = ${fn}(${JSON.stringify(path)});`, `return [{ name: ${JSON.stringify(name)}, shape: imported }];`].join("\n");
|
|
43126
43643
|
}
|
|
@@ -43274,7 +43791,7 @@ function useGeometryComparison(args) {
|
|
|
43274
43791
|
class InspectWorkerClient {
|
|
43275
43792
|
constructor(workerFactory = () => new Worker(new URL(
|
|
43276
43793
|
/* @vite-ignore */
|
|
43277
|
-
"/assets/inspectWorker-
|
|
43794
|
+
"/assets/inspectWorker-CZsCFtQT.js",
|
|
43278
43795
|
import.meta.url
|
|
43279
43796
|
), { type: "module" })) {
|
|
43280
43797
|
__publicField(this, "worker", null);
|
|
@@ -44467,7 +44984,7 @@ function Viewport() {
|
|
|
44467
44984
|
if (activeFile && !isModelFile(activeFile) && !isSvgActive && !meshPreviewFile) {
|
|
44468
44985
|
return {
|
|
44469
44986
|
title: "Viewport disabled",
|
|
44470
|
-
body: `${activeFile} is a
|
|
44987
|
+
body: `${activeFile} is a text file, not a .forge.js or .sketch.js model. Open a model file to render geometry.`
|
|
44471
44988
|
};
|
|
44472
44989
|
}
|
|
44473
44990
|
if (!(result == null ? void 0 : result.error) && (result == null ? void 0 : result.assemblyKinematics) && objects.length === 0 && !rigInspectActive) {
|
|
@@ -44478,7 +44995,10 @@ function Viewport() {
|
|
|
44478
44995
|
}
|
|
44479
44996
|
return null;
|
|
44480
44997
|
}, [activeFile, isSvgActive, meshPreviewFile, objects.length, result, rigInspectActive]);
|
|
44481
|
-
const canvasDpr =
|
|
44998
|
+
const canvasDpr = reactExports.useMemo(() => {
|
|
44999
|
+
if (hasVisibleSdfObjects) return renderStylePreset.canvasDpr.live;
|
|
45000
|
+
return [1, renderStylePreset.canvasDpr.idleMax];
|
|
45001
|
+
}, [hasVisibleSdfObjects, renderStylePreset.canvasDpr.idleMax, renderStylePreset.canvasDpr.live]);
|
|
44482
45002
|
const effectiveSdfObjectSettings = reactExports.useMemo(() => {
|
|
44483
45003
|
const next = {};
|
|
44484
45004
|
for (const obj of objects) {
|
|
@@ -45115,6 +45635,7 @@ function Viewport() {
|
|
|
45115
45635
|
/* @__PURE__ */ jsxRuntimeExports.jsx(ViewManager, { isSketchOnly, controlsRef }),
|
|
45116
45636
|
/* @__PURE__ */ jsxRuntimeExports.jsx(ViewPersistence, { controlsRef, isSketchOnly, onResolved: handleViewPersistenceResolved }),
|
|
45117
45637
|
/* @__PURE__ */ jsxRuntimeExports.jsx(OrbitExporterBridge, { controlsRef }),
|
|
45638
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(ViewportImageCaptureBridge, {}),
|
|
45118
45639
|
/* @__PURE__ */ jsxRuntimeExports.jsx(ViewportRecordingBridge, { controlsRef }),
|
|
45119
45640
|
historyMode && /* @__PURE__ */ jsxRuntimeExports.jsx(HistoryRecorderBridge, {}),
|
|
45120
45641
|
/* @__PURE__ */ jsxRuntimeExports.jsx(TrajectoryRecorderBridge, { controlsRef })
|
|
@@ -45690,7 +46211,7 @@ function Viewport() {
|
|
|
45690
46211
|
}
|
|
45691
46212
|
);
|
|
45692
46213
|
}
|
|
45693
|
-
const EditorApp$1 = reactExports.lazy(() => __vitePreload(() => import("./EditorApp-
|
|
46214
|
+
const EditorApp$1 = reactExports.lazy(() => __vitePreload(() => import("./EditorApp-QXsAISLR.js"), true ? __vite__mapDeps([0]) : void 0).then((m2) => ({ default: m2.EditorApp })));
|
|
45694
46215
|
const PENDING_SHARE_COPY_KEY = "fc-pending-share-copy";
|
|
45695
46216
|
function storePendingShareCopy(shareId) {
|
|
45696
46217
|
sessionStorage.setItem(PENDING_SHARE_COPY_KEY, shareId);
|
|
@@ -45956,17 +46477,17 @@ function SeoMetadata() {
|
|
|
45956
46477
|
}, [location.pathname]);
|
|
45957
46478
|
return null;
|
|
45958
46479
|
}
|
|
45959
|
-
reactExports.lazy(() => __vitePreload(() => import("./LandingPageProofDriven-
|
|
45960
|
-
const DocsPage = reactExports.lazy(() => __vitePreload(() => import("./DocsPage-
|
|
45961
|
-
reactExports.lazy(() => __vitePreload(() => import("./BlogPage-
|
|
45962
|
-
reactExports.lazy(() => __vitePreload(() => import("./BenchmarkPage-
|
|
45963
|
-
reactExports.lazy(() => __vitePreload(() => import("./AdminPage-
|
|
46480
|
+
reactExports.lazy(() => __vitePreload(() => import("./LandingPageProofDriven-yhhOodbf.js"), true ? __vite__mapDeps([1]) : void 0).then((m2) => ({ default: m2.LandingPageProofDriven })));
|
|
46481
|
+
const DocsPage = reactExports.lazy(() => __vitePreload(() => import("./DocsPage-B5LePEuj.js"), true ? [] : void 0).then((m2) => ({ default: m2.DocsPage })));
|
|
46482
|
+
reactExports.lazy(() => __vitePreload(() => import("./BlogPage-DodHpvmf.js"), true ? [] : void 0).then((m2) => ({ default: m2.BlogPage })));
|
|
46483
|
+
reactExports.lazy(() => __vitePreload(() => import("./BenchmarkPage-a9_f-1US.js"), true ? __vite__mapDeps([1,2]) : void 0).then((m2) => ({ default: m2.BenchmarkPage })));
|
|
46484
|
+
reactExports.lazy(() => __vitePreload(() => import("./AdminPage-DwYHz72L.js"), true ? [] : void 0).then((m2) => ({ default: m2.AdminPage })));
|
|
45964
46485
|
reactExports.lazy(() => __vitePreload(() => Promise.resolve().then(() => PublishedModelPage$1), true ? void 0 : void 0).then((m2) => ({ default: m2.PublishedModelPage })));
|
|
45965
|
-
reactExports.lazy(() => __vitePreload(() => import("./SettingsPage-
|
|
45966
|
-
reactExports.lazy(() => __vitePreload(() => import("./PricingPage-
|
|
45967
|
-
reactExports.lazy(() => __vitePreload(() => import("./LegalPage-
|
|
45968
|
-
const EditorApp = reactExports.lazy(() => __vitePreload(() => import("./EditorApp-
|
|
45969
|
-
const EmbedViewer = reactExports.lazy(() => __vitePreload(() => import("./EmbedViewer-
|
|
46486
|
+
reactExports.lazy(() => __vitePreload(() => import("./SettingsPage-BJZcM97j.js"), true ? [] : void 0).then((m2) => ({ default: m2.SettingsPage })));
|
|
46487
|
+
reactExports.lazy(() => __vitePreload(() => import("./PricingPage-E3Rma7aV.js"), true ? __vite__mapDeps([1,3]) : void 0).then((m2) => ({ default: m2.PricingPage })));
|
|
46488
|
+
reactExports.lazy(() => __vitePreload(() => import("./LegalPage-5RbKRGYK.js"), true ? __vite__mapDeps([1,4]) : void 0).then((m2) => ({ default: m2.LegalPage })));
|
|
46489
|
+
const EditorApp = reactExports.lazy(() => __vitePreload(() => import("./EditorApp-QXsAISLR.js"), true ? __vite__mapDeps([0]) : void 0).then((m2) => ({ default: m2.EditorApp })));
|
|
46490
|
+
const EmbedViewer = reactExports.lazy(() => __vitePreload(() => import("./EmbedViewer-DdEHGUMU.js"), true ? [] : void 0).then((m2) => ({ default: m2.EmbedViewer })));
|
|
45970
46491
|
const embedMode = isEmbedMode() && !window.location.pathname.startsWith("/m/");
|
|
45971
46492
|
const EDITABLE_CRASH_FILE = /\.(?:forge\.js|[cm]?[jt]sx?|json|md|txt|svg|dxf)$/i;
|
|
45972
46493
|
function firstMeaningfulLine(text) {
|
|
@@ -46186,66 +46707,73 @@ function App() {
|
|
|
46186
46707
|
applyTheme(localStorage.getItem("fc-theme") || "dark");
|
|
46187
46708
|
clientExports.createRoot(document.getElementById("root")).render(/* @__PURE__ */ jsxRuntimeExports.jsx(App, {}));
|
|
46188
46709
|
export {
|
|
46189
|
-
|
|
46710
|
+
INSPECT_POINT_SAMPLE_COUNT_MIN as $,
|
|
46190
46711
|
AuthApiError as A,
|
|
46191
46712
|
BrandMark as B,
|
|
46192
|
-
|
|
46193
|
-
|
|
46194
|
-
|
|
46713
|
+
captureViewportImageBlobFromStore as C,
|
|
46714
|
+
exportExactFromStore as D,
|
|
46715
|
+
storageQuotaUpgradeMessage as E,
|
|
46195
46716
|
FLAG_DEFINITIONS as F,
|
|
46196
|
-
|
|
46197
|
-
|
|
46198
|
-
|
|
46199
|
-
|
|
46200
|
-
|
|
46201
|
-
|
|
46202
|
-
|
|
46203
|
-
|
|
46204
|
-
|
|
46205
|
-
|
|
46206
|
-
|
|
46207
|
-
|
|
46208
|
-
|
|
46209
|
-
|
|
46210
|
-
|
|
46211
|
-
|
|
46212
|
-
|
|
46213
|
-
|
|
46214
|
-
|
|
46215
|
-
|
|
46216
|
-
|
|
46717
|
+
isImportableProjectMeshFile as G,
|
|
46718
|
+
isImportableProjectBinaryFile as H,
|
|
46719
|
+
hasExternalFiles as I,
|
|
46720
|
+
isImportableProjectExactFile as J,
|
|
46721
|
+
resolvePreviewFile as K,
|
|
46722
|
+
countParamSnapshotDiff as L,
|
|
46723
|
+
buildProjectShareUrl as M,
|
|
46724
|
+
buildEmbedSnippet as N,
|
|
46725
|
+
publishProjectShare as O,
|
|
46726
|
+
unpublishProjectShare as P,
|
|
46727
|
+
formatComputeBackendLabel as Q,
|
|
46728
|
+
themes as R,
|
|
46729
|
+
computeBackendFromParts as S,
|
|
46730
|
+
formatArea as T,
|
|
46731
|
+
sliderToAnimationSpeed as U,
|
|
46732
|
+
animationSpeedToSlider as V,
|
|
46733
|
+
formatAnimationSpeed as W,
|
|
46734
|
+
resolveJointRange as X,
|
|
46735
|
+
useJointsConfig as Y,
|
|
46736
|
+
useJointAnimationValues as Z,
|
|
46737
|
+
INSPECT_POINT_SAMPLE_COUNT_MAX as _,
|
|
46217
46738
|
applyTheme as a,
|
|
46218
|
-
|
|
46219
|
-
|
|
46220
|
-
|
|
46221
|
-
|
|
46222
|
-
|
|
46223
|
-
|
|
46224
|
-
|
|
46225
|
-
|
|
46226
|
-
|
|
46227
|
-
|
|
46228
|
-
|
|
46229
|
-
|
|
46230
|
-
|
|
46231
|
-
|
|
46232
|
-
|
|
46233
|
-
|
|
46234
|
-
|
|
46235
|
-
|
|
46236
|
-
|
|
46237
|
-
|
|
46238
|
-
|
|
46239
|
-
|
|
46240
|
-
|
|
46241
|
-
|
|
46242
|
-
|
|
46243
|
-
|
|
46244
|
-
|
|
46245
|
-
|
|
46246
|
-
|
|
46247
|
-
|
|
46248
|
-
|
|
46739
|
+
VOXEL_INTENT_TOOL_ORDER as a0,
|
|
46740
|
+
VOXEL_INTENT_TOOL_LABELS as a1,
|
|
46741
|
+
VOXEL_INTENT_TOOL_COLORS as a2,
|
|
46742
|
+
VOXEL_INTENT_PLACEMENT_ORDER as a3,
|
|
46743
|
+
VOXEL_INTENT_PLACEMENT_LABELS as a4,
|
|
46744
|
+
highlightLanguageForProjectFile as a5,
|
|
46745
|
+
hasProjectTextFileExtension as a6,
|
|
46746
|
+
expandBoundsByTransformedAabb as a7,
|
|
46747
|
+
Canvas as a8,
|
|
46748
|
+
PerspectiveCamera as a9,
|
|
46749
|
+
buildShareUrl as aA,
|
|
46750
|
+
share as aB,
|
|
46751
|
+
ControlsInteractionBridge as aa,
|
|
46752
|
+
ViewController as ab,
|
|
46753
|
+
SceneConfigurator as ac,
|
|
46754
|
+
LocalEnvironment as ad,
|
|
46755
|
+
ForgeObject as ae,
|
|
46756
|
+
RenderLabelsOverlay as af,
|
|
46757
|
+
Grid as ag,
|
|
46758
|
+
OrbitControls2 as ah,
|
|
46759
|
+
TOUCH_GESTURES_3D as ai,
|
|
46760
|
+
MOUSE_BUTTONS_3D as aj,
|
|
46761
|
+
ModelJourneyBar as ak,
|
|
46762
|
+
useJointAnimationLoop as al,
|
|
46763
|
+
computeJointNodeMatrices as am,
|
|
46764
|
+
computeObjectJointMatrices as an,
|
|
46765
|
+
readLastActiveFileForUser as ao,
|
|
46766
|
+
ToastContainer as ap,
|
|
46767
|
+
isMobile as aq,
|
|
46768
|
+
useFeatureFlag as ar,
|
|
46769
|
+
decodeSharedHash as as,
|
|
46770
|
+
decodeSharedBundle as at,
|
|
46771
|
+
getExternalUrl as au,
|
|
46772
|
+
getGistId as av,
|
|
46773
|
+
Viewport as aw,
|
|
46774
|
+
shouldBlockBrowserShortcut as ax,
|
|
46775
|
+
useDrawStore as ay,
|
|
46776
|
+
storePendingShareCopy as az,
|
|
46249
46777
|
authFetch as b,
|
|
46250
46778
|
authApi as c,
|
|
46251
46779
|
showToast as d,
|
|
@@ -46253,22 +46781,22 @@ export {
|
|
|
46253
46781
|
formatStorageBytes as f,
|
|
46254
46782
|
useForgeStore as g,
|
|
46255
46783
|
fileSystem as h,
|
|
46256
|
-
|
|
46257
|
-
|
|
46258
|
-
|
|
46259
|
-
|
|
46260
|
-
|
|
46261
|
-
|
|
46262
|
-
|
|
46263
|
-
|
|
46264
|
-
|
|
46784
|
+
isRunnableFile as i,
|
|
46785
|
+
copyTextToClipboard as j,
|
|
46786
|
+
useFeatureFlagStore as k,
|
|
46787
|
+
fetchGistModel as l,
|
|
46788
|
+
monacoLanguageForProjectFile as m,
|
|
46789
|
+
fetchUrlModel as n,
|
|
46790
|
+
exportMeshFromStore as o,
|
|
46791
|
+
exportReportFromStore as p,
|
|
46792
|
+
exportViewportImageFromStore as q,
|
|
46265
46793
|
readProjectFilesFromDataTransfer as r,
|
|
46266
46794
|
storageUsagePercent as s,
|
|
46267
46795
|
triggerDownload as t,
|
|
46268
46796
|
useAuthStore as u,
|
|
46269
|
-
|
|
46270
|
-
|
|
46271
|
-
|
|
46272
|
-
|
|
46273
|
-
|
|
46797
|
+
exportOrbitVideoFromStore as v,
|
|
46798
|
+
exportSketchFromStore as w,
|
|
46799
|
+
buildGistShareUrl as x,
|
|
46800
|
+
deriveExportStem as y,
|
|
46801
|
+
sanitizeExportStem as z
|
|
46274
46802
|
};
|