@willwade/aac-processors 0.0.11 → 0.0.13
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 +44 -41
- package/dist/cli/index.js +7 -0
- package/dist/core/analyze.js +1 -0
- package/dist/core/treeStructure.d.ts +45 -2
- package/dist/core/treeStructure.js +22 -3
- package/dist/index.d.ts +2 -1
- package/dist/index.js +20 -3
- package/dist/{analytics → optional/analytics}/history.d.ts +15 -4
- package/dist/{analytics → optional/analytics}/history.js +3 -3
- package/dist/optional/analytics/index.d.ts +30 -0
- package/dist/optional/analytics/index.js +78 -0
- package/dist/optional/analytics/metrics/comparison.d.ts +36 -0
- package/dist/optional/analytics/metrics/comparison.js +334 -0
- package/dist/optional/analytics/metrics/core.d.ts +45 -0
- package/dist/optional/analytics/metrics/core.js +575 -0
- package/dist/optional/analytics/metrics/effort.d.ts +147 -0
- package/dist/optional/analytics/metrics/effort.js +211 -0
- package/dist/optional/analytics/metrics/index.d.ts +15 -0
- package/dist/optional/analytics/metrics/index.js +36 -0
- package/dist/optional/analytics/metrics/obl-types.d.ts +93 -0
- package/dist/optional/analytics/metrics/obl-types.js +7 -0
- package/dist/optional/analytics/metrics/obl.d.ts +40 -0
- package/dist/optional/analytics/metrics/obl.js +287 -0
- package/dist/optional/analytics/metrics/sentence.d.ts +49 -0
- package/dist/optional/analytics/metrics/sentence.js +112 -0
- package/dist/optional/analytics/metrics/types.d.ts +157 -0
- package/dist/optional/analytics/metrics/types.js +7 -0
- package/dist/optional/analytics/metrics/vocabulary.d.ts +65 -0
- package/dist/optional/analytics/metrics/vocabulary.js +142 -0
- package/dist/optional/analytics/reference/index.d.ts +51 -0
- package/dist/optional/analytics/reference/index.js +102 -0
- package/dist/optional/analytics/utils/idGenerator.d.ts +59 -0
- package/dist/optional/analytics/utils/idGenerator.js +96 -0
- package/dist/optional/symbolTools.js +13 -16
- package/dist/processors/astericsGridProcessor.d.ts +15 -0
- package/dist/processors/astericsGridProcessor.js +17 -0
- package/dist/processors/gridset/helpers.d.ts +4 -1
- package/dist/processors/gridset/helpers.js +4 -0
- package/dist/processors/gridset/pluginTypes.js +51 -50
- package/dist/processors/gridset/symbolExtractor.js +3 -2
- package/dist/processors/gridset/symbolSearch.js +9 -7
- package/dist/processors/gridsetProcessor.js +82 -20
- package/dist/processors/index.d.ts +1 -0
- package/dist/processors/index.js +5 -3
- package/dist/processors/obfProcessor.js +37 -2
- package/dist/processors/obfsetProcessor.d.ts +26 -0
- package/dist/processors/obfsetProcessor.js +179 -0
- package/dist/processors/snap/helpers.d.ts +5 -1
- package/dist/processors/snap/helpers.js +5 -0
- package/dist/processors/snapProcessor.d.ts +2 -0
- package/dist/processors/snapProcessor.js +184 -5
- package/dist/processors/touchchatProcessor.js +50 -4
- package/dist/types/aac.d.ts +67 -0
- package/dist/types/aac.js +33 -0
- package/dist/validation/gridsetValidator.js +10 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# AACProcessors
|
|
2
2
|
|
|
3
|
-
[](./coverage)
|
|
4
4
|
[](https://www.typescriptlang.org/)
|
|
5
|
-
[](./test)
|
|
6
6
|
[](https://opensource.org/licenses/MIT)
|
|
7
7
|
|
|
8
8
|
A comprehensive **TypeScript library** for processing AAC (Augmentative and Alternative Communication) file formats with advanced translation support, cross-format conversion, and robust error handling.
|
|
@@ -20,6 +20,7 @@ A comprehensive **TypeScript library** for processing AAC (Augmentative and Alte
|
|
|
20
20
|
- **Apple Panels** (MacOS) - Plist format support
|
|
21
21
|
- **Asterics Grid** - Native Asterics Grid format with audio
|
|
22
22
|
- **Excel** - Export to Microsoft Excel for vocabulary analysis
|
|
23
|
+
- **Analyics & Metrics** - High-parity AAC effort metrics and clinical analysis tools
|
|
23
24
|
|
|
24
25
|
### **Advanced Capabilities**
|
|
25
26
|
|
|
@@ -28,6 +29,7 @@ A comprehensive **TypeScript library** for processing AAC (Augmentative and Alte
|
|
|
28
29
|
- 🎨 **Comprehensive styling support** - Preserve visual appearance across formats
|
|
29
30
|
- 🧪 **Property-based testing** - Robust validation with 140+ tests
|
|
30
31
|
- ✅ **Format validation** - Spec-based validation for all supported formats
|
|
32
|
+
- 📊 **Clinical Metrics** - High-parity AAC effort algorithm (v0.2) and vocabulary coverage analysis
|
|
31
33
|
- ⚡ **Performance optimized** - Memory-efficient processing of large files
|
|
32
34
|
- 🛡️ **Error recovery** - Graceful handling of corrupted data
|
|
33
35
|
- 🔒 **Thread-safe** - Concurrent processing support
|
|
@@ -192,6 +194,29 @@ const translatedBuffer = processor.processTexts(
|
|
|
192
194
|
console.log("Translation complete!");
|
|
193
195
|
```
|
|
194
196
|
|
|
197
|
+
### 📊 AAC Analytics & Clinical Metrics
|
|
198
|
+
|
|
199
|
+
The library includes an optional high-performance analytics engine for evaluating AAC board sets based on the **AAC Effort Algorithm (v0.2)**.
|
|
200
|
+
|
|
201
|
+
#### **Key Metrics Features**
|
|
202
|
+
- **Effort Scores**: Calculate the physical/cognitive cost of any word (Distance, Field Size, Motor Planning).
|
|
203
|
+
- **Vocabulary Coverage**: Compare board sets against core vocabulary lists (e.g., Anderson & Bitner).
|
|
204
|
+
- **Sentence Analysis**: Measure the effort required to construct common test sentences.
|
|
205
|
+
- **Comparative Analysis**: Identify gaps and improvements between two pageset versions.
|
|
206
|
+
|
|
207
|
+
For detailed documentation, see the **[AAC Metrics Guide](./src/optional/analytics/docs/AAC_METRICS_GUIDE.md)** and **[Vocabulary Analysis Guide](./src/optional/analytics/docs/VOCABULARY_ANALYSIS_GUIDE.md)**.
|
|
208
|
+
|
|
209
|
+
```typescript
|
|
210
|
+
import { ObfsetProcessor, Analytics } from '@willwade/aac-processors';
|
|
211
|
+
|
|
212
|
+
const processor = new ObfsetProcessor();
|
|
213
|
+
const tree = processor.loadIntoTree('my_pageset.obfset');
|
|
214
|
+
|
|
215
|
+
// Run clinical effort analysis
|
|
216
|
+
const result = new Analytics.MetricsCalculator().analyze(tree);
|
|
217
|
+
console.log(`Average Effort: ${result.total_words}`);
|
|
218
|
+
```
|
|
219
|
+
|
|
195
220
|
### Format Validation
|
|
196
221
|
|
|
197
222
|
Validate AAC files against format specifications to ensure data integrity:
|
|
@@ -710,6 +735,14 @@ npm run coverage:report
|
|
|
710
735
|
|
|
711
736
|
**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.
|
|
712
737
|
|
|
738
|
+
### 🛠️ Utility Scripts
|
|
739
|
+
|
|
740
|
+
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:
|
|
741
|
+
- **Analysis**: Pageset reporting and vocabulary extraction.
|
|
742
|
+
- **Audio**: Automated TTS generation and audio-enhanced pageset creation.
|
|
743
|
+
- **Conversion**: TSV-to-Gridset and other format-shifting tools.
|
|
744
|
+
- **Translation**: Batch translation workflows using Google, Azure, and Gemini.
|
|
745
|
+
|
|
713
746
|
### Development Commands
|
|
714
747
|
|
|
715
748
|
```bash
|
|
@@ -798,57 +831,27 @@ Inspired by the Python AACProcessors project
|
|
|
798
831
|
|
|
799
832
|
### 🔥 Critical Priority (Immediate Action Required)
|
|
800
833
|
|
|
801
|
-
- [ ] **
|
|
802
|
-
- [ ] **
|
|
803
|
-
- [
|
|
834
|
+
- [ ] **Road Testing** - Perform comprehensive layout and formatting validation across diverse pagesets to verify conversion fidelity.
|
|
835
|
+
- [ ] **Fix audio persistence issues** - Resolve functional audio recording persistence in `SnapProcessor` save/load cycle (5 failing tests remaining).
|
|
836
|
+
- [x] **Access Method Modeling** - Support for switch scanning (linear, row-column, block) integrated into AAC metrics.
|
|
804
837
|
|
|
805
838
|
### 🚨 High Priority (Next Sprint)
|
|
806
839
|
|
|
807
|
-
- [ ] **Complete SnapProcessor coverage** (currently
|
|
808
|
-
- [ ] **
|
|
809
|
-
- [ ] **
|
|
810
|
-
|
|
811
|
-
### ⚠️ Medium Priority (Following Sprint)
|
|
840
|
+
- [ ] **Complete SnapProcessor coverage** (currently ~60%) - Reach >75% coverage by adding comprehensive audio handling and database corruption tests.
|
|
841
|
+
- [ ] **Symbol System Rethink** - Explore treating "Symbols" as a first-class entity (alongside Pages/Buttons) to support richer metadata (library IDs, synonyms, multi-lang names).
|
|
842
|
+
- [ ] **Language & Locale Persistence** - Ensure current language and locale information is correctly preserved and bubbled up to the `AACTree` level.
|
|
812
843
|
|
|
813
|
-
|
|
814
|
-
- [ ] **Improve AstericsGridProcessor coverage** (currently 62.5%) - Add comprehensive tests for Asterics Grid format processing to reach >80% coverage
|
|
815
|
-
- [ ] **Add Symbol Tools coverage** (currently 0%) - Implement tests for PCS and ARASAAC symbol lookups to reach >70% coverage
|
|
816
|
-
- [ ] **Fix property-based test failures** - Resolve TypeScript interface compatibility issues in edge case generators
|
|
844
|
+
### ⚠️ Medium Priority
|
|
817
845
|
|
|
818
|
-
|
|
846
|
+
- [ ] **Adaptive Metrics** - Expand scanning analysis to include dwell times and more complex switch logic configurations.
|
|
819
847
|
|
|
820
|
-
- [ ] **Performance optimization** - Optimize memory usage for very large communication boards (1000+ buttons)
|
|
821
|
-
- [ ] **Add GridsetProcessor ZIP handling** - Improve support for complex Grid3 ZIP archives
|
|
822
|
-
- [ ] **Enhance error recovery** - Better handling of partially corrupted database files
|
|
823
|
-
- [ ] **Add streaming support** - Process very large files without loading entirely into memory
|
|
824
|
-
- [ ] **Improve translation workflows** - Add support for translation service integrations (Google Translate, Azure, etc.)
|
|
825
|
-
- [ ] **Add symbol library integration** - Complete implementation of PCS, ARASAAC symbol lookups
|
|
826
848
|
|
|
827
849
|
### Low Priority
|
|
828
850
|
|
|
829
|
-
- [ ] **Add more AAC formats** - Look for other common AAC formats to add
|
|
830
|
-
- [ ] **Plugin system** - Allow third-party processors and extensions
|
|
831
|
-
- [ ] **Batch processing CLI** - Process multiple files in parallel
|
|
832
|
-
- [ ] **Configuration file support** - Allow .aacprocessors.json config files
|
|
833
851
|
|
|
834
|
-
|
|
852
|
+
- [ ] **Batch processing CLI** - Process multiple files/directories in parallel.
|
|
835
853
|
|
|
836
|
-
- [ ] **Reach 80%+ test coverage** - Current: 65.15% (target: 80%+)
|
|
837
|
-
- [ ] **Add mutation testing** - Use Stryker.js for mutation testing
|
|
838
|
-
- [ ] **Add benchmark suite** - Performance regression testing
|
|
839
|
-
- [ ] **CI/CD improvements** - Add automated releases and npm publishing
|
|
840
|
-
- [ ] **Documentation improvements** - Add more real-world examples and tutorials
|
|
841
|
-
|
|
842
|
-
## More enhancements
|
|
843
|
-
|
|
844
|
-
- Much more effort put into fixing the layout issues. Grid sizes are not reliably and X, Y positions too. Particularly in the Grid3
|
|
845
|
-
- Action types on buttons. We have SPEAK, NAVIGATE, but we could also have things like "PLAY_AUDIO", "SEND_MESSAGE", "OPEN_URL", etc. This would allow us to have a more flexible structure for actions, especially if we want to support different types of actions or additional metadata in the future. This needs to be very flexible. eaach system has a very different set of actions. We could have a set of core actions that are supported by all systems, and then allow each system to define its own additional actions. This could be done by having a set of core action types that are defined in the AACSystem type, and then allowing each system to define its own additional action types in the AACPageSet or AACPage types.
|
|
846
|
-
- Current language and locale information of aac pageset
|
|
847
|
-
- Symbols and their associated data. Now we have an optional part but I think this might need rethinking. I wonder if "Symbols" should be a separate type - alongside AACPageSet and AACPage. that then AACPageSet and AACPage can reference. This would allow us to have a more flexible structure for symbols, especially if we want to support different types of symbols or additional metadata in the future. Symbols would have: Library name, ID, Text name, Reference (URL, DB ID, etc.), and an optional part for additional metadata. We could have synoynms, antonyms, also and for different languages somehow.
|
|
848
|
-
- Somehow we need to deal with access. Switch scanning: Blocks probably being the main aspect. But also - we need to identify somewhere a set of core rules for each aac system. Like for example - what access methods are supported, what languages are supported, what symbols are supported, etc. This could be a set of rules that can be referenced by AACSystem - a different type altogether maybe? It could be in a JSON format maybe. (use case here being for a MCP).
|
|
849
854
|
|
|
850
855
|
### Contributing
|
|
851
856
|
|
|
852
857
|
Want to help with any of these items? See our [Contributing Guidelines](#-contributing) and pick an issue that interests you!
|
|
853
|
-
|
|
854
|
-
---
|
package/dist/cli/index.js
CHANGED
|
@@ -17,6 +17,13 @@ function detectFormat(filePath) {
|
|
|
17
17
|
filePath.endsWith('.ascconfig')) {
|
|
18
18
|
return 'ascconfig';
|
|
19
19
|
}
|
|
20
|
+
// Map multi-file formats to their base processor
|
|
21
|
+
if (filePath.endsWith('.obfset')) {
|
|
22
|
+
return 'obf'; // Use ObfProcessor for .obfset files
|
|
23
|
+
}
|
|
24
|
+
if (filePath.endsWith('.gridset')) {
|
|
25
|
+
return 'gridset';
|
|
26
|
+
}
|
|
20
27
|
// Otherwise use file extension
|
|
21
28
|
return path_1.default.extname(filePath).slice(1);
|
|
22
29
|
}
|
package/dist/core/analyze.js
CHANGED
|
@@ -22,6 +22,7 @@ function getProcessor(format, options) {
|
|
|
22
22
|
case 'opml':
|
|
23
23
|
return new opmlProcessor_1.OpmlProcessor(options);
|
|
24
24
|
case 'obf':
|
|
25
|
+
case 'obfset': // Obfset files use ObfProcessor
|
|
25
26
|
return new obfProcessor_1.ObfProcessor(options);
|
|
26
27
|
case 'touchchat':
|
|
27
28
|
case 'ce': // TouchChat file extension
|
|
@@ -29,6 +29,25 @@ export declare enum AACSemanticIntent {
|
|
|
29
29
|
SCAN_SELECT = "SCAN_SELECT",
|
|
30
30
|
PLATFORM_SPECIFIC = "PLATFORM_SPECIFIC"
|
|
31
31
|
}
|
|
32
|
+
/**
|
|
33
|
+
* Scanning types for accessibility
|
|
34
|
+
*/
|
|
35
|
+
export declare enum AACScanType {
|
|
36
|
+
LINEAR = "linear",// Left-to-right, top-to-bottom
|
|
37
|
+
ROW_COLUMN = "row-column",// Scan rows, then columns
|
|
38
|
+
COLUMN_ROW = "column-row",// Scan columns, then rows
|
|
39
|
+
BLOCK_ROW_COLUMN = "block-row-column",// Scan blocks, then rows, then columns
|
|
40
|
+
BLOCK_COLUMN_ROW = "block-column-row"
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Configuration for a scan block
|
|
44
|
+
*/
|
|
45
|
+
export interface AACScanBlock {
|
|
46
|
+
id: number;
|
|
47
|
+
name?: string;
|
|
48
|
+
order?: number;
|
|
49
|
+
scanType?: AACScanType;
|
|
50
|
+
}
|
|
32
51
|
export interface AACSemanticAction {
|
|
33
52
|
category?: AACSemanticCategory;
|
|
34
53
|
intent: AACSemanticIntent | string;
|
|
@@ -83,6 +102,8 @@ export interface AACSemanticAction {
|
|
|
83
102
|
type: 'SPEAK' | 'NAVIGATE' | 'ACTION';
|
|
84
103
|
message?: string;
|
|
85
104
|
targetPageId?: string;
|
|
105
|
+
temporary_home?: boolean | string | null;
|
|
106
|
+
add_to_sentence?: boolean;
|
|
86
107
|
};
|
|
87
108
|
}
|
|
88
109
|
export declare class AACButton implements IAACButton {
|
|
@@ -108,14 +129,23 @@ export declare class AACButton implements IAACButton {
|
|
|
108
129
|
y?: number;
|
|
109
130
|
columnSpan?: number;
|
|
110
131
|
rowSpan?: number;
|
|
132
|
+
/**
|
|
133
|
+
* @deprecated Use scanBlock instead (singular, not array)
|
|
134
|
+
*/
|
|
111
135
|
scanBlocks?: number[];
|
|
136
|
+
/**
|
|
137
|
+
* Scan block number (1-8) for block scanning
|
|
138
|
+
*/
|
|
139
|
+
scanBlock?: number;
|
|
112
140
|
visibility?: 'Visible' | 'Hidden' | 'Disabled' | 'PointerAndTouchOnly' | 'Empty';
|
|
113
141
|
directActivate?: boolean;
|
|
114
142
|
audioDescription?: string;
|
|
115
143
|
parameters?: {
|
|
116
144
|
[key: string]: any;
|
|
117
145
|
};
|
|
118
|
-
|
|
146
|
+
semantic_id?: string;
|
|
147
|
+
clone_id?: string;
|
|
148
|
+
constructor({ id, label, message, targetPageId, semanticAction, audioRecording, style, contentType, contentSubType, image, resolvedImageEntry, symbolLibrary, symbolPath, x, y, columnSpan, rowSpan, scanBlocks, scanBlock, visibility, directActivate, parameters, semantic_id, clone_id, type, action, }: {
|
|
119
149
|
id: string;
|
|
120
150
|
label?: string;
|
|
121
151
|
message?: string;
|
|
@@ -139,11 +169,14 @@ export declare class AACButton implements IAACButton {
|
|
|
139
169
|
columnSpan?: number;
|
|
140
170
|
rowSpan?: number;
|
|
141
171
|
scanBlocks?: number[];
|
|
172
|
+
scanBlock?: number;
|
|
142
173
|
visibility?: 'Visible' | 'Hidden' | 'Disabled' | 'PointerAndTouchOnly' | 'Empty';
|
|
143
174
|
directActivate?: boolean;
|
|
144
175
|
parameters?: {
|
|
145
176
|
[key: string]: any;
|
|
146
177
|
};
|
|
178
|
+
semantic_id?: string;
|
|
179
|
+
clone_id?: string;
|
|
147
180
|
type?: 'SPEAK' | 'NAVIGATE' | 'ACTION';
|
|
148
181
|
action?: {
|
|
149
182
|
type: 'SPEAK' | 'NAVIGATE' | 'ACTION';
|
|
@@ -169,7 +202,12 @@ export declare class AACPage implements IAACPage {
|
|
|
169
202
|
descriptionHtml?: string;
|
|
170
203
|
images?: any[];
|
|
171
204
|
sounds?: any[];
|
|
172
|
-
|
|
205
|
+
semantic_ids?: string[];
|
|
206
|
+
clone_ids?: string[];
|
|
207
|
+
scanningConfig?: import('../types/aac').ScanningConfig;
|
|
208
|
+
scanType?: AACScanType;
|
|
209
|
+
scanBlocksConfig?: AACScanBlock[];
|
|
210
|
+
constructor({ id, name, grid, buttons, parentId, style, locale, descriptionHtml, images, sounds, semantic_ids, clone_ids, scanningConfig, scanBlocksConfig, scanType, }: {
|
|
173
211
|
id: string;
|
|
174
212
|
name?: string;
|
|
175
213
|
grid?: Array<Array<AACButton | null>> | {
|
|
@@ -183,6 +221,11 @@ export declare class AACPage implements IAACPage {
|
|
|
183
221
|
descriptionHtml?: string;
|
|
184
222
|
images?: any[];
|
|
185
223
|
sounds?: any[];
|
|
224
|
+
semantic_ids?: string[];
|
|
225
|
+
clone_ids?: string[];
|
|
226
|
+
scanningConfig?: import('../types/aac').ScanningConfig;
|
|
227
|
+
scanBlocksConfig?: AACScanBlock[];
|
|
228
|
+
scanType?: AACScanType;
|
|
186
229
|
});
|
|
187
230
|
addButton(button: AACButton): void;
|
|
188
231
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.AACTree = exports.AACPage = exports.AACButton = exports.AACSemanticIntent = exports.AACSemanticCategory = void 0;
|
|
3
|
+
exports.AACTree = exports.AACPage = exports.AACButton = exports.AACScanType = exports.AACSemanticIntent = exports.AACSemanticCategory = void 0;
|
|
4
4
|
// Semantic action categories for cross-platform compatibility
|
|
5
5
|
var AACSemanticCategory;
|
|
6
6
|
(function (AACSemanticCategory) {
|
|
@@ -42,8 +42,19 @@ var AACSemanticIntent;
|
|
|
42
42
|
// Custom
|
|
43
43
|
AACSemanticIntent["PLATFORM_SPECIFIC"] = "PLATFORM_SPECIFIC";
|
|
44
44
|
})(AACSemanticIntent || (exports.AACSemanticIntent = AACSemanticIntent = {}));
|
|
45
|
+
/**
|
|
46
|
+
* Scanning types for accessibility
|
|
47
|
+
*/
|
|
48
|
+
var AACScanType;
|
|
49
|
+
(function (AACScanType) {
|
|
50
|
+
AACScanType["LINEAR"] = "linear";
|
|
51
|
+
AACScanType["ROW_COLUMN"] = "row-column";
|
|
52
|
+
AACScanType["COLUMN_ROW"] = "column-row";
|
|
53
|
+
AACScanType["BLOCK_ROW_COLUMN"] = "block-row-column";
|
|
54
|
+
AACScanType["BLOCK_COLUMN_ROW"] = "block-column-row";
|
|
55
|
+
})(AACScanType || (exports.AACScanType = AACScanType = {}));
|
|
45
56
|
class AACButton {
|
|
46
|
-
constructor({ id, label = '', message = '', targetPageId, semanticAction, audioRecording, style, contentType, contentSubType, image, resolvedImageEntry, symbolLibrary, symbolPath, x, y, columnSpan, rowSpan, scanBlocks, visibility, directActivate, parameters,
|
|
57
|
+
constructor({ id, label = '', message = '', targetPageId, semanticAction, audioRecording, style, contentType, contentSubType, image, resolvedImageEntry, symbolLibrary, symbolPath, x, y, columnSpan, rowSpan, scanBlocks, scanBlock, visibility, directActivate, parameters, semantic_id, clone_id,
|
|
47
58
|
// Legacy input support
|
|
48
59
|
type, action, }) {
|
|
49
60
|
this.id = id;
|
|
@@ -64,9 +75,12 @@ class AACButton {
|
|
|
64
75
|
this.columnSpan = columnSpan;
|
|
65
76
|
this.rowSpan = rowSpan;
|
|
66
77
|
this.scanBlocks = scanBlocks;
|
|
78
|
+
this.scanBlock = scanBlock;
|
|
67
79
|
this.visibility = visibility;
|
|
68
80
|
this.directActivate = directActivate;
|
|
69
81
|
this.parameters = parameters;
|
|
82
|
+
this.semantic_id = semantic_id;
|
|
83
|
+
this.clone_id = clone_id;
|
|
70
84
|
// Legacy mapping: if no semanticAction provided, derive from legacy `action` first
|
|
71
85
|
if (!this.semanticAction && action) {
|
|
72
86
|
if (action.type === 'NAVIGATE' && (action.targetPageId || this.targetPageId)) {
|
|
@@ -154,7 +168,7 @@ class AACButton {
|
|
|
154
168
|
}
|
|
155
169
|
exports.AACButton = AACButton;
|
|
156
170
|
class AACPage {
|
|
157
|
-
constructor({ id, name = '', grid = [], buttons = [], parentId = null, style, locale, descriptionHtml, images, sounds, }) {
|
|
171
|
+
constructor({ id, name = '', grid = [], buttons = [], parentId = null, style, locale, descriptionHtml, images, sounds, semantic_ids, clone_ids, scanningConfig, scanBlocksConfig, scanType, }) {
|
|
158
172
|
this.id = id;
|
|
159
173
|
this.name = name;
|
|
160
174
|
if (Array.isArray(grid)) {
|
|
@@ -175,6 +189,11 @@ class AACPage {
|
|
|
175
189
|
this.descriptionHtml = descriptionHtml;
|
|
176
190
|
this.images = images;
|
|
177
191
|
this.sounds = sounds;
|
|
192
|
+
this.semantic_ids = semantic_ids;
|
|
193
|
+
this.clone_ids = clone_ids;
|
|
194
|
+
this.scanningConfig = scanningConfig;
|
|
195
|
+
this.scanBlocksConfig = scanBlocksConfig;
|
|
196
|
+
this.scanType = scanType;
|
|
178
197
|
}
|
|
179
198
|
addButton(button) {
|
|
180
199
|
this.buttons.push(button);
|
package/dist/index.d.ts
CHANGED
|
@@ -2,8 +2,9 @@ export * from './core/treeStructure';
|
|
|
2
2
|
export * from './core/baseProcessor';
|
|
3
3
|
export * from './core/stringCasing';
|
|
4
4
|
export * from './processors';
|
|
5
|
-
export { collectUnifiedHistory, listGrid3Users as listHistoryGrid3Users, listSnapUsers as listHistorySnapUsers, } from './analytics/history';
|
|
6
5
|
export * from './validation';
|
|
6
|
+
export * as Analytics from './optional/analytics';
|
|
7
|
+
export { collectUnifiedHistory, listGrid3Users as listHistoryGrid3Users, listSnapUsers as listHistorySnapUsers, } from './optional/analytics/history';
|
|
7
8
|
import { BaseProcessor } from './core/baseProcessor';
|
|
8
9
|
/**
|
|
9
10
|
* Factory function to get the appropriate processor for a file extension
|
package/dist/index.js
CHANGED
|
@@ -10,11 +10,23 @@ var __createBinding = (this && this.__createBinding) || (Object.create ? (functi
|
|
|
10
10
|
if (k2 === undefined) k2 = k;
|
|
11
11
|
o[k2] = m[k];
|
|
12
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
|
+
});
|
|
13
18
|
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
19
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
20
|
};
|
|
21
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
22
|
+
if (mod && mod.__esModule) return mod;
|
|
23
|
+
var result = {};
|
|
24
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
25
|
+
__setModuleDefault(result, mod);
|
|
26
|
+
return result;
|
|
27
|
+
};
|
|
16
28
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
exports.listHistorySnapUsers = exports.listHistoryGrid3Users = exports.collectUnifiedHistory = void 0;
|
|
29
|
+
exports.listHistorySnapUsers = exports.listHistoryGrid3Users = exports.collectUnifiedHistory = exports.Analytics = void 0;
|
|
18
30
|
exports.getProcessor = getProcessor;
|
|
19
31
|
exports.getSupportedExtensions = getSupportedExtensions;
|
|
20
32
|
exports.isExtensionSupported = isExtensionSupported;
|
|
@@ -23,11 +35,12 @@ __exportStar(require("./core/treeStructure"), exports);
|
|
|
23
35
|
__exportStar(require("./core/baseProcessor"), exports);
|
|
24
36
|
__exportStar(require("./core/stringCasing"), exports);
|
|
25
37
|
__exportStar(require("./processors"), exports);
|
|
26
|
-
|
|
38
|
+
__exportStar(require("./validation"), exports);
|
|
39
|
+
exports.Analytics = __importStar(require("./optional/analytics"));
|
|
40
|
+
var history_1 = require("./optional/analytics/history");
|
|
27
41
|
Object.defineProperty(exports, "collectUnifiedHistory", { enumerable: true, get: function () { return history_1.collectUnifiedHistory; } });
|
|
28
42
|
Object.defineProperty(exports, "listHistoryGrid3Users", { enumerable: true, get: function () { return history_1.listGrid3Users; } });
|
|
29
43
|
Object.defineProperty(exports, "listHistorySnapUsers", { enumerable: true, get: function () { return history_1.listSnapUsers; } });
|
|
30
|
-
__exportStar(require("./validation"), exports);
|
|
31
44
|
const dotProcessor_1 = require("./processors/dotProcessor");
|
|
32
45
|
const excelProcessor_1 = require("./processors/excelProcessor");
|
|
33
46
|
const opmlProcessor_1 = require("./processors/opmlProcessor");
|
|
@@ -37,6 +50,7 @@ const snapProcessor_1 = require("./processors/snapProcessor");
|
|
|
37
50
|
const touchchatProcessor_1 = require("./processors/touchchatProcessor");
|
|
38
51
|
const applePanelsProcessor_1 = require("./processors/applePanelsProcessor");
|
|
39
52
|
const astericsGridProcessor_1 = require("./processors/astericsGridProcessor");
|
|
53
|
+
const obfsetProcessor_1 = require("./processors/obfsetProcessor");
|
|
40
54
|
/**
|
|
41
55
|
* Factory function to get the appropriate processor for a file extension
|
|
42
56
|
* @param filePathOrExtension - File path or extension (e.g., '.dot', '/path/to/file.obf')
|
|
@@ -58,6 +72,8 @@ function getProcessor(filePathOrExtension) {
|
|
|
58
72
|
case '.obf':
|
|
59
73
|
case '.obz':
|
|
60
74
|
return new obfProcessor_1.ObfProcessor();
|
|
75
|
+
case '.obfset':
|
|
76
|
+
return new obfsetProcessor_1.ObfsetProcessor();
|
|
61
77
|
case '.gridset':
|
|
62
78
|
case '.gridsetx':
|
|
63
79
|
return new gridsetProcessor_1.GridsetProcessor();
|
|
@@ -85,6 +101,7 @@ function getSupportedExtensions() {
|
|
|
85
101
|
'.opml',
|
|
86
102
|
'.obf',
|
|
87
103
|
'.obz',
|
|
104
|
+
'.obfset',
|
|
88
105
|
'.gridset',
|
|
89
106
|
'.gridsetx',
|
|
90
107
|
'.spb',
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { dotNetTicksToDate } from '
|
|
2
|
-
import { Grid3UserPath } from '
|
|
3
|
-
import { SnapUserInfo } from '
|
|
4
|
-
|
|
1
|
+
import { dotNetTicksToDate } from '../../utils/dotnetTicks';
|
|
2
|
+
import { Grid3UserPath } from '../../processors/gridset/helpers';
|
|
3
|
+
import { SnapUserInfo } from '../../processors/snap/helpers';
|
|
4
|
+
import { AACSemanticCategory, AACSemanticIntent } from '../../core/treeStructure';
|
|
5
|
+
export type HistorySource = 'Grid' | 'Snap' | 'OBL' | string;
|
|
5
6
|
export interface HistoryOccurrence {
|
|
6
7
|
timestamp: Date;
|
|
7
8
|
latitude?: number | null;
|
|
@@ -9,12 +10,22 @@ export interface HistoryOccurrence {
|
|
|
9
10
|
modeling?: boolean;
|
|
10
11
|
accessMethod?: number | null;
|
|
11
12
|
pageId?: string | null;
|
|
13
|
+
buttonId?: string | null;
|
|
14
|
+
boardId?: string | null;
|
|
15
|
+
spoken?: boolean;
|
|
16
|
+
vocalization?: string;
|
|
17
|
+
imageUrl?: string;
|
|
18
|
+
actions?: any[];
|
|
19
|
+
type?: 'button' | 'action' | 'utterance' | 'note' | 'other';
|
|
20
|
+
intent?: AACSemanticIntent | string;
|
|
21
|
+
category?: AACSemanticCategory;
|
|
12
22
|
}
|
|
13
23
|
export interface HistoryPlatformExtras {
|
|
14
24
|
label?: string;
|
|
15
25
|
message?: string;
|
|
16
26
|
buttonId?: string;
|
|
17
27
|
contentXml?: string;
|
|
28
|
+
[key: string]: any;
|
|
18
29
|
}
|
|
19
30
|
export interface HistoryEntry {
|
|
20
31
|
id: string;
|
|
@@ -9,10 +9,10 @@ exports.readSnapUsageForUser = readSnapUsageForUser;
|
|
|
9
9
|
exports.listSnapUsers = listSnapUsers;
|
|
10
10
|
exports.listGrid3Users = listGrid3Users;
|
|
11
11
|
exports.collectUnifiedHistory = collectUnifiedHistory;
|
|
12
|
-
const dotnetTicks_1 = require("
|
|
12
|
+
const dotnetTicks_1 = require("../../utils/dotnetTicks");
|
|
13
13
|
Object.defineProperty(exports, "dotNetTicksToDate", { enumerable: true, get: function () { return dotnetTicks_1.dotNetTicksToDate; } });
|
|
14
|
-
const helpers_1 = require("
|
|
15
|
-
const helpers_2 = require("
|
|
14
|
+
const helpers_1 = require("../../processors/gridset/helpers");
|
|
15
|
+
const helpers_2 = require("../../processors/snap/helpers");
|
|
16
16
|
/**
|
|
17
17
|
* Read Grid 3 phrase history from a history.sqlite database and tag entries with their source.
|
|
18
18
|
*/
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AAC Analytics Module (Optional)
|
|
3
|
+
*
|
|
4
|
+
* This module provides metrics calculation and analysis for AAC board sets.
|
|
5
|
+
* The core types, utilities, and effort functions are always available.
|
|
6
|
+
*
|
|
7
|
+
* This module is similar to symbolTools - the functionality is here but
|
|
8
|
+
* you only use it if you need it. No special installation required.
|
|
9
|
+
*
|
|
10
|
+
* @module
|
|
11
|
+
*/
|
|
12
|
+
export * from './metrics/types';
|
|
13
|
+
export * from './metrics/effort';
|
|
14
|
+
export * from './utils/idGenerator';
|
|
15
|
+
export * from './history';
|
|
16
|
+
export * from './metrics/obl-types';
|
|
17
|
+
export { OblUtil, OblAnonymizer } from './metrics/obl';
|
|
18
|
+
export { MetricsCalculator } from './metrics/core';
|
|
19
|
+
export { VocabularyAnalyzer } from './metrics/vocabulary';
|
|
20
|
+
export { SentenceAnalyzer } from './metrics/sentence';
|
|
21
|
+
export { ComparisonAnalyzer } from './metrics/comparison';
|
|
22
|
+
export { ReferenceLoader } from './reference';
|
|
23
|
+
/**
|
|
24
|
+
* Get the default reference data path
|
|
25
|
+
*/
|
|
26
|
+
export declare function getReferenceDataPath(): string;
|
|
27
|
+
/**
|
|
28
|
+
* Check if reference data files exist
|
|
29
|
+
*/
|
|
30
|
+
export declare function hasReferenceData(): boolean;
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* AAC Analytics Module (Optional)
|
|
4
|
+
*
|
|
5
|
+
* This module provides metrics calculation and analysis for AAC board sets.
|
|
6
|
+
* The core types, utilities, and effort functions are always available.
|
|
7
|
+
*
|
|
8
|
+
* This module is similar to symbolTools - the functionality is here but
|
|
9
|
+
* you only use it if you need it. No special installation required.
|
|
10
|
+
*
|
|
11
|
+
* @module
|
|
12
|
+
*/
|
|
13
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
14
|
+
if (k2 === undefined) k2 = k;
|
|
15
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
16
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
17
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
18
|
+
}
|
|
19
|
+
Object.defineProperty(o, k2, desc);
|
|
20
|
+
}) : (function(o, m, k, k2) {
|
|
21
|
+
if (k2 === undefined) k2 = k;
|
|
22
|
+
o[k2] = m[k];
|
|
23
|
+
}));
|
|
24
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
25
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
26
|
+
};
|
|
27
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
28
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
29
|
+
};
|
|
30
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
31
|
+
exports.ReferenceLoader = exports.ComparisonAnalyzer = exports.SentenceAnalyzer = exports.VocabularyAnalyzer = exports.MetricsCalculator = exports.OblAnonymizer = exports.OblUtil = void 0;
|
|
32
|
+
exports.getReferenceDataPath = getReferenceDataPath;
|
|
33
|
+
exports.hasReferenceData = hasReferenceData;
|
|
34
|
+
const path_1 = __importDefault(require("path"));
|
|
35
|
+
const fs_1 = __importDefault(require("fs"));
|
|
36
|
+
// Always-available exports
|
|
37
|
+
__exportStar(require("./metrics/types"), exports);
|
|
38
|
+
__exportStar(require("./metrics/effort"), exports);
|
|
39
|
+
__exportStar(require("./utils/idGenerator"), exports);
|
|
40
|
+
// Export history functionality
|
|
41
|
+
__exportStar(require("./history"), exports);
|
|
42
|
+
// Export OBL logging support
|
|
43
|
+
__exportStar(require("./metrics/obl-types"), exports);
|
|
44
|
+
var obl_1 = require("./metrics/obl");
|
|
45
|
+
Object.defineProperty(exports, "OblUtil", { enumerable: true, get: function () { return obl_1.OblUtil; } });
|
|
46
|
+
Object.defineProperty(exports, "OblAnonymizer", { enumerable: true, get: function () { return obl_1.OblAnonymizer; } });
|
|
47
|
+
// Export core metrics calculator
|
|
48
|
+
var core_1 = require("./metrics/core");
|
|
49
|
+
Object.defineProperty(exports, "MetricsCalculator", { enumerable: true, get: function () { return core_1.MetricsCalculator; } });
|
|
50
|
+
// Export vocabulary and comparison analyzers
|
|
51
|
+
var vocabulary_1 = require("./metrics/vocabulary");
|
|
52
|
+
Object.defineProperty(exports, "VocabularyAnalyzer", { enumerable: true, get: function () { return vocabulary_1.VocabularyAnalyzer; } });
|
|
53
|
+
var sentence_1 = require("./metrics/sentence");
|
|
54
|
+
Object.defineProperty(exports, "SentenceAnalyzer", { enumerable: true, get: function () { return sentence_1.SentenceAnalyzer; } });
|
|
55
|
+
var comparison_1 = require("./metrics/comparison");
|
|
56
|
+
Object.defineProperty(exports, "ComparisonAnalyzer", { enumerable: true, get: function () { return comparison_1.ComparisonAnalyzer; } });
|
|
57
|
+
var reference_1 = require("./reference");
|
|
58
|
+
Object.defineProperty(exports, "ReferenceLoader", { enumerable: true, get: function () { return reference_1.ReferenceLoader; } });
|
|
59
|
+
/**
|
|
60
|
+
* Get the default reference data path
|
|
61
|
+
*/
|
|
62
|
+
function getReferenceDataPath() {
|
|
63
|
+
return path_1.default.join(__dirname, 'reference', 'data');
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Check if reference data files exist
|
|
67
|
+
*/
|
|
68
|
+
function hasReferenceData() {
|
|
69
|
+
const dataPath = getReferenceDataPath();
|
|
70
|
+
const requiredFiles = [
|
|
71
|
+
'core_lists.en.json',
|
|
72
|
+
'common_words.en.json',
|
|
73
|
+
'sentences.en.json',
|
|
74
|
+
'synonyms.en.json',
|
|
75
|
+
'fringe.en.json',
|
|
76
|
+
];
|
|
77
|
+
return requiredFiles.every((file) => fs_1.default.existsSync(path_1.default.join(dataPath, file)));
|
|
78
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Comparative Analysis
|
|
3
|
+
*
|
|
4
|
+
* Compares two AAC board sets to identify missing/extra words,
|
|
5
|
+
* analyze vocabulary differences, and generate CARE component scores.
|
|
6
|
+
*/
|
|
7
|
+
import { MetricsResult, ComparisonResult } from './types';
|
|
8
|
+
export declare class ComparisonAnalyzer {
|
|
9
|
+
private vocabAnalyzer;
|
|
10
|
+
private sentenceAnalyzer;
|
|
11
|
+
private referenceLoader;
|
|
12
|
+
constructor();
|
|
13
|
+
/**
|
|
14
|
+
* Compare two board sets
|
|
15
|
+
*/
|
|
16
|
+
compare(targetResult: MetricsResult, compareResult: MetricsResult, options?: {
|
|
17
|
+
includeSentences?: boolean;
|
|
18
|
+
locale?: string;
|
|
19
|
+
}): ComparisonResult;
|
|
20
|
+
/**
|
|
21
|
+
* Calculate CARE component scores
|
|
22
|
+
*/
|
|
23
|
+
private calculateCareComponents;
|
|
24
|
+
/**
|
|
25
|
+
* Analyze fringe vocabulary
|
|
26
|
+
*/
|
|
27
|
+
private analyzeFringe;
|
|
28
|
+
/**
|
|
29
|
+
* Analyze common fringe vocabulary
|
|
30
|
+
*/
|
|
31
|
+
private analyzeCommonFringe;
|
|
32
|
+
/**
|
|
33
|
+
* Calculate overall effort score for a metrics result
|
|
34
|
+
*/
|
|
35
|
+
private calculateEffortScore;
|
|
36
|
+
}
|