@ca-plant-list/ca-plant-list 0.4.10 → 0.4.12
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/data/exceptions.json +16 -1
- package/data/inattaxonphotos.csv +27 -0
- package/data/synonyms.csv +7 -0
- package/data/taxa.csv +1364 -1361
- package/data/text/Asclepias-californica.md +1 -0
- package/data/text/Asclepias-cordifolia.md +1 -0
- package/data/text/Asclepias-eriocarpa.md +1 -0
- package/data/text/Asclepias-speciosa.md +1 -0
- package/data/text/Calystegia-malacophylla-subsp-pedicellata.md +1 -0
- package/data/text/Calystegia-purpurata-subsp-purpurata.md +1 -0
- package/data/text/Calystegia-sepium-subsp-limnophila.md +1 -0
- package/data/text/Calystegia-silvatica-subsp-disjuncta.md +1 -0
- package/data/text/Ribes-aureum-var-gracillimum.md +1 -0
- package/data/text/Ribes-californicum-var-californicum.md +1 -0
- package/data/text/Ribes-divaricatum-var-pubiflorum.md +1 -0
- package/data/text/Ribes-malvaceum-var-malvaceum.md +1 -0
- package/data/text/Ribes-menziesii-var-menziesii.md +1 -0
- package/data/text/Ribes-quercetorum.md +1 -0
- package/data/text/Ribes-sanguineum-var-glutinosum.md +1 -0
- package/data/text/Ribes-speciosum.md +1 -0
- package/data/text/Toxicoscordion-fremontii.md +1 -1
- package/data/text/Toxicoscordion-paniculatum.md +1 -1
- package/data/text/Toxicoscordion-venenosum-var-venenosum.md +1 -1
- package/data/text/Viola-purpurea-subsp-purpurea.md +1 -0
- package/data/text/Viola-purpurea-subsp-quercetorum.md +1 -1
- package/lib/csv.js +37 -1
- package/lib/exceptions.js +2 -2
- package/lib/htmltaxon.js +17 -0
- package/lib/taxa.js +8 -2
- package/lib/taxon.js +24 -6
- package/lib/tools/calflora.js +220 -0
- package/lib/tools/calscape.js +214 -0
- package/lib/tools/taxacsv.js +31 -0
- package/lib/web/pagetaxon.js +5 -1
- package/package.json +4 -3
- package/schemas/exceptions.schema.json +6 -1
- package/scripts/cpl-photos.js +5 -1
- package/scripts/cpl-tools.js +177 -0
- package/types/classes.d.ts +6 -0
@@ -0,0 +1,214 @@
|
|
1
|
+
import path from "node:path";
|
2
|
+
import xlsx from "exceljs";
|
3
|
+
import { Files } from "../files.js";
|
4
|
+
import { TaxaCSV } from "./taxacsv.js";
|
5
|
+
import { Taxon } from "../taxon.js";
|
6
|
+
|
7
|
+
export class Calscape {
|
8
|
+
/**
|
9
|
+
* @param {string} toolsDataDir
|
10
|
+
* @param {string} dataDir
|
11
|
+
* @param {Taxa} taxa
|
12
|
+
* @param {import("../exceptions.js").Exceptions} exceptions
|
13
|
+
* @param {ErrorLog} errorLog
|
14
|
+
* @param {boolean} update
|
15
|
+
*/
|
16
|
+
static async analyze(
|
17
|
+
toolsDataDir,
|
18
|
+
dataDir,
|
19
|
+
taxa,
|
20
|
+
exceptions,
|
21
|
+
errorLog,
|
22
|
+
update,
|
23
|
+
) {
|
24
|
+
const calscapeData = await getCalscapeData(toolsDataDir);
|
25
|
+
|
26
|
+
for (const taxon of taxa.getTaxonList()) {
|
27
|
+
const taxonName = taxon.getName();
|
28
|
+
const taxonCN = taxon.getCalscapeCommonName();
|
29
|
+
const calscapeCN = getCalscapeCommonName(
|
30
|
+
taxonName,
|
31
|
+
calscapeData,
|
32
|
+
exceptions,
|
33
|
+
);
|
34
|
+
|
35
|
+
if (taxonCN !== calscapeCN) {
|
36
|
+
errorLog.log(
|
37
|
+
taxonName,
|
38
|
+
"name in Calscape data is different than taxa.csv",
|
39
|
+
calscapeCN ?? "undefined",
|
40
|
+
taxonCN ?? "undefined",
|
41
|
+
);
|
42
|
+
}
|
43
|
+
// Calscape should only have natives, so make sure it's recorded as native.
|
44
|
+
if (calscapeCN && !taxon.isCANative()) {
|
45
|
+
errorLog.log(
|
46
|
+
taxonName,
|
47
|
+
"is in Calscape but not native in taxa.csv",
|
48
|
+
);
|
49
|
+
}
|
50
|
+
}
|
51
|
+
|
52
|
+
checkExceptions(taxa, exceptions, errorLog);
|
53
|
+
|
54
|
+
if (update) {
|
55
|
+
updateTaxaCSV(dataDir, calscapeData, exceptions);
|
56
|
+
}
|
57
|
+
}
|
58
|
+
}
|
59
|
+
|
60
|
+
/**
|
61
|
+
* @param {Taxa} taxa
|
62
|
+
* @param {import("../exceptions.js").Exceptions} exceptions
|
63
|
+
* @param {ErrorLog} errorLog
|
64
|
+
*/
|
65
|
+
function checkExceptions(taxa, exceptions, errorLog) {
|
66
|
+
// Check the Calscape exceptions and make sure they still apply.
|
67
|
+
for (const [name, v] of exceptions.getExceptions()) {
|
68
|
+
const exceptions = v.calscape;
|
69
|
+
if (!exceptions) {
|
70
|
+
continue;
|
71
|
+
}
|
72
|
+
|
73
|
+
// Make sure the taxon is still in our list.
|
74
|
+
const taxon = taxa.getTaxon(name);
|
75
|
+
if (!taxon) {
|
76
|
+
// Don't process global exceptions if taxon is not in local list.
|
77
|
+
if (taxa.isSubset() && !v.local) {
|
78
|
+
continue;
|
79
|
+
}
|
80
|
+
errorLog.log(
|
81
|
+
name,
|
82
|
+
"has Calscape exceptions but not in Taxa collection",
|
83
|
+
);
|
84
|
+
continue;
|
85
|
+
}
|
86
|
+
|
87
|
+
for (const [k] of Object.entries(exceptions)) {
|
88
|
+
switch (k) {
|
89
|
+
case "notnative": {
|
90
|
+
if (taxon.isCANative()) {
|
91
|
+
errorLog.log(
|
92
|
+
name,
|
93
|
+
"has Calscape notnative exception but is native in taxa.csv",
|
94
|
+
);
|
95
|
+
}
|
96
|
+
break;
|
97
|
+
}
|
98
|
+
default:
|
99
|
+
errorLog.log(name, "unrecognized Calscape exception", k);
|
100
|
+
}
|
101
|
+
}
|
102
|
+
}
|
103
|
+
}
|
104
|
+
|
105
|
+
/**
|
106
|
+
* @param {string} taxonName
|
107
|
+
* @param {Map<string,string>} calscapeData
|
108
|
+
* @param {import("../exceptions.js").Exceptions} exceptions
|
109
|
+
* @returns {string|undefined}
|
110
|
+
*/
|
111
|
+
function getCalscapeCommonName(taxonName, calscapeData, exceptions) {
|
112
|
+
const calscapeCN = calscapeData.get(Taxon.getCalscapeName(taxonName));
|
113
|
+
if (
|
114
|
+
calscapeCN &&
|
115
|
+
exceptions.hasException(taxonName, "calscape", "notnative")
|
116
|
+
) {
|
117
|
+
return;
|
118
|
+
}
|
119
|
+
return calscapeCN;
|
120
|
+
}
|
121
|
+
|
122
|
+
/**
|
123
|
+
* @param {string} toolsDataDir
|
124
|
+
* @returns {Promise<Map<string,string>>}
|
125
|
+
*/
|
126
|
+
async function getCalscapeData(toolsDataDir) {
|
127
|
+
/**
|
128
|
+
* @param {import("exceljs").Cell} cell
|
129
|
+
*/
|
130
|
+
function getCellValue(cell) {
|
131
|
+
const value = cell.value;
|
132
|
+
if (value === null || value === undefined) {
|
133
|
+
return undefined;
|
134
|
+
}
|
135
|
+
return value.toString();
|
136
|
+
}
|
137
|
+
|
138
|
+
toolsDataDir = path.join(toolsDataDir, "calscape");
|
139
|
+
Files.mkdir(toolsDataDir);
|
140
|
+
await retrieveCalscapeFile(toolsDataDir);
|
141
|
+
|
142
|
+
/** @type {Map<string,string>} */
|
143
|
+
const data = new Map();
|
144
|
+
|
145
|
+
const wb = new xlsx.Workbook();
|
146
|
+
await wb.xlsx.readFile(getExcelFilename(toolsDataDir)).then(function () {
|
147
|
+
const ws = wb.worksheets[0];
|
148
|
+
let isInData = false;
|
149
|
+
for (let index = 0; index < ws.rowCount; index++) {
|
150
|
+
const row = ws.getRow(index);
|
151
|
+
const col1 = getCellValue(row.getCell(1));
|
152
|
+
if (!isInData) {
|
153
|
+
if (col1 === "Botanical Name") {
|
154
|
+
isInData = true;
|
155
|
+
}
|
156
|
+
continue;
|
157
|
+
}
|
158
|
+
const col2 = getCellValue(row.getCell(2));
|
159
|
+
if (!col1 || !col2) {
|
160
|
+
continue;
|
161
|
+
}
|
162
|
+
data.set(col1, col2);
|
163
|
+
}
|
164
|
+
});
|
165
|
+
|
166
|
+
return data;
|
167
|
+
}
|
168
|
+
|
169
|
+
/**
|
170
|
+
* @param {string} toolsDataDir
|
171
|
+
*/
|
172
|
+
function getExcelFilename(toolsDataDir) {
|
173
|
+
return path.join(toolsDataDir, "calscape.xlsx");
|
174
|
+
}
|
175
|
+
|
176
|
+
/**
|
177
|
+
* @param {string} toolsDataDir
|
178
|
+
*/
|
179
|
+
async function retrieveCalscapeFile(toolsDataDir) {
|
180
|
+
// Retrieve file if it's not there.
|
181
|
+
const targetFile = getExcelFilename(toolsDataDir);
|
182
|
+
if (Files.exists(targetFile)) {
|
183
|
+
return;
|
184
|
+
}
|
185
|
+
console.info("retrieving " + targetFile);
|
186
|
+
await Files.fetch("https://www.calscape.org/export/search/", targetFile);
|
187
|
+
}
|
188
|
+
|
189
|
+
/**
|
190
|
+
* @param {string} dataDir
|
191
|
+
* @param {Map<string,string>} calscapeData
|
192
|
+
* @param {import("../exceptions.js").Exceptions} exceptions
|
193
|
+
*/
|
194
|
+
function updateTaxaCSV(dataDir, calscapeData, exceptions) {
|
195
|
+
const taxa = new TaxaCSV(dataDir);
|
196
|
+
|
197
|
+
for (const taxonData of taxa.getTaxa()) {
|
198
|
+
const taxonCN = taxonData.calscape_cn;
|
199
|
+
const calscapeCN = getCalscapeCommonName(
|
200
|
+
taxonData.taxon_name,
|
201
|
+
calscapeData,
|
202
|
+
exceptions,
|
203
|
+
);
|
204
|
+
if (taxonCN !== calscapeCN) {
|
205
|
+
if (calscapeCN === undefined) {
|
206
|
+
delete taxonData.calscape_cn;
|
207
|
+
} else {
|
208
|
+
taxonData.calscape_cn = calscapeCN;
|
209
|
+
}
|
210
|
+
}
|
211
|
+
}
|
212
|
+
|
213
|
+
taxa.write();
|
214
|
+
}
|
@@ -0,0 +1,31 @@
|
|
1
|
+
import path from "path";
|
2
|
+
import { CSV } from "../csv.js";
|
3
|
+
|
4
|
+
export class TaxaCSV {
|
5
|
+
#filePath;
|
6
|
+
#headers;
|
7
|
+
/** @type {TaxonData[]} */
|
8
|
+
#taxa;
|
9
|
+
|
10
|
+
/**
|
11
|
+
* @param {string} dataDir
|
12
|
+
*/
|
13
|
+
constructor(dataDir) {
|
14
|
+
this.#filePath = path.join(dataDir, "taxa.csv");
|
15
|
+
const csv = CSV.readFileAndHeaders(this.#filePath);
|
16
|
+
// @ts-ignore
|
17
|
+
this.#taxa = csv.data;
|
18
|
+
this.#headers = csv.headers;
|
19
|
+
}
|
20
|
+
|
21
|
+
/**
|
22
|
+
* @returns {TaxonData[]}
|
23
|
+
*/
|
24
|
+
getTaxa() {
|
25
|
+
return this.#taxa;
|
26
|
+
}
|
27
|
+
|
28
|
+
write() {
|
29
|
+
CSV.writeFileObject(this.#filePath, this.#taxa, this.#headers);
|
30
|
+
}
|
31
|
+
}
|
package/lib/web/pagetaxon.js
CHANGED
@@ -36,6 +36,10 @@ class PageTaxon extends GenericPage {
|
|
36
36
|
if (iNatLink) {
|
37
37
|
links.push(iNatLink);
|
38
38
|
}
|
39
|
+
const calscapeLink = HTMLTaxon.getCalscapeLink(this.#taxon);
|
40
|
+
if (calscapeLink) {
|
41
|
+
links.push(calscapeLink);
|
42
|
+
}
|
39
43
|
const rpiLink = this.#taxon.getRPITaxonLink();
|
40
44
|
if (rpiLink) {
|
41
45
|
links.push(rpiLink);
|
@@ -120,7 +124,7 @@ class PageTaxon extends GenericPage {
|
|
120
124
|
}
|
121
125
|
|
122
126
|
return HTML.wrap("div", "<ul>" + HTML.arrayToLI(ranks) + "</ul>", {
|
123
|
-
class: "section",
|
127
|
+
class: "section nobullet",
|
124
128
|
});
|
125
129
|
}
|
126
130
|
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@ca-plant-list/ca-plant-list",
|
3
|
-
"version": "0.4.
|
3
|
+
"version": "0.4.12",
|
4
4
|
"description": "Tools to create Jekyll files for a website listing plants in an area of California.",
|
5
5
|
"license": "MIT",
|
6
6
|
"repository": {
|
@@ -16,7 +16,8 @@
|
|
16
16
|
"bin": {
|
17
17
|
"ca-plant-list": "scripts/build-site.js",
|
18
18
|
"ca-plant-book": "scripts/build-ebook.js",
|
19
|
-
"cpl-photos": "scripts/cpl-photos.js"
|
19
|
+
"cpl-photos": "scripts/cpl-photos.js",
|
20
|
+
"cpl-tools": "scripts/cpl-tools.js"
|
20
21
|
},
|
21
22
|
"dependencies": {
|
22
23
|
"archiver": "^5.3.1",
|
@@ -36,8 +37,8 @@
|
|
36
37
|
"@types/markdown-it": "^14.1.2",
|
37
38
|
"@types/node": "^22.7.8",
|
38
39
|
"@types/unzipper": "^0.10.9",
|
39
|
-
"ajv-cli": "^5.0.0",
|
40
40
|
"eslint": "^9.13.0",
|
41
|
+
"exceljs": "^4.4.0",
|
41
42
|
"prettier": "^3.3.3",
|
42
43
|
"typescript": "^5.6.3"
|
43
44
|
}
|
@@ -9,12 +9,17 @@
|
|
9
9
|
"badjepsonid": {
|
10
10
|
"const": true
|
11
11
|
},
|
12
|
+
"native": { "type": "boolean" },
|
12
13
|
"notintaxondata": {
|
13
14
|
"const": true
|
14
15
|
}
|
15
16
|
},
|
16
17
|
"additionalProperties": false
|
17
18
|
},
|
19
|
+
"calscape": {
|
20
|
+
"type": "object",
|
21
|
+
"properties": { "notnative": { "const": true } }
|
22
|
+
},
|
18
23
|
"comment": {
|
19
24
|
"type": "string"
|
20
25
|
},
|
@@ -54,4 +59,4 @@
|
|
54
59
|
},
|
55
60
|
"additionalProperties": false
|
56
61
|
}
|
57
|
-
}
|
62
|
+
}
|
package/scripts/cpl-photos.js
CHANGED
@@ -0,0 +1,177 @@
|
|
1
|
+
#!/usr/bin/env node
|
2
|
+
|
3
|
+
import * as path from "node:path";
|
4
|
+
import { Option } from "commander";
|
5
|
+
import { Taxa } from "../lib/taxa.js";
|
6
|
+
import { Program } from "../lib/program.js";
|
7
|
+
import { Calflora } from "../lib/tools/calflora.js";
|
8
|
+
import { Exceptions } from "../lib/exceptions.js";
|
9
|
+
import { ErrorLog } from "../lib/errorlog.js";
|
10
|
+
import { Calscape } from "../lib/tools/calscape.js";
|
11
|
+
|
12
|
+
const TOOLS = {
|
13
|
+
CALFLORA: "calflora",
|
14
|
+
CALSCAPE: "calscape",
|
15
|
+
INAT: "inat",
|
16
|
+
JEPSON_EFLORA: "jepson-eflora",
|
17
|
+
JEPSON_FAM: "jepson-families",
|
18
|
+
RPI: "rpi",
|
19
|
+
TEXT: "text",
|
20
|
+
};
|
21
|
+
|
22
|
+
const ALL_TOOLS = [
|
23
|
+
TOOLS.CALFLORA,
|
24
|
+
TOOLS.CALSCAPE,
|
25
|
+
TOOLS.INAT,
|
26
|
+
TOOLS.JEPSON_EFLORA,
|
27
|
+
TOOLS.RPI,
|
28
|
+
TOOLS.TEXT,
|
29
|
+
];
|
30
|
+
|
31
|
+
const OPT_LOADER = "loader";
|
32
|
+
const OPT_TOOL = "tool";
|
33
|
+
|
34
|
+
const TOOLS_DATA_DIR = "./external_data";
|
35
|
+
|
36
|
+
/**
|
37
|
+
* @param {import("commander").Command} program
|
38
|
+
* @param {import("commander").OptionValues} options
|
39
|
+
*/
|
40
|
+
async function build(program, options) {
|
41
|
+
let tools = options[OPT_TOOL];
|
42
|
+
if (!tools) {
|
43
|
+
program.help();
|
44
|
+
}
|
45
|
+
if (tools[0] === "all") {
|
46
|
+
tools = ALL_TOOLS;
|
47
|
+
}
|
48
|
+
|
49
|
+
const exceptions = new Exceptions(options.datadir);
|
50
|
+
// const config = new Config(options.datadir);
|
51
|
+
const taxa = await getTaxa(options);
|
52
|
+
|
53
|
+
const errorLog = new ErrorLog(options.outputdir + "/log.tsv", true);
|
54
|
+
for (const tool of tools) {
|
55
|
+
switch (tool) {
|
56
|
+
case TOOLS.CALFLORA:
|
57
|
+
await Calflora.analyze(
|
58
|
+
TOOLS_DATA_DIR,
|
59
|
+
taxa,
|
60
|
+
exceptions,
|
61
|
+
errorLog,
|
62
|
+
);
|
63
|
+
break;
|
64
|
+
case TOOLS.CALSCAPE:
|
65
|
+
await Calscape.analyze(
|
66
|
+
TOOLS_DATA_DIR,
|
67
|
+
options.datadir,
|
68
|
+
taxa,
|
69
|
+
exceptions,
|
70
|
+
errorLog,
|
71
|
+
!!options.update,
|
72
|
+
);
|
73
|
+
break;
|
74
|
+
case TOOLS.INAT:
|
75
|
+
// await INat.analyze(
|
76
|
+
// TOOLS_DATA_DIR,
|
77
|
+
// taxa,
|
78
|
+
// exceptions,
|
79
|
+
// errorLog,
|
80
|
+
// options.inTaxafile,
|
81
|
+
// );
|
82
|
+
break;
|
83
|
+
case TOOLS.JEPSON_EFLORA: {
|
84
|
+
// const eflora = new JepsonEFlora(
|
85
|
+
// TOOLS_DATA_DIR,
|
86
|
+
// taxa,
|
87
|
+
// errorLog,
|
88
|
+
// options.efLognotes,
|
89
|
+
// );
|
90
|
+
// await eflora.analyze(exceptions);
|
91
|
+
break;
|
92
|
+
}
|
93
|
+
case TOOLS.JEPSON_FAM:
|
94
|
+
// await JepsonFamilies.build(TOOLS_DATA_DIR, options.outputdir);
|
95
|
+
break;
|
96
|
+
case TOOLS.RPI:
|
97
|
+
// await RPI.analyze(
|
98
|
+
// TOOLS_DATA_DIR,
|
99
|
+
// taxa,
|
100
|
+
// config,
|
101
|
+
// exceptions,
|
102
|
+
// errorLog,
|
103
|
+
// );
|
104
|
+
break;
|
105
|
+
case TOOLS.TEXT:
|
106
|
+
// SupplementalText.analyze(taxa, errorLog);
|
107
|
+
break;
|
108
|
+
default:
|
109
|
+
console.log("unrecognized tool: " + tool);
|
110
|
+
return;
|
111
|
+
}
|
112
|
+
}
|
113
|
+
|
114
|
+
errorLog.write();
|
115
|
+
}
|
116
|
+
|
117
|
+
/**
|
118
|
+
* @param {import("commander").OptionValues} options
|
119
|
+
*/
|
120
|
+
async function getTaxa(options) {
|
121
|
+
const errorLog = new ErrorLog(options.outputdir + "/errors.tsv", true);
|
122
|
+
|
123
|
+
const loader = options[OPT_LOADER];
|
124
|
+
let taxa;
|
125
|
+
if (loader) {
|
126
|
+
const taxaLoaderClass = await import("file:" + path.resolve(loader));
|
127
|
+
taxa = await taxaLoaderClass.TaxaLoader.loadTaxa(options, errorLog);
|
128
|
+
} else {
|
129
|
+
taxa = new Taxa(
|
130
|
+
Program.getIncludeList(options.datadir),
|
131
|
+
errorLog,
|
132
|
+
options.showFlowerErrors,
|
133
|
+
);
|
134
|
+
}
|
135
|
+
|
136
|
+
errorLog.write();
|
137
|
+
return taxa;
|
138
|
+
}
|
139
|
+
|
140
|
+
const program = Program.getProgram();
|
141
|
+
program.addOption(
|
142
|
+
new Option(
|
143
|
+
"-t, --tool <tool...>",
|
144
|
+
"The tools to run. Value may be any subset of the tools below.",
|
145
|
+
).choices(["all"].concat(ALL_TOOLS).concat(TOOLS.JEPSON_FAM)),
|
146
|
+
);
|
147
|
+
program.option(
|
148
|
+
"--in-taxafile <file>",
|
149
|
+
"The name of the file containing the iNaturalist taxa. Can be used for testing on a smaller subset of the iNaturalist data.",
|
150
|
+
"inat_taxa.csv",
|
151
|
+
);
|
152
|
+
program.option(
|
153
|
+
"--ef-lognotes",
|
154
|
+
"When running the jepson-eflora tool, include eFlora notes, invalid names, etc. in the log file.",
|
155
|
+
);
|
156
|
+
program.option(
|
157
|
+
"--loader <path>",
|
158
|
+
"The path (relative to the current directory) of the JavaScript file containing the TaxaLoader class. If not provided, the default TaxaLoader will be used.",
|
159
|
+
);
|
160
|
+
program.option("--update", "Update taxa.csv to remove errors if possible.");
|
161
|
+
program.addHelpText(
|
162
|
+
"after",
|
163
|
+
`
|
164
|
+
Tools:
|
165
|
+
'all' runs the 'calflora', 'inat', 'jepson-eflora', 'rpi', and 'text' tools.
|
166
|
+
'${TOOLS.CALFLORA}' retrieves data from Calflora and compares with local data.
|
167
|
+
'${TOOLS.CALSCAPE}' retrieves data from Calscape and compares with local data.
|
168
|
+
'${TOOLS.INAT}' retrieves data from iNaturalist and compares with local data.
|
169
|
+
'${TOOLS.JEPSON_EFLORA}' retrieves data from Jepson eFlora indexes and compares with local data.
|
170
|
+
'${TOOLS.JEPSON_FAM}' retrieves section, family and genus data from Jepson eFlora and creates data files for use by ca-plant-list.
|
171
|
+
'${TOOLS.RPI}' retrieves data from the CNPS Rare Plant Inventory and compares with local data.
|
172
|
+
'${TOOLS.TEXT}' checks supplemental text files to make sure their names are referenced.
|
173
|
+
`,
|
174
|
+
);
|
175
|
+
program.action((options) => build(program, options));
|
176
|
+
|
177
|
+
await program.parseAsync();
|
package/types/classes.d.ts
CHANGED
@@ -83,6 +83,7 @@ declare class Taxa {
|
|
83
83
|
getFlowerColors(): FlowerColor[];
|
84
84
|
getTaxon(name: string): Taxon;
|
85
85
|
getTaxonList(): Taxon[];
|
86
|
+
isSubset(): boolean;
|
86
87
|
}
|
87
88
|
|
88
89
|
declare class TaxaCol {
|
@@ -96,8 +97,11 @@ declare class Taxon {
|
|
96
97
|
getBaseFileName(): string;
|
97
98
|
getBloomEnd(): number | undefined;
|
98
99
|
getBloomStart(): number | undefined;
|
100
|
+
getCalfloraID(): string;
|
99
101
|
getCalfloraName(): string;
|
100
102
|
getCalfloraTaxonLink(): string | undefined;
|
103
|
+
getCalscapeCommonName(): string | undefined;
|
104
|
+
getCalscapeName(): string;
|
101
105
|
getCESA(): string | undefined;
|
102
106
|
getCommonNames(): string[];
|
103
107
|
getFamily(): Family;
|
@@ -123,6 +127,7 @@ declare class Taxon {
|
|
123
127
|
getRPITaxonLink(): string;
|
124
128
|
getStatusDescription(config: Config): string;
|
125
129
|
getSynonyms(): string[];
|
130
|
+
isCANative(): boolean;
|
126
131
|
isNative(): boolean;
|
127
132
|
}
|
128
133
|
|
@@ -130,6 +135,7 @@ declare class TaxonData {
|
|
130
135
|
bloom_end: string;
|
131
136
|
bloom_start: string;
|
132
137
|
calrecnum: string;
|
138
|
+
calscape_cn?: string;
|
133
139
|
CESA: string;
|
134
140
|
"common name": string;
|
135
141
|
CRPR: string;
|