Merge branch 'visualizations-update' of gitlab.ub.uni-bielefeld.de:sfb1288inf/nopaque into visualizations-update

This commit is contained in:
Inga Kirschnick
2023-07-03 11:06:59 +02:00
28 changed files with 2197 additions and 122941 deletions

File diff suppressed because it is too large Load Diff

View File

@ -71,25 +71,19 @@ class CorpusAnalysisApp {
this.disableActionElements();
this.elements.m.initModal.open();
// Init data
this.data.cQiClient = new CQiClient(this.settings.corpusId);
this.data.cQiClient.connect()
.then(cQiStatus => {
return this.data.cQiClient.corpora.get(`NOPAQUE_${this.settings.corpusId}`);
this.data.cqiClient = new cqi.CQiClient('/cqi_over_sio', this.settings.corpusId);
this.data.cqiClient.connect('anonymous', '')
.then((cqiStatus) => {
return this.data.cqiClient.corpora.list();
})
.then(
cQiCorpus => {
this.data.corpus = {o: cQiCorpus};
this.data.corpus.o.getVisualizationData()
.then(
(data) => {
console.log(data);
this.renderGeneralCorpusInfo(data);
this.renderTextInfoList(data);
this.renderTextProportionsGraphic(data);
this.renderFrequenciesGraphic(data);
this.renderBoundsGraphic(data);
}
);
.then((cqiCorpora) => {
this.data.corpus = {o: cqiCorpora[0]};
console.log(this.data.corpus.o.staticData);
this.renderGeneralCorpusInfo(this.data.corpus.o.staticData);
this.renderTextInfoList(this.data.corpus.o.staticData);
this.renderTextProportionsGraphic(this.data.corpus.o.staticData);
this.renderFrequenciesGraphic(this.data.corpus.o.staticData);
this.renderBoundsGraphic(this.data.corpus.o.staticData);
// this.data.corpus.o.getCorpusData()
// .then(corpusData => {
// console.log(corpusData);
@ -100,19 +94,19 @@ class CorpusAnalysisApp {
// this.renderBoundsGraphic(corpusData);
// });
// TODO: Don't do this hgere
cQiCorpus.updateDb();
this.data.corpus.o.updateDb();
this.enableActionElements();
for (let extension of Object.values(this.extensions)) {extension.init();}
this.elements.m.initModal.close();
},
cQiError => {
(cqiError) => {
let errorsElement = this.elements.initModal.querySelector('.errors');
let progressElement = this.elements.initModal.querySelector('.progress');
errorsElement.innerText = JSON.stringify(cQiError);
errorsElement.innerText = JSON.stringify(cqiError);
errorsElement.classList.remove('hide');
progressElement.classList.add('hide');
if ('payload' in cQiError && 'code' in cQiError.payload && 'msg' in cQiError.payload) {
app.flash(`${cQiError.payload.code}: ${cQiError.payload.msg}`, 'error');
if ('payload' in cqiError && 'code' in cqiError.payload && 'msg' in cqiError.payload) {
app.flash(`${cqiError.payload.code}: ${cqiError.payload.msg}`, 'error');
}
}
);

View File

@ -45,18 +45,18 @@ class CorpusAnalysisConcordance {
this.elements.progress.classList.remove('hide');
let subcorpus = {};
this.data.corpus.o.query(subcorpusName, query)
.then(cQiStatus => {
.then((cqiStatus) => {
subcorpus.q = query;
subcorpus.selectedItems = new Set();
if (subcorpusName !== 'Last') {this.data.subcorpora.Last = subcorpus;}
return this.data.corpus.o.subcorpora.get(subcorpusName);
})
.then(cQiSubcorpus => {
subcorpus.o = cQiSubcorpus;
return cQiSubcorpus.paginate(1, this.settings.perPage, this.settings.context);
.then((cqiSubcorpus) => {
subcorpus.o = cqiSubcorpus;
return cqiSubcorpus.paginate(this.settings.context, 1, this.settings.perPage);
})
.then(
paginatedSubcorpus => {
(paginatedSubcorpus) => {
subcorpus.p = paginatedSubcorpus;
this.data.subcorpora[subcorpusName] = subcorpus;
this.settings.selectedSubcorpus = subcorpusName;
@ -68,11 +68,12 @@ class CorpusAnalysisConcordance {
this.elements.progress.classList.add('hide');
this.app.enableActionElements();
},
cQiError => {
this.elements.error.innerText = JSON.stringify(cQiError);
(cqiStatus) => {
// TODDO: CHECK THIS!
this.elements.error.innerText = JSON.stringify(cqiStatus);
this.elements.error.classList.remove('hide');
if ('payload' in cQiError && 'code' in cQiError.payload && 'msg' in cQiError.payload) {
app.flash(`${cQiError.payload.code}: ${cQiError.payload.msg}`, 'error');
if ('payload' in cqiStatus && 'code' in cqiStatus.payload && 'msg' in cqiStatus.payload) {
app.flash(`${cqiStatus.payload.code}: ${cqiStatus.payload.msg}`, 'error');
}
this.elements.progress.classList.add('hide');
this.app.enableActionElements();
@ -236,7 +237,7 @@ class CorpusAnalysisConcordance {
app.flash('No matches selected', 'error');
return;
}
promise = subcorpus.o.partial_export([...subcorpus.selectedItems], 50);
promise = subcorpus.o.partialExport([...subcorpus.selectedItems], 50);
} else {
promise = subcorpus.o.export(50);
}
@ -291,7 +292,7 @@ class CorpusAnalysisConcordance {
event.preventDefault();
let subcorpus = this.data.subcorpora[this.settings.selectedSubcorpus];
subcorpus.o.drop().then(
cQiStatus => {
(cQiStatus) => {
app.flash(`${subcorpus.o.name} deleted`, 'corpus');
delete this.data.subcorpora[subcorpus.o.name];
this.settings.selectedSubcorpus = undefined;
@ -312,7 +313,7 @@ class CorpusAnalysisConcordance {
this.clearSubcorpusPagination();
}
},
cQiError => {
(cQiError) => {
app.flash(`${cQiError.payload.code}: ${cQiError.payload.msg}`, 'error');
}
);

View File

@ -28,7 +28,6 @@ class CorpusAnalysisReader {
init() {
// Init data
this.data.corpus = this.app.data.corpus;
this.data.subcorpora = {};
// Add event listeners
this.elements.form.addEventListener('submit', (event) => {
event.preventDefault();
@ -38,14 +37,14 @@ class CorpusAnalysisReader {
this.elements.progress.classList.remove('hide');
this.data.corpus.o.paginate(1, this.settings.perPage)
.then(
paginatedCorpus => {
(paginatedCorpus) => {
this.data.corpus.p = paginatedCorpus;
this.renderCorpus();
this.renderCorpusPagination();
this.elements.progress.classList.add('hide');
this.app.enableActionElements();
},
error => {
(cqiError) => {
this.elements.error.innerText = JSON.stringify(error);
this.elements.error.classList.remove('hide');
if ('payload' in error && 'code' in error.payload && 'msg' in error.payload) {
@ -247,7 +246,7 @@ class CorpusAnalysisReader {
this.elements.progress.classList.remove('hide');
this.data.corpus.o.paginate(pageNum, this.settings.perPage)
.then(
paginatedCorpus => {
(paginatedCorpus) => {
this.data.corpus.p = paginatedCorpus;
this.renderCorpus();
this.renderCorpusPagination();

View File

@ -0,0 +1,691 @@
cqi.api.APIClient = class APIClient {
/**
* @param {string} host
* @param {string} corpusId
* @param {number} [timeout=60] timeout
* @param {string} [version=0.1] version
*/
constructor(host, corpus_id, timeout = 60, version = '0.1') {
this.host = host;
this.timeout = timeout * 1000; // convert seconds to milliseconds
this.version = version;
this.socket = io(
this.host,
{
auth: {corpus_id: corpus_id},
transports: ['websocket'],
upgrade: false
}
);
}
/**
* @param {string} fn_name
* @param {object} [fn_args={}]
* @returns {Promise<cqi.status.StatusConnectOk>}
*/
#request(fn_name, fn_args = {}) {
return new Promise((resolve, reject) => {
this.socket.timeout(this.timeout).emit('cqi', {fn_name: fn_name, fn_args: fn_args}, (timeoutError, response) => {
if (timeoutError) {
reject(timeoutError);
}
if (response.code === 200) {
resolve(response.payload);
}
if (response.code === 500) {
reject(new Error(`[${response.code}] ${response.msg}`));
}
if (response.code === 502) {
reject(new cqi.errors.lookup[response.payload.code]());
}
});
});
}
/**
* @param {string} username
* @param {string} password
* @returns {Promise<cqi.status.StatusConnectOk>}
*/
async ctrl_connect(username, password) {
const fn_name = 'ctrl_connect';
const fn_args = {username: username, password: password};
let payload = await this.#request(fn_name, fn_args);
return new cqi.status.lookup[payload.code]();
}
/**
* @returns {Promise<cqi.status.StatusByeOk>}
*/
async ctrl_bye() {
const fn_name = 'ctrl_bye';
let payload = await this.#request(fn_name);
return new cqi.status.lookup[payload.code]();
}
/**
* @returns {Promise<null>}
*/
async ctrl_user_abort() {
const fn_name = 'ctrl_user_abort';
return await this.#request(fn_name);
}
/**
* @returns {Promise<cqi.status.StatusPingOk>}
*/
async ctrl_ping() {
const fn_name = 'ctrl_ping';
let payload = await this.#request(fn_name);
return new cqi.status.lookup[payload.code]();
}
/**
* Full-text error message for the last general error reported
* by the CQi server
*
* @returns {Promise<string>}
*/
async ctrl_last_general_error() {
const fn_name = 'ctrl_last_general_error';
return await this.#request(fn_name);
}
/**
* @returns {Promise<boolean>}
*/
async ask_feature_cqi_1_0() {
const fn_name = 'ask_feature_cqi_1_0';
return await this.#request(fn_name);
}
/**
* @returns {Promise<boolean>}
*/
async ask_feature_cl_2_3() {
const fn_name = 'ask_feature_cl_2_3';
return await this.#request(fn_name);
}
/**
* @returns {Promise<boolean>}
*/
async ask_feature_cqp_2_3() {
const fn_name = 'ask_feature_cqp_2_3';
return await this.#request(fn_name);
}
/**
* @returns {Promise<string[]>}
*/
async corpus_list_corpora() {
const fn_name = 'corpus_list_corpora';
return await this.#request(fn_name);
}
/**
* @param {string} corpus
* @returns {Promise<string>}
*/
async corpus_charset(corpus) {
const fn_name = 'corpus_charset';
const fn_args = {corpus: corpus};
return await this.#request(fn_name, fn_args);
}
/**
* @param {string} corpus
* @returns {Promise<string[]>}
*/
async corpus_properties(corpus) {
const fn_name = 'corpus_properties';
const fn_args = {corpus: corpus};
return await this.#request(fn_name, fn_args);
}
/**
* @param {string} corpus
* @returns {Promise<string[]>}
*/
async corpus_positional_attributes(corpus) {
const fn_name = 'corpus_positional_attributes';
const fn_args = {corpus: corpus};
return await this.#request(fn_name, fn_args);
}
/**
* @param {string} corpus
* @returns {Promise<string[]>}
*/
async corpus_structural_attributes(corpus) {
const fn_name = 'corpus_structural_attributes';
const fn_args = {corpus: corpus};
return await this.#request(fn_name, fn_args);
}
/**
* @param {string} corpus
* @param {string} attribute
* @returns {Promise<boolean>}
*/
async corpus_structural_attribute_has_values(corpus, attribute) {
const fn_name = 'corpus_structural_attribute_has_values';
const fn_args = {corpus: corpus, attribute: attribute};
return await this.#request(fn_name, fn_args);
}
/**
* @param {string} corpus
* @returns {Promise<string[]>}
*/
async corpus_alignment_attributes(corpus) {
const fn_name = 'corpus_alignment_attributes';
const fn_args = {corpus: corpus};
return await this.#request(fn_name, fn_args);
}
/**
* the full name of <corpus> as specified in its registry entry
*
* @param {string} corpus
* @returns {Promise<string>}
*/
async corpus_full_name(corpus) {
const fn_name = 'corpus_full_name';
const fn_args = {corpus: corpus};
return await this.#request(fn_name, fn_args);
}
/**
* returns the contents of the .info file of <corpus> as a list of lines
*
* @param {string} corpus
* @returns {Promise<string[]>}
*/
async corpus_info(corpus) {
const fn_name = 'corpus_info';
const fn_args = {corpus: corpus};
return await this.#request(fn_name, fn_args);
}
/**
* try to unload a corpus and all its attributes from memory
*
* @param {string} corpus
* @returns {Promise<cqi.status.StatusOk>}
*/
async corpus_drop_corpus(corpus) {
const fn_name = 'corpus_drop_corpus';
const fn_args = {corpus: corpus};
let payload = await this.#request(fn_name, fn_args);
return new cqi.status.lookup[payload.code]();
}
/**
* returns the size of <attribute>:
* - number of tokens (positional)
* - number of regions (structural)
* - number of alignments (alignment)
*
* @param {string} attribute
* @returns {Promise<number>}
*/
async cl_attribute_size(attribute) {
const fn_name = 'cl_attribute_size';
const fn_args = {attribute: attribute};
return await this.#request(fn_name, fn_args);
}
/**
* returns the number of entries in the lexicon of a positional attribute;
*
* valid lexicon IDs range from 0 .. (lexicon_size - 1)
*
* @param {string} attribute
* @returns {Promise<number>}
*/
async cl_lexicon_size(attribute) {
const fn_name = 'cl_lexicon_size';
const fn_args = {attribute: attribute};
return await this.#request(fn_name, fn_args);
}
/**
* unload attribute from memory
*
* @param {string} attribute
* @returns {Promise<cqi.status.StatusOk>}
*/
async cl_drop_attribute(attribute) {
const fn_name = 'cl_drop_attribute';
const fn_args = {attribute: attribute};
let payload = await this.#request(fn_name, fn_args);
return new cqi.status.lookup[payload.code]();
}
/**
* NOTE: simple (scalar) mappings are applied to lists (the returned list
* has exactly the same length as the list passed as an argument)
*/
/**
* returns -1 for every string in <strings> that is not found in the lexicon
*
* @param {string} attribute
* @param {strings[]} string
* @returns {Promise<number[]>}
*/
async cl_str2id(attribute, strings) {
const fn_name = 'cl_str2id';
const fn_args = {attribute: attribute, strings: strings};
return await this.#request(fn_name, fn_args);
}
/**
* returns "" for every ID in <id> that is out of range
*
* @param {string} attribute
* @param {number[]} id
* @returns {Promise<string[]>}
*/
async cl_id2str(attribute, id) {
const fn_name = 'cl_id2str';
const fn_args = {attribute: attribute, id: id};
return await this.#request(fn_name, fn_args);
}
/**
* returns 0 for every ID in <id> that is out of range
*
* @param {string} attribute
* @param {number[]} id
* @returns {Promise<number[]>}
*/
async cl_id2freq(attribute, id) {
const fn_name = 'cl_id2freq';
const fn_args = {attribute: attribute, id: id};
return await this.#request(fn_name, fn_args);
}
/**
* returns -1 for every corpus position in <cpos> that is out of range
*
* @param {string} attribute
* @param {number[]} cpos
* @returns {Promise<number[]>}
*/
async cl_cpos2id(attribute, cpos) {
const fn_name = 'cl_cpos2id';
const fn_args = {attribute: attribute, cpos: cpos};
return await this.#request(fn_name, fn_args);
}
/**
* returns "" for every corpus position in <cpos> that is out of range
*
* @param {string} attribute
* @param {number[]} cpos
* @returns {Promise<string[]>}
*/
async cl_cpos2str(attribute, cpos) {
const fn_name = 'cl_cpos2str';
const fn_args = {attribute: attribute, cpos: cpos};
return await this.#request(fn_name, fn_args);
}
/**
* returns -1 for every corpus position not inside a structure region
*
* @param {string} attribute
* @param {number[]} cpos
* @returns {Promise<number[]>}
*/
async cl_cpos2struc(attribute, cpos) {
const fn_name = 'cl_cpos2struc';
const fn_args = {attribute: attribute, cpos: cpos};
return await this.#request(fn_name, fn_args);
}
/**
* NOTE: temporary addition for the Euralex2000 tutorial, but should
* probably be included in CQi specs
*/
/**
* returns left boundary of s-attribute region enclosing cpos,
* -1 if not in region
*
* @param {string} attribute
* @param {number[]} cpos
* @returns {Promise<number[]>}
*/
async cl_cpos2lbound(attribute, cpos) {
const fn_name = 'cl_cpos2lbound';
const fn_args = {attribute: attribute, cpos: cpos};
return await this.#request(fn_name, fn_args);
}
/**
* returns right boundary of s-attribute region enclosing cpos,
* -1 if not in region
*
* @param {string} attribute
* @param {number[]} cpos
* @returns {Promise<number[]>}
*/
async cl_cpos2rbound(attribute, cpos) {
const fn_name = 'cl_cpos2rbound';
const fn_args = {attribute: attribute, cpos: cpos};
return await this.#request(fn_name, fn_args);
}
/**
* returns -1 for every corpus position not inside an alignment
*
* @param {string} attribute
* @param {number[]} cpos
* @returns {Promise<number[]>}
*/
async cl_cpos2alg(attribute, cpos) {
const fn_name = 'cl_cpos2alg';
const fn_args = {attribute: attribute, cpos: cpos};
return await this.#request(fn_name, fn_args);
}
/**
* returns annotated string values of structure regions in <strucs>;
* "" if out of range
*
* check corpus_structural_attribute_has_values(<attribute>) first
*
* @param {string} attribute
* @param {number[]} strucs
* @returns {Promise<string[]>}
*/
async cl_struc2str(attribute, strucs) {
const fn_name = 'cl_struc2str';
const fn_args = {attribute: attribute, strucs: strucs};
return await this.#request(fn_name, fn_args);
}
/**
* NOTE: the following mappings take a single argument and return multiple
* values, including lists of arbitrary size
*/
/**
* returns all corpus positions where the given token occurs
*
* @param {string} attribute
* @param {number} id
* @returns {Promise<number[]>}
*/
async cl_id2cpos(attribute, id) {
const fn_name = 'cl_id2cpos';
const fn_args = {attribute: attribute, id: id};
return await this.#request(fn_name, fn_args);
}
/**
* returns all corpus positions where one of the tokens in <id_list> occurs;
* the returned list is sorted as a whole, not per token id
*
* @param {string} attribute
* @param {number[]} id_list
* @returns {Promise<number[]>}
*/
async cl_idlist2cpos(attribute, id_list) {
const fn_name = 'cl_idlist2cpos';
const fn_args = {attribute: attribute, id_list: id_list};
return await this.#request(fn_name, fn_args);
}
/**
* returns lexicon IDs of all tokens that match <regex>;
* the returned list may be empty (size 0);
*
* @param {string} attribute
* @param {string} regex
* @returns {Promise<number[]>}
*/
async cl_regex2id(attribute, regex) {
const fn_name = 'cl_regex2id';
const fn_args = {attribute: attribute, regex: regex};
return await this.#request(fn_name, fn_args);
}
/**
* returns start and end corpus positions of structure region <struc>
*
* @param {string} attribute
* @param {number} struc
* @returns {Promise<[number, number]>}
*/
async cl_struc2cpos(attribute, struc) {
const fn_name = 'cl_struc2cpos';
const fn_args = {attribute: attribute, struc: struc};
return await this.#request(fn_name, fn_args);
}
/**
* returns (src_start, src_end, target_start, target_end)
*
* @param {string} attribute
* @param {number} alg
* @returns {Promise<[number, number, number, number]>}
*/
async alg2cpos(attribute, alg) {
const fn_name = 'alg2cpos';
const fn_args = {attribute: attribute, alg: alg};
return await this.#request(fn_name, fn_args);
}
/**
* <query> must include the ';' character terminating the query.
*
* @param {string} mother_corpus
* @param {string} subcorpus_name
* @param {string} query
* @returns {Promise<cqi.status.StatusOk>}
*/
async cqp_query(mother_corpus, subcorpus_name, query) {
const fn_name = 'cqp_query';
const fn_args = {mother_corpus: mother_corpus, subcorpus_name: subcorpus_name, query: query};
let payload = await this.#request(fn_name, fn_args);
return new cqi.status.lookup[payload.code]();
}
/**
* @param {string} corpus
* @returns {Promise<string[]>}
*/
async cqp_list_subcorpora(corpus) {
const fn_name = 'cqp_list_subcorpora';
const fn_args = {corpus: corpus};
return await this.#request(fn_name, fn_args);
}
/**
* @param {string} subcorpus
* @returns {Promise<number>}
*/
async cqp_subcorpus_size(subcorpus) {
const fn_name = 'cqp_subcorpus_size';
const fn_args = {subcorpus: subcorpus};
return await this.#request(fn_name, fn_args);
}
/**
* @param {string} subcorpus
* @param {number} field
* @returns {Promise<boolean>}
*/
async cqp_subcorpus_has_field(subcorpus, field) {
const fn_name = 'cqp_subcorpus_has_field';
const fn_args = {subcorpus: subcorpus, field: field};
return await this.#request(fn_name, fn_args);
}
/**
* Dump the values of <field> for match ranges <first> .. <last>
* in <subcorpus>. <field> is one of the CQI_CONST_FIELD_* constants.
*
* @param {string} subcorpus
* @param {number} field
* @param {number} first
* @param {number} last
* @returns {Promise<number[]>}
*/
async cqp_dump_subcorpus(subcorpus, field, first, last) {
const fn_name = 'cqp_dump_subcorpus';
const fn_args = {subcorpus: subcorpus, field: field, first: first, last: last};
return await this.#request(fn_name, fn_args);
}
/**
* delete a subcorpus from memory
*
* @param {string} subcorpus
* @returns {Promise<cqi.status.StatusOk>}
*/
async cqp_drop_subcorpus(subcorpus) {
const fn_name = 'cqp_drop_subcorpus';
const fn_args = {subcorpus: subcorpus};
let payload = await this.#request(fn_name, fn_args);
return new cqi.status.lookup[payload.code]();
}
/**
* NOTE: The following two functions are temporarily included for the
* Euralex 2000 tutorial demo
*/
/**
* frequency distribution of single tokens
*
* returns <n> (id, frequency) pairs flattened into a list of size 2*<n>
* field is one of
* - CQI_CONST_FIELD_MATCH
* - CQI_CONST_FIELD_TARGET
* - CQI_CONST_FIELD_KEYWORD
*
* NB: pairs are sorted by frequency desc.
*
* @param {string} subcorpus
* @param {number} cutoff
* @param {number} field
* @param {string} attribute
* @returns {Promise<number[]>}
*/
async cqp_fdist_1(subcorpus, cutoff, field, attribute) {
const fn_name = 'cqp_fdist_1';
const fn_args = {subcorpus: subcorpus, cutoff: cutoff, field: field, attribute: attribute};
return await this.#request(fn_name, fn_args);
}
/**
* frequency distribution of pairs of tokens
*
* returns <n> (id1, id2, frequency) pairs flattened into a list of
* size 3*<n>
*
* NB: triples are sorted by frequency desc.
*
* @param {string} subcorpus
* @param {number} cutoff
* @param {number} field1
* @param {string} attribute1
* @param {number} field2
* @param {string} attribute2
* @returns {Promise<number[]>}
*/
async cqp_fdist_2(subcorpus, cutoff, field1, attribute1, field2, attribute2) {
const fn_name = 'cqp_fdist_2';
const fn_args = {subcorpus: subcorpus, cutoff: cutoff, field1: field1, attribute1: attribute1, field2: field2, attribute2: attribute2};
return await this.#request(fn_name, fn_args);
}
/**************************************************************************
* NOTE: The following is not included in the CQi specification. *
**************************************************************************/
/**************************************************************************
* Custom additions for nopaque *
**************************************************************************/
/**
* @param {string} corpus
* @returns {Promise<cqi.status.StatusOk>}
*/
async ext_corpus_update_db(corpus) {
const fn_name = 'ext_corpus_update_db';
const fn_args = {corpus: corpus};
let payload = await this.#request(fn_name, fn_args);
return new cqi.status.lookup[payload.code]();
}
/**
* @param {string} corpus
* @returns {Promise<object>}
*/
async ext_corpus_static_data(corpus) {
const fn_name = 'ext_corpus_static_data';
const fn_args = {corpus: corpus};
return await this.#request(fn_name, fn_args);
}
/**
* @param {string} corpus
* @param {number=} page
* @param {number=} per_page
* @returns {Promise<object>}
*/
async ext_corpus_paginate_corpus(corpus, page, per_page) {
const fn_name = 'ext_corpus_paginate_corpus';
const fn_args = {corpus: corpus}
if (page !== undefined) {fn_args.page = page;}
if (per_page !== undefined) {fn_args.per_page = per_page;}
return await this.#request(fn_name, fn_args);
}
/**
* @param {string} subcorpus
* @param {number=} context
* @param {number=} page
* @param {number=} per_page
* @returns {Promise<object>}
*/
async ext_cqp_paginate_subcorpus(subcorpus, context, page, per_page) {
const fn_name = 'ext_cqp_paginate_subcorpus';
const fn_args = {subcorpus: subcorpus}
if (context !== undefined) {fn_args.context = context;}
if (page !== undefined) {fn_args.page = page;}
if (per_page !== undefined) {fn_args.per_page = per_page;}
return await this.#request(fn_name, fn_args);
}
/**
* @param {string} subcorpus
* @param {number[]} match_id_list
* @param {number=} context
* @returns {Promise<object>}
*/
async ext_cqp_partial_export_subcorpus(subcorpus, match_id_list, context) {
const fn_name = 'ext_cqp_partial_export_subcorpus';
const fn_args = {subcorpus: subcorpus, match_id_list: match_id_list};
if (context !== undefined) {fn_args.context = context;}
return await this.#request(fn_name, fn_args);
}
/**
* @param {string} subcorpus
* @param {number=} context
* @returns {Promise<object>}
*/
async ext_cqp_export_subcorpus(subcorpus, context) {
const fn_name = 'ext_cqp_export_subcorpus';
const fn_args = {subcorpus: subcorpus};
if (context !== undefined) {fn_args.context = context;}
return await this.#request(fn_name, fn_args);
}
};

View File

@ -0,0 +1 @@
cqi.api = {};

View File

@ -0,0 +1,58 @@
cqi.CQiClient = class CQiClient {
/**
* @param {string} host
* @param {string} corpusId
* @param {number} [timeout=60] timeout
* @param {string} [version=0.1] version
*/
constructor(host, corpusId, timeout = 60, version = '0.1') {
/** @type {cqi.api.APIClient} */
this.api = new cqi.api.APIClient(host, corpusId, timeout, version);
}
/**
* @returns {cqi.models.corpora.CorpusCollection}
*/
get corpora() {
return new cqi.models.corpora.CorpusCollection(this);
}
/**
* @returns {Promise<cqi.status.StatusByeOk>}
*/
async bye() {
return await this.api.ctrl_bye();
}
/**
* @param {string} username
* @param {string} password
* @returns {Promise<cqi.status.StatusConnectOk>}
*/
async connect(username, password) {
return await this.api.ctrl_connect(username, password);
}
/**
* @returns {Promise<cqi.status.StatusPingOk>}
*/
async ping() {
return await this.api.ctrl_ping();
}
/**
* @returns {Promise<null>}
*/
async userAbort() {
return await this.api.ctrl_user_abort();
}
/**
* Alias for "bye" method
*
* @returns {Promise<cqi.status.StatusByeOk>}
*/
async disconnect() {
return await this.api.ctrl_bye();
}
};

185
app/static/js/cqi/errors.js Normal file
View File

@ -0,0 +1,185 @@
cqi.errors = {};
/**
* A base class from which all other errors inherit.
* If you want to catch all errors that the CQi package might throw,
* catch this base error.
*/
cqi.errors.CQiError = class CQiError extends Error {
constructor(message) {
super(message);
this.code = undefined;
this.description = undefined;
}
};
cqi.errors.Error = class Error extends cqi.errors.CQiError {
constructor(message) {
super(message);
this.code = 2;
}
};
cqi.errors.ErrorGeneralError = class ErrorGeneralError extends cqi.errors.Error {
constructor(message) {
super(message);
this.code = 513;
}
};
cqi.errors.ErrorConnectRefused = class ErrorConnectRefused extends cqi.errors.Error {
constructor(message) {
super(message);
this.code = 514;
}
};
cqi.errors.ErrorUserAbort = class ErrorUserAbort extends cqi.errors.Error {
constructor(message) {
super(message);
this.code = 515;
}
};
cqi.errors.ErrorSyntaxError = class ErrorSyntaxError extends cqi.errors.Error {
constructor(message) {
super(message);
this.code = 516;
}
};
cqi.errors.CLError = class Error extends cqi.errors.CQiError {
constructor(message) {
super(message);
this.code = 4;
}
};
cqi.errors.CLErrorNoSuchAttribute = class CLErrorNoSuchAttribute extends cqi.errors.CLError {
constructor(message) {
super(message);
this.code = 1025;
this.description = "CQi server couldn't open attribute";
}
};
cqi.errors.CLErrorWrongAttributeType = class CLErrorWrongAttributeType extends cqi.errors.CLError {
constructor(message) {
super(message);
this.code = 1026;
}
};
cqi.errors.CLErrorOutOfRange = class CLErrorOutOfRange extends cqi.errors.CLError {
constructor(message) {
super(message);
this.code = 1027;
}
};
cqi.errors.CLErrorRegex = class CLErrorRegex extends cqi.errors.CLError {
constructor(message) {
super(message);
this.code = 1028;
}
};
cqi.errors.CLErrorCorpusAccess = class CLErrorCorpusAccess extends cqi.errors.CLError {
constructor(message) {
super(message);
this.code = 1029;
}
};
cqi.errors.CLErrorOutOfMemory = class CLErrorOutOfMemory extends cqi.errors.CLError {
constructor(message) {
super(message);
this.code = 1030;
this.description = 'CQi server has run out of memory; try discarding some other corpora and/or subcorpora';
}
};
cqi.errors.CLErrorInternal = class CLErrorInternal extends cqi.errors.CLError {
constructor(message) {
super(message);
this.code = 1031;
this.description = "The classical 'please contact technical support' error";
}
};
cqi.errors.CQPError = class Error extends cqi.errors.CQiError {
constructor(message) {
super(message);
this.code = 5;
}
};
cqi.errors.CQPErrorGeneral = class CQPErrorGeneral extends cqi.errors.CQPError {
constructor(message) {
super(message);
this.code = 1281;
}
};
cqi.errors.CQPErrorNoSuchCorpus = class CQPErrorNoSuchCorpus extends cqi.errors.CQPError {
constructor(message) {
super(message);
this.code = 1282;
}
};
cqi.errors.CQPErrorInvalidField = class CQPErrorInvalidField extends cqi.errors.CQPError {
constructor(message) {
super(message);
this.code = 1283;
}
};
cqi.errors.CQPErrorOutOfRange = class CQPErrorOutOfRange extends cqi.errors.CQPError {
constructor(message) {
super(message);
this.code = 1284;
this.description = 'A number is out of range';
}
};
cqi.errors.lookup = {
2: cqi.errors.Error,
513: cqi.errors.ErrorGeneralError,
514: cqi.errors.ErrorConnectRefused,
515: cqi.errors.ErrorUserAbort,
516: cqi.errors.ErrorSyntaxError,
4: cqi.errors.CLError,
1025: cqi.errors.CLErrorNoSuchAttribute,
1026: cqi.errors.CLErrorWrongAttributeType,
1027: cqi.errors.CLErrorOutOfRange,
1028: cqi.errors.CLErrorRegex,
1029: cqi.errors.CLErrorCorpusAccess,
1030: cqi.errors.CLErrorOutOfMemory,
1031: cqi.errors.CLErrorInternal,
5: cqi.errors.CQPError,
1281: cqi.errors.CQPErrorGeneral,
1282: cqi.errors.CQPErrorNoSuchCorpus,
1283: cqi.errors.CQPErrorInvalidField,
1284: cqi.errors.CQPErrorOutOfRange
};

View File

@ -0,0 +1,289 @@
cqi.models.attributes = {};
cqi.models.attributes.Attribute = class Attribute extends cqi.models.resource.Model {
/**
* @returns {string}
*/
get apiName() {
return this.attrs.api_name;
}
/**
* @returns {string}
*/
get name() {
return this.attrs.name;
}
/**
* @returns {number}
*/
get size() {
return this.attrs.size;
}
/**
* @returns {Promise<cqi.status.StatusOk>}
*/
async drop() {
return await this.client.api.cl_drop_attribute(this.apiName);
}
};
cqi.models.attributes.AttributeCollection = class AttributeCollection extends cqi.models.resource.Collection {
/** @type{typeof cqi.models.attributes.Attribute} */
static model = cqi.models.attributes.Attribute;
/**
* @param {cqi.CQiClient} client
* @param {cqi.models.corpora.Corpus} corpus
*/
constructor(client, corpus) {
super(client);
/** @type {cqi.models.corpora.Corpus} */
this.corpus = corpus;
}
/**
* @param {string} attributeName
* @returns {Promise<object>}
*/
async _get(attributeName) {
/** @type{string} */
let apiName = `${this.corpus.apiName}.${attributeName}`;
return {
api_name: apiName,
name: attributeName,
size: await this.client.api.cl_attribute_size(apiName)
}
}
/**
* @param {string} attributeName
* @returns {Promise<cqi.models.attributes.Attribute>}
*/
async get(attributeName) {
return this.prepareModel(await this._get(attributeName));
}
};
cqi.models.attributes.AlignmentAttribute = class AlignmentAttribute extends cqi.models.attributes.Attribute {
/**
* @param {number} id
* @returns {Promise<[number, number, number, number]>}
*/
async cposById(id) {
return await this.client.api.cl_alg2cpos(this.apiName, id);
}
/**
* @param {number[]} cposList
* @returns {Promise<number[]>}
*/
async idsByCpos(cposList) {
return await this.client.api.cl_cpos2alg(this.apiName, cposList);
}
};
cqi.models.attributes.AlignmentAttributeCollection = class AlignmentAttributeCollection extends cqi.models.attributes.AttributeCollection {
/** @type{typeof cqi.models.attributes.AlignmentAttribute} */
static model = cqi.models.attributes.AlignmentAttribute;
/**
* @returns {Promise<cqi.models.attributes.AlignmentAttribute[]>}
*/
async list() {
/** @type {string[]} */
let alignmentAttributeNames = await this.client.api.corpus_alignment_attributes(this.corpus.apiName);
/** @type {cqi.models.attributes.AlignmentAttribute[]} */
let alignmentAttributes = [];
for (let alignmentAttributeName of alignmentAttributeNames) {
alignmentAttributes.push(await this.get(alignmentAttributeName));
}
return alignmentAttributes;
}
};
cqi.models.attributes.PositionalAttribute = class PositionalAttribute extends cqi.models.attributes.Attribute {
/**
* @returns {number}
*/
get lexiconSize() {
return this.attrs.lexicon_size;
}
/**
* @param {number} id
* @returns {Promise<number[]>}
*/
async cposById(id) {
return await this.client.api.cl_id2cpos(this.apiName, id);
}
/**
* @param {number[]} idList
* @returns {Promise<number[]>}
*/
async cposByIds(idList) {
return await this.client.api.cl_idlist2cpos(this.apiName, idList);
}
/**
* @param {number[]} idList
* @returns {Promise<number[]>}
*/
async freqsByIds(idList) {
return await this.client.api.cl_id2freq(this.apiName, idList);
}
/**
* @param {number[]} cposList
* @returns {Promise<number[]>}
*/
async idsByCpos(cposList) {
return await this.client.api.cl_cpos2id(this.apiName, cposList);
}
/**
* @param {string} regex
* @returns {Promise<number[]>}
*/
async idsByRegex(regex) {
return await this.client.api.cl_regex2id(this.apiName, regex);
}
/**
* @param {string[]} valueList
* @returns {Promise<number[]>}
*/
async idsByValues(valueList) {
return await this.client.api.cl_str2id(this.apiName, valueList);
}
/**
* @param {number[]} cposList
* @returns {Promise<string[]>}
*/
async valuesByCpos(cposList) {
return await this.client.api.cl_cpos2str(this.apiName, cposList);
}
/**
* @param {number[]} idList
* @returns {Promise<string[]>}
*/
async valuesByIds(idList) {
return await this.client.api.cl_id2str(this.apiName, idList);
}
};
cqi.models.attributes.PositionalAttributeCollection = class PositionalAttributeCollection extends cqi.models.attributes.AttributeCollection {
/** @type{typeof cqi.models.attributes.PositionalAttribute} */
static model = cqi.models.attributes.PositionalAttribute;
/**
* @param {string} positionalAttributeName
* @returns {Promise<object>}
*/
async _get(positionalAttributeName) {
let positionalAttribute = await super._get(positionalAttributeName);
positionalAttribute.lexicon_size = await this.client.api.cl_lexicon_size(positionalAttribute.api_name);
return positionalAttribute;
}
/**
* @returns {Promise<cqi.models.attributes.PositionalAttribute[]>}
*/
async list() {
let positionalAttributeNames = await this.client.api.corpus_positional_attributes(this.corpus.apiName);
let positionalAttributes = [];
for (let positionalAttributeName of positionalAttributeNames) {
positionalAttributes.push(await this.get(positionalAttributeName));
}
return positionalAttributes;
}
};
cqi.models.attributes.StructuralAttribute = class StructuralAttribute extends cqi.models.attributes.Attribute {
/**
* @returns {boolean}
*/
get hasValues() {
return this.attrs.has_values;
}
/**
* @param {number} id
* @returns {Promise<[number, number]>}
*/
async cposById(id) {
return await this.client.api.cl_struc2cpos(this.apiName, id);
}
/**
* @param {number[]} cposList
* @returns {Promise<number[]>}
*/
async idsByCpos(cposList) {
return await this.client.api.cl_cpos2struc(this.apiName, cposList);
}
/**
* @param {number[]} cposList
* @returns {Promise<number[]>}
*/
async lboundByCpos(cposList) {
return await this.client.api.cl_cpos2lbound(this.apiName, cposList);
}
/**
* @param {number[]} cposList
* @returns {Promise<number[]>}
*/
async rboundByCpos(cposList) {
return await this.client.api.cl_cpos2rbound(this.apiName, cposList);
}
/**
* @param {number[]} idList
* @returns {Promise<string[]>}
*/
async valuesByIds(idList) {
return await this.client.api.cl_struc2str(this.apiName, idList);
}
};
cqi.models.attributes.StructuralAttributeCollection = class StructuralAttributeCollection extends cqi.models.attributes.AttributeCollection {
/** @type{typeof cqi.models.attributes.StructuralAttribute} */
static model = cqi.models.attributes.StructuralAttribute;
/**
* @param {string} structuralAttributeName
* @returns {Promise<object>}
*/
async _get(structuralAttributeName) {
let structuralAttribute = await super._get(structuralAttributeName);
structuralAttribute.has_values = await this.client.api.cl_has_values(structuralAttribute.api_name);
return structuralAttribute;
}
/**
* @returns {Promise<cqi.models.attributes.StructuralAttribute[]>}
*/
async list() {
let structuralAttributeNames = await this.client.api.corpus_structural_attributes(this.corpus.apiName);
let structuralAttributes = [];
for (let structuralAttributeName of structuralAttributeNames) {
structuralAttributes.push(await this.get(structuralAttributeName));
}
return structuralAttributes;
}
};

View File

@ -0,0 +1,166 @@
cqi.models.corpora = {};
cqi.models.corpora.Corpus = class Corpus extends cqi.models.resource.Model {
/**
* @returns {string}
*/
get apiName() {
return this.attrs.api_name;
}
/**
* @returns {string}
*/
get name() {
return this.attrs.name;
}
/**
* @returns {number}
*/
get size() {
return this.attrs.size;
}
/**
* @returns {string}
*/
get charset() {
return this.attrs.charset;
}
/**
* @returns {string[]}
*/
get properties() {
return this.attrs?.properties;
}
/**
* @returns {cqi.models.attributes.AlignmentAttributeCollection}
*/
get alignmentAttributes() {
return new cqi.models.attributes.AlignmentAttributeCollection(this.client, this);
}
/**
* @returns {cqi.models.attributes.PositionalAttributeCollection}
*/
get positionalAttributes() {
return new cqi.models.attributes.PositionalAttributeCollection(this.client, this);
}
/**
* @returns {cqi.models.attributes.StructuralAttributeCollection}
*/
get structuralAttributes() {
return new cqi.models.attributes.StructuralAttributeCollection(this.client, this);
}
/**
* @returns {cqi.models.subcorpora.SubcorpusCollection}
*/
get subcorpora() {
return new cqi.models.subcorpora.SubcorpusCollection(this.client, this);
}
/**
* @returns {Promise<cqi.status.StatusOk>}
*/
async drop() {
return await this.client.api.corpus_drop_corpus(this.apiName);
}
/**
* @param {string} subcorpusName
* @param {string} query
* @returns {Promise<cqi.status.StatusOk>}
*/
async query(subcorpusName, query) {
return await this.client.api.cqp_query(this.apiName, subcorpusName, query);
}
/**************************************************************************
* NOTE: The following is not included in the CQi specification. *
**************************************************************************/
/**************************************************************************
* Custom additions for nopaque *
**************************************************************************/
/**
* @returns {string}
*/
get staticData() {
return this.attrs.static_data;
}
/**
* @returns {cqi.status.StatusOk}
*/
async updateDb() {
return await this.client.api.ext_corpus_update_db(this.apiName);
}
/**
* @param {number=} page
* @param {number=} per_page
* @returns {Promise<object>}
*/
async paginate(page, per_page) {
return await this.client.api.ext_corpus_paginate_corpus(this.apiName, page, per_page);
}
};
cqi.models.corpora.CorpusCollection = class CorpusCollection extends cqi.models.resource.Collection {
/** @type {typeof cqi.models.corpora.Corpus} */
static model = cqi.models.corpora.Corpus;
/**
* @param {string} corpusName
* @returns {Promise<object>}
*/
async _get(corpusName) {
const returnValue = {
api_name: corpusName,
charset: await this.client.api.corpus_charset(corpusName),
// full_name: await this.client.api.corpus_full_name(corpusName),
// info: await this.client.api.corpus_info(corpusName),
name: corpusName,
properties: await this.client.api.corpus_properties(corpusName),
size: await this.client.api.cl_attribute_size(`${corpusName}.word`)
};
/************************************************************************
* NOTE: The following is not included in the CQi specification. *
************************************************************************/
/************************************************************************
* Custom additions for nopaque *
************************************************************************/
returnValue.static_data = await this.client.api.ext_corpus_static_data(corpusName);
return returnValue;
}
/**
* @param {string} corpusName
* @returns {Promise<cqi.models.corpora.Corpus>}
*/
async get(corpusName) {
return this.prepareModel(await this._get(corpusName));
}
/**
* @returns {Promise<cqi.models.corpora.Corpus[]>}
*/
async list() {
/** @type {string[]} */
let corpusNames = await this.client.api.corpus_list_corpora();
/** @type {cqi.models.corpora.Corpus[]} */
let corpora = [];
for (let corpusName of corpusNames) {
corpora.push(await this.get(corpusName));
}
return corpora;
}
};

View File

@ -0,0 +1 @@
cqi.models = {};

View File

@ -0,0 +1,90 @@
cqi.models.resource = {};
/**
* A base class for representing a single object on the server.
*/
cqi.models.resource.Model = class Model {
/**
* @param {object} attrs
* @param {cqi.CQiClient} client
* @param {cqi.models.resource.Collection} collection
*/
constructor(attrs, client, collection) {
/**
* A client pointing at the server that this object is on.
*
* @type {cqi.CQiClient}
*/
this.client = client;
/**
* The collection that this model is part of.
*
* @type {cqi.models.resource.Collection}
*/
this.collection = collection;
/**
* The raw representation of this object from the API
*
* @type {object}
*/
this.attrs = attrs;
}
/**
* @returns {string}
*/
get apiName() {
throw new Error('Not implemented');
}
/**
* @returns {Promise<void>}
*/
async reload() {
this.attrs = await this.collection.get(this.apiName).attrs;
}
};
/**
* A base class for representing all objects of a particular type on the server.
*/
cqi.models.resource.Collection = class Collection {
/**
* The type of object this collection represents, set by subclasses
*
* @type {typeof cqi.models.resource.Model}
*/
static model;
/**
* @param {cqi.CQiClient} client
*/
constructor(client) {
/**
* A client pointing at the server that this object is on.
*
* @type {cqi.CQiClient}
*/
this.client = client;
}
async list() {
throw new Error('Not implemented');
}
async get() {
throw new Error('Not implemented');
}
/**
* Create a model from a set of attributes.
*
* @param {object} attrs
* @returns {cqi.models.resource.Model}
*/
prepareModel(attrs) {
return new this.constructor.model(attrs, this.client, this);
}
};

View File

@ -0,0 +1,189 @@
cqi.models.subcorpora = {};
cqi.models.subcorpora.Subcorpus = class Subcorpus extends cqi.models.resource.Model {
/**
* @returns {string}
*/
get apiName() {
return this.attrs.api_name;
}
/**
* @returns {object}
*/
get fields() {
return this.attrs.fields;
}
/**
* @returns {string}
*/
get name() {
return this.attrs.name;
}
/**
* @returns {number}
*/
get size() {
return this.attrs.size;
}
/**
* @returns {Promise<cqi.status.StatusOk>}
*/
async drop() {
return await this.client.api.cqp_drop_subcorpus(this.apiName);
}
/**
* @param {number} field
* @param {number} first
* @param {number} last
* @returns {Promise<number[]>}
*/
async dump(field, first, last) {
return await this.client.api.cqp_dump_subcorpus(
this.apiName,
field,
first,
last
);
}
/**
* @param {number} cutoff
* @param {number} field
* @param {cqi.models.attributes.PositionalAttribute} attribute
* @returns {Promise<number[]>}
*/
async fdist1(cutoff, field, attribute) {
return await this.client.api.cqp_fdist_1(
this.apiName,
cutoff,
field,
attribute.apiName
);
}
/**
* @param {number} cutoff
* @param {number} field1
* @param {cqi.models.attributes.PositionalAttribute} attribute1
* @param {number} field2
* @param {cqi.models.attributes.PositionalAttribute} attribute2
* @returns {Promise<number[]>}
*/
async fdist2(cutoff, field1, attribute1, field2, attribute2) {
return await this.client.api.cqp_fdist_2(
this.apiName,
cutoff,
field1,
attribute1.apiName,
field2,
attribute2.apiName
);
}
/**************************************************************************
* NOTE: The following is not included in the CQi specification. *
**************************************************************************/
/**************************************************************************
* Custom additions for nopaque *
**************************************************************************/
/**
* @param {number=} context
* @param {number=} page
* @param {number=} perPage
* @returns {Promise<object>}
*/
async paginate(context, page, perPage) {
return await this.client.api.ext_cqp_paginate_subcorpus(this.apiName, context, page, perPage);
}
/**
* @param {number[]} matchIdList
* @param {number=} context
* @returns {Promise<object>}
*/
async partialExport(matchIdList, context) {
return await this.client.api.ext_cqp_partial_export_subcorpus(this.apiName, matchIdList, context);
}
/**
* @param {number=} context
* @returns {Promise<object>}
*/
async export(context) {
return await this.client.api.ext_cqp_export_subcorpus(this.apiName, context);
}
};
cqi.models.subcorpora.SubcorpusCollection = class SubcorpusCollection extends cqi.models.resource.Collection {
/** @type {typeof cqi.models.subcorpora.Subcorpus} */
static model = cqi.models.subcorpora.Subcorpus;
/**
* @param {cqi.CQiClient} client
* @param {cqi.models.corpora.Corpus} corpus
*/
constructor(client, corpus) {
super(client);
/** @type {cqi.models.corpora.Corpus} */
this.corpus = corpus;
}
/**
* @param {string} subcorpusName
* @returns {Promise<object>}
*/
async _get(subcorpusName) {
/** @type {string} */
let apiName = `${this.corpus.apiName}:${subcorpusName}`;
/** @type {object} */
let fields = {};
if (await this.client.api.cqp_subcorpus_has_field(apiName, cqi.CONST_FIELD_MATCH)) {
fields.match = cqi.CONST_FIELD_MATCH;
}
if (await this.client.api.cqp_subcorpus_has_field(apiName, cqi.CONST_FIELD_MATCHEND)) {
fields.matchend = cqi.CONST_FIELD_MATCHEND
}
if (await this.client.api.cqp_subcorpus_has_field(apiName, cqi.CONST_FIELD_TARGET)) {
fields.target = cqi.CONST_FIELD_TARGET
}
if (await this.client.api.cqp_subcorpus_has_field(apiName, cqi.CONST_FIELD_KEYWORD)) {
fields.keyword = cqi.CONST_FIELD_KEYWORD
}
return {
api_name: apiName,
fields: fields,
name: subcorpusName,
size: await this.client.api.cqp_subcorpus_size(apiName)
}
}
/**
* @param {string} subcorpusName
* @returns {Promise<cqi.models.subcorpora.Subcorpus>}
*/
async get(subcorpusName) {
return this.prepareModel(await this._get(subcorpusName));
}
/**
* @returns {Promise<cqi.models.subcorpora.Subcorpus[]>}
*/
async list() {
/** @type {string[]} */
let subcorpusNames = await this.client.api.cqp_list_subcorpora(this.corpus.apiName);
/** @type {cqi.models.subcorpora.Subcorpus[]} */
let subcorpora = [];
for (let subcorpusName of subcorpusNames) {
subcorpora.push(await this.get(subcorpusName));
}
return subcorpora;
}
};

View File

@ -0,0 +1,6 @@
var cqi = {};
cqi.CONST_FIELD_KEYWORD = 9;
cqi.CONST_FIELD_MATCH = 16;
cqi.CONST_FIELD_MATCHEND = 17;
cqi.CONST_FIELD_TARGET = 0;

View File

@ -0,0 +1,51 @@
cqi.status = {};
/**
* A base class from which all other status inherit.
*/
cqi.status.CQiStatus = class CQiStatus {
constructor() {
this.code = undefined;
}
};
cqi.status.StatusOk = class StatusOk extends cqi.status.CQiStatus {
constructor() {
super();
this.code = 257;
}
};
cqi.status.StatusConnectOk = class StatusConnectOk extends cqi.status.CQiStatus {
constructor() {
super();
this.code = 258;
}
};
cqi.status.StatusByeOk = class StatusByeOk extends cqi.status.CQiStatus {
constructor() {
super();
this.code = 259;
}
};
cqi.status.StatusPingOk = class StatusPingOk extends cqi.status.CQiStatus {
constructor() {
super();
this.code = 260;
}
};
cqi.status.lookup = {
257: cqi.status.StatusOk,
258: cqi.status.StatusConnectOk,
259: cqi.status.StatusByeOk,
260: cqi.status.StatusPingOk
};