@jjlmoya/utils-developer 1.28.0 → 1.29.1

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 (457) hide show
  1. package/package.json +1 -1
  2. package/src/entries.ts +4 -1
  3. package/src/tests/entry_contract.test.ts +10 -0
  4. package/src/tests/i18n_coverage.test.ts +5 -2
  5. package/src/tests/locale_completeness.test.ts +1 -1
  6. package/src/tests/qa-test-helpers.ts +32 -0
  7. package/src/tests/qa_bibliography_links.test.ts +43 -0
  8. package/src/tests/qa_claim_evidence.test.ts +69 -0
  9. package/src/tests/qa_logic_reference_coverage.test.ts +46 -0
  10. package/src/tests/qa_runtime_i18n.test.ts +115 -0
  11. package/src/tests/tool_validation.test.ts +1 -1
  12. package/src/tool/aspectRatio/bibliography.astro +2 -10
  13. package/src/tool/aspectRatio/bibliography.ts +7 -0
  14. package/src/tool/aspectRatio/i18n/de.ts +2 -14
  15. package/src/tool/aspectRatio/i18n/en.ts +2 -14
  16. package/src/tool/aspectRatio/i18n/es.ts +2 -14
  17. package/src/tool/aspectRatio/i18n/fr.ts +2 -14
  18. package/src/tool/aspectRatio/i18n/id.ts +2 -14
  19. package/src/tool/aspectRatio/i18n/it.ts +2 -14
  20. package/src/tool/aspectRatio/i18n/ja.ts +2 -14
  21. package/src/tool/aspectRatio/i18n/ko.ts +2 -14
  22. package/src/tool/aspectRatio/i18n/nl.ts +2 -14
  23. package/src/tool/aspectRatio/i18n/pl.ts +2 -14
  24. package/src/tool/aspectRatio/i18n/pt.ts +2 -14
  25. package/src/tool/aspectRatio/i18n/ru.ts +2 -14
  26. package/src/tool/aspectRatio/i18n/sv.ts +2 -14
  27. package/src/tool/aspectRatio/i18n/tr.ts +2 -14
  28. package/src/tool/aspectRatio/i18n/zh.ts +2 -14
  29. package/src/tool/calculadoraTiempoDatos/bibliography.astro +2 -10
  30. package/src/tool/calculadoraTiempoDatos/bibliography.ts +8 -0
  31. package/src/tool/calculadoraTiempoDatos/component.astro +6 -2
  32. package/src/tool/calculadoraTiempoDatos/i18n/de.ts +2 -6
  33. package/src/tool/calculadoraTiempoDatos/i18n/en.ts +2 -6
  34. package/src/tool/calculadoraTiempoDatos/i18n/es.ts +2 -6
  35. package/src/tool/calculadoraTiempoDatos/i18n/fr.ts +2 -6
  36. package/src/tool/calculadoraTiempoDatos/i18n/id.ts +2 -6
  37. package/src/tool/calculadoraTiempoDatos/i18n/it.ts +2 -6
  38. package/src/tool/calculadoraTiempoDatos/i18n/ja.ts +2 -6
  39. package/src/tool/calculadoraTiempoDatos/i18n/ko.ts +2 -6
  40. package/src/tool/calculadoraTiempoDatos/i18n/nl.ts +2 -6
  41. package/src/tool/calculadoraTiempoDatos/i18n/pl.ts +2 -6
  42. package/src/tool/calculadoraTiempoDatos/i18n/pt.ts +2 -6
  43. package/src/tool/calculadoraTiempoDatos/i18n/ru.ts +2 -6
  44. package/src/tool/calculadoraTiempoDatos/i18n/sv.ts +2 -6
  45. package/src/tool/calculadoraTiempoDatos/i18n/tr.ts +2 -6
  46. package/src/tool/calculadoraTiempoDatos/i18n/zh.ts +2 -6
  47. package/src/tool/colorConverter/bibliography.astro +2 -10
  48. package/src/tool/colorConverter/bibliography.ts +7 -0
  49. package/src/tool/colorConverter/i18n/de.ts +2 -5
  50. package/src/tool/colorConverter/i18n/en.ts +5 -8
  51. package/src/tool/colorConverter/i18n/es.ts +4 -7
  52. package/src/tool/colorConverter/i18n/fr.ts +2 -5
  53. package/src/tool/colorConverter/i18n/id.ts +2 -5
  54. package/src/tool/colorConverter/i18n/it.ts +2 -5
  55. package/src/tool/colorConverter/i18n/ja.ts +2 -5
  56. package/src/tool/colorConverter/i18n/ko.ts +2 -5
  57. package/src/tool/colorConverter/i18n/nl.ts +2 -5
  58. package/src/tool/colorConverter/i18n/pl.ts +2 -5
  59. package/src/tool/colorConverter/i18n/pt.ts +2 -5
  60. package/src/tool/colorConverter/i18n/ru.ts +2 -5
  61. package/src/tool/colorConverter/i18n/sv.ts +2 -5
  62. package/src/tool/colorConverter/i18n/tr.ts +2 -5
  63. package/src/tool/colorConverter/i18n/zh.ts +2 -5
  64. package/src/tool/conversorExcelCsvHtml/bibliography.astro +2 -10
  65. package/src/tool/conversorExcelCsvHtml/bibliography.ts +8 -0
  66. package/src/tool/conversorExcelCsvHtml/component.astro +4 -3
  67. package/src/tool/conversorExcelCsvHtml/i18n/de.ts +2 -6
  68. package/src/tool/conversorExcelCsvHtml/i18n/en.ts +2 -6
  69. package/src/tool/conversorExcelCsvHtml/i18n/es.ts +2 -6
  70. package/src/tool/conversorExcelCsvHtml/i18n/fr.ts +2 -6
  71. package/src/tool/conversorExcelCsvHtml/i18n/id.ts +2 -6
  72. package/src/tool/conversorExcelCsvHtml/i18n/it.ts +2 -6
  73. package/src/tool/conversorExcelCsvHtml/i18n/ja.ts +2 -6
  74. package/src/tool/conversorExcelCsvHtml/i18n/ko.ts +2 -6
  75. package/src/tool/conversorExcelCsvHtml/i18n/nl.ts +2 -6
  76. package/src/tool/conversorExcelCsvHtml/i18n/pl.ts +2 -6
  77. package/src/tool/conversorExcelCsvHtml/i18n/pt.ts +2 -6
  78. package/src/tool/conversorExcelCsvHtml/i18n/ru.ts +2 -6
  79. package/src/tool/conversorExcelCsvHtml/i18n/sv.ts +2 -6
  80. package/src/tool/conversorExcelCsvHtml/i18n/tr.ts +2 -6
  81. package/src/tool/conversorExcelCsvHtml/i18n/zh.ts +2 -6
  82. package/src/tool/cronGenerator/bibliography.astro +2 -10
  83. package/src/tool/cronGenerator/bibliography.ts +6 -0
  84. package/src/tool/cronGenerator/component.astro +5 -1
  85. package/src/tool/cronGenerator/i18n/de.ts +2 -10
  86. package/src/tool/cronGenerator/i18n/en.ts +2 -10
  87. package/src/tool/cronGenerator/i18n/es.ts +2 -10
  88. package/src/tool/cronGenerator/i18n/fr.ts +2 -10
  89. package/src/tool/cronGenerator/i18n/id.ts +2 -10
  90. package/src/tool/cronGenerator/i18n/it.ts +2 -10
  91. package/src/tool/cronGenerator/i18n/ja.ts +2 -10
  92. package/src/tool/cronGenerator/i18n/ko.ts +2 -10
  93. package/src/tool/cronGenerator/i18n/nl.ts +2 -10
  94. package/src/tool/cronGenerator/i18n/pl.ts +2 -10
  95. package/src/tool/cronGenerator/i18n/pt.ts +2 -10
  96. package/src/tool/cronGenerator/i18n/ru.ts +2 -10
  97. package/src/tool/cronGenerator/i18n/sv.ts +2 -10
  98. package/src/tool/cronGenerator/i18n/tr.ts +2 -10
  99. package/src/tool/cronGenerator/i18n/zh.ts +2 -10
  100. package/src/tool/cssBoxShadowGenerator/component.astro +2 -1
  101. package/src/tool/cssBoxShadowGenerator/logic.test.ts +28 -0
  102. package/src/tool/cssSpecificityCalculator/bibliography.astro +2 -10
  103. package/src/tool/cssSpecificityCalculator/bibliography.ts +6 -0
  104. package/src/tool/cssSpecificityCalculator/i18n/de.ts +2 -10
  105. package/src/tool/cssSpecificityCalculator/i18n/en.ts +2 -10
  106. package/src/tool/cssSpecificityCalculator/i18n/es.ts +2 -10
  107. package/src/tool/cssSpecificityCalculator/i18n/fr.ts +2 -10
  108. package/src/tool/cssSpecificityCalculator/i18n/id.ts +2 -10
  109. package/src/tool/cssSpecificityCalculator/i18n/it.ts +2 -10
  110. package/src/tool/cssSpecificityCalculator/i18n/ja.ts +2 -10
  111. package/src/tool/cssSpecificityCalculator/i18n/ko.ts +2 -10
  112. package/src/tool/cssSpecificityCalculator/i18n/nl.ts +2 -10
  113. package/src/tool/cssSpecificityCalculator/i18n/pl.ts +2 -10
  114. package/src/tool/cssSpecificityCalculator/i18n/pt.ts +2 -10
  115. package/src/tool/cssSpecificityCalculator/i18n/ru.ts +2 -10
  116. package/src/tool/cssSpecificityCalculator/i18n/sv.ts +2 -10
  117. package/src/tool/cssSpecificityCalculator/i18n/tr.ts +2 -10
  118. package/src/tool/cssSpecificityCalculator/i18n/zh.ts +2 -10
  119. package/src/tool/cssToInlineConverter/bibliography.astro +2 -10
  120. package/src/tool/cssToInlineConverter/bibliography.ts +7 -0
  121. package/src/tool/cssToInlineConverter/i18n/de.ts +2 -14
  122. package/src/tool/cssToInlineConverter/i18n/en.ts +4 -16
  123. package/src/tool/cssToInlineConverter/i18n/es.ts +5 -17
  124. package/src/tool/cssToInlineConverter/i18n/fr.ts +2 -14
  125. package/src/tool/cssToInlineConverter/i18n/id.ts +2 -14
  126. package/src/tool/cssToInlineConverter/i18n/it.ts +2 -14
  127. package/src/tool/cssToInlineConverter/i18n/ja.ts +2 -14
  128. package/src/tool/cssToInlineConverter/i18n/ko.ts +2 -14
  129. package/src/tool/cssToInlineConverter/i18n/nl.ts +2 -14
  130. package/src/tool/cssToInlineConverter/i18n/pl.ts +2 -14
  131. package/src/tool/cssToInlineConverter/i18n/pt.ts +2 -14
  132. package/src/tool/cssToInlineConverter/i18n/ru.ts +2 -14
  133. package/src/tool/cssToInlineConverter/i18n/sv.ts +2 -14
  134. package/src/tool/cssToInlineConverter/i18n/tr.ts +2 -14
  135. package/src/tool/cssToInlineConverter/i18n/zh.ts +2 -14
  136. package/src/tool/duplicateCssRemover/bibliography.astro +2 -10
  137. package/src/tool/duplicateCssRemover/bibliography.ts +7 -0
  138. package/src/tool/duplicateCssRemover/i18n/de.ts +2 -14
  139. package/src/tool/duplicateCssRemover/i18n/en.ts +4 -16
  140. package/src/tool/duplicateCssRemover/i18n/es.ts +4 -16
  141. package/src/tool/duplicateCssRemover/i18n/fr.ts +2 -14
  142. package/src/tool/duplicateCssRemover/i18n/id.ts +2 -14
  143. package/src/tool/duplicateCssRemover/i18n/it.ts +2 -14
  144. package/src/tool/duplicateCssRemover/i18n/ja.ts +2 -14
  145. package/src/tool/duplicateCssRemover/i18n/ko.ts +2 -14
  146. package/src/tool/duplicateCssRemover/i18n/nl.ts +2 -14
  147. package/src/tool/duplicateCssRemover/i18n/pl.ts +2 -14
  148. package/src/tool/duplicateCssRemover/i18n/pt.ts +2 -14
  149. package/src/tool/duplicateCssRemover/i18n/ru.ts +2 -14
  150. package/src/tool/duplicateCssRemover/i18n/sv.ts +2 -14
  151. package/src/tool/duplicateCssRemover/i18n/tr.ts +2 -14
  152. package/src/tool/duplicateCssRemover/i18n/zh.ts +2 -14
  153. package/src/tool/generadorSecurityTxt/bibliography.astro +2 -10
  154. package/src/tool/generadorSecurityTxt/bibliography.ts +7 -0
  155. package/src/tool/generadorSecurityTxt/component.astro +1 -2
  156. package/src/tool/generadorSecurityTxt/i18n/de.ts +2 -5
  157. package/src/tool/generadorSecurityTxt/i18n/en.ts +2 -5
  158. package/src/tool/generadorSecurityTxt/i18n/es.ts +2 -5
  159. package/src/tool/generadorSecurityTxt/i18n/fr.ts +2 -5
  160. package/src/tool/generadorSecurityTxt/i18n/id.ts +2 -5
  161. package/src/tool/generadorSecurityTxt/i18n/it.ts +2 -5
  162. package/src/tool/generadorSecurityTxt/i18n/ja.ts +2 -5
  163. package/src/tool/generadorSecurityTxt/i18n/ko.ts +2 -5
  164. package/src/tool/generadorSecurityTxt/i18n/nl.ts +2 -5
  165. package/src/tool/generadorSecurityTxt/i18n/pl.ts +2 -5
  166. package/src/tool/generadorSecurityTxt/i18n/pt.ts +2 -5
  167. package/src/tool/generadorSecurityTxt/i18n/ru.ts +2 -5
  168. package/src/tool/generadorSecurityTxt/i18n/sv.ts +2 -5
  169. package/src/tool/generadorSecurityTxt/i18n/tr.ts +2 -5
  170. package/src/tool/generadorSecurityTxt/i18n/zh.ts +2 -5
  171. package/src/tool/hashGenerator/bibliography.astro +2 -10
  172. package/src/tool/hashGenerator/bibliography.ts +7 -0
  173. package/src/tool/hashGenerator/i18n/de.ts +2 -5
  174. package/src/tool/hashGenerator/i18n/en.ts +2 -5
  175. package/src/tool/hashGenerator/i18n/es.ts +2 -5
  176. package/src/tool/hashGenerator/i18n/fr.ts +2 -5
  177. package/src/tool/hashGenerator/i18n/id.ts +2 -5
  178. package/src/tool/hashGenerator/i18n/it.ts +2 -5
  179. package/src/tool/hashGenerator/i18n/ja.ts +2 -5
  180. package/src/tool/hashGenerator/i18n/ko.ts +2 -5
  181. package/src/tool/hashGenerator/i18n/nl.ts +2 -5
  182. package/src/tool/hashGenerator/i18n/pl.ts +2 -5
  183. package/src/tool/hashGenerator/i18n/pt.ts +2 -5
  184. package/src/tool/hashGenerator/i18n/ru.ts +2 -5
  185. package/src/tool/hashGenerator/i18n/sv.ts +2 -5
  186. package/src/tool/hashGenerator/i18n/tr.ts +2 -5
  187. package/src/tool/hashGenerator/i18n/zh.ts +2 -5
  188. package/src/tool/inspectorCertificadosSsl/bibliography.astro +2 -10
  189. package/src/tool/inspectorCertificadosSsl/bibliography.ts +8 -0
  190. package/src/tool/inspectorCertificadosSsl/component.astro +4 -3
  191. package/src/tool/inspectorCertificadosSsl/i18n/de.ts +2 -6
  192. package/src/tool/inspectorCertificadosSsl/i18n/en.ts +2 -6
  193. package/src/tool/inspectorCertificadosSsl/i18n/es.ts +2 -6
  194. package/src/tool/inspectorCertificadosSsl/i18n/fr.ts +2 -6
  195. package/src/tool/inspectorCertificadosSsl/i18n/id.ts +2 -6
  196. package/src/tool/inspectorCertificadosSsl/i18n/it.ts +2 -6
  197. package/src/tool/inspectorCertificadosSsl/i18n/ja.ts +2 -6
  198. package/src/tool/inspectorCertificadosSsl/i18n/ko.ts +2 -6
  199. package/src/tool/inspectorCertificadosSsl/i18n/nl.ts +2 -6
  200. package/src/tool/inspectorCertificadosSsl/i18n/pl.ts +2 -6
  201. package/src/tool/inspectorCertificadosSsl/i18n/pt.ts +2 -6
  202. package/src/tool/inspectorCertificadosSsl/i18n/ru.ts +2 -6
  203. package/src/tool/inspectorCertificadosSsl/i18n/sv.ts +2 -6
  204. package/src/tool/inspectorCertificadosSsl/i18n/tr.ts +2 -6
  205. package/src/tool/inspectorCertificadosSsl/i18n/zh.ts +2 -6
  206. package/src/tool/jsonFormatter/bibliography.astro +2 -10
  207. package/src/tool/jsonFormatter/bibliography.ts +8 -0
  208. package/src/tool/jsonFormatter/i18n/de.ts +2 -18
  209. package/src/tool/jsonFormatter/i18n/en.ts +2 -18
  210. package/src/tool/jsonFormatter/i18n/es.ts +2 -18
  211. package/src/tool/jsonFormatter/i18n/fr.ts +2 -18
  212. package/src/tool/jsonFormatter/i18n/id.ts +2 -18
  213. package/src/tool/jsonFormatter/i18n/it.ts +2 -18
  214. package/src/tool/jsonFormatter/i18n/ja.ts +2 -18
  215. package/src/tool/jsonFormatter/i18n/ko.ts +2 -18
  216. package/src/tool/jsonFormatter/i18n/nl.ts +2 -18
  217. package/src/tool/jsonFormatter/i18n/pl.ts +2 -18
  218. package/src/tool/jsonFormatter/i18n/pt.ts +2 -18
  219. package/src/tool/jsonFormatter/i18n/ru.ts +2 -18
  220. package/src/tool/jsonFormatter/i18n/sv.ts +2 -18
  221. package/src/tool/jsonFormatter/i18n/tr.ts +2 -18
  222. package/src/tool/jsonFormatter/i18n/zh.ts +2 -18
  223. package/src/tool/jwtDecoder/component.astro +2 -1
  224. package/src/tool/jwtDecoder/logic.test.ts +32 -0
  225. package/src/tool/keycode/bibliography.astro +2 -10
  226. package/src/tool/keycode/bibliography.ts +7 -0
  227. package/src/tool/keycode/i18n/de.ts +2 -14
  228. package/src/tool/keycode/i18n/en.ts +2 -14
  229. package/src/tool/keycode/i18n/es.ts +2 -14
  230. package/src/tool/keycode/i18n/fr.ts +2 -14
  231. package/src/tool/keycode/i18n/id.ts +2 -14
  232. package/src/tool/keycode/i18n/it.ts +2 -14
  233. package/src/tool/keycode/i18n/ja.ts +2 -14
  234. package/src/tool/keycode/i18n/ko.ts +2 -14
  235. package/src/tool/keycode/i18n/nl.ts +2 -14
  236. package/src/tool/keycode/i18n/pl.ts +2 -14
  237. package/src/tool/keycode/i18n/pt.ts +2 -14
  238. package/src/tool/keycode/i18n/ru.ts +2 -14
  239. package/src/tool/keycode/i18n/sv.ts +2 -14
  240. package/src/tool/keycode/i18n/tr.ts +2 -14
  241. package/src/tool/keycode/i18n/zh.ts +2 -14
  242. package/src/tool/llmCostCalculator/bibliography.astro +2 -10
  243. package/src/tool/llmCostCalculator/bibliography.ts +8 -0
  244. package/src/tool/llmCostCalculator/i18n/de.ts +2 -18
  245. package/src/tool/llmCostCalculator/i18n/en.ts +2 -18
  246. package/src/tool/llmCostCalculator/i18n/es.ts +2 -18
  247. package/src/tool/llmCostCalculator/i18n/fr.ts +2 -18
  248. package/src/tool/llmCostCalculator/i18n/id.ts +2 -18
  249. package/src/tool/llmCostCalculator/i18n/it.ts +2 -18
  250. package/src/tool/llmCostCalculator/i18n/ja.ts +2 -18
  251. package/src/tool/llmCostCalculator/i18n/ko.ts +2 -18
  252. package/src/tool/llmCostCalculator/i18n/nl.ts +2 -18
  253. package/src/tool/llmCostCalculator/i18n/pl.ts +2 -18
  254. package/src/tool/llmCostCalculator/i18n/pt.ts +2 -18
  255. package/src/tool/llmCostCalculator/i18n/ru.ts +2 -18
  256. package/src/tool/llmCostCalculator/i18n/sv.ts +2 -18
  257. package/src/tool/llmCostCalculator/i18n/tr.ts +2 -18
  258. package/src/tool/llmCostCalculator/i18n/zh.ts +2 -18
  259. package/src/tool/mobileMockupGenerator/bibliography.astro +2 -10
  260. package/src/tool/mobileMockupGenerator/bibliography.ts +6 -0
  261. package/src/tool/mobileMockupGenerator/i18n/de.ts +2 -4
  262. package/src/tool/mobileMockupGenerator/i18n/en.ts +2 -4
  263. package/src/tool/mobileMockupGenerator/i18n/es.ts +2 -4
  264. package/src/tool/mobileMockupGenerator/i18n/fr.ts +2 -4
  265. package/src/tool/mobileMockupGenerator/i18n/id.ts +2 -4
  266. package/src/tool/mobileMockupGenerator/i18n/it.ts +2 -4
  267. package/src/tool/mobileMockupGenerator/i18n/ja.ts +2 -4
  268. package/src/tool/mobileMockupGenerator/i18n/ko.ts +2 -4
  269. package/src/tool/mobileMockupGenerator/i18n/nl.ts +2 -4
  270. package/src/tool/mobileMockupGenerator/i18n/pl.ts +2 -1
  271. package/src/tool/mobileMockupGenerator/i18n/pt.ts +2 -4
  272. package/src/tool/mobileMockupGenerator/i18n/ru.ts +2 -4
  273. package/src/tool/mobileMockupGenerator/i18n/sv.ts +2 -4
  274. package/src/tool/mobileMockupGenerator/i18n/tr.ts +2 -4
  275. package/src/tool/mobileMockupGenerator/i18n/zh.ts +2 -4
  276. package/src/tool/musicalTypography/bibliography.astro +2 -10
  277. package/src/tool/musicalTypography/bibliography.ts +7 -0
  278. package/src/tool/musicalTypography/i18n/de.ts +2 -14
  279. package/src/tool/musicalTypography/i18n/en.ts +3 -15
  280. package/src/tool/musicalTypography/i18n/es.ts +3 -15
  281. package/src/tool/musicalTypography/i18n/fr.ts +2 -14
  282. package/src/tool/musicalTypography/i18n/id.ts +2 -14
  283. package/src/tool/musicalTypography/i18n/it.ts +2 -14
  284. package/src/tool/musicalTypography/i18n/ja.ts +2 -14
  285. package/src/tool/musicalTypography/i18n/ko.ts +2 -14
  286. package/src/tool/musicalTypography/i18n/nl.ts +2 -14
  287. package/src/tool/musicalTypography/i18n/pl.ts +2 -14
  288. package/src/tool/musicalTypography/i18n/pt.ts +2 -5
  289. package/src/tool/musicalTypography/i18n/ru.ts +2 -5
  290. package/src/tool/musicalTypography/i18n/sv.ts +2 -1
  291. package/src/tool/musicalTypography/i18n/tr.ts +2 -1
  292. package/src/tool/musicalTypography/i18n/zh.ts +2 -1
  293. package/src/tool/placeholderGenerator/bibliography.astro +2 -10
  294. package/src/tool/placeholderGenerator/bibliography.ts +7 -0
  295. package/src/tool/placeholderGenerator/i18n/de.ts +2 -14
  296. package/src/tool/placeholderGenerator/i18n/en.ts +4 -16
  297. package/src/tool/placeholderGenerator/i18n/es.ts +4 -16
  298. package/src/tool/placeholderGenerator/i18n/fr.ts +2 -14
  299. package/src/tool/placeholderGenerator/i18n/id.ts +2 -14
  300. package/src/tool/placeholderGenerator/i18n/it.ts +2 -14
  301. package/src/tool/placeholderGenerator/i18n/ja.ts +2 -14
  302. package/src/tool/placeholderGenerator/i18n/ko.ts +2 -14
  303. package/src/tool/placeholderGenerator/i18n/nl.ts +2 -14
  304. package/src/tool/placeholderGenerator/i18n/pl.ts +2 -14
  305. package/src/tool/placeholderGenerator/i18n/pt.ts +2 -14
  306. package/src/tool/placeholderGenerator/i18n/ru.ts +2 -14
  307. package/src/tool/placeholderGenerator/i18n/sv.ts +2 -14
  308. package/src/tool/placeholderGenerator/i18n/tr.ts +2 -14
  309. package/src/tool/placeholderGenerator/i18n/zh.ts +2 -14
  310. package/src/tool/promoteThisWebsite/asset-bindings.ts +73 -0
  311. package/src/tool/promoteThisWebsite/bibliography.astro +14 -0
  312. package/src/tool/promoteThisWebsite/bibliography.ts +14 -0
  313. package/src/tool/promoteThisWebsite/component.astro +136 -0
  314. package/src/tool/promoteThisWebsite/control-views.ts +83 -0
  315. package/src/tool/promoteThisWebsite/controller.ts +232 -0
  316. package/src/tool/promoteThisWebsite/dom-views.ts +322 -0
  317. package/src/tool/promoteThisWebsite/entry.ts +16 -0
  318. package/src/tool/promoteThisWebsite/evaluator.ts +9 -0
  319. package/src/tool/promoteThisWebsite/i18n/en.ts +111 -0
  320. package/src/tool/promoteThisWebsite/i18n/es.ts +111 -0
  321. package/src/tool/promoteThisWebsite/index.ts +11 -0
  322. package/src/tool/promoteThisWebsite/jjlmoya-overlay.png +0 -0
  323. package/src/tool/promoteThisWebsite/logic.test.ts +29 -0
  324. package/src/tool/promoteThisWebsite/logic.ts +108 -0
  325. package/src/tool/promoteThisWebsite/pixel-cat.png +0 -0
  326. package/src/tool/promoteThisWebsite/promote-this-website.css +322 -0
  327. package/src/tool/promoteThisWebsite/seo.astro +15 -0
  328. package/src/tool/promoteThisWebsite/storage.ts +28 -0
  329. package/src/tool/promoteThisWebsite/title-view.ts +206 -0
  330. package/src/tool/promoteThisWebsite/ui.ts +59 -0
  331. package/src/tool/promptLibrary/bibliography.astro +2 -10
  332. package/src/tool/promptLibrary/bibliography.ts +6 -0
  333. package/src/tool/promptLibrary/i18n/de.ts +2 -4
  334. package/src/tool/promptLibrary/i18n/en.ts +2 -4
  335. package/src/tool/promptLibrary/i18n/es.ts +2 -4
  336. package/src/tool/promptLibrary/i18n/fr.ts +2 -4
  337. package/src/tool/promptLibrary/i18n/id.ts +2 -4
  338. package/src/tool/promptLibrary/i18n/it.ts +2 -4
  339. package/src/tool/promptLibrary/i18n/ja.ts +2 -4
  340. package/src/tool/promptLibrary/i18n/ko.ts +2 -4
  341. package/src/tool/promptLibrary/i18n/nl.ts +2 -4
  342. package/src/tool/promptLibrary/i18n/pl.ts +2 -1
  343. package/src/tool/promptLibrary/i18n/pt.ts +2 -4
  344. package/src/tool/promptLibrary/i18n/ru.ts +2 -4
  345. package/src/tool/promptLibrary/i18n/sv.ts +2 -4
  346. package/src/tool/promptLibrary/i18n/tr.ts +2 -4
  347. package/src/tool/promptLibrary/i18n/zh.ts +2 -4
  348. package/src/tool/readabilityCalculator/bibliography.astro +2 -10
  349. package/src/tool/readabilityCalculator/bibliography.ts +7 -0
  350. package/src/tool/readabilityCalculator/i18n/de.ts +2 -5
  351. package/src/tool/readabilityCalculator/i18n/en.ts +2 -5
  352. package/src/tool/readabilityCalculator/i18n/es.ts +2 -5
  353. package/src/tool/readabilityCalculator/i18n/fr.ts +2 -5
  354. package/src/tool/readabilityCalculator/i18n/id.ts +2 -5
  355. package/src/tool/readabilityCalculator/i18n/it.ts +2 -5
  356. package/src/tool/readabilityCalculator/i18n/ja.ts +2 -5
  357. package/src/tool/readabilityCalculator/i18n/ko.ts +2 -5
  358. package/src/tool/readabilityCalculator/i18n/nl.ts +2 -5
  359. package/src/tool/readabilityCalculator/i18n/pl.ts +2 -1
  360. package/src/tool/readabilityCalculator/i18n/pt.ts +2 -5
  361. package/src/tool/readabilityCalculator/i18n/ru.ts +2 -5
  362. package/src/tool/readabilityCalculator/i18n/sv.ts +2 -5
  363. package/src/tool/readabilityCalculator/i18n/tr.ts +2 -5
  364. package/src/tool/readabilityCalculator/i18n/zh.ts +2 -5
  365. package/src/tool/serpPixelSimulator/controller.ts +1 -0
  366. package/src/tool/serpPixelSimulator/i18n/en.ts +2 -2
  367. package/src/tool/serpPixelSimulator/i18n/es.ts +2 -2
  368. package/src/tool/serpPixelSimulator/logic.test.ts +25 -0
  369. package/src/tool/svgSanitizer/bibliography.astro +2 -10
  370. package/src/tool/svgSanitizer/bibliography.ts +7 -0
  371. package/src/tool/svgSanitizer/i18n/de.ts +2 -5
  372. package/src/tool/svgSanitizer/i18n/en.ts +2 -5
  373. package/src/tool/svgSanitizer/i18n/es.ts +2 -5
  374. package/src/tool/svgSanitizer/i18n/fr.ts +2 -5
  375. package/src/tool/svgSanitizer/i18n/id.ts +2 -5
  376. package/src/tool/svgSanitizer/i18n/it.ts +2 -5
  377. package/src/tool/svgSanitizer/i18n/ja.ts +2 -5
  378. package/src/tool/svgSanitizer/i18n/ko.ts +2 -5
  379. package/src/tool/svgSanitizer/i18n/nl.ts +2 -5
  380. package/src/tool/svgSanitizer/i18n/pl.ts +2 -5
  381. package/src/tool/svgSanitizer/i18n/pt.ts +2 -1
  382. package/src/tool/svgSanitizer/i18n/ru.ts +2 -5
  383. package/src/tool/svgSanitizer/i18n/sv.ts +2 -5
  384. package/src/tool/svgSanitizer/i18n/tr.ts +2 -5
  385. package/src/tool/svgSanitizer/i18n/zh.ts +2 -5
  386. package/src/tool/svgToCss/bibliography.astro +2 -10
  387. package/src/tool/svgToCss/bibliography.ts +8 -0
  388. package/src/tool/svgToCss/i18n/de.ts +2 -18
  389. package/src/tool/svgToCss/i18n/en.ts +2 -18
  390. package/src/tool/svgToCss/i18n/es.ts +2 -18
  391. package/src/tool/svgToCss/i18n/fr.ts +2 -18
  392. package/src/tool/svgToCss/i18n/id.ts +2 -18
  393. package/src/tool/svgToCss/i18n/it.ts +2 -18
  394. package/src/tool/svgToCss/i18n/ja.ts +2 -18
  395. package/src/tool/svgToCss/i18n/ko.ts +2 -18
  396. package/src/tool/svgToCss/i18n/nl.ts +2 -18
  397. package/src/tool/svgToCss/i18n/pl.ts +2 -18
  398. package/src/tool/svgToCss/i18n/pt.ts +2 -18
  399. package/src/tool/svgToCss/i18n/ru.ts +2 -18
  400. package/src/tool/svgToCss/i18n/sv.ts +2 -18
  401. package/src/tool/svgToCss/i18n/tr.ts +2 -18
  402. package/src/tool/svgToCss/i18n/zh.ts +2 -18
  403. package/src/tool/urlCleaner/bibliography.astro +2 -10
  404. package/src/tool/urlCleaner/bibliography.ts +7 -0
  405. package/src/tool/urlCleaner/i18n/de.ts +2 -5
  406. package/src/tool/urlCleaner/i18n/en.ts +2 -5
  407. package/src/tool/urlCleaner/i18n/es.ts +2 -5
  408. package/src/tool/urlCleaner/i18n/fr.ts +2 -5
  409. package/src/tool/urlCleaner/i18n/id.ts +2 -5
  410. package/src/tool/urlCleaner/i18n/it.ts +2 -5
  411. package/src/tool/urlCleaner/i18n/ja.ts +2 -5
  412. package/src/tool/urlCleaner/i18n/ko.ts +2 -5
  413. package/src/tool/urlCleaner/i18n/nl.ts +2 -5
  414. package/src/tool/urlCleaner/i18n/pl.ts +2 -1
  415. package/src/tool/urlCleaner/i18n/pt.ts +2 -5
  416. package/src/tool/urlCleaner/i18n/ru.ts +2 -5
  417. package/src/tool/urlCleaner/i18n/sv.ts +2 -5
  418. package/src/tool/urlCleaner/i18n/tr.ts +2 -5
  419. package/src/tool/urlCleaner/i18n/zh.ts +2 -5
  420. package/src/tool/urlEncoderDecoder/bibliography.astro +2 -10
  421. package/src/tool/urlEncoderDecoder/bibliography.ts +7 -0
  422. package/src/tool/urlEncoderDecoder/i18n/de.ts +2 -14
  423. package/src/tool/urlEncoderDecoder/i18n/en.ts +3 -15
  424. package/src/tool/urlEncoderDecoder/i18n/es.ts +3 -15
  425. package/src/tool/urlEncoderDecoder/i18n/fr.ts +2 -14
  426. package/src/tool/urlEncoderDecoder/i18n/id.ts +2 -14
  427. package/src/tool/urlEncoderDecoder/i18n/it.ts +2 -14
  428. package/src/tool/urlEncoderDecoder/i18n/ja.ts +2 -14
  429. package/src/tool/urlEncoderDecoder/i18n/ko.ts +2 -14
  430. package/src/tool/urlEncoderDecoder/i18n/nl.ts +2 -14
  431. package/src/tool/urlEncoderDecoder/i18n/pl.ts +2 -14
  432. package/src/tool/urlEncoderDecoder/i18n/pt.ts +2 -14
  433. package/src/tool/urlEncoderDecoder/i18n/ru.ts +2 -14
  434. package/src/tool/urlEncoderDecoder/i18n/sv.ts +2 -14
  435. package/src/tool/urlEncoderDecoder/i18n/tr.ts +2 -14
  436. package/src/tool/urlEncoderDecoder/i18n/zh.ts +2 -14
  437. package/src/tool/utmGenerator/bibliography.astro +2 -10
  438. package/src/tool/utmGenerator/bibliography.ts +6 -0
  439. package/src/tool/utmGenerator/i18n/de.ts +2 -4
  440. package/src/tool/utmGenerator/i18n/en.ts +2 -4
  441. package/src/tool/utmGenerator/i18n/es.ts +2 -4
  442. package/src/tool/utmGenerator/i18n/fr.ts +2 -4
  443. package/src/tool/utmGenerator/i18n/id.ts +2 -4
  444. package/src/tool/utmGenerator/i18n/it.ts +2 -4
  445. package/src/tool/utmGenerator/i18n/ja.ts +2 -4
  446. package/src/tool/utmGenerator/i18n/ko.ts +2 -4
  447. package/src/tool/utmGenerator/i18n/nl.ts +2 -4
  448. package/src/tool/utmGenerator/i18n/pl.ts +2 -4
  449. package/src/tool/utmGenerator/i18n/pt.ts +2 -4
  450. package/src/tool/utmGenerator/i18n/ru.ts +2 -4
  451. package/src/tool/utmGenerator/i18n/sv.ts +2 -4
  452. package/src/tool/utmGenerator/i18n/tr.ts +2 -4
  453. package/src/tool/utmGenerator/i18n/zh.ts +2 -4
  454. package/src/tool/visualCssGridFlexboxGenerator/component.astro +1 -0
  455. package/src/tool/visualCssGridFlexboxGenerator/logic.test.ts +29 -0
  456. package/src/tool/visualCssGridFlexboxGenerator/workspace.ts +13 -1
  457. package/src/tools.ts +2 -1
@@ -0,0 +1,322 @@
1
+ .promote-tool {
2
+ --promote-ink: #091426;
3
+ --promote-muted: #617078;
4
+ --promote-line: rgba(9, 20, 38, 0.12);
5
+ --promote-panel: rgba(255, 252, 244, 0.86);
6
+ --promote-accent: #c45a2f;
7
+
8
+ display: grid;
9
+ grid-template-columns: minmax(260px, 330px) minmax(0, 1fr);
10
+ gap: 1rem;
11
+ width: min(100%, 1320px);
12
+ min-height: 740px;
13
+ padding: 1rem;
14
+ color: var(--promote-ink);
15
+ background: linear-gradient(135deg, #f4ecdf, #d8e5e3);
16
+ border: 1px solid var(--promote-line);
17
+ border-radius: 24px;
18
+ box-shadow: 0 30px 80px rgba(9, 20, 38, 0.16);
19
+ }
20
+
21
+ .theme-dark .promote-tool {
22
+ --promote-ink: #f7ebd7;
23
+ --promote-muted: #9aabae;
24
+ --promote-line: rgba(247, 235, 215, 0.15);
25
+ --promote-panel: rgba(9, 20, 38, 0.86);
26
+
27
+ background: linear-gradient(135deg, #0b1526, #19344a);
28
+ }
29
+
30
+ .promote-sidebar,
31
+ .promote-stage {
32
+ min-width: 0;
33
+ }
34
+
35
+ .promote-sidebar {
36
+ display: grid;
37
+ align-content: start;
38
+ gap: 0.85rem;
39
+ padding: 1.05rem;
40
+ background: var(--promote-panel);
41
+ border: 1px solid var(--promote-line);
42
+ border-radius: 18px;
43
+ backdrop-filter: blur(18px);
44
+ }
45
+
46
+ .promote-control-group > label,
47
+ .promote-control-grid > label,
48
+ .promote-fieldset legend,
49
+ .promote-layer {
50
+ color: var(--promote-muted);
51
+ font-size: 0.68rem;
52
+ font-weight: 850;
53
+ letter-spacing: 0.05em;
54
+ text-transform: uppercase;
55
+ }
56
+
57
+ .promote-status {
58
+ margin: 0;
59
+ color: var(--promote-muted);
60
+ font-size: 0.78rem;
61
+ line-height: 1.45;
62
+ }
63
+
64
+ .promote-control-group,
65
+ .promote-control-grid,
66
+ .promote-fieldset {
67
+ display: grid;
68
+ gap: 0.45rem;
69
+ }
70
+
71
+ .promote-advanced {
72
+ display: grid;
73
+ gap: 0.75rem;
74
+ }
75
+
76
+ .promote-advanced summary {
77
+ padding: 0.55rem 0;
78
+ color: var(--promote-muted);
79
+ font-size: 0.68rem;
80
+ font-weight: 850;
81
+ letter-spacing: 0.05em;
82
+ text-transform: uppercase;
83
+ cursor: pointer;
84
+ }
85
+
86
+ .promote-inline-control {
87
+ display: grid;
88
+ grid-template-columns: 1fr auto;
89
+ gap: 0.4rem;
90
+ }
91
+
92
+ .promote-control-grid {
93
+ grid-template-columns: 1fr 1fr;
94
+ align-items: center;
95
+ }
96
+
97
+ .promote-control-grid > label {
98
+ letter-spacing: 0;
99
+ }
100
+
101
+ .promote-tool input[type='url'],
102
+ .promote-tool input[type='text'],
103
+ .promote-custom-select,
104
+ .promote-tool button {
105
+ min-height: 2.2rem;
106
+ color: var(--promote-ink);
107
+ font: inherit;
108
+ border: 1px solid var(--promote-line);
109
+ border-radius: 9px;
110
+ background: rgba(255, 255, 255, 0.45);
111
+ }
112
+
113
+ .theme-dark .promote-tool input[type='url'],
114
+ .theme-dark .promote-tool input[type='text'],
115
+ .theme-dark .promote-custom-select,
116
+ .theme-dark .promote-tool button {
117
+ background: rgba(0, 0, 0, 0.2);
118
+ }
119
+
120
+ .promote-tool input[type='url'],
121
+ .promote-tool input[type='text'] {
122
+ width: 100%;
123
+ padding: 0.5rem 0.6rem;
124
+ }
125
+
126
+ .promote-custom-select {
127
+ position: relative;
128
+ min-width: 0;
129
+ }
130
+
131
+ .promote-select-trigger {
132
+ display: flex;
133
+ align-items: center;
134
+ justify-content: space-between;
135
+ width: 100%;
136
+ padding: 0.5rem 0.6rem;
137
+ text-align: left;
138
+ }
139
+
140
+ .promote-select-trigger span:first-child {
141
+ min-width: 0;
142
+ overflow: hidden;
143
+ text-overflow: ellipsis;
144
+ white-space: nowrap;
145
+ }
146
+
147
+ .promote-select-menu {
148
+ position: absolute;
149
+ z-index: 20;
150
+ top: calc(100% + 0.25rem);
151
+ right: 0;
152
+ width: max-content;
153
+ min-width: 100%;
154
+ max-width: min(260px, calc(100vw - 2rem));
155
+ display: grid;
156
+ padding: 0.25rem;
157
+ overflow: visible;
158
+ background: #fffaf0;
159
+ border: 1px solid var(--promote-accent);
160
+ border-radius: 10px;
161
+ box-shadow: 0 14px 28px rgba(4, 11, 24, 0.3);
162
+ }
163
+
164
+ .promote-select-menu[data-placement='top'] {
165
+ top: auto;
166
+ bottom: calc(100% + 0.25rem);
167
+ }
168
+
169
+ .promote-select-menu[hidden] {
170
+ display: none;
171
+ }
172
+
173
+ .theme-dark .promote-select-menu {
174
+ background: #14243b;
175
+ border-color: #11d6c4;
176
+ box-shadow: 0 14px 28px rgba(0, 0, 0, 0.45);
177
+ }
178
+
179
+ .promote-tool .promote-select-option {
180
+ width: 100%;
181
+ min-height: 1.95rem;
182
+ padding: 0.45rem 0.55rem;
183
+ color: #071226;
184
+ text-align: left;
185
+ background: transparent;
186
+ border: 0;
187
+ border-radius: 7px;
188
+ white-space: nowrap;
189
+ }
190
+
191
+ .theme-dark .promote-tool .promote-select-option {
192
+ color: #f7ebd7;
193
+ }
194
+
195
+ .promote-tool .promote-select-option:hover,
196
+ .promote-tool .promote-select-option:focus-visible,
197
+ .promote-tool .promote-select-option[aria-selected='true'] {
198
+ color: #fffaf0;
199
+ background: var(--promote-accent);
200
+ }
201
+
202
+ .promote-tool button {
203
+ padding: 0.5rem 0.7rem;
204
+ cursor: pointer;
205
+ }
206
+
207
+ .promote-tool button:hover,
208
+ .promote-tool button:focus-visible {
209
+ border-color: var(--promote-accent);
210
+ }
211
+
212
+ .promote-tool .promote-primary {
213
+ color: #fffaf0;
214
+ background: var(--promote-accent);
215
+ border-color: var(--promote-accent);
216
+ }
217
+
218
+ .promote-fieldset {
219
+ margin: 0;
220
+ padding: 0.7rem;
221
+ border: 1px solid var(--promote-line);
222
+ border-radius: 12px;
223
+ }
224
+
225
+ .promote-fieldset label {
226
+ display: grid;
227
+ gap: 0.28rem;
228
+ color: var(--promote-muted);
229
+ font-size: 0.72rem;
230
+ font-weight: 700;
231
+ }
232
+
233
+ .promote-fieldset input[type='file'] {
234
+ width: 100%;
235
+ font-size: 0.68rem;
236
+ }
237
+
238
+ .promote-fieldset label.promote-layer {
239
+ display: grid;
240
+ grid-template-columns: 1fr 90px;
241
+ align-items: center;
242
+ gap: 0.5rem;
243
+ letter-spacing: 0;
244
+ }
245
+
246
+ .promote-layer span {
247
+ min-width: 0;
248
+ overflow: hidden;
249
+ text-overflow: ellipsis;
250
+ white-space: nowrap;
251
+ }
252
+
253
+ .promote-layer input[type='range'] {
254
+ accent-color: var(--promote-accent);
255
+ }
256
+
257
+ .promote-actions {
258
+ display: grid;
259
+ grid-template-columns: 1fr 1fr;
260
+ gap: 0.5rem;
261
+ }
262
+
263
+ .promote-stage {
264
+ display: grid;
265
+ grid-template-rows: auto minmax(0, 1fr);
266
+ gap: 0.65rem;
267
+ min-height: 0;
268
+ }
269
+
270
+ .promote-stage-meta {
271
+ display: flex;
272
+ justify-content: space-between;
273
+ color: var(--promote-muted);
274
+ font-size: 0.72rem;
275
+ font-weight: 800;
276
+ letter-spacing: 0.04em;
277
+ text-transform: uppercase;
278
+ }
279
+
280
+ .promote-canvas-wrap {
281
+ position: relative;
282
+ display: grid;
283
+ min-height: 0;
284
+ place-items: center;
285
+ padding: clamp(0.5rem, 3vw, 2rem);
286
+ overflow: hidden;
287
+ background: rgba(9, 20, 38, 0.15);
288
+ border: 1px solid var(--promote-line);
289
+ border-radius: 18px;
290
+ }
291
+
292
+ .promote-canvas-wrap canvas {
293
+ position: relative;
294
+ z-index: 2;
295
+ display: block;
296
+ width: min(100%, 1000px);
297
+ height: auto;
298
+ max-height: 100%;
299
+ object-fit: contain;
300
+ border-radius: 4px;
301
+ box-shadow: 0 24px 50px rgba(9, 20, 38, 0.25);
302
+ cursor: grab;
303
+ touch-action: none;
304
+ }
305
+
306
+ .promote-canvas-wrap canvas:active {
307
+ cursor: grabbing;
308
+ }
309
+
310
+ @media (max-width: 850px) {
311
+ .promote-tool {
312
+ grid-template-columns: 1fr;
313
+ }
314
+
315
+ .promote-sidebar {
316
+ order: 2;
317
+ }
318
+
319
+ .promote-stage {
320
+ min-height: 50vh;
321
+ }
322
+ }
@@ -0,0 +1,15 @@
1
+ ---
2
+ import { SEORenderer } from '@jjlmoya/utils-shared';
3
+ import { promoteThisWebsite } from './index';
4
+ import type { KnownLocale } from '../../types';
5
+
6
+ interface Props {
7
+ locale?: KnownLocale;
8
+ }
9
+
10
+ const { locale = 'en' } = Astro.props;
11
+ const content = await promoteThisWebsite.i18n[locale]?.();
12
+ if (!content) return null;
13
+ ---
14
+
15
+ {content.seo.length > 0 && <SEORenderer content={{ locale, sections: content.seo }} />}
@@ -0,0 +1,28 @@
1
+ import type { CompositionState } from './logic';
2
+
3
+ const STORAGE_KEY = 'promote-this-website-state-v2';
4
+
5
+ export function readState(): Partial<CompositionState> | null {
6
+ try {
7
+ const raw = window.localStorage.getItem(STORAGE_KEY);
8
+ return raw ? JSON.parse(raw) as Partial<CompositionState> : null;
9
+ } catch {
10
+ return null;
11
+ }
12
+ }
13
+
14
+ export function writeState(state: CompositionState): void {
15
+ try {
16
+ window.localStorage.setItem(STORAGE_KEY, JSON.stringify(state));
17
+ } catch {
18
+ return;
19
+ }
20
+ }
21
+
22
+ export function clearState(): void {
23
+ try {
24
+ window.localStorage.removeItem(STORAGE_KEY);
25
+ } catch {
26
+ return;
27
+ }
28
+ }
@@ -0,0 +1,206 @@
1
+ import { clamp, type CompositionState, type LayerPosition, type TitleStyle } from './logic';
2
+
3
+ interface TitlePalette {
4
+ fill: string;
5
+ text: string;
6
+ accent: string;
7
+ }
8
+
9
+ const palettes: Record<TitleStyle, TitlePalette> = {
10
+ paper: { fill: '#f7ebd7', text: '#08182b', accent: '#c45a2f' },
11
+ ribbon: { fill: '#c45a2f', text: '#fffaf0', accent: '#f7ebd7' },
12
+ ink: { fill: '#172a3c', text: '#f7ebd7', accent: '#11d6c4' },
13
+ poster: { fill: '#071226', text: '#fffaf0', accent: '#11d6c4' },
14
+ ticket: { fill: '#f1dfc4', text: '#08182b', accent: '#577b86' },
15
+ marker: { fill: '#f4f6fb', text: '#08182b', accent: '#11a99d' },
16
+ split: { fill: '#08182b', text: '#fffaf0', accent: '#11d6c4' },
17
+ capsule: { fill: '#fffaf0', text: '#08182b', accent: '#c45a2f' },
18
+ corner: { fill: '#10283b', text: '#fffaf0', accent: '#f0b45b' },
19
+ vertical: { fill: '#172a3c', text: '#fffaf0', accent: '#c45a2f' },
20
+ };
21
+
22
+ function roundedRect(context: CanvasRenderingContext2D, position: LayerPosition, radius: number): void {
23
+ const r = Math.min(radius, position.width / 2, position.height / 2);
24
+ context.beginPath();
25
+ context.roundRect(position.x, position.y, position.width, position.height, r);
26
+ }
27
+
28
+ function wrapLines(context: CanvasRenderingContext2D, text: string, maxWidth: number): string[] {
29
+ const words = text.trim().split(/\s+/).filter(Boolean);
30
+ const lines: string[] = [];
31
+ let current = '';
32
+ words.forEach((word) => {
33
+ const candidate = current ? `${current} ${word}` : word;
34
+ if (current && context.measureText(candidate).width > maxWidth) {
35
+ lines.push(current);
36
+ current = word;
37
+ } else current = candidate;
38
+ });
39
+ if (current) lines.push(current);
40
+ return lines.slice(0, 3);
41
+ }
42
+
43
+ function drawPaper(context: CanvasRenderingContext2D, palette: TitlePalette, position: LayerPosition): void {
44
+ roundedRect(context, position, 16);
45
+ context.fill();
46
+ context.stroke();
47
+ context.fillStyle = palette.accent;
48
+ context.fillRect(position.x + position.width * 0.09, position.y + position.height * 0.78, position.width * 0.24, 6);
49
+ }
50
+
51
+ function drawRibbon(context: CanvasRenderingContext2D, position: LayerPosition): void {
52
+ context.beginPath();
53
+ context.moveTo(position.x + 28, position.y);
54
+ context.lineTo(position.x + position.width - 28, position.y);
55
+ context.lineTo(position.x + position.width, position.y + position.height / 2);
56
+ context.lineTo(position.x + position.width - 28, position.y + position.height);
57
+ context.lineTo(position.x + 28, position.y + position.height);
58
+ context.lineTo(position.x, position.y + position.height / 2);
59
+ context.closePath();
60
+ context.fill();
61
+ context.stroke();
62
+ }
63
+
64
+ function drawInk(context: CanvasRenderingContext2D, position: LayerPosition): void {
65
+ context.save();
66
+ context.translate(position.x + position.width / 2, position.y + position.height / 2);
67
+ context.rotate(-0.025);
68
+ const width = position.width;
69
+ const height = position.height;
70
+ context.beginPath();
71
+ context.moveTo(-width * 0.48, -height * 0.05);
72
+ context.bezierCurveTo(-width * 0.43, -height * 0.46, -width * 0.12, -height * 0.58, width * 0.25, -height * 0.45);
73
+ context.bezierCurveTo(width * 0.54, -height * 0.36, width * 0.55, height * 0.08, width * 0.32, height * 0.34);
74
+ context.bezierCurveTo(width * 0.04, height * 0.62, -width * 0.36, height * 0.46, -width * 0.48, -height * 0.05);
75
+ context.fill();
76
+ context.stroke();
77
+ context.fillStyle = '#11d6c4';
78
+ context.beginPath();
79
+ context.arc(width * 0.34, height * 0.34, Math.max(4, height * 0.08), 0, Math.PI * 2);
80
+ context.fill();
81
+ context.restore();
82
+ }
83
+
84
+ function drawPoster(context: CanvasRenderingContext2D, position: LayerPosition): void {
85
+ context.fillRect(position.x, position.y, position.width, position.height);
86
+ context.strokeRect(position.x, position.y, position.width, position.height);
87
+ }
88
+
89
+ function drawTicket(context: CanvasRenderingContext2D, position: LayerPosition): void {
90
+ roundedRect(context, position, 20);
91
+ context.fill();
92
+ context.stroke();
93
+ context.save();
94
+ context.globalCompositeOperation = 'destination-out';
95
+ context.beginPath();
96
+ context.arc(position.x, position.y + position.height / 2, Math.min(14, position.height * 0.22), 0, Math.PI * 2);
97
+ context.arc(position.x + position.width, position.y + position.height / 2, Math.min(14, position.height * 0.22), 0, Math.PI * 2);
98
+ context.fill();
99
+ context.restore();
100
+ context.fillStyle = '#577b86';
101
+ context.fillRect(position.x, position.y + position.height * 0.15, 8, position.height * 0.7);
102
+ context.setLineDash([6, 10]);
103
+ context.beginPath();
104
+ context.moveTo(position.x + position.width * 0.78, position.y + 12);
105
+ context.lineTo(position.x + position.width * 0.78, position.y + position.height - 12);
106
+ context.stroke();
107
+ context.setLineDash([]);
108
+ }
109
+
110
+ function drawMarker(context: CanvasRenderingContext2D, palette: TitlePalette, position: LayerPosition): void {
111
+ roundedRect(context, position, 14);
112
+ context.fill();
113
+ context.stroke();
114
+ context.fillStyle = palette.accent;
115
+ context.fillRect(position.x + position.width * 0.08, position.y + position.height * 0.78, position.width * 0.38, 7);
116
+ }
117
+
118
+ function drawSplit(context: CanvasRenderingContext2D, palette: TitlePalette, position: LayerPosition): void {
119
+ roundedRect(context, position, 8);
120
+ context.fillStyle = palette.fill;
121
+ context.fill();
122
+ context.save();
123
+ context.beginPath();
124
+ context.rect(position.x + position.width * 0.58, position.y, position.width * 0.42, position.height);
125
+ context.clip();
126
+ context.fillStyle = palette.accent;
127
+ context.fillRect(position.x + position.width * 0.58, position.y, position.width * 0.42, position.height);
128
+ context.restore();
129
+ context.stroke();
130
+ }
131
+
132
+ function drawCapsule(context: CanvasRenderingContext2D, position: LayerPosition): void {
133
+ roundedRect(context, position, position.height / 2);
134
+ context.fill();
135
+ context.stroke();
136
+ }
137
+
138
+ function drawCorner(context: CanvasRenderingContext2D, palette: TitlePalette, position: LayerPosition): void {
139
+ context.fillRect(position.x, position.y, position.width, position.height);
140
+ context.fillStyle = palette.accent;
141
+ context.fillRect(position.x, position.y + position.height - 8, position.width * 0.3, 8);
142
+ }
143
+
144
+ function drawVertical(context: CanvasRenderingContext2D, palette: TitlePalette, position: LayerPosition): void {
145
+ context.fillRect(position.x, position.y, position.width, position.height);
146
+ context.fillStyle = palette.accent;
147
+ context.fillRect(position.x + position.width - 10, position.y + 12, 4, position.height - 24);
148
+ context.beginPath();
149
+ context.arc(position.x + position.width - 8, position.y + 8, 3, 0, Math.PI * 2);
150
+ context.fill();
151
+ }
152
+
153
+ function drawShape(context: CanvasRenderingContext2D, style: TitleStyle, palette: TitlePalette, position: LayerPosition): void {
154
+ const drawers: Record<TitleStyle, () => void> = {
155
+ paper: () => drawPaper(context, palette, position), ribbon: () => drawRibbon(context, position), ink: () => drawInk(context, position), poster: () => drawPoster(context, position), ticket: () => drawTicket(context, position), marker: () => drawMarker(context, palette, position), split: () => drawSplit(context, palette, position), capsule: () => drawCapsule(context, position), corner: () => drawCorner(context, palette, position), vertical: () => drawVertical(context, palette, position),
156
+ };
157
+ drawers[style]();
158
+ }
159
+
160
+ function drawTitleText(context: CanvasRenderingContext2D, state: CompositionState, palette: TitlePalette, position: LayerPosition): void {
161
+ const fontSize = clamp(position.height * 0.34 * state.titleFontSize, 12, 74);
162
+ const textTop = state.titleStyle === 'marker' ? 0.24 : 0.18;
163
+ context.font = `800 ${fontSize}px Georgia, serif`;
164
+ context.textAlign = 'left';
165
+ context.textBaseline = 'top';
166
+ const lines = wrapLines(context, state.title, position.width * 0.82);
167
+ lines.forEach((line, index) => {
168
+ const y = position.y + position.height * textTop + index * fontSize * 1.05;
169
+ if (state.titleStyle !== 'split') {
170
+ context.fillStyle = palette.text;
171
+ context.fillText(line, position.x + position.width * 0.09, y);
172
+ return;
173
+ }
174
+ context.save();
175
+ context.beginPath();
176
+ context.rect(position.x, position.y, position.width * 0.58, position.height);
177
+ context.clip();
178
+ context.fillStyle = palette.text;
179
+ context.fillText(line, position.x + position.width * 0.09, y);
180
+ context.restore();
181
+ context.save();
182
+ context.beginPath();
183
+ context.rect(position.x + position.width * 0.58, position.y, position.width * 0.42, position.height);
184
+ context.clip();
185
+ context.fillStyle = '#fffaf0';
186
+ context.fillText(line, position.x + position.width * 0.09, y);
187
+ context.restore();
188
+ });
189
+ }
190
+
191
+ export function drawTitle(context: CanvasRenderingContext2D, state: CompositionState): void {
192
+ if (!state.title.trim()) return;
193
+ const position = state.positions.title;
194
+ const palette = palettes[state.titleStyle];
195
+ context.save();
196
+ context.shadowColor = 'rgba(4, 11, 24, 0.25)';
197
+ context.shadowBlur = 22;
198
+ context.shadowOffsetY = 10;
199
+ context.fillStyle = palette.fill;
200
+ context.strokeStyle = palette.accent;
201
+ context.lineWidth = 3;
202
+ drawShape(context, state.titleStyle, palette, position);
203
+ context.shadowColor = 'transparent';
204
+ drawTitleText(context, state, palette, position);
205
+ context.restore();
206
+ }
@@ -0,0 +1,59 @@
1
+ export interface PromoteThisWebsiteUI extends Record<string, string> {
2
+ urlLabel: string;
3
+ urlPlaceholder: string;
4
+ applyUrl: string;
5
+ formatLabel: string;
6
+ panoramic: string;
7
+ instagram: string;
8
+ square: string;
9
+ story: string;
10
+ titleLabel: string;
11
+ titlePlaceholder: string;
12
+ titleSizeLabel: string;
13
+ titleBoxSizeLabel: string;
14
+ titleStyleLabel: string;
15
+ brandLabel: string;
16
+ brandStyleLabel: string;
17
+ advancedLabel: string;
18
+ assetsLabel: string;
19
+ backgroundLabel: string;
20
+ toolLabel: string;
21
+ logoLabel: string;
22
+ mascotLabel: string;
23
+ layersLabel: string;
24
+ backgroundLayer: string;
25
+ toolLayer: string;
26
+ logoLayer: string;
27
+ mascotLayer: string;
28
+ titleLayer: string;
29
+ reset: string;
30
+ download: string;
31
+ activeLayer: string;
32
+ canvasHint: string;
33
+ pasted: string;
34
+ urlApplied: string;
35
+ urlLoading: string;
36
+ urlFailed: string;
37
+ fileLoaded: string;
38
+ titlePaper: string;
39
+ titleRibbon: string;
40
+ titleInk: string;
41
+ titlePoster: string;
42
+ titleTicket: string;
43
+ titleMarker: string;
44
+ titleSplit: string;
45
+ titleCapsule: string;
46
+ titleCorner: string;
47
+ titleVertical: string;
48
+ brandPlain: string;
49
+ brandPlaque: string;
50
+ brandTicket: string;
51
+ brandStamp: string;
52
+ brandNeon: string;
53
+ brandRibbon: string;
54
+ brandCorner: string;
55
+ brandPixel: string;
56
+ brandHalo: string;
57
+ brandEditorial: string;
58
+ defaultTool: string;
59
+ }
@@ -1,14 +1,6 @@
1
1
  ---
2
2
  import { Bibliography as SharedBibliography } from '@jjlmoya/utils-shared';
3
- import { promptLibrary } from './index';
4
- import type { KnownLocale } from '../../types';
5
-
6
- interface Props {
7
- locale?: KnownLocale;
8
- }
9
-
10
- const { locale = 'es' } = Astro.props;
11
- const content = await promptLibrary.i18n[locale]?.();
3
+ import { bibliography } from './bibliography';
12
4
  ---
13
5
 
14
- {content && <SharedBibliography links={content.bibliography} />}
6
+ <SharedBibliography links={bibliography} />
@@ -0,0 +1,6 @@
1
+ import type { BibliographyEntry } from '../../types';
2
+
3
+ export const bibliography: BibliographyEntry[] = [
4
+ { name: 'Prompt Engineering Guide (DAIR.AI)', url: 'https://www.promptingguide.ai/techniques' },
5
+ { name: 'What is prompt engineering (Google Cloud)', url: 'https://cloud.google.com/discover/what-is-prompt-engineering' },
6
+ ];
@@ -1,3 +1,4 @@
1
+ import { bibliography } from '../bibliography';
1
2
  import type { WithContext, FAQPage, HowToThing, SoftwareApplication } from 'schema-dts';
2
3
  import type { ToolLocaleContent } from '../../../types';
3
4
  import type { PromptLibraryUI } from '../ui';
@@ -95,10 +96,7 @@ export const content: ToolLocaleContent<PromptLibraryUI> = {
95
96
  faqTitle: 'Häufig gestellte Fragen',
96
97
  faq: faqData,
97
98
  bibliographyTitle: 'Referenzen zum Prompt Engineering',
98
- bibliography: [
99
- { name: 'Prompt Engineering Guide (DAIR.AI)', url: 'https://www.promptingguide.ai/' },
100
- { name: 'Was ist Prompt Engineering (Google Cloud)', url: 'https://cloud.google.com/discover/what-is-prompt-engineering' },
101
- ],
99
+ bibliography,
102
100
  howTo: howToData,
103
101
  schemas: [faqSchema, howToSchema, appSchema],
104
102
  seo: [
@@ -1,3 +1,4 @@
1
+ import { bibliography } from '../bibliography';
1
2
  import type { WithContext, FAQPage, HowToThing, SoftwareApplication } from 'schema-dts';
2
3
  import type { ToolLocaleContent } from '../../../types';
3
4
  import type { PromptLibraryUI } from '../ui';
@@ -95,10 +96,7 @@ export const content: ToolLocaleContent<PromptLibraryUI> = {
95
96
  faqTitle: 'Frequently Asked Questions',
96
97
  faq: faqData,
97
98
  bibliographyTitle: 'Prompt Engineering References',
98
- bibliography: [
99
- { name: 'Prompt Engineering Guide (DAIR.AI)', url: 'https://www.promptingguide.ai/' },
100
- { name: 'What is prompt engineering (Google Cloud)', url: 'https://cloud.google.com/discover/what-is-prompt-engineering' },
101
- ],
99
+ bibliography,
102
100
  howTo: howToData,
103
101
  schemas: [faqSchema, howToSchema, appSchema],
104
102
  seo: [