chrono-phylo-tree 1.0.16 → 1.1.1

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.
Files changed (66) hide show
  1. package/eslint.config.js +28 -0
  2. package/global.d.ts +26 -0
  3. package/index.html +13 -0
  4. package/package.json +2 -7
  5. package/src/App.css +131 -0
  6. package/src/App.tsx +149 -0
  7. package/src/assets/react.svg +1 -0
  8. package/src/classes/Species.tsx +267 -0
  9. package/src/components/HoverDescription.tsx +27 -0
  10. package/src/components/LanguageSelector.tsx +29 -0
  11. package/src/components/Menu.tsx +348 -0
  12. package/src/components/NavBar.tsx +234 -0
  13. package/src/components/PhTree.tsx +362 -0
  14. package/src/index.css +68 -0
  15. package/src/index.ts +4 -0
  16. package/src/main.tsx +10 -0
  17. package/src/types.d.ts +9 -0
  18. package/src/utils/between.tsx +3 -0
  19. package/src/utils/example.tsx +73 -0
  20. package/src/utils/hexToRGBA.tsx +12 -0
  21. package/src/utils/scientificNotation.tsx +20 -0
  22. package/src/utils/setFromJson.tsx +40 -0
  23. package/src/utils/translate.tsx +68 -0
  24. package/src/utils/updateSpecies.tsx +129 -0
  25. package/src/vite-env.d.ts +1 -0
  26. package/tsconfig.app.json +26 -0
  27. package/tsconfig.json +17 -0
  28. package/tsconfig.node.json +24 -0
  29. package/vite.config.ts +34 -0
  30. package/dist/App.d.ts +0 -3
  31. package/dist/App.d.ts.map +0 -1
  32. package/dist/chrono-phylo-tree.js +0 -1111
  33. package/dist/chrono-phylo-tree.umd.cjs +0 -15
  34. package/dist/classes/Species.d.ts +0 -35
  35. package/dist/classes/Species.d.ts.map +0 -1
  36. package/dist/components/HoverDescription.d.ts +0 -15
  37. package/dist/components/HoverDescription.d.ts.map +0 -1
  38. package/dist/components/LanguageSelector.d.ts +0 -9
  39. package/dist/components/LanguageSelector.d.ts.map +0 -1
  40. package/dist/components/Menu.d.ts +0 -15
  41. package/dist/components/Menu.d.ts.map +0 -1
  42. package/dist/components/NavBar.d.ts +0 -33
  43. package/dist/components/NavBar.d.ts.map +0 -1
  44. package/dist/components/PhTree.d.ts +0 -31
  45. package/dist/components/PhTree.d.ts.map +0 -1
  46. package/dist/index.d.ts +0 -5
  47. package/dist/index.d.ts.map +0 -1
  48. package/dist/main.d.ts +0 -1
  49. package/dist/main.d.ts.map +0 -1
  50. package/dist/utils/between.d.ts +0 -2
  51. package/dist/utils/between.d.ts.map +0 -1
  52. package/dist/utils/example.d.ts +0 -3
  53. package/dist/utils/example.d.ts.map +0 -1
  54. package/dist/utils/hexToRGBA.d.ts +0 -2
  55. package/dist/utils/hexToRGBA.d.ts.map +0 -1
  56. package/dist/utils/scientificNotation.d.ts +0 -2
  57. package/dist/utils/scientificNotation.d.ts.map +0 -1
  58. package/dist/utils/setFromJson.d.ts +0 -3
  59. package/dist/utils/setFromJson.d.ts.map +0 -1
  60. package/dist/utils/translate.d.ts +0 -4
  61. package/dist/utils/translate.d.ts.map +0 -1
  62. package/dist/utils/updateSpecies.d.ts +0 -7
  63. package/dist/utils/updateSpecies.d.ts.map +0 -1
  64. /package/{dist → public}/logo.png +0 -0
  65. /package/{dist → public}/translate.csv +0 -0
  66. /package/{dist → public}/vite.svg +0 -0
@@ -0,0 +1,29 @@
1
+ import { codeText } from "../utils/translate";
2
+
3
+ export const LanguageSelector = ({className = "", languages, language, setLanguage}: LanguageSelectorProps) => {
4
+ return (
5
+ <tr className={"text-start " + className}>
6
+ <td>{codeText("nvlbl05", language)}:</td>
7
+ <td>
8
+ <select
9
+ value={language}
10
+ onChange={(e) => setLanguage(e.target.value)}
11
+ className="bg-white dark:bg-[#242424] rounded"
12
+ >
13
+ {Array.from(languages).map(([key, value], index) => (
14
+ <option value={key} key={index}>
15
+ {value}
16
+ </option>
17
+ ))}
18
+ </select>
19
+ </td>
20
+ </tr>
21
+ );
22
+ };
23
+
24
+ interface LanguageSelectorProps {
25
+ className?: string;
26
+ languages: Map<string, string>;
27
+ language: string;
28
+ setLanguage: (language: string) => void;
29
+ }
@@ -0,0 +1,348 @@
1
+ import { useState } from "react";
2
+ import { Species } from "../classes/Species";
3
+ import { between } from "../utils/between";
4
+ import { codeText } from "../utils/translate";
5
+
6
+ interface MenuProps {
7
+ species: Species;
8
+ language?: string;
9
+ open?: boolean;
10
+ onClose?: () => void;
11
+ saveSpecies?: (
12
+ s: Species,
13
+ name: string,
14
+ apparition: number,
15
+ duration: number,
16
+ description: string,
17
+ image: string
18
+ ) => Promise<void>;
19
+ createDescendant?: (
20
+ s: Species,
21
+ name: string,
22
+ afterApparition: number,
23
+ duration: number,
24
+ description: string,
25
+ image: string
26
+ ) => Promise<void>;
27
+ createAncestor?: (
28
+ s: Species,
29
+ name: string,
30
+ previousApparition: number,
31
+ duration: number,
32
+ description: string,
33
+ image: string
34
+ ) => Promise<void>;
35
+ deleteAncestor?: () => Promise<void>;
36
+ deleteSpecies?: () => Promise<void>;
37
+ }
38
+
39
+ export const Menu = ({species, language, open, onClose, saveSpecies, createDescendant, createAncestor, deleteAncestor, deleteSpecies}: MenuProps) => {
40
+ const [name, setName] = useState(species.name);
41
+ const [apparition, setApparition] = useState(species.apparition);
42
+ const [duration, setDuration] = useState(species.duration);
43
+ const [description, setDescription] = useState(species.description ?? "");
44
+ const [addDescendant, setAddDescendant] = useState(false);
45
+ const [addAncestor, setAddAncestor] = useState(false);
46
+ const [image, setImage] = useState(species.image ?? "");
47
+
48
+ const toggleAddDescendant = () => {
49
+ setAddDescendant(!addDescendant);
50
+ };
51
+
52
+ const toggleAddAncestor = () => {
53
+ setAddAncestor(!addAncestor);
54
+ };
55
+
56
+ const uniqueDescendant = (s: Species): boolean => {
57
+ return s.ancestor ? s.ancestor.descendants.length === 1 && uniqueDescendant(s.ancestor) : true;
58
+ }
59
+
60
+ return(
61
+ <Modal open={open} onClose={onClose}>
62
+ <form style={{backgroundColor: "grey"}} className="flex flex-col text-start w-auto fixed p-2.5">
63
+ <Data
64
+ name={name}
65
+ setName={setName}
66
+ apparition={apparition}
67
+ setApparition={(n) => {
68
+ setApparition(species.ancestor ? between(n, species.ancestor.apparition, species.ancestor.extinction()) : n);
69
+ setDuration(species.descendants.length > 0 ? Math.max(Math.max(...species.descendants.map(desc => desc.apparition)) - apparition, duration) : duration);
70
+ }}
71
+ minApparition={species.ancestor ? species.ancestor.apparition : undefined}
72
+ maxApparition={species.ancestor ? species.ancestor.extinction() : undefined}
73
+ duration={duration}
74
+ setDuration={setDuration}
75
+ minDuration={species.descendants.length > 0 ? Math.max(...species.descendants.map(desc => desc.apparition)) - apparition : undefined}
76
+ maxDuration={species.descendants.length > 0 ? Math.max(...species.descendants.map(desc => desc.apparition)) - apparition : undefined}
77
+ description={description}
78
+ setDescription={setDescription}
79
+ image={image}
80
+ setImage={setImage}
81
+ language={language}
82
+ >
83
+ <button onClick={async () => {
84
+ try{
85
+ await saveSpecies?.(species, name, apparition, duration, description, image);
86
+ onClose?.();
87
+ } catch(e) {
88
+ console.error(e);
89
+ }
90
+ }}>
91
+ {codeText("spbtn00", language ?? "")}
92
+ </button>
93
+ <button type="button" onClick={deleteSpecies}>
94
+ {codeText("spbtn01", language ?? "")}
95
+ </button>
96
+ <button type="button" onClick={toggleAddDescendant}>
97
+ {codeText("spbtn02", language ?? "")}
98
+ </button>
99
+ {addDescendant &&
100
+ <AddDescendant
101
+ species={species}
102
+ language={language}
103
+ onClose={onClose}
104
+ createDescendant={createDescendant}
105
+ />}
106
+ {species.ancestor ?
107
+ uniqueDescendant(species) &&
108
+ <button type="button" onClick={async () => {
109
+ try {
110
+ await deleteAncestor?.();
111
+ onClose?.();
112
+ } catch(e){
113
+ console.error(e);
114
+ }
115
+ }}>
116
+ {codeText("spbtn04" + (species.ancestor.ancestor ? "_0" : ""), language ?? "")}
117
+ </button> :
118
+ <button type="button" onClick={toggleAddAncestor}>
119
+ {codeText("spbtn03", language ?? "")}
120
+ </button>}
121
+ {addAncestor &&
122
+ <AddAncestor
123
+ species={species}
124
+ language={language}
125
+ onClose={onClose}
126
+ createAncestor={createAncestor}
127
+ />}
128
+ <button type="button" onClick={onClose}>
129
+ {codeText("spbtn05", language ?? "")}
130
+ </button>
131
+ </Data>
132
+ </form>
133
+ </Modal>
134
+ );
135
+ };
136
+
137
+ interface DataProps {
138
+ name: string;
139
+ setName: (name: string) => void;
140
+ apparition: number;
141
+ setApparition: (apparition: number) => void;
142
+ minApparition?: number;
143
+ maxApparition?: number;
144
+ duration: number;
145
+ setDuration: (duration: number) => void;
146
+ minDuration?: number;
147
+ maxDuration?: number;
148
+ description?: string;
149
+ setDescription: (description: string) => void;
150
+ image: string;
151
+ setImage: (image: string) => void;
152
+ language?: string;
153
+ children?: any;
154
+ }
155
+
156
+ const Data = ({
157
+ name,
158
+ setName,
159
+ apparition,
160
+ setApparition,
161
+ minApparition,
162
+ maxApparition,
163
+ duration,
164
+ setDuration,
165
+ minDuration,
166
+ maxDuration,
167
+ description,
168
+ setDescription,
169
+ language,
170
+ image,
171
+ setImage,
172
+ children
173
+ }: DataProps) => {
174
+ return (
175
+ <>
176
+ <table>
177
+ <tbody>
178
+ <tr>
179
+ <td>{codeText("splbl00", language ?? "")}:</td>
180
+ <td>
181
+ <input
182
+ type="text"
183
+ value={name}
184
+ onChange={(e) => setName(e.target.value)}
185
+ />
186
+ </td>
187
+ </tr>
188
+ <tr>
189
+ <td>{codeText("splbl01", language ?? "")}:</td>
190
+ <td>
191
+ <input
192
+ type="number"
193
+ min={minApparition}
194
+ max={maxApparition}
195
+ value={apparition}
196
+ onChange={(e) => setApparition(Number(e.target.value))}
197
+ />
198
+ </td>
199
+ </tr>
200
+ <tr>
201
+ <td>{codeText("splbl02", language ?? "")}:</td>
202
+ <td>
203
+ <input
204
+ type="number"
205
+ min={minDuration}
206
+ max={maxDuration}
207
+ value={duration}
208
+ onChange={(e) => setDuration(Number(e.target.value))}
209
+ />
210
+ </td>
211
+ </tr>
212
+ <tr>
213
+ <td>{codeText("splbl03", language ?? "")}:</td>
214
+ <td>
215
+ <textarea
216
+ value={description}
217
+ onChange={(e) => setDescription(e.target.value)}
218
+ />
219
+ </td>
220
+ </tr>
221
+ <tr>
222
+ <td>{codeText("splbl04", language ?? "")}:</td>
223
+ <td>
224
+ <input
225
+ type="text"
226
+ value={image}
227
+ onChange={(e) => setImage(e.target.value)}
228
+ />
229
+ </td>
230
+ </tr>
231
+ <tr>
232
+ <td colSpan={2}>
233
+ <img
234
+ src={image}
235
+ style={{height: "100px"}}
236
+ />
237
+ </td>
238
+ </tr>
239
+ </tbody>
240
+ </table>
241
+ {children}
242
+ </>
243
+ );
244
+ };
245
+
246
+ const AddDescendant = ({species, language, onClose, createDescendant}: MenuProps) => {
247
+ const [name, setName] = useState('');
248
+ const [afterApparition, setAfterApparition] = useState(species.duration);
249
+ const [duration, setDuration] = useState(species.duration);
250
+ const [description, setDescription] = useState('');
251
+ const [image, setImage] = useState('');
252
+
253
+ return(
254
+ <>
255
+ <Data
256
+ name={name}
257
+ setName={setName}
258
+ apparition={species.apparition + afterApparition}
259
+ setApparition={(n) => setAfterApparition(n - species.apparition)}
260
+ minApparition={species.apparition}
261
+ maxApparition={species.extinction()}
262
+ duration={duration}
263
+ setDuration={setDuration}
264
+ description={description}
265
+ setDescription={setDescription}
266
+ image={image}
267
+ setImage={setImage}
268
+ language={language}
269
+ >
270
+ <button type="button" onClick={async () => {
271
+ try{
272
+ await createDescendant?.(species, name, afterApparition, duration, description, image);
273
+ onClose?.();
274
+ } catch(e) {
275
+ console.error(e);
276
+ }
277
+ }}>
278
+ {codeText("cdbtn00", language ?? "")}
279
+ </button>
280
+ </Data>
281
+ </>
282
+ );
283
+ };
284
+
285
+ const AddAncestor = ({species, language, onClose, createAncestor}: MenuProps) => {
286
+ const [name, setName] = useState('');
287
+ const [previousApparition, setPreviousApparition] = useState(species.duration);
288
+ const [duration, setDuration] = useState(species.duration);
289
+ const [description, setDescription] = useState('');
290
+ const [image, setImage] = useState('');
291
+
292
+ return(
293
+ <>
294
+ <Data
295
+ name={name}
296
+ setName={setName}
297
+ apparition={species.apparition - previousApparition}
298
+ setApparition={(n) => {
299
+ setPreviousApparition(species.apparition - n);
300
+ setDuration(Math.max(species.apparition - n, duration));
301
+ }}
302
+ maxApparition={species.apparition}
303
+ duration={duration}
304
+ setDuration={setDuration}
305
+ minDuration={previousApparition}
306
+ description={description}
307
+ setDescription={setDescription}
308
+ image={image}
309
+ setImage={setImage}
310
+ language={language}
311
+ >
312
+ <button type="button" onClick={async () => {
313
+ try {
314
+ await createAncestor?.(species, name, previousApparition, duration, description, image);
315
+ onClose?.();
316
+ } catch (e) {
317
+ console.error(e);
318
+ }
319
+ }}>
320
+ {codeText("cdbtn00", language ?? "")}
321
+ </button>
322
+ </Data>
323
+ </>
324
+ );
325
+ };
326
+
327
+ interface ModalProps {
328
+ open?: boolean;
329
+ onClose?: () => void;
330
+ children: any;
331
+ }
332
+
333
+ const Modal = ({open, onClose, children}: ModalProps) => {
334
+ return (
335
+ <div
336
+ style={{backgroundColor: open ? 'rgba(0, 0, 0, 0.2)' : 'rgba(0, 0, 0, 0)',}}
337
+ className={`flex fixed inset-0 justify-center items-center transition-colors duration-300 ease-in-out ${open ? "visible" : "hidden"}`}
338
+ onClick={onClose}
339
+ >
340
+ <div
341
+ onClick={(e) => e.stopPropagation()}
342
+ className="flex justify-center items-center"
343
+ >
344
+ {children}
345
+ </div>
346
+ </div>
347
+ );
348
+ };
@@ -0,0 +1,234 @@
1
+ import { Species } from "../classes/Species";
2
+ import { codeText } from "../utils/translate";
3
+ import { LanguageSelector } from "./LanguageSelector";
4
+
5
+ export const NavBar = ({
6
+ species,
7
+ color,
8
+ lineColor,
9
+ setLineColor,
10
+ language,
11
+ languages,
12
+ setLanguage,
13
+ minScale = 1e-12,
14
+ maxScale,
15
+ scale,
16
+ setScale,
17
+ showScaleNumber,
18
+ chronoScale,
19
+ setChronoScale,
20
+ showHover,
21
+ setShowHover,
22
+ showImages,
23
+ setShowImages,
24
+ presentTime,
25
+ presentTimeBoolean,
26
+ setPresentTimeBoolean,
27
+ changePresentTime,
28
+ setFromJson,
29
+ deleteAllSpecies,
30
+ createEmptySpecies,
31
+ showExample
32
+ }: NavBarProps) => {
33
+ return (
34
+ <nav style={{
35
+ backgroundColor: color,
36
+ maxWidth: window.screen.width - 64,
37
+ }}
38
+ className={`flex flex-col sm:flex-row w-auto ${species ? "fixed" : "static"} p-2.5 box-border ${species ? "transform translate-z-0" : "transform-none"}`}
39
+ >
40
+ <table className="flex flex-col justify-start text-start">
41
+ <tbody>
42
+ <LanguageSelector
43
+ className="block sm:hidden"
44
+ languages={languages}
45
+ language={language}
46
+ setLanguage={setLanguage}
47
+ />
48
+ <tr className="block sm:hidden h-2.5"/>
49
+ <tr>
50
+ <td>{codeText("nvlbl00", language)}: </td>
51
+ <td>
52
+ <input
53
+ type="range"
54
+ min={minScale}
55
+ max={maxScale}
56
+ step={minScale}
57
+ value={maxScale - scale + minScale}
58
+ onChange={(e) => setScale(maxScale - Number(e.target.value) + minScale)}
59
+ /> {showScaleNumber && <input
60
+ type="number"
61
+ min={1}
62
+ max={maxScale}
63
+ value={scale}
64
+ onChange={(e) => setScale(Number(e.target.value))}
65
+ />}
66
+ </td>
67
+ </tr>
68
+ <tr className="h-2.5"/>
69
+ <tr>
70
+ <td>{codeText("nvlbl06", language)}: </td>
71
+ <td>
72
+ <input
73
+ type="checkbox"
74
+ checked={chronoScale}
75
+ onChange={(e) => setChronoScale(e.target.checked)}
76
+ />
77
+ </td>
78
+ </tr>
79
+ <tr className="h-2.5"/>
80
+ <tr>
81
+ <td>{codeText("nvlbl07", language)}: </td>
82
+ <td>
83
+ <input
84
+ type="checkbox"
85
+ checked={showHover}
86
+ onChange={(e) => setShowHover(e.target.checked)}
87
+ />
88
+ </td>
89
+ </tr>
90
+ <tr className="h-2.5"/>
91
+ <tr>
92
+ <td>{codeText("nvlbl08", language)}</td>
93
+ <td>
94
+ <input
95
+ type="checkbox"
96
+ checked={showImages}
97
+ onChange={(e) => setShowImages(e.target.checked)}
98
+ />
99
+ </td>
100
+ </tr>
101
+ <tr className="h-2.5"/>
102
+ <tr>
103
+ <td>{codeText("nvlbl01", language)}: </td>
104
+ <td>
105
+ <input
106
+ type="range"
107
+ min={species ? species.apparition : 0}
108
+ max={species ? species.absoluteExtinction() : 1}
109
+ value={presentTime}
110
+ onChange={(e) => changePresentTime(Number(e.target.value))}
111
+ disabled={!presentTimeBoolean || !chronoScale}
112
+ /> <input
113
+ type="number"
114
+ min={species ? species.apparition : 0}
115
+ max={species ? species.absoluteExtinction() : 1}
116
+ value={presentTime}
117
+ onChange={(e) => changePresentTime(Number(e.target.value))}
118
+ disabled={!presentTimeBoolean || !chronoScale}
119
+ /> <input
120
+ type="checkbox"
121
+ checked={presentTimeBoolean}
122
+ onChange={(e) => setPresentTimeBoolean(e.target.checked)}
123
+ disabled={!chronoScale}
124
+ />
125
+ </td>
126
+ </tr>
127
+ </tbody>
128
+ </table>
129
+ <div className="h-2.5 sm:w-2.5 sm:h-auto"/>
130
+ <table className="flex flex-col justify-start text-start">
131
+ <tbody>
132
+ <tr>
133
+ <td>{codeText("nvlbl03", language)}: </td>
134
+ <td>
135
+ <a href="https://github.com/LUCHER4321/chrono-phylo-tree" target="_blank" className="ml-1.25 flex items-center">
136
+ <img style={{maxHeight: 25}} src="https://img.logo.dev/github.com?token=pk_VXzZR_o_QTelazRSvSRkNw&format=png"/>
137
+ </a>
138
+ </td>
139
+ </tr>
140
+ <tr className="h-2.5"/>
141
+ <tr>
142
+ <td>{codeText("nvlbl04", language)}: </td>
143
+ <td>
144
+ <input
145
+ type="file"
146
+ accept=".json"
147
+ value={undefined}
148
+ onChange={async (e) => await setFromJson(e.target.files?.[0])}
149
+ />
150
+ </td>
151
+ </tr>
152
+ <tr className="h-2.5"/>
153
+ <tr className="block sm:hidden">
154
+ <td>{codeText("nvlbl02", language)}: </td>
155
+ <td>
156
+ <input
157
+ type="color"
158
+ value={lineColor}
159
+ onChange={(e) => setLineColor(e.target.value)}
160
+ />
161
+ </td>
162
+ </tr>
163
+ </tbody>
164
+ <tbody>
165
+ <tr className="h-2.5 sm:h-auto"/>
166
+ <tr className="flex flex-col sm:flex-row">
167
+ <button type="button" onClick={async () => species ? deleteAllSpecies() : await createEmptySpecies()}>
168
+ {codeText("nvbtn00" + (species ? "_0" : ""), language)}
169
+ </button>
170
+ <div className="h-2.5 sm:w-2.5 sm:h-auto"/>
171
+ <button type="button" onClick={showExample}>
172
+ {codeText("nvbtn01", language)}
173
+ </button>
174
+ <div className="h-2.5 sm:w-2.5 sm:h-auto"/>
175
+ <button onClick={async () => await species?.saveJSON()} disabled={!species}>
176
+ {codeText("nvbtn02", language)}
177
+ </button>
178
+ </tr>
179
+ </tbody>
180
+ </table>
181
+ <div className="h-2.5 sm:w-2.5 sm:h-auto"/>
182
+ <table className="flex flex-col justify-start text-start hidden sm:block">
183
+ <tbody>
184
+ <LanguageSelector
185
+ languages={languages}
186
+ language={language}
187
+ setLanguage={setLanguage}
188
+ />
189
+ <tr className="h-2.5"/>
190
+ <tr>
191
+ <td>{codeText("nvlbl02", language)}:</td>
192
+ <td>
193
+ <input
194
+ type="color"
195
+ value={lineColor}
196
+ onChange={(e) => setLineColor(e.target.value)}
197
+ />
198
+ </td>
199
+ </tr>
200
+ </tbody>
201
+ </table>
202
+ </nav>
203
+ );
204
+ }
205
+
206
+ interface NavBarProps {
207
+ species?: Species;
208
+ color: string;
209
+ lineColor: string;
210
+ setLineColor: (lineColor: string) => void;
211
+ language: string;
212
+ languages: Map<string, string>;
213
+ setLanguage: (language: string) => void;
214
+ minScale?: number;
215
+ maxScale: number;
216
+ scale: number;
217
+ setScale: (scale: number) => void;
218
+ showScaleNumber: boolean;
219
+ chronoScale: boolean;
220
+ setChronoScale: (chronoScale: boolean) => void;
221
+ showHover: boolean;
222
+ setShowHover: (showHover: boolean) => void;
223
+ showImages: boolean;
224
+ setShowImages: (showImages: boolean) => void;
225
+ presentTime: number;
226
+ setPresentTime: (presentTime: number) => void;
227
+ presentTimeBoolean: boolean;
228
+ setPresentTimeBoolean: (presentTimeBoolean: boolean) => void;
229
+ changePresentTime: (presentTime: number) => void;
230
+ setFromJson: (file: File | undefined) => Promise<void>;
231
+ deleteAllSpecies: () => void;
232
+ createEmptySpecies: () => Promise<void>;
233
+ showExample: () => void;
234
+ }