@kieransimkin/dancemoves 3.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +338 -0
- package/README.md +893 -0
- package/RUDIMENTS-API.md +394 -0
- package/docs/README.md +73 -0
- package/docs/api/adapters.md +400 -0
- package/docs/api/downloads.md +158 -0
- package/docs/api/effects.md +463 -0
- package/docs/api/javascript.md +500 -0
- package/docs/api/paper-planes.md +167 -0
- package/docs/api/styling.md +292 -0
- package/docs/api/surface.json +446 -0
- package/docs/api/wordpress.md +365 -0
- package/docs/clay-transform-validation.md +84 -0
- package/docs/development.md +254 -0
- package/docs/guide.md +288 -0
- package/docs/javascript-api.md +292 -0
- package/docs/javascript-server.md +150 -0
- package/docs/react-next.md +185 -0
- package/docs/releasing-shared.md +162 -0
- package/docs/rudiments-source-integrity.md +80 -0
- package/docs/shared-feature-coverage.md +34 -0
- package/docs/shared-runtime-migration.md +111 -0
- package/docs/source-audit.md +120 -0
- package/docs/validation-setup.md +102 -0
- package/docs/wordpress-examples.md +206 -0
- package/docs/wordpress-shared-runtime.md +133 -0
- package/lib/admin.min.js +1 -0
- package/lib/assets/DanceRudiments-LICENSE +21 -0
- package/lib/assets/DanceRudiments-build-manifest.json +21 -0
- package/lib/assets/paper-dreams-plane-atlas.png +0 -0
- package/lib/build-manifest.json +117 -0
- package/lib/dancemoves.css +9 -0
- package/lib/dancemoves.min.js +5 -0
- package/lib/index.cjs +4802 -0
- package/lib/index.d.ts +71 -0
- package/lib/index.mjs +4780 -0
- package/lib/react.cjs +154 -0
- package/lib/react.d.ts +12 -0
- package/lib/react.mjs +135 -0
- package/lib/rudiments.d.ts +124 -0
- package/lib/server.cjs +411 -0
- package/lib/server.d.ts +11 -0
- package/lib/server.mjs +367 -0
- package/lib/styles/clay-stars-effects.css +1 -0
- package/lib/styles/clay-stars-rudiments.css +1 -0
- package/lib/styles/dance-moves-core.css +1 -0
- package/lib/styles/ks-epk-device-orientation.css +1 -0
- package/lib/styles/paper-dreams-flight.css +1 -0
- package/lib/wordpress.js +5 -0
- package/package.json +101 -0
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
# Development, validation and operations
|
|
2
|
+
|
|
3
|
+
[Documentation index](README.md) · [Source audit](source-audit.md)
|
|
4
|
+
|
|
5
|
+
This guide describes the checked-in 2.8.0 tools, not a claim that a particular
|
|
6
|
+
machine, deployment or physical device has passed them. The authoritative
|
|
7
|
+
publication requirements remain [TEST-PLAN.md](../TEST-PLAN.md). The
|
|
8
|
+
[HARNESS-IMPLEMENTATION-PLAN.md](../HARNESS-IMPLEMENTATION-PLAN.md) contains planned
|
|
9
|
+
and staged work; its existence does not make every proposed feature a production
|
|
10
|
+
API or an implemented test command.
|
|
11
|
+
|
|
12
|
+
## Repository layout
|
|
13
|
+
|
|
14
|
+
| Path | Role |
|
|
15
|
+
| --- | --- |
|
|
16
|
+
| `kieran-epk-device-orientation.php` | Plugin identity, page configuration, editor UI, REST capture, signed downloads and content transforms. |
|
|
17
|
+
| `assets/` | Production timing, catalogue, orientation, shared effects, paper-plane sprites, Clay/Stars and admin assets. |
|
|
18
|
+
| `docs/` | User guide and source-audited API reference. |
|
|
19
|
+
| `tests/` | Node contracts, PHP transform checks, integration fixtures and mobile capture/conformance utilities. |
|
|
20
|
+
| `tests/harness/plugin-core/` | Shared local harness assets/contracts. |
|
|
21
|
+
| `tests/harness/clay-stars/`, `tests/harness/california-screamin/` | Release-specific harness configurations. |
|
|
22
|
+
| `tools/` | Validation, preview building, read-only audits and packaging utilities. |
|
|
23
|
+
| `migration/`, `qa/` | Staged migration data and dated evidence. Do not interpret a historical result as approval for a new artifact. |
|
|
24
|
+
| `dist/` | Versioned WordPress ZIPs and manifests. These are not automatically regenerated by documentation edits. |
|
|
25
|
+
|
|
26
|
+
## Normal unit validation
|
|
27
|
+
|
|
28
|
+
The existing coordinator is [tools/validate.ps1](../tools/validate.ps1), with:
|
|
29
|
+
|
|
30
|
+
| Argument | Meaning |
|
|
31
|
+
| --- | --- |
|
|
32
|
+
| `-Mode Unit` | Default. Lint, contracts, encoding, transforms and scaffold checks, without rebuilding migration/package artifacts. |
|
|
33
|
+
| `-Mode Package` | Explicitly rebuild migration and distribution artifacts and check package identity/layout. |
|
|
34
|
+
| `-Mode All` | Run Unit, then Package. This is not a read-only documentation check. |
|
|
35
|
+
| `-ReleasesRoot` | Optional release-workspace root forwarded to the migration builder in Package/All mode. Unit mode does not need it. |
|
|
36
|
+
| `-IncludeFailureFixture` | Deliberately exercise a syntax failure; valid only when Unit runs. Not a normal passing test run. |
|
|
37
|
+
|
|
38
|
+
The scripts assume the repository's Windows/PowerShell workflow, with `php`,
|
|
39
|
+
`node` and `python` on PATH. The source does not declare a definitive minimum
|
|
40
|
+
version matrix for these tools or for WordPress/PHP. Record actual versions used
|
|
41
|
+
rather than inventing a support guarantee. In particular, Package mode invokes
|
|
42
|
+
`powershell` explicitly and some paths/exclusions are Windows-specific.
|
|
43
|
+
|
|
44
|
+
```powershell
|
|
45
|
+
powershell -NoProfile -ExecutionPolicy Bypass -File .\tools\validate.ps1 -Mode Unit
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
The process-scoped execution-policy argument does not change machine-wide
|
|
49
|
+
policy. Inspect scripts before running them. Unit mode performs PHP lint,
|
|
50
|
+
JavaScript syntax checks, sequential direct execution of each top-level
|
|
51
|
+
`tests/*.test.cjs`, PHP Clay transform/collision and download-path checks, shared/Clay harness
|
|
52
|
+
scaffold validation, UTF-8/null/replacement-character checks and plugin
|
|
53
|
+
name/version checks. It deliberately excludes the failing fixture from the
|
|
54
|
+
normal syntax scan.
|
|
55
|
+
|
|
56
|
+
**California Screamin' caveat:** the coordinator treats its full-page scaffold
|
|
57
|
+
audit failure as a warning because the page retains known width/background-position
|
|
58
|
+
blockers. Passing Unit is therefore not a statement that every release's browser,
|
|
59
|
+
visual, accessibility or performance gate passed.
|
|
60
|
+
|
|
61
|
+
The coordinator runs each Node contract as `node path/to/file.test.cjs`, not one
|
|
62
|
+
parallel `node --test` invocation. That is also the appropriate focused pattern:
|
|
63
|
+
|
|
64
|
+
```sh
|
|
65
|
+
node tests/dance-moves-core.test.cjs
|
|
66
|
+
node tests/dance-moves-diagnostics.test.cjs
|
|
67
|
+
node tests/timed-lyric-popover.test.cjs
|
|
68
|
+
node tests/exact-cue-seek.test.cjs
|
|
69
|
+
node tests/cue-timeline.test.cjs
|
|
70
|
+
node tests/effects-primitives.test.cjs
|
|
71
|
+
node tests/epk-download-contract.test.cjs
|
|
72
|
+
node tests/paper-dreams-flight.test.cjs
|
|
73
|
+
node tests/catalogue-timing.test.cjs
|
|
74
|
+
node tests/clay-adapter.test.cjs
|
|
75
|
+
node tests/sensor-raf-scheduler.test.cjs
|
|
76
|
+
node tests/runtime.test.cjs
|
|
77
|
+
node tests/california-adapter.test.cjs
|
|
78
|
+
php tests/validate-clay-transform.php
|
|
79
|
+
php tests/validate-clay-legacy-collision.php
|
|
80
|
+
php tests/validate-epk-download-paths.php
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
These focused commands do **not** replace the coordinator. Other checked-in
|
|
84
|
+
contract files cover WordPress metadata/uploads, shared component timing,
|
|
85
|
+
orientation maths, mobile API parity, capture duration and harness foundations.
|
|
86
|
+
See [tests/](../tests/) for the inventory. Use
|
|
87
|
+
[tools/test-validator-failure.ps1](../tools/test-validator-failure.ps1) when
|
|
88
|
+
verifying that the deliberate failure is correctly attributed and returns a
|
|
89
|
+
nonzero exit status.
|
|
90
|
+
|
|
91
|
+
## Local harness workflow
|
|
92
|
+
|
|
93
|
+
Serve the repository rather than opening timing-fetch fixtures through `file:`:
|
|
94
|
+
|
|
95
|
+
```sh
|
|
96
|
+
python -m http.server 8765 --bind 127.0.0.1
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
From the resulting local site, open the appropriate checked-in fixture under
|
|
100
|
+
`tests/`, such as `dance-moves-integration.html`, `shared-component-timing.html`
|
|
101
|
+
or `mobile-harness.html`, plus `effects-primitives-preview.html` and
|
|
102
|
+
`paper-dreams-flight-preview.html`, or follow the release harness's own files. Supply only
|
|
103
|
+
approved, locally available media/manifests; repository fixtures are not proof
|
|
104
|
+
that an external canonical master exists on your machine. A local HTTP server
|
|
105
|
+
does not make a LAN-served page a secure physical-phone sensor origin.
|
|
106
|
+
|
|
107
|
+
The shared harness validation commands used by the coordinator are:
|
|
108
|
+
|
|
109
|
+
```sh
|
|
110
|
+
python -X utf8 tools/validate-effect-harness.py tests/harness/plugin-core --mode scaffold
|
|
111
|
+
python -X utf8 tools/validate-effect-harness.py tests/harness/clay-stars --mode scaffold --manifest-file tests/harness/clay-stars/clay-stars.json --shared-root tests/harness/plugin-core
|
|
112
|
+
python -X utf8 tools/validate-effect-harness.py tests/harness/california-screamin --mode scaffold --manifest-file tests/harness/california-screamin/california-screamin.json --shared-root tests/harness/plugin-core
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
The [validator source](../tools/validate-effect-harness.py), release manifests and
|
|
116
|
+
[test plan](../TEST-PLAN.md) define their expected evidence. Manifest-driven
|
|
117
|
+
master/timing/effect controls, deterministic input/cue simulation, attributed
|
|
118
|
+
handler timing, CSS-property audits and release snapshots are development
|
|
119
|
+
facilities. They are not an additional public production control plane.
|
|
120
|
+
`EPKEffectHarnessProbe`, simulated orientation events and capture/conformance
|
|
121
|
+
utilities under `tests/` must not be shipped as front-end dependencies.
|
|
122
|
+
|
|
123
|
+
When instrumenting the core, set `danceMovesConfig.diagnostics = true` **before**
|
|
124
|
+
the core asset executes, then install a bounded `setDiagnosticsSink()` receiver.
|
|
125
|
+
Give every cue/lyric/interval effect a stable attribution ID. The normal
|
|
126
|
+
WordPress configuration does not enable diagnostics. See
|
|
127
|
+
[diagnostics API](api/javascript.md#diagnostics) for the payloads and limits.
|
|
128
|
+
|
|
129
|
+
## Release selection before changing documentation
|
|
130
|
+
|
|
131
|
+
Do not infer the latest plugin from the default branch. At this audit, `main`
|
|
132
|
+
remains 2.4.0 while the latest published tag is **v2.8.0**. The release commit is
|
|
133
|
+
`4cb6a71f60459b5579be87d7e55ac8b1426c578e`; the current staging branch is one
|
|
134
|
+
publication-evidence commit ahead, with identical production source and README.
|
|
135
|
+
Compare tags, release assets and staging before selecting a baseline.
|
|
136
|
+
|
|
137
|
+
This patch replaces the earlier 2.4.0 documentation patch; it is not incremental.
|
|
138
|
+
Apply to a clean 2.8.0/staging checkout without the previous patch's added `docs/`.
|
|
139
|
+
For example, after saving local work and placing the patch outside the checkout:
|
|
140
|
+
|
|
141
|
+
```sh
|
|
142
|
+
git fetch origin timed-lyrics-staging-2026-09-20 --tags
|
|
143
|
+
git switch -c docs/complete-api-reference-v2.8.0 origin/timed-lyrics-staging-2026-09-20
|
|
144
|
+
git apply --check /path/to/DanceMoves-2.8.0-documentation.patch
|
|
145
|
+
git apply /path/to/DanceMoves-2.8.0-documentation.patch
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
For an immutable release-based branch, use `v2.8.0` as the start point instead.
|
|
149
|
+
Review any newly fetched changes before applying. The commands do not push,
|
|
150
|
+
merge, rebuild a ZIP or write to WordPress. No PHP/JavaScript version bump is
|
|
151
|
+
required for a source-documentation change.
|
|
152
|
+
|
|
153
|
+
## Acceptance checks for an integration
|
|
154
|
+
|
|
155
|
+
Exercise ordinary playback, pause/resume, end/replay, playback-rate changes,
|
|
156
|
+
forward/backward seeks, more than one player, absent/invalid timing files,
|
|
157
|
+
blank/repeated/long lyric lines and a dynamically inserted audio element. Check
|
|
158
|
+
that only master-length players bind and call `discoverAudio()` after deliberate
|
|
159
|
+
dynamic insertion. Recreate interval subscriptions around backward seeks when
|
|
160
|
+
required by the documented scheduling caveat.
|
|
161
|
+
|
|
162
|
+
For shared timelines, test zero-time cues, default/opt-in playing and paused
|
|
163
|
+
landings, duplicate IDs, overlapping intervals, gap discontinuities, rate changes,
|
|
164
|
+
callback failures and repeated teardown. Confirm full interval reconstruction,
|
|
165
|
+
not merely a transient class firing. The core landing policy is different from
|
|
166
|
+
the timeline's opt-in policy. Verify every `next*` and `nextVisible*` field across
|
|
167
|
+
blank cues and the final line.
|
|
168
|
+
|
|
169
|
+
For downloads, test real GET/HEAD and invalid signatures, local-file availability,
|
|
170
|
+
Unicode filenames, cached page links and the original player's seek behaviour.
|
|
171
|
+
For paper planes, test hero clipping/stacking, compact counts, offscreen pause,
|
|
172
|
+
reduced-motion hiding and the forced-colour CSS-versus-loop distinction. For the
|
|
173
|
+
shared quality controller, test a preference already active at initial mount.
|
|
174
|
+
|
|
175
|
+
Test at desktop, tablet and narrow-mobile widths, signed out, with reduced motion
|
|
176
|
+
and forced colours. Preserve complete readable lyrics, keyboard focus, controls,
|
|
177
|
+
safe areas and static artwork. Test both permissions granted and denied on actual
|
|
178
|
+
supported devices, plus hidden-tab/page lifecycle changes. Confirm the adapter's
|
|
179
|
+
root identity before interpreting diagnostic attributes.
|
|
180
|
+
|
|
181
|
+
Performance acceptance requires sustained-load measurements and recovery trials,
|
|
182
|
+
not merely a snapshot of `profile: "full"`. Record the exact plugin/source or
|
|
183
|
+
package hash, browser/device, viewport, time and evidence location. Synthetic
|
|
184
|
+
orientation events verify contracts, not native trust, physical-device smoothness
|
|
185
|
+
or input-to-display latency. The motion-capture schema stores orientation/parity
|
|
186
|
+
data; it does not contain all the physical performance telemetry required by the
|
|
187
|
+
test plan.
|
|
188
|
+
|
|
189
|
+
The plugin release gate and the EPK pre-live gate are independent. `BLOCKED` and
|
|
190
|
+
`NOT RUN` are not `PASS`. No WordPress upload, page-meta write, timing-media upload
|
|
191
|
+
or legacy-plugin deactivation is authorised merely by running a local test.
|
|
192
|
+
|
|
193
|
+
## Packaging and upgrade identity
|
|
194
|
+
|
|
195
|
+
Only run the following for an intentional package/migration rebuild:
|
|
196
|
+
|
|
197
|
+
```powershell
|
|
198
|
+
powershell -NoProfile -ExecutionPolicy Bypass -File .\tools\validate.ps1 -Mode Package
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
[tools/package.ps1](../tools/package.ps1) reads the version from the PHP header,
|
|
202
|
+
uses the root `kieran-epk-device-orientation/`, and includes **only** the entrypoint,
|
|
203
|
+
root `README.md` and `assets/`. It writes `dist/DanceMoves-<version>.zip` and the
|
|
204
|
+
matching package manifest, including ZIP/file hashes and layout checks. The
|
|
205
|
+
manifest builder is a separate step invoked by Package mode.
|
|
206
|
+
|
|
207
|
+
`docs/`, tests, tools, QA, migration evidence and master audio are not copied into
|
|
208
|
+
the WordPress ZIP by the current allowlist. The complete API reference lives in
|
|
209
|
+
the source repository; the root README links to it online for packaged readers.
|
|
210
|
+
This documentation patch deliberately does not alter that packaging policy,
|
|
211
|
+
regenerate immutable evidence, overwrite existing ZIPs or bump runtime versions.
|
|
212
|
+
A later intentional package rebuild will include the updated root README.
|
|
213
|
+
|
|
214
|
+
Do not rename the internal folder or PHP entrypoint to `DanceMoves`: WordPress
|
|
215
|
+
must recognise the same installed plugin on upgrade. Check both the artifact
|
|
216
|
+
identity and package layout before deployment. Preserve an exact rollback ZIP
|
|
217
|
+
and its checksum. Reactivating the old Clay/Stars effects plugin suppresses the
|
|
218
|
+
new page-252 takeover when its `KS_CLAY_STARS_EFFECTS_VERSION` constant is defined;
|
|
219
|
+
it is not a general rollback for the shared timing core.
|
|
220
|
+
|
|
221
|
+
## Troubleshooting
|
|
222
|
+
|
|
223
|
+
| Symptom | Check / documented limitation |
|
|
224
|
+
| --- | --- |
|
|
225
|
+
| `DanceMoves` undefined | Script dependency/order, whether the request is a WordPress Page, footer output and browser console. The core has no public ready event or load promise; `dance-moves-effects-ready` belongs to the separate shared-effects layer. |
|
|
226
|
+
| Page shows fallback BPM | Metadata must be finite and within 20–400; blank/invalid values use 120 without claiming a known tempo. |
|
|
227
|
+
| Cue file has no entries | Use bracketed LRC-style timestamps, not CD `TRACK`/`INDEX` syntax. Blank cue labels are ignored. |
|
|
228
|
+
| Fetch failure looks like status `none` | Final initialisation overwrites the temporary `unavailable` marker. Inspect network/console and entry counts, not status alone. |
|
|
229
|
+
| Cue behaviour differs between integrations | Core LRC playback arms one cue within 50 ms, including at zero; the shared timeline fires crossings and has opt-in playing seek landings. Initialize persistent timeline state in render. |
|
|
230
|
+
| New audio does not follow cues | Insert it before discovery or call `discoverAudio()` after insertion; confirm metadata/duration and then normal playback events. |
|
|
231
|
+
| Repeating interval waits after backward seek | A retained interval boundary is not fully rebased; remove and recreate the subscription for that seek. |
|
|
232
|
+
| Custom lyric output remains visible on pause | `onLyric()` is not a complete playback-state stream. Handle pause/end for your custom renderer. |
|
|
233
|
+
| Lyric CSS does not match | The generated layer is under `body`, outside `.ks-epk`; component-local defaults also outrank merely inherited palette variables. |
|
|
234
|
+
| Phone UI absent | Production mobile/secure-context/sensor gate, root selector, adapter mapping, reduced motion and permission support. |
|
|
235
|
+
| Performance never reaches a fixed 60 FPS | Identify the controller: Clay uses median/p95 and probation; shared quality uses frame-count windows and fixed cooldowns. Neither proves physical refresh rate. |
|
|
236
|
+
| Paper snapshot reports 2.6.3 | This is the adapter-local marker; plugin `DanceMoves.version` is 2.8.0. |
|
|
237
|
+
| MP3 opens inline | Confirm the anchor has `download`, passed through main Page `the_content`, and matched the upload base. Direct player URLs intentionally stay inline. |
|
|
238
|
+
| Untouched assets fail byte hashes | Check `.gitattributes`, checkout line-ending conversion and the exact locked production bytes; never update locks merely to silence a mismatch. |
|
|
239
|
+
| A gate passes on a simulator but not a phone | Keep synthetic contracts and real physical-device evidence separate. |
|
|
240
|
+
|
|
241
|
+
For additional read-only inspection and preview utilities, inspect the commands
|
|
242
|
+
and assumptions in [tools/](../tools/): `audit-live-epk-motion.mjs`,
|
|
243
|
+
`capture-public-viewports.mjs`, `inspect-phone-epk.mjs`,
|
|
244
|
+
`build-clay-stars-preview.ps1` and `build-california-screamin-preview.ps1`.
|
|
245
|
+
No generic install command or undocumented command-line flags are implied here.
|
|
246
|
+
|
|
247
|
+
## Documentation maintenance
|
|
248
|
+
|
|
249
|
+
Keep troubleshooting limited to reproducible current plugin or integration problems,
|
|
250
|
+
with checks and links to the relevant API contract. Put test prerequisites beside
|
|
251
|
+
the commands they affect. Do not accumulate one-time shell/automation mistakes,
|
|
252
|
+
resolved fixture bugs, private workspace notes or dated success reports in the
|
|
253
|
+
README. Retain release provenance in existing version-control and migration/QA
|
|
254
|
+
records; changing documentation is not a new deployment or validation result.
|
package/docs/guide.md
ADDED
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
# User and integration guide
|
|
2
|
+
|
|
3
|
+
[Documentation index](README.md) · [JavaScript API](api/javascript.md) ·
|
|
4
|
+
[WordPress API](api/wordpress.md)
|
|
5
|
+
|
|
6
|
+
Source: [plugin entrypoint](../kieran-epk-device-orientation.php),
|
|
7
|
+
[timing runtime](../assets/dance-moves-core.js),
|
|
8
|
+
[catalogue adopter](../assets/dance-moves-catalogue-timing.js).
|
|
9
|
+
Baseline: **2.8.0 / `4cb6a71f60459b5579be87d7e55ac8b1426c578e`**.
|
|
10
|
+
|
|
11
|
+
## Install and upgrade
|
|
12
|
+
|
|
13
|
+
Use the reviewed release asset `DanceMoves-2.8.0.zip` (also kept in `dist/`),
|
|
14
|
+
not a GitHub source archive, for a
|
|
15
|
+
WordPress installation. Confirm its matching manifest and hashes before upload.
|
|
16
|
+
The visible plugin name is **DanceMoves**, but the installed folder and entrypoint
|
|
17
|
+
remain `kieran-epk-device-orientation/kieran-epk-device-orientation.php`. Keep that
|
|
18
|
+
identity when upgrading; renaming the folder can create a parallel installation.
|
|
19
|
+
|
|
20
|
+
The plugin header does not declare a minimum WordPress or PHP version. Do not
|
|
21
|
+
infer a supported-version matrix from that absence. Verify the site's PHP,
|
|
22
|
+
WordPress metadata/revision behaviour and target browsers in staging. The browser
|
|
23
|
+
runtime uses modern DOM, Promise/fetch, animation-frame and Web Animations APIs.
|
|
24
|
+
Phone input also needs a supported, secure browser context.
|
|
25
|
+
|
|
26
|
+
The shared CSS, core JavaScript, shared effect primitives and catalogue adopter are enqueued on singular
|
|
27
|
+
WordPress **Pages**, not arbitrary posts or archive screens. Orientation is
|
|
28
|
+
additionally limited by the configured page-ID map. The plugin does not create an
|
|
29
|
+
EPK, a music player, a lyrics transcript, or a chapter-navigation interface.
|
|
30
|
+
|
|
31
|
+
## Set page properties
|
|
32
|
+
|
|
33
|
+
Open the Page editor's **EPK Timing** meta box.
|
|
34
|
+
|
|
35
|
+
| Field | Input | Behaviour |
|
|
36
|
+
| --- | --- | --- |
|
|
37
|
+
| BPM | Finite 20–400, up to three stored decimal places | Blank clears the stored value. Unknown/invalid stored BPM resolves to 120 with `bpmSource: "fallback"`, not an assertion that the song is 120 BPM. |
|
|
38
|
+
| Lyric Timing File | Media Library `.lrc` attachment | The attachment ID is saved; its current URL is resolved when the page renders. |
|
|
39
|
+
| Cue Timing File | Media Library `.lrc` or `.cue` attachment | Uses the same bracketed timestamp grammar as LRC. |
|
|
40
|
+
| Timed lyric pop-ups | Checkbox, initially off | Enables the neutral built-in visual layer; it does not replace the complete readable lyric section. |
|
|
41
|
+
| Ambient effect | None or Paper planes | Stores `_dance_moves_effect` as `""` or `"paper-planes"`. Only the latter enqueues the plane assets; the page must supply `.ks-epk .epk-hero`. |
|
|
42
|
+
|
|
43
|
+
The hidden `_dance_moves_master_duration_ms` value is positive milliseconds, up to
|
|
44
|
+
one day, and is maintained through trusted server-side code rather than the meta
|
|
45
|
+
box or the standard page REST response. All six keys are registered for revision
|
|
46
|
+
support. See the [metadata reference](api/wordpress.md#page-metadata).
|
|
47
|
+
|
|
48
|
+
Editor saves require the plugin nonce, `edit_post` permission and a non-autosave
|
|
49
|
+
request. An invalid nonblank BPM or invalid timing attachment preserves that
|
|
50
|
+
field's previous value and queues an admin error; clearing a selection deletes
|
|
51
|
+
its metadata but **does not delete the shared Media Library attachment**. Fields
|
|
52
|
+
are saved independently, not as an atomic transaction. The checkbox is not
|
|
53
|
+
programmatically prevented from being enabled without a valid lyric file, so the
|
|
54
|
+
release review remains an explicit workflow requirement.
|
|
55
|
+
|
|
56
|
+
## Prepare cue and lyric files
|
|
57
|
+
|
|
58
|
+
Files selected through the editor must be readable local Media Library
|
|
59
|
+
attachments, no larger than **1,048,576 bytes**, with strict UTF-8 and no null or
|
|
60
|
+
replacement characters. There must be at least one bracketed timestamp, and all
|
|
61
|
+
timestamp tokens in file order must be nondecreasing. Equal timestamps are
|
|
62
|
+
allowed. Lyric files use `.lrc`; cue files use `.lrc` or `.cue`.
|
|
63
|
+
|
|
64
|
+
Accepted timestamp syntax is `[M:SS]`, `[MM:SS.ff]`, `[MMM:SS.fff]`, or the same
|
|
65
|
+
fraction introduced with `:`. Minutes have one to three digits, seconds exactly
|
|
66
|
+
two, and fractions one to three. Fractions are decimal seconds, **not frames**.
|
|
67
|
+
Use seconds 00–59 in authored files even though the current parser's pattern does
|
|
68
|
+
not independently reject a higher two-digit seconds field.
|
|
69
|
+
|
|
70
|
+
Example cue file:
|
|
71
|
+
|
|
72
|
+
```text
|
|
73
|
+
[00:04.000][SECTION: VERSE 1]
|
|
74
|
+
[00:20.000][SECTION: CHORUS 1]
|
|
75
|
+
[00:36.000]BREAK
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
Example lyric file:
|
|
79
|
+
|
|
80
|
+
```text
|
|
81
|
+
[00:00.000]
|
|
82
|
+
[00:04.000]First sung line
|
|
83
|
+
[00:08.000]Second sung line
|
|
84
|
+
[00:12.000]
|
|
85
|
+
[00:20.000]The repeated hook
|
|
86
|
+
[00:24.000]The repeated hook
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
A blank timed lyric clears the display. It is ignored by the cue parser. Multiple
|
|
90
|
+
timestamps on one line generate multiple entries; make sure their physical order
|
|
91
|
+
still satisfies the server's monotonic check. The browser sorts parsed entries,
|
|
92
|
+
but that does not make an out-of-order upload valid in the editor.
|
|
93
|
+
|
|
94
|
+
Metadata-only lines are ignored by the browser parsers. LRC offset tags, enhanced
|
|
95
|
+
word-by-word timing and conventional CD `FILE`/`TRACK`/`INDEX` cuesheet syntax are
|
|
96
|
+
not implemented. Timing text is data, never executable code or HTML.
|
|
97
|
+
|
|
98
|
+
The two files are fetched separately using same-origin credentials and
|
|
99
|
+
`cache: "no-cache"`. Cross-origin hosting needs the browser to permit the fetch.
|
|
100
|
+
The browser parser itself does not repeat the server's byte-size or monotonicity
|
|
101
|
+
validation. REST/programmatic attachment assignments need explicit validation;
|
|
102
|
+
see [WordPress validation](api/wordpress.md#timing-attachment-validation).
|
|
103
|
+
|
|
104
|
+
## Understand ticks before writing effects
|
|
105
|
+
|
|
106
|
+
One tick is **one sixteenth of a beat**, not a conventional sixteenth note:
|
|
107
|
+
|
|
108
|
+
```text
|
|
109
|
+
one tick = 3750 / BPM milliseconds
|
|
110
|
+
one beat = 16 ticks
|
|
111
|
+
one 4/4 bar = 64 ticks
|
|
112
|
+
at 120 BPM = 31.25 ms/tick, 500 ms/beat, 2000 ms/bar
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
Visual durations are rounded half upward to a positive integer tick. Results
|
|
116
|
+
above 16 are then rounded to the nearest multiple of 16, again half upward.
|
|
117
|
+
Consequently 17 duration ticks become 16; 24 become 32. Interval spacing uses
|
|
118
|
+
positive integer ticks without that long-duration quantisation. Use
|
|
119
|
+
`durationMilliseconds()` and the published CSS timing variables rather than
|
|
120
|
+
independent millisecond guesses.
|
|
121
|
+
|
|
122
|
+
The page clock starts when the core script evaluates. Playback interval helpers
|
|
123
|
+
wait for an active, matching audio element. `currentTick({clock: "audio"})` is a
|
|
124
|
+
special case: when no supplied/active audio is currently playing, it falls back to
|
|
125
|
+
the page clock. A paused song must therefore be guarded explicitly in a canvas
|
|
126
|
+
animation, rather than assuming that this call returns a frozen audio position.
|
|
127
|
+
|
|
128
|
+
There is no beat-offset, time-signature, variable-tempo or tempo-map setting. The
|
|
129
|
+
grid is anchored to audio time zero at a single BPM. For another meter, choose an
|
|
130
|
+
explicit interval, for example 48 ticks for three beats.
|
|
131
|
+
|
|
132
|
+
## Connect audio
|
|
133
|
+
|
|
134
|
+
Ordinary `<audio>` elements are discovered after both timing-file loads settle.
|
|
135
|
+
The preferred matching reference is the configured master duration. Otherwise the
|
|
136
|
+
runtime uses the first element in document order matching
|
|
137
|
+
`audio[data-dance-moves-master], #ks-clay-stars-audio`, otherwise the first audio
|
|
138
|
+
element. Mark the canonical
|
|
139
|
+
player explicitly when a page contains previews or unrelated audio:
|
|
140
|
+
|
|
141
|
+
```html
|
|
142
|
+
<audio id="release-audio" data-dance-moves-master controls preload="metadata">
|
|
143
|
+
<source src="/media/release-full-length.mp3" type="audio/mpeg">
|
|
144
|
+
</audio>
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
A positive finite duration matches when the absolute difference is at most
|
|
148
|
+
`max(0.25, audio.duration / 100000)` seconds. A preview, differently trimmed master
|
|
149
|
+
or live/infinite-duration stream is not safely interchangeable with the canonical
|
|
150
|
+
programme. This is a duration check, not audio fingerprinting or beat alignment.
|
|
151
|
+
|
|
152
|
+
Matching players are marked `data-dance-moves-timing="master-length"`. Each has its
|
|
153
|
+
own cue cursor; interval helpers use the player most recently started via
|
|
154
|
+
`play`/`playing`. Owned animations follow playback-rate changes. Seeking reindexes
|
|
155
|
+
the cue cursor without replaying skipped cues; lyrics resume at the current line.
|
|
156
|
+
The core arms the earliest cue within 50 ms of an initial/seek position, including
|
|
157
|
+
a cue at zero. It dispatches that pending cue once at playback start, or when a
|
|
158
|
+
playing seek completes. Other skipped cues are not replayed. This is not general
|
|
159
|
+
state reconstruction: use `DanceMovesEffects.cueTimeline()` for active intervals
|
|
160
|
+
and deterministic seek restoration, and initialise persistent visuals in its
|
|
161
|
+
`render` callback. The two cue mechanisms have different landing policies; see
|
|
162
|
+
[core cue landings](api/javascript.md#exact-cue-landings) and
|
|
163
|
+
[cue timelines](api/effects.md#cuetimelineoptions).
|
|
164
|
+
|
|
165
|
+
For dynamically inserted audio, call `DanceMoves.discoverAudio()` after insertion.
|
|
166
|
+
There is no global audio MutationObserver. Install integrations before starting
|
|
167
|
+
playback; discovery is not a transport-control or automatic-play API. Avoid
|
|
168
|
+
simultaneous players: cues are per-player, but the lyric layer, ownership resets
|
|
169
|
+
and active interval clock are shared.
|
|
170
|
+
|
|
171
|
+
## Subscribe and clean up
|
|
172
|
+
|
|
173
|
+
Enqueue a page script with `dance-moves-core` as a WordPress dependency. The global
|
|
174
|
+
is available when that script executes, but asynchronous timing fetches may still
|
|
175
|
+
be pending. There is no `DanceMoves.ready()` method or ready event.
|
|
176
|
+
|
|
177
|
+
```js
|
|
178
|
+
(() => {
|
|
179
|
+
const dm = window.DanceMoves;
|
|
180
|
+
const root = document.querySelector('.ks-epk');
|
|
181
|
+
if (!dm || !root) return;
|
|
182
|
+
|
|
183
|
+
const disposers = [
|
|
184
|
+
dm.onCue('CHORUS 1', detail => {
|
|
185
|
+
root.dataset.section = detail.normalisedName;
|
|
186
|
+
}, { id: 'release:chorus-state' }),
|
|
187
|
+
dm.onEveryInterval(detail => {
|
|
188
|
+
root.dataset.barTick = String(detail.boundaryTick);
|
|
189
|
+
}, 64, { id: 'release:bar-state' })
|
|
190
|
+
];
|
|
191
|
+
|
|
192
|
+
window.addEventListener('pagehide', () => {
|
|
193
|
+
disposers.forEach(remove => remove());
|
|
194
|
+
}, { once: true });
|
|
195
|
+
})();
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
This simple example assumes a normal page load; an application restoring a page
|
|
199
|
+
from the back-forward cache must re-register its own disposed handlers on
|
|
200
|
+
`pageshow`. Keep stable diagnostic IDs, and prefer `onCue()`/`onLyric()` over a
|
|
201
|
+
second parser or clock. For DOM listeners, register on `document`: cue and lyric
|
|
202
|
+
events are dispatched there, not on each EPK child.
|
|
203
|
+
|
|
204
|
+
## Adopt timed lyrics
|
|
205
|
+
|
|
206
|
+
A selected lyric file powers `onLyric()` even while the built-in pop-up is off.
|
|
207
|
+
The built-in layer is one body-level `.dance-moves-lyric-popover` containing a
|
|
208
|
+
`.dance-moves-lyric-popover__text`. It uses `textContent`, is noninteractive and
|
|
209
|
+
`aria-hidden`, hides on pause/end, and clears on a blank lyric. Reduced motion
|
|
210
|
+
keeps the words but removes entry/exit movement; forced colours have a fallback.
|
|
211
|
+
|
|
212
|
+
Before enabling it for a release, inspect that song's artwork and visual-language
|
|
213
|
+
record, distinguish observed/inferred/proposed/adopted decisions, and document a
|
|
214
|
+
distinctive treatment. Keep real text, full readable lyrics, safe areas and player
|
|
215
|
+
clearance. Test normal and long lines, blank clears, repeated hooks, seeking,
|
|
216
|
+
pause/resume/end, narrow screens, reduced motion and forced colours. A generic
|
|
217
|
+
checkbox-only adoption is not the approved workflow.
|
|
218
|
+
|
|
219
|
+
The renderer is appended to `body`, not inside `.ks-epk`. A selector such as
|
|
220
|
+
`.ks-epk .dance-moves-lyric-popover` will not reach it. Scope release styling through
|
|
221
|
+
an appropriate body page class or other release-specific ancestor context. See
|
|
222
|
+
[lyric styling](api/styling.md#timed-lyric-component).
|
|
223
|
+
|
|
224
|
+
Custom lyric consumers must handle audio `pause`/`ended` themselves when they need
|
|
225
|
+
to hide: `onLyric()` does not emit a synthetic blank on those events. It also does
|
|
226
|
+
not immediately replay the last value to a newly registered handler.
|
|
227
|
+
|
|
228
|
+
## Use the shared effects API
|
|
229
|
+
|
|
230
|
+
Load after `dance-moves-effects`, or mount once in response to the document's
|
|
231
|
+
`dance-moves-effects-ready` event. Select the smallest matching primitive:
|
|
232
|
+
`pointer()` for bounded input, `playbackPulse()` for phase-aligned CSS,
|
|
233
|
+
`cueClass()` for a short cue-triggered class, `cueTimeline()` for reconstructable
|
|
234
|
+
playback state, and `quality()` for a reusable quality controller. Stable IDs
|
|
235
|
+
identify instances for `get()`, `snapshot()` and teardown. Each has explicit
|
|
236
|
+
options, callback payloads and disposal semantics in the [shared API](api/effects.md).
|
|
237
|
+
These are APIs, not auto-enabled visual presets. In particular, a cue timeline
|
|
238
|
+
accepts page-owned cue objects; it does not automatically import the Page cue LRC.
|
|
239
|
+
|
|
240
|
+
For paper planes, select **Ambient effect → Paper planes** and provide an existing
|
|
241
|
+
hero with explicit containment. Check full and compact counts, clipping, readable
|
|
242
|
+
controls and reduced motion before publication. See the [paper-plane API](api/paper-planes.md).
|
|
243
|
+
|
|
244
|
+
## Provide MP3 downloads without breaking playback
|
|
245
|
+
|
|
246
|
+
Use an ordinary same-upload-host MP3 link with an explicit `download` attribute:
|
|
247
|
+
|
|
248
|
+
```html
|
|
249
|
+
<a href="/wp-content/uploads/2026/09/example.mp3" download>Download MP3</a>
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
On the main Page content render, DanceMoves rewrites eligible anchors to its
|
|
253
|
+
signed attachment endpoint. It does not rewrite players, `<source>` elements,
|
|
254
|
+
external media or links without `download`. Server-generated signed URLs are
|
|
255
|
+
shareable and do not expire automatically; they are not a private-media service.
|
|
256
|
+
The [download reference](api/downloads.md) covers URL helpers, request methods,
|
|
257
|
+
response headers, path validation and errors.
|
|
258
|
+
|
|
259
|
+
## Adopt catalogue and orientation motion
|
|
260
|
+
|
|
261
|
+
The catalogue adopter chooses `.ks-epk` first, with specific fallback roots listed
|
|
262
|
+
in the [adapter reference](api/adapters.md#catalogue-timing). It converts owned
|
|
263
|
+
animation/transition durations and delays, preserving zero and special reduced-
|
|
264
|
+
motion/view-timeline sentinels. It also registers the release root for cue resets
|
|
265
|
+
and observes inserted elements/style-attribute changes. It does not change
|
|
266
|
+
artwork, invent choreography, rewrite keyframe geometry, or retime canvas code.
|
|
267
|
+
|
|
268
|
+
Phone orientation is a separate nine-page adapter map. The production wrapper
|
|
269
|
+
checks mobile eligibility and sensor support. Permission-requesting browsers get
|
|
270
|
+
**Use phone motion**; denied/unavailable input leaves the ordinary page usable.
|
|
271
|
+
Hidden pages, reduced motion and teardown stop input work; screen rotation
|
|
272
|
+
recalibrates it. Release-specific motion-off controls remain relevant. CSS
|
|
273
|
+
transitions interpolate targets published at a two-tick cadence; the two-second
|
|
274
|
+
rolling window is input processing, not a musical duration.
|
|
275
|
+
|
|
276
|
+
For Clay/Stars, keep the existing legacy effects plugin active until the approved
|
|
277
|
+
takeover. While `KS_CLAY_STARS_EFFECTS_VERSION` is defined, DanceMoves suppresses
|
|
278
|
+
its Clay CSS/JS and content transform. Deactivating the legacy plugin permits
|
|
279
|
+
takeover on a subsequent request. Do not transplant that release's artwork or
|
|
280
|
+
motion treatment onto other EPKs.
|
|
281
|
+
|
|
282
|
+
## Diagnostics and deployment
|
|
283
|
+
|
|
284
|
+
Use [development and operations](development.md) for local tests, diagnostics,
|
|
285
|
+
performance tiers, approval gates and rollback. A motion capture is an explicit
|
|
286
|
+
submission of a supplied recording; ordinary plugin playback does not record or
|
|
287
|
+
upload phone samples. No WordPress upload, metadata write or deployment is part
|
|
288
|
+
of a documentation update.
|