From ef5a6f20bdc642efc59cbd50b3040833e74a77fd Mon Sep 17 00:00:00 2001 From: "Joshua A. Horton" Date: Sun, 24 Mar 2024 21:51:08 +0700 Subject: [PATCH 01/26] feat(common/models/templates): initial trie node compression/decompression Aims for a UCS-2 encoded string and does not shy away from unpaired surrogates in the encoding. --- common/models/templates/src/trie-model.ts | 12 +- .../models/templates/src/tries/compression.ts | 245 ++++++++++++++++++ .../models/templates/test/trie-compression.js | 212 +++++++++++++++ 3 files changed, 465 insertions(+), 4 deletions(-) create mode 100644 common/models/templates/src/tries/compression.ts create mode 100644 common/models/templates/test/trie-compression.js diff --git a/common/models/templates/src/trie-model.ts b/common/models/templates/src/trie-model.ts index cbbe9181623..b5f33ca6ff2 100644 --- a/common/models/templates/src/trie-model.ts +++ b/common/models/templates/src/trie-model.ts @@ -384,14 +384,18 @@ interface Wordform2Key { // trie-ing is copyright (C) 2015–2017 Conrad Irwin. // Distributed under the terms of the MIT license: // https://github.com/ConradIrwin/trie-ing/blob/df55d7af7068d357829db9e0a7faa8a38add1d1d/LICENSE +// +// Trie compression / decompression seen here is fully custom. -type Node = InternalNode | Leaf; +type CompressedNode = string; + +export type Node = InternalNode | Leaf; /** * An internal node in the trie. Internal nodes NEVER contain entries; if an * internal node should contain an entry, then it has a dummy leaf node (see * below), that can be accessed by node.children["\uFDD0"]. */ -interface InternalNode { +export interface InternalNode { type: 'internal'; weight: number; /** Maintains the keys of children in descending order of weight. */ @@ -404,7 +408,7 @@ interface InternalNode { children: { [codeunit: string]: Node }; } /** Only leaf nodes actually contain entries (i.e., the words proper). */ -interface Leaf { +export interface Leaf { type: 'leaf'; weight: number; entries: Entry[]; @@ -413,7 +417,7 @@ interface Leaf { /** * An entry in the prefix trie (stored in leaf nodes exclusively!) */ -interface Entry { +export interface Entry { /** The actual word form, stored in the trie. */ content: string; /** A search key that usually simplifies the word form, for ease of search. */ diff --git a/common/models/templates/src/tries/compression.ts b/common/models/templates/src/tries/compression.ts new file mode 100644 index 00000000000..c7392891010 --- /dev/null +++ b/common/models/templates/src/tries/compression.ts @@ -0,0 +1,245 @@ +import { Entry, InternalNode, Leaf, Node } from "../trie-model.js"; + +const SINGLE_CHAR_RANGE = Math.pow(2, 16); +const WEIGHT_WIDTH = 2; +const NODE_SIZE_WIDTH = 2; + +export function decompressNumber(str: string, start: number, end: number) { + end ??= str.length; + let num = 0; + + for(let i = start; i < end; i++) { + let val = str.charCodeAt(i); + num = num * SINGLE_CHAR_RANGE + val; + } + + return num; +} + +export function compressNumber(num: number, width?: number) { + let compressed = ''; + width ||= 1; + + // Note: JS bit-shift operators assume 32-bit signed ints. + // JS numbers can easily represent larger ints, though. + while(width > 0) { + const piece = num % SINGLE_CHAR_RANGE; + num = Math.floor(num / SINGLE_CHAR_RANGE); + + compressed = String.fromCharCode(piece) + compressed; + + width--; + } + + if(num) { + throw new Error(`Could not properly compress ${num} within specified char width of ${width}`); + } + + return compressed; +} + +const ENTRY_HEADER_WIDTH = NODE_SIZE_WIDTH + WEIGHT_WIDTH + 1; + +// encoded ENTRY: +// - entryLen: 2 char +// - total encoded size of all following bits. +// - as raw, concatenated string data - no JSON.stringify action taken. +// - weight: 2? chars (with quote-offset on each char?) +// - keyLen: 1 char (with quote-offset?) +// - contentLen: safe to infer from all other values +// - key: string: from index [header+5] to [header+5 + keyLen - 1] +// - content: string: from [header+5 + keyLen] to [header+5 + keyLen + contentLen - 1] + +export function compressEntry(entry: Entry): string { + const { key, content, weight } = entry; + + const keyLenEnc = compressNumber(key.length); + const weightEnc = compressNumber(weight, WEIGHT_WIDTH); + + const entryLenEnc = compressNumber(key.length + content.length + ENTRY_HEADER_WIDTH, 2); + + return `${entryLenEnc}${weightEnc}${keyLenEnc}${key}${content}`; +} + +export function decompressEntry(str: string, baseIndex: number): Entry { + baseIndex ||= 0; + + const entryLen = decompressNumber(str, baseIndex + 0, baseIndex + NODE_SIZE_WIDTH); + // c8 ignore start + if(str.length < baseIndex + entryLen) { + throw new Error('Parts of the encoded entry are missing'); + } + // c8 ignore end + + const headerEnd = baseIndex + ENTRY_HEADER_WIDTH; + const weight = decompressNumber(str, baseIndex + NODE_SIZE_WIDTH, headerEnd - 1); + const keyLen = decompressNumber(str, headerEnd - 1, headerEnd); + + const contentStart = headerEnd + keyLen; + const key = str.substring(headerEnd, contentStart); + const content = str.substring(contentStart, baseIndex + entryLen); + + return { + key: key as any, // due to special `SearchKey` type shenanigans in its definition. + content: content, + weight: weight + } +} + + +// BOTH node types: +// totalLen: 2 chars (fixed position, size) - size of the encoded node. +// weight: number - could be encoded. +// - 2^32 ~= 4*10^9, representable in 2 chars... if it weren't for `"`-escaping. +// - 2^64 ~= 1.8*10^19 - surely far, far more than enough. +// Next char: indicates BOTH a flag of something and a high-bit indicating 'leaf' or 'internal'. +// - function of other bits will be indicated by their sections. + +export const NODE_TYPE_INDEX = NODE_SIZE_WIDTH + WEIGHT_WIDTH; + +export function compressNode(node: Node) { + let encodedSpecifics = node.type == 'leaf' ? compressLeaf(node) : compressInternal(node); + let weightEnc = compressNumber(node.weight, WEIGHT_WIDTH); + let charLength = encodedSpecifics.length + NODE_SIZE_WIDTH + WEIGHT_WIDTH; + + return `${compressNumber(charLength, 2)}${weightEnc}${encodedSpecifics}`; +} + +export function decompressNode(str: string, baseIndex: number) { + baseIndex ||= 0; + + const entryLen = decompressNumber(str, baseIndex + 0, baseIndex + NODE_SIZE_WIDTH); + // c8 ignore start + if(str.length < baseIndex + entryLen) { + throw new Error('Parts of the encoded node are missing'); + } + // c8 ignore end + + const typeFlagSrc = decompressNumber(str, baseIndex + NODE_TYPE_INDEX, baseIndex + NODE_TYPE_INDEX + 1); + const isLeafType = typeFlagSrc & 0x8000; + + return isLeafType ? decompressLeaf(str, baseIndex) : decompressInternal(str, baseIndex); +} + +// encoded LEAF: +// - BOTH-section header +// - entriesCnt: 1 char (fixed position) +// - type flag overlaps here - high bit of the representing char should be one. +// - entries: full encoding of all contained entries. + +function compressLeaf(leaf: Leaf): string { + const entries = leaf.entries; + + // key, content, weight - per entry + const entryCntAndType = entries.length | 0x8000; + // c8 ignore start + if(entries.length >= 0x8000) { + throw new Error("Cannot encode leaf: too many direct entries"); + } + // c8 ignore end + let compressedEntries = [compressNumber(entryCntAndType)].concat(entries.map((entry) => { + // if already compressed, no need to recompress it. + return typeof entry == 'string' ? entry : compressEntry(entry); + })); + + return compressedEntries.join(''); +} + +function decompressLeaf(str: string, baseIndex: number): Omit & {entries: string[]} { + const weight = decompressNumber(str, baseIndex + NODE_SIZE_WIDTH, baseIndex + NODE_SIZE_WIDTH + WEIGHT_WIDTH); + + // Assumes string-subsection size check has passed. + const entryCntSrc = decompressNumber(str, baseIndex + NODE_TYPE_INDEX, baseIndex + NODE_TYPE_INDEX + 1); + // Remove the type-flag bit indicating 'leaf node'. + const entryCnt = entryCntSrc & 0x007F; + + let compressedEntries: string[] = []; + baseIndex = baseIndex + NODE_TYPE_INDEX + 1; + for(let i = 0; i < entryCnt; i++) { + const entryWidth = decompressNumber(str, baseIndex, baseIndex+2); + const nextIndex = baseIndex + entryWidth; + compressedEntries.push(str.substring(baseIndex, nextIndex)); + baseIndex = nextIndex; + } + + return { + type: 'leaf', + weight: weight, + + // To consider: is it better to just make a 'lazy span' against the original string? + // - would use more memory, especially once a Trie is "mostly" decompressed + // - current approach 'discards' decoded parts of the original string. + // - would likely decompress a bit faster. + entries: compressedEntries + } +} + +// encoded INTERNAL: +// - BOTH-section header +// - valLen: 1 char (fixed position, size) - we shouldn't ever have an array of > 65000, right? +// - is also the count for children. +// - type flag overlaps here - high bit of the representing char should be zero. +// - values: string +// - ezpz - they're already single-char strings. +// - children: full encoding of next-layer nodes. Same order as the entries are found within `values`. +// - that is, no need to insert keys. +// - first two bits: length of following bits... so can use that to calculate offset for next entry's +// encoding start. + +function compressInternal(node: InternalNode): string { + const values = node.values; + const valueCntAndType = values.length; + // c8 ignore start + if(valueCntAndType >= 0x8000) { + throw new Error("Cannot encode node: too many direct children"); + } + // c8 ignore end + + const compressedChildren = values.map((value) => { + const child = node.children[value]; + // No need to recompress it if it's already compressed. + return typeof child == 'string' ? child : compressNode(child); + }); + + const totalArr = [compressNumber(valueCntAndType)].concat(values).concat(compressedChildren); + return totalArr.join(''); +} + +function decompressInternal(str: string, baseIndex: number): Omit & { children: {[char: string]: string} } { + const weight = decompressNumber(str, baseIndex + NODE_SIZE_WIDTH, baseIndex + NODE_SIZE_WIDTH + WEIGHT_WIDTH); + + // Assumes string-subsection size check has passed. + const childCnt = decompressNumber(str, baseIndex + NODE_TYPE_INDEX, baseIndex + NODE_TYPE_INDEX + 1); + + baseIndex = baseIndex + NODE_TYPE_INDEX + 1; + let nextIndex = baseIndex + childCnt; + const values = str.substring(baseIndex, nextIndex).split(''); + baseIndex = nextIndex; + + let compressedChildren: {[char: string]: string} = {}; + for(let i = 0; i < childCnt; i++) { + const childWidth = decompressNumber(str, baseIndex, baseIndex+2); + nextIndex = baseIndex + childWidth; + compressedChildren[values[i]] = str.substring(baseIndex, nextIndex); + baseIndex = nextIndex; + } + + return { + type: 'internal', + weight: weight, + values: values, + // To consider: is it better to just make a 'lazy span' against the original string? + // - would use more memory, especially once a Trie is "mostly" decompressed + // - would likely decompress a bit faster. + children: compressedChildren + } +} + +// Finally... +// +// encoded ROOT: +// - JSON.stringify(encoded INTERNAL form) - to be loadable in the file. +// - loads to a decoded InternalNode equivalent, but with still-encoded children. +// - upon a request _for_ the children, decodes them. +// - they are requested as an array. +// - fully decodes leaf nodes, does one decode layer for internals (stopping at still-encoded [grand]children) diff --git a/common/models/templates/test/trie-compression.js b/common/models/templates/test/trie-compression.js new file mode 100644 index 00000000000..082c37b81aa --- /dev/null +++ b/common/models/templates/test/trie-compression.js @@ -0,0 +1,212 @@ +/* + * Unit tests for the Trie prediction model. + */ + +import { assert } from 'chai'; +import { + compressEntry, decompressEntry, + compressNode, decompressNode, + compressNumber, decompressNumber +} from '@keymanapp/models-templates/obj/tries/compression.js'; + +const TEST_DATA = {}; +TEST_DATA.ENTRIES = { + four: { + // total length: header = 5, text = 8 -> 13. (Made with weight-width 2) + // -totalLen- -weight- -keylen- + compressed: '\u0000\u000d\u0000\u0008\u0004fourfour', + decompressed: { + key: 'four', + content: 'four', + weight: 8 + }, + original: { + key: 'four', + content: 'four', + weight: 8 + } + } +}; + +TEST_DATA.LEAVES = { + four: { + // expected width difference: 5 (2: total size, 2: weight, 1: entry count) + // -totalLen- -weight- -type/size- + compressed: `\u0000\u0012\u0000\u0008\u8001${TEST_DATA.ENTRIES.four.compressed}`, + decompressed: { + type: 'leaf', + weight: 8, + entries: [TEST_DATA.ENTRIES.four.compressed] + }, + original: { + type: 'leaf', + weight: 8, + entries: [{ + key: 'four', + content: 'four', + weight: 8 + }] + } + } +} + +TEST_DATA.NODES = { + four: { + // expected width difference: 6 (2: total size, 2: weight, 1: entry count, 1: value count) + // -totalLen- -weight- -type/size- + compressed: `\u0000\u0018\u0000\u0008\u0001r${TEST_DATA.LEAVES.four.compressed}`, + decompressed: { + type: 'internal', + weight: 8, + values: ['r'], + children: {r: TEST_DATA.LEAVES.four.compressed} + }, + original: { + type: 'internal', + weight: 8, + values: ['r'], + children: {r: TEST_DATA.LEAVES.four.decompressed} + } + } +} + +describe('Trie compression', function() { + describe('`number`s', () => { + it('uses single-char compression by default', () => { + assert.equal(compressNumber(0x0020).length, 1); + }); + + it('width 1: compresses properly', () => { + assert.equal(compressNumber(0x0020, 1), ' '); + assert.equal(compressNumber('"'.charCodeAt(0), 1), '"'); + assert.equal(compressNumber(0xfffe, 1), '\ufffe'); + }); + + it('width 2: compresses properly', () => { + assert.equal(compressNumber(0x00200020, 2), ' '); + assert.equal( + compressNumber(0x0321fd20, 2), String.fromCharCode(0x0321, 0xfd20) + ); + }); + + it('width 2: compressing values one-char wide', () => { + assert.equal(compressNumber(0x0020, 2), '\u0000 '); + }); + + it('throws when numbers are too large for the specified width', () => { + assert.throws(() => compressNumber(0x00200020, 1)); + assert.throws(() => compressNumber(0x002000200020, 2)); + }) + }); + + describe('`Entry`s', () => { + it('compresses properly', () => { + const entry = { + key: 'four', + content: 'four', + weight: 8 + }; + + assert.equal(compressEntry(TEST_DATA.ENTRIES.four.original), TEST_DATA.ENTRIES.four.compressed); + }); + }); + + describe('Leaf nodes', () => { + it('compresses (mocked Entry)', () => { + // Should not attempt to recompress the mock-compressed entry. + assert.equal(compressNode(TEST_DATA.LEAVES.four.decompressed), TEST_DATA.LEAVES.four.compressed); + }); + + it('compresses (unmocked Entry)', () => { + assert.equal(compressNode(TEST_DATA.LEAVES.four.original), TEST_DATA.LEAVES.four.compressed); + }); + }); + + describe('Internal nodes', () => { + it('compresses (mocked Leaf)', () => { + // Should not attempt to recompress the mock-compressed leaf. + assert.equal(compressNode(TEST_DATA.NODES.four.decompressed), TEST_DATA.NODES.four.compressed); + }); + + it('compresses (unmocked Leaf)', () => { + assert.equal(compressNode(TEST_DATA.NODES.four.original), TEST_DATA.NODES.four.compressed); + }); + }); +}); + +describe('Trie decompression', function () { + describe('`number`s', () => { + describe('not inlined', () => { + it('decompresses single-char strings', () => { + assert.equal(decompressNumber(' ', 0), 0x0020); + assert.equal(decompressNumber('"', 0), '"'.charCodeAt(0)); + assert.equal(decompressNumber('\ufffe', 0), 0xfffe); + }); + + it('decompresses two-char strings', () => { + assert.equal(decompressNumber(' ', 0), 0x00200020); + assert.equal(decompressNumber(String.fromCharCode(0x0321, 0xfd20), 0), 0x0321fd20); + }); + + it('decompresses two-char strings of one-char value width', () => { + assert.equal(decompressNumber('\u0000 ', 0), 0x0020); + }); + }); + + describe('with mock-inlining', () => { + it('decompresses single-char strings', () => { + assert.equal(decompressNumber('xxx xx', 3, 4), 0x0020); + assert.equal(decompressNumber('xx"x', 2, 3), '"'.charCodeAt(0)); + assert.equal(decompressNumber('\uffff\ufffe', 1), 0xfffe); + }); + + it('decompresses two-char strings', () => { + assert.equal(decompressNumber('xxxx xx', 4, 6), 0x00200020); + }); + }); + }); + + describe('`Entry`s', () => { + it('not inlined', () => { + const mockedDecompression = TEST_DATA.ENTRIES.four.decompressed; + const compressionSrc = TEST_DATA.ENTRIES.four.compressed; + assert.deepEqual(decompressEntry(compressionSrc), mockedDecompression); + }); + + it('inlined', () => { + const mockedDecompression = TEST_DATA.ENTRIES.four.decompressed; + + // total length: header = 5, text = 8 -> 13. + const compressionSrc = `xxxxx${TEST_DATA.ENTRIES.four.compressed}xx`; + assert.deepEqual(decompressEntry(compressionSrc, /* start index */ 5), mockedDecompression); + }); + }); + + describe('Leaf nodes', () => { + describe('bootstrapping cases', () => { + it('not inlined', () => { + const encodedLeaf = TEST_DATA.LEAVES.four.compressed; + assert.deepEqual(decompressNode(encodedLeaf, 0), TEST_DATA.LEAVES.four.decompressed); + }); + + it('inlined', () => { + const encodedLeaf = TEST_DATA.LEAVES.four.compressed; + assert.deepEqual(decompressNode(`xxxxxxxxx${encodedLeaf}xx`, 9), TEST_DATA.LEAVES.four.decompressed); + }); + }); + }); + + describe('Internal nodes', () => { + describe('bootstrapping cases', () => { + it('not inlined', () => { + const encodedNode = TEST_DATA.NODES.four.compressed; + assert.deepEqual(decompressNode(encodedNode, 0), TEST_DATA.NODES.four.decompressed); + }); + + it('inlined', () => { + const encodedNode = TEST_DATA.NODES.four.compressed; + assert.deepEqual(decompressNode(`xxxxxxx${encodedNode}xx`, 7), TEST_DATA.NODES.four.decompressed); + }); + }); + }); +}); \ No newline at end of file From 84a36bc8bae43ca685a5e06249573fdd27124426 Mon Sep 17 00:00:00 2001 From: "Joshua A. Horton" Date: Sun, 24 Mar 2024 21:55:32 +0700 Subject: [PATCH 02/26] fix(common/models/templates): early test-fixture did not use sentinel code When a leaf node exists at the same Trie location as an internal node, it should be a child of that internal node using SENTINEL_CODE_UNIT (\ufdd0). The fixture was using null/undefined instead! --- common/models/templates/src/tries/compression.ts | 7 +++++++ .../models/templates/test/fixtures/tries/english-1000.json | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/common/models/templates/src/tries/compression.ts b/common/models/templates/src/tries/compression.ts index c7392891010..478177b4817 100644 --- a/common/models/templates/src/tries/compression.ts +++ b/common/models/templates/src/tries/compression.ts @@ -197,6 +197,13 @@ function compressInternal(node: InternalNode): string { const compressedChildren = values.map((value) => { const child = node.children[value]; + + // c8 ignore start + if(!child) { + throw new Error("unexpected empty reference for child"); + } + // c8 ignore end + // No need to recompress it if it's already compressed. return typeof child == 'string' ? child : compressNode(child); }); diff --git a/common/models/templates/test/fixtures/tries/english-1000.json b/common/models/templates/test/fixtures/tries/english-1000.json index 519a97aeb60..d98d289e0ec 100644 --- a/common/models/templates/test/fixtures/tries/english-1000.json +++ b/common/models/templates/test/fixtures/tries/english-1000.json @@ -1,4 +1,4 @@ { "totalWeight": 500500, - "root": {"type":"internal","weight":1000,"values":["t","o","a","i","w","h","f","b","n","y","s","m","u","c","d","l","e","j","p","g","v","k","r","q"],"children":{"t":{"type":"internal","weight":1000,"values":["h","o","i","w","a","u","e","r","y"],"children":{"h":{"type":"internal","weight":1000,"values":["e","a","i","r","o","u"],"children":{"e":{"type":"internal","weight":1000,"values":["\ufdd0","y","r","i","m","s","n","o"],"children":{"\ufdd0":{"type":"leaf","weight":1000,"entries":[{"key":"the","weight":1000,"content":"the"}]},"y":{"type":"leaf","weight":971,"entries":[{"key":"they","weight":971,"content":"they"}]},"r":{"type":"internal","weight":963,"values":["e"],"children":{"e":{"type":"internal","weight":963,"values":["\ufdd0","f"],"children":{"\ufdd0":{"type":"leaf","weight":963,"entries":[{"key":"there","weight":963,"content":"there"}]},"f":{"type":"leaf","weight":552,"entries":[{"key":"therefore","weight":552,"content":"therefore"}]}}}}},"i":{"type":"leaf","weight":961,"entries":[{"key":"their","weight":961,"content":"their"}]},"m":{"type":"internal","weight":941,"values":["\ufdd0","s"],"children":{"\ufdd0":{"type":"leaf","weight":941,"entries":[{"key":"them","weight":941,"content":"them"}]},"s":{"type":"leaf","weight":662,"entries":[{"key":"themselves","weight":662,"content":"themselves"}]}}},"s":{"type":"leaf","weight":933,"entries":[{"key":"these","weight":933,"content":"these"}]},"n":{"type":"leaf","weight":930,"entries":[{"key":"then","weight":930,"content":"then"}]},"o":{"type":"leaf","weight":229,"entries":[{"key":"theory","weight":229,"content":"theory"}]}}},"a":{"type":"internal","weight":994,"values":["t","n"],"children":{"t":{"type":"leaf","weight":994,"entries":[{"key":"that","weight":994,"content":"that"}]},"n":{"type":"leaf","weight":942,"entries":[{"key":"than","weight":942,"content":"than"}]}}},"i":{"type":"internal","weight":980,"values":["s","n","r"],"children":{"s":{"type":"leaf","weight":980,"entries":[{"key":"this","weight":980,"content":"this"}]},"n":{"type":"internal","weight":808,"values":["k","g"],"children":{"k":{"type":"internal","weight":808,"values":["\ufdd0","i"],"children":{"\ufdd0":{"type":"leaf","weight":808,"entries":[{"key":"think","weight":808,"content":"think"}]},"i":{"type":"leaf","weight":337,"entries":[{"key":"thinking","weight":337,"content":"thinking"}]}}},"g":{"type":"leaf","weight":754,"entries":[{"key":"things","weight":754,"content":"things"},{"key":"thing","weight":732,"content":"thing"}]}}},"r":{"type":"leaf","weight":504,"entries":[{"key":"third","weight":504,"content":"third"}]}}},"r":{"type":"internal","weight":908,"values":["o","e"],"children":{"o":{"type":"internal","weight":908,"values":["u"],"children":{"u":{"type":"internal","weight":908,"values":["g"],"children":{"g":{"type":"internal","weight":908,"values":["h"],"children":{"h":{"type":"internal","weight":908,"values":["\ufdd0","o"],"children":{"\ufdd0":{"type":"leaf","weight":908,"entries":[{"key":"through","weight":908,"content":"through"}]},"o":{"type":"leaf","weight":305,"entries":[{"key":"throughout","weight":305,"content":"throughout"}]}}}}}}}}},"e":{"type":"leaf","weight":852,"entries":[{"key":"three","weight":852,"content":"three"}]}}},"o":{"type":"internal","weight":895,"values":["s","u"],"children":{"s":{"type":"leaf","weight":895,"entries":[{"key":"those","weight":895,"content":"those"}]},"u":{"type":"internal","weight":835,"values":["g"],"children":{"g":{"type":"internal","weight":835,"values":["h"],"children":{"h":{"type":"leaf","weight":835,"entries":[{"key":"thought","weight":835,"content":"thought"},{"key":"though","weight":812,"content":"though"}]}}}}}}},"u":{"type":"leaf","weight":711,"entries":[{"key":"thus","weight":711,"content":"thus"}]}}},"o":{"type":"internal","weight":997,"values":["\ufdd0","o","l","w","d","g","t","p"],"children":{"\ufdd0":{"type":"leaf","weight":997,"entries":[{"key":"to","weight":997,"content":"to"}]},"o":{"type":"internal","weight":893,"values":["\ufdd0","k"],"children":{"\ufdd0":{"type":"leaf","weight":893,"entries":[{"key":"too","weight":893,"content":"too"}]},"k":{"type":"leaf","weight":804,"entries":[{"key":"took","weight":804,"content":"took"}]}}},"l":{"type":"leaf","weight":796,"entries":[{"key":"told","weight":796,"content":"told"}]},"w":{"type":"internal","weight":776,"values":["a","n"],"children":{"a":{"type":"leaf","weight":776,"entries":[{"key":"toward","weight":776,"content":"toward"}]},"n":{"type":"leaf","weight":567,"entries":[{"key":"town","weight":567,"content":"town"}]}}},"d":{"type":"leaf","weight":683,"entries":[{"key":"today","weight":683,"content":"today"}]},"g":{"type":"leaf","weight":658,"entries":[{"key":"together","weight":658,"content":"together"}]},"t":{"type":"leaf","weight":564,"entries":[{"key":"total","weight":564,"content":"total"}]},"p":{"type":"leaf","weight":550,"entries":[{"key":"top","weight":550,"content":"top"}]}}},"i":{"type":"internal","weight":934,"values":["m"],"children":{"m":{"type":"internal","weight":934,"values":["e"],"children":{"e":{"type":"internal","weight":934,"values":["\ufdd0","s"],"children":{"\ufdd0":{"type":"leaf","weight":934,"entries":[{"key":"time","weight":934,"content":"time"}]},"s":{"type":"leaf","weight":700,"entries":[{"key":"times","weight":700,"content":"times"}]}}}}}}},"w":{"type":"leaf","weight":932,"entries":[{"key":"two","weight":932,"content":"two"}]},"a":{"type":"internal","weight":851,"values":["k","x","b","l"],"children":{"k":{"type":"internal","weight":851,"values":["e","i"],"children":{"e":{"type":"internal","weight":851,"values":["\ufdd0","n"],"children":{"\ufdd0":{"type":"leaf","weight":851,"entries":[{"key":"take","weight":851,"content":"take"}]},"n":{"type":"leaf","weight":678,"entries":[{"key":"taken","weight":678,"content":"taken"}]}}},"i":{"type":"leaf","weight":464,"entries":[{"key":"taking","weight":464,"content":"taking"}]}}},"x":{"type":"leaf","weight":542,"entries":[{"key":"tax","weight":542,"content":"tax"}]},"b":{"type":"leaf","weight":529,"entries":[{"key":"table","weight":529,"content":"table"}]},"l":{"type":"leaf","weight":374,"entries":[{"key":"talk","weight":374,"content":"talk"}]}}},"u":{"type":"internal","weight":720,"values":["r"],"children":{"r":{"type":"internal","weight":720,"values":["n"],"children":{"n":{"type":"leaf","weight":720,"entries":[{"key":"turned","weight":720,"content":"turned"},{"key":"turn","weight":610,"content":"turn"}]}}}}},"e":{"type":"internal","weight":660,"values":["l","n","r","m","c","s"],"children":{"l":{"type":"leaf","weight":660,"entries":[{"key":"tell","weight":660,"content":"tell"}]},"n":{"type":"leaf","weight":415,"entries":[{"key":"ten","weight":415,"content":"ten"}]},"r":{"type":"leaf","weight":411,"entries":[{"key":"terms","weight":411,"content":"terms"}]},"m":{"type":"leaf","weight":270,"entries":[{"key":"temperature","weight":270,"content":"temperature"}]},"c":{"type":"leaf","weight":162,"entries":[{"key":"technical","weight":162,"content":"technical"}]},"s":{"type":"leaf","weight":157,"entries":[{"key":"test","weight":157,"content":"test"}]}}},"r":{"type":"internal","weight":607,"values":["u","i","y","a","o","e"],"children":{"u":{"type":"internal","weight":607,"values":["e","t"],"children":{"e":{"type":"leaf","weight":607,"entries":[{"key":"true","weight":607,"content":"true"}]},"t":{"type":"leaf","weight":203,"entries":[{"key":"truth","weight":203,"content":"truth"}]}}},"i":{"type":"internal","weight":431,"values":["e","a"],"children":{"e":{"type":"leaf","weight":431,"entries":[{"key":"tried","weight":431,"content":"tried"}]},"a":{"type":"leaf","weight":268,"entries":[{"key":"trial","weight":268,"content":"trial"}]}}},"y":{"type":"leaf","weight":409,"entries":[{"key":"trying","weight":409,"content":"trying"},{"key":"try","weight":295,"content":"try"}]},"a":{"type":"internal","weight":382,"values":["i","d"],"children":{"i":{"type":"leaf","weight":382,"entries":[{"key":"training","weight":382,"content":"training"}]},"d":{"type":"leaf","weight":315,"entries":[{"key":"trade","weight":315,"content":"trade"}]}}},"o":{"type":"leaf","weight":267,"entries":[{"key":"trouble","weight":267,"content":"trouble"}]},"e":{"type":"leaf","weight":216,"entries":[{"key":"treatment","weight":216,"content":"treatment"}]}}},"y":{"type":"internal","weight":540,"values":["p"],"children":{"p":{"type":"internal","weight":540,"values":["e"],"children":{"e":{"type":"internal","weight":540,"values":["\ufdd0","s"],"children":{"\ufdd0":{"type":"leaf","weight":540,"entries":[{"key":"type","weight":540,"content":"type"}]},"s":{"type":"leaf","weight":132,"entries":[{"key":"types","weight":132,"content":"types"}]}}}}}}}}},"o":{"type":"internal","weight":999,"values":["f","n","r","u","t","v","w","l","p","h","b"],"children":{"f":{"type":"internal","weight":999,"values":["\ufdd0","f","t"],"children":{"\ufdd0":{"type":"leaf","weight":999,"entries":[{"key":"of","weight":999,"content":"of"}]},"f":{"type":"internal","weight":860,"values":["\ufdd0","i"],"children":{"\ufdd0":{"type":"leaf","weight":860,"entries":[{"key":"off","weight":860,"content":"off"}]},"i":{"type":"leaf","weight":641,"entries":[{"key":"office","weight":641,"content":"office"}]}}},"t":{"type":"leaf","weight":756,"entries":[{"key":"often","weight":756,"content":"often"}]}}},"n":{"type":"internal","weight":985,"values":["\ufdd0","e","l","c"],"children":{"\ufdd0":{"type":"leaf","weight":985,"entries":[{"key":"on","weight":985,"content":"on"}]},"e":{"type":"internal","weight":969,"values":["\ufdd0","s"],"children":{"\ufdd0":{"type":"leaf","weight":969,"entries":[{"key":"one","weight":969,"content":"one"}]},"s":{"type":"leaf","weight":133,"entries":[{"key":"ones","weight":133,"content":"ones"}]}}},"l":{"type":"leaf","weight":939,"entries":[{"key":"only","weight":939,"content":"only"}]},"c":{"type":"leaf","weight":831,"entries":[{"key":"once","weight":831,"content":"once"}]}}},"r":{"type":"internal","weight":974,"values":["\ufdd0","d","g","i"],"children":{"\ufdd0":{"type":"leaf","weight":974,"entries":[{"key":"or","weight":974,"content":"or"}]},"d":{"type":"leaf","weight":765,"entries":[{"key":"order","weight":765,"content":"order"}]},"g":{"type":"leaf","weight":219,"entries":[{"key":"organization","weight":219,"content":"organization"}]},"i":{"type":"leaf","weight":4,"entries":[{"key":"original","weight":4,"content":"original"}]}}},"u":{"type":"internal","weight":950,"values":["t","r"],"children":{"t":{"type":"internal","weight":950,"values":["\ufdd0","s"],"children":{"\ufdd0":{"type":"leaf","weight":950,"entries":[{"key":"out","weight":950,"content":"out"}]},"s":{"type":"leaf","weight":562,"entries":[{"key":"outside","weight":562,"content":"outside"}]}}},"r":{"type":"leaf","weight":922,"entries":[{"key":"our","weight":922,"content":"our"}]}}},"t":{"type":"internal","weight":938,"values":["h"],"children":{"h":{"type":"internal","weight":938,"values":["e"],"children":{"e":{"type":"internal","weight":938,"values":["r"],"children":{"r":{"type":"internal","weight":938,"values":["\ufdd0","s"],"children":{"\ufdd0":{"type":"leaf","weight":938,"entries":[{"key":"other","weight":938,"content":"other"}]},"s":{"type":"leaf","weight":722,"entries":[{"key":"others","weight":722,"content":"others"}]}}}}}}}}},"v":{"type":"leaf","weight":921,"entries":[{"key":"over","weight":921,"content":"over"}]},"w":{"type":"leaf","weight":884,"entries":[{"key":"own","weight":884,"content":"own"}]},"l":{"type":"leaf","weight":862,"entries":[{"key":"old","weight":862,"content":"old"}]},"p":{"type":"internal","weight":718,"values":["e","p"],"children":{"e":{"type":"internal","weight":718,"values":["n","r"],"children":{"n":{"type":"internal","weight":718,"values":["\ufdd0","e"],"children":{"\ufdd0":{"type":"leaf","weight":718,"entries":[{"key":"open","weight":718,"content":"open"}]},"e":{"type":"leaf","weight":243,"entries":[{"key":"opened","weight":243,"content":"opened"}]}}},"r":{"type":"leaf","weight":93,"entries":[{"key":"operation","weight":93,"content":"operation"}]}}},"p":{"type":"leaf","weight":167,"entries":[{"key":"opportunity","weight":167,"content":"opportunity"}]}}},"h":{"type":"leaf","weight":176,"entries":[{"key":"oh","weight":176,"content":"oh"}]},"b":{"type":"internal","weight":119,"values":["t","v"],"children":{"t":{"type":"leaf","weight":119,"entries":[{"key":"obtained","weight":119,"content":"obtained"}]},"v":{"type":"leaf","weight":110,"entries":[{"key":"obviously","weight":110,"content":"obviously"}]}}}}},"a":{"type":"internal","weight":998,"values":["n","\ufdd0","s","t","r","l","b","f","g","m","w","c","i","v","d","p","j","u","h"],"children":{"n":{"type":"internal","weight":998,"values":["d","\ufdd0","y","o","s","a"],"children":{"d":{"type":"leaf","weight":998,"entries":[{"key":"and","weight":998,"content":"and"}]},"\ufdd0":{"type":"leaf","weight":972,"entries":[{"key":"an","weight":972,"content":"an"}]},"y":{"type":"internal","weight":927,"values":["\ufdd0","t","o"],"children":{"\ufdd0":{"type":"leaf","weight":927,"entries":[{"key":"any","weight":927,"content":"any"}]},"t":{"type":"leaf","weight":676,"entries":[{"key":"anything","weight":676,"content":"anything"}]},"o":{"type":"leaf","weight":296,"entries":[{"key":"anyone","weight":296,"content":"anyone"}]}}},"o":{"type":"leaf","weight":869,"entries":[{"key":"another","weight":869,"content":"another"}]},"s":{"type":"leaf","weight":366,"entries":[{"key":"answer","weight":366,"content":"answer"}]},"a":{"type":"leaf","weight":65,"entries":[{"key":"analysis","weight":65,"content":"analysis"}]}}},"\ufdd0":{"type":"leaf","weight":996,"entries":[{"key":"a","weight":996,"content":"a"}]},"s":{"type":"internal","weight":987,"values":["\ufdd0","k","s"],"children":{"\ufdd0":{"type":"leaf","weight":987,"entries":[{"key":"as","weight":987,"content":"as"}]},"k":{"type":"leaf","weight":786,"entries":[{"key":"asked","weight":786,"content":"asked"},{"key":"ask","weight":221,"content":"ask"}]},"s":{"type":"leaf","weight":256,"entries":[{"key":"association","weight":256,"content":"association"}]}}},"t":{"type":"internal","weight":983,"values":["\ufdd0","t"],"children":{"\ufdd0":{"type":"leaf","weight":983,"entries":[{"key":"at","weight":983,"content":"at"}]},"t":{"type":"internal","weight":473,"values":["e","i","a"],"children":{"e":{"type":"leaf","weight":473,"entries":[{"key":"attention","weight":473,"content":"attention"}]},"i":{"type":"leaf","weight":48,"entries":[{"key":"attitude","weight":48,"content":"attitude"}]},"a":{"type":"leaf","weight":28,"entries":[{"key":"attack","weight":28,"content":"attack"}]}}}}},"r":{"type":"internal","weight":977,"values":["e","o","t","m"],"children":{"e":{"type":"internal","weight":977,"values":["\ufdd0","a"],"children":{"\ufdd0":{"type":"leaf","weight":977,"entries":[{"key":"are","weight":977,"content":"are"}]},"a":{"type":"internal","weight":724,"values":["\ufdd0","s"],"children":{"\ufdd0":{"type":"leaf","weight":724,"entries":[{"key":"area","weight":724,"content":"area"}]},"s":{"type":"leaf","weight":613,"entries":[{"key":"areas","weight":613,"content":"areas"}]}}}}},"o":{"type":"leaf","weight":840,"entries":[{"key":"around","weight":840,"content":"around"}]},"t":{"type":"leaf","weight":559,"entries":[{"key":"art","weight":559,"content":"art"}]},"m":{"type":"internal","weight":250,"values":["y","s"],"children":{"y":{"type":"leaf","weight":250,"entries":[{"key":"army","weight":250,"content":"army"}]},"s":{"type":"leaf","weight":169,"entries":[{"key":"arms","weight":169,"content":"arms"}]}}}}},"l":{"type":"internal","weight":965,"values":["l","s","w","m","o","t","r"],"children":{"l":{"type":"leaf","weight":965,"entries":[{"key":"all","weight":965,"content":"all"}]},"s":{"type":"leaf","weight":914,"entries":[{"key":"also","weight":914,"content":"also"}]},"w":{"type":"leaf","weight":817,"entries":[{"key":"always","weight":817,"content":"always"}]},"m":{"type":"leaf","weight":807,"entries":[{"key":"almost","weight":807,"content":"almost"}]},"o":{"type":"internal","weight":741,"values":["n"],"children":{"n":{"type":"internal","weight":741,"values":["g","e"],"children":{"g":{"type":"leaf","weight":741,"entries":[{"key":"along","weight":741,"content":"along"}]},"e":{"type":"leaf","weight":519,"entries":[{"key":"alone","weight":519,"content":"alone"}]}}}}},"t":{"type":"leaf","weight":721,"entries":[{"key":"although","weight":721,"content":"although"}]},"r":{"type":"leaf","weight":663,"entries":[{"key":"already","weight":663,"content":"already"}]}}},"b":{"type":"internal","weight":944,"values":["o","l"],"children":{"o":{"type":"internal","weight":944,"values":["u","v"],"children":{"u":{"type":"leaf","weight":944,"entries":[{"key":"about","weight":944,"content":"about"}]},"v":{"type":"leaf","weight":696,"entries":[{"key":"above","weight":696,"content":"above"}]}}},"l":{"type":"leaf","weight":578,"entries":[{"key":"able","weight":578,"content":"able"}]}}},"f":{"type":"internal","weight":915,"values":["t","\ufdd0"],"children":{"t":{"type":"internal","weight":915,"values":["e"],"children":{"e":{"type":"internal","weight":915,"values":["r"],"children":{"r":{"type":"internal","weight":915,"values":["\ufdd0","n"],"children":{"\ufdd0":{"type":"leaf","weight":915,"entries":[{"key":"after","weight":915,"content":"after"}]},"n":{"type":"leaf","weight":33,"entries":[{"key":"afternoon","weight":33,"content":"afternoon"}]}}}}}}},"\ufdd0":{"type":"leaf","weight":909,"entries":[{"key":"af","weight":909,"content":"af"}]}}},"g":{"type":"internal","weight":857,"values":["a","o","e","r"],"children":{"a":{"type":"internal","weight":857,"values":["i"],"children":{"i":{"type":"internal","weight":857,"values":["n"],"children":{"n":{"type":"leaf","weight":857,"entries":[{"key":"against","weight":857,"content":"against"},{"key":"again","weight":843,"content":"again"}]}}}}},"o":{"type":"leaf","weight":630,"entries":[{"key":"ago","weight":630,"content":"ago"}]},"e":{"type":"leaf","weight":600,"entries":[{"key":"age","weight":600,"content":"age"}]},"r":{"type":"leaf","weight":36,"entries":[{"key":"agreement","weight":36,"content":"agreement"}]}}},"m":{"type":"internal","weight":841,"values":["e","o",null],"children":{"e":{"type":"internal","weight":841,"values":["r"],"children":{"r":{"type":"internal","weight":841,"values":["i"],"children":{"i":{"type":"internal","weight":841,"values":["c"],"children":{"c":{"type":"internal","weight":841,"values":["a"],"children":{"a":{"type":"leaf","weight":841,"entries":[{"key":"american","weight":841,"content":"american"},{"key":"america","weight":512,"content":"america"}]}}}}}}}}},"o":{"type":"internal","weight":758,"values":["n","u"],"children":{"n":{"type":"leaf","weight":758,"entries":[{"key":"among","weight":758,"content":"among"}]},"u":{"type":"leaf","weight":442,"entries":[{"key":"amount","weight":442,"content":"amount"}]}}},"undefined":{"type":"leaf","weight":614,"entries":[{"key":"am","weight":614,"content":"am"}]}}},"w":{"type":"leaf","weight":816,"entries":[{"key":"away","weight":816,"content":"away"}]},"c":{"type":"internal","weight":693,"values":["t","r","c"],"children":{"t":{"type":"internal","weight":693,"values":["i","\ufdd0","u"],"children":{"i":{"type":"internal","weight":693,"values":["o","v"],"children":{"o":{"type":"leaf","weight":693,"entries":[{"key":"action","weight":693,"content":"action"}]},"v":{"type":"internal","weight":131,"values":["i"],"children":{"i":{"type":"internal","weight":131,"values":["t"],"children":{"t":{"type":"internal","weight":131,"values":["y","i"],"children":{"y":{"type":"leaf","weight":131,"entries":[{"key":"activity","weight":131,"content":"activity"}]},"i":{"type":"leaf","weight":121,"entries":[{"key":"activities","weight":121,"content":"activities"}]}}}}}}}}},"\ufdd0":{"type":"leaf","weight":682,"entries":[{"key":"act","weight":682,"content":"act"}]},"u":{"type":"leaf","weight":423,"entries":[{"key":"actually","weight":423,"content":"actually"}]}}},"r":{"type":"leaf","weight":680,"entries":[{"key":"across","weight":680,"content":"across"}]},"c":{"type":"internal","weight":298,"values":["o"],"children":{"o":{"type":"internal","weight":298,"values":["r","u"],"children":{"r":{"type":"leaf","weight":298,"entries":[{"key":"according","weight":298,"content":"according"}]},"u":{"type":"leaf","weight":135,"entries":[{"key":"account","weight":135,"content":"account"}]}}}}}}},"i":{"type":"internal","weight":643,"values":["r","d"],"children":{"r":{"type":"leaf","weight":643,"entries":[{"key":"air","weight":643,"content":"air"}]},"d":{"type":"leaf","weight":265,"entries":[{"key":"aid","weight":265,"content":"aid"}]}}},"v":{"type":"internal","weight":627,"values":["a","e"],"children":{"a":{"type":"leaf","weight":627,"entries":[{"key":"available","weight":627,"content":"available"}]},"e":{"type":"leaf","weight":241,"entries":[{"key":"average","weight":241,"content":"average"}]}}},"d":{"type":"internal","weight":446,"values":["d","m"],"children":{"d":{"type":"internal","weight":446,"values":["e","i"],"children":{"e":{"type":"leaf","weight":446,"entries":[{"key":"added","weight":446,"content":"added"}]},"i":{"type":"internal","weight":308,"values":["t"],"children":{"t":{"type":"internal","weight":308,"values":["i"],"children":{"i":{"type":"internal","weight":308,"values":["o"],"children":{"o":{"type":"internal","weight":308,"values":["n"],"children":{"n":{"type":"internal","weight":308,"values":["\ufdd0","a"],"children":{"\ufdd0":{"type":"leaf","weight":308,"entries":[{"key":"addition","weight":308,"content":"addition"}]},"a":{"type":"leaf","weight":164,"entries":[{"key":"additional","weight":164,"content":"additional"}]}}}}}}}}}}}}},"m":{"type":"leaf","weight":402,"entries":[{"key":"administration","weight":402,"content":"administration"}]}}},"p":{"type":"internal","weight":275,"values":["p"],"children":{"p":{"type":"internal","weight":275,"values":["e","a","r","l"],"children":{"e":{"type":"internal","weight":275,"values":["a"],"children":{"a":{"type":"internal","weight":275,"values":["r"],"children":{"r":{"type":"leaf","weight":275,"entries":[{"key":"appeared","weight":275,"content":"appeared"},{"key":"appear","weight":137,"content":"appear"}]}}}}},"a":{"type":"leaf","weight":195,"entries":[{"key":"apparently","weight":195,"content":"apparently"}]},"r":{"type":"leaf","weight":185,"entries":[{"key":"approach","weight":185,"content":"approach"}]},"l":{"type":"leaf","weight":39,"entries":[{"key":"applied","weight":39,"content":"applied"}]}}}}},"j":{"type":"leaf","weight":142,"entries":[{"key":"aj","weight":142,"content":"aj"}]},"u":{"type":"leaf","weight":118,"entries":[{"key":"audience","weight":118,"content":"audience"}]},"h":{"type":"leaf","weight":73,"entries":[{"key":"ahead","weight":73,"content":"ahead"}]}}},"i":{"type":"internal","weight":995,"values":["n","s","t","f","m","d",null],"children":{"n":{"type":"internal","weight":995,"values":["\ufdd0","t","f","d","c","s","v"],"children":{"\ufdd0":{"type":"leaf","weight":995,"entries":[{"key":"in","weight":995,"content":"in"}]},"t":{"type":"internal","weight":943,"values":["o","e"],"children":{"o":{"type":"leaf","weight":943,"entries":[{"key":"into","weight":943,"content":"into"}]},"e":{"type":"internal","weight":728,"values":["r"],"children":{"r":{"type":"internal","weight":728,"values":["e","n"],"children":{"e":{"type":"internal","weight":728,"values":["s"],"children":{"s":{"type":"internal","weight":728,"values":["t"],"children":{"t":{"type":"internal","weight":728,"values":["\ufdd0","e"],"children":{"\ufdd0":{"type":"leaf","weight":728,"entries":[{"key":"interest","weight":728,"content":"interest"}]},"e":{"type":"leaf","weight":24,"entries":[{"key":"interested","weight":24,"content":"interested"}]}}}}}}},"n":{"type":"leaf","weight":380,"entries":[{"key":"international","weight":380,"content":"international"}]}}}}}}},"f":{"type":"internal","weight":661,"values":["o","l"],"children":{"o":{"type":"leaf","weight":661,"entries":[{"key":"information","weight":661,"content":"information"}]},"l":{"type":"leaf","weight":254,"entries":[{"key":"influence","weight":254,"content":"influence"}]}}},"d":{"type":"internal","weight":617,"values":["i","u","e"],"children":{"i":{"type":"internal","weight":617,"values":["v","c"],"children":{"v":{"type":"leaf","weight":617,"entries":[{"key":"individual","weight":617,"content":"individual"}]},"c":{"type":"leaf","weight":59,"entries":[{"key":"indicated","weight":59,"content":"indicated"}]}}},"u":{"type":"internal","weight":432,"values":["s"],"children":{"s":{"type":"internal","weight":432,"values":["t"],"children":{"t":{"type":"internal","weight":432,"values":["r"],"children":{"r":{"type":"internal","weight":432,"values":["y","i"],"children":{"y":{"type":"leaf","weight":432,"entries":[{"key":"industry","weight":432,"content":"industry"}]},"i":{"type":"leaf","weight":323,"entries":[{"key":"industrial","weight":323,"content":"industrial"}]}}}}}}}}},"e":{"type":"leaf","weight":408,"entries":[{"key":"indeed","weight":408,"content":"indeed"}]}}},"c":{"type":"internal","weight":514,"values":["r","l","o"],"children":{"r":{"type":"internal","weight":514,"values":["e"],"children":{"e":{"type":"internal","weight":514,"values":["a"],"children":{"a":{"type":"internal","weight":514,"values":["s"],"children":{"s":{"type":"internal","weight":514,"values":["e"],"children":{"e":{"type":"internal","weight":514,"values":["\ufdd0","d"],"children":{"\ufdd0":{"type":"leaf","weight":514,"entries":[{"key":"increase","weight":514,"content":"increase"}]},"d":{"type":"leaf","weight":339,"entries":[{"key":"increased","weight":339,"content":"increased"}]}}}}}}}}}}},"l":{"type":"internal","weight":438,"values":["u"],"children":{"u":{"type":"internal","weight":438,"values":["d"],"children":{"d":{"type":"internal","weight":438,"values":["i","e"],"children":{"i":{"type":"leaf","weight":438,"entries":[{"key":"including","weight":438,"content":"including"}]},"e":{"type":"leaf","weight":102,"entries":[{"key":"include","weight":102,"content":"include"}]}}}}}}},"o":{"type":"leaf","weight":71,"entries":[{"key":"income","weight":71,"content":"income"}]}}},"s":{"type":"internal","weight":459,"values":["i","t"],"children":{"i":{"type":"leaf","weight":459,"entries":[{"key":"inside","weight":459,"content":"inside"}]},"t":{"type":"leaf","weight":452,"entries":[{"key":"instead","weight":452,"content":"instead"}]}}},"v":{"type":"leaf","weight":344,"entries":[{"key":"involved","weight":344,"content":"involved"}]}}},"s":{"type":"internal","weight":993,"values":["\ufdd0","l","s"],"children":{"\ufdd0":{"type":"leaf","weight":993,"entries":[{"key":"is","weight":993,"content":"is"}]},"l":{"type":"leaf","weight":424,"entries":[{"key":"island","weight":424,"content":"island"}]},"s":{"type":"leaf","weight":368,"entries":[{"key":"issue","weight":368,"content":"issue"}]}}},"t":{"type":"internal","weight":989,"values":["\ufdd0","s"],"children":{"\ufdd0":{"type":"leaf","weight":989,"entries":[{"key":"it","weight":989,"content":"it"}]},"s":{"type":"internal","weight":945,"values":["\ufdd0","e"],"children":{"\ufdd0":{"type":"leaf","weight":945,"entries":[{"key":"its","weight":945,"content":"its"}]},"e":{"type":"leaf","weight":702,"entries":[{"key":"itself","weight":702,"content":"itself"}]}}}}},"undefined":{"type":"leaf","weight":981,"entries":[{"key":"i","weight":981,"content":"i"}]},"f":{"type":"leaf","weight":952,"entries":[{"key":"if","weight":952,"content":"if"}]},"m":{"type":"internal","weight":755,"values":["p","m","a"],"children":{"p":{"type":"internal","weight":755,"values":["o"],"children":{"o":{"type":"internal","weight":755,"values":["r"],"children":{"r":{"type":"internal","weight":755,"values":["t"],"children":{"t":{"type":"internal","weight":755,"values":["a"],"children":{"a":{"type":"internal","weight":755,"values":["n"],"children":{"n":{"type":"internal","weight":755,"values":["t","c"],"children":{"t":{"type":"leaf","weight":755,"entries":[{"key":"important","weight":755,"content":"important"}]},"c":{"type":"leaf","weight":67,"entries":[{"key":"importance","weight":67,"content":"importance"}]}}}}}}}}}}}}},"m":{"type":"leaf","weight":184,"entries":[{"key":"immediately","weight":184,"content":"immediately"}]},"a":{"type":"leaf","weight":152,"entries":[{"key":"image","weight":152,"content":"image"}]}}},"d":{"type":"internal","weight":520,"values":["e"],"children":{"e":{"type":"internal","weight":520,"values":["a"],"children":{"a":{"type":"internal","weight":520,"values":["\ufdd0","s"],"children":{"\ufdd0":{"type":"leaf","weight":520,"entries":[{"key":"idea","weight":520,"content":"idea"}]},"s":{"type":"leaf","weight":319,"entries":[{"key":"ideas","weight":319,"content":"ideas"}]}}}}}}}}},"w":{"type":"internal","weight":992,"values":["a","i","h","e","o","r"],"children":{"a":{"type":"internal","weight":992,"values":["s","y","r","t","n","l","i"],"children":{"s":{"type":"internal","weight":992,"values":["\ufdd0","h"],"children":{"\ufdd0":{"type":"leaf","weight":992,"entries":[{"key":"was","weight":992,"content":"was"}]},"h":{"type":"leaf","weight":554,"entries":[{"key":"washington","weight":554,"content":"washington"}]}}},"y":{"type":"internal","weight":902,"values":["\ufdd0","s"],"children":{"\ufdd0":{"type":"leaf","weight":902,"entries":[{"key":"way","weight":902,"content":"way"}]},"s":{"type":"leaf","weight":217,"entries":[{"key":"ways","weight":217,"content":"ways"}]}}},"r":{"type":"leaf","weight":819,"entries":[{"key":"war","weight":819,"content":"war"}]},"t":{"type":"leaf","weight":813,"entries":[{"key":"water","weight":813,"content":"water"}]},"n":{"type":"internal","weight":727,"values":["t"],"children":{"t":{"type":"internal","weight":727,"values":["\ufdd0","e"],"children":{"\ufdd0":{"type":"leaf","weight":727,"entries":[{"key":"want","weight":727,"content":"want"}]},"e":{"type":"leaf","weight":598,"entries":[{"key":"wanted","weight":598,"content":"wanted"}]}}}}},"l":{"type":"internal","weight":395,"values":["l","k"],"children":{"l":{"type":"leaf","weight":395,"entries":[{"key":"wall","weight":395,"content":"wall"}]},"k":{"type":"leaf","weight":394,"entries":[{"key":"walked","weight":394,"content":"walked"}]}}},"i":{"type":"leaf","weight":81,"entries":[{"key":"waiting","weight":81,"content":"waiting"}]}}},"i":{"type":"internal","weight":988,"values":["t","l","f","d","n","s"],"children":{"t":{"type":"internal","weight":988,"values":["h"],"children":{"h":{"type":"internal","weight":988,"values":["\ufdd0","o","i"],"children":{"\ufdd0":{"type":"leaf","weight":988,"entries":[{"key":"with","weight":988,"content":"with"}]},"o":{"type":"leaf","weight":844,"entries":[{"key":"without","weight":844,"content":"without"}]},"i":{"type":"leaf","weight":744,"entries":[{"key":"within","weight":744,"content":"within"}]}}}}},"l":{"type":"internal","weight":954,"values":["l"],"children":{"l":{"type":"internal","weight":954,"values":["\ufdd0","i"],"children":{"\ufdd0":{"type":"leaf","weight":954,"entries":[{"key":"will","weight":954,"content":"will"}]},"i":{"type":"leaf","weight":347,"entries":[{"key":"william","weight":347,"content":"william"}]}}}}},"f":{"type":"leaf","weight":601,"entries":[{"key":"wife","weight":601,"content":"wife"}]},"d":{"type":"leaf","weight":192,"entries":[{"key":"wide","weight":192,"content":"wide"}]},"n":{"type":"leaf","weight":149,"entries":[{"key":"window","weight":149,"content":"window"}]},"s":{"type":"leaf","weight":77,"entries":[{"key":"wish","weight":77,"content":"wish"}]}}},"h":{"type":"internal","weight":970,"values":["i","e","o","a","y"],"children":{"i":{"type":"internal","weight":970,"values":["c","l","t"],"children":{"c":{"type":"leaf","weight":970,"entries":[{"key":"which","weight":970,"content":"which"}]},"l":{"type":"leaf","weight":867,"entries":[{"key":"while","weight":867,"content":"while"}]},"t":{"type":"leaf","weight":751,"entries":[{"key":"white","weight":751,"content":"white"}]}}},"e":{"type":"internal","weight":956,"values":["n","r","t"],"children":{"n":{"type":"leaf","weight":956,"entries":[{"key":"when","weight":956,"content":"when"}]},"r":{"type":"leaf","weight":904,"entries":[{"key":"where","weight":904,"content":"where"}]},"t":{"type":"leaf","weight":688,"entries":[{"key":"whether","weight":688,"content":"whether"}]}}},"o":{"type":"internal","weight":955,"values":["\ufdd0","l","s","m"],"children":{"\ufdd0":{"type":"leaf","weight":955,"entries":[{"key":"who","weight":955,"content":"who"}]},"l":{"type":"leaf","weight":705,"entries":[{"key":"whole","weight":705,"content":"whole"}]},"s":{"type":"leaf","weight":638,"entries":[{"key":"whose","weight":638,"content":"whose"}]},"m":{"type":"leaf","weight":341,"entries":[{"key":"whom","weight":341,"content":"whom"}]}}},"a":{"type":"internal","weight":947,"values":["t"],"children":{"t":{"type":"internal","weight":947,"values":["\ufdd0","e"],"children":{"\ufdd0":{"type":"leaf","weight":947,"entries":[{"key":"what","weight":947,"content":"what"}]},"e":{"type":"leaf","weight":91,"entries":[{"key":"whatever","weight":91,"content":"whatever"}]}}}}},"y":{"type":"leaf","weight":792,"entries":[{"key":"why","weight":792,"content":"why"}]}}},"e":{"type":"internal","weight":967,"values":["r","\ufdd0","l","n","e","s"],"children":{"r":{"type":"leaf","weight":967,"entries":[{"key":"were","weight":967,"content":"were"}]},"\ufdd0":{"type":"leaf","weight":960,"entries":[{"key":"we","weight":960,"content":"we"}]},"l":{"type":"leaf","weight":901,"entries":[{"key":"well","weight":901,"content":"well"}]},"n":{"type":"leaf","weight":834,"entries":[{"key":"went","weight":834,"content":"went"}]},"e":{"type":"internal","weight":668,"values":["k"],"children":{"k":{"type":"internal","weight":668,"values":["\ufdd0","s"],"children":{"\ufdd0":{"type":"leaf","weight":668,"entries":[{"key":"week","weight":668,"content":"week"}]},"s":{"type":"leaf","weight":299,"entries":[{"key":"weeks","weight":299,"content":"weeks"}]}}}}},"s":{"type":"internal","weight":612,"values":["t"],"children":{"t":{"type":"internal","weight":612,"values":["\ufdd0","e"],"children":{"\ufdd0":{"type":"leaf","weight":612,"entries":[{"key":"west","weight":612,"content":"west"}]},"e":{"type":"leaf","weight":282,"entries":[{"key":"western","weight":282,"content":"western"}]}}}}}}},"o":{"type":"internal","weight":962,"values":["u","r","m"],"children":{"u":{"type":"leaf","weight":962,"entries":[{"key":"would","weight":962,"content":"would"}]},"r":{"type":"internal","weight":886,"values":["l","k","d"],"children":{"l":{"type":"leaf","weight":886,"entries":[{"key":"world","weight":886,"content":"world"}]},"k":{"type":"internal","weight":881,"values":["\ufdd0","i","s","e"],"children":{"\ufdd0":{"type":"leaf","weight":881,"entries":[{"key":"work","weight":881,"content":"work"}]},"i":{"type":"leaf","weight":363,"entries":[{"key":"working","weight":363,"content":"working"}]},"s":{"type":"leaf","weight":237,"entries":[{"key":"works","weight":237,"content":"works"}]},"e":{"type":"leaf","weight":222,"entries":[{"key":"worked","weight":222,"content":"worked"}]}}},"d":{"type":"leaf","weight":665,"entries":[{"key":"words","weight":665,"content":"words"},{"key":"word","weight":664,"content":"word"}]}}},"m":{"type":"internal","weight":594,"values":["a","e"],"children":{"a":{"type":"leaf","weight":594,"entries":[{"key":"woman","weight":594,"content":"woman"}]},"e":{"type":"leaf","weight":518,"entries":[{"key":"women","weight":518,"content":"women"}]}}}}},"r":{"type":"internal","weight":481,"values":["o","i"],"children":{"o":{"type":"internal","weight":481,"values":["t","n"],"children":{"t":{"type":"leaf","weight":481,"entries":[{"key":"wrote","weight":481,"content":"wrote"}]},"n":{"type":"leaf","weight":227,"entries":[{"key":"wrong","weight":227,"content":"wrong"}]}}},"i":{"type":"internal","weight":373,"values":["t"],"children":{"t":{"type":"internal","weight":373,"values":["t","i","e"],"children":{"t":{"type":"leaf","weight":373,"entries":[{"key":"written","weight":373,"content":"written"}]},"i":{"type":"leaf","weight":139,"entries":[{"key":"writing","weight":139,"content":"writing"}]},"e":{"type":"leaf","weight":34,"entries":[{"key":"write","weight":34,"content":"write"}]}}}}}}}}},"h":{"type":"internal","weight":991,"values":["e","i","a","o","u"],"children":{"e":{"type":"internal","weight":991,"values":["\ufdd0","r","a","l"],"children":{"\ufdd0":{"type":"leaf","weight":991,"entries":[{"key":"he","weight":991,"content":"he"}]},"r":{"type":"internal","weight":966,"values":["\ufdd0","e","s"],"children":{"\ufdd0":{"type":"leaf","weight":966,"entries":[{"key":"her","weight":966,"content":"her"}]},"e":{"type":"leaf","weight":879,"entries":[{"key":"here","weight":879,"content":"here"}]},"s":{"type":"leaf","weight":196,"entries":[{"key":"herself","weight":196,"content":"herself"}]}}},"a":{"type":"internal","weight":802,"values":["d","r","v","l"],"children":{"d":{"type":"leaf","weight":802,"entries":[{"key":"head","weight":802,"content":"head"}]},"r":{"type":"internal","weight":634,"values":["d","t",null],"children":{"d":{"type":"leaf","weight":634,"entries":[{"key":"heard","weight":634,"content":"heard"}]},"t":{"type":"leaf","weight":453,"entries":[{"key":"heart","weight":453,"content":"heart"}]},"undefined":{"type":"leaf","weight":369,"entries":[{"key":"hear","weight":369,"content":"hear"}]}}},"v":{"type":"leaf","weight":84,"entries":[{"key":"heavy","weight":84,"content":"heavy"}]},"l":{"type":"leaf","weight":30,"entries":[{"key":"health","weight":30,"content":"health"}]}}},"l":{"type":"internal","weight":707,"values":["p","d"],"children":{"p":{"type":"leaf","weight":707,"entries":[{"key":"help","weight":707,"content":"help"}]},"d":{"type":"leaf","weight":653,"entries":[{"key":"held","weight":653,"content":"held"}]}}}}},"i":{"type":"internal","weight":986,"values":["s","m","g","t"],"children":{"s":{"type":"internal","weight":986,"values":["\ufdd0","t"],"children":{"\ufdd0":{"type":"leaf","weight":986,"entries":[{"key":"his","weight":986,"content":"his"}]},"t":{"type":"leaf","weight":687,"entries":[{"key":"history","weight":687,"content":"history"}]}}},"m":{"type":"internal","weight":959,"values":["\ufdd0","s"],"children":{"\ufdd0":{"type":"leaf","weight":959,"entries":[{"key":"him","weight":959,"content":"him"}]},"s":{"type":"leaf","weight":850,"entries":[{"key":"himself","weight":850,"content":"himself"}]}}},"g":{"type":"internal","weight":829,"values":["h"],"children":{"h":{"type":"internal","weight":829,"values":["\ufdd0","e"],"children":{"\ufdd0":{"type":"leaf","weight":829,"entries":[{"key":"high","weight":829,"content":"high"}]},"e":{"type":"leaf","weight":397,"entries":[{"key":"higher","weight":397,"content":"higher"}]}}}}},"t":{"type":"leaf","weight":114,"entries":[{"key":"hit","weight":114,"content":"hit"}]}}},"a":{"type":"internal","weight":979,"values":["d","v","s","n","l","r","p","i"],"children":{"d":{"type":"leaf","weight":979,"entries":[{"key":"had","weight":979,"content":"had"}]},"v":{"type":"internal","weight":973,"values":["e","i"],"children":{"e":{"type":"leaf","weight":973,"entries":[{"key":"have","weight":973,"content":"have"}]},"i":{"type":"leaf","weight":675,"entries":[{"key":"having","weight":675,"content":"having"}]}}},"s":{"type":"leaf","weight":957,"entries":[{"key":"has","weight":957,"content":"has"}]},"n":{"type":"internal","weight":806,"values":["d"],"children":{"d":{"type":"internal","weight":806,"values":["\ufdd0","s"],"children":{"\ufdd0":{"type":"leaf","weight":806,"entries":[{"key":"hand","weight":806,"content":"hand"}]},"s":{"type":"leaf","weight":691,"entries":[{"key":"hands","weight":691,"content":"hands"}]}}}}},"l":{"type":"internal","weight":669,"values":["f","l"],"children":{"f":{"type":"leaf","weight":669,"entries":[{"key":"half","weight":669,"content":"half"}]},"l":{"type":"leaf","weight":367,"entries":[{"key":"hall","weight":367,"content":"hall"}]}}},"r":{"type":"internal","weight":545,"values":["d"],"children":{"d":{"type":"internal","weight":545,"values":["\ufdd0","l"],"children":{"\ufdd0":{"type":"leaf","weight":545,"entries":[{"key":"hard","weight":545,"content":"hard"}]},"l":{"type":"leaf","weight":40,"entries":[{"key":"hardly","weight":40,"content":"hardly"}]}}}}},"p":{"type":"leaf","weight":353,"entries":[{"key":"happened","weight":353,"content":"happened"}]},"i":{"type":"leaf","weight":348,"entries":[{"key":"hair","weight":348,"content":"hair"}]}}},"o":{"type":"internal","weight":892,"values":["w","u","m","p","l","t","r","s"],"children":{"w":{"type":"internal","weight":892,"values":["\ufdd0","e"],"children":{"\ufdd0":{"type":"leaf","weight":892,"entries":[{"key":"how","weight":892,"content":"how"}]},"e":{"type":"leaf","weight":839,"entries":[{"key":"however","weight":839,"content":"however"}]}}},"u":{"type":"internal","weight":846,"values":["s","r"],"children":{"s":{"type":"leaf","weight":846,"entries":[{"key":"house","weight":846,"content":"house"}]},"r":{"type":"leaf","weight":454,"entries":[{"key":"hours","weight":454,"content":"hours"},{"key":"hour","weight":331,"content":"hour"}]}}},"m":{"type":"leaf","weight":838,"entries":[{"key":"home","weight":838,"content":"home"}]},"p":{"type":"leaf","weight":471,"entries":[{"key":"hope","weight":471,"content":"hope"}]},"l":{"type":"leaf","weight":428,"entries":[{"key":"hold","weight":428,"content":"hold"}]},"t":{"type":"internal","weight":238,"values":["\ufdd0","e"],"children":{"\ufdd0":{"type":"leaf","weight":238,"entries":[{"key":"hot","weight":238,"content":"hot"}]},"e":{"type":"leaf","weight":201,"entries":[{"key":"hotel","weight":201,"content":"hotel"}]}}},"r":{"type":"leaf","weight":138,"entries":[{"key":"horse","weight":138,"content":"horse"}]},"s":{"type":"leaf","weight":79,"entries":[{"key":"hospital","weight":79,"content":"hospital"}]}}},"u":{"type":"internal","weight":699,"values":["m","n","s"],"children":{"m":{"type":"leaf","weight":699,"entries":[{"key":"human","weight":699,"content":"human"}]},"n":{"type":"leaf","weight":434,"entries":[{"key":"hundred","weight":434,"content":"hundred"}]},"s":{"type":"leaf","weight":247,"entries":[{"key":"husband","weight":247,"content":"husband"}]}}}}},"f":{"type":"internal","weight":990,"values":["o","r","i","e","a","u","l"],"children":{"o":{"type":"internal","weight":990,"values":["r","u","l","o"],"children":{"r":{"type":"internal","weight":990,"values":["\ufdd0","m","c","e","w"],"children":{"\ufdd0":{"type":"leaf","weight":990,"entries":[{"key":"for","weight":990,"content":"for"}]},"m":{"type":"internal","weight":757,"values":["\ufdd0","e","s"],"children":{"\ufdd0":{"type":"leaf","weight":757,"entries":[{"key":"form","weight":757,"content":"form"}]},"e":{"type":"leaf","weight":242,"entries":[{"key":"former","weight":242,"content":"former"}]},"s":{"type":"leaf","weight":206,"entries":[{"key":"forms","weight":206,"content":"forms"}]}}},"c":{"type":"internal","weight":606,"values":["e"],"children":{"e":{"type":"internal","weight":606,"values":["\ufdd0","s"],"children":{"\ufdd0":{"type":"leaf","weight":606,"entries":[{"key":"force","weight":606,"content":"force"}]},"s":{"type":"leaf","weight":461,"entries":[{"key":"forces","weight":461,"content":"forces"}]}}}}},"e":{"type":"leaf","weight":390,"entries":[{"key":"foreign","weight":390,"content":"foreign"}]},"w":{"type":"leaf","weight":124,"entries":[{"key":"forward","weight":124,"content":"forward"}]}}},"u":{"type":"internal","weight":836,"values":["n","r"],"children":{"n":{"type":"leaf","weight":836,"entries":[{"key":"found","weight":836,"content":"found"}]},"r":{"type":"leaf","weight":747,"entries":[{"key":"four","weight":747,"content":"four"}]}}},"l":{"type":"internal","weight":588,"values":["l"],"children":{"l":{"type":"internal","weight":588,"values":["o"],"children":{"o":{"type":"internal","weight":588,"values":["w"],"children":{"w":{"type":"internal","weight":588,"values":["i","e"],"children":{"i":{"type":"leaf","weight":588,"entries":[{"key":"following","weight":588,"content":"following"}]},"e":{"type":"leaf","weight":443,"entries":[{"key":"followed","weight":443,"content":"followed"}]}}}}}}}}},"o":{"type":"leaf","weight":342,"entries":[{"key":"food","weight":342,"content":"food"}]}}},"r":{"type":"internal","weight":975,"values":["o","e","i"],"children":{"o":{"type":"internal","weight":975,"values":["m","n"],"children":{"m":{"type":"leaf","weight":975,"entries":[{"key":"from","weight":975,"content":"from"}]},"n":{"type":"leaf","weight":589,"entries":[{"key":"front","weight":589,"content":"front"}]}}},"e":{"type":"internal","weight":650,"values":["e","n"],"children":{"e":{"type":"internal","weight":650,"values":["\ufdd0","d"],"children":{"\ufdd0":{"type":"leaf","weight":650,"entries":[{"key":"free","weight":650,"content":"free"}]},"d":{"type":"leaf","weight":223,"entries":[{"key":"freedom","weight":223,"content":"freedom"}]}}},"n":{"type":"leaf","weight":288,"entries":[{"key":"french","weight":288,"content":"french"}]}}},"i":{"type":"internal","weight":406,"values":["e"],"children":{"e":{"type":"internal","weight":406,"values":["n"],"children":{"n":{"type":"internal","weight":406,"values":["d"],"children":{"d":{"type":"leaf","weight":406,"entries":[{"key":"friends","weight":406,"content":"friends"},{"key":"friend","weight":263,"content":"friend"}]}}}}}}}}},"i":{"type":"internal","weight":928,"values":["r","n","v","e","g","s"],"children":{"r":{"type":"internal","weight":928,"values":["s","e","m"],"children":{"s":{"type":"leaf","weight":928,"entries":[{"key":"first","weight":928,"content":"first"}]},"e":{"type":"leaf","weight":499,"entries":[{"key":"fire","weight":499,"content":"fire"}]},"m":{"type":"leaf","weight":68,"entries":[{"key":"firm","weight":68,"content":"firm"}]}}},"n":{"type":"internal","weight":789,"values":["d","a","e"],"children":{"d":{"type":"leaf","weight":789,"entries":[{"key":"find","weight":789,"content":"find"}]},"a":{"type":"internal","weight":508,"values":["l"],"children":{"l":{"type":"leaf","weight":508,"entries":[{"key":"finally","weight":508,"content":"finally"},{"key":"final","weight":384,"content":"final"}]}}},"e":{"type":"leaf","weight":400,"entries":[{"key":"fine","weight":400,"content":"fine"}]}}},"v":{"type":"leaf","weight":686,"entries":[{"key":"five","weight":686,"content":"five"}]},"e":{"type":"leaf","weight":666,"entries":[{"key":"field","weight":666,"content":"field"}]},"g":{"type":"internal","weight":560,"values":["u"],"children":{"u":{"type":"internal","weight":560,"values":["r"],"children":{"r":{"type":"internal","weight":560,"values":["e"],"children":{"e":{"type":"internal","weight":560,"values":["\ufdd0","s"],"children":{"\ufdd0":{"type":"leaf","weight":560,"entries":[{"key":"figure","weight":560,"content":"figure"}]},"s":{"type":"leaf","weight":100,"entries":[{"key":"figures","weight":100,"content":"figures"}]}}}}}}}}},"s":{"type":"leaf","weight":160,"entries":[{"key":"fiscal","weight":160,"content":"fiscal"}]}}},"e":{"type":"internal","weight":848,"values":["w","l","e","d","a"],"children":{"w":{"type":"leaf","weight":848,"entries":[{"key":"few","weight":848,"content":"few"}]},"l":{"type":"leaf","weight":742,"entries":[{"key":"felt","weight":742,"content":"felt"}]},"e":{"type":"internal","weight":681,"values":["t","l","d"],"children":{"t":{"type":"leaf","weight":681,"entries":[{"key":"feet","weight":681,"content":"feet"}]},"l":{"type":"internal","weight":580,"values":["\ufdd0","i"],"children":{"\ufdd0":{"type":"leaf","weight":580,"entries":[{"key":"feel","weight":580,"content":"feel"}]},"i":{"type":"leaf","weight":440,"entries":[{"key":"feeling","weight":440,"content":"feeling"}]}}},"d":{"type":"leaf","weight":174,"entries":[{"key":"feed","weight":174,"content":"feed"}]}}},"d":{"type":"leaf","weight":629,"entries":[{"key":"federal","weight":629,"content":"federal"}]},"a":{"type":"leaf","weight":215,"entries":[{"key":"fear","weight":215,"content":"fear"}]}}},"a":{"type":"internal","weight":814,"values":["c","r","m","t","l","i"],"children":{"c":{"type":"internal","weight":814,"values":["t","e"],"children":{"t":{"type":"internal","weight":814,"values":["\ufdd0","o"],"children":{"\ufdd0":{"type":"leaf","weight":814,"entries":[{"key":"fact","weight":814,"content":"fact"}]},"o":{"type":"leaf","weight":41,"entries":[{"key":"factors","weight":41,"content":"factors"}]}}},"e":{"type":"leaf","weight":760,"entries":[{"key":"face","weight":760,"content":"face"}]}}},"r":{"type":"internal","weight":803,"values":["\ufdd0","m"],"children":{"\ufdd0":{"type":"leaf","weight":803,"entries":[{"key":"far","weight":803,"content":"far"}]},"m":{"type":"leaf","weight":188,"entries":[{"key":"farm","weight":188,"content":"farm"}]}}},"m":{"type":"leaf","weight":729,"entries":[{"key":"family","weight":729,"content":"family"}]},"t":{"type":"leaf","weight":487,"entries":[{"key":"father","weight":487,"content":"father"}]},"l":{"type":"leaf","weight":343,"entries":[{"key":"fall","weight":343,"content":"fall"}]},"i":{"type":"leaf","weight":88,"entries":[{"key":"faith","weight":88,"content":"faith"}]}}},"u":{"type":"internal","weight":605,"values":["l","t","r","n"],"children":{"l":{"type":"leaf","weight":605,"entries":[{"key":"full","weight":605,"content":"full"}]},"t":{"type":"leaf","weight":599,"entries":[{"key":"future","weight":599,"content":"future"}]},"r":{"type":"leaf","weight":583,"entries":[{"key":"further","weight":583,"content":"further"}]},"n":{"type":"leaf","weight":105,"entries":[{"key":"function","weight":105,"content":"function"}]}}},"l":{"type":"leaf","weight":391,"entries":[{"key":"floor","weight":391,"content":"floor"}]}}},"b":{"type":"internal","weight":984,"values":["e","y","u","a","o","i","r","l",null],"children":{"e":{"type":"internal","weight":984,"values":["\ufdd0","e","f","c","t","i","s","g","h","l","y","a","d"],"children":{"\ufdd0":{"type":"leaf","weight":984,"entries":[{"key":"be","weight":984,"content":"be"}]},"e":{"type":"leaf","weight":958,"entries":[{"key":"been","weight":958,"content":"been"}]},"f":{"type":"leaf","weight":911,"entries":[{"key":"before","weight":911,"content":"before"}]},"c":{"type":"internal","weight":898,"values":["a","o"],"children":{"a":{"type":"internal","weight":898,"values":["u","m"],"children":{"u":{"type":"leaf","weight":898,"entries":[{"key":"because","weight":898,"content":"because"}]},"m":{"type":"leaf","weight":633,"entries":[{"key":"became","weight":633,"content":"became"}]}}},"o":{"type":"internal","weight":743,"values":["m"],"children":{"m":{"type":"internal","weight":743,"values":["e"],"children":{"e":{"type":"internal","weight":743,"values":["\ufdd0","s"],"children":{"\ufdd0":{"type":"leaf","weight":743,"entries":[{"key":"become","weight":743,"content":"become"}]},"s":{"type":"leaf","weight":17,"entries":[{"key":"becomes","weight":17,"content":"becomes"}]}}}}}}}}},"t":{"type":"internal","weight":877,"values":["w","t"],"children":{"w":{"type":"leaf","weight":877,"entries":[{"key":"between","weight":877,"content":"between"}]},"t":{"type":"leaf","weight":797,"entries":[{"key":"better","weight":797,"content":"better"}]}}},"i":{"type":"leaf","weight":874,"entries":[{"key":"being","weight":874,"content":"being"}]},"s":{"type":"leaf","weight":738,"entries":[{"key":"best","weight":738,"content":"best"}]},"g":{"type":"internal","weight":710,"values":["a","i"],"children":{"a":{"type":"leaf","weight":710,"entries":[{"key":"began","weight":710,"content":"began"}]},"i":{"type":"leaf","weight":416,"entries":[{"key":"beginning","weight":416,"content":"beginning"}]}}},"h":{"type":"leaf","weight":648,"entries":[{"key":"behind","weight":648,"content":"behind"}]},"l":{"type":"internal","weight":541,"values":["i","o"],"children":{"i":{"type":"leaf","weight":541,"entries":[{"key":"believe","weight":541,"content":"believe"}]},"o":{"type":"leaf","weight":333,"entries":[{"key":"below","weight":333,"content":"below"}]}}},"y":{"type":"leaf","weight":466,"entries":[{"key":"beyond","weight":466,"content":"beyond"}]},"a":{"type":"leaf","weight":214,"entries":[{"key":"beautiful","weight":214,"content":"beautiful"}]},"d":{"type":"leaf","weight":211,"entries":[{"key":"bed","weight":211,"content":"bed"}]}}},"y":{"type":"leaf","weight":982,"entries":[{"key":"by","weight":982,"content":"by"}]},"u":{"type":"internal","weight":976,"values":["t","s","i"],"children":{"t":{"type":"leaf","weight":976,"entries":[{"key":"but","weight":976,"content":"but"}]},"s":{"type":"leaf","weight":779,"entries":[{"key":"business","weight":779,"content":"business"}]},"i":{"type":"internal","weight":398,"values":["l"],"children":{"l":{"type":"internal","weight":398,"values":["d","t"],"children":{"d":{"type":"leaf","weight":398,"entries":[{"key":"building","weight":398,"content":"building"}]},"t":{"type":"leaf","weight":9,"entries":[{"key":"built","weight":9,"content":"built"}]}}}}}}},"a":{"type":"internal","weight":907,"values":["c","s","d","l"],"children":{"c":{"type":"leaf","weight":907,"entries":[{"key":"back","weight":907,"content":"back"}]},"s":{"type":"internal","weight":489,"values":["i","e"],"children":{"i":{"type":"internal","weight":489,"values":["s","c"],"children":{"s":{"type":"leaf","weight":489,"entries":[{"key":"basis","weight":489,"content":"basis"}]},"c":{"type":"leaf","weight":439,"entries":[{"key":"basic","weight":439,"content":"basic"}]}}},"e":{"type":"leaf","weight":154,"entries":[{"key":"based","weight":154,"content":"based"}]}}},"d":{"type":"leaf","weight":313,"entries":[{"key":"bad","weight":313,"content":"bad"}]},"l":{"type":"leaf","weight":78,"entries":[{"key":"ball","weight":78,"content":"ball"}]}}},"o":{"type":"internal","weight":876,"values":["t","d","y","a","o","r"],"children":{"t":{"type":"leaf","weight":876,"entries":[{"key":"both","weight":876,"content":"both"}]},"d":{"type":"leaf","weight":671,"entries":[{"key":"body","weight":671,"content":"body"}]},"y":{"type":"internal","weight":623,"values":["\ufdd0","s"],"children":{"\ufdd0":{"type":"leaf","weight":623,"entries":[{"key":"boy","weight":623,"content":"boy"}]},"s":{"type":"leaf","weight":324,"entries":[{"key":"boys","weight":324,"content":"boys"}]}}},"a":{"type":"leaf","weight":618,"entries":[{"key":"board","weight":618,"content":"board"}]},"o":{"type":"leaf","weight":528,"entries":[{"key":"book","weight":528,"content":"book"}]},"r":{"type":"leaf","weight":99,"entries":[{"key":"born","weight":99,"content":"born"}]}}},"i":{"type":"internal","weight":745,"values":["g","l"],"children":{"g":{"type":"leaf","weight":745,"entries":[{"key":"big","weight":745,"content":"big"}]},"l":{"type":"leaf","weight":322,"entries":[{"key":"bill","weight":322,"content":"bill"}]}}},"r":{"type":"internal","weight":640,"values":["o","i"],"children":{"o":{"type":"internal","weight":640,"values":["u","w"],"children":{"u":{"type":"leaf","weight":640,"entries":[{"key":"brought","weight":640,"content":"brought"}]},"w":{"type":"leaf","weight":467,"entries":[{"key":"brown","weight":467,"content":"brown"}]}}},"i":{"type":"internal","weight":392,"values":["n","t"],"children":{"n":{"type":"leaf","weight":392,"entries":[{"key":"bring","weight":392,"content":"bring"}]},"t":{"type":"leaf","weight":143,"entries":[{"key":"british","weight":143,"content":"british"}]}}}}},"l":{"type":"internal","weight":546,"values":["a","u","o"],"children":{"a":{"type":"leaf","weight":546,"entries":[{"key":"black","weight":546,"content":"black"}]},"u":{"type":"leaf","weight":316,"entries":[{"key":"blue","weight":316,"content":"blue"}]},"o":{"type":"leaf","weight":168,"entries":[{"key":"blood","weight":168,"content":"blood"}]}}},"undefined":{"type":"leaf","weight":32,"entries":[{"key":"b","weight":32,"content":"b"}]}}},"n":{"type":"internal","weight":978,"values":["o","e","u","i","a"],"children":{"o":{"type":"internal","weight":978,"values":["t","\ufdd0","w","r","n"],"children":{"t":{"type":"internal","weight":978,"values":["\ufdd0","h","e"],"children":{"\ufdd0":{"type":"leaf","weight":978,"entries":[{"key":"not","weight":978,"content":"not"}]},"h":{"type":"leaf","weight":795,"entries":[{"key":"nothing","weight":795,"content":"nothing"}]},"e":{"type":"leaf","weight":204,"entries":[{"key":"note","weight":204,"content":"note"}]}}},"\ufdd0":{"type":"leaf","weight":951,"entries":[{"key":"no","weight":951,"content":"no"}]},"w":{"type":"leaf","weight":925,"entries":[{"key":"now","weight":925,"content":"now"}]},"r":{"type":"internal","weight":555,"values":["t","\ufdd0","m"],"children":{"t":{"type":"leaf","weight":555,"entries":[{"key":"north","weight":555,"content":"north"}]},"\ufdd0":{"type":"leaf","weight":521,"entries":[{"key":"nor","weight":521,"content":"nor"}]},"m":{"type":"leaf","weight":277,"entries":[{"key":"normal","weight":277,"content":"normal"}]}}},"n":{"type":"leaf","weight":61,"entries":[{"key":"none","weight":61,"content":"none"}]}}},"e":{"type":"internal","weight":937,"values":["w","v","x","e","c","a","i","g"],"children":{"w":{"type":"leaf","weight":937,"entries":[{"key":"new","weight":937,"content":"new"}]},"v":{"type":"leaf","weight":872,"entries":[{"key":"never","weight":872,"content":"never"}]},"x":{"type":"leaf","weight":782,"entries":[{"key":"next","weight":782,"content":"next"}]},"e":{"type":"internal","weight":746,"values":["d"],"children":{"d":{"type":"internal","weight":746,"values":["\ufdd0","e","s"],"children":{"\ufdd0":{"type":"leaf","weight":746,"entries":[{"key":"need","weight":746,"content":"need"}]},"e":{"type":"leaf","weight":498,"entries":[{"key":"needed","weight":498,"content":"needed"}]},"s":{"type":"leaf","weight":365,"entries":[{"key":"needs","weight":365,"content":"needs"}]}}}}},"c":{"type":"leaf","weight":591,"entries":[{"key":"necessary","weight":591,"content":"necessary"}]},"a":{"type":"internal","weight":532,"values":["r"],"children":{"r":{"type":"internal","weight":532,"values":["\ufdd0","l"],"children":{"\ufdd0":{"type":"leaf","weight":532,"entries":[{"key":"near","weight":532,"content":"near"}]},"l":{"type":"leaf","weight":303,"entries":[{"key":"nearly","weight":303,"content":"nearly"}]}}}}},"i":{"type":"leaf","weight":307,"entries":[{"key":"neither","weight":307,"content":"neither"}]},"g":{"type":"leaf","weight":43,"entries":[{"key":"negro","weight":43,"content":"negro"}]}}},"u":{"type":"internal","weight":821,"values":["m","c"],"children":{"m":{"type":"internal","weight":821,"values":["b"],"children":{"b":{"type":"internal","weight":821,"values":["e"],"children":{"e":{"type":"internal","weight":821,"values":["r"],"children":{"r":{"type":"internal","weight":821,"values":["\ufdd0","s"],"children":{"\ufdd0":{"type":"leaf","weight":821,"entries":[{"key":"number","weight":821,"content":"number"}]},"s":{"type":"leaf","weight":199,"entries":[{"key":"numbers","weight":199,"content":"numbers"}]}}}}}}}}},"c":{"type":"leaf","weight":127,"entries":[{"key":"nuclear","weight":127,"content":"nuclear"}]}}},"i":{"type":"leaf","weight":794,"entries":[{"key":"night","weight":794,"content":"night"}]},"a":{"type":"internal","weight":764,"values":["t","m"],"children":{"t":{"type":"internal","weight":764,"values":["i","u"],"children":{"i":{"type":"internal","weight":764,"values":["o"],"children":{"o":{"type":"internal","weight":764,"values":["n"],"children":{"n":{"type":"internal","weight":764,"values":["a","s",null],"children":{"a":{"type":"leaf","weight":764,"entries":[{"key":"national","weight":764,"content":"national"}]},"s":{"type":"leaf","weight":462,"entries":[{"key":"nations","weight":462,"content":"nations"}]},"undefined":{"type":"leaf","weight":291,"entries":[{"key":"nation","weight":291,"content":"nation"}]}}}}}}},"u":{"type":"internal","weight":506,"values":["r"],"children":{"r":{"type":"internal","weight":506,"values":["e","a"],"children":{"e":{"type":"leaf","weight":506,"entries":[{"key":"nature","weight":506,"content":"nature"}]},"a":{"type":"leaf","weight":385,"entries":[{"key":"natural","weight":385,"content":"natural"}]}}}}}}},"m":{"type":"leaf","weight":695,"entries":[{"key":"name","weight":695,"content":"name"}]}}}}},"y":{"type":"internal","weight":968,"values":["o","e"],"children":{"o":{"type":"internal","weight":968,"values":["u","r"],"children":{"u":{"type":"internal","weight":968,"values":["\ufdd0","r","n"],"children":{"\ufdd0":{"type":"leaf","weight":968,"entries":[{"key":"you","weight":968,"content":"you"}]},"r":{"type":"leaf","weight":903,"entries":[{"key":"your","weight":903,"content":"your"}]},"n":{"type":"leaf","weight":775,"entries":[{"key":"young","weight":775,"content":"young"}]}}},"r":{"type":"leaf","weight":701,"entries":[{"key":"york","weight":701,"content":"york"}]}}},"e":{"type":"internal","weight":906,"values":["a","t","s"],"children":{"a":{"type":"internal","weight":906,"values":["r"],"children":{"r":{"type":"leaf","weight":906,"entries":[{"key":"years","weight":906,"content":"years"},{"key":"year","weight":861,"content":"year"}]}}},"t":{"type":"leaf","weight":801,"entries":[{"key":"yet","weight":801,"content":"yet"}]},"s":{"type":"leaf","weight":326,"entries":[{"key":"yes","weight":326,"content":"yes"}]}}}}},"s":{"type":"internal","weight":964,"values":["h","o","a","u","t","e","i","m","c","y","p","q","l"],"children":{"h":{"type":"internal","weight":964,"values":["e","o","a"],"children":{"e":{"type":"leaf","weight":964,"entries":[{"key":"she","weight":964,"content":"she"}]},"o":{"type":"internal","weight":899,"values":["u","w","r","t"],"children":{"u":{"type":"leaf","weight":899,"entries":[{"key":"should","weight":899,"content":"should"}]},"w":{"type":"internal","weight":689,"values":["\ufdd0","n","e"],"children":{"\ufdd0":{"type":"leaf","weight":689,"entries":[{"key":"show","weight":689,"content":"show"}]},"n":{"type":"leaf","weight":422,"entries":[{"key":"shown","weight":422,"content":"shown"}]},"e":{"type":"leaf","weight":306,"entries":[{"key":"showed","weight":306,"content":"showed"}]}}},"r":{"type":"leaf","weight":566,"entries":[{"key":"short","weight":566,"content":"short"}]},"t":{"type":"leaf","weight":92,"entries":[{"key":"shot","weight":92,"content":"shot"}]}}},"a":{"type":"leaf","weight":659,"entries":[{"key":"shall","weight":659,"content":"shall"}]}}},"o":{"type":"internal","weight":949,"values":["\ufdd0","m","c","u","o","n","r","v"],"children":{"\ufdd0":{"type":"leaf","weight":949,"entries":[{"key":"so","weight":949,"content":"so"}]},"m":{"type":"internal","weight":936,"values":["e"],"children":{"e":{"type":"internal","weight":936,"values":["\ufdd0","t","w"],"children":{"\ufdd0":{"type":"leaf","weight":936,"entries":[{"key":"some","weight":936,"content":"some"}]},"t":{"type":"internal","weight":815,"values":["h","i"],"children":{"h":{"type":"leaf","weight":815,"entries":[{"key":"something","weight":815,"content":"something"}]},"i":{"type":"leaf","weight":587,"entries":[{"key":"sometimes","weight":587,"content":"sometimes"}]}}},"w":{"type":"leaf","weight":209,"entries":[{"key":"somewhat","weight":209,"content":"somewhat"}]}}}}},"c":{"type":"internal","weight":769,"values":["i"],"children":{"i":{"type":"internal","weight":769,"values":["a","e"],"children":{"a":{"type":"leaf","weight":769,"entries":[{"key":"social","weight":769,"content":"social"}]},"e":{"type":"leaf","weight":615,"entries":[{"key":"society","weight":615,"content":"society"}]}}}}},"u":{"type":"internal","weight":620,"values":["t","n"],"children":{"t":{"type":"internal","weight":620,"values":["h"],"children":{"h":{"type":"internal","weight":620,"values":["\ufdd0","e"],"children":{"\ufdd0":{"type":"leaf","weight":620,"entries":[{"key":"south","weight":620,"content":"south"}]},"e":{"type":"leaf","weight":278,"entries":[{"key":"southern","weight":278,"content":"southern"}]}}}}},"n":{"type":"leaf","weight":548,"entries":[{"key":"sound","weight":548,"content":"sound"}]}}},"o":{"type":"leaf","weight":534,"entries":[{"key":"soon","weight":534,"content":"soon"}]},"n":{"type":"leaf","weight":421,"entries":[{"key":"son","weight":421,"content":"son"}]},"r":{"type":"leaf","weight":414,"entries":[{"key":"sort","weight":414,"content":"sort"}]},"v":{"type":"leaf","weight":224,"entries":[{"key":"soviet","weight":224,"content":"soviet"}]}}},"a":{"type":"internal","weight":948,"values":["i","m","y","w","t","l"],"children":{"i":{"type":"leaf","weight":948,"entries":[{"key":"said","weight":948,"content":"said"}]},"m":{"type":"leaf","weight":870,"entries":[{"key":"same","weight":870,"content":"same"}]},"y":{"type":"internal","weight":833,"values":["\ufdd0","s","i"],"children":{"\ufdd0":{"type":"leaf","weight":833,"entries":[{"key":"say","weight":833,"content":"say"}]},"s":{"type":"leaf","weight":538,"entries":[{"key":"says","weight":538,"content":"says"}]},"i":{"type":"leaf","weight":106,"entries":[{"key":"saying","weight":106,"content":"saying"}]}}},"w":{"type":"leaf","weight":739,"entries":[{"key":"saw","weight":739,"content":"saw"}]},"t":{"type":"leaf","weight":358,"entries":[{"key":"sat","weight":358,"content":"sat"}]},"l":{"type":"leaf","weight":262,"entries":[{"key":"sales","weight":262,"content":"sales"}]}}},"u":{"type":"internal","weight":924,"values":["c","r","p","b","d","m","n","g"],"children":{"c":{"type":"leaf","weight":924,"entries":[{"key":"such","weight":924,"content":"such"}]},"r":{"type":"internal","weight":652,"values":["e","f"],"children":{"e":{"type":"leaf","weight":652,"entries":[{"key":"sure","weight":652,"content":"sure"}]},"f":{"type":"leaf","weight":536,"entries":[{"key":"surface","weight":536,"content":"surface"}]}}},"p":{"type":"leaf","weight":478,"entries":[{"key":"support","weight":478,"content":"support"}]},"b":{"type":"leaf","weight":401,"entries":[{"key":"subject","weight":401,"content":"subject"}]},"d":{"type":"leaf","weight":370,"entries":[{"key":"suddenly","weight":370,"content":"suddenly"}]},"m":{"type":"leaf","weight":266,"entries":[{"key":"summer","weight":266,"content":"summer"}]},"n":{"type":"leaf","weight":89,"entries":[{"key":"sun","weight":89,"content":"sun"}]},"g":{"type":"leaf","weight":31,"entries":[{"key":"suggested","weight":31,"content":"suggested"}]}}},"t":{"type":"internal","weight":890,"values":["a","i","u","r","o","e"],"children":{"a":{"type":"internal","weight":890,"values":["t","r","g","n","f","y"],"children":{"t":{"type":"internal","weight":890,"values":["e","i"],"children":{"e":{"type":"internal","weight":890,"values":["\ufdd0","s","m"],"children":{"\ufdd0":{"type":"leaf","weight":890,"entries":[{"key":"state","weight":890,"content":"state"}]},"s":{"type":"leaf","weight":849,"entries":[{"key":"states","weight":849,"content":"states"}]},"m":{"type":"leaf","weight":302,"entries":[{"key":"statement","weight":302,"content":"statement"}]}}},"i":{"type":"leaf","weight":23,"entries":[{"key":"station","weight":23,"content":"station"}]}}},"r":{"type":"internal","weight":511,"values":["t"],"children":{"t":{"type":"leaf","weight":511,"entries":[{"key":"started","weight":511,"content":"started"},{"key":"start","weight":372,"content":"start"}]}}},"g":{"type":"leaf","weight":465,"entries":[{"key":"stage","weight":465,"content":"stage"}]},"n":{"type":"internal","weight":349,"values":["d"],"children":{"d":{"type":"internal","weight":349,"values":["\ufdd0","a"],"children":{"\ufdd0":{"type":"leaf","weight":349,"entries":[{"key":"stand","weight":349,"content":"stand"}]},"a":{"type":"leaf","weight":80,"entries":[{"key":"standard","weight":80,"content":"standard"}]}}}}},"f":{"type":"leaf","weight":103,"entries":[{"key":"staff","weight":103,"content":"staff"}]},"y":{"type":"leaf","weight":97,"entries":[{"key":"stay","weight":97,"content":"stay"}]}}},"i":{"type":"leaf","weight":885,"entries":[{"key":"still","weight":885,"content":"still"}]},"u":{"type":"internal","weight":631,"values":["d"],"children":{"d":{"type":"internal","weight":631,"values":["y","e","i"],"children":{"y":{"type":"leaf","weight":631,"entries":[{"key":"study","weight":631,"content":"study"}]},"e":{"type":"internal","weight":571,"values":["n"],"children":{"n":{"type":"internal","weight":571,"values":["t"],"children":{"t":{"type":"leaf","weight":571,"entries":[{"key":"students","weight":571,"content":"students"},{"key":"student","weight":244,"content":"student"}]}}}}},"i":{"type":"leaf","weight":3,"entries":[{"key":"studies","weight":3,"content":"studies"}]}}}}},"r":{"type":"internal","weight":626,"values":["e","o","a"],"children":{"e":{"type":"internal","weight":626,"values":["e","n","s"],"children":{"e":{"type":"leaf","weight":626,"entries":[{"key":"street","weight":626,"content":"street"}]},"n":{"type":"leaf","weight":281,"entries":[{"key":"strength","weight":281,"content":"strength"}]},"s":{"type":"leaf","weight":49,"entries":[{"key":"stress","weight":49,"content":"stress"}]}}},"o":{"type":"leaf","weight":544,"entries":[{"key":"strong","weight":544,"content":"strong"}]},"a":{"type":"leaf","weight":109,"entries":[{"key":"straight","weight":109,"content":"straight"}]}}},"o":{"type":"internal","weight":568,"values":["o","r","c","p"],"children":{"o":{"type":"leaf","weight":568,"entries":[{"key":"stood","weight":568,"content":"stood"}]},"r":{"type":"leaf","weight":371,"entries":[{"key":"story","weight":371,"content":"story"}]},"c":{"type":"leaf","weight":345,"entries":[{"key":"stock","weight":345,"content":"stock"}]},"p":{"type":"leaf","weight":231,"entries":[{"key":"stopped","weight":231,"content":"stopped"},{"key":"stop","weight":161,"content":"stop"}]}}},"e":{"type":"internal","weight":246,"values":["p"],"children":{"p":{"type":"internal","weight":246,"values":["\ufdd0","s"],"children":{"\ufdd0":{"type":"leaf","weight":246,"entries":[{"key":"step","weight":246,"content":"step"}]},"s":{"type":"leaf","weight":153,"entries":[{"key":"steps","weight":153,"content":"steps"}]}}}}}}},"e":{"type":"internal","weight":883,"values":["e","t","v","c","r","n","a"],"children":{"e":{"type":"internal","weight":883,"values":["\ufdd0","m","n"],"children":{"\ufdd0":{"type":"leaf","weight":883,"entries":[{"key":"see","weight":883,"content":"see"}]},"m":{"type":"internal","weight":731,"values":["e","s",null],"children":{"e":{"type":"leaf","weight":731,"entries":[{"key":"seemed","weight":731,"content":"seemed"}]},"s":{"type":"leaf","weight":649,"entries":[{"key":"seems","weight":649,"content":"seems"}]},"undefined":{"type":"leaf","weight":603,"entries":[{"key":"seem","weight":603,"content":"seem"}]}}},"n":{"type":"leaf","weight":674,"entries":[{"key":"seen","weight":674,"content":"seen"}]}}},"t":{"type":"leaf","weight":798,"entries":[{"key":"set","weight":798,"content":"set"}]},"v":{"type":"internal","weight":766,"values":["e"],"children":{"e":{"type":"internal","weight":766,"values":["r","n"],"children":{"r":{"type":"leaf","weight":766,"entries":[{"key":"several","weight":766,"content":"several"}]},"n":{"type":"leaf","weight":96,"entries":[{"key":"seven","weight":96,"content":"seven"}]}}}}},"c":{"type":"internal","weight":761,"values":["o","r","t"],"children":{"o":{"type":"leaf","weight":761,"entries":[{"key":"second","weight":761,"content":"second"}]},"r":{"type":"leaf","weight":505,"entries":[{"key":"secretary","weight":505,"content":"secretary"}]},"t":{"type":"leaf","weight":503,"entries":[{"key":"section","weight":503,"content":"section"}]}}},"r":{"type":"internal","weight":716,"values":["v","i"],"children":{"v":{"type":"internal","weight":716,"values":["i","e"],"children":{"i":{"type":"internal","weight":716,"values":["c"],"children":{"c":{"type":"internal","weight":716,"values":["e"],"children":{"e":{"type":"internal","weight":716,"values":["\ufdd0","s"],"children":{"\ufdd0":{"type":"leaf","weight":716,"entries":[{"key":"service","weight":716,"content":"service"}]},"s":{"type":"leaf","weight":290,"entries":[{"key":"services","weight":290,"content":"services"}]}}}}}}},"e":{"type":"leaf","weight":150,"entries":[{"key":"served","weight":150,"content":"served"},{"key":"serve","weight":50,"content":"serve"}]}}},"i":{"type":"internal","weight":239,"values":["e","o"],"children":{"e":{"type":"leaf","weight":239,"entries":[{"key":"series","weight":239,"content":"series"}]},"o":{"type":"leaf","weight":134,"entries":[{"key":"serious","weight":134,"content":"serious"}]}}}}},"n":{"type":"internal","weight":708,"values":["s","t"],"children":{"s":{"type":"leaf","weight":708,"entries":[{"key":"sense","weight":708,"content":"sense"}]},"t":{"type":"leaf","weight":328,"entries":[{"key":"sent","weight":328,"content":"sent"}]}}},"a":{"type":"leaf","weight":25,"entries":[{"key":"season","weight":25,"content":"season"}]}}},"i":{"type":"internal","weight":858,"values":["n","d","x","t","m","z"],"children":{"n":{"type":"internal","weight":858,"values":["c","g"],"children":{"c":{"type":"leaf","weight":858,"entries":[{"key":"since","weight":858,"content":"since"}]},"g":{"type":"leaf","weight":444,"entries":[{"key":"single","weight":444,"content":"single"}]}}},"d":{"type":"leaf","weight":770,"entries":[{"key":"side","weight":770,"content":"side"}]},"x":{"type":"leaf","weight":585,"entries":[{"key":"six","weight":585,"content":"six"}]},"t":{"type":"leaf","weight":525,"entries":[{"key":"situation","weight":525,"content":"situation"}]},"m":{"type":"internal","weight":437,"values":["p","i"],"children":{"p":{"type":"internal","weight":437,"values":["l"],"children":{"l":{"type":"internal","weight":437,"values":["y","e"],"children":{"y":{"type":"leaf","weight":437,"entries":[{"key":"simply","weight":437,"content":"simply"}]},"e":{"type":"leaf","weight":396,"entries":[{"key":"simple","weight":396,"content":"simple"}]}}}}},"i":{"type":"leaf","weight":388,"entries":[{"key":"similar","weight":388,"content":"similar"}]}}},"z":{"type":"leaf","weight":285,"entries":[{"key":"size","weight":285,"content":"size"}]}}},"m":{"type":"leaf","weight":837,"entries":[{"key":"small","weight":837,"content":"small"}]},"c":{"type":"internal","weight":827,"values":["h","i","e"],"children":{"h":{"type":"internal","weight":827,"values":["o"],"children":{"o":{"type":"internal","weight":827,"values":["o"],"children":{"o":{"type":"internal","weight":827,"values":["l"],"children":{"l":{"type":"internal","weight":827,"values":["\ufdd0","s"],"children":{"\ufdd0":{"type":"leaf","weight":827,"entries":[{"key":"school","weight":827,"content":"school"}]},"s":{"type":"leaf","weight":516,"entries":[{"key":"schools","weight":516,"content":"schools"}]}}}}}}}}},"i":{"type":"leaf","weight":249,"entries":[{"key":"science","weight":249,"content":"science"}]},"e":{"type":"leaf","weight":35,"entries":[{"key":"scene","weight":35,"content":"scene"}]}}},"y":{"type":"internal","weight":799,"values":["s"],"children":{"s":{"type":"internal","weight":799,"values":["t"],"children":{"t":{"type":"internal","weight":799,"values":["e"],"children":{"e":{"type":"internal","weight":799,"values":["m"],"children":{"m":{"type":"internal","weight":799,"values":["\ufdd0","s"],"children":{"\ufdd0":{"type":"leaf","weight":799,"entries":[{"key":"system","weight":799,"content":"system"}]},"s":{"type":"leaf","weight":233,"entries":[{"key":"systems","weight":233,"content":"systems"}]}}}}}}}}}}},"p":{"type":"internal","weight":637,"values":["e","a","i","r"],"children":{"e":{"type":"internal","weight":637,"values":["c","a","n"],"children":{"c":{"type":"internal","weight":637,"values":["i"],"children":{"i":{"type":"internal","weight":637,"values":["a","f"],"children":{"a":{"type":"leaf","weight":637,"entries":[{"key":"special","weight":637,"content":"special"}]},"f":{"type":"leaf","weight":126,"entries":[{"key":"specific","weight":126,"content":"specific"}]}}}}},"a":{"type":"leaf","weight":85,"entries":[{"key":"speak","weight":85,"content":"speak"}]},"n":{"type":"leaf","weight":13,"entries":[{"key":"spent","weight":13,"content":"spent"}]}}},"a":{"type":"leaf","weight":488,"entries":[{"key":"space","weight":488,"content":"space"}]},"i":{"type":"leaf","weight":485,"entries":[{"key":"spirit","weight":485,"content":"spirit"}]},"r":{"type":"leaf","weight":210,"entries":[{"key":"spring","weight":210,"content":"spring"}]}}},"q":{"type":"leaf","weight":317,"entries":[{"key":"square","weight":317,"content":"square"}]},"l":{"type":"leaf","weight":125,"entries":[{"key":"slowly","weight":125,"content":"slowly"}]}}},"m":{"type":"internal","weight":953,"values":["o","a","y","e","u","i"],"children":{"o":{"type":"internal","weight":953,"values":["r","s","n","m","t","d","v","u"],"children":{"r":{"type":"internal","weight":953,"values":["e","n","a"],"children":{"e":{"type":"leaf","weight":953,"entries":[{"key":"more","weight":953,"content":"more"}]},"n":{"type":"leaf","weight":563,"entries":[{"key":"morning","weight":563,"content":"morning"}]},"a":{"type":"leaf","weight":314,"entries":[{"key":"moral","weight":314,"content":"moral"}]}}},"s":{"type":"leaf","weight":917,"entries":[{"key":"most","weight":917,"content":"most"}]},"n":{"type":"internal","weight":656,"values":["e","t"],"children":{"e":{"type":"leaf","weight":656,"entries":[{"key":"money","weight":656,"content":"money"}]},"t":{"type":"internal","weight":502,"values":["h"],"children":{"h":{"type":"leaf","weight":502,"entries":[{"key":"months","weight":502,"content":"months"},{"key":"month","weight":240,"content":"month"}]}}}}},"m":{"type":"leaf","weight":632,"entries":[{"key":"moment","weight":632,"content":"moment"}]},"t":{"type":"leaf","weight":579,"entries":[{"key":"mother","weight":579,"content":"mother"}]},"d":{"type":"leaf","weight":533,"entries":[{"key":"modern","weight":533,"content":"modern"}]},"v":{"type":"internal","weight":479,"values":["e","i"],"children":{"e":{"type":"internal","weight":479,"values":["d","\ufdd0","m"],"children":{"d":{"type":"leaf","weight":479,"entries":[{"key":"moved","weight":479,"content":"moved"}]},"\ufdd0":{"type":"leaf","weight":436,"entries":[{"key":"move","weight":436,"content":"move"}]},"m":{"type":"leaf","weight":220,"entries":[{"key":"movement","weight":220,"content":"movement"}]}}},"i":{"type":"leaf","weight":111,"entries":[{"key":"moving","weight":111,"content":"moving"}]}}},"u":{"type":"leaf","weight":6,"entries":[{"key":"mouth","weight":6,"content":"mouth"}]}}},"a":{"type":"internal","weight":931,"values":["y","n","d","k","t","j","r","i","c"],"children":{"y":{"type":"internal","weight":931,"values":["\ufdd0","b"],"children":{"\ufdd0":{"type":"leaf","weight":931,"entries":[{"key":"may","weight":931,"content":"may"}]},"b":{"type":"leaf","weight":259,"entries":[{"key":"maybe","weight":259,"content":"maybe"}]}}},"n":{"type":"internal","weight":920,"values":["\ufdd0","y","n"],"children":{"\ufdd0":{"type":"leaf","weight":920,"entries":[{"key":"man","weight":920,"content":"man"}]},"y":{"type":"leaf","weight":912,"entries":[{"key":"many","weight":912,"content":"many"}]},"n":{"type":"leaf","weight":190,"entries":[{"key":"manner","weight":190,"content":"manner"}]}}},"d":{"type":"leaf","weight":916,"entries":[{"key":"made","weight":916,"content":"made"}]},"k":{"type":"internal","weight":887,"values":["e","i"],"children":{"e":{"type":"internal","weight":887,"values":["\ufdd0","s"],"children":{"\ufdd0":{"type":"leaf","weight":887,"entries":[{"key":"make","weight":887,"content":"make"}]},"s":{"type":"leaf","weight":445,"entries":[{"key":"makes","weight":445,"content":"makes"}]}}},"i":{"type":"leaf","weight":642,"entries":[{"key":"making","weight":642,"content":"making"}]}}},"t":{"type":"internal","weight":704,"values":["t","e"],"children":{"t":{"type":"leaf","weight":704,"entries":[{"key":"matter","weight":704,"content":"matter"}]},"e":{"type":"leaf","weight":463,"entries":[{"key":"material","weight":463,"content":"material"}]}}},"j":{"type":"leaf","weight":635,"entries":[{"key":"major","weight":635,"content":"major"}]},"r":{"type":"internal","weight":377,"values":["k","c","r"],"children":{"k":{"type":"leaf","weight":377,"entries":[{"key":"market","weight":377,"content":"market"}]},"c":{"type":"leaf","weight":166,"entries":[{"key":"march","weight":166,"content":"march"}]},"r":{"type":"leaf","weight":21,"entries":[{"key":"married","weight":21,"content":"married"}]}}},"i":{"type":"leaf","weight":155,"entries":[{"key":"main","weight":155,"content":"main"}]},"c":{"type":"leaf","weight":1,"entries":[{"key":"machine","weight":1,"content":"machine"}]}}},"y":{"type":"internal","weight":926,"values":["\ufdd0","s"],"children":{"\ufdd0":{"type":"leaf","weight":926,"entries":[{"key":"my","weight":926,"content":"my"}]},"s":{"type":"leaf","weight":230,"entries":[{"key":"myself","weight":230,"content":"myself"}]}}},"e":{"type":"internal","weight":919,"values":["\ufdd0","n","m","a","d","e","t","r"],"children":{"\ufdd0":{"type":"leaf","weight":919,"entries":[{"key":"me","weight":919,"content":"me"}]},"n":{"type":"leaf","weight":882,"entries":[{"key":"men","weight":882,"content":"men"}]},"m":{"type":"internal","weight":725,"values":["b"],"children":{"b":{"type":"internal","weight":725,"values":["e"],"children":{"e":{"type":"internal","weight":725,"values":["r"],"children":{"r":{"type":"leaf","weight":725,"entries":[{"key":"members","weight":725,"content":"members"},{"key":"member","weight":284,"content":"member"}]}}}}}}},"a":{"type":"internal","weight":706,"values":["n"],"children":{"n":{"type":"internal","weight":706,"values":["s","\ufdd0","i"],"children":{"s":{"type":"leaf","weight":706,"entries":[{"key":"means","weight":706,"content":"means"}]},"\ufdd0":{"type":"leaf","weight":535,"entries":[{"key":"mean","weight":535,"content":"mean"}]},"i":{"type":"leaf","weight":213,"entries":[{"key":"meaning","weight":213,"content":"meaning"}]}}}}},"d":{"type":"leaf","weight":405,"entries":[{"key":"medical","weight":405,"content":"medical"}]},"e":{"type":"internal","weight":393,"values":["t"],"children":{"t":{"type":"leaf","weight":393,"entries":[{"key":"meeting","weight":393,"content":"meeting"},{"key":"meet","weight":356,"content":"meet"}]}}},"t":{"type":"internal","weight":311,"values":["h",null],"children":{"h":{"type":"internal","weight":311,"values":["o"],"children":{"o":{"type":"internal","weight":311,"values":["d"],"children":{"d":{"type":"leaf","weight":311,"entries":[{"key":"methods","weight":311,"content":"methods"},{"key":"method","weight":309,"content":"method"}]}}}}},"undefined":{"type":"leaf","weight":251,"entries":[{"key":"met","weight":251,"content":"met"}]}}},"r":{"type":"leaf","weight":274,"entries":[{"key":"merely","weight":274,"content":"merely"}]}}},"u":{"type":"internal","weight":910,"values":["s","c"],"children":{"s":{"type":"internal","weight":910,"values":["t","i"],"children":{"t":{"type":"leaf","weight":910,"entries":[{"key":"must","weight":910,"content":"must"}]},"i":{"type":"leaf","weight":581,"entries":[{"key":"music","weight":581,"content":"music"}]}}},"c":{"type":"leaf","weight":905,"entries":[{"key":"much","weight":905,"content":"much"}]}}},"i":{"type":"internal","weight":864,"values":["g","n","s","l","d"],"children":{"g":{"type":"leaf","weight":864,"entries":[{"key":"might","weight":864,"content":"might"}]},"n":{"type":"internal","weight":726,"values":["d","u"],"children":{"d":{"type":"leaf","weight":726,"entries":[{"key":"mind","weight":726,"content":"mind"}]},"u":{"type":"leaf","weight":523,"entries":[{"key":"minutes","weight":523,"content":"minutes"}]}}},"s":{"type":"leaf","weight":639,"entries":[{"key":"miss","weight":639,"content":"miss"}]},"l":{"type":"internal","weight":565,"values":["i","l","e"],"children":{"i":{"type":"leaf","weight":565,"entries":[{"key":"military","weight":565,"content":"military"}]},"l":{"type":"leaf","weight":547,"entries":[{"key":"million","weight":547,"content":"million"}]},"e":{"type":"leaf","weight":450,"entries":[{"key":"miles","weight":450,"content":"miles"}]}}},"d":{"type":"leaf","weight":144,"entries":[{"key":"middle","weight":144,"content":"middle"}]}}}}},"u":{"type":"internal","weight":946,"values":["p","n","s"],"children":{"p":{"type":"internal","weight":946,"values":["\ufdd0","o"],"children":{"\ufdd0":{"type":"leaf","weight":946,"entries":[{"key":"up","weight":946,"content":"up"}]},"o":{"type":"leaf","weight":828,"entries":[{"key":"upon","weight":828,"content":"upon"}]}}},"n":{"type":"internal","weight":873,"values":["d","i","t"],"children":{"d":{"type":"internal","weight":873,"values":["e"],"children":{"e":{"type":"internal","weight":873,"values":["r"],"children":{"r":{"type":"internal","weight":873,"values":["\ufdd0","s"],"children":{"\ufdd0":{"type":"leaf","weight":873,"entries":[{"key":"under","weight":873,"content":"under"}]},"s":{"type":"internal","weight":283,"values":["t"],"children":{"t":{"type":"internal","weight":283,"values":["a"],"children":{"a":{"type":"internal","weight":283,"values":["n"],"children":{"n":{"type":"internal","weight":283,"values":["d"],"children":{"d":{"type":"internal","weight":283,"values":["\ufdd0","i"],"children":{"\ufdd0":{"type":"leaf","weight":283,"entries":[{"key":"understand","weight":283,"content":"understand"}]},"i":{"type":"leaf","weight":170,"entries":[{"key":"understanding","weight":170,"content":"understanding"}]}}}}}}}}}}}}}}}}},"i":{"type":"internal","weight":823,"values":["t","v","o"],"children":{"t":{"type":"leaf","weight":823,"entries":[{"key":"united","weight":823,"content":"united"},{"key":"unit","weight":10,"content":"unit"}]},"v":{"type":"leaf","weight":575,"entries":[{"key":"university","weight":575,"content":"university"}]},"o":{"type":"leaf","weight":483,"entries":[{"key":"union","weight":483,"content":"union"}]}}},"t":{"type":"leaf","weight":818,"entries":[{"key":"until","weight":818,"content":"until"}]}}},"s":{"type":"internal","weight":865,"values":["\ufdd0","e","u","i"],"children":{"\ufdd0":{"type":"leaf","weight":865,"entries":[{"key":"us","weight":865,"content":"us"}]},"e":{"type":"leaf","weight":853,"entries":[{"key":"used","weight":853,"content":"used"},{"key":"use","weight":847,"content":"use"}]},"u":{"type":"leaf","weight":556,"entries":[{"key":"usually","weight":556,"content":"usually"}]},"i":{"type":"leaf","weight":330,"entries":[{"key":"using","weight":330,"content":"using"}]}}}}},"c":{"type":"internal","weight":940,"values":["a","o","i","h","e","l","u",null],"children":{"a":{"type":"internal","weight":940,"values":["n","m","l","s","r","u"],"children":{"n":{"type":"internal","weight":940,"values":["\ufdd0","n"],"children":{"\ufdd0":{"type":"leaf","weight":940,"entries":[{"key":"can","weight":940,"content":"can"}]},"n":{"type":"leaf","weight":646,"entries":[{"key":"cannot","weight":646,"content":"cannot"}]}}},"m":{"type":"leaf","weight":855,"entries":[{"key":"came","weight":855,"content":"came"}]},"l":{"type":"internal","weight":791,"values":["l"],"children":{"l":{"type":"leaf","weight":791,"entries":[{"key":"called","weight":791,"content":"called"},{"key":"call","weight":500,"content":"call"}]}}},"s":{"type":"internal","weight":750,"values":["e"],"children":{"e":{"type":"internal","weight":750,"values":["\ufdd0","s"],"children":{"\ufdd0":{"type":"leaf","weight":750,"entries":[{"key":"case","weight":750,"content":"case"}]},"s":{"type":"leaf","weight":350,"entries":[{"key":"cases","weight":350,"content":"cases"}]}}}}},"r":{"type":"internal","weight":667,"values":["\ufdd0","e","r","s"],"children":{"\ufdd0":{"type":"leaf","weight":667,"entries":[{"key":"car","weight":667,"content":"car"}]},"e":{"type":"leaf","weight":407,"entries":[{"key":"care","weight":407,"content":"care"}]},"r":{"type":"leaf","weight":200,"entries":[{"key":"carried","weight":200,"content":"carried"}]},"s":{"type":"leaf","weight":90,"entries":[{"key":"cars","weight":90,"content":"cars"}]}}},"u":{"type":"leaf","weight":236,"entries":[{"key":"cause","weight":236,"content":"cause"}]}}},"o":{"type":"internal","weight":935,"values":["u","m","l","s","n","r","v"],"children":{"u":{"type":"internal","weight":935,"values":["l","r","n","p"],"children":{"l":{"type":"leaf","weight":935,"entries":[{"key":"could","weight":935,"content":"could"}]},"r":{"type":"internal","weight":820,"values":["s","t"],"children":{"s":{"type":"leaf","weight":820,"entries":[{"key":"course","weight":820,"content":"course"}]},"t":{"type":"leaf","weight":604,"entries":[{"key":"court","weight":604,"content":"court"}]}}},"n":{"type":"internal","weight":723,"values":["t","c"],"children":{"t":{"type":"internal","weight":723,"values":["r","y"],"children":{"r":{"type":"internal","weight":723,"values":["y","i"],"children":{"y":{"type":"leaf","weight":723,"entries":[{"key":"country","weight":723,"content":"country"}]},"i":{"type":"leaf","weight":360,"entries":[{"key":"countries","weight":360,"content":"countries"}]}}},"y":{"type":"leaf","weight":378,"entries":[{"key":"county","weight":378,"content":"county"}]}}},"c":{"type":"leaf","weight":11,"entries":[{"key":"council","weight":11,"content":"council"}]}}},"p":{"type":"leaf","weight":178,"entries":[{"key":"couple","weight":178,"content":"couple"}]}}},"m":{"type":"internal","weight":859,"values":["e","p","m","i"],"children":{"e":{"type":"internal","weight":859,"values":["\ufdd0","s"],"children":{"\ufdd0":{"type":"leaf","weight":859,"entries":[{"key":"come","weight":859,"content":"come"}]},"s":{"type":"leaf","weight":279,"entries":[{"key":"comes","weight":279,"content":"comes"}]}}},"p":{"type":"internal","weight":692,"values":["a","l"],"children":{"a":{"type":"leaf","weight":692,"entries":[{"key":"company","weight":692,"content":"company"}]},"l":{"type":"internal","weight":482,"values":["e"],"children":{"e":{"type":"internal","weight":482,"values":["t"],"children":{"t":{"type":"internal","weight":482,"values":["e"],"children":{"e":{"type":"internal","weight":482,"values":["\ufdd0","l"],"children":{"\ufdd0":{"type":"leaf","weight":482,"entries":[{"key":"complete","weight":482,"content":"complete"}]},"l":{"type":"leaf","weight":83,"entries":[{"key":"completely","weight":83,"content":"completely"}]}}}}}}}}}}},"m":{"type":"internal","weight":608,"values":["u","o","i"],"children":{"u":{"type":"leaf","weight":608,"entries":[{"key":"community","weight":608,"content":"community"}]},"o":{"type":"leaf","weight":593,"entries":[{"key":"common","weight":593,"content":"common"}]},"i":{"type":"internal","weight":427,"values":["t","s"],"children":{"t":{"type":"leaf","weight":427,"entries":[{"key":"committee","weight":427,"content":"committee"}]},"s":{"type":"leaf","weight":8,"entries":[{"key":"commission","weight":8,"content":"commission"}]}}}}},"i":{"type":"leaf","weight":456,"entries":[{"key":"coming","weight":456,"content":"coming"}]}}},"l":{"type":"internal","weight":657,"values":["l","d","o"],"children":{"l":{"type":"leaf","weight":657,"entries":[{"key":"college","weight":657,"content":"college"}]},"d":{"type":"leaf","weight":435,"entries":[{"key":"cold","weight":435,"content":"cold"}]},"o":{"type":"leaf","weight":294,"entries":[{"key":"color","weight":294,"content":"color"}]}}},"s":{"type":"internal","weight":602,"values":["t"],"children":{"t":{"type":"internal","weight":602,"values":["\ufdd0","s"],"children":{"\ufdd0":{"type":"leaf","weight":602,"entries":[{"key":"cost","weight":602,"content":"cost"}]},"s":{"type":"leaf","weight":468,"entries":[{"key":"costs","weight":468,"content":"costs"}]}}}}},"n":{"type":"internal","weight":592,"values":["t","d","g","s","c"],"children":{"t":{"type":"internal","weight":592,"values":["r","i"],"children":{"r":{"type":"leaf","weight":592,"entries":[{"key":"control","weight":592,"content":"control"}]},"i":{"type":"internal","weight":258,"values":["n"],"children":{"n":{"type":"internal","weight":258,"values":["u"],"children":{"u":{"type":"internal","weight":258,"values":["e"],"children":{"e":{"type":"leaf","weight":258,"entries":[{"key":"continued","weight":258,"content":"continued"},{"key":"continue","weight":54,"content":"continue"}]}}}}}}}}},"d":{"type":"leaf","weight":476,"entries":[{"key":"conditions","weight":476,"content":"conditions"}]},"g":{"type":"leaf","weight":364,"entries":[{"key":"congress","weight":364,"content":"congress"}]},"s":{"type":"internal","weight":361,"values":["i"],"children":{"i":{"type":"internal","weight":361,"values":["d"],"children":{"d":{"type":"internal","weight":361,"values":["e"],"children":{"e":{"type":"internal","weight":361,"values":["r"],"children":{"r":{"type":"leaf","weight":361,"entries":[{"key":"considered","weight":361,"content":"considered"},{"key":"consider","weight":212,"content":"consider"}]}}}}}}}}},"c":{"type":"leaf","weight":273,"entries":[{"key":"concerned","weight":273,"content":"concerned"}]}}},"r":{"type":"internal","weight":120,"values":["n","p"],"children":{"n":{"type":"leaf","weight":120,"entries":[{"key":"corner","weight":120,"content":"corner"}]},"p":{"type":"leaf","weight":76,"entries":[{"key":"corps","weight":76,"content":"corps"}]}}},"v":{"type":"leaf","weight":19,"entries":[{"key":"covered","weight":19,"content":"covered"}]}}},"i":{"type":"internal","weight":780,"values":["t"],"children":{"t":{"type":"internal","weight":780,"values":["y","i"],"children":{"y":{"type":"leaf","weight":780,"entries":[{"key":"city","weight":780,"content":"city"}]},"i":{"type":"leaf","weight":44,"entries":[{"key":"cities","weight":44,"content":"cities"}]}}}}},"h":{"type":"internal","weight":740,"values":["i","u","a","r","o"],"children":{"i":{"type":"internal","weight":740,"values":["l","e"],"children":{"l":{"type":"internal","weight":740,"values":["d"],"children":{"d":{"type":"leaf","weight":740,"entries":[{"key":"children","weight":740,"content":"children"},{"key":"child","weight":569,"content":"child"}]}}},"e":{"type":"leaf","weight":151,"entries":[{"key":"chief","weight":151,"content":"chief"}]}}},"u":{"type":"leaf","weight":737,"entries":[{"key":"church","weight":737,"content":"church"}]},"a":{"type":"internal","weight":619,"values":["n","r"],"children":{"n":{"type":"internal","weight":619,"values":["g","c"],"children":{"g":{"type":"internal","weight":619,"values":["e"],"children":{"e":{"type":"internal","weight":619,"values":["\ufdd0","s"],"children":{"\ufdd0":{"type":"leaf","weight":619,"entries":[{"key":"change","weight":619,"content":"change"}]},"s":{"type":"leaf","weight":248,"entries":[{"key":"changes","weight":248,"content":"changes"}]}}}}},"c":{"type":"leaf","weight":245,"entries":[{"key":"chance","weight":245,"content":"chance"}]}}},"r":{"type":"internal","weight":179,"values":["g","a"],"children":{"g":{"type":"leaf","weight":179,"entries":[{"key":"charge","weight":179,"content":"charge"}]},"a":{"type":"leaf","weight":145,"entries":[{"key":"character","weight":145,"content":"character"}]}}}}},"r":{"type":"leaf","weight":327,"entries":[{"key":"christian","weight":327,"content":"christian"}]},"o":{"type":"leaf","weight":104,"entries":[{"key":"choice","weight":104,"content":"choice"}]}}},"e":{"type":"internal","weight":713,"values":["r","n"],"children":{"r":{"type":"internal","weight":713,"values":["t"],"children":{"t":{"type":"internal","weight":713,"values":["a"],"children":{"a":{"type":"internal","weight":713,"values":["i"],"children":{"i":{"type":"internal","weight":713,"values":["n"],"children":{"n":{"type":"internal","weight":713,"values":["\ufdd0","l"],"children":{"\ufdd0":{"type":"leaf","weight":713,"entries":[{"key":"certain","weight":713,"content":"certain"}]},"l":{"type":"leaf","weight":318,"entries":[{"key":"certainly","weight":318,"content":"certainly"}]}}}}}}}}}}},"n":{"type":"internal","weight":595,"values":["t"],"children":{"t":{"type":"internal","weight":595,"values":["e","u","r",null],"children":{"e":{"type":"leaf","weight":595,"entries":[{"key":"center","weight":595,"content":"center"}]},"u":{"type":"leaf","weight":557,"entries":[{"key":"century","weight":557,"content":"century"}]},"r":{"type":"leaf","weight":420,"entries":[{"key":"central","weight":420,"content":"central"}]},"undefined":{"type":"leaf","weight":379,"entries":[{"key":"cent","weight":379,"content":"cent"}]}}}}}}},"l":{"type":"internal","weight":611,"values":["o","e","a","u"],"children":{"o":{"type":"internal","weight":611,"values":["s"],"children":{"s":{"type":"internal","weight":611,"values":["e"],"children":{"e":{"type":"internal","weight":611,"values":["\ufdd0","d"],"children":{"\ufdd0":{"type":"leaf","weight":611,"entries":[{"key":"close","weight":611,"content":"close"}]},"d":{"type":"leaf","weight":37,"entries":[{"key":"closed","weight":37,"content":"closed"}]}}}}}}},"e":{"type":"internal","weight":584,"values":["a"],"children":{"a":{"type":"internal","weight":584,"values":["r"],"children":{"r":{"type":"internal","weight":584,"values":["\ufdd0","l"],"children":{"\ufdd0":{"type":"leaf","weight":584,"entries":[{"key":"clear","weight":584,"content":"clear"}]},"l":{"type":"leaf","weight":218,"entries":[{"key":"clearly","weight":218,"content":"clearly"}]}}}}}}},"a":{"type":"leaf","weight":558,"entries":[{"key":"class","weight":558,"content":"class"}]},"u":{"type":"leaf","weight":336,"entries":[{"key":"club","weight":336,"content":"club"}]}}},"u":{"type":"internal","weight":509,"values":["t","r"],"children":{"t":{"type":"leaf","weight":509,"entries":[{"key":"cut","weight":509,"content":"cut"}]},"r":{"type":"leaf","weight":15,"entries":[{"key":"current","weight":15,"content":"current"}]}}},"undefined":{"type":"leaf","weight":171,"entries":[{"key":"c","weight":171,"content":"c"}]}}},"d":{"type":"internal","weight":929,"values":["o","i","a","u","e","r"],"children":{"o":{"type":"internal","weight":929,"values":["\ufdd0","w","e","n","o","i","u"],"children":{"\ufdd0":{"type":"leaf","weight":929,"entries":[{"key":"do","weight":929,"content":"do"}]},"w":{"type":"leaf","weight":900,"entries":[{"key":"down","weight":900,"content":"down"}]},"e":{"type":"leaf","weight":825,"entries":[{"key":"does","weight":825,"content":"does"}]},"n":{"type":"leaf","weight":719,"entries":[{"key":"done","weight":719,"content":"done"}]},"o":{"type":"leaf","weight":709,"entries":[{"key":"door","weight":709,"content":"door"}]},"i":{"type":"leaf","weight":410,"entries":[{"key":"doing","weight":410,"content":"doing"}]},"u":{"type":"leaf","weight":116,"entries":[{"key":"doubt","weight":116,"content":"doubt"}]}}},"i":{"type":"internal","weight":913,"values":["d","f","r","s","v"],"children":{"d":{"type":"leaf","weight":913,"entries":[{"key":"did","weight":913,"content":"did"}]},"f":{"type":"internal","weight":712,"values":["f"],"children":{"f":{"type":"internal","weight":712,"values":["e","i"],"children":{"e":{"type":"internal","weight":712,"values":["r"],"children":{"r":{"type":"internal","weight":712,"values":["e"],"children":{"e":{"type":"internal","weight":712,"values":["n"],"children":{"n":{"type":"internal","weight":712,"values":["t","c"],"children":{"t":{"type":"leaf","weight":712,"entries":[{"key":"different","weight":712,"content":"different"}]},"c":{"type":"leaf","weight":351,"entries":[{"key":"difference","weight":351,"content":"difference"}]}}}}}}}}},"i":{"type":"leaf","weight":399,"entries":[{"key":"difficult","weight":399,"content":"difficult"}]}}}}},"r":{"type":"internal","weight":304,"values":["e"],"children":{"e":{"type":"internal","weight":304,"values":["c"],"children":{"c":{"type":"internal","weight":304,"values":["t"],"children":{"t":{"type":"internal","weight":304,"values":["l","i",null],"children":{"l":{"type":"leaf","weight":304,"entries":[{"key":"directly","weight":304,"content":"directly"}]},"i":{"type":"leaf","weight":269,"entries":[{"key":"direction","weight":269,"content":"direction"}]},"undefined":{"type":"leaf","weight":234,"entries":[{"key":"direct","weight":234,"content":"direct"}]}}}}}}}}},"s":{"type":"internal","weight":272,"values":["t"],"children":{"t":{"type":"internal","weight":272,"values":["r","a"],"children":{"r":{"type":"leaf","weight":272,"entries":[{"key":"district","weight":272,"content":"district"}]},"a":{"type":"leaf","weight":60,"entries":[{"key":"distance","weight":60,"content":"distance"}]}}}}},"v":{"type":"leaf","weight":55,"entries":[{"key":"division","weight":55,"content":"division"}]}}},"a":{"type":"internal","weight":871,"values":["y","r","t","i"],"children":{"y":{"type":"internal","weight":871,"values":["\ufdd0","s"],"children":{"\ufdd0":{"type":"leaf","weight":871,"entries":[{"key":"day","weight":871,"content":"day"}]},"s":{"type":"leaf","weight":772,"entries":[{"key":"days","weight":772,"content":"days"}]}}},"r":{"type":"leaf","weight":490,"entries":[{"key":"dark","weight":490,"content":"dark"}]},"t":{"type":"internal","weight":447,"values":["a","e"],"children":{"a":{"type":"leaf","weight":447,"entries":[{"key":"data","weight":447,"content":"data"}]},"e":{"type":"leaf","weight":7,"entries":[{"key":"date","weight":7,"content":"date"}]}}},"i":{"type":"leaf","weight":180,"entries":[{"key":"daily","weight":180,"content":"daily"}]}}},"u":{"type":"internal","weight":845,"values":["r","e"],"children":{"r":{"type":"leaf","weight":845,"entries":[{"key":"during","weight":845,"content":"during"}]},"e":{"type":"leaf","weight":312,"entries":[{"key":"due","weight":312,"content":"due"}]}}},"e":{"type":"internal","weight":733,"values":["v","a","p","f","c","g","s","t","e","m",null],"children":{"v":{"type":"internal","weight":733,"values":["e"],"children":{"e":{"type":"internal","weight":733,"values":["l"],"children":{"l":{"type":"internal","weight":733,"values":["o"],"children":{"o":{"type":"internal","weight":733,"values":["p"],"children":{"p":{"type":"internal","weight":733,"values":["m","e"],"children":{"m":{"type":"leaf","weight":733,"entries":[{"key":"development","weight":733,"content":"development"}]},"e":{"type":"leaf","weight":430,"entries":[{"key":"developed","weight":430,"content":"developed"}]}}}}}}}}}}},"a":{"type":"internal","weight":673,"values":["t","d","l"],"children":{"t":{"type":"leaf","weight":673,"entries":[{"key":"death","weight":673,"content":"death"}]},"d":{"type":"leaf","weight":458,"entries":[{"key":"dead","weight":458,"content":"dead"}]},"l":{"type":"leaf","weight":321,"entries":[{"key":"deal","weight":321,"content":"deal"}]}}},"p":{"type":"leaf","weight":596,"entries":[{"key":"department","weight":596,"content":"department"}]},"f":{"type":"leaf","weight":426,"entries":[{"key":"defense","weight":426,"content":"defense"}]},"c":{"type":"internal","weight":301,"values":["i"],"children":{"i":{"type":"internal","weight":301,"values":["d","s"],"children":{"d":{"type":"leaf","weight":301,"entries":[{"key":"decided","weight":301,"content":"decided"}]},"s":{"type":"leaf","weight":148,"entries":[{"key":"decision","weight":148,"content":"decision"}]}}}}},"g":{"type":"leaf","weight":193,"entries":[{"key":"degree","weight":193,"content":"degree"}]},"undefined":{"type":"leaf","weight":173,"entries":[{"key":"de","weight":173,"content":"de"}]},"s":{"type":"internal","weight":163,"values":["c","i","p"],"children":{"c":{"type":"leaf","weight":163,"entries":[{"key":"described","weight":163,"content":"described"}]},"i":{"type":"internal","weight":108,"values":["g"],"children":{"g":{"type":"internal","weight":108,"values":["n"],"children":{"n":{"type":"internal","weight":108,"values":["\ufdd0","e"],"children":{"\ufdd0":{"type":"leaf","weight":108,"entries":[{"key":"design","weight":108,"content":"design"}]},"e":{"type":"leaf","weight":64,"entries":[{"key":"designed","weight":64,"content":"designed"}]}}}}}}},"p":{"type":"leaf","weight":20,"entries":[{"key":"despite","weight":20,"content":"despite"}]}}},"t":{"type":"internal","weight":147,"values":["e"],"children":{"e":{"type":"internal","weight":147,"values":["r"],"children":{"r":{"type":"internal","weight":147,"values":["m"],"children":{"m":{"type":"internal","weight":147,"values":["i"],"children":{"i":{"type":"internal","weight":147,"values":["n"],"children":{"n":{"type":"internal","weight":147,"values":["e"],"children":{"e":{"type":"leaf","weight":147,"entries":[{"key":"determined","weight":147,"content":"determined"},{"key":"determine","weight":51,"content":"determine"}]}}}}}}}}}}}}},"e":{"type":"leaf","weight":72,"entries":[{"key":"deep","weight":72,"content":"deep"}]},"m":{"type":"leaf","weight":69,"entries":[{"key":"democratic","weight":69,"content":"democratic"}]}}},"r":{"type":"leaf","weight":26,"entries":[{"key":"drive","weight":26,"content":"drive"}]}}},"l":{"type":"internal","weight":923,"values":["i","o","a","e"],"children":{"i":{"type":"internal","weight":923,"values":["k","t","f","g","n","v","s","m"],"children":{"k":{"type":"internal","weight":923,"values":["e"],"children":{"e":{"type":"internal","weight":923,"values":["\ufdd0","l"],"children":{"\ufdd0":{"type":"leaf","weight":923,"entries":[{"key":"like","weight":923,"content":"like"}]},"l":{"type":"leaf","weight":362,"entries":[{"key":"likely","weight":362,"content":"likely"}]}}}}},"t":{"type":"internal","weight":891,"values":["t","e"],"children":{"t":{"type":"leaf","weight":891,"entries":[{"key":"little","weight":891,"content":"little"}]},"e":{"type":"leaf","weight":261,"entries":[{"key":"literature","weight":261,"content":"literature"}]}}},"f":{"type":"leaf","weight":875,"entries":[{"key":"life","weight":875,"content":"life"}]},"g":{"type":"leaf","weight":730,"entries":[{"key":"light","weight":730,"content":"light"}]},"n":{"type":"internal","weight":697,"values":["e"],"children":{"e":{"type":"internal","weight":697,"values":["\ufdd0","s"],"children":{"\ufdd0":{"type":"leaf","weight":697,"entries":[{"key":"line","weight":697,"content":"line"}]},"s":{"type":"leaf","weight":530,"entries":[{"key":"lines","weight":530,"content":"lines"}]}}}}},"v":{"type":"internal","weight":513,"values":["i","e"],"children":{"i":{"type":"leaf","weight":513,"entries":[{"key":"living","weight":513,"content":"living"}]},"e":{"type":"internal","weight":470,"values":["\ufdd0","d"],"children":{"\ufdd0":{"type":"leaf","weight":470,"entries":[{"key":"live","weight":470,"content":"live"}]},"d":{"type":"leaf","weight":122,"entries":[{"key":"lived","weight":122,"content":"lived"}]}}}}},"s":{"type":"leaf","weight":260,"entries":[{"key":"list","weight":260,"content":"list"}]},"m":{"type":"leaf","weight":38,"entries":[{"key":"limited","weight":38,"content":"limited"}]}}},"o":{"type":"internal","weight":880,"values":["n","o","c","v","w","s","t"],"children":{"n":{"type":"internal","weight":880,"values":["g"],"children":{"g":{"type":"internal","weight":880,"values":["\ufdd0","e"],"children":{"\ufdd0":{"type":"leaf","weight":880,"entries":[{"key":"long","weight":880,"content":"long"}]},"e":{"type":"leaf","weight":510,"entries":[{"key":"longer","weight":510,"content":"longer"}]}}}}},"o":{"type":"internal","weight":788,"values":["k"],"children":{"k":{"type":"internal","weight":788,"values":["\ufdd0","e","i"],"children":{"\ufdd0":{"type":"leaf","weight":788,"entries":[{"key":"look","weight":788,"content":"look"}]},"e":{"type":"leaf","weight":753,"entries":[{"key":"looked","weight":753,"content":"looked"}]},"i":{"type":"leaf","weight":448,"entries":[{"key":"looking","weight":448,"content":"looking"}]}}}}},"c":{"type":"leaf","weight":690,"entries":[{"key":"local","weight":690,"content":"local"}]},"v":{"type":"leaf","weight":609,"entries":[{"key":"love","weight":609,"content":"love"}]},"w":{"type":"internal","weight":451,"values":["\ufdd0","e"],"children":{"\ufdd0":{"type":"leaf","weight":451,"entries":[{"key":"low","weight":451,"content":"low"}]},"e":{"type":"leaf","weight":187,"entries":[{"key":"lower","weight":187,"content":"lower"}]}}},"s":{"type":"leaf","weight":449,"entries":[{"key":"lost","weight":449,"content":"lost"}]},"t":{"type":"leaf","weight":207,"entries":[{"key":"lot","weight":207,"content":"lot"}]}}},"a":{"type":"internal","weight":866,"values":["s","t","r","w","n","b","y","c"],"children":{"s":{"type":"leaf","weight":866,"entries":[{"key":"last","weight":866,"content":"last"}]},"t":{"type":"internal","weight":785,"values":["e","t"],"children":{"e":{"type":"leaf","weight":785,"entries":[{"key":"later","weight":785,"content":"later"},{"key":"late","weight":472,"content":"late"}]},"t":{"type":"leaf","weight":115,"entries":[{"key":"latter","weight":115,"content":"latter"}]}}},"r":{"type":"internal","weight":748,"values":["g"],"children":{"g":{"type":"internal","weight":748,"values":["e"],"children":{"e":{"type":"internal","weight":748,"values":["\ufdd0","r"],"children":{"\ufdd0":{"type":"leaf","weight":748,"entries":[{"key":"large","weight":748,"content":"large"}]},"r":{"type":"leaf","weight":182,"entries":[{"key":"larger","weight":182,"content":"larger"}]}}}}}}},"w":{"type":"leaf","weight":698,"entries":[{"key":"law","weight":698,"content":"law"}]},"n":{"type":"internal","weight":582,"values":["d","g"],"children":{"d":{"type":"leaf","weight":582,"entries":[{"key":"land","weight":582,"content":"land"}]},"g":{"type":"leaf","weight":74,"entries":[{"key":"language","weight":74,"content":"language"}]}}},"b":{"type":"leaf","weight":354,"entries":[{"key":"labor","weight":354,"content":"labor"}]},"y":{"type":"leaf","weight":289,"entries":[{"key":"lay","weight":289,"content":"lay"}]},"c":{"type":"leaf","weight":82,"entries":[{"key":"lack","weight":82,"content":"lack"}]}}},"e":{"type":"internal","weight":822,"values":["f","s","t","a","v","d","n"],"children":{"f":{"type":"leaf","weight":822,"entries":[{"key":"left","weight":822,"content":"left"}]},"s":{"type":"leaf","weight":809,"entries":[{"key":"less","weight":809,"content":"less"}]},"t":{"type":"internal","weight":774,"values":["\ufdd0","t"],"children":{"\ufdd0":{"type":"leaf","weight":774,"entries":[{"key":"let","weight":774,"content":"let"}]},"t":{"type":"internal","weight":335,"values":["e"],"children":{"e":{"type":"internal","weight":335,"values":["r"],"children":{"r":{"type":"internal","weight":335,"values":["\ufdd0","s"],"children":{"\ufdd0":{"type":"leaf","weight":335,"entries":[{"key":"letter","weight":335,"content":"letter"}]},"s":{"type":"leaf","weight":128,"entries":[{"key":"letters","weight":128,"content":"letters"}]}}}}}}}}},"a":{"type":"internal","weight":735,"values":["s","v","d","r"],"children":{"s":{"type":"leaf","weight":735,"entries":[{"key":"least","weight":735,"content":"least"}]},"v":{"type":"leaf","weight":553,"entries":[{"key":"leave","weight":553,"content":"leave"}]},"d":{"type":"internal","weight":235,"values":["\ufdd0","e"],"children":{"\ufdd0":{"type":"leaf","weight":235,"entries":[{"key":"lead","weight":235,"content":"lead"}]},"e":{"type":"leaf","weight":53,"entries":[{"key":"leaders","weight":53,"content":"leaders"}]}}},"r":{"type":"leaf","weight":136,"entries":[{"key":"learned","weight":136,"content":"learned"}]}}},"v":{"type":"leaf","weight":573,"entries":[{"key":"level","weight":573,"content":"level"}]},"d":{"type":"leaf","weight":253,"entries":[{"key":"led","weight":253,"content":"led"}]},"n":{"type":"leaf","weight":129,"entries":[{"key":"length","weight":129,"content":"length"}]}}}}},"e":{"type":"internal","weight":918,"values":["v","a","n","y","x","i","c","d","f","l","q","s","u"],"children":{"v":{"type":"internal","weight":918,"values":["e","i"],"children":{"e":{"type":"internal","weight":918,"values":["n","r"],"children":{"n":{"type":"internal","weight":918,"values":["\ufdd0","i"],"children":{"\ufdd0":{"type":"leaf","weight":918,"entries":[{"key":"even","weight":918,"content":"even"}]},"i":{"type":"leaf","weight":257,"entries":[{"key":"evening","weight":257,"content":"evening"}]}}},"r":{"type":"internal","weight":826,"values":["y","\ufdd0"],"children":{"y":{"type":"internal","weight":826,"values":["\ufdd0","t"],"children":{"\ufdd0":{"type":"leaf","weight":826,"entries":[{"key":"every","weight":826,"content":"every"}]},"t":{"type":"leaf","weight":492,"entries":[{"key":"everything","weight":492,"content":"everything"}]}}},"\ufdd0":{"type":"leaf","weight":736,"entries":[{"key":"ever","weight":736,"content":"ever"}]}}}}},"i":{"type":"leaf","weight":549,"entries":[{"key":"evidence","weight":549,"content":"evidence"}]}}},"a":{"type":"internal","weight":897,"values":["c","r","s"],"children":{"c":{"type":"leaf","weight":897,"entries":[{"key":"each","weight":897,"content":"each"}]},"r":{"type":"internal","weight":752,"values":["l","t"],"children":{"l":{"type":"internal","weight":752,"values":["y","i"],"children":{"y":{"type":"leaf","weight":752,"entries":[{"key":"early","weight":752,"content":"early"}]},"i":{"type":"leaf","weight":340,"entries":[{"key":"earlier","weight":340,"content":"earlier"}]}}},"t":{"type":"leaf","weight":359,"entries":[{"key":"earth","weight":359,"content":"earth"}]}}},"s":{"type":"internal","weight":486,"values":["t","y","i"],"children":{"t":{"type":"leaf","weight":486,"entries":[{"key":"east","weight":486,"content":"east"}]},"y":{"type":"leaf","weight":191,"entries":[{"key":"easy","weight":191,"content":"easy"}]},"i":{"type":"leaf","weight":45,"entries":[{"key":"easily","weight":45,"content":"easily"}]}}}}},"n":{"type":"internal","weight":805,"values":["o","d","g","t"],"children":{"o":{"type":"leaf","weight":805,"entries":[{"key":"enough","weight":805,"content":"enough"}]},"d":{"type":"leaf","weight":793,"entries":[{"key":"end","weight":793,"content":"end"}]},"g":{"type":"internal","weight":517,"values":["l"],"children":{"l":{"type":"internal","weight":517,"values":["i","a"],"children":{"i":{"type":"leaf","weight":517,"entries":[{"key":"english","weight":517,"content":"english"}]},"a":{"type":"leaf","weight":375,"entries":[{"key":"england","weight":375,"content":"england"}]}}}}},"t":{"type":"leaf","weight":357,"entries":[{"key":"entire","weight":357,"content":"entire"}]}}},"y":{"type":"internal","weight":790,"values":["e"],"children":{"e":{"type":"leaf","weight":790,"entries":[{"key":"eyes","weight":790,"content":"eyes"},{"key":"eye","weight":177,"content":"eye"}]}}},"x":{"type":"internal","weight":694,"values":["a","p","c","t","i"],"children":{"a":{"type":"internal","weight":694,"values":["m","c"],"children":{"m":{"type":"leaf","weight":694,"entries":[{"key":"example","weight":694,"content":"example"}]},"c":{"type":"leaf","weight":5,"entries":[{"key":"exactly","weight":5,"content":"exactly"}]}}},"p":{"type":"internal","weight":672,"values":["e"],"children":{"e":{"type":"internal","weight":672,"values":["r","c"],"children":{"r":{"type":"leaf","weight":672,"entries":[{"key":"experience","weight":672,"content":"experience"}]},"c":{"type":"internal","weight":497,"values":["t"],"children":{"t":{"type":"leaf","weight":497,"entries":[{"key":"expected","weight":497,"content":"expected"},{"key":"expect","weight":56,"content":"expect"}]}}}}}}},"c":{"type":"leaf","weight":480,"entries":[{"key":"except","weight":480,"content":"except"}]},"t":{"type":"leaf","weight":86,"entries":[{"key":"extent","weight":86,"content":"extent"}]},"i":{"type":"leaf","weight":52,"entries":[{"key":"existence","weight":52,"content":"existence"}]}}},"i":{"type":"internal","weight":684,"values":["t","g"],"children":{"t":{"type":"leaf","weight":684,"entries":[{"key":"either","weight":684,"content":"either"}]},"g":{"type":"leaf","weight":16,"entries":[{"key":"eight","weight":16,"content":"eight"}]}}},"c":{"type":"leaf","weight":624,"entries":[{"key":"economic","weight":624,"content":"economic"}]},"d":{"type":"leaf","weight":574,"entries":[{"key":"education","weight":574,"content":"education"}]},"f":{"type":"internal","weight":570,"values":["f"],"children":{"f":{"type":"internal","weight":570,"values":["e","o"],"children":{"e":{"type":"internal","weight":570,"values":["c"],"children":{"c":{"type":"internal","weight":570,"values":["t"],"children":{"t":{"type":"internal","weight":570,"values":["\ufdd0","i","s"],"children":{"\ufdd0":{"type":"leaf","weight":570,"entries":[{"key":"effect","weight":570,"content":"effect"}]},"i":{"type":"leaf","weight":226,"entries":[{"key":"effective","weight":226,"content":"effective"}]},"s":{"type":"leaf","weight":63,"entries":[{"key":"effects","weight":63,"content":"effects"}]}}}}}}},"o":{"type":"internal","weight":332,"values":["r"],"children":{"r":{"type":"internal","weight":332,"values":["t"],"children":{"t":{"type":"internal","weight":332,"values":["\ufdd0","s"],"children":{"\ufdd0":{"type":"leaf","weight":332,"entries":[{"key":"effort","weight":332,"content":"effort"}]},"s":{"type":"leaf","weight":205,"entries":[{"key":"efforts","weight":205,"content":"efforts"}]}}}}}}}}}}},"l":{"type":"internal","weight":469,"values":["s","e"],"children":{"s":{"type":"leaf","weight":469,"entries":[{"key":"else","weight":469,"content":"else"}]},"e":{"type":"leaf","weight":46,"entries":[{"key":"elements","weight":46,"content":"elements"}]}}},"q":{"type":"leaf","weight":425,"entries":[{"key":"equipment","weight":425,"content":"equipment"}]},"s":{"type":"internal","weight":403,"values":["p","t"],"children":{"p":{"type":"leaf","weight":403,"entries":[{"key":"especially","weight":403,"content":"especially"}]},"t":{"type":"leaf","weight":58,"entries":[{"key":"established","weight":58,"content":"established"}]}}},"u":{"type":"leaf","weight":141,"entries":[{"key":"europe","weight":141,"content":"europe"}]}}},"j":{"type":"internal","weight":896,"values":["u","o"],"children":{"u":{"type":"internal","weight":896,"values":["s"],"children":{"s":{"type":"internal","weight":896,"values":["t"],"children":{"t":{"type":"internal","weight":896,"values":["\ufdd0","i"],"children":{"\ufdd0":{"type":"leaf","weight":896,"entries":[{"key":"just","weight":896,"content":"just"}]},"i":{"type":"leaf","weight":117,"entries":[{"key":"justice","weight":117,"content":"justice"}]}}}}}}},"o":{"type":"internal","weight":749,"values":["h","b"],"children":{"h":{"type":"leaf","weight":749,"entries":[{"key":"john","weight":749,"content":"john"}]},"b":{"type":"leaf","weight":616,"entries":[{"key":"job","weight":616,"content":"job"}]}}}}},"p":{"type":"internal","weight":894,"values":["e","l","a","u","o","r","i","h"],"children":{"e":{"type":"internal","weight":894,"values":["o","r","a"],"children":{"o":{"type":"leaf","weight":894,"entries":[{"key":"people","weight":894,"content":"people"}]},"r":{"type":"internal","weight":759,"values":["\ufdd0","h","i","s","f"],"children":{"\ufdd0":{"type":"leaf","weight":759,"entries":[{"key":"per","weight":759,"content":"per"}]},"h":{"type":"leaf","weight":703,"entries":[{"key":"perhaps","weight":703,"content":"perhaps"}]},"i":{"type":"leaf","weight":655,"entries":[{"key":"period","weight":655,"content":"period"}]},"s":{"type":"internal","weight":524,"values":["o"],"children":{"o":{"type":"internal","weight":524,"values":["n"],"children":{"n":{"type":"internal","weight":524,"values":["a","\ufdd0","s"],"children":{"a":{"type":"leaf","weight":524,"entries":[{"key":"personal","weight":524,"content":"personal"}]},"\ufdd0":{"type":"leaf","weight":455,"entries":[{"key":"person","weight":455,"content":"person"}]},"s":{"type":"leaf","weight":172,"entries":[{"key":"persons","weight":172,"content":"persons"}]}}}}}}},"f":{"type":"leaf","weight":175,"entries":[{"key":"performance","weight":175,"content":"performance"}]}}},"a":{"type":"leaf","weight":531,"entries":[{"key":"peace","weight":531,"content":"peace"}]}}},"l":{"type":"internal","weight":842,"values":["a"],"children":{"a":{"type":"internal","weight":842,"values":["c","n","y"],"children":{"c":{"type":"internal","weight":842,"values":["e"],"children":{"e":{"type":"internal","weight":842,"values":["\ufdd0","d"],"children":{"\ufdd0":{"type":"leaf","weight":842,"entries":[{"key":"place","weight":842,"content":"place"}]},"d":{"type":"leaf","weight":202,"entries":[{"key":"placed","weight":202,"content":"placed"}]}}}}},"n":{"type":"internal","weight":551,"values":["\ufdd0","n","t","e","s"],"children":{"\ufdd0":{"type":"leaf","weight":551,"entries":[{"key":"plan","weight":551,"content":"plan"}]},"n":{"type":"leaf","weight":232,"entries":[{"key":"planning","weight":232,"content":"planning"}]},"t":{"type":"leaf","weight":197,"entries":[{"key":"plant","weight":197,"content":"plant"}]},"e":{"type":"leaf","weight":113,"entries":[{"key":"plane","weight":113,"content":"plane"}]},"s":{"type":"leaf","weight":94,"entries":[{"key":"plans","weight":94,"content":"plans"}]}}},"y":{"type":"internal","weight":537,"values":["\ufdd0","e"],"children":{"\ufdd0":{"type":"leaf","weight":537,"entries":[{"key":"play","weight":537,"content":"play"}]},"e":{"type":"leaf","weight":14,"entries":[{"key":"played","weight":14,"content":"played"}]}}}}}}},"a":{"type":"internal","weight":832,"values":["r","s","y","p","i","t"],"children":{"r":{"type":"internal","weight":832,"values":["t"],"children":{"t":{"type":"internal","weight":832,"values":["\ufdd0","y","i","s"],"children":{"\ufdd0":{"type":"leaf","weight":832,"entries":[{"key":"part","weight":832,"content":"part"}]},"y":{"type":"leaf","weight":577,"entries":[{"key":"party","weight":577,"content":"party"}]},"i":{"type":"internal","weight":474,"values":["c"],"children":{"c":{"type":"internal","weight":474,"values":["u"],"children":{"u":{"type":"internal","weight":474,"values":["l"],"children":{"l":{"type":"internal","weight":474,"values":["a"],"children":{"a":{"type":"internal","weight":474,"values":["r"],"children":{"r":{"type":"internal","weight":474,"values":["\ufdd0","l"],"children":{"\ufdd0":{"type":"leaf","weight":474,"entries":[{"key":"particular","weight":474,"content":"particular"}]},"l":{"type":"leaf","weight":338,"entries":[{"key":"particularly","weight":338,"content":"particularly"}]}}}}}}}}}}}}},"s":{"type":"leaf","weight":98,"entries":[{"key":"parts","weight":98,"content":"parts"}]}}}}},"s":{"type":"internal","weight":677,"values":["t","s"],"children":{"t":{"type":"leaf","weight":677,"entries":[{"key":"past","weight":677,"content":"past"}]},"s":{"type":"leaf","weight":389,"entries":[{"key":"passed","weight":389,"content":"passed"}]}}},"y":{"type":"leaf","weight":441,"entries":[{"key":"pay","weight":441,"content":"pay"}]},"p":{"type":"leaf","weight":387,"entries":[{"key":"paper","weight":387,"content":"paper"}]},"i":{"type":"leaf","weight":329,"entries":[{"key":"paid","weight":329,"content":"paid"}]},"t":{"type":"leaf","weight":101,"entries":[{"key":"pattern","weight":101,"content":"pattern"}]}}},"u":{"type":"internal","weight":811,"values":["b","t","r"],"children":{"b":{"type":"leaf","weight":811,"entries":[{"key":"public","weight":811,"content":"public"}]},"t":{"type":"leaf","weight":810,"entries":[{"key":"put","weight":810,"content":"put"}]},"r":{"type":"leaf","weight":355,"entries":[{"key":"purpose","weight":355,"content":"purpose"}]}}},"o":{"type":"internal","weight":784,"values":["i","s","w","l","p","o"],"children":{"i":{"type":"internal","weight":784,"values":["n"],"children":{"n":{"type":"internal","weight":784,"values":["t"],"children":{"t":{"type":"internal","weight":784,"values":["\ufdd0","s"],"children":{"\ufdd0":{"type":"leaf","weight":784,"entries":[{"key":"point","weight":784,"content":"point"}]},"s":{"type":"leaf","weight":325,"entries":[{"key":"points","weight":325,"content":"points"}]}}}}}}},"s":{"type":"internal","weight":763,"values":["s","i"],"children":{"s":{"type":"leaf","weight":763,"entries":[{"key":"possible","weight":763,"content":"possible"}]},"i":{"type":"leaf","weight":621,"entries":[{"key":"position","weight":621,"content":"position"}]}}},"w":{"type":"leaf","weight":734,"entries":[{"key":"power","weight":734,"content":"power"}]},"l":{"type":"internal","weight":645,"values":["i"],"children":{"i":{"type":"internal","weight":645,"values":["t","c"],"children":{"t":{"type":"leaf","weight":645,"entries":[{"key":"political","weight":645,"content":"political"}]},"c":{"type":"internal","weight":590,"values":["y","e"],"children":{"y":{"type":"leaf","weight":590,"entries":[{"key":"policy","weight":590,"content":"policy"}]},"e":{"type":"leaf","weight":381,"entries":[{"key":"police","weight":381,"content":"police"}]}}}}}}},"p":{"type":"leaf","weight":276,"entries":[{"key":"population","weight":276,"content":"population"}]},"o":{"type":"internal","weight":95,"values":["r","l"],"children":{"r":{"type":"leaf","weight":95,"entries":[{"key":"poor","weight":95,"content":"poor"}]},"l":{"type":"leaf","weight":87,"entries":[{"key":"pool","weight":87,"content":"pool"}]}}}}},"r":{"type":"internal","weight":781,"values":["o","e","i"],"children":{"o":{"type":"internal","weight":781,"values":["g","b","v","c","p","d","f"],"children":{"g":{"type":"internal","weight":781,"values":["r"],"children":{"r":{"type":"internal","weight":781,"values":["a","e"],"children":{"a":{"type":"internal","weight":781,"values":["m"],"children":{"m":{"type":"internal","weight":781,"values":["\ufdd0","s"],"children":{"\ufdd0":{"type":"leaf","weight":781,"entries":[{"key":"program","weight":781,"content":"program"}]},"s":{"type":"leaf","weight":292,"entries":[{"key":"programs","weight":292,"content":"programs"}]}}}}},"e":{"type":"leaf","weight":165,"entries":[{"key":"progress","weight":165,"content":"progress"}]}}}}},"b":{"type":"internal","weight":715,"values":["l","a"],"children":{"l":{"type":"internal","weight":715,"values":["e"],"children":{"e":{"type":"internal","weight":715,"values":["m"],"children":{"m":{"type":"internal","weight":715,"values":["\ufdd0","s"],"children":{"\ufdd0":{"type":"leaf","weight":715,"entries":[{"key":"problem","weight":715,"content":"problem"}]},"s":{"type":"leaf","weight":636,"entries":[{"key":"problems","weight":636,"content":"problems"}]}}}}}}},"a":{"type":"leaf","weight":651,"entries":[{"key":"probably","weight":651,"content":"probably"}]}}},"v":{"type":"internal","weight":576,"values":["i"],"children":{"i":{"type":"internal","weight":576,"values":["d"],"children":{"d":{"type":"internal","weight":576,"values":["e"],"children":{"e":{"type":"internal","weight":576,"values":["\ufdd0","d"],"children":{"\ufdd0":{"type":"leaf","weight":576,"entries":[{"key":"provide","weight":576,"content":"provide"}]},"d":{"type":"leaf","weight":252,"entries":[{"key":"provided","weight":252,"content":"provided"}]}}}}}}}}},"c":{"type":"leaf","weight":522,"entries":[{"key":"process","weight":522,"content":"process"}]},"p":{"type":"leaf","weight":383,"entries":[{"key":"property","weight":383,"content":"property"}]},"d":{"type":"internal","weight":346,"values":["u"],"children":{"u":{"type":"internal","weight":346,"values":["c"],"children":{"c":{"type":"internal","weight":346,"values":["t"],"children":{"t":{"type":"internal","weight":346,"values":["i","s"],"children":{"i":{"type":"leaf","weight":346,"entries":[{"key":"production","weight":346,"content":"production"}]},"s":{"type":"leaf","weight":57,"entries":[{"key":"products","weight":57,"content":"products"}]}}}}}}}}},"f":{"type":"leaf","weight":29,"entries":[{"key":"professional","weight":29,"content":"professional"}]}}},"e":{"type":"internal","weight":771,"values":["s","t"],"children":{"s":{"type":"internal","weight":771,"values":["i","e","s"],"children":{"i":{"type":"leaf","weight":771,"entries":[{"key":"president","weight":771,"content":"president"}]},"e":{"type":"leaf","weight":767,"entries":[{"key":"present","weight":767,"content":"present"}]},"s":{"type":"leaf","weight":491,"entries":[{"key":"pressure","weight":491,"content":"pressure"},{"key":"press","weight":208,"content":"press"}]}}},"t":{"type":"leaf","weight":47,"entries":[{"key":"pretty","weight":47,"content":"pretty"}]}}},"i":{"type":"internal","weight":507,"values":["v","n","c"],"children":{"v":{"type":"leaf","weight":507,"entries":[{"key":"private","weight":507,"content":"private"}]},"n":{"type":"leaf","weight":70,"entries":[{"key":"principle","weight":70,"content":"principle"}]},"c":{"type":"leaf","weight":62,"entries":[{"key":"price","weight":62,"content":"price"}]}}}}},"i":{"type":"internal","weight":404,"values":["c","e"],"children":{"c":{"type":"leaf","weight":404,"entries":[{"key":"picture","weight":404,"content":"picture"}]},"e":{"type":"leaf","weight":228,"entries":[{"key":"piece","weight":228,"content":"piece"}]}}},"h":{"type":"leaf","weight":286,"entries":[{"key":"physical","weight":286,"content":"physical"}]}}},"g":{"type":"internal","weight":889,"values":["o","e","r","i","a","u"],"children":{"o":{"type":"internal","weight":889,"values":["o","\ufdd0","t","v","i","d","n"],"children":{"o":{"type":"leaf","weight":889,"entries":[{"key":"good","weight":889,"content":"good"}]},"\ufdd0":{"type":"leaf","weight":856,"entries":[{"key":"go","weight":856,"content":"go"}]},"t":{"type":"leaf","weight":824,"entries":[{"key":"got","weight":824,"content":"got"}]},"v":{"type":"leaf","weight":800,"entries":[{"key":"government","weight":800,"content":"government"}]},"i":{"type":"leaf","weight":787,"entries":[{"key":"going","weight":787,"content":"going"}]},"d":{"type":"leaf","weight":717,"entries":[{"key":"god","weight":717,"content":"god"}]},"n":{"type":"leaf","weight":515,"entries":[{"key":"gone","weight":515,"content":"gone"}]}}},"e":{"type":"internal","weight":878,"values":["t","n","o"],"children":{"t":{"type":"internal","weight":878,"values":["\ufdd0","t"],"children":{"\ufdd0":{"type":"leaf","weight":878,"entries":[{"key":"get","weight":878,"content":"get"}]},"t":{"type":"leaf","weight":417,"entries":[{"key":"getting","weight":417,"content":"getting"}]}}},"n":{"type":"internal","weight":830,"values":["e"],"children":{"e":{"type":"internal","weight":830,"values":["r"],"children":{"r":{"type":"internal","weight":830,"values":["a"],"children":{"a":{"type":"internal","weight":830,"values":["l"],"children":{"l":{"type":"internal","weight":830,"values":["\ufdd0","l"],"children":{"\ufdd0":{"type":"leaf","weight":830,"entries":[{"key":"general","weight":830,"content":"general"}]},"l":{"type":"leaf","weight":255,"entries":[{"key":"generally","weight":255,"content":"generally"}]}}}}}}}}}}},"o":{"type":"leaf","weight":225,"entries":[{"key":"george","weight":225,"content":"george"}]}}},"r":{"type":"internal","weight":863,"values":["e","o"],"children":{"e":{"type":"internal","weight":863,"values":["a","e"],"children":{"a":{"type":"internal","weight":863,"values":["t"],"children":{"t":{"type":"internal","weight":863,"values":["\ufdd0","e"],"children":{"\ufdd0":{"type":"leaf","weight":863,"entries":[{"key":"great","weight":863,"content":"great"}]},"e":{"type":"leaf","weight":501,"entries":[{"key":"greater","weight":501,"content":"greater"}]}}}}},"e":{"type":"leaf","weight":130,"entries":[{"key":"green","weight":130,"content":"green"}]}}},"o":{"type":"internal","weight":778,"values":["u","w"],"children":{"u":{"type":"internal","weight":778,"values":["p","n"],"children":{"p":{"type":"internal","weight":778,"values":["\ufdd0","s"],"children":{"\ufdd0":{"type":"leaf","weight":778,"entries":[{"key":"group","weight":778,"content":"group"}]},"s":{"type":"leaf","weight":194,"entries":[{"key":"groups","weight":194,"content":"groups"}]}}},"n":{"type":"leaf","weight":493,"entries":[{"key":"ground","weight":493,"content":"ground"}]}}},"w":{"type":"internal","weight":376,"values":["t","i"],"children":{"t":{"type":"leaf","weight":376,"entries":[{"key":"growth","weight":376,"content":"growth"}]},"i":{"type":"leaf","weight":66,"entries":[{"key":"growing","weight":66,"content":"growing"}]}}}}}}},"i":{"type":"internal","weight":777,"values":["v","r"],"children":{"v":{"type":"internal","weight":777,"values":["e"],"children":{"e":{"type":"internal","weight":777,"values":["\ufdd0","n","s"],"children":{"\ufdd0":{"type":"leaf","weight":777,"entries":[{"key":"give","weight":777,"content":"give"}]},"n":{"type":"leaf","weight":768,"entries":[{"key":"given","weight":768,"content":"given"}]},"s":{"type":"leaf","weight":112,"entries":[{"key":"gives","weight":112,"content":"gives"}]}}}}},"r":{"type":"internal","weight":586,"values":["l"],"children":{"l":{"type":"internal","weight":586,"values":["\ufdd0","s"],"children":{"\ufdd0":{"type":"leaf","weight":586,"entries":[{"key":"girl","weight":586,"content":"girl"}]},"s":{"type":"leaf","weight":310,"entries":[{"key":"girls","weight":310,"content":"girls"}]}}}}}}},"a":{"type":"internal","weight":685,"values":["v","m"],"children":{"v":{"type":"leaf","weight":685,"entries":[{"key":"gave","weight":685,"content":"gave"}]},"m":{"type":"leaf","weight":183,"entries":[{"key":"game","weight":183,"content":"game"}]}}},"u":{"type":"leaf","weight":140,"entries":[{"key":"gun","weight":140,"content":"gun"}]}}},"v":{"type":"internal","weight":888,"values":["e","o","a","i"],"children":{"e":{"type":"leaf","weight":888,"entries":[{"key":"very","weight":888,"content":"very"}]},"o":{"type":"internal","weight":597,"values":["i","l"],"children":{"i":{"type":"leaf","weight":597,"entries":[{"key":"voice","weight":597,"content":"voice"}]},"l":{"type":"leaf","weight":271,"entries":[{"key":"volume","weight":271,"content":"volume"}]}}},"a":{"type":"internal","weight":543,"values":["r","l"],"children":{"r":{"type":"leaf","weight":543,"entries":[{"key":"various","weight":543,"content":"various"}]},"l":{"type":"internal","weight":539,"values":["u"],"children":{"u":{"type":"internal","weight":539,"values":["e"],"children":{"e":{"type":"internal","weight":539,"values":["\ufdd0","s"],"children":{"\ufdd0":{"type":"leaf","weight":539,"entries":[{"key":"value","weight":539,"content":"value"}]},"s":{"type":"leaf","weight":495,"entries":[{"key":"values","weight":495,"content":"values"}]}}}}}}}}},"i":{"type":"internal","weight":496,"values":["e","s"],"children":{"e":{"type":"leaf","weight":496,"entries":[{"key":"view","weight":496,"content":"view"}]},"s":{"type":"leaf","weight":75,"entries":[{"key":"visit","weight":75,"content":"visit"}]}}}}},"k":{"type":"internal","weight":868,"values":["n","i","e"],"children":{"n":{"type":"internal","weight":868,"values":["o","e"],"children":{"o":{"type":"internal","weight":868,"values":["w"],"children":{"w":{"type":"internal","weight":868,"values":["\ufdd0","n","l"],"children":{"\ufdd0":{"type":"leaf","weight":868,"entries":[{"key":"know","weight":868,"content":"know"}]},"n":{"type":"leaf","weight":628,"entries":[{"key":"known","weight":628,"content":"known"}]},"l":{"type":"leaf","weight":334,"entries":[{"key":"knowledge","weight":334,"content":"knowledge"}]}}}}},"e":{"type":"leaf","weight":783,"entries":[{"key":"knew","weight":783,"content":"knew"}]}}},"i":{"type":"leaf","weight":714,"entries":[{"key":"kind","weight":714,"content":"kind"}]},"e":{"type":"internal","weight":654,"values":["e","p","n"],"children":{"e":{"type":"leaf","weight":654,"entries":[{"key":"keep","weight":654,"content":"keep"}]},"p":{"type":"leaf","weight":494,"entries":[{"key":"kept","weight":494,"content":"kept"}]},"n":{"type":"leaf","weight":293,"entries":[{"key":"kennedy","weight":293,"content":"kennedy"}]}}}}},"r":{"type":"internal","weight":854,"values":["i","o","a","e","u","h"],"children":{"i":{"type":"internal","weight":854,"values":["g","v"],"children":{"g":{"type":"leaf","weight":854,"entries":[{"key":"right","weight":854,"content":"right"}]},"v":{"type":"leaf","weight":418,"entries":[{"key":"river","weight":418,"content":"river"}]}}},"o":{"type":"internal","weight":773,"values":["o","a","l"],"children":{"o":{"type":"leaf","weight":773,"entries":[{"key":"room","weight":773,"content":"room"}]},"a":{"type":"leaf","weight":527,"entries":[{"key":"road","weight":527,"content":"road"}]},"l":{"type":"leaf","weight":18,"entries":[{"key":"role","weight":18,"content":"role"}]}}},"a":{"type":"internal","weight":762,"values":["t","n","d","c"],"children":{"t":{"type":"internal","weight":762,"values":["h","e"],"children":{"h":{"type":"leaf","weight":762,"entries":[{"key":"rather","weight":762,"content":"rather"}]},"e":{"type":"leaf","weight":561,"entries":[{"key":"rate","weight":561,"content":"rate"}]}}},"n":{"type":"leaf","weight":386,"entries":[{"key":"range","weight":386,"content":"range"},{"key":"ran","weight":264,"content":"ran"}]},"d":{"type":"leaf","weight":159,"entries":[{"key":"radio","weight":159,"content":"radio"}]},"c":{"type":"leaf","weight":2,"entries":[{"key":"race","weight":2,"content":"race"}]}}},"e":{"type":"internal","weight":670,"values":["a","s","d","q","t","c","p","l","m"],"children":{"a":{"type":"internal","weight":670,"values":["l","s","d","c"],"children":{"l":{"type":"leaf","weight":670,"entries":[{"key":"really","weight":670,"content":"really"},{"key":"real","weight":647,"content":"real"}]},"s":{"type":"internal","weight":622,"values":["o"],"children":{"o":{"type":"internal","weight":622,"values":["n"],"children":{"n":{"type":"internal","weight":622,"values":["\ufdd0","s"],"children":{"\ufdd0":{"type":"leaf","weight":622,"entries":[{"key":"reason","weight":622,"content":"reason"}]},"s":{"type":"leaf","weight":12,"entries":[{"key":"reasons","weight":12,"content":"reasons"}]}}}}}}},"d":{"type":"internal","weight":457,"values":["\ufdd0","y","i"],"children":{"\ufdd0":{"type":"leaf","weight":457,"entries":[{"key":"read","weight":457,"content":"read"}]},"y":{"type":"leaf","weight":320,"entries":[{"key":"ready","weight":320,"content":"ready"}]},"i":{"type":"leaf","weight":300,"entries":[{"key":"reading","weight":300,"content":"reading"}]}}},"c":{"type":"internal","weight":429,"values":["h","t"],"children":{"h":{"type":"leaf","weight":429,"entries":[{"key":"reached","weight":429,"content":"reached"},{"key":"reach","weight":27,"content":"reach"}]},"t":{"type":"leaf","weight":189,"entries":[{"key":"reaction","weight":189,"content":"reaction"}]}}}}},"s":{"type":"internal","weight":625,"values":["u","e","t","p"],"children":{"u":{"type":"internal","weight":625,"values":["l"],"children":{"l":{"type":"internal","weight":625,"values":["t"],"children":{"t":{"type":"internal","weight":625,"values":["\ufdd0","s"],"children":{"\ufdd0":{"type":"leaf","weight":625,"entries":[{"key":"result","weight":625,"content":"result"}]},"s":{"type":"leaf","weight":352,"entries":[{"key":"results","weight":352,"content":"results"}]}}}}}}},"e":{"type":"leaf","weight":433,"entries":[{"key":"research","weight":433,"content":"research"}]},"t":{"type":"leaf","weight":412,"entries":[{"key":"rest","weight":412,"content":"rest"}]},"p":{"type":"internal","weight":198,"values":["e","o"],"children":{"e":{"type":"leaf","weight":198,"entries":[{"key":"respect","weight":198,"content":"respect"}]},"o":{"type":"leaf","weight":146,"entries":[{"key":"responsibility","weight":146,"content":"responsibility"}]}}}}},"d":{"type":"leaf","weight":526,"entries":[{"key":"red","weight":526,"content":"red"}]},"q":{"type":"leaf","weight":484,"entries":[{"key":"required","weight":484,"content":"required"}]},"t":{"type":"internal","weight":477,"values":["u"],"children":{"u":{"type":"internal","weight":477,"values":["r"],"children":{"r":{"type":"internal","weight":477,"values":["n"],"children":{"n":{"type":"internal","weight":477,"values":["\ufdd0","e"],"children":{"\ufdd0":{"type":"leaf","weight":477,"entries":[{"key":"return","weight":477,"content":"return"}]},"e":{"type":"leaf","weight":123,"entries":[{"key":"returned","weight":123,"content":"returned"}]}}}}}}}}},"c":{"type":"internal","weight":475,"values":["e","o"],"children":{"e":{"type":"internal","weight":475,"values":["n","i"],"children":{"n":{"type":"internal","weight":475,"values":["t"],"children":{"t":{"type":"internal","weight":475,"values":["\ufdd0","l"],"children":{"\ufdd0":{"type":"leaf","weight":475,"entries":[{"key":"recent","weight":475,"content":"recent"}]},"l":{"type":"leaf","weight":186,"entries":[{"key":"recently","weight":186,"content":"recently"}]}}}}},"i":{"type":"leaf","weight":413,"entries":[{"key":"received","weight":413,"content":"received"}]}}},"o":{"type":"leaf","weight":280,"entries":[{"key":"record","weight":280,"content":"record"}]}}},"p":{"type":"internal","weight":460,"values":["o"],"children":{"o":{"type":"internal","weight":460,"values":["r"],"children":{"r":{"type":"internal","weight":460,"values":["t"],"children":{"t":{"type":"internal","weight":460,"values":["\ufdd0","e"],"children":{"\ufdd0":{"type":"leaf","weight":460,"entries":[{"key":"report","weight":460,"content":"report"}]},"e":{"type":"leaf","weight":156,"entries":[{"key":"reported","weight":156,"content":"reported"}]}}}}}}}}},"l":{"type":"internal","weight":419,"values":["i"],"children":{"i":{"type":"internal","weight":419,"values":["g"],"children":{"g":{"type":"internal","weight":419,"values":["i"],"children":{"i":{"type":"internal","weight":419,"values":["o"],"children":{"o":{"type":"internal","weight":419,"values":["u","n"],"children":{"u":{"type":"leaf","weight":419,"entries":[{"key":"religious","weight":419,"content":"religious"}]},"n":{"type":"leaf","weight":158,"entries":[{"key":"religion","weight":158,"content":"religion"}]}}}}}}}}}}},"m":{"type":"internal","weight":287,"values":["e","a"],"children":{"e":{"type":"leaf","weight":287,"entries":[{"key":"remember","weight":287,"content":"remember"}]},"a":{"type":"leaf","weight":42,"entries":[{"key":"remained","weight":42,"content":"remained"}]}}}}},"u":{"type":"internal","weight":572,"values":["n"],"children":{"n":{"type":"internal","weight":572,"values":["\ufdd0","n"],"children":{"\ufdd0":{"type":"leaf","weight":572,"entries":[{"key":"run","weight":572,"content":"run"}]},"n":{"type":"leaf","weight":181,"entries":[{"key":"running","weight":181,"content":"running"}]}}}}},"h":{"type":"leaf","weight":22,"entries":[{"key":"rhode","weight":22,"content":"rhode"}]}}},"q":{"type":"internal","weight":679,"values":["u"],"children":{"u":{"type":"internal","weight":679,"values":["i","e","a"],"children":{"i":{"type":"leaf","weight":679,"entries":[{"key":"quite","weight":679,"content":"quite"}]},"e":{"type":"internal","weight":644,"values":["s"],"children":{"s":{"type":"internal","weight":644,"values":["t"],"children":{"t":{"type":"internal","weight":644,"values":["i"],"children":{"i":{"type":"internal","weight":644,"values":["o"],"children":{"o":{"type":"internal","weight":644,"values":["n"],"children":{"n":{"type":"internal","weight":644,"values":["\ufdd0","s"],"children":{"\ufdd0":{"type":"leaf","weight":644,"entries":[{"key":"question","weight":644,"content":"question"}]},"s":{"type":"leaf","weight":297,"entries":[{"key":"questions","weight":297,"content":"questions"}]}}}}}}}}}}}}},"a":{"type":"leaf","weight":107,"entries":[{"key":"quality","weight":107,"content":"quality"}]}}}}}}} + "root": {"type":"internal","weight":1000,"values":["t","o","a","i","w","h","f","b","n","y","s","m","u","c","d","l","e","j","p","g","v","k","r","q"],"children":{"t":{"type":"internal","weight":1000,"values":["h","o","i","w","a","u","e","r","y"],"children":{"h":{"type":"internal","weight":1000,"values":["e","a","i","r","o","u"],"children":{"e":{"type":"internal","weight":1000,"values":["\ufdd0","y","r","i","m","s","n","o"],"children":{"\ufdd0":{"type":"leaf","weight":1000,"entries":[{"key":"the","weight":1000,"content":"the"}]},"y":{"type":"leaf","weight":971,"entries":[{"key":"they","weight":971,"content":"they"}]},"r":{"type":"internal","weight":963,"values":["e"],"children":{"e":{"type":"internal","weight":963,"values":["\ufdd0","f"],"children":{"\ufdd0":{"type":"leaf","weight":963,"entries":[{"key":"there","weight":963,"content":"there"}]},"f":{"type":"leaf","weight":552,"entries":[{"key":"therefore","weight":552,"content":"therefore"}]}}}}},"i":{"type":"leaf","weight":961,"entries":[{"key":"their","weight":961,"content":"their"}]},"m":{"type":"internal","weight":941,"values":["\ufdd0","s"],"children":{"\ufdd0":{"type":"leaf","weight":941,"entries":[{"key":"them","weight":941,"content":"them"}]},"s":{"type":"leaf","weight":662,"entries":[{"key":"themselves","weight":662,"content":"themselves"}]}}},"s":{"type":"leaf","weight":933,"entries":[{"key":"these","weight":933,"content":"these"}]},"n":{"type":"leaf","weight":930,"entries":[{"key":"then","weight":930,"content":"then"}]},"o":{"type":"leaf","weight":229,"entries":[{"key":"theory","weight":229,"content":"theory"}]}}},"a":{"type":"internal","weight":994,"values":["t","n"],"children":{"t":{"type":"leaf","weight":994,"entries":[{"key":"that","weight":994,"content":"that"}]},"n":{"type":"leaf","weight":942,"entries":[{"key":"than","weight":942,"content":"than"}]}}},"i":{"type":"internal","weight":980,"values":["s","n","r"],"children":{"s":{"type":"leaf","weight":980,"entries":[{"key":"this","weight":980,"content":"this"}]},"n":{"type":"internal","weight":808,"values":["k","g"],"children":{"k":{"type":"internal","weight":808,"values":["\ufdd0","i"],"children":{"\ufdd0":{"type":"leaf","weight":808,"entries":[{"key":"think","weight":808,"content":"think"}]},"i":{"type":"leaf","weight":337,"entries":[{"key":"thinking","weight":337,"content":"thinking"}]}}},"g":{"type":"leaf","weight":754,"entries":[{"key":"things","weight":754,"content":"things"},{"key":"thing","weight":732,"content":"thing"}]}}},"r":{"type":"leaf","weight":504,"entries":[{"key":"third","weight":504,"content":"third"}]}}},"r":{"type":"internal","weight":908,"values":["o","e"],"children":{"o":{"type":"internal","weight":908,"values":["u"],"children":{"u":{"type":"internal","weight":908,"values":["g"],"children":{"g":{"type":"internal","weight":908,"values":["h"],"children":{"h":{"type":"internal","weight":908,"values":["\ufdd0","o"],"children":{"\ufdd0":{"type":"leaf","weight":908,"entries":[{"key":"through","weight":908,"content":"through"}]},"o":{"type":"leaf","weight":305,"entries":[{"key":"throughout","weight":305,"content":"throughout"}]}}}}}}}}},"e":{"type":"leaf","weight":852,"entries":[{"key":"three","weight":852,"content":"three"}]}}},"o":{"type":"internal","weight":895,"values":["s","u"],"children":{"s":{"type":"leaf","weight":895,"entries":[{"key":"those","weight":895,"content":"those"}]},"u":{"type":"internal","weight":835,"values":["g"],"children":{"g":{"type":"internal","weight":835,"values":["h"],"children":{"h":{"type":"leaf","weight":835,"entries":[{"key":"thought","weight":835,"content":"thought"},{"key":"though","weight":812,"content":"though"}]}}}}}}},"u":{"type":"leaf","weight":711,"entries":[{"key":"thus","weight":711,"content":"thus"}]}}},"o":{"type":"internal","weight":997,"values":["\ufdd0","o","l","w","d","g","t","p"],"children":{"\ufdd0":{"type":"leaf","weight":997,"entries":[{"key":"to","weight":997,"content":"to"}]},"o":{"type":"internal","weight":893,"values":["\ufdd0","k"],"children":{"\ufdd0":{"type":"leaf","weight":893,"entries":[{"key":"too","weight":893,"content":"too"}]},"k":{"type":"leaf","weight":804,"entries":[{"key":"took","weight":804,"content":"took"}]}}},"l":{"type":"leaf","weight":796,"entries":[{"key":"told","weight":796,"content":"told"}]},"w":{"type":"internal","weight":776,"values":["a","n"],"children":{"a":{"type":"leaf","weight":776,"entries":[{"key":"toward","weight":776,"content":"toward"}]},"n":{"type":"leaf","weight":567,"entries":[{"key":"town","weight":567,"content":"town"}]}}},"d":{"type":"leaf","weight":683,"entries":[{"key":"today","weight":683,"content":"today"}]},"g":{"type":"leaf","weight":658,"entries":[{"key":"together","weight":658,"content":"together"}]},"t":{"type":"leaf","weight":564,"entries":[{"key":"total","weight":564,"content":"total"}]},"p":{"type":"leaf","weight":550,"entries":[{"key":"top","weight":550,"content":"top"}]}}},"i":{"type":"internal","weight":934,"values":["m"],"children":{"m":{"type":"internal","weight":934,"values":["e"],"children":{"e":{"type":"internal","weight":934,"values":["\ufdd0","s"],"children":{"\ufdd0":{"type":"leaf","weight":934,"entries":[{"key":"time","weight":934,"content":"time"}]},"s":{"type":"leaf","weight":700,"entries":[{"key":"times","weight":700,"content":"times"}]}}}}}}},"w":{"type":"leaf","weight":932,"entries":[{"key":"two","weight":932,"content":"two"}]},"a":{"type":"internal","weight":851,"values":["k","x","b","l"],"children":{"k":{"type":"internal","weight":851,"values":["e","i"],"children":{"e":{"type":"internal","weight":851,"values":["\ufdd0","n"],"children":{"\ufdd0":{"type":"leaf","weight":851,"entries":[{"key":"take","weight":851,"content":"take"}]},"n":{"type":"leaf","weight":678,"entries":[{"key":"taken","weight":678,"content":"taken"}]}}},"i":{"type":"leaf","weight":464,"entries":[{"key":"taking","weight":464,"content":"taking"}]}}},"x":{"type":"leaf","weight":542,"entries":[{"key":"tax","weight":542,"content":"tax"}]},"b":{"type":"leaf","weight":529,"entries":[{"key":"table","weight":529,"content":"table"}]},"l":{"type":"leaf","weight":374,"entries":[{"key":"talk","weight":374,"content":"talk"}]}}},"u":{"type":"internal","weight":720,"values":["r"],"children":{"r":{"type":"internal","weight":720,"values":["n"],"children":{"n":{"type":"leaf","weight":720,"entries":[{"key":"turned","weight":720,"content":"turned"},{"key":"turn","weight":610,"content":"turn"}]}}}}},"e":{"type":"internal","weight":660,"values":["l","n","r","m","c","s"],"children":{"l":{"type":"leaf","weight":660,"entries":[{"key":"tell","weight":660,"content":"tell"}]},"n":{"type":"leaf","weight":415,"entries":[{"key":"ten","weight":415,"content":"ten"}]},"r":{"type":"leaf","weight":411,"entries":[{"key":"terms","weight":411,"content":"terms"}]},"m":{"type":"leaf","weight":270,"entries":[{"key":"temperature","weight":270,"content":"temperature"}]},"c":{"type":"leaf","weight":162,"entries":[{"key":"technical","weight":162,"content":"technical"}]},"s":{"type":"leaf","weight":157,"entries":[{"key":"test","weight":157,"content":"test"}]}}},"r":{"type":"internal","weight":607,"values":["u","i","y","a","o","e"],"children":{"u":{"type":"internal","weight":607,"values":["e","t"],"children":{"e":{"type":"leaf","weight":607,"entries":[{"key":"true","weight":607,"content":"true"}]},"t":{"type":"leaf","weight":203,"entries":[{"key":"truth","weight":203,"content":"truth"}]}}},"i":{"type":"internal","weight":431,"values":["e","a"],"children":{"e":{"type":"leaf","weight":431,"entries":[{"key":"tried","weight":431,"content":"tried"}]},"a":{"type":"leaf","weight":268,"entries":[{"key":"trial","weight":268,"content":"trial"}]}}},"y":{"type":"leaf","weight":409,"entries":[{"key":"trying","weight":409,"content":"trying"},{"key":"try","weight":295,"content":"try"}]},"a":{"type":"internal","weight":382,"values":["i","d"],"children":{"i":{"type":"leaf","weight":382,"entries":[{"key":"training","weight":382,"content":"training"}]},"d":{"type":"leaf","weight":315,"entries":[{"key":"trade","weight":315,"content":"trade"}]}}},"o":{"type":"leaf","weight":267,"entries":[{"key":"trouble","weight":267,"content":"trouble"}]},"e":{"type":"leaf","weight":216,"entries":[{"key":"treatment","weight":216,"content":"treatment"}]}}},"y":{"type":"internal","weight":540,"values":["p"],"children":{"p":{"type":"internal","weight":540,"values":["e"],"children":{"e":{"type":"internal","weight":540,"values":["\ufdd0","s"],"children":{"\ufdd0":{"type":"leaf","weight":540,"entries":[{"key":"type","weight":540,"content":"type"}]},"s":{"type":"leaf","weight":132,"entries":[{"key":"types","weight":132,"content":"types"}]}}}}}}}}},"o":{"type":"internal","weight":999,"values":["f","n","r","u","t","v","w","l","p","h","b"],"children":{"f":{"type":"internal","weight":999,"values":["\ufdd0","f","t"],"children":{"\ufdd0":{"type":"leaf","weight":999,"entries":[{"key":"of","weight":999,"content":"of"}]},"f":{"type":"internal","weight":860,"values":["\ufdd0","i"],"children":{"\ufdd0":{"type":"leaf","weight":860,"entries":[{"key":"off","weight":860,"content":"off"}]},"i":{"type":"leaf","weight":641,"entries":[{"key":"office","weight":641,"content":"office"}]}}},"t":{"type":"leaf","weight":756,"entries":[{"key":"often","weight":756,"content":"often"}]}}},"n":{"type":"internal","weight":985,"values":["\ufdd0","e","l","c"],"children":{"\ufdd0":{"type":"leaf","weight":985,"entries":[{"key":"on","weight":985,"content":"on"}]},"e":{"type":"internal","weight":969,"values":["\ufdd0","s"],"children":{"\ufdd0":{"type":"leaf","weight":969,"entries":[{"key":"one","weight":969,"content":"one"}]},"s":{"type":"leaf","weight":133,"entries":[{"key":"ones","weight":133,"content":"ones"}]}}},"l":{"type":"leaf","weight":939,"entries":[{"key":"only","weight":939,"content":"only"}]},"c":{"type":"leaf","weight":831,"entries":[{"key":"once","weight":831,"content":"once"}]}}},"r":{"type":"internal","weight":974,"values":["\ufdd0","d","g","i"],"children":{"\ufdd0":{"type":"leaf","weight":974,"entries":[{"key":"or","weight":974,"content":"or"}]},"d":{"type":"leaf","weight":765,"entries":[{"key":"order","weight":765,"content":"order"}]},"g":{"type":"leaf","weight":219,"entries":[{"key":"organization","weight":219,"content":"organization"}]},"i":{"type":"leaf","weight":4,"entries":[{"key":"original","weight":4,"content":"original"}]}}},"u":{"type":"internal","weight":950,"values":["t","r"],"children":{"t":{"type":"internal","weight":950,"values":["\ufdd0","s"],"children":{"\ufdd0":{"type":"leaf","weight":950,"entries":[{"key":"out","weight":950,"content":"out"}]},"s":{"type":"leaf","weight":562,"entries":[{"key":"outside","weight":562,"content":"outside"}]}}},"r":{"type":"leaf","weight":922,"entries":[{"key":"our","weight":922,"content":"our"}]}}},"t":{"type":"internal","weight":938,"values":["h"],"children":{"h":{"type":"internal","weight":938,"values":["e"],"children":{"e":{"type":"internal","weight":938,"values":["r"],"children":{"r":{"type":"internal","weight":938,"values":["\ufdd0","s"],"children":{"\ufdd0":{"type":"leaf","weight":938,"entries":[{"key":"other","weight":938,"content":"other"}]},"s":{"type":"leaf","weight":722,"entries":[{"key":"others","weight":722,"content":"others"}]}}}}}}}}},"v":{"type":"leaf","weight":921,"entries":[{"key":"over","weight":921,"content":"over"}]},"w":{"type":"leaf","weight":884,"entries":[{"key":"own","weight":884,"content":"own"}]},"l":{"type":"leaf","weight":862,"entries":[{"key":"old","weight":862,"content":"old"}]},"p":{"type":"internal","weight":718,"values":["e","p"],"children":{"e":{"type":"internal","weight":718,"values":["n","r"],"children":{"n":{"type":"internal","weight":718,"values":["\ufdd0","e"],"children":{"\ufdd0":{"type":"leaf","weight":718,"entries":[{"key":"open","weight":718,"content":"open"}]},"e":{"type":"leaf","weight":243,"entries":[{"key":"opened","weight":243,"content":"opened"}]}}},"r":{"type":"leaf","weight":93,"entries":[{"key":"operation","weight":93,"content":"operation"}]}}},"p":{"type":"leaf","weight":167,"entries":[{"key":"opportunity","weight":167,"content":"opportunity"}]}}},"h":{"type":"leaf","weight":176,"entries":[{"key":"oh","weight":176,"content":"oh"}]},"b":{"type":"internal","weight":119,"values":["t","v"],"children":{"t":{"type":"leaf","weight":119,"entries":[{"key":"obtained","weight":119,"content":"obtained"}]},"v":{"type":"leaf","weight":110,"entries":[{"key":"obviously","weight":110,"content":"obviously"}]}}}}},"a":{"type":"internal","weight":998,"values":["n","\ufdd0","s","t","r","l","b","f","g","m","w","c","i","v","d","p","j","u","h"],"children":{"n":{"type":"internal","weight":998,"values":["d","\ufdd0","y","o","s","a"],"children":{"d":{"type":"leaf","weight":998,"entries":[{"key":"and","weight":998,"content":"and"}]},"\ufdd0":{"type":"leaf","weight":972,"entries":[{"key":"an","weight":972,"content":"an"}]},"y":{"type":"internal","weight":927,"values":["\ufdd0","t","o"],"children":{"\ufdd0":{"type":"leaf","weight":927,"entries":[{"key":"any","weight":927,"content":"any"}]},"t":{"type":"leaf","weight":676,"entries":[{"key":"anything","weight":676,"content":"anything"}]},"o":{"type":"leaf","weight":296,"entries":[{"key":"anyone","weight":296,"content":"anyone"}]}}},"o":{"type":"leaf","weight":869,"entries":[{"key":"another","weight":869,"content":"another"}]},"s":{"type":"leaf","weight":366,"entries":[{"key":"answer","weight":366,"content":"answer"}]},"a":{"type":"leaf","weight":65,"entries":[{"key":"analysis","weight":65,"content":"analysis"}]}}},"\ufdd0":{"type":"leaf","weight":996,"entries":[{"key":"a","weight":996,"content":"a"}]},"s":{"type":"internal","weight":987,"values":["\ufdd0","k","s"],"children":{"\ufdd0":{"type":"leaf","weight":987,"entries":[{"key":"as","weight":987,"content":"as"}]},"k":{"type":"leaf","weight":786,"entries":[{"key":"asked","weight":786,"content":"asked"},{"key":"ask","weight":221,"content":"ask"}]},"s":{"type":"leaf","weight":256,"entries":[{"key":"association","weight":256,"content":"association"}]}}},"t":{"type":"internal","weight":983,"values":["\ufdd0","t"],"children":{"\ufdd0":{"type":"leaf","weight":983,"entries":[{"key":"at","weight":983,"content":"at"}]},"t":{"type":"internal","weight":473,"values":["e","i","a"],"children":{"e":{"type":"leaf","weight":473,"entries":[{"key":"attention","weight":473,"content":"attention"}]},"i":{"type":"leaf","weight":48,"entries":[{"key":"attitude","weight":48,"content":"attitude"}]},"a":{"type":"leaf","weight":28,"entries":[{"key":"attack","weight":28,"content":"attack"}]}}}}},"r":{"type":"internal","weight":977,"values":["e","o","t","m"],"children":{"e":{"type":"internal","weight":977,"values":["\ufdd0","a"],"children":{"\ufdd0":{"type":"leaf","weight":977,"entries":[{"key":"are","weight":977,"content":"are"}]},"a":{"type":"internal","weight":724,"values":["\ufdd0","s"],"children":{"\ufdd0":{"type":"leaf","weight":724,"entries":[{"key":"area","weight":724,"content":"area"}]},"s":{"type":"leaf","weight":613,"entries":[{"key":"areas","weight":613,"content":"areas"}]}}}}},"o":{"type":"leaf","weight":840,"entries":[{"key":"around","weight":840,"content":"around"}]},"t":{"type":"leaf","weight":559,"entries":[{"key":"art","weight":559,"content":"art"}]},"m":{"type":"internal","weight":250,"values":["y","s"],"children":{"y":{"type":"leaf","weight":250,"entries":[{"key":"army","weight":250,"content":"army"}]},"s":{"type":"leaf","weight":169,"entries":[{"key":"arms","weight":169,"content":"arms"}]}}}}},"l":{"type":"internal","weight":965,"values":["l","s","w","m","o","t","r"],"children":{"l":{"type":"leaf","weight":965,"entries":[{"key":"all","weight":965,"content":"all"}]},"s":{"type":"leaf","weight":914,"entries":[{"key":"also","weight":914,"content":"also"}]},"w":{"type":"leaf","weight":817,"entries":[{"key":"always","weight":817,"content":"always"}]},"m":{"type":"leaf","weight":807,"entries":[{"key":"almost","weight":807,"content":"almost"}]},"o":{"type":"internal","weight":741,"values":["n"],"children":{"n":{"type":"internal","weight":741,"values":["g","e"],"children":{"g":{"type":"leaf","weight":741,"entries":[{"key":"along","weight":741,"content":"along"}]},"e":{"type":"leaf","weight":519,"entries":[{"key":"alone","weight":519,"content":"alone"}]}}}}},"t":{"type":"leaf","weight":721,"entries":[{"key":"although","weight":721,"content":"although"}]},"r":{"type":"leaf","weight":663,"entries":[{"key":"already","weight":663,"content":"already"}]}}},"b":{"type":"internal","weight":944,"values":["o","l"],"children":{"o":{"type":"internal","weight":944,"values":["u","v"],"children":{"u":{"type":"leaf","weight":944,"entries":[{"key":"about","weight":944,"content":"about"}]},"v":{"type":"leaf","weight":696,"entries":[{"key":"above","weight":696,"content":"above"}]}}},"l":{"type":"leaf","weight":578,"entries":[{"key":"able","weight":578,"content":"able"}]}}},"f":{"type":"internal","weight":915,"values":["t","\ufdd0"],"children":{"t":{"type":"internal","weight":915,"values":["e"],"children":{"e":{"type":"internal","weight":915,"values":["r"],"children":{"r":{"type":"internal","weight":915,"values":["\ufdd0","n"],"children":{"\ufdd0":{"type":"leaf","weight":915,"entries":[{"key":"after","weight":915,"content":"after"}]},"n":{"type":"leaf","weight":33,"entries":[{"key":"afternoon","weight":33,"content":"afternoon"}]}}}}}}},"\ufdd0":{"type":"leaf","weight":909,"entries":[{"key":"af","weight":909,"content":"af"}]}}},"g":{"type":"internal","weight":857,"values":["a","o","e","r"],"children":{"a":{"type":"internal","weight":857,"values":["i"],"children":{"i":{"type":"internal","weight":857,"values":["n"],"children":{"n":{"type":"leaf","weight":857,"entries":[{"key":"against","weight":857,"content":"against"},{"key":"again","weight":843,"content":"again"}]}}}}},"o":{"type":"leaf","weight":630,"entries":[{"key":"ago","weight":630,"content":"ago"}]},"e":{"type":"leaf","weight":600,"entries":[{"key":"age","weight":600,"content":"age"}]},"r":{"type":"leaf","weight":36,"entries":[{"key":"agreement","weight":36,"content":"agreement"}]}}},"m":{"type":"internal","weight":841,"values":["e","o","\ufdd0"],"children":{"e":{"type":"internal","weight":841,"values":["r"],"children":{"r":{"type":"internal","weight":841,"values":["i"],"children":{"i":{"type":"internal","weight":841,"values":["c"],"children":{"c":{"type":"internal","weight":841,"values":["a"],"children":{"a":{"type":"leaf","weight":841,"entries":[{"key":"american","weight":841,"content":"american"},{"key":"america","weight":512,"content":"america"}]}}}}}}}}},"o":{"type":"internal","weight":758,"values":["n","u"],"children":{"n":{"type":"leaf","weight":758,"entries":[{"key":"among","weight":758,"content":"among"}]},"u":{"type":"leaf","weight":442,"entries":[{"key":"amount","weight":442,"content":"amount"}]}}},"\ufdd0":{"type":"leaf","weight":614,"entries":[{"key":"am","weight":614,"content":"am"}]}}},"w":{"type":"leaf","weight":816,"entries":[{"key":"away","weight":816,"content":"away"}]},"c":{"type":"internal","weight":693,"values":["t","r","c"],"children":{"t":{"type":"internal","weight":693,"values":["i","\ufdd0","u"],"children":{"i":{"type":"internal","weight":693,"values":["o","v"],"children":{"o":{"type":"leaf","weight":693,"entries":[{"key":"action","weight":693,"content":"action"}]},"v":{"type":"internal","weight":131,"values":["i"],"children":{"i":{"type":"internal","weight":131,"values":["t"],"children":{"t":{"type":"internal","weight":131,"values":["y","i"],"children":{"y":{"type":"leaf","weight":131,"entries":[{"key":"activity","weight":131,"content":"activity"}]},"i":{"type":"leaf","weight":121,"entries":[{"key":"activities","weight":121,"content":"activities"}]}}}}}}}}},"\ufdd0":{"type":"leaf","weight":682,"entries":[{"key":"act","weight":682,"content":"act"}]},"u":{"type":"leaf","weight":423,"entries":[{"key":"actually","weight":423,"content":"actually"}]}}},"r":{"type":"leaf","weight":680,"entries":[{"key":"across","weight":680,"content":"across"}]},"c":{"type":"internal","weight":298,"values":["o"],"children":{"o":{"type":"internal","weight":298,"values":["r","u"],"children":{"r":{"type":"leaf","weight":298,"entries":[{"key":"according","weight":298,"content":"according"}]},"u":{"type":"leaf","weight":135,"entries":[{"key":"account","weight":135,"content":"account"}]}}}}}}},"i":{"type":"internal","weight":643,"values":["r","d"],"children":{"r":{"type":"leaf","weight":643,"entries":[{"key":"air","weight":643,"content":"air"}]},"d":{"type":"leaf","weight":265,"entries":[{"key":"aid","weight":265,"content":"aid"}]}}},"v":{"type":"internal","weight":627,"values":["a","e"],"children":{"a":{"type":"leaf","weight":627,"entries":[{"key":"available","weight":627,"content":"available"}]},"e":{"type":"leaf","weight":241,"entries":[{"key":"average","weight":241,"content":"average"}]}}},"d":{"type":"internal","weight":446,"values":["d","m"],"children":{"d":{"type":"internal","weight":446,"values":["e","i"],"children":{"e":{"type":"leaf","weight":446,"entries":[{"key":"added","weight":446,"content":"added"}]},"i":{"type":"internal","weight":308,"values":["t"],"children":{"t":{"type":"internal","weight":308,"values":["i"],"children":{"i":{"type":"internal","weight":308,"values":["o"],"children":{"o":{"type":"internal","weight":308,"values":["n"],"children":{"n":{"type":"internal","weight":308,"values":["\ufdd0","a"],"children":{"\ufdd0":{"type":"leaf","weight":308,"entries":[{"key":"addition","weight":308,"content":"addition"}]},"a":{"type":"leaf","weight":164,"entries":[{"key":"additional","weight":164,"content":"additional"}]}}}}}}}}}}}}},"m":{"type":"leaf","weight":402,"entries":[{"key":"administration","weight":402,"content":"administration"}]}}},"p":{"type":"internal","weight":275,"values":["p"],"children":{"p":{"type":"internal","weight":275,"values":["e","a","r","l"],"children":{"e":{"type":"internal","weight":275,"values":["a"],"children":{"a":{"type":"internal","weight":275,"values":["r"],"children":{"r":{"type":"leaf","weight":275,"entries":[{"key":"appeared","weight":275,"content":"appeared"},{"key":"appear","weight":137,"content":"appear"}]}}}}},"a":{"type":"leaf","weight":195,"entries":[{"key":"apparently","weight":195,"content":"apparently"}]},"r":{"type":"leaf","weight":185,"entries":[{"key":"approach","weight":185,"content":"approach"}]},"l":{"type":"leaf","weight":39,"entries":[{"key":"applied","weight":39,"content":"applied"}]}}}}},"j":{"type":"leaf","weight":142,"entries":[{"key":"aj","weight":142,"content":"aj"}]},"u":{"type":"leaf","weight":118,"entries":[{"key":"audience","weight":118,"content":"audience"}]},"h":{"type":"leaf","weight":73,"entries":[{"key":"ahead","weight":73,"content":"ahead"}]}}},"i":{"type":"internal","weight":995,"values":["n","s","t","f","m","d","\ufdd0"],"children":{"n":{"type":"internal","weight":995,"values":["\ufdd0","t","f","d","c","s","v"],"children":{"\ufdd0":{"type":"leaf","weight":995,"entries":[{"key":"in","weight":995,"content":"in"}]},"t":{"type":"internal","weight":943,"values":["o","e"],"children":{"o":{"type":"leaf","weight":943,"entries":[{"key":"into","weight":943,"content":"into"}]},"e":{"type":"internal","weight":728,"values":["r"],"children":{"r":{"type":"internal","weight":728,"values":["e","n"],"children":{"e":{"type":"internal","weight":728,"values":["s"],"children":{"s":{"type":"internal","weight":728,"values":["t"],"children":{"t":{"type":"internal","weight":728,"values":["\ufdd0","e"],"children":{"\ufdd0":{"type":"leaf","weight":728,"entries":[{"key":"interest","weight":728,"content":"interest"}]},"e":{"type":"leaf","weight":24,"entries":[{"key":"interested","weight":24,"content":"interested"}]}}}}}}},"n":{"type":"leaf","weight":380,"entries":[{"key":"international","weight":380,"content":"international"}]}}}}}}},"f":{"type":"internal","weight":661,"values":["o","l"],"children":{"o":{"type":"leaf","weight":661,"entries":[{"key":"information","weight":661,"content":"information"}]},"l":{"type":"leaf","weight":254,"entries":[{"key":"influence","weight":254,"content":"influence"}]}}},"d":{"type":"internal","weight":617,"values":["i","u","e"],"children":{"i":{"type":"internal","weight":617,"values":["v","c"],"children":{"v":{"type":"leaf","weight":617,"entries":[{"key":"individual","weight":617,"content":"individual"}]},"c":{"type":"leaf","weight":59,"entries":[{"key":"indicated","weight":59,"content":"indicated"}]}}},"u":{"type":"internal","weight":432,"values":["s"],"children":{"s":{"type":"internal","weight":432,"values":["t"],"children":{"t":{"type":"internal","weight":432,"values":["r"],"children":{"r":{"type":"internal","weight":432,"values":["y","i"],"children":{"y":{"type":"leaf","weight":432,"entries":[{"key":"industry","weight":432,"content":"industry"}]},"i":{"type":"leaf","weight":323,"entries":[{"key":"industrial","weight":323,"content":"industrial"}]}}}}}}}}},"e":{"type":"leaf","weight":408,"entries":[{"key":"indeed","weight":408,"content":"indeed"}]}}},"c":{"type":"internal","weight":514,"values":["r","l","o"],"children":{"r":{"type":"internal","weight":514,"values":["e"],"children":{"e":{"type":"internal","weight":514,"values":["a"],"children":{"a":{"type":"internal","weight":514,"values":["s"],"children":{"s":{"type":"internal","weight":514,"values":["e"],"children":{"e":{"type":"internal","weight":514,"values":["\ufdd0","d"],"children":{"\ufdd0":{"type":"leaf","weight":514,"entries":[{"key":"increase","weight":514,"content":"increase"}]},"d":{"type":"leaf","weight":339,"entries":[{"key":"increased","weight":339,"content":"increased"}]}}}}}}}}}}},"l":{"type":"internal","weight":438,"values":["u"],"children":{"u":{"type":"internal","weight":438,"values":["d"],"children":{"d":{"type":"internal","weight":438,"values":["i","e"],"children":{"i":{"type":"leaf","weight":438,"entries":[{"key":"including","weight":438,"content":"including"}]},"e":{"type":"leaf","weight":102,"entries":[{"key":"include","weight":102,"content":"include"}]}}}}}}},"o":{"type":"leaf","weight":71,"entries":[{"key":"income","weight":71,"content":"income"}]}}},"s":{"type":"internal","weight":459,"values":["i","t"],"children":{"i":{"type":"leaf","weight":459,"entries":[{"key":"inside","weight":459,"content":"inside"}]},"t":{"type":"leaf","weight":452,"entries":[{"key":"instead","weight":452,"content":"instead"}]}}},"v":{"type":"leaf","weight":344,"entries":[{"key":"involved","weight":344,"content":"involved"}]}}},"s":{"type":"internal","weight":993,"values":["\ufdd0","l","s"],"children":{"\ufdd0":{"type":"leaf","weight":993,"entries":[{"key":"is","weight":993,"content":"is"}]},"l":{"type":"leaf","weight":424,"entries":[{"key":"island","weight":424,"content":"island"}]},"s":{"type":"leaf","weight":368,"entries":[{"key":"issue","weight":368,"content":"issue"}]}}},"t":{"type":"internal","weight":989,"values":["\ufdd0","s"],"children":{"\ufdd0":{"type":"leaf","weight":989,"entries":[{"key":"it","weight":989,"content":"it"}]},"s":{"type":"internal","weight":945,"values":["\ufdd0","e"],"children":{"\ufdd0":{"type":"leaf","weight":945,"entries":[{"key":"its","weight":945,"content":"its"}]},"e":{"type":"leaf","weight":702,"entries":[{"key":"itself","weight":702,"content":"itself"}]}}}}},"\ufdd0":{"type":"leaf","weight":981,"entries":[{"key":"i","weight":981,"content":"i"}]},"f":{"type":"leaf","weight":952,"entries":[{"key":"if","weight":952,"content":"if"}]},"m":{"type":"internal","weight":755,"values":["p","m","a"],"children":{"p":{"type":"internal","weight":755,"values":["o"],"children":{"o":{"type":"internal","weight":755,"values":["r"],"children":{"r":{"type":"internal","weight":755,"values":["t"],"children":{"t":{"type":"internal","weight":755,"values":["a"],"children":{"a":{"type":"internal","weight":755,"values":["n"],"children":{"n":{"type":"internal","weight":755,"values":["t","c"],"children":{"t":{"type":"leaf","weight":755,"entries":[{"key":"important","weight":755,"content":"important"}]},"c":{"type":"leaf","weight":67,"entries":[{"key":"importance","weight":67,"content":"importance"}]}}}}}}}}}}}}},"m":{"type":"leaf","weight":184,"entries":[{"key":"immediately","weight":184,"content":"immediately"}]},"a":{"type":"leaf","weight":152,"entries":[{"key":"image","weight":152,"content":"image"}]}}},"d":{"type":"internal","weight":520,"values":["e"],"children":{"e":{"type":"internal","weight":520,"values":["a"],"children":{"a":{"type":"internal","weight":520,"values":["\ufdd0","s"],"children":{"\ufdd0":{"type":"leaf","weight":520,"entries":[{"key":"idea","weight":520,"content":"idea"}]},"s":{"type":"leaf","weight":319,"entries":[{"key":"ideas","weight":319,"content":"ideas"}]}}}}}}}}},"w":{"type":"internal","weight":992,"values":["a","i","h","e","o","r"],"children":{"a":{"type":"internal","weight":992,"values":["s","y","r","t","n","l","i"],"children":{"s":{"type":"internal","weight":992,"values":["\ufdd0","h"],"children":{"\ufdd0":{"type":"leaf","weight":992,"entries":[{"key":"was","weight":992,"content":"was"}]},"h":{"type":"leaf","weight":554,"entries":[{"key":"washington","weight":554,"content":"washington"}]}}},"y":{"type":"internal","weight":902,"values":["\ufdd0","s"],"children":{"\ufdd0":{"type":"leaf","weight":902,"entries":[{"key":"way","weight":902,"content":"way"}]},"s":{"type":"leaf","weight":217,"entries":[{"key":"ways","weight":217,"content":"ways"}]}}},"r":{"type":"leaf","weight":819,"entries":[{"key":"war","weight":819,"content":"war"}]},"t":{"type":"leaf","weight":813,"entries":[{"key":"water","weight":813,"content":"water"}]},"n":{"type":"internal","weight":727,"values":["t"],"children":{"t":{"type":"internal","weight":727,"values":["\ufdd0","e"],"children":{"\ufdd0":{"type":"leaf","weight":727,"entries":[{"key":"want","weight":727,"content":"want"}]},"e":{"type":"leaf","weight":598,"entries":[{"key":"wanted","weight":598,"content":"wanted"}]}}}}},"l":{"type":"internal","weight":395,"values":["l","k"],"children":{"l":{"type":"leaf","weight":395,"entries":[{"key":"wall","weight":395,"content":"wall"}]},"k":{"type":"leaf","weight":394,"entries":[{"key":"walked","weight":394,"content":"walked"}]}}},"i":{"type":"leaf","weight":81,"entries":[{"key":"waiting","weight":81,"content":"waiting"}]}}},"i":{"type":"internal","weight":988,"values":["t","l","f","d","n","s"],"children":{"t":{"type":"internal","weight":988,"values":["h"],"children":{"h":{"type":"internal","weight":988,"values":["\ufdd0","o","i"],"children":{"\ufdd0":{"type":"leaf","weight":988,"entries":[{"key":"with","weight":988,"content":"with"}]},"o":{"type":"leaf","weight":844,"entries":[{"key":"without","weight":844,"content":"without"}]},"i":{"type":"leaf","weight":744,"entries":[{"key":"within","weight":744,"content":"within"}]}}}}},"l":{"type":"internal","weight":954,"values":["l"],"children":{"l":{"type":"internal","weight":954,"values":["\ufdd0","i"],"children":{"\ufdd0":{"type":"leaf","weight":954,"entries":[{"key":"will","weight":954,"content":"will"}]},"i":{"type":"leaf","weight":347,"entries":[{"key":"william","weight":347,"content":"william"}]}}}}},"f":{"type":"leaf","weight":601,"entries":[{"key":"wife","weight":601,"content":"wife"}]},"d":{"type":"leaf","weight":192,"entries":[{"key":"wide","weight":192,"content":"wide"}]},"n":{"type":"leaf","weight":149,"entries":[{"key":"window","weight":149,"content":"window"}]},"s":{"type":"leaf","weight":77,"entries":[{"key":"wish","weight":77,"content":"wish"}]}}},"h":{"type":"internal","weight":970,"values":["i","e","o","a","y"],"children":{"i":{"type":"internal","weight":970,"values":["c","l","t"],"children":{"c":{"type":"leaf","weight":970,"entries":[{"key":"which","weight":970,"content":"which"}]},"l":{"type":"leaf","weight":867,"entries":[{"key":"while","weight":867,"content":"while"}]},"t":{"type":"leaf","weight":751,"entries":[{"key":"white","weight":751,"content":"white"}]}}},"e":{"type":"internal","weight":956,"values":["n","r","t"],"children":{"n":{"type":"leaf","weight":956,"entries":[{"key":"when","weight":956,"content":"when"}]},"r":{"type":"leaf","weight":904,"entries":[{"key":"where","weight":904,"content":"where"}]},"t":{"type":"leaf","weight":688,"entries":[{"key":"whether","weight":688,"content":"whether"}]}}},"o":{"type":"internal","weight":955,"values":["\ufdd0","l","s","m"],"children":{"\ufdd0":{"type":"leaf","weight":955,"entries":[{"key":"who","weight":955,"content":"who"}]},"l":{"type":"leaf","weight":705,"entries":[{"key":"whole","weight":705,"content":"whole"}]},"s":{"type":"leaf","weight":638,"entries":[{"key":"whose","weight":638,"content":"whose"}]},"m":{"type":"leaf","weight":341,"entries":[{"key":"whom","weight":341,"content":"whom"}]}}},"a":{"type":"internal","weight":947,"values":["t"],"children":{"t":{"type":"internal","weight":947,"values":["\ufdd0","e"],"children":{"\ufdd0":{"type":"leaf","weight":947,"entries":[{"key":"what","weight":947,"content":"what"}]},"e":{"type":"leaf","weight":91,"entries":[{"key":"whatever","weight":91,"content":"whatever"}]}}}}},"y":{"type":"leaf","weight":792,"entries":[{"key":"why","weight":792,"content":"why"}]}}},"e":{"type":"internal","weight":967,"values":["r","\ufdd0","l","n","e","s"],"children":{"r":{"type":"leaf","weight":967,"entries":[{"key":"were","weight":967,"content":"were"}]},"\ufdd0":{"type":"leaf","weight":960,"entries":[{"key":"we","weight":960,"content":"we"}]},"l":{"type":"leaf","weight":901,"entries":[{"key":"well","weight":901,"content":"well"}]},"n":{"type":"leaf","weight":834,"entries":[{"key":"went","weight":834,"content":"went"}]},"e":{"type":"internal","weight":668,"values":["k"],"children":{"k":{"type":"internal","weight":668,"values":["\ufdd0","s"],"children":{"\ufdd0":{"type":"leaf","weight":668,"entries":[{"key":"week","weight":668,"content":"week"}]},"s":{"type":"leaf","weight":299,"entries":[{"key":"weeks","weight":299,"content":"weeks"}]}}}}},"s":{"type":"internal","weight":612,"values":["t"],"children":{"t":{"type":"internal","weight":612,"values":["\ufdd0","e"],"children":{"\ufdd0":{"type":"leaf","weight":612,"entries":[{"key":"west","weight":612,"content":"west"}]},"e":{"type":"leaf","weight":282,"entries":[{"key":"western","weight":282,"content":"western"}]}}}}}}},"o":{"type":"internal","weight":962,"values":["u","r","m"],"children":{"u":{"type":"leaf","weight":962,"entries":[{"key":"would","weight":962,"content":"would"}]},"r":{"type":"internal","weight":886,"values":["l","k","d"],"children":{"l":{"type":"leaf","weight":886,"entries":[{"key":"world","weight":886,"content":"world"}]},"k":{"type":"internal","weight":881,"values":["\ufdd0","i","s","e"],"children":{"\ufdd0":{"type":"leaf","weight":881,"entries":[{"key":"work","weight":881,"content":"work"}]},"i":{"type":"leaf","weight":363,"entries":[{"key":"working","weight":363,"content":"working"}]},"s":{"type":"leaf","weight":237,"entries":[{"key":"works","weight":237,"content":"works"}]},"e":{"type":"leaf","weight":222,"entries":[{"key":"worked","weight":222,"content":"worked"}]}}},"d":{"type":"leaf","weight":665,"entries":[{"key":"words","weight":665,"content":"words"},{"key":"word","weight":664,"content":"word"}]}}},"m":{"type":"internal","weight":594,"values":["a","e"],"children":{"a":{"type":"leaf","weight":594,"entries":[{"key":"woman","weight":594,"content":"woman"}]},"e":{"type":"leaf","weight":518,"entries":[{"key":"women","weight":518,"content":"women"}]}}}}},"r":{"type":"internal","weight":481,"values":["o","i"],"children":{"o":{"type":"internal","weight":481,"values":["t","n"],"children":{"t":{"type":"leaf","weight":481,"entries":[{"key":"wrote","weight":481,"content":"wrote"}]},"n":{"type":"leaf","weight":227,"entries":[{"key":"wrong","weight":227,"content":"wrong"}]}}},"i":{"type":"internal","weight":373,"values":["t"],"children":{"t":{"type":"internal","weight":373,"values":["t","i","e"],"children":{"t":{"type":"leaf","weight":373,"entries":[{"key":"written","weight":373,"content":"written"}]},"i":{"type":"leaf","weight":139,"entries":[{"key":"writing","weight":139,"content":"writing"}]},"e":{"type":"leaf","weight":34,"entries":[{"key":"write","weight":34,"content":"write"}]}}}}}}}}},"h":{"type":"internal","weight":991,"values":["e","i","a","o","u"],"children":{"e":{"type":"internal","weight":991,"values":["\ufdd0","r","a","l"],"children":{"\ufdd0":{"type":"leaf","weight":991,"entries":[{"key":"he","weight":991,"content":"he"}]},"r":{"type":"internal","weight":966,"values":["\ufdd0","e","s"],"children":{"\ufdd0":{"type":"leaf","weight":966,"entries":[{"key":"her","weight":966,"content":"her"}]},"e":{"type":"leaf","weight":879,"entries":[{"key":"here","weight":879,"content":"here"}]},"s":{"type":"leaf","weight":196,"entries":[{"key":"herself","weight":196,"content":"herself"}]}}},"a":{"type":"internal","weight":802,"values":["d","r","v","l"],"children":{"d":{"type":"leaf","weight":802,"entries":[{"key":"head","weight":802,"content":"head"}]},"r":{"type":"internal","weight":634,"values":["d","t","\ufdd0"],"children":{"d":{"type":"leaf","weight":634,"entries":[{"key":"heard","weight":634,"content":"heard"}]},"t":{"type":"leaf","weight":453,"entries":[{"key":"heart","weight":453,"content":"heart"}]},"\ufdd0":{"type":"leaf","weight":369,"entries":[{"key":"hear","weight":369,"content":"hear"}]}}},"v":{"type":"leaf","weight":84,"entries":[{"key":"heavy","weight":84,"content":"heavy"}]},"l":{"type":"leaf","weight":30,"entries":[{"key":"health","weight":30,"content":"health"}]}}},"l":{"type":"internal","weight":707,"values":["p","d"],"children":{"p":{"type":"leaf","weight":707,"entries":[{"key":"help","weight":707,"content":"help"}]},"d":{"type":"leaf","weight":653,"entries":[{"key":"held","weight":653,"content":"held"}]}}}}},"i":{"type":"internal","weight":986,"values":["s","m","g","t"],"children":{"s":{"type":"internal","weight":986,"values":["\ufdd0","t"],"children":{"\ufdd0":{"type":"leaf","weight":986,"entries":[{"key":"his","weight":986,"content":"his"}]},"t":{"type":"leaf","weight":687,"entries":[{"key":"history","weight":687,"content":"history"}]}}},"m":{"type":"internal","weight":959,"values":["\ufdd0","s"],"children":{"\ufdd0":{"type":"leaf","weight":959,"entries":[{"key":"him","weight":959,"content":"him"}]},"s":{"type":"leaf","weight":850,"entries":[{"key":"himself","weight":850,"content":"himself"}]}}},"g":{"type":"internal","weight":829,"values":["h"],"children":{"h":{"type":"internal","weight":829,"values":["\ufdd0","e"],"children":{"\ufdd0":{"type":"leaf","weight":829,"entries":[{"key":"high","weight":829,"content":"high"}]},"e":{"type":"leaf","weight":397,"entries":[{"key":"higher","weight":397,"content":"higher"}]}}}}},"t":{"type":"leaf","weight":114,"entries":[{"key":"hit","weight":114,"content":"hit"}]}}},"a":{"type":"internal","weight":979,"values":["d","v","s","n","l","r","p","i"],"children":{"d":{"type":"leaf","weight":979,"entries":[{"key":"had","weight":979,"content":"had"}]},"v":{"type":"internal","weight":973,"values":["e","i"],"children":{"e":{"type":"leaf","weight":973,"entries":[{"key":"have","weight":973,"content":"have"}]},"i":{"type":"leaf","weight":675,"entries":[{"key":"having","weight":675,"content":"having"}]}}},"s":{"type":"leaf","weight":957,"entries":[{"key":"has","weight":957,"content":"has"}]},"n":{"type":"internal","weight":806,"values":["d"],"children":{"d":{"type":"internal","weight":806,"values":["\ufdd0","s"],"children":{"\ufdd0":{"type":"leaf","weight":806,"entries":[{"key":"hand","weight":806,"content":"hand"}]},"s":{"type":"leaf","weight":691,"entries":[{"key":"hands","weight":691,"content":"hands"}]}}}}},"l":{"type":"internal","weight":669,"values":["f","l"],"children":{"f":{"type":"leaf","weight":669,"entries":[{"key":"half","weight":669,"content":"half"}]},"l":{"type":"leaf","weight":367,"entries":[{"key":"hall","weight":367,"content":"hall"}]}}},"r":{"type":"internal","weight":545,"values":["d"],"children":{"d":{"type":"internal","weight":545,"values":["\ufdd0","l"],"children":{"\ufdd0":{"type":"leaf","weight":545,"entries":[{"key":"hard","weight":545,"content":"hard"}]},"l":{"type":"leaf","weight":40,"entries":[{"key":"hardly","weight":40,"content":"hardly"}]}}}}},"p":{"type":"leaf","weight":353,"entries":[{"key":"happened","weight":353,"content":"happened"}]},"i":{"type":"leaf","weight":348,"entries":[{"key":"hair","weight":348,"content":"hair"}]}}},"o":{"type":"internal","weight":892,"values":["w","u","m","p","l","t","r","s"],"children":{"w":{"type":"internal","weight":892,"values":["\ufdd0","e"],"children":{"\ufdd0":{"type":"leaf","weight":892,"entries":[{"key":"how","weight":892,"content":"how"}]},"e":{"type":"leaf","weight":839,"entries":[{"key":"however","weight":839,"content":"however"}]}}},"u":{"type":"internal","weight":846,"values":["s","r"],"children":{"s":{"type":"leaf","weight":846,"entries":[{"key":"house","weight":846,"content":"house"}]},"r":{"type":"leaf","weight":454,"entries":[{"key":"hours","weight":454,"content":"hours"},{"key":"hour","weight":331,"content":"hour"}]}}},"m":{"type":"leaf","weight":838,"entries":[{"key":"home","weight":838,"content":"home"}]},"p":{"type":"leaf","weight":471,"entries":[{"key":"hope","weight":471,"content":"hope"}]},"l":{"type":"leaf","weight":428,"entries":[{"key":"hold","weight":428,"content":"hold"}]},"t":{"type":"internal","weight":238,"values":["\ufdd0","e"],"children":{"\ufdd0":{"type":"leaf","weight":238,"entries":[{"key":"hot","weight":238,"content":"hot"}]},"e":{"type":"leaf","weight":201,"entries":[{"key":"hotel","weight":201,"content":"hotel"}]}}},"r":{"type":"leaf","weight":138,"entries":[{"key":"horse","weight":138,"content":"horse"}]},"s":{"type":"leaf","weight":79,"entries":[{"key":"hospital","weight":79,"content":"hospital"}]}}},"u":{"type":"internal","weight":699,"values":["m","n","s"],"children":{"m":{"type":"leaf","weight":699,"entries":[{"key":"human","weight":699,"content":"human"}]},"n":{"type":"leaf","weight":434,"entries":[{"key":"hundred","weight":434,"content":"hundred"}]},"s":{"type":"leaf","weight":247,"entries":[{"key":"husband","weight":247,"content":"husband"}]}}}}},"f":{"type":"internal","weight":990,"values":["o","r","i","e","a","u","l"],"children":{"o":{"type":"internal","weight":990,"values":["r","u","l","o"],"children":{"r":{"type":"internal","weight":990,"values":["\ufdd0","m","c","e","w"],"children":{"\ufdd0":{"type":"leaf","weight":990,"entries":[{"key":"for","weight":990,"content":"for"}]},"m":{"type":"internal","weight":757,"values":["\ufdd0","e","s"],"children":{"\ufdd0":{"type":"leaf","weight":757,"entries":[{"key":"form","weight":757,"content":"form"}]},"e":{"type":"leaf","weight":242,"entries":[{"key":"former","weight":242,"content":"former"}]},"s":{"type":"leaf","weight":206,"entries":[{"key":"forms","weight":206,"content":"forms"}]}}},"c":{"type":"internal","weight":606,"values":["e"],"children":{"e":{"type":"internal","weight":606,"values":["\ufdd0","s"],"children":{"\ufdd0":{"type":"leaf","weight":606,"entries":[{"key":"force","weight":606,"content":"force"}]},"s":{"type":"leaf","weight":461,"entries":[{"key":"forces","weight":461,"content":"forces"}]}}}}},"e":{"type":"leaf","weight":390,"entries":[{"key":"foreign","weight":390,"content":"foreign"}]},"w":{"type":"leaf","weight":124,"entries":[{"key":"forward","weight":124,"content":"forward"}]}}},"u":{"type":"internal","weight":836,"values":["n","r"],"children":{"n":{"type":"leaf","weight":836,"entries":[{"key":"found","weight":836,"content":"found"}]},"r":{"type":"leaf","weight":747,"entries":[{"key":"four","weight":747,"content":"four"}]}}},"l":{"type":"internal","weight":588,"values":["l"],"children":{"l":{"type":"internal","weight":588,"values":["o"],"children":{"o":{"type":"internal","weight":588,"values":["w"],"children":{"w":{"type":"internal","weight":588,"values":["i","e"],"children":{"i":{"type":"leaf","weight":588,"entries":[{"key":"following","weight":588,"content":"following"}]},"e":{"type":"leaf","weight":443,"entries":[{"key":"followed","weight":443,"content":"followed"}]}}}}}}}}},"o":{"type":"leaf","weight":342,"entries":[{"key":"food","weight":342,"content":"food"}]}}},"r":{"type":"internal","weight":975,"values":["o","e","i"],"children":{"o":{"type":"internal","weight":975,"values":["m","n"],"children":{"m":{"type":"leaf","weight":975,"entries":[{"key":"from","weight":975,"content":"from"}]},"n":{"type":"leaf","weight":589,"entries":[{"key":"front","weight":589,"content":"front"}]}}},"e":{"type":"internal","weight":650,"values":["e","n"],"children":{"e":{"type":"internal","weight":650,"values":["\ufdd0","d"],"children":{"\ufdd0":{"type":"leaf","weight":650,"entries":[{"key":"free","weight":650,"content":"free"}]},"d":{"type":"leaf","weight":223,"entries":[{"key":"freedom","weight":223,"content":"freedom"}]}}},"n":{"type":"leaf","weight":288,"entries":[{"key":"french","weight":288,"content":"french"}]}}},"i":{"type":"internal","weight":406,"values":["e"],"children":{"e":{"type":"internal","weight":406,"values":["n"],"children":{"n":{"type":"internal","weight":406,"values":["d"],"children":{"d":{"type":"leaf","weight":406,"entries":[{"key":"friends","weight":406,"content":"friends"},{"key":"friend","weight":263,"content":"friend"}]}}}}}}}}},"i":{"type":"internal","weight":928,"values":["r","n","v","e","g","s"],"children":{"r":{"type":"internal","weight":928,"values":["s","e","m"],"children":{"s":{"type":"leaf","weight":928,"entries":[{"key":"first","weight":928,"content":"first"}]},"e":{"type":"leaf","weight":499,"entries":[{"key":"fire","weight":499,"content":"fire"}]},"m":{"type":"leaf","weight":68,"entries":[{"key":"firm","weight":68,"content":"firm"}]}}},"n":{"type":"internal","weight":789,"values":["d","a","e"],"children":{"d":{"type":"leaf","weight":789,"entries":[{"key":"find","weight":789,"content":"find"}]},"a":{"type":"internal","weight":508,"values":["l"],"children":{"l":{"type":"leaf","weight":508,"entries":[{"key":"finally","weight":508,"content":"finally"},{"key":"final","weight":384,"content":"final"}]}}},"e":{"type":"leaf","weight":400,"entries":[{"key":"fine","weight":400,"content":"fine"}]}}},"v":{"type":"leaf","weight":686,"entries":[{"key":"five","weight":686,"content":"five"}]},"e":{"type":"leaf","weight":666,"entries":[{"key":"field","weight":666,"content":"field"}]},"g":{"type":"internal","weight":560,"values":["u"],"children":{"u":{"type":"internal","weight":560,"values":["r"],"children":{"r":{"type":"internal","weight":560,"values":["e"],"children":{"e":{"type":"internal","weight":560,"values":["\ufdd0","s"],"children":{"\ufdd0":{"type":"leaf","weight":560,"entries":[{"key":"figure","weight":560,"content":"figure"}]},"s":{"type":"leaf","weight":100,"entries":[{"key":"figures","weight":100,"content":"figures"}]}}}}}}}}},"s":{"type":"leaf","weight":160,"entries":[{"key":"fiscal","weight":160,"content":"fiscal"}]}}},"e":{"type":"internal","weight":848,"values":["w","l","e","d","a"],"children":{"w":{"type":"leaf","weight":848,"entries":[{"key":"few","weight":848,"content":"few"}]},"l":{"type":"leaf","weight":742,"entries":[{"key":"felt","weight":742,"content":"felt"}]},"e":{"type":"internal","weight":681,"values":["t","l","d"],"children":{"t":{"type":"leaf","weight":681,"entries":[{"key":"feet","weight":681,"content":"feet"}]},"l":{"type":"internal","weight":580,"values":["\ufdd0","i"],"children":{"\ufdd0":{"type":"leaf","weight":580,"entries":[{"key":"feel","weight":580,"content":"feel"}]},"i":{"type":"leaf","weight":440,"entries":[{"key":"feeling","weight":440,"content":"feeling"}]}}},"d":{"type":"leaf","weight":174,"entries":[{"key":"feed","weight":174,"content":"feed"}]}}},"d":{"type":"leaf","weight":629,"entries":[{"key":"federal","weight":629,"content":"federal"}]},"a":{"type":"leaf","weight":215,"entries":[{"key":"fear","weight":215,"content":"fear"}]}}},"a":{"type":"internal","weight":814,"values":["c","r","m","t","l","i"],"children":{"c":{"type":"internal","weight":814,"values":["t","e"],"children":{"t":{"type":"internal","weight":814,"values":["\ufdd0","o"],"children":{"\ufdd0":{"type":"leaf","weight":814,"entries":[{"key":"fact","weight":814,"content":"fact"}]},"o":{"type":"leaf","weight":41,"entries":[{"key":"factors","weight":41,"content":"factors"}]}}},"e":{"type":"leaf","weight":760,"entries":[{"key":"face","weight":760,"content":"face"}]}}},"r":{"type":"internal","weight":803,"values":["\ufdd0","m"],"children":{"\ufdd0":{"type":"leaf","weight":803,"entries":[{"key":"far","weight":803,"content":"far"}]},"m":{"type":"leaf","weight":188,"entries":[{"key":"farm","weight":188,"content":"farm"}]}}},"m":{"type":"leaf","weight":729,"entries":[{"key":"family","weight":729,"content":"family"}]},"t":{"type":"leaf","weight":487,"entries":[{"key":"father","weight":487,"content":"father"}]},"l":{"type":"leaf","weight":343,"entries":[{"key":"fall","weight":343,"content":"fall"}]},"i":{"type":"leaf","weight":88,"entries":[{"key":"faith","weight":88,"content":"faith"}]}}},"u":{"type":"internal","weight":605,"values":["l","t","r","n"],"children":{"l":{"type":"leaf","weight":605,"entries":[{"key":"full","weight":605,"content":"full"}]},"t":{"type":"leaf","weight":599,"entries":[{"key":"future","weight":599,"content":"future"}]},"r":{"type":"leaf","weight":583,"entries":[{"key":"further","weight":583,"content":"further"}]},"n":{"type":"leaf","weight":105,"entries":[{"key":"function","weight":105,"content":"function"}]}}},"l":{"type":"leaf","weight":391,"entries":[{"key":"floor","weight":391,"content":"floor"}]}}},"b":{"type":"internal","weight":984,"values":["e","y","u","a","o","i","r","l","\ufdd0"],"children":{"e":{"type":"internal","weight":984,"values":["\ufdd0","e","f","c","t","i","s","g","h","l","y","a","d"],"children":{"\ufdd0":{"type":"leaf","weight":984,"entries":[{"key":"be","weight":984,"content":"be"}]},"e":{"type":"leaf","weight":958,"entries":[{"key":"been","weight":958,"content":"been"}]},"f":{"type":"leaf","weight":911,"entries":[{"key":"before","weight":911,"content":"before"}]},"c":{"type":"internal","weight":898,"values":["a","o"],"children":{"a":{"type":"internal","weight":898,"values":["u","m"],"children":{"u":{"type":"leaf","weight":898,"entries":[{"key":"because","weight":898,"content":"because"}]},"m":{"type":"leaf","weight":633,"entries":[{"key":"became","weight":633,"content":"became"}]}}},"o":{"type":"internal","weight":743,"values":["m"],"children":{"m":{"type":"internal","weight":743,"values":["e"],"children":{"e":{"type":"internal","weight":743,"values":["\ufdd0","s"],"children":{"\ufdd0":{"type":"leaf","weight":743,"entries":[{"key":"become","weight":743,"content":"become"}]},"s":{"type":"leaf","weight":17,"entries":[{"key":"becomes","weight":17,"content":"becomes"}]}}}}}}}}},"t":{"type":"internal","weight":877,"values":["w","t"],"children":{"w":{"type":"leaf","weight":877,"entries":[{"key":"between","weight":877,"content":"between"}]},"t":{"type":"leaf","weight":797,"entries":[{"key":"better","weight":797,"content":"better"}]}}},"i":{"type":"leaf","weight":874,"entries":[{"key":"being","weight":874,"content":"being"}]},"s":{"type":"leaf","weight":738,"entries":[{"key":"best","weight":738,"content":"best"}]},"g":{"type":"internal","weight":710,"values":["a","i"],"children":{"a":{"type":"leaf","weight":710,"entries":[{"key":"began","weight":710,"content":"began"}]},"i":{"type":"leaf","weight":416,"entries":[{"key":"beginning","weight":416,"content":"beginning"}]}}},"h":{"type":"leaf","weight":648,"entries":[{"key":"behind","weight":648,"content":"behind"}]},"l":{"type":"internal","weight":541,"values":["i","o"],"children":{"i":{"type":"leaf","weight":541,"entries":[{"key":"believe","weight":541,"content":"believe"}]},"o":{"type":"leaf","weight":333,"entries":[{"key":"below","weight":333,"content":"below"}]}}},"y":{"type":"leaf","weight":466,"entries":[{"key":"beyond","weight":466,"content":"beyond"}]},"a":{"type":"leaf","weight":214,"entries":[{"key":"beautiful","weight":214,"content":"beautiful"}]},"d":{"type":"leaf","weight":211,"entries":[{"key":"bed","weight":211,"content":"bed"}]}}},"y":{"type":"leaf","weight":982,"entries":[{"key":"by","weight":982,"content":"by"}]},"u":{"type":"internal","weight":976,"values":["t","s","i"],"children":{"t":{"type":"leaf","weight":976,"entries":[{"key":"but","weight":976,"content":"but"}]},"s":{"type":"leaf","weight":779,"entries":[{"key":"business","weight":779,"content":"business"}]},"i":{"type":"internal","weight":398,"values":["l"],"children":{"l":{"type":"internal","weight":398,"values":["d","t"],"children":{"d":{"type":"leaf","weight":398,"entries":[{"key":"building","weight":398,"content":"building"}]},"t":{"type":"leaf","weight":9,"entries":[{"key":"built","weight":9,"content":"built"}]}}}}}}},"a":{"type":"internal","weight":907,"values":["c","s","d","l"],"children":{"c":{"type":"leaf","weight":907,"entries":[{"key":"back","weight":907,"content":"back"}]},"s":{"type":"internal","weight":489,"values":["i","e"],"children":{"i":{"type":"internal","weight":489,"values":["s","c"],"children":{"s":{"type":"leaf","weight":489,"entries":[{"key":"basis","weight":489,"content":"basis"}]},"c":{"type":"leaf","weight":439,"entries":[{"key":"basic","weight":439,"content":"basic"}]}}},"e":{"type":"leaf","weight":154,"entries":[{"key":"based","weight":154,"content":"based"}]}}},"d":{"type":"leaf","weight":313,"entries":[{"key":"bad","weight":313,"content":"bad"}]},"l":{"type":"leaf","weight":78,"entries":[{"key":"ball","weight":78,"content":"ball"}]}}},"o":{"type":"internal","weight":876,"values":["t","d","y","a","o","r"],"children":{"t":{"type":"leaf","weight":876,"entries":[{"key":"both","weight":876,"content":"both"}]},"d":{"type":"leaf","weight":671,"entries":[{"key":"body","weight":671,"content":"body"}]},"y":{"type":"internal","weight":623,"values":["\ufdd0","s"],"children":{"\ufdd0":{"type":"leaf","weight":623,"entries":[{"key":"boy","weight":623,"content":"boy"}]},"s":{"type":"leaf","weight":324,"entries":[{"key":"boys","weight":324,"content":"boys"}]}}},"a":{"type":"leaf","weight":618,"entries":[{"key":"board","weight":618,"content":"board"}]},"o":{"type":"leaf","weight":528,"entries":[{"key":"book","weight":528,"content":"book"}]},"r":{"type":"leaf","weight":99,"entries":[{"key":"born","weight":99,"content":"born"}]}}},"i":{"type":"internal","weight":745,"values":["g","l"],"children":{"g":{"type":"leaf","weight":745,"entries":[{"key":"big","weight":745,"content":"big"}]},"l":{"type":"leaf","weight":322,"entries":[{"key":"bill","weight":322,"content":"bill"}]}}},"r":{"type":"internal","weight":640,"values":["o","i"],"children":{"o":{"type":"internal","weight":640,"values":["u","w"],"children":{"u":{"type":"leaf","weight":640,"entries":[{"key":"brought","weight":640,"content":"brought"}]},"w":{"type":"leaf","weight":467,"entries":[{"key":"brown","weight":467,"content":"brown"}]}}},"i":{"type":"internal","weight":392,"values":["n","t"],"children":{"n":{"type":"leaf","weight":392,"entries":[{"key":"bring","weight":392,"content":"bring"}]},"t":{"type":"leaf","weight":143,"entries":[{"key":"british","weight":143,"content":"british"}]}}}}},"l":{"type":"internal","weight":546,"values":["a","u","o"],"children":{"a":{"type":"leaf","weight":546,"entries":[{"key":"black","weight":546,"content":"black"}]},"u":{"type":"leaf","weight":316,"entries":[{"key":"blue","weight":316,"content":"blue"}]},"o":{"type":"leaf","weight":168,"entries":[{"key":"blood","weight":168,"content":"blood"}]}}},"\ufdd0":{"type":"leaf","weight":32,"entries":[{"key":"b","weight":32,"content":"b"}]}}},"n":{"type":"internal","weight":978,"values":["o","e","u","i","a"],"children":{"o":{"type":"internal","weight":978,"values":["t","\ufdd0","w","r","n"],"children":{"t":{"type":"internal","weight":978,"values":["\ufdd0","h","e"],"children":{"\ufdd0":{"type":"leaf","weight":978,"entries":[{"key":"not","weight":978,"content":"not"}]},"h":{"type":"leaf","weight":795,"entries":[{"key":"nothing","weight":795,"content":"nothing"}]},"e":{"type":"leaf","weight":204,"entries":[{"key":"note","weight":204,"content":"note"}]}}},"\ufdd0":{"type":"leaf","weight":951,"entries":[{"key":"no","weight":951,"content":"no"}]},"w":{"type":"leaf","weight":925,"entries":[{"key":"now","weight":925,"content":"now"}]},"r":{"type":"internal","weight":555,"values":["t","\ufdd0","m"],"children":{"t":{"type":"leaf","weight":555,"entries":[{"key":"north","weight":555,"content":"north"}]},"\ufdd0":{"type":"leaf","weight":521,"entries":[{"key":"nor","weight":521,"content":"nor"}]},"m":{"type":"leaf","weight":277,"entries":[{"key":"normal","weight":277,"content":"normal"}]}}},"n":{"type":"leaf","weight":61,"entries":[{"key":"none","weight":61,"content":"none"}]}}},"e":{"type":"internal","weight":937,"values":["w","v","x","e","c","a","i","g"],"children":{"w":{"type":"leaf","weight":937,"entries":[{"key":"new","weight":937,"content":"new"}]},"v":{"type":"leaf","weight":872,"entries":[{"key":"never","weight":872,"content":"never"}]},"x":{"type":"leaf","weight":782,"entries":[{"key":"next","weight":782,"content":"next"}]},"e":{"type":"internal","weight":746,"values":["d"],"children":{"d":{"type":"internal","weight":746,"values":["\ufdd0","e","s"],"children":{"\ufdd0":{"type":"leaf","weight":746,"entries":[{"key":"need","weight":746,"content":"need"}]},"e":{"type":"leaf","weight":498,"entries":[{"key":"needed","weight":498,"content":"needed"}]},"s":{"type":"leaf","weight":365,"entries":[{"key":"needs","weight":365,"content":"needs"}]}}}}},"c":{"type":"leaf","weight":591,"entries":[{"key":"necessary","weight":591,"content":"necessary"}]},"a":{"type":"internal","weight":532,"values":["r"],"children":{"r":{"type":"internal","weight":532,"values":["\ufdd0","l"],"children":{"\ufdd0":{"type":"leaf","weight":532,"entries":[{"key":"near","weight":532,"content":"near"}]},"l":{"type":"leaf","weight":303,"entries":[{"key":"nearly","weight":303,"content":"nearly"}]}}}}},"i":{"type":"leaf","weight":307,"entries":[{"key":"neither","weight":307,"content":"neither"}]},"g":{"type":"leaf","weight":43,"entries":[{"key":"negro","weight":43,"content":"negro"}]}}},"u":{"type":"internal","weight":821,"values":["m","c"],"children":{"m":{"type":"internal","weight":821,"values":["b"],"children":{"b":{"type":"internal","weight":821,"values":["e"],"children":{"e":{"type":"internal","weight":821,"values":["r"],"children":{"r":{"type":"internal","weight":821,"values":["\ufdd0","s"],"children":{"\ufdd0":{"type":"leaf","weight":821,"entries":[{"key":"number","weight":821,"content":"number"}]},"s":{"type":"leaf","weight":199,"entries":[{"key":"numbers","weight":199,"content":"numbers"}]}}}}}}}}},"c":{"type":"leaf","weight":127,"entries":[{"key":"nuclear","weight":127,"content":"nuclear"}]}}},"i":{"type":"leaf","weight":794,"entries":[{"key":"night","weight":794,"content":"night"}]},"a":{"type":"internal","weight":764,"values":["t","m"],"children":{"t":{"type":"internal","weight":764,"values":["i","u"],"children":{"i":{"type":"internal","weight":764,"values":["o"],"children":{"o":{"type":"internal","weight":764,"values":["n"],"children":{"n":{"type":"internal","weight":764,"values":["a","s","\ufdd0"],"children":{"a":{"type":"leaf","weight":764,"entries":[{"key":"national","weight":764,"content":"national"}]},"s":{"type":"leaf","weight":462,"entries":[{"key":"nations","weight":462,"content":"nations"}]},"\ufdd0":{"type":"leaf","weight":291,"entries":[{"key":"nation","weight":291,"content":"nation"}]}}}}}}},"u":{"type":"internal","weight":506,"values":["r"],"children":{"r":{"type":"internal","weight":506,"values":["e","a"],"children":{"e":{"type":"leaf","weight":506,"entries":[{"key":"nature","weight":506,"content":"nature"}]},"a":{"type":"leaf","weight":385,"entries":[{"key":"natural","weight":385,"content":"natural"}]}}}}}}},"m":{"type":"leaf","weight":695,"entries":[{"key":"name","weight":695,"content":"name"}]}}}}},"y":{"type":"internal","weight":968,"values":["o","e"],"children":{"o":{"type":"internal","weight":968,"values":["u","r"],"children":{"u":{"type":"internal","weight":968,"values":["\ufdd0","r","n"],"children":{"\ufdd0":{"type":"leaf","weight":968,"entries":[{"key":"you","weight":968,"content":"you"}]},"r":{"type":"leaf","weight":903,"entries":[{"key":"your","weight":903,"content":"your"}]},"n":{"type":"leaf","weight":775,"entries":[{"key":"young","weight":775,"content":"young"}]}}},"r":{"type":"leaf","weight":701,"entries":[{"key":"york","weight":701,"content":"york"}]}}},"e":{"type":"internal","weight":906,"values":["a","t","s"],"children":{"a":{"type":"internal","weight":906,"values":["r"],"children":{"r":{"type":"leaf","weight":906,"entries":[{"key":"years","weight":906,"content":"years"},{"key":"year","weight":861,"content":"year"}]}}},"t":{"type":"leaf","weight":801,"entries":[{"key":"yet","weight":801,"content":"yet"}]},"s":{"type":"leaf","weight":326,"entries":[{"key":"yes","weight":326,"content":"yes"}]}}}}},"s":{"type":"internal","weight":964,"values":["h","o","a","u","t","e","i","m","c","y","p","q","l"],"children":{"h":{"type":"internal","weight":964,"values":["e","o","a"],"children":{"e":{"type":"leaf","weight":964,"entries":[{"key":"she","weight":964,"content":"she"}]},"o":{"type":"internal","weight":899,"values":["u","w","r","t"],"children":{"u":{"type":"leaf","weight":899,"entries":[{"key":"should","weight":899,"content":"should"}]},"w":{"type":"internal","weight":689,"values":["\ufdd0","n","e"],"children":{"\ufdd0":{"type":"leaf","weight":689,"entries":[{"key":"show","weight":689,"content":"show"}]},"n":{"type":"leaf","weight":422,"entries":[{"key":"shown","weight":422,"content":"shown"}]},"e":{"type":"leaf","weight":306,"entries":[{"key":"showed","weight":306,"content":"showed"}]}}},"r":{"type":"leaf","weight":566,"entries":[{"key":"short","weight":566,"content":"short"}]},"t":{"type":"leaf","weight":92,"entries":[{"key":"shot","weight":92,"content":"shot"}]}}},"a":{"type":"leaf","weight":659,"entries":[{"key":"shall","weight":659,"content":"shall"}]}}},"o":{"type":"internal","weight":949,"values":["\ufdd0","m","c","u","o","n","r","v"],"children":{"\ufdd0":{"type":"leaf","weight":949,"entries":[{"key":"so","weight":949,"content":"so"}]},"m":{"type":"internal","weight":936,"values":["e"],"children":{"e":{"type":"internal","weight":936,"values":["\ufdd0","t","w"],"children":{"\ufdd0":{"type":"leaf","weight":936,"entries":[{"key":"some","weight":936,"content":"some"}]},"t":{"type":"internal","weight":815,"values":["h","i"],"children":{"h":{"type":"leaf","weight":815,"entries":[{"key":"something","weight":815,"content":"something"}]},"i":{"type":"leaf","weight":587,"entries":[{"key":"sometimes","weight":587,"content":"sometimes"}]}}},"w":{"type":"leaf","weight":209,"entries":[{"key":"somewhat","weight":209,"content":"somewhat"}]}}}}},"c":{"type":"internal","weight":769,"values":["i"],"children":{"i":{"type":"internal","weight":769,"values":["a","e"],"children":{"a":{"type":"leaf","weight":769,"entries":[{"key":"social","weight":769,"content":"social"}]},"e":{"type":"leaf","weight":615,"entries":[{"key":"society","weight":615,"content":"society"}]}}}}},"u":{"type":"internal","weight":620,"values":["t","n"],"children":{"t":{"type":"internal","weight":620,"values":["h"],"children":{"h":{"type":"internal","weight":620,"values":["\ufdd0","e"],"children":{"\ufdd0":{"type":"leaf","weight":620,"entries":[{"key":"south","weight":620,"content":"south"}]},"e":{"type":"leaf","weight":278,"entries":[{"key":"southern","weight":278,"content":"southern"}]}}}}},"n":{"type":"leaf","weight":548,"entries":[{"key":"sound","weight":548,"content":"sound"}]}}},"o":{"type":"leaf","weight":534,"entries":[{"key":"soon","weight":534,"content":"soon"}]},"n":{"type":"leaf","weight":421,"entries":[{"key":"son","weight":421,"content":"son"}]},"r":{"type":"leaf","weight":414,"entries":[{"key":"sort","weight":414,"content":"sort"}]},"v":{"type":"leaf","weight":224,"entries":[{"key":"soviet","weight":224,"content":"soviet"}]}}},"a":{"type":"internal","weight":948,"values":["i","m","y","w","t","l"],"children":{"i":{"type":"leaf","weight":948,"entries":[{"key":"said","weight":948,"content":"said"}]},"m":{"type":"leaf","weight":870,"entries":[{"key":"same","weight":870,"content":"same"}]},"y":{"type":"internal","weight":833,"values":["\ufdd0","s","i"],"children":{"\ufdd0":{"type":"leaf","weight":833,"entries":[{"key":"say","weight":833,"content":"say"}]},"s":{"type":"leaf","weight":538,"entries":[{"key":"says","weight":538,"content":"says"}]},"i":{"type":"leaf","weight":106,"entries":[{"key":"saying","weight":106,"content":"saying"}]}}},"w":{"type":"leaf","weight":739,"entries":[{"key":"saw","weight":739,"content":"saw"}]},"t":{"type":"leaf","weight":358,"entries":[{"key":"sat","weight":358,"content":"sat"}]},"l":{"type":"leaf","weight":262,"entries":[{"key":"sales","weight":262,"content":"sales"}]}}},"u":{"type":"internal","weight":924,"values":["c","r","p","b","d","m","n","g"],"children":{"c":{"type":"leaf","weight":924,"entries":[{"key":"such","weight":924,"content":"such"}]},"r":{"type":"internal","weight":652,"values":["e","f"],"children":{"e":{"type":"leaf","weight":652,"entries":[{"key":"sure","weight":652,"content":"sure"}]},"f":{"type":"leaf","weight":536,"entries":[{"key":"surface","weight":536,"content":"surface"}]}}},"p":{"type":"leaf","weight":478,"entries":[{"key":"support","weight":478,"content":"support"}]},"b":{"type":"leaf","weight":401,"entries":[{"key":"subject","weight":401,"content":"subject"}]},"d":{"type":"leaf","weight":370,"entries":[{"key":"suddenly","weight":370,"content":"suddenly"}]},"m":{"type":"leaf","weight":266,"entries":[{"key":"summer","weight":266,"content":"summer"}]},"n":{"type":"leaf","weight":89,"entries":[{"key":"sun","weight":89,"content":"sun"}]},"g":{"type":"leaf","weight":31,"entries":[{"key":"suggested","weight":31,"content":"suggested"}]}}},"t":{"type":"internal","weight":890,"values":["a","i","u","r","o","e"],"children":{"a":{"type":"internal","weight":890,"values":["t","r","g","n","f","y"],"children":{"t":{"type":"internal","weight":890,"values":["e","i"],"children":{"e":{"type":"internal","weight":890,"values":["\ufdd0","s","m"],"children":{"\ufdd0":{"type":"leaf","weight":890,"entries":[{"key":"state","weight":890,"content":"state"}]},"s":{"type":"leaf","weight":849,"entries":[{"key":"states","weight":849,"content":"states"}]},"m":{"type":"leaf","weight":302,"entries":[{"key":"statement","weight":302,"content":"statement"}]}}},"i":{"type":"leaf","weight":23,"entries":[{"key":"station","weight":23,"content":"station"}]}}},"r":{"type":"internal","weight":511,"values":["t"],"children":{"t":{"type":"leaf","weight":511,"entries":[{"key":"started","weight":511,"content":"started"},{"key":"start","weight":372,"content":"start"}]}}},"g":{"type":"leaf","weight":465,"entries":[{"key":"stage","weight":465,"content":"stage"}]},"n":{"type":"internal","weight":349,"values":["d"],"children":{"d":{"type":"internal","weight":349,"values":["\ufdd0","a"],"children":{"\ufdd0":{"type":"leaf","weight":349,"entries":[{"key":"stand","weight":349,"content":"stand"}]},"a":{"type":"leaf","weight":80,"entries":[{"key":"standard","weight":80,"content":"standard"}]}}}}},"f":{"type":"leaf","weight":103,"entries":[{"key":"staff","weight":103,"content":"staff"}]},"y":{"type":"leaf","weight":97,"entries":[{"key":"stay","weight":97,"content":"stay"}]}}},"i":{"type":"leaf","weight":885,"entries":[{"key":"still","weight":885,"content":"still"}]},"u":{"type":"internal","weight":631,"values":["d"],"children":{"d":{"type":"internal","weight":631,"values":["y","e","i"],"children":{"y":{"type":"leaf","weight":631,"entries":[{"key":"study","weight":631,"content":"study"}]},"e":{"type":"internal","weight":571,"values":["n"],"children":{"n":{"type":"internal","weight":571,"values":["t"],"children":{"t":{"type":"leaf","weight":571,"entries":[{"key":"students","weight":571,"content":"students"},{"key":"student","weight":244,"content":"student"}]}}}}},"i":{"type":"leaf","weight":3,"entries":[{"key":"studies","weight":3,"content":"studies"}]}}}}},"r":{"type":"internal","weight":626,"values":["e","o","a"],"children":{"e":{"type":"internal","weight":626,"values":["e","n","s"],"children":{"e":{"type":"leaf","weight":626,"entries":[{"key":"street","weight":626,"content":"street"}]},"n":{"type":"leaf","weight":281,"entries":[{"key":"strength","weight":281,"content":"strength"}]},"s":{"type":"leaf","weight":49,"entries":[{"key":"stress","weight":49,"content":"stress"}]}}},"o":{"type":"leaf","weight":544,"entries":[{"key":"strong","weight":544,"content":"strong"}]},"a":{"type":"leaf","weight":109,"entries":[{"key":"straight","weight":109,"content":"straight"}]}}},"o":{"type":"internal","weight":568,"values":["o","r","c","p"],"children":{"o":{"type":"leaf","weight":568,"entries":[{"key":"stood","weight":568,"content":"stood"}]},"r":{"type":"leaf","weight":371,"entries":[{"key":"story","weight":371,"content":"story"}]},"c":{"type":"leaf","weight":345,"entries":[{"key":"stock","weight":345,"content":"stock"}]},"p":{"type":"leaf","weight":231,"entries":[{"key":"stopped","weight":231,"content":"stopped"},{"key":"stop","weight":161,"content":"stop"}]}}},"e":{"type":"internal","weight":246,"values":["p"],"children":{"p":{"type":"internal","weight":246,"values":["\ufdd0","s"],"children":{"\ufdd0":{"type":"leaf","weight":246,"entries":[{"key":"step","weight":246,"content":"step"}]},"s":{"type":"leaf","weight":153,"entries":[{"key":"steps","weight":153,"content":"steps"}]}}}}}}},"e":{"type":"internal","weight":883,"values":["e","t","v","c","r","n","a"],"children":{"e":{"type":"internal","weight":883,"values":["\ufdd0","m","n"],"children":{"\ufdd0":{"type":"leaf","weight":883,"entries":[{"key":"see","weight":883,"content":"see"}]},"m":{"type":"internal","weight":731,"values":["e","s","\ufdd0"],"children":{"e":{"type":"leaf","weight":731,"entries":[{"key":"seemed","weight":731,"content":"seemed"}]},"s":{"type":"leaf","weight":649,"entries":[{"key":"seems","weight":649,"content":"seems"}]},"\ufdd0":{"type":"leaf","weight":603,"entries":[{"key":"seem","weight":603,"content":"seem"}]}}},"n":{"type":"leaf","weight":674,"entries":[{"key":"seen","weight":674,"content":"seen"}]}}},"t":{"type":"leaf","weight":798,"entries":[{"key":"set","weight":798,"content":"set"}]},"v":{"type":"internal","weight":766,"values":["e"],"children":{"e":{"type":"internal","weight":766,"values":["r","n"],"children":{"r":{"type":"leaf","weight":766,"entries":[{"key":"several","weight":766,"content":"several"}]},"n":{"type":"leaf","weight":96,"entries":[{"key":"seven","weight":96,"content":"seven"}]}}}}},"c":{"type":"internal","weight":761,"values":["o","r","t"],"children":{"o":{"type":"leaf","weight":761,"entries":[{"key":"second","weight":761,"content":"second"}]},"r":{"type":"leaf","weight":505,"entries":[{"key":"secretary","weight":505,"content":"secretary"}]},"t":{"type":"leaf","weight":503,"entries":[{"key":"section","weight":503,"content":"section"}]}}},"r":{"type":"internal","weight":716,"values":["v","i"],"children":{"v":{"type":"internal","weight":716,"values":["i","e"],"children":{"i":{"type":"internal","weight":716,"values":["c"],"children":{"c":{"type":"internal","weight":716,"values":["e"],"children":{"e":{"type":"internal","weight":716,"values":["\ufdd0","s"],"children":{"\ufdd0":{"type":"leaf","weight":716,"entries":[{"key":"service","weight":716,"content":"service"}]},"s":{"type":"leaf","weight":290,"entries":[{"key":"services","weight":290,"content":"services"}]}}}}}}},"e":{"type":"leaf","weight":150,"entries":[{"key":"served","weight":150,"content":"served"},{"key":"serve","weight":50,"content":"serve"}]}}},"i":{"type":"internal","weight":239,"values":["e","o"],"children":{"e":{"type":"leaf","weight":239,"entries":[{"key":"series","weight":239,"content":"series"}]},"o":{"type":"leaf","weight":134,"entries":[{"key":"serious","weight":134,"content":"serious"}]}}}}},"n":{"type":"internal","weight":708,"values":["s","t"],"children":{"s":{"type":"leaf","weight":708,"entries":[{"key":"sense","weight":708,"content":"sense"}]},"t":{"type":"leaf","weight":328,"entries":[{"key":"sent","weight":328,"content":"sent"}]}}},"a":{"type":"leaf","weight":25,"entries":[{"key":"season","weight":25,"content":"season"}]}}},"i":{"type":"internal","weight":858,"values":["n","d","x","t","m","z"],"children":{"n":{"type":"internal","weight":858,"values":["c","g"],"children":{"c":{"type":"leaf","weight":858,"entries":[{"key":"since","weight":858,"content":"since"}]},"g":{"type":"leaf","weight":444,"entries":[{"key":"single","weight":444,"content":"single"}]}}},"d":{"type":"leaf","weight":770,"entries":[{"key":"side","weight":770,"content":"side"}]},"x":{"type":"leaf","weight":585,"entries":[{"key":"six","weight":585,"content":"six"}]},"t":{"type":"leaf","weight":525,"entries":[{"key":"situation","weight":525,"content":"situation"}]},"m":{"type":"internal","weight":437,"values":["p","i"],"children":{"p":{"type":"internal","weight":437,"values":["l"],"children":{"l":{"type":"internal","weight":437,"values":["y","e"],"children":{"y":{"type":"leaf","weight":437,"entries":[{"key":"simply","weight":437,"content":"simply"}]},"e":{"type":"leaf","weight":396,"entries":[{"key":"simple","weight":396,"content":"simple"}]}}}}},"i":{"type":"leaf","weight":388,"entries":[{"key":"similar","weight":388,"content":"similar"}]}}},"z":{"type":"leaf","weight":285,"entries":[{"key":"size","weight":285,"content":"size"}]}}},"m":{"type":"leaf","weight":837,"entries":[{"key":"small","weight":837,"content":"small"}]},"c":{"type":"internal","weight":827,"values":["h","i","e"],"children":{"h":{"type":"internal","weight":827,"values":["o"],"children":{"o":{"type":"internal","weight":827,"values":["o"],"children":{"o":{"type":"internal","weight":827,"values":["l"],"children":{"l":{"type":"internal","weight":827,"values":["\ufdd0","s"],"children":{"\ufdd0":{"type":"leaf","weight":827,"entries":[{"key":"school","weight":827,"content":"school"}]},"s":{"type":"leaf","weight":516,"entries":[{"key":"schools","weight":516,"content":"schools"}]}}}}}}}}},"i":{"type":"leaf","weight":249,"entries":[{"key":"science","weight":249,"content":"science"}]},"e":{"type":"leaf","weight":35,"entries":[{"key":"scene","weight":35,"content":"scene"}]}}},"y":{"type":"internal","weight":799,"values":["s"],"children":{"s":{"type":"internal","weight":799,"values":["t"],"children":{"t":{"type":"internal","weight":799,"values":["e"],"children":{"e":{"type":"internal","weight":799,"values":["m"],"children":{"m":{"type":"internal","weight":799,"values":["\ufdd0","s"],"children":{"\ufdd0":{"type":"leaf","weight":799,"entries":[{"key":"system","weight":799,"content":"system"}]},"s":{"type":"leaf","weight":233,"entries":[{"key":"systems","weight":233,"content":"systems"}]}}}}}}}}}}},"p":{"type":"internal","weight":637,"values":["e","a","i","r"],"children":{"e":{"type":"internal","weight":637,"values":["c","a","n"],"children":{"c":{"type":"internal","weight":637,"values":["i"],"children":{"i":{"type":"internal","weight":637,"values":["a","f"],"children":{"a":{"type":"leaf","weight":637,"entries":[{"key":"special","weight":637,"content":"special"}]},"f":{"type":"leaf","weight":126,"entries":[{"key":"specific","weight":126,"content":"specific"}]}}}}},"a":{"type":"leaf","weight":85,"entries":[{"key":"speak","weight":85,"content":"speak"}]},"n":{"type":"leaf","weight":13,"entries":[{"key":"spent","weight":13,"content":"spent"}]}}},"a":{"type":"leaf","weight":488,"entries":[{"key":"space","weight":488,"content":"space"}]},"i":{"type":"leaf","weight":485,"entries":[{"key":"spirit","weight":485,"content":"spirit"}]},"r":{"type":"leaf","weight":210,"entries":[{"key":"spring","weight":210,"content":"spring"}]}}},"q":{"type":"leaf","weight":317,"entries":[{"key":"square","weight":317,"content":"square"}]},"l":{"type":"leaf","weight":125,"entries":[{"key":"slowly","weight":125,"content":"slowly"}]}}},"m":{"type":"internal","weight":953,"values":["o","a","y","e","u","i"],"children":{"o":{"type":"internal","weight":953,"values":["r","s","n","m","t","d","v","u"],"children":{"r":{"type":"internal","weight":953,"values":["e","n","a"],"children":{"e":{"type":"leaf","weight":953,"entries":[{"key":"more","weight":953,"content":"more"}]},"n":{"type":"leaf","weight":563,"entries":[{"key":"morning","weight":563,"content":"morning"}]},"a":{"type":"leaf","weight":314,"entries":[{"key":"moral","weight":314,"content":"moral"}]}}},"s":{"type":"leaf","weight":917,"entries":[{"key":"most","weight":917,"content":"most"}]},"n":{"type":"internal","weight":656,"values":["e","t"],"children":{"e":{"type":"leaf","weight":656,"entries":[{"key":"money","weight":656,"content":"money"}]},"t":{"type":"internal","weight":502,"values":["h"],"children":{"h":{"type":"leaf","weight":502,"entries":[{"key":"months","weight":502,"content":"months"},{"key":"month","weight":240,"content":"month"}]}}}}},"m":{"type":"leaf","weight":632,"entries":[{"key":"moment","weight":632,"content":"moment"}]},"t":{"type":"leaf","weight":579,"entries":[{"key":"mother","weight":579,"content":"mother"}]},"d":{"type":"leaf","weight":533,"entries":[{"key":"modern","weight":533,"content":"modern"}]},"v":{"type":"internal","weight":479,"values":["e","i"],"children":{"e":{"type":"internal","weight":479,"values":["d","\ufdd0","m"],"children":{"d":{"type":"leaf","weight":479,"entries":[{"key":"moved","weight":479,"content":"moved"}]},"\ufdd0":{"type":"leaf","weight":436,"entries":[{"key":"move","weight":436,"content":"move"}]},"m":{"type":"leaf","weight":220,"entries":[{"key":"movement","weight":220,"content":"movement"}]}}},"i":{"type":"leaf","weight":111,"entries":[{"key":"moving","weight":111,"content":"moving"}]}}},"u":{"type":"leaf","weight":6,"entries":[{"key":"mouth","weight":6,"content":"mouth"}]}}},"a":{"type":"internal","weight":931,"values":["y","n","d","k","t","j","r","i","c"],"children":{"y":{"type":"internal","weight":931,"values":["\ufdd0","b"],"children":{"\ufdd0":{"type":"leaf","weight":931,"entries":[{"key":"may","weight":931,"content":"may"}]},"b":{"type":"leaf","weight":259,"entries":[{"key":"maybe","weight":259,"content":"maybe"}]}}},"n":{"type":"internal","weight":920,"values":["\ufdd0","y","n"],"children":{"\ufdd0":{"type":"leaf","weight":920,"entries":[{"key":"man","weight":920,"content":"man"}]},"y":{"type":"leaf","weight":912,"entries":[{"key":"many","weight":912,"content":"many"}]},"n":{"type":"leaf","weight":190,"entries":[{"key":"manner","weight":190,"content":"manner"}]}}},"d":{"type":"leaf","weight":916,"entries":[{"key":"made","weight":916,"content":"made"}]},"k":{"type":"internal","weight":887,"values":["e","i"],"children":{"e":{"type":"internal","weight":887,"values":["\ufdd0","s"],"children":{"\ufdd0":{"type":"leaf","weight":887,"entries":[{"key":"make","weight":887,"content":"make"}]},"s":{"type":"leaf","weight":445,"entries":[{"key":"makes","weight":445,"content":"makes"}]}}},"i":{"type":"leaf","weight":642,"entries":[{"key":"making","weight":642,"content":"making"}]}}},"t":{"type":"internal","weight":704,"values":["t","e"],"children":{"t":{"type":"leaf","weight":704,"entries":[{"key":"matter","weight":704,"content":"matter"}]},"e":{"type":"leaf","weight":463,"entries":[{"key":"material","weight":463,"content":"material"}]}}},"j":{"type":"leaf","weight":635,"entries":[{"key":"major","weight":635,"content":"major"}]},"r":{"type":"internal","weight":377,"values":["k","c","r"],"children":{"k":{"type":"leaf","weight":377,"entries":[{"key":"market","weight":377,"content":"market"}]},"c":{"type":"leaf","weight":166,"entries":[{"key":"march","weight":166,"content":"march"}]},"r":{"type":"leaf","weight":21,"entries":[{"key":"married","weight":21,"content":"married"}]}}},"i":{"type":"leaf","weight":155,"entries":[{"key":"main","weight":155,"content":"main"}]},"c":{"type":"leaf","weight":1,"entries":[{"key":"machine","weight":1,"content":"machine"}]}}},"y":{"type":"internal","weight":926,"values":["\ufdd0","s"],"children":{"\ufdd0":{"type":"leaf","weight":926,"entries":[{"key":"my","weight":926,"content":"my"}]},"s":{"type":"leaf","weight":230,"entries":[{"key":"myself","weight":230,"content":"myself"}]}}},"e":{"type":"internal","weight":919,"values":["\ufdd0","n","m","a","d","e","t","r"],"children":{"\ufdd0":{"type":"leaf","weight":919,"entries":[{"key":"me","weight":919,"content":"me"}]},"n":{"type":"leaf","weight":882,"entries":[{"key":"men","weight":882,"content":"men"}]},"m":{"type":"internal","weight":725,"values":["b"],"children":{"b":{"type":"internal","weight":725,"values":["e"],"children":{"e":{"type":"internal","weight":725,"values":["r"],"children":{"r":{"type":"leaf","weight":725,"entries":[{"key":"members","weight":725,"content":"members"},{"key":"member","weight":284,"content":"member"}]}}}}}}},"a":{"type":"internal","weight":706,"values":["n"],"children":{"n":{"type":"internal","weight":706,"values":["s","\ufdd0","i"],"children":{"s":{"type":"leaf","weight":706,"entries":[{"key":"means","weight":706,"content":"means"}]},"\ufdd0":{"type":"leaf","weight":535,"entries":[{"key":"mean","weight":535,"content":"mean"}]},"i":{"type":"leaf","weight":213,"entries":[{"key":"meaning","weight":213,"content":"meaning"}]}}}}},"d":{"type":"leaf","weight":405,"entries":[{"key":"medical","weight":405,"content":"medical"}]},"e":{"type":"internal","weight":393,"values":["t"],"children":{"t":{"type":"leaf","weight":393,"entries":[{"key":"meeting","weight":393,"content":"meeting"},{"key":"meet","weight":356,"content":"meet"}]}}},"t":{"type":"internal","weight":311,"values":["h","\ufdd0"],"children":{"h":{"type":"internal","weight":311,"values":["o"],"children":{"o":{"type":"internal","weight":311,"values":["d"],"children":{"d":{"type":"leaf","weight":311,"entries":[{"key":"methods","weight":311,"content":"methods"},{"key":"method","weight":309,"content":"method"}]}}}}},"\ufdd0":{"type":"leaf","weight":251,"entries":[{"key":"met","weight":251,"content":"met"}]}}},"r":{"type":"leaf","weight":274,"entries":[{"key":"merely","weight":274,"content":"merely"}]}}},"u":{"type":"internal","weight":910,"values":["s","c"],"children":{"s":{"type":"internal","weight":910,"values":["t","i"],"children":{"t":{"type":"leaf","weight":910,"entries":[{"key":"must","weight":910,"content":"must"}]},"i":{"type":"leaf","weight":581,"entries":[{"key":"music","weight":581,"content":"music"}]}}},"c":{"type":"leaf","weight":905,"entries":[{"key":"much","weight":905,"content":"much"}]}}},"i":{"type":"internal","weight":864,"values":["g","n","s","l","d"],"children":{"g":{"type":"leaf","weight":864,"entries":[{"key":"might","weight":864,"content":"might"}]},"n":{"type":"internal","weight":726,"values":["d","u"],"children":{"d":{"type":"leaf","weight":726,"entries":[{"key":"mind","weight":726,"content":"mind"}]},"u":{"type":"leaf","weight":523,"entries":[{"key":"minutes","weight":523,"content":"minutes"}]}}},"s":{"type":"leaf","weight":639,"entries":[{"key":"miss","weight":639,"content":"miss"}]},"l":{"type":"internal","weight":565,"values":["i","l","e"],"children":{"i":{"type":"leaf","weight":565,"entries":[{"key":"military","weight":565,"content":"military"}]},"l":{"type":"leaf","weight":547,"entries":[{"key":"million","weight":547,"content":"million"}]},"e":{"type":"leaf","weight":450,"entries":[{"key":"miles","weight":450,"content":"miles"}]}}},"d":{"type":"leaf","weight":144,"entries":[{"key":"middle","weight":144,"content":"middle"}]}}}}},"u":{"type":"internal","weight":946,"values":["p","n","s"],"children":{"p":{"type":"internal","weight":946,"values":["\ufdd0","o"],"children":{"\ufdd0":{"type":"leaf","weight":946,"entries":[{"key":"up","weight":946,"content":"up"}]},"o":{"type":"leaf","weight":828,"entries":[{"key":"upon","weight":828,"content":"upon"}]}}},"n":{"type":"internal","weight":873,"values":["d","i","t"],"children":{"d":{"type":"internal","weight":873,"values":["e"],"children":{"e":{"type":"internal","weight":873,"values":["r"],"children":{"r":{"type":"internal","weight":873,"values":["\ufdd0","s"],"children":{"\ufdd0":{"type":"leaf","weight":873,"entries":[{"key":"under","weight":873,"content":"under"}]},"s":{"type":"internal","weight":283,"values":["t"],"children":{"t":{"type":"internal","weight":283,"values":["a"],"children":{"a":{"type":"internal","weight":283,"values":["n"],"children":{"n":{"type":"internal","weight":283,"values":["d"],"children":{"d":{"type":"internal","weight":283,"values":["\ufdd0","i"],"children":{"\ufdd0":{"type":"leaf","weight":283,"entries":[{"key":"understand","weight":283,"content":"understand"}]},"i":{"type":"leaf","weight":170,"entries":[{"key":"understanding","weight":170,"content":"understanding"}]}}}}}}}}}}}}}}}}},"i":{"type":"internal","weight":823,"values":["t","v","o"],"children":{"t":{"type":"leaf","weight":823,"entries":[{"key":"united","weight":823,"content":"united"},{"key":"unit","weight":10,"content":"unit"}]},"v":{"type":"leaf","weight":575,"entries":[{"key":"university","weight":575,"content":"university"}]},"o":{"type":"leaf","weight":483,"entries":[{"key":"union","weight":483,"content":"union"}]}}},"t":{"type":"leaf","weight":818,"entries":[{"key":"until","weight":818,"content":"until"}]}}},"s":{"type":"internal","weight":865,"values":["\ufdd0","e","u","i"],"children":{"\ufdd0":{"type":"leaf","weight":865,"entries":[{"key":"us","weight":865,"content":"us"}]},"e":{"type":"leaf","weight":853,"entries":[{"key":"used","weight":853,"content":"used"},{"key":"use","weight":847,"content":"use"}]},"u":{"type":"leaf","weight":556,"entries":[{"key":"usually","weight":556,"content":"usually"}]},"i":{"type":"leaf","weight":330,"entries":[{"key":"using","weight":330,"content":"using"}]}}}}},"c":{"type":"internal","weight":940,"values":["a","o","i","h","e","l","u","\ufdd0"],"children":{"a":{"type":"internal","weight":940,"values":["n","m","l","s","r","u"],"children":{"n":{"type":"internal","weight":940,"values":["\ufdd0","n"],"children":{"\ufdd0":{"type":"leaf","weight":940,"entries":[{"key":"can","weight":940,"content":"can"}]},"n":{"type":"leaf","weight":646,"entries":[{"key":"cannot","weight":646,"content":"cannot"}]}}},"m":{"type":"leaf","weight":855,"entries":[{"key":"came","weight":855,"content":"came"}]},"l":{"type":"internal","weight":791,"values":["l"],"children":{"l":{"type":"leaf","weight":791,"entries":[{"key":"called","weight":791,"content":"called"},{"key":"call","weight":500,"content":"call"}]}}},"s":{"type":"internal","weight":750,"values":["e"],"children":{"e":{"type":"internal","weight":750,"values":["\ufdd0","s"],"children":{"\ufdd0":{"type":"leaf","weight":750,"entries":[{"key":"case","weight":750,"content":"case"}]},"s":{"type":"leaf","weight":350,"entries":[{"key":"cases","weight":350,"content":"cases"}]}}}}},"r":{"type":"internal","weight":667,"values":["\ufdd0","e","r","s"],"children":{"\ufdd0":{"type":"leaf","weight":667,"entries":[{"key":"car","weight":667,"content":"car"}]},"e":{"type":"leaf","weight":407,"entries":[{"key":"care","weight":407,"content":"care"}]},"r":{"type":"leaf","weight":200,"entries":[{"key":"carried","weight":200,"content":"carried"}]},"s":{"type":"leaf","weight":90,"entries":[{"key":"cars","weight":90,"content":"cars"}]}}},"u":{"type":"leaf","weight":236,"entries":[{"key":"cause","weight":236,"content":"cause"}]}}},"o":{"type":"internal","weight":935,"values":["u","m","l","s","n","r","v"],"children":{"u":{"type":"internal","weight":935,"values":["l","r","n","p"],"children":{"l":{"type":"leaf","weight":935,"entries":[{"key":"could","weight":935,"content":"could"}]},"r":{"type":"internal","weight":820,"values":["s","t"],"children":{"s":{"type":"leaf","weight":820,"entries":[{"key":"course","weight":820,"content":"course"}]},"t":{"type":"leaf","weight":604,"entries":[{"key":"court","weight":604,"content":"court"}]}}},"n":{"type":"internal","weight":723,"values":["t","c"],"children":{"t":{"type":"internal","weight":723,"values":["r","y"],"children":{"r":{"type":"internal","weight":723,"values":["y","i"],"children":{"y":{"type":"leaf","weight":723,"entries":[{"key":"country","weight":723,"content":"country"}]},"i":{"type":"leaf","weight":360,"entries":[{"key":"countries","weight":360,"content":"countries"}]}}},"y":{"type":"leaf","weight":378,"entries":[{"key":"county","weight":378,"content":"county"}]}}},"c":{"type":"leaf","weight":11,"entries":[{"key":"council","weight":11,"content":"council"}]}}},"p":{"type":"leaf","weight":178,"entries":[{"key":"couple","weight":178,"content":"couple"}]}}},"m":{"type":"internal","weight":859,"values":["e","p","m","i"],"children":{"e":{"type":"internal","weight":859,"values":["\ufdd0","s"],"children":{"\ufdd0":{"type":"leaf","weight":859,"entries":[{"key":"come","weight":859,"content":"come"}]},"s":{"type":"leaf","weight":279,"entries":[{"key":"comes","weight":279,"content":"comes"}]}}},"p":{"type":"internal","weight":692,"values":["a","l"],"children":{"a":{"type":"leaf","weight":692,"entries":[{"key":"company","weight":692,"content":"company"}]},"l":{"type":"internal","weight":482,"values":["e"],"children":{"e":{"type":"internal","weight":482,"values":["t"],"children":{"t":{"type":"internal","weight":482,"values":["e"],"children":{"e":{"type":"internal","weight":482,"values":["\ufdd0","l"],"children":{"\ufdd0":{"type":"leaf","weight":482,"entries":[{"key":"complete","weight":482,"content":"complete"}]},"l":{"type":"leaf","weight":83,"entries":[{"key":"completely","weight":83,"content":"completely"}]}}}}}}}}}}},"m":{"type":"internal","weight":608,"values":["u","o","i"],"children":{"u":{"type":"leaf","weight":608,"entries":[{"key":"community","weight":608,"content":"community"}]},"o":{"type":"leaf","weight":593,"entries":[{"key":"common","weight":593,"content":"common"}]},"i":{"type":"internal","weight":427,"values":["t","s"],"children":{"t":{"type":"leaf","weight":427,"entries":[{"key":"committee","weight":427,"content":"committee"}]},"s":{"type":"leaf","weight":8,"entries":[{"key":"commission","weight":8,"content":"commission"}]}}}}},"i":{"type":"leaf","weight":456,"entries":[{"key":"coming","weight":456,"content":"coming"}]}}},"l":{"type":"internal","weight":657,"values":["l","d","o"],"children":{"l":{"type":"leaf","weight":657,"entries":[{"key":"college","weight":657,"content":"college"}]},"d":{"type":"leaf","weight":435,"entries":[{"key":"cold","weight":435,"content":"cold"}]},"o":{"type":"leaf","weight":294,"entries":[{"key":"color","weight":294,"content":"color"}]}}},"s":{"type":"internal","weight":602,"values":["t"],"children":{"t":{"type":"internal","weight":602,"values":["\ufdd0","s"],"children":{"\ufdd0":{"type":"leaf","weight":602,"entries":[{"key":"cost","weight":602,"content":"cost"}]},"s":{"type":"leaf","weight":468,"entries":[{"key":"costs","weight":468,"content":"costs"}]}}}}},"n":{"type":"internal","weight":592,"values":["t","d","g","s","c"],"children":{"t":{"type":"internal","weight":592,"values":["r","i"],"children":{"r":{"type":"leaf","weight":592,"entries":[{"key":"control","weight":592,"content":"control"}]},"i":{"type":"internal","weight":258,"values":["n"],"children":{"n":{"type":"internal","weight":258,"values":["u"],"children":{"u":{"type":"internal","weight":258,"values":["e"],"children":{"e":{"type":"leaf","weight":258,"entries":[{"key":"continued","weight":258,"content":"continued"},{"key":"continue","weight":54,"content":"continue"}]}}}}}}}}},"d":{"type":"leaf","weight":476,"entries":[{"key":"conditions","weight":476,"content":"conditions"}]},"g":{"type":"leaf","weight":364,"entries":[{"key":"congress","weight":364,"content":"congress"}]},"s":{"type":"internal","weight":361,"values":["i"],"children":{"i":{"type":"internal","weight":361,"values":["d"],"children":{"d":{"type":"internal","weight":361,"values":["e"],"children":{"e":{"type":"internal","weight":361,"values":["r"],"children":{"r":{"type":"leaf","weight":361,"entries":[{"key":"considered","weight":361,"content":"considered"},{"key":"consider","weight":212,"content":"consider"}]}}}}}}}}},"c":{"type":"leaf","weight":273,"entries":[{"key":"concerned","weight":273,"content":"concerned"}]}}},"r":{"type":"internal","weight":120,"values":["n","p"],"children":{"n":{"type":"leaf","weight":120,"entries":[{"key":"corner","weight":120,"content":"corner"}]},"p":{"type":"leaf","weight":76,"entries":[{"key":"corps","weight":76,"content":"corps"}]}}},"v":{"type":"leaf","weight":19,"entries":[{"key":"covered","weight":19,"content":"covered"}]}}},"i":{"type":"internal","weight":780,"values":["t"],"children":{"t":{"type":"internal","weight":780,"values":["y","i"],"children":{"y":{"type":"leaf","weight":780,"entries":[{"key":"city","weight":780,"content":"city"}]},"i":{"type":"leaf","weight":44,"entries":[{"key":"cities","weight":44,"content":"cities"}]}}}}},"h":{"type":"internal","weight":740,"values":["i","u","a","r","o"],"children":{"i":{"type":"internal","weight":740,"values":["l","e"],"children":{"l":{"type":"internal","weight":740,"values":["d"],"children":{"d":{"type":"leaf","weight":740,"entries":[{"key":"children","weight":740,"content":"children"},{"key":"child","weight":569,"content":"child"}]}}},"e":{"type":"leaf","weight":151,"entries":[{"key":"chief","weight":151,"content":"chief"}]}}},"u":{"type":"leaf","weight":737,"entries":[{"key":"church","weight":737,"content":"church"}]},"a":{"type":"internal","weight":619,"values":["n","r"],"children":{"n":{"type":"internal","weight":619,"values":["g","c"],"children":{"g":{"type":"internal","weight":619,"values":["e"],"children":{"e":{"type":"internal","weight":619,"values":["\ufdd0","s"],"children":{"\ufdd0":{"type":"leaf","weight":619,"entries":[{"key":"change","weight":619,"content":"change"}]},"s":{"type":"leaf","weight":248,"entries":[{"key":"changes","weight":248,"content":"changes"}]}}}}},"c":{"type":"leaf","weight":245,"entries":[{"key":"chance","weight":245,"content":"chance"}]}}},"r":{"type":"internal","weight":179,"values":["g","a"],"children":{"g":{"type":"leaf","weight":179,"entries":[{"key":"charge","weight":179,"content":"charge"}]},"a":{"type":"leaf","weight":145,"entries":[{"key":"character","weight":145,"content":"character"}]}}}}},"r":{"type":"leaf","weight":327,"entries":[{"key":"christian","weight":327,"content":"christian"}]},"o":{"type":"leaf","weight":104,"entries":[{"key":"choice","weight":104,"content":"choice"}]}}},"e":{"type":"internal","weight":713,"values":["r","n"],"children":{"r":{"type":"internal","weight":713,"values":["t"],"children":{"t":{"type":"internal","weight":713,"values":["a"],"children":{"a":{"type":"internal","weight":713,"values":["i"],"children":{"i":{"type":"internal","weight":713,"values":["n"],"children":{"n":{"type":"internal","weight":713,"values":["\ufdd0","l"],"children":{"\ufdd0":{"type":"leaf","weight":713,"entries":[{"key":"certain","weight":713,"content":"certain"}]},"l":{"type":"leaf","weight":318,"entries":[{"key":"certainly","weight":318,"content":"certainly"}]}}}}}}}}}}},"n":{"type":"internal","weight":595,"values":["t"],"children":{"t":{"type":"internal","weight":595,"values":["e","u","r","\ufdd0"],"children":{"e":{"type":"leaf","weight":595,"entries":[{"key":"center","weight":595,"content":"center"}]},"u":{"type":"leaf","weight":557,"entries":[{"key":"century","weight":557,"content":"century"}]},"r":{"type":"leaf","weight":420,"entries":[{"key":"central","weight":420,"content":"central"}]},"\ufdd0":{"type":"leaf","weight":379,"entries":[{"key":"cent","weight":379,"content":"cent"}]}}}}}}},"l":{"type":"internal","weight":611,"values":["o","e","a","u"],"children":{"o":{"type":"internal","weight":611,"values":["s"],"children":{"s":{"type":"internal","weight":611,"values":["e"],"children":{"e":{"type":"internal","weight":611,"values":["\ufdd0","d"],"children":{"\ufdd0":{"type":"leaf","weight":611,"entries":[{"key":"close","weight":611,"content":"close"}]},"d":{"type":"leaf","weight":37,"entries":[{"key":"closed","weight":37,"content":"closed"}]}}}}}}},"e":{"type":"internal","weight":584,"values":["a"],"children":{"a":{"type":"internal","weight":584,"values":["r"],"children":{"r":{"type":"internal","weight":584,"values":["\ufdd0","l"],"children":{"\ufdd0":{"type":"leaf","weight":584,"entries":[{"key":"clear","weight":584,"content":"clear"}]},"l":{"type":"leaf","weight":218,"entries":[{"key":"clearly","weight":218,"content":"clearly"}]}}}}}}},"a":{"type":"leaf","weight":558,"entries":[{"key":"class","weight":558,"content":"class"}]},"u":{"type":"leaf","weight":336,"entries":[{"key":"club","weight":336,"content":"club"}]}}},"u":{"type":"internal","weight":509,"values":["t","r"],"children":{"t":{"type":"leaf","weight":509,"entries":[{"key":"cut","weight":509,"content":"cut"}]},"r":{"type":"leaf","weight":15,"entries":[{"key":"current","weight":15,"content":"current"}]}}},"\ufdd0":{"type":"leaf","weight":171,"entries":[{"key":"c","weight":171,"content":"c"}]}}},"d":{"type":"internal","weight":929,"values":["o","i","a","u","e","r"],"children":{"o":{"type":"internal","weight":929,"values":["\ufdd0","w","e","n","o","i","u"],"children":{"\ufdd0":{"type":"leaf","weight":929,"entries":[{"key":"do","weight":929,"content":"do"}]},"w":{"type":"leaf","weight":900,"entries":[{"key":"down","weight":900,"content":"down"}]},"e":{"type":"leaf","weight":825,"entries":[{"key":"does","weight":825,"content":"does"}]},"n":{"type":"leaf","weight":719,"entries":[{"key":"done","weight":719,"content":"done"}]},"o":{"type":"leaf","weight":709,"entries":[{"key":"door","weight":709,"content":"door"}]},"i":{"type":"leaf","weight":410,"entries":[{"key":"doing","weight":410,"content":"doing"}]},"u":{"type":"leaf","weight":116,"entries":[{"key":"doubt","weight":116,"content":"doubt"}]}}},"i":{"type":"internal","weight":913,"values":["d","f","r","s","v"],"children":{"d":{"type":"leaf","weight":913,"entries":[{"key":"did","weight":913,"content":"did"}]},"f":{"type":"internal","weight":712,"values":["f"],"children":{"f":{"type":"internal","weight":712,"values":["e","i"],"children":{"e":{"type":"internal","weight":712,"values":["r"],"children":{"r":{"type":"internal","weight":712,"values":["e"],"children":{"e":{"type":"internal","weight":712,"values":["n"],"children":{"n":{"type":"internal","weight":712,"values":["t","c"],"children":{"t":{"type":"leaf","weight":712,"entries":[{"key":"different","weight":712,"content":"different"}]},"c":{"type":"leaf","weight":351,"entries":[{"key":"difference","weight":351,"content":"difference"}]}}}}}}}}},"i":{"type":"leaf","weight":399,"entries":[{"key":"difficult","weight":399,"content":"difficult"}]}}}}},"r":{"type":"internal","weight":304,"values":["e"],"children":{"e":{"type":"internal","weight":304,"values":["c"],"children":{"c":{"type":"internal","weight":304,"values":["t"],"children":{"t":{"type":"internal","weight":304,"values":["l","i","\ufdd0"],"children":{"l":{"type":"leaf","weight":304,"entries":[{"key":"directly","weight":304,"content":"directly"}]},"i":{"type":"leaf","weight":269,"entries":[{"key":"direction","weight":269,"content":"direction"}]},"\ufdd0":{"type":"leaf","weight":234,"entries":[{"key":"direct","weight":234,"content":"direct"}]}}}}}}}}},"s":{"type":"internal","weight":272,"values":["t"],"children":{"t":{"type":"internal","weight":272,"values":["r","a"],"children":{"r":{"type":"leaf","weight":272,"entries":[{"key":"district","weight":272,"content":"district"}]},"a":{"type":"leaf","weight":60,"entries":[{"key":"distance","weight":60,"content":"distance"}]}}}}},"v":{"type":"leaf","weight":55,"entries":[{"key":"division","weight":55,"content":"division"}]}}},"a":{"type":"internal","weight":871,"values":["y","r","t","i"],"children":{"y":{"type":"internal","weight":871,"values":["\ufdd0","s"],"children":{"\ufdd0":{"type":"leaf","weight":871,"entries":[{"key":"day","weight":871,"content":"day"}]},"s":{"type":"leaf","weight":772,"entries":[{"key":"days","weight":772,"content":"days"}]}}},"r":{"type":"leaf","weight":490,"entries":[{"key":"dark","weight":490,"content":"dark"}]},"t":{"type":"internal","weight":447,"values":["a","e"],"children":{"a":{"type":"leaf","weight":447,"entries":[{"key":"data","weight":447,"content":"data"}]},"e":{"type":"leaf","weight":7,"entries":[{"key":"date","weight":7,"content":"date"}]}}},"i":{"type":"leaf","weight":180,"entries":[{"key":"daily","weight":180,"content":"daily"}]}}},"u":{"type":"internal","weight":845,"values":["r","e"],"children":{"r":{"type":"leaf","weight":845,"entries":[{"key":"during","weight":845,"content":"during"}]},"e":{"type":"leaf","weight":312,"entries":[{"key":"due","weight":312,"content":"due"}]}}},"e":{"type":"internal","weight":733,"values":["v","a","p","f","c","g","s","t","e","m","\ufdd0"],"children":{"v":{"type":"internal","weight":733,"values":["e"],"children":{"e":{"type":"internal","weight":733,"values":["l"],"children":{"l":{"type":"internal","weight":733,"values":["o"],"children":{"o":{"type":"internal","weight":733,"values":["p"],"children":{"p":{"type":"internal","weight":733,"values":["m","e"],"children":{"m":{"type":"leaf","weight":733,"entries":[{"key":"development","weight":733,"content":"development"}]},"e":{"type":"leaf","weight":430,"entries":[{"key":"developed","weight":430,"content":"developed"}]}}}}}}}}}}},"a":{"type":"internal","weight":673,"values":["t","d","l"],"children":{"t":{"type":"leaf","weight":673,"entries":[{"key":"death","weight":673,"content":"death"}]},"d":{"type":"leaf","weight":458,"entries":[{"key":"dead","weight":458,"content":"dead"}]},"l":{"type":"leaf","weight":321,"entries":[{"key":"deal","weight":321,"content":"deal"}]}}},"p":{"type":"leaf","weight":596,"entries":[{"key":"department","weight":596,"content":"department"}]},"f":{"type":"leaf","weight":426,"entries":[{"key":"defense","weight":426,"content":"defense"}]},"c":{"type":"internal","weight":301,"values":["i"],"children":{"i":{"type":"internal","weight":301,"values":["d","s"],"children":{"d":{"type":"leaf","weight":301,"entries":[{"key":"decided","weight":301,"content":"decided"}]},"s":{"type":"leaf","weight":148,"entries":[{"key":"decision","weight":148,"content":"decision"}]}}}}},"g":{"type":"leaf","weight":193,"entries":[{"key":"degree","weight":193,"content":"degree"}]},"\ufdd0":{"type":"leaf","weight":173,"entries":[{"key":"de","weight":173,"content":"de"}]},"s":{"type":"internal","weight":163,"values":["c","i","p"],"children":{"c":{"type":"leaf","weight":163,"entries":[{"key":"described","weight":163,"content":"described"}]},"i":{"type":"internal","weight":108,"values":["g"],"children":{"g":{"type":"internal","weight":108,"values":["n"],"children":{"n":{"type":"internal","weight":108,"values":["\ufdd0","e"],"children":{"\ufdd0":{"type":"leaf","weight":108,"entries":[{"key":"design","weight":108,"content":"design"}]},"e":{"type":"leaf","weight":64,"entries":[{"key":"designed","weight":64,"content":"designed"}]}}}}}}},"p":{"type":"leaf","weight":20,"entries":[{"key":"despite","weight":20,"content":"despite"}]}}},"t":{"type":"internal","weight":147,"values":["e"],"children":{"e":{"type":"internal","weight":147,"values":["r"],"children":{"r":{"type":"internal","weight":147,"values":["m"],"children":{"m":{"type":"internal","weight":147,"values":["i"],"children":{"i":{"type":"internal","weight":147,"values":["n"],"children":{"n":{"type":"internal","weight":147,"values":["e"],"children":{"e":{"type":"leaf","weight":147,"entries":[{"key":"determined","weight":147,"content":"determined"},{"key":"determine","weight":51,"content":"determine"}]}}}}}}}}}}}}},"e":{"type":"leaf","weight":72,"entries":[{"key":"deep","weight":72,"content":"deep"}]},"m":{"type":"leaf","weight":69,"entries":[{"key":"democratic","weight":69,"content":"democratic"}]}}},"r":{"type":"leaf","weight":26,"entries":[{"key":"drive","weight":26,"content":"drive"}]}}},"l":{"type":"internal","weight":923,"values":["i","o","a","e"],"children":{"i":{"type":"internal","weight":923,"values":["k","t","f","g","n","v","s","m"],"children":{"k":{"type":"internal","weight":923,"values":["e"],"children":{"e":{"type":"internal","weight":923,"values":["\ufdd0","l"],"children":{"\ufdd0":{"type":"leaf","weight":923,"entries":[{"key":"like","weight":923,"content":"like"}]},"l":{"type":"leaf","weight":362,"entries":[{"key":"likely","weight":362,"content":"likely"}]}}}}},"t":{"type":"internal","weight":891,"values":["t","e"],"children":{"t":{"type":"leaf","weight":891,"entries":[{"key":"little","weight":891,"content":"little"}]},"e":{"type":"leaf","weight":261,"entries":[{"key":"literature","weight":261,"content":"literature"}]}}},"f":{"type":"leaf","weight":875,"entries":[{"key":"life","weight":875,"content":"life"}]},"g":{"type":"leaf","weight":730,"entries":[{"key":"light","weight":730,"content":"light"}]},"n":{"type":"internal","weight":697,"values":["e"],"children":{"e":{"type":"internal","weight":697,"values":["\ufdd0","s"],"children":{"\ufdd0":{"type":"leaf","weight":697,"entries":[{"key":"line","weight":697,"content":"line"}]},"s":{"type":"leaf","weight":530,"entries":[{"key":"lines","weight":530,"content":"lines"}]}}}}},"v":{"type":"internal","weight":513,"values":["i","e"],"children":{"i":{"type":"leaf","weight":513,"entries":[{"key":"living","weight":513,"content":"living"}]},"e":{"type":"internal","weight":470,"values":["\ufdd0","d"],"children":{"\ufdd0":{"type":"leaf","weight":470,"entries":[{"key":"live","weight":470,"content":"live"}]},"d":{"type":"leaf","weight":122,"entries":[{"key":"lived","weight":122,"content":"lived"}]}}}}},"s":{"type":"leaf","weight":260,"entries":[{"key":"list","weight":260,"content":"list"}]},"m":{"type":"leaf","weight":38,"entries":[{"key":"limited","weight":38,"content":"limited"}]}}},"o":{"type":"internal","weight":880,"values":["n","o","c","v","w","s","t"],"children":{"n":{"type":"internal","weight":880,"values":["g"],"children":{"g":{"type":"internal","weight":880,"values":["\ufdd0","e"],"children":{"\ufdd0":{"type":"leaf","weight":880,"entries":[{"key":"long","weight":880,"content":"long"}]},"e":{"type":"leaf","weight":510,"entries":[{"key":"longer","weight":510,"content":"longer"}]}}}}},"o":{"type":"internal","weight":788,"values":["k"],"children":{"k":{"type":"internal","weight":788,"values":["\ufdd0","e","i"],"children":{"\ufdd0":{"type":"leaf","weight":788,"entries":[{"key":"look","weight":788,"content":"look"}]},"e":{"type":"leaf","weight":753,"entries":[{"key":"looked","weight":753,"content":"looked"}]},"i":{"type":"leaf","weight":448,"entries":[{"key":"looking","weight":448,"content":"looking"}]}}}}},"c":{"type":"leaf","weight":690,"entries":[{"key":"local","weight":690,"content":"local"}]},"v":{"type":"leaf","weight":609,"entries":[{"key":"love","weight":609,"content":"love"}]},"w":{"type":"internal","weight":451,"values":["\ufdd0","e"],"children":{"\ufdd0":{"type":"leaf","weight":451,"entries":[{"key":"low","weight":451,"content":"low"}]},"e":{"type":"leaf","weight":187,"entries":[{"key":"lower","weight":187,"content":"lower"}]}}},"s":{"type":"leaf","weight":449,"entries":[{"key":"lost","weight":449,"content":"lost"}]},"t":{"type":"leaf","weight":207,"entries":[{"key":"lot","weight":207,"content":"lot"}]}}},"a":{"type":"internal","weight":866,"values":["s","t","r","w","n","b","y","c"],"children":{"s":{"type":"leaf","weight":866,"entries":[{"key":"last","weight":866,"content":"last"}]},"t":{"type":"internal","weight":785,"values":["e","t"],"children":{"e":{"type":"leaf","weight":785,"entries":[{"key":"later","weight":785,"content":"later"},{"key":"late","weight":472,"content":"late"}]},"t":{"type":"leaf","weight":115,"entries":[{"key":"latter","weight":115,"content":"latter"}]}}},"r":{"type":"internal","weight":748,"values":["g"],"children":{"g":{"type":"internal","weight":748,"values":["e"],"children":{"e":{"type":"internal","weight":748,"values":["\ufdd0","r"],"children":{"\ufdd0":{"type":"leaf","weight":748,"entries":[{"key":"large","weight":748,"content":"large"}]},"r":{"type":"leaf","weight":182,"entries":[{"key":"larger","weight":182,"content":"larger"}]}}}}}}},"w":{"type":"leaf","weight":698,"entries":[{"key":"law","weight":698,"content":"law"}]},"n":{"type":"internal","weight":582,"values":["d","g"],"children":{"d":{"type":"leaf","weight":582,"entries":[{"key":"land","weight":582,"content":"land"}]},"g":{"type":"leaf","weight":74,"entries":[{"key":"language","weight":74,"content":"language"}]}}},"b":{"type":"leaf","weight":354,"entries":[{"key":"labor","weight":354,"content":"labor"}]},"y":{"type":"leaf","weight":289,"entries":[{"key":"lay","weight":289,"content":"lay"}]},"c":{"type":"leaf","weight":82,"entries":[{"key":"lack","weight":82,"content":"lack"}]}}},"e":{"type":"internal","weight":822,"values":["f","s","t","a","v","d","n"],"children":{"f":{"type":"leaf","weight":822,"entries":[{"key":"left","weight":822,"content":"left"}]},"s":{"type":"leaf","weight":809,"entries":[{"key":"less","weight":809,"content":"less"}]},"t":{"type":"internal","weight":774,"values":["\ufdd0","t"],"children":{"\ufdd0":{"type":"leaf","weight":774,"entries":[{"key":"let","weight":774,"content":"let"}]},"t":{"type":"internal","weight":335,"values":["e"],"children":{"e":{"type":"internal","weight":335,"values":["r"],"children":{"r":{"type":"internal","weight":335,"values":["\ufdd0","s"],"children":{"\ufdd0":{"type":"leaf","weight":335,"entries":[{"key":"letter","weight":335,"content":"letter"}]},"s":{"type":"leaf","weight":128,"entries":[{"key":"letters","weight":128,"content":"letters"}]}}}}}}}}},"a":{"type":"internal","weight":735,"values":["s","v","d","r"],"children":{"s":{"type":"leaf","weight":735,"entries":[{"key":"least","weight":735,"content":"least"}]},"v":{"type":"leaf","weight":553,"entries":[{"key":"leave","weight":553,"content":"leave"}]},"d":{"type":"internal","weight":235,"values":["\ufdd0","e"],"children":{"\ufdd0":{"type":"leaf","weight":235,"entries":[{"key":"lead","weight":235,"content":"lead"}]},"e":{"type":"leaf","weight":53,"entries":[{"key":"leaders","weight":53,"content":"leaders"}]}}},"r":{"type":"leaf","weight":136,"entries":[{"key":"learned","weight":136,"content":"learned"}]}}},"v":{"type":"leaf","weight":573,"entries":[{"key":"level","weight":573,"content":"level"}]},"d":{"type":"leaf","weight":253,"entries":[{"key":"led","weight":253,"content":"led"}]},"n":{"type":"leaf","weight":129,"entries":[{"key":"length","weight":129,"content":"length"}]}}}}},"e":{"type":"internal","weight":918,"values":["v","a","n","y","x","i","c","d","f","l","q","s","u"],"children":{"v":{"type":"internal","weight":918,"values":["e","i"],"children":{"e":{"type":"internal","weight":918,"values":["n","r"],"children":{"n":{"type":"internal","weight":918,"values":["\ufdd0","i"],"children":{"\ufdd0":{"type":"leaf","weight":918,"entries":[{"key":"even","weight":918,"content":"even"}]},"i":{"type":"leaf","weight":257,"entries":[{"key":"evening","weight":257,"content":"evening"}]}}},"r":{"type":"internal","weight":826,"values":["y","\ufdd0"],"children":{"y":{"type":"internal","weight":826,"values":["\ufdd0","t"],"children":{"\ufdd0":{"type":"leaf","weight":826,"entries":[{"key":"every","weight":826,"content":"every"}]},"t":{"type":"leaf","weight":492,"entries":[{"key":"everything","weight":492,"content":"everything"}]}}},"\ufdd0":{"type":"leaf","weight":736,"entries":[{"key":"ever","weight":736,"content":"ever"}]}}}}},"i":{"type":"leaf","weight":549,"entries":[{"key":"evidence","weight":549,"content":"evidence"}]}}},"a":{"type":"internal","weight":897,"values":["c","r","s"],"children":{"c":{"type":"leaf","weight":897,"entries":[{"key":"each","weight":897,"content":"each"}]},"r":{"type":"internal","weight":752,"values":["l","t"],"children":{"l":{"type":"internal","weight":752,"values":["y","i"],"children":{"y":{"type":"leaf","weight":752,"entries":[{"key":"early","weight":752,"content":"early"}]},"i":{"type":"leaf","weight":340,"entries":[{"key":"earlier","weight":340,"content":"earlier"}]}}},"t":{"type":"leaf","weight":359,"entries":[{"key":"earth","weight":359,"content":"earth"}]}}},"s":{"type":"internal","weight":486,"values":["t","y","i"],"children":{"t":{"type":"leaf","weight":486,"entries":[{"key":"east","weight":486,"content":"east"}]},"y":{"type":"leaf","weight":191,"entries":[{"key":"easy","weight":191,"content":"easy"}]},"i":{"type":"leaf","weight":45,"entries":[{"key":"easily","weight":45,"content":"easily"}]}}}}},"n":{"type":"internal","weight":805,"values":["o","d","g","t"],"children":{"o":{"type":"leaf","weight":805,"entries":[{"key":"enough","weight":805,"content":"enough"}]},"d":{"type":"leaf","weight":793,"entries":[{"key":"end","weight":793,"content":"end"}]},"g":{"type":"internal","weight":517,"values":["l"],"children":{"l":{"type":"internal","weight":517,"values":["i","a"],"children":{"i":{"type":"leaf","weight":517,"entries":[{"key":"english","weight":517,"content":"english"}]},"a":{"type":"leaf","weight":375,"entries":[{"key":"england","weight":375,"content":"england"}]}}}}},"t":{"type":"leaf","weight":357,"entries":[{"key":"entire","weight":357,"content":"entire"}]}}},"y":{"type":"internal","weight":790,"values":["e"],"children":{"e":{"type":"leaf","weight":790,"entries":[{"key":"eyes","weight":790,"content":"eyes"},{"key":"eye","weight":177,"content":"eye"}]}}},"x":{"type":"internal","weight":694,"values":["a","p","c","t","i"],"children":{"a":{"type":"internal","weight":694,"values":["m","c"],"children":{"m":{"type":"leaf","weight":694,"entries":[{"key":"example","weight":694,"content":"example"}]},"c":{"type":"leaf","weight":5,"entries":[{"key":"exactly","weight":5,"content":"exactly"}]}}},"p":{"type":"internal","weight":672,"values":["e"],"children":{"e":{"type":"internal","weight":672,"values":["r","c"],"children":{"r":{"type":"leaf","weight":672,"entries":[{"key":"experience","weight":672,"content":"experience"}]},"c":{"type":"internal","weight":497,"values":["t"],"children":{"t":{"type":"leaf","weight":497,"entries":[{"key":"expected","weight":497,"content":"expected"},{"key":"expect","weight":56,"content":"expect"}]}}}}}}},"c":{"type":"leaf","weight":480,"entries":[{"key":"except","weight":480,"content":"except"}]},"t":{"type":"leaf","weight":86,"entries":[{"key":"extent","weight":86,"content":"extent"}]},"i":{"type":"leaf","weight":52,"entries":[{"key":"existence","weight":52,"content":"existence"}]}}},"i":{"type":"internal","weight":684,"values":["t","g"],"children":{"t":{"type":"leaf","weight":684,"entries":[{"key":"either","weight":684,"content":"either"}]},"g":{"type":"leaf","weight":16,"entries":[{"key":"eight","weight":16,"content":"eight"}]}}},"c":{"type":"leaf","weight":624,"entries":[{"key":"economic","weight":624,"content":"economic"}]},"d":{"type":"leaf","weight":574,"entries":[{"key":"education","weight":574,"content":"education"}]},"f":{"type":"internal","weight":570,"values":["f"],"children":{"f":{"type":"internal","weight":570,"values":["e","o"],"children":{"e":{"type":"internal","weight":570,"values":["c"],"children":{"c":{"type":"internal","weight":570,"values":["t"],"children":{"t":{"type":"internal","weight":570,"values":["\ufdd0","i","s"],"children":{"\ufdd0":{"type":"leaf","weight":570,"entries":[{"key":"effect","weight":570,"content":"effect"}]},"i":{"type":"leaf","weight":226,"entries":[{"key":"effective","weight":226,"content":"effective"}]},"s":{"type":"leaf","weight":63,"entries":[{"key":"effects","weight":63,"content":"effects"}]}}}}}}},"o":{"type":"internal","weight":332,"values":["r"],"children":{"r":{"type":"internal","weight":332,"values":["t"],"children":{"t":{"type":"internal","weight":332,"values":["\ufdd0","s"],"children":{"\ufdd0":{"type":"leaf","weight":332,"entries":[{"key":"effort","weight":332,"content":"effort"}]},"s":{"type":"leaf","weight":205,"entries":[{"key":"efforts","weight":205,"content":"efforts"}]}}}}}}}}}}},"l":{"type":"internal","weight":469,"values":["s","e"],"children":{"s":{"type":"leaf","weight":469,"entries":[{"key":"else","weight":469,"content":"else"}]},"e":{"type":"leaf","weight":46,"entries":[{"key":"elements","weight":46,"content":"elements"}]}}},"q":{"type":"leaf","weight":425,"entries":[{"key":"equipment","weight":425,"content":"equipment"}]},"s":{"type":"internal","weight":403,"values":["p","t"],"children":{"p":{"type":"leaf","weight":403,"entries":[{"key":"especially","weight":403,"content":"especially"}]},"t":{"type":"leaf","weight":58,"entries":[{"key":"established","weight":58,"content":"established"}]}}},"u":{"type":"leaf","weight":141,"entries":[{"key":"europe","weight":141,"content":"europe"}]}}},"j":{"type":"internal","weight":896,"values":["u","o"],"children":{"u":{"type":"internal","weight":896,"values":["s"],"children":{"s":{"type":"internal","weight":896,"values":["t"],"children":{"t":{"type":"internal","weight":896,"values":["\ufdd0","i"],"children":{"\ufdd0":{"type":"leaf","weight":896,"entries":[{"key":"just","weight":896,"content":"just"}]},"i":{"type":"leaf","weight":117,"entries":[{"key":"justice","weight":117,"content":"justice"}]}}}}}}},"o":{"type":"internal","weight":749,"values":["h","b"],"children":{"h":{"type":"leaf","weight":749,"entries":[{"key":"john","weight":749,"content":"john"}]},"b":{"type":"leaf","weight":616,"entries":[{"key":"job","weight":616,"content":"job"}]}}}}},"p":{"type":"internal","weight":894,"values":["e","l","a","u","o","r","i","h"],"children":{"e":{"type":"internal","weight":894,"values":["o","r","a"],"children":{"o":{"type":"leaf","weight":894,"entries":[{"key":"people","weight":894,"content":"people"}]},"r":{"type":"internal","weight":759,"values":["\ufdd0","h","i","s","f"],"children":{"\ufdd0":{"type":"leaf","weight":759,"entries":[{"key":"per","weight":759,"content":"per"}]},"h":{"type":"leaf","weight":703,"entries":[{"key":"perhaps","weight":703,"content":"perhaps"}]},"i":{"type":"leaf","weight":655,"entries":[{"key":"period","weight":655,"content":"period"}]},"s":{"type":"internal","weight":524,"values":["o"],"children":{"o":{"type":"internal","weight":524,"values":["n"],"children":{"n":{"type":"internal","weight":524,"values":["a","\ufdd0","s"],"children":{"a":{"type":"leaf","weight":524,"entries":[{"key":"personal","weight":524,"content":"personal"}]},"\ufdd0":{"type":"leaf","weight":455,"entries":[{"key":"person","weight":455,"content":"person"}]},"s":{"type":"leaf","weight":172,"entries":[{"key":"persons","weight":172,"content":"persons"}]}}}}}}},"f":{"type":"leaf","weight":175,"entries":[{"key":"performance","weight":175,"content":"performance"}]}}},"a":{"type":"leaf","weight":531,"entries":[{"key":"peace","weight":531,"content":"peace"}]}}},"l":{"type":"internal","weight":842,"values":["a"],"children":{"a":{"type":"internal","weight":842,"values":["c","n","y"],"children":{"c":{"type":"internal","weight":842,"values":["e"],"children":{"e":{"type":"internal","weight":842,"values":["\ufdd0","d"],"children":{"\ufdd0":{"type":"leaf","weight":842,"entries":[{"key":"place","weight":842,"content":"place"}]},"d":{"type":"leaf","weight":202,"entries":[{"key":"placed","weight":202,"content":"placed"}]}}}}},"n":{"type":"internal","weight":551,"values":["\ufdd0","n","t","e","s"],"children":{"\ufdd0":{"type":"leaf","weight":551,"entries":[{"key":"plan","weight":551,"content":"plan"}]},"n":{"type":"leaf","weight":232,"entries":[{"key":"planning","weight":232,"content":"planning"}]},"t":{"type":"leaf","weight":197,"entries":[{"key":"plant","weight":197,"content":"plant"}]},"e":{"type":"leaf","weight":113,"entries":[{"key":"plane","weight":113,"content":"plane"}]},"s":{"type":"leaf","weight":94,"entries":[{"key":"plans","weight":94,"content":"plans"}]}}},"y":{"type":"internal","weight":537,"values":["\ufdd0","e"],"children":{"\ufdd0":{"type":"leaf","weight":537,"entries":[{"key":"play","weight":537,"content":"play"}]},"e":{"type":"leaf","weight":14,"entries":[{"key":"played","weight":14,"content":"played"}]}}}}}}},"a":{"type":"internal","weight":832,"values":["r","s","y","p","i","t"],"children":{"r":{"type":"internal","weight":832,"values":["t"],"children":{"t":{"type":"internal","weight":832,"values":["\ufdd0","y","i","s"],"children":{"\ufdd0":{"type":"leaf","weight":832,"entries":[{"key":"part","weight":832,"content":"part"}]},"y":{"type":"leaf","weight":577,"entries":[{"key":"party","weight":577,"content":"party"}]},"i":{"type":"internal","weight":474,"values":["c"],"children":{"c":{"type":"internal","weight":474,"values":["u"],"children":{"u":{"type":"internal","weight":474,"values":["l"],"children":{"l":{"type":"internal","weight":474,"values":["a"],"children":{"a":{"type":"internal","weight":474,"values":["r"],"children":{"r":{"type":"internal","weight":474,"values":["\ufdd0","l"],"children":{"\ufdd0":{"type":"leaf","weight":474,"entries":[{"key":"particular","weight":474,"content":"particular"}]},"l":{"type":"leaf","weight":338,"entries":[{"key":"particularly","weight":338,"content":"particularly"}]}}}}}}}}}}}}},"s":{"type":"leaf","weight":98,"entries":[{"key":"parts","weight":98,"content":"parts"}]}}}}},"s":{"type":"internal","weight":677,"values":["t","s"],"children":{"t":{"type":"leaf","weight":677,"entries":[{"key":"past","weight":677,"content":"past"}]},"s":{"type":"leaf","weight":389,"entries":[{"key":"passed","weight":389,"content":"passed"}]}}},"y":{"type":"leaf","weight":441,"entries":[{"key":"pay","weight":441,"content":"pay"}]},"p":{"type":"leaf","weight":387,"entries":[{"key":"paper","weight":387,"content":"paper"}]},"i":{"type":"leaf","weight":329,"entries":[{"key":"paid","weight":329,"content":"paid"}]},"t":{"type":"leaf","weight":101,"entries":[{"key":"pattern","weight":101,"content":"pattern"}]}}},"u":{"type":"internal","weight":811,"values":["b","t","r"],"children":{"b":{"type":"leaf","weight":811,"entries":[{"key":"public","weight":811,"content":"public"}]},"t":{"type":"leaf","weight":810,"entries":[{"key":"put","weight":810,"content":"put"}]},"r":{"type":"leaf","weight":355,"entries":[{"key":"purpose","weight":355,"content":"purpose"}]}}},"o":{"type":"internal","weight":784,"values":["i","s","w","l","p","o"],"children":{"i":{"type":"internal","weight":784,"values":["n"],"children":{"n":{"type":"internal","weight":784,"values":["t"],"children":{"t":{"type":"internal","weight":784,"values":["\ufdd0","s"],"children":{"\ufdd0":{"type":"leaf","weight":784,"entries":[{"key":"point","weight":784,"content":"point"}]},"s":{"type":"leaf","weight":325,"entries":[{"key":"points","weight":325,"content":"points"}]}}}}}}},"s":{"type":"internal","weight":763,"values":["s","i"],"children":{"s":{"type":"leaf","weight":763,"entries":[{"key":"possible","weight":763,"content":"possible"}]},"i":{"type":"leaf","weight":621,"entries":[{"key":"position","weight":621,"content":"position"}]}}},"w":{"type":"leaf","weight":734,"entries":[{"key":"power","weight":734,"content":"power"}]},"l":{"type":"internal","weight":645,"values":["i"],"children":{"i":{"type":"internal","weight":645,"values":["t","c"],"children":{"t":{"type":"leaf","weight":645,"entries":[{"key":"political","weight":645,"content":"political"}]},"c":{"type":"internal","weight":590,"values":["y","e"],"children":{"y":{"type":"leaf","weight":590,"entries":[{"key":"policy","weight":590,"content":"policy"}]},"e":{"type":"leaf","weight":381,"entries":[{"key":"police","weight":381,"content":"police"}]}}}}}}},"p":{"type":"leaf","weight":276,"entries":[{"key":"population","weight":276,"content":"population"}]},"o":{"type":"internal","weight":95,"values":["r","l"],"children":{"r":{"type":"leaf","weight":95,"entries":[{"key":"poor","weight":95,"content":"poor"}]},"l":{"type":"leaf","weight":87,"entries":[{"key":"pool","weight":87,"content":"pool"}]}}}}},"r":{"type":"internal","weight":781,"values":["o","e","i"],"children":{"o":{"type":"internal","weight":781,"values":["g","b","v","c","p","d","f"],"children":{"g":{"type":"internal","weight":781,"values":["r"],"children":{"r":{"type":"internal","weight":781,"values":["a","e"],"children":{"a":{"type":"internal","weight":781,"values":["m"],"children":{"m":{"type":"internal","weight":781,"values":["\ufdd0","s"],"children":{"\ufdd0":{"type":"leaf","weight":781,"entries":[{"key":"program","weight":781,"content":"program"}]},"s":{"type":"leaf","weight":292,"entries":[{"key":"programs","weight":292,"content":"programs"}]}}}}},"e":{"type":"leaf","weight":165,"entries":[{"key":"progress","weight":165,"content":"progress"}]}}}}},"b":{"type":"internal","weight":715,"values":["l","a"],"children":{"l":{"type":"internal","weight":715,"values":["e"],"children":{"e":{"type":"internal","weight":715,"values":["m"],"children":{"m":{"type":"internal","weight":715,"values":["\ufdd0","s"],"children":{"\ufdd0":{"type":"leaf","weight":715,"entries":[{"key":"problem","weight":715,"content":"problem"}]},"s":{"type":"leaf","weight":636,"entries":[{"key":"problems","weight":636,"content":"problems"}]}}}}}}},"a":{"type":"leaf","weight":651,"entries":[{"key":"probably","weight":651,"content":"probably"}]}}},"v":{"type":"internal","weight":576,"values":["i"],"children":{"i":{"type":"internal","weight":576,"values":["d"],"children":{"d":{"type":"internal","weight":576,"values":["e"],"children":{"e":{"type":"internal","weight":576,"values":["\ufdd0","d"],"children":{"\ufdd0":{"type":"leaf","weight":576,"entries":[{"key":"provide","weight":576,"content":"provide"}]},"d":{"type":"leaf","weight":252,"entries":[{"key":"provided","weight":252,"content":"provided"}]}}}}}}}}},"c":{"type":"leaf","weight":522,"entries":[{"key":"process","weight":522,"content":"process"}]},"p":{"type":"leaf","weight":383,"entries":[{"key":"property","weight":383,"content":"property"}]},"d":{"type":"internal","weight":346,"values":["u"],"children":{"u":{"type":"internal","weight":346,"values":["c"],"children":{"c":{"type":"internal","weight":346,"values":["t"],"children":{"t":{"type":"internal","weight":346,"values":["i","s"],"children":{"i":{"type":"leaf","weight":346,"entries":[{"key":"production","weight":346,"content":"production"}]},"s":{"type":"leaf","weight":57,"entries":[{"key":"products","weight":57,"content":"products"}]}}}}}}}}},"f":{"type":"leaf","weight":29,"entries":[{"key":"professional","weight":29,"content":"professional"}]}}},"e":{"type":"internal","weight":771,"values":["s","t"],"children":{"s":{"type":"internal","weight":771,"values":["i","e","s"],"children":{"i":{"type":"leaf","weight":771,"entries":[{"key":"president","weight":771,"content":"president"}]},"e":{"type":"leaf","weight":767,"entries":[{"key":"present","weight":767,"content":"present"}]},"s":{"type":"leaf","weight":491,"entries":[{"key":"pressure","weight":491,"content":"pressure"},{"key":"press","weight":208,"content":"press"}]}}},"t":{"type":"leaf","weight":47,"entries":[{"key":"pretty","weight":47,"content":"pretty"}]}}},"i":{"type":"internal","weight":507,"values":["v","n","c"],"children":{"v":{"type":"leaf","weight":507,"entries":[{"key":"private","weight":507,"content":"private"}]},"n":{"type":"leaf","weight":70,"entries":[{"key":"principle","weight":70,"content":"principle"}]},"c":{"type":"leaf","weight":62,"entries":[{"key":"price","weight":62,"content":"price"}]}}}}},"i":{"type":"internal","weight":404,"values":["c","e"],"children":{"c":{"type":"leaf","weight":404,"entries":[{"key":"picture","weight":404,"content":"picture"}]},"e":{"type":"leaf","weight":228,"entries":[{"key":"piece","weight":228,"content":"piece"}]}}},"h":{"type":"leaf","weight":286,"entries":[{"key":"physical","weight":286,"content":"physical"}]}}},"g":{"type":"internal","weight":889,"values":["o","e","r","i","a","u"],"children":{"o":{"type":"internal","weight":889,"values":["o","\ufdd0","t","v","i","d","n"],"children":{"o":{"type":"leaf","weight":889,"entries":[{"key":"good","weight":889,"content":"good"}]},"\ufdd0":{"type":"leaf","weight":856,"entries":[{"key":"go","weight":856,"content":"go"}]},"t":{"type":"leaf","weight":824,"entries":[{"key":"got","weight":824,"content":"got"}]},"v":{"type":"leaf","weight":800,"entries":[{"key":"government","weight":800,"content":"government"}]},"i":{"type":"leaf","weight":787,"entries":[{"key":"going","weight":787,"content":"going"}]},"d":{"type":"leaf","weight":717,"entries":[{"key":"god","weight":717,"content":"god"}]},"n":{"type":"leaf","weight":515,"entries":[{"key":"gone","weight":515,"content":"gone"}]}}},"e":{"type":"internal","weight":878,"values":["t","n","o"],"children":{"t":{"type":"internal","weight":878,"values":["\ufdd0","t"],"children":{"\ufdd0":{"type":"leaf","weight":878,"entries":[{"key":"get","weight":878,"content":"get"}]},"t":{"type":"leaf","weight":417,"entries":[{"key":"getting","weight":417,"content":"getting"}]}}},"n":{"type":"internal","weight":830,"values":["e"],"children":{"e":{"type":"internal","weight":830,"values":["r"],"children":{"r":{"type":"internal","weight":830,"values":["a"],"children":{"a":{"type":"internal","weight":830,"values":["l"],"children":{"l":{"type":"internal","weight":830,"values":["\ufdd0","l"],"children":{"\ufdd0":{"type":"leaf","weight":830,"entries":[{"key":"general","weight":830,"content":"general"}]},"l":{"type":"leaf","weight":255,"entries":[{"key":"generally","weight":255,"content":"generally"}]}}}}}}}}}}},"o":{"type":"leaf","weight":225,"entries":[{"key":"george","weight":225,"content":"george"}]}}},"r":{"type":"internal","weight":863,"values":["e","o"],"children":{"e":{"type":"internal","weight":863,"values":["a","e"],"children":{"a":{"type":"internal","weight":863,"values":["t"],"children":{"t":{"type":"internal","weight":863,"values":["\ufdd0","e"],"children":{"\ufdd0":{"type":"leaf","weight":863,"entries":[{"key":"great","weight":863,"content":"great"}]},"e":{"type":"leaf","weight":501,"entries":[{"key":"greater","weight":501,"content":"greater"}]}}}}},"e":{"type":"leaf","weight":130,"entries":[{"key":"green","weight":130,"content":"green"}]}}},"o":{"type":"internal","weight":778,"values":["u","w"],"children":{"u":{"type":"internal","weight":778,"values":["p","n"],"children":{"p":{"type":"internal","weight":778,"values":["\ufdd0","s"],"children":{"\ufdd0":{"type":"leaf","weight":778,"entries":[{"key":"group","weight":778,"content":"group"}]},"s":{"type":"leaf","weight":194,"entries":[{"key":"groups","weight":194,"content":"groups"}]}}},"n":{"type":"leaf","weight":493,"entries":[{"key":"ground","weight":493,"content":"ground"}]}}},"w":{"type":"internal","weight":376,"values":["t","i"],"children":{"t":{"type":"leaf","weight":376,"entries":[{"key":"growth","weight":376,"content":"growth"}]},"i":{"type":"leaf","weight":66,"entries":[{"key":"growing","weight":66,"content":"growing"}]}}}}}}},"i":{"type":"internal","weight":777,"values":["v","r"],"children":{"v":{"type":"internal","weight":777,"values":["e"],"children":{"e":{"type":"internal","weight":777,"values":["\ufdd0","n","s"],"children":{"\ufdd0":{"type":"leaf","weight":777,"entries":[{"key":"give","weight":777,"content":"give"}]},"n":{"type":"leaf","weight":768,"entries":[{"key":"given","weight":768,"content":"given"}]},"s":{"type":"leaf","weight":112,"entries":[{"key":"gives","weight":112,"content":"gives"}]}}}}},"r":{"type":"internal","weight":586,"values":["l"],"children":{"l":{"type":"internal","weight":586,"values":["\ufdd0","s"],"children":{"\ufdd0":{"type":"leaf","weight":586,"entries":[{"key":"girl","weight":586,"content":"girl"}]},"s":{"type":"leaf","weight":310,"entries":[{"key":"girls","weight":310,"content":"girls"}]}}}}}}},"a":{"type":"internal","weight":685,"values":["v","m"],"children":{"v":{"type":"leaf","weight":685,"entries":[{"key":"gave","weight":685,"content":"gave"}]},"m":{"type":"leaf","weight":183,"entries":[{"key":"game","weight":183,"content":"game"}]}}},"u":{"type":"leaf","weight":140,"entries":[{"key":"gun","weight":140,"content":"gun"}]}}},"v":{"type":"internal","weight":888,"values":["e","o","a","i"],"children":{"e":{"type":"leaf","weight":888,"entries":[{"key":"very","weight":888,"content":"very"}]},"o":{"type":"internal","weight":597,"values":["i","l"],"children":{"i":{"type":"leaf","weight":597,"entries":[{"key":"voice","weight":597,"content":"voice"}]},"l":{"type":"leaf","weight":271,"entries":[{"key":"volume","weight":271,"content":"volume"}]}}},"a":{"type":"internal","weight":543,"values":["r","l"],"children":{"r":{"type":"leaf","weight":543,"entries":[{"key":"various","weight":543,"content":"various"}]},"l":{"type":"internal","weight":539,"values":["u"],"children":{"u":{"type":"internal","weight":539,"values":["e"],"children":{"e":{"type":"internal","weight":539,"values":["\ufdd0","s"],"children":{"\ufdd0":{"type":"leaf","weight":539,"entries":[{"key":"value","weight":539,"content":"value"}]},"s":{"type":"leaf","weight":495,"entries":[{"key":"values","weight":495,"content":"values"}]}}}}}}}}},"i":{"type":"internal","weight":496,"values":["e","s"],"children":{"e":{"type":"leaf","weight":496,"entries":[{"key":"view","weight":496,"content":"view"}]},"s":{"type":"leaf","weight":75,"entries":[{"key":"visit","weight":75,"content":"visit"}]}}}}},"k":{"type":"internal","weight":868,"values":["n","i","e"],"children":{"n":{"type":"internal","weight":868,"values":["o","e"],"children":{"o":{"type":"internal","weight":868,"values":["w"],"children":{"w":{"type":"internal","weight":868,"values":["\ufdd0","n","l"],"children":{"\ufdd0":{"type":"leaf","weight":868,"entries":[{"key":"know","weight":868,"content":"know"}]},"n":{"type":"leaf","weight":628,"entries":[{"key":"known","weight":628,"content":"known"}]},"l":{"type":"leaf","weight":334,"entries":[{"key":"knowledge","weight":334,"content":"knowledge"}]}}}}},"e":{"type":"leaf","weight":783,"entries":[{"key":"knew","weight":783,"content":"knew"}]}}},"i":{"type":"leaf","weight":714,"entries":[{"key":"kind","weight":714,"content":"kind"}]},"e":{"type":"internal","weight":654,"values":["e","p","n"],"children":{"e":{"type":"leaf","weight":654,"entries":[{"key":"keep","weight":654,"content":"keep"}]},"p":{"type":"leaf","weight":494,"entries":[{"key":"kept","weight":494,"content":"kept"}]},"n":{"type":"leaf","weight":293,"entries":[{"key":"kennedy","weight":293,"content":"kennedy"}]}}}}},"r":{"type":"internal","weight":854,"values":["i","o","a","e","u","h"],"children":{"i":{"type":"internal","weight":854,"values":["g","v"],"children":{"g":{"type":"leaf","weight":854,"entries":[{"key":"right","weight":854,"content":"right"}]},"v":{"type":"leaf","weight":418,"entries":[{"key":"river","weight":418,"content":"river"}]}}},"o":{"type":"internal","weight":773,"values":["o","a","l"],"children":{"o":{"type":"leaf","weight":773,"entries":[{"key":"room","weight":773,"content":"room"}]},"a":{"type":"leaf","weight":527,"entries":[{"key":"road","weight":527,"content":"road"}]},"l":{"type":"leaf","weight":18,"entries":[{"key":"role","weight":18,"content":"role"}]}}},"a":{"type":"internal","weight":762,"values":["t","n","d","c"],"children":{"t":{"type":"internal","weight":762,"values":["h","e"],"children":{"h":{"type":"leaf","weight":762,"entries":[{"key":"rather","weight":762,"content":"rather"}]},"e":{"type":"leaf","weight":561,"entries":[{"key":"rate","weight":561,"content":"rate"}]}}},"n":{"type":"leaf","weight":386,"entries":[{"key":"range","weight":386,"content":"range"},{"key":"ran","weight":264,"content":"ran"}]},"d":{"type":"leaf","weight":159,"entries":[{"key":"radio","weight":159,"content":"radio"}]},"c":{"type":"leaf","weight":2,"entries":[{"key":"race","weight":2,"content":"race"}]}}},"e":{"type":"internal","weight":670,"values":["a","s","d","q","t","c","p","l","m"],"children":{"a":{"type":"internal","weight":670,"values":["l","s","d","c"],"children":{"l":{"type":"leaf","weight":670,"entries":[{"key":"really","weight":670,"content":"really"},{"key":"real","weight":647,"content":"real"}]},"s":{"type":"internal","weight":622,"values":["o"],"children":{"o":{"type":"internal","weight":622,"values":["n"],"children":{"n":{"type":"internal","weight":622,"values":["\ufdd0","s"],"children":{"\ufdd0":{"type":"leaf","weight":622,"entries":[{"key":"reason","weight":622,"content":"reason"}]},"s":{"type":"leaf","weight":12,"entries":[{"key":"reasons","weight":12,"content":"reasons"}]}}}}}}},"d":{"type":"internal","weight":457,"values":["\ufdd0","y","i"],"children":{"\ufdd0":{"type":"leaf","weight":457,"entries":[{"key":"read","weight":457,"content":"read"}]},"y":{"type":"leaf","weight":320,"entries":[{"key":"ready","weight":320,"content":"ready"}]},"i":{"type":"leaf","weight":300,"entries":[{"key":"reading","weight":300,"content":"reading"}]}}},"c":{"type":"internal","weight":429,"values":["h","t"],"children":{"h":{"type":"leaf","weight":429,"entries":[{"key":"reached","weight":429,"content":"reached"},{"key":"reach","weight":27,"content":"reach"}]},"t":{"type":"leaf","weight":189,"entries":[{"key":"reaction","weight":189,"content":"reaction"}]}}}}},"s":{"type":"internal","weight":625,"values":["u","e","t","p"],"children":{"u":{"type":"internal","weight":625,"values":["l"],"children":{"l":{"type":"internal","weight":625,"values":["t"],"children":{"t":{"type":"internal","weight":625,"values":["\ufdd0","s"],"children":{"\ufdd0":{"type":"leaf","weight":625,"entries":[{"key":"result","weight":625,"content":"result"}]},"s":{"type":"leaf","weight":352,"entries":[{"key":"results","weight":352,"content":"results"}]}}}}}}},"e":{"type":"leaf","weight":433,"entries":[{"key":"research","weight":433,"content":"research"}]},"t":{"type":"leaf","weight":412,"entries":[{"key":"rest","weight":412,"content":"rest"}]},"p":{"type":"internal","weight":198,"values":["e","o"],"children":{"e":{"type":"leaf","weight":198,"entries":[{"key":"respect","weight":198,"content":"respect"}]},"o":{"type":"leaf","weight":146,"entries":[{"key":"responsibility","weight":146,"content":"responsibility"}]}}}}},"d":{"type":"leaf","weight":526,"entries":[{"key":"red","weight":526,"content":"red"}]},"q":{"type":"leaf","weight":484,"entries":[{"key":"required","weight":484,"content":"required"}]},"t":{"type":"internal","weight":477,"values":["u"],"children":{"u":{"type":"internal","weight":477,"values":["r"],"children":{"r":{"type":"internal","weight":477,"values":["n"],"children":{"n":{"type":"internal","weight":477,"values":["\ufdd0","e"],"children":{"\ufdd0":{"type":"leaf","weight":477,"entries":[{"key":"return","weight":477,"content":"return"}]},"e":{"type":"leaf","weight":123,"entries":[{"key":"returned","weight":123,"content":"returned"}]}}}}}}}}},"c":{"type":"internal","weight":475,"values":["e","o"],"children":{"e":{"type":"internal","weight":475,"values":["n","i"],"children":{"n":{"type":"internal","weight":475,"values":["t"],"children":{"t":{"type":"internal","weight":475,"values":["\ufdd0","l"],"children":{"\ufdd0":{"type":"leaf","weight":475,"entries":[{"key":"recent","weight":475,"content":"recent"}]},"l":{"type":"leaf","weight":186,"entries":[{"key":"recently","weight":186,"content":"recently"}]}}}}},"i":{"type":"leaf","weight":413,"entries":[{"key":"received","weight":413,"content":"received"}]}}},"o":{"type":"leaf","weight":280,"entries":[{"key":"record","weight":280,"content":"record"}]}}},"p":{"type":"internal","weight":460,"values":["o"],"children":{"o":{"type":"internal","weight":460,"values":["r"],"children":{"r":{"type":"internal","weight":460,"values":["t"],"children":{"t":{"type":"internal","weight":460,"values":["\ufdd0","e"],"children":{"\ufdd0":{"type":"leaf","weight":460,"entries":[{"key":"report","weight":460,"content":"report"}]},"e":{"type":"leaf","weight":156,"entries":[{"key":"reported","weight":156,"content":"reported"}]}}}}}}}}},"l":{"type":"internal","weight":419,"values":["i"],"children":{"i":{"type":"internal","weight":419,"values":["g"],"children":{"g":{"type":"internal","weight":419,"values":["i"],"children":{"i":{"type":"internal","weight":419,"values":["o"],"children":{"o":{"type":"internal","weight":419,"values":["u","n"],"children":{"u":{"type":"leaf","weight":419,"entries":[{"key":"religious","weight":419,"content":"religious"}]},"n":{"type":"leaf","weight":158,"entries":[{"key":"religion","weight":158,"content":"religion"}]}}}}}}}}}}},"m":{"type":"internal","weight":287,"values":["e","a"],"children":{"e":{"type":"leaf","weight":287,"entries":[{"key":"remember","weight":287,"content":"remember"}]},"a":{"type":"leaf","weight":42,"entries":[{"key":"remained","weight":42,"content":"remained"}]}}}}},"u":{"type":"internal","weight":572,"values":["n"],"children":{"n":{"type":"internal","weight":572,"values":["\ufdd0","n"],"children":{"\ufdd0":{"type":"leaf","weight":572,"entries":[{"key":"run","weight":572,"content":"run"}]},"n":{"type":"leaf","weight":181,"entries":[{"key":"running","weight":181,"content":"running"}]}}}}},"h":{"type":"leaf","weight":22,"entries":[{"key":"rhode","weight":22,"content":"rhode"}]}}},"q":{"type":"internal","weight":679,"values":["u"],"children":{"u":{"type":"internal","weight":679,"values":["i","e","a"],"children":{"i":{"type":"leaf","weight":679,"entries":[{"key":"quite","weight":679,"content":"quite"}]},"e":{"type":"internal","weight":644,"values":["s"],"children":{"s":{"type":"internal","weight":644,"values":["t"],"children":{"t":{"type":"internal","weight":644,"values":["i"],"children":{"i":{"type":"internal","weight":644,"values":["o"],"children":{"o":{"type":"internal","weight":644,"values":["n"],"children":{"n":{"type":"internal","weight":644,"values":["\ufdd0","s"],"children":{"\ufdd0":{"type":"leaf","weight":644,"entries":[{"key":"question","weight":644,"content":"question"}]},"s":{"type":"leaf","weight":297,"entries":[{"key":"questions","weight":297,"content":"questions"}]}}}}}}}}}}}}},"a":{"type":"leaf","weight":107,"entries":[{"key":"quality","weight":107,"content":"quality"}]}}}}}}} } From af2b7ace9b0c893f82dc6c523212a25ffac76ae0 Mon Sep 17 00:00:00 2001 From: "Joshua A. Horton" Date: Sun, 24 Mar 2024 21:56:22 +0700 Subject: [PATCH 03/26] feat(common/models/templates): basic full-trie compression test --- .../models/templates/test/trie-compression.js | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/common/models/templates/test/trie-compression.js b/common/models/templates/test/trie-compression.js index 082c37b81aa..bb228584f98 100644 --- a/common/models/templates/test/trie-compression.js +++ b/common/models/templates/test/trie-compression.js @@ -209,4 +209,30 @@ describe('Trie decompression', function () { }); }); }); + + it('compresses fixture successfully: english-1000', () => { + const trie = jsonFixture('tries/english-1000'); + // The test: does it throw? + const compressedTrie = compressNode(trie.root); + const compression = { + // Achieves FAR better compression than JSON.stringify, which \u-escapes most chars. + // As of the commit when this was written... + // - length of encoding below: 26097 + // - JSON-encoding length: 69122 + // - Source fixture's filesize: 141309 bytes + root: `"${compressedTrie.replace(/"/g, '\"')}"`, + totalWeight: trie.totalWeight + } + + // We could easily get even better savings (with some cost) by using the search-term-to-key function + // as part of decompression, avoiding the near-duplicating key/content effect we currently have. + // - if we didn't save the keys: 20490 (estimation) (~21.4% savings) + + // // TODO: Temp code for diagnostics & exploration. + // console.log(`Compressed length: ${compression.root.length}`); + // console.log(`Result: ${compression.root}`); + + // Note: a naive round-tripping test won't work. We only partly decompress + // at each step, after all. + }); }); \ No newline at end of file From be66dfffcce02e6c8bc9e1bcd7f73b0cd68b4613 Mon Sep 17 00:00:00 2001 From: "Joshua A. Horton" Date: Sun, 24 Mar 2024 22:20:37 +0700 Subject: [PATCH 04/26] fix(common/models/templates): model-compiler error correction for compressor --- common/models/templates/src/tries/compression.ts | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/common/models/templates/src/tries/compression.ts b/common/models/templates/src/tries/compression.ts index 478177b4817..ac4b601d500 100644 --- a/common/models/templates/src/tries/compression.ts +++ b/common/models/templates/src/tries/compression.ts @@ -187,7 +187,7 @@ function decompressLeaf(str: string, baseIndex: number): Omit & // encoding start. function compressInternal(node: InternalNode): string { - const values = node.values; + let values = node.values; const valueCntAndType = values.length; // c8 ignore start if(valueCntAndType >= 0x8000) { @@ -196,6 +196,14 @@ function compressInternal(node: InternalNode): string { // c8 ignore end const compressedChildren = values.map((value) => { + // BIG ERROR DETECTED: lexical-model compiler is not emitting SENTINEL chars correctly + // for _some_ cases! '﷐' shows up for 'most', but not _all_, places where it belongs. + // Approx 20% error rate!? + // + // detected via `sil.km.gcc - 1.0`. + if(value === null) { + value = "undefined"; // yes, really. + } const child = node.children[value]; // c8 ignore start @@ -208,6 +216,9 @@ function compressInternal(node: InternalNode): string { return typeof child == 'string' ? child : compressNode(child); }); + // Properly fix the sentinel-value issue. + values = values.map((value) => value === null ? '\ufdd0' : value); + const totalArr = [compressNumber(valueCntAndType)].concat(values).concat(compressedChildren); return totalArr.join(''); } From 56fd03075839fd5e1786a9f91d97563da87ecbdf Mon Sep 17 00:00:00 2001 From: "Joshua A. Horton" Date: Sun, 24 Mar 2024 22:23:44 +0700 Subject: [PATCH 05/26] chore(common/models/templates): doc on probable error location --- common/models/templates/src/tries/compression.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/common/models/templates/src/tries/compression.ts b/common/models/templates/src/tries/compression.ts index ac4b601d500..fbe96a1efa6 100644 --- a/common/models/templates/src/tries/compression.ts +++ b/common/models/templates/src/tries/compression.ts @@ -200,6 +200,10 @@ function compressInternal(node: InternalNode): string { // for _some_ cases! '﷐' shows up for 'most', but not _all_, places where it belongs. // Approx 20% error rate!? // + // STRONG SUSPICION: addItemToInternalNode + // - current line 376: let char = item.key[index]; + // - does not validate that the char exists! + // // detected via `sil.km.gcc - 1.0`. if(value === null) { value = "undefined"; // yes, really. From c0febbad566f61eb2d0e923d58faf3201ad8d752 Mon Sep 17 00:00:00 2001 From: "Joshua A. Horton" Date: Mon, 25 Mar 2024 09:53:44 +0700 Subject: [PATCH 06/26] change(common/models/templates): encoded-num range-offset experiment --- .../models/templates/src/tries/compression.ts | 12 ++- .../models/templates/test/trie-compression.js | 91 ++++++++++++++++++- 2 files changed, 96 insertions(+), 7 deletions(-) diff --git a/common/models/templates/src/tries/compression.ts b/common/models/templates/src/tries/compression.ts index fbe96a1efa6..fd6c8cece8f 100644 --- a/common/models/templates/src/tries/compression.ts +++ b/common/models/templates/src/tries/compression.ts @@ -1,6 +1,12 @@ import { Entry, InternalNode, Leaf, Node } from "../trie-model.js"; -const SINGLE_CHAR_RANGE = Math.pow(2, 16); +// const SINGLE_CHAR_RANGE = Math.pow(2, 16) - 64; +// const ENCODED_NUM_BASE = 64; + +// Offsetting by even just 0x0020 avoids control-code chars + avoids VS Code not liking the encoding. +const ENCODED_NUM_BASE = 0x0020; +const SINGLE_CHAR_RANGE = Math.pow(2, 16) - ENCODED_NUM_BASE; + const WEIGHT_WIDTH = 2; const NODE_SIZE_WIDTH = 2; @@ -10,7 +16,7 @@ export function decompressNumber(str: string, start: number, end: number) { for(let i = start; i < end; i++) { let val = str.charCodeAt(i); - num = num * SINGLE_CHAR_RANGE + val; + num = num * SINGLE_CHAR_RANGE + val - ENCODED_NUM_BASE; } return num; @@ -23,7 +29,7 @@ export function compressNumber(num: number, width?: number) { // Note: JS bit-shift operators assume 32-bit signed ints. // JS numbers can easily represent larger ints, though. while(width > 0) { - const piece = num % SINGLE_CHAR_RANGE; + const piece = num % SINGLE_CHAR_RANGE + ENCODED_NUM_BASE; num = Math.floor(num / SINGLE_CHAR_RANGE); compressed = String.fromCharCode(piece) + compressed; diff --git a/common/models/templates/test/trie-compression.js b/common/models/templates/test/trie-compression.js index bb228584f98..32650ea6e8a 100644 --- a/common/models/templates/test/trie-compression.js +++ b/common/models/templates/test/trie-compression.js @@ -9,6 +9,14 @@ import { compressNumber, decompressNumber } from '@keymanapp/models-templates/obj/tries/compression.js'; +import fs from 'fs'; + +// Written with: +// const ENCODED_NUM_BASE = 0; // 0x0020; +// const SINGLE_CHAR_RANGE = Math.pow(2, 16) - ENCODED_NUM_BASE; +// +// Will need manual re-encoding for \u-sequences if ENCODED_NUM_BASE is changed. + const TEST_DATA = {}; TEST_DATA.ENTRIES = { four: { @@ -214,13 +222,22 @@ describe('Trie decompression', function () { const trie = jsonFixture('tries/english-1000'); // The test: does it throw? const compressedTrie = compressNode(trie.root); + + const encodedSerializableString = `${ + compressedTrie + .replace(/\\/g, '\\\\') // preservation - escape char as literal + .replace(/`/g, '\\`') // escape the primary quote + .replace(/\n/g, '\\n') // prevent CRLF shenanigans + .replace(/\r/g, '\\r') + }`; + const compression = { // Achieves FAR better compression than JSON.stringify, which \u-escapes most chars. // As of the commit when this was written... // - length of encoding below: 26097 // - JSON-encoding length: 69122 // - Source fixture's filesize: 141309 bytes - root: `"${compressedTrie.replace(/"/g, '\"')}"`, + root: `\`${encodedSerializableString}\``, totalWeight: trie.totalWeight } @@ -228,11 +245,77 @@ describe('Trie decompression', function () { // as part of decompression, avoiding the near-duplicating key/content effect we currently have. // - if we didn't save the keys: 20490 (estimation) (~21.4% savings) - // // TODO: Temp code for diagnostics & exploration. - // console.log(`Compressed length: ${compression.root.length}`); - // console.log(`Result: ${compression.root}`); + // TODO: Temp code for diagnostics & exploration. + console.log(`Compressed length: ${compression.root.length}`); + console.log(`Result: ${compression.root}`); // Note: a naive round-tripping test won't work. We only partly decompress // at each step, after all. + +// // Chrome parses it safely, but VS Code complains about the encoding. +// // Complaints are dropped if all encoded numbers are offset by +0x0020. +// // - This does narrow the range of representable values a bit, though. +// // - It -also- brings manual encoding and JSON encoding into near-parity; +// // control char escapes were using a lot of space. +// // +// fs.writeFileSync('temptemp.js', `let trieData = { +// "root": ${compression.root}, +// "totalWeight": ${compression.totalWeight} +// }` +// ); + +// fs.writeFileSync('temptemp.json', `{ +// "root": ${JSON.stringify(compressedTrie)}, +// "totalWeight": ${compression.totalWeight} +// }` +// ); }); + +// it('compresses fixture successfully: sil.km.gcc - 1.0', () => { +// const trie = jsonFixture('tries/sil.km.gcc - 1.0'); +// // The test: does it throw? +// const compressedTrie = compressNode(trie.root); + +// const encodedSerializableString = `${ +// compressedTrie +// .replace(/\\/g, '\\\\') // preservation - escape char as literal +// .replace(/`/g, '\\`') // escape the primary quote +// .replace(/\n/g, '\\n') // prevent CRLF shenanigans +// .replace(/\r/g, '\\r') +// }`; + +// const compression = { +// // Achieves FAR better compression than JSON.stringify, which \u-escapes most chars. +// // As of the commit when this was written... +// // - length of encoding below: 405468 +// // - JSON-encoding length: 1145955 +// // - Source fixture's filesize: 2491696 bytes +// // +// // As is... it compressed in 99ms on my personal development machine. +// root: `"${encodedSerializableString}"`, +// totalWeight: trie.totalWeight +// } + +// // We could easily get even better savings (with some cost) by using the search-term-to-key function +// // as part of decompression, avoiding the near-duplicating key/content effect we currently have. + +// // TODO: Temp code for diagnostics & exploration. +// console.log(`Compressed length: ${compression.root.length}`); +// // console.log(`Result: ${compression.root}`); + +// // Note: a naive round-tripping test won't work. We only partly decompress +// // at each step, after all. + +// fs.writeFileSync('temptemp.js', `let trieData = { +// "root": ${compression.root}, +// "totalWeight": ${compression.totalWeight} +// }` +// ); + +// fs.writeFileSync('temptemp.json', `{ +// "root": ${JSON.stringify(compressedTrie)}, +// "totalWeight": ${compression.totalWeight} +// }` +// ); +// }); }); \ No newline at end of file From 94900c5994cc3734ab5f733de30872bc15ca64ec Mon Sep 17 00:00:00 2001 From: "Joshua A. Horton" Date: Mon, 25 Mar 2024 10:00:52 +0700 Subject: [PATCH 07/26] chore(common/models/templates): reverts offset but leaves its infrastructure --- common/models/templates/src/tries/compression.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/models/templates/src/tries/compression.ts b/common/models/templates/src/tries/compression.ts index fd6c8cece8f..3c93b25c8ce 100644 --- a/common/models/templates/src/tries/compression.ts +++ b/common/models/templates/src/tries/compression.ts @@ -4,7 +4,7 @@ import { Entry, InternalNode, Leaf, Node } from "../trie-model.js"; // const ENCODED_NUM_BASE = 64; // Offsetting by even just 0x0020 avoids control-code chars + avoids VS Code not liking the encoding. -const ENCODED_NUM_BASE = 0x0020; +const ENCODED_NUM_BASE = 0x0000; const SINGLE_CHAR_RANGE = Math.pow(2, 16) - ENCODED_NUM_BASE; const WEIGHT_WIDTH = 2; From 467efd4196ed4b8cc17f1e7fb8d244f33f5cccea Mon Sep 17 00:00:00 2001 From: "Joshua A. Horton" Date: Mon, 25 Mar 2024 10:03:26 +0700 Subject: [PATCH 08/26] docs(common/models/templates): minor notes on noted editor complaints for compressed-Trie code --- common/models/templates/test/trie-compression.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/common/models/templates/test/trie-compression.js b/common/models/templates/test/trie-compression.js index 32650ea6e8a..77fc25aaad9 100644 --- a/common/models/templates/test/trie-compression.js +++ b/common/models/templates/test/trie-compression.js @@ -253,6 +253,9 @@ describe('Trie decompression', function () { // at each step, after all. // // Chrome parses it safely, but VS Code complains about the encoding. +// // > "The file is not displayed in the text editor because it is either binary or uses an unsupported text encoding." +// // - likely b/c the "binary" angle. +// // // // Complaints are dropped if all encoded numbers are offset by +0x0020. // // - This does narrow the range of representable values a bit, though. // // - It -also- brings manual encoding and JSON encoding into near-parity; From 7644d386fc69f38099e69e0c0133274ff27a73af Mon Sep 17 00:00:00 2001 From: "Joshua A. Horton" Date: Thu, 4 Jul 2024 13:02:36 +0700 Subject: [PATCH 09/26] refactor(common/models): split trie-model implementation into separate components --- common/models/templates/src/common.ts | 18 ++ common/models/templates/src/trie-model.ts | 303 ++-------------------- common/models/templates/src/trie.ts | 244 +++++++++++++++++ 3 files changed, 282 insertions(+), 283 deletions(-) create mode 100644 common/models/templates/src/trie.ts diff --git a/common/models/templates/src/common.ts b/common/models/templates/src/common.ts index 853bc7c18dd..80c4470cb54 100644 --- a/common/models/templates/src/common.ts +++ b/common/models/templates/src/common.ts @@ -152,3 +152,21 @@ export function defaultApplyCasing(casing: CasingForm, text: string): string { return text.substring(0, headUnitLength).toUpperCase() .concat(text.substring(headUnitLength)); } } + +/** + * An **opaque** type for a string that is exclusively used as a search key in + * the trie. There should be a function that converts arbitrary strings + * (queries) and converts them into a standard search key for a given language + * model. + * + * Fun fact: This opaque type has ALREADY saved my bacon and found a bug! + */ +export type SearchKey = string & { _: 'SearchKey'}; + +/** + * A function that converts a string (word form or query) into a search key + * (secretly, this is also a string). + */ +export interface Wordform2Key { + (wordform: string): SearchKey; +} diff --git a/common/models/templates/src/trie-model.ts b/common/models/templates/src/trie-model.ts index 9de2fb9050e..0a48d673a3d 100644 --- a/common/models/templates/src/trie-model.ts +++ b/common/models/templates/src/trie-model.ts @@ -29,7 +29,8 @@ import { extendString, PriorityQueue } from "@keymanapp/web-utils"; import { default as defaultWordBreaker } from "@keymanapp/models-wordbreakers"; -import { applyTransform, isHighSurrogate, isSentinel, SENTINEL_CODE_UNIT, transformToSuggestion } from "./common.js"; +import { applyTransform, SearchKey, transformToSuggestion, Wordform2Key } from "./common.js"; +import { Node, Trie } from './trie.js'; import { getLastPreCaretToken } from "./tokenization.js"; extendString(); @@ -73,186 +74,6 @@ export interface TrieModelOptions { punctuation?: LexicalModelPunctuation; } -class Traversal implements LexiconTraversal { - /** - * The lexical prefix corresponding to the current traversal state. - */ - prefix: String; - - /** - * The current traversal node. Serves as the 'root' of its own sub-Trie, - * and we cannot navigate back to its parent. - */ - root: Node; - - /** - * The max weight for the Trie being 'traversed'. Needed for probability - * calculations. - */ - totalWeight: number; - - constructor(root: Node, prefix: string, totalWeight: number) { - this.root = root; - this.prefix = prefix; - this.totalWeight = totalWeight; - } - - child(char: USVString): LexiconTraversal | undefined { - /* - Note: would otherwise return the current instance if `char == ''`. If - such a call is happening, it's probably indicative of an implementation - issue elsewhere - let's signal now in order to catch such stuff early. - */ - if(char == '') { - return undefined; - } - - // Split into individual code units. - let steps = char.split(''); - let traversal: Traversal | undefined = this; - - while(steps.length > 0 && traversal) { - const step: string = steps.shift()!; - traversal = traversal._child(step); - } - - return traversal; - } - - // Handles one code unit at a time. - private _child(char: USVString): Traversal | undefined { - const root = this.root; - const totalWeight = this.totalWeight; - const nextPrefix = this.prefix + char; - - if(root.type == 'internal') { - let childNode = root.children[char]; - if(!childNode) { - return undefined; - } - - return new Traversal(childNode, nextPrefix, totalWeight); - } else { - // root.type == 'leaf'; - const legalChildren = root.entries.filter(function(entry) { - return entry.key.indexOf(nextPrefix) == 0; - }); - - if(!legalChildren.length) { - return undefined; - } - - return new Traversal(root, nextPrefix, totalWeight); - } - } - - *children(): Generator<{char: USVString, traversal: () => LexiconTraversal}> { - let root = this.root; - - // We refer to the field multiple times in this method, and it doesn't change. - // This also assists minification a bit, since we can't minify when re-accessing - // through `this.`. - const totalWeight = this.totalWeight; - - if(root.type == 'internal') { - for(let entry of root.values) { - let entryNode = root.children[entry]; - - // UTF-16 astral plane check. - if(isHighSurrogate(entry)) { - // First code unit of a UTF-16 code point. - // For now, we'll just assume the second always completes such a char. - // - // Note: Things get nasty here if this is only sometimes true; in the future, - // we should compile-time enforce that this assumption is always true if possible. - if(entryNode.type == 'internal') { - let internalNode = entryNode; - for(let lowSurrogate of internalNode.values) { - let prefix = this.prefix + entry + lowSurrogate; - yield { - char: entry + lowSurrogate, - traversal: function() { return new Traversal(internalNode.children[lowSurrogate], prefix, totalWeight) } - } - } - } else { - // Determine how much of the 'leaf' entry has no Trie nodes, emulate them. - let fullText = entryNode.entries[0].key; - entry = entry + fullText[this.prefix.length + 1]; // The other half of the non-BMP char. - let prefix = this.prefix + entry; - - yield { - char: entry, - traversal: function () {return new Traversal(entryNode, prefix, totalWeight)} - } - } - } else if(isSentinel(entry)) { - continue; - } else if(!entry) { - // Prevent any accidental 'null' or 'undefined' entries from having an effect. - continue; - } else { - let prefix = this.prefix + entry; - yield { - char: entry, - traversal: function() { return new Traversal(entryNode, prefix, totalWeight)} - } - } - } - - return; - } else { // type == 'leaf' - let prefix = this.prefix; - - let children = root.entries.filter(function(entry) { - return entry.key != prefix && prefix.length < entry.key.length; - }) - - for(let {key} of children) { - let nodeKey = key[prefix.length]; - - if(isHighSurrogate(nodeKey)) { - // Merge the other half of an SMP char in! - nodeKey = nodeKey + key[prefix.length+1]; - } - yield { - char: nodeKey, - traversal: function() { return new Traversal(root, prefix + nodeKey, totalWeight)} - } - }; - return; - } - } - - get entries() { - const entryMapper = (value: Entry) => { - return { - text: value.content, - p: value.weight / this.totalWeight - } - } - - if(this.root.type == 'leaf') { - let prefix = this.prefix; - let matches = this.root.entries.filter(function(entry) { - return entry.key == prefix; - }); - - return matches.map(entryMapper); - } else { - let matchingLeaf = this.root.children[SENTINEL_CODE_UNIT]; - if(matchingLeaf && matchingLeaf.type == 'leaf') { - return matchingLeaf.entries.map(entryMapper); - } else { - return []; - } - } - } - - get p(): number { - return this.root.weight / this.totalWeight; - } -} - /** * @class TrieModel * @@ -298,7 +119,7 @@ export default class TrieModel implements LexicalModel { predict(transform: Transform, context: Context): Distribution { // Special-case the empty buffer/transform: return the top suggestions. if (!transform.insert && !context.left && !context.right && context.startOfBuffer && context.endOfBuffer) { - return makeDistribution(this._trie.firstN(MAX_SUGGESTIONS).map(({text, p}) => ({ + return makeDistribution(this.firstN(MAX_SUGGESTIONS).map(({text, p}) => ({ transform: { insert: text, deleteLeft: 0 @@ -319,7 +140,7 @@ export default class TrieModel implements LexicalModel { let prefix = getLastPreCaretToken(this.breakWords, newContext); // Return suggestions from the trie. - return makeDistribution(this._trie.lookup(prefix).map(({text, p}) => + return makeDistribution(this.lookup(prefix).map(({text, p}) => transformToSuggestion({ insert: text, // Delete whatever the prefix that the user wrote. @@ -350,101 +171,13 @@ export default class TrieModel implements LexicalModel { public traverseFromRoot(): LexiconTraversal { return this._trie.traverseFromRoot(); } -}; - -///////////////////////////////////////////////////////////////////////////////// -// What remains in this file is the trie implementation proper. Note: to // -// reduce bundle size, any functions/methods related to creating the trie have // -// been removed. // -///////////////////////////////////////////////////////////////////////////////// - -/** - * An **opaque** type for a string that is exclusively used as a search key in - * the trie. There should be a function that converts arbitrary strings - * (queries) and converts them into a standard search key for a given language - * model. - * - * Fun fact: This opaque type has ALREADY saved my bacon and found a bug! - */ -type SearchKey = string & { _: 'SearchKey'}; - -/** - * The priority queue will always pop the most probable item - be it a Traversal - * state or a lexical entry reached via Traversal. - */ -type TraversableWithProb = TextWithProbability | LexiconTraversal; - -/** - * A function that converts a string (word form or query) into a search key - * (secretly, this is also a string). - */ -interface Wordform2Key { - (wordform: string): SearchKey; -} - -// The following trie implementation has been (heavily) derived from trie-ing -// by Conrad Irwin. -// trie-ing is copyright (C) 2015–2017 Conrad Irwin. -// Distributed under the terms of the MIT license: -// https://github.com/ConradIrwin/trie-ing/blob/df55d7af7068d357829db9e0a7faa8a38add1d1d/LICENSE -type Node = InternalNode | Leaf; -/** - * An internal node in the trie. Internal nodes NEVER contain entries; if an - * internal node should contain an entry, then it has a dummy leaf node (see - * below), that can be accessed by node.children["\uFDD0"]. - */ -interface InternalNode { - type: 'internal'; - weight: number; - /** Maintains the keys of children in descending order of weight. */ - values: string[]; // TODO: As an optimization, "values" can be a single string! - /** - * Maps a single UTF-16 code unit to a child node in the trie. This child - * node may be a leaf or an internal node. The keys of this object are kept - * in sorted order in the .values array. - */ - children: { [codeunit: string]: Node }; -} -/** Only leaf nodes actually contain entries (i.e., the words proper). */ -interface Leaf { - type: 'leaf'; - weight: number; - entries: Entry[]; -} - -/** - * An entry in the prefix trie (stored in leaf nodes exclusively!) - */ -interface Entry { - /** The actual word form, stored in the trie. */ - content: string; - /** A search key that usually simplifies the word form, for ease of search. */ - key: SearchKey; - weight: number; -} - -/** - * Wrapper class for the trie and its nodes. - */ -class Trie { - public readonly root: Node; - /** The total weight of the entire trie. */ - readonly totalWeight: number; /** - * Converts arbitrary strings to a search key. The trie is built up of - * search keys; not each entry's word form! + * Returns the top N suggestions from the trie. + * @param n How many suggestions, maximum, to return. */ - toKey: Wordform2Key; - - constructor(root: Node, totalWeight: number, wordform2key: Wordform2Key) { - this.root = root; - this.toKey = wordform2key; - this.totalWeight = totalWeight; - } - - public traverseFromRoot(): LexiconTraversal { - return new Traversal(this.root, '', this.totalWeight); + firstN(n: number): TextWithProbability[] { + return getSortedResults(this._trie.traverseFromRoot(), n); } /** @@ -475,15 +208,19 @@ class Trie { // priority over anything from its descendants. return directEntries.concat(deduplicated); } +}; - /** - * Returns the top N suggestions from the trie. - * @param n How many suggestions, maximum, to return. - */ - firstN(n: number): TextWithProbability[] { - return getSortedResults(this.traverseFromRoot(), n); - } -} +///////////////////////////////////////////////////////////////////////////////// +// What remains in this file is the trie implementation proper. Note: to // +// reduce bundle size, any functions/methods related to creating the trie have // +// been removed. // +///////////////////////////////////////////////////////////////////////////////// + +/** + * The priority queue will always pop the most probable item - be it a Traversal + * state or a lexical entry reached via Traversal. + */ +type TraversableWithProb = TextWithProbability | LexiconTraversal; /** * Returns all entries matching the given prefix, in descending order of diff --git a/common/models/templates/src/trie.ts b/common/models/templates/src/trie.ts new file mode 100644 index 00000000000..fc3ab7d5bc5 --- /dev/null +++ b/common/models/templates/src/trie.ts @@ -0,0 +1,244 @@ +import { isHighSurrogate, isSentinel, SearchKey, SENTINEL_CODE_UNIT, Wordform2Key } from "./common.js"; + +// The following trie implementation has been (heavily) derived from trie-ing +// by Conrad Irwin. +// trie-ing is copyright (C) 2015–2017 Conrad Irwin. +// Distributed under the terms of the MIT license: +// https://github.com/ConradIrwin/trie-ing/blob/df55d7af7068d357829db9e0a7faa8a38add1d1d/LICENSE + +export type Node = InternalNode | Leaf; +/** + * An internal node in the trie. Internal nodes NEVER contain entries; if an + * internal node should contain an entry, then it has a dummy leaf node (see + * below), that can be accessed by node.children["\uFDD0"]. + */ +export interface InternalNode { + type: 'internal'; + weight: number; + /** Maintains the keys of children in descending order of weight. */ + values: string[]; // TODO: As an optimization, "values" can be a single string! + /** + * Maps a single UTF-16 code unit to a child node in the trie. This child + * node may be a leaf or an internal node. The keys of this object are kept + * in sorted order in the .values array. + */ + children: { [codeunit: string]: Node }; +} +/** Only leaf nodes actually contain entries (i.e., the words proper). */ +export interface Leaf { + type: 'leaf'; + weight: number; + entries: Entry[]; +} + +/** + * An entry in the prefix trie (stored in leaf nodes exclusively!) + */ +export interface Entry { + /** The actual word form, stored in the trie. */ + content: string; + /** A search key that usually simplifies the word form, for ease of search. */ + key: SearchKey; + weight: number; +} + +export class TrieTraversal implements LexiconTraversal { + /** + * The lexical prefix corresponding to the current traversal state. + */ + prefix: String; + + /** + * The current traversal node. Serves as the 'root' of its own sub-Trie, + * and we cannot navigate back to its parent. + */ + root: Node; + + /** + * The max weight for the Trie being 'traversed'. Needed for probability + * calculations. + */ + totalWeight: number; + + constructor(root: Node, prefix: string, totalWeight: number) { + this.root = root; + this.prefix = prefix; + this.totalWeight = totalWeight; + } + + child(char: USVString): LexiconTraversal | undefined { + /* + Note: would otherwise return the current instance if `char == ''`. If + such a call is happening, it's probably indicative of an implementation + issue elsewhere - let's signal now in order to catch such stuff early. + */ + if(char == '') { + return undefined; + } + + // Split into individual code units. + let steps = char.split(''); + let traversal: ReturnType = this; + + while(steps.length > 0 && traversal) { + const step: string = steps.shift()!; + traversal = traversal._child(step); + } + + return traversal; + } + + // Handles one code unit at a time. + private _child(char: USVString): TrieTraversal | undefined { + const root = this.root; + const totalWeight = this.totalWeight; + const nextPrefix = this.prefix + char; + + if(root.type == 'internal') { + let childNode = root.children[char]; + if(!childNode) { + return undefined; + } + + return new TrieTraversal(childNode, nextPrefix, totalWeight); + } else { + // root.type == 'leaf'; + const legalChildren = root.entries.filter(function(entry) { + return entry.key.indexOf(nextPrefix) == 0; + }); + + if(!legalChildren.length) { + return undefined; + } + + return new TrieTraversal(root, nextPrefix, totalWeight); + } + } + + *children(): Generator<{char: USVString, traversal: () => LexiconTraversal}> { + let root = this.root; + const totalWeight = this.totalWeight; + + if(root.type == 'internal') { + for(let entry of root.values) { + let entryNode = root.children[entry]; + + // UTF-16 astral plane check. + if(isHighSurrogate(entry)) { + // First code unit of a UTF-16 code point. + // For now, we'll just assume the second always completes such a char. + // + // Note: Things get nasty here if this is only sometimes true; in the future, + // we should compile-time enforce that this assumption is always true if possible. + if(entryNode.type == 'internal') { + let internalNode = entryNode; + for(let lowSurrogate of internalNode.values) { + let prefix = this.prefix + entry + lowSurrogate; + yield { + char: entry + lowSurrogate, + traversal: function() { return new TrieTraversal(internalNode.children[lowSurrogate], prefix, totalWeight) } + } + } + } else { + // Determine how much of the 'leaf' entry has no Trie nodes, emulate them. + let fullText = entryNode.entries[0].key; + entry = entry + fullText[this.prefix.length + 1]; // The other half of the non-BMP char. + let prefix = this.prefix + entry; + + yield { + char: entry, + traversal: function () {return new TrieTraversal(entryNode, prefix, totalWeight)} + } + } + } else if(isSentinel(entry)) { + continue; + } else if(!entry) { + // Prevent any accidental 'null' or 'undefined' entries from having an effect. + continue; + } else { + let prefix = this.prefix + entry; + yield { + char: entry, + traversal: function() { return new TrieTraversal(entryNode, prefix, totalWeight)} + } + } + } + + return; + } else { // type == 'leaf' + let prefix = this.prefix; + + let children = root.entries.filter(function(entry) { + return entry.key != prefix && prefix.length < entry.key.length; + }) + + for(let {key} of children) { + let nodeKey = key[prefix.length]; + + if(isHighSurrogate(nodeKey)) { + // Merge the other half of an SMP char in! + nodeKey = nodeKey + key[prefix.length+1]; + } + yield { + char: nodeKey, + traversal: function() { return new TrieTraversal(root, prefix + nodeKey, totalWeight)} + } + }; + return; + } + } + + get entries() { + const totalWeight = this.totalWeight; + const entryMapper = function(value: Entry) { + return { + text: value.content, + p: value.weight / totalWeight + } + } + + if(this.root.type == 'leaf') { + let prefix = this.prefix; + let matches = this.root.entries.filter(function(entry) { + return entry.key == prefix; + }); + + return matches.map(entryMapper); + } else { + let matchingLeaf = this.root.children[SENTINEL_CODE_UNIT]; + if(matchingLeaf && matchingLeaf.type == 'leaf') { + return matchingLeaf.entries.map(entryMapper); + } else { + return []; + } + } + } + + get p(): number { + return this.root.weight / this.totalWeight; + } +} + +/** + * Wrapper class for the trie and its nodes. + */ +export class Trie { + private root: Node; + /** The total weight of the entire trie. */ + readonly totalWeight: number; + /** + * Converts arbitrary strings to a search key. The trie is built up of + * search keys; not each entry's word form! + */ + toKey: Wordform2Key; + + constructor(root: Node, totalWeight: number, wordform2key: Wordform2Key) { + this.root = root; + this.toKey = wordform2key; + this.totalWeight = totalWeight; + } + + public traverseFromRoot(): LexiconTraversal { + return new TrieTraversal(this.root, '', this.totalWeight); + } +} \ No newline at end of file From c16ae2724a312132b63c946fcb16508907c6922e Mon Sep 17 00:00:00 2001 From: "Joshua A. Horton" Date: Fri, 2 Aug 2024 12:31:24 +0700 Subject: [PATCH 10/26] refactor(developer/compilers): prepare for trie-compiler split --- developer/src/kmc-model/src/build-trie.ts | 30 ++++++++++++----------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/developer/src/kmc-model/src/build-trie.ts b/developer/src/kmc-model/src/build-trie.ts index 8bbc6aaa53a..76da23662fe 100644 --- a/developer/src/kmc-model/src/build-trie.ts +++ b/developer/src/kmc-model/src/build-trie.ts @@ -291,13 +291,28 @@ namespace Trie { * @returns A JSON-serialiable object that can be given to the TrieModel constructor. */ export function buildTrie(wordlist: WordList, keyFunction: SearchTermToKey): object { - let root = new Trie(keyFunction).buildFromWordList(wordlist).root; + let trie = new Trie(keyFunction); + buildFromWordList(trie, wordlist); + const root = trie.root; return { totalWeight: sumWeights(root), root: root } } + /** + * Populates the trie with the contents of an entire wordlist. + * @param words a list of word and count pairs. + */ + function buildFromWordList(trie: Trie, words: WordList): Trie { + for (let [wordform, weight] of Object.entries(words)) { + let key = trie.toKey(wordform); + addUnsorted(trie.root, { key, weight, content: wordform }, 0); + } + sortTrie(trie.root); + return trie; + } + /** * Wrapper class for the trie and its nodes and wordform to search */ @@ -307,19 +322,6 @@ namespace Trie { constructor(wordform2key: SearchTermToKey) { this.toKey = wordform2key; } - - /** - * Populates the trie with the contents of an entire wordlist. - * @param words a list of word and count pairs. - */ - buildFromWordList(words: WordList): Trie { - for (let [wordform, weight] of Object.entries(words)) { - let key = this.toKey(wordform); - addUnsorted(this.root, { key, weight, content: wordform }, 0); - } - sortTrie(this.root); - return this; - } } // "Constructors" From 54bdf73c93b958df609c1103b07efc98aa5a8374 Mon Sep 17 00:00:00 2001 From: "Joshua A. Horton" Date: Fri, 2 Aug 2024 12:42:54 +0700 Subject: [PATCH 11/26] refactor(common/models): move primary trie-compilation code into common/models/templates We'll likely want to dynamically build a Trie to represent user-specific entries made available by the active OS. We'll then blend _that_ with the 'static' distributed model. --- common/models/templates/src/index.ts | 4 + common/models/templates/src/trie-builder.ts | 155 +++++++++ common/models/templates/src/trie.ts | 28 +- developer/src/kmc-model/src/build-trie.ts | 353 ++++---------------- 4 files changed, 250 insertions(+), 290 deletions(-) create mode 100644 common/models/templates/src/trie-builder.ts diff --git a/common/models/templates/src/index.ts b/common/models/templates/src/index.ts index 8563004fefa..b32c37d45a8 100644 --- a/common/models/templates/src/index.ts +++ b/common/models/templates/src/index.ts @@ -4,4 +4,8 @@ export { } from "./common.js"; export { default as QuoteBehavior } from "./quote-behavior.js"; export { Tokenization, tokenize, getLastPreCaretToken, wordbreak } from "./tokenization.js"; +export { + Entry, InternalNode, Leaf, Node +} from './trie.js'; +export { addUnsorted, TrieBuilder } from './trie-builder.js'; export { default as TrieModel, TrieModelOptions } from "./trie-model.js"; \ No newline at end of file diff --git a/common/models/templates/src/trie-builder.ts b/common/models/templates/src/trie-builder.ts new file mode 100644 index 00000000000..8b90b5f28d7 --- /dev/null +++ b/common/models/templates/src/trie-builder.ts @@ -0,0 +1,155 @@ +import { SENTINEL_CODE_UNIT, Wordform2Key } from "./common.js"; +import { Entry, InternalNode, Leaf, Node, Trie } from "./trie.js"; + +function createRootNode(): Node { + return { + type: 'leaf', + weight: 0, + entries: [] + }; +} + +/** + * Adds an entry to the trie. + * + * Note that the trie will likely be unsorted after the add occurs. Before + * performing a lookup on the trie, use call sortTrie() on the root note! + * + * @param node Which node should the entry be added to? + * @param entry the wordform/weight/key to add to the trie + * @param index the index in the key and also the trie depth. Should be set to + * zero when adding onto the root node of the trie. + */ +export function addUnsorted(node: Node, entry: Entry, index: number = 0) { + // Each node stores the MAXIMUM weight out of all of its decesdents, to + // enable a greedy search through the trie. + node.weight = Math.max(node.weight, entry.weight); + + // When should a leaf become an interior node? + // When it already has a value, but the key of the current value is longer + // than the prefix. + if (node.type === 'leaf' && index < entry.key.length && node.entries.length >= 1) { + convertLeafToInternalNode(node, index); + } + + if (node.type === 'leaf') { + // The key matches this leaf node, so add yet another entry. + addItemToLeaf(node, entry); + } else { + // Push the node down to a lower node. + addItemToInternalNode(node, entry, index); + } + + node.unsorted = true; +} + +/** + * Adds an item to the internal node at a given depth. + * @param item + * @param index + */ +function addItemToInternalNode(node: InternalNode, item: Entry, index: number) { + let char = item.key[index]; + // If an internal node is the proper site for item, it belongs under the + // corresponding (sentinel, internal-use) child node signifying this. + if(char == undefined) { + char = SENTINEL_CODE_UNIT; + } + if (!node.children[char]) { + node.children[char] = createRootNode(); + node.values.push(char); + } + addUnsorted(node.children[char], item, index + 1); +} + +function addItemToLeaf(leaf: Leaf, item: Entry) { + leaf.entries.push(item); +} + +/** + * Mutates the given Leaf to turn it into an InternalNode. + * + * NOTE: the node passed in will be DESTRUCTIVELY CHANGED into a different + * type when passed into this function! + * + * @param depth depth of the trie at this level. + */ +function convertLeafToInternalNode(leaf: Leaf, depth: number): void { + let entries = leaf.entries; + + // Alias the current node, as the desired type. + let internal = ( leaf) as InternalNode; + internal.type = 'internal'; + + delete (leaf as Partial).entries; + internal.values = []; + internal.children = {}; + + // Convert the old values array into the format for interior nodes. + for (let item of entries) { + let char: string; + if (depth < item.key.length) { + char = item.key[depth]; + } else { + char = SENTINEL_CODE_UNIT; + } + + if (!internal.children[char]) { + internal.children[char] = createRootNode(); + internal.values.push(char); + } + addUnsorted(internal.children[char], item, depth + 1); + } + + internal.unsorted = true; +} + +/** + * Recursively sort the trie, in descending order of weight. + * @param node any node in the trie + */ +function sortTrie(node: Node) { + if (node.type === 'leaf') { + if (!node.unsorted) { + return; + } + + node.entries.sort(function (a, b) { return b.weight - a.weight; }); + } else { + // We MUST recurse and sort children before returning. + for (let char of node.values) { + sortTrie(node.children[char]); + } + + if (!node.unsorted) { + return; + } + + node.values.sort((a, b) => { + return node.children[b].weight - node.children[a].weight; + }); + } + + delete node.unsorted; +} + +/** + * Wrapper class for the trie and its nodes. + */ +export class TrieBuilder extends Trie { + /** The total weight of the entire trie. */ + totalWeight: number; + + constructor(toKey: Wordform2Key) { + super(createRootNode(), 0, toKey); + this.totalWeight = 0; + } + + sort() { + sortTrie(this.root); + } + + getRoot(): Node { + return this.root; + } +} \ No newline at end of file diff --git a/common/models/templates/src/trie.ts b/common/models/templates/src/trie.ts index fc3ab7d5bc5..47dc6fe5dc6 100644 --- a/common/models/templates/src/trie.ts +++ b/common/models/templates/src/trie.ts @@ -23,12 +23,22 @@ export interface InternalNode { * in sorted order in the .values array. */ children: { [codeunit: string]: Node }; + + /** + * Used during compilation. + */ + unsorted?: boolean; } /** Only leaf nodes actually contain entries (i.e., the words proper). */ export interface Leaf { type: 'leaf'; weight: number; entries: Entry[]; + + /** + * Used during compilation. + */ + unsorted?: boolean; } /** @@ -88,12 +98,26 @@ export class TrieTraversal implements LexiconTraversal { return traversal; } + private sortNodeIfNeeded(node: Node) { + if(node.unsorted) { + if(node.type == 'leaf') { + node.entries.sort((a, b) => b.weight - a.weight) + } else { + node.values.sort((a, b) => node.children[b].weight - node.children[a].weight); + } + + node.unsorted = false; + } + } + // Handles one code unit at a time. private _child(char: USVString): TrieTraversal | undefined { const root = this.root; const totalWeight = this.totalWeight; const nextPrefix = this.prefix + char; + this.sortNodeIfNeeded(root); + if(root.type == 'internal') { let childNode = root.children[char]; if(!childNode) { @@ -119,6 +143,8 @@ export class TrieTraversal implements LexiconTraversal { let root = this.root; const totalWeight = this.totalWeight; + this.sortNodeIfNeeded(root); + if(root.type == 'internal') { for(let entry of root.values) { let entryNode = root.children[entry]; @@ -223,7 +249,7 @@ export class TrieTraversal implements LexiconTraversal { * Wrapper class for the trie and its nodes. */ export class Trie { - private root: Node; + protected root: Node; /** The total weight of the entire trie. */ readonly totalWeight: number; /** diff --git a/developer/src/kmc-model/src/build-trie.ts b/developer/src/kmc-model/src/build-trie.ts index 76da23662fe..efcda3d38cf 100644 --- a/developer/src/kmc-model/src/build-trie.ts +++ b/developer/src/kmc-model/src/build-trie.ts @@ -1,6 +1,8 @@ import { ModelCompilerError, ModelCompilerMessageContext, ModelCompilerMessages } from "./model-compiler-messages.js"; import { callbacks } from "./compiler-callbacks.js"; +import { addUnsorted, Node, TrieBuilder } from '@keymanapp/models-templates'; + // Supports LF or CRLF line terminators. const NEWLINE_SEPARATOR = /\u000d?\u000a/; @@ -29,7 +31,7 @@ export function createTrieDataStructure(filenames: string[], searchTermToKey?: ( let wordlist: WordList = {}; filenames.forEach(filename => parseWordListFromFilename(wordlist, filename)); - let trie = Trie.buildTrie(wordlist, searchTermToKey as Trie.SearchTermToKey); + let trie = buildTrie(wordlist, searchTermToKey as SearchTermToKey); return JSON.stringify(trie); } @@ -185,304 +187,77 @@ function* enumerateLines(lines: string[]): Generator { } } -namespace Trie { - /** - * An **opaque** type for a string that is exclusively used as a search key in - * the trie. There should be a function that converts arbitrary strings - * (queries) and converts them into a standard search key for a given language - * model. - * - * Fun fact: This opaque type has ALREADY saved my bacon and found a bug! - */ - type SearchKey = string & { _: 'SearchKey'}; - - /** - * A function that converts a string (word form or query) into a search key - * (secretly, this is also a string). - */ - export interface SearchTermToKey { - (wordform: string): SearchKey; - } - - // The following trie implementation has been (heavily) derived from trie-ing - // by Conrad Irwin. - // - // trie-ing is distributed under the terms of the MIT license, reproduced here: - // - // The MIT License - // Copyright (c) 2015-2017 Conrad Irwin - // Copyright (c) 2011 Marc Campbell - // - // Permission is hereby granted, free of charge, to any person obtaining a copy - // of this software and associated documentation files (the "Software"), to deal - // in the Software without restriction, including without limitation the rights - // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - // copies of the Software, and to permit persons to whom the Software is - // furnished to do so, subject to the following conditions: - // - // The above copyright notice and this permission notice shall be included in - // all copies or substantial portions of the Software. - // - // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - // THE SOFTWARE. - // - // See: https://github.com/ConradIrwin/trie-ing/blob/df55d7af7068d357829db9e0a7faa8a38add1d1d/LICENSE - - /** - * An entry in the prefix trie. The matched word is "content". - */ - interface Entry { - content: string; - key: SearchKey; - weight: number; - } - - /** - * The trie is made up of nodes. A node can be EITHER an internal node (whose - * only children are other nodes) OR a leaf, which actually contains the word - * form entries. - */ - type Node = InternalNode | Leaf; - - /** - * An internal node. - */ - interface InternalNode { - type: 'internal'; - weight: number; - // TODO: As an optimization, "values" can be a single string! - values: string[]; - children: { [codeunit: string]: Node }; - unsorted?: true; - } - - /** - * A leaf node. - */ - interface Leaf { - type: 'leaf'; - weight: number; - entries: Entry[]; - unsorted?: true; - } - - /** - * A sentinel value for when an internal node has contents and requires an - * "internal" leaf. That is, this internal node has content. Instead of placing - * entries as children in an internal node, a "fake" leaf is created, and its - * key is this special internal value. - * - * The value is a valid Unicode BMP code point, but it is a "non-character". - * Unicode will never assign semantics to these characters, as they are - * intended to be used internally as sentinel values. - */ - const INTERNAL_VALUE = '\uFDD0'; - - /** - * Builds a trie from a word list. - * - * @param wordlist The wordlist with non-negative weights. - * @param keyFunction Function that converts word forms into indexed search keys - * @returns A JSON-serialiable object that can be given to the TrieModel constructor. - */ - export function buildTrie(wordlist: WordList, keyFunction: SearchTermToKey): object { - let trie = new Trie(keyFunction); - buildFromWordList(trie, wordlist); - const root = trie.root; - return { - totalWeight: sumWeights(root), - root: root - } - } - - /** - * Populates the trie with the contents of an entire wordlist. - * @param words a list of word and count pairs. - */ - function buildFromWordList(trie: Trie, words: WordList): Trie { - for (let [wordform, weight] of Object.entries(words)) { - let key = trie.toKey(wordform); - addUnsorted(trie.root, { key, weight, content: wordform }, 0); - } - sortTrie(trie.root); - return trie; - } - - /** - * Wrapper class for the trie and its nodes and wordform to search - */ - class Trie { - readonly root = createRootNode(); - toKey: SearchTermToKey; - constructor(wordform2key: SearchTermToKey) { - this.toKey = wordform2key; - } - } - - // "Constructors" - function createRootNode(): Node { - return { - type: 'leaf', - weight: 0, - entries: [] - }; - } - - // Implement Trie creation. - - /** - * Adds an entry to the trie. - * - * Note that the trie will likely be unsorted after the add occurs. Before - * performing a lookup on the trie, use call sortTrie() on the root note! - * - * @param node Which node should the entry be added to? - * @param entry the wordform/weight/key to add to the trie - * @param index the index in the key and also the trie depth. Should be set to - * zero when adding onto the root node of the trie. - */ - function addUnsorted(node: Node, entry: Entry, index: number = 0) { - // Each node stores the MAXIMUM weight out of all of its decesdents, to - // enable a greedy search through the trie. - node.weight = Math.max(node.weight, entry.weight); - - // When should a leaf become an interior node? - // When it already has a value, but the key of the current value is longer - // than the prefix. - if (node.type === 'leaf' && index < entry.key.length && node.entries.length >= 1) { - convertLeafToInternalNode(node, index); - } - - if (node.type === 'leaf') { - // The key matches this leaf node, so add yet another entry. - addItemToLeaf(node, entry); - } else { - // Push the node down to a lower node. - addItemToInternalNode(node, entry, index); - } +/** + * An **opaque** type for a string that is exclusively used as a search key in + * the trie. There should be a function that converts arbitrary strings + * (queries) and converts them into a standard search key for a given language + * model. + * + * Fun fact: This opaque type has ALREADY saved my bacon and found a bug! + */ +type SearchKey = string & { _: 'SearchKey'}; - node.unsorted = true; - } +/** + * A function that converts a string (word form or query) into a search key + * (secretly, this is also a string). + */ +export interface SearchTermToKey { + (wordform: string): SearchKey; +} - /** - * Adds an item to the internal node at a given depth. - * @param item - * @param index - */ - function addItemToInternalNode(node: InternalNode, item: Entry, index: number) { - let char = item.key[index]; - // If an internal node is the proper site for item, it belongs under the - // corresponding (sentinel, internal-use) child node signifying this. - if(char == undefined) { - char = INTERNAL_VALUE; - } - if (!node.children[char]) { - node.children[char] = createRootNode(); - node.values.push(char); - } - addUnsorted(node.children[char], item, index + 1); - } +/** + * Builds a trie from a word list. + * + * @param wordlist The wordlist with non-negative weights. + * @param keyFunction Function that converts word forms into indexed search keys + * @returns A JSON-serialiable object that can be given to the TrieModel constructor. + */ +export function buildTrie(wordlist: WordList, keyFunction: SearchTermToKey): object { + let collater = new TrieBuilder(keyFunction); - function addItemToLeaf(leaf: Leaf, item: Entry) { - leaf.entries.push(item); + buildFromWordList(collater, wordlist); + return { + totalWeight: sumWeights(collater.getRoot()), + root: collater.getRoot() } +} - /** - * Mutates the given Leaf to turn it into an InternalNode. - * - * NOTE: the node passed in will be DESTRUCTIVELY CHANGED into a different - * type when passed into this function! - * - * @param depth depth of the trie at this level. - */ - function convertLeafToInternalNode(leaf: Leaf, depth: number): void { - let entries = leaf.entries; - - // Alias the current node, as the desired type. - let internal = ( leaf) as InternalNode; - internal.type = 'internal'; - - delete leaf.entries; - internal.values = []; - internal.children = {}; - - // Convert the old values array into the format for interior nodes. - for (let item of entries) { - let char: string; - if (depth < item.key.length) { - char = item.key[depth]; - } else { - char = INTERNAL_VALUE; - } - - if (!internal.children[char]) { - internal.children[char] = createRootNode(); - internal.values.push(char); - } - addUnsorted(internal.children[char], item, depth + 1); - } - - internal.unsorted = true; +/** + * Populates the trie with the contents of an entire wordlist. + * @param words a list of word and count pairs. + */ +function buildFromWordList(trieCollator: TrieBuilder, words: WordList): TrieBuilder { + for (let [wordform, weight] of Object.entries(words)) { + let key = trieCollator.toKey(wordform); + addUnsorted(trieCollator.getRoot(), { content: wordform, key, weight }); } + trieCollator.sort(); + return trieCollator; +} - /** - * Recursively sort the trie, in descending order of weight. - * @param node any node in the trie - */ - function sortTrie(node: Node) { - if (node.type === 'leaf') { - if (!node.unsorted) { - return; - } - - node.entries.sort(function (a, b) { return b.weight - a.weight; }); - } else { - // We MUST recurse and sort children before returning. - for (let char of node.values) { - sortTrie(node.children[char]); - } - - if (!node.unsorted) { - return; - } - - node.values.sort((a, b) => { - return node.children[b].weight - node.children[a].weight; - }); - } - - delete node.unsorted; +/** + * O(n) recursive traversal to sum the total weight of all leaves in the + * trie, starting at the provided node. + * + * @param node The node to start summing weights. + */ +function sumWeights(node: Node): number { + let val: number; + if (node.type === 'leaf') { + val = node.entries + .map(entry => entry.weight) + //.map(entry => isNaN(entry.weight) ? 1 : entry.weight) + .reduce((acc, count) => acc + count, 0); + } else { + val = Object.keys(node.children) + .map((key) => sumWeights(node.children[key])) + .reduce((acc, count) => acc + count, 0); } - /** - * O(n) recursive traversal to sum the total weight of all leaves in the - * trie, starting at the provided node. - * - * @param node The node to start summing weights. - */ - function sumWeights(node: Node): number { - let val: number; - if (node.type === 'leaf') { - val = node.entries - .map(entry => entry.weight) - //.map(entry => isNaN(entry.weight) ? 1 : entry.weight) - .reduce((acc, count) => acc + count, 0); - } else { - val = Object.keys(node.children) - .map((key) => sumWeights(node.children[key])) - .reduce((acc, count) => acc + count, 0); - } - - if(isNaN(val)) { - throw new Error("Unexpected NaN has appeared!"); - } - return val; + if(isNaN(val)) { + throw new Error("Unexpected NaN has appeared!"); } + return val; } /** From 768435365cab644f4e677e2b132c006e0c201f5f Mon Sep 17 00:00:00 2001 From: "Joshua A. Horton" Date: Thu, 4 Jul 2024 15:14:51 +0700 Subject: [PATCH 12/26] refactor(common/models): refactor migrated trie-construction code for improved encapsulation --- common/models/templates/src/index.ts | 2 +- common/models/templates/src/trie-builder.ts | 20 ++++++++++++- developer/src/kmc-model/src/build-trie.ts | 32 ++------------------- 3 files changed, 23 insertions(+), 31 deletions(-) diff --git a/common/models/templates/src/index.ts b/common/models/templates/src/index.ts index b32c37d45a8..b67528a355d 100644 --- a/common/models/templates/src/index.ts +++ b/common/models/templates/src/index.ts @@ -7,5 +7,5 @@ export { Tokenization, tokenize, getLastPreCaretToken, wordbreak } from "./token export { Entry, InternalNode, Leaf, Node } from './trie.js'; -export { addUnsorted, TrieBuilder } from './trie-builder.js'; +export { TrieBuilder } from './trie-builder.js'; export { default as TrieModel, TrieModelOptions } from "./trie-model.js"; \ No newline at end of file diff --git a/common/models/templates/src/trie-builder.ts b/common/models/templates/src/trie-builder.ts index 8b90b5f28d7..0ac5cfa5756 100644 --- a/common/models/templates/src/trie-builder.ts +++ b/common/models/templates/src/trie-builder.ts @@ -20,7 +20,7 @@ function createRootNode(): Node { * @param index the index in the key and also the trie depth. Should be set to * zero when adding onto the root node of the trie. */ -export function addUnsorted(node: Node, entry: Entry, index: number = 0) { +function addUnsorted(node: Node, entry: Entry, index: number = 0) { // Each node stores the MAXIMUM weight out of all of its decesdents, to // enable a greedy search through the trie. node.weight = Math.max(node.weight, entry.weight); @@ -145,6 +145,20 @@ export class TrieBuilder extends Trie { this.totalWeight = 0; } + addEntry(word: string, weight?: number) { + weight = (isNaN(weight ?? NaN) || !weight) ? 1 : weight; + this.totalWeight += weight; + + addUnsorted( + this.root, { + key: this.toKey(word), + content: word, + weight: weight + }, + 0 + ); + } + sort() { sortTrie(this.root); } @@ -152,4 +166,8 @@ export class TrieBuilder extends Trie { getRoot(): Node { return this.root; } + + getTotalWeight(): number { + return this.totalWeight; + } } \ No newline at end of file diff --git a/developer/src/kmc-model/src/build-trie.ts b/developer/src/kmc-model/src/build-trie.ts index efcda3d38cf..9e34cd54691 100644 --- a/developer/src/kmc-model/src/build-trie.ts +++ b/developer/src/kmc-model/src/build-trie.ts @@ -1,7 +1,7 @@ import { ModelCompilerError, ModelCompilerMessageContext, ModelCompilerMessages } from "./model-compiler-messages.js"; import { callbacks } from "./compiler-callbacks.js"; -import { addUnsorted, Node, TrieBuilder } from '@keymanapp/models-templates'; +import { TrieBuilder } from '@keymanapp/models-templates'; // Supports LF or CRLF line terminators. const NEWLINE_SEPARATOR = /\u000d?\u000a/; @@ -217,7 +217,7 @@ export function buildTrie(wordlist: WordList, keyFunction: SearchTermToKey): obj buildFromWordList(collater, wordlist); return { - totalWeight: sumWeights(collater.getRoot()), + totalWeight: collater.getTotalWeight(), root: collater.getRoot() } } @@ -228,38 +228,12 @@ export function buildTrie(wordlist: WordList, keyFunction: SearchTermToKey): obj */ function buildFromWordList(trieCollator: TrieBuilder, words: WordList): TrieBuilder { for (let [wordform, weight] of Object.entries(words)) { - let key = trieCollator.toKey(wordform); - addUnsorted(trieCollator.getRoot(), { content: wordform, key, weight }); + trieCollator.addEntry(wordform, weight); } trieCollator.sort(); return trieCollator; } -/** - * O(n) recursive traversal to sum the total weight of all leaves in the - * trie, starting at the provided node. - * - * @param node The node to start summing weights. - */ -function sumWeights(node: Node): number { - let val: number; - if (node.type === 'leaf') { - val = node.entries - .map(entry => entry.weight) - //.map(entry => isNaN(entry.weight) ? 1 : entry.weight) - .reduce((acc, count) => acc + count, 0); - } else { - val = Object.keys(node.children) - .map((key) => sumWeights(node.children[key])) - .reduce((acc, count) => acc + count, 0); - } - - if(isNaN(val)) { - throw new Error("Unexpected NaN has appeared!"); - } - return val; -} - /** * Detects the encoding of a text file. * From f7d2d63e9e7767dd040816b4d4b98aaa8f4a0431 Mon Sep 17 00:00:00 2001 From: "Joshua A. Horton" Date: Fri, 5 Jul 2024 14:54:07 +0700 Subject: [PATCH 13/26] change(common/models): clean up trie construction code, add unit tests --- common/models/templates/src/index.ts | 1 + common/models/templates/src/trie-builder.ts | 26 +- common/models/templates/src/trie.ts | 23 +- .../templates/test/test-trie-builder.js | 257 ++++++++++++++++++ 4 files changed, 281 insertions(+), 26 deletions(-) create mode 100644 common/models/templates/test/test-trie-builder.js diff --git a/common/models/templates/src/index.ts b/common/models/templates/src/index.ts index b67528a355d..d4d9e645740 100644 --- a/common/models/templates/src/index.ts +++ b/common/models/templates/src/index.ts @@ -8,4 +8,5 @@ export { Entry, InternalNode, Leaf, Node } from './trie.js'; export { TrieBuilder } from './trie-builder.js'; +export * as trieConstruction from './trie-builder.js'; export { default as TrieModel, TrieModelOptions } from "./trie-model.js"; \ No newline at end of file diff --git a/common/models/templates/src/trie-builder.ts b/common/models/templates/src/trie-builder.ts index 0ac5cfa5756..f88956dcbfe 100644 --- a/common/models/templates/src/trie-builder.ts +++ b/common/models/templates/src/trie-builder.ts @@ -1,7 +1,7 @@ import { SENTINEL_CODE_UNIT, Wordform2Key } from "./common.js"; import { Entry, InternalNode, Leaf, Node, Trie } from "./trie.js"; -function createRootNode(): Node { +export function createRootNode(): Node { return { type: 'leaf', weight: 0, @@ -10,7 +10,8 @@ function createRootNode(): Node { } /** - * Adds an entry to the trie. + * Adds an entry to the trie. Currently assumes there is no pre-existing match + * for the entry. * * Note that the trie will likely be unsorted after the add occurs. Before * performing a lookup on the trie, use call sortTrie() on the root note! @@ -20,7 +21,7 @@ function createRootNode(): Node { * @param index the index in the key and also the trie depth. Should be set to * zero when adding onto the root node of the trie. */ -function addUnsorted(node: Node, entry: Entry, index: number = 0) { +export function addUnsorted(node: Node, entry: Entry, index: number = 0) { // Each node stores the MAXIMUM weight out of all of its decesdents, to // enable a greedy search through the trie. node.weight = Math.max(node.weight, entry.weight); @@ -48,7 +49,7 @@ function addUnsorted(node: Node, entry: Entry, index: number = 0) { * @param item * @param index */ -function addItemToInternalNode(node: InternalNode, item: Entry, index: number) { +export function addItemToInternalNode(node: InternalNode, item: Entry, index: number) { let char = item.key[index]; // If an internal node is the proper site for item, it belongs under the // corresponding (sentinel, internal-use) child node signifying this. @@ -62,7 +63,7 @@ function addItemToInternalNode(node: InternalNode, item: Entry, index: number) { addUnsorted(node.children[char], item, index + 1); } -function addItemToLeaf(leaf: Leaf, item: Entry) { +export function addItemToLeaf(leaf: Leaf, item: Entry) { leaf.entries.push(item); } @@ -74,7 +75,7 @@ function addItemToLeaf(leaf: Leaf, item: Entry) { * * @param depth depth of the trie at this level. */ -function convertLeafToInternalNode(leaf: Leaf, depth: number): void { +export function convertLeafToInternalNode(leaf: Leaf, depth: number): void { let entries = leaf.entries; // Alias the current node, as the desired type. @@ -108,7 +109,7 @@ function convertLeafToInternalNode(leaf: Leaf, depth: number): void { * Recursively sort the trie, in descending order of weight. * @param node any node in the trie */ -function sortTrie(node: Node) { +export function sortNode(node: Node, onlyLocal?: boolean) { if (node.type === 'leaf') { if (!node.unsorted) { return; @@ -116,9 +117,11 @@ function sortTrie(node: Node) { node.entries.sort(function (a, b) { return b.weight - a.weight; }); } else { - // We MUST recurse and sort children before returning. - for (let char of node.values) { - sortTrie(node.children[char]); + if(!onlyLocal) { + // We recurse and sort children before returning if sorting the full Trie. + for (let char of node.values) { + sortNode(node.children[char], onlyLocal); + } } if (!node.unsorted) { @@ -160,7 +163,8 @@ export class TrieBuilder extends Trie { } sort() { - sortTrie(this.root); + // Sorts the full Trie, not just a part of it. + sortNode(this.root); } getRoot(): Node { diff --git a/common/models/templates/src/trie.ts b/common/models/templates/src/trie.ts index 47dc6fe5dc6..7fda0b86b88 100644 --- a/common/models/templates/src/trie.ts +++ b/common/models/templates/src/trie.ts @@ -1,4 +1,5 @@ import { isHighSurrogate, isSentinel, SearchKey, SENTINEL_CODE_UNIT, Wordform2Key } from "./common.js"; +import { sortNode } from "./trie-builder.js"; // The following trie implementation has been (heavily) derived from trie-ing // by Conrad Irwin. @@ -62,7 +63,7 @@ export class TrieTraversal implements LexiconTraversal { * The current traversal node. Serves as the 'root' of its own sub-Trie, * and we cannot navigate back to its parent. */ - root: Node; + readonly root: Node; /** * The max weight for the Trie being 'traversed'. Needed for probability @@ -98,25 +99,15 @@ export class TrieTraversal implements LexiconTraversal { return traversal; } - private sortNodeIfNeeded(node: Node) { - if(node.unsorted) { - if(node.type == 'leaf') { - node.entries.sort((a, b) => b.weight - a.weight) - } else { - node.values.sort((a, b) => node.children[b].weight - node.children[a].weight); - } - - node.unsorted = false; - } - } - // Handles one code unit at a time. private _child(char: USVString): TrieTraversal | undefined { const root = this.root; const totalWeight = this.totalWeight; const nextPrefix = this.prefix + char; - this.sortNodeIfNeeded(root); + // Sorts _just_ the current level, and only if needed. + // We only care about sorting parts that we're actually accessing. + sortNode(root, true); if(root.type == 'internal') { let childNode = root.children[char]; @@ -143,7 +134,9 @@ export class TrieTraversal implements LexiconTraversal { let root = this.root; const totalWeight = this.totalWeight; - this.sortNodeIfNeeded(root); + // Sorts _just_ the current level, and only if needed. + // We only care about sorting parts that we're actually accessing. + sortNode(root, true); if(root.type == 'internal') { for(let entry of root.values) { diff --git a/common/models/templates/test/test-trie-builder.js b/common/models/templates/test/test-trie-builder.js new file mode 100644 index 00000000000..ddf03178af2 --- /dev/null +++ b/common/models/templates/test/test-trie-builder.js @@ -0,0 +1,257 @@ +/* + * Unit tests for the Trie prediction model. + */ + +import { assert } from 'chai'; +import { SENTINEL_CODE_UNIT, trieConstruction, TrieBuilder } from '@keymanapp/models-templates'; + +describe('trie construction', () => { + it('default root node', () => { + const defaultRoot = trieConstruction.createRootNode(); + assert.equal(defaultRoot.type, 'leaf'); + assert.equal(defaultRoot.weight, 0); + assert.sameMembers(defaultRoot.entries, []); + }); + + it('addItemToLeaf', () => { + // `weight` is managed by addUnsorted, not by addItemToLeaf. + // As a result, we don't test for it here. + const defaultRoot = trieConstruction.createRootNode(); + trieConstruction.addItemToLeaf(defaultRoot, { + content: 'cafe', + weight: 2, + key: 'cafe' + }); + + assert.equal(defaultRoot.type, 'leaf'); + assert.equal(defaultRoot.entries.length, 1); + + trieConstruction.addItemToLeaf(defaultRoot, { + content: 'café', + weight: 1, + key: 'cafe' + }); + + assert.equal(defaultRoot.type, 'leaf'); + assert.equal(defaultRoot.entries.length, 2); + }); + + it('convertLeafToInternalNode', () => { + const defaultRoot = trieConstruction.createRootNode(); + const cafeEntry = { + content: 'cafe', + weight: 5, + key: 'cafe' + }; + trieConstruction.addItemToLeaf(defaultRoot, cafeEntry); + + defaultRoot.weight = 5; + trieConstruction.convertLeafToInternalNode(defaultRoot, 4); + + assert.equal(defaultRoot.type, 'internal'); + assert.sameMembers(defaultRoot.values, [SENTINEL_CODE_UNIT]); + assert.sameMembers(Object.keys(defaultRoot.children), defaultRoot.values); + assert.equal(defaultRoot.weight, 5); + + const sentinelChild = defaultRoot.children[SENTINEL_CODE_UNIT]; + assert.equal(sentinelChild.type, 'leaf'); + assert.equal(sentinelChild.weight, 5); + assert.equal(sentinelChild.entries.length, 1); + // Should be strict-equal too, but we only really care if it's deep-equal. + assert.deepEqual(sentinelChild.entries[0], cafeEntry); + }); + + it('addUnsorted - simple initial entry', () => { + // `weight` is managed by addUnsorted, not by addItemToLeaf. + // As a result, we don't test for it here. + const defaultRoot = trieConstruction.createRootNode(); + trieConstruction.addUnsorted(defaultRoot, { + content: 'cafe', + weight: 2, + key: 'cafe' + }, 4); + + assert.equal(defaultRoot.type, 'leaf'); + assert.equal(defaultRoot.weight, 2); + assert.equal(defaultRoot.entries.length, 1); + + // smaller weight, will not override. Is not additive. + trieConstruction.addUnsorted(defaultRoot, { + content: 'café', + weight: 1, + key: 'cafe' + }, 4); + + assert.equal(defaultRoot.type, 'leaf'); + assert.equal(defaultRoot.weight, 2); + assert.equal(defaultRoot.entries.length, 2); + }); + + it('addUnsorted - short word, then longer word with same prefix', () => { + const defaultRoot = trieConstruction.createRootNode(); + trieConstruction.addUnsorted(defaultRoot, { + content: 'cafe', + weight: 5, + key: 'cafe' + }, 4); + + assert.equal(defaultRoot.type, 'leaf'); + assert.equal(defaultRoot.weight, 5); + assert.equal(defaultRoot.entries.length, 1); + + // smaller weight, will not override. Is not additive. + trieConstruction.addUnsorted(defaultRoot, { + content: 'cafeteria', + weight: 3, + key: 'cafeteria' + }, 4); + + assert.equal(defaultRoot.type, 'internal'); + assert.equal(defaultRoot.weight, 5); + assert.deepEqual(defaultRoot.values, [SENTINEL_CODE_UNIT, 't']); + assert.equal(defaultRoot.children[SENTINEL_CODE_UNIT].weight, 5); + assert.equal(defaultRoot.children['t'].weight, 3); + }); + + it('addUnsorted', () => { + // Perspective: current root is actually representing `ca`. + const defaultRoot = trieConstruction.createRootNode(); + trieConstruction.addUnsorted(defaultRoot, { + content: 'cafe', + weight: 5, + key: 'cafe' + }, 2); + + // There's only one child, so there's no reason to start making + // internal structure just yet. + assert.equal(defaultRoot.type, 'leaf'); + assert.equal(defaultRoot.weight, 5); + + // Adds a second child; that child has more than one letter not-in-common with the first. + trieConstruction.addUnsorted(defaultRoot, { + content: 'call', + weight: 8, + key: 'call' + }, 2); + + assert.equal(defaultRoot.type, 'internal'); + assert.equal(defaultRoot.weight, 8); + assert.sameMembers(defaultRoot.values, ['f', 'l']); + assert.equal(defaultRoot.children['f'].weight, 5); + assert.equal(defaultRoot.children['l'].weight, 8); + }); + + it('addUnsorted - lower frequency prefix', () => { + // Will correspond to 'thin'. + const root = trieConstruction.createRootNode(); + trieConstruction.addUnsorted(root, { + key: 'think', + content: 'think', + weight: 100 + }, 4); + trieConstruction.addUnsorted(root, { + key: 'thing', + content: 'thing', + weight: 40 + }, 4); + + assert.equal(root.type, 'internal'); + assert.sameMembers(root.values, ['k', 'g']); + + // Interesting noted behavior: if just 'think' into 'thin', and nothing else... + // it remains a leaf! That doesn't seem... entirely proper. With 'thing', it + // will at least be an 'internal' node already. + trieConstruction.addUnsorted(root, { + key: 'thin', + content: 'thin', + weight: 20 + }, 4); + + assert.sameMembers(root.values, ['k', 'g', SENTINEL_CODE_UNIT]); + assert.isOk(root.children[SENTINEL_CODE_UNIT]); + assert.equal(root.children[SENTINEL_CODE_UNIT].weight, 20); + }); + + describe('TrieBuilder', () => { + it('standard Trie construction', () => { + const builder = new TrieBuilder((text) => text); + builder.addEntry('caffeine', 2); + builder.addEntry('cafe', 5); + builder.addEntry('calm', 3); + builder.addEntry('calf', 4); + builder.addEntry('call', 6); // total: 20 + builder.addEntry('can', 10); // total: 30 + builder.addEntry('and', 20); // total: 50 + + assert.equal(builder.getTotalWeight(), 50); + + const root = builder.getRoot(); + const aNode = root.children['c'].children['a']; + + // As the nodes were not added in sorted order, they should not currently be ordered. + assert.sameMembers(aNode.values, ['n', 'l', 'f']); + assert.notSameOrderedMembers(aNode.values, ['n', 'l', 'f']); + + const lNode = aNode.children['l']; + assert.sameMembers(lNode.values, ['l', 'f', 'm']); + assert.notSameOrderedMembers(lNode.values, ['l', 'f', 'm']); + + builder.sort(); + + assert.sameOrderedMembers(aNode.values, ['n', 'l', 'f']); + assert.sameOrderedMembers(lNode.values, ['l', 'f', 'm']); + }); + + // In case of high startup-time for user-dictionary processing, this could allow use + // of a 'partially' processed user wordlist. (We'd prioritize predicting when the + // user is interacting with text, then resume processing once 'idle'.) + it('interspersed construction + lookup', () => { + const builder = new TrieBuilder((text) => text); + builder.addEntry('caffeine', 2); + builder.addEntry('cafe', 5); + builder.addEntry('calm', 3); + builder.addEntry('calf', 4); + builder.addEntry('call', 6); // total: 20 + + // ------------------------------------------ + // Pause construction; actually use the Trie. + + assert.equal(builder.getTotalWeight(), 20); + const root = builder.getRoot(); + const caNode = root.children['c'].children['a']; + + // As the nodes were not added in sorted order, they should not currently be ordered. + assert.sameMembers(caNode.values, ['l', 'f']); + assert.notSameOrderedMembers(caNode.values, ['l', 'f']); + + const cal = builder.traverseFromRoot().child('cal'); + // Actually traversing through the node should auto-sort the entries. + assert.sameOrderedMembers(caNode.values, ['l', 'f']); + // Including the reached node's children. + assert.sameOrderedMembers([...cal.children()].map((entry) => entry.char), ['l', 'f', 'm']); + + const cafNode = caNode.children['f']; + + // 'caffeine' was added before 'cafe'. + // Parts not 'traversed' should not be unnecessarily sorted. + assert.notSameOrderedMembers(cafNode.values, ['e', 'f']); + + // ------------------- + // Resume construction + + builder.addEntry('can', 10); // total: 30 + builder.addEntry('and', 20); // total: 50 + + assert.equal(builder.getTotalWeight(), 50); + + // As the nodes were not added in sorted order, they should not currently be ordered. + assert.sameMembers(caNode.values, ['n', 'l', 'f']); + // 'n' was added later, thus will be out of sorted order. + assert.notSameOrderedMembers(caNode.values, ['n', 'l', 'f']); + + builder.sort(); + + assert.sameOrderedMembers(caNode.values, ['n', 'l', 'f']); + }); + }); +}); \ No newline at end of file From 32a31bc693003b84d553e035b88cc5da5c028f91 Mon Sep 17 00:00:00 2001 From: "Joshua A. Horton" Date: Fri, 2 Aug 2024 13:36:07 +0700 Subject: [PATCH 14/26] fix(developer): add 'build' dependency link to models/templates --- developer/src/kmc-model/build.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/developer/src/kmc-model/build.sh b/developer/src/kmc-model/build.sh index c549648b451..d0cf48817bb 100755 --- a/developer/src/kmc-model/build.sh +++ b/developer/src/kmc-model/build.sh @@ -13,7 +13,7 @@ THIS_SCRIPT="$(readlink -f "${BASH_SOURCE[0]}")" builder_describe "Keyman kmc Lexical Model Compiler module" \ "@/common/web/keyman-version" \ "@/developer/src/common/web/test-helpers" \ - "@/common/models/templates test" \ + "@/common/models/templates" \ "clean" \ "configure" \ "build" \ From 3b563361284f61b76cd09533d514d85a0b10502e Mon Sep 17 00:00:00 2001 From: "Joshua A. Horton" Date: Fri, 2 Aug 2024 14:11:25 +0700 Subject: [PATCH 15/26] fix(common/models): relocates sortNode to avoid cyclic imports --- common/models/templates/src/trie-builder.ts | 33 +-------------------- common/models/templates/src/trie.ts | 32 +++++++++++++++++++- 2 files changed, 32 insertions(+), 33 deletions(-) diff --git a/common/models/templates/src/trie-builder.ts b/common/models/templates/src/trie-builder.ts index f88956dcbfe..790923a1e49 100644 --- a/common/models/templates/src/trie-builder.ts +++ b/common/models/templates/src/trie-builder.ts @@ -1,5 +1,5 @@ import { SENTINEL_CODE_UNIT, Wordform2Key } from "./common.js"; -import { Entry, InternalNode, Leaf, Node, Trie } from "./trie.js"; +import { Entry, InternalNode, Leaf, Node, Trie, sortNode } from "./trie.js"; export function createRootNode(): Node { return { @@ -105,37 +105,6 @@ export function convertLeafToInternalNode(leaf: Leaf, depth: number): void { internal.unsorted = true; } -/** - * Recursively sort the trie, in descending order of weight. - * @param node any node in the trie - */ -export function sortNode(node: Node, onlyLocal?: boolean) { - if (node.type === 'leaf') { - if (!node.unsorted) { - return; - } - - node.entries.sort(function (a, b) { return b.weight - a.weight; }); - } else { - if(!onlyLocal) { - // We recurse and sort children before returning if sorting the full Trie. - for (let char of node.values) { - sortNode(node.children[char], onlyLocal); - } - } - - if (!node.unsorted) { - return; - } - - node.values.sort((a, b) => { - return node.children[b].weight - node.children[a].weight; - }); - } - - delete node.unsorted; -} - /** * Wrapper class for the trie and its nodes. */ diff --git a/common/models/templates/src/trie.ts b/common/models/templates/src/trie.ts index 7fda0b86b88..7918c8023b1 100644 --- a/common/models/templates/src/trie.ts +++ b/common/models/templates/src/trie.ts @@ -1,5 +1,4 @@ import { isHighSurrogate, isSentinel, SearchKey, SENTINEL_CODE_UNIT, Wordform2Key } from "./common.js"; -import { sortNode } from "./trie-builder.js"; // The following trie implementation has been (heavily) derived from trie-ing // by Conrad Irwin. @@ -53,6 +52,37 @@ export interface Entry { weight: number; } +/** + * Recursively sort the trie, in descending order of weight. + * @param node any node in the trie + */ +export function sortNode(node: Node, onlyLocal?: boolean) { + if (node.type === 'leaf') { + if (!node.unsorted) { + return; + } + + node.entries.sort(function (a, b) { return b.weight - a.weight; }); + } else { + if(!onlyLocal) { + // We recurse and sort children before returning if sorting the full Trie. + for (let char of node.values) { + sortNode(node.children[char], onlyLocal); + } + } + + if (!node.unsorted) { + return; + } + + node.values.sort((a, b) => { + return node.children[b].weight - node.children[a].weight; + }); + } + + delete node.unsorted; +} + export class TrieTraversal implements LexiconTraversal { /** * The lexical prefix corresponding to the current traversal state. From 58a0f2161a4c30da3985d778c4d3d430ae7408de Mon Sep 17 00:00:00 2001 From: "Joshua A. Horton" Date: Wed, 7 Aug 2024 11:45:38 +0700 Subject: [PATCH 16/26] chore(web): update for new base branch --- .../templates/src/{tries/compression.ts => trie-compression.ts} | 2 +- .../test/{trie-compression.js => test-trie-compression.js} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename common/models/templates/src/{tries/compression.ts => trie-compression.ts} (99%) rename common/models/templates/test/{trie-compression.js => test-trie-compression.js} (100%) diff --git a/common/models/templates/src/tries/compression.ts b/common/models/templates/src/trie-compression.ts similarity index 99% rename from common/models/templates/src/tries/compression.ts rename to common/models/templates/src/trie-compression.ts index 3c93b25c8ce..7aa3273935e 100644 --- a/common/models/templates/src/tries/compression.ts +++ b/common/models/templates/src/trie-compression.ts @@ -1,4 +1,4 @@ -import { Entry, InternalNode, Leaf, Node } from "../trie-model.js"; +import { Entry, InternalNode, Leaf, Node } from "./trie.js"; // const SINGLE_CHAR_RANGE = Math.pow(2, 16) - 64; // const ENCODED_NUM_BASE = 64; diff --git a/common/models/templates/test/trie-compression.js b/common/models/templates/test/test-trie-compression.js similarity index 100% rename from common/models/templates/test/trie-compression.js rename to common/models/templates/test/test-trie-compression.js From d1b5d8c69f5c00e74b95c6a88113e34d32a638e6 Mon Sep 17 00:00:00 2001 From: "Joshua A. Horton" Date: Wed, 7 Aug 2024 11:45:38 +0700 Subject: [PATCH 17/26] chore(web): update for new base branch --- .../templates/src/{tries/compression.ts => trie-compression.ts} | 2 +- .../test/{trie-compression.js => test-trie-compression.js} | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename common/models/templates/src/{tries/compression.ts => trie-compression.ts} (99%) rename common/models/templates/test/{trie-compression.js => test-trie-compression.js} (99%) diff --git a/common/models/templates/src/tries/compression.ts b/common/models/templates/src/trie-compression.ts similarity index 99% rename from common/models/templates/src/tries/compression.ts rename to common/models/templates/src/trie-compression.ts index 3c93b25c8ce..7aa3273935e 100644 --- a/common/models/templates/src/tries/compression.ts +++ b/common/models/templates/src/trie-compression.ts @@ -1,4 +1,4 @@ -import { Entry, InternalNode, Leaf, Node } from "../trie-model.js"; +import { Entry, InternalNode, Leaf, Node } from "./trie.js"; // const SINGLE_CHAR_RANGE = Math.pow(2, 16) - 64; // const ENCODED_NUM_BASE = 64; diff --git a/common/models/templates/test/trie-compression.js b/common/models/templates/test/test-trie-compression.js similarity index 99% rename from common/models/templates/test/trie-compression.js rename to common/models/templates/test/test-trie-compression.js index 77fc25aaad9..d22195bd69f 100644 --- a/common/models/templates/test/trie-compression.js +++ b/common/models/templates/test/test-trie-compression.js @@ -7,7 +7,7 @@ import { compressEntry, decompressEntry, compressNode, decompressNode, compressNumber, decompressNumber -} from '@keymanapp/models-templates/obj/tries/compression.js'; +} from '@keymanapp/models-templates/obj/trie-compression.js'; import fs from 'fs'; From 5c5c0b19964fe4541ae6ef07368e85f4e00ebb58 Mon Sep 17 00:00:00 2001 From: "Joshua A. Horton" Date: Wed, 7 Aug 2024 12:15:25 +0700 Subject: [PATCH 18/26] change(common/models): recompute entry keys via keying func --- .../models/templates/src/trie-compression.ts | 27 ++++++++----------- .../templates/test/test-trie-compression.js | 24 ++++++++--------- 2 files changed, 22 insertions(+), 29 deletions(-) diff --git a/common/models/templates/src/trie-compression.ts b/common/models/templates/src/trie-compression.ts index 7aa3273935e..573c5b96981 100644 --- a/common/models/templates/src/trie-compression.ts +++ b/common/models/templates/src/trie-compression.ts @@ -44,30 +44,29 @@ export function compressNumber(num: number, width?: number) { return compressed; } -const ENTRY_HEADER_WIDTH = NODE_SIZE_WIDTH + WEIGHT_WIDTH + 1; +const ENTRY_HEADER_WIDTH = NODE_SIZE_WIDTH + WEIGHT_WIDTH; // encoded ENTRY: // - entryLen: 2 char // - total encoded size of all following bits. // - as raw, concatenated string data - no JSON.stringify action taken. // - weight: 2? chars (with quote-offset on each char?) -// - keyLen: 1 char (with quote-offset?) // - contentLen: safe to infer from all other values -// - key: string: from index [header+5] to [header+5 + keyLen - 1] -// - content: string: from [header+5 + keyLen] to [header+5 + keyLen + contentLen - 1] +// - content: string: from [header+4] to [header+4 + contentLen - 1] +// +// - key: not encoded; we can regenerate it via the keying function export function compressEntry(entry: Entry): string { - const { key, content, weight } = entry; + const { content, weight } = entry; - const keyLenEnc = compressNumber(key.length); const weightEnc = compressNumber(weight, WEIGHT_WIDTH); - const entryLenEnc = compressNumber(key.length + content.length + ENTRY_HEADER_WIDTH, 2); + const entryLenEnc = compressNumber(content.length + ENTRY_HEADER_WIDTH, 2); - return `${entryLenEnc}${weightEnc}${keyLenEnc}${key}${content}`; + return `${entryLenEnc}${weightEnc}${content}`; } -export function decompressEntry(str: string, baseIndex: number): Entry { +export function decompressEntry(str: string, keyFunction: (val: string) => string, baseIndex: number): Entry { baseIndex ||= 0; const entryLen = decompressNumber(str, baseIndex + 0, baseIndex + NODE_SIZE_WIDTH); @@ -78,15 +77,11 @@ export function decompressEntry(str: string, baseIndex: number): Entry { // c8 ignore end const headerEnd = baseIndex + ENTRY_HEADER_WIDTH; - const weight = decompressNumber(str, baseIndex + NODE_SIZE_WIDTH, headerEnd - 1); - const keyLen = decompressNumber(str, headerEnd - 1, headerEnd); - - const contentStart = headerEnd + keyLen; - const key = str.substring(headerEnd, contentStart); - const content = str.substring(contentStart, baseIndex + entryLen); + const weight = decompressNumber(str, baseIndex + NODE_SIZE_WIDTH, headerEnd); + const content = str.substring(headerEnd, baseIndex + entryLen); return { - key: key as any, // due to special `SearchKey` type shenanigans in its definition. + key: keyFunction(content) as any, // needed due to special `SearchKey` type shenanigans in its definition. content: content, weight: weight } diff --git a/common/models/templates/test/test-trie-compression.js b/common/models/templates/test/test-trie-compression.js index d22195bd69f..8e171f1bc15 100644 --- a/common/models/templates/test/test-trie-compression.js +++ b/common/models/templates/test/test-trie-compression.js @@ -9,7 +9,11 @@ import { compressNumber, decompressNumber } from '@keymanapp/models-templates/obj/trie-compression.js'; -import fs from 'fs'; +/** + * @param {string} str + * @returns + */ +const identityKey = (str) => str; // Written with: // const ENCODED_NUM_BASE = 0; // 0x0020; @@ -20,9 +24,9 @@ import fs from 'fs'; const TEST_DATA = {}; TEST_DATA.ENTRIES = { four: { - // total length: header = 5, text = 8 -> 13. (Made with weight-width 2) + // total length: header = 4, text = 4 -> 8. (Made with weight-width 2) // -totalLen- -weight- -keylen- - compressed: '\u0000\u000d\u0000\u0008\u0004fourfour', + compressed: '\u0000\u0008\u0000\u0008four', decompressed: { key: 'four', content: 'four', @@ -40,7 +44,7 @@ TEST_DATA.LEAVES = { four: { // expected width difference: 5 (2: total size, 2: weight, 1: entry count) // -totalLen- -weight- -type/size- - compressed: `\u0000\u0012\u0000\u0008\u8001${TEST_DATA.ENTRIES.four.compressed}`, + compressed: `\u0000\u000D\u0000\u0008\u8001${TEST_DATA.ENTRIES.four.compressed}`, decompressed: { type: 'leaf', weight: 8, @@ -62,7 +66,7 @@ TEST_DATA.NODES = { four: { // expected width difference: 6 (2: total size, 2: weight, 1: entry count, 1: value count) // -totalLen- -weight- -type/size- - compressed: `\u0000\u0018\u0000\u0008\u0001r${TEST_DATA.LEAVES.four.compressed}`, + compressed: `\u0000\u0013\u0000\u0008\u0001r${TEST_DATA.LEAVES.four.compressed}`, decompressed: { type: 'internal', weight: 8, @@ -109,12 +113,6 @@ describe('Trie compression', function() { describe('`Entry`s', () => { it('compresses properly', () => { - const entry = { - key: 'four', - content: 'four', - weight: 8 - }; - assert.equal(compressEntry(TEST_DATA.ENTRIES.four.original), TEST_DATA.ENTRIES.four.compressed); }); }); @@ -178,7 +176,7 @@ describe('Trie decompression', function () { it('not inlined', () => { const mockedDecompression = TEST_DATA.ENTRIES.four.decompressed; const compressionSrc = TEST_DATA.ENTRIES.four.compressed; - assert.deepEqual(decompressEntry(compressionSrc), mockedDecompression); + assert.deepEqual(decompressEntry(compressionSrc, identityKey), mockedDecompression); }); it('inlined', () => { @@ -186,7 +184,7 @@ describe('Trie decompression', function () { // total length: header = 5, text = 8 -> 13. const compressionSrc = `xxxxx${TEST_DATA.ENTRIES.four.compressed}xx`; - assert.deepEqual(decompressEntry(compressionSrc, /* start index */ 5), mockedDecompression); + assert.deepEqual(decompressEntry(compressionSrc, identityKey, /* start index */ 5), mockedDecompression); }); }); From 5933d217116d88e84bbd2e6266fc0e43a5c94bd6 Mon Sep 17 00:00:00 2001 From: "Joshua A. Horton" Date: Wed, 7 Aug 2024 12:30:53 +0700 Subject: [PATCH 19/26] change(common/models): sets leaves to auto-decompress entries --- .../models/templates/src/trie-compression.ts | 14 +++++++------- .../templates/test/test-trie-compression.js | 19 ++++++++----------- 2 files changed, 15 insertions(+), 18 deletions(-) diff --git a/common/models/templates/src/trie-compression.ts b/common/models/templates/src/trie-compression.ts index 573c5b96981..400e3451a74 100644 --- a/common/models/templates/src/trie-compression.ts +++ b/common/models/templates/src/trie-compression.ts @@ -66,7 +66,7 @@ export function compressEntry(entry: Entry): string { return `${entryLenEnc}${weightEnc}${content}`; } -export function decompressEntry(str: string, keyFunction: (val: string) => string, baseIndex: number): Entry { +export function decompressEntry(str: string, keyFunction: (text: string) => string, baseIndex: number): Entry { baseIndex ||= 0; const entryLen = decompressNumber(str, baseIndex + 0, baseIndex + NODE_SIZE_WIDTH); @@ -106,7 +106,7 @@ export function compressNode(node: Node) { return `${compressNumber(charLength, 2)}${weightEnc}${encodedSpecifics}`; } -export function decompressNode(str: string, baseIndex: number) { +export function decompressNode(str: string, keyFunction: (text: string) => string, baseIndex: number) { baseIndex ||= 0; const entryLen = decompressNumber(str, baseIndex + 0, baseIndex + NODE_SIZE_WIDTH); @@ -119,7 +119,7 @@ export function decompressNode(str: string, baseIndex: number) { const typeFlagSrc = decompressNumber(str, baseIndex + NODE_TYPE_INDEX, baseIndex + NODE_TYPE_INDEX + 1); const isLeafType = typeFlagSrc & 0x8000; - return isLeafType ? decompressLeaf(str, baseIndex) : decompressInternal(str, baseIndex); + return isLeafType ? decompressLeaf(str, keyFunction, baseIndex) : decompressInternal(str, baseIndex); } // encoded LEAF: @@ -146,7 +146,7 @@ function compressLeaf(leaf: Leaf): string { return compressedEntries.join(''); } -function decompressLeaf(str: string, baseIndex: number): Omit & {entries: string[]} { +function decompressLeaf(str: string, keyFunction: (text: string) => string, baseIndex: number): Leaf { const weight = decompressNumber(str, baseIndex + NODE_SIZE_WIDTH, baseIndex + NODE_SIZE_WIDTH + WEIGHT_WIDTH); // Assumes string-subsection size check has passed. @@ -154,12 +154,12 @@ function decompressLeaf(str: string, baseIndex: number): Omit & // Remove the type-flag bit indicating 'leaf node'. const entryCnt = entryCntSrc & 0x007F; - let compressedEntries: string[] = []; + let entries: Entry[] = []; baseIndex = baseIndex + NODE_TYPE_INDEX + 1; for(let i = 0; i < entryCnt; i++) { const entryWidth = decompressNumber(str, baseIndex, baseIndex+2); const nextIndex = baseIndex + entryWidth; - compressedEntries.push(str.substring(baseIndex, nextIndex)); + entries.push(decompressEntry(str, keyFunction, baseIndex)); baseIndex = nextIndex; } @@ -171,7 +171,7 @@ function decompressLeaf(str: string, baseIndex: number): Omit & // - would use more memory, especially once a Trie is "mostly" decompressed // - current approach 'discards' decoded parts of the original string. // - would likely decompress a bit faster. - entries: compressedEntries + entries: entries } } diff --git a/common/models/templates/test/test-trie-compression.js b/common/models/templates/test/test-trie-compression.js index 8e171f1bc15..8296fcac9cf 100644 --- a/common/models/templates/test/test-trie-compression.js +++ b/common/models/templates/test/test-trie-compression.js @@ -48,7 +48,7 @@ TEST_DATA.LEAVES = { decompressed: { type: 'leaf', weight: 8, - entries: [TEST_DATA.ENTRIES.four.compressed] + entries: [TEST_DATA.ENTRIES.four.decompressed] }, original: { type: 'leaf', @@ -192,12 +192,12 @@ describe('Trie decompression', function () { describe('bootstrapping cases', () => { it('not inlined', () => { const encodedLeaf = TEST_DATA.LEAVES.four.compressed; - assert.deepEqual(decompressNode(encodedLeaf, 0), TEST_DATA.LEAVES.four.decompressed); + assert.deepEqual(decompressNode(encodedLeaf, identityKey, 0), TEST_DATA.LEAVES.four.decompressed); }); it('inlined', () => { const encodedLeaf = TEST_DATA.LEAVES.four.compressed; - assert.deepEqual(decompressNode(`xxxxxxxxx${encodedLeaf}xx`, 9), TEST_DATA.LEAVES.four.decompressed); + assert.deepEqual(decompressNode(`xxxxxxxxx${encodedLeaf}xx`, identityKey, 9), TEST_DATA.LEAVES.four.decompressed); }); }); }); @@ -206,12 +206,12 @@ describe('Trie decompression', function () { describe('bootstrapping cases', () => { it('not inlined', () => { const encodedNode = TEST_DATA.NODES.four.compressed; - assert.deepEqual(decompressNode(encodedNode, 0), TEST_DATA.NODES.four.decompressed); + assert.deepEqual(decompressNode(encodedNode, identityKey, 0), TEST_DATA.NODES.four.decompressed); }); it('inlined', () => { const encodedNode = TEST_DATA.NODES.four.compressed; - assert.deepEqual(decompressNode(`xxxxxxx${encodedNode}xx`, 7), TEST_DATA.NODES.four.decompressed); + assert.deepEqual(decompressNode(`xxxxxxx${encodedNode}xx`, identityKey, 7), TEST_DATA.NODES.four.decompressed); }); }); }); @@ -230,8 +230,9 @@ describe('Trie decompression', function () { }`; const compression = { - // Achieves FAR better compression than JSON.stringify, which \u-escapes most chars. - // As of the commit when this was written... + // The encoding pattern used above achives FAR better compression than + // JSON.stringify, which \u-escapes most chars. As of the commit when + // this was written, before we stopped storing 'key' for entries... // - length of encoding below: 26097 // - JSON-encoding length: 69122 // - Source fixture's filesize: 141309 bytes @@ -239,10 +240,6 @@ describe('Trie decompression', function () { totalWeight: trie.totalWeight } - // We could easily get even better savings (with some cost) by using the search-term-to-key function - // as part of decompression, avoiding the near-duplicating key/content effect we currently have. - // - if we didn't save the keys: 20490 (estimation) (~21.4% savings) - // TODO: Temp code for diagnostics & exploration. console.log(`Compressed length: ${compression.root.length}`); console.log(`Result: ${compression.root}`); From 642719625f41db021e5744d5d6316e7a43e2026e Mon Sep 17 00:00:00 2001 From: "Joshua A. Horton" Date: Wed, 7 Aug 2024 12:57:16 +0700 Subject: [PATCH 20/26] change(common/models): adjust unit tests to work with alternate encoding bases --- .../models/templates/src/trie-compression.ts | 4 +- .../templates/test/test-trie-compression.js | 52 +++++++++---------- 2 files changed, 26 insertions(+), 30 deletions(-) diff --git a/common/models/templates/src/trie-compression.ts b/common/models/templates/src/trie-compression.ts index 400e3451a74..7517b615b91 100644 --- a/common/models/templates/src/trie-compression.ts +++ b/common/models/templates/src/trie-compression.ts @@ -4,8 +4,8 @@ import { Entry, InternalNode, Leaf, Node } from "./trie.js"; // const ENCODED_NUM_BASE = 64; // Offsetting by even just 0x0020 avoids control-code chars + avoids VS Code not liking the encoding. -const ENCODED_NUM_BASE = 0x0000; -const SINGLE_CHAR_RANGE = Math.pow(2, 16) - ENCODED_NUM_BASE; +export const ENCODED_NUM_BASE = 0x0020; +export const SINGLE_CHAR_RANGE = Math.pow(2, 16) - ENCODED_NUM_BASE; const WEIGHT_WIDTH = 2; const NODE_SIZE_WIDTH = 2; diff --git a/common/models/templates/test/test-trie-compression.js b/common/models/templates/test/test-trie-compression.js index 8296fcac9cf..ec53ced7034 100644 --- a/common/models/templates/test/test-trie-compression.js +++ b/common/models/templates/test/test-trie-compression.js @@ -6,7 +6,9 @@ import { assert } from 'chai'; import { compressEntry, decompressEntry, compressNode, decompressNode, - compressNumber, decompressNumber + compressNumber, decompressNumber, + ENCODED_NUM_BASE, + SINGLE_CHAR_RANGE } from '@keymanapp/models-templates/obj/trie-compression.js'; /** @@ -25,8 +27,8 @@ const TEST_DATA = {}; TEST_DATA.ENTRIES = { four: { // total length: header = 4, text = 4 -> 8. (Made with weight-width 2) - // -totalLen- -weight- -keylen- - compressed: '\u0000\u0008\u0000\u0008four', + // -totalLen- -weight- + compressed: `${compressNumber(8, 2)}${compressNumber(8, 2)}four`, decompressed: { key: 'four', content: 'four', @@ -43,8 +45,8 @@ TEST_DATA.ENTRIES = { TEST_DATA.LEAVES = { four: { // expected width difference: 5 (2: total size, 2: weight, 1: entry count) - // -totalLen- -weight- -type/size- - compressed: `\u0000\u000D\u0000\u0008\u8001${TEST_DATA.ENTRIES.four.compressed}`, + // -totalLen- -weight- -type=leaf + size- + compressed: `${compressNumber(13, 2)}${compressNumber(8, 2)}${compressNumber(0x8000 + 1, 1)}${TEST_DATA.ENTRIES.four.compressed}`, decompressed: { type: 'leaf', weight: 8, @@ -66,7 +68,7 @@ TEST_DATA.NODES = { four: { // expected width difference: 6 (2: total size, 2: weight, 1: entry count, 1: value count) // -totalLen- -weight- -type/size- - compressed: `\u0000\u0013\u0000\u0008\u0001r${TEST_DATA.LEAVES.four.compressed}`, + compressed: `${compressNumber(19, 2)}${compressNumber(8, 2)}${compressNumber(1)}r${TEST_DATA.LEAVES.four.compressed}`, decompressed: { type: 'internal', weight: 8, @@ -88,21 +90,20 @@ describe('Trie compression', function() { assert.equal(compressNumber(0x0020).length, 1); }); - it('width 1: compresses properly', () => { - assert.equal(compressNumber(0x0020, 1), ' '); - assert.equal(compressNumber('"'.charCodeAt(0), 1), '"'); - assert.equal(compressNumber(0xfffe, 1), '\ufffe'); + it('compresses properly when targeting single-char width', () => { + assert.equal(compressNumber(0x0020, 1), String.fromCharCode(0x0020 + ENCODED_NUM_BASE)); + assert.equal(compressNumber('"'.charCodeAt(0), 1), String.fromCharCode('"'.charCodeAt(0) + ENCODED_NUM_BASE)); }); - it('width 2: compresses properly', () => { - assert.equal(compressNumber(0x00200020, 2), ' '); - assert.equal( - compressNumber(0x0321fd20, 2), String.fromCharCode(0x0321, 0xfd20) + it('has non-null leading char for numbers needing two-char representations', () => { + assert.notEqual(compressNumber(0x00200020, 2).charAt(0), String.fromCharCode(0)); + assert.notEqual( + compressNumber(0x0321ad20, 2).charAt(0), String.fromCharCode(0) ); }); it('width 2: compressing values one-char wide', () => { - assert.equal(compressNumber(0x0020, 2), '\u0000 '); + assert.equal(compressNumber(0x0020, 2), `${String.fromCharCode(ENCODED_NUM_BASE)}${String.fromCharCode(0x0020 + ENCODED_NUM_BASE)}`); }); it('throws when numbers are too large for the specified width', () => { @@ -144,30 +145,25 @@ describe('Trie decompression', function () { describe('`number`s', () => { describe('not inlined', () => { it('decompresses single-char strings', () => { - assert.equal(decompressNumber(' ', 0), 0x0020); - assert.equal(decompressNumber('"', 0), '"'.charCodeAt(0)); - assert.equal(decompressNumber('\ufffe', 0), 0xfffe); - }); - - it('decompresses two-char strings', () => { - assert.equal(decompressNumber(' ', 0), 0x00200020); - assert.equal(decompressNumber(String.fromCharCode(0x0321, 0xfd20), 0), 0x0321fd20); + assert.equal(decompressNumber(String.fromCharCode(0x0020 + ENCODED_NUM_BASE), 0), 0x0020); + assert.equal(decompressNumber(String.fromCharCode('"'.charCodeAt(0) + ENCODED_NUM_BASE), 0), '"'.charCodeAt(0)); + assert.equal(decompressNumber('\ufffe', 0), 0xfffe - ENCODED_NUM_BASE); }); it('decompresses two-char strings of one-char value width', () => { - assert.equal(decompressNumber('\u0000 ', 0), 0x0020); + assert.equal(decompressNumber(`${String.fromCharCode(ENCODED_NUM_BASE)}${String.fromCharCode(0x0020 + ENCODED_NUM_BASE)}`, 0), 0x0020); }); }); describe('with mock-inlining', () => { it('decompresses single-char strings', () => { - assert.equal(decompressNumber('xxx xx', 3, 4), 0x0020); - assert.equal(decompressNumber('xx"x', 2, 3), '"'.charCodeAt(0)); - assert.equal(decompressNumber('\uffff\ufffe', 1), 0xfffe); + assert.equal(decompressNumber(`xxx${String.fromCharCode(0x0020 + ENCODED_NUM_BASE)}xx`, 3, 4), 0x0020); + assert.equal(decompressNumber(`xx${String.fromCharCode('"'.charCodeAt(0) + ENCODED_NUM_BASE)}x`, 2, 3), '"'.charCodeAt(0)); + assert.equal(decompressNumber('\uffff\ufffe', 1), 0xfffe - ENCODED_NUM_BASE); }); it('decompresses two-char strings', () => { - assert.equal(decompressNumber('xxxx xx', 4, 6), 0x00200020); + assert.equal(decompressNumber(`xxxx${compressNumber(0x00200020, 2)}xx`, 4, 6), 0x00200020); }); }); }); From 6b7feb57308d2dd9457343dea601e0f4ced1e0ff Mon Sep 17 00:00:00 2001 From: "Joshua A. Horton" Date: Thu, 8 Aug 2024 11:44:25 +0700 Subject: [PATCH 21/26] chore(common/models): clean up comments + keying-func typing --- .../models/templates/src/trie-compression.ts | 49 +++++++------------ 1 file changed, 18 insertions(+), 31 deletions(-) diff --git a/common/models/templates/src/trie-compression.ts b/common/models/templates/src/trie-compression.ts index 7517b615b91..7163ab2085c 100644 --- a/common/models/templates/src/trie-compression.ts +++ b/common/models/templates/src/trie-compression.ts @@ -1,3 +1,4 @@ +import { Wordform2Key } from "./common.js"; import { Entry, InternalNode, Leaf, Node } from "./trie.js"; // const SINGLE_CHAR_RANGE = Math.pow(2, 16) - 64; @@ -66,15 +67,15 @@ export function compressEntry(entry: Entry): string { return `${entryLenEnc}${weightEnc}${content}`; } -export function decompressEntry(str: string, keyFunction: (text: string) => string, baseIndex: number): Entry { +export function decompressEntry(str: string, keyFunction: Wordform2Key, baseIndex: number): Entry { baseIndex ||= 0; const entryLen = decompressNumber(str, baseIndex + 0, baseIndex + NODE_SIZE_WIDTH); - // c8 ignore start + /* c8 ignore start */ if(str.length < baseIndex + entryLen) { throw new Error('Parts of the encoded entry are missing'); } - // c8 ignore end + /* c8 ignore end */ const headerEnd = baseIndex + ENTRY_HEADER_WIDTH; const weight = decompressNumber(str, baseIndex + NODE_SIZE_WIDTH, headerEnd); @@ -106,15 +107,15 @@ export function compressNode(node: Node) { return `${compressNumber(charLength, 2)}${weightEnc}${encodedSpecifics}`; } -export function decompressNode(str: string, keyFunction: (text: string) => string, baseIndex: number) { +export function decompressNode(str: string, keyFunction: Wordform2Key, baseIndex: number) { baseIndex ||= 0; const entryLen = decompressNumber(str, baseIndex + 0, baseIndex + NODE_SIZE_WIDTH); - // c8 ignore start + /* c8 ignore start */ if(str.length < baseIndex + entryLen) { throw new Error('Parts of the encoded node are missing'); } - // c8 ignore end + /* c8 ignore end */ const typeFlagSrc = decompressNumber(str, baseIndex + NODE_TYPE_INDEX, baseIndex + NODE_TYPE_INDEX + 1); const isLeafType = typeFlagSrc & 0x8000; @@ -133,11 +134,11 @@ function compressLeaf(leaf: Leaf): string { // key, content, weight - per entry const entryCntAndType = entries.length | 0x8000; - // c8 ignore start + /* c8 ignore start */ if(entries.length >= 0x8000) { throw new Error("Cannot encode leaf: too many direct entries"); } - // c8 ignore end + /* c8 ignore end */ let compressedEntries = [compressNumber(entryCntAndType)].concat(entries.map((entry) => { // if already compressed, no need to recompress it. return typeof entry == 'string' ? entry : compressEntry(entry); @@ -146,7 +147,7 @@ function compressLeaf(leaf: Leaf): string { return compressedEntries.join(''); } -function decompressLeaf(str: string, keyFunction: (text: string) => string, baseIndex: number): Leaf { +function decompressLeaf(str: string, keyFunction: Wordform2Key, baseIndex: number): Leaf { const weight = decompressNumber(str, baseIndex + NODE_SIZE_WIDTH, baseIndex + NODE_SIZE_WIDTH + WEIGHT_WIDTH); // Assumes string-subsection size check has passed. @@ -190,38 +191,31 @@ function decompressLeaf(str: string, keyFunction: (text: string) => string, base function compressInternal(node: InternalNode): string { let values = node.values; const valueCntAndType = values.length; - // c8 ignore start + /* c8 ignore start */ if(valueCntAndType >= 0x8000) { throw new Error("Cannot encode node: too many direct children"); } - // c8 ignore end + /* c8 ignore end */ const compressedChildren = values.map((value) => { - // BIG ERROR DETECTED: lexical-model compiler is not emitting SENTINEL chars correctly - // for _some_ cases! '﷐' shows up for 'most', but not _all_, places where it belongs. - // Approx 20% error rate!? - // - // STRONG SUSPICION: addItemToInternalNode - // - current line 376: let char = item.key[index]; - // - does not validate that the char exists! - // - // detected via `sil.km.gcc - 1.0`. + // In case of regression for #11073 if(value === null) { value = "undefined"; // yes, really. } const child = node.children[value]; - // c8 ignore start + /* c8 ignore start */ if(!child) { throw new Error("unexpected empty reference for child"); } - // c8 ignore end + /* c8 ignore end */ // No need to recompress it if it's already compressed. return typeof child == 'string' ? child : compressNode(child); }); // Properly fix the sentinel-value issue. + // Also of note: this array may contain halves of surrogate pairs. values = values.map((value) => value === null ? '\ufdd0' : value); const totalArr = [compressNumber(valueCntAndType)].concat(values).concat(compressedChildren); @@ -254,15 +248,8 @@ function decompressInternal(str: string, baseIndex: number): Omit Date: Thu, 8 Aug 2024 11:44:54 +0700 Subject: [PATCH 22/26] feat(common/models): add TrieBuilder.compress(), unit tests reliant upon it --- common/models/templates/src/trie-builder.ts | 5 + .../templates/test/test-trie-compression.js | 129 +++++------------- 2 files changed, 42 insertions(+), 92 deletions(-) diff --git a/common/models/templates/src/trie-builder.ts b/common/models/templates/src/trie-builder.ts index 790923a1e49..c157e1e4d53 100644 --- a/common/models/templates/src/trie-builder.ts +++ b/common/models/templates/src/trie-builder.ts @@ -1,4 +1,5 @@ import { SENTINEL_CODE_UNIT, Wordform2Key } from "./common.js"; +import { compressNode } from "./trie-compression.js"; import { Entry, InternalNode, Leaf, Node, Trie, sortNode } from "./trie.js"; export function createRootNode(): Node { @@ -143,4 +144,8 @@ export class TrieBuilder extends Trie { getTotalWeight(): number { return this.totalWeight; } + + compress(): string { + return compressNode(this.root); + } } \ No newline at end of file diff --git a/common/models/templates/test/test-trie-compression.js b/common/models/templates/test/test-trie-compression.js index ec53ced7034..bbe9798b09f 100644 --- a/common/models/templates/test/test-trie-compression.js +++ b/common/models/templates/test/test-trie-compression.js @@ -7,15 +7,30 @@ import { compressEntry, decompressEntry, compressNode, decompressNode, compressNumber, decompressNumber, - ENCODED_NUM_BASE, - SINGLE_CHAR_RANGE + ENCODED_NUM_BASE } from '@keymanapp/models-templates/obj/trie-compression.js'; +import { TrieBuilder } from '@keymanapp/models-templates'; +import { Trie } from '../build/obj/trie.js'; + +const smpWordlist = [ + ['CRAZ🤪', 13644], + ['🙄', 9134], + ['😇', 4816], + ['🇸'], + ['u'] +]; + /** * @param {string} str * @returns */ const identityKey = (str) => str; +/** + * @param {string} str + * @returns + */ +const lowercaseKey = (str) => str.toLowerCase(); // Written with: // const ENCODED_NUM_BASE = 0; // 0x0020; @@ -213,103 +228,33 @@ describe('Trie decompression', function () { }); it('compresses fixture successfully: english-1000', () => { - const trie = jsonFixture('tries/english-1000'); - // The test: does it throw? - const compressedTrie = compressNode(trie.root); - - const encodedSerializableString = `${ - compressedTrie - .replace(/\\/g, '\\\\') // preservation - escape char as literal - .replace(/`/g, '\\`') // escape the primary quote - .replace(/\n/g, '\\n') // prevent CRLF shenanigans - .replace(/\r/g, '\\r') - }`; - - const compression = { + const trieFixture = jsonFixture('tries/english-1000'); + const trie = new TrieBuilder(identityKey, trieFixture.root, trieFixture.totalWeight); + + assert.doesNotThrow(() => { return { // The encoding pattern used above achives FAR better compression than // JSON.stringify, which \u-escapes most chars. As of the commit when // this was written, before we stopped storing 'key' for entries... // - length of encoding below: 26097 // - JSON-encoding length: 69122 // - Source fixture's filesize: 141309 bytes - root: `\`${encodedSerializableString}\``, - totalWeight: trie.totalWeight - } + root: `\`${trie.compress()}\``, + totalWeight: trie.getTotalWeight() + } }); - // TODO: Temp code for diagnostics & exploration. - console.log(`Compressed length: ${compression.root.length}`); - console.log(`Result: ${compression.root}`); - - // Note: a naive round-tripping test won't work. We only partly decompress - // at each step, after all. - -// // Chrome parses it safely, but VS Code complains about the encoding. -// // > "The file is not displayed in the text editor because it is either binary or uses an unsupported text encoding." -// // - likely b/c the "binary" angle. -// // -// // Complaints are dropped if all encoded numbers are offset by +0x0020. -// // - This does narrow the range of representable values a bit, though. -// // - It -also- brings manual encoding and JSON encoding into near-parity; -// // control char escapes were using a lot of space. -// // -// fs.writeFileSync('temptemp.js', `let trieData = { -// "root": ${compression.root}, -// "totalWeight": ${compression.totalWeight} -// }` -// ); - -// fs.writeFileSync('temptemp.json', `{ -// "root": ${JSON.stringify(compressedTrie)}, -// "totalWeight": ${compression.totalWeight} -// }` -// ); + // The test: did it throw? If no, we'll assume we're good. }); -// it('compresses fixture successfully: sil.km.gcc - 1.0', () => { -// const trie = jsonFixture('tries/sil.km.gcc - 1.0'); -// // The test: does it throw? -// const compressedTrie = compressNode(trie.root); - -// const encodedSerializableString = `${ -// compressedTrie -// .replace(/\\/g, '\\\\') // preservation - escape char as literal -// .replace(/`/g, '\\`') // escape the primary quote -// .replace(/\n/g, '\\n') // prevent CRLF shenanigans -// .replace(/\r/g, '\\r') -// }`; - -// const compression = { -// // Achieves FAR better compression than JSON.stringify, which \u-escapes most chars. -// // As of the commit when this was written... -// // - length of encoding below: 405468 -// // - JSON-encoding length: 1145955 -// // - Source fixture's filesize: 2491696 bytes -// // -// // As is... it compressed in 99ms on my personal development machine. -// root: `"${encodedSerializableString}"`, -// totalWeight: trie.totalWeight -// } - -// // We could easily get even better savings (with some cost) by using the search-term-to-key function -// // as part of decompression, avoiding the near-duplicating key/content effect we currently have. - -// // TODO: Temp code for diagnostics & exploration. -// console.log(`Compressed length: ${compression.root.length}`); -// // console.log(`Result: ${compression.root}`); - -// // Note: a naive round-tripping test won't work. We only partly decompress -// // at each step, after all. - -// fs.writeFileSync('temptemp.js', `let trieData = { -// "root": ${compression.root}, -// "totalWeight": ${compression.totalWeight} -// }` -// ); - -// fs.writeFileSync('temptemp.json', `{ -// "root": ${JSON.stringify(compressedTrie)}, -// "totalWeight": ${compression.totalWeight} -// }` -// ); -// }); + describe('surrogate-pair handling', () => { + it('compresses a Trie with non-BMP characters without throwing an error', () => { + const builder = new TrieBuilder(identityKey); + smpWordlist.forEach((tuple) => builder.addEntry(tuple[0], tuple[1])); + + assert.doesNotThrow(() => builder.compress()); + }); + + it.skip('properly round-trips a Trie through compression and decompression', () => { + // Requires full Trie integration, which isn't included yet. + }); + }); }); \ No newline at end of file From ee5877c645d03de7a65a8ccae1559cd39bdd5dc9 Mon Sep 17 00:00:00 2001 From: "Joshua A. Horton" Date: Fri, 9 Aug 2024 09:23:42 +0700 Subject: [PATCH 23/26] docs(common/models): improves a comment --- common/models/templates/src/trie-compression.ts | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/common/models/templates/src/trie-compression.ts b/common/models/templates/src/trie-compression.ts index 7163ab2085c..1e1e94141b9 100644 --- a/common/models/templates/src/trie-compression.ts +++ b/common/models/templates/src/trie-compression.ts @@ -89,12 +89,14 @@ export function decompressEntry(str: string, keyFunction: Wordform2Key, baseInde } -// BOTH node types: -// totalLen: 2 chars (fixed position, size) - size of the encoded node. -// weight: number - could be encoded. +// BOTH node types: totalLen: 2 chars (fixed position, size) - size of the +// encoded node. weight: number - could be encoded. // - 2^32 ~= 4*10^9, representable in 2 chars... if it weren't for `"`-escaping. // - 2^64 ~= 1.8*10^19 - surely far, far more than enough. -// Next char: indicates BOTH a flag of something and a high-bit indicating 'leaf' or 'internal'. +// +// Next char: +// indicates BOTH a count of something (entries or direct children) and a +// high-bit indicating 'leaf' or 'internal'. // - function of other bits will be indicated by their sections. export const NODE_TYPE_INDEX = NODE_SIZE_WIDTH + WEIGHT_WIDTH; From f53dfde043854a3e15e641e29984ce7e2ae926f1 Mon Sep 17 00:00:00 2001 From: "Joshua A. Horton" Date: Fri, 23 Aug 2024 09:59:03 +0700 Subject: [PATCH 24/26] chore(common/models): pulls in comment tweaks from later reviews on epic/user-dict --- common/models/templates/src/common.ts | 5 +---- developer/src/kmc-model/src/build-trie.ts | 2 -- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/common/models/templates/src/common.ts b/common/models/templates/src/common.ts index 80c4470cb54..621d8412304 100644 --- a/common/models/templates/src/common.ts +++ b/common/models/templates/src/common.ts @@ -157,15 +157,12 @@ export function defaultApplyCasing(casing: CasingForm, text: string): string { * An **opaque** type for a string that is exclusively used as a search key in * the trie. There should be a function that converts arbitrary strings * (queries) and converts them into a standard search key for a given language - * model. - * - * Fun fact: This opaque type has ALREADY saved my bacon and found a bug! */ export type SearchKey = string & { _: 'SearchKey'}; /** * A function that converts a string (word form or query) into a search key - * (secretly, this is also a string). + * (which, internally, is also a string type). */ export interface Wordform2Key { (wordform: string): SearchKey; diff --git a/developer/src/kmc-model/src/build-trie.ts b/developer/src/kmc-model/src/build-trie.ts index 9e34cd54691..6c288c6a864 100644 --- a/developer/src/kmc-model/src/build-trie.ts +++ b/developer/src/kmc-model/src/build-trie.ts @@ -192,8 +192,6 @@ function* enumerateLines(lines: string[]): Generator { * the trie. There should be a function that converts arbitrary strings * (queries) and converts them into a standard search key for a given language * model. - * - * Fun fact: This opaque type has ALREADY saved my bacon and found a bug! */ type SearchKey = string & { _: 'SearchKey'}; From b351cd1cbde04459e2750ce2f516d423396048f3 Mon Sep 17 00:00:00 2001 From: Joshua Horton Date: Tue, 27 Aug 2024 14:44:27 +0700 Subject: [PATCH 25/26] chore(common/models): Apply suggestions from code review Co-authored-by: Eberhard Beilharz --- common/models/templates/src/trie-compression.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/common/models/templates/src/trie-compression.ts b/common/models/templates/src/trie-compression.ts index 1e1e94141b9..5666afd4ffe 100644 --- a/common/models/templates/src/trie-compression.ts +++ b/common/models/templates/src/trie-compression.ts @@ -49,7 +49,7 @@ const ENTRY_HEADER_WIDTH = NODE_SIZE_WIDTH + WEIGHT_WIDTH; // encoded ENTRY: // - entryLen: 2 char -// - total encoded size of all following bits. +// - total encoded size of the entry, including `entryLen` // - as raw, concatenated string data - no JSON.stringify action taken. // - weight: 2? chars (with quote-offset on each char?) // - contentLen: safe to infer from all other values @@ -155,12 +155,12 @@ function decompressLeaf(str: string, keyFunction: Wordform2Key, baseIndex: numbe // Assumes string-subsection size check has passed. const entryCntSrc = decompressNumber(str, baseIndex + NODE_TYPE_INDEX, baseIndex + NODE_TYPE_INDEX + 1); // Remove the type-flag bit indicating 'leaf node'. - const entryCnt = entryCntSrc & 0x007F; + const entryCnt = entryCntSrc & 0x7FFF; let entries: Entry[] = []; baseIndex = baseIndex + NODE_TYPE_INDEX + 1; for(let i = 0; i < entryCnt; i++) { - const entryWidth = decompressNumber(str, baseIndex, baseIndex+2); + const entryWidth = decompressNumber(str, baseIndex, baseIndex+NODE_SIZE_WIDTH); const nextIndex = baseIndex + entryWidth; entries.push(decompressEntry(str, keyFunction, baseIndex)); baseIndex = nextIndex; From 2e92a7f3ea8b8807b8f6e58ee2e9cafed50da8a4 Mon Sep 17 00:00:00 2001 From: "Joshua A. Horton" Date: Tue, 27 Aug 2024 14:51:55 +0700 Subject: [PATCH 26/26] chore(common/models): addresses a number of PR comments --- .../models/templates/src/trie-compression.ts | 36 +++++++++++++------ .../templates/test/test-trie-compression.js | 15 ++------ 2 files changed, 29 insertions(+), 22 deletions(-) diff --git a/common/models/templates/src/trie-compression.ts b/common/models/templates/src/trie-compression.ts index 5666afd4ffe..8d9a1605c7f 100644 --- a/common/models/templates/src/trie-compression.ts +++ b/common/models/templates/src/trie-compression.ts @@ -8,8 +8,14 @@ import { Entry, InternalNode, Leaf, Node } from "./trie.js"; export const ENCODED_NUM_BASE = 0x0020; export const SINGLE_CHAR_RANGE = Math.pow(2, 16) - ENCODED_NUM_BASE; -const WEIGHT_WIDTH = 2; +/** + * The number of characters allocated to representing the total length of a node or entry. + */ const NODE_SIZE_WIDTH = 2; +/** + * The number of characters allocated to representing the weight (frequency) of entries. + */ +const WEIGHT_WIDTH = 2; export function decompressNumber(str: string, start: number, end: number) { end ??= str.length; @@ -45,13 +51,18 @@ export function compressNumber(num: number, width?: number) { return compressed; } +/** + * Length of the 'header' section for encoded entries, representing the + * total size for the entry + its weight. + */ const ENTRY_HEADER_WIDTH = NODE_SIZE_WIDTH + WEIGHT_WIDTH; // encoded ENTRY: // - entryLen: 2 char // - total encoded size of the entry, including `entryLen` // - as raw, concatenated string data - no JSON.stringify action taken. -// - weight: 2? chars (with quote-offset on each char?) +// - weight: 2 chars +// - frequency of the entry // - contentLen: safe to infer from all other values // - content: string: from [header+4] to [header+4 + contentLen - 1] // @@ -89,16 +100,21 @@ export function decompressEntry(str: string, keyFunction: Wordform2Key, baseInde } -// BOTH node types: totalLen: 2 chars (fixed position, size) - size of the -// encoded node. weight: number - could be encoded. -// - 2^32 ~= 4*10^9, representable in 2 chars... if it weren't for `"`-escaping. -// - 2^64 ~= 1.8*10^19 - surely far, far more than enough. +// BOTH node types: +// - totalLen: 2 chars (fixed position, size) - size of the encoded node. +// - weight: weight of the highest frequency entry within the node's sub-trie. +// - 2^32 ~= 4*10^9, representable in 2 chars... if it weren't for +// `"`-escaping. // -// Next char: -// indicates BOTH a count of something (entries or direct children) and a -// high-bit indicating 'leaf' or 'internal'. +// Next char: indicates BOTH a count of something (entries or direct children) +// and a high-bit indicating 'leaf' or 'internal'. // - function of other bits will be indicated by their sections. +/** + * Length of the 'header' section for encoded leaf and internal nodes, representing the + * total size for their children/entries + the weight of the highest-frequency entry + * represented by each node's represented sub-trie. + */ export const NODE_TYPE_INDEX = NODE_SIZE_WIDTH + WEIGHT_WIDTH; export function compressNode(node: Node) { @@ -237,7 +253,7 @@ function decompressInternal(str: string, baseIndex: number): Omit { - it('compresses (mocked Entry)', () => { - // Should not attempt to recompress the mock-compressed entry. - assert.equal(compressNode(TEST_DATA.LEAVES.four.decompressed), TEST_DATA.LEAVES.four.compressed); - }); - - it('compresses (unmocked Entry)', () => { + it('compresses itself and represented entries', () => { assert.equal(compressNode(TEST_DATA.LEAVES.four.original), TEST_DATA.LEAVES.four.compressed); }); });