| 1 | /** |
| 2 | * The same fact remembered twice (two runs that learned it, or one saved |
| 3 | * again) is shown once: the first of them in the order given, so a pinned |
| 4 | * one or the newest wins. Facts match when their words do, whatever the |
| 5 | * case, spacing or a closing full stop. |
| 6 | */ |
| 7 | export function distinctFacts<T extends { text: string }>(facts: T[]): T[] { |
| 8 | const seen = new Set<string>(); |
| 9 | return facts.filter((fact) => { |
| 10 | const key = fact.text.trim().toLowerCase().replace(/\s+/g, " ").replace(/[.!]+$/, ""); |
| 11 | if (seen.has(key)) return false; |
| 12 | seen.add(key); |
| 13 | return true; |
| 14 | }); |
| 15 | } |