linked-rolls 0.36.0 → 0.37.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.
- package/README.md +28 -1
- package/lib/EditionView.d.ts +2 -2
- package/lib/EditionView.js +2 -2
- package/lib/Feature.d.ts +46 -18
- package/lib/Feature.js +4 -2
- package/lib/RollCopy.d.ts +58 -26
- package/lib/RollCopy.js +26 -0
- package/lib/alignment.d.ts +2 -2
- package/lib/alignment.js +5 -4
- package/lib/asJsonLd.d.ts +5 -0
- package/lib/asJsonLd.js +55 -1
- package/lib/editionOps.d.ts +7 -5
- package/lib/editionOps.js +59 -30
- package/lib/importJsonLd.js +11 -1
- package/lib/migrate.js +103 -5
- package/lib/readers/phillipsEroll.js +1 -2
- package/lib/readers/spencerBar.js +2 -3
- package/lib/readers/stanfordAton.js +2 -3
- package/lib/reservations.js +2 -2
- package/lib/schema.json +390 -58
- package/lib/spec/context.json +31 -13
- package/package.json +1 -1
package/lib/editionOps.js
CHANGED
|
@@ -4,7 +4,7 @@ import { getAt } from "./EditionView";
|
|
|
4
4
|
import { isPerforation, placementRelations } from "./Symbol";
|
|
5
5
|
import { collationsOf, defaultCollationTolerance } from "./Collation";
|
|
6
6
|
import { collationToleranceOf, editsOf, insertedBy, principalDerivationOf } from "./Version";
|
|
7
|
-
import { asSymbols, barOf, isPaperStretch } from "./RollCopy";
|
|
7
|
+
import { asSymbols, barOf, featuresByAct, featuresOf, isPaperStretch, statesNothing } from "./RollCopy";
|
|
8
8
|
import { systemOf } from "./TrackerBar";
|
|
9
9
|
import { substitutionsBetween } from "./substitution";
|
|
10
10
|
import { trackerBarOf } from "./systems";
|
|
@@ -24,7 +24,7 @@ const onVersion = (versionId, op) => draft => {
|
|
|
24
24
|
op(version, draft);
|
|
25
25
|
};
|
|
26
26
|
const onFeature = (copyId, featureId, op) => onCopy(copyId, copy => {
|
|
27
|
-
const feature = copy.
|
|
27
|
+
const feature = featuresOf(copy).find(f => f.id === featureId);
|
|
28
28
|
if (feature)
|
|
29
29
|
op(feature);
|
|
30
30
|
});
|
|
@@ -82,7 +82,7 @@ export const createVersion = (copy) => draft => {
|
|
|
82
82
|
type: 'Version',
|
|
83
83
|
id: v4(),
|
|
84
84
|
system: systemOf(bar),
|
|
85
|
-
edits: asSymbols(copy
|
|
85
|
+
edits: asSymbols(featuresOf(copy), bar).map(insertion),
|
|
86
86
|
motivations: []
|
|
87
87
|
});
|
|
88
88
|
};
|
|
@@ -203,7 +203,7 @@ export const stateFeatureCondition = (copyId, featureId, condition) => onFeature
|
|
|
203
203
|
feature.condition = condition;
|
|
204
204
|
});
|
|
205
205
|
/** The ids of every feature the copy bears, those a patch bears among them. */
|
|
206
|
-
const featureIdsOf = (copy) => new Set(copy.
|
|
206
|
+
const featureIdsOf = (copy) => new Set(featuresOf(copy).flatMap(withBorneFeatures).map(feature => feature.id));
|
|
207
207
|
/**
|
|
208
208
|
* A symbol every carrier of which lies among the features loses its
|
|
209
209
|
* evidence with them. A symbol without carriers, such as a label,
|
|
@@ -279,26 +279,27 @@ const writeInto = (draft, before, after) => Object.entries(after).forEach(([key,
|
|
|
279
279
|
const isCopy = (record) => 'type' in record && record.type === 'RollCopy';
|
|
280
280
|
const isBelief = (record) => 'type' in record && record.type === 'belief';
|
|
281
281
|
const isComprehension = (reason) => reason.type === 'meaningComprehension';
|
|
282
|
-
/** What the modification names, be it as added or as removed. */
|
|
283
|
-
const membersOf = (modification) => modification.type === 'Addition' ? modification.added : modification.removed;
|
|
284
|
-
const namesNothing = (modification) => membersOf(modification).length === 0;
|
|
285
282
|
const comprehendsNothing = (reason) => isComprehension(reason) && reason.comprehends.length === 0;
|
|
286
|
-
/**
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
283
|
+
/**
|
|
284
|
+
* The modification with what it names rewritten, or the very same one
|
|
285
|
+
* where that leaves it as it was. Only a removal names anything by id:
|
|
286
|
+
* what an act produced or glued on it states itself.
|
|
287
|
+
*/
|
|
288
|
+
const renamingMembers = (rename) => (modification) => modification.type === 'Removal'
|
|
289
|
+
? replacing(modification, 'removed', rename(modification.removed))
|
|
290
|
+
: modification;
|
|
290
291
|
/** The reason with what a comprehension comprehends rewritten; any other reason names nothing of the kind. */
|
|
291
292
|
const renamingComprehended = (rename) => (reason) => isComprehension(reason) ? replacing(reason, 'comprehends', rename(reason.comprehends)) : reason;
|
|
292
293
|
/**
|
|
293
|
-
* The record with the ids it names rewritten: what a copy's
|
|
294
|
-
*
|
|
295
|
-
*
|
|
296
|
-
*
|
|
297
|
-
*
|
|
294
|
+
* The record with the ids it names rewritten: what a copy's removals
|
|
295
|
+
* removed, and what the comprehensions among a belief's reasons
|
|
296
|
+
* comprehend. A removal or a comprehension the rewriting emptied goes
|
|
297
|
+
* with what it named; one that named nothing before stays, as an edit
|
|
298
|
+
* that was empty before it does.
|
|
298
299
|
*/
|
|
299
300
|
const renaming = (rename) => (record) => {
|
|
300
301
|
if (isCopy(record)) {
|
|
301
|
-
return replacing(record, 'modifications', pruned(record.modifications, renamingMembers(rename),
|
|
302
|
+
return replacing(record, 'modifications', pruned(record.modifications, renamingMembers(rename), statesNothing));
|
|
302
303
|
}
|
|
303
304
|
if (isBelief(record)) {
|
|
304
305
|
return replacing(record, 'reasons', pruned(record.reasons, renamingComprehended(rename), comprehendsNothing));
|
|
@@ -356,16 +357,39 @@ const withoutBorne = (feature, named) => {
|
|
|
356
357
|
};
|
|
357
358
|
/** The features without those named, wherever they lie, and without whatever those bore. */
|
|
358
359
|
const withoutFeatures = (features, named) => mapped(without(features, feature => named.has(feature.id)), feature => withoutBorne(feature, named));
|
|
360
|
+
/** The act with its features rewritten, or the very same one where the rewriting left them. */
|
|
361
|
+
const rewritingAct = (rewrite) => (modification) => {
|
|
362
|
+
if (modification.type === 'Alteration')
|
|
363
|
+
return replacing(modification, 'produced', rewrite(modification.produced));
|
|
364
|
+
if (modification.type === 'Attachment')
|
|
365
|
+
return replacing(modification, 'added', rewrite(modification.added));
|
|
366
|
+
return modification;
|
|
367
|
+
};
|
|
368
|
+
/**
|
|
369
|
+
* Writes the rewriting onto the features of every act of the copy, and
|
|
370
|
+
* takes out an act it left with nothing to state.
|
|
371
|
+
*/
|
|
372
|
+
const rewriteFeatures = (copy, rewrite) => {
|
|
373
|
+
const state = stateOf(copy);
|
|
374
|
+
const produced = state.production?.produced;
|
|
375
|
+
if (produced && copy.production) {
|
|
376
|
+
const rewritten = rewrite(produced);
|
|
377
|
+
if (rewritten !== produced)
|
|
378
|
+
copy.production.produced = rewritten;
|
|
379
|
+
}
|
|
380
|
+
copy.modifications = pruned(state.modifications, rewritingAct(rewrite), statesNothing);
|
|
381
|
+
};
|
|
359
382
|
/**
|
|
360
383
|
* Takes the features off the copy, and out of the versions with what
|
|
361
384
|
* only they carried. A feature may be named wherever the copy bears it:
|
|
362
385
|
* a patch goes with everything glued onto it, and a feature of a patch
|
|
363
|
-
* may be taken back on its own, the patch staying where it is.
|
|
386
|
+
* may be taken back on its own, the patch staying where it is. An act
|
|
387
|
+
* left having produced or added nothing goes as well.
|
|
364
388
|
*/
|
|
365
389
|
export const removeFeatures = (copyId, featureIds) => onCopy(copyId, (copy, draft) => {
|
|
366
390
|
const named = new Set(featureIds);
|
|
367
|
-
const features = stateOf(copy
|
|
368
|
-
copy
|
|
391
|
+
const features = featuresOf(stateOf(copy));
|
|
392
|
+
rewriteFeatures(copy, (stated) => withoutFeatures(stated, named));
|
|
369
393
|
forgetFeatures(draft, new Set(goneWith(features, named)));
|
|
370
394
|
});
|
|
371
395
|
/**
|
|
@@ -445,9 +469,9 @@ const spanning = (features) => ({
|
|
|
445
469
|
* others being alike in all but their place. The depiction goes: a
|
|
446
470
|
* region of the scan showing one part depicts no more than that part.
|
|
447
471
|
*/
|
|
448
|
-
const mergedFrom = (features) => {
|
|
472
|
+
const mergedFrom = (features, id) => {
|
|
449
473
|
const stating = features.find(feature => feature.condition) ?? features[0];
|
|
450
|
-
const merged = { ...stating, id
|
|
474
|
+
const merged = { ...stating, id, horizontal: spanning(features) };
|
|
451
475
|
delete merged.depiction;
|
|
452
476
|
return merged;
|
|
453
477
|
};
|
|
@@ -485,24 +509,29 @@ const carryOver = (draft, replaced, mergedId) => {
|
|
|
485
509
|
* Only the features the copy bears itself are merged. A feature of a
|
|
486
510
|
* patch states no place along the roll of its own, so there is nothing
|
|
487
511
|
* for a merge to span, and an id naming one is passed over as an id the
|
|
488
|
-
* copy does not bear is.
|
|
512
|
+
* copy does not bear is. Features of two different acts are not merged
|
|
513
|
+
* either: one feature is the work of one act.
|
|
489
514
|
*
|
|
490
515
|
* Throws where the features cannot stand for one; `mergeObstacle`
|
|
491
516
|
* says beforehand whether they can.
|
|
492
517
|
*/
|
|
493
518
|
export const mergeFeatures = (copyId, featureIds) => onCopy(copyId, (copy, draft) => {
|
|
494
519
|
const named = new Set(featureIds);
|
|
495
|
-
const
|
|
496
|
-
const
|
|
497
|
-
const
|
|
520
|
+
const holds = (features) => features.some(feature => named.has(feature.id));
|
|
521
|
+
const acts = featuresByAct(stateOf(copy)).filter(holds);
|
|
522
|
+
const toMerge = (acts[0] ?? []).filter(feature => named.has(feature.id));
|
|
523
|
+
const obstacle = acts.length > 1 ? 'different-acts' : mergeObstacle(toMerge);
|
|
498
524
|
if (obstacle) {
|
|
499
525
|
throw new Error(`The features of copy ${copyId} cannot be merged: ${obstacle}`);
|
|
500
526
|
}
|
|
501
527
|
const replaced = new Set(toMerge.map(feature => feature.id));
|
|
502
|
-
const
|
|
503
|
-
copy
|
|
504
|
-
|
|
505
|
-
|
|
528
|
+
const mergedId = v4();
|
|
529
|
+
rewriteFeatures(copy, (stated) => {
|
|
530
|
+
const stands = (feature) => replaced.has(feature.id);
|
|
531
|
+
return stated.some(stands) ? standingFor(stated, stands, mergedFrom(stated.filter(stands), mergedId)) : stated;
|
|
532
|
+
});
|
|
533
|
+
carryOver(draft, replaced, mergedId);
|
|
534
|
+
renameReferences(draft, ids => standingFor(ids, id => replaced.has(id), mergedId));
|
|
506
535
|
});
|
|
507
536
|
/** The carriers of each collated symbol pass to its counterpart. */
|
|
508
537
|
const handOverCarriers = (view, draft, collations) => collations.forEach(({ symbol, counterpart }) => {
|
package/lib/importJsonLd.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { derivedKeys } from "./asJsonLd";
|
|
1
2
|
import { migrate } from "./migrate";
|
|
2
3
|
import { isDateString } from "./utils";
|
|
3
4
|
export const importDate = (str) => {
|
|
@@ -17,6 +18,15 @@ const fromJsonLdValue = (value) => {
|
|
|
17
18
|
return fromJsonLdEntity(value);
|
|
18
19
|
return value;
|
|
19
20
|
};
|
|
21
|
+
/**
|
|
22
|
+
* A node without what the export derived from it. A copy bears the
|
|
23
|
+
* features its acts brought about, and the graph has to be told so.
|
|
24
|
+
* In the edition the act that made a feature is the one place it
|
|
25
|
+
* stands.
|
|
26
|
+
*/
|
|
27
|
+
const asStated = (json) => Object.keys(json).some(key => derivedKeys.has(key))
|
|
28
|
+
? Object.fromEntries(Object.entries(json).filter(([key]) => !derivedKeys.has(key)))
|
|
29
|
+
: json;
|
|
20
30
|
/**
|
|
21
31
|
* An entity with its keywords read as plain keys. The input is left as
|
|
22
32
|
* it is. The `@type` of a value object names the datatype of the value,
|
|
@@ -25,7 +35,7 @@ const fromJsonLdValue = (value) => {
|
|
|
25
35
|
* rather than to the edition, which states the system as data.
|
|
26
36
|
*/
|
|
27
37
|
const fromJsonLdEntity = (json) => {
|
|
28
|
-
const { '@type': type, '@id': id, '@context': context, ...rest } = json;
|
|
38
|
+
const { '@type': type, '@id': id, '@context': context, ...rest } = asStated(json);
|
|
29
39
|
const entity = Object.fromEntries(Object.entries(rest).map(([key, value]) => [key, fromJsonLdValue(value)]));
|
|
30
40
|
if (type !== undefined && !('@value' in json))
|
|
31
41
|
entity.type = type;
|
package/lib/migrate.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { conditions } from "./Feature";
|
|
1
|
+
import { conditions, isFeatureType } from "./Feature";
|
|
2
2
|
import { rollConditions } from "./RollCopy";
|
|
3
3
|
import { systemIdIn, systemOf, translationBetween } from "./TrackerBar";
|
|
4
4
|
import { trackerBars } from "./systems";
|
|
@@ -12,6 +12,14 @@ const renamedKeys = {
|
|
|
12
12
|
classification: 'editType'
|
|
13
13
|
};
|
|
14
14
|
const referenceKeys = ['alignedWith', 'pairedWith', 'basedOn'];
|
|
15
|
+
/**
|
|
16
|
+
* The five type terms that were capitalised while the rest of the
|
|
17
|
+
* vocabulary was not, under the keys that carry them.
|
|
18
|
+
*/
|
|
19
|
+
const lowerCasedTerms = {
|
|
20
|
+
method: { Print: 'print', Handwriting: 'handwriting', Stamp: 'stamp' },
|
|
21
|
+
material: { Paper: 'paper', Tape: 'tape' }
|
|
22
|
+
};
|
|
15
23
|
const named = (name) => ({ name, sameAs: [] });
|
|
16
24
|
const withRenamedKeys = (node) => Object.keys(node).some(key => Object.hasOwn(renamedKeys, key))
|
|
17
25
|
? Object.fromEntries(Object.entries(node).map(([key, value]) => [renamedKeys[key] ?? key, value]))
|
|
@@ -32,6 +40,10 @@ const withoutVersionType = (node) => {
|
|
|
32
40
|
const { versionType: _retired, ...rest } = node;
|
|
33
41
|
return rest;
|
|
34
42
|
};
|
|
43
|
+
const withLowerCaseTerms = (node) => Object.entries(lowerCasedTerms).reduce((result, [key, terms]) => {
|
|
44
|
+
const lowered = terms[result[key]];
|
|
45
|
+
return lowered ? { ...result, [key]: lowered } : result;
|
|
46
|
+
}, node);
|
|
35
47
|
const withReferences = (node) => referenceKeys.reduce((result, key) => {
|
|
36
48
|
const reference = result[key];
|
|
37
49
|
if (reference && typeof reference === 'object' && '@value' in reference) {
|
|
@@ -79,15 +91,100 @@ const withScale = (node) => {
|
|
|
79
91
|
/** A derivation written as a single one, before a version could name several. */
|
|
80
92
|
const isSingleDerivation = (basedOn) => basedOn !== null && typeof basedOn === 'object' && !Array.isArray(basedOn);
|
|
81
93
|
const withDerivationList = (node) => isSingleDerivation(node.basedOn) ? { ...node, basedOn: [node.basedOn] } : node;
|
|
94
|
+
/** The features a copy states at a place of its own, in either shape. */
|
|
95
|
+
const featuresOf = (copy) => [
|
|
96
|
+
...(Array.isArray(copy.features) ? copy.features : []),
|
|
97
|
+
...(Array.isArray(copy.production?.produced) ? copy.production.produced : [])
|
|
98
|
+
];
|
|
82
99
|
/**
|
|
83
100
|
* A copy read on a roll reader was stated as a recording before a sound
|
|
84
101
|
* recording could be one. A sound recording gives no holes, so a recording
|
|
85
102
|
* with holes is a reading.
|
|
86
103
|
*/
|
|
87
|
-
const withReadingKind = (node) => node.readFrom?.kind === 'recording'
|
|
88
|
-
&& node.
|
|
104
|
+
const withReadingKind = (node) => node.readFrom?.kind === 'recording'
|
|
105
|
+
&& featuresOf(node).some((feature) => feature?.['@type'] === 'Hole')
|
|
89
106
|
? { ...node, readFrom: { ...node.readFrom, kind: 'reading' } }
|
|
90
107
|
: node;
|
|
108
|
+
/** A feature written while the kind of a feature was a type beside its class. */
|
|
109
|
+
const withoutFeatureKind = (node) => {
|
|
110
|
+
if (!isFeatureType(node['@type']) || !Object.hasOwn(node, 'kind'))
|
|
111
|
+
return node;
|
|
112
|
+
const { kind: _typed, ...rest } = node;
|
|
113
|
+
return rest;
|
|
114
|
+
};
|
|
115
|
+
const isPatch = (feature) => feature?.['@type'] === 'GluedOn';
|
|
116
|
+
/**
|
|
117
|
+
* A feature a patch bears was sometimes written without an id, and what
|
|
118
|
+
* has no id can be referred to from nowhere: neither by a reading of it
|
|
119
|
+
* nor by the statement that the copy bears it. It is named after the
|
|
120
|
+
* patch and the place it stands in.
|
|
121
|
+
*/
|
|
122
|
+
const withBorneFeaturesNamed = (node) => {
|
|
123
|
+
const bearer = node['@id'];
|
|
124
|
+
if (typeof bearer !== 'string' || !Array.isArray(node.features))
|
|
125
|
+
return node;
|
|
126
|
+
if (node.features.every((feature) => typeof feature?.['@id'] === 'string'))
|
|
127
|
+
return node;
|
|
128
|
+
return {
|
|
129
|
+
...node,
|
|
130
|
+
features: node.features.map((feature, index) => feature && typeof feature === 'object' && typeof feature['@id'] !== 'string'
|
|
131
|
+
? { '@id': `${bearer}-${index + 1}`, ...feature }
|
|
132
|
+
: feature)
|
|
133
|
+
};
|
|
134
|
+
};
|
|
135
|
+
/**
|
|
136
|
+
* A copy held its features in one list and a modification named by id
|
|
137
|
+
* what it had added. Each feature now stands in the act that brought it
|
|
138
|
+
* about: a patch in an attachment, a feature an act names in an
|
|
139
|
+
* alteration, and everything else in the production of the copy, which
|
|
140
|
+
* is the punching. An addition naming both a patch and a feature
|
|
141
|
+
* becomes two acts, since gluing something on and drawing something are
|
|
142
|
+
* not one act.
|
|
143
|
+
*
|
|
144
|
+
* A feature a patch bears is not moved: it has no place of its own, and
|
|
145
|
+
* it came onto the copy with the patch.
|
|
146
|
+
*/
|
|
147
|
+
const withFeaturesInActs = (node) => {
|
|
148
|
+
if (node['@type'] !== 'RollCopy' || !Array.isArray(node.features))
|
|
149
|
+
return node;
|
|
150
|
+
const { features, modifications, ...rest } = node;
|
|
151
|
+
const byId = new Map(features
|
|
152
|
+
.filter((feature) => typeof feature?.['@id'] === 'string')
|
|
153
|
+
.map((feature) => [feature['@id'], feature]));
|
|
154
|
+
const taken = new Set();
|
|
155
|
+
/** The features the modification named, each going to the first act that names it. */
|
|
156
|
+
const namedBy = (modification) => (Array.isArray(modification.added) ? modification.added : [])
|
|
157
|
+
.flatMap((id) => {
|
|
158
|
+
if (typeof id !== 'string' || taken.has(id) || !byId.has(id))
|
|
159
|
+
return [];
|
|
160
|
+
taken.add(id);
|
|
161
|
+
return [byId.get(id)];
|
|
162
|
+
});
|
|
163
|
+
const acts = (Array.isArray(modifications) ? modifications : []).flatMap((modification) => {
|
|
164
|
+
if (modification?.['@type'] !== 'Addition')
|
|
165
|
+
return [modification];
|
|
166
|
+
const { added: _named, ...act } = modification;
|
|
167
|
+
const held = namedBy(modification);
|
|
168
|
+
const glued = held.filter(isPatch);
|
|
169
|
+
const made = held.filter(feature => !isPatch(feature));
|
|
170
|
+
if (glued.length === 0)
|
|
171
|
+
return [{ ...act, '@type': 'Alteration', produced: made }];
|
|
172
|
+
return [
|
|
173
|
+
...(made.length > 0 ? [{ ...act, '@type': 'Alteration', produced: made }] : []),
|
|
174
|
+
{ ...act, '@type': 'Attachment', added: glued }
|
|
175
|
+
];
|
|
176
|
+
});
|
|
177
|
+
const left = features.filter((feature) => !taken.has(feature?.['@id']));
|
|
178
|
+
const punched = left.filter((feature) => !isPatch(feature));
|
|
179
|
+
const loose = left.filter(isPatch);
|
|
180
|
+
return {
|
|
181
|
+
...rest,
|
|
182
|
+
...((rest.production || punched.length > 0) && {
|
|
183
|
+
production: { ...rest.production, ...(punched.length > 0 && { produced: punched }) }
|
|
184
|
+
}),
|
|
185
|
+
modifications: [...acts, ...(loose.length > 0 ? [{ '@type': 'Attachment', added: loose }] : [])]
|
|
186
|
+
};
|
|
187
|
+
};
|
|
91
188
|
/** A keeper nobody could name was written as an empty one before a copy could leave it out. */
|
|
92
189
|
const withoutEmptyKeeper = (node) => {
|
|
93
190
|
if (node.keeper?.name !== '' || node.keeper.sameAs?.length)
|
|
@@ -106,8 +203,9 @@ const withTimeSpanDates = (node) => {
|
|
|
106
203
|
const { '@value': within, '@type': _typed, ...rest } = node;
|
|
107
204
|
return { ...rest, within };
|
|
108
205
|
};
|
|
109
|
-
const migrateNode = (node) => [withRenamedKeys, withTypology, withoutVersionType, withReferences, withKeeper, withoutEmptyKeeper,
|
|
110
|
-
withDerivationList, withReadingKind, withTimeSpanDates
|
|
206
|
+
const migrateNode = (node) => [withRenamedKeys, withTypology, withoutVersionType, withLowerCaseTerms, withReferences, withKeeper, withoutEmptyKeeper,
|
|
207
|
+
withProductionNodes, withScale, withDerivationList, withReadingKind, withTimeSpanDates, withoutFeatureKind,
|
|
208
|
+
withBorneFeaturesNamed, withFeaturesInActs]
|
|
111
209
|
.reduce((result, step) => step(result), node);
|
|
112
210
|
/** The items each walked, or the very same list where the walk changed none. */
|
|
113
211
|
const walked = (items) => {
|
|
@@ -148,9 +148,8 @@ export function readFromPhillipsEroll(buffer, { system = welteT100, controlOffse
|
|
|
148
148
|
ops: [],
|
|
149
149
|
conditions: [],
|
|
150
150
|
measurements: {},
|
|
151
|
-
production: { system: systemOf(system) },
|
|
151
|
+
production: { system: systemOf(system), produced: features },
|
|
152
152
|
modifications: [],
|
|
153
|
-
features,
|
|
154
153
|
readFrom: {
|
|
155
154
|
kind: 'reading',
|
|
156
155
|
actor: assignObject({ name: 'Phillips, Peter', sameAs: [] }),
|
|
@@ -114,9 +114,8 @@ export function readFromSpencerBar(buffer, { rowsPerInch = SPENCER_ROWS_PER_INCH
|
|
|
114
114
|
ops: [],
|
|
115
115
|
conditions: [],
|
|
116
116
|
measurements: {},
|
|
117
|
-
production: { system: systemOf(system) },
|
|
118
|
-
modifications: []
|
|
119
|
-
features
|
|
117
|
+
production: { system: systemOf(system), produced: features },
|
|
118
|
+
modifications: []
|
|
120
119
|
};
|
|
121
120
|
}
|
|
122
121
|
/**
|
|
@@ -157,7 +157,7 @@ export function readFromStanfordAton(atonString, { trackShift, system = welteT10
|
|
|
157
157
|
id: v4(),
|
|
158
158
|
ops: [],
|
|
159
159
|
conditions: [],
|
|
160
|
-
production: { system: systemOf(system) },
|
|
160
|
+
production: { system: systemOf(system), produced: features },
|
|
161
161
|
modifications: [],
|
|
162
162
|
...((scan ?? stanford) && { scan: scan ?? stanford?.scan }),
|
|
163
163
|
measurements: {
|
|
@@ -183,7 +183,6 @@ export function readFromStanfordAton(atonString, { trackShift, system = welteT10
|
|
|
183
183
|
}),
|
|
184
184
|
trackCalibration: calibration,
|
|
185
185
|
...(measuredBy && { measuredBy })
|
|
186
|
-
}
|
|
187
|
-
features
|
|
186
|
+
}
|
|
188
187
|
};
|
|
189
188
|
}
|
package/lib/reservations.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { bearsPhysicalEvidence, isMeasured, sourceLabels } from "./FeatureSource";
|
|
2
|
-
import { calibrationOf } from "./RollCopy";
|
|
2
|
+
import { calibrationOf, featuresOf } from "./RollCopy";
|
|
3
3
|
import { trackerBarOf } from "./systems";
|
|
4
4
|
import { witnessesOf } from "./witnesses";
|
|
5
5
|
export const reservationTypes = [
|
|
@@ -81,7 +81,7 @@ const keeperKnown = copy => copy.keeper ? undefined : {
|
|
|
81
81
|
note: 'Nobody is known to hold the copy, so its paper cannot be consulted.'
|
|
82
82
|
};
|
|
83
83
|
/** A check on what a copy's features leave open, which has nothing to say of a copy without any. */
|
|
84
|
-
const onFeatures = (check) => copy => copy.
|
|
84
|
+
const onFeatures = (check) => copy => featuresOf(copy).length > 0 ? check(copy) : undefined;
|
|
85
85
|
const checks = [
|
|
86
86
|
sourceStated,
|
|
87
87
|
sourceDocumented,
|