@willwade/aac-processors 0.0.30 β 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 +116 -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
package/README.md
CHANGED
|
@@ -1,896 +1,96 @@
|
|
|
1
1
|
# AACProcessors
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
[](https://opensource.org/licenses/MIT)
|
|
3
|
+
A TypeScript library for reading, analyzing, translating, and converting AAC
|
|
4
|
+
(Augmentative and Alternative Communication) file formats. The package ships
|
|
5
|
+
as a dual build: a full Node.js entry and a browser-safe entry.
|
|
7
6
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
## π Features
|
|
11
|
-
|
|
12
|
-
### **Multi-Format Support**
|
|
13
|
-
|
|
14
|
-
- **Snap/SPS** (Tobii Dynavox) - Full database support with audio
|
|
15
|
-
- **Grid3/Gridset** (Smartbox) - XML-based format processing
|
|
16
|
-
- **TouchChat** (PRC-Saltillo) - SQLite database handling
|
|
17
|
-
- **OBF/OBZ** (Open Board Format) - JSON and ZIP support
|
|
18
|
-
- **OPML** (Outline Processor Markup Language) - Hierarchical structures
|
|
19
|
-
- **DOT** (Graphviz) - Graph-based communication boards
|
|
20
|
-
- **Apple Panels** (MacOS) - Plist format support
|
|
21
|
-
- **Asterics Grid** - Native Asterics Grid format with audio
|
|
22
|
-
- **Excel** - Export to Microsoft Excel for vocabulary analysis
|
|
23
|
-
- **Analyics & Metrics** - High-parity AAC effort metrics and clinical analysis tools
|
|
24
|
-
|
|
25
|
-
### **Advanced Capabilities**
|
|
26
|
-
|
|
27
|
-
- π **Cross-format conversion** - Convert between any supported formats
|
|
28
|
-
- π **Translation workflows** - Built-in i18n support with `processTexts()`
|
|
29
|
-
- π¨ **Comprehensive styling support** - Preserve visual appearance across formats
|
|
30
|
-
- π§ͺ **Property-based testing** - Robust validation with 140+ tests
|
|
31
|
-
- β
**Format validation** - Spec-based validation for all supported formats
|
|
32
|
-
- π **Clinical Metrics** - High-parity AAC effort algorithm (v0.2) and vocabulary coverage analysis
|
|
33
|
-
- β‘ **Performance optimized** - Memory-efficient processing of large files
|
|
34
|
-
- π‘οΈ **Error recovery** - Graceful handling of corrupted data
|
|
35
|
-
- π **Thread-safe** - Concurrent processing support
|
|
36
|
-
- π **Comprehensive logging** - Detailed operation insights
|
|
37
|
-
|
|
38
|
-
---
|
|
39
|
-
|
|
40
|
-
## π¦ Installation
|
|
41
|
-
|
|
42
|
-
### From npm (Recommended)
|
|
7
|
+
## Install
|
|
43
8
|
|
|
44
9
|
```bash
|
|
45
10
|
npm install @willwade/aac-processors
|
|
46
11
|
```
|
|
47
12
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
```bash
|
|
51
|
-
git clone https://github.com/willwade/AACProcessors-nodejs.git
|
|
52
|
-
cd AACProcessors-nodejs
|
|
53
|
-
npm install
|
|
54
|
-
npm run build
|
|
55
|
-
```
|
|
56
|
-
|
|
57
|
-
### Requirements
|
|
58
|
-
|
|
59
|
-
- **Node.js** 20.0.0 or higher
|
|
60
|
-
- **TypeScript** 5.5+ (for development)
|
|
61
|
-
|
|
62
|
-
---
|
|
63
|
-
|
|
64
|
-
## Using with Electron
|
|
65
|
-
|
|
66
|
-
`better-sqlite3` is a native module and must be rebuilt against Electron's Node.js runtime. If you see a `NODE_MODULE_VERSION` mismatch error, rebuild after installing dependencies:
|
|
67
|
-
|
|
68
|
-
```bash
|
|
69
|
-
npm install
|
|
70
|
-
npx electron-rebuild
|
|
71
|
-
```
|
|
72
|
-
|
|
73
|
-
Or add a postinstall hook so the rebuild happens automatically:
|
|
74
|
-
|
|
75
|
-
```json
|
|
76
|
-
{
|
|
77
|
-
"scripts": {
|
|
78
|
-
"postinstall": "electron-builder install-app-deps"
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
```
|
|
82
|
-
|
|
83
|
-
This step is only required for Electron apps; regular Node.js consumers do not need it.
|
|
13
|
+
## Dual Build Targets
|
|
84
14
|
|
|
85
|
-
|
|
15
|
+
### Node.js (default)
|
|
16
|
+
Full feature set, including filesystem access, SQLite-backed formats, and
|
|
17
|
+
ZIP/encrypted formats.
|
|
86
18
|
|
|
87
|
-
|
|
19
|
+
```ts
|
|
20
|
+
import { getProcessor, SnapProcessor } from '@willwade/aac-processors';
|
|
88
21
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
- **Snap vocabularies**: `C:\Users\{username}\AppData\Roaming\Tobii Dynavox\Snap Scene\Users\{userId}\` (`.sps`/`.spb`)
|
|
22
|
+
const processor = getProcessor('board.sps');
|
|
23
|
+
const tree = await processor.loadIntoTree('board.sps');
|
|
92
24
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
## π§ Quick Start
|
|
96
|
-
|
|
97
|
-
### Basic Usage (TypeScript)
|
|
98
|
-
|
|
99
|
-
```typescript
|
|
100
|
-
import {
|
|
101
|
-
getProcessor,
|
|
102
|
-
DotProcessor,
|
|
103
|
-
SnapProcessor,
|
|
104
|
-
AstericsGridProcessor,
|
|
105
|
-
} from "aac-processors";
|
|
106
|
-
|
|
107
|
-
// Auto-detect processor by file extension
|
|
108
|
-
const processor = getProcessor("communication-board.dot");
|
|
109
|
-
const tree = processor.loadIntoTree("communication-board.dot");
|
|
110
|
-
|
|
111
|
-
// Extract all text content
|
|
112
|
-
const texts = processor.extractTexts("communication-board.dot");
|
|
113
|
-
console.log("Found texts:", texts);
|
|
114
|
-
|
|
115
|
-
// Direct processor usage
|
|
116
|
-
const dotProcessor = new DotProcessor();
|
|
117
|
-
const aacTree = dotProcessor.loadIntoTree("examples/example.dot");
|
|
118
|
-
console.log("Pages:", Object.keys(aacTree.pages).length);
|
|
25
|
+
const snap = new SnapProcessor();
|
|
26
|
+
const texts = await snap.extractTexts('board.sps');
|
|
119
27
|
```
|
|
120
28
|
|
|
121
|
-
###
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
- **File system access** - Required for reading/writing AAC files
|
|
126
|
-
- **Native SQLite** - Used by Snap, TouchChat, and Analytics features
|
|
127
|
-
- **Binary format processing** - ZIP, encrypted formats, etc.
|
|
29
|
+
### Browser
|
|
30
|
+
Browser-safe entry that avoids Node-only dependencies. It expects `Buffer`,
|
|
31
|
+
`Uint8Array`, or `ArrayBuffer` inputs rather than file paths.
|
|
128
32
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
- **Arc Core** - Browser-based AAC communication
|
|
132
|
-
- **Cboard** - Web-based AAC display system
|
|
33
|
+
```ts
|
|
34
|
+
import { GridsetProcessor } from '@willwade/aac-processors/browser';
|
|
133
35
|
|
|
134
|
-
This library focuses on **server-side file processing**, not client-side rendering.
|
|
135
|
-
|
|
136
|
-
### Button Filtering System
|
|
137
|
-
|
|
138
|
-
AACProcessors includes an intelligent filtering system to handle navigation bars and system buttons that are common in AAC applications but may not be appropriate when converting between formats.
|
|
139
|
-
|
|
140
|
-
#### **Default Behavior**
|
|
141
|
-
|
|
142
|
-
By default, the following buttons are filtered out during conversion:
|
|
143
|
-
|
|
144
|
-
- **Navigation buttons**: Home, Back (toolbar navigation)
|
|
145
|
-
- **System buttons**: Delete, Clear, Copy (text editing functions)
|
|
146
|
-
- **Label-based filtering**: Buttons with common navigation terms
|
|
147
|
-
|
|
148
|
-
#### **Configuration Options**
|
|
149
|
-
|
|
150
|
-
```typescript
|
|
151
|
-
import { GridsetProcessor } from "aac-processors";
|
|
152
|
-
|
|
153
|
-
// Default: exclude navigation/system buttons (recommended)
|
|
154
36
|
const processor = new GridsetProcessor();
|
|
155
|
-
|
|
156
|
-
// Preserve all buttons (legacy behavior)
|
|
157
|
-
const processor = new GridsetProcessor({ preserveAllButtons: true });
|
|
158
|
-
|
|
159
|
-
// Custom filtering
|
|
160
|
-
const processor = new GridsetProcessor({
|
|
161
|
-
excludeNavigationButtons: true,
|
|
162
|
-
excludeSystemButtons: false,
|
|
163
|
-
customButtonFilter: (button) => !button.label.includes("Settings"),
|
|
164
|
-
});
|
|
37
|
+
const tree = await processor.loadIntoTree(gridsetUint8Array);
|
|
165
38
|
```
|
|
166
39
|
|
|
167
|
-
|
|
40
|
+
## Supported Formats
|
|
168
41
|
|
|
169
|
-
-
|
|
170
|
-
-
|
|
171
|
-
-
|
|
42
|
+
- Snap/SPS (Tobii Dynavox)
|
|
43
|
+
- Grid3/Gridset (Smartbox)
|
|
44
|
+
- TouchChat (PRC-Saltillo)
|
|
45
|
+
- OBF/OBZ (Open Board Format)
|
|
46
|
+
- OPML
|
|
47
|
+
- DOT (Graphviz)
|
|
48
|
+
- Apple Panels (macOS plist)
|
|
49
|
+
- Asterics Grid
|
|
50
|
+
- Excel export
|
|
172
51
|
|
|
173
|
-
|
|
52
|
+
## Translation Workflow
|
|
174
53
|
|
|
175
|
-
All processors
|
|
54
|
+
All processors implement `processTexts()` for translation use cases.
|
|
176
55
|
|
|
177
|
-
```
|
|
178
|
-
import { DotProcessor } from
|
|
56
|
+
```ts
|
|
57
|
+
import { DotProcessor } from '@willwade/aac-processors';
|
|
179
58
|
|
|
180
59
|
const processor = new DotProcessor();
|
|
60
|
+
const texts = await processor.extractTexts('board.dot');
|
|
181
61
|
|
|
182
|
-
// 1. Extract all translatable text
|
|
183
|
-
const originalTexts = processor.extractTexts("board.dot");
|
|
184
|
-
|
|
185
|
-
// 2. Create translation map (integrate with your translation service)
|
|
186
62
|
const translations = new Map([
|
|
187
|
-
[
|
|
188
|
-
[
|
|
189
|
-
["Food", "Comida"],
|
|
63
|
+
['Hello', 'Hola'],
|
|
64
|
+
['Food', 'Comida'],
|
|
190
65
|
]);
|
|
191
66
|
|
|
192
|
-
|
|
193
|
-
const translatedBuffer = processor.processTexts(
|
|
194
|
-
"board.dot",
|
|
195
|
-
translations,
|
|
196
|
-
"board-spanish.dot",
|
|
197
|
-
);
|
|
198
|
-
|
|
199
|
-
console.log("Translation complete!");
|
|
200
|
-
```
|
|
201
|
-
|
|
202
|
-
### π€ LLM-Based Translation with Symbol Preservation
|
|
203
|
-
|
|
204
|
-
For advanced AI-powered translation that preserves symbol-to-word associations across languages, see the **[Translation Utilities Guide](./src/utilities/translation/README.md)**.
|
|
205
|
-
|
|
206
|
-
**Features:**
|
|
207
|
-
- π§ **Intelligent symbol mapping**: LLMs understand grammar, not just word position
|
|
208
|
-
- π― **Cross-format support**: Works with Gridset, OBF/OBZ, TouchChat, and Snap
|
|
209
|
-
- π **Symbol preservation**: Symbols stay attached to correct translated words
|
|
210
|
-
- β
**Validated output**: Built-in validation catches translation errors
|
|
211
|
-
|
|
212
|
-
**Quick Demo:**
|
|
213
|
-
```bash
|
|
214
|
-
# Translate a Grid 3 file to Spanish using Gemini 2.0 Flash
|
|
215
|
-
export GEMINI_API_KEY="your-key-here"
|
|
216
|
-
node scripts/translation/gemini-translate-gridset.js "./tmp/Voco Chat.gridset" Spanish
|
|
217
|
-
```
|
|
218
|
-
|
|
219
|
-
**Complete Example:**
|
|
220
|
-
```typescript
|
|
221
|
-
import { GridsetProcessor } from "@willwade/aac-processors";
|
|
222
|
-
|
|
223
|
-
const processor = new GridsetProcessor();
|
|
224
|
-
|
|
225
|
-
// 1. Extract buttons with symbol information
|
|
226
|
-
const buttons = processor.extractSymbolsForLLM("board.gridset");
|
|
227
|
-
|
|
228
|
-
// 2. Create LLM prompt (or call your LLM API directly)
|
|
229
|
-
// See: src/utilities/translation/README.md
|
|
230
|
-
|
|
231
|
-
// 3. Apply translations with preserved symbols
|
|
232
|
-
processor.processLLMTranslations(
|
|
233
|
-
"board.gridset",
|
|
234
|
-
llmTranslations,
|
|
235
|
-
"board-spanish.gridset"
|
|
236
|
-
);
|
|
237
|
-
```
|
|
238
|
-
|
|
239
|
-
See **[scripts/translation/](./scripts/translation/)** for complete working examples with Gemini, GPT-4, and other LLMs.
|
|
240
|
-
|
|
241
|
-
### π AAC Analytics & Clinical Metrics
|
|
242
|
-
|
|
243
|
-
The library includes an optional high-performance analytics engine for evaluating AAC board sets based on the **AAC Effort Algorithm (v0.2)**.
|
|
244
|
-
|
|
245
|
-
#### **Key Metrics Features**
|
|
246
|
-
|
|
247
|
-
- **Effort Scores**: Calculate the physical/cognitive cost of any word (Distance, Field Size, Motor Planning).
|
|
248
|
-
- **Vocabulary Coverage**: Compare board sets against core vocabulary lists (e.g., Anderson & Bitner).
|
|
249
|
-
- **Sentence Analysis**: Measure the effort required to construct common test sentences.
|
|
250
|
-
- **Comparative Analysis**: Identify gaps and improvements between two pageset versions.
|
|
251
|
-
|
|
252
|
-
For detailed documentation, see the **[AAC Metrics Guide](./src/utilities/analytics/docs/AAC_METRICS_GUIDE.md)** and **[Vocabulary Analysis Guide](./src/utilities/analytics/docs/VOCABULARY_ANALYSIS_GUIDE.md)**.
|
|
253
|
-
|
|
254
|
-
```typescript
|
|
255
|
-
import { ObfsetProcessor, Analytics } from "@willwade/aac-processors";
|
|
256
|
-
|
|
257
|
-
const processor = new ObfsetProcessor();
|
|
258
|
-
const tree = processor.loadIntoTree("my_pageset.obfset");
|
|
259
|
-
|
|
260
|
-
// Run clinical effort analysis
|
|
261
|
-
const result = new Analytics.MetricsCalculator().analyze(tree);
|
|
262
|
-
console.log(`Average Effort: ${result.total_words}`);
|
|
67
|
+
await processor.processTexts('board.dot', translations, 'board-es.dot');
|
|
263
68
|
```
|
|
264
69
|
|
|
265
|
-
|
|
70
|
+
## Documentation
|
|
266
71
|
|
|
267
|
-
|
|
72
|
+
- API reference (TypeDoc): https://willwade.github.io/AACProcessors-nodejs/
|
|
73
|
+
- Metrics guide: `src/utilities/analytics/docs/AAC_METRICS_GUIDE.md`
|
|
74
|
+
- Vocabulary analysis guide: `src/utilities/analytics/docs/VOCABULARY_ANALYSIS_GUIDE.md`
|
|
268
75
|
|
|
269
|
-
|
|
270
|
-
import { validateFileOrBuffer, getValidatorForFile } from "@willwade/aac-processors/validation";
|
|
76
|
+
## Examples and Scripts
|
|
271
77
|
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
const validator = getValidatorForFile(fileName);
|
|
275
|
-
const bufferOrPath = new Uint8Array(await file.arrayBuffer()); // or fs path in Node
|
|
276
|
-
const result = await validateFileOrBuffer(bufferOrPath, fileName);
|
|
78
|
+
- Code examples: `examples/`
|
|
79
|
+
- Utility scripts and workflows: `scripts/` (see `scripts/README.md`)
|
|
277
80
|
|
|
278
|
-
|
|
279
|
-
result.results.forEach((check) => {
|
|
280
|
-
if (!check.valid) console.log(`β ${check.description}: ${check.error}`);
|
|
281
|
-
});
|
|
282
|
-
```
|
|
283
|
-
|
|
284
|
-
#### Using the CLI
|
|
81
|
+
## Build, Lint, Test
|
|
285
82
|
|
|
286
83
|
```bash
|
|
287
|
-
|
|
288
|
-
aacprocessors validate board.obf
|
|
289
|
-
|
|
290
|
-
# JSON output
|
|
291
|
-
aacprocessors validate board.obf --json
|
|
292
|
-
|
|
293
|
-
# Quiet mode (just valid/invalid)
|
|
294
|
-
aacprocessors validate board.gridset --quiet
|
|
295
|
-
|
|
296
|
-
# Validate encrypted Gridset file
|
|
297
|
-
aacprocessors validate board.gridsetx --gridset-password <password>
|
|
298
|
-
```
|
|
299
|
-
|
|
300
|
-
#### What Gets Validated?
|
|
301
|
-
|
|
302
|
-
- **OBF/OBZ**: Spec compliance (Open Board Format)
|
|
303
|
-
- **Gridset/Gridsetx**: ZIP/XML structure, required Smartbox assets
|
|
304
|
-
- **Snap**: ZIP/package content, settings/pages/images
|
|
305
|
-
- **TouchChat**: ZIP structure, vocab metadata, nested boards
|
|
306
|
-
- **Asterics (.grd)**: JSON parse, grids, elements, coordinates
|
|
307
|
-
- **Excel (.xlsx/.xls)**: Workbook readability and worksheet content
|
|
308
|
-
- **OPML**: XML validity and outline hierarchy
|
|
309
|
-
- **DOT**: Graph nodes/edges present and text content
|
|
310
|
-
- **Apple Panels (.plist/.ascconfig)**: PanelDefinitions presence and buttons
|
|
311
|
-
- **OBFSet**: Bundled board layout checks
|
|
312
|
-
|
|
313
|
-
- **Gridset**: XML structure
|
|
314
|
-
- Required elements (gridset, pages, cells)
|
|
315
|
-
- FixedCellSize configuration
|
|
316
|
-
- Page and cell attributes
|
|
317
|
-
- Image references
|
|
318
|
-
|
|
319
|
-
- **Snap**: Package structure
|
|
320
|
-
- ZIP package validity
|
|
321
|
-
- Settings file format
|
|
322
|
-
- Page/button configurations
|
|
323
|
-
|
|
324
|
-
- **TouchChat**: XML structure
|
|
325
|
-
- PageSet hierarchy
|
|
326
|
-
- Button definitions
|
|
327
|
-
- Navigation links
|
|
328
|
-
|
|
329
|
-
### Cross-Format Conversion
|
|
330
|
-
|
|
331
|
-
Convert between any supported AAC formats:
|
|
332
|
-
|
|
333
|
-
```typescript
|
|
334
|
-
import { DotProcessor, ObfProcessor } from "aac-processors";
|
|
335
|
-
|
|
336
|
-
// Load from DOT format
|
|
337
|
-
const dotProcessor = new DotProcessor();
|
|
338
|
-
const tree = dotProcessor.loadIntoTree("communication-board.dot");
|
|
339
|
-
|
|
340
|
-
// Save as OBF format
|
|
341
|
-
const obfProcessor = new ObfProcessor();
|
|
342
|
-
obfProcessor.saveFromTree(tree, "communication-board.obf");
|
|
343
|
-
|
|
344
|
-
// The tree structure is preserved across formats
|
|
345
|
-
console.log("Conversion complete!");
|
|
346
|
-
```
|
|
347
|
-
|
|
348
|
-
### Advanced Usage
|
|
349
|
-
|
|
350
|
-
#### Asterics Grid with Audio Support
|
|
351
|
-
|
|
352
|
-
```typescript
|
|
353
|
-
import { AstericsGridProcessor } from "aac-processors";
|
|
354
|
-
|
|
355
|
-
// Load Asterics Grid file with audio support
|
|
356
|
-
const processor = new AstericsGridProcessor({ loadAudio: true });
|
|
357
|
-
const tree = processor.loadIntoTree("communication-board.grd");
|
|
358
|
-
|
|
359
|
-
// Access audio recordings from buttons
|
|
360
|
-
tree.traverse((page) => {
|
|
361
|
-
page.buttons.forEach((button) => {
|
|
362
|
-
if (button.audioRecording) {
|
|
363
|
-
console.log(`Button "${button.label}" has audio recording`);
|
|
364
|
-
console.log(
|
|
365
|
-
`Audio data size: ${button.audioRecording.data?.length} bytes`,
|
|
366
|
-
);
|
|
367
|
-
}
|
|
368
|
-
});
|
|
369
|
-
});
|
|
370
|
-
|
|
371
|
-
// Add audio to specific elements
|
|
372
|
-
const audioData = Buffer.from(/* your audio data */);
|
|
373
|
-
processor.addAudioToElement(
|
|
374
|
-
"board.grd",
|
|
375
|
-
"element-id",
|
|
376
|
-
audioData,
|
|
377
|
-
JSON.stringify({ mimeType: "audio/wav", durationMs: 2000 }),
|
|
378
|
-
);
|
|
379
|
-
|
|
380
|
-
// Create enhanced version with multiple audio recordings
|
|
381
|
-
const audioMappings = new Map();
|
|
382
|
-
audioMappings.set("element-1", { audioData: audioBuffer1 });
|
|
383
|
-
audioMappings.set("element-2", { audioData: audioBuffer2 });
|
|
384
|
-
processor.createAudioEnhancedGridFile(
|
|
385
|
-
"source.grd",
|
|
386
|
-
"enhanced.grd",
|
|
387
|
-
audioMappings,
|
|
388
|
-
);
|
|
389
|
-
```
|
|
390
|
-
|
|
391
|
-
#### Excel Export for Vocabulary Analysis
|
|
392
|
-
|
|
393
|
-
```typescript
|
|
394
|
-
import { ExcelProcessor, getProcessor } from "aac-processors";
|
|
395
|
-
|
|
396
|
-
// Convert any AAC format to Excel for analysis
|
|
397
|
-
const sourceProcessor = getProcessor("communication-board.gridset");
|
|
398
|
-
const tree = sourceProcessor.loadIntoTree("communication-board.gridset");
|
|
399
|
-
|
|
400
|
-
// Export to Excel with visual styling and navigation
|
|
401
|
-
const excelProcessor = new ExcelProcessor();
|
|
402
|
-
excelProcessor.saveFromTree(tree, "vocabulary-analysis.xlsx");
|
|
403
|
-
|
|
404
|
-
// Each AAC page becomes an Excel worksheet tab
|
|
405
|
-
// Buttons are represented as cells with:
|
|
406
|
-
// - Cell value = button label
|
|
407
|
-
// - Cell background = button background color
|
|
408
|
-
// - Cell font color = button font color
|
|
409
|
-
// - Cell comments = button message/vocalization
|
|
410
|
-
// - Hyperlinks for navigation between worksheets
|
|
411
|
-
|
|
412
|
-
// Optional: Navigation row with standard AAC buttons
|
|
413
|
-
// (Home, Message Bar, Delete, Back, Clear) appears on each worksheet
|
|
414
|
-
```
|
|
415
|
-
|
|
416
|
-
#### Working with the AACTree Structure
|
|
417
|
-
|
|
418
|
-
```typescript
|
|
419
|
-
import { AACTree, AACPage, AACButton } from "aac-processors";
|
|
420
|
-
|
|
421
|
-
// Create a communication board programmatically
|
|
422
|
-
const tree = new AACTree();
|
|
423
|
-
|
|
424
|
-
const homePage = new AACPage({
|
|
425
|
-
id: "home",
|
|
426
|
-
name: "Home Page",
|
|
427
|
-
buttons: [],
|
|
428
|
-
});
|
|
429
|
-
|
|
430
|
-
const helloButton = new AACButton({
|
|
431
|
-
id: "btn_hello",
|
|
432
|
-
label: "Hello",
|
|
433
|
-
message: "Hello, how are you?",
|
|
434
|
-
type: "SPEAK",
|
|
435
|
-
});
|
|
436
|
-
|
|
437
|
-
const foodButton = new AACButton({
|
|
438
|
-
id: "btn_food",
|
|
439
|
-
label: "Food",
|
|
440
|
-
message: "I want food",
|
|
441
|
-
type: "NAVIGATE",
|
|
442
|
-
targetPageId: "food_page",
|
|
443
|
-
});
|
|
444
|
-
|
|
445
|
-
homePage.addButton(helloButton);
|
|
446
|
-
homePage.addButton(foodButton);
|
|
447
|
-
tree.addPage(homePage);
|
|
448
|
-
|
|
449
|
-
// Save to any format
|
|
450
|
-
const processor = new DotProcessor();
|
|
451
|
-
processor.saveFromTree(tree, "my-board.dot");
|
|
452
|
-
```
|
|
453
|
-
|
|
454
|
-
#### Error Handling
|
|
455
|
-
|
|
456
|
-
```typescript
|
|
457
|
-
import { DotProcessor } from "aac-processors";
|
|
458
|
-
|
|
459
|
-
const processor = new DotProcessor();
|
|
460
|
-
|
|
461
|
-
try {
|
|
462
|
-
const tree = processor.loadIntoTree("potentially-corrupted.dot");
|
|
463
|
-
console.log("Successfully loaded:", Object.keys(tree.pages).length, "pages");
|
|
464
|
-
} catch (error) {
|
|
465
|
-
console.error("Failed to load file:", error.message);
|
|
466
|
-
// Processor handles corruption gracefully and provides meaningful errors
|
|
467
|
-
}
|
|
468
|
-
```
|
|
469
|
-
|
|
470
|
-
### Styling Support
|
|
471
|
-
|
|
472
|
-
The library now provides comprehensive styling support across all AAC formats, preserving visual appearance when converting between formats.
|
|
473
|
-
|
|
474
|
-
#### Supported Styling Properties
|
|
475
|
-
|
|
476
|
-
```typescript
|
|
477
|
-
interface AACStyle {
|
|
478
|
-
backgroundColor?: string; // Button/page background color
|
|
479
|
-
fontColor?: string; // Text color
|
|
480
|
-
borderColor?: string; // Border color
|
|
481
|
-
borderWidth?: number; // Border thickness
|
|
482
|
-
fontSize?: number; // Font size in pixels
|
|
483
|
-
fontFamily?: string; // Font family name
|
|
484
|
-
fontWeight?: string; // "normal" | "bold"
|
|
485
|
-
fontStyle?: string; // "normal" | "italic"
|
|
486
|
-
textUnderline?: boolean; // Text underline
|
|
487
|
-
labelOnTop?: boolean; // Label position (TouchChat)
|
|
488
|
-
transparent?: boolean; // Transparent background
|
|
489
|
-
}
|
|
490
|
-
```
|
|
491
|
-
|
|
492
|
-
#### Creating Styled AAC Content
|
|
493
|
-
|
|
494
|
-
```typescript
|
|
495
|
-
import { AACTree, AACPage, AACButton } from "aac-processors";
|
|
496
|
-
|
|
497
|
-
// Create a page with styling
|
|
498
|
-
const page = new AACPage({
|
|
499
|
-
id: "main-page",
|
|
500
|
-
name: "Main Communication Board",
|
|
501
|
-
grid: [],
|
|
502
|
-
buttons: [],
|
|
503
|
-
parentId: null,
|
|
504
|
-
style: {
|
|
505
|
-
backgroundColor: "#f0f8ff",
|
|
506
|
-
fontFamily: "Arial",
|
|
507
|
-
fontSize: 16,
|
|
508
|
-
},
|
|
509
|
-
});
|
|
510
|
-
|
|
511
|
-
// Create buttons with comprehensive styling
|
|
512
|
-
const speakButton = new AACButton({
|
|
513
|
-
id: "speak-btn-1",
|
|
514
|
-
label: "Hello",
|
|
515
|
-
message: "Hello, how are you?",
|
|
516
|
-
type: "SPEAK",
|
|
517
|
-
action: null,
|
|
518
|
-
style: {
|
|
519
|
-
backgroundColor: "#4CAF50",
|
|
520
|
-
fontColor: "#ffffff",
|
|
521
|
-
borderColor: "#45a049",
|
|
522
|
-
borderWidth: 2,
|
|
523
|
-
fontSize: 18,
|
|
524
|
-
fontFamily: "Helvetica",
|
|
525
|
-
fontWeight: "bold",
|
|
526
|
-
labelOnTop: true,
|
|
527
|
-
},
|
|
528
|
-
});
|
|
529
|
-
|
|
530
|
-
const navButton = new AACButton({
|
|
531
|
-
id: "nav-btn-1",
|
|
532
|
-
label: "More",
|
|
533
|
-
message: "Navigate to more options",
|
|
534
|
-
type: "NAVIGATE",
|
|
535
|
-
targetPageId: "more-page",
|
|
536
|
-
action: {
|
|
537
|
-
type: "NAVIGATE",
|
|
538
|
-
targetPageId: "more-page",
|
|
539
|
-
},
|
|
540
|
-
style: {
|
|
541
|
-
backgroundColor: "#2196F3",
|
|
542
|
-
fontColor: "#ffffff",
|
|
543
|
-
borderColor: "#1976D2",
|
|
544
|
-
borderWidth: 1,
|
|
545
|
-
fontSize: 16,
|
|
546
|
-
fontStyle: "italic",
|
|
547
|
-
transparent: false,
|
|
548
|
-
},
|
|
549
|
-
});
|
|
550
|
-
|
|
551
|
-
page.addButton(speakButton);
|
|
552
|
-
page.addButton(navButton);
|
|
553
|
-
|
|
554
|
-
const tree = new AACTree();
|
|
555
|
-
tree.addPage(page);
|
|
556
|
-
|
|
557
|
-
// Save with styling preserved
|
|
558
|
-
import { SnapProcessor } from "aac-processors";
|
|
559
|
-
const processor = new SnapProcessor();
|
|
560
|
-
processor.saveFromTree(tree, "styled-board.spb");
|
|
561
|
-
```
|
|
562
|
-
|
|
563
|
-
#### Format-Specific Styling Support
|
|
564
|
-
|
|
565
|
-
| Format | Background | Font | Border | Advanced |
|
|
566
|
-
| ----------------- | ---------- | ------------ | ------- | ------------------------------- |
|
|
567
|
-
| **Snap/SPS** | β
Full | β
Full | β
Full | β
All properties |
|
|
568
|
-
| **TouchChat** | β
Full | β
Full | β
Full | β
Label position, transparency |
|
|
569
|
-
| **OBF/OBZ** | β
Yes | β No | β
Yes | β Basic only |
|
|
570
|
-
| **Grid3** | β
Yes | β
Yes | β
Yes | β
Style references |
|
|
571
|
-
| **Asterics Grid** | β
Yes | β
Yes | β
Yes | β
Metadata-based |
|
|
572
|
-
| **Apple Panels** | β
Yes | β
Size only | β No | β
Display weight |
|
|
573
|
-
| **Dot** | βNo | β Yes | β No | β Basic only |
|
|
574
|
-
| **OPML** | βNo | β Yes | β No | β Basic only |
|
|
575
|
-
| **Excel** | β
Yes | β
Size only | β No | β
Display weight |
|
|
576
|
-
|
|
577
|
-
#### Cross-Format Styling Conversion
|
|
578
|
-
|
|
579
|
-
```typescript
|
|
580
|
-
import { getProcessor } from "aac-processors";
|
|
581
|
-
|
|
582
|
-
// Load styled content from TouchChat
|
|
583
|
-
const touchChatProcessor = getProcessor("input.ce");
|
|
584
|
-
const styledTree = touchChatProcessor.loadIntoTree("input.ce");
|
|
585
|
-
|
|
586
|
-
// Convert to Snap format while preserving styling
|
|
587
|
-
const snapProcessor = getProcessor("output.spb");
|
|
588
|
-
snapProcessor.saveFromTree(styledTree, "output.spb");
|
|
589
|
-
|
|
590
|
-
// Styling information is automatically mapped between formats
|
|
591
|
-
console.log("Styling preserved across formats!");
|
|
592
|
-
```
|
|
593
|
-
|
|
594
|
-
### CLI Usage
|
|
595
|
-
|
|
596
|
-
The CLI provides three main commands for working with AAC files:
|
|
597
|
-
|
|
598
|
-
#### **Extract Text Content**
|
|
599
|
-
|
|
600
|
-
```bash
|
|
601
|
-
# Extract all text from an AAC file
|
|
602
|
-
npx aac-processors extract examples/example.dot
|
|
603
|
-
|
|
604
|
-
# With format specification and verbose output
|
|
605
|
-
npx aac-processors extract examples/example.sps --format snap --verbose
|
|
606
|
-
```
|
|
607
|
-
|
|
608
|
-
#### **Convert Between Formats**
|
|
609
|
-
|
|
610
|
-
```bash
|
|
611
|
-
# Convert from one format to another (format auto-detected from input extension)
|
|
612
|
-
npx aac-processors convert input.sps output.obf --format obf
|
|
613
|
-
|
|
614
|
-
# Convert TouchChat to Snap format
|
|
615
|
-
npx aac-processors convert communication.ce backup.spb --format snap
|
|
616
|
-
|
|
617
|
-
# Convert any AAC format to Excel for vocabulary analysis
|
|
618
|
-
npx aac-processors convert input.gridset vocabulary-analysis.xlsx --format xlsx
|
|
619
|
-
|
|
620
|
-
# Convert with button filtering options
|
|
621
|
-
npx aac-processors convert input.gridset output.grd --format grd --preserve-all-buttons
|
|
622
|
-
npx aac-processors convert input.ce output.spb --format snap --exclude-buttons "settings,menu"
|
|
623
|
-
npx aac-processors convert input.obf output.gridset --format gridset --no-exclude-system
|
|
624
|
-
```
|
|
625
|
-
|
|
626
|
-
#### **Analyze File Structure**
|
|
627
|
-
|
|
628
|
-
```bash
|
|
629
|
-
# Get detailed file information in JSON format
|
|
630
|
-
npx aac-processors analyze examples/example.ce
|
|
631
|
-
|
|
632
|
-
# Get human-readable file information
|
|
633
|
-
npx aac-processors analyze examples/example.gridset --pretty
|
|
634
|
-
```
|
|
635
|
-
|
|
636
|
-
#### **Available Options**
|
|
637
|
-
|
|
638
|
-
**General Options:**
|
|
639
|
-
|
|
640
|
-
- `--format <format>` - Specify format type (auto-detected if not provided)
|
|
641
|
-
- `--pretty` - Human-readable output (analyze command)
|
|
642
|
-
- `--verbose` - Detailed output (extract command)
|
|
643
|
-
- `--quiet` - Minimal output (extract command)
|
|
644
|
-
- `--gridset-password <password>` - Password for encrypted Grid 3 archives (`.gridsetx`)
|
|
645
|
-
|
|
646
|
-
**Button Filtering Options:**
|
|
647
|
-
|
|
648
|
-
- `--preserve-all-buttons` - Preserve all buttons including navigation/system buttons
|
|
649
|
-
- `--no-exclude-navigation` - Don't exclude navigation buttons (Home, Back)
|
|
650
|
-
- `--no-exclude-system` - Don't exclude system buttons (Delete, Clear, etc.)
|
|
651
|
-
- `--exclude-buttons <list>` - Comma-separated list of button labels/terms to exclude
|
|
652
|
-
|
|
653
|
-
**Examples:**
|
|
654
|
-
|
|
655
|
-
```bash
|
|
656
|
-
# Extract text with all buttons preserved
|
|
657
|
-
npx aac-processors extract input.ce --preserve-all-buttons --verbose
|
|
658
|
-
|
|
659
|
-
# Convert excluding only custom buttons
|
|
660
|
-
npx aac-processors convert input.gridset output.grd --format grd --exclude-buttons "settings,help,menu"
|
|
661
|
-
|
|
662
|
-
# Analyze with navigation buttons excluded but system buttons preserved
|
|
663
|
-
npx aac-processors analyze input.spb --no-exclude-system --pretty
|
|
664
|
-
```
|
|
665
|
-
|
|
666
|
-
---
|
|
667
|
-
|
|
668
|
-
## π API Reference
|
|
669
|
-
|
|
670
|
-
### Core Classes
|
|
671
|
-
|
|
672
|
-
#### `getProcessor(filePathOrExtension: string): BaseProcessor`
|
|
673
|
-
|
|
674
|
-
Factory function that returns the appropriate processor for a file extension.
|
|
675
|
-
|
|
676
|
-
```typescript
|
|
677
|
-
const processor = getProcessor(".dot"); // Returns DotProcessor
|
|
678
|
-
const processor2 = getProcessor("file.obf"); // Returns ObfProcessor
|
|
679
|
-
```
|
|
680
|
-
|
|
681
|
-
#### `BaseProcessor`
|
|
682
|
-
|
|
683
|
-
Abstract base class for all processors with these key methods:
|
|
684
|
-
|
|
685
|
-
- `loadIntoTree(filePathOrBuffer: string | Buffer): AACTree` - Load file into tree structure
|
|
686
|
-
- `saveFromTree(tree: AACTree, outputPath: string): void` - Save tree to file
|
|
687
|
-
- `extractTexts(filePathOrBuffer: string | Buffer): string[]` - Extract all text content
|
|
688
|
-
- `processTexts(input: string | Buffer, translations: Map<string, string>, outputPath: string): Buffer` - Apply translations
|
|
689
|
-
|
|
690
|
-
#### `AACTree`
|
|
691
|
-
|
|
692
|
-
Core data structure representing a communication board:
|
|
693
|
-
|
|
694
|
-
```typescript
|
|
695
|
-
interface AACTree {
|
|
696
|
-
pages: Record<string, AACPage>;
|
|
697
|
-
rootId?: string;
|
|
698
|
-
addPage(page: AACPage): void;
|
|
699
|
-
traverse(callback: (page: AACPage) => void): void;
|
|
700
|
-
}
|
|
701
|
-
```
|
|
702
|
-
|
|
703
|
-
#### `AACPage`
|
|
704
|
-
|
|
705
|
-
Represents a single page/screen in a communication board:
|
|
706
|
-
|
|
707
|
-
```typescript
|
|
708
|
-
interface AACPage {
|
|
709
|
-
id: string;
|
|
710
|
-
name: string;
|
|
711
|
-
buttons: AACButton[];
|
|
712
|
-
parentId?: string;
|
|
713
|
-
addButton(button: AACButton): void;
|
|
714
|
-
}
|
|
715
|
-
```
|
|
716
|
-
|
|
717
|
-
#### `AACButton`
|
|
718
|
-
|
|
719
|
-
Represents a button/cell in a communication board:
|
|
720
|
-
|
|
721
|
-
```typescript
|
|
722
|
-
interface AACButton {
|
|
723
|
-
id: string;
|
|
724
|
-
label: string;
|
|
725
|
-
message?: string;
|
|
726
|
-
type: "SPEAK" | "NAVIGATE";
|
|
727
|
-
targetPageId?: string; // For navigation buttons
|
|
728
|
-
}
|
|
729
|
-
```
|
|
730
|
-
|
|
731
|
-
### Supported Processors
|
|
732
|
-
|
|
733
|
-
| Processor | File Extensions | Description |
|
|
734
|
-
| ----------------------- | ----------------------- | ----------------------------- |
|
|
735
|
-
| `DotProcessor` | `.dot` | Graphviz DOT format |
|
|
736
|
-
| `OpmlProcessor` | `.opml` | OPML hierarchical format |
|
|
737
|
-
| `ObfProcessor` | `.obf`, `.obz` | Open Board Format (JSON/ZIP) |
|
|
738
|
-
| `SnapProcessor` | `.sps`, `.spb` | Tobii Dynavox Snap format |
|
|
739
|
-
| `GridsetProcessor` | `.gridset`, `.gridsetx` | Smartbox Grid 3 format |
|
|
740
|
-
| `TouchChatProcessor` | `.ce` | PRC-Saltillo TouchChat format |
|
|
741
|
-
| `ApplePanelsProcessor` | `.plist` | iOS Apple Panels format |
|
|
742
|
-
| `AstericsGridProcessor` | `.grd` | Asterics Grid native format |
|
|
743
|
-
| `ExcelProcessor` | `.xlsx` | Microsoft Excel format |
|
|
744
|
-
|
|
745
|
-
---
|
|
746
|
-
|
|
747
|
-
## π§ͺ Testing & Quality
|
|
748
|
-
|
|
749
|
-
This library maintains **65% test coverage** with **111 comprehensive tests** including:
|
|
750
|
-
|
|
751
|
-
- **Unit tests** for all processors and core functionality
|
|
752
|
-
- **Integration tests** for cross-format workflows
|
|
753
|
-
- **Property-based tests** using fast-check for edge case discovery
|
|
754
|
-
- **Performance tests** for memory usage and large file handling
|
|
755
|
-
- **Error handling tests** for corrupted data and edge cases
|
|
756
|
-
|
|
757
|
-
### Running Tests
|
|
758
|
-
|
|
759
|
-
```bash
|
|
760
|
-
# Run all tests (automatically builds first)
|
|
761
|
-
npm test
|
|
762
|
-
|
|
763
|
-
# Run with coverage report (automatically builds first)
|
|
764
|
-
npm run test:coverage
|
|
765
|
-
|
|
766
|
-
# Run tests in watch mode (automatically builds first)
|
|
767
|
-
npm run test:watch
|
|
768
|
-
|
|
769
|
-
# Generate detailed coverage analysis
|
|
770
|
-
npm run coverage:report
|
|
771
|
-
```
|
|
772
|
-
|
|
773
|
-
**Note**: All test commands automatically run `npm run build` first to ensure CLI tests have the required `dist/` files. CLI integration tests require the compiled JavaScript files to test the command-line interface.
|
|
774
|
-
|
|
775
|
-
### π οΈ Utility Scripts
|
|
776
|
-
|
|
777
|
-
A wide range of utility scripts for batch processing, audio generation, and advanced analysis are available in the **[scripts/](./scripts/README.md)** directory. These include:
|
|
778
|
-
|
|
779
|
-
- **Analysis**: Pageset reporting and vocabulary extraction.
|
|
780
|
-
- **Audio**: Automated TTS generation and audio-enhanced pageset creation.
|
|
781
|
-
- **Conversion**: TSV-to-Gridset and other format-shifting tools.
|
|
782
|
-
- **Translation**: Batch translation workflows using Google, Azure, and Gemini.
|
|
783
|
-
|
|
784
|
-
### Development Commands
|
|
785
|
-
|
|
786
|
-
```bash
|
|
787
|
-
# Build TypeScript
|
|
788
|
-
npm run build
|
|
789
|
-
|
|
790
|
-
# Watch mode for development
|
|
791
|
-
npm run build:watch
|
|
792
|
-
|
|
793
|
-
# Lint code
|
|
84
|
+
npm run build:all
|
|
794
85
|
npm run lint
|
|
795
|
-
|
|
796
|
-
# Format code
|
|
797
|
-
npm run format
|
|
798
|
-
|
|
799
|
-
# Type checking
|
|
800
|
-
npm run type-check
|
|
86
|
+
npm test
|
|
801
87
|
```
|
|
802
88
|
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
## π€ Contributing
|
|
89
|
+
## Electron Note
|
|
806
90
|
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
1. Fork the repository
|
|
810
|
-
2. Create a feature branch: `git checkout -b feature/amazing-feature`
|
|
811
|
-
3. Make your changes with tests
|
|
812
|
-
4. Run the test suite: `npm test`
|
|
813
|
-
5. Commit your changes: `git commit -m 'Add amazing feature'`
|
|
814
|
-
6. Push to the branch: `git push origin feature/amazing-feature`
|
|
815
|
-
7. Open a Pull Request
|
|
816
|
-
|
|
817
|
-
### Development Setup
|
|
91
|
+
`better-sqlite3` is a native dependency. For Electron, rebuild it against the
|
|
92
|
+
Electron runtime:
|
|
818
93
|
|
|
819
94
|
```bash
|
|
820
|
-
|
|
821
|
-
cd AACProcessors-nodejs
|
|
822
|
-
npm install
|
|
823
|
-
npm run build
|
|
824
|
-
npm test
|
|
95
|
+
npx electron-rebuild
|
|
825
96
|
```
|
|
826
|
-
|
|
827
|
-
### Environment Variables
|
|
828
|
-
|
|
829
|
-
- Copy the template: `cp .envrc.example .envrc`
|
|
830
|
-
- Fill in your own API keys locally; `.envrc` is ignored to prevent accidental commits
|
|
831
|
-
- If you rotate keys, update only your local `.envrc`βnever commit real secrets
|
|
832
|
-
|
|
833
|
-
### Publishing to npm
|
|
834
|
-
|
|
835
|
-
- The repository keeps `package.json` at `0.0.0-development`; release tags control the published version.
|
|
836
|
-
- Create a GitHub release with a semantic tag (e.g. `v2.1.0`). Publishing only runs for non-prerelease tags.
|
|
837
|
-
- The workflow (`.github/workflows/publish.yml`) automatically installs dependencies, rewrites the package version from the tag, and runs the standard publish pipeline.
|
|
838
|
-
|
|
839
|
-
---
|
|
840
|
-
|
|
841
|
-
## π License
|
|
842
|
-
|
|
843
|
-
MIT License - see [LICENSE](LICENSE) file for details.
|
|
844
|
-
|
|
845
|
-
---
|
|
846
|
-
|
|
847
|
-
## π Credits
|
|
848
|
-
|
|
849
|
-
Created by **Will Wade** and contributors.
|
|
850
|
-
|
|
851
|
-
Inspired by the Python AACProcessors project
|
|
852
|
-
|
|
853
|
-
### Related Projects
|
|
854
|
-
|
|
855
|
-
- [AACProcessors (Python)](https://github.com/willwade/AACProcessors) - Original Python implementation
|
|
856
|
-
- [Open Board Format](https://www.openboardformat.org/) - Open standard for communication boards
|
|
857
|
-
|
|
858
|
-
---
|
|
859
|
-
|
|
860
|
-
## π Support
|
|
861
|
-
|
|
862
|
-
- π **Bug Reports**: [GitHub Issues](https://github.com/willwade/AACProcessors-nodejs/issues)
|
|
863
|
-
- π¬ **Discussions**: [GitHub Discussions](https://github.com/willwade/AACProcessors-nodejs/discussions)
|
|
864
|
-
- π§ **Email**: wwade@acecentre.org.uk
|
|
865
|
-
|
|
866
|
-
---
|
|
867
|
-
|
|
868
|
-
## π TODO & Roadmap
|
|
869
|
-
|
|
870
|
-
### π₯ Critical Priority (Immediate Action Required)
|
|
871
|
-
|
|
872
|
-
- [ ] **Road Testing** - Perform comprehensive layout and formatting validation across diverse pagesets to verify conversion fidelity.
|
|
873
|
-
- [ ] **Fix audio persistence issues** - Resolve functional audio recording persistence in `SnapProcessor` save/load cycle (5 failing tests remaining).
|
|
874
|
-
- [x] **Access Method Modeling** - Support for switch scanning (linear, row-column, block) integrated into AAC metrics.
|
|
875
|
-
|
|
876
|
-
### π¨ High Priority (Next Sprint)
|
|
877
|
-
|
|
878
|
-
- [ ] **Complete SnapProcessor coverage** (currently ~60%) - Reach >75% coverage by adding comprehensive audio handling and database corruption tests.
|
|
879
|
-
- [ ] **Symbol System Rethink** - Explore treating "Symbols" as a first-class entity (alongside Pages/Buttons) to support richer metadata (library IDs, synonyms, multi-lang names).
|
|
880
|
-
- [ ] **Language & Locale Persistence** - Ensure current language and locale information is correctly preserved and bubbled up to the `AACTree` level.
|
|
881
|
-
|
|
882
|
-
### β οΈ Medium Priority
|
|
883
|
-
|
|
884
|
-
- [ ] **Adaptive Metrics** - Expand scanning analysis to include dwell times and more complex switch logic configurations.
|
|
885
|
-
|
|
886
|
-
### Low Priority
|
|
887
|
-
|
|
888
|
-
- [ ] **Batch processing CLI** - Process multiple files/directories in parallel.
|
|
889
|
-
|
|
890
|
-
### Contributing
|
|
891
|
-
|
|
892
|
-
Want to help with any of these items? See our [Contributing Guidelines](#-contributing) and pick an issue that interests you!
|
|
893
|
-
|
|
894
|
-
### Credits
|
|
895
|
-
|
|
896
|
-
Some of the OBF work is directly from https://github.com/open-aac/obf and https://github.com/open-aac/aac-metrics - OBLA too https://www.openboardformat.org/logs
|