function binSearch(list, word) { let first = 0; let last = list.length; for (;;) { let ptr = (first + (last - first) / 2) | 0; if (list[ptr] === word) { return true; } else if (last - first <= 1) { return false; } else if (list[ptr] > word) { last = ptr; } else if (list[ptr] < word) { first = ptr; } } } export class WordSource { constructor() { this._wordData = null; this._pattern = null; this._currentWord = null; } isWord(word) { let list = this._wordData.words[word.length.toString()]; if (!list) { return false; } return binSearch(list, word); } async getCurrentWord() { if (this._currentWord) { return this._currentWord; } let words = await this._fetchAllWordsIfNecessary(); let idx = this._pattern.index["4"][7]; this._currentWord = words.words["4"][idx]; return this._currentWord; } async nextWord() { if (this._currentWord >= this._words.length - 1) { return false; } this._currentWord += 1; return true; } async _fetchAllWordsIfNecessary() { if (this._wordData) { return this._wordData; } this._wordData = await (await fetch("/assets/data/words.json")).json(); this._pattern = await (await fetch("/assets/data/shuffle_pattern.json")).json(); return this._wordData; } }