From 803ccc1661384ee484298f3495585d3923495dd4 Mon Sep 17 00:00:00 2001 From: siikamiika Date: Sun, 1 Oct 2017 04:17:02 +0300 Subject: [PATCH] merged: first draft, only supports JMdict --- ext/bg/js/api.js | 8 +-- ext/bg/js/database.js | 27 +++++++++- ext/bg/js/handlebars.js | 12 +++++ ext/bg/js/options.js | 7 +++ ext/bg/js/templates.js | 109 +++++++++++++++++++++++++--------------- ext/bg/js/translator.js | 69 +++++++++++++++++++++++-- 6 files changed, 184 insertions(+), 48 deletions(-) diff --git a/ext/bg/js/api.js b/ext/bg/js/api.js index 01322357..de3ad64e 100644 --- a/ext/bg/js/api.js +++ b/ext/bg/js/api.js @@ -29,9 +29,11 @@ async function apiTermsFind(text) { const options = utilBackend().options; const translator = utilBackend().translator; - const searcher = (options.general.resultOutputMode === 'merge') && translator.findTermsMerged.bind(translator) - || (options.general.resultOutputMode === 'split') && translator.findTermsSplit.bind(translator) - || (options.general.resultOutputMode === 'group') && translator.findTermsGrouped.bind(translator); + const searcher = { + 'merge': translator.findTermsMerged, + 'split': translator.findTermsSplit, + 'group': translator.findTermsGrouped + }[options.general.resultOutputMode].bind(translator); const {definitions, length} = await searcher( text, diff --git a/ext/bg/js/database.js b/ext/bg/js/database.js index 29ab6d4e..9787b0f8 100644 --- a/ext/bg/js/database.js +++ b/ext/bg/js/database.js @@ -30,7 +30,7 @@ class Database { this.db = new Dexie('dict'); this.db.version(2).stores({ - terms: '++id,dictionary,expression,reading', + terms: '++id,dictionary,expression,reading,sequence', kanji: '++,dictionary,character', tagMeta: '++,dictionary', dictionaries: '++,title,version' @@ -73,7 +73,8 @@ class Database { glossary: row.glossary, score: row.score, dictionary: row.dictionary, - id: row.id + id: row.id, + sequence: row.sequence }); } }); @@ -81,6 +82,28 @@ class Database { return results; } + async findEntry(sequence) { + if (!this.db) { + throw 'Database not initialized'; + } + + const entry = []; + await this.db.terms.where('sequence').equals(sequence).each(row => { + entry.push({ + expression: row.expression, + reading: row.reading, + tags: dictFieldSplit(row.tags), + rules: dictFieldSplit(row.rules), + glossary: row.glossary, + score: row.score, + dictionary: row.dictionary, + id: row.id + }); + }); + + return entry; + } + async findTermMeta(term, titles) { if (!this.db) { throw 'Database not initialized'; diff --git a/ext/bg/js/handlebars.js b/ext/bg/js/handlebars.js index 66d5fa2b..08304d43 100644 --- a/ext/bg/js/handlebars.js +++ b/ext/bg/js/handlebars.js @@ -71,6 +71,16 @@ function handlebarsKanjiLinks(options) { return result; } +function handlebarsExpressions(options) { + const definition = options.fn(this); + return definition.expression; +} + +function handlebarsReadings(options) { + const definition = options.fn(this); + return definition.reading; +} + function handlebarsMultiLine(options) { return options.fn(this).split('\n').join('
'); } @@ -83,6 +93,8 @@ function handlebarsRegisterHelpers() { Handlebars.registerHelper('furiganaPlain', handlebarsFuriganaPlain); Handlebars.registerHelper('kanjiLinks', handlebarsKanjiLinks); Handlebars.registerHelper('multiLine', handlebarsMultiLine); + Handlebars.registerHelper('expressions', handlebarsExpressions); + Handlebars.registerHelper('readings', handlebarsReadings); } } diff --git a/ext/bg/js/options.js b/ext/bg/js/options.js index de3da943..b49c32da 100644 --- a/ext/bg/js/options.js +++ b/ext/bg/js/options.js @@ -205,6 +205,13 @@ function optionsVersion(options) { } else { options.scanning.modifier = 'none'; } + }, + () => { + if (options.general.groupResults) { + options.general.resultOutputMode = 'group'; + } else { + options.general.resultOutputMode = 'split'; + } } ]; diff --git a/ext/bg/js/templates.js b/ext/bg/js/templates.js index b5d352fc..2cea8b07 100644 --- a/ext/bg/js/templates.js +++ b/ext/bg/js/templates.js @@ -249,61 +249,85 @@ templates['terms.html'] = template({"1":function(container,depth0,helpers,partia return container.escapeExpression(container.lambda(((stack1 = (depth0 != null ? depth0.glossary : depth0)) != null ? stack1["0"] : stack1), depth0)); },"12":function(container,depth0,helpers,partials,data) { - var stack1, helper, options, alias1=depth0 != null ? depth0 : (container.nullContext || {}), buffer = - "
\n
\n" + var stack1, alias1=depth0 != null ? depth0 : (container.nullContext || {}); + + return "
\n
\n" + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.addable : depth0),{"name":"if","hash":{},"fn":container.program(13, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.playback : depth0),{"name":"if","hash":{},"fn":container.program(15, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") - + " \n
\n\n
"; - stack1 = ((helper = (helper = helpers.kanjiLinks || (depth0 != null ? depth0.kanjiLinks : depth0)) != null ? helper : helpers.helperMissing),(options={"name":"kanjiLinks","hash":{},"fn":container.program(17, data, 0),"inverse":container.noop,"data":data}),(typeof helper === "function" ? helper.call(alias1,options) : helper)); - if (!helpers.kanjiLinks) { stack1 = helpers.blockHelperMissing.call(depth0,stack1,options)} - if (stack1 != null) { buffer += stack1; } - return buffer + "
\n\n" - + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.reasons : depth0),{"name":"if","hash":{},"fn":container.program(20, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") + + " \n
\n\n" + + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.merged : depth0),{"name":"if","hash":{},"fn":container.program(17, data, 0),"inverse":container.program(21, data, 0),"data":data})) != null ? stack1 : "") + "\n" - + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.frequencies : depth0),{"name":"if","hash":{},"fn":container.program(24, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") + + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.reasons : depth0),{"name":"if","hash":{},"fn":container.program(24, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") + + "\n" + + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.frequencies : depth0),{"name":"if","hash":{},"fn":container.program(28, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") + "\n
\n" - + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.grouped : depth0),{"name":"if","hash":{},"fn":container.program(27, data, 0),"inverse":container.program(33, data, 0),"data":data})) != null ? stack1 : "") + + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.grouped : depth0),{"name":"if","hash":{},"fn":container.program(31, data, 0),"inverse":container.program(37, data, 0),"data":data})) != null ? stack1 : "") + "
\n\n" - + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.debug : depth0),{"name":"if","hash":{},"fn":container.program(35, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") + + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.debug : depth0),{"name":"if","hash":{},"fn":container.program(40, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") + "
\n"; },"13":function(container,depth0,helpers,partials,data) { return " \n \n \n"; },"15":function(container,depth0,helpers,partials,data) { return " \n"; },"17":function(container,depth0,helpers,partials,data) { + var stack1, helper, options, alias1=depth0 != null ? depth0 : (container.nullContext || {}), alias2=helpers.helperMissing, alias3="function", alias4=helpers.blockHelperMissing, buffer = + "
"; + stack1 = ((helper = (helper = helpers.kanjiLinks || (depth0 != null ? depth0.kanjiLinks : depth0)) != null ? helper : alias2),(options={"name":"kanjiLinks","hash":{},"fn":container.program(18, data, 0),"inverse":container.noop,"data":data}),(typeof helper === alias3 ? helper.call(alias1,options) : helper)); + if (!helpers.kanjiLinks) { stack1 = alias4.call(depth0,stack1,options)} + if (stack1 != null) { buffer += stack1; } + buffer += "
\n
"; + stack1 = ((helper = (helper = helpers.readings || (depth0 != null ? depth0.readings : depth0)) != null ? helper : alias2),(options={"name":"readings","hash":{},"fn":container.program(19, data, 0),"inverse":container.noop,"data":data}),(typeof helper === alias3 ? helper.call(alias1,options) : helper)); + if (!helpers.readings) { stack1 = alias4.call(depth0,stack1,options)} + if (stack1 != null) { buffer += stack1; } + return buffer + "
\n"; +},"18":function(container,depth0,helpers,partials,data) { var stack1, helper, options; - stack1 = ((helper = (helper = helpers.furigana || (depth0 != null ? depth0.furigana : depth0)) != null ? helper : helpers.helperMissing),(options={"name":"furigana","hash":{},"fn":container.program(18, data, 0),"inverse":container.noop,"data":data}),(typeof helper === "function" ? helper.call(depth0 != null ? depth0 : (container.nullContext || {}),options) : helper)); - if (!helpers.furigana) { stack1 = helpers.blockHelperMissing.call(depth0,stack1,options)} + stack1 = ((helper = (helper = helpers.expressions || (depth0 != null ? depth0.expressions : depth0)) != null ? helper : helpers.helperMissing),(options={"name":"expressions","hash":{},"fn":container.program(19, data, 0),"inverse":container.noop,"data":data}),(typeof helper === "function" ? helper.call(depth0 != null ? depth0 : (container.nullContext || {}),options) : helper)); + if (!helpers.expressions) { stack1 = helpers.blockHelperMissing.call(depth0,stack1,options)} if (stack1 != null) { return stack1; } else { return ''; } -},"18":function(container,depth0,helpers,partials,data) { +},"19":function(container,depth0,helpers,partials,data) { var stack1; return ((stack1 = container.lambda(depth0, depth0)) != null ? stack1 : ""); -},"20":function(container,depth0,helpers,partials,data) { +},"21":function(container,depth0,helpers,partials,data) { + var stack1, helper, options, buffer = + "
"; + stack1 = ((helper = (helper = helpers.kanjiLinks || (depth0 != null ? depth0.kanjiLinks : depth0)) != null ? helper : helpers.helperMissing),(options={"name":"kanjiLinks","hash":{},"fn":container.program(22, data, 0),"inverse":container.noop,"data":data}),(typeof helper === "function" ? helper.call(depth0 != null ? depth0 : (container.nullContext || {}),options) : helper)); + if (!helpers.kanjiLinks) { stack1 = helpers.blockHelperMissing.call(depth0,stack1,options)} + if (stack1 != null) { buffer += stack1; } + return buffer + "
\n"; +},"22":function(container,depth0,helpers,partials,data) { + var stack1, helper, options; + + stack1 = ((helper = (helper = helpers.furigana || (depth0 != null ? depth0.furigana : depth0)) != null ? helper : helpers.helperMissing),(options={"name":"furigana","hash":{},"fn":container.program(19, data, 0),"inverse":container.noop,"data":data}),(typeof helper === "function" ? helper.call(depth0 != null ? depth0 : (container.nullContext || {}),options) : helper)); + if (!helpers.furigana) { stack1 = helpers.blockHelperMissing.call(depth0,stack1,options)} + if (stack1 != null) { return stack1; } + else { return ''; } +},"24":function(container,depth0,helpers,partials,data) { var stack1; return "
\n" - + ((stack1 = helpers.each.call(depth0 != null ? depth0 : (container.nullContext || {}),(depth0 != null ? depth0.reasons : depth0),{"name":"each","hash":{},"fn":container.program(21, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") + + ((stack1 = helpers.each.call(depth0 != null ? depth0 : (container.nullContext || {}),(depth0 != null ? depth0.reasons : depth0),{"name":"each","hash":{},"fn":container.program(25, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") + "
\n"; -},"21":function(container,depth0,helpers,partials,data) { +},"25":function(container,depth0,helpers,partials,data) { var stack1; return " " + container.escapeExpression(container.lambda(depth0, depth0)) + " " - + ((stack1 = helpers.unless.call(depth0 != null ? depth0 : (container.nullContext || {}),(data && data.last),{"name":"unless","hash":{},"fn":container.program(22, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") + + ((stack1 = helpers.unless.call(depth0 != null ? depth0 : (container.nullContext || {}),(data && data.last),{"name":"unless","hash":{},"fn":container.program(26, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") + "\n"; -},"22":function(container,depth0,helpers,partials,data) { +},"26":function(container,depth0,helpers,partials,data) { return "«"; -},"24":function(container,depth0,helpers,partials,data) { +},"28":function(container,depth0,helpers,partials,data) { var stack1; return "
\n" - + ((stack1 = helpers.each.call(depth0 != null ? depth0 : (container.nullContext || {}),(depth0 != null ? depth0.frequencies : depth0),{"name":"each","hash":{},"fn":container.program(25, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") + + ((stack1 = helpers.each.call(depth0 != null ? depth0 : (container.nullContext || {}),(depth0 != null ? depth0.frequencies : depth0),{"name":"each","hash":{},"fn":container.program(29, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") + "
\n"; -},"25":function(container,depth0,helpers,partials,data) { +},"29":function(container,depth0,helpers,partials,data) { var helper, alias1=depth0 != null ? depth0 : (container.nullContext || {}), alias2=helpers.helperMissing, alias3="function", alias4=container.escapeExpression; return " " @@ -311,56 +335,61 @@ templates['terms.html'] = template({"1":function(container,depth0,helpers,partia + ":" + alias4(((helper = (helper = helpers.frequency || (depth0 != null ? depth0.frequency : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"frequency","hash":{},"data":data}) : helper))) + "\n"; -},"27":function(container,depth0,helpers,partials,data) { +},"31":function(container,depth0,helpers,partials,data) { var stack1; - return ((stack1 = helpers["if"].call(depth0 != null ? depth0 : (container.nullContext || {}),((stack1 = (depth0 != null ? depth0.definitions : depth0)) != null ? stack1["1"] : stack1),{"name":"if","hash":{},"fn":container.program(28, data, 0),"inverse":container.program(31, data, 0),"data":data})) != null ? stack1 : ""); -},"28":function(container,depth0,helpers,partials,data) { + return ((stack1 = helpers["if"].call(depth0 != null ? depth0 : (container.nullContext || {}),((stack1 = (depth0 != null ? depth0.definitions : depth0)) != null ? stack1["1"] : stack1),{"name":"if","hash":{},"fn":container.program(32, data, 0),"inverse":container.program(35, data, 0),"data":data})) != null ? stack1 : ""); +},"32":function(container,depth0,helpers,partials,data) { var stack1; return "
    \n" - + ((stack1 = helpers.each.call(depth0 != null ? depth0 : (container.nullContext || {}),(depth0 != null ? depth0.definitions : depth0),{"name":"each","hash":{},"fn":container.program(29, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") + + ((stack1 = helpers.each.call(depth0 != null ? depth0 : (container.nullContext || {}),(depth0 != null ? depth0.definitions : depth0),{"name":"each","hash":{},"fn":container.program(33, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") + "
\n"; -},"29":function(container,depth0,helpers,partials,data) { +},"33":function(container,depth0,helpers,partials,data) { var stack1; return "
  • " + ((stack1 = container.invokePartial(partials.definition,depth0,{"name":"definition","data":data,"helpers":helpers,"partials":partials,"decorators":container.decorators})) != null ? stack1 : "") + "
  • \n"; -},"31":function(container,depth0,helpers,partials,data) { +},"35":function(container,depth0,helpers,partials,data) { var stack1; return ((stack1 = container.invokePartial(partials.definition,((stack1 = (depth0 != null ? depth0.definitions : depth0)) != null ? stack1["0"] : stack1),{"name":"definition","data":data,"indent":" ","helpers":helpers,"partials":partials,"decorators":container.decorators})) != null ? stack1 : ""); -},"33":function(container,depth0,helpers,partials,data) { +},"37":function(container,depth0,helpers,partials,data) { var stack1; - return ((stack1 = container.invokePartial(partials.definition,depth0,{"name":"definition","data":data,"indent":" ","helpers":helpers,"partials":partials,"decorators":container.decorators})) != null ? stack1 : ""); -},"35":function(container,depth0,helpers,partials,data) { + return ((stack1 = helpers["if"].call(depth0 != null ? depth0 : (container.nullContext || {}),(depth0 != null ? depth0.merged : depth0),{"name":"if","hash":{},"fn":container.program(31, data, 0),"inverse":container.program(38, data, 0),"data":data})) != null ? stack1 : ""); +},"38":function(container,depth0,helpers,partials,data) { + var stack1; + + return ((stack1 = container.invokePartial(partials.definition,depth0,{"name":"definition","data":data,"indent":" ","helpers":helpers,"partials":partials,"decorators":container.decorators})) != null ? stack1 : "") + + " "; +},"40":function(container,depth0,helpers,partials,data) { var stack1, helper, options, buffer = "
    ";
    -  stack1 = ((helper = (helper = helpers.dumpObject || (depth0 != null ? depth0.dumpObject : depth0)) != null ? helper : helpers.helperMissing),(options={"name":"dumpObject","hash":{},"fn":container.program(18, data, 0),"inverse":container.noop,"data":data}),(typeof helper === "function" ? helper.call(depth0 != null ? depth0 : (container.nullContext || {}),options) : helper));
    +  stack1 = ((helper = (helper = helpers.dumpObject || (depth0 != null ? depth0.dumpObject : depth0)) != null ? helper : helpers.helperMissing),(options={"name":"dumpObject","hash":{},"fn":container.program(19, data, 0),"inverse":container.noop,"data":data}),(typeof helper === "function" ? helper.call(depth0 != null ? depth0 : (container.nullContext || {}),options) : helper));
       if (!helpers.dumpObject) { stack1 = helpers.blockHelperMissing.call(depth0,stack1,options)}
       if (stack1 != null) { buffer += stack1; }
       return buffer + "
    \n"; -},"37":function(container,depth0,helpers,partials,data,blockParams,depths) { +},"42":function(container,depth0,helpers,partials,data,blockParams,depths) { var stack1; - return ((stack1 = helpers.each.call(depth0 != null ? depth0 : (container.nullContext || {}),(depth0 != null ? depth0.definitions : depth0),{"name":"each","hash":{},"fn":container.program(38, data, 0, blockParams, depths),"inverse":container.noop,"data":data})) != null ? stack1 : ""); -},"38":function(container,depth0,helpers,partials,data,blockParams,depths) { + return ((stack1 = helpers.each.call(depth0 != null ? depth0 : (container.nullContext || {}),(depth0 != null ? depth0.definitions : depth0),{"name":"each","hash":{},"fn":container.program(43, data, 0, blockParams, depths),"inverse":container.noop,"data":data})) != null ? stack1 : ""); +},"43":function(container,depth0,helpers,partials,data,blockParams,depths) { var stack1; - return ((stack1 = helpers.unless.call(depth0 != null ? depth0 : (container.nullContext || {}),(data && data.first),{"name":"unless","hash":{},"fn":container.program(39, data, 0, blockParams, depths),"inverse":container.noop,"data":data})) != null ? stack1 : "") + return ((stack1 = helpers.unless.call(depth0 != null ? depth0 : (container.nullContext || {}),(data && data.first),{"name":"unless","hash":{},"fn":container.program(44, data, 0, blockParams, depths),"inverse":container.noop,"data":data})) != null ? stack1 : "") + "\n" - + ((stack1 = container.invokePartial(partials.term,depth0,{"name":"term","hash":{"playback":(depths[1] != null ? depths[1].playback : depths[1]),"addable":(depths[1] != null ? depths[1].addable : depths[1]),"grouped":(depths[1] != null ? depths[1].grouped : depths[1]),"debug":(depths[1] != null ? depths[1].debug : depths[1])},"data":data,"helpers":helpers,"partials":partials,"decorators":container.decorators})) != null ? stack1 : ""); -},"39":function(container,depth0,helpers,partials,data) { + + ((stack1 = container.invokePartial(partials.term,depth0,{"name":"term","hash":{"playback":(depths[1] != null ? depths[1].playback : depths[1]),"addable":(depths[1] != null ? depths[1].addable : depths[1]),"merged":(depths[1] != null ? depths[1].merged : depths[1]),"grouped":(depths[1] != null ? depths[1].grouped : depths[1]),"debug":(depths[1] != null ? depths[1].debug : depths[1])},"data":data,"helpers":helpers,"partials":partials,"decorators":container.decorators})) != null ? stack1 : ""); +},"44":function(container,depth0,helpers,partials,data) { return "
    "; -},"41":function(container,depth0,helpers,partials,data) { +},"46":function(container,depth0,helpers,partials,data) { return "

    No results found.

    \n"; },"compiler":[7,">= 4.0.0"],"main":function(container,depth0,helpers,partials,data,blockParams,depths) { var stack1; return "\n\n" - + ((stack1 = helpers["if"].call(depth0 != null ? depth0 : (container.nullContext || {}),(depth0 != null ? depth0.definitions : depth0),{"name":"if","hash":{},"fn":container.program(37, data, 0, blockParams, depths),"inverse":container.program(41, data, 0, blockParams, depths),"data":data})) != null ? stack1 : ""); + + ((stack1 = helpers["if"].call(depth0 != null ? depth0 : (container.nullContext || {}),(depth0 != null ? depth0.definitions : depth0),{"name":"if","hash":{},"fn":container.program(42, data, 0, blockParams, depths),"inverse":container.program(46, data, 0, blockParams, depths),"data":data})) != null ? stack1 : ""); },"main_d": function(fn, props, container, depth0, data, blockParams, depths) { var decorators = container.decorators; diff --git a/ext/bg/js/translator.js b/ext/bg/js/translator.js index 8fa2b60b..db287d63 100644 --- a/ext/bg/js/translator.js +++ b/ext/bg/js/translator.js @@ -49,15 +49,78 @@ class Translator { } async findTermsMerged(text, dictionaries, alphanumeric) { - const titles = Object.keys(dictionaries); + // const titles = Object.keys(dictionaries); const {length, definitions} = await this.findTerms(text, dictionaries, alphanumeric); - const definitionsMerged = dictTermsGroup(definitions, dictionaries); + // const definitionsMerged = dictTermsMerge(definitions, dictionaries, this.database); // for (const definition of definitionsMerged) { // await this.buildTermFrequencies(definition, titles); // } - return {length, definitions: definitionsMerged}; + const sequences = {}; + const stray = []; + for (const definition of definitions) { + if (typeof definition.sequence !== 'undefined') { + if (!sequences[definition.sequence]) { + sequences[definition.sequence] = { + reasons: definition.reasons, + score: Number.MIN_SAFE_INTEGER, + expression: new Set(), + reading: new Set(), + source: definition.source, + definitions: [] + }; + } + const seq = sequences[definition.sequence]; + seq.score = Math.max(seq.score, definition.score); + } else { + stray.push(definition); + } + } + + const definitionsMerged = dictTermsGroup(stray, dictionaries); + for (const sequence in sequences) { + const entry = await this.database.findEntry(Number(sequence)); + + const result = sequences[sequence]; + const glossaries = new Map(); + for (const definition of entry) { + + const gloss = definition.glossary.join('||'); + if (!glossaries.get(gloss)) { + const tags = await this.expandTags(definition.tags, definition.dictionary); + tags.push(dictTagBuildSource(definition.dictionary)); + glossaries.set(gloss, { + expressions: new Set(), + readings: new Set(), + tags: dictTagsSort(tags), // TODO: use correct tags + source: result.source, + reasons: [], + score: definition.score, + id: definition.id, + dictionary: definition.dictionary + }); + } + glossaries.get(gloss).expressions.add(definition.expression); + glossaries.get(gloss).readings.add(definition.reading); + + result.expression.add(definition.expression); + result.reading.add(definition.reading); + } + + for (const gloss of glossaries.keys()) { + const definition = glossaries.get(gloss); + definition.glossary = gloss.split('||'); + result.definitions.push(definition); + } + //dictTermsSort(groupDefs, dictionaries) + + result.expression = Array.from(result.expression).join(', '); + result.reading = Array.from(result.reading).join(', '); + definitionsMerged.push(result); + } + + return {length, definitions: dictTermsSort(definitionsMerged)}; } async findTermsSplit(text, dictionaries, alphanumeric) {