@reicek/neataptic-ts 0.1.21 → 0.1.22

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 (223) hide show
  1. package/.github/agents/boundary-mapper.agent.md +29 -0
  2. package/.github/agents/docs-scout.agent.md +29 -0
  3. package/.github/agents/plan-scout.agent.md +29 -0
  4. package/.github/agents/solid-split.agent.md +138 -0
  5. package/.github/copilot-instructions.md +103 -0
  6. package/package.json +6 -3
  7. package/plans/ES2023 migration +13 -8
  8. package/plans/Evolution_Training_Interoperability_Contracts.md +1 -1
  9. package/plans/Interactive_Examples_and_Learning_Path.md +10 -2
  10. package/plans/Memory_Optimization.md +3 -3
  11. package/plans/README.md +63 -0
  12. package/plans/Roadmap.md +15 -3
  13. package/plans/asciiMaze_SOLID_split.done.md +130 -0
  14. package/plans/flappy_bird_SOLID_split.done.md +67 -0
  15. package/scripts/assets/theme.css +221 -34
  16. package/scripts/copy-examples.mjs +9 -5
  17. package/scripts/export-onnx.mjs +3 -3
  18. package/scripts/generate-bench-tables.mjs +10 -10
  19. package/scripts/generate-bench-tables.ts +10 -10
  20. package/scripts/generate-docs.ts +1415 -449
  21. package/scripts/render-docs-html.ts +15 -8
  22. package/src/README.md +101 -223
  23. package/src/architecture/README.md +57 -185
  24. package/src/architecture/layer/README.md +38 -38
  25. package/src/architecture/network/README.md +33 -31
  26. package/src/architecture/network/activate/README.md +77 -77
  27. package/src/architecture/network/connect/README.md +15 -13
  28. package/src/architecture/network/deterministic/README.md +7 -7
  29. package/src/architecture/network/evolve/README.md +44 -44
  30. package/src/architecture/network/gating/README.md +20 -20
  31. package/src/architecture/network/genetic/README.md +51 -51
  32. package/src/architecture/network/mutate/README.md +97 -97
  33. package/src/architecture/network/onnx/README.md +264 -264
  34. package/src/architecture/network/prune/README.md +39 -39
  35. package/src/architecture/network/remove/README.md +26 -26
  36. package/src/architecture/network/serialize/README.md +56 -56
  37. package/src/architecture/network/slab/README.md +61 -61
  38. package/src/architecture/network/standalone/README.md +24 -24
  39. package/src/architecture/network/stats/README.md +9 -9
  40. package/src/architecture/network/topology/README.md +46 -46
  41. package/src/architecture/network/training/README.md +21 -21
  42. package/src/methods/README.md +9 -87
  43. package/src/multithreading/README.md +8 -77
  44. package/src/multithreading/workers/README.md +2 -2
  45. package/src/multithreading/workers/browser/README.md +0 -6
  46. package/src/multithreading/workers/node/README.md +0 -3
  47. package/src/neat/README.md +562 -568
  48. package/src/utils/README.md +18 -18
  49. package/test/examples/asciiMaze/README.md +59 -59
  50. package/test/examples/asciiMaze/asciiMaze.e2e.test.ts +14 -9
  51. package/test/examples/asciiMaze/browser-entry/README.md +196 -0
  52. package/test/examples/asciiMaze/browser-entry/browser-entry.abort.services.ts +95 -0
  53. package/test/examples/asciiMaze/browser-entry/browser-entry.constants.ts +23 -0
  54. package/test/examples/asciiMaze/browser-entry/browser-entry.curriculum.services.ts +115 -0
  55. package/test/examples/asciiMaze/browser-entry/browser-entry.globals.services.ts +106 -0
  56. package/test/examples/asciiMaze/browser-entry/browser-entry.host.services.ts +157 -0
  57. package/test/examples/asciiMaze/browser-entry/browser-entry.services.ts +14 -0
  58. package/test/examples/asciiMaze/browser-entry/browser-entry.ts +129 -0
  59. package/test/examples/asciiMaze/browser-entry/browser-entry.types.ts +120 -0
  60. package/test/examples/asciiMaze/browser-entry/browser-entry.utils.ts +98 -0
  61. package/test/examples/asciiMaze/browser-entry.ts +10 -576
  62. package/test/examples/asciiMaze/dashboardManager/README.md +276 -0
  63. package/test/examples/asciiMaze/dashboardManager/archive/README.md +16 -0
  64. package/test/examples/asciiMaze/dashboardManager/archive/dashboardManager.archive.services.ts +267 -0
  65. package/test/examples/asciiMaze/dashboardManager/dashboardManager.constants.ts +35 -0
  66. package/test/examples/asciiMaze/dashboardManager/dashboardManager.services.ts +103 -0
  67. package/test/examples/asciiMaze/dashboardManager/dashboardManager.ts +181 -0
  68. package/test/examples/asciiMaze/dashboardManager/dashboardManager.types.ts +267 -0
  69. package/test/examples/asciiMaze/dashboardManager/dashboardManager.utils.ts +254 -0
  70. package/test/examples/asciiMaze/dashboardManager/live/README.md +14 -0
  71. package/test/examples/asciiMaze/dashboardManager/live/dashboardManager.live.services.ts +264 -0
  72. package/test/examples/asciiMaze/dashboardManager/telemetry/README.md +47 -0
  73. package/test/examples/asciiMaze/dashboardManager/telemetry/dashboardManager.telemetry.services.ts +513 -0
  74. package/test/examples/asciiMaze/dashboardManager.ts +13 -2335
  75. package/test/examples/asciiMaze/evolutionEngine/README.md +1058 -0
  76. package/test/examples/asciiMaze/evolutionEngine/curriculumPhase.ts +90 -0
  77. package/test/examples/asciiMaze/evolutionEngine/engineState.constants.ts +36 -0
  78. package/test/examples/asciiMaze/evolutionEngine/engineState.ts +58 -513
  79. package/test/examples/asciiMaze/evolutionEngine/engineState.types.ts +212 -0
  80. package/test/examples/asciiMaze/evolutionEngine/engineState.utils.ts +301 -0
  81. package/test/examples/asciiMaze/evolutionEngine/evolutionEngine.types.ts +445 -0
  82. package/test/examples/asciiMaze/evolutionEngine/evolutionLoop.ts +81 -50
  83. package/test/examples/asciiMaze/evolutionEngine/optionsAndSetup.ts +2 -4
  84. package/test/examples/asciiMaze/evolutionEngine/populationDynamics.ts +17 -33
  85. package/test/examples/asciiMaze/evolutionEngine/populationPruning.ts +1 -1
  86. package/test/examples/asciiMaze/evolutionEngine/rngAndTiming.ts +1 -2
  87. package/test/examples/asciiMaze/evolutionEngine/sampling.ts +1 -1
  88. package/test/examples/asciiMaze/evolutionEngine/scratchPools.ts +2 -5
  89. package/test/examples/asciiMaze/evolutionEngine/setupHelpers.ts +30 -37
  90. package/test/examples/asciiMaze/evolutionEngine/telemetryMetrics.ts +16 -58
  91. package/test/examples/asciiMaze/evolutionEngine/trainingWarmStart.ts +2 -2
  92. package/test/examples/asciiMaze/evolutionEngine.ts +55 -55
  93. package/test/examples/asciiMaze/fitness.ts +2 -2
  94. package/test/examples/asciiMaze/fitness.types.ts +65 -0
  95. package/test/examples/asciiMaze/interfaces.ts +64 -1352
  96. package/test/examples/asciiMaze/mazeMovement/README.md +356 -0
  97. package/test/examples/asciiMaze/mazeMovement/finalization/README.md +49 -0
  98. package/test/examples/asciiMaze/mazeMovement/finalization/mazeMovement.finalization.ts +138 -0
  99. package/test/examples/asciiMaze/mazeMovement/mazeMovement.constants.ts +101 -0
  100. package/test/examples/asciiMaze/mazeMovement/mazeMovement.services.ts +230 -0
  101. package/test/examples/asciiMaze/mazeMovement/mazeMovement.ts +299 -0
  102. package/test/examples/asciiMaze/mazeMovement/mazeMovement.types.ts +185 -0
  103. package/test/examples/asciiMaze/mazeMovement/mazeMovement.utils.ts +153 -0
  104. package/test/examples/asciiMaze/mazeMovement/policy/README.md +91 -0
  105. package/test/examples/asciiMaze/mazeMovement/policy/mazeMovement.policy.ts +467 -0
  106. package/test/examples/asciiMaze/mazeMovement/runtime/README.md +95 -0
  107. package/test/examples/asciiMaze/mazeMovement/runtime/mazeMovement.runtime.ts +354 -0
  108. package/test/examples/asciiMaze/mazeMovement/shaping/README.md +124 -0
  109. package/test/examples/asciiMaze/mazeMovement/shaping/mazeMovement.shaping.ts +459 -0
  110. package/test/examples/asciiMaze/mazeMovement.ts +12 -2978
  111. package/test/examples/flappy_bird/Trace-20260309T191949.json +24124 -0
  112. package/test/examples/flappy_bird/browser-entry/README.md +1129 -0
  113. package/test/examples/flappy_bird/browser-entry/browser-entry.host.utils.ts +4 -324
  114. package/test/examples/flappy_bird/browser-entry/browser-entry.network-view.utils.ts +6 -399
  115. package/test/examples/flappy_bird/browser-entry/browser-entry.playback.utils.ts +1 -717
  116. package/test/examples/flappy_bird/browser-entry/browser-entry.spawn.utils.ts +11 -31
  117. package/test/examples/flappy_bird/browser-entry/browser-entry.visualization.utils.ts +15 -893
  118. package/test/examples/flappy_bird/browser-entry/host/README.md +307 -0
  119. package/test/examples/flappy_bird/browser-entry/host/host.resize.service.ts +1 -295
  120. package/test/examples/flappy_bird/browser-entry/host/host.ts +562 -6
  121. package/test/examples/flappy_bird/browser-entry/host/resize/README.md +274 -0
  122. package/test/examples/flappy_bird/browser-entry/host/resize/host.resize.service.constants.ts +31 -0
  123. package/test/examples/flappy_bird/browser-entry/host/resize/host.resize.service.services.ts +360 -0
  124. package/test/examples/flappy_bird/browser-entry/host/resize/host.resize.service.ts +117 -0
  125. package/test/examples/flappy_bird/browser-entry/host/resize/host.resize.service.types.ts +63 -0
  126. package/test/examples/flappy_bird/browser-entry/host/resize/host.resize.service.utils.ts +250 -0
  127. package/test/examples/flappy_bird/browser-entry/network-view/README.md +399 -0
  128. package/test/examples/flappy_bird/browser-entry/network-view/network-view.topology.utils.ts +255 -0
  129. package/test/examples/flappy_bird/browser-entry/network-view/network-view.ts +802 -7
  130. package/test/examples/flappy_bird/browser-entry/playback/README.md +684 -0
  131. package/test/examples/flappy_bird/browser-entry/playback/background/README.md +277 -0
  132. package/test/examples/flappy_bird/browser-entry/playback/background/ground-grid/README.md +770 -0
  133. package/test/examples/flappy_bird/browser-entry/playback/background/ground-grid/playback.background.ground-grid.cache.services.ts +178 -0
  134. package/test/examples/flappy_bird/browser-entry/playback/background/ground-grid/playback.background.ground-grid.constants.ts +107 -0
  135. package/test/examples/flappy_bird/browser-entry/playback/background/ground-grid/playback.background.ground-grid.geometry.utils.ts +518 -0
  136. package/test/examples/flappy_bird/browser-entry/playback/background/ground-grid/playback.background.ground-grid.math.utils.ts +117 -0
  137. package/test/examples/flappy_bird/browser-entry/playback/background/ground-grid/playback.background.ground-grid.pulse.utils.ts +233 -0
  138. package/test/examples/flappy_bird/browser-entry/playback/background/ground-grid/playback.background.ground-grid.services.ts +211 -0
  139. package/test/examples/flappy_bird/browser-entry/playback/background/ground-grid/playback.background.ground-grid.ts +48 -0
  140. package/test/examples/flappy_bird/browser-entry/playback/background/ground-grid/playback.background.ground-grid.types.ts +212 -0
  141. package/test/examples/flappy_bird/browser-entry/playback/background/ground-grid/playback.background.ground-grid.utils.ts +81 -0
  142. package/test/examples/flappy_bird/browser-entry/playback/background/playback.background.cache.services.ts +96 -0
  143. package/test/examples/flappy_bird/browser-entry/playback/background/playback.background.constants.ts +62 -0
  144. package/test/examples/flappy_bird/browser-entry/playback/background/playback.background.services.ts +244 -0
  145. package/test/examples/flappy_bird/browser-entry/playback/background/playback.background.ts +53 -0
  146. package/test/examples/flappy_bird/browser-entry/playback/background/playback.background.types.ts +68 -0
  147. package/test/examples/flappy_bird/browser-entry/playback/background/playback.background.utils.ts +100 -0
  148. package/test/examples/flappy_bird/browser-entry/playback/frame-render/README.md +310 -0
  149. package/test/examples/flappy_bird/browser-entry/playback/frame-render/playback.frame-render.service.ts +92 -0
  150. package/test/examples/flappy_bird/browser-entry/playback/frame-render/playback.frame-render.services.ts +272 -0
  151. package/test/examples/flappy_bird/browser-entry/playback/frame-render/playback.frame-render.types.ts +39 -0
  152. package/test/examples/flappy_bird/browser-entry/playback/frame-render/playback.frame-render.utils.ts +493 -0
  153. package/test/examples/flappy_bird/browser-entry/playback/playback.constants.ts +1 -1
  154. package/test/examples/flappy_bird/browser-entry/playback/playback.frame-render.service.ts +4 -0
  155. package/test/examples/flappy_bird/browser-entry/playback/playback.snapshot.utils.ts +44 -0
  156. package/test/examples/flappy_bird/browser-entry/playback/playback.starfield.service.ts +39 -122
  157. package/test/examples/flappy_bird/browser-entry/playback/playback.starfield.services.ts +272 -0
  158. package/test/examples/flappy_bird/browser-entry/playback/playback.starfield.types.ts +62 -0
  159. package/test/examples/flappy_bird/browser-entry/playback/playback.starfield.utils.ts +11 -4
  160. package/test/examples/flappy_bird/browser-entry/playback/playback.ts +409 -8
  161. package/test/examples/flappy_bird/browser-entry/playback/playback.types.ts +4 -12
  162. package/test/examples/flappy_bird/browser-entry/runtime/README.md +235 -0
  163. package/test/examples/flappy_bird/browser-entry/runtime/runtime.evolution-launch.service.ts +45 -0
  164. package/test/examples/flappy_bird/browser-entry/runtime/runtime.lifecycle.service.ts +81 -0
  165. package/test/examples/flappy_bird/browser-entry/runtime/runtime.startup.service.ts +74 -0
  166. package/test/examples/flappy_bird/browser-entry/runtime/runtime.ts +31 -121
  167. package/test/examples/flappy_bird/browser-entry/runtime/runtime.types.ts +36 -0
  168. package/test/examples/flappy_bird/browser-entry/visualization/README.md +557 -0
  169. package/test/examples/flappy_bird/browser-entry/visualization/visualization.constants.ts +110 -0
  170. package/test/examples/flappy_bird/browser-entry/visualization/visualization.draw.service.ts +957 -19
  171. package/test/examples/flappy_bird/browser-entry/visualization/visualization.legend.utils.ts +138 -3
  172. package/test/examples/flappy_bird/browser-entry/visualization/visualization.topology.utils.ts +3 -27
  173. package/test/examples/flappy_bird/browser-entry/visualization/visualization.ts +1 -23
  174. package/test/examples/flappy_bird/browser-entry/worker-channel/README.md +156 -0
  175. package/test/examples/flappy_bird/constants/README.md +1179 -0
  176. package/test/examples/flappy_bird/constants/constants.network-view.ts +24 -0
  177. package/test/examples/flappy_bird/constants/constants.palette.ts +7 -0
  178. package/test/examples/flappy_bird/constants/constants.starfield.ts +78 -3
  179. package/test/examples/flappy_bird/environment/README.md +143 -0
  180. package/test/examples/flappy_bird/environment/environment.observation.utils.ts +1 -19
  181. package/test/examples/flappy_bird/environment/environment.step.service.ts +3 -66
  182. package/test/examples/flappy_bird/evaluation/README.md +130 -0
  183. package/test/examples/flappy_bird/evaluation/evaluation.fitness.utils.ts +1 -1
  184. package/test/examples/flappy_bird/evaluation/evaluation.rollout.service.ts +5 -375
  185. package/test/examples/flappy_bird/evaluation/rollout/README.md +291 -0
  186. package/test/examples/flappy_bird/evaluation/rollout/evaluation.rollout.constants.ts +30 -0
  187. package/test/examples/flappy_bird/evaluation/rollout/evaluation.rollout.service.ts +58 -0
  188. package/test/examples/flappy_bird/evaluation/rollout/evaluation.rollout.services.ts +310 -0
  189. package/test/examples/flappy_bird/evaluation/rollout/evaluation.rollout.types.ts +56 -0
  190. package/test/examples/flappy_bird/evaluation/rollout/evaluation.rollout.utils.ts +368 -0
  191. package/test/examples/flappy_bird/flappy-evolution-worker/README.md +618 -0
  192. package/test/examples/flappy_bird/flappy-evolution-worker/flappy-evolution-worker.playback.service.ts +7 -7
  193. package/test/examples/flappy_bird/flappy-evolution-worker/flappy-evolution-worker.simulation.frame.service.ts +364 -0
  194. package/test/examples/flappy_bird/flappy-evolution-worker/flappy-evolution-worker.simulation.types.ts +14 -0
  195. package/test/examples/flappy_bird/flappy-evolution-worker/flappy-evolution-worker.simulation.utils.ts +4 -201
  196. package/test/examples/flappy_bird/flappy-evolution-worker/flappy-evolution-worker.ts +184 -345
  197. package/test/examples/flappy_bird/flappy-evolution-worker/flappy-evolution-worker.warm-start.service.ts +291 -0
  198. package/test/examples/flappy_bird/flappy.simulation.shared.utils.ts +5 -0
  199. package/test/examples/flappy_bird/simulation-shared/README.md +417 -0
  200. package/test/examples/flappy_bird/simulation-shared/observation/README.md +183 -0
  201. package/test/examples/flappy_bird/simulation-shared/observation/observation.features.utils.ts +301 -0
  202. package/test/examples/flappy_bird/simulation-shared/observation/observation.ts +9 -0
  203. package/test/examples/flappy_bird/simulation-shared/observation/observation.vector.utils.ts +59 -0
  204. package/test/examples/flappy_bird/simulation-shared/simulation-shared.observation.utils.ts +5 -403
  205. package/test/examples/flappy_bird/simulation-shared/simulation-shared.spawn.utils.ts +20 -6
  206. package/test/examples/flappy_bird/{evaluation/evaluation.statistics.utils.ts → simulation-shared/simulation-shared.statistics.utils.ts} +23 -8
  207. package/test/examples/flappy_bird/trainer/README.md +563 -0
  208. package/test/examples/flappy_bird/trainer/evaluation/README.md +199 -0
  209. package/test/examples/flappy_bird/trainer/evaluation/trainer.evaluation.service.constants.ts +9 -0
  210. package/test/examples/flappy_bird/trainer/evaluation/trainer.evaluation.service.services.ts +73 -0
  211. package/test/examples/flappy_bird/trainer/evaluation/trainer.evaluation.service.ts +165 -0
  212. package/test/examples/flappy_bird/trainer/evaluation/trainer.evaluation.service.types.ts +25 -0
  213. package/test/examples/flappy_bird/trainer/evaluation/trainer.evaluation.service.utils.ts +161 -0
  214. package/test/examples/flappy_bird/trainer/trainer.evaluation.service.ts +13 -0
  215. package/test/examples/flappy_bird/trainer/trainer.report.service.services.ts +181 -0
  216. package/test/examples/flappy_bird/trainer/trainer.report.service.ts +126 -0
  217. package/test/examples/flappy_bird/trainer/trainer.selection.utils.ts +89 -0
  218. package/test/examples/flappy_bird/trainer/trainer.ts +11 -553
  219. package/test/examples/flappy_bird/browser-entry/browser-entry.utils.ts +0 -12
  220. package/test/examples/flappy_bird/environment/environment.ts +0 -7
  221. package/test/examples/flappy_bird/evaluation/evaluation.ts +0 -7
  222. package/test/examples/flappy_bird/simulation-shared/simulation-shared.ts +0 -15
  223. package/test/examples/flappy_bird/trainer/trainer.statistics.utils.ts +0 -78
@@ -0,0 +1,81 @@
1
+ import {
2
+ resolvePlaybackGroundGridHorizontalGeometry,
3
+ resolvePlaybackGroundGridVerticalGeometry,
4
+ } from './playback.background.ground-grid.geometry.utils';
5
+ import { resolvePlaybackGroundGridPulse } from './playback.background.ground-grid.pulse.utils';
6
+ import type {
7
+ PlaybackBackgroundGroundGridSceneContext,
8
+ PlaybackBackgroundGroundGridSourceScene,
9
+ PlaybackGroundGridGeometry,
10
+ PlaybackGroundGridHorizontalGeometry,
11
+ PlaybackGroundGridVerticalGeometry,
12
+ } from './playback.background.ground-grid.types';
13
+
14
+ export {
15
+ interpolatePlaybackGroundGridPoint,
16
+ resolvePlaybackGroundGridDepthCurve,
17
+ resolvePlaybackGroundGridDepthFromHorizonDistance,
18
+ resolvePlaybackGroundGridLineAlpha,
19
+ resolvePlaybackGroundGridLineBlur,
20
+ resolvePlaybackGroundGridLineThickness,
21
+ } from './playback.background.ground-grid.math.utils';
22
+
23
+ /**
24
+ * Resolves the shared scene context used by the ground-grid renderer.
25
+ *
26
+ * @param sceneContext - Lower-band geometry provided by the background module.
27
+ * @returns Narrow scene contract consumed by grid-specific helpers.
28
+ */
29
+ export function resolvePlaybackGroundGridSceneContext(
30
+ sceneContext: PlaybackBackgroundGroundGridSourceScene,
31
+ ): PlaybackBackgroundGroundGridSceneContext {
32
+ return {
33
+ viewportOffsetXPx: sceneContext.viewportLeftXPx,
34
+ visibleWorldWidthPx: sceneContext.visibleWorldWidthPx,
35
+ alignedHorizonYPx: sceneContext.alignedHorizonYPx,
36
+ lowerBandTopYPx: sceneContext.lowerBandTopYPx,
37
+ lowerBandHeightPx: sceneContext.lowerBandHeightPx,
38
+ lowerBandBottomYPx: sceneContext.lowerBandBottomYPx,
39
+ vanishingPointXPx:
40
+ sceneContext.vanishingPointXPx - sceneContext.viewportLeftXPx,
41
+ vanishingPointYPx: sceneContext.vanishingPointYPx,
42
+ };
43
+ }
44
+
45
+ /**
46
+ * Builds the line geometry for the neon ground grid.
47
+ *
48
+ * @param sceneContext - Lower-band geometry for the current viewport.
49
+ * @param frameIndex - Current deterministic playback frame index.
50
+ * @param scrollBasePx - Shared world scroll used for parallax motion.
51
+ * @returns Horizontal depth bands and perspective rays for the current frame.
52
+ */
53
+ export function resolvePlaybackGroundGridGeometry(
54
+ sceneContext: PlaybackBackgroundGroundGridSceneContext,
55
+ frameIndex: number,
56
+ scrollBasePx: number,
57
+ ): PlaybackGroundGridGeometry {
58
+ // Step 1: Resolve and cache the fixed horizontal depth bands for the lower plane.
59
+ const horizontalGeometry: PlaybackGroundGridHorizontalGeometry =
60
+ resolvePlaybackGroundGridHorizontalGeometry(sceneContext);
61
+
62
+ // Step 2: Resolve and cache the moving perspective rays within one wrapped cycle.
63
+ const verticalGeometry: PlaybackGroundGridVerticalGeometry =
64
+ resolvePlaybackGroundGridVerticalGeometry(sceneContext, scrollBasePx);
65
+
66
+ // Step 3: Resolve one visible pulse above the grid lines.
67
+ const pulse = resolvePlaybackGroundGridPulse({
68
+ frameIndex,
69
+ horizontalPulsePaths: horizontalGeometry.preferredHorizontalPulsePaths,
70
+ sceneContext,
71
+ verticalPulsePaths: verticalGeometry.verticalPulsePaths,
72
+ visibleVerticalPulsePaths: verticalGeometry.visibleVerticalPulsePaths,
73
+ });
74
+
75
+ // Step 4: Return the pure geometry bundle used by the canvas renderer.
76
+ return {
77
+ horizontalLineBatches: horizontalGeometry.horizontalLineBatches,
78
+ pulse,
79
+ verticalLineBatches: verticalGeometry.verticalLineBatches,
80
+ };
81
+ }
@@ -0,0 +1,96 @@
1
+ import type {
2
+ PlaybackBackgroundLayout,
3
+ PlaybackBackgroundLayoutFactory,
4
+ } from './playback.background.types';
5
+
6
+ let cachedViewportSizeKey: string | null = null;
7
+
8
+ const cachedLayoutsByHeightPx = new Map<number, PlaybackBackgroundLayout>();
9
+ const cachedTileCoverageCountsByTileWidthPx = new Map<number, number>();
10
+
11
+ /**
12
+ * Ensures background caches only retain entries for the current viewport size.
13
+ *
14
+ * When the page size changes, cached geometry and coverage counts become
15
+ * obsolete because the background bands and tile coverage both depend on the
16
+ * current viewport dimensions.
17
+ *
18
+ * @param visibleWorldWidthPx - Current visible world width in pixels.
19
+ * @param visibleWorldHeightPx - Current visible world height in pixels.
20
+ * @returns Stable viewport-size cache key for the current frame.
21
+ */
22
+ export function ensurePlaybackBackgroundViewportCacheValidity(
23
+ visibleWorldWidthPx: number,
24
+ visibleWorldHeightPx: number,
25
+ ): string {
26
+ const viewportSizeKey = resolvePlaybackBackgroundViewportCacheKey(
27
+ visibleWorldWidthPx,
28
+ visibleWorldHeightPx,
29
+ );
30
+
31
+ if (cachedViewportSizeKey === viewportSizeKey) {
32
+ return viewportSizeKey;
33
+ }
34
+
35
+ cachedViewportSizeKey = viewportSizeKey;
36
+ cachedLayoutsByHeightPx.clear();
37
+ cachedTileCoverageCountsByTileWidthPx.clear();
38
+ return viewportSizeKey;
39
+ }
40
+
41
+ /**
42
+ * Resolves the stable viewport-size cache key used by background caches.
43
+ *
44
+ * @param visibleWorldWidthPx - Current visible world width in pixels.
45
+ * @param visibleWorldHeightPx - Current visible world height in pixels.
46
+ * @returns Cache key that changes whenever the page size changes.
47
+ */
48
+ export function resolvePlaybackBackgroundViewportCacheKey(
49
+ visibleWorldWidthPx: number,
50
+ visibleWorldHeightPx: number,
51
+ ): string {
52
+ return `${visibleWorldWidthPx}x${visibleWorldHeightPx}`;
53
+ }
54
+
55
+ /**
56
+ * Resolves cached background layout for the current viewport height.
57
+ *
58
+ * @param visibleWorldHeightPx - Current visible world height in pixels.
59
+ * @param factory - Lazy layout builder used when the cache misses.
60
+ * @returns Cached background layout for the current viewport size.
61
+ */
62
+ export function resolveCachedPlaybackBackgroundLayout(
63
+ visibleWorldHeightPx: number,
64
+ factory: PlaybackBackgroundLayoutFactory,
65
+ ): PlaybackBackgroundLayout {
66
+ const cachedLayout = cachedLayoutsByHeightPx.get(visibleWorldHeightPx);
67
+ if (cachedLayout) {
68
+ return cachedLayout;
69
+ }
70
+
71
+ const resolvedLayout = factory();
72
+ cachedLayoutsByHeightPx.set(visibleWorldHeightPx, resolvedLayout);
73
+ return resolvedLayout;
74
+ }
75
+
76
+ /**
77
+ * Resolves cached tile coverage count for one tile width.
78
+ *
79
+ * @param tileWidthPx - Width of one repeated starfield tile in pixels.
80
+ * @param factory - Lazy coverage builder used when the cache misses.
81
+ * @returns Cached tile coverage count for the active viewport width.
82
+ */
83
+ export function resolveCachedPlaybackTileCoverageCount(
84
+ tileWidthPx: number,
85
+ factory: () => number,
86
+ ): number {
87
+ const cachedCoverageCount =
88
+ cachedTileCoverageCountsByTileWidthPx.get(tileWidthPx);
89
+ if (cachedCoverageCount !== undefined) {
90
+ return cachedCoverageCount;
91
+ }
92
+
93
+ const resolvedCoverageCount = factory();
94
+ cachedTileCoverageCountsByTileWidthPx.set(tileWidthPx, resolvedCoverageCount);
95
+ return resolvedCoverageCount;
96
+ }
@@ -0,0 +1,62 @@
1
+ import { FLAPPY_NEON_PALETTE } from '../../../constants/constants';
2
+ import type { PlaybackHorizonStyle } from './playback.background.types';
3
+
4
+ /**
5
+ * Background layout ratio reserved for the starfield sky band.
6
+ *
7
+ * The top band intentionally occupies most of the scene so the future ground
8
+ * layer can take over the lower strip without competing with the stars.
9
+ */
10
+ export const FLAPPY_BACKGROUND_SKY_HEIGHT_RATIO = 2 / 3;
11
+
12
+ /** Minimum safe viewport dimension used by background render math (pixels). */
13
+ export const FLAPPY_BACKGROUND_MIN_VIEWPORT_DIMENSION_PX = 1;
14
+
15
+ /** Index offset used to draw one extra tile before the visible left edge. */
16
+ export const FLAPPY_BACKGROUND_TILE_ROW_START_INDEX = -1;
17
+
18
+ /** Extra tile count rendered past the visible right edge for seamless wrap. */
19
+ export const FLAPPY_BACKGROUND_TILE_ROW_BUFFER_COUNT = 1;
20
+
21
+ /** Half-thickness multiplier used to center the horizon line on the split. */
22
+ export const FLAPPY_BACKGROUND_HORIZON_HALF_THICKNESS_MULTIPLIER = 0.5;
23
+
24
+ /** Divisor used to detect odd stroke widths for pixel snapping. */
25
+ export const FLAPPY_BACKGROUND_ODD_STROKE_DIVISOR = 2;
26
+
27
+ /** Pixel offset used to align odd-width strokes to the device pixel grid. */
28
+ export const FLAPPY_BACKGROUND_ODD_STROKE_ALIGNMENT_OFFSET_PX = 0.5;
29
+
30
+ /** Composite mode used for standard opaque drawing passes. */
31
+ export const FLAPPY_BACKGROUND_COMPOSITE_SOURCE_OVER = 'source-over';
32
+
33
+ /** Composite mode used when stacking glow-heavy starfield layers. */
34
+ export const FLAPPY_BACKGROUND_COMPOSITE_LIGHTER = 'lighter';
35
+
36
+ /** Transparent shadow color used to reset canvas glow state. */
37
+ export const FLAPPY_BACKGROUND_TRANSPARENT_SHADOW_COLOR = 'transparent';
38
+
39
+ /** Thickness of the neon horizon divider line (pixels). */
40
+ export const FLAPPY_BACKGROUND_HORIZON_LINE_THICKNESS_PX = 4;
41
+
42
+ /** Soft glow opacity applied during the horizon glow pass. */
43
+ export const FLAPPY_BACKGROUND_HORIZON_GLOW_ALPHA = 0.92;
44
+
45
+ /** Blur radius used to bloom the horizon divider glow (pixels). */
46
+ export const FLAPPY_BACKGROUND_HORIZON_GLOW_BLUR_PX = 14;
47
+
48
+ /**
49
+ * Frozen neon paint bundle reused by the playback horizon renderer.
50
+ *
51
+ * Keeping this style object in the constants module prevents repeated
52
+ * allocation during every background frame while still keeping the palette
53
+ * centrally theme-owned.
54
+ */
55
+ export const FLAPPY_BACKGROUND_HORIZON_STYLE: PlaybackHorizonStyle =
56
+ Object.freeze({
57
+ lineColor: FLAPPY_NEON_PALETTE.horizonLine,
58
+ glowColor: FLAPPY_NEON_PALETTE.horizonGlow,
59
+ glowAlpha: FLAPPY_BACKGROUND_HORIZON_GLOW_ALPHA,
60
+ glowBlurPx: FLAPPY_BACKGROUND_HORIZON_GLOW_BLUR_PX,
61
+ lineThicknessPx: FLAPPY_BACKGROUND_HORIZON_LINE_THICKNESS_PX,
62
+ });
@@ -0,0 +1,244 @@
1
+ import { FLAPPY_NEON_PALETTE } from '../../../constants/constants';
2
+ import { resolveStarfieldTiles } from '../playback.starfield.service';
3
+ import { positiveModulo } from '../playback.starfield.utils';
4
+ import {
5
+ ensurePlaybackBackgroundViewportCacheValidity,
6
+ resolveCachedPlaybackBackgroundLayout,
7
+ resolveCachedPlaybackTileCoverageCount,
8
+ } from './playback.background.cache.services';
9
+ import {
10
+ FLAPPY_BACKGROUND_COMPOSITE_LIGHTER,
11
+ FLAPPY_BACKGROUND_COMPOSITE_SOURCE_OVER,
12
+ FLAPPY_BACKGROUND_TILE_ROW_BUFFER_COUNT,
13
+ FLAPPY_BACKGROUND_TILE_ROW_START_INDEX,
14
+ FLAPPY_BACKGROUND_TRANSPARENT_SHADOW_COLOR,
15
+ } from './playback.background.constants';
16
+ import type {
17
+ PlaybackBackgroundRequest,
18
+ PlaybackBackgroundSceneContext,
19
+ PlaybackHorizonLineRequest,
20
+ } from './playback.background.types';
21
+ import {
22
+ resolveAlignedHorizonYPx,
23
+ resolvePlaybackBackgroundLayout,
24
+ resolvePlaybackHorizonStyle,
25
+ resolveSafeBackgroundDimension,
26
+ } from './playback.background.utils';
27
+
28
+ /**
29
+ * Resolves the derived scene contract required by the background passes.
30
+ *
31
+ * @param request - Narrow render input required for background composition.
32
+ * @returns Immutable scene context shared by the private render helpers.
33
+ */
34
+ export function resolvePlaybackBackgroundSceneContext(
35
+ request: PlaybackBackgroundRequest,
36
+ ): PlaybackBackgroundSceneContext {
37
+ // Step 1: Clamp viewport dimensions into render-safe pixel values.
38
+ const visibleWorldWidthPx = resolveSafeBackgroundDimension(
39
+ request.visibleWorldWidthPx,
40
+ );
41
+ const visibleWorldHeightPx = resolveSafeBackgroundDimension(
42
+ request.visibleWorldHeightPx,
43
+ );
44
+ ensurePlaybackBackgroundViewportCacheValidity(
45
+ visibleWorldWidthPx,
46
+ visibleWorldHeightPx,
47
+ );
48
+
49
+ // Step 2: Resolve the vertical sky-ground split and horizon style.
50
+ const backgroundLayout = resolveCachedPlaybackBackgroundLayout(
51
+ visibleWorldHeightPx,
52
+ () => resolvePlaybackBackgroundLayout(visibleWorldHeightPx),
53
+ );
54
+ const horizonStyle = resolvePlaybackHorizonStyle();
55
+ const alignedHorizonYPx = resolveAlignedHorizonYPx(
56
+ backgroundLayout.horizonYPx,
57
+ horizonStyle.lineThicknessPx,
58
+ );
59
+ const vanishingPointXPx = request.viewportLeftXPx + visibleWorldWidthPx * 0.5;
60
+ const vanishingPointYPx = visibleWorldHeightPx * 0.5;
61
+
62
+ // Step 3: Return a compact context object for the remaining passes.
63
+ return {
64
+ viewportLeftXPx: request.viewportLeftXPx,
65
+ visibleWorldWidthPx,
66
+ visibleWorldHeightPx,
67
+ skyHeightPx: backgroundLayout.skyHeightPx,
68
+ lowerBandTopYPx: backgroundLayout.lowerBandTopYPx,
69
+ lowerBandHeightPx: backgroundLayout.lowerBandHeightPx,
70
+ lowerBandBottomYPx: backgroundLayout.lowerBandBottomYPx,
71
+ alignedHorizonYPx,
72
+ vanishingPointXPx,
73
+ vanishingPointYPx,
74
+ horizonStyle,
75
+ };
76
+ }
77
+
78
+ /**
79
+ * Paints the base background fill for the currently visible viewport.
80
+ *
81
+ * @param context - Canvas 2D drawing context.
82
+ * @param sceneContext - Derived scene geometry and style contract.
83
+ * @returns Nothing.
84
+ */
85
+ export function paintPlaybackBackgroundBase(
86
+ context: CanvasRenderingContext2D,
87
+ sceneContext: PlaybackBackgroundSceneContext,
88
+ ): void {
89
+ // Step 1: Reset canvas paint state to a predictable base pass.
90
+ context.globalAlpha = 1;
91
+ context.globalCompositeOperation = FLAPPY_BACKGROUND_COMPOSITE_SOURCE_OVER;
92
+ context.shadowBlur = 0;
93
+ context.shadowColor = FLAPPY_BACKGROUND_TRANSPARENT_SHADOW_COLOR;
94
+ context.fillStyle = FLAPPY_NEON_PALETTE.background;
95
+
96
+ // Step 2: Fill only the currently visible world-space viewport.
97
+ context.fillRect(
98
+ sceneContext.viewportLeftXPx,
99
+ 0,
100
+ sceneContext.visibleWorldWidthPx,
101
+ sceneContext.visibleWorldHeightPx,
102
+ );
103
+ }
104
+
105
+ /**
106
+ * Draws the starfield parallax clipped to the upper sky band.
107
+ *
108
+ * @param context - Canvas 2D drawing context.
109
+ * @param sceneContext - Derived scene geometry and style contract.
110
+ * @param request - Narrow render input required for background composition.
111
+ * @returns Nothing.
112
+ */
113
+ export function drawPlaybackBackgroundSky(
114
+ context: CanvasRenderingContext2D,
115
+ sceneContext: PlaybackBackgroundSceneContext,
116
+ request: PlaybackBackgroundRequest,
117
+ ): void {
118
+ // Step 1: Constrain star drawing to the sky band above the horizon.
119
+ context.save();
120
+ context.beginPath();
121
+ context.rect(
122
+ sceneContext.viewportLeftXPx,
123
+ 0,
124
+ sceneContext.visibleWorldWidthPx,
125
+ sceneContext.skyHeightPx,
126
+ );
127
+ context.clip();
128
+ context.globalCompositeOperation = FLAPPY_BACKGROUND_COMPOSITE_LIGHTER;
129
+
130
+ // Step 2: Draw each cached starfield layer with its own parallax offset.
131
+ const starfieldTiles = resolveStarfieldTiles(sceneContext.skyHeightPx);
132
+ for (const starfieldTile of starfieldTiles) {
133
+ const scrollOffsetPx = request.scrollBasePx * starfieldTile.scrollRatio;
134
+ drawPlaybackTiledImageRow(
135
+ context,
136
+ sceneContext.viewportLeftXPx,
137
+ starfieldTile.image,
138
+ starfieldTile.tileWidthPx,
139
+ sceneContext.visibleWorldWidthPx,
140
+ scrollOffsetPx,
141
+ );
142
+ }
143
+
144
+ // Step 3: Restore the caller's unclipped canvas state.
145
+ context.restore();
146
+ }
147
+
148
+ /**
149
+ * Draws the glowing horizon divider across the visible viewport.
150
+ *
151
+ * @param context - Canvas 2D drawing context.
152
+ * @param sceneContext - Derived scene geometry and style contract.
153
+ * @returns Nothing.
154
+ */
155
+ export function drawPlaybackBackgroundHorizon(
156
+ context: CanvasRenderingContext2D,
157
+ sceneContext: PlaybackBackgroundSceneContext,
158
+ ): void {
159
+ // Step 1: Delegate the divider rendering to the dedicated horizon helper.
160
+ drawPlaybackHorizonLine(context, {
161
+ viewportLeftXPx: sceneContext.viewportLeftXPx,
162
+ visibleWorldWidthPx: sceneContext.visibleWorldWidthPx,
163
+ alignedHorizonYPx: sceneContext.alignedHorizonYPx,
164
+ horizonStyle: sceneContext.horizonStyle,
165
+ });
166
+ }
167
+
168
+ /**
169
+ * Draws a horizontally tiled image strip across the visible width.
170
+ *
171
+ * @param context - Canvas 2D drawing context.
172
+ * @param startXPx - Leftmost visible world x-position for the tiled strip.
173
+ * @param tile - Pre-rendered tile image reused across the sky band.
174
+ * @param tileWidthPx - Width of one repeated tile in pixels.
175
+ * @param visibleWidthPx - Current visible width that must be fully covered.
176
+ * @param offsetPx - Parallax scroll offset used to wrap tile placement.
177
+ * @returns Nothing.
178
+ */
179
+ function drawPlaybackTiledImageRow(
180
+ context: CanvasRenderingContext2D,
181
+ startXPx: number,
182
+ tile: CanvasImageSource,
183
+ tileWidthPx: number,
184
+ visibleWidthPx: number,
185
+ offsetPx: number,
186
+ ): void {
187
+ // Step 1: Normalize the scroll offset so tile placement stays bounded.
188
+ const normalizedOffsetPx = positiveModulo(offsetPx, tileWidthPx);
189
+ const maximumTileIndex = resolveCachedPlaybackTileCoverageCount(
190
+ tileWidthPx,
191
+ () =>
192
+ Math.ceil(visibleWidthPx / tileWidthPx) +
193
+ FLAPPY_BACKGROUND_TILE_ROW_BUFFER_COUNT,
194
+ );
195
+
196
+ // Step 2: Draw enough repeated tiles to cover the visible strip.
197
+ for (
198
+ let tileIndex = FLAPPY_BACKGROUND_TILE_ROW_START_INDEX;
199
+ tileIndex <= maximumTileIndex;
200
+ tileIndex += 1
201
+ ) {
202
+ const tileLeftPx = startXPx + tileIndex * tileWidthPx - normalizedOffsetPx;
203
+ context.drawImage(tile, tileLeftPx, 0);
204
+ }
205
+ }
206
+
207
+ /**
208
+ * Draws the glowing horizon divider using the provided neon style.
209
+ *
210
+ * @param context - Canvas 2D drawing context.
211
+ * @param request - Width, aligned y-position, and style for the divider.
212
+ * @returns Nothing.
213
+ */
214
+ function drawPlaybackHorizonLine(
215
+ context: CanvasRenderingContext2D,
216
+ request: PlaybackHorizonLineRequest,
217
+ ): void {
218
+ // Step 1: Draw the outer glow pass to establish the neon bloom.
219
+ context.globalCompositeOperation = FLAPPY_BACKGROUND_COMPOSITE_SOURCE_OVER;
220
+ context.strokeStyle = request.horizonStyle.lineColor;
221
+ context.lineWidth = request.horizonStyle.lineThicknessPx;
222
+ context.shadowColor = request.horizonStyle.glowColor;
223
+ context.shadowBlur = request.horizonStyle.glowBlurPx;
224
+ context.globalAlpha = request.horizonStyle.glowAlpha;
225
+ context.beginPath();
226
+ context.moveTo(request.viewportLeftXPx, request.alignedHorizonYPx);
227
+ context.lineTo(
228
+ request.viewportLeftXPx + request.visibleWorldWidthPx,
229
+ request.alignedHorizonYPx,
230
+ );
231
+ context.stroke();
232
+
233
+ // Step 2: Restore a crisp core line after the glow pass.
234
+ context.shadowBlur = 0;
235
+ context.shadowColor = FLAPPY_BACKGROUND_TRANSPARENT_SHADOW_COLOR;
236
+ context.globalAlpha = 1;
237
+ context.beginPath();
238
+ context.moveTo(request.viewportLeftXPx, request.alignedHorizonYPx);
239
+ context.lineTo(
240
+ request.viewportLeftXPx + request.visibleWorldWidthPx,
241
+ request.alignedHorizonYPx,
242
+ );
243
+ context.stroke();
244
+ }
@@ -0,0 +1,53 @@
1
+ import { renderPlaybackBackgroundGroundGrid } from './ground-grid/playback.background.ground-grid';
2
+ import {
3
+ drawPlaybackBackgroundHorizon,
4
+ drawPlaybackBackgroundSky,
5
+ paintPlaybackBackgroundBase,
6
+ resolvePlaybackBackgroundSceneContext,
7
+ } from './playback.background.services';
8
+ import type { PlaybackBackgroundRequest } from './playback.background.types';
9
+
10
+ /**
11
+ * Draws the layered playback background.
12
+ *
13
+ * The composition keeps the top two-thirds for the neon starfield, fills the
14
+ * lower band with a TRON-like perspective ground grid, and separates both
15
+ * regions with a glowing horizon divider.
16
+ *
17
+ * @param context - Canvas 2D drawing context.
18
+ * @param request - Narrow render input required for background composition.
19
+ * @returns Nothing.
20
+ *
21
+ * @example
22
+ * ```ts
23
+ * renderPlaybackBackground(context, {
24
+ * viewportLeftXPx: cameraLeftPx,
25
+ * visibleWorldWidthPx: 288,
26
+ * visibleWorldHeightPx: 512,
27
+ * frameIndex,
28
+ * scrollBasePx: frameIndex * pipeSpeedPxPerFrame,
29
+ * });
30
+ * ```
31
+ */
32
+ export function renderPlaybackBackground(
33
+ context: CanvasRenderingContext2D,
34
+ request: PlaybackBackgroundRequest,
35
+ ): void {
36
+ // Step 1: Resolve the scene contracts needed by the background passes.
37
+ const backgroundSceneContext = resolvePlaybackBackgroundSceneContext(request);
38
+
39
+ // Step 2: Paint the shared base fill behind all background layers.
40
+ paintPlaybackBackgroundBase(context, backgroundSceneContext);
41
+
42
+ // Step 3: Render the sky-only starfield inside the horizon clip band.
43
+ drawPlaybackBackgroundSky(context, backgroundSceneContext, request);
44
+
45
+ // Step 4: Render the lower-band neon grid beneath the horizon seam.
46
+ renderPlaybackBackgroundGroundGrid(context, backgroundSceneContext, {
47
+ frameIndex: request.frameIndex,
48
+ scrollBasePx: request.scrollBasePx,
49
+ });
50
+
51
+ // Step 5: Draw the horizon divider above the sky and ground layers.
52
+ drawPlaybackBackgroundHorizon(context, backgroundSceneContext);
53
+ }
@@ -0,0 +1,68 @@
1
+ /**
2
+ * Minimal render input required to draw the playback background.
3
+ *
4
+ * Keeping this contract narrow prevents the background renderer from reaching
5
+ * into unrelated playback state such as birds, pipes, or trail caches.
6
+ */
7
+ export type PlaybackBackgroundRequest = {
8
+ viewportLeftXPx: number;
9
+ visibleWorldWidthPx: number;
10
+ visibleWorldHeightPx: number;
11
+ frameIndex: number;
12
+ scrollBasePx: number;
13
+ };
14
+
15
+ /**
16
+ * Derived scene contract shared by the playback background render passes.
17
+ */
18
+ export type PlaybackBackgroundSceneContext = {
19
+ viewportLeftXPx: number;
20
+ visibleWorldWidthPx: number;
21
+ visibleWorldHeightPx: number;
22
+ skyHeightPx: number;
23
+ lowerBandTopYPx: number;
24
+ lowerBandHeightPx: number;
25
+ lowerBandBottomYPx: number;
26
+ alignedHorizonYPx: number;
27
+ vanishingPointXPx: number;
28
+ vanishingPointYPx: number;
29
+ horizonStyle: PlaybackHorizonStyle;
30
+ };
31
+
32
+ /**
33
+ * Resolved vertical scene split used by playback background composition.
34
+ */
35
+ export type PlaybackBackgroundLayout = {
36
+ skyHeightPx: number;
37
+ lowerBandTopYPx: number;
38
+ lowerBandHeightPx: number;
39
+ lowerBandBottomYPx: number;
40
+ horizonYPx: number;
41
+ horizonThicknessPx: number;
42
+ };
43
+
44
+ /**
45
+ * Zero-argument builder used to lazily construct one cached background layout.
46
+ */
47
+ export type PlaybackBackgroundLayoutFactory = () => PlaybackBackgroundLayout;
48
+
49
+ /**
50
+ * Neon styling contract for the horizon divider line.
51
+ */
52
+ export type PlaybackHorizonStyle = {
53
+ lineColor: string;
54
+ glowColor: string;
55
+ glowAlpha: number;
56
+ glowBlurPx: number;
57
+ lineThicknessPx: number;
58
+ };
59
+
60
+ /**
61
+ * Draw request for the horizon divider line.
62
+ */
63
+ export type PlaybackHorizonLineRequest = {
64
+ viewportLeftXPx: number;
65
+ visibleWorldWidthPx: number;
66
+ alignedHorizonYPx: number;
67
+ horizonStyle: PlaybackHorizonStyle;
68
+ };