nodality 1.0.221 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (279) hide show
  1. package/API.md +227 -0
  2. package/bin/nodality.js +64 -0
  3. package/dist/animator.cjs.js +1 -1
  4. package/dist/animator.cjs.js.LICENSE.txt +1 -1
  5. package/dist/animator.esm.js +1 -1
  6. package/dist/animator.esm.js.LICENSE.txt +1 -1
  7. package/dist/audionew.cjs.js +1 -1
  8. package/dist/audionew.cjs.js.LICENSE.txt +1 -1
  9. package/dist/audionew.esm.js +1 -1
  10. package/dist/audionew.esm.js.LICENSE.txt +1 -1
  11. package/dist/base.cjs.js +1 -1
  12. package/dist/base.cjs.js.LICENSE.txt +1 -1
  13. package/dist/base.esm.js +1 -1
  14. package/dist/base.esm.js.LICENSE.txt +1 -1
  15. package/dist/beta-desktop-bar.cjs.js +1 -1
  16. package/dist/beta-desktop-bar.cjs.js.LICENSE.txt +1 -1
  17. package/dist/beta-desktop-bar.esm.js +1 -1
  18. package/dist/beta-desktop-bar.esm.js.LICENSE.txt +1 -1
  19. package/dist/beta-mobile-bar.cjs.js +1 -1
  20. package/dist/beta-mobile-bar.cjs.js.LICENSE.txt +1 -1
  21. package/dist/beta-mobile-bar.esm.js +1 -1
  22. package/dist/beta-mobile-bar.esm.js.LICENSE.txt +1 -1
  23. package/dist/bundle.umd.js +1 -1
  24. package/dist/bundle.umd.js.LICENSE.txt +131 -1
  25. package/dist/button.cjs.js +1 -1
  26. package/dist/button.cjs.js.LICENSE.txt +1 -1
  27. package/dist/button.esm.js +1 -1
  28. package/dist/button.esm.js.LICENSE.txt +1 -1
  29. package/dist/card-getter.cjs.js.LICENSE.txt +1 -1
  30. package/dist/card-getter.esm.js.LICENSE.txt +1 -1
  31. package/dist/center.cjs.js +1 -1
  32. package/dist/center.cjs.js.LICENSE.txt +1 -1
  33. package/dist/center.esm.js +1 -1
  34. package/dist/center.esm.js.LICENSE.txt +1 -1
  35. package/dist/checkbox.cjs.js +1 -1
  36. package/dist/checkbox.cjs.js.LICENSE.txt +1 -1
  37. package/dist/checkbox.esm.js +1 -1
  38. package/dist/checkbox.esm.js.LICENSE.txt +1 -1
  39. package/dist/code.cjs.js +1 -1
  40. package/dist/code.cjs.js.LICENSE.txt +1 -1
  41. package/dist/code.esm.js +1 -1
  42. package/dist/code.esm.js.LICENSE.txt +1 -1
  43. package/dist/container.cjs.js +1 -1
  44. package/dist/container.cjs.js.LICENSE.txt +1 -1
  45. package/dist/container.esm.js +1 -1
  46. package/dist/container.esm.js.LICENSE.txt +1 -1
  47. package/dist/data-list.cjs.js +1 -1
  48. package/dist/data-list.cjs.js.LICENSE.txt +1 -1
  49. package/dist/data-list.esm.js +1 -1
  50. package/dist/data-list.esm.js.LICENSE.txt +1 -1
  51. package/dist/designer.cjs.js +1 -1
  52. package/dist/designer.cjs.js.LICENSE.txt +97 -1
  53. package/dist/designer.esm.js +1 -1
  54. package/dist/designer.esm.js.LICENSE.txt +97 -1
  55. package/dist/element-mapper.cjs.js +1 -1
  56. package/dist/element-mapper.cjs.js.LICENSE.txt +17 -1
  57. package/dist/element-mapper.esm.js +1 -1
  58. package/dist/element-mapper.esm.js.LICENSE.txt +17 -1
  59. package/dist/finalresult.esm.js +1 -1
  60. package/dist/finalresult.esm.js.LICENSE.txt +158 -1
  61. package/dist/flex-card.cjs.js +1 -1
  62. package/dist/flex-card.cjs.js.LICENSE.txt +1 -1
  63. package/dist/flex-card.esm.js +1 -1
  64. package/dist/flex-card.esm.js.LICENSE.txt +1 -1
  65. package/dist/flex-grid.cjs.js +1 -1
  66. package/dist/flex-grid.cjs.js.LICENSE.txt +1 -1
  67. package/dist/flex-grid.esm.js +1 -1
  68. package/dist/flex-grid.esm.js.LICENSE.txt +1 -1
  69. package/dist/flex-row.cjs.js +1 -1
  70. package/dist/flex-row.cjs.js.LICENSE.txt +1 -1
  71. package/dist/flex-row.esm.js +1 -1
  72. package/dist/flex-row.esm.js.LICENSE.txt +1 -1
  73. package/dist/floating-input.cjs.js +1 -1
  74. package/dist/floating-input.cjs.js.LICENSE.txt +1 -1
  75. package/dist/floating-input.esm.js +1 -1
  76. package/dist/floating-input.esm.js.LICENSE.txt +1 -1
  77. package/dist/free.cjs.js +1 -1
  78. package/dist/free.cjs.js.LICENSE.txt +1 -1
  79. package/dist/free.esm.js +1 -1
  80. package/dist/free.esm.js.LICENSE.txt +1 -1
  81. package/dist/horizontal-scroller.cjs.js.LICENSE.txt +1 -1
  82. package/dist/horizontal-scroller.esm.js.LICENSE.txt +1 -1
  83. package/dist/image-picker.cjs.js +1 -1
  84. package/dist/image-picker.cjs.js.LICENSE.txt +1 -1
  85. package/dist/image-picker.esm.js +1 -1
  86. package/dist/image-picker.esm.js.LICENSE.txt +1 -1
  87. package/dist/image.cjs.js +1 -1
  88. package/dist/image.cjs.js.LICENSE.txt +1 -1
  89. package/dist/image.esm.js +1 -1
  90. package/dist/image.esm.js.LICENSE.txt +1 -1
  91. package/dist/index.cjs.js +1 -1
  92. package/dist/index.cjs.js.LICENSE.txt +158 -1
  93. package/dist/index.d.ts +962 -0
  94. package/dist/index.esm.js +1 -1
  95. package/dist/index.esm.js.LICENSE.txt +158 -1
  96. package/dist/keyframe-animation.cjs.js.LICENSE.txt +1 -1
  97. package/dist/keyframe-animation.esm.js.LICENSE.txt +1 -1
  98. package/dist/link-getter.cjs.js +1 -1
  99. package/dist/link-getter.cjs.js.LICENSE.txt +1 -1
  100. package/dist/link-getter.esm.js +1 -1
  101. package/dist/link-getter.esm.js.LICENSE.txt +1 -1
  102. package/dist/link.cjs.js +1 -1
  103. package/dist/link.cjs.js.LICENSE.txt +1 -1
  104. package/dist/link.esm.js +1 -1
  105. package/dist/link.esm.js.LICENSE.txt +1 -1
  106. package/dist/meta-adder.cjs.js +1 -1
  107. package/dist/meta-adder.cjs.js.LICENSE.txt +1 -1
  108. package/dist/meta-adder.esm.js +1 -1
  109. package/dist/meta-adder.esm.js.LICENSE.txt +1 -1
  110. package/dist/modal-2025.cjs.js +1 -1
  111. package/dist/modal-2025.cjs.js.LICENSE.txt +1 -1
  112. package/dist/modal-2025.esm.js +1 -1
  113. package/dist/modal-2025.esm.js.LICENSE.txt +1 -1
  114. package/dist/multiswitcher.cjs.js +1 -1
  115. package/dist/multiswitcher.cjs.js.LICENSE.txt +1 -1
  116. package/dist/multiswitcher.esm.js +1 -1
  117. package/dist/multiswitcher.esm.js.LICENSE.txt +1 -1
  118. package/dist/new-nav-bar.cjs.js +1 -1
  119. package/dist/new-nav-bar.cjs.js.LICENSE.txt +1 -1
  120. package/dist/new-nav-bar.esm.js +1 -1
  121. package/dist/new-nav-bar.esm.js.LICENSE.txt +1 -1
  122. package/dist/picker.cjs.js +1 -1
  123. package/dist/picker.cjs.js.LICENSE.txt +1 -1
  124. package/dist/picker.esm.js +1 -1
  125. package/dist/picker.esm.js.LICENSE.txt +1 -1
  126. package/dist/progress.cjs.js +1 -1
  127. package/dist/progress.cjs.js.LICENSE.txt +1 -1
  128. package/dist/progress.esm.js +1 -1
  129. package/dist/progress.esm.js.LICENSE.txt +1 -1
  130. package/dist/radio.cjs.js +1 -1
  131. package/dist/radio.cjs.js.LICENSE.txt +1 -1
  132. package/dist/radio.esm.js +1 -1
  133. package/dist/radio.esm.js.LICENSE.txt +1 -1
  134. package/dist/range.cjs.js +1 -1
  135. package/dist/range.cjs.js.LICENSE.txt +1 -1
  136. package/dist/range.esm.js +1 -1
  137. package/dist/range.esm.js.LICENSE.txt +1 -1
  138. package/dist/scroll-video.cjs.js.LICENSE.txt +1 -1
  139. package/dist/scroll-video.esm.js.LICENSE.txt +1 -1
  140. package/dist/side-bar.cjs.js +1 -1
  141. package/dist/side-bar.cjs.js.LICENSE.txt +1 -1
  142. package/dist/side-bar.esm.js +1 -1
  143. package/dist/side-bar.esm.js.LICENSE.txt +1 -1
  144. package/dist/side-nav-bar.cjs.js +1 -1
  145. package/dist/side-nav-bar.cjs.js.LICENSE.txt +1 -1
  146. package/dist/side-nav-bar.esm.js +1 -1
  147. package/dist/side-nav-bar.esm.js.LICENSE.txt +1 -1
  148. package/dist/simple-bar.cjs.js +1 -1
  149. package/dist/simple-bar.cjs.js.LICENSE.txt +1 -1
  150. package/dist/simple-bar.esm.js +1 -1
  151. package/dist/simple-bar.esm.js.LICENSE.txt +1 -1
  152. package/dist/slider-2025.cjs.js +1 -1
  153. package/dist/slider-2025.cjs.js.LICENSE.txt +1 -1
  154. package/dist/slider-2025.esm.js +1 -1
  155. package/dist/slider-2025.esm.js.LICENSE.txt +1 -1
  156. package/dist/spacer.cjs.js +1 -1
  157. package/dist/spacer.cjs.js.LICENSE.txt +1 -1
  158. package/dist/spacer.esm.js +1 -1
  159. package/dist/spacer.esm.js.LICENSE.txt +1 -1
  160. package/dist/stack.cjs.js +1 -1
  161. package/dist/stack.cjs.js.LICENSE.txt +1 -1
  162. package/dist/stack.esm.js +1 -1
  163. package/dist/stack.esm.js.LICENSE.txt +1 -1
  164. package/dist/stacker.cjs.js.LICENSE.txt +1 -1
  165. package/dist/stacker.esm.js.LICENSE.txt +1 -1
  166. package/dist/table.cjs.js +1 -1
  167. package/dist/table.cjs.js.LICENSE.txt +1 -1
  168. package/dist/table.esm.js +1 -1
  169. package/dist/table.esm.js.LICENSE.txt +1 -1
  170. package/dist/text-field.cjs.js +1 -1
  171. package/dist/text-field.cjs.js.LICENSE.txt +1 -1
  172. package/dist/text-field.esm.js +1 -1
  173. package/dist/text-field.esm.js.LICENSE.txt +1 -1
  174. package/dist/text.cjs.js +1 -1
  175. package/dist/text.cjs.js.LICENSE.txt +1 -1
  176. package/dist/text.esm.js +1 -1
  177. package/dist/text.esm.js.LICENSE.txt +1 -1
  178. package/dist/theme.cjs.js.LICENSE.txt +1 -1
  179. package/dist/theme.esm.js.LICENSE.txt +1 -1
  180. package/dist/transform-anim.cjs.js.LICENSE.txt +1 -1
  181. package/dist/transform-anim.esm.js.LICENSE.txt +1 -1
  182. package/dist/ulist.cjs.js +1 -1
  183. package/dist/ulist.cjs.js.LICENSE.txt +1 -1
  184. package/dist/ulist.esm.js +1 -1
  185. package/dist/ulist.esm.js.LICENSE.txt +1 -1
  186. package/dist/video.cjs.js +1 -1
  187. package/dist/video.cjs.js.LICENSE.txt +1 -1
  188. package/dist/video.esm.js +1 -1
  189. package/dist/video.esm.js.LICENSE.txt +1 -1
  190. package/dist/wrap.cjs.js +1 -1
  191. package/dist/wrap.cjs.js.LICENSE.txt +1 -1
  192. package/dist/wrap.esm.js +1 -1
  193. package/dist/wrap.esm.js.LICENSE.txt +1 -1
  194. package/dist/zoom-card.cjs.js +1 -1
  195. package/dist/zoom-card.cjs.js.LICENSE.txt +1 -1
  196. package/dist/zoom-card.esm.js +1 -1
  197. package/dist/zoom-card.esm.js.LICENSE.txt +1 -1
  198. package/examples/custom-raster-op.js +174 -0
  199. package/layout/animator.js +30 -2
  200. package/layout/audio.js +1 -1
  201. package/layout/audionew.js +1 -1
  202. package/layout/base.js +1 -1
  203. package/layout/beta-desktop-bar.js +1 -1
  204. package/layout/beta-mobile-bar.js +3 -2
  205. package/layout/button.js +1 -1
  206. package/layout/center.js +1 -1
  207. package/layout/checkbox.js +2 -2
  208. package/layout/circle.js +3 -2
  209. package/layout/code.js +3 -2
  210. package/layout/container.js +3 -4
  211. package/layout/dropdown-2025.js +1 -1
  212. package/layout/flex-card.js +1 -1
  213. package/layout/flex-grid.js +1 -1
  214. package/layout/flex-row.js +3 -2
  215. package/layout/form-components/custom.js +1 -1
  216. package/layout/form-components/data-list.js +2 -2
  217. package/layout/form-components/floating-input.js +2 -2
  218. package/layout/form-components/form-all.js +2 -2
  219. package/layout/form-components/form.js +1 -1
  220. package/layout/form-components/image-picker.js +1 -1
  221. package/layout/form-components/picker.js +2 -2
  222. package/layout/form-components/radio.js +2 -2
  223. package/layout/form-components/radiogroup.js +2 -2
  224. package/layout/form-components/range.js +2 -2
  225. package/layout/free.js +3 -4
  226. package/layout/grid-switcher.js +1 -1
  227. package/layout/grid.js +1 -1
  228. package/layout/horizontal-scroller.js +1 -1
  229. package/layout/image.js +1 -1
  230. package/layout/index.js +1 -1
  231. package/layout/link.js +5 -5
  232. package/layout/list.js +3 -4
  233. package/layout/meta-adder.js +1 -1
  234. package/layout/modal-2025.js +1 -1
  235. package/layout/morph.js +1003 -0
  236. package/layout/multiswitcher.js +11 -3
  237. package/layout/nav-bar.js +2 -3
  238. package/layout/nav-factor/custom-div.js +2 -2
  239. package/layout/new-nav-bar.js +11 -4
  240. package/layout/polygon.js +3 -4
  241. package/layout/prerender-site.js +1 -1
  242. package/layout/prerender.js +1 -1
  243. package/layout/progress.js +1 -1
  244. package/layout/row.js +1 -1
  245. package/layout/scroll-video.js +1 -1
  246. package/layout/side-bar.js +1 -1
  247. package/layout/side-nav-bar.js +1 -1
  248. package/layout/simple-bar.js +1 -1
  249. package/layout/slider-2025.js +1 -1
  250. package/layout/spacer.js +1 -1
  251. package/layout/stack.js +1 -1
  252. package/layout/svg.js +3 -4
  253. package/layout/switcher.js +1 -1
  254. package/layout/table.js +1 -1
  255. package/layout/text-field.js +1 -1
  256. package/layout/text.js +5 -5
  257. package/layout/ulist.js +1 -1
  258. package/layout/video.js +1 -1
  259. package/layout/wrap.js +1 -1
  260. package/layout/zoom-card.js +1 -1
  261. package/lib/card-getter.js +1 -1
  262. package/lib/codegen.js +62 -0
  263. package/lib/data.js +37 -1
  264. package/lib/designer.js +18 -1
  265. package/lib/element-mapper.js +351 -247
  266. package/lib/keyframe-animation.js +1 -1
  267. package/lib/link-getter.js +1 -1
  268. package/lib/morph-node.js +424 -0
  269. package/lib/raster-inspect.js +409 -0
  270. package/lib/raster-ops.js +1980 -81
  271. package/lib/raster-presets.js +329 -0
  272. package/lib/scroll-video.js +1 -1
  273. package/lib/seo.js +28 -1
  274. package/lib/stacker.js +1 -1
  275. package/lib/suggest.js +66 -0
  276. package/lib/theme.js +1 -1
  277. package/lib/transform-anim.js +1 -1
  278. package/lib/transition.js +205 -0
  279. package/package.json +20 -7
@@ -1,7 +1,164 @@
1
1
  /*!
2
- * nodality v1.0.220
2
+ * codegen.js — options object -> JavaScript source, for toCode().
3
+ *
4
+ * Every toCode() in the library used to hand-roll the same two steps:
5
+ *
6
+ * JSON.stringify(obj, null, 4).replace(/"([^"]+)":/g, '$1:')
7
+ *
8
+ * The replace unquotes EVERY key. That is correct for `radius` and wrong
9
+ * for any key that is not a bare identifier — and the library emits those
10
+ * now: `vars: { --nod-split: 0.9 }` from the morph expansion, and content
11
+ * slots like `"main.hero.title"`. Neither parses as JavaScript, so the
12
+ * emitted code could not be run, pasted, or ejected. Fourteen copies of
13
+ * the bad spelling had drifted across twelve files, while the correct one
14
+ * (`/"(\w+)"\s*:/g`) already sat in image.js, table.js, button.js and
15
+ * side-nav-bar.js — the same rule, written both ways, in one codebase.
16
+ *
17
+ * This module is the one place that rule lives now. It is pure: no DOM, no
18
+ * imports, safe to load anywhere (see __tests__/unit/import-inert).
19
+ *
20
+ * toObjectSource(obj, 4) // an object -> "{\n radius: \"2px\"\n}"
21
+ * unquoteKeys(jsonString) // already have the JSON? just fix the keys
22
+ * IDENT_KEY // the pattern, for call sites that chain
23
+ * // further replaces onto the same string
24
+ */
25
+
26
+ /*!
27
+ * morph-node.js — `{ op: "morph" }`, the (E,N) form of a transition.
28
+ *
29
+ * Everything else in N describes how an element LOOKS. A morph node
30
+ * describes which element BECOMES which, and on what interaction:
31
+ *
32
+ * { op: "morph", from: "topnav", to: ["work", "about", "contact"],
33
+ * effect: "t-vhs", duration: 900, back: true }
34
+ *
35
+ * Before this, a transition was the one thing the two arrays could not
36
+ * express. A page wanting a morph had to capture both sides itself,
37
+ * measure two rects, call applyRasterPipeline with a `transition` block,
38
+ * drive `t` through a timeline, and wire the clicks — a few hundred lines
39
+ * sitting *around* the arrays rather than in them.
40
+ *
41
+ * What this owns, so a caller does not have to:
42
+ *
43
+ * - the destinations start hidden, so only the source is on screen
44
+ * - link i in the source maps to destination i
45
+ * - both sides are captured as stills and travel one converging box
46
+ * - `back: true` wires the destination's own button to return
47
+ *
48
+ * Runs AFTER Des has mounted, because it needs rendered geometry: rects
49
+ * come from real layout, not from the descriptors.
50
+ */
51
+
52
+ /*!
53
+ * nodality v1.0.224
3
54
  * (c) 2026 Filip Vabrousek
4
55
  * License: MIT
5
56
  */
6
57
 
58
+ /*!
59
+ * nodality/data — runtime/SSG-aware data loader
60
+ *
61
+ * `loadJson(name, opts?)` resolves JSON in whichever environment the
62
+ * page entry is currently executing:
63
+ *
64
+ * • Browser → relative `fetch("./<name>")` from the page's URL.
65
+ * • Node → ESM JSON import from `../<name>` relative to this
66
+ * module (i.e. from the project's `upload/` directory).
67
+ *
68
+ * The two paths differ because under SSG (nodality prerender + jsdom)
69
+ * there is no dev server to fetch from — fetches silently fail and
70
+ * the page ships an empty mount. The ESM import path reads the JSON
71
+ * straight off disk, embedding the data into the prerendered HTML so
72
+ * crawlers see real content.
73
+ *
74
+ * Usage in a page entry:
75
+ *
76
+ * import { loadJson } from "nodality/data";
77
+ * const products = await loadJson("products.json");
78
+ *
79
+ * Conventions:
80
+ * • At runtime the file must live next to the page HTML (so
81
+ * `./products.json` resolves under the deployed origin).
82
+ * • At build time the file must live in `upload/` (the project's
83
+ * `uploadDir`) — which is the same place. Single source of truth.
84
+ *
85
+ * `fallback` is an opt-in escape hatch: pass `{ fallback: [] }` to
86
+ * return the supplied value instead of throwing when the file is
87
+ * missing. Useful for "team.json doesn't exist yet" stub pages.
88
+ *
89
+ * Add `{ quiet: true }` when that missing file is the EXPECTED state, so
90
+ * the build stays silent for a stub and still warns when a file that is
91
+ * supposed to be there fails to load.
92
+ */
93
+
94
+ /*!
95
+ * nodality/seo — SEO metadata helpers
96
+ *
97
+ * Exposes a single `applySeoMeta()` call that idempotently writes a
98
+ * full per-page metadata bundle into <head>: description, canonical,
99
+ * Open Graph (Facebook / iMessage / WhatsApp / Slack / LinkedIn),
100
+ * Twitter / X card, and an optional schema.org JSON-LD payload.
101
+ *
102
+ * Also exports a handful of pre-built JSON-LD builders for the
103
+ * common schema types (Organization, WebSite, Product, Article,
104
+ * BreadcrumbList) so projects don't have to memorise the schema.org
105
+ * field names.
106
+ *
107
+ * Works in both directions:
108
+ * • At SSG time (nodality prerender) the tags land in the static
109
+ * HTML response — crawlers and social-card scrapers index them.
110
+ * • At browser hydration time the same call re-applies the tags
111
+ * against the live <head>; idempotent via `data-seo="1"` markers,
112
+ * so re-rendering the page doesn't pile up duplicates.
113
+ *
114
+ * Origin handling: pass `path` as a leading-slash route ("/" or
115
+ * "/blog/post-1") and configure the origin globally via
116
+ * `setSeoOrigin("https://example.com")` once at app boot. Falls back
117
+ * to `window.location.origin` in the browser if no origin is set;
118
+ * falls back to "" under SSG (canonical-relative).
119
+ */
120
+
121
+ /*!
122
+ * suggest.js — "did you mean …?" over a closed vocabulary.
123
+ *
124
+ * The library's most expensive historical bug class is the silently
125
+ * ignored key: a typo'd option or element type that does nothing, reports
126
+ * nothing, and is found minutes later by eye. Everywhere a vocabulary is
127
+ * closed — morph's tokens/kinds/axes, ElementMapper's element types — the
128
+ * rule is the same: throw, and name the nearest valid word.
129
+ *
130
+ * Extracted from layout/morph.js (phase M1) so the mapper can use the same
131
+ * matching, and so the ~15-line DP exists once. No dependency: writing it
132
+ * is cheaper than owning one, which is the same call the allocator made.
133
+ *
134
+ * Pure — no DOM, safe to import anywhere.
135
+ */
136
+
137
+ /*!
138
+ * transition.js — driving transition progress. Phase T4.
139
+ *
140
+ * The pipeline already renders any `t` you hand it (phases T1–T3). This
141
+ * module is only about WHERE t comes from: a timeline, a scroll range, a
142
+ * drag, a test. It owns no pixels.
143
+ *
144
+ * import { progressTimeline } from "nodality/transition";
145
+ *
146
+ * const tl = progressTimeline(pipeline, { duration: 600 });
147
+ * tl.to(1); // play forward
148
+ * tl.to(0); // reverse — from wherever it is NOW
149
+ * tl.bindScroll("#section");
150
+ * tl.set(0.37); // deterministic, for tests and gestures
151
+ *
152
+ * The one property everything rests on: **retargeting starts from the
153
+ * current value, never from zero.** Interrupting a half-finished morph
154
+ * and sending it back is `to(0)`, and it continues from 0.5 rather than
155
+ * snapping. That falls out of `t` being an input rather than a timer
156
+ * (P-1) — there is no timeline state to unwind, only a number to move.
157
+ *
158
+ * Duration scales with the distance actually travelled, so a reversal
159
+ * from the midpoint takes half as long as a full play. A fixed duration
160
+ * makes short corrections feel sluggish and is the usual reason
161
+ * interruptible animation feels wrong.
162
+ */
163
+
7
164
  /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/babel/babel/blob/main/packages/babel-helpers/LICENSE */
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * nodality v1.0.220
2
+ * nodality v1.0.224
3
3
  * (c) 2026 Filip Vabrousek
4
4
  * License: MIT
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * nodality v1.0.220
2
+ * nodality v1.0.224
3
3
  * (c) 2026 Filip Vabrousek
4
4
  * License: MIT
5
5
  */