@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
|
@@ -106,10 +106,10 @@ function detectPluginCellType(content) {
|
|
|
106
106
|
if (!content) {
|
|
107
107
|
return { cellType: Grid3CellType.Regular };
|
|
108
108
|
}
|
|
109
|
-
const contentType = content.ContentType || content.contenttype
|
|
110
|
-
const contentSubType = content.ContentSubType || content.contentsubtype
|
|
109
|
+
const contentType = content.ContentType || content.contenttype;
|
|
110
|
+
const contentSubType = content.ContentSubType || content.contentsubtype;
|
|
111
111
|
// Workspace cells - full editing workspaces
|
|
112
|
-
if (contentType === 'Workspace') {
|
|
112
|
+
if (contentType === 'Workspace' || content.Style?.BasedOnStyle === 'Workspace') {
|
|
113
113
|
return {
|
|
114
114
|
cellType: Grid3CellType.Workspace,
|
|
115
115
|
subType: contentSubType || undefined,
|
|
@@ -118,7 +118,7 @@ function detectPluginCellType(content) {
|
|
|
118
118
|
};
|
|
119
119
|
}
|
|
120
120
|
// LiveCell detection - dynamic content displays
|
|
121
|
-
if (contentType === 'LiveCell') {
|
|
121
|
+
if (contentType === 'LiveCell' || content.Style?.BasedOnStyle === 'LiveCell') {
|
|
122
122
|
return {
|
|
123
123
|
cellType: Grid3CellType.LiveCell,
|
|
124
124
|
liveCellType: contentSubType || undefined,
|
|
@@ -127,7 +127,7 @@ function detectPluginCellType(content) {
|
|
|
127
127
|
};
|
|
128
128
|
}
|
|
129
129
|
// AutoContent detection - dynamic word/content suggestions
|
|
130
|
-
if (contentType === 'AutoContent') {
|
|
130
|
+
if (contentType === 'AutoContent' || content.Style?.BasedOnStyle === 'AutoContent') {
|
|
131
131
|
const autoContentType = extractAutoContentType(content);
|
|
132
132
|
return {
|
|
133
133
|
cellType: Grid3CellType.AutoContent,
|
|
@@ -172,38 +172,38 @@ function inferWorkspacePlugin(subType) {
|
|
|
172
172
|
return undefined;
|
|
173
173
|
const normalized = subType.toLowerCase();
|
|
174
174
|
if (normalized.includes('chat'))
|
|
175
|
-
return '
|
|
175
|
+
return 'Grid3.Chat';
|
|
176
176
|
if (normalized.includes('email') || normalized.includes('mail'))
|
|
177
|
-
return '
|
|
178
|
-
if (normalized.includes('word') || normalized.includes('
|
|
179
|
-
return '
|
|
177
|
+
return 'Grid3.Email';
|
|
178
|
+
if (normalized.includes('word') || normalized.includes('doc'))
|
|
179
|
+
return 'Grid3.WordProcessor';
|
|
180
180
|
if (normalized.includes('phone'))
|
|
181
|
-
return '
|
|
181
|
+
return 'Grid3.Phone';
|
|
182
182
|
if (normalized.includes('sms') || normalized.includes('text'))
|
|
183
|
-
return '
|
|
184
|
-
if (normalized.includes('
|
|
185
|
-
return '
|
|
186
|
-
if (normalized.includes('computer')
|
|
187
|
-
return '
|
|
188
|
-
if (normalized.includes('
|
|
189
|
-
return '
|
|
190
|
-
if (normalized.includes('timer')
|
|
191
|
-
return '
|
|
183
|
+
return 'Grid3.Sms';
|
|
184
|
+
if (normalized.includes('browser') || normalized.includes('web'))
|
|
185
|
+
return 'Grid3.WebBrowser';
|
|
186
|
+
if (normalized.includes('computer'))
|
|
187
|
+
return 'Grid3.ComputerControl';
|
|
188
|
+
if (normalized.includes('calc'))
|
|
189
|
+
return 'Grid3.Calculator';
|
|
190
|
+
if (normalized.includes('timer'))
|
|
191
|
+
return 'Grid3.Timer';
|
|
192
192
|
if (normalized.includes('music') || normalized.includes('video'))
|
|
193
|
-
return '
|
|
193
|
+
return 'Grid3.MusicVideo';
|
|
194
194
|
if (normalized.includes('photo') || normalized.includes('image'))
|
|
195
|
-
return '
|
|
195
|
+
return 'Grid3.Photos';
|
|
196
196
|
if (normalized.includes('contact'))
|
|
197
|
-
return '
|
|
197
|
+
return 'Grid3.Contacts';
|
|
198
198
|
if (normalized.includes('learning'))
|
|
199
|
-
return '
|
|
200
|
-
if (normalized.includes('message') && normalized.includes('
|
|
201
|
-
return '
|
|
202
|
-
if (normalized.includes('
|
|
203
|
-
return '
|
|
204
|
-
if (normalized.includes('
|
|
205
|
-
return '
|
|
206
|
-
return
|
|
199
|
+
return 'Grid3.InteractiveLearning';
|
|
200
|
+
if (normalized.includes('message') && normalized.includes('banking'))
|
|
201
|
+
return 'Grid3.MessageBanking';
|
|
202
|
+
if (normalized.includes('control'))
|
|
203
|
+
return 'Grid3.EnvironmentControl';
|
|
204
|
+
if (normalized.includes('settings'))
|
|
205
|
+
return 'Grid3.Settings';
|
|
206
|
+
return `Grid3.${subType}`;
|
|
207
207
|
}
|
|
208
208
|
/**
|
|
209
209
|
* Infer plugin ID from live cell type
|
|
@@ -212,24 +212,25 @@ function inferLiveCellPlugin(liveCellType) {
|
|
|
212
212
|
if (!liveCellType)
|
|
213
213
|
return undefined;
|
|
214
214
|
const normalized = liveCellType.toLowerCase();
|
|
215
|
-
if (normalized.includes('clock')
|
|
216
|
-
return '
|
|
217
|
-
|
|
215
|
+
if (normalized.includes('clock'))
|
|
216
|
+
return 'Grid3.Clock';
|
|
217
|
+
if (normalized.includes('date'))
|
|
218
|
+
return 'Grid3.Clock';
|
|
218
219
|
if (normalized.includes('volume'))
|
|
219
|
-
return '
|
|
220
|
+
return 'Grid3.Volume';
|
|
220
221
|
if (normalized.includes('speed'))
|
|
221
|
-
return '
|
|
222
|
+
return 'Grid3.Speed';
|
|
222
223
|
if (normalized.includes('voice'))
|
|
223
|
-
return '
|
|
224
|
+
return 'Grid3.Speech';
|
|
224
225
|
if (normalized.includes('message'))
|
|
225
|
-
return '
|
|
226
|
+
return 'Grid3.Chat';
|
|
226
227
|
if (normalized.includes('battery'))
|
|
227
|
-
return '
|
|
228
|
-
if (normalized.includes('wifi')
|
|
229
|
-
return '
|
|
228
|
+
return 'Grid3.Battery';
|
|
229
|
+
if (normalized.includes('wifi'))
|
|
230
|
+
return 'Grid3.Wifi';
|
|
230
231
|
if (normalized.includes('bluetooth'))
|
|
231
|
-
return '
|
|
232
|
-
return
|
|
232
|
+
return 'Grid3.Bluetooth';
|
|
233
|
+
return `Grid3.${liveCellType}`;
|
|
233
234
|
}
|
|
234
235
|
/**
|
|
235
236
|
* Infer plugin ID from auto content type
|
|
@@ -239,24 +240,24 @@ function inferAutoContentPlugin(autoContentType) {
|
|
|
239
240
|
return undefined;
|
|
240
241
|
const normalized = autoContentType.toLowerCase();
|
|
241
242
|
if (normalized.includes('voice') || normalized.includes('speed'))
|
|
242
|
-
return '
|
|
243
|
+
return 'Grid3.Speech';
|
|
243
244
|
if (normalized.includes('email') || normalized.includes('mail'))
|
|
244
|
-
return '
|
|
245
|
+
return 'Grid3.Email';
|
|
245
246
|
if (normalized.includes('phone'))
|
|
246
|
-
return '
|
|
247
|
+
return 'Grid3.Phone';
|
|
247
248
|
if (normalized.includes('sms') || normalized.includes('text'))
|
|
248
|
-
return '
|
|
249
|
+
return 'Grid3.Sms';
|
|
249
250
|
if (normalized.includes('web') ||
|
|
250
251
|
normalized.includes('favorite') ||
|
|
251
252
|
normalized.includes('history')) {
|
|
252
|
-
return '
|
|
253
|
+
return 'Grid3.WebBrowser';
|
|
253
254
|
}
|
|
254
255
|
if (normalized.includes('prediction'))
|
|
255
|
-
return '
|
|
256
|
+
return 'Grid3.Prediction';
|
|
256
257
|
if (normalized.includes('grammar'))
|
|
257
|
-
return '
|
|
258
|
+
return 'Grid3.Grammar';
|
|
258
259
|
if (normalized.includes('context'))
|
|
259
|
-
return '
|
|
260
|
+
return 'Grid3.AutoContent';
|
|
260
261
|
return undefined;
|
|
261
262
|
}
|
|
262
263
|
/**
|
|
@@ -154,10 +154,11 @@ function extractSymbolLibraryImage(reference, options = {}) {
|
|
|
154
154
|
};
|
|
155
155
|
}
|
|
156
156
|
// Successfully extracted!
|
|
157
|
-
const
|
|
157
|
+
const data = resolved.data;
|
|
158
|
+
const format = data ? detectImageFormat(data) : 'unknown';
|
|
158
159
|
return {
|
|
159
160
|
found: true,
|
|
160
|
-
data
|
|
161
|
+
data,
|
|
161
162
|
format,
|
|
162
163
|
source: 'symbol-library',
|
|
163
164
|
reference: reference,
|
|
@@ -126,13 +126,15 @@ function searchSymbols(searchTerm, options = {}) {
|
|
|
126
126
|
// Exact match first
|
|
127
127
|
if (index.searchTerms.has(lowerSearchTerm)) {
|
|
128
128
|
const symbolFilename = index.searchTerms.get(lowerSearchTerm);
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
129
|
+
if (symbolFilename) {
|
|
130
|
+
results.push({
|
|
131
|
+
searchTerm: lowerSearchTerm,
|
|
132
|
+
symbolFilename,
|
|
133
|
+
displayName: index.filenames.get(symbolFilename) || lowerSearchTerm,
|
|
134
|
+
library: libraryName,
|
|
135
|
+
exactMatch: true,
|
|
136
|
+
});
|
|
137
|
+
}
|
|
136
138
|
}
|
|
137
139
|
// Fuzzy match if enabled
|
|
138
140
|
if (options.fuzzyMatch !== false) {
|
|
@@ -19,6 +19,7 @@ const pluginTypes_1 = require("./gridset/pluginTypes");
|
|
|
19
19
|
const commands_1 = require("./gridset/commands");
|
|
20
20
|
const symbols_1 = require("./gridset/symbols");
|
|
21
21
|
const resolver_2 = require("./gridset/resolver");
|
|
22
|
+
const idGenerator_1 = require("../optional/analytics/utils/idGenerator");
|
|
22
23
|
class GridsetProcessor extends baseProcessor_1.BaseProcessor {
|
|
23
24
|
constructor(options) {
|
|
24
25
|
super(options);
|
|
@@ -489,18 +490,62 @@ class GridsetProcessor extends baseProcessor_1.BaseProcessor {
|
|
|
489
490
|
const cellY = Math.max(0, parseInt(String(cell['@_Y'] || '1'), 10) - 1);
|
|
490
491
|
const colSpan = parseInt(String(cell['@_ColumnSpan'] || '1'), 10);
|
|
491
492
|
const rowSpan = parseInt(String(cell['@_RowSpan'] || '1'), 10);
|
|
493
|
+
// Extract scan block number (1-8) for block scanning support
|
|
494
|
+
const scanBlock = parseInt(String(cell['@_ScanBlock'] || '1'), 10);
|
|
495
|
+
// Extract visibility from Grid 3's <Visibility> child element
|
|
496
|
+
// Grid 3 stores visibility as a child element, not an attribute
|
|
497
|
+
// Valid values: Visible, Hidden, Disabled, PointerAndTouchOnly, TouchOnly, PointerOnly
|
|
498
|
+
const grid3Visibility = cell.Visibility || cell.visibility;
|
|
499
|
+
// Map Grid 3 visibility values to AAC standard values
|
|
500
|
+
// Grid 3 can have additional values like TouchOnly, PointerOnly that map to PointerAndTouchOnly
|
|
501
|
+
let cellVisibility;
|
|
502
|
+
if (grid3Visibility) {
|
|
503
|
+
const vis = String(grid3Visibility);
|
|
504
|
+
// Direct mapping for standard values
|
|
505
|
+
if (vis === 'Visible' ||
|
|
506
|
+
vis === 'Hidden' ||
|
|
507
|
+
vis === 'Disabled' ||
|
|
508
|
+
vis === 'PointerAndTouchOnly') {
|
|
509
|
+
cellVisibility = vis;
|
|
510
|
+
}
|
|
511
|
+
// Map Grid 3 specific values to AAC standard
|
|
512
|
+
else if (vis === 'TouchOnly' || vis === 'PointerOnly') {
|
|
513
|
+
cellVisibility = 'PointerAndTouchOnly';
|
|
514
|
+
}
|
|
515
|
+
// Grid 3 may use 'Empty' for cells that exist but have no content
|
|
516
|
+
else if (vis === 'Empty') {
|
|
517
|
+
cellVisibility = 'Empty';
|
|
518
|
+
}
|
|
519
|
+
// Unknown visibility - default to Visible
|
|
520
|
+
else {
|
|
521
|
+
cellVisibility = undefined; // Let it default
|
|
522
|
+
}
|
|
523
|
+
}
|
|
492
524
|
// Extract label from CaptionAndImage/Caption
|
|
493
525
|
const content = cell.Content;
|
|
494
526
|
const captionAndImage = content.CaptionAndImage || content.captionAndImage;
|
|
495
527
|
let label = captionAndImage?.Caption || captionAndImage?.caption || '';
|
|
528
|
+
// Check if cell has an image/symbol (needed to decide if we should keep it)
|
|
529
|
+
const hasImageCandidate = !!(captionAndImage?.Image ||
|
|
530
|
+
captionAndImage?.image ||
|
|
531
|
+
captionAndImage?.ImageName ||
|
|
532
|
+
captionAndImage?.imageName ||
|
|
533
|
+
captionAndImage?.Symbol ||
|
|
534
|
+
captionAndImage?.symbol);
|
|
496
535
|
// If no caption, try other sources or create a placeholder
|
|
497
536
|
if (!label) {
|
|
498
|
-
// For cells without captions
|
|
537
|
+
// For cells without captions, check if they have images/symbols before skipping
|
|
499
538
|
if (content.ContentType === 'AutoContent') {
|
|
500
539
|
label = `AutoContent_${idx}`;
|
|
501
540
|
}
|
|
541
|
+
else if (hasImageCandidate ||
|
|
542
|
+
content.ContentType === 'Workspace' ||
|
|
543
|
+
content.ContentType === 'LiveCell') {
|
|
544
|
+
// Keep cells with images/symbols even if no caption
|
|
545
|
+
label = `Cell_${idx}`;
|
|
546
|
+
}
|
|
502
547
|
else {
|
|
503
|
-
return; // Skip cells without labels
|
|
548
|
+
return; // Skip cells without labels AND without images/symbols
|
|
504
549
|
}
|
|
505
550
|
}
|
|
506
551
|
const message = label; // Use caption as message
|
|
@@ -922,12 +967,14 @@ class GridsetProcessor extends baseProcessor_1.BaseProcessor {
|
|
|
922
967
|
message: String(message),
|
|
923
968
|
targetPageId: navigationTarget ? String(navigationTarget) : undefined,
|
|
924
969
|
semanticAction: semanticAction,
|
|
970
|
+
semantic_id: cell.semantic_id || cell.SemanticId || undefined, // Extract semantic_id if present
|
|
925
971
|
image: declaredImageName,
|
|
926
972
|
resolvedImageEntry: resolvedImageEntry,
|
|
927
973
|
x: cellX,
|
|
928
974
|
y: cellY,
|
|
929
975
|
columnSpan: colSpan,
|
|
930
976
|
rowSpan: rowSpan,
|
|
977
|
+
scanBlock: scanBlock, // Add scan block number for block scanning metrics
|
|
931
978
|
contentType: pluginMetadata.cellType === pluginTypes_1.Grid3CellType.Regular
|
|
932
979
|
? 'Normal'
|
|
933
980
|
: pluginMetadata.cellType === pluginTypes_1.Grid3CellType.Workspace
|
|
@@ -940,6 +987,7 @@ class GridsetProcessor extends baseProcessor_1.BaseProcessor {
|
|
|
940
987
|
pluginMetadata.autoContentType,
|
|
941
988
|
symbolLibrary: symbolLibraryRef?.library || undefined,
|
|
942
989
|
symbolPath: symbolLibraryRef?.path || undefined,
|
|
990
|
+
visibility: cellVisibility,
|
|
943
991
|
style: {
|
|
944
992
|
...cellStyle,
|
|
945
993
|
...inlineStyle, // Inline styles override referenced styles
|
|
@@ -963,6 +1011,29 @@ class GridsetProcessor extends baseProcessor_1.BaseProcessor {
|
|
|
963
1011
|
});
|
|
964
1012
|
// Set the page's grid layout
|
|
965
1013
|
page.grid = gridLayout;
|
|
1014
|
+
// Generate clone_id for each button in the grid
|
|
1015
|
+
const semanticIds = [];
|
|
1016
|
+
const cloneIds = [];
|
|
1017
|
+
gridLayout.forEach((row, rowIndex) => {
|
|
1018
|
+
row.forEach((btn, colIndex) => {
|
|
1019
|
+
if (btn) {
|
|
1020
|
+
// Generate clone_id based on position and label
|
|
1021
|
+
btn.clone_id = (0, idGenerator_1.generateCloneId)(maxRows, maxCols, rowIndex, colIndex, btn.label);
|
|
1022
|
+
cloneIds.push(btn.clone_id);
|
|
1023
|
+
// Track semantic_id if present
|
|
1024
|
+
if (btn.semantic_id) {
|
|
1025
|
+
semanticIds.push(btn.semantic_id);
|
|
1026
|
+
}
|
|
1027
|
+
}
|
|
1028
|
+
});
|
|
1029
|
+
});
|
|
1030
|
+
// Track IDs on the page
|
|
1031
|
+
if (semanticIds.length > 0) {
|
|
1032
|
+
page.semantic_ids = semanticIds;
|
|
1033
|
+
}
|
|
1034
|
+
if (cloneIds.length > 0) {
|
|
1035
|
+
page.clone_ids = cloneIds;
|
|
1036
|
+
}
|
|
966
1037
|
}
|
|
967
1038
|
tree.addPage(page);
|
|
968
1039
|
}
|
|
@@ -1143,30 +1214,18 @@ class GridsetProcessor extends baseProcessor_1.BaseProcessor {
|
|
|
1143
1214
|
GridGuid: page.id,
|
|
1144
1215
|
// Calculate grid dimensions based on actual layout
|
|
1145
1216
|
ColumnDefinitions: this.calculateColumnDefinitions(page),
|
|
1146
|
-
RowDefinitions: this.calculateRowDefinitions(page),
|
|
1217
|
+
RowDefinitions: this.calculateRowDefinitions(page, false), // No automatic workspace row injection
|
|
1147
1218
|
AutoContentCommands: '',
|
|
1148
1219
|
Cells: page.buttons.length > 0
|
|
1149
1220
|
? {
|
|
1150
1221
|
Cell: [
|
|
1151
|
-
// Add workspace/message bar cell at the top of ALL pages
|
|
1152
|
-
// Grid3 uses 0-based coordinates; omit X and Y to use defaults (0, 0)
|
|
1153
|
-
{
|
|
1154
|
-
'@_ColumnSpan': 4,
|
|
1155
|
-
Content: {
|
|
1156
|
-
ContentType: 'Workspace',
|
|
1157
|
-
ContentSubType: 'Chat',
|
|
1158
|
-
Style: {
|
|
1159
|
-
BasedOnStyle: 'Workspace',
|
|
1160
|
-
},
|
|
1161
|
-
},
|
|
1162
|
-
},
|
|
1163
1222
|
// Regular button cells
|
|
1164
1223
|
...this.filterPageButtons(page.buttons).map((button, btnIndex) => {
|
|
1165
1224
|
const buttonStyleId = button.style ? addStyle(button.style) : '';
|
|
1166
1225
|
// Find button position in grid layout
|
|
1167
1226
|
const position = this.findButtonPosition(page, button, btnIndex);
|
|
1168
|
-
//
|
|
1169
|
-
const yOffset =
|
|
1227
|
+
// Use position directly from tree
|
|
1228
|
+
const yOffset = 0;
|
|
1170
1229
|
// Build CaptionAndImage object
|
|
1171
1230
|
const captionAndImage = {
|
|
1172
1231
|
Caption: button.label || '',
|
|
@@ -1207,6 +1266,8 @@ class GridsetProcessor extends baseProcessor_1.BaseProcessor {
|
|
|
1207
1266
|
'@_ColumnSpan': position.columnSpan,
|
|
1208
1267
|
'@_RowSpan': position.rowSpan,
|
|
1209
1268
|
Content: {
|
|
1269
|
+
ContentType: button.contentType === 'Normal' ? undefined : button.contentType,
|
|
1270
|
+
ContentSubType: button.contentSubType,
|
|
1210
1271
|
Commands: this.generateCommandsFromSemanticAction(button, tree),
|
|
1211
1272
|
CaptionAndImage: captionAndImage,
|
|
1212
1273
|
},
|
|
@@ -1322,15 +1383,16 @@ class GridsetProcessor extends baseProcessor_1.BaseProcessor {
|
|
|
1322
1383
|
};
|
|
1323
1384
|
}
|
|
1324
1385
|
// Helper method to calculate row definitions based on page layout
|
|
1325
|
-
calculateRowDefinitions(page) {
|
|
1386
|
+
calculateRowDefinitions(page, addWorkspaceOffset = false) {
|
|
1326
1387
|
let maxRows = 4; // Default minimum
|
|
1388
|
+
const offset = addWorkspaceOffset ? 1 : 0;
|
|
1327
1389
|
if (page.grid && page.grid.length > 0) {
|
|
1328
|
-
maxRows = Math.max(maxRows, page.grid.length);
|
|
1390
|
+
maxRows = Math.max(maxRows, page.grid.length + offset);
|
|
1329
1391
|
}
|
|
1330
1392
|
else {
|
|
1331
1393
|
// Fallback: estimate from button count
|
|
1332
1394
|
const estimatedCols = Math.ceil(Math.sqrt(page.buttons.length));
|
|
1333
|
-
maxRows = Math.max(4, Math.ceil(page.buttons.length / estimatedCols));
|
|
1395
|
+
maxRows = Math.max(4, Math.ceil(page.buttons.length / estimatedCols)) + offset;
|
|
1334
1396
|
}
|
|
1335
1397
|
return {
|
|
1336
1398
|
RowDefinition: Array(maxRows).fill({}),
|
|
@@ -7,6 +7,7 @@ export { OpmlProcessor } from './opmlProcessor';
|
|
|
7
7
|
export { SnapProcessor } from './snapProcessor';
|
|
8
8
|
export { TouchChatProcessor } from './touchchatProcessor';
|
|
9
9
|
export { AstericsGridProcessor } from './astericsGridProcessor';
|
|
10
|
+
export { ObfsetProcessor } from './obfsetProcessor';
|
|
10
11
|
export { getPageTokenImageMap, getAllowedImageEntries, openImage, generateGrid3Guid, createSettingsXml, createFileMapXml, getCommonDocumentsPath, findGrid3UserPaths, findGrid3HistoryDatabases, findGrid3Users, findGrid3Vocabularies, findGrid3UserHistory, isGrid3Installed, readGrid3History, readGrid3HistoryForUser, readAllGrid3History, type Grid3UserPath, type Grid3VocabularyPath, type Grid3HistoryEntry, } from './gridset/helpers';
|
|
11
12
|
export { getPageTokenImageMap as getGridsetPageTokenImageMap, getAllowedImageEntries as getGridsetAllowedImageEntries, openImage as openGridsetImage, generateGrid3Guid as generateGridsetGuid, createSettingsXml as createGridsetSettingsXml, createFileMapXml as createGridsetFileMapXml, getCommonDocumentsPath as getGridsetCommonDocumentsPath, findGrid3UserPaths as findGridsetUserPaths, findGrid3HistoryDatabases as findGridsetHistoryDatabases, findGrid3Users as findGridsetUsers, findGrid3Vocabularies as findGridsetVocabularies, findGrid3UserHistory as findGridsetUserHistory, isGrid3Installed as isGridsetInstalled, readGrid3History as readGridsetHistory, readGrid3HistoryForUser as readGridsetHistoryForUser, readAllGrid3History as readAllGridsetHistory, } from './gridset/helpers';
|
|
12
13
|
export { resolveGrid3CellImage } from './gridset/resolver';
|
package/dist/processors/index.js
CHANGED
|
@@ -14,9 +14,9 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
14
14
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
exports.
|
|
18
|
-
exports.
|
|
19
|
-
exports.openTouchChatImage = exports.getTouchChatAllowedImageEntries = exports.getTouchChatPageTokenImageMap = exports.readSnapUsageForUser = exports.readSnapUsage = exports.isSnapInstalled = exports.findSnapUserHistory = exports.findSnapUserVocabularies = exports.findSnapUsers = exports.findSnapPackagePath = exports.findSnapPackages = exports.openSnapImage = exports.getSnapAllowedImageEntries = exports.getSnapPageTokenImageMap = exports.getSymbolSearchStats = exports.countLibrarySymbols = exports.getSearchSuggestions = exports.getAllSearchTerms = exports.getSymbolDisplayName = exports.getSymbolFilename = exports.searchSymbolsWithReferences = exports.searchSymbols = exports.loadSearchIndexes = exports.parsePixFile = exports.createSymbolManifest = exports.exportSymbolReferencesToCsv = exports.suggestExtractionStrategy = exports.analyzeSymbolExtraction = exports.convertToAstericsImage = exports.extractSymbolLibraryImage = exports.extractButtonImage = exports.getSymbolSearchDir = exports.getSymbolsDir = exports.parseImageSymbolReference = exports.isSymbolLibraryReference = void 0;
|
|
17
|
+
exports.getNamedColor = exports.resolveGridsetPasswordFromEnv = exports.resolveGridsetPassword = exports.wordlistToXml = exports.updateWordlist = exports.extractWordlists = exports.createWordlist = exports.resolveGrid3CellImage = exports.readAllGridsetHistory = exports.readGridsetHistoryForUser = exports.readGridsetHistory = exports.isGridsetInstalled = exports.findGridsetUserHistory = exports.findGridsetVocabularies = exports.findGridsetUsers = exports.findGridsetHistoryDatabases = exports.findGridsetUserPaths = exports.getGridsetCommonDocumentsPath = exports.createGridsetFileMapXml = exports.createGridsetSettingsXml = exports.generateGridsetGuid = exports.openGridsetImage = exports.getGridsetAllowedImageEntries = exports.getGridsetPageTokenImageMap = exports.readAllGrid3History = exports.readGrid3HistoryForUser = exports.readGrid3History = exports.isGrid3Installed = exports.findGrid3UserHistory = exports.findGrid3Vocabularies = exports.findGrid3Users = exports.findGrid3HistoryDatabases = exports.findGrid3UserPaths = exports.getCommonDocumentsPath = exports.createFileMapXml = exports.createSettingsXml = exports.generateGrid3Guid = exports.openImage = exports.getAllowedImageEntries = exports.getPageTokenImageMap = exports.ObfsetProcessor = exports.AstericsGridProcessor = exports.TouchChatProcessor = exports.SnapProcessor = exports.OpmlProcessor = exports.ObfProcessor = exports.GridsetProcessor = exports.ExcelProcessor = exports.DotProcessor = exports.ApplePanelsProcessor = void 0;
|
|
18
|
+
exports.symbolReferenceToFilename = exports.getSymbolSearchIndexesDir = exports.getSymbolLibrariesDir = exports.getDefaultGrid3Path = exports.getSymbolLibraryDisplayName = exports.isKnownSymbolLibrary = exports.getSymbolPath = exports.getSymbolLibraryName = exports.createSymbolReference = exports.analyzeSymbolUsage = exports.extractSymbolReferences = exports.getSymbolLibraryInfo = exports.getAvailableSymbolLibraries = exports.resolveSymbolReference = exports.isSymbolReference = exports.parseSymbolReference = exports.Grid3CommandCategory = exports.GRID3_COMMANDS = exports.extractCommandParameters = exports.getAllPluginIds = exports.getAllCommandIds = exports.getCommandsByCategory = exports.getCommandsByPlugin = exports.getCommandDefinition = exports.detectCommand = exports.isRegularCell = exports.isAutoContentCell = exports.isLiveCell = exports.isWorkspaceCell = exports.getCellTypeDisplayName = exports.AUTOCONTENT_TYPES = exports.LIVECELL_TYPES = exports.WORKSPACE_TYPES = exports.Grid3CellType = exports.detectPluginCellType = exports.ensureAlphaChannelFromStyles = exports.SHAPE_NAMES = exports.CellBackgroundShape = exports.createCategoryStyle = exports.createDefaultStylesXml = exports.CATEGORY_STYLES = exports.DEFAULT_GRID3_STYLES = exports.ensureAlphaChannel = exports.normalizeColor = exports.darkenColor = exports.toHexColor = exports.clampAlpha = exports.clampColorChannel = exports.channelToHex = exports.rgbaToHex = void 0;
|
|
19
|
+
exports.openTouchChatImage = exports.getTouchChatAllowedImageEntries = exports.getTouchChatPageTokenImageMap = exports.readSnapUsageForUser = exports.readSnapUsage = exports.isSnapInstalled = exports.findSnapUserHistory = exports.findSnapUserVocabularies = exports.findSnapUsers = exports.findSnapPackagePath = exports.findSnapPackages = exports.openSnapImage = exports.getSnapAllowedImageEntries = exports.getSnapPageTokenImageMap = exports.getSymbolSearchStats = exports.countLibrarySymbols = exports.getSearchSuggestions = exports.getAllSearchTerms = exports.getSymbolDisplayName = exports.getSymbolFilename = exports.searchSymbolsWithReferences = exports.searchSymbols = exports.loadSearchIndexes = exports.parsePixFile = exports.createSymbolManifest = exports.exportSymbolReferencesToCsv = exports.suggestExtractionStrategy = exports.analyzeSymbolExtraction = exports.convertToAstericsImage = exports.extractSymbolLibraryImage = exports.extractButtonImage = exports.getSymbolSearchDir = exports.getSymbolsDir = exports.parseImageSymbolReference = exports.isSymbolLibraryReference = exports.SYMBOL_LIBRARIES = void 0;
|
|
20
20
|
var applePanelsProcessor_1 = require("./applePanelsProcessor");
|
|
21
21
|
Object.defineProperty(exports, "ApplePanelsProcessor", { enumerable: true, get: function () { return applePanelsProcessor_1.ApplePanelsProcessor; } });
|
|
22
22
|
var dotProcessor_1 = require("./dotProcessor");
|
|
@@ -35,6 +35,8 @@ var touchchatProcessor_1 = require("./touchchatProcessor");
|
|
|
35
35
|
Object.defineProperty(exports, "TouchChatProcessor", { enumerable: true, get: function () { return touchchatProcessor_1.TouchChatProcessor; } });
|
|
36
36
|
var astericsGridProcessor_1 = require("./astericsGridProcessor");
|
|
37
37
|
Object.defineProperty(exports, "AstericsGridProcessor", { enumerable: true, get: function () { return astericsGridProcessor_1.AstericsGridProcessor; } });
|
|
38
|
+
var obfsetProcessor_1 = require("./obfsetProcessor");
|
|
39
|
+
Object.defineProperty(exports, "ObfsetProcessor", { enumerable: true, get: function () { return obfsetProcessor_1.ObfsetProcessor; } });
|
|
38
40
|
// Gridset (Grid 3) helpers
|
|
39
41
|
var helpers_1 = require("./gridset/helpers");
|
|
40
42
|
Object.defineProperty(exports, "getPageTokenImageMap", { enumerable: true, get: function () { return helpers_1.getPageTokenImageMap; } });
|
|
@@ -6,12 +6,22 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
exports.ObfProcessor = void 0;
|
|
7
7
|
const baseProcessor_1 = require("../core/baseProcessor");
|
|
8
8
|
const treeStructure_1 = require("../core/treeStructure");
|
|
9
|
-
|
|
9
|
+
const idGenerator_1 = require("../optional/analytics/utils/idGenerator");
|
|
10
10
|
const adm_zip_1 = __importDefault(require("adm-zip"));
|
|
11
11
|
const fs_1 = __importDefault(require("fs"));
|
|
12
|
-
// Removed unused import: path
|
|
13
12
|
const obfValidator_1 = require("../validation/obfValidator");
|
|
14
13
|
const OBF_FORMAT_VERSION = 'open-board-0.1';
|
|
14
|
+
/**
|
|
15
|
+
* Map OBF hidden value to AAC standard visibility
|
|
16
|
+
* OBF: true = hidden, false/undefined = visible
|
|
17
|
+
* Maps to: 'Hidden' | 'Visible' | undefined
|
|
18
|
+
*/
|
|
19
|
+
function mapObfVisibility(hidden) {
|
|
20
|
+
if (hidden === undefined) {
|
|
21
|
+
return undefined; // Default to visible
|
|
22
|
+
}
|
|
23
|
+
return hidden ? 'Hidden' : 'Visible';
|
|
24
|
+
}
|
|
15
25
|
class ObfProcessor extends baseProcessor_1.BaseProcessor {
|
|
16
26
|
constructor(options) {
|
|
17
27
|
super(options);
|
|
@@ -42,12 +52,14 @@ class ObfProcessor extends baseProcessor_1.BaseProcessor {
|
|
|
42
52
|
id: String(btn?.id || ''),
|
|
43
53
|
label: String(btn?.label || ''),
|
|
44
54
|
message: String(btn?.vocalization || btn?.label || ''),
|
|
55
|
+
visibility: mapObfVisibility(btn.hidden),
|
|
45
56
|
style: {
|
|
46
57
|
backgroundColor: btn.background_color,
|
|
47
58
|
borderColor: btn.border_color,
|
|
48
59
|
},
|
|
49
60
|
semanticAction,
|
|
50
61
|
targetPageId: btn.load_board?.path,
|
|
62
|
+
semantic_id: btn.semantic_id, // Extract semantic_id if present
|
|
51
63
|
});
|
|
52
64
|
});
|
|
53
65
|
const buttonMap = new Map(buttons.map((btn) => [btn.id, btn]));
|
|
@@ -105,6 +117,29 @@ class ObfProcessor extends baseProcessor_1.BaseProcessor {
|
|
|
105
117
|
}
|
|
106
118
|
}
|
|
107
119
|
page.grid = grid;
|
|
120
|
+
// Generate clone_id for buttons in the grid
|
|
121
|
+
const semanticIds = [];
|
|
122
|
+
const cloneIds = [];
|
|
123
|
+
grid.forEach((row, rowIndex) => {
|
|
124
|
+
row.forEach((btn, colIndex) => {
|
|
125
|
+
if (btn) {
|
|
126
|
+
// Generate clone_id based on position and label
|
|
127
|
+
btn.clone_id = (0, idGenerator_1.generateCloneId)(rows, cols, rowIndex, colIndex, btn.label);
|
|
128
|
+
cloneIds.push(btn.clone_id);
|
|
129
|
+
// Track semantic_id if present
|
|
130
|
+
if (btn.semantic_id) {
|
|
131
|
+
semanticIds.push(btn.semantic_id);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
});
|
|
135
|
+
});
|
|
136
|
+
// Track IDs on the page
|
|
137
|
+
if (semanticIds.length > 0) {
|
|
138
|
+
page.semantic_ids = semanticIds;
|
|
139
|
+
}
|
|
140
|
+
if (cloneIds.length > 0) {
|
|
141
|
+
page.clone_ids = cloneIds;
|
|
142
|
+
}
|
|
108
143
|
}
|
|
109
144
|
}
|
|
110
145
|
return page;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OBF Set Processor - Handles JSON-formatted .obfset files
|
|
3
|
+
* These are pre-extracted board sets in JSON array format
|
|
4
|
+
*/
|
|
5
|
+
import { AACTree } from '../core/treeStructure';
|
|
6
|
+
import { BaseProcessor, ProcessorOptions } from '../core/baseProcessor';
|
|
7
|
+
export declare class ObfsetProcessor extends BaseProcessor {
|
|
8
|
+
constructor(options?: ProcessorOptions);
|
|
9
|
+
/**
|
|
10
|
+
* Extract all text content
|
|
11
|
+
*/
|
|
12
|
+
extractTexts(filePathOrBuffer: string | Buffer): string[];
|
|
13
|
+
/**
|
|
14
|
+
* Load an .obfset file (JSON array of boards)
|
|
15
|
+
*/
|
|
16
|
+
loadIntoTree(filePathOrBuffer: string | Buffer): AACTree;
|
|
17
|
+
/**
|
|
18
|
+
* Process texts (not supported for .obfset currently)
|
|
19
|
+
*/
|
|
20
|
+
processTexts(_filePathOrBuffer: string | Buffer, _translations: Map<string, string>, _outputPath: string): Buffer;
|
|
21
|
+
/**
|
|
22
|
+
* Save tree structure back to file
|
|
23
|
+
*/
|
|
24
|
+
saveFromTree(_tree: AACTree, _outputPath: string): void;
|
|
25
|
+
supportsExtension(extension: string): boolean;
|
|
26
|
+
}
|