@jjlmoya/utils-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.
- package/package.json +64 -0
- package/src/category/i18n/en.ts +97 -0
- package/src/category/i18n/es.ts +97 -0
- package/src/category/i18n/fr.ts +96 -0
- package/src/category/index.ts +17 -0
- package/src/category/seo.astro +15 -0
- package/src/components/PreviewNavSidebar.astro +116 -0
- package/src/components/PreviewToolbar.astro +143 -0
- package/src/data.ts +11 -0
- package/src/env.d.ts +5 -0
- package/src/index.ts +24 -0
- package/src/layouts/PreviewLayout.astro +117 -0
- package/src/pages/[locale]/[slug].astro +146 -0
- package/src/pages/[locale].astro +251 -0
- package/src/pages/index.astro +4 -0
- package/src/tests/faq_count.test.ts +19 -0
- package/src/tests/locale_completeness.test.ts +42 -0
- package/src/tests/mocks/astro_mock.js +2 -0
- package/src/tests/no_h1_in_components.test.ts +48 -0
- package/src/tests/seo_length.test.ts +22 -0
- package/src/tests/tool_validation.test.ts +17 -0
- package/src/tool/asteroid-impact/AsteroidImpact.css +799 -0
- package/src/tool/asteroid-impact/bibliography.astro +14 -0
- package/src/tool/asteroid-impact/component.astro +436 -0
- package/src/tool/asteroid-impact/constants.ts +67 -0
- package/src/tool/asteroid-impact/helpers.ts +17 -0
- package/src/tool/asteroid-impact/i18n/en.ts +153 -0
- package/src/tool/asteroid-impact/i18n/es.ts +153 -0
- package/src/tool/asteroid-impact/i18n/fr.ts +153 -0
- package/src/tool/asteroid-impact/index.ts +24 -0
- package/src/tool/asteroid-impact/logic/impactPhysics.ts +86 -0
- package/src/tool/asteroid-impact/script.ts +256 -0
- package/src/tool/asteroid-impact/seo.astro +15 -0
- package/src/tool/asteroid-impact/ui-helpers.ts +56 -0
- package/src/tool/asteroid-impact/ui.ts +69 -0
- package/src/tool/asteroid-impact/utils.ts +17 -0
- package/src/tool/cellular-renewal/CellularRenewal.css +1 -0
- package/src/tool/cellular-renewal/bibliography.astro +14 -0
- package/src/tool/cellular-renewal/component.astro +387 -0
- package/src/tool/cellular-renewal/i18n/en.ts +170 -0
- package/src/tool/cellular-renewal/i18n/es.ts +170 -0
- package/src/tool/cellular-renewal/i18n/fr.ts +170 -0
- package/src/tool/cellular-renewal/index.ts +24 -0
- package/src/tool/cellular-renewal/logic/CellularRenewalEngine.ts +50 -0
- package/src/tool/cellular-renewal/seo.astro +14 -0
- package/src/tool/colony-counter/ColonyCounter.css +473 -0
- package/src/tool/colony-counter/bibliography.astro +14 -0
- package/src/tool/colony-counter/component.astro +358 -0
- package/src/tool/colony-counter/i18n/en.ts +151 -0
- package/src/tool/colony-counter/i18n/es.ts +151 -0
- package/src/tool/colony-counter/i18n/fr.ts +151 -0
- package/src/tool/colony-counter/index.ts +27 -0
- package/src/tool/colony-counter/seo.astro +15 -0
- package/src/tool/microwave-detector/MicrowaveDetector.css +122 -0
- package/src/tool/microwave-detector/bibliography.astro +14 -0
- package/src/tool/microwave-detector/component.astro +650 -0
- package/src/tool/microwave-detector/i18n/en.ts +155 -0
- package/src/tool/microwave-detector/i18n/es.ts +155 -0
- package/src/tool/microwave-detector/i18n/fr.ts +155 -0
- package/src/tool/microwave-detector/index.ts +24 -0
- package/src/tool/microwave-detector/logic/MicrowaveEngine.ts +89 -0
- package/src/tool/microwave-detector/seo.astro +14 -0
- package/src/tool/simulation-probability/SimulationProbability.css +1 -0
- package/src/tool/simulation-probability/bibliography.astro +14 -0
- package/src/tool/simulation-probability/component.astro +348 -0
- package/src/tool/simulation-probability/i18n/en.ts +184 -0
- package/src/tool/simulation-probability/i18n/es.ts +184 -0
- package/src/tool/simulation-probability/i18n/fr.ts +184 -0
- package/src/tool/simulation-probability/index.ts +24 -0
- package/src/tool/simulation-probability/logic/SimulationEngine.ts +42 -0
- package/src/tool/simulation-probability/seo.astro +14 -0
- package/src/tools.ts +15 -0
- package/src/types.ts +72 -0
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
import type { ToolLocaleContent } from '../../../types';
|
|
2
|
+
|
|
3
|
+
const slug = 'compteur-colonies';
|
|
4
|
+
const title = 'Compteur de Colonies: Outil Numérique de Comptage CFU pour Boîtes de Pétri';
|
|
5
|
+
const description = 'Outil numérique pour compter les colonies bactériennes sur boîtes de Pétri. Différenciez les types, évitez les erreurs et calculez l\'UFC avec précision.';
|
|
6
|
+
|
|
7
|
+
export const content: ToolLocaleContent = {
|
|
8
|
+
slug,
|
|
9
|
+
title,
|
|
10
|
+
description,
|
|
11
|
+
faqTitle: 'Questions Fréquemment Posées',
|
|
12
|
+
bibliographyTitle: 'Références Bibliographiques',
|
|
13
|
+
ui: {
|
|
14
|
+
uploadTitle: 'Cliquez pour télécharger votre boîte de Pétri',
|
|
15
|
+
uploadSubtitle: 'Téléchargez une photo de votre boîte et commencez à compter les colonies',
|
|
16
|
+
currentModeLabel: 'Mode Actuel',
|
|
17
|
+
typeA: 'Type A',
|
|
18
|
+
typeB: 'Type B',
|
|
19
|
+
colonyType: 'Type de Colonie',
|
|
20
|
+
counting: 'Comptage',
|
|
21
|
+
totalCFU: 'Total UFC',
|
|
22
|
+
undo: 'Annuler le dernier',
|
|
23
|
+
clearAll: 'Effacer Tout',
|
|
24
|
+
infoClick: 'Cliquez sur la plaque pour marquer les colonies',
|
|
25
|
+
infoChange: 'Changez de type avant de marquer',
|
|
26
|
+
confirmClear: 'Êtes-vous sûr de vouloir effacer toutes les colonies marquées ?',
|
|
27
|
+
},
|
|
28
|
+
seo: [
|
|
29
|
+
{
|
|
30
|
+
type: 'title',
|
|
31
|
+
text: 'Microbiologie Numérique: Comptage Précis des Colonies',
|
|
32
|
+
level: 2,
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
type: 'paragraph',
|
|
36
|
+
html: 'Le comptage des colonies bactériennes sur boîtes de Pétri est une technique fondamentale en microbiologie. Traditionnellement effectué avec un compteur manuel et un marqueur, il est facile de perdre le compte ou de marquer deux fois la même colonie. Cet outil numérique élimine ces erreurs et permet une différenciation visuelle entre les types de colonies.',
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
type: 'title',
|
|
40
|
+
text: 'Pourquoi le Comptage des Colonies est Important',
|
|
41
|
+
level: 3,
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
type: 'paragraph',
|
|
45
|
+
html: 'Le nombre de colonies sur une boîte est directement proportionnel à la concentration de micro-organismes viables dans l\'échantillon d\'origine. Ces données sont critiques pour:',
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
type: 'list',
|
|
49
|
+
items: [
|
|
50
|
+
'<strong>Contrôle de la Qualité Alimentaire:</strong> Détecter la contamination bactérienne.',
|
|
51
|
+
'<strong>Recherche Pharmaceutique:</strong> Évaluer l\'efficacité des antibiotiques.',
|
|
52
|
+
'<strong>Diagnostic Clinique:</strong> Quantifier les infections dans les échantillons de patients.',
|
|
53
|
+
'<strong>Biotechnologie:</strong> Optimiser les cultures de production de protéines recombinantes.',
|
|
54
|
+
],
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
type: 'title',
|
|
58
|
+
text: 'Unités Formant Colonies (UFC)',
|
|
59
|
+
level: 3,
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
type: 'paragraph',
|
|
63
|
+
html: 'Chaque colonie visible sur une boîte est supposée provenir d\'une seule cellule viable. C\'est pourquoi elles sont appelées <strong>UFC</strong> (Unités Formant Colonies) ou <strong>CFU</strong> en anglais (Colony Forming Units).',
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
type: 'paragraph',
|
|
67
|
+
html: '<strong>Formule de Concentration:</strong><br><code>UFC/mL = (Colonies Comptées × Facteur de Dilution) / Volume Ensemencé</code>',
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
type: 'title',
|
|
71
|
+
text: 'Bonnes Pratiques de Comptage',
|
|
72
|
+
level: 3,
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
type: 'title',
|
|
76
|
+
text: 'Plage Comptable',
|
|
77
|
+
level: 4,
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
type: 'paragraph',
|
|
81
|
+
html: 'La plage idéale pour un comptage manuel est de <strong>30 à 300 colonies</strong> par boîte. En dessous de 30, l\'erreur statistique est trop élevée. Au-dessus de 300, les colonies commencent à fusionner et la distinction individuelle devient impossible.',
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
type: 'title',
|
|
85
|
+
text: 'Types de Colonies',
|
|
86
|
+
level: 4,
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
type: 'paragraph',
|
|
90
|
+
html: 'Sur des milieux sélectifs ou différentiels, il est courant de voir plusieurs morphologies de colonies:',
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
type: 'list',
|
|
94
|
+
items: [
|
|
95
|
+
'<strong>Type A (Bleu-Vert):</strong> Grandes colonies mucoïdes, typiques des bactéries Gram négatives fermentant le lactose.',
|
|
96
|
+
'<strong>Type B (Rose/Violet):</strong> Petites colonies translucides, non-fermentantes.',
|
|
97
|
+
],
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
type: 'paragraph',
|
|
101
|
+
html: 'Notre outil permet de différencier jusqu\'à deux types de colonies avec des couleurs distinctes, facilitant le comptage différentiel sans besoin de marqueurs physiques.',
|
|
102
|
+
},
|
|
103
|
+
],
|
|
104
|
+
faq: [
|
|
105
|
+
{
|
|
106
|
+
question: 'Qu\'est-ce que le comptage UFC?',
|
|
107
|
+
answer: 'Les Unités Formant Colonies (UFC) est une mesure qui estime le nombre de cellules bactériennes ou fongiques viables dans un échantillon. On suppose que chaque colonie visible provient d\'une seule cellule ou d\'un groupe de cellules.',
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
question: 'Pourquoi un compteur numérique est-il mieux qu\'un comptage manuel?',
|
|
111
|
+
answer: 'Le comptage numérique évite l\'erreur humaine de "perdre le compte" lors du marquage visuel des colonies. Notre outil permet également de différencier les types de colonies par couleurs, facilitant l\'analyse des boîtes mixtes.',
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
question: 'Comment les UFC par millilitre sont-elles calculées?',
|
|
115
|
+
answer: 'Le nombre de colonies comptées est multiplié par le facteur de dilution inversé. Par exemple, si vous comptez 30 colonies dans une dilution 1:100, l\'échantillon original contient 3000 UFC/ml.',
|
|
116
|
+
},
|
|
117
|
+
{
|
|
118
|
+
question: 'Quand une boîte est-elle considérée comme "non comptable"?',
|
|
119
|
+
answer: 'En microbiologie standard, s\'il y a plus de 250-300 colonies, la boîte est considérée comme trop peuplée (Trop Nombreuses à Compter, TNTC) et les données ne sont pas fiables en raison de la concurrence entre colonies.',
|
|
120
|
+
},
|
|
121
|
+
],
|
|
122
|
+
bibliography: [
|
|
123
|
+
{
|
|
124
|
+
name: 'FDA - Bacteriological Analytical Manual',
|
|
125
|
+
url: 'https://www.fda.gov/food/laboratory-methods-food/bacteriological-analytical-manual-bam',
|
|
126
|
+
},
|
|
127
|
+
{
|
|
128
|
+
name: 'ISO 4833 - Technique de Comptage des Colonies',
|
|
129
|
+
url: 'https://www.iso.org/standard/53728.html',
|
|
130
|
+
},
|
|
131
|
+
],
|
|
132
|
+
howTo: [
|
|
133
|
+
{
|
|
134
|
+
name: 'Préparer l\'image de la boîte',
|
|
135
|
+
text: 'Placez votre boîte de Pétri sur un fond sombre ou utilisez un rétro-illuminateur pour que les colonies contrastent clairement.',
|
|
136
|
+
},
|
|
137
|
+
{
|
|
138
|
+
name: 'Identifier les types de colonies',
|
|
139
|
+
text: 'Utilisez différentes couleurs de marqueur pour grouper les colonies selon leur morphologie, couleur ou taille.',
|
|
140
|
+
},
|
|
141
|
+
{
|
|
142
|
+
name: 'Marquer chaque colonie',
|
|
143
|
+
text: 'Cliquez sur chaque colonie visible. L\'outil numérotera automatiquement chaque clic pour éviter les répétitions ou les colonies oubliées.',
|
|
144
|
+
},
|
|
145
|
+
{
|
|
146
|
+
name: 'Calculer la concentration finale',
|
|
147
|
+
text: 'Entrez le volume ensemencé et le facteur de dilution pour obtenir le résultat final en UFC/ml ou UFC/g.',
|
|
148
|
+
},
|
|
149
|
+
],
|
|
150
|
+
schemas: [],
|
|
151
|
+
};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { ScienceToolEntry, ToolDefinition, ToolLocaleContent } from '../../types';
|
|
2
|
+
import ColonyCounterComponent from './component.astro';
|
|
3
|
+
import ColonyCounterSEO from './seo.astro';
|
|
4
|
+
import ColonyCounterBibliography from './bibliography.astro';
|
|
5
|
+
|
|
6
|
+
export interface ColonyCounterUI {
|
|
7
|
+
[key: string]: string;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export type ColonyCounterLocaleContent = ToolLocaleContent<ColonyCounterUI>;
|
|
11
|
+
|
|
12
|
+
export const colonyCounter: ScienceToolEntry<ColonyCounterUI> = {
|
|
13
|
+
id: 'colony-counter',
|
|
14
|
+
icons: { bg: 'mdi:microscope', fg: 'mdi:circle-multiple' },
|
|
15
|
+
i18n: {
|
|
16
|
+
es: () => import('./i18n/es').then((m) => m.content),
|
|
17
|
+
en: () => import('./i18n/en').then((m) => m.content),
|
|
18
|
+
fr: () => import('./i18n/fr').then((m) => m.content),
|
|
19
|
+
},
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export const COLONY_COUNTER_TOOL: ToolDefinition = {
|
|
23
|
+
entry: colonyCounter,
|
|
24
|
+
Component: ColonyCounterComponent,
|
|
25
|
+
SEOComponent: ColonyCounterSEO,
|
|
26
|
+
BibliographyComponent: ColonyCounterBibliography,
|
|
27
|
+
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
---
|
|
2
|
+
import { SEORenderer } from '@jjlmoya/utils-shared';
|
|
3
|
+
import { colonyCounter } 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 colonyCounter.i18n[locale]?.();
|
|
12
|
+
if (!content) return null;
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
<SEORenderer content={{ sections: content.seo, locale }} />
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
:root {
|
|
2
|
+
--microwave-primary: #e11d48;
|
|
3
|
+
--microwave-text: #0f172a;
|
|
4
|
+
--microwave-text-muted: #64748b;
|
|
5
|
+
--microwave-bg: #fff;
|
|
6
|
+
--microwave-bg-secondary: #fafbfc;
|
|
7
|
+
--microwave-bg-tertiary: #f1f5f9;
|
|
8
|
+
--microwave-border: #e2e8f0;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
.theme-dark {
|
|
12
|
+
--microwave-text: #fff;
|
|
13
|
+
--microwave-text-muted: #94a3b8;
|
|
14
|
+
--microwave-bg: #000;
|
|
15
|
+
--microwave-bg-secondary: #0f172a;
|
|
16
|
+
--microwave-bg-tertiary: #1e293b;
|
|
17
|
+
--microwave-border: #1e293b;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
.microwave-app {
|
|
21
|
+
max-width: 900px;
|
|
22
|
+
margin: 0 auto;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
.microwave-card {
|
|
26
|
+
background: var(--microwave-bg);
|
|
27
|
+
border: 1px solid var(--microwave-border);
|
|
28
|
+
border-radius: 1.5rem;
|
|
29
|
+
padding: 2rem;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
.microwave-header {
|
|
33
|
+
display: flex;
|
|
34
|
+
justify-content: space-between;
|
|
35
|
+
align-items: center;
|
|
36
|
+
margin-bottom: 2rem;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
.microwave-title-group {
|
|
40
|
+
display: flex;
|
|
41
|
+
align-items: center;
|
|
42
|
+
gap: 1rem;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
.microwave-tool-name {
|
|
46
|
+
font-size: 1.5rem;
|
|
47
|
+
font-weight: 700;
|
|
48
|
+
margin: 0;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
.microwave-test-btn {
|
|
52
|
+
display: flex;
|
|
53
|
+
align-items: center;
|
|
54
|
+
gap: 0.5rem;
|
|
55
|
+
padding: 0.75rem 1.5rem;
|
|
56
|
+
background: var(--microwave-primary);
|
|
57
|
+
color: white;
|
|
58
|
+
border: none;
|
|
59
|
+
border-radius: 0.75rem;
|
|
60
|
+
cursor: pointer;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
.microwave-grid {
|
|
64
|
+
display: grid;
|
|
65
|
+
grid-template-columns: 1fr 1fr;
|
|
66
|
+
gap: 2rem;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
.microwave-chart-panel {
|
|
70
|
+
background: var(--microwave-bg-secondary);
|
|
71
|
+
border: 1px solid var(--microwave-border);
|
|
72
|
+
border-radius: 1rem;
|
|
73
|
+
padding: 1.5rem;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
.microwave-data-panel {
|
|
77
|
+
display: flex;
|
|
78
|
+
flex-direction: column;
|
|
79
|
+
gap: 1.5rem;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
.data-card {
|
|
83
|
+
background: var(--microwave-bg-secondary);
|
|
84
|
+
border: 1px solid var(--microwave-border);
|
|
85
|
+
border-radius: 0.75rem;
|
|
86
|
+
padding: 1rem;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
.probability-card {
|
|
90
|
+
background: var(--microwave-bg-secondary);
|
|
91
|
+
border: 1px solid var(--microwave-border);
|
|
92
|
+
border-radius: 0.75rem;
|
|
93
|
+
padding: 1.5rem;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
.prob-bar-bg {
|
|
97
|
+
width: 100%;
|
|
98
|
+
height: 8px;
|
|
99
|
+
background: var(--microwave-bg-tertiary);
|
|
100
|
+
border-radius: 4px;
|
|
101
|
+
overflow: hidden;
|
|
102
|
+
margin: 1rem 0;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
.prob-bar-fill {
|
|
106
|
+
height: 100%;
|
|
107
|
+
background: linear-gradient(90deg, #10b981 0%, #3b82f6 100%);
|
|
108
|
+
transition: width 0.3s ease;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
.stats-list {
|
|
112
|
+
display: flex;
|
|
113
|
+
flex-direction: column;
|
|
114
|
+
gap: 1rem;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
.stat-item {
|
|
118
|
+
display: flex;
|
|
119
|
+
justify-content: space-between;
|
|
120
|
+
padding: 0.75rem 0;
|
|
121
|
+
border-bottom: 1px solid var(--microwave-border);
|
|
122
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
---
|
|
2
|
+
import { Bibliography } from '@jjlmoya/utils-shared';
|
|
3
|
+
import { microwaveDetector } 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 microwaveDetector.i18n[locale]?.();
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
{content && <Bibliography links={content.bibliography} />}
|