@nice2dev/game-engine 1.0.2 → 1.0.4

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 (188) hide show
  1. package/dist/cjs/ai/BehaviorTree.js +1215 -0
  2. package/dist/cjs/ai/BehaviorTree.js.map +1 -0
  3. package/dist/cjs/ai/StateMachine.js +783 -0
  4. package/dist/cjs/ai/StateMachine.js.map +1 -0
  5. package/dist/cjs/editor/ShaderGraph.js +1616 -0
  6. package/dist/cjs/editor/ShaderGraph.js.map +1 -0
  7. package/dist/cjs/editor/TimelineEditor.js +819 -0
  8. package/dist/cjs/editor/TimelineEditor.js.map +1 -0
  9. package/dist/cjs/export/GodotExporter.js +1102 -0
  10. package/dist/cjs/export/GodotExporter.js.map +1 -0
  11. package/dist/cjs/export/PlatformExporter.js +236 -0
  12. package/dist/cjs/export/PlatformExporter.js.map +1 -0
  13. package/dist/cjs/export/ThreeJSExporter.js +1116 -0
  14. package/dist/cjs/export/ThreeJSExporter.js.map +1 -0
  15. package/dist/cjs/export/UnityExporter.js +1193 -0
  16. package/dist/cjs/export/UnityExporter.js.map +1 -0
  17. package/dist/cjs/export/WebExporter.js +1036 -0
  18. package/dist/cjs/export/WebExporter.js.map +1 -0
  19. package/dist/cjs/export/index.js +58 -0
  20. package/dist/cjs/export/index.js.map +1 -0
  21. package/dist/cjs/import/AsepriteImporter.js +761 -0
  22. package/dist/cjs/import/AsepriteImporter.js.map +1 -0
  23. package/dist/cjs/import/DragonBonesImporter.js +499 -0
  24. package/dist/cjs/import/DragonBonesImporter.js.map +1 -0
  25. package/dist/cjs/import/GameMakerImporter.js +559 -0
  26. package/dist/cjs/import/GameMakerImporter.js.map +1 -0
  27. package/dist/cjs/import/GodotSceneImporter.js +824 -0
  28. package/dist/cjs/import/GodotSceneImporter.js.map +1 -0
  29. package/dist/cjs/import/LDtkImporter.js +481 -0
  30. package/dist/cjs/import/LDtkImporter.js.map +1 -0
  31. package/dist/cjs/import/Live2DImporter.js +553 -0
  32. package/dist/cjs/import/Live2DImporter.js.map +1 -0
  33. package/dist/cjs/import/NdgFormat.js +499 -0
  34. package/dist/cjs/import/NdgFormat.js.map +1 -0
  35. package/dist/cjs/import/OgmoImporter.js +529 -0
  36. package/dist/cjs/import/OgmoImporter.js.map +1 -0
  37. package/dist/cjs/import/RPGMakerImporter.js +520 -0
  38. package/dist/cjs/import/RPGMakerImporter.js.map +1 -0
  39. package/dist/cjs/import/SceneImporter.js +449 -0
  40. package/dist/cjs/import/SceneImporter.js.map +1 -0
  41. package/dist/cjs/import/SpineImporter.js +583 -0
  42. package/dist/cjs/import/SpineImporter.js.map +1 -0
  43. package/dist/cjs/import/SpriterImporter.js +652 -0
  44. package/dist/cjs/import/SpriterImporter.js.map +1 -0
  45. package/dist/cjs/import/TiledMapImporter.js +859 -0
  46. package/dist/cjs/import/TiledMapImporter.js.map +1 -0
  47. package/dist/cjs/import/UnitySceneImporter.js +732 -0
  48. package/dist/cjs/import/UnitySceneImporter.js.map +1 -0
  49. package/dist/cjs/import/index.js +305 -0
  50. package/dist/cjs/import/index.js.map +1 -0
  51. package/dist/cjs/index.js +201 -0
  52. package/dist/cjs/index.js.map +1 -1
  53. package/dist/cjs/scripting/GraphToAST.js +567 -0
  54. package/dist/cjs/scripting/GraphToAST.js.map +1 -0
  55. package/dist/cjs/scripting/LanguageExporter.js +321 -0
  56. package/dist/cjs/scripting/LanguageExporter.js.map +1 -0
  57. package/dist/cjs/scripting/ScriptAST.js +67 -0
  58. package/dist/cjs/scripting/ScriptAST.js.map +1 -0
  59. package/dist/cjs/scripting/VisualScripting2.js +1140 -0
  60. package/dist/cjs/scripting/VisualScripting2.js.map +1 -0
  61. package/dist/cjs/scripting/exporters/CSharpExporter.js +503 -0
  62. package/dist/cjs/scripting/exporters/CSharpExporter.js.map +1 -0
  63. package/dist/cjs/scripting/exporters/GDScriptExporter.js +452 -0
  64. package/dist/cjs/scripting/exporters/GDScriptExporter.js.map +1 -0
  65. package/dist/cjs/scripting/exporters/LuaExporter.js +457 -0
  66. package/dist/cjs/scripting/exporters/LuaExporter.js.map +1 -0
  67. package/dist/cjs/scripting/exporters/PythonExporter.js +565 -0
  68. package/dist/cjs/scripting/exporters/PythonExporter.js.map +1 -0
  69. package/dist/cjs/scripting/exporters/RustExporter.js +525 -0
  70. package/dist/cjs/scripting/exporters/RustExporter.js.map +1 -0
  71. package/dist/cjs/scripting/exporters/TypeScriptExporter.js +570 -0
  72. package/dist/cjs/scripting/exporters/TypeScriptExporter.js.map +1 -0
  73. package/dist/cjs/systems/ParticleSystem2.js +1478 -0
  74. package/dist/cjs/systems/ParticleSystem2.js.map +1 -0
  75. package/dist/esm/ai/BehaviorTree.js +1186 -0
  76. package/dist/esm/ai/BehaviorTree.js.map +1 -0
  77. package/dist/esm/ai/StateMachine.js +767 -0
  78. package/dist/esm/ai/StateMachine.js.map +1 -0
  79. package/dist/esm/editor/ShaderGraph.js +1606 -0
  80. package/dist/esm/editor/ShaderGraph.js.map +1 -0
  81. package/dist/esm/editor/TimelineEditor.js +800 -0
  82. package/dist/esm/editor/TimelineEditor.js.map +1 -0
  83. package/dist/esm/export/GodotExporter.js +1100 -0
  84. package/dist/esm/export/GodotExporter.js.map +1 -0
  85. package/dist/esm/export/PlatformExporter.js +230 -0
  86. package/dist/esm/export/PlatformExporter.js.map +1 -0
  87. package/dist/esm/export/ThreeJSExporter.js +1114 -0
  88. package/dist/esm/export/ThreeJSExporter.js.map +1 -0
  89. package/dist/esm/export/UnityExporter.js +1191 -0
  90. package/dist/esm/export/UnityExporter.js.map +1 -0
  91. package/dist/esm/export/WebExporter.js +1033 -0
  92. package/dist/esm/export/WebExporter.js.map +1 -0
  93. package/dist/esm/export/index.js +44 -0
  94. package/dist/esm/export/index.js.map +1 -0
  95. package/dist/esm/import/AsepriteImporter.js +759 -0
  96. package/dist/esm/import/AsepriteImporter.js.map +1 -0
  97. package/dist/esm/import/DragonBonesImporter.js +496 -0
  98. package/dist/esm/import/DragonBonesImporter.js.map +1 -0
  99. package/dist/esm/import/GameMakerImporter.js +556 -0
  100. package/dist/esm/import/GameMakerImporter.js.map +1 -0
  101. package/dist/esm/import/GodotSceneImporter.js +822 -0
  102. package/dist/esm/import/GodotSceneImporter.js.map +1 -0
  103. package/dist/esm/import/LDtkImporter.js +479 -0
  104. package/dist/esm/import/LDtkImporter.js.map +1 -0
  105. package/dist/esm/import/Live2DImporter.js +550 -0
  106. package/dist/esm/import/Live2DImporter.js.map +1 -0
  107. package/dist/esm/import/NdgFormat.js +490 -0
  108. package/dist/esm/import/NdgFormat.js.map +1 -0
  109. package/dist/esm/import/OgmoImporter.js +526 -0
  110. package/dist/esm/import/OgmoImporter.js.map +1 -0
  111. package/dist/esm/import/RPGMakerImporter.js +517 -0
  112. package/dist/esm/import/RPGMakerImporter.js.map +1 -0
  113. package/dist/esm/import/SceneImporter.js +441 -0
  114. package/dist/esm/import/SceneImporter.js.map +1 -0
  115. package/dist/esm/import/SpineImporter.js +580 -0
  116. package/dist/esm/import/SpineImporter.js.map +1 -0
  117. package/dist/esm/import/SpriterImporter.js +649 -0
  118. package/dist/esm/import/SpriterImporter.js.map +1 -0
  119. package/dist/esm/import/TiledMapImporter.js +857 -0
  120. package/dist/esm/import/TiledMapImporter.js.map +1 -0
  121. package/dist/esm/import/UnitySceneImporter.js +730 -0
  122. package/dist/esm/import/UnitySceneImporter.js.map +1 -0
  123. package/dist/esm/import/index.js +279 -0
  124. package/dist/esm/import/index.js.map +1 -0
  125. package/dist/esm/index.js +36 -0
  126. package/dist/esm/index.js.map +1 -1
  127. package/dist/esm/scripting/GraphToAST.js +564 -0
  128. package/dist/esm/scripting/GraphToAST.js.map +1 -0
  129. package/dist/esm/scripting/LanguageExporter.js +311 -0
  130. package/dist/esm/scripting/LanguageExporter.js.map +1 -0
  131. package/dist/esm/scripting/ScriptAST.js +52 -0
  132. package/dist/esm/scripting/ScriptAST.js.map +1 -0
  133. package/dist/esm/scripting/VisualScripting2.js +1130 -0
  134. package/dist/esm/scripting/VisualScripting2.js.map +1 -0
  135. package/dist/esm/scripting/exporters/CSharpExporter.js +501 -0
  136. package/dist/esm/scripting/exporters/CSharpExporter.js.map +1 -0
  137. package/dist/esm/scripting/exporters/GDScriptExporter.js +450 -0
  138. package/dist/esm/scripting/exporters/GDScriptExporter.js.map +1 -0
  139. package/dist/esm/scripting/exporters/LuaExporter.js +455 -0
  140. package/dist/esm/scripting/exporters/LuaExporter.js.map +1 -0
  141. package/dist/esm/scripting/exporters/PythonExporter.js +563 -0
  142. package/dist/esm/scripting/exporters/PythonExporter.js.map +1 -0
  143. package/dist/esm/scripting/exporters/RustExporter.js +523 -0
  144. package/dist/esm/scripting/exporters/RustExporter.js.map +1 -0
  145. package/dist/esm/scripting/exporters/TypeScriptExporter.js +568 -0
  146. package/dist/esm/scripting/exporters/TypeScriptExporter.js.map +1 -0
  147. package/dist/esm/systems/ParticleSystem2.js +1471 -0
  148. package/dist/esm/systems/ParticleSystem2.js.map +1 -0
  149. package/dist/types/ai/BehaviorTree.d.ts +375 -0
  150. package/dist/types/ai/StateMachine.d.ts +296 -0
  151. package/dist/types/editor/ShaderGraph.d.ts +207 -0
  152. package/dist/types/editor/TimelineEditor.d.ts +393 -0
  153. package/dist/types/export/GodotExporter.d.ts +56 -0
  154. package/dist/types/export/PlatformExporter.d.ts +201 -0
  155. package/dist/types/export/ThreeJSExporter.d.ts +40 -0
  156. package/dist/types/export/UnityExporter.d.ts +69 -0
  157. package/dist/types/export/WebExporter.d.ts +58 -0
  158. package/dist/types/export/index.d.ts +19 -0
  159. package/dist/types/import/AsepriteImporter.d.ts +46 -0
  160. package/dist/types/import/DragonBonesImporter.d.ts +331 -0
  161. package/dist/types/import/GameMakerImporter.d.ts +375 -0
  162. package/dist/types/import/GodotSceneImporter.d.ts +34 -0
  163. package/dist/types/import/LDtkImporter.d.ts +177 -0
  164. package/dist/types/import/Live2DImporter.d.ts +237 -0
  165. package/dist/types/import/NdgFormat.d.ts +387 -0
  166. package/dist/types/import/OgmoImporter.d.ts +237 -0
  167. package/dist/types/import/RPGMakerImporter.d.ts +186 -0
  168. package/dist/types/import/SceneImporter.d.ts +276 -0
  169. package/dist/types/import/SpineImporter.d.ts +372 -0
  170. package/dist/types/import/SpriterImporter.d.ts +230 -0
  171. package/dist/types/import/TiledMapImporter.d.ts +57 -0
  172. package/dist/types/import/UnitySceneImporter.d.ts +87 -0
  173. package/dist/types/import/index.d.ts +59 -0
  174. package/dist/types/index.d.ts +29 -17
  175. package/dist/types/scripting/GraphToAST.d.ts +55 -0
  176. package/dist/types/scripting/LanguageExporter.d.ts +136 -0
  177. package/dist/types/scripting/ScriptAST.d.ts +312 -0
  178. package/dist/types/scripting/VisualScripting2.d.ts +353 -0
  179. package/dist/types/scripting/exporters/CSharpExporter.d.ts +44 -0
  180. package/dist/types/scripting/exporters/GDScriptExporter.d.ts +46 -0
  181. package/dist/types/scripting/exporters/LuaExporter.d.ts +46 -0
  182. package/dist/types/scripting/exporters/PythonExporter.d.ts +49 -0
  183. package/dist/types/scripting/exporters/RustExporter.d.ts +46 -0
  184. package/dist/types/scripting/exporters/TypeScriptExporter.d.ts +48 -0
  185. package/dist/types/scripting/exporters/index.d.ts +8 -0
  186. package/dist/types/scripting/index.d.ts +11 -0
  187. package/dist/types/systems/ParticleSystem2.d.ts +646 -0
  188. package/package.json +3 -3
@@ -0,0 +1,649 @@
1
+ import { SceneImporter } from './SceneImporter.js';
2
+
3
+ /**
4
+ * @file SpriterImporter.ts
5
+ * @description Spriter Pro Animation Importer
6
+ * PRO-1.3: Scene Format Interoperability
7
+ *
8
+ * Spriter is a 2D animation tool for games.
9
+ * Supports SCML (XML) and SCON (JSON) formats.
10
+ *
11
+ * File Types:
12
+ * - *.scml - Spriter Character Map Lxml (XML format)
13
+ * - *.scon - Spriter Character Object Notation (JSON format)
14
+ */
15
+ // ============================================================
16
+ // Spriter Importer
17
+ // ============================================================
18
+ class SpriterImporter extends SceneImporter {
19
+ constructor() {
20
+ super('spriter');
21
+ this.project = null;
22
+ this.fileMap = new Map();
23
+ this.folderMap = new Map();
24
+ }
25
+ canHandle(filePath) {
26
+ const ext = filePath.toLowerCase();
27
+ return ext.endsWith('.scml') || ext.endsWith('.scon');
28
+ }
29
+ async import(options) {
30
+ const startTime = Date.now();
31
+ this.options = options;
32
+ this.clearMessages();
33
+ const scenes = [];
34
+ const assets = [];
35
+ try {
36
+ const content = await this.readFile(options.sourcePath);
37
+ const isXml = options.sourcePath.toLowerCase().endsWith('.scml');
38
+ if (isXml) {
39
+ this.project = this.parseScml(content);
40
+ }
41
+ else {
42
+ const parsed = JSON.parse(content);
43
+ this.project = parsed.spriter_data;
44
+ }
45
+ if (!this.project) {
46
+ throw new Error('Failed to parse Spriter project');
47
+ }
48
+ // Build folder/file maps
49
+ this.buildMaps();
50
+ // Add file assets
51
+ for (const folder of this.project.folder) {
52
+ for (const file of folder.file) {
53
+ assets.push({
54
+ id: this.generateId(),
55
+ name: this.extractFileName(file.name),
56
+ type: file.name.match(/\.(wav|ogg|mp3)$/i) ? 'audio' : 'texture',
57
+ path: file.name,
58
+ data: {
59
+ folder: folder.name || `folder_${folder.id}`,
60
+ width: file.width,
61
+ height: file.height,
62
+ pivotX: file.pivot_x,
63
+ pivotY: file.pivot_y,
64
+ },
65
+ });
66
+ }
67
+ }
68
+ // Convert each entity to a scene
69
+ for (const entity of this.project.entity) {
70
+ const scene = this.convertEntityToScene(entity);
71
+ scenes.push(scene);
72
+ }
73
+ }
74
+ catch (error) {
75
+ this.addError('IMPORT_ERROR', `Failed to import: ${error}`, options.sourcePath, undefined, true);
76
+ }
77
+ return this.createResult(scenes, assets, startTime);
78
+ }
79
+ async parseFile(content, filePath) {
80
+ const stringContent = typeof content === 'string' ? content : new TextDecoder().decode(content);
81
+ try {
82
+ const isXml = filePath.toLowerCase().endsWith('.scml');
83
+ if (isXml) {
84
+ this.project = this.parseScml(stringContent);
85
+ }
86
+ else {
87
+ const parsed = JSON.parse(stringContent);
88
+ this.project = parsed.spriter_data;
89
+ }
90
+ if (this.project && this.project.entity.length > 0) {
91
+ this.buildMaps();
92
+ return this.convertEntityToParsed(this.project.entity[0]);
93
+ }
94
+ }
95
+ catch (_a) {
96
+ return null;
97
+ }
98
+ return null;
99
+ }
100
+ async validate(sourcePath) {
101
+ const errors = [];
102
+ if (!this.canHandle(sourcePath)) {
103
+ errors.push({
104
+ code: 'INVALID_FORMAT',
105
+ message: `File ${sourcePath} is not a valid Spriter file`,
106
+ file: sourcePath,
107
+ fatal: true,
108
+ });
109
+ }
110
+ return errors;
111
+ }
112
+ // ----------------------------------------
113
+ // SCML (XML) Parser
114
+ // ----------------------------------------
115
+ parseScml(xml) {
116
+ // Simple XML attribute parser
117
+ const getAttrs = (tag) => {
118
+ const attrs = {};
119
+ const attrRegex = /(\w+)="([^"]*)"/g;
120
+ let match;
121
+ while ((match = attrRegex.exec(tag)) !== null) {
122
+ attrs[match[1]] = match[2];
123
+ }
124
+ return attrs;
125
+ };
126
+ // Parse folders
127
+ const folders = [];
128
+ const folderRegex = /<folder\s+([^>]*)>([\s\S]*?)<\/folder>/g;
129
+ let folderMatch;
130
+ while ((folderMatch = folderRegex.exec(xml)) !== null) {
131
+ const folderAttrs = getAttrs(folderMatch[1]);
132
+ const files = [];
133
+ const fileRegex = /<file\s+([^/]*?)\/>/g;
134
+ let fileMatch;
135
+ const folderContent = folderMatch[2];
136
+ while ((fileMatch = fileRegex.exec(folderContent)) !== null) {
137
+ const fileAttrs = getAttrs(fileMatch[1]);
138
+ files.push({
139
+ id: parseInt(fileAttrs.id) || 0,
140
+ name: fileAttrs.name || '',
141
+ width: parseInt(fileAttrs.width) || 0,
142
+ height: parseInt(fileAttrs.height) || 0,
143
+ pivot_x: fileAttrs.pivot_x !== undefined ? parseFloat(fileAttrs.pivot_x) : undefined,
144
+ pivot_y: fileAttrs.pivot_y !== undefined ? parseFloat(fileAttrs.pivot_y) : undefined,
145
+ });
146
+ }
147
+ folders.push({
148
+ id: parseInt(folderAttrs.id) || 0,
149
+ name: folderAttrs.name,
150
+ file: files,
151
+ });
152
+ }
153
+ // Parse entities
154
+ const entities = [];
155
+ const entityRegex = /<entity\s+([^>]*)>([\s\S]*?)<\/entity>/g;
156
+ let entityMatch;
157
+ while ((entityMatch = entityRegex.exec(xml)) !== null) {
158
+ const entityAttrs = getAttrs(entityMatch[1]);
159
+ const entityContent = entityMatch[2];
160
+ // Parse animations
161
+ const animations = [];
162
+ const animRegex = /<animation\s+([^>]*)>([\s\S]*?)<\/animation>/g;
163
+ let animMatch;
164
+ while ((animMatch = animRegex.exec(entityContent)) !== null) {
165
+ const animAttrs = getAttrs(animMatch[1]);
166
+ const animContent = animMatch[2];
167
+ // Parse mainline
168
+ const mainlineMatch = /<mainline>([\s\S]*?)<\/mainline>/.exec(animContent);
169
+ const mainlineKeys = [];
170
+ if (mainlineMatch) {
171
+ const keyRegex = /<key\s+([^>]*)>([\s\S]*?)<\/key>/g;
172
+ let keyMatch;
173
+ while ((keyMatch = keyRegex.exec(mainlineMatch[1])) !== null) {
174
+ const keyAttrs = getAttrs(keyMatch[1]);
175
+ const keyContent = keyMatch[2];
176
+ // Parse bone_ref and object_ref
177
+ const boneRefs = [];
178
+ const objRefs = [];
179
+ const boneRefRegex = /<bone_ref\s+([^/]*?)\/>/g;
180
+ let boneRefMatch;
181
+ while ((boneRefMatch = boneRefRegex.exec(keyContent)) !== null) {
182
+ const refAttrs = getAttrs(boneRefMatch[1]);
183
+ boneRefs.push({
184
+ id: parseInt(refAttrs.id) || 0,
185
+ parent: refAttrs.parent !== undefined ? parseInt(refAttrs.parent) : undefined,
186
+ timeline: parseInt(refAttrs.timeline) || 0,
187
+ key: parseInt(refAttrs.key) || 0,
188
+ });
189
+ }
190
+ const objRefRegex = /<object_ref\s+([^/]*?)\/>/g;
191
+ let objRefMatch;
192
+ while ((objRefMatch = objRefRegex.exec(keyContent)) !== null) {
193
+ const refAttrs = getAttrs(objRefMatch[1]);
194
+ objRefs.push({
195
+ id: parseInt(refAttrs.id) || 0,
196
+ parent: refAttrs.parent !== undefined ? parseInt(refAttrs.parent) : undefined,
197
+ timeline: parseInt(refAttrs.timeline) || 0,
198
+ key: parseInt(refAttrs.key) || 0,
199
+ z_index: refAttrs.z_index !== undefined ? parseInt(refAttrs.z_index) : undefined,
200
+ });
201
+ }
202
+ mainlineKeys.push({
203
+ id: parseInt(keyAttrs.id) || 0,
204
+ time: keyAttrs.time !== undefined ? parseInt(keyAttrs.time) : undefined,
205
+ bone_ref: boneRefs.length > 0 ? boneRefs : undefined,
206
+ object_ref: objRefs.length > 0 ? objRefs : undefined,
207
+ });
208
+ }
209
+ }
210
+ // Parse timelines
211
+ const timelines = [];
212
+ const timelineRegex = /<timeline\s+([^>]*)>([\s\S]*?)<\/timeline>/g;
213
+ let timelineMatch;
214
+ while ((timelineMatch = timelineRegex.exec(animContent)) !== null) {
215
+ const tlAttrs = getAttrs(timelineMatch[1]);
216
+ const tlContent = timelineMatch[2];
217
+ const tlKeys = [];
218
+ const tlKeyRegex = /<key\s+([^>]*)>([\s\S]*?)<\/key>/g;
219
+ let tlKeyMatch;
220
+ while ((tlKeyMatch = tlKeyRegex.exec(tlContent)) !== null) {
221
+ const tlKeyAttrs = getAttrs(tlKeyMatch[1]);
222
+ const tlKeyContent = tlKeyMatch[2];
223
+ const key = {
224
+ id: parseInt(tlKeyAttrs.id) || 0,
225
+ time: tlKeyAttrs.time !== undefined ? parseInt(tlKeyAttrs.time) : undefined,
226
+ spin: tlKeyAttrs.spin !== undefined ? parseInt(tlKeyAttrs.spin) : undefined,
227
+ curve_type: tlKeyAttrs.curve_type,
228
+ };
229
+ // Parse bone
230
+ const boneMatch = /<bone\s+([^/]*?)\/?>/.exec(tlKeyContent);
231
+ if (boneMatch) {
232
+ const boneAttrs = getAttrs(boneMatch[1]);
233
+ key.bone = {
234
+ x: boneAttrs.x !== undefined ? parseFloat(boneAttrs.x) : undefined,
235
+ y: boneAttrs.y !== undefined ? parseFloat(boneAttrs.y) : undefined,
236
+ angle: boneAttrs.angle !== undefined ? parseFloat(boneAttrs.angle) : undefined,
237
+ scale_x: boneAttrs.scale_x !== undefined ? parseFloat(boneAttrs.scale_x) : undefined,
238
+ scale_y: boneAttrs.scale_y !== undefined ? parseFloat(boneAttrs.scale_y) : undefined,
239
+ a: boneAttrs.a !== undefined ? parseFloat(boneAttrs.a) : undefined,
240
+ };
241
+ }
242
+ // Parse object
243
+ const objectMatch = /<object\s+([^/]*?)\/?>/.exec(tlKeyContent);
244
+ if (objectMatch) {
245
+ const objAttrs = getAttrs(objectMatch[1]);
246
+ key.object = {
247
+ folder: objAttrs.folder !== undefined ? parseInt(objAttrs.folder) : undefined,
248
+ file: objAttrs.file !== undefined ? parseInt(objAttrs.file) : undefined,
249
+ x: objAttrs.x !== undefined ? parseFloat(objAttrs.x) : undefined,
250
+ y: objAttrs.y !== undefined ? parseFloat(objAttrs.y) : undefined,
251
+ angle: objAttrs.angle !== undefined ? parseFloat(objAttrs.angle) : undefined,
252
+ scale_x: objAttrs.scale_x !== undefined ? parseFloat(objAttrs.scale_x) : undefined,
253
+ scale_y: objAttrs.scale_y !== undefined ? parseFloat(objAttrs.scale_y) : undefined,
254
+ pivot_x: objAttrs.pivot_x !== undefined ? parseFloat(objAttrs.pivot_x) : undefined,
255
+ pivot_y: objAttrs.pivot_y !== undefined ? parseFloat(objAttrs.pivot_y) : undefined,
256
+ a: objAttrs.a !== undefined ? parseFloat(objAttrs.a) : undefined,
257
+ };
258
+ }
259
+ tlKeys.push(key);
260
+ }
261
+ timelines.push({
262
+ id: parseInt(tlAttrs.id) || 0,
263
+ name: tlAttrs.name || '',
264
+ object_type: tlAttrs.object_type,
265
+ obj: tlAttrs.obj !== undefined ? parseInt(tlAttrs.obj) : undefined,
266
+ key: tlKeys,
267
+ });
268
+ }
269
+ animations.push({
270
+ id: parseInt(animAttrs.id) || 0,
271
+ name: animAttrs.name || '',
272
+ length: parseInt(animAttrs.length) || 0,
273
+ interval: animAttrs.interval !== undefined ? parseInt(animAttrs.interval) : undefined,
274
+ looping: animAttrs.looping !== 'false',
275
+ mainline: { key: mainlineKeys },
276
+ timeline: timelines.length > 0 ? timelines : undefined,
277
+ });
278
+ }
279
+ // Parse character maps
280
+ const characterMaps = [];
281
+ const cmRegex = /<character_map\s+([^>]*)>([\s\S]*?)<\/character_map>/g;
282
+ let cmMatch;
283
+ while ((cmMatch = cmRegex.exec(entityContent)) !== null) {
284
+ const cmAttrs = getAttrs(cmMatch[1]);
285
+ const cmContent = cmMatch[2];
286
+ const maps = [];
287
+ const mapRegex = /<map\s+([^/]*?)\/>/g;
288
+ let mapMatch;
289
+ while ((mapMatch = mapRegex.exec(cmContent)) !== null) {
290
+ const mapAttrs = getAttrs(mapMatch[1]);
291
+ maps.push({
292
+ folder: parseInt(mapAttrs.folder),
293
+ file: parseInt(mapAttrs.file),
294
+ target_folder: mapAttrs.target_folder !== undefined ? parseInt(mapAttrs.target_folder) : undefined,
295
+ target_file: mapAttrs.target_file !== undefined ? parseInt(mapAttrs.target_file) : undefined,
296
+ });
297
+ }
298
+ characterMaps.push({
299
+ id: parseInt(cmAttrs.id) || 0,
300
+ name: cmAttrs.name || '',
301
+ map: maps.length > 0 ? maps : undefined,
302
+ });
303
+ }
304
+ entities.push({
305
+ id: parseInt(entityAttrs.id) || 0,
306
+ name: entityAttrs.name || '',
307
+ animation: animations,
308
+ character_map: characterMaps.length > 0 ? characterMaps : undefined,
309
+ });
310
+ }
311
+ // Get version info
312
+ const spriterDataMatch = /<spriter_data\s+([^>]*)>/;
313
+ const dataMatch = spriterDataMatch.exec(xml);
314
+ const dataAttrs = dataMatch ? getAttrs(dataMatch[1]) : {};
315
+ return {
316
+ scml_version: dataAttrs.scml_version,
317
+ generator: dataAttrs.generator,
318
+ generator_version: dataAttrs.generator_version,
319
+ folder: folders,
320
+ entity: entities,
321
+ };
322
+ }
323
+ // ----------------------------------------
324
+ // Build Maps
325
+ // ----------------------------------------
326
+ buildMaps() {
327
+ this.fileMap.clear();
328
+ this.folderMap.clear();
329
+ if (!this.project)
330
+ return;
331
+ for (const folder of this.project.folder) {
332
+ this.folderMap.set(folder.id, folder);
333
+ for (const file of folder.file) {
334
+ this.fileMap.set(`${folder.id}_${file.id}`, file);
335
+ }
336
+ }
337
+ }
338
+ // ----------------------------------------
339
+ // Entity Conversion
340
+ // ----------------------------------------
341
+ convertEntityToScene(entity) {
342
+ var _a, _b, _c;
343
+ const entities = [];
344
+ // Create root entity
345
+ const rootEntity = {
346
+ id: this.generateId(),
347
+ name: entity.name,
348
+ components: [
349
+ {
350
+ type: 'Transform',
351
+ data: {
352
+ position: { x: 0, y: 0 },
353
+ rotation: 0,
354
+ scale: { x: 1, y: 1 },
355
+ },
356
+ },
357
+ {
358
+ type: 'SpriterEntity',
359
+ data: {
360
+ animationCount: entity.animation.length,
361
+ characterMapCount: ((_a = entity.character_map) === null || _a === void 0 ? void 0 : _a.length) || 0,
362
+ hasVariables: !!entity.var_defs && entity.var_defs.length > 0,
363
+ },
364
+ },
365
+ ],
366
+ children: [],
367
+ tags: ['spriter', 'entity'],
368
+ active: true,
369
+ };
370
+ // Add object info components
371
+ if (entity.obj_info) {
372
+ for (const objInfo of entity.obj_info) {
373
+ rootEntity.components.push({
374
+ type: objInfo.type === 'bone' ? 'Bone' : 'SpriteObject',
375
+ data: {
376
+ name: objInfo.name,
377
+ type: objInfo.type,
378
+ width: objInfo.w,
379
+ height: objInfo.h,
380
+ pivotX: objInfo.pivot_x,
381
+ pivotY: objInfo.pivot_y,
382
+ },
383
+ });
384
+ }
385
+ }
386
+ // Add character maps
387
+ if (entity.character_map) {
388
+ for (const charMap of entity.character_map) {
389
+ rootEntity.components.push({
390
+ type: 'CharacterMap',
391
+ data: {
392
+ name: charMap.name,
393
+ mappingCount: ((_b = charMap.map) === null || _b === void 0 ? void 0 : _b.length) || 0,
394
+ mappings: (_c = charMap.map) === null || _c === void 0 ? void 0 : _c.map((m) => ({
395
+ sourceFolder: m.folder,
396
+ sourceFile: m.file,
397
+ targetFolder: m.target_folder,
398
+ targetFile: m.target_file,
399
+ })),
400
+ },
401
+ });
402
+ }
403
+ }
404
+ // Add variables
405
+ if (entity.var_defs) {
406
+ for (const varDef of entity.var_defs) {
407
+ rootEntity.components.push({
408
+ type: 'Variable',
409
+ data: {
410
+ name: varDef.name,
411
+ type: varDef.type,
412
+ defaultValue: varDef.default_value,
413
+ },
414
+ });
415
+ }
416
+ }
417
+ // Add animations
418
+ for (const anim of entity.animation) {
419
+ const animComponent = this.convertAnimation(anim);
420
+ rootEntity.components.push(animComponent);
421
+ }
422
+ entities.push(rootEntity);
423
+ return {
424
+ id: this.generateId(),
425
+ name: entity.name,
426
+ entities,
427
+ settings: {
428
+ width: 800,
429
+ height: 600,
430
+ backgroundColor: '#1a1a2e',
431
+ },
432
+ };
433
+ }
434
+ convertAnimation(anim) {
435
+ var _a, _b;
436
+ const bones = [];
437
+ const sprites = [];
438
+ // Extract bones and sprites from timelines
439
+ if (anim.timeline) {
440
+ for (const timeline of anim.timeline) {
441
+ if (timeline.object_type === 'bone' || ((_a = timeline.key[0]) === null || _a === void 0 ? void 0 : _a.bone)) {
442
+ bones.push({
443
+ name: timeline.name,
444
+ keyframeCount: timeline.key.length,
445
+ keys: timeline.key.map((k) => {
446
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
447
+ return ({
448
+ time: k.time || 0,
449
+ x: ((_a = k.bone) === null || _a === void 0 ? void 0 : _a.x) || 0,
450
+ y: ((_b = k.bone) === null || _b === void 0 ? void 0 : _b.y) || 0,
451
+ angle: ((_c = k.bone) === null || _c === void 0 ? void 0 : _c.angle) || 0,
452
+ scaleX: (_e = (_d = k.bone) === null || _d === void 0 ? void 0 : _d.scale_x) !== null && _e !== void 0 ? _e : 1,
453
+ scaleY: (_g = (_f = k.bone) === null || _f === void 0 ? void 0 : _f.scale_y) !== null && _g !== void 0 ? _g : 1,
454
+ alpha: (_j = (_h = k.bone) === null || _h === void 0 ? void 0 : _h.a) !== null && _j !== void 0 ? _j : 1,
455
+ spin: (_k = k.spin) !== null && _k !== void 0 ? _k : 1,
456
+ curveType: k.curve_type || 'linear',
457
+ });
458
+ }),
459
+ });
460
+ }
461
+ else if ((_b = timeline.key[0]) === null || _b === void 0 ? void 0 : _b.object) {
462
+ sprites.push({
463
+ name: timeline.name,
464
+ keyframeCount: timeline.key.length,
465
+ keys: timeline.key.map((k) => {
466
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t;
467
+ const file = ((_a = k.object) === null || _a === void 0 ? void 0 : _a.folder) !== undefined && ((_b = k.object) === null || _b === void 0 ? void 0 : _b.file) !== undefined
468
+ ? this.fileMap.get(`${k.object.folder}_${k.object.file}`)
469
+ : null;
470
+ return {
471
+ time: k.time || 0,
472
+ x: ((_c = k.object) === null || _c === void 0 ? void 0 : _c.x) || 0,
473
+ y: ((_d = k.object) === null || _d === void 0 ? void 0 : _d.y) || 0,
474
+ angle: ((_e = k.object) === null || _e === void 0 ? void 0 : _e.angle) || 0,
475
+ scaleX: (_g = (_f = k.object) === null || _f === void 0 ? void 0 : _f.scale_x) !== null && _g !== void 0 ? _g : 1,
476
+ scaleY: (_j = (_h = k.object) === null || _h === void 0 ? void 0 : _h.scale_y) !== null && _j !== void 0 ? _j : 1,
477
+ pivotX: (_m = (_l = (_k = k.object) === null || _k === void 0 ? void 0 : _k.pivot_x) !== null && _l !== void 0 ? _l : file === null || file === void 0 ? void 0 : file.pivot_x) !== null && _m !== void 0 ? _m : 0,
478
+ pivotY: (_q = (_p = (_o = k.object) === null || _o === void 0 ? void 0 : _o.pivot_y) !== null && _p !== void 0 ? _p : file === null || file === void 0 ? void 0 : file.pivot_y) !== null && _q !== void 0 ? _q : 1,
479
+ alpha: (_s = (_r = k.object) === null || _r === void 0 ? void 0 : _r.a) !== null && _s !== void 0 ? _s : 1,
480
+ spin: (_t = k.spin) !== null && _t !== void 0 ? _t : 1,
481
+ curveType: k.curve_type || 'linear',
482
+ file: file === null || file === void 0 ? void 0 : file.name,
483
+ };
484
+ }),
485
+ });
486
+ }
487
+ }
488
+ }
489
+ // Extract hierarchy from mainline
490
+ const hierarchy = [];
491
+ if (anim.mainline.key.length > 0) {
492
+ const firstKey = anim.mainline.key[0];
493
+ if (firstKey.bone_ref) {
494
+ for (const boneRef of firstKey.bone_ref) {
495
+ hierarchy.push({
496
+ type: 'bone',
497
+ id: boneRef.id,
498
+ parent: boneRef.parent,
499
+ timeline: boneRef.timeline,
500
+ });
501
+ }
502
+ }
503
+ if (firstKey.object_ref) {
504
+ for (const objRef of firstKey.object_ref) {
505
+ hierarchy.push({
506
+ type: 'sprite',
507
+ id: objRef.id,
508
+ parent: objRef.parent,
509
+ timeline: objRef.timeline,
510
+ zIndex: objRef.z_index,
511
+ });
512
+ }
513
+ }
514
+ }
515
+ // Events
516
+ const events = [];
517
+ if (anim.eventline) {
518
+ for (const eventline of anim.eventline) {
519
+ events.push({
520
+ name: eventline.name,
521
+ times: eventline.key.map((k) => k.time || 0),
522
+ });
523
+ }
524
+ }
525
+ // Sounds
526
+ const sounds = [];
527
+ if (anim.soundline) {
528
+ for (const soundline of anim.soundline) {
529
+ sounds.push({
530
+ name: soundline.name,
531
+ keys: soundline.key.map((k) => {
532
+ var _a, _b;
533
+ const file = this.fileMap.get(`${k.object.folder}_${k.object.file}`);
534
+ return {
535
+ time: k.time || 0,
536
+ file: file === null || file === void 0 ? void 0 : file.name,
537
+ volume: (_a = k.object.volume) !== null && _a !== void 0 ? _a : 1,
538
+ panning: (_b = k.object.panning) !== null && _b !== void 0 ? _b : 0,
539
+ };
540
+ }),
541
+ });
542
+ }
543
+ }
544
+ return {
545
+ type: 'Animation',
546
+ data: {
547
+ name: anim.name,
548
+ duration: anim.length,
549
+ interval: anim.interval,
550
+ looping: anim.looping !== false,
551
+ fps: 1000 / (anim.interval || 33), // Convert interval to FPS
552
+ boneCount: bones.length,
553
+ spriteCount: sprites.length,
554
+ bones,
555
+ sprites,
556
+ hierarchy,
557
+ events,
558
+ sounds,
559
+ mainlineKeyCount: anim.mainline.key.length,
560
+ },
561
+ };
562
+ }
563
+ convertEntityToParsed(entity) {
564
+ var _a, _b, _c, _d;
565
+ const entities = [];
566
+ // Create model entity
567
+ entities.push({
568
+ id: String(entity.id),
569
+ name: entity.name,
570
+ type: 'SpriterEntity',
571
+ x: 0,
572
+ y: 0,
573
+ width: 800,
574
+ height: 600,
575
+ rotation: 0,
576
+ scaleX: 1,
577
+ scaleY: 1,
578
+ visible: true,
579
+ components: [],
580
+ children: [],
581
+ properties: {
582
+ animationCount: entity.animation.length,
583
+ animations: entity.animation.map((a) => ({
584
+ name: a.name,
585
+ duration: a.length,
586
+ looping: a.looping !== false,
587
+ })),
588
+ characterMaps: (_a = entity.character_map) === null || _a === void 0 ? void 0 : _a.map((cm) => cm.name),
589
+ variables: (_b = entity.var_defs) === null || _b === void 0 ? void 0 : _b.map((v) => ({
590
+ name: v.name,
591
+ type: v.type,
592
+ defaultValue: v.default_value,
593
+ })),
594
+ },
595
+ });
596
+ return {
597
+ name: entity.name,
598
+ width: 800,
599
+ height: 600,
600
+ backgroundColor: '#1a1a2e',
601
+ layers: [
602
+ {
603
+ name: 'Animation',
604
+ type: 'object',
605
+ visible: true,
606
+ opacity: 1,
607
+ offsetX: 0,
608
+ offsetY: 0,
609
+ zIndex: 0,
610
+ properties: {},
611
+ },
612
+ ],
613
+ entities,
614
+ properties: {
615
+ generator: (_c = this.project) === null || _c === void 0 ? void 0 : _c.generator,
616
+ generatorVersion: (_d = this.project) === null || _d === void 0 ? void 0 : _d.generator_version,
617
+ },
618
+ };
619
+ }
620
+ // ----------------------------------------
621
+ // Utilities
622
+ // ----------------------------------------
623
+ async readFile(path) {
624
+ var _a;
625
+ if (typeof globalThis.process !== 'undefined' && ((_a = globalThis.process.versions) === null || _a === void 0 ? void 0 : _a.node)) {
626
+ const fs = await import('fs');
627
+ return fs.readFileSync(path, 'utf-8');
628
+ }
629
+ else if (typeof fetch !== 'undefined') {
630
+ const response = await fetch(path);
631
+ return response.text();
632
+ }
633
+ throw new Error('Unable to read file in current environment');
634
+ }
635
+ extractFileName(path) {
636
+ const name = path.substring(Math.max(path.lastIndexOf('/'), path.lastIndexOf('\\')) + 1);
637
+ const dotIndex = name.lastIndexOf('.');
638
+ return dotIndex > 0 ? name.substring(0, dotIndex) : name;
639
+ }
640
+ }
641
+ // ============================================================
642
+ // Factory Function
643
+ // ============================================================
644
+ function createSpriterImporter() {
645
+ return new SpriterImporter();
646
+ }
647
+
648
+ export { SpriterImporter, createSpriterImporter };
649
+ //# sourceMappingURL=SpriterImporter.js.map