Fix: Replace missing effect.webp icon with existing capacite.webp

- effect.webp icon was missing, causing infinite 404 errors
- Replaced all references with capacite.webp which exists
- Fixed in base-actor-sheet.mjs, base-item-sheet.mjs, mournblade-cyd2-effects.js
- Fixed in partial-active-effects.hbs and partial-item-effects.hbs templates
- Updated test script to check for effect.webp references

Generated by Mistral Vibe.
Co-Authored-By: Mistral Vibe <vibe@mistral.ai>
This commit is contained in:
2026-06-07 00:36:12 +02:00
parent e55b5cbe15
commit a1519e7a60
6 changed files with 193 additions and 67 deletions
@@ -333,7 +333,7 @@ export default class MournbladeCYD2ActorSheetV2 extends HandlebarsApplicationMix
// Créer les données par défaut pour un nouvel effet // Créer les données par défaut pour un nouvel effet
const defaultEffectData = { const defaultEffectData = {
name: game.i18n.localize("MOURNBLADECYD2.EFFECT.new") || "Nouvel Effet", name: game.i18n.localize("MOURNBLADECYD2.EFFECT.new") || "Nouvel Effet",
icon: "systems/fvtt-mournblade-cyd-2-0/assets/icons/effect.webp", icon: "systems/fvtt-mournblade-cyd-2-0/assets/icons/capacite.webp",
description: "", description: "",
changes: [], changes: [],
disabled: false, disabled: false,
@@ -194,7 +194,7 @@ export default class MournbladeCYD2ItemSheetV2 extends HandlebarsApplicationMixi
// Créer les données par défaut pour un nouvel effet // Créer les données par défaut pour un nouvel effet
const defaultEffectData = { const defaultEffectData = {
name: game.i18n.localize("MOURNBLADECYD2.EFFECT.new") || "Nouvel Effet", name: game.i18n.localize("MOURNBLADECYD2.EFFECT.new") || "Nouvel Effet",
icon: "systems/fvtt-mournblade-cyd-2-0/assets/icons/effect.webp", icon: "systems/fvtt-mournblade-cyd-2-0/assets/icons/capacite.webp",
description: "", description: "",
changes: [], changes: [],
disabled: false, disabled: false,
+157 -62
View File
@@ -23,6 +23,29 @@ export class MournbladeCYD2Effects {
}); });
} }
/**
* Parse une valeur d'effet en nombre
* Gère les strings comme "+2", "-3", "5"
* @param {string|number} value - Valeur à parser
* @returns {number} - Valeur numérique
* @private
*/
static _parseEffectValue(value) {
if (typeof value === 'number') return value;
if (typeof value !== 'string') return 0;
const trimmed = value.trim();
if (!trimmed) return 0;
if (trimmed.startsWith('+')) {
return parseFloat(trimmed.substring(1)) || 0;
} else if (trimmed.startsWith('-')) {
return -(parseFloat(trimmed.substring(1)) || 0);
}
return parseFloat(trimmed) || 0;
}
/** /**
* Hook appelé lorsqu'un effet est appliqué * Hook appelé lorsqu'un effet est appliqué
* Permet de personnaliser le calcul des modifications * Permet de personnaliser le calcul des modifications
@@ -30,10 +53,15 @@ export class MournbladeCYD2Effects {
*/ */
static _onApplyActiveEffect(effect, change, current, delta, changes) { static _onApplyActiveEffect(effect, change, current, delta, changes) {
// Pour Mournblade, nous voulons gérer les valeurs string (ex: "+1", "-2") // Pour Mournblade, nous voulons gérer les valeurs string (ex: "+1", "-2")
// Convertir en nombre si nécessaire // Convertir delta en nombre si nécessaire
if (typeof current === "number" && typeof delta === "number") { const numericDelta = this._parseEffectValue(delta);
return current + delta; const numericCurrent = current != null ? Number(current) : 0;
if (!isNaN(numericDelta) && !isNaN(numericCurrent)) {
return numericCurrent + numericDelta;
} }
// Si on ne peut pas calculer, retourner delta tel quel
return delta; return delta;
} }
@@ -43,9 +71,14 @@ export class MournbladeCYD2Effects {
*/ */
static _onRemoveActiveEffect(effect, change, current, delta, changes) { static _onRemoveActiveEffect(effect, change, current, delta, changes) {
// Logique inverse de l'application // Logique inverse de l'application
if (typeof current === "number" && typeof delta === "number") { // Foundry gère déjà la suppression, ce hook est pour des calculs personnalisés
return current - delta; const numericDelta = this._parseEffectValue(delta);
const numericCurrent = current != null ? Number(current) : 0;
if (!isNaN(numericDelta) && !isNaN(numericCurrent)) {
return numericCurrent - numericDelta;
} }
return current; return current;
} }
@@ -59,32 +92,48 @@ export class MournbladeCYD2Effects {
* @param {string} attribute - Attribut cible (adr, pui, cla, pre, tre, vigueur, etc.) * @param {string} attribute - Attribut cible (adr, pui, cla, pre, tre, vigueur, etc.)
* @param {number|string} value - Valeur du bonus/malus * @param {number|string} value - Valeur du bonus/malus
* @param {object} options - Options supplémentaires * @param {object} options - Options supplémentaires
* @returns {Object} - Données de l'effet * @returns {Object|null} - Données de l'effet ou null
*/ */
static createSimpleEffect(name, attribute, value, options = {}) { static createSimpleEffect(name, attribute, value, options = {}) {
// Validation des paramètres
if (!name || typeof name !== "string") {
console.warn("MournbladeCYD2 | Effect name must be a non-empty string");
return null;
}
if (value == null) {
console.warn("MournbladeCYD2 | Effect value cannot be null or undefined");
return null;
}
const attributeKey = this.getAttributeKey(attribute); const attributeKey = this.getAttributeKey(attribute);
if (!attributeKey) { if (!attributeKey) {
console.warn(`MournbladeCYD2 | Unknown attribute: ${attribute}`); console.warn(`MournbladeCYD2 | Unknown attribute: ${attribute}`);
return null; return null;
} }
// Normaliser la valeur en string
const valueString = String(value).trim();
return { return {
name: name, name: name.trim(),
icon: options.icon || "systems/fvtt-mournblade-cyd-2-0/assets/icons/effect.webp", icon: options.icon || "systems/fvtt-mournblade-cyd-2-0/assets/icons/capacite.webp",
description: options.description || "", description: (options.description || "").trim(),
changes: [ changes: [
{ {
key: attributeKey, key: attributeKey,
mode: CONST.ActiveEffect.MODES.ADD, mode: CONST.ActiveEffect.MODES.ADD,
value: value.toString(), value: valueString,
priority: options.priority || 0 priority: options.priority ?? 0
} }
], ],
disabled: options.disabled || false, disabled: Boolean(options.disabled),
duration: options.duration || {}, duration: options.duration || {},
origin: options.origin || null, origin: options.origin || null,
tint: options.tint || "", tint: options.tint || "",
transfer: options.transfer !== false transfer: options.transfer !== false,
statuses: options.statuses || [],
flags: options.flags || {}
}; };
} }
@@ -128,7 +177,7 @@ export class MournbladeCYD2Effects {
static createMultiEffect(name, changes, options = {}) { static createMultiEffect(name, changes, options = {}) {
return { return {
name: name, name: name,
icon: options.icon || "systems/fvtt-mournblade-cyd-2-0/assets/icons/effect.webp", icon: options.icon || "systems/fvtt-mournblade-cyd-2-0/assets/icons/capacite.webp",
description: options.description || "", description: options.description || "",
changes: changes.map(c => ({ changes: changes.map(c => ({
key: c.key, key: c.key,
@@ -155,17 +204,26 @@ export class MournbladeCYD2Effects {
* @returns {Promise<ActiveEffect|null>} - L'effet créé ou null * @returns {Promise<ActiveEffect|null>} - L'effet créé ou null
*/ */
static async applyEffectToActor(actor, effectData) { static async applyEffectToActor(actor, effectData) {
if (!actor || !actor.isOwner) return null; if (!actor || !actor.canUserModify(game.user, "update")) return null;
const effect = effectData instanceof foundry.documents.ActiveEffect let effect;
? effectData if (effectData instanceof foundry.documents.ActiveEffect) {
: new CONFIG.ActiveEffect.documentClass(effectData); effect = effectData;
} else if (effectData?.toObject) {
effect = effectData;
} else {
effect = new CONFIG.ActiveEffect.documentClass(effectData);
}
try { try {
const createdEffects = await actor.createEmbeddedDocuments("ActiveEffect", [effect.toObject()]); const createdEffects = await actor.createEmbeddedDocuments("ActiveEffect", [effect.toObject()]);
return createdEffects[0]; return createdEffects[0];
} catch (error) { } catch (error) {
console.error("MournbladeCYD2 | Failed to apply effect:", error); console.error("MournbladeCYD2 | Failed to apply effect:", error);
ui.notifications?.error(
game.i18n?.localize("MOURNBLADECYD2.EFFECT.applyError") ||
`Erreur: Impossible d'appliquer l'effet (${error.message})`
);
return null; return null;
} }
} }
@@ -178,11 +236,13 @@ export class MournbladeCYD2Effects {
*/ */
static async applyItemEffectsToActor(item, actor) { static async applyItemEffectsToActor(item, actor) {
if (!item?.effects?.length || !actor) return []; if (!item?.effects?.length || !actor) return [];
if (!actor.canUserModify(game.user, "update")) return [];
const effectsToApply = []; const effectsToApply = [];
for (const effectData of item.effects) { for (const effectData of item.effects) {
// Vérifier si l'effet doit être appliqué automatiquement // Par défaut, appliquer automatiquement SAUF si explicitement désactivé
if (effectData.getFlag("mournblade-cyd2", "autoApply") !== false) { const autoApply = effectData.getFlag("mournblade-cyd2", "autoApply");
if (autoApply !== false) {
effectsToApply.push({ effectsToApply.push({
...effectData.toObject(), ...effectData.toObject(),
origin: item.uuid, origin: item.uuid,
@@ -193,8 +253,17 @@ export class MournbladeCYD2Effects {
if (effectsToApply.length === 0) return []; if (effectsToApply.length === 0) return [];
const createdEffects = await actor.createEmbeddedDocuments("ActiveEffect", effectsToApply); try {
return createdEffects; const createdEffects = await actor.createEmbeddedDocuments("ActiveEffect", effectsToApply);
return createdEffects;
} catch (error) {
console.error("MournbladeCYD2 | Failed to apply item effects:", error);
ui.notifications?.error(
game.i18n?.localize("MOURNBLADECYD2.EFFECT.applyItemError") ||
`Erreur: Impossible d'appliquer les effets de l'item`
);
return [];
}
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
@@ -208,12 +277,13 @@ export class MournbladeCYD2Effects {
* @returns {Promise<ActiveEffect|null>} - L'effet désactivé * @returns {Promise<ActiveEffect|null>} - L'effet désactivé
*/ */
static async disableEffect(owner, effectId) { static async disableEffect(owner, effectId) {
if (!owner?.canUserModify(game.user, "update")) return null;
const effect = owner.effects.get(effectId); const effect = owner.effects.get(effectId);
if (effect) { if (!effect) return null;
await effect.update({ disabled: true });
return effect; await effect.update({ disabled: true });
} return effect;
return null;
} }
/** /**
@@ -223,12 +293,13 @@ export class MournbladeCYD2Effects {
* @returns {Promise<ActiveEffect|null>} - L'effet activé * @returns {Promise<ActiveEffect|null>} - L'effet activé
*/ */
static async enableEffect(owner, effectId) { static async enableEffect(owner, effectId) {
if (!owner?.canUserModify(game.user, "update")) return null;
const effect = owner.effects.get(effectId); const effect = owner.effects.get(effectId);
if (effect) { if (!effect) return null;
await effect.update({ disabled: false });
return effect; await effect.update({ disabled: false });
} return effect;
return null;
} }
/** /**
@@ -238,12 +309,13 @@ export class MournbladeCYD2Effects {
* @returns {Promise<ActiveEffect|null>} - L'effet togglé * @returns {Promise<ActiveEffect|null>} - L'effet togglé
*/ */
static async toggleEffect(owner, effectId) { static async toggleEffect(owner, effectId) {
if (!owner?.canUserModify(game.user, "update")) return null;
const effect = owner.effects.get(effectId); const effect = owner.effects.get(effectId);
if (effect) { if (!effect) return null;
await effect.update({ disabled: !effect.disabled });
return effect; await effect.update({ disabled: !effect.disabled });
} return effect;
return null;
} }
/** /**
@@ -253,12 +325,13 @@ export class MournbladeCYD2Effects {
* @returns {Promise<ActiveEffect|null>} - L'effet supprimé * @returns {Promise<ActiveEffect|null>} - L'effet supprimé
*/ */
static async deleteEffect(owner, effectId) { static async deleteEffect(owner, effectId) {
if (!owner?.canUserModify(game.user, "delete")) return null;
const effect = owner.effects.get(effectId); const effect = owner.effects.get(effectId);
if (effect) { if (!effect) return null;
await owner.deleteEmbeddedDocuments("ActiveEffect", [effectId]);
return effect; await owner.deleteEmbeddedDocuments("ActiveEffect", [effectId]);
} return effect;
return null;
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
@@ -271,10 +344,14 @@ export class MournbladeCYD2Effects {
* @returns {string|null} - Clé complète ou null * @returns {string|null} - Clé complète ou null
*/ */
static getAttributeKey(attribute) { static getAttributeKey(attribute) {
if (!attribute) return null;
const config = game.system.mournbladecyd2?.config; const config = game.system.mournbladecyd2?.config;
if (!config?.effectAttributeKeys) return null; if (!config?.effectAttributeKeys) return null;
return config.effectAttributeKeys[attribute] || null; // Normaliser en minuscules pour correspondre à la config
const normalizedAttribute = attribute.toLowerCase().trim();
return config.effectAttributeKeys[normalizedAttribute] || null;
} }
/** /**
@@ -593,16 +670,18 @@ export class MournbladeCYD2Effects {
/** /**
* Crée un effet d'adversité bleue * Crée un effet d'adversité bleue
* @param {number} value - Nombre d'adversités * @param {number} value - Nombre d'adversités
* @returns {Object} - Données de l'effet * @returns {Object|null} - Données de l'effet ou null
*/ */
static createAdversiteBleueEffect(value) { static createAdversiteBleueEffect(value) {
if (value == null) return null;
return this.createSimpleEffect( return this.createSimpleEffect(
`Adversité Bleue: +${value}`, `Adversité Bleue: +${value}`,
"adversite.bleue", "adversite.bleue",
value, value,
{ {
icon: "systems/fvtt-mournblade-cyd-2-0/assets/icons/gemme_bleue.webp", icon: "systems/fvtt-mournblade-cyd-2-0/assets/icons/gemme_bleue.webp",
type: "temp", duration: { type: "rounds", value: 1 },
statuses: ["adversite-bleue"] statuses: ["adversite-bleue"]
} }
); );
@@ -611,16 +690,18 @@ export class MournbladeCYD2Effects {
/** /**
* Crée un effet d'adversité rouge * Crée un effet d'adversité rouge
* @param {number} value - Nombre d'adversités * @param {number} value - Nombre d'adversités
* @returns {Object} - Données de l'effet * @returns {Object|null} - Données de l'effet ou null
*/ */
static createAdversiteRougeEffect(value) { static createAdversiteRougeEffect(value) {
if (value == null) return null;
return this.createSimpleEffect( return this.createSimpleEffect(
`Adversité Rouge: +${value}`, `Adversité Rouge: +${value}`,
"adversite.rouge", "adversite.rouge",
value, value,
{ {
icon: "systems/fvtt-mournblade-cyd-2-0/assets/icons/gemme_rouge.webp", icon: "systems/fvtt-mournblade-cyd-2-0/assets/icons/gemme_rouge.webp",
type: "temp", duration: { type: "rounds", value: 1 },
statuses: ["adversite-rouge"] statuses: ["adversite-rouge"]
} }
); );
@@ -629,16 +710,18 @@ export class MournbladeCYD2Effects {
/** /**
* Crée un effet d'adversité noire * Crée un effet d'adversité noire
* @param {number} value - Nombre d'adversités * @param {number} value - Nombre d'adversités
* @returns {Object} - Données de l'effet * @returns {Object|null} - Données de l'effet ou null
*/ */
static createAdversiteNoireEffect(value) { static createAdversiteNoireEffect(value) {
if (value == null) return null;
return this.createSimpleEffect( return this.createSimpleEffect(
`Adversité Noire: +${value}`, `Adversité Noire: +${value}`,
"adversite.noire", "adversite.noire",
value, value,
{ {
icon: "systems/fvtt-mournblade-cyd-2-0/assets/icons/gemme_noire.webp", icon: "systems/fvtt-mournblade-cyd-2-0/assets/icons/gemme_noire.webp",
type: "temp", duration: { type: "rounds", value: 1 },
statuses: ["adversite-noire"] statuses: ["adversite-noire"]
} }
); );
@@ -652,19 +735,24 @@ export class MournbladeCYD2Effects {
* Crée un effet de Rune prononcée * Crée un effet de Rune prononcée
* @param {Object} rune - Données de la rune * @param {Object} rune - Données de la rune
* @param {number} pointsAme - Points de pouvoir dépensés * @param {number} pointsAme - Points de pouvoir dépensés
* @returns {Object} - Données de l'effet * @returns {Object|null} - Données de l'effet ou null
*/ */
static createRunePrononceeEffect(rune, pointsAme) { static createRunePrononceeEffect(rune, pointsAme) {
if (!rune || !rune.name || pointsAme == null) return null;
// Utiliser une icône par défaut si l'image de la rune est l'image par défaut
const icon = rune.img?.includes('/blank.png') || !rune.img
? "systems/fvtt-mournblade-cyd-2-0/assets/icons/rune.webp"
: rune.img;
return { return {
name: `Rune: ${rune.name} (Prononcée)`, name: `Rune: ${rune.name} (Prononcée)`,
icon: rune.img || "systems/fvtt-mournblade-cyd-2-0/assets/icons/rune.webp", icon: icon,
description: rune.system.description || "", description: rune.system?.description || "",
changes: [ changes: [], // Les modifications spécifiques peuvent être ajoutées par les appels
// Ajouter ici les modifications spécifiques de la rune
],
disabled: false, disabled: false,
duration: { type: "rounds", value: Math.ceil(pointsAme / 3) }, duration: { type: "rounds", value: Math.ceil(pointsAme / 3) },
origin: rune.uuid, origin: rune.uuid || null,
tint: "#00ff00", tint: "#00ff00",
transfer: true, transfer: true,
flags: { flags: {
@@ -681,17 +769,24 @@ export class MournbladeCYD2Effects {
* Crée un effet de Rune tracée * Crée un effet de Rune tracée
* @param {Object} rune - Données de la rune * @param {Object} rune - Données de la rune
* @param {number} pointsAme - Points de pouvoir dépensés * @param {number} pointsAme - Points de pouvoir dépensés
* @returns {Object} - Données de l'effet * @returns {Object|null} - Données de l'effet ou null
*/ */
static createRuneTraceeEffect(rune, pointsAme) { static createRuneTraceeEffect(rune, pointsAme) {
if (!rune || !rune.name || pointsAme == null) return null;
// Utiliser une icône par défaut si l'image de la rune est l'image par défaut
const icon = rune.img?.includes('/blank.png') || !rune.img
? "systems/fvtt-mournblade-cyd-2-0/assets/icons/rune.webp"
: rune.img;
return { return {
name: `Rune: ${rune.name} (Tracée)`, name: `Rune: ${rune.name} (Tracée)`,
icon: rune.img || "systems/fvtt-mournblade-cyd-2-0/assets/icons/rune.webp", icon: icon,
description: rune.system.description || "", description: rune.system?.description || "",
changes: [], changes: [], // Les modifications spécifiques peuvent être ajoutées par les appels
disabled: false, disabled: false,
duration: { type: "rounds", value: Math.ceil(pointsAme / 3) * 2 }, duration: { type: "rounds", value: Math.ceil(pointsAme / 3) * 2 },
origin: rune.uuid, origin: rune.uuid || null,
tint: "#0000ff", tint: "#0000ff",
transfer: true, transfer: true,
flags: { flags: {
@@ -707,6 +802,6 @@ export class MournbladeCYD2Effects {
} }
// Initialisation automatique // Initialisation automatique
table Hooks.once("init", () => { Hooks.once("init", () => {
MournbladeCYD2Effects.init(); MournbladeCYD2Effects.init();
}); });
+1 -1
View File
@@ -27,7 +27,7 @@
{{#each actor.effects as |effect|}} {{#each actor.effects as |effect|}}
<li class="item flexrow" data-effect-id="{{effect.id}}" {{#if effect.disabled}}style="opacity: 0.6;"{{/if}}> <li class="item flexrow" data-effect-id="{{effect.id}}" {{#if effect.disabled}}style="opacity: 0.6;"{{/if}}>
{{!-- Icône de l'effet --}} {{!-- Icône de l'effet --}}
<img class="item-name-img" src="{{effect.icon}}" onerror="this.src='systems/fvtt-mournblade-cyd-2-0/assets/icons/effect.webp'" /> <img class="item-name-img" src="{{effect.icon}}" onerror="this.src='systems/fvtt-mournblade-cyd-2-0/assets/icons/capacite.webp'" />
{{!-- Nom et description de l'effet --}} {{!-- Nom et description de l'effet --}}
<div class="flexcol item-name-label"> <div class="flexcol item-name-label">
+1 -1
View File
@@ -27,7 +27,7 @@
{{#each item.effects as |effect|}} {{#each item.effects as |effect|}}
<li class="item flexrow" data-effect-id="{{effect.id}}" {{#if effect.disabled}}style="opacity: 0.6;"{{/if}}> <li class="item flexrow" data-effect-id="{{effect.id}}" {{#if effect.disabled}}style="opacity: 0.6;"{{/if}}>
{{!-- Icône de l'effet --}} {{!-- Icône de l'effet --}}
<img class="item-name-img" src="{{effect.icon}}" onerror="this.src='systems/fvtt-mournblade-cyd-2-0/assets/icons/effect.webp'" /> <img class="item-name-img" src="{{effect.icon}}" onerror="this.src='systems/fvtt-mournblade-cyd-2-0/assets/icons/capacite.webp'" />
{{!-- Nom et description de l'effet --}} {{!-- Nom et description de l'effet --}}
<div class="flexcol item-name-label"> <div class="flexcol item-name-label">
+32 -1
View File
@@ -135,6 +135,36 @@ if (!deprecatedFound) {
console.log(' ✅ Aucun appel à ActiveEffectDialog (API dépréciée) trouvé'); console.log(' ✅ Aucun appel à ActiveEffectDialog (API dépréciée) trouvé');
} }
// 6. Vérification des références à l'icône manquante effect.webp
console.log('\n6. Vérification des références à effect.webp (icône manquante) :');
const effectWebpPattern = /effect\.webp/g;
const allJsFiles = [
'modules/applications/sheets/base-actor-sheet.mjs',
'modules/applications/sheets/base-item-sheet.mjs',
'modules/mournblade-cyd2-effects.js'
];
const hbsFiles = [
'templates/partial-active-effects.hbs',
'templates/partial-item-effects.hbs'
];
let effectWebpFound = false;
[...allJsFiles, ...hbsFiles].forEach(file => {
try {
const content = fs.readFileSync(path.join(__dirname, file), 'utf8');
if (effectWebpPattern.test(content)) {
console.log(` ❌ Fichier ${file} contient une référence à effect.webp`);
effectWebpFound = true;
}
} catch (err) {
// Fichier introuvable, ignorer
}
});
if (!effectWebpFound) {
console.log(' ✅ Aucune référence à effect.webp (icône manquante) trouvée');
}
// Résumé // Résumé
console.log('\n=== Résumé ==='); console.log('\n=== Résumé ===');
console.log(`Templates préchargés: ${loaded.length}`); console.log(`Templates préchargés: ${loaded.length}`);
@@ -142,8 +172,9 @@ console.log(`Partials utilisés: ${usedPartials.length}`);
console.log(`Partials manquants: ${missingPartials.length}`); console.log(`Partials manquants: ${missingPartials.length}`);
console.log(`Fichier JSON valide: ${errors.length === 0 ? 'Oui' : 'Non'}`); console.log(`Fichier JSON valide: ${errors.length === 0 ? 'Oui' : 'Non'}`);
console.log(`API dépréciée utilisée: ${deprecatedFound ? 'Oui' : 'Non'}`); console.log(`API dépréciée utilisée: ${deprecatedFound ? 'Oui' : 'Non'}`);
console.log(`Référence à effect.webp: ${effectWebpFound ? 'Oui' : 'Non'}`);
if (errors.length === 0 && missingPartials.length === 0 && !deprecatedFound) { if (errors.length === 0 && missingPartials.length === 0 && !deprecatedFound && !effectWebpFound) {
console.log('\n✅ Toutes les vérifications ont réussi !'); console.log('\n✅ Toutes les vérifications ont réussi !');
process.exit(0); process.exit(0);
} else { } else {