imerss-bioinfo 1.13.0 → 1.14.0

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 (51) hide show
  1. package/build.js +44 -17
  2. package/docs/css/data-table.css +176 -0
  3. package/docs/css/imerss-bbea.css +0 -4
  4. package/docs/css/imerss-core.css +20 -5
  5. package/docs/css/imerss-viz-all.css +20 -5
  6. package/docs/css/imerss-viz-lib.css +20 -5
  7. package/docs/css/imerss-viz-new.css +243 -11
  8. package/docs/css/resize-bar.css +56 -0
  9. package/docs/js/imerss-bbea.js +39 -38
  10. package/docs/js/imerss-blitz.js +61 -51
  11. package/docs/js/imerss-plants.js +84 -0
  12. package/docs/js/imerss-viz-all.js +1 -1
  13. package/docs/js/imerss-viz-all.js.map +1 -1
  14. package/docs/js/imerss-viz-lib.js +1 -1
  15. package/docs/js/imerss-viz-lib.js.map +1 -1
  16. package/docs/js/imerss-viz-new-core.js +1 -1
  17. package/docs/js/imerss-viz-new-core.js.map +1 -1
  18. package/docs/js/imerss-viz-new.js +1 -1
  19. package/docs/js/imerss-viz-new.js.map +1 -1
  20. package/docs/js/imerss-viz.js +16 -8
  21. package/indexBeasBCBA.html +264 -0
  22. package/indexBeasOBA.html +2 -1
  23. package/indexBeasWaBA.html +2 -1
  24. package/package.json +3 -3
  25. package/src/assignBNames.js +47 -9
  26. package/src/buildSource/indexBeasBCBA.html +261 -0
  27. package/src/buildSource/indexBeasOBA.html +4 -3
  28. package/src/buildSource/indexBeasWaBA.html +4 -3
  29. package/src/client/css/data-table.css +176 -0
  30. package/src/client/css/imerss-bbea.css +0 -4
  31. package/src/client/css/imerss-core.css +20 -5
  32. package/src/client/css/resize-bar.css +56 -0
  33. package/src/client/js/new/data-table.js +483 -0
  34. package/src/client/js/new/filters.js +161 -46
  35. package/src/client/js/new/fluidNew.js +67 -1
  36. package/src/client/js/new/imerss-bbea.js +39 -38
  37. package/src/client/js/new/imerss-blitz.js +61 -51
  38. package/src/client/js/new/imerss-new.js +305 -121
  39. package/src/client/js/new/imerss-plants.js +84 -0
  40. package/src/client/js/new/imerss-viz.js +16 -8
  41. package/src/client/js/new/newChecklist.js +66 -14
  42. package/src/client/js/new/polygon-draw.js +2 -1
  43. package/src/client/js/new/resize-bar.js +289 -0
  44. package/src/copyBeasOut.js +3 -1
  45. package/src/copyMelitOut.js +2 -2
  46. package/src/dataProcessing/readCSV.js +1 -1
  47. package/src/geom/geoJSON.js +4 -2
  48. package/src/iNaturalist/taxonAPI.js +69 -17
  49. package/src/inatObs.js +2 -0
  50. package/src/validateUTF8.js +226 -0
  51. package/test/testiNatDisambig.js +12 -2
package/build.js CHANGED
@@ -81,6 +81,8 @@ const buildIndex = {
81
81
  newSource: [
82
82
  "node_modules/@mapbox/mapbox-gl-draw/dist/mapbox-gl-draw.js",
83
83
  "src/client/css/mapbox-gl-draw.css", // has our own overrides
84
+ "src/client/css/data-table.css",
85
+ "src/client/css/resize-bar.css",
84
86
  "node_modules/papaparse/papaparse.min.js",
85
87
  "node_modules/pako/dist/pako_inflate.min.js",
86
88
  "node_modules/pretty-checkbox/dist/pretty-checkbox.min.css",
@@ -91,6 +93,8 @@ const buildIndex = {
91
93
  "src/client/js/new/filters.js",
92
94
  "src/client/js/new/polygon-draw.js",
93
95
  "src/client/js/new/dual-range-input.js",
96
+ "src/client/js/new/data-table.js",
97
+ "src/client/js/new/resize-bar.js",
94
98
  "src/client/js/autocomplete.js",
95
99
  "src/client/js/tabs.js"
96
100
  ],
@@ -126,6 +130,9 @@ const buildIndex = {
126
130
  }, {
127
131
  src: "src/client/js/new/imerss-blitz.js",
128
132
  dest: "docs/js/imerss-blitz.js"
133
+ }, {
134
+ src: "src/client/js/new/imerss-plants.js",
135
+ dest: "docs/js/imerss-plants.js"
129
136
  }, {
130
137
  src: "src/lib/vizjs.js",
131
138
  dest: "docs/js/vizjs.js"
@@ -180,6 +187,15 @@ const buildIndex = {
180
187
  }, {
181
188
  src: "data/b-team/plant-pollinators-WaBA-2025-regionIndirection.csv",
182
189
  dest: "docs/data/b-team/plant-pollinators-WaBA-2025-regionIndirection.csv"
190
+ }, {
191
+ src: "data/b-team/plant-pollinators-BCBA-labels.viz",
192
+ dest: "docs/data/b-team/plant-pollinators-BCBA-labels.viz"
193
+ }, {
194
+ src: "data/b-team/plant-pollinators-BCBA-assigned-taxa.viz",
195
+ dest: "docs/data/b-team/plant-pollinators-BCBA-assigned-taxa.viz"
196
+ }, {
197
+ src: "data/b-team/plant-pollinators-BCBA-regionIndirection.csv",
198
+ dest: "docs/data/b-team/plant-pollinators-BCBA-regionIndirection.csv"
183
199
  }, {
184
200
  src: "data/Galiano 2023 BioBlitz/Galiano_Island_vascular_plant_records_consolidated-prepared.csv",
185
201
  dest: "docs/data/Galiano 2023 BioBlitz/Galiano_Island_vascular_plant_records_consolidated-prepared.csv"
@@ -266,13 +282,7 @@ const minify = async function (hash, filename) {
266
282
  });
267
283
  };
268
284
 
269
- const buildFromFiles = async function (buildIndex) {
270
- const allOldFiles = buildIndex.libSource.concat(buildIndex.oldSource);
271
- console.log("allOldFiles ", allOldFiles);
272
-
273
- const oldJsHash = filesToContentHash(allOldFiles, ".js");
274
- const allOldJsHash = fluid.extend({header: buildIndex.codeHeader}, oldJsHash, {footer: buildIndex.codeFooter});
275
- const minifiedAllOld = await minify(allOldJsHash, "imerss-viz-all.js");
285
+ const buildStory = async function (buildIndex) {
276
286
 
277
287
  // imerss-viz-lib.js contains just upstream libraries we depend on, to support reasonably easy deploy of "new" framework
278
288
  const libJsHash = filesToContentHash(buildIndex.libSource, ".js");
@@ -287,10 +297,6 @@ const buildFromFiles = async function (buildIndex) {
287
297
  console.log("newFiles ", buildIndex.newSource);
288
298
  const newJs = await minify(newJsHash, "imerss-viz-new.js");
289
299
 
290
- fs.removeSync("docs");
291
- fs.ensureDirSync("docs/js");
292
- fs.writeFileSync("docs/js/imerss-viz-all.js", minifiedAllOld.code, "utf8");
293
- fs.writeFileSync("docs/js/imerss-viz-all.js.map", minifiedAllOld.map);
294
300
  fs.writeFileSync("docs/js/imerss-viz-lib.js", minifiedLib.code, "utf8");
295
301
  fs.writeFileSync("docs/js/imerss-viz-lib.js.map", minifiedLib.map);
296
302
  fs.writeFileSync("docs/js/imerss-viz-new-core.js", newCoreJs.code, "utf8");
@@ -298,9 +304,6 @@ const buildFromFiles = async function (buildIndex) {
298
304
  fs.writeFileSync("docs/js/imerss-viz-new.js", newJs.code, "utf8");
299
305
  fs.writeFileSync("docs/js/imerss-viz-new.js.map", newJs.map);
300
306
 
301
- const allOldCssHash = filesToContentHash(allOldFiles, ".css");
302
- const allOldCssConcat = String.prototype.concat.apply("", Object.values(allOldCssHash));
303
-
304
307
  const cssLibHash = filesToContentHash(buildIndex.libSource, ".css");
305
308
  const cssLibConcat = String.prototype.concat.apply("", Object.values(cssLibHash));
306
309
 
@@ -310,12 +313,34 @@ const buildFromFiles = async function (buildIndex) {
310
313
  const cssNewHash = filesToContentHash(buildIndex.newSource, ".css");
311
314
  const cssNewConcat = String.prototype.concat.apply("", Object.values(cssNewHash));
312
315
 
313
- fs.ensureDirSync("docs/css");
314
- fs.writeFileSync("docs/css/imerss-viz-all.css", allOldCssConcat);
315
316
  fs.writeFileSync("docs/css/imerss-viz-lib.css", cssLibConcat);
316
317
  fs.writeFileSync("docs/css/imerss-viz-new-core.css", cssNewCoreConcat);
317
318
  fs.writeFileSync("docs/css/imerss-viz-new.css", cssNewConcat);
318
319
 
320
+ };
321
+
322
+ const buildFromFiles = async function (buildIndex) {
323
+ const allOldFiles = buildIndex.libSource.concat(buildIndex.oldSource);
324
+ console.log("allOldFiles ", allOldFiles);
325
+
326
+ const oldJsHash = filesToContentHash(allOldFiles, ".js");
327
+ const allOldJsHash = fluid.extend({header: buildIndex.codeHeader}, oldJsHash, {footer: buildIndex.codeFooter});
328
+ const minifiedAllOld = await minify(allOldJsHash, "imerss-viz-all.js");
329
+
330
+ fs.removeSync("docs");
331
+ fs.ensureDirSync("docs/js");
332
+ fs.writeFileSync("docs/js/imerss-viz-all.js", minifiedAllOld.code, "utf8");
333
+ fs.writeFileSync("docs/js/imerss-viz-all.js.map", minifiedAllOld.map);
334
+
335
+
336
+ const allOldCssHash = filesToContentHash(allOldFiles, ".css");
337
+ const allOldCssConcat = String.prototype.concat.apply("", Object.values(allOldCssHash));
338
+
339
+ fs.ensureDirSync("docs/css");
340
+ fs.writeFileSync("docs/css/imerss-viz-all.css", allOldCssConcat);
341
+
342
+ await buildStory(buildIndex);
343
+
319
344
  buildIndex.copy.forEach(function (oneCopy) {
320
345
  copyDep(oneCopy.src, oneCopy.dest);
321
346
  });
@@ -324,6 +349,8 @@ const buildFromFiles = async function (buildIndex) {
324
349
 
325
350
  fluid.setLogging(true);
326
351
 
327
- buildFromFiles(buildIndex).then(null, function (error) {
352
+ const buildFn = process.argv[2] === "story" ? buildStory : buildFromFiles;
353
+
354
+ buildFn(buildIndex).then(null, function (error) {
328
355
  console.log(error);
329
356
  });
@@ -0,0 +1,176 @@
1
+
2
+ :root {
3
+ --data-table-bg: #0e1117;
4
+ --data-table-surface: #161b22;
5
+ --data-table-border: #2a2f3a;
6
+ --data-table-text: #e2e6ed;
7
+ --data-table-text-dim: #7d8590;
8
+ --data-table-accent: #58a6ff;
9
+ --data-table-accent-dim: rgba(88, 166, 255, 0.12);
10
+ --data-table-radius: 8px;
11
+ --data-table-font: "DM Sans", sans-serif;
12
+ }
13
+
14
+ .hortis-dataTable {
15
+ height: 100%;
16
+ display: flex;
17
+ }
18
+
19
+ .hortis-dataTable-icon {
20
+ width: 24px;
21
+ height: 24px;
22
+ }
23
+
24
+ .hortis-dataTable-sort {
25
+ line-height: 0;
26
+ }
27
+
28
+ .hortis-dataTable-sort-wrap {
29
+ display: flex;
30
+ align-items: center;
31
+ }
32
+
33
+ .hortis-dataTable-selected-row {
34
+ background-color: #a5d6ff;
35
+ }
36
+
37
+ .hortis-dataTable-row-check {
38
+ display: block;
39
+ }
40
+
41
+
42
+ .hortis-dataTable-wrap {
43
+ flex: 1;
44
+ min-height: 0;
45
+ height: 100%;
46
+ overflow: hidden;
47
+ border: 1px solid var(--data-table-border);
48
+ border-radius: var(--data-table-radius);
49
+ background: var(--data-table-surface);
50
+ display: flex;
51
+ flex-direction: column;
52
+ }
53
+
54
+ .hortis-dataTable-scroll {
55
+ flex: 1;
56
+ min-height: 0;
57
+ overflow-x: scroll;
58
+ overflow-y: hidden;
59
+ }
60
+
61
+ .hortis-dataTable-scroll table {
62
+ border-collapse: collapse;
63
+ table-layout: fixed;
64
+ }
65
+
66
+ .hortis-dataTable-scroll thead th {
67
+ position: sticky;
68
+ top: 0;
69
+ z-index: 2;
70
+ background: var(--data-table-surface);
71
+ font-size: 12px;
72
+ font-weight: 600;
73
+ color: var(--data-table-text-dim);
74
+ text-align: left;
75
+ padding: 6px 10px;
76
+ border-bottom: 1px solid var(--data-table-border);
77
+ white-space: nowrap;
78
+ }
79
+
80
+ .hortis-dataTable-scroll thead th.hortis-dataTable-num {
81
+ text-align: right;
82
+ }
83
+
84
+ .hortis-dataTable-scroll tbody td {
85
+ padding: 3px 10px;
86
+ font-size: 13px;
87
+ border-bottom: 1px solid var(--data-table-border);
88
+ white-space: nowrap;
89
+ overflow: hidden;
90
+ text-overflow: ellipsis;
91
+ }
92
+
93
+ .hortis-dataTable-scroll tbody tr {
94
+ transition: background 0.15s ease;
95
+ }
96
+
97
+ .hortis-dataTable-scroll tbody tr:last-child td {
98
+ border-bottom: none;
99
+ }
100
+
101
+ :root {
102
+ --datatable-scrollbar-width: 12px;
103
+ }
104
+
105
+ .hortis-dataTable-wrap ::-webkit-scrollbar {
106
+ -webkit-appearance: none;
107
+ width: var(--datatable-scrollbar-width);
108
+ background-color: #eee
109
+ }
110
+
111
+ .hortis-dataTable-wrap ::-webkit-scrollbar-thumb {
112
+ border-radius: 6px;
113
+ background-color: #C1C1C1;
114
+ -webkit-box-shadow: 0 0 1px rgba(255,255,255,.5);
115
+ }
116
+
117
+ .hortis-dataTable-wrap ::-webkit-scrollbar-thumb:hover {
118
+ background-color: #A8A8A8;
119
+ }
120
+
121
+
122
+ td.hortis-dataTable-num, th.hortis-dataTable-num {
123
+ text-align: right;
124
+ font-size: 12px;
125
+ }
126
+
127
+ /* ── Pagination bar ── */
128
+ .hortis-dataTable-pagination {
129
+ flex-shrink: 0;
130
+ display: flex;
131
+ align-items: center;
132
+ justify-content: space-between;
133
+ padding: 10px 16px;
134
+ border-top: 1px solid var(--data-table-border);
135
+ font-size: 12px;
136
+ color: var(--data-table-text-dim);
137
+ user-select: none;
138
+ }
139
+
140
+ .hortis-dataTable-pageInfo {
141
+ }
142
+
143
+ .hortis-dataTable-pageControls {
144
+ display: flex;
145
+ gap: 4px;
146
+ }
147
+
148
+ .hortis-dataTable-pagination button {
149
+ font-family: var(--data-table-font);
150
+ font-size: 12px;
151
+ font-weight: 500;
152
+ background: transparent;
153
+ border: 1px solid var(--data-table-border);
154
+ border-radius: 6px;
155
+ color: var(--data-table-text-dim);
156
+ padding: 4px 12px;
157
+ cursor: pointer;
158
+ transition: all 0.15s ease;
159
+ }
160
+
161
+ .hortis-dataTable-pagination button:hover:not(:disabled) {
162
+ border-color: var(--data-table-accent);
163
+ color: var(--data-table-accent);
164
+ background: var(--data-table-accent-dim);
165
+ }
166
+
167
+ .hortis-dataTable-pagination button:disabled {
168
+ opacity: 0.3;
169
+ cursor: default;
170
+ }
171
+
172
+ .hortis-dataTable-pagination button.hortis-dataTable-active {
173
+ border-color: var(--data-table-accent);
174
+ color: var(--data-table-accent);
175
+ background: var(--data-table-accent-dim);
176
+ }
@@ -185,10 +185,6 @@ body {
185
185
  }
186
186
 
187
187
 
188
- .imerss-collector-report.imerss-hidden {
189
- display: none;
190
- }
191
-
192
188
  .imerss-sex-filter-checks {
193
189
  display: flex;
194
190
  flex-direction: row;
@@ -80,6 +80,7 @@
80
80
  width: 10em;
81
81
  margin-left: auto;
82
82
  margin-right: 10px;
83
+ margin-top: 8px;
83
84
  background: #555e;
84
85
  pointer-events: all;
85
86
  display: flex;
@@ -362,6 +363,9 @@
362
363
  margin-top: 0.5rem;
363
364
  }
364
365
 
366
+ .imerss-tooltip.imerss-grid-tooltip div.text {
367
+ max-width: none;
368
+ }
365
369
 
366
370
  .imerss-autocomplete {
367
371
  width: 30em;
@@ -431,6 +435,10 @@
431
435
 
432
436
  .imerss-filter {
433
437
  padding: 2px 0 2px;
438
+ margin-top: -1px;
439
+ margin-bottom: 1px;
440
+ display: flex;
441
+ flex-direction: column;
434
442
  border-bottom: 1px solid #dbe3e7;
435
443
  }
436
444
 
@@ -498,10 +506,6 @@
498
506
  background: #d0d7de33;
499
507
  }
500
508
 
501
- .imerss-filter-clear.imerss-hidden {
502
- display: none;
503
- }
504
-
505
509
  .imerss-free-region-filter {
506
510
  display: flex;
507
511
  flex-direction: column;
@@ -573,6 +577,11 @@
573
577
  padding: 10px;
574
578
  }
575
579
 
580
+ /** Override core definition in tooltip.css */
581
+ .ui-tooltip {
582
+ max-width: none;
583
+ }
584
+
576
585
  #fli-tab-checklist.ui-tabs-panel, #fli-tab-simple-checklist.ui-tabs-panel {
577
586
  padding: 0;
578
587
  }
@@ -617,7 +626,13 @@
617
626
  width: calc(100% - 20px)
618
627
  }
619
628
 
620
- .imerss-search-checklist svg {
629
+ /** This one hits the close box next to the filter */
630
+ .imerss-search-checklist .imerss-filter-clear {
631
+ right: -12px;
632
+ }
633
+
634
+ /** This one hits the magnifying glass icon inside the search box */
635
+ .imerss-search-checklist > svg {
621
636
  left: 0;
622
637
  top: -2px;
623
638
  position: absolute;
@@ -776,6 +776,7 @@ a.ui-button:active,
776
776
  width: 10em;
777
777
  margin-left: auto;
778
778
  margin-right: 10px;
779
+ margin-top: 8px;
779
780
  background: #555e;
780
781
  pointer-events: all;
781
782
  display: flex;
@@ -1058,6 +1059,9 @@ a.ui-button:active,
1058
1059
  margin-top: 0.5rem;
1059
1060
  }
1060
1061
 
1062
+ .imerss-tooltip.imerss-grid-tooltip div.text {
1063
+ max-width: none;
1064
+ }
1061
1065
 
1062
1066
  .imerss-autocomplete {
1063
1067
  width: 30em;
@@ -1127,6 +1131,10 @@ a.ui-button:active,
1127
1131
 
1128
1132
  .imerss-filter {
1129
1133
  padding: 2px 0 2px;
1134
+ margin-top: -1px;
1135
+ margin-bottom: 1px;
1136
+ display: flex;
1137
+ flex-direction: column;
1130
1138
  border-bottom: 1px solid #dbe3e7;
1131
1139
  }
1132
1140
 
@@ -1194,10 +1202,6 @@ a.ui-button:active,
1194
1202
  background: #d0d7de33;
1195
1203
  }
1196
1204
 
1197
- .imerss-filter-clear.imerss-hidden {
1198
- display: none;
1199
- }
1200
-
1201
1205
  .imerss-free-region-filter {
1202
1206
  display: flex;
1203
1207
  flex-direction: column;
@@ -1269,6 +1273,11 @@ a.ui-button:active,
1269
1273
  padding: 10px;
1270
1274
  }
1271
1275
 
1276
+ /** Override core definition in tooltip.css */
1277
+ .ui-tooltip {
1278
+ max-width: none;
1279
+ }
1280
+
1272
1281
  #fli-tab-checklist.ui-tabs-panel, #fli-tab-simple-checklist.ui-tabs-panel {
1273
1282
  padding: 0;
1274
1283
  }
@@ -1313,7 +1322,13 @@ a.ui-button:active,
1313
1322
  width: calc(100% - 20px)
1314
1323
  }
1315
1324
 
1316
- .imerss-search-checklist svg {
1325
+ /** This one hits the close box next to the filter */
1326
+ .imerss-search-checklist .imerss-filter-clear {
1327
+ right: -12px;
1328
+ }
1329
+
1330
+ /** This one hits the magnifying glass icon inside the search box */
1331
+ .imerss-search-checklist > svg {
1317
1332
  left: 0;
1318
1333
  top: -2px;
1319
1334
  position: absolute;
@@ -776,6 +776,7 @@ a.ui-button:active,
776
776
  width: 10em;
777
777
  margin-left: auto;
778
778
  margin-right: 10px;
779
+ margin-top: 8px;
779
780
  background: #555e;
780
781
  pointer-events: all;
781
782
  display: flex;
@@ -1058,6 +1059,9 @@ a.ui-button:active,
1058
1059
  margin-top: 0.5rem;
1059
1060
  }
1060
1061
 
1062
+ .imerss-tooltip.imerss-grid-tooltip div.text {
1063
+ max-width: none;
1064
+ }
1061
1065
 
1062
1066
  .imerss-autocomplete {
1063
1067
  width: 30em;
@@ -1127,6 +1131,10 @@ a.ui-button:active,
1127
1131
 
1128
1132
  .imerss-filter {
1129
1133
  padding: 2px 0 2px;
1134
+ margin-top: -1px;
1135
+ margin-bottom: 1px;
1136
+ display: flex;
1137
+ flex-direction: column;
1130
1138
  border-bottom: 1px solid #dbe3e7;
1131
1139
  }
1132
1140
 
@@ -1194,10 +1202,6 @@ a.ui-button:active,
1194
1202
  background: #d0d7de33;
1195
1203
  }
1196
1204
 
1197
- .imerss-filter-clear.imerss-hidden {
1198
- display: none;
1199
- }
1200
-
1201
1205
  .imerss-free-region-filter {
1202
1206
  display: flex;
1203
1207
  flex-direction: column;
@@ -1269,6 +1273,11 @@ a.ui-button:active,
1269
1273
  padding: 10px;
1270
1274
  }
1271
1275
 
1276
+ /** Override core definition in tooltip.css */
1277
+ .ui-tooltip {
1278
+ max-width: none;
1279
+ }
1280
+
1272
1281
  #fli-tab-checklist.ui-tabs-panel, #fli-tab-simple-checklist.ui-tabs-panel {
1273
1282
  padding: 0;
1274
1283
  }
@@ -1313,7 +1322,13 @@ a.ui-button:active,
1313
1322
  width: calc(100% - 20px)
1314
1323
  }
1315
1324
 
1316
- .imerss-search-checklist svg {
1325
+ /** This one hits the close box next to the filter */
1326
+ .imerss-search-checklist .imerss-filter-clear {
1327
+ right: -12px;
1328
+ }
1329
+
1330
+ /** This one hits the magnifying glass icon inside the search box */
1331
+ .imerss-search-checklist > svg {
1317
1332
  left: 0;
1318
1333
  top: -2px;
1319
1334
  position: absolute;