@fps-games/editor 0.1.5-beta.5 → 0.1.7-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (469) hide show
  1. package/dist/agent-bridge/capabilities/assets.d.ts +8 -0
  2. package/dist/agent-bridge/capabilities/assets.d.ts.map +1 -0
  3. package/dist/agent-bridge/capabilities/assets.js +226 -0
  4. package/dist/agent-bridge/capabilities/assets.js.map +1 -0
  5. package/dist/agent-bridge/capabilities/editor-state.d.ts +5 -0
  6. package/dist/agent-bridge/capabilities/editor-state.d.ts.map +1 -0
  7. package/dist/agent-bridge/capabilities/editor-state.js +72 -0
  8. package/dist/agent-bridge/capabilities/editor-state.js.map +1 -0
  9. package/dist/agent-bridge/capabilities/host-lifecycle.d.ts +4 -0
  10. package/dist/agent-bridge/capabilities/host-lifecycle.d.ts.map +1 -0
  11. package/dist/agent-bridge/capabilities/host-lifecycle.js +87 -0
  12. package/dist/agent-bridge/capabilities/host-lifecycle.js.map +1 -0
  13. package/dist/agent-bridge/capabilities/prefabs.d.ts +5 -0
  14. package/dist/agent-bridge/capabilities/prefabs.d.ts.map +1 -0
  15. package/dist/agent-bridge/capabilities/prefabs.js +735 -0
  16. package/dist/agent-bridge/capabilities/prefabs.js.map +1 -0
  17. package/dist/agent-bridge/capabilities/scene-objects.d.ts +9 -0
  18. package/dist/agent-bridge/capabilities/scene-objects.d.ts.map +1 -0
  19. package/dist/agent-bridge/capabilities/scene-objects.js +394 -0
  20. package/dist/agent-bridge/capabilities/scene-objects.js.map +1 -0
  21. package/dist/agent-bridge/capabilities/selection.d.ts +5 -0
  22. package/dist/agent-bridge/capabilities/selection.d.ts.map +1 -0
  23. package/dist/agent-bridge/capabilities/selection.js +57 -0
  24. package/dist/agent-bridge/capabilities/selection.js.map +1 -0
  25. package/dist/agent-bridge/capabilities/shadows.d.ts +5 -0
  26. package/dist/agent-bridge/capabilities/shadows.d.ts.map +1 -0
  27. package/dist/agent-bridge/capabilities/shadows.js +1876 -0
  28. package/dist/agent-bridge/capabilities/shadows.js.map +1 -0
  29. package/dist/agent-bridge/capabilities/transform.d.ts +5 -0
  30. package/dist/agent-bridge/capabilities/transform.d.ts.map +1 -0
  31. package/dist/agent-bridge/capabilities/transform.js +162 -0
  32. package/dist/agent-bridge/capabilities/transform.js.map +1 -0
  33. package/dist/agent-bridge/capabilities/ui-regions.d.ts +4 -0
  34. package/dist/agent-bridge/capabilities/ui-regions.d.ts.map +1 -0
  35. package/dist/agent-bridge/capabilities/ui-regions.js +168 -0
  36. package/dist/agent-bridge/capabilities/ui-regions.js.map +1 -0
  37. package/dist/agent-bridge/capabilities/viewport.d.ts +5 -0
  38. package/dist/agent-bridge/capabilities/viewport.d.ts.map +1 -0
  39. package/dist/agent-bridge/capabilities/viewport.js +407 -0
  40. package/dist/agent-bridge/capabilities/viewport.js.map +1 -0
  41. package/dist/agent-bridge/capability-sources.d.ts +6 -0
  42. package/dist/agent-bridge/capability-sources.d.ts.map +1 -0
  43. package/dist/agent-bridge/capability-sources.js +26 -0
  44. package/dist/agent-bridge/capability-sources.js.map +1 -0
  45. package/dist/agent-bridge/diagnostics.d.ts +12 -0
  46. package/dist/agent-bridge/diagnostics.d.ts.map +1 -0
  47. package/dist/agent-bridge/diagnostics.js +45 -0
  48. package/dist/agent-bridge/diagnostics.js.map +1 -0
  49. package/dist/agent-bridge/index.d.ts +5 -0
  50. package/dist/agent-bridge/index.d.ts.map +1 -0
  51. package/dist/agent-bridge/index.js +5 -0
  52. package/dist/agent-bridge/index.js.map +1 -0
  53. package/dist/agent-bridge/register.d.ts +4 -0
  54. package/dist/agent-bridge/register.d.ts.map +1 -0
  55. package/dist/agent-bridge/register.js +908 -0
  56. package/dist/agent-bridge/register.js.map +1 -0
  57. package/dist/agent-bridge/shared.d.ts +189 -0
  58. package/dist/agent-bridge/shared.d.ts.map +1 -0
  59. package/dist/agent-bridge/shared.js +39 -0
  60. package/dist/agent-bridge/shared.js.map +1 -0
  61. package/dist/agent-bridge/source-types.d.ts +90 -0
  62. package/dist/agent-bridge/source-types.d.ts.map +1 -0
  63. package/dist/agent-bridge/source-types.js +2 -0
  64. package/dist/agent-bridge/source-types.js.map +1 -0
  65. package/dist/build-info.json +17 -17
  66. package/dist/local-editor-agent-actions.d.ts +8 -1
  67. package/dist/local-editor-agent-actions.d.ts.map +1 -1
  68. package/dist/local-editor-agent-actions.js +171 -12
  69. package/dist/local-editor-agent-actions.js.map +1 -1
  70. package/dist/local-editor-agent-bridge-transport.d.ts +95 -0
  71. package/dist/local-editor-agent-bridge-transport.d.ts.map +1 -0
  72. package/dist/local-editor-agent-bridge-transport.js +340 -0
  73. package/dist/local-editor-agent-bridge-transport.js.map +1 -0
  74. package/dist/local-editor-agent-bridge.d.ts +2 -0
  75. package/dist/local-editor-agent-bridge.d.ts.map +1 -0
  76. package/dist/local-editor-agent-bridge.js +2 -0
  77. package/dist/local-editor-agent-bridge.js.map +1 -0
  78. package/dist/local-editor-agent-context.d.ts +29 -1
  79. package/dist/local-editor-agent-context.d.ts.map +1 -1
  80. package/dist/local-editor-agent-context.js +403 -0
  81. package/dist/local-editor-agent-context.js.map +1 -1
  82. package/dist/local-editor-harness.d.ts +128 -6
  83. package/dist/local-editor-harness.d.ts.map +1 -1
  84. package/dist/local-editor-harness.js +2730 -151
  85. package/dist/local-editor-harness.js.map +1 -1
  86. package/dist/local-editor-marker-graph.d.ts +92 -0
  87. package/dist/local-editor-marker-graph.d.ts.map +1 -0
  88. package/dist/local-editor-marker-graph.js +1432 -0
  89. package/dist/local-editor-marker-graph.js.map +1 -0
  90. package/dist/local-editor-performance-stats.js +1 -1
  91. package/dist/local-editor-performance-stats.js.map +1 -1
  92. package/dist/playable-babylon-facade.d.ts +2 -2
  93. package/dist/playable-babylon-facade.d.ts.map +1 -1
  94. package/dist/playable-babylon-facade.js +1 -1
  95. package/dist/playable-babylon-facade.js.map +1 -1
  96. package/dist/playable-babylon-rendering.js +20 -0
  97. package/dist/playable-babylon-rendering.js.map +1 -1
  98. package/dist/playable-local-editor-host.d.ts +57 -7
  99. package/dist/playable-local-editor-host.d.ts.map +1 -1
  100. package/dist/playable-local-editor-host.js +25 -1
  101. package/dist/playable-local-editor-host.js.map +1 -1
  102. package/dist/playable-sdk.d.ts +4 -2
  103. package/dist/playable-sdk.d.ts.map +1 -1
  104. package/dist/playable-sdk.js +2 -1
  105. package/dist/playable-sdk.js.map +1 -1
  106. package/node_modules/@fps-games/babylon-renderer/dist/shadows/blob-shadow-system.d.ts.map +1 -1
  107. package/node_modules/@fps-games/babylon-renderer/dist/shadows/blob-shadow-system.js +6 -4
  108. package/node_modules/@fps-games/babylon-renderer/dist/shadows/blob-shadow-system.js.map +1 -1
  109. package/node_modules/@fps-games/babylon-renderer/dist/shadows/planar-shadow-shaders.d.ts.map +1 -1
  110. package/node_modules/@fps-games/babylon-renderer/dist/shadows/planar-shadow-shaders.js +103 -1
  111. package/node_modules/@fps-games/babylon-renderer/dist/shadows/planar-shadow-shaders.js.map +1 -1
  112. package/node_modules/@fps-games/babylon-renderer/dist/shadows/planar-shadow-system.d.ts.map +1 -1
  113. package/node_modules/@fps-games/babylon-renderer/dist/shadows/planar-shadow-system.js +330 -27
  114. package/node_modules/@fps-games/babylon-renderer/dist/shadows/planar-shadow-system.js.map +1 -1
  115. package/node_modules/@fps-games/babylon-renderer/dist/shadows/static-projected-shadow-artifact-system.d.ts.map +1 -1
  116. package/node_modules/@fps-games/babylon-renderer/dist/shadows/static-projected-shadow-artifact-system.js +159 -0
  117. package/node_modules/@fps-games/babylon-renderer/dist/shadows/static-projected-shadow-artifact-system.js.map +1 -1
  118. package/node_modules/@fps-games/babylon-renderer/dist/shadows/static-projected-shadow-baker.js +8 -1
  119. package/node_modules/@fps-games/babylon-renderer/dist/shadows/static-projected-shadow-baker.js.map +1 -1
  120. package/node_modules/@fps-games/babylon-renderer/dist/shadows/types.d.ts +53 -2
  121. package/node_modules/@fps-games/babylon-renderer/dist/shadows/types.d.ts.map +1 -1
  122. package/node_modules/@fps-games/babylon-renderer/dist/shadows/types.js +1 -0
  123. package/node_modules/@fps-games/babylon-renderer/dist/shadows/types.js.map +1 -1
  124. package/node_modules/@fps-games/babylon-renderer/package.json +1 -1
  125. package/node_modules/@fps-games/editor-babylon/dist/camera-controller.d.ts.map +1 -1
  126. package/node_modules/@fps-games/editor-babylon/dist/camera-controller.js +11 -0
  127. package/node_modules/@fps-games/editor-babylon/dist/camera-controller.js.map +1 -1
  128. package/node_modules/@fps-games/editor-babylon/dist/editor-sky.d.ts +3 -1
  129. package/node_modules/@fps-games/editor-babylon/dist/editor-sky.d.ts.map +1 -1
  130. package/node_modules/@fps-games/editor-babylon/dist/editor-sky.js +114 -18
  131. package/node_modules/@fps-games/editor-babylon/dist/editor-sky.js.map +1 -1
  132. package/node_modules/@fps-games/editor-babylon/dist/editor-world.d.ts +1 -0
  133. package/node_modules/@fps-games/editor-babylon/dist/editor-world.d.ts.map +1 -1
  134. package/node_modules/@fps-games/editor-babylon/dist/editor-world.js +3 -0
  135. package/node_modules/@fps-games/editor-babylon/dist/editor-world.js.map +1 -1
  136. package/node_modules/@fps-games/editor-babylon/dist/index.d.ts +3 -0
  137. package/node_modules/@fps-games/editor-babylon/dist/index.d.ts.map +1 -1
  138. package/node_modules/@fps-games/editor-babylon/dist/index.js +3 -0
  139. package/node_modules/@fps-games/editor-babylon/dist/index.js.map +1 -1
  140. package/node_modules/@fps-games/editor-babylon/dist/marker-overlay.d.ts +52 -0
  141. package/node_modules/@fps-games/editor-babylon/dist/marker-overlay.d.ts.map +1 -0
  142. package/node_modules/@fps-games/editor-babylon/dist/marker-overlay.js +1395 -0
  143. package/node_modules/@fps-games/editor-babylon/dist/marker-overlay.js.map +1 -0
  144. package/node_modules/@fps-games/editor-babylon/dist/material-property-adapter.d.ts.map +1 -1
  145. package/node_modules/@fps-games/editor-babylon/dist/material-property-adapter.js +4 -65
  146. package/node_modules/@fps-games/editor-babylon/dist/material-property-adapter.js.map +1 -1
  147. package/node_modules/@fps-games/editor-babylon/dist/material-slot-source-resolver.d.ts +28 -0
  148. package/node_modules/@fps-games/editor-babylon/dist/material-slot-source-resolver.d.ts.map +1 -0
  149. package/node_modules/@fps-games/editor-babylon/dist/material-slot-source-resolver.js +235 -0
  150. package/node_modules/@fps-games/editor-babylon/dist/material-slot-source-resolver.js.map +1 -0
  151. package/node_modules/@fps-games/editor-babylon/dist/prefab-comparison-preview-controller.d.ts +37 -0
  152. package/node_modules/@fps-games/editor-babylon/dist/prefab-comparison-preview-controller.d.ts.map +1 -0
  153. package/node_modules/@fps-games/editor-babylon/dist/prefab-comparison-preview-controller.js +451 -0
  154. package/node_modules/@fps-games/editor-babylon/dist/prefab-comparison-preview-controller.js.map +1 -0
  155. package/node_modules/@fps-games/editor-babylon/dist/projection-asset-container-importer.d.ts.map +1 -1
  156. package/node_modules/@fps-games/editor-babylon/dist/projection-asset-container-importer.js +14 -3
  157. package/node_modules/@fps-games/editor-babylon/dist/projection-asset-container-importer.js.map +1 -1
  158. package/node_modules/@fps-games/editor-babylon/dist/projection-pick-resolver.d.ts +1 -0
  159. package/node_modules/@fps-games/editor-babylon/dist/projection-pick-resolver.d.ts.map +1 -1
  160. package/node_modules/@fps-games/editor-babylon/dist/projection-pick-resolver.js +20 -4
  161. package/node_modules/@fps-games/editor-babylon/dist/projection-pick-resolver.js.map +1 -1
  162. package/node_modules/@fps-games/editor-babylon/dist/projection-source-owner-path.d.ts +3 -6
  163. package/node_modules/@fps-games/editor-babylon/dist/projection-source-owner-path.d.ts.map +1 -1
  164. package/node_modules/@fps-games/editor-babylon/dist/projection-source-owner-path.js +4 -37
  165. package/node_modules/@fps-games/editor-babylon/dist/projection-source-owner-path.js.map +1 -1
  166. package/node_modules/@fps-games/editor-babylon/dist/projection.d.ts +74 -1
  167. package/node_modules/@fps-games/editor-babylon/dist/projection.d.ts.map +1 -1
  168. package/node_modules/@fps-games/editor-babylon/dist/projection.js +641 -52
  169. package/node_modules/@fps-games/editor-babylon/dist/projection.js.map +1 -1
  170. package/node_modules/@fps-games/editor-babylon/dist/scene-view-camera-controller.d.ts +11 -0
  171. package/node_modules/@fps-games/editor-babylon/dist/scene-view-camera-controller.d.ts.map +1 -1
  172. package/node_modules/@fps-games/editor-babylon/dist/scene-view-camera-controller.js +113 -29
  173. package/node_modules/@fps-games/editor-babylon/dist/scene-view-camera-controller.js.map +1 -1
  174. package/node_modules/@fps-games/editor-babylon/dist/shadow-preview-controller.d.ts +13 -1
  175. package/node_modules/@fps-games/editor-babylon/dist/shadow-preview-controller.d.ts.map +1 -1
  176. package/node_modules/@fps-games/editor-babylon/dist/shadow-preview-controller.js +543 -3
  177. package/node_modules/@fps-games/editor-babylon/dist/shadow-preview-controller.js.map +1 -1
  178. package/node_modules/@fps-games/editor-babylon/package.json +5 -5
  179. package/node_modules/@fps-games/editor-browser/dist/index.d.ts +8 -2
  180. package/node_modules/@fps-games/editor-browser/dist/index.d.ts.map +1 -1
  181. package/node_modules/@fps-games/editor-browser/dist/index.js +4 -0
  182. package/node_modules/@fps-games/editor-browser/dist/index.js.map +1 -1
  183. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-asset-kind.d.ts +5 -0
  184. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-asset-kind.d.ts.map +1 -0
  185. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-asset-kind.js +23 -0
  186. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-asset-kind.js.map +1 -0
  187. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-context-menu.js +1 -1
  188. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-context-menu.js.map +1 -1
  189. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-actions.d.ts.map +1 -1
  190. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-actions.js +76 -9
  191. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-actions.js.map +1 -1
  192. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-attach-dialog.d.ts.map +1 -1
  193. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-attach-dialog.js +3 -2
  194. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-attach-dialog.js.map +1 -1
  195. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-command-adapter.d.ts +21 -0
  196. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-command-adapter.d.ts.map +1 -0
  197. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-command-adapter.js +75 -0
  198. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-command-adapter.js.map +1 -0
  199. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-controller.d.ts +2 -0
  200. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-controller.d.ts.map +1 -1
  201. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-controller.js +326 -72
  202. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-controller.js.map +1 -1
  203. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-scope.d.ts +5 -0
  204. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-scope.d.ts.map +1 -0
  205. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-scope.js +92 -0
  206. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-scope.js.map +1 -0
  207. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-tree.d.ts +4 -1
  208. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-tree.d.ts.map +1 -1
  209. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-tree.js +22 -7
  210. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-tree.js.map +1 -1
  211. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-view.d.ts +4 -0
  212. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-view.d.ts.map +1 -1
  213. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-view.js +24 -11
  214. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-view.js.map +1 -1
  215. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-icons.d.ts +1 -1
  216. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-icons.d.ts.map +1 -1
  217. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-icons.js +7 -0
  218. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-icons.js.map +1 -1
  219. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-panel-registry.js +1 -1
  220. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-panel-registry.js.map +1 -1
  221. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-panels.d.ts +4 -0
  222. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-panels.d.ts.map +1 -1
  223. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-panels.js +1471 -29
  224. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-panels.js.map +1 -1
  225. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-prefab-stage.d.ts +70 -0
  226. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-prefab-stage.d.ts.map +1 -0
  227. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-prefab-stage.js +171 -0
  228. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-prefab-stage.js.map +1 -0
  229. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-primitives.d.ts +1 -1
  230. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-primitives.d.ts.map +1 -1
  231. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-primitives.js +2 -2
  232. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-primitives.js.map +1 -1
  233. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-shared.d.ts.map +1 -1
  234. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-shared.js +9 -2
  235. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-shared.js.map +1 -1
  236. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-types.d.ts +301 -3
  237. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-types.d.ts.map +1 -1
  238. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-workbench.d.ts +12 -1
  239. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-workbench.d.ts.map +1 -1
  240. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-workbench.js +13 -1
  241. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-workbench.js.map +1 -1
  242. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui.d.ts +6 -4
  243. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui.d.ts.map +1 -1
  244. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui.js +1501 -122
  245. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui.js.map +1 -1
  246. package/node_modules/@fps-games/editor-browser/package.json +3 -3
  247. package/node_modules/@fps-games/editor-core/dist/agent-bridge.d.ts +18 -0
  248. package/node_modules/@fps-games/editor-core/dist/agent-bridge.d.ts.map +1 -0
  249. package/node_modules/@fps-games/editor-core/dist/agent-bridge.js +102 -0
  250. package/node_modules/@fps-games/editor-core/dist/agent-bridge.js.map +1 -0
  251. package/node_modules/@fps-games/editor-core/dist/index.d.ts +1 -0
  252. package/node_modules/@fps-games/editor-core/dist/index.d.ts.map +1 -1
  253. package/node_modules/@fps-games/editor-core/dist/index.js +1 -0
  254. package/node_modules/@fps-games/editor-core/dist/index.js.map +1 -1
  255. package/node_modules/@fps-games/editor-core/dist/scene-graph.d.ts +1 -1
  256. package/node_modules/@fps-games/editor-core/dist/scene-graph.d.ts.map +1 -1
  257. package/node_modules/@fps-games/editor-core/dist/viewport-tools.d.ts +3 -1
  258. package/node_modules/@fps-games/editor-core/dist/viewport-tools.d.ts.map +1 -1
  259. package/node_modules/@fps-games/editor-core/dist/viewport-tools.js +1 -0
  260. package/node_modules/@fps-games/editor-core/dist/viewport-tools.js.map +1 -1
  261. package/node_modules/@fps-games/editor-core/package.json +2 -2
  262. package/node_modules/@fps-games/editor-forge-play/package.json +2 -2
  263. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-database/config.d.ts +3 -0
  264. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-database/config.d.ts.map +1 -0
  265. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-database/config.js +9 -0
  266. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-database/config.js.map +1 -0
  267. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-database/generated-module.d.ts +6 -0
  268. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-database/generated-module.d.ts.map +1 -0
  269. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-database/generated-module.js +89 -0
  270. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-database/generated-module.js.map +1 -0
  271. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-database/identity.d.ts +18 -0
  272. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-database/identity.d.ts.map +1 -0
  273. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-database/identity.js +121 -0
  274. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-database/identity.js.map +1 -0
  275. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-database/index.d.ts +4 -0
  276. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-database/index.d.ts.map +1 -0
  277. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-database/index.js +3 -0
  278. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-database/index.js.map +1 -0
  279. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-database/metadata.d.ts +27 -0
  280. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-database/metadata.d.ts.map +1 -0
  281. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-database/metadata.js +782 -0
  282. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-database/metadata.js.map +1 -0
  283. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-database/node.d.ts +5 -0
  284. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-database/node.d.ts.map +1 -0
  285. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-database/node.js +5 -0
  286. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-database/node.js.map +1 -0
  287. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-database/registry.d.ts +80 -0
  288. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-database/registry.d.ts.map +1 -0
  289. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-database/registry.js +600 -0
  290. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-database/registry.js.map +1 -0
  291. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-database/types.d.ts +51 -0
  292. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-database/types.d.ts.map +1 -0
  293. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-database/types.js +2 -0
  294. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-database/types.js.map +1 -0
  295. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-library/catalog.d.ts.map +1 -1
  296. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-library/catalog.js +17 -3
  297. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-library/catalog.js.map +1 -1
  298. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-library/document.d.ts.map +1 -1
  299. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-library/document.js +2 -1
  300. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-library/document.js.map +1 -1
  301. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-library/types.d.ts +3 -2
  302. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-library/types.d.ts.map +1 -1
  303. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-placement/document.d.ts +1 -1
  304. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-placement/document.d.ts.map +1 -1
  305. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-placement/document.js +48 -20
  306. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-placement/document.js.map +1 -1
  307. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-placement/index.d.ts +1 -1
  308. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-placement/index.d.ts.map +1 -1
  309. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-placement/index.js +1 -1
  310. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-placement/index.js.map +1 -1
  311. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-placement/placement.d.ts.map +1 -1
  312. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-placement/placement.js +2 -1
  313. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-placement/placement.js.map +1 -1
  314. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-placement/types.d.ts +3 -0
  315. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-placement/types.d.ts.map +1 -1
  316. package/node_modules/@fps-games/editor-playable-sdk/dist/document/helpers.d.ts +97 -2
  317. package/node_modules/@fps-games/editor-playable-sdk/dist/document/helpers.d.ts.map +1 -1
  318. package/node_modules/@fps-games/editor-playable-sdk/dist/document/helpers.js +1143 -8
  319. package/node_modules/@fps-games/editor-playable-sdk/dist/document/helpers.js.map +1 -1
  320. package/node_modules/@fps-games/editor-playable-sdk/dist/document/types.d.ts +145 -2
  321. package/node_modules/@fps-games/editor-playable-sdk/dist/document/types.d.ts.map +1 -1
  322. package/node_modules/@fps-games/editor-playable-sdk/dist/field-schema/index.d.ts +1 -1
  323. package/node_modules/@fps-games/editor-playable-sdk/dist/field-schema/index.d.ts.map +1 -1
  324. package/node_modules/@fps-games/editor-playable-sdk/dist/field-schema/index.js +1 -1
  325. package/node_modules/@fps-games/editor-playable-sdk/dist/field-schema/index.js.map +1 -1
  326. package/node_modules/@fps-games/editor-playable-sdk/dist/field-schema/schema.d.ts.map +1 -1
  327. package/node_modules/@fps-games/editor-playable-sdk/dist/field-schema/schema.js +24 -9
  328. package/node_modules/@fps-games/editor-playable-sdk/dist/field-schema/schema.js.map +1 -1
  329. package/node_modules/@fps-games/editor-playable-sdk/dist/field-schema/validators.d.ts +6 -0
  330. package/node_modules/@fps-games/editor-playable-sdk/dist/field-schema/validators.d.ts.map +1 -1
  331. package/node_modules/@fps-games/editor-playable-sdk/dist/field-schema/validators.js +31 -0
  332. package/node_modules/@fps-games/editor-playable-sdk/dist/field-schema/validators.js.map +1 -1
  333. package/node_modules/@fps-games/editor-playable-sdk/dist/index.d.ts +3 -0
  334. package/node_modules/@fps-games/editor-playable-sdk/dist/index.d.ts.map +1 -1
  335. package/node_modules/@fps-games/editor-playable-sdk/dist/index.js +3 -0
  336. package/node_modules/@fps-games/editor-playable-sdk/dist/index.js.map +1 -1
  337. package/node_modules/@fps-games/editor-playable-sdk/dist/inspector/document-sections.d.ts +82 -2
  338. package/node_modules/@fps-games/editor-playable-sdk/dist/inspector/document-sections.d.ts.map +1 -1
  339. package/node_modules/@fps-games/editor-playable-sdk/dist/inspector/document-sections.js +396 -22
  340. package/node_modules/@fps-games/editor-playable-sdk/dist/inspector/document-sections.js.map +1 -1
  341. package/node_modules/@fps-games/editor-playable-sdk/dist/inspector/index.d.ts +1 -1
  342. package/node_modules/@fps-games/editor-playable-sdk/dist/inspector/index.d.ts.map +1 -1
  343. package/node_modules/@fps-games/editor-playable-sdk/dist/inspector/index.js +1 -1
  344. package/node_modules/@fps-games/editor-playable-sdk/dist/inspector/index.js.map +1 -1
  345. package/node_modules/@fps-games/editor-playable-sdk/dist/inspector/validation.d.ts.map +1 -1
  346. package/node_modules/@fps-games/editor-playable-sdk/dist/inspector/validation.js +0 -3
  347. package/node_modules/@fps-games/editor-playable-sdk/dist/inspector/validation.js.map +1 -1
  348. package/node_modules/@fps-games/editor-playable-sdk/dist/lighting-debug/math.d.ts +29 -1
  349. package/node_modules/@fps-games/editor-playable-sdk/dist/lighting-debug/math.d.ts.map +1 -1
  350. package/node_modules/@fps-games/editor-playable-sdk/dist/lighting-debug/math.js +143 -0
  351. package/node_modules/@fps-games/editor-playable-sdk/dist/lighting-debug/math.js.map +1 -1
  352. package/node_modules/@fps-games/editor-playable-sdk/dist/local-harness/lifecycle.d.ts.map +1 -1
  353. package/node_modules/@fps-games/editor-playable-sdk/dist/local-harness/lifecycle.js +3 -7
  354. package/node_modules/@fps-games/editor-playable-sdk/dist/local-harness/lifecycle.js.map +1 -1
  355. package/node_modules/@fps-games/editor-playable-sdk/dist/material-binding/binding.d.ts.map +1 -1
  356. package/node_modules/@fps-games/editor-playable-sdk/dist/material-binding/binding.js +6 -0
  357. package/node_modules/@fps-games/editor-playable-sdk/dist/material-binding/binding.js.map +1 -1
  358. package/node_modules/@fps-games/editor-playable-sdk/dist/material-binding/types.d.ts +2 -10
  359. package/node_modules/@fps-games/editor-playable-sdk/dist/material-binding/types.d.ts.map +1 -1
  360. package/node_modules/@fps-games/editor-playable-sdk/dist/mutation/field-patch.d.ts.map +1 -1
  361. package/node_modules/@fps-games/editor-playable-sdk/dist/mutation/field-patch.js +107 -11
  362. package/node_modules/@fps-games/editor-playable-sdk/dist/mutation/field-patch.js.map +1 -1
  363. package/node_modules/@fps-games/editor-playable-sdk/dist/mutation/reducer.d.ts.map +1 -1
  364. package/node_modules/@fps-games/editor-playable-sdk/dist/mutation/reducer.js +4 -1
  365. package/node_modules/@fps-games/editor-playable-sdk/dist/mutation/reducer.js.map +1 -1
  366. package/node_modules/@fps-games/editor-playable-sdk/dist/mutation/transform.d.ts.map +1 -1
  367. package/node_modules/@fps-games/editor-playable-sdk/dist/mutation/transform.js +19 -1
  368. package/node_modules/@fps-games/editor-playable-sdk/dist/mutation/transform.js.map +1 -1
  369. package/node_modules/@fps-games/editor-playable-sdk/dist/rendering-profile/panel.d.ts.map +1 -1
  370. package/node_modules/@fps-games/editor-playable-sdk/dist/rendering-profile/panel.js +19 -3
  371. package/node_modules/@fps-games/editor-playable-sdk/dist/rendering-profile/panel.js.map +1 -1
  372. package/node_modules/@fps-games/editor-playable-sdk/dist/runtime-preview/assets.d.ts +1 -2
  373. package/node_modules/@fps-games/editor-playable-sdk/dist/runtime-preview/assets.d.ts.map +1 -1
  374. package/node_modules/@fps-games/editor-playable-sdk/dist/runtime-preview/assets.js +0 -14
  375. package/node_modules/@fps-games/editor-playable-sdk/dist/runtime-preview/assets.js.map +1 -1
  376. package/node_modules/@fps-games/editor-playable-sdk/dist/runtime-preview/import-plan.d.ts +1 -7
  377. package/node_modules/@fps-games/editor-playable-sdk/dist/runtime-preview/import-plan.d.ts.map +1 -1
  378. package/node_modules/@fps-games/editor-playable-sdk/dist/runtime-preview/import-plan.js +3 -32
  379. package/node_modules/@fps-games/editor-playable-sdk/dist/runtime-preview/import-plan.js.map +1 -1
  380. package/node_modules/@fps-games/editor-playable-sdk/dist/runtime-preview/nodes.d.ts.map +1 -1
  381. package/node_modules/@fps-games/editor-playable-sdk/dist/runtime-preview/nodes.js +82 -63
  382. package/node_modules/@fps-games/editor-playable-sdk/dist/runtime-preview/nodes.js.map +1 -1
  383. package/node_modules/@fps-games/editor-playable-sdk/dist/runtime-preview/types.d.ts +7 -23
  384. package/node_modules/@fps-games/editor-playable-sdk/dist/runtime-preview/types.d.ts.map +1 -1
  385. package/node_modules/@fps-games/editor-playable-sdk/dist/scene-compiler/compiler.d.ts +5 -0
  386. package/node_modules/@fps-games/editor-playable-sdk/dist/scene-compiler/compiler.d.ts.map +1 -0
  387. package/node_modules/@fps-games/editor-playable-sdk/dist/scene-compiler/compiler.js +996 -0
  388. package/node_modules/@fps-games/editor-playable-sdk/dist/scene-compiler/compiler.js.map +1 -0
  389. package/node_modules/@fps-games/editor-playable-sdk/dist/scene-compiler/index.d.ts +3 -0
  390. package/node_modules/@fps-games/editor-playable-sdk/dist/scene-compiler/index.d.ts.map +1 -0
  391. package/node_modules/@fps-games/editor-playable-sdk/dist/scene-compiler/index.js +3 -0
  392. package/node_modules/@fps-games/editor-playable-sdk/dist/scene-compiler/index.js.map +1 -0
  393. package/node_modules/@fps-games/editor-playable-sdk/dist/scene-compiler/types.d.ts +152 -0
  394. package/node_modules/@fps-games/editor-playable-sdk/dist/scene-compiler/types.d.ts.map +1 -0
  395. package/node_modules/@fps-games/editor-playable-sdk/dist/scene-compiler/types.js +2 -0
  396. package/node_modules/@fps-games/editor-playable-sdk/dist/scene-compiler/types.js.map +1 -0
  397. package/node_modules/@fps-games/editor-playable-sdk/dist/scene-source/protocol.d.ts.map +1 -1
  398. package/node_modules/@fps-games/editor-playable-sdk/dist/scene-source/protocol.js +44 -2
  399. package/node_modules/@fps-games/editor-playable-sdk/dist/scene-source/protocol.js.map +1 -1
  400. package/node_modules/@fps-games/editor-playable-sdk/dist/serialized-property/descriptors.d.ts +1 -0
  401. package/node_modules/@fps-games/editor-playable-sdk/dist/serialized-property/descriptors.d.ts.map +1 -1
  402. package/node_modules/@fps-games/editor-playable-sdk/dist/serialized-property/descriptors.js +244 -12
  403. package/node_modules/@fps-games/editor-playable-sdk/dist/serialized-property/descriptors.js.map +1 -1
  404. package/node_modules/@fps-games/editor-playable-sdk/dist/serialized-property/inspector.d.ts.map +1 -1
  405. package/node_modules/@fps-games/editor-playable-sdk/dist/serialized-property/inspector.js +216 -67
  406. package/node_modules/@fps-games/editor-playable-sdk/dist/serialized-property/inspector.js.map +1 -1
  407. package/node_modules/@fps-games/editor-playable-sdk/dist/serialized-property/object.d.ts.map +1 -1
  408. package/node_modules/@fps-games/editor-playable-sdk/dist/serialized-property/object.js +7 -4
  409. package/node_modules/@fps-games/editor-playable-sdk/dist/serialized-property/object.js.map +1 -1
  410. package/node_modules/@fps-games/editor-playable-sdk/dist/serialized-property/patch.d.ts.map +1 -1
  411. package/node_modules/@fps-games/editor-playable-sdk/dist/serialized-property/patch.js +45 -1
  412. package/node_modules/@fps-games/editor-playable-sdk/dist/serialized-property/patch.js.map +1 -1
  413. package/node_modules/@fps-games/editor-playable-sdk/dist/session/hierarchy.d.ts.map +1 -1
  414. package/node_modules/@fps-games/editor-playable-sdk/dist/session/hierarchy.js +2 -1
  415. package/node_modules/@fps-games/editor-playable-sdk/dist/session/hierarchy.js.map +1 -1
  416. package/node_modules/@fps-games/editor-playable-sdk/dist/shadow-system/index.d.ts +5 -0
  417. package/node_modules/@fps-games/editor-playable-sdk/dist/shadow-system/index.d.ts.map +1 -0
  418. package/node_modules/@fps-games/editor-playable-sdk/dist/shadow-system/index.js +5 -0
  419. package/node_modules/@fps-games/editor-playable-sdk/dist/shadow-system/index.js.map +1 -0
  420. package/node_modules/@fps-games/editor-playable-sdk/dist/shadow-system/legacy.d.ts +21 -0
  421. package/node_modules/@fps-games/editor-playable-sdk/dist/shadow-system/legacy.d.ts.map +1 -0
  422. package/node_modules/@fps-games/editor-playable-sdk/dist/shadow-system/legacy.js +158 -0
  423. package/node_modules/@fps-games/editor-playable-sdk/dist/shadow-system/legacy.js.map +1 -0
  424. package/node_modules/@fps-games/editor-playable-sdk/dist/shadow-system/quality.d.ts +5 -0
  425. package/node_modules/@fps-games/editor-playable-sdk/dist/shadow-system/quality.d.ts.map +1 -0
  426. package/node_modules/@fps-games/editor-playable-sdk/dist/shadow-system/quality.js +83 -0
  427. package/node_modules/@fps-games/editor-playable-sdk/dist/shadow-system/quality.js.map +1 -0
  428. package/node_modules/@fps-games/editor-playable-sdk/dist/shadow-system/resolver.d.ts +35 -0
  429. package/node_modules/@fps-games/editor-playable-sdk/dist/shadow-system/resolver.d.ts.map +1 -0
  430. package/node_modules/@fps-games/editor-playable-sdk/dist/shadow-system/resolver.js +363 -0
  431. package/node_modules/@fps-games/editor-playable-sdk/dist/shadow-system/resolver.js.map +1 -0
  432. package/node_modules/@fps-games/editor-playable-sdk/dist/shadow-system/types.d.ts +105 -0
  433. package/node_modules/@fps-games/editor-playable-sdk/dist/shadow-system/types.d.ts.map +1 -0
  434. package/node_modules/@fps-games/editor-playable-sdk/dist/shadow-system/types.js +6 -0
  435. package/node_modules/@fps-games/editor-playable-sdk/dist/shadow-system/types.js.map +1 -0
  436. package/node_modules/@fps-games/editor-playable-sdk/dist/static-shadows/artifact.d.ts +3 -0
  437. package/node_modules/@fps-games/editor-playable-sdk/dist/static-shadows/artifact.d.ts.map +1 -1
  438. package/node_modules/@fps-games/editor-playable-sdk/dist/static-shadows/artifact.js +44 -0
  439. package/node_modules/@fps-games/editor-playable-sdk/dist/static-shadows/artifact.js.map +1 -1
  440. package/node_modules/@fps-games/editor-playable-sdk/dist/vite/asset-authoring.d.ts +26 -0
  441. package/node_modules/@fps-games/editor-playable-sdk/dist/vite/asset-authoring.d.ts.map +1 -0
  442. package/node_modules/@fps-games/editor-playable-sdk/dist/vite/asset-authoring.js +105 -0
  443. package/node_modules/@fps-games/editor-playable-sdk/dist/vite/asset-authoring.js.map +1 -0
  444. package/node_modules/@fps-games/editor-playable-sdk/dist/vite/index.d.ts +3 -0
  445. package/node_modules/@fps-games/editor-playable-sdk/dist/vite/index.d.ts.map +1 -1
  446. package/node_modules/@fps-games/editor-playable-sdk/dist/vite/index.js +3 -0
  447. package/node_modules/@fps-games/editor-playable-sdk/dist/vite/index.js.map +1 -1
  448. package/node_modules/@fps-games/editor-playable-sdk/package.json +3 -3
  449. package/node_modules/@fps-games/editor-protocol/dist/agent-bridge.d.ts +1127 -0
  450. package/node_modules/@fps-games/editor-protocol/dist/agent-bridge.d.ts.map +1 -0
  451. package/node_modules/@fps-games/editor-protocol/dist/agent-bridge.js +2180 -0
  452. package/node_modules/@fps-games/editor-protocol/dist/agent-bridge.js.map +1 -0
  453. package/node_modules/@fps-games/editor-protocol/dist/agent-trace.d.ts +68 -0
  454. package/node_modules/@fps-games/editor-protocol/dist/agent-trace.d.ts.map +1 -0
  455. package/node_modules/@fps-games/editor-protocol/dist/agent-trace.js +23 -0
  456. package/node_modules/@fps-games/editor-protocol/dist/agent-trace.js.map +1 -0
  457. package/node_modules/@fps-games/editor-protocol/dist/agent.d.ts +57 -3
  458. package/node_modules/@fps-games/editor-protocol/dist/agent.d.ts.map +1 -1
  459. package/node_modules/@fps-games/editor-protocol/dist/agent.js.map +1 -1
  460. package/node_modules/@fps-games/editor-protocol/dist/index.d.ts +21 -0
  461. package/node_modules/@fps-games/editor-protocol/dist/index.d.ts.map +1 -1
  462. package/node_modules/@fps-games/editor-protocol/dist/index.js +3 -0
  463. package/node_modules/@fps-games/editor-protocol/dist/index.js.map +1 -1
  464. package/node_modules/@fps-games/editor-protocol/dist/marker-graph.d.ts +128 -0
  465. package/node_modules/@fps-games/editor-protocol/dist/marker-graph.d.ts.map +1 -0
  466. package/node_modules/@fps-games/editor-protocol/dist/marker-graph.js +2 -0
  467. package/node_modules/@fps-games/editor-protocol/dist/marker-graph.js.map +1 -0
  468. package/node_modules/@fps-games/editor-protocol/package.json +1 -1
  469. package/package.json +8 -8
@@ -1,3 +1,20 @@
1
+ import { mergeArtistMaterialProfiles, } from '@fps-games/editor-protocol';
2
+ import { isEditorSceneArtistMaterialPatchPath, normalizeEditorSceneMaterialSlotOwnerPath, readEditorSceneChildMaterialBindingOwnerPath, readEditorSceneMaterialSlotBindingSlotId, } from '../material-binding/paths.js';
3
+ export const EDITOR_SCENE_PREFAB_COMPOSITION_VERSION = 1;
4
+ export const EDITOR_SCENE_PREFAB_LEGACY_ROOT_NODE_ID = 'prefab-root';
5
+ export const EDITOR_SCENE_PREFAB_LEGACY_MODEL_NODE_ID = 'prefab-model';
6
+ const EDITOR_SCENE_PREFAB_OVERRIDE_FIELD_PATH_PREFIX = 'prefab.';
7
+ const EDITOR_SCENE_PREFAB_CORE_MATERIAL_OVERRIDE_PROFILE_FIELD_PATHS = new Set([
8
+ 'profile.baseColor.color',
9
+ 'profile.baseColor.texture.textureAssetId',
10
+ 'profile.normal.texture.textureAssetId',
11
+ 'profile.normal.strength',
12
+ 'profile.metallic',
13
+ 'profile.roughness',
14
+ 'profile.emission.color',
15
+ 'profile.emission.intensity',
16
+ 'profile.emission.texture.textureAssetId',
17
+ ]);
1
18
  export function cloneEditorSceneDocument(document) {
2
19
  return structuredClone(document);
3
20
  }
@@ -7,6 +24,932 @@ export function findEditorSceneTransform(gameObject) {
7
24
  export function findEditorSceneModelRenderer(gameObject) {
8
25
  return gameObject.components.find(isEditorSceneModelRendererComponent) ?? null;
9
26
  }
27
+ export function isEditorScenePrefabAsset(asset) {
28
+ return asset?.type === 'prefab' && readEditorSceneNonEmptyString(asset.prefab?.sourceAssetId) != null;
29
+ }
30
+ export function isEditorScenePrefabInstance(gameObject) {
31
+ return readEditorSceneNonEmptyString(gameObject?.prefab?.prefabId) != null;
32
+ }
33
+ export function resolveEditorScenePrefabSourceAssetId(prefabAsset) {
34
+ return readEditorSceneNonEmptyString(prefabAsset?.prefab?.sourceAssetId);
35
+ }
36
+ export function readEditorScenePrefabRootNodeId(prefabAsset) {
37
+ if (!prefabAsset?.prefab)
38
+ return null;
39
+ const nodes = readEditorScenePrefabExplicitNodes(prefabAsset.prefab);
40
+ const explicitRootNodeId = readEditorSceneNonEmptyString(prefabAsset.prefab.rootNodeId);
41
+ if (explicitRootNodeId && nodes.some(node => node.id === explicitRootNodeId))
42
+ return explicitRootNodeId;
43
+ const explicitRoot = nodes.find(node => node.kind === 'root' && !node.parentId);
44
+ if (explicitRoot)
45
+ return explicitRoot.id;
46
+ if (nodes.length > 0)
47
+ return null;
48
+ const legacyRoot = createEditorScenePrefabLegacyRootNode(prefabAsset);
49
+ return legacyRoot ? legacyRoot.id : null;
50
+ }
51
+ export function readEditorScenePrefabNodes(prefabAsset) {
52
+ if (!prefabAsset?.prefab)
53
+ return [];
54
+ const explicitNodes = readEditorScenePrefabExplicitNodes(prefabAsset.prefab);
55
+ if (explicitNodes.length > 0)
56
+ return explicitNodes;
57
+ return createEditorScenePrefabLegacyCompositionNodes(prefabAsset);
58
+ }
59
+ export function findEditorScenePrefabNode(prefabAsset, nodeId) {
60
+ const normalizedNodeId = readEditorSceneNonEmptyString(nodeId);
61
+ if (!normalizedNodeId)
62
+ return null;
63
+ return readEditorScenePrefabNodes(prefabAsset).find(node => node.id === normalizedNodeId) ?? null;
64
+ }
65
+ export function readEditorScenePrefabNodeChildren(prefabAsset, parentNodeId) {
66
+ const normalizedParentId = readEditorSceneNonEmptyString(parentNodeId);
67
+ return readEditorScenePrefabNodes(prefabAsset).filter((node) => {
68
+ const parentId = readEditorSceneNonEmptyString(node.parentId);
69
+ return normalizedParentId ? parentId === normalizedParentId : !parentId;
70
+ });
71
+ }
72
+ export function ensureEditorScenePrefabComposition(prefabAsset) {
73
+ if (!isEditorScenePrefabAsset(prefabAsset)) {
74
+ return createEditorScenePrefabMutationResult(prefabAsset, false, null, [{
75
+ code: 'prefab.invalidDefinition',
76
+ severity: 'error',
77
+ message: `Asset "${prefabAsset.id}" is not a valid prefab definition.`,
78
+ assetId: prefabAsset.id,
79
+ }]);
80
+ }
81
+ const next = cloneEditorScenePrefabAssetWithComposition(prefabAsset);
82
+ return createEditorScenePrefabMutationResult(next, JSON.stringify(next.prefab) !== JSON.stringify(prefabAsset.prefab));
83
+ }
84
+ export function selectEditorScenePrefabNode(prefabAsset, nodeId) {
85
+ const prepared = ensureEditorScenePrefabComposition(prefabAsset);
86
+ if (!prepared.ok)
87
+ return prepared;
88
+ const normalizedNodeId = readEditorSceneNonEmptyString(nodeId);
89
+ const node = normalizedNodeId ? findEditorScenePrefabNode(prepared.prefabAsset, normalizedNodeId) : null;
90
+ if (!node) {
91
+ return createEditorScenePrefabMutationResult(prepared.prefabAsset, false, null, [{
92
+ code: 'prefab.nodeNotFound',
93
+ severity: 'error',
94
+ message: `Prefab node "${nodeId}" was not found.`,
95
+ assetId: prefabAsset.id,
96
+ nodeId,
97
+ }]);
98
+ }
99
+ return createEditorScenePrefabMutationResult(prepared.prefabAsset, false, node, [], {
100
+ selectedNodeId: node.id,
101
+ });
102
+ }
103
+ export function renameEditorScenePrefabAsset(document, assetId, displayName) {
104
+ const normalizedAssetId = readEditorSceneNonEmptyString(assetId);
105
+ const prefabAsset = normalizedAssetId
106
+ ? document.assets.find(asset => asset.id === normalizedAssetId && isEditorScenePrefabAsset(asset))
107
+ : null;
108
+ if (!prefabAsset) {
109
+ return createEditorScenePrefabMutationResult({
110
+ id: normalizedAssetId ?? String(assetId ?? ''),
111
+ type: 'prefab',
112
+ prefab: { sourceAssetId: '' },
113
+ }, false, null, [{
114
+ code: 'prefab.invalidDefinition',
115
+ severity: 'error',
116
+ message: `Prefab asset "${assetId}" was not found.`,
117
+ assetId,
118
+ }]);
119
+ }
120
+ const nameResult = normalizeEditorScenePrefabEditableName(displayName);
121
+ if (!nameResult.ok) {
122
+ return createEditorScenePrefabMutationResult(prefabAsset, false, null, [{
123
+ code: 'prefab.invalidName',
124
+ severity: 'error',
125
+ message: nameResult.message,
126
+ assetId: prefabAsset.id,
127
+ }]);
128
+ }
129
+ const normalizedDisplayName = nameResult.name;
130
+ const lowerName = normalizedDisplayName.toLowerCase();
131
+ const conflict = document.assets.find(candidate => (candidate.id !== prefabAsset.id
132
+ && isEditorScenePrefabAsset(candidate)
133
+ && readEditorSceneNonEmptyString(candidate.displayName)?.toLowerCase() === lowerName));
134
+ if (conflict) {
135
+ return createEditorScenePrefabMutationResult(prefabAsset, false, null, [{
136
+ code: 'prefab.nameConflict',
137
+ severity: 'error',
138
+ message: `Prefab asset name "${normalizedDisplayName}" is already used by "${conflict.id}".`,
139
+ assetId: prefabAsset.id,
140
+ }]);
141
+ }
142
+ if (prefabAsset.displayName === normalizedDisplayName) {
143
+ return createEditorScenePrefabMutationResult(prefabAsset, false);
144
+ }
145
+ const next = cloneEditorScenePrefabAssetWithComposition({
146
+ ...structuredClone(prefabAsset),
147
+ displayName: normalizedDisplayName,
148
+ });
149
+ const rootNodeId = readEditorScenePrefabRootNodeId(next);
150
+ if (rootNodeId && Array.isArray(next.prefab?.nodes)) {
151
+ const rootIndex = next.prefab.nodes.findIndex(node => node.id === rootNodeId);
152
+ if (rootIndex >= 0) {
153
+ next.prefab.nodes = [...next.prefab.nodes];
154
+ next.prefab.nodes[rootIndex] = {
155
+ ...structuredClone(next.prefab.nodes[rootIndex]),
156
+ name: normalizedDisplayName,
157
+ };
158
+ }
159
+ }
160
+ return createEditorScenePrefabMutationResult(next, true);
161
+ }
162
+ export function renameEditorScenePrefabNode(prefabAsset, nodeId, name) {
163
+ const prepared = ensureEditorScenePrefabComposition(prefabAsset);
164
+ if (!prepared.ok)
165
+ return prepared;
166
+ const normalizedNodeId = readEditorSceneNonEmptyString(nodeId);
167
+ const node = normalizedNodeId ? findEditorScenePrefabNode(prepared.prefabAsset, normalizedNodeId) : null;
168
+ if (!node) {
169
+ return createEditorScenePrefabMutationResult(prepared.prefabAsset, false, null, [{
170
+ code: 'prefab.nodeNotFound',
171
+ severity: 'error',
172
+ message: `Prefab node "${nodeId}" was not found.`,
173
+ assetId: prefabAsset.id,
174
+ nodeId,
175
+ }]);
176
+ }
177
+ const rootNodeId = readEditorScenePrefabRootNodeId(prepared.prefabAsset);
178
+ if (node.id === rootNodeId) {
179
+ return createEditorScenePrefabMutationResult(prepared.prefabAsset, false, node, [{
180
+ code: 'prefab.rootRenameRejected',
181
+ severity: 'error',
182
+ message: 'Prefab root node name follows the prefab asset displayName; use prefab.asset.rename instead.',
183
+ assetId: prefabAsset.id,
184
+ nodeId: node.id,
185
+ }]);
186
+ }
187
+ const nameResult = normalizeEditorScenePrefabEditableName(name);
188
+ if (!nameResult.ok) {
189
+ return createEditorScenePrefabMutationResult(prepared.prefabAsset, false, node, [{
190
+ code: 'prefab.invalidName',
191
+ severity: 'error',
192
+ message: nameResult.message,
193
+ assetId: prefabAsset.id,
194
+ nodeId: node.id,
195
+ }]);
196
+ }
197
+ const normalizedName = nameResult.name;
198
+ const siblings = readEditorScenePrefabNodeChildren(prepared.prefabAsset, node.parentId);
199
+ const conflict = siblings.find(candidate => (candidate.id !== node.id
200
+ && readEditorSceneNonEmptyString(candidate.name)?.toLowerCase() === normalizedName.toLowerCase()));
201
+ if (conflict) {
202
+ return createEditorScenePrefabMutationResult(prepared.prefabAsset, false, node, [{
203
+ code: 'prefab.nameConflict',
204
+ severity: 'error',
205
+ message: `Prefab node name "${normalizedName}" is already used by sibling "${conflict.id}".`,
206
+ assetId: prefabAsset.id,
207
+ nodeId: node.id,
208
+ parentId: node.parentId,
209
+ }]);
210
+ }
211
+ return updateEditorScenePrefabNode(prepared.prefabAsset, node.id, (candidate) => ({
212
+ ...candidate,
213
+ name: normalizedName,
214
+ }));
215
+ }
216
+ export function createEditorScenePrefabNodeFromAsset(prefabAsset, asset, options = {}) {
217
+ const prepared = ensureEditorScenePrefabComposition(prefabAsset);
218
+ if (!prepared.ok)
219
+ return prepared;
220
+ if (asset.id === prefabAsset.id) {
221
+ return createEditorScenePrefabMutationResult(prepared.prefabAsset, false, null, [{
222
+ code: 'prefab.selfReferenceRejected',
223
+ severity: 'error',
224
+ message: `Prefab "${prefabAsset.id}" cannot contain itself directly.`,
225
+ assetId: asset.id,
226
+ }]);
227
+ }
228
+ const parentResult = resolveEditorScenePrefabMutationParent(prepared.prefabAsset, options.parentId);
229
+ if (!parentResult.ok)
230
+ return createEditorScenePrefabMutationResult(prepared.prefabAsset, false, null, parentResult.diagnostics);
231
+ const nodes = readEditorScenePrefabNodes(prepared.prefabAsset);
232
+ const isChildPrefab = isEditorScenePrefabAsset(asset);
233
+ const isModel = asset.type !== 'prefab' && (asset.type === 'glb' || asset.type === 'model' || asset.type === 'gltf');
234
+ if (!isChildPrefab && !isModel) {
235
+ return createEditorScenePrefabMutationResult(prepared.prefabAsset, false, null, [{
236
+ code: 'prefab.assetUnsupported',
237
+ severity: 'error',
238
+ message: `Asset "${asset.id}" cannot be added to a prefab composition.`,
239
+ assetId: asset.id,
240
+ }]);
241
+ }
242
+ const node = {
243
+ id: options.id ?? createUniqueEditorScenePrefabNodeId(nodes, `${isChildPrefab ? 'prefab' : 'model'}-${asset.id}`),
244
+ ...(options.guid ? { guid: options.guid } : {}),
245
+ name: options.name ?? asset.displayName ?? asset.id,
246
+ parentId: parentResult.parentId,
247
+ kind: isChildPrefab ? 'prefabInstance' : 'model',
248
+ ...(options.transform ? { transform: structuredClone(options.transform) } : {}),
249
+ ...(isChildPrefab ? { childPrefabId: asset.id } : { sourceAssetId: asset.id }),
250
+ ...(readEditorSceneNonEmptyString(options.sourceNodePath) ? { sourceNodePath: readEditorSceneNonEmptyString(options.sourceNodePath) } : {}),
251
+ };
252
+ return appendEditorScenePrefabNode(prepared.prefabAsset, node);
253
+ }
254
+ export function createEditorScenePrefabPrimitiveNode(prefabAsset, options) {
255
+ const prepared = ensureEditorScenePrefabComposition(prefabAsset);
256
+ if (!prepared.ok)
257
+ return prepared;
258
+ const parentResult = resolveEditorScenePrefabMutationParent(prepared.prefabAsset, options.parentId);
259
+ if (!parentResult.ok)
260
+ return createEditorScenePrefabMutationResult(prepared.prefabAsset, false, null, parentResult.diagnostics);
261
+ const shape = readEditorSceneNonEmptyString(options.shape);
262
+ if (!shape) {
263
+ return createEditorScenePrefabMutationResult(prepared.prefabAsset, false, null, [{
264
+ code: 'prefab.assetUnsupported',
265
+ severity: 'error',
266
+ message: 'Prefab primitive shape must be a non-empty string.',
267
+ assetId: prefabAsset.id,
268
+ }]);
269
+ }
270
+ const nodes = readEditorScenePrefabNodes(prepared.prefabAsset);
271
+ const node = {
272
+ id: options.id ?? createUniqueEditorScenePrefabNodeId(nodes, `primitive-${shape}`),
273
+ ...(options.guid ? { guid: options.guid } : {}),
274
+ name: options.name ?? `${shape[0].toUpperCase()}${shape.slice(1)}`,
275
+ parentId: parentResult.parentId,
276
+ kind: 'primitive',
277
+ primitive: { shape },
278
+ ...(options.transform ? { transform: structuredClone(options.transform) } : {}),
279
+ };
280
+ return appendEditorScenePrefabNode(prepared.prefabAsset, node);
281
+ }
282
+ export function createEditorScenePrefabGroupNode(prefabAsset, options = {}) {
283
+ const prepared = ensureEditorScenePrefabComposition(prefabAsset);
284
+ if (!prepared.ok)
285
+ return prepared;
286
+ const parentResult = resolveEditorScenePrefabMutationParent(prepared.prefabAsset, options.parentId);
287
+ if (!parentResult.ok)
288
+ return createEditorScenePrefabMutationResult(prepared.prefabAsset, false, null, parentResult.diagnostics);
289
+ const nodes = readEditorScenePrefabNodes(prepared.prefabAsset);
290
+ const node = {
291
+ id: options.id ?? createUniqueEditorScenePrefabNodeId(nodes, 'group'),
292
+ ...(options.guid ? { guid: options.guid } : {}),
293
+ name: options.name ?? 'Empty',
294
+ parentId: parentResult.parentId,
295
+ kind: 'group',
296
+ ...(options.transform ? { transform: structuredClone(options.transform) } : {}),
297
+ };
298
+ return appendEditorScenePrefabNode(prepared.prefabAsset, node);
299
+ }
300
+ export function setEditorScenePrefabNodeTransform(prefabAsset, nodeId, transform) {
301
+ const prepared = ensureEditorScenePrefabComposition(prefabAsset);
302
+ if (!prepared.ok)
303
+ return prepared;
304
+ if (!transform || transform.type !== 'Transform') {
305
+ return createEditorScenePrefabMutationResult(prepared.prefabAsset, false, null, [{
306
+ code: 'prefab.invalidTransform',
307
+ severity: 'error',
308
+ message: `Prefab node "${nodeId}" requires a Transform component payload.`,
309
+ assetId: prefabAsset.id,
310
+ nodeId,
311
+ }]);
312
+ }
313
+ return updateEditorScenePrefabNode(prepared.prefabAsset, nodeId, (node) => ({
314
+ ...node,
315
+ transform: structuredClone(transform),
316
+ }));
317
+ }
318
+ export function setEditorScenePrefabNodeShadow(prefabAsset, nodeId, shadow) {
319
+ const prepared = ensureEditorScenePrefabComposition(prefabAsset);
320
+ if (!prepared.ok)
321
+ return prepared;
322
+ return updateEditorScenePrefabNode(prepared.prefabAsset, nodeId, (node) => {
323
+ const defaults = { ...(node.defaults ?? {}) };
324
+ if (shadow && Object.keys(shadow).length > 0)
325
+ defaults.shadow = structuredClone(shadow);
326
+ else
327
+ delete defaults.shadow;
328
+ if (Object.keys(defaults).length > 0)
329
+ return { ...node, defaults };
330
+ const { defaults: _defaults, ...rest } = node;
331
+ return rest;
332
+ });
333
+ }
334
+ export function reparentEditorScenePrefabNode(prefabAsset, nodeId, parentId) {
335
+ const prepared = ensureEditorScenePrefabComposition(prefabAsset);
336
+ if (!prepared.ok)
337
+ return prepared;
338
+ const rootNodeId = readEditorScenePrefabRootNodeId(prepared.prefabAsset);
339
+ if (nodeId === rootNodeId) {
340
+ return createEditorScenePrefabMutationResult(prepared.prefabAsset, false, null, [{
341
+ code: 'prefab.rootReparentRejected',
342
+ severity: 'error',
343
+ message: 'Prefab root node cannot be reparented.',
344
+ assetId: prefabAsset.id,
345
+ nodeId,
346
+ }]);
347
+ }
348
+ const nodes = readEditorScenePrefabNodes(prepared.prefabAsset);
349
+ if (!nodes.some(node => node.id === nodeId)) {
350
+ return createEditorScenePrefabMutationResult(prepared.prefabAsset, false, null, [{
351
+ code: 'prefab.nodeNotFound',
352
+ severity: 'error',
353
+ message: `Prefab node "${nodeId}" was not found.`,
354
+ assetId: prefabAsset.id,
355
+ nodeId,
356
+ }]);
357
+ }
358
+ if (!nodes.some(node => node.id === parentId)) {
359
+ return createEditorScenePrefabMutationResult(prepared.prefabAsset, false, null, [{
360
+ code: 'prefab.parentNotFound',
361
+ severity: 'error',
362
+ message: `Prefab parent node "${parentId}" was not found.`,
363
+ assetId: prefabAsset.id,
364
+ nodeId,
365
+ parentId,
366
+ }]);
367
+ }
368
+ if (nodeId === parentId || isEditorScenePrefabNodeDescendant(nodes, parentId, nodeId)) {
369
+ return createEditorScenePrefabMutationResult(prepared.prefabAsset, false, null, [{
370
+ code: 'prefab.cycleReparentRejected',
371
+ severity: 'error',
372
+ message: `Prefab node "${nodeId}" cannot be parented under its own descendant "${parentId}".`,
373
+ assetId: prefabAsset.id,
374
+ nodeId,
375
+ parentId,
376
+ }]);
377
+ }
378
+ return updateEditorScenePrefabNode(prepared.prefabAsset, nodeId, (node) => ({
379
+ ...node,
380
+ parentId,
381
+ }));
382
+ }
383
+ export function deleteEditorScenePrefabNode(prefabAsset, nodeId) {
384
+ const prepared = ensureEditorScenePrefabComposition(prefabAsset);
385
+ if (!prepared.ok)
386
+ return prepared;
387
+ const rootNodeId = readEditorScenePrefabRootNodeId(prepared.prefabAsset);
388
+ if (nodeId === rootNodeId) {
389
+ return createEditorScenePrefabMutationResult(prepared.prefabAsset, false, null, [{
390
+ code: 'prefab.rootDeleteRejected',
391
+ severity: 'error',
392
+ message: 'Prefab root node cannot be deleted.',
393
+ assetId: prefabAsset.id,
394
+ nodeId,
395
+ }]);
396
+ }
397
+ const nodes = readEditorScenePrefabNodes(prepared.prefabAsset);
398
+ const target = nodes.find(node => node.id === nodeId);
399
+ if (!target) {
400
+ return createEditorScenePrefabMutationResult(prepared.prefabAsset, false, null, [{
401
+ code: 'prefab.nodeNotFound',
402
+ severity: 'error',
403
+ message: `Prefab node "${nodeId}" was not found.`,
404
+ assetId: prefabAsset.id,
405
+ nodeId,
406
+ }]);
407
+ }
408
+ const deleted = new Set();
409
+ collectEditorScenePrefabNodeSubtree(nodes, nodeId, deleted);
410
+ const next = structuredClone(prepared.prefabAsset);
411
+ next.prefab = structuredClone(next.prefab);
412
+ next.prefab.nodes = nodes.filter(node => !deleted.has(node.id));
413
+ return createEditorScenePrefabMutationResult(next, true, target, [], {
414
+ deletedNodeIds: [...deleted],
415
+ });
416
+ }
417
+ function createEditorScenePrefabMutationResult(prefabAsset, changed, node = null, diagnostics = [], extra = {}) {
418
+ return {
419
+ ok: diagnostics.every(diagnostic => diagnostic.severity !== 'error'),
420
+ changed,
421
+ prefabAsset,
422
+ ...(extra.selectedNodeId ? { selectedNodeId: extra.selectedNodeId } : {}),
423
+ ...(extra.createdNodeId ? { createdNodeId: extra.createdNodeId } : {}),
424
+ ...(extra.deletedNodeIds ? { deletedNodeIds: [...extra.deletedNodeIds] } : {}),
425
+ ...(node ? { node: structuredClone(node) } : {}),
426
+ diagnostics: diagnostics.map(diagnostic => ({ ...diagnostic })),
427
+ };
428
+ }
429
+ function cloneEditorScenePrefabAssetWithComposition(prefabAsset) {
430
+ const next = structuredClone(prefabAsset);
431
+ const nodes = readEditorScenePrefabNodes(prefabAsset);
432
+ next.prefab = structuredClone(next.prefab);
433
+ next.prefab.compositionVersion = EDITOR_SCENE_PREFAB_COMPOSITION_VERSION;
434
+ next.prefab.nodes = nodes;
435
+ const rootNodeId = readEditorScenePrefabRootNodeId({ ...prefabAsset, prefab: { ...prefabAsset.prefab, nodes } });
436
+ if (rootNodeId)
437
+ next.prefab.rootNodeId = rootNodeId;
438
+ else
439
+ delete next.prefab.rootNodeId;
440
+ return next;
441
+ }
442
+ function resolveEditorScenePrefabMutationParent(prefabAsset, parentId) {
443
+ const rootNodeId = readEditorScenePrefabRootNodeId(prefabAsset);
444
+ const normalizedParentId = readEditorSceneNonEmptyString(parentId) ?? rootNodeId;
445
+ if (!normalizedParentId || !findEditorScenePrefabNode(prefabAsset, normalizedParentId)) {
446
+ return {
447
+ ok: false,
448
+ diagnostics: [{
449
+ code: 'prefab.parentNotFound',
450
+ severity: 'error',
451
+ message: `Prefab parent node "${normalizedParentId ?? parentId ?? 'root'}" was not found.`,
452
+ assetId: prefabAsset.id,
453
+ ...(normalizedParentId ? { parentId: normalizedParentId } : {}),
454
+ }],
455
+ };
456
+ }
457
+ return { ok: true, parentId: normalizedParentId };
458
+ }
459
+ function appendEditorScenePrefabNode(prefabAsset, node) {
460
+ const next = structuredClone(prefabAsset);
461
+ const nodes = readEditorScenePrefabNodes(prefabAsset);
462
+ const nodeId = createUniqueEditorScenePrefabNodeId(nodes, node.id);
463
+ const nextNode = {
464
+ ...structuredClone(node),
465
+ id: nodeId,
466
+ };
467
+ next.prefab = structuredClone(next.prefab);
468
+ next.prefab.compositionVersion = EDITOR_SCENE_PREFAB_COMPOSITION_VERSION;
469
+ const rootNodeId = readEditorScenePrefabRootNodeId(prefabAsset);
470
+ if (rootNodeId)
471
+ next.prefab.rootNodeId = rootNodeId;
472
+ else
473
+ delete next.prefab.rootNodeId;
474
+ next.prefab.nodes = [...nodes, nextNode];
475
+ return createEditorScenePrefabMutationResult(next, true, nextNode, [], {
476
+ createdNodeId: nextNode.id,
477
+ selectedNodeId: nextNode.id,
478
+ });
479
+ }
480
+ function updateEditorScenePrefabNode(prefabAsset, nodeId, update) {
481
+ const nodes = readEditorScenePrefabNodes(prefabAsset);
482
+ const index = nodes.findIndex(node => node.id === nodeId);
483
+ if (index < 0) {
484
+ return createEditorScenePrefabMutationResult(prefabAsset, false, null, [{
485
+ code: 'prefab.nodeNotFound',
486
+ severity: 'error',
487
+ message: `Prefab node "${nodeId}" was not found.`,
488
+ assetId: prefabAsset.id,
489
+ nodeId,
490
+ }]);
491
+ }
492
+ const updated = update(structuredClone(nodes[index]));
493
+ const nextNodes = [...nodes];
494
+ nextNodes[index] = updated;
495
+ const next = structuredClone(prefabAsset);
496
+ next.prefab = structuredClone(next.prefab);
497
+ next.prefab.compositionVersion = EDITOR_SCENE_PREFAB_COMPOSITION_VERSION;
498
+ const rootNodeId = readEditorScenePrefabRootNodeId(prefabAsset);
499
+ if (rootNodeId)
500
+ next.prefab.rootNodeId = rootNodeId;
501
+ else
502
+ delete next.prefab.rootNodeId;
503
+ next.prefab.nodes = nextNodes;
504
+ return createEditorScenePrefabMutationResult(next, JSON.stringify(nodes[index]) !== JSON.stringify(updated), updated, [], {
505
+ selectedNodeId: updated.id,
506
+ });
507
+ }
508
+ function createUniqueEditorScenePrefabNodeId(nodes, preferredId) {
509
+ const used = new Set(nodes.map(node => node.id));
510
+ const base = normalizeEditorScenePrefabIdentifierPart(preferredId) ?? 'prefab_node';
511
+ if (!used.has(base))
512
+ return base;
513
+ let suffix = 1;
514
+ let candidate = `${base}_${suffix}`;
515
+ while (used.has(candidate)) {
516
+ suffix += 1;
517
+ candidate = `${base}_${suffix}`;
518
+ }
519
+ return candidate;
520
+ }
521
+ function isEditorScenePrefabNodeDescendant(nodes, candidateNodeId, ancestorNodeId) {
522
+ let current = nodes.find(node => node.id === candidateNodeId);
523
+ const visited = new Set();
524
+ while (current?.parentId) {
525
+ if (current.parentId === ancestorNodeId)
526
+ return true;
527
+ if (visited.has(current.parentId))
528
+ return false;
529
+ visited.add(current.parentId);
530
+ current = nodes.find(node => node.id === current?.parentId);
531
+ }
532
+ return false;
533
+ }
534
+ function collectEditorScenePrefabNodeSubtree(nodes, nodeId, output) {
535
+ if (output.has(nodeId))
536
+ return;
537
+ output.add(nodeId);
538
+ for (const child of nodes.filter(node => node.parentId === nodeId)) {
539
+ collectEditorScenePrefabNodeSubtree(nodes, child.id, output);
540
+ }
541
+ }
542
+ export function createEditorScenePrefabDefinitionFromAsset(sourceAsset, options = {}) {
543
+ return {
544
+ id: options.id ?? `${sourceAsset.id}-prefab`,
545
+ ...(options.guid ? { guid: options.guid } : {}),
546
+ type: 'prefab',
547
+ displayName: options.displayName ?? createEditorScenePrefabDisplayName(sourceAsset),
548
+ category: options.category ?? 'Prefab',
549
+ prefab: {
550
+ sourceAssetId: sourceAsset.id,
551
+ ...(sourceAsset.guid ? { sourceAssetGuid: sourceAsset.guid } : {}),
552
+ ...(options.defaults ? { defaults: { ...options.defaults } } : {}),
553
+ compositionVersion: EDITOR_SCENE_PREFAB_COMPOSITION_VERSION,
554
+ rootNodeId: EDITOR_SCENE_PREFAB_LEGACY_ROOT_NODE_ID,
555
+ nodes: [
556
+ {
557
+ id: EDITOR_SCENE_PREFAB_LEGACY_ROOT_NODE_ID,
558
+ name: options.displayName ?? createEditorScenePrefabDisplayName(sourceAsset),
559
+ kind: 'root',
560
+ ...(options.defaults ? { defaults: { ...options.defaults } } : {}),
561
+ },
562
+ {
563
+ id: EDITOR_SCENE_PREFAB_LEGACY_MODEL_NODE_ID,
564
+ name: sourceAsset.displayName ?? sourceAsset.id,
565
+ parentId: EDITOR_SCENE_PREFAB_LEGACY_ROOT_NODE_ID,
566
+ kind: 'model',
567
+ sourceAssetId: sourceAsset.id,
568
+ },
569
+ ],
570
+ },
571
+ ...(options.metadata ? { metadata: { ...options.metadata } } : {}),
572
+ };
573
+ }
574
+ function readEditorScenePrefabExplicitNodes(prefab) {
575
+ if (!Array.isArray(prefab.nodes))
576
+ return [];
577
+ const nodes = [];
578
+ for (const rawNode of prefab.nodes) {
579
+ const node = readEditorScenePrefabNode(rawNode);
580
+ if (node && !nodes.some(existing => existing.id === node.id))
581
+ nodes.push(node);
582
+ }
583
+ return structuredClone(nodes);
584
+ }
585
+ function readEditorScenePrefabNode(value) {
586
+ if (!value || typeof value !== 'object' || Array.isArray(value))
587
+ return null;
588
+ const record = value;
589
+ const id = readEditorSceneNonEmptyString(record.id);
590
+ if (!id || !isEditorScenePrefabNodeKind(record.kind))
591
+ return null;
592
+ return {
593
+ id,
594
+ ...(readEditorSceneNonEmptyString(record.guid) ? { guid: readEditorSceneNonEmptyString(record.guid) } : {}),
595
+ ...(readEditorSceneNonEmptyString(record.name) ? { name: readEditorSceneNonEmptyString(record.name) } : {}),
596
+ ...(readEditorSceneNonEmptyString(record.parentId) ? { parentId: readEditorSceneNonEmptyString(record.parentId) } : {}),
597
+ kind: record.kind,
598
+ ...(record.transform ? { transform: structuredClone(record.transform) } : {}),
599
+ ...(readEditorSceneNonEmptyString(record.sourceAssetId) ? { sourceAssetId: readEditorSceneNonEmptyString(record.sourceAssetId) } : {}),
600
+ ...(readEditorSceneNonEmptyString(record.sourceNodePath) ? { sourceNodePath: readEditorSceneNonEmptyString(record.sourceNodePath) } : {}),
601
+ ...(readEditorSceneNonEmptyString(record.childPrefabId) ? { childPrefabId: readEditorSceneNonEmptyString(record.childPrefabId) } : {}),
602
+ ...(record.primitive ? { primitive: structuredClone(record.primitive) } : {}),
603
+ ...(record.light ? { light: structuredClone(record.light) } : {}),
604
+ ...(record.defaults ? { defaults: structuredClone(record.defaults) } : {}),
605
+ ...(record.overrides ? { overrides: structuredClone(record.overrides) } : {}),
606
+ ...(record.metadata ? { metadata: structuredClone(record.metadata) } : {}),
607
+ };
608
+ }
609
+ function isEditorScenePrefabNodeKind(value) {
610
+ return value === 'root'
611
+ || value === 'group'
612
+ || value === 'model'
613
+ || value === 'primitive'
614
+ || value === 'light'
615
+ || value === 'prefabInstance'
616
+ || value === 'collision';
617
+ }
618
+ function createEditorScenePrefabLegacyCompositionNodes(prefabAsset) {
619
+ const root = createEditorScenePrefabLegacyRootNode(prefabAsset);
620
+ const sourceAssetId = resolveEditorScenePrefabSourceAssetId(prefabAsset);
621
+ if (!root || !sourceAssetId)
622
+ return [];
623
+ return [
624
+ root,
625
+ {
626
+ id: EDITOR_SCENE_PREFAB_LEGACY_MODEL_NODE_ID,
627
+ name: readEditorSceneNonEmptyString(prefabAsset.displayName) ?? sourceAssetId,
628
+ parentId: root.id,
629
+ kind: 'model',
630
+ sourceAssetId,
631
+ },
632
+ ];
633
+ }
634
+ function createEditorScenePrefabLegacyRootNode(prefabAsset) {
635
+ if (!resolveEditorScenePrefabSourceAssetId(prefabAsset))
636
+ return null;
637
+ return {
638
+ id: EDITOR_SCENE_PREFAB_LEGACY_ROOT_NODE_ID,
639
+ name: readEditorSceneNonEmptyString(prefabAsset.displayName) ?? 'Prefab',
640
+ kind: 'root',
641
+ ...(prefabAsset.prefab?.defaults ? { defaults: structuredClone(prefabAsset.prefab.defaults) } : {}),
642
+ ...(prefabAsset.prefab?.overrides ? { overrides: structuredClone(prefabAsset.prefab.overrides) } : {}),
643
+ };
644
+ }
645
+ export function createEditorScenePrefabInstanceGameObject(input) {
646
+ const sourceAssetId = resolveEditorScenePrefabSourceAssetId(input.prefabAsset);
647
+ if (!sourceAssetId) {
648
+ throw new Error(`Prefab asset "${input.prefabAsset.id}" does not define a source asset.`);
649
+ }
650
+ const defaults = input.prefabAsset.prefab?.defaults;
651
+ return {
652
+ id: input.id,
653
+ ...(input.guid ? { guid: input.guid } : {}),
654
+ name: input.name ?? input.prefabAsset.displayName ?? input.prefabAsset.id,
655
+ kind: 'instance',
656
+ ...(input.parentId ? { parentId: input.parentId } : {}),
657
+ active: input.active ?? defaults?.active ?? true,
658
+ ...(input.shadowMode ?? defaults?.shadowMode ? { shadowMode: input.shadowMode ?? defaults?.shadowMode } : {}),
659
+ ...(input.shadow ?? defaults?.shadow ? { shadow: structuredClone(input.shadow ?? defaults?.shadow) } : {}),
660
+ prefab: {
661
+ prefabId: input.prefabAsset.id,
662
+ ...(input.prefabAsset.guid ? { prefabGuid: input.prefabAsset.guid } : {}),
663
+ sourceAssetId,
664
+ },
665
+ ...(input.metadata ? { metadata: { ...input.metadata } } : {}),
666
+ ...(input.overrides !== undefined ? { overrides: input.overrides } : {}),
667
+ components: [
668
+ input.transform,
669
+ {
670
+ type: 'ModelRenderer',
671
+ assetId: sourceAssetId,
672
+ },
673
+ ],
674
+ };
675
+ }
676
+ export function createEditorScenePrefabDefinitionFromGameObject(document, gameObjectId, options = {}) {
677
+ const gameObject = findEditorSceneGameObject(document, gameObjectId);
678
+ if (!gameObject)
679
+ return null;
680
+ const modelRenderer = findEditorSceneModelRenderer(gameObject);
681
+ const sourceAssetId = readEditorSceneNonEmptyString(modelRenderer?.assetId);
682
+ if (!sourceAssetId)
683
+ return null;
684
+ const sourceAsset = document.assets.find(asset => asset.id === sourceAssetId);
685
+ if (!sourceAsset || isEditorScenePrefabAsset(sourceAsset))
686
+ return null;
687
+ const displayName = options.displayName
688
+ ?? createEditorScenePrefabDisplayName({ id: gameObject.id, displayName: gameObject.name ?? sourceAsset.displayName });
689
+ return createEditorScenePrefabDefinitionFromAsset(sourceAsset, {
690
+ id: options.id ?? createUniqueEditorScenePrefabAssetId(document, `${gameObject.id}-prefab`),
691
+ guid: options.guid ?? options.createGuid?.() ?? createEditorScenePrefabGuid(),
692
+ displayName,
693
+ category: options.category,
694
+ defaults: options.defaults,
695
+ metadata: options.metadata,
696
+ });
697
+ }
698
+ export function createEditorSceneDuplicatedPrefabDefinition(document, prefabAssetId, options = {}) {
699
+ const source = document.assets.find(asset => asset.id === prefabAssetId);
700
+ if (!source || !isEditorScenePrefabAsset(source))
701
+ return null;
702
+ const sourcePrefab = structuredClone(source.prefab);
703
+ const displayName = options.displayName
704
+ ?? createUniqueEditorScenePrefabDisplayName(document.assets.map(asset => asset.displayName ?? asset.id), `${source.displayName ?? source.id} Copy`);
705
+ return {
706
+ ...structuredClone(source),
707
+ id: options.id ?? createUniqueEditorScenePrefabAssetId(document, `${source.id}_copy`),
708
+ guid: options.guid ?? options.createGuid?.() ?? createEditorScenePrefabGuid(),
709
+ displayName,
710
+ category: options.category ?? source.category,
711
+ prefab: {
712
+ ...sourcePrefab,
713
+ ...(sourcePrefab.defaults ? { defaults: { ...sourcePrefab.defaults } } : {}),
714
+ },
715
+ ...(options.metadata ? { metadata: { ...options.metadata } } : {}),
716
+ };
717
+ }
718
+ export function readEditorScenePrefabOverrideMaterialPath(path) {
719
+ if (!path.startsWith(EDITOR_SCENE_PREFAB_OVERRIDE_FIELD_PATH_PREFIX))
720
+ return null;
721
+ const materialPath = path.slice(EDITOR_SCENE_PREFAB_OVERRIDE_FIELD_PATH_PREFIX.length);
722
+ return isEditorSceneArtistMaterialPatchPath(materialPath) ? materialPath : null;
723
+ }
724
+ export function isEditorScenePrefabOverridePath(path) {
725
+ return readEditorScenePrefabOverrideMaterialPath(path) != null;
726
+ }
727
+ export function isEditorScenePrefabCoreMaterialOverridePath(path) {
728
+ const materialPath = readEditorScenePrefabOverrideMaterialPath(path);
729
+ if (!materialPath)
730
+ return false;
731
+ if (materialPath.endsWith('.materialAssetId'))
732
+ return true;
733
+ const profilePath = readEditorScenePrefabOverrideProfileFieldPath(path);
734
+ return profilePath != null && EDITOR_SCENE_PREFAB_CORE_MATERIAL_OVERRIDE_PROFILE_FIELD_PATHS.has(profilePath);
735
+ }
736
+ export function readEditorScenePrefabOverrideProfileFieldPath(path) {
737
+ const materialPath = readEditorScenePrefabOverrideMaterialPath(path);
738
+ if (!materialPath)
739
+ return null;
740
+ const marker = '.override.';
741
+ const markerIndex = materialPath.lastIndexOf(marker);
742
+ if (markerIndex < 0)
743
+ return null;
744
+ const profilePath = materialPath.slice(markerIndex + marker.length);
745
+ return profilePath ? `profile.${profilePath}` : null;
746
+ }
747
+ export function patchEditorScenePrefabOverride(prefabAsset, path, value) {
748
+ const materialPath = readEditorScenePrefabOverrideMaterialPath(path);
749
+ if (!materialPath || !isEditorScenePrefabAsset(prefabAsset))
750
+ return prefabAsset;
751
+ const segments = splitEditorScenePrefabOverrideFieldPath(materialPath);
752
+ if (!segments)
753
+ return prefabAsset;
754
+ const next = structuredClone(prefabAsset);
755
+ next.prefab = structuredClone(next.prefab ?? prefabAsset.prefab);
756
+ applyEditorScenePrefabOverrideJsonPatch(next.prefab, segments, value);
757
+ const prunedOverrides = pruneEditorScenePrefabOverrides(next.prefab?.overrides);
758
+ if (prunedOverrides) {
759
+ next.prefab.overrides = prunedOverrides;
760
+ }
761
+ else {
762
+ delete next.prefab.overrides;
763
+ }
764
+ return JSON.stringify(next) === JSON.stringify(prefabAsset) ? prefabAsset : next;
765
+ }
766
+ export function mergeEditorSceneMaterialBindingOverrides(base, override) {
767
+ const baseMaterialAssetId = readEditorSceneNonEmptyString(base?.materialAssetId);
768
+ const overrideMaterialAssetId = readEditorSceneNonEmptyString(override?.materialAssetId);
769
+ const profile = mergeArtistMaterialProfiles(base?.override, override?.override);
770
+ return pruneEditorSceneMaterialBinding({
771
+ ...(overrideMaterialAssetId ?? baseMaterialAssetId
772
+ ? { materialAssetId: overrideMaterialAssetId ?? baseMaterialAssetId }
773
+ : {}),
774
+ ...(hasEditorSceneObjectFields(profile) ? { override: profile } : {}),
775
+ });
776
+ }
777
+ export function mergeEditorScenePrefabOverrides(base, override) {
778
+ const next = {};
779
+ const materialBinding = mergeEditorSceneMaterialBindingOverrides(base?.materialBinding, override?.materialBinding);
780
+ if (materialBinding)
781
+ next.materialBinding = materialBinding;
782
+ const materialSlotBindings = mergeEditorSceneMaterialBindingRecords(base?.materialSlotBindings, override?.materialSlotBindings);
783
+ if (materialSlotBindings)
784
+ next.materialSlotBindings = materialSlotBindings;
785
+ const childMaterialBindings = mergeEditorSceneMaterialBindingRecords(base?.childMaterialBindings, override?.childMaterialBindings);
786
+ if (childMaterialBindings)
787
+ next.childMaterialBindings = childMaterialBindings;
788
+ return hasEditorSceneObjectFields(next) ? next : undefined;
789
+ }
790
+ export function resolveEditorScenePrefabInstanceEffectiveOverrides(document, gameObjectId) {
791
+ const relation = resolveEditorScenePrefabInstanceRelation(document, gameObjectId);
792
+ if (!relation.gameObject || !relation.prefab)
793
+ return undefined;
794
+ return mergeEditorScenePrefabOverrides(relation.definition?.prefab?.overrides, readEditorScenePrefabOverrides(relation.gameObject.overrides));
795
+ }
796
+ export function createEditorScenePrefabAgentSummary(document, gameObjectId) {
797
+ const relation = resolveEditorScenePrefabInstanceRelation(document, gameObjectId);
798
+ if (!relation.gameObject || !relation.prefab)
799
+ return null;
800
+ const errorCount = relation.diagnostics.filter(diagnostic => diagnostic.severity === 'error').length;
801
+ const warningCount = relation.diagnostics.filter(diagnostic => diagnostic.severity === 'warning').length;
802
+ const sourceAssetId = resolveEditorScenePrefabSourceAssetId(relation.definition)
803
+ ?? readEditorSceneNonEmptyString(relation.prefab.sourceAssetId)
804
+ ?? undefined;
805
+ const effectiveOverrides = resolveEditorScenePrefabInstanceEffectiveOverrides(document, gameObjectId);
806
+ const summary = {
807
+ kind: 'prefab-instance',
808
+ status: errorCount > 0 ? 'error' : warningCount > 0 ? 'warning' : 'ok',
809
+ prefabId: relation.prefab.prefabId,
810
+ ...(relation.prefab.prefabGuid ? { prefabGuid: relation.prefab.prefabGuid } : {}),
811
+ ...(readEditorSceneNonEmptyString(relation.definition?.displayName)
812
+ ? { prefabDisplayName: readEditorSceneNonEmptyString(relation.definition?.displayName) }
813
+ : {}),
814
+ ...(sourceAssetId ? { sourceAssetId } : {}),
815
+ ...(readEditorSceneNonEmptyString(relation.sourceAsset?.guid) ? { sourceAssetGuid: readEditorSceneNonEmptyString(relation.sourceAsset?.guid) } : {}),
816
+ ...(readEditorSceneNonEmptyString(relation.sourceAsset?.displayName)
817
+ ? { sourceAssetDisplayName: readEditorSceneNonEmptyString(relation.sourceAsset?.displayName) }
818
+ : {}),
819
+ ...(readEditorSceneNonEmptyString(relation.prefab.sourceAssetId) ? { instanceSourceAssetId: readEditorSceneNonEmptyString(relation.prefab.sourceAssetId) } : {}),
820
+ diagnostics: relation.diagnostics.map(diagnostic => ({ ...diagnostic })),
821
+ materialTargets: createEditorScenePrefabAgentMaterialTargets(relation.sourceAsset),
822
+ ...(effectiveOverrides ? { effectiveOverrides } : {}),
823
+ };
824
+ return summary;
825
+ }
826
+ export function resolveEditorScenePrefabInstanceRelation(document, gameObjectId) {
827
+ const gameObject = findEditorSceneGameObject(document, gameObjectId);
828
+ const diagnostics = [];
829
+ const prefab = isEditorScenePrefabInstance(gameObject) ? gameObject.prefab : null;
830
+ if (!gameObject || !prefab) {
831
+ diagnostics.push({
832
+ code: 'not-prefab-instance',
833
+ severity: 'info',
834
+ message: gameObject
835
+ ? `GameObject "${gameObject.id}" is not a prefab instance.`
836
+ : `GameObject "${gameObjectId}" was not found.`,
837
+ });
838
+ return {
839
+ gameObject,
840
+ prefab: null,
841
+ definition: null,
842
+ sourceAsset: null,
843
+ diagnostics,
844
+ };
845
+ }
846
+ const definition = document.assets.find(asset => asset.id === prefab.prefabId && isEditorScenePrefabAsset(asset));
847
+ if (!definition) {
848
+ diagnostics.push({
849
+ code: 'missing-prefab-definition',
850
+ severity: 'error',
851
+ message: `Prefab definition "${prefab.prefabId}" was not found.`,
852
+ prefabId: prefab.prefabId,
853
+ });
854
+ }
855
+ const expectedSourceAssetId = resolveEditorScenePrefabSourceAssetId(definition) ?? readEditorSceneNonEmptyString(prefab.sourceAssetId);
856
+ if (definition && prefab.sourceAssetId && expectedSourceAssetId && prefab.sourceAssetId !== expectedSourceAssetId) {
857
+ diagnostics.push({
858
+ code: 'source-asset-mismatch',
859
+ severity: 'warning',
860
+ message: `Prefab instance source "${prefab.sourceAssetId}" does not match definition source "${expectedSourceAssetId}".`,
861
+ prefabId: prefab.prefabId,
862
+ expectedSourceAssetId,
863
+ actualSourceAssetId: prefab.sourceAssetId,
864
+ });
865
+ }
866
+ const sourceAsset = expectedSourceAssetId
867
+ ? document.assets.find(asset => asset.id === expectedSourceAssetId)
868
+ : undefined;
869
+ if (expectedSourceAssetId && !sourceAsset) {
870
+ diagnostics.push({
871
+ code: 'missing-source-asset',
872
+ severity: 'error',
873
+ message: `Prefab source asset "${expectedSourceAssetId}" was not found.`,
874
+ prefabId: prefab.prefabId,
875
+ sourceAssetId: expectedSourceAssetId,
876
+ });
877
+ }
878
+ if (expectedSourceAssetId) {
879
+ const sourcePrefabIds = document.assets
880
+ .filter(asset => isEditorScenePrefabAsset(asset) && resolveEditorScenePrefabSourceAssetId(asset) === expectedSourceAssetId)
881
+ .map(asset => asset.id);
882
+ if (sourcePrefabIds.length > 1) {
883
+ diagnostics.push({
884
+ code: 'duplicate-source-prefab',
885
+ severity: 'info',
886
+ message: `Source asset "${expectedSourceAssetId}" is referenced by ${sourcePrefabIds.length} prefab definitions.`,
887
+ prefabId: prefab.prefabId,
888
+ sourceAssetId: expectedSourceAssetId,
889
+ });
890
+ }
891
+ }
892
+ return {
893
+ gameObject,
894
+ prefab,
895
+ definition: definition ?? null,
896
+ sourceAsset: sourceAsset ?? null,
897
+ diagnostics,
898
+ };
899
+ }
900
+ function createEditorScenePrefabAgentMaterialTargets(sourceAsset) {
901
+ const rawSlots = Array.isArray(sourceAsset?.metadata?.materialSlots) ? sourceAsset.metadata.materialSlots : [];
902
+ const targets = [];
903
+ for (const [index, rawSlot] of rawSlots.entries()) {
904
+ const slot = readEditorScenePrefabAgentMaterialSlot(rawSlot);
905
+ if (!slot)
906
+ continue;
907
+ const targetKey = slot.slotId ?? slot.ownerNodePath;
908
+ const bindingPath = slot.slotId
909
+ ? `prefab.overrides.materialSlotBindings.${slot.slotId}`
910
+ : `prefab.overrides.childMaterialBindings.${slot.ownerNodePath}`;
911
+ targets.push({
912
+ kind: slot.slotId ? 'material-slot' : 'owner-node-path',
913
+ label: slot.label ?? slot.materialName ?? slot.ownerNodePath ?? `Material Slot ${index + 1}`,
914
+ bindingPath,
915
+ materialAssetIdPath: `${bindingPath}.materialAssetId`,
916
+ overridePath: `${bindingPath}.override`,
917
+ ...(slot.slotId ? { slotId: slot.slotId } : {}),
918
+ ...(slot.ownerNodePath ? { ownerNodePath: slot.ownerNodePath } : {}),
919
+ ...(slot.sourceMaterialIndex != null ? { sourceMaterialIndex: slot.sourceMaterialIndex } : {}),
920
+ ...(slot.materialName ? { sourceMaterialName: slot.materialName } : {}),
921
+ });
922
+ if (!targetKey)
923
+ targets.pop();
924
+ }
925
+ return targets;
926
+ }
927
+ function readEditorScenePrefabAgentMaterialSlot(value) {
928
+ if (typeof value === 'string') {
929
+ const ownerNodePath = normalizeEditorSceneMaterialSlotOwnerPath(readEditorSceneNonEmptyString(value) ?? '');
930
+ return ownerNodePath ? { ownerNodePath } : null;
931
+ }
932
+ if (!value || typeof value !== 'object' || Array.isArray(value))
933
+ return null;
934
+ const record = value;
935
+ const ownerNodePath = normalizeEditorSceneMaterialSlotOwnerPath(readEditorSceneNonEmptyString(record.ownerNodePath)
936
+ ?? readEditorSceneNonEmptyString(record.path)
937
+ ?? readEditorSceneNonEmptyString(record.name)
938
+ ?? '');
939
+ const slotId = readEditorSceneNonEmptyString(record.slotId) ?? undefined;
940
+ if (!slotId && !ownerNodePath)
941
+ return null;
942
+ const label = readEditorSceneNonEmptyString(record.label) ?? undefined;
943
+ const materialName = readEditorSceneNonEmptyString(record.materialName) ?? undefined;
944
+ const sourceMaterialIndex = Number.isInteger(record.sourceMaterialIndex) ? record.sourceMaterialIndex : undefined;
945
+ return {
946
+ ...(slotId ? { slotId } : {}),
947
+ ownerNodePath,
948
+ ...(label ? { label } : {}),
949
+ ...(materialName ? { materialName } : {}),
950
+ ...(sourceMaterialIndex != null ? { sourceMaterialIndex } : {}),
951
+ };
952
+ }
10
953
  export function readEditorSceneNodeKind(gameObject) {
11
954
  if (gameObject.kind === 'group'
12
955
  || gameObject.kind === 'instance'
@@ -14,6 +957,8 @@ export function readEditorSceneNodeKind(gameObject) {
14
957
  || gameObject.kind === 'primitive') {
15
958
  return gameObject.kind;
16
959
  }
960
+ if (isEditorScenePrefabInstance(gameObject))
961
+ return 'instance';
17
962
  if (gameObject.primitive)
18
963
  return 'primitive';
19
964
  if (findEditorSceneModelRenderer(gameObject))
@@ -27,8 +972,7 @@ export function resolveEditorSceneGameObjectRendering(gameObject) {
27
972
  ? gameObject.rendering
28
973
  : undefined;
29
974
  const renderingGroupId = readEditorSceneGameObjectRenderingGroupId(rendering?.renderingGroupId);
30
- const alphaIndex = readEditorSceneFiniteNumber(rendering?.alphaIndex)
31
- ?? readEditorSceneLegacyGroundDecalAlphaIndex(gameObject);
975
+ const alphaIndex = readEditorSceneFiniteNumber(rendering?.alphaIndex);
32
976
  const resolved = {};
33
977
  if (renderingGroupId != null)
34
978
  resolved.renderingGroupId = renderingGroupId;
@@ -48,13 +992,204 @@ function isEditorSceneTransformComponent(component) {
48
992
  function isEditorSceneModelRendererComponent(component) {
49
993
  return component.type === 'ModelRenderer';
50
994
  }
51
- function readEditorSceneLegacyGroundDecalAlphaIndex(gameObject) {
52
- const groundDecal = gameObject.groundDecal;
53
- if (!groundDecal || typeof groundDecal !== 'object' || Array.isArray(groundDecal))
54
- return null;
55
- return readEditorSceneFiniteNumber(groundDecal.alphaIndex);
56
- }
57
995
  function readEditorSceneFiniteNumber(value) {
58
996
  return typeof value === 'number' && Number.isFinite(value) ? value : null;
59
997
  }
998
+ function readEditorSceneNonEmptyString(value) {
999
+ return typeof value === 'string' && value.trim().length > 0 ? value.trim() : null;
1000
+ }
1001
+ function normalizeEditorScenePrefabEditableName(value) {
1002
+ if (typeof value !== 'string')
1003
+ return { ok: false, message: 'Prefab name must be a string.' };
1004
+ const name = value.trim();
1005
+ if (!name)
1006
+ return { ok: false, message: 'Prefab name cannot be empty.' };
1007
+ if (name.length > 80)
1008
+ return { ok: false, message: 'Prefab name cannot be longer than 80 characters.' };
1009
+ if (/[\u0000-\u001f\u007f/\\]/u.test(name)) {
1010
+ return { ok: false, message: 'Prefab name cannot contain control characters, /, or \\.' };
1011
+ }
1012
+ return { ok: true, name };
1013
+ }
1014
+ function findEditorSceneGameObject(document, gameObjectId) {
1015
+ return document.scene.gameObjects.find(gameObject => gameObject.id === gameObjectId) ?? null;
1016
+ }
1017
+ function createEditorScenePrefabDisplayName(sourceAsset) {
1018
+ const displayName = readEditorSceneNonEmptyString(sourceAsset.displayName)
1019
+ ?? readEditorSceneNonEmptyString(sourceAsset.id)
1020
+ ?? 'Prefab';
1021
+ return `${displayName} Prefab`;
1022
+ }
1023
+ function createEditorScenePrefabGuid() {
1024
+ const randomId = globalThis.crypto?.randomUUID?.() ?? `${Date.now().toString(36)}-${Math.random().toString(36).slice(2)}`;
1025
+ return `prefab_${randomId}`;
1026
+ }
1027
+ function createUniqueEditorScenePrefabAssetId(document, preferredId) {
1028
+ const used = new Set(document.assets.map(asset => asset.id));
1029
+ const base = normalizeEditorScenePrefabIdentifierPart(preferredId) ?? 'prefab';
1030
+ if (!used.has(base))
1031
+ return base;
1032
+ let suffix = 1;
1033
+ let candidate = `${base}_${suffix}`;
1034
+ while (used.has(candidate)) {
1035
+ suffix += 1;
1036
+ candidate = `${base}_${suffix}`;
1037
+ }
1038
+ return candidate;
1039
+ }
1040
+ function createUniqueEditorScenePrefabDisplayName(existingNames, preferredName) {
1041
+ const used = new Set(existingNames
1042
+ .map(name => readEditorSceneNonEmptyString(name))
1043
+ .filter((name) => !!name));
1044
+ if (!used.has(preferredName))
1045
+ return preferredName;
1046
+ let suffix = 1;
1047
+ let candidate = `${preferredName} ${suffix}`;
1048
+ while (used.has(candidate)) {
1049
+ suffix += 1;
1050
+ candidate = `${preferredName} ${suffix}`;
1051
+ }
1052
+ return candidate;
1053
+ }
1054
+ function normalizeEditorScenePrefabIdentifierPart(value) {
1055
+ const raw = readEditorSceneNonEmptyString(value);
1056
+ if (!raw)
1057
+ return null;
1058
+ const normalized = raw
1059
+ .replace(/\s+/g, '_')
1060
+ .replace(/[^a-zA-Z0-9_:-]/g, '_')
1061
+ .replace(/_+/g, '_')
1062
+ .replace(/^_+|_+$/g, '');
1063
+ return normalized || null;
1064
+ }
1065
+ function splitEditorScenePrefabOverrideFieldPath(path) {
1066
+ if (path === 'overrides.materialBinding.materialAssetId') {
1067
+ return ['overrides', 'materialBinding', 'materialAssetId'];
1068
+ }
1069
+ const rootOverridePrefix = 'overrides.materialBinding.override.';
1070
+ if (path.startsWith(rootOverridePrefix)) {
1071
+ const profilePath = path.slice(rootOverridePrefix.length);
1072
+ return splitEditorScenePrefabProfilePath(['overrides', 'materialBinding', 'override'], profilePath);
1073
+ }
1074
+ const slotMaterialAssetId = readEditorSceneMaterialSlotBindingSlotId(path, 'materialAssetId');
1075
+ if (slotMaterialAssetId) {
1076
+ return ['overrides', 'materialSlotBindings', slotMaterialAssetId, 'materialAssetId'];
1077
+ }
1078
+ const slotOverrideId = readEditorSceneMaterialSlotBindingSlotId(path, 'override');
1079
+ if (slotOverrideId) {
1080
+ const profilePath = readEditorSceneBindingOverrideProfilePath(path);
1081
+ return profilePath
1082
+ ? splitEditorScenePrefabProfilePath(['overrides', 'materialSlotBindings', slotOverrideId, 'override'], profilePath)
1083
+ : null;
1084
+ }
1085
+ const childMaterialAssetId = readEditorSceneChildMaterialBindingOwnerPath(path, 'materialAssetId');
1086
+ if (childMaterialAssetId) {
1087
+ return ['overrides', 'childMaterialBindings', childMaterialAssetId, 'materialAssetId'];
1088
+ }
1089
+ const childOverrideOwnerPath = readEditorSceneChildMaterialBindingOwnerPath(path, 'override');
1090
+ if (childOverrideOwnerPath) {
1091
+ const profilePath = readEditorSceneBindingOverrideProfilePath(path);
1092
+ return profilePath
1093
+ ? splitEditorScenePrefabProfilePath(['overrides', 'childMaterialBindings', childOverrideOwnerPath, 'override'], profilePath)
1094
+ : null;
1095
+ }
1096
+ return null;
1097
+ }
1098
+ function readEditorSceneBindingOverrideProfilePath(path) {
1099
+ const marker = '.override.';
1100
+ const markerIndex = path.lastIndexOf(marker);
1101
+ if (markerIndex < 0)
1102
+ return null;
1103
+ const profilePath = path.slice(markerIndex + marker.length);
1104
+ return profilePath ? profilePath : null;
1105
+ }
1106
+ function splitEditorScenePrefabProfilePath(prefix, profilePath) {
1107
+ const profileSegments = profilePath.split('.').filter(Boolean);
1108
+ if (profileSegments.length === 0 || profileSegments.some(isUnsafeEditorScenePrefabOverridePathSegment))
1109
+ return null;
1110
+ return [...prefix, ...profileSegments];
1111
+ }
1112
+ function applyEditorScenePrefabOverrideJsonPatch(target, segments, value) {
1113
+ if (segments.some(isUnsafeEditorScenePrefabOverridePathSegment))
1114
+ return;
1115
+ let cursor = target;
1116
+ for (const segment of segments.slice(0, -1)) {
1117
+ const current = cursor[segment];
1118
+ if (!current || typeof current !== 'object' || Array.isArray(current)) {
1119
+ cursor[segment] = {};
1120
+ }
1121
+ cursor = cursor[segment];
1122
+ }
1123
+ const leaf = segments[segments.length - 1];
1124
+ if (!leaf)
1125
+ return;
1126
+ if (value == null)
1127
+ delete cursor[leaf];
1128
+ else
1129
+ cursor[leaf] = structuredClone(value);
1130
+ }
1131
+ function pruneEditorScenePrefabOverrides(overrides) {
1132
+ if (!overrides || typeof overrides !== 'object' || Array.isArray(overrides))
1133
+ return undefined;
1134
+ const source = overrides;
1135
+ const next = {};
1136
+ const materialBinding = pruneEditorSceneMaterialBinding(source.materialBinding);
1137
+ if (materialBinding)
1138
+ next.materialBinding = materialBinding;
1139
+ const materialSlotBindings = pruneEditorSceneMaterialBindingRecord(source.materialSlotBindings);
1140
+ if (materialSlotBindings)
1141
+ next.materialSlotBindings = materialSlotBindings;
1142
+ const childMaterialBindings = pruneEditorSceneMaterialBindingRecord(source.childMaterialBindings);
1143
+ if (childMaterialBindings)
1144
+ next.childMaterialBindings = childMaterialBindings;
1145
+ return hasEditorSceneObjectFields(next) ? next : undefined;
1146
+ }
1147
+ function pruneEditorSceneMaterialBinding(binding) {
1148
+ if (!binding || typeof binding !== 'object' || Array.isArray(binding))
1149
+ return undefined;
1150
+ const source = binding;
1151
+ const materialAssetId = readEditorSceneNonEmptyString(source.materialAssetId);
1152
+ const profile = mergeArtistMaterialProfiles(source.override);
1153
+ const next = {
1154
+ ...(materialAssetId ? { materialAssetId } : {}),
1155
+ ...(hasEditorSceneObjectFields(profile) ? { override: profile } : {}),
1156
+ };
1157
+ return hasEditorSceneObjectFields(next) ? next : undefined;
1158
+ }
1159
+ function pruneEditorSceneMaterialBindingRecord(record) {
1160
+ if (!record || typeof record !== 'object' || Array.isArray(record))
1161
+ return undefined;
1162
+ const next = {};
1163
+ for (const [key, binding] of Object.entries(record)) {
1164
+ const normalizedKey = readEditorSceneNonEmptyString(key);
1165
+ if (!normalizedKey)
1166
+ continue;
1167
+ const prunedBinding = pruneEditorSceneMaterialBinding(binding);
1168
+ if (prunedBinding)
1169
+ next[normalizedKey] = prunedBinding;
1170
+ }
1171
+ return hasEditorSceneObjectFields(next) ? next : undefined;
1172
+ }
1173
+ function mergeEditorSceneMaterialBindingRecords(base, override) {
1174
+ const keys = new Set([
1175
+ ...Object.keys(base ?? {}),
1176
+ ...Object.keys(override ?? {}),
1177
+ ]);
1178
+ const next = {};
1179
+ for (const key of keys) {
1180
+ const binding = mergeEditorSceneMaterialBindingOverrides(base?.[key], override?.[key]);
1181
+ if (binding)
1182
+ next[key] = binding;
1183
+ }
1184
+ return hasEditorSceneObjectFields(next) ? next : undefined;
1185
+ }
1186
+ function readEditorScenePrefabOverrides(value) {
1187
+ return pruneEditorScenePrefabOverrides(value);
1188
+ }
1189
+ function hasEditorSceneObjectFields(value) {
1190
+ return !!value && typeof value === 'object' && !Array.isArray(value) && Object.keys(value).length > 0;
1191
+ }
1192
+ function isUnsafeEditorScenePrefabOverridePathSegment(segment) {
1193
+ return segment === '__proto__' || segment === 'prototype' || segment === 'constructor';
1194
+ }
60
1195
  //# sourceMappingURL=helpers.js.map