@number10/phaserjsx 0.3.1 → 0.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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 +11 -1
  136. package/dist/TransformOriginView-CzVjS16F.js.map +0 -1
  137. package/dist/TransformOriginView-KcTgaYRi.cjs.map +0 -1
@@ -74,623 +74,6 @@ const host = {
74
74
  layout() {
75
75
  }
76
76
  };
77
- function shallowEqual$1(a, b) {
78
- if (!a || !b) return a === b;
79
- if (a.length !== b.length) return false;
80
- return a.every((val, i) => val === b[i]);
81
- }
82
- function applyGraphicsProps(node, _prev, next) {
83
- const prevDeps = node.__drawDependencies;
84
- const nextDeps = next.dependencies;
85
- const depsChanged2 = !shallowEqual$1(prevDeps, nextDeps);
86
- if (depsChanged2 && next.onDraw) {
87
- if (next.autoClear !== false) {
88
- node.clear();
89
- }
90
- next.onDraw(node, next);
91
- node.__drawDependencies = nextDeps;
92
- }
93
- }
94
- function applyGraphicsLayout(node, prev, next) {
95
- node.__layoutProps = next;
96
- if (prev.width !== next.width || prev.height !== next.height || prev.headless !== next.headless) {
97
- node.__getLayoutSize = () => {
98
- if (next.headless ?? true) {
99
- return { width: 0.01, height: 0.01 };
100
- }
101
- return {
102
- width: typeof next.width === "number" ? next.width : 0,
103
- height: typeof next.height === "number" ? next.height : 0
104
- };
105
- };
106
- }
107
- }
108
- function normalizeVisible$1(visible) {
109
- if (visible === void 0) return true;
110
- if (typeof visible === "boolean") return visible;
111
- if (visible === "visible") return true;
112
- if (visible === "invisible" || visible === "none") return false;
113
- return true;
114
- }
115
- function applyPhaserProps(node, prev, next) {
116
- if (prev.alpha !== next.alpha && typeof next.alpha === "number") {
117
- node.setAlpha?.(next.alpha);
118
- }
119
- if (prev.depth !== next.depth && typeof next.depth === "number") {
120
- node.setDepth?.(next.depth);
121
- }
122
- if (prev.visible !== next.visible) {
123
- const visibleValue = normalizeVisible$1(next.visible);
124
- node.visible = visibleValue;
125
- }
126
- }
127
- function applyTransformProps(node, prev, next) {
128
- if (prev.x !== next.x && typeof next.x === "number") {
129
- node.x = next.x;
130
- }
131
- if (prev.y !== next.y && typeof next.y === "number") {
132
- node.y = next.y;
133
- }
134
- if (prev.rotation !== next.rotation && typeof next.rotation === "number") {
135
- node.rotation = next.rotation;
136
- }
137
- const nextScale = next.scale;
138
- const nextScaleX = next.scaleX;
139
- const nextScaleY = next.scaleY;
140
- const prevScale = prev.scale;
141
- const prevScaleX = prev.scaleX;
142
- const prevScaleY = prev.scaleY;
143
- if (nextScale !== void 0 && nextScale !== prevScale) {
144
- node.setScale?.(nextScale, nextScale);
145
- } else if (nextScaleX !== prevScaleX || nextScaleY !== prevScaleY) {
146
- const currentScaleX = node.scaleX ?? 1;
147
- const currentScaleY = node.scaleY ?? 1;
148
- const sx = nextScaleX ?? currentScaleX;
149
- const sy = nextScaleY ?? currentScaleY;
150
- node.setScale?.(sx, sy);
151
- }
152
- }
153
- function createGraphicsLayout(graphics, props) {
154
- if (props.headless === false) {
155
- if (typeof props.width !== "number" || typeof props.height !== "number") {
156
- throw new Error(
157
- "Graphics component requires explicit width and height props when headless=false"
158
- );
159
- }
160
- }
161
- graphics.__layoutProps = props;
162
- graphics.__getLayoutSize = () => {
163
- if (graphics.__layoutProps?.headless ?? true) {
164
- return { width: 0.01, height: 0.01 };
165
- }
166
- return {
167
- width: props.width ?? 0,
168
- height: props.height ?? 0
169
- };
170
- };
171
- graphics.__drawDependencies = props.dependencies;
172
- }
173
- function normalizeVisible(visible) {
174
- if (visible === void 0) return true;
175
- if (typeof visible === "boolean") return visible;
176
- if (visible === "visible") return true;
177
- if (visible === "invisible" || visible === "none") return false;
178
- return true;
179
- }
180
- function createPhaser(node, props) {
181
- if (props.visible !== void 0) {
182
- node.visible = normalizeVisible(props.visible);
183
- }
184
- if (props.depth !== void 0) {
185
- node.setDepth(props.depth);
186
- }
187
- if (props.alpha !== void 0) {
188
- node.setAlpha(props.alpha);
189
- }
190
- }
191
- function createTransform(node, props) {
192
- if (props.scaleX !== void 0 || props.scaleY !== void 0) {
193
- node.setScale(
194
- props.scaleX ?? 1,
195
- props.scaleY ?? 1
196
- );
197
- }
198
- if (props.rotation !== void 0) {
199
- node.setRotation(props.rotation);
200
- }
201
- }
202
- const graphicsCreator = (scene, props) => {
203
- const graphics = scene.add.graphics();
204
- graphics.setPosition(props.x ?? 0, props.y ?? 0);
205
- createTransform(graphics, props);
206
- createPhaser(graphics, props);
207
- createGraphicsLayout(graphics, props);
208
- if (props.onDraw) {
209
- props.onDraw(graphics, props);
210
- }
211
- return graphics;
212
- };
213
- const graphicsPatcher = (node, prev, next) => {
214
- applyTransformProps(node, prev, next);
215
- applyPhaserProps(node, prev, next);
216
- applyGraphicsProps(node, prev, next);
217
- applyGraphicsLayout(node, prev, next);
218
- };
219
- function calculateFitScale$1(image, targetWidth, targetHeight, fit = "fill") {
220
- const textureWidth = image.width;
221
- const textureHeight = image.height;
222
- if (textureWidth === 0 || textureHeight === 0) {
223
- return { scaleX: 1, scaleY: 1 };
224
- }
225
- if (fit === "fill") {
226
- return {
227
- scaleX: targetWidth / textureWidth,
228
- scaleY: targetHeight / textureHeight
229
- };
230
- }
231
- const targetAspect = targetWidth / targetHeight;
232
- const textureAspect = textureWidth / textureHeight;
233
- if (fit === "contain") {
234
- const scale = targetAspect > textureAspect ? targetHeight / textureHeight : targetWidth / textureWidth;
235
- return { scaleX: scale, scaleY: scale };
236
- }
237
- if (fit === "cover") {
238
- const scale = targetAspect < textureAspect ? targetHeight / textureHeight : targetWidth / textureWidth;
239
- return { scaleX: scale, scaleY: scale };
240
- }
241
- return { scaleX: 1, scaleY: 1 };
242
- }
243
- function applyImageProps(image, prev, next) {
244
- const textureChanged = prev.texture !== next.texture || prev.frame !== next.frame;
245
- if (textureChanged && next.texture) {
246
- image.setTexture(next.texture, next.frame);
247
- }
248
- if (prev.tint !== next.tint) {
249
- if (typeof next.tint === "number") {
250
- image.setTint(next.tint);
251
- } else {
252
- image.clearTint();
253
- }
254
- }
255
- if (prev.originX !== next.originX || prev.originY !== next.originY) {
256
- const originX = next.originX ?? image.originX;
257
- const originY = next.originY ?? image.originY;
258
- image.setOrigin(originX, originY);
259
- }
260
- const displayWidthChanged = prev.displayWidth !== next.displayWidth;
261
- const displayHeightChanged = prev.displayHeight !== next.displayHeight;
262
- const fitChanged = prev.fit !== next.fit;
263
- if (displayWidthChanged || displayHeightChanged || fitChanged || textureChanged) {
264
- if (typeof next.displayWidth === "number" && typeof next.displayHeight === "number") {
265
- const { scaleX, scaleY } = calculateFitScale$1(
266
- image,
267
- next.displayWidth,
268
- next.displayHeight,
269
- next.fit
270
- );
271
- image.setScale(scaleX, scaleY);
272
- } else if (typeof next.displayWidth === "number") {
273
- const scale = next.displayWidth / image.width;
274
- image.setScale(scale);
275
- } else if (typeof next.displayHeight === "number") {
276
- const scale = next.displayHeight / image.height;
277
- image.setScale(scale, scale);
278
- }
279
- }
280
- }
281
- function applyImageLayout(image, prev, next) {
282
- image.__layoutProps = next;
283
- if (prev.headless !== next.headless) {
284
- image.__getLayoutSize = () => {
285
- if (image.__layoutProps?.headless) {
286
- return { width: 0.01, height: 0.01 };
287
- }
288
- return {
289
- width: image.displayWidth,
290
- height: image.displayHeight
291
- };
292
- };
293
- }
294
- }
295
- function createImageLayout(image, props) {
296
- image.__layoutProps = props;
297
- image.__getLayoutSize = () => {
298
- if (image.__layoutProps?.headless) {
299
- return { width: 0.01, height: 0.01 };
300
- }
301
- return {
302
- width: image.displayWidth,
303
- height: image.displayHeight
304
- };
305
- };
306
- }
307
- const imageCreator = (scene, props) => {
308
- const image = scene.add.image(props.x ?? 0, props.y ?? 0, props.texture, props.frame);
309
- if (props.headless) {
310
- image.setOrigin(0.5, 0.5);
311
- } else {
312
- image.setOrigin(0, 0);
313
- }
314
- if (props.originX !== void 0 || props.originY !== void 0) {
315
- image.setOrigin(props.originX ?? image.originX, props.originY ?? image.originY);
316
- }
317
- const normalizedProps = { ...props };
318
- if (props.headless) {
319
- delete normalizedProps.padding;
320
- delete normalizedProps.margin;
321
- delete normalizedProps.gap;
322
- } else {
323
- if (normalizedProps.rotation !== void 0) {
324
- delete normalizedProps.rotation;
325
- }
326
- }
327
- createTransform(image, normalizedProps);
328
- createPhaser(image, normalizedProps);
329
- if (props.tint !== void 0) {
330
- image.setTint(props.tint);
331
- }
332
- if (props.displayWidth !== void 0 || props.displayHeight !== void 0) {
333
- if (props.displayWidth !== void 0 && props.displayHeight !== void 0) {
334
- const fit = props.fit ?? "fill";
335
- const textureWidth = image.width;
336
- const textureHeight = image.height;
337
- if (textureWidth > 0 && textureHeight > 0) {
338
- if (fit === "fill") {
339
- image.setDisplaySize(props.displayWidth, props.displayHeight);
340
- } else if (fit === "contain") {
341
- const targetAspect = props.displayWidth / props.displayHeight;
342
- const textureAspect = textureWidth / textureHeight;
343
- const scale = targetAspect > textureAspect ? props.displayHeight / textureHeight : props.displayWidth / textureWidth;
344
- image.setScale(scale);
345
- } else if (fit === "cover") {
346
- const targetAspect = props.displayWidth / props.displayHeight;
347
- const textureAspect = textureWidth / textureHeight;
348
- const scale = targetAspect < textureAspect ? props.displayHeight / textureHeight : props.displayWidth / textureWidth;
349
- image.setScale(scale);
350
- }
351
- }
352
- } else if (props.displayWidth !== void 0) {
353
- const scale = props.displayWidth / image.width;
354
- image.setScale(scale);
355
- } else if (props.displayHeight !== void 0) {
356
- const scale = props.displayHeight / image.height;
357
- image.setScale(scale);
358
- }
359
- }
360
- createImageLayout(image, normalizedProps);
361
- if (props.onReady) {
362
- props.onReady(image);
363
- }
364
- return image;
365
- };
366
- const imagePatcher = (node, prev, next) => {
367
- if (prev.headless !== next.headless) {
368
- if (next.headless) {
369
- node.setOrigin(0.5, 0.5);
370
- } else {
371
- node.setOrigin(0, 0);
372
- }
373
- }
374
- const normalizedPrev = { ...prev };
375
- const normalizedNext = { ...next };
376
- if (next.headless) {
377
- delete normalizedNext.padding;
378
- delete normalizedNext.margin;
379
- delete normalizedNext.gap;
380
- } else {
381
- if (normalizedNext.rotation !== void 0) {
382
- delete normalizedNext.rotation;
383
- }
384
- }
385
- if (prev.headless) {
386
- delete normalizedPrev.padding;
387
- delete normalizedPrev.margin;
388
- delete normalizedPrev.gap;
389
- } else {
390
- if (normalizedPrev.rotation !== void 0) {
391
- delete normalizedPrev.rotation;
392
- }
393
- }
394
- applyTransformProps(node, normalizedPrev, normalizedNext);
395
- applyPhaserProps(node, normalizedPrev, normalizedNext);
396
- applyImageProps(node, normalizedPrev, normalizedNext);
397
- applyImageLayout(node, normalizedPrev, normalizedNext);
398
- };
399
- function applyNineSliceProps(nineSlice, prev, next) {
400
- const textureChanged = prev.texture !== next.texture || prev.frame !== next.frame;
401
- if (textureChanged && next.texture) {
402
- nineSlice.setTexture(next.texture, next.frame);
403
- }
404
- const sliceChanged = prev.leftWidth !== next.leftWidth || prev.rightWidth !== next.rightWidth || prev.topHeight !== next.topHeight || prev.bottomHeight !== next.bottomHeight;
405
- if (sliceChanged) {
406
- const width = typeof next.width === "number" ? next.width : nineSlice.width;
407
- const height = typeof next.height === "number" ? next.height : nineSlice.height;
408
- nineSlice.setSlices(
409
- width,
410
- height,
411
- next.leftWidth ?? prev.leftWidth ?? 0,
412
- next.rightWidth ?? prev.rightWidth ?? 0,
413
- next.topHeight ?? prev.topHeight,
414
- next.bottomHeight ?? prev.bottomHeight
415
- );
416
- }
417
- const prevWidth = typeof prev.width === "number" ? prev.width : nineSlice.width;
418
- const nextWidth = typeof next.width === "number" ? next.width : nineSlice.width;
419
- const prevHeight = typeof prev.height === "number" ? prev.height : nineSlice.height;
420
- const nextHeight = typeof next.height === "number" ? next.height : nineSlice.height;
421
- if (prevWidth !== nextWidth || prevHeight !== nextHeight) {
422
- nineSlice.setSize(nextWidth, nextHeight);
423
- }
424
- if (prev.tint !== next.tint) {
425
- if (next.tint !== void 0) {
426
- nineSlice.setTint(next.tint);
427
- } else {
428
- nineSlice.clearTint();
429
- }
430
- }
431
- }
432
- function applyNineSliceLayout(nineSlice, prev, next) {
433
- nineSlice.__layoutProps = next;
434
- if (prev.width !== next.width || prev.height !== next.height) {
435
- nineSlice.__getLayoutSize = () => {
436
- return {
437
- width: nineSlice.width,
438
- height: nineSlice.height
439
- };
440
- };
441
- }
442
- }
443
- function createNineSliceLayout(nineSlice, props) {
444
- nineSlice.__layoutProps = props;
445
- nineSlice.__getLayoutSize = () => {
446
- return {
447
- width: nineSlice.width,
448
- height: nineSlice.height
449
- };
450
- };
451
- }
452
- const nineSliceCreator = (scene, props) => {
453
- const initialWidth = typeof props.width === "number" ? props.width : 64;
454
- const initialHeight = typeof props.height === "number" ? props.height : 64;
455
- const nineSlice = scene.add.nineslice(
456
- props.x ?? 0,
457
- props.y ?? 0,
458
- props.texture,
459
- props.frame,
460
- initialWidth,
461
- initialHeight,
462
- props.leftWidth,
463
- props.rightWidth,
464
- props.topHeight,
465
- props.bottomHeight
466
- );
467
- nineSlice.setOrigin(0, 0);
468
- if (props.tint !== void 0) {
469
- nineSlice.setTint(props.tint);
470
- }
471
- createTransform(nineSlice, props);
472
- createPhaser(nineSlice, props);
473
- createNineSliceLayout(nineSlice, props);
474
- return nineSlice;
475
- };
476
- const nineSlicePatcher = (node, prev, next) => {
477
- applyTransformProps(node, prev, next);
478
- applyPhaserProps(node, prev, next);
479
- applyNineSliceProps(node, prev, next);
480
- applyNineSliceLayout(node, prev, next);
481
- };
482
- function getOriginalTextureDimensions(sprite) {
483
- const frame = sprite.frame;
484
- return {
485
- width: frame.width,
486
- height: frame.height
487
- };
488
- }
489
- function calculateFitScale(sprite, targetWidth, targetHeight, fit = "fill") {
490
- const { width: textureWidth, height: textureHeight } = getOriginalTextureDimensions(sprite);
491
- if (textureWidth === 0 || textureHeight === 0) {
492
- return { scaleX: 1, scaleY: 1 };
493
- }
494
- if (fit === "fill") {
495
- return {
496
- scaleX: targetWidth / textureWidth,
497
- scaleY: targetHeight / textureHeight
498
- };
499
- }
500
- const targetAspect = targetWidth / targetHeight;
501
- const textureAspect = textureWidth / textureHeight;
502
- if (fit === "contain") {
503
- const scale = targetAspect > textureAspect ? targetHeight / textureHeight : targetWidth / textureWidth;
504
- return { scaleX: scale, scaleY: scale };
505
- }
506
- if (fit === "cover") {
507
- const scale = targetAspect < textureAspect ? targetHeight / textureHeight : targetWidth / textureWidth;
508
- return { scaleX: scale, scaleY: scale };
509
- }
510
- return { scaleX: 1, scaleY: 1 };
511
- }
512
- function applySpriteProps(sprite, prev, next) {
513
- const textureChanged = prev.texture !== next.texture || prev.frame !== next.frame;
514
- if (textureChanged && next.texture) {
515
- sprite.setTexture(next.texture, next.frame);
516
- }
517
- if (prev.tint !== next.tint) {
518
- if (typeof next.tint === "number") {
519
- sprite.setTint(next.tint);
520
- } else {
521
- sprite.clearTint();
522
- }
523
- }
524
- if (prev.originX !== next.originX || prev.originY !== next.originY) {
525
- const originX = next.originX ?? sprite.originX;
526
- const originY = next.originY ?? sprite.originY;
527
- sprite.setOrigin(originX, originY);
528
- }
529
- const displayWidthChanged = prev.displayWidth !== next.displayWidth;
530
- const displayHeightChanged = prev.displayHeight !== next.displayHeight;
531
- const fitChanged = prev.fit !== next.fit;
532
- if (displayWidthChanged || displayHeightChanged || fitChanged || textureChanged) {
533
- if (typeof next.displayWidth === "number" && typeof next.displayHeight === "number") {
534
- const fit = next.fit ?? "fill";
535
- if (fit === "fill") {
536
- sprite.setDisplaySize(next.displayWidth, next.displayHeight);
537
- } else {
538
- const { scaleX, scaleY } = calculateFitScale(
539
- sprite,
540
- next.displayWidth,
541
- next.displayHeight,
542
- fit
543
- );
544
- sprite.setScale(scaleX, scaleY);
545
- }
546
- } else if (typeof next.displayWidth === "number") {
547
- const { width: origWidth } = getOriginalTextureDimensions(sprite);
548
- const scale = next.displayWidth / origWidth;
549
- sprite.setScale(scale);
550
- } else if (typeof next.displayHeight === "number") {
551
- const { height: origHeight } = getOriginalTextureDimensions(sprite);
552
- const scale = next.displayHeight / origHeight;
553
- sprite.setScale(scale, scale);
554
- } else {
555
- sprite.setScale(1);
556
- }
557
- }
558
- const animationChanged = prev.animationKey !== next.animationKey || prev.loop !== next.loop || prev.repeatDelay !== next.repeatDelay;
559
- if (animationChanged) {
560
- if (sprite.anims.isPlaying) {
561
- sprite.anims.stop();
562
- }
563
- if (next.animationKey) {
564
- sprite.anims.play({
565
- key: next.animationKey,
566
- repeat: next.loop ? -1 : 0,
567
- repeatDelay: next.repeatDelay ?? 0
568
- });
569
- }
570
- }
571
- const callbacksChanged = prev.onAnimationStart !== next.onAnimationStart || prev.onAnimationComplete !== next.onAnimationComplete || prev.onAnimationRepeat !== next.onAnimationRepeat || prev.onAnimationUpdate !== next.onAnimationUpdate;
572
- if (callbacksChanged) {
573
- sprite.off("animationstart");
574
- sprite.off("animationcomplete");
575
- sprite.off("animationrepeat");
576
- sprite.off("animationupdate");
577
- if (next.onAnimationStart) {
578
- sprite.on("animationstart", (anim) => {
579
- next.onAnimationStart?.(anim.key);
580
- });
581
- }
582
- if (next.onAnimationComplete) {
583
- sprite.on("animationcomplete", (anim) => {
584
- next.onAnimationComplete?.(anim.key);
585
- });
586
- }
587
- if (next.onAnimationRepeat) {
588
- sprite.on("animationrepeat", (anim) => {
589
- next.onAnimationRepeat?.(anim.key);
590
- });
591
- }
592
- if (next.onAnimationUpdate) {
593
- sprite.on(
594
- "animationupdate",
595
- (anim, frame) => {
596
- next.onAnimationUpdate?.(anim.key, frame);
597
- }
598
- );
599
- }
600
- }
601
- }
602
- function applySpriteLayout(sprite, _prev, next) {
603
- sprite.__layoutProps = next;
604
- }
605
- function createSpriteLayout(sprite, props) {
606
- sprite.__layoutProps = props;
607
- sprite.__getLayoutSize = () => {
608
- return { width: 0.01, height: 0.01 };
609
- };
610
- }
611
- const spriteCreator = (scene, props) => {
612
- const sprite = scene.add.sprite(props.x ?? 0, props.y ?? 0, props.texture, props.frame);
613
- sprite.setOrigin(0.5, 0.5);
614
- if (props.originX !== void 0 || props.originY !== void 0) {
615
- sprite.setOrigin(props.originX ?? sprite.originX, props.originY ?? sprite.originY);
616
- }
617
- createTransform(sprite, props);
618
- createPhaser(sprite, props);
619
- if (props.tint !== void 0) {
620
- sprite.setTint(props.tint);
621
- }
622
- if (props.displayWidth !== void 0 || props.displayHeight !== void 0) {
623
- if (props.displayWidth !== void 0 && props.displayHeight !== void 0) {
624
- const fit = props.fit ?? "fill";
625
- const textureWidth = sprite.width;
626
- const textureHeight = sprite.height;
627
- if (textureWidth > 0 && textureHeight > 0) {
628
- if (fit === "fill") {
629
- sprite.setDisplaySize(props.displayWidth, props.displayHeight);
630
- } else if (fit === "contain") {
631
- const targetAspect = props.displayWidth / props.displayHeight;
632
- const textureAspect = textureWidth / textureHeight;
633
- const scale = targetAspect > textureAspect ? props.displayHeight / textureHeight : props.displayWidth / textureWidth;
634
- sprite.setScale(scale);
635
- } else if (fit === "cover") {
636
- const targetAspect = props.displayWidth / props.displayHeight;
637
- const textureAspect = textureWidth / textureHeight;
638
- const scale = targetAspect < textureAspect ? props.displayHeight / textureHeight : props.displayWidth / textureWidth;
639
- sprite.setScale(scale);
640
- }
641
- }
642
- } else if (props.displayWidth !== void 0) {
643
- const scale = props.displayWidth / sprite.width;
644
- sprite.setScale(scale);
645
- } else if (props.displayHeight !== void 0) {
646
- const scale = props.displayHeight / sprite.height;
647
- sprite.setScale(scale);
648
- }
649
- }
650
- if (props.animationKey) {
651
- if (sprite.scene && sprite.scene.anims.exists(props.animationKey)) {
652
- sprite.anims.play({
653
- key: props.animationKey,
654
- repeat: props.loop ? -1 : 0,
655
- repeatDelay: props.repeatDelay ?? 0
656
- });
657
- }
658
- }
659
- if (props.onAnimationStart) {
660
- sprite.on("animationstart", (anim) => {
661
- props.onAnimationStart?.(anim.key);
662
- });
663
- }
664
- if (props.onAnimationComplete) {
665
- sprite.on("animationcomplete", (anim) => {
666
- props.onAnimationComplete?.(anim.key);
667
- });
668
- }
669
- if (props.onAnimationRepeat) {
670
- sprite.on("animationrepeat", (anim) => {
671
- props.onAnimationRepeat?.(anim.key);
672
- });
673
- }
674
- if (props.onAnimationUpdate) {
675
- sprite.on(
676
- "animationupdate",
677
- (anim, frame) => {
678
- props.onAnimationUpdate?.(anim.key, frame);
679
- }
680
- );
681
- }
682
- createSpriteLayout(sprite, props);
683
- if (props.onReady) {
684
- props.onReady(sprite);
685
- }
686
- return sprite;
687
- };
688
- const spritePatcher = (node, prev, next) => {
689
- applyTransformProps(node, prev, next);
690
- applyPhaserProps(node, prev, next);
691
- applySpriteProps(node, prev, next);
692
- applySpriteLayout(node, prev, next);
693
- };
694
77
  var commonjsGlobal = typeof globalThis !== "undefined" ? globalThis : typeof window !== "undefined" ? window : typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : {};
695
78
  function getDefaultExportFromCjs(x) {
696
79
  return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, "default") ? x["default"] : x;
@@ -6765,213 +6148,6 @@ function clampSize(size, minSize, maxSize, parentSize, fallbackSize, parentPaddi
6765
6148
  }
6766
6149
  return clamped;
6767
6150
  }
6768
- function applyTextProps(node, prev, next) {
6769
- if (node.active === false || node.scene && !node.scene.sys.game) {
6770
- return;
6771
- }
6772
- let needsUpdate = false;
6773
- if (prev.text !== next.text && typeof next.text === "string") {
6774
- node.setText(next.text);
6775
- needsUpdate = true;
6776
- }
6777
- if (next.style !== void 0 && !equal(next.style, prev.style || {})) {
6778
- try {
6779
- node.setStyle(next.style);
6780
- needsUpdate = true;
6781
- } catch (error) {
6782
- console.warn("Failed to apply text style (scene may be transitioning):", error);
6783
- }
6784
- }
6785
- if (next.maxWidth !== prev.maxWidth && next.maxWidth !== void 0) {
6786
- const viewport = viewportRegistry.getViewport();
6787
- const parsedMaxWidth = parseSize(next.maxWidth);
6788
- const resolvedMaxWidth = resolveSize(parsedMaxWidth, viewport?.width, void 0, void 0);
6789
- node.setWordWrapWidth(resolvedMaxWidth, true);
6790
- needsUpdate = true;
6791
- }
6792
- if (prev.style !== next.style && next.style !== void 0) {
6793
- try {
6794
- node.setStyle(next.style);
6795
- needsUpdate = true;
6796
- } catch (error) {
6797
- console.warn("Failed to apply text style (scene may be transitioning):", error);
6798
- }
6799
- }
6800
- if (needsUpdate && node.updateText) {
6801
- node.updateText();
6802
- }
6803
- }
6804
- function applyTextLayout(text, _prev, next) {
6805
- text.__layoutProps = next;
6806
- text.__getLayoutSize = () => {
6807
- if (text.__layoutProps?.headless) {
6808
- return { width: 0.01, height: 0.01 };
6809
- }
6810
- return {
6811
- width: text.width,
6812
- height: text.height
6813
- };
6814
- };
6815
- }
6816
- function createTextLayout(text, props) {
6817
- text.__layoutProps = props;
6818
- text.__getLayoutSize = () => {
6819
- if (text.__layoutProps?.headless) {
6820
- return { width: 0.01, height: 0.01 };
6821
- }
6822
- return {
6823
- width: text.width,
6824
- height: text.height
6825
- };
6826
- };
6827
- }
6828
- const textCreator = (scene, props) => {
6829
- const text = scene.add.text(props.x ?? 0, props.y ?? 0, props.text ?? "", props.style);
6830
- if (props.headless) {
6831
- text.setOrigin(0.5, 0.5);
6832
- } else {
6833
- text.setOrigin(0, 0);
6834
- }
6835
- const normalizedProps = { ...props };
6836
- if (props.headless) {
6837
- delete normalizedProps.padding;
6838
- delete normalizedProps.margin;
6839
- delete normalizedProps.gap;
6840
- } else {
6841
- if (normalizedProps.rotation !== void 0) {
6842
- delete normalizedProps.rotation;
6843
- }
6844
- }
6845
- createTransform(text, normalizedProps);
6846
- createPhaser(text, normalizedProps);
6847
- createTextLayout(text, normalizedProps);
6848
- return text;
6849
- };
6850
- const textPatcher = (node, prev, next) => {
6851
- if (prev.headless !== next.headless) {
6852
- if (next.headless) {
6853
- node.setOrigin(0.5, 0.5);
6854
- } else {
6855
- node.setOrigin(0, 0);
6856
- }
6857
- }
6858
- const normalizedPrev = { ...prev };
6859
- const normalizedNext = { ...next };
6860
- if (next.headless) {
6861
- delete normalizedNext.padding;
6862
- delete normalizedNext.margin;
6863
- delete normalizedNext.gap;
6864
- } else {
6865
- if (normalizedNext.rotation !== void 0) {
6866
- delete normalizedNext.rotation;
6867
- }
6868
- }
6869
- if (prev.headless) {
6870
- delete normalizedPrev.padding;
6871
- delete normalizedPrev.margin;
6872
- delete normalizedPrev.gap;
6873
- } else {
6874
- if (normalizedPrev.rotation !== void 0) {
6875
- delete normalizedPrev.rotation;
6876
- }
6877
- }
6878
- applyTransformProps(node, normalizedPrev, normalizedNext);
6879
- applyPhaserProps(node, normalizedPrev, normalizedNext);
6880
- applyTextProps(node, normalizedPrev, normalizedNext);
6881
- applyTextLayout(node, normalizedPrev, normalizedNext);
6882
- };
6883
- const tileSpriteCreator = (_scene, _props) => {
6884
- throw new Error(
6885
- "TileSprite component not implemented yet. This is a placeholder for architecture planning."
6886
- );
6887
- };
6888
- const tileSpritePatcher = (_node, _prev, _next) => {
6889
- throw new Error(
6890
- "TileSprite component not implemented yet. This is a placeholder for architecture planning."
6891
- );
6892
- };
6893
- function applyBackgroundProps(container, prev, next) {
6894
- const prevBgColor = prev.backgroundColor;
6895
- const nextBgColor = next.backgroundColor;
6896
- const prevBgAlpha = prev.backgroundAlpha ?? 1;
6897
- const nextBgAlpha = next.backgroundAlpha ?? 1;
6898
- const prevWidth = typeof prev.width === "number" ? prev.width : 100;
6899
- const nextWidth = typeof next.width === "number" ? next.width : 100;
6900
- const prevHeight = typeof prev.height === "number" ? prev.height : 100;
6901
- const nextHeight = typeof next.height === "number" ? next.height : 100;
6902
- const prevCornerRadius = prev.cornerRadius ?? 0;
6903
- const nextCornerRadius = next.cornerRadius ?? 0;
6904
- const prevBorderColor = prev.borderColor;
6905
- const nextBorderColor = next.borderColor;
6906
- const prevBorderWidth = prev.borderWidth ?? 0;
6907
- const nextBorderWidth = next.borderWidth ?? 0;
6908
- const prevBorderAlpha = prev.borderAlpha ?? 1;
6909
- const nextBorderAlpha = next.borderAlpha ?? 1;
6910
- const prevHasBorder = prevBorderWidth > 0 && prevBorderColor !== void 0;
6911
- const nextHasBorder = nextBorderWidth > 0 && nextBorderColor !== void 0;
6912
- const prevHasGraphics = prevBgColor !== void 0 || prevHasBorder;
6913
- const nextHasGraphics = nextBgColor !== void 0 || nextHasBorder;
6914
- if (prevHasGraphics && !nextHasGraphics) {
6915
- if (container.__background) {
6916
- container.__background.destroy();
6917
- delete container.__background;
6918
- }
6919
- } else if (!prevHasGraphics && nextHasGraphics) {
6920
- if (container.scene) {
6921
- const background = container.scene.add.graphics();
6922
- if (nextBgColor !== void 0) {
6923
- background.fillStyle(nextBgColor, nextBgAlpha);
6924
- }
6925
- if (nextHasBorder) {
6926
- background.lineStyle(nextBorderWidth, nextBorderColor, nextBorderAlpha);
6927
- }
6928
- if (nextCornerRadius !== 0) {
6929
- if (nextBgColor !== void 0) {
6930
- background.fillRoundedRect(0, 0, nextWidth, nextHeight, nextCornerRadius);
6931
- }
6932
- if (nextHasBorder) {
6933
- background.strokeRoundedRect(0, 0, nextWidth, nextHeight, nextCornerRadius);
6934
- }
6935
- } else {
6936
- if (nextBgColor !== void 0) {
6937
- background.fillRect(0, 0, nextWidth, nextHeight);
6938
- }
6939
- if (nextHasBorder) {
6940
- background.strokeRect(0, 0, nextWidth, nextHeight);
6941
- }
6942
- }
6943
- container.addAt(background, 0);
6944
- container.__background = background;
6945
- background.__isBackground = true;
6946
- }
6947
- } else if (container.__background && nextHasGraphics) {
6948
- const needsRedraw = prevBgColor !== nextBgColor || prevBgAlpha !== nextBgAlpha || prevWidth !== nextWidth || prevHeight !== nextHeight || prevCornerRadius !== nextCornerRadius || prevBorderWidth !== nextBorderWidth || prevBorderColor !== nextBorderColor || prevBorderAlpha !== nextBorderAlpha;
6949
- if (needsRedraw) {
6950
- container.__background.clear();
6951
- if (nextBgColor !== void 0) {
6952
- container.__background.fillStyle(nextBgColor, nextBgAlpha);
6953
- }
6954
- if (nextHasBorder) {
6955
- container.__background.lineStyle(nextBorderWidth, nextBorderColor, nextBorderAlpha);
6956
- }
6957
- if (nextCornerRadius !== 0) {
6958
- if (nextBgColor !== void 0) {
6959
- container.__background.fillRoundedRect(0, 0, nextWidth, nextHeight, nextCornerRadius);
6960
- }
6961
- if (nextHasBorder) {
6962
- container.__background.strokeRoundedRect(0, 0, nextWidth, nextHeight, nextCornerRadius);
6963
- }
6964
- } else {
6965
- if (nextBgColor !== void 0) {
6966
- container.__background.fillRect(0, 0, nextWidth, nextHeight);
6967
- }
6968
- if (nextHasBorder) {
6969
- container.__background.strokeRect(0, 0, nextWidth, nextHeight);
6970
- }
6971
- }
6972
- }
6973
- }
6974
- }
6975
6151
  const DEFAULT_GESTURE_CONFIG = {
6976
6152
  longPressDuration: 500,
6977
6153
  doubleTapDelay: 300,
@@ -7231,8 +6407,8 @@ class GestureManager {
7231
6407
  this.activePointerDown = {
7232
6408
  pointerId: pointer.id,
7233
6409
  container: state.container,
7234
- startX: pointer.x,
7235
- startY: pointer.y
6410
+ startX: pointer.worldX,
6411
+ startY: pointer.worldY
7236
6412
  };
7237
6413
  state.longPressTriggered = false;
7238
6414
  state.pointerDownTime = Date.now();
@@ -7254,12 +6430,31 @@ class GestureManager {
7254
6430
  }
7255
6431
  }, state.config.longPressDuration);
7256
6432
  }
7257
- state.pointerDownPosition = { x: pointer.x, y: pointer.y };
6433
+ state.pointerDownPosition = { x: pointer.worldX, y: pointer.worldY };
7258
6434
  }
7259
6435
  }
7260
6436
  }
7261
6437
  if (hitContainers.size > 0) {
7262
6438
  this.activeContainersForMove.set(pointer.id, hitContainers);
6439
+ this.bubbleEvent(
6440
+ pointer,
6441
+ "onTouchMove",
6442
+ (targetState, targetLocalPos) => {
6443
+ const isInside = this.isPointerInContainer(pointer, targetState);
6444
+ const data = this.createEventData(
6445
+ pointer,
6446
+ targetLocalPos.x,
6447
+ targetLocalPos.y,
6448
+ targetState.hitArea.width,
6449
+ targetState.hitArea.height,
6450
+ { dx: 0, dy: 0, isInside, state: "start" }
6451
+ );
6452
+ targetState.callbacks.onTouchMove?.(data);
6453
+ targetState.isFirstMove = false;
6454
+ return data.isPropagationStopped();
6455
+ },
6456
+ hitContainers
6457
+ );
7263
6458
  }
7264
6459
  }
7265
6460
  /**
@@ -7281,8 +6476,8 @@ class GestureManager {
7281
6476
  const touchDuration = state.pointerDownTime ? Date.now() - state.pointerDownTime : 0;
7282
6477
  const isTouchTooLong = touchDuration > state.config.maxTouchDuration;
7283
6478
  const last = this.lastPointerPositions.get(pointer.id);
7284
- const dx = last ? pointer.x - last.x : 0;
7285
- const dy = last ? pointer.y - last.y : 0;
6479
+ const dx = last ? pointer.worldX - last.x : 0;
6480
+ const dy = last ? pointer.worldY - last.y : 0;
7286
6481
  const hitContainers = this.activeContainersForMove.get(pointer.id);
7287
6482
  this.bubbleEvent(
7288
6483
  pointer,
@@ -7418,8 +6613,8 @@ class GestureManager {
7418
6613
  state.longPressTimer = void 0;
7419
6614
  }
7420
6615
  const last = this.lastPointerPositions.get(pointer.id);
7421
- const dx = last ? pointer.x - last.x : 0;
7422
- const dy = last ? pointer.y - last.y : 0;
6616
+ const dx = last ? pointer.worldX - last.x : 0;
6617
+ const dy = last ? pointer.worldY - last.y : 0;
7423
6618
  const hitContainers = this.activeContainersForMove.get(pointer.id);
7424
6619
  this.bubbleEvent(
7425
6620
  pointer,
@@ -7457,9 +6652,9 @@ class GestureManager {
7457
6652
  */
7458
6653
  handlePointerMove(pointer) {
7459
6654
  const last = this.lastPointerPositions.get(pointer.id);
7460
- const dx = last ? pointer.x - last.x : 0;
7461
- const dy = last ? pointer.y - last.y : 0;
7462
- this.lastPointerPositions.set(pointer.id, { x: pointer.x, y: pointer.y });
6655
+ const dx = last ? pointer.worldX - last.x : 0;
6656
+ const dy = last ? pointer.worldY - last.y : 0;
6657
+ this.lastPointerPositions.set(pointer.id, { x: pointer.worldX, y: pointer.worldY });
7463
6658
  this.detectHoverChanges(pointer);
7464
6659
  if (!this.activePointerDown || pointer.id !== this.activePointerDown.pointerId) {
7465
6660
  return;
@@ -7533,7 +6728,7 @@ class GestureManager {
7533
6728
  getLocalPosition(pointer, container) {
7534
6729
  const matrix = container.getWorldTransformMatrix();
7535
6730
  const inverseMatrix = matrix.invert();
7536
- const localPos = inverseMatrix.transformPoint(pointer.x, pointer.y);
6731
+ const localPos = inverseMatrix.transformPoint(pointer.worldX, pointer.worldY);
7537
6732
  return { x: localPos.x, y: localPos.y };
7538
6733
  }
7539
6734
  /**
@@ -7603,6 +6798,7 @@ class GestureManager {
7603
6798
  const scaleY = canvas.height / rect.height;
7604
6799
  pointer.x = (event.clientX - rect.left) * scaleX;
7605
6800
  pointer.y = (event.clientY - rect.top) * scaleY;
6801
+ pointer.updateWorldPoint(pointer.camera ?? this.scene.cameras.main);
7606
6802
  const containersUnderPointer = [];
7607
6803
  Array.from(this.containers.values()).forEach((state, originalIndex) => {
7608
6804
  if (!state.callbacks.onWheel) return;
@@ -7703,83 +6899,6 @@ function getGestureManager(scene) {
7703
6899
  }
7704
6900
  return manager;
7705
6901
  }
7706
- function applyGesturesProps(scene, container, prev, next) {
7707
- if (!scene || !scene.sys || !scene.data) {
7708
- console.warn("applyGesturesProps: Invalid scene or scene not initialized");
7709
- return;
7710
- }
7711
- if (!scene.sys.isActive() || scene.sys.game === null) {
7712
- console.warn("applyGesturesProps: Scene is not active or game is null");
7713
- return;
7714
- }
7715
- const hasAnyGesture = !!(next.onTouch || next.onTouchOutside || next.onTouchMove || next.onDoubleTap || next.onLongPress || next.onHoverStart || next.onHoverEnd || next.onWheel);
7716
- const hadAnyGesture = !!(prev.onTouch || prev.onTouchOutside || prev.onTouchMove || prev.onDoubleTap || prev.onLongPress || prev.onHoverStart || prev.onHoverEnd || prev.onWheel);
7717
- const prevEnabled = hadAnyGesture && prev.enableGestures !== false;
7718
- const nextEnabled = hasAnyGesture && next.enableGestures !== false;
7719
- const manager = getGestureManager(scene);
7720
- if (!prevEnabled && nextEnabled && hasAnyGesture) {
7721
- const containerWithLayout = container;
7722
- let width = 100;
7723
- let height = 100;
7724
- if (containerWithLayout.__getLayoutSize) {
7725
- const size = containerWithLayout.__getLayoutSize();
7726
- width = size.width;
7727
- height = size.height;
7728
- } else {
7729
- const bounds = container.getBounds();
7730
- width = bounds.width || 100;
7731
- height = bounds.height || 100;
7732
- }
7733
- const hitArea = new Phaser$1.Geom.Rectangle(0, 0, width, height);
7734
- const callbacks = {};
7735
- if (next.onTouch) callbacks.onTouch = next.onTouch;
7736
- if (next.onTouchOutside) callbacks.onTouchOutside = next.onTouchOutside;
7737
- if (next.onTouchMove) callbacks.onTouchMove = next.onTouchMove;
7738
- if (next.onDoubleTap) callbacks.onDoubleTap = next.onDoubleTap;
7739
- if (next.onLongPress) callbacks.onLongPress = next.onLongPress;
7740
- if (next.onHoverStart) callbacks.onHoverStart = next.onHoverStart;
7741
- if (next.onHoverEnd) callbacks.onHoverEnd = next.onHoverEnd;
7742
- if (next.onWheel) callbacks.onWheel = next.onWheel;
7743
- const config = {};
7744
- if (next.longPressDuration !== void 0) config.longPressDuration = next.longPressDuration;
7745
- if (next.doubleTapDelay !== void 0) config.doubleTapDelay = next.doubleTapDelay;
7746
- manager.registerContainer(container, callbacks, hitArea, config);
7747
- return;
7748
- }
7749
- if (prevEnabled && (!nextEnabled || !hasAnyGesture)) {
7750
- manager.unregisterContainer(container);
7751
- return;
7752
- }
7753
- if (nextEnabled && hasAnyGesture) {
7754
- 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;
7755
- if (callbacksChanged) {
7756
- const callbacks = {};
7757
- if (next.onTouch) callbacks.onTouch = next.onTouch;
7758
- if (next.onTouchOutside) callbacks.onTouchOutside = next.onTouchOutside;
7759
- if (next.onTouchMove) callbacks.onTouchMove = next.onTouchMove;
7760
- if (next.onDoubleTap) callbacks.onDoubleTap = next.onDoubleTap;
7761
- if (next.onLongPress) callbacks.onLongPress = next.onLongPress;
7762
- if (next.onHoverStart) callbacks.onHoverStart = next.onHoverStart;
7763
- if (next.onHoverEnd) callbacks.onHoverEnd = next.onHoverEnd;
7764
- if (next.onWheel) callbacks.onWheel = next.onWheel;
7765
- manager.updateCallbacks(container, callbacks);
7766
- }
7767
- const containerWithLayout = container;
7768
- let width = 100;
7769
- let height = 100;
7770
- if (containerWithLayout.__getLayoutSize) {
7771
- const size = containerWithLayout.__getLayoutSize();
7772
- width = size.width;
7773
- height = size.height;
7774
- } else {
7775
- const bounds = container.getBounds();
7776
- width = bounds.width || 100;
7777
- height = bounds.height || 100;
7778
- }
7779
- const hitArea = new Phaser$1.Geom.Rectangle(0, 0, width, height);
7780
- manager.updateHitArea(container, hitArea);
7781
- }
7782
- }
7783
6902
  function normalizeEdgeInsets(value) {
7784
6903
  if (value === void 0) {
7785
6904
  return {};
@@ -8855,10 +7974,57 @@ const strategies = {
8855
7974
  row: new RowLayoutStrategy(),
8856
7975
  stack: new StackLayoutStrategy()
8857
7976
  };
7977
+ const LAYOUT_CYCLE_EPSILON = 0.5;
7978
+ const LAYOUT_CYCLE_TIME_MS = 100;
7979
+ const LAYOUT_CYCLE_MAX = 5;
7980
+ const LAYOUT_MAX_SIZE = 2e5;
7981
+ const layoutCycleGuard = /* @__PURE__ */ new WeakMap();
7982
+ function isCloseSize(a, b, epsilon) {
7983
+ return Math.abs(a.width - b.width) < epsilon && Math.abs(a.height - b.height) < epsilon;
7984
+ }
8858
7985
  function invalidateParentLayoutIfNeeded(container, oldSize, newWidth, newHeight) {
8859
- if (!oldSize || oldSize.width === newWidth && oldSize.height === newHeight) {
7986
+ if (!oldSize || Math.abs(oldSize.width - newWidth) < LAYOUT_CYCLE_EPSILON && Math.abs(oldSize.height - newHeight) < LAYOUT_CYCLE_EPSILON) {
7987
+ return;
7988
+ }
7989
+ if (!Number.isFinite(newWidth) || !Number.isFinite(newHeight) || newWidth > LAYOUT_MAX_SIZE || newHeight > LAYOUT_MAX_SIZE) {
7990
+ const containerWithProps = container;
7991
+ DebugLogger.warn("layout", "Runaway layout size detected, skipping parent invalidation", {
7992
+ oldSize,
7993
+ newSize: { width: newWidth, height: newHeight },
7994
+ containerProps: containerWithProps.__layoutProps,
7995
+ childCount: containerWithProps.list?.length ?? 0
7996
+ });
8860
7997
  return;
8861
7998
  }
7999
+ const newSize = { width: newWidth, height: newHeight };
8000
+ const now = Date.now();
8001
+ const guard = layoutCycleGuard.get(container);
8002
+ if (guard) {
8003
+ const repeatsPrev = guard.prev ? isCloseSize(guard.prev, newSize, LAYOUT_CYCLE_EPSILON) : false;
8004
+ if (repeatsPrev && now - guard.lastTime < LAYOUT_CYCLE_TIME_MS) {
8005
+ guard.count += 1;
8006
+ } else {
8007
+ guard.count = 0;
8008
+ }
8009
+ guard.prev = guard.last;
8010
+ guard.last = newSize;
8011
+ guard.lastTime = now;
8012
+ layoutCycleGuard.set(container, guard);
8013
+ if (guard.count >= LAYOUT_CYCLE_MAX) {
8014
+ DebugLogger.warn("layout", "Layout cycle detected, skipping parent invalidation", {
8015
+ container,
8016
+ oldSize,
8017
+ newSize
8018
+ });
8019
+ return;
8020
+ }
8021
+ } else {
8022
+ layoutCycleGuard.set(container, {
8023
+ last: newSize,
8024
+ count: 0,
8025
+ lastTime: now
8026
+ });
8027
+ }
8862
8028
  const parent = container.parentContainer;
8863
8029
  if (!parent || !parent.__layoutProps) {
8864
8030
  return;
@@ -9243,87 +8409,6 @@ function calculateLayoutImmediate(container, containerProps, parentSize, parentP
9243
8409
  function calculateLayout(container, containerProps, parentSize, parentPadding) {
9244
8410
  LayoutBatchQueue.schedule(container, containerProps, parentSize, parentPadding);
9245
8411
  }
9246
- function updateGestureHitAreaIfNeeded(node) {
9247
- const containerWithLayout = node;
9248
- if (!containerWithLayout.__getLayoutSize) return;
9249
- try {
9250
- const manager = getGestureManager(containerWithLayout.scene);
9251
- const size = containerWithLayout.__getLayoutSize();
9252
- const hitArea = new Phaser.Geom.Rectangle(0, 0, size.width, size.height);
9253
- manager.updateHitArea(node, hitArea);
9254
- } catch {
9255
- }
9256
- }
9257
- const LAYOUT_RELEVANT_PROPS = [
9258
- "width",
9259
- "height",
9260
- "minWidth",
9261
- "maxWidth",
9262
- "minHeight",
9263
- "maxHeight",
9264
- "flex",
9265
- "margin",
9266
- "padding",
9267
- "gap",
9268
- "direction",
9269
- "justifyContent",
9270
- "alignItems",
9271
- "overflow"
9272
- ];
9273
- const DEEP_COMPARE_PROPS$1 = /* @__PURE__ */ new Set(["margin", "padding"]);
9274
- function hasLayoutPropsChanged$1(prev, next) {
9275
- for (const prop of LAYOUT_RELEVANT_PROPS) {
9276
- const oldVal = prev[prop];
9277
- const newVal = next[prop];
9278
- if (DEEP_COMPARE_PROPS$1.has(prop)) {
9279
- if (!equal(oldVal, newVal)) {
9280
- return true;
9281
- }
9282
- } else {
9283
- if (oldVal !== newVal) {
9284
- return true;
9285
- }
9286
- }
9287
- }
9288
- return false;
9289
- }
9290
- function getParentLayoutContext(node) {
9291
- const parent = node.parentContainer;
9292
- if (parent && parent.__layoutProps && parent.__getLayoutSize) {
9293
- const parentSize = parent.__getLayoutSize();
9294
- const padding = parent.__layoutProps.padding ?? 0;
9295
- const normPadding = typeof padding === "number" ? { left: padding, right: padding, top: padding, bottom: padding } : {
9296
- left: padding.left ?? 0,
9297
- right: padding.right ?? 0,
9298
- top: padding.top ?? 0,
9299
- bottom: padding.bottom ?? 0
9300
- };
9301
- return {
9302
- parentSize: {
9303
- width: parentSize.width - normPadding.left - normPadding.right,
9304
- height: parentSize.height - normPadding.top - normPadding.bottom
9305
- }
9306
- // Parent already provides content-area, no padding offset needed
9307
- };
9308
- }
9309
- if (node.scene) {
9310
- return {
9311
- parentSize: {
9312
- width: node.scene.scale.width,
9313
- height: node.scene.scale.height
9314
- }
9315
- };
9316
- }
9317
- return {};
9318
- }
9319
- function applyLayoutProps(node, prev, next) {
9320
- node.__layoutProps = next;
9321
- if (hasLayoutPropsChanged$1(prev, next)) {
9322
- const { parentSize, parentPadding } = getParentLayoutContext(node);
9323
- calculateLayout(node, next, parentSize, parentPadding);
9324
- updateGestureHitAreaIfNeeded(node);
9325
- }
9326
- }
9327
8412
  class HexColor extends String {
9328
8413
  /**
9329
8414
  * Convert to Phaser number format
@@ -9817,6 +8902,10 @@ function buildDefaultTheme(colors) {
9817
8902
  alpha: 1,
9818
8903
  visible: true
9819
8904
  },
8905
+ particles: {
8906
+ alpha: 1,
8907
+ visible: true
8908
+ },
9820
8909
  // Public API (uppercase)
9821
8910
  View: {
9822
8911
  alpha: 1,
@@ -9848,6 +8937,10 @@ function buildDefaultTheme(colors) {
9848
8937
  alpha: 1,
9849
8938
  visible: true
9850
8939
  },
8940
+ Particles: {
8941
+ alpha: 1,
8942
+ visible: true
8943
+ },
9851
8944
  RadioButton: {
9852
8945
  selectedColor: colors.primary.DEFAULT.toNumber(),
9853
8946
  color: colors.border.medium.toNumber(),
@@ -10032,6 +9125,41 @@ function buildDefaultTheme(colors) {
10032
9125
  fontSize: "18px"
10033
9126
  }
10034
9127
  },
9128
+ Tabs: {
9129
+ tabListStyle: {
9130
+ backgroundColor: colors.surface.dark.toNumber(),
9131
+ padding: { left: 8, right: 8, top: 8, bottom: 0 },
9132
+ cornerRadius: { tl: 6, tr: 6, bl: 0, br: 0 },
9133
+ width: "fill",
9134
+ gap: 10,
9135
+ alignItems: "end",
9136
+ justifyContent: "start"
9137
+ },
9138
+ tabStyle: {
9139
+ backgroundColor: colors.surface.medium.toNumber(),
9140
+ borderColor: colors.border.medium.toNumber(),
9141
+ borderWidth: 1,
9142
+ padding: { left: 8, right: 8, top: 8, bottom: 3 },
9143
+ cornerRadius: { tl: 6, tr: 6, bl: 0, br: 0 }
9144
+ },
9145
+ tabActiveStyle: {
9146
+ padding: { left: 8, right: 8, top: 8, bottom: 8 },
9147
+ backgroundColor: colors.primary.DEFAULT.toNumber(),
9148
+ borderColor: colors.primary.dark.toNumber(),
9149
+ borderWidth: 2
9150
+ },
9151
+ tabDisabledStyle: {
9152
+ alpha: 0.4
9153
+ },
9154
+ panelStyle: {
9155
+ backgroundColor: colors.surface.light.toNumber(),
9156
+ borderColor: colors.border.medium.toNumber(),
9157
+ borderWidth: 1,
9158
+ padding: 10,
9159
+ cornerRadius: { tl: 0, tr: 0, bl: 6, br: 6 },
9160
+ width: "fill"
9161
+ }
9162
+ },
10035
9163
  NineSliceButton: {},
10036
9164
  CharText: {
10037
9165
  charSpacing: 0,
@@ -10486,442 +9614,6 @@ function getThemedProps(componentName, localTheme, explicitProps) {
10486
9614
  nestedTheme: mergedNestedThemes
10487
9615
  };
10488
9616
  }
10489
- const tooltipStates = /* @__PURE__ */ new Map();
10490
- function calculateTooltipPosition(targetBounds, position, offset, tooltipWidth, tooltipHeight) {
10491
- const viewport = {
10492
- width: window.innerWidth,
10493
- height: window.innerHeight
10494
- };
10495
- let x = 0;
10496
- let y = 0;
10497
- switch (position) {
10498
- case "top":
10499
- x = targetBounds.centerX - tooltipWidth / 2;
10500
- y = targetBounds.top - tooltipHeight - offset;
10501
- break;
10502
- case "bottom":
10503
- x = targetBounds.centerX - tooltipWidth / 2;
10504
- y = targetBounds.bottom + offset;
10505
- break;
10506
- case "left":
10507
- x = targetBounds.left - tooltipWidth - offset;
10508
- y = targetBounds.centerY - tooltipHeight / 2;
10509
- break;
10510
- case "right":
10511
- x = targetBounds.right + offset;
10512
- y = targetBounds.centerY - tooltipHeight / 2;
10513
- break;
10514
- }
10515
- x = Math.max(8, Math.min(x, viewport.width - tooltipWidth - 8));
10516
- y = Math.max(8, Math.min(y, viewport.height - tooltipHeight - 8));
10517
- return { x, y };
10518
- }
10519
- function showTooltip(scene, container, config) {
10520
- const state = tooltipStates.get(container);
10521
- if (!state || state.isVisible) return;
10522
- state.isVisible = true;
10523
- state.currentConfig = config;
10524
- const theme = themeRegistry.getGlobalTheme();
10525
- const tooltipTheme = theme.Tooltip || {};
10526
- const position = config.position ?? tooltipTheme.position ?? "top";
10527
- const offset = config.offset ?? tooltipTheme.offset ?? 8;
10528
- const content = config.content;
10529
- const targetBounds = container.getBounds();
10530
- const textStyle = tooltipTheme.textStyle ?? {
10531
- fontSize: "14px",
10532
- fontFamily: "Arial",
10533
- color: "#ffffff",
10534
- padding: { x: 8, y: 4 }
10535
- };
10536
- const { backgroundColor: bgColor, ...styleWithoutBg } = textStyle;
10537
- const text = scene.add.text(0, 0, content, styleWithoutBg);
10538
- text.setOrigin(0.5);
10539
- const padding = textStyle.padding ?? { x: 8, y: 4 };
10540
- const paddingX = typeof padding === "number" ? padding : padding.x ?? 8;
10541
- const paddingY = typeof padding === "number" ? padding : padding.y ?? 4;
10542
- const textWidth = text.width;
10543
- const textHeight = text.height;
10544
- const bgWidth = textWidth + paddingX * 2;
10545
- const bgHeight = textHeight + paddingY * 2;
10546
- const cornerRadius = tooltipTheme.cornerRadius ?? 6;
10547
- const graphics = scene.add.graphics();
10548
- const bg = bgColor ?? "#000000dd";
10549
- let fillColor = 0;
10550
- let fillAlpha = 0.87;
10551
- if (typeof bg === "string") {
10552
- if (bg.startsWith("#")) {
10553
- const hex2 = bg.slice(1);
10554
- if (hex2.length === 8) {
10555
- fillColor = parseInt(hex2.slice(0, 6), 16);
10556
- fillAlpha = parseInt(hex2.slice(6, 8), 16) / 255;
10557
- } else if (hex2.length === 6) {
10558
- fillColor = parseInt(hex2, 16);
10559
- fillAlpha = 1;
10560
- }
10561
- }
10562
- }
10563
- graphics.fillStyle(fillColor, fillAlpha);
10564
- graphics.fillRoundedRect(-bgWidth / 2, -bgHeight / 2, bgWidth, bgHeight, cornerRadius);
10565
- const tooltipContainer = scene.add.container(0, 0, [graphics, text]);
10566
- tooltipContainer.setDepth(1e4);
10567
- const textBounds = tooltipContainer.getBounds();
10568
- const pos = calculateTooltipPosition(
10569
- targetBounds,
10570
- position,
10571
- offset,
10572
- textBounds.width,
10573
- textBounds.height
10574
- );
10575
- const themeAnim = tooltipTheme.animation || {};
10576
- const anim = config.animation || {};
10577
- const fadeInDuration = anim.fadeIn ?? themeAnim.fadeIn ?? 200;
10578
- const moveOffset = {
10579
- dx: anim.move?.dx ?? themeAnim.move?.dx ?? 0,
10580
- dy: anim.move?.dy ?? themeAnim.move?.dy ?? 0
10581
- };
10582
- const pulse = anim.pulse ?? themeAnim.pulse ?? false;
10583
- const pulseScale = anim.pulseScale ?? [0.75, 1.25];
10584
- tooltipContainer.setPosition(
10585
- pos.x + textBounds.width / 2 - moveOffset.dx,
10586
- pos.y + textBounds.height / 2 - moveOffset.dy
10587
- );
10588
- tooltipContainer.setAlpha(0);
10589
- state.tooltip = tooltipContainer;
10590
- const fadeTween = scene.tweens.add({
10591
- targets: tooltipContainer,
10592
- alpha: 1,
10593
- x: pos.x + textBounds.width / 2,
10594
- y: pos.y + textBounds.height / 2,
10595
- duration: fadeInDuration,
10596
- ease: "Cubic.Out"
10597
- });
10598
- state.activeTweens.push(fadeTween);
10599
- if (pulse) {
10600
- const pulseTween = scene.tweens.add({
10601
- targets: tooltipContainer,
10602
- scale: { from: pulseScale[0], to: pulseScale[1] },
10603
- duration: 600,
10604
- yoyo: true,
10605
- repeat: -1,
10606
- ease: "Sine.InOut"
10607
- });
10608
- state.activeTweens.push(pulseTween);
10609
- }
10610
- if (config.autoDismiss && config.autoDismiss > 0) {
10611
- state.autoDismissTimer = setTimeout(() => {
10612
- hideTooltip(container);
10613
- }, config.autoDismiss);
10614
- }
10615
- }
10616
- function hideTooltip(container) {
10617
- const state = tooltipStates.get(container);
10618
- if (!state || !state.isVisible) return;
10619
- state.isVisible = false;
10620
- const config = state.currentConfig;
10621
- state.currentConfig = null;
10622
- if (state.autoDismissTimer) {
10623
- clearTimeout(state.autoDismissTimer);
10624
- state.autoDismissTimer = null;
10625
- }
10626
- if (!state.tooltip) return;
10627
- const tooltip = state.tooltip;
10628
- const scene = tooltip.scene;
10629
- const theme = themeRegistry.getGlobalTheme();
10630
- const tooltipTheme = theme.Tooltip || {};
10631
- const themeAnim = tooltipTheme.animation || {};
10632
- const anim = config?.animation || {};
10633
- const fadeOutDuration = anim.fadeOut ?? themeAnim.fadeOut ?? 200;
10634
- state.activeTweens.forEach((tween) => tween.stop());
10635
- state.activeTweens = [];
10636
- scene.tweens.add({
10637
- targets: tooltip,
10638
- alpha: 0,
10639
- duration: fadeOutDuration,
10640
- ease: "Cubic.In",
10641
- onComplete: () => {
10642
- tooltip.destroy();
10643
- }
10644
- });
10645
- state.tooltip = null;
10646
- }
10647
- function applyTooltip(scene, container, nextCallback, existingOnHoverStart, existingOnHoverEnd) {
10648
- if (!tooltipStates.has(container)) {
10649
- tooltipStates.set(container, {
10650
- isVisible: false,
10651
- tooltip: null,
10652
- activeTweens: [],
10653
- showTimer: null,
10654
- hideTimer: null,
10655
- autoDismissTimer: null,
10656
- currentConfig: null
10657
- });
10658
- container.once("destroy", () => {
10659
- const state2 = tooltipStates.get(container);
10660
- if (state2) {
10661
- if (state2.showTimer) clearTimeout(state2.showTimer);
10662
- if (state2.hideTimer) clearTimeout(state2.hideTimer);
10663
- if (state2.autoDismissTimer) clearTimeout(state2.autoDismissTimer);
10664
- state2.activeTweens.forEach((tween) => tween.stop());
10665
- hideTooltip(container);
10666
- tooltipStates.delete(container);
10667
- }
10668
- });
10669
- }
10670
- const state = tooltipStates.get(container);
10671
- if (!state) {
10672
- throw new Error("applyTooltip: state not initialized");
10673
- }
10674
- const theme = themeRegistry.getGlobalTheme();
10675
- const tooltipTheme = theme.Tooltip || {};
10676
- const onHoverStart = (data) => {
10677
- if (existingOnHoverStart) existingOnHoverStart(data);
10678
- if (!nextCallback) return;
10679
- const result = nextCallback();
10680
- if (!result) return;
10681
- const config = typeof result === "string" ? { content: result } : result;
10682
- if (config.disabled) return;
10683
- if (state.hideTimer) {
10684
- clearTimeout(state.hideTimer);
10685
- state.hideTimer = null;
10686
- }
10687
- if (state.autoDismissTimer) {
10688
- clearTimeout(state.autoDismissTimer);
10689
- state.autoDismissTimer = null;
10690
- }
10691
- const showDelay = config.showDelay ?? tooltipTheme.showDelay ?? 500;
10692
- state.showTimer = setTimeout(() => {
10693
- showTooltip(scene, container, config);
10694
- }, showDelay);
10695
- };
10696
- const onHoverEnd = (data) => {
10697
- if (existingOnHoverEnd) existingOnHoverEnd(data);
10698
- if (state.showTimer) {
10699
- clearTimeout(state.showTimer);
10700
- state.showTimer = null;
10701
- }
10702
- const hideDelay = state.currentConfig?.hideDelay ?? tooltipTheme.hideDelay ?? 0;
10703
- if (hideDelay > 0) {
10704
- state.hideTimer = setTimeout(() => {
10705
- hideTooltip(container);
10706
- }, hideDelay);
10707
- } else {
10708
- hideTooltip(container);
10709
- }
10710
- };
10711
- return { onHoverStart, onHoverEnd };
10712
- }
10713
- function createBackground(scene, container, props) {
10714
- const hasBackground = props.backgroundColor !== void 0;
10715
- const hasBorder = props.borderColor !== void 0;
10716
- if (hasBackground || hasBorder) {
10717
- const width = typeof props.width === "number" ? props.width : 100;
10718
- const height = typeof props.height === "number" ? props.height : 100;
10719
- const bgColor = props.backgroundColor;
10720
- const bgAlpha = props.backgroundAlpha ?? 1;
10721
- const cornerRadius = props.cornerRadius ?? 0;
10722
- const borderColor = props.borderColor;
10723
- const borderWidth = props.borderWidth ?? 0;
10724
- const borderAlpha = props.borderAlpha ?? 1;
10725
- const background = scene.add.graphics();
10726
- if (bgColor !== void 0) {
10727
- background.fillStyle(bgColor, bgAlpha);
10728
- }
10729
- if (borderWidth > 0 && borderColor !== void 0) {
10730
- background.lineStyle(borderWidth, borderColor, borderAlpha);
10731
- }
10732
- if (cornerRadius !== 0) {
10733
- if (bgColor !== void 0) {
10734
- background.fillRoundedRect(0, 0, width, height, cornerRadius);
10735
- }
10736
- if (borderWidth > 0 && borderColor !== void 0) {
10737
- background.strokeRoundedRect(0, 0, width, height, cornerRadius);
10738
- }
10739
- } else {
10740
- if (bgColor !== void 0) {
10741
- background.fillRect(0, 0, width, height);
10742
- }
10743
- if (borderWidth > 0 && borderColor !== void 0) {
10744
- background.strokeRect(0, 0, width, height);
10745
- }
10746
- }
10747
- container.addAt(background, 0);
10748
- container.__background = background;
10749
- background.__isBackground = true;
10750
- }
10751
- }
10752
- function createGestures(scene, container, props) {
10753
- const hasAnyGesture = !!(props.onTouch || props.onTouchOutside || props.onTouchMove || props.onDoubleTap || props.onLongPress || props.onHoverStart || props.onHoverEnd || props.onWheel);
10754
- const shouldEnable = hasAnyGesture && props.enableGestures !== false;
10755
- if (!shouldEnable) {
10756
- return;
10757
- }
10758
- const manager = getGestureManager(scene);
10759
- const containerWithLayout = container;
10760
- let width = 100;
10761
- let height = 100;
10762
- if (containerWithLayout.__getLayoutSize) {
10763
- const size = containerWithLayout.__getLayoutSize();
10764
- width = size.width;
10765
- height = size.height;
10766
- } else {
10767
- const bounds = container.getBounds();
10768
- width = bounds.width || 100;
10769
- height = bounds.height || 100;
10770
- }
10771
- const hitArea = new Phaser$1.Geom.Rectangle(0, 0, width, height);
10772
- const callbacks = {};
10773
- if (props.onTouch) callbacks.onTouch = props.onTouch;
10774
- if (props.onTouchOutside) callbacks.onTouchOutside = props.onTouchOutside;
10775
- if (props.onTouchMove) callbacks.onTouchMove = props.onTouchMove;
10776
- if (props.onDoubleTap) callbacks.onDoubleTap = props.onDoubleTap;
10777
- if (props.onLongPress) callbacks.onLongPress = props.onLongPress;
10778
- if (props.onHoverStart) callbacks.onHoverStart = props.onHoverStart;
10779
- if (props.onHoverEnd) callbacks.onHoverEnd = props.onHoverEnd;
10780
- if (props.onWheel) callbacks.onWheel = props.onWheel;
10781
- const config = {};
10782
- if (props.longPressDuration !== void 0) config.longPressDuration = props.longPressDuration;
10783
- if (props.doubleTapDelay !== void 0) config.doubleTapDelay = props.doubleTapDelay;
10784
- if (props.maxTouchDuration !== void 0) config.maxTouchDuration = props.maxTouchDuration;
10785
- manager.registerContainer(container, callbacks, hitArea, config);
10786
- }
10787
- function createLayout(container, props) {
10788
- container.__layoutProps = props;
10789
- container.__getLayoutSize = () => {
10790
- const children = container.list;
10791
- const direction = props.direction ?? "column";
10792
- const paddingRaw = props.padding ?? {};
10793
- const padding = typeof paddingRaw === "number" ? { left: paddingRaw, top: paddingRaw, right: paddingRaw, bottom: paddingRaw } : paddingRaw;
10794
- const paddingLeft = padding.left ?? 0;
10795
- const paddingTop = padding.top ?? 0;
10796
- const paddingRight = padding.right ?? 0;
10797
- const paddingBottom = padding.bottom ?? 0;
10798
- const gapNormalized = normalizeGap(props.gap);
10799
- let maxWidth = 0;
10800
- let maxHeight = 0;
10801
- let totalMainSize = 0;
10802
- let childCount = 0;
10803
- for (const child of children) {
10804
- if (child.__isBackground) {
10805
- continue;
10806
- }
10807
- childCount++;
10808
- const marginRaw = child.__layoutProps?.margin ?? {};
10809
- const margin = typeof marginRaw === "number" ? { top: marginRaw, right: marginRaw, bottom: marginRaw, left: marginRaw } : marginRaw;
10810
- const marginTop = margin.top ?? 0;
10811
- const marginBottom = margin.bottom ?? 0;
10812
- const marginLeft = margin.left ?? 0;
10813
- const marginRight = margin.right ?? 0;
10814
- const childSize = getChildSize(child);
10815
- if (direction === "row") {
10816
- totalMainSize += marginLeft + childSize.width + marginRight;
10817
- const childTotalHeight = marginTop + childSize.height + marginBottom;
10818
- maxHeight = Math.max(maxHeight, childTotalHeight);
10819
- } else {
10820
- const childTotalWidth = marginLeft + childSize.width + marginRight;
10821
- maxWidth = Math.max(maxWidth, childTotalWidth);
10822
- totalMainSize += marginTop + childSize.height + marginBottom;
10823
- }
10824
- }
10825
- if (childCount > 1) {
10826
- const gapValue = direction === "row" ? gapNormalized.horizontal : gapNormalized.vertical;
10827
- totalMainSize += gapValue * (childCount - 1);
10828
- }
10829
- const defaultWidth = direction === "row" ? totalMainSize + paddingLeft + paddingRight : maxWidth + paddingLeft + paddingRight;
10830
- const defaultHeight = direction === "row" ? maxHeight + paddingTop + paddingBottom : totalMainSize + paddingTop + paddingBottom;
10831
- const parsedWidth = parseSize(props.width);
10832
- const finalWidth = resolveSize(parsedWidth, void 0, defaultWidth);
10833
- const parsedHeight = parseSize(props.height);
10834
- const finalHeight = resolveSize(parsedHeight, void 0, defaultHeight);
10835
- return {
10836
- width: finalWidth,
10837
- height: finalHeight
10838
- };
10839
- };
10840
- }
10841
- function normalizeBackgroundProps(props) {
10842
- const bgProps = props;
10843
- const hasBackground = bgProps.backgroundColor !== void 0;
10844
- const hasBorder = bgProps.borderColor !== void 0;
10845
- if (!hasBackground && !hasBorder) {
10846
- return props;
10847
- }
10848
- const normalized = { ...props };
10849
- if (hasBackground && (bgProps.backgroundAlpha === void 0 || bgProps.backgroundAlpha === 0)) {
10850
- normalized.backgroundAlpha = 1;
10851
- }
10852
- if (hasBorder) {
10853
- if (bgProps.borderWidth === void 0 || bgProps.borderWidth === 0) {
10854
- normalized.borderWidth = 1;
10855
- }
10856
- if (bgProps.borderAlpha === void 0 || bgProps.borderAlpha === 0) {
10857
- normalized.borderAlpha = 1;
10858
- }
10859
- }
10860
- return normalized;
10861
- }
10862
- const viewCreator = (scene, props) => {
10863
- if (props.backgroundColor !== void 0 || props.cornerRadius !== void 0) {
10864
- DebugLogger.log("theme", "View Creator - Props received:", {
10865
- backgroundColor: props.backgroundColor,
10866
- cornerRadius: props.cornerRadius,
10867
- width: props.width,
10868
- height: props.height
10869
- });
10870
- }
10871
- const normalizedProps = normalizeBackgroundProps(props);
10872
- const container = scene.add.container(normalizedProps.x ?? 0, normalizedProps.y ?? 0);
10873
- createTransform(container, normalizedProps);
10874
- createPhaser(container, normalizedProps);
10875
- createBackground(
10876
- scene,
10877
- container,
10878
- normalizedProps
10879
- );
10880
- createLayout(container, normalizedProps);
10881
- if (normalizedProps.onTooltip) {
10882
- const handlers = applyTooltip(
10883
- scene,
10884
- container,
10885
- normalizedProps.onTooltip,
10886
- normalizedProps.onHoverStart,
10887
- normalizedProps.onHoverEnd
10888
- );
10889
- normalizedProps.onHoverStart = handlers.onHoverStart;
10890
- normalizedProps.onHoverEnd = handlers.onHoverEnd;
10891
- }
10892
- createGestures(scene, container, normalizedProps);
10893
- DebugLogger.log(
10894
- "layout",
10895
- "View creator storing __layoutProps with padding:",
10896
- normalizedProps.padding
10897
- );
10898
- return container;
10899
- };
10900
- const viewPatcher = (node, prev, next) => {
10901
- const normalizedPrev = normalizeBackgroundProps(prev);
10902
- const normalizedNext = normalizeBackgroundProps(next);
10903
- applyTransformProps(node, normalizedPrev, normalizedNext);
10904
- applyPhaserProps(node, normalizedPrev, normalizedNext);
10905
- const container = node;
10906
- applyBackgroundProps(container, normalizedPrev, normalizedNext);
10907
- if (container.scene && container.scene.data) {
10908
- if (normalizedNext.onTooltip) {
10909
- const handlers = applyTooltip(
10910
- container.scene,
10911
- container,
10912
- normalizedNext.onTooltip,
10913
- normalizedNext.onHoverStart,
10914
- normalizedNext.onHoverEnd
10915
- );
10916
- normalizedNext.onHoverStart = handlers.onHoverStart;
10917
- normalizedNext.onHoverEnd = handlers.onHoverEnd;
10918
- }
10919
- }
10920
- if (container.scene && container.scene.data) {
10921
- applyGesturesProps(container.scene, container, normalizedPrev, normalizedNext);
10922
- }
10923
- applyLayoutProps(container, normalizedPrev, normalizedNext);
10924
- };
10925
9617
  class RenderContext {
10926
9618
  constructor(scene) {
10927
9619
  this.scene = scene;
@@ -11273,6 +9965,41 @@ class MountRegistry {
11273
9965
  getEntry(id) {
11274
9966
  return this.entries.get(id);
11275
9967
  }
9968
+ /**
9969
+ * Find a mount entry by parent and optional key
9970
+ * If key is provided, matches parent AND key
9971
+ * If key is omitted, returns first mount with matching parent (backward compatibility)
9972
+ * Validates that scene is still active and objects are not destroyed
9973
+ * @param parent - Parent container or scene
9974
+ * @param key - Optional unique key to distinguish multiple mounts on same parent
9975
+ * @returns Mount entry or undefined if not found or invalid
9976
+ */
9977
+ findByParentAndKey(parent, key) {
9978
+ for (const entry of this.entries.values()) {
9979
+ const scene = entry.parent instanceof Phaser$1.Scene ? entry.parent : entry.parent.scene;
9980
+ if (!scene || !scene.sys || !scene.sys.settings.active) {
9981
+ DebugLogger.log("vdom", `Removing mount ${entry.id} - scene inactive`);
9982
+ this.unregister(entry.id);
9983
+ continue;
9984
+ }
9985
+ if (!entry.rootNode.active || entry.rootNode.scene !== scene) {
9986
+ DebugLogger.log("vdom", `Removing mount ${entry.id} - rootNode destroyed or scene changed`);
9987
+ this.unregister(entry.id);
9988
+ continue;
9989
+ }
9990
+ const entryKey = entry.props.key;
9991
+ if (key !== void 0) {
9992
+ if (entry.parent === parent && entryKey === key) {
9993
+ return entry;
9994
+ }
9995
+ } else {
9996
+ if (entry.parent === parent) {
9997
+ return entry;
9998
+ }
9999
+ }
10000
+ }
10001
+ return void 0;
10002
+ }
11276
10003
  /**
11277
10004
  * Get all active mount entries
11278
10005
  * @returns Array of mount entries
@@ -11280,6 +10007,50 @@ class MountRegistry {
11280
10007
  getAllEntries() {
11281
10008
  return Array.from(this.entries.values());
11282
10009
  }
10010
+ /**
10011
+ * Get count of active mounts
10012
+ * @returns Number of registered mounts
10013
+ */
10014
+ getCount() {
10015
+ return this.entries.size;
10016
+ }
10017
+ /**
10018
+ * Get statistics about active mounts
10019
+ * @returns Object with mount statistics
10020
+ */
10021
+ getStats() {
10022
+ const byType = /* @__PURE__ */ new Map();
10023
+ const byParent = /* @__PURE__ */ new Map();
10024
+ const byKey = /* @__PURE__ */ new Map();
10025
+ const mounts = [];
10026
+ for (const entry of this.entries.values()) {
10027
+ const typeName = typeof entry.type === "string" ? entry.type : entry.type.name || "Component";
10028
+ byType.set(typeName, (byType.get(typeName) ?? 0) + 1);
10029
+ byParent.set(entry.parent, (byParent.get(entry.parent) ?? 0) + 1);
10030
+ const key = entry.props.key;
10031
+ if (key) {
10032
+ byKey.set(key, (byKey.get(key) ?? 0) + 1);
10033
+ }
10034
+ const parentType = entry.parent instanceof Phaser$1.Scene ? "Scene" : "Container";
10035
+ const mountInfo = {
10036
+ id: entry.id,
10037
+ type: typeName,
10038
+ parentType,
10039
+ propsKeys: Object.keys(entry.props)
10040
+ };
10041
+ if (key !== void 0) {
10042
+ mountInfo.key = key;
10043
+ }
10044
+ mounts.push(mountInfo);
10045
+ }
10046
+ return {
10047
+ totalMounts: this.entries.size,
10048
+ byType,
10049
+ byParent,
10050
+ byKey,
10051
+ mounts
10052
+ };
10053
+ }
11283
10054
  /**
11284
10055
  * Clear all entries (for testing)
11285
10056
  */
@@ -11289,6 +10060,9 @@ class MountRegistry {
11289
10060
  }
11290
10061
  }
11291
10062
  const mountRegistry = new MountRegistry();
10063
+ function getMountStats() {
10064
+ return mountRegistry.getStats();
10065
+ }
11292
10066
  function remountAll() {
11293
10067
  const entries = mountRegistry.getAllEntries();
11294
10068
  if (entries.length === 0) {
@@ -11360,6 +10134,14 @@ function remountAll() {
11360
10134
  });
11361
10135
  console.log("[REMOUNT] Remount complete");
11362
10136
  }
10137
+ function normalizeVNodeLike(rendered) {
10138
+ if (!rendered) return null;
10139
+ if (Array.isArray(rendered)) {
10140
+ const flat = rendered.flat(Infinity);
10141
+ return { type: Fragment, props: {}, children: flat };
10142
+ }
10143
+ return rendered;
10144
+ }
11363
10145
  function flattenChildren(children) {
11364
10146
  if (!children) return [];
11365
10147
  return children.flat(Infinity);
@@ -11613,10 +10395,11 @@ function mount(parentOrScene, vnode) {
11613
10395
  };
11614
10396
  vnode = setVNodePropSafe(vnode, "__ctx", ctx);
11615
10397
  const propsWithChildren = vnode.children?.length ? { ...vnode.props ?? {}, children: vnode.children } : vnode.props;
11616
- let rendered = withHooks(
10398
+ const renderedRaw = withHooks(
11617
10399
  ctx,
11618
10400
  () => vnode.type(propsWithChildren)
11619
10401
  );
10402
+ let rendered = normalizeVNodeLike(renderedRaw);
11620
10403
  if (!rendered) {
11621
10404
  ctx.vnode = rendered;
11622
10405
  for (const run of ctx.effects) run();
@@ -11775,6 +10558,30 @@ function patchVNode(parent, oldV, newV) {
11775
10558
  warnUnnecessaryRemount(oldV, newV);
11776
10559
  unmount(oldV);
11777
10560
  mount(parent, newV);
10561
+ if (parent && typeof parent === "object" && "list" in parent) {
10562
+ const parentContainer = parent;
10563
+ if (parentContainer.__layoutProps) {
10564
+ let grandparentSize;
10565
+ const grandparent = parentContainer.parentContainer;
10566
+ if (grandparent && grandparent.__layoutProps && grandparent.__getLayoutSize) {
10567
+ const gpSize = grandparent.__getLayoutSize();
10568
+ const gpPadding = grandparent.__layoutProps.padding ?? 0;
10569
+ const normGpPadding = typeof gpPadding === "number" ? { left: gpPadding, right: gpPadding, top: gpPadding, bottom: gpPadding } : {
10570
+ left: gpPadding.left ?? 0,
10571
+ right: gpPadding.right ?? 0,
10572
+ top: gpPadding.top ?? 0,
10573
+ bottom: gpPadding.bottom ?? 0
10574
+ };
10575
+ grandparentSize = {
10576
+ width: gpSize.width - normGpPadding.left - normGpPadding.right,
10577
+ height: gpSize.height - normGpPadding.top - normGpPadding.bottom
10578
+ };
10579
+ }
10580
+ calculateLayout(parentContainer, parentContainer.__layoutProps, grandparentSize);
10581
+ const renderContext = getRenderContext(parent);
10582
+ renderContext.deferLayout(() => updateGestureHitAreaAfterLayout(parentContainer));
10583
+ }
10584
+ }
11778
10585
  return;
11779
10586
  }
11780
10587
  if (oldV.type === Fragment && newV.type === Fragment) {
@@ -11820,10 +10627,12 @@ function patchVNode(parent, oldV, newV) {
11820
10627
  if (!ctx) {
11821
10628
  if (!newV || !oldV) return;
11822
10629
  const propsWithChildren2 = newV.children?.length ? { ...newV.props ?? {}, children: newV.children } : newV.props;
11823
- const oldRendered = oldV.type(
10630
+ const oldRenderedRaw = oldV.type(
11824
10631
  oldV.children?.length ? { ...oldV.props ?? {}, children: oldV.children } : oldV.props
11825
10632
  );
11826
- const newRendered = newV.type(propsWithChildren2);
10633
+ const newRenderedRaw = newV.type(propsWithChildren2);
10634
+ const oldRendered = normalizeVNodeLike(oldRenderedRaw);
10635
+ const newRendered = normalizeVNodeLike(newRenderedRaw);
11827
10636
  patchVNode(parent, oldRendered, newRendered);
11828
10637
  return;
11829
10638
  }
@@ -11841,10 +10650,11 @@ function patchVNode(parent, oldV, newV) {
11841
10650
  if (!shouldComponentUpdate(ctx, propsWithChildren)) {
11842
10651
  return;
11843
10652
  }
11844
- const renderedNext = withHooks(
10653
+ const renderedNextRaw = withHooks(
11845
10654
  ctx,
11846
10655
  () => newVWithCtx.type(propsWithChildren)
11847
10656
  );
10657
+ const renderedNext = normalizeVNodeLike(renderedNextRaw);
11848
10658
  if (!renderedNext) {
11849
10659
  ctx.vnode = renderedNext;
11850
10660
  for (const run of ctx.effects) run();
@@ -11875,6 +10685,7 @@ function patchVNode(parent, oldV, newV) {
11875
10685
  }
11876
10686
  const nodeType = oldV.type;
11877
10687
  newV = setVNodePropSafe(newV, "__node", oldV.__node);
10688
+ newV = setVNodePropSafe(newV, "__parent", parent);
11878
10689
  if (newV.__theme !== void 0) {
11879
10690
  const themed = setThemeSafe(oldV, newV.__theme);
11880
10691
  if (themed !== oldV) {
@@ -11919,6 +10730,11 @@ function patchVNode(parent, oldV, newV) {
11919
10730
  warnMissingKeys(newV, b);
11920
10731
  }
11921
10732
  const containerLayoutChanged = hasLayoutPropsChanged(oldV, newV);
10733
+ const oldValidChildCount = a.filter((c) => c != null && c !== false).length;
10734
+ const newValidChildCount = b.filter((c) => c != null && c !== false).length;
10735
+ if (oldValidChildCount !== newValidChildCount) {
10736
+ childrenChanged = true;
10737
+ }
11922
10738
  for (let i = 0; i < len; i++) {
11923
10739
  const c1 = a[i], c2 = b[i];
11924
10740
  const isValidC1 = c1 != null && c1 !== false;
@@ -11999,7 +10815,74 @@ function patchVNode(parent, oldV, newV) {
11999
10815
  }
12000
10816
  }
12001
10817
  function mountJSX(parentOrScene, type, props = { width: 0, height: 0 }) {
12002
- const { width, height, disableAutoSize = false, ...componentProps } = props;
10818
+ const key = props.key;
10819
+ const existingMount = mountRegistry.findByParentAndKey(parentOrScene, key);
10820
+ if (existingMount) {
10821
+ if (existingMount.type !== type) {
10822
+ const oldTypeName = typeof existingMount.type === "string" ? existingMount.type : existingMount.type.name || "Component";
10823
+ const newTypeName = typeof type === "string" ? type : type.name || "Component";
10824
+ console.warn(
10825
+ `[PhaserJSX] mountJSX type mismatch: Attempting to patch <${oldTypeName}> with <${newTypeName}>.
10826
+ This usually means you're missing a 'key' prop to distinguish multiple mounts on the same parent.
10827
+ Solution: Add unique keys like { key: 'sidebar', ... } and { key: 'main', ... }`
10828
+ );
10829
+ }
10830
+ const newWidth = props.width ?? existingMount.props.width;
10831
+ const newHeight = props.height ?? existingMount.props.height;
10832
+ const dimensionsChanged = newWidth !== existingMount.props.width || newHeight !== existingMount.props.height;
10833
+ const { disableAutoSize: _d, key: _k, ...componentProps2 } = props;
10834
+ if (dimensionsChanged) {
10835
+ existingMount.props = {
10836
+ ...existingMount.props,
10837
+ ...componentProps2,
10838
+ width: newWidth,
10839
+ height: newHeight
10840
+ };
10841
+ } else {
10842
+ existingMount.props = { ...existingMount.props, ...componentProps2 };
10843
+ }
10844
+ let newVNode;
10845
+ if (existingMount.props.disableAutoSize) {
10846
+ newVNode = {
10847
+ type: existingMount.type,
10848
+ props: {
10849
+ ...componentProps2,
10850
+ width: existingMount.props.width,
10851
+ height: existingMount.props.height
10852
+ },
10853
+ children: []
10854
+ };
10855
+ } else {
10856
+ const componentVNode = {
10857
+ type: existingMount.type,
10858
+ props: {
10859
+ ...componentProps2,
10860
+ width: existingMount.props.width,
10861
+ height: existingMount.props.height
10862
+ },
10863
+ children: []
10864
+ };
10865
+ newVNode = {
10866
+ type: SceneWrapper,
10867
+ props: {
10868
+ width: existingMount.props.width,
10869
+ height: existingMount.props.height,
10870
+ children: componentVNode
10871
+ },
10872
+ children: []
10873
+ };
10874
+ }
10875
+ patchVNode(parentOrScene, existingMount.vnode, newVNode);
10876
+ existingMount.vnode = newVNode;
10877
+ const handle2 = existingMount.rootNode;
10878
+ handle2.unmount = () => unmountJSX(handle2);
10879
+ DebugLogger.log(
10880
+ "vdom",
10881
+ `Patched existing mount ${existingMount.id} on same parent (type: ${typeof type === "string" ? type : type.name})`
10882
+ );
10883
+ return handle2;
10884
+ }
10885
+ const { width, height, disableAutoSize = false, key: _key, ...componentProps } = props;
12003
10886
  const scene = parentOrScene instanceof Phaser$1.Scene ? parentOrScene : parentOrScene.scene;
12004
10887
  if (scene) {
12005
10888
  const renderContext = getRenderContext(parentOrScene);
@@ -12012,7 +10895,11 @@ function mountJSX(parentOrScene, type, props = { width: 0, height: 0 }) {
12012
10895
  } else {
12013
10896
  const componentVNode = {
12014
10897
  type,
12015
- props: componentProps,
10898
+ props: {
10899
+ ...componentProps,
10900
+ width,
10901
+ height
10902
+ },
12016
10903
  children: []
12017
10904
  };
12018
10905
  vnode = {
@@ -12066,8 +10953,10 @@ function unmountJSX(target) {
12066
10953
  const vdom = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
12067
10954
  __proto__: null,
12068
10955
  createElement,
10956
+ getMountStats,
12069
10957
  mount,
12070
10958
  mountJSX,
10959
+ normalizeVNodeLike,
12071
10960
  patchVNode,
12072
10961
  remountAll,
12073
10962
  unmount,
@@ -12162,6 +11051,68 @@ function useScene() {
12162
11051
  const renderContext = getContextFromParent(ctx.parent);
12163
11052
  return renderContext.scene;
12164
11053
  }
11054
+ function useViewportSize() {
11055
+ const ctx = getCurrent();
11056
+ if (!ctx) {
11057
+ throw new Error("useViewportSize must be called within a component");
11058
+ }
11059
+ const renderContext = getContextFromParent(ctx.parent);
11060
+ return renderContext.getViewport();
11061
+ }
11062
+ function getLayoutSize(container) {
11063
+ if (!container) return void 0;
11064
+ const withLayout = container;
11065
+ return withLayout.__getLayoutSize?.();
11066
+ }
11067
+ function useLayoutSize(ref) {
11068
+ return getLayoutSize(ref.current);
11069
+ }
11070
+ function getLayoutProps(container) {
11071
+ if (!container) return void 0;
11072
+ const withLayout = container;
11073
+ return withLayout.__layoutProps;
11074
+ }
11075
+ function getBackgroundGraphics(container) {
11076
+ if (!container) return void 0;
11077
+ const withBackground = container;
11078
+ return withBackground.__background;
11079
+ }
11080
+ function useBackgroundGraphics(ref) {
11081
+ return getBackgroundGraphics(ref.current);
11082
+ }
11083
+ function getLayoutRect(container) {
11084
+ if (!container) return void 0;
11085
+ const size = getLayoutSize(container);
11086
+ if (!size) return void 0;
11087
+ return {
11088
+ x: container.x,
11089
+ y: container.y,
11090
+ width: size.width,
11091
+ height: size.height
11092
+ };
11093
+ }
11094
+ function useLayoutRect(ref) {
11095
+ return getLayoutRect(ref.current);
11096
+ }
11097
+ function getWorldLayoutRect(container) {
11098
+ if (!container) return void 0;
11099
+ const size = getLayoutSize(container);
11100
+ if (!size) return void 0;
11101
+ const matrix = container.getWorldTransformMatrix();
11102
+ const worldX = matrix.tx;
11103
+ const worldY = matrix.ty;
11104
+ const worldWidth = size.width * Math.abs(matrix.scaleX);
11105
+ const worldHeight = size.height * Math.abs(matrix.scaleY);
11106
+ return {
11107
+ x: worldX,
11108
+ y: worldY,
11109
+ width: worldWidth,
11110
+ height: worldHeight
11111
+ };
11112
+ }
11113
+ function useWorldLayoutRect(ref) {
11114
+ return getWorldLayoutRect(ref.current);
11115
+ }
12165
11116
  function useEffect(fn, deps) {
12166
11117
  const c = getCurrent();
12167
11118
  const i = c.index++;
@@ -12175,6 +11126,21 @@ function useEffect(fn, deps) {
12175
11126
  }
12176
11127
  });
12177
11128
  }
11129
+ function useLayoutEffect(fn, deps) {
11130
+ const c = getCurrent();
11131
+ const i = c.index++;
11132
+ const slot = c.slots[i] ?? (c.slots[i] = { deps: void 0, cleanup: void 0 });
11133
+ c.effects.push(() => {
11134
+ if (!depsChanged(slot.deps, deps)) return;
11135
+ if (typeof slot.cleanup === "function") slot.cleanup();
11136
+ requestAnimationFrame(() => {
11137
+ slot.cleanup = fn();
11138
+ });
11139
+ if (deps !== void 0) {
11140
+ slot.deps = deps;
11141
+ }
11142
+ });
11143
+ }
12178
11144
  function depsChanged(a, b) {
12179
11145
  if (!a || !b) return true;
12180
11146
  if (a.length !== b.length) return true;
@@ -12227,7 +11193,7 @@ function scheduleUpdate(c) {
12227
11193
  }
12228
11194
  const componentProps = c.componentVNode.props ?? {};
12229
11195
  const propsWithChildren = c.componentVNode.children?.length ? { ...componentProps, children: c.componentVNode.children } : componentProps;
12230
- const nextVNode = withHooks(c, () => c.function(propsWithChildren));
11196
+ const nextVNode = normalizeVNodeLike(withHooks(c, () => c.function(propsWithChildren)));
12231
11197
  patchVNode(c.parent, c.vnode, nextVNode);
12232
11198
  c.vnode = nextVNode;
12233
11199
  for (const run of c.effects) run();
@@ -13011,6 +11977,11 @@ function Button(props) {
13011
11977
  }
13012
11978
  );
13013
11979
  }
11980
+ function Graphics(props) {
11981
+ const localTheme = useTheme();
11982
+ const { props: themed, nestedTheme } = getThemedProps("Graphics", localTheme, props);
11983
+ return /* @__PURE__ */ jsx("graphics", { ...themed, theme: nestedTheme });
11984
+ }
13014
11985
  function RadioButton(props) {
13015
11986
  const { props: themed, nestedTheme } = getThemedProps("RadioButton", void 0, {});
13016
11987
  const size = themed.size ?? 16;
@@ -13113,24 +12084,8 @@ function Text(props) {
13113
12084
  const { props: themed, nestedTheme } = getThemedProps("Text", localTheme, props);
13114
12085
  return /* @__PURE__ */ jsx("text", { ...themed, theme: nestedTheme });
13115
12086
  }
13116
- const Sprite = "Sprite";
13117
- const Graphics = "Graphics";
13118
- const TileSprite = "TileSprite";
13119
- function registerBuiltins() {
13120
- register("view", { create: viewCreator, patch: viewPatcher });
13121
- register("text", { create: textCreator, patch: textPatcher });
13122
- register("nineslice", { create: nineSliceCreator, patch: nineSlicePatcher });
13123
- register("sprite", { create: spriteCreator, patch: spritePatcher });
13124
- register("image", { create: imageCreator, patch: imagePatcher });
13125
- register("graphics", { create: graphicsCreator, patch: graphicsPatcher });
13126
- register("tilesprite", { create: tileSpriteCreator, patch: tileSpritePatcher });
13127
- register("View", { create: viewCreator, patch: viewPatcher });
13128
- register("Text", { create: textCreator, patch: textPatcher });
13129
- register("NineSlice", { create: nineSliceCreator, patch: nineSlicePatcher });
13130
- register("Sprite", { create: spriteCreator, patch: spritePatcher });
13131
- register("Image", { create: imageCreator, patch: imagePatcher });
13132
- register("Graphics", { create: graphicsCreator, patch: graphicsPatcher });
13133
- register("TileSprite", { create: tileSpriteCreator, patch: tileSpritePatcher });
12087
+ function Particles(props) {
12088
+ return /* @__PURE__ */ jsx("particles", { ...props });
13134
12089
  }
13135
12090
  function preprocessSvgForTinting(svg) {
13136
12091
  return svg.replace(/fill="currentColor"/gi, 'fill="#FFFFFF"').replace(/fill='currentColor'/gi, "fill='#FFFFFF'").replace(/fill:\s*currentColor/gi, "fill: #FFFFFF").replace(/fill="#000000"/gi, 'fill="#FFFFFF"').replace(/fill="#000"/gi, 'fill="#FFFFFF"').replace(/fill='#000000'/gi, "fill='#FFFFFF'").replace(/fill='#000'/gi, "fill='#FFFFFF'");
@@ -14036,6 +12991,13 @@ function Portal(props) {
14036
12991
  const blockEvents = props.blockEvents ?? true;
14037
12992
  const mountedNodesRef = useRef([]);
14038
12993
  const previousChildrenRef = useRef([]);
12994
+ const normalizeChildren2 = (children) => {
12995
+ if (!children) return [];
12996
+ const flat = Array.isArray(children) ? children.flat(Infinity) : [children];
12997
+ return flat.filter(
12998
+ (child) => !!child && typeof child === "object" && "type" in child
12999
+ );
13000
+ };
14039
13001
  useEffect(() => {
14040
13002
  const portalContainer = portalRegistry.register(
14041
13003
  portalId,
@@ -14050,7 +13012,7 @@ function Portal(props) {
14050
13012
  portalContainer.add(blockerContainer);
14051
13013
  blockerContainer.setDepth(-1);
14052
13014
  }
14053
- const children = Array.isArray(props.children) ? props.children : [props.children];
13015
+ const children = normalizeChildren2(props.children);
14054
13016
  const mountedNodes = [];
14055
13017
  for (const child of children) {
14056
13018
  if (child) {
@@ -14114,7 +13076,7 @@ function Portal(props) {
14114
13076
  const portal = portalRegistry.get(portalId);
14115
13077
  if (!portal) return;
14116
13078
  const portalContainer = portal.container;
14117
- const newChildren = Array.isArray(props.children) ? props.children : [props.children];
13079
+ const newChildren = normalizeChildren2(props.children);
14118
13080
  const oldChildren = previousChildrenRef.current;
14119
13081
  const maxLen = Math.max(oldChildren.length, newChildren.length);
14120
13082
  for (let i = 0; i < maxLen; i++) {
@@ -15519,7 +14481,7 @@ function Divider(props) {
15519
14481
  }
15520
14482
  function calculateSliderSize(size) {
15521
14483
  const { props: themed } = getThemedProps("ScrollSlider", void 0, {});
15522
- const sizeFactor = size === "large" ? 1.25 : size === "small" ? 0.75 : size === "tiny" ? 0.5 : 1;
14484
+ const sizeFactor = size === "large" ? 1.25 : size === "small" ? 0.75 : size === "tiny" ? 0.5 : size === "micro" ? 0.25 : size === "nano" ? 0.125 : 1;
15523
14485
  const border = (themed.borderWidth ?? 1) * sizeFactor;
15524
14486
  const outer = (themed.size ?? 24) * sizeFactor;
15525
14487
  const dimension = outer - border * 2;
@@ -15680,10 +14642,17 @@ function ScrollView(props) {
15680
14642
  snap = false,
15681
14643
  snapAlignment = "start",
15682
14644
  snapThreshold = 20,
15683
- momentum = true
14645
+ momentum = true,
14646
+ onSnap,
14647
+ ...viewProps
15684
14648
  } = props;
15685
- const [scroll, setScroll] = useState(initialScroll ?? { dx: 0, dy: 0 });
14649
+ const [scroll, setScroll] = useState({
14650
+ dx: initialScroll?.dx ?? 0,
14651
+ dy: initialScroll?.dy ?? 0
14652
+ });
15686
14653
  const scrollRef = useRef(scroll);
14654
+ const hasMountedRef = useRef(false);
14655
+ const lastAppliedSnapIndexRef = useRef(initialScroll?.snapIndex);
15687
14656
  const contentRef = useRef(null);
15688
14657
  const viewportRef = useRef(null);
15689
14658
  const [contentHeight, setContentHeight] = useState(0);
@@ -15693,7 +14662,6 @@ function ScrollView(props) {
15693
14662
  const tweenRef = useRef(null);
15694
14663
  const wheelSnapTimeoutRef = useRef(null);
15695
14664
  const WHEEL_SNAP_DELAY = 200;
15696
- const { outer: sliderSize } = calculateSliderSize(props.sliderSize);
15697
14665
  const viewportHeight = viewportRef.current?.height ?? 0;
15698
14666
  const viewportWidth = viewportRef.current?.width ?? 0;
15699
14667
  const effectiveContentHeight = Math.max(contentHeight, viewportHeight);
@@ -15703,6 +14671,11 @@ function ScrollView(props) {
15703
14671
  const needsHorizontalScroll = effectiveContentWidth > viewportWidth + epsilon;
15704
14672
  const showVerticalSliderActual = showVerticalSlider === true || needsVerticalScroll && showVerticalSlider === "auto";
15705
14673
  const showHorizontalSliderActual = showHorizontalSlider === true || needsHorizontalScroll && showHorizontalSlider === "auto";
14674
+ const { outer: sliderSize } = calculateSliderSize(props.sliderSize);
14675
+ props.onSliderSize?.({
14676
+ width: showVerticalSlider ? sliderSize : 0,
14677
+ height: showHorizontalSliderActual ? sliderSize : 0
14678
+ });
15706
14679
  const maxScrollY = Math.max(0, effectiveContentHeight - viewportHeight);
15707
14680
  const maxScrollX = Math.max(0, effectiveContentWidth - viewportWidth);
15708
14681
  const updateScroll = (value) => {
@@ -15721,10 +14694,77 @@ function ScrollView(props) {
15721
14694
  const resolvedSnapThreshold = typeof snap === "object" && "positions" in snap ? snap.threshold ?? snapThreshold : snapThreshold;
15722
14695
  const effectiveSnapThreshold = resolvedSnapThreshold === void 0 || resolvedSnapThreshold < 0 ? Infinity : resolvedSnapThreshold;
15723
14696
  useEffect(() => {
15724
- if (initialScroll) {
15725
- updateScroll(initialScroll);
14697
+ if (!initialScroll) return;
14698
+ const allowAnimate = hasMountedRef.current;
14699
+ if (snap && typeof snap === "object" && "positions" in snap) {
14700
+ const { x: xTargets, y: yTargets } = getSnapTargets();
14701
+ const hasTargets = xTargets.length > 0 || yTargets.length > 0;
14702
+ if (initialScroll.snapIndex !== void 0 && hasTargets) {
14703
+ const maxIdx = Math.max(xTargets.length, yTargets.length) - 1;
14704
+ const clampedIdx = Math.max(0, Math.min(initialScroll.snapIndex, maxIdx));
14705
+ const targetX = xTargets[clampedIdx];
14706
+ const targetY = yTargets[clampedIdx];
14707
+ const nextDx = targetX !== void 0 ? alignTargetPosition(targetX, viewportWidth, maxScrollX) : initialScroll.dx ?? scrollRef.current.dx;
14708
+ const nextDy = targetY !== void 0 ? alignTargetPosition(targetY, viewportHeight, maxScrollY) : initialScroll.dy ?? scrollRef.current.dy;
14709
+ const shouldAnimate = allowAnimate && (clampedIdx !== lastAppliedSnapIndexRef.current || Math.abs(scrollRef.current.dx - nextDx) > 0.5 || Math.abs(scrollRef.current.dy - nextDy) > 0.5);
14710
+ lastAppliedSnapIndexRef.current = clampedIdx;
14711
+ if (shouldAnimate && contentRef.current?.scene) {
14712
+ stopActiveTween();
14713
+ const scene = contentRef.current.scene;
14714
+ tweenRef.current = scene.tweens.add({
14715
+ targets: { dx: scrollRef.current.dx, dy: scrollRef.current.dy },
14716
+ dx: nextDx,
14717
+ dy: nextDy,
14718
+ duration: 220,
14719
+ ease: "Quad.easeOut",
14720
+ onUpdate: (tween) => {
14721
+ const target = tween.targets[0];
14722
+ updateScroll({ dx: target.dx, dy: target.dy });
14723
+ },
14724
+ onComplete: () => {
14725
+ tweenRef.current = null;
14726
+ if (onSnap) {
14727
+ onSnap(clampedIdx);
14728
+ }
14729
+ }
14730
+ });
14731
+ } else {
14732
+ updateScroll({ dx: nextDx, dy: nextDy });
14733
+ if (onSnap) {
14734
+ onSnap(clampedIdx);
14735
+ }
14736
+ }
14737
+ hasMountedRef.current = true;
14738
+ return;
14739
+ }
14740
+ }
14741
+ if (initialScroll.dx !== void 0 && initialScroll.dy !== void 0) {
14742
+ const nextDx = initialScroll.dx;
14743
+ const nextDy = initialScroll.dy;
14744
+ const shouldAnimate = allowAnimate && (Math.abs(scrollRef.current.dx - nextDx) > 0.5 || Math.abs(scrollRef.current.dy - nextDy) > 0.5);
14745
+ if (shouldAnimate && contentRef.current?.scene) {
14746
+ stopActiveTween();
14747
+ const scene = contentRef.current.scene;
14748
+ tweenRef.current = scene.tweens.add({
14749
+ targets: { dx: scrollRef.current.dx, dy: scrollRef.current.dy },
14750
+ dx: nextDx,
14751
+ dy: nextDy,
14752
+ duration: 220,
14753
+ ease: "Quad.easeOut",
14754
+ onUpdate: (tween) => {
14755
+ const target = tween.targets[0];
14756
+ updateScroll({ dx: target.dx, dy: target.dy });
14757
+ },
14758
+ onComplete: () => {
14759
+ tweenRef.current = null;
14760
+ }
14761
+ });
14762
+ } else {
14763
+ updateScroll({ dx: nextDx, dy: nextDy });
14764
+ }
15726
14765
  }
15727
- }, [initialScroll]);
14766
+ hasMountedRef.current = true;
14767
+ }, [initialScroll, snap, viewportWidth, viewportHeight, maxScrollX, maxScrollY]);
15728
14768
  useEffect(() => {
15729
14769
  if (onScrollInfoChange && viewportWidth > 0 && viewportHeight > 0) {
15730
14770
  onScrollInfoChange({
@@ -15806,6 +14846,9 @@ function ScrollView(props) {
15806
14846
  },
15807
14847
  onComplete: () => {
15808
14848
  tweenRef.current = null;
14849
+ if (snappedTarget && snappedTarget.index >= 0 && onSnap) {
14850
+ onSnap(snappedTarget.index);
14851
+ }
15809
14852
  }
15810
14853
  });
15811
14854
  };
@@ -15831,10 +14874,12 @@ function ScrollView(props) {
15831
14874
  return { x: [], y: [] };
15832
14875
  };
15833
14876
  const findNearestSnap = (current, targets, viewportSize, maxScroll) => {
15834
- if (targets.length === 0) return current;
14877
+ if (targets.length === 0) return { position: current, index: -1 };
15835
14878
  let nearest = current;
15836
14879
  let minDistance = Infinity;
15837
- for (const { position, size } of targets) {
14880
+ let nearestIndex = -1;
14881
+ for (let index = 0; index < targets.length; index++) {
14882
+ const { position, size } = targets[index] ?? { position: 0, size: 0 };
15838
14883
  let adjustedPos = position;
15839
14884
  if (snapAlignment === "center") {
15840
14885
  adjustedPos = position + size / 2 - viewportSize / 2;
@@ -15846,29 +14891,47 @@ function ScrollView(props) {
15846
14891
  if (distance < minDistance && distance <= effectiveSnapThreshold) {
15847
14892
  minDistance = distance;
15848
14893
  nearest = adjustedPos;
14894
+ nearestIndex = index;
15849
14895
  } else if (distance < minDistance && effectiveSnapThreshold === Infinity) {
15850
14896
  minDistance = distance;
15851
14897
  nearest = adjustedPos;
14898
+ nearestIndex = index;
15852
14899
  }
15853
14900
  }
15854
- return nearest;
14901
+ return { position: nearest, index: nearestIndex };
15855
14902
  };
15856
14903
  const calculateSnapDestination = (baseDx, baseDy) => {
15857
14904
  const { x: xTargets, y: yTargets } = getSnapTargets();
15858
14905
  const viewportHeightLocal = viewportRef.current?.height ?? 0;
15859
14906
  const viewportWidthLocal = viewportRef.current?.width ?? 0;
15860
- const targetDx = findNearestSnap(baseDx, xTargets, viewportWidthLocal, maxScrollX);
15861
- const targetDy = findNearestSnap(baseDy, yTargets, viewportHeightLocal, maxScrollY);
15862
- return { dx: targetDx, dy: targetDy };
14907
+ const snapX = findNearestSnap(baseDx, xTargets, viewportWidthLocal, maxScrollX);
14908
+ const snapY = findNearestSnap(baseDy, yTargets, viewportHeightLocal, maxScrollY);
14909
+ const snapIndex = snapY.index >= 0 ? snapY.index : snapX.index;
14910
+ return { dx: snapX.position, dy: snapY.position, index: snapIndex };
14911
+ };
14912
+ const alignTargetPosition = (target, viewportSize, maxScroll) => {
14913
+ let adjustedPos = target.position;
14914
+ if (snapAlignment === "center") {
14915
+ adjustedPos = target.position + target.size / 2 - viewportSize / 2;
14916
+ } else if (snapAlignment === "end") {
14917
+ adjustedPos = target.position + target.size - viewportSize;
14918
+ }
14919
+ return Math.max(0, Math.min(maxScroll, adjustedPos));
15863
14920
  };
15864
14921
  const applySnap = () => {
15865
14922
  if (!contentRef.current?.scene || !snap) return;
15866
14923
  const currentScroll = scrollRef.current;
15867
- const { dx: targetDx, dy: targetDy } = calculateSnapDestination(
15868
- currentScroll.dx,
15869
- currentScroll.dy
15870
- );
15871
- if (targetDx === currentScroll.dx && targetDy === currentScroll.dy) return;
14924
+ const {
14925
+ dx: targetDx,
14926
+ dy: targetDy,
14927
+ index: snapIndex
14928
+ } = calculateSnapDestination(currentScroll.dx, currentScroll.dy);
14929
+ if (targetDx === currentScroll.dx && targetDy === currentScroll.dy) {
14930
+ if (snapIndex >= 0 && onSnap) {
14931
+ onSnap(snapIndex);
14932
+ }
14933
+ return;
14934
+ }
15872
14935
  const scene = contentRef.current.scene;
15873
14936
  stopActiveTween();
15874
14937
  tweenRef.current = scene.tweens.add({
@@ -15883,6 +14946,9 @@ function ScrollView(props) {
15883
14946
  },
15884
14947
  onComplete: () => {
15885
14948
  tweenRef.current = null;
14949
+ if (snapIndex >= 0 && onSnap) {
14950
+ onSnap(snapIndex);
14951
+ }
15886
14952
  }
15887
14953
  });
15888
14954
  };
@@ -15954,7 +15020,8 @@ function ScrollView(props) {
15954
15020
  stopActiveTween();
15955
15021
  };
15956
15022
  }, [showVerticalSliderActual, showHorizontalSliderActual]);
15957
- return /* @__PURE__ */ jsx(View, { visible, children: /* @__PURE__ */ jsxs(View, { direction: "row", width: "100%", height: "100%", gap: 0, padding: 0, children: [
15023
+ const resolvedVisible = viewProps.visible === "none" ? "none" : visible ? viewProps.visible ?? true : false;
15024
+ return /* @__PURE__ */ jsx(View, { ...viewProps, visible: resolvedVisible, children: /* @__PURE__ */ jsxs(View, { direction: "row", width: "100%", height: "100%", gap: 0, padding: 0, children: [
15958
15025
  /* @__PURE__ */ jsxs(View, { flex: 1, height: "100%", direction: "column", children: [
15959
15026
  /* @__PURE__ */ jsxs(
15960
15027
  View,
@@ -16373,6 +15440,395 @@ function useIconPreload(type, loader) {
16373
15440
  }, [type, loader]);
16374
15441
  return svg !== null;
16375
15442
  }
15443
+ function joystickThemeFactory(joystickTheme, radius) {
15444
+ function createNeonBase(radius2, color = 65280) {
15445
+ return /* @__PURE__ */ jsx(
15446
+ Graphics,
15447
+ {
15448
+ onDraw: (g) => {
15449
+ g.fillStyle(color, 0.1);
15450
+ g.fillCircle(0, 0, radius2 + 10);
15451
+ g.fillStyle(0, 0.4);
15452
+ g.fillCircle(0, 0, radius2);
15453
+ g.lineStyle(3, color, 1);
15454
+ g.strokeCircle(0, 0, radius2);
15455
+ g.lineStyle(1, color, 0.5);
15456
+ g.strokeCircle(0, 0, radius2 - 5);
15457
+ for (let i = 0; i < 4; i++) {
15458
+ const angle = i * 90 * Math.PI / 180;
15459
+ const x1 = Math.cos(angle) * (radius2 - 15);
15460
+ const y1 = Math.sin(angle) * (radius2 - 15);
15461
+ const x2 = Math.cos(angle) * (radius2 - 5);
15462
+ const y2 = Math.sin(angle) * (radius2 - 5);
15463
+ g.lineStyle(2, color, 0.7);
15464
+ g.lineBetween(x1, y1, x2, y2);
15465
+ }
15466
+ }
15467
+ }
15468
+ );
15469
+ }
15470
+ function createNeonThumb(radius2, color = 65280) {
15471
+ const r = radius2 * 0.4;
15472
+ return /* @__PURE__ */ jsx(
15473
+ Graphics,
15474
+ {
15475
+ onDraw: (g) => {
15476
+ g.fillStyle(color, 0.2);
15477
+ g.fillCircle(0, 0, r + 5);
15478
+ g.fillStyle(color, 0.8);
15479
+ g.fillCircle(0, 0, r);
15480
+ g.lineStyle(2, color, 1);
15481
+ g.strokeCircle(0, 0, r);
15482
+ g.lineStyle(2, 0, 0.8);
15483
+ g.moveTo(0, -r * 0.6);
15484
+ g.lineTo(0, r * 0.6);
15485
+ g.moveTo(-r * 0.6, 0);
15486
+ g.lineTo(r * 0.6, 0);
15487
+ g.strokePath();
15488
+ }
15489
+ }
15490
+ );
15491
+ }
15492
+ function createTargetBase(radius2, tint2 = 16711680) {
15493
+ return /* @__PURE__ */ jsx(
15494
+ Graphics,
15495
+ {
15496
+ onDraw: (g) => {
15497
+ g.fillStyle(0, 0.3);
15498
+ g.fillCircle(0, 0, radius2);
15499
+ for (let i = 0; i < 3; i++) {
15500
+ const r = radius2 - i * 20;
15501
+ g.lineStyle(2, tint2, 0.6 - i * 0.15);
15502
+ g.strokeCircle(0, 0, r);
15503
+ }
15504
+ g.lineStyle(1, tint2, 0.5);
15505
+ g.moveTo(-radius2, 0);
15506
+ g.lineTo(radius2, 0);
15507
+ g.moveTo(0, -radius2);
15508
+ g.lineTo(0, radius2);
15509
+ g.strokePath();
15510
+ g.fillStyle(tint2, 0.8);
15511
+ g.fillCircle(0, 0, 5);
15512
+ }
15513
+ }
15514
+ );
15515
+ }
15516
+ function createTargetThumb(radius2, tint2 = 16711680) {
15517
+ const r = radius2 * 0.35;
15518
+ return /* @__PURE__ */ jsx(
15519
+ Graphics,
15520
+ {
15521
+ onDraw: (g) => {
15522
+ g.fillStyle(tint2, 0.7);
15523
+ g.fillCircle(0, 0, r);
15524
+ g.fillStyle(16777215, 0.9);
15525
+ g.fillCircle(0, 0, r * 0.5);
15526
+ g.fillStyle(tint2, 1);
15527
+ g.fillCircle(0, 0, r * 0.2);
15528
+ g.lineStyle(3, tint2, 1);
15529
+ g.beginPath();
15530
+ g.moveTo(0, -r);
15531
+ g.lineTo(r * 0.3, -r * 0.6);
15532
+ g.lineTo(-r * 0.3, -r * 0.6);
15533
+ g.closePath();
15534
+ g.fillPath();
15535
+ }
15536
+ }
15537
+ );
15538
+ }
15539
+ function createGlassBase(radius2, tint2 = 16777215) {
15540
+ return /* @__PURE__ */ jsx(
15541
+ Graphics,
15542
+ {
15543
+ onDraw: (g) => {
15544
+ g.fillStyle(tint2, 0.15);
15545
+ g.fillCircle(0, 0, radius2);
15546
+ g.fillStyle(tint2, 0.3);
15547
+ g.fillCircle(-radius2 * 0.3, -radius2 * 0.3, radius2 * 0.4);
15548
+ g.lineStyle(2, tint2, 0.5);
15549
+ g.strokeCircle(0, 0, radius2);
15550
+ g.lineStyle(1, tint2, 0.3);
15551
+ g.strokeCircle(0, 0, radius2 - 3);
15552
+ }
15553
+ }
15554
+ );
15555
+ }
15556
+ function createGlassThumb(radius2, tint2 = 16777215) {
15557
+ const r = radius2 * 0.4;
15558
+ return /* @__PURE__ */ jsx(
15559
+ Graphics,
15560
+ {
15561
+ onDraw: (g) => {
15562
+ g.fillStyle(0, 0.2);
15563
+ g.fillCircle(r * 0.1, r * 0.1, r);
15564
+ g.fillStyle(tint2, 0.4);
15565
+ g.fillCircle(0, 0, r);
15566
+ g.fillStyle(tint2, 0.6);
15567
+ g.fillCircle(-r * 0.3, -r * 0.3, r * 0.4);
15568
+ g.lineStyle(2, tint2, 0.7);
15569
+ g.strokeCircle(0, 0, r);
15570
+ }
15571
+ }
15572
+ );
15573
+ }
15574
+ function createMilitaryBase(radius2, tint2 = 65280) {
15575
+ return /* @__PURE__ */ jsx(
15576
+ Graphics,
15577
+ {
15578
+ onDraw: (g) => {
15579
+ g.fillStyle(1710618, 0.8);
15580
+ g.fillCircle(0, 0, radius2);
15581
+ g.lineStyle(1, tint2, 0.3);
15582
+ const step = 20;
15583
+ for (let i = -radius2; i <= radius2; i += step) {
15584
+ g.moveTo(-radius2, i);
15585
+ g.lineTo(radius2, i);
15586
+ g.moveTo(i, -radius2);
15587
+ g.lineTo(i, radius2);
15588
+ }
15589
+ g.strokePath();
15590
+ g.lineStyle(2, tint2, 0.6);
15591
+ g.strokeCircle(0, 0, radius2);
15592
+ g.strokeCircle(0, 0, radius2 * 0.66);
15593
+ g.strokeCircle(0, 0, radius2 * 0.33);
15594
+ const corners = [
15595
+ { x: -radius2 * 0.7, y: -radius2 * 0.7 },
15596
+ { x: radius2 * 0.7, y: -radius2 * 0.7 },
15597
+ { x: -radius2 * 0.7, y: radius2 * 0.7 },
15598
+ { x: radius2 * 0.7, y: radius2 * 0.7 }
15599
+ ];
15600
+ g.lineStyle(3, tint2, 0.8);
15601
+ corners.forEach(({ x, y }) => {
15602
+ g.moveTo(x - 10, y);
15603
+ g.lineTo(x + 10, y);
15604
+ g.moveTo(x, y - 10);
15605
+ g.lineTo(x, y + 10);
15606
+ });
15607
+ g.strokePath();
15608
+ }
15609
+ }
15610
+ );
15611
+ }
15612
+ function createMilitaryThumb(radius2, tint2 = 65280) {
15613
+ const r = radius2 * 0.3;
15614
+ return /* @__PURE__ */ jsx(
15615
+ Graphics,
15616
+ {
15617
+ onDraw: (g) => {
15618
+ g.fillStyle(tint2, 0.9);
15619
+ g.fillCircle(0, 0, r);
15620
+ g.fillStyle(0, 1);
15621
+ g.beginPath();
15622
+ g.moveTo(0, -r);
15623
+ g.lineTo(r * 0.5, r * 0.3);
15624
+ g.lineTo(-r * 0.5, r * 0.3);
15625
+ g.closePath();
15626
+ g.fillPath();
15627
+ g.lineStyle(2, 0, 0.8);
15628
+ g.strokeCircle(0, 0, r);
15629
+ }
15630
+ }
15631
+ );
15632
+ }
15633
+ function createDefaultBase(radius2, tint2 = 65280) {
15634
+ const size = { width: radius2 * 2 };
15635
+ return /* @__PURE__ */ jsx(
15636
+ Graphics,
15637
+ {
15638
+ onDraw: (g) => {
15639
+ g.fillStyle(0, 0.25);
15640
+ g.lineStyle(1, tint2);
15641
+ g.fillCircle(0, 0, size.width / 2);
15642
+ g.strokeCircle(0, 0, size.width / 2);
15643
+ }
15644
+ }
15645
+ );
15646
+ }
15647
+ function createDefaultThumb(radius2, tint2 = 65280) {
15648
+ const size = { width: radius2 * 2 };
15649
+ return /* @__PURE__ */ jsx(
15650
+ Graphics,
15651
+ {
15652
+ onDraw: (g) => {
15653
+ const r = size.width * 0.2;
15654
+ g.lineStyle(2, 0, 1);
15655
+ g.moveTo(0, -r);
15656
+ g.lineTo(0, r);
15657
+ g.moveTo(-r, 0);
15658
+ g.lineTo(r, 0);
15659
+ g.strokePath();
15660
+ g.lineStyle(2, tint2, 0.75);
15661
+ g.strokeCircle(0, 0, r * 1.1);
15662
+ }
15663
+ }
15664
+ );
15665
+ }
15666
+ const theme = joystickTheme != null ? joystickTheme.theme : "default";
15667
+ const tint = (joystickTheme != null ? joystickTheme.tint : 65280) ?? 65280;
15668
+ switch (theme) {
15669
+ case "neon":
15670
+ return {
15671
+ base: createNeonBase(radius, tint),
15672
+ thumb: createNeonThumb(radius, tint),
15673
+ rotateThumb: false
15674
+ };
15675
+ case "target":
15676
+ return {
15677
+ base: createTargetBase(radius, tint),
15678
+ thumb: createTargetThumb(radius, tint),
15679
+ rotateThumb: true
15680
+ };
15681
+ case "glass":
15682
+ return {
15683
+ base: createGlassBase(radius, tint),
15684
+ thumb: createGlassThumb(radius, tint),
15685
+ rotateThumb: false
15686
+ };
15687
+ case "military":
15688
+ return {
15689
+ base: createMilitaryBase(radius, tint),
15690
+ thumb: createMilitaryThumb(radius, tint),
15691
+ rotateThumb: true
15692
+ };
15693
+ case "default":
15694
+ default:
15695
+ return {
15696
+ base: createDefaultBase(radius, tint),
15697
+ thumb: createDefaultThumb(radius, tint),
15698
+ rotateThumb: false
15699
+ };
15700
+ }
15701
+ }
15702
+ function Joystick(props) {
15703
+ const outerRef = useRef(null);
15704
+ const [center, setCenter] = useState({ x: 0, y: 0 });
15705
+ const [size, setSize] = useState({ width: 0, height: 0 });
15706
+ const thumbRef = useRef(null);
15707
+ const forceExceededMinimumRef = useRef(false);
15708
+ const activeTweenRef = useRef(null);
15709
+ const isDraggingRef = useRef(false);
15710
+ const currentThumbPosRef = useRef({ x: 0, y: 0 });
15711
+ useEffect(() => {
15712
+ setTimeout(() => {
15713
+ const size2 = getLayoutSize(outerRef.current);
15714
+ console.log(`Joystick size: ${JSON.stringify(size2)}`);
15715
+ if (size2 != null) {
15716
+ const newCenter = { x: size2.width / 2, y: size2.height / 2 };
15717
+ setCenter(newCenter);
15718
+ setSize({ width: size2.width, height: size2.height });
15719
+ if (!isDraggingRef.current && !activeTweenRef.current) {
15720
+ currentThumbPosRef.current = newCenter;
15721
+ if (thumbRef.current != null) {
15722
+ thumbRef.current.setPosition(newCenter.x, newCenter.y);
15723
+ }
15724
+ }
15725
+ }
15726
+ }, 0);
15727
+ }, [outerRef]);
15728
+ const themeType = props.joystickTheme?.theme;
15729
+ const themeTint = props.joystickTheme?.tint;
15730
+ const sizeKey = `${size.width}x${size.height}`;
15731
+ const elements = useMemo(() => {
15732
+ if (props.base != null && props.thumb)
15733
+ return {
15734
+ base: props.base,
15735
+ thumb: props.thumb,
15736
+ rotateThumb: props.rotateThumb ?? false
15737
+ };
15738
+ if (size.width === 0 || size.height === 0)
15739
+ return {
15740
+ base: null,
15741
+ thumb: null,
15742
+ rotateThumb: false
15743
+ };
15744
+ const radius = Math.min(size.width, size.height) / 2;
15745
+ return joystickThemeFactory(props.joystickTheme, radius);
15746
+ }, [props.base, props.thumb, props.rotateThumb, themeType, themeTint, sizeKey]);
15747
+ const touchMove = (data) => {
15748
+ data.stopPropagation();
15749
+ if (thumbRef.current == null) return;
15750
+ if (data.state === "start") {
15751
+ forceExceededMinimumRef.current = false;
15752
+ isDraggingRef.current = true;
15753
+ }
15754
+ if (data.state === "end") {
15755
+ isDraggingRef.current = false;
15756
+ if (activeTweenRef.current) {
15757
+ activeTweenRef.current.stop();
15758
+ activeTweenRef.current = null;
15759
+ }
15760
+ if (thumbRef.current.scene) {
15761
+ activeTweenRef.current = thumbRef.current.scene.tweens.add({
15762
+ targets: thumbRef.current,
15763
+ x: center.x,
15764
+ y: center.y,
15765
+ angle: 0,
15766
+ duration: 150,
15767
+ ease: "Cubic.easeOut",
15768
+ onComplete: () => {
15769
+ activeTweenRef.current = null;
15770
+ currentThumbPosRef.current = { x: center.x, y: center.y };
15771
+ }
15772
+ });
15773
+ }
15774
+ props.onMove?.(false, 0, 0);
15775
+ return;
15776
+ }
15777
+ let offsetX = data.localX - data.width / 2 + center.x;
15778
+ let offsetY = data.localY - data.height / 2 + center.y;
15779
+ const radius = size.width / 2;
15780
+ const dx = offsetX - center.x;
15781
+ const dy = offsetY - center.y;
15782
+ const dist = Math.sqrt(dx * dx + dy * dy);
15783
+ const angle = Math.atan2(dy, dx) * (180 / Math.PI);
15784
+ const rawForce = Math.min(dist / radius, 1);
15785
+ const minForce = props.minForce ?? 0.2;
15786
+ const force = rawForce < minForce ? 0 : (rawForce - minForce) / (1 - minForce);
15787
+ if (force > 0) {
15788
+ forceExceededMinimumRef.current = true;
15789
+ }
15790
+ if (dist > radius) {
15791
+ const angleRad = Math.atan2(dy, dx);
15792
+ offsetX = center.x + Math.cos(angleRad) * radius;
15793
+ offsetY = center.y + Math.sin(angleRad) * radius;
15794
+ }
15795
+ if (activeTweenRef.current) {
15796
+ activeTweenRef.current.stop();
15797
+ activeTweenRef.current = null;
15798
+ }
15799
+ thumbRef.current.setPosition(offsetX, offsetY);
15800
+ currentThumbPosRef.current = { x: offsetX, y: offsetY };
15801
+ if (props.rotateThumb || elements.rotateThumb) {
15802
+ thumbRef.current.setAngle(angle + 90);
15803
+ }
15804
+ if (force > 0) {
15805
+ props.onMove?.(true, angle, force);
15806
+ } else {
15807
+ props.onMove?.(true, 0, 0);
15808
+ }
15809
+ };
15810
+ const handleTouch = () => {
15811
+ if (!forceExceededMinimumRef.current) {
15812
+ props.onTap?.();
15813
+ }
15814
+ };
15815
+ return /* @__PURE__ */ jsx(View, { ref: outerRef, width: props.width, height: props.height, children: /* @__PURE__ */ jsxs(
15816
+ RefOriginView,
15817
+ {
15818
+ width: props.width,
15819
+ height: props.height,
15820
+ originX: 0.5,
15821
+ originY: 0.5,
15822
+ onTouchMove: touchMove,
15823
+ onTouch: handleTouch,
15824
+ direction: "stack",
15825
+ children: [
15826
+ /* @__PURE__ */ jsx(View, { x: center.x, y: center.y, children: elements.base }),
15827
+ /* @__PURE__ */ jsx(View, { ref: thumbRef, x: currentThumbPosRef.current.x, y: currentThumbPosRef.current.y, children: elements.thumb })
15828
+ ]
15829
+ }
15830
+ ) });
15831
+ }
16376
15832
  function NineSlice(props) {
16377
15833
  const localTheme = useTheme();
16378
15834
  const { props: themed, nestedTheme } = getThemedProps("NineSlice", localTheme, props);
@@ -16572,7 +16028,13 @@ function Sidebar(props) {
16572
16028
  ...itemContainer
16573
16029
  } = itemStyle ?? {};
16574
16030
  const { textStyle: badgeTextStyle, ...badgeContainer } = badgeStyle ?? {};
16575
- const normalizeChildren = (child) => child ? Array.isArray(child) ? child : [child] : [];
16031
+ const normalizeChildren2 = (child) => {
16032
+ if (!child) return [];
16033
+ const flat = Array.isArray(child) ? child.flat(Infinity) : [child];
16034
+ return flat.filter(
16035
+ (node) => !!node && typeof node === "object" && "type" in node
16036
+ );
16037
+ };
16576
16038
  const renderTitle = (title) => {
16577
16039
  if (!title) return null;
16578
16040
  return typeof title === "string" ? /* @__PURE__ */ jsx(Text, { text: title, style: titleStyle }) : title;
@@ -16599,9 +16061,9 @@ function Sidebar(props) {
16599
16061
  const activeProps = item.active ? activeItemStyle ?? {} : {};
16600
16062
  const disabledProps = item.disabled && disabledAlpha !== void 0 ? { alpha: disabledAlpha } : {};
16601
16063
  const content = item.content ?? (item.label ? /* @__PURE__ */ jsx(Text, { text: item.label, style: itemTextStyle }) : null);
16602
- const iconNodes = normalizeChildren(item.icon ?? null);
16603
- const contentNodes2 = normalizeChildren(content);
16604
- const badgeNodes = normalizeChildren(renderBadge(item.badge));
16064
+ const iconNodes = normalizeChildren2(item.icon ?? null);
16065
+ const contentNodes2 = normalizeChildren2(content);
16066
+ const badgeNodes = normalizeChildren2(renderBadge(item.badge));
16605
16067
  const handleTouch = item.disabled ? void 0 : () => item.onSelect?.(item.key ?? key);
16606
16068
  return /* @__PURE__ */ jsx(
16607
16069
  View,
@@ -16646,7 +16108,7 @@ function Sidebar(props) {
16646
16108
  const hasSections = !!props.sections?.length;
16647
16109
  const primaryContent = sectionsContent ?? (!hasSections ? props.children : null) ?? null;
16648
16110
  const extraContent = hasSections ? props.children ?? null : null;
16649
- const contentNodes = [...normalizeChildren(primaryContent), ...normalizeChildren(extraContent)];
16111
+ const contentNodes = [...normalizeChildren2(primaryContent), ...normalizeChildren2(extraContent)];
16650
16112
  return /* @__PURE__ */ jsxs(
16651
16113
  View,
16652
16114
  {
@@ -17119,6 +16581,114 @@ function Slider(props) {
17119
16581
  function RangeSlider(props) {
17120
16582
  return /* @__PURE__ */ jsx(BaseSlider, { ...props, mode: "range" });
17121
16583
  }
16584
+ function Tab(_props) {
16585
+ return null;
16586
+ }
16587
+ function TabPanel(_props) {
16588
+ return null;
16589
+ }
16590
+ const normalizeChildren = (children) => {
16591
+ if (!children) return [];
16592
+ const flat = Array.isArray(children) ? children.flat(Infinity) : [children];
16593
+ return flat.filter(
16594
+ (child) => !!child && typeof child === "object" && "type" in child
16595
+ );
16596
+ };
16597
+ function Tabs(props) {
16598
+ const localTheme = useTheme();
16599
+ const { props: themed, nestedTheme } = getThemedProps("Tabs", localTheme, {});
16600
+ const [internalIndex, setInternalIndex] = useState(props.defaultIndex ?? 0);
16601
+ const rawIndex = props.activeIndex ?? internalIndex;
16602
+ const { tabs, panels } = useMemo(() => {
16603
+ const nodes = normalizeChildren(props.children);
16604
+ const collectedTabs = [];
16605
+ const collectedPanels = [];
16606
+ for (const node of nodes) {
16607
+ if (node.type === Tab) collectedTabs.push(node);
16608
+ if (node.type === TabPanel) collectedPanels.push(node);
16609
+ }
16610
+ return { tabs: collectedTabs, panels: collectedPanels };
16611
+ }, [props.children]);
16612
+ const panelCount = Math.min(tabs.length, panels.length);
16613
+ const safeIndex = panelCount > 0 ? Math.min(Math.max(rawIndex, 0), panelCount - 1) : 0;
16614
+ const handleSelect = (index) => {
16615
+ if (props.activeIndex === void 0) {
16616
+ setInternalIndex(index);
16617
+ }
16618
+ if (index !== safeIndex) {
16619
+ props.onChange?.(index);
16620
+ }
16621
+ };
16622
+ const tabListStyle = themed.tabListStyle ?? {};
16623
+ const tabStyle = themed.tabStyle ?? {};
16624
+ const tabActiveStyle = themed.tabActiveStyle ?? {};
16625
+ const tabDisabledStyle = themed.tabDisabledStyle ?? {};
16626
+ const panelStyle = themed.panelStyle ?? {};
16627
+ const {
16628
+ children: _children,
16629
+ activeIndex: _activeIndex,
16630
+ defaultIndex: _defaultIndex,
16631
+ onChange: _onChange,
16632
+ ...viewProps
16633
+ } = props;
16634
+ const activePanel = panels[safeIndex];
16635
+ const activePanelProps = activePanel?.props ?? {};
16636
+ const panelChildren = activePanel?.children ?? activePanelProps.children;
16637
+ const { children: _panelChildren, ...panelViewProps } = activePanelProps;
16638
+ const scrollableTabs = props.scrollableTabs ?? true;
16639
+ const tabListScrollProps = props.tabListScrollProps ?? {};
16640
+ const tabListContent = /* @__PURE__ */ jsx(View, { ...tabListStyle, direction: "row", width: scrollableTabs ? "auto" : "100%", children: tabs.slice(0, panelCount).map((tab, index) => {
16641
+ const tabProps = tab.props ?? {};
16642
+ const { disabled, onTouch, enableGestures, ...tabViewProps } = tabProps;
16643
+ const tabChildren = tab.children ?? tabProps.children;
16644
+ const isActive = index === safeIndex;
16645
+ const combinedTabStyle = {
16646
+ ...tabStyle,
16647
+ ...isActive ? tabActiveStyle : {},
16648
+ ...disabled ? tabDisabledStyle : {},
16649
+ ...tabViewProps
16650
+ };
16651
+ const tabKey = tab.__key ?? tabProps.key ?? index;
16652
+ return /* @__PURE__ */ jsx(
16653
+ View,
16654
+ {
16655
+ ...combinedTabStyle,
16656
+ enableGestures: !disabled && (enableGestures ?? true),
16657
+ onTouch: (data) => {
16658
+ if (disabled) return;
16659
+ handleSelect(index);
16660
+ onTouch?.(data);
16661
+ },
16662
+ children: tabChildren
16663
+ },
16664
+ tabKey
16665
+ );
16666
+ }) });
16667
+ const [tabHeight, setTabHeight] = useState(0);
16668
+ const [sliderHeight, setSliderHeight] = useState(0);
16669
+ const ref = useRef(null);
16670
+ useLayoutEffect(() => {
16671
+ const layout = useLayoutRect(ref);
16672
+ if (layout) setTabHeight(layout.height);
16673
+ }, [props, ref]);
16674
+ return /* @__PURE__ */ jsxs(View, { ...themed, ...viewProps, direction: "column", theme: nestedTheme, children: [
16675
+ scrollableTabs ? /* @__PURE__ */ jsx(
16676
+ ScrollView,
16677
+ {
16678
+ width: "100%",
16679
+ height: tabHeight + sliderHeight,
16680
+ showHorizontalSlider: "auto",
16681
+ showVerticalSlider: false,
16682
+ sliderSize: "nano",
16683
+ theme: nestedTheme,
16684
+ onSliderSize: (size) => setSliderHeight(size.height),
16685
+ ...tabListScrollProps,
16686
+ children: /* @__PURE__ */ jsx(View, { ref, children: tabListContent })
16687
+ }
16688
+ ) : tabListContent,
16689
+ activePanel ? /* @__PURE__ */ jsx(View, { ...panelStyle, ...panelViewProps, children: panelChildren }) : null
16690
+ ] });
16691
+ }
17122
16692
  function interpolateColor(color1, color2, progress) {
17123
16693
  const rgb1 = numberToRgb(color1);
17124
16694
  const rgb2 = numberToRgb(color2);
@@ -17250,7 +16820,7 @@ function Toggle(props) {
17250
16820
  ]
17251
16821
  }
17252
16822
  );
17253
- const labelElement = props.label && labelPosition !== "none" && /* @__PURE__ */ jsx(Text, { text: props.label, style: themed.labelStyle });
16823
+ const labelElement = props.label && labelPosition !== "none" ? /* @__PURE__ */ jsx(Text, { text: props.label, style: themed.labelStyle }) : null;
17254
16824
  if (!props.label || labelPosition === "none") {
17255
16825
  return /* @__PURE__ */ jsxs(View, { ref: containerRef, direction: "row", alignItems: "center", gap, theme: nestedTheme, children: [
17256
16826
  props.prefix,
@@ -17344,163 +16914,170 @@ function TransformOriginView({
17344
16914
  );
17345
16915
  }
17346
16916
  export {
17347
- DEFAULT_EFFECT as $,
16917
+ alpha as $,
17348
16918
  Accordion as A,
17349
16919
  Button as B,
17350
16920
  CharText as C,
17351
16921
  Dialog as D,
17352
- createTextStyleTokens as E,
17353
- registerBuiltins as F,
17354
- normalizeCornerRadius as G,
17355
- normalizeEdgeInsets as H,
16922
+ themeRegistry as E,
16923
+ normalizeGap as F,
16924
+ getChildSize as G,
16925
+ DebugLogger as H,
17356
16926
  Icon as I,
17357
- normalizeGap as J,
17358
- DOMInputElement as K,
17359
- KeyboardInputManager as L,
16927
+ Joystick as J,
16928
+ useTheme as K,
16929
+ getThemedProps as L,
17360
16930
  Modal as M,
17361
16931
  NineSlice as N,
17362
- mountJSX as O,
17363
- Portal as P,
17364
- viewportRegistry as Q,
16932
+ register as O,
16933
+ Particles as P,
16934
+ useEffect as Q,
17365
16935
  RadioButton as R,
17366
16936
  ScrollSlider as S,
17367
- Toggle as T,
17368
- getRenderContext as U,
17369
- DebugLogger as V,
16937
+ Tab as T,
16938
+ useScene as U,
16939
+ useRef as V,
17370
16940
  WrapText as W,
17371
- DevConfig as X,
17372
- DevPresets as Y,
17373
- svgToTexture as Z,
17374
- useGameObjectEffect as _,
16941
+ useCallback as X,
16942
+ mountJSX as Y,
16943
+ useState as Z,
16944
+ getPresetWithMode as _,
17375
16945
  AlertDialog as a,
17376
- nineSlicePatcher as a$,
17377
- EFFECT_REGISTRY as a0,
17378
- applyEffectByName as a1,
17379
- resolveEffect as a2,
17380
- createBounceEffect as a3,
17381
- createBreatheEffect as a4,
17382
- createFadeEffect as a5,
17383
- createFlashEffect as a6,
17384
- createFlipInEffect as a7,
17385
- createFlipOutEffect as a8,
17386
- createFloatEffect as a9,
17387
- releaseAllSVGTextures as aA,
17388
- useSVGTexture as aB,
17389
- useSVGTextures as aC,
17390
- nodeRegistry as aD,
17391
- register as aE,
17392
- host as aF,
17393
- createDefaultTheme as aG,
17394
- defaultTheme as aH,
17395
- mergeThemes as aI,
17396
- createTheme as aJ,
17397
- getThemedProps as aK,
17398
- remountAll as aL,
17399
- createElement as aM,
17400
- mount as aN,
17401
- unmount as aO,
17402
- patchVNode as aP,
17403
- unmountJSX as aQ,
17404
- Sprite as aR,
17405
- Graphics as aS,
17406
- TileSprite as aT,
17407
- Text as aU,
17408
- View as aV,
17409
- textCreator as aW,
17410
- textPatcher as aX,
17411
- viewCreator as aY,
17412
- viewPatcher as aZ,
17413
- nineSliceCreator as a_,
17414
- createJelloEffect as aa,
17415
- createNoneEffect as ab,
17416
- createPressEffect as ac,
17417
- createPulseEffect as ad,
17418
- createShakeEffect as ae,
17419
- createSlideInEffect as af,
17420
- createSlideOutEffect as ag,
17421
- createSpinEffect as ah,
17422
- createSwingEffect as ai,
17423
- createTadaEffect as aj,
17424
- createWiggleEffect as ak,
17425
- createWobbleEffect as al,
17426
- createZoomInEffect as am,
17427
- createZoomOutEffect as an,
17428
- getCurrent as ao,
17429
- withHooks as ap,
17430
- useForceRedraw as aq,
17431
- useMemo as ar,
17432
- useCallback as as,
17433
- useScene as at,
17434
- shallowEqual as au,
17435
- shouldComponentUpdate as av,
17436
- useRedraw as aw,
17437
- disposeCtx as ax,
17438
- releaseSVGTexture as ay,
17439
- releaseSVGTextures as az,
16946
+ nodeRegistry as a$,
16947
+ defaultRadiusTokens as a0,
16948
+ defaultSizeTokens as a1,
16949
+ defaultSpacingTokens as a2,
16950
+ createTextStyleTokens as a3,
16951
+ normalizeCornerRadius as a4,
16952
+ normalizeEdgeInsets as a5,
16953
+ DOMInputElement as a6,
16954
+ KeyboardInputManager as a7,
16955
+ getMountStats as a8,
16956
+ getRenderContext as a9,
16957
+ createWobbleEffect as aA,
16958
+ createZoomInEffect as aB,
16959
+ createZoomOutEffect as aC,
16960
+ getCurrent as aD,
16961
+ withHooks as aE,
16962
+ useForceRedraw as aF,
16963
+ useMemo as aG,
16964
+ useViewportSize as aH,
16965
+ getLayoutSize as aI,
16966
+ useLayoutSize as aJ,
16967
+ getLayoutProps as aK,
16968
+ getBackgroundGraphics as aL,
16969
+ useBackgroundGraphics as aM,
16970
+ getLayoutRect as aN,
16971
+ useLayoutRect as aO,
16972
+ getWorldLayoutRect as aP,
16973
+ useWorldLayoutRect as aQ,
16974
+ useLayoutEffect as aR,
16975
+ shallowEqual as aS,
16976
+ shouldComponentUpdate as aT,
16977
+ useRedraw as aU,
16978
+ disposeCtx as aV,
16979
+ releaseSVGTexture as aW,
16980
+ releaseSVGTextures as aX,
16981
+ releaseAllSVGTextures as aY,
16982
+ useSVGTexture as aZ,
16983
+ useSVGTextures as a_,
16984
+ DevConfig as aa,
16985
+ DevPresets as ab,
16986
+ svgToTexture as ac,
16987
+ useGameObjectEffect as ad,
16988
+ DEFAULT_EFFECT as ae,
16989
+ EFFECT_REGISTRY as af,
16990
+ applyEffectByName as ag,
16991
+ resolveEffect as ah,
16992
+ createBounceEffect as ai,
16993
+ createBreatheEffect as aj,
16994
+ createFadeEffect as ak,
16995
+ createFlashEffect as al,
16996
+ createFlipInEffect as am,
16997
+ createFlipOutEffect as an,
16998
+ createFloatEffect as ao,
16999
+ createJelloEffect as ap,
17000
+ createNoneEffect as aq,
17001
+ createPressEffect as ar,
17002
+ createPulseEffect as as,
17003
+ createShakeEffect as at,
17004
+ createSlideInEffect as au,
17005
+ createSlideOutEffect as av,
17006
+ createSpinEffect as aw,
17007
+ createSwingEffect as ax,
17008
+ createTadaEffect as ay,
17009
+ createWiggleEffect as az,
17440
17010
  CharTextInput as b,
17441
- spriteCreator as b0,
17442
- spritePatcher as b1,
17443
- imageCreator as b2,
17444
- imagePatcher as b3,
17445
- graphicsCreator as b4,
17446
- graphicsPatcher as b5,
17447
- tileSpriteCreator as b6,
17448
- tileSpritePatcher as b7,
17449
- portalRegistry as b8,
17450
- animatedSignal as b9,
17451
- oceanBluePreset as bA,
17452
- presets as bB,
17453
- defaultTextStyleTokens as bC,
17454
- vdom as bD,
17455
- isAnimatedSignal as ba,
17456
- unwrapSignal as bb,
17457
- DEFAULT_SPRING_CONFIG as bc,
17458
- SPRING_PRESETS as bd,
17459
- SpringPhysics as be,
17460
- useSpring as bf,
17461
- useSprings as bg,
17462
- HexColor as bh,
17463
- hexToNumber as bi,
17464
- numberToHex as bj,
17465
- numberToRgb as bk,
17466
- rgbToNumber as bl,
17467
- darken as bm,
17468
- darkenHex as bn,
17469
- hex as bo,
17470
- lighten as bp,
17471
- lightenHex as bq,
17472
- createTextStyle as br,
17473
- ensureContrast as bs,
17474
- getContrastRatio as bt,
17475
- applyDarkMode as bu,
17476
- applyLightMode as bv,
17477
- forestGreenPreset as bw,
17478
- generateColorScale as bx,
17479
- getPreset as by,
17480
- midnightPreset as bz,
17011
+ host as b0,
17012
+ createDefaultTheme as b1,
17013
+ defaultTheme as b2,
17014
+ mergeThemes as b3,
17015
+ createTheme as b4,
17016
+ remountAll as b5,
17017
+ normalizeVNodeLike as b6,
17018
+ createElement as b7,
17019
+ mount as b8,
17020
+ unmount as b9,
17021
+ getContrastRatio as bA,
17022
+ applyDarkMode as bB,
17023
+ applyLightMode as bC,
17024
+ forestGreenPreset as bD,
17025
+ generateColorScale as bE,
17026
+ getPreset as bF,
17027
+ midnightPreset as bG,
17028
+ oceanBluePreset as bH,
17029
+ presets as bI,
17030
+ defaultTextStyleTokens as bJ,
17031
+ vdom as bK,
17032
+ patchVNode as ba,
17033
+ unmountJSX as bb,
17034
+ Graphics as bc,
17035
+ Text as bd,
17036
+ View as be,
17037
+ portalRegistry as bf,
17038
+ animatedSignal as bg,
17039
+ isAnimatedSignal as bh,
17040
+ unwrapSignal as bi,
17041
+ DEFAULT_SPRING_CONFIG as bj,
17042
+ SPRING_PRESETS as bk,
17043
+ SpringPhysics as bl,
17044
+ useSpring as bm,
17045
+ useSprings as bn,
17046
+ HexColor as bo,
17047
+ hexToNumber as bp,
17048
+ numberToHex as bq,
17049
+ numberToRgb as br,
17050
+ rgbToNumber as bs,
17051
+ darken as bt,
17052
+ darkenHex as bu,
17053
+ hex as bv,
17054
+ lighten as bw,
17055
+ lightenHex as bx,
17056
+ createTextStyle as by,
17057
+ ensureContrast as bz,
17481
17058
  Divider as c,
17482
17059
  Dropdown as d,
17483
17060
  createIconComponent as e,
17484
17061
  Image$1 as f,
17485
17062
  NineSliceButton as g,
17486
- RadioGroup as h,
17487
- RefOriginView as i,
17488
- calculateSliderSize as j,
17489
- ScrollView as k,
17490
- Sidebar as l,
17491
- RangeSlider as m,
17492
- Slider as n,
17493
- TransformOriginView as o,
17494
- useRef as p,
17495
- useEffect as q,
17496
- useState as r,
17497
- useTheme as s,
17498
- themeRegistry as t,
17063
+ Portal as h,
17064
+ RadioGroup as i,
17065
+ RefOriginView as j,
17066
+ calculateSliderSize as k,
17067
+ ScrollView as l,
17068
+ Sidebar as m,
17069
+ RangeSlider as n,
17070
+ Slider as o,
17071
+ TabPanel as p,
17072
+ Tabs as q,
17073
+ Toggle as r,
17074
+ TransformOriginView as s,
17075
+ equal as t,
17499
17076
  useIconPreload as u,
17500
- getPresetWithMode as v,
17501
- alpha as w,
17502
- defaultRadiusTokens as x,
17503
- defaultSizeTokens as y,
17504
- defaultSpacingTokens as z
17077
+ viewportRegistry as v,
17078
+ parseSize as w,
17079
+ resolveSize as x,
17080
+ getGestureManager as y,
17081
+ calculateLayout as z
17505
17082
  };
17506
- //# sourceMappingURL=TransformOriginView-CzVjS16F.js.map
17083
+ //# sourceMappingURL=TransformOriginView-DCvId72M.js.map