@ca-plant-list/ca-plant-list 0.4.22 → 0.4.23
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/lib/basepagerenderer.js +10 -4
- package/lib/ebook/images.js +3 -3
- package/lib/ebook/pages/{page_list_families.js → pageListFamilies.js} +1 -1
- package/lib/ebook/pages/{page_list_flowers.js → pageListFlowers.js} +2 -2
- package/lib/ebook/pages/page_list_species.js +1 -1
- package/lib/ebook/pages/taxonpage.js +1 -1
- package/lib/ebook/pages/tocpage.js +2 -2
- package/lib/ebook/plantbook.js +3 -3
- package/lib/externalsites.js +86 -37
- package/lib/flowercolor.js +2 -2
- package/lib/genera.js +4 -4
- package/lib/html.js +7 -8
- package/lib/htmltaxon.js +106 -27
- package/lib/index.d.ts +51 -16
- package/lib/index.js +3 -3
- package/lib/pagerenderer.js +6 -6
- package/lib/taxonomy/families.js +104 -0
- package/lib/{taxa.js → taxonomy/taxa.js} +18 -18
- package/lib/{taxon.js → taxonomy/taxon.js} +9 -108
- package/lib/taxonomy/taxonomy.js +17 -0
- package/lib/tools/calflora.js +2 -2
- package/lib/tools/calscape.js +3 -3
- package/lib/tools/cch2.js +3 -3
- package/lib/tools/fna.js +2 -2
- package/lib/tools/inat.js +3 -3
- package/lib/tools/jepsoneflora.js +1 -1
- package/lib/tools/rpi.js +3 -3
- package/lib/tools/supplementaltext.js +1 -1
- package/lib/types.js +10 -0
- package/lib/utils/inat-tools.js +2 -2
- package/lib/web/pageFamily.js +146 -0
- package/lib/web/pagetaxon.js +20 -56
- package/package.json +1 -1
- package/scripts/build-ebook.js +4 -4
- package/scripts/build-site.js +3 -3
- package/scripts/cpl-photos.js +1 -1
- package/scripts/cpl-tools.js +1 -1
- package/scripts/inatobsphotos.js +2 -2
- package/scripts/inattaxonphotos.js +2 -2
- package/lib/families.js +0 -243
- package/lib/jepson.js +0 -17
package/lib/basepagerenderer.js
CHANGED
@@ -2,12 +2,13 @@ import { Config } from "./config.js";
|
|
2
2
|
import { Files } from "./files.js";
|
3
3
|
import { Jekyll } from "./jekyll.js";
|
4
4
|
import { GlossaryPages } from "./web/glossarypages.js";
|
5
|
+
import { PageFamilyList } from "./web/pageFamily.js";
|
5
6
|
|
6
7
|
class BasePageRenderer {
|
7
8
|
/**
|
8
9
|
* @param {string} outputDir
|
9
|
-
* @param {import("./
|
10
|
-
* @param {import("./
|
10
|
+
* @param {import("./types.js").Taxa} taxa
|
11
|
+
* @param {import("./types.js").TaxaColDef[]} [familyCols]
|
11
12
|
*/
|
12
13
|
static renderBasePages(outputDir, taxa, familyCols) {
|
13
14
|
const siteGenerator = new Jekyll(outputDir);
|
@@ -21,7 +22,12 @@ class BasePageRenderer {
|
|
21
22
|
// Copy illustrations.
|
22
23
|
siteGenerator.copyIllustrations(taxa.getFlowerColors());
|
23
24
|
|
24
|
-
|
25
|
+
const fl = new PageFamilyList(
|
26
|
+
outputDir,
|
27
|
+
taxa.getFamilies().getFamilies(),
|
28
|
+
);
|
29
|
+
fl.render(familyCols);
|
30
|
+
fl.renderPages(outputDir, familyCols);
|
25
31
|
|
26
32
|
new GlossaryPages(siteGenerator).renderPages();
|
27
33
|
|
@@ -30,7 +36,7 @@ class BasePageRenderer {
|
|
30
36
|
|
31
37
|
/**
|
32
38
|
* @param {string} outputDir
|
33
|
-
* @param {import("./
|
39
|
+
* @param {import("./types.js").Taxa} taxa
|
34
40
|
*/
|
35
41
|
static renderTools(outputDir, taxa) {
|
36
42
|
const names = [];
|
package/lib/ebook/images.js
CHANGED
@@ -14,7 +14,7 @@ class Images {
|
|
14
14
|
/**
|
15
15
|
* @param {import("../sitegenerator.js").SiteGenerator} siteGenerator
|
16
16
|
* @param {string} contentDir
|
17
|
-
* @param {import("../
|
17
|
+
* @param {import("../types.js").Taxa} taxa
|
18
18
|
*/
|
19
19
|
constructor(siteGenerator, contentDir, taxa) {
|
20
20
|
this.#siteGenerator = siteGenerator;
|
@@ -23,7 +23,7 @@ class Images {
|
|
23
23
|
}
|
24
24
|
|
25
25
|
/**
|
26
|
-
* @param {import("../taxon.js").Taxon[]} taxa
|
26
|
+
* @param {import("../taxonomy/taxon.js").Taxon[]} taxa
|
27
27
|
*/
|
28
28
|
async createImages(taxa) {
|
29
29
|
const meter = new ProgressMeter("processing photos", taxa.length);
|
@@ -118,7 +118,7 @@ class Images {
|
|
118
118
|
}
|
119
119
|
|
120
120
|
/**
|
121
|
-
* @param {import("../taxon.js").Taxon} taxon
|
121
|
+
* @param {import("../taxonomy/taxon.js").Taxon} taxon
|
122
122
|
* @returns {import("../photo.js").Photo[]}
|
123
123
|
*/
|
124
124
|
static getTaxonPhotos(taxon) {
|
@@ -6,7 +6,7 @@ class PageListFamilies extends EBookPage {
|
|
6
6
|
|
7
7
|
/**
|
8
8
|
* @param {string} outputDir
|
9
|
-
* @param {import("../../
|
9
|
+
* @param {import("../../types.js").Families} families
|
10
10
|
*/
|
11
11
|
constructor(outputDir, families) {
|
12
12
|
super(outputDir + "/list_families.html", "All Families");
|
@@ -8,7 +8,7 @@ const FN_FLOWER_TIME_INDEX = "fm.html";
|
|
8
8
|
class PageListFlowers {
|
9
9
|
/**
|
10
10
|
* @param {string} contentDir
|
11
|
-
* @param {import("../../
|
11
|
+
* @param {import("../../types.js").Taxa} taxa
|
12
12
|
*/
|
13
13
|
static createPages(contentDir, taxa) {
|
14
14
|
new PageListFlowerTimeIndex(contentDir).create();
|
@@ -83,7 +83,7 @@ class PageListFlowerTime extends EBookPage {
|
|
83
83
|
|
84
84
|
/**
|
85
85
|
* @param {string} outputDir
|
86
|
-
* @param {import("../../
|
86
|
+
* @param {import("../../types.js").Taxa} taxa
|
87
87
|
* @param {number} month
|
88
88
|
*/
|
89
89
|
constructor(outputDir, taxa, month) {
|
@@ -13,7 +13,7 @@ class TaxonPage extends EBookPage {
|
|
13
13
|
|
14
14
|
/**
|
15
15
|
* @param {string} outputDir
|
16
|
-
* @param {import("../../taxon.js").Taxon} taxon
|
16
|
+
* @param {import("../../taxonomy/taxon.js").Taxon} taxon
|
17
17
|
* @param {Images} images
|
18
18
|
*/
|
19
19
|
constructor(outputDir, taxon, images) {
|
@@ -1,13 +1,13 @@
|
|
1
1
|
import { EBookPage } from "../ebookpage.js";
|
2
2
|
import { XHTML } from "../xhtml.js";
|
3
|
-
import { PageListFlowers } from "./
|
3
|
+
import { PageListFlowers } from "./pageListFlowers.js";
|
4
4
|
|
5
5
|
class TOCPage extends EBookPage {
|
6
6
|
#taxa;
|
7
7
|
|
8
8
|
/**
|
9
9
|
* @param {string} outputDir
|
10
|
-
* @param {import("../../taxa.js").Taxa} taxa
|
10
|
+
* @param {import("../../taxonomy/taxa.js").Taxa} taxa
|
11
11
|
*/
|
12
12
|
constructor(outputDir, taxa) {
|
13
13
|
super(outputDir + "/toc.xhtml", "Table of Contents");
|
package/lib/ebook/plantbook.js
CHANGED
@@ -3,9 +3,9 @@ import { EBook } from "./ebook.js";
|
|
3
3
|
import { EBookSiteGenerator } from "./ebooksitegenerator.js";
|
4
4
|
import { GlossaryPages } from "./glossarypages.js";
|
5
5
|
import { Images } from "./images.js";
|
6
|
-
import { PageListFamilies } from "./pages/
|
6
|
+
import { PageListFamilies } from "./pages/pageListFamilies.js";
|
7
7
|
import { PageListFlowerColor } from "./pages/page_list_flower_color.js";
|
8
|
-
import { PageListFlowers } from "./pages/
|
8
|
+
import { PageListFlowers } from "./pages/pageListFlowers.js";
|
9
9
|
import { PageListSpecies } from "./pages/page_list_species.js";
|
10
10
|
import { TaxonPage } from "./pages/taxonpage.js";
|
11
11
|
import { TOCPage } from "./pages/tocpage.js";
|
@@ -18,7 +18,7 @@ class PlantBook extends EBook {
|
|
18
18
|
/**
|
19
19
|
* @param {string} outputDir
|
20
20
|
* @param {import("../config.js").Config} config
|
21
|
-
* @param {import("../
|
21
|
+
* @param {import("../types.js").Taxa} taxa
|
22
22
|
*/
|
23
23
|
constructor(outputDir, config, taxa) {
|
24
24
|
super(
|
package/lib/externalsites.js
CHANGED
@@ -1,13 +1,37 @@
|
|
1
|
-
/** @typedef {{
|
2
|
-
coords?: [number, number];
|
3
|
-
project_id?: string;
|
4
|
-
subview?: "grid" | "list" | "map";
|
5
|
-
taxon_id?: string;
|
6
|
-
}} InatObsOptions */
|
7
|
-
|
8
1
|
export class ExternalSites {
|
9
2
|
/**
|
10
|
-
* @param {import("./
|
3
|
+
* @param {import("./types.js").Taxon} taxon
|
4
|
+
* @param {import("./types.js").Config} config
|
5
|
+
* @returns {URL|undefined}
|
6
|
+
*/
|
7
|
+
static getCalfloraObsLink(taxon, config) {
|
8
|
+
const name = taxon.getCalfloraName();
|
9
|
+
if (!name) {
|
10
|
+
return;
|
11
|
+
}
|
12
|
+
const url = new URL(
|
13
|
+
"https://www.calflora.org/entry/observ.html?track=m#srch=t&grezc=5&cols=b&lpcli=t&cc=" +
|
14
|
+
config.getCountyCodes().join("!") +
|
15
|
+
"&incobs=f&taxon=" +
|
16
|
+
name,
|
17
|
+
);
|
18
|
+
return url;
|
19
|
+
}
|
20
|
+
|
21
|
+
/**
|
22
|
+
* @param {import("./types.js").Taxon} taxon
|
23
|
+
* @returns {URL|undefined}
|
24
|
+
*/
|
25
|
+
static getCalfloraRefLink(taxon) {
|
26
|
+
const calfloraID = taxon.getCalfloraID();
|
27
|
+
if (!calfloraID) {
|
28
|
+
return;
|
29
|
+
}
|
30
|
+
return new URL("https://www.calflora.org/app/taxon?crn=" + calfloraID);
|
31
|
+
}
|
32
|
+
|
33
|
+
/**
|
34
|
+
* @param {import("./types.js").Taxon} taxon
|
11
35
|
* @returns {URL|undefined}
|
12
36
|
*/
|
13
37
|
static getCalscapeLink(taxon) {
|
@@ -21,7 +45,7 @@ export class ExternalSites {
|
|
21
45
|
}
|
22
46
|
|
23
47
|
/**
|
24
|
-
* @param {import("./
|
48
|
+
* @param {import("./types.js").Taxon} taxon
|
25
49
|
* @param {import("./config.js").Config} config
|
26
50
|
* @returns {URL|undefined}
|
27
51
|
*/
|
@@ -35,7 +59,7 @@ export class ExternalSites {
|
|
35
59
|
}
|
36
60
|
|
37
61
|
/**
|
38
|
-
* @param {import("./
|
62
|
+
* @param {import("./types.js").Taxon} taxon
|
39
63
|
* @returns {URL|undefined}
|
40
64
|
*/
|
41
65
|
static getCCH2RefLink(taxon) {
|
@@ -49,7 +73,7 @@ export class ExternalSites {
|
|
49
73
|
}
|
50
74
|
|
51
75
|
/**
|
52
|
-
* @param {import("./
|
76
|
+
* @param {import("./types.js").Taxon} taxon
|
53
77
|
* @returns {URL|undefined}
|
54
78
|
*/
|
55
79
|
static getFNARefLink(taxon) {
|
@@ -64,40 +88,65 @@ export class ExternalSites {
|
|
64
88
|
}
|
65
89
|
|
66
90
|
/**
|
67
|
-
* @param {
|
91
|
+
* @param {import("./types.js").Taxon} taxon
|
92
|
+
* @param {import("./config.js").Config} config
|
93
|
+
* @returns {URL|undefined}
|
68
94
|
*/
|
69
|
-
static getInatObsLink(
|
95
|
+
static getInatObsLink(taxon, config) {
|
96
|
+
const iNatID = taxon.getINatID();
|
97
|
+
if (!iNatID) {
|
98
|
+
return;
|
99
|
+
}
|
100
|
+
|
70
101
|
const url = new URL(
|
71
102
|
"https://www.inaturalist.org/observations?subview=map",
|
72
103
|
);
|
104
|
+
url.searchParams.set("taxon_id", iNatID);
|
105
|
+
for (const p of ["place_id", "project_id"]) {
|
106
|
+
const v = config.getConfigValue("inat", p);
|
107
|
+
if (v) {
|
108
|
+
url.searchParams.set(p, v);
|
109
|
+
}
|
110
|
+
}
|
111
|
+
|
112
|
+
return url;
|
113
|
+
}
|
73
114
|
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
params.set("swlng", (lng - delta).toString());
|
115
|
+
/**
|
116
|
+
* @param {import("./types.js").Taxon} taxon
|
117
|
+
* @returns {URL|undefined}
|
118
|
+
*/
|
119
|
+
static getINatRefLink(taxon) {
|
120
|
+
const iNatID = taxon.getINatID();
|
121
|
+
if (!iNatID) {
|
122
|
+
return;
|
83
123
|
}
|
124
|
+
return new URL("https://www.inaturalist.org/taxa/" + iNatID);
|
125
|
+
}
|
84
126
|
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
case "taxon_name":
|
94
|
-
if (typeof v === "string") {
|
95
|
-
url.searchParams.set(k, v);
|
96
|
-
}
|
97
|
-
break;
|
98
|
-
}
|
127
|
+
/**
|
128
|
+
* @param {import("./types.js").Taxonomy} taxon
|
129
|
+
* @returns {URL|undefined}
|
130
|
+
*/
|
131
|
+
static getJepsonRefLink(taxon) {
|
132
|
+
const id = taxon.getJepsonID();
|
133
|
+
if (!id) {
|
134
|
+
return;
|
99
135
|
}
|
136
|
+
return new URL(
|
137
|
+
"https://ucjeps.berkeley.edu/eflora/eflora_display.php?tid=" + id,
|
138
|
+
);
|
139
|
+
}
|
100
140
|
|
101
|
-
|
141
|
+
/**
|
142
|
+
* @param {import("./types.js").Taxon} taxon
|
143
|
+
* @returns {URL|undefined}
|
144
|
+
*/
|
145
|
+
static getRPIRefLink(taxon) {
|
146
|
+
const rpiID = taxon.getRPIID();
|
147
|
+
if (!rpiID) {
|
148
|
+
return;
|
149
|
+
}
|
150
|
+
return new URL("https://rareplants.cnps.org/Plants/Details/" + rpiID);
|
102
151
|
}
|
103
152
|
}
|
package/lib/flowercolor.js
CHANGED
@@ -3,7 +3,7 @@ import { TextUtils } from "./textutils.js";
|
|
3
3
|
class FlowerColor {
|
4
4
|
#colorName;
|
5
5
|
#colorCode;
|
6
|
-
/** @type {import("./
|
6
|
+
/** @type {import("./types.js").Taxon[]} */
|
7
7
|
#taxa = [];
|
8
8
|
|
9
9
|
/**
|
@@ -16,7 +16,7 @@ class FlowerColor {
|
|
16
16
|
}
|
17
17
|
|
18
18
|
/**
|
19
|
-
* @param {import("./
|
19
|
+
* @param {import("./types.js").Taxon} taxon
|
20
20
|
*/
|
21
21
|
addTaxon(taxon) {
|
22
22
|
this.#taxa.push(taxon);
|
package/lib/genera.js
CHANGED
@@ -6,7 +6,7 @@ class Genera {
|
|
6
6
|
#genera;
|
7
7
|
|
8
8
|
/**
|
9
|
-
* @param {import("./
|
9
|
+
* @param {import("./types.js").Families} families
|
10
10
|
*/
|
11
11
|
constructor(families) {
|
12
12
|
const dataDir = Config.getPackageDir() + "/data";
|
@@ -15,7 +15,7 @@ class Genera {
|
|
15
15
|
}
|
16
16
|
|
17
17
|
/**
|
18
|
-
* @param {import("./
|
18
|
+
* @param {import("./types.js").Taxon} taxon
|
19
19
|
*/
|
20
20
|
addTaxon(taxon) {
|
21
21
|
const genusName = taxon.getGenusName();
|
@@ -46,7 +46,7 @@ class Genus {
|
|
46
46
|
#data;
|
47
47
|
|
48
48
|
/**
|
49
|
-
* @param {{family:string,familyObj:import("./
|
49
|
+
* @param {{family:string,familyObj:import("./types.js").Family,taxa:import("./types.js").Taxon[]}} data
|
50
50
|
*/
|
51
51
|
constructor(data) {
|
52
52
|
this.#data = data;
|
@@ -57,7 +57,7 @@ class Genus {
|
|
57
57
|
}
|
58
58
|
|
59
59
|
/**
|
60
|
-
* @returns {import("./
|
60
|
+
* @returns {import("./types.js").Taxon[]}
|
61
61
|
*/
|
62
62
|
getTaxa() {
|
63
63
|
return this.#data.taxa.sort((a, b) =>
|
package/lib/html.js
CHANGED
@@ -48,7 +48,7 @@ export class HTML {
|
|
48
48
|
|
49
49
|
/**
|
50
50
|
* Generate HTML for an <a> element.
|
51
|
-
* @param {string|undefined} href
|
51
|
+
* @param {URL|string|undefined} href
|
52
52
|
* @param {string} linkText
|
53
53
|
* @param {string|Object<string,string>} [attributes]
|
54
54
|
* @param {boolean} [openInNewWindow] true if the link should open in a new window.
|
@@ -57,7 +57,7 @@ export class HTML {
|
|
57
57
|
static getLink(href, linkText, attributes = {}, openInNewWindow) {
|
58
58
|
let html = "<a";
|
59
59
|
if (href !== undefined) {
|
60
|
-
html += this.renderAttribute("href", href);
|
60
|
+
html += this.renderAttribute("href", href.toString());
|
61
61
|
}
|
62
62
|
html += this.renderAttributes(attributes);
|
63
63
|
if (openInNewWindow) {
|
@@ -70,8 +70,7 @@ export class HTML {
|
|
70
70
|
* Get a Bootstrap formatted tooltip element.
|
71
71
|
* @param {string} text - The text or HTML that should trigger the tooltip on hover.
|
72
72
|
* @param {string} tooltip - The tooltip text or HTML.
|
73
|
-
* @param {
|
74
|
-
* @param {boolean} [options.icon] [true] display an icon after the text
|
73
|
+
* @param {{icon?:boolean}} options
|
75
74
|
* @returns {string} A <span> element to be used as a Bootstrap tooltip.
|
76
75
|
*/
|
77
76
|
static getToolTip(text, tooltip, options = {}) {
|
@@ -106,19 +105,19 @@ export class HTML {
|
|
106
105
|
|
107
106
|
/**
|
108
107
|
* @param {string} elName
|
109
|
-
* @param {string} text
|
108
|
+
* @param {string|number} text
|
110
109
|
* @param {Object<string,string>} [attributes]
|
111
110
|
*/
|
112
111
|
static textElement(elName, text, attributes = {}) {
|
113
|
-
return HTML.#getElement(elName, text, attributes, true);
|
112
|
+
return HTML.#getElement(elName, text.toString(), attributes, true);
|
114
113
|
}
|
115
114
|
|
116
115
|
/**
|
117
116
|
* @param {string} elName
|
118
|
-
* @param {string} text
|
117
|
+
* @param {string|number} text
|
119
118
|
* @param {string|Object<string,string>|undefined} [attributes]
|
120
119
|
*/
|
121
120
|
static wrap(elName, text, attributes) {
|
122
|
-
return HTML.#getElement(elName, text, attributes, false);
|
121
|
+
return HTML.#getElement(elName, text.toString(), attributes, false);
|
123
122
|
}
|
124
123
|
}
|
package/lib/htmltaxon.js
CHANGED
@@ -7,15 +7,7 @@ import { RarePlants } from "./rareplants.js";
|
|
7
7
|
import { TextUtils } from "./textutils.js";
|
8
8
|
|
9
9
|
/**
|
10
|
-
* @
|
11
|
-
class?: string;
|
12
|
-
data: (taxon: import("./taxon.js").Taxon) => string;
|
13
|
-
title: string;
|
14
|
-
}} TaxaColDef
|
15
|
-
*/
|
16
|
-
|
17
|
-
/**
|
18
|
-
* @type {Record<string,TaxaColDef>}
|
10
|
+
* @type {Record<string,import("./types.js").TaxaColDef>}
|
19
11
|
*/
|
20
12
|
const TAXA_LIST_COLS = {
|
21
13
|
CESA: {
|
@@ -31,7 +23,7 @@ const TAXA_LIST_COLS = {
|
|
31
23
|
data: (t) =>
|
32
24
|
HTML.getToolTip(
|
33
25
|
HTML.textElement("span", t.getRPIRankAndThreat()),
|
34
|
-
|
26
|
+
HTMLTaxon.getRPIRankAndThreatTooltip(t),
|
35
27
|
),
|
36
28
|
},
|
37
29
|
FESA: {
|
@@ -40,33 +32,66 @@ const TAXA_LIST_COLS = {
|
|
40
32
|
},
|
41
33
|
SPECIES: {
|
42
34
|
title: "Species",
|
43
|
-
data: (t) =>
|
35
|
+
data: (t) => HTMLTaxon.getHTMLLink(t, true, true),
|
44
36
|
},
|
45
37
|
SPECIES_BARE: {
|
46
38
|
title: "Species",
|
47
|
-
data: (t) =>
|
39
|
+
data: (t) => HTMLTaxon.getHTMLLink(t, true, false),
|
48
40
|
},
|
49
41
|
};
|
50
42
|
|
51
|
-
/** @type {TaxaColDef[]} */
|
43
|
+
/** @type {import("./types.js").TaxaColDef[]} */
|
52
44
|
const DEFAULT_TAXA_COLUMNS = [
|
53
45
|
TAXA_LIST_COLS.SPECIES,
|
54
46
|
TAXA_LIST_COLS.COMMON_NAME,
|
55
47
|
];
|
56
48
|
|
57
|
-
/** @type {Object<string,{label:string,href:function(import("./
|
49
|
+
/** @type {Object<string,{label:string,href:function(import("./types.js").Taxon,import("./types.js").Config):URL|undefined}>} */
|
50
|
+
const OBSLINKS = {
|
51
|
+
calflora: {
|
52
|
+
label: "Calflora",
|
53
|
+
href: (taxon, config) =>
|
54
|
+
ExternalSites.getCalfloraObsLink(taxon, config),
|
55
|
+
},
|
56
|
+
cch: {
|
57
|
+
label: "CCH2",
|
58
|
+
href: (taxon, config) => ExternalSites.getCCH2ObsLink(taxon, config),
|
59
|
+
},
|
60
|
+
inat: {
|
61
|
+
label: "iNaturalist",
|
62
|
+
href: (taxon, config) => ExternalSites.getInatObsLink(taxon, config),
|
63
|
+
},
|
64
|
+
};
|
65
|
+
|
66
|
+
/** @type {Object<string,{label:string,href:function(import("./types.js").Taxon):URL|undefined}>} */
|
58
67
|
const REFLINKS = {
|
68
|
+
calflora: {
|
69
|
+
label: "Calflora",
|
70
|
+
href: (taxon) => ExternalSites.getCalfloraRefLink(taxon),
|
71
|
+
},
|
59
72
|
calscape: {
|
60
73
|
label: "Calscape",
|
61
74
|
href: (taxon) => ExternalSites.getCalscapeLink(taxon),
|
62
75
|
},
|
76
|
+
cch: {
|
77
|
+
label: "CCH2",
|
78
|
+
href: (taxon) => ExternalSites.getCCH2RefLink(taxon),
|
79
|
+
},
|
63
80
|
fna: {
|
64
81
|
label: "Flora of North America",
|
65
82
|
href: (taxon) => ExternalSites.getFNARefLink(taxon),
|
66
83
|
},
|
67
|
-
|
68
|
-
label: "
|
69
|
-
href: (taxon) => ExternalSites.
|
84
|
+
inat: {
|
85
|
+
label: "iNaturalist",
|
86
|
+
href: (taxon) => ExternalSites.getINatRefLink(taxon),
|
87
|
+
},
|
88
|
+
jepson: {
|
89
|
+
label: "Jepson eFlora",
|
90
|
+
href: (taxon) => ExternalSites.getJepsonRefLink(taxon),
|
91
|
+
},
|
92
|
+
rpi: {
|
93
|
+
label: "CNPS Rare Plant Inventory",
|
94
|
+
href: (taxon) => ExternalSites.getRPIRefLink(taxon),
|
70
95
|
},
|
71
96
|
};
|
72
97
|
|
@@ -75,23 +100,37 @@ class HTMLTaxon {
|
|
75
100
|
* @param {string[]} links
|
76
101
|
* @param {URL|string|undefined} href
|
77
102
|
* @param {string} label
|
103
|
+
* @param {string} [suffix=""]
|
78
104
|
*/
|
79
|
-
static addLink(links, href, label) {
|
105
|
+
static addLink(links, href, label, suffix = "") {
|
80
106
|
if (href === undefined) {
|
81
107
|
return;
|
82
108
|
}
|
83
109
|
const link = HTML.getLink(href.toString(), label, {}, true);
|
84
|
-
links.push(link);
|
110
|
+
links.push(link + suffix);
|
85
111
|
}
|
86
112
|
|
87
113
|
/**
|
88
114
|
* @param {string[]} links
|
89
|
-
* @param {import("./
|
115
|
+
* @param {import("./types.js").Taxon} taxon
|
116
|
+
* @param {import("./types.js").Config} config
|
90
117
|
* @param {import("./index.js").RefSourceCode} sourceCode
|
118
|
+
* @param {string} [label]
|
91
119
|
*/
|
92
|
-
static
|
120
|
+
static addObsLink(links, taxon, config, sourceCode, label) {
|
121
|
+
const source = OBSLINKS[sourceCode];
|
122
|
+
this.addLink(links, source.href(taxon, config), label ?? source.label);
|
123
|
+
}
|
124
|
+
|
125
|
+
/**
|
126
|
+
* @param {string[]} links
|
127
|
+
* @param {import("./types.js").Taxon} taxon
|
128
|
+
* @param {import("./index.js").RefSourceCode} sourceCode
|
129
|
+
* @param {string} [suffix=""]
|
130
|
+
*/
|
131
|
+
static addRefLink(links, taxon, sourceCode, suffix = "") {
|
93
132
|
const source = REFLINKS[sourceCode];
|
94
|
-
this.addLink(links, source.href(taxon), source.label);
|
133
|
+
this.addLink(links, source.href(taxon), source.label, suffix);
|
95
134
|
}
|
96
135
|
|
97
136
|
/**
|
@@ -120,7 +159,7 @@ class HTMLTaxon {
|
|
120
159
|
}
|
121
160
|
|
122
161
|
/**
|
123
|
-
* @param {import("./
|
162
|
+
* @param {import("./types.js").Taxon} taxon
|
124
163
|
* @param {string} classNames
|
125
164
|
* @param {boolean} [includeColorLink=true]
|
126
165
|
*/
|
@@ -161,7 +200,7 @@ class HTMLTaxon {
|
|
161
200
|
}
|
162
201
|
|
163
202
|
/**
|
164
|
-
* @param {import("./
|
203
|
+
* @param {import("./types.js").Taxon} taxon
|
165
204
|
* @returns {string}
|
166
205
|
*/
|
167
206
|
static getFooterHTML(taxon) {
|
@@ -174,7 +213,38 @@ class HTMLTaxon {
|
|
174
213
|
}
|
175
214
|
|
176
215
|
/**
|
177
|
-
* @param {import("./
|
216
|
+
* @param {import("./types.js").Taxon} taxon
|
217
|
+
* @param {boolean|string|undefined} href
|
218
|
+
* @param {boolean} includeRPI
|
219
|
+
*/
|
220
|
+
static getHTMLLink(taxon, href = true, includeRPI = true) {
|
221
|
+
href = href ? "./" + taxon.getFileName() : undefined;
|
222
|
+
let className = taxon.isNative() ? "native" : "non-native";
|
223
|
+
let isRare = false;
|
224
|
+
if (includeRPI && taxon.isRare()) {
|
225
|
+
isRare = true;
|
226
|
+
className += " rare";
|
227
|
+
}
|
228
|
+
const attributes = { class: className };
|
229
|
+
const link = HTML.wrap(
|
230
|
+
"span",
|
231
|
+
HTML.getLink(href, taxon.getName()),
|
232
|
+
attributes,
|
233
|
+
);
|
234
|
+
if (isRare) {
|
235
|
+
return HTML.getToolTip(
|
236
|
+
link,
|
237
|
+
this.getRPIRankAndThreatTooltip(taxon),
|
238
|
+
{
|
239
|
+
icon: false,
|
240
|
+
},
|
241
|
+
);
|
242
|
+
}
|
243
|
+
return link;
|
244
|
+
}
|
245
|
+
|
246
|
+
/**
|
247
|
+
* @param {import("./types.js").Taxon} taxon
|
178
248
|
*/
|
179
249
|
static getLink(taxon) {
|
180
250
|
return (
|
@@ -214,8 +284,17 @@ class HTMLTaxon {
|
|
214
284
|
}
|
215
285
|
|
216
286
|
/**
|
217
|
-
* @param {import("./
|
218
|
-
|
287
|
+
* @param {import("./types.js").Taxon} taxon
|
288
|
+
*/
|
289
|
+
static getRPIRankAndThreatTooltip(taxon) {
|
290
|
+
return RarePlants.getRPIRankAndThreatDescriptions(
|
291
|
+
taxon.getRPIRankAndThreat(),
|
292
|
+
).join("<br>");
|
293
|
+
}
|
294
|
+
|
295
|
+
/**
|
296
|
+
* @param {import("./types.js").Taxon[]} taxa
|
297
|
+
* @param {import("./types.js").TaxaColDef[]} [columns]
|
219
298
|
*/
|
220
299
|
static getTaxaTable(taxa, columns = DEFAULT_TAXA_COLUMNS) {
|
221
300
|
let html = "<table><thead>";
|