linked-rolls 0.43.0 → 0.45.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 (80) hide show
  1. package/README.md +94 -2
  2. package/lib/Agent.d.ts +1 -1
  3. package/lib/Assumption.d.ts +2 -2
  4. package/lib/Collation.d.ts +84 -7
  5. package/lib/Collation.js +63 -16
  6. package/lib/ConditionState.d.ts +1 -1
  7. package/lib/Edit.d.ts +3 -3
  8. package/lib/Edition.d.ts +14 -8
  9. package/lib/EditionView.d.ts +8 -8
  10. package/lib/EditionView.js +6 -6
  11. package/lib/Emulation.d.ts +4 -4
  12. package/lib/Emulation.js +3 -3
  13. package/lib/Feature.d.ts +5 -5
  14. package/lib/FeatureSource.d.ts +4 -4
  15. package/lib/ReproducingSystem.d.ts +4 -4
  16. package/lib/RollCopy.d.ts +10 -10
  17. package/lib/RollCopy.js +4 -4
  18. package/lib/Symbol.d.ts +2 -2
  19. package/lib/Symbol.js +1 -1
  20. package/lib/TrackCalibration.d.ts +1 -1
  21. package/lib/TrackCalibration.js +1 -1
  22. package/lib/TrackerBar.d.ts +3 -3
  23. package/lib/TrackerBar.js +1 -1
  24. package/lib/Version.d.ts +13 -15
  25. package/lib/Version.js +2 -2
  26. package/lib/alignment.d.ts +4 -4
  27. package/lib/alignment.js +3 -3
  28. package/lib/asJsonLd.d.ts +1 -1
  29. package/lib/asJsonLd.js +3 -3
  30. package/lib/constraints.d.ts +1 -1
  31. package/lib/constraints.js +5 -5
  32. package/lib/context.js +4 -4
  33. package/lib/editionOps.d.ts +42 -10
  34. package/lib/editionOps.js +132 -19
  35. package/lib/importJsonLd.d.ts +1 -1
  36. package/lib/importJsonLd.js +3 -3
  37. package/lib/index.d.ts +42 -40
  38. package/lib/index.js +42 -40
  39. package/lib/migrate.js +18 -7
  40. package/lib/procedures.d.ts +1 -1
  41. package/lib/readers/phillipsEroll.d.ts +19 -4
  42. package/lib/readers/phillipsEroll.js +21 -6
  43. package/lib/readers/spencerBar.d.ts +2 -2
  44. package/lib/readers/spencerBar.js +3 -3
  45. package/lib/readers/stanfordAton.d.ts +3 -3
  46. package/lib/readers/stanfordAton.js +4 -4
  47. package/lib/reservations.d.ts +3 -3
  48. package/lib/reservations.js +4 -4
  49. package/lib/scatter.d.ts +225 -0
  50. package/lib/scatter.js +231 -0
  51. package/lib/schema.json +60 -12
  52. package/lib/sigla.d.ts +1 -1
  53. package/lib/sigla.js +4 -4
  54. package/lib/statistics.d.ts +71 -0
  55. package/lib/statistics.js +121 -0
  56. package/lib/substitution.d.ts +5 -5
  57. package/lib/substitution.js +2 -2
  58. package/lib/systems/index.d.ts +2 -2
  59. package/lib/systems/index.js +4 -4
  60. package/lib/systems/welteLicensee/bar.d.ts +1 -1
  61. package/lib/systems/welteLicensee/bar.js +2 -2
  62. package/lib/systems/welteLicensee/system.d.ts +2 -2
  63. package/lib/systems/welteLicensee/system.js +3 -3
  64. package/lib/systems/welteT100/bar.d.ts +1 -1
  65. package/lib/systems/welteT100/bar.js +2 -2
  66. package/lib/systems/welteT100/system.d.ts +4 -4
  67. package/lib/systems/welteT100/system.js +4 -4
  68. package/lib/systems/welteT98/bar.d.ts +1 -1
  69. package/lib/systems/welteT98/bar.js +2 -2
  70. package/lib/systems/welteT98/system.d.ts +4 -4
  71. package/lib/systems/welteT98/system.js +4 -4
  72. package/lib/utils.d.ts +2 -0
  73. package/lib/utils.js +10 -0
  74. package/lib/validate.d.ts +1 -1
  75. package/lib/validate.js +1 -1
  76. package/lib/vocabulary.d.ts +1 -1
  77. package/lib/vocabulary.js +3 -3
  78. package/lib/witnesses.d.ts +2 -2
  79. package/lib/witnesses.js +2 -2
  80. package/package.json +1 -1
package/lib/Version.js CHANGED
@@ -1,5 +1,5 @@
1
- import { certainties, certaintyOf, idOf } from "./Assumption";
2
- import { defaultCollationTolerance } from "./Collation";
1
+ import { certainties, certaintyOf, idOf } from "./Assumption.js";
2
+ import { defaultCollationTolerance } from "./Collation.js";
3
3
  /** The tolerance the derivation was collated at, or the default where it states none. */
4
4
  export const collationToleranceOf = (derivation) => derivation.collationTolerance ?? defaultCollationTolerance;
5
5
  /** The edits the version states, none where it leaves its text unstated. */
@@ -1,7 +1,7 @@
1
- import { FeatureOrPatch } from "./Feature";
2
- import { RollCopy, Shift } from "./RollCopy";
3
- import { TrackerBar } from "./TrackerBar";
4
- import { Millimeters } from "./Quantity";
1
+ import { FeatureOrPatch } from "./Feature.js";
2
+ import { RollCopy, Shift } from "./RollCopy.js";
3
+ import { TrackerBar } from "./TrackerBar.js";
4
+ import { Millimeters } from "./Quantity.js";
5
5
  export declare const applyShift: (shift: Shift, copy: RollCopy) => void;
6
6
  /** Scales the copy's features away from the beginning of the roll, and records the factor. */
7
7
  export declare const applyScale: (factor: number, copy: RollCopy) => void;
package/lib/alignment.js CHANGED
@@ -1,6 +1,6 @@
1
- import { featuresOf } from "./RollCopy";
2
- import { welteT100 } from "./systems/welteT100/bar";
3
- import { add, mm, scale } from "./Quantity";
1
+ import { featuresOf } from "./RollCopy.js";
2
+ import { welteT100 } from "./systems/welteT100/bar.js";
3
+ import { add, mm, scale } from "./Quantity.js";
4
4
  /** Moves both ends of a span, the far end only where the span has one. */
5
5
  const move = (span, by) => {
6
6
  span.from = add(span.from, by);
package/lib/asJsonLd.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { Edition } from "./Edition";
1
+ import { Edition } from "./Edition.js";
2
2
  /**
3
3
  * The keys an export derives from the tree, which no node of the
4
4
  * edition states itself. An import reads them off again.
package/lib/asJsonLd.js CHANGED
@@ -1,6 +1,6 @@
1
- import { systemIdIn } from "./TrackerBar";
2
- import { certaintyOf, isAsserted } from "./Assumption";
3
- import context from "./spec/context.json";
1
+ import { systemIdIn } from "./TrackerBar.js";
2
+ import { certaintyOf, isAsserted } from "./Assumption.js";
3
+ import context from "./spec/context.json" with { type: 'json' };
4
4
  /**
5
5
  * The keys an export derives from the tree, which no node of the
6
6
  * edition states itself. An import reads them off again.
@@ -1,4 +1,4 @@
1
- import { EditionView } from "./EditionView";
1
+ import { EditionView } from "./EditionView.js";
2
2
  export type ConstraintProblem = {
3
3
  version: string;
4
4
  symbol: string;
@@ -1,8 +1,8 @@
1
- import { idOf } from "./Assumption";
2
- import { isCommand, pairsAmong, placementsOf } from "./Symbol";
3
- import { keyOf } from "./TrackerBar";
4
- import { trackerBarOf } from "./systems";
5
- import { barOf } from "./RollCopy";
1
+ import { idOf } from "./Assumption.js";
2
+ import { isCommand, pairsAmong, placementsOf } from "./Symbol.js";
3
+ import { keyOf } from "./TrackerBar.js";
4
+ import { trackerBarOf } from "./systems/index.js";
5
+ import { barOf } from "./RollCopy.js";
6
6
  const missingReference = {
7
7
  alignedWith: 'alignment-reference-missing',
8
8
  before: 'before-reference-missing',
package/lib/context.js CHANGED
@@ -1,12 +1,12 @@
1
- export { default as jsonLdContext } from './spec/context.json';
1
+ export { default as jsonLdContext } from './spec/context.json' with { type: 'json' };
2
2
  /** The context of the Welte-Mignon T-100, added to a version coded for it. */
3
- export { default as welteT100JsonLdContext } from './spec/welte-t100.context.json';
3
+ export { default as welteT100JsonLdContext } from './spec/welte-t100.context.json' with { type: 'json' };
4
4
  /**
5
5
  * The context of the Welte-Mignon Licensee. Its expression terms are
6
6
  * the T-100's, the two systems differing in the tracker scale rather
7
7
  * than in the coding, so it reads them out of the T-100's vocabulary
8
8
  * rather than minting a second set of IRIs for the same commands.
9
9
  */
10
- export { default as welteLicenseeJsonLdContext } from './spec/welte-licensee.context.json';
10
+ export { default as welteLicenseeJsonLdContext } from './spec/welte-licensee.context.json' with { type: 'json' };
11
11
  /** The context of the Welte-Mignon T-98, added to an edition of a green roll. */
12
- export { default as welteT98JsonLdContext } from './spec/welte-t98.context.json';
12
+ export { default as welteT98JsonLdContext } from './spec/welte-t98.context.json' with { type: 'json' };
@@ -1,13 +1,13 @@
1
1
  import { Draft } from "immer";
2
- import { EditionView, Path } from "./EditionView";
3
- import { Edition } from "./Edition";
4
- import { AnySymbol, PlacementRelation } from "./Symbol";
5
- import { CollationTolerance } from "./Collation";
6
- import { Edit } from "./Edit";
7
- import { GeneralRollCondition, ModificationPurpose, RollCopy, ScaleReading, Shift } from "./RollCopy";
8
- import { FeatureSource } from "./FeatureSource";
9
- import { AnyArgumentation, Belief, Certainty, ObjectAssumption } from "./Assumption";
10
- import { FeatureConditionAssignment, FeatureOrPatch, NestedFeature } from "./Feature";
2
+ import { EditionView, Path } from "./EditionView.js";
3
+ import { Edition } from "./Edition.js";
4
+ import { AnySymbol, PlacementRelation } from "./Symbol.js";
5
+ import { CollationTolerance } from "./Collation.js";
6
+ import { Edit } from "./Edit.js";
7
+ import { GeneralRollCondition, ModificationPurpose, RollCopy, ScaleReading, Shift } from "./RollCopy.js";
8
+ import { FeatureSource } from "./FeatureSource.js";
9
+ import { AnyArgumentation, Belief, Certainty, ObjectAssumption } from "./Assumption.js";
10
+ import { FeatureConditionAssignment, FeatureOrPatch, NestedFeature } from "./Feature.js";
11
11
  /**
12
12
  * A change to an edition, written onto an immer draft of it. One
13
13
  * operation is one undo step, so an operation that has to read the
@@ -157,14 +157,46 @@ export declare const mergeFeatures: (copyId: string, featureIds: readonly string
157
157
  * and the child lacks becomes its deletions. The derivation states the
158
158
  * tolerance it was collated at and becomes the principal one; the
159
159
  * hypotheses the child stated beside its former one stay.
160
+ *
161
+ * The edits the child already stated are rewritten only as far as a
162
+ * collation wrote them (`isCollationsOwn`). An editor's reading of the
163
+ * difference between the two texts stays, and the symbols it speaks for
164
+ * are left out of the collation, so that connecting the two again
165
+ * neither doubles them nor silently drops what somebody established by
166
+ * hand. An equivalence is the collation's own, since it is drawn from
167
+ * the two systems' vocabularies rather than read off the paper, but one
168
+ * drawn again over the very same symbols is kept as it stands, with its
169
+ * identifier and whatever was written on it.
170
+ *
171
+ * The child's own text is what it shows less what the parent hands
172
+ * down, so that connecting two versions already connected collates the
173
+ * child's symbols and not the parent's with themselves.
160
174
  */
161
- export declare const connectVersions: (view: EditionView, childId: string, parentId: string, tolerance?: CollationTolerance) => EditionOp;
175
+ export declare const connectVersions: (view: EditionView, childId: string, parentId: string, tolerance?: ObjectAssumption<CollationTolerance>) => EditionOp;
162
176
  /**
163
177
  * Folds the version's own symbols into those it inherits and collates
164
178
  * with: the carriers pass over, and the insertions go. Collates at the
165
179
  * tolerance of the derivation, where the caller names none.
166
180
  */
167
181
  export declare const collateSymbols: (view: EditionView, versionId: string, symbolIds: readonly string[], tolerance?: CollationTolerance) => EditionOp;
182
+ /**
183
+ * Takes the copy's reading of a symbol back out of the symbol it was
184
+ * collated into: the copy's carriers pass to a new symbol of the
185
+ * version's own, the other copies keep the symbol they had, and the
186
+ * version states the exchange.
187
+ *
188
+ * This is the inverse of the hand-over a collation makes, and it is
189
+ * what lets a derivation be collated a second time. A collated symbol
190
+ * is one symbol carrying every copy that reads it, so nothing else
191
+ * takes the two readings apart again, and without that a tolerance
192
+ * arrived at after the fact could never be applied.
193
+ *
194
+ * Symbols the copy alone carries are already the version's own and are
195
+ * passed over, so a reading somebody has separated by hand keeps its
196
+ * identifier and the edit that speaks for it. Named symbols narrow the
197
+ * act to those; naming none separates the copy's whole reading.
198
+ */
199
+ export declare const separateReadings: (view: EditionView, versionId: string, copyId: string, symbolIds?: readonly string[]) => EditionOp;
168
200
  /**
169
201
  * Makes the version stand on its own: what it inherited becomes its
170
202
  * own insertions, and its derivations go, the hypotheses among them,
package/lib/editionOps.js CHANGED
@@ -1,17 +1,17 @@
1
1
  import { current, isDraft } from "immer";
2
2
  import { v4 } from "uuid";
3
- import { getAt } from "./EditionView";
4
- import { isCommand, placementRelations } from "./Symbol";
5
- import { collationsOf, defaultCollationTolerance } from "./Collation";
6
- import { collationToleranceOf, editsOf, insertedBy, principalDerivationOf } from "./Version";
7
- import { asSymbols, barOf, featuresByAct, featuresOf, isPaperStretch, statesNothing } from "./RollCopy";
8
- import { systemOf } from "./TrackerBar";
9
- import { substitutionsBetween } from "./substitution";
10
- import { trackerBarOf } from "./systems";
11
- import { applyShift, applyScale, revertShift, revertScale } from "./alignment";
12
- import { assignReference, idOf } from "./Assumption";
13
- import { conditions as conditionsAllowed, featuresBorneBy, isGluedOn, withBorneFeatures } from "./Feature";
14
- import { distance, mm, subtract } from "./Quantity";
3
+ import { getAt } from "./EditionView.js";
4
+ import { isCommand, placementRelations } from "./Symbol.js";
5
+ import { collationsOf, defaultCollationTolerance, isCollationsOwn } from "./Collation.js";
6
+ import { collationToleranceOf, editsOf, insertedBy, principalDerivationOf } from "./Version.js";
7
+ import { asSymbols, barOf, featuresByAct, featuresOf, isPaperStretch, statesNothing } from "./RollCopy.js";
8
+ import { systemOf } from "./TrackerBar.js";
9
+ import { substitutionsBetween } from "./substitution.js";
10
+ import { trackerBarOf } from "./systems/index.js";
11
+ import { applyShift, applyScale, revertShift, revertScale } from "./alignment.js";
12
+ import { assignReference, idOf } from "./Assumption.js";
13
+ import { conditions as conditionsAllowed, featuresBorneBy, isGluedOn, withBorneFeatures } from "./Feature.js";
14
+ import { distance, mm, subtract } from "./Quantity.js";
15
15
  const noChange = () => undefined;
16
16
  const onCopy = (copyId, op) => draft => {
17
17
  const copy = draft.copies.find(c => c.id === copyId);
@@ -651,6 +651,20 @@ const dropDerivations = (version, matches) => {
651
651
  else
652
652
  delete version.basedOn;
653
653
  };
654
+ /** The symbols a set of edits speaks for, whether by inserting or by deleting them. */
655
+ const spokenForBy = (edits) => new Set(edits.flatMap(edit => [
656
+ ...(edit.insert ?? []).map(symbol => symbol.id),
657
+ ...(edit.delete ?? [])
658
+ ]));
659
+ /** An exchange of symbols, as a key: what it puts in against what it takes out. */
660
+ const exchangeKey = (inserted, deleted) => `${[...inserted].sort().join(',')}/${[...deleted].sort().join(',')}`;
661
+ /**
662
+ * The edits already stated, by the exchange each of them makes. An
663
+ * equivalence the collation draws a second time is the one already
664
+ * stated, and drawing it again is no reason to mint a new identifier or
665
+ * to drop the motivation somebody wrote on it.
666
+ */
667
+ const byExchange = (edits) => new Map(edits.map(edit => [exchangeKey((edit.insert ?? []).map(symbol => symbol.id), edit.delete ?? []), edit]));
654
668
  /**
655
669
  * Bases the child on the parent. A symbol of the child that collates
656
670
  * with one the parent hands down adds its carriers to that symbol; the
@@ -658,10 +672,36 @@ const dropDerivations = (version, matches) => {
658
672
  * and the child lacks becomes its deletions. The derivation states the
659
673
  * tolerance it was collated at and becomes the principal one; the
660
674
  * hypotheses the child stated beside its former one stay.
675
+ *
676
+ * The edits the child already stated are rewritten only as far as a
677
+ * collation wrote them (`isCollationsOwn`). An editor's reading of the
678
+ * difference between the two texts stays, and the symbols it speaks for
679
+ * are left out of the collation, so that connecting the two again
680
+ * neither doubles them nor silently drops what somebody established by
681
+ * hand. An equivalence is the collation's own, since it is drawn from
682
+ * the two systems' vocabularies rather than read off the paper, but one
683
+ * drawn again over the very same symbols is kept as it stands, with its
684
+ * identifier and whatever was written on it.
685
+ *
686
+ * The child's own text is what it shows less what the parent hands
687
+ * down, so that connecting two versions already connected collates the
688
+ * child's symbols and not the parent's with themselves.
661
689
  */
662
690
  export const connectVersions = (view, childId, parentId, tolerance = defaultCollationTolerance) => {
663
- const inherited = view.snapshot(parentId);
664
- const own = view.snapshot(childId);
691
+ const child = view.get(childId);
692
+ const stated = child ? editsOf(child) : [];
693
+ const established = stated.filter(edit => !isCollationsOwn(edit));
694
+ const spokenFor = spokenForBy(established);
695
+ const unspoken = (symbol) => !spokenFor.has(symbol.id);
696
+ // What the parent hands down and the child still shows passes
697
+ // through: it is neither the child's own symbol nor one it lacks.
698
+ // Without that, connecting a pair already connected would collate
699
+ // the inherited symbols with themselves and double their carriers.
700
+ const handedDown = view.snapshot(parentId).filter(unspoken);
701
+ const shown = new Set(view.snapshot(childId).map(symbol => symbol.id));
702
+ const inheritedIds = new Set(handedDown.map(symbol => symbol.id));
703
+ const inherited = handedDown.filter(symbol => !shown.has(symbol.id));
704
+ const own = view.snapshot(childId).filter(symbol => unspoken(symbol) && !inheritedIds.has(symbol.id));
665
705
  const locate = (symbol) => view.placeOf(symbol);
666
706
  const collations = collationsOf(own, inherited, locate, tolerance);
667
707
  const collated = new Set(collations.map(({ symbol }) => symbol.id));
@@ -673,18 +713,25 @@ export const connectVersions = (view, childId, parentId, tolerance = defaultColl
673
713
  * apart would make the apparatus a list of unexplained losses beside
674
714
  * a list of unexplained gains.
675
715
  */
676
- const substituted = differ(view.get(childId), view.get(parentId))
716
+ const substituted = differ(child, view.get(parentId))
677
717
  ? substitutionsBetween(own.filter(symbol => !collated.has(symbol.id)), inherited.filter(symbol => !matched.has(symbol.id)), locate, tolerance)
678
718
  : [];
679
719
  const paired = new Set(substituted.flatMap(({ replaced, by }) => [...by, ...replaced].map(symbol => symbol.id)));
680
- const edits = [
681
- ...substituted.map(({ replaced, by }) => ({
720
+ const alreadyStated = byExchange(stated);
721
+ const equivalence = ({ replaced, by }) => {
722
+ const inserted = by.map(symbol => symbol.id);
723
+ const deleted = replaced.map(symbol => symbol.id);
724
+ return alreadyStated.get(exchangeKey(inserted, deleted)) ?? {
682
725
  type: 'edit',
683
726
  id: v4(),
684
727
  editType: 'replace-with-equivalent',
685
728
  insert: [...by],
686
- delete: replaced.map(symbol => symbol.id)
687
- })),
729
+ delete: deleted
730
+ };
731
+ };
732
+ const edits = [
733
+ ...established,
734
+ ...substituted.map(equivalence),
688
735
  ...own.filter(symbol => !collated.has(symbol.id) && !paired.has(symbol.id)).map(insertion),
689
736
  ...inherited
690
737
  .filter(symbol => !matched.has(symbol.id) && !paired.has(symbol.id))
@@ -718,6 +765,72 @@ export const collateSymbols = (view, versionId, symbolIds, tolerance) => {
718
765
  dropInsertions(version, collated);
719
766
  });
720
767
  };
768
+ /** The symbol as one copy reads it: what it says, on the given carriers, standing in no relation of its own. */
769
+ const readingOf = (symbol, carriers) => {
770
+ const identity = { id: v4(), carriers };
771
+ switch (symbol.type) {
772
+ case 'note':
773
+ return { type: 'note', pitch: symbol.pitch, ...identity };
774
+ case 'expression':
775
+ return { type: 'expression', expressionType: symbol.expressionType, scope: symbol.scope, ...identity };
776
+ case 'text':
777
+ return { type: 'text', text: symbol.text, ...identity };
778
+ }
779
+ };
780
+ /** The symbol where the copy and at least one other carry it, with the carriers of each side. */
781
+ const sharedWith = (view, symbol, copyId) => {
782
+ const onCopy = (carrier) => view.copyOf(idOf(carrier))?.id === copyId;
783
+ const mine = symbol.carriers.filter(onCopy);
784
+ const theirs = symbol.carriers.filter(carrier => !onCopy(carrier));
785
+ return mine.length > 0 && theirs.length > 0 ? [{ symbol, mine, theirs }] : [];
786
+ };
787
+ /**
788
+ * Takes the copy's reading of a symbol back out of the symbol it was
789
+ * collated into: the copy's carriers pass to a new symbol of the
790
+ * version's own, the other copies keep the symbol they had, and the
791
+ * version states the exchange.
792
+ *
793
+ * This is the inverse of the hand-over a collation makes, and it is
794
+ * what lets a derivation be collated a second time. A collated symbol
795
+ * is one symbol carrying every copy that reads it, so nothing else
796
+ * takes the two readings apart again, and without that a tolerance
797
+ * arrived at after the fact could never be applied.
798
+ *
799
+ * Symbols the copy alone carries are already the version's own and are
800
+ * passed over, so a reading somebody has separated by hand keeps its
801
+ * identifier and the edit that speaks for it. Named symbols narrow the
802
+ * act to those; naming none separates the copy's whole reading.
803
+ */
804
+ export const separateReadings = (view, versionId, copyId, symbolIds) => {
805
+ const version = view.get(versionId);
806
+ if (!version)
807
+ return noChange;
808
+ const chosen = symbolIds && new Set(symbolIds);
809
+ const shared = view.snapshot(versionId)
810
+ .filter(symbol => chosen === undefined || chosen.has(symbol.id))
811
+ .flatMap(symbol => sharedWith(view, symbol, copyId));
812
+ if (shared.length === 0)
813
+ return noChange;
814
+ const inserted = new Set(insertedBy(version).map(symbol => symbol.id));
815
+ const stated = editsOf(version);
816
+ const separations = shared.map(({ symbol, mine }) => ({
817
+ type: 'edit',
818
+ id: v4(),
819
+ insert: [readingOf(symbol, [...mine])],
820
+ // A symbol the version inserts itself stays where it is, minus
821
+ // the carriers that leave it. Only one it inherits is exchanged.
822
+ ...(inserted.has(symbol.id) ? {} : { delete: [symbol.id] })
823
+ }));
824
+ return onVersion(versionId, (version, draft) => {
825
+ shared.forEach(({ symbol, theirs }) => {
826
+ const path = view.getPath(symbol.id);
827
+ const target = path && getAt(path, draft);
828
+ if (target)
829
+ target.carriers = theirs;
830
+ });
831
+ version.edits = [...stated, ...separations];
832
+ });
833
+ };
721
834
  /**
722
835
  * Makes the version stand on its own: what it inherited becomes its
723
836
  * own insertions, and its derivations go, the hypotheses among them,
@@ -1,4 +1,4 @@
1
- import { Edition } from "./Edition";
1
+ import { Edition } from "./Edition.js";
2
2
  export declare const importDate: (str: string) => Date;
3
3
  type Json = any;
4
4
  export declare const importJsonLd: (json: Json) => Edition;
@@ -1,6 +1,6 @@
1
- import { derivedKeys } from "./asJsonLd";
2
- import { migrate } from "./migrate";
3
- import { isDateString } from "./utils";
1
+ import { derivedKeys } from "./asJsonLd.js";
2
+ import { migrate } from "./migrate.js";
3
+ import { isDateString } from "./utils.js";
4
4
  export const importDate = (str) => {
5
5
  const [y, m, d] = str.split('-').map(s => parseInt(s, 10));
6
6
  if ([y, m, d].some(n => isNaN(n))) {
package/lib/index.d.ts CHANGED
@@ -1,40 +1,42 @@
1
- export * from './utils';
2
- export * from './Quantity';
3
- export * from './Agent';
4
- export * from './Assumption';
5
- export * from './ConditionState';
6
- export * from './Symbol';
7
- export * from './Feature';
8
- export * from './Edit';
9
- export * from './Version';
10
- export * from './Collation';
11
- export * from './TrackCalibration';
12
- export * from './TrackerBar';
13
- export * from './systems/welteT100/bar';
14
- export * from './systems/welteLicensee/bar';
15
- export * from './systems/welteT98/bar';
16
- export * from './systems';
17
- export * from './ReproducingSystem';
18
- export * from './FeatureSource';
19
- export * from './RollCopy';
20
- export * from './procedures';
21
- export * from './vocabulary';
22
- export * from './reservations';
23
- export * from './witnesses';
24
- export * from './alignment';
25
- export * from './Edition';
26
- export * from './EditionView';
27
- export * from './editionOps';
28
- export * from './Emulation';
29
- export * from './validate';
30
- export * from './constraints';
31
- export * from './substitution';
32
- export * from './context';
33
- export * from './sigla';
34
- export * from './notes';
35
- export * from './asJsonLd';
36
- export * from './importJsonLd';
37
- export * from './migrate';
38
- export { readFromStanfordAton, type StanfordAtonOptions } from './readers/stanfordAton';
39
- export { readFromPhillipsEroll, CONTROL_OFFSET, phillipsSystems, type PhillipsErollOptions } from './readers/phillipsEroll';
40
- export { readFromSpencerBar, readSpencerAnn, paperSpeedOfSpencerAnn, SPENCER_ROWS_PER_INCH, type SpencerBarOptions } from './readers/spencerBar';
1
+ export * from './utils.js';
2
+ export * from './Quantity.js';
3
+ export * from './Agent.js';
4
+ export * from './Assumption.js';
5
+ export * from './ConditionState.js';
6
+ export * from './Symbol.js';
7
+ export * from './Feature.js';
8
+ export * from './Edit.js';
9
+ export * from './Version.js';
10
+ export * from './Collation.js';
11
+ export * from './TrackCalibration.js';
12
+ export * from './TrackerBar.js';
13
+ export * from './systems/welteT100/bar.js';
14
+ export * from './systems/welteLicensee/bar.js';
15
+ export * from './systems/welteT98/bar.js';
16
+ export * from './systems/index.js';
17
+ export * from './ReproducingSystem.js';
18
+ export * from './FeatureSource.js';
19
+ export * from './RollCopy.js';
20
+ export * from './procedures.js';
21
+ export * from './vocabulary.js';
22
+ export * from './reservations.js';
23
+ export * from './witnesses.js';
24
+ export * from './alignment.js';
25
+ export * from './statistics.js';
26
+ export * from './Edition.js';
27
+ export * from './EditionView.js';
28
+ export * from './scatter.js';
29
+ export * from './editionOps.js';
30
+ export * from './Emulation.js';
31
+ export * from './validate.js';
32
+ export * from './constraints.js';
33
+ export * from './substitution.js';
34
+ export * from './context.js';
35
+ export * from './sigla.js';
36
+ export * from './notes.js';
37
+ export * from './asJsonLd.js';
38
+ export * from './importJsonLd.js';
39
+ export * from './migrate.js';
40
+ export { readFromStanfordAton, type StanfordAtonOptions } from './readers/stanfordAton.js';
41
+ export { readFromPhillipsEroll, CONTROL_OFFSET, phillipsSystems, type PhillipsErollOptions } from './readers/phillipsEroll.js';
42
+ export { readFromSpencerBar, readSpencerAnn, paperSpeedOfSpencerAnn, SPENCER_ROWS_PER_INCH, type SpencerBarOptions } from './readers/spencerBar.js';
package/lib/index.js CHANGED
@@ -1,40 +1,42 @@
1
- export * from './utils';
2
- export * from './Quantity';
3
- export * from './Agent';
4
- export * from './Assumption';
5
- export * from './ConditionState';
6
- export * from './Symbol';
7
- export * from './Feature';
8
- export * from './Edit';
9
- export * from './Version';
10
- export * from './Collation';
11
- export * from './TrackCalibration';
12
- export * from './TrackerBar';
13
- export * from './systems/welteT100/bar';
14
- export * from './systems/welteLicensee/bar';
15
- export * from './systems/welteT98/bar';
16
- export * from './systems';
17
- export * from './ReproducingSystem';
18
- export * from './FeatureSource';
19
- export * from './RollCopy';
20
- export * from './procedures';
21
- export * from './vocabulary';
22
- export * from './reservations';
23
- export * from './witnesses';
24
- export * from './alignment';
25
- export * from './Edition';
26
- export * from './EditionView';
27
- export * from './editionOps';
28
- export * from './Emulation';
29
- export * from './validate';
30
- export * from './constraints';
31
- export * from './substitution';
32
- export * from './context';
33
- export * from './sigla';
34
- export * from './notes';
35
- export * from './asJsonLd';
36
- export * from './importJsonLd';
37
- export * from './migrate';
38
- export { readFromStanfordAton } from './readers/stanfordAton';
39
- export { readFromPhillipsEroll, CONTROL_OFFSET, phillipsSystems } from './readers/phillipsEroll';
40
- export { readFromSpencerBar, readSpencerAnn, paperSpeedOfSpencerAnn, SPENCER_ROWS_PER_INCH } from './readers/spencerBar';
1
+ export * from './utils.js';
2
+ export * from './Quantity.js';
3
+ export * from './Agent.js';
4
+ export * from './Assumption.js';
5
+ export * from './ConditionState.js';
6
+ export * from './Symbol.js';
7
+ export * from './Feature.js';
8
+ export * from './Edit.js';
9
+ export * from './Version.js';
10
+ export * from './Collation.js';
11
+ export * from './TrackCalibration.js';
12
+ export * from './TrackerBar.js';
13
+ export * from './systems/welteT100/bar.js';
14
+ export * from './systems/welteLicensee/bar.js';
15
+ export * from './systems/welteT98/bar.js';
16
+ export * from './systems/index.js';
17
+ export * from './ReproducingSystem.js';
18
+ export * from './FeatureSource.js';
19
+ export * from './RollCopy.js';
20
+ export * from './procedures.js';
21
+ export * from './vocabulary.js';
22
+ export * from './reservations.js';
23
+ export * from './witnesses.js';
24
+ export * from './alignment.js';
25
+ export * from './statistics.js';
26
+ export * from './Edition.js';
27
+ export * from './EditionView.js';
28
+ export * from './scatter.js';
29
+ export * from './editionOps.js';
30
+ export * from './Emulation.js';
31
+ export * from './validate.js';
32
+ export * from './constraints.js';
33
+ export * from './substitution.js';
34
+ export * from './context.js';
35
+ export * from './sigla.js';
36
+ export * from './notes.js';
37
+ export * from './asJsonLd.js';
38
+ export * from './importJsonLd.js';
39
+ export * from './migrate.js';
40
+ export { readFromStanfordAton } from './readers/stanfordAton.js';
41
+ export { readFromPhillipsEroll, CONTROL_OFFSET, phillipsSystems } from './readers/phillipsEroll.js';
42
+ export { readFromSpencerBar, readSpencerAnn, paperSpeedOfSpencerAnn, SPENCER_ROWS_PER_INCH } from './readers/spencerBar.js';
package/lib/migrate.js CHANGED
@@ -1,9 +1,9 @@
1
- import { conditions, isFeatureType, media, techniques } from "./Feature";
2
- import { rollConditions } from "./RollCopy";
3
- import { systemIdIn, systemOf, translationBetween } from "./TrackerBar";
4
- import { trackerBars } from "./systems";
5
- import { welteT100 } from "./systems/welteT100/bar";
6
- import { isDateString } from "./utils";
1
+ import { conditions, isFeatureType, media, techniques } from "./Feature.js";
2
+ import { rollConditions } from "./RollCopy.js";
3
+ import { systemIdIn, systemOf, translationBetween } from "./TrackerBar.js";
4
+ import { trackerBars } from "./systems/index.js";
5
+ import { welteT100 } from "./systems/welteT100/bar.js";
6
+ import { isDateString } from "./utils.js";
7
7
  const retiredVersionTypes = new Set(['edition', 'unicum']);
8
8
  const conditionTypeValues = new Set([...rollConditions, ...Object.values(conditions).flat()]);
9
9
  const renamedKeys = {
@@ -40,6 +40,17 @@ const withoutVersionType = (node) => {
40
40
  const { versionType: _retired, ...rest } = node;
41
41
  return rest;
42
42
  };
43
+ /**
44
+ * A version carried the label it was cited under, from before the sigla
45
+ * were read off the stemma. A copy keeps its siglum, which is given by
46
+ * hand and derives from nothing.
47
+ */
48
+ const withoutVersionSiglum = (node) => {
49
+ if (node['@type'] !== 'Version' || !Object.hasOwn(node, 'siglum'))
50
+ return node;
51
+ const { siglum: _labelled, ...rest } = node;
52
+ return rest;
53
+ };
43
54
  const withLowerCaseTerms = (node) => Object.entries(lowerCasedTerms).reduce((result, [key, terms]) => {
44
55
  const lowered = terms[result[key]];
45
56
  return lowered ? { ...result, [key]: lowered } : result;
@@ -221,7 +232,7 @@ const withTimeSpanDates = (node) => {
221
232
  const { '@value': within, '@type': _typed, ...rest } = node;
222
233
  return { ...rest, within };
223
234
  };
224
- const migrateNode = (node) => [withRenamedKeys, withTypology, withoutVersionType, withLowerCaseTerms, withSplitMethod, withReferences, withKeeper, withoutEmptyKeeper,
235
+ const migrateNode = (node) => [withRenamedKeys, withTypology, withoutVersionType, withoutVersionSiglum, withLowerCaseTerms, withSplitMethod, withReferences, withKeeper, withoutEmptyKeeper,
225
236
  withProductionNodes, withScale, withDerivationList, withReadingKind, withTimeSpanDates, withoutFeatureKind,
226
237
  withBorneFeaturesNamed, withFeaturesInActs]
227
238
  .reduce((result, step) => step(result), node);
@@ -1,4 +1,4 @@
1
- import { Concept } from "./Agent";
1
+ import { Concept } from "./Agent.js";
2
2
  /**
3
3
  * The procedures the type vocabulary declares, for a consumer that has
4
4
  * to offer them. The names are the German labels of the concepts, which
@@ -1,6 +1,6 @@
1
- import { RollCopy } from "../RollCopy";
2
- import { TrackerBar } from "../TrackerBar";
3
- import { Millimeters, Seconds } from "../Quantity";
1
+ import { RollCopy } from "../RollCopy.js";
2
+ import { TrackerBar } from "../TrackerBar.js";
3
+ import { Millimeters, Seconds } from "../Quantity.js";
4
4
  /**
5
5
  * Peter Phillips's "e-roll" file, the unprocessed output of his
6
6
  * pneumatic roll reader (thesis pp. 182–196): the roll runs over a
@@ -14,7 +14,22 @@ import { Millimeters, Seconds } from "../Quantity";
14
14
  * elapsed time, not paper, and the take-up spool accelerates the paper
15
15
  * as it fills, so `placeAt` has to put the time back onto the paper.
16
16
  * And a switch stays open longer than its perforation is long, so a
17
- * hole read here runs past the punched one.
17
+ * hole read here runs past the punched one: Phillips measures the
18
+ * pneumatic on-time as exceeding the apparent length of a perforation
19
+ * (p. 178), and names what it depends on as the length of the
20
+ * perforation, the height of the tracker bar hole and the paper speed
21
+ * (p. 180).
22
+ *
23
+ * That extension is not subtracted. Doing so would need the absolute
24
+ * hole height of the Welte bar, where he gives only the 0.5 mm by which
25
+ * it exceeds the Licensee's. So the end of a hole on this copy is a
26
+ * pneumatic on-time where the end of a scanned copy's hole is a punched
27
+ * slot, and the two are not the same quantity. It shows in a collation:
28
+ * across welte225.org his notes run about 1.8 mm longer than the other
29
+ * copies read them, while the onsets agree. Until it is corrected, a
30
+ * comparison of hole ends against this copy measures the reader as much
31
+ * as the roll, and `offsetEnd` on the derivation absorbs the systematic
32
+ * part of it.
18
33
  */
19
34
  /**
20
35
  * He numbers his files by two rules at once, which his free samples