@nice2dev/ui-graphics 1.2.0 → 1.2.2

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 (98) hide show
  1. package/CHANGELOG.md +142 -0
  2. package/dist/cjs/animation/AnimatedPerson.js +3 -1
  3. package/dist/cjs/animation/Audience.js +3 -1
  4. package/dist/cjs/animation/rig/RigPlayer.js +1 -1
  5. package/dist/cjs/animation/rig/presets.js +67 -55
  6. package/dist/cjs/animation/shapes/headwear.js +4 -1
  7. package/dist/cjs/core/NiceBrushEngine.js +8 -5
  8. package/dist/cjs/core/collaboration.js +11 -6
  9. package/dist/cjs/core/editorAsk.js +48 -0
  10. package/dist/cjs/core/i18n.js +7 -3
  11. package/dist/cjs/core/minimap.js +21 -20
  12. package/dist/cjs/core/plugins.js +1 -1
  13. package/dist/cjs/core/rtl.js +1 -1
  14. package/dist/cjs/core/theme.js +1 -1
  15. package/dist/cjs/font/NiceFontEditor.js +14 -12
  16. package/dist/cjs/game/GameAsset2dEditor.js +75 -44
  17. package/dist/cjs/nice2dev-ui-graphics.css +1 -1
  18. package/dist/cjs/photo/FilterThumb.js +3 -3
  19. package/dist/cjs/photo/NiceAITools.js +6 -4
  20. package/dist/cjs/photo/PhotoEditor.js +3 -1
  21. package/dist/cjs/photo/PhotoEditorCanvas.js +8 -6
  22. package/dist/cjs/photo/PhotoEditorLeftPanel.js +29 -29
  23. package/dist/cjs/photo/PhotoEditorToolbar.js +4 -4
  24. package/dist/cjs/photo/photoFilters.js +1 -0
  25. package/dist/cjs/pixel/PixelEditor.js +6 -3
  26. package/dist/cjs/pixel/PixelEditorCanvas.js +10 -6
  27. package/dist/cjs/pixel/PixelEditorMenuBar.js +95 -30
  28. package/dist/cjs/pixel/PixelEditorRightPanel.js +32 -24
  29. package/dist/cjs/pixel/PixelEditorStatusBar.js +12 -4
  30. package/dist/cjs/pixel/PixelEditorTimeline.js +15 -2
  31. package/dist/cjs/pixel/PixelEditorToolbar.js +12 -6
  32. package/dist/cjs/pixel/SpriteGeneratorPanel.js +28 -17
  33. package/dist/cjs/pixel/animalGeneratorPresets.js +31 -31
  34. package/dist/cjs/pixel/buildingGeneratorPresets.js +24 -24
  35. package/dist/cjs/pixel/characterGeneratorPresets.js +25 -25
  36. package/dist/cjs/pixel/usePixelEditor.js +13 -10
  37. package/dist/cjs/texture/Nice3DTexturePainter.js +16 -10
  38. package/dist/cjs/ui/NiceUIDesigner.js +17 -13
  39. package/dist/cjs/vector/NiceSvgToCode.js +7 -5
  40. package/dist/cjs/vector/VectorEditor.js +3 -2
  41. package/dist/cjs/vector/VectorEditorMenuBar.js +7 -1
  42. package/dist/cjs/vector/VectorEditorRightPanel.js +1 -1
  43. package/dist/cjs/vector/VectorEditorShapeRenderer.js +3 -1
  44. package/dist/cjs/vector/useVectorEditor.js +38 -29
  45. package/dist/cjs/vector/vectorEditorImport.js +1 -0
  46. package/dist/cjs/vector/vectorIconImport.js +1 -0
  47. package/dist/esm/animation/AnimatedPerson.js +3 -1
  48. package/dist/esm/animation/Audience.js +3 -1
  49. package/dist/esm/animation/rig/RigPlayer.js +1 -1
  50. package/dist/esm/animation/rig/presets.js +68 -56
  51. package/dist/esm/animation/shapes/headwear.js +4 -1
  52. package/dist/esm/animation/spineExport.js +1 -1
  53. package/dist/esm/core/NiceBrushEngine.js +8 -5
  54. package/dist/esm/core/collaboration.js +11 -6
  55. package/dist/esm/core/editorAsk.js +45 -0
  56. package/dist/esm/core/i18n.js +8 -4
  57. package/dist/esm/core/minimap.js +21 -20
  58. package/dist/esm/core/plugins.js +1 -1
  59. package/dist/esm/core/rtl.js +1 -1
  60. package/dist/esm/core/theme.js +1 -1
  61. package/dist/esm/font/NiceFontEditor.js +14 -12
  62. package/dist/esm/game/GameAsset2dEditor.js +75 -44
  63. package/dist/esm/nice2dev-ui-graphics.css +1 -1
  64. package/dist/esm/photo/FilterThumb.js +3 -3
  65. package/dist/esm/photo/NiceAITools.js +6 -4
  66. package/dist/esm/photo/PhotoEditor.js +3 -1
  67. package/dist/esm/photo/PhotoEditorCanvas.js +8 -6
  68. package/dist/esm/photo/PhotoEditorLeftPanel.js +29 -29
  69. package/dist/esm/photo/PhotoEditorToolbar.js +4 -4
  70. package/dist/esm/photo/photoFilters.js +1 -0
  71. package/dist/esm/pixel/PixelEditor.js +6 -3
  72. package/dist/esm/pixel/PixelEditorCanvas.js +10 -6
  73. package/dist/esm/pixel/PixelEditorMenuBar.js +95 -30
  74. package/dist/esm/pixel/PixelEditorRightPanel.js +32 -24
  75. package/dist/esm/pixel/PixelEditorStatusBar.js +12 -4
  76. package/dist/esm/pixel/PixelEditorTimeline.js +15 -2
  77. package/dist/esm/pixel/PixelEditorToolbar.js +12 -6
  78. package/dist/esm/pixel/SpriteGeneratorPanel.js +28 -17
  79. package/dist/esm/pixel/animalGeneratorPresets.js +32 -32
  80. package/dist/esm/pixel/buildingGeneratorPresets.js +25 -25
  81. package/dist/esm/pixel/characterGeneratorPresets.js +26 -26
  82. package/dist/esm/pixel/usePixelEditor.js +13 -10
  83. package/dist/esm/texture/Nice3DTexturePainter.js +16 -10
  84. package/dist/esm/ui/NiceUIDesigner.js +17 -13
  85. package/dist/esm/vector/NiceSvgToCode.js +7 -5
  86. package/dist/esm/vector/VectorEditor.js +3 -2
  87. package/dist/esm/vector/VectorEditorMenuBar.js +7 -1
  88. package/dist/esm/vector/VectorEditorRightPanel.js +1 -1
  89. package/dist/esm/vector/VectorEditorShapeRenderer.js +3 -1
  90. package/dist/esm/vector/useVectorEditor.js +38 -29
  91. package/dist/esm/vector/vectorEditorImport.js +1 -0
  92. package/dist/esm/vector/vectorIconImport.js +1 -0
  93. package/dist/types/core/LocalUI.d.ts +1 -2
  94. package/dist/types/core/editorAsk.d.ts +26 -0
  95. package/dist/types/core/i18n.d.ts +1 -17
  96. package/dist/types/pixel/usePixelEditor.d.ts +3 -0
  97. package/dist/types/vector/useVectorEditor.d.ts +2 -0
  98. package/package.json +5 -5
@@ -32,25 +32,25 @@ const ROOF_PALETTES = {
32
32
  ════════════════════════════════════════════════════════════════ */
33
33
  const _ = -1;
34
34
  /* ── Foundations ── */
35
- const FOUNDATION_STONE = spriteGeneratorCore.createPartData(16, 4, [
35
+ const FOUNDATION_STONE = /* @__PURE__ */ spriteGeneratorCore.createPartData(16, 4, [
36
36
  [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
37
37
  [0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0],
38
38
  [0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0],
39
39
  [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
40
40
  ], ['var(--nice-text-muted, #a0a0a0)', '#606060']);
41
- const FOUNDATION_BRICK = spriteGeneratorCore.createPartData(16, 4, [
41
+ const FOUNDATION_BRICK = /* @__PURE__ */ spriteGeneratorCore.createPartData(16, 4, [
42
42
  [1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0],
43
43
  [0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0],
44
44
  [1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0],
45
45
  [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
46
46
  ], ['#c06040', '#803020']);
47
- const FOUNDATION_WOOD = spriteGeneratorCore.createPartData(16, 3, [
47
+ const FOUNDATION_WOOD = /* @__PURE__ */ spriteGeneratorCore.createPartData(16, 3, [
48
48
  [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
49
49
  [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
50
50
  [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
51
51
  ], ['#c09060', '#604828']);
52
52
  /* ── Wall sections (one floor height) ── */
53
- const WALL_STONE_SECTION = spriteGeneratorCore.createPartData(16, 8, [
53
+ const WALL_STONE_SECTION = /* @__PURE__ */ spriteGeneratorCore.createPartData(16, 8, [
54
54
  [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
55
55
  [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
56
56
  [0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 2, 0, 0, 0, 0, 0],
@@ -60,7 +60,7 @@ const WALL_STONE_SECTION = spriteGeneratorCore.createPartData(16, 8, [
60
60
  [0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0],
61
61
  [0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 2, 0],
62
62
  ], ['var(--nice-text-muted, #a0a0a0)', 'var(--nice-text-secondary, #808080)', '#606060']);
63
- const WALL_BRICK_SECTION = spriteGeneratorCore.createPartData(16, 8, [
63
+ const WALL_BRICK_SECTION = /* @__PURE__ */ spriteGeneratorCore.createPartData(16, 8, [
64
64
  [2, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0],
65
65
  [0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 0],
66
66
  [2, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0],
@@ -70,7 +70,7 @@ const WALL_BRICK_SECTION = spriteGeneratorCore.createPartData(16, 8, [
70
70
  [2, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0],
71
71
  [0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 0],
72
72
  ], ['#c06040', '#a04830', '#803020']);
73
- const WALL_WOOD_SECTION = spriteGeneratorCore.createPartData(16, 8, [
73
+ const WALL_WOOD_SECTION = /* @__PURE__ */ spriteGeneratorCore.createPartData(16, 8, [
74
74
  [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
75
75
  [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
76
76
  [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
@@ -80,7 +80,7 @@ const WALL_WOOD_SECTION = spriteGeneratorCore.createPartData(16, 8, [
80
80
  [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
81
81
  [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
82
82
  ], ['#c09060', '#806038']);
83
- const WALL_HALFTIMBER_SECTION = spriteGeneratorCore.createPartData(16, 8, [
83
+ const WALL_HALFTIMBER_SECTION = /* @__PURE__ */ spriteGeneratorCore.createPartData(16, 8, [
84
84
  [2, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 2],
85
85
  [2, 0, 0, 0, 0, 0, 2, 0, 0, 2, 0, 0, 0, 0, 0, 2],
86
86
  [2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2],
@@ -91,7 +91,7 @@ const WALL_HALFTIMBER_SECTION = spriteGeneratorCore.createPartData(16, 8, [
91
91
  [2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2],
92
92
  ], ['#f0e8d0', '#e0d8c0', '#806038']);
93
93
  /* ── Roofs ── */
94
- const ROOF_TRIANGLE = spriteGeneratorCore.createPartData(20, 8, [
94
+ const ROOF_TRIANGLE = /* @__PURE__ */ spriteGeneratorCore.createPartData(20, 8, [
95
95
  [_, _, _, _, _, _, _, _, _, 0, 0, _, _, _, _, _, _, _, _, _],
96
96
  [_, _, _, _, _, _, _, _, 0, 1, 1, 0, _, _, _, _, _, _, _, _],
97
97
  [_, _, _, _, _, _, _, 0, 1, 1, 1, 1, 0, _, _, _, _, _, _, _],
@@ -101,13 +101,13 @@ const ROOF_TRIANGLE = spriteGeneratorCore.createPartData(20, 8, [
101
101
  [_, _, _, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, _, _, _],
102
102
  [_, _, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, _, _],
103
103
  ], ['#c04030', '#a03020', '#602018']);
104
- const ROOF_FLAT = spriteGeneratorCore.createPartData(18, 4, [
104
+ const ROOF_FLAT = /* @__PURE__ */ spriteGeneratorCore.createPartData(18, 4, [
105
105
  [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
106
106
  [0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0],
107
107
  [0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0],
108
108
  [2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2],
109
109
  ], ['#505058', '#404048', '#303038']);
110
- const ROOF_PAGODA = spriteGeneratorCore.createPartData(22, 6, [
110
+ const ROOF_PAGODA = /* @__PURE__ */ spriteGeneratorCore.createPartData(22, 6, [
111
111
  [_, _, _, _, _, _, _, _, _, _, 0, 0, _, _, _, _, _, _, _, _, _, _],
112
112
  [_, _, _, _, _, _, _, _, 0, 0, 1, 1, 0, 0, _, _, _, _, _, _, _, _],
113
113
  [_, _, _, _, _, _, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, _, _, _, _, _, _],
@@ -115,7 +115,7 @@ const ROOF_PAGODA = spriteGeneratorCore.createPartData(22, 6, [
115
115
  [_, _, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, _, _],
116
116
  [0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0],
117
117
  ], ['#c04030', '#a03020', '#602018']);
118
- const ROOF_DOME = spriteGeneratorCore.createPartData(18, 8, [
118
+ const ROOF_DOME = /* @__PURE__ */ spriteGeneratorCore.createPartData(18, 8, [
119
119
  [_, _, _, _, _, _, _, 0, 0, 0, 0, _, _, _, _, _, _, _],
120
120
  [_, _, _, _, _, 0, 0, 1, 1, 1, 1, 0, 0, _, _, _, _, _],
121
121
  [_, _, _, _, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, _, _, _, _],
@@ -126,7 +126,7 @@ const ROOF_DOME = spriteGeneratorCore.createPartData(18, 8, [
126
126
  [0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0],
127
127
  ], ['#4060b0', '#304890', '#203870']);
128
128
  /* ── Doors ── */
129
- const DOOR_WOOD = spriteGeneratorCore.createPartData(4, 6, [
129
+ const DOOR_WOOD = /* @__PURE__ */ spriteGeneratorCore.createPartData(4, 6, [
130
130
  [_, 0, 0, _],
131
131
  [0, 1, 1, 0],
132
132
  [0, 1, 1, 0],
@@ -134,7 +134,7 @@ const DOOR_WOOD = spriteGeneratorCore.createPartData(4, 6, [
134
134
  [0, 1, 1, 0],
135
135
  [0, 1, 1, 0],
136
136
  ], ['#604828', '#c09060', '#f0d060']);
137
- const DOOR_ARCH = spriteGeneratorCore.createPartData(6, 8, [
137
+ const DOOR_ARCH = /* @__PURE__ */ spriteGeneratorCore.createPartData(6, 8, [
138
138
  [_, _, 0, 0, _, _],
139
139
  [_, 0, 1, 1, 0, _],
140
140
  [0, 1, 1, 1, 1, 0],
@@ -144,7 +144,7 @@ const DOOR_ARCH = spriteGeneratorCore.createPartData(6, 8, [
144
144
  [0, 1, 1, 1, 1, 0],
145
145
  [0, 1, 1, 1, 1, 0],
146
146
  ], ['#604828', '#a07848', '#f0d060']);
147
- const DOOR_DOUBLE = spriteGeneratorCore.createPartData(8, 7, [
147
+ const DOOR_DOUBLE = /* @__PURE__ */ spriteGeneratorCore.createPartData(8, 7, [
148
148
  [_, 0, 0, 0, 0, 0, 0, _],
149
149
  [0, 1, 1, 0, 0, 1, 1, 0],
150
150
  [0, 1, 1, 0, 0, 1, 1, 0],
@@ -154,33 +154,33 @@ const DOOR_DOUBLE = spriteGeneratorCore.createPartData(8, 7, [
154
154
  [0, 0, 0, 0, 0, 0, 0, 0],
155
155
  ], ['#604828', '#c09060', '#f0d060']);
156
156
  /* ── Windows ── */
157
- const WINDOW_SIMPLE = spriteGeneratorCore.createPartData(4, 4, [
157
+ const WINDOW_SIMPLE = /* @__PURE__ */ spriteGeneratorCore.createPartData(4, 4, [
158
158
  [0, 0, 0, 0],
159
159
  [0, 1, 1, 0],
160
160
  [0, 1, 1, 0],
161
161
  [0, 0, 0, 0],
162
162
  ], ['var(--nice-border, #404040)', '#88c8ff']);
163
- const WINDOW_CROSS = spriteGeneratorCore.createPartData(4, 4, [
163
+ const WINDOW_CROSS = /* @__PURE__ */ spriteGeneratorCore.createPartData(4, 4, [
164
164
  [0, 0, 0, 0],
165
165
  [0, 1, 0, 1],
166
166
  [0, 0, 0, 0],
167
167
  [0, 1, 0, 1],
168
168
  ], ['var(--nice-border, #404040)', '#88c8ff']);
169
- const WINDOW_ARCH = spriteGeneratorCore.createPartData(4, 5, [
169
+ const WINDOW_ARCH = /* @__PURE__ */ spriteGeneratorCore.createPartData(4, 5, [
170
170
  [_, 0, 0, _],
171
171
  [0, 1, 1, 0],
172
172
  [0, 1, 1, 0],
173
173
  [0, 0, 0, 0],
174
174
  [0, 1, 1, 0],
175
175
  ], ['var(--nice-border, #404040)', '#88c8ff']);
176
- const WINDOW_ROUND = spriteGeneratorCore.createPartData(4, 4, [
176
+ const WINDOW_ROUND = /* @__PURE__ */ spriteGeneratorCore.createPartData(4, 4, [
177
177
  [_, 0, 0, _],
178
178
  [0, 1, 1, 0],
179
179
  [0, 1, 1, 0],
180
180
  [_, 0, 0, _],
181
181
  ], ['var(--nice-border, #404040)', '#88c8ff']);
182
182
  /* ── Chimneys ── */
183
- const CHIMNEY_BRICK = spriteGeneratorCore.createPartData(4, 6, [
183
+ const CHIMNEY_BRICK = /* @__PURE__ */ spriteGeneratorCore.createPartData(4, 6, [
184
184
  [_, 2, 2, _],
185
185
  [0, 0, 0, 0],
186
186
  [0, 1, 1, 0],
@@ -188,7 +188,7 @@ const CHIMNEY_BRICK = spriteGeneratorCore.createPartData(4, 6, [
188
188
  [0, 1, 1, 0],
189
189
  [0, 0, 0, 0],
190
190
  ], ['#c06040', '#a04830', '#606060']);
191
- const CHIMNEY_STONE = spriteGeneratorCore.createPartData(3, 5, [
191
+ const CHIMNEY_STONE = /* @__PURE__ */ spriteGeneratorCore.createPartData(3, 5, [
192
192
  [_, 2, _],
193
193
  [0, 0, 0],
194
194
  [0, 1, 0],
@@ -196,12 +196,12 @@ const CHIMNEY_STONE = spriteGeneratorCore.createPartData(3, 5, [
196
196
  [0, 0, 0],
197
197
  ], ['var(--nice-text-secondary, #808080)', 'var(--nice-text-muted, #a0a0a0)', '#505050']);
198
198
  /* ── Decorations ── */
199
- const BALCONY = spriteGeneratorCore.createPartData(8, 3, [
199
+ const BALCONY = /* @__PURE__ */ spriteGeneratorCore.createPartData(8, 3, [
200
200
  [0, 0, 0, 0, 0, 0, 0, 0],
201
201
  [0, _, 0, _, _, 0, _, 0],
202
202
  [0, 0, 0, 0, 0, 0, 0, 0],
203
203
  ], ['var(--nice-text-secondary, #808080)']);
204
- const BANNER = spriteGeneratorCore.createPartData(4, 6, [
204
+ const BANNER = /* @__PURE__ */ spriteGeneratorCore.createPartData(4, 6, [
205
205
  [_, 0, 0, _],
206
206
  [_, 1, 1, _],
207
207
  [_, 1, 1, _],
@@ -209,13 +209,13 @@ const BANNER = spriteGeneratorCore.createPartData(4, 6, [
209
209
  [_, 1, 1, _],
210
210
  [_, _, 1, _],
211
211
  ], ['#806038', '#d04040']);
212
- const TOWER_TOP = spriteGeneratorCore.createPartData(8, 4, [
212
+ const TOWER_TOP = /* @__PURE__ */ spriteGeneratorCore.createPartData(8, 4, [
213
213
  [0, _, 0, _, 0, _, 0, _],
214
214
  [0, 0, 0, 0, 0, 0, 0, 0],
215
215
  [0, 1, 1, 1, 1, 1, 1, 0],
216
216
  [0, 1, 1, 1, 1, 1, 1, 0],
217
217
  ], ['var(--nice-text-secondary, #808080)', 'var(--nice-text-muted, #a0a0a0)']);
218
- const SHOP_AWNING = spriteGeneratorCore.createPartData(14, 4, [
218
+ const SHOP_AWNING = /* @__PURE__ */ spriteGeneratorCore.createPartData(14, 4, [
219
219
  [_, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, _],
220
220
  [0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1],
221
221
  [_, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, _],
@@ -49,7 +49,7 @@ const CLOTHING_PALETTES = {
49
49
  16×16 CHARACTER PARTS — HEADS
50
50
  ════════════════════════════════════════════════════════════════ */
51
51
  const _ = -1; // transparent shorthand
52
- const HEAD_ROUND_S = spriteGeneratorCore.createPartData(8, 8, [
52
+ const HEAD_ROUND_S = /* @__PURE__ */ spriteGeneratorCore.createPartData(8, 8, [
53
53
  [_, _, 1, 1, 1, 1, _, _],
54
54
  [_, 1, 0, 0, 0, 0, 1, _],
55
55
  [1, 0, 0, 0, 0, 0, 0, 1],
@@ -59,7 +59,7 @@ const HEAD_ROUND_S = spriteGeneratorCore.createPartData(8, 8, [
59
59
  [_, 1, 0, 0, 0, 0, 1, _],
60
60
  [_, _, 1, 1, 1, 1, _, _],
61
61
  ], ['var(--nice-warning-bg, #ffecd2)', '#c07848', '#e05050', '#2a2a4e']);
62
- const HEAD_ROUND_E = spriteGeneratorCore.createPartData(7, 8, [
62
+ const HEAD_ROUND_E = /* @__PURE__ */ spriteGeneratorCore.createPartData(7, 8, [
63
63
  [_, _, 1, 1, 1, _, _],
64
64
  [_, 1, 0, 0, 0, 1, _],
65
65
  [1, 0, 0, 0, 0, 0, 1],
@@ -69,7 +69,7 @@ const HEAD_ROUND_E = spriteGeneratorCore.createPartData(7, 8, [
69
69
  [_, 1, 0, 0, 0, 1, _],
70
70
  [_, _, 1, 1, 1, _, _],
71
71
  ], ['var(--nice-warning-bg, #ffecd2)', '#c07848', '#e05050', '#2a2a4e']);
72
- const HEAD_ROUND_N = spriteGeneratorCore.createPartData(8, 8, [
72
+ const HEAD_ROUND_N = /* @__PURE__ */ spriteGeneratorCore.createPartData(8, 8, [
73
73
  [_, _, 1, 1, 1, 1, _, _],
74
74
  [_, 1, 0, 0, 0, 0, 1, _],
75
75
  [1, 0, 0, 0, 0, 0, 0, 1],
@@ -79,7 +79,7 @@ const HEAD_ROUND_N = spriteGeneratorCore.createPartData(8, 8, [
79
79
  [_, 1, 0, 0, 0, 0, 1, _],
80
80
  [_, _, 1, 1, 1, 1, _, _],
81
81
  ], ['var(--nice-warning-bg, #ffecd2)', '#c07848', '#e05050', '#2a2a4e']);
82
- const HEAD_SQUARE_S = spriteGeneratorCore.createPartData(8, 7, [
82
+ const HEAD_SQUARE_S = /* @__PURE__ */ spriteGeneratorCore.createPartData(8, 7, [
83
83
  [_, 1, 1, 1, 1, 1, 1, _],
84
84
  [1, 0, 0, 0, 0, 0, 0, 1],
85
85
  [1, 0, 3, 0, 0, 3, 0, 1],
@@ -88,7 +88,7 @@ const HEAD_SQUARE_S = spriteGeneratorCore.createPartData(8, 7, [
88
88
  [1, 0, 0, 0, 0, 0, 0, 1],
89
89
  [_, 1, 1, 1, 1, 1, 1, _],
90
90
  ], ['var(--nice-warning-bg, #ffecd2)', '#c07848', '#e05050', '#2a2a4e']);
91
- const HEAD_CHIBI_S = spriteGeneratorCore.createPartData(10, 10, [
91
+ const HEAD_CHIBI_S = /* @__PURE__ */ spriteGeneratorCore.createPartData(10, 10, [
92
92
  [_, _, _, 1, 1, 1, 1, _, _, _],
93
93
  [_, _, 1, 0, 0, 0, 0, 1, _, _],
94
94
  [_, 1, 0, 0, 0, 0, 0, 0, 1, _],
@@ -101,13 +101,13 @@ const HEAD_CHIBI_S = spriteGeneratorCore.createPartData(10, 10, [
101
101
  [_, _, 1, 1, 1, 1, 1, 1, _, _],
102
102
  ], ['var(--nice-warning-bg, #ffecd2)', '#c07848', '#e05050', '#2a2a4e']);
103
103
  /* ── HAIR ── */
104
- const HAIR_SHORT_S = spriteGeneratorCore.createPartData(8, 4, [
104
+ const HAIR_SHORT_S = /* @__PURE__ */ spriteGeneratorCore.createPartData(8, 4, [
105
105
  [_, _, 0, 0, 0, 0, _, _],
106
106
  [_, 0, 0, 0, 0, 0, 0, _],
107
107
  [0, 0, 1, 1, 1, 1, 0, 0],
108
108
  [0, 1, _, _, _, _, 1, 0],
109
109
  ], ['#4a3508', '#6b4e0a']);
110
- const HAIR_LONG_S = spriteGeneratorCore.createPartData(10, 10, [
110
+ const HAIR_LONG_S = /* @__PURE__ */ spriteGeneratorCore.createPartData(10, 10, [
111
111
  [_, _, _, 0, 0, 0, 0, _, _, _],
112
112
  [_, _, 0, 0, 0, 0, 0, 0, _, _],
113
113
  [_, 0, 0, 1, 1, 1, 1, 0, 0, _],
@@ -119,7 +119,7 @@ const HAIR_LONG_S = spriteGeneratorCore.createPartData(10, 10, [
119
119
  [_, 0, _, _, _, _, _, _, 0, _],
120
120
  [_, 0, 0, _, _, _, _, 0, 0, _],
121
121
  ], ['#4a3508', '#6b4e0a']);
122
- const HAIR_MOHAWK_S = spriteGeneratorCore.createPartData(8, 6, [
122
+ const HAIR_MOHAWK_S = /* @__PURE__ */ spriteGeneratorCore.createPartData(8, 6, [
123
123
  [_, _, _, 0, 0, _, _, _],
124
124
  [_, _, 0, 0, 0, 0, _, _],
125
125
  [_, _, 0, 0, 0, 0, _, _],
@@ -127,7 +127,7 @@ const HAIR_MOHAWK_S = spriteGeneratorCore.createPartData(8, 6, [
127
127
  [_, 0, 1, _, _, 1, 0, _],
128
128
  [0, 1, _, _, _, _, 1, 0],
129
129
  ], ['#d03020', '#a02018']);
130
- const HAIR_PONYTAIL_S = spriteGeneratorCore.createPartData(10, 8, [
130
+ const HAIR_PONYTAIL_S = /* @__PURE__ */ spriteGeneratorCore.createPartData(10, 8, [
131
131
  [_, _, _, 0, 0, 0, 0, _, _, _],
132
132
  [_, _, 0, 0, 0, 0, 0, 0, _, _],
133
133
  [_, 0, 0, 1, 1, 1, 1, 0, 0, _],
@@ -137,7 +137,7 @@ const HAIR_PONYTAIL_S = spriteGeneratorCore.createPartData(10, 8, [
137
137
  [_, _, _, _, _, _, _, _, _, 0],
138
138
  [_, _, _, _, _, _, _, _, 0, _],
139
139
  ], ['#f0d060', '#d0b040']);
140
- const HAIR_SPIKY_S = spriteGeneratorCore.createPartData(10, 6, [
140
+ const HAIR_SPIKY_S = /* @__PURE__ */ spriteGeneratorCore.createPartData(10, 6, [
141
141
  [_, 0, _, _, 0, _, 0, _, _, _],
142
142
  [_, 0, 0, 0, 0, 0, 0, 0, _, _],
143
143
  [0, 0, 0, 0, 0, 0, 0, 0, 0, _],
@@ -146,7 +146,7 @@ const HAIR_SPIKY_S = spriteGeneratorCore.createPartData(10, 6, [
146
146
  [_, _, _, _, _, _, _, _, _, _],
147
147
  ], ['var(--nice-bg, #1a1a2e)', '#101020']);
148
148
  /* ── TORSOS ── */
149
- const TORSO_BASIC_S = spriteGeneratorCore.createPartData(8, 6, [
149
+ const TORSO_BASIC_S = /* @__PURE__ */ spriteGeneratorCore.createPartData(8, 6, [
150
150
  [_, _, 1, 1, 1, 1, _, _],
151
151
  [_, 1, 0, 0, 0, 0, 1, _],
152
152
  [1, 0, 0, 0, 0, 0, 0, 1],
@@ -154,7 +154,7 @@ const TORSO_BASIC_S = spriteGeneratorCore.createPartData(8, 6, [
154
154
  [_, 1, 0, 0, 0, 0, 1, _],
155
155
  [_, _, 1, 1, 1, 1, _, _],
156
156
  ], ['#4060d0', '#3040b0']);
157
- const TORSO_ARMOR_S = spriteGeneratorCore.createPartData(10, 7, [
157
+ const TORSO_ARMOR_S = /* @__PURE__ */ spriteGeneratorCore.createPartData(10, 7, [
158
158
  [_, _, _, 1, 1, 1, 1, _, _, _],
159
159
  [_, _, 1, 0, 2, 2, 0, 1, _, _],
160
160
  [_, 1, 0, 0, 2, 2, 0, 0, 1, _],
@@ -163,7 +163,7 @@ const TORSO_ARMOR_S = spriteGeneratorCore.createPartData(10, 7, [
163
163
  [_, 1, 0, 0, 0, 0, 0, 0, 1, _],
164
164
  [_, _, 1, 1, 1, 1, 1, 1, _, _],
165
165
  ], ['var(--nice-border, #c0c0c8)', '#909098', '#f0d060']);
166
- const TORSO_ROBE_S = spriteGeneratorCore.createPartData(10, 10, [
166
+ const TORSO_ROBE_S = /* @__PURE__ */ spriteGeneratorCore.createPartData(10, 10, [
167
167
  [_, _, _, 1, 1, 1, 1, _, _, _],
168
168
  [_, _, 1, 0, 0, 0, 0, 1, _, _],
169
169
  [_, 1, 0, 0, 2, 2, 0, 0, 1, _],
@@ -176,14 +176,14 @@ const TORSO_ROBE_S = spriteGeneratorCore.createPartData(10, 10, [
176
176
  [_, _, _, 1, 1, 1, 1, _, _, _],
177
177
  ], ['#8020a0', '#601080', '#f0d060']);
178
178
  /* ── ARMS ── */
179
- const ARM_BASIC_S = spriteGeneratorCore.createPartData(3, 5, [
179
+ const ARM_BASIC_S = /* @__PURE__ */ spriteGeneratorCore.createPartData(3, 5, [
180
180
  [_, 0, _],
181
181
  [0, 0, 1],
182
182
  [0, 0, 1],
183
183
  [0, 0, 1],
184
184
  [_, 0, _],
185
185
  ], ['var(--nice-warning-bg, #ffecd2)', '#c07848']);
186
- const ARM_ARMORED_S = spriteGeneratorCore.createPartData(4, 5, [
186
+ const ARM_ARMORED_S = /* @__PURE__ */ spriteGeneratorCore.createPartData(4, 5, [
187
187
  [_, 0, 1, _],
188
188
  [0, 0, 0, 1],
189
189
  [0, 0, 0, 1],
@@ -191,14 +191,14 @@ const ARM_ARMORED_S = spriteGeneratorCore.createPartData(4, 5, [
191
191
  [_, 0, 1, _],
192
192
  ], ['var(--nice-border, #c0c0c8)', '#909098']);
193
193
  /* ── LEGS ── */
194
- const LEG_BASIC_S = spriteGeneratorCore.createPartData(3, 5, [
194
+ const LEG_BASIC_S = /* @__PURE__ */ spriteGeneratorCore.createPartData(3, 5, [
195
195
  [_, 0, _],
196
196
  [0, 0, 1],
197
197
  [0, 0, 1],
198
198
  [0, 0, 1],
199
199
  [0, 1, 1],
200
200
  ], ['#4060d0', '#3040b0']);
201
- const LEG_BOOT_S = spriteGeneratorCore.createPartData(4, 5, [
201
+ const LEG_BOOT_S = /* @__PURE__ */ spriteGeneratorCore.createPartData(4, 5, [
202
202
  [_, 0, 0, _],
203
203
  [_, 0, 0, _],
204
204
  [_, 0, 0, _],
@@ -206,7 +206,7 @@ const LEG_BOOT_S = spriteGeneratorCore.createPartData(4, 5, [
206
206
  [0, 0, 0, 1],
207
207
  ], ['#b08060', '#906840']);
208
208
  /* ── HATS ── */
209
- const HAT_WIZARD_S = spriteGeneratorCore.createPartData(10, 8, [
209
+ const HAT_WIZARD_S = /* @__PURE__ */ spriteGeneratorCore.createPartData(10, 8, [
210
210
  [_, _, _, _, 0, _, _, _, _, _],
211
211
  [_, _, _, 0, 0, 0, _, _, _, _],
212
212
  [_, _, 0, 0, 0, 0, 0, _, _, _],
@@ -216,7 +216,7 @@ const HAT_WIZARD_S = spriteGeneratorCore.createPartData(10, 8, [
216
216
  [0, 1, 1, 1, 1, 1, 1, 1, 0, _],
217
217
  [_, _, _, _, _, _, _, _, _, _],
218
218
  ], ['#8020a0', '#601080', '#f0d060']);
219
- const HAT_KNIGHT_S = spriteGeneratorCore.createPartData(10, 6, [
219
+ const HAT_KNIGHT_S = /* @__PURE__ */ spriteGeneratorCore.createPartData(10, 6, [
220
220
  [_, _, _, 0, 0, 0, 0, _, _, _],
221
221
  [_, _, 0, 0, 0, 0, 0, 0, _, _],
222
222
  [_, 0, 0, 0, 0, 0, 0, 0, 0, _],
@@ -224,14 +224,14 @@ const HAT_KNIGHT_S = spriteGeneratorCore.createPartData(10, 6, [
224
224
  [0, 0, 2, 2, 2, 2, 2, 2, 0, 0],
225
225
  [_, _, _, 1, 1, 1, 1, _, _, _],
226
226
  ], ['var(--nice-border, #c0c0c8)', '#606068', '#f0d060']);
227
- const HAT_CROWN_S = spriteGeneratorCore.createPartData(10, 5, [
227
+ const HAT_CROWN_S = /* @__PURE__ */ spriteGeneratorCore.createPartData(10, 5, [
228
228
  [_, 2, _, _, 2, _, _, 2, _, _],
229
229
  [_, 0, 2, _, 0, _, 2, 0, _, _],
230
230
  [_, 0, 0, 2, 0, 2, 0, 0, _, _],
231
231
  [_, 0, 0, 0, 0, 0, 0, 0, _, _],
232
232
  [_, 1, 1, 1, 1, 1, 1, 1, _, _],
233
233
  ], ['#f0d060', '#d0b040', '#ff4040']);
234
- const HAT_CAP_S = spriteGeneratorCore.createPartData(9, 5, [
234
+ const HAT_CAP_S = /* @__PURE__ */ spriteGeneratorCore.createPartData(9, 5, [
235
235
  [_, _, _, 0, 0, 0, _, _, _],
236
236
  [_, _, 0, 0, 0, 0, 0, _, _],
237
237
  [_, 0, 0, 0, 0, 0, 0, 0, _],
@@ -239,7 +239,7 @@ const HAT_CAP_S = spriteGeneratorCore.createPartData(9, 5, [
239
239
  [_, _, 1, 1, 1, 1, 1, _, _],
240
240
  ], ['#d04040', '#b02020']);
241
241
  /* ── WEAPONS ── */
242
- const WEAPON_SWORD_S = spriteGeneratorCore.createPartData(3, 10, [
242
+ const WEAPON_SWORD_S = /* @__PURE__ */ spriteGeneratorCore.createPartData(3, 10, [
243
243
  [_, 0, _],
244
244
  [_, 0, _],
245
245
  [_, 0, _],
@@ -251,7 +251,7 @@ const WEAPON_SWORD_S = spriteGeneratorCore.createPartData(3, 10, [
251
251
  [_, 2, _],
252
252
  [_, 2, _],
253
253
  ], ['var(--nice-border, #c0c0c8)', '#f0d060', '#8b5e3c']);
254
- const WEAPON_STAFF_S = spriteGeneratorCore.createPartData(3, 12, [
254
+ const WEAPON_STAFF_S = /* @__PURE__ */ spriteGeneratorCore.createPartData(3, 12, [
255
255
  [_, 1, _],
256
256
  [1, 1, 1],
257
257
  [_, 1, _],
@@ -265,7 +265,7 @@ const WEAPON_STAFF_S = spriteGeneratorCore.createPartData(3, 12, [
265
265
  [_, 0, _],
266
266
  [_, 0, _],
267
267
  ], ['#8b5e3c', '#4080e0']);
268
- const WEAPON_BOW_S = spriteGeneratorCore.createPartData(5, 10, [
268
+ const WEAPON_BOW_S = /* @__PURE__ */ spriteGeneratorCore.createPartData(5, 10, [
269
269
  [_, _, _, 0, _],
270
270
  [_, _, 0, _, 1],
271
271
  [_, 0, _, _, 1],
@@ -277,7 +277,7 @@ const WEAPON_BOW_S = spriteGeneratorCore.createPartData(5, 10, [
277
277
  [_, _, 0, _, 1],
278
278
  [_, _, _, 0, _],
279
279
  ], ['#8b5e3c', 'var(--nice-border, #c0c0c8)']);
280
- const SHIELD_ROUND_S = spriteGeneratorCore.createPartData(6, 7, [
280
+ const SHIELD_ROUND_S = /* @__PURE__ */ spriteGeneratorCore.createPartData(6, 7, [
281
281
  [_, _, 1, 1, _, _],
282
282
  [_, 1, 0, 0, 1, _],
283
283
  [1, 0, 0, 2, 0, 1],
@@ -2,6 +2,7 @@
2
2
 
3
3
  var uiCore = require('@nice2dev/ui-core');
4
4
  var React = require('react');
5
+ var editorAsk = require('../core/editorAsk.js');
5
6
  var asepriteFormat = require('./asepriteFormat.js');
6
7
  var pixelEditorExports = require('./pixelEditorExports.js');
7
8
  var pixelEditorTypes = require('./pixelEditorTypes.js');
@@ -11,11 +12,12 @@ var pixelEditorUtils = require('./pixelEditorUtils.js');
11
12
  * usePixelEditor — custom hook encapsulating ALL state, refs, callbacks,
12
13
  * side-effects and memos for the PixelEditor component.
13
14
  */
14
- const log = { warn: console.warn, error: console.error, info: console.info, debug: console.debug };
15
+ const log = { warn: console.warn, error: console.error };
15
16
  /* ═══════════════════════════════════════════
16
17
  Hook
17
18
  ═══════════════════════════════════════════ */
18
19
  function usePixelEditor({ initialWidth = 64, initialHeight = 64, onSaveToLibrary, }) {
20
+ const { pendingAsk, ask } = editorAsk.useEditorAsk();
19
21
  /* ── state ── */
20
22
  const [dw, setDw] = React.useState(initialWidth);
21
23
  const [dh, setDh] = React.useState(initialHeight);
@@ -296,7 +298,7 @@ function usePixelEditor({ initialWidth = 64, initialHeight = 64, onSaveToLibrary
296
298
  }
297
299
  // symmetry guides
298
300
  if (symmetry !== 'none') {
299
- ctx.strokeStyle = 'rgba(255,100,100,0.3)';
301
+ ctx.strokeStyle = uiCore.resolveCssColor('var(--nice-danger-tint-30, rgba(255,100,100,0.3))', ctx.canvas);
300
302
  ctx.lineWidth = 1 / zoom;
301
303
  ctx.setLineDash([4 / zoom, 4 / zoom]);
302
304
  if (symmetry === 'h' || symmetry === 'both') {
@@ -331,6 +333,7 @@ function usePixelEditor({ initialWidth = 64, initialHeight = 64, onSaveToLibrary
331
333
  }
332
334
  // grid
333
335
  if (grid && zoom >= 4) {
336
+ // audit-allow: literal-color — a faint light grid over the pixels, the same on every theme's canvas
334
337
  ctx.strokeStyle = 'rgba(255,255,255,0.07)';
335
338
  ctx.lineWidth = 1 / zoom;
336
339
  for (let x = 0; x <= dw; x++) {
@@ -347,7 +350,7 @@ function usePixelEditor({ initialWidth = 64, initialHeight = 64, onSaveToLibrary
347
350
  }
348
351
  }
349
352
  // border
350
- ctx.strokeStyle = 'rgba(80,100,200,0.4)';
353
+ ctx.strokeStyle = uiCore.resolveCssColor('var(--nice-primary-tint-40, rgba(80,100,200,0.4))', ctx.canvas);
351
354
  ctx.lineWidth = 1 / zoom;
352
355
  ctx.strokeRect(-0.5 / zoom, -0.5 / zoom, dw + 1 / zoom, dh + 1 / zoom);
353
356
  // brush cursor preview
@@ -834,13 +837,12 @@ function usePixelEditor({ initialWidth = 64, initialHeight = 64, onSaveToLibrary
834
837
  cv.height = dh;
835
838
  cv.getContext('2d').putImageData(data, 0, 0);
836
839
  const dataUrl = cv.toDataURL('image/png');
837
- const defaultName = `sprite-${dw}x${dh}.png`;
838
- const name = window.prompt('Save to library as:', defaultName);
839
- if (!name || !name.trim()) {
840
- return;
841
- }
842
- onSaveToLibrary(dataUrl, name.trim(), 'image/png');
843
- }, [onSaveToLibrary, afi, dw, dh, compFrame]);
840
+ void ask('prompt', 'Save to library as:', `sprite-${dw}x${dh}.png`).then((name) => {
841
+ if (name && name.trim()) {
842
+ onSaveToLibrary(dataUrl, name.trim(), 'image/png');
843
+ }
844
+ });
845
+ }, [onSaveToLibrary, afi, dw, dh, compFrame, ask]);
844
846
  /* ── layer management ── */
845
847
  const addLayer = React.useCallback(() => {
846
848
  snap('Add Layer');
@@ -1274,6 +1276,7 @@ function usePixelEditor({ initialWidth = 64, initialHeight = 64, onSaveToLibrary
1274
1276
  }, [fc, dw, dh, layers, tick]);
1275
1277
  /* ── return API ── */
1276
1278
  return {
1279
+ pendingAsk,
1277
1280
  dw,
1278
1281
  dh,
1279
1282
  layers,
@@ -3,6 +3,7 @@
3
3
  var jsxRuntime = require('react/jsx-runtime');
4
4
  var uiCore = require('@nice2dev/ui-core');
5
5
  var React = require('react');
6
+ var i18n = require('../core/i18n.js');
6
7
 
7
8
  // ── Default Config ──────────────────────────────────────────────
8
9
  const DEFAULT_BRUSH = {
@@ -203,6 +204,7 @@ function useTexturePainter(width, height) {
203
204
  // ── Component ───────────────────────────────────────────────────
204
205
  /** 3D texture painting tool with UV-space brush painting, zoom/pan, and layers. */
205
206
  const Nice3DTexturePainter = ({ textureWidth = 1024, textureHeight = 1024, onSave, className = '', }) => {
207
+ const { t } = i18n.useNiceTranslation();
206
208
  const painter = useTexturePainter(textureWidth, textureHeight);
207
209
  const canvasRef = React.useRef(null);
208
210
  const isPainting = React.useRef(false);
@@ -334,17 +336,17 @@ const Nice3DTexturePainter = ({ textureWidth = 1024, textureHeight = 1024, onSav
334
336
  color: 'var(--nice-text, #c1c2c5)',
335
337
  padding: 12,
336
338
  borderRadius: 8,
337
- }, children: [jsxRuntime.jsxs("div", { style: { width: 140, fontSize: 11, display: 'flex', flexDirection: 'column', gap: 4 }, children: [jsxRuntime.jsx("strong", { style: { fontSize: 12 }, children: "Tools" }), ['brush', 'eraser', 'eyedropper', 'fill'].map((t) => (jsxRuntime.jsxs("button", { onClick: () => painter.setTool(t), style: btnStyle(painter.tool === t), children: [jsxRuntime.jsx(uiCore.NiceIcon, { name: toolIcons[t], size: 14 }), " ", t.charAt(0).toUpperCase() + t.slice(1), ' ', jsxRuntime.jsx("span", { style: { color: 'var(--nice-text-secondary, #868e96)', marginLeft: 'auto' }, children: t === 'brush' ? 'B' : t === 'eraser' ? 'E' : t === 'eyedropper' ? 'I' : 'G' })] }, t))), jsxRuntime.jsx("hr", { style: {
339
+ }, children: [jsxRuntime.jsxs("div", { style: { width: 140, fontSize: 11, display: 'flex', flexDirection: 'column', gap: 4 }, children: [jsxRuntime.jsx("strong", { style: { fontSize: 12 }, children: t('texturePainter3d.tools', 'Tools') }), ['brush', 'eraser', 'eyedropper', 'fill'].map((t) => (jsxRuntime.jsxs("button", { onClick: () => painter.setTool(t), style: btnStyle(painter.tool === t), children: [jsxRuntime.jsx(uiCore.NiceIcon, { name: toolIcons[t], size: 14 }), " ", t.charAt(0).toUpperCase() + t.slice(1), ' ', jsxRuntime.jsx("span", { style: { color: 'var(--nice-text-secondary, #868e96)', marginLeft: 'auto' }, children: t === 'brush' ? 'B' : t === 'eraser' ? 'E' : t === 'eyedropper' ? 'I' : 'G' })] }, t))), jsxRuntime.jsx("hr", { style: {
338
340
  border: 'none',
339
341
  borderTop: '1px solid var(--nice-border, #373a40)',
340
342
  width: '100%',
341
343
  margin: '4px 0',
342
- } }), jsxRuntime.jsx("div", { style: { display: 'flex', justifyContent: 'space-between' }, children: jsxRuntime.jsxs("button", { onClick: () => painter.undo(), style: btnStyle(false), title: "Undo (Ctrl+Z)", children: [jsxRuntime.jsx(uiCore.NiceIcon, { name: "reply", size: 14 }), " Undo"] }) }), jsxRuntime.jsx("hr", { style: {
344
+ } }), jsxRuntime.jsx("div", { style: { display: 'flex', justifyContent: 'space-between' }, children: jsxRuntime.jsxs("button", { onClick: () => painter.undo(), style: btnStyle(false), title: t('texturePainter3d.undoCtrlZ', 'Undo (Ctrl+Z)'), children: [jsxRuntime.jsx(uiCore.NiceIcon, { name: "reply", size: 14 }), " ", t('texturePainter3d.undo', 'Undo')] }) }), jsxRuntime.jsx("hr", { style: {
343
345
  border: 'none',
344
346
  borderTop: '1px solid var(--nice-border, #373a40)',
345
347
  width: '100%',
346
348
  margin: '4px 0',
347
- } }), jsxRuntime.jsxs("label", { children: ["Size: ", painter.brush.size, "px"] }), jsxRuntime.jsx("input", { type: "range", min: 1, max: 100, value: painter.brush.size, onChange: (e) => painter.setBrush({ ...painter.brush, size: Number(e.target.value) }), style: { width: '100%' } }), jsxRuntime.jsxs("label", { children: ["Opacity: ", Math.round(painter.brush.opacity * 100), "%"] }), jsxRuntime.jsx("input", { type: "range", min: 0, max: 1, step: 0.01, value: painter.brush.opacity, onChange: (e) => painter.setBrush({ ...painter.brush, opacity: Number(e.target.value) }), style: { width: '100%' } }), jsxRuntime.jsxs("label", { children: ["Hardness: ", Math.round(painter.brush.hardness * 100), "%"] }), jsxRuntime.jsx("input", { type: "range", min: 0, max: 1, step: 0.01, value: painter.brush.hardness, onChange: (e) => painter.setBrush({ ...painter.brush, hardness: Number(e.target.value) }), style: { width: '100%' } }), jsxRuntime.jsx("label", { children: "Blend Mode" }), jsxRuntime.jsxs("select", { value: painter.brush.blendMode, onChange: (e) => painter.setBrush({
349
+ } }), jsxRuntime.jsx("label", { children: t('texturePainter3d.sizePx', 'Size: {size}px').replace('{size}', String(painter.brush.size)) }), jsxRuntime.jsx("input", { type: "range", min: 1, max: 100, value: painter.brush.size, onChange: (e) => painter.setBrush({ ...painter.brush, size: Number(e.target.value) }), style: { width: '100%' } }), jsxRuntime.jsx("label", { children: t('texturePainter3d.opacity', 'Opacity: {opacity}%').replace('{opacity}', String(Math.round(painter.brush.opacity * 100))) }), jsxRuntime.jsx("input", { type: "range", min: 0, max: 1, step: 0.01, value: painter.brush.opacity, onChange: (e) => painter.setBrush({ ...painter.brush, opacity: Number(e.target.value) }), style: { width: '100%' } }), jsxRuntime.jsx("label", { children: t('texturePainter3d.hardness', 'Hardness: {hardness}%').replace('{hardness}', String(Math.round(painter.brush.hardness * 100))) }), jsxRuntime.jsx("input", { type: "range", min: 0, max: 1, step: 0.01, value: painter.brush.hardness, onChange: (e) => painter.setBrush({ ...painter.brush, hardness: Number(e.target.value) }), style: { width: '100%' } }), jsxRuntime.jsx("label", { children: t('texturePainter3d.blendMode', 'Blend Mode') }), jsxRuntime.jsxs("select", { value: painter.brush.blendMode, onChange: (e) => painter.setBrush({
348
350
  ...painter.brush,
349
351
  blendMode: e.target.value,
350
352
  }), style: {
@@ -355,12 +357,12 @@ const Nice3DTexturePainter = ({ textureWidth = 1024, textureHeight = 1024, onSav
355
357
  border: '1px solid var(--nice-border, #373a40)',
356
358
  borderRadius: 3,
357
359
  fontSize: 10,
358
- }, children: [jsxRuntime.jsx("option", { value: "normal", children: "Normal" }), jsxRuntime.jsx("option", { value: "multiply", children: "Multiply" }), jsxRuntime.jsx("option", { value: "screen", children: "Screen" }), jsxRuntime.jsx("option", { value: "overlay", children: "Overlay" })] }), jsxRuntime.jsx("label", { children: "Color" }), jsxRuntime.jsxs("div", { style: { display: 'flex', gap: 4, alignItems: 'center' }, children: [jsxRuntime.jsx("input", { type: "color", value: painter.brush.color, onChange: (e) => painter.setBrush({ ...painter.brush, color: e.target.value }), style: { width: 32, height: 24, border: 'none', cursor: 'pointer' } }), jsxRuntime.jsx("span", { style: { fontFamily: 'monospace', fontSize: 10 }, children: painter.brush.color })] }), jsxRuntime.jsx("hr", { style: {
360
+ }, children: [jsxRuntime.jsx("option", { value: "normal", children: t('texturePainter3d.normal', 'Normal') }), jsxRuntime.jsx("option", { value: "multiply", children: t('texturePainter3d.multiply', 'Multiply') }), jsxRuntime.jsx("option", { value: "screen", children: t('texturePainter3d.screen', 'Screen') }), jsxRuntime.jsx("option", { value: "overlay", children: t('texturePainter3d.overlay', 'Overlay') })] }), jsxRuntime.jsx("label", { children: t('texturePainter3d.color', 'Color') }), jsxRuntime.jsxs("div", { style: { display: 'flex', gap: 4, alignItems: 'center' }, children: [jsxRuntime.jsx("input", { type: "color", value: painter.brush.color, onChange: (e) => painter.setBrush({ ...painter.brush, color: e.target.value }), style: { width: 32, height: 24, border: 'none', cursor: 'pointer' } }), jsxRuntime.jsx("span", { style: { fontFamily: 'monospace', fontSize: 10 }, children: painter.brush.color })] }), jsxRuntime.jsx("hr", { style: {
359
361
  border: 'none',
360
362
  borderTop: '1px solid var(--nice-border, #373a40)',
361
363
  width: '100%',
362
364
  margin: '4px 0',
363
- } }), jsxRuntime.jsxs("label", { children: ["Zoom: ", Math.round(zoom * 100), "%"] }), jsxRuntime.jsxs("div", { style: { display: 'flex', gap: 2 }, children: [jsxRuntime.jsx("button", { onClick: () => setZoom((z) => Math.max(0.1, z - 0.1)), style: btnStyle(false), children: "\u2212" }), jsxRuntime.jsx("button", { onClick: () => setZoom(0.5), style: btnStyle(false), children: "Reset" }), jsxRuntime.jsx("button", { onClick: () => setZoom((z) => Math.min(4, z + 0.1)), style: btnStyle(false), children: "+" })] })] }), jsxRuntime.jsxs("div", { style: {
365
+ } }), jsxRuntime.jsx("label", { children: t('texturePainter3d.zoom', 'Zoom: {zoom}%').replace('{zoom}', String(Math.round(zoom * 100))) }), jsxRuntime.jsxs("div", { style: { display: 'flex', gap: 2 }, children: [jsxRuntime.jsx("button", { onClick: () => setZoom((z) => Math.max(0.1, z - 0.1)), style: btnStyle(false), children: "\u2212" }), jsxRuntime.jsx("button", { onClick: () => setZoom(0.5), style: btnStyle(false), children: t('texturePainter3d.reset', 'Reset') }), jsxRuntime.jsx("button", { onClick: () => setZoom((z) => Math.min(4, z + 0.1)), style: btnStyle(false), children: "+" })] })] }), jsxRuntime.jsxs("div", { style: {
364
366
  flex: 1,
365
367
  overflow: 'hidden',
366
368
  position: 'relative',
@@ -382,7 +384,7 @@ const Nice3DTexturePainter = ({ textureWidth = 1024, textureHeight = 1024, onSav
382
384
  color: 'var(--nice-text-secondary, #868e96)',
383
385
  display: 'flex',
384
386
  gap: 12,
385
- }, children: [jsxRuntime.jsxs("span", { children: [textureWidth, "\u00D7", textureHeight] }), cursorPos && (jsxRuntime.jsxs("span", { children: ["X: ", cursorPos.x, " Y: ", cursorPos.y] })), jsxRuntime.jsxs("span", { children: ["Zoom: ", Math.round(zoom * 100), "%"] })] })] }), jsxRuntime.jsxs("div", { style: { width: 160, fontSize: 11, display: 'flex', flexDirection: 'column', gap: 4 }, children: [jsxRuntime.jsx("strong", { style: { fontSize: 12 }, children: "Layers" }), jsxRuntime.jsx("div", { style: { flex: 1, overflowY: 'auto', display: 'flex', flexDirection: 'column', gap: 2 }, children: [...painter.layers].reverse().map((l) => (jsxRuntime.jsxs("div", { style: {
387
+ }, children: [jsxRuntime.jsxs("span", { children: [textureWidth, "\u00D7", textureHeight] }), cursorPos && (jsxRuntime.jsxs("span", { children: ["X: ", cursorPos.x, " Y: ", cursorPos.y] })), jsxRuntime.jsx("span", { children: t('texturePainter3d.zoom', 'Zoom: {zoom}%').replace('{zoom}', String(Math.round(zoom * 100))) })] })] }), jsxRuntime.jsxs("div", { style: { width: 160, fontSize: 11, display: 'flex', flexDirection: 'column', gap: 4 }, children: [jsxRuntime.jsx("strong", { style: { fontSize: 12 }, children: t('texturePainter3d.layers', 'Layers') }), jsxRuntime.jsx("div", { style: { flex: 1, overflowY: 'auto', display: 'flex', flexDirection: 'column', gap: 2 }, children: [...painter.layers].reverse().map((l) => (jsxRuntime.jsxs("div", { style: {
386
388
  padding: '4px 6px',
387
389
  borderRadius: 3,
388
390
  background: painter.activeLayerId === l.id
@@ -403,7 +405,11 @@ const Nice3DTexturePainter = ({ textureWidth = 1024, textureHeight = 1024, onSav
403
405
  ? 'var(--nice-text, #c1c2c5)'
404
406
  : 'var(--nice-text-secondary, #5c5f66)',
405
407
  fontSize: 12,
406
- }, title: l.visible ? 'Hide layer' : 'Show layer', "aria-label": l.visible ? 'Hide layer' : 'Show layer', children: jsxRuntime.jsx(uiCore.NiceIcon, { name: l.visible ? 'eye' : 'eye-off', size: 14 }) }), jsxRuntime.jsx("span", { style: {
408
+ }, title: l.visible
409
+ ? t('texturePainter3d.hideLayer', 'Hide layer')
410
+ : t('texturePainter3d.showLayer', 'Show layer'), "aria-label": l.visible
411
+ ? t('texturePainter3d.hideLayer', 'Hide layer')
412
+ : t('texturePainter3d.showLayer', 'Show layer'), children: jsxRuntime.jsx(uiCore.NiceIcon, { name: l.visible ? 'eye' : 'eye-off', size: 14 }) }), jsxRuntime.jsx("span", { style: {
407
413
  flex: 1,
408
414
  overflow: 'hidden',
409
415
  textOverflow: 'ellipsis',
@@ -418,14 +424,14 @@ const Nice3DTexturePainter = ({ textureWidth = 1024, textureHeight = 1024, onSav
418
424
  cursor: 'pointer',
419
425
  padding: 0,
420
426
  fontSize: 10,
421
- }, "aria-label": "Remove layer", title: "Remove layer", children: jsxRuntime.jsx(uiCore.NiceIcon, { name: "close", size: 10 }) }))] }), jsxRuntime.jsxs("div", { style: { display: 'flex', alignItems: 'center', gap: 4, marginTop: 2 }, children: [jsxRuntime.jsx("span", { style: { fontSize: 9, color: 'var(--nice-text-secondary, #868e96)' }, children: "\u03B1" }), jsxRuntime.jsx("input", { type: "range", min: 0, max: 1, step: 0.01, value: l.opacity, onChange: (e) => painter.setLayerOpacity(l.id, Number(e.target.value)), style: { flex: 1, height: 12 } }), jsxRuntime.jsxs("span", { style: { fontSize: 9, minWidth: 24, textAlign: 'right' }, children: [Math.round(l.opacity * 100), "%"] })] })] }, l.id))) }), jsxRuntime.jsx("button", { onClick: () => painter.addLayer(`Layer ${painter.layers.length + 1}`), style: {
427
+ }, "aria-label": t('texturePainter3d.removeLayer', 'Remove layer'), title: t('texturePainter3d.removeLayer', 'Remove layer'), children: jsxRuntime.jsx(uiCore.NiceIcon, { name: "close", size: 10 }) }))] }), jsxRuntime.jsxs("div", { style: { display: 'flex', alignItems: 'center', gap: 4, marginTop: 2 }, children: [jsxRuntime.jsx("span", { style: { fontSize: 9, color: 'var(--nice-text-secondary, #868e96)' }, children: "\u03B1" }), jsxRuntime.jsx("input", { type: "range", min: 0, max: 1, step: 0.01, value: l.opacity, onChange: (e) => painter.setLayerOpacity(l.id, Number(e.target.value)), style: { flex: 1, height: 12 } }), jsxRuntime.jsxs("span", { style: { fontSize: 9, minWidth: 24, textAlign: 'right' }, children: [Math.round(l.opacity * 100), "%"] })] })] }, l.id))) }), jsxRuntime.jsx("button", { onClick: () => painter.addLayer(`Layer ${painter.layers.length + 1}`), style: {
422
428
  padding: '4px 8px',
423
429
  border: 'none',
424
430
  borderRadius: 3,
425
431
  cursor: 'pointer',
426
432
  background: 'var(--nice-bg-secondary, #2c2e33)',
427
433
  color: 'var(--nice-text, #c1c2c5)',
428
- }, children: "+ Add Layer" }), jsxRuntime.jsx("hr", { style: {
434
+ }, children: t('texturePainter3d.addLayer', '+ Add Layer') }), jsxRuntime.jsx("hr", { style: {
429
435
  border: 'none',
430
436
  borderTop: '1px solid var(--nice-border, #373a40)',
431
437
  width: '100%',
@@ -438,7 +444,7 @@ const Nice3DTexturePainter = ({ textureWidth = 1024, textureHeight = 1024, onSav
438
444
  borderRadius: 3,
439
445
  cursor: 'pointer',
440
446
  fontWeight: 'bold',
441
- }, children: "Save Texture" })] })] }));
447
+ }, children: t('texturePainter3d.saveTexture', 'Save Texture') })] })] }));
442
448
  };
443
449
 
444
450
  exports.Nice3DTexturePainter = Nice3DTexturePainter;