@willwade/aac-processors 0.0.26 → 0.0.27

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.
@@ -39,6 +39,20 @@ export declare class MetricsCalculator {
39
39
  * Calculate what percentage of links to this board match semantic_id/clone_id
40
40
  */
41
41
  private calculateBoardLinkPercentages;
42
+ /**
43
+ * Calculate metrics for word forms (smart grammar predictions)
44
+ *
45
+ * Word forms are dynamically generated and not part of the tree structure.
46
+ * Their effort is calculated as:
47
+ * - Parent button's cumulative effort (to reach the button)
48
+ * - + Effort to select the word form from its position in predictions grid
49
+ *
50
+ * @param tree - The AAC tree
51
+ * @param buttons - Already calculated button metrics
52
+ * @param options - Metrics options
53
+ * @returns Array of word form button metrics
54
+ */
55
+ private calculateWordFormMetrics;
42
56
  /**
43
57
  * Calculate grid dimensions from the tree
44
58
  */
@@ -83,6 +83,11 @@ class MetricsCalculator {
83
83
  });
84
84
  // Update buttons using dynamic spelling effort if applicable
85
85
  const buttons = Array.from(knownButtons.values()).sort((a, b) => a.effort - b.effort);
86
+ // Calculate metrics for word forms (smart grammar predictions)
87
+ const wordFormMetrics = this.calculateWordFormMetrics(tree, buttons, options);
88
+ buttons.push(...wordFormMetrics);
89
+ // Re-sort after adding word forms
90
+ buttons.sort((a, b) => a.effort - b.effort);
86
91
  // Calculate grid dimensions
87
92
  const grid = this.calculateGridDimensions(tree);
88
93
  // Identify prediction metrics
@@ -560,6 +565,75 @@ class MetricsCalculator {
560
565
  boardPcts['all'] = totalLinks;
561
566
  return boardPcts;
562
567
  }
568
+ /**
569
+ * Calculate metrics for word forms (smart grammar predictions)
570
+ *
571
+ * Word forms are dynamically generated and not part of the tree structure.
572
+ * Their effort is calculated as:
573
+ * - Parent button's cumulative effort (to reach the button)
574
+ * - + Effort to select the word form from its position in predictions grid
575
+ *
576
+ * @param tree - The AAC tree
577
+ * @param buttons - Already calculated button metrics
578
+ * @param options - Metrics options
579
+ * @returns Array of word form button metrics
580
+ */
581
+ calculateWordFormMetrics(tree, buttons, _options = {}) {
582
+ const wordFormMetrics = [];
583
+ // Track which buttons already exist to avoid duplicates
584
+ const existingLabels = new Map();
585
+ buttons.forEach((btn) => existingLabels.set(btn.label.toLowerCase(), btn));
586
+ // Iterate through all pages to find buttons with predictions
587
+ Object.values(tree.pages).forEach((page) => {
588
+ page.grid.forEach((row) => {
589
+ row.forEach((btn) => {
590
+ if (!btn || !btn.predictions || btn.predictions.length === 0)
591
+ return;
592
+ // Find the parent button's metrics
593
+ const parentMetrics = buttons.find((b) => b.id === btn.id);
594
+ if (!parentMetrics)
595
+ return;
596
+ // Calculate effort for each word form
597
+ btn.predictions.forEach((wordForm, index) => {
598
+ const wordFormLower = wordForm.toLowerCase();
599
+ // Skip if this word form already exists as a regular button
600
+ if (existingLabels.has(wordFormLower)) {
601
+ return;
602
+ }
603
+ // Calculate effort based on position in predictions array
604
+ // Assume predictions are displayed in a grid layout (e.g., 2 columns)
605
+ const predictionsGridCols = 2; // Typical predictions layout
606
+ const predictionRowIndex = Math.floor(index / predictionsGridCols);
607
+ const predictionColIndex = index % predictionsGridCols;
608
+ // Calculate visual scan effort to reach this word form position
609
+ // Using similar logic to button scanning effort
610
+ const predictionPriorItems = predictionRowIndex * predictionsGridCols + predictionColIndex;
611
+ const predictionSelectionEffort = (0, effort_1.visualScanEffort)(predictionPriorItems);
612
+ // Word form effort = parent button's cumulative effort + selection effort
613
+ const wordFormEffort = parentMetrics.effort + predictionSelectionEffort;
614
+ // Mark as word form with a special ID pattern
615
+ const wordFormBtn = {
616
+ id: `${btn.id}_wordform_${index}`,
617
+ label: wordForm,
618
+ level: parentMetrics.level,
619
+ effort: wordFormEffort,
620
+ count: 1,
621
+ semantic_id: parentMetrics.semantic_id,
622
+ clone_id: parentMetrics.clone_id,
623
+ temporary_home_id: parentMetrics.temporary_home_id,
624
+ is_word_form: true, // Mark this as a word form metric
625
+ parent_button_id: btn.id, // Track parent button
626
+ parent_button_label: parentMetrics.label, // Track parent label
627
+ };
628
+ wordFormMetrics.push(wordFormBtn);
629
+ existingLabels.set(wordFormLower, wordFormBtn);
630
+ });
631
+ });
632
+ });
633
+ });
634
+ console.log(`📝 Calculated ${wordFormMetrics.length} word form metrics from predictions`);
635
+ return wordFormMetrics;
636
+ }
563
637
  /**
564
638
  * Calculate grid dimensions from the tree
565
639
  */
@@ -18,6 +18,9 @@ export interface ButtonMetrics {
18
18
  temporary_home_id?: string;
19
19
  comp_level?: number;
20
20
  comp_effort?: number;
21
+ is_word_form?: boolean;
22
+ parent_button_id?: string;
23
+ parent_button_label?: string;
21
24
  }
22
25
  /**
23
26
  * Board/page level analysis result
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@willwade/aac-processors",
3
- "version": "0.0.26",
3
+ "version": "0.0.27",
4
4
  "description": "A comprehensive TypeScript library for processing AAC (Augmentative and Alternative Communication) file formats with translation support",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",