"use strict"; // Prefix predictor for the mnemonicode wordlist. Words are not distinct at // any fixed prefix length (one pair, "capital"/"capitan", needs 6 of 7 // chars), so matching always refines on the full typed prefix rather than // assuming a fixed cutoff. function lowerBound(sorted, target) { let lo = 0; let hi = sorted.length; while (lo < hi) { const mid = (lo + hi) >>> 1; if (sorted[mid] < target) lo = mid + 1; else hi = mid; } return lo; } class Predictor { constructor(words) { this.words = words.slice().sort(); } // All words starting with `prefix`, in alphabetical order. matches(prefix) { const lo = lowerBound(this.words, prefix); const hi = lowerBound(this.words, prefix + "￿"); return this.words.slice(lo, hi); } // Prediction state for a prefix the user has typed so far. predict(prefix) { const matches = this.matches(prefix); return { prefix, matches, isWord: matches.includes(prefix), completion: matches.length === 1 ? matches[0] : null, }; } } module.exports = { Predictor };