@larsgw/formica 0.7.3 → 0.8.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.
@@ -0,0 +1,740 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ var __assign = (this && this.__assign) || function () {
4
+ __assign = Object.assign || function(t) {
5
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
6
+ s = arguments[i];
7
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
8
+ t[p] = s[p];
9
+ }
10
+ return t;
11
+ };
12
+ return __assign.apply(this, arguments);
13
+ };
14
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
15
+ if (k2 === undefined) k2 = k;
16
+ var desc = Object.getOwnPropertyDescriptor(m, k);
17
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
18
+ desc = { enumerable: true, get: function() { return m[k]; } };
19
+ }
20
+ Object.defineProperty(o, k2, desc);
21
+ }) : (function(o, m, k, k2) {
22
+ if (k2 === undefined) k2 = k;
23
+ o[k2] = m[k];
24
+ }));
25
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
26
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
27
+ }) : function(o, v) {
28
+ o["default"] = v;
29
+ });
30
+ var __importStar = (this && this.__importStar) || (function () {
31
+ var ownKeys = function(o) {
32
+ ownKeys = Object.getOwnPropertyNames || function (o) {
33
+ var ar = [];
34
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
35
+ return ar;
36
+ };
37
+ return ownKeys(o);
38
+ };
39
+ return function (mod) {
40
+ if (mod && mod.__esModule) return mod;
41
+ var result = {};
42
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
43
+ __setModuleDefault(result, mod);
44
+ return result;
45
+ };
46
+ })();
47
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
48
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
49
+ return new (P || (P = Promise))(function (resolve, reject) {
50
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
51
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
52
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
53
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
54
+ });
55
+ };
56
+ var __generator = (this && this.__generator) || function (thisArg, body) {
57
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
58
+ return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
59
+ function verb(n) { return function (v) { return step([n, v]); }; }
60
+ function step(op) {
61
+ if (f) throw new TypeError("Generator is already executing.");
62
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
63
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
64
+ if (y = 0, t) op = [op[0] & 2, t.value];
65
+ switch (op[0]) {
66
+ case 0: case 1: t = op; break;
67
+ case 4: _.label++; return { value: op[1], done: false };
68
+ case 5: _.label++; y = op[1]; op = [0]; continue;
69
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
70
+ default:
71
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
72
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
73
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
74
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
75
+ if (t[2]) _.ops.pop();
76
+ _.trys.pop(); continue;
77
+ }
78
+ op = body.call(thisArg, _);
79
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
80
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
81
+ }
82
+ };
83
+ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
84
+ if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
85
+ if (ar || !(i in from)) {
86
+ if (!ar) ar = Array.prototype.slice.call(from, 0, i);
87
+ ar[i] = from[i];
88
+ }
89
+ }
90
+ return to.concat(ar || Array.prototype.slice.call(from));
91
+ };
92
+ Object.defineProperty(exports, "__esModule", { value: true });
93
+ var fs_1 = require("fs");
94
+ var path = __importStar(require("path"));
95
+ var util = __importStar(require("util"));
96
+ var jsonld = __importStar(require("jsonld"));
97
+ var N3 = __importStar(require("n3"));
98
+ var index_1 = require("../index");
99
+ var resource_1 = require("../resources/resource");
100
+ var csv_1 = require("../csv");
101
+ var SHEETS = ['catalog', 'authors', 'places', 'publishers', 'taxa'];
102
+ var PREFIX = 'https://purl.org/identification-resources/';
103
+ var HANDLE_PREFIX = 'https://hdl.handle.net/';
104
+ var SCOPES = {
105
+ // animal life stage
106
+ 'adults': ['dwciri:lifeStage', 'http://rs.gbif.org/vocabulary/gbif/life_stage/adult'],
107
+ 'pupae': ['dwciri:lifeStage', 'http://rs.gbif.org/vocabulary/gbif/life_stage/pupa'],
108
+ 'juveniles': ['dwciri:lifeStage', 'http://rs.gbif.org/vocabulary/gbif/life_stage/juvenile'],
109
+ 'subimagos': ['dwciri:lifeStage', 'http://rs.gbif.org/vocabulary/gbif/life_stage/juvenile'],
110
+ 'larvae': ['dwciri:lifeStage', 'http://rs.gbif.org/vocabulary/gbif/life_stage/larva'],
111
+ 'larvae (instar V)': ['dwciri:lifeStage', 'http://rs.gbif.org/vocabulary/gbif/life_stage/larva'],
112
+ 'larvae (instar IV)': ['dwciri:lifeStage', 'http://rs.gbif.org/vocabulary/gbif/life_stage/larva'],
113
+ 'larvae (instar III)': ['dwciri:lifeStage', 'http://rs.gbif.org/vocabulary/gbif/life_stage/larva'],
114
+ 'larvae (instar I)': ['dwciri:lifeStage', 'http://rs.gbif.org/vocabulary/gbif/life_stage/larva'],
115
+ 'nymphs': ['dwciri:lifeStage', 'http://rs.gbif.org/vocabulary/gbif/life_stage/larva'],
116
+ 'nypmhs': ['dwciri:lifeStage', 'http://rs.gbif.org/vocabulary/gbif/life_stage/larva'],
117
+ 'nymphs (instar V)': ['dwciri:lifeStage', 'http://rs.gbif.org/vocabulary/gbif/life_stage/larva'],
118
+ 'eggs': ['dwciri:lifeStage', 'http://rs.gbif.org/vocabulary/gbif/life_stage/embryo'],
119
+ // plant life stage
120
+ 'flowering plants': ['dwciri:lifeStage', 'http://rs.gbif.org/vocabulary/gbif/life_stage/adult'],
121
+ 'fruiting plants': ['dwciri:lifeStage', 'http://rs.gbif.org/vocabulary/gbif/life_stage/adult'],
122
+ 'without sporangia': ['dwciri:lifeStage', 'http://rs.gbif.org/vocabulary/gbif/life_stage/juvenile'],
123
+ 'with sporangia': ['dwciri:lifeStage', 'http://rs.gbif.org/vocabulary/gbif/life_stage/adult'],
124
+ 'teleomorphs': ['dwciri:lifeStage', 'http://rs.gbif.org/vocabulary/gbif/life_stage/adult'],
125
+ // sex
126
+ 'females': ['dwciri:sex', 'http://rs.gbif.org/vocabulary/gbif/sex/female'],
127
+ 'males': ['dwciri:sex', 'http://rs.gbif.org/vocabulary/gbif/sex/male'],
128
+ // caste
129
+ 'queens': ['dwc:caste', 'queen'],
130
+ 'workers': ['dwc:caste', 'worker'],
131
+ 'soldiers': ['dwc:caste', 'soldier'],
132
+ 'alates': ['dwc:caste', 'alate'],
133
+ 'alatae': ['dwc:caste', 'alate'],
134
+ 'apterae': ['dwc:caste', 'aptera'],
135
+ 'viviparae': ['dwc:caste', 'vivipara'],
136
+ // evidence
137
+ 'nests': ['ac:subjectPartLiteral', 'nest'],
138
+ 'galls': ['ac:subjectPartLiteral', 'gall'],
139
+ 'puparia': ['ac:subjectPartLiteral', 'puparium'],
140
+ 'eggcases': ['ac:subjectPart', 'http://rs.tdwg.org/acpart/values/p0031'],
141
+ 'bones': ['ac:subjectPartLiteral', 'skeleton'],
142
+ 'bones (skulls)': ['ac:subjectPart', 'http://rs.tdwg.org/acpart/values/p0027'],
143
+ 'bones (upper jaws)': ['ac:subjectPart', 'http://rs.tdwg.org/acpart/values/p0028'],
144
+ 'bones (lower jaws)': ['ac:subjectPart', 'http://rs.tdwg.org/acpart/values/p0029'],
145
+ };
146
+ var PREFIXES = {
147
+ 'ac': 'http://rs.tdwg.org/ac/terms/',
148
+ 'bibo': 'http://purl.org/ontology/bibo/',
149
+ 'dcterms': 'http://purl.org/dc/terms/',
150
+ 'dwc': 'http://rs.tdwg.org/dwc/terms/',
151
+ 'dwciri': 'http://rs.tdwg.org/dwc/iri/',
152
+ 'foaf': 'http://xmlns.com/foaf/0.1/',
153
+ 'owl': 'http://www.w3.org/2002/07/owl#',
154
+ 'schema': 'https://schema.org/',
155
+ };
156
+ var DWC_FIELDS = {
157
+ scientificName: 'dwc:scientificName',
158
+ scientificNameAuthorship: 'dwc:scientificNameAuthorship',
159
+ genericName: 'dwc:genericName',
160
+ infragenericEpithet: 'dwc:infragenericEpithet',
161
+ specificEpithet: 'dwc:specificEpithet',
162
+ infraspecificEpithet: 'dwc:infraspecificEpithet',
163
+ taxonRank: 'dwc:taxonRank',
164
+ taxonRemarks: 'dwc:taxonRemarks',
165
+ taxonomicStatus: 'dwc:taxonomicStatus',
166
+ verbatimIdentification: 'dwc:verbatimIdentification',
167
+ };
168
+ var GBIF_RANKS = ['kingdom', 'phylum', 'class', 'order', 'family', 'genus', 'species', 'subspecies'];
169
+ function getCoveringTaxon(taxa) {
170
+ if (taxa.length === 1 && !taxa[0].has('gbif')) {
171
+ return "".concat(PREFIX, "taxon/").concat(taxa[0].get('id'));
172
+ }
173
+ function getAncestors(taxon) {
174
+ var _a;
175
+ var parents = ((_a = taxon.get('parent_taxa')) !== null && _a !== void 0 ? _a : []).slice(0);
176
+ if (taxon.has('gbif')) {
177
+ parents.push(taxon.get('gbif'));
178
+ }
179
+ return parents;
180
+ }
181
+ var ancestors = getAncestors(taxa[0]);
182
+ for (var _i = 0, _a = taxa.slice(1); _i < _a.length; _i++) {
183
+ var taxon = _a[_i];
184
+ var otherAncestors = getAncestors(taxon);
185
+ for (var i = 0; i < ancestors.length; i++) {
186
+ if (ancestors[i] !== otherAncestors[i]) {
187
+ ancestors.splice(i);
188
+ }
189
+ }
190
+ }
191
+ return ancestors.length ? makeGbifUri(ancestors[ancestors.length - 1])['@id'] : null;
192
+ }
193
+ function mapEntities(names, entities) {
194
+ var result = [];
195
+ var _loop_1 = function (name_1) {
196
+ var entity = entities.find(function (entity) {
197
+ var values = entity.get('name');
198
+ return Array.isArray(values) ? values.includes(name_1) : values === name_1;
199
+ });
200
+ if (!entity) {
201
+ console.error('Unmapped entity:', name_1);
202
+ return "continue";
203
+ }
204
+ result.push(entity);
205
+ };
206
+ for (var _i = 0, names_1 = names; _i < names_1.length; _i++) {
207
+ var name_1 = names_1[_i];
208
+ _loop_1(name_1);
209
+ }
210
+ return result;
211
+ }
212
+ function makeWikidataUri(qid) {
213
+ return { '@id': "http://www.wikidata.org/entity/".concat(qid) };
214
+ }
215
+ function makeGbifUri(id) {
216
+ return { '@id': "https://gbif.org/species/".concat(id) };
217
+ }
218
+ function makeWorkUri(id) {
219
+ return { '@id': "".concat(PREFIX, "catalog/").concat(id) };
220
+ }
221
+ function makeScientificNameUri(id) {
222
+ var resource = id.split(':').slice(0, -1).join(':');
223
+ return { '@id': "".concat(PREFIX, "resource/").concat(resource, "#").concat(id) };
224
+ }
225
+ function makeLinkedDataForAuthor(author) {
226
+ var node = {
227
+ '@id': "".concat(PREFIX, "author/").concat(author.get('id')),
228
+ '@type': 'foaf:Person',
229
+ 'foaf:name': author.get('display_name')
230
+ };
231
+ if (author.has('qid')) {
232
+ node['owl:sameAs'] = makeWikidataUri(author.get('qid'));
233
+ }
234
+ return node;
235
+ }
236
+ function makeLinkedDataForPlace(place) {
237
+ var node = {
238
+ '@id': "".concat(PREFIX, "place/").concat(place.get('id')),
239
+ '@type': 'dcterms:Location',
240
+ 'dcterms:title': place.get('display_name'),
241
+ };
242
+ if (place.has('qid')) {
243
+ node['owl:sameAs'] = makeWikidataUri(place.get('qid'));
244
+ }
245
+ return node;
246
+ }
247
+ function makeLinkedDataForPublisher(publisher) {
248
+ var node = {
249
+ '@id': "".concat(PREFIX, "author/").concat(publisher.get('id')),
250
+ '@type': 'foaf:Organization',
251
+ 'foaf:name': publisher.get('display_name')
252
+ };
253
+ if (publisher.has('qid')) {
254
+ node['owl:sameAs'] = makeWikidataUri(publisher.get('qid'));
255
+ }
256
+ return node;
257
+ }
258
+ function makeLinkedDataForTaxon(taxon) {
259
+ var node = {
260
+ '@id': "".concat(PREFIX, "taxon/").concat(taxon.get('id')),
261
+ '@type': 'dwc:Taxon',
262
+ 'dwc:scientificName': taxon.get('display_name'),
263
+ };
264
+ if (taxon.has('rank')) {
265
+ node['dwc:taxonRank'] = taxon.get('rank');
266
+ }
267
+ var ids = [];
268
+ if (taxon.has('qid')) {
269
+ ids.push(makeWikidataUri(taxon.get('qid')));
270
+ }
271
+ if (taxon.has('gbif')) {
272
+ ids.push(makeGbifUri(taxon.get('gbif')));
273
+ }
274
+ if (ids.length) {
275
+ node['owl:sameAs'] = ids;
276
+ }
277
+ return node;
278
+ }
279
+ function makeLinkedDataForTaxa(files) {
280
+ var _a;
281
+ var nodes = [];
282
+ var gbifTaxa = {};
283
+ for (var _i = 0, _b = files.taxa.entities; _i < _b.length; _i++) {
284
+ var taxon = _b[_i];
285
+ var node = makeLinkedDataForTaxon(taxon);
286
+ var ancestors = (_a = taxon.get('ancestors_gbif')) !== null && _a !== void 0 ? _a : [];
287
+ if (ancestors.length) {
288
+ node['dwc:parentNameUsageID'] = makeGbifUri(ancestors[ancestors.length - 1]);
289
+ }
290
+ else if (taxon.get('id') !== 'T141') {
291
+ node['dwc:parentNameUsageID'] = { '@id': "".concat(PREFIX, "taxon/T141") };
292
+ }
293
+ for (var i = 0; i < ancestors.length; i++) {
294
+ gbifTaxa[ancestors[i]] = __assign(__assign({}, makeGbifUri(ancestors[i])), { 'dwc:taxonRank': GBIF_RANKS[i], 'dwc:parentNameUsageID': i ? makeGbifUri(ancestors[i - 1]) : { '@id': "".concat(PREFIX, "taxon/T141") } });
295
+ }
296
+ if (taxon.has('children_gbif')) {
297
+ var children = taxon.get('children_gbif');
298
+ node['@reverse'] = { 'dwc:parentNameUsageID': children.map(makeGbifUri) };
299
+ var childRank = GBIF_RANKS[ancestors.length];
300
+ for (var _c = 0, children_1 = children; _c < children_1.length; _c++) {
301
+ var child = children_1[_c];
302
+ gbifTaxa[child] = __assign(__assign({}, makeGbifUri(child)), { 'dwc:taxonRank': childRank });
303
+ }
304
+ }
305
+ nodes.push(node);
306
+ }
307
+ nodes.push.apply(nodes, Object.values(gbifTaxa));
308
+ return nodes;
309
+ }
310
+ function makeLinkedDataForScientificName(name) {
311
+ var node = __assign(__assign({}, makeScientificNameUri(name.scientificNameID)), { '@type': 'dwc:Taxon' });
312
+ for (var field in DWC_FIELDS) {
313
+ var value = name[field];
314
+ if (value) {
315
+ node[DWC_FIELDS[field]] = value;
316
+ }
317
+ }
318
+ if (name.acceptedNameUsageID) {
319
+ node['dwc:acceptedNameUsageID'] = makeScientificNameUri(name.acceptedNameUsageID);
320
+ }
321
+ if (name.parentNameUsageID) {
322
+ node['dwc:parentNameUsageID'] = makeScientificNameUri(name.parentNameUsageID);
323
+ }
324
+ var identifiers = [];
325
+ if (name.gbifTaxonID) {
326
+ identifiers.push(makeGbifUri(name.gbifTaxonID));
327
+ }
328
+ if (name.colTaxonID) {
329
+ identifiers.push({ '@id': "https://www.checklistbank.org/dataset/309120/taxon/".concat(name.colTaxonID) });
330
+ }
331
+ if (identifiers.length) {
332
+ node['dwc:taxonID'] = identifiers;
333
+ }
334
+ return node;
335
+ }
336
+ function makeLinkedDataForResource(work, files, resourceId) {
337
+ var _a, _b, _c, _d, _e, _f, _g, _h;
338
+ var resource = new resource_1.WorkResource({});
339
+ if (!resourceId) {
340
+ resourceId = "".concat(work.get('id'), ":0");
341
+ }
342
+ if (files.resources[resourceId] && files.resources[resourceId].metadata.catalog) {
343
+ resource.fields = files.resources[resourceId].metadata.catalog;
344
+ }
345
+ if (!resource.has('language')) {
346
+ resource.fields.language = work.get('language');
347
+ }
348
+ var node = __assign(__assign({}, makeLinkedDataForWork(resource, files)), { '@id': "".concat(PREFIX, "resource/").concat(resourceId), '@type': 'bibo:DocumentPart' });
349
+ var types = (_b = (_a = resource.get('key_type')) !== null && _a !== void 0 ? _a : work.get('key_type')) !== null && _b !== void 0 ? _b : [];
350
+ if (types.includes('matrix')) {
351
+ node['dcterms:type'] = { '@id': 'http://purl.org/dc/dcmitype/Software' };
352
+ }
353
+ else if (types.includes('key') || types.includes('reference') || types.includes('supplement')) {
354
+ node['dcterms:type'] = { '@id': 'http://purl.org/dc/dcmitype/Text' };
355
+ }
356
+ else if (types.includes('gallery') || types.includes('collection')) {
357
+ node['dcterms:type'] = { '@id': 'http://purl.org/dc/dcmitype/Collection' };
358
+ }
359
+ if (types.includes('key') || types.includes('matrix')) {
360
+ node['ac:subtype'] = { '@id': 'http://rs.tdwg.org/acsubtype/values/IdentificationKey' };
361
+ }
362
+ var taxonNames = (_c = resource.get('taxon')) !== null && _c !== void 0 ? _c : work.get('taxon');
363
+ if (taxonNames) {
364
+ var taxa = mapEntities(taxonNames, files.taxa.entities);
365
+ var coveringTaxon = taxa.length ? getCoveringTaxon(taxa) : null;
366
+ if (coveringTaxon !== null) {
367
+ node['ac:taxonCoverage'] = { '@id': coveringTaxon };
368
+ }
369
+ node['dwc:taxonID'] = taxa.map(function (taxon) { return ({ '@id': "".concat(PREFIX, "taxon/").concat(taxon.get('id')) }); });
370
+ }
371
+ var scopes = (_d = resource.get('scope')) !== null && _d !== void 0 ? _d : work.get('scope');
372
+ if (scopes) {
373
+ for (var _i = 0, _j = scopes; _i < _j.length; _i++) {
374
+ var scope = _j[_i];
375
+ if (!SCOPES[scope]) {
376
+ console.error('Unmapped scope:', scope);
377
+ continue;
378
+ }
379
+ var _k = SCOPES[scope], property = _k[0], values = _k.slice(1);
380
+ if (!Array.isArray(node[property])) {
381
+ node[property] = [];
382
+ }
383
+ for (var _l = 0, values_1 = values; _l < values_1.length; _l++) {
384
+ var value = values_1[_l];
385
+ if (value.startsWith('http')) {
386
+ node[property].push({ '@id': value });
387
+ }
388
+ else {
389
+ node[property].push(value);
390
+ }
391
+ }
392
+ }
393
+ }
394
+ var region = (_e = resource.get('region')) !== null && _e !== void 0 ? _e : work.get('region');
395
+ if (region) {
396
+ var places = mapEntities(region, files.places.entities).map(function (place) { return ({ '@id': "".concat(PREFIX, "place/").concat(place.get('id')) }); });
397
+ node['dcterms:spatial'] = places;
398
+ }
399
+ var tags = [];
400
+ var taxonScopes = (_f = resource.get('taxon_scope')) !== null && _f !== void 0 ? _f : work.get('taxon_scope');
401
+ if (taxonScopes) {
402
+ tags.push.apply(tags, taxonScopes);
403
+ }
404
+ else if (((_g = resource.get('complete')) !== null && _g !== void 0 ? _g : work.get('complete')) === 'FALSE') {
405
+ tags.push('not intended to be complete');
406
+ }
407
+ var targetTaxa = (_h = resource.get('target_taxa')) !== null && _h !== void 0 ? _h : work.get('target_taxa');
408
+ if (targetTaxa) {
409
+ var first = targetTaxa.slice(0, -1).map(function (rank) { return rank + ','; });
410
+ var last = targetTaxa[targetTaxa.length - 1];
411
+ var list = first.length ? first.join('') + ' or ' + last : last;
412
+ tags.push("for identification to ".concat(list));
413
+ }
414
+ if (tags.length) {
415
+ node['ac:tag'] = tags;
416
+ }
417
+ if (files.resources[resourceId].taxa) {
418
+ var leafs = new Set(files.resources[resourceId].taxa.map(function (taxon) { return taxon.scientificNameID; }));
419
+ var taxa = [];
420
+ for (var _m = 0, _o = files.resources[resourceId].taxa; _m < _o.length; _m++) {
421
+ var taxon = _o[_m];
422
+ taxa.push(makeLinkedDataForScientificName(taxon));
423
+ if (taxon.parentNameUsageID) {
424
+ leafs.delete(taxon.parentNameUsageID);
425
+ }
426
+ }
427
+ node['dcterms:subject'] = taxa;
428
+ node['ac:taxonCount'] = leafs.size;
429
+ }
430
+ return node;
431
+ }
432
+ function makeLinkedDataForWork(work, files) {
433
+ var id = work.get('id');
434
+ var node = makeWorkUri(id);
435
+ var languages = work.get('language');
436
+ node['dcterms:language'] = languages.map(function (language) { return ({ '@id': "http://id.loc.gov/vocabulary/iso639-1/".concat(language) }); });
437
+ if (work.has('title')) {
438
+ var title = work.get('title');
439
+ node['dcterms:title'] = title.map(function (value, i) { return ({ '@value': value, '@lang': languages[i] }); });
440
+ }
441
+ if (work.has('pages') && work.get('pages').includes('-')) {
442
+ var containers = work.has('part_of') ? work.get('part_of').map(function (id) { return files.catalog.get(id); }) : [];
443
+ if (containers.find(function (container) { return container.get('entry_type') === 'online'; })) {
444
+ node['@type'] = 'bibo:BookSection';
445
+ }
446
+ else {
447
+ node['@type'] = 'bibo:AcademicArticle';
448
+ }
449
+ }
450
+ else if (work.get('entry_type') === 'online') {
451
+ node['@type'] = 'bibo:Website';
452
+ }
453
+ else {
454
+ node['@type'] = 'bibo:Book';
455
+ }
456
+ if (work.has('author')) {
457
+ var authors = mapEntities(work.get('author'), files.authors.entities).map(function (author) { return ({ '@id': "".concat(PREFIX, "author/").concat(author.get('id')) }); });
458
+ node['bibo:authorList'] = { '@list': authors };
459
+ node['dcterms:creator'] = authors;
460
+ }
461
+ if (work.has('url')) {
462
+ var urls = work.get('url');
463
+ var handle = urls.find(function (url) { return url.startsWith(HANDLE_PREFIX); });
464
+ if (handle) {
465
+ node['bibo:handle'] = handle.slice(HANDLE_PREFIX.length);
466
+ }
467
+ node['schema:url'] = urls.map(function (url) { return ({ '@id': url }); });
468
+ }
469
+ if (work.has('fulltext_url')) {
470
+ var urls = work.get('fulltext_url');
471
+ node['schema:encoding'] = urls.map(function (url) { return ({ '@type': 'schema:MediaObject', 'schema:contentUrl': { '@id': url } }); });
472
+ }
473
+ if (work.has('archive_url')) {
474
+ node['schema:archivedAt'] = work.get('archive_url').map(function (url) { return ({ '@id': url }); });
475
+ }
476
+ if (work.has('date')) {
477
+ node['dcterms:issued'] = work.get('date');
478
+ }
479
+ if (work.has('publisher')) {
480
+ var publishers = mapEntities(work.get('publisher'), files.publishers.entities).map(function (publisher) { return ({ '@id': "".concat(PREFIX, "publisher/").concat(publisher.get('id')) }); });
481
+ node['dcterms:publisher'] = publishers;
482
+ }
483
+ if (work.has('ISSN')) {
484
+ node['bibo:issn'] = work.get('ISSN');
485
+ }
486
+ if (work.has('ISBN')) {
487
+ var isbns = work.get('ISBN');
488
+ for (var _i = 0, isbns_1 = isbns; _i < isbns_1.length; _i++) {
489
+ var isbn = isbns_1[_i];
490
+ if (isbn.length === 13) {
491
+ node['bibo:isbn13'] = isbn;
492
+ }
493
+ else if (isbn.length === 10) {
494
+ node['bibo:isbn10'] = isbn;
495
+ }
496
+ else {
497
+ node['bibo:isbn'] = isbn;
498
+ }
499
+ }
500
+ }
501
+ if (work.has('QID')) {
502
+ node['bibo:uri'] = makeWikidataUri(work.get('QID'));
503
+ }
504
+ if (work.has('DOI')) {
505
+ node['bibo:doi'] = work.get('DOI');
506
+ }
507
+ if (work.has('volume')) {
508
+ node['bibo:volume'] = work.get('volume');
509
+ }
510
+ if (work.has('issue')) {
511
+ node['bibo:issue'] = work.get('issue');
512
+ }
513
+ if (work.has('pages')) {
514
+ var pages = work.get('pages');
515
+ var range = pages.split('-');
516
+ if (pages.match(/^\d+$/)) {
517
+ node['bibo:numPages'] = parseInt(pages);
518
+ }
519
+ else if (range.length === 2) {
520
+ node['bibo:pages'] = pages;
521
+ var _a = range.map(function (part) { return parseInt(part); }), start = _a[0], end = _a[1];
522
+ node['bibo:pageStart'] = start;
523
+ node['bibo:pageEnd'] = end;
524
+ node['bibo:numPages'] = end - start + 1;
525
+ }
526
+ else {
527
+ node['bibo:pages'] = pages;
528
+ }
529
+ }
530
+ if (work.has('edition')) {
531
+ node['bibo:edition'] = work.get('edition');
532
+ }
533
+ if (work.has('license')) {
534
+ var licenses = work.get('license');
535
+ node['dcterms:rights'] = licenses.map(function (license) {
536
+ if (license === '<public domain>' || license.match(/^<.+\?>$/)) {
537
+ return license.slice(1, -1);
538
+ }
539
+ else {
540
+ return { '@id': "https://spdx.org/licenses/".concat(license, ".html") };
541
+ }
542
+ });
543
+ }
544
+ return node;
545
+ }
546
+ function makeLinkedDataForWorks(files) {
547
+ var nodes = {};
548
+ var works = files.catalog;
549
+ for (var _i = 0, _a = works.entities; _i < _a.length; _i++) {
550
+ var work = _a[_i];
551
+ nodes[work.get('id')] = makeLinkedDataForWork(work, files);
552
+ }
553
+ var _loop_2 = function (work) {
554
+ var id = work.get('id');
555
+ var node = nodes[id];
556
+ var language = work.get('language');
557
+ if (work.has('part_of')) {
558
+ var containers = work.get('part_of');
559
+ if (work.get('key_type').includes('supplement')) {
560
+ node['bibo:annotates'] = containers.map(makeWorkUri);
561
+ }
562
+ else {
563
+ node['dcterms:isPartOf'] = containers.map(makeWorkUri);
564
+ for (var _d = 0, containers_1 = containers; _d < containers_1.length; _d++) {
565
+ var container = containers_1[_d];
566
+ if (!Array.isArray(nodes[container]['dcterms:hasPart'])) {
567
+ nodes[container]['dcterms:hasPart'] = [];
568
+ }
569
+ nodes[container]['dcterms:hasPart'].push(makeWorkUri(id));
570
+ }
571
+ }
572
+ }
573
+ if (work.has('listed_in')) {
574
+ var referers = work.get('listed_in');
575
+ node['bibo:citedBy'] = node['dcterms:isReferencedBy'] = referers.map(makeWorkUri);
576
+ for (var _e = 0, referers_1 = referers; _e < referers_1.length; _e++) {
577
+ var referer = referers_1[_e];
578
+ nodes[referer]['bibo:cites'] = nodes[referer]['dcterms:references'] = makeWorkUri(id);
579
+ }
580
+ }
581
+ if (work.has('version_of')) {
582
+ var originals = work.get('version_of');
583
+ var originalLanguages_1 = originals.map(function (id) { return works.get(id).get('language').join(); });
584
+ node['bibo:translationOf'] = originals.filter(function (_, i) { return originalLanguages_1[i] !== language.join(); }).map(makeWorkUri);
585
+ node['dcterms:isVersionOf'] = originals.map(makeWorkUri);
586
+ }
587
+ var resourceIndex = 1;
588
+ var resourceId = void 0;
589
+ while ((resourceId = "".concat(id, ":").concat(resourceIndex++)) in files.resources) {
590
+ var resource = makeLinkedDataForResource(work, files, resourceId);
591
+ if (!Array.isArray(node['dcterms:hasPart'])) {
592
+ node['dcterms:hasPart'] = [];
593
+ }
594
+ node['dcterms:hasPart'].push(resource);
595
+ if (!Array.isArray(resource['dcterms:isPartof'])) {
596
+ resource['dcterms:isPartof'] = [];
597
+ }
598
+ resource['dcterms:isPartof'].push({ '@id': node['@id'] });
599
+ }
600
+ };
601
+ for (var _b = 0, _c = works.entities; _b < _c.length; _b++) {
602
+ var work = _c[_b];
603
+ _loop_2(work);
604
+ }
605
+ return Object.values(nodes);
606
+ }
607
+ function writeOutput(document_1) {
608
+ return __awaiter(this, arguments, void 0, function (document, format) {
609
+ var nquads, parser, writer;
610
+ if (format === void 0) { format = 'jsonld'; }
611
+ return __generator(this, function (_a) {
612
+ switch (_a.label) {
613
+ case 0:
614
+ if (format === 'jsonld') {
615
+ process.stdout.write(JSON.stringify(document, null, 2));
616
+ return [2 /*return*/];
617
+ }
618
+ return [4 /*yield*/, jsonld.toRDF(document, { format: 'application/n-quads' })];
619
+ case 1:
620
+ nquads = _a.sent();
621
+ if (format === 'nquads') {
622
+ process.stdout.write(nquads);
623
+ return [2 /*return*/];
624
+ }
625
+ parser = new N3.StreamParser();
626
+ writer = new N3.StreamWriter({ prefixes: PREFIXES });
627
+ parser.write(nquads);
628
+ parser.pipe(writer);
629
+ writer.pipe(process.stdout);
630
+ return [2 /*return*/];
631
+ }
632
+ });
633
+ });
634
+ }
635
+ function main() {
636
+ return __awaiter(this, void 0, void 0, function () {
637
+ var args, directory, files, _i, SHEETS_1, sheet, filePath, file, resources, _a, _b, _loop_3, _c, _d, _e, _f, id, graph, _g, _h, entity, _j, _k, entity, _l, _m, entity, document;
638
+ return __generator(this, function (_o) {
639
+ switch (_o.label) {
640
+ case 0:
641
+ args = util.parseArgs({
642
+ allowPositionals: true,
643
+ options: {
644
+ format: {
645
+ type: 'string',
646
+ short: 'f',
647
+ default: 'jsonld',
648
+ }
649
+ },
650
+ });
651
+ directory = path.resolve(args.positionals[0]);
652
+ files = {};
653
+ _i = 0, SHEETS_1 = SHEETS;
654
+ _o.label = 1;
655
+ case 1:
656
+ if (!(_i < SHEETS_1.length)) return [3 /*break*/, 4];
657
+ sheet = SHEETS_1[_i];
658
+ filePath = path.join(directory, "".concat(sheet, ".csv"));
659
+ if (!(0, fs_1.existsSync)(filePath)) {
660
+ throw new Error("File \"".concat(sheet, ".csv\" must be provided"));
661
+ }
662
+ return [4 /*yield*/, fs_1.promises.readFile(filePath, 'utf8')];
663
+ case 2:
664
+ file = _o.sent();
665
+ files[sheet] = index_1.catalog.loadData(file, sheet);
666
+ _o.label = 3;
667
+ case 3:
668
+ _i++;
669
+ return [3 /*break*/, 1];
670
+ case 4:
671
+ files.resources = {};
672
+ _b = (_a = JSON).parse;
673
+ return [4 /*yield*/, fs_1.promises.readFile(path.join(directory, 'resources', 'index.json'), 'utf8')];
674
+ case 5:
675
+ resources = _b.apply(_a, [_o.sent()]);
676
+ _loop_3 = function (id) {
677
+ var filePath, file, _p, header, rows, taxa;
678
+ return __generator(this, function (_q) {
679
+ switch (_q.label) {
680
+ case 0:
681
+ filePath = path.join(directory, 'resources', 'dwc', id.split(':').join('-') + '.csv');
682
+ return [4 /*yield*/, fs_1.promises.readFile(filePath, 'utf8')];
683
+ case 1:
684
+ file = _q.sent();
685
+ _p = (0, csv_1.parseCsv)(file), header = _p[0], rows = _p.slice(1);
686
+ taxa = rows.map(function (row) { return row.reduce(function (object, value, index) {
687
+ object[header[index]] = value;
688
+ return object;
689
+ }, {}); });
690
+ files.resources[id] = { metadata: resources[id], taxa: taxa };
691
+ return [2 /*return*/];
692
+ }
693
+ });
694
+ };
695
+ _c = resources;
696
+ _d = [];
697
+ for (_e in _c)
698
+ _d.push(_e);
699
+ _f = 0;
700
+ _o.label = 6;
701
+ case 6:
702
+ if (!(_f < _d.length)) return [3 /*break*/, 9];
703
+ _e = _d[_f];
704
+ if (!(_e in _c)) return [3 /*break*/, 8];
705
+ id = _e;
706
+ return [5 /*yield**/, _loop_3(id)];
707
+ case 7:
708
+ _o.sent();
709
+ _o.label = 8;
710
+ case 8:
711
+ _f++;
712
+ return [3 /*break*/, 6];
713
+ case 9:
714
+ graph = __spreadArray(__spreadArray([], makeLinkedDataForWorks(files), true), makeLinkedDataForTaxa(files), true);
715
+ for (_g = 0, _h = files.authors.entities; _g < _h.length; _g++) {
716
+ entity = _h[_g];
717
+ graph.push(makeLinkedDataForAuthor(entity));
718
+ }
719
+ for (_j = 0, _k = files.places.entities; _j < _k.length; _j++) {
720
+ entity = _k[_j];
721
+ graph.push(makeLinkedDataForPlace(entity));
722
+ }
723
+ for (_l = 0, _m = files.publishers.entities; _l < _m.length; _l++) {
724
+ entity = _m[_l];
725
+ graph.push(makeLinkedDataForPublisher(entity));
726
+ }
727
+ document = {
728
+ '@context': PREFIXES,
729
+ '@graph': graph
730
+ };
731
+ writeOutput(document, args.values.format);
732
+ return [2 /*return*/];
733
+ }
734
+ });
735
+ });
736
+ }
737
+ main().catch(function (error) {
738
+ console.error(error);
739
+ process.exit(1);
740
+ });