@silvestv/migration-planificator 3.0.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/LICENSE +96 -0
- package/README.fr.md +359 -0
- package/README.md +360 -0
- package/SECURITY.md +187 -0
- package/dist/client.bundle.js +357 -0
- package/dist/src/core/app-analyzer.js +134 -0
- package/dist/src/core/ast/matchers/html/html-attribute-matcher.js +86 -0
- package/dist/src/core/ast/matchers/html/html-component-matcher.js +40 -0
- package/dist/src/core/ast/matchers/html/html-element-matcher.js +54 -0
- package/dist/src/core/ast/matchers/html/html-parser.js +58 -0
- package/dist/src/core/ast/matchers/html/html-pipe-matcher.js +95 -0
- package/dist/src/core/ast/matchers/html/html-text-matcher.js +53 -0
- package/dist/src/core/ast/matchers/html/index.js +118 -0
- package/dist/src/core/ast/matchers/index.js +377 -0
- package/dist/src/core/ast/matchers/ts/collection-matcher.js +51 -0
- package/dist/src/core/ast/matchers/ts/context-matcher.js +275 -0
- package/dist/src/core/ast/matchers/ts/decorator-matcher.js +465 -0
- package/dist/src/core/ast/matchers/ts/expression-matcher.js +237 -0
- package/dist/src/core/ast/matchers/ts/file-matcher.js +97 -0
- package/dist/src/core/ast/matchers/ts/hierarchy-matcher.js +172 -0
- package/dist/src/core/ast/matchers/ts/import-matcher.js +39 -0
- package/dist/src/core/ast/matchers/ts/index.js +53 -0
- package/dist/src/core/ast/matchers/ts/node-matcher.js +156 -0
- package/dist/src/core/ast/matchers/ts/symbol-matcher.js +281 -0
- package/dist/src/core/ast/matchers/ts/type-matcher.js +207 -0
- package/dist/src/core/ast/matchers/utils/matcher-helpers.js +37 -0
- package/dist/src/core/ast/scanner-ast.js +444 -0
- package/dist/src/core/project-detector.js +196 -0
- package/dist/src/core/project-strategy/index.js +9 -0
- package/dist/src/core/project-strategy/nx-strategy.js +130 -0
- package/dist/src/core/project-strategy/project-strategy.interface.js +2 -0
- package/dist/src/core/project-strategy/standalone-strategy.js +74 -0
- package/dist/src/core/project-strategy/strategy-factory.js +15 -0
- package/dist/src/core/rules-loader.js +89 -0
- package/dist/src/core/scan-reporter.js +316 -0
- package/dist/src/core/scanner-delta.js +339 -0
- package/dist/src/core/scanner-orchestrator.js +266 -0
- package/dist/src/core/scanner-regex.js +298 -0
- package/dist/src/core/workload/calculator.js +82 -0
- package/dist/src/core/workload/constants.js +15 -0
- package/dist/src/core/workload/grouping.js +18 -0
- package/dist/src/core/workload/hierarchy-calculator.js +127 -0
- package/dist/src/core/workload/index.js +11 -0
- package/dist/src/core/workload/metadata.js +20 -0
- package/dist/src/core/workload/special-workload.js +101 -0
- package/dist/src/core/workload/target-resolver.js +34 -0
- package/dist/src/data/angular-migration-rules.json +2337 -0
- package/dist/src/data/markdown/angular-migration-17-18.md +408 -0
- package/dist/src/data/markdown/angular-migration-18-19.md +600 -0
- package/dist/src/data/markdown/angular-migration-19-20.md +521 -0
- package/dist/src/data/rules/rearchitecture/rearchitecture-rules.json +66 -0
- package/dist/src/data/rules/to18/rules-18-obligatoire.json +374 -0
- package/dist/src/data/rules/to18/rules-18-optionnelle.json +188 -0
- package/dist/src/data/rules/to18/rules-18-recommande.json +218 -0
- package/dist/src/data/rules/to19/rules-19-obligatoire.json +348 -0
- package/dist/src/data/rules/to19/rules-19-optionnelle.json +223 -0
- package/dist/src/data/rules/to19/rules-19-recommande.json +200 -0
- package/dist/src/data/rules/to20/rules-20-obligatoire.json +556 -0
- package/dist/src/data/rules/to20/rules-20-optionnelle.json +190 -0
- package/dist/src/data/rules/to20/rules-20-recommande.json +151 -0
- package/dist/src/index.js +161 -0
- package/dist/src/models/chip-config.js +45 -0
- package/dist/src/models/interfaces/app-details.interface.js +2 -0
- package/dist/src/models/interfaces/ast-interfaces.js +5 -0
- package/dist/src/models/interfaces/ast-pattern.interface.js +2 -0
- package/dist/src/models/interfaces/client-interfaces.js +6 -0
- package/dist/src/models/interfaces/detection-stats.interface.js +2 -0
- package/dist/src/models/interfaces/html-match.interface.js +2 -0
- package/dist/src/models/interfaces/html-report-data.interface.js +2 -0
- package/dist/src/models/interfaces/lib-details.interface.js +2 -0
- package/dist/src/models/interfaces/migration-rules.interface.js +2 -0
- package/dist/src/models/interfaces/parsed-args.interface.js +2 -0
- package/dist/src/models/interfaces/project-info.interface.js +2 -0
- package/dist/src/models/interfaces/project-overview-data.interface.js +2 -0
- package/dist/src/models/interfaces/rule-match.interface.js +2 -0
- package/dist/src/models/interfaces/rule.interface.js +2 -0
- package/dist/src/models/interfaces/rules-by-priority.interface.js +2 -0
- package/dist/src/models/interfaces/scanner-comparison.interface.js +2 -0
- package/dist/src/models/interfaces/special-workload.interface.js +2 -0
- package/dist/src/models/interfaces/workload-report.interface.js +2 -0
- package/dist/src/models/types/build-block-blob.type.js +2 -0
- package/dist/src/models/types/migration-version.type.js +2 -0
- package/dist/src/models/types/project-type.type.js +2 -0
- package/dist/src/models/types/risk-level.type.js +2 -0
- package/dist/src/models/types/rule-category.type.js +2 -0
- package/dist/src/models/types/rule-priority.type.js +2 -0
- package/dist/src/models/types/rule-workload-type.type.js +2 -0
- package/dist/src/templates/landing/applications-analyzed.template.js +18 -0
- package/dist/src/templates/landing/card-app-info.template.js +63 -0
- package/dist/src/templates/landing/card-lib-info.template.js +67 -0
- package/dist/src/templates/landing/libs-analyzed.template.js +22 -0
- package/dist/src/templates/landing/nx-summary.template.js +115 -0
- package/dist/src/templates/landing/project-overview.template.js +27 -0
- package/dist/src/templates/page/index-page.template.js +95 -0
- package/dist/src/templates/page/main.template.js +83 -0
- package/dist/src/templates/page/migration-guide.template.js +175 -0
- package/dist/src/templates/page/workload-report.template.js +53 -0
- package/dist/src/templates/workload/dashboard.template.js +184 -0
- package/dist/src/templates/workload/filters-panel.template.js +215 -0
- package/dist/src/templates/workload/guide-rule-card.template.js +107 -0
- package/dist/src/templates/workload/hierarchy-nx.template.js +104 -0
- package/dist/src/templates/workload/hierarchy-shared.js +163 -0
- package/dist/src/templates/workload/hierarchy-standalone.template.js +36 -0
- package/dist/src/templates/workload/hierarchy.template.js +35 -0
- package/dist/src/templates/workload/rule-modal.template.js +280 -0
- package/dist/src/utils/core/args-parser.js +123 -0
- package/dist/src/utils/core/array-helpers.js +18 -0
- package/dist/src/utils/core/ast-helpers.js +99 -0
- package/dist/src/utils/core/file-helpers.js +109 -0
- package/dist/src/utils/core/html-helpers.js +36 -0
- package/dist/src/utils/core/index.js +28 -0
- package/dist/src/utils/core/logger.js +38 -0
- package/dist/src/utils/core/rule-helpers.js +15 -0
- package/dist/src/utils/core/workload-formatter.js +6 -0
- package/dist/src/utils/shared/array-helpers.js +25 -0
- package/dist/src/utils/shared/date-helpers.js +109 -0
- package/dist/src/utils/shared/html-helpers.js +37 -0
- package/dist/src/utils/shared/index.js +25 -0
- package/dist/src/utils/shared/rule-helpers.js +20 -0
- package/dist/src/utils/shared/time-formatters.js +76 -0
- package/dist/styles.css +2 -0
- package/package.json +107 -0
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Utils core/serveur (dépendent de Node.js APIs)
|
|
4
|
+
* Barrel export pour imports simplifiés
|
|
5
|
+
*/
|
|
6
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
7
|
+
if (k2 === undefined) k2 = k;
|
|
8
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
9
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
10
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
11
|
+
}
|
|
12
|
+
Object.defineProperty(o, k2, desc);
|
|
13
|
+
}) : (function(o, m, k, k2) {
|
|
14
|
+
if (k2 === undefined) k2 = k;
|
|
15
|
+
o[k2] = m[k];
|
|
16
|
+
}));
|
|
17
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
18
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
19
|
+
};
|
|
20
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
21
|
+
__exportStar(require("./logger"), exports);
|
|
22
|
+
__exportStar(require("./file-helpers"), exports);
|
|
23
|
+
__exportStar(require("./html-helpers"), exports);
|
|
24
|
+
__exportStar(require("./workload-formatter"), exports);
|
|
25
|
+
__exportStar(require("./rule-helpers"), exports);
|
|
26
|
+
__exportStar(require("./array-helpers"), exports);
|
|
27
|
+
__exportStar(require("./ast-helpers"), exports);
|
|
28
|
+
__exportStar(require("./args-parser"), exports);
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Logger simple avec codes couleur ANSI pour terminal
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.logger = void 0;
|
|
7
|
+
const COLORS = {
|
|
8
|
+
reset: '\x1b[0m',
|
|
9
|
+
blue: '\x1b[34m',
|
|
10
|
+
green: '\x1b[32m',
|
|
11
|
+
yellow: '\x1b[33m',
|
|
12
|
+
red: '\x1b[31m',
|
|
13
|
+
cyan: '\x1b[36m',
|
|
14
|
+
gray: '\x1b[90m'
|
|
15
|
+
};
|
|
16
|
+
exports.logger = {
|
|
17
|
+
info(message) {
|
|
18
|
+
console.log(`${COLORS.blue}ℹ${COLORS.reset} ${message}`);
|
|
19
|
+
},
|
|
20
|
+
success(message) {
|
|
21
|
+
console.log(`${COLORS.green}✓${COLORS.reset} ${message}`);
|
|
22
|
+
},
|
|
23
|
+
warning(message) {
|
|
24
|
+
console.log(`${COLORS.yellow}⚠${COLORS.reset} ${message}`);
|
|
25
|
+
},
|
|
26
|
+
error(message) {
|
|
27
|
+
console.log(`${COLORS.red}✗${COLORS.reset} ${message}`);
|
|
28
|
+
},
|
|
29
|
+
step(message) {
|
|
30
|
+
console.log(`${COLORS.cyan}→${COLORS.reset} ${message}`);
|
|
31
|
+
},
|
|
32
|
+
debug(message) {
|
|
33
|
+
console.log(`${COLORS.gray}${message}${COLORS.reset}`);
|
|
34
|
+
},
|
|
35
|
+
blank() {
|
|
36
|
+
console.log('');
|
|
37
|
+
}
|
|
38
|
+
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.isRoutineRule = void 0;
|
|
4
|
+
exports.createRuleMap = createRuleMap;
|
|
5
|
+
/**
|
|
6
|
+
* Crée une Map ruleKey → Rule pour accès rapide O(1)
|
|
7
|
+
* @param rules Liste des règles
|
|
8
|
+
* @returns Map avec clés ruleKey et valeurs Rule
|
|
9
|
+
*/
|
|
10
|
+
function createRuleMap(rules) {
|
|
11
|
+
return new Map(rules.map(r => [r.key, r]));
|
|
12
|
+
}
|
|
13
|
+
// Re-export isRoutineRule depuis shared pour rétrocompatibilité
|
|
14
|
+
var rule_helpers_1 = require("../shared/rule-helpers");
|
|
15
|
+
Object.defineProperty(exports, "isRoutineRule", { enumerable: true, get: function () { return rule_helpers_1.isRoutineRule; } });
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.formatWorkloadTime = exports.convertMinutesToWorkloadTime = void 0;
|
|
4
|
+
const shared_1 = require("../shared");
|
|
5
|
+
Object.defineProperty(exports, "convertMinutesToWorkloadTime", { enumerable: true, get: function () { return shared_1.convertMinutesToWorkloadTime; } });
|
|
6
|
+
Object.defineProperty(exports, "formatWorkloadTime", { enumerable: true, get: function () { return shared_1.formatWorkloadTime; } });
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.groupBy = groupBy;
|
|
4
|
+
/**
|
|
5
|
+
* Groupe un tableau d'éléments selon une clé extraite par une fonction
|
|
6
|
+
* @param items Tableau d'éléments à grouper
|
|
7
|
+
* @param keyExtractor Fonction qui extrait la clé de grouping pour chaque élément
|
|
8
|
+
* @returns Map avec clés → tableaux d'éléments
|
|
9
|
+
* @example
|
|
10
|
+
* groupBy([{id: 1, type: 'a'}, {id: 2, type: 'a'}], item => item.type)
|
|
11
|
+
* // Map { 'a' => [{id: 1, type: 'a'}, {id: 2, type: 'a'}] }
|
|
12
|
+
*/
|
|
13
|
+
function groupBy(items, keyExtractor) {
|
|
14
|
+
const grouped = new Map();
|
|
15
|
+
for (const item of items) {
|
|
16
|
+
const key = keyExtractor(item);
|
|
17
|
+
if (key === null || key === undefined)
|
|
18
|
+
continue;
|
|
19
|
+
if (!grouped.has(key)) {
|
|
20
|
+
grouped.set(key, []);
|
|
21
|
+
}
|
|
22
|
+
grouped.get(key).push(item);
|
|
23
|
+
}
|
|
24
|
+
return grouped;
|
|
25
|
+
}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Helpers de dates partagés (client + serveur)
|
|
4
|
+
* Consolidation de formatters.ts + html-helpers.ts + parallelization-calculator.ts
|
|
5
|
+
*
|
|
6
|
+
* PRINCIPE DRY : Single Source of Truth pour les opérations sur dates
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.addDays = addDays;
|
|
10
|
+
exports.addWorkingDays = addWorkingDays;
|
|
11
|
+
exports.formatDate = formatDate;
|
|
12
|
+
exports.isWeekend = isWeekend;
|
|
13
|
+
exports.isWorkingDay = isWorkingDay;
|
|
14
|
+
/**
|
|
15
|
+
* Ajoute des jours à une date (simple, sans logique jours ouvrés)
|
|
16
|
+
* Utilise Math.ceil pour arrondir les fractions de jours vers le haut
|
|
17
|
+
*
|
|
18
|
+
* @param startDate Date de début
|
|
19
|
+
* @param days Nombre de jours à ajouter (peut être décimal)
|
|
20
|
+
* @returns Nouvelle date
|
|
21
|
+
*/
|
|
22
|
+
function addDays(startDate, days) {
|
|
23
|
+
const result = new Date(startDate);
|
|
24
|
+
result.setDate(result.getDate() + Math.ceil(days));
|
|
25
|
+
return result;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Ajoute des jours ouvrés à une date (skip weekends)
|
|
29
|
+
* Logique : Le premier jour est déjà le jour de début.
|
|
30
|
+
* Ex: 1.9j → ceil(1.9) - 1 = 1 jour supplémentaire → termine le 2e jour
|
|
31
|
+
* Ex: 0.5j → ceil(0.5) - 1 = 0 jour supplémentaire → termine le 1er jour (même jour)
|
|
32
|
+
*
|
|
33
|
+
* @param startDate Date de début
|
|
34
|
+
* @param days Nombre de jours ouvrés à ajouter (peut être décimal)
|
|
35
|
+
* @returns Nouvelle date (en excluant weekends)
|
|
36
|
+
*/
|
|
37
|
+
function addWorkingDays(startDate, days) {
|
|
38
|
+
if (days === 0)
|
|
39
|
+
return new Date(startDate);
|
|
40
|
+
const result = new Date(startDate);
|
|
41
|
+
// Nombre de jours ouvrés supplémentaires à ajouter après le jour de début
|
|
42
|
+
const additionalWorkDays = Math.ceil(days) - 1;
|
|
43
|
+
let addedDays = 0;
|
|
44
|
+
while (addedDays < additionalWorkDays) {
|
|
45
|
+
result.setDate(result.getDate() + 1);
|
|
46
|
+
// Vérifier si c'est un jour ouvré (lundi=1 à vendredi=5)
|
|
47
|
+
const dayOfWeek = result.getDay();
|
|
48
|
+
if (dayOfWeek !== 0 && dayOfWeek !== 6) { // Pas dimanche (0) ni samedi (6)
|
|
49
|
+
addedDays++;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
return result;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Formate une date en string selon le format spécifié
|
|
56
|
+
*
|
|
57
|
+
* Formats disponibles :
|
|
58
|
+
* - 'short' : "21/10/2025"
|
|
59
|
+
* - 'long' : "21 octobre 2025"
|
|
60
|
+
* - 'iso' : "2025-10-21"
|
|
61
|
+
* - 'french' : "21/10/2025 à 12:30" (avec heure)
|
|
62
|
+
*
|
|
63
|
+
* @param date Date ou string ISO
|
|
64
|
+
* @param format Format de sortie
|
|
65
|
+
* @returns String formatée
|
|
66
|
+
*/
|
|
67
|
+
function formatDate(date, format = 'short') {
|
|
68
|
+
const d = typeof date === 'string' ? new Date(date) : date;
|
|
69
|
+
if (format === 'iso') {
|
|
70
|
+
return d.toISOString().split('T')[0];
|
|
71
|
+
}
|
|
72
|
+
if (format === 'short') {
|
|
73
|
+
const day = String(d.getDate()).padStart(2, '0');
|
|
74
|
+
const month = String(d.getMonth() + 1).padStart(2, '0');
|
|
75
|
+
return `${day}/${month}`;
|
|
76
|
+
}
|
|
77
|
+
if (format === 'french') {
|
|
78
|
+
return d.toLocaleDateString('fr-FR', {
|
|
79
|
+
year: 'numeric',
|
|
80
|
+
month: '2-digit',
|
|
81
|
+
day: '2-digit',
|
|
82
|
+
hour: '2-digit',
|
|
83
|
+
minute: '2-digit'
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
// format === 'long'
|
|
87
|
+
return d.toLocaleDateString('fr-FR', {
|
|
88
|
+
year: 'numeric',
|
|
89
|
+
month: 'long',
|
|
90
|
+
day: 'numeric'
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Retourne true si la date est un weekend
|
|
95
|
+
* @param date Date à vérifier
|
|
96
|
+
* @returns true si samedi ou dimanche
|
|
97
|
+
*/
|
|
98
|
+
function isWeekend(date) {
|
|
99
|
+
const dayOfWeek = date.getDay();
|
|
100
|
+
return dayOfWeek === 0 || dayOfWeek === 6;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Retourne true si la date est un jour ouvré
|
|
104
|
+
* @param date Date à vérifier
|
|
105
|
+
* @returns true si lundi à vendredi
|
|
106
|
+
*/
|
|
107
|
+
function isWorkingDay(date) {
|
|
108
|
+
return !isWeekend(date);
|
|
109
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Helpers HTML partagés (client + serveur)
|
|
4
|
+
* Fonctions pures sans dépendance Node.js/DOM
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.escapeHtml = escapeHtml;
|
|
8
|
+
exports.renderBadge = renderBadge;
|
|
9
|
+
exports.escapeJson = escapeJson;
|
|
10
|
+
/**
|
|
11
|
+
* Échappe HTML pour prévenir XSS
|
|
12
|
+
*/
|
|
13
|
+
function escapeHtml(text) {
|
|
14
|
+
const map = {
|
|
15
|
+
'&': '&',
|
|
16
|
+
'<': '<',
|
|
17
|
+
'>': '>',
|
|
18
|
+
'"': '"',
|
|
19
|
+
"'": '''
|
|
20
|
+
};
|
|
21
|
+
return text.replace(/[&<>"']/g, m => map[m]);
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Génère un badge HTML
|
|
25
|
+
*/
|
|
26
|
+
function renderBadge(text, colorClass = 'blue') {
|
|
27
|
+
return `<span class="inline-block px-2 py-1 text-xs font-semibold rounded bg-${colorClass}-100 text-${colorClass}-800">${escapeHtml(text)}</span>`;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Échappe JSON pour insertion dans <script>
|
|
31
|
+
*/
|
|
32
|
+
function escapeJson(obj) {
|
|
33
|
+
return JSON.stringify(obj)
|
|
34
|
+
.replace(/</g, '\\u003c')
|
|
35
|
+
.replace(/>/g, '\\u003e')
|
|
36
|
+
.replace(/&/g, '\\u0026');
|
|
37
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Utils partagés (client + serveur)
|
|
4
|
+
* Barrel export pour imports simplifiés
|
|
5
|
+
*/
|
|
6
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
7
|
+
if (k2 === undefined) k2 = k;
|
|
8
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
9
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
10
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
11
|
+
}
|
|
12
|
+
Object.defineProperty(o, k2, desc);
|
|
13
|
+
}) : (function(o, m, k, k2) {
|
|
14
|
+
if (k2 === undefined) k2 = k;
|
|
15
|
+
o[k2] = m[k];
|
|
16
|
+
}));
|
|
17
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
18
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
19
|
+
};
|
|
20
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
21
|
+
__exportStar(require("./time-formatters"), exports);
|
|
22
|
+
__exportStar(require("./date-helpers"), exports);
|
|
23
|
+
__exportStar(require("./html-helpers"), exports);
|
|
24
|
+
__exportStar(require("./rule-helpers"), exports);
|
|
25
|
+
__exportStar(require("./array-helpers"), exports);
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.isRoutineRule = isRoutineRule;
|
|
4
|
+
/**
|
|
5
|
+
* Identifie si une règle est une routine (tâche manuelle unique par projet)
|
|
6
|
+
*
|
|
7
|
+
* Critères:
|
|
8
|
+
* - Possède un champ onFile (indique un fichier de configuration spécifique)
|
|
9
|
+
*
|
|
10
|
+
* Ces règles représentent des tâches manuelles systématiques comme:
|
|
11
|
+
* - Mise à jour de Node.js (détectée via package.json)
|
|
12
|
+
* - Mise à jour de TypeScript (détectée via package.json)
|
|
13
|
+
* - Configuration manuelle de fichiers (détectée via angular.json, tsconfig.json, etc.)
|
|
14
|
+
*
|
|
15
|
+
* @param rule Règle à vérifier
|
|
16
|
+
* @returns true si la règle est une routine
|
|
17
|
+
*/
|
|
18
|
+
function isRoutineRule(rule) {
|
|
19
|
+
return !!rule.onFile;
|
|
20
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Formatters de temps partagés (client + serveur)
|
|
4
|
+
* Consolidation de formatters.ts + workload-formatter.ts + html-helpers.ts
|
|
5
|
+
*
|
|
6
|
+
* PRINCIPE DRY : Single Source of Truth pour le formatage temps
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.convertMinutesToWorkloadTime = convertMinutesToWorkloadTime;
|
|
10
|
+
exports.formatWorkloadTime = formatWorkloadTime;
|
|
11
|
+
exports.formatTimeForAxis = formatTimeForAxis;
|
|
12
|
+
exports.formatTime = formatTime;
|
|
13
|
+
/**
|
|
14
|
+
* Convertit des minutes en WorkloadTime
|
|
15
|
+
* @param minutes Nombre total de minutes
|
|
16
|
+
* @param hoursPerDay Heures par jour (défaut: 7)
|
|
17
|
+
* @returns Objet avec minutes, hours, days (arrondis 2 décimales)
|
|
18
|
+
*/
|
|
19
|
+
function convertMinutesToWorkloadTime(minutes, hoursPerDay = 7) {
|
|
20
|
+
const hours = Math.round((minutes / 60) * 100) / 100;
|
|
21
|
+
const days = Math.round((hours / hoursPerDay) * 100) / 100;
|
|
22
|
+
return { minutes, hours, days };
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Formate un WorkloadTime en string lisible avec seuils intelligents
|
|
26
|
+
*
|
|
27
|
+
* Seuils :
|
|
28
|
+
* - < 60min : affiche minutes
|
|
29
|
+
* - < 420min (7h) : affiche heures
|
|
30
|
+
* - >= 420min : affiche jours
|
|
31
|
+
*
|
|
32
|
+
* @param time WorkloadTime object
|
|
33
|
+
* @param verbose Si true, affiche détails entre parenthèses (ex: "2.5j (17.5h)")
|
|
34
|
+
* @returns String formatée
|
|
35
|
+
*/
|
|
36
|
+
function formatWorkloadTime(time, verbose = false) {
|
|
37
|
+
if (time.minutes < 60) {
|
|
38
|
+
return `${time.minutes}min`;
|
|
39
|
+
}
|
|
40
|
+
if (time.minutes < 420) { // < 7h
|
|
41
|
+
return verbose ? `${time.hours}h (${time.minutes}min)` : `${time.hours}h`;
|
|
42
|
+
}
|
|
43
|
+
return verbose ? `${time.days}j (${time.hours}h)` : `${time.days}j`;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Formate un temps pour axes de graphiques
|
|
47
|
+
* Retourne label avec unité appropriée pour affichage sur axes
|
|
48
|
+
*
|
|
49
|
+
* @param minutes Nombre de minutes
|
|
50
|
+
* @param hoursPerDay Heures par jour (défaut: 7)
|
|
51
|
+
* @returns String formatée avec espace (ex: "3.5 h")
|
|
52
|
+
*/
|
|
53
|
+
function formatTimeForAxis(minutes, hoursPerDay = 7) {
|
|
54
|
+
if (minutes < 60) {
|
|
55
|
+
return `${minutes} min`;
|
|
56
|
+
}
|
|
57
|
+
const hours = Math.round((minutes / 60) * 100) / 100;
|
|
58
|
+
if (minutes < hoursPerDay * 60) {
|
|
59
|
+
return `${hours} h`;
|
|
60
|
+
}
|
|
61
|
+
const days = Math.round((hours / hoursPerDay) * 100) / 100;
|
|
62
|
+
return `${days} j`;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Formate un WorkloadTime complet (helper pour html-helpers)
|
|
66
|
+
* Retourne string avec minutes, hours et days
|
|
67
|
+
*
|
|
68
|
+
* @param minutes Minutes
|
|
69
|
+
* @param hours Heures
|
|
70
|
+
* @param days Jours
|
|
71
|
+
* @returns String formatée intelligente
|
|
72
|
+
*/
|
|
73
|
+
function formatTime(minutes, hours, days) {
|
|
74
|
+
const time = { minutes, hours, days };
|
|
75
|
+
return formatWorkloadTime(time, false);
|
|
76
|
+
}
|
package/dist/styles.css
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
/*! tailwindcss v4.1.14 | MIT License | https://tailwindcss.com */
|
|
2
|
+
@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-space-y-reverse:0;--tw-space-x-reverse:0;--tw-border-style:solid;--tw-gradient-position:initial;--tw-gradient-from:#0000;--tw-gradient-via:#0000;--tw-gradient-to:#0000;--tw-gradient-stops:initial;--tw-gradient-via-stops:initial;--tw-gradient-from-position:0%;--tw-gradient-via-position:50%;--tw-gradient-to-position:100%;--tw-leading:initial;--tw-font-weight:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial;--tw-duration:initial;--tw-scale-x:1;--tw-scale-y:1;--tw-scale-z:1}}}@layer theme{:root,:host{--font-sans:ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--font-mono:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;--color-red-100:oklch(93.6% .032 17.717);--color-red-500:oklch(63.7% .237 25.331);--color-red-600:oklch(57.7% .245 27.325);--color-red-700:oklch(50.5% .213 27.518);--color-orange-50:oklch(98% .016 73.684);--color-orange-100:oklch(95.4% .038 75.164);--color-orange-500:oklch(70.5% .213 47.604);--color-orange-600:oklch(64.6% .222 41.116);--color-orange-700:oklch(55.3% .195 38.402);--color-yellow-50:oklch(98.7% .026 102.212);--color-yellow-100:oklch(97.3% .071 103.193);--color-yellow-400:oklch(85.2% .199 91.936);--color-yellow-500:oklch(79.5% .184 86.047);--color-yellow-600:oklch(68.1% .162 75.834);--color-yellow-700:oklch(55.4% .135 66.442);--color-yellow-800:oklch(47.6% .114 61.907);--color-green-50:oklch(98.2% .018 155.826);--color-green-100:oklch(96.2% .044 156.743);--color-green-400:oklch(79.2% .209 151.711);--color-green-500:oklch(72.3% .219 149.579);--color-green-600:oklch(62.7% .194 149.214);--color-green-700:oklch(52.7% .154 150.069);--color-teal-50:oklch(98.4% .014 180.72);--color-teal-400:oklch(77.7% .152 181.912);--color-teal-500:oklch(70.4% .14 182.503);--color-teal-600:oklch(60% .118 184.704);--color-teal-700:oklch(51.1% .096 186.391);--color-teal-800:oklch(43.7% .078 188.216);--color-blue-50:oklch(97% .014 254.604);--color-blue-100:oklch(93.2% .032 255.585);--color-blue-200:oklch(88.2% .059 254.128);--color-blue-500:oklch(62.3% .214 259.815);--color-blue-600:oklch(54.6% .245 262.881);--color-blue-700:oklch(48.8% .243 264.376);--color-blue-800:oklch(42.4% .199 265.638);--color-blue-900:oklch(37.9% .146 265.522);--color-indigo-50:oklch(96.2% .018 272.314);--color-indigo-100:oklch(93% .034 272.788);--color-indigo-500:oklch(58.5% .233 277.117);--color-indigo-600:oklch(51.1% .262 276.966);--color-indigo-700:oklch(45.7% .24 277.023);--color-indigo-900:oklch(35.9% .144 278.697);--color-violet-50:oklch(96.9% .016 293.756);--color-violet-600:oklch(54.1% .281 293.009);--color-violet-700:oklch(49.1% .27 292.581);--color-purple-50:oklch(97.7% .014 308.299);--color-purple-100:oklch(94.6% .033 307.174);--color-purple-500:oklch(62.7% .265 303.9);--color-purple-600:oklch(55.8% .288 302.321);--color-purple-700:oklch(49.6% .265 301.924);--color-purple-900:oklch(38.1% .176 304.987);--color-pink-50:oklch(97.1% .014 343.198);--color-pink-100:oklch(94.8% .028 342.258);--color-pink-500:oklch(65.6% .241 354.308);--color-pink-600:oklch(59.2% .249 .584);--color-pink-700:oklch(52.5% .223 3.958);--color-pink-900:oklch(40.8% .153 2.432);--color-gray-50:oklch(98.5% .002 247.839);--color-gray-100:oklch(96.7% .003 264.542);--color-gray-200:oklch(92.8% .006 264.531);--color-gray-300:oklch(87.2% .01 258.338);--color-gray-400:oklch(70.7% .022 261.325);--color-gray-500:oklch(55.1% .027 264.364);--color-gray-600:oklch(44.6% .03 256.802);--color-gray-700:oklch(37.3% .034 259.733);--color-gray-800:oklch(27.8% .033 256.848);--color-gray-900:oklch(21% .034 264.665);--color-black:#000;--color-white:#fff;--spacing:.25rem;--container-4xl:56rem;--container-7xl:80rem;--text-xs:.75rem;--text-xs--line-height:calc(1/.75);--text-sm:.875rem;--text-sm--line-height:calc(1.25/.875);--text-base:1rem;--text-base--line-height:calc(1.5/1);--text-lg:1.125rem;--text-lg--line-height:calc(1.75/1.125);--text-xl:1.25rem;--text-xl--line-height:calc(1.75/1.25);--text-2xl:1.5rem;--text-2xl--line-height:calc(2/1.5);--text-3xl:1.875rem;--text-3xl--line-height:calc(2.25/1.875);--text-4xl:2.25rem;--text-4xl--line-height:calc(2.5/2.25);--text-5xl:3rem;--text-5xl--line-height:1;--text-6xl:3.75rem;--text-6xl--line-height:1;--font-weight-medium:500;--font-weight-semibold:600;--font-weight-bold:700;--radius-lg:.5rem;--radius-xl:.75rem;--radius-2xl:1rem;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4,0,.2,1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono)}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab, red, red)){::placeholder{color:color-mix(in oklab,currentcolor 50%,transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}}@layer components;@layer utilities{.pointer-events-none{pointer-events:none}.collapse{visibility:collapse}.visible{visibility:visible}.fixed{position:fixed}.relative{position:relative}.sticky{position:sticky}.inset-0{inset:calc(var(--spacing)*0)}.top-0{top:calc(var(--spacing)*0)}.top-4{top:calc(var(--spacing)*4)}.bottom-0{bottom:calc(var(--spacing)*0)}.z-10{z-index:10}.z-20{z-index:20}.z-50{z-index:50}.container{width:100%}@media (min-width:40rem){.container{max-width:40rem}}@media (min-width:48rem){.container{max-width:48rem}}@media (min-width:64rem){.container{max-width:64rem}}@media (min-width:80rem){.container{max-width:80rem}}@media (min-width:96rem){.container{max-width:96rem}}.mx-1{margin-inline:calc(var(--spacing)*1)}.mx-auto{margin-inline:auto}.mt-1{margin-top:calc(var(--spacing)*1)}.mt-2{margin-top:calc(var(--spacing)*2)}.mt-3{margin-top:calc(var(--spacing)*3)}.mt-4{margin-top:calc(var(--spacing)*4)}.mt-6{margin-top:calc(var(--spacing)*6)}.mt-8{margin-top:calc(var(--spacing)*8)}.mt-12{margin-top:calc(var(--spacing)*12)}.mr-1{margin-right:calc(var(--spacing)*1)}.mr-1\.5{margin-right:calc(var(--spacing)*1.5)}.mr-2{margin-right:calc(var(--spacing)*2)}.mr-3{margin-right:calc(var(--spacing)*3)}.mr-4{margin-right:calc(var(--spacing)*4)}.mb-1{margin-bottom:calc(var(--spacing)*1)}.mb-2{margin-bottom:calc(var(--spacing)*2)}.mb-3{margin-bottom:calc(var(--spacing)*3)}.mb-4{margin-bottom:calc(var(--spacing)*4)}.mb-6{margin-bottom:calc(var(--spacing)*6)}.mb-8{margin-bottom:calc(var(--spacing)*8)}.mb-12{margin-bottom:calc(var(--spacing)*12)}.ml-1{margin-left:calc(var(--spacing)*1)}.ml-2{margin-left:calc(var(--spacing)*2)}.ml-4{margin-left:calc(var(--spacing)*4)}.ml-6{margin-left:calc(var(--spacing)*6)}.ml-8{margin-left:calc(var(--spacing)*8)}.block{display:block}.contents{display:contents}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline{display:inline}.inline-block{display:inline-block}.inline-flex{display:inline-flex}.h-3{height:calc(var(--spacing)*3)}.h-4{height:calc(var(--spacing)*4)}.h-5{height:calc(var(--spacing)*5)}.h-6{height:calc(var(--spacing)*6)}.h-8{height:calc(var(--spacing)*8)}.h-full{height:100%}.max-h-64{max-height:calc(var(--spacing)*64)}.max-h-\[90vh\]{max-height:90vh}.min-h-0{min-height:calc(var(--spacing)*0)}.min-h-screen{min-height:100vh}.w-3{width:calc(var(--spacing)*3)}.w-4{width:calc(var(--spacing)*4)}.w-5{width:calc(var(--spacing)*5)}.w-6{width:calc(var(--spacing)*6)}.w-8{width:calc(var(--spacing)*8)}.w-14{width:calc(var(--spacing)*14)}.w-64{width:calc(var(--spacing)*64)}.w-full{width:100%}.max-w-4xl{max-width:var(--container-4xl)}.max-w-7xl{max-width:var(--container-7xl)}.max-w-32{max-width:calc(var(--spacing)*32)}.min-w-0{min-width:calc(var(--spacing)*0)}.min-w-16{min-width:calc(var(--spacing)*16)}.flex-1{flex:1}.flex-shrink-0{flex-shrink:0}.transform{transform:var(--tw-rotate-x,)var(--tw-rotate-y,)var(--tw-rotate-z,)var(--tw-skew-x,)var(--tw-skew-y,)}.cursor-pointer{cursor:pointer}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-center{align-items:center}.items-start{align-items:flex-start}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.justify-end{justify-content:flex-end}.gap-1{gap:calc(var(--spacing)*1)}.gap-2{gap:calc(var(--spacing)*2)}.gap-3{gap:calc(var(--spacing)*3)}.gap-4{gap:calc(var(--spacing)*4)}.gap-6{gap:calc(var(--spacing)*6)}.gap-8{gap:calc(var(--spacing)*8)}:where(.space-y-1\.5>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*1.5)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*1.5)*calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-2>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*2)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*2)*calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-3>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*3)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*3)*calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-4>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*4)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*4)*calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-6>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*6)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*6)*calc(1 - var(--tw-space-y-reverse)))}:where(.space-x-2>:not(:last-child)){--tw-space-x-reverse:0;margin-inline-start:calc(calc(var(--spacing)*2)*var(--tw-space-x-reverse));margin-inline-end:calc(calc(var(--spacing)*2)*calc(1 - var(--tw-space-x-reverse)))}:where(.space-x-3>:not(:last-child)){--tw-space-x-reverse:0;margin-inline-start:calc(calc(var(--spacing)*3)*var(--tw-space-x-reverse));margin-inline-end:calc(calc(var(--spacing)*3)*calc(1 - var(--tw-space-x-reverse)))}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-y-auto{overflow-y:auto}.rounded{border-radius:.25rem}.rounded-2xl{border-radius:var(--radius-2xl)}.rounded-full{border-radius:3.40282e38px}.rounded-lg{border-radius:var(--radius-lg)}.rounded-xl{border-radius:var(--radius-xl)}.rounded-t-xl{border-top-left-radius:var(--radius-xl);border-top-right-radius:var(--radius-xl)}.rounded-b-xl{border-bottom-right-radius:var(--radius-xl);border-bottom-left-radius:var(--radius-xl)}.border{border-style:var(--tw-border-style);border-width:1px}.border-2{border-style:var(--tw-border-style);border-width:2px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-l-2{border-left-style:var(--tw-border-style);border-left-width:2px}.border-l-4{border-left-style:var(--tw-border-style);border-left-width:4px}.border-blue-200{border-color:var(--color-blue-200)}.border-blue-500{border-color:var(--color-blue-500)}.border-blue-600{border-color:var(--color-blue-600)}.border-gray-200{border-color:var(--color-gray-200)}.border-gray-300{border-color:var(--color-gray-300)}.border-green-500{border-color:var(--color-green-500)}.border-indigo-500{border-color:var(--color-indigo-500)}.border-purple-500{border-color:var(--color-purple-500)}.border-teal-400{border-color:var(--color-teal-400)}.border-transparent{border-color:#0000}.border-yellow-400{border-color:var(--color-yellow-400)}.bg-black{background-color:var(--color-black)}.bg-blue-50{background-color:var(--color-blue-50)}.bg-blue-100{background-color:var(--color-blue-100)}.bg-blue-500{background-color:var(--color-blue-500)}.bg-blue-600{background-color:var(--color-blue-600)}.bg-gray-50{background-color:var(--color-gray-50)}.bg-gray-100{background-color:var(--color-gray-100)}.bg-gray-200{background-color:var(--color-gray-200)}.bg-gray-500{background-color:var(--color-gray-500)}.bg-gray-600{background-color:var(--color-gray-600)}.bg-gray-800{background-color:var(--color-gray-800)}.bg-green-50{background-color:var(--color-green-50)}.bg-green-100{background-color:var(--color-green-100)}.bg-green-500{background-color:var(--color-green-500)}.bg-indigo-50{background-color:var(--color-indigo-50)}.bg-indigo-100{background-color:var(--color-indigo-100)}.bg-orange-50{background-color:var(--color-orange-50)}.bg-pink-50{background-color:var(--color-pink-50)}.bg-purple-50{background-color:var(--color-purple-50)}.bg-purple-100{background-color:var(--color-purple-100)}.bg-red-500{background-color:var(--color-red-500)}.bg-teal-50{background-color:var(--color-teal-50)}.bg-violet-50{background-color:var(--color-violet-50)}.bg-white{background-color:var(--color-white)}.bg-yellow-50{background-color:var(--color-yellow-50)}.bg-gradient-to-br{--tw-gradient-position:to bottom right in oklab;background-image:linear-gradient(var(--tw-gradient-stops))}.bg-gradient-to-r{--tw-gradient-position:to right in oklab;background-image:linear-gradient(var(--tw-gradient-stops))}.from-blue-50{--tw-gradient-from:var(--color-blue-50);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.from-blue-600{--tw-gradient-from:var(--color-blue-600);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.from-green-500{--tw-gradient-from:var(--color-green-500);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.from-indigo-50{--tw-gradient-from:var(--color-indigo-50);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.from-orange-500{--tw-gradient-from:var(--color-orange-500);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.from-pink-50{--tw-gradient-from:var(--color-pink-50);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.from-purple-50{--tw-gradient-from:var(--color-purple-50);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.from-red-500{--tw-gradient-from:var(--color-red-500);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.from-yellow-500{--tw-gradient-from:var(--color-yellow-500);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.to-blue-100{--tw-gradient-to:var(--color-blue-100);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.to-green-600{--tw-gradient-to:var(--color-green-600);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.to-indigo-50{--tw-gradient-to:var(--color-indigo-50);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.to-indigo-100{--tw-gradient-to:var(--color-indigo-100);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.to-indigo-600{--tw-gradient-to:var(--color-indigo-600);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.to-indigo-700{--tw-gradient-to:var(--color-indigo-700);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.to-orange-600{--tw-gradient-to:var(--color-orange-600);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.to-pink-100{--tw-gradient-to:var(--color-pink-100);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.to-purple-100{--tw-gradient-to:var(--color-purple-100);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.to-red-600{--tw-gradient-to:var(--color-red-600);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.to-yellow-600{--tw-gradient-to:var(--color-yellow-600);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.bg-clip-text{-webkit-background-clip:text;background-clip:text}.p-0\.5{padding:calc(var(--spacing)*.5)}.p-1\.5{padding:calc(var(--spacing)*1.5)}.p-2{padding:calc(var(--spacing)*2)}.p-3{padding:calc(var(--spacing)*3)}.p-4{padding:calc(var(--spacing)*4)}.p-6{padding:calc(var(--spacing)*6)}.p-8{padding:calc(var(--spacing)*8)}.px-2{padding-inline:calc(var(--spacing)*2)}.px-3{padding-inline:calc(var(--spacing)*3)}.px-4{padding-inline:calc(var(--spacing)*4)}.px-6{padding-inline:calc(var(--spacing)*6)}.px-8{padding-inline:calc(var(--spacing)*8)}.py-1{padding-block:calc(var(--spacing)*1)}.py-1\.5{padding-block:calc(var(--spacing)*1.5)}.py-2{padding-block:calc(var(--spacing)*2)}.py-2\.5{padding-block:calc(var(--spacing)*2.5)}.py-3{padding-block:calc(var(--spacing)*3)}.py-4{padding-block:calc(var(--spacing)*4)}.py-6{padding-block:calc(var(--spacing)*6)}.py-8{padding-block:calc(var(--spacing)*8)}.pt-0{padding-top:calc(var(--spacing)*0)}.pt-4{padding-top:calc(var(--spacing)*4)}.pt-6{padding-top:calc(var(--spacing)*6)}.pl-4{padding-left:calc(var(--spacing)*4)}.text-center{text-align:center}.font-mono{font-family:var(--font-mono)}.text-2xl{font-size:var(--text-2xl);line-height:var(--tw-leading,var(--text-2xl--line-height))}.text-3xl{font-size:var(--text-3xl);line-height:var(--tw-leading,var(--text-3xl--line-height))}.text-4xl{font-size:var(--text-4xl);line-height:var(--tw-leading,var(--text-4xl--line-height))}.text-5xl{font-size:var(--text-5xl);line-height:var(--tw-leading,var(--text-5xl--line-height))}.text-6xl{font-size:var(--text-6xl);line-height:var(--tw-leading,var(--text-6xl--line-height))}.text-base{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}.text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xl{font-size:var(--text-xl);line-height:var(--tw-leading,var(--text-xl--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.leading-none{--tw-leading:1;line-height:1}.font-bold{--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.whitespace-pre-line{white-space:pre-line}.whitespace-pre-wrap{white-space:pre-wrap}.text-blue-100{color:var(--color-blue-100)}.text-blue-600{color:var(--color-blue-600)}.text-blue-700{color:var(--color-blue-700)}.text-blue-800{color:var(--color-blue-800)}.text-blue-900{color:var(--color-blue-900)}.text-gray-400{color:var(--color-gray-400)}.text-gray-500{color:var(--color-gray-500)}.text-gray-600{color:var(--color-gray-600)}.text-gray-700{color:var(--color-gray-700)}.text-gray-800{color:var(--color-gray-800)}.text-gray-900{color:var(--color-gray-900)}.text-green-100{color:var(--color-green-100)}.text-green-400{color:var(--color-green-400)}.text-green-600{color:var(--color-green-600)}.text-green-700{color:var(--color-green-700)}.text-indigo-600{color:var(--color-indigo-600)}.text-indigo-700{color:var(--color-indigo-700)}.text-indigo-900{color:var(--color-indigo-900)}.text-orange-100{color:var(--color-orange-100)}.text-orange-600{color:var(--color-orange-600)}.text-orange-700{color:var(--color-orange-700)}.text-pink-600{color:var(--color-pink-600)}.text-pink-700{color:var(--color-pink-700)}.text-pink-900{color:var(--color-pink-900)}.text-purple-600{color:var(--color-purple-600)}.text-purple-700{color:var(--color-purple-700)}.text-purple-900{color:var(--color-purple-900)}.text-red-100{color:var(--color-red-100)}.text-red-600{color:var(--color-red-600)}.text-red-700{color:var(--color-red-700)}.text-teal-600{color:var(--color-teal-600)}.text-teal-700{color:var(--color-teal-700)}.text-teal-800{color:var(--color-teal-800)}.text-transparent{color:#0000}.text-violet-600{color:var(--color-violet-600)}.text-violet-700{color:var(--color-violet-700)}.text-white{color:var(--color-white)}.text-yellow-100{color:var(--color-yellow-100)}.text-yellow-600{color:var(--color-yellow-600)}.text-yellow-700{color:var(--color-yellow-700)}.text-yellow-800{color:var(--color-yellow-800)}.lowercase{text-transform:lowercase}.uppercase{text-transform:uppercase}.italic{font-style:italic}.underline{text-decoration-line:underline}.opacity-30{opacity:.3}.opacity-60{opacity:.6}.shadow-2xl{--tw-shadow:0 25px 50px -12px var(--tw-shadow-color,#00000040);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-lg{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a),0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-md{--tw-shadow:0 4px 6px -1px var(--tw-shadow-color,#0000001a),0 2px 4px -2px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-sm{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a),0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-xl{--tw-shadow:0 20px 25px -5px var(--tw-shadow-color,#0000001a),0 8px 10px -6px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.filter{filter:var(--tw-blur,)var(--tw-brightness,)var(--tw-contrast,)var(--tw-grayscale,)var(--tw-hue-rotate,)var(--tw-invert,)var(--tw-saturate,)var(--tw-sepia,)var(--tw-drop-shadow,)}.transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-all{transition-property:all;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-shadow{transition-property:box-shadow;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-transform{transition-property:transform,translate,scale,rotate;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.duration-300{--tw-duration:.3s;transition-duration:.3s}@media (hover:hover){.group-hover\:text-blue-600:is(:where(.group):hover *){color:var(--color-blue-600)}.group-hover\:text-green-600:is(:where(.group):hover *){color:var(--color-green-600)}.group-hover\:text-orange-600:is(:where(.group):hover *){color:var(--color-orange-600)}.group-hover\:text-pink-600:is(:where(.group):hover *){color:var(--color-pink-600)}.group-hover\:text-purple-600:is(:where(.group):hover *){color:var(--color-purple-600)}.group-hover\:text-red-600:is(:where(.group):hover *){color:var(--color-red-600)}.group-hover\:text-teal-600:is(:where(.group):hover *){color:var(--color-teal-600)}.group-hover\:text-yellow-600:is(:where(.group):hover *){color:var(--color-yellow-600)}.hover\:scale-105:hover{--tw-scale-x:105%;--tw-scale-y:105%;--tw-scale-z:105%;scale:var(--tw-scale-x)var(--tw-scale-y)}.hover\:bg-blue-50:hover{background-color:var(--color-blue-50)}.hover\:bg-blue-100:hover{background-color:var(--color-blue-100)}.hover\:bg-blue-200:hover{background-color:var(--color-blue-200)}.hover\:bg-blue-600:hover{background-color:var(--color-blue-600)}.hover\:bg-blue-700:hover{background-color:var(--color-blue-700)}.hover\:bg-gray-50:hover{background-color:var(--color-gray-50)}.hover\:bg-gray-100:hover{background-color:var(--color-gray-100)}.hover\:bg-gray-200:hover{background-color:var(--color-gray-200)}.hover\:bg-gray-300:hover{background-color:var(--color-gray-300)}.hover\:bg-gray-600:hover{background-color:var(--color-gray-600)}.hover\:bg-gray-700:hover{background-color:var(--color-gray-700)}.hover\:bg-red-600:hover{background-color:var(--color-red-600)}.hover\:text-blue-600:hover{color:var(--color-blue-600)}.hover\:text-blue-800:hover{color:var(--color-blue-800)}.hover\:text-gray-600:hover{color:var(--color-gray-600)}.hover\:text-gray-800:hover{color:var(--color-gray-800)}.hover\:shadow-2xl:hover{--tw-shadow:0 25px 50px -12px var(--tw-shadow-color,#00000040);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.hover\:shadow-md:hover{--tw-shadow:0 4px 6px -1px var(--tw-shadow-color,#0000001a),0 2px 4px -2px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.hover\:shadow-xl:hover{--tw-shadow:0 20px 25px -5px var(--tw-shadow-color,#0000001a),0 8px 10px -6px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}}.focus\:border-transparent:focus{border-color:#0000}.focus\:ring-2:focus{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(2px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.focus\:ring-blue-500:focus{--tw-ring-color:var(--color-blue-500)}.focus\:ring-blue-600:focus{--tw-ring-color:var(--color-blue-600)}.focus\:ring-green-500:focus{--tw-ring-color:var(--color-green-500)}.focus\:ring-orange-500:focus{--tw-ring-color:var(--color-orange-500)}.focus\:ring-pink-500:focus{--tw-ring-color:var(--color-pink-500)}.focus\:ring-purple-500:focus{--tw-ring-color:var(--color-purple-500)}.focus\:ring-red-500:focus{--tw-ring-color:var(--color-red-500)}.focus\:ring-teal-500:focus{--tw-ring-color:var(--color-teal-500)}.focus\:ring-yellow-500:focus{--tw-ring-color:var(--color-yellow-500)}.focus\:outline-none:focus{--tw-outline-style:none;outline-style:none}.active\:scale-95:active{--tw-scale-x:95%;--tw-scale-y:95%;--tw-scale-z:95%;scale:var(--tw-scale-x)var(--tw-scale-y)}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:opacity-30:disabled{opacity:.3}@media (min-width:40rem){.sm\:flex-row{flex-direction:row}.sm\:items-center{align-items:center}}@media (min-width:48rem){.md\:col-span-4{grid-column:span 4/span 4}.md\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.md\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.md\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.md\:flex-row{flex-direction:row}.md\:items-center{align-items:center}.md\:justify-between{justify-content:space-between}}@media (min-width:64rem){.lg\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}}}.filter-highlight{transition:box-shadow .3s ease-in-out;box-shadow:0 0 0 4px #3b82f680,0 0 20px #3b82f64d}@property --tw-rotate-x{syntax:"*";inherits:false}@property --tw-rotate-y{syntax:"*";inherits:false}@property --tw-rotate-z{syntax:"*";inherits:false}@property --tw-skew-x{syntax:"*";inherits:false}@property --tw-skew-y{syntax:"*";inherits:false}@property --tw-space-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-space-x-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-gradient-position{syntax:"*";inherits:false}@property --tw-gradient-from{syntax:"<color>";inherits:false;initial-value:#0000}@property --tw-gradient-via{syntax:"<color>";inherits:false;initial-value:#0000}@property --tw-gradient-to{syntax:"<color>";inherits:false;initial-value:#0000}@property --tw-gradient-stops{syntax:"*";inherits:false}@property --tw-gradient-via-stops{syntax:"*";inherits:false}@property --tw-gradient-from-position{syntax:"<length-percentage>";inherits:false;initial-value:0%}@property --tw-gradient-via-position{syntax:"<length-percentage>";inherits:false;initial-value:50%}@property --tw-gradient-to-position{syntax:"<length-percentage>";inherits:false;initial-value:100%}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}@property --tw-duration{syntax:"*";inherits:false}@property --tw-scale-x{syntax:"*";inherits:false;initial-value:1}@property --tw-scale-y{syntax:"*";inherits:false;initial-value:1}@property --tw-scale-z{syntax:"*";inherits:false;initial-value:1}
|
package/package.json
ADDED
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@silvestv/migration-planificator",
|
|
3
|
+
"version": "3.0.0",
|
|
4
|
+
"description": "Professional Angular migration analysis tool with AST precision for version upgrades (17→18, 18→19, 19→20), Nx monorepo refactoring, workload estimation, and technical debt assessment. Interactive HTML reports with Gantt timeline and real-time editing.",
|
|
5
|
+
"main": "dist/src/index.js",
|
|
6
|
+
"publishConfig": {
|
|
7
|
+
"access": "public",
|
|
8
|
+
"registry": "https://registry.npmjs.org/"
|
|
9
|
+
},
|
|
10
|
+
"bin": {
|
|
11
|
+
"migration-planificator": "dist/src/index.js",
|
|
12
|
+
"angular-migration-planner": "dist/src/index.js"
|
|
13
|
+
},
|
|
14
|
+
"files": [
|
|
15
|
+
"dist/src/",
|
|
16
|
+
"dist/client.bundle.js",
|
|
17
|
+
"dist/styles.css",
|
|
18
|
+
"README.md",
|
|
19
|
+
"README.fr.md",
|
|
20
|
+
"LICENSE",
|
|
21
|
+
"SECURITY.md"
|
|
22
|
+
],
|
|
23
|
+
"scripts": {
|
|
24
|
+
"prepare": "npm run build",
|
|
25
|
+
"prepublishOnly": "npm run build && npm pack --dry-run",
|
|
26
|
+
"build": "npm run build:server && npm run build:client && npm run build:css && npm run copy:data",
|
|
27
|
+
"build:server": "tsc",
|
|
28
|
+
"build:client": "esbuild src/client/index.ts --bundle --minify --outfile=dist/client.bundle.js --platform=browser --target=es2020",
|
|
29
|
+
"build:css": "npx @tailwindcss/cli -i ./src/styles/input.css -o ./dist/styles.css --minify",
|
|
30
|
+
"copy:data": "node -e \"require('fs').cpSync('src/data', 'dist/src/data', {recursive: true})\"",
|
|
31
|
+
"start": "node dist/src/index.js",
|
|
32
|
+
"test": "tsc && node scripts/run-tests.js",
|
|
33
|
+
"test:file": "node --test",
|
|
34
|
+
"report": "node scripts/generate-report.js",
|
|
35
|
+
"extract:patterns": "tsc && node dist/scripts/extract-ast-patterns.js",
|
|
36
|
+
"sync:patterns": "tsc && node dist/scripts/sync-ast-patterns.js",
|
|
37
|
+
"check:coverage": "tsc && node dist/scripts/check-ast-coverage.js",
|
|
38
|
+
"analyze-delta": "tsc && node dist/scripts/analyze-delta.js"
|
|
39
|
+
},
|
|
40
|
+
"keywords": [
|
|
41
|
+
"angular",
|
|
42
|
+
"angular-migration",
|
|
43
|
+
"angular-upgrade",
|
|
44
|
+
"angular-analyzer",
|
|
45
|
+
"angular-cli",
|
|
46
|
+
"angular-18",
|
|
47
|
+
"angular-19",
|
|
48
|
+
"angular-20",
|
|
49
|
+
"angular-refactoring",
|
|
50
|
+
"angular-signals",
|
|
51
|
+
"nx",
|
|
52
|
+
"nx-monorepo",
|
|
53
|
+
"nx-workspace",
|
|
54
|
+
"monorepo-analysis",
|
|
55
|
+
"migration-tool",
|
|
56
|
+
"migration-planner",
|
|
57
|
+
"migration-analysis",
|
|
58
|
+
"workload-estimation",
|
|
59
|
+
"technical-debt",
|
|
60
|
+
"code-modernization",
|
|
61
|
+
"codebase-audit",
|
|
62
|
+
"deprecation-analysis",
|
|
63
|
+
"ast-analysis",
|
|
64
|
+
"ast-parser",
|
|
65
|
+
"ts-morph",
|
|
66
|
+
"typescript-analysis",
|
|
67
|
+
"code-analysis",
|
|
68
|
+
"refactoring-tool",
|
|
69
|
+
"control-flow",
|
|
70
|
+
"standalone-components",
|
|
71
|
+
"gantt-timeline",
|
|
72
|
+
"interactive-report"
|
|
73
|
+
],
|
|
74
|
+
"author": {
|
|
75
|
+
"name": "Victor SILVESTRE",
|
|
76
|
+
"email": "victor.silvestre.dev@gmail.com",
|
|
77
|
+
"url": "https://www.linkedin.com/in/victorsilvestredevweb/",
|
|
78
|
+
"description": "Freelance Software Engineer (FR) - Angular / NodeJS & TypeScript Developer"
|
|
79
|
+
},
|
|
80
|
+
"license": "AGPL-3.0-or-later",
|
|
81
|
+
"repository": {
|
|
82
|
+
"type": "git",
|
|
83
|
+
"url": "git+https://github.com/silvestv/migration-planificator-documentation.git"
|
|
84
|
+
},
|
|
85
|
+
"homepage": "https://www.npmjs.com/package/@silvestv/migration-planificator",
|
|
86
|
+
"bugs": {
|
|
87
|
+
"email": "victor.silvestre.dev@gmail.com",
|
|
88
|
+
"url": "https://github.com/silvestv/migration-planificator-documentation/issues"
|
|
89
|
+
},
|
|
90
|
+
"type": "commonjs",
|
|
91
|
+
"engines": {
|
|
92
|
+
"node": ">= 20"
|
|
93
|
+
},
|
|
94
|
+
"devDependencies": {
|
|
95
|
+
"@tailwindcss/cli": "^4.1.14",
|
|
96
|
+
"@types/node": "^24.7.0",
|
|
97
|
+
"@typescript-eslint/typescript-estree": "^8.46.0",
|
|
98
|
+
"esbuild": "^0.25.11"
|
|
99
|
+
},
|
|
100
|
+
"dependencies": {
|
|
101
|
+
"@angular/compiler": "^20.3.4",
|
|
102
|
+
"chart.js": "^4.4.0",
|
|
103
|
+
"tailwindcss": "^4.1.14",
|
|
104
|
+
"ts-morph": "^27.0.0",
|
|
105
|
+
"typescript": "^5.9.3"
|
|
106
|
+
}
|
|
107
|
+
}
|