siderust-js 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (272) hide show
  1. package/.github/workflows/ci.yml +166 -0
  2. package/.gitmodules +9 -0
  3. package/CHANGELOG.md +26 -0
  4. package/LICENSE +661 -0
  5. package/README.md +138 -0
  6. package/package.json +12 -0
  7. package/qtty-js/.github/workflows/ci.yml +151 -0
  8. package/qtty-js/.gitmodules +3 -0
  9. package/qtty-js/CHANGELOG.md +31 -0
  10. package/qtty-js/LICENSE +661 -0
  11. package/qtty-js/README.md +132 -0
  12. package/qtty-js/package.json +20 -0
  13. package/qtty-js/qtty/.github/workflows/ci.yml +155 -0
  14. package/qtty-js/qtty/CHANGELOG.md +120 -0
  15. package/qtty-js/qtty/Cargo.lock +1462 -0
  16. package/qtty-js/qtty/Cargo.toml +12 -0
  17. package/qtty-js/qtty/LICENSE +661 -0
  18. package/qtty-js/qtty/README.md +9 -0
  19. package/qtty-js/qtty/qtty/Cargo.toml +41 -0
  20. package/qtty-js/qtty/qtty/README.md +8 -0
  21. package/qtty-js/qtty/qtty/examples/angles.rs +14 -0
  22. package/qtty-js/qtty/qtty/examples/astronomy.rs +17 -0
  23. package/qtty-js/qtty/qtty/examples/dimensional_arithmetic.rs +83 -0
  24. package/qtty-js/qtty/qtty/examples/python_integration.rs +61 -0
  25. package/qtty-js/qtty/qtty/examples/quickstart.rs +15 -0
  26. package/qtty-js/qtty/qtty/examples/ratios.rs +12 -0
  27. package/qtty-js/qtty/qtty/examples/serde_with_unit.rs +234 -0
  28. package/qtty-js/qtty/qtty/examples/serialization.rs +141 -0
  29. package/qtty-js/qtty/qtty/examples/serialization_advanced.rs +155 -0
  30. package/qtty-js/qtty/qtty/src/f32.rs +108 -0
  31. package/qtty-js/qtty/qtty/src/f64.rs +30 -0
  32. package/qtty-js/qtty/qtty/src/i128.rs +111 -0
  33. package/qtty-js/qtty/qtty/src/i16.rs +111 -0
  34. package/qtty-js/qtty/qtty/src/i32.rs +111 -0
  35. package/qtty-js/qtty/qtty/src/i64.rs +111 -0
  36. package/qtty-js/qtty/qtty/src/i8.rs +111 -0
  37. package/qtty-js/qtty/qtty/src/lib.rs +238 -0
  38. package/qtty-js/qtty/qtty/tests/fixtures/qtty-vec-no-std/Cargo.lock +83 -0
  39. package/qtty-js/qtty/qtty/tests/fixtures/qtty-vec-no-std/Cargo.toml +10 -0
  40. package/qtty-js/qtty/qtty/tests/fixtures/qtty-vec-no-std/src/lib.rs +7 -0
  41. package/qtty-js/qtty/qtty/tests/fixtures/qtty-vec-no-std-alloc/Cargo.lock +83 -0
  42. package/qtty-js/qtty/qtty/tests/fixtures/qtty-vec-no-std-alloc/Cargo.toml +10 -0
  43. package/qtty-js/qtty/qtty/tests/fixtures/qtty-vec-no-std-alloc/src/lib.rs +7 -0
  44. package/qtty-js/qtty/qtty/tests/fixtures/qtty-vec-std/Cargo.lock +83 -0
  45. package/qtty-js/qtty/qtty/tests/fixtures/qtty-vec-std/Cargo.toml +10 -0
  46. package/qtty-js/qtty/qtty/tests/fixtures/qtty-vec-std/src/lib.rs +5 -0
  47. package/qtty-js/qtty/qtty/tests/integration_tests.rs +529 -0
  48. package/qtty-js/qtty/qtty/tests/qtty_vec_feature_matrix.rs +58 -0
  49. package/qtty-js/qtty/qtty-core/Cargo.toml +41 -0
  50. package/qtty-js/qtty/qtty-core/README.md +8 -0
  51. package/qtty-js/qtty/qtty-core/examples/diesel_integration.rs +145 -0
  52. package/qtty-js/qtty/qtty-core/examples/quantity_db_serde.rs +215 -0
  53. package/qtty-js/qtty/qtty-core/src/dimension.rs +249 -0
  54. package/qtty-js/qtty/qtty-core/src/feature_diesel.rs +318 -0
  55. package/qtty-js/qtty/qtty-core/src/feature_pyo3.rs +27 -0
  56. package/qtty-js/qtty/qtty-core/src/feature_serde.rs +203 -0
  57. package/qtty-js/qtty/qtty-core/src/feature_tiberius.rs +28 -0
  58. package/qtty-js/qtty/qtty-core/src/lib.rs +744 -0
  59. package/qtty-js/qtty/qtty-core/src/macros.rs +93 -0
  60. package/qtty-js/qtty/qtty-core/src/quantity.rs +810 -0
  61. package/qtty-js/qtty/qtty-core/src/scalar.rs +1742 -0
  62. package/qtty-js/qtty/qtty-core/src/unit.rs +332 -0
  63. package/qtty-js/qtty/qtty-core/src/units/angular.rs +1228 -0
  64. package/qtty-js/qtty/qtty-core/src/units/area.rs +243 -0
  65. package/qtty-js/qtty/qtty-core/src/units/frequency.rs +179 -0
  66. package/qtty-js/qtty/qtty-core/src/units/length.rs +1270 -0
  67. package/qtty-js/qtty/qtty-core/src/units/mass.rs +488 -0
  68. package/qtty-js/qtty/qtty-core/src/units/mod.rs +26 -0
  69. package/qtty-js/qtty/qtty-core/src/units/power.rs +324 -0
  70. package/qtty-js/qtty/qtty-core/src/units/time.rs +667 -0
  71. package/qtty-js/qtty/qtty-core/src/units/unitless.rs +212 -0
  72. package/qtty-js/qtty/qtty-core/src/units/velocity.rs +210 -0
  73. package/qtty-js/qtty/qtty-core/src/units/volume.rs +269 -0
  74. package/qtty-js/qtty/qtty-core/tests/core.rs +628 -0
  75. package/qtty-js/qtty/qtty-core/tests/diesel.rs +461 -0
  76. package/qtty-js/qtty/qtty-core/tests/integers.rs +632 -0
  77. package/qtty-js/qtty/qtty-core/tests/no_cross_unit_ops.rs +35 -0
  78. package/qtty-js/qtty/qtty-core/tests/pyo3.rs +334 -0
  79. package/qtty-js/qtty/qtty-core/tests/quantity_f32.rs +276 -0
  80. package/qtty-js/qtty/qtty-core/tests/scalar_decimal.rs +258 -0
  81. package/qtty-js/qtty/qtty-core/tests/scalar_f32.rs +286 -0
  82. package/qtty-js/qtty/qtty-core/tests/scalar_f64_real.rs +287 -0
  83. package/qtty-js/qtty/qtty-core/tests/scalar_rational.rs +260 -0
  84. package/qtty-js/qtty/qtty-core/tests/serde.rs +256 -0
  85. package/qtty-js/qtty/qtty-core/tests/tiberius.rs +208 -0
  86. package/qtty-js/qtty/qtty-derive/Cargo.toml +23 -0
  87. package/qtty-js/qtty/qtty-derive/README.md +8 -0
  88. package/qtty-js/qtty/qtty-derive/src/lib.rs +340 -0
  89. package/qtty-js/qtty/qtty-ffi/ARCHITECTURE.md +3 -0
  90. package/qtty-js/qtty/qtty-ffi/Cargo.toml +31 -0
  91. package/qtty-js/qtty/qtty-ffi/README.md +9 -0
  92. package/qtty-js/qtty/qtty-ffi/build.rs +326 -0
  93. package/qtty-js/qtty/qtty-ffi/cbindgen.toml +105 -0
  94. package/qtty-js/qtty/qtty-ffi/include/qtty_ffi.h +1126 -0
  95. package/qtty-js/qtty/qtty-ffi/src/ffi.rs +1251 -0
  96. package/qtty-js/qtty/qtty-ffi/src/ffi_serde.rs +294 -0
  97. package/qtty-js/qtty/qtty-ffi/src/helpers.rs +310 -0
  98. package/qtty-js/qtty/qtty-ffi/src/lib.rs +229 -0
  99. package/qtty-js/qtty/qtty-ffi/src/macros.rs +121 -0
  100. package/qtty-js/qtty/qtty-ffi/src/registry.rs +274 -0
  101. package/qtty-js/qtty/qtty-ffi/src/types.rs +620 -0
  102. package/qtty-js/qtty/qtty-ffi/tests/integration_tests.rs +842 -0
  103. package/qtty-js/qtty/qtty-ffi/units.csv +156 -0
  104. package/qtty-js/qtty/qtty-ffi/units.csv.md +3 -0
  105. package/qtty-js/qtty-node/.prettierignore +6 -0
  106. package/qtty-js/qtty-node/.prettierrc.json +6 -0
  107. package/qtty-js/qtty-node/README.md +250 -0
  108. package/qtty-js/qtty-node/c8.config.json +11 -0
  109. package/qtty-js/qtty-node/eslint.config.js +31 -0
  110. package/qtty-js/qtty-node/examples/arithmetic.mjs +64 -0
  111. package/qtty-js/qtty-node/examples/astronomy.mjs +90 -0
  112. package/qtty-js/qtty-node/examples/quickstart.mjs +36 -0
  113. package/qtty-js/qtty-node/examples/serialization.mjs +125 -0
  114. package/qtty-js/qtty-node/examples/unit_factories.mjs +74 -0
  115. package/qtty-js/qtty-node/index.d.ts +219 -0
  116. package/qtty-js/qtty-node/index.js +323 -0
  117. package/qtty-js/qtty-node/lib/DerivedQuantity.js +122 -0
  118. package/qtty-js/qtty-node/lib/Quantity.js +151 -0
  119. package/qtty-js/qtty-node/lib/backend.js +25 -0
  120. package/qtty-js/qtty-node/native.cjs +306 -0
  121. package/qtty-js/qtty-node/package-lock.json +3223 -0
  122. package/qtty-js/qtty-node/package.json +70 -0
  123. package/qtty-js/qtty-node/units.d.ts +299 -0
  124. package/qtty-js/qtty-node/units.js +210 -0
  125. package/qtty-js/qtty-web/Cargo.lock +767 -0
  126. package/qtty-js/qtty-web/Cargo.toml +21 -0
  127. package/qtty-js/qtty-web/index.d.ts +140 -0
  128. package/qtty-js/qtty-web/index.js +20 -0
  129. package/qtty-js/qtty-web/lib/DerivedQuantity.js +58 -0
  130. package/qtty-js/qtty-web/lib/Quantity.js +75 -0
  131. package/qtty-js/qtty-web/lib/backend.js +80 -0
  132. package/qtty-js/qtty-web/package.json +45 -0
  133. package/qtty-js/qtty-web/src/lib.rs +111 -0
  134. package/qtty-js/scripts/ci.sh +73 -0
  135. package/scripts/ci.sh +123 -0
  136. package/siderust-core/Cargo.lock +787 -0
  137. package/siderust-core/Cargo.toml +18 -0
  138. package/siderust-core/DEDUPLICATION.md +124 -0
  139. package/siderust-core/src/body.rs +120 -0
  140. package/siderust-core/src/events.rs +184 -0
  141. package/siderust-core/src/lib.rs +20 -0
  142. package/siderust-core/src/observer.rs +55 -0
  143. package/siderust-core/src/position.rs +213 -0
  144. package/siderust-node/.prettierignore +7 -0
  145. package/siderust-node/.prettierrc.json +6 -0
  146. package/siderust-node/Cargo.lock +906 -0
  147. package/siderust-node/Cargo.toml +29 -0
  148. package/siderust-node/README.md +109 -0
  149. package/siderust-node/__test__/index.test.mjs +248 -0
  150. package/siderust-node/build.rs +5 -0
  151. package/siderust-node/c8.config.json +3 -0
  152. package/siderust-node/eslint.config.js +31 -0
  153. package/siderust-node/examples/01_basic_coordinates.mjs +24 -0
  154. package/siderust-node/examples/02_coordinate_transformations.mjs +25 -0
  155. package/siderust-node/examples/03_all_frames_conversions.mjs +26 -0
  156. package/siderust-node/examples/04_all_center_conversions.mjs +24 -0
  157. package/siderust-node/examples/05_target_tracking.mjs +22 -0
  158. package/siderust-node/examples/06_night_events.mjs +18 -0
  159. package/siderust-node/examples/07_moon_properties.mjs +21 -0
  160. package/siderust-node/examples/08_solar_system.mjs +19 -0
  161. package/siderust-node/examples/09_star_observability.mjs +22 -0
  162. package/siderust-node/examples/10_time_periods.mjs +9 -0
  163. package/siderust-node/examples/11_serialization.mjs +31 -0
  164. package/siderust-node/examples/12_runtime_ephemeris.mjs +27 -0
  165. package/siderust-node/examples/13_coordinate_operations.mjs +20 -0
  166. package/siderust-node/index.d.ts +623 -0
  167. package/siderust-node/index.js +79 -0
  168. package/siderust-node/lib/Observer.js +112 -0
  169. package/siderust-node/lib/Star.js +118 -0
  170. package/siderust-node/lib/backend.js +63 -0
  171. package/siderust-node/lib/wrappers.js +566 -0
  172. package/siderust-node/main.js +20 -0
  173. package/siderust-node/native.cjs +360 -0
  174. package/siderust-node/package-lock.json +3261 -0
  175. package/siderust-node/package.json +71 -0
  176. package/siderust-node/src/body.rs +74 -0
  177. package/siderust-node/src/coordinates.rs +372 -0
  178. package/siderust-node/src/ephemeris.rs +462 -0
  179. package/siderust-node/src/events.rs +577 -0
  180. package/siderust-node/src/lib.rs +43 -0
  181. package/siderust-node/src/observer.rs +132 -0
  182. package/siderust-node/src/phase.rs +218 -0
  183. package/siderust-node/src/position.rs +292 -0
  184. package/siderust-node/src/star.rs +200 -0
  185. package/siderust-web/Cargo.lock +855 -0
  186. package/siderust-web/Cargo.toml +34 -0
  187. package/siderust-web/README.md +100 -0
  188. package/siderust-web/__test__/index.test.mjs +118 -0
  189. package/siderust-web/examples/github-pages/README.md +31 -0
  190. package/siderust-web/examples/github-pages/index.html +135 -0
  191. package/siderust-web/index.d.ts +311 -0
  192. package/siderust-web/index.js +66 -0
  193. package/siderust-web/lib/Observer.js +103 -0
  194. package/siderust-web/lib/Star.js +116 -0
  195. package/siderust-web/lib/backend.js +400 -0
  196. package/siderust-web/lib/wrappers.js +512 -0
  197. package/siderust-web/package.json +55 -0
  198. package/siderust-web/src/body.rs +69 -0
  199. package/siderust-web/src/coordinates.rs +302 -0
  200. package/siderust-web/src/ephemeris.rs +456 -0
  201. package/siderust-web/src/events.rs +520 -0
  202. package/siderust-web/src/lib.rs +51 -0
  203. package/siderust-web/src/observer.rs +117 -0
  204. package/siderust-web/src/phase.rs +190 -0
  205. package/siderust-web/src/position.rs +291 -0
  206. package/siderust-web/src/star.rs +178 -0
  207. package/tempoch-js/.github/workflows/ci.yml +142 -0
  208. package/tempoch-js/.gitmodules +3 -0
  209. package/tempoch-js/CHANGELOG.md +25 -0
  210. package/tempoch-js/LICENSE +661 -0
  211. package/tempoch-js/README.md +126 -0
  212. package/tempoch-js/package.json +20 -0
  213. package/tempoch-js/scripts/ci.sh +73 -0
  214. package/tempoch-js/tempoch/.github/workflows/ci.yml +113 -0
  215. package/tempoch-js/tempoch/CHANGELOG.md +82 -0
  216. package/tempoch-js/tempoch/Cargo.lock +947 -0
  217. package/tempoch-js/tempoch/Cargo.toml +3 -0
  218. package/tempoch-js/tempoch/LICENSE +661 -0
  219. package/tempoch-js/tempoch/README.md +76 -0
  220. package/tempoch-js/tempoch/tempoch/Cargo.toml +27 -0
  221. package/tempoch-js/tempoch/tempoch/examples/periods.rs +45 -0
  222. package/tempoch-js/tempoch/tempoch/examples/quickstart.rs +13 -0
  223. package/tempoch-js/tempoch/tempoch/src/lib.rs +49 -0
  224. package/tempoch-js/tempoch/tempoch/tests/integration.rs +57 -0
  225. package/tempoch-js/tempoch/tempoch-core/Cargo.toml +24 -0
  226. package/tempoch-js/tempoch/tempoch-core/src/delta_t.rs +345 -0
  227. package/tempoch-js/tempoch/tempoch-core/src/instant.rs +811 -0
  228. package/tempoch-js/tempoch/tempoch-core/src/julian_date_ext.rs +142 -0
  229. package/tempoch-js/tempoch/tempoch-core/src/lib.rs +81 -0
  230. package/tempoch-js/tempoch/tempoch-core/src/period.rs +1168 -0
  231. package/tempoch-js/tempoch/tempoch-core/src/scales.rs +779 -0
  232. package/tempoch-js/tempoch/tempoch-ffi/Cargo.lock +889 -0
  233. package/tempoch-js/tempoch/tempoch-ffi/Cargo.toml +26 -0
  234. package/tempoch-js/tempoch/tempoch-ffi/build.rs +24 -0
  235. package/tempoch-js/tempoch/tempoch-ffi/cbindgen.toml +30 -0
  236. package/tempoch-js/tempoch/tempoch-ffi/src/error.rs +19 -0
  237. package/tempoch-js/tempoch/tempoch-ffi/src/lib.rs +82 -0
  238. package/tempoch-js/tempoch/tempoch-ffi/src/period.rs +101 -0
  239. package/tempoch-js/tempoch/tempoch-ffi/src/time.rs +711 -0
  240. package/tempoch-js/tempoch/tempoch-ffi/tests/ffi.rs +265 -0
  241. package/tempoch-js/tempoch-node/.prettierignore +6 -0
  242. package/tempoch-js/tempoch-node/.prettierrc.json +6 -0
  243. package/tempoch-js/tempoch-node/Cargo.lock +496 -0
  244. package/tempoch-js/tempoch-node/Cargo.toml +29 -0
  245. package/tempoch-js/tempoch-node/README.md +265 -0
  246. package/tempoch-js/tempoch-node/__test__/index.test.mjs +598 -0
  247. package/tempoch-js/tempoch-node/build.rs +5 -0
  248. package/tempoch-js/tempoch-node/c8.config.json +3 -0
  249. package/tempoch-js/tempoch-node/eslint.config.js +31 -0
  250. package/tempoch-js/tempoch-node/examples/periods.mjs +79 -0
  251. package/tempoch-js/tempoch-node/examples/quickstart.mjs +71 -0
  252. package/tempoch-js/tempoch-node/examples/timescales.mjs +92 -0
  253. package/tempoch-js/tempoch-node/index.d.ts +280 -0
  254. package/tempoch-js/tempoch-node/index.js +32 -0
  255. package/tempoch-js/tempoch-node/lib/JulianDate.js +176 -0
  256. package/tempoch-js/tempoch-node/lib/ModifiedJulianDate.js +156 -0
  257. package/tempoch-js/tempoch-node/lib/Period.js +133 -0
  258. package/tempoch-js/tempoch-node/lib/backend.js +38 -0
  259. package/tempoch-js/tempoch-node/lib/qttyCompat.js +92 -0
  260. package/tempoch-js/tempoch-node/native.cjs +317 -0
  261. package/tempoch-js/tempoch-node/package-lock.json +3223 -0
  262. package/tempoch-js/tempoch-node/package.json +56 -0
  263. package/tempoch-js/tempoch-node/src/lib.rs +573 -0
  264. package/tempoch-js/tempoch-web/Cargo.toml +23 -0
  265. package/tempoch-js/tempoch-web/index.d.ts +95 -0
  266. package/tempoch-js/tempoch-web/index.js +27 -0
  267. package/tempoch-js/tempoch-web/lib/JulianDate.js +170 -0
  268. package/tempoch-js/tempoch-web/lib/ModifiedJulianDate.js +145 -0
  269. package/tempoch-js/tempoch-web/lib/Period.js +121 -0
  270. package/tempoch-js/tempoch-web/lib/backend.js +118 -0
  271. package/tempoch-js/tempoch-web/package.json +46 -0
  272. package/tempoch-js/tempoch-web/src/lib.rs +184 -0
@@ -0,0 +1,83 @@
1
+ # This file is automatically @generated by Cargo.
2
+ # It is not intended for manual editing.
3
+ version = 4
4
+
5
+ [[package]]
6
+ name = "libm"
7
+ version = "0.2.16"
8
+ source = "registry+https://github.com/rust-lang/crates.io-index"
9
+ checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981"
10
+
11
+ [[package]]
12
+ name = "proc-macro2"
13
+ version = "1.0.106"
14
+ source = "registry+https://github.com/rust-lang/crates.io-index"
15
+ checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934"
16
+ dependencies = [
17
+ "unicode-ident",
18
+ ]
19
+
20
+ [[package]]
21
+ name = "qtty"
22
+ version = "0.4.0"
23
+ dependencies = [
24
+ "qtty-core",
25
+ "qtty-derive",
26
+ ]
27
+
28
+ [[package]]
29
+ name = "qtty-core"
30
+ version = "0.4.0"
31
+ dependencies = [
32
+ "libm",
33
+ "qtty-derive",
34
+ "typenum",
35
+ ]
36
+
37
+ [[package]]
38
+ name = "qtty-derive"
39
+ version = "0.4.0"
40
+ dependencies = [
41
+ "proc-macro2",
42
+ "quote",
43
+ "syn",
44
+ ]
45
+
46
+ [[package]]
47
+ name = "qtty-vec-std-fixture"
48
+ version = "0.0.0"
49
+ dependencies = [
50
+ "qtty",
51
+ ]
52
+
53
+ [[package]]
54
+ name = "quote"
55
+ version = "1.0.44"
56
+ source = "registry+https://github.com/rust-lang/crates.io-index"
57
+ checksum = "21b2ebcf727b7760c461f091f9f0f539b77b8e87f2fd88131e7f1b433b3cece4"
58
+ dependencies = [
59
+ "proc-macro2",
60
+ ]
61
+
62
+ [[package]]
63
+ name = "syn"
64
+ version = "2.0.114"
65
+ source = "registry+https://github.com/rust-lang/crates.io-index"
66
+ checksum = "d4d107df263a3013ef9b1879b0df87d706ff80f65a86ea879bd9c31f9b307c2a"
67
+ dependencies = [
68
+ "proc-macro2",
69
+ "quote",
70
+ "unicode-ident",
71
+ ]
72
+
73
+ [[package]]
74
+ name = "typenum"
75
+ version = "1.19.0"
76
+ source = "registry+https://github.com/rust-lang/crates.io-index"
77
+ checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb"
78
+
79
+ [[package]]
80
+ name = "unicode-ident"
81
+ version = "1.0.23"
82
+ source = "registry+https://github.com/rust-lang/crates.io-index"
83
+ checksum = "537dd038a89878be9b64dd4bd1b260315c1bb94f4d784956b81e27a088d9a09e"
@@ -0,0 +1,10 @@
1
+ [package]
2
+ name = "qtty-vec-std-fixture"
3
+ version = "0.0.0"
4
+ edition = "2021"
5
+ publish = false
6
+
7
+ [dependencies]
8
+ qtty = { path = "../../.." }
9
+
10
+ [workspace]
@@ -0,0 +1,5 @@
1
+ use qtty::Seconds;
2
+
3
+ pub fn build_samples() -> Vec<Seconds> {
4
+ qtty::qtty_vec!(vec Seconds; 1.0, 2.0, 3.0)
5
+ }
@@ -0,0 +1,529 @@
1
+ //! Integration-level smoke tests for the `qtty` facade crate.
2
+
3
+ use qtty::*;
4
+
5
+ use approx::{assert_abs_diff_eq, assert_relative_eq};
6
+
7
+ #[test]
8
+ fn smoke_test_angular() {
9
+ let deg = Degrees::new(180.0);
10
+ let rad: Radians = deg.to();
11
+ assert_abs_diff_eq!(rad.value(), std::f64::consts::PI, epsilon = 1e-12);
12
+ }
13
+
14
+ #[test]
15
+ fn smoke_test_time() {
16
+ let day = Days::new(1.0);
17
+ let sec: Seconds = day.to();
18
+ assert_abs_diff_eq!(sec.value(), 86400.0, epsilon = 1e-9);
19
+ }
20
+
21
+ #[test]
22
+ fn smoke_test_length() {
23
+ let km = Kilometers::new(1.0);
24
+ let m: Meters = km.to();
25
+ assert_abs_diff_eq!(m.value(), 1000.0, epsilon = 1e-9);
26
+ }
27
+
28
+ #[test]
29
+ fn smoke_test_mass() {
30
+ let kg = Kilograms::new(1000.0);
31
+ let g: Grams = kg.to();
32
+ assert_abs_diff_eq!(g.value(), 1_000_000.0, epsilon = 1e-6);
33
+ }
34
+
35
+ #[test]
36
+ fn smoke_test_power() {
37
+ let sol = SolarLuminosities::new(1.0);
38
+ let w: Watts = sol.to();
39
+ assert_relative_eq!(w.value(), 3.828e26, max_relative = 1e-9);
40
+ }
41
+
42
+ #[test]
43
+ fn smoke_test_velocity() {
44
+ let v: velocity::Velocity<Kilometer, Second> = velocity::Velocity::new(1.0);
45
+ let v_mps: velocity::Velocity<Meter, Second> = v.to();
46
+ assert_abs_diff_eq!(v_mps.value(), 1000.0, epsilon = 1e-9);
47
+ }
48
+
49
+ #[test]
50
+ fn smoke_test_frequency() {
51
+ let f: frequency::Frequency<Degree, Day> = frequency::Frequency::new(360.0);
52
+ let f_rad: frequency::Frequency<Radian, Day> = f.to();
53
+ assert_abs_diff_eq!(f_rad.value(), 2.0 * std::f64::consts::PI, epsilon = 1e-12);
54
+ }
55
+
56
+ #[test]
57
+ fn smoke_test_unitless() {
58
+ let m = Meters::new(42.0);
59
+ let u: Quantity<Unitless> = m.into();
60
+ assert_eq!(u.value(), 42.0);
61
+ }
62
+
63
+ #[test]
64
+ fn smoke_test_unitless_from_time() {
65
+ let s = Seconds::new(5.0);
66
+ let u: Quantity<Unitless> = s.into();
67
+ assert_eq!(u.value(), 5.0);
68
+ }
69
+
70
+ #[test]
71
+ fn smoke_test_unitless_from_mass() {
72
+ let kg = Kilograms::new(2.0);
73
+ let u: Quantity<Unitless> = kg.into();
74
+ assert_eq!(u.value(), 2.0);
75
+ }
76
+
77
+ #[test]
78
+ fn smoke_test_unitless_from_angular() {
79
+ let deg = Degrees::new(15.0);
80
+ let u: Quantity<Unitless> = deg.into();
81
+ assert_eq!(u.value(), 15.0);
82
+ }
83
+
84
+ #[test]
85
+ fn orbital_distance_calculation() {
86
+ // Earth's orbital velocity ≈ 29.78 km/s
87
+ let earth_velocity: velocity::Velocity<Kilometer, Second> = velocity::Velocity::new(29.78);
88
+
89
+ // Time: 1 day
90
+ let time = Days::new(1.0);
91
+ let time_sec: Seconds = time.to();
92
+
93
+ // Distance = velocity × time
94
+ let distance: Kilometers = (earth_velocity * time_sec).to();
95
+
96
+ // Earth travels about 2.57 million km per day
97
+ assert_relative_eq!(distance.value(), 2_573_395.2, max_relative = 1e-3);
98
+ }
99
+
100
+ #[test]
101
+ fn proxima_centauri_distance() {
102
+ // Proxima Centauri is about 4.24 light years away
103
+ let distance_ly = LightYears::new(4.24);
104
+
105
+ // Convert to AU
106
+ let distance_au: AstronomicalUnits = distance_ly.to();
107
+
108
+ // Should be about 268,000 AU
109
+ assert_relative_eq!(distance_au.value(), 268_000.0, max_relative = 0.01);
110
+ }
111
+
112
+ #[test]
113
+ fn angular_separation() {
114
+ // Two stars at different positions
115
+ let star1_ra = Degrees::new(45.0);
116
+ let star2_ra = Degrees::new(350.0);
117
+
118
+ // Separation should wrap around
119
+ let sep = star1_ra.abs_separation(star2_ra);
120
+
121
+ // 45° to 350° is 55° the short way
122
+ assert_abs_diff_eq!(sep.value(), 55.0, epsilon = 1e-12);
123
+ }
124
+
125
+ #[test]
126
+ fn earth_rotation() {
127
+ // Earth rotates 360° per sidereal day (~23h 56m)
128
+ let rotation_rate: frequency::Frequency<Degree, Day> = frequency::Frequency::new(360.0);
129
+
130
+ // After 6 hours (0.25 days)
131
+ let time = Days::new(0.25);
132
+ let angle: Degrees = (rotation_rate * time).to();
133
+
134
+ assert_abs_diff_eq!(angle.value(), 90.0, epsilon = 1e-12);
135
+ }
136
+
137
+ #[test]
138
+ fn sun_mass() {
139
+ let sun = SolarMasses::new(1.0);
140
+ let kg: Kilograms = sun.to();
141
+
142
+ // Sun's mass is about 2e30 kg
143
+ assert_relative_eq!(kg.value(), 1.988416e30, max_relative = 1e-5);
144
+ }
145
+
146
+ #[test]
147
+ fn sun_luminosity() {
148
+ let sun = SolarLuminosities::new(1.0);
149
+ let watts: Watts = sun.to();
150
+
151
+ // Sun's luminosity is about 3.828e26 W
152
+ assert_relative_eq!(watts.value(), 3.828e26, max_relative = 1e-9);
153
+ }
154
+
155
+ #[test]
156
+ fn calculate_velocity_from_distance_time() {
157
+ // Light year to km
158
+ let distance = LightYears::new(1.0);
159
+ let distance_km: Kilometers = distance.to();
160
+
161
+ // Julian year to seconds
162
+ let time = JulianYears::new(1.0);
163
+ let time_sec: Seconds = time.to();
164
+
165
+ // Velocity = distance / time
166
+ let velocity: velocity::Velocity<Kilometer, Second> = distance_km / time_sec;
167
+
168
+ // Should be approximately speed of light (299,792 km/s)
169
+ assert_relative_eq!(velocity.value(), 299_792.458, max_relative = 0.001);
170
+ }
171
+
172
+ #[test]
173
+ fn mean_motion_conversion() {
174
+ // Earth's mean motion ≈ 0.9856°/day
175
+ let mean_motion: frequency::Frequency<Degree, Day> = frequency::Frequency::new(0.9856);
176
+
177
+ // Convert to degrees per year
178
+ let per_year: frequency::Frequency<Degree, Year> = mean_motion.to();
179
+
180
+ // Should be about 360°/year
181
+ assert_relative_eq!(per_year.value(), 360.0, max_relative = 0.01);
182
+ }
183
+
184
+ #[test]
185
+ fn trigonometric_calculation() {
186
+ // 30° angle
187
+ let angle = Degrees::new(30.0);
188
+
189
+ // sin(30°) = 0.5
190
+ assert_abs_diff_eq!(angle.sin(), 0.5, epsilon = 1e-12);
191
+
192
+ // cos(30°) = √3/2
193
+ assert_abs_diff_eq!(angle.cos(), 3.0_f64.sqrt() / 2.0, epsilon = 1e-12);
194
+
195
+ // tan(30°) = 1/√3
196
+ assert_abs_diff_eq!(angle.tan(), 1.0 / 3.0_f64.sqrt(), epsilon = 1e-12);
197
+ }
198
+
199
+ #[test]
200
+ fn derive_macro_produces_correct_symbol() {
201
+ // Verify that units defined with derive macro have correct symbols
202
+ assert_eq!(Meter::SYMBOL, "m");
203
+ assert_eq!(Kilometer::SYMBOL, "km");
204
+ assert_eq!(Second::SYMBOL, "s");
205
+ assert_eq!(Day::SYMBOL, "d");
206
+ assert_eq!(Degree::SYMBOL, "°");
207
+ assert_eq!(Radian::SYMBOL, "rad");
208
+ }
209
+
210
+ #[test]
211
+ fn derive_macro_produces_correct_ratio() {
212
+ // Verify ratios are correct
213
+ assert_eq!(Meter::RATIO, 1.0);
214
+ assert_eq!(Kilometer::RATIO, 1000.0);
215
+ assert_eq!(Second::RATIO, 1.0);
216
+ assert_eq!(Degree::RATIO, 1.0);
217
+ }
218
+
219
+ #[test]
220
+ fn derive_macro_display_formatting() {
221
+ let m = Meters::new(42.0);
222
+ assert_eq!(format!("{}", m), "42 m");
223
+
224
+ let km = Kilometers::new(1.5);
225
+ assert_eq!(format!("{}", km), "1.5 km");
226
+
227
+ let deg = Degrees::new(90.0);
228
+ assert_eq!(format!("{}", deg), "90 °");
229
+ }
230
+
231
+ #[test]
232
+ fn display_format_precision() {
233
+ let x = Seconds::new(1234.56789);
234
+ // {:.2} → two decimal places
235
+ assert_eq!(format!("{:.2}", x), "1234.57 s");
236
+ // {:.0} → no decimal places (rounded)
237
+ assert_eq!(format!("{:.0}", x), "1235 s");
238
+ // {:.5} → five decimal places
239
+ assert_eq!(format!("{:.5}", x), "1234.56789 s");
240
+ }
241
+
242
+ #[test]
243
+ fn display_lower_exp_formatting() {
244
+ let x = Seconds::new(1234.56789);
245
+ // {:e} → default scientific notation (lower-case e)
246
+ assert_eq!(format!("{:e}", x), "1.23456789e3 s");
247
+ // {:.4e} → precision + scientific
248
+ assert_eq!(format!("{:.4e}", x), "1.2346e3 s");
249
+ // {:.0e} → zero decimal places
250
+ assert_eq!(format!("{:.0e}", x), "1e3 s");
251
+ }
252
+
253
+ #[test]
254
+ fn display_upper_exp_formatting() {
255
+ let x = Seconds::new(1234.56789);
256
+ // {:E} → scientific notation upper-case E
257
+ assert_eq!(format!("{:E}", x), "1.23456789E3 s");
258
+ // {:.4E} → precision + upper-case scientific
259
+ assert_eq!(format!("{:.4E}", x), "1.2346E3 s");
260
+ }
261
+
262
+ #[test]
263
+ fn display_format_annotations_per_unit() {
264
+ let v: velocity::Velocity<Kilometer, Second> = velocity::Velocity::new(1234.56789);
265
+ // Default
266
+ assert_eq!(format!("{}", v), "1234.56789 km/s");
267
+ // Precision
268
+ assert_eq!(format!("{:.2}", v), "1234.57 km/s");
269
+ // Scientific lower
270
+ assert_eq!(format!("{:.4e}", v), "1.2346e3 km/s");
271
+ // Scientific upper
272
+ assert_eq!(format!("{:.4E}", v), "1.2346E3 km/s");
273
+ }
274
+
275
+ #[test]
276
+ fn display_sign_and_negative_values() {
277
+ let neg = Meters::new(-42.5);
278
+ assert_eq!(format!("{}", neg), "-42.5 m");
279
+ assert_eq!(format!("{:.1}", neg), "-42.5 m");
280
+ assert_eq!(format!("{:.2e}", neg), "-4.25e1 m");
281
+ }
282
+
283
+ #[test]
284
+ fn quantity_basic_arithmetic() {
285
+ let a = Meters::new(10.0);
286
+ let b = Meters::new(5.0);
287
+
288
+ assert_eq!((a + b).value(), 15.0);
289
+ assert_eq!((a - b).value(), 5.0);
290
+ assert_eq!((a * 2.0).value(), 20.0);
291
+ assert_eq!((a / 2.0).value(), 5.0);
292
+ }
293
+
294
+ #[test]
295
+ fn quantity_conversion_chain() {
296
+ // Convert through multiple units
297
+ let au = AstronomicalUnits::new(1.0);
298
+ let km: Kilometers = au.to();
299
+ let m: Meters = km.to();
300
+
301
+ // Direct conversion should match
302
+ let m_direct: Meters = au.to();
303
+ assert_abs_diff_eq!(m.value(), m_direct.value(), epsilon = 1e-3);
304
+ }
305
+
306
+ #[test]
307
+ fn quantity_negation() {
308
+ let pos = Degrees::new(45.0);
309
+ let neg = -pos;
310
+ assert_eq!(neg.value(), -45.0);
311
+ }
312
+
313
+ #[test]
314
+ fn quantity_abs() {
315
+ let neg = Degrees::new(-45.0);
316
+ assert_eq!(neg.abs().value(), 45.0);
317
+ }
318
+
319
+ #[test]
320
+ fn per_unit_display() {
321
+ let v: velocity::Velocity<Kilometer, Second> = velocity::Velocity::new(10.0);
322
+ let s = format!("{}", v);
323
+ assert_eq!(s, "10 km/s");
324
+ }
325
+
326
+ #[test]
327
+ fn per_unit_multiplication_recovers_numerator() {
328
+ let v: velocity::Velocity<Kilometer, Second> = velocity::Velocity::new(100.0);
329
+ let t: Seconds = Seconds::new(3600.0);
330
+ let d: Kilometers = (v * t).to();
331
+ assert_abs_diff_eq!(d.value(), 360_000.0, epsilon = 1e-6);
332
+ }
333
+
334
+ #[test]
335
+ fn qtty_values_macro_builds_seconds_array() {
336
+ const DT: [Seconds; 3] = qtty::qtty_vec!(Seconds; 56.86, 63.83, 70.0);
337
+ assert_abs_diff_eq!(DT[0].value(), 56.86, epsilon = 1e-12);
338
+ assert_abs_diff_eq!(DT[1].value(), 63.83, epsilon = 1e-12);
339
+ assert_abs_diff_eq!(DT[2].value(), 70.0, epsilon = 1e-12);
340
+ }
341
+
342
+ #[test]
343
+ fn qtty_values_macro_builds_seconds_vec() {
344
+ let dt: Vec<Seconds> = qtty::qtty_vec!(vec Seconds; 56.86, 63.83, 70.0);
345
+ assert_eq!(dt.len(), 3);
346
+ assert_abs_diff_eq!(dt[1].value(), 63.83, epsilon = 1e-12);
347
+ }
348
+
349
+ #[test]
350
+ fn per_unit_division_creates_composite() {
351
+ let d = Kilometers::new(100.0);
352
+ let t = Seconds::new(10.0);
353
+ let v: velocity::Velocity<Kilometer, Second> = d / t;
354
+ assert_abs_diff_eq!(v.value(), 10.0, epsilon = 1e-12);
355
+ }
356
+
357
+ #[test]
358
+ fn unit_constants_have_value_one() {
359
+ assert_eq!(AU.value(), 1.0);
360
+ assert_eq!(LY.value(), 1.0);
361
+ assert_eq!(KM.value(), 1.0);
362
+ assert_eq!(DAY.value(), 1.0);
363
+ assert_eq!(SEC.value(), 1.0);
364
+ assert_eq!(DEG.value(), 1.0);
365
+ assert_eq!(RAD.value(), 1.0);
366
+ }
367
+
368
+ #[test]
369
+ fn constants_can_be_multiplied() {
370
+ let distance = 4.24 * LY;
371
+ assert_eq!(distance.value(), 4.24);
372
+
373
+ let time = 365.25 * DAY;
374
+ assert_eq!(time.value(), 365.25);
375
+ }
376
+
377
+ #[test]
378
+ fn macro_generated_conversions() {
379
+ // Test conversions that are now generated by impl_unit_conversions! macro
380
+ // These weren't manually implemented before
381
+
382
+ // Meter -> AstronomicalUnit (AU is exactly 149,597,870,700 m)
383
+ let m = Meters::new(149_597_870_700.0);
384
+ let au: AstronomicalUnits = m.into();
385
+ assert_relative_eq!(au.value(), 1.0, max_relative = 1e-12);
386
+
387
+ // Nominal SolarRadius -> Kilometer
388
+ use qtty_core::length::nominal::SolarRadiuses;
389
+ let sr = SolarRadiuses::new(1.0);
390
+ let km: Kilometers = sr.into();
391
+ assert_abs_diff_eq!(km.value(), 695_700.0, epsilon = 1e-6);
392
+
393
+ // Parsec -> AstronomicalUnit
394
+ let pc = Parsecs::new(1.0);
395
+ let au: AstronomicalUnits = pc.into();
396
+ // 1 pc = au * 648000 / π
397
+ let expected = 648_000.0 / core::f64::consts::PI;
398
+ assert_relative_eq!(au.value(), expected, max_relative = 1e-12);
399
+ }
400
+
401
+ #[test]
402
+ fn new_angular_units() {
403
+ // Test the new angular units added via impl_unit_conversions! macro
404
+
405
+ // Arcminute conversions
406
+ let deg = Degrees::new(1.0);
407
+ let arcm: Arcminutes = deg.into();
408
+ assert_abs_diff_eq!(arcm.value(), 60.0, epsilon = 1e-12);
409
+
410
+ // Microarcsecond conversions
411
+ let arcs = Arcseconds::new(1.0);
412
+ let uas: MicroArcseconds = arcs.into();
413
+ assert_abs_diff_eq!(uas.value(), 1_000_000.0, epsilon = 1e-6);
414
+
415
+ // Gradian conversions (1 full turn = 400 gradians)
416
+ let turn = Turns::new(1.0);
417
+ let gon: Gradians = turn.into();
418
+ assert_abs_diff_eq!(gon.value(), 400.0, epsilon = 1e-12);
419
+
420
+ // Turn conversions
421
+ let deg = Degrees::new(180.0);
422
+ let turn: Turns = deg.into();
423
+ assert_abs_diff_eq!(turn.value(), 0.5, epsilon = 1e-12);
424
+
425
+ // Test trig functions work with new units
426
+ let right_angle = Gradians::new(100.0); // 90 degrees
427
+ assert_abs_diff_eq!(right_angle.sin(), 1.0, epsilon = 1e-12);
428
+ assert_abs_diff_eq!(right_angle.cos(), 0.0, epsilon = 1e-12);
429
+
430
+ // Test wrapping with new units
431
+ let turn = Turns::new(2.7);
432
+ let wrapped = turn.wrap_pos();
433
+ assert_abs_diff_eq!(wrapped.value(), 0.7, epsilon = 1e-12);
434
+ }
435
+
436
+ // ─────────────────────────────────────────────────────────────────────────────
437
+ // f32 scalar type tests
438
+ // ─────────────────────────────────────────────────────────────────────────────
439
+
440
+ #[test]
441
+ fn smoke_test_f32_angular() {
442
+ use qtty::f32::{Degrees, Radians};
443
+
444
+ let deg = Degrees::new(180.0_f32);
445
+ let rad: Radians = deg.to();
446
+ assert!((rad.value() - core::f32::consts::PI).abs() < 1e-5);
447
+ }
448
+
449
+ #[test]
450
+ fn smoke_test_f32_length() {
451
+ use qtty::f32::{Kilometers, Meters};
452
+
453
+ let km = Kilometers::new(1.0_f32);
454
+ let m: Meters = km.to();
455
+ assert!((m.value() - 1000.0).abs() < 1e-4);
456
+ }
457
+
458
+ #[test]
459
+ fn smoke_test_f32_time() {
460
+ use qtty::f32::{Days, Seconds};
461
+
462
+ let day = Days::new(1.0_f32);
463
+ let sec: Seconds = day.to();
464
+ assert!((sec.value() - 86400.0).abs() < 1.0);
465
+ }
466
+
467
+ #[test]
468
+ fn smoke_test_f32_arithmetic() {
469
+ use qtty::f32::Meters;
470
+
471
+ let a = Meters::new(10.0_f32);
472
+ let b = Meters::new(5.0_f32);
473
+ let sum = a + b;
474
+ let diff = a - b;
475
+
476
+ assert!((sum.value() - 15.0).abs() < 1e-6);
477
+ assert!((diff.value() - 5.0).abs() < 1e-6);
478
+ }
479
+
480
+ #[test]
481
+ fn smoke_test_f32_trig() {
482
+ use qtty::f32::Degrees;
483
+
484
+ let angle = Degrees::new(90.0_f32);
485
+ assert!((angle.sin() - 1.0).abs() < 1e-5);
486
+ assert!(angle.cos().abs() < 1e-5);
487
+ }
488
+
489
+ // ─────────────────────────────────────────────────────────────────────────────
490
+ // Integer scalar module tests
491
+ // ─────────────────────────────────────────────────────────────────────────────
492
+
493
+ #[test]
494
+ fn smoke_test_i8_module_arithmetic_and_lossy_conversion() {
495
+ use qtty::i8::{Meters, Minutes, Seconds};
496
+
497
+ let a = Meters::new(50);
498
+ let b = Meters::new(20);
499
+ assert_eq!((a + b).value(), 70);
500
+ assert_eq!((a - b).value(), 30);
501
+
502
+ let sec = Seconds::new(125);
503
+ let min: Minutes = sec.to_lossy();
504
+ assert_eq!(min.value(), 2);
505
+ }
506
+
507
+ #[test]
508
+ fn smoke_test_i16_module_arithmetic_and_lossy_conversion() {
509
+ use qtty::i16::{Kilometers, Meters};
510
+
511
+ let a = Meters::new(1_500);
512
+ let b = Meters::new(250);
513
+ assert_eq!((a + b).value(), 1_750);
514
+
515
+ let km: Kilometers = a.to_lossy();
516
+ assert_eq!(km.value(), 1);
517
+ }
518
+
519
+ #[test]
520
+ fn smoke_test_i128_module_arithmetic_and_lossy_conversion() {
521
+ use qtty::i128::{Days, Seconds};
522
+
523
+ let a = Seconds::new(172_800);
524
+ let b = Seconds::new(3_600);
525
+ assert_eq!((a + b).value(), 176_400);
526
+
527
+ let days: Days = a.to_lossy();
528
+ assert_eq!(days.value(), 2);
529
+ }
@@ -0,0 +1,58 @@
1
+ use std::path::{Path, PathBuf};
2
+ use std::process::{Command, Output};
3
+
4
+ fn fixture_manifest(name: &str) -> PathBuf {
5
+ Path::new(env!("CARGO_MANIFEST_DIR"))
6
+ .join("tests")
7
+ .join("fixtures")
8
+ .join(name)
9
+ .join("Cargo.toml")
10
+ }
11
+
12
+ fn cargo_check(manifest_path: &Path) -> Output {
13
+ let target_dir = Path::new(env!("CARGO_MANIFEST_DIR"))
14
+ .join("target")
15
+ .join("qtty-vec-feature-matrix");
16
+
17
+ Command::new(env!("CARGO"))
18
+ .arg("check")
19
+ .arg("--manifest-path")
20
+ .arg(manifest_path)
21
+ .current_dir(env!("CARGO_MANIFEST_DIR"))
22
+ .env("CARGO_TERM_COLOR", "never")
23
+ .env("CARGO_TARGET_DIR", target_dir)
24
+ .output()
25
+ .expect("failed to run cargo check")
26
+ }
27
+
28
+ #[test]
29
+ fn qtty_vec_feature_matrix() {
30
+ let std_manifest = fixture_manifest("qtty-vec-std");
31
+ let std_out = cargo_check(&std_manifest);
32
+ assert!(
33
+ std_out.status.success(),
34
+ "std mode should compile\nstderr:\n{}",
35
+ String::from_utf8_lossy(&std_out.stderr)
36
+ );
37
+
38
+ let no_std_alloc_manifest = fixture_manifest("qtty-vec-no-std-alloc");
39
+ let no_std_alloc_out = cargo_check(&no_std_alloc_manifest);
40
+ assert!(
41
+ no_std_alloc_out.status.success(),
42
+ "no_std + alloc mode should compile\nstderr:\n{}",
43
+ String::from_utf8_lossy(&no_std_alloc_out.stderr)
44
+ );
45
+
46
+ let no_std_manifest = fixture_manifest("qtty-vec-no-std");
47
+ let no_std_out = cargo_check(&no_std_manifest);
48
+ assert!(
49
+ !no_std_out.status.success(),
50
+ "pure no_std mode should fail for vec form"
51
+ );
52
+
53
+ let stderr = String::from_utf8_lossy(&no_std_out.stderr);
54
+ assert!(
55
+ stderr.contains("requires the `std` or `alloc` feature"),
56
+ "expected a clear feature requirement in compiler output\nstderr:\n{stderr}"
57
+ );
58
+ }