@rb-games/core 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (388) hide show
  1. package/README.md +488 -0
  2. package/dist/devtools/DraggableController.d.ts +10 -0
  3. package/dist/devtools/DraggableController.d.ts.map +1 -0
  4. package/dist/devtools/ResizableController.d.ts +19 -0
  5. package/dist/devtools/ResizableController.d.ts.map +1 -0
  6. package/dist/devtools/index.d.ts +7 -0
  7. package/dist/devtools/index.d.ts.map +1 -0
  8. package/dist/devtools/index.js +884 -0
  9. package/dist/devtools/index.js.map +1 -0
  10. package/dist/devtools/overlayPlugin.d.ts +3 -0
  11. package/dist/devtools/overlayPlugin.d.ts.map +1 -0
  12. package/dist/devtools/spinePropertiesPlugin.d.ts +3 -0
  13. package/dist/devtools/spinePropertiesPlugin.d.ts.map +1 -0
  14. package/dist/devtools/spriteTextPropertiesPlugin.d.ts +3 -0
  15. package/dist/devtools/spriteTextPropertiesPlugin.d.ts.map +1 -0
  16. package/dist/devtools/treePlugin.d.ts +7 -0
  17. package/dist/devtools/treePlugin.d.ts.map +1 -0
  18. package/dist/engine/PixiEngine.d.ts +404 -0
  19. package/dist/engine/PixiEngine.d.ts.map +1 -0
  20. package/dist/engine/index.d.ts +2 -0
  21. package/dist/engine/index.d.ts.map +1 -0
  22. package/dist/engine/index.js +1818 -0
  23. package/dist/engine/index.js.map +1 -0
  24. package/dist/filters/ChromaKeyFilter.d.ts +64 -0
  25. package/dist/filters/ChromaKeyFilter.d.ts.map +1 -0
  26. package/dist/filters/index.d.ts +2 -0
  27. package/dist/filters/index.d.ts.map +1 -0
  28. package/dist/filters/index.js +248 -0
  29. package/dist/filters/index.js.map +1 -0
  30. package/dist/helpers/AssetHelper.d.ts +117 -0
  31. package/dist/helpers/AssetHelper.d.ts.map +1 -0
  32. package/dist/helpers/SVGAssetHelper.d.ts +397 -0
  33. package/dist/helpers/SVGAssetHelper.d.ts.map +1 -0
  34. package/dist/helpers/SVGLoader.d.ts +46 -0
  35. package/dist/helpers/SVGLoader.d.ts.map +1 -0
  36. package/dist/helpers/SVGParser.d.ts +121 -0
  37. package/dist/helpers/SVGParser.d.ts.map +1 -0
  38. package/dist/helpers/eventBridge.d.ts +150 -0
  39. package/dist/helpers/eventBridge.d.ts.map +1 -0
  40. package/dist/helpers/index.d.ts +8 -0
  41. package/dist/helpers/index.d.ts.map +1 -0
  42. package/dist/helpers/index.js +702 -0
  43. package/dist/helpers/index.js.map +1 -0
  44. package/dist/helpers/mergeUtils.d.ts +21 -0
  45. package/dist/helpers/mergeUtils.d.ts.map +1 -0
  46. package/dist/helpers/resolvePublicPath.d.ts +6 -0
  47. package/dist/helpers/resolvePublicPath.d.ts.map +1 -0
  48. package/dist/i18n/index.d.ts +2 -0
  49. package/dist/i18n/index.d.ts.map +1 -0
  50. package/dist/i18n/index.js +527 -0
  51. package/dist/i18n/index.js.map +1 -0
  52. package/dist/i18n/sharedI18n.d.ts +11 -0
  53. package/dist/i18n/sharedI18n.d.ts.map +1 -0
  54. package/dist/layout/Align.d.ts +126 -0
  55. package/dist/layout/Align.d.ts.map +1 -0
  56. package/dist/layout/Bounds.d.ts +120 -0
  57. package/dist/layout/Bounds.d.ts.map +1 -0
  58. package/dist/layout/Distribute.d.ts +103 -0
  59. package/dist/layout/Distribute.d.ts.map +1 -0
  60. package/dist/layout/Flow.d.ts +213 -0
  61. package/dist/layout/Flow.d.ts.map +1 -0
  62. package/dist/layout/PositionUtils.d.ts +57 -0
  63. package/dist/layout/PositionUtils.d.ts.map +1 -0
  64. package/dist/layout/index.d.ts +6 -0
  65. package/dist/layout/index.d.ts.map +1 -0
  66. package/dist/layout/index.js +673 -0
  67. package/dist/layout/index.js.map +1 -0
  68. package/dist/particle/Emitter.d.ts +290 -0
  69. package/dist/particle/Emitter.d.ts.map +1 -0
  70. package/dist/particle/EmitterConfig.d.ts +228 -0
  71. package/dist/particle/EmitterConfig.d.ts.map +1 -0
  72. package/dist/particle/LinkedListContainer.d.ts +7 -0
  73. package/dist/particle/LinkedListContainer.d.ts.map +1 -0
  74. package/dist/particle/Particle.d.ts +63 -0
  75. package/dist/particle/Particle.d.ts.map +1 -0
  76. package/dist/particle/ParticleUtils.d.ts +97 -0
  77. package/dist/particle/ParticleUtils.d.ts.map +1 -0
  78. package/dist/particle/PropertyList.d.ts +40 -0
  79. package/dist/particle/PropertyList.d.ts.map +1 -0
  80. package/dist/particle/PropertyNode.d.ts +74 -0
  81. package/dist/particle/PropertyNode.d.ts.map +1 -0
  82. package/dist/particle/SpineEmitter.d.ts +55 -0
  83. package/dist/particle/SpineEmitter.d.ts.map +1 -0
  84. package/dist/particle/SpineParticle.d.ts +74 -0
  85. package/dist/particle/SpineParticle.d.ts.map +1 -0
  86. package/dist/particle/behaviors/AccelerationMovement.d.ts +62 -0
  87. package/dist/particle/behaviors/AccelerationMovement.d.ts.map +1 -0
  88. package/dist/particle/behaviors/Alpha.d.ts +60 -0
  89. package/dist/particle/behaviors/Alpha.d.ts.map +1 -0
  90. package/dist/particle/behaviors/AnimatedTexture.d.ts +111 -0
  91. package/dist/particle/behaviors/AnimatedTexture.d.ts.map +1 -0
  92. package/dist/particle/behaviors/Behaviors.d.ts +71 -0
  93. package/dist/particle/behaviors/Behaviors.d.ts.map +1 -0
  94. package/dist/particle/behaviors/BlendMode.d.ts +31 -0
  95. package/dist/particle/behaviors/BlendMode.d.ts.map +1 -0
  96. package/dist/particle/behaviors/BurstSpawn.d.ts +43 -0
  97. package/dist/particle/behaviors/BurstSpawn.d.ts.map +1 -0
  98. package/dist/particle/behaviors/Color.d.ts +60 -0
  99. package/dist/particle/behaviors/Color.d.ts.map +1 -0
  100. package/dist/particle/behaviors/MultiStateAnimatedTexture.d.ts +99 -0
  101. package/dist/particle/behaviors/MultiStateAnimatedTexture.d.ts.map +1 -0
  102. package/dist/particle/behaviors/OrderedTexture.d.ts +33 -0
  103. package/dist/particle/behaviors/OrderedTexture.d.ts.map +1 -0
  104. package/dist/particle/behaviors/PathMovement.d.ts +68 -0
  105. package/dist/particle/behaviors/PathMovement.d.ts.map +1 -0
  106. package/dist/particle/behaviors/PointSpawn.d.ts +21 -0
  107. package/dist/particle/behaviors/PointSpawn.d.ts.map +1 -0
  108. package/dist/particle/behaviors/RandomColor.d.ts +17 -0
  109. package/dist/particle/behaviors/RandomColor.d.ts.map +1 -0
  110. package/dist/particle/behaviors/RandomTexture.d.ts +32 -0
  111. package/dist/particle/behaviors/RandomTexture.d.ts.map +1 -0
  112. package/dist/particle/behaviors/Rotation.d.ts +114 -0
  113. package/dist/particle/behaviors/Rotation.d.ts.map +1 -0
  114. package/dist/particle/behaviors/Scale.d.ts +74 -0
  115. package/dist/particle/behaviors/Scale.d.ts.map +1 -0
  116. package/dist/particle/behaviors/ShapeSpawn.d.ts +58 -0
  117. package/dist/particle/behaviors/ShapeSpawn.d.ts.map +1 -0
  118. package/dist/particle/behaviors/SingleTexture.d.ts +32 -0
  119. package/dist/particle/behaviors/SingleTexture.d.ts.map +1 -0
  120. package/dist/particle/behaviors/SpeedMovement.d.ts +76 -0
  121. package/dist/particle/behaviors/SpeedMovement.d.ts.map +1 -0
  122. package/dist/particle/behaviors/SpineTexture.d.ts +173 -0
  123. package/dist/particle/behaviors/SpineTexture.d.ts.map +1 -0
  124. package/dist/particle/behaviors/ZindexBehavior.d.ts +16 -0
  125. package/dist/particle/behaviors/ZindexBehavior.d.ts.map +1 -0
  126. package/dist/particle/behaviors/editor/Types.d.ts +104 -0
  127. package/dist/particle/behaviors/editor/Types.d.ts.map +1 -0
  128. package/dist/particle/behaviors/editor/behaviors/AccelerationMovement.d.ts +2 -0
  129. package/dist/particle/behaviors/editor/behaviors/AccelerationMovement.d.ts.map +1 -0
  130. package/dist/particle/behaviors/editor/behaviors/Alpha.d.ts +2 -0
  131. package/dist/particle/behaviors/editor/behaviors/Alpha.d.ts.map +1 -0
  132. package/dist/particle/behaviors/editor/behaviors/AnimatedTexture.d.ts +2 -0
  133. package/dist/particle/behaviors/editor/behaviors/AnimatedTexture.d.ts.map +1 -0
  134. package/dist/particle/behaviors/editor/behaviors/BlendMode.d.ts +2 -0
  135. package/dist/particle/behaviors/editor/behaviors/BlendMode.d.ts.map +1 -0
  136. package/dist/particle/behaviors/editor/behaviors/BurstSpawn.d.ts +2 -0
  137. package/dist/particle/behaviors/editor/behaviors/BurstSpawn.d.ts.map +1 -0
  138. package/dist/particle/behaviors/editor/behaviors/Color.d.ts +2 -0
  139. package/dist/particle/behaviors/editor/behaviors/Color.d.ts.map +1 -0
  140. package/dist/particle/behaviors/editor/behaviors/OrderedTexture.d.ts +2 -0
  141. package/dist/particle/behaviors/editor/behaviors/OrderedTexture.d.ts.map +1 -0
  142. package/dist/particle/behaviors/editor/behaviors/PathMovement.d.ts +2 -0
  143. package/dist/particle/behaviors/editor/behaviors/PathMovement.d.ts.map +1 -0
  144. package/dist/particle/behaviors/editor/behaviors/PointSpawn.d.ts +2 -0
  145. package/dist/particle/behaviors/editor/behaviors/PointSpawn.d.ts.map +1 -0
  146. package/dist/particle/behaviors/editor/behaviors/RandomTexture.d.ts +2 -0
  147. package/dist/particle/behaviors/editor/behaviors/RandomTexture.d.ts.map +1 -0
  148. package/dist/particle/behaviors/editor/behaviors/Rotation.d.ts +2 -0
  149. package/dist/particle/behaviors/editor/behaviors/Rotation.d.ts.map +1 -0
  150. package/dist/particle/behaviors/editor/behaviors/Scale.d.ts +2 -0
  151. package/dist/particle/behaviors/editor/behaviors/Scale.d.ts.map +1 -0
  152. package/dist/particle/behaviors/editor/behaviors/ShapeSpawn.d.ts +2 -0
  153. package/dist/particle/behaviors/editor/behaviors/ShapeSpawn.d.ts.map +1 -0
  154. package/dist/particle/behaviors/editor/behaviors/SingleTexture.d.ts +2 -0
  155. package/dist/particle/behaviors/editor/behaviors/SingleTexture.d.ts.map +1 -0
  156. package/dist/particle/behaviors/editor/behaviors/SpeedMovement.d.ts +2 -0
  157. package/dist/particle/behaviors/editor/behaviors/SpeedMovement.d.ts.map +1 -0
  158. package/dist/particle/behaviors/editor/behaviors/index.d.ts +15 -0
  159. package/dist/particle/behaviors/editor/behaviors/index.d.ts.map +1 -0
  160. package/dist/particle/behaviors/editor/index.d.ts +5 -0
  161. package/dist/particle/behaviors/editor/index.d.ts.map +1 -0
  162. package/dist/particle/behaviors/editor/shapes/PolygonalChain.d.ts +2 -0
  163. package/dist/particle/behaviors/editor/shapes/PolygonalChain.d.ts.map +1 -0
  164. package/dist/particle/behaviors/editor/shapes/Rectangle.d.ts +2 -0
  165. package/dist/particle/behaviors/editor/shapes/Rectangle.d.ts.map +1 -0
  166. package/dist/particle/behaviors/editor/shapes/Torus.d.ts +2 -0
  167. package/dist/particle/behaviors/editor/shapes/Torus.d.ts.map +1 -0
  168. package/dist/particle/behaviors/index.d.ts +25 -0
  169. package/dist/particle/behaviors/index.d.ts.map +1 -0
  170. package/dist/particle/behaviors/shapes/PolygonalChain.d.ts +57 -0
  171. package/dist/particle/behaviors/shapes/PolygonalChain.d.ts.map +1 -0
  172. package/dist/particle/behaviors/shapes/Rectangle.d.ts +59 -0
  173. package/dist/particle/behaviors/shapes/Rectangle.d.ts.map +1 -0
  174. package/dist/particle/behaviors/shapes/SpawnShape.d.ts +32 -0
  175. package/dist/particle/behaviors/shapes/SpawnShape.d.ts.map +1 -0
  176. package/dist/particle/behaviors/shapes/Torus.d.ts +71 -0
  177. package/dist/particle/behaviors/shapes/Torus.d.ts.map +1 -0
  178. package/dist/particle/behaviors/shapes/index.d.ts +5 -0
  179. package/dist/particle/behaviors/shapes/index.d.ts.map +1 -0
  180. package/dist/particle/index.d.ts +11 -0
  181. package/dist/particle/index.d.ts.map +1 -0
  182. package/dist/particle/index.js +2845 -0
  183. package/dist/particle/index.js.map +1 -0
  184. package/dist/plugins/Plugin.types.d.ts +80 -0
  185. package/dist/plugins/Plugin.types.d.ts.map +1 -0
  186. package/dist/plugins/device/DeviceOptimizerPlugin.d.ts +187 -0
  187. package/dist/plugins/device/DeviceOptimizerPlugin.d.ts.map +1 -0
  188. package/dist/plugins/device/DeviceOptimizerPlugin.types.d.ts +134 -0
  189. package/dist/plugins/device/DeviceOptimizerPlugin.types.d.ts.map +1 -0
  190. package/dist/plugins/device/index.d.ts +3 -0
  191. package/dist/plugins/device/index.d.ts.map +1 -0
  192. package/dist/plugins/display/DisplayPlugin.d.ts +208 -0
  193. package/dist/plugins/display/DisplayPlugin.d.ts.map +1 -0
  194. package/dist/plugins/display/DisplayPlugin.types.d.ts +174 -0
  195. package/dist/plugins/display/DisplayPlugin.types.d.ts.map +1 -0
  196. package/dist/plugins/display/displayViewport.d.ts +10 -0
  197. package/dist/plugins/display/displayViewport.d.ts.map +1 -0
  198. package/dist/plugins/display/index.d.ts +4 -0
  199. package/dist/plugins/display/index.d.ts.map +1 -0
  200. package/dist/plugins/eventbus/EventBusPlugin.d.ts +21 -0
  201. package/dist/plugins/eventbus/EventBusPlugin.d.ts.map +1 -0
  202. package/dist/plugins/eventbus/EventBusPlugin.types.d.ts +24 -0
  203. package/dist/plugins/eventbus/EventBusPlugin.types.d.ts.map +1 -0
  204. package/dist/plugins/eventbus/index.d.ts +3 -0
  205. package/dist/plugins/eventbus/index.d.ts.map +1 -0
  206. package/dist/plugins/gsap/GsapPlugin.d.ts +307 -0
  207. package/dist/plugins/gsap/GsapPlugin.d.ts.map +1 -0
  208. package/dist/plugins/gsap/index.d.ts +2 -0
  209. package/dist/plugins/gsap/index.d.ts.map +1 -0
  210. package/dist/plugins/index.d.ts +13 -0
  211. package/dist/plugins/index.d.ts.map +1 -0
  212. package/dist/plugins/index.js +12806 -0
  213. package/dist/plugins/index.js.map +1 -0
  214. package/dist/plugins/input/InputPlugin.const.d.ts +80 -0
  215. package/dist/plugins/input/InputPlugin.const.d.ts.map +1 -0
  216. package/dist/plugins/input/InputPlugin.d.ts +141 -0
  217. package/dist/plugins/input/InputPlugin.d.ts.map +1 -0
  218. package/dist/plugins/input/InputPlugin.types.d.ts +41 -0
  219. package/dist/plugins/input/InputPlugin.types.d.ts.map +1 -0
  220. package/dist/plugins/input/KeyboardManager.d.ts +139 -0
  221. package/dist/plugins/input/KeyboardManager.d.ts.map +1 -0
  222. package/dist/plugins/input/KeyboardManager.types.d.ts +27 -0
  223. package/dist/plugins/input/KeyboardManager.types.d.ts.map +1 -0
  224. package/dist/plugins/input/index.d.ts +4 -0
  225. package/dist/plugins/input/index.d.ts.map +1 -0
  226. package/dist/plugins/language/I18NextPlugin.d.ts +30 -0
  227. package/dist/plugins/language/I18NextPlugin.d.ts.map +1 -0
  228. package/dist/plugins/language/I18NextPlugin.types.d.ts +29 -0
  229. package/dist/plugins/language/I18NextPlugin.types.d.ts.map +1 -0
  230. package/dist/plugins/language/index.d.ts +3 -0
  231. package/dist/plugins/language/index.d.ts.map +1 -0
  232. package/dist/plugins/resource/ResourcePlugin.d.ts +189 -0
  233. package/dist/plugins/resource/ResourcePlugin.d.ts.map +1 -0
  234. package/dist/plugins/resource/ResourcePlugin.types.d.ts +153 -0
  235. package/dist/plugins/resource/ResourcePlugin.types.d.ts.map +1 -0
  236. package/dist/plugins/resource/index.d.ts +3 -0
  237. package/dist/plugins/resource/index.d.ts.map +1 -0
  238. package/dist/plugins/scene/Scene.d.ts +203 -0
  239. package/dist/plugins/scene/Scene.d.ts.map +1 -0
  240. package/dist/plugins/scene/ScenePlugin.d.ts +162 -0
  241. package/dist/plugins/scene/ScenePlugin.d.ts.map +1 -0
  242. package/dist/plugins/scene/ScenePlugin.types.d.ts +35 -0
  243. package/dist/plugins/scene/ScenePlugin.types.d.ts.map +1 -0
  244. package/dist/plugins/scene/index.d.ts +4 -0
  245. package/dist/plugins/scene/index.d.ts.map +1 -0
  246. package/dist/plugins/sentry/SentryPlugin.d.ts +66 -0
  247. package/dist/plugins/sentry/SentryPlugin.d.ts.map +1 -0
  248. package/dist/plugins/sentry/SentryPlugin.types.d.ts +8 -0
  249. package/dist/plugins/sentry/SentryPlugin.types.d.ts.map +1 -0
  250. package/dist/plugins/sentry/index.d.ts +3 -0
  251. package/dist/plugins/sentry/index.d.ts.map +1 -0
  252. package/dist/plugins/service/ServiceAdapter.d.ts +88 -0
  253. package/dist/plugins/service/ServiceAdapter.d.ts.map +1 -0
  254. package/dist/plugins/service/ServiceEventHelper.d.ts +6 -0
  255. package/dist/plugins/service/ServiceEventHelper.d.ts.map +1 -0
  256. package/dist/plugins/service/ServicePlugin.d.ts +135 -0
  257. package/dist/plugins/service/ServicePlugin.d.ts.map +1 -0
  258. package/dist/plugins/service/ServicePlugin.types.d.ts +14 -0
  259. package/dist/plugins/service/ServicePlugin.types.d.ts.map +1 -0
  260. package/dist/plugins/service/adapters/DevAuthAdapter.d.ts +56 -0
  261. package/dist/plugins/service/adapters/DevAuthAdapter.d.ts.map +1 -0
  262. package/dist/plugins/service/adapters/RGSAdapter.d.ts +82 -0
  263. package/dist/plugins/service/adapters/RGSAdapter.d.ts.map +1 -0
  264. package/dist/plugins/service/adapters/index.d.ts +7 -0
  265. package/dist/plugins/service/adapters/index.d.ts.map +1 -0
  266. package/dist/plugins/service/adapters/resolvePublicIp.d.ts +10 -0
  267. package/dist/plugins/service/adapters/resolvePublicIp.d.ts.map +1 -0
  268. package/dist/plugins/service/index.d.ts +10 -0
  269. package/dist/plugins/service/index.d.ts.map +1 -0
  270. package/dist/plugins/service/types/api.types.d.ts +299 -0
  271. package/dist/plugins/service/types/api.types.d.ts.map +1 -0
  272. package/dist/plugins/service/types/index.d.ts +6 -0
  273. package/dist/plugins/service/types/index.d.ts.map +1 -0
  274. package/dist/plugins/skin/ISkin.d.ts +62 -0
  275. package/dist/plugins/skin/ISkin.d.ts.map +1 -0
  276. package/dist/plugins/skin/Skin.d.ts +155 -0
  277. package/dist/plugins/skin/Skin.d.ts.map +1 -0
  278. package/dist/plugins/skin/SkinPlugin.d.ts +285 -0
  279. package/dist/plugins/skin/SkinPlugin.d.ts.map +1 -0
  280. package/dist/plugins/skin/SkinPlugin.types.d.ts +56 -0
  281. package/dist/plugins/skin/SkinPlugin.types.d.ts.map +1 -0
  282. package/dist/plugins/skin/index.d.ts +5 -0
  283. package/dist/plugins/skin/index.d.ts.map +1 -0
  284. package/dist/plugins/sound/SoundPlugin.d.ts +319 -0
  285. package/dist/plugins/sound/SoundPlugin.d.ts.map +1 -0
  286. package/dist/plugins/sound/SoundPlugin.types.d.ts +102 -0
  287. package/dist/plugins/sound/SoundPlugin.types.d.ts.map +1 -0
  288. package/dist/plugins/sound/SoundTestGUI.d.ts +42 -0
  289. package/dist/plugins/sound/SoundTestGUI.d.ts.map +1 -0
  290. package/dist/plugins/sound/index.d.ts +4 -0
  291. package/dist/plugins/sound/index.d.ts.map +1 -0
  292. package/dist/state-machine/ConfigBuilder.d.ts +239 -0
  293. package/dist/state-machine/ConfigBuilder.d.ts.map +1 -0
  294. package/dist/state-machine/StateMachine.d.ts +251 -0
  295. package/dist/state-machine/StateMachine.d.ts.map +1 -0
  296. package/dist/state-machine/guards.d.ts +151 -0
  297. package/dist/state-machine/guards.d.ts.map +1 -0
  298. package/dist/state-machine/index.d.ts +5 -0
  299. package/dist/state-machine/index.d.ts.map +1 -0
  300. package/dist/state-machine/index.js +954 -0
  301. package/dist/state-machine/index.js.map +1 -0
  302. package/dist/state-machine/types.d.ts +65 -0
  303. package/dist/state-machine/types.d.ts.map +1 -0
  304. package/dist/store/DataStore.d.ts +167 -0
  305. package/dist/store/DataStore.d.ts.map +1 -0
  306. package/dist/store/index.d.ts +3 -0
  307. package/dist/store/index.d.ts.map +1 -0
  308. package/dist/store/index.js +197 -0
  309. package/dist/store/index.js.map +1 -0
  310. package/dist/ui/behaviors/ButtonBehavior.d.ts +245 -0
  311. package/dist/ui/behaviors/ButtonBehavior.d.ts.map +1 -0
  312. package/dist/ui/behaviors/InputBehavior.d.ts +169 -0
  313. package/dist/ui/behaviors/InputBehavior.d.ts.map +1 -0
  314. package/dist/ui/behaviors/ScrollbarBehavior.d.ts +371 -0
  315. package/dist/ui/behaviors/ScrollbarBehavior.d.ts.map +1 -0
  316. package/dist/ui/behaviors/index.d.ts +4 -0
  317. package/dist/ui/behaviors/index.d.ts.map +1 -0
  318. package/dist/ui/components/ButtonComp.d.ts +138 -0
  319. package/dist/ui/components/ButtonComp.d.ts.map +1 -0
  320. package/dist/ui/components/Comp.utils.d.ts +390 -0
  321. package/dist/ui/components/Comp.utils.d.ts.map +1 -0
  322. package/dist/ui/components/Component.types.d.ts +41 -0
  323. package/dist/ui/components/Component.types.d.ts.map +1 -0
  324. package/dist/ui/components/InputComp.d.ts +43 -0
  325. package/dist/ui/components/InputComp.d.ts.map +1 -0
  326. package/dist/ui/components/LabelBox.d.ts +49 -0
  327. package/dist/ui/components/LabelBox.d.ts.map +1 -0
  328. package/dist/ui/components/ListTableComp.d.ts +106 -0
  329. package/dist/ui/components/ListTableComp.d.ts.map +1 -0
  330. package/dist/ui/components/Skinable.d.ts +261 -0
  331. package/dist/ui/components/Skinable.d.ts.map +1 -0
  332. package/dist/ui/components/SliderComp.d.ts +60 -0
  333. package/dist/ui/components/SliderComp.d.ts.map +1 -0
  334. package/dist/ui/components/SpriteTextBBCode.d.ts +16 -0
  335. package/dist/ui/components/SpriteTextBBCode.d.ts.map +1 -0
  336. package/dist/ui/components/StepperComp.d.ts +89 -0
  337. package/dist/ui/components/StepperComp.d.ts.map +1 -0
  338. package/dist/ui/components/index.d.ts +12 -0
  339. package/dist/ui/components/index.d.ts.map +1 -0
  340. package/dist/ui/components/spriteText/SpriteText.d.ts +114 -0
  341. package/dist/ui/components/spriteText/SpriteText.d.ts.map +1 -0
  342. package/dist/ui/components/spriteText/SpriteText.types.d.ts +109 -0
  343. package/dist/ui/components/spriteText/SpriteText.types.d.ts.map +1 -0
  344. package/dist/ui/components/spriteText/SpriteTextAlignment.d.ts +25 -0
  345. package/dist/ui/components/spriteText/SpriteTextAlignment.d.ts.map +1 -0
  346. package/dist/ui/components/spriteText/SpriteTextBezier.d.ts +20 -0
  347. package/dist/ui/components/spriteText/SpriteTextBezier.d.ts.map +1 -0
  348. package/dist/ui/components/spriteText/SpriteTextCurve.d.ts +4 -0
  349. package/dist/ui/components/spriteText/SpriteTextCurve.d.ts.map +1 -0
  350. package/dist/ui/components/spriteText/SpriteTextKerning.d.ts +7 -0
  351. package/dist/ui/components/spriteText/SpriteTextKerning.d.ts.map +1 -0
  352. package/dist/ui/components/spriteText/SpriteTextTexture.d.ts +16 -0
  353. package/dist/ui/components/spriteText/SpriteTextTexture.d.ts.map +1 -0
  354. package/dist/ui/components/spriteText/SpriteTextWrap.d.ts +19 -0
  355. package/dist/ui/components/spriteText/SpriteTextWrap.d.ts.map +1 -0
  356. package/dist/ui/components/spriteText/index.d.ts +3 -0
  357. package/dist/ui/components/spriteText/index.d.ts.map +1 -0
  358. package/dist/ui/index.d.ts +3 -0
  359. package/dist/ui/index.d.ts.map +1 -0
  360. package/dist/ui/index.js +4778 -0
  361. package/dist/ui/index.js.map +1 -0
  362. package/dist/utils/ArrayUtils.d.ts +24 -0
  363. package/dist/utils/ArrayUtils.d.ts.map +1 -0
  364. package/dist/utils/ColorUtils.d.ts +34 -0
  365. package/dist/utils/ColorUtils.d.ts.map +1 -0
  366. package/dist/utils/DataInjector.d.ts +67 -0
  367. package/dist/utils/DataInjector.d.ts.map +1 -0
  368. package/dist/utils/Logger.d.ts +332 -0
  369. package/dist/utils/Logger.d.ts.map +1 -0
  370. package/dist/utils/NumberFormatter.d.ts +126 -0
  371. package/dist/utils/NumberFormatter.d.ts.map +1 -0
  372. package/dist/utils/ObjectUtils.d.ts +64 -0
  373. package/dist/utils/ObjectUtils.d.ts.map +1 -0
  374. package/dist/utils/PixiUtils.d.ts +118 -0
  375. package/dist/utils/PixiUtils.d.ts.map +1 -0
  376. package/dist/utils/Throttle.d.ts +103 -0
  377. package/dist/utils/Throttle.d.ts.map +1 -0
  378. package/dist/utils/index.d.ts +9 -0
  379. package/dist/utils/index.d.ts.map +1 -0
  380. package/dist/utils/index.js +899 -0
  381. package/dist/utils/index.js.map +1 -0
  382. package/dist/vite/index.d.ts +3 -0
  383. package/dist/vite/index.d.ts.map +1 -0
  384. package/dist/vite/index.js +126 -0
  385. package/dist/vite/index.js.map +1 -0
  386. package/dist/vite/mergeLocalesPlugin.d.ts +22 -0
  387. package/dist/vite/mergeLocalesPlugin.d.ts.map +1 -0
  388. package/package.json +143 -0
@@ -0,0 +1,4778 @@
1
+ import { Rectangle, Color, Texture, Sprite, Graphics, Container, Text, ColorMatrixFilter, Assets, Point } from 'pixi.js';
2
+ import { merge } from 'lodash';
3
+
4
+ var __create = Object.create;
5
+ var __defProp = Object.defineProperty;
6
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
7
+ var __getOwnPropNames = Object.getOwnPropertyNames;
8
+ var __getProtoOf = Object.getPrototypeOf;
9
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
10
+ var __commonJS = (cb, mod) => function __require() {
11
+ return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
12
+ };
13
+ var __copyProps = (to, from, except, desc) => {
14
+ if (from && typeof from === "object" || typeof from === "function") {
15
+ for (let key of __getOwnPropNames(from))
16
+ if (!__hasOwnProp.call(to, key) && key !== except)
17
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
18
+ }
19
+ return to;
20
+ };
21
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
22
+ // If the importer is in node compatibility mode or this is not an ESM
23
+ // file that has been converted to a CommonJS file using a Babel-
24
+ // compatible transform (i.e. "__esModule" has not been set), then set
25
+ // "default" to the CommonJS "module.exports" for node compatibility.
26
+ __defProp(target, "default", { value: mod, enumerable: true }) ,
27
+ mod
28
+ ));
29
+
30
+ // ../../node_modules/eventemitter3/index.js
31
+ var require_eventemitter3 = __commonJS({
32
+ "../../node_modules/eventemitter3/index.js"(exports, module) {
33
+ var has = Object.prototype.hasOwnProperty;
34
+ var prefix = "~";
35
+ function Events() {
36
+ }
37
+ if (Object.create) {
38
+ Events.prototype = /* @__PURE__ */ Object.create(null);
39
+ if (!new Events().__proto__) prefix = false;
40
+ }
41
+ function EE(fn, context, once) {
42
+ this.fn = fn;
43
+ this.context = context;
44
+ this.once = once || false;
45
+ }
46
+ function addListener(emitter, event, fn, context, once) {
47
+ if (typeof fn !== "function") {
48
+ throw new TypeError("The listener must be a function");
49
+ }
50
+ var listener = new EE(fn, context || emitter, once), evt = prefix ? prefix + event : event;
51
+ if (!emitter._events[evt]) emitter._events[evt] = listener, emitter._eventsCount++;
52
+ else if (!emitter._events[evt].fn) emitter._events[evt].push(listener);
53
+ else emitter._events[evt] = [emitter._events[evt], listener];
54
+ return emitter;
55
+ }
56
+ function clearEvent(emitter, evt) {
57
+ if (--emitter._eventsCount === 0) emitter._events = new Events();
58
+ else delete emitter._events[evt];
59
+ }
60
+ function EventEmitter2() {
61
+ this._events = new Events();
62
+ this._eventsCount = 0;
63
+ }
64
+ EventEmitter2.prototype.eventNames = function eventNames() {
65
+ var names = [], events, name;
66
+ if (this._eventsCount === 0) return names;
67
+ for (name in events = this._events) {
68
+ if (has.call(events, name)) names.push(prefix ? name.slice(1) : name);
69
+ }
70
+ if (Object.getOwnPropertySymbols) {
71
+ return names.concat(Object.getOwnPropertySymbols(events));
72
+ }
73
+ return names;
74
+ };
75
+ EventEmitter2.prototype.listeners = function listeners(event) {
76
+ var evt = prefix ? prefix + event : event, handlers = this._events[evt];
77
+ if (!handlers) return [];
78
+ if (handlers.fn) return [handlers.fn];
79
+ for (var i = 0, l = handlers.length, ee = new Array(l); i < l; i++) {
80
+ ee[i] = handlers[i].fn;
81
+ }
82
+ return ee;
83
+ };
84
+ EventEmitter2.prototype.listenerCount = function listenerCount(event) {
85
+ var evt = prefix ? prefix + event : event, listeners = this._events[evt];
86
+ if (!listeners) return 0;
87
+ if (listeners.fn) return 1;
88
+ return listeners.length;
89
+ };
90
+ EventEmitter2.prototype.emit = function emit(event, a1, a2, a3, a4, a5) {
91
+ var evt = prefix ? prefix + event : event;
92
+ if (!this._events[evt]) return false;
93
+ var listeners = this._events[evt], len = arguments.length, args, i;
94
+ if (listeners.fn) {
95
+ if (listeners.once) this.removeListener(event, listeners.fn, void 0, true);
96
+ switch (len) {
97
+ case 1:
98
+ return listeners.fn.call(listeners.context), true;
99
+ case 2:
100
+ return listeners.fn.call(listeners.context, a1), true;
101
+ case 3:
102
+ return listeners.fn.call(listeners.context, a1, a2), true;
103
+ case 4:
104
+ return listeners.fn.call(listeners.context, a1, a2, a3), true;
105
+ case 5:
106
+ return listeners.fn.call(listeners.context, a1, a2, a3, a4), true;
107
+ case 6:
108
+ return listeners.fn.call(listeners.context, a1, a2, a3, a4, a5), true;
109
+ }
110
+ for (i = 1, args = new Array(len - 1); i < len; i++) {
111
+ args[i - 1] = arguments[i];
112
+ }
113
+ listeners.fn.apply(listeners.context, args);
114
+ } else {
115
+ var length = listeners.length, j;
116
+ for (i = 0; i < length; i++) {
117
+ if (listeners[i].once) this.removeListener(event, listeners[i].fn, void 0, true);
118
+ switch (len) {
119
+ case 1:
120
+ listeners[i].fn.call(listeners[i].context);
121
+ break;
122
+ case 2:
123
+ listeners[i].fn.call(listeners[i].context, a1);
124
+ break;
125
+ case 3:
126
+ listeners[i].fn.call(listeners[i].context, a1, a2);
127
+ break;
128
+ case 4:
129
+ listeners[i].fn.call(listeners[i].context, a1, a2, a3);
130
+ break;
131
+ default:
132
+ if (!args) for (j = 1, args = new Array(len - 1); j < len; j++) {
133
+ args[j - 1] = arguments[j];
134
+ }
135
+ listeners[i].fn.apply(listeners[i].context, args);
136
+ }
137
+ }
138
+ }
139
+ return true;
140
+ };
141
+ EventEmitter2.prototype.on = function on(event, fn, context) {
142
+ return addListener(this, event, fn, context, false);
143
+ };
144
+ EventEmitter2.prototype.once = function once(event, fn, context) {
145
+ return addListener(this, event, fn, context, true);
146
+ };
147
+ EventEmitter2.prototype.removeListener = function removeListener(event, fn, context, once) {
148
+ var evt = prefix ? prefix + event : event;
149
+ if (!this._events[evt]) return this;
150
+ if (!fn) {
151
+ clearEvent(this, evt);
152
+ return this;
153
+ }
154
+ var listeners = this._events[evt];
155
+ if (listeners.fn) {
156
+ if (listeners.fn === fn && (!once || listeners.once) && (!context || listeners.context === context)) {
157
+ clearEvent(this, evt);
158
+ }
159
+ } else {
160
+ for (var i = 0, events = [], length = listeners.length; i < length; i++) {
161
+ if (listeners[i].fn !== fn || once && !listeners[i].once || context && listeners[i].context !== context) {
162
+ events.push(listeners[i]);
163
+ }
164
+ }
165
+ if (events.length) this._events[evt] = events.length === 1 ? events[0] : events;
166
+ else clearEvent(this, evt);
167
+ }
168
+ return this;
169
+ };
170
+ EventEmitter2.prototype.removeAllListeners = function removeAllListeners(event) {
171
+ var evt;
172
+ if (event) {
173
+ evt = prefix ? prefix + event : event;
174
+ if (this._events[evt]) clearEvent(this, evt);
175
+ } else {
176
+ this._events = new Events();
177
+ this._eventsCount = 0;
178
+ }
179
+ return this;
180
+ };
181
+ EventEmitter2.prototype.off = EventEmitter2.prototype.removeListener;
182
+ EventEmitter2.prototype.addListener = EventEmitter2.prototype.on;
183
+ EventEmitter2.prefixed = prefix;
184
+ EventEmitter2.EventEmitter = EventEmitter2;
185
+ if ("undefined" !== typeof module) {
186
+ module.exports = EventEmitter2;
187
+ }
188
+ }
189
+ });
190
+
191
+ // ../../node_modules/eventemitter3/index.mjs
192
+ var import_index = __toESM(require_eventemitter3());
193
+
194
+ // ui/behaviors/ButtonBehavior.ts
195
+ var ButtonBehavior = class _ButtonBehavior extends import_index.default {
196
+ _view = null;
197
+ _enabled = true;
198
+ _isPressed = false;
199
+ _isHolding = false;
200
+ _pointerDownOnThis = false;
201
+ _isOver = false;
202
+ // 👈 isOver added
203
+ _holdTimer = null;
204
+ _holdInterval = null;
205
+ _holdDelay;
206
+ _holdIntervalTime;
207
+ _cursor = "pointer";
208
+ // Toggle properties
209
+ _isToggle = false;
210
+ _selected = false;
211
+ _allowHoldWhenToggle = false;
212
+ _holdMode;
213
+ // Track if events are bound to current view
214
+ _eventsBound = false;
215
+ // Static factory methods
216
+ static withView(view, options = {}) {
217
+ const button = new _ButtonBehavior(options);
218
+ button.attachView(view);
219
+ return button;
220
+ }
221
+ // Method overloads - now only takes options
222
+ constructor(options = {}) {
223
+ super();
224
+ this._holdDelay = options.holdDelay || 500;
225
+ this._holdIntervalTime = options.holdInterval || 100;
226
+ this._holdMode = options.holdMode ?? "none";
227
+ this._cursor = options.cursor || "pointer";
228
+ this._isToggle = options.isToggle || false;
229
+ this._selected = options.selected || false;
230
+ this._allowHoldWhenToggle = options.allowHoldWhenToggle || false;
231
+ if (options.view) {
232
+ this.attachView(options.view);
233
+ }
234
+ }
235
+ // View Management Methods
236
+ attachView(view) {
237
+ if (this._view === view) return;
238
+ if (this._view) {
239
+ this.detachView();
240
+ }
241
+ this._view = view;
242
+ this._setupInteractivity();
243
+ this._bindEvents();
244
+ this._setupDestroyListener();
245
+ this._eventsBound = true;
246
+ this.emit("viewAttached", view);
247
+ this._emitStateChange();
248
+ }
249
+ detachView() {
250
+ if (!this._view) return;
251
+ const oldView = this._view;
252
+ this._unbindEvents();
253
+ this._view = null;
254
+ this._eventsBound = false;
255
+ this._stopHoldTimer();
256
+ this._isPressed = false;
257
+ this._isHolding = false;
258
+ this._pointerDownOnThis = false;
259
+ this._isOver = false;
260
+ this.emit("viewDetached", oldView);
261
+ }
262
+ get view() {
263
+ return this._view;
264
+ }
265
+ get hasView() {
266
+ return this._view !== null;
267
+ }
268
+ _setupInteractivity() {
269
+ if (!this._view) return;
270
+ this._view.eventMode = "static";
271
+ this._view.cursor = this._cursor;
272
+ }
273
+ _bindEvents() {
274
+ if (!this._view) return;
275
+ this._view.on("pointerdown", this._onPointerDown.bind(this));
276
+ this._view.on("pointerup", this._onPointerUp.bind(this));
277
+ this._view.on("pointerupoutside", this._onPointerUp.bind(this));
278
+ this._view.on("pointerover", this._onPointerOver.bind(this));
279
+ this._view.on("pointerout", this._onPointerOut.bind(this));
280
+ this._view.on("wheel", this._onWheel.bind(this));
281
+ }
282
+ _unbindEvents() {
283
+ if (!this._view || !this._eventsBound) return;
284
+ this._view.off("pointerdown", this._onPointerDown.bind(this));
285
+ this._view.off("pointerup", this._onPointerUp.bind(this));
286
+ this._view.off("pointerupoutside", this._onPointerUp.bind(this));
287
+ this._view.off("pointerover", this._onPointerOver.bind(this));
288
+ this._view.off("pointerout", this._onPointerOut.bind(this));
289
+ this._view.off("wheel", this._onWheel.bind(this));
290
+ this._view.off("destroyed", this._onViewDestroyed.bind(this));
291
+ }
292
+ _setupDestroyListener() {
293
+ if (!this._view) return;
294
+ this._view.on("destroyed", this._onViewDestroyed.bind(this));
295
+ }
296
+ _emitStateChange() {
297
+ const state = {
298
+ enabled: this._enabled,
299
+ pressed: this._isPressed,
300
+ holding: this._isHolding,
301
+ selected: this._selected,
302
+ cursor: this._cursor,
303
+ over: this._isOver,
304
+ state: this._calculateStateString()
305
+ // type-safe
306
+ };
307
+ this.emit("stateChanged", state);
308
+ }
309
+ _onViewDestroyed() {
310
+ this._stopHoldTimer();
311
+ this._isPressed = false;
312
+ this._isHolding = false;
313
+ this._pointerDownOnThis = false;
314
+ this._isOver = false;
315
+ this.removeAllListeners();
316
+ }
317
+ _onPointerDown(event) {
318
+ if (!this._enabled || !this._view) return;
319
+ this._isPressed = true;
320
+ this._pointerDownOnThis = true;
321
+ if (this._holdMode !== "none" && (!this._isToggle || this._allowHoldWhenToggle)) {
322
+ this._startHoldTimer();
323
+ }
324
+ this.emit("down", event);
325
+ this._emitStateChange();
326
+ }
327
+ _onPointerUp(event) {
328
+ if (!this._enabled || !this._view) return;
329
+ if (!this._pointerDownOnThis) {
330
+ return;
331
+ }
332
+ this._isPressed = false;
333
+ this._pointerDownOnThis = false;
334
+ this._stopHoldTimer();
335
+ this.emit("up", event);
336
+ if (this._isHolding) {
337
+ this._isHolding = false;
338
+ this.emit("holdEnd");
339
+ if (this._holdMode === "clickThrough") {
340
+ if (this._isToggle) {
341
+ this._handleToggle();
342
+ } else {
343
+ this.emit("click");
344
+ }
345
+ }
346
+ } else if (this._enabled) {
347
+ if (this._isToggle) {
348
+ this._handleToggle();
349
+ } else {
350
+ this.emit("click");
351
+ }
352
+ }
353
+ this._emitStateChange();
354
+ }
355
+ _handleToggle() {
356
+ this._selected = !this._selected;
357
+ this.emit("toggle", this._selected);
358
+ if (this._selected) {
359
+ this.emit("select");
360
+ } else {
361
+ this.emit("deselect");
362
+ }
363
+ this.emit("click");
364
+ }
365
+ _onPointerOver(event) {
366
+ if (!this._enabled || !this._view) return;
367
+ this._isOver = true;
368
+ this.emit("over", event);
369
+ this._emitStateChange();
370
+ }
371
+ _onPointerOut(event) {
372
+ if (!this._enabled || !this._view) return;
373
+ this._isOver = false;
374
+ this.emit("out", event);
375
+ this._emitStateChange();
376
+ }
377
+ _onWheel(event) {
378
+ if (!this._enabled || !this._view) return;
379
+ this.emit("wheel", event);
380
+ }
381
+ _startHoldTimer() {
382
+ this._stopHoldTimer();
383
+ this._holdTimer = setTimeout(() => {
384
+ if (this._isPressed && this._enabled) {
385
+ this._isHolding = true;
386
+ this.emit("holdStart");
387
+ this.emit("hold");
388
+ this._holdInterval = setInterval(() => {
389
+ if (this._isHolding && this._enabled) {
390
+ this.emit("hold");
391
+ }
392
+ }, this._holdIntervalTime);
393
+ }
394
+ }, this._holdDelay);
395
+ }
396
+ _stopHoldTimer() {
397
+ if (this._holdTimer) {
398
+ clearTimeout(this._holdTimer);
399
+ this._holdTimer = null;
400
+ }
401
+ if (this._holdInterval) {
402
+ clearInterval(this._holdInterval);
403
+ this._holdInterval = null;
404
+ }
405
+ }
406
+ // Properties
407
+ get holdMode() {
408
+ return this._holdMode;
409
+ }
410
+ set holdMode(value) {
411
+ this._holdMode = value;
412
+ }
413
+ get isEnabled() {
414
+ return this._enabled;
415
+ }
416
+ set isEnabled(value) {
417
+ this._enabled = value;
418
+ if (this._view) {
419
+ this._view.eventMode = value ? "static" : "none";
420
+ this._view.cursor = value ? this._cursor : "default";
421
+ }
422
+ if (!value) {
423
+ this._stopHoldTimer();
424
+ this._isPressed = false;
425
+ this._isHolding = false;
426
+ this._pointerDownOnThis = false;
427
+ this._isOver = false;
428
+ }
429
+ this._emitStateChange();
430
+ }
431
+ get isPressed() {
432
+ return this._isPressed;
433
+ }
434
+ get isHolding() {
435
+ return this._isHolding;
436
+ }
437
+ // Toggle properties
438
+ get isToggle() {
439
+ return this._isToggle;
440
+ }
441
+ set isToggle(value) {
442
+ this._isToggle = value;
443
+ if (!value) {
444
+ this._selected = false;
445
+ }
446
+ }
447
+ get isSelected() {
448
+ return this._selected;
449
+ }
450
+ set isSelected(value) {
451
+ if (this._selected !== value) {
452
+ this._selected = value;
453
+ this.emit("toggle", this._selected);
454
+ if (this._selected) {
455
+ this.emit("select");
456
+ } else {
457
+ this.emit("deselect");
458
+ }
459
+ this._emitStateChange();
460
+ }
461
+ }
462
+ get allowHoldWhenToggle() {
463
+ return this._allowHoldWhenToggle;
464
+ }
465
+ set allowHoldWhenToggle(value) {
466
+ this._allowHoldWhenToggle = value;
467
+ }
468
+ // Hold timing properties
469
+ get holdDelay() {
470
+ return this._holdDelay;
471
+ }
472
+ set holdDelay(value) {
473
+ this._holdDelay = value;
474
+ }
475
+ get holdInterval() {
476
+ return this._holdIntervalTime;
477
+ }
478
+ set holdInterval(value) {
479
+ this._holdIntervalTime = value;
480
+ }
481
+ // Cursor property
482
+ get cursor() {
483
+ return this._cursor;
484
+ }
485
+ set cursor(value) {
486
+ this._cursor = value;
487
+ if (this._view && this._enabled) {
488
+ this._view.cursor = value;
489
+ }
490
+ this._emitStateChange();
491
+ }
492
+ // Toggle methods
493
+ toggle() {
494
+ if (this._isToggle) {
495
+ this.isSelected = !this._selected;
496
+ }
497
+ }
498
+ select() {
499
+ if (this._isToggle) {
500
+ this.isSelected = true;
501
+ }
502
+ }
503
+ deselect() {
504
+ if (this._isToggle) {
505
+ this.isSelected = false;
506
+ }
507
+ }
508
+ /**
509
+ * Programmatically simulates a pointer down on this button.
510
+ * Triggers press state, hold timer, and visual feedback — same as a real pointer down.
511
+ * Does NOT emit the `down` event (which requires a FederatedPointerEvent).
512
+ * Use together with `simulateUp()` for full keyboard/gamepad/test bindings.
513
+ */
514
+ simulateDown() {
515
+ if (!this._enabled) return;
516
+ this._isPressed = true;
517
+ this._pointerDownOnThis = true;
518
+ if (this._holdMode !== "none" && (!this._isToggle || this._allowHoldWhenToggle)) {
519
+ this._startHoldTimer();
520
+ }
521
+ this._emitStateChange();
522
+ }
523
+ /**
524
+ * Programmatically simulates a pointer up on this button.
525
+ * Triggers click (or holdEnd/toggle) and visual feedback — same as a real pointer up.
526
+ * Does NOT emit the `up` event (which requires a FederatedPointerEvent).
527
+ * Use together with `simulateDown()` for full keyboard/gamepad/test bindings.
528
+ */
529
+ simulateUp() {
530
+ if (!this._enabled) return;
531
+ if (!this._pointerDownOnThis) return;
532
+ this._isPressed = false;
533
+ this._pointerDownOnThis = false;
534
+ this._stopHoldTimer();
535
+ if (this._isHolding) {
536
+ this._isHolding = false;
537
+ this.emit("holdEnd");
538
+ if (this._holdMode === "clickThrough") {
539
+ if (this._isToggle) {
540
+ this._handleToggle();
541
+ } else {
542
+ this.emit("click");
543
+ }
544
+ }
545
+ } else if (this._enabled) {
546
+ if (this._isToggle) {
547
+ this._handleToggle();
548
+ } else {
549
+ this.emit("click");
550
+ }
551
+ }
552
+ this._emitStateChange();
553
+ }
554
+ destroy() {
555
+ this._stopHoldTimer();
556
+ if (this._view) {
557
+ this._unbindEvents();
558
+ }
559
+ this._view = null;
560
+ this._eventsBound = false;
561
+ this.removeAllListeners();
562
+ }
563
+ _calculateStateString() {
564
+ if (!this._enabled) {
565
+ if (this._isToggle && this._selected) return "selected_disabled";
566
+ return "disabled";
567
+ }
568
+ if (this._isToggle && this._selected) {
569
+ if (this._isPressed) return "selected_down";
570
+ if (this._isOver) return "selected_over";
571
+ return "selected_up";
572
+ }
573
+ if (this._isPressed) return "down";
574
+ if (this._isOver) return "over";
575
+ return "up";
576
+ }
577
+ };
578
+ var ScrollbarBehavior = class _ScrollbarBehavior extends import_index.default {
579
+ _trackView = null;
580
+ _knobView = null;
581
+ _enabled = true;
582
+ _isDragging = false;
583
+ _dragStartPosition = 0;
584
+ _dragStartValue = 0;
585
+ _dragOffset = 0;
586
+ // Configuration
587
+ _orientation;
588
+ _min;
589
+ _max;
590
+ _value;
591
+ _step;
592
+ _margin;
593
+ // Wheel options
594
+ _wheelStep;
595
+ _enableWheel;
596
+ // Cursor options
597
+ _trackCursor;
598
+ _knobCursor;
599
+ // Track if events are bound
600
+ _eventsBound = false;
601
+ // Arrow function event handlers for proper cleanup
602
+ _onTrackPointerDown = (event) => this._handleTrackPointerDown(event);
603
+ _onKnobPointerDown = (event) => this._handleKnobPointerDown(event);
604
+ _onKnobPointerUp = (event) => this._handleKnobPointerUp(event);
605
+ _onKnobPointerUpOutside = (event) => this._handleKnobPointerUp(event);
606
+ _onGlobalPointerMove = (event) => this._handleGlobalPointerMove(event);
607
+ _onTrackWheel = (event) => this._handleWheel(event);
608
+ _onKnobWheel = (event) => this._handleWheel(event);
609
+ // Static factory methods
610
+ static withViews(trackView, knobView, options = {}) {
611
+ const scrollbar = new _ScrollbarBehavior(options);
612
+ scrollbar.attachViews(trackView, knobView);
613
+ return scrollbar;
614
+ }
615
+ constructor(options = {}) {
616
+ var _a, _b;
617
+ super();
618
+ this._orientation = options.orientation || "horizontal";
619
+ this._margin = {
620
+ start: ((_a = options.margin) == null ? void 0 : _a.start) || 0,
621
+ end: ((_b = options.margin) == null ? void 0 : _b.end) || 0
622
+ };
623
+ this._min = options.min || 0;
624
+ this._max = options.max || 100;
625
+ this._value = options.value || 0;
626
+ this._step = options.step || 1;
627
+ this._wheelStep = options.wheelStep || this._step;
628
+ this._enableWheel = options.enableWheel !== false;
629
+ this._trackCursor = options.trackCursor || "pointer";
630
+ this._knobCursor = options.knobCursor || "grab";
631
+ }
632
+ // View Management Methods
633
+ attachTrackView(trackView) {
634
+ if (this._trackView === trackView) return;
635
+ if (this._trackView) {
636
+ this._unbindTrackEvents();
637
+ }
638
+ this._trackView = trackView;
639
+ this._setupTrackInteractivity();
640
+ this._bindTrackEvents();
641
+ this._updateEventsBoundState();
642
+ this._emitStateChange();
643
+ }
644
+ attachKnobView(knobView) {
645
+ if (this._knobView === knobView) return;
646
+ if (this._knobView) {
647
+ this._unbindKnobEvents();
648
+ }
649
+ this._knobView = knobView;
650
+ this._setupKnobInteractivity();
651
+ this._bindKnobEvents();
652
+ if (this.hasViews) {
653
+ this._updateKnobPosition();
654
+ }
655
+ this._updateEventsBoundState();
656
+ this._emitStateChange();
657
+ }
658
+ attachViews(trackView, knobView) {
659
+ if (this._trackView === trackView && this._knobView === knobView) return;
660
+ const hadViews = this.hasViews;
661
+ const trackChanged = this._trackView !== trackView;
662
+ const knobChanged = this._knobView !== knobView;
663
+ if (trackChanged) {
664
+ this.attachTrackView(trackView);
665
+ }
666
+ if (knobChanged) {
667
+ this.attachKnobView(knobView);
668
+ }
669
+ if (this.hasViews && (trackChanged || knobChanged)) {
670
+ this.emit("viewAttached", trackView, knobView);
671
+ if (!hadViews) {
672
+ this._emitStateChange();
673
+ }
674
+ }
675
+ }
676
+ detachViews() {
677
+ if (!this.hasViews) return;
678
+ const oldTrackView = this._trackView;
679
+ const oldKnobView = this._knobView;
680
+ this._unbindAllEvents();
681
+ this._trackView = null;
682
+ this._knobView = null;
683
+ this._eventsBound = false;
684
+ this._isDragging = false;
685
+ if (oldKnobView && oldTrackView) {
686
+ this.emit("viewDetached", oldTrackView, oldKnobView);
687
+ }
688
+ this._emitStateChange();
689
+ }
690
+ get trackView() {
691
+ return this._trackView;
692
+ }
693
+ get knobView() {
694
+ return this._knobView;
695
+ }
696
+ get hasViews() {
697
+ return this._trackView !== null && this._knobView !== null;
698
+ }
699
+ _setupTrackInteractivity() {
700
+ if (!this._trackView) return;
701
+ this._trackView.eventMode = "static";
702
+ this._trackView.cursor = this._trackCursor;
703
+ const trackSize = this._getTrackSize();
704
+ const trackThickness = this._getTrackThickness();
705
+ if (this._orientation === "horizontal") {
706
+ this._trackView.hitArea = new Rectangle(0, 0, trackSize, trackThickness);
707
+ } else {
708
+ this._trackView.hitArea = new Rectangle(0, 0, trackThickness, trackSize);
709
+ }
710
+ }
711
+ _setupKnobInteractivity() {
712
+ if (!this._knobView) return;
713
+ this._knobView.eventMode = "static";
714
+ this._knobView.cursor = this._knobCursor;
715
+ }
716
+ // --- Event binding section ---
717
+ _bindTrackEvents() {
718
+ if (!this._trackView) return;
719
+ this._trackView.on("pointerdown", this._onTrackPointerDown);
720
+ this._trackView.on("pointerup", (e) => this.emit("trackUp", e));
721
+ this._trackView.on("pointerover", (e) => this.emit("trackOver", e));
722
+ this._trackView.on("pointerout", (e) => this.emit("trackOut", e));
723
+ this._trackView.on("click", (e) => this.emit("trackClick", e));
724
+ if (this._enableWheel) {
725
+ this._trackView.on("wheel", this._onTrackWheel);
726
+ }
727
+ }
728
+ _unbindTrackEvents() {
729
+ if (!this._trackView) return;
730
+ this._trackView.off("pointerdown", this._onTrackPointerDown);
731
+ this._trackView.off("wheel", this._onTrackWheel);
732
+ }
733
+ _bindKnobEvents() {
734
+ if (!this._knobView) return;
735
+ this._knobView.on("pointerdown", this._onKnobPointerDown);
736
+ this._knobView.on("pointerup", this._onKnobPointerUp);
737
+ this._knobView.on("pointerupoutside", this._onKnobPointerUpOutside);
738
+ this._knobView.on("pointerover", (e) => this.emit("knobOver", e));
739
+ this._knobView.on("pointerout", (e) => this.emit("knobOut", e));
740
+ this._knobView.on("click", (e) => this.emit("knobClick", e));
741
+ this._knobView.on("pointerdown", (e) => this.emit("knobDown", e));
742
+ this._knobView.on("pointerup", (e) => this.emit("knobUp", e));
743
+ if (this._enableWheel) {
744
+ this._knobView.on("wheel", this._onKnobWheel);
745
+ }
746
+ }
747
+ _unbindKnobEvents() {
748
+ if (!this._knobView) return;
749
+ this._knobView.off("pointerdown", this._onKnobPointerDown);
750
+ this._knobView.off("pointerup", this._onKnobPointerUp);
751
+ this._knobView.off("pointerupoutside", this._onKnobPointerUpOutside);
752
+ this._knobView.off("wheel", this._onKnobWheel);
753
+ this._knobView.off("globalpointermove", this._onGlobalPointerMove);
754
+ }
755
+ _unbindAllEvents() {
756
+ this._unbindTrackEvents();
757
+ this._unbindKnobEvents();
758
+ }
759
+ _updateEventsBoundState() {
760
+ this._eventsBound = this.hasViews;
761
+ }
762
+ // Event Handlers
763
+ _handleTrackPointerDown(event) {
764
+ if (!this._enabled || !this._trackView) return;
765
+ const localPosition = event.getLocalPosition(this._trackView);
766
+ const clickPosition = this._orientation === "horizontal" ? localPosition.x : localPosition.y;
767
+ const effectiveArea = this._getEffectiveTrackArea();
768
+ const effectiveClickPosition = clickPosition - effectiveArea.start;
769
+ const percentage = Math.max(0, Math.min(1, effectiveClickPosition / effectiveArea.size));
770
+ const newValue = this._min + (this._max - this._min) * percentage;
771
+ this.emit("click", { x: localPosition.x, y: localPosition.y }, percentage);
772
+ this.value = newValue;
773
+ this.emit("scroll", this._value, this.percentage);
774
+ }
775
+ _handleKnobPointerDown(event) {
776
+ if (!this._enabled || !this._knobView || !this._trackView) return;
777
+ this._isDragging = true;
778
+ this._knobView.cursor = "grabbing";
779
+ const knobLocalPosition = event.getLocalPosition(this._knobView);
780
+ this._dragOffset = this._orientation === "horizontal" ? knobLocalPosition.x : knobLocalPosition.y;
781
+ const trackLocalPosition = event.getLocalPosition(this._trackView);
782
+ this._dragStartPosition = this._orientation === "horizontal" ? trackLocalPosition.x : trackLocalPosition.y;
783
+ this._dragStartValue = this._value;
784
+ this._knobView.on("globalpointermove", this._onGlobalPointerMove);
785
+ this.emit("scrollStart", this._value);
786
+ this._emitStateChange();
787
+ }
788
+ _handleKnobPointerUp(event) {
789
+ if (!this._isDragging || !this._knobView) return;
790
+ this._isDragging = false;
791
+ this._knobView.cursor = this._knobCursor;
792
+ this._knobView.off("globalpointermove", this._onGlobalPointerMove);
793
+ this.emit("scrollEnd", this._value);
794
+ this._emitStateChange();
795
+ }
796
+ _handleGlobalPointerMove(event) {
797
+ if (!this._isDragging || !this._enabled || !this._trackView) return;
798
+ const localPosition = event.getLocalPosition(this._trackView);
799
+ const currentPosition = this._orientation === "horizontal" ? localPosition.x : localPosition.y;
800
+ const adjustedPosition = currentPosition - this._dragOffset;
801
+ const deltaPosition = adjustedPosition - (this._dragStartPosition - this._dragOffset);
802
+ const effectiveArea = this._getEffectiveTrackArea();
803
+ const deltaValue = deltaPosition / effectiveArea.size * (this._max - this._min);
804
+ const newValue = this._dragStartValue + deltaValue;
805
+ this.value = newValue;
806
+ this.emit("scroll", this._value, this.percentage);
807
+ }
808
+ _handleWheel(event) {
809
+ if (!this._enabled) return;
810
+ event.preventDefault();
811
+ event.stopPropagation();
812
+ const delta = event.deltaY || event.wheelDelta || event.detail;
813
+ let scrollAmount = 0;
814
+ if (delta > 0) {
815
+ scrollAmount = this._wheelStep;
816
+ } else if (delta < 0) {
817
+ scrollAmount = -this._wheelStep;
818
+ }
819
+ if (scrollAmount !== 0) {
820
+ const newValue = this._value + scrollAmount;
821
+ this.value = newValue;
822
+ this.emit("scroll", this._value, this.percentage);
823
+ }
824
+ }
825
+ // Size calculation methods
826
+ _getTrackSize() {
827
+ if (!this._trackView) return 0;
828
+ return this._orientation === "horizontal" ? this._trackView.width : this._trackView.height;
829
+ }
830
+ _getTrackThickness() {
831
+ if (!this._trackView) return 0;
832
+ return this._orientation === "horizontal" ? this._trackView.height : this._trackView.width;
833
+ }
834
+ _getKnobSize() {
835
+ if (!this._knobView) return 0;
836
+ const knobBoundingBox = this._knobView.getLocalBounds();
837
+ return this._orientation === "horizontal" ? knobBoundingBox.width + knobBoundingBox.x * 2 : knobBoundingBox.height + knobBoundingBox.y * 2;
838
+ }
839
+ _getEffectiveTrackArea() {
840
+ const trackSize = this._getTrackSize();
841
+ const knobSize = this._getKnobSize();
842
+ const start = this._margin.start;
843
+ const end = trackSize - this._margin.end;
844
+ const availableSize = end - start - knobSize;
845
+ return { start, size: Math.max(0, availableSize) };
846
+ }
847
+ _updateKnobPosition() {
848
+ if (!this._knobView || !this._trackView) return;
849
+ const percentage = (this._value - this._min) / (this._max - this._min);
850
+ const effectiveArea = this._getEffectiveTrackArea();
851
+ const trackThickness = this._getTrackThickness();
852
+ if (this._orientation === "horizontal") {
853
+ const knobX = effectiveArea.start + percentage * effectiveArea.size;
854
+ this._knobView.x = knobX;
855
+ this._knobView.y = trackThickness / 2;
856
+ } else {
857
+ const knobY = effectiveArea.start + percentage * effectiveArea.size;
858
+ this._knobView.x = trackThickness / 2;
859
+ this._knobView.y = knobY;
860
+ }
861
+ }
862
+ _emitStateChange() {
863
+ const state = {
864
+ enabled: this._enabled,
865
+ dragging: this._isDragging,
866
+ value: this._value,
867
+ percentage: this.percentage,
868
+ orientation: this._orientation,
869
+ trackSize: this._getTrackSize(),
870
+ trackThickness: this._getTrackThickness(),
871
+ knobSize: this._getKnobSize()
872
+ };
873
+ this.emit("stateChanged", state);
874
+ }
875
+ // Properties
876
+ get enabled() {
877
+ return this._enabled;
878
+ }
879
+ set enabled(value) {
880
+ this._enabled = value;
881
+ if (this._trackView) {
882
+ this._trackView.eventMode = value ? "static" : "none";
883
+ }
884
+ if (this._knobView) {
885
+ this._knobView.eventMode = value ? "static" : "none";
886
+ }
887
+ if (!value && this._isDragging) {
888
+ this._isDragging = false;
889
+ if (this._knobView) {
890
+ this._knobView.cursor = this._knobCursor;
891
+ this._knobView.off("globalpointermove", this._onGlobalPointerMove);
892
+ }
893
+ this.emit("scrollEnd", this._value);
894
+ }
895
+ this._emitStateChange();
896
+ }
897
+ get isDragging() {
898
+ return this._isDragging;
899
+ }
900
+ get value() {
901
+ return this._value;
902
+ }
903
+ set value(newValue) {
904
+ const clampedValue = Math.max(this._min, Math.min(this._max, newValue));
905
+ const steppedValue = Math.round(clampedValue / this._step) * this._step;
906
+ if (this._value !== steppedValue) {
907
+ this._value = steppedValue;
908
+ this._updateKnobPosition();
909
+ this._emitStateChange();
910
+ }
911
+ }
912
+ get percentage() {
913
+ return (this._value - this._min) / (this._max - this._min);
914
+ }
915
+ get trackSize() {
916
+ return this._getTrackSize();
917
+ }
918
+ get trackThickness() {
919
+ return this._getTrackThickness();
920
+ }
921
+ get knobSize() {
922
+ return this._getKnobSize();
923
+ }
924
+ get orientation() {
925
+ return this._orientation;
926
+ }
927
+ set orientation(value) {
928
+ if (this._orientation !== value) {
929
+ this._orientation = value;
930
+ this._setupTrackInteractivity();
931
+ this._setupKnobInteractivity();
932
+ this._updateKnobPosition();
933
+ this._emitStateChange();
934
+ }
935
+ }
936
+ get margin() {
937
+ return { ...this._margin };
938
+ }
939
+ set margin(value) {
940
+ this._margin = {
941
+ start: value.start || 0,
942
+ end: value.end || 0
943
+ };
944
+ this._updateKnobPosition();
945
+ this._emitStateChange();
946
+ }
947
+ get wheelStep() {
948
+ return this._wheelStep;
949
+ }
950
+ set wheelStep(value) {
951
+ this._wheelStep = value;
952
+ }
953
+ get enableWheel() {
954
+ return this._enableWheel;
955
+ }
956
+ set enableWheel(value) {
957
+ if (this._enableWheel !== value) {
958
+ this._enableWheel = value;
959
+ if (this._trackView) {
960
+ this._trackView.off("wheel", this._onTrackWheel);
961
+ if (value) {
962
+ this._trackView.on("wheel", this._onTrackWheel);
963
+ }
964
+ }
965
+ if (this._knobView) {
966
+ this._knobView.off("wheel", this._onKnobWheel);
967
+ if (value) {
968
+ this._knobView.on("wheel", this._onKnobWheel);
969
+ }
970
+ }
971
+ }
972
+ }
973
+ get step() {
974
+ return this._step;
975
+ }
976
+ set step(value) {
977
+ this._step = value;
978
+ this.value = this._value;
979
+ }
980
+ get trackCursor() {
981
+ return this._trackCursor;
982
+ }
983
+ set trackCursor(value) {
984
+ this._trackCursor = value;
985
+ if (this._trackView && this._enabled) {
986
+ this._trackView.cursor = value;
987
+ }
988
+ }
989
+ get knobCursor() {
990
+ return this._knobCursor;
991
+ }
992
+ set knobCursor(value) {
993
+ this._knobCursor = value;
994
+ if (this._knobView && this._enabled && !this._isDragging) {
995
+ this._knobView.cursor = value;
996
+ }
997
+ }
998
+ // Min property
999
+ get min() {
1000
+ return this._min;
1001
+ }
1002
+ set min(value) {
1003
+ this._min = value;
1004
+ this.value = this._value;
1005
+ }
1006
+ // Max property
1007
+ get max() {
1008
+ return this._max;
1009
+ }
1010
+ set max(value) {
1011
+ this._max = value;
1012
+ this.value = this._value;
1013
+ }
1014
+ // Utility methods
1015
+ getTrackBounds() {
1016
+ const trackSize = this._getTrackSize();
1017
+ const trackThickness = this._getTrackThickness();
1018
+ if (this._orientation === "horizontal") {
1019
+ return { x: 0, y: 0, width: trackSize, height: trackThickness };
1020
+ } else {
1021
+ return { x: 0, y: 0, width: trackThickness, height: trackSize };
1022
+ }
1023
+ }
1024
+ getEffectiveArea() {
1025
+ const area = this._getEffectiveTrackArea();
1026
+ if (this._orientation === "horizontal") {
1027
+ return {
1028
+ x: area.start,
1029
+ y: 0,
1030
+ width: area.size,
1031
+ height: this._getTrackThickness()
1032
+ };
1033
+ } else {
1034
+ return {
1035
+ x: 0,
1036
+ y: area.start,
1037
+ width: this._getTrackThickness(),
1038
+ height: area.size
1039
+ };
1040
+ }
1041
+ }
1042
+ refreshSizes() {
1043
+ this._setupTrackInteractivity();
1044
+ this._setupKnobInteractivity();
1045
+ this._updateKnobPosition();
1046
+ this._emitStateChange();
1047
+ }
1048
+ setRange(min, max) {
1049
+ this._min = min;
1050
+ this._max = max;
1051
+ this.value = this._value;
1052
+ }
1053
+ destroy() {
1054
+ if (this._isDragging && this._knobView) {
1055
+ this._knobView.off("globalpointermove", this._onGlobalPointerMove);
1056
+ }
1057
+ this._unbindAllEvents();
1058
+ this._trackView = null;
1059
+ this._knobView = null;
1060
+ this._eventsBound = false;
1061
+ this.removeAllListeners();
1062
+ }
1063
+ };
1064
+
1065
+ // ui/behaviors/InputBehavior.ts
1066
+ var InputBehavior = class extends import_index.default {
1067
+ _domInput;
1068
+ _state;
1069
+ _options;
1070
+ _view = null;
1071
+ constructor(options = {}) {
1072
+ super();
1073
+ this._options = options;
1074
+ const guid = "input-" + Math.random().toString(36).slice(2, 11);
1075
+ if (options.multiline) {
1076
+ this._domInput = document.createElement("textarea");
1077
+ } else {
1078
+ this._domInput = document.createElement("input");
1079
+ this._domInput.type = options.type || "text";
1080
+ }
1081
+ this._domInput.id = guid;
1082
+ this._domInput.name = guid;
1083
+ this._domInput.style.position = "fixed";
1084
+ this._domInput.style.opacity = "0.000001";
1085
+ this._domInput.style.border = "none";
1086
+ this._domInput.style.outline = "none";
1087
+ this._domInput.placeholder = options.placeholder || "";
1088
+ if (options.maxLength) this._domInput.maxLength = options.maxLength;
1089
+ document.body.appendChild(this._domInput);
1090
+ this._state = {
1091
+ value: "",
1092
+ focused: false,
1093
+ enabled: options.enabled !== false,
1094
+ selection: { start: 0, end: 0 }
1095
+ };
1096
+ this._domInput.addEventListener("focus", () => {
1097
+ this._state.focused = true;
1098
+ this.emit("focus");
1099
+ this.emit("stateChanged", this._state);
1100
+ });
1101
+ this._domInput.addEventListener("blur", () => {
1102
+ this._state.focused = false;
1103
+ this.emit("blur");
1104
+ this.emit("stateChanged", this._state);
1105
+ });
1106
+ this._domInput.addEventListener("input", () => {
1107
+ let val = this._domInput.value;
1108
+ if (options.restricted) {
1109
+ val = val.replace(options.restricted, "");
1110
+ this._domInput.value = val;
1111
+ }
1112
+ if (options.mask) {
1113
+ this._domInput.value = options.mask(val);
1114
+ }
1115
+ this._state.value = val;
1116
+ this.emit("input", val);
1117
+ this.emit("stateChanged", this._state);
1118
+ });
1119
+ this._domInput.addEventListener("change", () => {
1120
+ this.emit("change", this._domInput.value);
1121
+ });
1122
+ this._domInput.addEventListener("keydown", (e) => {
1123
+ const ke = e;
1124
+ if (ke.key === "Enter") this.emit("enter");
1125
+ if (ke.key === "Escape") this.emit("esc");
1126
+ });
1127
+ }
1128
+ attachView(view) {
1129
+ if (this._view === view) return;
1130
+ if (this._view) {
1131
+ this._view.off("pointerdown", this._onViewPointerDown);
1132
+ }
1133
+ this._view = view;
1134
+ this._view.on("pointerdown", this._onViewPointerDown);
1135
+ this.updateDomPosition();
1136
+ }
1137
+ _onViewPointerDown = () => {
1138
+ this.activateView();
1139
+ };
1140
+ detachView() {
1141
+ if (this._view) {
1142
+ this._view.off("pointerdown", this._onViewPointerDown);
1143
+ }
1144
+ this._view = null;
1145
+ }
1146
+ get hasView() {
1147
+ return !!this._view;
1148
+ }
1149
+ get view() {
1150
+ return this._view;
1151
+ }
1152
+ focus() {
1153
+ this._domInput.focus();
1154
+ }
1155
+ blur() {
1156
+ this._domInput.blur();
1157
+ }
1158
+ setValue(val) {
1159
+ if (this._options.restricted) {
1160
+ val = val.replace(this._options.restricted, "");
1161
+ }
1162
+ this._domInput.value = val;
1163
+ this._state.value = val;
1164
+ this.emit("stateChanged", this._state);
1165
+ }
1166
+ get value() {
1167
+ return this._state.value;
1168
+ }
1169
+ set enabled(val) {
1170
+ this._state.enabled = val;
1171
+ this._domInput.disabled = !val;
1172
+ this.emit("stateChanged", this._state);
1173
+ }
1174
+ get enabled() {
1175
+ return this._state.enabled;
1176
+ }
1177
+ setSelection(start, end) {
1178
+ this._domInput.setSelectionRange(start, end);
1179
+ this._state.selection = { start, end };
1180
+ this.emit("stateChanged", this._state);
1181
+ }
1182
+ // Position the input according to the view coordinates
1183
+ updateDomPosition() {
1184
+ if (!this._view) return;
1185
+ const bounds = this._view.getBounds();
1186
+ this._domInput.style.left = `${bounds.x}px`;
1187
+ this._domInput.style.top = `${bounds.y}px`;
1188
+ this._domInput.style.width = `${bounds.width}px`;
1189
+ this._domInput.style.height = `${bounds.height}px`;
1190
+ }
1191
+ activateView() {
1192
+ this.updateDomPosition();
1193
+ this.focus();
1194
+ }
1195
+ destroy() {
1196
+ this._domInput.remove();
1197
+ this.removeAllListeners();
1198
+ }
1199
+ };
1200
+
1201
+ // utils/ObjectUtils.ts
1202
+ function getNestedValue(obj, path) {
1203
+ return path.split(".").reduce((current, key) => current == null ? void 0 : current[key], obj);
1204
+ }
1205
+
1206
+ // ui/components/Skinable.ts
1207
+ var SKIN = Symbol("skinData");
1208
+ function Skinable(Base) {
1209
+ class SkinableClass extends Base {
1210
+ [SKIN] = null;
1211
+ // Optional hook implementable by subclasses
1212
+ skinApply;
1213
+ setSkinData(data, opts = {}) {
1214
+ var _a, _b;
1215
+ const { mergeWithExisting = false } = opts;
1216
+ if (data === null) {
1217
+ this[SKIN] = null;
1218
+ (_a = this.skinApply) == null ? void 0 : _a.call(this, null);
1219
+ return;
1220
+ }
1221
+ const current = this[SKIN];
1222
+ if (mergeWithExisting && current) {
1223
+ this[SKIN] = merge({}, current, data);
1224
+ } else {
1225
+ this[SKIN] = merge({}, data);
1226
+ }
1227
+ (_b = this.skinApply) == null ? void 0 : _b.call(this, this[SKIN] ?? null);
1228
+ }
1229
+ getSkinData() {
1230
+ return this[SKIN];
1231
+ }
1232
+ // Subclasses should implement:
1233
+ // protected skinApply?(skin: TSkinData | null): void
1234
+ }
1235
+ return SkinableClass;
1236
+ }
1237
+ var mergeSkins = (a, b) => {
1238
+ const out = { ...a };
1239
+ for (const k of Object.keys(b)) {
1240
+ const av = a == null ? void 0 : a[k];
1241
+ const bv = b[k];
1242
+ if (av && bv && typeof av === "object" && !Array.isArray(av) && typeof bv === "object" && !Array.isArray(bv)) {
1243
+ out[k] = mergeSkins(av, bv);
1244
+ } else {
1245
+ out[k] = bv;
1246
+ }
1247
+ }
1248
+ return out;
1249
+ };
1250
+ function defineGlobalSkin() {
1251
+ let _globalSkin = null;
1252
+ function globalSkin(skin) {
1253
+ if (arguments.length === 0) return _globalSkin;
1254
+ _globalSkin = skin ?? null;
1255
+ }
1256
+ return globalSkin;
1257
+ }
1258
+ function mergeGlobalAndInstanceSkin(globalSkinGetter, instanceSkin) {
1259
+ const globalSkin = globalSkinGetter() || null;
1260
+ const effectiveSkin = instanceSkin ? globalSkin ? mergeSkins(globalSkin, instanceSkin) : instanceSkin : globalSkin;
1261
+ return effectiveSkin || null;
1262
+ }
1263
+ function applyLayoutMappings(skin, mappings) {
1264
+ mappings.forEach(({ path, target }) => {
1265
+ const value = getNestedValue(skin, path);
1266
+ if (value !== void 0) {
1267
+ target().layout = value;
1268
+ }
1269
+ });
1270
+ }
1271
+ function applyStyleMappings(skin, mappings) {
1272
+ mappings.forEach(({ path, target }) => {
1273
+ const value = getNestedValue(skin, path);
1274
+ if (value !== void 0) {
1275
+ target().style = value;
1276
+ }
1277
+ });
1278
+ }
1279
+ function applyTextMappings(skin, mappings) {
1280
+ mappings.forEach(({ path, target }) => {
1281
+ const value = getNestedValue(skin, path);
1282
+ if (value !== void 0) {
1283
+ target().text = value;
1284
+ }
1285
+ });
1286
+ }
1287
+ function applySkinMappings(skin, mappings, mergeWithExisting) {
1288
+ mappings.forEach(({ path, target }) => {
1289
+ const value = getNestedValue(skin, path);
1290
+ if (value !== void 0) {
1291
+ target().setSkinData(value, { mergeWithExisting: mergeWithExisting ?? false });
1292
+ }
1293
+ });
1294
+ }
1295
+
1296
+ // ui/components/SpriteTextBBCode.ts
1297
+ var DEFAULT_STYLE = (defaultFontIndex) => ({
1298
+ fontIndex: defaultFontIndex
1299
+ });
1300
+ function parseColorValue(value) {
1301
+ const trimmed = value.trim();
1302
+ if (trimmed.startsWith("#")) {
1303
+ const hex = trimmed.slice(1);
1304
+ if (hex.length === 3) {
1305
+ const r = parseInt(hex[0] + hex[0], 16);
1306
+ const g = parseInt(hex[1] + hex[1], 16);
1307
+ const b = parseInt(hex[2] + hex[2], 16);
1308
+ return (r << 16) + (g << 8) + b;
1309
+ }
1310
+ if (hex.length === 6) {
1311
+ return parseInt(hex, 16);
1312
+ }
1313
+ }
1314
+ if (trimmed.startsWith("0x") || trimmed.startsWith("0X")) {
1315
+ return parseInt(trimmed, 16);
1316
+ }
1317
+ return void 0;
1318
+ }
1319
+ function resolveFontIndex(value, options) {
1320
+ const trimmed = value.trim();
1321
+ const fonts = options.fonts ?? [];
1322
+ const defaultIndex = options.defaultFontIndex ?? 0;
1323
+ const numericIndex = Number(trimmed);
1324
+ if (!Number.isNaN(numericIndex) && Number.isInteger(numericIndex)) {
1325
+ if (numericIndex >= 0 && numericIndex < fonts.length) {
1326
+ return numericIndex;
1327
+ }
1328
+ return defaultIndex;
1329
+ }
1330
+ const aliases = options.aliases ?? {};
1331
+ const aliasTarget = aliases[trimmed];
1332
+ if (aliasTarget !== void 0) {
1333
+ if (typeof aliasTarget === "number") {
1334
+ if (aliasTarget >= 0 && aliasTarget < fonts.length) {
1335
+ return aliasTarget;
1336
+ }
1337
+ return defaultIndex;
1338
+ }
1339
+ const fontIndex = fonts.indexOf(aliasTarget);
1340
+ return fontIndex >= 0 ? fontIndex : defaultIndex;
1341
+ }
1342
+ const directIndex = fonts.indexOf(trimmed);
1343
+ return directIndex >= 0 ? directIndex : defaultIndex;
1344
+ }
1345
+ function parseFontAttributes(attrString, options) {
1346
+ const style = { fontIndex: options.defaultFontIndex ?? 0 };
1347
+ const tokens = attrString.trim().split(/\s+/).filter(Boolean);
1348
+ let fontSet = false;
1349
+ for (const token of tokens) {
1350
+ const eqIdx = token.indexOf("=");
1351
+ if (eqIdx === -1) {
1352
+ if (!fontSet) {
1353
+ style.fontIndex = resolveFontIndex(token, options);
1354
+ fontSet = true;
1355
+ }
1356
+ continue;
1357
+ }
1358
+ const key = token.slice(0, eqIdx);
1359
+ const val = token.slice(eqIdx + 1);
1360
+ if (key === "font") {
1361
+ style.fontIndex = resolveFontIndex(val, options);
1362
+ fontSet = true;
1363
+ } else if (key === "tint") {
1364
+ style.tint = parseColorValue(val);
1365
+ } else if (key === "scale") {
1366
+ const scale = parseFloat(val);
1367
+ if (!Number.isNaN(scale)) {
1368
+ style.scale = scale;
1369
+ }
1370
+ }
1371
+ }
1372
+ if (!fontSet && tokens.length === 1 && tokens[0].includes("=") === false) {
1373
+ style.fontIndex = resolveFontIndex(tokens[0], options);
1374
+ }
1375
+ return style;
1376
+ }
1377
+ function parseOpenTag(tagContent, options) {
1378
+ const defaultFontIndex = options.defaultFontIndex ?? 0;
1379
+ if (tagContent.startsWith("font=")) {
1380
+ return {
1381
+ tagType: "font",
1382
+ style: parseFontAttributes(tagContent.slice(5), options)
1383
+ };
1384
+ }
1385
+ if (tagContent.startsWith("tint=")) {
1386
+ const tint = parseColorValue(tagContent.slice(5));
1387
+ return {
1388
+ tagType: "tint",
1389
+ style: { fontIndex: defaultFontIndex, tint }
1390
+ };
1391
+ }
1392
+ if (tagContent.startsWith("scale=")) {
1393
+ const scale = parseFloat(tagContent.slice(6));
1394
+ return {
1395
+ tagType: "scale",
1396
+ style: {
1397
+ fontIndex: defaultFontIndex,
1398
+ scale: Number.isNaN(scale) ? void 0 : scale
1399
+ }
1400
+ };
1401
+ }
1402
+ return null;
1403
+ }
1404
+ function mergeAdjacentRuns(runs) {
1405
+ if (runs.length === 0) return runs;
1406
+ const merged = [];
1407
+ let current = { ...runs[0] };
1408
+ for (let i = 1; i < runs.length; i++) {
1409
+ const next = runs[i];
1410
+ if (current.fontIndex === next.fontIndex && current.tint === next.tint && current.scale === next.scale) {
1411
+ current.text += next.text;
1412
+ } else {
1413
+ merged.push(current);
1414
+ current = { ...next };
1415
+ }
1416
+ }
1417
+ merged.push(current);
1418
+ return merged;
1419
+ }
1420
+ function parseSpriteTextBBCode(input, options = {}) {
1421
+ const defaultFontIndex = options.defaultFontIndex ?? 0;
1422
+ const runs = [];
1423
+ let buffer = "";
1424
+ let currentStyle = DEFAULT_STYLE(defaultFontIndex);
1425
+ let activeTag = null;
1426
+ const flush = () => {
1427
+ if (buffer.length === 0) return;
1428
+ runs.push({
1429
+ text: buffer,
1430
+ fontIndex: currentStyle.fontIndex,
1431
+ tint: currentStyle.tint,
1432
+ scale: currentStyle.scale
1433
+ });
1434
+ buffer = "";
1435
+ };
1436
+ let i = 0;
1437
+ while (i < input.length) {
1438
+ if (input[i] === "\\" && input[i + 1] === "[") {
1439
+ buffer += "[";
1440
+ i += 2;
1441
+ continue;
1442
+ }
1443
+ if (input[i] !== "[") {
1444
+ buffer += input[i];
1445
+ i += 1;
1446
+ continue;
1447
+ }
1448
+ const closeIdx = input.indexOf("]", i);
1449
+ if (closeIdx === -1) {
1450
+ buffer += input[i];
1451
+ i += 1;
1452
+ continue;
1453
+ }
1454
+ const tagContent = input.slice(i + 1, closeIdx);
1455
+ if (tagContent.startsWith("/")) {
1456
+ const closeTag = tagContent.slice(1);
1457
+ if (activeTag !== null && closeTag === activeTag) {
1458
+ flush();
1459
+ activeTag = null;
1460
+ currentStyle = DEFAULT_STYLE(defaultFontIndex);
1461
+ } else {
1462
+ buffer += input.slice(i, closeIdx + 1);
1463
+ }
1464
+ } else {
1465
+ const parsed = parseOpenTag(tagContent, options);
1466
+ if (parsed) {
1467
+ flush();
1468
+ activeTag = parsed.tagType;
1469
+ currentStyle = parsed.style;
1470
+ } else {
1471
+ buffer += input.slice(i, closeIdx + 1);
1472
+ }
1473
+ }
1474
+ i = closeIdx + 1;
1475
+ }
1476
+ flush();
1477
+ return mergeAdjacentRuns(runs);
1478
+ }
1479
+ function isKnownBBCodeTag(tagContent) {
1480
+ if (tagContent.startsWith("/")) {
1481
+ const closeTag = tagContent.slice(1);
1482
+ return closeTag === "font" || closeTag === "tint" || closeTag === "scale";
1483
+ }
1484
+ return tagContent.startsWith("font=") || tagContent.startsWith("tint=") || tagContent.startsWith("scale=");
1485
+ }
1486
+ function stripSpriteTextBBCode(input) {
1487
+ let result = "";
1488
+ let i = 0;
1489
+ while (i < input.length) {
1490
+ if (input[i] === "\\" && input[i + 1] === "[") {
1491
+ result += "[";
1492
+ i += 2;
1493
+ continue;
1494
+ }
1495
+ if (input[i] !== "[") {
1496
+ result += input[i];
1497
+ i += 1;
1498
+ continue;
1499
+ }
1500
+ const closeIdx = input.indexOf("]", i);
1501
+ if (closeIdx === -1) {
1502
+ result += input[i];
1503
+ i += 1;
1504
+ continue;
1505
+ }
1506
+ const tagContent = input.slice(i + 1, closeIdx);
1507
+ if (!isKnownBBCodeTag(tagContent)) {
1508
+ result += input.slice(i, closeIdx + 1);
1509
+ }
1510
+ i = closeIdx + 1;
1511
+ }
1512
+ return result;
1513
+ }
1514
+
1515
+ // ui/components/spriteText/SpriteTextKerning.ts
1516
+ function kerningKey(firstCode, secondCode) {
1517
+ return `${firstCode}_${secondCode}`;
1518
+ }
1519
+ function charPairToKey(first, second) {
1520
+ return kerningKey(first.charCodeAt(0), second.charCodeAt(0));
1521
+ }
1522
+ function codesToKey(first, second) {
1523
+ const firstCode = typeof first === "string" ? first.charCodeAt(0) : first;
1524
+ const secondCode = typeof second === "string" ? second.charCodeAt(0) : second;
1525
+ return kerningKey(firstCode, secondCode);
1526
+ }
1527
+ function getKerningFromMap(map, first, second) {
1528
+ return map.get(charPairToKey(first, second)) ?? 0;
1529
+ }
1530
+ function applyKerningPairs(map, pairs) {
1531
+ map.clear();
1532
+ if (Array.isArray(pairs)) {
1533
+ for (const pair of pairs) {
1534
+ map.set(kerningKey(pair.first, pair.second), pair.amount);
1535
+ }
1536
+ return;
1537
+ }
1538
+ for (const [chars, amount] of Object.entries(pairs)) {
1539
+ if (chars.length === 2) {
1540
+ map.set(charPairToKey(chars[0], chars[1]), amount);
1541
+ }
1542
+ }
1543
+ }
1544
+ function resolveCharTexture(char, fontIndex, ctx) {
1545
+ try {
1546
+ if (char === "\n" || char === "\r" || char === " ") {
1547
+ return null;
1548
+ }
1549
+ const font = ctx.fonts[fontIndex] ?? ctx.fonts[0];
1550
+ if (!font) return null;
1551
+ const fontStyle = ctx.getFontStyle(fontIndex);
1552
+ const glyphMap = (fontStyle == null ? void 0 : fontStyle.glyphMap) ?? ctx.glyphMap;
1553
+ let textureName;
1554
+ if (glyphMap[char]) {
1555
+ textureName = `${font}/${glyphMap[char]}`;
1556
+ } else {
1557
+ textureName = `${font}/${char.charCodeAt(0)}`;
1558
+ }
1559
+ const texture = Assets.get(textureName);
1560
+ if (!texture || texture === Texture.EMPTY) {
1561
+ return null;
1562
+ }
1563
+ return texture;
1564
+ } catch {
1565
+ return null;
1566
+ }
1567
+ }
1568
+ function resolveRefWidth(char, fontIndex, ctx) {
1569
+ const fontStyle = ctx.getFontStyle(fontIndex);
1570
+ const fixedWidth = (fontStyle == null ? void 0 : fontStyle.fixedWidth) ?? ctx.fixedWidth;
1571
+ if (fixedWidth === false) {
1572
+ return 0;
1573
+ }
1574
+ if (fixedWidth === true) {
1575
+ const refTexture = resolveCharTexture("0", fontIndex, ctx);
1576
+ return (refTexture == null ? void 0 : refTexture.width) ?? 0;
1577
+ }
1578
+ if (typeof fixedWidth === "string") {
1579
+ const refTexture = resolveCharTexture(fixedWidth, fontIndex, ctx);
1580
+ return (refTexture == null ? void 0 : refTexture.width) ?? 0;
1581
+ }
1582
+ if (typeof fixedWidth === "object" && fixedWidth !== null) {
1583
+ for (const [pattern, refChar] of Object.entries(fixedWidth)) {
1584
+ try {
1585
+ const regex = new RegExp(pattern);
1586
+ if (regex.test(char)) {
1587
+ const refTexture = resolveCharTexture(refChar, fontIndex, ctx);
1588
+ return (refTexture == null ? void 0 : refTexture.width) ?? 0;
1589
+ }
1590
+ } catch {
1591
+ continue;
1592
+ }
1593
+ }
1594
+ }
1595
+ return 0;
1596
+ }
1597
+ function measureCharMetaWidth(meta, ctx) {
1598
+ const effectiveScale = ctx.glyphScale * meta.runScale;
1599
+ if (meta.char === " ") {
1600
+ const refTexture = resolveCharTexture("0", meta.fontIndex, ctx);
1601
+ return ((refTexture == null ? void 0 : refTexture.width) ?? 0) * effectiveScale * ctx.spaceWidth;
1602
+ }
1603
+ if (meta.char === "\n") {
1604
+ return 0;
1605
+ }
1606
+ if (meta.char === " ") {
1607
+ const refTexture = resolveCharTexture("0", meta.fontIndex, ctx);
1608
+ return ((refTexture == null ? void 0 : refTexture.width) ?? 0) * effectiveScale * ctx.spaceWidth * 4;
1609
+ }
1610
+ const texture = resolveCharTexture(meta.char, meta.fontIndex, ctx);
1611
+ if (!texture) return 0;
1612
+ const refWidth = resolveRefWidth(meta.char, meta.fontIndex, ctx);
1613
+ const width = refWidth > 0 ? refWidth : texture.width;
1614
+ return width * effectiveScale;
1615
+ }
1616
+
1617
+ // ui/components/spriteText/SpriteTextWrap.ts
1618
+ function measureCharMetasWidth(metas, ctx) {
1619
+ let width = 0;
1620
+ for (let i = 0; i < metas.length; i++) {
1621
+ width += ctx.getCharMetaWidth(metas[i]);
1622
+ width += ctx.letterSpacing * ctx.glyphScale;
1623
+ if (ctx.kerningEnabled && i < metas.length - 1) {
1624
+ const current = metas[i];
1625
+ const next = metas[i + 1];
1626
+ if (current.fontIndex === next.fontIndex) {
1627
+ width += ctx.getKerning(current.char, next.char) * ctx.glyphScale;
1628
+ }
1629
+ }
1630
+ }
1631
+ return width;
1632
+ }
1633
+ function runsToMetas(runs) {
1634
+ const metas = [];
1635
+ for (const run of runs) {
1636
+ const runScale = run.scale ?? 1;
1637
+ for (const char of run.text) {
1638
+ metas.push({
1639
+ char,
1640
+ fontIndex: run.fontIndex,
1641
+ tint: run.tint,
1642
+ runScale
1643
+ });
1644
+ }
1645
+ }
1646
+ return metas;
1647
+ }
1648
+ function metasToRuns(metas) {
1649
+ if (metas.length === 0) return [];
1650
+ const runs = [];
1651
+ let current = {
1652
+ text: metas[0].char,
1653
+ fontIndex: metas[0].fontIndex,
1654
+ tint: metas[0].tint,
1655
+ scale: metas[0].runScale
1656
+ };
1657
+ for (let i = 1; i < metas.length; i++) {
1658
+ const meta = metas[i];
1659
+ if (current.fontIndex === meta.fontIndex && current.tint === meta.tint && current.scale === meta.runScale) {
1660
+ current.text += meta.char;
1661
+ } else {
1662
+ runs.push(current);
1663
+ current = {
1664
+ text: meta.char,
1665
+ fontIndex: meta.fontIndex,
1666
+ tint: meta.tint,
1667
+ scale: meta.runScale
1668
+ };
1669
+ }
1670
+ }
1671
+ runs.push(current);
1672
+ return runs;
1673
+ }
1674
+ function mergeRunLinesWithNewlines(lines) {
1675
+ const merged = [];
1676
+ lines.forEach((line, lineIndex) => {
1677
+ if (lineIndex > 0) {
1678
+ merged.push({ text: "\n", fontIndex: 0, scale: 1 });
1679
+ }
1680
+ merged.push(...line);
1681
+ });
1682
+ return merged;
1683
+ }
1684
+ function wrapCharMetas(metas, ctx) {
1685
+ const lines = [];
1686
+ let currentLine = [];
1687
+ let currentWord = [];
1688
+ const measureLine = (line) => measureCharMetasWidth(line, ctx);
1689
+ const flushWord = () => {
1690
+ if (currentWord.length === 0) return;
1691
+ const testLine = [...currentLine, ...currentWord];
1692
+ if (measureLine(testLine) > ctx.wordWrapWidth / ctx.scaleX && currentLine.length > 0) {
1693
+ lines.push(currentLine);
1694
+ currentLine = [...currentWord];
1695
+ } else {
1696
+ currentLine.push(...currentWord);
1697
+ }
1698
+ currentWord = [];
1699
+ };
1700
+ for (const meta of metas) {
1701
+ if (meta.char === "\n") {
1702
+ flushWord();
1703
+ lines.push(currentLine);
1704
+ currentLine = [];
1705
+ continue;
1706
+ }
1707
+ if (meta.char === " ") {
1708
+ flushWord();
1709
+ currentLine.push(meta);
1710
+ continue;
1711
+ }
1712
+ if (ctx.breakWord && currentWord.length === 0 && currentLine.length > 0) {
1713
+ const testWord = [meta];
1714
+ if (measureLine([...currentLine, ...testWord]) > ctx.wordWrapWidth / ctx.scaleX) {
1715
+ lines.push(currentLine);
1716
+ currentLine = [];
1717
+ }
1718
+ }
1719
+ currentWord.push(meta);
1720
+ if (ctx.breakWord && currentWord.length > 1) {
1721
+ const testLine = [...currentLine, ...currentWord];
1722
+ if (measureLine(testLine) > ctx.wordWrapWidth / ctx.scaleX) {
1723
+ const overflowChar = currentWord.pop();
1724
+ if (currentWord.length > 0) {
1725
+ flushWord();
1726
+ }
1727
+ if (overflowChar) {
1728
+ currentWord = [overflowChar];
1729
+ }
1730
+ }
1731
+ }
1732
+ }
1733
+ flushWord();
1734
+ if (currentLine.length > 0) {
1735
+ lines.push(currentLine);
1736
+ }
1737
+ return lines.length > 0 ? lines : [[]];
1738
+ }
1739
+ function wrapRuns(runs, ctx) {
1740
+ const metas = runsToMetas(runs);
1741
+ const lines = wrapCharMetas(metas, ctx);
1742
+ return lines.map((line) => metasToRuns(line));
1743
+ }
1744
+
1745
+ // ui/components/spriteText/SpriteTextBezier.ts
1746
+ function getBezierPoint(t, p0, p1, p2) {
1747
+ const mt = 1 - t;
1748
+ const mt2 = mt * mt;
1749
+ const t2 = t * t;
1750
+ return {
1751
+ x: mt2 * p0.x + 2 * mt * t * p1.x + t2 * p2.x,
1752
+ y: mt2 * p0.y + 2 * mt * t * p1.y + t2 * p2.y
1753
+ };
1754
+ }
1755
+ function getBezierTangent(t, p0, p1, p2) {
1756
+ const mt = 1 - t;
1757
+ const dx = 2 * mt * (p1.x - p0.x) + 2 * t * (p2.x - p1.x);
1758
+ const dy = 2 * mt * (p1.y - p0.y) + 2 * t * (p2.y - p1.y);
1759
+ return Math.atan2(dy, dx);
1760
+ }
1761
+ function buildBezierArcLengthTable(p0, p1, p2, samples = 64) {
1762
+ const table = [{ t: 0, length: 0 }];
1763
+ let accum = 0;
1764
+ let prev = p0;
1765
+ for (let i = 1; i <= samples; i++) {
1766
+ const t = i / samples;
1767
+ const point = getBezierPoint(t, p0, p1, p2);
1768
+ accum += Math.hypot(point.x - prev.x, point.y - prev.y);
1769
+ table.push({ t, length: accum });
1770
+ prev = point;
1771
+ }
1772
+ return table;
1773
+ }
1774
+ var CURVE_WIDTH_BULGE_RATIO = 0.2;
1775
+ var CURVE_SPREAD_FACTOR = 0.65;
1776
+ function computeCurveBulge(lineWidth, lineHeight, controlYPercent) {
1777
+ const magnitude = Math.abs(controlYPercent);
1778
+ return Math.min(lineHeight * magnitude, lineWidth * magnitude * CURVE_WIDTH_BULGE_RATIO);
1779
+ }
1780
+ function computeCurveSpread(lineWidth, lineHeight, controlYPercent) {
1781
+ const bulge = computeCurveBulge(lineWidth, lineHeight, controlYPercent);
1782
+ const bulgeRatio = bulge / Math.max(lineWidth, 1);
1783
+ return 1 + bulgeRatio * CURVE_SPREAD_FACTOR;
1784
+ }
1785
+ function computeProportionalArcLength(centerFraction, totalArcLength, spread) {
1786
+ const spreadFraction = 0.5 + (centerFraction - 0.5) * spread;
1787
+ const clampedFraction = Math.min(Math.max(spreadFraction, 0), 1);
1788
+ return clampedFraction * totalArcLength;
1789
+ }
1790
+ function getRotatedOffset(localX, localY, rotation) {
1791
+ const cos = Math.cos(rotation);
1792
+ const sin = Math.sin(rotation);
1793
+ return {
1794
+ x: localX * cos - localY * sin,
1795
+ y: localX * sin + localY * cos
1796
+ };
1797
+ }
1798
+ function placeLocalPointOnCurve(curvePos, tangent, localX, localY) {
1799
+ const rotated = getRotatedOffset(localX, localY, tangent);
1800
+ return {
1801
+ x: curvePos.x - rotated.x,
1802
+ y: curvePos.y - rotated.y
1803
+ };
1804
+ }
1805
+ function getBezierTForArcLength(table, targetLength) {
1806
+ if (table.length === 0) {
1807
+ return 0;
1808
+ }
1809
+ const totalLength = table[table.length - 1].length;
1810
+ if (targetLength <= 0) {
1811
+ return 0;
1812
+ }
1813
+ if (targetLength >= totalLength) {
1814
+ return 1;
1815
+ }
1816
+ let lo = 0;
1817
+ let hi = table.length - 1;
1818
+ while (lo < hi - 1) {
1819
+ const mid = Math.floor((lo + hi) / 2);
1820
+ if (table[mid].length < targetLength) {
1821
+ lo = mid;
1822
+ } else {
1823
+ hi = mid;
1824
+ }
1825
+ }
1826
+ const a = table[lo];
1827
+ const b = table[hi];
1828
+ const segmentLength = b.length - a.length;
1829
+ if (segmentLength <= 0) {
1830
+ return a.t;
1831
+ }
1832
+ const ratio = (targetLength - a.length) / segmentLength;
1833
+ return a.t + ratio * (b.t - a.t);
1834
+ }
1835
+
1836
+ // ui/components/spriteText/SpriteTextCurve.ts
1837
+ function applyCurveToLine(glyphs, config) {
1838
+ var _a;
1839
+ const {
1840
+ lineIndex,
1841
+ lineWidth,
1842
+ lineHeight,
1843
+ lineAlignOffset,
1844
+ controlXPercent,
1845
+ controlYPercent
1846
+ } = config;
1847
+ const lineCenterX = lineAlignOffset + lineWidth / 2;
1848
+ const curveHalfWidth = lineWidth / 2;
1849
+ const curveStartX = lineCenterX - curveHalfWidth;
1850
+ const curveEndX = lineCenterX + curveHalfWidth;
1851
+ const curveStartY = lineIndex * lineHeight;
1852
+ const curveControlX = lineCenterX + lineWidth * (controlXPercent - 0.5);
1853
+ const bulge = computeCurveBulge(lineWidth, lineHeight, controlYPercent);
1854
+ const verticalSign = controlYPercent < 0 ? -1 : controlYPercent > 0 ? 1 : 0;
1855
+ const curveControlY = curveStartY + verticalSign * bulge;
1856
+ const curveEndY = curveStartY;
1857
+ const p0 = { x: curveStartX, y: curveStartY };
1858
+ const p1 = { x: curveControlX, y: curveControlY };
1859
+ const p2 = { x: curveEndX, y: curveEndY };
1860
+ const arcTable = lineWidth > 0 ? buildBezierArcLengthTable(p0, p1, p2) : [{ t: 0, length: 0 }];
1861
+ const totalArcLength = ((_a = arcTable[arcTable.length - 1]) == null ? void 0 : _a.length) ?? 0;
1862
+ const targetCenterX = lineAlignOffset + lineWidth / 2;
1863
+ const spread = computeCurveSpread(lineWidth, lineHeight, controlYPercent);
1864
+ glyphs.forEach((glyph) => {
1865
+ const bounds = glyph.getLocalBounds();
1866
+ const scaleX = glyph.scale.x;
1867
+ const scaleY = glyph.scale.y;
1868
+ const glyphWidth = bounds.width * scaleX;
1869
+ const glyphHeight = bounds.height * scaleY;
1870
+ const glyphLeft = glyph.x + bounds.x * scaleX;
1871
+ const centerFraction = lineWidth > 0 ? (glyphLeft + glyphWidth / 2) / lineWidth : 0;
1872
+ const trackingArc = computeProportionalArcLength(centerFraction, totalArcLength, spread);
1873
+ const t = totalArcLength > 0 ? getBezierTForArcLength(arcTable, trackingArc) : 0;
1874
+ const curvePos = getBezierPoint(t, p0, p1, p2);
1875
+ const curveTangent = getBezierTangent(t, p0, p1, p2);
1876
+ const localBottomCenterX = bounds.x * scaleX + glyphWidth / 2;
1877
+ const localBottomCenterY = bounds.y * scaleY + glyphHeight;
1878
+ const position = placeLocalPointOnCurve(
1879
+ curvePos,
1880
+ curveTangent,
1881
+ localBottomCenterX,
1882
+ localBottomCenterY
1883
+ );
1884
+ glyph.x = position.x;
1885
+ glyph.y = position.y;
1886
+ glyph.rotation = curveTangent;
1887
+ });
1888
+ const curvedBounds = getGlyphsAxisBounds(glyphs);
1889
+ const offsetX = targetCenterX - curvedBounds.centerX;
1890
+ const offsetY = 0;
1891
+ glyphs.forEach((glyph) => {
1892
+ glyph.x += offsetX;
1893
+ glyph.y += offsetY;
1894
+ });
1895
+ }
1896
+ function getGlyphsAxisBounds(glyphs) {
1897
+ let minX = Infinity;
1898
+ let maxX = -Infinity;
1899
+ let minY = Infinity;
1900
+ let maxY = -Infinity;
1901
+ glyphs.forEach((glyph) => {
1902
+ const bounds = glyph.getLocalBounds();
1903
+ const scaleX = glyph.scale.x;
1904
+ const scaleY = glyph.scale.y;
1905
+ const width = bounds.width * scaleX;
1906
+ const height = bounds.height * scaleY;
1907
+ const localCorners = [
1908
+ { x: bounds.x * scaleX, y: bounds.y * scaleY },
1909
+ { x: bounds.x * scaleX + width, y: bounds.y * scaleY },
1910
+ { x: bounds.x * scaleX + width, y: bounds.y * scaleY + height },
1911
+ { x: bounds.x * scaleX, y: bounds.y * scaleY + height }
1912
+ ];
1913
+ localCorners.forEach((corner) => {
1914
+ const cos = Math.cos(glyph.rotation);
1915
+ const sin = Math.sin(glyph.rotation);
1916
+ const x = glyph.x + (corner.x * cos - corner.y * sin);
1917
+ const y = glyph.y + (corner.x * sin + corner.y * cos);
1918
+ minX = Math.min(minX, x);
1919
+ maxX = Math.max(maxX, x);
1920
+ minY = Math.min(minY, y);
1921
+ maxY = Math.max(maxY, y);
1922
+ });
1923
+ });
1924
+ if (!Number.isFinite(minX)) {
1925
+ return { minX: 0, maxX: 0, minY: 0, maxY: 0, centerX: 0, centerY: 0 };
1926
+ }
1927
+ return {
1928
+ minX,
1929
+ maxX,
1930
+ minY,
1931
+ maxY,
1932
+ centerX: (minX + maxX) / 2,
1933
+ centerY: (minY + maxY) / 2
1934
+ };
1935
+ }
1936
+
1937
+ // ui/components/spriteText/SpriteTextAlignment.ts
1938
+ function splitGlyphsIntoLines(glyphs) {
1939
+ const lines = [];
1940
+ let currentLine = [];
1941
+ glyphs.forEach((glyph) => {
1942
+ if (glyph.isLinebreak) {
1943
+ if (currentLine.length > 0) {
1944
+ lines.push(currentLine);
1945
+ currentLine = [];
1946
+ }
1947
+ } else {
1948
+ currentLine.push(glyph);
1949
+ }
1950
+ });
1951
+ if (currentLine.length > 0) {
1952
+ lines.push(currentLine);
1953
+ }
1954
+ return lines;
1955
+ }
1956
+ function layoutFlatLines(lines, ctx) {
1957
+ const lineWidths = [];
1958
+ const lineHeights = [];
1959
+ lines.forEach((lineGlyphs, lineIndex) => {
1960
+ if (lineGlyphs.length === 0) {
1961
+ lineWidths.push(0);
1962
+ lineHeights.push(0);
1963
+ return;
1964
+ }
1965
+ let xCursor = 0;
1966
+ const lineHeight = Math.max(
1967
+ ...lineGlyphs.map((glyph) => glyph.height || glyph.getLocalBounds().height * glyph.scale.y),
1968
+ 0
1969
+ );
1970
+ lineHeights.push(lineHeight);
1971
+ lineGlyphs.forEach((glyph, glyphIndex) => {
1972
+ glyph.x = xCursor - glyph.getLocalBounds().x * glyph.scale.x;
1973
+ glyph.y = lineIndex * lineHeight - glyph.getLocalBounds().y * glyph.scale.y;
1974
+ xCursor += glyph.getLocalBounds().width * glyph.scale.x + ctx.letterSpacing * ctx.glyphScale;
1975
+ if (ctx.kerningEnabled && glyphIndex < lineGlyphs.length - 1) {
1976
+ const nextGlyph = lineGlyphs[glyphIndex + 1];
1977
+ if (glyph.fontIndex === nextGlyph.fontIndex) {
1978
+ xCursor += ctx.getKerning(glyph.char, nextGlyph.char) * ctx.glyphScale;
1979
+ }
1980
+ }
1981
+ });
1982
+ const lineWidth = xCursor - ctx.letterSpacing * ctx.glyphScale;
1983
+ lineWidths.push(lineWidth);
1984
+ });
1985
+ return { lineWidths, lineHeights };
1986
+ }
1987
+ function computeLineAlignOffset(lineAlign, lineWidth, maxWidth) {
1988
+ switch (lineAlign) {
1989
+ case "left":
1990
+ return 0;
1991
+ case "center":
1992
+ return (maxWidth - lineWidth) / 2;
1993
+ case "right":
1994
+ return maxWidth - lineWidth;
1995
+ }
1996
+ }
1997
+ function applyContainerPivot(container, bounds, pivotHorizontal, pivotVertical) {
1998
+ switch (pivotHorizontal) {
1999
+ case "left":
2000
+ container.pivot.x = bounds.x;
2001
+ break;
2002
+ case "center":
2003
+ container.pivot.x = bounds.x + bounds.width / 2;
2004
+ break;
2005
+ case "right":
2006
+ container.pivot.x = bounds.x + bounds.width;
2007
+ break;
2008
+ }
2009
+ switch (pivotVertical) {
2010
+ case "top":
2011
+ container.pivot.y = bounds.y;
2012
+ break;
2013
+ case "middle":
2014
+ container.pivot.y = bounds.y + bounds.height / 2;
2015
+ break;
2016
+ case "bottom":
2017
+ container.pivot.y = bounds.y + bounds.height;
2018
+ break;
2019
+ }
2020
+ }
2021
+ function resolveSpriteTextAlignment(container, ctx) {
2022
+ const lines = splitGlyphsIntoLines(ctx.glyphs);
2023
+ const { lineWidths, lineHeights } = layoutFlatLines(lines, ctx);
2024
+ const maxWidth = Math.max(...lineWidths, 0);
2025
+ lines.forEach((lineGlyphs, lineIndex) => {
2026
+ if (lineGlyphs.length === 0) return;
2027
+ const lineWidth = lineWidths[lineIndex];
2028
+ const lineHeight = lineHeights[lineIndex];
2029
+ const lineAlignOffset = computeLineAlignOffset(ctx.lineAlign, lineWidth, maxWidth);
2030
+ if (!ctx.curveEnabled) {
2031
+ lineGlyphs.forEach((glyph) => {
2032
+ glyph.x += lineAlignOffset;
2033
+ glyph.rotation = 0;
2034
+ });
2035
+ return;
2036
+ }
2037
+ applyCurveToLine(lineGlyphs, {
2038
+ lineIndex,
2039
+ lineWidth,
2040
+ lineHeight,
2041
+ lineAlignOffset,
2042
+ controlXPercent: ctx.curveControlXPercent,
2043
+ controlYPercent: ctx.curveControlYPercent
2044
+ });
2045
+ });
2046
+ container.boundsArea = void 0;
2047
+ const bounds = container.getLocalBounds();
2048
+ applyContainerPivot(container, bounds, ctx.pivotHorizontal, ctx.pivotVertical);
2049
+ }
2050
+
2051
+ // ui/components/spriteText/SpriteText.ts
2052
+ var SpriteText = class _SpriteText extends Skinable(Container) {
2053
+ static globalSkin = defineGlobalSkin();
2054
+ _glyphs = [];
2055
+ _text = "";
2056
+ _fonts = [];
2057
+ _font = "";
2058
+ _bbcodeEnabled = false;
2059
+ _richTextExplicit;
2060
+ _bbcodeAliases = {};
2061
+ _fontStyles = [];
2062
+ _runsOverride = null;
2063
+ _tint = 16777215;
2064
+ _pivotHorizontal = "center";
2065
+ _pivotVertical = "middle";
2066
+ _lineAlign = "left";
2067
+ _letterSpacing = 0;
2068
+ _spaceWidth = 0.5;
2069
+ _wordWrap = false;
2070
+ _wordWrapWidth = 100;
2071
+ _breakWord = false;
2072
+ _allowLineBreak = false;
2073
+ _kerningEnabled = false;
2074
+ _kerningMap = /* @__PURE__ */ new Map();
2075
+ _glyphAnchor = { x: 0, y: 0 };
2076
+ _glyphMap = {};
2077
+ _fixedWidth = false;
2078
+ _glyphScale = 1;
2079
+ _curveEnabled = false;
2080
+ _curveControlXPercent = 0.5;
2081
+ _curveControlYPercent = -0.5;
2082
+ constructor(options = {}) {
2083
+ super();
2084
+ if (options.text !== void 0) {
2085
+ this._text = options.text;
2086
+ }
2087
+ const effectiveSkin = mergeGlobalAndInstanceSkin(
2088
+ () => _SpriteText.globalSkin(),
2089
+ options.skinData
2090
+ );
2091
+ this.setSkinData(effectiveSkin, { mergeWithExisting: false });
2092
+ }
2093
+ skinApply(skin) {
2094
+ if (!skin) return;
2095
+ const propertyMap = {
2096
+ text: "_text",
2097
+ tint: "_tint",
2098
+ "pivot.horizontal": "_pivotHorizontal",
2099
+ "pivot.vertical": "_pivotVertical",
2100
+ lineAlign: "_lineAlign",
2101
+ "spacing.letter": "_letterSpacing",
2102
+ "spacing.space": "_spaceWidth",
2103
+ "wordWrap.enabled": "_wordWrap",
2104
+ "wordWrap.width": "_wordWrapWidth",
2105
+ "wordWrap.breakWord": "_breakWord",
2106
+ "lineBreak.enabled": "_allowLineBreak",
2107
+ "kerning.enabled": "_kerningEnabled",
2108
+ "kerning.pairs": null,
2109
+ "glyph.anchor": "_glyphAnchor",
2110
+ "glyph.map": "_glyphMap",
2111
+ "glyph.fixedWidth": "_fixedWidth",
2112
+ "glyph.scale": "_glyphScale",
2113
+ "curve.enabled": "_curveEnabled",
2114
+ "curve.controlXPercent": "_curveControlXPercent",
2115
+ "curve.controlYPercent": "_curveControlYPercent"
2116
+ };
2117
+ Object.entries(propertyMap).forEach(([skinPath, instanceProperty]) => {
2118
+ const value = getNestedValue(skin, skinPath);
2119
+ if (value !== void 0) {
2120
+ if (skinPath === "text" && this._text !== "") return;
2121
+ if (skinPath === "kerning.pairs") {
2122
+ this.setKerningPairs(value);
2123
+ } else if (instanceProperty) {
2124
+ this[instanceProperty] = value;
2125
+ }
2126
+ }
2127
+ });
2128
+ this.applyLegacyAlignmentSkin(skin);
2129
+ if (skin.fonts !== void 0) {
2130
+ this._fonts = [...skin.fonts];
2131
+ } else if (skin.font !== void 0) {
2132
+ this._fonts = [skin.font];
2133
+ }
2134
+ this._font = this._fonts[0] ?? "";
2135
+ if (skin.richText !== void 0) {
2136
+ this._richTextExplicit = skin.richText.enabled;
2137
+ this._bbcodeAliases = skin.richText.aliases ?? {};
2138
+ }
2139
+ this._bbcodeEnabled = this._richTextExplicit ?? this._fonts.length > 1;
2140
+ if (skin.fontStyles !== void 0) {
2141
+ this._fontStyles = skin.fontStyles.map((fontStyle) => {
2142
+ var _a, _b;
2143
+ return {
2144
+ scale: fontStyle.scale ?? 1,
2145
+ tint: fontStyle.tint !== void 0 ? Color.shared.setValue(fontStyle.tint).toNumber() : void 0,
2146
+ glyphMap: (_a = fontStyle.glyph) == null ? void 0 : _a.map,
2147
+ fixedWidth: (_b = fontStyle.glyph) == null ? void 0 : _b.fixedWidth
2148
+ };
2149
+ });
2150
+ }
2151
+ this.generateText();
2152
+ }
2153
+ applyLegacyAlignmentSkin(skin) {
2154
+ var _a, _b;
2155
+ const legacy = skin.alignment;
2156
+ if (!legacy) return;
2157
+ if (((_a = skin.pivot) == null ? void 0 : _a.horizontal) === void 0 && legacy.horizontal !== void 0) {
2158
+ this._pivotHorizontal = legacy.horizontal;
2159
+ }
2160
+ if (((_b = skin.pivot) == null ? void 0 : _b.vertical) === void 0 && legacy.vertical !== void 0) {
2161
+ this._pivotVertical = legacy.vertical;
2162
+ }
2163
+ if (skin.lineAlign === void 0 && legacy.lineAlign !== void 0) {
2164
+ this._lineAlign = legacy.lineAlign;
2165
+ }
2166
+ }
2167
+ getTextureContext() {
2168
+ return {
2169
+ fonts: this._fonts,
2170
+ glyphMap: this._glyphMap,
2171
+ fixedWidth: this._fixedWidth,
2172
+ fontStyles: this._fontStyles,
2173
+ getFontStyle: (fontIndex) => this.getFontStyle(fontIndex)
2174
+ };
2175
+ }
2176
+ getWrapContext() {
2177
+ const textureCtx = this.getTextureContext();
2178
+ return {
2179
+ wordWrapWidth: this._wordWrapWidth,
2180
+ scaleX: this.scale.x,
2181
+ breakWord: this._breakWord,
2182
+ letterSpacing: this._letterSpacing,
2183
+ glyphScale: this._glyphScale,
2184
+ kerningEnabled: this._kerningEnabled,
2185
+ getKerning: (first, second) => this.getKerning(first, second),
2186
+ getCharMetaWidth: (meta) => measureCharMetaWidth(meta, {
2187
+ ...textureCtx,
2188
+ glyphScale: this._glyphScale,
2189
+ spaceWidth: this._spaceWidth
2190
+ })
2191
+ };
2192
+ }
2193
+ applyFontStyleDefaults(run) {
2194
+ const fontStyle = this._fontStyles[run.fontIndex];
2195
+ const fontStyleScale = (fontStyle == null ? void 0 : fontStyle.scale) ?? 1;
2196
+ return {
2197
+ text: run.text,
2198
+ fontIndex: run.fontIndex,
2199
+ tint: run.tint ?? (fontStyle == null ? void 0 : fontStyle.tint),
2200
+ scale: (run.scale ?? 1) * fontStyleScale
2201
+ };
2202
+ }
2203
+ resolveRuns() {
2204
+ if (this._runsOverride) {
2205
+ return this._runsOverride;
2206
+ }
2207
+ const rawRuns = this._bbcodeEnabled ? parseSpriteTextBBCode(this._text, {
2208
+ defaultFontIndex: 0,
2209
+ aliases: this._bbcodeAliases,
2210
+ fonts: this._fonts
2211
+ }) : [{ text: this._text, fontIndex: 0 }];
2212
+ return rawRuns.map((run) => this.applyFontStyleDefaults(run));
2213
+ }
2214
+ buildTextChunks(runs) {
2215
+ if (this._wordWrap) {
2216
+ const wrappedLines = wrapRuns(runs, this.getWrapContext()).filter((line) => line.length > 0);
2217
+ if (this._allowLineBreak) {
2218
+ return [mergeRunLinesWithNewlines(wrappedLines)];
2219
+ }
2220
+ return wrappedLines;
2221
+ }
2222
+ return [runs];
2223
+ }
2224
+ generateText() {
2225
+ if (!this._font) return;
2226
+ const runs = this.resolveRuns();
2227
+ const textChunks = this.buildTextChunks(runs);
2228
+ let visibleTextLength = 0;
2229
+ const textureCtx = this.getTextureContext();
2230
+ textChunks.forEach((chunk) => {
2231
+ const metas = runsToMetas(chunk);
2232
+ for (const meta of metas) {
2233
+ const char = meta.char;
2234
+ let texture = resolveCharTexture(char, meta.fontIndex, textureCtx);
2235
+ const isSpace = texture === null && char === " ";
2236
+ const isLineBreak = texture === null && char === "\n";
2237
+ const isTab = texture === null && char === " ";
2238
+ if (isSpace || isLineBreak || isTab) {
2239
+ texture = Texture.WHITE;
2240
+ }
2241
+ if (texture !== null) {
2242
+ const effectiveScale = this._glyphScale * meta.runScale;
2243
+ const glyphTint = meta.tint ?? this._tint;
2244
+ if (this._glyphs[visibleTextLength]) {
2245
+ this._glyphs[visibleTextLength].texture = texture;
2246
+ this._glyphs[visibleTextLength].tint = glyphTint;
2247
+ this._glyphs[visibleTextLength].scale.set(effectiveScale, effectiveScale);
2248
+ } else {
2249
+ this._glyphs[visibleTextLength] = new Sprite();
2250
+ this._glyphs[visibleTextLength].anchor.set(this._glyphAnchor.x, this._glyphAnchor.y);
2251
+ this._glyphs[visibleTextLength].tint = glyphTint;
2252
+ this._glyphs[visibleTextLength].texture = texture;
2253
+ this._glyphs[visibleTextLength].scale.set(effectiveScale, effectiveScale);
2254
+ }
2255
+ this._glyphs[visibleTextLength].char = char;
2256
+ this._glyphs[visibleTextLength].charCode = char.charCodeAt(0);
2257
+ this._glyphs[visibleTextLength].fontIndex = meta.fontIndex;
2258
+ this._glyphs[visibleTextLength].runTint = meta.tint;
2259
+ this._glyphs[visibleTextLength].runScale = meta.runScale;
2260
+ this._glyphs[visibleTextLength].isLinebreak = isLineBreak;
2261
+ this._glyphs[visibleTextLength].isSpace = isSpace;
2262
+ this._glyphs[visibleTextLength].isTab = isTab;
2263
+ const ref0Texture = resolveCharTexture("0", meta.fontIndex, textureCtx);
2264
+ const ref0Width = ((ref0Texture == null ? void 0 : ref0Texture.width) ?? 0) * effectiveScale;
2265
+ const ref0Height = ((ref0Texture == null ? void 0 : ref0Texture.height) ?? 0) * effectiveScale;
2266
+ if (isSpace) {
2267
+ this._glyphs[visibleTextLength].width = ref0Width * this._spaceWidth;
2268
+ this._glyphs[visibleTextLength].height = ref0Height;
2269
+ this._glyphs[visibleTextLength].label = "space";
2270
+ this._glyphs[visibleTextLength].alpha = 0;
2271
+ } else if (isTab) {
2272
+ this._glyphs[visibleTextLength].width = ref0Width * this._spaceWidth * 4;
2273
+ this._glyphs[visibleTextLength].height = ref0Height;
2274
+ this._glyphs[visibleTextLength].label = "tab";
2275
+ this._glyphs[visibleTextLength].alpha = 0;
2276
+ } else if (isLineBreak) {
2277
+ this._glyphs[visibleTextLength].width = 0;
2278
+ this._glyphs[visibleTextLength].label = "lineBreak";
2279
+ this._glyphs[visibleTextLength].height = ref0Height;
2280
+ this._glyphs[visibleTextLength].alpha = 0;
2281
+ } else {
2282
+ this._glyphs[visibleTextLength].alpha = 1;
2283
+ this._glyphs[visibleTextLength].label = char;
2284
+ const refWidth = resolveRefWidth(char, meta.fontIndex, textureCtx);
2285
+ if (refWidth > 0) {
2286
+ this._glyphs[visibleTextLength].width = refWidth * effectiveScale;
2287
+ } else {
2288
+ this._glyphs[visibleTextLength].width = ((texture == null ? void 0 : texture.width) ?? 0) * effectiveScale;
2289
+ }
2290
+ }
2291
+ visibleTextLength++;
2292
+ }
2293
+ }
2294
+ });
2295
+ if (this._glyphs.length > visibleTextLength) {
2296
+ const oldChars = this._glyphs.splice(
2297
+ visibleTextLength,
2298
+ this._glyphs.length - visibleTextLength
2299
+ );
2300
+ for (let oIndex = 0; oIndex < oldChars.length; oIndex++) {
2301
+ oldChars[oIndex].destroy({ children: true });
2302
+ }
2303
+ }
2304
+ if (this._glyphs.length > 0) {
2305
+ this.addChild(...this._glyphs);
2306
+ }
2307
+ this.resolveAlignment();
2308
+ }
2309
+ getFontStyle(fontIndex) {
2310
+ return this._fontStyles[fontIndex];
2311
+ }
2312
+ resolveAlignment() {
2313
+ resolveSpriteTextAlignment(this, {
2314
+ glyphs: this._glyphs,
2315
+ lineAlign: this._lineAlign,
2316
+ curveEnabled: this._curveEnabled,
2317
+ curveControlXPercent: this._curveControlXPercent,
2318
+ curveControlYPercent: this._curveControlYPercent,
2319
+ letterSpacing: this._letterSpacing,
2320
+ glyphScale: this._glyphScale,
2321
+ kerningEnabled: this._kerningEnabled,
2322
+ getKerning: (first, second) => this.getKerning(first, second),
2323
+ pivotHorizontal: this._pivotHorizontal,
2324
+ pivotVertical: this._pivotVertical
2325
+ });
2326
+ }
2327
+ get text() {
2328
+ return this._text;
2329
+ }
2330
+ set text(value) {
2331
+ if (this._text !== value) {
2332
+ this._text = value;
2333
+ this._runsOverride = null;
2334
+ this.generateText();
2335
+ }
2336
+ }
2337
+ get plainText() {
2338
+ return this._bbcodeEnabled ? stripSpriteTextBBCode(this._text) : this._text;
2339
+ }
2340
+ get font() {
2341
+ return this._font;
2342
+ }
2343
+ set font(value) {
2344
+ if (this._font !== value) {
2345
+ this._fonts = [value];
2346
+ this._font = value;
2347
+ this._bbcodeEnabled = this._richTextExplicit ?? this._fonts.length > 1;
2348
+ this.generateText();
2349
+ }
2350
+ }
2351
+ get fonts() {
2352
+ return [...this._fonts];
2353
+ }
2354
+ set fonts(value) {
2355
+ this._fonts = [...value];
2356
+ this._font = value[0] ?? "";
2357
+ this._bbcodeEnabled = this._richTextExplicit ?? this._fonts.length > 1;
2358
+ this.generateText();
2359
+ }
2360
+ get bbcodeEnabled() {
2361
+ return this._bbcodeEnabled;
2362
+ }
2363
+ setRuns(runs) {
2364
+ this._runsOverride = runs.map((run) => this.applyFontStyleDefaults(run));
2365
+ this.generateText();
2366
+ }
2367
+ get tint() {
2368
+ return this._tint;
2369
+ }
2370
+ set tint(value) {
2371
+ const numericValue = Color.shared.setValue(value ?? 16777215).toNumber();
2372
+ if (this._tint !== numericValue) {
2373
+ this._tint = numericValue;
2374
+ for (let gIndex = 0; gIndex < this._glyphs.length; gIndex++) {
2375
+ if (this._glyphs[gIndex].runTint === void 0) {
2376
+ this._glyphs[gIndex].tint = this._tint;
2377
+ }
2378
+ }
2379
+ }
2380
+ }
2381
+ get pivotHorizontal() {
2382
+ return this._pivotHorizontal;
2383
+ }
2384
+ set pivotHorizontal(value) {
2385
+ if (this._pivotHorizontal !== value) {
2386
+ this._pivotHorizontal = value;
2387
+ this.resolveAlignment();
2388
+ }
2389
+ }
2390
+ get pivotVertical() {
2391
+ return this._pivotVertical;
2392
+ }
2393
+ set pivotVertical(value) {
2394
+ if (this._pivotVertical !== value) {
2395
+ this._pivotVertical = value;
2396
+ this.resolveAlignment();
2397
+ }
2398
+ }
2399
+ /** @deprecated Use pivotHorizontal */
2400
+ get textHAlign() {
2401
+ return this._pivotHorizontal;
2402
+ }
2403
+ /** @deprecated Use pivotHorizontal */
2404
+ set textHAlign(value) {
2405
+ this.pivotHorizontal = value;
2406
+ }
2407
+ /** @deprecated Use pivotVertical */
2408
+ get textVAlign() {
2409
+ return this._pivotVertical;
2410
+ }
2411
+ /** @deprecated Use pivotVertical */
2412
+ set textVAlign(value) {
2413
+ this.pivotVertical = value;
2414
+ }
2415
+ get lineAlign() {
2416
+ return this._lineAlign;
2417
+ }
2418
+ set lineAlign(value) {
2419
+ if (this._lineAlign !== value) {
2420
+ this._lineAlign = value;
2421
+ this.resolveAlignment();
2422
+ }
2423
+ }
2424
+ get letterSpacing() {
2425
+ return this._letterSpacing;
2426
+ }
2427
+ set letterSpacing(value) {
2428
+ if (this._letterSpacing !== value) {
2429
+ this._letterSpacing = value;
2430
+ this.resolveAlignment();
2431
+ }
2432
+ }
2433
+ get spaceWidth() {
2434
+ return this._spaceWidth;
2435
+ }
2436
+ set spaceWidth(value) {
2437
+ if (this._spaceWidth !== value) {
2438
+ this._spaceWidth = value;
2439
+ this.generateText();
2440
+ }
2441
+ }
2442
+ get wordWrap() {
2443
+ return this._wordWrap;
2444
+ }
2445
+ set wordWrap(value) {
2446
+ if (this._wordWrap !== value) {
2447
+ this._wordWrap = value;
2448
+ this.generateText();
2449
+ }
2450
+ }
2451
+ get wordWrapWidth() {
2452
+ return this._wordWrapWidth;
2453
+ }
2454
+ set wordWrapWidth(value) {
2455
+ if (this._wordWrapWidth !== value) {
2456
+ this._wordWrapWidth = value;
2457
+ this.generateText();
2458
+ }
2459
+ }
2460
+ get breakWord() {
2461
+ return this._breakWord;
2462
+ }
2463
+ set breakWord(value) {
2464
+ if (this._breakWord !== value) {
2465
+ this._breakWord = value;
2466
+ this.generateText();
2467
+ }
2468
+ }
2469
+ get allowLineBreak() {
2470
+ return this._allowLineBreak;
2471
+ }
2472
+ set allowLineBreak(value) {
2473
+ if (this._allowLineBreak !== value) {
2474
+ this._allowLineBreak = value;
2475
+ this.generateText();
2476
+ }
2477
+ }
2478
+ getGlyphs() {
2479
+ return this._glyphs;
2480
+ }
2481
+ getGlyphAt(pos) {
2482
+ return this._glyphs[pos];
2483
+ }
2484
+ get glyphCount() {
2485
+ return this._glyphs.length;
2486
+ }
2487
+ get kerningEnabled() {
2488
+ return this._kerningEnabled;
2489
+ }
2490
+ set kerningEnabled(value) {
2491
+ if (this._kerningEnabled !== value) {
2492
+ this._kerningEnabled = value;
2493
+ this.resolveAlignment();
2494
+ }
2495
+ }
2496
+ getKerning(first, second) {
2497
+ if (!this._kerningEnabled) return 0;
2498
+ return getKerningFromMap(this._kerningMap, first, second);
2499
+ }
2500
+ setKerningPairs(pairs) {
2501
+ applyKerningPairs(this._kerningMap, pairs);
2502
+ if (this._kerningEnabled) {
2503
+ this.resolveAlignment();
2504
+ }
2505
+ }
2506
+ setKerning(first, second, amount) {
2507
+ this._kerningMap.set(codesToKey(first, second), amount);
2508
+ if (this._kerningEnabled) {
2509
+ this.resolveAlignment();
2510
+ }
2511
+ }
2512
+ getKerningAmount(first, second) {
2513
+ return this._kerningMap.get(codesToKey(first, second)) ?? 0;
2514
+ }
2515
+ clearKerning() {
2516
+ this._kerningMap.clear();
2517
+ if (this._kerningEnabled) {
2518
+ this.resolveAlignment();
2519
+ }
2520
+ }
2521
+ get glyphAnchor() {
2522
+ return { ...this._glyphAnchor };
2523
+ }
2524
+ set glyphAnchor(value) {
2525
+ if (this._glyphAnchor.x !== value.x || this._glyphAnchor.y !== value.y) {
2526
+ this._glyphAnchor = { ...value };
2527
+ this._glyphs.forEach((glyph) => {
2528
+ if (!glyph.isSpace && !glyph.isLinebreak) {
2529
+ glyph.anchor.set(this._glyphAnchor.x, this._glyphAnchor.y);
2530
+ }
2531
+ });
2532
+ this.resolveAlignment();
2533
+ }
2534
+ }
2535
+ setGlyphAnchor(x, y) {
2536
+ this.glyphAnchor = { x, y: y ?? x };
2537
+ }
2538
+ get curveEnabled() {
2539
+ return this._curveEnabled;
2540
+ }
2541
+ set curveEnabled(value) {
2542
+ if (this._curveEnabled !== value) {
2543
+ this._curveEnabled = value;
2544
+ this.resolveAlignment();
2545
+ }
2546
+ }
2547
+ get curveControlXPercent() {
2548
+ return this._curveControlXPercent;
2549
+ }
2550
+ set curveControlXPercent(value) {
2551
+ if (this._curveControlXPercent !== value) {
2552
+ this._curveControlXPercent = value;
2553
+ if (this._curveEnabled) {
2554
+ this.resolveAlignment();
2555
+ }
2556
+ }
2557
+ }
2558
+ get curveControlYPercent() {
2559
+ return this._curveControlYPercent;
2560
+ }
2561
+ set curveControlYPercent(value) {
2562
+ if (this._curveControlYPercent !== value) {
2563
+ this._curveControlYPercent = value;
2564
+ if (this._curveEnabled) {
2565
+ this.resolveAlignment();
2566
+ }
2567
+ }
2568
+ }
2569
+ get fontSize() {
2570
+ return this._glyphScale;
2571
+ }
2572
+ set fontSize(value) {
2573
+ if (this._glyphScale !== value) {
2574
+ this._glyphScale = value;
2575
+ this.generateText();
2576
+ }
2577
+ }
2578
+ };
2579
+
2580
+ // ui/components/ButtonComp.ts
2581
+ var ButtonComp = class _ButtonComp extends Skinable(Container) {
2582
+ _buttonBehaviors;
2583
+ _background;
2584
+ _placeHolder;
2585
+ _icon;
2586
+ _labelText = null;
2587
+ _buttonLabel = "";
2588
+ _iconTextures = null;
2589
+ _currentState = "up";
2590
+ _enabled = true;
2591
+ _effects = /* @__PURE__ */ new Map();
2592
+ _previousState;
2593
+ _stateDataCache = /* @__PURE__ */ new Map();
2594
+ constructor(options = {}) {
2595
+ super({ label: options.label });
2596
+ this.eventMode = "static";
2597
+ this._background = new Graphics();
2598
+ this._placeHolder = new Container({ label: "placeHolder" });
2599
+ this.addChild(this._background);
2600
+ this.addChild(this._placeHolder);
2601
+ this._buttonBehaviors = new ButtonBehavior();
2602
+ this._buttonBehaviors.attachView(this);
2603
+ this.setupEventListeners();
2604
+ this.enabled = options.enabled !== false;
2605
+ if (options.text) {
2606
+ this._buttonLabel = options.text;
2607
+ }
2608
+ if (options.icon) {
2609
+ this._iconTextures = options.icon;
2610
+ }
2611
+ this.setSkinData(options.skinData || null, { mergeWithExisting: false });
2612
+ }
2613
+ setupEventListeners() {
2614
+ this._buttonBehaviors.on("stateChanged", (newState) => {
2615
+ if (this._enabled) {
2616
+ this.setState(newState.state);
2617
+ }
2618
+ });
2619
+ }
2620
+ setState(state) {
2621
+ this._previousState = this._currentState;
2622
+ this._currentState = state;
2623
+ this.updateVisualState();
2624
+ this.notifyEffectsStateChange();
2625
+ }
2626
+ _lastLayout = null;
2627
+ _lastPlaceHolderLayout = null;
2628
+ _lastBackgroundConfig;
2629
+ _lastIconConfig;
2630
+ _lastTextConfig;
2631
+ _lastZIndex;
2632
+ updateVisualState() {
2633
+ const currentStateData = this.getCurrentStateData();
2634
+ if (!currentStateData) return;
2635
+ this.updateBackground(currentStateData);
2636
+ this.updateIcon(currentStateData);
2637
+ this.updateText(currentStateData);
2638
+ if (JSON.stringify(this._lastLayout) !== JSON.stringify(currentStateData.layout)) {
2639
+ this.layout = currentStateData.layout ?? null;
2640
+ this._lastLayout = currentStateData.layout ?? null;
2641
+ }
2642
+ if (JSON.stringify(this._lastPlaceHolderLayout) !== JSON.stringify(currentStateData.placeHolderLayout)) {
2643
+ this._placeHolder.layout = currentStateData.placeHolderLayout ?? null;
2644
+ this._lastPlaceHolderLayout = currentStateData.placeHolderLayout ?? null;
2645
+ }
2646
+ if (this._lastZIndex !== currentStateData.zIndex) {
2647
+ this.zIndex = currentStateData.zIndex ?? 0;
2648
+ this._lastZIndex = currentStateData.zIndex;
2649
+ }
2650
+ }
2651
+ skinApply(skinData) {
2652
+ this._stateDataCache.clear();
2653
+ this._lastLayout = null;
2654
+ this._lastPlaceHolderLayout = null;
2655
+ this._lastBackgroundConfig = void 0;
2656
+ this._lastIconConfig = void 0;
2657
+ this._lastTextConfig = void 0;
2658
+ this._lastZIndex = void 0;
2659
+ if (skinData) {
2660
+ this.precomputeAllStates(skinData);
2661
+ }
2662
+ this.updateVisualState();
2663
+ }
2664
+ precomputeAllStates(skin) {
2665
+ const allStates = [
2666
+ "up",
2667
+ "over",
2668
+ "down",
2669
+ "disabled",
2670
+ "selected_up",
2671
+ "selected_over",
2672
+ "selected_down",
2673
+ "selected_disabled"
2674
+ ];
2675
+ for (const state of allStates) {
2676
+ const chain = _ButtonComp.stateFallbackChain[state];
2677
+ let base = "";
2678
+ let background;
2679
+ let textConfig;
2680
+ let icon;
2681
+ let layout;
2682
+ let zIndex;
2683
+ let placeHolderLayout;
2684
+ for (const stateKey of chain) {
2685
+ const stateData = skin[stateKey];
2686
+ if (stateData) {
2687
+ if (stateData.base !== void 0) {
2688
+ base = stateData.base;
2689
+ }
2690
+ if (stateData.background !== void 0) {
2691
+ background = background ? merge({}, background, stateData.background) : stateData.background;
2692
+ }
2693
+ if (stateData.textConfig !== void 0) {
2694
+ textConfig = textConfig ? merge({}, textConfig, stateData.textConfig) : stateData.textConfig;
2695
+ }
2696
+ if (stateData.icon !== void 0) {
2697
+ icon = icon ? merge({}, icon, stateData.icon) : stateData.icon;
2698
+ }
2699
+ if (stateData.layout !== void 0) {
2700
+ layout = stateData.layout;
2701
+ }
2702
+ if (stateData.placeHolderLayout !== void 0) {
2703
+ placeHolderLayout = stateData.placeHolderLayout;
2704
+ }
2705
+ if (stateData.zIndex !== void 0) {
2706
+ zIndex = stateData.zIndex;
2707
+ }
2708
+ }
2709
+ }
2710
+ this._stateDataCache.set(state, { base, background, textConfig, icon, layout, placeHolderLayout, zIndex });
2711
+ }
2712
+ }
2713
+ static stateFallbackChain = {
2714
+ // Normal flow: up -> over -> down
2715
+ up: ["up"],
2716
+ over: ["up", "over"],
2717
+ down: ["up", "over", "down"],
2718
+ // Selected flow: selected_up -> selected_over -> selected_down
2719
+ selected_up: ["up", "selected_up"],
2720
+ selected_over: ["up", "selected_up", "selected_over"],
2721
+ selected_down: ["up", "selected_up", "selected_over", "selected_down"],
2722
+ // Disabled states
2723
+ disabled: ["up", "disabled"],
2724
+ selected_disabled: ["up", "selected_up", "selected_disabled"]
2725
+ };
2726
+ getCurrentStateData() {
2727
+ return this._stateDataCache.get(this._currentState) ?? null;
2728
+ }
2729
+ updateBackground(stateData) {
2730
+ const bg = stateData.background;
2731
+ if (!bg) return;
2732
+ if (this._lastBackgroundConfig === bg) return;
2733
+ this._lastBackgroundConfig = bg;
2734
+ const base = stateData.base ?? "";
2735
+ const prevBackground = this._background;
2736
+ if ("texture" in bg) {
2737
+ this._background = this.drawSprite(this._background, bg, base);
2738
+ } else {
2739
+ this._background = this.drawGraphic(this._background, bg);
2740
+ }
2741
+ if (this._background !== prevBackground) {
2742
+ this.addChildAt(this._background, 0);
2743
+ }
2744
+ }
2745
+ updateIcon(stateData) {
2746
+ const iconConfig = stateData.icon;
2747
+ if (!this._iconTextures && this._lastIconConfig === iconConfig) return;
2748
+ this._lastIconConfig = iconConfig;
2749
+ let textureToUse = null;
2750
+ if (this._iconTextures) {
2751
+ if (typeof this._iconTextures === "string") {
2752
+ textureToUse = this._iconTextures;
2753
+ } else {
2754
+ textureToUse = this._iconTextures[this._currentState] || this._iconTextures.up || null;
2755
+ }
2756
+ }
2757
+ const base = stateData.base ?? "";
2758
+ if (textureToUse) {
2759
+ const skinIcon = iconConfig && "texture" in iconConfig ? iconConfig : void 0;
2760
+ const spriteConfig = {
2761
+ texture: textureToUse,
2762
+ alpha: (skinIcon == null ? void 0 : skinIcon.alpha) ?? 1,
2763
+ tint: (skinIcon == null ? void 0 : skinIcon.tint) ?? 16777215,
2764
+ anchor: skinIcon == null ? void 0 : skinIcon.anchor,
2765
+ layout: skinIcon == null ? void 0 : skinIcon.layout
2766
+ };
2767
+ const prevIcon = this._icon;
2768
+ this._icon = this.drawSprite(this._icon, spriteConfig, base);
2769
+ if (this._icon !== prevIcon) {
2770
+ this._placeHolder.addChild(this._icon);
2771
+ }
2772
+ return;
2773
+ }
2774
+ if (iconConfig) {
2775
+ const prevIcon = this._icon;
2776
+ if ("texture" in iconConfig) {
2777
+ this._icon = this.drawSprite(this._icon, iconConfig, base);
2778
+ } else {
2779
+ this._icon = this.drawGraphic(this._icon, iconConfig);
2780
+ }
2781
+ if (this._icon !== prevIcon) {
2782
+ this._placeHolder.addChild(this._icon);
2783
+ }
2784
+ return;
2785
+ }
2786
+ if (this._icon) {
2787
+ this._icon.destroy();
2788
+ this._icon = void 0;
2789
+ }
2790
+ }
2791
+ drawSprite(current, config, base = "") {
2792
+ let sprite;
2793
+ if (current instanceof Sprite) {
2794
+ sprite = current;
2795
+ } else {
2796
+ if (current) {
2797
+ current.destroy();
2798
+ }
2799
+ sprite = new Sprite();
2800
+ }
2801
+ const texturePath = base ? `${base}/${config.texture}` : config.texture;
2802
+ sprite.texture = Texture.from(texturePath);
2803
+ sprite.alpha = config.alpha ?? 1;
2804
+ sprite.tint = config.tint ?? 16777215;
2805
+ if (config.anchor) {
2806
+ sprite.anchor.set(config.anchor.x, config.anchor.y);
2807
+ }
2808
+ sprite.layout = config.layout ?? null;
2809
+ return sprite;
2810
+ }
2811
+ drawGraphic(current, config) {
2812
+ let graphics;
2813
+ if (current instanceof Graphics) {
2814
+ graphics = current;
2815
+ } else {
2816
+ if (current) {
2817
+ current.destroy();
2818
+ }
2819
+ graphics = new Graphics();
2820
+ }
2821
+ graphics.clear();
2822
+ if ("circle" in config) {
2823
+ graphics.circle(config.circle.radius, config.circle.radius, config.circle.radius);
2824
+ } else if ("rect" in config) {
2825
+ graphics.rect(0, 0, config.rect.width, config.rect.height);
2826
+ } else if ("roundRect" in config) {
2827
+ graphics.roundRect(
2828
+ 0,
2829
+ 0,
2830
+ config.roundRect.width,
2831
+ config.roundRect.height,
2832
+ config.roundRect.radius
2833
+ );
2834
+ }
2835
+ if (config.fill) {
2836
+ graphics.fill(config.fill);
2837
+ }
2838
+ if (config.stroke) {
2839
+ graphics.stroke(config.stroke);
2840
+ }
2841
+ graphics.layout = config.layout ?? null;
2842
+ return graphics;
2843
+ }
2844
+ updateText(stateData) {
2845
+ const textConfig = stateData.textConfig;
2846
+ const hasText = this._buttonLabel || textConfig;
2847
+ this._lastTextConfig = textConfig;
2848
+ if (!hasText) {
2849
+ if (this._labelText) {
2850
+ this._labelText.destroy();
2851
+ this._labelText = null;
2852
+ }
2853
+ return;
2854
+ }
2855
+ const needsRecreate = this._labelText && ((textConfig == null ? void 0 : textConfig.type) === "sprite" && !(this._labelText instanceof SpriteText) || (textConfig == null ? void 0 : textConfig.type) === "text" && this._labelText instanceof SpriteText || !textConfig && this._labelText instanceof SpriteText);
2856
+ if (needsRecreate) {
2857
+ this._labelText.destroy();
2858
+ this._labelText = null;
2859
+ }
2860
+ if (!this._labelText) {
2861
+ if ((textConfig == null ? void 0 : textConfig.type) === "sprite") {
2862
+ this._labelText = new SpriteText({
2863
+ text: this._buttonLabel,
2864
+ skinData: textConfig.spriteData
2865
+ });
2866
+ } else {
2867
+ this._labelText = new Text({
2868
+ text: this._buttonLabel,
2869
+ style: textConfig == null ? void 0 : textConfig.textStyle
2870
+ });
2871
+ }
2872
+ this._placeHolder.addChild(this._labelText);
2873
+ } else {
2874
+ this._labelText.text = this._buttonLabel;
2875
+ if (this._labelText instanceof Text && (textConfig == null ? void 0 : textConfig.textStyle)) {
2876
+ this._labelText.style = textConfig.textStyle;
2877
+ }
2878
+ }
2879
+ if (this._labelText && (textConfig == null ? void 0 : textConfig.layout)) {
2880
+ this._labelText.layout = textConfig.layout;
2881
+ }
2882
+ if (this._labelText instanceof Text && (textConfig == null ? void 0 : textConfig.anchor)) {
2883
+ this._labelText.anchor.set(textConfig.anchor.x, textConfig.anchor.y);
2884
+ }
2885
+ }
2886
+ // Public API
2887
+ get enabled() {
2888
+ return this._enabled;
2889
+ }
2890
+ set enabled(value) {
2891
+ this._enabled = value;
2892
+ this._buttonBehaviors.isEnabled = value;
2893
+ if (!value) {
2894
+ this.setState("disabled");
2895
+ } else {
2896
+ this.setState("up");
2897
+ }
2898
+ }
2899
+ get buttonLabel() {
2900
+ return this._buttonLabel;
2901
+ }
2902
+ set buttonLabel(value) {
2903
+ this._buttonLabel = value;
2904
+ const currentStateData = this.getCurrentStateData();
2905
+ if (currentStateData) {
2906
+ this.updateText(currentStateData);
2907
+ }
2908
+ }
2909
+ set iconTexture(iconTextures) {
2910
+ this._iconTextures = iconTextures;
2911
+ const currentStateData = this.getCurrentStateData();
2912
+ if (currentStateData) {
2913
+ this.updateIcon(currentStateData);
2914
+ }
2915
+ }
2916
+ get iconTexture() {
2917
+ return this._iconTextures;
2918
+ }
2919
+ get text() {
2920
+ return this._labelText;
2921
+ }
2922
+ get background() {
2923
+ return this._background;
2924
+ }
2925
+ get icon() {
2926
+ return this._icon;
2927
+ }
2928
+ get placeHolder() {
2929
+ return this._placeHolder;
2930
+ }
2931
+ get currentState() {
2932
+ return this._currentState;
2933
+ }
2934
+ addButtonEffect(...effects) {
2935
+ effects.forEach((effect) => {
2936
+ this._effects.set(effect.name, effect);
2937
+ effect._onAttach(this, this._currentState);
2938
+ });
2939
+ return this;
2940
+ }
2941
+ removeButtonEffect(name) {
2942
+ const effect = this._effects.get(name);
2943
+ if (effect) {
2944
+ effect._onDetach();
2945
+ return this._effects.delete(name);
2946
+ }
2947
+ return false;
2948
+ }
2949
+ hasButtonEffect(name) {
2950
+ return this._effects.has(name);
2951
+ }
2952
+ getButtonEffect(name) {
2953
+ return this._effects.get(name);
2954
+ }
2955
+ notifyEffectsStateChange() {
2956
+ this._effects.forEach((effect) => {
2957
+ effect._onStateChange(this, this._currentState, this._previousState);
2958
+ });
2959
+ }
2960
+ destroy() {
2961
+ this._effects.forEach((effect) => {
2962
+ effect._onDestroy();
2963
+ });
2964
+ this._effects.clear();
2965
+ this._buttonBehaviors.destroy();
2966
+ super.destroy();
2967
+ }
2968
+ get behavior() {
2969
+ return this._buttonBehaviors;
2970
+ }
2971
+ };
2972
+ var InputComp = class extends Skinable(Container) {
2973
+ _background;
2974
+ _textMask;
2975
+ _textLabel;
2976
+ _behavior;
2977
+ _currentState = "up";
2978
+ _isFocused = false;
2979
+ constructor(options = {}) {
2980
+ super();
2981
+ this.eventMode = "static";
2982
+ this._background = new Graphics();
2983
+ this._textLabel = new Text({
2984
+ text: "",
2985
+ style: { fontSize: 24, fill: 16777215 }
2986
+ });
2987
+ this._textMask = new Graphics();
2988
+ this.addChild(this._background);
2989
+ this.addChild(this._textLabel);
2990
+ this.addChild(this._textMask);
2991
+ this._behavior = new InputBehavior({ ...options });
2992
+ this._behavior.attachView(this);
2993
+ this._behavior.on("input", (val) => {
2994
+ this._textLabel.text = val;
2995
+ });
2996
+ this._behavior.on("stateChanged", (state) => {
2997
+ this._isFocused = state.focused;
2998
+ if (!state.enabled) {
2999
+ this.setState("disabled");
3000
+ } else if (state.focused) {
3001
+ this.setState("focused");
3002
+ } else {
3003
+ this.setState("up");
3004
+ }
3005
+ });
3006
+ this.eventMode = "static";
3007
+ this.on("pointerover", () => {
3008
+ if (this._behavior.enabled && !this._isFocused) {
3009
+ this.setState("over");
3010
+ }
3011
+ });
3012
+ this.on("pointerout", () => {
3013
+ if (this._behavior.enabled && !this._isFocused) {
3014
+ this.setState("up");
3015
+ }
3016
+ });
3017
+ this.setSkinData(options.skinData || null, { mergeWithExisting: false });
3018
+ }
3019
+ setState(state) {
3020
+ this._currentState = state;
3021
+ this.updateVisualState();
3022
+ }
3023
+ skinApply(_) {
3024
+ this.updateVisualState();
3025
+ }
3026
+ updateVisualState() {
3027
+ const current = this.getCurrentStateData();
3028
+ if (!current) return;
3029
+ this.updateBackground(current);
3030
+ this.updateTextMask(current);
3031
+ if (current.textStyle) {
3032
+ this._textLabel.style = current.textStyle;
3033
+ }
3034
+ this._textLabel.position.set(
3035
+ current.padding || 0,
3036
+ (this._background.height - this._textLabel.height) / 2
3037
+ );
3038
+ this._textLabel.mask = this._textMask;
3039
+ this._behavior.updateDomPosition();
3040
+ this.updateHitArea();
3041
+ }
3042
+ updateTextMask(current) {
3043
+ this._textMask.clear().rect(
3044
+ current.padding || 0,
3045
+ 0,
3046
+ this._background.width - (current.padding || 0) * 2,
3047
+ this._background.height
3048
+ ).fill({ color: 16777215, alpha: 1 });
3049
+ }
3050
+ getCurrentStateData() {
3051
+ const skin = this.getSkinData();
3052
+ if (!skin) return null;
3053
+ const baseData = skin.up;
3054
+ const stateData = skin[this._currentState] || {};
3055
+ return merge({}, baseData, stateData);
3056
+ }
3057
+ updateBackground(stateData) {
3058
+ const bg = stateData.background;
3059
+ if (!bg) return;
3060
+ if ("texture" in bg) {
3061
+ if (this._background) {
3062
+ this.removeChild(this._background);
3063
+ this._background.destroy();
3064
+ }
3065
+ const texture = Texture.from(bg.texture);
3066
+ this._background = new Sprite(texture);
3067
+ if (bg.alpha !== void 0) this._background.alpha = bg.alpha;
3068
+ if (bg.tint !== void 0) this._background.tint = bg.tint;
3069
+ this.addChildAt(this._background, 0);
3070
+ } else {
3071
+ if (!(this._background instanceof Graphics)) {
3072
+ if (this._background) {
3073
+ this.removeChild(this._background);
3074
+ this._background.destroy();
3075
+ }
3076
+ this._background = new Graphics();
3077
+ this.addChildAt(this._background, 0);
3078
+ }
3079
+ const graphics = this._background;
3080
+ graphics.clear();
3081
+ if ("circle" in bg) {
3082
+ graphics.circle(0, 0, bg.circle.radius);
3083
+ } else if ("rect" in bg) {
3084
+ graphics.rect(0, 0, bg.rect.width, bg.rect.height);
3085
+ } else if ("roundRect" in bg) {
3086
+ graphics.roundRect(0, 0, bg.roundRect.width, bg.roundRect.height, bg.roundRect.radius);
3087
+ }
3088
+ if (bg.fill) {
3089
+ graphics.fill(bg.fill);
3090
+ }
3091
+ if (bg.stroke) {
3092
+ graphics.stroke(bg.stroke);
3093
+ }
3094
+ }
3095
+ }
3096
+ updateHitArea() {
3097
+ if (this._background) {
3098
+ this.hitArea = new Rectangle(0, 0, this._background.width, this._background.height);
3099
+ }
3100
+ }
3101
+ get behavior() {
3102
+ return this._behavior;
3103
+ }
3104
+ destroy() {
3105
+ this._behavior.destroy();
3106
+ super.destroy();
3107
+ }
3108
+ };
3109
+ var SliderComp = class extends Skinable(Container) {
3110
+ _slider;
3111
+ _trackContainer;
3112
+ _progressContainer;
3113
+ _knobContainer;
3114
+ _currentState = "up";
3115
+ _progressGraphics = null;
3116
+ _progressConfig = null;
3117
+ constructor(options = {}) {
3118
+ super();
3119
+ this.layout = true;
3120
+ this.eventMode = "passive";
3121
+ this._trackContainer = new Container();
3122
+ this._trackContainer.eventMode = "static";
3123
+ this._progressContainer = new Container();
3124
+ this._progressContainer.eventMode = "none";
3125
+ this._knobContainer = new Container();
3126
+ this._knobContainer.eventMode = "static";
3127
+ this.addChild(this._trackContainer);
3128
+ this.addChild(this._progressContainer);
3129
+ this.addChild(this._knobContainer);
3130
+ this._slider = new ScrollbarBehavior({
3131
+ orientation: "horizontal",
3132
+ min: 0,
3133
+ max: 100,
3134
+ step: 1,
3135
+ value: 0,
3136
+ ...options
3137
+ });
3138
+ this._slider.attachViews(this._trackContainer, this._knobContainer);
3139
+ this.setupEventListeners();
3140
+ if (options.value !== void 0) {
3141
+ this._slider.value = options.value;
3142
+ }
3143
+ this.setSkinData(options.skinData || null, { mergeWithExisting: false });
3144
+ }
3145
+ setupEventListeners() {
3146
+ this._slider.on("knobOver", () => this.setState("over"));
3147
+ this._slider.on("knobDown", () => this.setState("down"));
3148
+ this._slider.on("knobUp", () => this.setState("up"));
3149
+ this._slider.on("knobOut", () => this.setState("up"));
3150
+ this._slider.on("knobClick", () => this.setState("up"));
3151
+ this._slider.on("trackOver", () => this.setState("over"));
3152
+ this._slider.on("trackDown", () => this.setState("down"));
3153
+ this._slider.on("trackUp", () => this.setState("up"));
3154
+ this._slider.on("trackOut", () => this.setState("up"));
3155
+ this._slider.on("scroll", (_value, percentage) => {
3156
+ this.updateProgressWidth(percentage);
3157
+ });
3158
+ }
3159
+ setState(state) {
3160
+ this._currentState = state;
3161
+ this.updateVisualState();
3162
+ }
3163
+ updateVisualState() {
3164
+ const currentStateData = this.getCurrentStateData();
3165
+ if (!currentStateData) return;
3166
+ if (currentStateData.orientation) {
3167
+ this._slider.orientation = currentStateData.orientation;
3168
+ }
3169
+ this.updateTrack(currentStateData);
3170
+ this.updateProgress(currentStateData);
3171
+ this.updateKnob(currentStateData);
3172
+ if (currentStateData.margin !== void 0) {
3173
+ this._slider.margin = currentStateData.margin;
3174
+ }
3175
+ if (currentStateData.scale !== void 0) {
3176
+ this.scale.set(currentStateData.scale);
3177
+ }
3178
+ this.boundsArea = this._trackContainer.getLocalBounds().rectangle;
3179
+ }
3180
+ skinApply(_) {
3181
+ this.updateVisualState();
3182
+ }
3183
+ getCurrentStateData() {
3184
+ const skin = this.getSkinData();
3185
+ if (!skin) return null;
3186
+ const baseData = skin.up;
3187
+ const stateData = skin[this._currentState] || {};
3188
+ return merge({}, baseData, stateData);
3189
+ }
3190
+ updateTrack(stateData) {
3191
+ var _a, _b;
3192
+ const trackConfig = stateData.track;
3193
+ if (!trackConfig) return;
3194
+ this._trackContainer.removeChildren();
3195
+ let newTrack;
3196
+ if ("texture" in trackConfig) {
3197
+ newTrack = new Sprite(Texture.from(trackConfig.texture));
3198
+ if (trackConfig.alpha !== void 0) newTrack.alpha = trackConfig.alpha;
3199
+ if (trackConfig.tint !== void 0) newTrack.tint = trackConfig.tint;
3200
+ } else {
3201
+ newTrack = new Graphics();
3202
+ if ("circle" in trackConfig) {
3203
+ newTrack.circle(0, 0, trackConfig.circle.radius);
3204
+ } else if ("rect" in trackConfig) {
3205
+ newTrack.rect(0, 0, trackConfig.rect.width, trackConfig.rect.height);
3206
+ } else if ("roundRect" in trackConfig) {
3207
+ newTrack.roundRect(
3208
+ 0,
3209
+ 0,
3210
+ trackConfig.roundRect.width,
3211
+ trackConfig.roundRect.height,
3212
+ trackConfig.roundRect.radius
3213
+ );
3214
+ }
3215
+ if (trackConfig.fill) {
3216
+ newTrack.fill(trackConfig.fill);
3217
+ }
3218
+ if (trackConfig.stroke) {
3219
+ newTrack.stroke(trackConfig.stroke);
3220
+ }
3221
+ }
3222
+ this._trackContainer.addChild(newTrack);
3223
+ (_b = (_a = this._slider).refreshSizes) == null ? void 0 : _b.call(_a);
3224
+ }
3225
+ updateProgress(stateData) {
3226
+ const progressConfig = stateData.progress;
3227
+ this._progressContainer.removeChildren();
3228
+ if (!progressConfig) {
3229
+ this._progressGraphics = null;
3230
+ this._progressConfig = null;
3231
+ return;
3232
+ }
3233
+ this._progressConfig = progressConfig;
3234
+ this._progressGraphics = new Graphics();
3235
+ this._progressContainer.addChild(this._progressGraphics);
3236
+ this.updateProgressWidth(this._slider.percentage);
3237
+ }
3238
+ updateProgressWidth(percentage) {
3239
+ if (!this._progressGraphics || !this._progressConfig) return;
3240
+ this._progressGraphics.clear();
3241
+ const trackWidth = this.getTrackWidth();
3242
+ const trackHeight = this.getTrackHeight();
3243
+ const trackRadius = this.getTrackRadius();
3244
+ const progressWidth = trackWidth * percentage;
3245
+ if (progressWidth <= 0 || trackHeight <= 0) return;
3246
+ if (trackRadius > 0) {
3247
+ const radius = Math.min(trackRadius, progressWidth / 2);
3248
+ this._progressGraphics.roundRect(0, 0, progressWidth, trackHeight, radius);
3249
+ } else {
3250
+ this._progressGraphics.rect(0, 0, progressWidth, trackHeight);
3251
+ }
3252
+ if (this._progressConfig.fill) {
3253
+ this._progressGraphics.fill(this._progressConfig.fill);
3254
+ }
3255
+ if (this._progressConfig.stroke) {
3256
+ this._progressGraphics.stroke(this._progressConfig.stroke);
3257
+ }
3258
+ }
3259
+ getTrackWidth() {
3260
+ var _a;
3261
+ const skin = this.getSkinData();
3262
+ if (!((_a = skin == null ? void 0 : skin.up) == null ? void 0 : _a.track)) return 0;
3263
+ const track = skin.up.track;
3264
+ if ("texture" in track) return this._trackContainer.width;
3265
+ if ("roundRect" in track) return track.roundRect.width;
3266
+ if ("rect" in track) return track.rect.width;
3267
+ return 0;
3268
+ }
3269
+ getTrackHeight() {
3270
+ var _a;
3271
+ const skin = this.getSkinData();
3272
+ if (!((_a = skin == null ? void 0 : skin.up) == null ? void 0 : _a.track)) return 0;
3273
+ const track = skin.up.track;
3274
+ if ("texture" in track) return this._trackContainer.height;
3275
+ if ("roundRect" in track) return track.roundRect.height;
3276
+ if ("rect" in track) return track.rect.height;
3277
+ return 0;
3278
+ }
3279
+ getTrackRadius() {
3280
+ var _a;
3281
+ const skin = this.getSkinData();
3282
+ if (!((_a = skin == null ? void 0 : skin.up) == null ? void 0 : _a.track)) return 0;
3283
+ const track = skin.up.track;
3284
+ if ("roundRect" in track) return track.roundRect.radius;
3285
+ return 0;
3286
+ }
3287
+ updateKnob(stateData) {
3288
+ var _a, _b;
3289
+ const knobConfig = stateData.knob;
3290
+ if (!knobConfig) return;
3291
+ this._knobContainer.removeChildren();
3292
+ let newKnob;
3293
+ if ("texture" in knobConfig) {
3294
+ newKnob = new Sprite(Texture.from(knobConfig.texture));
3295
+ if (knobConfig.alpha !== void 0) newKnob.alpha = knobConfig.alpha;
3296
+ if (knobConfig.tint !== void 0) newKnob.tint = knobConfig.tint;
3297
+ newKnob.anchor.set(0.5, 0.5);
3298
+ } else {
3299
+ newKnob = new Graphics();
3300
+ if ("circle" in knobConfig) {
3301
+ newKnob.circle(0, 0, knobConfig.circle.radius);
3302
+ } else if ("rect" in knobConfig) {
3303
+ newKnob.rect(0, 0, knobConfig.rect.width, knobConfig.rect.height);
3304
+ } else if ("roundRect" in knobConfig) {
3305
+ newKnob.roundRect(
3306
+ 0,
3307
+ 0,
3308
+ knobConfig.roundRect.width,
3309
+ knobConfig.roundRect.height,
3310
+ knobConfig.roundRect.radius
3311
+ );
3312
+ }
3313
+ if (knobConfig.fill) {
3314
+ newKnob.fill(knobConfig.fill);
3315
+ }
3316
+ if (knobConfig.stroke) {
3317
+ newKnob.stroke(knobConfig.stroke);
3318
+ }
3319
+ if ("circle" in knobConfig) {
3320
+ newKnob.pivot.set(0, 0);
3321
+ } else if ("rect" in knobConfig) {
3322
+ newKnob.pivot.set(knobConfig.rect.width / 2, knobConfig.rect.height / 2);
3323
+ } else if ("roundRect" in knobConfig) {
3324
+ newKnob.pivot.set(knobConfig.roundRect.width / 2, knobConfig.roundRect.height / 2);
3325
+ }
3326
+ }
3327
+ this._knobContainer.addChild(newKnob);
3328
+ (_b = (_a = this._slider).refreshSizes) == null ? void 0 : _b.call(_a);
3329
+ }
3330
+ // When the component is destroyed, clean up event listeners
3331
+ destroy() {
3332
+ this._slider.destroy();
3333
+ super.destroy();
3334
+ }
3335
+ get behavior() {
3336
+ return this._slider;
3337
+ }
3338
+ // Refresh sizes (call when track/knob size changes)
3339
+ refreshSizes() {
3340
+ this._slider.refreshSizes();
3341
+ }
3342
+ };
3343
+ function createSpriteButtonSkin(config) {
3344
+ const {
3345
+ states = ["up", "over", "down", "disabled"],
3346
+ separator = "_",
3347
+ background,
3348
+ icon,
3349
+ textStyle
3350
+ } = config;
3351
+ const skin = {};
3352
+ states.forEach((state) => {
3353
+ if (background) {
3354
+ if (background.perState ?? true) {
3355
+ if (!skin[state]) skin[state] = {};
3356
+ skin[state].background = {
3357
+ texture: `${background.texture}${separator}${state}`,
3358
+ ...background.config
3359
+ };
3360
+ } else if (state === "up") {
3361
+ if (!skin[state]) skin[state] = {};
3362
+ skin[state].background = {
3363
+ texture: background.texture,
3364
+ ...background.config
3365
+ };
3366
+ }
3367
+ }
3368
+ if (textStyle) {
3369
+ if (!skin[state]) skin[state] = {};
3370
+ skin[state].textConfig = { type: "text", textStyle };
3371
+ }
3372
+ if (icon) {
3373
+ if (icon.perState) {
3374
+ if (!skin[state]) skin[state] = {};
3375
+ skin[state].icon = {
3376
+ texture: `${icon.texture}${separator}${state}`,
3377
+ ...icon.config
3378
+ };
3379
+ } else if (state === "up") {
3380
+ if (!skin[state]) skin[state] = {};
3381
+ skin[state].icon = {
3382
+ texture: icon.texture,
3383
+ ...icon.config
3384
+ };
3385
+ }
3386
+ }
3387
+ });
3388
+ return skin;
3389
+ }
3390
+ function createButtonEffect(config) {
3391
+ return {
3392
+ name: config.name,
3393
+ _onAttach(button, state) {
3394
+ if (config.onAttach) {
3395
+ const ctx = {
3396
+ button,
3397
+ state,
3398
+ background: button.background,
3399
+ icon: button.icon,
3400
+ text: button.text,
3401
+ placeHolder: button.placeHolder
3402
+ };
3403
+ config.onAttach(ctx);
3404
+ }
3405
+ },
3406
+ _onDetach() {
3407
+ var _a;
3408
+ (_a = config.onDetach) == null ? void 0 : _a.call(config);
3409
+ },
3410
+ _onStateChange(button, state, previousState) {
3411
+ if (config.onStateChange) {
3412
+ const ctx = {
3413
+ button,
3414
+ state,
3415
+ previousState,
3416
+ background: button.background,
3417
+ icon: button.icon,
3418
+ text: button.text,
3419
+ placeHolder: button.placeHolder
3420
+ };
3421
+ config.onStateChange(ctx);
3422
+ }
3423
+ },
3424
+ _onDestroy() {
3425
+ var _a;
3426
+ (_a = config.onDestroy) == null ? void 0 : _a.call(config);
3427
+ }
3428
+ };
3429
+ }
3430
+ function createToggleIconSlideEffect(options) {
3431
+ const { duration = 0.1, ease = "expo.out", offset = 5 } = options ?? {};
3432
+ const updatePlaceholderPosition = (ctx, animDuration) => {
3433
+ if (!ctx.placeHolder || !ctx.background) return;
3434
+ const isSelected = ctx.state.startsWith("selected_");
3435
+ const bgWidth = ctx.background.width;
3436
+ const placeHolderBounds = ctx.placeHolder.getLocalBounds();
3437
+ if (ctx.icon) {
3438
+ const targetX = isSelected ? bgWidth - (placeHolderBounds.width + placeHolderBounds.x) - offset * 2 : -placeHolderBounds.x + offset;
3439
+ import('gsap').then(({ default: gsap }) => {
3440
+ gsap.to(ctx.placeHolder, {
3441
+ x: targetX,
3442
+ duration: animDuration,
3443
+ ease
3444
+ });
3445
+ });
3446
+ }
3447
+ };
3448
+ return createButtonEffect({
3449
+ name: "toggleIconSlide",
3450
+ onAttach(ctx) {
3451
+ updatePlaceholderPosition(ctx, 0);
3452
+ },
3453
+ onStateChange(ctx) {
3454
+ updatePlaceholderPosition(ctx, duration);
3455
+ },
3456
+ onDetach() {
3457
+ }
3458
+ });
3459
+ }
3460
+ function createFlatButtonEffect(options) {
3461
+ const {
3462
+ overAlpha = 0.85,
3463
+ downScale = 0.95,
3464
+ downAlpha = 0.9,
3465
+ disabledAlpha = 0.5,
3466
+ duration = 0.12,
3467
+ ease = "power2.out"
3468
+ } = options ?? {};
3469
+ let desatFilter = null;
3470
+ const isOverState = (state) => state === "over" || state === "selected_over";
3471
+ const isDownState = (state) => state === "down" || state === "selected_down";
3472
+ const isDisabledState = (state) => state === "disabled" || state === "selected_disabled";
3473
+ const applyState = (ctx, animDuration) => {
3474
+ import('gsap').then(({ default: gsap }) => {
3475
+ gsap.killTweensOf(ctx.button.scale);
3476
+ gsap.killTweensOf(ctx.button);
3477
+ if (isOverState(ctx.state)) {
3478
+ gsap.to(ctx.button, { alpha: 1, duration: animDuration, ease });
3479
+ gsap.to(ctx.button.scale, { x: 1, y: 1, duration: animDuration, ease });
3480
+ gsap.to(ctx.background, { alpha: overAlpha, duration: animDuration, ease });
3481
+ const content = ctx.icon ?? ctx.text;
3482
+ if (content) {
3483
+ gsap.killTweensOf(content);
3484
+ gsap.to(content, { alpha: 1, duration: animDuration, ease });
3485
+ }
3486
+ removeDesatFilter(ctx);
3487
+ } else if (isDownState(ctx.state)) {
3488
+ gsap.to(ctx.button, { alpha: downAlpha, duration: animDuration, ease });
3489
+ gsap.to(ctx.background, { alpha: 1, duration: animDuration, ease });
3490
+ const content = ctx.icon ?? ctx.text;
3491
+ if (content) {
3492
+ gsap.killTweensOf(content);
3493
+ gsap.to(content, { alpha: 1, duration: animDuration, ease });
3494
+ }
3495
+ removeDesatFilter(ctx);
3496
+ } else if (isDisabledState(ctx.state)) {
3497
+ gsap.to(ctx.button, { alpha: disabledAlpha, duration: animDuration, ease });
3498
+ gsap.to(ctx.button.scale, { x: 1, y: 1, duration: animDuration, ease });
3499
+ gsap.to(ctx.background, { alpha: 1, duration: animDuration, ease });
3500
+ applyDesatFilter(ctx);
3501
+ } else {
3502
+ gsap.to(ctx.button, { alpha: 1, duration: animDuration, ease });
3503
+ gsap.to(ctx.button.scale, { x: 1, y: 1, duration: animDuration, ease });
3504
+ gsap.to(ctx.background, { alpha: 1, duration: animDuration, ease });
3505
+ const content = ctx.icon ?? ctx.text;
3506
+ if (content) {
3507
+ gsap.killTweensOf(content);
3508
+ gsap.to(content, { alpha: 1, duration: animDuration, ease });
3509
+ }
3510
+ removeDesatFilter(ctx);
3511
+ }
3512
+ });
3513
+ };
3514
+ const applyDesatFilter = (ctx) => {
3515
+ if (!desatFilter) {
3516
+ desatFilter = new ColorMatrixFilter();
3517
+ }
3518
+ desatFilter.desaturate();
3519
+ const filters = ctx.button.filters ?? [];
3520
+ const arr = Array.isArray(filters) ? filters : [filters];
3521
+ if (!arr.includes(desatFilter)) {
3522
+ ctx.button.filters = [...arr, desatFilter];
3523
+ }
3524
+ };
3525
+ const removeDesatFilter = (ctx) => {
3526
+ if (!desatFilter) return;
3527
+ const filters = ctx.button.filters;
3528
+ if (filters) {
3529
+ const arr = Array.isArray(filters) ? filters : [filters];
3530
+ const idx = arr.indexOf(desatFilter);
3531
+ if (idx !== -1) {
3532
+ const next = arr.filter((f) => f !== desatFilter);
3533
+ ctx.button.filters = next.length > 0 ? next : null;
3534
+ }
3535
+ }
3536
+ };
3537
+ const cleanup = (button) => {
3538
+ import('gsap').then(({ default: gsap }) => {
3539
+ if (button) {
3540
+ gsap.killTweensOf(button.scale);
3541
+ gsap.killTweensOf(button);
3542
+ gsap.killTweensOf(button.background);
3543
+ const content = button.icon ?? button.text;
3544
+ if (content) gsap.killTweensOf(content);
3545
+ }
3546
+ });
3547
+ desatFilter = null;
3548
+ };
3549
+ let _button = null;
3550
+ return createButtonEffect({
3551
+ name: "flatButton",
3552
+ onAttach(ctx) {
3553
+ _button = ctx.button;
3554
+ applyState(ctx, 0);
3555
+ },
3556
+ onStateChange(ctx) {
3557
+ applyState(ctx, duration);
3558
+ },
3559
+ onDetach() {
3560
+ if (_button) {
3561
+ cleanup(_button);
3562
+ _button = null;
3563
+ }
3564
+ },
3565
+ onDestroy() {
3566
+ if (_button) {
3567
+ cleanup(_button);
3568
+ _button = null;
3569
+ }
3570
+ }
3571
+ });
3572
+ }
3573
+ function rectToBoundsLike(r) {
3574
+ const left = r.x;
3575
+ const top = r.y;
3576
+ const width = r.width;
3577
+ const height = r.height;
3578
+ const right = left + width;
3579
+ const bottom = top + height;
3580
+ return {
3581
+ left,
3582
+ right,
3583
+ top,
3584
+ bottom,
3585
+ width,
3586
+ height,
3587
+ centerX: left + width / 2,
3588
+ centerY: top + height / 2
3589
+ };
3590
+ }
3591
+ function getCommonParent(items) {
3592
+ var _a;
3593
+ const parent = (_a = items[0]) == null ? void 0 : _a.parent;
3594
+ if (!parent) throw new Error("Items must have a parent");
3595
+ for (const it of items) {
3596
+ if (it.parent !== parent) throw new Error("All items must share the same parent");
3597
+ }
3598
+ return parent;
3599
+ }
3600
+ function getLocalBoundsInParent(child, parent) {
3601
+ const world = child.getBounds();
3602
+ const topLeft = parent.toLocal(new Point(world.x, world.y));
3603
+ const bottomRight = parent.toLocal(new Point(world.x + world.width, world.y + world.height));
3604
+ const left = Math.min(topLeft.x, bottomRight.x);
3605
+ const right = Math.max(topLeft.x, bottomRight.x);
3606
+ const top = Math.min(topLeft.y, bottomRight.y);
3607
+ const bottom = Math.max(topLeft.y, bottomRight.y);
3608
+ const width = right - left;
3609
+ const height = bottom - top;
3610
+ return {
3611
+ left,
3612
+ right,
3613
+ top,
3614
+ bottom,
3615
+ width,
3616
+ height,
3617
+ centerX: left + width / 2,
3618
+ centerY: top + height / 2
3619
+ };
3620
+ }
3621
+ function getSelectionBounds(items, parent) {
3622
+ const p = parent ?? getCommonParent(items);
3623
+ let left = Infinity, right = -Infinity, top = Infinity, bottom = -Infinity;
3624
+ for (const it of items) {
3625
+ const b = getLocalBoundsInParent(it, p);
3626
+ left = Math.min(left, b.left);
3627
+ right = Math.max(right, b.right);
3628
+ top = Math.min(top, b.top);
3629
+ bottom = Math.max(bottom, b.bottom);
3630
+ }
3631
+ const width = right - left;
3632
+ const height = bottom - top;
3633
+ return {
3634
+ left,
3635
+ right,
3636
+ top,
3637
+ bottom,
3638
+ width,
3639
+ height,
3640
+ centerX: left + width / 2,
3641
+ centerY: top + height / 2
3642
+ };
3643
+ }
3644
+ function getReferenceBounds(items, options) {
3645
+ if (options == null ? void 0 : options.container) {
3646
+ const box = options.container;
3647
+ if (box instanceof Container) {
3648
+ const parent2 = box;
3649
+ const world = parent2.getBounds();
3650
+ const topLeft = parent2.toLocal(new Point(world.x, world.y));
3651
+ const bottomRight = parent2.toLocal(new Point(world.x + world.width, world.y + world.height));
3652
+ const left = Math.min(topLeft.x, bottomRight.x);
3653
+ const right = Math.max(topLeft.x, bottomRight.x);
3654
+ const top = Math.min(topLeft.y, bottomRight.y);
3655
+ const bottom = Math.max(topLeft.y, bottomRight.y);
3656
+ const width = right - left;
3657
+ const height = bottom - top;
3658
+ return {
3659
+ ref: {
3660
+ left,
3661
+ right,
3662
+ top,
3663
+ bottom,
3664
+ width,
3665
+ height,
3666
+ centerX: left + width / 2,
3667
+ centerY: top + height / 2
3668
+ },
3669
+ parent: parent2
3670
+ };
3671
+ } else {
3672
+ const parent2 = getCommonParent(items);
3673
+ return { ref: rectToBoundsLike(box), parent: parent2 };
3674
+ }
3675
+ }
3676
+ const parent = getCommonParent(items);
3677
+ if (options == null ? void 0 : options.key) {
3678
+ if (options.key.parent !== parent) throw new Error("key and items must share the same parent");
3679
+ return { ref: getLocalBoundsInParent(options.key, parent), parent };
3680
+ }
3681
+ return { ref: getSelectionBounds(items, parent), parent };
3682
+ }
3683
+ function nudgeX(child, dx) {
3684
+ child.x += dx;
3685
+ }
3686
+ function nudgeY(child, dy) {
3687
+ child.y += dy;
3688
+ }
3689
+
3690
+ // layout/Flow.ts
3691
+ function normalizeGap(opts) {
3692
+ if (typeof opts.gap === "number") return { h: opts.gap, v: opts.gap };
3693
+ if (typeof opts.gap === "object" && opts.gap) return { h: opts.gap.h ?? 0, v: opts.gap.v ?? 0 };
3694
+ const h = opts.columnGap ?? 0;
3695
+ const v = opts.rowGap ?? 0;
3696
+ return { h, v };
3697
+ }
3698
+ function normalizePadding(p) {
3699
+ if (typeof p === "number") return { top: p, right: p, bottom: p, left: p };
3700
+ return { top: (p == null ? void 0 : p.top) ?? 0, right: (p == null ? void 0 : p.right) ?? 0, bottom: (p == null ? void 0 : p.bottom) ?? 0, left: (p == null ? void 0 : p.left) ?? 0 };
3701
+ }
3702
+ function normalizeMargin(value) {
3703
+ if (value === void 0) {
3704
+ return { top: 0, right: 0, bottom: 0, left: 0 };
3705
+ }
3706
+ if (typeof value === "number") {
3707
+ return { top: value, right: value, bottom: value, left: value };
3708
+ }
3709
+ const top = value.top ?? value.y ?? 0;
3710
+ const bottom = value.bottom ?? value.y ?? 0;
3711
+ const left = value.left ?? value.x ?? 0;
3712
+ const right = value.right ?? value.x ?? 0;
3713
+ return { top, right, bottom, left };
3714
+ }
3715
+ function getFlowBounds(items, opts, parent) {
3716
+ const pad = normalizePadding(opts.padding);
3717
+ if (opts.wrap === "bounds" && opts.bounds) {
3718
+ let r;
3719
+ if (opts.bounds instanceof Rectangle) {
3720
+ r = opts.bounds;
3721
+ } else {
3722
+ const b = getLocalBoundsInParent(opts.bounds, parent);
3723
+ r = new Rectangle(b.left, b.top, b.width, b.height);
3724
+ }
3725
+ return new Rectangle(
3726
+ r.x + pad.left,
3727
+ r.y + pad.top,
3728
+ Math.max(0, r.width - pad.left - pad.right),
3729
+ Math.max(0, r.height - pad.top - pad.bottom)
3730
+ );
3731
+ }
3732
+ const sel = getSelectionBounds(items, parent);
3733
+ return new Rectangle(
3734
+ // TODO Not sure side effects check this out latter
3735
+ /*sel.left +*/
3736
+ pad.left,
3737
+ /*sel.top + */
3738
+ pad.top,
3739
+ Math.max(0, sel.width - pad.left - pad.right),
3740
+ Math.max(0, sel.height - pad.top - pad.bottom)
3741
+ );
3742
+ }
3743
+ var Flow = class {
3744
+ /**
3745
+ * Arranges containers in a flexbox-like layout.
3746
+ *
3747
+ * This method modifies container positions in-place to create the desired layout.
3748
+ * Items are sorted (if order function provided) and then arranged according to
3749
+ * direction, wrapping, alignment, and justification settings.
3750
+ *
3751
+ * @param items - Array of containers to layout
3752
+ * @param options - Layout configuration options
3753
+ *
3754
+ * @example
3755
+ * ```typescript
3756
+ * // Simple horizontal row
3757
+ * Flow.layout(items, { direction: 'row', gap: 10 });
3758
+ *
3759
+ * // Grid with 4 columns
3760
+ * Flow.layout(items, {
3761
+ * direction: 'row',
3762
+ * wrap: 'count',
3763
+ * columnCount: 4,
3764
+ * gap: { h: 10, v: 15 }
3765
+ * });
3766
+ *
3767
+ * // Centered vertical list
3768
+ * Flow.layout(items, {
3769
+ * direction: 'column',
3770
+ * align: 'center',
3771
+ * gap: 20
3772
+ * });
3773
+ * ```
3774
+ */
3775
+ static layout(items, options) {
3776
+ if (!items || items.length === 0) return;
3777
+ const opts = {
3778
+ direction: "row",
3779
+ wrap: "none",
3780
+ gap: 0,
3781
+ justify: "start",
3782
+ align: "start",
3783
+ ...options
3784
+ };
3785
+ const parent = getCommonParent(items);
3786
+ const gap = normalizeGap(opts);
3787
+ const dir = opts.direction ?? "row";
3788
+ const wrap = opts.wrap ?? "none";
3789
+ const ordered = opts.order ? [...items].sort(opts.order) : [...items];
3790
+ const area = getFlowBounds(ordered, opts, parent);
3791
+ if (wrap === "count") {
3792
+ if (dir === "row") {
3793
+ const cols = opts.columnCount ?? (opts.rowCount ? Math.ceil(ordered.length / opts.rowCount) : ordered.length);
3794
+ const lines = [];
3795
+ for (let i = 0; i < ordered.length; i += cols) lines.push(ordered.slice(i, i + cols));
3796
+ layoutLinesRow(lines, parent, area, gap, opts.justify, opts.align, opts.margins);
3797
+ } else {
3798
+ const rows = opts.rowCount ?? (opts.columnCount ? Math.ceil(ordered.length / opts.columnCount) : ordered.length);
3799
+ const columns = [];
3800
+ for (let i = 0; i < ordered.length; i += rows) columns.push(ordered.slice(i, i + rows));
3801
+ layoutLinesColumn(columns, parent, area, gap, opts.justify, opts.align, opts.margins);
3802
+ }
3803
+ return;
3804
+ }
3805
+ if (wrap === "bounds") {
3806
+ if (dir === "row") {
3807
+ const lines = [];
3808
+ let line = [];
3809
+ let lineW = 0;
3810
+ for (const it of ordered) {
3811
+ const b = getLocalBoundsInParent(it, parent);
3812
+ const needed = line.length === 0 ? b.width : gap.h + b.width;
3813
+ if (line.length > 0 && lineW + needed > area.width) {
3814
+ lines.push(line);
3815
+ line = [it];
3816
+ lineW = b.width;
3817
+ } else {
3818
+ line.push(it);
3819
+ lineW += needed;
3820
+ }
3821
+ }
3822
+ if (line.length) lines.push(line);
3823
+ layoutLinesRow(lines, parent, area, gap, opts.justify, opts.align, opts.margins);
3824
+ } else {
3825
+ const columns = [];
3826
+ let col = [];
3827
+ let colH = 0;
3828
+ for (const it of ordered) {
3829
+ const b = getLocalBoundsInParent(it, parent);
3830
+ const needed = col.length === 0 ? b.height : gap.v + b.height;
3831
+ if (col.length > 0 && colH + needed > area.height) {
3832
+ columns.push(col);
3833
+ col = [it];
3834
+ colH = b.height;
3835
+ } else {
3836
+ col.push(it);
3837
+ colH += needed;
3838
+ }
3839
+ }
3840
+ if (col.length) columns.push(col);
3841
+ layoutLinesColumn(columns, parent, area, gap, opts.justify, opts.align, opts.margins);
3842
+ }
3843
+ return;
3844
+ }
3845
+ if (wrap === "none") {
3846
+ if (dir === "row") {
3847
+ const lines = [ordered];
3848
+ layoutLinesRow(lines, parent, area, gap, opts.justify, opts.align, opts.margins);
3849
+ } else {
3850
+ const columns = [ordered];
3851
+ layoutLinesColumn(columns, parent, area, gap, opts.justify, opts.align, opts.margins);
3852
+ }
3853
+ }
3854
+ }
3855
+ };
3856
+ function layoutLinesRow(lines, parent, area, gap, justify, align, margins) {
3857
+ let y = area.y;
3858
+ for (const line of lines) {
3859
+ let contentW = 0;
3860
+ let lineH = 0;
3861
+ const sizes = line.map((it) => {
3862
+ const b = getLocalBoundsInParent(it, parent);
3863
+ lineH = Math.max(lineH, b.height);
3864
+ return b;
3865
+ });
3866
+ if (line.length > 0) contentW = sizes.reduce((s, b, i) => s + b.width + (i > 0 ? gap.h : 0), 0);
3867
+ let x = area.x;
3868
+ if (justify === "center") {
3869
+ x += Math.max(0, (area.width - contentW) / 2);
3870
+ } else if (justify === "end") {
3871
+ x += Math.max(0, area.width - contentW);
3872
+ } else if (justify === "space-between" && line.length > 1) {
3873
+ const free = Math.max(0, area.width - sizes.reduce((s, b) => s + b.width, 0));
3874
+ const g = free / (line.length - 1);
3875
+ positionRow(line, sizes, parent, x, y, lineH, { h: g, v: gap.v }, align, margins);
3876
+ y += lineH + gap.v;
3877
+ continue;
3878
+ } else if (justify === "space-around" && line.length > 0) {
3879
+ const free = Math.max(0, area.width - sizes.reduce((s, b) => s + b.width, 0));
3880
+ const g = free / line.length;
3881
+ x += g / 2;
3882
+ positionRow(line, sizes, parent, x, y, lineH, { h: g, v: gap.v }, align, margins);
3883
+ y += lineH + gap.v;
3884
+ continue;
3885
+ } else if (justify === "space-evenly" && line.length > 0) {
3886
+ const free = Math.max(0, area.width - sizes.reduce((s, b) => s + b.width, 0));
3887
+ const g = free / (line.length + 1);
3888
+ x += g;
3889
+ positionRow(line, sizes, parent, x, y, lineH, { h: g, v: gap.v }, align, margins);
3890
+ y += lineH + gap.v;
3891
+ continue;
3892
+ }
3893
+ positionRow(line, sizes, parent, x, y, lineH, gap, align, margins);
3894
+ y += lineH + gap.v;
3895
+ }
3896
+ }
3897
+ function positionRow(line, sizes, parent, x, y, lineH, gap, align, margins) {
3898
+ let cursor = x;
3899
+ for (let i = 0; i < line.length; i++) {
3900
+ const it = line[i];
3901
+ const b = sizes[i];
3902
+ const margin = normalizeMargin(margins == null ? void 0 : margins[i]);
3903
+ const dx = cursor + margin.left - b.left;
3904
+ let dy = 0;
3905
+ if (align === "start") dy = y + margin.top - b.top;
3906
+ else if (align === "center") dy = y + margin.top + (lineH - b.height) / 2 - b.top;
3907
+ else dy = y + margin.top + (lineH - b.height) - b.top;
3908
+ nudgeX(it, dx);
3909
+ nudgeY(it, dy);
3910
+ cursor += margin.left + b.width + margin.right + gap.h;
3911
+ }
3912
+ }
3913
+ function layoutLinesColumn(columns, parent, area, gap, justify, align, margins) {
3914
+ let x = area.x;
3915
+ for (const col of columns) {
3916
+ let contentH = 0;
3917
+ let colW = 0;
3918
+ const sizes = col.map((it) => {
3919
+ const b = getLocalBoundsInParent(it, parent);
3920
+ colW = Math.max(colW, b.width);
3921
+ return b;
3922
+ });
3923
+ if (col.length > 0) contentH = sizes.reduce((s, b, i) => s + b.height + (i > 0 ? gap.v : 0), 0);
3924
+ let y = area.y;
3925
+ if (justify === "center") {
3926
+ y += Math.max(0, (area.height - contentH) / 2);
3927
+ } else if (justify === "end") {
3928
+ y += Math.max(0, area.height - contentH);
3929
+ } else if (justify === "space-between" && col.length > 1) {
3930
+ const free = Math.max(0, area.height - sizes.reduce((s, b) => s + b.height, 0));
3931
+ const g = free / (col.length - 1);
3932
+ positionColumn(col, sizes, parent, x, y, colW, { h: gap.h, v: g }, align, margins);
3933
+ x += colW + gap.h;
3934
+ continue;
3935
+ } else if (justify === "space-around" && col.length > 0) {
3936
+ const free = Math.max(0, area.height - sizes.reduce((s, b) => s + b.height, 0));
3937
+ const g = free / col.length;
3938
+ y += g / 2;
3939
+ positionColumn(col, sizes, parent, x, y, colW, { h: gap.h, v: g }, align, margins);
3940
+ x += colW + gap.h;
3941
+ continue;
3942
+ } else if (justify === "space-evenly" && col.length > 0) {
3943
+ const free = Math.max(0, area.height - sizes.reduce((s, b) => s + b.height, 0));
3944
+ const g = free / (col.length + 1);
3945
+ y += g;
3946
+ positionColumn(col, sizes, parent, x, y, colW, { h: gap.h, v: g }, align, margins);
3947
+ x += colW + gap.h;
3948
+ continue;
3949
+ }
3950
+ positionColumn(col, sizes, parent, x, y, colW, gap, align, margins);
3951
+ x += colW + gap.h;
3952
+ }
3953
+ }
3954
+ function positionColumn(col, sizes, parent, x, y, colW, gap, align, margins) {
3955
+ let cursor = y;
3956
+ for (let i = 0; i < col.length; i++) {
3957
+ const it = col[i];
3958
+ const b = sizes[i];
3959
+ const margin = normalizeMargin(margins == null ? void 0 : margins[i]);
3960
+ let dx = 0;
3961
+ if (align === "start") dx = x + margin.left - b.left;
3962
+ else if (align === "center") dx = x + margin.left + (colW - b.width) / 2 - b.left;
3963
+ else dx = x + margin.left + (colW - b.width) - b.left;
3964
+ const dy = cursor + margin.top - b.top;
3965
+ nudgeX(it, dx);
3966
+ nudgeY(it, dy);
3967
+ cursor += margin.top + b.height + margin.bottom + gap.v;
3968
+ }
3969
+ }
3970
+
3971
+ // layout/Align.ts
3972
+ var Align = class {
3973
+ /**
3974
+ * Aligns containers to the left edge of the reference bounds.
3975
+ *
3976
+ * @param items - Array of containers to align
3977
+ * @param options - Alignment options to control the reference point
3978
+ *
3979
+ * @example
3980
+ * ```typescript
3981
+ * // Align to selection bounds (default)
3982
+ * Align.left([sprite1, sprite2, sprite3]);
3983
+ *
3984
+ * // Align to container
3985
+ * Align.left([sprite1, sprite2], { container: bounds });
3986
+ * ```
3987
+ */
3988
+ static left(items, options) {
3989
+ const { ref, parent } = getReferenceBounds(items, options);
3990
+ for (const it of items) {
3991
+ const b = getLocalBoundsInParent(it, parent);
3992
+ nudgeX(it, ref.left - b.left);
3993
+ }
3994
+ }
3995
+ /**
3996
+ * Aligns containers to the horizontal center of the reference bounds.
3997
+ *
3998
+ * @param items - Array of containers to align
3999
+ * @param options - Alignment options to control the reference point
4000
+ *
4001
+ * @example
4002
+ * ```typescript
4003
+ * // Center horizontally within selection
4004
+ * Align.hCenter([sprite1, sprite2, sprite3]);
4005
+ * ```
4006
+ */
4007
+ static hCenter(items, options) {
4008
+ const { ref, parent } = getReferenceBounds(items, options);
4009
+ for (const it of items) {
4010
+ const b = getLocalBoundsInParent(it, parent);
4011
+ nudgeX(it, ref.centerX - b.centerX);
4012
+ }
4013
+ }
4014
+ /**
4015
+ * Aligns containers to the right edge of the reference bounds.
4016
+ *
4017
+ * @param items - Array of containers to align
4018
+ * @param options - Alignment options to control the reference point
4019
+ */
4020
+ static right(items, options) {
4021
+ const { ref, parent } = getReferenceBounds(items, options);
4022
+ for (const it of items) {
4023
+ const b = getLocalBoundsInParent(it, parent);
4024
+ nudgeX(it, ref.right - b.right);
4025
+ }
4026
+ }
4027
+ /**
4028
+ * Aligns containers to the top edge of the reference bounds.
4029
+ *
4030
+ * @param items - Array of containers to align
4031
+ * @param options - Alignment options to control the reference point
4032
+ */
4033
+ static top(items, options) {
4034
+ const { ref, parent } = getReferenceBounds(items, options);
4035
+ for (const it of items) {
4036
+ const b = getLocalBoundsInParent(it, parent);
4037
+ nudgeY(it, ref.top - b.top);
4038
+ }
4039
+ }
4040
+ /**
4041
+ * Aligns containers to the vertical center of the reference bounds.
4042
+ *
4043
+ * @param items - Array of containers to align
4044
+ * @param options - Alignment options to control the reference point
4045
+ */
4046
+ static vCenter(items, options) {
4047
+ const { ref, parent } = getReferenceBounds(items, options);
4048
+ for (const it of items) {
4049
+ const b = getLocalBoundsInParent(it, parent);
4050
+ nudgeY(it, ref.centerY - b.centerY);
4051
+ }
4052
+ }
4053
+ /**
4054
+ * Aligns containers to the bottom edge of the reference bounds.
4055
+ *
4056
+ * @param items - Array of containers to align
4057
+ * @param options - Alignment options to control the reference point
4058
+ */
4059
+ static bottom(items, options) {
4060
+ const { ref, parent } = getReferenceBounds(items, options);
4061
+ for (const it of items) {
4062
+ const b = getLocalBoundsInParent(it, parent);
4063
+ nudgeY(it, ref.bottom - b.bottom);
4064
+ }
4065
+ }
4066
+ };
4067
+
4068
+ // ui/components/StepperComp.ts
4069
+ var StepperComp = class extends Skinable(Container) {
4070
+ _minusButton;
4071
+ _plusButton;
4072
+ _displayContainer;
4073
+ _displayBackground;
4074
+ _displayText;
4075
+ _value = 0;
4076
+ _min = 0;
4077
+ _max = 100;
4078
+ _step = 1;
4079
+ _formatFunction = (val) => val.toString();
4080
+ _enabled = true;
4081
+ _currentState = "up";
4082
+ _holdEnabled = true;
4083
+ _holdDelay = 500;
4084
+ _holdInterval = 100;
4085
+ constructor(options = {}) {
4086
+ super();
4087
+ this.layout = true;
4088
+ this.eventMode = "passive";
4089
+ this._min = options.min ?? 0;
4090
+ this._max = options.max ?? 100;
4091
+ this._step = options.step ?? 1;
4092
+ this._value = options.value ?? this._min;
4093
+ if (options.formatFunction) {
4094
+ this._formatFunction = options.formatFunction;
4095
+ }
4096
+ this._holdEnabled = options.holdEnabled ?? true;
4097
+ this._holdDelay = options.holdDelay ?? 500;
4098
+ this._holdInterval = options.holdInterval ?? 100;
4099
+ this._minusButton = new ButtonComp();
4100
+ this._minusButton.eventMode = "static";
4101
+ this._minusButton.behavior.holdDelay = this._holdDelay;
4102
+ this._minusButton.behavior.holdInterval = this._holdInterval;
4103
+ this.addChild(this._minusButton);
4104
+ this._displayContainer = new Container();
4105
+ this._displayContainer.eventMode = "passive";
4106
+ this._displayBackground = new Graphics();
4107
+ this._displayText = new Text({
4108
+ text: this._formatFunction(this._value),
4109
+ style: { fontSize: 24, fill: 16777215 }
4110
+ });
4111
+ this._displayContainer.addChild(this._displayBackground);
4112
+ this._displayContainer.addChild(this._displayText);
4113
+ this.addChild(this._displayContainer);
4114
+ this._plusButton = new ButtonComp();
4115
+ this._plusButton.eventMode = "static";
4116
+ this._plusButton.behavior.holdDelay = this._holdDelay;
4117
+ this._plusButton.behavior.holdInterval = this._holdInterval;
4118
+ this.addChild(this._plusButton);
4119
+ this.setupEventListeners();
4120
+ this.enabled = options.enabled !== false;
4121
+ this.setSkinData(options.skinData || null, { mergeWithExisting: false });
4122
+ this.updateButtonStates();
4123
+ }
4124
+ setupEventListeners() {
4125
+ this._minusButton.behavior.on("click", () => this.decrementValue());
4126
+ this._plusButton.behavior.on("click", () => this.incrementValue());
4127
+ this._minusButton.behavior.on("holdStart", () => {
4128
+ if (this._holdEnabled) {
4129
+ this.value = this._min;
4130
+ }
4131
+ });
4132
+ this._plusButton.behavior.on("holdStart", () => {
4133
+ if (this._holdEnabled) {
4134
+ this.value = this._max;
4135
+ }
4136
+ });
4137
+ this._minusButton.behavior.on("stateChanged", () => this.updateParentState());
4138
+ this._plusButton.behavior.on("stateChanged", () => this.updateParentState());
4139
+ }
4140
+ updateParentState() {
4141
+ if (!this._enabled) {
4142
+ this.setState("disabled");
4143
+ return;
4144
+ }
4145
+ const minusState = this._minusButton.currentState;
4146
+ const plusState = this._plusButton.currentState;
4147
+ if (minusState === "over" || plusState === "over") {
4148
+ this.setState("over");
4149
+ } else {
4150
+ this.setState("up");
4151
+ }
4152
+ }
4153
+ setState(state) {
4154
+ this._currentState = state;
4155
+ this.updateVisualState();
4156
+ }
4157
+ decrementValue() {
4158
+ if (!this._enabled) return;
4159
+ const newValue = this._value - this._step;
4160
+ if (newValue >= this._min) {
4161
+ this.value = newValue;
4162
+ }
4163
+ }
4164
+ incrementValue() {
4165
+ if (!this._enabled) return;
4166
+ const newValue = this._value + this._step;
4167
+ if (newValue <= this._max) {
4168
+ this.value = newValue;
4169
+ }
4170
+ }
4171
+ updateButtonStates() {
4172
+ const atMin = this._value <= this._min;
4173
+ const atMax = this._value >= this._max;
4174
+ this._minusButton.enabled = this._enabled && !atMin;
4175
+ this._plusButton.enabled = this._enabled && !atMax;
4176
+ }
4177
+ updateVisualState() {
4178
+ const currentStateData = this.getCurrentStateData();
4179
+ if (!currentStateData) return;
4180
+ this.updateDisplay(currentStateData);
4181
+ this.updateButtonSkins(currentStateData);
4182
+ this.updateHoldSettings(currentStateData);
4183
+ this.updateLayout(currentStateData);
4184
+ }
4185
+ skinApply(_) {
4186
+ this.updateVisualState();
4187
+ }
4188
+ getCurrentStateData() {
4189
+ const skin = this.getSkinData();
4190
+ if (!skin) return null;
4191
+ const baseData = skin.up;
4192
+ const stateData = skin[this._currentState] || {};
4193
+ return merge({}, baseData, stateData);
4194
+ }
4195
+ updateDisplay(stateData) {
4196
+ const displayConfig = stateData.display;
4197
+ if (!displayConfig) return;
4198
+ if ("texture" in displayConfig) {
4199
+ if (!(this._displayBackground instanceof Sprite)) {
4200
+ this._displayContainer.removeChild(this._displayBackground);
4201
+ this._displayBackground.destroy();
4202
+ this._displayBackground = new Sprite();
4203
+ this._displayContainer.addChildAt(this._displayBackground, 0);
4204
+ }
4205
+ const sprite = this._displayBackground;
4206
+ const base = stateData.base ?? "";
4207
+ const texturePath = base ? `${base}/${displayConfig.texture}` : displayConfig.texture;
4208
+ sprite.texture = Texture.from(texturePath);
4209
+ sprite.alpha = displayConfig.alpha ?? 1;
4210
+ sprite.tint = displayConfig.tint ?? 16777215;
4211
+ if (displayConfig.anchor) {
4212
+ sprite.anchor.set(displayConfig.anchor.x, displayConfig.anchor.y);
4213
+ }
4214
+ } else {
4215
+ if (!(this._displayBackground instanceof Graphics)) {
4216
+ this._displayContainer.removeChild(this._displayBackground);
4217
+ this._displayBackground.destroy();
4218
+ this._displayBackground = new Graphics();
4219
+ this._displayContainer.addChildAt(this._displayBackground, 0);
4220
+ }
4221
+ const graphics = this._displayBackground;
4222
+ graphics.clear();
4223
+ if ("circle" in displayConfig) {
4224
+ graphics.circle(0, 0, displayConfig.circle.radius);
4225
+ } else if ("rect" in displayConfig) {
4226
+ graphics.rect(0, 0, displayConfig.rect.width, displayConfig.rect.height);
4227
+ } else if ("roundRect" in displayConfig) {
4228
+ graphics.roundRect(
4229
+ 0,
4230
+ 0,
4231
+ displayConfig.roundRect.width,
4232
+ displayConfig.roundRect.height,
4233
+ displayConfig.roundRect.radius
4234
+ );
4235
+ }
4236
+ if (displayConfig.fill) {
4237
+ graphics.fill(displayConfig.fill);
4238
+ }
4239
+ if (displayConfig.stroke) {
4240
+ graphics.stroke(displayConfig.stroke);
4241
+ }
4242
+ }
4243
+ if (stateData.textStyle) {
4244
+ this._displayText.style = stateData.textStyle;
4245
+ }
4246
+ this._displayText.text = this._formatFunction(this._value);
4247
+ Align.hCenter([this._displayText], { container: this._displayContainer });
4248
+ Align.vCenter([this._displayText], { container: this._displayContainer });
4249
+ }
4250
+ updateButtonSkins(stateData) {
4251
+ if (stateData.minusButton) {
4252
+ this._minusButton.setSkinData(stateData.minusButton, { mergeWithExisting: false });
4253
+ }
4254
+ if (stateData.plusButton) {
4255
+ this._plusButton.setSkinData(stateData.plusButton, { mergeWithExisting: false });
4256
+ }
4257
+ }
4258
+ updateHoldSettings(stateData) {
4259
+ if (stateData.holdEnabled !== void 0) {
4260
+ this._holdEnabled = stateData.holdEnabled;
4261
+ }
4262
+ if (stateData.holdDelay !== void 0) {
4263
+ this._holdDelay = stateData.holdDelay;
4264
+ this._minusButton.behavior.holdDelay = this._holdDelay;
4265
+ this._plusButton.behavior.holdDelay = this._holdDelay;
4266
+ }
4267
+ if (stateData.holdInterval !== void 0) {
4268
+ this._holdInterval = stateData.holdInterval;
4269
+ this._minusButton.behavior.holdInterval = this._holdInterval;
4270
+ this._plusButton.behavior.holdInterval = this._holdInterval;
4271
+ }
4272
+ }
4273
+ updateLayout(stateData) {
4274
+ const flowOptions = stateData.flowOptions || {
4275
+ direction: "row",
4276
+ wrap: "none",
4277
+ gap: 10,
4278
+ align: "center"
4279
+ };
4280
+ Flow.layout([this._minusButton, this._displayContainer, this._plusButton], flowOptions);
4281
+ }
4282
+ get value() {
4283
+ return this._value;
4284
+ }
4285
+ set value(val) {
4286
+ const clampedValue = Math.max(this._min, Math.min(this._max, val));
4287
+ if (this._value !== clampedValue) {
4288
+ this._value = clampedValue;
4289
+ this.updateButtonStates();
4290
+ this.updateDisplayText();
4291
+ this.emit("valueChanged", this._value);
4292
+ }
4293
+ }
4294
+ updateDisplayText() {
4295
+ this._displayText.text = this._formatFunction(this._value);
4296
+ }
4297
+ get min() {
4298
+ return this._min;
4299
+ }
4300
+ set min(val) {
4301
+ this._min = val;
4302
+ if (this._value < this._min) {
4303
+ this.value = this._min;
4304
+ }
4305
+ this.updateButtonStates();
4306
+ }
4307
+ get max() {
4308
+ return this._max;
4309
+ }
4310
+ set max(val) {
4311
+ this._max = val;
4312
+ if (this._value > this._max) {
4313
+ this.value = this._max;
4314
+ }
4315
+ this.updateButtonStates();
4316
+ }
4317
+ get step() {
4318
+ return this._step;
4319
+ }
4320
+ set step(val) {
4321
+ this._step = val;
4322
+ }
4323
+ get enabled() {
4324
+ return this._enabled;
4325
+ }
4326
+ set enabled(val) {
4327
+ this._enabled = val;
4328
+ this.updateButtonStates();
4329
+ if (!val) {
4330
+ this.setState("disabled");
4331
+ } else {
4332
+ this.setState("up");
4333
+ }
4334
+ }
4335
+ get formatFunction() {
4336
+ return this._formatFunction;
4337
+ }
4338
+ set formatFunction(fn) {
4339
+ this._formatFunction = fn;
4340
+ this.updateDisplayText();
4341
+ }
4342
+ get minusButton() {
4343
+ return this._minusButton;
4344
+ }
4345
+ get plusButton() {
4346
+ return this._plusButton;
4347
+ }
4348
+ get displayText() {
4349
+ return this._displayText;
4350
+ }
4351
+ get displayBackground() {
4352
+ return this._displayBackground;
4353
+ }
4354
+ destroy() {
4355
+ this._minusButton.destroy();
4356
+ this._plusButton.destroy();
4357
+ super.destroy();
4358
+ }
4359
+ };
4360
+ var LabelBox = class extends Skinable(Container) {
4361
+ _background;
4362
+ _text;
4363
+ _currentState = "default";
4364
+ _stateDataCache = /* @__PURE__ */ new Map();
4365
+ constructor(options = {}) {
4366
+ super({ label: options.label });
4367
+ this.eventMode = "passive";
4368
+ this._background = new Graphics();
4369
+ this._text = new Text({
4370
+ text: options.text ?? "",
4371
+ style: { fontSize: 24, fill: 16777215 }
4372
+ });
4373
+ this.addChild(this._background);
4374
+ this.addChild(this._text);
4375
+ if (options.state) {
4376
+ this._currentState = options.state;
4377
+ }
4378
+ this.setSkinData(options.skinData || null, { mergeWithExisting: false });
4379
+ }
4380
+ get text() {
4381
+ return this._text.text;
4382
+ }
4383
+ set text(value) {
4384
+ this._text.text = value;
4385
+ }
4386
+ get background() {
4387
+ return this._background;
4388
+ }
4389
+ get state() {
4390
+ return this._currentState;
4391
+ }
4392
+ set state(value) {
4393
+ if (this._currentState === value) return;
4394
+ this._currentState = value;
4395
+ this.applyCurrentState();
4396
+ }
4397
+ getStateData(state) {
4398
+ const cached = this._stateDataCache.get(state);
4399
+ if (cached) return cached;
4400
+ const skin = this.getSkinData();
4401
+ if (!skin) return {};
4402
+ const baseState = skin.default;
4403
+ const stateOverride = skin[state];
4404
+ const merged = stateOverride ? merge({}, baseState, stateOverride) : baseState;
4405
+ this._stateDataCache.set(state, merged);
4406
+ return merged;
4407
+ }
4408
+ applyCurrentState() {
4409
+ const stateData = this.getStateData(this._currentState);
4410
+ this.applyStateData(stateData);
4411
+ }
4412
+ applyStateData(stateData) {
4413
+ if (stateData.background) {
4414
+ this._background.clear();
4415
+ this.drawGraphics(stateData.background);
4416
+ }
4417
+ if (stateData.textStyle) {
4418
+ this._text.style = stateData.textStyle;
4419
+ }
4420
+ if (stateData.textLayout !== void 0) {
4421
+ this._text.layout = stateData.textLayout;
4422
+ }
4423
+ if (stateData.layout !== void 0) {
4424
+ this.layout = stateData.layout;
4425
+ }
4426
+ }
4427
+ drawGraphics(config) {
4428
+ if ("circle" in config) {
4429
+ this._background.circle(config.circle.radius, config.circle.radius, config.circle.radius);
4430
+ } else if ("rect" in config) {
4431
+ this._background.rect(0, 0, config.rect.width, config.rect.height);
4432
+ } else if ("roundRect" in config) {
4433
+ this._background.roundRect(
4434
+ 0,
4435
+ 0,
4436
+ config.roundRect.width,
4437
+ config.roundRect.height,
4438
+ config.roundRect.radius
4439
+ );
4440
+ }
4441
+ if (config.fill) {
4442
+ this._background.fill(config.fill);
4443
+ }
4444
+ if (config.stroke) {
4445
+ this._background.stroke(config.stroke);
4446
+ }
4447
+ if (config.layout !== void 0) {
4448
+ this._background.layout = config.layout;
4449
+ }
4450
+ }
4451
+ skinApply(skin) {
4452
+ this._stateDataCache.clear();
4453
+ if (!skin) {
4454
+ this._background.clear();
4455
+ return;
4456
+ }
4457
+ this.applyCurrentState();
4458
+ }
4459
+ };
4460
+ var ListTableComp = class extends Skinable(Container) {
4461
+ _columns;
4462
+ _tableWidth;
4463
+ _tableHeight;
4464
+ _rowHeight;
4465
+ _headerHeight;
4466
+ _rowGap;
4467
+ _cellGap;
4468
+ _showHeader;
4469
+ _showScrollbar;
4470
+ _headerContainer;
4471
+ _headerCells = [];
4472
+ _listContainer;
4473
+ _listContent;
4474
+ _listMask;
4475
+ _scrollbar;
4476
+ _data = [];
4477
+ _rowViews = [];
4478
+ _hoveredRowIndex = -1;
4479
+ _scrollValue = 0;
4480
+ constructor(options) {
4481
+ super();
4482
+ this.eventMode = "static";
4483
+ this._columns = options.columns;
4484
+ this._tableWidth = options.tableWidth;
4485
+ this._tableHeight = options.tableHeight;
4486
+ this._rowHeight = options.rowHeight;
4487
+ this._headerHeight = options.headerHeight ?? 0;
4488
+ this._rowGap = options.rowGap ?? 0;
4489
+ this._cellGap = options.cellGap ?? 0;
4490
+ this._showHeader = options.showHeader ?? true;
4491
+ this._showScrollbar = options.showScrollbar ?? true;
4492
+ this._headerContainer = new Container({ label: "header" });
4493
+ this._headerContainer.visible = this._showHeader;
4494
+ this.addChild(this._headerContainer);
4495
+ this._listContainer = new Container({ label: "listContainer" });
4496
+ this._listContainer.eventMode = "static";
4497
+ this.addChild(this._listContainer);
4498
+ this._listContent = new Container({ label: "listContent" });
4499
+ this._listContainer.addChild(this._listContent);
4500
+ this._listMask = new Graphics();
4501
+ this._listContainer.addChild(this._listMask);
4502
+ this._listContent.mask = this._listMask;
4503
+ this._scrollbar = new SliderComp({
4504
+ orientation: "vertical",
4505
+ min: 0,
4506
+ max: 0,
4507
+ value: 0
4508
+ });
4509
+ this._scrollbar.label = "scrollbar";
4510
+ this._scrollbar.visible = this._showScrollbar;
4511
+ this.addChild(this._scrollbar);
4512
+ this._scrollbar.behavior.on("scroll", (value) => {
4513
+ this._scrollValue = value;
4514
+ this._listContent.y = -value;
4515
+ this.emit("scroll", value);
4516
+ });
4517
+ this._listContainer.on("wheel", this.onWheel.bind(this));
4518
+ this.buildHeader();
4519
+ this.updateLayout();
4520
+ if (options.skinData) {
4521
+ this.setSkinData(options.skinData, { mergeWithExisting: false });
4522
+ }
4523
+ }
4524
+ buildHeader() {
4525
+ this._headerContainer.removeChildren();
4526
+ this._headerCells = [];
4527
+ for (const column of this._columns) {
4528
+ const headerCell = new Container({ label: `header_${column.key}` });
4529
+ headerCell.boundsArea = new Rectangle(0, 0, column.width, this._rowHeight);
4530
+ const headerText = new Text({ text: column.label });
4531
+ headerCell.addChild(headerText);
4532
+ Align.hCenter([headerText], { container: headerCell.boundsArea });
4533
+ Align.vCenter([headerText], { container: headerCell.boundsArea });
4534
+ this._headerContainer.addChild(headerCell);
4535
+ this._headerCells.push(headerCell);
4536
+ }
4537
+ Flow.layout(this._headerCells, {
4538
+ direction: "row",
4539
+ gap: this._cellGap
4540
+ });
4541
+ if (this._headerHeight === 0) {
4542
+ this._headerHeight = this._headerContainer.height;
4543
+ }
4544
+ }
4545
+ updateLayout() {
4546
+ const listY = this._showHeader ? this._headerHeight : 0;
4547
+ this._listContainer.y = listY;
4548
+ this._listMask.clear();
4549
+ this._listMask.rect(0, 0, this._tableWidth, this._tableHeight);
4550
+ this._listMask.fill({ color: 16777215 });
4551
+ this._scrollbar.x = this._tableWidth + 10;
4552
+ this._scrollbar.y = listY;
4553
+ }
4554
+ updateScrollRange() {
4555
+ const contentHeight = this._rowViews.length * (this._rowHeight + this._rowGap);
4556
+ const maxScroll = Math.max(0, contentHeight - this._tableHeight);
4557
+ this._scrollbar.behavior.max = maxScroll;
4558
+ this._scrollbar.visible = this._showScrollbar && maxScroll > 0;
4559
+ }
4560
+ onWheel(event) {
4561
+ const delta = event.deltaY;
4562
+ const newValue = Math.max(0, Math.min(this._scrollbar.behavior.max, this._scrollValue + delta));
4563
+ this._scrollbar.behavior.value = newValue;
4564
+ }
4565
+ drawList(data) {
4566
+ this.clearList();
4567
+ this._data = data;
4568
+ const skin = this.getSkinData();
4569
+ for (let i = 0; i < data.length; i++) {
4570
+ this.createRow(i, data[i], skin);
4571
+ }
4572
+ const rowContainers = this._rowViews.map((v) => v.container);
4573
+ Flow.layout(rowContainers, {
4574
+ direction: "column",
4575
+ gap: this._rowGap
4576
+ });
4577
+ this.updateScrollRange();
4578
+ }
4579
+ createRow(index, item, skin) {
4580
+ var _a;
4581
+ const rowSkin = skin == null ? void 0 : skin.row;
4582
+ const container = new Container({ label: `row_${index}` });
4583
+ container.eventMode = "static";
4584
+ container.cursor = "pointer";
4585
+ const background = new Graphics();
4586
+ container.addChild(background);
4587
+ this.drawRowBackground(background, index, false, skin);
4588
+ const cells = [];
4589
+ for (const column of this._columns) {
4590
+ const cell = new Container({ label: column.key });
4591
+ cell.boundsArea = new Rectangle(0, 0, column.width, this._rowHeight);
4592
+ if (column.renderer) {
4593
+ const customContent = column.renderer(item, index, column);
4594
+ cell.addChild(customContent);
4595
+ Align.hCenter([customContent], { container: cell.boundsArea });
4596
+ Align.vCenter([customContent], { container: cell.boundsArea });
4597
+ } else {
4598
+ const value = item[column.key];
4599
+ const text = new Text({ text: String(value ?? "") });
4600
+ const cellStyle = (_a = skin == null ? void 0 : skin.cellStyles) == null ? void 0 : _a[column.key];
4601
+ if (cellStyle == null ? void 0 : cellStyle.textStyle) {
4602
+ text.style = cellStyle.textStyle;
4603
+ } else if (rowSkin == null ? void 0 : rowSkin.textStyle) {
4604
+ text.style = rowSkin.textStyle;
4605
+ }
4606
+ cell.addChild(text);
4607
+ Align.hCenter([text], { container: cell.boundsArea });
4608
+ Align.vCenter([text], { container: cell.boundsArea });
4609
+ }
4610
+ container.addChild(cell);
4611
+ cells.push(cell);
4612
+ }
4613
+ Flow.layout(cells, {
4614
+ direction: "row",
4615
+ gap: this._cellGap
4616
+ });
4617
+ container.on("pointerover", () => {
4618
+ this._hoveredRowIndex = index;
4619
+ this.drawRowBackground(background, index, true, skin);
4620
+ this.emit("rowHover", item, index);
4621
+ });
4622
+ container.on("pointerout", () => {
4623
+ this._hoveredRowIndex = -1;
4624
+ this.drawRowBackground(background, index, false, skin);
4625
+ this.emit("rowOut", item, index);
4626
+ });
4627
+ container.on("pointertap", () => {
4628
+ this.emit("rowClick", item, index);
4629
+ });
4630
+ this._listContent.addChild(container);
4631
+ this._rowViews.push({ container, background, cells });
4632
+ }
4633
+ drawRowBackground(graphics, index, isHovered, skin) {
4634
+ graphics.clear();
4635
+ const rowSkin = skin == null ? void 0 : skin.row;
4636
+ let bgConfig;
4637
+ if (isHovered && (rowSkin == null ? void 0 : rowSkin.hoverBackground)) {
4638
+ bgConfig = rowSkin.hoverBackground;
4639
+ } else if (index % 2 === 0 && (rowSkin == null ? void 0 : rowSkin.evenBackground)) {
4640
+ bgConfig = rowSkin.evenBackground;
4641
+ } else if (index % 2 === 1 && (rowSkin == null ? void 0 : rowSkin.oddBackground)) {
4642
+ bgConfig = rowSkin.oddBackground;
4643
+ } else if (rowSkin == null ? void 0 : rowSkin.background) {
4644
+ bgConfig = rowSkin.background;
4645
+ }
4646
+ if (!bgConfig) {
4647
+ graphics.rect(0, 0, this._tableWidth, this._rowHeight);
4648
+ graphics.fill({ color: index % 2 === 0 ? 1711933 : 987945, alpha: 0.5 });
4649
+ return;
4650
+ }
4651
+ if ("rect" in bgConfig) {
4652
+ graphics.rect(0, 0, bgConfig.rect.width, bgConfig.rect.height);
4653
+ } else if ("roundRect" in bgConfig) {
4654
+ graphics.roundRect(0, 0, bgConfig.roundRect.width, bgConfig.roundRect.height, bgConfig.roundRect.radius);
4655
+ } else if ("circle" in bgConfig) {
4656
+ graphics.circle(0, 0, bgConfig.circle.radius);
4657
+ }
4658
+ if (bgConfig.fill) {
4659
+ graphics.fill(bgConfig.fill);
4660
+ }
4661
+ if (bgConfig.stroke) {
4662
+ graphics.stroke(bgConfig.stroke);
4663
+ }
4664
+ }
4665
+ clearList() {
4666
+ this._listContent.removeChildren();
4667
+ this._rowViews = [];
4668
+ this._data = [];
4669
+ this._hoveredRowIndex = -1;
4670
+ this._scrollValue = 0;
4671
+ this._listContent.y = 0;
4672
+ }
4673
+ getRowAt(index) {
4674
+ var _a;
4675
+ return ((_a = this._rowViews[index]) == null ? void 0 : _a.container) ?? null;
4676
+ }
4677
+ scrollTo(index) {
4678
+ const targetY = index * (this._rowHeight + this._rowGap);
4679
+ this._scrollbar.behavior.value = Math.min(targetY, this._scrollbar.behavior.max);
4680
+ }
4681
+ get data() {
4682
+ return this._data;
4683
+ }
4684
+ get columns() {
4685
+ return this._columns;
4686
+ }
4687
+ get showHeader() {
4688
+ return this._showHeader;
4689
+ }
4690
+ set showHeader(value) {
4691
+ this._showHeader = value;
4692
+ this._headerContainer.visible = value;
4693
+ this.updateLayout();
4694
+ }
4695
+ get showScrollbar() {
4696
+ return this._showScrollbar;
4697
+ }
4698
+ set showScrollbar(value) {
4699
+ this._showScrollbar = value;
4700
+ this.updateScrollRange();
4701
+ }
4702
+ get scrollbar() {
4703
+ return this._scrollbar;
4704
+ }
4705
+ get headerContainer() {
4706
+ return this._headerContainer;
4707
+ }
4708
+ get listContainer() {
4709
+ return this._listContainer;
4710
+ }
4711
+ get listContent() {
4712
+ return this._listContent;
4713
+ }
4714
+ skinApply(skin) {
4715
+ if (!skin) return;
4716
+ this.applyHeaderSkin(skin);
4717
+ if (skin.scrollbar) {
4718
+ this._scrollbar.setSkinData(skin.scrollbar, { mergeWithExisting: false });
4719
+ }
4720
+ if (this._data.length > 0) {
4721
+ this.applyRowSkins(skin);
4722
+ }
4723
+ }
4724
+ applyHeaderSkin(skin) {
4725
+ const headerSkin = skin.header;
4726
+ if (!headerSkin) return;
4727
+ for (let i = 0; i < this._headerCells.length; i++) {
4728
+ const cell = this._headerCells[i];
4729
+ const text = cell.children[0];
4730
+ if (text && headerSkin.textStyle) {
4731
+ text.style = headerSkin.textStyle;
4732
+ }
4733
+ }
4734
+ Flow.layout(this._headerCells, {
4735
+ direction: "row",
4736
+ gap: this._cellGap
4737
+ });
4738
+ }
4739
+ applyRowSkins(skin) {
4740
+ var _a;
4741
+ const rowSkin = skin.row;
4742
+ for (let i = 0; i < this._rowViews.length; i++) {
4743
+ const view = this._rowViews[i];
4744
+ const isHovered = this._hoveredRowIndex === i;
4745
+ this.drawRowBackground(view.background, i, isHovered, skin);
4746
+ for (let j = 0; j < view.cells.length; j++) {
4747
+ const cell = view.cells[j];
4748
+ const column = this._columns[j];
4749
+ const cellStyle = (_a = skin.cellStyles) == null ? void 0 : _a[column.key];
4750
+ const text = cell.children[0];
4751
+ if (text && !(text instanceof Graphics)) {
4752
+ if (cellStyle == null ? void 0 : cellStyle.textStyle) {
4753
+ text.style = cellStyle.textStyle;
4754
+ } else if (rowSkin == null ? void 0 : rowSkin.textStyle) {
4755
+ text.style = rowSkin.textStyle;
4756
+ }
4757
+ }
4758
+ }
4759
+ Flow.layout(view.cells, {
4760
+ direction: "row",
4761
+ gap: this._cellGap
4762
+ });
4763
+ }
4764
+ const rowContainers = this._rowViews.map((v) => v.container);
4765
+ Flow.layout(rowContainers, {
4766
+ direction: "column",
4767
+ gap: this._rowGap
4768
+ });
4769
+ }
4770
+ destroy() {
4771
+ this._scrollbar.destroy();
4772
+ super.destroy();
4773
+ }
4774
+ };
4775
+
4776
+ export { ButtonBehavior, ButtonComp, InputBehavior, InputComp, LabelBox, ListTableComp, ScrollbarBehavior, Skinable, SliderComp, SpriteText, StepperComp, applyLayoutMappings, applySkinMappings, applyStyleMappings, applyTextMappings, createButtonEffect, createFlatButtonEffect, createSpriteButtonSkin, createToggleIconSlideEffect, defineGlobalSkin, mergeGlobalAndInstanceSkin, mergeSkins, parseColorValue, parseSpriteTextBBCode, resolveFontIndex, stripSpriteTextBBCode };
4777
+ //# sourceMappingURL=index.js.map
4778
+ //# sourceMappingURL=index.js.map