adofai 2.9.10 → 2.9.11

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "adofai",
3
- "version": "2.9.10",
3
+ "version": "2.9.11",
4
4
  "main": "index.js",
5
5
  "scripts": {
6
6
  "build": "webpack",
@@ -1,59 +1,48 @@
1
1
  class StringParser {
2
2
  static parse(text: string | null, reviver?: (key: string, value: any) => any): any {
3
- if (text == null) return null
4
-
5
- const result = new ParserX(text).parseValue()
6
-
7
- // Apply reviver function if provided (similar to JSON.parse)
3
+ if (text == null) return null;
4
+ const result = new ParserX(text).parseValue();
8
5
  if (typeof reviver === "function") {
9
- return this._applyReviver("", result, reviver)
6
+ return this._applyReviver("", result, reviver);
10
7
  }
11
-
12
- return result
8
+ return result;
13
9
  }
14
10
 
15
11
  static parsePartially(text: string | null, upToSection: string | null, reviver?: (key: string, value: any) => any): any {
16
- if (text == null) return null
17
-
18
- const result = new ParserX(text, upToSection).parseValue()
19
-
12
+ if (text == null) return null;
13
+ const result = new ParserX(text, upToSection).parseValue();
20
14
  if (typeof reviver === "function") {
21
- return this._applyReviver("", result, reviver)
15
+ return this._applyReviver("", result, reviver);
22
16
  }
23
-
24
- return result
17
+ return result;
25
18
  }
26
19
 
27
20
  static stringify(value: any, replacer?: (key: string, value: any) => any, space?: string | number): string {
28
- const serializer = new Serializer(replacer, space)
29
- return serializer.serialize(value)
21
+ const serializer = new Serializer(replacer, space);
22
+ return serializer.serialize(value);
30
23
  }
31
24
 
32
- // Helper method for reviver function
33
25
  static _applyReviver(key: string, value: any, reviver: (key: string, value: any) => any): any {
34
26
  if (value && typeof value === "object") {
35
27
  if (Array.isArray(value)) {
36
- const arrValue = value as any[];
37
- for (let i = 0; i < arrValue.length; i++) {
38
- arrValue[i] = this._applyReviver(i.toString(), arrValue[i], reviver)
28
+ for (let i = 0; i < value.length; i++) {
29
+ value[i] = this._applyReviver(i.toString(), value[i], reviver);
39
30
  }
40
31
  } else {
41
- const objValue = value as Record<string, any>;
42
- for (const prop in objValue) {
43
- if (Object.prototype.hasOwnProperty.call(objValue, prop)) {
44
- objValue[prop] = this._applyReviver(prop, objValue[prop], reviver)
32
+ for (const prop in value) {
33
+ if (Object.prototype.hasOwnProperty.call(value, prop)) {
34
+ value[prop] = this._applyReviver(prop, value[prop], reviver);
45
35
  }
46
36
  }
47
37
  }
48
38
  }
49
- return reviver(key, value)
39
+ return reviver(key, value);
50
40
  }
51
41
  }
52
42
 
53
43
  class ParserX {
54
- static WHITE_SPACE = " \t\n\r\uFEFF"
55
- static WORD_BREAK = ' \t\n\r{}[],:\"'
56
-
44
+ static WHITE_SPACE = " \t\n\r\uFEFF";
45
+ static WORD_BREAK = ' \t\n\r{}[],:"';
57
46
  static TOKEN = {
58
47
  NONE: 0,
59
48
  CURLY_OPEN: 1,
@@ -67,79 +56,390 @@ class ParserX {
67
56
  TRUE: 9,
68
57
  FALSE: 10,
69
58
  NULL: 11,
70
- }
71
-
59
+ };
72
60
  private json: string;
73
61
  private position: number;
74
62
  private endSection: string | null;
75
-
76
63
  constructor(jsonString: string, endSection: string | null = null) {
77
- this.json = jsonString
78
- this.position = 0
79
- this.endSection = endSection
80
-
81
- // Skip BOM if present
64
+ this.json = jsonString;
65
+ this.position = 0;
66
+ this.endSection = endSection;
82
67
  if (this.peek() === 0xfeff) {
83
- this.read()
68
+ this.read();
84
69
  }
85
70
  }
86
-
87
71
  parseValue(): any {
88
- return this.parseByToken(this.nextToken)
72
+ return this.parseByToken(this.nextToken);
89
73
  }
90
-
91
74
  parseObject(): Record<string, any> | null {
92
- const obj: Record<string, any> = {}
93
- this.read() // consume '{'
94
-
75
+ const obj: Record<string, any> = {};
76
+ this.read();
95
77
  while (true) {
96
- let nextToken
78
+ let nextToken;
97
79
  do {
98
- nextToken = this.nextToken
80
+ nextToken = this.nextToken;
99
81
  if (nextToken === ParserX.TOKEN.NONE) {
100
- return null
82
+ return null;
101
83
  }
102
84
  if (nextToken === ParserX.TOKEN.CURLY_CLOSE) {
103
- return obj
85
+ return obj;
104
86
  }
105
- } while (nextToken === ParserX.TOKEN.COMMA)
106
-
107
- // Rest of the parser implementation would go here
108
- // This is a placeholder for the remaining parser code
87
+ } while (nextToken === ParserX.TOKEN.COMMA);
88
+ const key = this.parseString();
89
+ if (key === null) {
90
+ return null;
91
+ }
92
+ if (this.nextToken !== ParserX.TOKEN.COLON) {
93
+ return null;
94
+ }
95
+ if (this.endSection == null || key !== this.endSection) {
96
+ this.read();
97
+ obj[key] = this.parseValue();
98
+ } else {
99
+ return obj;
100
+ }
109
101
  }
110
102
  }
111
-
112
- // Placeholder for other methods that would be in the Parser class
113
- private get nextToken(): number {
114
- // Implementation would go here
115
- return 0;
103
+ parseArray(): any[] | null {
104
+ const array: any[] = [];
105
+ this.read();
106
+ let parsing = true;
107
+ while (parsing) {
108
+ const nextToken = this.nextToken;
109
+ switch (nextToken) {
110
+ case ParserX.TOKEN.NONE:
111
+ return null;
112
+ case ParserX.TOKEN.SQUARED_CLOSE:
113
+ parsing = false;
114
+ break;
115
+ case ParserX.TOKEN.COMMA:
116
+ break;
117
+ default:
118
+ const value = this.parseByToken(nextToken);
119
+ array.push(value);
120
+ break;
121
+ }
122
+ }
123
+ return array;
116
124
  }
117
-
118
- private read(): number {
119
- // Implementation would go here
120
- return 0;
125
+ parseByToken(token: number): any {
126
+ switch (token) {
127
+ case ParserX.TOKEN.CURLY_OPEN:
128
+ return this.parseObject();
129
+ case ParserX.TOKEN.SQUARED_OPEN:
130
+ return this.parseArray();
131
+ case ParserX.TOKEN.STRING:
132
+ return this.parseString();
133
+ case ParserX.TOKEN.NUMBER:
134
+ return this.parseNumber();
135
+ case ParserX.TOKEN.TRUE:
136
+ return true;
137
+ case ParserX.TOKEN.FALSE:
138
+ return false;
139
+ case ParserX.TOKEN.NULL:
140
+ return null;
141
+ default:
142
+ return null;
143
+ }
121
144
  }
122
-
123
- private peek(): number {
124
- // Implementation would go here
125
- return 0;
145
+ parseString(): string | null {
146
+ let result = "";
147
+ this.read();
148
+ let parsing = true;
149
+ while (parsing) {
150
+ if (this.peek() === -1) {
151
+ break;
152
+ }
153
+ const char = this.nextChar;
154
+ switch (char) {
155
+ case '"':
156
+ parsing = false;
157
+ break;
158
+ case "\\":
159
+ if (this.peek() === -1) {
160
+ parsing = false;
161
+ break;
162
+ }
163
+ const escaped = this.nextChar;
164
+ switch (escaped) {
165
+ case '"':
166
+ case "/":
167
+ case "\\":
168
+ result += escaped;
169
+ break;
170
+ case "b":
171
+ result += "\b";
172
+ break;
173
+ case "f":
174
+ result += "\f";
175
+ break;
176
+ case "n":
177
+ result += "\n";
178
+ break;
179
+ case "r":
180
+ result += "\r";
181
+ break;
182
+ case "t":
183
+ result += "\t";
184
+ break;
185
+ case "u":
186
+ let unicode = "";
187
+ for (let i = 0; i < 4; i++) {
188
+ unicode += this.nextChar;
189
+ }
190
+ result += String.fromCharCode(Number.parseInt(unicode, 16));
191
+ break;
192
+ }
193
+ break;
194
+ default:
195
+ result += char;
196
+ break;
197
+ }
198
+ }
199
+ return result;
126
200
  }
127
-
128
- private parseByToken(token: number): any {
129
- // Implementation would go here
130
- return null;
201
+ parseNumber(): number {
202
+ const word = this.nextWord;
203
+ if (word.indexOf(".") === -1) {
204
+ return Number.parseInt(word, 10) || 0;
205
+ } else {
206
+ return Number.parseFloat(word) || 0.0;
207
+ }
208
+ }
209
+ eatWhitespace(): void {
210
+ while (ParserX.WHITE_SPACE.indexOf(this.peekChar) !== -1) {
211
+ this.read();
212
+ if (this.peek() === -1) {
213
+ break;
214
+ }
215
+ }
216
+ }
217
+ peek(): number {
218
+ if (this.position >= this.json.length) {
219
+ return -1;
220
+ }
221
+ return this.json.charCodeAt(this.position);
222
+ }
223
+ read(): number {
224
+ if (this.position >= this.json.length) {
225
+ return -1;
226
+ }
227
+ return this.json.charCodeAt(this.position++);
228
+ }
229
+ get peekChar(): string {
230
+ const code = this.peek();
231
+ return code === -1 ? "\0" : String.fromCharCode(code);
232
+ }
233
+ get nextChar(): string {
234
+ const code = this.read();
235
+ return code === -1 ? "\0" : String.fromCharCode(code);
236
+ }
237
+ get nextWord(): string {
238
+ let result = "";
239
+ while (ParserX.WORD_BREAK.indexOf(this.peekChar) === -1) {
240
+ result += this.nextChar;
241
+ if (this.peek() === -1) {
242
+ break;
243
+ }
244
+ }
245
+ return result;
246
+ }
247
+ get nextToken(): number {
248
+ this.eatWhitespace();
249
+ if (this.peek() === -1) {
250
+ return ParserX.TOKEN.NONE;
251
+ }
252
+ const char = this.peekChar;
253
+ switch (char) {
254
+ case '"':
255
+ return ParserX.TOKEN.STRING;
256
+ case ",":
257
+ this.read();
258
+ return ParserX.TOKEN.COMMA;
259
+ case "-":
260
+ case "0":
261
+ case "1":
262
+ case "2":
263
+ case "3":
264
+ case "4":
265
+ case "5":
266
+ case "6":
267
+ case "7":
268
+ case "8":
269
+ case "9":
270
+ return ParserX.TOKEN.NUMBER;
271
+ case ":":
272
+ return ParserX.TOKEN.COLON;
273
+ case "[":
274
+ return ParserX.TOKEN.SQUARED_OPEN;
275
+ case "]":
276
+ this.read();
277
+ return ParserX.TOKEN.SQUARED_CLOSE;
278
+ case "{":
279
+ return ParserX.TOKEN.CURLY_OPEN;
280
+ case "}":
281
+ this.read();
282
+ return ParserX.TOKEN.CURLY_CLOSE;
283
+ default:
284
+ const word = this.nextWord;
285
+ switch (word) {
286
+ case "false":
287
+ return ParserX.TOKEN.FALSE;
288
+ case "true":
289
+ return ParserX.TOKEN.TRUE;
290
+ case "null":
291
+ return ParserX.TOKEN.NULL;
292
+ default:
293
+ return ParserX.TOKEN.NONE;
294
+ }
295
+ }
131
296
  }
132
297
  }
133
298
 
134
299
  class Serializer {
300
+ private result: string = "";
301
+ private replacer: ((key: string, value: any) => any) | null;
302
+ private space: string | number | null;
303
+ private indent: number = 0;
304
+ private indentStr: string = "";
135
305
  constructor(replacer?: (key: string, value: any) => any, space?: string | number) {
136
- // Implementation would go here
306
+ this.replacer = replacer || null;
307
+ this.space = space || null;
308
+ if (typeof space === "number") {
309
+ this.indentStr = " ".repeat(Math.min(10, Math.max(0, space)));
310
+ } else if (typeof space === "string") {
311
+ this.indentStr = space.slice(0, 10);
312
+ }
137
313
  }
138
-
139
- serialize(value: any): string {
140
- // Implementation would go here
141
- return "";
314
+ serialize(obj: any): string {
315
+ this.result = "";
316
+ this.serializeValue(obj, "");
317
+ return this.result;
318
+ }
319
+ private serializeValue(value: any, key: string = ""): void {
320
+ if (typeof this.replacer === "function") {
321
+ value = this.replacer(key, value);
322
+ }
323
+ if (value === null || value === undefined) {
324
+ this.result += "null";
325
+ } else if (typeof value === "string") {
326
+ this.serializeString(value);
327
+ } else if (typeof value === "boolean") {
328
+ this.result += value.toString();
329
+ } else if (Array.isArray(value)) {
330
+ this.serializeArray(value);
331
+ } else if (typeof value === "object") {
332
+ this.serializeObject(value);
333
+ } else {
334
+ this.serializeOther(value);
335
+ }
336
+ }
337
+ private serializeObject(obj: Record<string, any>): void {
338
+ let first = true;
339
+ this.result += "{";
340
+ if (this.indentStr) {
341
+ this.result += "\n";
342
+ this.indent++;
343
+ }
344
+ for (const key in obj) {
345
+ if (Object.prototype.hasOwnProperty.call(obj, key)) {
346
+ if (Array.isArray(this.replacer) && !this.replacer.includes(key)) {
347
+ continue;
348
+ }
349
+ if (!first) {
350
+ this.result += ",";
351
+ if (this.indentStr) this.result += "\n";
352
+ }
353
+ if (this.indentStr) {
354
+ this.result += this.indentStr.repeat(this.indent);
355
+ }
356
+ this.serializeString(key.toString());
357
+ this.result += ":";
358
+ if (this.indentStr) this.result += " ";
359
+ this.serializeValue(obj[key], key);
360
+ first = false;
361
+ }
362
+ }
363
+ if (this.indentStr) {
364
+ this.result += "\n";
365
+ this.indent--;
366
+ this.result += this.indentStr.repeat(this.indent);
367
+ }
368
+ this.result += "}";
369
+ }
370
+ private serializeArray(array: any[]): void {
371
+ this.result += "[";
372
+ if (this.indentStr && array.length > 0) {
373
+ this.result += "\n";
374
+ this.indent++;
375
+ }
376
+ let first = true;
377
+ for (let i = 0; i < array.length; i++) {
378
+ if (!first) {
379
+ this.result += ",";
380
+ if (this.indentStr) this.result += "\n";
381
+ }
382
+ if (this.indentStr) {
383
+ this.result += this.indentStr.repeat(this.indent);
384
+ }
385
+ this.serializeValue(array[i], i.toString());
386
+ first = false;
387
+ }
388
+ if (this.indentStr && array.length > 0) {
389
+ this.result += "\n";
390
+ this.indent--;
391
+ this.result += this.indentStr.repeat(this.indent);
392
+ }
393
+ this.result += "]";
394
+ }
395
+ private serializeString(str: string): void {
396
+ this.result += '"';
397
+ for (const char of str) {
398
+ switch (char) {
399
+ case "\b":
400
+ this.result += "\\b";
401
+ break;
402
+ case "\t":
403
+ this.result += "\\t";
404
+ break;
405
+ case "\n":
406
+ this.result += "\\n";
407
+ break;
408
+ case "\f":
409
+ this.result += "\\f";
410
+ break;
411
+ case "\r":
412
+ this.result += "\\r";
413
+ break;
414
+ case '"':
415
+ this.result += '\\"';
416
+ break;
417
+ case "\\":
418
+ this.result += "\\\\";
419
+ break;
420
+ default:
421
+ const code = char.charCodeAt(0);
422
+ if (code >= 32 && code <= 126) {
423
+ this.result += char;
424
+ } else {
425
+ this.result += "\\u" + code.toString(16).padStart(4, "0");
426
+ }
427
+ break;
428
+ }
429
+ }
430
+ this.result += '"';
431
+ }
432
+ private serializeOther(value: any): void {
433
+ if (typeof value === "number") {
434
+ if (isFinite(value)) {
435
+ this.result += value.toString();
436
+ } else {
437
+ this.result += "null";
438
+ }
439
+ } else {
440
+ this.serializeString(value.toString());
441
+ }
142
442
  }
143
443
  }
144
444
 
145
- export default StringParser
445
+ export default StringParser;
@@ -40,41 +40,41 @@ export class Level {
40
40
  switch (typeof opt) {
41
41
  case 'string':
42
42
  try {
43
- options = Parser.parseAsObject(opt, this._provider);
43
+ options = Parser.parseAsObject(opt, this._provider) as LevelOptions;
44
44
  } catch (e) {
45
45
  reject(e);
46
46
  return;
47
47
  }
48
48
  break;
49
49
  case 'object':
50
- options = Object.assign({}, opt);
50
+ options = Object.assign({}, opt) as LevelOptions;
51
51
  break;
52
52
  default:
53
53
  reject("Options must be String or Object");
54
54
  return;
55
55
  }
56
- if ('pathData' in options) {
56
+ if (options && typeof options === 'object' && options !== null && typeof options.pathData !== 'undefined') {
57
57
  this.angleData = pathData.parseToangleData(options['pathData']!);
58
58
  } else {
59
- if ('angleData' in options) {
60
- this.angleData = options['angleData']!;
61
- } else {
62
- reject("There is not any angle datas.");
63
- return;
64
- }
59
+ if (options && typeof options === 'object' && options !== null && typeof options.angleData !== 'undefined') {
60
+ this.angleData = options['angleData']!;
61
+ } else {
62
+ reject("There is not any angle datas.");
63
+ return;
64
+ }
65
65
  }
66
- if ('actions' in options) {
66
+ if (options && typeof options === 'object' && options !== null && typeof options.actions !== 'undefined') {
67
67
  this.actions = options['actions']!;
68
68
  } else {
69
69
  this.actions = [];
70
70
  }
71
- if ('settings' in options) {
71
+ if (options && typeof options === 'object' && options !== null && typeof options.settings !== 'undefined') {
72
72
  this.settings = options['settings']!;
73
73
  } else {
74
74
  reject("There is no ADOFAI settings.");
75
75
  return;
76
76
  }
77
- if ('decorations' in options) {
77
+ if (options && typeof options === 'object' && options !== null && typeof options.decorations !== 'undefined') {
78
78
  this.__decorations = options['decorations']!;
79
79
  } else {
80
80
  this.__decorations = [];
@@ -261,7 +261,7 @@ export class Level {
261
261
  let currentTile = this.tiles[i];
262
262
  if (this.getActionsByIndex('PositionTrack', i).count > 0) {
263
263
  let pevent = this.getActionsByIndex('PositionTrack', i).actions[0];
264
- if ('positionOffset' in pevent) {
264
+ if (pevent.positionOffset) {
265
265
  if (pevent['editorOnly'] !== true && pevent['editorOnly'] !== 'Enabled') {
266
266
  startPos[0] += pevent['positionOffset'][0];
267
267
  startPos[1] += pevent['positionOffset'][1];
package/test/editor.html CHANGED
@@ -15,7 +15,7 @@
15
15
  <script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.10.0/ace.min.js"></script>
16
16
  <script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.10.0/mode-json.min.js"></script>
17
17
  <script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.10.0/theme-monokai.min.js"></script>
18
- <script src="../dist/adofai.min.js"></script>
18
+ <script src="../dist/index.js"></script>
19
19
 
20
20
  <!-- 配置Tailwind -->
21
21
  <script>
package/test/index.html CHANGED
@@ -1,7 +1,7 @@
1
1
  <input type="file" id="inputFile">
2
2
  <button id="export">Export as ADOFAI</button>
3
+ <script src="../dist/index.js"></script>
3
4
  <script type="module">
4
- import * as ADOFAI from '../dist/index.js'
5
5
  let fl, reader;
6
6
  document.querySelector('#inputFile').addEventListener('change', f => {
7
7
  fl = f.target.files[0];
@@ -9,6 +9,7 @@
9
9
  reader.onload = () => {
10
10
  const a = new ADOFAI.Level(reader.result);
11
11
  window.CurADOFAI = a;
12
+ a.load();
12
13
  }
13
14
  reader.readAsText(fl, 'utf-8')
14
15