@willwade/aac-processors 0.0.29 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +52 -852
- package/dist/browser/core/baseProcessor.js +241 -0
- package/dist/browser/core/stringCasing.js +179 -0
- package/dist/browser/core/treeStructure.js +255 -0
- package/dist/browser/index.browser.js +73 -0
- package/dist/browser/processors/applePanelsProcessor.js +582 -0
- package/dist/browser/processors/astericsGridProcessor.js +1509 -0
- package/dist/browser/processors/dotProcessor.js +221 -0
- package/dist/browser/processors/gridset/commands.js +962 -0
- package/dist/browser/processors/gridset/crypto.js +53 -0
- package/dist/browser/processors/gridset/password.js +43 -0
- package/dist/browser/processors/gridset/pluginTypes.js +277 -0
- package/dist/browser/processors/gridset/resolver.js +137 -0
- package/dist/browser/processors/gridset/symbolAlignment.js +276 -0
- package/dist/browser/processors/gridset/symbols.js +421 -0
- package/dist/browser/processors/gridsetProcessor.js +2002 -0
- package/dist/browser/processors/obfProcessor.js +705 -0
- package/dist/browser/processors/opmlProcessor.js +274 -0
- package/dist/browser/types/aac.js +38 -0
- package/dist/browser/utilities/analytics/utils/idGenerator.js +89 -0
- package/dist/browser/utilities/translation/translationProcessor.js +200 -0
- package/dist/browser/utils/io.js +95 -0
- package/dist/browser/validation/baseValidator.js +156 -0
- package/dist/browser/validation/gridsetValidator.js +355 -0
- package/dist/browser/validation/obfValidator.js +500 -0
- package/dist/browser/validation/validationTypes.js +46 -0
- package/dist/cli/index.js +5 -5
- package/dist/core/analyze.d.ts +2 -2
- package/dist/core/analyze.js +2 -2
- package/dist/core/baseProcessor.d.ts +5 -4
- package/dist/core/baseProcessor.js +22 -27
- package/dist/core/treeStructure.d.ts +5 -5
- package/dist/core/treeStructure.js +1 -4
- package/dist/index.browser.d.ts +37 -0
- package/dist/index.browser.js +99 -0
- package/dist/index.d.ts +1 -48
- package/dist/index.js +1 -136
- package/dist/index.node.d.ts +48 -0
- package/dist/index.node.js +152 -0
- package/dist/processors/applePanelsProcessor.d.ts +5 -4
- package/dist/processors/applePanelsProcessor.js +58 -62
- package/dist/processors/astericsGridProcessor.d.ts +7 -6
- package/dist/processors/astericsGridProcessor.js +31 -42
- package/dist/processors/dotProcessor.d.ts +5 -4
- package/dist/processors/dotProcessor.js +25 -33
- package/dist/processors/excelProcessor.d.ts +4 -3
- package/dist/processors/excelProcessor.js +6 -3
- package/dist/processors/gridset/crypto.d.ts +18 -0
- package/dist/processors/gridset/crypto.js +57 -0
- package/dist/processors/gridset/helpers.d.ts +1 -1
- package/dist/processors/gridset/helpers.js +18 -8
- package/dist/processors/gridset/password.d.ts +20 -3
- package/dist/processors/gridset/password.js +17 -3
- package/dist/processors/gridset/wordlistHelpers.d.ts +3 -3
- package/dist/processors/gridset/wordlistHelpers.js +21 -20
- package/dist/processors/gridsetProcessor.d.ts +7 -12
- package/dist/processors/gridsetProcessor.js +118 -77
- package/dist/processors/obfProcessor.d.ts +9 -7
- package/dist/processors/obfProcessor.js +131 -56
- package/dist/processors/obfsetProcessor.d.ts +5 -4
- package/dist/processors/obfsetProcessor.js +10 -16
- package/dist/processors/opmlProcessor.d.ts +5 -4
- package/dist/processors/opmlProcessor.js +27 -34
- package/dist/processors/snapProcessor.d.ts +8 -7
- package/dist/processors/snapProcessor.js +15 -12
- package/dist/processors/touchchatProcessor.d.ts +8 -7
- package/dist/processors/touchchatProcessor.js +22 -17
- package/dist/types/aac.d.ts +0 -2
- package/dist/types/aac.js +2 -0
- package/dist/utils/io.d.ts +12 -0
- package/dist/utils/io.js +107 -0
- package/dist/validation/gridsetValidator.js +7 -7
- package/dist/validation/snapValidator.js +28 -35
- package/docs/BROWSER_USAGE.md +618 -0
- package/examples/README.md +77 -0
- package/examples/browser-test-server.js +81 -0
- package/examples/browser-test.html +331 -0
- package/examples/vitedemo/QUICKSTART.md +74 -0
- package/examples/vitedemo/README.md +157 -0
- package/examples/vitedemo/index.html +376 -0
- package/examples/vitedemo/package-lock.json +1221 -0
- package/examples/vitedemo/package.json +18 -0
- package/examples/vitedemo/src/main.ts +519 -0
- package/examples/vitedemo/test-files/example.dot +14 -0
- package/examples/vitedemo/test-files/example.grd +1 -0
- package/examples/vitedemo/test-files/example.gridset +0 -0
- package/examples/vitedemo/test-files/example.obz +0 -0
- package/examples/vitedemo/test-files/example.opml +18 -0
- package/examples/vitedemo/test-files/simple.obf +53 -0
- package/examples/vitedemo/tsconfig.json +24 -0
- package/examples/vitedemo/vite.config.ts +34 -0
- package/package.json +20 -4
|
@@ -1,19 +1,36 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var
|
|
3
|
-
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
4
24
|
};
|
|
5
25
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
26
|
exports.GridsetProcessor = void 0;
|
|
7
27
|
const baseProcessor_1 = require("../core/baseProcessor");
|
|
8
28
|
const treeStructure_1 = require("../core/treeStructure");
|
|
9
|
-
const adm_zip_1 = __importDefault(require("adm-zip"));
|
|
10
|
-
const fs_1 = __importDefault(require("fs"));
|
|
11
29
|
const fast_xml_parser_1 = require("fast-xml-parser");
|
|
12
30
|
const resolver_1 = require("./gridset/resolver");
|
|
13
31
|
const translationProcessor_1 = require("../utilities/translation/translationProcessor");
|
|
14
32
|
const password_1 = require("./gridset/password");
|
|
15
|
-
const crypto_1 =
|
|
16
|
-
const zlib_1 = __importDefault(require("zlib"));
|
|
33
|
+
const crypto_1 = require("./gridset/crypto");
|
|
17
34
|
const gridsetValidator_1 = require("../validation/gridsetValidator");
|
|
18
35
|
// New imports for enhanced Grid 3 support
|
|
19
36
|
const pluginTypes_1 = require("./gridset/pluginTypes");
|
|
@@ -22,33 +39,35 @@ const symbols_1 = require("./gridset/symbols");
|
|
|
22
39
|
const resolver_2 = require("./gridset/resolver");
|
|
23
40
|
const idGenerator_1 = require("../utilities/analytics/utils/idGenerator");
|
|
24
41
|
const symbolAlignment_1 = require("./gridset/symbolAlignment");
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* Decrypt and inflate a Grid3 encrypted payload (DesktopContentEncrypter).
|
|
31
|
-
* Uses AES-256-CBC with key/IV derived from the password padded with spaces
|
|
32
|
-
* and then Deflate decompression.
|
|
33
|
-
*/
|
|
34
|
-
decryptGridsetEntry(buffer, password) {
|
|
35
|
-
const pwd = (password || 'Chocolate').padEnd(32, ' ');
|
|
36
|
-
const key = Buffer.from(pwd.slice(0, 32), 'utf8');
|
|
37
|
-
const iv = Buffer.from(pwd.slice(0, 16), 'utf8');
|
|
42
|
+
const io_1 = require("../utils/io");
|
|
43
|
+
let JSZipModule;
|
|
44
|
+
async function getJSZip() {
|
|
45
|
+
if (!JSZipModule) {
|
|
38
46
|
try {
|
|
39
|
-
|
|
40
|
-
const
|
|
47
|
+
// Try ES module import first (browser/Vite)
|
|
48
|
+
const module = await Promise.resolve().then(() => __importStar(require('jszip')));
|
|
49
|
+
JSZipModule = module.default || module;
|
|
50
|
+
}
|
|
51
|
+
catch (error) {
|
|
52
|
+
// Fall back to CommonJS require (Node.js)
|
|
41
53
|
try {
|
|
42
|
-
|
|
54
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
55
|
+
const module = require('jszip');
|
|
56
|
+
JSZipModule = module.default || module;
|
|
43
57
|
}
|
|
44
|
-
catch {
|
|
45
|
-
|
|
46
|
-
return decrypted;
|
|
58
|
+
catch (err2) {
|
|
59
|
+
throw new Error('Zip handling requires JSZip in this environment.');
|
|
47
60
|
}
|
|
48
61
|
}
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
62
|
+
}
|
|
63
|
+
if (!JSZipModule) {
|
|
64
|
+
throw new Error('Zip handling requires JSZip in this environment.');
|
|
65
|
+
}
|
|
66
|
+
return JSZipModule;
|
|
67
|
+
}
|
|
68
|
+
class GridsetProcessor extends baseProcessor_1.BaseProcessor {
|
|
69
|
+
constructor(options) {
|
|
70
|
+
super(options);
|
|
52
71
|
}
|
|
53
72
|
// Determine password to use when opening encrypted gridset archives (.gridsetx)
|
|
54
73
|
getGridsetPassword(source) {
|
|
@@ -394,8 +413,8 @@ class GridsetProcessor extends baseProcessor_1.BaseProcessor {
|
|
|
394
413
|
}
|
|
395
414
|
return undefined;
|
|
396
415
|
}
|
|
397
|
-
extractTexts(filePathOrBuffer) {
|
|
398
|
-
const tree = this.loadIntoTree(filePathOrBuffer);
|
|
416
|
+
async extractTexts(filePathOrBuffer) {
|
|
417
|
+
const tree = await this.loadIntoTree(filePathOrBuffer);
|
|
399
418
|
const texts = [];
|
|
400
419
|
for (const pageId in tree.pages) {
|
|
401
420
|
const page = tree.pages[pageId];
|
|
@@ -410,11 +429,13 @@ class GridsetProcessor extends baseProcessor_1.BaseProcessor {
|
|
|
410
429
|
}
|
|
411
430
|
return texts;
|
|
412
431
|
}
|
|
413
|
-
loadIntoTree(filePathOrBuffer) {
|
|
432
|
+
async loadIntoTree(filePathOrBuffer) {
|
|
414
433
|
const tree = new treeStructure_1.AACTree();
|
|
415
434
|
let zip;
|
|
416
435
|
try {
|
|
417
|
-
|
|
436
|
+
const JSZip = await getJSZip();
|
|
437
|
+
const zipInput = (0, io_1.readBinaryFromInput)(filePathOrBuffer);
|
|
438
|
+
zip = await JSZip.loadAsync(zipInput);
|
|
418
439
|
}
|
|
419
440
|
catch (error) {
|
|
420
441
|
throw new Error(`Invalid ZIP file format: ${error.message}`);
|
|
@@ -430,18 +451,22 @@ class GridsetProcessor extends baseProcessor_1.BaseProcessor {
|
|
|
430
451
|
isSmartBox: isEncryptedArchive, // SmartBox files are .gridsetx encrypted archives
|
|
431
452
|
passwordProtected: !!password,
|
|
432
453
|
};
|
|
433
|
-
const readEntryBuffer = (entry) => {
|
|
434
|
-
|
|
435
|
-
|
|
454
|
+
const readEntryBuffer = async (entry) => {
|
|
455
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-return, @typescript-eslint/no-unsafe-argument
|
|
456
|
+
const raw = await entry.getData();
|
|
457
|
+
if (!isEncryptedArchive) {
|
|
458
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
|
436
459
|
return raw;
|
|
437
|
-
|
|
460
|
+
}
|
|
461
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-unsafe-return
|
|
462
|
+
return (0, crypto_1.decryptGridsetEntry)(raw, encryptedContentPassword);
|
|
438
463
|
};
|
|
439
464
|
// Parse FileMap.xml if present to index dynamic files per grid
|
|
440
465
|
const fileMapIndex = new Map();
|
|
441
466
|
try {
|
|
442
467
|
const fmEntry = entries.find((e) => e.entryName.endsWith('FileMap.xml'));
|
|
443
468
|
if (fmEntry) {
|
|
444
|
-
const fmXml = readEntryBuffer(fmEntry)
|
|
469
|
+
const fmXml = (0, io_1.decodeText)(await readEntryBuffer(fmEntry));
|
|
445
470
|
const fmData = parser.parse(fmXml);
|
|
446
471
|
const entries = fmData?.FileMap?.Entries?.Entry || fmData?.fileMap?.entries?.entry;
|
|
447
472
|
if (entries) {
|
|
@@ -476,7 +501,7 @@ class GridsetProcessor extends baseProcessor_1.BaseProcessor {
|
|
|
476
501
|
const styleEntry = entries.find((entry) => entry.entryName.endsWith('styles.xml') || entry.entryName.endsWith('style.xml'));
|
|
477
502
|
if (styleEntry) {
|
|
478
503
|
try {
|
|
479
|
-
const styleXmlContent = readEntryBuffer(styleEntry)
|
|
504
|
+
const styleXmlContent = (0, io_1.decodeText)(await readEntryBuffer(styleEntry));
|
|
480
505
|
const styleData = parser.parse(styleXmlContent);
|
|
481
506
|
// Parse styles and store them in the map
|
|
482
507
|
// Grid3 uses StyleData.Styles.Style with Key attribute
|
|
@@ -507,18 +532,23 @@ class GridsetProcessor extends baseProcessor_1.BaseProcessor {
|
|
|
507
532
|
}
|
|
508
533
|
}
|
|
509
534
|
// Debug: log all entry names
|
|
510
|
-
|
|
535
|
+
console.log('[Gridset] Total zip entries:', entries.length);
|
|
536
|
+
const gridEntries = entries.filter((e) => e.entryName.startsWith('Grids/') && e.entryName.endsWith('grid.xml'));
|
|
537
|
+
console.log('[Gridset] Grid XML entries found:', gridEntries.length);
|
|
538
|
+
if (gridEntries.length > 0) {
|
|
539
|
+
console.log('[Gridset] First few grid entries:', gridEntries.slice(0, 3).map((e) => e.entryName));
|
|
540
|
+
}
|
|
511
541
|
// First pass: collect all grid names and IDs for navigation resolution
|
|
512
542
|
const gridNameToIdMap = new Map();
|
|
513
543
|
const gridIdToNameMap = new Map();
|
|
514
|
-
|
|
544
|
+
for (const entry of entries) {
|
|
515
545
|
if (entry.entryName.startsWith('Grids/') && entry.entryName.endsWith('grid.xml')) {
|
|
516
546
|
try {
|
|
517
|
-
const xmlContent = readEntryBuffer(entry)
|
|
547
|
+
const xmlContent = (0, io_1.decodeText)(await readEntryBuffer(entry));
|
|
518
548
|
const data = parser.parse(xmlContent);
|
|
519
549
|
const grid = data.Grid || data.grid;
|
|
520
550
|
if (!grid)
|
|
521
|
-
|
|
551
|
+
continue;
|
|
522
552
|
const gridId = this.textOf(grid.GridGuid || grid.gridGuid || grid.id);
|
|
523
553
|
const gridName = this.textOf(grid.Name) || this.textOf(grid.name) || this.textOf(grid['@_Name']);
|
|
524
554
|
const folderMatch = entry.entryName.match(/^Grids\/([^/]+)\//);
|
|
@@ -541,32 +571,36 @@ class GridsetProcessor extends baseProcessor_1.BaseProcessor {
|
|
|
541
571
|
// Skip errors in first pass
|
|
542
572
|
}
|
|
543
573
|
}
|
|
544
|
-
}
|
|
574
|
+
}
|
|
545
575
|
// Second pass: process each grid file in the gridset
|
|
546
|
-
|
|
576
|
+
for (const entry of entries) {
|
|
547
577
|
// Only process files named grid.xml under Grids/ (any subdir)
|
|
548
578
|
if (entry.entryName.startsWith('Grids/') && entry.entryName.endsWith('grid.xml')) {
|
|
549
579
|
let xmlContent;
|
|
550
580
|
try {
|
|
551
|
-
|
|
581
|
+
const buffer = await readEntryBuffer(entry);
|
|
582
|
+
xmlContent = (0, io_1.decodeText)(buffer);
|
|
583
|
+
console.log(`[Gridset] Raw XML content (first 200 chars) for ${entry.entryName}:`, xmlContent.substring(0, 200));
|
|
552
584
|
}
|
|
553
585
|
catch (e) {
|
|
554
586
|
// Skip unreadable files
|
|
555
|
-
|
|
587
|
+
continue;
|
|
556
588
|
}
|
|
557
589
|
let data;
|
|
558
590
|
try {
|
|
559
591
|
data = parser.parse(xmlContent);
|
|
592
|
+
console.log(`[Gridset] Parsed ${entry.entryName}, root keys:`, Object.keys(data));
|
|
560
593
|
}
|
|
561
594
|
catch (error) {
|
|
562
595
|
// Skip malformed XML but log the specific error
|
|
563
596
|
console.warn(`Malformed XML in ${entry.entryName}: ${error.message}`);
|
|
564
|
-
|
|
597
|
+
continue;
|
|
565
598
|
}
|
|
566
599
|
// Grid3 XML: <Grid> root
|
|
567
600
|
const grid = data.Grid || data.grid;
|
|
568
601
|
if (!grid) {
|
|
569
|
-
|
|
602
|
+
console.warn(`[Gridset] No Grid/grid found in ${entry.entryName}`);
|
|
603
|
+
continue;
|
|
570
604
|
}
|
|
571
605
|
// Defensive: GridGuid and Name required
|
|
572
606
|
const gridId = this.textOf(grid.GridGuid || grid.gridGuid || grid.id);
|
|
@@ -578,7 +612,7 @@ class GridsetProcessor extends baseProcessor_1.BaseProcessor {
|
|
|
578
612
|
gridName = match[1];
|
|
579
613
|
}
|
|
580
614
|
if (!gridId || !gridName) {
|
|
581
|
-
|
|
615
|
+
continue;
|
|
582
616
|
}
|
|
583
617
|
const page = new treeStructure_1.AACPage({
|
|
584
618
|
id: String(gridId),
|
|
@@ -1291,6 +1325,8 @@ class GridsetProcessor extends baseProcessor_1.BaseProcessor {
|
|
|
1291
1325
|
pluginMetadata.autoContentType === 'Prediction'
|
|
1292
1326
|
? predictionCellCounter
|
|
1293
1327
|
: undefined,
|
|
1328
|
+
// Store page name for Grid3 image lookup
|
|
1329
|
+
gridPageName: gridName,
|
|
1294
1330
|
},
|
|
1295
1331
|
});
|
|
1296
1332
|
// Add button to page
|
|
@@ -1332,7 +1368,7 @@ class GridsetProcessor extends baseProcessor_1.BaseProcessor {
|
|
|
1332
1368
|
}
|
|
1333
1369
|
tree.addPage(page);
|
|
1334
1370
|
}
|
|
1335
|
-
}
|
|
1371
|
+
}
|
|
1336
1372
|
// After all pages are loaded, set parentId for navigation targets
|
|
1337
1373
|
for (const pageId in tree.pages) {
|
|
1338
1374
|
const page = tree.pages[pageId];
|
|
@@ -1349,7 +1385,7 @@ class GridsetProcessor extends baseProcessor_1.BaseProcessor {
|
|
|
1349
1385
|
try {
|
|
1350
1386
|
const settingsEntry = entries.find((e) => e.entryName.endsWith('settings.xml'));
|
|
1351
1387
|
if (settingsEntry) {
|
|
1352
|
-
const settingsXml = readEntryBuffer(settingsEntry)
|
|
1388
|
+
const settingsXml = (0, io_1.decodeText)(await readEntryBuffer(settingsEntry));
|
|
1353
1389
|
const settingsData = parser.parse(settingsXml);
|
|
1354
1390
|
const gsName = settingsData?.GridSetSettings?.Name ||
|
|
1355
1391
|
settingsData?.gridSetSettings?.name ||
|
|
@@ -1443,9 +1479,9 @@ class GridsetProcessor extends baseProcessor_1.BaseProcessor {
|
|
|
1443
1479
|
tree.metadata = metadata;
|
|
1444
1480
|
return tree;
|
|
1445
1481
|
}
|
|
1446
|
-
processTexts(filePathOrBuffer, translations, outputPath) {
|
|
1482
|
+
async processTexts(filePathOrBuffer, translations, outputPath) {
|
|
1447
1483
|
// Load the tree, apply translations, and save to new file
|
|
1448
|
-
const tree = this.loadIntoTree(filePathOrBuffer);
|
|
1484
|
+
const tree = await this.loadIntoTree(filePathOrBuffer);
|
|
1449
1485
|
// Apply translations to all text content
|
|
1450
1486
|
Object.values(tree.pages).forEach((page) => {
|
|
1451
1487
|
// Translate page names
|
|
@@ -1503,8 +1539,8 @@ class GridsetProcessor extends baseProcessor_1.BaseProcessor {
|
|
|
1503
1539
|
});
|
|
1504
1540
|
});
|
|
1505
1541
|
// Save the translated tree and return its content
|
|
1506
|
-
this.saveFromTree(tree, outputPath);
|
|
1507
|
-
return
|
|
1542
|
+
await this.saveFromTree(tree, outputPath);
|
|
1543
|
+
return (0, io_1.readBinaryFromInput)(outputPath);
|
|
1508
1544
|
}
|
|
1509
1545
|
/**
|
|
1510
1546
|
* Extract symbol information from a gridset for LLM-based translation.
|
|
@@ -1515,8 +1551,8 @@ class GridsetProcessor extends baseProcessor_1.BaseProcessor {
|
|
|
1515
1551
|
* @param filePathOrBuffer - Path to gridset file or buffer
|
|
1516
1552
|
* @returns Array of symbol information for LLM processing
|
|
1517
1553
|
*/
|
|
1518
|
-
extractSymbolsForLLM(filePathOrBuffer) {
|
|
1519
|
-
const tree = this.loadIntoTree(filePathOrBuffer);
|
|
1554
|
+
async extractSymbolsForLLM(filePathOrBuffer) {
|
|
1555
|
+
const tree = await this.loadIntoTree(filePathOrBuffer);
|
|
1520
1556
|
// Collect all buttons from all pages
|
|
1521
1557
|
const allButtons = [];
|
|
1522
1558
|
Object.values(tree.pages).forEach((page) => {
|
|
@@ -1545,8 +1581,8 @@ class GridsetProcessor extends baseProcessor_1.BaseProcessor {
|
|
|
1545
1581
|
* @param options - Translation options (e.g., allowPartial for testing)
|
|
1546
1582
|
* @returns Buffer of the translated gridset
|
|
1547
1583
|
*/
|
|
1548
|
-
processLLMTranslations(filePathOrBuffer, llmTranslations, outputPath, options) {
|
|
1549
|
-
const tree = this.loadIntoTree(filePathOrBuffer);
|
|
1584
|
+
async processLLMTranslations(filePathOrBuffer, llmTranslations, outputPath, options) {
|
|
1585
|
+
const tree = await this.loadIntoTree(filePathOrBuffer);
|
|
1550
1586
|
// Validate translations using shared utility
|
|
1551
1587
|
const buttonIds = Object.values(tree.pages).flatMap((page) => page.buttons.map((b) => b.id));
|
|
1552
1588
|
(0, translationProcessor_1.validateTranslationResults)(llmTranslations, buttonIds, options);
|
|
@@ -1583,14 +1619,17 @@ class GridsetProcessor extends baseProcessor_1.BaseProcessor {
|
|
|
1583
1619
|
});
|
|
1584
1620
|
});
|
|
1585
1621
|
// Save and return
|
|
1586
|
-
this.saveFromTree(tree, outputPath);
|
|
1587
|
-
return
|
|
1622
|
+
await this.saveFromTree(tree, outputPath);
|
|
1623
|
+
return (0, io_1.readBinaryFromInput)(outputPath);
|
|
1588
1624
|
}
|
|
1589
|
-
saveFromTree(tree, outputPath) {
|
|
1590
|
-
const
|
|
1625
|
+
async saveFromTree(tree, outputPath) {
|
|
1626
|
+
const JSZip = await getJSZip();
|
|
1627
|
+
const zip = new JSZip();
|
|
1591
1628
|
if (Object.keys(tree.pages).length === 0) {
|
|
1592
1629
|
// Create empty zip for empty tree
|
|
1593
|
-
zip.
|
|
1630
|
+
const zipBuffer = await zip.generateAsync({ type: 'uint8array' });
|
|
1631
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
1632
|
+
require('fs').writeFileSync(outputPath, zipBuffer);
|
|
1594
1633
|
return;
|
|
1595
1634
|
}
|
|
1596
1635
|
// Collect all unique styles from pages and buttons
|
|
@@ -1662,7 +1701,7 @@ class GridsetProcessor extends baseProcessor_1.BaseProcessor {
|
|
|
1662
1701
|
suppressEmptyNode: true,
|
|
1663
1702
|
});
|
|
1664
1703
|
const settingsXmlContent = settingsBuilder.build(settingsData);
|
|
1665
|
-
zip.
|
|
1704
|
+
zip.file('Settings0/settings.xml', settingsXmlContent, { binary: false });
|
|
1666
1705
|
// Create Settings0/Styles/style.xml if there are styles
|
|
1667
1706
|
if (uniqueStyles.size > 0) {
|
|
1668
1707
|
const stylesArray = Array.from(uniqueStyles.values()).map(({ id, style }) => {
|
|
@@ -1695,7 +1734,7 @@ class GridsetProcessor extends baseProcessor_1.BaseProcessor {
|
|
|
1695
1734
|
indentBy: ' ',
|
|
1696
1735
|
});
|
|
1697
1736
|
const styleXmlContent = styleBuilder.build(styleData);
|
|
1698
|
-
zip.
|
|
1737
|
+
zip.file('Settings0/Styles/styles.xml', styleXmlContent, { binary: false });
|
|
1699
1738
|
}
|
|
1700
1739
|
// Collect grid file paths for FileMap.xml
|
|
1701
1740
|
const gridFilePaths = [];
|
|
@@ -1778,8 +1817,8 @@ class GridsetProcessor extends baseProcessor_1.BaseProcessor {
|
|
|
1778
1817
|
}
|
|
1779
1818
|
}
|
|
1780
1819
|
const cellData = {
|
|
1781
|
-
'@_X': position.x, // Grid3 uses
|
|
1782
|
-
'@_Y': position.y + yOffset, // Grid3 uses
|
|
1820
|
+
'@_X': position.x + 1, // Grid3 uses 1-based X coordinates
|
|
1821
|
+
'@_Y': position.y + yOffset + 1, // Grid3 uses 1-based Y coordinates with workspace offset
|
|
1783
1822
|
'@_ColumnSpan': position.columnSpan,
|
|
1784
1823
|
'@_RowSpan': position.rowSpan,
|
|
1785
1824
|
Content: {
|
|
@@ -1834,16 +1873,16 @@ class GridsetProcessor extends baseProcessor_1.BaseProcessor {
|
|
|
1834
1873
|
});
|
|
1835
1874
|
const xmlContent = builder.build(gridData);
|
|
1836
1875
|
// Add to zip in Grids folder with proper Grid3 naming
|
|
1837
|
-
const gridPath = `Grids
|
|
1876
|
+
const gridPath = `Grids/${page.name || page.id}/grid.xml`;
|
|
1838
1877
|
gridFilePaths.push(gridPath);
|
|
1839
|
-
zip.
|
|
1878
|
+
zip.file(gridPath, xmlContent, { binary: false });
|
|
1840
1879
|
});
|
|
1841
1880
|
// Write image files to ZIP
|
|
1842
1881
|
buttonImages.forEach((imgData) => {
|
|
1843
1882
|
if (imgData.imageData && imgData.imageData.length > 0) {
|
|
1844
1883
|
// Create image path in the grid's directory
|
|
1845
|
-
const imagePath = `Grids
|
|
1846
|
-
zip.
|
|
1884
|
+
const imagePath = `Grids/${imgData.pageName}/${imgData.x}-${imgData.y}-0-text-0.${imgData.ext}`;
|
|
1885
|
+
zip.file(imagePath, imgData.imageData);
|
|
1847
1886
|
}
|
|
1848
1887
|
});
|
|
1849
1888
|
// Create FileMap.xml to map all grid files with their dynamic image files
|
|
@@ -1854,13 +1893,13 @@ class GridsetProcessor extends baseProcessor_1.BaseProcessor {
|
|
|
1854
1893
|
Entries: {
|
|
1855
1894
|
Entry: gridFilePaths.map((gridPath) => {
|
|
1856
1895
|
// Find all image files for this grid
|
|
1857
|
-
const gridName = gridPath.match(/Grids
|
|
1896
|
+
const gridName = gridPath.match(/Grids\/([^/]+)\/grid\.xml$/)?.[1] || '';
|
|
1858
1897
|
const imageFiles = [];
|
|
1859
1898
|
// Collect image filenames for buttons on this page
|
|
1860
|
-
// IMPORTANT: FileMap.xml requires full paths like "Grids
|
|
1899
|
+
// IMPORTANT: FileMap.xml requires full paths like "Grids/PageName/1-5-0-text-0.png"
|
|
1861
1900
|
buttonImages.forEach((imgData) => {
|
|
1862
1901
|
if (imgData.pageName === gridName && imgData.imageData.length > 0) {
|
|
1863
|
-
const imagePath = `Grids
|
|
1902
|
+
const imagePath = `Grids/${gridName}/${imgData.x}-${imgData.y}-0-text-0.${imgData.ext}`;
|
|
1864
1903
|
imageFiles.push(imagePath);
|
|
1865
1904
|
}
|
|
1866
1905
|
});
|
|
@@ -1882,9 +1921,11 @@ class GridsetProcessor extends baseProcessor_1.BaseProcessor {
|
|
|
1882
1921
|
indentBy: ' ',
|
|
1883
1922
|
});
|
|
1884
1923
|
const fileMapXmlContent = fileMapBuilder.build(fileMapData);
|
|
1885
|
-
zip.
|
|
1924
|
+
zip.file('FileMap.xml', fileMapXmlContent, { binary: false });
|
|
1886
1925
|
// Write the zip file
|
|
1887
|
-
zip.
|
|
1926
|
+
const zipBuffer = await zip.generateAsync({ type: 'uint8array' });
|
|
1927
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
1928
|
+
require('fs').writeFileSync(outputPath, zipBuffer);
|
|
1888
1929
|
}
|
|
1889
1930
|
// Helper method to calculate column definitions based on page layout
|
|
1890
1931
|
calculateColumnDefinitions(page) {
|
|
@@ -2,6 +2,7 @@ import { BaseProcessor, ProcessorOptions, ExtractStringsResult, TranslatedString
|
|
|
2
2
|
import { AACTree } from '../core/treeStructure';
|
|
3
3
|
import { ValidationResult } from '../validation/validationTypes';
|
|
4
4
|
import { type ButtonForTranslation, type LLMLTranslationResult } from '../utilities/translation/translationProcessor';
|
|
5
|
+
import { ProcessorInput } from '../utils/io';
|
|
5
6
|
declare class ObfProcessor extends BaseProcessor {
|
|
6
7
|
private zipFile?;
|
|
7
8
|
private imageCache;
|
|
@@ -16,12 +17,12 @@ declare class ObfProcessor extends BaseProcessor {
|
|
|
16
17
|
private extractImageAsDataUrl;
|
|
17
18
|
private getMimeTypeFromFilename;
|
|
18
19
|
private processBoard;
|
|
19
|
-
extractTexts(filePathOrBuffer:
|
|
20
|
-
loadIntoTree(filePathOrBuffer:
|
|
20
|
+
extractTexts(filePathOrBuffer: ProcessorInput): Promise<string[]>;
|
|
21
|
+
loadIntoTree(filePathOrBuffer: ProcessorInput): Promise<AACTree>;
|
|
21
22
|
private buildGridMetadata;
|
|
22
23
|
private createObfBoardFromPage;
|
|
23
|
-
processTexts(filePathOrBuffer:
|
|
24
|
-
saveFromTree(tree: AACTree, outputPath: string): void
|
|
24
|
+
processTexts(filePathOrBuffer: ProcessorInput, translations: Map<string, string>, outputPath: string): Promise<Uint8Array>;
|
|
25
|
+
saveFromTree(tree: AACTree, outputPath: string): Promise<void>;
|
|
25
26
|
/**
|
|
26
27
|
* Extract strings with metadata for aac-tools-platform compatibility
|
|
27
28
|
* Uses the generic implementation from BaseProcessor
|
|
@@ -47,7 +48,7 @@ declare class ObfProcessor extends BaseProcessor {
|
|
|
47
48
|
* @param filePathOrBuffer - Path to OBF/OBZ file or buffer
|
|
48
49
|
* @returns Array of symbol information for LLM processing
|
|
49
50
|
*/
|
|
50
|
-
extractSymbolsForLLM(filePathOrBuffer:
|
|
51
|
+
extractSymbolsForLLM(filePathOrBuffer: ProcessorInput): Promise<ButtonForTranslation[]>;
|
|
51
52
|
/**
|
|
52
53
|
* Apply LLM translations with symbol information.
|
|
53
54
|
* The LLM should provide translations with symbol attachments in the correct positions.
|
|
@@ -60,8 +61,9 @@ declare class ObfProcessor extends BaseProcessor {
|
|
|
60
61
|
* @param options - Translation options (e.g., allowPartial for testing)
|
|
61
62
|
* @returns Buffer of the translated OBF/OBZ file
|
|
62
63
|
*/
|
|
63
|
-
processLLMTranslations(filePathOrBuffer:
|
|
64
|
+
processLLMTranslations(filePathOrBuffer: ProcessorInput, llmTranslations: LLMLTranslationResult[], outputPath: string, options?: {
|
|
64
65
|
allowPartial?: boolean;
|
|
65
|
-
}):
|
|
66
|
+
}): Promise<Uint8Array>;
|
|
67
|
+
private getObfValidator;
|
|
66
68
|
}
|
|
67
69
|
export { ObfProcessor };
|