« get me outta code hell

hsmusic-wiki - HSMusic - static wiki software cataloguing collaborative creation
about summary refs log tree commit diff
path: root/src/data/composite/things
diff options
context:
space:
mode:
Diffstat (limited to 'src/data/composite/things')
-rw-r--r--src/data/composite/things/album/index.js2
-rw-r--r--src/data/composite/things/album/withHasCoverArt.js64
-rw-r--r--src/data/composite/things/album/withTracks.js29
-rw-r--r--src/data/composite/things/art-tag/index.js2
-rw-r--r--src/data/composite/things/art-tag/withAllDescendantArtTags.js44
-rw-r--r--src/data/composite/things/art-tag/withAncestorArtTagBaobabTree.js46
-rw-r--r--src/data/composite/things/artist/artistTotalDuration.js69
-rw-r--r--src/data/composite/things/artist/index.js1
-rw-r--r--src/data/composite/things/artwork/index.js4
-rw-r--r--src/data/composite/things/artwork/withAttachedArtwork.js43
-rw-r--r--src/data/composite/things/artwork/withContribsFromAttachedArtwork.js28
-rw-r--r--src/data/composite/things/artwork/withDate.js41
-rw-r--r--src/data/composite/things/artwork/withPropertyFromAttachedArtwork.js65
-rw-r--r--src/data/composite/things/commentary-entry/index.js1
-rw-r--r--src/data/composite/things/content/hasAnnotationPart.js25
-rw-r--r--src/data/composite/things/content/index.js4
-rw-r--r--src/data/composite/things/content/withAnnotationPartNodeLists.js28
-rw-r--r--src/data/composite/things/content/withExpressedOrImplicitArtistReferences.js61
-rw-r--r--src/data/composite/things/content/withWebArchiveDate.js (renamed from src/data/composite/things/commentary-entry/withWebArchiveDate.js)0
-rw-r--r--src/data/composite/things/contribution/index.js4
-rw-r--r--src/data/composite/things/contribution/inheritFromContributionPresets.js17
-rw-r--r--src/data/composite/things/contribution/thingPropertyMatches.js46
-rw-r--r--src/data/composite/things/contribution/thingReferenceTypeMatches.js66
-rw-r--r--src/data/composite/things/contribution/withContainingReverseContributionList.js8
-rw-r--r--src/data/composite/things/contribution/withContributionArtist.js26
-rw-r--r--src/data/composite/things/contribution/withMatchingContributionPresets.js70
-rw-r--r--src/data/composite/things/flash-act/index.js1
-rw-r--r--src/data/composite/things/flash-act/withFlashSide.js22
-rw-r--r--src/data/composite/things/flash/index.js1
-rw-r--r--src/data/composite/things/flash/withFlashAct.js22
-rw-r--r--src/data/composite/things/track-section/index.js3
-rw-r--r--src/data/composite/things/track-section/withAlbum.js20
-rw-r--r--src/data/composite/things/track-section/withContinueCountingFrom.js25
-rw-r--r--src/data/composite/things/track-section/withStartCountingFrom.js64
-rw-r--r--src/data/composite/things/track/exitWithoutUniqueCoverArt.js26
-rw-r--r--src/data/composite/things/track/index.js15
-rw-r--r--src/data/composite/things/track/inheritContributionListFromMainRelease.js29
-rw-r--r--src/data/composite/things/track/inheritFromMainRelease.js28
-rw-r--r--src/data/composite/things/track/trackAdditionalNameList.js38
-rw-r--r--src/data/composite/things/track/withAllReleases.js47
-rw-r--r--src/data/composite/things/track/withAlwaysReferenceByDirectory.js97
-rw-r--r--src/data/composite/things/track/withContainingTrackSection.js20
-rw-r--r--src/data/composite/things/track/withCoverArtistContribs.js73
-rw-r--r--src/data/composite/things/track/withDate.js34
-rw-r--r--src/data/composite/things/track/withDirectorySuffix.js36
-rw-r--r--src/data/composite/things/track/withHasUniqueCoverArt.js108
-rw-r--r--src/data/composite/things/track/withMainRelease.js70
-rw-r--r--src/data/composite/things/track/withOtherReleases.js30
-rw-r--r--src/data/composite/things/track/withPropertyFromAlbum.js48
-rw-r--r--src/data/composite/things/track/withPropertyFromMainRelease.js86
-rw-r--r--src/data/composite/things/track/withSuffixDirectoryFromAlbum.js53
-rw-r--r--src/data/composite/things/track/withTrackArtDate.js60
-rw-r--r--src/data/composite/things/track/withTrackNumber.js50
53 files changed, 144 insertions, 1756 deletions
diff --git a/src/data/composite/things/album/index.js b/src/data/composite/things/album/index.js
deleted file mode 100644
index dfc6864f..00000000
--- a/src/data/composite/things/album/index.js
+++ /dev/null
@@ -1,2 +0,0 @@
-export {default as withHasCoverArt} from './withHasCoverArt.js';
-export {default as withTracks} from './withTracks.js';
diff --git a/src/data/composite/things/album/withHasCoverArt.js b/src/data/composite/things/album/withHasCoverArt.js
deleted file mode 100644
index fd3f2894..00000000
--- a/src/data/composite/things/album/withHasCoverArt.js
+++ /dev/null
@@ -1,64 +0,0 @@
-// TODO: This shouldn't be coded as an Album-specific thing,
-// or even really to do with cover artworks in particular, either.
-
-import {input, templateCompositeFrom} from '#composite';
-
-import {raiseOutputWithoutDependency, withResultOfAvailabilityCheck}
-  from '#composite/control-flow';
-import {fillMissingListItems, withFlattenedList, withPropertyFromList}
-  from '#composite/data';
-
-export default templateCompositeFrom({
-  annotation: 'withHasCoverArt',
-
-  outputs: ['#hasCoverArt'],
-
-  steps: () => [
-    withResultOfAvailabilityCheck({
-      from: 'coverArtistContribs',
-      mode: input.value('empty'),
-    }),
-
-    {
-      dependencies: ['#availability'],
-      compute: (continuation, {
-        ['#availability']: availability,
-      }) =>
-        (availability
-          ? continuation.raiseOutput({
-              ['#hasCoverArt']: true,
-            })
-          : continuation()),
-    },
-
-    raiseOutputWithoutDependency({
-      dependency: 'coverArtworks',
-      mode: input.value('empty'),
-      output: input.value({'#hasCoverArt': false}),
-    }),
-
-    withPropertyFromList({
-      list: 'coverArtworks',
-      property: input.value('artistContribs'),
-      internal: input.value(true),
-    }),
-
-    // Since we're getting the update value for each artwork's artistContribs,
-    // it may not be set at all, and in that case won't be exposing as [].
-    fillMissingListItems({
-      list: '#coverArtworks.artistContribs',
-      fill: input.value([]),
-    }),
-
-    withFlattenedList({
-      list: '#coverArtworks.artistContribs',
-    }),
-
-    withResultOfAvailabilityCheck({
-      from: '#flattenedList',
-      mode: input.value('empty'),
-    }).outputs({
-      '#availability': '#hasCoverArt',
-    }),
-  ],
-});
diff --git a/src/data/composite/things/album/withTracks.js b/src/data/composite/things/album/withTracks.js
deleted file mode 100644
index 835ee570..00000000
--- a/src/data/composite/things/album/withTracks.js
+++ /dev/null
@@ -1,29 +0,0 @@
-import {input, templateCompositeFrom} from '#composite';
-
-import {withFlattenedList, withPropertyFromList} from '#composite/data';
-
-import {raiseOutputWithoutDependency} from '#composite/control-flow';
-
-export default templateCompositeFrom({
-  annotation: `withTracks`,
-
-  outputs: ['#tracks'],
-
-  steps: () => [
-    raiseOutputWithoutDependency({
-      dependency: 'trackSections',
-      output: input.value({'#tracks': []}),
-    }),
-
-    withPropertyFromList({
-      list: 'trackSections',
-      property: input.value('tracks'),
-    }),
-
-    withFlattenedList({
-      list: '#trackSections.tracks',
-    }).outputs({
-      ['#flattenedList']: '#tracks',
-    }),
-  ],
-});
diff --git a/src/data/composite/things/art-tag/index.js b/src/data/composite/things/art-tag/index.js
deleted file mode 100644
index bbd38293..00000000
--- a/src/data/composite/things/art-tag/index.js
+++ /dev/null
@@ -1,2 +0,0 @@
-export {default as withAllDescendantArtTags} from './withAllDescendantArtTags.js';
-export {default as withAncestorArtTagBaobabTree} from './withAncestorArtTagBaobabTree.js';
diff --git a/src/data/composite/things/art-tag/withAllDescendantArtTags.js b/src/data/composite/things/art-tag/withAllDescendantArtTags.js
deleted file mode 100644
index 795f96cd..00000000
--- a/src/data/composite/things/art-tag/withAllDescendantArtTags.js
+++ /dev/null
@@ -1,44 +0,0 @@
-// Gets all the art tags which descend from this one - that means its own direct
-// descendants, but also all the direct and indirect desceands of each of those!
-// The results aren't specially sorted, but they won't contain any duplicates
-// (for example if two descendant tags both route deeper to end up including
-// some of the same tags).
-
-import {input, templateCompositeFrom} from '#composite';
-import {unique} from '#sugar';
-
-import {raiseOutputWithoutDependency} from '#composite/control-flow';
-import {withResolvedReferenceList} from '#composite/wiki-data';
-import {soupyFind} from '#composite/wiki-properties';
-
-export default templateCompositeFrom({
-  annotation: `withAllDescendantArtTags`,
-
-  outputs: ['#allDescendantArtTags'],
-
-  steps: () => [
-    raiseOutputWithoutDependency({
-      dependency: 'directDescendantArtTags',
-      mode: input.value('empty'),
-      output: input.value({'#allDescendantArtTags': []})
-    }),
-
-    withResolvedReferenceList({
-      list: 'directDescendantArtTags',
-      find: soupyFind.input('artTag'),
-    }),
-
-    {
-      dependencies: ['#resolvedReferenceList'],
-      compute: (continuation, {
-        ['#resolvedReferenceList']: directDescendantArtTags,
-      }) => continuation({
-        ['#allDescendantArtTags']:
-          unique([
-            ...directDescendantArtTags,
-            ...directDescendantArtTags.flatMap(artTag => artTag.allDescendantArtTags),
-          ]),
-      }),
-    },
-  ],
-})
diff --git a/src/data/composite/things/art-tag/withAncestorArtTagBaobabTree.js b/src/data/composite/things/art-tag/withAncestorArtTagBaobabTree.js
deleted file mode 100644
index e084a42b..00000000
--- a/src/data/composite/things/art-tag/withAncestorArtTagBaobabTree.js
+++ /dev/null
@@ -1,46 +0,0 @@
-// Gets all the art tags which are ancestors of this one as a "baobab tree" -
-// what you'd typically think of as roots are all up in the air! Since this
-// really is backwards from the way that the art tag tree is written in data,
-// chances are pretty good that there will be many of the exact same "leaf"
-// nodes - art tags which don't themselves have any ancestors. In the actual
-// data structure, each node is a Map, with keys for each ancestor and values
-// for each ancestor's own baobab (thus a branching structure, just like normal
-// trees in this regard).
-
-import {input, templateCompositeFrom} from '#composite';
-
-import {raiseOutputWithoutDependency} from '#composite/control-flow';
-import {withReverseReferenceList} from '#composite/wiki-data';
-import {soupyReverse} from '#composite/wiki-properties';
-
-export default templateCompositeFrom({
-  annotation: `withAncestorArtTagBaobabTree`,
-
-  outputs: ['#ancestorArtTagBaobabTree'],
-
-  steps: () => [
-    withReverseReferenceList({
-      reverse: soupyReverse.input('artTagsWhichDirectlyAncestor'),
-    }).outputs({
-      ['#reverseReferenceList']: '#directAncestorArtTags',
-    }),
-
-    raiseOutputWithoutDependency({
-      dependency: '#directAncestorArtTags',
-      mode: input.value('empty'),
-      output: input.value({'#ancestorArtTagBaobabTree': new Map()}),
-    }),
-
-    {
-      dependencies: ['#directAncestorArtTags'],
-      compute: (continuation, {
-        ['#directAncestorArtTags']: directAncestorArtTags,
-      }) => continuation({
-        ['#ancestorArtTagBaobabTree']:
-          new Map(
-            directAncestorArtTags
-              .map(artTag => [artTag, artTag.ancestorArtTagBaobabTree])),
-      }),
-    },
-  ],
-});
diff --git a/src/data/composite/things/artist/artistTotalDuration.js b/src/data/composite/things/artist/artistTotalDuration.js
deleted file mode 100644
index b8a205fe..00000000
--- a/src/data/composite/things/artist/artistTotalDuration.js
+++ /dev/null
@@ -1,69 +0,0 @@
-import {input, templateCompositeFrom} from '#composite';
-
-import {exposeDependency} from '#composite/control-flow';
-import {withFilteredList, withPropertyFromList} from '#composite/data';
-import {withContributionListSums, withReverseReferenceList}
-  from '#composite/wiki-data';
-import {soupyReverse} from '#composite/wiki-properties';
-
-export default templateCompositeFrom({
-  annotation: `artistTotalDuration`,
-
-  compose: false,
-
-  steps: () => [
-    withReverseReferenceList({
-      reverse: soupyReverse.input('trackArtistContributionsBy'),
-    }).outputs({
-      '#reverseReferenceList': '#contributionsAsArtist',
-    }),
-
-    withReverseReferenceList({
-      reverse: soupyReverse.input('trackContributorContributionsBy'),
-    }).outputs({
-      '#reverseReferenceList': '#contributionsAsContributor',
-    }),
-
-    {
-      dependencies: [
-        '#contributionsAsArtist',
-        '#contributionsAsContributor',
-      ],
-
-      compute: (continuation, {
-        ['#contributionsAsArtist']: artistContribs,
-        ['#contributionsAsContributor']: contributorContribs,
-      }) => continuation({
-        ['#allContributions']: [
-          ...artistContribs,
-          ...contributorContribs,
-        ],
-      }),
-    },
-
-    withPropertyFromList({
-      list: '#allContributions',
-      property: input.value('thing'),
-    }),
-
-    withPropertyFromList({
-      list: '#allContributions.thing',
-      property: input.value('isMainRelease'),
-    }),
-
-    withFilteredList({
-      list: '#allContributions',
-      filter: '#allContributions.thing.isMainRelease',
-    }).outputs({
-      '#filteredList': '#mainReleaseContributions',
-    }),
-
-    withContributionListSums({
-      list: '#mainReleaseContributions',
-    }),
-
-    exposeDependency({
-      dependency: '#contributionListDuration',
-    }),
-  ],
-});
diff --git a/src/data/composite/things/artist/index.js b/src/data/composite/things/artist/index.js
deleted file mode 100644
index 55514c71..00000000
--- a/src/data/composite/things/artist/index.js
+++ /dev/null
@@ -1 +0,0 @@
-export {default as artistTotalDuration} from './artistTotalDuration.js';
diff --git a/src/data/composite/things/artwork/index.js b/src/data/composite/things/artwork/index.js
index 3693c10f..2cd3c388 100644
--- a/src/data/composite/things/artwork/index.js
+++ b/src/data/composite/things/artwork/index.js
@@ -1,5 +1 @@
-export {default as withAttachedArtwork} from './withAttachedArtwork.js';
 export {default as withContainingArtworkList} from './withContainingArtworkList.js';
-export {default as withContribsFromAttachedArtwork} from './withContribsFromAttachedArtwork.js';
-export {default as withDate} from './withDate.js';
-export {default as withPropertyFromAttachedArtwork} from './withPropertyFromAttachedArtwork.js';
diff --git a/src/data/composite/things/artwork/withAttachedArtwork.js b/src/data/composite/things/artwork/withAttachedArtwork.js
deleted file mode 100644
index d7c0d87b..00000000
--- a/src/data/composite/things/artwork/withAttachedArtwork.js
+++ /dev/null
@@ -1,43 +0,0 @@
-import {input, templateCompositeFrom} from '#composite';
-
-import {flipFilter, raiseOutputWithoutDependency}
-  from '#composite/control-flow';
-import {withNearbyItemFromList, withPropertyFromList} from '#composite/data';
-
-import withContainingArtworkList from './withContainingArtworkList.js';
-
-export default templateCompositeFrom({
-  annotaion: `withContribsFromMainArtwork`,
-
-  outputs: ['#attachedArtwork'],
-
-  steps: () => [
-    raiseOutputWithoutDependency({
-      dependency: 'attachAbove',
-      mode: input.value('falsy'),
-      output: input.value({'#attachedArtwork': null}),
-    }),
-
-    withContainingArtworkList(),
-
-    withPropertyFromList({
-      list: '#containingArtworkList',
-      property: input.value('attachAbove'),
-    }),
-
-    flipFilter({
-      filter: '#containingArtworkList.attachAbove',
-    }).outputs({
-      '#containingArtworkList.attachAbove': '#filterNotAttached',
-    }),
-
-    withNearbyItemFromList({
-      list: '#containingArtworkList',
-      item: input.myself(),
-      offset: input.value(-1),
-      filter: '#filterNotAttached',
-    }).outputs({
-      '#nearbyItem': '#attachedArtwork',
-    }),
-  ],
-});
diff --git a/src/data/composite/things/artwork/withContribsFromAttachedArtwork.js b/src/data/composite/things/artwork/withContribsFromAttachedArtwork.js
deleted file mode 100644
index 36abb3fe..00000000
--- a/src/data/composite/things/artwork/withContribsFromAttachedArtwork.js
+++ /dev/null
@@ -1,28 +0,0 @@
-import {input, templateCompositeFrom} from '#composite';
-
-import {raiseOutputWithoutDependency} from '#composite/control-flow';
-import {withPropertyFromObject} from '#composite/data';
-import {withRecontextualizedContributionList} from '#composite/wiki-data';
-
-import withPropertyFromAttachedArtwork from './withPropertyFromAttachedArtwork.js';
-
-export default templateCompositeFrom({
-  annotaion: `withContribsFromAttachedArtwork`,
-
-  outputs: ['#attachedArtwork.artistContribs'],
-
-  steps: () => [
-    withPropertyFromAttachedArtwork({
-      property: input.value('artistContribs'),
-    }),
-
-    raiseOutputWithoutDependency({
-      dependency: '#attachedArtwork.artistContribs',
-      output: input.value({'#attachedArtwork.artistContribs': null}),
-    }),
-
-    withRecontextualizedContributionList({
-      list: '#attachedArtwork.artistContribs',
-    }),
-  ],
-});
diff --git a/src/data/composite/things/artwork/withDate.js b/src/data/composite/things/artwork/withDate.js
deleted file mode 100644
index 5e05b814..00000000
--- a/src/data/composite/things/artwork/withDate.js
+++ /dev/null
@@ -1,41 +0,0 @@
-import {input, templateCompositeFrom} from '#composite';
-
-import {raiseOutputWithoutDependency} from '#composite/control-flow';
-import {withPropertyFromObject} from '#composite/data';
-
-export default templateCompositeFrom({
-  annotation: `withDate`,
-
-  inputs: {
-    from: input({
-      defaultDependency: 'date',
-      acceptsNull: true,
-    }),
-  },
-
-  outputs: ['#date'],
-
-  steps: () => [
-    {
-      dependencies: [input('from')],
-      compute: (continuation, {
-        [input('from')]: date,
-      }) =>
-        (date
-          ? continuation.raiseOutput({'#date': date})
-          : continuation()),
-    },
-
-    raiseOutputWithoutDependency({
-      dependency: 'dateFromThingProperty',
-      output: input.value({'#date': null}),
-    }),
-
-    withPropertyFromObject({
-      object: 'thing',
-      property: 'dateFromThingProperty',
-    }).outputs({
-      ['#value']: '#date',
-    }),
-  ],
-})
diff --git a/src/data/composite/things/artwork/withPropertyFromAttachedArtwork.js b/src/data/composite/things/artwork/withPropertyFromAttachedArtwork.js
deleted file mode 100644
index a2f954b9..00000000
--- a/src/data/composite/things/artwork/withPropertyFromAttachedArtwork.js
+++ /dev/null
@@ -1,65 +0,0 @@
-import {input, templateCompositeFrom} from '#composite';
-
-import {withResultOfAvailabilityCheck} from '#composite/control-flow';
-import {withPropertyFromObject} from '#composite/data';
-
-import withAttachedArtwork from './withAttachedArtwork.js';
-
-function getOutputName({
-  [input.staticValue('property')]: property,
-}) {
-  if (property) {
-    return `#attachedArtwork.${property}`;
-  } else {
-    return '#value';
-  }
-}
-
-export default templateCompositeFrom({
-  annotation: `withPropertyFromAttachedArtwork`,
-
-  inputs: {
-    property: input({type: 'string'}),
-  },
-
-  outputs: inputs => [getOutputName(inputs)],
-
-  steps: () => [
-    {
-      dependencies: [input.staticValue('property')],
-      compute: (continuation, inputs) =>
-        continuation({'#output': getOutputName(inputs)}),
-    },
-
-    withAttachedArtwork(),
-
-    withResultOfAvailabilityCheck({
-      from: '#attachedArtwork',
-    }),
-
-    {
-      dependencies: ['#availability', '#output'],
-      compute: (continuation, {
-        ['#availability']: availability,
-        ['#output']: output,
-      }) =>
-        (availability
-          ? continuation()
-          : continuation.raiseOutput({[output]: null})),
-    },
-
-    withPropertyFromObject({
-      object: '#attachedArtwork',
-      property: input('property'),
-    }),
-
-    {
-      dependencies: ['#value', '#output'],
-      compute: (continuation, {
-        ['#value']: value,
-        ['#output']: output,
-      }) =>
-        continuation.raiseOutput({[output]: value}),
-    },
-  ],
-});
diff --git a/src/data/composite/things/commentary-entry/index.js b/src/data/composite/things/commentary-entry/index.js
deleted file mode 100644
index 091bae1a..00000000
--- a/src/data/composite/things/commentary-entry/index.js
+++ /dev/null
@@ -1 +0,0 @@
-export {default as withWebArchiveDate} from './withWebArchiveDate.js';
diff --git a/src/data/composite/things/content/hasAnnotationPart.js b/src/data/composite/things/content/hasAnnotationPart.js
new file mode 100644
index 00000000..93aaf5e5
--- /dev/null
+++ b/src/data/composite/things/content/hasAnnotationPart.js
@@ -0,0 +1,25 @@
+import {input, templateCompositeFrom} from '#composite';
+
+export default templateCompositeFrom({
+  annotation: `hasAnnotationPart`,
+
+  compose: false,
+
+  inputs: {
+    part: input({type: 'string'}),
+  },
+
+  steps: () => [
+    {
+      dependencies: [input('part'), 'annotationParts'],
+
+      compute: ({
+        [input('part')]: search,
+        ['annotationParts']: parts,
+      }) =>
+          parts.some(part =>
+            part.toLowerCase() ===
+            search.toLowerCase()),
+    },
+  ],
+});
diff --git a/src/data/composite/things/content/index.js b/src/data/composite/things/content/index.js
new file mode 100644
index 00000000..27bf7c53
--- /dev/null
+++ b/src/data/composite/things/content/index.js
@@ -0,0 +1,4 @@
+export {default as hasAnnotationPart} from './hasAnnotationPart.js';
+export {default as withAnnotationPartNodeLists} from './withAnnotationPartNodeLists.js';
+export {default as withExpressedOrImplicitArtistReferences} from './withExpressedOrImplicitArtistReferences.js';
+export {default as withWebArchiveDate} from './withWebArchiveDate.js';
diff --git a/src/data/composite/things/content/withAnnotationPartNodeLists.js b/src/data/composite/things/content/withAnnotationPartNodeLists.js
new file mode 100644
index 00000000..fc304594
--- /dev/null
+++ b/src/data/composite/things/content/withAnnotationPartNodeLists.js
@@ -0,0 +1,28 @@
+import {input, templateCompositeFrom} from '#composite';
+
+import {raiseOutputWithoutDependency} from '#composite/control-flow';
+import {splitContentNodesAround, withContentNodes} from '#composite/wiki-data';
+
+export default templateCompositeFrom({
+  annotation: `withAnnotationPartNodeLists`,
+
+  outputs: ['#annotationPartNodeLists'],
+
+  steps: () => [
+    raiseOutputWithoutDependency({
+      dependency: 'annotation',
+      output: input.value({'#annotationPartNodeLists': []}),
+    }),
+
+    withContentNodes({
+      from: 'annotation',
+    }),
+
+    splitContentNodesAround({
+      nodes: '#contentNodes',
+      around: input.value(/, */g),
+    }).outputs({
+      '#contentNodeLists': '#annotationPartNodeLists',
+    }),
+  ],
+});
diff --git a/src/data/composite/things/content/withExpressedOrImplicitArtistReferences.js b/src/data/composite/things/content/withExpressedOrImplicitArtistReferences.js
new file mode 100644
index 00000000..69da8c75
--- /dev/null
+++ b/src/data/composite/things/content/withExpressedOrImplicitArtistReferences.js
@@ -0,0 +1,61 @@
+import {input, templateCompositeFrom} from '#composite';
+
+import {raiseOutputWithoutDependency} from '#composite/control-flow';
+import {withFilteredList, withMappedList} from '#composite/data';
+import {withContentNodes} from '#composite/wiki-data';
+
+export default templateCompositeFrom({
+  annotation: `withExpressedOrImplicitArtistReferences`,
+
+  inputs: {
+    from: input({type: 'array', acceptsNull: true}),
+  },
+
+  outputs: ['#artistReferences'],
+
+  steps: () => [
+    {
+      dependencies: [input('from')],
+      compute: (continuation, {
+        [input('from')]: expressedArtistReferences,
+      }) =>
+        (expressedArtistReferences
+          ? continuation.raiseOutput({'#artistReferences': expressedArtistReferences})
+          : continuation()),
+    },
+
+    raiseOutputWithoutDependency({
+      dependency: 'artistText',
+      output: input.value({'#artistReferences': null}),
+    }),
+
+    withContentNodes({
+      from: 'artistText',
+    }),
+
+    withMappedList({
+      list: '#contentNodes',
+      map: input.value(node =>
+        node.type === 'tag' &&
+        node.data.replacerKey?.data === 'artist'),
+    }).outputs({
+      '#mappedList': '#artistTagFilter',
+    }),
+
+    withFilteredList({
+      list: '#contentNodes',
+      filter: '#artistTagFilter',
+    }).outputs({
+      '#filteredList': '#artistTags',
+    }),
+
+    withMappedList({
+      list: '#artistTags',
+      map: input.value(node =>
+        'artist:' +
+        node.data.replacerValue[0].data),
+    }).outputs({
+      '#mappedList': '#artistReferences',
+    }),
+  ],
+});
diff --git a/src/data/composite/things/commentary-entry/withWebArchiveDate.js b/src/data/composite/things/content/withWebArchiveDate.js
index 3aaa4f64..3aaa4f64 100644
--- a/src/data/composite/things/commentary-entry/withWebArchiveDate.js
+++ b/src/data/composite/things/content/withWebArchiveDate.js
diff --git a/src/data/composite/things/contribution/index.js b/src/data/composite/things/contribution/index.js
index 9b22be2e..2bbf994d 100644
--- a/src/data/composite/things/contribution/index.js
+++ b/src/data/composite/things/contribution/index.js
@@ -1,7 +1,3 @@
 export {default as inheritFromContributionPresets} from './inheritFromContributionPresets.js';
-export {default as thingPropertyMatches} from './thingPropertyMatches.js';
-export {default as thingReferenceTypeMatches} from './thingReferenceTypeMatches.js';
 export {default as withContainingReverseContributionList} from './withContainingReverseContributionList.js';
-export {default as withContributionArtist} from './withContributionArtist.js';
 export {default as withContributionContext} from './withContributionContext.js';
-export {default as withMatchingContributionPresets} from './withMatchingContributionPresets.js';
diff --git a/src/data/composite/things/contribution/inheritFromContributionPresets.js b/src/data/composite/things/contribution/inheritFromContributionPresets.js
index a74e6db3..b429b3ef 100644
--- a/src/data/composite/things/contribution/inheritFromContributionPresets.js
+++ b/src/data/composite/things/contribution/inheritFromContributionPresets.js
@@ -3,29 +3,18 @@ import {input, templateCompositeFrom} from '#composite';
 import {raiseOutputWithoutDependency} from '#composite/control-flow';
 import {withPropertyFromList} from '#composite/data';
 
-import withMatchingContributionPresets
-  from './withMatchingContributionPresets.js';
-
 export default templateCompositeFrom({
   annotation: `inheritFromContributionPresets`,
 
-  inputs: {
-    property: input({type: 'string'}),
-  },
-
   steps: () => [
-    withMatchingContributionPresets().outputs({
-      '#matchingContributionPresets': '#presets',
-    }),
-
     raiseOutputWithoutDependency({
-      dependency: '#presets',
+      dependency: 'matchingContributionPresets',
       mode: input.value('empty'),
     }),
 
     withPropertyFromList({
-      list: '#presets',
-      property: input('property'),
+      list: 'matchingContributionPresets',
+      property: input.thisProperty(),
     }),
 
     {
diff --git a/src/data/composite/things/contribution/thingPropertyMatches.js b/src/data/composite/things/contribution/thingPropertyMatches.js
deleted file mode 100644
index 1e9019b8..00000000
--- a/src/data/composite/things/contribution/thingPropertyMatches.js
+++ /dev/null
@@ -1,46 +0,0 @@
-import {input, templateCompositeFrom} from '#composite';
-
-import {exitWithoutDependency} from '#composite/control-flow';
-import {withPropertyFromObject} from '#composite/data';
-
-export default templateCompositeFrom({
-  annotation: `thingPropertyMatches`,
-
-  compose: false,
-
-  inputs: {
-    value: input({type: 'string'}),
-  },
-
-  steps: () => [
-    {
-      dependencies: ['thing', 'thingProperty'],
-
-      compute: (continuation, {thing, thingProperty}) =>
-        continuation({
-          ['#thingProperty']:
-            (thing.constructor[Symbol.for('Thing.referenceType')] === 'artwork'
-              ? thing.artistContribsFromThingProperty
-              : thingProperty),
-        }),
-    },
-
-    exitWithoutDependency({
-      dependency: '#thingProperty',
-      value: input.value(false),
-    }),
-
-    {
-      dependencies: [
-        '#thingProperty',
-        input('value'),
-      ],
-
-      compute: ({
-        ['#thingProperty']: thingProperty,
-        [input('value')]: value,
-      }) =>
-        thingProperty === value,
-    },
-  ],
-});
diff --git a/src/data/composite/things/contribution/thingReferenceTypeMatches.js b/src/data/composite/things/contribution/thingReferenceTypeMatches.js
deleted file mode 100644
index 4042e78f..00000000
--- a/src/data/composite/things/contribution/thingReferenceTypeMatches.js
+++ /dev/null
@@ -1,66 +0,0 @@
-import {input, templateCompositeFrom} from '#composite';
-
-import {exitWithoutDependency} from '#composite/control-flow';
-import {withPropertyFromObject} from '#composite/data';
-
-export default templateCompositeFrom({
-  annotation: `thingReferenceTypeMatches`,
-
-  compose: false,
-
-  inputs: {
-    value: input({type: 'string'}),
-  },
-
-  steps: () => [
-    exitWithoutDependency({
-      dependency: 'thing',
-      value: input.value(false),
-    }),
-
-    withPropertyFromObject({
-      object: 'thing',
-      property: input.value('constructor'),
-    }),
-
-    {
-      dependencies: [
-        '#thing.constructor',
-        input('value'),
-      ],
-
-      compute: (continuation, {
-        ['#thing.constructor']: constructor,
-        [input('value')]: value,
-      }) =>
-        (constructor[Symbol.for('Thing.referenceType')] === value
-          ? continuation.exit(true)
-       : constructor[Symbol.for('Thing.referenceType')] === 'artwork'
-          ? continuation()
-          : continuation.exit(false)),
-    },
-
-    withPropertyFromObject({
-      object: 'thing',
-      property: input.value('thing'),
-    }),
-
-    withPropertyFromObject({
-      object: '#thing.thing',
-      property: input.value('constructor'),
-    }),
-
-    {
-      dependencies: [
-        '#thing.thing.constructor',
-        input('value'),
-      ],
-
-      compute: ({
-        ['#thing.thing.constructor']: constructor,
-        [input('value')]: value,
-      }) =>
-        constructor[Symbol.for('Thing.referenceType')] === value,
-    },
-  ],
-});
diff --git a/src/data/composite/things/contribution/withContainingReverseContributionList.js b/src/data/composite/things/contribution/withContainingReverseContributionList.js
index 175d6cbb..a9ba31c9 100644
--- a/src/data/composite/things/contribution/withContainingReverseContributionList.js
+++ b/src/data/composite/things/contribution/withContainingReverseContributionList.js
@@ -9,14 +9,12 @@ import {raiseOutputWithoutDependency, withResultOfAvailabilityCheck}
   from '#composite/control-flow';
 import {withPropertyFromObject} from '#composite/data';
 
-import withContributionArtist from './withContributionArtist.js';
-
 export default templateCompositeFrom({
   annotation: `withContainingReverseContributionList`,
 
   inputs: {
     artistProperty: input({
-      defaultDependency: 'artistProperty',
+      defaultDependency: '_artistProperty',
       acceptsNull: true,
     }),
   },
@@ -32,10 +30,8 @@ export default templateCompositeFrom({
       }),
     }),
 
-    withContributionArtist(),
-
     withPropertyFromObject({
-      object: '#artist',
+      object: 'artist',
       property: input('artistProperty'),
     }).outputs({
       ['#value']: '#list',
diff --git a/src/data/composite/things/contribution/withContributionArtist.js b/src/data/composite/things/contribution/withContributionArtist.js
deleted file mode 100644
index 5f81c716..00000000
--- a/src/data/composite/things/contribution/withContributionArtist.js
+++ /dev/null
@@ -1,26 +0,0 @@
-import {input, templateCompositeFrom} from '#composite';
-
-import {withResolvedReference} from '#composite/wiki-data';
-import {soupyFind} from '#composite/wiki-properties';
-
-export default templateCompositeFrom({
-  annotation: `withContributionArtist`,
-
-  inputs: {
-    ref: input({
-      type: 'string',
-      defaultDependency: 'artist',
-    }),
-  },
-
-  outputs: ['#artist'],
-
-  steps: () => [
-    withResolvedReference({
-      ref: input('ref'),
-      find: soupyFind.input('artist'),
-    }).outputs({
-      '#resolvedReference': '#artist',
-    }),
-  ],
-});
diff --git a/src/data/composite/things/contribution/withMatchingContributionPresets.js b/src/data/composite/things/contribution/withMatchingContributionPresets.js
deleted file mode 100644
index 09454164..00000000
--- a/src/data/composite/things/contribution/withMatchingContributionPresets.js
+++ /dev/null
@@ -1,70 +0,0 @@
-import {input, templateCompositeFrom} from '#composite';
-
-import {raiseOutputWithoutDependency} from '#composite/control-flow';
-import {withPropertyFromObject} from '#composite/data';
-
-import withContributionContext from './withContributionContext.js';
-
-export default templateCompositeFrom({
-  annotation: `withMatchingContributionPresets`,
-
-  outputs: ['#matchingContributionPresets'],
-
-  steps: () => [
-    withPropertyFromObject({
-      object: 'thing',
-      property: input.value('wikiInfo'),
-      internal: input.value(true),
-    }),
-
-    raiseOutputWithoutDependency({
-      dependency: '#thing.wikiInfo',
-      output: input.value({
-        '#matchingContributionPresets': null,
-      }),
-    }),
-
-    withPropertyFromObject({
-      object: '#thing.wikiInfo',
-      property: input.value('contributionPresets'),
-    }).outputs({
-      '#thing.wikiInfo.contributionPresets': '#contributionPresets',
-    }),
-
-    raiseOutputWithoutDependency({
-      dependency: '#contributionPresets',
-      mode: input.value('empty'),
-      output: input.value({
-        '#matchingContributionPresets': [],
-      }),
-    }),
-
-    withContributionContext(),
-
-    {
-      dependencies: [
-        '#contributionPresets',
-        '#contributionTarget',
-        '#contributionProperty',
-        'annotation',
-      ],
-
-      compute: (continuation, {
-        ['#contributionPresets']: presets,
-        ['#contributionTarget']: target,
-        ['#contributionProperty']: property,
-        ['annotation']: annotation,
-      }) => continuation({
-        ['#matchingContributionPresets']:
-          presets
-            .filter(preset =>
-              preset.context[0] === target &&
-              preset.context.slice(1).includes(property) &&
-              // For now, only match if the annotation is a complete match.
-              // Partial matches (e.g. because the contribution includes "two"
-              // annotations, separated by commas) don't count.
-              preset.annotation === annotation),
-      })
-    },
-  ],
-});
diff --git a/src/data/composite/things/flash-act/index.js b/src/data/composite/things/flash-act/index.js
deleted file mode 100644
index 40fecd2f..00000000
--- a/src/data/composite/things/flash-act/index.js
+++ /dev/null
@@ -1 +0,0 @@
-export {default as withFlashSide} from './withFlashSide.js';
diff --git a/src/data/composite/things/flash-act/withFlashSide.js b/src/data/composite/things/flash-act/withFlashSide.js
deleted file mode 100644
index e09f06e6..00000000
--- a/src/data/composite/things/flash-act/withFlashSide.js
+++ /dev/null
@@ -1,22 +0,0 @@
-// Gets the flash act's side. This will early exit if flashSideData is missing.
-// If there's no side whose list of flash acts includes this act, the output
-// dependency will be null.
-
-import {templateCompositeFrom} from '#composite';
-
-import {withUniqueReferencingThing} from '#composite/wiki-data';
-import {soupyReverse} from '#composite/wiki-properties';
-
-export default templateCompositeFrom({
-  annotation: `withFlashSide`,
-
-  outputs: ['#flashSide'],
-
-  steps: () => [
-    withUniqueReferencingThing({
-      reverse: soupyReverse.input('flashSidesWhoseActsInclude'),
-    }).outputs({
-      ['#uniqueReferencingThing']: '#flashSide',
-    }),
-  ],
-});
diff --git a/src/data/composite/things/flash/index.js b/src/data/composite/things/flash/index.js
deleted file mode 100644
index 63ac13da..00000000
--- a/src/data/composite/things/flash/index.js
+++ /dev/null
@@ -1 +0,0 @@
-export {default as withFlashAct} from './withFlashAct.js';
diff --git a/src/data/composite/things/flash/withFlashAct.js b/src/data/composite/things/flash/withFlashAct.js
deleted file mode 100644
index 87922aff..00000000
--- a/src/data/composite/things/flash/withFlashAct.js
+++ /dev/null
@@ -1,22 +0,0 @@
-// Gets the flash's act. This will early exit if flashActData is missing.
-// If there's no flash whose list of flashes includes this flash, the output
-// dependency will be null.
-
-import {templateCompositeFrom} from '#composite';
-
-import {withUniqueReferencingThing} from '#composite/wiki-data';
-import {soupyReverse} from '#composite/wiki-properties';
-
-export default templateCompositeFrom({
-  annotation: `withFlashAct`,
-
-  outputs: ['#flashAct'],
-
-  steps: () => [
-    withUniqueReferencingThing({
-      reverse: soupyReverse.input('flashActsWhoseFlashesInclude'),
-    }).outputs({
-      ['#uniqueReferencingThing']: '#flashAct',
-    }),
-  ],
-});
diff --git a/src/data/composite/things/track-section/index.js b/src/data/composite/things/track-section/index.js
deleted file mode 100644
index f11a2ab5..00000000
--- a/src/data/composite/things/track-section/index.js
+++ /dev/null
@@ -1,3 +0,0 @@
-export {default as withAlbum} from './withAlbum.js';
-export {default as withContinueCountingFrom} from './withContinueCountingFrom.js';
-export {default as withStartCountingFrom} from './withStartCountingFrom.js';
diff --git a/src/data/composite/things/track-section/withAlbum.js b/src/data/composite/things/track-section/withAlbum.js
deleted file mode 100644
index e257062e..00000000
--- a/src/data/composite/things/track-section/withAlbum.js
+++ /dev/null
@@ -1,20 +0,0 @@
-// Gets the track section's album.
-
-import {templateCompositeFrom} from '#composite';
-
-import {withUniqueReferencingThing} from '#composite/wiki-data';
-import {soupyReverse} from '#composite/wiki-properties';
-
-export default templateCompositeFrom({
-  annotation: `withAlbum`,
-
-  outputs: ['#album'],
-
-  steps: () => [
-    withUniqueReferencingThing({
-      reverse: soupyReverse.input('albumsWhoseTrackSectionsInclude'),
-    }).outputs({
-      ['#uniqueReferencingThing']: '#album',
-    }),
-  ],
-});
diff --git a/src/data/composite/things/track-section/withContinueCountingFrom.js b/src/data/composite/things/track-section/withContinueCountingFrom.js
deleted file mode 100644
index e034b7a5..00000000
--- a/src/data/composite/things/track-section/withContinueCountingFrom.js
+++ /dev/null
@@ -1,25 +0,0 @@
-import {input, templateCompositeFrom} from '#composite';
-
-import withStartCountingFrom from './withStartCountingFrom.js';
-
-export default templateCompositeFrom({
-  annotation: `withContinueCountingFrom`,
-
-  outputs: ['#continueCountingFrom'],
-
-  steps: () => [
-    withStartCountingFrom(),
-
-    {
-      dependencies: ['#startCountingFrom', 'tracks'],
-      compute: (continuation, {
-        ['#startCountingFrom']: startCountingFrom,
-        ['tracks']: tracks,
-      }) => continuation({
-        ['#continueCountingFrom']:
-          startCountingFrom +
-          tracks.length,
-      }),
-    },
-  ],
-});
diff --git a/src/data/composite/things/track-section/withStartCountingFrom.js b/src/data/composite/things/track-section/withStartCountingFrom.js
deleted file mode 100644
index ef345327..00000000
--- a/src/data/composite/things/track-section/withStartCountingFrom.js
+++ /dev/null
@@ -1,64 +0,0 @@
-import {input, templateCompositeFrom} from '#composite';
-
-import {raiseOutputWithoutDependency} from '#composite/control-flow';
-import {withNearbyItemFromList, withPropertyFromObject} from '#composite/data';
-
-import withAlbum from './withAlbum.js';
-
-export default templateCompositeFrom({
-  annotation: `withStartCountingFrom`,
-
-  inputs: {
-    from: input({
-      type: 'number',
-      defaultDependency: 'startCountingFrom',
-      acceptsNull: true,
-    }),
-  },
-
-  outputs: ['#startCountingFrom'],
-
-  steps: () => [
-    {
-      dependencies: [input('from')],
-      compute: (continuation, {
-        [input('from')]: from,
-      }) =>
-        (from === null
-          ? continuation()
-          : continuation.raiseOutput({'#startCountingFrom': from})),
-    },
-
-    withAlbum(),
-
-    raiseOutputWithoutDependency({
-      dependency: '#album',
-      output: input.value({'#startCountingFrom': 1}),
-    }),
-
-    withPropertyFromObject({
-      object: '#album',
-      property: input.value('trackSections'),
-    }),
-
-    withNearbyItemFromList({
-      list: '#album.trackSections',
-      item: input.myself(),
-      offset: input.value(-1),
-    }).outputs({
-      '#nearbyItem': '#previousTrackSection',
-    }),
-
-    raiseOutputWithoutDependency({
-      dependency: '#previousTrackSection',
-      output: input.value({'#startCountingFrom': 1}),
-    }),
-
-    withPropertyFromObject({
-      object: '#previousTrackSection',
-      property: input.value('continueCountingFrom'),
-    }).outputs({
-      '#previousTrackSection.continueCountingFrom': '#startCountingFrom',
-    }),
-  ],
-});
diff --git a/src/data/composite/things/track/exitWithoutUniqueCoverArt.js b/src/data/composite/things/track/exitWithoutUniqueCoverArt.js
deleted file mode 100644
index f47086d9..00000000
--- a/src/data/composite/things/track/exitWithoutUniqueCoverArt.js
+++ /dev/null
@@ -1,26 +0,0 @@
-// Shorthand for checking if the track has unique cover art and exposing a
-// fallback value if it isn't.
-
-import {input, templateCompositeFrom} from '#composite';
-
-import {exitWithoutDependency} from '#composite/control-flow';
-
-import withHasUniqueCoverArt from './withHasUniqueCoverArt.js';
-
-export default templateCompositeFrom({
-  annotation: `exitWithoutUniqueCoverArt`,
-
-  inputs: {
-    value: input({defaultValue: null}),
-  },
-
-  steps: () => [
-    withHasUniqueCoverArt(),
-
-    exitWithoutDependency({
-      dependency: '#hasUniqueCoverArt',
-      mode: input.value('falsy'),
-      value: input('value'),
-    }),
-  ],
-});
diff --git a/src/data/composite/things/track/index.js b/src/data/composite/things/track/index.js
index e789e736..c200df19 100644
--- a/src/data/composite/things/track/index.js
+++ b/src/data/composite/things/track/index.js
@@ -1,17 +1,2 @@
-export {default as exitWithoutUniqueCoverArt} from './exitWithoutUniqueCoverArt.js';
 export {default as inheritContributionListFromMainRelease} from './inheritContributionListFromMainRelease.js';
 export {default as inheritFromMainRelease} from './inheritFromMainRelease.js';
-export {default as withAllReleases} from './withAllReleases.js';
-export {default as withAlwaysReferenceByDirectory} from './withAlwaysReferenceByDirectory.js';
-export {default as withContainingTrackSection} from './withContainingTrackSection.js';
-export {default as withCoverArtistContribs} from './withCoverArtistContribs.js';
-export {default as withDate} from './withDate.js';
-export {default as withDirectorySuffix} from './withDirectorySuffix.js';
-export {default as withHasUniqueCoverArt} from './withHasUniqueCoverArt.js';
-export {default as withMainRelease} from './withMainRelease.js';
-export {default as withOtherReleases} from './withOtherReleases.js';
-export {default as withPropertyFromAlbum} from './withPropertyFromAlbum.js';
-export {default as withPropertyFromMainRelease} from './withPropertyFromMainRelease.js';
-export {default as withSuffixDirectoryFromAlbum} from './withSuffixDirectoryFromAlbum.js';
-export {default as withTrackArtDate} from './withTrackArtDate.js';
-export {default as withTrackNumber} from './withTrackNumber.js';
diff --git a/src/data/composite/things/track/inheritContributionListFromMainRelease.js b/src/data/composite/things/track/inheritContributionListFromMainRelease.js
index 89252feb..8db50060 100644
--- a/src/data/composite/things/track/inheritContributionListFromMainRelease.js
+++ b/src/data/composite/things/track/inheritContributionListFromMainRelease.js
@@ -5,40 +5,37 @@ import {input, templateCompositeFrom} from '#composite';
 
 import {exposeDependency, raiseOutputWithoutDependency}
   from '#composite/control-flow';
+import {withPropertyFromObject} from '#composite/data';
 import {withRecontextualizedContributionList, withRedatedContributionList}
   from '#composite/wiki-data';
 
-import withDate from './withDate.js';
-import withPropertyFromMainRelease
-  from './withPropertyFromMainRelease.js';
-
 export default templateCompositeFrom({
   annotation: `inheritContributionListFromMainRelease`,
 
   steps: () => [
-    withPropertyFromMainRelease({
-      property: input.thisProperty(),
-      notFoundValue: input.value([]),
-    }),
-
     raiseOutputWithoutDependency({
-      dependency: '#isSecondaryRelease',
+      dependency: 'isSecondaryRelease',
       mode: input.value('falsy'),
     }),
 
-    withRecontextualizedContributionList({
-      list: '#mainReleaseValue',
+    withPropertyFromObject({
+      object: 'mainReleaseTrack',
+      property: input.thisProperty(),
+    }).outputs({
+      '#value': '#contributions',
     }),
 
-    withDate(),
+    withRecontextualizedContributionList({
+      list: '#contributions',
+    }),
 
     withRedatedContributionList({
-      list: '#mainReleaseValue',
-      date: '#date',
+      list: '#contributions',
+      date: 'date',
     }),
 
     exposeDependency({
-      dependency: '#mainReleaseValue',
+      dependency: '#contributions',
     }),
   ],
 });
diff --git a/src/data/composite/things/track/inheritFromMainRelease.js b/src/data/composite/things/track/inheritFromMainRelease.js
index b1cbb65e..ca532bc7 100644
--- a/src/data/composite/things/track/inheritFromMainRelease.js
+++ b/src/data/composite/things/track/inheritFromMainRelease.js
@@ -1,41 +1,29 @@
 // Early exits with the value for the same property as specified on the
 // main release, if this track is a secondary release, and otherwise continues
 // without providing any further dependencies.
-//
-// Like withMainRelease, this will early exit (with notFoundValue) if the
-// main release is specified by reference and that reference doesn't
-// resolve to anything.
 
 import {input, templateCompositeFrom} from '#composite';
 
 import {exposeDependency, raiseOutputWithoutDependency}
   from '#composite/control-flow';
-
-import withPropertyFromMainRelease
-  from './withPropertyFromMainRelease.js';
+import {withPropertyFromObject} from '#composite/data';
 
 export default templateCompositeFrom({
   annotation: `inheritFromMainRelease`,
 
-  inputs: {
-    notFoundValue: input({
-      defaultValue: null,
-    }),
-  },
-
   steps: () => [
-    withPropertyFromMainRelease({
-      property: input.thisProperty(),
-      notFoundValue: input('notFoundValue'),
-    }),
-
     raiseOutputWithoutDependency({
-      dependency: '#isSecondaryRelease',
+      dependency: 'isSecondaryRelease',
       mode: input.value('falsy'),
     }),
 
+    withPropertyFromObject({
+      object: 'mainReleaseTrack',
+      property: input.thisProperty(),
+    }),
+
     exposeDependency({
-      dependency: '#mainReleaseValue',
+      dependency: '#value',
     }),
   ],
 });
diff --git a/src/data/composite/things/track/trackAdditionalNameList.js b/src/data/composite/things/track/trackAdditionalNameList.js
deleted file mode 100644
index 65a2263d..00000000
--- a/src/data/composite/things/track/trackAdditionalNameList.js
+++ /dev/null
@@ -1,38 +0,0 @@
-// Compiles additional names from various sources.
-
-import {input, templateCompositeFrom} from '#composite';
-import {isAdditionalNameList} from '#validators';
-
-import withInferredAdditionalNames from './withInferredAdditionalNames.js';
-import withSharedAdditionalNames from './withSharedAdditionalNames.js';
-
-export default templateCompositeFrom({
-  annotation: `trackAdditionalNameList`,
-
-  compose: false,
-
-  update: {validate: isAdditionalNameList},
-
-  steps: () => [
-    withInferredAdditionalNames(),
-    withSharedAdditionalNames(),
-
-    {
-      dependencies: [
-        '#inferredAdditionalNames',
-        '#sharedAdditionalNames',
-        input.updateValue(),
-      ],
-
-      compute: ({
-        ['#inferredAdditionalNames']: inferredAdditionalNames,
-        ['#sharedAdditionalNames']: sharedAdditionalNames,
-        [input.updateValue()]: providedAdditionalNames,
-      }) => [
-        ...providedAdditionalNames ?? [],
-        ...sharedAdditionalNames,
-        ...inferredAdditionalNames,
-      ],
-    },
-  ],
-});
diff --git a/src/data/composite/things/track/withAllReleases.js b/src/data/composite/things/track/withAllReleases.js
deleted file mode 100644
index b93bf753..00000000
--- a/src/data/composite/things/track/withAllReleases.js
+++ /dev/null
@@ -1,47 +0,0 @@
-// Gets all releases of the current track. All items of the outputs are
-// distinct Track objects; one track is the main release; all else are
-// secondary releases of that main release; and one item, which may be
-// the main release or one of the secondary releases, is the current
-// track. The results are sorted by date, and it is possible that the
-// main release is not actually the earliest/first.
-
-import {input, templateCompositeFrom} from '#composite';
-import {sortByDate} from '#sort';
-
-import {exitWithoutDependency} from '#composite/control-flow';
-import {withPropertyFromObject} from '#composite/data';
-
-import withMainRelease from './withMainRelease.js';
-
-export default templateCompositeFrom({
-  annotation: `withAllReleases`,
-
-  outputs: ['#allReleases'],
-
-  steps: () => [
-    withMainRelease({
-      selfIfMain: input.value(true),
-      notFoundValue: input.value([]),
-    }),
-
-    // We don't talk about bruno no no
-    // Yes, this can perform a normal access equivalent to
-    // `this.secondaryReleases` from within a data composition.
-    // Oooooooooooooooooooooooooooooooooooooooooooooooo
-    withPropertyFromObject({
-      object: '#mainRelease',
-      property: input.value('secondaryReleases'),
-    }),
-
-    {
-      dependencies: ['#mainRelease', '#mainRelease.secondaryReleases'],
-      compute: (continuation, {
-        ['#mainRelease']: mainRelease,
-        ['#mainRelease.secondaryReleases']: secondaryReleases,
-      }) => continuation({
-        ['#allReleases']:
-          sortByDate([mainRelease, ...secondaryReleases]),
-      }),
-    },
-  ],
-});
diff --git a/src/data/composite/things/track/withAlwaysReferenceByDirectory.js b/src/data/composite/things/track/withAlwaysReferenceByDirectory.js
deleted file mode 100644
index 60faeaf4..00000000
--- a/src/data/composite/things/track/withAlwaysReferenceByDirectory.js
+++ /dev/null
@@ -1,97 +0,0 @@
-// Controls how find.track works - it'll never be matched by a reference
-// just to the track's name, which means you don't have to always reference
-// some *other* (much more commonly referenced) track by directory instead
-// of more naturally by name.
-
-import {input, templateCompositeFrom} from '#composite';
-import find from '#find';
-import {isBoolean} from '#validators';
-
-import {withPropertyFromObject} from '#composite/data';
-import {withResolvedReference} from '#composite/wiki-data';
-import {soupyFind} from '#composite/wiki-properties';
-
-import {
-  exitWithoutDependency,
-  exposeDependencyOrContinue,
-  exposeUpdateValueOrContinue,
-} from '#composite/control-flow';
-
-import withPropertyFromAlbum from './withPropertyFromAlbum.js';
-
-export default templateCompositeFrom({
-  annotation: `withAlwaysReferenceByDirectory`,
-
-  outputs: ['#alwaysReferenceByDirectory'],
-
-  steps: () => [
-    exposeUpdateValueOrContinue({
-      validate: input.value(isBoolean),
-    }),
-
-    withPropertyFromAlbum({
-      property: input.value('alwaysReferenceTracksByDirectory'),
-    }),
-
-    // Falsy mode means this exposes true if the album's property is true,
-    // but continues if the property is false (which is also the default).
-    exposeDependencyOrContinue({
-      dependency: '#album.alwaysReferenceTracksByDirectory',
-      mode: input.value('falsy'),
-    }),
-
-    // Remaining code is for defaulting to true if this track is a rerelease of
-    // another with the same name, so everything further depends on access to
-    // trackData as well as mainReleaseTrack.
-
-    exitWithoutDependency({
-      dependency: 'trackData',
-      mode: input.value('empty'),
-      value: input.value(false),
-    }),
-
-    exitWithoutDependency({
-      dependency: 'mainReleaseTrack',
-      value: input.value(false),
-    }),
-
-    // It's necessary to use the custom trackMainReleasesOnly find function
-    // here, so as to avoid recursion issues - the find.track() function depends
-    // on accessing each track's alwaysReferenceByDirectory, which means it'll
-    // hit *this track* - and thus this step - and end up recursing infinitely.
-    // By definition, find.trackMainReleasesOnly excludes tracks which have
-    // an mainReleaseTrack update value set, which means even though it does
-    // still access each of tracks' `alwaysReferenceByDirectory` property, it
-    // won't access that of *this* track - it will never proceed past the
-    // `exitWithoutDependency` step directly above, so there's no opportunity
-    // for recursion.
-    withResolvedReference({
-      ref: 'mainReleaseTrack',
-      data: 'trackData',
-      find: input.value(find.trackMainReleasesOnly),
-    }).outputs({
-      '#resolvedReference': '#mainRelease',
-    }),
-
-    exitWithoutDependency({
-      dependency: '#mainRelease',
-      value: input.value(false),
-    }),
-
-    withPropertyFromObject({
-      object: '#mainRelease',
-      property: input.value('name'),
-    }),
-
-    {
-      dependencies: ['name', '#mainRelease.name'],
-      compute: (continuation, {
-        name,
-        ['#mainRelease.name']: mainReleaseName,
-      }) => continuation({
-        ['#alwaysReferenceByDirectory']:
-          name === mainReleaseName,
-      }),
-    },
-  ],
-});
diff --git a/src/data/composite/things/track/withContainingTrackSection.js b/src/data/composite/things/track/withContainingTrackSection.js
deleted file mode 100644
index 3d4d081e..00000000
--- a/src/data/composite/things/track/withContainingTrackSection.js
+++ /dev/null
@@ -1,20 +0,0 @@
-// Gets the track section containing this track from its album's track list.
-
-import {templateCompositeFrom} from '#composite';
-
-import {withUniqueReferencingThing} from '#composite/wiki-data';
-import {soupyReverse} from '#composite/wiki-properties';
-
-export default templateCompositeFrom({
-  annotation: `withContainingTrackSection`,
-
-  outputs: ['#trackSection'],
-
-  steps: () => [
-    withUniqueReferencingThing({
-      reverse: soupyReverse.input('trackSectionsWhichInclude'),
-    }).outputs({
-      ['#uniqueReferencingThing']: '#trackSection',
-    }),
-  ],
-});
diff --git a/src/data/composite/things/track/withCoverArtistContribs.js b/src/data/composite/things/track/withCoverArtistContribs.js
deleted file mode 100644
index 9057cfeb..00000000
--- a/src/data/composite/things/track/withCoverArtistContribs.js
+++ /dev/null
@@ -1,73 +0,0 @@
-import {input, templateCompositeFrom} from '#composite';
-import {isContributionList} from '#validators';
-
-import {exposeDependencyOrContinue} from '#composite/control-flow';
-
-import {
-  withRecontextualizedContributionList,
-  withRedatedContributionList,
-  withResolvedContribs,
-} from '#composite/wiki-data';
-
-import exitWithoutUniqueCoverArt from './exitWithoutUniqueCoverArt.js';
-import withPropertyFromAlbum from './withPropertyFromAlbum.js';
-import withTrackArtDate from './withTrackArtDate.js';
-
-export default templateCompositeFrom({
-  annotation: `withCoverArtistContribs`,
-
-  inputs: {
-    from: input({
-      defaultDependency: 'coverArtistContribs',
-      validate: isContributionList,
-      acceptsNull: true,
-    }),
-  },
-
-  outputs: ['#coverArtistContribs'],
-
-  steps: () => [
-    exitWithoutUniqueCoverArt({
-      value: input.value([]),
-    }),
-
-    withTrackArtDate(),
-
-    withResolvedContribs({
-      from: input('from'),
-      thingProperty: input.value('coverArtistContribs'),
-      artistProperty: input.value('trackCoverArtistContributions'),
-      date: '#trackArtDate',
-    }).outputs({
-      '#resolvedContribs': '#coverArtistContribs',
-    }),
-
-    exposeDependencyOrContinue({
-      dependency: '#coverArtistContribs',
-      mode: input.value('empty'),
-    }),
-
-    withPropertyFromAlbum({
-      property: input.value('trackCoverArtistContribs'),
-    }),
-
-    withRecontextualizedContributionList({
-      list: '#album.trackCoverArtistContribs',
-      artistProperty: input.value('trackCoverArtistContributions'),
-    }),
-
-    withRedatedContributionList({
-      list: '#album.trackCoverArtistContribs',
-      date: '#trackArtDate',
-    }),
-
-    {
-      dependencies: ['#album.trackCoverArtistContribs'],
-      compute: (continuation, {
-        ['#album.trackCoverArtistContribs']: coverArtistContribs,
-      }) => continuation({
-        ['#coverArtistContribs']: coverArtistContribs,
-      }),
-    },
-  ],
-});
diff --git a/src/data/composite/things/track/withDate.js b/src/data/composite/things/track/withDate.js
deleted file mode 100644
index b5a770e9..00000000
--- a/src/data/composite/things/track/withDate.js
+++ /dev/null
@@ -1,34 +0,0 @@
-// Gets the track's own date. This is either its dateFirstReleased property
-// or, if unset, the album's date.
-
-import {input, templateCompositeFrom} from '#composite';
-
-import withPropertyFromAlbum from './withPropertyFromAlbum.js';
-
-export default templateCompositeFrom({
-  annotation: `withDate`,
-
-  outputs: ['#date'],
-
-  steps: () => [
-    {
-      dependencies: ['dateFirstReleased'],
-      compute: (continuation, {dateFirstReleased}) =>
-        (dateFirstReleased
-          ? continuation.raiseOutput({'#date': dateFirstReleased})
-          : continuation()),
-    },
-
-    withPropertyFromAlbum({
-      property: input.value('date'),
-    }),
-
-    {
-      dependencies: ['#album.date'],
-      compute: (continuation, {['#album.date']: albumDate}) =>
-        (albumDate
-          ? continuation.raiseOutput({'#date': albumDate})
-          : continuation.raiseOutput({'#date': null})),
-    },
-  ],
-})
diff --git a/src/data/composite/things/track/withDirectorySuffix.js b/src/data/composite/things/track/withDirectorySuffix.js
deleted file mode 100644
index c063e158..00000000
--- a/src/data/composite/things/track/withDirectorySuffix.js
+++ /dev/null
@@ -1,36 +0,0 @@
-import {input, templateCompositeFrom} from '#composite';
-
-import {raiseOutputWithoutDependency} from '#composite/control-flow';
-
-import withPropertyFromAlbum from './withPropertyFromAlbum.js';
-import withSuffixDirectoryFromAlbum from './withSuffixDirectoryFromAlbum.js';
-
-export default templateCompositeFrom({
-  annotation: `withDirectorySuffix`,
-
-  outputs: ['#directorySuffix'],
-
-  steps: () => [
-    withSuffixDirectoryFromAlbum(),
-
-    raiseOutputWithoutDependency({
-      dependency: '#suffixDirectoryFromAlbum',
-      mode: input.value('falsy'),
-      output: input.value({['#directorySuffix']: null}),
-    }),
-
-    withPropertyFromAlbum({
-      property: input.value('directorySuffix'),
-    }),
-
-    {
-      dependencies: ['#album.directorySuffix'],
-      compute: (continuation, {
-        ['#album.directorySuffix']: directorySuffix,
-      }) => continuation({
-        ['#directorySuffix']:
-          directorySuffix,
-      }),
-    },
-  ],
-});
diff --git a/src/data/composite/things/track/withHasUniqueCoverArt.js b/src/data/composite/things/track/withHasUniqueCoverArt.js
deleted file mode 100644
index 85d3b92a..00000000
--- a/src/data/composite/things/track/withHasUniqueCoverArt.js
+++ /dev/null
@@ -1,108 +0,0 @@
-// Whether or not the track has "unique" cover artwork - a cover which is
-// specifically associated with this track in particular, rather than with
-// the track's album as a whole. This is typically used to select between
-// displaying the track artwork and a fallback, such as the album artwork
-// or a placeholder. (This property is named hasUniqueCoverArt instead of
-// the usual hasCoverArt to emphasize that it does not inherit from the
-// album.)
-//
-// withHasUniqueCoverArt is based only around the presence of *specified*
-// cover artist contributions, not whether the references to artists on those
-// contributions actually resolve to anything. It completely evades interacting
-// with find/replace.
-
-import {input, templateCompositeFrom} from '#composite';
-
-import {raiseOutputWithoutDependency, withResultOfAvailabilityCheck}
-  from '#composite/control-flow';
-import {fillMissingListItems, withFlattenedList, withPropertyFromList}
-  from '#composite/data';
-
-import withPropertyFromAlbum from './withPropertyFromAlbum.js';
-
-export default templateCompositeFrom({
-  annotation: 'withHasUniqueCoverArt',
-
-  outputs: ['#hasUniqueCoverArt'],
-
-  steps: () => [
-    {
-      dependencies: ['disableUniqueCoverArt'],
-      compute: (continuation, {disableUniqueCoverArt}) =>
-        (disableUniqueCoverArt
-          ? continuation.raiseOutput({
-              ['#hasUniqueCoverArt']: false,
-            })
-          : continuation()),
-    },
-
-    withResultOfAvailabilityCheck({
-      from: 'coverArtistContribs',
-      mode: input.value('empty'),
-    }),
-
-    {
-      dependencies: ['#availability'],
-      compute: (continuation, {
-        ['#availability']: availability,
-      }) =>
-        (availability
-          ? continuation.raiseOutput({
-              ['#hasUniqueCoverArt']: true,
-            })
-          : continuation()),
-    },
-
-    withPropertyFromAlbum({
-      property: input.value('trackCoverArtistContribs'),
-      internal: input.value(true),
-    }),
-
-    withResultOfAvailabilityCheck({
-      from: '#album.trackCoverArtistContribs',
-      mode: input.value('empty'),
-    }),
-
-    {
-      dependencies: ['#availability'],
-      compute: (continuation, {
-        ['#availability']: availability,
-      }) =>
-        (availability
-          ? continuation.raiseOutput({
-              ['#hasUniqueCoverArt']: true,
-            })
-          : continuation()),
-    },
-
-    raiseOutputWithoutDependency({
-      dependency: 'trackArtworks',
-      mode: input.value('empty'),
-      output: input.value({'#hasUniqueCoverArt': false}),
-    }),
-
-    withPropertyFromList({
-      list: 'trackArtworks',
-      property: input.value('artistContribs'),
-      internal: input.value(true),
-    }),
-
-    // Since we're getting the update value for each artwork's artistContribs,
-    // it may not be set at all, and in that case won't be exposing as [].
-    fillMissingListItems({
-      list: '#trackArtworks.artistContribs',
-      fill: input.value([]),
-    }),
-
-    withFlattenedList({
-      list: '#trackArtworks.artistContribs',
-    }),
-
-    withResultOfAvailabilityCheck({
-      from: '#flattenedList',
-      mode: input.value('empty'),
-    }).outputs({
-      '#availability': '#hasUniqueCoverArt',
-    }),
-  ],
-});
diff --git a/src/data/composite/things/track/withMainRelease.js b/src/data/composite/things/track/withMainRelease.js
deleted file mode 100644
index 3a91edae..00000000
--- a/src/data/composite/things/track/withMainRelease.js
+++ /dev/null
@@ -1,70 +0,0 @@
-// Just includes the main release of this track as a dependency.
-// If this track isn't a secondary release, then it'll provide null, unless
-// the {selfIfMain} option is set, in which case it'll provide this track
-// itself. This will early exit (with notFoundValue) if the main release
-// is specified by reference and that reference doesn't resolve to anything.
-
-import {input, templateCompositeFrom} from '#composite';
-
-import {exitWithoutDependency, withResultOfAvailabilityCheck}
-  from '#composite/control-flow';
-import {withResolvedReference} from '#composite/wiki-data';
-import {soupyFind} from '#composite/wiki-properties';
-
-export default templateCompositeFrom({
-  annotation: `withMainRelease`,
-
-  inputs: {
-    selfIfMain: input({type: 'boolean', defaultValue: false}),
-    notFoundValue: input({defaultValue: null}),
-  },
-
-  outputs: ['#mainRelease'],
-
-  steps: () => [
-    withResultOfAvailabilityCheck({
-      from: 'mainReleaseTrack',
-    }),
-
-    {
-      dependencies: [
-        input.myself(),
-        input('selfIfMain'),
-        '#availability',
-      ],
-
-      compute: (continuation, {
-        [input.myself()]: track,
-        [input('selfIfMain')]: selfIfMain,
-        '#availability': availability,
-      }) =>
-        (availability
-          ? continuation()
-          : continuation.raiseOutput({
-              ['#mainRelease']:
-                (selfIfMain ? track : null),
-            })),
-    },
-
-    withResolvedReference({
-      ref: 'mainReleaseTrack',
-      find: soupyFind.input('track'),
-    }),
-
-    exitWithoutDependency({
-      dependency: '#resolvedReference',
-      value: input('notFoundValue'),
-    }),
-
-    {
-      dependencies: ['#resolvedReference'],
-
-      compute: (continuation, {
-        ['#resolvedReference']: resolvedReference,
-      }) =>
-        continuation({
-          ['#mainRelease']: resolvedReference,
-        }),
-    },
-  ],
-});
diff --git a/src/data/composite/things/track/withOtherReleases.js b/src/data/composite/things/track/withOtherReleases.js
deleted file mode 100644
index 0639742f..00000000
--- a/src/data/composite/things/track/withOtherReleases.js
+++ /dev/null
@@ -1,30 +0,0 @@
-// Gets all releases of the current track *except* this track itself;
-// in other words, all other releases of the current track.
-
-import {input, templateCompositeFrom} from '#composite';
-
-import {exitWithoutDependency} from '#composite/control-flow';
-import {withPropertyFromObject} from '#composite/data';
-
-import withAllReleases from './withAllReleases.js';
-
-export default templateCompositeFrom({
-  annotation: `withOtherReleases`,
-
-  outputs: ['#otherReleases'],
-
-  steps: () => [
-    withAllReleases(),
-
-    {
-      dependencies: [input.myself(), '#allReleases'],
-      compute: (continuation, {
-        [input.myself()]: thisTrack,
-        ['#allReleases']: allReleases,
-      }) => continuation({
-        ['#otherReleases']:
-          allReleases.filter(track => track !== thisTrack),
-      }),
-    },
-  ],
-});
diff --git a/src/data/composite/things/track/withPropertyFromAlbum.js b/src/data/composite/things/track/withPropertyFromAlbum.js
deleted file mode 100644
index a203c2e7..00000000
--- a/src/data/composite/things/track/withPropertyFromAlbum.js
+++ /dev/null
@@ -1,48 +0,0 @@
-// Gets a single property from this track's album, providing it as the same
-// property name prefixed with '#album.' (by default).
-
-import {input, templateCompositeFrom} from '#composite';
-
-import {withPropertyFromObject} from '#composite/data';
-
-export default templateCompositeFrom({
-  annotation: `withPropertyFromAlbum`,
-
-  inputs: {
-    property: input.staticValue({type: 'string'}),
-    internal: input({type: 'boolean', defaultValue: false}),
-  },
-
-  outputs: ({
-    [input.staticValue('property')]: property,
-  }) => ['#album.' + property],
-
-  steps: () => [
-    // XXX: This is a ridiculous hack considering `defaultValue` above.
-    // If we were certain what was up, we'd just get around to fixing it LOL
-    {
-      dependencies: [input('internal')],
-      compute: (continuation, {
-        [input('internal')]: internal,
-      }) => continuation({
-        ['#internal']: internal ?? false,
-      }),
-    },
-
-    withPropertyFromObject({
-      object: 'album',
-      property: input('property'),
-      internal: '#internal',
-    }),
-
-    {
-      dependencies: ['#value', input.staticValue('property')],
-      compute: (continuation, {
-        ['#value']: value,
-        [input.staticValue('property')]: property,
-      }) => continuation({
-        ['#album.' + property]: value,
-      }),
-    },
-  ],
-});
diff --git a/src/data/composite/things/track/withPropertyFromMainRelease.js b/src/data/composite/things/track/withPropertyFromMainRelease.js
deleted file mode 100644
index 393a4c63..00000000
--- a/src/data/composite/things/track/withPropertyFromMainRelease.js
+++ /dev/null
@@ -1,86 +0,0 @@
-// Provides a value inherited from the main release, if applicable, and a
-// flag indicating if this track is a secondary release or not.
-//
-// Like withMainRelease, this will early exit (with notFoundValue) if the
-// main release is specified by reference and that reference doesn't
-// resolve to anything.
-
-import {input, templateCompositeFrom} from '#composite';
-
-import {withResultOfAvailabilityCheck} from '#composite/control-flow';
-import {withPropertyFromObject} from '#composite/data';
-
-import withMainRelease from './withMainRelease.js';
-
-export default templateCompositeFrom({
-  annotation: `inheritFromMainRelease`,
-
-  inputs: {
-    property: input({type: 'string'}),
-
-    notFoundValue: input({
-      defaultValue: null,
-    }),
-  },
-
-  outputs: ({
-    [input.staticValue('property')]: property,
-  }) =>
-    ['#isSecondaryRelease'].concat(
-      (property
-        ? ['#mainRelease.' + property]
-        : ['#mainReleaseValue'])),
-
-  steps: () => [
-    withMainRelease({
-      notFoundValue: input('notFoundValue'),
-    }),
-
-    withResultOfAvailabilityCheck({
-      from: '#mainRelease',
-    }),
-
-    {
-      dependencies: [
-        '#availability',
-        input.staticValue('property'),
-      ],
-
-      compute: (continuation, {
-        ['#availability']: availability,
-        [input.staticValue('property')]: property,
-      }) =>
-        (availability
-          ? continuation()
-          : continuation.raiseOutput(
-              Object.assign(
-                {'#isSecondaryRelease': false},
-                (property
-                  ? {['#mainRelease.' + property]: null}
-                  : {'#mainReleaseValue': null})))),
-    },
-
-    withPropertyFromObject({
-      object: '#mainRelease',
-      property: input('property'),
-    }),
-
-    {
-      dependencies: [
-        '#value',
-        input.staticValue('property'),
-      ],
-
-      compute: (continuation, {
-        ['#value']: value,
-        [input.staticValue('property')]: property,
-      }) =>
-        continuation.raiseOutput(
-          Object.assign(
-            {'#isSecondaryRelease': true},
-            (property
-              ? {['#mainRelease.' + property]: value}
-              : {'#mainReleaseValue': value}))),
-    },
-  ],
-});
diff --git a/src/data/composite/things/track/withSuffixDirectoryFromAlbum.js b/src/data/composite/things/track/withSuffixDirectoryFromAlbum.js
deleted file mode 100644
index 7159a3f4..00000000
--- a/src/data/composite/things/track/withSuffixDirectoryFromAlbum.js
+++ /dev/null
@@ -1,53 +0,0 @@
-import {input, templateCompositeFrom} from '#composite';
-
-import {withResultOfAvailabilityCheck} from '#composite/control-flow';
-
-import withPropertyFromAlbum from './withPropertyFromAlbum.js';
-
-export default templateCompositeFrom({
-  annotation: `withSuffixDirectoryFromAlbum`,
-
-  inputs: {
-    flagValue: input({
-      defaultDependency: 'suffixDirectoryFromAlbum',
-      acceptsNull: true,
-    }),
-  },
-
-  outputs: ['#suffixDirectoryFromAlbum'],
-
-  steps: () => [
-    withResultOfAvailabilityCheck({
-      from: 'suffixDirectoryFromAlbum',
-    }),
-
-    {
-      dependencies: [
-        '#availability',
-        'suffixDirectoryFromAlbum'
-      ],
-
-      compute: (continuation, {
-        ['#availability']: availability,
-        ['suffixDirectoryFromAlbum']: flagValue,
-      }) =>
-        (availability
-          ? continuation.raiseOutput({['#suffixDirectoryFromAlbum']: flagValue})
-          : continuation()),
-    },
-
-    withPropertyFromAlbum({
-      property: input.value('suffixTrackDirectories'),
-    }),
-
-    {
-      dependencies: ['#album.suffixTrackDirectories'],
-      compute: (continuation, {
-        ['#album.suffixTrackDirectories']: suffixTrackDirectories,
-      }) => continuation({
-        ['#suffixDirectoryFromAlbum']:
-          suffixTrackDirectories,
-      }),
-    },
-  ],
-});
diff --git a/src/data/composite/things/track/withTrackArtDate.js b/src/data/composite/things/track/withTrackArtDate.js
deleted file mode 100644
index 9b7b61c7..00000000
--- a/src/data/composite/things/track/withTrackArtDate.js
+++ /dev/null
@@ -1,60 +0,0 @@
-import {input, templateCompositeFrom} from '#composite';
-import {isDate} from '#validators';
-
-import {raiseOutputWithoutDependency} from '#composite/control-flow';
-
-import withDate from './withDate.js';
-import withHasUniqueCoverArt from './withHasUniqueCoverArt.js';
-import withPropertyFromAlbum from './withPropertyFromAlbum.js';
-
-export default templateCompositeFrom({
-  annotation: `withTrackArtDate`,
-
-  inputs: {
-    from: input({
-      validate: isDate,
-      defaultDependency: 'coverArtDate',
-      acceptsNull: true,
-    }),
-  },
-
-  outputs: ['#trackArtDate'],
-
-  steps: () => [
-    withHasUniqueCoverArt(),
-
-    raiseOutputWithoutDependency({
-      dependency: '#hasUniqueCoverArt',
-      mode: input.value('falsy'),
-      output: input.value({'#trackArtDate': null}),
-    }),
-
-    {
-      dependencies: [input('from')],
-      compute: (continuation, {
-        [input('from')]: from,
-      }) =>
-        (from
-          ? continuation.raiseOutput({'#trackArtDate': from})
-          : continuation()),
-    },
-
-    withPropertyFromAlbum({
-      property: input.value('trackArtDate'),
-    }),
-
-    {
-      dependencies: ['#album.trackArtDate'],
-      compute: (continuation, {
-        ['#album.trackArtDate']: albumTrackArtDate,
-      }) =>
-        (albumTrackArtDate
-          ? continuation.raiseOutput({'#trackArtDate': albumTrackArtDate})
-          : continuation()),
-    },
-
-    withDate().outputs({
-      '#date': '#trackArtDate',
-    }),
-  ],
-});
diff --git a/src/data/composite/things/track/withTrackNumber.js b/src/data/composite/things/track/withTrackNumber.js
deleted file mode 100644
index 61428e8c..00000000
--- a/src/data/composite/things/track/withTrackNumber.js
+++ /dev/null
@@ -1,50 +0,0 @@
-import {input, templateCompositeFrom} from '#composite';
-
-import {raiseOutputWithoutDependency} from '#composite/control-flow';
-import {withIndexInList, withPropertiesFromObject} from '#composite/data';
-
-import withContainingTrackSection from './withContainingTrackSection.js';
-
-export default templateCompositeFrom({
-  annotation: `withTrackNumber`,
-
-  outputs: ['#trackNumber'],
-
-  steps: () => [
-    withContainingTrackSection(),
-
-    // Zero is the fallback, not one, but in most albums the first track
-    // (and its intended output by this composition) will be one.
-    raiseOutputWithoutDependency({
-      dependency: '#trackSection',
-      output: input.value({'#trackNumber': 0}),
-    }),
-
-    withPropertiesFromObject({
-      object: '#trackSection',
-      properties: input.value(['tracks', 'startCountingFrom']),
-    }),
-
-    withIndexInList({
-      list: '#trackSection.tracks',
-      item: input.myself(),
-    }),
-
-    raiseOutputWithoutDependency({
-      dependency: '#index',
-      output: input.value({'#trackNumber': 0}),
-    }),
-
-    {
-      dependencies: ['#trackSection.startCountingFrom', '#index'],
-      compute: (continuation, {
-        ['#trackSection.startCountingFrom']: startCountingFrom,
-        ['#index']: index,
-      }) => continuation({
-        ['#trackNumber']:
-          startCountingFrom +
-          index,
-      }),
-    },
-  ],
-});