linked-rolls 0.56.0 → 0.58.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 +54 -361
- package/lib/{constraints.d.ts → analysis/constraints.d.ts} +1 -1
- package/lib/{constraints.js → analysis/constraints.js} +9 -8
- package/lib/analysis/ownPaper.d.ts +26 -0
- package/lib/analysis/ownPaper.js +41 -0
- package/lib/{reservations.d.ts → analysis/reservations.d.ts} +3 -3
- package/lib/{reservations.js → analysis/reservations.js} +3 -3
- package/lib/{sigla.d.ts → analysis/sigla.d.ts} +2 -2
- package/lib/{sigla.js → analysis/sigla.js} +4 -4
- package/lib/{witnesses.d.ts → analysis/witnesses.d.ts} +2 -2
- package/lib/{witnesses.js → analysis/witnesses.js} +4 -4
- package/lib/{Collation.d.ts → collation/Collation.d.ts} +4 -4
- package/lib/{Collation.js → collation/Collation.js} +4 -4
- package/lib/{alignment.d.ts → collation/alignment.d.ts} +4 -4
- package/lib/{alignment.js → collation/alignment.js} +10 -16
- package/lib/{scatter.d.ts → collation/scatter.d.ts} +4 -4
- package/lib/{scatter.js → collation/scatter.js} +6 -6
- package/lib/{statistics.d.ts → collation/statistics.d.ts} +1 -1
- package/lib/{statistics.js → collation/statistics.js} +2 -2
- package/lib/{substitution.d.ts → collation/substitution.d.ts} +9 -24
- package/lib/{substitution.js → collation/substitution.js} +13 -37
- package/lib/emulation/Emulation.d.ts +64 -0
- package/lib/emulation/Emulation.js +282 -0
- package/lib/emulation/negotiation.d.ts +14 -0
- package/lib/emulation/negotiation.js +20 -0
- package/lib/index.d.ts +43 -35
- package/lib/index.js +36 -35
- package/lib/{asJsonLd.d.ts → io/asJsonLd.d.ts} +1 -1
- package/lib/{asJsonLd.js → io/asJsonLd.js} +22 -51
- package/lib/{context.d.ts → io/context.d.ts} +4 -4
- package/lib/{context.js → io/context.js} +4 -4
- package/lib/{importJsonLd.d.ts → io/importJsonLd.d.ts} +1 -1
- package/lib/io/importJsonLd.js +128 -0
- package/lib/{migrate.d.ts → io/migrate.d.ts} +9 -0
- package/lib/{migrate.js → io/migrate.js} +97 -54
- package/lib/{Agent.d.ts → model/Agent.d.ts} +1 -1
- package/lib/{Assumption.d.ts → model/Assumption.d.ts} +1 -1
- package/lib/{ConditionState.d.ts → model/ConditionState.d.ts} +1 -2
- package/lib/{Edit.d.ts → model/Edit.d.ts} +1 -1
- package/lib/{Edition.d.ts → model/Edition.d.ts} +2 -2
- package/lib/{Feature.d.ts → model/Feature.d.ts} +3 -1
- package/lib/{Feature.js → model/Feature.js} +2 -0
- package/lib/{FeatureSource.d.ts → model/FeatureSource.d.ts} +1 -1
- package/lib/{Perforator.d.ts → model/Perforator.d.ts} +1 -1
- package/lib/{RollCopy.d.ts → model/RollCopy.d.ts} +5 -12
- package/lib/{RollCopy.js → model/RollCopy.js} +3 -5
- package/lib/{Symbol.d.ts → model/Symbol.d.ts} +1 -1
- package/lib/{Version.d.ts → model/Version.d.ts} +11 -3
- package/lib/{Version.js → model/Version.js} +24 -1
- package/lib/{vocabulary.js → model/vocabulary.js} +2 -2
- package/lib/ops/beliefs.d.ts +9 -0
- package/lib/ops/beliefs.js +31 -0
- package/lib/ops/collation.d.ts +62 -0
- package/lib/ops/collation.js +228 -0
- package/lib/ops/commands.d.ts +9 -0
- package/lib/ops/commands.js +29 -0
- package/lib/ops/copies.d.ts +74 -0
- package/lib/ops/copies.js +135 -0
- package/lib/ops/draft.d.ts +59 -0
- package/lib/ops/draft.js +81 -0
- package/lib/ops/edits.d.ts +10 -0
- package/lib/ops/edits.js +82 -0
- package/lib/ops/features.d.ts +84 -0
- package/lib/ops/features.js +296 -0
- package/lib/ops/forget.d.ts +31 -0
- package/lib/ops/forget.js +110 -0
- package/lib/ops/immutable.d.ts +16 -0
- package/lib/ops/immutable.js +46 -0
- package/lib/ops/index.d.ts +13 -0
- package/lib/ops/index.js +7 -0
- package/lib/ops/versions.d.ts +33 -0
- package/lib/ops/versions.js +95 -0
- package/lib/readers/AtonParser.js +5 -7
- package/lib/readers/phillipsEroll.d.ts +3 -3
- package/lib/readers/phillipsEroll.js +4 -5
- package/lib/readers/spencerBar.d.ts +2 -2
- package/lib/readers/spencerBar.js +2 -3
- package/lib/readers/stanfordAton.d.ts +3 -3
- package/lib/readers/stanfordAton.js +2 -4
- package/lib/schema.json +11 -151
- package/lib/spec/context.json +2 -12
- package/lib/{ReproducingSystem.d.ts → systems/ReproducingSystem.d.ts} +3 -3
- package/lib/{TrackerBar.d.ts → systems/TrackerBar.d.ts} +48 -8
- package/lib/{TrackerBar.js → systems/TrackerBar.js} +11 -2
- package/lib/systems/index.d.ts +8 -2
- package/lib/systems/index.js +7 -1
- package/lib/systems/welte.d.ts +100 -0
- package/lib/systems/welte.js +119 -0
- package/lib/systems/welteLicensee/bar.d.ts +1 -1
- package/lib/systems/welteLicensee/bar.js +5 -2
- package/lib/systems/welteLicensee/system.d.ts +1 -1
- package/lib/systems/welteLicensee/system.js +1 -1
- package/lib/systems/welteT100/bar.d.ts +27 -1
- package/lib/systems/welteT100/bar.js +44 -2
- package/lib/systems/welteT100/system.d.ts +6 -39
- package/lib/systems/welteT100/system.js +19 -128
- package/lib/systems/welteT98/bar.d.ts +1 -1
- package/lib/systems/welteT98/bar.js +18 -2
- package/lib/systems/welteT98/system.d.ts +20 -38
- package/lib/systems/welteT98/system.js +20 -121
- package/lib/validate.d.ts +1 -1
- package/lib/{EditionView.d.ts → view/EditionView.d.ts} +38 -48
- package/lib/{EditionView.js → view/EditionView.js} +90 -96
- package/package.json +7 -2
- package/lib/Emulation.d.ts +0 -36
- package/lib/Emulation.js +0 -250
- package/lib/editionOps.d.ts +0 -260
- package/lib/editionOps.js +0 -1081
- package/lib/importJsonLd.js +0 -62
- /package/lib/{Agent.js → model/Agent.js} +0 -0
- /package/lib/{Assumption.js → model/Assumption.js} +0 -0
- /package/lib/{ConditionState.js → model/ConditionState.js} +0 -0
- /package/lib/{Edit.js → model/Edit.js} +0 -0
- /package/lib/{Edition.js → model/Edition.js} +0 -0
- /package/lib/{FeatureSource.js → model/FeatureSource.js} +0 -0
- /package/lib/{Perforator.js → model/Perforator.js} +0 -0
- /package/lib/{Quantity.d.ts → model/Quantity.d.ts} +0 -0
- /package/lib/{Quantity.js → model/Quantity.js} +0 -0
- /package/lib/{Symbol.js → model/Symbol.js} +0 -0
- /package/lib/{TrackCalibration.d.ts → model/TrackCalibration.d.ts} +0 -0
- /package/lib/{TrackCalibration.js → model/TrackCalibration.js} +0 -0
- /package/lib/{notes.d.ts → model/notes.d.ts} +0 -0
- /package/lib/{notes.js → model/notes.js} +0 -0
- /package/lib/{procedures.d.ts → model/procedures.d.ts} +0 -0
- /package/lib/{procedures.js → model/procedures.js} +0 -0
- /package/lib/{vocabulary.d.ts → model/vocabulary.d.ts} +0 -0
- /package/lib/{sorted.d.ts → shared/sorted.d.ts} +0 -0
- /package/lib/{sorted.js → shared/sorted.js} +0 -0
- /package/lib/{utils.d.ts → shared/utils.d.ts} +0 -0
- /package/lib/{utils.js → shared/utils.js} +0 -0
- /package/lib/{ReproducingSystem.js → systems/ReproducingSystem.js} +0 -0
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import { derivedKeys } from "./asJsonLd.js";
|
|
2
|
+
import { migrate, plainCopyId } from "./migrate.js";
|
|
3
|
+
import { isDateString } from "../shared/utils.js";
|
|
4
|
+
import schema from "../schema.json" with { type: 'json' };
|
|
5
|
+
export const importDate = (str) => {
|
|
6
|
+
const [y, m, d] = str.split('-').map(s => parseInt(s, 10));
|
|
7
|
+
if ([y, m, d].some(n => isNaN(n))) {
|
|
8
|
+
throw new Error(`Invalid date format: "${str}". Expected "YYYY-MM-DD".`);
|
|
9
|
+
}
|
|
10
|
+
return new Date(y, m - 1, d);
|
|
11
|
+
};
|
|
12
|
+
/** The names of the properties the schema holds dates under, wherever they stand in it. */
|
|
13
|
+
const dateKeysIn = (node, keys = new Set()) => {
|
|
14
|
+
if (Array.isArray(node))
|
|
15
|
+
node.forEach(item => dateKeysIn(item, keys));
|
|
16
|
+
else if (node !== null && typeof node === 'object') {
|
|
17
|
+
Object.entries(node).forEach(([key, value]) => {
|
|
18
|
+
if (key === 'properties' && value !== null && typeof value === 'object') {
|
|
19
|
+
Object.entries(value)
|
|
20
|
+
.filter(([, property]) => property?.format === 'date')
|
|
21
|
+
.forEach(([name]) => keys.add(name));
|
|
22
|
+
}
|
|
23
|
+
dateKeysIn(value, keys);
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
return keys;
|
|
27
|
+
};
|
|
28
|
+
/**
|
|
29
|
+
* The keys a date is read under. Only these: a string elsewhere that
|
|
30
|
+
* happens to read like a date, such as the transcription of a dated
|
|
31
|
+
* label, is text and stays text.
|
|
32
|
+
*/
|
|
33
|
+
const dateKeys = dateKeysIn(schema);
|
|
34
|
+
/** A value as the edition holds it under the key: a date read, an entity converted, anything else as it stands. */
|
|
35
|
+
const fromJsonLdValue = (key, value) => {
|
|
36
|
+
if (typeof value === 'string')
|
|
37
|
+
return dateKeys.has(key) && isDateString(value) ? importDate(value) : value;
|
|
38
|
+
if (Array.isArray(value))
|
|
39
|
+
return value.map(item => fromJsonLdValue(key, item));
|
|
40
|
+
if (value !== null && typeof value === 'object')
|
|
41
|
+
return fromJsonLdEntity(value);
|
|
42
|
+
return value;
|
|
43
|
+
};
|
|
44
|
+
/** A node without what the export derived from it: what an act changed follows from where the act stands. */
|
|
45
|
+
const asStated = (json) => Object.keys(json).some(key => derivedKeys.has(key))
|
|
46
|
+
? Object.fromEntries(Object.entries(json).filter(([key]) => !derivedKeys.has(key)))
|
|
47
|
+
: json;
|
|
48
|
+
/**
|
|
49
|
+
* An entity with its keywords read as plain keys. The input is left as
|
|
50
|
+
* it is. The `@type` of a value object names the datatype of the value,
|
|
51
|
+
* not a class, and is dropped. So is a context: a version carries one
|
|
52
|
+
* naming its system's vocabulary, and it belongs to the serialisation
|
|
53
|
+
* rather than to the edition, which states the system as data.
|
|
54
|
+
*/
|
|
55
|
+
const fromJsonLdEntity = (json) => {
|
|
56
|
+
const { '@type': type, '@id': id, '@context': context, ...rest } = asStated(json);
|
|
57
|
+
const entity = Object.fromEntries(Object.entries(rest).map(([key, value]) => [key, fromJsonLdValue(key, value)]));
|
|
58
|
+
if (type !== undefined && !('@value' in json))
|
|
59
|
+
entity.type = type;
|
|
60
|
+
if (id !== undefined)
|
|
61
|
+
entity.id = id;
|
|
62
|
+
return entity;
|
|
63
|
+
};
|
|
64
|
+
// Every entity is named by its id alone. Documents written before that was so
|
|
65
|
+
// prefixed a copy's with `copy/`, and are read here as though they had not.
|
|
66
|
+
const withPlainCopyIds = (json) => ({
|
|
67
|
+
...json,
|
|
68
|
+
copies: (json.copies ?? []).map((copy) => ({
|
|
69
|
+
...copy,
|
|
70
|
+
'@id': typeof copy['@id'] === 'string' ? plainCopyId(copy['@id']) : copy['@id']
|
|
71
|
+
}))
|
|
72
|
+
});
|
|
73
|
+
/** A statement an export quoted rather than stated: an included node whose id is a triple. */
|
|
74
|
+
const isQuotedStatement = (node) => node !== null && typeof node === 'object' && node['@id'] !== null && typeof node['@id'] === 'object';
|
|
75
|
+
/** The reference a quoted statement made, annotated again with the belief the export set beside it. */
|
|
76
|
+
const referenceOf = (statement) => {
|
|
77
|
+
const { '@id': { '@id': subject, ...made }, annotation, ...about } = statement;
|
|
78
|
+
const [key, value] = Object.entries(made)[0];
|
|
79
|
+
const listed = Array.isArray(value);
|
|
80
|
+
return {
|
|
81
|
+
subject,
|
|
82
|
+
key,
|
|
83
|
+
listed,
|
|
84
|
+
reference: {
|
|
85
|
+
...(listed ? value[0] : value),
|
|
86
|
+
'@annotation': { ...(annotation !== undefined && { '@id': annotation }), ...about }
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
};
|
|
90
|
+
/** Whether the object states anything beside its id, which a reference to a node does not. */
|
|
91
|
+
const isNode = (value) => typeof value['@id'] === 'string' && Object.keys(value).some(key => key !== '@id' && key !== '@annotation');
|
|
92
|
+
/** The document with each quoted reference back on the node that makes it. */
|
|
93
|
+
const withReferencesOn = (value, bySubject) => {
|
|
94
|
+
if (Array.isArray(value))
|
|
95
|
+
return value.map(item => withReferencesOn(item, bySubject));
|
|
96
|
+
if (!value || typeof value !== 'object')
|
|
97
|
+
return value;
|
|
98
|
+
const walked = Object.fromEntries(Object.entries(value).map(([key, child]) => [key, withReferencesOn(child, bySubject)]));
|
|
99
|
+
const references = isNode(value)
|
|
100
|
+
? bySubject.get(value['@id']) ?? []
|
|
101
|
+
: [];
|
|
102
|
+
return references.reduce((node, { key, listed, reference }) => ({ ...node, [key]: listed ? [...(node[key] ?? []), reference] : reference }), walked);
|
|
103
|
+
};
|
|
104
|
+
/**
|
|
105
|
+
* Puts back what an export quoted. A reference the edition doubts goes
|
|
106
|
+
* out as a JSON-LD-star embedded node beside the document, so that RDF
|
|
107
|
+
* does not state it; in the edition it belongs on the node that makes
|
|
108
|
+
* it, under its belief. In a list it comes back after the references
|
|
109
|
+
* that were stated.
|
|
110
|
+
*/
|
|
111
|
+
const withQuotedStatementsInPlace = (edition) => {
|
|
112
|
+
const included = Array.isArray(edition['@included']) ? edition['@included'] : [];
|
|
113
|
+
const statements = included.filter(isQuotedStatement);
|
|
114
|
+
if (statements.length === 0)
|
|
115
|
+
return edition;
|
|
116
|
+
const others = included.filter(node => !isQuotedStatement(node));
|
|
117
|
+
const { '@included': _quoted, ...rest } = edition;
|
|
118
|
+
const bySubject = Map.groupBy(statements.map(referenceOf), ({ subject }) => subject);
|
|
119
|
+
return withReferencesOn({ ...rest, ...(others.length > 0 && { '@included': others }) }, bySubject);
|
|
120
|
+
};
|
|
121
|
+
export const importJsonLd = (json) => {
|
|
122
|
+
const { '@context': context, formatVersion: _revision, ...document } = withPlainCopyIds(migrate(withQuotedStatementsInPlace(json)));
|
|
123
|
+
const edition = fromJsonLdEntity(document);
|
|
124
|
+
edition.base = Array.isArray(context)
|
|
125
|
+
? context.find((c) => c['@base'])?.['@base'] || ''
|
|
126
|
+
: '';
|
|
127
|
+
return edition;
|
|
128
|
+
};
|
|
@@ -13,5 +13,14 @@
|
|
|
13
13
|
type Json = any;
|
|
14
14
|
/** A copy's id without the `copy/` that documents of earlier releases put before it. */
|
|
15
15
|
export declare const plainCopyId: (id: string) => string;
|
|
16
|
+
/**
|
|
17
|
+
* The revision of the format this release writes, stated in every export
|
|
18
|
+
* as `formatVersion`. A document stating it is in the current shape and
|
|
19
|
+
* passes through untouched; one stating none was written before the
|
|
20
|
+
* revisions were numbered and is brought up by recognising its shapes.
|
|
21
|
+
* A step added later is to run on the documents of the revisions before
|
|
22
|
+
* it, and to raise this number.
|
|
23
|
+
*/
|
|
24
|
+
export declare const formatVersion = 1;
|
|
16
25
|
export declare const migrate: (edition: Json) => Json;
|
|
17
26
|
export {};
|
|
@@ -1,11 +1,24 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import { welteT100 } from "./systems/welteT100/bar.js";
|
|
6
|
-
import { isDateString } from "./utils.js";
|
|
1
|
+
import { systemIdIn, systemOf, translationBetween } from "../systems/TrackerBar.js";
|
|
2
|
+
import { trackerBars } from "../systems/index.js";
|
|
3
|
+
import { welteT100 } from "../systems/welteT100/bar.js";
|
|
4
|
+
import { isDateString } from "../shared/utils.js";
|
|
7
5
|
const retiredVersionTypes = new Set(['edition', 'unicum']);
|
|
8
|
-
|
|
6
|
+
/**
|
|
7
|
+
* The vocabulary the steps below were written against, as it stood when
|
|
8
|
+
* the format was first given a revision number. It is copied here rather
|
|
9
|
+
* than imported from the model, so that changing today's vocabulary
|
|
10
|
+
* cannot change how an old document is read. The tracker bars are still
|
|
11
|
+
* asked, being the layout of instruments rather than a choice of the
|
|
12
|
+
* format.
|
|
13
|
+
*/
|
|
14
|
+
const conditionTypeValues = new Set([
|
|
15
|
+
'general', 'paper-stretch',
|
|
16
|
+
'partially-torn', 'missing-perforation', 'illegible', 'faded', 'detaching', 'ripped'
|
|
17
|
+
]);
|
|
18
|
+
const techniques = ['print', 'handwriting', 'stamp'];
|
|
19
|
+
const media = ['ink', 'pencil', 'crayon'];
|
|
20
|
+
const featureTypes = ['HoleChain', 'Writing', 'Mark', 'Patch'];
|
|
21
|
+
const isFeatureType = (value) => typeof value === 'string' && featureTypes.includes(value);
|
|
9
22
|
const renamedKeys = {
|
|
10
23
|
productionEvent: 'production',
|
|
11
24
|
annotates: 'depiction',
|
|
@@ -128,6 +141,38 @@ const withScale = (node) => {
|
|
|
128
141
|
const factor = (node.conditions ?? []).find(isPaperStretch)?.factor;
|
|
129
142
|
return factor === undefined ? node : { ...node, measurements: { ...node.measurements, scale: factor } };
|
|
130
143
|
};
|
|
144
|
+
/**
|
|
145
|
+
* What each entry of a copy's former `ops` list stands for among its
|
|
146
|
+
* measurements, and the value that does nothing where the list claimed
|
|
147
|
+
* an act whose amount was never recorded.
|
|
148
|
+
*/
|
|
149
|
+
const opsInMeasurements = [
|
|
150
|
+
['shifted', 'shift', { horizontal: 0, vertical: 0 }],
|
|
151
|
+
['stretched', 'scale', 1],
|
|
152
|
+
['shortened', 'readerExtension', { length: 0 }]
|
|
153
|
+
];
|
|
154
|
+
/**
|
|
155
|
+
* A copy listed what had been done to line its features up, which said
|
|
156
|
+
* again what its measurements state; the measurements now say it alone.
|
|
157
|
+
* Where the two disagreed, the list is what the alignment went by, so
|
|
158
|
+
* the measurements are made to say what it said: a measurement it does
|
|
159
|
+
* not list is dropped, and an act it lists without a recorded amount is
|
|
160
|
+
* recorded as one that moved nothing. `withScale` has read the list by
|
|
161
|
+
* the time this runs.
|
|
162
|
+
*/
|
|
163
|
+
const withoutOps = (node) => {
|
|
164
|
+
if (!Array.isArray(node.ops))
|
|
165
|
+
return node;
|
|
166
|
+
const { ops, ...rest } = node;
|
|
167
|
+
const measurements = { ...rest.measurements };
|
|
168
|
+
opsInMeasurements.forEach(([op, key, nothing]) => {
|
|
169
|
+
if (!ops.includes(op))
|
|
170
|
+
delete measurements[key];
|
|
171
|
+
else if (measurements[key] === undefined)
|
|
172
|
+
measurements[key] = nothing;
|
|
173
|
+
});
|
|
174
|
+
return { ...rest, measurements };
|
|
175
|
+
};
|
|
131
176
|
/** A copy's id without the `copy/` that documents of earlier releases put before it. */
|
|
132
177
|
export const plainCopyId = (id) => id.replace(/^copy\//, '');
|
|
133
178
|
/**
|
|
@@ -156,7 +201,6 @@ const withPerforator = (node) => {
|
|
|
156
201
|
perforator: {
|
|
157
202
|
...perforator,
|
|
158
203
|
condition: {
|
|
159
|
-
'@type': 'ConditionState',
|
|
160
204
|
conditionType: 'setting',
|
|
161
205
|
...perforator.condition,
|
|
162
206
|
punchDiameter: diameter
|
|
@@ -196,6 +240,22 @@ const withoutPattern = (node) => {
|
|
|
196
240
|
const { pattern: _moved, ...rest } = node;
|
|
197
241
|
return rest;
|
|
198
242
|
};
|
|
243
|
+
/** A version and a condition state once stated their class, which the key they stand under entails. */
|
|
244
|
+
const withoutEntailedType = (node) => {
|
|
245
|
+
if (node['@type'] !== 'Version' && node['@type'] !== 'ConditionState')
|
|
246
|
+
return node;
|
|
247
|
+
const { '@type': _entailed, ...rest } = node;
|
|
248
|
+
return rest;
|
|
249
|
+
};
|
|
250
|
+
/** An export once stated what a copy or a patch bears, which a reasoner now derives from the acts. */
|
|
251
|
+
const withoutBearings = (node) => {
|
|
252
|
+
if (!Object.hasOwn(node, 'bears') && !Object.hasOwn(node, 'composedOf'))
|
|
253
|
+
return node;
|
|
254
|
+
if (node['@type'] !== 'RollCopy' && node['@type'] !== 'Patch')
|
|
255
|
+
return node;
|
|
256
|
+
const { bears: _bears, composedOf: _composedOf, ...rest } = node;
|
|
257
|
+
return rest;
|
|
258
|
+
};
|
|
199
259
|
/** A derivation written as a single one, before a version could name several. */
|
|
200
260
|
const isSingleDerivation = (basedOn) => basedOn !== null && typeof basedOn === 'object' && !Array.isArray(basedOn);
|
|
201
261
|
const withDerivationList = (node) => isSingleDerivation(node.basedOn) ? { ...node, basedOn: [node.basedOn] } : node;
|
|
@@ -312,8 +372,8 @@ const withTimeSpanDates = (node) => {
|
|
|
312
372
|
return { ...rest, within };
|
|
313
373
|
};
|
|
314
374
|
const migrateNode = (node) => [withRenamedKeys, withTypology, withRenamedType, withoutVersionType, withoutVersionSiglum, withLowerCaseTerms, withSplitMethod, withReferences, withKeeper, withoutEmptyKeeper,
|
|
315
|
-
withPerforator, withProductionNodes, withTypedPerforator, withScale, withDerivationList, withReadingKind, withTimeSpanDates,
|
|
316
|
-
withoutFeatureKind, withBorneFeaturesNamed, withFeaturesInActs, withDriveOfStaggering, withoutPattern]
|
|
375
|
+
withPerforator, withProductionNodes, withTypedPerforator, withScale, withoutOps, withDerivationList, withReadingKind, withTimeSpanDates,
|
|
376
|
+
withoutFeatureKind, withBorneFeaturesNamed, withFeaturesInActs, withDriveOfStaggering, withoutPattern, withoutBearings, withoutEntailedType]
|
|
317
377
|
.reduce((result, step) => step(result), node);
|
|
318
378
|
/** The items each walked, or the very same list where the walk changed none. */
|
|
319
379
|
const walked = (items) => {
|
|
@@ -390,6 +450,13 @@ const onOwnBar = (copy, rollSystem) => {
|
|
|
390
450
|
* roll that named no system was a T-100 roll, and the text a copy's
|
|
391
451
|
* production gave for it is kept as the system's name.
|
|
392
452
|
*/
|
|
453
|
+
/** An export once stated the class of the edition, which R17i was created by entails. */
|
|
454
|
+
const withoutEditionType = (edition) => {
|
|
455
|
+
if (edition['@type'] !== 'Edition')
|
|
456
|
+
return edition;
|
|
457
|
+
const { '@type': _entailed, ...rest } = edition;
|
|
458
|
+
return rest;
|
|
459
|
+
};
|
|
393
460
|
const withSystems = (edition) => {
|
|
394
461
|
if (!edition.roll || !namesSystemOnTheRoll(edition))
|
|
395
462
|
return edition;
|
|
@@ -444,51 +511,27 @@ const withDerivationTolerance = (edition) => {
|
|
|
444
511
|
: version)
|
|
445
512
|
};
|
|
446
513
|
};
|
|
447
|
-
|
|
448
|
-
const isQuotedStatement = (node) => node !== null && typeof node === 'object' && node['@id'] !== null && typeof node['@id'] === 'object';
|
|
449
|
-
/** The reference a quoted statement made, annotated again with the belief the export set beside it. */
|
|
450
|
-
const referenceOf = (statement) => {
|
|
451
|
-
const { '@id': { '@id': subject, ...made }, annotation, ...about } = statement;
|
|
452
|
-
const [key, value] = Object.entries(made)[0];
|
|
453
|
-
const listed = Array.isArray(value);
|
|
454
|
-
return {
|
|
455
|
-
subject,
|
|
456
|
-
key,
|
|
457
|
-
listed,
|
|
458
|
-
reference: {
|
|
459
|
-
...(listed ? value[0] : value),
|
|
460
|
-
'@annotation': { ...(annotation !== undefined && { '@id': annotation }), ...about }
|
|
461
|
-
}
|
|
462
|
-
};
|
|
463
|
-
};
|
|
464
|
-
/** The document with each quoted reference back on the node that makes it, a node being what has a type. */
|
|
465
|
-
const withReferencesOn = (value, bySubject) => {
|
|
466
|
-
if (Array.isArray(value))
|
|
467
|
-
return value.map(item => withReferencesOn(item, bySubject));
|
|
468
|
-
if (!value || typeof value !== 'object')
|
|
469
|
-
return value;
|
|
470
|
-
const walked = Object.fromEntries(Object.entries(value).map(([key, child]) => [key, withReferencesOn(child, bySubject)]));
|
|
471
|
-
const references = typeof value['@id'] === 'string' && value['@type'] !== undefined
|
|
472
|
-
? bySubject.get(value['@id']) ?? []
|
|
473
|
-
: [];
|
|
474
|
-
return references.reduce((node, { key, listed, reference }) => ({ ...node, [key]: listed ? [...(node[key] ?? []), reference] : reference }), walked);
|
|
475
|
-
};
|
|
514
|
+
const editionSteps = [withoutEditionType, withSystems, withEditors, withDerivationTolerance];
|
|
476
515
|
/**
|
|
477
|
-
*
|
|
478
|
-
*
|
|
479
|
-
*
|
|
480
|
-
*
|
|
481
|
-
*
|
|
516
|
+
* The revision of the format this release writes, stated in every export
|
|
517
|
+
* as `formatVersion`. A document stating it is in the current shape and
|
|
518
|
+
* passes through untouched; one stating none was written before the
|
|
519
|
+
* revisions were numbered and is brought up by recognising its shapes.
|
|
520
|
+
* A step added later is to run on the documents of the revisions before
|
|
521
|
+
* it, and to raise this number.
|
|
482
522
|
*/
|
|
483
|
-
const
|
|
484
|
-
|
|
485
|
-
const
|
|
486
|
-
if (
|
|
523
|
+
export const formatVersion = 1;
|
|
524
|
+
export const migrate = (edition) => {
|
|
525
|
+
const stated = edition?.formatVersion;
|
|
526
|
+
if (stated === formatVersion)
|
|
487
527
|
return edition;
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
528
|
+
if (typeof stated === 'number' && stated > formatVersion) {
|
|
529
|
+
throw new Error(`The document is written in revision ${stated} of the format, which this release, reading up to ${formatVersion}, does not know`);
|
|
530
|
+
}
|
|
531
|
+
const current = walk(editionSteps.reduce((result, step) => step(result), edition));
|
|
532
|
+
// What comes out is in the current revision and says so, so that it
|
|
533
|
+
// passes through untouched when it is migrated again.
|
|
534
|
+
return current !== null && typeof current === 'object' && !Array.isArray(current)
|
|
535
|
+
? { ...current, formatVersion }
|
|
536
|
+
: current;
|
|
492
537
|
};
|
|
493
|
-
const editionSteps = [withQuotedStatementsInPlace, withSystems, withEditors, withDerivationTolerance];
|
|
494
|
-
export const migrate = (edition) => walk(editionSteps.reduce((result, step) => step(result), edition));
|
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
import { WithType } from "./utils.js";
|
|
2
1
|
/**
|
|
3
2
|
* Physical condition of a roll or
|
|
4
3
|
* of a feature on the roll (e.g. a damaged
|
|
5
4
|
* or unsuccessful perforation).
|
|
6
5
|
* @see crm:E3 Condition State
|
|
7
6
|
*/
|
|
8
|
-
export interface ConditionState<T extends string>
|
|
7
|
+
export interface ConditionState<T extends string> {
|
|
9
8
|
/**
|
|
10
9
|
* The kind of condition, from the list the roll or
|
|
11
10
|
* the kind of feature allows.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Assumption } from "./Assumption.js";
|
|
2
2
|
import { AnySymbol } from "./Symbol.js";
|
|
3
|
-
import { WithId } from "
|
|
3
|
+
import { WithId } from "../shared/utils.js";
|
|
4
4
|
export declare const editTypes: readonly [
|
|
5
5
|
/**
|
|
6
6
|
* An additional accent that can only be encoded with
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { RollCopy } from "./RollCopy.js";
|
|
2
2
|
import { Version } from "./Version.js";
|
|
3
|
-
import { CollationTolerance } from "
|
|
3
|
+
import { CollationTolerance } from "../collation/Collation.js";
|
|
4
4
|
import { DateAssignment, ObjectAssumption } from "./Assumption.js";
|
|
5
5
|
import { Editor, Person, Place } from "./Agent.js";
|
|
6
|
-
import { RollTempo } from "
|
|
6
|
+
import { RollTempo } from "../systems/ReproducingSystem.js";
|
|
7
7
|
/**
|
|
8
8
|
* This type describes the creation of an edition,
|
|
9
9
|
* i.e. the editor, publisher, and publication date.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { ObjectAssumption } from "./Assumption.js";
|
|
2
2
|
import { ConditionState } from "./ConditionState.js";
|
|
3
3
|
import { Text } from "./Symbol.js";
|
|
4
|
-
import { PartialBy, WithId, WithType } from "
|
|
4
|
+
import { PartialBy, WithId, WithType } from "../shared/utils.js";
|
|
5
5
|
import { Measure, Millimeters, Track } from "./Quantity.js";
|
|
6
6
|
/**
|
|
7
7
|
* Describes the horizontal extent of a feature on the roll,
|
|
@@ -238,6 +238,8 @@ type Unplaced<T> = T extends FeatureOrPatch ? PartialBy<T, 'horizontal' | 'verti
|
|
|
238
238
|
* the feature bearing it standing in one.
|
|
239
239
|
*/
|
|
240
240
|
export type NestedFeature = Unplaced<FeatureOrPatch>;
|
|
241
|
+
/** Whether the feature states a place of its own, which one a patch bears does not. */
|
|
242
|
+
export declare const isPlaced: (feature: NestedFeature) => feature is FeatureOrPatch;
|
|
241
243
|
export declare const isRollFeature: (obj: object) => obj is FeatureOrPatch;
|
|
242
244
|
export declare const isPatch: <T extends NestedFeature>(feature: T) => feature is T & Patch;
|
|
243
245
|
/** The features a feature bears: a patch those stated as parts of it, any other feature none. */
|
|
@@ -8,6 +8,8 @@ export const conditions = {
|
|
|
8
8
|
};
|
|
9
9
|
export const techniques = ['print', 'handwriting', 'stamp'];
|
|
10
10
|
export const media = ['ink', 'pencil', 'crayon'];
|
|
11
|
+
/** Whether the feature states a place of its own, which one a patch bears does not. */
|
|
12
|
+
export const isPlaced = (feature) => feature.horizontal !== undefined && feature.vertical !== undefined;
|
|
11
13
|
export const isRollFeature = (obj) => {
|
|
12
14
|
return 'type' in obj && isFeatureType(obj.type);
|
|
13
15
|
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { ActorAssignment, DateAssignment, ObjectAssumption } from "./Assumption.js";
|
|
2
2
|
import { Concept, Named } from "./Agent.js";
|
|
3
3
|
import { ConditionState } from "./ConditionState.js";
|
|
4
|
-
import { WithNote } from "
|
|
4
|
+
import { WithNote } from "../shared/utils.js";
|
|
5
5
|
/**
|
|
6
6
|
* What a copy's features were read from. The kinds run from the paper
|
|
7
7
|
* itself, through files in which the roll has already been read into
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { ObjectAssumption } from "./Assumption.js";
|
|
2
2
|
import { ConditionState } from "./ConditionState.js";
|
|
3
3
|
import { Measure, Millimeters } from "./Quantity.js";
|
|
4
|
-
import { WithId, WithType } from "
|
|
4
|
+
import { WithId, WithType } from "../shared/utils.js";
|
|
5
5
|
/**
|
|
6
6
|
* The pitch in the engineering sense: the distance along the roll from
|
|
7
7
|
* one punch of a chain to the next, which is the slot one firing cut
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { ConditionState } from "./ConditionState.js";
|
|
2
2
|
import { AnySymbol } from "./Symbol.js";
|
|
3
|
-
import { TrackerBar } from "
|
|
3
|
+
import { TrackerBar } from "../systems/TrackerBar.js";
|
|
4
4
|
import { TrackCalibration } from "./TrackCalibration.js";
|
|
5
5
|
import { AnyFeature, FeatureOrPatch, Patch } from "./Feature.js";
|
|
6
6
|
import { ActorAssignment, DateAssignment, ObjectAssumption, ReferenceAssumption } from "./Assumption.js";
|
|
7
|
-
import { WithId, WithType } from "
|
|
7
|
+
import { WithId, WithType } from "../shared/utils.js";
|
|
8
8
|
import { Agent, Concept } from "./Agent.js";
|
|
9
9
|
import { FeatureSource } from "./FeatureSource.js";
|
|
10
10
|
import { Measure, Millimeters, Quantity, Track } from "./Quantity.js";
|
|
@@ -128,7 +128,7 @@ export interface ProductionEvent {
|
|
|
128
128
|
* at once and states it here, and a feature an editor reads as the
|
|
129
129
|
* work of a later hand belongs in the act that made it, whichever
|
|
130
130
|
* kind of feature it is.
|
|
131
|
-
* @see
|
|
131
|
+
* @see reo:produced
|
|
132
132
|
*/
|
|
133
133
|
produced?: AnyFeature[];
|
|
134
134
|
}
|
|
@@ -173,7 +173,7 @@ export type Modification = Partial<{
|
|
|
173
173
|
* paper, a circle in pencil, a hole punched by hand. Any kind of
|
|
174
174
|
* feature may come of a later act, as any kind may come of the
|
|
175
175
|
* punching.
|
|
176
|
-
* @see
|
|
176
|
+
* @see reo:produced
|
|
177
177
|
*/
|
|
178
178
|
produced: AnyFeature[];
|
|
179
179
|
/**
|
|
@@ -203,12 +203,6 @@ export type Modification = Partial<{
|
|
|
203
203
|
* @see reo:RollCopy
|
|
204
204
|
*/
|
|
205
205
|
export interface RollCopy extends WithType<'RollCopy'>, WithId {
|
|
206
|
-
/**
|
|
207
|
-
* A list of operations that have been applied to this copy's features
|
|
208
|
-
* (e.g. 'shifted', 'stretched') to normalize measurements
|
|
209
|
-
* for comparison with other copies. Not exported to RDF.
|
|
210
|
-
*/
|
|
211
|
-
ops: Array<'shifted' | 'stretched' | 'shortened'>;
|
|
212
206
|
/**
|
|
213
207
|
* Physical measurements of this roll copy, including
|
|
214
208
|
* dimensions, hole separation, margins, shift corrections,
|
|
@@ -403,8 +397,7 @@ export declare const featuresOf: (copy: Pick<RollCopy, 'production' | 'modificat
|
|
|
403
397
|
export declare const isPaperStretch: (condition: RollConditionAssignment) => boolean;
|
|
404
398
|
/**
|
|
405
399
|
* The bar a copy is read by, which is the one it was cut for. A copy
|
|
406
|
-
* that names no system falls back to
|
|
407
|
-
* before the systems were told apart; `reservationsAbout` says so.
|
|
400
|
+
* that names no system falls back to `defaultTrackerBar`.
|
|
408
401
|
*/
|
|
409
402
|
export declare const barOf: (copy: Pick<RollCopy, 'production'>) => TrackerBar;
|
|
410
403
|
/** The diameter of the punch the copy was cut with, where the edition holds it true or likely. */
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { v4 } from "uuid";
|
|
2
|
-
import {
|
|
3
|
-
import { trackerBarOf } from "./systems/index.js";
|
|
2
|
+
import { defaultTrackerBar, trackerBarOf } from "../systems/index.js";
|
|
4
3
|
import { assignReference, certaintyOf, isAsserted } from "./Assumption.js";
|
|
5
4
|
import { px, track } from "./Quantity.js";
|
|
6
5
|
export const rollConditions = [
|
|
@@ -43,10 +42,9 @@ export const featuresOf = (copy) => featuresByAct(copy).flat();
|
|
|
43
42
|
export const isPaperStretch = (condition) => condition.conditionType === 'paper-stretch';
|
|
44
43
|
/**
|
|
45
44
|
* The bar a copy is read by, which is the one it was cut for. A copy
|
|
46
|
-
* that names no system falls back to
|
|
47
|
-
* before the systems were told apart; `reservationsAbout` says so.
|
|
45
|
+
* that names no system falls back to `defaultTrackerBar`.
|
|
48
46
|
*/
|
|
49
|
-
export const barOf = (copy) => trackerBarOf(copy.production?.system) ??
|
|
47
|
+
export const barOf = (copy) => trackerBarOf(copy.production?.system) ?? defaultTrackerBar;
|
|
50
48
|
/** The diameter of the punch the copy was cut with, where the edition holds it true or likely. */
|
|
51
49
|
export const punchDiameterOf = (copy) => {
|
|
52
50
|
const diameter = copy.production?.perforator?.condition?.punchDiameter;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ReferenceAssumption } from "./Assumption.js";
|
|
2
|
-
import { WithId } from "
|
|
2
|
+
import { WithId } from "../shared/utils.js";
|
|
3
3
|
/**
|
|
4
4
|
* A symbol is an abstract musical or textual entity carried by one or more
|
|
5
5
|
* physical features on the roll. Symbols are the result of interpreting
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { Edit } from "./Edit.js";
|
|
2
2
|
import { Concept } from "./Agent.js";
|
|
3
3
|
import { ActorAssignment, Belief, Certainty, DateAssignment, ObjectAssumption, ReferenceAssumption } from "./Assumption.js";
|
|
4
|
-
import { CollationTolerance } from "
|
|
4
|
+
import { CollationTolerance } from "../collation/Collation.js";
|
|
5
5
|
import { AnySymbol } from "./Symbol.js";
|
|
6
|
-
import { WithId, WithNote, WithType } from "
|
|
6
|
+
import { WithId, WithNote, WithType } from "../shared/utils.js";
|
|
7
7
|
/**
|
|
8
8
|
* A motivation provides a reason or rationale for an editorial change.
|
|
9
9
|
* Motivations are defined at the version level and referenced by edits.
|
|
@@ -71,7 +71,7 @@ export interface VersionCreation {
|
|
|
71
71
|
* it describes.
|
|
72
72
|
* @see lrmoo:F2 Expression
|
|
73
73
|
*/
|
|
74
|
-
export interface Version extends WithId
|
|
74
|
+
export interface Version extends WithId {
|
|
75
75
|
/**
|
|
76
76
|
* The reproducing system this version is coded for. One roll was
|
|
77
77
|
* often issued for several of them, and a version is a reading in
|
|
@@ -131,3 +131,11 @@ export declare const derivationsOf: (version: Readonly<Version>) => {
|
|
|
131
131
|
* below another's reads the version's edits against another parent.
|
|
132
132
|
*/
|
|
133
133
|
export declare const principalDerivationOf: (version: Readonly<Version>) => Readonly<Derivation> | undefined;
|
|
134
|
+
/**
|
|
135
|
+
* Whether the version derives from the other, directly or through the
|
|
136
|
+
* versions between them, by any derivation it states, a hypothesis
|
|
137
|
+
* among them: a hypothesis held more certain becomes the principal one.
|
|
138
|
+
* A version derives from itself in no statement, and a stemma that
|
|
139
|
+
* loops is walked once round.
|
|
140
|
+
*/
|
|
141
|
+
export declare const derivesFrom: (versions: readonly Readonly<Version>[], versionId: string, ancestorId: string) => boolean;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { certainties, certaintyOf, idOf } from "./Assumption.js";
|
|
2
|
-
import { defaultCollationTolerance } from "
|
|
2
|
+
import { defaultCollationTolerance } from "../collation/Collation.js";
|
|
3
3
|
/** The tolerance the derivation was collated at, or the default where it states none. */
|
|
4
4
|
export const collationToleranceOf = (derivation) => derivation.collationTolerance ?? defaultCollationTolerance;
|
|
5
5
|
/** The edits the version states, none where it leaves its text unstated. */
|
|
@@ -26,3 +26,26 @@ const rankOf = (derivation) => certainties.indexOf(certaintyOf(derivation));
|
|
|
26
26
|
export const principalDerivationOf = (version) => (version.basedOn ?? [])
|
|
27
27
|
.filter(derivation => rankOf(derivation) <= certainties.indexOf('possible'))
|
|
28
28
|
.reduce((principal, derivation) => principal === undefined || rankOf(derivation) < rankOf(principal) ? derivation : principal, undefined);
|
|
29
|
+
/**
|
|
30
|
+
* Whether the version derives from the other, directly or through the
|
|
31
|
+
* versions between them, by any derivation it states, a hypothesis
|
|
32
|
+
* among them: a hypothesis held more certain becomes the principal one.
|
|
33
|
+
* A version derives from itself in no statement, and a stemma that
|
|
34
|
+
* loops is walked once round.
|
|
35
|
+
*/
|
|
36
|
+
export const derivesFrom = (versions, versionId, ancestorId) => {
|
|
37
|
+
const byId = new Map(versions.map(version => [version.id, version]));
|
|
38
|
+
const seen = new Set();
|
|
39
|
+
const pending = [versionId];
|
|
40
|
+
while (pending.length > 0) {
|
|
41
|
+
const id = pending.pop();
|
|
42
|
+
if (seen.has(id))
|
|
43
|
+
continue;
|
|
44
|
+
seen.add(id);
|
|
45
|
+
const parents = (byId.get(id)?.basedOn ?? []).map(idOf);
|
|
46
|
+
if (parents.includes(ancestorId))
|
|
47
|
+
return true;
|
|
48
|
+
pending.push(...parents);
|
|
49
|
+
}
|
|
50
|
+
return false;
|
|
51
|
+
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { drives } from "./Perforator.js";
|
|
2
2
|
import { procedures } from "./procedures.js";
|
|
3
|
-
import { systemOf } from "
|
|
4
|
-
import { trackerBars } from "
|
|
3
|
+
import { systemOf } from "../systems/TrackerBar.js";
|
|
4
|
+
import { trackerBars } from "../systems/index.js";
|
|
5
5
|
/**
|
|
6
6
|
* The concepts the type vocabulary declares, whatever kind they are:
|
|
7
7
|
* the reproducing systems, the procedures and the drives of a
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { Path } from "../view/EditionView.js";
|
|
2
|
+
import { AnyArgumentation, Certainty } from "../model/Assumption.js";
|
|
3
|
+
import { EditionOp } from "./draft.js";
|
|
4
|
+
/** Annotates the assumption at the path with a belief held true, for reasons to be added. */
|
|
5
|
+
export declare const createBelief: (path: Path) => EditionOp;
|
|
6
|
+
export declare const clearBelief: (path: Path) => EditionOp;
|
|
7
|
+
export declare const setCertainty: (path: Path, certainty: Certainty) => EditionOp;
|
|
8
|
+
export declare const addReason: (path: Path, reason: AnyArgumentation) => EditionOp;
|
|
9
|
+
export declare const removeReason: (path: Path, index: number) => EditionOp;
|