@willwade/aac-processors 0.0.14 → 0.0.16
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 +58 -10
- package/dist/applePanels.d.ts +6 -0
- package/dist/applePanels.js +13 -0
- package/dist/astericsGrid.d.ts +6 -0
- package/dist/astericsGrid.js +13 -0
- package/dist/core/treeStructure.d.ts +1 -0
- package/dist/dot.d.ts +6 -0
- package/dist/dot.js +13 -0
- package/dist/excel.d.ts +6 -0
- package/dist/excel.js +13 -0
- package/dist/gridset.d.ts +17 -0
- package/dist/gridset.js +130 -0
- package/dist/index.d.ts +23 -2
- package/dist/index.js +36 -7
- package/dist/obf.d.ts +7 -0
- package/dist/obf.js +15 -0
- package/dist/obfset.d.ts +6 -0
- package/dist/obfset.js +13 -0
- package/dist/opml.d.ts +6 -0
- package/dist/opml.js +13 -0
- package/dist/processors/gridset/commands.js +15 -0
- package/dist/processors/gridset/pluginTypes.js +4 -4
- package/dist/processors/gridsetProcessor.d.ts +4 -0
- package/dist/processors/gridsetProcessor.js +315 -47
- package/dist/processors/index.d.ts +8 -18
- package/dist/processors/index.js +9 -175
- package/dist/processors/snapProcessor.js +105 -9
- package/dist/processors/touchchatProcessor.js +33 -13
- package/dist/snap.d.ts +7 -0
- package/dist/snap.js +24 -0
- package/dist/touchchat.d.ts +7 -0
- package/dist/touchchat.js +16 -0
- package/dist/translation.d.ts +13 -0
- package/dist/translation.js +21 -0
- package/dist/types/aac.d.ts +13 -3
- package/dist/types/aac.js +6 -2
- package/dist/utilities/analytics/metrics/comparison.d.ts +1 -0
- package/dist/utilities/analytics/metrics/comparison.js +52 -24
- package/dist/utilities/analytics/metrics/core.d.ts +7 -2
- package/dist/utilities/analytics/metrics/core.js +327 -197
- package/dist/utilities/analytics/metrics/effort.d.ts +8 -3
- package/dist/utilities/analytics/metrics/effort.js +10 -5
- package/dist/utilities/analytics/metrics/sentence.js +17 -4
- package/dist/utilities/analytics/metrics/types.d.ts +39 -0
- package/dist/utilities/analytics/metrics/vocabulary.js +1 -1
- package/dist/utilities/analytics/reference/index.js +12 -1
- package/dist/utilities/translation/translationProcessor.d.ts +2 -1
- package/dist/utilities/translation/translationProcessor.js +5 -2
- package/dist/validation.d.ts +13 -0
- package/dist/validation.js +28 -0
- package/package.json +58 -4
- package/dist/utilities/screenshotConverter.d.ts +0 -69
- package/dist/utilities/screenshotConverter.js +0 -453
|
@@ -74,6 +74,35 @@ class GridsetProcessor extends baseProcessor_1.BaseProcessor {
|
|
|
74
74
|
// Invalid or unknown format, return white
|
|
75
75
|
return '#FFFFFFFF';
|
|
76
76
|
}
|
|
77
|
+
/**
|
|
78
|
+
* Extract words from Grid3 WordList structure
|
|
79
|
+
*/
|
|
80
|
+
_extractWordsFromWordList(param) {
|
|
81
|
+
if (!param)
|
|
82
|
+
return [];
|
|
83
|
+
// Sometimes the param itself is the WordList, sometimes it has a WordList property
|
|
84
|
+
const wordList = param.WordList || param.wordlist || (param.Items || param.items ? param : undefined);
|
|
85
|
+
if (!wordList || !(wordList.Items || wordList.items))
|
|
86
|
+
return [];
|
|
87
|
+
const items = wordList.Items?.WordListItem || wordList.items?.wordlistitem || [];
|
|
88
|
+
const itemArr = Array.isArray(items) ? items : [items];
|
|
89
|
+
const words = [];
|
|
90
|
+
for (const item of itemArr) {
|
|
91
|
+
const text = item.Text || item.text;
|
|
92
|
+
if (text) {
|
|
93
|
+
const val = this.textOf(text);
|
|
94
|
+
if (val)
|
|
95
|
+
words.push(val);
|
|
96
|
+
}
|
|
97
|
+
else if (item['#text'] !== undefined) {
|
|
98
|
+
words.push(String(item['#text']));
|
|
99
|
+
}
|
|
100
|
+
else if (typeof item === 'string') {
|
|
101
|
+
words.push(item);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
return words;
|
|
105
|
+
}
|
|
77
106
|
// Helper function to generate Grid3 commands from semantic actions
|
|
78
107
|
generateCommandsFromSemanticAction(button, tree) {
|
|
79
108
|
const semanticAction = button.semanticAction;
|
|
@@ -280,8 +309,45 @@ class GridsetProcessor extends baseProcessor_1.BaseProcessor {
|
|
|
280
309
|
return undefined;
|
|
281
310
|
if (typeof val === 'string')
|
|
282
311
|
return val;
|
|
283
|
-
if (typeof val === '
|
|
284
|
-
return String(val
|
|
312
|
+
if (typeof val === 'number')
|
|
313
|
+
return String(val);
|
|
314
|
+
if (typeof val === 'object') {
|
|
315
|
+
if ('#text' in val)
|
|
316
|
+
return String(val['#text']);
|
|
317
|
+
// Handle Grid3 structured format <p><s><r>text</r></s></p>
|
|
318
|
+
// Can start at p, s, or r level
|
|
319
|
+
const parts = [];
|
|
320
|
+
const processS = (s) => {
|
|
321
|
+
if (!s)
|
|
322
|
+
return;
|
|
323
|
+
if (s.r !== undefined) {
|
|
324
|
+
const rElements = Array.isArray(s.r) ? s.r : [s.r];
|
|
325
|
+
for (const r of rElements) {
|
|
326
|
+
if (typeof r === 'object' && r !== null && '#text' in r) {
|
|
327
|
+
parts.push(String(r['#text']));
|
|
328
|
+
}
|
|
329
|
+
else {
|
|
330
|
+
parts.push(String(r));
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
};
|
|
335
|
+
if (val.p) {
|
|
336
|
+
const p = val.p;
|
|
337
|
+
const sElements = Array.isArray(p.s) ? p.s : p.s ? [p.s] : [];
|
|
338
|
+
sElements.forEach(processS);
|
|
339
|
+
}
|
|
340
|
+
else if (val.s) {
|
|
341
|
+
const sElements = Array.isArray(val.s) ? val.s : [val.s];
|
|
342
|
+
sElements.forEach(processS);
|
|
343
|
+
}
|
|
344
|
+
else if (val.r !== undefined) {
|
|
345
|
+
processS(val);
|
|
346
|
+
}
|
|
347
|
+
if (parts.length > 0) {
|
|
348
|
+
return parts.join('').trim();
|
|
349
|
+
}
|
|
350
|
+
}
|
|
285
351
|
return undefined;
|
|
286
352
|
}
|
|
287
353
|
extractTexts(filePathOrBuffer) {
|
|
@@ -404,15 +470,21 @@ class GridsetProcessor extends baseProcessor_1.BaseProcessor {
|
|
|
404
470
|
if (!grid)
|
|
405
471
|
return;
|
|
406
472
|
const gridId = this.textOf(grid.GridGuid || grid.gridGuid || grid.id);
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
473
|
+
const gridName = this.textOf(grid.Name) || this.textOf(grid.name) || this.textOf(grid['@_Name']);
|
|
474
|
+
const folderMatch = entry.entryName.match(/^Grids\/([^/]+)\//);
|
|
475
|
+
const folderName = folderMatch ? folderMatch[1] : undefined;
|
|
476
|
+
if (gridId) {
|
|
477
|
+
if (gridName) {
|
|
478
|
+
gridNameToIdMap.set(gridName, gridId);
|
|
479
|
+
gridIdToNameMap.set(gridId, gridName);
|
|
480
|
+
}
|
|
481
|
+
if (folderName) {
|
|
482
|
+
// Folder name is often used as the grid name in Jump.To commands
|
|
483
|
+
gridNameToIdMap.set(folderName, gridId);
|
|
484
|
+
if (!gridName) {
|
|
485
|
+
gridIdToNameMap.set(gridId, folderName);
|
|
486
|
+
}
|
|
487
|
+
}
|
|
416
488
|
}
|
|
417
489
|
}
|
|
418
490
|
catch (e) {
|
|
@@ -483,6 +555,32 @@ class GridsetProcessor extends baseProcessor_1.BaseProcessor {
|
|
|
483
555
|
for (let r = 0; r < maxRows; r++) {
|
|
484
556
|
gridLayout[r] = new Array(maxCols).fill(null);
|
|
485
557
|
}
|
|
558
|
+
const pagePredictedWords = new Set();
|
|
559
|
+
// Extract words from grid-level AutoContentCommands (e.g., Prediction Bar)
|
|
560
|
+
if (grid.AutoContentCommands) {
|
|
561
|
+
const collections = grid.AutoContentCommands.AutoContentCommandCollection;
|
|
562
|
+
const collectionArr = Array.isArray(collections)
|
|
563
|
+
? collections
|
|
564
|
+
: collections
|
|
565
|
+
? [collections]
|
|
566
|
+
: [];
|
|
567
|
+
collectionArr.forEach((collection) => {
|
|
568
|
+
const commands = collection.Commands?.Command;
|
|
569
|
+
const commandArr = Array.isArray(commands) ? commands : commands ? [commands] : [];
|
|
570
|
+
commandArr.forEach((command) => {
|
|
571
|
+
const commandId = command['@_ID'] || command.ID || command.id;
|
|
572
|
+
if (commandId === 'Prediction.PredictThis') {
|
|
573
|
+
const params = command.Parameter;
|
|
574
|
+
const paramArr = Array.isArray(params) ? params : params ? [params] : [];
|
|
575
|
+
const wordListParam = paramArr.find((p) => (p['@_Key'] || p.Key || p.key) === 'wordlist');
|
|
576
|
+
if (wordListParam) {
|
|
577
|
+
const words = this._extractWordsFromWordList(wordListParam);
|
|
578
|
+
words.forEach((w) => pagePredictedWords.add(w));
|
|
579
|
+
}
|
|
580
|
+
}
|
|
581
|
+
});
|
|
582
|
+
});
|
|
583
|
+
}
|
|
486
584
|
cellArr.forEach((cell, idx) => {
|
|
487
585
|
if (!cell || !cell.Content)
|
|
488
586
|
return;
|
|
@@ -526,7 +624,7 @@ class GridsetProcessor extends baseProcessor_1.BaseProcessor {
|
|
|
526
624
|
// Extract label from CaptionAndImage/Caption
|
|
527
625
|
const content = cell.Content;
|
|
528
626
|
const captionAndImage = content.CaptionAndImage || content.captionAndImage;
|
|
529
|
-
let label = captionAndImage?.Caption || captionAndImage?.caption || '';
|
|
627
|
+
let label = this.textOf(captionAndImage?.Caption || captionAndImage?.caption) || '';
|
|
530
628
|
// Check if cell has an image/symbol (needed to decide if we should keep it)
|
|
531
629
|
const hasImageCandidate = !!(captionAndImage?.Image ||
|
|
532
630
|
captionAndImage?.image ||
|
|
@@ -586,6 +684,25 @@ class GridsetProcessor extends baseProcessor_1.BaseProcessor {
|
|
|
586
684
|
if (commands) {
|
|
587
685
|
const commandArr = Array.isArray(commands) ? commands : [commands];
|
|
588
686
|
detectedCommands = commandArr.map((cmd) => (0, commands_1.detectCommand)(cmd));
|
|
687
|
+
// Scan all commands for vocabulary (predictions) before identifying primary action
|
|
688
|
+
commandArr.forEach((cmd) => {
|
|
689
|
+
const id = cmd['@_ID'] || cmd.ID || cmd.id;
|
|
690
|
+
if (id === 'Prediction.PredictThis') {
|
|
691
|
+
const params = cmd.Parameter || cmd.parameter;
|
|
692
|
+
const pArr = params ? (Array.isArray(params) ? params : [params]) : [];
|
|
693
|
+
let wlP;
|
|
694
|
+
for (const p of pArr) {
|
|
695
|
+
if (p['@_Key'] === 'wordlist' || p.Key === 'wordlist' || p.key === 'wordlist') {
|
|
696
|
+
wlP = p;
|
|
697
|
+
break;
|
|
698
|
+
}
|
|
699
|
+
}
|
|
700
|
+
if (wlP) {
|
|
701
|
+
const words = this._extractWordsFromWordList(wlP);
|
|
702
|
+
words.forEach((w) => pagePredictedWords.add(w));
|
|
703
|
+
}
|
|
704
|
+
}
|
|
705
|
+
});
|
|
589
706
|
for (const command of commandArr) {
|
|
590
707
|
const commandId = command['@_ID'] || command.ID || command.id;
|
|
591
708
|
const parameters = command.Parameter || command.parameter;
|
|
@@ -594,50 +711,52 @@ class GridsetProcessor extends baseProcessor_1.BaseProcessor {
|
|
|
594
711
|
? parameters
|
|
595
712
|
: [parameters]
|
|
596
713
|
: [];
|
|
597
|
-
// Helper to
|
|
598
|
-
const
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
// Handle p.s array or single s element
|
|
603
|
-
const sElements = Array.isArray(p.s) ? p.s : p.s ? [p.s] : [];
|
|
604
|
-
// Extract all r values and concatenate
|
|
605
|
-
const parts = [];
|
|
606
|
-
for (const s of sElements) {
|
|
607
|
-
if (s && s.r !== undefined) {
|
|
608
|
-
parts.push(String(s.r));
|
|
609
|
-
}
|
|
610
|
-
}
|
|
611
|
-
if (parts.length > 0) {
|
|
612
|
-
return parts.join('');
|
|
714
|
+
// Helper to get raw parameter object
|
|
715
|
+
const getRawParam = (key) => {
|
|
716
|
+
for (const param of paramArr) {
|
|
717
|
+
if (param['@_Key'] === key || param.Key === key || param.key === key) {
|
|
718
|
+
return param;
|
|
613
719
|
}
|
|
614
720
|
}
|
|
615
721
|
return undefined;
|
|
616
722
|
};
|
|
617
723
|
// Helper to get parameter value
|
|
618
724
|
const getParam = (key) => {
|
|
619
|
-
|
|
725
|
+
const param = getRawParam(key);
|
|
726
|
+
if (param === undefined)
|
|
620
727
|
return undefined;
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
return structuredValue;
|
|
632
|
-
}
|
|
633
|
-
// Fallback to string conversion
|
|
634
|
-
if (typeof param === 'string') {
|
|
635
|
-
return param;
|
|
636
|
-
}
|
|
637
|
-
}
|
|
638
|
-
}
|
|
728
|
+
const simpleValue = param['#text'] ?? param.text ?? param.value;
|
|
729
|
+
if (typeof simpleValue === 'string')
|
|
730
|
+
return simpleValue;
|
|
731
|
+
if (typeof simpleValue === 'number')
|
|
732
|
+
return String(simpleValue);
|
|
733
|
+
const structuredValue = this.textOf(param);
|
|
734
|
+
if (structuredValue !== undefined)
|
|
735
|
+
return structuredValue;
|
|
736
|
+
if (typeof param === 'string')
|
|
737
|
+
return param;
|
|
639
738
|
return undefined;
|
|
640
739
|
};
|
|
740
|
+
// Skip PredictThis in primary action loop as it was handled in pre-pass
|
|
741
|
+
// unless we need a primary action and nothing else exists
|
|
742
|
+
if (commandId === 'Prediction.PredictThis') {
|
|
743
|
+
if (!semanticAction) {
|
|
744
|
+
const wlParam = getRawParam('wordlist');
|
|
745
|
+
if (wlParam) {
|
|
746
|
+
const words = this._extractWordsFromWordList(wlParam);
|
|
747
|
+
semanticAction = {
|
|
748
|
+
category: treeStructure_1.AACSemanticCategory.COMMUNICATION,
|
|
749
|
+
intent: treeStructure_1.AACSemanticIntent.PLATFORM_SPECIFIC,
|
|
750
|
+
text: words.slice(0, 3).join(', '),
|
|
751
|
+
platformData: {
|
|
752
|
+
grid3: { commandId, parameters: { wordlist: words } },
|
|
753
|
+
},
|
|
754
|
+
fallback: { type: 'ACTION', message: 'Predict words' },
|
|
755
|
+
};
|
|
756
|
+
}
|
|
757
|
+
}
|
|
758
|
+
continue;
|
|
759
|
+
}
|
|
641
760
|
switch (commandId) {
|
|
642
761
|
case 'Jump.To': {
|
|
643
762
|
const gridTarget = getParam('grid');
|
|
@@ -689,10 +808,13 @@ class GridsetProcessor extends baseProcessor_1.BaseProcessor {
|
|
|
689
808
|
};
|
|
690
809
|
break;
|
|
691
810
|
case 'Jump.Home':
|
|
811
|
+
case 'Jump.SetHome':
|
|
692
812
|
// action
|
|
813
|
+
navigationTarget = tree.rootId || undefined;
|
|
693
814
|
semanticAction = {
|
|
694
815
|
category: treeStructure_1.AACSemanticCategory.NAVIGATION,
|
|
695
816
|
intent: treeStructure_1.AACSemanticIntent.GO_HOME,
|
|
817
|
+
targetId: tree.rootId || undefined,
|
|
696
818
|
platformData: {
|
|
697
819
|
grid3: {
|
|
698
820
|
commandId,
|
|
@@ -708,6 +830,79 @@ class GridsetProcessor extends baseProcessor_1.BaseProcessor {
|
|
|
708
830
|
type: 'GO_HOME',
|
|
709
831
|
};
|
|
710
832
|
break;
|
|
833
|
+
case 'Jump.ToKeyboard': {
|
|
834
|
+
// Navigate to the set keyboard if we found one in settings
|
|
835
|
+
const keyboardGridName = tree.keyboardGridName;
|
|
836
|
+
const keyboardPageId = gridNameToIdMap.get(keyboardGridName);
|
|
837
|
+
if (keyboardPageId) {
|
|
838
|
+
navigationTarget = keyboardPageId;
|
|
839
|
+
}
|
|
840
|
+
semanticAction = {
|
|
841
|
+
category: treeStructure_1.AACSemanticCategory.NAVIGATION,
|
|
842
|
+
intent: treeStructure_1.AACSemanticIntent.GO_HOME, // Close enough to 'navigation to keyboard'
|
|
843
|
+
targetId: keyboardPageId,
|
|
844
|
+
platformData: {
|
|
845
|
+
grid3: {
|
|
846
|
+
commandId,
|
|
847
|
+
parameters: {},
|
|
848
|
+
},
|
|
849
|
+
},
|
|
850
|
+
fallback: {
|
|
851
|
+
type: 'NAVIGATE',
|
|
852
|
+
targetPageId: keyboardPageId,
|
|
853
|
+
},
|
|
854
|
+
};
|
|
855
|
+
break;
|
|
856
|
+
}
|
|
857
|
+
case 'Action.InsertTextAndSpeak': {
|
|
858
|
+
const insertText = getParam('text');
|
|
859
|
+
semanticAction = {
|
|
860
|
+
category: treeStructure_1.AACSemanticCategory.COMMUNICATION,
|
|
861
|
+
intent: treeStructure_1.AACSemanticIntent.SPEAK_IMMEDIATE,
|
|
862
|
+
text: insertText,
|
|
863
|
+
platformData: {
|
|
864
|
+
grid3: {
|
|
865
|
+
commandId,
|
|
866
|
+
parameters: { text: insertText },
|
|
867
|
+
},
|
|
868
|
+
},
|
|
869
|
+
fallback: {
|
|
870
|
+
type: 'SPEAK',
|
|
871
|
+
message: insertText,
|
|
872
|
+
},
|
|
873
|
+
};
|
|
874
|
+
break;
|
|
875
|
+
}
|
|
876
|
+
case 'Prediction.PredictThis': {
|
|
877
|
+
const wlParam = getRawParam('wordlist');
|
|
878
|
+
if (wlParam) {
|
|
879
|
+
const words = this._extractWordsFromWordList(wlParam);
|
|
880
|
+
// Add to page-wide set of predicted words
|
|
881
|
+
words.forEach((w) => pagePredictedWords.add(w));
|
|
882
|
+
// Store words in a way that analyzer can find them
|
|
883
|
+
// For now, we'll attach to semanticAction so it can be used later
|
|
884
|
+
// We only set this as the primary action if we don't have one yet
|
|
885
|
+
if (!semanticAction) {
|
|
886
|
+
semanticAction = {
|
|
887
|
+
category: treeStructure_1.AACSemanticCategory.COMMUNICATION,
|
|
888
|
+
intent: treeStructure_1.AACSemanticIntent.PLATFORM_SPECIFIC,
|
|
889
|
+
text: words.slice(0, 3).join(', '), // Provide first few as preview
|
|
890
|
+
platformData: {
|
|
891
|
+
grid3: {
|
|
892
|
+
commandId,
|
|
893
|
+
parameters: { wordlist: words },
|
|
894
|
+
},
|
|
895
|
+
},
|
|
896
|
+
fallback: {
|
|
897
|
+
type: 'ACTION',
|
|
898
|
+
message: 'Predict words',
|
|
899
|
+
},
|
|
900
|
+
};
|
|
901
|
+
}
|
|
902
|
+
}
|
|
903
|
+
// Continue to check other commands (e.g. Action.InsertText)
|
|
904
|
+
continue;
|
|
905
|
+
}
|
|
711
906
|
case 'Action.Speak': {
|
|
712
907
|
// speak
|
|
713
908
|
const speakUnit = getParam('unit');
|
|
@@ -963,6 +1158,19 @@ class GridsetProcessor extends baseProcessor_1.BaseProcessor {
|
|
|
963
1158
|
if (content.Style.FontSize)
|
|
964
1159
|
inlineStyle.fontSize = parseInt(String(content.Style.FontSize));
|
|
965
1160
|
}
|
|
1161
|
+
// Extract grammar tags from commands (Smart Grammar)
|
|
1162
|
+
const grammar = {};
|
|
1163
|
+
detectedCommands.forEach((cmd) => {
|
|
1164
|
+
if (cmd.parameters.pos)
|
|
1165
|
+
grammar.pos = cmd.parameters.pos;
|
|
1166
|
+
if (cmd.parameters.person)
|
|
1167
|
+
grammar.person = cmd.parameters.person;
|
|
1168
|
+
if (cmd.parameters.number)
|
|
1169
|
+
grammar.number = cmd.parameters.number;
|
|
1170
|
+
if (cmd.parameters.feature)
|
|
1171
|
+
grammar.feature = cmd.parameters.feature;
|
|
1172
|
+
});
|
|
1173
|
+
const isSmartGrammarCell = Object.keys(grammar).length > 0;
|
|
966
1174
|
const button = new treeStructure_1.AACButton({
|
|
967
1175
|
id: `${gridId}_btn_${idx}`,
|
|
968
1176
|
label: String(label),
|
|
@@ -998,6 +1206,8 @@ class GridsetProcessor extends baseProcessor_1.BaseProcessor {
|
|
|
998
1206
|
pluginMetadata: pluginMetadata, // Store full plugin metadata for future use
|
|
999
1207
|
grid3Commands: detectedCommands, // Store detected command metadata
|
|
1000
1208
|
symbolLibraryRef: symbolLibraryRef, // Store full symbol reference
|
|
1209
|
+
grammar: isSmartGrammarCell ? grammar : undefined,
|
|
1210
|
+
isSmartGrammarCell: isSmartGrammarCell,
|
|
1001
1211
|
},
|
|
1002
1212
|
});
|
|
1003
1213
|
// Add button to page
|
|
@@ -1011,6 +1221,59 @@ class GridsetProcessor extends baseProcessor_1.BaseProcessor {
|
|
|
1011
1221
|
}
|
|
1012
1222
|
}
|
|
1013
1223
|
});
|
|
1224
|
+
// Process predicted words: Populate AutoContent slots first, then add virtual buttons at bottom
|
|
1225
|
+
if (pagePredictedWords.size > 0) {
|
|
1226
|
+
const extraWords = Array.from(pagePredictedWords).filter((w) => w.trim().length > 0);
|
|
1227
|
+
if (extraWords.length > 0) {
|
|
1228
|
+
let wordIdx = 0;
|
|
1229
|
+
// Step 1: Fill dedicated AutoContent prediction slots (e.g. at the top)
|
|
1230
|
+
page.buttons.forEach((btn) => {
|
|
1231
|
+
if (btn.contentType === 'AutoContent' &&
|
|
1232
|
+
btn.contentSubType === 'Prediction' &&
|
|
1233
|
+
wordIdx < extraWords.length) {
|
|
1234
|
+
const word = extraWords[wordIdx++];
|
|
1235
|
+
btn.label = word;
|
|
1236
|
+
btn.message = word;
|
|
1237
|
+
btn.semanticAction = {
|
|
1238
|
+
category: treeStructure_1.AACSemanticCategory.COMMUNICATION,
|
|
1239
|
+
intent: treeStructure_1.AACSemanticIntent.INSERT_TEXT,
|
|
1240
|
+
text: word,
|
|
1241
|
+
fallback: { type: 'SPEAK', message: word },
|
|
1242
|
+
};
|
|
1243
|
+
}
|
|
1244
|
+
});
|
|
1245
|
+
// Step 2: Add remaining words as virtual buttons at the bottom
|
|
1246
|
+
if (wordIdx < extraWords.length) {
|
|
1247
|
+
const remainingWords = extraWords.slice(wordIdx);
|
|
1248
|
+
const extraRowsCount = Math.ceil(remainingWords.length / maxCols);
|
|
1249
|
+
for (let r = 0; r < extraRowsCount; r++) {
|
|
1250
|
+
const row = new Array(maxCols).fill(null);
|
|
1251
|
+
for (let c = 0; c < maxCols; c++) {
|
|
1252
|
+
const idx = r * maxCols + c;
|
|
1253
|
+
if (idx < remainingWords.length) {
|
|
1254
|
+
const word = remainingWords[idx];
|
|
1255
|
+
const vBtn = new treeStructure_1.AACButton({
|
|
1256
|
+
id: `${gridId}_vpredict_${wordIdx + idx}`,
|
|
1257
|
+
label: word,
|
|
1258
|
+
message: word,
|
|
1259
|
+
x: c,
|
|
1260
|
+
y: maxRows + r,
|
|
1261
|
+
semanticAction: {
|
|
1262
|
+
category: treeStructure_1.AACSemanticCategory.COMMUNICATION,
|
|
1263
|
+
intent: treeStructure_1.AACSemanticIntent.INSERT_TEXT,
|
|
1264
|
+
text: word,
|
|
1265
|
+
fallback: { type: 'SPEAK', message: word },
|
|
1266
|
+
},
|
|
1267
|
+
});
|
|
1268
|
+
row[c] = vBtn;
|
|
1269
|
+
page.addButton(vBtn);
|
|
1270
|
+
}
|
|
1271
|
+
}
|
|
1272
|
+
gridLayout.push(row);
|
|
1273
|
+
}
|
|
1274
|
+
}
|
|
1275
|
+
}
|
|
1276
|
+
}
|
|
1014
1277
|
// Set the page's grid layout
|
|
1015
1278
|
page.grid = gridLayout;
|
|
1016
1279
|
// Generate clone_id for each button in the grid
|
|
@@ -1068,6 +1331,11 @@ class GridsetProcessor extends baseProcessor_1.BaseProcessor {
|
|
|
1068
1331
|
tree.rootId = homeGridId;
|
|
1069
1332
|
}
|
|
1070
1333
|
}
|
|
1334
|
+
const keyboardGridName = settingsData?.GridSetSettings?.KeyboardGrid ||
|
|
1335
|
+
settingsData?.gridSetSettings?.keyboardGrid;
|
|
1336
|
+
if (keyboardGridName && typeof keyboardGridName === 'string') {
|
|
1337
|
+
tree.keyboardGridName = keyboardGridName;
|
|
1338
|
+
}
|
|
1071
1339
|
}
|
|
1072
1340
|
}
|
|
1073
1341
|
catch (e) {
|
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AAC Processor Classes
|
|
3
|
+
*
|
|
4
|
+
* All processor classes for different AAC file formats.
|
|
5
|
+
* For platform-specific utilities (Gridset, Snap, etc.), use the namespace imports:
|
|
6
|
+
* - import { Gridset } from 'aac-processors/gridset';
|
|
7
|
+
* - import { Snap } from 'aac-processors/snap';
|
|
8
|
+
*/
|
|
1
9
|
export { ApplePanelsProcessor } from './applePanelsProcessor';
|
|
2
10
|
export { DotProcessor } from './dotProcessor';
|
|
3
11
|
export { ExcelProcessor } from './excelProcessor';
|
|
@@ -8,21 +16,3 @@ export { SnapProcessor } from './snapProcessor';
|
|
|
8
16
|
export { TouchChatProcessor } from './touchchatProcessor';
|
|
9
17
|
export { AstericsGridProcessor } from './astericsGridProcessor';
|
|
10
18
|
export { ObfsetProcessor } from './obfsetProcessor';
|
|
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';
|
|
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';
|
|
13
|
-
export { resolveGrid3CellImage } from './gridset/resolver';
|
|
14
|
-
export { createWordlist, extractWordlists, updateWordlist, wordlistToXml, type WordList, type WordListItem, } from './gridset/wordlistHelpers';
|
|
15
|
-
export { resolveGridsetPassword, resolveGridsetPasswordFromEnv } from './gridset/password';
|
|
16
|
-
export { getNamedColor, rgbaToHex, channelToHex, clampColorChannel, clampAlpha, toHexColor, darkenColor, normalizeColor, ensureAlphaChannel, } from './gridset/colorUtils';
|
|
17
|
-
export { DEFAULT_GRID3_STYLES, CATEGORY_STYLES, createDefaultStylesXml, createCategoryStyle, CellBackgroundShape, SHAPE_NAMES, } from './gridset/styleHelpers';
|
|
18
|
-
export { ensureAlphaChannel as ensureAlphaChannelFromStyles } from './gridset/styleHelpers';
|
|
19
|
-
export { detectPluginCellType, type Grid3PluginMetadata, Grid3CellType, WORKSPACE_TYPES, LIVECELL_TYPES, AUTOCONTENT_TYPES, getCellTypeDisplayName, isWorkspaceCell, isLiveCell, isAutoContentCell, isRegularCell, } from './gridset/pluginTypes';
|
|
20
|
-
export { detectCommand, getCommandDefinition, getCommandsByPlugin, getCommandsByCategory, getAllCommandIds, getAllPluginIds, extractCommandParameters, GRID3_COMMANDS, type Grid3CommandDefinition, type CommandParameter, type ExtractedParameters, Grid3CommandCategory, } from './gridset/commands';
|
|
21
|
-
export * from './gridset/index';
|
|
22
|
-
export { parseSymbolReference, isSymbolReference, resolveSymbolReference, getAvailableSymbolLibraries, getSymbolLibraryInfo, extractSymbolReferences, analyzeSymbolUsage, createSymbolReference, getSymbolLibraryName, getSymbolPath, isKnownSymbolLibrary, getSymbolLibraryDisplayName, getDefaultGrid3Path, getSymbolLibrariesDir, getSymbolSearchIndexesDir, symbolReferenceToFilename, SYMBOL_LIBRARIES, } from './gridset/symbols';
|
|
23
|
-
export { isSymbolLibraryReference, parseImageSymbolReference } from './gridset/resolver';
|
|
24
|
-
export { getSymbolsDir, getSymbolSearchDir } from './gridset/symbols';
|
|
25
|
-
export { extractButtonImage, extractSymbolLibraryImage, convertToAstericsImage, analyzeSymbolExtraction, suggestExtractionStrategy, exportSymbolReferencesToCsv, createSymbolManifest, } from './gridset/symbolExtractor';
|
|
26
|
-
export { parsePixFile, loadSearchIndexes, searchSymbols, searchSymbolsWithReferences, getSymbolFilename, getSymbolDisplayName, getAllSearchTerms, getSearchSuggestions, countLibrarySymbols, getSymbolSearchStats, } from './gridset/symbolSearch';
|
|
27
|
-
export { getPageTokenImageMap as getSnapPageTokenImageMap, getAllowedImageEntries as getSnapAllowedImageEntries, openImage as openSnapImage, findSnapPackages, findSnapPackagePath, findSnapUsers, findSnapUserVocabularies, findSnapUserHistory, isSnapInstalled, readSnapUsage, readSnapUsageForUser, type SnapPackagePath, type SnapUserInfo, type SnapUsageEntry, } from './snap/helpers';
|
|
28
|
-
export { getPageTokenImageMap as getTouchChatPageTokenImageMap, getAllowedImageEntries as getTouchChatAllowedImageEntries, openImage as openTouchChatImage, } from './touchchat/helpers';
|