linked-rolls 0.62.0 → 0.63.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 +14 -3
- package/lib/analysis/constraints.js +16 -10
- package/lib/analysis/ownPaper.d.ts +9 -14
- package/lib/analysis/ownPaper.js +13 -31
- package/lib/analysis/paper.d.ts +129 -0
- package/lib/analysis/paper.js +260 -0
- package/lib/collation/alignment.d.ts +46 -8
- package/lib/collation/alignment.js +137 -47
- package/lib/index.d.ts +2 -1
- package/lib/index.js +2 -1
- package/lib/io/asJsonLd.js +6 -1
- package/lib/io/importJsonLd.d.ts +5 -0
- package/lib/io/importJsonLd.js +7 -0
- package/lib/io/migrate.js +94 -2
- package/lib/model/Assumption.d.ts +21 -9
- package/lib/model/Edition.d.ts +19 -0
- package/lib/model/Edition.js +9 -1
- package/lib/model/Quantity.d.ts +4 -1
- package/lib/model/Quantity.js +1 -0
- package/lib/model/RollCopy.d.ts +144 -48
- package/lib/model/RollCopy.js +9 -6
- package/lib/ops/copies.d.ts +47 -10
- package/lib/ops/copies.js +92 -26
- package/lib/ops/index.d.ts +1 -1
- package/lib/ops/index.js +1 -1
- package/lib/readers/stanfordAton.js +28 -1
- package/lib/schema.json +183 -24
- package/lib/spec/context.json +33 -1
- package/lib/systems/ReproducingSystem.d.ts +7 -6
- package/package.json +1 -1
package/lib/model/RollCopy.d.ts
CHANGED
|
@@ -2,26 +2,52 @@ import { ConditionState } from "./ConditionState.js";
|
|
|
2
2
|
import { AnySymbol } from "./Symbol.js";
|
|
3
3
|
import { TrackerBar } from "../systems/TrackerBar.js";
|
|
4
4
|
import { TrackCalibration } from "./TrackCalibration.js";
|
|
5
|
-
import { AnyFeature, FeatureOrPatch, Patch } from "./Feature.js";
|
|
5
|
+
import { AnyFeature, FeatureOrPatch, HorizontalSpan, Patch } from "./Feature.js";
|
|
6
6
|
import { ActorAssignment, DateAssignment, ObjectAssumption, ReferenceAssumption } from "./Assumption.js";
|
|
7
7
|
import { WithId, WithType } from "../shared/utils.js";
|
|
8
8
|
import { Agent, Concept } from "./Agent.js";
|
|
9
9
|
import { FeatureSource } from "./FeatureSource.js";
|
|
10
|
-
import { Measure, Millimeters, Quantity, Track } from "./Quantity.js";
|
|
10
|
+
import { Measure, Millimeters, Percent, Quantity, Track } from "./Quantity.js";
|
|
11
11
|
import { Perforator } from "./Perforator.js";
|
|
12
12
|
/**
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
13
|
+
* How far the paper has stretched, or shrunk where it is negative, since
|
|
14
|
+
* it was perforated, as a share of its length then: the strain
|
|
15
|
+
* ΔL / L. It is a ratio of two lengths and so has no unit of its own,
|
|
16
|
+
* and it is stated in per cent because what paper does is a matter of
|
|
17
|
+
* tenths of one. It is taken in one direction, along the roll or across
|
|
18
|
+
* it, since machine-made paper does not stretch the same way in both.
|
|
19
|
+
* @see crm:E54 Dimension
|
|
20
|
+
*/
|
|
21
|
+
export interface Strain extends Measure<'percent'> {
|
|
22
|
+
/**
|
|
23
|
+
* The standard uncertainty of the value, one standard deviation.
|
|
24
|
+
* Left out where the measurement gave none, which leaves it no more
|
|
25
|
+
* precise than paper is known to vary.
|
|
26
|
+
* @see reo:uncertainty
|
|
27
|
+
*/
|
|
28
|
+
uncertainty?: Percent;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* The paper of the copy stretched or shrunk, as measured on the copy:
|
|
32
|
+
* with a rule against a length the perforator fixed, or across the roll
|
|
33
|
+
* against the pitch of the punch block. What the alignments of the
|
|
34
|
+
* copies say about the paper is worked out from them (`paperOf`) and not
|
|
35
|
+
* stated here, so that a condition stands only where something was
|
|
36
|
+
* measured. A strain along the roll goes into that working out.
|
|
37
|
+
* @see crm:E3 Condition State
|
|
17
38
|
*/
|
|
18
39
|
export interface PaperStretch extends ConditionState<'paper-stretch'> {
|
|
19
40
|
/**
|
|
20
|
-
* The
|
|
21
|
-
*
|
|
22
|
-
|
|
41
|
+
* The strain along the roll, the direction the alignment measures.
|
|
42
|
+
* @see reo:strainAlong
|
|
43
|
+
*/
|
|
44
|
+
along?: Strain;
|
|
45
|
+
/**
|
|
46
|
+
* The strain across the roll. Paper stretches more across than
|
|
47
|
+
* along, so this is no measure of the other.
|
|
48
|
+
* @see reo:strainAcross
|
|
23
49
|
*/
|
|
24
|
-
|
|
50
|
+
across?: Strain;
|
|
25
51
|
}
|
|
26
52
|
/**
|
|
27
53
|
* A general condition description for a roll copy, e.g.
|
|
@@ -31,20 +57,53 @@ export interface PaperStretch extends ConditionState<'paper-stretch'> {
|
|
|
31
57
|
export interface GeneralRollCondition extends ConditionState<'general'> {
|
|
32
58
|
}
|
|
33
59
|
/**
|
|
34
|
-
*
|
|
60
|
+
* The paper of the copy torn at one place, most often a tear running in
|
|
61
|
+
* from one of its edges. Each tear is a condition of its own, so that
|
|
62
|
+
* each can carry the belief it rests on and serve as a premise. A tear
|
|
63
|
+
* that runs into a chain of holes damages the chain as well, which is
|
|
64
|
+
* then stated of the chain as `partially-torn`.
|
|
65
|
+
* @see crm:E3 Condition State
|
|
66
|
+
*/
|
|
67
|
+
export interface Tear extends ConditionState<'torn'> {
|
|
68
|
+
/**
|
|
69
|
+
* Where along the roll the tear lies, measured as the copy's
|
|
70
|
+
* features are, so that it moves with them when the copy is aligned.
|
|
71
|
+
* @see reo:horizontal
|
|
72
|
+
*/
|
|
73
|
+
horizontal: HorizontalSpan;
|
|
74
|
+
/**
|
|
75
|
+
* The edge of the paper the tear runs in from, where it runs in
|
|
76
|
+
* from one.
|
|
77
|
+
* @see reo:edge
|
|
78
|
+
*/
|
|
79
|
+
edge?: 'bass' | 'treble';
|
|
80
|
+
/**
|
|
81
|
+
* How far the tear reaches into the paper, taken across the roll
|
|
82
|
+
* from the edge it runs in from.
|
|
83
|
+
* @see reo:depth
|
|
84
|
+
*/
|
|
85
|
+
depth?: Measure<'mm'>;
|
|
86
|
+
/**
|
|
87
|
+
* IIIF region pointing to a depiction of the tear in the scan.
|
|
88
|
+
* @see crm:P138i has representation
|
|
89
|
+
*/
|
|
90
|
+
depiction?: string;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* An assignment of a condition (general, paper-stretch or a tear)
|
|
35
94
|
* to a roll copy, annotatable with a belief about its certainty.
|
|
36
95
|
*/
|
|
37
|
-
export type RollConditionAssignment = ObjectAssumption<GeneralRollCondition | PaperStretch>;
|
|
96
|
+
export type RollConditionAssignment = ObjectAssumption<GeneralRollCondition | PaperStretch | Tear>;
|
|
38
97
|
/**
|
|
39
98
|
* The keeper a copy is held by, as an object assumption, so that the
|
|
40
99
|
* statement can carry the belief it rests on and the reasons for it.
|
|
41
100
|
*/
|
|
42
101
|
export type KeeperAssignment = ObjectAssumption<Agent>;
|
|
43
|
-
export declare const rollConditions: readonly ['general', 'paper-stretch'];
|
|
102
|
+
export declare const rollConditions: readonly ['general', 'paper-stretch', 'torn'];
|
|
44
103
|
/**
|
|
45
|
-
*
|
|
46
|
-
*
|
|
47
|
-
*
|
|
104
|
+
* How far an alignment moves a copy's places before it scales them:
|
|
105
|
+
* along the roll, in the copy's own millimetres, and across it, in
|
|
106
|
+
* tracks.
|
|
48
107
|
*/
|
|
49
108
|
export interface Shift {
|
|
50
109
|
/** Along the roll. */
|
|
@@ -52,6 +111,56 @@ export interface Shift {
|
|
|
52
111
|
/** Across the tracker bar. */
|
|
53
112
|
vertical: Track;
|
|
54
113
|
}
|
|
114
|
+
/**
|
|
115
|
+
* How the copy's own places are carried onto the edition's axis, which
|
|
116
|
+
* is the millimetres of its reference copy (`Edition.referenceCopy`):
|
|
117
|
+
*
|
|
118
|
+
* x_axis = (x + shift.horizontal) · scale
|
|
119
|
+
* track_axis = track + shift.vertical
|
|
120
|
+
*
|
|
121
|
+
* It is found, not given: `alignCopy` matches the copy's notes with the
|
|
122
|
+
* reference copy's and records what it found, and can find it again.
|
|
123
|
+
* The document holds the copy's features and tears at its own places,
|
|
124
|
+
* as they were read, and this beside them; `importJsonLd` puts them
|
|
125
|
+
* onto the axis and `asJsonLd` takes them back, so that within the
|
|
126
|
+
* library every place along the roll is a place on the axis.
|
|
127
|
+
*
|
|
128
|
+
* What the scale is put down to, the paper or the speed the copy was
|
|
129
|
+
* cut for, is worked out from all the alignments together (`paperOf`).
|
|
130
|
+
* Not exported to RDF.
|
|
131
|
+
*/
|
|
132
|
+
export interface Alignment {
|
|
133
|
+
/**
|
|
134
|
+
* The copy it was found against, by id: the edition's reference
|
|
135
|
+
* copy at the time. Left out by alignments recorded before this was.
|
|
136
|
+
*/
|
|
137
|
+
against?: string;
|
|
138
|
+
/** Applied before the scale. */
|
|
139
|
+
shift: Shift;
|
|
140
|
+
/** Own millimetres to the axis's, applied after the shift. */
|
|
141
|
+
scale: number;
|
|
142
|
+
/** How many notes of the copy found their counterpart on the reference copy. */
|
|
143
|
+
matched?: number;
|
|
144
|
+
/** How far the counterparts still lie apart, as a root mean square in millimetres of the axis. */
|
|
145
|
+
residual?: Millimeters;
|
|
146
|
+
/**
|
|
147
|
+
* The standard error of the scale: the residual over the spread of
|
|
148
|
+
* the matched notes along the roll, as for a line of least squares.
|
|
149
|
+
*/
|
|
150
|
+
scaleError?: number;
|
|
151
|
+
/** The software that found it, and when. */
|
|
152
|
+
foundBy?: {
|
|
153
|
+
/** The name of the method. */
|
|
154
|
+
software: string;
|
|
155
|
+
/** Its revision (`ALIGNMENT_METHOD`). */
|
|
156
|
+
version: string;
|
|
157
|
+
/**
|
|
158
|
+
* The day it was found.
|
|
159
|
+
* @format date
|
|
160
|
+
*/
|
|
161
|
+
date: Date;
|
|
162
|
+
};
|
|
163
|
+
}
|
|
55
164
|
/** The margins on the treble and bass sides of the roll, in the unit the scan was measured in. */
|
|
56
165
|
export interface Margins<U extends 'px' | 'mm'> {
|
|
57
166
|
treble: Quantity<U>;
|
|
@@ -64,18 +173,6 @@ export interface Margins<U extends 'px' | 'mm'> {
|
|
|
64
173
|
* @see crm:E54 Dimension
|
|
65
174
|
*/
|
|
66
175
|
export type PaperSpeed = Measure<'ft/min'> | Measure<'m/min'>;
|
|
67
|
-
/**
|
|
68
|
-
* What the scale an alignment found is put down to: the paper of the
|
|
69
|
-
* copy having stretched or shrunk, or the copy having been cut for
|
|
70
|
-
* another paper speed than the roll it is aligned with.
|
|
71
|
-
*/
|
|
72
|
-
export type ScaleReading = {
|
|
73
|
-
cause: 'paper';
|
|
74
|
-
condition: ObjectAssumption<PaperStretch>;
|
|
75
|
-
} | {
|
|
76
|
-
cause: 'speed';
|
|
77
|
-
speed: ObjectAssumption<PaperSpeed>;
|
|
78
|
-
};
|
|
79
176
|
/**
|
|
80
177
|
* Describes the production of a roll copy: the manufacturer,
|
|
81
178
|
* the paper used, the date, and the system and paper speed the
|
|
@@ -114,8 +211,10 @@ export interface ProductionEvent {
|
|
|
114
211
|
/**
|
|
115
212
|
* The paper speed the copy was cut for. A copy cut from the same
|
|
116
213
|
* master for another speed comes out longer or shorter than the
|
|
117
|
-
* roll it is aligned with by the ratio of the speeds
|
|
118
|
-
*
|
|
214
|
+
* roll it is aligned with by the ratio of the speeds. The alignment
|
|
215
|
+
* measures that ratio far more closely than a label states a speed,
|
|
216
|
+
* so the speed is held against what the alignments give
|
|
217
|
+
* (`alignmentProblems`) rather than used to find it.
|
|
119
218
|
* @see reo:paperSpeed
|
|
120
219
|
*/
|
|
121
220
|
speed?: ObjectAssumption<PaperSpeed>;
|
|
@@ -209,8 +308,8 @@ export type Modification = Partial<{
|
|
|
209
308
|
export interface RollCopy extends WithType<'RollCopy'>, WithId {
|
|
210
309
|
/**
|
|
211
310
|
* Physical measurements of this roll copy, including
|
|
212
|
-
* dimensions, hole separation, margins,
|
|
213
|
-
* and information about the measuring software. What the
|
|
311
|
+
* dimensions, hole separation, margins, the alignment onto the
|
|
312
|
+
* edition's axis, and information about the measuring software. What the
|
|
214
313
|
* perforations tell about the machine that cut them is stated
|
|
215
314
|
* with the production.
|
|
216
315
|
* @see crm:P39i was measured by
|
|
@@ -252,17 +351,12 @@ export interface RollCopy extends WithType<'RollCopy'>, WithId {
|
|
|
252
351
|
*/
|
|
253
352
|
margins: Margins<'px'> | Margins<'mm'>;
|
|
254
353
|
/**
|
|
255
|
-
*
|
|
354
|
+
* How the copy's places are carried onto the edition's axis.
|
|
355
|
+
* Left out for the reference copy, whose places are the axis,
|
|
356
|
+
* and for a copy not aligned yet.
|
|
256
357
|
* Not exported to RDF.
|
|
257
358
|
*/
|
|
258
|
-
|
|
259
|
-
/**
|
|
260
|
-
* The factor this copy's features were scaled by to align them
|
|
261
|
-
* with the others. What it is put down to is stated apart: a
|
|
262
|
-
* paper-stretch condition, or the speed the copy was cut for.
|
|
263
|
-
* Not exported to RDF.
|
|
264
|
-
*/
|
|
265
|
-
scale: number;
|
|
359
|
+
alignment: Alignment;
|
|
266
360
|
/**
|
|
267
361
|
* What a pneumatic reader added to this copy's chains of holes,
|
|
268
362
|
* where it was taken off again. Such a reader reports how long a
|
|
@@ -332,7 +426,7 @@ export interface RollCopy extends WithType<'RollCopy'>, WithId {
|
|
|
332
426
|
production?: ProductionEvent;
|
|
333
427
|
/**
|
|
334
428
|
* Condition assessments of this roll copy (e.g. paper stretch,
|
|
335
|
-
* general wear). Each condition is an assumption annotatable
|
|
429
|
+
* general wear, a tear). Each condition is an assumption annotatable
|
|
336
430
|
* with a belief.
|
|
337
431
|
* @see crm:P44 has condition
|
|
338
432
|
*/
|
|
@@ -402,12 +496,14 @@ export declare const statesNothing: (modification: Modification) => boolean;
|
|
|
402
496
|
export declare const featuresByAct: (copy: Pick<RollCopy, 'production' | 'modifications'>) => FeatureOrPatch[][];
|
|
403
497
|
/** Every feature the copy states at a place of its own, whichever act made it. */
|
|
404
498
|
export declare const featuresOf: (copy: Pick<RollCopy, 'production' | 'modifications'>) => FeatureOrPatch[];
|
|
405
|
-
/**
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
*/
|
|
410
|
-
export declare const
|
|
499
|
+
/** Whether the condition is the stretch or shrinkage of the paper, as measured on the copy. */
|
|
500
|
+
export declare const isPaperStretch: (condition: RollConditionAssignment) => condition is ObjectAssumption<PaperStretch>;
|
|
501
|
+
/** What the copy's paper was measured to have done, where anything was measured. */
|
|
502
|
+
export declare const paperStretchOf: (copy: Pick<RollCopy, 'conditions'>) => ObjectAssumption<PaperStretch> | undefined;
|
|
503
|
+
/** Whether the condition is a tear in the paper. */
|
|
504
|
+
export declare const isTear: (condition: RollConditionAssignment) => condition is ObjectAssumption<Tear>;
|
|
505
|
+
/** The tears the copy is stated to have. */
|
|
506
|
+
export declare const tearsOf: (copy: Pick<RollCopy, 'conditions'>) => ObjectAssumption<Tear>[];
|
|
411
507
|
/**
|
|
412
508
|
* The bar a copy is read by, which is the one it was cut for. A copy
|
|
413
509
|
* that names no system falls back to `defaultTrackerBar`.
|
package/lib/model/RollCopy.js
CHANGED
|
@@ -4,7 +4,8 @@ import { assignReference, certaintyOf, isAsserted } from "./Assumption.js";
|
|
|
4
4
|
import { px, track } from "./Quantity.js";
|
|
5
5
|
export const rollConditions = [
|
|
6
6
|
'general',
|
|
7
|
-
'paper-stretch'
|
|
7
|
+
'paper-stretch',
|
|
8
|
+
'torn'
|
|
8
9
|
];
|
|
9
10
|
export const modificationPurposes = [
|
|
10
11
|
'musical-improvement',
|
|
@@ -34,12 +35,14 @@ export const statesNothing = (modification) => modification.type === 'Removal' ?
|
|
|
34
35
|
export const featuresByAct = (copy) => [copy.production?.produced ?? [], ...copy.modifications.map(featuresMadeBy)];
|
|
35
36
|
/** Every feature the copy states at a place of its own, whichever act made it. */
|
|
36
37
|
export const featuresOf = (copy) => featuresByAct(copy).flat();
|
|
37
|
-
/**
|
|
38
|
-
* Whether the condition is the stretch or shrinkage of the paper. A
|
|
39
|
-
* scale put down to this belongs to the one exemplar and says nothing
|
|
40
|
-
* about the speed its system's rolls were cut at.
|
|
41
|
-
*/
|
|
38
|
+
/** Whether the condition is the stretch or shrinkage of the paper, as measured on the copy. */
|
|
42
39
|
export const isPaperStretch = (condition) => condition.conditionType === 'paper-stretch';
|
|
40
|
+
/** What the copy's paper was measured to have done, where anything was measured. */
|
|
41
|
+
export const paperStretchOf = (copy) => copy.conditions.find(isPaperStretch);
|
|
42
|
+
/** Whether the condition is a tear in the paper. */
|
|
43
|
+
export const isTear = (condition) => condition.conditionType === 'torn';
|
|
44
|
+
/** The tears the copy is stated to have. */
|
|
45
|
+
export const tearsOf = (copy) => copy.conditions.filter(isTear);
|
|
43
46
|
/**
|
|
44
47
|
* The bar a copy is read by, which is the one it was cut for. A copy
|
|
45
48
|
* that names no system falls back to `defaultTrackerBar`.
|
package/lib/ops/copies.d.ts
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { Draft } from "immer";
|
|
3
3
|
import { Edition } from "../model/Edition.js";
|
|
4
4
|
import { AnySymbol } from "../model/Symbol.js";
|
|
5
|
-
import { GeneralRollCondition,
|
|
5
|
+
import { Alignment, GeneralRollCondition, PaperStretch, RollCopy, Tear } from "../model/RollCopy.js";
|
|
6
6
|
import { FeatureSource } from "../model/FeatureSource.js";
|
|
7
7
|
import { Belief, ObjectAssumption, ReferenceAssumption } from "../model/Assumption.js";
|
|
8
8
|
import { Millimeters } from "../model/Quantity.js";
|
|
@@ -21,15 +21,38 @@ export declare const createVersion: (copy: RollCopy) => EditionOp;
|
|
|
21
21
|
*/
|
|
22
22
|
export declare const addCopy: (copy: RollCopy) => EditionOp;
|
|
23
23
|
/**
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
* or the
|
|
24
|
+
* What aligning the copy with the reference copy finds, or nothing
|
|
25
|
+
* where the two share no run of notes, where there is no reference
|
|
26
|
+
* copy, or where the copy is the reference itself. The copy is read at
|
|
27
|
+
* its own places whatever alignment it has, and through its own bar,
|
|
28
|
+
* which is what lets a copy cut for another system be aligned at all.
|
|
27
29
|
*/
|
|
28
|
-
export declare const
|
|
30
|
+
export declare const alignmentFor: (edition: Edition, copy: RollCopy, date?: Date) => Alignment | undefined;
|
|
29
31
|
/**
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
32
|
+
* Aligns the copy with the edition's reference copy: finds the shift
|
|
33
|
+
* and scale that carry its notes onto the reference copy's, and puts
|
|
34
|
+
* its features and tears onto the axis by them, in place of any
|
|
35
|
+
* alignment it had. A copy that shares no run of notes with the
|
|
36
|
+
* reference copy is left as it was.
|
|
37
|
+
*/
|
|
38
|
+
export declare const alignCopy: (copyId: string, date?: Date) => EditionOp;
|
|
39
|
+
/**
|
|
40
|
+
* Aligns every copy that has features with the reference copy, as
|
|
41
|
+
* `alignCopy` does one. The reference copy itself is taken off any
|
|
42
|
+
* alignment it had, its places being the axis.
|
|
43
|
+
*/
|
|
44
|
+
export declare const alignCopies: (date?: Date) => EditionOp;
|
|
45
|
+
/**
|
|
46
|
+
* Makes the copy the one whose millimetres are the edition's axis, and
|
|
47
|
+
* aligns every other copy onto it. Every place the edition gives along
|
|
48
|
+
* the roll moves with this, which is why it is a choice and not
|
|
49
|
+
* something worked out.
|
|
50
|
+
*/
|
|
51
|
+
export declare const chooseReferenceCopy: (copyId: string, date?: Date) => EditionOp;
|
|
52
|
+
/**
|
|
53
|
+
* Puts the copy's features back where they were measured, off the
|
|
54
|
+
* axis. What the alignments say about the paper goes with it, since
|
|
55
|
+
* that is worked out from them.
|
|
33
56
|
*/
|
|
34
57
|
export declare const unalignCopy: (copyId: string) => EditionOp;
|
|
35
58
|
/**
|
|
@@ -60,10 +83,24 @@ export declare const stateCarriage: (copyId: string, versionId: string, belief?:
|
|
|
60
83
|
export declare const clearCarriage: (copyId: string, versionId: string) => EditionOp;
|
|
61
84
|
/**
|
|
62
85
|
* Adds a general condition to the copy, beside whatever is stated of it
|
|
63
|
-
* already.
|
|
64
|
-
*
|
|
86
|
+
* already. A paper stretch is added the same way, where one was
|
|
87
|
+
* measured; what the alignments say of the paper is worked out from
|
|
88
|
+
* them and stated nowhere.
|
|
65
89
|
*/
|
|
66
90
|
export declare const addGeneralCondition: (copyId: string, condition: ObjectAssumption<GeneralRollCondition>) => EditionOp;
|
|
91
|
+
/**
|
|
92
|
+
* States what the copy's paper was measured to have done, in place of
|
|
93
|
+
* what was stated before; given nothing, it takes the statement away. A
|
|
94
|
+
* copy has one paper, so it has one such condition, which may give a
|
|
95
|
+
* strain in either direction.
|
|
96
|
+
*/
|
|
97
|
+
export declare const statePaperStretch: (copyId: string, stretch?: ObjectAssumption<PaperStretch>) => EditionOp;
|
|
98
|
+
/**
|
|
99
|
+
* Adds a tear to the copy, beside whatever is stated of it already. The
|
|
100
|
+
* tear is given on the axis, where the copy's features stand, and moves
|
|
101
|
+
* with them from then on.
|
|
102
|
+
*/
|
|
103
|
+
export declare const addTear: (copyId: string, tear: ObjectAssumption<Tear>) => EditionOp;
|
|
67
104
|
/** The symbols of the versions that no other copy carries. */
|
|
68
105
|
export declare const symbolsCarriedOnlyBy: (edition: Edition, copyId: string) => AnySymbol[];
|
|
69
106
|
/**
|
package/lib/ops/copies.js
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { v4 } from "uuid";
|
|
2
|
+
import { referenceCopyOf } from "../model/Edition.js";
|
|
2
3
|
import { asSymbols, barOf, featuresOf, isPaperStretch } from "../model/RollCopy.js";
|
|
3
4
|
import { systemOf } from "../systems/TrackerBar.js";
|
|
4
|
-
import {
|
|
5
|
+
import { alignFeatures, ALIGNMENT_METHOD, applyAlignment, ownFeaturesOf, revertAlignment, revertShortening, shortenChains } from "../collation/alignment.js";
|
|
5
6
|
import { idOf } from "../model/Assumption.js";
|
|
7
|
+
import { track } from "../model/Quantity.js";
|
|
6
8
|
import { onCopy, stateOf, insertion, insertedIn, referenceHeld, withoutReferences } from "./draft.js";
|
|
7
9
|
import { without } from "./immutable.js";
|
|
8
10
|
import { featureIdsOf, carriedOnlyOn, forgetFeatures } from "./forget.js";
|
|
@@ -30,36 +32,80 @@ export const createVersion = (copy) => draft => {
|
|
|
30
32
|
export const addCopy = (copy) => draft => {
|
|
31
33
|
draft.copies.push(copy);
|
|
32
34
|
};
|
|
33
|
-
/**
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
35
|
+
/**
|
|
36
|
+
* What aligning the copy with the reference copy finds, or nothing
|
|
37
|
+
* where the two share no run of notes, where there is no reference
|
|
38
|
+
* copy, or where the copy is the reference itself. The copy is read at
|
|
39
|
+
* its own places whatever alignment it has, and through its own bar,
|
|
40
|
+
* which is what lets a copy cut for another system be aligned at all.
|
|
41
|
+
*/
|
|
42
|
+
export const alignmentFor = (edition, copy, date = new Date()) => {
|
|
43
|
+
const reference = referenceCopyOf(edition);
|
|
44
|
+
if (!reference || reference.id === copy.id)
|
|
45
|
+
return undefined;
|
|
46
|
+
const found = alignFeatures(ownFeaturesOf(copy), featuresOf(reference), barOf(copy), barOf(reference));
|
|
47
|
+
if (!found)
|
|
48
|
+
return undefined;
|
|
49
|
+
return {
|
|
50
|
+
against: reference.id,
|
|
51
|
+
shift: { horizontal: found.shift, vertical: track(0) },
|
|
52
|
+
scale: found.scale,
|
|
53
|
+
matched: found.matched,
|
|
54
|
+
residual: found.residual,
|
|
55
|
+
scaleError: found.scaleError,
|
|
56
|
+
foundBy: { ...ALIGNMENT_METHOD, date }
|
|
57
|
+
};
|
|
58
|
+
};
|
|
59
|
+
/**
|
|
60
|
+
* Aligns the copy with the edition's reference copy: finds the shift
|
|
61
|
+
* and scale that carry its notes onto the reference copy's, and puts
|
|
62
|
+
* its features and tears onto the axis by them, in place of any
|
|
63
|
+
* alignment it had. A copy that shares no run of notes with the
|
|
64
|
+
* reference copy is left as it was.
|
|
65
|
+
*/
|
|
66
|
+
export const alignCopy = (copyId, date = new Date()) => draft => {
|
|
67
|
+
const state = stateOf(draft);
|
|
68
|
+
const copy = state.copies.find(c => c.id === copyId);
|
|
69
|
+
const alignment = copy && alignmentFor(state, copy, date);
|
|
70
|
+
const target = draft.copies.find(c => c.id === copyId);
|
|
71
|
+
if (alignment && target)
|
|
72
|
+
applyAlignment(alignment, target);
|
|
73
|
+
};
|
|
74
|
+
/**
|
|
75
|
+
* Aligns every copy that has features with the reference copy, as
|
|
76
|
+
* `alignCopy` does one. The reference copy itself is taken off any
|
|
77
|
+
* alignment it had, its places being the axis.
|
|
78
|
+
*/
|
|
79
|
+
export const alignCopies = (date = new Date()) => draft => {
|
|
80
|
+
const reference = referenceCopyOf(stateOf(draft));
|
|
81
|
+
if (!reference)
|
|
37
82
|
return;
|
|
38
|
-
|
|
39
|
-
if (
|
|
40
|
-
|
|
41
|
-
|
|
83
|
+
const own = draft.copies.find(c => c.id === reference.id);
|
|
84
|
+
if (own)
|
|
85
|
+
revertAlignment(own);
|
|
86
|
+
stateOf(draft).copies
|
|
87
|
+
.filter(copy => copy.id !== reference.id && featuresOf(copy).length > 0)
|
|
88
|
+
.forEach(copy => alignCopy(copy.id, date)(draft));
|
|
42
89
|
};
|
|
43
90
|
/**
|
|
44
|
-
*
|
|
45
|
-
*
|
|
46
|
-
*
|
|
91
|
+
* Makes the copy the one whose millimetres are the edition's axis, and
|
|
92
|
+
* aligns every other copy onto it. Every place the edition gives along
|
|
93
|
+
* the roll moves with this, which is why it is a choice and not
|
|
94
|
+
* something worked out.
|
|
47
95
|
*/
|
|
48
|
-
export const
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
}
|
|
96
|
+
export const chooseReferenceCopy = (copyId, date = new Date()) => draft => {
|
|
97
|
+
if (!draft.copies.some(copy => copy.id === copyId))
|
|
98
|
+
return;
|
|
99
|
+
draft.referenceCopy = copyId;
|
|
100
|
+
alignCopies(date)(draft);
|
|
101
|
+
};
|
|
54
102
|
/**
|
|
55
|
-
* Puts the copy's features back where they were measured
|
|
56
|
-
*
|
|
57
|
-
*
|
|
103
|
+
* Puts the copy's features back where they were measured, off the
|
|
104
|
+
* axis. What the alignments say about the paper goes with it, since
|
|
105
|
+
* that is worked out from them.
|
|
58
106
|
*/
|
|
59
107
|
export const unalignCopy = (copyId) => onCopy(copyId, copy => {
|
|
60
|
-
|
|
61
|
-
revertShift(copy);
|
|
62
|
-
copy.conditions = without(copy.conditions, isPaperStretch);
|
|
108
|
+
revertAlignment(copy);
|
|
63
109
|
});
|
|
64
110
|
/**
|
|
65
111
|
* Takes the extension a pneumatic reader adds off the ends of the
|
|
@@ -113,12 +159,30 @@ export const stateCarriage = (copyId, versionId, belief) => onCopy(copyId, copy
|
|
|
113
159
|
export const clearCarriage = (copyId, versionId) => onCopy(copyId, copy => dropStatements(copy, statement => idOf(statement) === versionId));
|
|
114
160
|
/**
|
|
115
161
|
* Adds a general condition to the copy, beside whatever is stated of it
|
|
116
|
-
* already.
|
|
117
|
-
*
|
|
162
|
+
* already. A paper stretch is added the same way, where one was
|
|
163
|
+
* measured; what the alignments say of the paper is worked out from
|
|
164
|
+
* them and stated nowhere.
|
|
118
165
|
*/
|
|
119
166
|
export const addGeneralCondition = (copyId, condition) => onCopy(copyId, copy => {
|
|
120
167
|
copy.conditions.push(condition);
|
|
121
168
|
});
|
|
169
|
+
/**
|
|
170
|
+
* States what the copy's paper was measured to have done, in place of
|
|
171
|
+
* what was stated before; given nothing, it takes the statement away. A
|
|
172
|
+
* copy has one paper, so it has one such condition, which may give a
|
|
173
|
+
* strain in either direction.
|
|
174
|
+
*/
|
|
175
|
+
export const statePaperStretch = (copyId, stretch) => onCopy(copyId, copy => {
|
|
176
|
+
copy.conditions = [...without(copy.conditions, isPaperStretch), ...(stretch ? [stretch] : [])];
|
|
177
|
+
});
|
|
178
|
+
/**
|
|
179
|
+
* Adds a tear to the copy, beside whatever is stated of it already. The
|
|
180
|
+
* tear is given on the axis, where the copy's features stand, and moves
|
|
181
|
+
* with them from then on.
|
|
182
|
+
*/
|
|
183
|
+
export const addTear = (copyId, tear) => onCopy(copyId, copy => {
|
|
184
|
+
copy.conditions.push(tear);
|
|
185
|
+
});
|
|
122
186
|
/** The symbols of the versions that no other copy carries. */
|
|
123
187
|
export const symbolsCarriedOnlyBy = (edition, copyId) => {
|
|
124
188
|
const copy = edition.copies.find(c => c.id === copyId);
|
|
@@ -132,4 +196,6 @@ export const symbolsCarriedOnlyBy = (edition, copyId) => {
|
|
|
132
196
|
export const removeCopy = (copyId) => onCopy(copyId, (copy, draft) => {
|
|
133
197
|
forgetFeatures(draft, featureIdsOf(copy));
|
|
134
198
|
draft.copies = draft.copies.filter(c => c.id !== copyId);
|
|
199
|
+
if (draft.referenceCopy === copyId)
|
|
200
|
+
delete draft.referenceCopy;
|
|
135
201
|
});
|
package/lib/ops/index.d.ts
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* the ones the library offers.
|
|
5
5
|
*/
|
|
6
6
|
export type { EditionOp } from "./draft.js";
|
|
7
|
-
export { createVersion, addCopy, alignCopy, unalignCopy, shortenCopy, unshortenCopy, stateSource, clearSource, nameCopy, stateCarriage, clearCarriage, addGeneralCondition, symbolsCarriedOnlyBy, removeCopy } from "./copies.js";
|
|
7
|
+
export { createVersion, addCopy, alignmentFor, alignCopy, alignCopies, chooseReferenceCopy, unalignCopy, shortenCopy, unshortenCopy, stateSource, clearSource, nameCopy, stateCarriage, clearCarriage, addGeneralCondition, statePaperStretch, addTear, symbolsCarriedOnlyBy, removeCopy } from "./copies.js";
|
|
8
8
|
export { stateFeatureCondition, addFeature, addBorneFeature, removeFeatures, mergeObstacle, mergeObstacleIn, mergeFeatures, type FeatureAct, type MergeObstacle } from "./features.js";
|
|
9
9
|
export { detachVersion, removeVersion, removeSymbols, deriveVersion, stateDerivation, clearDerivation } from "./versions.js";
|
|
10
10
|
export { connectVersions, collateSymbols, separateReadings } from "./collation.js";
|
package/lib/ops/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { createVersion, addCopy, alignCopy, unalignCopy, shortenCopy, unshortenCopy, stateSource, clearSource, nameCopy, stateCarriage, clearCarriage, addGeneralCondition, symbolsCarriedOnlyBy, removeCopy } from "./copies.js";
|
|
1
|
+
export { createVersion, addCopy, alignmentFor, alignCopy, alignCopies, chooseReferenceCopy, unalignCopy, shortenCopy, unshortenCopy, stateSource, clearSource, nameCopy, stateCarriage, clearCarriage, addGeneralCondition, statePaperStretch, addTear, symbolsCarriedOnlyBy, removeCopy } from "./copies.js";
|
|
2
2
|
export { stateFeatureCondition, addFeature, addBorneFeature, removeFeatures, mergeObstacle, mergeObstacleIn, mergeFeatures } from "./features.js";
|
|
3
3
|
export { detachVersion, removeVersion, removeSymbols, deriveVersion, stateDerivation, clearDerivation } from "./versions.js";
|
|
4
4
|
export { connectVersions, collateSymbols, separateReadings } from "./collation.js";
|
|
@@ -96,6 +96,33 @@ const stanfordScan = (druid) => ({
|
|
|
96
96
|
scan: `https://stacks.stanford.edu/image/iiif/${druid}%2F${druid}_0001/`,
|
|
97
97
|
depictionOf: (column, row, width, height) => `https://stacks.stanford.edu/image/iiif/${druid}/${druid}_0001/${column},${row},${width},${height}/128,/270/default.jpg`
|
|
98
98
|
});
|
|
99
|
+
/**
|
|
100
|
+
* The edge tears the analysis found, one condition each. The analysis
|
|
101
|
+
* lists only those that reach deeper into the paper than a tenth of an
|
|
102
|
+
* inch, and measures each by the box around it, so the tear runs across
|
|
103
|
+
* the roll as far as the box is wide.
|
|
104
|
+
*/
|
|
105
|
+
const tearsIn = (tears, dpi, depictionOf) => {
|
|
106
|
+
const onEdge = (edge, listed) => listOf(listed).map((tear) => {
|
|
107
|
+
const row = readPx(tear.ORIGIN_ROW);
|
|
108
|
+
const length = readPx(tear.WIDTH_ROW);
|
|
109
|
+
const column = readPx(tear.ORIGIN_COL);
|
|
110
|
+
const depth = readPx(tear.WIDTH_COL);
|
|
111
|
+
return {
|
|
112
|
+
conditionType: 'torn',
|
|
113
|
+
horizontal: {
|
|
114
|
+
unit: 'mm',
|
|
115
|
+
from: inMillimeters(row, dpi),
|
|
116
|
+
to: inMillimeters(px(row + length), dpi)
|
|
117
|
+
},
|
|
118
|
+
edge,
|
|
119
|
+
depth: { value: inMillimeters(depth, dpi), unit: 'mm' },
|
|
120
|
+
...(depictionOf && { depiction: depictionOf(column, row, depth, length) })
|
|
121
|
+
};
|
|
122
|
+
});
|
|
123
|
+
return [...onEdge('bass', tears?.BASS_TEARS?.TEAR), ...onEdge('treble', tears?.TREBLE_TEARS?.TEAR)]
|
|
124
|
+
.sort((a, b) => a.horizontal.from - b.horizontal.from);
|
|
125
|
+
};
|
|
99
126
|
/**
|
|
100
127
|
* The software behind an analysis and when it was run, as the
|
|
101
128
|
* analysis file states them.
|
|
@@ -155,7 +182,7 @@ export function readFromStanfordAton(atonString, { trackShift, system = welteT10
|
|
|
155
182
|
return {
|
|
156
183
|
type: 'RollCopy',
|
|
157
184
|
id: v4(),
|
|
158
|
-
conditions:
|
|
185
|
+
conditions: tearsIn(json.ROLLINFO.TEARS, dpi, stanford?.depictionOf),
|
|
159
186
|
production: {
|
|
160
187
|
system: systemOf(system),
|
|
161
188
|
...(punchDiameter !== undefined && {
|