@number10/phaserjsx 0.3.1 → 0.4.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 (137) hide show
  1. package/dist/{TransformOriginView-KcTgaYRi.cjs → TransformOriginView-Bx81YEUU.cjs} +1077 -1500
  2. package/dist/TransformOriginView-Bx81YEUU.cjs.map +1 -0
  3. package/dist/{TransformOriginView-CzVjS16F.js → TransformOriginView-DCvId72M.js} +1200 -1623
  4. package/dist/TransformOriginView-DCvId72M.js.map +1 -0
  5. package/dist/camera/camera-fx-registry.d.ts +47 -0
  6. package/dist/camera/camera-fx-registry.d.ts.map +1 -0
  7. package/dist/camera/index.d.ts +6 -0
  8. package/dist/camera/index.d.ts.map +1 -0
  9. package/dist/camera/use-camera-fx.d.ts +59 -0
  10. package/dist/camera/use-camera-fx.d.ts.map +1 -0
  11. package/dist/components/appliers/applyBackground.d.ts +4 -0
  12. package/dist/components/appliers/applyBackground.d.ts.map +1 -1
  13. package/dist/components/appliers/applyParticles.d.ts +7 -0
  14. package/dist/components/appliers/applyParticles.d.ts.map +1 -0
  15. package/dist/components/appliers/applyParticlesLayout.d.ts +11 -0
  16. package/dist/components/appliers/applyParticlesLayout.d.ts.map +1 -0
  17. package/dist/components/creators/createParticlesLayout.d.ts +14 -0
  18. package/dist/components/creators/createParticlesLayout.d.ts.map +1 -0
  19. package/dist/components/custom/Accordion.d.ts +3 -2
  20. package/dist/components/custom/Accordion.d.ts.map +1 -1
  21. package/dist/components/custom/AlertDialog.d.ts +2 -1
  22. package/dist/components/custom/AlertDialog.d.ts.map +1 -1
  23. package/dist/components/custom/Button.d.ts +2 -1
  24. package/dist/components/custom/Button.d.ts.map +1 -1
  25. package/dist/components/custom/CharText/CharText.d.ts +2 -1
  26. package/dist/components/custom/CharText/CharText.d.ts.map +1 -1
  27. package/dist/components/custom/CharTextInput.d.ts +2 -1
  28. package/dist/components/custom/CharTextInput.d.ts.map +1 -1
  29. package/dist/components/custom/Dialog.d.ts +2 -1
  30. package/dist/components/custom/Dialog.d.ts.map +1 -1
  31. package/dist/components/custom/Divider.d.ts +2 -1
  32. package/dist/components/custom/Divider.d.ts.map +1 -1
  33. package/dist/components/custom/Dropdown.d.ts +2 -1
  34. package/dist/components/custom/Dropdown.d.ts.map +1 -1
  35. package/dist/components/custom/Graphics.d.ts +45 -0
  36. package/dist/components/custom/Graphics.d.ts.map +1 -0
  37. package/dist/components/custom/Icon.d.ts +3 -2
  38. package/dist/components/custom/Icon.d.ts.map +1 -1
  39. package/dist/components/custom/Image.d.ts +2 -1
  40. package/dist/components/custom/Image.d.ts.map +1 -1
  41. package/dist/components/custom/Joystick.d.ts +42 -0
  42. package/dist/components/custom/Joystick.d.ts.map +1 -0
  43. package/dist/components/custom/Modal.d.ts +2 -1
  44. package/dist/components/custom/Modal.d.ts.map +1 -1
  45. package/dist/components/custom/NineSlice.d.ts +2 -1
  46. package/dist/components/custom/NineSlice.d.ts.map +1 -1
  47. package/dist/components/custom/NineSliceButton.d.ts +2 -1
  48. package/dist/components/custom/NineSliceButton.d.ts.map +1 -1
  49. package/dist/components/custom/Particles.d.ts +17 -0
  50. package/dist/components/custom/Particles.d.ts.map +1 -0
  51. package/dist/components/custom/Portal.d.ts +2 -1
  52. package/dist/components/custom/Portal.d.ts.map +1 -1
  53. package/dist/components/custom/RadioButton.d.ts +2 -1
  54. package/dist/components/custom/RadioButton.d.ts.map +1 -1
  55. package/dist/components/custom/RadioGroup.d.ts +2 -5
  56. package/dist/components/custom/RadioGroup.d.ts.map +1 -1
  57. package/dist/components/custom/RefOriginView.d.ts +2 -1
  58. package/dist/components/custom/RefOriginView.d.ts.map +1 -1
  59. package/dist/components/custom/ScrollSlider.d.ts +3 -2
  60. package/dist/components/custom/ScrollSlider.d.ts.map +1 -1
  61. package/dist/components/custom/ScrollView.d.ts +13 -4
  62. package/dist/components/custom/ScrollView.d.ts.map +1 -1
  63. package/dist/components/custom/Sidebar.d.ts +2 -1
  64. package/dist/components/custom/Sidebar.d.ts.map +1 -1
  65. package/dist/components/custom/Slider.d.ts +4 -3
  66. package/dist/components/custom/Slider.d.ts.map +1 -1
  67. package/dist/components/custom/Sprite.d.ts +74 -0
  68. package/dist/components/custom/Sprite.d.ts.map +1 -0
  69. package/dist/components/custom/Tabs.d.ts +50 -0
  70. package/dist/components/custom/Tabs.d.ts.map +1 -0
  71. package/dist/components/custom/Text.d.ts +2 -1
  72. package/dist/components/custom/Text.d.ts.map +1 -1
  73. package/dist/components/custom/TileSprite.d.ts +60 -0
  74. package/dist/components/custom/TileSprite.d.ts.map +1 -0
  75. package/dist/components/custom/Toggle.d.ts +2 -1
  76. package/dist/components/custom/Toggle.d.ts.map +1 -1
  77. package/dist/components/custom/TransformOriginView.d.ts +3 -2
  78. package/dist/components/custom/TransformOriginView.d.ts.map +1 -1
  79. package/dist/components/custom/View.d.ts +2 -1
  80. package/dist/components/custom/View.d.ts.map +1 -1
  81. package/dist/components/custom/WrapText.d.ts +2 -1
  82. package/dist/components/custom/WrapText.d.ts.map +1 -1
  83. package/dist/components/custom/index.cjs +6 -1
  84. package/dist/components/custom/index.cjs.map +1 -1
  85. package/dist/components/custom/index.d.ts +3 -0
  86. package/dist/components/custom/index.d.ts.map +1 -1
  87. package/dist/components/custom/index.js +16 -11
  88. package/dist/components/index.d.ts +10 -8
  89. package/dist/components/index.d.ts.map +1 -1
  90. package/dist/components/internal/SceneWrapper.d.ts +1 -1
  91. package/dist/components/internal/SceneWrapper.d.ts.map +1 -1
  92. package/dist/components/primitives/particles.d.ts +37 -0
  93. package/dist/components/primitives/particles.d.ts.map +1 -0
  94. package/dist/core-types.d.ts +5 -0
  95. package/dist/core-types.d.ts.map +1 -1
  96. package/dist/gestures/gesture-manager.d.ts.map +1 -1
  97. package/dist/hooks.d.ts +124 -3
  98. package/dist/hooks.d.ts.map +1 -1
  99. package/dist/index.cjs +2152 -20
  100. package/dist/index.cjs.map +1 -1
  101. package/dist/index.d.ts +4 -1
  102. package/dist/index.d.ts.map +1 -1
  103. package/dist/index.js +2265 -132
  104. package/dist/index.js.map +1 -1
  105. package/dist/jsx-runtime.cjs.map +1 -1
  106. package/dist/jsx-runtime.d.ts +2 -3
  107. package/dist/jsx-runtime.d.ts.map +1 -1
  108. package/dist/jsx-runtime.js.map +1 -1
  109. package/dist/jsx-types.d.ts +8 -0
  110. package/dist/jsx-types.d.ts.map +1 -1
  111. package/dist/layout/layout-engine.d.ts.map +1 -1
  112. package/dist/particles/emit-zone.d.ts +67 -0
  113. package/dist/particles/emit-zone.d.ts.map +1 -0
  114. package/dist/particles/index.d.ts +8 -0
  115. package/dist/particles/index.d.ts.map +1 -0
  116. package/dist/particles/particle-types.d.ts +20 -0
  117. package/dist/particles/particle-types.d.ts.map +1 -0
  118. package/dist/particles/preset-registry.d.ts +46 -0
  119. package/dist/particles/preset-registry.d.ts.map +1 -0
  120. package/dist/particles/use-particles.d.ts +15 -0
  121. package/dist/particles/use-particles.d.ts.map +1 -0
  122. package/dist/particles/utils.d.ts +10 -0
  123. package/dist/particles/utils.d.ts.map +1 -0
  124. package/dist/plugin.d.ts +157 -0
  125. package/dist/plugin.d.ts.map +1 -0
  126. package/dist/theme-base.d.ts +10 -1
  127. package/dist/theme-base.d.ts.map +1 -1
  128. package/dist/theme-custom.d.ts +7 -0
  129. package/dist/theme-custom.d.ts.map +1 -1
  130. package/dist/theme-defaults.d.ts.map +1 -1
  131. package/dist/types.d.ts +18 -1
  132. package/dist/types.d.ts.map +1 -1
  133. package/dist/vdom.d.ts +28 -3
  134. package/dist/vdom.d.ts.map +1 -1
  135. package/package.json +1 -1
  136. package/dist/TransformOriginView-CzVjS16F.js.map +0 -1
  137. package/dist/TransformOriginView-KcTgaYRi.cjs.map +0 -1
package/dist/index.cjs CHANGED
@@ -1,8 +1,1883 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const vdom = require("./TransformOriginView-KcTgaYRi.cjs");
3
+ const vdom = require("./TransformOriginView-Bx81YEUU.cjs");
4
+ const Phaser$1 = require("phaser");
4
5
  const jsxRuntime = require("./jsx-runtime.cjs");
5
6
  const signalsCore = require("@preact/signals-core");
7
+ function shallowEqual(a, b) {
8
+ if (!a || !b) return a === b;
9
+ if (a.length !== b.length) return false;
10
+ return a.every((val, i) => val === b[i]);
11
+ }
12
+ function applyGraphicsProps(node, _prev, next) {
13
+ const prevDeps = node.__drawDependencies;
14
+ const nextDeps = next.dependencies;
15
+ const depsChanged = !shallowEqual(prevDeps, nextDeps);
16
+ if (depsChanged && next.onDraw) {
17
+ if (next.autoClear !== false) {
18
+ node.clear();
19
+ }
20
+ next.onDraw(node, next);
21
+ node.__drawDependencies = nextDeps;
22
+ }
23
+ }
24
+ function applyGraphicsLayout(node, prev, next) {
25
+ node.__layoutProps = next;
26
+ if (prev.width !== next.width || prev.height !== next.height || prev.headless !== next.headless) {
27
+ node.__getLayoutSize = () => {
28
+ if (next.headless ?? true) {
29
+ return { width: 0.01, height: 0.01 };
30
+ }
31
+ return {
32
+ width: typeof next.width === "number" ? next.width : 0,
33
+ height: typeof next.height === "number" ? next.height : 0
34
+ };
35
+ };
36
+ }
37
+ }
38
+ function normalizeVisible$1(visible) {
39
+ if (visible === void 0) return true;
40
+ if (typeof visible === "boolean") return visible;
41
+ if (visible === "visible") return true;
42
+ if (visible === "invisible" || visible === "none") return false;
43
+ return true;
44
+ }
45
+ function applyPhaserProps(node, prev, next) {
46
+ if (prev.alpha !== next.alpha && typeof next.alpha === "number") {
47
+ node.setAlpha?.(next.alpha);
48
+ }
49
+ if (prev.depth !== next.depth && typeof next.depth === "number") {
50
+ node.setDepth?.(next.depth);
51
+ }
52
+ if (prev.visible !== next.visible) {
53
+ const visibleValue = normalizeVisible$1(next.visible);
54
+ node.visible = visibleValue;
55
+ }
56
+ }
57
+ function applyTransformProps(node, prev, next) {
58
+ if (prev.x !== next.x && typeof next.x === "number") {
59
+ node.x = next.x;
60
+ }
61
+ if (prev.y !== next.y && typeof next.y === "number") {
62
+ node.y = next.y;
63
+ }
64
+ if (prev.rotation !== next.rotation && typeof next.rotation === "number") {
65
+ node.rotation = next.rotation;
66
+ }
67
+ const nextScale = next.scale;
68
+ const nextScaleX = next.scaleX;
69
+ const nextScaleY = next.scaleY;
70
+ const prevScale = prev.scale;
71
+ const prevScaleX = prev.scaleX;
72
+ const prevScaleY = prev.scaleY;
73
+ if (nextScale !== void 0 && nextScale !== prevScale) {
74
+ node.setScale?.(nextScale, nextScale);
75
+ } else if (nextScaleX !== prevScaleX || nextScaleY !== prevScaleY) {
76
+ const currentScaleX = node.scaleX ?? 1;
77
+ const currentScaleY = node.scaleY ?? 1;
78
+ const sx = nextScaleX ?? currentScaleX;
79
+ const sy = nextScaleY ?? currentScaleY;
80
+ node.setScale?.(sx, sy);
81
+ }
82
+ }
83
+ function createGraphicsLayout(graphics, props) {
84
+ if (props.headless === false) {
85
+ if (typeof props.width !== "number" || typeof props.height !== "number") {
86
+ throw new Error(
87
+ "Graphics component requires explicit width and height props when headless=false"
88
+ );
89
+ }
90
+ }
91
+ graphics.__layoutProps = props;
92
+ graphics.__getLayoutSize = () => {
93
+ if (graphics.__layoutProps?.headless ?? true) {
94
+ return { width: 0.01, height: 0.01 };
95
+ }
96
+ return {
97
+ width: props.width ?? 0,
98
+ height: props.height ?? 0
99
+ };
100
+ };
101
+ graphics.__drawDependencies = props.dependencies;
102
+ }
103
+ function normalizeVisible(visible) {
104
+ if (visible === void 0) return true;
105
+ if (typeof visible === "boolean") return visible;
106
+ if (visible === "visible") return true;
107
+ if (visible === "invisible" || visible === "none") return false;
108
+ return true;
109
+ }
110
+ function createPhaser(node, props) {
111
+ if (props.visible !== void 0) {
112
+ node.visible = normalizeVisible(props.visible);
113
+ }
114
+ if (props.depth !== void 0) {
115
+ node.setDepth(props.depth);
116
+ }
117
+ if (props.alpha !== void 0) {
118
+ node.setAlpha(props.alpha);
119
+ }
120
+ }
121
+ function createTransform(node, props) {
122
+ if (props.scaleX !== void 0 || props.scaleY !== void 0) {
123
+ node.setScale(
124
+ props.scaleX ?? 1,
125
+ props.scaleY ?? 1
126
+ );
127
+ }
128
+ if (props.rotation !== void 0) {
129
+ node.setRotation(props.rotation);
130
+ }
131
+ }
132
+ const graphicsCreator = (scene, props) => {
133
+ const graphics = scene.add.graphics();
134
+ graphics.setPosition(props.x ?? 0, props.y ?? 0);
135
+ createTransform(graphics, props);
136
+ createPhaser(graphics, props);
137
+ createGraphicsLayout(graphics, props);
138
+ if (props.onDraw) {
139
+ props.onDraw(graphics, props);
140
+ }
141
+ return graphics;
142
+ };
143
+ const graphicsPatcher = (node, prev, next) => {
144
+ applyTransformProps(node, prev, next);
145
+ applyPhaserProps(node, prev, next);
146
+ applyGraphicsProps(node, prev, next);
147
+ applyGraphicsLayout(node, prev, next);
148
+ };
149
+ function calculateFitScale$1(image, targetWidth, targetHeight, fit = "fill") {
150
+ const textureWidth = image.width;
151
+ const textureHeight = image.height;
152
+ if (textureWidth === 0 || textureHeight === 0) {
153
+ return { scaleX: 1, scaleY: 1 };
154
+ }
155
+ if (fit === "fill") {
156
+ return {
157
+ scaleX: targetWidth / textureWidth,
158
+ scaleY: targetHeight / textureHeight
159
+ };
160
+ }
161
+ const targetAspect = targetWidth / targetHeight;
162
+ const textureAspect = textureWidth / textureHeight;
163
+ if (fit === "contain") {
164
+ const scale = targetAspect > textureAspect ? targetHeight / textureHeight : targetWidth / textureWidth;
165
+ return { scaleX: scale, scaleY: scale };
166
+ }
167
+ if (fit === "cover") {
168
+ const scale = targetAspect < textureAspect ? targetHeight / textureHeight : targetWidth / textureWidth;
169
+ return { scaleX: scale, scaleY: scale };
170
+ }
171
+ return { scaleX: 1, scaleY: 1 };
172
+ }
173
+ function applyImageProps(image, prev, next) {
174
+ const textureChanged = prev.texture !== next.texture || prev.frame !== next.frame;
175
+ if (textureChanged && next.texture) {
176
+ image.setTexture(next.texture, next.frame);
177
+ }
178
+ if (prev.tint !== next.tint) {
179
+ if (typeof next.tint === "number") {
180
+ image.setTint(next.tint);
181
+ } else {
182
+ image.clearTint();
183
+ }
184
+ }
185
+ if (prev.originX !== next.originX || prev.originY !== next.originY) {
186
+ const originX = next.originX ?? image.originX;
187
+ const originY = next.originY ?? image.originY;
188
+ image.setOrigin(originX, originY);
189
+ }
190
+ const displayWidthChanged = prev.displayWidth !== next.displayWidth;
191
+ const displayHeightChanged = prev.displayHeight !== next.displayHeight;
192
+ const fitChanged = prev.fit !== next.fit;
193
+ if (displayWidthChanged || displayHeightChanged || fitChanged || textureChanged) {
194
+ if (typeof next.displayWidth === "number" && typeof next.displayHeight === "number") {
195
+ const { scaleX, scaleY } = calculateFitScale$1(
196
+ image,
197
+ next.displayWidth,
198
+ next.displayHeight,
199
+ next.fit
200
+ );
201
+ image.setScale(scaleX, scaleY);
202
+ } else if (typeof next.displayWidth === "number") {
203
+ const scale = next.displayWidth / image.width;
204
+ image.setScale(scale);
205
+ } else if (typeof next.displayHeight === "number") {
206
+ const scale = next.displayHeight / image.height;
207
+ image.setScale(scale, scale);
208
+ }
209
+ }
210
+ }
211
+ function applyImageLayout(image, prev, next) {
212
+ image.__layoutProps = next;
213
+ if (prev.headless !== next.headless) {
214
+ image.__getLayoutSize = () => {
215
+ if (image.__layoutProps?.headless) {
216
+ return { width: 0.01, height: 0.01 };
217
+ }
218
+ return {
219
+ width: image.displayWidth,
220
+ height: image.displayHeight
221
+ };
222
+ };
223
+ }
224
+ }
225
+ function createImageLayout(image, props) {
226
+ image.__layoutProps = props;
227
+ image.__getLayoutSize = () => {
228
+ if (image.__layoutProps?.headless) {
229
+ return { width: 0.01, height: 0.01 };
230
+ }
231
+ return {
232
+ width: image.displayWidth,
233
+ height: image.displayHeight
234
+ };
235
+ };
236
+ }
237
+ const imageCreator = (scene, props) => {
238
+ const image = scene.add.image(props.x ?? 0, props.y ?? 0, props.texture, props.frame);
239
+ if (props.headless) {
240
+ image.setOrigin(0.5, 0.5);
241
+ } else {
242
+ image.setOrigin(0, 0);
243
+ }
244
+ if (props.originX !== void 0 || props.originY !== void 0) {
245
+ image.setOrigin(props.originX ?? image.originX, props.originY ?? image.originY);
246
+ }
247
+ const normalizedProps = { ...props };
248
+ if (props.headless) {
249
+ delete normalizedProps.padding;
250
+ delete normalizedProps.margin;
251
+ delete normalizedProps.gap;
252
+ } else {
253
+ if (normalizedProps.rotation !== void 0) {
254
+ delete normalizedProps.rotation;
255
+ }
256
+ }
257
+ createTransform(image, normalizedProps);
258
+ createPhaser(image, normalizedProps);
259
+ if (props.tint !== void 0) {
260
+ image.setTint(props.tint);
261
+ }
262
+ if (props.displayWidth !== void 0 || props.displayHeight !== void 0) {
263
+ if (props.displayWidth !== void 0 && props.displayHeight !== void 0) {
264
+ const fit = props.fit ?? "fill";
265
+ const textureWidth = image.width;
266
+ const textureHeight = image.height;
267
+ if (textureWidth > 0 && textureHeight > 0) {
268
+ if (fit === "fill") {
269
+ image.setDisplaySize(props.displayWidth, props.displayHeight);
270
+ } else if (fit === "contain") {
271
+ const targetAspect = props.displayWidth / props.displayHeight;
272
+ const textureAspect = textureWidth / textureHeight;
273
+ const scale = targetAspect > textureAspect ? props.displayHeight / textureHeight : props.displayWidth / textureWidth;
274
+ image.setScale(scale);
275
+ } else if (fit === "cover") {
276
+ const targetAspect = props.displayWidth / props.displayHeight;
277
+ const textureAspect = textureWidth / textureHeight;
278
+ const scale = targetAspect < textureAspect ? props.displayHeight / textureHeight : props.displayWidth / textureWidth;
279
+ image.setScale(scale);
280
+ }
281
+ }
282
+ } else if (props.displayWidth !== void 0) {
283
+ const scale = props.displayWidth / image.width;
284
+ image.setScale(scale);
285
+ } else if (props.displayHeight !== void 0) {
286
+ const scale = props.displayHeight / image.height;
287
+ image.setScale(scale);
288
+ }
289
+ }
290
+ createImageLayout(image, normalizedProps);
291
+ if (props.onReady) {
292
+ props.onReady(image);
293
+ }
294
+ return image;
295
+ };
296
+ const imagePatcher = (node, prev, next) => {
297
+ if (prev.headless !== next.headless) {
298
+ if (next.headless) {
299
+ node.setOrigin(0.5, 0.5);
300
+ } else {
301
+ node.setOrigin(0, 0);
302
+ }
303
+ }
304
+ const normalizedPrev = { ...prev };
305
+ const normalizedNext = { ...next };
306
+ if (next.headless) {
307
+ delete normalizedNext.padding;
308
+ delete normalizedNext.margin;
309
+ delete normalizedNext.gap;
310
+ } else {
311
+ if (normalizedNext.rotation !== void 0) {
312
+ delete normalizedNext.rotation;
313
+ }
314
+ }
315
+ if (prev.headless) {
316
+ delete normalizedPrev.padding;
317
+ delete normalizedPrev.margin;
318
+ delete normalizedPrev.gap;
319
+ } else {
320
+ if (normalizedPrev.rotation !== void 0) {
321
+ delete normalizedPrev.rotation;
322
+ }
323
+ }
324
+ applyTransformProps(node, normalizedPrev, normalizedNext);
325
+ applyPhaserProps(node, normalizedPrev, normalizedNext);
326
+ applyImageProps(node, normalizedPrev, normalizedNext);
327
+ applyImageLayout(node, normalizedPrev, normalizedNext);
328
+ };
329
+ function applyNineSliceProps(nineSlice, prev, next) {
330
+ const textureChanged = prev.texture !== next.texture || prev.frame !== next.frame;
331
+ if (textureChanged && next.texture) {
332
+ nineSlice.setTexture(next.texture, next.frame);
333
+ }
334
+ const sliceChanged = prev.leftWidth !== next.leftWidth || prev.rightWidth !== next.rightWidth || prev.topHeight !== next.topHeight || prev.bottomHeight !== next.bottomHeight;
335
+ if (sliceChanged) {
336
+ const width = typeof next.width === "number" ? next.width : nineSlice.width;
337
+ const height = typeof next.height === "number" ? next.height : nineSlice.height;
338
+ nineSlice.setSlices(
339
+ width,
340
+ height,
341
+ next.leftWidth ?? prev.leftWidth ?? 0,
342
+ next.rightWidth ?? prev.rightWidth ?? 0,
343
+ next.topHeight ?? prev.topHeight,
344
+ next.bottomHeight ?? prev.bottomHeight
345
+ );
346
+ }
347
+ const prevWidth = typeof prev.width === "number" ? prev.width : nineSlice.width;
348
+ const nextWidth = typeof next.width === "number" ? next.width : nineSlice.width;
349
+ const prevHeight = typeof prev.height === "number" ? prev.height : nineSlice.height;
350
+ const nextHeight = typeof next.height === "number" ? next.height : nineSlice.height;
351
+ if (prevWidth !== nextWidth || prevHeight !== nextHeight) {
352
+ nineSlice.setSize(nextWidth, nextHeight);
353
+ }
354
+ if (prev.tint !== next.tint) {
355
+ if (next.tint !== void 0) {
356
+ nineSlice.setTint(next.tint);
357
+ } else {
358
+ nineSlice.clearTint();
359
+ }
360
+ }
361
+ }
362
+ function applyNineSliceLayout(nineSlice, prev, next) {
363
+ nineSlice.__layoutProps = next;
364
+ if (prev.width !== next.width || prev.height !== next.height) {
365
+ nineSlice.__getLayoutSize = () => {
366
+ return {
367
+ width: nineSlice.width,
368
+ height: nineSlice.height
369
+ };
370
+ };
371
+ }
372
+ }
373
+ function createNineSliceLayout(nineSlice, props) {
374
+ nineSlice.__layoutProps = props;
375
+ nineSlice.__getLayoutSize = () => {
376
+ return {
377
+ width: nineSlice.width,
378
+ height: nineSlice.height
379
+ };
380
+ };
381
+ }
382
+ const nineSliceCreator = (scene, props) => {
383
+ const initialWidth = typeof props.width === "number" ? props.width : 64;
384
+ const initialHeight = typeof props.height === "number" ? props.height : 64;
385
+ const nineSlice = scene.add.nineslice(
386
+ props.x ?? 0,
387
+ props.y ?? 0,
388
+ props.texture,
389
+ props.frame,
390
+ initialWidth,
391
+ initialHeight,
392
+ props.leftWidth,
393
+ props.rightWidth,
394
+ props.topHeight,
395
+ props.bottomHeight
396
+ );
397
+ nineSlice.setOrigin(0, 0);
398
+ if (props.tint !== void 0) {
399
+ nineSlice.setTint(props.tint);
400
+ }
401
+ createTransform(nineSlice, props);
402
+ createPhaser(nineSlice, props);
403
+ createNineSliceLayout(nineSlice, props);
404
+ return nineSlice;
405
+ };
406
+ const nineSlicePatcher = (node, prev, next) => {
407
+ applyTransformProps(node, prev, next);
408
+ applyPhaserProps(node, prev, next);
409
+ applyNineSliceProps(node, prev, next);
410
+ applyNineSliceLayout(node, prev, next);
411
+ };
412
+ function resolveNumericSize(value) {
413
+ return typeof value === "number" ? value : void 0;
414
+ }
415
+ function resolveZoneSize(zone, fallback) {
416
+ const size = {};
417
+ const width = zone.width ?? fallback.width;
418
+ const height = zone.height ?? fallback.height;
419
+ if (width !== void 0) size.width = width;
420
+ if (height !== void 0) size.height = height;
421
+ return size;
422
+ }
423
+ function buildZoneSource(zone, fallbackSize) {
424
+ const baseX = zone.x ?? 0;
425
+ const baseY = zone.y ?? 0;
426
+ const { width, height } = resolveZoneSize(zone, fallbackSize);
427
+ switch (zone.shape) {
428
+ case "rect":
429
+ return new Phaser$1.Geom.Rectangle(baseX, baseY, width ?? 1, height ?? 1);
430
+ case "circle":
431
+ return new Phaser$1.Geom.Circle(baseX, baseY, zone.radius ?? 1);
432
+ case "ellipse":
433
+ return new Phaser$1.Geom.Ellipse(baseX, baseY, width ?? 1, height ?? 1);
434
+ case "line":
435
+ return new Phaser$1.Geom.Line(
436
+ baseX,
437
+ baseY,
438
+ zone.endX ?? baseX + (width ?? 1),
439
+ zone.endY ?? baseY + (height ?? 1)
440
+ );
441
+ default:
442
+ return void 0;
443
+ }
444
+ }
445
+ function buildEmitZone(zone, fallbackSize = {}) {
446
+ const type = zone.type ?? "random";
447
+ const source = buildZoneSource(zone, fallbackSize);
448
+ if (!source) return void 0;
449
+ return { type, source };
450
+ }
451
+ function buildEmitZoneFromLayout(zone, width, height) {
452
+ const fallback = {};
453
+ const resolvedWidth = resolveNumericSize(width);
454
+ const resolvedHeight = resolveNumericSize(height);
455
+ if (resolvedWidth !== void 0) fallback.width = resolvedWidth;
456
+ if (resolvedHeight !== void 0) fallback.height = resolvedHeight;
457
+ return buildEmitZone(zone, fallback);
458
+ }
459
+ function buildDeathZone(zone, fallbackSize = {}) {
460
+ const type = zone.mode ?? "onEnter";
461
+ const source = buildZoneSource(zone, fallbackSize);
462
+ if (!source) return void 0;
463
+ return { type, source };
464
+ }
465
+ function buildDeathZonesFromLayout(zones, width, height) {
466
+ if (!zones) return void 0;
467
+ const list = Array.isArray(zones) ? zones : [zones];
468
+ const fallback = {};
469
+ const resolvedWidth = resolveNumericSize(width);
470
+ const resolvedHeight = resolveNumericSize(height);
471
+ if (resolvedWidth !== void 0) fallback.width = resolvedWidth;
472
+ if (resolvedHeight !== void 0) fallback.height = resolvedHeight;
473
+ const deathZones = list.map((zone) => buildDeathZone(zone, fallback)).filter((zone) => Boolean(zone));
474
+ return deathZones.length > 0 ? deathZones : void 0;
475
+ }
476
+ const PARTICLE_PRESET_REGISTRY = {
477
+ explosion: {
478
+ speed: { min: 120, max: 320 },
479
+ scale: { start: 1, end: 0 },
480
+ alpha: { start: 1, end: 0 },
481
+ lifespan: 600,
482
+ quantity: 24,
483
+ blendMode: "ADD"
484
+ },
485
+ trail: {
486
+ speed: { min: 30, max: 80 },
487
+ scale: { start: 0.6, end: 0 },
488
+ alpha: { start: 0.8, end: 0 },
489
+ lifespan: 700,
490
+ frequency: 40
491
+ },
492
+ rain: {
493
+ speed: { min: 320, max: 520 },
494
+ angle: { min: 80, max: 100 },
495
+ scale: { start: 0.5, end: 0.2 },
496
+ alpha: { start: 0.6, end: 0.1 },
497
+ lifespan: 1e3,
498
+ frequency: 20
499
+ },
500
+ snow: {
501
+ speed: { min: 40, max: 120 },
502
+ angle: { min: 80, max: 100 },
503
+ gravityY: 8,
504
+ scale: { start: 0.6, end: 0.6 },
505
+ alpha: { start: 0.8, end: 0.3 },
506
+ lifespan: 2600,
507
+ frequency: 80
508
+ },
509
+ sparkle: {
510
+ speed: { min: 20, max: 60 },
511
+ scale: { start: 0.4, end: 0 },
512
+ alpha: { start: 1, end: 0 },
513
+ lifespan: 500,
514
+ frequency: 60,
515
+ blendMode: "ADD"
516
+ }
517
+ };
518
+ function resolveParticlePreset(preset, config = {}) {
519
+ const base = preset ? PARTICLE_PRESET_REGISTRY[preset] : void 0;
520
+ if (preset && !base) {
521
+ console.warn(`[Particles] Preset "${String(preset)}" not found in registry`);
522
+ }
523
+ return {
524
+ ...base ?? {},
525
+ ...config
526
+ };
527
+ }
528
+ function isParticleEmitter(target) {
529
+ return !!target && typeof target.explode === "function";
530
+ }
531
+ function getFirstEmitter(manager) {
532
+ if (!manager) return null;
533
+ if (manager.__emitter) return manager.__emitter;
534
+ const emitters = manager.emitters;
535
+ if (Array.isArray(emitters)) {
536
+ return emitters[0] ?? null;
537
+ }
538
+ if (emitters && "list" in emitters && Array.isArray(emitters.list)) {
539
+ return emitters.list[0] ?? null;
540
+ }
541
+ return null;
542
+ }
543
+ function applyEmitterConfig(emitter, config) {
544
+ if (!emitter) return;
545
+ const withConfig = emitter;
546
+ if (withConfig.setConfig) {
547
+ withConfig.setConfig(config);
548
+ return;
549
+ }
550
+ if (withConfig.fromJSON) {
551
+ withConfig.fromJSON(config);
552
+ return;
553
+ }
554
+ Object.assign(emitter, config);
555
+ }
556
+ function applyEmitZone(emitter, emitZone) {
557
+ if (!emitter || !emitZone) return;
558
+ const withZone = emitter;
559
+ if (withZone.setEmitZone) {
560
+ withZone.setEmitZone(emitZone);
561
+ return;
562
+ }
563
+ }
564
+ function applyDeathZone(emitter, deathZone) {
565
+ if (!emitter) return;
566
+ const withZone = emitter;
567
+ const isDefined = (value) => value !== null && value !== void 0;
568
+ const normalized = Array.isArray(deathZone) ? deathZone.filter(isDefined) : deathZone ? [deathZone] : [];
569
+ const hasZone = normalized.length > 0;
570
+ if (hasZone && withZone.setDeathZone) {
571
+ withZone.setDeathZone(normalized);
572
+ return;
573
+ }
574
+ if (!hasZone) {
575
+ if (withZone.clearDeathZones) {
576
+ withZone.clearDeathZones();
577
+ return;
578
+ }
579
+ if (withZone.deathZones) {
580
+ withZone.deathZones = [];
581
+ }
582
+ return;
583
+ }
584
+ if (withZone.clearDeathZones) {
585
+ withZone.clearDeathZones();
586
+ }
587
+ if (withZone.addDeathZone) {
588
+ withZone.addDeathZone(normalized);
589
+ return;
590
+ }
591
+ if (withZone.deathZones) {
592
+ withZone.deathZones = normalized;
593
+ }
594
+ }
595
+ function mergeDeathZones(base, extra) {
596
+ const baseList = Array.isArray(base) ? base : base ? [base] : [];
597
+ const extraList = extra ?? [];
598
+ const merged = [...baseList, ...extraList];
599
+ return merged.length > 0 ? merged : void 0;
600
+ }
601
+ function applyParticlesProps(manager, prev, next) {
602
+ if (!manager) return;
603
+ const textureChanged = prev.texture !== next.texture || prev.frame !== next.frame;
604
+ if (textureChanged && next.texture && "setTexture" in manager && manager.setTexture) {
605
+ manager.setTexture(next.texture, next.frame);
606
+ }
607
+ const configChanged = prev.preset !== next.preset || prev.config !== next.config || prev.zone !== next.zone || prev.excludeZones !== next.excludeZones || prev.width !== next.width || prev.height !== next.height;
608
+ if (configChanged) {
609
+ const resolvedConfig = resolveParticlePreset(next.preset, next.config);
610
+ let emitter = null;
611
+ if (isParticleEmitter(manager)) {
612
+ emitter = manager;
613
+ } else {
614
+ const managerLike = manager;
615
+ emitter = managerLike.__emitter ?? getFirstEmitter(managerLike);
616
+ if (!emitter && managerLike.createEmitter) {
617
+ const created = managerLike.createEmitter(resolvedConfig);
618
+ emitter = created ?? null;
619
+ }
620
+ managerLike.__emitter = emitter;
621
+ }
622
+ if (!emitter) return;
623
+ applyEmitterConfig(emitter, resolvedConfig);
624
+ if (next.zone) {
625
+ const emitZone = buildEmitZoneFromLayout(next.zone, next.width, next.height);
626
+ if (emitZone) {
627
+ applyEmitZone(emitter, emitZone);
628
+ }
629
+ }
630
+ const deathZones = buildDeathZonesFromLayout(next.excludeZones, next.width, next.height);
631
+ const combined = mergeDeathZones(
632
+ resolvedConfig.deathZone,
633
+ deathZones
634
+ );
635
+ applyDeathZone(emitter, combined);
636
+ }
637
+ }
638
+ function applyParticlesLayout(particles, _prev, next) {
639
+ particles.__layoutProps = next;
640
+ }
641
+ function createParticlesLayout(particles, props) {
642
+ particles.__layoutProps = props;
643
+ particles.__getLayoutSize = () => ({ width: 0.01, height: 0.01 });
644
+ }
645
+ const particlesCreator = (scene, props) => {
646
+ const resolvedConfig = {
647
+ ...resolveParticlePreset(props.preset, props.config)
648
+ };
649
+ if (props.zone) {
650
+ const emitZone = buildEmitZoneFromLayout(props.zone, props.width, props.height);
651
+ if (emitZone) {
652
+ const configWithZone = resolvedConfig;
653
+ configWithZone.emitZone = emitZone;
654
+ }
655
+ }
656
+ const particles = scene.add.particles(
657
+ props.x ?? 0,
658
+ props.y ?? 0,
659
+ props.texture,
660
+ resolvedConfig
661
+ );
662
+ if (props.frame !== void 0) {
663
+ const configWithFrame = resolvedConfig;
664
+ configWithFrame.frame = props.frame;
665
+ if ("setTexture" in particles && particles.setTexture) {
666
+ particles.setTexture(props.texture, props.frame);
667
+ }
668
+ }
669
+ const emitter = isParticleEmitter(particles) ? particles : getFirstEmitter(particles);
670
+ if (!isParticleEmitter(particles)) {
671
+ particles.__emitter = emitter;
672
+ }
673
+ if ("setOrigin" in particles && typeof particles.setOrigin === "function") {
674
+ particles.setOrigin(0, 0);
675
+ }
676
+ createTransform(particles, props);
677
+ createPhaser(particles, props);
678
+ createParticlesLayout(particles, props);
679
+ if (props.excludeZones && emitter) {
680
+ const deathZones = buildDeathZonesFromLayout(props.excludeZones, props.width, props.height);
681
+ const combinedDeathZones = mergeDeathZones(
682
+ resolvedConfig.deathZone,
683
+ deathZones
684
+ );
685
+ if (combinedDeathZones) {
686
+ applyDeathZone(emitter, combinedDeathZones);
687
+ }
688
+ }
689
+ if (props.onReady) {
690
+ props.onReady(particles);
691
+ }
692
+ return particles;
693
+ };
694
+ const particlesPatcher = (node, prev, next) => {
695
+ applyTransformProps(node, prev, next);
696
+ applyPhaserProps(node, prev, next);
697
+ applyParticlesProps(node, prev, next);
698
+ applyParticlesLayout(node, prev, next);
699
+ };
700
+ function getOriginalTextureDimensions(sprite) {
701
+ const frame = sprite.frame;
702
+ return {
703
+ width: frame.width,
704
+ height: frame.height
705
+ };
706
+ }
707
+ function calculateFitScale(sprite, targetWidth, targetHeight, fit = "fill") {
708
+ const { width: textureWidth, height: textureHeight } = getOriginalTextureDimensions(sprite);
709
+ if (textureWidth === 0 || textureHeight === 0) {
710
+ return { scaleX: 1, scaleY: 1 };
711
+ }
712
+ if (fit === "fill") {
713
+ return {
714
+ scaleX: targetWidth / textureWidth,
715
+ scaleY: targetHeight / textureHeight
716
+ };
717
+ }
718
+ const targetAspect = targetWidth / targetHeight;
719
+ const textureAspect = textureWidth / textureHeight;
720
+ if (fit === "contain") {
721
+ const scale = targetAspect > textureAspect ? targetHeight / textureHeight : targetWidth / textureWidth;
722
+ return { scaleX: scale, scaleY: scale };
723
+ }
724
+ if (fit === "cover") {
725
+ const scale = targetAspect < textureAspect ? targetHeight / textureHeight : targetWidth / textureWidth;
726
+ return { scaleX: scale, scaleY: scale };
727
+ }
728
+ return { scaleX: 1, scaleY: 1 };
729
+ }
730
+ function applySpriteProps(sprite, prev, next) {
731
+ const textureChanged = prev.texture !== next.texture || prev.frame !== next.frame;
732
+ if (textureChanged && next.texture) {
733
+ sprite.setTexture(next.texture, next.frame);
734
+ }
735
+ if (prev.tint !== next.tint) {
736
+ if (typeof next.tint === "number") {
737
+ sprite.setTint(next.tint);
738
+ } else {
739
+ sprite.clearTint();
740
+ }
741
+ }
742
+ if (prev.originX !== next.originX || prev.originY !== next.originY) {
743
+ const originX = next.originX ?? sprite.originX;
744
+ const originY = next.originY ?? sprite.originY;
745
+ sprite.setOrigin(originX, originY);
746
+ }
747
+ const displayWidthChanged = prev.displayWidth !== next.displayWidth;
748
+ const displayHeightChanged = prev.displayHeight !== next.displayHeight;
749
+ const fitChanged = prev.fit !== next.fit;
750
+ if (displayWidthChanged || displayHeightChanged || fitChanged || textureChanged) {
751
+ if (typeof next.displayWidth === "number" && typeof next.displayHeight === "number") {
752
+ const fit = next.fit ?? "fill";
753
+ if (fit === "fill") {
754
+ sprite.setDisplaySize(next.displayWidth, next.displayHeight);
755
+ } else {
756
+ const { scaleX, scaleY } = calculateFitScale(
757
+ sprite,
758
+ next.displayWidth,
759
+ next.displayHeight,
760
+ fit
761
+ );
762
+ sprite.setScale(scaleX, scaleY);
763
+ }
764
+ } else if (typeof next.displayWidth === "number") {
765
+ const { width: origWidth } = getOriginalTextureDimensions(sprite);
766
+ const scale = next.displayWidth / origWidth;
767
+ sprite.setScale(scale);
768
+ } else if (typeof next.displayHeight === "number") {
769
+ const { height: origHeight } = getOriginalTextureDimensions(sprite);
770
+ const scale = next.displayHeight / origHeight;
771
+ sprite.setScale(scale, scale);
772
+ } else {
773
+ sprite.setScale(1);
774
+ }
775
+ }
776
+ const animationChanged = prev.animationKey !== next.animationKey || prev.loop !== next.loop || prev.repeatDelay !== next.repeatDelay;
777
+ if (animationChanged) {
778
+ if (sprite.anims.isPlaying) {
779
+ sprite.anims.stop();
780
+ }
781
+ if (next.animationKey) {
782
+ sprite.anims.play({
783
+ key: next.animationKey,
784
+ repeat: next.loop ? -1 : 0,
785
+ repeatDelay: next.repeatDelay ?? 0
786
+ });
787
+ }
788
+ }
789
+ const callbacksChanged = prev.onAnimationStart !== next.onAnimationStart || prev.onAnimationComplete !== next.onAnimationComplete || prev.onAnimationRepeat !== next.onAnimationRepeat || prev.onAnimationUpdate !== next.onAnimationUpdate;
790
+ if (callbacksChanged) {
791
+ sprite.off("animationstart");
792
+ sprite.off("animationcomplete");
793
+ sprite.off("animationrepeat");
794
+ sprite.off("animationupdate");
795
+ if (next.onAnimationStart) {
796
+ sprite.on("animationstart", (anim) => {
797
+ next.onAnimationStart?.(anim.key);
798
+ });
799
+ }
800
+ if (next.onAnimationComplete) {
801
+ sprite.on("animationcomplete", (anim) => {
802
+ next.onAnimationComplete?.(anim.key);
803
+ });
804
+ }
805
+ if (next.onAnimationRepeat) {
806
+ sprite.on("animationrepeat", (anim) => {
807
+ next.onAnimationRepeat?.(anim.key);
808
+ });
809
+ }
810
+ if (next.onAnimationUpdate) {
811
+ sprite.on(
812
+ "animationupdate",
813
+ (anim, frame) => {
814
+ next.onAnimationUpdate?.(anim.key, frame);
815
+ }
816
+ );
817
+ }
818
+ }
819
+ }
820
+ function applySpriteLayout(sprite, _prev, next) {
821
+ sprite.__layoutProps = next;
822
+ }
823
+ function createSpriteLayout(sprite, props) {
824
+ sprite.__layoutProps = props;
825
+ sprite.__getLayoutSize = () => {
826
+ return { width: 0.01, height: 0.01 };
827
+ };
828
+ }
829
+ const spriteCreator = (scene, props) => {
830
+ const sprite = scene.add.sprite(props.x ?? 0, props.y ?? 0, props.texture, props.frame);
831
+ sprite.setOrigin(0.5, 0.5);
832
+ if (props.originX !== void 0 || props.originY !== void 0) {
833
+ sprite.setOrigin(props.originX ?? sprite.originX, props.originY ?? sprite.originY);
834
+ }
835
+ createTransform(sprite, props);
836
+ createPhaser(sprite, props);
837
+ if (props.tint !== void 0) {
838
+ sprite.setTint(props.tint);
839
+ }
840
+ if (props.displayWidth !== void 0 || props.displayHeight !== void 0) {
841
+ if (props.displayWidth !== void 0 && props.displayHeight !== void 0) {
842
+ const fit = props.fit ?? "fill";
843
+ const textureWidth = sprite.width;
844
+ const textureHeight = sprite.height;
845
+ if (textureWidth > 0 && textureHeight > 0) {
846
+ if (fit === "fill") {
847
+ sprite.setDisplaySize(props.displayWidth, props.displayHeight);
848
+ } else if (fit === "contain") {
849
+ const targetAspect = props.displayWidth / props.displayHeight;
850
+ const textureAspect = textureWidth / textureHeight;
851
+ const scale = targetAspect > textureAspect ? props.displayHeight / textureHeight : props.displayWidth / textureWidth;
852
+ sprite.setScale(scale);
853
+ } else if (fit === "cover") {
854
+ const targetAspect = props.displayWidth / props.displayHeight;
855
+ const textureAspect = textureWidth / textureHeight;
856
+ const scale = targetAspect < textureAspect ? props.displayHeight / textureHeight : props.displayWidth / textureWidth;
857
+ sprite.setScale(scale);
858
+ }
859
+ }
860
+ } else if (props.displayWidth !== void 0) {
861
+ const scale = props.displayWidth / sprite.width;
862
+ sprite.setScale(scale);
863
+ } else if (props.displayHeight !== void 0) {
864
+ const scale = props.displayHeight / sprite.height;
865
+ sprite.setScale(scale);
866
+ }
867
+ }
868
+ if (props.animationKey) {
869
+ if (sprite.scene && sprite.scene.anims.exists(props.animationKey)) {
870
+ sprite.anims.play({
871
+ key: props.animationKey,
872
+ repeat: props.loop ? -1 : 0,
873
+ repeatDelay: props.repeatDelay ?? 0
874
+ });
875
+ }
876
+ }
877
+ if (props.onAnimationStart) {
878
+ sprite.on("animationstart", (anim) => {
879
+ props.onAnimationStart?.(anim.key);
880
+ });
881
+ }
882
+ if (props.onAnimationComplete) {
883
+ sprite.on("animationcomplete", (anim) => {
884
+ props.onAnimationComplete?.(anim.key);
885
+ });
886
+ }
887
+ if (props.onAnimationRepeat) {
888
+ sprite.on("animationrepeat", (anim) => {
889
+ props.onAnimationRepeat?.(anim.key);
890
+ });
891
+ }
892
+ if (props.onAnimationUpdate) {
893
+ sprite.on(
894
+ "animationupdate",
895
+ (anim, frame) => {
896
+ props.onAnimationUpdate?.(anim.key, frame);
897
+ }
898
+ );
899
+ }
900
+ createSpriteLayout(sprite, props);
901
+ if (props.onReady) {
902
+ props.onReady(sprite);
903
+ }
904
+ return sprite;
905
+ };
906
+ const spritePatcher = (node, prev, next) => {
907
+ applyTransformProps(node, prev, next);
908
+ applyPhaserProps(node, prev, next);
909
+ applySpriteProps(node, prev, next);
910
+ applySpriteLayout(node, prev, next);
911
+ };
912
+ function applyTextProps(node, prev, next) {
913
+ if (node.active === false || node.scene && !node.scene.sys.game) {
914
+ return;
915
+ }
916
+ let needsUpdate = false;
917
+ if (prev.text !== next.text && typeof next.text === "string") {
918
+ node.setText(next.text);
919
+ needsUpdate = true;
920
+ }
921
+ if (next.style !== void 0 && !vdom.equal(next.style, prev.style || {})) {
922
+ try {
923
+ node.setStyle(next.style);
924
+ needsUpdate = true;
925
+ } catch (error) {
926
+ console.warn("Failed to apply text style (scene may be transitioning):", error);
927
+ }
928
+ }
929
+ if (next.maxWidth !== prev.maxWidth && next.maxWidth !== void 0) {
930
+ const viewport = vdom.viewportRegistry.getViewport();
931
+ const parsedMaxWidth = vdom.parseSize(next.maxWidth);
932
+ const resolvedMaxWidth = vdom.resolveSize(parsedMaxWidth, viewport?.width, void 0, void 0);
933
+ node.setWordWrapWidth(resolvedMaxWidth, true);
934
+ needsUpdate = true;
935
+ }
936
+ if (prev.style !== next.style && next.style !== void 0) {
937
+ try {
938
+ node.setStyle(next.style);
939
+ needsUpdate = true;
940
+ } catch (error) {
941
+ console.warn("Failed to apply text style (scene may be transitioning):", error);
942
+ }
943
+ }
944
+ if (needsUpdate && node.updateText) {
945
+ node.updateText();
946
+ }
947
+ }
948
+ function applyTextLayout(text, _prev, next) {
949
+ text.__layoutProps = next;
950
+ text.__getLayoutSize = () => {
951
+ if (text.__layoutProps?.headless) {
952
+ return { width: 0.01, height: 0.01 };
953
+ }
954
+ return {
955
+ width: text.width,
956
+ height: text.height
957
+ };
958
+ };
959
+ }
960
+ function createTextLayout(text, props) {
961
+ text.__layoutProps = props;
962
+ text.__getLayoutSize = () => {
963
+ if (text.__layoutProps?.headless) {
964
+ return { width: 0.01, height: 0.01 };
965
+ }
966
+ return {
967
+ width: text.width,
968
+ height: text.height
969
+ };
970
+ };
971
+ }
972
+ const textCreator = (scene, props) => {
973
+ const text = scene.add.text(props.x ?? 0, props.y ?? 0, props.text ?? "", props.style);
974
+ if (props.headless) {
975
+ text.setOrigin(0.5, 0.5);
976
+ } else {
977
+ text.setOrigin(0, 0);
978
+ }
979
+ const normalizedProps = { ...props };
980
+ if (props.headless) {
981
+ delete normalizedProps.padding;
982
+ delete normalizedProps.margin;
983
+ delete normalizedProps.gap;
984
+ } else {
985
+ if (normalizedProps.rotation !== void 0) {
986
+ delete normalizedProps.rotation;
987
+ }
988
+ }
989
+ createTransform(text, normalizedProps);
990
+ createPhaser(text, normalizedProps);
991
+ createTextLayout(text, normalizedProps);
992
+ return text;
993
+ };
994
+ const textPatcher = (node, prev, next) => {
995
+ if (prev.headless !== next.headless) {
996
+ if (next.headless) {
997
+ node.setOrigin(0.5, 0.5);
998
+ } else {
999
+ node.setOrigin(0, 0);
1000
+ }
1001
+ }
1002
+ const normalizedPrev = { ...prev };
1003
+ const normalizedNext = { ...next };
1004
+ if (next.headless) {
1005
+ delete normalizedNext.padding;
1006
+ delete normalizedNext.margin;
1007
+ delete normalizedNext.gap;
1008
+ } else {
1009
+ if (normalizedNext.rotation !== void 0) {
1010
+ delete normalizedNext.rotation;
1011
+ }
1012
+ }
1013
+ if (prev.headless) {
1014
+ delete normalizedPrev.padding;
1015
+ delete normalizedPrev.margin;
1016
+ delete normalizedPrev.gap;
1017
+ } else {
1018
+ if (normalizedPrev.rotation !== void 0) {
1019
+ delete normalizedPrev.rotation;
1020
+ }
1021
+ }
1022
+ applyTransformProps(node, normalizedPrev, normalizedNext);
1023
+ applyPhaserProps(node, normalizedPrev, normalizedNext);
1024
+ applyTextProps(node, normalizedPrev, normalizedNext);
1025
+ applyTextLayout(node, normalizedPrev, normalizedNext);
1026
+ };
1027
+ const tileSpriteCreator = (_scene, _props) => {
1028
+ throw new Error(
1029
+ "TileSprite component not implemented yet. This is a placeholder for architecture planning."
1030
+ );
1031
+ };
1032
+ const tileSpritePatcher = (_node, _prev, _next) => {
1033
+ throw new Error(
1034
+ "TileSprite component not implemented yet. This is a placeholder for architecture planning."
1035
+ );
1036
+ };
1037
+ function applyBackgroundProps(container, prev, next) {
1038
+ const prevBgColor = prev.backgroundColor;
1039
+ const nextBgColor = next.backgroundColor;
1040
+ const prevBgAlpha = prev.backgroundAlpha ?? 1;
1041
+ const nextBgAlpha = next.backgroundAlpha ?? 1;
1042
+ let prevWidth = typeof prev.width === "number" ? prev.width : 100;
1043
+ let prevHeight = typeof prev.height === "number" ? prev.height : 100;
1044
+ let nextWidth = typeof next.width === "number" ? next.width : 100;
1045
+ let nextHeight = typeof next.height === "number" ? next.height : 100;
1046
+ if (container.__getLayoutSize) {
1047
+ const layoutSize = container.__getLayoutSize();
1048
+ prevWidth = layoutSize.width;
1049
+ prevHeight = layoutSize.height;
1050
+ nextWidth = layoutSize.width;
1051
+ nextHeight = layoutSize.height;
1052
+ }
1053
+ const prevCornerRadius = prev.cornerRadius ?? 0;
1054
+ const nextCornerRadius = next.cornerRadius ?? 0;
1055
+ const prevBorderColor = prev.borderColor;
1056
+ const nextBorderColor = next.borderColor;
1057
+ const prevBorderWidth = prev.borderWidth ?? 0;
1058
+ const nextBorderWidth = next.borderWidth ?? 0;
1059
+ const prevBorderAlpha = prev.borderAlpha ?? 1;
1060
+ const nextBorderAlpha = next.borderAlpha ?? 1;
1061
+ const prevHasBorder = prevBorderWidth > 0 && prevBorderColor !== void 0;
1062
+ const nextHasBorder = nextBorderWidth > 0 && nextBorderColor !== void 0;
1063
+ const prevHasGraphics = prevBgColor !== void 0 || prevHasBorder;
1064
+ const nextHasGraphics = nextBgColor !== void 0 || nextHasBorder;
1065
+ if (prevHasGraphics && !nextHasGraphics) {
1066
+ if (container.__background) {
1067
+ container.__background.destroy();
1068
+ delete container.__background;
1069
+ }
1070
+ } else if (!prevHasGraphics && nextHasGraphics) {
1071
+ if (container.scene) {
1072
+ const background = container.scene.add.graphics();
1073
+ if (nextBgColor !== void 0) {
1074
+ background.fillStyle(nextBgColor, nextBgAlpha);
1075
+ }
1076
+ if (nextHasBorder) {
1077
+ background.lineStyle(nextBorderWidth, nextBorderColor, nextBorderAlpha);
1078
+ }
1079
+ if (nextCornerRadius !== 0) {
1080
+ if (nextBgColor !== void 0) {
1081
+ background.fillRoundedRect(0, 0, nextWidth, nextHeight, nextCornerRadius);
1082
+ }
1083
+ if (nextHasBorder) {
1084
+ background.strokeRoundedRect(0, 0, nextWidth, nextHeight, nextCornerRadius);
1085
+ }
1086
+ } else {
1087
+ if (nextBgColor !== void 0) {
1088
+ background.fillRect(0, 0, nextWidth, nextHeight);
1089
+ }
1090
+ if (nextHasBorder) {
1091
+ background.strokeRect(0, 0, nextWidth, nextHeight);
1092
+ }
1093
+ }
1094
+ container.addAt(background, 0);
1095
+ container.__background = background;
1096
+ background.__isBackground = true;
1097
+ }
1098
+ } else if (container.__background && nextHasGraphics) {
1099
+ const needsRedraw = prevBgColor !== nextBgColor || prevBgAlpha !== nextBgAlpha || prevWidth !== nextWidth || prevHeight !== nextHeight || prevCornerRadius !== nextCornerRadius || prevBorderWidth !== nextBorderWidth || prevBorderColor !== nextBorderColor || prevBorderAlpha !== nextBorderAlpha;
1100
+ if (needsRedraw) {
1101
+ container.__background.clear();
1102
+ if (nextBgColor !== void 0) {
1103
+ container.__background.fillStyle(nextBgColor, nextBgAlpha);
1104
+ }
1105
+ if (nextHasBorder) {
1106
+ container.__background.lineStyle(nextBorderWidth, nextBorderColor, nextBorderAlpha);
1107
+ }
1108
+ if (nextCornerRadius !== 0) {
1109
+ if (nextBgColor !== void 0) {
1110
+ container.__background.fillRoundedRect(0, 0, nextWidth, nextHeight, nextCornerRadius);
1111
+ }
1112
+ if (nextHasBorder) {
1113
+ container.__background.strokeRoundedRect(0, 0, nextWidth, nextHeight, nextCornerRadius);
1114
+ }
1115
+ } else {
1116
+ if (nextBgColor !== void 0) {
1117
+ container.__background.fillRect(0, 0, nextWidth, nextHeight);
1118
+ }
1119
+ if (nextHasBorder) {
1120
+ container.__background.strokeRect(0, 0, nextWidth, nextHeight);
1121
+ }
1122
+ }
1123
+ }
1124
+ }
1125
+ }
1126
+ function applyGesturesProps(scene, container, prev, next) {
1127
+ if (!scene || !scene.sys || !scene.data) {
1128
+ console.warn("applyGesturesProps: Invalid scene or scene not initialized");
1129
+ return;
1130
+ }
1131
+ if (!scene.sys.isActive() || scene.sys.game === null) {
1132
+ console.warn("applyGesturesProps: Scene is not active or game is null");
1133
+ return;
1134
+ }
1135
+ const hasAnyGesture = !!(next.onTouch || next.onTouchOutside || next.onTouchMove || next.onDoubleTap || next.onLongPress || next.onHoverStart || next.onHoverEnd || next.onWheel);
1136
+ const hadAnyGesture = !!(prev.onTouch || prev.onTouchOutside || prev.onTouchMove || prev.onDoubleTap || prev.onLongPress || prev.onHoverStart || prev.onHoverEnd || prev.onWheel);
1137
+ const prevEnabled = hadAnyGesture && prev.enableGestures !== false;
1138
+ const nextEnabled = hasAnyGesture && next.enableGestures !== false;
1139
+ const manager = vdom.getGestureManager(scene);
1140
+ if (!prevEnabled && nextEnabled && hasAnyGesture) {
1141
+ const containerWithLayout = container;
1142
+ let width = 100;
1143
+ let height = 100;
1144
+ if (containerWithLayout.__getLayoutSize) {
1145
+ const size = containerWithLayout.__getLayoutSize();
1146
+ width = size.width;
1147
+ height = size.height;
1148
+ } else {
1149
+ const bounds = container.getBounds();
1150
+ width = bounds.width || 100;
1151
+ height = bounds.height || 100;
1152
+ }
1153
+ const hitArea = new Phaser$1.Geom.Rectangle(0, 0, width, height);
1154
+ const callbacks = {};
1155
+ if (next.onTouch) callbacks.onTouch = next.onTouch;
1156
+ if (next.onTouchOutside) callbacks.onTouchOutside = next.onTouchOutside;
1157
+ if (next.onTouchMove) callbacks.onTouchMove = next.onTouchMove;
1158
+ if (next.onDoubleTap) callbacks.onDoubleTap = next.onDoubleTap;
1159
+ if (next.onLongPress) callbacks.onLongPress = next.onLongPress;
1160
+ if (next.onHoverStart) callbacks.onHoverStart = next.onHoverStart;
1161
+ if (next.onHoverEnd) callbacks.onHoverEnd = next.onHoverEnd;
1162
+ if (next.onWheel) callbacks.onWheel = next.onWheel;
1163
+ const config = {};
1164
+ if (next.longPressDuration !== void 0) config.longPressDuration = next.longPressDuration;
1165
+ if (next.doubleTapDelay !== void 0) config.doubleTapDelay = next.doubleTapDelay;
1166
+ manager.registerContainer(container, callbacks, hitArea, config);
1167
+ return;
1168
+ }
1169
+ if (prevEnabled && (!nextEnabled || !hasAnyGesture)) {
1170
+ manager.unregisterContainer(container);
1171
+ return;
1172
+ }
1173
+ if (nextEnabled && hasAnyGesture) {
1174
+ const callbacksChanged = prev.onTouch !== next.onTouch || prev.onTouchOutside !== next.onTouchOutside || prev.onTouchMove !== next.onTouchMove || prev.onDoubleTap !== next.onDoubleTap || prev.onLongPress !== next.onLongPress || prev.onHoverStart !== next.onHoverStart || prev.onHoverEnd !== next.onHoverEnd || prev.onWheel !== next.onWheel;
1175
+ if (callbacksChanged) {
1176
+ const callbacks = {};
1177
+ if (next.onTouch) callbacks.onTouch = next.onTouch;
1178
+ if (next.onTouchOutside) callbacks.onTouchOutside = next.onTouchOutside;
1179
+ if (next.onTouchMove) callbacks.onTouchMove = next.onTouchMove;
1180
+ if (next.onDoubleTap) callbacks.onDoubleTap = next.onDoubleTap;
1181
+ if (next.onLongPress) callbacks.onLongPress = next.onLongPress;
1182
+ if (next.onHoverStart) callbacks.onHoverStart = next.onHoverStart;
1183
+ if (next.onHoverEnd) callbacks.onHoverEnd = next.onHoverEnd;
1184
+ if (next.onWheel) callbacks.onWheel = next.onWheel;
1185
+ manager.updateCallbacks(container, callbacks);
1186
+ }
1187
+ const containerWithLayout = container;
1188
+ let width = 100;
1189
+ let height = 100;
1190
+ if (containerWithLayout.__getLayoutSize) {
1191
+ const size = containerWithLayout.__getLayoutSize();
1192
+ width = size.width;
1193
+ height = size.height;
1194
+ } else {
1195
+ const bounds = container.getBounds();
1196
+ width = bounds.width || 100;
1197
+ height = bounds.height || 100;
1198
+ }
1199
+ const hitArea = new Phaser$1.Geom.Rectangle(0, 0, width, height);
1200
+ manager.updateHitArea(container, hitArea);
1201
+ }
1202
+ }
1203
+ function updateGestureHitAreaIfNeeded(node) {
1204
+ const containerWithLayout = node;
1205
+ if (!containerWithLayout.__getLayoutSize) return;
1206
+ try {
1207
+ const manager = vdom.getGestureManager(containerWithLayout.scene);
1208
+ const size = containerWithLayout.__getLayoutSize();
1209
+ const hitArea = new Phaser.Geom.Rectangle(0, 0, size.width, size.height);
1210
+ manager.updateHitArea(node, hitArea);
1211
+ } catch {
1212
+ }
1213
+ }
1214
+ const LAYOUT_RELEVANT_PROPS = [
1215
+ "width",
1216
+ "height",
1217
+ "minWidth",
1218
+ "maxWidth",
1219
+ "minHeight",
1220
+ "maxHeight",
1221
+ "flex",
1222
+ "margin",
1223
+ "padding",
1224
+ "gap",
1225
+ "direction",
1226
+ "justifyContent",
1227
+ "alignItems",
1228
+ "overflow"
1229
+ ];
1230
+ const DEEP_COMPARE_PROPS = /* @__PURE__ */ new Set(["margin", "padding"]);
1231
+ function hasLayoutPropsChanged(prev, next) {
1232
+ for (const prop of LAYOUT_RELEVANT_PROPS) {
1233
+ const oldVal = prev[prop];
1234
+ const newVal = next[prop];
1235
+ if (DEEP_COMPARE_PROPS.has(prop)) {
1236
+ if (!vdom.equal(oldVal, newVal)) {
1237
+ return true;
1238
+ }
1239
+ } else {
1240
+ if (oldVal !== newVal) {
1241
+ return true;
1242
+ }
1243
+ }
1244
+ }
1245
+ return false;
1246
+ }
1247
+ function getParentLayoutContext(node) {
1248
+ const parent = node.parentContainer;
1249
+ if (parent && parent.__layoutProps && parent.__getLayoutSize) {
1250
+ const parentSize = parent.__getLayoutSize();
1251
+ const padding = parent.__layoutProps.padding ?? 0;
1252
+ const normPadding = typeof padding === "number" ? { left: padding, right: padding, top: padding, bottom: padding } : {
1253
+ left: padding.left ?? 0,
1254
+ right: padding.right ?? 0,
1255
+ top: padding.top ?? 0,
1256
+ bottom: padding.bottom ?? 0
1257
+ };
1258
+ return {
1259
+ parentSize: {
1260
+ width: parentSize.width - normPadding.left - normPadding.right,
1261
+ height: parentSize.height - normPadding.top - normPadding.bottom
1262
+ }
1263
+ // Parent already provides content-area, no padding offset needed
1264
+ };
1265
+ }
1266
+ if (node.scene) {
1267
+ return {
1268
+ parentSize: {
1269
+ width: node.scene.scale.width,
1270
+ height: node.scene.scale.height
1271
+ }
1272
+ };
1273
+ }
1274
+ return {};
1275
+ }
1276
+ function applyLayoutProps(node, prev, next) {
1277
+ node.__layoutProps = next;
1278
+ if (hasLayoutPropsChanged(prev, next)) {
1279
+ const { parentSize, parentPadding } = getParentLayoutContext(node);
1280
+ vdom.calculateLayout(node, next, parentSize, parentPadding);
1281
+ updateGestureHitAreaIfNeeded(node);
1282
+ }
1283
+ }
1284
+ const tooltipStates = /* @__PURE__ */ new Map();
1285
+ function calculateTooltipPosition(targetBounds, position, offset, tooltipWidth, tooltipHeight) {
1286
+ const viewport = {
1287
+ width: window.innerWidth,
1288
+ height: window.innerHeight
1289
+ };
1290
+ let x = 0;
1291
+ let y = 0;
1292
+ switch (position) {
1293
+ case "top":
1294
+ x = targetBounds.centerX - tooltipWidth / 2;
1295
+ y = targetBounds.top - tooltipHeight - offset;
1296
+ break;
1297
+ case "bottom":
1298
+ x = targetBounds.centerX - tooltipWidth / 2;
1299
+ y = targetBounds.bottom + offset;
1300
+ break;
1301
+ case "left":
1302
+ x = targetBounds.left - tooltipWidth - offset;
1303
+ y = targetBounds.centerY - tooltipHeight / 2;
1304
+ break;
1305
+ case "right":
1306
+ x = targetBounds.right + offset;
1307
+ y = targetBounds.centerY - tooltipHeight / 2;
1308
+ break;
1309
+ }
1310
+ x = Math.max(8, Math.min(x, viewport.width - tooltipWidth - 8));
1311
+ y = Math.max(8, Math.min(y, viewport.height - tooltipHeight - 8));
1312
+ return { x, y };
1313
+ }
1314
+ function showTooltip(scene, container, config) {
1315
+ const state = tooltipStates.get(container);
1316
+ if (!state || state.isVisible) return;
1317
+ state.isVisible = true;
1318
+ state.currentConfig = config;
1319
+ const theme = vdom.themeRegistry.getGlobalTheme();
1320
+ const tooltipTheme = theme.Tooltip || {};
1321
+ const position = config.position ?? tooltipTheme.position ?? "top";
1322
+ const offset = config.offset ?? tooltipTheme.offset ?? 8;
1323
+ const content = config.content;
1324
+ const targetBounds = container.getBounds();
1325
+ const textStyle = tooltipTheme.textStyle ?? {
1326
+ fontSize: "14px",
1327
+ fontFamily: "Arial",
1328
+ color: "#ffffff",
1329
+ padding: { x: 8, y: 4 }
1330
+ };
1331
+ const { backgroundColor: bgColor, ...styleWithoutBg } = textStyle;
1332
+ const text = scene.add.text(0, 0, content, styleWithoutBg);
1333
+ text.setOrigin(0.5);
1334
+ const padding = textStyle.padding ?? { x: 8, y: 4 };
1335
+ const paddingX = typeof padding === "number" ? padding : padding.x ?? 8;
1336
+ const paddingY = typeof padding === "number" ? padding : padding.y ?? 4;
1337
+ const textWidth = text.width;
1338
+ const textHeight = text.height;
1339
+ const bgWidth = textWidth + paddingX * 2;
1340
+ const bgHeight = textHeight + paddingY * 2;
1341
+ const cornerRadius = tooltipTheme.cornerRadius ?? 6;
1342
+ const graphics = scene.add.graphics();
1343
+ const bg = bgColor ?? "#000000dd";
1344
+ let fillColor = 0;
1345
+ let fillAlpha = 0.87;
1346
+ if (typeof bg === "string") {
1347
+ if (bg.startsWith("#")) {
1348
+ const hex = bg.slice(1);
1349
+ if (hex.length === 8) {
1350
+ fillColor = parseInt(hex.slice(0, 6), 16);
1351
+ fillAlpha = parseInt(hex.slice(6, 8), 16) / 255;
1352
+ } else if (hex.length === 6) {
1353
+ fillColor = parseInt(hex, 16);
1354
+ fillAlpha = 1;
1355
+ }
1356
+ }
1357
+ }
1358
+ graphics.fillStyle(fillColor, fillAlpha);
1359
+ graphics.fillRoundedRect(-bgWidth / 2, -bgHeight / 2, bgWidth, bgHeight, cornerRadius);
1360
+ const tooltipContainer = scene.add.container(0, 0, [graphics, text]);
1361
+ tooltipContainer.setDepth(1e4);
1362
+ const textBounds = tooltipContainer.getBounds();
1363
+ const pos = calculateTooltipPosition(
1364
+ targetBounds,
1365
+ position,
1366
+ offset,
1367
+ textBounds.width,
1368
+ textBounds.height
1369
+ );
1370
+ const themeAnim = tooltipTheme.animation || {};
1371
+ const anim = config.animation || {};
1372
+ const fadeInDuration = anim.fadeIn ?? themeAnim.fadeIn ?? 200;
1373
+ const moveOffset = {
1374
+ dx: anim.move?.dx ?? themeAnim.move?.dx ?? 0,
1375
+ dy: anim.move?.dy ?? themeAnim.move?.dy ?? 0
1376
+ };
1377
+ const pulse = anim.pulse ?? themeAnim.pulse ?? false;
1378
+ const pulseScale = anim.pulseScale ?? [0.75, 1.25];
1379
+ tooltipContainer.setPosition(
1380
+ pos.x + textBounds.width / 2 - moveOffset.dx,
1381
+ pos.y + textBounds.height / 2 - moveOffset.dy
1382
+ );
1383
+ tooltipContainer.setAlpha(0);
1384
+ state.tooltip = tooltipContainer;
1385
+ const fadeTween = scene.tweens.add({
1386
+ targets: tooltipContainer,
1387
+ alpha: 1,
1388
+ x: pos.x + textBounds.width / 2,
1389
+ y: pos.y + textBounds.height / 2,
1390
+ duration: fadeInDuration,
1391
+ ease: "Cubic.Out"
1392
+ });
1393
+ state.activeTweens.push(fadeTween);
1394
+ if (pulse) {
1395
+ const pulseTween = scene.tweens.add({
1396
+ targets: tooltipContainer,
1397
+ scale: { from: pulseScale[0], to: pulseScale[1] },
1398
+ duration: 600,
1399
+ yoyo: true,
1400
+ repeat: -1,
1401
+ ease: "Sine.InOut"
1402
+ });
1403
+ state.activeTweens.push(pulseTween);
1404
+ }
1405
+ if (config.autoDismiss && config.autoDismiss > 0) {
1406
+ state.autoDismissTimer = setTimeout(() => {
1407
+ hideTooltip(container);
1408
+ }, config.autoDismiss);
1409
+ }
1410
+ }
1411
+ function hideTooltip(container) {
1412
+ const state = tooltipStates.get(container);
1413
+ if (!state || !state.isVisible) return;
1414
+ state.isVisible = false;
1415
+ const config = state.currentConfig;
1416
+ state.currentConfig = null;
1417
+ if (state.autoDismissTimer) {
1418
+ clearTimeout(state.autoDismissTimer);
1419
+ state.autoDismissTimer = null;
1420
+ }
1421
+ if (!state.tooltip) return;
1422
+ const tooltip = state.tooltip;
1423
+ const scene = tooltip.scene;
1424
+ const theme = vdom.themeRegistry.getGlobalTheme();
1425
+ const tooltipTheme = theme.Tooltip || {};
1426
+ const themeAnim = tooltipTheme.animation || {};
1427
+ const anim = config?.animation || {};
1428
+ const fadeOutDuration = anim.fadeOut ?? themeAnim.fadeOut ?? 200;
1429
+ state.activeTweens.forEach((tween) => tween.stop());
1430
+ state.activeTweens = [];
1431
+ scene.tweens.add({
1432
+ targets: tooltip,
1433
+ alpha: 0,
1434
+ duration: fadeOutDuration,
1435
+ ease: "Cubic.In",
1436
+ onComplete: () => {
1437
+ tooltip.destroy();
1438
+ }
1439
+ });
1440
+ state.tooltip = null;
1441
+ }
1442
+ function applyTooltip(scene, container, nextCallback, existingOnHoverStart, existingOnHoverEnd) {
1443
+ if (!tooltipStates.has(container)) {
1444
+ tooltipStates.set(container, {
1445
+ isVisible: false,
1446
+ tooltip: null,
1447
+ activeTweens: [],
1448
+ showTimer: null,
1449
+ hideTimer: null,
1450
+ autoDismissTimer: null,
1451
+ currentConfig: null
1452
+ });
1453
+ container.once("destroy", () => {
1454
+ const state2 = tooltipStates.get(container);
1455
+ if (state2) {
1456
+ if (state2.showTimer) clearTimeout(state2.showTimer);
1457
+ if (state2.hideTimer) clearTimeout(state2.hideTimer);
1458
+ if (state2.autoDismissTimer) clearTimeout(state2.autoDismissTimer);
1459
+ state2.activeTweens.forEach((tween) => tween.stop());
1460
+ hideTooltip(container);
1461
+ tooltipStates.delete(container);
1462
+ }
1463
+ });
1464
+ }
1465
+ const state = tooltipStates.get(container);
1466
+ if (!state) {
1467
+ throw new Error("applyTooltip: state not initialized");
1468
+ }
1469
+ const theme = vdom.themeRegistry.getGlobalTheme();
1470
+ const tooltipTheme = theme.Tooltip || {};
1471
+ const onHoverStart = (data) => {
1472
+ if (existingOnHoverStart) existingOnHoverStart(data);
1473
+ if (!nextCallback) return;
1474
+ const result = nextCallback();
1475
+ if (!result) return;
1476
+ const config = typeof result === "string" ? { content: result } : result;
1477
+ if (config.disabled) return;
1478
+ if (state.hideTimer) {
1479
+ clearTimeout(state.hideTimer);
1480
+ state.hideTimer = null;
1481
+ }
1482
+ if (state.autoDismissTimer) {
1483
+ clearTimeout(state.autoDismissTimer);
1484
+ state.autoDismissTimer = null;
1485
+ }
1486
+ const showDelay = config.showDelay ?? tooltipTheme.showDelay ?? 500;
1487
+ state.showTimer = setTimeout(() => {
1488
+ showTooltip(scene, container, config);
1489
+ }, showDelay);
1490
+ };
1491
+ const onHoverEnd = (data) => {
1492
+ if (existingOnHoverEnd) existingOnHoverEnd(data);
1493
+ if (state.showTimer) {
1494
+ clearTimeout(state.showTimer);
1495
+ state.showTimer = null;
1496
+ }
1497
+ const hideDelay = state.currentConfig?.hideDelay ?? tooltipTheme.hideDelay ?? 0;
1498
+ if (hideDelay > 0) {
1499
+ state.hideTimer = setTimeout(() => {
1500
+ hideTooltip(container);
1501
+ }, hideDelay);
1502
+ } else {
1503
+ hideTooltip(container);
1504
+ }
1505
+ };
1506
+ return { onHoverStart, onHoverEnd };
1507
+ }
1508
+ function createBackground(scene, container, props) {
1509
+ const hasBackground = props.backgroundColor !== void 0;
1510
+ const hasBorder = props.borderColor !== void 0;
1511
+ if (hasBackground || hasBorder) {
1512
+ const width = typeof props.width === "number" ? props.width : 100;
1513
+ const height = typeof props.height === "number" ? props.height : 100;
1514
+ const bgColor = props.backgroundColor;
1515
+ const bgAlpha = props.backgroundAlpha ?? 1;
1516
+ const cornerRadius = props.cornerRadius ?? 0;
1517
+ const borderColor = props.borderColor;
1518
+ const borderWidth = props.borderWidth ?? 0;
1519
+ const borderAlpha = props.borderAlpha ?? 1;
1520
+ const background = scene.add.graphics();
1521
+ if (bgColor !== void 0) {
1522
+ background.fillStyle(bgColor, bgAlpha);
1523
+ }
1524
+ if (borderWidth > 0 && borderColor !== void 0) {
1525
+ background.lineStyle(borderWidth, borderColor, borderAlpha);
1526
+ }
1527
+ if (cornerRadius !== 0) {
1528
+ if (bgColor !== void 0) {
1529
+ background.fillRoundedRect(0, 0, width, height, cornerRadius);
1530
+ }
1531
+ if (borderWidth > 0 && borderColor !== void 0) {
1532
+ background.strokeRoundedRect(0, 0, width, height, cornerRadius);
1533
+ }
1534
+ } else {
1535
+ if (bgColor !== void 0) {
1536
+ background.fillRect(0, 0, width, height);
1537
+ }
1538
+ if (borderWidth > 0 && borderColor !== void 0) {
1539
+ background.strokeRect(0, 0, width, height);
1540
+ }
1541
+ }
1542
+ container.addAt(background, 0);
1543
+ container.__background = background;
1544
+ background.__isBackground = true;
1545
+ }
1546
+ }
1547
+ function createGestures(scene, container, props) {
1548
+ const hasAnyGesture = !!(props.onTouch || props.onTouchOutside || props.onTouchMove || props.onDoubleTap || props.onLongPress || props.onHoverStart || props.onHoverEnd || props.onWheel);
1549
+ const shouldEnable = hasAnyGesture && props.enableGestures !== false;
1550
+ if (!shouldEnable) {
1551
+ return;
1552
+ }
1553
+ const manager = vdom.getGestureManager(scene);
1554
+ const containerWithLayout = container;
1555
+ let width = 100;
1556
+ let height = 100;
1557
+ if (containerWithLayout.__getLayoutSize) {
1558
+ const size = containerWithLayout.__getLayoutSize();
1559
+ width = size.width;
1560
+ height = size.height;
1561
+ } else {
1562
+ const bounds = container.getBounds();
1563
+ width = bounds.width || 100;
1564
+ height = bounds.height || 100;
1565
+ }
1566
+ const hitArea = new Phaser$1.Geom.Rectangle(0, 0, width, height);
1567
+ const callbacks = {};
1568
+ if (props.onTouch) callbacks.onTouch = props.onTouch;
1569
+ if (props.onTouchOutside) callbacks.onTouchOutside = props.onTouchOutside;
1570
+ if (props.onTouchMove) callbacks.onTouchMove = props.onTouchMove;
1571
+ if (props.onDoubleTap) callbacks.onDoubleTap = props.onDoubleTap;
1572
+ if (props.onLongPress) callbacks.onLongPress = props.onLongPress;
1573
+ if (props.onHoverStart) callbacks.onHoverStart = props.onHoverStart;
1574
+ if (props.onHoverEnd) callbacks.onHoverEnd = props.onHoverEnd;
1575
+ if (props.onWheel) callbacks.onWheel = props.onWheel;
1576
+ const config = {};
1577
+ if (props.longPressDuration !== void 0) config.longPressDuration = props.longPressDuration;
1578
+ if (props.doubleTapDelay !== void 0) config.doubleTapDelay = props.doubleTapDelay;
1579
+ if (props.maxTouchDuration !== void 0) config.maxTouchDuration = props.maxTouchDuration;
1580
+ manager.registerContainer(container, callbacks, hitArea, config);
1581
+ }
1582
+ function createLayout(container, props) {
1583
+ container.__layoutProps = props;
1584
+ container.__getLayoutSize = () => {
1585
+ const children = container.list;
1586
+ const direction = props.direction ?? "column";
1587
+ const paddingRaw = props.padding ?? {};
1588
+ const padding = typeof paddingRaw === "number" ? { left: paddingRaw, top: paddingRaw, right: paddingRaw, bottom: paddingRaw } : paddingRaw;
1589
+ const paddingLeft = padding.left ?? 0;
1590
+ const paddingTop = padding.top ?? 0;
1591
+ const paddingRight = padding.right ?? 0;
1592
+ const paddingBottom = padding.bottom ?? 0;
1593
+ const gapNormalized = vdom.normalizeGap(props.gap);
1594
+ let maxWidth = 0;
1595
+ let maxHeight = 0;
1596
+ let totalMainSize = 0;
1597
+ let childCount = 0;
1598
+ for (const child of children) {
1599
+ if (child.__isBackground) {
1600
+ continue;
1601
+ }
1602
+ childCount++;
1603
+ const marginRaw = child.__layoutProps?.margin ?? {};
1604
+ const margin = typeof marginRaw === "number" ? { top: marginRaw, right: marginRaw, bottom: marginRaw, left: marginRaw } : marginRaw;
1605
+ const marginTop = margin.top ?? 0;
1606
+ const marginBottom = margin.bottom ?? 0;
1607
+ const marginLeft = margin.left ?? 0;
1608
+ const marginRight = margin.right ?? 0;
1609
+ const childSize = vdom.getChildSize(child);
1610
+ if (direction === "row") {
1611
+ totalMainSize += marginLeft + childSize.width + marginRight;
1612
+ const childTotalHeight = marginTop + childSize.height + marginBottom;
1613
+ maxHeight = Math.max(maxHeight, childTotalHeight);
1614
+ } else {
1615
+ const childTotalWidth = marginLeft + childSize.width + marginRight;
1616
+ maxWidth = Math.max(maxWidth, childTotalWidth);
1617
+ totalMainSize += marginTop + childSize.height + marginBottom;
1618
+ }
1619
+ }
1620
+ if (childCount > 1) {
1621
+ const gapValue = direction === "row" ? gapNormalized.horizontal : gapNormalized.vertical;
1622
+ totalMainSize += gapValue * (childCount - 1);
1623
+ }
1624
+ const defaultWidth = direction === "row" ? totalMainSize + paddingLeft + paddingRight : maxWidth + paddingLeft + paddingRight;
1625
+ const defaultHeight = direction === "row" ? maxHeight + paddingTop + paddingBottom : totalMainSize + paddingTop + paddingBottom;
1626
+ const parsedWidth = vdom.parseSize(props.width);
1627
+ const finalWidth = vdom.resolveSize(parsedWidth, void 0, defaultWidth);
1628
+ const parsedHeight = vdom.parseSize(props.height);
1629
+ const finalHeight = vdom.resolveSize(parsedHeight, void 0, defaultHeight);
1630
+ return {
1631
+ width: finalWidth,
1632
+ height: finalHeight
1633
+ };
1634
+ };
1635
+ }
1636
+ function normalizeBackgroundProps(props) {
1637
+ const bgProps = props;
1638
+ const hasBackground = bgProps.backgroundColor !== void 0;
1639
+ const hasBorder = bgProps.borderColor !== void 0;
1640
+ if (!hasBackground && !hasBorder) {
1641
+ return props;
1642
+ }
1643
+ const normalized = { ...props };
1644
+ if (hasBackground && bgProps.backgroundAlpha === void 0) {
1645
+ normalized.backgroundAlpha = 1;
1646
+ }
1647
+ if (hasBorder) {
1648
+ if (bgProps.borderWidth === void 0 || bgProps.borderWidth === 0) {
1649
+ normalized.borderWidth = 1;
1650
+ }
1651
+ if (bgProps.borderAlpha === void 0 || bgProps.borderAlpha === 0) {
1652
+ normalized.borderAlpha = 1;
1653
+ }
1654
+ }
1655
+ return normalized;
1656
+ }
1657
+ const viewCreator = (scene, props) => {
1658
+ if (props.backgroundColor !== void 0 || props.cornerRadius !== void 0) {
1659
+ vdom.DebugLogger.log("theme", "View Creator - Props received:", {
1660
+ backgroundColor: props.backgroundColor,
1661
+ cornerRadius: props.cornerRadius,
1662
+ width: props.width,
1663
+ height: props.height
1664
+ });
1665
+ }
1666
+ const normalizedProps = normalizeBackgroundProps(props);
1667
+ const container = scene.add.container(normalizedProps.x ?? 0, normalizedProps.y ?? 0);
1668
+ createTransform(container, normalizedProps);
1669
+ createPhaser(container, normalizedProps);
1670
+ createBackground(
1671
+ scene,
1672
+ container,
1673
+ normalizedProps
1674
+ );
1675
+ createLayout(container, normalizedProps);
1676
+ if (normalizedProps.onTooltip) {
1677
+ const handlers = applyTooltip(
1678
+ scene,
1679
+ container,
1680
+ normalizedProps.onTooltip,
1681
+ normalizedProps.onHoverStart,
1682
+ normalizedProps.onHoverEnd
1683
+ );
1684
+ normalizedProps.onHoverStart = handlers.onHoverStart;
1685
+ normalizedProps.onHoverEnd = handlers.onHoverEnd;
1686
+ }
1687
+ createGestures(scene, container, normalizedProps);
1688
+ vdom.DebugLogger.log(
1689
+ "layout",
1690
+ "View creator storing __layoutProps with padding:",
1691
+ normalizedProps.padding
1692
+ );
1693
+ return container;
1694
+ };
1695
+ const viewPatcher = (node, prev, next) => {
1696
+ const normalizedPrev = normalizeBackgroundProps(prev);
1697
+ const normalizedNext = normalizeBackgroundProps(next);
1698
+ applyTransformProps(node, normalizedPrev, normalizedNext);
1699
+ applyPhaserProps(node, normalizedPrev, normalizedNext);
1700
+ const container = node;
1701
+ applyBackgroundProps(container, normalizedPrev, normalizedNext);
1702
+ if (container.scene && container.scene.data) {
1703
+ if (normalizedNext.onTooltip) {
1704
+ const handlers = applyTooltip(
1705
+ container.scene,
1706
+ container,
1707
+ normalizedNext.onTooltip,
1708
+ normalizedNext.onHoverStart,
1709
+ normalizedNext.onHoverEnd
1710
+ );
1711
+ normalizedNext.onHoverStart = handlers.onHoverStart;
1712
+ normalizedNext.onHoverEnd = handlers.onHoverEnd;
1713
+ }
1714
+ }
1715
+ if (container.scene && container.scene.data) {
1716
+ applyGesturesProps(container.scene, container, normalizedPrev, normalizedNext);
1717
+ }
1718
+ applyLayoutProps(container, normalizedPrev, normalizedNext);
1719
+ };
1720
+ function Sprite(props) {
1721
+ const localTheme = vdom.useTheme();
1722
+ const { props: themed, nestedTheme } = vdom.getThemedProps("Sprite", localTheme, props);
1723
+ return /* @__PURE__ */ jsxRuntime.jsx("sprite", { ...themed, theme: nestedTheme });
1724
+ }
1725
+ function TileSprite(props) {
1726
+ const localTheme = vdom.useTheme();
1727
+ const { props: themed, nestedTheme } = vdom.getThemedProps("TileSprite", localTheme, props);
1728
+ return /* @__PURE__ */ jsxRuntime.jsx("tilesprite", { ...themed, theme: nestedTheme });
1729
+ }
1730
+ function registerBuiltins() {
1731
+ vdom.register("view", { create: viewCreator, patch: viewPatcher });
1732
+ vdom.register("text", { create: textCreator, patch: textPatcher });
1733
+ vdom.register("nineslice", { create: nineSliceCreator, patch: nineSlicePatcher });
1734
+ vdom.register("particles", { create: particlesCreator, patch: particlesPatcher });
1735
+ vdom.register("sprite", { create: spriteCreator, patch: spritePatcher });
1736
+ vdom.register("image", { create: imageCreator, patch: imagePatcher });
1737
+ vdom.register("graphics", { create: graphicsCreator, patch: graphicsPatcher });
1738
+ vdom.register("tilesprite", { create: tileSpriteCreator, patch: tileSpritePatcher });
1739
+ vdom.register("View", { create: viewCreator, patch: viewPatcher });
1740
+ vdom.register("Text", { create: textCreator, patch: textPatcher });
1741
+ vdom.register("NineSlice", { create: nineSliceCreator, patch: nineSlicePatcher });
1742
+ vdom.register("Particles", { create: particlesCreator, patch: particlesPatcher });
1743
+ vdom.register("Sprite", { create: spriteCreator, patch: spritePatcher });
1744
+ vdom.register("Image", { create: imageCreator, patch: imagePatcher });
1745
+ vdom.register("Graphics", { create: graphicsCreator, patch: graphicsPatcher });
1746
+ vdom.register("TileSprite", { create: tileSpriteCreator, patch: tileSpritePatcher });
1747
+ }
1748
+ const createCameraShakeFX = (camera, config) => {
1749
+ const duration = config.duration ?? 250;
1750
+ const intensity = typeof config.intensity === "object" ? new Phaser$1.Math.Vector2(config.intensity.x, config.intensity.y) : config.intensity ?? 0.01;
1751
+ camera.shake(duration, intensity, config.force ?? false, config.onComplete);
1752
+ };
1753
+ const createCameraFlashFX = (camera, config) => {
1754
+ const duration = config.duration ?? 200;
1755
+ const red = config.red ?? 255;
1756
+ const green = config.green ?? 255;
1757
+ const blue = config.blue ?? 255;
1758
+ camera.flash(duration, red, green, blue, config.force ?? false, config.onComplete);
1759
+ };
1760
+ const createCameraFadeInFX = (camera, config) => {
1761
+ const duration = config.duration ?? 300;
1762
+ const red = config.red ?? 0;
1763
+ const green = config.green ?? 0;
1764
+ const blue = config.blue ?? 0;
1765
+ camera.fadeIn(duration, red, green, blue, config.onComplete);
1766
+ };
1767
+ const createCameraFadeOutFX = (camera, config) => {
1768
+ const duration = config.duration ?? 300;
1769
+ const red = config.red ?? 0;
1770
+ const green = config.green ?? 0;
1771
+ const blue = config.blue ?? 0;
1772
+ camera.fadeOut(duration, red, green, blue, config.onComplete);
1773
+ };
1774
+ const createCameraZoomFX = (camera, config) => {
1775
+ const duration = config.duration ?? 250;
1776
+ const targetZoom = config.zoom ?? camera.zoom * 1.1;
1777
+ camera.zoomTo(targetZoom, duration, config.ease, config.force ?? false, config.onComplete);
1778
+ };
1779
+ function useCameraFX(cameraRef, options = {}) {
1780
+ const scene = vdom.useScene();
1781
+ const activeFxRef = vdom.useRef(/* @__PURE__ */ new Set());
1782
+ const baseZoomRef = vdom.useRef(null);
1783
+ const getCamera = vdom.useCallback(() => {
1784
+ return cameraRef?.current ?? scene.cameras.main;
1785
+ }, [cameraRef, scene]);
1786
+ const applyCameraFX = vdom.useCallback(
1787
+ (fx, config) => {
1788
+ const camera = getCamera();
1789
+ if (!camera) {
1790
+ console.warn("[useCameraFX] No camera available");
1791
+ return;
1792
+ }
1793
+ if (baseZoomRef.current === null) {
1794
+ baseZoomRef.current = camera.zoom;
1795
+ }
1796
+ const cleanup = fx(camera, config);
1797
+ if (typeof cleanup === "function") {
1798
+ activeFxRef.current.add(cleanup);
1799
+ }
1800
+ },
1801
+ [getCamera]
1802
+ );
1803
+ const clearCameraFX = vdom.useCallback(() => {
1804
+ const camera = getCamera();
1805
+ activeFxRef.current.forEach((cleanup) => cleanup());
1806
+ activeFxRef.current.clear();
1807
+ if (!camera) return;
1808
+ const cameraWithStops = camera;
1809
+ if (typeof cameraWithStops.stopShake === "function") cameraWithStops.stopShake();
1810
+ if (typeof cameraWithStops.stopFlash === "function") cameraWithStops.stopFlash();
1811
+ if (typeof cameraWithStops.stopFade === "function") cameraWithStops.stopFade();
1812
+ if (options.resetZoomOnClear !== false && baseZoomRef.current !== null) {
1813
+ camera.setZoom(baseZoomRef.current);
1814
+ }
1815
+ }, [getCamera, options.resetZoomOnClear]);
1816
+ vdom.useEffect(() => {
1817
+ return () => clearCameraFX();
1818
+ }, [clearCameraFX]);
1819
+ return { applyCameraFX, clearCameraFX };
1820
+ }
1821
+ function useScreenShake(config = {}, cameraRef) {
1822
+ const { applyCameraFX, clearCameraFX } = useCameraFX(cameraRef);
1823
+ vdom.useEffect(() => {
1824
+ applyCameraFX(createCameraShakeFX, config);
1825
+ return () => clearCameraFX();
1826
+ }, [applyCameraFX, clearCameraFX, config]);
1827
+ return { clearCameraFX };
1828
+ }
1829
+ function useCameraFlash(config = {}, cameraRef) {
1830
+ const { applyCameraFX, clearCameraFX } = useCameraFX(cameraRef);
1831
+ vdom.useEffect(() => {
1832
+ applyCameraFX(createCameraFlashFX, config);
1833
+ return () => clearCameraFX();
1834
+ }, [applyCameraFX, clearCameraFX, config]);
1835
+ return { clearCameraFX };
1836
+ }
1837
+ function useCameraFade(config = {}, cameraRef) {
1838
+ const { applyCameraFX, clearCameraFX } = useCameraFX(cameraRef);
1839
+ vdom.useEffect(() => {
1840
+ const fx = config.direction === "in" ? createCameraFadeInFX : createCameraFadeOutFX;
1841
+ applyCameraFX(fx, config);
1842
+ return () => clearCameraFX();
1843
+ }, [applyCameraFX, clearCameraFX, config]);
1844
+ return { clearCameraFX };
1845
+ }
1846
+ function useCameraZoom(config = {}, cameraRef) {
1847
+ const { applyCameraFX, clearCameraFX } = useCameraFX(cameraRef);
1848
+ vdom.useEffect(() => {
1849
+ applyCameraFX(createCameraZoomFX, config);
1850
+ return () => clearCameraFX();
1851
+ }, [applyCameraFX, clearCameraFX, config]);
1852
+ return { clearCameraFX };
1853
+ }
1854
+ const CAMERA_FX_REGISTRY = {
1855
+ shake: createCameraShakeFX,
1856
+ flash: createCameraFlashFX,
1857
+ fadeIn: createCameraFadeInFX,
1858
+ fadeOut: createCameraFadeOutFX,
1859
+ zoom: createCameraZoomFX
1860
+ };
1861
+ const DEFAULT_CAMERA_FX = {
1862
+ fx: "shake",
1863
+ fxConfig: { duration: 200, force: false }
1864
+ };
1865
+ function applyCameraFXByName(applyCameraFX, fxName, fxConfig) {
1866
+ const name = fxName ?? DEFAULT_CAMERA_FX.fx;
1867
+ const config = fxConfig ?? DEFAULT_CAMERA_FX.fxConfig;
1868
+ const fx = CAMERA_FX_REGISTRY[name];
1869
+ if (fx) {
1870
+ applyCameraFX(fx, config);
1871
+ return true;
1872
+ }
1873
+ return false;
1874
+ }
1875
+ function resolveCameraFX(props) {
1876
+ return {
1877
+ fx: props?.fx ?? DEFAULT_CAMERA_FX.fx,
1878
+ fxConfig: props?.fxConfig ?? DEFAULT_CAMERA_FX.fxConfig
1879
+ };
1880
+ }
6
1881
  function useFX(ref) {
7
1882
  const activeEffectsRef = vdom.useRef(/* @__PURE__ */ new Set());
8
1883
  vdom.useEffect(() => {
@@ -221,6 +2096,221 @@ function noMemo(vnode) {
221
2096
  function memo(vnode) {
222
2097
  return setMemoSafe(vnode, true);
223
2098
  }
2099
+ function useParticles(ref) {
2100
+ const getManager = vdom.useCallback(() => ref.current ?? null, [ref]);
2101
+ const getEmitter = vdom.useCallback(() => {
2102
+ const current = ref.current;
2103
+ if (!current) return null;
2104
+ if (isParticleEmitter(current)) return current;
2105
+ return getFirstEmitter(current);
2106
+ }, [ref]);
2107
+ const start = vdom.useCallback(() => {
2108
+ const emitter = getEmitter();
2109
+ emitter?.start();
2110
+ }, [getEmitter]);
2111
+ const stop = vdom.useCallback(() => {
2112
+ const emitter = getEmitter();
2113
+ emitter?.stop();
2114
+ }, [getEmitter]);
2115
+ const explode = vdom.useCallback(
2116
+ (count, x, y) => {
2117
+ const emitter = getEmitter();
2118
+ emitter?.explode(count, x, y);
2119
+ },
2120
+ [getEmitter]
2121
+ );
2122
+ const setConfig = vdom.useCallback(
2123
+ (config) => {
2124
+ const emitter = getEmitter();
2125
+ applyEmitterConfig(emitter, config);
2126
+ },
2127
+ [getEmitter]
2128
+ );
2129
+ const setEmitZone = vdom.useCallback(
2130
+ (zone, width, height) => {
2131
+ const emitter = getEmitter();
2132
+ const emitZone = buildEmitZoneFromLayout(zone, width, height);
2133
+ applyEmitZone(emitter, emitZone);
2134
+ },
2135
+ [getEmitter]
2136
+ );
2137
+ const setExcludeZones = vdom.useCallback(
2138
+ (zones, width, height) => {
2139
+ const emitter = getEmitter();
2140
+ const deathZones = buildDeathZonesFromLayout(zones, width, height);
2141
+ applyDeathZone(emitter, deathZones);
2142
+ },
2143
+ [getEmitter]
2144
+ );
2145
+ return {
2146
+ getManager,
2147
+ getEmitter,
2148
+ start,
2149
+ stop,
2150
+ explode,
2151
+ setConfig,
2152
+ setEmitZone,
2153
+ setExcludeZones
2154
+ };
2155
+ }
2156
+ function createPhaserJSXPlugin(config) {
2157
+ return {
2158
+ key: "PhaserJSX",
2159
+ plugin: PhaserJSXPlugin,
2160
+ start: true,
2161
+ data: config
2162
+ };
2163
+ }
2164
+ class PhaserJSXPlugin extends Phaser$1.Plugins.BasePlugin {
2165
+ config;
2166
+ mountHandle;
2167
+ container;
2168
+ targetScene;
2169
+ /**
2170
+ * Constructor - receives plugin manager and optional mapping
2171
+ */
2172
+ constructor(pluginManager) {
2173
+ super(pluginManager);
2174
+ }
2175
+ /**
2176
+ * Init lifecycle - called first with config data
2177
+ */
2178
+ init(data) {
2179
+ if (data) {
2180
+ this.config = { ...data };
2181
+ }
2182
+ }
2183
+ /**
2184
+ * Start lifecycle - called when plugin should start
2185
+ */
2186
+ start() {
2187
+ this.game.events.on("ready", this.onGameReady, this);
2188
+ }
2189
+ /**
2190
+ * Game ready handler - scene system is now initialized
2191
+ */
2192
+ onGameReady() {
2193
+ const scenes = this.game.scene.scenes;
2194
+ if (scenes.length > 0) {
2195
+ const targetScene = scenes[0];
2196
+ if (!targetScene) return;
2197
+ this.targetScene = targetScene;
2198
+ targetScene.events.once("create", this.onSceneCreate, this);
2199
+ if (targetScene.scene.isActive()) {
2200
+ this.onSceneCreate();
2201
+ }
2202
+ } else {
2203
+ console.warn("[PhaserJSX Plugin] No scenes found to mount JSX");
2204
+ }
2205
+ }
2206
+ /**
2207
+ * Scene create handler - auto-mount JSX
2208
+ */
2209
+ onSceneCreate() {
2210
+ const shouldAutoMount = this.config?.autoMount !== false;
2211
+ if (shouldAutoMount && this.config?.component) {
2212
+ this.mount();
2213
+ if (this.config?.autoResize !== false) {
2214
+ this.setupResizeHandler();
2215
+ }
2216
+ } else {
2217
+ console.warn("[PhaserJSX Plugin] Auto-mount disabled or no component configured");
2218
+ }
2219
+ }
2220
+ /**
2221
+ * Setup resize event handler
2222
+ */
2223
+ setupResizeHandler() {
2224
+ if (!this.targetScene) return;
2225
+ this.targetScene.scale.on("resize", this.onResize, this);
2226
+ }
2227
+ /**
2228
+ * Handle scene resize - update component props
2229
+ */
2230
+ onResize(gameSize) {
2231
+ if (!this.mountHandle || !this.config?.component || !this.container) return;
2232
+ const props = this.config.props || {};
2233
+ const width = props.width ?? gameSize.width;
2234
+ const height = props.height ?? gameSize.height;
2235
+ this.mountHandle = vdom.mountJSX(this.container, this.config.component, {
2236
+ ...props,
2237
+ width,
2238
+ height
2239
+ });
2240
+ }
2241
+ /**
2242
+ * Configure plugin
2243
+ * Can be called from scene to set up component dynamically
2244
+ */
2245
+ configure(component, props) {
2246
+ const newConfig = {
2247
+ component
2248
+ };
2249
+ if (props !== void 0) {
2250
+ newConfig.props = props;
2251
+ }
2252
+ this.config = {
2253
+ ...this.config,
2254
+ ...newConfig
2255
+ };
2256
+ }
2257
+ /**
2258
+ * Mount JSX component
2259
+ */
2260
+ mount() {
2261
+ if (!this.targetScene) {
2262
+ console.warn("[PhaserJSX Plugin] No scene available for mounting");
2263
+ return;
2264
+ }
2265
+ if (!this.config?.component) {
2266
+ console.warn("[PhaserJSX Plugin] No component configured for mounting");
2267
+ return;
2268
+ }
2269
+ if (!this.container) {
2270
+ const containerConfig = this.config.container || {};
2271
+ this.container = this.targetScene.add.container(
2272
+ containerConfig.x ?? 0,
2273
+ containerConfig.y ?? 0
2274
+ );
2275
+ this.container.setDepth(containerConfig.depth ?? 100);
2276
+ }
2277
+ const props = this.config.props || {};
2278
+ const width = props.width ?? this.targetScene.scale.width;
2279
+ const height = props.height ?? this.targetScene.scale.height;
2280
+ this.mountHandle = vdom.mountJSX(this.container, this.config.component, {
2281
+ ...props,
2282
+ width,
2283
+ height
2284
+ });
2285
+ }
2286
+ /**
2287
+ * Unmount JSX component
2288
+ */
2289
+ unmount() {
2290
+ if (this.mountHandle) {
2291
+ this.mountHandle.unmount();
2292
+ this.mountHandle = void 0;
2293
+ }
2294
+ }
2295
+ /**
2296
+ * Destroy lifecycle - cleanup
2297
+ */
2298
+ destroy() {
2299
+ this.unmount();
2300
+ if (this.container) {
2301
+ this.container.destroy();
2302
+ this.container = void 0;
2303
+ }
2304
+ this.game.events.off("ready", this.onGameReady, this);
2305
+ if (this.targetScene) {
2306
+ this.targetScene.events.off("create", this.onSceneCreate, this);
2307
+ this.targetScene.scale.off("resize", this.onResize, this);
2308
+ }
2309
+ this.targetScene = void 0;
2310
+ this.config = void 0;
2311
+ super.destroy();
2312
+ }
2313
+ }
224
2314
  function useColorMode() {
225
2315
  const [colorMode, setColorModeState] = vdom.useState(vdom.themeRegistry.getColorMode());
226
2316
  vdom.useEffect(() => {
@@ -316,7 +2406,7 @@ function setColorPreset(presetName, colorMode) {
316
2406
  return;
317
2407
  }
318
2408
  setTimeout(() => {
319
- Promise.resolve().then(() => require("./TransformOriginView-KcTgaYRi.cjs")).then((n) => n.vdom).then(({ remountAll }) => {
2409
+ Promise.resolve().then(() => require("./TransformOriginView-Bx81YEUU.cjs")).then((n) => n.vdom).then(({ remountAll }) => {
320
2410
  remountAll();
321
2411
  });
322
2412
  }, 0);
@@ -391,7 +2481,7 @@ function useThemeTokens() {
391
2481
  }, [localTheme]);
392
2482
  return tokens;
393
2483
  }
394
- vdom.registerBuiltins();
2484
+ registerBuiltins();
395
2485
  exports.Accordion = vdom.Accordion;
396
2486
  exports.AlertDialog = vdom.AlertDialog;
397
2487
  exports.Button = vdom.Button;
@@ -411,10 +2501,12 @@ exports.Graphics = vdom.Graphics;
411
2501
  exports.HexColor = vdom.HexColor;
412
2502
  exports.Icon = vdom.Icon;
413
2503
  exports.Image = vdom.Image;
2504
+ exports.Joystick = vdom.Joystick;
414
2505
  exports.KeyboardInputManager = vdom.KeyboardInputManager;
415
2506
  exports.Modal = vdom.Modal;
416
2507
  exports.NineSlice = vdom.NineSlice;
417
2508
  exports.NineSliceButton = vdom.NineSliceButton;
2509
+ exports.Particles = vdom.Particles;
418
2510
  exports.Portal = vdom.Portal;
419
2511
  exports.RadioButton = vdom.RadioButton;
420
2512
  exports.RadioGroup = vdom.RadioGroup;
@@ -426,9 +2518,10 @@ exports.ScrollView = vdom.ScrollView;
426
2518
  exports.Sidebar = vdom.Sidebar;
427
2519
  exports.Slider = vdom.Slider;
428
2520
  exports.SpringPhysics = vdom.SpringPhysics;
429
- exports.Sprite = vdom.Sprite;
2521
+ exports.Tab = vdom.Tab;
2522
+ exports.TabPanel = vdom.TabPanel;
2523
+ exports.Tabs = vdom.Tabs;
430
2524
  exports.Text = vdom.Text;
431
- exports.TileSprite = vdom.TileSprite;
432
2525
  exports.Toggle = vdom.Toggle;
433
2526
  exports.TransformOriginView = vdom.TransformOriginView;
434
2527
  exports.View = vdom.View;
@@ -477,19 +2570,21 @@ exports.disposeCtx = vdom.disposeCtx;
477
2570
  exports.ensureContrast = vdom.ensureContrast;
478
2571
  exports.forestGreenPreset = vdom.forestGreenPreset;
479
2572
  exports.generateColorScale = vdom.generateColorScale;
2573
+ exports.getBackgroundGraphics = vdom.getBackgroundGraphics;
480
2574
  exports.getContrastRatio = vdom.getContrastRatio;
481
2575
  exports.getCurrent = vdom.getCurrent;
2576
+ exports.getLayoutProps = vdom.getLayoutProps;
2577
+ exports.getLayoutRect = vdom.getLayoutRect;
2578
+ exports.getLayoutSize = vdom.getLayoutSize;
2579
+ exports.getMountStats = vdom.getMountStats;
482
2580
  exports.getPreset = vdom.getPreset;
483
2581
  exports.getPresetWithMode = vdom.getPresetWithMode;
484
2582
  exports.getRenderContext = vdom.getRenderContext;
485
2583
  exports.getThemedProps = vdom.getThemedProps;
486
- exports.graphicsCreator = vdom.graphicsCreator;
487
- exports.graphicsPatcher = vdom.graphicsPatcher;
2584
+ exports.getWorldLayoutRect = vdom.getWorldLayoutRect;
488
2585
  exports.hex = vdom.hex;
489
2586
  exports.hexToNumber = vdom.hexToNumber;
490
2587
  exports.host = vdom.host;
491
- exports.imageCreator = vdom.imageCreator;
492
- exports.imagePatcher = vdom.imagePatcher;
493
2588
  exports.isAnimatedSignal = vdom.isAnimatedSignal;
494
2589
  exports.lighten = vdom.lighten;
495
2590
  exports.lightenHex = vdom.lightenHex;
@@ -498,12 +2593,11 @@ exports.midnightPreset = vdom.midnightPreset;
498
2593
  exports.mount = vdom.mount;
499
2594
  exports.mountComponent = vdom.mountJSX;
500
2595
  exports.mountJSX = vdom.mountJSX;
501
- exports.nineSliceCreator = vdom.nineSliceCreator;
502
- exports.nineSlicePatcher = vdom.nineSlicePatcher;
503
2596
  exports.nodeRegistry = vdom.nodeRegistry;
504
2597
  exports.normalizeCornerRadius = vdom.normalizeCornerRadius;
505
2598
  exports.normalizeEdgeInsets = vdom.normalizeEdgeInsets;
506
2599
  exports.normalizeGap = vdom.normalizeGap;
2600
+ exports.normalizeVNodeLike = vdom.normalizeVNodeLike;
507
2601
  exports.numberToHex = vdom.numberToHex;
508
2602
  exports.numberToRgb = vdom.numberToRgb;
509
2603
  exports.oceanBluePreset = vdom.oceanBluePreset;
@@ -511,7 +2605,6 @@ exports.patchVNode = vdom.patchVNode;
511
2605
  exports.portalRegistry = vdom.portalRegistry;
512
2606
  exports.presets = vdom.presets;
513
2607
  exports.register = vdom.register;
514
- exports.registerBuiltins = vdom.registerBuiltins;
515
2608
  exports.releaseAllSVGTextures = vdom.releaseAllSVGTextures;
516
2609
  exports.releaseSVGTexture = vdom.releaseSVGTexture;
517
2610
  exports.releaseSVGTextures = vdom.releaseSVGTextures;
@@ -520,22 +2613,20 @@ exports.resolveEffect = vdom.resolveEffect;
520
2613
  exports.rgbToNumber = vdom.rgbToNumber;
521
2614
  exports.shallowEqual = vdom.shallowEqual;
522
2615
  exports.shouldComponentUpdate = vdom.shouldComponentUpdate;
523
- exports.spriteCreator = vdom.spriteCreator;
524
- exports.spritePatcher = vdom.spritePatcher;
525
2616
  exports.svgToTexture = vdom.svgToTexture;
526
- exports.textCreator = vdom.textCreator;
527
- exports.textPatcher = vdom.textPatcher;
528
2617
  exports.themeRegistry = vdom.themeRegistry;
529
- exports.tileSpriteCreator = vdom.tileSpriteCreator;
530
- exports.tileSpritePatcher = vdom.tileSpritePatcher;
531
2618
  exports.unmount = vdom.unmount;
532
2619
  exports.unmountJSX = vdom.unmountJSX;
533
2620
  exports.unwrapSignal = vdom.unwrapSignal;
2621
+ exports.useBackgroundGraphics = vdom.useBackgroundGraphics;
534
2622
  exports.useCallback = vdom.useCallback;
535
2623
  exports.useEffect = vdom.useEffect;
536
2624
  exports.useForceRedraw = vdom.useForceRedraw;
537
2625
  exports.useGameObjectEffect = vdom.useGameObjectEffect;
538
2626
  exports.useIconPreload = vdom.useIconPreload;
2627
+ exports.useLayoutEffect = vdom.useLayoutEffect;
2628
+ exports.useLayoutRect = vdom.useLayoutRect;
2629
+ exports.useLayoutSize = vdom.useLayoutSize;
539
2630
  exports.useMemo = vdom.useMemo;
540
2631
  exports.useRedraw = vdom.useRedraw;
541
2632
  exports.useRef = vdom.useRef;
@@ -546,8 +2637,8 @@ exports.useSpring = vdom.useSpring;
546
2637
  exports.useSprings = vdom.useSprings;
547
2638
  exports.useState = vdom.useState;
548
2639
  exports.useTheme = vdom.useTheme;
549
- exports.viewCreator = vdom.viewCreator;
550
- exports.viewPatcher = vdom.viewPatcher;
2640
+ exports.useViewportSize = vdom.useViewportSize;
2641
+ exports.useWorldLayoutRect = vdom.useWorldLayoutRect;
551
2642
  exports.viewportRegistry = vdom.viewportRegistry;
552
2643
  exports.withHooks = vdom.withHooks;
553
2644
  exports.Fragment = jsxRuntime.Fragment;
@@ -557,13 +2648,29 @@ Object.defineProperty(exports, "computed", {
557
2648
  enumerable: true,
558
2649
  get: () => signalsCore.computed
559
2650
  });
2651
+ exports.CAMERA_FX_REGISTRY = CAMERA_FX_REGISTRY;
2652
+ exports.DEFAULT_CAMERA_FX = DEFAULT_CAMERA_FX;
560
2653
  exports.DEFAULT_FX = DEFAULT_FX;
561
2654
  exports.FX_REGISTRY = FX_REGISTRY;
2655
+ exports.PARTICLE_PRESET_REGISTRY = PARTICLE_PRESET_REGISTRY;
2656
+ exports.PhaserJSXPlugin = PhaserJSXPlugin;
2657
+ exports.Sprite = Sprite;
2658
+ exports.TileSprite = TileSprite;
2659
+ exports.applyCameraFXByName = applyCameraFXByName;
562
2660
  exports.applyFXByName = applyFXByName;
2661
+ exports.buildDeathZonesFromLayout = buildDeathZonesFromLayout;
2662
+ exports.buildEmitZone = buildEmitZone;
2663
+ exports.buildEmitZoneFromLayout = buildEmitZoneFromLayout;
563
2664
  exports.colorsToTheme = colorsToTheme;
564
2665
  exports.createBlurFX = createBlurFX;
2666
+ exports.createCameraFadeInFX = createCameraFadeInFX;
2667
+ exports.createCameraFadeOutFX = createCameraFadeOutFX;
2668
+ exports.createCameraFlashFX = createCameraFlashFX;
2669
+ exports.createCameraShakeFX = createCameraShakeFX;
2670
+ exports.createCameraZoomFX = createCameraZoomFX;
565
2671
  exports.createColorMatrixFX = createColorMatrixFX;
566
2672
  exports.createGlowFX = createGlowFX;
2673
+ exports.createPhaserJSXPlugin = createPhaserJSXPlugin;
567
2674
  exports.createPixelateFX = createPixelateFX;
568
2675
  exports.createShadowFX = createShadowFX;
569
2676
  exports.createVignetteFX = createVignetteFX;
@@ -573,17 +2680,42 @@ exports.getBorderColor = getBorderColor;
573
2680
  exports.getCurrentPreset = getCurrentPreset;
574
2681
  exports.getSurfaceColor = getSurfaceColor;
575
2682
  exports.getTextColor = getTextColor;
2683
+ exports.graphicsCreator = graphicsCreator;
2684
+ exports.graphicsPatcher = graphicsPatcher;
2685
+ exports.imageCreator = imageCreator;
2686
+ exports.imagePatcher = imagePatcher;
576
2687
  exports.memo = memo;
2688
+ exports.nineSliceCreator = nineSliceCreator;
2689
+ exports.nineSlicePatcher = nineSlicePatcher;
577
2690
  exports.noMemo = noMemo;
2691
+ exports.particlesCreator = particlesCreator;
2692
+ exports.particlesPatcher = particlesPatcher;
2693
+ exports.registerBuiltins = registerBuiltins;
2694
+ exports.resolveCameraFX = resolveCameraFX;
578
2695
  exports.resolveFX = resolveFX;
2696
+ exports.resolveParticlePreset = resolveParticlePreset;
579
2697
  exports.setColorMode = setColorMode;
580
2698
  exports.setColorPreset = setColorPreset;
2699
+ exports.spriteCreator = spriteCreator;
2700
+ exports.spritePatcher = spritePatcher;
2701
+ exports.textCreator = textCreator;
2702
+ exports.textPatcher = textPatcher;
2703
+ exports.tileSpriteCreator = tileSpriteCreator;
2704
+ exports.tileSpritePatcher = tileSpritePatcher;
581
2705
  exports.useBlur = useBlur;
2706
+ exports.useCameraFX = useCameraFX;
2707
+ exports.useCameraFade = useCameraFade;
2708
+ exports.useCameraFlash = useCameraFlash;
2709
+ exports.useCameraZoom = useCameraZoom;
582
2710
  exports.useColorMode = useColorMode;
583
2711
  exports.useColors = useColors;
584
2712
  exports.useFX = useFX;
585
2713
  exports.useGlow = useGlow;
2714
+ exports.useParticles = useParticles;
2715
+ exports.useScreenShake = useScreenShake;
586
2716
  exports.useShadow = useShadow;
587
2717
  exports.useThemeSubscription = useThemeSubscription;
588
2718
  exports.useThemeTokens = useThemeTokens;
2719
+ exports.viewCreator = viewCreator;
2720
+ exports.viewPatcher = viewPatcher;
589
2721
  //# sourceMappingURL=index.cjs.map