@rafaelaugusto/jolt 0.1.0-beta.9 → 0.1.0-rc.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.
Files changed (576) hide show
  1. package/README.md +167 -21
  2. package/dist/animate.d.ts +25 -4
  3. package/dist/animate.d.ts.map +1 -1
  4. package/dist/animate.js +67 -26
  5. package/dist/animate.js.map +1 -1
  6. package/dist/blur/index.d.ts +6 -0
  7. package/dist/blur/index.d.ts.map +1 -0
  8. package/dist/blur/index.js +196 -0
  9. package/dist/blur/index.js.map +1 -0
  10. package/dist/blur/native.d.ts +17 -0
  11. package/dist/blur/native.d.ts.map +1 -0
  12. package/dist/blur/native.js +44 -0
  13. package/dist/blur/native.js.map +1 -0
  14. package/dist/blur/types.d.ts +32 -0
  15. package/dist/blur/types.d.ts.map +1 -0
  16. package/dist/blur/types.js +2 -0
  17. package/dist/blur/types.js.map +1 -0
  18. package/dist/bottom-sheet/geometry.d.ts +18 -0
  19. package/dist/bottom-sheet/geometry.d.ts.map +1 -0
  20. package/dist/bottom-sheet/geometry.js +51 -0
  21. package/dist/bottom-sheet/geometry.js.map +1 -0
  22. package/dist/bottom-sheet/index.d.ts +56 -0
  23. package/dist/bottom-sheet/index.d.ts.map +1 -0
  24. package/dist/bottom-sheet/index.js +462 -0
  25. package/dist/bottom-sheet/index.js.map +1 -0
  26. package/dist/bottom-sheet/native.d.ts +11 -0
  27. package/dist/bottom-sheet/native.d.ts.map +1 -0
  28. package/dist/bottom-sheet/native.js +173 -0
  29. package/dist/bottom-sheet/native.js.map +1 -0
  30. package/dist/config.d.ts +9 -0
  31. package/dist/config.d.ts.map +1 -1
  32. package/dist/config.js +40 -1
  33. package/dist/config.js.map +1 -1
  34. package/dist/decay.d.ts +1 -0
  35. package/dist/decay.d.ts.map +1 -1
  36. package/dist/decay.js +7 -0
  37. package/dist/decay.js.map +1 -1
  38. package/dist/drag-physics.d.ts +6 -1
  39. package/dist/drag-physics.d.ts.map +1 -1
  40. package/dist/drag.d.ts +17 -3
  41. package/dist/drag.d.ts.map +1 -1
  42. package/dist/drag.js +34 -11
  43. package/dist/drag.js.map +1 -1
  44. package/dist/driver/android-gradient.d.ts +5 -0
  45. package/dist/driver/android-gradient.d.ts.map +1 -0
  46. package/dist/driver/android-gradient.js +99 -0
  47. package/dist/driver/android-gradient.js.map +1 -0
  48. package/dist/driver/android-particles.d.ts +6 -0
  49. package/dist/driver/android-particles.d.ts.map +1 -0
  50. package/dist/driver/android-particles.js +93 -0
  51. package/dist/driver/android-particles.js.map +1 -0
  52. package/dist/driver/android.d.ts.map +1 -1
  53. package/dist/driver/android.js +27 -1
  54. package/dist/driver/android.js.map +1 -1
  55. package/dist/driver/frame.d.ts +3 -0
  56. package/dist/driver/frame.d.ts.map +1 -0
  57. package/dist/driver/frame.js +7 -0
  58. package/dist/driver/frame.js.map +1 -0
  59. package/dist/driver/index.d.ts +4 -0
  60. package/dist/driver/index.d.ts.map +1 -1
  61. package/dist/driver/index.js.map +1 -1
  62. package/dist/driver/ios-gradient.d.ts +5 -0
  63. package/dist/driver/ios-gradient.d.ts.map +1 -0
  64. package/dist/driver/ios-gradient.js +131 -0
  65. package/dist/driver/ios-gradient.js.map +1 -0
  66. package/dist/driver/ios-scroll-delegate.d.ts +4 -0
  67. package/dist/driver/ios-scroll-delegate.d.ts.map +1 -0
  68. package/dist/driver/ios-scroll-delegate.js +26 -0
  69. package/dist/driver/ios-scroll-delegate.js.map +1 -0
  70. package/dist/driver/ios.d.ts.map +1 -1
  71. package/dist/driver/ios.js +9 -0
  72. package/dist/driver/ios.js.map +1 -1
  73. package/dist/easing.d.ts +3 -1
  74. package/dist/easing.d.ts.map +1 -1
  75. package/dist/easing.js +18 -1
  76. package/dist/easing.js.map +1 -1
  77. package/dist/engine.d.ts +31 -2
  78. package/dist/engine.d.ts.map +1 -1
  79. package/dist/engine.js +194 -42
  80. package/dist/engine.js.map +1 -1
  81. package/dist/gesture-native.d.ts +28 -0
  82. package/dist/gesture-native.d.ts.map +1 -0
  83. package/dist/gesture-native.js +61 -0
  84. package/dist/gesture-native.js.map +1 -0
  85. package/dist/gestures/index.d.ts +69 -0
  86. package/dist/gestures/index.d.ts.map +1 -0
  87. package/dist/gestures/index.js +262 -0
  88. package/dist/gestures/index.js.map +1 -0
  89. package/dist/glass/index.d.ts +55 -0
  90. package/dist/glass/index.d.ts.map +1 -0
  91. package/dist/glass/index.js +205 -0
  92. package/dist/glass/index.js.map +1 -0
  93. package/dist/gradient-binding.d.ts +38 -0
  94. package/dist/gradient-binding.d.ts.map +1 -0
  95. package/dist/gradient-binding.js +128 -0
  96. package/dist/gradient-binding.js.map +1 -0
  97. package/dist/gradient.d.ts +105 -0
  98. package/dist/gradient.d.ts.map +1 -0
  99. package/dist/gradient.js +514 -0
  100. package/dist/gradient.js.map +1 -0
  101. package/dist/gravity.d.ts +13 -0
  102. package/dist/gravity.d.ts.map +1 -0
  103. package/dist/gravity.js +84 -0
  104. package/dist/gravity.js.map +1 -0
  105. package/dist/haptics.d.ts.map +1 -1
  106. package/dist/haptics.js +101 -28
  107. package/dist/haptics.js.map +1 -1
  108. package/dist/image-effect.d.ts +1 -0
  109. package/dist/image-effect.d.ts.map +1 -1
  110. package/dist/image-effect.js +10 -2
  111. package/dist/image-effect.js.map +1 -1
  112. package/dist/index.d.ts +19 -7
  113. package/dist/index.d.ts.map +1 -1
  114. package/dist/index.js +10 -4
  115. package/dist/index.js.map +1 -1
  116. package/dist/inspector/index.d.ts +86 -0
  117. package/dist/inspector/index.d.ts.map +1 -0
  118. package/dist/inspector/index.js +419 -0
  119. package/dist/inspector/index.js.map +1 -0
  120. package/dist/inspector/plot.d.ts +4 -0
  121. package/dist/inspector/plot.d.ts.map +1 -0
  122. package/dist/inspector/plot.js +23 -0
  123. package/dist/inspector/plot.js.map +1 -0
  124. package/dist/inspector/probe.d.ts +19 -0
  125. package/dist/inspector/probe.d.ts.map +1 -0
  126. package/dist/inspector/probe.js +37 -0
  127. package/dist/inspector/probe.js.map +1 -0
  128. package/dist/inspector/tuning.d.ts +19 -0
  129. package/dist/inspector/tuning.d.ts.map +1 -0
  130. package/dist/inspector/tuning.js +37 -0
  131. package/dist/inspector/tuning.js.map +1 -0
  132. package/dist/interactive-navigation/index.d.ts +44 -0
  133. package/dist/interactive-navigation/index.d.ts.map +1 -0
  134. package/dist/interactive-navigation/index.js +350 -0
  135. package/dist/interactive-navigation/index.js.map +1 -0
  136. package/dist/keyboard.d.ts +24 -0
  137. package/dist/keyboard.d.ts.map +1 -1
  138. package/dist/keyboard.js +199 -6
  139. package/dist/keyboard.js.map +1 -1
  140. package/dist/live-spring-driver.d.ts +52 -0
  141. package/dist/live-spring-driver.d.ts.map +1 -0
  142. package/dist/live-spring-driver.js +104 -0
  143. package/dist/live-spring-driver.js.map +1 -0
  144. package/dist/mixer.d.ts +55 -0
  145. package/dist/mixer.d.ts.map +1 -0
  146. package/dist/mixer.js +286 -0
  147. package/dist/mixer.js.map +1 -0
  148. package/dist/motion-scope.d.ts +8 -2
  149. package/dist/motion-scope.d.ts.map +1 -1
  150. package/dist/motion-scope.js +24 -3
  151. package/dist/motion-scope.js.map +1 -1
  152. package/dist/motion-states.d.ts +19 -7
  153. package/dist/motion-states.d.ts.map +1 -1
  154. package/dist/motion-states.js +116 -26
  155. package/dist/motion-states.js.map +1 -1
  156. package/dist/motion-value.d.ts +227 -0
  157. package/dist/motion-value.d.ts.map +1 -0
  158. package/dist/motion-value.js +1074 -0
  159. package/dist/motion-value.js.map +1 -0
  160. package/dist/native/index.d.ts +10 -0
  161. package/dist/native/index.d.ts.map +1 -0
  162. package/dist/native/index.js +6 -0
  163. package/dist/native/index.js.map +1 -0
  164. package/dist/native-properties.d.ts +28 -0
  165. package/dist/native-properties.d.ts.map +1 -0
  166. package/dist/native-properties.js +154 -0
  167. package/dist/native-properties.js.map +1 -0
  168. package/dist/native-property-driver.d.ts +19 -0
  169. package/dist/native-property-driver.d.ts.map +1 -0
  170. package/dist/native-property-driver.js +69 -0
  171. package/dist/native-property-driver.js.map +1 -0
  172. package/dist/native-property.d.ts +37 -0
  173. package/dist/native-property.d.ts.map +1 -0
  174. package/dist/native-property.js +285 -0
  175. package/dist/native-property.js.map +1 -0
  176. package/dist/particles.d.ts +5 -2
  177. package/dist/particles.d.ts.map +1 -1
  178. package/dist/particles.js +16 -10
  179. package/dist/particles.js.map +1 -1
  180. package/dist/path.d.ts.map +1 -1
  181. package/dist/path.js +2 -2
  182. package/dist/path.js.map +1 -1
  183. package/dist/physics/index.d.ts +139 -0
  184. package/dist/physics/index.d.ts.map +1 -0
  185. package/dist/physics/index.js +316 -0
  186. package/dist/physics/index.js.map +1 -0
  187. package/dist/physics/native.d.ts +54 -0
  188. package/dist/physics/native.d.ts.map +1 -0
  189. package/dist/physics/native.js +64 -0
  190. package/dist/physics/native.js.map +1 -0
  191. package/dist/playback-group.d.ts.map +1 -1
  192. package/dist/playback-group.js +17 -1
  193. package/dist/playback-group.js.map +1 -1
  194. package/dist/playback.d.ts +15 -0
  195. package/dist/playback.d.ts.map +1 -1
  196. package/dist/playback.js +23 -0
  197. package/dist/playback.js.map +1 -1
  198. package/dist/predictive-back/index.d.ts +45 -0
  199. package/dist/predictive-back/index.d.ts.map +1 -0
  200. package/dist/predictive-back/index.js +220 -0
  201. package/dist/predictive-back/index.js.map +1 -0
  202. package/dist/predictive-back/presentation.d.ts +4 -0
  203. package/dist/predictive-back/presentation.d.ts.map +1 -0
  204. package/dist/predictive-back/presentation.js +3 -0
  205. package/dist/predictive-back/presentation.js.map +1 -0
  206. package/dist/press.d.ts.map +1 -1
  207. package/dist/press.js +11 -2
  208. package/dist/press.js.map +1 -1
  209. package/dist/reorder/handle.d.ts +6 -0
  210. package/dist/reorder/handle.d.ts.map +1 -0
  211. package/dist/reorder/handle.js +10 -0
  212. package/dist/reorder/handle.js.map +1 -0
  213. package/dist/reorder/index.d.ts +10 -0
  214. package/dist/reorder/index.d.ts.map +1 -0
  215. package/dist/reorder/index.js +233 -0
  216. package/dist/reorder/index.js.map +1 -0
  217. package/dist/reorder/list-view.d.ts +5 -0
  218. package/dist/reorder/list-view.d.ts.map +1 -0
  219. package/dist/reorder/list-view.js +238 -0
  220. package/dist/reorder/list-view.js.map +1 -0
  221. package/dist/reorder/model.d.ts +6 -0
  222. package/dist/reorder/model.d.ts.map +1 -0
  223. package/dist/reorder/model.js +30 -0
  224. package/dist/reorder/model.js.map +1 -0
  225. package/dist/reorder/surface.d.ts +6 -0
  226. package/dist/reorder/surface.d.ts.map +1 -0
  227. package/dist/reorder/surface.js +10 -0
  228. package/dist/reorder/surface.js.map +1 -0
  229. package/dist/reorder/types.d.ts +92 -0
  230. package/dist/reorder/types.d.ts.map +1 -0
  231. package/dist/reorder/types.js +2 -0
  232. package/dist/reorder/types.js.map +1 -0
  233. package/dist/sampling.d.ts +35 -0
  234. package/dist/sampling.d.ts.map +1 -0
  235. package/dist/sampling.js +123 -0
  236. package/dist/sampling.js.map +1 -0
  237. package/dist/scene-appearance.d.ts +14 -0
  238. package/dist/scene-appearance.d.ts.map +1 -0
  239. package/dist/scene-appearance.js +68 -0
  240. package/dist/scene-appearance.js.map +1 -0
  241. package/dist/scene-camera.d.ts +5 -0
  242. package/dist/scene-camera.d.ts.map +1 -0
  243. package/dist/scene-camera.js +23 -0
  244. package/dist/scene-camera.js.map +1 -0
  245. package/dist/scene-shader.d.ts +18 -0
  246. package/dist/scene-shader.d.ts.map +1 -0
  247. package/dist/scene-shader.js +76 -0
  248. package/dist/scene-shader.js.map +1 -0
  249. package/dist/scroll-header/geometry.d.ts +18 -0
  250. package/dist/scroll-header/geometry.d.ts.map +1 -0
  251. package/dist/scroll-header/geometry.js +46 -0
  252. package/dist/scroll-header/geometry.js.map +1 -0
  253. package/dist/scroll-header/index.d.ts +48 -0
  254. package/dist/scroll-header/index.d.ts.map +1 -0
  255. package/dist/scroll-header/index.js +399 -0
  256. package/dist/scroll-header/index.js.map +1 -0
  257. package/dist/scroll-header/native.d.ts +28 -0
  258. package/dist/scroll-header/native.d.ts.map +1 -0
  259. package/dist/scroll-header/native.js +43 -0
  260. package/dist/scroll-header/native.js.map +1 -0
  261. package/dist/sensors/index.d.ts +69 -0
  262. package/dist/sensors/index.d.ts.map +1 -0
  263. package/dist/sensors/index.js +149 -0
  264. package/dist/sensors/index.js.map +1 -0
  265. package/dist/sensors/native.d.ts +20 -0
  266. package/dist/sensors/native.d.ts.map +1 -0
  267. package/dist/sensors/native.js +48 -0
  268. package/dist/sensors/native.js.map +1 -0
  269. package/dist/sequence.d.ts +24 -0
  270. package/dist/sequence.d.ts.map +1 -1
  271. package/dist/sequence.js +181 -19
  272. package/dist/sequence.js.map +1 -1
  273. package/dist/shapes/android.d.ts +3 -0
  274. package/dist/shapes/android.d.ts.map +1 -0
  275. package/dist/shapes/android.js +51 -0
  276. package/dist/shapes/android.js.map +1 -0
  277. package/dist/shapes/index.d.ts +6 -0
  278. package/dist/shapes/index.d.ts.map +1 -0
  279. package/dist/shapes/index.js +238 -0
  280. package/dist/shapes/index.js.map +1 -0
  281. package/dist/shapes/ios.d.ts +3 -0
  282. package/dist/shapes/ios.d.ts.map +1 -0
  283. package/dist/shapes/ios.js +164 -0
  284. package/dist/shapes/ios.js.map +1 -0
  285. package/dist/shapes/native.d.ts +18 -0
  286. package/dist/shapes/native.d.ts.map +1 -0
  287. package/dist/shapes/native.js +10 -0
  288. package/dist/shapes/native.js.map +1 -0
  289. package/dist/shapes/path.d.ts +10 -0
  290. package/dist/shapes/path.d.ts.map +1 -0
  291. package/dist/shapes/path.js +106 -0
  292. package/dist/shapes/path.js.map +1 -0
  293. package/dist/shapes/types.d.ts +55 -0
  294. package/dist/shapes/types.d.ts.map +1 -0
  295. package/dist/shapes/types.js +11 -0
  296. package/dist/shapes/types.js.map +1 -0
  297. package/dist/shared-layout/index.d.ts +40 -0
  298. package/dist/shared-layout/index.d.ts.map +1 -0
  299. package/dist/shared-layout/index.js +267 -0
  300. package/dist/shared-layout/index.js.map +1 -0
  301. package/dist/shared-layout/native.d.ts +15 -0
  302. package/dist/shared-layout/native.d.ts.map +1 -0
  303. package/dist/shared-layout/native.js +79 -0
  304. package/dist/shared-layout/native.js.map +1 -0
  305. package/dist/shared-layout/timing.d.ts +9 -0
  306. package/dist/shared-layout/timing.d.ts.map +1 -0
  307. package/dist/shared-layout/timing.js +68 -0
  308. package/dist/shared-layout/timing.js.map +1 -0
  309. package/dist/shared-navigation/entry.d.ts +51 -0
  310. package/dist/shared-navigation/entry.d.ts.map +1 -0
  311. package/dist/shared-navigation/entry.js +619 -0
  312. package/dist/shared-navigation/entry.js.map +1 -0
  313. package/dist/shared-navigation/index.d.ts +58 -0
  314. package/dist/shared-navigation/index.d.ts.map +1 -0
  315. package/dist/shared-navigation/index.js +318 -0
  316. package/dist/shared-navigation/index.js.map +1 -0
  317. package/dist/shared-navigation/return-signal.d.ts +16 -0
  318. package/dist/shared-navigation/return-signal.d.ts.map +1 -0
  319. package/dist/shared-navigation/return-signal.js +35 -0
  320. package/dist/shared-navigation/return-signal.js.map +1 -0
  321. package/dist/shared-navigation/return-target.d.ts +32 -0
  322. package/dist/shared-navigation/return-target.d.ts.map +1 -0
  323. package/dist/shared-navigation/return-target.js +168 -0
  324. package/dist/shared-navigation/return-target.js.map +1 -0
  325. package/dist/shared-navigation/scope.d.ts +4 -0
  326. package/dist/shared-navigation/scope.d.ts.map +1 -0
  327. package/dist/shared-navigation/scope.js +2 -0
  328. package/dist/shared-navigation/scope.js.map +1 -0
  329. package/dist/shared-navigation/targets.d.ts +6 -0
  330. package/dist/shared-navigation/targets.d.ts.map +1 -0
  331. package/dist/shared-navigation/targets.js +36 -0
  332. package/dist/shared-navigation/targets.js.map +1 -0
  333. package/dist/size-layout.d.ts +19 -0
  334. package/dist/size-layout.d.ts.map +1 -0
  335. package/dist/size-layout.js +216 -0
  336. package/dist/size-layout.js.map +1 -0
  337. package/dist/size.d.ts +19 -0
  338. package/dist/size.d.ts.map +1 -0
  339. package/dist/size.js +251 -0
  340. package/dist/size.js.map +1 -0
  341. package/dist/spring.d.ts +2 -0
  342. package/dist/spring.d.ts.map +1 -1
  343. package/dist/spring.js +11 -0
  344. package/dist/spring.js.map +1 -1
  345. package/dist/svg-path.d.ts +18 -0
  346. package/dist/svg-path.d.ts.map +1 -1
  347. package/dist/svg-path.js +3 -2
  348. package/dist/svg-path.js.map +1 -1
  349. package/dist/testing/clock.d.ts +40 -0
  350. package/dist/testing/clock.d.ts.map +1 -0
  351. package/dist/testing/clock.js +116 -0
  352. package/dist/testing/clock.js.map +1 -0
  353. package/dist/testing/handoff-recorder.d.ts +8 -0
  354. package/dist/testing/handoff-recorder.d.ts.map +1 -0
  355. package/dist/testing/handoff-recorder.js +77 -0
  356. package/dist/testing/handoff-recorder.js.map +1 -0
  357. package/dist/testing/index.d.ts +5 -0
  358. package/dist/testing/index.d.ts.map +1 -0
  359. package/dist/testing/index.js +5 -0
  360. package/dist/testing/index.js.map +1 -0
  361. package/dist/testing/native.d.ts +46 -0
  362. package/dist/testing/native.d.ts.map +1 -0
  363. package/dist/testing/native.js +313 -0
  364. package/dist/testing/native.js.map +1 -0
  365. package/dist/testing/presentation.d.ts +11 -0
  366. package/dist/testing/presentation.d.ts.map +1 -0
  367. package/dist/testing/presentation.js +45 -0
  368. package/dist/testing/presentation.js.map +1 -0
  369. package/dist/testing/replay.d.ts +39 -0
  370. package/dist/testing/replay.d.ts.map +1 -0
  371. package/dist/testing/replay.js +99 -0
  372. package/dist/testing/replay.js.map +1 -0
  373. package/dist/testing/scroll-handoff-native.d.ts +10 -0
  374. package/dist/testing/scroll-handoff-native.d.ts.map +1 -0
  375. package/dist/testing/scroll-handoff-native.js +151 -0
  376. package/dist/testing/scroll-handoff-native.js.map +1 -0
  377. package/dist/testing/scroll-handoff.d.ts +25 -0
  378. package/dist/testing/scroll-handoff.d.ts.map +1 -0
  379. package/dist/testing/scroll-handoff.js +127 -0
  380. package/dist/testing/scroll-handoff.js.map +1 -0
  381. package/dist/testing/sensors.d.ts +13 -0
  382. package/dist/testing/sensors.d.ts.map +1 -0
  383. package/dist/testing/sensors.js +26 -0
  384. package/dist/testing/sensors.js.map +1 -0
  385. package/dist/testing/trace.d.ts +101 -0
  386. package/dist/testing/trace.d.ts.map +1 -0
  387. package/dist/testing/trace.js +263 -0
  388. package/dist/testing/trace.js.map +1 -0
  389. package/dist/timed-animation.d.ts +38 -0
  390. package/dist/timed-animation.d.ts.map +1 -0
  391. package/dist/timed-animation.js +177 -0
  392. package/dist/timed-animation.js.map +1 -0
  393. package/dist/track.d.ts +3 -0
  394. package/dist/track.d.ts.map +1 -1
  395. package/dist/track.js +281 -40
  396. package/dist/track.js.map +1 -1
  397. package/dist/transition.d.ts +54 -2
  398. package/dist/transition.d.ts.map +1 -1
  399. package/dist/transition.js +128 -8
  400. package/dist/transition.js.map +1 -1
  401. package/dist/types.d.ts +10 -1
  402. package/dist/types.d.ts.map +1 -1
  403. package/dist/value-observers.d.ts +22 -0
  404. package/dist/value-observers.d.ts.map +1 -0
  405. package/dist/value-observers.js +122 -0
  406. package/dist/value-observers.js.map +1 -0
  407. package/dist/value-track.d.ts +13 -0
  408. package/dist/value-track.d.ts.map +1 -0
  409. package/dist/value-track.js +59 -0
  410. package/dist/value-track.js.map +1 -0
  411. package/dist/vue/index.d.ts +33 -3
  412. package/dist/vue/index.d.ts.map +1 -1
  413. package/dist/vue/index.js +118 -3
  414. package/dist/vue/index.js.map +1 -1
  415. package/dist/zoomable.d.ts +1 -1
  416. package/dist/zoomable.d.ts.map +1 -1
  417. package/package.json +68 -3
  418. package/platforms/android/include.gradle +10 -0
  419. package/platforms/android/java/org/rafaelaugusto/jolt/BlurEffect.java +89 -0
  420. package/platforms/android/java/org/rafaelaugusto/jolt/CircleMath.java +158 -0
  421. package/platforms/android/java/org/rafaelaugusto/jolt/CircleWorld.java +221 -0
  422. package/platforms/android/java/org/rafaelaugusto/jolt/GestureSession.java +227 -0
  423. package/platforms/android/java/org/rafaelaugusto/jolt/GestureSurface.java +54 -0
  424. package/platforms/android/java/org/rafaelaugusto/jolt/GradientLayer.java +224 -0
  425. package/platforms/android/java/org/rafaelaugusto/jolt/KeyboardFrame.java +53 -0
  426. package/platforms/android/java/org/rafaelaugusto/jolt/KeyboardFrameFollower.java +57 -0
  427. package/platforms/android/java/org/rafaelaugusto/jolt/KeyboardObserver.java +97 -0
  428. package/platforms/android/java/org/rafaelaugusto/jolt/LiveSpring.java +277 -0
  429. package/platforms/android/java/org/rafaelaugusto/jolt/MotionProbe.java +70 -0
  430. package/platforms/android/java/org/rafaelaugusto/jolt/ParticleEmitter.java +192 -0
  431. package/platforms/android/java/org/rafaelaugusto/jolt/ParticleSimulation.java +114 -0
  432. package/platforms/android/java/org/rafaelaugusto/jolt/PredictiveBackSession.java +212 -0
  433. package/platforms/android/java/org/rafaelaugusto/jolt/ReorderHandle.java +25 -0
  434. package/platforms/android/java/org/rafaelaugusto/jolt/ReorderSession.java +213 -0
  435. package/platforms/android/java/org/rafaelaugusto/jolt/ReorderSurface.java +27 -0
  436. package/platforms/android/java/org/rafaelaugusto/jolt/ScrollHeader.java +84 -0
  437. package/platforms/android/java/org/rafaelaugusto/jolt/SensorMath.java +28 -0
  438. package/platforms/android/java/org/rafaelaugusto/jolt/SensorSource.java +217 -0
  439. package/platforms/android/java/org/rafaelaugusto/jolt/ShapeLayer.java +120 -0
  440. package/platforms/android/java/org/rafaelaugusto/jolt/SharedLayoutFlight.java +287 -0
  441. package/platforms/android/java/org/rafaelaugusto/jolt/SharedNavigationScene.java +115 -0
  442. package/platforms/android/java/org/rafaelaugusto/jolt/SpringState.java +39 -0
  443. package/platforms/android/proguard-rules.pro +20 -0
  444. package/platforms/ios/build.xcconfig +1 -1
  445. package/platforms/ios/src/JoltBlur.h +14 -0
  446. package/platforms/ios/src/JoltBlur.m +86 -0
  447. package/platforms/ios/src/JoltCircleMath.h +191 -0
  448. package/platforms/ios/src/JoltCircleWorld.h +18 -0
  449. package/platforms/ios/src/JoltCircleWorld.m +218 -0
  450. package/platforms/ios/src/JoltGestureSession.h +23 -0
  451. package/platforms/ios/src/JoltGestureSession.m +251 -0
  452. package/platforms/ios/src/JoltInteractiveNavigation.h +23 -0
  453. package/platforms/ios/src/JoltInteractiveNavigation.m +255 -0
  454. package/platforms/ios/src/JoltLiveSpring.h +29 -0
  455. package/platforms/ios/src/JoltLiveSpring.m +243 -0
  456. package/platforms/ios/src/JoltMotionProbe.h +9 -0
  457. package/platforms/ios/src/JoltMotionProbe.m +72 -0
  458. package/platforms/ios/src/JoltReorderSession.h +15 -0
  459. package/platforms/ios/src/JoltReorderSession.m +205 -0
  460. package/platforms/ios/src/JoltScrollHeader.h +13 -0
  461. package/platforms/ios/src/JoltScrollHeader.m +101 -0
  462. package/platforms/ios/src/JoltSensorMath.h +39 -0
  463. package/platforms/ios/src/JoltSensorSource.h +13 -0
  464. package/platforms/ios/src/JoltSensorSource.m +201 -0
  465. package/platforms/ios/src/JoltSharedLayoutFlight.h +19 -0
  466. package/platforms/ios/src/JoltSharedLayoutFlight.m +250 -0
  467. package/platforms/ios/src/JoltSpringState.h +35 -0
  468. package/platforms/ios/src/module.modulemap +10 -0
  469. package/src/android-plugin.d.ts +464 -0
  470. package/src/animate.ts +129 -15
  471. package/src/blur/index.ts +195 -0
  472. package/src/blur/native.ts +70 -0
  473. package/src/blur/types.ts +32 -0
  474. package/src/bottom-sheet/geometry.ts +84 -0
  475. package/src/bottom-sheet/index.ts +536 -0
  476. package/src/bottom-sheet/native.ts +214 -0
  477. package/src/config.ts +39 -1
  478. package/src/decay.ts +9 -0
  479. package/src/drag.ts +67 -21
  480. package/src/driver/android-gradient.ts +116 -0
  481. package/src/driver/android-particles.ts +118 -0
  482. package/src/driver/android.ts +31 -1
  483. package/src/driver/frame.ts +10 -0
  484. package/src/driver/index.ts +4 -0
  485. package/src/driver/ios-gradient.ts +136 -0
  486. package/src/driver/ios-scroll-delegate.ts +23 -0
  487. package/src/driver/ios.ts +10 -0
  488. package/src/easing.ts +21 -1
  489. package/src/engine.ts +209 -60
  490. package/src/gesture-native.ts +139 -0
  491. package/src/gestures/index.ts +365 -0
  492. package/src/glass/index.ts +218 -0
  493. package/src/gradient-binding.ts +158 -0
  494. package/src/gradient.ts +663 -0
  495. package/src/gravity.ts +107 -0
  496. package/src/haptics.ts +106 -28
  497. package/src/image-effect.ts +10 -2
  498. package/src/index.ts +56 -7
  499. package/src/inspector/index.ts +523 -0
  500. package/src/inspector/plot.ts +27 -0
  501. package/src/inspector/probe.ts +50 -0
  502. package/src/inspector/tuning.ts +51 -0
  503. package/src/interactive-navigation/index.ts +427 -0
  504. package/src/ios-plugin.d.ts +280 -0
  505. package/src/keyboard.ts +231 -7
  506. package/src/live-spring-driver.ts +181 -0
  507. package/src/mixer.ts +312 -0
  508. package/src/motion-scope.ts +39 -6
  509. package/src/motion-states.ts +149 -42
  510. package/src/motion-value.ts +1289 -0
  511. package/src/native/index.ts +30 -0
  512. package/src/native-properties.ts +188 -0
  513. package/src/native-property-driver.ts +123 -0
  514. package/src/native-property.ts +366 -0
  515. package/src/particles.ts +18 -17
  516. package/src/path.ts +2 -1
  517. package/src/physics/index.ts +476 -0
  518. package/src/physics/native.ts +121 -0
  519. package/src/playback-group.ts +17 -1
  520. package/src/playback.ts +41 -0
  521. package/src/predictive-back/index.ts +280 -0
  522. package/src/predictive-back/presentation.ts +6 -0
  523. package/src/press.ts +10 -2
  524. package/src/reorder/handle.ts +9 -0
  525. package/src/reorder/index.ts +243 -0
  526. package/src/reorder/list-view.ts +262 -0
  527. package/src/reorder/model.ts +47 -0
  528. package/src/reorder/surface.ts +10 -0
  529. package/src/reorder/types.ts +87 -0
  530. package/src/sampling.ts +173 -0
  531. package/src/scene-appearance.ts +92 -0
  532. package/src/scene-camera.ts +30 -0
  533. package/src/scene-shader.ts +139 -0
  534. package/src/scroll-header/geometry.ts +88 -0
  535. package/src/scroll-header/index.ts +530 -0
  536. package/src/scroll-header/native.ts +89 -0
  537. package/src/sensors/index.ts +246 -0
  538. package/src/sensors/native.ts +72 -0
  539. package/src/sequence.ts +209 -20
  540. package/src/shapes/android.ts +63 -0
  541. package/src/shapes/index.ts +267 -0
  542. package/src/shapes/ios.ts +194 -0
  543. package/src/shapes/native.ts +27 -0
  544. package/src/shapes/path.ts +127 -0
  545. package/src/shapes/types.ts +63 -0
  546. package/src/shared-layout/index.ts +343 -0
  547. package/src/shared-layout/native.ts +138 -0
  548. package/src/shared-layout/timing.ts +87 -0
  549. package/src/shared-navigation/entry.ts +695 -0
  550. package/src/shared-navigation/index.ts +414 -0
  551. package/src/shared-navigation/return-signal.ts +41 -0
  552. package/src/shared-navigation/return-target.ts +197 -0
  553. package/src/shared-navigation/scope.ts +3 -0
  554. package/src/shared-navigation/targets.ts +38 -0
  555. package/src/size-layout.ts +237 -0
  556. package/src/size.ts +302 -0
  557. package/src/spring.ts +18 -0
  558. package/src/svg-path.ts +8 -3
  559. package/src/testing/clock.ts +128 -0
  560. package/src/testing/handoff-recorder.ts +98 -0
  561. package/src/testing/index.ts +4 -0
  562. package/src/testing/native.ts +386 -0
  563. package/src/testing/presentation.ts +46 -0
  564. package/src/testing/replay.ts +149 -0
  565. package/src/testing/scroll-handoff-native.ts +201 -0
  566. package/src/testing/scroll-handoff.ts +140 -0
  567. package/src/testing/sensors.ts +41 -0
  568. package/src/testing/trace.ts +340 -0
  569. package/src/timed-animation.ts +192 -0
  570. package/src/track.ts +334 -38
  571. package/src/transition.ts +197 -9
  572. package/src/types.ts +11 -1
  573. package/src/value-observers.ts +147 -0
  574. package/src/value-track.ts +71 -0
  575. package/src/vue/index.ts +147 -1
  576. package/src/zoomable.ts +1 -1
@@ -0,0 +1,255 @@
1
+ #import "JoltInteractiveNavigation.h"
2
+ #import "JoltSpringState.h"
3
+ #import "JoltSharedLayoutFlight.h"
4
+
5
+ @interface JoltInteractiveNavigation () {
6
+ JoltSpringState _spring;
7
+ }
8
+ @property(nonatomic, weak) UINavigationController *navigation;
9
+ @property(nonatomic, weak) UIViewController *presented;
10
+ @property(nonatomic) UIScreenEdgePanGestureRecognizer *pan;
11
+ @property(nonatomic, copy) BOOL (^shouldBegin)(void);
12
+ @property(nonatomic, copy) void (^onEvent)(NSInteger);
13
+ @property(nonatomic) id<UIViewControllerContextTransitioning> context;
14
+ @property(nonatomic) UIView *fromView, *toView, *shade;
15
+ @property(nonatomic) CGAffineTransform fromTransform, toTransform;
16
+ @property(nonatomic) CGFloat fromAlpha, toAlpha;
17
+ @property(nonatomic) JoltSharedLayoutFlight *sharedFlight;
18
+ @property(nonatomic) CGRect bounds;
19
+ @property(nonatomic) CADisplayLink *link;
20
+ @property(nonatomic) double stiffness, damping, mass, started, previous, target, direction, timeScale;
21
+ @property(nonatomic) NSInteger operation;
22
+ @property(nonatomic) NSNumber *pendingEnd;
23
+ @property(nonatomic, readwrite) BOOL interactive;
24
+ @property(nonatomic) BOOL reduced, settling, committed, disposed, suppressed, sharedPending;
25
+ @property(nonatomic) double pendingStarted, rawProgress, gestureOffset;
26
+ @end
27
+
28
+ @implementation JoltInteractiveNavigation
29
+ static NSUInteger active = 0, recognizers = 0;
30
+ + (NSUInteger)activeCount { return active; }
31
+ + (NSUInteger)recognizerCount { return recognizers; }
32
+ + (instancetype)attach:(UINavigationController *)navigation stiffness:(double)stiffness
33
+ damping:(double)damping mass:(double)mass
34
+ shouldBegin:(BOOL (^)(void))shouldBegin onEvent:(void (^)(NSInteger))onEvent {
35
+ JoltInteractiveNavigation *owner = [self new];
36
+ owner.navigation = navigation;
37
+ owner.stiffness = stiffness; owner.damping = damping; owner.mass = mass;
38
+ owner.shouldBegin = shouldBegin; owner.onEvent = onEvent;
39
+ owner.pan = [[UIScreenEdgePanGestureRecognizer alloc] initWithTarget:owner action:@selector(pan:)];
40
+ owner.pan.delegate = owner;
41
+ owner.direction = navigation.view.effectiveUserInterfaceLayoutDirection == UIUserInterfaceLayoutDirectionRightToLeft ? -1 : 1;
42
+ owner.pan.edges = owner.direction < 0 ? UIRectEdgeRight : UIRectEdgeLeft;
43
+ [navigation.view addGestureRecognizer:owner.pan];
44
+ recognizers++;
45
+ [[NSNotificationCenter defaultCenter] addObserver:owner selector:@selector(cancel) name:UIApplicationWillResignActiveNotification object:nil];
46
+ return owner;
47
+ }
48
+ - (UIGestureRecognizer *)contentPop {
49
+ // The full-content pop gesture was added in iOS 26. Keep older SDKs compatible.
50
+ if ([self.navigation respondsToSelector:NSSelectorFromString(@"interactiveContentPopGestureRecognizer")])
51
+ return [self.navigation valueForKey:@"interactiveContentPopGestureRecognizer"];
52
+ return nil;
53
+ }
54
+ - (void)sync {
55
+ if (self.disposed || self.navigation.topViewController != self.presented) return;
56
+ if (!self.suppressed) {
57
+ self.suppressed = YES;
58
+ }
59
+ self.navigation.interactivePopGestureRecognizer.enabled = NO;
60
+ self.contentPop.enabled = NO;
61
+ }
62
+ - (void)prepareOperation:(NSInteger)operation presented:(UIViewController *)presented reduced:(BOOL)reduced timeScale:(double)timeScale {
63
+ self.operation = operation; self.reduced = reduced;
64
+ self.timeScale = timeScale;
65
+ if (operation == UINavigationControllerOperationPush) self.presented = presented;
66
+ }
67
+ - (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)recognizer {
68
+ CGPoint velocity = [self.pan velocityInView:self.navigation.view];
69
+ return !self.disposed && !self.context && self.navigation.topViewController == self.presented &&
70
+ self.navigation.viewControllers.count > 1 && !self.navigation.transitionCoordinator &&
71
+ velocity.x * self.direction > fabs(velocity.y) && self.shouldBegin && self.shouldBegin();
72
+ }
73
+ - (void)pan:(UIScreenEdgePanGestureRecognizer *)pan {
74
+ if (pan.state == UIGestureRecognizerStateBegan) {
75
+ self.pendingEnd = nil;self.rawProgress=0;self.gestureOffset=0;
76
+ self.interactive = YES;
77
+ if (self.onEvent) self.onEvent(2); // JS enters Core's interactive state and invokes its pop callback once.
78
+ // UIKit may deliver startInteractiveTransition on the next main-loop turn.
79
+ // Keep the interactive request alive until that context arrives.
80
+ }
81
+ if (!self.interactive || self.settling) return;
82
+ double width = MAX(1, self.context ? self.bounds.size.width : self.navigation.view.bounds.size.width);
83
+ double progress = MAX(0, MIN(1, [pan translationInView:self.navigation.view].x * self.direction / width));
84
+ double velocity = [pan velocityInView:self.navigation.view].x * self.direction / width;
85
+ self.rawProgress=progress;
86
+ double mapped=self.sharedPending?0:MAX(0,MIN(1,(progress-self.gestureOffset)/MAX(.01,1-self.gestureOffset)));
87
+ _spring = (JoltSpringState){mapped, velocity/MAX(.01,1-self.gestureOffset)};
88
+ if (self.context) {
89
+ [self render:_spring.position];
90
+ [self.context updateInteractiveTransition:_spring.position];
91
+ }
92
+ if (pan.state == UIGestureRecognizerStateEnded || pan.state == UIGestureRecognizerStateCancelled || pan.state == UIGestureRecognizerStateFailed) {
93
+ BOOL finish = pan.state == UIGestureRecognizerStateEnded && progress + velocity * .16 > .5;
94
+ if (self.context) [self settle:finish velocity:velocity];
95
+ else self.pendingEnd = @(finish);
96
+ }
97
+ }
98
+ - (NSTimeInterval)transitionDuration:(id<UIViewControllerContextTransitioning>)context { return self.reduced ? 0 : .55; }
99
+ - (BOOL)wantsInteractiveStart { return self.interactive; }
100
+ - (CGFloat)completionSpeed { return 1; }
101
+ - (UIViewAnimationCurve)completionCurve { return UIViewAnimationCurveLinear; }
102
+ - (double)progress { return _spring.position; }
103
+ - (double)velocity { return _spring.velocity; }
104
+ - (void)prepare:(id<UIViewControllerContextTransitioning>)context {
105
+ self.context = context; active++;
106
+ UIViewController *from = [context viewControllerForKey:UITransitionContextFromViewControllerKey];
107
+ UIViewController *to = [context viewControllerForKey:UITransitionContextToViewControllerKey];
108
+ self.fromView = [context viewForKey:UITransitionContextFromViewKey] ?: from.view;
109
+ self.toView = [context viewForKey:UITransitionContextToViewKey] ?: to.view;
110
+ self.fromTransform = self.fromView.transform; self.toTransform = self.toView.transform;
111
+ self.fromAlpha = self.fromView.alpha; self.toAlpha = self.toView.alpha;
112
+ self.toView.frame = [context finalFrameForViewController:to];
113
+ UIView *container = context.containerView;
114
+ if (self.operation == UINavigationControllerOperationPush) [container addSubview:self.toView];
115
+ else [container insertSubview:self.toView belowSubview:self.fromView];
116
+ [self.toView setNeedsLayout];
117
+ // A recycled page may still be rebuilding its JS-backed data source. Let
118
+ // the deferred provider cross Core's layout boundary before forcing UIKit.
119
+ if(!self.sharedDeferred)[self.toView layoutIfNeeded];
120
+ self.bounds = container.bounds;
121
+ self.sharedPending=self.sharedDeferred;self.pendingStarted=CACurrentMediaTime();
122
+ // One setup callback after UIKit lays out both pages; subsequent progress stays native.
123
+ if(self.sharedEnabled && self.onEvent)self.onEvent(8);
124
+ self.shade = [[UIView alloc] initWithFrame:self.bounds];
125
+ self.shade.backgroundColor = UIColor.blackColor;
126
+ self.shade.userInteractionEnabled = NO; self.shade.isAccessibilityElement = NO;
127
+ [container insertSubview:self.shade belowSubview:self.operation == UINavigationControllerOperationPush ? self.toView : self.fromView];
128
+ _spring = (JoltSpringState){0, 0};
129
+ [self render:0];
130
+ }
131
+ - (void)startInteractiveTransition:(id<UIViewControllerContextTransitioning>)context {
132
+ JoltSpringState held = _spring;
133
+ [self prepare:context];
134
+ _spring = self.sharedPending?(JoltSpringState){0,held.velocity}:held; [self render:_spring.position];
135
+ [context updateInteractiveTransition:MAX(0, MIN(1, _spring.position))];
136
+ [self startLink]; // Monitors resize/suspension while the finger is held; no JS display callbacks.
137
+ if (self.pendingEnd || self.disposed) {
138
+ [self settle:!self.disposed && self.pendingEnd.boolValue velocity:_spring.velocity];
139
+ self.pendingEnd = nil;
140
+ }
141
+ }
142
+ - (void)animateTransition:(id<UIViewControllerContextTransitioning>)context {
143
+ [self prepare:context];
144
+ if (self.onEvent) self.onEvent(0);
145
+ [self settle:YES velocity:0];
146
+ }
147
+ - (void)render:(double)progress {
148
+ double p = MAX(0, MIN(1, progress)), width = self.bounds.size.width * self.direction;
149
+ BOOL push = self.operation == UINavigationControllerOperationPush;
150
+ [CATransaction begin]; [CATransaction setDisableActions:YES];
151
+ if(self.sharedPending) {
152
+ self.fromView.transform=self.fromTransform;self.toView.transform=self.toTransform;self.fromView.alpha=self.fromAlpha;self.toView.alpha=self.toAlpha;self.shade.alpha=0;
153
+ } else if(self.sharedFlight) {
154
+ self.fromView.alpha = self.fromAlpha * (push ? 1 : 1-p); self.toView.alpha = self.toAlpha * (push ? p : 1);
155
+ self.shade.alpha = 0;
156
+ [self.sharedFlight updateInteractive:p];
157
+ } else if(self.sharedDeferred && !push) {
158
+ // A missing/deleted recycled target fades to the live collection. Do
159
+ // not translate its table while Core is realizing replacement cells.
160
+ self.fromView.alpha=self.fromAlpha*(1-p);self.toView.alpha=self.toAlpha;
161
+ self.shade.alpha=0;
162
+ } else {
163
+ self.fromView.transform = CGAffineTransformConcat(self.fromTransform, CGAffineTransformMakeTranslation(width * (push ? -.25 * p : p), 0));
164
+ self.toView.transform = CGAffineTransformConcat(self.toTransform, CGAffineTransformMakeTranslation(width * (push ? 1 - p : -.25 * (1 - p)), 0));
165
+ self.shade.alpha = .16 * (push ? p : 1 - p);
166
+ }
167
+ [CATransaction commit];
168
+ }
169
+ - (BOOL)prepareSharedFrom:(UIView *)from to:(UIView *)to image:(BOOL)image fromRadius:(double)fromRadius toRadius:(double)toRadius maxPixels:(double)maxPixels {
170
+ if(!self.context || self.reduced || self.sharedFlight || !from || !to)return NO;
171
+ JoltSharedLayoutFlight *flight=image?[JoltSharedLayoutFlight captureNavigationImage:from radius:fromRadius maxPixels:maxPixels]:[JoltSharedLayoutFlight capture:from image:NO radius:fromRadius maxPixels:maxPixels];
172
+ NSString *geometry=image?[flight prepareNavigationImage:to radius:toRadius maxPixels:maxPixels]:[flight prepare:to image:NO radius:toRadius maxPixels:maxPixels];
173
+ if(!geometry || ![flight beginInteractive:geometry]) { [flight dispose]; return NO; }
174
+ self.sharedFlight=flight; return YES;
175
+ }
176
+ - (void)completeSharedPreparation {
177
+ if(!self.context || !self.sharedPending)return;
178
+ self.sharedPending=NO;self.gestureOffset=self.rawProgress;
179
+ _spring.position=0;self.started=CACurrentMediaTime();self.previous=self.started;
180
+ [self render:0];
181
+ if(self.settling && self.reduced)[self finish];
182
+ }
183
+ - (void)startLink {
184
+ if (self.link || !self.context) return;
185
+ self.previous = CACurrentMediaTime();
186
+ self.link = [CADisplayLink displayLinkWithTarget:self selector:@selector(tick:)];
187
+ if (@available(iOS 15.0, *)) {
188
+ float maximum = MIN(120, UIScreen.mainScreen.maximumFramesPerSecond);
189
+ self.link.preferredFrameRateRange = CAFrameRateRangeMake(MIN(80, maximum), maximum, maximum);
190
+ }
191
+ [self.link addToRunLoop:NSRunLoop.mainRunLoop forMode:NSRunLoopCommonModes];
192
+ }
193
+ - (void)settle:(BOOL)finish velocity:(double)velocity {
194
+ if (!self.context || self.settling) return;
195
+ self.committed = finish; self.settling = YES; self.target = finish ? 1 : 0;
196
+ _spring.velocity = velocity;
197
+ if (self.interactive) {
198
+ if (finish) [self.context finishInteractiveTransition]; else [self.context cancelInteractiveTransition];
199
+ if (self.onEvent) self.onEvent(finish ? 3 : 4);
200
+ }
201
+ if (!self.context) return; // An observer may synchronously cancel/dispose at the release boundary.
202
+ self.started = CACurrentMediaTime(); self.previous = self.started;
203
+ if (self.sharedPending && !finish){self.sharedPending=NO;[self finish];return;}
204
+ if ((self.reduced && !self.sharedPending) || self.disposed) { [self finish]; return; }
205
+ [self startLink];
206
+ }
207
+ - (void)tick:(CADisplayLink *)link {
208
+ if (!CGRectEqualToRect(self.bounds, self.context.containerView.bounds) || !self.context.containerView.window) { [self cancel]; return; }
209
+ if(self.sharedFlight && ![self.sharedFlight destinationIsStable]) { [self cancel]; return; }
210
+ if(self.sharedPending){if(CACurrentMediaTime()-self.pendingStarted>5.1)[self completeSharedPreparation];else return;}
211
+ if (!self.settling) return;
212
+ double now = CACurrentMediaTime(), seconds = MAX(0, now - self.previous); self.previous = now;
213
+ _spring = JoltSpringAdvance(_spring, self.target, self.stiffness * self.timeScale * self.timeScale, self.damping * self.timeScale, self.mass, seconds);
214
+ if (!isfinite(_spring.position) || !isfinite(_spring.velocity)) { [self finish]; return; }
215
+ [self render:_spring.position];
216
+ // Bound even a deliberately slow/undamped spring; never leave UIKit's route queue stuck.
217
+ if ((fabs(_spring.position - self.target) < .0005 && fabs(_spring.velocity) < .005) || now - self.started >= 3) [self finish];
218
+ }
219
+ - (void)finish {
220
+ if (!self.context) return;
221
+ [self.link invalidate]; self.link = nil;
222
+ BOOL completed = self.committed, interactive = self.interactive;
223
+ self.sharedPending=NO;
224
+ _spring = (JoltSpringState){completed ? 1 : 0, 0}; [self render:_spring.position];
225
+ self.fromView.transform = self.fromTransform; self.toView.transform = self.toTransform;
226
+ self.fromView.alpha = self.fromAlpha; self.toView.alpha = self.toAlpha;
227
+ [self.sharedFlight dispose]; self.sharedFlight = nil;
228
+ [self.shade removeFromSuperview]; self.shade = nil;
229
+ id<UIViewControllerContextTransitioning> context = self.context;
230
+ self.context = nil; self.fromView = nil; self.toView = nil;
231
+ self.settling = NO; self.interactive = NO; active--;
232
+ // Complete exactly once. Core/Router observes UIKit's actual committed controller.
233
+ [context completeTransition:completed];
234
+ [self sync];
235
+ if (self.onEvent) self.onEvent(interactive ? (completed ? 5 : 6) : 1);
236
+ }
237
+ - (void)cancel {
238
+ if (!self.context) { if (self.interactive) self.pendingEnd = @NO; return; }
239
+ if (!self.settling) [self settle:!self.interactive velocity:0];
240
+ [self finish]; // Preserve an already-decided completion; otherwise roll an active drag back.
241
+ }
242
+ - (void)disposeRestoringSwipe:(BOOL)enabled {
243
+ if (self.disposed) return;
244
+ self.disposed = YES;
245
+ [self cancel];
246
+ [[NSNotificationCenter defaultCenter] removeObserver:self];
247
+ [self.navigation.view removeGestureRecognizer:self.pan]; self.pan.delegate = nil; self.pan = nil;
248
+ recognizers--;
249
+ if (self.suppressed && self.navigation.topViewController == self.presented) {
250
+ self.navigation.interactivePopGestureRecognizer.enabled = enabled;
251
+ self.contentPop.enabled = enabled;
252
+ }
253
+ self.onEvent = nil; self.shouldBegin = nil;
254
+ }
255
+ @end
@@ -0,0 +1,29 @@
1
+ #import <UIKit/UIKit.h>
2
+ NS_ASSUME_NONNULL_BEGIN
3
+ @class JoltLiveSpringBinding;
4
+ @interface JoltLiveSpring : NSObject
5
+ + (instancetype)create:(double)initial stiffness:(double)stiffness damping:(double)damping mass:(double)mass
6
+ restDelta:(double)restDelta restSpeed:(double)restSpeed reduced:(BOOL)reduced;
7
+ @property(nonatomic, readonly) double position;
8
+ @property(nonatomic, readonly) double velocity;
9
+ @property(nonatomic, readonly) BOOL moving;
10
+ + (NSUInteger)activeCount;
11
+ + (NSUInteger)nodeCount;
12
+ + (void)sync:(UIView *)view;
13
+ - (void)follow:(JoltLiveSpring *)source mappings:(NSString *)mappings;
14
+ - (void)updateInput:(NSString *)snapshot;
15
+ - (void)setSensorInput:(double)value;
16
+ - (void)setTarget:(double)value;
17
+ - (void)holdInput:(double)value velocity:(double)velocity;
18
+ - (void)releaseInput:(double)target velocity:(double)velocity;
19
+ - (void)setReduced:(BOOL)value;
20
+ - (void)setPaused:(BOOL)value;
21
+ - (JoltLiveSpringBinding *)bind:(UIView *)view property:(NSString *)property mappings:(NSString *)mappings;
22
+ - (void)dispose;
23
+ @end
24
+ @interface JoltLiveSpringBinding : NSObject
25
+ @property(nonatomic, readonly) double value;
26
+ - (void)setLayers:(NSString *)inputs;
27
+ - (void)cancel;
28
+ @end
29
+ NS_ASSUME_NONNULL_END
@@ -0,0 +1,243 @@
1
+ #import "JoltLiveSpring.h"
2
+ #import "JoltSpringState.h"
3
+ #import <QuartzCore/QuartzCore.h>
4
+
5
+ static id decode(NSString *json) {
6
+ return [NSJSONSerialization JSONObjectWithData:[json dataUsingEncoding:NSUTF8StringEncoding] options:0 error:nil];
7
+ }
8
+ static double mapped(double value, NSArray *mappings) {
9
+ for (NSDictionary *mapping in mappings) {
10
+ NSArray *input = mapping[@"input"], *output = mapping[@"output"];
11
+ BOOL clamp = [mapping[@"clamp"] boolValue];
12
+ if (clamp && value <= [input.firstObject doubleValue]) { value = [output.firstObject doubleValue]; continue; }
13
+ if (clamp && value >= [input.lastObject doubleValue]) { value = [output.lastObject doubleValue]; continue; }
14
+ NSUInteger index = 0;
15
+ while (index < input.count - 2 && value > [input[index + 1] doubleValue]) index++;
16
+ double span = [input[index + 1] doubleValue] - [input[index] doubleValue];
17
+ double fraction = span > 0 ? (value - [input[index] doubleValue]) / span : value < [input[index] doubleValue] ? 0 : 1;
18
+ value = [output[index] doubleValue] + ([output[index + 1] doubleValue] - [output[index] doubleValue]) * fraction;
19
+ }
20
+ return value;
21
+ }
22
+ static BOOL inputRunning(NSDictionary *input, double anchor, double now) {
23
+ double repeat = [input[@"repeat"] doubleValue];
24
+ return [input[@"running"] boolValue] && (repeat < 0 || now - anchor + [input[@"elapsed"] doubleValue] <
25
+ [input[@"delay"] doubleValue] + [input[@"duration"] doubleValue] * (repeat + 1));
26
+ }
27
+ static double inputValue(NSDictionary *input, double anchor, double now) {
28
+ NSArray *values = input[@"values"], *times = input[@"times"];
29
+ if (![input[@"running"] boolValue] || values.count < 2) return [input[@"value"] doubleValue];
30
+ if (!inputRunning(input, anchor, now)) return [input[@"to"] doubleValue];
31
+ double time = MAX(0, now - anchor + [input[@"elapsed"] doubleValue] - [input[@"delay"] doubleValue]);
32
+ double duration = MAX(1, [input[@"duration"] doubleValue]);
33
+ double iteration = floor(time / duration), progress = fmod(time, duration) / duration;
34
+ if ([input[@"reverse"] boolValue] && fmod(iteration, 2) >= 1) progress = 1 - progress;
35
+ NSUInteger lo = 0, hi = times.count - 1;
36
+ while (lo + 1 < hi) { NSUInteger mid = (lo + hi) / 2; if ([times[mid] doubleValue] <= progress) lo = mid; else hi = mid; }
37
+ double start = [times[lo] doubleValue], end = [times[hi] doubleValue];
38
+ double fraction = end > start ? (progress - start) / (end - start) : 1;
39
+ return [values[lo] doubleValue] + ([values[hi] doubleValue] - [values[lo] doubleValue]) * MAX(0, MIN(1, fraction));
40
+ }
41
+
42
+ @interface JoltLiveSpring () {
43
+ JoltSpringState _state;
44
+ }
45
+ @property(nonatomic) double stiffness, damping, mass, restDelta, restSpeed;
46
+ @property(nonatomic, readwrite) BOOL moving;
47
+ @property(nonatomic) BOOL reduced, paused, disposed, direct, inputHeld, sensorDriven;
48
+ @property(nonatomic) double targetValue;
49
+ @property(nonatomic, nullable) JoltLiveSpring *source;
50
+ @property(nonatomic) NSArray *sourceMaps;
51
+ @property(nonatomic) NSDictionary *input;
52
+ @property(nonatomic) double anchor;
53
+ @property(nonatomic) NSMutableArray<JoltLiveSpringBinding *> *bindings;
54
+ - (void)step:(double)now seconds:(double)seconds;
55
+ - (void)apply;
56
+ - (void)wake;
57
+ @end
58
+ @interface JoltLiveSpringBinding ()
59
+ @property(nonatomic, weak) UIView *view;
60
+ @property(nonatomic, weak) JoltLiveSpring *node;
61
+ @property(nonatomic) NSString *property;
62
+ @property(nonatomic) NSArray *mappings;
63
+ @property(nonatomic) BOOL stopped;
64
+ @property(nonatomic) NSArray *sampledLayers;
65
+ @property(nonatomic) double layerAnchor;
66
+ - (BOOL)running:(double)now;
67
+ - (void)apply;
68
+ @end
69
+
70
+ @implementation JoltLiveSpring
71
+ static NSMutableArray<JoltLiveSpring *> *nodes;
72
+ static CADisplayLink *displayLink;
73
+ static double previousFrame;
74
+ + (void)initialize {
75
+ if (self == [JoltLiveSpring class]) nodes = [NSMutableArray new];
76
+ }
77
+ + (void)schedule {
78
+ if (displayLink || !nodes.count) return;
79
+ displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(tick:)];
80
+ if (@available(iOS 15.0, *)) {
81
+ float maximum = MIN(120, UIScreen.mainScreen.maximumFramesPerSecond);
82
+ displayLink.preferredFrameRateRange = CAFrameRateRangeMake(MIN(80, maximum), maximum, maximum);
83
+ }
84
+ [displayLink addToRunLoop:NSRunLoop.mainRunLoop forMode:NSRunLoopCommonModes];
85
+ }
86
+ + (void)tick:(CADisplayLink *)link {
87
+ double now = link.timestamp * 1000;
88
+ double remaining = previousFrame == 0 ? 1.0 / 120 : MIN(.064, MAX(0, link.timestamp - previousFrame));
89
+ previousFrame = link.timestamp;
90
+ while (remaining > 1e-9) {
91
+ double dt = MIN(remaining, 1.0 / 240);
92
+ remaining -= dt;
93
+ for (JoltLiveSpring *node in nodes) [node step:now - remaining * 1000 seconds:dt];
94
+ }
95
+ BOOL active = NO;
96
+ [CATransaction begin]; [CATransaction setDisableActions:YES];
97
+ for (JoltLiveSpring *node in nodes) {
98
+ [node apply]; active |= node.moving;
99
+ for (JoltLiveSpringBinding *binding in node.bindings) active |= [binding running:now];
100
+ }
101
+ [CATransaction commit];
102
+ if (!active) { [displayLink invalidate]; displayLink = nil; previousFrame = 0; }
103
+ }
104
+ + (instancetype)create:(double)initial stiffness:(double)stiffness damping:(double)damping mass:(double)mass
105
+ restDelta:(double)restDelta restSpeed:(double)restSpeed reduced:(BOOL)reduced {
106
+ JoltLiveSpring *node = [self new];
107
+ node->_state = (JoltSpringState){initial, 0};
108
+ node.stiffness = stiffness; node.damping = damping; node.mass = mass;
109
+ node.restDelta = restDelta; node.restSpeed = restSpeed; node->_reduced = reduced;
110
+ node.direct = YES; node.targetValue = initial;
111
+ node.bindings = [NSMutableArray new]; node.sourceMaps = @[];
112
+ [nodes addObject:node];
113
+ return node;
114
+ }
115
+ - (double)position { return _state.position; }
116
+ - (double)velocity { return _state.velocity; }
117
+ + (NSUInteger)activeCount { return displayLink ? 1 : 0; }
118
+ + (NSUInteger)nodeCount { return nodes.count; }
119
+ - (void)follow:(JoltLiveSpring *)source mappings:(NSString *)mappings {
120
+ if (self.disposed || source.disposed || [nodes indexOfObject:source] >= [nodes indexOfObject:self])
121
+ [NSException raise:NSInvalidArgumentException format:@"A spring can only follow an existing live node"];
122
+ self.sourceMaps = decode(mappings); self.source = source; [self wake];
123
+ }
124
+ - (void)updateInput:(NSString *)snapshot {
125
+ if (self.disposed) return;
126
+ self.sensorDriven = NO; self.input = decode(snapshot); self.direct = NO; self.anchor = CACurrentMediaTime() * 1000; [self wake];
127
+ }
128
+ - (void)setSensorInput:(double)value {
129
+ if (self.disposed || !isfinite(value) || (self.sensorDriven && self.inputHeld && _state.position == value)) return;
130
+ self.sensorDriven = YES; self.inputHeld = YES; self.direct = YES; self.targetValue = value; self.input = nil;
131
+ _state = (JoltSpringState){value, 0}; self.moving = NO;
132
+ [JoltLiveSpring schedule];
133
+ }
134
+ - (void)setTarget:(double)value {
135
+ if (self.disposed) return;
136
+ self.sensorDriven = NO; self.direct = YES; self.targetValue = value; self.input = nil; [self wake];
137
+ }
138
+ - (void)holdInput:(double)value velocity:(double)velocity {
139
+ if (self.disposed) return;
140
+ self.sensorDriven = NO; self.inputHeld = YES; self.direct = YES; self.targetValue = value; self.input = nil;
141
+ _state = (JoltSpringState){value, velocity}; self.moving = YES;
142
+ [CATransaction begin]; [CATransaction setDisableActions:YES]; [self apply]; [CATransaction commit];
143
+ [JoltLiveSpring schedule];
144
+ }
145
+ - (void)releaseInput:(double)target velocity:(double)velocity {
146
+ if (self.disposed) return;
147
+ self.inputHeld = NO; _state.velocity = velocity; [self setTarget:target];
148
+ }
149
+ - (void)setReduced:(BOOL)value { _reduced = value; [self wake]; }
150
+ - (void)setPaused:(BOOL)value {
151
+ _paused = value;
152
+ if (value) self.moving = NO; else [self wake];
153
+ }
154
+ - (void)wake {
155
+ // Sensor inputs are held data, not springs. A policy change must not wake an endless clock.
156
+ if (self.disposed || self.paused || self.sensorDriven) return;
157
+ self.moving = YES;
158
+ if (self.reduced) {
159
+ [self step:CACurrentMediaTime() * 1000 seconds:0];
160
+ [CATransaction begin]; [CATransaction setDisableActions:YES]; [self apply]; [CATransaction commit];
161
+ }
162
+ [JoltLiveSpring schedule];
163
+ }
164
+ - (void)step:(double)now seconds:(double)seconds {
165
+ if (self.disposed || self.paused || self.inputHeld) return;
166
+ double target = self.source ? mapped(self.source.position, self.sourceMaps) : (self.direct ? self.targetValue : inputValue(self.input, self.anchor, now));
167
+ BOOL inputMoving = self.source ? self.source.moving : (!self.direct && inputRunning(self.input, self.anchor, now));
168
+ if (self.reduced) _state = (JoltSpringState){target, 0};
169
+ else _state = JoltSpringAdvance(_state, target, self.stiffness, self.damping, self.mass, seconds);
170
+ BOOL rest = fabs(_state.position - target) <= self.restDelta && fabs(_state.velocity) <= self.restSpeed;
171
+ if (rest && !inputMoving) _state = (JoltSpringState){target, 0};
172
+ self.moving = inputMoving || !rest;
173
+ }
174
+ - (JoltLiveSpringBinding *)bind:(UIView *)view property:(NSString *)property mappings:(NSString *)mappings {
175
+ if (self.disposed) [NSException raise:NSInvalidArgumentException format:@"Spring disposed"];
176
+ JoltLiveSpringBinding *binding = [JoltLiveSpringBinding new];
177
+ binding.node = self; binding.view = view; binding.property = property; binding.mappings = decode(mappings);
178
+ [self.bindings addObject:binding];
179
+ [CATransaction begin]; [CATransaction setDisableActions:YES]; [binding apply]; [CATransaction commit];
180
+ return binding;
181
+ }
182
+ - (void)apply {
183
+ for (NSInteger i = self.bindings.count - 1; i >= 0; i--) {
184
+ JoltLiveSpringBinding *binding = self.bindings[i];
185
+ if (!binding.view) [self.bindings removeObjectAtIndex:i]; else [binding apply];
186
+ }
187
+ }
188
+ + (void)sync:(UIView *)view {
189
+ [CATransaction begin]; [CATransaction setDisableActions:YES];
190
+ for (JoltLiveSpring *node in nodes)
191
+ for (JoltLiveSpringBinding *binding in node.bindings)
192
+ if (binding.view == view) [binding apply];
193
+ [CATransaction commit];
194
+ }
195
+ - (void)dispose {
196
+ if (self.disposed) return;
197
+ self.disposed = YES; self.moving = NO; [self.bindings removeAllObjects]; [nodes removeObject:self];
198
+ for (JoltLiveSpring *child in nodes) if (child.source == self) {
199
+ child.source = nil; [child setTarget:mapped(self.position, child.sourceMaps)];
200
+ }
201
+ self.source = nil;
202
+ if (!nodes.count) { [displayLink invalidate]; displayLink = nil; previousFrame = 0; }
203
+ }
204
+ @end
205
+
206
+ @implementation JoltLiveSpringBinding
207
+ - (double)value { return mapped(self.node.position, self.mappings); }
208
+ - (void)setLayers:(NSString *)inputs {
209
+ self.sampledLayers = decode(inputs); self.layerAnchor = CACurrentMediaTime() * 1000;
210
+ [CATransaction begin]; [CATransaction setDisableActions:YES]; [self apply]; [CATransaction commit];
211
+ [JoltLiveSpring schedule];
212
+ }
213
+ - (BOOL)running:(double)now {
214
+ for (NSDictionary *layer in self.sampledLayers) if (inputRunning(layer, self.layerAnchor, now)) return YES;
215
+ return NO;
216
+ }
217
+ - (void)cancel { self.stopped = YES; [self.node.bindings removeObject:self]; }
218
+ - (void)apply {
219
+ UIView *view = self.view;
220
+ if (self.stopped || !view.window) return;
221
+ NSString *key = self.property;
222
+ double value = self.value;
223
+ BOOL multiply = [key isEqualToString:@"opacity"] || [key hasPrefix:@"scale"];
224
+ double now = CACurrentMediaTime() * 1000;
225
+ for (NSDictionary *layer in self.sampledLayers) {
226
+ double part = inputValue(layer, self.layerAnchor, now);
227
+ value = multiply ? value * part : value + part;
228
+ }
229
+ if ([key isEqualToString:@"opacity"]) { view.alpha = MAX(0, MIN(1, value)); return; }
230
+ if ([key isEqualToString:@"x"]) key = @"transform.translation.x";
231
+ else if ([key isEqualToString:@"y"]) key = @"transform.translation.y";
232
+ else if ([key isEqualToString:@"scaleX"]) key = @"transform.scale.x";
233
+ else if ([key isEqualToString:@"scaleY"]) key = @"transform.scale.y";
234
+ else if ([key isEqualToString:@"rotate"]) { key = @"transform.rotation.z"; value *= M_PI / 180; }
235
+ else if ([key isEqualToString:@"rotateX"]) { key = @"transform.rotation.x"; value *= M_PI / 180; }
236
+ else if ([key isEqualToString:@"rotateY"]) { key = @"transform.rotation.y"; value *= M_PI / 180; }
237
+ [view.layer setValue:@(value) forKeyPath:key];
238
+ if ([view respondsToSelector:NSSelectorFromString(@"outerShadowContainerLayer")]) {
239
+ CALayer *shadow = [view valueForKey:@"outerShadowContainerLayer"];
240
+ [shadow setValue:@(value) forKeyPath:key];
241
+ }
242
+ }
243
+ @end
@@ -0,0 +1,9 @@
1
+ #import <UIKit/UIKit.h>
2
+
3
+ /** Inert until explicitly started by the optional development inspector. */
4
+ @interface JoltMotionProbe : NSObject
5
+ + (instancetype)startView:(UIView *)view capacity:(NSInteger)capacity hertz:(double)hertz;
6
+ + (NSInteger)activeCount;
7
+ - (NSString *)drain;
8
+ - (void)dispose;
9
+ @end
@@ -0,0 +1,72 @@
1
+ #import "JoltMotionProbe.h"
2
+ #import <QuartzCore/QuartzCore.h>
3
+ #include <math.h>
4
+
5
+ static NSInteger probeCount = 0;
6
+ @interface JoltMotionProbe () {
7
+ double *_rows;
8
+ }
9
+ @property(nonatomic, weak) UIView *view;
10
+ @property(nonatomic) CADisplayLink *link;
11
+ @property(nonatomic) NSInteger capacity, count, head, dropped, samples;
12
+ @property(nonatomic) double interval, last, sampleCPU, drainCPU;
13
+ @end
14
+
15
+ @implementation JoltMotionProbe
16
+ + (NSInteger)activeCount { return probeCount; }
17
+ + (instancetype)startView:(UIView *)view capacity:(NSInteger)capacity hertz:(double)hertz {
18
+ JoltMotionProbe *p = [JoltMotionProbe new];
19
+ p.view = view; p.capacity = MAX(8, MIN(600, capacity));
20
+ p.interval = 1000.0 / MAX(1, MIN(120, hertz)); p.last = -INFINITY;
21
+ p->_rows = calloc(p.capacity * 9, sizeof(double));
22
+ p.link = [CADisplayLink displayLinkWithTarget:p selector:@selector(frame:)];
23
+ if (@available(iOS 15.0, *)) {
24
+ float rate = MIN(hertz, view.window.screen.maximumFramesPerSecond ?: 60);
25
+ p.link.preferredFrameRateRange = CAFrameRateRangeMake(rate, rate, rate);
26
+ }
27
+ [p.link addToRunLoop:NSRunLoop.mainRunLoop forMode:NSRunLoopCommonModes];
28
+ [[NSNotificationCenter defaultCenter] addObserver:p selector:@selector(dispose) name:UIApplicationDidEnterBackgroundNotification object:nil];
29
+ probeCount++; return p;
30
+ }
31
+ - (void)frame:(CADisplayLink *)link {
32
+ if (!self.view.window) { [self dispose]; return; }
33
+ double begin = CACurrentMediaTime() * 1000;
34
+ if (begin - self.last < self.interval - 0.5) return;
35
+ self.last = begin;
36
+ NSInteger slot;
37
+ if (self.count == self.capacity) {
38
+ slot = self.head; self.head = (self.head + 1) % self.capacity; self.dropped++;
39
+ } else { slot = (self.head + self.count) % self.capacity; self.count++; }
40
+ double *row = _rows + slot * 9; row[0] = begin;
41
+ CALayer *layer = self.view.layer.presentationLayer;
42
+ static NSArray<NSString *> *paths;
43
+ static dispatch_once_t once;
44
+ dispatch_once(&once, ^{ paths = @[@"transform.translation.x", @"transform.translation.y", @"transform.scale.x", @"transform.scale.y", @"transform.rotation.z", @"transform.rotation.x", @"transform.rotation.y", @"opacity"]; });
45
+ for (NSInteger i = 0; i < 8; i++) {
46
+ // Missing presentation is explicitly unavailable, never replaced with the model layer.
47
+ row[i + 1] = layer ? [[layer valueForKeyPath:paths[i]] doubleValue] : NAN;
48
+ if (i >= 4 && i <= 6) row[i + 1] *= 180.0 / M_PI;
49
+ }
50
+ self.samples++; self.sampleCPU += CACurrentMediaTime() * 1000 - begin;
51
+ }
52
+ - (NSString *)drain {
53
+ double begin = CACurrentMediaTime() * 1000;
54
+ NSMutableArray *out = [NSMutableArray arrayWithCapacity:self.count];
55
+ for (NSInteger i = 0; i < self.count; i++) {
56
+ double *row = _rows + ((self.head + i) % self.capacity) * 9;
57
+ NSMutableArray *values = [NSMutableArray arrayWithCapacity:9];
58
+ for (NSInteger j = 0; j < 9; j++) [values addObject:isfinite(row[j]) ? @(row[j]) : NSNull.null];
59
+ [out addObject:values];
60
+ }
61
+ self.count = 0; self.head = 0;
62
+ NSDictionary *result = @{@"rows":out, @"dropped":@(self.dropped), @"samples":@(self.samples), @"sampleCpuMs":@(self.sampleCPU), @"drainCpuMs":@(self.drainCPU), @"active":@(self.link != nil)};
63
+ NSString *json = [[NSString alloc] initWithData:[NSJSONSerialization dataWithJSONObject:result options:0 error:nil] encoding:NSUTF8StringEncoding];
64
+ self.drainCPU += CACurrentMediaTime() * 1000 - begin;
65
+ return json;
66
+ }
67
+ - (void)dispose {
68
+ if (self.link) { [self.link invalidate]; self.link = nil; probeCount--; }
69
+ [[NSNotificationCenter defaultCenter] removeObserver:self]; self.view = nil;
70
+ }
71
+ - (void)dealloc { free(_rows); }
72
+ @end
@@ -0,0 +1,15 @@
1
+ #import <UIKit/UIKit.h>
2
+
3
+ @interface JoltReorderHandle : UIButton
4
+ @property(nonatomic, copy) void (^onMove)(NSInteger direction);
5
+ @end
6
+
7
+ @interface JoltReorderSession : NSObject
8
+ + (instancetype)attach:(UITableView *)list options:(NSString *)options onState:(void (^)(NSInteger state, NSInteger index, NSInteger toIndex))onState;
9
+ - (void)registerHandle:(UIView *)view;
10
+ - (void)setEnabled:(BOOL)enabled;
11
+ - (void)setReducedMotion:(BOOL)reduced;
12
+ - (void)cancel;
13
+ - (void)dispose;
14
+ @property(nonatomic, readonly) BOOL active;
15
+ @end