linked-rolls 0.57.0 → 0.59.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 (130) hide show
  1. package/README.md +54 -367
  2. package/lib/{constraints.d.ts → analysis/constraints.d.ts} +1 -1
  3. package/lib/{constraints.js → analysis/constraints.js} +8 -7
  4. package/lib/analysis/ownPaper.d.ts +26 -0
  5. package/lib/analysis/ownPaper.js +41 -0
  6. package/lib/{reservations.d.ts → analysis/reservations.d.ts} +3 -3
  7. package/lib/{reservations.js → analysis/reservations.js} +3 -3
  8. package/lib/{sigla.d.ts → analysis/sigla.d.ts} +2 -2
  9. package/lib/{sigla.js → analysis/sigla.js} +4 -4
  10. package/lib/{witnesses.d.ts → analysis/witnesses.d.ts} +2 -2
  11. package/lib/{witnesses.js → analysis/witnesses.js} +2 -2
  12. package/lib/{Collation.d.ts → collation/Collation.d.ts} +4 -4
  13. package/lib/{Collation.js → collation/Collation.js} +4 -4
  14. package/lib/{alignment.d.ts → collation/alignment.d.ts} +4 -4
  15. package/lib/{alignment.js → collation/alignment.js} +10 -16
  16. package/lib/{scatter.d.ts → collation/scatter.d.ts} +4 -4
  17. package/lib/{scatter.js → collation/scatter.js} +3 -3
  18. package/lib/{statistics.d.ts → collation/statistics.d.ts} +1 -1
  19. package/lib/{statistics.js → collation/statistics.js} +2 -2
  20. package/lib/{substitution.d.ts → collation/substitution.d.ts} +9 -24
  21. package/lib/{substitution.js → collation/substitution.js} +13 -37
  22. package/lib/emulation/Emulation.d.ts +64 -0
  23. package/lib/emulation/Emulation.js +282 -0
  24. package/lib/emulation/negotiation.d.ts +14 -0
  25. package/lib/emulation/negotiation.js +20 -0
  26. package/lib/index.d.ts +43 -35
  27. package/lib/index.js +36 -35
  28. package/lib/{asJsonLd.d.ts → io/asJsonLd.d.ts} +1 -1
  29. package/lib/{asJsonLd.js → io/asJsonLd.js} +3 -3
  30. package/lib/{context.d.ts → io/context.d.ts} +4 -4
  31. package/lib/{context.js → io/context.js} +4 -4
  32. package/lib/{importJsonLd.d.ts → io/importJsonLd.d.ts} +1 -1
  33. package/lib/io/importJsonLd.js +128 -0
  34. package/lib/{migrate.js → io/migrate.js} +59 -55
  35. package/lib/{Agent.d.ts → model/Agent.d.ts} +1 -1
  36. package/lib/{Assumption.d.ts → model/Assumption.d.ts} +1 -1
  37. package/lib/{Edit.d.ts → model/Edit.d.ts} +1 -1
  38. package/lib/{Edition.d.ts → model/Edition.d.ts} +2 -2
  39. package/lib/{Feature.d.ts → model/Feature.d.ts} +1 -1
  40. package/lib/{FeatureSource.d.ts → model/FeatureSource.d.ts} +1 -1
  41. package/lib/{Perforator.d.ts → model/Perforator.d.ts} +1 -1
  42. package/lib/{RollCopy.d.ts → model/RollCopy.d.ts} +3 -10
  43. package/lib/{RollCopy.js → model/RollCopy.js} +3 -5
  44. package/lib/{Symbol.d.ts → model/Symbol.d.ts} +1 -1
  45. package/lib/{Version.d.ts → model/Version.d.ts} +10 -2
  46. package/lib/{Version.js → model/Version.js} +24 -1
  47. package/lib/{vocabulary.js → model/vocabulary.js} +2 -2
  48. package/lib/ops/beliefs.d.ts +9 -0
  49. package/lib/ops/beliefs.js +31 -0
  50. package/lib/ops/collation.d.ts +62 -0
  51. package/lib/ops/collation.js +228 -0
  52. package/lib/ops/commands.d.ts +9 -0
  53. package/lib/ops/commands.js +29 -0
  54. package/lib/ops/copies.d.ts +74 -0
  55. package/lib/ops/copies.js +135 -0
  56. package/lib/ops/draft.d.ts +59 -0
  57. package/lib/ops/draft.js +81 -0
  58. package/lib/ops/edits.d.ts +10 -0
  59. package/lib/ops/edits.js +82 -0
  60. package/lib/ops/features.d.ts +84 -0
  61. package/lib/ops/features.js +296 -0
  62. package/lib/ops/forget.d.ts +31 -0
  63. package/lib/ops/forget.js +110 -0
  64. package/lib/ops/immutable.d.ts +16 -0
  65. package/lib/ops/immutable.js +46 -0
  66. package/lib/ops/index.d.ts +13 -0
  67. package/lib/ops/index.js +7 -0
  68. package/lib/ops/versions.d.ts +33 -0
  69. package/lib/ops/versions.js +95 -0
  70. package/lib/readers/AtonParser.js +5 -7
  71. package/lib/readers/phillipsEroll.d.ts +3 -3
  72. package/lib/readers/phillipsEroll.js +4 -5
  73. package/lib/readers/spencerBar.d.ts +2 -2
  74. package/lib/readers/spencerBar.js +2 -3
  75. package/lib/readers/stanfordAton.d.ts +3 -3
  76. package/lib/readers/stanfordAton.js +2 -3
  77. package/lib/schema.json +0 -13
  78. package/lib/{ReproducingSystem.d.ts → systems/ReproducingSystem.d.ts} +3 -3
  79. package/lib/{TrackerBar.d.ts → systems/TrackerBar.d.ts} +48 -8
  80. package/lib/{TrackerBar.js → systems/TrackerBar.js} +11 -2
  81. package/lib/systems/index.d.ts +8 -2
  82. package/lib/systems/index.js +7 -1
  83. package/lib/systems/welte.d.ts +100 -0
  84. package/lib/systems/welte.js +119 -0
  85. package/lib/systems/welteLicensee/bar.d.ts +1 -1
  86. package/lib/systems/welteLicensee/bar.js +5 -2
  87. package/lib/systems/welteLicensee/system.d.ts +1 -1
  88. package/lib/systems/welteLicensee/system.js +1 -1
  89. package/lib/systems/welteT100/bar.d.ts +27 -1
  90. package/lib/systems/welteT100/bar.js +44 -2
  91. package/lib/systems/welteT100/system.d.ts +6 -39
  92. package/lib/systems/welteT100/system.js +19 -128
  93. package/lib/systems/welteT98/bar.d.ts +1 -1
  94. package/lib/systems/welteT98/bar.js +18 -2
  95. package/lib/systems/welteT98/system.d.ts +20 -38
  96. package/lib/systems/welteT98/system.js +20 -121
  97. package/lib/validate.d.ts +1 -1
  98. package/lib/{EditionView.d.ts → view/EditionView.d.ts} +17 -41
  99. package/lib/{EditionView.js → view/EditionView.js} +26 -75
  100. package/package.json +7 -2
  101. package/lib/Emulation.d.ts +0 -36
  102. package/lib/Emulation.js +0 -250
  103. package/lib/editionOps.d.ts +0 -260
  104. package/lib/editionOps.js +0 -1079
  105. package/lib/importJsonLd.js +0 -57
  106. /package/lib/{migrate.d.ts → io/migrate.d.ts} +0 -0
  107. /package/lib/{Agent.js → model/Agent.js} +0 -0
  108. /package/lib/{Assumption.js → model/Assumption.js} +0 -0
  109. /package/lib/{ConditionState.d.ts → model/ConditionState.d.ts} +0 -0
  110. /package/lib/{ConditionState.js → model/ConditionState.js} +0 -0
  111. /package/lib/{Edit.js → model/Edit.js} +0 -0
  112. /package/lib/{Edition.js → model/Edition.js} +0 -0
  113. /package/lib/{Feature.js → model/Feature.js} +0 -0
  114. /package/lib/{FeatureSource.js → model/FeatureSource.js} +0 -0
  115. /package/lib/{Perforator.js → model/Perforator.js} +0 -0
  116. /package/lib/{Quantity.d.ts → model/Quantity.d.ts} +0 -0
  117. /package/lib/{Quantity.js → model/Quantity.js} +0 -0
  118. /package/lib/{Symbol.js → model/Symbol.js} +0 -0
  119. /package/lib/{TrackCalibration.d.ts → model/TrackCalibration.d.ts} +0 -0
  120. /package/lib/{TrackCalibration.js → model/TrackCalibration.js} +0 -0
  121. /package/lib/{notes.d.ts → model/notes.d.ts} +0 -0
  122. /package/lib/{notes.js → model/notes.js} +0 -0
  123. /package/lib/{procedures.d.ts → model/procedures.d.ts} +0 -0
  124. /package/lib/{procedures.js → model/procedures.js} +0 -0
  125. /package/lib/{vocabulary.d.ts → model/vocabulary.d.ts} +0 -0
  126. /package/lib/{sorted.d.ts → shared/sorted.d.ts} +0 -0
  127. /package/lib/{sorted.js → shared/sorted.js} +0 -0
  128. /package/lib/{utils.d.ts → shared/utils.d.ts} +0 -0
  129. /package/lib/{utils.js → shared/utils.js} +0 -0
  130. /package/lib/{ReproducingSystem.js → systems/ReproducingSystem.js} +0 -0
@@ -0,0 +1,20 @@
1
+ /**
2
+ * The symbol as a performance needs it: where it lies, and the
3
+ * position the performing bar reads it on.
4
+ *
5
+ * Nothing where that bar reads nothing of it, which is the case a
6
+ * transfer between systems leaves behind: a red `ForzandoOn` a
7
+ * green version still inherits cannot be performed on a green
8
+ * machine, and an edit has yet to say what took its place.
9
+ */
10
+ export const negotiatedEventOf = (view, symbol, bar) => {
11
+ const horizontal = view.placeOf(symbol);
12
+ const position = bar.positionOf(symbol);
13
+ if (!horizontal || position === undefined)
14
+ return null;
15
+ return {
16
+ ...symbol,
17
+ horizontal,
18
+ vertical: { unit: 'track', from: position }
19
+ };
20
+ };
package/lib/index.d.ts CHANGED
@@ -1,43 +1,51 @@
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';
1
+ /**
2
+ * The public interface of the library. Everything else under lib/ is its
3
+ * implementation and may change in any release: the in-place helpers the
4
+ * operations are built from, the date conversions of the serialisation,
5
+ * and the general utilities.
6
+ */
7
+ export type { WithId, WithNote, WithType } from './shared/utils.js';
8
+ export * from './model/Quantity.js';
9
+ export * from './model/Agent.js';
10
+ export * from './model/Assumption.js';
11
+ export * from './model/ConditionState.js';
12
+ export * from './model/Symbol.js';
13
+ export * from './model/Feature.js';
14
+ export * from './model/Edit.js';
15
+ export * from './model/Version.js';
16
+ export * from './collation/Collation.js';
17
+ export * from './model/TrackCalibration.js';
18
+ export * from './systems/TrackerBar.js';
13
19
  export * from './systems/welteT100/bar.js';
14
20
  export * from './systems/welteLicensee/bar.js';
15
21
  export * from './systems/welteT98/bar.js';
16
22
  export * from './systems/index.js';
17
- export * from './ReproducingSystem.js';
18
- export * from './FeatureSource.js';
19
- export * from './Perforator.js';
20
- export * from './RollCopy.js';
21
- export * from './procedures.js';
22
- export * from './vocabulary.js';
23
- export * from './reservations.js';
24
- export * from './witnesses.js';
25
- export * from './alignment.js';
26
- export * from './statistics.js';
27
- export * from './Edition.js';
28
- export * from './EditionView.js';
29
- export * from './scatter.js';
30
- export * from './editionOps.js';
31
- export * from './Emulation.js';
23
+ export * from './systems/ReproducingSystem.js';
24
+ export * from './model/FeatureSource.js';
25
+ export * from './model/Perforator.js';
26
+ export * from './model/RollCopy.js';
27
+ export * from './model/procedures.js';
28
+ export * from './model/vocabulary.js';
29
+ export * from './analysis/reservations.js';
30
+ export * from './analysis/witnesses.js';
31
+ export { alignFeatures, tooShortToShorten, type AlignmentResult } from './collation/alignment.js';
32
+ export * from './collation/statistics.js';
33
+ export * from './model/Edition.js';
34
+ export * from './view/EditionView.js';
35
+ export * from './analysis/ownPaper.js';
36
+ export * from './emulation/negotiation.js';
37
+ export * from './collation/scatter.js';
38
+ export * from './ops/index.js';
39
+ export * from './emulation/Emulation.js';
32
40
  export * from './validate.js';
33
- export * from './constraints.js';
34
- export * from './substitution.js';
35
- export * from './context.js';
36
- export * from './sigla.js';
37
- export * from './notes.js';
38
- export * from './asJsonLd.js';
39
- export * from './importJsonLd.js';
40
- export * from './migrate.js';
41
+ export * from './analysis/constraints.js';
42
+ export * from './collation/substitution.js';
43
+ export * from './io/context.js';
44
+ export * from './analysis/sigla.js';
45
+ export * from './model/notes.js';
46
+ export { asJsonLd } from './io/asJsonLd.js';
47
+ export { importJsonLd } from './io/importJsonLd.js';
48
+ export { migrate } from './io/migrate.js';
41
49
  export { readFromStanfordAton, type StanfordAtonOptions } from './readers/stanfordAton.js';
42
50
  export { readFromPhillipsEroll, CONTROL_OFFSET, phillipsSystems, type PhillipsErollOptions } from './readers/phillipsEroll.js';
43
51
  export { readFromSpencerBar, readSpencerAnn, paperSpeedOfSpencerAnn, SPENCER_ROWS_PER_INCH, type SpencerBarOptions } from './readers/spencerBar.js';
package/lib/index.js CHANGED
@@ -1,43 +1,44 @@
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';
1
+ export * from './model/Quantity.js';
2
+ export * from './model/Agent.js';
3
+ export * from './model/Assumption.js';
4
+ export * from './model/ConditionState.js';
5
+ export * from './model/Symbol.js';
6
+ export * from './model/Feature.js';
7
+ export * from './model/Edit.js';
8
+ export * from './model/Version.js';
9
+ export * from './collation/Collation.js';
10
+ export * from './model/TrackCalibration.js';
11
+ export * from './systems/TrackerBar.js';
13
12
  export * from './systems/welteT100/bar.js';
14
13
  export * from './systems/welteLicensee/bar.js';
15
14
  export * from './systems/welteT98/bar.js';
16
15
  export * from './systems/index.js';
17
- export * from './ReproducingSystem.js';
18
- export * from './FeatureSource.js';
19
- export * from './Perforator.js';
20
- export * from './RollCopy.js';
21
- export * from './procedures.js';
22
- export * from './vocabulary.js';
23
- export * from './reservations.js';
24
- export * from './witnesses.js';
25
- export * from './alignment.js';
26
- export * from './statistics.js';
27
- export * from './Edition.js';
28
- export * from './EditionView.js';
29
- export * from './scatter.js';
30
- export * from './editionOps.js';
31
- export * from './Emulation.js';
16
+ export * from './systems/ReproducingSystem.js';
17
+ export * from './model/FeatureSource.js';
18
+ export * from './model/Perforator.js';
19
+ export * from './model/RollCopy.js';
20
+ export * from './model/procedures.js';
21
+ export * from './model/vocabulary.js';
22
+ export * from './analysis/reservations.js';
23
+ export * from './analysis/witnesses.js';
24
+ export { alignFeatures, tooShortToShorten } from './collation/alignment.js';
25
+ export * from './collation/statistics.js';
26
+ export * from './model/Edition.js';
27
+ export * from './view/EditionView.js';
28
+ export * from './analysis/ownPaper.js';
29
+ export * from './emulation/negotiation.js';
30
+ export * from './collation/scatter.js';
31
+ export * from './ops/index.js';
32
+ export * from './emulation/Emulation.js';
32
33
  export * from './validate.js';
33
- export * from './constraints.js';
34
- export * from './substitution.js';
35
- export * from './context.js';
36
- export * from './sigla.js';
37
- export * from './notes.js';
38
- export * from './asJsonLd.js';
39
- export * from './importJsonLd.js';
40
- export * from './migrate.js';
34
+ export * from './analysis/constraints.js';
35
+ export * from './collation/substitution.js';
36
+ export * from './io/context.js';
37
+ export * from './analysis/sigla.js';
38
+ export * from './model/notes.js';
39
+ export { asJsonLd } from './io/asJsonLd.js';
40
+ export { importJsonLd } from './io/importJsonLd.js';
41
+ export { migrate } from './io/migrate.js';
41
42
  export { readFromStanfordAton } from './readers/stanfordAton.js';
42
43
  export { readFromPhillipsEroll, CONTROL_OFFSET, phillipsSystems } from './readers/phillipsEroll.js';
43
44
  export { readFromSpencerBar, readSpencerAnn, paperSpeedOfSpencerAnn, SPENCER_ROWS_PER_INCH } from './readers/spencerBar.js';
@@ -1,4 +1,4 @@
1
- import { Edition } from "./Edition.js";
1
+ import { Edition } from "../model/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.
@@ -1,6 +1,6 @@
1
- import { systemIdIn } from "./TrackerBar.js";
2
- import { certaintyOf, isAsserted } from "./Assumption.js";
3
- import context from "./spec/context.json" with { type: 'json' };
1
+ import { systemIdIn } from "../systems/TrackerBar.js";
2
+ import { certaintyOf, isAsserted } from "../model/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,12 +1,12 @@
1
- export { default as jsonLdContext } from './spec/context.json';
1
+ export { default as jsonLdContext } from '../spec/context.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';
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';
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';
@@ -1,12 +1,12 @@
1
- export { default as jsonLdContext } from './spec/context.json' with { type: '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' with { type: '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' with { type: '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' with { type: 'json' };
12
+ export { default as welteT98JsonLdContext } from '../spec/welte-t98.context.json' with { type: 'json' };
@@ -1,4 +1,4 @@
1
- import { Edition } from "./Edition.js";
1
+ import { Edition } from "../model/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;
@@ -0,0 +1,128 @@
1
+ import { derivedKeys } from "./asJsonLd.js";
2
+ import { migrate, plainCopyId } from "./migrate.js";
3
+ import { isDateString } from "../shared/utils.js";
4
+ import schema from "../schema.json" with { type: 'json' };
5
+ export const importDate = (str) => {
6
+ const [y, m, d] = str.split('-').map(s => parseInt(s, 10));
7
+ if ([y, m, d].some(n => isNaN(n))) {
8
+ throw new Error(`Invalid date format: "${str}". Expected "YYYY-MM-DD".`);
9
+ }
10
+ return new Date(y, m - 1, d);
11
+ };
12
+ /** The names of the properties the schema holds dates under, wherever they stand in it. */
13
+ const dateKeysIn = (node, keys = new Set()) => {
14
+ if (Array.isArray(node))
15
+ node.forEach(item => dateKeysIn(item, keys));
16
+ else if (node !== null && typeof node === 'object') {
17
+ Object.entries(node).forEach(([key, value]) => {
18
+ if (key === 'properties' && value !== null && typeof value === 'object') {
19
+ Object.entries(value)
20
+ .filter(([, property]) => property?.format === 'date')
21
+ .forEach(([name]) => keys.add(name));
22
+ }
23
+ dateKeysIn(value, keys);
24
+ });
25
+ }
26
+ return keys;
27
+ };
28
+ /**
29
+ * The keys a date is read under. Only these: a string elsewhere that
30
+ * happens to read like a date, such as the transcription of a dated
31
+ * label, is text and stays text.
32
+ */
33
+ const dateKeys = dateKeysIn(schema);
34
+ /** A value as the edition holds it under the key: a date read, an entity converted, anything else as it stands. */
35
+ const fromJsonLdValue = (key, value) => {
36
+ if (typeof value === 'string')
37
+ return dateKeys.has(key) && isDateString(value) ? importDate(value) : value;
38
+ if (Array.isArray(value))
39
+ return value.map(item => fromJsonLdValue(key, item));
40
+ if (value !== null && typeof value === 'object')
41
+ return fromJsonLdEntity(value);
42
+ return value;
43
+ };
44
+ /** A node without what the export derived from it: what an act changed follows from where the act stands. */
45
+ const asStated = (json) => Object.keys(json).some(key => derivedKeys.has(key))
46
+ ? Object.fromEntries(Object.entries(json).filter(([key]) => !derivedKeys.has(key)))
47
+ : json;
48
+ /**
49
+ * An entity with its keywords read as plain keys. The input is left as
50
+ * it is. The `@type` of a value object names the datatype of the value,
51
+ * not a class, and is dropped. So is a context: a version carries one
52
+ * naming its system's vocabulary, and it belongs to the serialisation
53
+ * rather than to the edition, which states the system as data.
54
+ */
55
+ const fromJsonLdEntity = (json) => {
56
+ const { '@type': type, '@id': id, '@context': context, ...rest } = asStated(json);
57
+ const entity = Object.fromEntries(Object.entries(rest).map(([key, value]) => [key, fromJsonLdValue(key, value)]));
58
+ if (type !== undefined && !('@value' in json))
59
+ entity.type = type;
60
+ if (id !== undefined)
61
+ entity.id = id;
62
+ return entity;
63
+ };
64
+ // Every entity is named by its id alone. Documents written before that was so
65
+ // prefixed a copy's with `copy/`, and are read here as though they had not.
66
+ const withPlainCopyIds = (json) => ({
67
+ ...json,
68
+ copies: (json.copies ?? []).map((copy) => ({
69
+ ...copy,
70
+ '@id': typeof copy['@id'] === 'string' ? plainCopyId(copy['@id']) : copy['@id']
71
+ }))
72
+ });
73
+ /** A statement an export quoted rather than stated: an included node whose id is a triple. */
74
+ const isQuotedStatement = (node) => node !== null && typeof node === 'object' && node['@id'] !== null && typeof node['@id'] === 'object';
75
+ /** The reference a quoted statement made, annotated again with the belief the export set beside it. */
76
+ const referenceOf = (statement) => {
77
+ const { '@id': { '@id': subject, ...made }, annotation, ...about } = statement;
78
+ const [key, value] = Object.entries(made)[0];
79
+ const listed = Array.isArray(value);
80
+ return {
81
+ subject,
82
+ key,
83
+ listed,
84
+ reference: {
85
+ ...(listed ? value[0] : value),
86
+ '@annotation': { ...(annotation !== undefined && { '@id': annotation }), ...about }
87
+ }
88
+ };
89
+ };
90
+ /** Whether the object states anything beside its id, which a reference to a node does not. */
91
+ const isNode = (value) => typeof value['@id'] === 'string' && Object.keys(value).some(key => key !== '@id' && key !== '@annotation');
92
+ /** The document with each quoted reference back on the node that makes it. */
93
+ const withReferencesOn = (value, bySubject) => {
94
+ if (Array.isArray(value))
95
+ return value.map(item => withReferencesOn(item, bySubject));
96
+ if (!value || typeof value !== 'object')
97
+ return value;
98
+ const walked = Object.fromEntries(Object.entries(value).map(([key, child]) => [key, withReferencesOn(child, bySubject)]));
99
+ const references = isNode(value)
100
+ ? bySubject.get(value['@id']) ?? []
101
+ : [];
102
+ return references.reduce((node, { key, listed, reference }) => ({ ...node, [key]: listed ? [...(node[key] ?? []), reference] : reference }), walked);
103
+ };
104
+ /**
105
+ * Puts back what an export quoted. A reference the edition doubts goes
106
+ * out as a JSON-LD-star embedded node beside the document, so that RDF
107
+ * does not state it; in the edition it belongs on the node that makes
108
+ * it, under its belief. In a list it comes back after the references
109
+ * that were stated.
110
+ */
111
+ const withQuotedStatementsInPlace = (edition) => {
112
+ const included = Array.isArray(edition['@included']) ? edition['@included'] : [];
113
+ const statements = included.filter(isQuotedStatement);
114
+ if (statements.length === 0)
115
+ return edition;
116
+ const others = included.filter(node => !isQuotedStatement(node));
117
+ const { '@included': _quoted, ...rest } = edition;
118
+ const bySubject = Map.groupBy(statements.map(referenceOf), ({ subject }) => subject);
119
+ return withReferencesOn({ ...rest, ...(others.length > 0 && { '@included': others }) }, bySubject);
120
+ };
121
+ export const importJsonLd = (json) => {
122
+ const { '@context': context, ...document } = withPlainCopyIds(migrate(withQuotedStatementsInPlace(json)));
123
+ const edition = fromJsonLdEntity(document);
124
+ edition.base = Array.isArray(context)
125
+ ? context.find((c) => c['@base'])?.['@base'] || ''
126
+ : '';
127
+ return edition;
128
+ };
@@ -1,11 +1,24 @@
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";
1
+ import { systemIdIn, systemOf, translationBetween } from "../systems/TrackerBar.js";
2
+ import { trackerBars } from "../systems/index.js";
3
+ import { welteT100 } from "../systems/welteT100/bar.js";
4
+ import { isDateString } from "../shared/utils.js";
7
5
  const retiredVersionTypes = new Set(['edition', 'unicum']);
8
- const conditionTypeValues = new Set([...rollConditions, ...Object.values(conditions).flat()]);
6
+ /**
7
+ * The vocabulary the steps below were written against, as it stood in
8
+ * release 0.58.0. It is copied here rather than imported from the model,
9
+ * so that changing today's vocabulary cannot change how an old document
10
+ * is read. The tracker bars are still
11
+ * asked, being the layout of instruments rather than a choice of the
12
+ * format.
13
+ */
14
+ const conditionTypeValues = new Set([
15
+ 'general', 'paper-stretch',
16
+ 'partially-torn', 'missing-perforation', 'illegible', 'faded', 'detaching', 'ripped'
17
+ ]);
18
+ const techniques = ['print', 'handwriting', 'stamp'];
19
+ const media = ['ink', 'pencil', 'crayon'];
20
+ const featureTypes = ['HoleChain', 'Writing', 'Mark', 'Patch'];
21
+ const isFeatureType = (value) => typeof value === 'string' && featureTypes.includes(value);
9
22
  const renamedKeys = {
10
23
  productionEvent: 'production',
11
24
  annotates: 'depiction',
@@ -128,6 +141,38 @@ const withScale = (node) => {
128
141
  const factor = (node.conditions ?? []).find(isPaperStretch)?.factor;
129
142
  return factor === undefined ? node : { ...node, measurements: { ...node.measurements, scale: factor } };
130
143
  };
144
+ /**
145
+ * What each entry of a copy's former `ops` list stands for among its
146
+ * measurements, and the value that does nothing where the list claimed
147
+ * an act whose amount was never recorded.
148
+ */
149
+ const opsInMeasurements = [
150
+ ['shifted', 'shift', { horizontal: 0, vertical: 0 }],
151
+ ['stretched', 'scale', 1],
152
+ ['shortened', 'readerExtension', { length: 0 }]
153
+ ];
154
+ /**
155
+ * A copy listed what had been done to line its features up, which said
156
+ * again what its measurements state; the measurements now say it alone.
157
+ * Where the two disagreed, the list is what the alignment went by, so
158
+ * the measurements are made to say what it said: a measurement it does
159
+ * not list is dropped, and an act it lists without a recorded amount is
160
+ * recorded as one that moved nothing. `withScale` has read the list by
161
+ * the time this runs.
162
+ */
163
+ const withoutOps = (node) => {
164
+ if (!Array.isArray(node.ops))
165
+ return node;
166
+ const { ops, ...rest } = node;
167
+ const measurements = { ...rest.measurements };
168
+ opsInMeasurements.forEach(([op, key, nothing]) => {
169
+ if (!ops.includes(op))
170
+ delete measurements[key];
171
+ else if (measurements[key] === undefined)
172
+ measurements[key] = nothing;
173
+ });
174
+ return { ...rest, measurements };
175
+ };
131
176
  /** A copy's id without the `copy/` that documents of earlier releases put before it. */
132
177
  export const plainCopyId = (id) => id.replace(/^copy\//, '');
133
178
  /**
@@ -327,7 +372,7 @@ const withTimeSpanDates = (node) => {
327
372
  return { ...rest, within };
328
373
  };
329
374
  const migrateNode = (node) => [withRenamedKeys, withTypology, withRenamedType, withoutVersionType, withoutVersionSiglum, withLowerCaseTerms, withSplitMethod, withReferences, withKeeper, withoutEmptyKeeper,
330
- withPerforator, withProductionNodes, withTypedPerforator, withScale, withDerivationList, withReadingKind, withTimeSpanDates,
375
+ withPerforator, withProductionNodes, withTypedPerforator, withScale, withoutOps, withDerivationList, withReadingKind, withTimeSpanDates,
331
376
  withoutFeatureKind, withBorneFeaturesNamed, withFeaturesInActs, withDriveOfStaggering, withoutPattern, withoutBearings, withoutEntailedType]
332
377
  .reduce((result, step) => step(result), node);
333
378
  /** The items each walked, or the very same list where the walk changed none. */
@@ -466,53 +511,12 @@ const withDerivationTolerance = (edition) => {
466
511
  : version)
467
512
  };
468
513
  };
469
- /** A statement an export quoted rather than stated: an included node whose id is a triple. */
470
- const isQuotedStatement = (node) => node !== null && typeof node === 'object' && node['@id'] !== null && typeof node['@id'] === 'object';
471
- /** The reference a quoted statement made, annotated again with the belief the export set beside it. */
472
- const referenceOf = (statement) => {
473
- const { '@id': { '@id': subject, ...made }, annotation, ...about } = statement;
474
- const [key, value] = Object.entries(made)[0];
475
- const listed = Array.isArray(value);
476
- return {
477
- subject,
478
- key,
479
- listed,
480
- reference: {
481
- ...(listed ? value[0] : value),
482
- '@annotation': { ...(annotation !== undefined && { '@id': annotation }), ...about }
483
- }
484
- };
485
- };
486
- /** Whether the object states anything beside its id, which a reference to a node does not. */
487
- const isNode = (value) => typeof value['@id'] === 'string' && Object.keys(value).some(key => key !== '@id' && key !== '@annotation');
488
- /** The document with each quoted reference back on the node that makes it. */
489
- const withReferencesOn = (value, bySubject) => {
490
- if (Array.isArray(value))
491
- return value.map(item => withReferencesOn(item, bySubject));
492
- if (!value || typeof value !== 'object')
493
- return value;
494
- const walked = Object.fromEntries(Object.entries(value).map(([key, child]) => [key, withReferencesOn(child, bySubject)]));
495
- const references = isNode(value)
496
- ? bySubject.get(value['@id']) ?? []
497
- : [];
498
- return references.reduce((node, { key, listed, reference }) => ({ ...node, [key]: listed ? [...(node[key] ?? []), reference] : reference }), walked);
499
- };
500
- /**
501
- * Puts back what an export quoted. A reference the edition doubts goes
502
- * out as a JSON-LD-star embedded node beside the document, so that RDF
503
- * does not state it; in the edition it belongs on the node that makes
504
- * it, under its belief. In a list it comes back after the references
505
- * that were stated.
506
- */
507
- const withQuotedStatementsInPlace = (edition) => {
508
- const included = Array.isArray(edition['@included']) ? edition['@included'] : [];
509
- const statements = included.filter(isQuotedStatement);
510
- if (statements.length === 0)
514
+ /** Release 0.58.0 stated a revision of the format, which the format does not state. */
515
+ const withoutFormatVersion = (edition) => {
516
+ if (!Object.hasOwn(edition, 'formatVersion'))
511
517
  return edition;
512
- const others = included.filter(node => !isQuotedStatement(node));
513
- const { '@included': _quoted, ...rest } = edition;
514
- const bySubject = Map.groupBy(statements.map(referenceOf), ({ subject }) => subject);
515
- return withReferencesOn({ ...rest, ...(others.length > 0 && { '@included': others }) }, bySubject);
518
+ const { formatVersion: _stated, ...rest } = edition;
519
+ return rest;
516
520
  };
517
- const editionSteps = [withoutEditionType, withQuotedStatementsInPlace, withSystems, withEditors, withDerivationTolerance];
521
+ const editionSteps = [withoutFormatVersion, withoutEditionType, withSystems, withEditors, withDerivationTolerance];
518
522
  export const migrate = (edition) => walk(editionSteps.reduce((result, step) => step(result), edition));
@@ -1,4 +1,4 @@
1
- import { WithId } from "./utils.js";
1
+ import { WithId } from "../shared/utils.js";
2
2
  /**
3
3
  * Something with a name and, where one exists, an authority record.
4
4
  */
@@ -1,4 +1,4 @@
1
- import { WithNote, WithId } from "./utils.js";
1
+ import { WithNote, WithId } from "../shared/utils.js";
2
2
  import { Person, WithActor } from "./Agent.js";
3
3
  export declare const certainties: readonly ['true', 'likely', 'possible', 'unlikely', 'false'];
4
4
  /**
@@ -1,6 +1,6 @@
1
1
  import { Assumption } from "./Assumption.js";
2
2
  import { AnySymbol } from "./Symbol.js";
3
- import { WithId } from "./utils.js";
3
+ import { WithId } from "../shared/utils.js";
4
4
  export declare const editTypes: readonly [
5
5
  /**
6
6
  * An additional accent that can only be encoded with
@@ -1,9 +1,9 @@
1
1
  import { RollCopy } from "./RollCopy.js";
2
2
  import { Version } from "./Version.js";
3
- import { CollationTolerance } from "./Collation.js";
3
+ import { CollationTolerance } from "../collation/Collation.js";
4
4
  import { DateAssignment, ObjectAssumption } from "./Assumption.js";
5
5
  import { Editor, Person, Place } from "./Agent.js";
6
- import { RollTempo } from "./ReproducingSystem.js";
6
+ import { RollTempo } from "../systems/ReproducingSystem.js";
7
7
  /**
8
8
  * This type describes the creation of an edition,
9
9
  * i.e. the editor, publisher, and publication date.
@@ -1,7 +1,7 @@
1
1
  import { ObjectAssumption } from "./Assumption.js";
2
2
  import { ConditionState } from "./ConditionState.js";
3
3
  import { Text } from "./Symbol.js";
4
- import { PartialBy, WithId, WithType } from "./utils.js";
4
+ import { PartialBy, WithId, WithType } from "../shared/utils.js";
5
5
  import { Measure, Millimeters, Track } from "./Quantity.js";
6
6
  /**
7
7
  * Describes the horizontal extent of a feature on the roll,
@@ -1,7 +1,7 @@
1
1
  import { ActorAssignment, DateAssignment, ObjectAssumption } from "./Assumption.js";
2
2
  import { Concept, Named } from "./Agent.js";
3
3
  import { ConditionState } from "./ConditionState.js";
4
- import { WithNote } from "./utils.js";
4
+ import { WithNote } from "../shared/utils.js";
5
5
  /**
6
6
  * What a copy's features were read from. The kinds run from the paper
7
7
  * itself, through files in which the roll has already been read into
@@ -1,7 +1,7 @@
1
1
  import { ObjectAssumption } from "./Assumption.js";
2
2
  import { ConditionState } from "./ConditionState.js";
3
3
  import { Measure, Millimeters } from "./Quantity.js";
4
- import { WithId, WithType } from "./utils.js";
4
+ import { WithId, WithType } from "../shared/utils.js";
5
5
  /**
6
6
  * The pitch in the engineering sense: the distance along the roll from
7
7
  * one punch of a chain to the next, which is the slot one firing cut
@@ -1,10 +1,10 @@
1
1
  import { ConditionState } from "./ConditionState.js";
2
2
  import { AnySymbol } from "./Symbol.js";
3
- import { TrackerBar } from "./TrackerBar.js";
3
+ import { TrackerBar } from "../systems/TrackerBar.js";
4
4
  import { TrackCalibration } from "./TrackCalibration.js";
5
5
  import { AnyFeature, FeatureOrPatch, Patch } from "./Feature.js";
6
6
  import { ActorAssignment, DateAssignment, ObjectAssumption, ReferenceAssumption } from "./Assumption.js";
7
- import { WithId, WithType } from "./utils.js";
7
+ import { WithId, WithType } from "../shared/utils.js";
8
8
  import { Agent, Concept } from "./Agent.js";
9
9
  import { FeatureSource } from "./FeatureSource.js";
10
10
  import { Measure, Millimeters, Quantity, Track } from "./Quantity.js";
@@ -203,12 +203,6 @@ export type Modification = Partial<{
203
203
  * @see reo:RollCopy
204
204
  */
205
205
  export interface RollCopy extends WithType<'RollCopy'>, WithId {
206
- /**
207
- * A list of operations that have been applied to this copy's features
208
- * (e.g. 'shifted', 'stretched') to normalize measurements
209
- * for comparison with other copies. Not exported to RDF.
210
- */
211
- ops: Array<'shifted' | 'stretched' | 'shortened'>;
212
206
  /**
213
207
  * Physical measurements of this roll copy, including
214
208
  * dimensions, hole separation, margins, shift corrections,
@@ -403,8 +397,7 @@ export declare const featuresOf: (copy: Pick<RollCopy, 'production' | 'modificat
403
397
  export declare const isPaperStretch: (condition: RollConditionAssignment) => boolean;
404
398
  /**
405
399
  * The bar a copy is read by, which is the one it was cut for. A copy
406
- * that names no system falls back to the T-100, as every copy was read
407
- * before the systems were told apart; `reservationsAbout` says so.
400
+ * that names no system falls back to `defaultTrackerBar`.
408
401
  */
409
402
  export declare const barOf: (copy: Pick<RollCopy, 'production'>) => TrackerBar;
410
403
  /** The diameter of the punch the copy was cut with, where the edition holds it true or likely. */