@jjlmoya/utils-finance 1.23.0 → 1.24.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 (37) hide show
  1. package/package.json +2 -2
  2. package/src/category/index.ts +2 -1
  3. package/src/entries.ts +4 -1
  4. package/src/index.ts +1 -0
  5. package/src/tests/locale_completeness.test.ts +2 -2
  6. package/src/tests/tool_validation.test.ts +2 -2
  7. package/src/tool/revolvingCardCalculator/bibliography.astro +14 -0
  8. package/src/tool/revolvingCardCalculator/bibliography.ts +24 -0
  9. package/src/tool/revolvingCardCalculator/component.astro +315 -0
  10. package/src/tool/revolvingCardCalculator/components/AmortizationTable.astro +57 -0
  11. package/src/tool/revolvingCardCalculator/components/CalculatorInputs.astro +117 -0
  12. package/src/tool/revolvingCardCalculator/components/ChartDisplay.astro +35 -0
  13. package/src/tool/revolvingCardCalculator/components/UsuryChecker.astro +32 -0
  14. package/src/tool/revolvingCardCalculator/constants.ts +36 -0
  15. package/src/tool/revolvingCardCalculator/entry.ts +31 -0
  16. package/src/tool/revolvingCardCalculator/i18n/de.ts +84 -0
  17. package/src/tool/revolvingCardCalculator/i18n/en.ts +322 -0
  18. package/src/tool/revolvingCardCalculator/i18n/es.ts +153 -0
  19. package/src/tool/revolvingCardCalculator/i18n/fr.ts +84 -0
  20. package/src/tool/revolvingCardCalculator/i18n/id.ts +84 -0
  21. package/src/tool/revolvingCardCalculator/i18n/it.ts +84 -0
  22. package/src/tool/revolvingCardCalculator/i18n/ja.ts +84 -0
  23. package/src/tool/revolvingCardCalculator/i18n/ko.ts +84 -0
  24. package/src/tool/revolvingCardCalculator/i18n/nl.ts +84 -0
  25. package/src/tool/revolvingCardCalculator/i18n/pl.ts +84 -0
  26. package/src/tool/revolvingCardCalculator/i18n/pt.ts +84 -0
  27. package/src/tool/revolvingCardCalculator/i18n/ru.ts +84 -0
  28. package/src/tool/revolvingCardCalculator/i18n/sv.ts +84 -0
  29. package/src/tool/revolvingCardCalculator/i18n/tr.ts +84 -0
  30. package/src/tool/revolvingCardCalculator/i18n/zh.ts +84 -0
  31. package/src/tool/revolvingCardCalculator/index.ts +10 -0
  32. package/src/tool/revolvingCardCalculator/logic.ts +237 -0
  33. package/src/tool/revolvingCardCalculator/revolving-card-calculator.css +564 -0
  34. package/src/tool/revolvingCardCalculator/seo.astro +15 -0
  35. package/src/tool/revolvingCardCalculator/types.ts +54 -0
  36. package/src/tool/revolvingCardCalculator/ui.ts +58 -0
  37. package/src/tools.ts +2 -1
@@ -0,0 +1,564 @@
1
+ :root {
2
+ --rc-bg-card: #fff;
3
+ --rc-border-card: #e5e7eb;
4
+ --rc-text-primary: #1f2937;
5
+ --rc-text-secondary: #6b7280;
6
+ --rc-bg-input: #fff;
7
+ --rc-border-input: #d1d5db;
8
+ --rc-text-input: #1f2937;
9
+ --rc-focus-border: #2563eb;
10
+ --rc-focus-ring: rgba(37, 99, 235, 0.15);
11
+ --rc-unit-color: #2563eb;
12
+ --rc-btn-primary: #2563eb;
13
+ --rc-btn-primary-hover: #1d4ed8;
14
+ --rc-btn-text: #fff;
15
+ --rc-btn-secondary: #f3f4f6;
16
+ --rc-btn-secondary-hover: #e5e7eb;
17
+ --rc-btn-secondary-text: #374151;
18
+ --rc-bg-success: #f0fdf4;
19
+ --rc-border-success: #bbf7d0;
20
+ --rc-text-success: #15803d;
21
+ --rc-bg-warning: #fffbeb;
22
+ --rc-border-warning: #fde68a;
23
+ --rc-text-warning: #b45309;
24
+ --rc-bg-error: #fef2f2;
25
+ --rc-border-error: #fca5a5;
26
+ --rc-text-error: #b91c1c;
27
+ --rc-bg-summary: #f9fafb;
28
+ --rc-border-summary: #e5e7eb;
29
+ --rc-gradient-start: #eff6ff;
30
+ --rc-gradient-end: #dbeafe;
31
+ --rc-gradient-text: #1e3a8a;
32
+ --rc-gradient-border: #bfdbfe;
33
+ --rc-chart-principal: #3b82f6;
34
+ --rc-chart-interest: #ef4444;
35
+ }
36
+
37
+ .theme-dark, [data-theme='dark'] {
38
+ --rc-bg-card: #1f2937;
39
+ --rc-border-card: #374151;
40
+ --rc-text-primary: #f3f4f6;
41
+ --rc-text-secondary: #9ca3af;
42
+ --rc-bg-input: #111827;
43
+ --rc-border-input: #4b5563;
44
+ --rc-text-input: #f3f4f6;
45
+ --rc-focus-border: #60a5fa;
46
+ --rc-focus-ring: rgba(96, 165, 250, 0.2);
47
+ --rc-unit-color: #60a5fa;
48
+ --rc-btn-primary: #3b82f6;
49
+ --rc-btn-primary-hover: #60a5fa;
50
+ --rc-btn-text: #111827;
51
+ --rc-btn-secondary: #374151;
52
+ --rc-btn-secondary-hover: #4b5563;
53
+ --rc-btn-secondary-text: #f3f4f6;
54
+ --rc-bg-success: #064e3b;
55
+ --rc-border-success: #047857;
56
+ --rc-text-success: #a7f3d0;
57
+ --rc-bg-warning: #78350f;
58
+ --rc-border-warning: #b45309;
59
+ --rc-text-warning: #fde68a;
60
+ --rc-bg-error: #7f1d1d;
61
+ --rc-border-error: #b91c1c;
62
+ --rc-text-error: #fca5a5;
63
+ --rc-bg-summary: #111827;
64
+ --rc-border-summary: #374151;
65
+ --rc-gradient-start: #1e3a8a;
66
+ --rc-gradient-end: #1e40af;
67
+ --rc-gradient-text: #93c5fd;
68
+ --rc-gradient-border: #3b82f6;
69
+ --rc-chart-principal: #3b82f6;
70
+ --rc-chart-interest: #ef4444;
71
+ }
72
+
73
+ @media (prefers-color-scheme: dark) {
74
+ :root {
75
+ --rc-bg-card: #1f2937;
76
+ --rc-border-card: #374151;
77
+ --rc-text-primary: #f3f4f6;
78
+ --rc-text-secondary: #9ca3af;
79
+ --rc-bg-input: #111827;
80
+ --rc-border-input: #4b5563;
81
+ --rc-text-input: #f3f4f6;
82
+ --rc-focus-border: #60a5fa;
83
+ --rc-focus-ring: rgba(96, 165, 250, 0.2);
84
+ --rc-unit-color: #60a5fa;
85
+ --rc-btn-primary: #3b82f6;
86
+ --rc-btn-primary-hover: #60a5fa;
87
+ --rc-btn-text: #111827;
88
+ --rc-btn-secondary: #374151;
89
+ --rc-btn-secondary-hover: #4b5563;
90
+ --rc-btn-secondary-text: #f3f4f6;
91
+ --rc-bg-success: #064e3b;
92
+ --rc-border-success: #047857;
93
+ --rc-text-success: #a7f3d0;
94
+ --rc-bg-warning: #78350f;
95
+ --rc-border-warning: #b45309;
96
+ --rc-text-warning: #fde68a;
97
+ --rc-bg-error: #7f1d1d;
98
+ --rc-border-error: #b91c1c;
99
+ --rc-text-error: #fca5a5;
100
+ --rc-bg-summary: #111827;
101
+ --rc-border-summary: #374151;
102
+ --rc-gradient-start: #1e3a8a;
103
+ --rc-gradient-end: #1e40af;
104
+ --rc-gradient-text: #93c5fd;
105
+ --rc-gradient-border: #3b82f6;
106
+ --rc-chart-principal: #3b82f6;
107
+ --rc-chart-interest: #ef4444;
108
+ }
109
+ }
110
+
111
+ .rev-container {
112
+ display: flex;
113
+ justify-content: center;
114
+ width: 100%;
115
+ padding: 1.5rem 1rem;
116
+ }
117
+
118
+ .rev-card {
119
+ background: var(--rc-bg-card);
120
+ border: 1px solid var(--rc-border-card);
121
+ border-radius: 16px;
122
+ padding: 2rem;
123
+ width: 100%;
124
+ max-width: 800px;
125
+ color: var(--rc-text-primary);
126
+ box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.05), 0 2px 4px -1px rgba(0, 0, 0, 0.03);
127
+ }
128
+
129
+ .rev-inputs-grid {
130
+ display: grid;
131
+ grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
132
+ gap: 1.25rem;
133
+ margin-bottom: 2rem;
134
+ }
135
+
136
+ .rev-input-group {
137
+ display: flex;
138
+ flex-direction: column;
139
+ }
140
+
141
+ .rev-input-group label {
142
+ font-weight: 600;
143
+ margin-bottom: 0.5rem;
144
+ font-size: 0.85rem;
145
+ color: var(--rc-text-primary);
146
+ }
147
+
148
+ .rev-input-wrapper,
149
+ .rev-select-wrapper {
150
+ position: relative;
151
+ display: flex;
152
+ align-items: center;
153
+ }
154
+
155
+ .rev-input-wrapper input,
156
+ .rev-select-wrapper select {
157
+ width: 100%;
158
+ padding: 0.75rem 1rem;
159
+ border: 1px solid var(--rc-border-input);
160
+ border-radius: 8px;
161
+ font-size: 0.95rem;
162
+ background: var(--rc-bg-input);
163
+ color: var(--rc-text-input);
164
+ outline: none;
165
+ transition: all 0.15s ease;
166
+ }
167
+
168
+ .theme-dark .rev-input-wrapper input,
169
+ .theme-dark .rev-select-wrapper select,
170
+ [data-theme='dark'] .rev-input-wrapper input,
171
+ [data-theme='dark'] .rev-select-wrapper select {
172
+ color-scheme: dark;
173
+ }
174
+
175
+ .rev-input-wrapper input:focus,
176
+ .rev-select-wrapper select:focus {
177
+ border-color: var(--rc-focus-border);
178
+ box-shadow: 0 0 0 3px var(--rc-focus-ring);
179
+ }
180
+
181
+ .rev-select-wrapper select {
182
+ padding-right: 2.5rem;
183
+ appearance: none;
184
+ background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath fill='%236b7280' d='M1 1l5 5 5-5'/%3E%3C/svg%3E");
185
+ background-repeat: no-repeat;
186
+ background-position: right 0.75rem center;
187
+ background-size: 12px 8px;
188
+ }
189
+
190
+ .rev-input-unit {
191
+ position: absolute;
192
+ right: 1rem;
193
+ font-weight: 600;
194
+ color: var(--rc-unit-color);
195
+ font-size: 0.9rem;
196
+ pointer-events: none;
197
+ }
198
+
199
+ .rev-usury-card {
200
+ background: var(--rc-bg-summary);
201
+ border: 1px solid var(--rc-border-summary);
202
+ border-radius: 12px;
203
+ padding: 1.5rem;
204
+ margin-bottom: 2rem;
205
+ }
206
+
207
+ .rev-usury-title {
208
+ font-size: 1.1rem;
209
+ font-weight: 700;
210
+ margin-top: 0;
211
+ margin-bottom: 1rem;
212
+ }
213
+
214
+ .rev-usury-status-container {
215
+ display: flex;
216
+ align-items: flex-start;
217
+ gap: 1rem;
218
+ padding: 1rem;
219
+ border-radius: 8px;
220
+ border: 1px solid transparent;
221
+ margin-bottom: 1.25rem;
222
+ transition: all 0.2s ease;
223
+ }
224
+
225
+ .rev-usury-status-container.safe {
226
+ background: var(--rc-bg-success);
227
+ border-color: var(--rc-border-success);
228
+ color: var(--rc-text-success);
229
+ }
230
+
231
+ .rev-usury-status-container.warning {
232
+ background: var(--rc-bg-warning);
233
+ border-color: var(--rc-border-warning);
234
+ color: var(--rc-text-warning);
235
+ }
236
+
237
+ .rev-usury-status-container.usurious {
238
+ background: var(--rc-bg-error);
239
+ border-color: var(--rc-border-error);
240
+ color: var(--rc-text-error);
241
+ }
242
+
243
+ .rev-status-icon-box {
244
+ width: 24px;
245
+ height: 24px;
246
+ flex-shrink: 0;
247
+ }
248
+
249
+ .rev-status-text {
250
+ font-size: 1rem;
251
+ font-weight: 700;
252
+ margin: 0 0 0.25rem;
253
+ }
254
+
255
+ .rev-status-description {
256
+ font-size: 0.85rem;
257
+ margin: 0;
258
+ line-height: 1.4;
259
+ color: inherit;
260
+ }
261
+
262
+ .rev-usury-stats {
263
+ display: grid;
264
+ grid-template-columns: 1fr 1fr;
265
+ gap: 1rem;
266
+ }
267
+
268
+ .rev-usury-stat-item {
269
+ display: flex;
270
+ flex-direction: column;
271
+ background: var(--rc-bg-card);
272
+ border: 1px solid var(--rc-border-card);
273
+ padding: 0.75rem 1rem;
274
+ border-radius: 8px;
275
+ }
276
+
277
+ .rev-usury-stat-label {
278
+ font-size: 0.75rem;
279
+ color: var(--rc-text-secondary);
280
+ margin-bottom: 0.25rem;
281
+ font-weight: 500;
282
+ }
283
+
284
+ .rev-usury-stat-value {
285
+ font-size: 1.2rem;
286
+ font-weight: 700;
287
+ color: var(--rc-text-primary);
288
+ }
289
+
290
+ .rev-summary-grid {
291
+ display: grid;
292
+ grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
293
+ gap: 1rem;
294
+ margin-bottom: 1.5rem;
295
+ }
296
+
297
+ .rev-summary-card {
298
+ background: var(--rc-bg-summary);
299
+ border: 1px solid var(--rc-border-summary);
300
+ border-radius: 12px;
301
+ padding: 1.25rem;
302
+ text-align: center;
303
+ display: flex;
304
+ flex-direction: column;
305
+ justify-content: center;
306
+ min-height: 100px;
307
+ }
308
+
309
+ .rev-summary-card.primary-gradient {
310
+ background: linear-gradient(135deg, var(--rc-gradient-start), var(--rc-gradient-end));
311
+ border-color: var(--rc-gradient-border);
312
+ color: var(--rc-gradient-text);
313
+ }
314
+
315
+ .rev-summary-card.primary-gradient .rev-summary-label {
316
+ color: var(--rc-gradient-text);
317
+ opacity: 0.85;
318
+ }
319
+
320
+ .rev-summary-card.primary-gradient .rev-summary-value {
321
+ color: var(--rc-gradient-text);
322
+ }
323
+
324
+ .rev-summary-label {
325
+ font-size: 0.8rem;
326
+ font-weight: 600;
327
+ color: var(--rc-text-secondary);
328
+ margin-bottom: 0.5rem;
329
+ }
330
+
331
+ .rev-summary-value {
332
+ font-size: 1.75rem;
333
+ font-weight: 800;
334
+ color: var(--rc-text-primary);
335
+ }
336
+
337
+ .rev-summary-subvalue {
338
+ font-size: 0.85rem;
339
+ color: var(--rc-text-secondary);
340
+ margin-top: 0.25rem;
341
+ }
342
+
343
+ .rev-alert-box {
344
+ display: flex;
345
+ align-items: center;
346
+ gap: 0.75rem;
347
+ padding: 1rem;
348
+ border-radius: 8px;
349
+ margin-bottom: 1.5rem;
350
+ border: 1px solid transparent;
351
+ }
352
+
353
+ .rev-alert-box.error {
354
+ background: var(--rc-bg-error);
355
+ border-color: var(--rc-border-error);
356
+ color: var(--rc-text-error);
357
+ }
358
+
359
+ .rev-alert-content {
360
+ font-size: 0.85rem;
361
+ font-weight: 600;
362
+ line-height: 1.4;
363
+ }
364
+
365
+ .rev-chart-container {
366
+ background: var(--rc-bg-summary);
367
+ border: 1px solid var(--rc-border-summary);
368
+ border-radius: 12px;
369
+ padding: 1.5rem;
370
+ margin-bottom: 2rem;
371
+ }
372
+
373
+ .rev-chart-header {
374
+ margin-bottom: 1.25rem;
375
+ }
376
+
377
+ .rev-chart-title {
378
+ font-size: 1rem;
379
+ font-weight: 700;
380
+ margin: 0;
381
+ }
382
+
383
+ .rev-breakdown-bar-wrapper {
384
+ margin-bottom: 1.5rem;
385
+ }
386
+
387
+ .rev-bar-labels {
388
+ display: flex;
389
+ justify-content: space-between;
390
+ font-size: 0.75rem;
391
+ font-weight: 600;
392
+ color: var(--rc-text-secondary);
393
+ margin-bottom: 0.5rem;
394
+ }
395
+
396
+ .rev-breakdown-bar {
397
+ display: flex;
398
+ height: 24px;
399
+ border-radius: 12px;
400
+ overflow: hidden;
401
+ background: var(--rc-border-card);
402
+ }
403
+
404
+ .rev-bar-segment {
405
+ display: flex;
406
+ align-items: center;
407
+ justify-content: center;
408
+ height: 100%;
409
+ color: #fff;
410
+ font-weight: 700;
411
+ font-size: 0.75rem;
412
+ transition: width 0.4s ease;
413
+ }
414
+
415
+ .rev-bar-segment.principal {
416
+ background: var(--rc-chart-principal);
417
+ }
418
+
419
+ .rev-bar-segment.interest {
420
+ background: var(--rc-chart-interest);
421
+ }
422
+
423
+ .rev-timeline-visual {
424
+ position: relative;
425
+ height: 48px;
426
+ display: flex;
427
+ align-items: center;
428
+ background: var(--rc-bg-card);
429
+ border: 1px solid var(--rc-border-card);
430
+ border-radius: 8px;
431
+ overflow: hidden;
432
+ padding: 0 1rem;
433
+ }
434
+
435
+ .rev-timeline-track {
436
+ display: flex;
437
+ width: 100%;
438
+ height: 12px;
439
+ background: #e5e7eb;
440
+ border-radius: 6px;
441
+ overflow: hidden;
442
+ position: relative;
443
+ }
444
+
445
+ .rev-timeline-fill {
446
+ height: 100%;
447
+ background: var(--rc-chart-principal);
448
+ transition: width 0.4s ease;
449
+ }
450
+
451
+ .rev-table-actions {
452
+ display: flex;
453
+ justify-content: center;
454
+ margin-bottom: 1.5rem;
455
+ }
456
+
457
+ .rev-table-container {
458
+ overflow-x: auto;
459
+ border: 1px solid var(--rc-border-card);
460
+ border-radius: 8px;
461
+ max-height: 350px;
462
+ overflow-y: auto;
463
+ }
464
+
465
+ .rev-table {
466
+ width: 100%;
467
+ border-collapse: collapse;
468
+ font-size: 0.85rem;
469
+ text-align: right;
470
+ }
471
+
472
+ .rev-table th {
473
+ position: sticky;
474
+ top: 0;
475
+ background: var(--rc-bg-summary);
476
+ color: var(--rc-text-primary);
477
+ font-weight: 700;
478
+ padding: 0.75rem 1rem;
479
+ border-bottom: 2px solid var(--rc-border-card);
480
+ }
481
+
482
+ .rev-table td {
483
+ padding: 0.75rem 1rem;
484
+ border-bottom: 1px solid var(--rc-border-card);
485
+ color: var(--rc-text-secondary);
486
+ }
487
+
488
+ .rev-table tbody tr:hover td {
489
+ background: var(--rc-bg-summary);
490
+ color: var(--rc-text-primary);
491
+ }
492
+
493
+ .rev-table th:first-child,
494
+ .rev-table td:first-child {
495
+ text-align: center;
496
+ }
497
+
498
+ .action-row {
499
+ display: flex;
500
+ gap: 1rem;
501
+ margin-top: 1.5rem;
502
+ }
503
+
504
+ .rev-btn-primary {
505
+ flex: 1;
506
+ padding: 0.75rem 1.5rem;
507
+ background: var(--rc-btn-primary);
508
+ color: var(--rc-btn-text);
509
+ border: none;
510
+ border-radius: 8px;
511
+ font-weight: 600;
512
+ cursor: pointer;
513
+ transition: all 0.2s;
514
+ }
515
+
516
+ .rev-btn-primary:hover {
517
+ background: var(--rc-btn-primary-hover);
518
+ transform: translateY(-1px);
519
+ }
520
+
521
+ .rev-btn-secondary {
522
+ padding: 0.6rem 1.25rem;
523
+ background: var(--rc-btn-secondary);
524
+ color: var(--rc-btn-secondary-text);
525
+ border: 1px solid var(--rc-border-card);
526
+ border-radius: 8px;
527
+ font-weight: 600;
528
+ cursor: pointer;
529
+ transition: all 0.2s;
530
+ }
531
+
532
+ .rev-btn-secondary:hover {
533
+ background: var(--rc-btn-secondary-hover);
534
+ }
535
+
536
+ .fade-in {
537
+ animation: rev-fade-in 0.4s ease-out;
538
+ }
539
+
540
+ @keyframes rev-fade-in {
541
+ from {
542
+ opacity: 0;
543
+ transform: translateY(10px);
544
+ }
545
+ to {
546
+ opacity: 1;
547
+ transform: translateY(0);
548
+ }
549
+ }
550
+
551
+ @media (max-width: 640px) {
552
+ .rev-inputs-grid {
553
+ grid-template-columns: 1fr;
554
+ }
555
+ .rev-summary-grid {
556
+ grid-template-columns: 1fr;
557
+ }
558
+ .rev-usury-stats {
559
+ grid-template-columns: 1fr;
560
+ }
561
+ .rev-card {
562
+ padding: 1.25rem;
563
+ }
564
+ }
@@ -0,0 +1,15 @@
1
+ ---
2
+ import { SEORenderer } from '@jjlmoya/utils-shared';
3
+ import { revolvingCardCalculator } 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 revolvingCardCalculator.i18n[locale]?.();
12
+ if (!content) return null;
13
+ ---
14
+
15
+ {content.seo?.length > 0 && <SEORenderer content={{ locale, sections: content.seo }} />}
@@ -0,0 +1,54 @@
1
+ export type RevolvingMarket =
2
+ | 'es'
3
+ | 'us'
4
+ | 'uk'
5
+ | 'eu'
6
+ | 'jp'
7
+ | 'kr'
8
+ | 'cn'
9
+ | 'br'
10
+ | 'mx'
11
+ | 'pl'
12
+ | 'id'
13
+ | 'tr'
14
+ | 'ru'
15
+ | 'se'
16
+ | 'au'
17
+ | 'ca'
18
+ | 'custom';
19
+
20
+ export interface RevolvingInputs {
21
+ balance: number;
22
+ creditLimit: number;
23
+ apr: number;
24
+ paymentType: 'fixed' | 'percentage';
25
+ paymentValue: number;
26
+ minPaymentValue: number;
27
+ market: RevolvingMarket;
28
+ customThreshold?: number;
29
+ }
30
+
31
+ export interface AmortizationRow {
32
+ month: number;
33
+ initialBalance: number;
34
+ interestPaid: number;
35
+ principalPaid: number;
36
+ payment: number;
37
+ finalBalance: number;
38
+ }
39
+
40
+ export interface AmortizationResult {
41
+ schedule: AmortizationRow[];
42
+ totalInterest: number;
43
+ totalPaid: number;
44
+ monthsToPay: number;
45
+ isInfinite: boolean;
46
+ }
47
+
48
+ export interface UsuryAnalysis {
49
+ status: 'safe' | 'warning' | 'usurious';
50
+ marketName: string;
51
+ referenceRate: number;
52
+ thresholdRate: number;
53
+ details: string;
54
+ }
@@ -0,0 +1,58 @@
1
+ export interface RevolvingCardCalculatorUI extends Record<string, unknown> {
2
+ title: string;
3
+ balanceLabel: string;
4
+ creditLimitLabel: string;
5
+ aprLabel: string;
6
+ paymentTypeLabel: string;
7
+ paymentTypeFixed: string;
8
+ paymentTypePercentage: string;
9
+ paymentValueLabel: string;
10
+ minPaymentValueLabel: string;
11
+ currencyLabel: string;
12
+ marketLabel: string;
13
+ marketES: string;
14
+ marketUS: string;
15
+ marketUK: string;
16
+ marketEU: string;
17
+ marketJP: string;
18
+ marketKR: string;
19
+ marketCN: string;
20
+ marketBR: string;
21
+ marketMX: string;
22
+ marketPL: string;
23
+ marketID: string;
24
+ marketTR: string;
25
+ marketRU: string;
26
+ marketSE: string;
27
+ marketAU: string;
28
+ marketCA: string;
29
+ marketCustom: string;
30
+ customThresholdLabel: string;
31
+
32
+ resultsTitle: string;
33
+ totalInterestLabel: string;
34
+ totalPaidLabel: string;
35
+ monthsToPayLabel: string;
36
+ infiniteDebtWarning: string;
37
+ payoffYearsLabel: string;
38
+
39
+ usuryTitle: string;
40
+ usurySafeStatus: string;
41
+ usuryWarningStatus: string;
42
+ usuryUsuriousStatus: string;
43
+ usuryReferenceLabel: string;
44
+ usuryThresholdLabel: string;
45
+
46
+ tableTitle: string;
47
+ tableHeaderMonth: string;
48
+ tableHeaderInitial: string;
49
+ tableHeaderInterest: string;
50
+ tableHeaderPrincipal: string;
51
+ tableHeaderPayment: string;
52
+ tableHeaderFinal: string;
53
+
54
+ copyTooltip: string;
55
+ copiedLabel: string;
56
+ currencySymbol: string;
57
+ percentSymbol: string;
58
+ }
package/src/tools.ts CHANGED
@@ -14,7 +14,8 @@ import { COURT_FEE_CALCULATOR_TOOL } from './tool/courtFeeCalculator';
14
14
  import { LEGAL_INTEREST_RATE_TOOL } from './tool/legalInterestRate';
15
15
  import { FIRE_CALCULATOR_TOOL } from './tool/fireCalculator';
16
16
  import { DEBT_SNOWBALL_TOOL } from './tool/debtSnowball';
17
+ import { REVOLVING_CARD_CALCULATOR_TOOL } from './tool/revolvingCardCalculator';
17
18
 
18
- export const ALL_TOOLS: ToolDefinition[] = [COMPOUND_INTEREST_TOOL, FINANCIAL_FREEDOM_TOOL, PROFITABILITY_TOOL, MORTGAGE_TOOL, INFLATION_TOOL, PERCENTAGE_CALCULATOR_TOOL, LATE_INTEREST_TOOL, IBAN_BIC_SWIFT_TOOL, RENT_INCREASE_TOOL, LOTTERY_OPTIMIZER_TOOL, COURT_FEE_CALCULATOR_TOOL, LEGAL_INTEREST_RATE_TOOL, FIRE_CALCULATOR_TOOL, DEBT_SNOWBALL_TOOL];
19
+ export const ALL_TOOLS: ToolDefinition[] = [COMPOUND_INTEREST_TOOL, FINANCIAL_FREEDOM_TOOL, PROFITABILITY_TOOL, MORTGAGE_TOOL, INFLATION_TOOL, PERCENTAGE_CALCULATOR_TOOL, LATE_INTEREST_TOOL, IBAN_BIC_SWIFT_TOOL, RENT_INCREASE_TOOL, LOTTERY_OPTIMIZER_TOOL, COURT_FEE_CALCULATOR_TOOL, LEGAL_INTEREST_RATE_TOOL, FIRE_CALCULATOR_TOOL, DEBT_SNOWBALL_TOOL, REVOLVING_CARD_CALCULATOR_TOOL];
19
20
 
20
21