@jjlmoya/utils-tools 1.8.0 → 1.10.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 (52) hide show
  1. package/package.json +7 -4
  2. package/scripts/postinstall.mjs +27 -0
  3. package/src/entries.ts +26 -0
  4. package/src/tool/date-diff-calculator/component.astro +0 -200
  5. package/src/tool/date-diff-calculator/date-difference-calculator.css +198 -0
  6. package/src/tool/date-diff-calculator/entry.ts +24 -0
  7. package/src/tool/date-diff-calculator/index.ts +2 -25
  8. package/src/tool/drive-direct-link/component.astro +0 -173
  9. package/src/tool/drive-direct-link/entry.ts +24 -0
  10. package/src/tool/drive-direct-link/google-drive-direct-download-link.css +171 -0
  11. package/src/tool/drive-direct-link/index.ts +2 -25
  12. package/src/tool/email-list-cleaner/component.astro +0 -204
  13. package/src/tool/email-list-cleaner/email-list-cleaner.css +202 -0
  14. package/src/tool/email-list-cleaner/entry.ts +24 -0
  15. package/src/tool/email-list-cleaner/index.ts +2 -25
  16. package/src/tool/env-badge-spain/component.astro +0 -156
  17. package/src/tool/env-badge-spain/entry.ts +24 -0
  18. package/src/tool/env-badge-spain/environmental-badge-simulator-spain.css +154 -0
  19. package/src/tool/env-badge-spain/index.ts +2 -25
  20. package/src/tool/morse-beacon/component.astro +0 -298
  21. package/src/tool/morse-beacon/entry.ts +24 -0
  22. package/src/tool/morse-beacon/index.ts +2 -25
  23. package/src/tool/morse-beacon/morse-beacon.css +296 -0
  24. package/src/tool/password-generator/component.astro +0 -88
  25. package/src/tool/password-generator/entry.ts +24 -0
  26. package/src/tool/password-generator/index.ts +2 -25
  27. package/src/tool/password-generator/password-generator.css +86 -0
  28. package/src/tool/routes/component.astro +0 -254
  29. package/src/tool/routes/entry.ts +24 -0
  30. package/src/tool/routes/index.ts +2 -25
  31. package/src/tool/routes/optimal-routes.css +252 -0
  32. package/src/tool/rule-of-three/component.astro +0 -249
  33. package/src/tool/rule-of-three/entry.ts +24 -0
  34. package/src/tool/rule-of-three/index.ts +2 -25
  35. package/src/tool/rule-of-three/rule-of-three.css +247 -0
  36. package/src/tool/seo-content-optimizer/component.astro +0 -278
  37. package/src/tool/seo-content-optimizer/entry.ts +24 -0
  38. package/src/tool/seo-content-optimizer/index.ts +2 -25
  39. package/src/tool/seo-content-optimizer/seo-content-optimizer.css +276 -0
  40. package/src/tool/speed-reader/component.astro +0 -400
  41. package/src/tool/speed-reader/entry.ts +24 -0
  42. package/src/tool/speed-reader/index.ts +2 -25
  43. package/src/tool/speed-reader/speed-reader.css +398 -0
  44. package/src/tool/text-pixel-calculator/component.astro +0 -96
  45. package/src/tool/text-pixel-calculator/entry.ts +24 -0
  46. package/src/tool/text-pixel-calculator/index.ts +2 -25
  47. package/src/tool/text-pixel-calculator/text-pixel-width-calculator.css +94 -0
  48. package/src/tool/whatsapp-link/component.astro +0 -264
  49. package/src/tool/whatsapp-link/entry.ts +24 -0
  50. package/src/tool/whatsapp-link/index.ts +2 -25
  51. package/src/tool/whatsapp-link/whatsapp-link-generator.css +262 -0
  52. package/src/tools.ts +1 -1
@@ -0,0 +1,252 @@
1
+ .rut-root {
2
+ --rut-accent: #06b6d4;
3
+ --rut-accent-hover: #0891b2;
4
+ --rut-sidebar-bg: #f8fafc;
5
+ --rut-sidebar-border: #e2e8f0;
6
+ --rut-map-bg: #f1f5f9;
7
+ --rut-text-main: #1e293b;
8
+ --rut-text-muted: #64748b;
9
+ --rut-item-bg: #fff;
10
+ --rut-item-border: #f1f5f9;
11
+ --rut-item-hover-border: rgba(6, 182, 212, 0.5);
12
+ --rut-badge-bg: rgba(207, 250, 254, 1);
13
+ --rut-badge-border: #a5f3fc;
14
+ --rut-badge-text: #0e7490;
15
+ --rut-stats-bg: rgba(236, 254, 255, 1);
16
+ --rut-stats-border: #a5f3fc;
17
+ --rut-stats-label: #164e63;
18
+ --rut-stats-value: #0891b2;
19
+ --rut-btn-clear-bg: #fff;
20
+ --rut-btn-clear-text: #334155;
21
+ --rut-btn-clear-border: #e2e8f0;
22
+ --rut-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
23
+ }
24
+
25
+ :global(.theme-dark) .rut-root {
26
+ --rut-sidebar-bg: rgba(15, 23, 42, 0.5);
27
+ --rut-sidebar-border: #1e293b;
28
+ --rut-map-bg: #1e293b;
29
+ --rut-text-main: #f1f5f9;
30
+ --rut-text-muted: #94a3b8;
31
+ --rut-item-bg: #1e293b;
32
+ --rut-item-border: #334155;
33
+ --rut-badge-bg: rgba(8, 145, 178, 0.3);
34
+ --rut-badge-border: #164e63;
35
+ --rut-badge-text: #67e8f9;
36
+ --rut-stats-bg: rgba(8, 145, 178, 0.2);
37
+ --rut-stats-border: rgba(8, 145, 178, 0.3);
38
+ --rut-stats-label: #a5f3fc;
39
+ --rut-stats-value: #22d3ee;
40
+ --rut-btn-clear-bg: #1e293b;
41
+ --rut-btn-clear-text: #cbd5e1;
42
+ --rut-btn-clear-border: #334155;
43
+ --rut-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
44
+ }
45
+
46
+ .rut-layout {
47
+ display: flex;
48
+ flex-direction: column;
49
+ height: calc(100vh - 100px);
50
+ min-height: 500px;
51
+ max-height: 800px;
52
+ }
53
+
54
+ @media (min-width: 1024px) {
55
+ .rut-layout {
56
+ display: grid;
57
+ grid-template-columns: 320px 1fr;
58
+ flex-direction: unset;
59
+ }
60
+ }
61
+
62
+ .rut-sidebar {
63
+ display: flex;
64
+ flex-direction: column;
65
+ padding: 1.5rem;
66
+ background: var(--rut-sidebar-bg);
67
+ border-bottom: 1px solid var(--rut-sidebar-border);
68
+ overflow: hidden;
69
+ height: 50%;
70
+ }
71
+
72
+ @media (min-width: 1024px) {
73
+ .rut-sidebar {
74
+ height: 100%;
75
+ border-bottom: none;
76
+ border-right: 1px solid var(--rut-sidebar-border);
77
+ order: 1;
78
+ }
79
+ }
80
+
81
+ .rut-sidebar-header {
82
+ margin-bottom: 1.25rem;
83
+ }
84
+
85
+ .rut-sidebar-title {
86
+ font-size: 1.2rem;
87
+ font-weight: 700;
88
+ color: var(--rut-text-main);
89
+ margin: 0 0 0.375rem;
90
+ }
91
+
92
+ .rut-sidebar-desc {
93
+ font-size: 0.875rem;
94
+ color: var(--rut-text-muted);
95
+ margin: 0;
96
+ }
97
+
98
+ .rut-list-wrapper {
99
+ flex: 1;
100
+ overflow-y: auto;
101
+ min-height: 0;
102
+ margin-bottom: 1rem;
103
+ padding-right: 0.25rem;
104
+ }
105
+
106
+ .rut-list-wrapper::-webkit-scrollbar {
107
+ width: 6px;
108
+ }
109
+
110
+ .rut-list-wrapper::-webkit-scrollbar-track {
111
+ background: transparent;
112
+ }
113
+
114
+ .rut-list-wrapper::-webkit-scrollbar-thumb {
115
+ background-color: rgba(156, 163, 175, 0.5);
116
+ border-radius: 20px;
117
+ }
118
+
119
+ .rut-points-list {
120
+ list-style: none;
121
+ margin: 0;
122
+ padding: 0;
123
+ display: flex;
124
+ flex-direction: column;
125
+ gap: 0.5rem;
126
+ }
127
+
128
+ .rut-empty-state {
129
+ text-align: center;
130
+ padding: 2rem 1rem;
131
+ color: var(--rut-text-muted);
132
+ border: 2px dashed var(--rut-sidebar-border);
133
+ border-radius: 0.5rem;
134
+ font-size: 0.875rem;
135
+ }
136
+
137
+ .rut-actions {
138
+ margin-top: auto;
139
+ padding-top: 1rem;
140
+ border-top: 1px solid var(--rut-sidebar-border);
141
+ display: flex;
142
+ flex-direction: column;
143
+ gap: 0.75rem;
144
+ }
145
+
146
+ .rut-btn-primary {
147
+ width: 100%;
148
+ padding: 0.75rem 1rem;
149
+ background: var(--rut-accent-hover);
150
+ color: #fff;
151
+ border: none;
152
+ border-radius: 0.5rem;
153
+ font-size: 0.9rem;
154
+ font-weight: 600;
155
+ cursor: pointer;
156
+ display: flex;
157
+ align-items: center;
158
+ justify-content: center;
159
+ gap: 0.5rem;
160
+ transition: background 0.15s;
161
+ box-shadow: 0 4px 6px -1px rgba(8, 145, 178, 0.2);
162
+ }
163
+
164
+ .rut-btn-primary:hover:not(:disabled) {
165
+ background: var(--rut-accent);
166
+ }
167
+
168
+ .rut-btn-primary:disabled {
169
+ opacity: 0.5;
170
+ cursor: not-allowed;
171
+ }
172
+
173
+ .rut-btn-secondary {
174
+ width: 100%;
175
+ padding: 0.5rem 1rem;
176
+ background: var(--rut-btn-clear-bg);
177
+ color: var(--rut-btn-clear-text);
178
+ border: 1px solid var(--rut-btn-clear-border);
179
+ border-radius: 0.5rem;
180
+ font-size: 0.875rem;
181
+ font-weight: 500;
182
+ cursor: pointer;
183
+ transition: opacity 0.15s;
184
+ }
185
+
186
+ .rut-btn-secondary:hover {
187
+ opacity: 0.8;
188
+ }
189
+
190
+ .rut-btn-icon {
191
+ flex-shrink: 0;
192
+ }
193
+
194
+ .rut-icon-spin {
195
+ display: none;
196
+ animation: rut-spin 1s linear infinite;
197
+ }
198
+
199
+ @keyframes rut-spin {
200
+ to { transform: rotate(360deg); }
201
+ }
202
+
203
+ .rut-btn-primary[data-loading] .rut-icon-chart {
204
+ display: none;
205
+ }
206
+
207
+ .rut-btn-primary[data-loading] .rut-icon-spin {
208
+ display: block;
209
+ }
210
+
211
+ .rut-stats-panel {
212
+ margin-top: 1rem;
213
+ padding: 1rem;
214
+ background: var(--rut-stats-bg);
215
+ border: 1px solid var(--rut-stats-border);
216
+ border-radius: 0.5rem;
217
+ }
218
+
219
+ .rut-stats-label {
220
+ font-size: 0.875rem;
221
+ font-weight: 500;
222
+ color: var(--rut-stats-label);
223
+ }
224
+
225
+ .rut-stats-value {
226
+ font-size: 1.5rem;
227
+ font-weight: 700;
228
+ color: var(--rut-stats-value);
229
+ }
230
+
231
+ .rut-map-area {
232
+ position: relative;
233
+ height: 50%;
234
+ order: 0;
235
+ }
236
+
237
+ @media (min-width: 1024px) {
238
+ .rut-map-area {
239
+ height: 100%;
240
+ order: 2;
241
+ }
242
+ }
243
+
244
+ .rut-map {
245
+ width: 100%;
246
+ height: 100%;
247
+ background: var(--rut-map-bg);
248
+ }
249
+
250
+ :global(.rut-hidden) {
251
+ display: none;
252
+ }
@@ -74,255 +74,6 @@ const t = (ui ?? {}) as RuleOfThreeUI;
74
74
  </div>
75
75
  </div>
76
76
 
77
- <style>
78
- .rot-root {
79
- --rot-accent: #7c3aed;
80
- --rot-accent-light: #8b5cf6;
81
- --rot-purple: #9333ea;
82
- --rot-result: #2563eb;
83
- --rot-result-bg: #eff6ff;
84
- --rot-result-border: #bfdbfe;
85
- --rot-result-label: #2563eb;
86
- --rot-field-bg: #f8fafc;
87
- --rot-field-border: #e2e8f0;
88
- --rot-field-hover: #bfdbfe;
89
- --rot-field-hover-purple: #e9d5ff;
90
- --rot-card-bg: rgba(255, 255, 255, 0.8);
91
- --rot-card-border: rgba(255, 255, 255, 0.2);
92
- --rot-text-main: #334155;
93
- --rot-text-label: #64748b;
94
- --rot-text-hint: #94a3b8;
95
- --rot-formula-bg: #f1f5f9;
96
- --rot-formula-text: #64748b;
97
- --rot-sep-color: #cbd5e1;
98
- }
99
-
100
- :global(.theme-dark) .rot-root {
101
- --rot-result-bg: rgba(37, 99, 235, 0.2);
102
- --rot-result-border: rgba(37, 99, 235, 0.3);
103
- --rot-result-label: #60a5fa;
104
- --rot-result: #60a5fa;
105
- --rot-field-bg: rgba(30, 41, 59, 0.5);
106
- --rot-field-border: #334155;
107
- --rot-field-hover: rgba(37, 99, 235, 0.3);
108
- --rot-field-hover-purple: rgba(147, 51, 234, 0.3);
109
- --rot-card-bg: rgba(15, 23, 42, 0.8);
110
- --rot-card-border: rgba(51, 65, 85, 0.3);
111
- --rot-text-main: #e2e8f0;
112
- --rot-text-label: #94a3b8;
113
- --rot-text-hint: #64748b;
114
- --rot-formula-bg: #1e293b;
115
- --rot-formula-text: #94a3b8;
116
- --rot-sep-color: #475569;
117
- }
118
-
119
- .rot-card {
120
- width: 100%;
121
- max-width: 56rem;
122
- margin: 0 auto;
123
- background: var(--rot-card-bg);
124
- border: 1px solid var(--rot-card-border);
125
- border-radius: 1.5rem;
126
- box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.08);
127
- padding: 2rem;
128
- display: flex;
129
- flex-direction: column;
130
- gap: 3rem;
131
- }
132
-
133
- @media (min-width: 768px) {
134
- .rot-card { padding: 3rem; }
135
- }
136
-
137
- .rot-grid {
138
- display: flex;
139
- flex-direction: column;
140
- gap: 1.5rem;
141
- }
142
-
143
- .rot-row {
144
- display: grid;
145
- grid-template-columns: 1fr;
146
- gap: 1.5rem;
147
- align-items: center;
148
- }
149
-
150
- @media (min-width: 768px) {
151
- .rot-row { grid-template-columns: 1fr auto 1fr; }
152
- }
153
-
154
- .rot-field {
155
- background: var(--rot-field-bg);
156
- border: 2px solid var(--rot-field-border);
157
- border-radius: 1rem;
158
- padding: 1.5rem;
159
- transition: border-color 0.2s;
160
- }
161
-
162
- .rot-field:focus-within {
163
- border-color: var(--rot-field-hover);
164
- }
165
-
166
- .rot-field-result {
167
- background: var(--rot-result-bg);
168
- border-color: var(--rot-result-border);
169
- box-shadow: 0 10px 15px -3px rgba(37, 99, 235, 0.05);
170
- }
171
-
172
- .rot-label {
173
- display: block;
174
- font-size: 0.75rem;
175
- font-weight: 700;
176
- color: var(--rot-text-label);
177
- text-transform: uppercase;
178
- letter-spacing: 0.05em;
179
- margin-bottom: 0.5rem;
180
- }
181
-
182
- .rot-label-result {
183
- color: var(--rot-result-label);
184
- }
185
-
186
- .rot-input {
187
- width: 100%;
188
- text-align: center;
189
- font-size: 1.875rem;
190
- font-weight: 700;
191
- background: transparent;
192
- border: none;
193
- outline: none;
194
- color: var(--rot-text-main);
195
- }
196
-
197
- .rot-input::placeholder {
198
- color: var(--rot-text-hint);
199
- }
200
-
201
- .rot-input-purple:focus {
202
- color: var(--rot-purple);
203
- }
204
-
205
- .rot-input-result {
206
- font-size: 2.25rem;
207
- font-weight: 900;
208
- color: var(--rot-result);
209
- cursor: default;
210
- }
211
-
212
- .rot-input-result::placeholder {
213
- color: var(--rot-result-border);
214
- }
215
-
216
- input[type="number"]::-webkit-inner-spin-button,
217
- input[type="number"]::-webkit-outer-spin-button {
218
- -webkit-appearance: none;
219
- margin: 0;
220
- }
221
-
222
- input[type="number"] {
223
- -moz-appearance: textfield;
224
- }
225
-
226
- .rot-hint {
227
- font-size: 0.75rem;
228
- text-align: center;
229
- color: var(--rot-text-hint);
230
- margin-top: 0.5rem;
231
- }
232
-
233
- .rot-hint-result {
234
- color: rgba(37, 99, 235, 0.5);
235
- }
236
-
237
- .rot-result-row {
238
- position: relative;
239
- display: flex;
240
- align-items: center;
241
- }
242
-
243
- .rot-copy-btn {
244
- position: absolute;
245
- right: 0;
246
- top: 50%;
247
- transform: translateY(-50%);
248
- padding: 0.5rem;
249
- background: none;
250
- border: none;
251
- cursor: pointer;
252
- color: var(--rot-result);
253
- opacity: 0.5;
254
- transition: opacity 0.15s;
255
- }
256
-
257
- .rot-copy-btn:hover {
258
- opacity: 1;
259
- }
260
-
261
- .rot-separator {
262
- display: flex;
263
- align-items: center;
264
- justify-content: center;
265
- gap: 0.5rem;
266
- color: var(--rot-sep-color);
267
- padding: 0.5rem 0;
268
- }
269
-
270
- .rot-sep-line {
271
- height: 1px;
272
- width: 1rem;
273
- background: currentcolor;
274
- display: none;
275
- }
276
-
277
- @media (min-width: 768px) {
278
- .rot-sep-line { display: block; }
279
- }
280
-
281
- .rot-sep-text {
282
- font-size: 0.875rem;
283
- font-weight: 500;
284
- text-transform: uppercase;
285
- }
286
-
287
- .rot-formula {
288
- display: inline-block;
289
- padding: 0.75rem 1.5rem;
290
- background: var(--rot-formula-bg);
291
- border-radius: 0.75rem;
292
- font-size: 0.9rem;
293
- color: var(--rot-formula-text);
294
- text-align: center;
295
- width: 100%;
296
- }
297
-
298
- .rot-formula-a {
299
- font-weight: 700;
300
- color: var(--rot-text-main);
301
- }
302
-
303
- .rot-formula-b {
304
- font-weight: 700;
305
- color: var(--rot-text-main);
306
- }
307
-
308
- .rot-formula-c {
309
- font-weight: 700;
310
- color: var(--rot-purple);
311
- }
312
-
313
- .rot-formula-x {
314
- font-weight: 700;
315
- color: var(--rot-result);
316
- }
317
-
318
- @keyframes rot-pop {
319
- 0% { transform: scale(1); }
320
- 50% { transform: scale(1.05); }
321
- 100% { transform: scale(1); }
322
- }
323
-
324
- :global(.rot-pop) { animation: rot-pop 0.2s ease; }
325
- </style>
326
77
 
327
78
  <script>
328
79
  const valA = document.getElementById('rot-val-a') as HTMLInputElement;
@@ -0,0 +1,24 @@
1
+ import type { ToolsToolEntry } from '../../types';
2
+ import type { RuleOfThreeUI } from './ui';
3
+
4
+ export const ruleOfThree: ToolsToolEntry<RuleOfThreeUI> = {
5
+ id: 'rule-of-three',
6
+ icons: { bg: 'mdi:calculator-variant', fg: 'mdi:equal' },
7
+ i18n: {
8
+ de: () => import('./i18n/de').then((m) => m.content),
9
+ en: () => import('./i18n/en').then((m) => m.content),
10
+ es: () => import('./i18n/es').then((m) => m.content),
11
+ fr: () => import('./i18n/fr').then((m) => m.content),
12
+ id: () => import('./i18n/id').then((m) => m.content),
13
+ it: () => import('./i18n/it').then((m) => m.content),
14
+ ja: () => import('./i18n/ja').then((m) => m.content),
15
+ ko: () => import('./i18n/ko').then((m) => m.content),
16
+ nl: () => import('./i18n/nl').then((m) => m.content),
17
+ pl: () => import('./i18n/pl').then((m) => m.content),
18
+ pt: () => import('./i18n/pt').then((m) => m.content),
19
+ ru: () => import('./i18n/ru').then((m) => m.content),
20
+ sv: () => import('./i18n/sv').then((m) => m.content),
21
+ tr: () => import('./i18n/tr').then((m) => m.content),
22
+ zh: () => import('./i18n/zh').then((m) => m.content),
23
+ },
24
+ };
@@ -1,28 +1,5 @@
1
- import type { ToolDefinition, ToolsToolEntry } from '../../types';
2
- import type { RuleOfThreeUI } from './ui';
3
-
4
- export const ruleOfThree: ToolsToolEntry<RuleOfThreeUI> = {
5
- id: 'rule-of-three',
6
- icons: { bg: 'mdi:calculator-variant', fg: 'mdi:equal' },
7
- i18n: {
8
- de: () => import('./i18n/de').then((m) => m.content),
9
- en: () => import('./i18n/en').then((m) => m.content),
10
- es: () => import('./i18n/es').then((m) => m.content),
11
- fr: () => import('./i18n/fr').then((m) => m.content),
12
- id: () => import('./i18n/id').then((m) => m.content),
13
- it: () => import('./i18n/it').then((m) => m.content),
14
- ja: () => import('./i18n/ja').then((m) => m.content),
15
- ko: () => import('./i18n/ko').then((m) => m.content),
16
- nl: () => import('./i18n/nl').then((m) => m.content),
17
- pl: () => import('./i18n/pl').then((m) => m.content),
18
- pt: () => import('./i18n/pt').then((m) => m.content),
19
- ru: () => import('./i18n/ru').then((m) => m.content),
20
- sv: () => import('./i18n/sv').then((m) => m.content),
21
- tr: () => import('./i18n/tr').then((m) => m.content),
22
- zh: () => import('./i18n/zh').then((m) => m.content),
23
- },
24
- };
25
-
1
+ import { ruleOfThree } from './entry';
2
+ export * from './entry';
26
3
  export const RULE_OF_THREE_TOOL: ToolDefinition = {
27
4
  entry: ruleOfThree,
28
5
  Component: () => import('./component.astro'),