@ca-plant-list/ca-plant-list 0.3.2 → 0.3.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.vscode/settings.json +4 -2
- package/data/exceptions.json +0 -3
- package/data/glossary/ovary.md +3 -0
- package/data/glossary/pistil.md +3 -0
- package/data/glossary/stigma.md +3 -0
- package/data/glossary/style.md +3 -0
- package/data/illustrations/inkscape/pistil.svg +156 -0
- package/data/synonyms.csv +8 -2
- package/data/taxa.csv +54 -52
- package/data/text/Ceanothus-cuneatus-var-cuneatus.md +1 -0
- package/data/text/Ceanothus-leucodermis.md +1 -0
- package/data/text/Delphinium-californicum-subsp-californicum.md +1 -0
- package/data/text/Delphinium-decorum-subsp-decorum.md +1 -0
- package/data/text/Delphinium-hesperium-subsp-hesperium.md +1 -0
- package/data/text/Delphinium-patens-subsp-patens.md +1 -0
- package/data/text/Galium-andrewsii-subsp-gatense.md +1 -0
- package/data/text/Helianthella-californica-var-californica.md +1 -0
- package/data/text/Helianthella-castanea.md +1 -0
- package/data/text/Iris-macrosiphon.md +1 -0
- package/data/text/Lasthenia-californica-subsp-californica.md +1 -0
- package/data/text/Lasthenia-gracilis.md +1 -0
- package/data/text/Lithophragma-affine.md +1 -1
- package/data/text/Lithophragma-parviflorum-var-parviflorum.md +1 -1
- package/data/text/Lomatium-californicum.md +0 -0
- package/data/text/Lomatium-dasycarpum-subsp-dasycarpum.md +1 -0
- package/data/text/Lomatium-utriculatum.md +1 -0
- package/data/text/Nemophila-heterophylla.md +1 -0
- package/data/text/Nemophila-parviflora-var-parviflora.md +1 -0
- package/data/text/Plectritis-ciliosa.md +1 -0
- package/data/text/Plectritis-macrocera.md +1 -0
- package/data/text/Primula-clevelandii-var-patula.md +1 -0
- package/data/text/Primula-hendersonii.md +1 -0
- package/data/text/Sidalcea-diploscypha.md +1 -0
- package/data/text/Thysanocarpus-curvipes.md +1 -0
- package/data/text/Thysanocarpus-laciniatus.md +1 -0
- package/data/text/Viola-douglasii.md +1 -0
- package/data/text/Viola-pedunculata.md +1 -0
- package/data/text/Viola-purpurea-subsp-quercetorum.md +1 -0
- package/ebook/css/main.css +5 -0
- package/lib/basepagerenderer.js +30 -28
- package/lib/dateutils.js +36 -16
- package/lib/ebook/pages/taxonpage.js +63 -36
- package/lib/errorlog.js +16 -11
- package/lib/families.js +109 -71
- package/lib/files.js +103 -45
- package/lib/generictaxaloader.js +15 -7
- package/lib/index.js +38 -3
- package/lib/taxa.js +164 -87
- package/lib/taxaloader.js +28 -15
- package/lib/taxaprocessor.js +6 -8
- package/lib/taxon.js +109 -56
- package/package.json +4 -6
- package/scripts/build-ebook.js +30 -25
- package/lib/index.d.ts +0 -345
package/lib/families.js
CHANGED
@@ -4,30 +4,38 @@ import { Jepson } from "./jepson.js";
|
|
4
4
|
import { Taxa } from "./taxa.js";
|
5
5
|
import { Files } from "./files.js";
|
6
6
|
import { Config } from "./config.js";
|
7
|
+
// eslint-disable-next-line no-unused-vars
|
8
|
+
import { Taxon } from "./index.js";
|
7
9
|
|
8
10
|
class Family {
|
9
|
-
|
10
11
|
#name;
|
11
12
|
#data;
|
12
13
|
|
13
|
-
|
14
|
+
/**
|
15
|
+
* @param {string} name
|
16
|
+
* @param {*} data
|
17
|
+
*/
|
18
|
+
constructor(name, data) {
|
14
19
|
this.#name = name;
|
15
20
|
this.#data = data;
|
16
21
|
}
|
17
22
|
|
18
|
-
|
19
|
-
|
23
|
+
/**
|
24
|
+
* @param {Taxon} taxon
|
25
|
+
*/
|
26
|
+
addTaxon(taxon) {
|
27
|
+
if (!this.#data.taxa) {
|
20
28
|
this.#data.taxa = [];
|
21
29
|
}
|
22
|
-
this.#data.taxa.push(
|
23
|
-
Sections.addTaxon(
|
30
|
+
this.#data.taxa.push(taxon);
|
31
|
+
Sections.addTaxon(this.getSectionName(), taxon);
|
24
32
|
}
|
25
33
|
|
26
34
|
getBaseFileName() {
|
27
35
|
return this.getName();
|
28
36
|
}
|
29
37
|
|
30
|
-
getFileName(
|
38
|
+
getFileName(ext = "html") {
|
31
39
|
return this.getBaseFileName() + "." + ext;
|
32
40
|
}
|
33
41
|
|
@@ -46,163 +54,193 @@ class Family {
|
|
46
54
|
getTaxa() {
|
47
55
|
return this.#data.taxa;
|
48
56
|
}
|
49
|
-
|
50
57
|
}
|
51
58
|
|
52
59
|
class Families {
|
53
|
-
|
54
60
|
static #families;
|
55
61
|
|
56
62
|
static {
|
57
|
-
|
58
63
|
const dataDir = Config.getPackageDir() + "/data";
|
59
64
|
|
60
|
-
this.#families = JSON.parse(
|
61
|
-
for (
|
62
|
-
this.#families[
|
65
|
+
this.#families = JSON.parse(Files.read(dataDir + "/families.json"));
|
66
|
+
for (const [k, v] of Object.entries(this.#families)) {
|
67
|
+
this.#families[k] = new Family(k, v);
|
63
68
|
}
|
64
|
-
|
65
69
|
}
|
66
70
|
|
67
71
|
static getFamilies() {
|
68
|
-
return Object.values(
|
72
|
+
return Object.values(this.#families).sort((a, b) =>
|
73
|
+
a.getName().localeCompare(b.getName())
|
74
|
+
);
|
69
75
|
}
|
70
76
|
|
71
|
-
|
72
|
-
|
77
|
+
/**
|
78
|
+
* @param {string} familyName
|
79
|
+
*/
|
80
|
+
static getFamily(familyName) {
|
81
|
+
return this.#families[familyName];
|
73
82
|
}
|
74
83
|
|
75
|
-
|
76
|
-
|
84
|
+
/**
|
85
|
+
* @param {string} outputDir
|
86
|
+
* @param {import("./index.js").TaxaCol[]} taxaColumns
|
87
|
+
*/
|
88
|
+
static renderPages(outputDir, taxaColumns) {
|
89
|
+
new PageFamilyList(outputDir, this.#families).render(taxaColumns);
|
77
90
|
|
78
|
-
const names = Object.keys(
|
79
|
-
for (
|
80
|
-
const family = this.#families[
|
81
|
-
if (
|
82
|
-
new PageFamily(
|
91
|
+
const names = Object.keys(this.#families);
|
92
|
+
for (const name of names.sort()) {
|
93
|
+
const family = this.#families[name];
|
94
|
+
if (family.getTaxa()) {
|
95
|
+
new PageFamily(outputDir, family).render(taxaColumns);
|
83
96
|
}
|
84
97
|
}
|
85
98
|
}
|
86
|
-
|
87
99
|
}
|
88
100
|
|
89
101
|
class PageFamilyList extends GenericPage {
|
90
|
-
|
91
102
|
#families;
|
92
103
|
|
93
|
-
|
94
|
-
|
104
|
+
/**
|
105
|
+
* @param {string} outputDir
|
106
|
+
* @param {Object<string,Family>} families
|
107
|
+
*/
|
108
|
+
constructor(outputDir, families) {
|
109
|
+
super(outputDir, "Families", "list_families");
|
95
110
|
this.#families = families;
|
96
111
|
}
|
97
112
|
|
98
|
-
|
99
|
-
|
113
|
+
/**
|
114
|
+
* @param {import("./index.js").TaxaCol[]} taxaColumns
|
115
|
+
*/
|
116
|
+
render(taxaColumns) {
|
100
117
|
let html = this.getDefaultIntro();
|
101
118
|
|
102
119
|
const sections = Sections.getSections();
|
103
120
|
const sectionLinks = [];
|
104
|
-
for (
|
105
|
-
|
106
|
-
const taxa = sections[ name ];
|
121
|
+
for (const name of Object.keys(sections).sort()) {
|
122
|
+
const taxa = sections[name];
|
107
123
|
|
108
124
|
// Render the section page.
|
109
|
-
new PageSection(
|
125
|
+
new PageSection(this.getOutputDir(), name, taxa).render(
|
126
|
+
taxaColumns
|
127
|
+
);
|
110
128
|
|
111
129
|
// Render the link.
|
112
130
|
const href = "./" + name + ".html";
|
113
|
-
sectionLinks.push(
|
131
|
+
sectionLinks.push(
|
132
|
+
HTML.getLink(href, name) + " (" + taxa.length + ")"
|
133
|
+
);
|
114
134
|
}
|
115
|
-
html += HTML.wrap(
|
135
|
+
html += HTML.wrap("ul", HTML.arrayToLI(sectionLinks), {
|
136
|
+
class: "listmenu",
|
137
|
+
});
|
116
138
|
|
117
139
|
html += "<table>";
|
118
140
|
html += "<thead>";
|
119
|
-
html += HTML.textElement(
|
120
|
-
html += HTML.textElement(
|
141
|
+
html += HTML.textElement("th", "Family");
|
142
|
+
html += HTML.textElement("th", "Number of Species", { class: "right" });
|
121
143
|
html += "</thead>";
|
122
144
|
|
123
145
|
html += "<tbody>";
|
124
|
-
const names = Object.keys(
|
125
|
-
for (
|
126
|
-
const family = this.#families[
|
146
|
+
const names = Object.keys(this.#families).sort();
|
147
|
+
for (const name of names) {
|
148
|
+
const family = this.#families[name];
|
127
149
|
const taxa = family.getTaxa();
|
128
|
-
if (
|
150
|
+
if (!taxa) {
|
129
151
|
continue;
|
130
152
|
}
|
131
|
-
let cols = HTML.wrap(
|
132
|
-
|
133
|
-
|
153
|
+
let cols = HTML.wrap(
|
154
|
+
"td",
|
155
|
+
HTML.getLink("./" + family.getFileName(), family.getName())
|
156
|
+
);
|
157
|
+
cols += HTML.wrap("td", taxa.length, { class: "right" });
|
158
|
+
html += HTML.wrap("tr", cols);
|
134
159
|
}
|
135
160
|
html += "</tbody>";
|
136
161
|
|
137
162
|
html += "</table>";
|
138
163
|
|
139
|
-
this.writeFile(
|
164
|
+
this.writeFile(html);
|
140
165
|
}
|
141
166
|
}
|
142
167
|
|
143
168
|
class PageFamily extends GenericPage {
|
144
|
-
|
145
169
|
#family;
|
146
170
|
|
147
|
-
|
148
|
-
|
171
|
+
/**
|
172
|
+
* @param {string} outputDir
|
173
|
+
* @param {Family} family
|
174
|
+
*/
|
175
|
+
constructor(outputDir, family) {
|
176
|
+
super(outputDir, family.getName(), family.getBaseFileName());
|
149
177
|
this.#family = family;
|
150
178
|
}
|
151
179
|
|
152
|
-
|
153
|
-
|
180
|
+
/**
|
181
|
+
*
|
182
|
+
* @param {import("./index.js").TaxaCol[]} columns
|
183
|
+
*/
|
184
|
+
render(columns) {
|
154
185
|
let html = this.getDefaultIntro();
|
155
186
|
|
156
187
|
html += HTML.wrap(
|
157
188
|
"div",
|
158
|
-
Jepson.getEFloraLink(
|
189
|
+
Jepson.getEFloraLink(this.#family.getJepsonID()),
|
159
190
|
{ class: "section" }
|
160
191
|
);
|
161
192
|
|
162
|
-
html += Taxa.getHTMLTable(
|
163
|
-
|
164
|
-
this.writeFile( html );
|
193
|
+
html += Taxa.getHTMLTable(this.#family.getTaxa(), columns);
|
165
194
|
|
195
|
+
this.writeFile(html);
|
166
196
|
}
|
167
197
|
}
|
168
198
|
|
169
199
|
class PageSection extends GenericPage {
|
170
|
-
|
171
200
|
#taxa;
|
172
201
|
|
173
|
-
|
174
|
-
|
202
|
+
/**
|
203
|
+
* @param {string} outputDir
|
204
|
+
* @param {string} name
|
205
|
+
* @param {Taxon[]} taxa
|
206
|
+
*/
|
207
|
+
constructor(outputDir, name, taxa) {
|
208
|
+
super(outputDir, name, name);
|
175
209
|
this.#taxa = taxa;
|
176
210
|
}
|
177
211
|
|
178
|
-
|
179
|
-
|
212
|
+
/**
|
213
|
+
* @param {import("./index.js").TaxaCol[]} columns
|
214
|
+
*/
|
215
|
+
render(columns) {
|
180
216
|
let html = this.getDefaultIntro();
|
181
217
|
|
182
|
-
html += Taxa.getHTMLTable(
|
183
|
-
|
184
|
-
this.writeFile( html );
|
218
|
+
html += Taxa.getHTMLTable(this.#taxa, columns);
|
185
219
|
|
220
|
+
this.writeFile(html);
|
186
221
|
}
|
187
222
|
}
|
188
223
|
|
189
224
|
class Sections {
|
190
|
-
|
225
|
+
/** @type {Object<string,Taxon[]} */
|
191
226
|
static #sections = {};
|
192
227
|
|
193
|
-
|
194
|
-
|
195
|
-
|
228
|
+
/**
|
229
|
+
* @param {string} name
|
230
|
+
* @param {Taxon} taxon
|
231
|
+
*/
|
232
|
+
static addTaxon(name, taxon) {
|
233
|
+
let section = this.#sections[name];
|
234
|
+
if (!section) {
|
196
235
|
section = [];
|
197
|
-
this.#sections[
|
236
|
+
this.#sections[name] = section;
|
198
237
|
}
|
199
|
-
section.push(
|
238
|
+
section.push(taxon);
|
200
239
|
}
|
201
240
|
|
202
241
|
static getSections() {
|
203
242
|
return this.#sections;
|
204
243
|
}
|
205
|
-
|
206
244
|
}
|
207
245
|
|
208
|
-
export { Families };
|
246
|
+
export { Families };
|
package/lib/files.js
CHANGED
@@ -3,91 +3,149 @@ import * as path from "node:path";
|
|
3
3
|
import { default as unzipper } from "unzipper";
|
4
4
|
|
5
5
|
class Files {
|
6
|
-
|
7
|
-
|
8
|
-
|
6
|
+
/**
|
7
|
+
* @param {string} srcDir
|
8
|
+
* @param {string} targetDir
|
9
|
+
*/
|
10
|
+
static copyDir(srcDir, targetDir) {
|
11
|
+
fs.cpSync(srcDir, targetDir, { recursive: true });
|
9
12
|
}
|
10
13
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
14
|
+
/**
|
15
|
+
* @param {string} fileName
|
16
|
+
* @param {*} inStream
|
17
|
+
* @access private
|
18
|
+
*/
|
19
|
+
static #createFileFromStream(fileName, inStream) {
|
20
|
+
/**
|
21
|
+
*
|
22
|
+
* @param {string} fileName
|
23
|
+
* @param {*} inStream
|
24
|
+
* @param {*} resolve
|
25
|
+
*/
|
26
|
+
function implementation(fileName, inStream, resolve) {
|
27
|
+
const outStream = fs.createWriteStream(fileName);
|
28
|
+
outStream.on("finish", () => {
|
29
|
+
resolve(true);
|
30
|
+
});
|
31
|
+
inStream.pipe(outStream);
|
17
32
|
}
|
18
33
|
|
19
|
-
return new Promise(
|
34
|
+
return new Promise((resolve) => {
|
35
|
+
implementation(fileName, inStream, resolve);
|
36
|
+
});
|
20
37
|
}
|
21
38
|
|
22
|
-
|
23
|
-
|
39
|
+
/**
|
40
|
+
* @param {string} path
|
41
|
+
* @returns {boolean}
|
42
|
+
*/
|
43
|
+
static exists(path) {
|
44
|
+
return fs.existsSync(path);
|
24
45
|
}
|
25
46
|
|
26
47
|
/**
|
27
48
|
* Retrieve data from a URL and write it to a file. If the response status is anything other than 200, an Error is thrown.
|
28
|
-
* @param {string|URL} url
|
49
|
+
* @param {string|URL} url
|
29
50
|
* @param {string|undefined} targetFileName If targetFileName is undefined, the data will be retrieved but not written to a file.
|
30
51
|
* @param {Object} [headers={}] Request Headers.
|
31
52
|
* @returns {Promise<Headers>} The Response headers.
|
32
53
|
*/
|
33
|
-
static async fetch(
|
34
|
-
const response = await fetch(
|
35
|
-
if (
|
36
|
-
throw new Error(
|
54
|
+
static async fetch(url, targetFileName, headers = {}) {
|
55
|
+
const response = await fetch(url, headers);
|
56
|
+
if (response.status !== 200) {
|
57
|
+
throw new Error(response.status + " retrieving " + url);
|
37
58
|
}
|
38
59
|
const data = await response.blob();
|
39
60
|
const arrayBuffer = await data.arrayBuffer();
|
40
|
-
const buffer = Buffer.from(
|
41
|
-
if (
|
42
|
-
fs.writeFileSync(
|
61
|
+
const buffer = Buffer.from(arrayBuffer);
|
62
|
+
if (targetFileName) {
|
63
|
+
fs.writeFileSync(targetFileName, buffer);
|
43
64
|
}
|
44
65
|
return response.headers;
|
45
66
|
}
|
46
67
|
|
47
|
-
|
48
|
-
|
68
|
+
/**
|
69
|
+
* @param {string} path
|
70
|
+
* @returns {string[]}
|
71
|
+
*/
|
72
|
+
static getDirEntries(path) {
|
73
|
+
return fs.readdirSync(path);
|
49
74
|
}
|
50
75
|
|
51
|
-
|
52
|
-
|
76
|
+
/**
|
77
|
+
* @param {string} path
|
78
|
+
* @returns {boolean}
|
79
|
+
*/
|
80
|
+
static isDir(path) {
|
81
|
+
const stats = fs.statSync(path, { throwIfNoEntry: false });
|
53
82
|
return stats !== undefined && stats.isDirectory();
|
54
83
|
}
|
55
84
|
|
56
|
-
|
57
|
-
|
85
|
+
/**
|
86
|
+
* @param {string[]} paths
|
87
|
+
* @returns {string}
|
88
|
+
*/
|
89
|
+
static join(...paths) {
|
90
|
+
return path.join(...paths).replaceAll("\\", "/");
|
58
91
|
}
|
59
92
|
|
60
|
-
|
61
|
-
|
93
|
+
/**
|
94
|
+
* @param {string} path
|
95
|
+
*/
|
96
|
+
static mkdir(path) {
|
97
|
+
fs.mkdirSync(path, { recursive: true });
|
62
98
|
}
|
63
99
|
|
64
|
-
|
65
|
-
|
100
|
+
/**
|
101
|
+
* @param {string} path
|
102
|
+
* @returns {string}
|
103
|
+
*/
|
104
|
+
static read(path) {
|
105
|
+
return fs.readFileSync(path, "utf8");
|
66
106
|
}
|
67
107
|
|
68
|
-
|
69
|
-
|
108
|
+
/**
|
109
|
+
* @param {string} dir
|
110
|
+
*/
|
111
|
+
static rmDir(dir) {
|
112
|
+
fs.rmSync(dir, {
|
113
|
+
force: true,
|
114
|
+
recursive: true,
|
115
|
+
maxRetries: 2,
|
116
|
+
retryDelay: 1000,
|
117
|
+
});
|
70
118
|
}
|
71
119
|
|
72
|
-
|
73
|
-
|
74
|
-
|
120
|
+
/**
|
121
|
+
* @param {string} path
|
122
|
+
* @param {string} data
|
123
|
+
* @param {boolean} overwrite
|
124
|
+
*/
|
125
|
+
static write(path, data, overwrite = false) {
|
126
|
+
if (!overwrite && this.exists(path)) {
|
127
|
+
throw new Error(path + " already exists");
|
75
128
|
}
|
76
|
-
fs.writeFileSync(
|
129
|
+
fs.writeFileSync(path, data);
|
77
130
|
}
|
78
131
|
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
132
|
+
/**
|
133
|
+
* @param {string} zipFilePath
|
134
|
+
* @param {string} fileNameToUnzip
|
135
|
+
* @param {string} targetFilePath
|
136
|
+
*/
|
137
|
+
static async zipFileExtract(zipFilePath, fileNameToUnzip, targetFilePath) {
|
138
|
+
const zipDir = await unzipper.Open.file(zipFilePath);
|
139
|
+
for (const entry of zipDir.files) {
|
140
|
+
if (entry.path === fileNameToUnzip) {
|
141
|
+
await this.#createFileFromStream(
|
142
|
+
targetFilePath,
|
143
|
+
entry.stream()
|
144
|
+
);
|
85
145
|
break;
|
86
146
|
}
|
87
147
|
}
|
88
|
-
|
89
148
|
}
|
90
|
-
|
91
149
|
}
|
92
150
|
|
93
|
-
export { Files };
|
151
|
+
export { Files };
|
package/lib/generictaxaloader.js
CHANGED
@@ -1,16 +1,22 @@
|
|
1
|
-
import { ErrorLog } from "./
|
1
|
+
import { ErrorLog } from "./index.js";
|
2
2
|
|
3
3
|
class GenericTaxaLoader {
|
4
|
-
|
5
4
|
#options;
|
6
5
|
#errorLog;
|
6
|
+
/** @type {import("./index.js").Taxa|undefined}*/
|
7
7
|
#taxa;
|
8
8
|
|
9
|
-
|
9
|
+
/**
|
10
|
+
* @param {*} options
|
11
|
+
*/
|
12
|
+
constructor(options) {
|
10
13
|
this.#options = options;
|
11
|
-
this.#errorLog = new ErrorLog(
|
14
|
+
this.#errorLog = new ErrorLog(options.outputdir + "/errors.tsv");
|
12
15
|
}
|
13
16
|
|
17
|
+
/**
|
18
|
+
* @returns {ErrorLog}
|
19
|
+
*/
|
14
20
|
getErrorLog() {
|
15
21
|
return this.#errorLog;
|
16
22
|
}
|
@@ -27,14 +33,16 @@ class GenericTaxaLoader {
|
|
27
33
|
this.#taxa = await this.loadTaxa();
|
28
34
|
}
|
29
35
|
|
36
|
+
/**
|
37
|
+
* @return {Promise<import("./index.js").Taxa>}
|
38
|
+
*/
|
30
39
|
async loadTaxa() {
|
31
|
-
throw new Error(
|
40
|
+
throw new Error("must be implemented by subclass");
|
32
41
|
}
|
33
42
|
|
34
43
|
writeErrorLog() {
|
35
44
|
this.#errorLog.write();
|
36
45
|
}
|
37
|
-
|
38
46
|
}
|
39
47
|
|
40
|
-
export { GenericTaxaLoader };
|
48
|
+
export { GenericTaxaLoader };
|
package/lib/index.js
CHANGED
@@ -1,3 +1,22 @@
|
|
1
|
+
/**
|
2
|
+
* @typedef {{
|
3
|
+
* bloom_end:string;
|
4
|
+
* bloom_start:string;
|
5
|
+
* calrecnum:string;
|
6
|
+
* CESA:string;
|
7
|
+
* CRPR:string;
|
8
|
+
* common_name:string;
|
9
|
+
* FESA:string;
|
10
|
+
* flower_color:string;
|
11
|
+
* GRank:string;
|
12
|
+
* "inat id":string;
|
13
|
+
* "jepson id":string;
|
14
|
+
* SRank:string;
|
15
|
+
* status:string;
|
16
|
+
* "RPI ID":string;
|
17
|
+
* taxon_name:string}} TaxonData
|
18
|
+
*/
|
19
|
+
|
1
20
|
import { BasePageRenderer } from "./basepagerenderer.js";
|
2
21
|
import { CommandProcessor } from "./commandprocessor.js";
|
3
22
|
import { CommandAndTaxaProcessor } from "./commandandtaxaprocessor.js";
|
@@ -17,6 +36,22 @@ import { TaxaProcessor } from "./taxaprocessor.js";
|
|
17
36
|
import { Taxon, TAXA_COLNAMES } from "./taxon.js";
|
18
37
|
|
19
38
|
export {
|
20
|
-
BasePageRenderer,
|
21
|
-
|
22
|
-
|
39
|
+
BasePageRenderer,
|
40
|
+
CommandProcessor,
|
41
|
+
CommandAndTaxaProcessor,
|
42
|
+
Config,
|
43
|
+
CSV,
|
44
|
+
ErrorLog,
|
45
|
+
Exceptions,
|
46
|
+
Families,
|
47
|
+
Files,
|
48
|
+
GenericTaxaLoader,
|
49
|
+
HTML,
|
50
|
+
Jekyll,
|
51
|
+
PlantBook,
|
52
|
+
Taxa,
|
53
|
+
TaxaLoader,
|
54
|
+
TaxaProcessor,
|
55
|
+
TAXA_COLNAMES,
|
56
|
+
Taxon,
|
57
|
+
};
|