linked-rolls 0.1.1 → 0.3.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/LICENSE +26 -0
- package/README.md +35 -0
- package/lib/Assumption.d.ts +7 -2
- package/lib/ConditionState.d.ts +8 -1
- package/lib/Edit.d.ts +4 -3
- package/lib/Edition.d.ts +65 -35
- package/lib/Edition.js +1 -1
- package/lib/Emulation.js +32 -10
- package/lib/Feature.d.ts +19 -4
- package/lib/Plan.js +2 -1
- package/lib/RollCopy.d.ts +58 -26
- package/lib/RollCopy.js +2 -2
- package/lib/Symbol.d.ts +37 -20
- package/lib/Symbol.js +12 -0
- package/lib/TrackerBar.d.ts +18 -0
- package/lib/TrackerBar.js +27 -0
- package/lib/Version.d.ts +12 -4
- package/lib/asJsonLd.js +16 -2
- package/lib/context.d.ts +2 -0
- package/lib/context.js +2 -0
- package/lib/importJsonLd.js +19 -5
- package/lib/migrate.d.ts +15 -0
- package/lib/migrate.js +77 -0
- package/lib/schema.json +322 -276
- package/lib/spec/context.json +201 -131
- package/lib/spec/welte-t100.context.json +10 -0
- package/lib/systems/welteT100.js +23 -30
- package/lib/validate.d.ts +26 -0
- package/lib/validate.js +46 -0
- package/package.json +4 -3
package/lib/RollCopy.d.ts
CHANGED
|
@@ -6,6 +6,7 @@ import { AnyFeature } from "./Feature";
|
|
|
6
6
|
import { ObjectAssumption, ValueAssumption } from "./Assumption";
|
|
7
7
|
import { WithId, WithType } from "./utils";
|
|
8
8
|
import { ActorAssignment } from "./Edit";
|
|
9
|
+
import { Agent, Concept } from "./Edition";
|
|
9
10
|
/**
|
|
10
11
|
* This condition state is used to describe the roll's
|
|
11
12
|
* paper shrinkage or stretching. It might be calculated
|
|
@@ -16,6 +17,7 @@ export interface PaperStretch extends ConditionState<'paper-stretch'> {
|
|
|
16
17
|
/**
|
|
17
18
|
* The stretch factor, e.g. 1.02 means the paper has
|
|
18
19
|
* stretched by 2% compared to its original dimensions.
|
|
20
|
+
* @see rdf:value
|
|
19
21
|
*/
|
|
20
22
|
factor: number;
|
|
21
23
|
}
|
|
@@ -53,11 +55,17 @@ export declare const applyStretch: (paperStretch: ObjectAssumption<PaperStretch>
|
|
|
53
55
|
* A date value wrapped as an assumption, so that the date
|
|
54
56
|
* can be annotated with a belief about its certainty and source.
|
|
55
57
|
*/
|
|
56
|
-
export type DateAssignment = ValueAssumption<Date
|
|
58
|
+
export type DateAssignment = ValueAssumption<Date> & {
|
|
59
|
+
/**
|
|
60
|
+
* The datatype of the value. Written on export so that
|
|
61
|
+
* RDF reads the value as a date rather than a string.
|
|
62
|
+
*/
|
|
63
|
+
'@type'?: 'xsd:date';
|
|
64
|
+
};
|
|
57
65
|
/**
|
|
58
|
-
* Describes the production of a roll copy
|
|
59
|
-
*
|
|
60
|
-
* @see
|
|
66
|
+
* Describes the production of a roll copy: the manufacturer,
|
|
67
|
+
* the paper used, and the date.
|
|
68
|
+
* @see lrmoo:F32 Item Production Event
|
|
61
69
|
*/
|
|
62
70
|
export interface ProductionEvent {
|
|
63
71
|
/**
|
|
@@ -65,20 +73,15 @@ export interface ProductionEvent {
|
|
|
65
73
|
* (e.g. "M. Welte & Söhne").
|
|
66
74
|
* @see crm:P14 carried out by
|
|
67
75
|
*/
|
|
68
|
-
company
|
|
69
|
-
/**
|
|
70
|
-
* The roll system used for production
|
|
71
|
-
* (e.g. "Welte-Mignon T100", "Welte-Mignon T98").
|
|
72
|
-
*/
|
|
73
|
-
system: string;
|
|
76
|
+
company?: Agent;
|
|
74
77
|
/**
|
|
75
|
-
* The paper
|
|
76
|
-
* @see P126
|
|
78
|
+
* The paper the roll copy was cut on.
|
|
79
|
+
* @see crm:P126 employed
|
|
77
80
|
*/
|
|
78
|
-
paper
|
|
81
|
+
paper?: Concept;
|
|
79
82
|
/**
|
|
80
83
|
* The date of production, if known.
|
|
81
|
-
* @see
|
|
84
|
+
* @see dcterms:date
|
|
82
85
|
*/
|
|
83
86
|
date?: DateAssignment;
|
|
84
87
|
}
|
|
@@ -89,7 +92,15 @@ export interface ProductionEvent {
|
|
|
89
92
|
* @see crm:E79 Part Addition, crm:E80 Part Removal
|
|
90
93
|
*/
|
|
91
94
|
export type Modification = Partial<{
|
|
95
|
+
/**
|
|
96
|
+
* Who carried out the modification.
|
|
97
|
+
* @see crm:P14 carried out by
|
|
98
|
+
*/
|
|
92
99
|
actor: ActorAssignment;
|
|
100
|
+
/**
|
|
101
|
+
* When the modification took place.
|
|
102
|
+
* @see dcterms:date
|
|
103
|
+
*/
|
|
93
104
|
date: DateAssignment;
|
|
94
105
|
}> & ({
|
|
95
106
|
type: 'Addition';
|
|
@@ -112,6 +123,7 @@ export type Modification = Partial<{
|
|
|
112
123
|
* Sometimes however, we may see traces of features
|
|
113
124
|
* that have been removed, e.g. through bright spots on
|
|
114
125
|
* the roll.
|
|
126
|
+
* @see crm:P21 had general purpose
|
|
115
127
|
*/
|
|
116
128
|
purpose: 'delabeling';
|
|
117
129
|
});
|
|
@@ -120,66 +132,78 @@ export type Modification = Partial<{
|
|
|
120
132
|
* Each roll copy has its own set of features, measurements,
|
|
121
133
|
* conditions, and modifications. Multiple copies of the same
|
|
122
134
|
* roll may exist across different archives or collections.
|
|
123
|
-
* @see
|
|
135
|
+
* @see lrmoo:F5 Item
|
|
124
136
|
*/
|
|
125
137
|
export interface RollCopy extends WithType<'RollCopy'>, WithId {
|
|
126
138
|
/**
|
|
127
139
|
* A list of operations that have been applied to this copy's features
|
|
128
140
|
* (e.g. 'shifted', 'stretched') to normalize measurements
|
|
129
|
-
* for comparison with other copies.
|
|
141
|
+
* for comparison with other copies. Not exported to RDF.
|
|
130
142
|
*/
|
|
131
143
|
ops: Array<'shifted' | 'stretched'>;
|
|
132
144
|
/**
|
|
133
145
|
* Physical measurements of this roll copy, including
|
|
134
146
|
* dimensions, punch diameter, hole separation, margins,
|
|
135
147
|
* shift corrections, and information about the measuring software.
|
|
148
|
+
* @see crm:P39i was measured by
|
|
136
149
|
*/
|
|
137
150
|
measurements: Partial<{
|
|
138
151
|
/**
|
|
139
152
|
* The physical dimensions of the roll.
|
|
153
|
+
* @see reo:dimensions
|
|
140
154
|
*/
|
|
141
155
|
dimensions: {
|
|
142
156
|
/**
|
|
143
157
|
* The width of the roll in the given unit.
|
|
158
|
+
* @see reo:width
|
|
144
159
|
*/
|
|
145
160
|
width: number;
|
|
146
161
|
/**
|
|
147
162
|
* The total height (length) of the roll in the given unit.
|
|
163
|
+
* @see reo:height
|
|
148
164
|
*/
|
|
149
165
|
height: number;
|
|
150
166
|
/**
|
|
151
167
|
* The unit of measurement (e.g. 'mm').
|
|
168
|
+
* @see crm:P91 has unit
|
|
152
169
|
*/
|
|
153
170
|
unit: string;
|
|
154
171
|
};
|
|
155
172
|
/**
|
|
156
173
|
* The average diameter of punched holes.
|
|
174
|
+
* @see reo:punchDiameter
|
|
157
175
|
*/
|
|
158
176
|
punchDiameter: {
|
|
159
177
|
/**
|
|
160
178
|
* The measured punch diameter value.
|
|
179
|
+
* @see crm:P90 has value
|
|
161
180
|
*/
|
|
162
181
|
value: number;
|
|
163
182
|
/**
|
|
164
183
|
* The unit of measurement (e.g. 'mm').
|
|
184
|
+
* @see crm:P91 has unit
|
|
165
185
|
*/
|
|
166
186
|
unit: string;
|
|
167
187
|
};
|
|
168
188
|
/**
|
|
169
189
|
* The distance between adjacent tracker bar holes.
|
|
190
|
+
* @see reo:holeSeparation
|
|
170
191
|
*/
|
|
171
192
|
holeSeparation: {
|
|
172
193
|
/**
|
|
173
194
|
* The measured hole separation value.
|
|
195
|
+
* @see crm:P90 has value
|
|
174
196
|
*/
|
|
175
197
|
value: number;
|
|
176
198
|
/**
|
|
177
199
|
* The unit of measurement (e.g. 'px', 'mm').
|
|
200
|
+
* @see crm:P91 has unit
|
|
178
201
|
*/
|
|
179
202
|
unit: string;
|
|
180
203
|
};
|
|
181
204
|
/**
|
|
182
205
|
* The margins on the treble and bass sides of the roll.
|
|
206
|
+
* Not exported to RDF.
|
|
183
207
|
*/
|
|
184
208
|
margins: {
|
|
185
209
|
/**
|
|
@@ -195,57 +219,65 @@ export interface RollCopy extends WithType<'RollCopy'>, WithId {
|
|
|
195
219
|
*/
|
|
196
220
|
unit: string;
|
|
197
221
|
};
|
|
222
|
+
/**
|
|
223
|
+
* The shift applied to align this copy with the others.
|
|
224
|
+
* Not exported to RDF.
|
|
225
|
+
*/
|
|
198
226
|
shift: Shift;
|
|
199
227
|
/**
|
|
200
228
|
* Relates this copy's scan to the tracker bar: how the scanning
|
|
201
229
|
* software's hole numbering was shifted onto the bar, and where
|
|
202
|
-
* the track grid sits in the image.
|
|
230
|
+
* the track grid sits in the image. Not exported to RDF.
|
|
203
231
|
*/
|
|
204
232
|
trackCalibration: TrackCalibration;
|
|
205
233
|
/**
|
|
206
234
|
* Information about the software used to take the measurements.
|
|
235
|
+
* @see crmdig:L23 used software or firmware
|
|
207
236
|
*/
|
|
208
237
|
measuredBy: {
|
|
209
238
|
/**
|
|
210
239
|
* The name of the measurement software.
|
|
240
|
+
* @see rdfs:label
|
|
211
241
|
*/
|
|
212
242
|
software: string;
|
|
213
243
|
/**
|
|
214
244
|
* The version of the measurement software.
|
|
245
|
+
* @see owl:versionInfo
|
|
215
246
|
*/
|
|
216
247
|
version: string;
|
|
217
248
|
/**
|
|
218
249
|
* The date on which the measurements were taken.
|
|
219
250
|
* @format date
|
|
251
|
+
* @see dcterms:date
|
|
220
252
|
*/
|
|
221
253
|
date: Date;
|
|
222
254
|
};
|
|
223
255
|
}>;
|
|
224
256
|
/**
|
|
225
257
|
* The production event that created this roll copy.
|
|
226
|
-
* @see
|
|
258
|
+
* @see lrmoo:R28i was produced by
|
|
227
259
|
*/
|
|
228
260
|
production?: ProductionEvent;
|
|
229
261
|
/**
|
|
230
262
|
* Condition assessments of this roll copy (e.g. paper stretch,
|
|
231
263
|
* general wear). Each condition is an assumption annotatable
|
|
232
264
|
* with a belief.
|
|
265
|
+
* @see crm:P44 has condition
|
|
233
266
|
*/
|
|
234
267
|
conditions: RollConditionAssignment[];
|
|
235
268
|
/**
|
|
236
|
-
* The
|
|
237
|
-
* @see crm:
|
|
269
|
+
* The institution or person holding this copy.
|
|
270
|
+
* @see crm:P50 has current keeper
|
|
238
271
|
*/
|
|
239
|
-
|
|
272
|
+
keeper: Agent;
|
|
240
273
|
/**
|
|
241
|
-
*
|
|
242
|
-
*
|
|
243
|
-
*
|
|
244
|
-
* exported in the final JSON.
|
|
274
|
+
* The physical features found on this copy, with shift
|
|
275
|
+
* and stretch already applied when `ops` says so.
|
|
276
|
+
* @see crm:P56 bears feature
|
|
245
277
|
*/
|
|
246
278
|
features: AnyFeature[];
|
|
247
279
|
/**
|
|
248
|
-
* @see crm:
|
|
280
|
+
* @see crm:P31i was modified by
|
|
249
281
|
*/
|
|
250
282
|
modifications: Modification[];
|
|
251
283
|
/**
|
package/lib/RollCopy.js
CHANGED
|
@@ -226,7 +226,7 @@ export function readFromStanfordAton(atonString, { trackShift, bar = welteT100,
|
|
|
226
226
|
id: v4(),
|
|
227
227
|
ops: [],
|
|
228
228
|
conditions: [],
|
|
229
|
-
|
|
229
|
+
keeper: { name: '', sameAs: [] },
|
|
230
230
|
modifications: [],
|
|
231
231
|
...((scan ?? stanford) && { scan: scan ?? stanford?.scan }),
|
|
232
232
|
measurements: {
|
|
@@ -302,7 +302,7 @@ export function readFromSpencerMIDI(midiBuffer, placeAt = atConstantSpeed(SPENCE
|
|
|
302
302
|
id: v4(),
|
|
303
303
|
ops: [],
|
|
304
304
|
conditions: [],
|
|
305
|
-
|
|
305
|
+
keeper: { name: '', sameAs: [] },
|
|
306
306
|
measurements: {},
|
|
307
307
|
modifications: [],
|
|
308
308
|
features
|
package/lib/Symbol.d.ts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import { ReferenceAssumption
|
|
1
|
+
import { ReferenceAssumption } from "./Assumption";
|
|
2
2
|
import { WithId } from "./utils";
|
|
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
|
|
6
6
|
* the physical features (holes, writings, etc.) on the roll copies.
|
|
7
|
+
* @see crm:E90 Symbolic Object
|
|
7
8
|
*/
|
|
8
9
|
export interface Symbol<T extends string> extends WithId {
|
|
9
10
|
type: T;
|
|
@@ -22,69 +23,84 @@ export declare const isSymbol: (object: any) => object is AnySymbol;
|
|
|
22
23
|
* A perforation is a symbol that is typically encoded as a single punched
|
|
23
24
|
* hole or a group of punched holes in the physical carrier.
|
|
24
25
|
* However, it might also have different physical appearences.
|
|
25
|
-
* @see reo:
|
|
26
|
+
* @see reo:Perforation
|
|
26
27
|
*/
|
|
27
28
|
export interface Perforation<T extends string> extends Symbol<T> {
|
|
28
29
|
/**
|
|
29
30
|
* In piano rolls, perforations are often aligned with other
|
|
30
31
|
* perforations, e.g. a "crescendo off" might be logically
|
|
31
|
-
* aligned to the start of a note perforation.
|
|
32
|
-
*
|
|
32
|
+
* aligned to the start of a note perforation. This points
|
|
33
|
+
* to the perforation by its `@id`.
|
|
34
|
+
* @see reo:alignedWith
|
|
33
35
|
*/
|
|
34
|
-
alignedWith?:
|
|
36
|
+
alignedWith?: ReferenceAssumption;
|
|
37
|
+
/**
|
|
38
|
+
* The perforation this one forms a pair with, e.g. a "forzando on"
|
|
39
|
+
* with its "forzando off". Any two perforations may be paired.
|
|
40
|
+
* The distance between the two is fixed: whatever displaces the
|
|
41
|
+
* one displaces the other. The relation is symmetric and is stated
|
|
42
|
+
* on one side only. This points to the perforation by its `@id`.
|
|
43
|
+
* @see reo:pairedWith
|
|
44
|
+
*/
|
|
45
|
+
pairedWith?: ReferenceAssumption;
|
|
35
46
|
}
|
|
47
|
+
type Pairable = WithId & {
|
|
48
|
+
pairedWith?: ReferenceAssumption;
|
|
49
|
+
};
|
|
50
|
+
/**
|
|
51
|
+
* The pairs among the given perforations, each once and in the order
|
|
52
|
+
* the pairing is stated. A pair whose partner is absent is left out.
|
|
53
|
+
*/
|
|
54
|
+
export declare const pairsAmong: <S extends Pairable>(perforations: readonly S[]) => [S, S][];
|
|
36
55
|
/**
|
|
37
56
|
* A note symbol, representing a single pitched musical event on the roll.
|
|
38
57
|
* The pitch is encoded via the tracker bar position (track number).
|
|
39
|
-
* @see reo:
|
|
58
|
+
* @see reo:Note
|
|
40
59
|
*/
|
|
41
60
|
export interface Note extends Perforation<'note'> {
|
|
42
61
|
/**
|
|
43
62
|
* The MIDI pitch number of the note (e.g. 60 for middle C).
|
|
44
|
-
* @see reo:
|
|
63
|
+
* @see reo:pitch
|
|
45
64
|
*/
|
|
46
65
|
pitch: number;
|
|
47
66
|
}
|
|
48
67
|
/**
|
|
49
68
|
* The scope of an expression perforation, indicating whether it
|
|
50
69
|
* applies to the bass or treble register of the piano.
|
|
51
|
-
* @see reo:
|
|
70
|
+
* @see reo:scope
|
|
52
71
|
*/
|
|
53
72
|
export type ExpressionScope = 'bass' | 'treble';
|
|
54
|
-
/**
|
|
55
|
-
* The type of expression encoded by a perforation on the roll,
|
|
56
|
-
* e.g. "crescendo on", "crescendo off", etc. on Welte T-100
|
|
57
|
-
* rolls.
|
|
58
|
-
* @see crm:P2 has type
|
|
59
|
-
*/
|
|
60
|
-
export type ExpressionType = 'SustainPedalOn' | 'SustainPedalOff' | 'SoftPedalOn' | 'SoftPedalOff' | 'MezzoforteOff' | 'MezzoforteOn' | 'SlowCrescendoOn' | 'SlowCrescendoOff' | 'ForzandoOn' | 'ForzandoOff' | 'MotorOff' | 'MotorOn' | 'Rewind' | 'ElectricCutOff';
|
|
61
73
|
/**
|
|
62
74
|
* An expression symbol, representing a perforation on the roll
|
|
63
75
|
* that governs dynamics, pedaling, or mechanical functions of the
|
|
64
76
|
* reproducing piano. Each expression has a scope (bass or treble)
|
|
65
77
|
* and a specific expression type.
|
|
66
|
-
* @see reo:
|
|
78
|
+
* @see reo:Expression
|
|
67
79
|
*/
|
|
68
80
|
export interface Expression extends Perforation<'expression'> {
|
|
69
81
|
/**
|
|
70
82
|
* Whether this expression applies to the bass or treble register.
|
|
71
|
-
* @see reo:
|
|
83
|
+
* @see reo:scope
|
|
72
84
|
*/
|
|
73
85
|
scope: ExpressionScope;
|
|
74
86
|
/**
|
|
75
|
-
* The
|
|
87
|
+
* The command the perforation gives, named as the reproducing
|
|
88
|
+
* system of the roll names it: "SustainPedalOn", "ForzandoOff"
|
|
89
|
+
* and so on for the Welte-Mignon T-100. The tracker bar of the
|
|
90
|
+
* system lists the values it reads.
|
|
76
91
|
* @see crm:P2 has type
|
|
77
92
|
*/
|
|
78
|
-
expressionType:
|
|
93
|
+
expressionType: string;
|
|
79
94
|
}
|
|
80
95
|
/**
|
|
81
96
|
* A textual symbol, e.g. a label or annotation found on the roll.
|
|
82
97
|
* @see crm:E33 Linguistic Object
|
|
83
98
|
*/
|
|
84
99
|
export interface Text extends Symbol<'text'> {
|
|
100
|
+
type: 'text';
|
|
85
101
|
/**
|
|
86
102
|
* The text content of the symbol.
|
|
87
|
-
* @see crm:
|
|
103
|
+
* @see crm:P190 has symbolic content
|
|
88
104
|
*/
|
|
89
105
|
text: string;
|
|
90
106
|
}
|
|
@@ -93,3 +109,4 @@ export interface Text extends Symbol<'text'> {
|
|
|
93
109
|
* Notes and expressions are perforations; texts are carried by writings.
|
|
94
110
|
*/
|
|
95
111
|
export type AnySymbol = Note | Expression | Text;
|
|
112
|
+
export {};
|
package/lib/Symbol.js
CHANGED
|
@@ -1,4 +1,16 @@
|
|
|
1
|
+
import { idOf } from "./Assumption";
|
|
1
2
|
export const isSymbol = (object) => {
|
|
2
3
|
return ('type' in object
|
|
3
4
|
&& (object.type === 'note' || object.type === 'expression' || object.type === 'text'));
|
|
4
5
|
};
|
|
6
|
+
/**
|
|
7
|
+
* The pairs among the given perforations, each once and in the order
|
|
8
|
+
* the pairing is stated. A pair whose partner is absent is left out.
|
|
9
|
+
*/
|
|
10
|
+
export const pairsAmong = (perforations) => {
|
|
11
|
+
const byId = new Map(perforations.map(p => [p.id, p]));
|
|
12
|
+
return perforations
|
|
13
|
+
.filter((p) => p.pairedWith !== undefined)
|
|
14
|
+
.map((p) => [p, byId.get(idOf(p.pairedWith))])
|
|
15
|
+
.filter((pair) => pair[1] !== undefined);
|
|
16
|
+
};
|
package/lib/TrackerBar.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { Concept } from "./Edition";
|
|
1
2
|
import { Expression, Note } from "./Symbol";
|
|
2
3
|
/**
|
|
3
4
|
* What a tracker bar position does: sound a note, or operate one of
|
|
@@ -27,6 +28,12 @@ export type TrackMeaning = NoteMeaning | ExpressionMeaning;
|
|
|
27
28
|
* ask the tracker bar rather than repeat the boundaries.
|
|
28
29
|
*/
|
|
29
30
|
export interface TrackerBar {
|
|
31
|
+
/**
|
|
32
|
+
* Names the reproducing system in the type vocabulary:
|
|
33
|
+
* the system is `https://w3id.org/reo/type/system/<id>` and its
|
|
34
|
+
* expression types live under `https://w3id.org/reo/type/<id>/`.
|
|
35
|
+
*/
|
|
36
|
+
readonly id: string;
|
|
30
37
|
readonly name: string;
|
|
31
38
|
/** Width of the roll the bar reads, in mm. */
|
|
32
39
|
readonly width: number;
|
|
@@ -34,6 +41,8 @@ export interface TrackerBar {
|
|
|
34
41
|
readonly trackCount: number;
|
|
35
42
|
/** The blocks of positions, from the bass edge upwards. */
|
|
36
43
|
readonly areas: readonly TrackArea[];
|
|
44
|
+
/** The expression types the bar reads, each a term of the system. */
|
|
45
|
+
readonly expressionTypes: readonly string[];
|
|
37
46
|
/**
|
|
38
47
|
* The position carrying the rewind perforation, which runs at
|
|
39
48
|
* the very end of a roll and is the usual landmark for calibrating
|
|
@@ -45,6 +54,15 @@ export interface TrackerBar {
|
|
|
45
54
|
/** `undefined` for a position the bar does not read. */
|
|
46
55
|
roleOf(track: number): TrackRole | undefined;
|
|
47
56
|
}
|
|
57
|
+
/** The roll system a tracker bar belongs to, as the roll metadata states it. */
|
|
58
|
+
export declare const systemOf: (bar: TrackerBar) => Concept;
|
|
59
|
+
/** The identifier of a system the type vocabulary knows, from its concept. */
|
|
60
|
+
export declare const systemIdOf: (system: Concept | undefined) => string | undefined;
|
|
61
|
+
/**
|
|
62
|
+
* The commands of the Welte-Mignon T-100, as its tracker bar reads them.
|
|
63
|
+
*/
|
|
64
|
+
export declare const welteT100ExpressionTypes: readonly ["SustainPedalOn", "SustainPedalOff", "SoftPedalOn", "SoftPedalOff", "MezzoforteOff", "MezzoforteOn", "SlowCrescendoOn", "SlowCrescendoOff", "ForzandoOn", "ForzandoOff", "MotorOff", "MotorOn", "Rewind", "ElectricCutOff"];
|
|
65
|
+
export type WelteT100ExpressionType = typeof welteT100ExpressionTypes[number];
|
|
48
66
|
/**
|
|
49
67
|
* Welte-Mignon T-100 ("red Welte"), cf. Hagmann, pp. 75 and 178.
|
|
50
68
|
*
|
package/lib/TrackerBar.js
CHANGED
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
const SYSTEM_IRI = 'https://w3id.org/reo/type/system/';
|
|
2
|
+
/** The roll system a tracker bar belongs to, as the roll metadata states it. */
|
|
3
|
+
export const systemOf = (bar) => ({ id: SYSTEM_IRI + bar.id, name: bar.name, sameAs: [] });
|
|
4
|
+
/** The identifier of a system the type vocabulary knows, from its concept. */
|
|
5
|
+
export const systemIdOf = (system) => system?.id?.startsWith(SYSTEM_IRI) ? system.id.slice(SYSTEM_IRI.length) : undefined;
|
|
1
6
|
const areasOf = ({ notes, trackCount }) => [
|
|
2
7
|
{ role: 'bass-expression', from: 1, to: notes.from - 1 },
|
|
3
8
|
{ role: 'note', from: notes.from, to: notes.to },
|
|
@@ -28,15 +33,36 @@ const describe = (spec) => {
|
|
|
28
33
|
throw new Error(`${spec.name} declares no rewind track`);
|
|
29
34
|
}
|
|
30
35
|
return {
|
|
36
|
+
id: spec.id,
|
|
31
37
|
name: spec.name,
|
|
32
38
|
width: spec.width,
|
|
33
39
|
trackCount: spec.trackCount,
|
|
34
40
|
areas,
|
|
41
|
+
expressionTypes: [...new Set(spec.expressions.values())],
|
|
35
42
|
rewindTrack,
|
|
36
43
|
meaningOf,
|
|
37
44
|
roleOf
|
|
38
45
|
};
|
|
39
46
|
};
|
|
47
|
+
/**
|
|
48
|
+
* The commands of the Welte-Mignon T-100, as its tracker bar reads them.
|
|
49
|
+
*/
|
|
50
|
+
export const welteT100ExpressionTypes = [
|
|
51
|
+
'SustainPedalOn',
|
|
52
|
+
'SustainPedalOff',
|
|
53
|
+
'SoftPedalOn',
|
|
54
|
+
'SoftPedalOff',
|
|
55
|
+
'MezzoforteOff',
|
|
56
|
+
'MezzoforteOn',
|
|
57
|
+
'SlowCrescendoOn',
|
|
58
|
+
'SlowCrescendoOff',
|
|
59
|
+
'ForzandoOn',
|
|
60
|
+
'ForzandoOff',
|
|
61
|
+
'MotorOff',
|
|
62
|
+
'MotorOn',
|
|
63
|
+
'Rewind',
|
|
64
|
+
'ElectricCutOff'
|
|
65
|
+
];
|
|
40
66
|
/**
|
|
41
67
|
* Welte-Mignon T-100 ("red Welte"), cf. Hagmann, pp. 75 and 178.
|
|
42
68
|
*
|
|
@@ -45,6 +71,7 @@ const describe = (spec) => {
|
|
|
45
71
|
* treble above it, in mirrored order.
|
|
46
72
|
*/
|
|
47
73
|
export const welteT100 = describe({
|
|
74
|
+
id: 'welte-t100',
|
|
48
75
|
name: 'Welte-Mignon T100',
|
|
49
76
|
width: 328,
|
|
50
77
|
trackCount: 100,
|
package/lib/Version.d.ts
CHANGED
|
@@ -11,31 +11,39 @@ export type VersionType = typeof versionTypes[number];
|
|
|
11
11
|
/**
|
|
12
12
|
* A motivation provides a reason or rationale for an editorial change.
|
|
13
13
|
* Motivations are defined at the version level and referenced by edits.
|
|
14
|
-
* @see crm:
|
|
14
|
+
* @see crm:E33 Linguistic Object
|
|
15
15
|
*/
|
|
16
16
|
export type Motivation = WithType<'motivation'> & WithId & WithNote;
|
|
17
17
|
/**
|
|
18
18
|
* A version is defined by the sum of edits applied
|
|
19
19
|
* to the version it is based on. For simple identification,
|
|
20
20
|
* a siglum is given to each version.
|
|
21
|
+
* @see lrmoo:F2 Expression
|
|
21
22
|
*/
|
|
22
|
-
export interface Version {
|
|
23
|
-
id: string;
|
|
23
|
+
export interface Version extends WithId, WithType<'Version'> {
|
|
24
24
|
/**
|
|
25
25
|
* A short siglum to identify the version, e.g. "A", "B1", "B2_rev", etc.
|
|
26
|
+
* @see reo:siglum
|
|
26
27
|
*/
|
|
27
28
|
siglum: string;
|
|
29
|
+
/**
|
|
30
|
+
* Whether the version served as a master for reproductions
|
|
31
|
+
* or exists on one copy only.
|
|
32
|
+
* @see crm:P2 has type
|
|
33
|
+
*/
|
|
34
|
+
versionType: VersionType;
|
|
28
35
|
/**
|
|
29
36
|
* If no derivation is defined, it is assumed that this version represents the mother roll.
|
|
37
|
+
* @see lrmoo:R76 is derivative of
|
|
30
38
|
*/
|
|
31
39
|
basedOn?: ReferenceAssumption;
|
|
32
40
|
/**
|
|
33
41
|
* The list of edits that, applied to the base version, produce this version.
|
|
42
|
+
* @see reo:involvedEdit
|
|
34
43
|
*/
|
|
35
44
|
edits: Edit[];
|
|
36
45
|
/**
|
|
37
46
|
* A collection of motivations used in this version's edits.
|
|
38
47
|
*/
|
|
39
48
|
motivations: Motivation[];
|
|
40
|
-
type: VersionType;
|
|
41
49
|
}
|
package/lib/asJsonLd.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { systemIdOf } from "./TrackerBar";
|
|
1
2
|
export const exportDate = (date) => {
|
|
2
3
|
const year = date.getFullYear();
|
|
3
4
|
const month = String(date.getMonth() + 1).padStart(2, "0");
|
|
@@ -32,13 +33,26 @@ const asJsonLdEntity = (obj) => {
|
|
|
32
33
|
result[key] = value;
|
|
33
34
|
}
|
|
34
35
|
}
|
|
36
|
+
if ('@value' in obj && obj['@value'] instanceof Date) {
|
|
37
|
+
result['@type'] = 'xsd:date';
|
|
38
|
+
}
|
|
35
39
|
return result;
|
|
36
40
|
};
|
|
41
|
+
/**
|
|
42
|
+
* The context of the roll's reproducing system, which reads the
|
|
43
|
+
* expression types as that system's terms.
|
|
44
|
+
*/
|
|
45
|
+
const systemContextOf = (edition) => {
|
|
46
|
+
const system = systemIdOf(edition.roll?.system);
|
|
47
|
+
return system ? [`https://w3id.org/reo/${system}/context.jsonld`] : [];
|
|
48
|
+
};
|
|
37
49
|
export const asJsonLd = (edition) => {
|
|
38
|
-
|
|
50
|
+
// The context is the export's own; one carried in from an import must not override it.
|
|
51
|
+
const { base, copies, '@context': carried, ...rest } = asJsonLdEntity(edition);
|
|
39
52
|
return {
|
|
40
53
|
'@context': [
|
|
41
|
-
'https://
|
|
54
|
+
'https://w3id.org/reo/context.jsonld',
|
|
55
|
+
...systemContextOf(edition),
|
|
42
56
|
{
|
|
43
57
|
'@base': edition.base
|
|
44
58
|
}
|
package/lib/context.d.ts
CHANGED
package/lib/context.js
CHANGED
package/lib/importJsonLd.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { migrate } from "./migrate";
|
|
1
2
|
const isDate = (value) => {
|
|
2
3
|
const datePattern = /^\d{4}-\d{1,2}-\d{1,2}$/;
|
|
3
4
|
return datePattern.test(value);
|
|
@@ -14,7 +15,11 @@ const fromJsonLdEntity = (json) => {
|
|
|
14
15
|
return json;
|
|
15
16
|
}
|
|
16
17
|
let result = json;
|
|
17
|
-
if ('@
|
|
18
|
+
if ('@value' in json) {
|
|
19
|
+
// the datatype of a value object, not a class
|
|
20
|
+
delete result['@type'];
|
|
21
|
+
}
|
|
22
|
+
else if ('@type' in json) {
|
|
18
23
|
result['type'] = json['@type'];
|
|
19
24
|
delete result['@type'];
|
|
20
25
|
}
|
|
@@ -49,10 +54,19 @@ const fromJsonLdEntity = (json) => {
|
|
|
49
54
|
}
|
|
50
55
|
return result;
|
|
51
56
|
};
|
|
57
|
+
// The export prefixes copy identifiers with `copy/`; this is its inverse.
|
|
58
|
+
const withPlainCopyIds = (json) => ({
|
|
59
|
+
...json,
|
|
60
|
+
copies: (json.copies ?? []).map((copy) => ({
|
|
61
|
+
...copy,
|
|
62
|
+
'@id': typeof copy['@id'] === 'string' ? copy['@id'].replace(/^copy\//, '') : copy['@id']
|
|
63
|
+
}))
|
|
64
|
+
});
|
|
52
65
|
export const importJsonLd = (json) => {
|
|
53
|
-
const
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
66
|
+
const { '@context': context, ...document } = withPlainCopyIds(migrate(json));
|
|
67
|
+
const edition = fromJsonLdEntity(document);
|
|
68
|
+
edition.base = Array.isArray(context)
|
|
69
|
+
? context.find((c) => c['@base'])?.['@base'] || ''
|
|
70
|
+
: '';
|
|
57
71
|
return edition;
|
|
58
72
|
};
|
package/lib/migrate.d.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Brings the JSON of an edition written by an earlier release of the
|
|
3
|
+
* format up to the current shape. The shapes are recognised
|
|
4
|
+
* structurally, so a file that is current already passes through
|
|
5
|
+
* unchanged, and a file may be migrated any number of times.
|
|
6
|
+
*
|
|
7
|
+
* Format 0.1 used the type discriminator of versions and conditions
|
|
8
|
+
* for their typology, held the keeper and the production metadata as
|
|
9
|
+
* strings, and named the roll system on each copy. Some 0.1 files
|
|
10
|
+
* also carry references written as values and two keys the format
|
|
11
|
+
* had renamed before.
|
|
12
|
+
*/
|
|
13
|
+
type Json = any;
|
|
14
|
+
export declare const migrate: (edition: Json) => Json;
|
|
15
|
+
export {};
|