Compare commits

...
3 Commits
22 changed files with 1731 additions and 873 deletions
+2
View File
@@ -150,3 +150,5 @@ app.*.symbols
.gclient_previous_custom_vars .gclient_previous_custom_vars
.gclient_previous_sync_commits .gclient_previous_sync_commits
em2rp/lib/config/env.dart em2rp/lib/config/env.dart
em2rp/lib/config/env.dart
+14 -13
View File
@@ -19,6 +19,7 @@ canvaskit/canvaskit.js,1759914809082,bb9141a62dec1f0a41e311b845569915df9ebb5f074
canvaskit/chromium/canvaskit.wasm,1759914809184,4a868d7961a9740ae6694f62fc15b2b0ed76df50598e8311d61e8ee814d78229 canvaskit/chromium/canvaskit.wasm,1759914809184,4a868d7961a9740ae6694f62fc15b2b0ed76df50598e8311d61e8ee814d78229
canvaskit/chromium/canvaskit.js.symbols,1759914809141,f395278c466a0eaed0201edd6b14a3aa8fee0a16bfedee2d239835cd7e865472 canvaskit/chromium/canvaskit.js.symbols,1759914809141,f395278c466a0eaed0201edd6b14a3aa8fee0a16bfedee2d239835cd7e865472
canvaskit/chromium/canvaskit.js,1759914809136,ce5184f74e2501d849490df34d0506167a0708b9120be088039b785343335664 canvaskit/chromium/canvaskit.js,1759914809136,ce5184f74e2501d849490df34d0506167a0708b9120be088039b785343335664
assets/packages/flutter_map/lib/assets/flutter_map_logo.png,1780664966224,26fe50c9203ccf93512b80d4ee1a7578184a910457b36a6a5b7d41b799efb966
assets/packages/flutter_dropzone_web/assets/flutter_dropzone.js,1748366257688,d640313cd6a02692249cd41e4643c2771b4202cc84e0f07f5f65cdc77a36826f assets/packages/flutter_dropzone_web/assets/flutter_dropzone.js,1748366257688,d640313cd6a02692249cd41e4643c2771b4202cc84e0f07f5f65cdc77a36826f
assets/assets/Google__G__logo.svg,1741027482182,b365d560438f8f04caf08ffaa5d8995eff6c09b36b4483f44d6f5f82d8559d4f assets/assets/Google__G__logo.svg,1741027482182,b365d560438f8f04caf08ffaa5d8995eff6c09b36b4483f44d6f5f82d8559d4f
assets/assets/google.png,1741029771653,537ca60ffa74c28eca4e62d249237403a7d47d2bc90bb90431b8d5aa923a92ee assets/assets/google.png,1741029771653,537ca60ffa74c28eca4e62d249237403a7d47d2bc90bb90431b8d5aa923a92ee
@@ -34,16 +35,16 @@ assets/assets/images/tshirt-incrust.webp,1737393735487,af7cb34adfca19c0b41c8eb63
assets/assets/icons/truss.svg,1761734811263,8ddfbbb4f96de5614348eb23fa55f61b2eb1edb064719a8bbd791c35883ec4cc assets/assets/icons/truss.svg,1761734811263,8ddfbbb4f96de5614348eb23fa55f61b2eb1edb064719a8bbd791c35883ec4cc
assets/assets/icons/tape.svg,1761734809221,631183f0ff972aa4dc3f9f51dc7abd41a607df749d1f9a44fa7e77202d95ccde assets/assets/icons/tape.svg,1761734809221,631183f0ff972aa4dc3f9f51dc7abd41a607df749d1f9a44fa7e77202d95ccde
assets/assets/icons/flight-case.svg,1761734822495,0cef47fdf5d7efdd110763c32f792ef9735df35c4f42ae7d02d5fbda40e6148d assets/assets/icons/flight-case.svg,1761734822495,0cef47fdf5d7efdd110763c32f792ef9735df35c4f42ae7d02d5fbda40e6148d
version.json,1779802456392,7626a7c596308bd2eb1add2ed984cd6dda5d4a3f0dedb3338244d2ae45c496cf version.json,1781276622421,53cb7b032096362a439141e58e2c19c6cd4d85422fa90618e3d5604b7450e50a
index.html,1779802461141,4e8c00552c71ef134bead8bc03706952e7a415d70fca602a3839dc02a3f7ae10 index.html,1781276629719,7dd070b4e8d51aa49d899690a8e2603bf8de2bd9e31f202a84d3f19ff280ae4b
flutter_service_worker.js,1779802555396,fadec2c9a1e8e16c22e332aef080b0b2aacc3998c4e260e5821b79afb9e000da flutter_service_worker.js,1781276711892,99cbb3dcbfa5b6e969bc6301858f448f52e353bfb6263bf506cc56badd845649
flutter_bootstrap.js,1779802461128,ad20054b92acf16bb75fbffd65f81c63c6d3cb6d752f799230dca5f2118af783 flutter_bootstrap.js,1781276629703,fb4c37e9827d0987f039b599cc441392fe88066945703b54093492427fe51021
assets/FontManifest.json,1779802551869,e38b95988f5d060cf9b7ce97cb5ac9236d6f4cc04a11d69567df97b2b4cbc5e5 assets/FontManifest.json,1781276708232,e38b95988f5d060cf9b7ce97cb5ac9236d6f4cc04a11d69567df97b2b4cbc5e5
assets/AssetManifest.json,1779802551869,0e35e7214421c832bf41b0af7c03037e66fee508b857d3143f40f6862e454dd6 assets/AssetManifest.json,1781276708232,a75793b913dabecfa1b5eade2735ec6f8f280210572cf25d0ce010d2a6d95e8f
assets/AssetManifest.bin.json,1779802551869,3a244f5f866d93c17f420cc01b1ba318584b4da92af9512d9ba4acd099b49d53 assets/AssetManifest.bin.json,1781276708232,a26149597dbbee9aeaec0377943061e2b76c73bf974246f6af0b1a82e7455eaa
assets/AssetManifest.bin,1779802551869,205908d2fcf1ca9708b7d1f91ec7ea80c5f07eaf6cfc1458cb9364a4d9106907 assets/AssetManifest.bin,1781276708232,61f45b0f17a664717759ebf0f1271212f4658bd4b83e35bd5d134689b73a01d6
assets/shaders/ink_sparkle.frag,1779802552052,591c7517d5cb43eb91ea451e0d3f9f585cbf8298cf6c46a9144b77cb0775a406 assets/shaders/ink_sparkle.frag,1781276708458,591c7517d5cb43eb91ea451e0d3f9f585cbf8298cf6c46a9144b77cb0775a406
assets/packages/cupertino_icons/assets/CupertinoIcons.ttf,1779802554433,d41473de1f7708a0702d7f19327693486512db442f6ab0cf7774e6d6576f9fcb assets/packages/cupertino_icons/assets/CupertinoIcons.ttf,1781276711048,d41473de1f7708a0702d7f19327693486512db442f6ab0cf7774e6d6576f9fcb
assets/fonts/MaterialIcons-Regular.otf,1779802554440,710dc8fc35289048b52970355f64206fb1b2c5e67c71ae77a46b53f0e2daecd6 assets/fonts/MaterialIcons-Regular.otf,1781276711054,1551d6f32ad2bc8ed771c39fdef3fc01f0188517d44127e47ad826188ca8c82f
assets/NOTICES,1779802551871,5522e1307c65771d1fbf26fcd9dc0548c751413f42196c4acaba5ee674eede1e assets/NOTICES,1781276708232,b4202bcf340224c6c2ba4b0e4d4c560f929a8bec3865a3f5c253b8abd8761b78
main.dart.js,1779802550741,ab892e930c97940c1ea4ff33079922082c7f688047d307acad0644a78cfda2d7 main.dart.js,1781276707053,1e2a854e74ffd2a641bf323c7cbf19bbdf8660e0edba953511550ab61df3f495
+9
View File
@@ -2,6 +2,15 @@
Toutes les modifications notables de ce projet seront documentées dans ce fichier. Toutes les modifications notables de ce projet seront documentées dans ce fichier.
## 12/06/2026
- Fix bug date des evenements, migration des dates vers le fuseau horaire Europe/Paris
## 05/06/2026bis
Fix bug vue mobile, amélioration de la vue de calcule des frais de déplacement
## 05/06/2026
Ajout de la fonctionnalité de génération d'itinéraire avec calcul de coût.
## 27/05/2026 ## 27/05/2026
Ajout de la fonction retour en arriere pour la validation du chargement des equipements et des conteneurs. Ajout de la fonction retour en arriere pour la validation du chargement des equipements et des conteneurs.
+1 -1
View File
@@ -8,4 +8,4 @@ SMTP_PASS="aL8@Rx8xqFrNij$a"
APP_URL="https://app.em2events.fr" APP_URL="https://app.em2events.fr"
GEMINI_API_KEY="AIzaSyB0hOvBjWeWjdrxVARzfErZ_uGuArlvmQc" GEMINI_API_KEY="AIzaSyB0hOvBjWeWjdrxVARzfErZ_uGuArlvmQc"
API_MAPS="AIzaSyDt2d-T9YRmHO3-QEq1uWomdqVbJqXfO04" API_MAPS="AIzaSyDt2d-T9YRmHO3-QEq1uWomdqVbJqXfO04"
+73
View File
@@ -0,0 +1,73 @@
const admin = require("firebase-admin");
const serviceAccount = require("./serviceAccountKey.json");
// Initialiser Firebase Admin
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
});
const db = admin.firestore();
async function migrateEventDates() {
console.log("🔧 Migration: Correction du fuseau horaire des événements");
console.log("================================================\n");
try {
const eventsSnapshot = await db.collection("events").get();
console.log(`📦 Total d'événements: ${eventsSnapshot.size}`);
let updatedCount = 0;
const batch = db.batch();
for (const doc of eventsSnapshot.docs) {
const data = doc.data();
let updated = false;
const updates = {};
const fixDate = (timestamp) => {
if (!timestamp) return null;
const oldDate = timestamp.toDate();
// On prend les composants UTC (qui étaient en fait l'heure locale mal enregistrée)
// et on crée une vraie date locale avec
const newDate = new Date(
oldDate.getUTCFullYear(),
oldDate.getUTCMonth(),
oldDate.getUTCDate(),
oldDate.getUTCHours(),
oldDate.getUTCMinutes(),
oldDate.getUTCSeconds()
);
return admin.firestore.Timestamp.fromDate(newDate);
};
if (data.StartDateTime) {
updates.StartDateTime = fixDate(data.StartDateTime);
updated = true;
}
if (data.EndDateTime) {
updates.EndDateTime = fixDate(data.EndDateTime);
updated = true;
}
if (updated) {
batch.update(doc.ref, updates);
updatedCount++;
}
}
if (updatedCount > 0) {
await batch.commit();
console.log(`${updatedCount} événements corrigés avec succès !`);
} else {
console.log("️ Aucun événement à corriger.");
}
} catch (error) {
console.error("❌ Erreur lors de la migration:", error);
process.exit(1);
}
}
migrateEventDates().then(() => process.exit(0));
+486 -16
View File
@@ -9,7 +9,9 @@
"@google-cloud/storage": "^7.18.0", "@google-cloud/storage": "^7.18.0",
"@google-cloud/text-to-speech": "^5.4.0", "@google-cloud/text-to-speech": "^5.4.0",
"@google/generative-ai": "^0.21.0", "@google/generative-ai": "^0.21.0",
"@mapbox/polyline": "^1.2.1",
"axios": "^1.13.2", "axios": "^1.13.2",
"csv-parser": "^3.2.1",
"dotenv": "^17.2.3", "dotenv": "^17.2.3",
"envdot": "^0.0.3", "envdot": "^0.0.3",
"firebase-admin": "^12.6.0", "firebase-admin": "^12.6.0",
@@ -44,7 +46,6 @@
"version": "7.27.1", "version": "7.27.1",
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz",
"integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==", "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==",
"dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@babel/helper-validator-identifier": "^7.27.1", "@babel/helper-validator-identifier": "^7.27.1",
@@ -187,7 +188,6 @@
"version": "7.27.1", "version": "7.27.1",
"resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz", "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz",
"integrity": "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==", "integrity": "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==",
"dev": true,
"license": "MIT", "license": "MIT",
"engines": { "engines": {
"node": ">=6.9.0" "node": ">=6.9.0"
@@ -1336,6 +1336,17 @@
"url": "https://opencollective.com/js-sdsl" "url": "https://opencollective.com/js-sdsl"
} }
}, },
"node_modules/@mapbox/polyline": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/@mapbox/polyline/-/polyline-1.2.1.tgz",
"integrity": "sha512-sn0V18O3OzW4RCcPoUIVDWvEGQaBNH9a0y5lgqrf5hUycyw1CzrhEoxV5irzrMNXKCkw1xRsZXcaVbsVZggHXA==",
"dependencies": {
"meow": "^9.0.0"
},
"bin": {
"polyline": "bin/polyline.bin.js"
}
},
"node_modules/@nodelib/fs.scandir": { "node_modules/@nodelib/fs.scandir": {
"version": "2.1.5", "version": "2.1.5",
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
@@ -1659,6 +1670,12 @@
"integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==", "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==",
"license": "MIT" "license": "MIT"
}, },
"node_modules/@types/minimist": {
"version": "1.2.5",
"resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.5.tgz",
"integrity": "sha512-hov8bUuiLiyFPGyFPE1lwWhmzYbirOXQNNo40+y3zow8aFVTeyn3VWL0VFFfdNddA8S4Vf0Tc062rzyNr7Paag==",
"license": "MIT"
},
"node_modules/@types/ms": { "node_modules/@types/ms": {
"version": "2.1.0", "version": "2.1.0",
"resolved": "https://registry.npmjs.org/@types/ms/-/ms-2.1.0.tgz", "resolved": "https://registry.npmjs.org/@types/ms/-/ms-2.1.0.tgz",
@@ -1674,6 +1691,12 @@
"undici-types": "~6.21.0" "undici-types": "~6.21.0"
} }
}, },
"node_modules/@types/normalize-package-data": {
"version": "2.4.4",
"resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.4.tgz",
"integrity": "sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==",
"license": "MIT"
},
"node_modules/@types/qs": { "node_modules/@types/qs": {
"version": "6.14.0", "version": "6.14.0",
"resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.14.0.tgz", "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.14.0.tgz",
@@ -2315,12 +2338,28 @@
"version": "5.3.1", "version": "5.3.1",
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
"integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
"dev": true,
"license": "MIT", "license": "MIT",
"engines": { "engines": {
"node": ">=6" "node": ">=6"
} }
}, },
"node_modules/camelcase-keys": {
"version": "6.2.2",
"resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-6.2.2.tgz",
"integrity": "sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==",
"license": "MIT",
"dependencies": {
"camelcase": "^5.3.1",
"map-obj": "^4.0.0",
"quick-lru": "^4.0.1"
},
"engines": {
"node": ">=8"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/caniuse-lite": { "node_modules/caniuse-lite": {
"version": "1.0.30001718", "version": "1.0.30001718",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001718.tgz", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001718.tgz",
@@ -2554,6 +2593,18 @@
"node": ">= 8" "node": ">= 8"
} }
}, },
"node_modules/csv-parser": {
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/csv-parser/-/csv-parser-3.2.1.tgz",
"integrity": "sha512-v8RPMSglouR9od735SnwSxLBbCJqEPSbgm1R5qfr8yIiMUCEFjox56kRZid0SvgHJEkxeIEu3+a9QS3YRh7CuA==",
"license": "MIT",
"bin": {
"csv-parser": "bin/csv-parser"
},
"engines": {
"node": ">= 10"
}
},
"node_modules/debug": { "node_modules/debug": {
"version": "4.4.1", "version": "4.4.1",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz",
@@ -2571,6 +2622,40 @@
} }
} }
}, },
"node_modules/decamelize": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
"integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==",
"license": "MIT",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/decamelize-keys": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.1.tgz",
"integrity": "sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg==",
"license": "MIT",
"dependencies": {
"decamelize": "^1.1.0",
"map-obj": "^1.0.0"
},
"engines": {
"node": ">=0.10.0"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/decamelize-keys/node_modules/map-obj": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz",
"integrity": "sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==",
"license": "MIT",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/dedent": { "node_modules/dedent": {
"version": "1.6.0", "version": "1.6.0",
"resolved": "https://registry.npmjs.org/dedent/-/dedent-1.6.0.tgz", "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.6.0.tgz",
@@ -2789,7 +2874,6 @@
"version": "1.3.2", "version": "1.3.2",
"resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
"integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==",
"dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"is-arrayish": "^0.2.1" "is-arrayish": "^0.2.1"
@@ -3830,6 +3914,15 @@
"uglify-js": "^3.1.4" "uglify-js": "^3.1.4"
} }
}, },
"node_modules/hard-rejection": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz",
"integrity": "sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==",
"license": "MIT",
"engines": {
"node": ">=6"
}
},
"node_modules/has-flag": { "node_modules/has-flag": {
"version": "4.0.0", "version": "4.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
@@ -3879,6 +3972,36 @@
"node": ">= 0.4" "node": ">= 0.4"
} }
}, },
"node_modules/hosted-git-info": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz",
"integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==",
"license": "ISC",
"dependencies": {
"lru-cache": "^6.0.0"
},
"engines": {
"node": ">=10"
}
},
"node_modules/hosted-git-info/node_modules/lru-cache": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
"integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
"license": "ISC",
"dependencies": {
"yallist": "^4.0.0"
},
"engines": {
"node": ">=10"
}
},
"node_modules/hosted-git-info/node_modules/yallist": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
"license": "ISC"
},
"node_modules/html-entities": { "node_modules/html-entities": {
"version": "2.6.0", "version": "2.6.0",
"resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.6.0.tgz", "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.6.0.tgz",
@@ -4042,6 +4165,15 @@
"node": ">=0.8.19" "node": ">=0.8.19"
} }
}, },
"node_modules/indent-string": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz",
"integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==",
"license": "MIT",
"engines": {
"node": ">=8"
}
},
"node_modules/inflight": { "node_modules/inflight": {
"version": "1.0.6", "version": "1.0.6",
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
@@ -4073,14 +4205,12 @@
"version": "0.2.1", "version": "0.2.1",
"resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
"integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==",
"dev": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/is-core-module": { "node_modules/is-core-module": {
"version": "2.16.1", "version": "2.16.1",
"resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz",
"integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==",
"dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"hasown": "^2.0.2" "hasown": "^2.0.2"
@@ -4154,6 +4284,15 @@
"node": ">=8" "node": ">=8"
} }
}, },
"node_modules/is-plain-obj": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz",
"integrity": "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==",
"license": "MIT",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/is-stream": { "node_modules/is-stream": {
"version": "2.0.1", "version": "2.0.1",
"resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
@@ -4867,7 +5006,6 @@
"version": "4.0.0", "version": "4.0.0",
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
"integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
"dev": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/js-yaml": { "node_modules/js-yaml": {
@@ -4916,7 +5054,6 @@
"version": "2.3.1", "version": "2.3.1",
"resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz",
"integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==",
"dev": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/json-schema-traverse": { "node_modules/json-schema-traverse": {
@@ -5049,6 +5186,15 @@
"json-buffer": "3.0.1" "json-buffer": "3.0.1"
} }
}, },
"node_modules/kind-of": {
"version": "6.0.3",
"resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
"integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==",
"license": "MIT",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/kleur": { "node_modules/kleur": {
"version": "3.0.3", "version": "3.0.3",
"resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz",
@@ -5092,7 +5238,6 @@
"version": "1.2.4", "version": "1.2.4",
"resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
"integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==",
"dev": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/locate-path": { "node_modules/locate-path": {
@@ -5262,6 +5407,18 @@
"tmpl": "1.0.5" "tmpl": "1.0.5"
} }
}, },
"node_modules/map-obj": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz",
"integrity": "sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==",
"license": "MIT",
"engines": {
"node": ">=8"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/math-intrinsics": { "node_modules/math-intrinsics": {
"version": "1.1.0", "version": "1.1.0",
"resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
@@ -5280,6 +5437,53 @@
"node": ">= 0.6" "node": ">= 0.6"
} }
}, },
"node_modules/meow": {
"version": "9.0.0",
"resolved": "https://registry.npmjs.org/meow/-/meow-9.0.0.tgz",
"integrity": "sha512-+obSblOQmRhcyBt62furQqRAQpNyWXo8BuQ5bN7dG8wmwQ+vwHKp/rCFD4CrTP8CsDQD1sjoZ94K417XEUk8IQ==",
"license": "MIT",
"dependencies": {
"@types/minimist": "^1.2.0",
"camelcase-keys": "^6.2.2",
"decamelize": "^1.2.0",
"decamelize-keys": "^1.1.0",
"hard-rejection": "^2.1.0",
"minimist-options": "4.1.0",
"normalize-package-data": "^3.0.0",
"read-pkg-up": "^7.0.1",
"redent": "^3.0.0",
"trim-newlines": "^3.0.0",
"type-fest": "^0.18.0",
"yargs-parser": "^20.2.3"
},
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/meow/node_modules/type-fest": {
"version": "0.18.1",
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.18.1.tgz",
"integrity": "sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==",
"license": "(MIT OR CC0-1.0)",
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/meow/node_modules/yargs-parser": {
"version": "20.2.9",
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz",
"integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==",
"license": "ISC",
"engines": {
"node": ">=10"
}
},
"node_modules/merge-descriptors": { "node_modules/merge-descriptors": {
"version": "1.0.3", "version": "1.0.3",
"resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz", "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz",
@@ -5362,6 +5566,15 @@
"node": ">=6" "node": ">=6"
} }
}, },
"node_modules/min-indent": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz",
"integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==",
"license": "MIT",
"engines": {
"node": ">=4"
}
},
"node_modules/minimatch": { "node_modules/minimatch": {
"version": "3.1.2", "version": "3.1.2",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
@@ -5384,6 +5597,29 @@
"url": "https://github.com/sponsors/ljharb" "url": "https://github.com/sponsors/ljharb"
} }
}, },
"node_modules/minimist-options": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz",
"integrity": "sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==",
"license": "MIT",
"dependencies": {
"arrify": "^1.0.1",
"is-plain-obj": "^1.1.0",
"kind-of": "^6.0.3"
},
"engines": {
"node": ">= 6"
}
},
"node_modules/minimist-options/node_modules/arrify": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz",
"integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==",
"license": "MIT",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/ms": { "node_modules/ms": {
"version": "2.1.3", "version": "2.1.3",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
@@ -5464,6 +5700,33 @@
"node": ">=6.0.0" "node": ">=6.0.0"
} }
}, },
"node_modules/normalize-package-data": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz",
"integrity": "sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==",
"license": "BSD-2-Clause",
"dependencies": {
"hosted-git-info": "^4.0.1",
"is-core-module": "^2.5.0",
"semver": "^7.3.4",
"validate-npm-package-license": "^3.0.1"
},
"engines": {
"node": ">=10"
}
},
"node_modules/normalize-package-data/node_modules/semver": {
"version": "7.8.2",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.8.2.tgz",
"integrity": "sha512-c8jsqUZm3omBOI66G90z1Dyw5z622G8oLG+omfsHBJf3CWQTlOcwOjvOG6wtiNfW6anKm/eA39LMwMtMez2TiQ==",
"license": "ISC",
"bin": {
"semver": "bin/semver.js"
},
"engines": {
"node": ">=10"
}
},
"node_modules/normalize-path": { "node_modules/normalize-path": {
"version": "3.0.0", "version": "3.0.0",
"resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
@@ -5607,7 +5870,6 @@
"version": "2.2.0", "version": "2.2.0",
"resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
"integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
"dev": true,
"license": "MIT", "license": "MIT",
"engines": { "engines": {
"node": ">=6" "node": ">=6"
@@ -5630,7 +5892,6 @@
"version": "5.2.0", "version": "5.2.0",
"resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz",
"integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==",
"dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@babel/code-frame": "^7.0.0", "@babel/code-frame": "^7.0.0",
@@ -5658,7 +5919,6 @@
"version": "4.0.0", "version": "4.0.0",
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
"integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
"dev": true,
"license": "MIT", "license": "MIT",
"engines": { "engines": {
"node": ">=8" "node": ">=8"
@@ -5688,7 +5948,6 @@
"version": "1.0.7", "version": "1.0.7",
"resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
"integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
"dev": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/path-to-regexp": { "node_modules/path-to-regexp": {
@@ -5701,7 +5960,6 @@
"version": "1.1.1", "version": "1.1.1",
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
"integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
"dev": true,
"license": "ISC" "license": "ISC"
}, },
"node_modules/picomatch": { "node_modules/picomatch": {
@@ -5966,6 +6224,15 @@
], ],
"license": "MIT" "license": "MIT"
}, },
"node_modules/quick-lru": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz",
"integrity": "sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==",
"license": "MIT",
"engines": {
"node": ">=8"
}
},
"node_modules/range-parser": { "node_modules/range-parser": {
"version": "1.2.1", "version": "1.2.1",
"resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
@@ -6026,6 +6293,135 @@
"dev": true, "dev": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/read-pkg": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz",
"integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==",
"license": "MIT",
"dependencies": {
"@types/normalize-package-data": "^2.4.0",
"normalize-package-data": "^2.5.0",
"parse-json": "^5.0.0",
"type-fest": "^0.6.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/read-pkg-up": {
"version": "7.0.1",
"resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz",
"integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==",
"license": "MIT",
"dependencies": {
"find-up": "^4.1.0",
"read-pkg": "^5.2.0",
"type-fest": "^0.8.1"
},
"engines": {
"node": ">=8"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/read-pkg-up/node_modules/find-up": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
"integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
"license": "MIT",
"dependencies": {
"locate-path": "^5.0.0",
"path-exists": "^4.0.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/read-pkg-up/node_modules/locate-path": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
"integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
"license": "MIT",
"dependencies": {
"p-locate": "^4.1.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/read-pkg-up/node_modules/p-limit": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
"integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
"license": "MIT",
"dependencies": {
"p-try": "^2.0.0"
},
"engines": {
"node": ">=6"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/read-pkg-up/node_modules/p-locate": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
"integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
"license": "MIT",
"dependencies": {
"p-limit": "^2.2.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/read-pkg-up/node_modules/type-fest": {
"version": "0.8.1",
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz",
"integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==",
"license": "(MIT OR CC0-1.0)",
"engines": {
"node": ">=8"
}
},
"node_modules/read-pkg/node_modules/hosted-git-info": {
"version": "2.8.9",
"resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz",
"integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==",
"license": "ISC"
},
"node_modules/read-pkg/node_modules/normalize-package-data": {
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz",
"integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==",
"license": "BSD-2-Clause",
"dependencies": {
"hosted-git-info": "^2.1.4",
"resolve": "^1.10.0",
"semver": "2 || 3 || 4 || 5",
"validate-npm-package-license": "^3.0.1"
}
},
"node_modules/read-pkg/node_modules/semver": {
"version": "5.7.2",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
"integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==",
"license": "ISC",
"bin": {
"semver": "bin/semver"
}
},
"node_modules/read-pkg/node_modules/type-fest": {
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz",
"integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==",
"license": "(MIT OR CC0-1.0)",
"engines": {
"node": ">=8"
}
},
"node_modules/readable-stream": { "node_modules/readable-stream": {
"version": "3.6.2", "version": "3.6.2",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
@@ -6040,6 +6436,19 @@
"node": ">= 6" "node": ">= 6"
} }
}, },
"node_modules/redent": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz",
"integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==",
"license": "MIT",
"dependencies": {
"indent-string": "^4.0.0",
"strip-indent": "^3.0.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/require-directory": { "node_modules/require-directory": {
"version": "2.1.1", "version": "2.1.1",
"resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
@@ -6053,7 +6462,6 @@
"version": "1.22.10", "version": "1.22.10",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz",
"integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==", "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==",
"dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"is-core-module": "^2.16.0", "is-core-module": "^2.16.0",
@@ -6444,6 +6852,38 @@
"source-map": "^0.6.0" "source-map": "^0.6.0"
} }
}, },
"node_modules/spdx-correct": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz",
"integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==",
"license": "Apache-2.0",
"dependencies": {
"spdx-expression-parse": "^3.0.0",
"spdx-license-ids": "^3.0.0"
}
},
"node_modules/spdx-exceptions": {
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz",
"integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==",
"license": "CC-BY-3.0"
},
"node_modules/spdx-expression-parse": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz",
"integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==",
"license": "MIT",
"dependencies": {
"spdx-exceptions": "^2.1.0",
"spdx-license-ids": "^3.0.0"
}
},
"node_modules/spdx-license-ids": {
"version": "3.0.23",
"resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.23.tgz",
"integrity": "sha512-CWLcCCH7VLu13TgOH+r8p1O/Znwhqv/dbb6lqWy67G+pT1kHmeD/+V36AVb/vq8QMIQwVShJ6Ssl5FPh0fuSdw==",
"license": "CC0-1.0"
},
"node_modules/sprintf-js": { "node_modules/sprintf-js": {
"version": "1.0.3", "version": "1.0.3",
"resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
@@ -6567,6 +7007,18 @@
"node": ">=6" "node": ">=6"
} }
}, },
"node_modules/strip-indent": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz",
"integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==",
"license": "MIT",
"dependencies": {
"min-indent": "^1.0.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/strip-json-comments": { "node_modules/strip-json-comments": {
"version": "3.1.1", "version": "3.1.1",
"resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
@@ -6615,7 +7067,6 @@
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
"integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
"dev": true,
"license": "MIT", "license": "MIT",
"engines": { "engines": {
"node": ">= 0.4" "node": ">= 0.4"
@@ -6735,6 +7186,15 @@
"integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==",
"license": "MIT" "license": "MIT"
}, },
"node_modules/trim-newlines": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.1.tgz",
"integrity": "sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==",
"license": "MIT",
"engines": {
"node": ">=8"
}
},
"node_modules/ts-deepmerge": { "node_modules/ts-deepmerge": {
"version": "2.0.7", "version": "2.0.7",
"resolved": "https://registry.npmjs.org/ts-deepmerge/-/ts-deepmerge-2.0.7.tgz", "resolved": "https://registry.npmjs.org/ts-deepmerge/-/ts-deepmerge-2.0.7.tgz",
@@ -6909,6 +7369,16 @@
"node": ">=10.12.0" "node": ">=10.12.0"
} }
}, },
"node_modules/validate-npm-package-license": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz",
"integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==",
"license": "Apache-2.0",
"dependencies": {
"spdx-correct": "^3.0.0",
"spdx-expression-parse": "^3.0.0"
}
},
"node_modules/vary": { "node_modules/vary": {
"version": "1.1.2", "version": "1.1.2",
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
+1 -1
View File
@@ -250,7 +250,7 @@ exports.googleMapsAutocomplete = async (req, res) => {
url.searchParams.set('key', apiKey); url.searchParams.set('key', apiKey);
url.searchParams.set('language', 'fr'); url.searchParams.set('language', 'fr');
url.searchParams.set('components', 'country:fr'); url.searchParams.set('components', 'country:fr');
url.searchParams.set('types', 'address'); url.searchParams.set('types', 'geocode');
const gRes = await axios.get(url.toString(), { timeout: 5000 }); const gRes = await axios.get(url.toString(), { timeout: 5000 });
return res.status(200).json(gRes.data); return res.status(200).json(gRes.data);
+1 -3
View File
@@ -1,12 +1,10 @@
/// Configuration de la version de l'application /// Configuration de la version de l'application
class AppVersion { class AppVersion {
static const String version = '1.2.4'; static const String version = '1.2.10';
/// Retourne la version complète de l'application /// Retourne la version complète de l'application
static String get fullVersion => 'v$version'; static String get fullVersion => 'v$version';
/// Retourne la version avec un préfixe personnalisé /// Retourne la version avec un préfixe personnalisé
static String getVersionWithPrefix(String prefix) => '$prefix $version'; static String getVersionWithPrefix(String prefix) => '$prefix $version';
} }
+1 -1
View File
@@ -154,7 +154,7 @@ class AlertModel {
DateTime parseDate(dynamic value) { DateTime parseDate(dynamic value) {
if (value == null) return DateTime.now(); if (value == null) return DateTime.now();
if (value is Timestamp) return value.toDate(); if (value is Timestamp) return value.toDate();
if (value is String) return DateTime.tryParse(value) ?? DateTime.now(); if (value is String) return DateTime.tryParse(value)?.toLocal() ?? DateTime.now();
return DateTime.now(); return DateTime.now();
} }
+2 -2
View File
@@ -254,7 +254,7 @@ class ContainerModel {
DateTime? parseDate(dynamic value) { DateTime? parseDate(dynamic value) {
if (value == null) return null; if (value == null) return null;
if (value is Timestamp) return value.toDate(); if (value is Timestamp) return value.toDate();
if (value is String) return DateTime.tryParse(value); if (value is String) return DateTime.tryParse(value)?.toLocal();
if (value is int) return DateTime.fromMillisecondsSinceEpoch(value); if (value is int) return DateTime.fromMillisecondsSinceEpoch(value);
return null; return null;
} }
@@ -375,7 +375,7 @@ class ContainerHistoryEntry {
DateTime parseDate(dynamic value) { DateTime parseDate(dynamic value) {
if (value == null) return DateTime.now(); if (value == null) return DateTime.now();
if (value is Timestamp) return value.toDate(); if (value is Timestamp) return value.toDate();
if (value is String) return DateTime.tryParse(value) ?? DateTime.now(); if (value is String) return DateTime.tryParse(value)?.toLocal() ?? DateTime.now();
if (value is int) return DateTime.fromMillisecondsSinceEpoch(value); if (value is int) return DateTime.fromMillisecondsSinceEpoch(value);
return DateTime.now(); return DateTime.now();
} }
+1 -1
View File
@@ -407,7 +407,7 @@ class EquipmentModel {
DateTime? parseDate(dynamic value) { DateTime? parseDate(dynamic value) {
if (value == null) return null; if (value == null) return null;
if (value is Timestamp) return value.toDate(); if (value is Timestamp) return value.toDate();
if (value is String) return DateTime.tryParse(value); if (value is String) return DateTime.tryParse(value)?.toLocal();
if (value is int) return DateTime.fromMillisecondsSinceEpoch(value); if (value is int) return DateTime.fromMillisecondsSinceEpoch(value);
return null; return null;
} }
+1 -1
View File
@@ -356,7 +356,7 @@ class EventModel {
DateTime parseDate(dynamic value, DateTime defaultValue) { DateTime parseDate(dynamic value, DateTime defaultValue) {
if (value == null) return defaultValue; if (value == null) return defaultValue;
if (value is Timestamp) return value.toDate(); if (value is Timestamp) return value.toDate();
if (value is String) return DateTime.tryParse(value) ?? defaultValue; if (value is String) return DateTime.tryParse(value)?.toLocal() ?? defaultValue;
return defaultValue; return defaultValue;
} }
+1 -1
View File
@@ -18,7 +18,7 @@ class EventTypeModel {
DateTime parseCreatedAt(dynamic value) { DateTime parseCreatedAt(dynamic value) {
if (value == null) return DateTime.now(); if (value == null) return DateTime.now();
if (value is Timestamp) return value.toDate(); if (value is Timestamp) return value.toDate();
if (value is String) return DateTime.tryParse(value) ?? DateTime.now(); if (value is String) return DateTime.tryParse(value)?.toLocal() ?? DateTime.now();
return DateTime.now(); return DateTime.now();
} }
+1 -1
View File
@@ -72,7 +72,7 @@ class MaintenanceModel {
DateTime? parseDate(dynamic value) { DateTime? parseDate(dynamic value) {
if (value == null) return null; if (value == null) return null;
if (value is Timestamp) return value.toDate(); if (value is Timestamp) return value.toDate();
if (value is String) return DateTime.tryParse(value); if (value is String) return DateTime.tryParse(value)?.toLocal();
if (value is int) return DateTime.fromMillisecondsSinceEpoch(value); if (value is int) return DateTime.fromMillisecondsSinceEpoch(value);
return null; return null;
} }
+5 -7
View File
@@ -72,24 +72,22 @@ class RouteResult {
required double maintenanceCostPerKm, required double maintenanceCostPerKm,
required int nbTechnicians, required int nbTechnicians,
required double hourlyRate, required double hourlyRate,
bool applyFreeZone = false, double freeZoneKm = 0,
double freeZoneMinutes = 0,
}) { }) {
const freeKm = 20.0;
const freeMinutes = 20.0;
return fuelCost( return fuelCost(
consumptionPer100km: consumptionPer100km, consumptionPer100km: consumptionPer100km,
fuelPricePerLiter: fuelPricePerLiter, fuelPricePerLiter: fuelPricePerLiter,
freeZoneKm: applyFreeZone ? freeKm : 0, freeZoneKm: freeZoneKm,
) + ) +
maintenanceCost( maintenanceCost(
costPerKm: maintenanceCostPerKm, costPerKm: maintenanceCostPerKm,
freeZoneKm: applyFreeZone ? freeKm : 0, freeZoneKm: freeZoneKm,
) + ) +
laborCost( laborCost(
nbTechnicians: nbTechnicians, nbTechnicians: nbTechnicians,
hourlyRate: hourlyRate, hourlyRate: hourlyRate,
freeZoneMinutes: applyFreeZone ? freeMinutes : 0, freeZoneMinutes: freeZoneMinutes,
) + ) +
tollCost; tollCost;
} }
+12 -5
View File
@@ -287,14 +287,21 @@ class EventProvider with ChangeNotifier {
/// Ajouter un nouvel événement /// Ajouter un nouvel événement
Future<void> addEvent(EventModel event) async { Future<void> addEvent(EventModel event) async {
try { try {
// Ajouter l'événement localement dans _events
_events.add(event);
// Ajouter dans le cache par mois
final monthKey = final monthKey =
'${event.startDateTime.year}-${event.startDateTime.month.toString().padLeft(2, '0')}'; '${event.startDateTime.year}-${event.startDateTime.month.toString().padLeft(2, '0')}';
// Ajouter dans le cache par mois s'il est chargé
if (_eventsByMonth.containsKey(monthKey)) { if (_eventsByMonth.containsKey(monthKey)) {
_eventsByMonth[monthKey]!.add(event); if (!_eventsByMonth[monthKey]!.any((e) => e.id == event.id)) {
_eventsByMonth[monthKey]!.add(event);
}
}
// Si _events est la même instance de liste, il a déjà été ajouté.
// Sinon (par exemple si on affiche un autre mois ou cache désynchronisé),
// on l'ajoute à _events uniquement si c'est pour le mois courant.
if ((_currentMonth == null || _currentMonth == monthKey) && !_events.any((e) => e.id == event.id)) {
_events.add(event);
} }
notifyListeners(); notifyListeners();
+2 -2
View File
@@ -48,10 +48,10 @@ class FirebaseFunctionsApiService implements ApiService {
// Types Firestore // Types Firestore
if (value is Timestamp) { if (value is Timestamp) {
return value.toDate().toIso8601String(); return value.toDate().toUtc().toIso8601String();
} }
if (value is DateTime) { if (value is DateTime) {
return value.toIso8601String(); return value.toUtc().toIso8601String();
} }
if (value is DocumentReference) { if (value is DocumentReference) {
return value.path; return value.path;
+2 -3
View File
@@ -104,9 +104,8 @@ class CalendarUtils {
static List<EventModel> getEventsForDay( static List<EventModel> getEventsForDay(
DateTime day, List<EventModel> events) { DateTime day, List<EventModel> events) {
final nextDay = day.add(const Duration(days: 1)); final dayStart = DateTime(day.year, day.month, day.day, 0, 0, 0);
final dayStart = DateTime(day.year, day.month, day.day, 2, 0); final dayEnd = DateTime(day.year, day.month, day.day, 23, 59, 59);
final dayEnd = DateTime(nextDay.year, nextDay.month, nextDay.day, 2, 59, 59);
return events.where((event) { return events.where((event) {
return !(event.endDateTime.isBefore(dayStart) || return !(event.endDateTime.isBefore(dayStart) ||
+72 -5
View File
@@ -523,6 +523,7 @@ class _EquipmentManagementPageState extends State<EquipmentManagementPage>
Widget _buildEquipmentCard(EquipmentModel equipment) { Widget _buildEquipmentCard(EquipmentModel equipment) {
final isSelected = isItemSelected(equipment.id); final isSelected = isItemSelected(equipment.id);
final isMobile = MediaQuery.of(context).size.width < 800;
// ✅ RepaintBoundary pour isoler le repaint de chaque carte // ✅ RepaintBoundary pour isoler le repaint de chaque carte
return RepaintBoundary( return RepaintBoundary(
@@ -563,9 +564,12 @@ class _EquipmentManagementPageState extends State<EquipmentManagementPage>
}, },
child: Padding( child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12), padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
child: Row( child: Column(
crossAxisAlignment: CrossAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.stretch,
children: [ children: [
Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
// 1. leading selection or icon // 1. leading selection or icon
if (isSelectionMode) if (isSelectionMode)
Padding( Padding(
@@ -642,15 +646,15 @@ class _EquipmentManagementPageState extends State<EquipmentManagementPage>
// 3. Status Badge OR Quantity Display (centered vertically in the row!) // 3. Status Badge OR Quantity Display (centered vertically in the row!)
Padding( Padding(
padding: const EdgeInsets.only(right: 16), padding: EdgeInsets.only(right: (!isSelectionMode && !isMobile) ? 16 : 0),
child: (equipment.category == EquipmentCategory.consumable || child: (equipment.category == EquipmentCategory.consumable ||
equipment.category == EquipmentCategory.cable) equipment.category == EquipmentCategory.cable)
? _buildQuantityDisplay(equipment) ? _buildQuantityDisplay(equipment)
: EquipmentStatusBadge(equipment: equipment), : EquipmentStatusBadge(equipment: equipment),
), ),
// 4. Trailing Action Buttons // 4. Trailing Action Buttons (Desktop inline)
if (!isSelectionMode) if (!isSelectionMode && !isMobile)
Row( Row(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ children: [
@@ -711,6 +715,69 @@ class _EquipmentManagementPageState extends State<EquipmentManagementPage>
), ),
], ],
), ),
if (!isSelectionMode && isMobile) ...[
const Divider(height: 24),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
// Bouton Restock (uniquement pour consommables/câbles avec permission)
if (equipment.category == EquipmentCategory.consumable ||
equipment.category == EquipmentCategory.cable)
PermissionGate(
requiredPermissions: const ['manage_equipment'],
child: IconButton(
icon: const Icon(Icons.add_shopping_cart,
color: AppColors.rouge, size: 20),
tooltip: 'Restock',
padding: EdgeInsets.zero,
constraints: const BoxConstraints(),
onPressed: () => _showRestockDialog(equipment),
),
),
if (equipment.category == EquipmentCategory.consumable ||
equipment.category == EquipmentCategory.cable)
const SizedBox(width: 16),
// Bouton QR Code
IconButton(
icon: const Icon(Icons.qr_code, color: AppColors.rouge, size: 20),
tooltip: 'QR Code',
padding: EdgeInsets.zero,
constraints: const BoxConstraints(),
onPressed: () => showDialog(
context: context,
builder: (context) =>
QRCodeDialog.forEquipment(equipment),
),
),
const SizedBox(width: 16),
// Bouton Modifier (permission required)
PermissionGate(
requiredPermissions: const ['manage_equipment'],
child: IconButton(
icon: const Icon(Icons.edit, color: AppColors.rouge, size: 20),
tooltip: 'Modifier',
padding: EdgeInsets.zero,
constraints: const BoxConstraints(),
onPressed: () => _editEquipment(equipment),
),
),
const SizedBox(width: 16),
// Bouton Supprimer (permission required)
PermissionGate(
requiredPermissions: const ['manage_equipment'],
child: IconButton(
icon: const Icon(Icons.delete, color: Colors.red, size: 20),
tooltip: 'Supprimer',
padding: EdgeInsets.zero,
constraints: const BoxConstraints(),
onPressed: () => _deleteEquipment(equipment),
),
),
],
),
],
],
),
), ),
), ),
), ),
File diff suppressed because it is too large Load Diff
@@ -46,6 +46,8 @@ class _TravelCostDialogState extends State<TravelCostDialog> {
int _nbTechnicians = 2; int _nbTechnicians = 2;
double _hourlyRate = 25.0; double _hourlyRate = 25.0;
bool _applyFreeZone = false; bool _applyFreeZone = false;
double _freeZoneKm = 20.0;
int _freeZoneMinutes = 20;
// Résultats // Résultats
List<RouteResult> _routes = []; List<RouteResult> _routes = [];
@@ -142,7 +144,8 @@ class _TravelCostDialogState extends State<TravelCostDialog> {
maintenanceCostPerKm: _selectedVehicle!.maintenanceCostPerKm, maintenanceCostPerKm: _selectedVehicle!.maintenanceCostPerKm,
nbTechnicians: _nbTechnicians, nbTechnicians: _nbTechnicians,
hourlyRate: _hourlyRate, hourlyRate: _hourlyRate,
applyFreeZone: _applyFreeZone, freeZoneKm: _applyFreeZone ? _freeZoneKm : 0.0,
freeZoneMinutes: _applyFreeZone ? _freeZoneMinutes.toDouble() : 0.0,
); );
Navigator.of(context).pop(total); Navigator.of(context).pop(total);
} }
@@ -230,29 +233,32 @@ class _TravelCostDialogState extends State<TravelCostDialog> {
); );
} }
if (_routes.isEmpty) {
return SingleChildScrollView(
padding: const EdgeInsets.all(24),
child: _buildConfigPanel(),
);
}
// Résultats
final screenW = MediaQuery.of(context).size.width; final screenW = MediaQuery.of(context).size.width;
final isWide = screenW > 900; final isWide = screenW > 900;
if (isWide) { if (isWide) {
return Row( return Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Expanded( Expanded(
flex: 3, flex: 3,
child: RouteMapWidget(routes: _routes, selectedRoute: _selectedRoute), child: _routes.isEmpty
? const Center(child: Text("Configurez le trajet et cliquez sur Calculer"))
: RouteMapWidget(routes: _routes, selectedRoute: _selectedRoute),
), ),
Expanded( Expanded(
flex: 2, flex: 2,
child: SingleChildScrollView( child: SingleChildScrollView(
padding: const EdgeInsets.all(16), padding: const EdgeInsets.all(16),
child: _buildResultsPanel(), child: Column(
children: [
_buildConfigPanel(),
if (_routes.isNotEmpty) ...[
const Divider(height: 32),
_buildResultsPanel(),
]
],
),
), ),
), ),
], ],
@@ -261,13 +267,22 @@ class _TravelCostDialogState extends State<TravelCostDialog> {
return SingleChildScrollView( return SingleChildScrollView(
child: Column( child: Column(
children: [ children: [
SizedBox( if (_routes.isNotEmpty)
height: 260, SizedBox(
child: RouteMapWidget(routes: _routes, selectedRoute: _selectedRoute), height: 260,
), child: RouteMapWidget(routes: _routes, selectedRoute: _selectedRoute),
),
Padding( Padding(
padding: const EdgeInsets.all(16), padding: const EdgeInsets.all(16),
child: _buildResultsPanel(), child: Column(
children: [
_buildConfigPanel(),
if (_routes.isNotEmpty) ...[
const Divider(height: 32),
_buildResultsPanel(),
]
],
),
), ),
], ],
), ),
@@ -413,10 +428,53 @@ class _TravelCostDialogState extends State<TravelCostDialog> {
activeColor: AppColors.rouge, activeColor: AppColors.rouge,
title: const Text('Appliquer la zone de gratuité'), title: const Text('Appliquer la zone de gratuité'),
subtitle: subtitle:
const Text('Déduit 20 km (carburant + maintenance) et 20 min (main-d\'œuvre)'), Text('Déduit ${_freeZoneKm.toStringAsFixed(0)} km (carburant + maintenance) et $_freeZoneMinutes min (main-d\'œuvre)'),
contentPadding: EdgeInsets.zero, contentPadding: EdgeInsets.zero,
controlAffinity: ListTileControlAffinity.leading, controlAffinity: ListTileControlAffinity.leading,
), ),
if (_applyFreeZone)
Padding(
padding: const EdgeInsets.only(left: 32, top: 8),
child: Row(
children: [
Expanded(
child: TextFormField(
initialValue: _freeZoneKm.toStringAsFixed(0),
decoration: const InputDecoration(
labelText: 'Distance déduite',
border: OutlineInputBorder(),
suffixText: 'km',
),
keyboardType: TextInputType.number,
inputFormatters: [
FilteringTextInputFormatter.allow(RegExp(r'^\d+\.?\d{0,2}'))
],
onChanged: (v) {
final parsed = double.tryParse(v);
if (parsed != null) setState(() => _freeZoneKm = parsed);
},
),
),
const SizedBox(width: 16),
Expanded(
child: TextFormField(
initialValue: _freeZoneMinutes.toString(),
decoration: const InputDecoration(
labelText: 'Temps déduit',
border: OutlineInputBorder(),
suffixText: 'min',
),
keyboardType: TextInputType.number,
inputFormatters: [FilteringTextInputFormatter.digitsOnly],
onChanged: (v) {
final parsed = int.tryParse(v);
if (parsed != null) setState(() => _freeZoneMinutes = parsed);
},
),
),
],
),
),
const SizedBox(height: 24), const SizedBox(height: 24),
@@ -492,21 +550,22 @@ class _TravelCostDialogState extends State<TravelCostDialog> {
maintenanceCostPerKm: vehicle.maintenanceCostPerKm, maintenanceCostPerKm: vehicle.maintenanceCostPerKm,
nbTechnicians: _nbTechnicians, nbTechnicians: _nbTechnicians,
hourlyRate: _hourlyRate, hourlyRate: _hourlyRate,
applyFreeZone: _applyFreeZone, freeZoneKm: _applyFreeZone ? _freeZoneKm : 0.0,
freeZoneMinutes: _applyFreeZone ? _freeZoneMinutes.toDouble() : 0.0,
); );
final fuel = route.fuelCost( final fuel = route.fuelCost(
consumptionPer100km: vehicle.consumptionPer100km, consumptionPer100km: vehicle.consumptionPer100km,
fuelPricePerLiter: fuelPrice, fuelPricePerLiter: fuelPrice,
freeZoneKm: _applyFreeZone ? 20 : 0, freeZoneKm: _applyFreeZone ? _freeZoneKm : 0.0,
); );
final maint = route.maintenanceCost( final maint = route.maintenanceCost(
costPerKm: vehicle.maintenanceCostPerKm, costPerKm: vehicle.maintenanceCostPerKm,
freeZoneKm: _applyFreeZone ? 20 : 0, freeZoneKm: _applyFreeZone ? _freeZoneKm : 0.0,
); );
final labor = route.laborCost( final labor = route.laborCost(
nbTechnicians: _nbTechnicians, nbTechnicians: _nbTechnicians,
hourlyRate: _hourlyRate, hourlyRate: _hourlyRate,
freeZoneMinutes: _applyFreeZone ? 20 : 0, freeZoneMinutes: _applyFreeZone ? _freeZoneMinutes.toDouble() : 0.0,
); );
final isToll = route.routeType == 'TOLL'; final isToll = route.routeType == 'TOLL';
+3 -3
View File
@@ -1,7 +1,7 @@
{ {
"version": "1.2.4", "version": "1.2.10",
"updateUrl": "https://app.em2events.fr", "updateUrl": "https://app.em2events.fr",
"forceUpdate": true, "forceUpdate": true,
"releaseNotes": "Ajout de la fonction retour en arriere pour la validation du chargement des equipements et des conteneurs.", "releaseNotes": "- Fix bug date des evenements, migration des dates vers le fuseau horaire Europe/Paris",
"timestamp": "2026-05-27T20:00:59.431Z" "timestamp": "2026-06-12T15:03:42.420Z"
} }