@holoscript/core 8.0.7 → 8.0.9

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 (462) hide show
  1. package/bin/holoscript.cjs +5 -1
  2. package/dist/GLTFPipeline-L76YTXKA.js +15 -0
  3. package/dist/GLTFPipeline-ZWJN7GI6.cjs +36 -0
  4. package/dist/HoloCompositionParser-K76KTEEE.js +12 -0
  5. package/dist/HoloCompositionParser-UZH6Y4HO.cjs +45 -0
  6. package/dist/HoloScriptCodeParser-2D4ERFUZ.js +6 -0
  7. package/dist/HoloScriptCodeParser-UDRLDA7I.cjs +23 -0
  8. package/dist/HoloScriptPlusParser-FTMCGWXD.js +13 -0
  9. package/dist/HoloScriptPlusParser-LQR5GIKF.cjs +30 -0
  10. package/dist/HoloScriptRuntime-UTRLJI5L.js +12 -0
  11. package/dist/HoloScriptRuntime-YBYXJHJN.cjs +21 -0
  12. package/dist/SceneIRCompiler-63KA3M2F.js +17 -0
  13. package/dist/SceneIRCompiler-KWUFHZ4O.cjs +42 -0
  14. package/dist/{USDZExporter-AUHZODOF.cjs → USDZExporter-ML4UMIGC.cjs} +3 -3
  15. package/dist/{USDZExporter-GXB4AUSG.js → USDZExporter-ZFKLQ76G.js} +3 -3
  16. package/dist/agents/index.cjs +1 -1
  17. package/dist/agents/index.js +1 -1
  18. package/dist/audit/AuditLogger.d.ts +106 -0
  19. package/dist/audit/AuditQueryBuilder.d.ts +79 -0
  20. package/dist/audit/ComplianceReporter.d.ts +90 -0
  21. package/dist/audit/index.d.ts +13 -0
  22. package/dist/{chunk-FGMDMJM7.js → chunk-2BYAUHBO.js} +3 -3
  23. package/dist/{chunk-EDPYCLRC.cjs → chunk-2E6PP5UE.cjs} +83 -59
  24. package/dist/{chunk-GASCWJK5.js → chunk-2EGGAZT3.js} +65 -287
  25. package/dist/{chunk-SIEXCILW.js → chunk-2I3XAGMF.js} +3 -3
  26. package/dist/{chunk-OS533P33.cjs → chunk-2KKOYZYI.cjs} +1074 -1655
  27. package/dist/chunk-2MQKNDNH.js +51 -0
  28. package/dist/{chunk-7DMMMBCY.cjs → chunk-2X3IPCBK.cjs} +10 -10
  29. package/dist/chunk-2ZOTBO25.cjs +202 -0
  30. package/dist/chunk-356N4NPM.cjs +152 -0
  31. package/dist/{chunk-X3GJPRVK.cjs → chunk-36NPLOI4.cjs} +92 -81
  32. package/dist/{chunk-SLU6UPJI.cjs → chunk-37HHY7RH.cjs} +5 -5
  33. package/dist/{chunk-YDPEHCCI.cjs → chunk-3CDDRUER.cjs} +3 -118
  34. package/dist/chunk-3F7ZZWIN.js +1651 -0
  35. package/dist/chunk-3ILD7TKP.cjs +187 -0
  36. package/dist/{chunk-X27QRG4C.cjs → chunk-3IUHTGDD.cjs} +153 -41
  37. package/dist/{chunk-PXNZ6TME.js → chunk-4376VHNJ.js} +60 -36
  38. package/dist/{chunk-YKGPCZEE.cjs → chunk-4FIBOJW6.cjs} +10 -10
  39. package/dist/chunk-4Q7RKQQI.cjs +14195 -0
  40. package/dist/{chunk-YCM6QQRT.cjs → chunk-566ZB4LZ.cjs} +180 -8
  41. package/dist/{chunk-2Y3V22SG.js → chunk-5CURIYGT.js} +3 -3
  42. package/dist/{chunk-QBWNJXNR.js → chunk-5FYMCVBY.js} +5 -5
  43. package/dist/{chunk-ZA34AN3R.js → chunk-5LVFTGKH.js} +841 -12
  44. package/dist/chunk-63AUAIL6.js +48 -0
  45. package/dist/chunk-655FATJU.js +110 -0
  46. package/dist/{chunk-TQ377OLB.cjs → chunk-65S62L4D.cjs} +28 -22
  47. package/dist/chunk-6NTAZN5Z.cjs +502 -0
  48. package/dist/chunk-6TRX6AR2.js +9376 -0
  49. package/dist/chunk-6ZCCLKS2.cjs +51 -0
  50. package/dist/{chunk-MDR235RZ.js → chunk-734OB5SK.js} +721 -8
  51. package/dist/{chunk-Q2Q34NF3.js → chunk-77QI552M.js} +6 -6
  52. package/dist/{chunk-WKX5AMOY.js → chunk-7I74JWPW.js} +3 -3
  53. package/dist/{chunk-5FSKKMR7.cjs → chunk-7IDJDMPU.cjs} +232 -4
  54. package/dist/chunk-7VBKRGIZ.cjs +847 -0
  55. package/dist/{chunk-KCPHASCO.js → chunk-AATYYLYK.js} +5 -5
  56. package/dist/{chunk-WFKVS2K4.cjs → chunk-AUZRKIHQ.cjs} +1101 -55
  57. package/dist/{chunk-DTGBOSEM.cjs → chunk-AWXFEAQL.cjs} +12 -12
  58. package/dist/{chunk-THCK6ECW.js → chunk-B3CWTCK2.js} +231 -3
  59. package/dist/chunk-BCP4E7MD.cjs +997 -0
  60. package/dist/chunk-BG7RPYJP.js +91 -0
  61. package/dist/{chunk-VF257YKO.js → chunk-BP4KTMLY.js} +117 -5
  62. package/dist/{chunk-YN6IETRZ.js → chunk-BQJ3YBF3.js} +6424 -987
  63. package/dist/{chunk-KOUAQL2B.cjs → chunk-CANAL6CT.cjs} +1569 -168
  64. package/dist/{chunk-FDSGHPAK.js → chunk-CBSDJF3B.js} +3 -3
  65. package/dist/{chunk-FEWUHQNM.cjs → chunk-CFVK26P4.cjs} +4 -4
  66. package/dist/{chunk-M7K4LE66.cjs → chunk-CI33NINL.cjs} +4 -4
  67. package/dist/{chunk-2OWDB4FB.js → chunk-CKV5NYAE.js} +6 -6
  68. package/dist/{chunk-LPS5AMQD.cjs → chunk-CM4NHXVO.cjs} +24 -24
  69. package/dist/chunk-D3HSRXYB.js +115 -0
  70. package/dist/{chunk-FNHJRI32.js → chunk-DBH3D2MU.js} +1561 -160
  71. package/dist/{chunk-GW3LKD5C.js → chunk-DJNH4HFW.js} +3 -3
  72. package/dist/{chunk-2GCNOI2U.cjs → chunk-DN6F4DHH.cjs} +9 -3
  73. package/dist/chunk-DQRJ5RJG.js +432 -0
  74. package/dist/{chunk-C7ZBSV2Q.js → chunk-DUG3OQAS.js} +106 -43
  75. package/dist/chunk-ECUYJOJ2.cjs +199 -0
  76. package/dist/chunk-EEMTCAK7.js +182 -0
  77. package/dist/{chunk-3SKLAUDD.cjs → chunk-EI3J6LTW.cjs} +359 -581
  78. package/dist/{chunk-SSSN7VAM.js → chunk-EM2OGPYE.js} +4 -4
  79. package/dist/{chunk-56VOWURB.cjs → chunk-ENZCIQZC.cjs} +522 -453
  80. package/dist/chunk-ESBXUYOC.cjs +836 -0
  81. package/dist/{chunk-L5U4W6JC.js → chunk-ESSEF6U2.js} +4 -4
  82. package/dist/chunk-ET3AN4W3.js +824 -0
  83. package/dist/chunk-EXKSFGSX.cjs +14 -14
  84. package/dist/{chunk-I76GIKN7.cjs → chunk-F3YT6GUF.cjs} +17 -17
  85. package/dist/{chunk-WRWEX5ZF.js → chunk-F75DZBBI.js} +3 -3
  86. package/dist/{chunk-4JGRWHZJ.js → chunk-FG6PYGIZ.js} +12 -6
  87. package/dist/chunk-FGGJQRLZ.js +14 -14
  88. package/dist/{chunk-SXOSDZD6.js → chunk-FWCHPCD4.js} +128 -10
  89. package/dist/{chunk-XW6IXEQH.cjs → chunk-G35CAQ7I.cjs} +5 -5
  90. package/dist/{chunk-7VMGP2FW.js → chunk-G6KACNMO.js} +132 -188
  91. package/dist/{chunk-FJPADH77.cjs → chunk-GAWJJAGT.cjs} +6 -6
  92. package/dist/chunk-GGR7QUKK.cjs +4724 -0
  93. package/dist/chunk-GIBF4BHH.js +14098 -0
  94. package/dist/{chunk-AWB7QYY6.cjs → chunk-GILYQ5VH.cjs} +6 -6
  95. package/dist/{chunk-FWVYAMNW.cjs → chunk-GKFCHGCM.cjs} +4 -4
  96. package/dist/{chunk-Y3ZFVUUU.js → chunk-GLEJ2TLS.js} +3 -3
  97. package/dist/{chunk-3GWWJT7L.js → chunk-GP3OKSKT.js} +13 -13
  98. package/dist/chunk-GTIPOEHN.js +196 -0
  99. package/dist/{chunk-LMJ5EBV7.cjs → chunk-GZPUA2TL.cjs} +16 -15
  100. package/dist/{chunk-IELX2OKI.js → chunk-H4LJ4HEA.js} +3 -115
  101. package/dist/{chunk-ACVWFGBI.cjs → chunk-HCX4SMFK.cjs} +3 -3
  102. package/dist/{chunk-HYNTS5CP.js → chunk-HHRZ6STP.js} +24 -2
  103. package/dist/chunk-HIDEIEFG.js +48 -0
  104. package/dist/{chunk-W6RW64BB.cjs → chunk-HSWBIDZM.cjs} +228 -5
  105. package/dist/{chunk-GSOUNWEL.js → chunk-HVX7QQYK.js} +1035 -1616
  106. package/dist/{chunk-TRCGG42I.cjs → chunk-IFW5IW4L.cjs} +6502 -1019
  107. package/dist/{chunk-F5LKJ6F5.cjs → chunk-IJU6AS67.cjs} +32 -28
  108. package/dist/{chunk-TVANHNJ7.js → chunk-IK6Z2HNC.js} +173 -3
  109. package/dist/{chunk-QGMUTVVH.cjs → chunk-IS7NTKY5.cjs} +20 -20
  110. package/dist/{chunk-YFVQWSNJ.js → chunk-IXWGYWH6.js} +3 -3
  111. package/dist/chunk-J2DAS2PL.js +148 -0
  112. package/dist/chunk-JBQXZIWB.js +148 -0
  113. package/dist/chunk-JBYBMBMW.js +261 -0
  114. package/dist/{chunk-LWUOUCYL.js → chunk-JEJ7TT54.js} +5 -5
  115. package/dist/{chunk-DUCB6LGL.js → chunk-JOTCTHN5.js} +211 -5
  116. package/dist/{chunk-47RUFYKR.js → chunk-K56UVEXV.js} +3 -3
  117. package/dist/{chunk-XSFNHP2E.js → chunk-KB26H447.js} +3 -3
  118. package/dist/{chunk-3NGDZZR4.js → chunk-KEYG7HGY.js} +430 -37
  119. package/dist/{chunk-DY72BMU5.js → chunk-KFVNCW4Q.js} +4 -4
  120. package/dist/chunk-KPGC7SK2.js +192 -0
  121. package/dist/chunk-KROXXBK5.cjs +53 -0
  122. package/dist/{chunk-ZPZAVHXL.cjs → chunk-LB3ZZMKT.cjs} +137 -19
  123. package/dist/chunk-LDYZWNJW.cjs +1654 -0
  124. package/dist/{chunk-ULMSSHCJ.cjs → chunk-LMB555QB.cjs} +405 -38
  125. package/dist/{chunk-CBJY23VL.js → chunk-MD4IVS42.js} +3 -3
  126. package/dist/{chunk-VMLKSV26.js → chunk-MDDWEBCX.js} +226 -3
  127. package/dist/chunk-MUWH4QK5.cjs +94 -0
  128. package/dist/{chunk-T6W3Z3SH.cjs → chunk-N2ILK7BF.cjs} +4 -4
  129. package/dist/{chunk-6EX3I5P4.cjs → chunk-N74QRJGP.cjs} +6 -6
  130. package/dist/chunk-NFFHLX37.cjs +132 -0
  131. package/dist/chunk-NJSYWX7H.js +190 -0
  132. package/dist/{chunk-SH5PPVK7.cjs → chunk-NQN5LFN4.cjs} +165 -221
  133. package/dist/chunk-NTQRFOPP.cjs +56 -0
  134. package/dist/{chunk-YFWRJW4B.js → chunk-NWMJPTVL.js} +51 -55
  135. package/dist/{chunk-63ZGNR2T.cjs → chunk-OC6GV5QH.cjs} +42 -42
  136. package/dist/{chunk-7E7GCQCK.js → chunk-OG3MBHM3.js} +9 -3
  137. package/dist/chunk-OMNHTCS4.cjs +264 -0
  138. package/dist/chunk-OQXB6NNC.cjs +117 -0
  139. package/dist/{chunk-Y57W2CT5.cjs → chunk-OV46CCA2.cjs} +51 -55
  140. package/dist/{chunk-6PRZIHGL.cjs → chunk-OV6HHKLE.cjs} +21 -266
  141. package/dist/{chunk-C37BHB7N.cjs → chunk-P26YYPOO.cjs} +5 -5
  142. package/dist/{chunk-2BZHWUSR.cjs → chunk-P7JEKJTZ.cjs} +16 -16
  143. package/dist/{chunk-NGBXXZLL.cjs → chunk-PDXX5UI4.cjs} +45 -45
  144. package/dist/{chunk-FHQFPYV4.js → chunk-PJFTTSKE.js} +8 -7
  145. package/dist/{chunk-GVFJ6T4S.cjs → chunk-PVODJEJ7.cjs} +721 -8
  146. package/dist/{chunk-ZZ7RO2UQ.js → chunk-Q265VZJ4.js} +3 -3
  147. package/dist/{chunk-E7JP3BS3.cjs → chunk-Q47JEE2C.cjs} +4 -4
  148. package/dist/chunk-QBY7LRN2.js +281 -0
  149. package/dist/{chunk-Z6PMDS4G.js → chunk-QDQWKSU3.js} +1090 -53
  150. package/dist/{chunk-GH6C2QGW.cjs → chunk-QEDMOGF3.cjs} +857 -16
  151. package/dist/{chunk-5WUNN6ZN.cjs → chunk-QHSAVOOL.cjs} +24 -2
  152. package/dist/chunk-QJNCDVYM.cjs +137 -0
  153. package/dist/chunk-QM7FJB5W.js +4717 -0
  154. package/dist/chunk-QQFB4RT2.cjs +448 -0
  155. package/dist/chunk-QSYBHQAD.cjs +196 -0
  156. package/dist/{chunk-UGXHYIWT.cjs → chunk-QUJ3ZB55.cjs} +28 -28
  157. package/dist/{chunk-2YSNA2F2.cjs → chunk-QVJMDVYZ.cjs} +5 -5
  158. package/dist/chunk-RAJMAX6D.js +131 -0
  159. package/dist/{chunk-VVKVQZI6.js → chunk-RAN3ECAS.js} +3 -3
  160. package/dist/chunk-RKGUZBOC.js +79 -0
  161. package/dist/{chunk-HLFDZ35S.cjs → chunk-RRQIAJLQ.cjs} +8 -8
  162. package/dist/{chunk-PABONWKI.js → chunk-RXQNRZ5F.js} +3 -3
  163. package/dist/{chunk-7ZHYEITD.cjs → chunk-S4O7CFHQ.cjs} +10 -11
  164. package/dist/chunk-SE7ANBGN.js +128 -0
  165. package/dist/{chunk-X2AVEAZM.cjs → chunk-SJIRCTIS.cjs} +176 -2
  166. package/dist/{chunk-WXQ57LAO.js → chunk-SQXAZHDG.js} +4 -4
  167. package/dist/chunk-SR73L5ZP.cjs +84 -0
  168. package/dist/{chunk-OABEO6HH.js → chunk-SZOLTWWD.js} +2349 -214
  169. package/dist/{chunk-5JEU52DW.js → chunk-TPZ3BN2D.js} +3 -3
  170. package/dist/{chunk-QFU53KRH.js → chunk-TSTFYGGX.js} +4 -5
  171. package/dist/{chunk-EBS32AJI.cjs → chunk-TZCFKZ6Z.cjs} +5 -5
  172. package/dist/chunk-UCVZXQ63.js +724 -0
  173. package/dist/chunk-UGQ3QNV6.js +992 -0
  174. package/dist/chunk-UNMVGZVW.js +142 -0
  175. package/dist/{chunk-TEVX443G.js → chunk-UTUD6GJI.js} +178 -6
  176. package/dist/chunk-UXBYA7DV.cjs +155 -0
  177. package/dist/chunk-V6GXFSK7.cjs +443 -0
  178. package/dist/chunk-VHORVGCG.cjs +761 -0
  179. package/dist/{chunk-B4EKV6HQ.js → chunk-VKCTYLDN.js} +500 -442
  180. package/dist/{chunk-O3MGZDCT.cjs → chunk-VTEXJOSD.cjs} +63 -63
  181. package/dist/chunk-VVAAZITA.cjs +287 -0
  182. package/dist/{chunk-V7AKE5VT.cjs → chunk-W2GA3EQB.cjs} +435 -42
  183. package/dist/chunk-W4GABFCR.js +37 -0
  184. package/dist/chunk-WKEK4NCA.js +490 -0
  185. package/dist/{chunk-5A4TCHOC.cjs → chunk-WNYXT4TE.cjs} +4 -4
  186. package/dist/{chunk-S762UEV5.js → chunk-WTH23ISI.js} +6 -6
  187. package/dist/{chunk-BTKZGHAV.js → chunk-WWNCM473.js} +10 -6
  188. package/dist/{chunk-7X5PNIQJ.js → chunk-X3YFRH6K.js} +27 -25
  189. package/dist/{chunk-4YNYPHH3.cjs → chunk-X75H75UY.cjs} +2351 -213
  190. package/dist/{chunk-LYJJI7ZK.cjs → chunk-XCUDDFKC.cjs} +216 -9
  191. package/dist/chunk-YAO4HPJL.cjs +120 -0
  192. package/dist/chunk-YKY2JBER.cjs +9443 -0
  193. package/dist/chunk-YP5CHEYU.cjs +154 -0
  194. package/dist/{chunk-WRNEH5MO.js → chunk-YW3I2FQL.js} +18 -7
  195. package/dist/{chunk-BRNUPDHJ.js → chunk-Z557DVYN.js} +386 -19
  196. package/dist/{chunk-VSACG2AR.js → chunk-Z6LZUYZF.js} +21 -264
  197. package/dist/chunk-ZHPMP447.cjs +43 -0
  198. package/dist/{chunk-LODTHGST.cjs → chunk-ZK7KX5CD.cjs} +133 -70
  199. package/dist/{chunk-CCPSNT6B.cjs → chunk-ZRPALBQB.cjs} +5 -5
  200. package/dist/chunk-ZVFHPMC5.js +824 -0
  201. package/dist/chunk-ZVQMKUGJ.js +443 -0
  202. package/dist/cli/holoscript-runner.cjs +86 -48
  203. package/dist/cli/holoscript-runner.js +54 -16
  204. package/dist/codebase/index.cjs +1 -1
  205. package/dist/codebase/index.js +1 -1
  206. package/dist/compiler/agent-inference.cjs +11 -11
  207. package/dist/compiler/agent-inference.js +9 -6
  208. package/dist/compiler/android-xr.cjs +13 -12
  209. package/dist/compiler/android-xr.js +11 -10
  210. package/dist/compiler/android.cjs +12 -12
  211. package/dist/compiler/android.js +10 -10
  212. package/dist/compiler/business-quest.cjs +10 -10
  213. package/dist/compiler/business-quest.js +2 -2
  214. package/dist/compiler/coco.cjs +1 -1
  215. package/dist/compiler/coco.js +1 -1
  216. package/dist/compiler/context.cjs +9 -9
  217. package/dist/compiler/context.js +6 -6
  218. package/dist/compiler/daimon-seed.cjs +36 -0
  219. package/dist/compiler/daimon-seed.js +12 -0
  220. package/dist/compiler/domain-block-utils.cjs +205 -156
  221. package/dist/compiler/domain-block-utils.js +8 -7
  222. package/dist/compiler/dtdl.cjs +10 -10
  223. package/dist/compiler/dtdl.js +7 -7
  224. package/dist/compiler/gltf-pipeline.cjs +9 -9
  225. package/dist/compiler/gltf-pipeline.js +2 -2
  226. package/dist/compiler/godot.cjs +10 -9
  227. package/dist/compiler/godot.js +9 -8
  228. package/dist/compiler/incremental.cjs +11 -11
  229. package/dist/compiler/incremental.js +6 -6
  230. package/dist/compiler/index.cjs +2585 -3273
  231. package/dist/compiler/index.d.ts +149 -35
  232. package/dist/compiler/index.js +2197 -3102
  233. package/dist/compiler/ios.cjs +11 -11
  234. package/dist/compiler/ios.js +9 -9
  235. package/dist/compiler/llm-provider-capabilities.cjs +9 -9
  236. package/dist/compiler/llm-provider-capabilities.js +6 -6
  237. package/dist/compiler/nodetoy.cjs +1 -1
  238. package/dist/compiler/nodetoy.js +1 -1
  239. package/dist/compiler/openxr.cjs +11 -10
  240. package/dist/compiler/openxr.js +10 -9
  241. package/dist/compiler/remotion.cjs +1 -1
  242. package/dist/compiler/remotion.js +1 -1
  243. package/dist/compiler/reproducibility.cjs +1 -1
  244. package/dist/compiler/reproducibility.js +1 -1
  245. package/dist/compiler/sdf.cjs +11 -10
  246. package/dist/compiler/sdf.js +9 -8
  247. package/dist/compiler/semantic-scene.cjs +7 -7
  248. package/dist/compiler/semantic-scene.js +2 -2
  249. package/dist/compiler/state.cjs +9 -9
  250. package/dist/compiler/state.js +7 -7
  251. package/dist/compiler/trait-composition.cjs +11 -11
  252. package/dist/compiler/trait-composition.js +7 -7
  253. package/dist/compiler/traits/ProvenanceSemiring.d.ts +167 -0
  254. package/dist/compiler/traits/Semiring.d.ts +26 -0
  255. package/dist/compiler/unity.cjs +11 -10
  256. package/dist/compiler/unity.js +10 -9
  257. package/dist/compiler/unreal.cjs +12 -11
  258. package/dist/compiler/unreal.js +10 -9
  259. package/dist/compiler/urdf.cjs +18 -17
  260. package/dist/compiler/urdf.js +9 -8
  261. package/dist/compiler/usd-physics.cjs +11 -10
  262. package/dist/compiler/usd-physics.js +8 -7
  263. package/dist/compiler/visionos.cjs +11 -10
  264. package/dist/compiler/visionos.js +10 -9
  265. package/dist/compiler/vrchat.cjs +11 -10
  266. package/dist/compiler/vrchat.js +9 -8
  267. package/dist/compiler/wasm.cjs +14 -13
  268. package/dist/compiler/wasm.js +9 -8
  269. package/dist/compiler/webgpu.cjs +10 -9
  270. package/dist/compiler/webgpu.js +9 -8
  271. package/dist/constants.cjs +398 -0
  272. package/dist/constants.js +9 -0
  273. package/dist/coordinators/index.cjs +4 -1
  274. package/dist/coordinators/index.js +4 -1
  275. package/dist/debugger.cjs +11 -9
  276. package/dist/debugger.js +9 -7
  277. package/dist/{dist-ACXG6IH5.cjs → dist-GRMOP2UL.cjs} +341 -65
  278. package/dist/{dist-VD4L6V7Q.js → dist-ZBUKU2JG.js} +333 -63
  279. package/dist/entries/interop.cjs +23 -23
  280. package/dist/entries/interop.js +3 -3
  281. package/dist/entries/scripting.cjs +12 -11
  282. package/dist/entries/scripting.js +8 -7
  283. package/dist/evolution/index.cjs +66 -0
  284. package/dist/evolution/index.d.ts +162 -0
  285. package/dist/evolution/index.js +17 -0
  286. package/dist/hololand/index.cjs +41 -37
  287. package/dist/hololand/index.js +3 -3
  288. package/dist/index.cjs +12394 -3224
  289. package/dist/index.d.ts +260 -18
  290. package/dist/index.js +10755 -2182
  291. package/dist/keyword-registry/PluginKeywordRegistry.d.ts +138 -0
  292. package/dist/keyword-registry/index.cjs +29 -0
  293. package/dist/keyword-registry/index.d.ts +1 -0
  294. package/dist/keyword-registry/index.js +4 -0
  295. package/dist/math/tropical-spmv.cjs +11 -11
  296. package/dist/math/tropical-spmv.d.ts +1 -0
  297. package/dist/math/tropical-spmv.js +2 -2
  298. package/dist/math/tropicalSpmv.d.ts +43 -0
  299. package/dist/math/vec3.cjs +1 -1
  300. package/dist/math/vec3.js +1 -1
  301. package/dist/matter/StagedMatter.d.ts +82 -0
  302. package/dist/matter/index.cjs +17 -0
  303. package/dist/matter/index.d.ts +1 -0
  304. package/dist/matter/index.js +4 -0
  305. package/dist/{ml-dsa-Z7JDKW4L.js → ml-dsa-J6VKVT4K.js} +3 -3
  306. package/dist/{ml-dsa-FSKBTE3W.cjs → ml-dsa-MTIK4ZUQ.cjs} +23 -23
  307. package/dist/paper-0c-spike/index.cjs +1 -1
  308. package/dist/paper-0c-spike/index.js +1 -1
  309. package/dist/parameter-envelope/ParameterEnvelope.d.ts +128 -0
  310. package/dist/parameter-envelope/index.cjs +17 -0
  311. package/dist/parameter-envelope/index.d.ts +2 -0
  312. package/dist/parameter-envelope/index.js +4 -0
  313. package/dist/parser/HoloCompositionTypes.d.ts +2013 -0
  314. package/dist/parser/PipelineParser.d.ts +162 -0
  315. package/dist/parser.cjs +36 -20
  316. package/dist/parser.js +13 -9
  317. package/dist/plugin-manifest/ManifestAutoLoader.d.ts +35 -0
  318. package/dist/plugin-manifest/PluginManifest.d.ts +156 -0
  319. package/dist/plugin-manifest/index.cjs +25 -0
  320. package/dist/plugin-manifest/index.d.ts +2 -0
  321. package/dist/plugin-manifest/index.js +4 -0
  322. package/dist/plugin-solver-contract/PluginSolverContract.d.ts +288 -0
  323. package/dist/plugin-solver-contract/index.cjs +41 -0
  324. package/dist/plugin-solver-contract/index.d.ts +1 -0
  325. package/dist/plugin-solver-contract/index.js +4 -0
  326. package/dist/policy/ContentPolicyGate.d.ts +51 -0
  327. package/dist/policy/PolicyPack.d.ts +120 -0
  328. package/dist/policy/blocklist.d.ts +32 -0
  329. package/dist/policy/defaults.d.ts +44 -0
  330. package/dist/policy/index.cjs +106 -0
  331. package/dist/policy/index.d.ts +17 -0
  332. package/dist/policy/index.js +5 -0
  333. package/dist/policy/jsonLogic.d.ts +31 -0
  334. package/dist/policy/types.d.ts +174 -0
  335. package/dist/proof-composition/ProofCompositionLaw.d.ts +93 -0
  336. package/dist/proof-composition/index.cjs +25 -0
  337. package/dist/proof-composition/index.d.ts +1 -0
  338. package/dist/proof-composition/index.js +4 -0
  339. package/dist/receipts/hash-policy.d.ts +85 -0
  340. package/dist/reconstruction/index.cjs +75 -47
  341. package/dist/reconstruction/index.js +5 -5
  342. package/dist/runtime/plugin-trait-registrar.d.ts +36 -0
  343. package/dist/runtime.cjs +81 -79
  344. package/dist/runtime.js +9 -7
  345. package/dist/scene-presets-EDKYZ5GW.js +4 -0
  346. package/dist/scene-presets-NCW2CFRS.cjs +17 -0
  347. package/dist/self-improvement/index.cjs +1 -1
  348. package/dist/self-improvement/index.js +1 -1
  349. package/dist/{src-PT2FERDV.cjs → src-G3D7ZATQ.cjs} +545 -21
  350. package/dist/{src-J6CM4AUR.js → src-UXYA7HM6.js} +539 -16
  351. package/dist/storage/index.cjs +10 -10
  352. package/dist/storage/index.js +3 -3
  353. package/dist/testing.cjs +1 -1
  354. package/dist/testing.js +1 -1
  355. package/dist/tools/index.cjs +3631 -0
  356. package/dist/tools/index.js +3581 -0
  357. package/dist/traitDocs/traitDocs.cjs +9 -9
  358. package/dist/traitDocs/traitDocs.d.ts +1 -0
  359. package/dist/traitDocs/traitDocs.js +3 -3
  360. package/dist/traits/ControlLoopTrait.d.ts +154 -0
  361. package/dist/traits/KinematicChainTrait.d.ts +116 -0
  362. package/dist/traits/SensorSamplingTrait.d.ts +154 -0
  363. package/dist/traits/TraitTypes.d.ts +270 -0
  364. package/dist/traits/TransactionTrait.d.ts +121 -0
  365. package/dist/traits/botanical-lotus.cjs +54 -50
  366. package/dist/traits/botanical-lotus.js +2 -5
  367. package/dist/traits/control-loop.cjs +21 -0
  368. package/dist/traits/control-loop.d.ts +1 -0
  369. package/dist/traits/control-loop.js +4 -0
  370. package/dist/traits/engines/cloth-verlet.d.ts +65 -0
  371. package/dist/traits/engines/index.cjs +19 -19
  372. package/dist/traits/engines/index.d.ts +15 -275
  373. package/dist/traits/engines/index.js +3 -3
  374. package/dist/traits/engines/motion-data-schema.d.ts +119 -0
  375. package/dist/traits/engines/motion-matching.d.ts +102 -0
  376. package/dist/traits/engines/noise.d.ts +25 -0
  377. package/dist/traits/engines/onnx-adapter.d.ts +173 -0
  378. package/dist/traits/engines/onnx-motion-matching.d.ts +163 -0
  379. package/dist/traits/engines/pfnn-network.d.ts +92 -0
  380. package/dist/traits/engines/synthetic-walk-cycle.d.ts +38 -0
  381. package/dist/traits/engines/tensor-ops.d.ts +15 -0
  382. package/dist/traits/index.cjs +2789 -1259
  383. package/dist/traits/index.d.ts +35 -0
  384. package/dist/traits/index.js +1692 -411
  385. package/dist/traits/kinematic-chain.cjs +25 -0
  386. package/dist/traits/kinematic-chain.d.ts +1 -0
  387. package/dist/traits/kinematic-chain.js +4 -0
  388. package/dist/traits/sensor-sampling.cjs +33 -0
  389. package/dist/traits/sensor-sampling.d.ts +1 -0
  390. package/dist/traits/sensor-sampling.js +4 -0
  391. package/dist/traits/simulation-solver-factory.cjs +1 -1
  392. package/dist/traits/simulation-solver-factory.js +1 -1
  393. package/dist/traits/transaction.cjs +29 -0
  394. package/dist/traits/transaction.d.ts +1 -0
  395. package/dist/traits/transaction.js +4 -0
  396. package/dist/traits/webcam-gaze.cjs +1 -1
  397. package/dist/traits/webcam-gaze.js +1 -1
  398. package/dist/type-checker.cjs +7 -6
  399. package/dist/type-checker.js +5 -4
  400. package/dist/types/AdvancedTypeSystem.d.ts +489 -0
  401. package/dist/types/HoloScriptPlus.d.ts +810 -0
  402. package/dist/types/base.d.ts +248 -0
  403. package/dist/types.d.ts +799 -0
  404. package/dist/world/index.cjs +3 -4
  405. package/dist/world/index.js +3 -4
  406. package/dist/world-model/index.cjs +1 -1
  407. package/dist/world-model/index.js +1 -1
  408. package/dist/wot/index.cjs +1 -1
  409. package/dist/wot/index.js +1 -1
  410. package/package.json +80 -13
  411. package/dist/GLTFPipeline-3EJLL3TS.cjs +0 -38
  412. package/dist/GLTFPipeline-3OWJV2VK.js +0 -17
  413. package/dist/HoloScriptPlusParser-ADWRY5OS.cjs +0 -698
  414. package/dist/HoloScriptPlusParser-JLJDXHSC.js +0 -693
  415. package/dist/HoloScriptPlusParser-QCGFPWIL.cjs +0 -27
  416. package/dist/HoloScriptPlusParser-WENAFEFV.js +0 -10
  417. package/dist/HoloScriptRuntime-GGRVEU4T.cjs +0 -19
  418. package/dist/HoloScriptRuntime-GJK6VJPH.js +0 -10
  419. package/dist/chunk-22Q5A6RV.js +0 -979
  420. package/dist/chunk-4C57PR42.js +0 -468
  421. package/dist/chunk-4W5G5QVL.cjs +0 -847
  422. package/dist/chunk-5ET6L4NS.js +0 -487
  423. package/dist/chunk-C4GSLCHE.cjs +0 -7153
  424. package/dist/chunk-F2G6CWFT.js +0 -7089
  425. package/dist/chunk-G6PNEASF.cjs +0 -814
  426. package/dist/chunk-GTA4Q3A3.js +0 -1491
  427. package/dist/chunk-HCCQLAA4.cjs +0 -74
  428. package/dist/chunk-HFSVMKM3.cjs +0 -72
  429. package/dist/chunk-KAIVDEIG.cjs +0 -4539
  430. package/dist/chunk-KQU64CIX.cjs +0 -1508
  431. package/dist/chunk-MSYSQ2AJ.js +0 -4533
  432. package/dist/chunk-NHJLP37F.js +0 -70
  433. package/dist/chunk-NHYRRAGI.cjs +0 -490
  434. package/dist/chunk-OIQYIIO3.cjs +0 -473
  435. package/dist/chunk-OL46QLBJ.js +0 -61
  436. package/dist/chunk-SKZPC5AG.cjs +0 -984
  437. package/dist/chunk-SLHLXUMO.js +0 -445
  438. package/dist/chunk-UOIGFQXC.cjs +0 -9750
  439. package/dist/chunk-UOL6Y5TD.cjs +0 -759
  440. package/dist/chunk-UVFI7XIR.cjs +0 -452
  441. package/dist/chunk-VEPGBETF.js +0 -844
  442. package/dist/chunk-XQ5MWMP2.js +0 -756
  443. package/dist/chunk-XT6JY5W5.js +0 -9684
  444. package/dist/chunk-YRRAUB35.js +0 -811
  445. package/dist/compiler/GasOptimizationAnalyzer.d.ts +0 -73
  446. package/dist/compiler/NFTMarketplaceCompiler.d.ts +0 -23
  447. package/dist/compiler/ar.cjs +0 -23
  448. package/dist/compiler/ar.js +0 -11
  449. package/dist/compiler/babylon.cjs +0 -21
  450. package/dist/compiler/babylon.js +0 -15
  451. package/dist/compiler/multi-layer.cjs +0 -24
  452. package/dist/compiler/multi-layer.js +0 -15
  453. package/dist/compiler/playcanvas.cjs +0 -19
  454. package/dist/compiler/playcanvas.js +0 -13
  455. package/dist/compiler/r3f.cjs +0 -39
  456. package/dist/compiler/r3f.d.ts +0 -22
  457. package/dist/compiler/r3f.js +0 -17
  458. package/dist/compiler/vrr.cjs +0 -24
  459. package/dist/compiler/vrr.js +0 -12
  460. package/dist/parser/NFTMarketplaceTypes.d.ts +0 -191
  461. package/dist/playwright-3AT3AKTV.cjs +0 -98673
  462. package/dist/playwright-VZPDVUEQ.js +0 -98660
@@ -1,6 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  var chunk3VBO3IYQ_cjs = require('./chunk-3VBO3IYQ.cjs');
4
+ var chunkOV6HHKLE_cjs = require('./chunk-OV6HHKLE.cjs');
4
5
 
5
6
  // src/parser/TypoDetector.ts
6
7
  var TypoDetector = class {
@@ -172,6 +173,17 @@ var KEYWORDS = {
172
173
  waypoints: "WAYPOINTS",
173
174
  constraint: "CONSTRAINT",
174
175
  terrain: "TERRAIN",
176
+ // MMO/AAA game constructs (v6.2)
177
+ loot_table: "LOOT_TABLE",
178
+ world_chunk: "WORLD_CHUNK",
179
+ spawn_point: "SPAWN_POINT",
180
+ game_trigger: "GAME_TRIGGER",
181
+ movement_path: "MOVEMENT_PATH",
182
+ reaction_trigger: "REACTION_TRIGGER",
183
+ world_layer: "WORLD_LAYER",
184
+ dungeon_instance: "DUNGEON_INSTANCE",
185
+ world_shard: "WORLD_SHARD",
186
+ real_estate: "REAL_ESTATE",
175
187
  // IoT / Digital Twin
176
188
  sensor: "IOT_SENSOR",
177
189
  device: "IOT_DEVICE",
@@ -252,6 +264,10 @@ var KEYWORDS = {
252
264
  bridge: "WEB3_CONTRACT",
253
265
  // Perception & simulation layer (v4.2 — March 2026)
254
266
  material: "MATERIAL",
267
+ material_graph: "MATERIAL_GRAPH",
268
+ light_field: "LIGHT_FIELD",
269
+ nav_field: "NAV_FIELD",
270
+ physics_contract: "PHYSICS_CONTRACT",
255
271
  pbr_material: "PBR_MATERIAL",
256
272
  unlit_material: "UNLIT_MATERIAL",
257
273
  shader: "SHADER",
@@ -273,6 +289,7 @@ var KEYWORDS = {
273
289
  particles: "PARTICLES",
274
290
  emitter: "EMITTER",
275
291
  vfx: "VFX",
292
+ particle_field: "PARTICLE_FIELD",
276
293
  post_processing: "POST_PROCESSING",
277
294
  post_fx: "POST_FX",
278
295
  render_pipeline: "POST_PROCESSING",
@@ -288,6 +305,7 @@ var KEYWORDS = {
288
305
  climate: "WEATHER",
289
306
  simulation: "SIMULATION",
290
307
  procedural: "PROCEDURAL",
308
+ pcg_graph: "PCG_GRAPH",
291
309
  generate: "PROCEDURAL",
292
310
  scatter: "SCATTER",
293
311
  distribute: "SCATTER",
@@ -331,6 +349,11 @@ var KEYWORDS = {
331
349
  payment_gate: "PAYMENT_GATE",
332
350
  subscription: "SUBSCRIPTION",
333
351
  tip_jar: "TIP_JAR",
352
+ // SimulationContract block (v6.3 — NORTH_STAR thesis: simulation IS the proof)
353
+ sim_contract: "HOLO_CONTRACT",
354
+ // Pub/sub messaging primitives (v6.4)
355
+ topic: "HOLO_TOPIC",
356
+ channel: "HOLO_CHANNEL",
334
357
  // v6 Universal domains (v5.4 — Domains Unified)
335
358
  service: "SERVICE_BLOCK",
336
359
  endpoint: "ENDPOINT_BLOCK",
@@ -762,6 +785,7 @@ var KEYWORDS_AS_IDENTIFIERS = [
762
785
  "EFFECTS",
763
786
  "CAMERA",
764
787
  "BIND",
788
+ "CONNECT",
765
789
  "TIMELINE",
766
790
  "AUDIO",
767
791
  "ZONE",
@@ -794,7 +818,9 @@ var KEYWORDS_AS_IDENTIFIERS = [
794
818
  "COMPOSITION",
795
819
  "SPATIAL_GROUP",
796
820
  "SPATIAL_AGENT",
797
- "SPATIAL_CONTAINER"
821
+ "SPATIAL_CONTAINER",
822
+ "HOLO_TOPIC",
823
+ "HOLO_CHANNEL"
798
824
  ];
799
825
  function isKeywordAsIdentifierType(api, type) {
800
826
  if (api.DOMAIN_TOKENS.has(type)) return true;
@@ -1050,7 +1076,6 @@ function parseObjectExpression(api) {
1050
1076
 
1051
1077
  // src/parser/HoloCompositionParser.ts
1052
1078
  var _HoloCompositionParser = class _HoloCompositionParser {
1053
- // Track parsing context for better errors
1054
1079
  constructor(options = {}) {
1055
1080
  this.tokens = [];
1056
1081
  this.pos = 0;
@@ -1063,6 +1088,15 @@ var _HoloCompositionParser = class _HoloCompositionParser {
1063
1088
  strict: false,
1064
1089
  ...options
1065
1090
  };
1091
+ this.errorRecovery = new chunkOV6HHKLE_cjs.ErrorRecovery(this.options.knownTraits);
1092
+ }
1093
+ /**
1094
+ * The error-recovery engine for this parser, seeded with the injected
1095
+ * `knownTraits` union when one was supplied via parser options. Exposed so
1096
+ * tooling (and tests) can verify the trait-vocabulary seam is wired through.
1097
+ */
1098
+ getErrorRecovery() {
1099
+ return this.errorRecovery;
1066
1100
  }
1067
1101
  /** Instance accessor for the static DOMAIN_TOKENS set — satisfies ExpressionParserApi. */
1068
1102
  get DOMAIN_TOKENS() {
@@ -1137,7 +1171,18 @@ var _HoloCompositionParser = class _HoloCompositionParser {
1137
1171
  domainBlocks: [],
1138
1172
  // v4.5 additions — CRSEC norm lifecycle
1139
1173
  norms: [],
1140
- metanorms: []
1174
+ metanorms: [],
1175
+ // v6.2 additions — MMO/AAA game constructs
1176
+ spawnPoints: [],
1177
+ triggers: [],
1178
+ lootTables: [],
1179
+ worldChunks: [],
1180
+ worldLayers: [],
1181
+ dungeonInstances: [],
1182
+ worldShards: [],
1183
+ movementPaths: [],
1184
+ reactionTriggers: [],
1185
+ policyPacks: []
1141
1186
  };
1142
1187
  while (!this.isAtEnd()) {
1143
1188
  try {
@@ -1181,8 +1226,9 @@ var _HoloCompositionParser = class _HoloCompositionParser {
1181
1226
  } else if (decoratorName === "state") {
1182
1227
  composition.state = this.parseStateBody();
1183
1228
  } else if (decoratorName === "state_machine") {
1229
+ const name = this.parseOptionalStateMachineName("implicit");
1184
1230
  if (this.check("LBRACE")) {
1185
- composition.stateMachines.push(this.parseStateMachineFromDecorator());
1231
+ composition.stateMachines.push(this.parseStateMachineFromDecorator(name));
1186
1232
  }
1187
1233
  } else {
1188
1234
  composition.traits = composition.traits || [];
@@ -1212,7 +1258,7 @@ var _HoloCompositionParser = class _HoloCompositionParser {
1212
1258
  composition.logic = this.parseLogic();
1213
1259
  } else if (this.check("TIMELINE")) {
1214
1260
  composition.timelines.push(this.parseTimeline());
1215
- } else if (this.check("STATE")) {
1261
+ } else if (this.check("STATE") && this.peek(1).type !== "COLON") {
1216
1262
  composition.state = this.parseState();
1217
1263
  } else if (this.check("IMPORT")) {
1218
1264
  composition.imports.push(this.parseImport());
@@ -1247,8 +1293,53 @@ var _HoloCompositionParser = class _HoloCompositionParser {
1247
1293
  composition.norms.push(this.parseNormBlock());
1248
1294
  } else if (this.check("METANORM")) {
1249
1295
  composition.metanorms.push(this.parseMetanormBlock());
1296
+ } else if (this.check("HOLO_CONTRACT")) {
1297
+ composition.contract = this.parseContractBlock();
1298
+ } else if (this.check("IDENTIFIER") && this.current().value === "policy_pack") {
1299
+ composition.policyPacks.push(this.parsePolicyPackBlock());
1300
+ } else if (this.check("HOLO_TOPIC")) {
1301
+ if (!composition.topics) composition.topics = [];
1302
+ composition.topics.push(this.parseTopicBlock());
1303
+ } else if (this.check("HOLO_CHANNEL")) {
1304
+ if (!composition.channels) composition.channels = [];
1305
+ composition.channels.push(this.parseChannelBlock());
1306
+ } else if (this.check("CONNECT")) {
1307
+ if (!composition.connections) composition.connections = [];
1308
+ composition.connections.push(this.parseConnectionStmt());
1309
+ } else if (this.check("IDENTIFIER") && this.current().value === "shareplay") {
1310
+ composition.metadata = {
1311
+ ...composition.metadata ?? {},
1312
+ shareplay: this.parseSharePlayBlock()
1313
+ };
1314
+ } else if (this.isLooseOnHandlerStart()) {
1315
+ this.skipLooseOnHandler();
1316
+ } else if (this.check("LOOT_TABLE")) {
1317
+ composition.lootTables.push(this.parseLootTable());
1318
+ } else if (this.check("WORLD_CHUNK")) {
1319
+ composition.worldChunks.push(this.parseWorldChunk());
1320
+ } else if (this.check("SPAWN_POINT")) {
1321
+ composition.spawnPoints.push(this.parseSpawnPoint());
1322
+ } else if (this.check("GAME_TRIGGER")) {
1323
+ composition.triggers.push(this.parseGameTrigger());
1324
+ } else if (this.check("MOVEMENT_PATH")) {
1325
+ composition.movementPaths.push(this.parseMovementPath());
1326
+ } else if (this.check("REACTION_TRIGGER")) {
1327
+ composition.reactionTriggers.push(this.parseReactionTrigger());
1328
+ } else if (this.check("WORLD_LAYER")) {
1329
+ composition.worldLayers.push(this.parseWorldLayer());
1330
+ } else if (this.check("DUNGEON_INSTANCE")) {
1331
+ composition.dungeonInstances.push(this.parseDungeonInstance());
1332
+ } else if (this.check("WORLD_SHARD")) {
1333
+ composition.worldShards.push(this.parseWorldShard());
1334
+ } else if (this.check("REAL_ESTATE")) {
1335
+ composition.domainBlocks.push(this.parseDomainBlock());
1336
+ } else if (this.check("SCENE")) {
1337
+ if (!composition.scenes) composition.scenes = [];
1338
+ composition.scenes.push(this.parseScene());
1250
1339
  } else if (this.isDomainBlockToken()) {
1251
1340
  composition.domainBlocks.push(this.parseDomainBlock());
1341
+ } else if (this.isLooseDomainBlockStart() || this.isLooseNamedDomainBlockStart()) {
1342
+ composition.domainBlocks.push(this.parseDomainBlock());
1252
1343
  } else if (this.check("MODULE")) {
1253
1344
  this.advance();
1254
1345
  if (this.check("STRING")) this.expectString();
@@ -1304,12 +1395,18 @@ var _HoloCompositionParser = class _HoloCompositionParser {
1304
1395
  this.expect("LBRACE");
1305
1396
  this.skipNewlines();
1306
1397
  while (!this.check("RBRACE") && !this.isAtEnd()) {
1307
- this.skipNewlines();
1398
+ this.skipBlockMemberSeparators();
1308
1399
  if (this.check("RBRACE")) break;
1309
- const key = this.expectIdentifier();
1310
- this.expect("COLON");
1311
- const value = this.parseValue();
1312
- properties.push({ type: "EnvironmentProperty", key, value });
1400
+ if (this.isPropertyName() && this.peek(1).type === "LBRACE") {
1401
+ const key = this.parsePropertyKey();
1402
+ const value = this.parseBlockTraitConfig();
1403
+ properties.push({ type: "EnvironmentProperty", key, value });
1404
+ } else {
1405
+ const key = this.parsePropertyKey();
1406
+ this.expect("COLON");
1407
+ const value = this.parseValue();
1408
+ properties.push({ type: "EnvironmentProperty", key, value });
1409
+ }
1313
1410
  this.skipNewlines();
1314
1411
  }
1315
1412
  this.expect("RBRACE");
@@ -1339,15 +1436,15 @@ var _HoloCompositionParser = class _HoloCompositionParser {
1339
1436
  this.expect("LBRACE");
1340
1437
  this.skipNewlines();
1341
1438
  while (!this.check("RBRACE") && !this.isAtEnd()) {
1342
- this.skipNewlines();
1439
+ this.skipBlockMemberSeparators();
1343
1440
  if (this.check("RBRACE")) break;
1344
1441
  if (this.check("AT")) {
1345
1442
  this.advance();
1346
1443
  const traitName = this.expectIdentifier();
1347
1444
  const config = this.parseOptionalTraitConfig();
1348
1445
  traits.push({ type: "ObjectTrait", name: traitName, config });
1349
- } else if (this.check("IDENTIFIER")) {
1350
- const key = this.expectIdentifier();
1446
+ } else if (this.isPropertyName()) {
1447
+ const key = this.parsePropertyKey();
1351
1448
  if (this.check("COLON")) {
1352
1449
  this.advance();
1353
1450
  properties.push({ type: "ObjectProperty", key, value: this.parseValue() });
@@ -1435,13 +1532,31 @@ var _HoloCompositionParser = class _HoloCompositionParser {
1435
1532
  domainBlocks: [],
1436
1533
  // v4.5 additions — CRSEC norm lifecycle
1437
1534
  norms: [],
1438
- metanorms: []
1535
+ metanorms: [],
1536
+ // v6.2 additions — MMO/AAA game constructs
1537
+ spawnPoints: [],
1538
+ triggers: [],
1539
+ lootTables: [],
1540
+ worldChunks: [],
1541
+ worldLayers: [],
1542
+ dungeonInstances: [],
1543
+ worldShards: [],
1544
+ movementPaths: [],
1545
+ reactionTriggers: [],
1546
+ policyPacks: []
1439
1547
  };
1440
1548
  while (!this.check("RBRACE") && !this.isAtEnd()) {
1441
1549
  try {
1442
- this.skipNewlines();
1550
+ this.skipBlockMemberSeparators();
1443
1551
  if (this.check("RBRACE")) break;
1444
- if (this.check("IMPORT")) {
1552
+ if (this.peek(1).type === "COLON" && (this.isPropertyName() || this.check("METADATA_BLOCK"))) {
1553
+ const key = this.advance().value;
1554
+ this.advance();
1555
+ const value = !this.check("RBRACE") && !this.isAtEnd() ? this.parseValue() : null;
1556
+ if (key === "metadata" && value && typeof value === "object" && !Array.isArray(value)) {
1557
+ composition.metadata = { ...composition.metadata ?? {}, ...value };
1558
+ }
1559
+ } else if (this.check("IMPORT")) {
1445
1560
  composition.imports.push(this.parseImport());
1446
1561
  } else if (this.check("THEME")) {
1447
1562
  composition.theme = this.parseTheme();
@@ -1450,7 +1565,7 @@ var _HoloCompositionParser = class _HoloCompositionParser {
1450
1565
  } else if (this.check("SCENE")) {
1451
1566
  if (!composition.scenes) composition.scenes = [];
1452
1567
  composition.scenes.push(this.parseScene());
1453
- } else if (this.check("STATE")) {
1568
+ } else if (this.check("STATE") && this.peek(1).type !== "COLON") {
1454
1569
  composition.state = this.parseState();
1455
1570
  } else if (this.check("METADATA_BLOCK")) {
1456
1571
  this.advance();
@@ -1522,8 +1637,48 @@ var _HoloCompositionParser = class _HoloCompositionParser {
1522
1637
  composition.norms.push(this.parseNormBlock());
1523
1638
  } else if (this.check("METANORM")) {
1524
1639
  composition.metanorms.push(this.parseMetanormBlock());
1640
+ } else if (this.check("HOLO_CONTRACT")) {
1641
+ composition.contract = this.parseContractBlock();
1642
+ } else if (this.check("IDENTIFIER") && this.current().value === "policy_pack") {
1643
+ composition.policyPacks.push(this.parsePolicyPackBlock());
1644
+ } else if (this.check("HOLO_TOPIC")) {
1645
+ if (!composition.topics) composition.topics = [];
1646
+ composition.topics.push(this.parseTopicBlock());
1647
+ } else if (this.check("HOLO_CHANNEL")) {
1648
+ if (!composition.channels) composition.channels = [];
1649
+ composition.channels.push(this.parseChannelBlock());
1650
+ } else if (this.check("CONNECT")) {
1651
+ if (!composition.connections) composition.connections = [];
1652
+ composition.connections.push(this.parseConnectionStmt());
1653
+ } else if (this.check("IDENTIFIER") && this.current().value === "shareplay") {
1654
+ composition.metadata = {
1655
+ ...composition.metadata ?? {},
1656
+ shareplay: this.parseSharePlayBlock()
1657
+ };
1658
+ } else if (this.check("LOOT_TABLE")) {
1659
+ composition.lootTables.push(this.parseLootTable());
1660
+ } else if (this.check("WORLD_CHUNK")) {
1661
+ composition.worldChunks.push(this.parseWorldChunk());
1662
+ } else if (this.check("SPAWN_POINT")) {
1663
+ composition.spawnPoints.push(this.parseSpawnPoint());
1664
+ } else if (this.check("GAME_TRIGGER")) {
1665
+ composition.triggers.push(this.parseGameTrigger());
1666
+ } else if (this.check("MOVEMENT_PATH")) {
1667
+ composition.movementPaths.push(this.parseMovementPath());
1668
+ } else if (this.check("REACTION_TRIGGER")) {
1669
+ composition.reactionTriggers.push(this.parseReactionTrigger());
1670
+ } else if (this.check("WORLD_LAYER")) {
1671
+ composition.worldLayers.push(this.parseWorldLayer());
1672
+ } else if (this.check("DUNGEON_INSTANCE")) {
1673
+ composition.dungeonInstances.push(this.parseDungeonInstance());
1674
+ } else if (this.check("WORLD_SHARD")) {
1675
+ composition.worldShards.push(this.parseWorldShard());
1676
+ } else if (this.check("REAL_ESTATE")) {
1677
+ composition.domainBlocks.push(this.parseDomainBlock());
1525
1678
  } else if (this.isDomainBlockToken()) {
1526
1679
  composition.domainBlocks.push(this.parseDomainBlock());
1680
+ } else if (this.isLooseDomainBlockStart() || this.isLooseNamedDomainBlockStart()) {
1681
+ composition.domainBlocks.push(this.parseDomainBlock());
1527
1682
  } else if (this.check("MODULE")) {
1528
1683
  composition.domainBlocks.push(this.parseDomainBlock());
1529
1684
  } else if (this.check("AT")) {
@@ -1564,8 +1719,9 @@ var _HoloCompositionParser = class _HoloCompositionParser {
1564
1719
  } else if (decoratorName === "world" || decoratorName === "environment") {
1565
1720
  composition.environment = this.parseEnvironmentBody();
1566
1721
  } else if (decoratorName === "state_machine") {
1722
+ const name2 = this.parseOptionalStateMachineName("implicit");
1567
1723
  if (this.check("LBRACE")) {
1568
- composition.stateMachines.push(this.parseStateMachineFromDecorator());
1724
+ composition.stateMachines.push(this.parseStateMachineFromDecorator(name2));
1569
1725
  }
1570
1726
  } else {
1571
1727
  composition.traits = composition.traits || [];
@@ -1576,6 +1732,8 @@ var _HoloCompositionParser = class _HoloCompositionParser {
1576
1732
  } else if (this.check("ACTION") || this.check("ASYNC")) {
1577
1733
  composition.actions = composition.actions || [];
1578
1734
  composition.actions.push(this.parseAction());
1735
+ } else if (this.check("FUNCTION")) {
1736
+ this.skipFunctionDeclaration();
1579
1737
  } else if (this.check("USING")) {
1580
1738
  this.advance();
1581
1739
  if (this.check("STRING") || this.check("IDENTIFIER")) this.advance();
@@ -1583,27 +1741,8 @@ var _HoloCompositionParser = class _HoloCompositionParser {
1583
1741
  this.advance();
1584
1742
  if (this.check("IDENTIFIER")) this.advance();
1585
1743
  }
1586
- } else if (this.check("IDENTIFIER") && this.current().value === "on" && this.peek(1).type === "IDENTIFIER") {
1587
- const eventName = this.peek(1).value;
1588
- this.advance();
1589
- this.advance();
1590
- while (this.check("DOT")) {
1591
- this.advance();
1592
- if (this.check("IDENTIFIER")) this.advance();
1593
- }
1594
- let parameters = [];
1595
- if (this.check("LPAREN")) {
1596
- parameters = this.parseParameterList();
1597
- }
1598
- if (this.check("LBRACE")) this.skipBlock();
1599
- composition.eventHandlers = composition.eventHandlers || [];
1600
- composition.eventHandlers.push({
1601
- type: "EventHandler",
1602
- event: eventName,
1603
- parameters,
1604
- body: []
1605
- // Skipped body
1606
- });
1744
+ } else if (this.isLooseOnHandlerStart()) {
1745
+ this.skipLooseOnHandler();
1607
1746
  } else if (this.check("COLON")) {
1608
1747
  this.advance();
1609
1748
  if (!this.check("RBRACE") && !this.isAtEnd()) this.parseValue();
@@ -1632,6 +1771,10 @@ var _HoloCompositionParser = class _HoloCompositionParser {
1632
1771
  if (this.check("COLON")) {
1633
1772
  this.advance();
1634
1773
  if (!this.check("RBRACE") && !this.isAtEnd()) this.parseValue();
1774
+ } else if (this.check("LBRACKET")) {
1775
+ this.advance();
1776
+ while (!this.check("RBRACKET") && !this.isAtEnd()) this.advance();
1777
+ if (this.check("RBRACKET")) this.advance();
1635
1778
  } else {
1636
1779
  if (this.check("STRING") || this.check("IDENTIFIER")) this.advance();
1637
1780
  if (this.check("LPAREN")) this.skipParens();
@@ -1780,7 +1923,7 @@ var _HoloCompositionParser = class _HoloCompositionParser {
1780
1923
  this.skipNewlines();
1781
1924
  const properties = [];
1782
1925
  while (!this.check("RBRACE") && !this.isAtEnd()) {
1783
- this.skipNewlines();
1926
+ this.skipBlockMemberSeparators();
1784
1927
  if (this.check("RBRACE")) break;
1785
1928
  if (this.check("PARTICLES") || this.check("PARTICLE_SYSTEM")) {
1786
1929
  const ps = this.parseParticleSystem();
@@ -1789,15 +1932,16 @@ var _HoloCompositionParser = class _HoloCompositionParser {
1789
1932
  key: ps.name,
1790
1933
  value: ps
1791
1934
  });
1935
+ } else if (this.isPropertyName() && this.peek(1).type === "LBRACE") {
1936
+ const key = this.parsePropertyKey();
1937
+ const value = this.parseBlockTraitConfig();
1938
+ properties.push({ type: "EnvironmentProperty", key, value });
1792
1939
  } else {
1793
- const key = this.expectIdentifier();
1940
+ const key = this.parsePropertyKey();
1794
1941
  this.expect("COLON");
1795
1942
  const value = this.parseValue();
1796
1943
  properties.push({ type: "EnvironmentProperty", key, value });
1797
1944
  }
1798
- if (this.check("SEMICOLON")) {
1799
- this.advance();
1800
- }
1801
1945
  this.skipNewlines();
1802
1946
  }
1803
1947
  this.expect("RBRACE");
@@ -1827,14 +1971,19 @@ var _HoloCompositionParser = class _HoloCompositionParser {
1827
1971
  let environment;
1828
1972
  const objects = [];
1829
1973
  while (!this.check("RBRACE") && !this.isAtEnd()) {
1830
- this.skipNewlines();
1974
+ this.skipBlockMemberSeparators();
1831
1975
  if (this.check("RBRACE")) break;
1832
1976
  if (this.check("ENVIRONMENT")) {
1833
1977
  environment = this.parseEnvironment();
1834
1978
  } else if (this.check("OBJECT")) {
1835
1979
  objects.push(this.parseObject());
1980
+ } else if (this.check("LBRACE")) {
1981
+ this.skipBlock();
1836
1982
  } else {
1837
1983
  this.advance();
1984
+ if (this.check("STRING") || this.check("IDENTIFIER")) this.advance();
1985
+ if (this.check("LPAREN")) this.skipParens();
1986
+ if (this.check("LBRACE")) this.skipBlock();
1838
1987
  }
1839
1988
  }
1840
1989
  this.expect("RBRACE");
@@ -1858,7 +2007,7 @@ var _HoloCompositionParser = class _HoloCompositionParser {
1858
2007
  this.skipNewlines();
1859
2008
  const properties = {};
1860
2009
  while (!this.check("RBRACE") && !this.isAtEnd()) {
1861
- this.skipNewlines();
2010
+ this.skipBlockMemberSeparators();
1862
2011
  if (this.check("RBRACE")) break;
1863
2012
  const key = this.expectIdentifier();
1864
2013
  this.expect("COLON");
@@ -1896,24 +2045,18 @@ var _HoloCompositionParser = class _HoloCompositionParser {
1896
2045
  this.advance();
1897
2046
  }
1898
2047
  }
2048
+ const inlineTraitProperties = [];
2049
+ while (this.check("AT")) {
2050
+ inlineTraitProperties.push(this.parseTraitAsLightProperty(true));
2051
+ }
1899
2052
  this.expect("LBRACE");
1900
2053
  this.skipNewlines();
1901
- const properties = [];
2054
+ const properties = [...inlineTraitProperties];
1902
2055
  while (!this.check("RBRACE") && !this.isAtEnd()) {
1903
- this.skipNewlines();
2056
+ this.skipBlockMemberSeparators();
1904
2057
  if (this.check("RBRACE")) break;
1905
2058
  if (this.check("AT")) {
1906
- this.advance();
1907
- const traitName = this.parseTraitName();
1908
- const cfg = this.parseOptionalTraitConfig();
1909
- const cfgKeys = Object.keys(cfg);
1910
- let traitValue;
1911
- if (cfgKeys.length === 0) traitValue = true;
1912
- else if (cfgKeys.every((k) => /^_arg\d+$/.test(k))) {
1913
- const arr = cfgKeys.sort().map((k) => cfg[k]);
1914
- traitValue = arr.length === 1 ? arr[0] : arr;
1915
- } else traitValue = cfg;
1916
- properties.push({ type: "LightProperty", key: traitName, value: traitValue });
2059
+ properties.push(this.parseTraitAsLightProperty());
1917
2060
  this.skipNewlines();
1918
2061
  continue;
1919
2062
  }
@@ -1949,6 +2092,19 @@ var _HoloCompositionParser = class _HoloCompositionParser {
1949
2092
  properties
1950
2093
  };
1951
2094
  }
2095
+ parseTraitAsLightProperty(requireBodyAfterBareBrace = false) {
2096
+ this.expect("AT");
2097
+ const traitName = this.parseTraitName();
2098
+ const cfg = this.parseOptionalTraitConfig(requireBodyAfterBareBrace);
2099
+ const cfgKeys = Object.keys(cfg);
2100
+ let traitValue;
2101
+ if (cfgKeys.length === 0) traitValue = true;
2102
+ else if (cfgKeys.every((k) => /^_arg\d+$/.test(k))) {
2103
+ const arr = cfgKeys.sort().map((k) => cfg[k]);
2104
+ traitValue = arr.length === 1 ? arr[0] : arr;
2105
+ } else traitValue = cfg;
2106
+ return { type: "LightProperty", key: traitName, value: traitValue };
2107
+ }
1952
2108
  // ===========================================================================
1953
2109
  // EFFECTS (post-processing block)
1954
2110
  // ===========================================================================
@@ -1959,14 +2115,14 @@ var _HoloCompositionParser = class _HoloCompositionParser {
1959
2115
  this.skipNewlines();
1960
2116
  const effects = [];
1961
2117
  while (!this.check("RBRACE") && !this.isAtEnd()) {
1962
- this.skipNewlines();
2118
+ this.skipBlockMemberSeparators();
1963
2119
  if (this.check("RBRACE")) break;
1964
2120
  const effectType = this.expectIdentifier();
1965
2121
  this.expect("LBRACE");
1966
2122
  this.skipNewlines();
1967
2123
  const properties = {};
1968
2124
  while (!this.check("RBRACE") && !this.isAtEnd()) {
1969
- this.skipNewlines();
2125
+ this.skipBlockMemberSeparators();
1970
2126
  if (this.check("RBRACE")) break;
1971
2127
  const key = this.expectIdentifier();
1972
2128
  this.expect("COLON");
@@ -2008,7 +2164,7 @@ var _HoloCompositionParser = class _HoloCompositionParser {
2008
2164
  this.skipNewlines();
2009
2165
  const properties = [];
2010
2166
  while (!this.check("RBRACE") && !this.isAtEnd()) {
2011
- this.skipNewlines();
2167
+ this.skipBlockMemberSeparators();
2012
2168
  if (this.check("RBRACE")) break;
2013
2169
  if (this.check("AT")) {
2014
2170
  this.advance();
@@ -2049,7 +2205,7 @@ var _HoloCompositionParser = class _HoloCompositionParser {
2049
2205
  let autoplay;
2050
2206
  let loop;
2051
2207
  while (!this.check("RBRACE") && !this.isAtEnd()) {
2052
- this.skipNewlines();
2208
+ this.skipBlockMemberSeparators();
2053
2209
  if (this.check("RBRACE")) break;
2054
2210
  if (this.check("IDENTIFIER") && (this.current().value === "autoplay" || this.current().value === "loop")) {
2055
2211
  const key = this.advance().value;
@@ -2088,7 +2244,7 @@ var _HoloCompositionParser = class _HoloCompositionParser {
2088
2244
  this.skipNewlines();
2089
2245
  const properties = {};
2090
2246
  while (!this.check("RBRACE") && !this.isAtEnd()) {
2091
- this.skipNewlines();
2247
+ this.skipBlockMemberSeparators();
2092
2248
  if (this.check("RBRACE")) break;
2093
2249
  const key = this.expectIdentifier();
2094
2250
  this.expect("COLON");
@@ -2133,7 +2289,7 @@ var _HoloCompositionParser = class _HoloCompositionParser {
2133
2289
  this.skipNewlines();
2134
2290
  const properties = [];
2135
2291
  while (!this.check("RBRACE") && !this.isAtEnd()) {
2136
- this.skipNewlines();
2292
+ this.skipBlockMemberSeparators();
2137
2293
  if (this.check("RBRACE")) break;
2138
2294
  if (this.check("AT")) {
2139
2295
  this.advance();
@@ -2172,7 +2328,7 @@ var _HoloCompositionParser = class _HoloCompositionParser {
2172
2328
  const properties = [];
2173
2329
  const handlers = [];
2174
2330
  while (!this.check("RBRACE") && !this.isAtEnd()) {
2175
- this.skipNewlines();
2331
+ this.skipBlockMemberSeparators();
2176
2332
  if (this.check("RBRACE")) break;
2177
2333
  if (this.check("IDENTIFIER") && this.current().value.startsWith("on_")) {
2178
2334
  const event = this.advance().value;
@@ -2212,7 +2368,7 @@ var _HoloCompositionParser = class _HoloCompositionParser {
2212
2368
  this.skipNewlines();
2213
2369
  const elements = [];
2214
2370
  while (!this.check("RBRACE") && !this.isAtEnd()) {
2215
- this.skipNewlines();
2371
+ this.skipBlockMemberSeparators();
2216
2372
  if (this.check("RBRACE")) break;
2217
2373
  if (this.check("ELEMENT")) {
2218
2374
  elements.push(this.parseUIElement());
@@ -2237,7 +2393,7 @@ var _HoloCompositionParser = class _HoloCompositionParser {
2237
2393
  this.skipNewlines();
2238
2394
  const properties = [];
2239
2395
  while (!this.check("RBRACE") && !this.isAtEnd()) {
2240
- this.skipNewlines();
2396
+ this.skipBlockMemberSeparators();
2241
2397
  if (this.check("RBRACE")) break;
2242
2398
  const key = this.expectIdentifier();
2243
2399
  this.expect("COLON");
@@ -2264,7 +2420,7 @@ var _HoloCompositionParser = class _HoloCompositionParser {
2264
2420
  this.skipNewlines();
2265
2421
  const properties = [];
2266
2422
  while (!this.check("RBRACE") && !this.isAtEnd()) {
2267
- this.skipNewlines();
2423
+ this.skipBlockMemberSeparators();
2268
2424
  if (this.check("RBRACE")) break;
2269
2425
  const key = this.expectIdentifier();
2270
2426
  this.expect("COLON");
@@ -2398,7 +2554,7 @@ var _HoloCompositionParser = class _HoloCompositionParser {
2398
2554
  this.skipNewlines();
2399
2555
  const properties = [];
2400
2556
  while (!this.check("RBRACE") && !this.isAtEnd()) {
2401
- this.skipNewlines();
2557
+ this.skipBlockMemberSeparators();
2402
2558
  if (this.check("RBRACE")) break;
2403
2559
  const key = this.expectIdentifier();
2404
2560
  this.expect("COLON");
@@ -2433,11 +2589,11 @@ var _HoloCompositionParser = class _HoloCompositionParser {
2433
2589
  // Initialize directives
2434
2590
  };
2435
2591
  while (!this.check("RBRACE") && !this.isAtEnd()) {
2436
- this.skipNewlines();
2592
+ this.skipBlockMemberSeparators();
2437
2593
  if (this.check("RBRACE")) break;
2438
- if (this.check("STATE")) {
2594
+ if (this.check("STATE") && this.peek(1).type !== "COLON") {
2439
2595
  template.state = this.parseState();
2440
- } else if (this.check("ACTION") || this.check("ASYNC")) {
2596
+ } else if (this.check("ACTION") && this.peek(1).type !== "COLON" || this.check("ASYNC")) {
2441
2597
  const action = this.parseAction();
2442
2598
  template.actions.push(action);
2443
2599
  template.directives.push({
@@ -2502,7 +2658,7 @@ var _HoloCompositionParser = class _HoloCompositionParser {
2502
2658
  body: []
2503
2659
  });
2504
2660
  } else if (this.isPropertyName() && this.peek(1).type === "LPAREN") {
2505
- const methodName = this.expectIdentifier();
2661
+ const methodName = this.parsePropertyKey();
2506
2662
  this.skipParens();
2507
2663
  if (this.check("LBRACE")) {
2508
2664
  this.skipBlock();
@@ -2514,7 +2670,7 @@ var _HoloCompositionParser = class _HoloCompositionParser {
2514
2670
  });
2515
2671
  }
2516
2672
  } else if (this.isPropertyName() && (this.peek(1).type === "IDENTIFIER" || this.peek(1).type === "STRING")) {
2517
- const blockType = this.expectIdentifier();
2673
+ const blockType = this.parsePropertyKey();
2518
2674
  const blockName = this.check("STRING") ? this.advance().value : this.expectIdentifier();
2519
2675
  if (this.check("LPAREN")) {
2520
2676
  this.skipParens();
@@ -2529,7 +2685,7 @@ var _HoloCompositionParser = class _HoloCompositionParser {
2529
2685
  });
2530
2686
  }
2531
2687
  } else if (this.isPropertyName() && this.peek(1).type === "LBRACE") {
2532
- const blockType = this.expectIdentifier();
2688
+ const blockType = this.parsePropertyKey();
2533
2689
  if (this.check("LBRACE")) {
2534
2690
  this.skipBlock();
2535
2691
  template.directives.push({
@@ -2540,12 +2696,12 @@ var _HoloCompositionParser = class _HoloCompositionParser {
2540
2696
  });
2541
2697
  }
2542
2698
  } else {
2543
- const key = this.expectIdentifier();
2699
+ const key = this.parsePropertyKey();
2544
2700
  this.expect("COLON");
2545
2701
  const value = this.parseValue();
2546
2702
  template.properties.push({ type: "TemplateProperty", key, value });
2547
2703
  }
2548
- this.skipNewlines();
2704
+ this.skipBlockMemberSeparators();
2549
2705
  }
2550
2706
  this.expect("RBRACE");
2551
2707
  template.loc = { start: startLoc, end: this.currentLocation() };
@@ -2565,8 +2721,8 @@ var _HoloCompositionParser = class _HoloCompositionParser {
2565
2721
  let name = "";
2566
2722
  if (this.check("STRING")) {
2567
2723
  name = this.expectString();
2568
- } else if (this.check("IDENTIFIER")) {
2569
- name = this.expectIdentifier();
2724
+ } else if (this.isObjectNameToken()) {
2725
+ name = this.advance().value;
2570
2726
  } else if (typeOverride === "behavior" && this.check("LBRACE")) {
2571
2727
  name = "behavior";
2572
2728
  } else {
@@ -2600,14 +2756,14 @@ var _HoloCompositionParser = class _HoloCompositionParser {
2600
2756
  const directives = [];
2601
2757
  let state;
2602
2758
  while (!this.check("RBRACE") && !this.check("EOF")) {
2603
- this.skipNewlines();
2759
+ this.skipBlockMemberSeparators();
2604
2760
  if (this.check("RBRACE")) break;
2605
- if (this.check("OBJECT") || this.check("SPATIAL_AGENT") || this.check("TOOL_SLOT") || this.check("BEHAVIOR") || this.current().type.startsWith("UI_")) {
2761
+ if (this.check("OBJECT") || this.check("SPATIAL_AGENT") || this.check("TOOL_SLOT") || this.check("BEHAVIOR") && this.peek(1).type !== "COLON" || this.current().type.startsWith("UI_")) {
2606
2762
  const nestedType = this.check("OBJECT") ? void 0 : this.current().value.toLowerCase();
2607
2763
  children.push(this.parseObject(nestedType));
2608
2764
  } else if (this.check("SUB_ORB")) {
2609
2765
  subOrbs.push(this.parseSubOrb());
2610
- } else if (this.check("ACTION") || this.check("ASYNC")) {
2766
+ } else if (this.check("ACTION") && this.peek(1).type !== "COLON" || this.check("ASYNC")) {
2611
2767
  const action = this.parseAction();
2612
2768
  directives.push({
2613
2769
  type: "method",
@@ -2658,7 +2814,7 @@ var _HoloCompositionParser = class _HoloCompositionParser {
2658
2814
  config: config2,
2659
2815
  platformConstraint: constraint
2660
2816
  });
2661
- } else if (this.check("OBJECT") || this.check("SPATIAL_AGENT") || this.check("TOOL_SLOT") || this.check("BEHAVIOR") || this.current().type.startsWith("UI_")) {
2817
+ } else if (this.check("OBJECT") || this.check("SPATIAL_AGENT") || this.check("TOOL_SLOT") || this.check("BEHAVIOR") && this.peek(1).type !== "COLON" || this.current().type.startsWith("UI_")) {
2662
2818
  const nestedType = this.check("OBJECT") ? void 0 : this.current().value.toLowerCase();
2663
2819
  const child = this.parseObject(nestedType);
2664
2820
  child.platformConstraint = constraint;
@@ -2671,7 +2827,7 @@ var _HoloCompositionParser = class _HoloCompositionParser {
2671
2827
  const trait = { type: "ObjectTrait", name: traitName, config };
2672
2828
  traits.push(trait);
2673
2829
  directives.push({ type: "trait", name: traitName, config });
2674
- } else if (this.check("STATE")) {
2830
+ } else if (this.check("STATE") && this.peek(1).type !== "COLON") {
2675
2831
  state = this.parseState();
2676
2832
  } else if (this.isDomainBlockToken() && this.peek(1).type !== "COLON") {
2677
2833
  const domainBlock = this.parseDomainBlock();
@@ -2683,7 +2839,7 @@ var _HoloCompositionParser = class _HoloCompositionParser {
2683
2839
  const physicsValue = this.parseValue();
2684
2840
  properties.push({ type: "ObjectProperty", key, value: physicsValue });
2685
2841
  } else if (this.isPropertyName()) {
2686
- const key = this.advance().value;
2842
+ const key = this.parsePropertyKey();
2687
2843
  if (this.check("COLON")) {
2688
2844
  this.advance();
2689
2845
  if (this.check("LBRACE")) {
@@ -2717,7 +2873,11 @@ var _HoloCompositionParser = class _HoloCompositionParser {
2717
2873
  if (this.check("LPAREN")) this.skipParens();
2718
2874
  let parsedBody = "";
2719
2875
  if (this.check("LBRACE")) {
2720
- parsedBody = this.parseBlockTraitConfig();
2876
+ if (key === "on" || key.startsWith("on_") || /^on[A-Z]/.test(key)) {
2877
+ this.skipBlock();
2878
+ } else {
2879
+ parsedBody = this.parseBlockTraitConfig();
2880
+ }
2721
2881
  }
2722
2882
  directives.push({ type: key, name: blockName, parameters: [], body: parsedBody });
2723
2883
  } else if (this.check("LBRACE")) {
@@ -2865,6 +3025,7 @@ var _HoloCompositionParser = class _HoloCompositionParser {
2865
3025
  this.expect("LBRACE");
2866
3026
  this.skipNewlines();
2867
3027
  const objects = [];
3028
+ const lights = [];
2868
3029
  const groups = [];
2869
3030
  const body = [];
2870
3031
  while (!this.check("RBRACE") && !this.isAtEnd()) {
@@ -2872,6 +3033,8 @@ var _HoloCompositionParser = class _HoloCompositionParser {
2872
3033
  if (this.check("RBRACE")) break;
2873
3034
  if (this.check("OBJECT")) {
2874
3035
  objects.push(this.parseObject());
3036
+ } else if (this.check("LIGHT")) {
3037
+ lights.push(this.parseLight());
2875
3038
  } else if (this.check("SPATIAL_GROUP")) {
2876
3039
  groups.push(this.parseSpatialGroup());
2877
3040
  } else if (this.check("TEMPLATE")) {
@@ -2924,6 +3087,7 @@ var _HoloCompositionParser = class _HoloCompositionParser {
2924
3087
  name,
2925
3088
  properties,
2926
3089
  objects,
3090
+ lights: lights.length > 0 ? lights : void 0,
2927
3091
  groups: groups.length > 0 ? groups : void 0,
2928
3092
  body: body.length > 0 ? body : void 0
2929
3093
  };
@@ -2943,6 +3107,18 @@ var _HoloCompositionParser = class _HoloCompositionParser {
2943
3107
  if (this.check("RBRACE")) break;
2944
3108
  if (this.check("ACTION") || this.check("ASYNC")) {
2945
3109
  actions.push(this.parseAction());
3110
+ } else if (this.check("FUNCTION")) {
3111
+ this.skipFunctionDeclaration();
3112
+ } else if (this.check("IDENTIFIER") && this.current().value === "on" && (this.peek(1).type === "STRING" || this.peek(1).type === "IDENTIFIER")) {
3113
+ this.advance();
3114
+ const event = this.advance().value;
3115
+ const parameters = this.check("LPAREN") ? this.parseParameterList() : [];
3116
+ if (this.check("LBRACE")) {
3117
+ this.skipBlock();
3118
+ handlers.push({ type: "EventHandler", event, parameters, body: [] });
3119
+ } else {
3120
+ handlers.push({ type: "EventHandler", event, parameters, body: [] });
3121
+ }
2946
3122
  } else if (this.check("IDENTIFIER")) {
2947
3123
  const name = this.advance().value;
2948
3124
  if (this.check("IDENTIFIER")) {
@@ -3323,6 +3499,12 @@ var _HoloCompositionParser = class _HoloCompositionParser {
3323
3499
  isKeywordAsIdentifier() {
3324
3500
  return isKeywordAsIdentifier(this._exprApi);
3325
3501
  }
3502
+ isObjectNameToken() {
3503
+ const type = this.current().type;
3504
+ if (type === "IDENTIFIER") return true;
3505
+ if (type === "OBJECT") return false;
3506
+ return this.isKeywordAsIdentifierType(type);
3507
+ }
3326
3508
  // ===========================================================================
3327
3509
  // VALUES
3328
3510
  // ===========================================================================
@@ -3350,14 +3532,22 @@ var _HoloCompositionParser = class _HoloCompositionParser {
3350
3532
  return this.parseBindValue();
3351
3533
  }
3352
3534
  if (this.match("AT")) {
3353
- if (this.check("IDENTIFIER")) {
3354
- return `@${this.advance().value}`;
3355
- }
3535
+ const traitName = this.parseTraitName();
3536
+ if (traitName) return `@${traitName}`;
3356
3537
  this.error(`Expected trait name after '@', got ${this.current().type}`);
3357
3538
  return null;
3358
3539
  }
3359
- if (this.match("IDENTIFIER")) {
3360
- return this.previous().value;
3540
+ if (this.match("HASH")) {
3541
+ return this.parseHashLiteral();
3542
+ }
3543
+ if (this.check("ENUM")) {
3544
+ return this.parseEnumTypeSpec();
3545
+ }
3546
+ if (this.check("FUNCTION")) {
3547
+ return this.parseFunctionValue();
3548
+ }
3549
+ if (this.isBarewordPathToken()) {
3550
+ return this.parseBarewordPathValue();
3361
3551
  }
3362
3552
  if (this.match("LBRACKET")) {
3363
3553
  return this.parseArrayValue();
@@ -3365,13 +3555,148 @@ var _HoloCompositionParser = class _HoloCompositionParser {
3365
3555
  if (this.match("LBRACE")) {
3366
3556
  return this.parseObjectValue();
3367
3557
  }
3368
- if (_HoloCompositionParser.DOMAIN_TOKENS.has(this.current().type) || this.isKeywordAsIdentifierType(this.current().type)) {
3369
- return this.advance().value;
3370
- }
3371
3558
  this.error(`Expected value, got ${this.current().type}`);
3372
3559
  this.advance();
3373
3560
  return null;
3374
3561
  }
3562
+ /**
3563
+ * Parse an `enum(...)` type-spec expression, e.g.:
3564
+ * enum("button" | "slider" | "checkbox")
3565
+ *
3566
+ * Returns the canonical string representation so trait loaders and schema
3567
+ * emitters can read it as a type annotation. Called from parseValue() when
3568
+ * the current token is ENUM (the keyword `enum` tokenized as 'ENUM' rather
3569
+ * than 'IDENTIFIER').
3570
+ *
3571
+ * The opening `enum` token is consumed here. The caller should check for a
3572
+ * trailing `= defaultValue` if the context supports it (e.g. parseObjectValue).
3573
+ */
3574
+ parseEnumTypeSpec() {
3575
+ this.advance();
3576
+ let spec = "enum";
3577
+ if (this.check("LPAREN")) {
3578
+ spec += this.parseParenthesizedLiteral();
3579
+ }
3580
+ return spec;
3581
+ }
3582
+ parseFunctionValue() {
3583
+ this.expect("FUNCTION");
3584
+ let name = "";
3585
+ if (this.check("STRING") || this.check("IDENTIFIER")) {
3586
+ name = this.advance().value;
3587
+ }
3588
+ const params = this.check("LPAREN") ? this.collectFunctionParameterNames() : [];
3589
+ if (this.check("LBRACE")) {
3590
+ this.skipBlock();
3591
+ }
3592
+ return {
3593
+ type: "FunctionValue",
3594
+ name,
3595
+ params
3596
+ };
3597
+ }
3598
+ skipFunctionDeclaration() {
3599
+ this.expect("FUNCTION");
3600
+ if (this.check("STRING") || this.check("IDENTIFIER")) {
3601
+ this.advance();
3602
+ }
3603
+ if (this.check("LPAREN")) {
3604
+ this.skipParens();
3605
+ }
3606
+ if (this.check("LBRACE")) {
3607
+ this.skipBlock();
3608
+ }
3609
+ }
3610
+ collectFunctionParameterNames() {
3611
+ const params = [];
3612
+ if (!this.check("LPAREN")) return params;
3613
+ this.advance();
3614
+ let parenDepth = 1;
3615
+ while (parenDepth > 0 && !this.isAtEnd()) {
3616
+ if (this.check("LPAREN")) {
3617
+ parenDepth++;
3618
+ this.advance();
3619
+ continue;
3620
+ }
3621
+ if (this.check("RPAREN")) {
3622
+ parenDepth--;
3623
+ this.advance();
3624
+ continue;
3625
+ }
3626
+ if (parenDepth === 1 && this.check("IDENTIFIER")) {
3627
+ params.push(this.advance().value);
3628
+ continue;
3629
+ }
3630
+ this.advance();
3631
+ }
3632
+ return params;
3633
+ }
3634
+ isBarewordPathToken(token = this.current()) {
3635
+ const type = token.type;
3636
+ return type === "IDENTIFIER" || type === "STATE" || _HoloCompositionParser.DOMAIN_TOKENS.has(type) || this.isKeywordAsIdentifierType(type);
3637
+ }
3638
+ parseBarewordPathValue() {
3639
+ let value = this.advance().value;
3640
+ while (this.match("DOT")) {
3641
+ if (!this.isBarewordPathToken()) {
3642
+ this.error(`Expected identifier after '.', got ${this.current().type}`);
3643
+ break;
3644
+ }
3645
+ value += `.${this.advance().value}`;
3646
+ }
3647
+ while (this.check("COLON") && this.isBarewordPathToken(this.peek(1))) {
3648
+ this.advance();
3649
+ value += `:${this.advance().value}`;
3650
+ }
3651
+ if (this.match("LESS")) {
3652
+ value += "<";
3653
+ let depth = 1;
3654
+ while (depth > 0 && !this.isAtEnd()) {
3655
+ if (this.check("LESS")) {
3656
+ depth++;
3657
+ value += this.advance().value;
3658
+ continue;
3659
+ }
3660
+ if (this.check("GREATER")) {
3661
+ depth--;
3662
+ this.advance();
3663
+ value += ">";
3664
+ if (depth === 0) break;
3665
+ continue;
3666
+ }
3667
+ value += this.advance().value;
3668
+ }
3669
+ }
3670
+ if (this.check("LPAREN")) {
3671
+ value += this.parseParenthesizedLiteral();
3672
+ }
3673
+ return value;
3674
+ }
3675
+ parseHashLiteral() {
3676
+ let value = "#";
3677
+ while (!this.isAtEnd()) {
3678
+ if (this.check("IDENTIFIER") || this.check("NUMBER") || this.check("MINUS") || this.check("DOT")) {
3679
+ value += this.advance().value;
3680
+ continue;
3681
+ }
3682
+ break;
3683
+ }
3684
+ return value;
3685
+ }
3686
+ parseParenthesizedLiteral() {
3687
+ let value = "";
3688
+ if (!this.check("LPAREN")) return value;
3689
+ let depth = 0;
3690
+ while (!this.isAtEnd()) {
3691
+ const token = this.current();
3692
+ if (token.type === "LPAREN") depth++;
3693
+ if (token.type === "RPAREN") depth--;
3694
+ value += token.type === "STRING" ? `"${token.value}"` : token.value;
3695
+ this.advance();
3696
+ if (depth === 0) break;
3697
+ }
3698
+ return value;
3699
+ }
3375
3700
  parseBindValue() {
3376
3701
  this.expect("BIND");
3377
3702
  this.expect("LPAREN");
@@ -3397,9 +3722,10 @@ var _HoloCompositionParser = class _HoloCompositionParser {
3397
3722
  const elements = [];
3398
3723
  while (!this.check("RBRACKET") && !this.isAtEnd()) {
3399
3724
  this.skipNewlines();
3725
+ if (this.check("RBRACKET")) break;
3400
3726
  elements.push(this.parseValue());
3401
3727
  this.skipNewlines();
3402
- if (!this.match("COMMA")) break;
3728
+ this.match("COMMA");
3403
3729
  this.skipNewlines();
3404
3730
  }
3405
3731
  this.skipNewlines();
@@ -3410,13 +3736,15 @@ var _HoloCompositionParser = class _HoloCompositionParser {
3410
3736
  this.skipNewlines();
3411
3737
  const obj = {};
3412
3738
  while (!this.check("RBRACE") && !this.isAtEnd()) {
3413
- this.skipNewlines();
3739
+ this.skipBlockMemberSeparators();
3414
3740
  if (this.check("RBRACE")) break;
3415
- this.match("COMMA");
3416
- if (this.isPropertyName() && this.peek(1).type === "COLON") {
3417
- const key = this.expectIdentifier();
3741
+ if (this.isPropertyAssignmentStart()) {
3742
+ const key = this.parsePropertyKey();
3418
3743
  this.expect("COLON");
3419
3744
  obj[key] = this.parseValue();
3745
+ if (this.match("EQUALS")) {
3746
+ this.parseValue();
3747
+ }
3420
3748
  } else if (this.check("RBRACE")) {
3421
3749
  break;
3422
3750
  } else {
@@ -3499,7 +3827,7 @@ var _HoloCompositionParser = class _HoloCompositionParser {
3499
3827
  this.skipNewlines();
3500
3828
  const properties = [];
3501
3829
  while (!this.check("RBRACE") && !this.isAtEnd()) {
3502
- this.skipNewlines();
3830
+ this.skipBlockMemberSeparators();
3503
3831
  if (this.check("RBRACE")) break;
3504
3832
  const key = this.expectIdentifier();
3505
3833
  this.expect("COLON");
@@ -3540,6 +3868,7 @@ var _HoloCompositionParser = class _HoloCompositionParser {
3540
3868
  "QUEST",
3541
3869
  "ABILITY",
3542
3870
  "DIALOGUE",
3871
+ "BEHAVIOR",
3543
3872
  "SHAPE",
3544
3873
  "IMPORT",
3545
3874
  "USING",
@@ -3558,10 +3887,42 @@ var _HoloCompositionParser = class _HoloCompositionParser {
3558
3887
  "WAYPOINTS",
3559
3888
  "CONSTRAINT",
3560
3889
  "TERRAIN",
3561
- "PARTICLES"
3890
+ "PARTICLES",
3891
+ "METADATA_BLOCK",
3892
+ "HOLO_TOPIC",
3893
+ "HOLO_CHANNEL",
3894
+ "CONNECT",
3895
+ "BIND"
3562
3896
  ];
3563
3897
  return validPropertyKeywords.includes(type);
3564
3898
  }
3899
+ isPropertyNameToken(token) {
3900
+ return token.type === "IDENTIFIER" || _HoloCompositionParser.DOMAIN_TOKENS.has(token.type) || this.isKeywordAsIdentifierType(token.type);
3901
+ }
3902
+ isPropertyAssignmentStart() {
3903
+ if (!this.isPropertyName()) return false;
3904
+ let index = this.pos + 1;
3905
+ if (this.tokens[index]?.type === "QUESTION") index++;
3906
+ while (this.tokens[index]?.type === "DOT" && this.isPropertyNameToken(this.tokens[index + 1])) {
3907
+ index += 2;
3908
+ if (this.tokens[index]?.type === "QUESTION") index++;
3909
+ }
3910
+ return this.tokens[index]?.type === "COLON";
3911
+ }
3912
+ parsePropertyKey() {
3913
+ const parts = [];
3914
+ parts.push(this.isPropertyName() ? this.advance().value : this.expectIdentifier());
3915
+ while (this.match("DOT")) {
3916
+ if (!this.isPropertyName()) {
3917
+ this.error(`Expected identifier after '.', got ${this.current().type}`);
3918
+ break;
3919
+ }
3920
+ parts.push(this.advance().value);
3921
+ }
3922
+ let key = parts.join(".");
3923
+ if (this.match("QUESTION")) key += "?";
3924
+ return key;
3925
+ }
3565
3926
  /**
3566
3927
  * Parse primitive#id or primitive #id { } syntax
3567
3928
  * Examples:
@@ -3599,15 +3960,15 @@ var _HoloCompositionParser = class _HoloCompositionParser {
3599
3960
  this.expect("LBRACE");
3600
3961
  this.skipNewlines();
3601
3962
  while (!this.check("RBRACE") && !this.isAtEnd()) {
3602
- this.skipNewlines();
3963
+ this.skipBlockMemberSeparators();
3603
3964
  if (this.check("RBRACE")) break;
3604
3965
  if (this.check("AT")) {
3605
3966
  this.advance();
3606
3967
  const name = this.parseTraitName();
3607
3968
  const config = this.parseOptionalTraitConfig();
3608
3969
  traits.push({ type: "ObjectTrait", name, config });
3609
- } else if (this.check("IDENTIFIER")) {
3610
- const key = this.expectIdentifier();
3970
+ } else if (this.isPropertyName()) {
3971
+ const key = this.parsePropertyKey();
3611
3972
  if (this.check("COLON")) {
3612
3973
  this.advance();
3613
3974
  properties.push({ type: "ObjectProperty", key, value: this.parseValue() });
@@ -3743,6 +4104,15 @@ var _HoloCompositionParser = class _HoloCompositionParser {
3743
4104
  while (this.match("NEWLINE")) {
3744
4105
  }
3745
4106
  }
4107
+ skipBlockMemberSeparators() {
4108
+ this.skipNewlines();
4109
+ while (this.matchBlockMemberSeparator()) {
4110
+ this.skipNewlines();
4111
+ }
4112
+ }
4113
+ matchBlockMemberSeparator() {
4114
+ return this.match("COMMA") || this.match("SEMICOLON");
4115
+ }
3746
4116
  currentLocation() {
3747
4117
  const token = this.current();
3748
4118
  return { line: token.line, column: token.column };
@@ -3830,16 +4200,14 @@ var _HoloCompositionParser = class _HoloCompositionParser {
3830
4200
  while (!this.check("RPAREN") && !this.check("EOF")) {
3831
4201
  this.skipNewlines();
3832
4202
  if (this.check("RPAREN")) break;
3833
- if (!this.isPropertyName() || this.peek(1).type !== "COLON") {
4203
+ if (!this.isPropertyAssignmentStart()) {
3834
4204
  config[`_arg${argIndex++}`] = this.parseValue();
3835
4205
  } else {
3836
- const key = this.expectIdentifier();
4206
+ const key = this.parsePropertyKey();
3837
4207
  this.expect("COLON");
3838
4208
  config[key] = this.parseValue();
3839
4209
  }
3840
- if (this.check("COMMA")) {
3841
- this.advance();
3842
- }
4210
+ this.matchBlockMemberSeparator();
3843
4211
  this.skipNewlines();
3844
4212
  }
3845
4213
  this.expect("RPAREN");
@@ -3850,19 +4218,128 @@ var _HoloCompositionParser = class _HoloCompositionParser {
3850
4218
  this.skipNewlines();
3851
4219
  const config = {};
3852
4220
  while (!this.check("RBRACE") && !this.isAtEnd()) {
3853
- this.skipNewlines();
4221
+ this.skipBlockMemberSeparators();
3854
4222
  if (this.check("RBRACE")) break;
3855
- const key = this.expectIdentifier();
3856
- this.expect("COLON");
3857
- config[key] = this.parseValue();
3858
- if (this.check("COMMA")) {
4223
+ if (this.isNamedOrTraitedPropertyBlockStart()) {
4224
+ const { key, value } = this.parseNamedOrTraitedPropertyBlock();
4225
+ config[key] = value;
4226
+ } else if (this.check("AT")) {
3859
4227
  this.advance();
4228
+ const traitName = this.parseTraitName();
4229
+ if (traitName) {
4230
+ config[`@${traitName}`] = this.parseOptionalTraitConfig();
4231
+ }
4232
+ } else if (this.isPropertyName() && this.peek(1).type === "LBRACE") {
4233
+ const nestedKey = this.parsePropertyKey();
4234
+ config[nestedKey] = this.parseBlockTraitConfig();
4235
+ } else {
4236
+ const key = this.parsePropertyKey();
4237
+ this.expect("COLON");
4238
+ config[key] = this.parseInlineExpressionTail(this.parseValue());
3860
4239
  }
4240
+ this.matchBlockMemberSeparator();
3861
4241
  this.skipNewlines();
3862
4242
  }
3863
4243
  this.expect("RBRACE");
3864
4244
  return config;
3865
4245
  }
4246
+ parseInlineExpressionTail(value) {
4247
+ if (value === null || typeof value === "object" && !Array.isArray(value) || !this.isInlineExpressionTailStart()) {
4248
+ return value;
4249
+ }
4250
+ let text = String(value);
4251
+ while (!this.check(["NEWLINE", "COMMA", "SEMICOLON", "RBRACE", "RPAREN", "RBRACKET", "EOF"])) {
4252
+ const token = this.current();
4253
+ const raw = token.type === "STRING" ? `"${token.value}"` : token.value;
4254
+ text += ` ${raw}`;
4255
+ this.advance();
4256
+ }
4257
+ return text;
4258
+ }
4259
+ isInlineExpressionTailStart() {
4260
+ return this.check([
4261
+ "EQUALS_EQUALS",
4262
+ "BANG_EQUALS",
4263
+ "LESS",
4264
+ "LESS_EQUALS",
4265
+ "GREATER",
4266
+ "GREATER_EQUALS",
4267
+ "AND",
4268
+ "OR",
4269
+ "PLUS",
4270
+ "MINUS",
4271
+ "STAR",
4272
+ "SLASH"
4273
+ ]);
4274
+ }
4275
+ isNamedOrTraitedPropertyBlockStart() {
4276
+ if (!this.isPropertyName()) return false;
4277
+ let index = this.pos + 1;
4278
+ const hasName = this.tokens[index]?.type === "STRING" || this.tokens[index]?.type === "IDENTIFIER";
4279
+ if (hasName) {
4280
+ index++;
4281
+ }
4282
+ while (this.tokens[index]?.type === "NEWLINE") index++;
4283
+ let hasTrait = false;
4284
+ while (this.tokens[index]?.type === "AT") {
4285
+ hasTrait = true;
4286
+ index++;
4287
+ if (this.tokens[index]?.type === "EOF") return false;
4288
+ index++;
4289
+ if (this.tokens[index]?.type === "LPAREN") {
4290
+ index = this.indexAfterBalancedTokens(index, "LPAREN", "RPAREN");
4291
+ }
4292
+ while (this.tokens[index]?.type === "NEWLINE") index++;
4293
+ }
4294
+ return (hasName || hasTrait) && this.tokens[index]?.type === "LBRACE";
4295
+ }
4296
+ indexAfterBalancedTokens(startIndex, openType, closeType) {
4297
+ let depth = 0;
4298
+ let index = startIndex;
4299
+ while (index < this.tokens.length) {
4300
+ if (this.tokens[index].type === openType) depth++;
4301
+ if (this.tokens[index].type === closeType) {
4302
+ depth--;
4303
+ index++;
4304
+ if (depth === 0) return index;
4305
+ continue;
4306
+ }
4307
+ index++;
4308
+ }
4309
+ return index;
4310
+ }
4311
+ parseNamedOrTraitedPropertyBlock() {
4312
+ const key = this.parsePropertyKey();
4313
+ const name = this.check("STRING") || this.check("IDENTIFIER") ? this.advance().value : void 0;
4314
+ const traits = this.parseInlineTraitNamesBeforeBlock();
4315
+ const body = this.check("LBRACE") ? this.parseBlockTraitConfig() : {};
4316
+ return {
4317
+ key,
4318
+ value: {
4319
+ ...name !== void 0 ? { name } : {},
4320
+ ...traits.length > 0 ? { traits } : {},
4321
+ ...body
4322
+ }
4323
+ };
4324
+ }
4325
+ parseInlineTraitNamesBeforeBlock() {
4326
+ const traits = [];
4327
+ while (this.check("AT")) {
4328
+ this.advance();
4329
+ const traitName = this.parseTraitName();
4330
+ if (traitName) traits.push(traitName);
4331
+ if (this.check("LPAREN")) {
4332
+ this.skipParens();
4333
+ }
4334
+ this.skipNewlines();
4335
+ }
4336
+ return traits;
4337
+ }
4338
+ parseSharePlayBlock() {
4339
+ this.advance();
4340
+ if (!this.check("LBRACE")) return {};
4341
+ return this.parseBlockTraitConfig();
4342
+ }
3866
4343
  // ===========================================================================
3867
4344
  // PLATFORM CONSTRAINT PARSING
3868
4345
  // ===========================================================================
@@ -3978,7 +4455,9 @@ var _HoloCompositionParser = class _HoloCompositionParser {
3978
4455
  type: "NPC",
3979
4456
  name,
3980
4457
  properties: [],
3981
- behaviors: []
4458
+ behaviors: [],
4459
+ traits: [],
4460
+ directives: []
3982
4461
  };
3983
4462
  while (!this.check("RBRACE") && !this.isAtEnd()) {
3984
4463
  this.skipNewlines();
@@ -3987,29 +4466,86 @@ var _HoloCompositionParser = class _HoloCompositionParser {
3987
4466
  npc.behaviors.push(this.parseBehavior());
3988
4467
  } else if (this.check("STATE")) {
3989
4468
  npc.state = this.parseState();
3990
- } else {
3991
- const key = this.expectIdentifier();
3992
- this.expect("COLON");
3993
- const value = this.parseValue();
3994
- if (key === "type") npc.npcType = value;
3995
- else if (key === "model") npc.model = value;
3996
- else if (key === "dialogue_tree") npc.dialogueTree = value;
3997
- else npc.properties.push({ type: "NPCProperty", key, value });
3998
- }
3999
- this.skipNewlines();
4000
- }
4001
- this.expect("RBRACE");
4002
- this.popContext();
4003
- return npc;
4004
- }
4005
- parseBehavior() {
4006
- this.expect("BEHAVIOR");
4007
- const name = this.expectString();
4008
- this.expect("LBRACE");
4009
- this.skipNewlines();
4010
- const behavior = {
4011
- type: "Behavior",
4012
- name,
4469
+ } else if (this.check("ACTION") || this.check("ASYNC")) {
4470
+ const action = this.parseAction();
4471
+ (npc.directives ?? (npc.directives = [])).push({
4472
+ type: "method",
4473
+ name: action.name,
4474
+ parameters: action.parameters || [],
4475
+ body: action.body,
4476
+ async: action.async
4477
+ });
4478
+ } else if (this.check("IDENTIFIER") && this.current().value === "on" && this.peek(1).type === "IDENTIFIER") {
4479
+ const eventName = this.peek(1).value;
4480
+ this.advance();
4481
+ this.advance();
4482
+ while (this.check("DOT")) {
4483
+ this.advance();
4484
+ if (this.check("IDENTIFIER")) this.advance();
4485
+ }
4486
+ let parameters = [];
4487
+ if (this.check("LPAREN")) {
4488
+ parameters = this.parseParameterList();
4489
+ }
4490
+ this.skipBlock();
4491
+ (npc.directives ?? (npc.directives = [])).push({
4492
+ type: "lifecycle",
4493
+ hook: eventName,
4494
+ parameters,
4495
+ body: []
4496
+ });
4497
+ } else if (this.check("AT")) {
4498
+ this.advance();
4499
+ const traitName = this.parseTraitName();
4500
+ const config = this.parseOptionalTraitConfig(true);
4501
+ (npc.traits ?? (npc.traits = [])).push({ type: "ObjectTrait", name: traitName, config });
4502
+ } else {
4503
+ const key = this.expectIdentifier();
4504
+ this.expect("COLON");
4505
+ const value = this.parseValue();
4506
+ if (key === "type") npc.npcType = value;
4507
+ else if (key === "model") npc.model = value;
4508
+ else if (key === "dialogue_tree") npc.dialogueTree = value;
4509
+ else if (key === "position") {
4510
+ if (Array.isArray(value) && value.length >= 3) {
4511
+ npc.position = { x: value[0], y: value[1], z: value[2] };
4512
+ } else if (value && typeof value === "object" && "x" in value) {
4513
+ const v = value;
4514
+ npc.position = { x: v.x, y: v.y, z: v.z };
4515
+ }
4516
+ } else if (key === "brain_ref") {
4517
+ npc.brain = {
4518
+ ...npc.brain ?? { type: "AgentBrainAttachment", brainType: "llm" },
4519
+ type: "AgentBrainAttachment",
4520
+ brainType: npc.brain?.brainType ?? "llm",
4521
+ brainRef: value
4522
+ };
4523
+ } else if (key === "brain") {
4524
+ const cfg = value && typeof value === "object" ? value : {};
4525
+ npc.brain = {
4526
+ type: "AgentBrainAttachment",
4527
+ brainType: cfg.type ?? "llm",
4528
+ autonomy: cfg.autonomy,
4529
+ brainRef: typeof cfg.ref === "string" ? cfg.ref : typeof cfg.brainRef === "string" ? cfg.brainRef : void 0,
4530
+ toolPermissions: Array.isArray(cfg.tools) ? cfg.tools.map(String) : void 0,
4531
+ model: cfg.model && typeof cfg.model === "object" ? cfg.model : void 0
4532
+ };
4533
+ } else npc.properties.push({ type: "NPCProperty", key, value });
4534
+ }
4535
+ this.skipNewlines();
4536
+ }
4537
+ this.expect("RBRACE");
4538
+ this.popContext();
4539
+ return npc;
4540
+ }
4541
+ parseBehavior() {
4542
+ this.expect("BEHAVIOR");
4543
+ const name = this.expectString();
4544
+ this.expect("LBRACE");
4545
+ this.skipNewlines();
4546
+ const behavior = {
4547
+ type: "Behavior",
4548
+ name,
4013
4549
  trigger: "idle",
4014
4550
  actions: []
4015
4551
  };
@@ -4351,7 +4887,7 @@ var _HoloCompositionParser = class _HoloCompositionParser {
4351
4887
  options: []
4352
4888
  };
4353
4889
  while (!this.check("RBRACE") && !this.isAtEnd()) {
4354
- this.skipNewlines();
4890
+ this.skipBlockMemberSeparators();
4355
4891
  if (this.check("RBRACE")) break;
4356
4892
  const key = this.expectIdentifier();
4357
4893
  this.expect("COLON");
@@ -4381,7 +4917,7 @@ var _HoloCompositionParser = class _HoloCompositionParser {
4381
4917
  text: ""
4382
4918
  };
4383
4919
  while (!this.check("RBRACE") && !this.isAtEnd()) {
4384
- this.skipNewlines();
4920
+ this.skipBlockMemberSeparators();
4385
4921
  if (this.check("RBRACE")) break;
4386
4922
  const key = this.expectIdentifier();
4387
4923
  this.expect("COLON");
@@ -4404,9 +4940,12 @@ var _HoloCompositionParser = class _HoloCompositionParser {
4404
4940
  // BRITTNEY AI FEATURES - STATE MACHINES
4405
4941
  // ===========================================================================
4406
4942
  parseStateMachine() {
4407
- this.currentLocation();
4943
+ const startLoc = this.currentLocation();
4408
4944
  this.expect("STATE_MACHINE");
4409
- const name = this.expectString();
4945
+ const name = this.parseOptionalStateMachineName("");
4946
+ if (!name) {
4947
+ this.error("Expected state_machine name");
4948
+ }
4410
4949
  this.pushContext(`StateMachine "${name}"`);
4411
4950
  this.expect("LBRACE");
4412
4951
  this.skipNewlines();
@@ -4414,11 +4953,19 @@ var _HoloCompositionParser = class _HoloCompositionParser {
4414
4953
  type: "StateMachine",
4415
4954
  name,
4416
4955
  initialState: "",
4417
- states: {}
4956
+ inputs: [],
4957
+ listeners: [],
4958
+ states: {},
4959
+ transitions: []
4418
4960
  };
4419
4961
  while (!this.check("RBRACE") && !this.isAtEnd()) {
4420
4962
  this.skipNewlines();
4421
4963
  if (this.check("RBRACE")) break;
4964
+ if (this.isAnimationTransitionShorthandStart()) {
4965
+ sm.transitions.push(this.parseAnimationTransitionShorthand());
4966
+ this.skipNewlines();
4967
+ continue;
4968
+ }
4422
4969
  if (this.check("STATE")) {
4423
4970
  this.advance();
4424
4971
  const stateName = this.check("STRING") || this.check("IDENTIFIER") ? this.advance().value : "anonymous";
@@ -4435,6 +4982,12 @@ var _HoloCompositionParser = class _HoloCompositionParser {
4435
4982
  while (!this.check("RBRACE") && !this.isAtEnd()) {
4436
4983
  this.skipNewlines();
4437
4984
  if (this.check("RBRACE")) break;
4985
+ if (this.current().type !== "IDENTIFIER" && !this.isKeywordAsIdentifierType(this.current().type)) {
4986
+ if (this.check("LPAREN")) this.skipParens();
4987
+ else if (this.check("LBRACE")) this.skipBlock();
4988
+ else this.advance();
4989
+ continue;
4990
+ }
4438
4991
  const key2 = this.expectIdentifier();
4439
4992
  if (this.check("COLON")) {
4440
4993
  this.advance();
@@ -4450,7 +5003,7 @@ var _HoloCompositionParser = class _HoloCompositionParser {
4450
5003
  this.expect("RBRACE");
4451
5004
  } else if (key2 === "actions") {
4452
5005
  state.actions = this.parseBehaviorActions();
4453
- } else if (key2 === "transitions") {
5006
+ } else if (this.parseAnimationStateMetadata(state, key2)) ; else if (key2 === "transitions") {
4454
5007
  state.transitions = this.parseStateTransitions();
4455
5008
  } else if (key2 === "onDamage") {
4456
5009
  state.onDamage = this.parseStatementBlock();
@@ -4459,7 +5012,11 @@ var _HoloCompositionParser = class _HoloCompositionParser {
4459
5012
  } else if (key2 === "onTimeout") {
4460
5013
  state.onTimeout = this.parseStatementBlock();
4461
5014
  } else {
4462
- this.parseValue();
5015
+ if (!this.check("RBRACE") && !this.isAtEnd()) {
5016
+ this.parseValue();
5017
+ if (this.check("LPAREN")) this.skipParens();
5018
+ if (this.check("LBRACE")) this.skipBlock();
5019
+ }
4463
5020
  }
4464
5021
  } else if (this.check("LBRACE")) {
4465
5022
  if (key2 === "enter" || key2 === "entry") {
@@ -4475,6 +5032,9 @@ var _HoloCompositionParser = class _HoloCompositionParser {
4475
5032
  } else {
4476
5033
  this.skipBlock();
4477
5034
  }
5035
+ } else if (this.check("LPAREN")) {
5036
+ this.skipParens();
5037
+ if (this.check("LBRACE")) this.skipBlock();
4478
5038
  }
4479
5039
  this.skipNewlines();
4480
5040
  }
@@ -4484,18 +5044,37 @@ var _HoloCompositionParser = class _HoloCompositionParser {
4484
5044
  this.skipNewlines();
4485
5045
  continue;
4486
5046
  }
5047
+ if (this.current().type !== "IDENTIFIER" && !this.isKeywordAsIdentifierType(this.current().type)) {
5048
+ if (this.check("LPAREN")) this.skipParens();
5049
+ else if (this.check("LBRACE")) this.skipBlock();
5050
+ else this.advance();
5051
+ this.skipNewlines();
5052
+ continue;
5053
+ }
4487
5054
  const key = this.expectIdentifier();
4488
5055
  if (key === "initial" || key === "initialState") {
4489
5056
  this.expect("COLON");
4490
5057
  sm.initialState = this.parseValue();
5058
+ } else if (key === "input") {
5059
+ sm.inputs.push(this.parseAnimationInputDeclaration(startLoc));
5060
+ } else if (key === "listen") {
5061
+ sm.listeners.push(this.parseAnimationListenerDeclaration(startLoc));
4491
5062
  } else if (key === "states" && this.check("COLON")) {
4492
5063
  this.advance();
4493
5064
  sm.states = this.parseStateMachineStates();
5065
+ } else if (key === "transitions" && this.check("COLON")) {
5066
+ this.advance();
5067
+ sm.transitions = this.parseStateTransitions();
4494
5068
  } else if (this.check("COLON")) {
4495
5069
  this.advance();
4496
5070
  this.parseValue();
5071
+ if (this.check("LPAREN")) this.skipParens();
5072
+ if (this.check("LBRACE")) this.skipBlock();
4497
5073
  } else if (this.check("LBRACE")) {
4498
5074
  this.skipBlock();
5075
+ } else if (this.check("LPAREN")) {
5076
+ this.skipParens();
5077
+ if (this.check("LBRACE")) this.skipBlock();
4499
5078
  }
4500
5079
  this.skipNewlines();
4501
5080
  }
@@ -4516,19 +5095,27 @@ var _HoloCompositionParser = class _HoloCompositionParser {
4516
5095
  * Without this, @state_machine blocks were stored as opaque traits and
4517
5096
  * invisible to compile_to_a2a_agent_card and other compilers.
4518
5097
  */
4519
- parseStateMachineFromDecorator() {
5098
+ parseStateMachineFromDecorator(name = "implicit") {
4520
5099
  const startLoc = this.currentLocation();
4521
5100
  this.expect("LBRACE");
4522
5101
  this.skipNewlines();
4523
5102
  const sm = {
4524
5103
  type: "StateMachine",
4525
- name: "implicit",
5104
+ name,
4526
5105
  initialState: "",
4527
- states: {}
5106
+ inputs: [],
5107
+ listeners: [],
5108
+ states: {},
5109
+ transitions: []
4528
5110
  };
4529
5111
  while (!this.check("RBRACE") && !this.isAtEnd()) {
4530
5112
  this.skipNewlines();
4531
5113
  if (this.check("RBRACE")) break;
5114
+ if (this.isAnimationTransitionShorthandStart()) {
5115
+ sm.transitions.push(this.parseAnimationTransitionShorthand());
5116
+ this.skipNewlines();
5117
+ continue;
5118
+ }
4532
5119
  if (this.check("STATE")) {
4533
5120
  this.advance();
4534
5121
  const stateName = this.check("STRING") || this.check("IDENTIFIER") ? this.advance().value : "anonymous";
@@ -4545,6 +5132,12 @@ var _HoloCompositionParser = class _HoloCompositionParser {
4545
5132
  while (!this.check("RBRACE") && !this.isAtEnd()) {
4546
5133
  this.skipNewlines();
4547
5134
  if (this.check("RBRACE")) break;
5135
+ if (this.current().type !== "IDENTIFIER" && !this.isKeywordAsIdentifierType(this.current().type)) {
5136
+ if (this.check("LPAREN")) this.skipParens();
5137
+ else if (this.check("LBRACE")) this.skipBlock();
5138
+ else this.advance();
5139
+ continue;
5140
+ }
4548
5141
  const key2 = this.expectIdentifier();
4549
5142
  if (this.check("COLON")) {
4550
5143
  this.advance();
@@ -4560,12 +5153,16 @@ var _HoloCompositionParser = class _HoloCompositionParser {
4560
5153
  this.expect("RBRACE");
4561
5154
  } else if (key2 === "actions") {
4562
5155
  state.actions = this.parseBehaviorActions();
4563
- } else if (key2 === "transitions") {
5156
+ } else if (this.parseAnimationStateMetadata(state, key2)) ; else if (key2 === "transitions") {
4564
5157
  state.transitions = this.parseStateTransitions();
4565
5158
  } else if (key2 === "timeout") {
4566
5159
  state.timeout = this.parseValue();
4567
5160
  } else {
4568
- this.parseValue();
5161
+ if (!this.check("RBRACE") && !this.isAtEnd()) {
5162
+ this.parseValue();
5163
+ if (this.check("LPAREN")) this.skipParens();
5164
+ if (this.check("LBRACE")) this.skipBlock();
5165
+ }
4569
5166
  }
4570
5167
  } else if (this.check("LBRACE")) {
4571
5168
  if (key2 === "enter" || key2 === "entry" || key2 === "on_entry") {
@@ -4583,6 +5180,9 @@ var _HoloCompositionParser = class _HoloCompositionParser {
4583
5180
  } else {
4584
5181
  this.skipBlock();
4585
5182
  }
5183
+ } else if (this.check("LPAREN")) {
5184
+ this.skipParens();
5185
+ if (this.check("LBRACE")) this.skipBlock();
4586
5186
  }
4587
5187
  this.skipNewlines();
4588
5188
  }
@@ -4592,21 +5192,40 @@ var _HoloCompositionParser = class _HoloCompositionParser {
4592
5192
  this.skipNewlines();
4593
5193
  continue;
4594
5194
  }
5195
+ if (this.current().type !== "IDENTIFIER" && !this.isKeywordAsIdentifierType(this.current().type)) {
5196
+ if (this.check("LPAREN")) this.skipParens();
5197
+ else if (this.check("LBRACE")) this.skipBlock();
5198
+ else this.advance();
5199
+ this.skipNewlines();
5200
+ continue;
5201
+ }
4595
5202
  const key = this.expectIdentifier();
4596
5203
  if (key === "initial" || key === "initialState") {
4597
5204
  this.expect("COLON");
4598
5205
  sm.initialState = this.parseValue();
5206
+ } else if (key === "input") {
5207
+ sm.inputs.push(this.parseAnimationInputDeclaration(startLoc));
5208
+ } else if (key === "listen") {
5209
+ sm.listeners.push(this.parseAnimationListenerDeclaration(startLoc));
4599
5210
  } else if (key === "name") {
4600
5211
  this.expect("COLON");
4601
5212
  sm.name = this.parseValue();
4602
5213
  } else if (key === "states" && this.check("COLON")) {
4603
5214
  this.advance();
4604
5215
  sm.states = this.parseStateMachineStates();
5216
+ } else if (key === "transitions" && this.check("COLON")) {
5217
+ this.advance();
5218
+ sm.transitions = this.parseStateTransitions();
4605
5219
  } else if (this.check("COLON")) {
4606
5220
  this.advance();
4607
5221
  this.parseValue();
5222
+ if (this.check("LPAREN")) this.skipParens();
5223
+ if (this.check("LBRACE")) this.skipBlock();
4608
5224
  } else if (this.check("LBRACE")) {
4609
5225
  this.skipBlock();
5226
+ } else if (this.check("LPAREN")) {
5227
+ this.skipParens();
5228
+ if (this.check("LBRACE")) this.skipBlock();
4610
5229
  }
4611
5230
  this.skipNewlines();
4612
5231
  }
@@ -4639,7 +5258,7 @@ var _HoloCompositionParser = class _HoloCompositionParser {
4639
5258
  if (key === "entry") state.entry = this.parseStatementBlock();
4640
5259
  else if (key === "exit") state.exit = this.parseStatementBlock();
4641
5260
  else if (key === "actions") state.actions = this.parseBehaviorActions();
4642
- else if (key === "onDamage") state.onDamage = this.parseStatementBlock();
5261
+ else if (this.parseAnimationStateMetadata(state, key)) ; else if (key === "onDamage") state.onDamage = this.parseStatementBlock();
4643
5262
  else if (key === "timeout") state.timeout = this.parseValue();
4644
5263
  else if (key === "onTimeout") state.onTimeout = this.parseStatementBlock();
4645
5264
  else if (key === "transitions") state.transitions = this.parseStateTransitions();
@@ -4653,13 +5272,385 @@ var _HoloCompositionParser = class _HoloCompositionParser {
4653
5272
  this.expect("RBRACE");
4654
5273
  return states;
4655
5274
  }
5275
+ parseOptionalStateMachineName(defaultName) {
5276
+ if (this.check("STRING") || this.check("IDENTIFIER") || this.isKeywordAsIdentifier()) {
5277
+ return this.advance().value;
5278
+ }
5279
+ return defaultName;
5280
+ }
5281
+ parseAnimationStateMetadata(state, key) {
5282
+ if (key === "clip") {
5283
+ state.clip = String(this.parseValue() ?? "");
5284
+ return true;
5285
+ }
5286
+ if (key === "clips") {
5287
+ state.clips = this.coerceStringArray(this.parseValue());
5288
+ return true;
5289
+ }
5290
+ if (key === "parameter") {
5291
+ state.parameter = String(this.parseValue() ?? "");
5292
+ return true;
5293
+ }
5294
+ if (key === "parameters") {
5295
+ state.parameters = this.coerceStringArray(this.parseValue());
5296
+ return true;
5297
+ }
5298
+ if (key === "thresholds") {
5299
+ state.thresholds = this.coerceNumberArray(this.parseValue());
5300
+ return true;
5301
+ }
5302
+ if (key === "blendType" || key === "blend_type" || key === "blend") {
5303
+ const blendType = String(this.parseValue() ?? "").toLowerCase();
5304
+ if (blendType === "1d" || blendType === "direct") {
5305
+ state.blendType = blendType;
5306
+ } else {
5307
+ this.error(`Unknown animation blend type "${blendType}"`);
5308
+ }
5309
+ return true;
5310
+ }
5311
+ if (key === "blendMode" || key === "blend_mode") {
5312
+ const blendMode = String(this.parseValue() ?? "").toLowerCase();
5313
+ if (blendMode === "override" || blendMode === "additive") {
5314
+ state.blendMode = blendMode;
5315
+ } else {
5316
+ this.error(`Unknown animation blend mode "${blendMode}"`);
5317
+ }
5318
+ return true;
5319
+ }
5320
+ if (key === "mask") {
5321
+ state.mask = this.coerceStringArray(this.parseValue());
5322
+ return true;
5323
+ }
5324
+ if (key === "baseline") {
5325
+ state.baseline = this.coerceNumberRecord(this.parseValue());
5326
+ return true;
5327
+ }
5328
+ return false;
5329
+ }
5330
+ coerceStringArray(value) {
5331
+ if (!Array.isArray(value)) return value == null ? [] : [String(value)];
5332
+ return value.map((entry) => String(entry));
5333
+ }
5334
+ coerceNumberArray(value) {
5335
+ if (!Array.isArray(value)) {
5336
+ const single = Number(value);
5337
+ return Number.isFinite(single) ? [single] : [];
5338
+ }
5339
+ return value.map((entry) => Number(entry)).filter((entry) => Number.isFinite(entry));
5340
+ }
5341
+ coerceNumberRecord(value) {
5342
+ if (!value || typeof value !== "object" || Array.isArray(value)) return {};
5343
+ const out = {};
5344
+ for (const [key, raw] of Object.entries(value)) {
5345
+ const numeric = Number(raw);
5346
+ if (Number.isFinite(numeric)) out[key] = numeric;
5347
+ }
5348
+ return out;
5349
+ }
5350
+ isStateNameToken(offset = 0) {
5351
+ const token = this.peek(offset);
5352
+ return token.type === "STRING" || token.type === "IDENTIFIER" || this.isKeywordAsIdentifierType(token.type);
5353
+ }
5354
+ isAnimationTransitionShorthandStart() {
5355
+ if (!this.isStateNameToken()) return false;
5356
+ return this.peek(1).type === "ARROW" || this.peek(1).type === "MINUS" && this.peek(2).type === "GREATER";
5357
+ }
5358
+ consumeStateTransitionArrow() {
5359
+ if (this.match("ARROW")) return true;
5360
+ if (this.check("MINUS") && this.peek(1).type === "GREATER") {
5361
+ this.advance();
5362
+ this.advance();
5363
+ return true;
5364
+ }
5365
+ return false;
5366
+ }
5367
+ parseAnimationInputDeclaration(startLoc) {
5368
+ const name = this.expectIdentifier();
5369
+ this.expect("COLON");
5370
+ const rawType = this.parseIdentifierOrStringValue();
5371
+ const inputType = this.normalizeAnimationInputType(rawType);
5372
+ let defaultValue;
5373
+ if (this.match("EQUALS")) {
5374
+ defaultValue = this.coerceAnimationInputDefault(inputType, this.parseValue());
5375
+ }
5376
+ return {
5377
+ type: "AnimationInput",
5378
+ name,
5379
+ inputType,
5380
+ rawType,
5381
+ default: defaultValue,
5382
+ loc: { start: startLoc, end: this.currentLocation() }
5383
+ };
5384
+ }
5385
+ parseAnimationListenerDeclaration(startLoc) {
5386
+ const event = this.parseDottedIdentifierValue("Expected listener event");
5387
+ if (!this.consumeStateTransitionArrow()) {
5388
+ this.error("Expected -> in animation listener");
5389
+ }
5390
+ if (this.isIdentifierValue("fire")) {
5391
+ this.advance();
5392
+ return {
5393
+ type: "AnimationListener",
5394
+ event,
5395
+ parameter: this.parseDottedIdentifierValue("Expected trigger input"),
5396
+ action: "fire",
5397
+ loc: { start: startLoc, end: this.currentLocation() }
5398
+ };
5399
+ }
5400
+ if (this.isIdentifierValue("reset")) {
5401
+ this.advance();
5402
+ return {
5403
+ type: "AnimationListener",
5404
+ event,
5405
+ parameter: this.parseDottedIdentifierValue("Expected trigger input"),
5406
+ action: "reset",
5407
+ loc: { start: startLoc, end: this.currentLocation() }
5408
+ };
5409
+ }
5410
+ const parameter = this.parseDottedIdentifierValue("Expected animation input");
5411
+ this.expect("EQUALS");
5412
+ const assignment = this.parseAnimationListenerValue();
5413
+ return {
5414
+ type: "AnimationListener",
5415
+ event,
5416
+ parameter,
5417
+ action: "set",
5418
+ ...assignment,
5419
+ loc: { start: startLoc, end: this.currentLocation() }
5420
+ };
5421
+ }
5422
+ parseAnimationListenerValue() {
5423
+ if (this.isIdentifierValue("event")) {
5424
+ return { source: this.parseDottedIdentifierValue("Expected event value source") };
5425
+ }
5426
+ const value = this.parseValue();
5427
+ if (typeof value === "number" || typeof value === "boolean" || typeof value === "string") {
5428
+ return { value };
5429
+ }
5430
+ return { value: String(value ?? "") };
5431
+ }
5432
+ normalizeAnimationInputType(rawType) {
5433
+ const normalized = rawType.toLowerCase();
5434
+ if (normalized === "number") return "float";
5435
+ if (normalized === "boolean") return "bool";
5436
+ if (normalized === "bool" || normalized === "float" || normalized === "int" || normalized === "trigger") {
5437
+ return normalized;
5438
+ }
5439
+ this.error(`Unknown animation input type "${rawType}", defaulting to float`);
5440
+ return "float";
5441
+ }
5442
+ coerceAnimationInputDefault(inputType, value) {
5443
+ if (inputType === "bool" || inputType === "trigger") return Boolean(value);
5444
+ if (typeof value === "number") return value;
5445
+ if (typeof value === "boolean") return value ? 1 : 0;
5446
+ return void 0;
5447
+ }
5448
+ parseAnimationTransitionShorthand() {
5449
+ const startLoc = this.currentLocation();
5450
+ const rawFrom = this.parseStateNameValue();
5451
+ const from = rawFrom.toLowerCase() === "any" ? "any" : rawFrom;
5452
+ if (!this.consumeStateTransitionArrow()) {
5453
+ this.error("Expected -> in animation transition");
5454
+ }
5455
+ const target = this.parseStateNameValue();
5456
+ const transition = {
5457
+ type: "StateTransition",
5458
+ from,
5459
+ target,
5460
+ conditions: [],
5461
+ loc: { start: startLoc, end: this.currentLocation() }
5462
+ };
5463
+ while (!this.check("NEWLINE") && !this.check("SEMICOLON") && !this.check("COMMA") && !this.check("RBRACE") && !this.isAtEnd()) {
5464
+ if (!this.isStateNameToken()) break;
5465
+ const clause = this.current().value.toLowerCase();
5466
+ this.advance();
5467
+ if (clause === "when") {
5468
+ transition.condition = this.parseExpression();
5469
+ transition.conditions = this.expressionToAnimationConditions(transition.condition);
5470
+ } else if (clause === "on") {
5471
+ const event = this.parseIdentifierOrStringValue();
5472
+ transition.event = event;
5473
+ transition.conditions = [
5474
+ {
5475
+ type: "AnimationTransitionCondition",
5476
+ parameter: event,
5477
+ operator: "==",
5478
+ value: true,
5479
+ loc: { start: startLoc, end: this.currentLocation() }
5480
+ }
5481
+ ];
5482
+ } else if (clause === "over" || clause === "duration") {
5483
+ transition.duration = this.parseNumberClauseValue();
5484
+ } else if (clause === "easing") {
5485
+ transition.easing = this.parseIdentifierOrStringValue();
5486
+ } else if (clause === "exittime" || clause === "exit_time") {
5487
+ transition.exitTime = this.parseNumberClauseValue();
5488
+ transition.hasExitTime = true;
5489
+ } else if (clause === "pausewhenexiting" || clause === "pause_when_exiting") {
5490
+ transition.pauseWhenExiting = this.parseOptionalBooleanFlag();
5491
+ } else if (clause === "priority") {
5492
+ transition.priority = this.parseNumberClauseValue();
5493
+ } else if (clause === "cantransitiontoself" || clause === "can_transition_to_self") {
5494
+ transition.canTransitionToSelf = this.parseOptionalBooleanFlag();
5495
+ } else {
5496
+ this.error(`Unknown animation transition clause "${clause}"`);
5497
+ break;
5498
+ }
5499
+ }
5500
+ transition.loc = { start: startLoc, end: this.currentLocation() };
5501
+ if (this.check("COMMA") || this.check("SEMICOLON")) this.advance();
5502
+ return transition;
5503
+ }
5504
+ parseStateNameValue() {
5505
+ if (this.check("STRING") || this.check("IDENTIFIER") || this.isKeywordAsIdentifier()) {
5506
+ return this.advance().value;
5507
+ }
5508
+ this.error(`Expected state name, got ${this.current().type}`);
5509
+ return this.isAtEnd() ? "" : this.advance().value;
5510
+ }
5511
+ parseNumberClauseValue() {
5512
+ if (this.check("COLON")) this.advance();
5513
+ const value = this.parseValue();
5514
+ return typeof value === "number" ? value : Number(value) || 0;
5515
+ }
5516
+ parseIdentifierOrStringValue() {
5517
+ if (this.check("COLON")) this.advance();
5518
+ if (this.check("STRING") || this.check("IDENTIFIER") || this.isKeywordAsIdentifier()) {
5519
+ return this.advance().value;
5520
+ }
5521
+ const value = this.parseValue();
5522
+ return value == null ? "" : String(value);
5523
+ }
5524
+ parseDottedIdentifierValue(message) {
5525
+ let value = this.parseIdentifierOrStringValue();
5526
+ if (!value) {
5527
+ this.error(message);
5528
+ }
5529
+ while (this.check("DOT")) {
5530
+ this.advance();
5531
+ const part = this.parseIdentifierOrStringValue();
5532
+ if (!part) {
5533
+ this.error("Expected property name after dot");
5534
+ break;
5535
+ }
5536
+ value += `.${part}`;
5537
+ }
5538
+ return value;
5539
+ }
5540
+ isIdentifierValue(value) {
5541
+ return (this.current().type === "IDENTIFIER" || this.isKeywordAsIdentifierType(this.current().type)) && this.current().value === value;
5542
+ }
5543
+ parseOptionalBooleanFlag() {
5544
+ if (this.check("COLON")) this.advance();
5545
+ if (this.check("BOOLEAN")) return this.advance().value === "true";
5546
+ if (this.check("IDENTIFIER")) {
5547
+ const value = this.current().value.toLowerCase();
5548
+ if (value === "true" || value === "false") {
5549
+ this.advance();
5550
+ return value === "true";
5551
+ }
5552
+ }
5553
+ return true;
5554
+ }
5555
+ expressionToAnimationConditions(expression) {
5556
+ if (expression.type === "BinaryExpression" && (expression.operator === "&&" || expression.operator === "||")) {
5557
+ const left = this.expressionToAnimationConditions(expression.left);
5558
+ const right = this.expressionToAnimationConditions(expression.right);
5559
+ if (left.length > 0 && right.length > 0) {
5560
+ left[left.length - 1].chain = expression.operator === "||" ? "or" : "and";
5561
+ }
5562
+ return [...left, ...right];
5563
+ }
5564
+ const comparison = this.expressionToAnimationCondition(expression);
5565
+ return comparison ? [comparison] : [];
5566
+ }
5567
+ expressionToAnimationCondition(expression) {
5568
+ const startLoc = expression.loc?.start ?? this.currentLocation();
5569
+ const endLoc = expression.loc?.end ?? this.currentLocation();
5570
+ if (expression.type === "BinaryExpression") {
5571
+ const normalizedOperator = this.normalizeAnimationConditionOperator(expression.operator);
5572
+ if (normalizedOperator) {
5573
+ const parameter = this.expressionToString(expression.left);
5574
+ if (parameter) {
5575
+ return {
5576
+ type: "AnimationTransitionCondition",
5577
+ parameter,
5578
+ operator: normalizedOperator,
5579
+ value: this.expressionLiteralValue(expression.right),
5580
+ loc: { start: startLoc, end: endLoc }
5581
+ };
5582
+ }
5583
+ }
5584
+ }
5585
+ if (expression.type === "Identifier" || expression.type === "MemberExpression") {
5586
+ return {
5587
+ type: "AnimationTransitionCondition",
5588
+ parameter: this.expressionToString(expression),
5589
+ operator: "==",
5590
+ value: true,
5591
+ loc: { start: startLoc, end: endLoc }
5592
+ };
5593
+ }
5594
+ if (expression.type === "UnaryExpression" && expression.operator === "!") {
5595
+ const parameter = this.expressionToString(expression.argument);
5596
+ if (parameter) {
5597
+ return {
5598
+ type: "AnimationTransitionCondition",
5599
+ parameter,
5600
+ operator: "==",
5601
+ value: false,
5602
+ loc: { start: startLoc, end: endLoc }
5603
+ };
5604
+ }
5605
+ }
5606
+ return null;
5607
+ }
5608
+ normalizeAnimationConditionOperator(operator) {
5609
+ if (operator === "===") return "==";
5610
+ if (operator === "!==") return "!=";
5611
+ if (operator === "==" || operator === "!=" || operator === ">" || operator === "<" || operator === ">=" || operator === "<=") {
5612
+ return operator;
5613
+ }
5614
+ return null;
5615
+ }
5616
+ expressionLiteralValue(expression) {
5617
+ if (expression.type === "Literal") {
5618
+ if (expression.value === null) return "null";
5619
+ return expression.value;
5620
+ }
5621
+ const value = this.expressionToString(expression);
5622
+ return value || "";
5623
+ }
4656
5624
  parseStateTransitions() {
5625
+ if (this.check("LBRACE")) {
5626
+ this.expect("LBRACE");
5627
+ this.skipNewlines();
5628
+ const transitions2 = [];
5629
+ while (!this.check("RBRACE") && !this.isAtEnd()) {
5630
+ this.skipNewlines();
5631
+ if (this.check("RBRACE")) break;
5632
+ if (this.isAnimationTransitionShorthandStart()) {
5633
+ transitions2.push(this.parseAnimationTransitionShorthand());
5634
+ } else {
5635
+ this.error(`Expected animation transition, got ${this.current().type}`);
5636
+ this.advance();
5637
+ }
5638
+ this.skipNewlines();
5639
+ }
5640
+ this.expect("RBRACE");
5641
+ return transitions2;
5642
+ }
4657
5643
  this.expect("LBRACKET");
4658
5644
  this.skipNewlines();
4659
5645
  const transitions = [];
4660
5646
  while (!this.check("RBRACKET") && !this.isAtEnd()) {
4661
5647
  this.skipNewlines();
4662
5648
  if (this.check("RBRACKET")) break;
5649
+ if (this.isAnimationTransitionShorthandStart()) {
5650
+ transitions.push(this.parseAnimationTransitionShorthand());
5651
+ this.skipNewlines();
5652
+ continue;
5653
+ }
4663
5654
  this.expect("LBRACE");
4664
5655
  this.skipNewlines();
4665
5656
  const transition = {
@@ -4671,9 +5662,46 @@ var _HoloCompositionParser = class _HoloCompositionParser {
4671
5662
  if (this.check("RBRACE")) break;
4672
5663
  const key = this.expectIdentifier();
4673
5664
  this.expect("COLON");
4674
- if (key === "target") transition.target = this.parseValue();
4675
- else if (key === "condition") transition.condition = this.parseExpression();
4676
- else if (key === "event") transition.event = this.parseValue();
5665
+ if (key === "from") {
5666
+ const from = this.parseValue();
5667
+ transition.from = from.toLowerCase() === "any" ? "any" : from;
5668
+ } else if (key === "target" || key === "to") {
5669
+ transition.target = this.parseValue();
5670
+ } else if (key === "condition" || key === "when") {
5671
+ transition.condition = this.parseExpression();
5672
+ transition.conditions = this.expressionToAnimationConditions(transition.condition);
5673
+ } else if (key === "event" || key === "on") {
5674
+ transition.event = this.parseValue();
5675
+ transition.conditions = [
5676
+ {
5677
+ type: "AnimationTransitionCondition",
5678
+ parameter: transition.event,
5679
+ operator: "==",
5680
+ value: true,
5681
+ loc: transition.loc
5682
+ }
5683
+ ];
5684
+ } else if (key === "duration" || key === "over") {
5685
+ const duration = this.parseValue();
5686
+ transition.duration = typeof duration === "number" ? duration : Number(duration) || 0;
5687
+ } else if (key === "easing") {
5688
+ transition.easing = this.parseValue();
5689
+ } else if (key === "exitTime" || key === "exit_time") {
5690
+ const exitTime = this.parseValue();
5691
+ transition.exitTime = typeof exitTime === "number" ? exitTime : Number(exitTime) || 0;
5692
+ transition.hasExitTime = true;
5693
+ } else if (key === "hasExitTime" || key === "has_exit_time") {
5694
+ transition.hasExitTime = Boolean(this.parseValue());
5695
+ } else if (key === "pauseWhenExiting" || key === "pause_when_exiting") {
5696
+ transition.pauseWhenExiting = Boolean(this.parseValue());
5697
+ } else if (key === "priority") {
5698
+ const priority = this.parseValue();
5699
+ transition.priority = typeof priority === "number" ? priority : Number(priority) || 0;
5700
+ } else if (key === "canTransitionToSelf" || key === "can_transition_to_self") {
5701
+ transition.canTransitionToSelf = Boolean(this.parseValue());
5702
+ } else {
5703
+ this.parseValue();
5704
+ }
4677
5705
  this.skipNewlines();
4678
5706
  }
4679
5707
  this.expect("RBRACE");
@@ -4963,32 +5991,714 @@ var _HoloCompositionParser = class _HoloCompositionParser {
4963
5991
  isDomainBlockToken() {
4964
5992
  return _HoloCompositionParser.DOMAIN_TOKENS.has(this.current().type);
4965
5993
  }
4966
- // ===========================================================================
4967
- // NORM LIFECYCLE BLOCKS (v4.5 March 2026, CRSEC Model)
4968
- // ===========================================================================
4969
- /**
4970
- * Parse a norm block with full CRSEC lifecycle sub-blocks.
4971
- *
4972
- * Pattern:
4973
- * ```
4974
- * norm "NormName" @trait1 @trait2 {
4975
- * description: "..."
4976
- * category: "..."
4977
- * priority: 8
4978
- *
4979
- * creation { ... }
4980
- * representation { ... }
4981
- * spreading { ... }
4982
- * evaluation { ... }
4983
- * compliance { ... }
4984
- *
4985
- * on norm_violated(agent, context) { ... }
4986
- * }
4987
- * ```
4988
- */
4989
- parseNormBlock() {
4990
- const startLoc = this.currentLocation();
4991
- this.pushContext("norm");
5994
+ isLooseOnHandlerStart() {
5995
+ return this.check("IDENTIFIER") && this.current().value === "on";
5996
+ }
5997
+ skipLooseOnHandler() {
5998
+ if (!this.isLooseOnHandlerStart()) return;
5999
+ this.advance();
6000
+ while (!this.check("LBRACE") && !this.isAtEnd()) {
6001
+ if (this.check("LPAREN")) {
6002
+ this.skipParens();
6003
+ } else {
6004
+ this.advance();
6005
+ }
6006
+ }
6007
+ if (this.check("LBRACE")) {
6008
+ this.skipBlock();
6009
+ }
6010
+ }
6011
+ isLooseDomainBlockStart() {
6012
+ if (!this.check("IDENTIFIER")) return false;
6013
+ const keyword = this.current().value;
6014
+ if (!/_material$/i.test(keyword)) return false;
6015
+ let index = this.pos + 1;
6016
+ if (this.tokens[index]?.type === "STRING" || this.tokens[index]?.type === "IDENTIFIER") {
6017
+ index++;
6018
+ }
6019
+ while (this.tokens[index]?.type === "AT") {
6020
+ index += 2;
6021
+ if (this.tokens[index]?.type === "LPAREN") {
6022
+ let depth = 1;
6023
+ index++;
6024
+ while (depth > 0 && index < this.tokens.length) {
6025
+ if (this.tokens[index].type === "LPAREN") depth++;
6026
+ else if (this.tokens[index].type === "RPAREN") depth--;
6027
+ index++;
6028
+ }
6029
+ }
6030
+ }
6031
+ while (this.tokens[index]?.type === "NEWLINE") index++;
6032
+ return this.tokens[index]?.type === "LBRACE";
6033
+ }
6034
+ isLooseNamedDomainBlockStart() {
6035
+ if (!this.check("IDENTIFIER")) return false;
6036
+ const keyword = this.current().value.toLowerCase();
6037
+ if (this.isPrimitiveShape(keyword) || this.isLightPrimitive(keyword) || keyword === "on") {
6038
+ return false;
6039
+ }
6040
+ let index = this.pos + 1;
6041
+ if (this.tokens[index]?.type !== "STRING" && this.tokens[index]?.type !== "IDENTIFIER") {
6042
+ return false;
6043
+ }
6044
+ index++;
6045
+ while (this.tokens[index]?.type === "AT") {
6046
+ index += 2;
6047
+ if (this.tokens[index]?.type === "LPAREN") {
6048
+ let depth = 1;
6049
+ index++;
6050
+ while (depth > 0 && index < this.tokens.length) {
6051
+ if (this.tokens[index].type === "LPAREN") depth++;
6052
+ else if (this.tokens[index].type === "RPAREN") depth--;
6053
+ index++;
6054
+ }
6055
+ }
6056
+ }
6057
+ while (this.tokens[index]?.type === "NEWLINE") index++;
6058
+ return this.tokens[index]?.type === "LBRACE";
6059
+ }
6060
+ // ===========================================================================
6061
+ // MMO/AAA GAME CONSTRUCTS (v6.2 — June 2026)
6062
+ // ===========================================================================
6063
+ /**
6064
+ * Parse a loot_table block with weighted entry sub-blocks and optional
6065
+ * guaranteed drop section.
6066
+ *
6067
+ * Syntax:
6068
+ * loot_table goblin_drops {
6069
+ * entry common_coin { item: "gold_coin" qty: "1..5" weight: 60 }
6070
+ * entry nothing { weight: 10 }
6071
+ * guaranteed { item: "goblin_ear" qty: 1 }
6072
+ * multiplier_on_faction_hostile: "ironveil * 1.5"
6073
+ * }
6074
+ */
6075
+ parseLootTable() {
6076
+ const startLoc = this.currentLocation();
6077
+ this.pushContext("loot-table");
6078
+ this.advance();
6079
+ const name = this.check("STRING") ? this.expectString() : this.expectIdentifier();
6080
+ this.expect("LBRACE");
6081
+ this.skipNewlines();
6082
+ const entries = [];
6083
+ let guaranteed;
6084
+ const properties = {};
6085
+ while (!this.check("RBRACE") && !this.isAtEnd()) {
6086
+ this.skipNewlines();
6087
+ if (this.check("RBRACE")) break;
6088
+ if (this.check("IDENTIFIER") && this.current().value === "entry") {
6089
+ this.advance();
6090
+ const entryId = this.check("STRING") ? this.expectString() : this.expectIdentifier();
6091
+ const entryProps = {};
6092
+ let weight = 0;
6093
+ let itemId;
6094
+ let qty;
6095
+ let rarity;
6096
+ let condition;
6097
+ if (this.check("LBRACE")) {
6098
+ this.advance();
6099
+ this.skipNewlines();
6100
+ while (!this.check("RBRACE") && !this.isAtEnd()) {
6101
+ this.skipNewlines();
6102
+ if (this.check("RBRACE")) break;
6103
+ const key = this.expectIdentifier();
6104
+ this.expect("COLON");
6105
+ const val = this.parseValue();
6106
+ if (key === "item") itemId = val;
6107
+ else if (key === "weight") weight = val;
6108
+ else if (key === "qty") qty = val;
6109
+ else if (key === "rarity") rarity = val;
6110
+ else if (key === "condition") condition = val;
6111
+ else entryProps[key] = val;
6112
+ if (this.check("COMMA")) this.advance();
6113
+ this.skipNewlines();
6114
+ }
6115
+ this.expect("RBRACE");
6116
+ }
6117
+ entries.push({
6118
+ type: "LootEntry",
6119
+ id: entryId,
6120
+ itemId,
6121
+ weight,
6122
+ qty,
6123
+ rarity,
6124
+ condition,
6125
+ properties: entryProps
6126
+ });
6127
+ } else if (this.check("IDENTIFIER") && this.current().value === "guaranteed") {
6128
+ this.advance();
6129
+ if (this.check("LBRACE")) {
6130
+ this.advance();
6131
+ this.skipNewlines();
6132
+ guaranteed = {};
6133
+ while (!this.check("RBRACE") && !this.isAtEnd()) {
6134
+ this.skipNewlines();
6135
+ if (this.check("RBRACE")) break;
6136
+ const key = this.expectIdentifier();
6137
+ this.expect("COLON");
6138
+ guaranteed[key] = this.parseValue();
6139
+ if (this.check("COMMA")) this.advance();
6140
+ this.skipNewlines();
6141
+ }
6142
+ this.expect("RBRACE");
6143
+ }
6144
+ } else {
6145
+ const key = this.expectIdentifier();
6146
+ this.expect("COLON");
6147
+ properties[key] = this.parseValue();
6148
+ }
6149
+ if (this.check("COMMA")) this.advance();
6150
+ this.skipNewlines();
6151
+ }
6152
+ this.expect("RBRACE");
6153
+ this.popContext();
6154
+ return {
6155
+ loc: { start: startLoc, end: this.currentLocation() },
6156
+ type: "LootTable",
6157
+ name,
6158
+ entries,
6159
+ guaranteed,
6160
+ properties
6161
+ };
6162
+ }
6163
+ /**
6164
+ * Parse a world_chunk block for open-world streaming.
6165
+ *
6166
+ * Syntax:
6167
+ * world_chunk dockside {
6168
+ * bounds: ((-200, 0, -200), (200, 100, 200))
6169
+ * priority: "high"
6170
+ * lod_distances: [50, 150, 400]
6171
+ * biome: "coastal_urban"
6172
+ * npc_roster: ["merchant_alva", "harbor_guard_01"]
6173
+ * streaming { load_radius: 300 unload_radius: 500 budget_kb: 32768 }
6174
+ * }
6175
+ */
6176
+ parseWorldChunk() {
6177
+ const startLoc = this.currentLocation();
6178
+ this.pushContext("world-chunk");
6179
+ this.advance();
6180
+ const name = this.check("STRING") ? this.expectString() : this.expectIdentifier();
6181
+ this.expect("LBRACE");
6182
+ this.skipNewlines();
6183
+ const properties = {};
6184
+ let priority;
6185
+ let biome;
6186
+ let lodDistances;
6187
+ let assetManifest;
6188
+ let npcRoster;
6189
+ let spawnPoints;
6190
+ let streaming;
6191
+ while (!this.check("RBRACE") && !this.isAtEnd()) {
6192
+ this.skipNewlines();
6193
+ if (this.check("RBRACE")) break;
6194
+ if (this.check("IDENTIFIER") && this.current().value === "streaming") {
6195
+ this.advance();
6196
+ if (this.check("LBRACE")) {
6197
+ this.advance();
6198
+ this.skipNewlines();
6199
+ streaming = {};
6200
+ while (!this.check("RBRACE") && !this.isAtEnd()) {
6201
+ this.skipNewlines();
6202
+ if (this.check("RBRACE")) break;
6203
+ const key = this.expectIdentifier();
6204
+ this.expect("COLON");
6205
+ streaming[key] = this.parseValue();
6206
+ if (this.check("COMMA")) this.advance();
6207
+ this.skipNewlines();
6208
+ }
6209
+ this.expect("RBRACE");
6210
+ }
6211
+ } else if (this.check("IDENTIFIER") && this.current().value === "asset_manifest") {
6212
+ this.advance();
6213
+ const val = this.parseValue();
6214
+ assetManifest = Array.isArray(val) ? val : [val];
6215
+ } else {
6216
+ const key = this.expectIdentifier();
6217
+ this.expect("COLON");
6218
+ const val = this.parseValue();
6219
+ if (key === "priority") priority = val;
6220
+ else if (key === "biome") biome = val;
6221
+ else if (key === "lod_distances")
6222
+ lodDistances = Array.isArray(val) ? val : [val];
6223
+ else if (key === "npc_roster") npcRoster = Array.isArray(val) ? val : [val];
6224
+ else if (key === "spawn_points") spawnPoints = val;
6225
+ else properties[key] = val;
6226
+ }
6227
+ if (this.check("COMMA")) this.advance();
6228
+ this.skipNewlines();
6229
+ }
6230
+ this.expect("RBRACE");
6231
+ this.popContext();
6232
+ return {
6233
+ loc: { start: startLoc, end: this.currentLocation() },
6234
+ type: "WorldChunk",
6235
+ name,
6236
+ priority,
6237
+ biome,
6238
+ lodDistances,
6239
+ assetManifest,
6240
+ npcRoster,
6241
+ spawnPoints,
6242
+ streaming,
6243
+ properties
6244
+ };
6245
+ }
6246
+ /**
6247
+ * Parse a world_layer block (P2.4 — phasing).
6248
+ *
6249
+ * Syntax:
6250
+ * world_layer post_awakening {
6251
+ * requires_quest: "main_chapter_1" // visible AFTER the quest is done
6252
+ * npcs: ["restored_keeper"] // forbids_quest = visible BEFORE
6253
+ * objects: ["healed_shrine"]
6254
+ * }
6255
+ */
6256
+ parseWorldLayer() {
6257
+ const startLoc = this.currentLocation();
6258
+ this.pushContext("world-layer");
6259
+ this.advance();
6260
+ const name = this.check("STRING") ? this.expectString() : this.expectIdentifier();
6261
+ this.expect("LBRACE");
6262
+ this.skipNewlines();
6263
+ const properties = {};
6264
+ let questId = "";
6265
+ let mustBeCompleted = true;
6266
+ let npcs = [];
6267
+ let objects = [];
6268
+ while (!this.check("RBRACE") && !this.isAtEnd()) {
6269
+ this.skipNewlines();
6270
+ if (this.check("RBRACE")) break;
6271
+ const key = this.expectIdentifier();
6272
+ this.expect("COLON");
6273
+ const val = this.parseValue();
6274
+ if (key === "requires_quest") {
6275
+ questId = String(val);
6276
+ mustBeCompleted = true;
6277
+ } else if (key === "forbids_quest") {
6278
+ questId = String(val);
6279
+ mustBeCompleted = false;
6280
+ } else if (key === "npcs") {
6281
+ npcs = (Array.isArray(val) ? val : [val]).map((v) => String(v));
6282
+ } else if (key === "objects") {
6283
+ objects = (Array.isArray(val) ? val : [val]).map((v) => String(v));
6284
+ } else {
6285
+ properties[key] = val;
6286
+ }
6287
+ if (this.check("COMMA")) this.advance();
6288
+ this.skipNewlines();
6289
+ }
6290
+ this.expect("RBRACE");
6291
+ this.popContext();
6292
+ return {
6293
+ loc: { start: startLoc, end: this.currentLocation() },
6294
+ type: "WorldLayer",
6295
+ name,
6296
+ predicate: { type: "PhasePredicate", kind: "quest_flag", questId, mustBeCompleted },
6297
+ npcs,
6298
+ objects,
6299
+ properties
6300
+ };
6301
+ }
6302
+ /**
6303
+ * Parse a dungeon_instance block (P2.6 — instanced content).
6304
+ *
6305
+ * Syntax:
6306
+ * dungeon_instance shadowfen_keep {
6307
+ * max_instances: 10
6308
+ * party_size: 5
6309
+ * reset_timer: 3600
6310
+ * completion_quest: "shadowfen_cleared"
6311
+ * npcs: ["dungeon_boss"]
6312
+ * }
6313
+ */
6314
+ parseDungeonInstance() {
6315
+ const startLoc = this.currentLocation();
6316
+ this.pushContext("dungeon-instance");
6317
+ this.advance();
6318
+ const name = this.check("STRING") ? this.expectString() : this.expectIdentifier();
6319
+ this.expect("LBRACE");
6320
+ this.skipNewlines();
6321
+ const properties = {};
6322
+ let maxInstances = 1;
6323
+ let partySize = 1;
6324
+ let resetTimer = 0;
6325
+ let completionQuest = "";
6326
+ let npcs = [];
6327
+ let objects = [];
6328
+ while (!this.check("RBRACE") && !this.isAtEnd()) {
6329
+ this.skipNewlines();
6330
+ if (this.check("RBRACE")) break;
6331
+ const key = this.expectIdentifier();
6332
+ this.expect("COLON");
6333
+ const val = this.parseValue();
6334
+ if (key === "max_instances") maxInstances = Number(val) || 1;
6335
+ else if (key === "party_size") partySize = Number(val) || 1;
6336
+ else if (key === "reset_timer") resetTimer = Number(val) || 0;
6337
+ else if (key === "completion_quest") completionQuest = String(val);
6338
+ else if (key === "npcs") npcs = (Array.isArray(val) ? val : [val]).map((v) => String(v));
6339
+ else if (key === "objects")
6340
+ objects = (Array.isArray(val) ? val : [val]).map((v) => String(v));
6341
+ else properties[key] = val;
6342
+ if (this.check("COMMA")) this.advance();
6343
+ this.skipNewlines();
6344
+ }
6345
+ this.expect("RBRACE");
6346
+ this.popContext();
6347
+ return {
6348
+ loc: { start: startLoc, end: this.currentLocation() },
6349
+ type: "DungeonInstance",
6350
+ name,
6351
+ maxInstances,
6352
+ partySize,
6353
+ resetTimer,
6354
+ completionQuest,
6355
+ npcs,
6356
+ objects,
6357
+ properties
6358
+ };
6359
+ }
6360
+ /**
6361
+ * Parse a world_shard block (P2.5 — world sharding).
6362
+ *
6363
+ * Syntax:
6364
+ * world_shard north_province {
6365
+ * min: [-1000, 0, -1000]
6366
+ * max: [0, 256, 1000]
6367
+ * neighbors: ["south_province"]
6368
+ * max_players: 200
6369
+ * handoff: "seamless"
6370
+ * }
6371
+ */
6372
+ parseWorldShard() {
6373
+ const startLoc = this.currentLocation();
6374
+ this.pushContext("world-shard");
6375
+ this.advance();
6376
+ const name = this.check("STRING") ? this.expectString() : this.expectIdentifier();
6377
+ this.expect("LBRACE");
6378
+ this.skipNewlines();
6379
+ const properties = {};
6380
+ let min = [0, 0, 0];
6381
+ let max = [0, 0, 0];
6382
+ let neighbors = [];
6383
+ let maxPlayers = 100;
6384
+ let handoff = "seamless";
6385
+ const toVec3 = (val) => {
6386
+ const a = (Array.isArray(val) ? val : [val]).map((v) => Number(v) || 0);
6387
+ return [a[0] ?? 0, a[1] ?? 0, a[2] ?? 0];
6388
+ };
6389
+ while (!this.check("RBRACE") && !this.isAtEnd()) {
6390
+ this.skipNewlines();
6391
+ if (this.check("RBRACE")) break;
6392
+ const key = this.expectIdentifier();
6393
+ this.expect("COLON");
6394
+ const val = this.parseValue();
6395
+ if (key === "min") min = toVec3(val);
6396
+ else if (key === "max") max = toVec3(val);
6397
+ else if (key === "neighbors")
6398
+ neighbors = (Array.isArray(val) ? val : [val]).map((v) => String(v));
6399
+ else if (key === "max_players") maxPlayers = Number(val) || 100;
6400
+ else if (key === "handoff") handoff = String(val);
6401
+ else properties[key] = val;
6402
+ if (this.check("COMMA")) this.advance();
6403
+ this.skipNewlines();
6404
+ }
6405
+ this.expect("RBRACE");
6406
+ this.popContext();
6407
+ return {
6408
+ loc: { start: startLoc, end: this.currentLocation() },
6409
+ type: "WorldShard",
6410
+ name,
6411
+ min,
6412
+ max,
6413
+ neighbors,
6414
+ maxPlayers,
6415
+ handoff,
6416
+ properties
6417
+ };
6418
+ }
6419
+ /**
6420
+ * Parse a spawn_point block.
6421
+ *
6422
+ * Syntax:
6423
+ * spawn_point village_entry {
6424
+ * faction: "neutral"
6425
+ * max_count: 10
6426
+ * respawn_radius: 5
6427
+ * position: (10, 0, 10)
6428
+ * }
6429
+ */
6430
+ parseSpawnPoint() {
6431
+ const startLoc = this.currentLocation();
6432
+ this.pushContext("spawn-point");
6433
+ this.advance();
6434
+ const name = this.check("STRING") ? this.expectString() : this.expectIdentifier();
6435
+ this.expect("LBRACE");
6436
+ this.skipNewlines();
6437
+ const properties = {};
6438
+ let faction;
6439
+ let maxCount;
6440
+ let respawnRadius;
6441
+ let position;
6442
+ while (!this.check("RBRACE") && !this.isAtEnd()) {
6443
+ this.skipNewlines();
6444
+ if (this.check("RBRACE")) break;
6445
+ const key = this.expectIdentifier();
6446
+ this.expect("COLON");
6447
+ const val = this.parseValue();
6448
+ if (key === "faction") faction = val;
6449
+ else if (key === "max_count") maxCount = val;
6450
+ else if (key === "respawn_radius") respawnRadius = val;
6451
+ else if (key === "position") {
6452
+ if (Array.isArray(val) && val.length >= 3) {
6453
+ position = { x: val[0], y: val[1], z: val[2] };
6454
+ }
6455
+ } else {
6456
+ properties[key] = val;
6457
+ }
6458
+ if (this.check("COMMA")) this.advance();
6459
+ this.skipNewlines();
6460
+ }
6461
+ this.expect("RBRACE");
6462
+ this.popContext();
6463
+ return {
6464
+ loc: { start: startLoc, end: this.currentLocation() },
6465
+ type: "SpawnPoint",
6466
+ name,
6467
+ faction,
6468
+ maxCount,
6469
+ respawnRadius,
6470
+ position,
6471
+ properties
6472
+ };
6473
+ }
6474
+ /**
6475
+ * Parse a trigger block for MMO interaction volumes.
6476
+ *
6477
+ * Syntax:
6478
+ * trigger dungeon_entrance {
6479
+ * radius: 3
6480
+ * faction_filter: ["alliance", "neutral"]
6481
+ * on_enter { emit("dungeon_enter") }
6482
+ * on_exit { emit("dungeon_exit") }
6483
+ * }
6484
+ */
6485
+ parseGameTrigger() {
6486
+ const startLoc = this.currentLocation();
6487
+ this.pushContext("game-trigger");
6488
+ this.advance();
6489
+ const name = this.check("STRING") ? this.expectString() : this.expectIdentifier();
6490
+ this.expect("LBRACE");
6491
+ this.skipNewlines();
6492
+ const properties = {};
6493
+ let radius = 1;
6494
+ let factionFilter;
6495
+ let position;
6496
+ const onEnter = [];
6497
+ const onExit = [];
6498
+ while (!this.check("RBRACE") && !this.isAtEnd()) {
6499
+ this.skipNewlines();
6500
+ if (this.check("RBRACE")) break;
6501
+ if (this.check("IDENTIFIER") && this.current().value === "on_enter") {
6502
+ this.advance();
6503
+ const params = this.check("LPAREN") ? this.parseParameterList() : [];
6504
+ const body = this.check("LBRACE") ? (() => {
6505
+ this.advance();
6506
+ this.skipNewlines();
6507
+ const stmts = this.parseStatementBlock();
6508
+ this.expect("RBRACE");
6509
+ return stmts;
6510
+ })() : [];
6511
+ onEnter.push({ type: "EventHandler", event: "on_enter", parameters: params, body });
6512
+ } else if (this.check("IDENTIFIER") && this.current().value === "on_exit") {
6513
+ this.advance();
6514
+ const params = this.check("LPAREN") ? this.parseParameterList() : [];
6515
+ const body = this.check("LBRACE") ? (() => {
6516
+ this.advance();
6517
+ this.skipNewlines();
6518
+ const stmts = this.parseStatementBlock();
6519
+ this.expect("RBRACE");
6520
+ return stmts;
6521
+ })() : [];
6522
+ onExit.push({ type: "EventHandler", event: "on_exit", parameters: params, body });
6523
+ } else {
6524
+ const key = this.expectIdentifier();
6525
+ this.expect("COLON");
6526
+ const val = this.parseValue();
6527
+ if (key === "radius") radius = val;
6528
+ else if (key === "faction_filter")
6529
+ factionFilter = Array.isArray(val) ? val : [val];
6530
+ else if (key === "position") {
6531
+ if (Array.isArray(val) && val.length >= 3) {
6532
+ position = { x: val[0], y: val[1], z: val[2] };
6533
+ }
6534
+ } else {
6535
+ properties[key] = val;
6536
+ }
6537
+ }
6538
+ if (this.check("COMMA")) this.advance();
6539
+ this.skipNewlines();
6540
+ }
6541
+ this.expect("RBRACE");
6542
+ this.popContext();
6543
+ return {
6544
+ loc: { start: startLoc, end: this.currentLocation() },
6545
+ type: "GameTrigger",
6546
+ name,
6547
+ radius,
6548
+ factionFilter,
6549
+ onEnter: onEnter.length > 0 ? onEnter : void 0,
6550
+ onExit: onExit.length > 0 ? onExit : void 0,
6551
+ position,
6552
+ properties
6553
+ };
6554
+ }
6555
+ /**
6556
+ * Parse a scene-level movement path:
6557
+ * movement_path patrol_route { mode: "patrol" loop: true speed: 2.5
6558
+ * waypoints: [[0,0,0],[10,0,0]] easing: "linear" }
6559
+ */
6560
+ parseMovementPath() {
6561
+ const startLoc = this.currentLocation();
6562
+ this.pushContext("movement-path");
6563
+ this.advance();
6564
+ const name = this.check("STRING") ? this.expectString() : this.expectIdentifier();
6565
+ this.expect("LBRACE");
6566
+ this.skipNewlines();
6567
+ const properties = {};
6568
+ let mode;
6569
+ let loop;
6570
+ let speed;
6571
+ let waypoints;
6572
+ let easing;
6573
+ while (!this.check("RBRACE") && !this.isAtEnd()) {
6574
+ this.skipNewlines();
6575
+ if (this.check("RBRACE")) break;
6576
+ const key = this.expectIdentifier();
6577
+ this.expect("COLON");
6578
+ const val = this.parseValue();
6579
+ if (key === "mode") mode = val;
6580
+ else if (key === "loop") loop = val;
6581
+ else if (key === "speed") speed = val;
6582
+ else if (key === "waypoints") waypoints = val;
6583
+ else if (key === "easing") easing = val;
6584
+ else properties[key] = val;
6585
+ if (this.check("COMMA")) this.advance();
6586
+ this.skipNewlines();
6587
+ }
6588
+ this.expect("RBRACE");
6589
+ this.popContext();
6590
+ return {
6591
+ loc: { start: startLoc, end: this.currentLocation() },
6592
+ type: "MovementPath",
6593
+ name,
6594
+ mode,
6595
+ loop,
6596
+ speed,
6597
+ waypoints,
6598
+ easing,
6599
+ properties
6600
+ };
6601
+ }
6602
+ /**
6603
+ * Parse a scene-level reaction trigger:
6604
+ * reaction_trigger on_player_enter { target: "player" condition: "..."
6605
+ * on_activate { emit("zone_entered") } on_deactivate { ... } cooldown: 2 }
6606
+ */
6607
+ parseReactionTrigger() {
6608
+ const startLoc = this.currentLocation();
6609
+ this.pushContext("reaction-trigger");
6610
+ this.advance();
6611
+ const name = this.check("STRING") ? this.expectString() : this.expectIdentifier();
6612
+ this.expect("LBRACE");
6613
+ this.skipNewlines();
6614
+ const properties = {};
6615
+ let target;
6616
+ let condition;
6617
+ let cooldown;
6618
+ const onActivate = [];
6619
+ const onDeactivate = [];
6620
+ while (!this.check("RBRACE") && !this.isAtEnd()) {
6621
+ this.skipNewlines();
6622
+ if (this.check("RBRACE")) break;
6623
+ if (this.check("IDENTIFIER") && this.current().value === "on_activate") {
6624
+ this.advance();
6625
+ const params = this.check("LPAREN") ? this.parseParameterList() : [];
6626
+ const body = this.check("LBRACE") ? (() => {
6627
+ this.advance();
6628
+ this.skipNewlines();
6629
+ const stmts = this.parseStatementBlock();
6630
+ this.expect("RBRACE");
6631
+ return stmts;
6632
+ })() : [];
6633
+ onActivate.push({ type: "EventHandler", event: "on_activate", parameters: params, body });
6634
+ } else if (this.check("IDENTIFIER") && this.current().value === "on_deactivate") {
6635
+ this.advance();
6636
+ const params = this.check("LPAREN") ? this.parseParameterList() : [];
6637
+ const body = this.check("LBRACE") ? (() => {
6638
+ this.advance();
6639
+ this.skipNewlines();
6640
+ const stmts = this.parseStatementBlock();
6641
+ this.expect("RBRACE");
6642
+ return stmts;
6643
+ })() : [];
6644
+ onDeactivate.push({
6645
+ type: "EventHandler",
6646
+ event: "on_deactivate",
6647
+ parameters: params,
6648
+ body
6649
+ });
6650
+ } else {
6651
+ const key = this.expectIdentifier();
6652
+ this.expect("COLON");
6653
+ const val = this.parseValue();
6654
+ if (key === "target") target = val;
6655
+ else if (key === "condition") condition = val;
6656
+ else if (key === "cooldown") cooldown = val;
6657
+ else properties[key] = val;
6658
+ }
6659
+ if (this.check("COMMA")) this.advance();
6660
+ this.skipNewlines();
6661
+ }
6662
+ this.expect("RBRACE");
6663
+ this.popContext();
6664
+ return {
6665
+ loc: { start: startLoc, end: this.currentLocation() },
6666
+ type: "ReactionTrigger",
6667
+ name,
6668
+ target,
6669
+ condition,
6670
+ cooldown,
6671
+ onActivate: onActivate.length > 0 ? onActivate : void 0,
6672
+ onDeactivate: onDeactivate.length > 0 ? onDeactivate : void 0,
6673
+ properties
6674
+ };
6675
+ }
6676
+ // ===========================================================================
6677
+ // NORM LIFECYCLE BLOCKS (v4.5 — March 2026, CRSEC Model)
6678
+ // ===========================================================================
6679
+ /**
6680
+ * Parse a norm block with full CRSEC lifecycle sub-blocks.
6681
+ *
6682
+ * Pattern:
6683
+ * ```
6684
+ * norm "NormName" @trait1 @trait2 {
6685
+ * description: "..."
6686
+ * category: "..."
6687
+ * priority: 8
6688
+ *
6689
+ * creation { ... }
6690
+ * representation { ... }
6691
+ * spreading { ... }
6692
+ * evaluation { ... }
6693
+ * compliance { ... }
6694
+ *
6695
+ * on norm_violated(agent, context) { ... }
6696
+ * }
6697
+ * ```
6698
+ */
6699
+ parseNormBlock() {
6700
+ const startLoc = this.currentLocation();
6701
+ this.pushContext("norm");
4992
6702
  this.advance();
4993
6703
  let name = "unnamed";
4994
6704
  if (this.check("STRING")) {
@@ -4996,15 +6706,7 @@ var _HoloCompositionParser = class _HoloCompositionParser {
4996
6706
  } else if (this.check("IDENTIFIER")) {
4997
6707
  name = this.expectIdentifier();
4998
6708
  }
4999
- const traits = [];
5000
- while (this.check("AT") && this.peek(1)?.type === "IDENTIFIER") {
5001
- this.advance();
5002
- traits.push(this.current().value);
5003
- this.advance();
5004
- if (this.check("LPAREN")) {
5005
- this.skipParens();
5006
- }
5007
- }
6709
+ const traits = this.parseInlineTraitNamesBeforeBlock();
5008
6710
  this.expect("LBRACE");
5009
6711
  this.skipNewlines();
5010
6712
  const properties = {};
@@ -5058,6 +6760,9 @@ var _HoloCompositionParser = class _HoloCompositionParser {
5058
6760
  body
5059
6761
  });
5060
6762
  }
6763
+ } else if (this.isPropertyName() && this.peek(1)?.type === "LBRACE") {
6764
+ const key = this.parsePropertyKey();
6765
+ properties[key] = this.parseBlockTraitConfig();
5061
6766
  } else if (this.check("IDENTIFIER") || this.check("STRING")) {
5062
6767
  const key = this.check("STRING") ? this.expectString() : this.expectIdentifier();
5063
6768
  this.expect("COLON");
@@ -5137,15 +6842,7 @@ var _HoloCompositionParser = class _HoloCompositionParser {
5137
6842
  } else if (this.check("IDENTIFIER")) {
5138
6843
  name = this.expectIdentifier();
5139
6844
  }
5140
- const traits = [];
5141
- while (this.check("AT") && this.peek(1)?.type === "IDENTIFIER") {
5142
- this.advance();
5143
- traits.push(this.current().value);
5144
- this.advance();
5145
- if (this.check("LPAREN")) {
5146
- this.skipParens();
5147
- }
5148
- }
6845
+ const traits = this.parseInlineTraitNamesBeforeBlock();
5149
6846
  this.expect("LBRACE");
5150
6847
  this.skipNewlines();
5151
6848
  const properties = {};
@@ -5187,6 +6884,9 @@ var _HoloCompositionParser = class _HoloCompositionParser {
5187
6884
  body
5188
6885
  });
5189
6886
  }
6887
+ } else if (this.isPropertyName() && this.peek(1)?.type === "LBRACE") {
6888
+ const key = this.parsePropertyKey();
6889
+ properties[key] = this.parseBlockTraitConfig();
5190
6890
  } else if (this.check("IDENTIFIER") || this.check("STRING")) {
5191
6891
  const key = this.check("STRING") ? this.expectString() : this.expectIdentifier();
5192
6892
  this.expect("COLON");
@@ -5211,6 +6911,303 @@ var _HoloCompositionParser = class _HoloCompositionParser {
5211
6911
  eventHandlers: eventHandlers.length > 0 ? eventHandlers : void 0
5212
6912
  };
5213
6913
  }
6914
+ // ===========================================================================
6915
+ // SIMULATION CONTRACT BLOCK (v6.3)
6916
+ // ===========================================================================
6917
+ /**
6918
+ * Parse a `sim_contract { ... }` block.
6919
+ *
6920
+ * Syntax:
6921
+ * ```
6922
+ * sim_contract {
6923
+ * precondition "name" { expr }
6924
+ * precondition "name" "description" { expr }
6925
+ * invariant "name" { expr }
6926
+ * receipt { field: type, ... }
6927
+ * }
6928
+ * ```
6929
+ */
6930
+ parseContractBlock() {
6931
+ const startLoc = this.currentLocation();
6932
+ this.pushContext("sim_contract");
6933
+ this.advance();
6934
+ this.expect("LBRACE");
6935
+ this.skipNewlines();
6936
+ const preconditions = [];
6937
+ const invariants = [];
6938
+ const receipt = {};
6939
+ while (!this.check("RBRACE") && !this.isAtEnd()) {
6940
+ this.skipNewlines();
6941
+ if (this.check("RBRACE")) break;
6942
+ const tokenLower = this.current().value.toLowerCase();
6943
+ if ((tokenLower === "precondition" || tokenLower === "invariant") && this.check("IDENTIFIER")) {
6944
+ const clauseKind = tokenLower;
6945
+ this.advance();
6946
+ let clauseName = "unnamed";
6947
+ if (this.check("STRING")) {
6948
+ clauseName = this.expectString();
6949
+ } else if (this.check("IDENTIFIER")) {
6950
+ clauseName = this.expectIdentifier();
6951
+ }
6952
+ let description;
6953
+ if (this.check("STRING")) {
6954
+ description = this.expectString();
6955
+ }
6956
+ let expr = "";
6957
+ if (this.check("LBRACE")) {
6958
+ this.advance();
6959
+ const parts = [];
6960
+ let depth = 1;
6961
+ while (depth > 0 && !this.isAtEnd()) {
6962
+ if (this.check("LBRACE")) depth++;
6963
+ if (this.check("RBRACE")) {
6964
+ depth--;
6965
+ if (depth === 0) break;
6966
+ }
6967
+ parts.push(this.current().value);
6968
+ this.advance();
6969
+ }
6970
+ this.expect("RBRACE");
6971
+ expr = parts.join(" ").trim();
6972
+ }
6973
+ const clause = { name: clauseName, expr };
6974
+ if (description !== void 0) clause.description = description;
6975
+ if (clauseKind === "precondition") {
6976
+ preconditions.push(clause);
6977
+ } else {
6978
+ invariants.push(clause);
6979
+ }
6980
+ } else if (tokenLower === "receipt" && this.check("IDENTIFIER")) {
6981
+ this.advance();
6982
+ if (this.check("LBRACE")) {
6983
+ this.advance();
6984
+ this.skipNewlines();
6985
+ while (!this.check("RBRACE") && !this.isAtEnd()) {
6986
+ this.skipNewlines();
6987
+ if (this.check("RBRACE")) break;
6988
+ let fieldName = "";
6989
+ if (this.check("IDENTIFIER")) {
6990
+ fieldName = this.expectIdentifier();
6991
+ } else if (this.check("STRING")) {
6992
+ fieldName = this.expectString();
6993
+ } else {
6994
+ this.advance();
6995
+ continue;
6996
+ }
6997
+ let typeName = "unknown";
6998
+ if (this.check("COLON")) {
6999
+ this.advance();
7000
+ if (this.check("IDENTIFIER")) {
7001
+ typeName = this.expectIdentifier();
7002
+ } else if (this.check("STRING")) {
7003
+ typeName = this.expectString();
7004
+ }
7005
+ }
7006
+ if (fieldName) receipt[fieldName] = typeName;
7007
+ if (this.check("COMMA")) this.advance();
7008
+ this.skipNewlines();
7009
+ }
7010
+ this.expect("RBRACE");
7011
+ }
7012
+ } else {
7013
+ this.advance();
7014
+ }
7015
+ this.skipNewlines();
7016
+ }
7017
+ this.expect("RBRACE");
7018
+ this.popContext();
7019
+ return {
7020
+ loc: { start: startLoc, end: this.currentLocation() },
7021
+ type: "contract",
7022
+ preconditions,
7023
+ invariants,
7024
+ receipt
7025
+ };
7026
+ }
7027
+ // ── Pub/sub messaging primitives (v6.4) ───────────────────────────────────
7028
+ /**
7029
+ * Parse policy_pack Name { ... } as a first-class regulated-AI governance
7030
+ * primitive. Validation lives in policy/PolicyPack.ts so compilers and deploy
7031
+ * gates consume the same schema the parser emits.
7032
+ */
7033
+ parsePolicyPackBlock() {
7034
+ const startLoc = this.currentLocation();
7035
+ this.pushContext("policy-pack");
7036
+ this.advance();
7037
+ const name = this.check("STRING") ? this.expectString() : this.expectIdentifier();
7038
+ this.expect("LBRACE");
7039
+ this.skipNewlines();
7040
+ const properties = {};
7041
+ let version = "1.0.0";
7042
+ let frameworkId = "";
7043
+ let requiredTests = [];
7044
+ let requiredCompileTargets = [];
7045
+ let auditRetention = {};
7046
+ let monitoringCadence = {};
7047
+ while (!this.check("RBRACE") && !this.isAtEnd()) {
7048
+ this.skipNewlines();
7049
+ if (this.check("RBRACE")) break;
7050
+ const key = this.expectIdentifier();
7051
+ if ((key === "audit_retention" || key === "auditRetention") && this.check("LBRACE")) {
7052
+ auditRetention = this.parseBlockTraitConfig();
7053
+ } else if ((key === "monitoring" || key === "monitoring_cadence" || key === "monitoringCadence") && this.check("LBRACE")) {
7054
+ monitoringCadence = this.parseBlockTraitConfig();
7055
+ } else {
7056
+ this.expect("COLON");
7057
+ const value = this.parseValue();
7058
+ if (key === "version") version = typeof value === "string" ? value : String(value);
7059
+ else if (key === "framework_id" || key === "frameworkId") {
7060
+ frameworkId = typeof value === "string" ? value : String(value);
7061
+ } else if (key === "required_tests" || key === "requiredTests") {
7062
+ requiredTests = Array.isArray(value) ? value : [value];
7063
+ } else if (key === "required_compile_targets" || key === "requiredCompileTargets") {
7064
+ requiredCompileTargets = (Array.isArray(value) ? value : [value]).map(
7065
+ (target) => String(target)
7066
+ );
7067
+ } else if (key === "audit_retention" || key === "auditRetention") {
7068
+ auditRetention = this.asRecord(value);
7069
+ } else if (key === "monitoring" || key === "monitoring_cadence" || key === "monitoringCadence") {
7070
+ monitoringCadence = this.asRecord(value);
7071
+ } else {
7072
+ properties[key] = value;
7073
+ }
7074
+ }
7075
+ if (this.check("COMMA")) this.advance();
7076
+ this.skipNewlines();
7077
+ }
7078
+ this.expect("RBRACE");
7079
+ this.popContext();
7080
+ return {
7081
+ loc: { start: startLoc, end: this.currentLocation() },
7082
+ type: "PolicyPack",
7083
+ name,
7084
+ version,
7085
+ frameworkId,
7086
+ requiredTests,
7087
+ requiredCompileTargets,
7088
+ auditRetention,
7089
+ monitoringCadence,
7090
+ properties
7091
+ };
7092
+ }
7093
+ asRecord(value) {
7094
+ if (!value || typeof value !== "object" || Array.isArray(value) || "__bind" in value) {
7095
+ return {};
7096
+ }
7097
+ return value;
7098
+ }
7099
+ /** Parse `topic Name { type: "T" broadcast: true }` */
7100
+ parseTopicBlock() {
7101
+ const startLoc = this.currentLocation();
7102
+ this.advance();
7103
+ const name = this.check("IDENTIFIER") ? this.expectIdentifier() : "unnamed";
7104
+ const metadata = {};
7105
+ let dataType;
7106
+ let broadcast;
7107
+ if (this.check("LBRACE")) {
7108
+ this.advance();
7109
+ this.skipNewlines();
7110
+ while (!this.check("RBRACE") && !this.isAtEnd()) {
7111
+ this.skipNewlines();
7112
+ if (this.check("RBRACE") || this.check("NEWLINE")) {
7113
+ if (!this.check("RBRACE")) this.advance();
7114
+ continue;
7115
+ }
7116
+ const key = this.current().value;
7117
+ this.advance();
7118
+ if (this.check("COLON")) this.advance();
7119
+ if (key === "type" || key === "dataType") {
7120
+ dataType = this.check("STRING") ? this.expectString() : this.check("IDENTIFIER") ? this.expectIdentifier() : (this.advance(), void 0);
7121
+ } else if (key === "broadcast") {
7122
+ broadcast = this.current().value === "true";
7123
+ this.advance();
7124
+ } else if (this.check("LBRACE") || this.check("STRING") || this.check("NUMBER") || this.check("IDENTIFIER") || this.check("LBRACKET")) {
7125
+ metadata[key] = this.parseValue();
7126
+ }
7127
+ if (this.check("COMMA")) this.advance();
7128
+ this.skipNewlines();
7129
+ }
7130
+ this.expect("RBRACE");
7131
+ }
7132
+ const topic = {
7133
+ loc: { start: startLoc, end: this.currentLocation() },
7134
+ type: "Topic",
7135
+ name
7136
+ };
7137
+ if (dataType !== void 0) topic.dataType = dataType;
7138
+ if (broadcast !== void 0) topic.broadcast = broadcast;
7139
+ if (Object.keys(metadata).length > 0) topic.metadata = metadata;
7140
+ return topic;
7141
+ }
7142
+ /** Parse `channel Name { from: A to: B capacity: N }` */
7143
+ parseChannelBlock() {
7144
+ const startLoc = this.currentLocation();
7145
+ this.advance();
7146
+ const name = this.check("IDENTIFIER") ? this.expectIdentifier() : "unnamed";
7147
+ const metadata = {};
7148
+ let from;
7149
+ let to;
7150
+ let capacity;
7151
+ if (this.check("LBRACE")) {
7152
+ this.advance();
7153
+ this.skipNewlines();
7154
+ while (!this.check("RBRACE") && !this.isAtEnd()) {
7155
+ this.skipNewlines();
7156
+ if (this.check("RBRACE") || this.check("NEWLINE")) {
7157
+ if (!this.check("RBRACE")) this.advance();
7158
+ continue;
7159
+ }
7160
+ const key = this.current().value;
7161
+ this.advance();
7162
+ if (this.check("COLON")) this.advance();
7163
+ if (key === "from") {
7164
+ from = this.check("STRING") ? this.expectString() : this.check("IDENTIFIER") ? this.expectIdentifier() : void 0;
7165
+ } else if (key === "to") {
7166
+ to = this.check("STRING") ? this.expectString() : this.check("IDENTIFIER") ? this.expectIdentifier() : void 0;
7167
+ } else if (key === "capacity") {
7168
+ capacity = this.check("NUMBER") ? Number(this.current().value) : void 0;
7169
+ if (capacity !== void 0) this.advance();
7170
+ } else if (this.check("LBRACE") || this.check("STRING") || this.check("NUMBER") || this.check("IDENTIFIER") || this.check("LBRACKET")) {
7171
+ metadata[key] = this.parseValue();
7172
+ }
7173
+ if (this.check("COMMA")) this.advance();
7174
+ this.skipNewlines();
7175
+ }
7176
+ this.expect("RBRACE");
7177
+ }
7178
+ const ch = {
7179
+ loc: { start: startLoc, end: this.currentLocation() },
7180
+ type: "Channel",
7181
+ name
7182
+ };
7183
+ if (from !== void 0) ch.from = from;
7184
+ if (to !== void 0) ch.to = to;
7185
+ if (capacity !== void 0) ch.capacity = capacity;
7186
+ if (Object.keys(metadata).length > 0) ch.metadata = metadata;
7187
+ return ch;
7188
+ }
7189
+ /** Parse `connect Identifier to Identifier [as "edgeType"]` */
7190
+ parseConnectionStmt() {
7191
+ const startLoc = this.currentLocation();
7192
+ this.advance();
7193
+ const from = this.check("IDENTIFIER") ? this.expectIdentifier() : "";
7194
+ if (this.check("IDENTIFIER") && this.current().value === "to") this.advance();
7195
+ const to = this.check("IDENTIFIER") ? this.expectIdentifier() : "";
7196
+ let edgeType;
7197
+ if (this.check("IDENTIFIER") && this.current().value === "as") {
7198
+ this.advance();
7199
+ if (this.check("STRING")) edgeType = this.expectString();
7200
+ else if (this.check("IDENTIFIER")) edgeType = this.expectIdentifier();
7201
+ }
7202
+ const conn = {
7203
+ loc: { start: startLoc, end: this.currentLocation() },
7204
+ type: "Connection",
7205
+ from,
7206
+ to
7207
+ };
7208
+ if (edgeType !== void 0) conn.edgeType = edgeType;
7209
+ return conn;
7210
+ }
5214
7211
  /**
5215
7212
  * Unified parser for all domain-specific blocks.
5216
7213
  * Pattern: KEYWORD NAME @trait1 @trait2 { properties... }
@@ -5257,27 +7254,27 @@ var _HoloCompositionParser = class _HoloCompositionParser {
5257
7254
  if (domain === "pipeline" && keyword === "pipeline") {
5258
7255
  return this.parsePipelineDomainBlock(name, traits);
5259
7256
  }
7257
+ if (token.type === "PCG_GRAPH") {
7258
+ return this.parsePCGGraphDomainBlock(startLoc, name, traits, keyword, domain);
7259
+ }
5260
7260
  this.expect("LBRACE");
5261
7261
  this.skipNewlines();
5262
7262
  const properties = {};
5263
7263
  const children = [];
5264
7264
  const eventHandlers = [];
5265
7265
  while (!this.check("RBRACE") && !this.isAtEnd()) {
5266
- this.skipNewlines();
7266
+ this.skipBlockMemberSeparators();
5267
7267
  if (this.check("RBRACE")) break;
5268
- if (this.check("OBJECT") || this.check("IDENTIFIER") && PRIMITIVE_SHAPES.has(this.current().value)) {
7268
+ if (this.check("OBJECT")) {
5269
7269
  children.push(this.parseObject());
7270
+ } else if (this.check("IDENTIFIER") && this.isPrimitiveShape(this.current().value) && this.peek(1).type !== "COLON") {
7271
+ children.push(this.parsePrimitiveObject());
5270
7272
  } else if (this.check("IDENTIFIER") && this.current().value.startsWith("on")) {
5271
7273
  const evtName = this.current().value;
5272
7274
  if (this.tokens[this.pos + 1]?.type === "LPAREN" || this.tokens[this.pos + 1]?.type === "LBRACE") {
5273
7275
  this.advance();
5274
7276
  if (this.check("LPAREN")) {
5275
- this.advance();
5276
- while (!this.check("RPAREN") && !this.isAtEnd()) {
5277
- this.expectIdentifier();
5278
- if (this.check("COMMA")) this.advance();
5279
- }
5280
- this.expect("RPAREN");
7277
+ this.skipParens();
5281
7278
  }
5282
7279
  if (this.check("LBRACE")) {
5283
7280
  this.skipBlock();
@@ -5289,13 +7286,51 @@ var _HoloCompositionParser = class _HoloCompositionParser {
5289
7286
  body: []
5290
7287
  });
5291
7288
  } else {
5292
- const key = this.expectIdentifier();
7289
+ const key = this.parsePropertyKey();
5293
7290
  this.expect("COLON");
5294
7291
  const value = this.parseValue();
5295
7292
  properties[key] = value;
5296
7293
  }
7294
+ } else if (this.check("AT")) {
7295
+ this.advance();
7296
+ const traitName = this.parseTraitName();
7297
+ if (traitName) traits.push(traitName);
7298
+ if (this.check("LPAREN") || this.check("LBRACE") || this.check("COLON")) {
7299
+ properties[`@${traitName}`] = this.parseOptionalTraitConfig();
7300
+ }
7301
+ } else if (this.isNamedOrTraitedPropertyBlockStart()) {
7302
+ const { key, value } = this.parseNamedOrTraitedPropertyBlock();
7303
+ properties[key] = value;
7304
+ } else if (this.isPropertyName() && this.peek(1).type === "LBRACE") {
7305
+ const key = this.parsePropertyKey();
7306
+ properties[key] = this.parseBlockTraitConfig();
7307
+ } else if (this.isPropertyName() && (this.peek(1).type === "STRING" || this.peek(1).type === "IDENTIFIER") && this.peek(2).type === "LBRACE") {
7308
+ const key = this.parsePropertyKey();
7309
+ const blockName = this.advance().value;
7310
+ properties[key] = {
7311
+ name: blockName,
7312
+ ...this.parseBlockTraitConfig()
7313
+ };
7314
+ } else if (this.isPropertyName() && (this.peek(1).type === "ARROW" || this.peek(1).type === "MINUS" && this.peek(2).type === "GREATER")) {
7315
+ const from = this.parsePropertyKey();
7316
+ if (this.check("ARROW")) {
7317
+ this.advance();
7318
+ } else {
7319
+ this.advance();
7320
+ this.advance();
7321
+ }
7322
+ if (domain === "input") {
7323
+ properties[from] = this.parseValue();
7324
+ if (this.check("COMMA")) this.advance();
7325
+ this.skipNewlines();
7326
+ continue;
7327
+ }
7328
+ const to = this.isBarewordPathToken() ? this.parseBarewordPathValue() : "";
7329
+ const existing = properties.connections;
7330
+ const connection = { from, to };
7331
+ properties.connections = Array.isArray(existing) ? [...existing, connection] : [connection];
5297
7332
  } else {
5298
- const key = this.expectIdentifier();
7333
+ const key = this.parsePropertyKey();
5299
7334
  this.expect("COLON");
5300
7335
  const value = this.parseValue();
5301
7336
  properties[key] = value;
@@ -5317,6 +7352,90 @@ var _HoloCompositionParser = class _HoloCompositionParser {
5317
7352
  eventHandlers: eventHandlers.length > 0 ? eventHandlers : void 0
5318
7353
  };
5319
7354
  }
7355
+ parsePCGGraphDomainBlock(startLoc, name, traits, keyword, domain) {
7356
+ this.expect("LBRACE");
7357
+ this.skipNewlines();
7358
+ const nodes = [];
7359
+ const properties = {
7360
+ nodes
7361
+ };
7362
+ while (!this.check("RBRACE") && !this.isAtEnd()) {
7363
+ this.skipNewlines();
7364
+ if (this.check("RBRACE")) break;
7365
+ const token = this.current();
7366
+ const next = this.peek(1);
7367
+ if (next?.type === "COLON" && (token.type === "IDENTIFIER" || token.type === "PCG_GRAPH")) {
7368
+ const key = token.value;
7369
+ this.advance();
7370
+ this.expect("COLON");
7371
+ properties[key] = this.parseValue();
7372
+ } else {
7373
+ const kind = token.value;
7374
+ this.advance();
7375
+ const nodeProperties = {};
7376
+ if (this.check("LPAREN")) {
7377
+ this.parsePCGNodeArgs(kind, nodeProperties);
7378
+ }
7379
+ nodes.push({
7380
+ kind,
7381
+ properties: nodeProperties
7382
+ });
7383
+ }
7384
+ this.skipNewlines();
7385
+ if (this.check("ARROW")) {
7386
+ this.advance();
7387
+ } else if (this.check("MINUS") && this.peek(1).type === "GREATER") {
7388
+ this.advance();
7389
+ this.advance();
7390
+ }
7391
+ if (this.check("COMMA")) this.advance();
7392
+ this.skipNewlines();
7393
+ }
7394
+ this.expect("RBRACE");
7395
+ this.popContext();
7396
+ return {
7397
+ loc: { start: startLoc, end: this.currentLocation() },
7398
+ type: "DomainBlock",
7399
+ domain,
7400
+ keyword,
7401
+ name,
7402
+ traits,
7403
+ properties
7404
+ };
7405
+ }
7406
+ parsePCGNodeArgs(kind, properties) {
7407
+ this.expect("LPAREN");
7408
+ const args = [];
7409
+ while (!this.check("RPAREN") && !this.isAtEnd()) {
7410
+ if (this.check("COMMA")) {
7411
+ this.advance();
7412
+ continue;
7413
+ }
7414
+ if (this.check("IDENTIFIER") && this.peek(1).type === "COLON") {
7415
+ const key = this.expectIdentifier();
7416
+ this.expect("COLON");
7417
+ properties[key] = this.parseValue();
7418
+ } else {
7419
+ args.push(this.parsePCGArgumentValue());
7420
+ }
7421
+ if (this.check("COMMA")) this.advance();
7422
+ }
7423
+ this.expect("RPAREN");
7424
+ if (kind === "scatter") {
7425
+ if (args[0] !== void 0) properties["source_mesh"] = args[0];
7426
+ if (args[1] !== void 0) properties["count"] = args[1];
7427
+ } else if (args.length > 0) {
7428
+ properties["args"] = args;
7429
+ }
7430
+ }
7431
+ parsePCGArgumentValue() {
7432
+ if (this.check("STRING") || this.check("NUMBER") || this.check("BOOLEAN") || this.check("NULL") || this.check("LBRACKET")) {
7433
+ return this.parseValue();
7434
+ }
7435
+ const value = this.current().value;
7436
+ this.advance();
7437
+ return value;
7438
+ }
5320
7439
  /**
5321
7440
  * Parse a pipeline domain block by extracting the raw body text
5322
7441
  * and delegating to PipelineParser for structured AST.
@@ -5455,6 +7574,10 @@ _HoloCompositionParser.DOMAIN_TOKENS = /* @__PURE__ */ new Set([
5455
7574
  "SIMULATION",
5456
7575
  // Perception & simulation layer
5457
7576
  "MATERIAL",
7577
+ "MATERIAL_GRAPH",
7578
+ "LIGHT_FIELD",
7579
+ "NAV_FIELD",
7580
+ "PHYSICS_CONTRACT",
5458
7581
  "PBR_MATERIAL",
5459
7582
  "UNLIT_MATERIAL",
5460
7583
  "SHADER",
@@ -5465,6 +7588,7 @@ _HoloCompositionParser.DOMAIN_TOKENS = /* @__PURE__ */ new Set([
5465
7588
  "PARTICLES",
5466
7589
  "EMITTER",
5467
7590
  "VFX",
7591
+ "PARTICLE_FIELD",
5468
7592
  "POST_PROCESSING",
5469
7593
  "POST_FX",
5470
7594
  "AUDIO_SOURCE",
@@ -5473,6 +7597,7 @@ _HoloCompositionParser.DOMAIN_TOKENS = /* @__PURE__ */ new Set([
5473
7597
  "WEATHER",
5474
7598
  "ATMOSPHERE",
5475
7599
  "PROCEDURAL",
7600
+ "PCG_GRAPH",
5476
7601
  "SCATTER",
5477
7602
  "LOD_BLOCK",
5478
7603
  "RENDER",
@@ -5542,7 +7667,9 @@ _HoloCompositionParser.DOMAIN_TOKENS = /* @__PURE__ */ new Set([
5542
7667
  "RETRY_BLOCK",
5543
7668
  "TIMEOUT_BLOCK",
5544
7669
  "FALLBACK_BLOCK",
5545
- "BULKHEAD_BLOCK"
7670
+ "BULKHEAD_BLOCK",
7671
+ // MMO/AAA game constructs (v6.2) — real_estate only; others handled by dedicated parsers
7672
+ "REAL_ESTATE"
5546
7673
  ]);
5547
7674
  /** Token → domain type mapping */
5548
7675
  _HoloCompositionParser.TOKEN_DOMAIN_MAP = {
@@ -5584,6 +7711,10 @@ _HoloCompositionParser.TOKEN_DOMAIN_MAP = {
5584
7711
  SIMULATION: "simulation",
5585
7712
  // Perception & simulation layer
5586
7713
  MATERIAL: "material",
7714
+ MATERIAL_GRAPH: "material_graph",
7715
+ LIGHT_FIELD: "light_field",
7716
+ NAV_FIELD: "nav_field",
7717
+ PHYSICS_CONTRACT: "physics_contract",
5587
7718
  PBR_MATERIAL: "material",
5588
7719
  UNLIT_MATERIAL: "material",
5589
7720
  SHADER: "material",
@@ -5594,6 +7725,7 @@ _HoloCompositionParser.TOKEN_DOMAIN_MAP = {
5594
7725
  PARTICLES: "vfx",
5595
7726
  EMITTER: "vfx",
5596
7727
  VFX: "vfx",
7728
+ PARTICLE_FIELD: "particle_field",
5597
7729
  POST_PROCESSING: "postfx",
5598
7730
  POST_FX: "postfx",
5599
7731
  AUDIO_SOURCE: "audio",
@@ -5602,6 +7734,7 @@ _HoloCompositionParser.TOKEN_DOMAIN_MAP = {
5602
7734
  WEATHER: "weather",
5603
7735
  ATMOSPHERE: "weather",
5604
7736
  PROCEDURAL: "procedural",
7737
+ PCG_GRAPH: "procedural",
5605
7738
  SCATTER: "procedural",
5606
7739
  LOD_BLOCK: "rendering",
5607
7740
  RENDER: "rendering",
@@ -5671,7 +7804,9 @@ _HoloCompositionParser.TOKEN_DOMAIN_MAP = {
5671
7804
  RETRY_BLOCK: "resilience",
5672
7805
  TIMEOUT_BLOCK: "resilience",
5673
7806
  FALLBACK_BLOCK: "resilience",
5674
- BULKHEAD_BLOCK: "resilience"
7807
+ BULKHEAD_BLOCK: "resilience",
7808
+ // MMO/AAA game constructs (v6.2)
7809
+ REAL_ESTATE: "custom"
5675
7810
  };
5676
7811
  var HoloCompositionParser = _HoloCompositionParser;
5677
7812
  function parseHolo(source, options) {
@@ -5742,8 +7877,11 @@ function parseHoloPartial(source, options) {
5742
7877
  }
5743
7878
 
5744
7879
  exports.HoloCompositionParser = HoloCompositionParser;
7880
+ exports.KEYWORDS = KEYWORDS;
7881
+ exports.LIGHT_PRIMITIVES = LIGHT_PRIMITIVES;
7882
+ exports.PRIMITIVE_SHAPES = PRIMITIVE_SHAPES;
5745
7883
  exports.parseHolo = parseHolo;
5746
7884
  exports.parseHoloPartial = parseHoloPartial;
5747
7885
  exports.parseHoloStrict = parseHoloStrict;
5748
- //# sourceMappingURL=chunk-4YNYPHH3.cjs.map
5749
- //# sourceMappingURL=chunk-4YNYPHH3.cjs.map
7886
+ //# sourceMappingURL=chunk-X75H75UY.cjs.map
7887
+ //# sourceMappingURL=chunk-X75H75UY.cjs.map