@jjlmoya/utils-forensic-science 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (316) hide show
  1. package/package.json +69 -0
  2. package/scripts/crystal-lattice-catalog-translations.mjs +459 -0
  3. package/scripts/postinstall.mjs +27 -0
  4. package/scripts/sync-crystal-lattice-i18n.mjs +50 -0
  5. package/src/category/i18n/de.ts +55 -0
  6. package/src/category/i18n/en.ts +55 -0
  7. package/src/category/i18n/es.ts +55 -0
  8. package/src/category/i18n/fr.ts +55 -0
  9. package/src/category/i18n/id.ts +55 -0
  10. package/src/category/i18n/it.ts +55 -0
  11. package/src/category/i18n/ja.ts +56 -0
  12. package/src/category/i18n/ko.ts +56 -0
  13. package/src/category/i18n/nl.ts +55 -0
  14. package/src/category/i18n/pl.ts +55 -0
  15. package/src/category/i18n/pt.ts +55 -0
  16. package/src/category/i18n/ru.ts +55 -0
  17. package/src/category/i18n/sv.ts +55 -0
  18. package/src/category/i18n/tr.ts +55 -0
  19. package/src/category/i18n/zh.ts +56 -0
  20. package/src/category/index.ts +48 -0
  21. package/src/category/seo.astro +15 -0
  22. package/src/components/PreviewNavSidebar.astro +116 -0
  23. package/src/components/PreviewToolbar.astro +143 -0
  24. package/src/data.ts +10 -0
  25. package/src/entries.ts +48 -0
  26. package/src/env.d.ts +5 -0
  27. package/src/index.ts +29 -0
  28. package/src/layouts/PreviewLayout.astro +117 -0
  29. package/src/pages/[locale]/[slug].astro +162 -0
  30. package/src/pages/[locale].astro +261 -0
  31. package/src/pages/index.astro +3 -0
  32. package/src/tests/diacritics_density.test.ts +140 -0
  33. package/src/tests/faq_count.test.ts +19 -0
  34. package/src/tests/i18n_coverage.test.ts +36 -0
  35. package/src/tests/inverted_punctuation.test.ts +84 -0
  36. package/src/tests/locale_completeness.test.ts +24 -0
  37. package/src/tests/mocks/astro_mock.js +2 -0
  38. package/src/tests/no_en_dash.test.ts +70 -0
  39. package/src/tests/no_h1_in_components.test.ts +48 -0
  40. package/src/tests/schemas_fulfillment.test.ts +23 -0
  41. package/src/tests/script_density.test.ts +94 -0
  42. package/src/tests/seo_length.test.ts +46 -0
  43. package/src/tests/shared-test-helpers.ts +56 -0
  44. package/src/tests/slug_language_code_format.test.ts +23 -0
  45. package/src/tests/slug_uniqueness.test.ts +81 -0
  46. package/src/tests/title_quality.test.ts +55 -0
  47. package/src/tests/tool_exports.test.ts +34 -0
  48. package/src/tests/tool_validation.test.ts +16 -0
  49. package/src/tests/widmark.test.ts +28 -0
  50. package/src/tool/forensic-age-estimator/bibliography.astro +14 -0
  51. package/src/tool/forensic-age-estimator/bibliography.ts +16 -0
  52. package/src/tool/forensic-age-estimator/component.astro +321 -0
  53. package/src/tool/forensic-age-estimator/dental-skeletal-third-molar-age-estimator.css +634 -0
  54. package/src/tool/forensic-age-estimator/entry.ts +32 -0
  55. package/src/tool/forensic-age-estimator/i18n/de.ts +245 -0
  56. package/src/tool/forensic-age-estimator/i18n/en.ts +245 -0
  57. package/src/tool/forensic-age-estimator/i18n/es.ts +245 -0
  58. package/src/tool/forensic-age-estimator/i18n/fr.ts +245 -0
  59. package/src/tool/forensic-age-estimator/i18n/id.ts +245 -0
  60. package/src/tool/forensic-age-estimator/i18n/it.ts +245 -0
  61. package/src/tool/forensic-age-estimator/i18n/ja.ts +245 -0
  62. package/src/tool/forensic-age-estimator/i18n/ko.ts +245 -0
  63. package/src/tool/forensic-age-estimator/i18n/nl.ts +245 -0
  64. package/src/tool/forensic-age-estimator/i18n/pl.ts +245 -0
  65. package/src/tool/forensic-age-estimator/i18n/pt.ts +245 -0
  66. package/src/tool/forensic-age-estimator/i18n/ru.ts +245 -0
  67. package/src/tool/forensic-age-estimator/i18n/sv.ts +245 -0
  68. package/src/tool/forensic-age-estimator/i18n/tr.ts +245 -0
  69. package/src/tool/forensic-age-estimator/i18n/zh.ts +246 -0
  70. package/src/tool/forensic-age-estimator/index.ts +11 -0
  71. package/src/tool/forensic-age-estimator/logic.ts +81 -0
  72. package/src/tool/forensic-age-estimator/seo.astro +15 -0
  73. package/src/tool/forensic-blood-test-simulator/bibliography.astro +6 -0
  74. package/src/tool/forensic-blood-test-simulator/bibliography.ts +12 -0
  75. package/src/tool/forensic-blood-test-simulator/component.astro +168 -0
  76. package/src/tool/forensic-blood-test-simulator/dom-utils.ts +40 -0
  77. package/src/tool/forensic-blood-test-simulator/entry.ts +32 -0
  78. package/src/tool/forensic-blood-test-simulator/forensic-presumptive-blood-testing-luminol-kastle-meyer-simulator.css +532 -0
  79. package/src/tool/forensic-blood-test-simulator/helpers.ts +16 -0
  80. package/src/tool/forensic-blood-test-simulator/i18n/de.ts +185 -0
  81. package/src/tool/forensic-blood-test-simulator/i18n/en.ts +185 -0
  82. package/src/tool/forensic-blood-test-simulator/i18n/es.ts +185 -0
  83. package/src/tool/forensic-blood-test-simulator/i18n/fr.ts +220 -0
  84. package/src/tool/forensic-blood-test-simulator/i18n/id.ts +220 -0
  85. package/src/tool/forensic-blood-test-simulator/i18n/it.ts +220 -0
  86. package/src/tool/forensic-blood-test-simulator/i18n/ja.ts +220 -0
  87. package/src/tool/forensic-blood-test-simulator/i18n/ko.ts +220 -0
  88. package/src/tool/forensic-blood-test-simulator/i18n/nl.ts +220 -0
  89. package/src/tool/forensic-blood-test-simulator/i18n/pl.ts +220 -0
  90. package/src/tool/forensic-blood-test-simulator/i18n/pt.ts +220 -0
  91. package/src/tool/forensic-blood-test-simulator/i18n/ru.ts +220 -0
  92. package/src/tool/forensic-blood-test-simulator/i18n/sv.ts +220 -0
  93. package/src/tool/forensic-blood-test-simulator/i18n/tr.ts +220 -0
  94. package/src/tool/forensic-blood-test-simulator/i18n/zh.ts +220 -0
  95. package/src/tool/forensic-blood-test-simulator/index.ts +11 -0
  96. package/src/tool/forensic-blood-test-simulator/logic.ts +174 -0
  97. package/src/tool/forensic-blood-test-simulator/script.ts +192 -0
  98. package/src/tool/forensic-blood-test-simulator/seo.astro +15 -0
  99. package/src/tool/forensic-fiber-comparison-microscope/bibliography.astro +6 -0
  100. package/src/tool/forensic-fiber-comparison-microscope/bibliography.ts +16 -0
  101. package/src/tool/forensic-fiber-comparison-microscope/component.astro +146 -0
  102. package/src/tool/forensic-fiber-comparison-microscope/entry.ts +32 -0
  103. package/src/tool/forensic-fiber-comparison-microscope/forensic-fiber-comparison-microscope.css +629 -0
  104. package/src/tool/forensic-fiber-comparison-microscope/i18n/de.ts +250 -0
  105. package/src/tool/forensic-fiber-comparison-microscope/i18n/en.ts +246 -0
  106. package/src/tool/forensic-fiber-comparison-microscope/i18n/es.ts +246 -0
  107. package/src/tool/forensic-fiber-comparison-microscope/i18n/fr.ts +246 -0
  108. package/src/tool/forensic-fiber-comparison-microscope/i18n/id.ts +250 -0
  109. package/src/tool/forensic-fiber-comparison-microscope/i18n/it.ts +246 -0
  110. package/src/tool/forensic-fiber-comparison-microscope/i18n/ja.ts +250 -0
  111. package/src/tool/forensic-fiber-comparison-microscope/i18n/ko.ts +246 -0
  112. package/src/tool/forensic-fiber-comparison-microscope/i18n/nl.ts +246 -0
  113. package/src/tool/forensic-fiber-comparison-microscope/i18n/pl.ts +250 -0
  114. package/src/tool/forensic-fiber-comparison-microscope/i18n/pt.ts +250 -0
  115. package/src/tool/forensic-fiber-comparison-microscope/i18n/ru.ts +250 -0
  116. package/src/tool/forensic-fiber-comparison-microscope/i18n/sv.ts +250 -0
  117. package/src/tool/forensic-fiber-comparison-microscope/i18n/tr.ts +246 -0
  118. package/src/tool/forensic-fiber-comparison-microscope/i18n/zh.ts +250 -0
  119. package/src/tool/forensic-fiber-comparison-microscope/index.ts +11 -0
  120. package/src/tool/forensic-fiber-comparison-microscope/logic.ts +244 -0
  121. package/src/tool/forensic-fiber-comparison-microscope/render.ts +265 -0
  122. package/src/tool/forensic-fiber-comparison-microscope/seo.astro +15 -0
  123. package/src/tool/forensic-fiber-comparison-microscope/view.ts +267 -0
  124. package/src/tool/forensic-glass-becke-line-simulator/bibliography.astro +6 -0
  125. package/src/tool/forensic-glass-becke-line-simulator/bibliography.ts +16 -0
  126. package/src/tool/forensic-glass-becke-line-simulator/component.astro +81 -0
  127. package/src/tool/forensic-glass-becke-line-simulator/entry.ts +32 -0
  128. package/src/tool/forensic-glass-becke-line-simulator/forensic-glass-becke-line-simulator.css +392 -0
  129. package/src/tool/forensic-glass-becke-line-simulator/i18n/de.ts +231 -0
  130. package/src/tool/forensic-glass-becke-line-simulator/i18n/en.ts +231 -0
  131. package/src/tool/forensic-glass-becke-line-simulator/i18n/es.ts +231 -0
  132. package/src/tool/forensic-glass-becke-line-simulator/i18n/fr.ts +231 -0
  133. package/src/tool/forensic-glass-becke-line-simulator/i18n/id.ts +231 -0
  134. package/src/tool/forensic-glass-becke-line-simulator/i18n/it.ts +231 -0
  135. package/src/tool/forensic-glass-becke-line-simulator/i18n/ja.ts +231 -0
  136. package/src/tool/forensic-glass-becke-line-simulator/i18n/ko.ts +231 -0
  137. package/src/tool/forensic-glass-becke-line-simulator/i18n/nl.ts +231 -0
  138. package/src/tool/forensic-glass-becke-line-simulator/i18n/pl.ts +231 -0
  139. package/src/tool/forensic-glass-becke-line-simulator/i18n/pt.ts +231 -0
  140. package/src/tool/forensic-glass-becke-line-simulator/i18n/ru.ts +231 -0
  141. package/src/tool/forensic-glass-becke-line-simulator/i18n/sv.ts +231 -0
  142. package/src/tool/forensic-glass-becke-line-simulator/i18n/tr.ts +231 -0
  143. package/src/tool/forensic-glass-becke-line-simulator/i18n/zh.ts +231 -0
  144. package/src/tool/forensic-glass-becke-line-simulator/index.ts +11 -0
  145. package/src/tool/forensic-glass-becke-line-simulator/logic.ts +100 -0
  146. package/src/tool/forensic-glass-becke-line-simulator/seo.astro +15 -0
  147. package/src/tool/forensic-glass-becke-line-simulator/view.ts +281 -0
  148. package/src/tool/forensic-image-authenticity-analyzer/bibliography.astro +9 -0
  149. package/src/tool/forensic-image-authenticity-analyzer/bibliography.ts +7 -0
  150. package/src/tool/forensic-image-authenticity-analyzer/component.astro +250 -0
  151. package/src/tool/forensic-image-authenticity-analyzer/entry.ts +29 -0
  152. package/src/tool/forensic-image-authenticity-analyzer/forensic-image-metadata-authenticity-analyzer.css +679 -0
  153. package/src/tool/forensic-image-authenticity-analyzer/i18n/de.ts +105 -0
  154. package/src/tool/forensic-image-authenticity-analyzer/i18n/en.ts +105 -0
  155. package/src/tool/forensic-image-authenticity-analyzer/i18n/es.ts +105 -0
  156. package/src/tool/forensic-image-authenticity-analyzer/i18n/fr.ts +105 -0
  157. package/src/tool/forensic-image-authenticity-analyzer/i18n/id.ts +76 -0
  158. package/src/tool/forensic-image-authenticity-analyzer/i18n/it.ts +105 -0
  159. package/src/tool/forensic-image-authenticity-analyzer/i18n/ja.ts +72 -0
  160. package/src/tool/forensic-image-authenticity-analyzer/i18n/ko.ts +72 -0
  161. package/src/tool/forensic-image-authenticity-analyzer/i18n/nl.ts +75 -0
  162. package/src/tool/forensic-image-authenticity-analyzer/i18n/pl.ts +75 -0
  163. package/src/tool/forensic-image-authenticity-analyzer/i18n/pt.ts +105 -0
  164. package/src/tool/forensic-image-authenticity-analyzer/i18n/ru.ts +75 -0
  165. package/src/tool/forensic-image-authenticity-analyzer/i18n/sv.ts +76 -0
  166. package/src/tool/forensic-image-authenticity-analyzer/i18n/tr.ts +76 -0
  167. package/src/tool/forensic-image-authenticity-analyzer/i18n/zh.ts +71 -0
  168. package/src/tool/forensic-image-authenticity-analyzer/index.ts +11 -0
  169. package/src/tool/forensic-image-authenticity-analyzer/logic.ts +283 -0
  170. package/src/tool/forensic-image-authenticity-analyzer/seo.astro +10 -0
  171. package/src/tool/forensic-microcrystal-drug-simulator/bibliography.astro +6 -0
  172. package/src/tool/forensic-microcrystal-drug-simulator/bibliography.ts +12 -0
  173. package/src/tool/forensic-microcrystal-drug-simulator/component.astro +240 -0
  174. package/src/tool/forensic-microcrystal-drug-simulator/entry.ts +32 -0
  175. package/src/tool/forensic-microcrystal-drug-simulator/forensic-microcrystal-drug-simulator.css +430 -0
  176. package/src/tool/forensic-microcrystal-drug-simulator/i18n/de.ts +244 -0
  177. package/src/tool/forensic-microcrystal-drug-simulator/i18n/en.ts +244 -0
  178. package/src/tool/forensic-microcrystal-drug-simulator/i18n/es.ts +244 -0
  179. package/src/tool/forensic-microcrystal-drug-simulator/i18n/fr.ts +244 -0
  180. package/src/tool/forensic-microcrystal-drug-simulator/i18n/id.ts +244 -0
  181. package/src/tool/forensic-microcrystal-drug-simulator/i18n/it.ts +244 -0
  182. package/src/tool/forensic-microcrystal-drug-simulator/i18n/ja.ts +244 -0
  183. package/src/tool/forensic-microcrystal-drug-simulator/i18n/ko.ts +244 -0
  184. package/src/tool/forensic-microcrystal-drug-simulator/i18n/nl.ts +244 -0
  185. package/src/tool/forensic-microcrystal-drug-simulator/i18n/pl.ts +244 -0
  186. package/src/tool/forensic-microcrystal-drug-simulator/i18n/pt.ts +244 -0
  187. package/src/tool/forensic-microcrystal-drug-simulator/i18n/ru.ts +244 -0
  188. package/src/tool/forensic-microcrystal-drug-simulator/i18n/sv.ts +244 -0
  189. package/src/tool/forensic-microcrystal-drug-simulator/i18n/tr.ts +244 -0
  190. package/src/tool/forensic-microcrystal-drug-simulator/i18n/zh.ts +244 -0
  191. package/src/tool/forensic-microcrystal-drug-simulator/index.ts +11 -0
  192. package/src/tool/forensic-microcrystal-drug-simulator/logic.ts +189 -0
  193. package/src/tool/forensic-microcrystal-drug-simulator/seo.astro +15 -0
  194. package/src/tool/forensic-sex-determinator/bibliography.astro +14 -0
  195. package/src/tool/forensic-sex-determinator/bibliography.ts +12 -0
  196. package/src/tool/forensic-sex-determinator/component.astro +463 -0
  197. package/src/tool/forensic-sex-determinator/entry.ts +32 -0
  198. package/src/tool/forensic-sex-determinator/forensic-sex-determinator.css +413 -0
  199. package/src/tool/forensic-sex-determinator/i18n/de.ts +211 -0
  200. package/src/tool/forensic-sex-determinator/i18n/en.ts +211 -0
  201. package/src/tool/forensic-sex-determinator/i18n/es.ts +211 -0
  202. package/src/tool/forensic-sex-determinator/i18n/fr.ts +211 -0
  203. package/src/tool/forensic-sex-determinator/i18n/id.ts +211 -0
  204. package/src/tool/forensic-sex-determinator/i18n/it.ts +211 -0
  205. package/src/tool/forensic-sex-determinator/i18n/ja.ts +211 -0
  206. package/src/tool/forensic-sex-determinator/i18n/ko.ts +211 -0
  207. package/src/tool/forensic-sex-determinator/i18n/nl.ts +211 -0
  208. package/src/tool/forensic-sex-determinator/i18n/pl.ts +211 -0
  209. package/src/tool/forensic-sex-determinator/i18n/pt.ts +211 -0
  210. package/src/tool/forensic-sex-determinator/i18n/ru.ts +211 -0
  211. package/src/tool/forensic-sex-determinator/i18n/sv.ts +211 -0
  212. package/src/tool/forensic-sex-determinator/i18n/tr.ts +211 -0
  213. package/src/tool/forensic-sex-determinator/i18n/zh.ts +211 -0
  214. package/src/tool/forensic-sex-determinator/index.ts +11 -0
  215. package/src/tool/forensic-sex-determinator/logic.ts +89 -0
  216. package/src/tool/forensic-sex-determinator/seo.astro +15 -0
  217. package/src/tool/forensic-stature-estimator/bibliography.astro +14 -0
  218. package/src/tool/forensic-stature-estimator/bibliography.ts +12 -0
  219. package/src/tool/forensic-stature-estimator/component.astro +49 -0
  220. package/src/tool/forensic-stature-estimator/components/EstimationPanel.astro +65 -0
  221. package/src/tool/forensic-stature-estimator/components/OsteometricBoard.astro +39 -0
  222. package/src/tool/forensic-stature-estimator/components/OsteometricSelector.astro +109 -0
  223. package/src/tool/forensic-stature-estimator/dom-utils.ts +71 -0
  224. package/src/tool/forensic-stature-estimator/entry.ts +32 -0
  225. package/src/tool/forensic-stature-estimator/forensic-stature-estimator.css +689 -0
  226. package/src/tool/forensic-stature-estimator/helpers.ts +51 -0
  227. package/src/tool/forensic-stature-estimator/i18n/de.ts +196 -0
  228. package/src/tool/forensic-stature-estimator/i18n/en.ts +196 -0
  229. package/src/tool/forensic-stature-estimator/i18n/es.ts +196 -0
  230. package/src/tool/forensic-stature-estimator/i18n/fr.ts +196 -0
  231. package/src/tool/forensic-stature-estimator/i18n/id.ts +196 -0
  232. package/src/tool/forensic-stature-estimator/i18n/it.ts +196 -0
  233. package/src/tool/forensic-stature-estimator/i18n/ja.ts +196 -0
  234. package/src/tool/forensic-stature-estimator/i18n/ko.ts +196 -0
  235. package/src/tool/forensic-stature-estimator/i18n/nl.ts +196 -0
  236. package/src/tool/forensic-stature-estimator/i18n/pl.ts +196 -0
  237. package/src/tool/forensic-stature-estimator/i18n/pt.ts +196 -0
  238. package/src/tool/forensic-stature-estimator/i18n/ru.ts +196 -0
  239. package/src/tool/forensic-stature-estimator/i18n/sv.ts +196 -0
  240. package/src/tool/forensic-stature-estimator/i18n/tr.ts +196 -0
  241. package/src/tool/forensic-stature-estimator/i18n/zh.ts +196 -0
  242. package/src/tool/forensic-stature-estimator/index.ts +11 -0
  243. package/src/tool/forensic-stature-estimator/logic.ts +119 -0
  244. package/src/tool/forensic-stature-estimator/script.ts +288 -0
  245. package/src/tool/forensic-stature-estimator/seo.astro +15 -0
  246. package/src/tool/forensic-tlc-ink-simulator/bibliography.astro +6 -0
  247. package/src/tool/forensic-tlc-ink-simulator/bibliography.ts +16 -0
  248. package/src/tool/forensic-tlc-ink-simulator/component.astro +245 -0
  249. package/src/tool/forensic-tlc-ink-simulator/entry.ts +32 -0
  250. package/src/tool/forensic-tlc-ink-simulator/forensic-tlc-ink-simulator.css +462 -0
  251. package/src/tool/forensic-tlc-ink-simulator/i18n/de.ts +243 -0
  252. package/src/tool/forensic-tlc-ink-simulator/i18n/en.ts +243 -0
  253. package/src/tool/forensic-tlc-ink-simulator/i18n/es.ts +243 -0
  254. package/src/tool/forensic-tlc-ink-simulator/i18n/fr.ts +243 -0
  255. package/src/tool/forensic-tlc-ink-simulator/i18n/id.ts +243 -0
  256. package/src/tool/forensic-tlc-ink-simulator/i18n/it.ts +243 -0
  257. package/src/tool/forensic-tlc-ink-simulator/i18n/ja.ts +235 -0
  258. package/src/tool/forensic-tlc-ink-simulator/i18n/ko.ts +235 -0
  259. package/src/tool/forensic-tlc-ink-simulator/i18n/nl.ts +243 -0
  260. package/src/tool/forensic-tlc-ink-simulator/i18n/pl.ts +243 -0
  261. package/src/tool/forensic-tlc-ink-simulator/i18n/pt.ts +243 -0
  262. package/src/tool/forensic-tlc-ink-simulator/i18n/ru.ts +243 -0
  263. package/src/tool/forensic-tlc-ink-simulator/i18n/sv.ts +243 -0
  264. package/src/tool/forensic-tlc-ink-simulator/i18n/tr.ts +243 -0
  265. package/src/tool/forensic-tlc-ink-simulator/i18n/zh.ts +235 -0
  266. package/src/tool/forensic-tlc-ink-simulator/index.ts +11 -0
  267. package/src/tool/forensic-tlc-ink-simulator/logic.ts +152 -0
  268. package/src/tool/forensic-tlc-ink-simulator/seo.astro +15 -0
  269. package/src/tool/gsr-dispersion-calculator/bibliography.astro +6 -0
  270. package/src/tool/gsr-dispersion-calculator/bibliography.ts +16 -0
  271. package/src/tool/gsr-dispersion-calculator/component.astro +294 -0
  272. package/src/tool/gsr-dispersion-calculator/entry.ts +32 -0
  273. package/src/tool/gsr-dispersion-calculator/gsr-dispersion-calculator.css +305 -0
  274. package/src/tool/gsr-dispersion-calculator/i18n/de.ts +272 -0
  275. package/src/tool/gsr-dispersion-calculator/i18n/en.ts +272 -0
  276. package/src/tool/gsr-dispersion-calculator/i18n/es.ts +272 -0
  277. package/src/tool/gsr-dispersion-calculator/i18n/fr.ts +272 -0
  278. package/src/tool/gsr-dispersion-calculator/i18n/id.ts +272 -0
  279. package/src/tool/gsr-dispersion-calculator/i18n/it.ts +272 -0
  280. package/src/tool/gsr-dispersion-calculator/i18n/ja.ts +272 -0
  281. package/src/tool/gsr-dispersion-calculator/i18n/ko.ts +272 -0
  282. package/src/tool/gsr-dispersion-calculator/i18n/nl.ts +272 -0
  283. package/src/tool/gsr-dispersion-calculator/i18n/pl.ts +272 -0
  284. package/src/tool/gsr-dispersion-calculator/i18n/pt.ts +272 -0
  285. package/src/tool/gsr-dispersion-calculator/i18n/ru.ts +272 -0
  286. package/src/tool/gsr-dispersion-calculator/i18n/sv.ts +272 -0
  287. package/src/tool/gsr-dispersion-calculator/i18n/tr.ts +272 -0
  288. package/src/tool/gsr-dispersion-calculator/i18n/zh.ts +272 -0
  289. package/src/tool/gsr-dispersion-calculator/index.ts +11 -0
  290. package/src/tool/gsr-dispersion-calculator/logic.ts +148 -0
  291. package/src/tool/gsr-dispersion-calculator/seo.astro +15 -0
  292. package/src/tool/widmark-alcohol-simulator/bibliography.astro +14 -0
  293. package/src/tool/widmark-alcohol-simulator/bibliography.ts +12 -0
  294. package/src/tool/widmark-alcohol-simulator/component.astro +453 -0
  295. package/src/tool/widmark-alcohol-simulator/entry.ts +32 -0
  296. package/src/tool/widmark-alcohol-simulator/i18n/de.ts +193 -0
  297. package/src/tool/widmark-alcohol-simulator/i18n/en.ts +206 -0
  298. package/src/tool/widmark-alcohol-simulator/i18n/es.ts +193 -0
  299. package/src/tool/widmark-alcohol-simulator/i18n/fr.ts +193 -0
  300. package/src/tool/widmark-alcohol-simulator/i18n/id.ts +193 -0
  301. package/src/tool/widmark-alcohol-simulator/i18n/it.ts +193 -0
  302. package/src/tool/widmark-alcohol-simulator/i18n/ja.ts +193 -0
  303. package/src/tool/widmark-alcohol-simulator/i18n/ko.ts +193 -0
  304. package/src/tool/widmark-alcohol-simulator/i18n/nl.ts +193 -0
  305. package/src/tool/widmark-alcohol-simulator/i18n/pl.ts +193 -0
  306. package/src/tool/widmark-alcohol-simulator/i18n/pt.ts +193 -0
  307. package/src/tool/widmark-alcohol-simulator/i18n/ru.ts +193 -0
  308. package/src/tool/widmark-alcohol-simulator/i18n/sv.ts +193 -0
  309. package/src/tool/widmark-alcohol-simulator/i18n/tr.ts +193 -0
  310. package/src/tool/widmark-alcohol-simulator/i18n/zh.ts +193 -0
  311. package/src/tool/widmark-alcohol-simulator/index.ts +11 -0
  312. package/src/tool/widmark-alcohol-simulator/logic.ts +97 -0
  313. package/src/tool/widmark-alcohol-simulator/seo.astro +15 -0
  314. package/src/tool/widmark-alcohol-simulator/widmark-alcohol-simulator.css +386 -0
  315. package/src/tools.ts +27 -0
  316. package/src/types.ts +70 -0
@@ -0,0 +1,532 @@
1
+ .forensic-chemical-card {
2
+ --fbt-bg: #fff;
3
+ --fbt-border: #e2e8f0;
4
+ --fbt-muted: #64748b;
5
+ --fbt-text: #0f172a;
6
+ --fbt-panel-bg: #f8fafc;
7
+ --fbt-panel-border: #e2e8f0;
8
+ --fbt-badge-bg: #f1f5f9;
9
+ --fbt-badge-text: #475569;
10
+ --fbt-primary: #0284c7;
11
+ --fbt-primary-hover: #0369a1;
12
+ --fbt-active: #38bdf8;
13
+ --fbt-viewport-bg: #f1f5f9;
14
+ --fbt-viewport-border: #cbd5e1;
15
+ --fbt-glass-tube: rgba(15, 23, 42, 0.05);
16
+ --fbt-glass-tube-border: rgba(15, 23, 42, 0.2);
17
+ --fbt-bottle-bg: #cbd5e1;
18
+ --fbt-bottle-cap: #475569;
19
+
20
+ background: var(--fbt-bg);
21
+ border: 1px solid var(--fbt-border);
22
+ border-radius: 20px;
23
+ padding: 2rem;
24
+ max-width: 1200px;
25
+ margin: 0 auto;
26
+ color: var(--fbt-text);
27
+ box-shadow: 0 4px 20px rgba(0, 0, 0, 0.02);
28
+ }
29
+
30
+ .theme-dark .forensic-chemical-card {
31
+ --fbt-bg: #0f172a;
32
+ --fbt-border: rgba(255, 255, 255, 0.08);
33
+ --fbt-muted: #94a3b8;
34
+ --fbt-text: #f8fafc;
35
+ --fbt-panel-bg: rgba(30, 41, 59, 0.4);
36
+ --fbt-panel-border: rgba(255, 255, 255, 0.05);
37
+ --fbt-badge-bg: rgba(255, 255, 255, 0.05);
38
+ --fbt-badge-text: #cbd5e1;
39
+ --fbt-primary: #06b6d4;
40
+ --fbt-primary-hover: #0891b2;
41
+ --fbt-active: #67e8f9;
42
+ --fbt-viewport-bg: #020617;
43
+ --fbt-viewport-border: rgba(255, 255, 255, 0.05);
44
+ --fbt-glass-tube: rgba(255, 255, 255, 0.05);
45
+ --fbt-glass-tube-border: rgba(255, 255, 255, 0.2);
46
+ --fbt-bottle-bg: #334155;
47
+ --fbt-bottle-cap: #1e293b;
48
+
49
+ box-shadow: 0 10px 30px rgba(0, 0, 0, 0.3);
50
+ }
51
+
52
+ .forensic-chemical-toolbar {
53
+ display: flex;
54
+ justify-content: flex-end;
55
+ margin-bottom: 2.5rem;
56
+ }
57
+
58
+
59
+ .btn-toggle-lights {
60
+ position: absolute;
61
+ top: 1rem;
62
+ right: 1rem;
63
+ width: 38px;
64
+ height: 38px;
65
+ background: var(--fbt-bg);
66
+ border: 1px solid var(--fbt-border);
67
+ border-radius: 50%;
68
+ cursor: pointer;
69
+ display: flex;
70
+ align-items: center;
71
+ justify-content: center;
72
+ z-index: 10;
73
+ transition: all 0.2s ease;
74
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
75
+ }
76
+
77
+ .btn-toggle-lights:hover {
78
+ transform: scale(1.05);
79
+ border-color: var(--fbt-primary);
80
+ }
81
+
82
+ .light-switch-icon {
83
+ width: 16px;
84
+ height: 16px;
85
+ border-radius: 50%;
86
+ background: #f59e0b;
87
+ position: relative;
88
+ transition: all 0.2s ease;
89
+ box-shadow: 0 0 8px #f59e0b;
90
+ }
91
+
92
+ .btn-toggle-lights.lights-off {
93
+ background: #1e293b;
94
+ border-color: #334155;
95
+ }
96
+
97
+ .btn-toggle-lights.lights-off .light-switch-icon {
98
+ background: #94a3b8;
99
+ box-shadow: none;
100
+ }
101
+
102
+ .chemical-workbench {
103
+ display: grid;
104
+ grid-template-columns: 1fr;
105
+ gap: 2rem;
106
+ }
107
+
108
+ @media (min-width: 1024px) {
109
+ .chemical-workbench {
110
+ grid-template-columns: 1.1fr 0.9fr;
111
+ }
112
+ }
113
+
114
+ .workbench-left {
115
+ display: flex;
116
+ flex-direction: column;
117
+ gap: 2rem;
118
+ }
119
+
120
+ .section-title {
121
+ font-size: 0.8rem;
122
+ font-weight: 800;
123
+ letter-spacing: 0.05em;
124
+ text-transform: uppercase;
125
+ color: var(--fbt-muted);
126
+ margin: 0 0 1rem;
127
+ }
128
+
129
+ .specimen-rack-container {
130
+ background: var(--fbt-panel-bg);
131
+ border: 1px solid var(--fbt-panel-border);
132
+ padding: 1.5rem;
133
+ border-radius: 16px;
134
+ }
135
+
136
+ .specimen-rack {
137
+ display: grid;
138
+ grid-template-columns: repeat(5, 1fr);
139
+ gap: 0.75rem;
140
+ }
141
+
142
+ .specimen-tube {
143
+ background: transparent;
144
+ border: 1px solid transparent;
145
+ display: flex;
146
+ flex-direction: column;
147
+ align-items: center;
148
+ gap: 0.75rem;
149
+ cursor: pointer;
150
+ padding: 1rem 0.5rem;
151
+ border-radius: 12px;
152
+ transition: background 0.2s ease, border-color 0.2s ease;
153
+ width: 100%;
154
+ }
155
+
156
+ .specimen-tube:hover {
157
+ background: var(--fbt-bg);
158
+ border-color: var(--fbt-border);
159
+ }
160
+
161
+ .tube-glass {
162
+ width: 20px;
163
+ height: 60px;
164
+ border: 2px solid var(--fbt-glass-tube-border);
165
+ border-top: none;
166
+ border-radius: 0 0 10px 10px;
167
+ position: relative;
168
+ background: var(--fbt-glass-tube);
169
+ display: block;
170
+ }
171
+
172
+ .tube-liquid {
173
+ position: absolute;
174
+ bottom: 0;
175
+ left: 0;
176
+ right: 0;
177
+ height: 35px;
178
+ border-radius: 0 0 8px 8px;
179
+ display: block;
180
+ }
181
+
182
+ .tube-liquid-blood { background: #dc2626; }
183
+ .tube-liquid-rust { background: #b45309; }
184
+ .tube-liquid-bleach {
185
+ background: rgba(255, 255, 255, 0.4);
186
+ border-top: 1px solid rgba(255, 255, 255, 0.8);
187
+ }
188
+ .tube-liquid-potato {
189
+ background: #ca8a04;
190
+ opacity: 0.6;
191
+ }
192
+ .tube-liquid-saliva { background: rgba(255, 255, 255, 0.15); }
193
+
194
+ .tube-label {
195
+ font-size: 0.75rem;
196
+ font-weight: 600;
197
+ color: var(--fbt-muted);
198
+ text-align: center;
199
+ overflow-wrap: break-word;
200
+ }
201
+
202
+ .specimen-tube.selected {
203
+ background: var(--fbt-bg);
204
+ border-color: var(--fbt-primary);
205
+ }
206
+
207
+ .specimen-tube.selected .tube-label {
208
+ color: var(--fbt-primary);
209
+ }
210
+
211
+ .reagents-shelf-container {
212
+ background: var(--fbt-panel-bg);
213
+ border: 1px solid var(--fbt-panel-border);
214
+ padding: 1.5rem;
215
+ border-radius: 16px;
216
+ }
217
+
218
+ .reagents-shelf {
219
+ display: flex;
220
+ flex-direction: column;
221
+ gap: 1.25rem;
222
+ }
223
+
224
+ .reagent-bottle {
225
+ display: flex;
226
+ align-items: center;
227
+ gap: 1.25rem;
228
+ background: var(--fbt-bg);
229
+ border: 1px solid var(--fbt-border);
230
+ border-radius: 12px;
231
+ padding: 1rem;
232
+ }
233
+
234
+ .bottle-visual {
235
+ width: 44px;
236
+ height: 76px;
237
+ display: flex;
238
+ flex-direction: column;
239
+ align-items: center;
240
+ position: relative;
241
+ flex-shrink: 0;
242
+ }
243
+
244
+ .bottle-neck {
245
+ width: 14px;
246
+ height: 14px;
247
+ background: var(--fbt-bottle-cap);
248
+ border-radius: 2px 2px 0 0;
249
+ }
250
+
251
+ .bottle-body {
252
+ width: 40px;
253
+ height: 62px;
254
+ background: var(--fbt-bottle-bg);
255
+ border: 2px solid var(--fbt-glass-tube-border);
256
+ border-radius: 6px;
257
+ position: relative;
258
+ display: flex;
259
+ align-items: center;
260
+ justify-content: center;
261
+ }
262
+
263
+ .bottle-liquid {
264
+ position: absolute;
265
+ bottom: 0;
266
+ left: 0;
267
+ right: 0;
268
+ height: 30px;
269
+ background: rgba(255, 255, 255, 0.2);
270
+ border-radius: 0 0 4px 4px;
271
+ }
272
+
273
+ .bottle-km .bottle-liquid { background: rgba(236, 72, 153, 0.15); }
274
+ .bottle-h2o2 .bottle-liquid { background: rgba(14, 165, 233, 0.15); }
275
+ .bottle-luminol .bottle-liquid { background: rgba(56, 189, 248, 0.1); }
276
+
277
+ .bottle-label-sticker {
278
+ background: #fff;
279
+ color: #0f172a;
280
+ border: 1px solid #94a3b8;
281
+ font-size: 0.6rem;
282
+ font-weight: 800;
283
+ padding: 2px 4px;
284
+ border-radius: 2px;
285
+ z-index: 2;
286
+ }
287
+
288
+ .reagent-details {
289
+ flex-grow: 1;
290
+ display: flex;
291
+ flex-direction: column;
292
+ gap: 0.25rem;
293
+ }
294
+
295
+ .reagent-name {
296
+ font-size: 0.9rem;
297
+ font-weight: 700;
298
+ }
299
+
300
+ .reagent-desc {
301
+ font-size: 0.75rem;
302
+ color: var(--fbt-muted);
303
+ }
304
+
305
+ .btn-dispense-fluid {
306
+ background: var(--fbt-panel-bg);
307
+ border: 1px solid var(--fbt-border);
308
+ color: var(--fbt-text);
309
+ font-size: 0.75rem;
310
+ font-weight: 700;
311
+ padding: 0.5rem 0.85rem;
312
+ border-radius: 8px;
313
+ cursor: pointer;
314
+ transition: all 0.15s ease;
315
+ }
316
+
317
+ .btn-dispense-fluid:hover {
318
+ background: var(--fbt-primary);
319
+ color: #fff;
320
+ border-color: var(--fbt-primary);
321
+ }
322
+
323
+ .workbench-right {
324
+ display: flex;
325
+ flex-direction: column;
326
+ gap: 2rem;
327
+ }
328
+
329
+ .workbench-viewport {
330
+ background: var(--fbt-viewport-bg);
331
+ border: 1px solid var(--fbt-viewport-border);
332
+ border-radius: 16px;
333
+ height: 280px;
334
+ display: flex;
335
+ align-items: center;
336
+ justify-content: center;
337
+ position: relative;
338
+ overflow: hidden;
339
+ transition: background-color 0.3s ease, border-color 0.3s ease;
340
+ }
341
+
342
+ .workbench-viewport.workbench-lights-off {
343
+ background-color: #000;
344
+ border-color: #1e293b;
345
+ }
346
+
347
+ .petri-dish {
348
+ width: 180px;
349
+ height: 180px;
350
+ border: 3px solid var(--fbt-glass-tube-border);
351
+ border-radius: 50%;
352
+ position: relative;
353
+ background: rgba(255, 255, 255, 0.02);
354
+ display: flex;
355
+ align-items: center;
356
+ justify-content: center;
357
+ overflow: hidden;
358
+ box-shadow: inset 0 0 10px rgba(0, 0, 0, 0.05);
359
+ }
360
+
361
+ .workbench-viewport.workbench-lights-off .petri-dish {
362
+ border-color: rgba(255, 255, 255, 0.1);
363
+ }
364
+
365
+ .petri-specimen {
366
+ width: 130px;
367
+ height: 130px;
368
+ border-radius: 50%;
369
+ background-color: transparent;
370
+ filter: blur(12px);
371
+ transition: all 0.4s ease;
372
+ }
373
+
374
+ .specimen-texture-overlay {
375
+ position: absolute;
376
+ width: 100px;
377
+ height: 100px;
378
+ border-radius: 50%;
379
+ opacity: 0.1;
380
+ background-size: cover;
381
+ pointer-events: none;
382
+ }
383
+
384
+ .chemical-drop {
385
+ position: absolute;
386
+ top: 0;
387
+ left: 50%;
388
+ transform: translateX(-50%);
389
+ width: 6px;
390
+ height: 12px;
391
+ background: #38bdf8;
392
+ border-radius: 50% / 70% 70% 30% 30%;
393
+ opacity: 0;
394
+ pointer-events: none;
395
+ }
396
+
397
+ .chemical-drop.animating {
398
+ animation: dripAnimation 0.5s cubic-bezier(0.5, 0, 0.7, 0.2) forwards;
399
+ }
400
+
401
+ @keyframes dripAnimation {
402
+ 0% {
403
+ top: 20px;
404
+ opacity: 1;
405
+ transform: translateX(-50%) scaleY(1.2);
406
+ }
407
+ 90% {
408
+ top: 130px;
409
+ opacity: 0.8;
410
+ }
411
+ 100% {
412
+ top: 140px;
413
+ opacity: 0;
414
+ transform: translateX(-50%) scale(0);
415
+ }
416
+ }
417
+
418
+ .analysis-console {
419
+ background: var(--fbt-panel-bg);
420
+ border: 1px solid var(--fbt-panel-border);
421
+ border-radius: 16px;
422
+ padding: 1.5rem;
423
+ display: flex;
424
+ flex-direction: column;
425
+ gap: 1.25rem;
426
+ }
427
+
428
+ .console-header {
429
+ display: flex;
430
+ justify-content: space-between;
431
+ align-items: center;
432
+ border-bottom: 1px solid var(--fbt-border);
433
+ padding-bottom: 0.75rem;
434
+ }
435
+
436
+ .status-indicator-group {
437
+ display: flex;
438
+ align-items: center;
439
+ gap: 0.75rem;
440
+ }
441
+
442
+ .console-label {
443
+ font-size: 0.75rem;
444
+ font-weight: 800;
445
+ letter-spacing: 0.05em;
446
+ text-transform: uppercase;
447
+ color: var(--fbt-muted);
448
+ }
449
+
450
+ .status-badge {
451
+ padding: 0.35rem 0.75rem;
452
+ border-radius: 6px;
453
+ font-size: 0.75rem;
454
+ font-weight: 800;
455
+ }
456
+
457
+ .status-true-positive {
458
+ background: rgba(239, 68, 68, 0.1);
459
+ color: #ef4444;
460
+ }
461
+
462
+ .status-false-positive {
463
+ background: rgba(245, 158, 11, 0.1);
464
+ color: #f59e0b;
465
+ }
466
+
467
+ .status-negative {
468
+ background: var(--fbt-badge-bg);
469
+ color: var(--fbt-badge-text);
470
+ }
471
+
472
+ .btn-clear-lab {
473
+ background: var(--fbt-bg);
474
+ border: 1px solid var(--fbt-border);
475
+ color: var(--fbt-text);
476
+ font-size: 0.75rem;
477
+ font-weight: 700;
478
+ padding: 0.4rem 0.85rem;
479
+ border-radius: 8px;
480
+ cursor: pointer;
481
+ transition: all 0.15s ease;
482
+ }
483
+
484
+ .btn-clear-lab:hover {
485
+ background: var(--fbt-panel-border);
486
+ }
487
+
488
+ .console-body {
489
+ display: flex;
490
+ flex-direction: column;
491
+ gap: 1.25rem;
492
+ }
493
+
494
+ .indicator-row {
495
+ display: flex;
496
+ flex-direction: column;
497
+ gap: 0.5rem;
498
+ }
499
+
500
+ .reaction-explanation-panel {
501
+ font-size: 0.85rem;
502
+ line-height: 1.5;
503
+ color: var(--fbt-text);
504
+ }
505
+
506
+ .stats-grid {
507
+ display: grid;
508
+ grid-template-columns: repeat(2, 1fr);
509
+ gap: 0.75rem;
510
+ }
511
+
512
+ .stat-cell {
513
+ background: var(--fbt-bg);
514
+ border: 1px solid var(--fbt-border);
515
+ padding: 0.85rem;
516
+ border-radius: 8px;
517
+ display: flex;
518
+ flex-direction: column;
519
+ gap: 0.25rem;
520
+ }
521
+
522
+ .stat-label {
523
+ font-size: 0.65rem;
524
+ font-weight: 700;
525
+ text-transform: uppercase;
526
+ color: var(--fbt-muted);
527
+ }
528
+
529
+ .stat-value {
530
+ font-size: 1rem;
531
+ font-weight: 800;
532
+ }
@@ -0,0 +1,16 @@
1
+ export function getReactionColor(colorHex: string, intensity: number): string {
2
+ if (colorHex === 'clear' || !colorHex) return 'rgba(255, 255, 255, 0.15)';
3
+ if (colorHex.startsWith('#')) {
4
+ const r = parseInt(colorHex.slice(1, 3), 16);
5
+ const g = parseInt(colorHex.slice(3, 5), 16);
6
+ const b = parseInt(colorHex.slice(5, 7), 16);
7
+ return `rgba(${r}, ${g}, ${b}, ${intensity.toFixed(2)})`;
8
+ }
9
+ return colorHex;
10
+ }
11
+
12
+ export function getGlowOpacity(elapsedMs: number, durationMs: number): number {
13
+ if (durationMs <= 0) return 0;
14
+ const ratio = Math.max(0, Math.min(1, elapsedMs / durationMs));
15
+ return 1 - ratio;
16
+ }