linked-rolls 0.62.0 → 0.64.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.
Files changed (71) hide show
  1. package/README.md +26 -7
  2. package/lib/analysis/constraints.d.ts +2 -2
  3. package/lib/analysis/constraints.js +30 -21
  4. package/lib/analysis/ownPaper.d.ts +11 -16
  5. package/lib/analysis/ownPaper.js +13 -31
  6. package/lib/analysis/paper.d.ts +129 -0
  7. package/lib/analysis/paper.js +260 -0
  8. package/lib/analysis/reservations.d.ts +2 -2
  9. package/lib/analysis/reservations.js +6 -6
  10. package/lib/analysis/sigla.d.ts +4 -5
  11. package/lib/analysis/sigla.js +4 -4
  12. package/lib/analysis/stemma.d.ts +22 -0
  13. package/lib/analysis/stemma.js +38 -0
  14. package/lib/analysis/text.d.ts +31 -0
  15. package/lib/analysis/text.js +62 -0
  16. package/lib/analysis/witnesses.d.ts +5 -5
  17. package/lib/analysis/witnesses.js +22 -20
  18. package/lib/collation/alignment.d.ts +46 -8
  19. package/lib/collation/alignment.js +137 -47
  20. package/lib/collation/scatter.d.ts +4 -4
  21. package/lib/collation/scatter.js +15 -13
  22. package/lib/emulation/Emulation.d.ts +7 -7
  23. package/lib/emulation/Emulation.js +29 -27
  24. package/lib/emulation/negotiation.d.ts +2 -2
  25. package/lib/emulation/negotiation.js +3 -2
  26. package/lib/index.d.ts +6 -2
  27. package/lib/index.js +6 -2
  28. package/lib/io/asJsonLd.js +16 -1
  29. package/lib/io/importJsonLd.d.ts +5 -0
  30. package/lib/io/importJsonLd.js +18 -1
  31. package/lib/io/migrate.js +94 -2
  32. package/lib/lookup/lookup.d.ts +32 -0
  33. package/lib/lookup/lookup.js +40 -0
  34. package/lib/lookup/paths.d.ts +11 -0
  35. package/lib/lookup/paths.js +78 -0
  36. package/lib/lookup/perState.d.ts +32 -0
  37. package/lib/lookup/perState.js +63 -0
  38. package/lib/model/Assumption.d.ts +21 -9
  39. package/lib/model/Edit.d.ts +4 -0
  40. package/lib/model/Edition.d.ts +19 -0
  41. package/lib/model/Edition.js +9 -1
  42. package/lib/model/Quantity.d.ts +4 -1
  43. package/lib/model/Quantity.js +1 -0
  44. package/lib/model/RollCopy.d.ts +144 -48
  45. package/lib/model/RollCopy.js +9 -6
  46. package/lib/model/Version.d.ts +7 -1
  47. package/lib/ops/beliefs.d.ts +1 -1
  48. package/lib/ops/beliefs.js +1 -1
  49. package/lib/ops/collation.d.ts +3 -4
  50. package/lib/ops/collation.js +25 -23
  51. package/lib/ops/commands.d.ts +4 -5
  52. package/lib/ops/commands.js +10 -10
  53. package/lib/ops/copies.d.ts +47 -10
  54. package/lib/ops/copies.js +92 -26
  55. package/lib/ops/draft.d.ts +12 -12
  56. package/lib/ops/draft.js +11 -13
  57. package/lib/ops/edits.d.ts +1 -2
  58. package/lib/ops/edits.js +13 -10
  59. package/lib/ops/features.d.ts +2 -2
  60. package/lib/ops/features.js +3 -2
  61. package/lib/ops/index.d.ts +2 -2
  62. package/lib/ops/index.js +7 -1
  63. package/lib/ops/versions.d.ts +2 -3
  64. package/lib/ops/versions.js +6 -5
  65. package/lib/readers/stanfordAton.js +28 -1
  66. package/lib/schema.json +185 -26
  67. package/lib/spec/context.json +33 -1
  68. package/lib/systems/ReproducingSystem.d.ts +7 -6
  69. package/package.json +1 -1
  70. package/lib/view/EditionView.d.ts +0 -103
  71. package/lib/view/EditionView.js +0 -329
@@ -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
- * This condition state is used to describe the roll's
14
- * paper shrinkage or stretching. It might be calculated
15
- * on the basis of comparing the vertical or horizontal
16
- * extent with other witnesses of the same roll.
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 stretch factor, e.g. 1.02 means the paper has
21
- * stretched by 2% compared to its original dimensions.
22
- * @see rdf:value
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
- factor: number;
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
- * An assignment of a condition (general or paper-stretch)
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
- * A shift correction applied to a roll copy to align it
46
- * with other copies. The shift is defined as horizontal
47
- * (along the roll length, in mm) and vertical (across tracks).
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, which is
118
- * what the alignment then measures.
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, shift corrections,
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
- * The shift applied to align this copy with the others.
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
- shift: Shift;
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
- * Whether the condition is the stretch or shrinkage of the paper. A
407
- * scale put down to this belongs to the one exemplar and says nothing
408
- * about the speed its system's rolls were cut at.
409
- */
410
- export declare const isPaperStretch: (condition: RollConditionAssignment) => boolean;
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`.
@@ -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`.
@@ -93,7 +93,13 @@ export interface Version extends WithId {
93
93
  basedOn?: Derivation[];
94
94
  /**
95
95
  * The act that made this version, where it is known: who carried it
96
- * out, when, and by what rule.
96
+ * out, when, and by what rule. The export states the act for every
97
+ * version, stating nothing of it where nothing is known, so that the
98
+ * axioms of reo.ttl can place it in time: it started after the
99
+ * recording and the creation of every version it derives from had
100
+ * started, and ended no later than the punching of any copy carrying
101
+ * a symbol it added. A date stated here stands beside those; which of
102
+ * them bounds the act closest is for a query to pick.
97
103
  * @see lrmoo:R17i was created by
98
104
  */
99
105
  creation?: VersionCreation;
@@ -1,4 +1,4 @@
1
- import { Path } from "../view/EditionView.js";
1
+ import { Path } from "../lookup/paths.js";
2
2
  import { AnyArgumentation, Certainty } from "../model/Assumption.js";
3
3
  import { EditionOp } from "./draft.js";
4
4
  /** Annotates the assumption at the path with a belief held true, for reasons to be added. */
@@ -1,5 +1,5 @@
1
1
  import { v4 } from "uuid";
2
- import { getAt } from "../view/EditionView.js";
2
+ import { getAt } from "../lookup/paths.js";
3
3
  const onAssumptionAt = (path, op) => draft => {
4
4
  const assumption = getAt(path, draft);
5
5
  if (assumption)
@@ -1,4 +1,3 @@
1
- import { EditionView } from "../view/EditionView.js";
2
1
  import { CollationTolerance } from "../collation/Collation.js";
3
2
  import { ObjectAssumption } from "../model/Assumption.js";
4
3
  import { EditionOp } from "./draft.js";
@@ -28,13 +27,13 @@ import { EditionOp } from "./draft.js";
28
27
  * statement, since the stemma would loop; asked for that, nothing
29
28
  * changes.
30
29
  */
31
- export declare const connectVersions: (given: EditionView, childId: string, parentId: string, tolerance?: ObjectAssumption<CollationTolerance>) => EditionOp;
30
+ export declare const connectVersions: (childId: string, parentId: string, tolerance?: ObjectAssumption<CollationTolerance>) => EditionOp;
32
31
  /**
33
32
  * Folds the version's own symbols into those it inherits and collates
34
33
  * with: the carriers pass over, and the insertions go. Collates at the
35
34
  * tolerance of the derivation, where the caller names none.
36
35
  */
37
- export declare const collateSymbols: (given: EditionView, versionId: string, symbolIds: readonly string[], tolerance?: CollationTolerance) => EditionOp;
36
+ export declare const collateSymbols: (versionId: string, symbolIds: readonly string[], tolerance?: CollationTolerance) => EditionOp;
38
37
  /**
39
38
  * Takes the named copies' reading of a symbol back out of the symbol it
40
39
  * was collated into: their carriers pass to a new symbol of the
@@ -59,4 +58,4 @@ export declare const collateSymbols: (given: EditionView, versionId: string, sym
59
58
  * keeps its identifier and the edit that speaks for it. Named symbols
60
59
  * narrow the act to those; naming none separates the whole reading.
61
60
  */
62
- export declare const separateReadings: (given: EditionView, versionId: string, copies: ReadonlySet<string>, symbolIds?: readonly string[]) => EditionOp;
61
+ export declare const separateReadings: (versionId: string, copies: ReadonlySet<string>, symbolIds?: readonly string[]) => EditionOp;
@@ -1,5 +1,5 @@
1
1
  import { v4 } from "uuid";
2
- import { getAt } from "../view/EditionView.js";
2
+ import { getAt, pathIn } from "../lookup/paths.js";
3
3
  import { collationsOf, defaultCollationTolerance, isCollationsOwn, unchecked } from "../collation/Collation.js";
4
4
  import { collationToleranceOf, derivesFrom, editsOf, insertedBy, principalDerivationOf } from "../model/Version.js";
5
5
  import { substitutionsBetween } from "../collation/substitution.js";
@@ -7,9 +7,11 @@ import { trackerBarOf } from "../systems/index.js";
7
7
  import { assignReference, idOf } from "../model/Assumption.js";
8
8
  import { noChange, onVersion, stateOf, insertion, deletion, asUnchecked, declaring, insertedIn, dropInsertions, reading } from "./draft.js";
9
9
  import { hypothesesBeside } from "./versions.js";
10
+ import { placeOf, snapshotOf } from "../analysis/text.js";
11
+ import { copyOfFeature, versionIn } from "../lookup/lookup.js";
10
12
  /** The carriers of each collated symbol pass to its counterpart. */
11
- const handOverCarriers = (view, draft, collations) => collations.forEach(({ symbol, counterpart }) => {
12
- const path = view.getPath(counterpart.id);
13
+ const handOverCarriers = (edition, draft, collations) => collations.forEach(({ symbol, counterpart }) => {
14
+ const path = pathIn(edition, counterpart.id);
13
15
  const target = path && getAt(path, draft);
14
16
  target?.carriers.push(...symbol.carriers);
15
17
  });
@@ -59,10 +61,10 @@ const byExchange = (edits) => new Map(edits.map(edit => [exchangeKey((edit.inser
59
61
  * statement, since the stemma would loop; asked for that, nothing
60
62
  * changes.
61
63
  */
62
- export const connectVersions = (given, childId, parentId, tolerance = defaultCollationTolerance) => reading(given, view => {
63
- if (childId === parentId || derivesFrom(view.edition.versions, parentId, childId))
64
+ export const connectVersions = (childId, parentId, tolerance = defaultCollationTolerance) => reading(edition => {
65
+ if (childId === parentId || derivesFrom(edition.versions, parentId, childId))
64
66
  return noChange;
65
- const child = view.version(childId);
67
+ const child = versionIn(edition, childId);
66
68
  const stated = child ? editsOf(child) : [];
67
69
  const established = stated.filter(edit => !isCollationsOwn(edit));
68
70
  const spokenFor = spokenForBy(established);
@@ -71,12 +73,12 @@ export const connectVersions = (given, childId, parentId, tolerance = defaultCol
71
73
  // through: it is neither the child's own symbol nor one it lacks.
72
74
  // Without that, connecting a pair already connected would collate
73
75
  // the inherited symbols with themselves and double their carriers.
74
- const handedDown = view.snapshot(parentId).filter(unspoken);
75
- const shown = new Set(view.snapshot(childId).map(symbol => symbol.id));
76
+ const handedDown = snapshotOf(edition, parentId).filter(unspoken);
77
+ const shown = new Set(snapshotOf(edition, childId).map(symbol => symbol.id));
76
78
  const inheritedIds = new Set(handedDown.map(symbol => symbol.id));
77
79
  const inherited = handedDown.filter(symbol => !shown.has(symbol.id));
78
- const own = view.snapshot(childId).filter(symbol => unspoken(symbol) && !inheritedIds.has(symbol.id));
79
- const locate = (symbol) => view.placeOf(symbol);
80
+ const own = snapshotOf(edition, childId).filter(symbol => unspoken(symbol) && !inheritedIds.has(symbol.id));
81
+ const locate = (symbol) => placeOf(edition, symbol);
80
82
  const collations = collationsOf(own, inherited, locate, tolerance);
81
83
  const collated = new Set(collations.map(({ symbol }) => symbol.id));
82
84
  const matched = new Set(collations.map(({ counterpart }) => counterpart.id));
@@ -87,7 +89,7 @@ export const connectVersions = (given, childId, parentId, tolerance = defaultCol
87
89
  * apart would make the apparatus a list of unexplained losses beside
88
90
  * a list of unexplained gains.
89
91
  */
90
- const substituted = differ(child, view.version(parentId))
92
+ const substituted = differ(child, versionIn(edition, parentId))
91
93
  ? substitutionsBetween(own.filter(symbol => !collated.has(symbol.id)), inherited.filter(symbol => !matched.has(symbol.id)), locate, tolerance)
92
94
  : [];
93
95
  const paired = new Set(substituted.flatMap(({ replaced, by }) => [...by, ...replaced].map(symbol => symbol.id)));
@@ -113,7 +115,7 @@ export const connectVersions = (given, childId, parentId, tolerance = defaultCol
113
115
  .map(symbol => asUnchecked(deletion(symbol.id)))
114
116
  ];
115
117
  return onVersion(childId, (child, draft) => {
116
- handOverCarriers(view, draft, collations);
118
+ handOverCarriers(edition, draft, collations);
117
119
  child.edits = edits;
118
120
  child.motivations = declaring(stateOf(child).motivations, edits);
119
121
  child.basedOn = [
@@ -127,17 +129,17 @@ export const connectVersions = (given, childId, parentId, tolerance = defaultCol
127
129
  * with: the carriers pass over, and the insertions go. Collates at the
128
130
  * tolerance of the derivation, where the caller names none.
129
131
  */
130
- export const collateSymbols = (given, versionId, symbolIds, tolerance) => reading(given, view => {
131
- const version = view.version(versionId);
132
+ export const collateSymbols = (versionId, symbolIds, tolerance) => reading(edition => {
133
+ const version = versionIn(edition, versionId);
132
134
  const principal = version && principalDerivationOf(version);
133
135
  if (!version || !principal)
134
136
  return noChange;
135
137
  const chosen = new Set(symbolIds);
136
138
  const own = insertedIn([version]).filter(symbol => chosen.has(symbol.id));
137
- const collations = collationsOf(own, view.snapshot(idOf(principal)), symbol => view.placeOf(symbol), tolerance ?? collationToleranceOf(principal));
139
+ const collations = collationsOf(own, snapshotOf(edition, idOf(principal)), symbol => placeOf(edition, symbol), tolerance ?? collationToleranceOf(principal));
138
140
  const collated = new Set(collations.map(({ symbol }) => symbol.id));
139
141
  return onVersion(versionId, (version, draft) => {
140
- handOverCarriers(view, draft, collations);
142
+ handOverCarriers(edition, draft, collations);
141
143
  dropInsertions(version, collated);
142
144
  });
143
145
  });
@@ -163,9 +165,9 @@ const readingOf = (symbol, carriers) => {
163
165
  * where the two versions do not disagree and there is nothing to take
164
166
  * apart.
165
167
  */
166
- const sharedWith = (view, symbol, copies) => {
168
+ const sharedWith = (edition, symbol, copies) => {
167
169
  const onNamedCopy = (carrier) => {
168
- const copy = view.copyOf(idOf(carrier));
170
+ const copy = copyOfFeature(edition, idOf(carrier));
169
171
  return copy !== undefined && copies.has(copy.id);
170
172
  };
171
173
  const mine = symbol.carriers.filter(onNamedCopy);
@@ -196,14 +198,14 @@ const sharedWith = (view, symbol, copies) => {
196
198
  * keeps its identifier and the edit that speaks for it. Named symbols
197
199
  * narrow the act to those; naming none separates the whole reading.
198
200
  */
199
- export const separateReadings = (given, versionId, copies, symbolIds) => reading(given, view => {
200
- const version = view.version(versionId);
201
+ export const separateReadings = (versionId, copies, symbolIds) => reading(edition => {
202
+ const version = versionIn(edition, versionId);
201
203
  if (!version)
202
204
  return noChange;
203
205
  const chosen = symbolIds && new Set(symbolIds);
204
- const shared = view.snapshot(versionId)
206
+ const shared = snapshotOf(edition, versionId)
205
207
  .filter(symbol => chosen === undefined || chosen.has(symbol.id))
206
- .flatMap(symbol => sharedWith(view, symbol, copies));
208
+ .flatMap(symbol => sharedWith(edition, symbol, copies));
207
209
  if (shared.length === 0)
208
210
  return noChange;
209
211
  const inserted = new Set(insertedBy(version).map(symbol => symbol.id));
@@ -218,7 +220,7 @@ export const separateReadings = (given, versionId, copies, symbolIds) => reading
218
220
  }));
219
221
  return onVersion(versionId, (version, draft) => {
220
222
  shared.forEach(({ symbol, theirs }) => {
221
- const path = view.getPath(symbol.id);
223
+ const path = pathIn(edition, symbol.id);
222
224
  const target = path && getAt(path, draft);
223
225
  if (target)
224
226
  target.carriers = theirs;
@@ -1,9 +1,8 @@
1
- import { EditionView } from "../view/EditionView.js";
2
1
  import { PlacementRelation } from "../model/Symbol.js";
3
2
  import { EditionOp } from "./draft.js";
4
3
  /** States how the follower is placed relative to the reference, in place of any earlier statement. */
5
- export declare const placeCommand: (view: EditionView, followerId: string, referenceId: string, relation: PlacementRelation) => EditionOp;
6
- export declare const unplaceCommand: (view: EditionView, followerId: string) => EditionOp;
4
+ export declare const placeCommand: (followerId: string, referenceId: string, relation: PlacementRelation) => EditionOp;
5
+ export declare const unplaceCommand: (followerId: string) => EditionOp;
7
6
  /** The pair is stated on `statingId` only, as the format asks. */
8
- export declare const pairCommands: (view: EditionView, statingId: string, partnerId: string) => EditionOp;
9
- export declare const unpairCommand: (view: EditionView, statingId: string) => EditionOp;
7
+ export declare const pairCommands: (statingId: string, partnerId: string) => EditionOp;
8
+ export declare const unpairCommand: (statingId: string) => EditionOp;
@@ -1,29 +1,29 @@
1
- import { getAt } from "../view/EditionView.js";
1
+ import { getAt, pathIn } from "../lookup/paths.js";
2
2
  import { isCommand, placementRelations } from "../model/Symbol.js";
3
3
  import { assignReference } from "../model/Assumption.js";
4
4
  import { reading } from "./draft.js";
5
5
  /**
6
- * Runs the change on the command the view locates by id, in whichever
7
- * version inserted it. A statement made there holds in every version
8
- * that carries the command.
6
+ * Runs the change on the command with the id, in whichever version
7
+ * inserted it. A statement made there holds in every version that
8
+ * carries the command.
9
9
  */
10
- const onCommand = (view, id, op) => reading(view, fresh => draft => {
11
- const path = fresh.getPath(id);
10
+ const onCommand = (id, op) => reading(edition => draft => {
11
+ const path = pathIn(edition, id);
12
12
  const symbol = path && getAt(path, draft);
13
13
  if (isCommand(symbol))
14
14
  op(symbol);
15
15
  });
16
16
  const clearPlacement = (command) => placementRelations.forEach(relation => { delete command[relation]; });
17
17
  /** States how the follower is placed relative to the reference, in place of any earlier statement. */
18
- export const placeCommand = (view, followerId, referenceId, relation) => onCommand(view, followerId, command => {
18
+ export const placeCommand = (followerId, referenceId, relation) => onCommand(followerId, command => {
19
19
  clearPlacement(command);
20
20
  command[relation] = assignReference(referenceId);
21
21
  });
22
- export const unplaceCommand = (view, followerId) => onCommand(view, followerId, clearPlacement);
22
+ export const unplaceCommand = (followerId) => onCommand(followerId, clearPlacement);
23
23
  /** The pair is stated on `statingId` only, as the format asks. */
24
- export const pairCommands = (view, statingId, partnerId) => onCommand(view, statingId, command => {
24
+ export const pairCommands = (statingId, partnerId) => onCommand(statingId, command => {
25
25
  command.pairedWith = assignReference(partnerId);
26
26
  });
27
- export const unpairCommand = (view, statingId) => onCommand(view, statingId, command => {
27
+ export const unpairCommand = (statingId) => onCommand(statingId, command => {
28
28
  delete command.pairedWith;
29
29
  });
@@ -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, RollCopy, ScaleReading, Shift } from "../model/RollCopy.js";
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
- * Shifts and then scales the copy's features into line with another
25
- * copy's, and puts the scale down to what the reading says: the paper,
26
- * or the speed the copy was cut for.
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 alignCopy: (copyId: string, shift: Shift, scale: number, reading?: ScaleReading) => EditionOp;
30
+ export declare const alignmentFor: (edition: Edition, copy: RollCopy, date?: Date) => Alignment | undefined;
29
31
  /**
30
- * Puts the copy's features back where they were measured. A paper
31
- * stretch read off the alignment goes with it; a speed stated stays,
32
- * being a fact about the copy.
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. The other condition a copy may be in, a paper stretch, is
64
- * read off an alignment and stated by `alignCopy`.
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
  /**