Compare commits
19 Commits
2.1.0
..
f4ba85bcb9
| Author | SHA1 | Date | |
|---|---|---|---|
| f4ba85bcb9 | |||
| 47442be3ef | |||
| 8882cf8ee2 | |||
| 00bcc775fe | |||
| 5a4d4c45dc | |||
| 7fc8d2c09c | |||
| bfe24812bd | |||
| 746f9e23bb | |||
| a53c7ace53 | |||
| efe37b8a96 | |||
| 49423f40f5 | |||
| 9abc2a8b19 | |||
| 9d96ec5543 | |||
| b6a4148829 | |||
| d8c61458ea | |||
| 9453c15d58 | |||
| 76870c27bf | |||
| ef7fe6e2bd | |||
| 4f53d903eb |
@@ -0,0 +1,73 @@
|
||||
# AGENTS.md — mgt2-compendium-amiral-denisov
|
||||
|
||||
## First read
|
||||
|
||||
- `.github/copilot-instructions.md` — packs, icons, module.json conventions (this file builds on it, don't repeat it)
|
||||
|
||||
## No package manager / no build
|
||||
|
||||
There is **no** `package.json`, no lockfile, no bundler. JavaScript is plain ESM loaded directly by FoundryVTT. Do not run `npm install` or any build command.
|
||||
|
||||
## Commands
|
||||
|
||||
5 chat commands registered at runtime (not declared in `module.json`):
|
||||
|
||||
| Command | Entrypoint | Dialog |
|
||||
|---|---|---|
|
||||
| `/commerce` | `scripts/commerce.js` | `CommerceDialog` (3 tabs) |
|
||||
| `/pnj` | `scripts/npc.js` | `NpcDialog` (4 tabs) |
|
||||
| `/rencontre` | `scripts/npc.js` | same dialog (tab 2) |
|
||||
| `/mission` | `scripts/npc.js` | same dialog (tab 3) |
|
||||
| `/sector` | `scripts/sector.js` | `SectorMapApp` (IFRAME Traveller Map, clics→chat) |
|
||||
| `/subsector` | `scripts/sector.js` | `SectorMapApp` (IFRAME) |
|
||||
|
||||
Commands are registered via `ChatLogV2.CHAT_COMMANDS` — not Hooks.on("chatMessage") as the copilot-instructions say (that file is stale). See `commerce.js:15` and `npc.js:15` for the actual pattern.
|
||||
|
||||
## Framework quirks
|
||||
|
||||
- **ApplicationV2** + `HandlebarsApplicationMixin` for all dialogs.
|
||||
- Foundry v13/v14 dual code paths: some hooks must handle both jQuery (v13) and DOM (v14) APIs.
|
||||
- Dice rolls: `await new Roll(formula).evaluate()` — always async.
|
||||
- Skill FQN format for `game.i18n`: e.g. `pilot.spacecraft`, `electronics.computers`, `gunner.turret`.
|
||||
|
||||
## Runtime systems (run at `ready` hook, GM only)
|
||||
|
||||
1. **Migration** (`mgt2eMigration.js`): converts legacy item types to mgt2e (armor→armour, equipment→item/augment, computer→hardware, etc.). Tracked via `game.settings` version flag. Forced re-run requires deleting the setting.
|
||||
|
||||
2. **NPC RollTable sync** (`npcRollTableSync.js`): writes D66 tables from `scripts/data/npcTables.js` into the `tables-pnj` compendium pack. Checksums to avoid redundant writes.
|
||||
|
||||
## Testing
|
||||
|
||||
```sh
|
||||
# standalone, no npm needed — install jest globally or use npx
|
||||
npx jest scripts/tests/travellerNpcGenerator.test.js
|
||||
```
|
||||
|
||||
- Single file, 1096 lines, hand-rolled FoundryVTT mocks.
|
||||
- Covers: utilities, lookups, validation, characteristic/skill generation, skill conversion, full NPC gen, ModuleCache, errors, config validation.
|
||||
- No CI test step — you must run manually.
|
||||
- No Jest config file — relies on defaults.
|
||||
|
||||
## Versioning
|
||||
|
||||
- `module.json` → `"version"` is the single source of truth.
|
||||
- Git tag format: `v1.3.0` (CI strips `v`).
|
||||
- No changelog file.
|
||||
|
||||
## CI/CD (Gitea)
|
||||
|
||||
- Only triggers on **`release: [published]`** — not on push/PR.
|
||||
- Builds a zip archive of `module.json + assets/ + packs/ + scripts/ + styles/ + templates/` and uploads to the release.
|
||||
- No test step in CI.
|
||||
|
||||
## Deprecated packs (still on disk, NOT in module.json)
|
||||
|
||||
- `packs/arme/` → superseded by `armes`
|
||||
- `packs/carriere/` → superseded by `carrieres`
|
||||
- `packs/talent-psy/` → superseded by `talents-psioniques`
|
||||
|
||||
Do not re-add them to `module.json`. They remain for historical data recovery only.
|
||||
|
||||
## All content is in French
|
||||
|
||||
Labels, comments, commit messages, UI strings, icon file names, rule references — everything. Check French naming before searching/grepping.
|
||||
@@ -0,0 +1,4 @@
|
||||
module.exports = {
|
||||
testMatch: ['**/scripts/tests/*.test.js'],
|
||||
transform: {},
|
||||
};
|
||||
+87
-4
@@ -1,21 +1,93 @@
|
||||
{
|
||||
"id": "mgt2-compendium-amiral-denisov",
|
||||
"title": "MgT2e - Compendium Amiral Denisov",
|
||||
"version": "1.2.1",
|
||||
"version": "1.3.0",
|
||||
"compatibility": {
|
||||
"minimum": "13",
|
||||
"verified": "13",
|
||||
"maximum": "14"
|
||||
},
|
||||
"description": "Module de compendium et d'outils Mongoose Traveller 2e pour FoundryVTT écrit par JdR.Ninja.\nInclut les commandes /commerce, /pnj, /rencontre et /mission pour automatiser le commerce, les PNJ rapides, les rencontres et les contrats aléatoires au-dessus du système mgt2e, en s'appuyant sur les compétences natives des fiches.",
|
||||
"socket": "true",
|
||||
"description": "Module de compendium et d'outils Mongoose Traveller 2e pour FoundryVTT écrit par JdR.Ninja.\nInclut les commandes /commerce, /pnj, /rencontre et /mission pour automatiser le commerce, les PNJ rapides, les rencontres et les contrats aléatoires. La fenêtre /pnj inclut un onglet 'PNJ Détaillé' pour la génération de PNJ Traveller selon les règles du générateur officiel, en s'appuyant sur les compétences natives des fiches.",
|
||||
"esmodules": [
|
||||
"scripts/batchNpcCreator.js",
|
||||
"scripts/commerce.js",
|
||||
"scripts/npc.js"
|
||||
"scripts/npc.js",
|
||||
"scripts/sector.js",
|
||||
"scripts/sectorSocket.js",
|
||||
"scripts/utils/travellerNpcUtils.js",
|
||||
"scripts/data/travellerNpcGenerator.js",
|
||||
"scripts/travellerNpcGenerator.js",
|
||||
"scripts/TravellerNpcDialog.js",
|
||||
"scripts/mgt2eMigration.js",
|
||||
"scripts/npcRollTableSync.js",
|
||||
"scripts/mgt2eSkills.js",
|
||||
"scripts/imperialCalendar.js"
|
||||
],
|
||||
"styles": [
|
||||
"styles/commerce.css",
|
||||
"styles/npc.css"
|
||||
"styles/npc.css",
|
||||
"styles/traveller-npc.css"
|
||||
],
|
||||
"packFolders": {
|
||||
"name": "Amiral Denisov",
|
||||
"sorting": "m",
|
||||
"color": "#00435c",
|
||||
"folders": [
|
||||
{
|
||||
"name": "Equipements",
|
||||
"sorting": "a",
|
||||
"color": "#00435c",
|
||||
"packs": [
|
||||
"armures",
|
||||
"objet",
|
||||
"equipement",
|
||||
"ordinateur",
|
||||
"contenant-sac-coffre",
|
||||
"armes"
|
||||
],
|
||||
"folders": []
|
||||
},
|
||||
{
|
||||
"name": "Références",
|
||||
"sorting": "b",
|
||||
"color": "#00435c",
|
||||
"packs": [
|
||||
"competences",
|
||||
"maladie-poison-and-blessure",
|
||||
"espece",
|
||||
"talents-psioniques",
|
||||
"carrieres"
|
||||
],
|
||||
"folders": []
|
||||
},
|
||||
{
|
||||
"name": "PNJ & Items",
|
||||
"sorting": "c",
|
||||
"color": "#00435c",
|
||||
"packs": [
|
||||
"tables-pnj",
|
||||
"pnj",
|
||||
"competences",
|
||||
"maladie-poison-and-blessure",
|
||||
"espece",
|
||||
"talents-psioniques",
|
||||
"carrieres"
|
||||
],
|
||||
"folders": []
|
||||
},
|
||||
{
|
||||
"name": "Journaux",
|
||||
"sorting": "d",
|
||||
"color": "#00435c",
|
||||
"packs": [
|
||||
"journal"
|
||||
],
|
||||
"folders": []
|
||||
}
|
||||
],
|
||||
"packs": []
|
||||
},
|
||||
"packs": [
|
||||
{
|
||||
"name": "armures",
|
||||
@@ -159,6 +231,17 @@
|
||||
"PLAYER": "OBSERVER",
|
||||
"ASSISTANT": "OWNER"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "pnj",
|
||||
"label": "PNJs",
|
||||
"path": "packs/pnj",
|
||||
"type": "Actor",
|
||||
"system": "mgt2e",
|
||||
"ownership": {
|
||||
"PLAYER": "OBSERVER",
|
||||
"ASSISTANT": "OWNER"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"type": "module",
|
||||
"private": true
|
||||
}
|
||||
+1
-1
@@ -1 +1 @@
|
||||
MANIFEST-000075
|
||||
MANIFEST-000180
|
||||
|
||||
+8
-15
@@ -1,15 +1,8 @@
|
||||
2026/05/24-16:50:54.659414 7fdf5b7fe6c0 Recovering log #73
|
||||
2026/05/24-16:50:54.670747 7fdf5b7fe6c0 Delete type=3 #71
|
||||
2026/05/24-16:50:54.670783 7fdf5b7fe6c0 Delete type=0 #73
|
||||
2026/05/24-17:30:55.121088 7fdf5affd6c0 Level-0 table #78: started
|
||||
2026/05/24-17:30:55.125303 7fdf5affd6c0 Level-0 table #78: 9864 bytes OK
|
||||
2026/05/24-17:30:55.131248 7fdf5affd6c0 Delete type=0 #76
|
||||
2026/05/24-17:30:55.131416 7fdf5affd6c0 Manual compaction at level-0 from '!folders!673DRfEBYUliGnKJ' @ 72057594037927935 : 1 .. '!items!yoIqL0RQEnzNVJB6' @ 0 : 0; will stop at (end)
|
||||
2026/05/24-17:30:55.131452 7fdf5affd6c0 Manual compaction at level-1 from '!folders!673DRfEBYUliGnKJ' @ 72057594037927935 : 1 .. '!items!yoIqL0RQEnzNVJB6' @ 0 : 0; will stop at '!items!yoIqL0RQEnzNVJB6' @ 161 : 1
|
||||
2026/05/24-17:30:55.131457 7fdf5affd6c0 Compacting 1@1 + 1@2 files
|
||||
2026/05/24-17:30:55.134712 7fdf5affd6c0 Generated table #79@1: 29 keys, 10438 bytes
|
||||
2026/05/24-17:30:55.134726 7fdf5affd6c0 Compacted 1@1 + 1@2 files => 10438 bytes
|
||||
2026/05/24-17:30:55.141487 7fdf5affd6c0 compacted to: files[ 0 0 1 0 0 0 0 ]
|
||||
2026/05/24-17:30:55.141544 7fdf5affd6c0 Delete type=2 #70
|
||||
2026/05/24-17:30:55.141639 7fdf5affd6c0 Delete type=2 #78
|
||||
2026/05/24-17:30:55.187693 7fdf5affd6c0 Manual compaction at level-1 from '!items!yoIqL0RQEnzNVJB6' @ 161 : 1 .. '!items!yoIqL0RQEnzNVJB6' @ 0 : 0; will stop at (end)
|
||||
2026/07/25-16:54:40.235374 7fb397fff6c0 Recovering log #178
|
||||
2026/07/25-16:54:40.246219 7fb397fff6c0 Delete type=3 #176
|
||||
2026/07/25-16:54:40.246321 7fb397fff6c0 Delete type=0 #178
|
||||
2026/07/25-17:22:36.365586 7fb394b4f6c0 Level-0 table #183: started
|
||||
2026/07/25-17:22:36.365618 7fb394b4f6c0 Level-0 table #183: 0 bytes OK
|
||||
2026/07/25-17:22:36.372300 7fb394b4f6c0 Delete type=0 #181
|
||||
2026/07/25-17:22:36.379902 7fb394b4f6c0 Manual compaction at level-0 from '!folders!673DRfEBYUliGnKJ' @ 72057594037927935 : 1 .. '!items!yoIqL0RQEnzNVJB6' @ 0 : 0; will stop at (end)
|
||||
2026/07/25-17:22:36.380052 7fb394b4f6c0 Manual compaction at level-1 from '!folders!673DRfEBYUliGnKJ' @ 72057594037927935 : 1 .. '!items!yoIqL0RQEnzNVJB6' @ 0 : 0; will stop at (end)
|
||||
|
||||
+8
-8
@@ -1,8 +1,8 @@
|
||||
2026/05/18-20:27:59.998100 7f5a46ffd6c0 Recovering log #68
|
||||
2026/05/18-20:28:00.055719 7f5a46ffd6c0 Delete type=3 #66
|
||||
2026/05/18-20:28:00.055824 7f5a46ffd6c0 Delete type=0 #68
|
||||
2026/05/18-20:29:47.499128 7f5a467fc6c0 Level-0 table #74: started
|
||||
2026/05/18-20:29:47.499199 7f5a467fc6c0 Level-0 table #74: 0 bytes OK
|
||||
2026/05/18-20:29:47.505640 7f5a467fc6c0 Delete type=0 #72
|
||||
2026/05/18-20:29:47.505916 7f5a467fc6c0 Manual compaction at level-0 from '!folders!673DRfEBYUliGnKJ' @ 72057594037927935 : 1 .. '!items!yoIqL0RQEnzNVJB6' @ 0 : 0; will stop at (end)
|
||||
2026/05/18-20:29:47.505957 7f5a467fc6c0 Manual compaction at level-1 from '!folders!673DRfEBYUliGnKJ' @ 72057594037927935 : 1 .. '!items!yoIqL0RQEnzNVJB6' @ 0 : 0; will stop at (end)
|
||||
2026/07/25-16:21:45.460294 7fb3977fe6c0 Recovering log #174
|
||||
2026/07/25-16:21:45.470482 7fb3977fe6c0 Delete type=3 #172
|
||||
2026/07/25-16:21:45.470569 7fb3977fe6c0 Delete type=0 #174
|
||||
2026/07/25-16:34:16.350463 7fb394b4f6c0 Level-0 table #179: started
|
||||
2026/07/25-16:34:16.350531 7fb394b4f6c0 Level-0 table #179: 0 bytes OK
|
||||
2026/07/25-16:34:16.357551 7fb394b4f6c0 Delete type=0 #177
|
||||
2026/07/25-16:34:16.510151 7fb394b4f6c0 Manual compaction at level-0 from '!folders!673DRfEBYUliGnKJ' @ 72057594037927935 : 1 .. '!items!yoIqL0RQEnzNVJB6' @ 0 : 0; will stop at (end)
|
||||
2026/07/25-16:34:16.680246 7fb394b4f6c0 Manual compaction at level-1 from '!folders!673DRfEBYUliGnKJ' @ 72057594037927935 : 1 .. '!items!yoIqL0RQEnzNVJB6' @ 0 : 0; will stop at (end)
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -1 +1 @@
|
||||
MANIFEST-000174
|
||||
MANIFEST-000279
|
||||
|
||||
+8
-15
@@ -1,15 +1,8 @@
|
||||
2026/05/24-16:50:54.546518 7fdf5b7fe6c0 Recovering log #172
|
||||
2026/05/24-16:50:54.556572 7fdf5b7fe6c0 Delete type=3 #170
|
||||
2026/05/24-16:50:54.556614 7fdf5b7fe6c0 Delete type=0 #172
|
||||
2026/05/24-17:30:54.977322 7fdf5affd6c0 Level-0 table #177: started
|
||||
2026/05/24-17:30:54.980526 7fdf5affd6c0 Level-0 table #177: 3210 bytes OK
|
||||
2026/05/24-17:30:54.986935 7fdf5affd6c0 Delete type=0 #175
|
||||
2026/05/24-17:30:55.016293 7fdf5affd6c0 Manual compaction at level-0 from '!items!8xqChkoKK7i0c9M1' @ 72057594037927935 : 1 .. '!items!wpBopoosZiWXjlKD' @ 0 : 0; will stop at (end)
|
||||
2026/05/24-17:30:55.016335 7fdf5affd6c0 Manual compaction at level-1 from '!items!8xqChkoKK7i0c9M1' @ 72057594037927935 : 1 .. '!items!wpBopoosZiWXjlKD' @ 0 : 0; will stop at '!items!wpBopoosZiWXjlKD' @ 78 : 1
|
||||
2026/05/24-17:30:55.016340 7fdf5affd6c0 Compacting 1@1 + 1@2 files
|
||||
2026/05/24-17:30:55.019483 7fdf5affd6c0 Generated table #178@1: 6 keys, 3210 bytes
|
||||
2026/05/24-17:30:55.019496 7fdf5affd6c0 Compacted 1@1 + 1@2 files => 3210 bytes
|
||||
2026/05/24-17:30:55.026070 7fdf5affd6c0 compacted to: files[ 0 0 1 0 0 0 0 ]
|
||||
2026/05/24-17:30:55.026126 7fdf5affd6c0 Delete type=2 #169
|
||||
2026/05/24-17:30:55.026250 7fdf5affd6c0 Delete type=2 #177
|
||||
2026/05/24-17:30:55.052180 7fdf5affd6c0 Manual compaction at level-1 from '!items!wpBopoosZiWXjlKD' @ 78 : 1 .. '!items!wpBopoosZiWXjlKD' @ 0 : 0; will stop at (end)
|
||||
2026/07/25-16:54:40.104032 7fb3e4fff6c0 Recovering log #277
|
||||
2026/07/25-16:54:40.114576 7fb3e4fff6c0 Delete type=3 #275
|
||||
2026/07/25-16:54:40.114680 7fb3e4fff6c0 Delete type=0 #277
|
||||
2026/07/25-17:22:36.288710 7fb394b4f6c0 Level-0 table #282: started
|
||||
2026/07/25-17:22:36.288757 7fb394b4f6c0 Level-0 table #282: 0 bytes OK
|
||||
2026/07/25-17:22:36.295586 7fb394b4f6c0 Delete type=0 #280
|
||||
2026/07/25-17:22:36.302495 7fb394b4f6c0 Manual compaction at level-0 from '!items!8xqChkoKK7i0c9M1' @ 72057594037927935 : 1 .. '!items!wpBopoosZiWXjlKD' @ 0 : 0; will stop at (end)
|
||||
2026/07/25-17:22:36.302790 7fb394b4f6c0 Manual compaction at level-1 from '!items!8xqChkoKK7i0c9M1' @ 72057594037927935 : 1 .. '!items!wpBopoosZiWXjlKD' @ 0 : 0; will stop at (end)
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
2026/05/18-20:27:59.309876 7f5a477fe6c0 Recovering log #167
|
||||
2026/05/18-20:27:59.371762 7f5a477fe6c0 Delete type=3 #165
|
||||
2026/05/18-20:27:59.371874 7f5a477fe6c0 Delete type=0 #167
|
||||
2026/05/18-20:29:47.416279 7f5a467fc6c0 Level-0 table #173: started
|
||||
2026/05/18-20:29:47.416343 7f5a467fc6c0 Level-0 table #173: 0 bytes OK
|
||||
2026/05/18-20:29:47.425598 7f5a467fc6c0 Delete type=0 #171
|
||||
2026/05/18-20:29:47.425873 7f5a467fc6c0 Manual compaction at level-0 from '!items!8xqChkoKK7i0c9M1' @ 72057594037927935 : 1 .. '!items!wpBopoosZiWXjlKD' @ 0 : 0; will stop at (end)
|
||||
2026/05/18-20:29:47.425920 7f5a467fc6c0 Manual compaction at level-1 from '!items!8xqChkoKK7i0c9M1' @ 72057594037927935 : 1 .. '!items!wpBopoosZiWXjlKD' @ 0 : 0; will stop at (end)
|
||||
2026/07/25-16:21:45.335501 7fb397fff6c0 Recovering log #273
|
||||
2026/07/25-16:21:45.346461 7fb397fff6c0 Delete type=3 #271
|
||||
2026/07/25-16:21:45.346548 7fb397fff6c0 Delete type=0 #273
|
||||
2026/07/25-16:34:16.287513 7fb394b4f6c0 Level-0 table #278: started
|
||||
2026/07/25-16:34:16.287557 7fb394b4f6c0 Level-0 table #278: 0 bytes OK
|
||||
2026/07/25-16:34:16.294033 7fb394b4f6c0 Delete type=0 #276
|
||||
2026/07/25-16:34:16.294225 7fb394b4f6c0 Manual compaction at level-0 from '!items!8xqChkoKK7i0c9M1' @ 72057594037927935 : 1 .. '!items!wpBopoosZiWXjlKD' @ 0 : 0; will stop at (end)
|
||||
2026/07/25-16:34:16.301494 7fb394b4f6c0 Manual compaction at level-1 from '!items!8xqChkoKK7i0c9M1' @ 72057594037927935 : 1 .. '!items!wpBopoosZiWXjlKD' @ 0 : 0; will stop at (end)
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -1 +1 @@
|
||||
MANIFEST-000058
|
||||
MANIFEST-000163
|
||||
|
||||
+8
-15
@@ -1,15 +1,8 @@
|
||||
2026/05/24-16:50:54.686699 7fdf5bfff6c0 Recovering log #56
|
||||
2026/05/24-16:50:54.695982 7fdf5bfff6c0 Delete type=3 #54
|
||||
2026/05/24-16:50:54.696016 7fdf5bfff6c0 Delete type=0 #56
|
||||
2026/05/24-17:30:55.150957 7fdf5affd6c0 Level-0 table #61: started
|
||||
2026/05/24-17:30:55.154345 7fdf5affd6c0 Level-0 table #61: 4273 bytes OK
|
||||
2026/05/24-17:30:55.160772 7fdf5affd6c0 Delete type=0 #59
|
||||
2026/05/24-17:30:55.187706 7fdf5affd6c0 Manual compaction at level-0 from '!items!57vgsVVCy9MRKM2M' @ 72057594037927935 : 1 .. '!items!vJInnoigCTJzuY2S' @ 0 : 0; will stop at (end)
|
||||
2026/05/24-17:30:55.210353 7fdf5affd6c0 Manual compaction at level-1 from '!items!57vgsVVCy9MRKM2M' @ 72057594037927935 : 1 .. '!items!vJInnoigCTJzuY2S' @ 0 : 0; will stop at '!items!vJInnoigCTJzuY2S' @ 126 : 1
|
||||
2026/05/24-17:30:55.210359 7fdf5affd6c0 Compacting 1@1 + 1@2 files
|
||||
2026/05/24-17:30:55.213753 7fdf5affd6c0 Generated table #62@1: 16 keys, 4273 bytes
|
||||
2026/05/24-17:30:55.213776 7fdf5affd6c0 Compacted 1@1 + 1@2 files => 4273 bytes
|
||||
2026/05/24-17:30:55.220661 7fdf5affd6c0 compacted to: files[ 0 0 1 0 0 0 0 ]
|
||||
2026/05/24-17:30:55.220738 7fdf5affd6c0 Delete type=2 #53
|
||||
2026/05/24-17:30:55.220857 7fdf5affd6c0 Delete type=2 #61
|
||||
2026/05/24-17:30:55.237555 7fdf5affd6c0 Manual compaction at level-1 from '!items!vJInnoigCTJzuY2S' @ 126 : 1 .. '!items!vJInnoigCTJzuY2S' @ 0 : 0; will stop at (end)
|
||||
2026/07/25-16:54:40.265755 7fb397fff6c0 Recovering log #161
|
||||
2026/07/25-16:54:40.276688 7fb397fff6c0 Delete type=3 #159
|
||||
2026/07/25-16:54:40.276786 7fb397fff6c0 Delete type=0 #161
|
||||
2026/07/25-17:22:36.380101 7fb394b4f6c0 Level-0 table #166: started
|
||||
2026/07/25-17:22:36.380168 7fb394b4f6c0 Level-0 table #166: 0 bytes OK
|
||||
2026/07/25-17:22:36.386681 7fb394b4f6c0 Delete type=0 #164
|
||||
2026/07/25-17:22:36.535741 7fb394b4f6c0 Manual compaction at level-0 from '!items!57vgsVVCy9MRKM2M' @ 72057594037927935 : 1 .. '!items!vJInnoigCTJzuY2S' @ 0 : 0; will stop at (end)
|
||||
2026/07/25-17:22:36.806569 7fb394b4f6c0 Manual compaction at level-1 from '!items!57vgsVVCy9MRKM2M' @ 72057594037927935 : 1 .. '!items!vJInnoigCTJzuY2S' @ 0 : 0; will stop at (end)
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
2026/05/18-20:28:00.170623 7f5a477fe6c0 Recovering log #51
|
||||
2026/05/18-20:28:00.231017 7f5a477fe6c0 Delete type=3 #49
|
||||
2026/05/18-20:28:00.231120 7f5a477fe6c0 Delete type=0 #51
|
||||
2026/05/18-20:29:47.515216 7f5a467fc6c0 Level-0 table #57: started
|
||||
2026/05/18-20:29:47.515280 7f5a467fc6c0 Level-0 table #57: 0 bytes OK
|
||||
2026/05/18-20:29:47.522604 7f5a467fc6c0 Delete type=0 #55
|
||||
2026/05/18-20:29:47.522854 7f5a467fc6c0 Manual compaction at level-0 from '!items!57vgsVVCy9MRKM2M' @ 72057594037927935 : 1 .. '!items!vJInnoigCTJzuY2S' @ 0 : 0; will stop at (end)
|
||||
2026/05/18-20:29:47.522882 7f5a467fc6c0 Manual compaction at level-1 from '!items!57vgsVVCy9MRKM2M' @ 72057594037927935 : 1 .. '!items!vJInnoigCTJzuY2S' @ 0 : 0; will stop at (end)
|
||||
2026/07/25-16:21:45.488403 7fb397fff6c0 Recovering log #157
|
||||
2026/07/25-16:21:45.499075 7fb397fff6c0 Delete type=3 #155
|
||||
2026/07/25-16:21:45.499160 7fb397fff6c0 Delete type=0 #157
|
||||
2026/07/25-16:34:16.357718 7fb394b4f6c0 Level-0 table #162: started
|
||||
2026/07/25-16:34:16.357749 7fb394b4f6c0 Level-0 table #162: 0 bytes OK
|
||||
2026/07/25-16:34:16.364285 7fb394b4f6c0 Delete type=0 #160
|
||||
2026/07/25-16:34:16.510175 7fb394b4f6c0 Manual compaction at level-0 from '!items!57vgsVVCy9MRKM2M' @ 72057594037927935 : 1 .. '!items!vJInnoigCTJzuY2S' @ 0 : 0; will stop at (end)
|
||||
2026/07/25-16:34:16.680277 7fb394b4f6c0 Manual compaction at level-1 from '!items!57vgsVVCy9MRKM2M' @ 72057594037927935 : 1 .. '!items!vJInnoigCTJzuY2S' @ 0 : 0; will stop at (end)
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -1 +1 @@
|
||||
MANIFEST-000177
|
||||
MANIFEST-000282
|
||||
|
||||
+8
-15
@@ -1,15 +1,8 @@
|
||||
2026/05/24-16:50:54.559278 7fdf5bfff6c0 Recovering log #175
|
||||
2026/05/24-16:50:54.569235 7fdf5bfff6c0 Delete type=3 #173
|
||||
2026/05/24-16:50:54.569273 7fdf5bfff6c0 Delete type=0 #175
|
||||
2026/05/24-17:30:54.996524 7fdf5affd6c0 Level-0 table #180: started
|
||||
2026/05/24-17:30:55.000122 7fdf5affd6c0 Level-0 table #180: 30255 bytes OK
|
||||
2026/05/24-17:30:55.006363 7fdf5affd6c0 Delete type=0 #178
|
||||
2026/05/24-17:30:55.016315 7fdf5affd6c0 Manual compaction at level-0 from '!items!04MdBSzwkYWUMJBC' @ 72057594037927935 : 1 .. '!items!yqjKyTCgpclCuHyK' @ 0 : 0; will stop at (end)
|
||||
2026/05/24-17:30:55.041863 7fdf5affd6c0 Manual compaction at level-1 from '!items!04MdBSzwkYWUMJBC' @ 72057594037927935 : 1 .. '!items!yqjKyTCgpclCuHyK' @ 0 : 0; will stop at '!items!yqjKyTCgpclCuHyK' @ 544 : 1
|
||||
2026/05/24-17:30:55.041874 7fdf5affd6c0 Compacting 1@1 + 1@2 files
|
||||
2026/05/24-17:30:55.045796 7fdf5affd6c0 Generated table #181@1: 39 keys, 30255 bytes
|
||||
2026/05/24-17:30:55.045823 7fdf5affd6c0 Compacted 1@1 + 1@2 files => 30255 bytes
|
||||
2026/05/24-17:30:55.051904 7fdf5affd6c0 compacted to: files[ 0 0 1 0 0 0 0 ]
|
||||
2026/05/24-17:30:55.051997 7fdf5affd6c0 Delete type=2 #172
|
||||
2026/05/24-17:30:55.052110 7fdf5affd6c0 Delete type=2 #180
|
||||
2026/05/24-17:30:55.062783 7fdf5affd6c0 Manual compaction at level-1 from '!items!yqjKyTCgpclCuHyK' @ 544 : 1 .. '!items!yqjKyTCgpclCuHyK' @ 0 : 0; will stop at (end)
|
||||
2026/07/25-16:54:40.118657 7fb3977fe6c0 Recovering log #280
|
||||
2026/07/25-16:54:40.129567 7fb3977fe6c0 Delete type=3 #278
|
||||
2026/07/25-16:54:40.129662 7fb3977fe6c0 Delete type=0 #280
|
||||
2026/07/25-17:22:36.295712 7fb394b4f6c0 Level-0 table #285: started
|
||||
2026/07/25-17:22:36.295740 7fb394b4f6c0 Level-0 table #285: 0 bytes OK
|
||||
2026/07/25-17:22:36.302356 7fb394b4f6c0 Delete type=0 #283
|
||||
2026/07/25-17:22:36.302757 7fb394b4f6c0 Manual compaction at level-0 from '!items!04MdBSzwkYWUMJBC' @ 72057594037927935 : 1 .. '!items!yqjKyTCgpclCuHyK' @ 0 : 0; will stop at (end)
|
||||
2026/07/25-17:22:36.317403 7fb394b4f6c0 Manual compaction at level-1 from '!items!04MdBSzwkYWUMJBC' @ 72057594037927935 : 1 .. '!items!yqjKyTCgpclCuHyK' @ 0 : 0; will stop at (end)
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
2026/05/18-20:27:59.380990 7f5a47fff6c0 Recovering log #170
|
||||
2026/05/18-20:27:59.439837 7f5a47fff6c0 Delete type=3 #168
|
||||
2026/05/18-20:27:59.439975 7f5a47fff6c0 Delete type=0 #170
|
||||
2026/05/18-20:29:47.426912 7f5a467fc6c0 Level-0 table #176: started
|
||||
2026/05/18-20:29:47.426974 7f5a467fc6c0 Level-0 table #176: 0 bytes OK
|
||||
2026/05/18-20:29:47.437378 7f5a467fc6c0 Delete type=0 #174
|
||||
2026/05/18-20:29:47.437633 7f5a467fc6c0 Manual compaction at level-0 from '!items!04MdBSzwkYWUMJBC' @ 72057594037927935 : 1 .. '!items!yqjKyTCgpclCuHyK' @ 0 : 0; will stop at (end)
|
||||
2026/05/18-20:29:47.437658 7f5a467fc6c0 Manual compaction at level-1 from '!items!04MdBSzwkYWUMJBC' @ 72057594037927935 : 1 .. '!items!yqjKyTCgpclCuHyK' @ 0 : 0; will stop at (end)
|
||||
2026/07/25-16:21:45.349559 7fb396ffd6c0 Recovering log #276
|
||||
2026/07/25-16:21:45.359598 7fb396ffd6c0 Delete type=3 #274
|
||||
2026/07/25-16:21:45.359698 7fb396ffd6c0 Delete type=0 #276
|
||||
2026/07/25-16:34:16.308405 7fb394b4f6c0 Level-0 table #281: started
|
||||
2026/07/25-16:34:16.308432 7fb394b4f6c0 Level-0 table #281: 0 bytes OK
|
||||
2026/07/25-16:34:16.316009 7fb394b4f6c0 Delete type=0 #279
|
||||
2026/07/25-16:34:16.322893 7fb394b4f6c0 Manual compaction at level-0 from '!items!04MdBSzwkYWUMJBC' @ 72057594037927935 : 1 .. '!items!yqjKyTCgpclCuHyK' @ 0 : 0; will stop at (end)
|
||||
2026/07/25-16:34:16.323046 7fb394b4f6c0 Manual compaction at level-1 from '!items!04MdBSzwkYWUMJBC' @ 72057594037927935 : 1 .. '!items!yqjKyTCgpclCuHyK' @ 0 : 0; will stop at (end)
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -1 +1 @@
|
||||
MANIFEST-000112
|
||||
MANIFEST-000216
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
2026/05/24-16:50:54.623242 7fdf5bfff6c0 Recovering log #110
|
||||
2026/05/24-16:50:54.633193 7fdf5bfff6c0 Delete type=3 #108
|
||||
2026/05/24-16:50:54.633252 7fdf5bfff6c0 Delete type=0 #110
|
||||
2026/05/24-17:30:55.081463 7fdf5affd6c0 Level-0 table #115: started
|
||||
2026/05/24-17:30:55.081487 7fdf5affd6c0 Level-0 table #115: 0 bytes OK
|
||||
2026/05/24-17:30:55.087560 7fdf5affd6c0 Delete type=0 #113
|
||||
2026/05/24-17:30:55.097957 7fdf5affd6c0 Manual compaction at level-0 from 'undefined' @ 72057594037927935 : 1 .. 'undefined' @ 0 : 0; will stop at (end)
|
||||
2026/07/25-16:54:40.192611 7fb3e4fff6c0 Recovering log #214
|
||||
2026/07/25-16:54:40.203144 7fb3e4fff6c0 Delete type=3 #212
|
||||
2026/07/25-16:54:40.203218 7fb3e4fff6c0 Delete type=0 #214
|
||||
2026/07/25-17:22:36.334207 7fb394b4f6c0 Level-0 table #219: started
|
||||
2026/07/25-17:22:36.334237 7fb394b4f6c0 Level-0 table #219: 0 bytes OK
|
||||
2026/07/25-17:22:36.344490 7fb394b4f6c0 Delete type=0 #217
|
||||
2026/07/25-17:22:36.358562 7fb394b4f6c0 Manual compaction at level-0 from 'undefined' @ 72057594037927935 : 1 .. 'undefined' @ 0 : 0; will stop at (end)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
2026/05/18-20:27:59.766699 7f5a47fff6c0 Recovering log #106
|
||||
2026/05/18-20:27:59.824574 7f5a47fff6c0 Delete type=3 #104
|
||||
2026/05/18-20:27:59.824666 7f5a47fff6c0 Delete type=0 #106
|
||||
2026/05/18-20:29:47.472932 7f5a467fc6c0 Level-0 table #111: started
|
||||
2026/05/18-20:29:47.473002 7f5a467fc6c0 Level-0 table #111: 0 bytes OK
|
||||
2026/05/18-20:29:47.479740 7f5a467fc6c0 Delete type=0 #109
|
||||
2026/05/18-20:29:47.479998 7f5a467fc6c0 Manual compaction at level-0 from 'undefined' @ 72057594037927935 : 1 .. 'undefined' @ 0 : 0; will stop at (end)
|
||||
2026/07/25-16:21:45.418689 7fb397fff6c0 Recovering log #210
|
||||
2026/07/25-16:21:45.429568 7fb397fff6c0 Delete type=3 #208
|
||||
2026/07/25-16:21:45.429651 7fb397fff6c0 Delete type=0 #210
|
||||
2026/07/25-16:34:16.329833 7fb394b4f6c0 Level-0 table #215: started
|
||||
2026/07/25-16:34:16.329859 7fb394b4f6c0 Level-0 table #215: 0 bytes OK
|
||||
2026/07/25-16:34:16.336695 7fb394b4f6c0 Delete type=0 #213
|
||||
2026/07/25-16:34:16.350122 7fb394b4f6c0 Manual compaction at level-0 from 'undefined' @ 72057594037927935 : 1 .. 'undefined' @ 0 : 0; will stop at (end)
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -1 +1 @@
|
||||
MANIFEST-000119
|
||||
MANIFEST-000224
|
||||
|
||||
+8
-15
@@ -1,15 +1,8 @@
|
||||
2026/05/24-16:50:54.597446 7fdf5b7fe6c0 Recovering log #117
|
||||
2026/05/24-16:50:54.607335 7fdf5b7fe6c0 Delete type=3 #115
|
||||
2026/05/24-16:50:54.607379 7fdf5b7fe6c0 Delete type=0 #117
|
||||
2026/05/24-17:30:55.052370 7fdf5affd6c0 Level-0 table #122: started
|
||||
2026/05/24-17:30:55.056355 7fdf5affd6c0 Level-0 table #122: 20248 bytes OK
|
||||
2026/05/24-17:30:55.062721 7fdf5affd6c0 Delete type=0 #120
|
||||
2026/05/24-17:30:55.081449 7fdf5affd6c0 Manual compaction at level-0 from '!folders!8swFcTr6RH7BnGiu' @ 72057594037927935 : 1 .. '!items!zRJfxioYBRq4iSBR' @ 0 : 0; will stop at (end)
|
||||
2026/05/24-17:30:55.087647 7fdf5affd6c0 Manual compaction at level-1 from '!folders!8swFcTr6RH7BnGiu' @ 72057594037927935 : 1 .. '!items!zRJfxioYBRq4iSBR' @ 0 : 0; will stop at '!items!zRJfxioYBRq4iSBR' @ 258 : 1
|
||||
2026/05/24-17:30:55.087653 7fdf5affd6c0 Compacting 1@1 + 1@2 files
|
||||
2026/05/24-17:30:55.091676 7fdf5affd6c0 Generated table #123@1: 42 keys, 19863 bytes
|
||||
2026/05/24-17:30:55.091690 7fdf5affd6c0 Compacted 1@1 + 1@2 files => 19863 bytes
|
||||
2026/05/24-17:30:55.097740 7fdf5affd6c0 compacted to: files[ 0 0 1 0 0 0 0 ]
|
||||
2026/05/24-17:30:55.097812 7fdf5affd6c0 Delete type=2 #114
|
||||
2026/05/24-17:30:55.097896 7fdf5affd6c0 Delete type=2 #122
|
||||
2026/05/24-17:30:55.104450 7fdf5affd6c0 Manual compaction at level-1 from '!items!zRJfxioYBRq4iSBR' @ 258 : 1 .. '!items!zRJfxioYBRq4iSBR' @ 0 : 0; will stop at (end)
|
||||
2026/07/25-16:54:40.162927 7fb3e4fff6c0 Recovering log #222
|
||||
2026/07/25-16:54:40.173541 7fb3e4fff6c0 Delete type=3 #220
|
||||
2026/07/25-16:54:40.173643 7fb3e4fff6c0 Delete type=0 #222
|
||||
2026/07/25-17:22:36.324212 7fb394b4f6c0 Level-0 table #227: started
|
||||
2026/07/25-17:22:36.324245 7fb394b4f6c0 Level-0 table #227: 0 bytes OK
|
||||
2026/07/25-17:22:36.333994 7fb394b4f6c0 Delete type=0 #225
|
||||
2026/07/25-17:22:36.358543 7fb394b4f6c0 Manual compaction at level-0 from '!folders!8swFcTr6RH7BnGiu' @ 72057594037927935 : 1 .. '!items!zRJfxioYBRq4iSBR' @ 0 : 0; will stop at (end)
|
||||
2026/07/25-17:22:36.358932 7fb394b4f6c0 Manual compaction at level-1 from '!folders!8swFcTr6RH7BnGiu' @ 72057594037927935 : 1 .. '!items!zRJfxioYBRq4iSBR' @ 0 : 0; will stop at (end)
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
2026/05/18-20:27:59.596317 7f5a47fff6c0 Recovering log #112
|
||||
2026/05/18-20:27:59.649784 7f5a47fff6c0 Delete type=3 #110
|
||||
2026/05/18-20:27:59.649914 7f5a47fff6c0 Delete type=0 #112
|
||||
2026/05/18-20:29:47.456954 7f5a467fc6c0 Level-0 table #118: started
|
||||
2026/05/18-20:29:47.457019 7f5a467fc6c0 Level-0 table #118: 0 bytes OK
|
||||
2026/05/18-20:29:47.463638 7f5a467fc6c0 Delete type=0 #116
|
||||
2026/05/18-20:29:47.463868 7f5a467fc6c0 Manual compaction at level-0 from '!folders!8swFcTr6RH7BnGiu' @ 72057594037927935 : 1 .. '!items!zRJfxioYBRq4iSBR' @ 0 : 0; will stop at (end)
|
||||
2026/05/18-20:29:47.463950 7f5a467fc6c0 Manual compaction at level-1 from '!folders!8swFcTr6RH7BnGiu' @ 72057594037927935 : 1 .. '!items!zRJfxioYBRq4iSBR' @ 0 : 0; will stop at (end)
|
||||
2026/07/25-16:21:45.391004 7fb397fff6c0 Recovering log #218
|
||||
2026/07/25-16:21:45.401154 7fb397fff6c0 Delete type=3 #216
|
||||
2026/07/25-16:21:45.401258 7fb397fff6c0 Delete type=0 #218
|
||||
2026/07/25-16:34:16.316171 7fb394b4f6c0 Level-0 table #223: started
|
||||
2026/07/25-16:34:16.316199 7fb394b4f6c0 Level-0 table #223: 0 bytes OK
|
||||
2026/07/25-16:34:16.322746 7fb394b4f6c0 Delete type=0 #221
|
||||
2026/07/25-16:34:16.323022 7fb394b4f6c0 Manual compaction at level-0 from '!folders!8swFcTr6RH7BnGiu' @ 72057594037927935 : 1 .. '!items!zRJfxioYBRq4iSBR' @ 0 : 0; will stop at (end)
|
||||
2026/07/25-16:34:16.329820 7fb394b4f6c0 Manual compaction at level-1 from '!folders!8swFcTr6RH7BnGiu' @ 72057594037927935 : 1 .. '!items!zRJfxioYBRq4iSBR' @ 0 : 0; will stop at (end)
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -1 +1 @@
|
||||
MANIFEST-000112
|
||||
MANIFEST-000216
|
||||
|
||||
+7
-7
@@ -1,7 +1,7 @@
|
||||
2026/05/24-16:50:54.634756 7fdfa8dfe6c0 Recovering log #110
|
||||
2026/05/24-16:50:54.645375 7fdfa8dfe6c0 Delete type=3 #108
|
||||
2026/05/24-16:50:54.645440 7fdfa8dfe6c0 Delete type=0 #110
|
||||
2026/05/24-17:30:55.097965 7fdf5affd6c0 Level-0 table #115: started
|
||||
2026/05/24-17:30:55.097985 7fdf5affd6c0 Level-0 table #115: 0 bytes OK
|
||||
2026/05/24-17:30:55.104346 7fdf5affd6c0 Delete type=0 #113
|
||||
2026/05/24-17:30:55.131378 7fdf5affd6c0 Manual compaction at level-0 from 'undefined' @ 72057594037927935 : 1 .. 'undefined' @ 0 : 0; will stop at (end)
|
||||
2026/07/25-16:54:40.207018 7fb396ffd6c0 Recovering log #214
|
||||
2026/07/25-16:54:40.218111 7fb396ffd6c0 Delete type=3 #212
|
||||
2026/07/25-16:54:40.218206 7fb396ffd6c0 Delete type=0 #214
|
||||
2026/07/25-17:22:36.344663 7fb394b4f6c0 Level-0 table #219: started
|
||||
2026/07/25-17:22:36.344695 7fb394b4f6c0 Level-0 table #219: 0 bytes OK
|
||||
2026/07/25-17:22:36.351019 7fb394b4f6c0 Delete type=0 #217
|
||||
2026/07/25-17:22:36.358578 7fb394b4f6c0 Manual compaction at level-0 from 'undefined' @ 72057594037927935 : 1 .. 'undefined' @ 0 : 0; will stop at (end)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
2026/05/18-20:27:59.838862 7f5a46ffd6c0 Recovering log #106
|
||||
2026/05/18-20:27:59.893943 7f5a46ffd6c0 Delete type=3 #104
|
||||
2026/05/18-20:27:59.894068 7f5a46ffd6c0 Delete type=0 #106
|
||||
2026/05/18-20:29:47.480953 7f5a467fc6c0 Level-0 table #111: started
|
||||
2026/05/18-20:29:47.481012 7f5a467fc6c0 Level-0 table #111: 0 bytes OK
|
||||
2026/05/18-20:29:47.487588 7f5a467fc6c0 Delete type=0 #109
|
||||
2026/05/18-20:29:47.487817 7f5a467fc6c0 Manual compaction at level-0 from 'undefined' @ 72057594037927935 : 1 .. 'undefined' @ 0 : 0; will stop at (end)
|
||||
2026/07/25-16:21:45.432370 7fb3e4fff6c0 Recovering log #210
|
||||
2026/07/25-16:21:45.442645 7fb3e4fff6c0 Delete type=3 #208
|
||||
2026/07/25-16:21:45.442704 7fb3e4fff6c0 Delete type=0 #210
|
||||
2026/07/25-16:34:16.336838 7fb394b4f6c0 Level-0 table #215: started
|
||||
2026/07/25-16:34:16.336867 7fb394b4f6c0 Level-0 table #215: 0 bytes OK
|
||||
2026/07/25-16:34:16.343246 7fb394b4f6c0 Delete type=0 #213
|
||||
2026/07/25-16:34:16.350151 7fb394b4f6c0 Manual compaction at level-0 from 'undefined' @ 72057594037927935 : 1 .. 'undefined' @ 0 : 0; will stop at (end)
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -1 +1 @@
|
||||
MANIFEST-000093
|
||||
MANIFEST-000197
|
||||
|
||||
+8
-8
@@ -1,8 +1,8 @@
|
||||
2026/05/24-16:50:54.647193 7fdf5b7fe6c0 Recovering log #91
|
||||
2026/05/24-16:50:54.656827 7fdf5b7fe6c0 Delete type=3 #89
|
||||
2026/05/24-16:50:54.656870 7fdf5b7fe6c0 Delete type=0 #91
|
||||
2026/05/24-17:30:55.114778 7fdf5affd6c0 Level-0 table #96: started
|
||||
2026/05/24-17:30:55.114807 7fdf5affd6c0 Level-0 table #96: 0 bytes OK
|
||||
2026/05/24-17:30:55.121001 7fdf5affd6c0 Delete type=0 #94
|
||||
2026/05/24-17:30:55.131407 7fdf5affd6c0 Manual compaction at level-0 from '!journal!26ZqV9BvS47hrLmV' @ 72057594037927935 : 1 .. '!journal.pages!26ZqV9BvS47hrLmV.ZS4936SEQUT9IA8i' @ 0 : 0; will stop at (end)
|
||||
2026/05/24-17:30:55.131437 7fdf5affd6c0 Manual compaction at level-1 from '!journal!26ZqV9BvS47hrLmV' @ 72057594037927935 : 1 .. '!journal.pages!26ZqV9BvS47hrLmV.ZS4936SEQUT9IA8i' @ 0 : 0; will stop at (end)
|
||||
2026/07/25-16:54:40.221457 7fb3e4fff6c0 Recovering log #195
|
||||
2026/07/25-16:54:40.231541 7fb3e4fff6c0 Delete type=3 #193
|
||||
2026/07/25-16:54:40.231630 7fb3e4fff6c0 Delete type=0 #195
|
||||
2026/07/25-17:22:36.358974 7fb394b4f6c0 Level-0 table #200: started
|
||||
2026/07/25-17:22:36.359013 7fb394b4f6c0 Level-0 table #200: 0 bytes OK
|
||||
2026/07/25-17:22:36.365407 7fb394b4f6c0 Delete type=0 #198
|
||||
2026/07/25-17:22:36.379885 7fb394b4f6c0 Manual compaction at level-0 from '!journal!26ZqV9BvS47hrLmV' @ 72057594037927935 : 1 .. '!journal.pages!26ZqV9BvS47hrLmV.ZS4936SEQUT9IA8i' @ 0 : 0; will stop at (end)
|
||||
2026/07/25-17:22:36.380062 7fb394b4f6c0 Manual compaction at level-1 from '!journal!26ZqV9BvS47hrLmV' @ 72057594037927935 : 1 .. '!journal.pages!26ZqV9BvS47hrLmV.ZS4936SEQUT9IA8i' @ 0 : 0; will stop at (end)
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
2026/05/18-20:27:59.909714 7f5a477fe6c0 Recovering log #87
|
||||
2026/05/18-20:27:59.963841 7f5a477fe6c0 Delete type=3 #85
|
||||
2026/05/18-20:27:59.963963 7f5a477fe6c0 Delete type=0 #87
|
||||
2026/05/18-20:29:47.488790 7f5a467fc6c0 Level-0 table #92: started
|
||||
2026/05/18-20:29:47.488852 7f5a467fc6c0 Level-0 table #92: 0 bytes OK
|
||||
2026/05/18-20:29:47.496720 7f5a467fc6c0 Delete type=0 #90
|
||||
2026/05/18-20:29:47.497943 7f5a467fc6c0 Manual compaction at level-0 from '!journal!26ZqV9BvS47hrLmV' @ 72057594037927935 : 1 .. '!journal.pages!26ZqV9BvS47hrLmV.ZS4936SEQUT9IA8i' @ 0 : 0; will stop at (end)
|
||||
2026/05/18-20:29:47.498034 7f5a467fc6c0 Manual compaction at level-1 from '!journal!26ZqV9BvS47hrLmV' @ 72057594037927935 : 1 .. '!journal.pages!26ZqV9BvS47hrLmV.ZS4936SEQUT9IA8i' @ 0 : 0; will stop at (end)
|
||||
2026/07/25-16:21:45.445936 7fb397fff6c0 Recovering log #191
|
||||
2026/07/25-16:21:45.456628 7fb397fff6c0 Delete type=3 #189
|
||||
2026/07/25-16:21:45.456706 7fb397fff6c0 Delete type=0 #191
|
||||
2026/07/25-16:34:16.343456 7fb394b4f6c0 Level-0 table #196: started
|
||||
2026/07/25-16:34:16.343486 7fb394b4f6c0 Level-0 table #196: 0 bytes OK
|
||||
2026/07/25-16:34:16.349952 7fb394b4f6c0 Delete type=0 #194
|
||||
2026/07/25-16:34:16.350230 7fb394b4f6c0 Manual compaction at level-0 from '!journal!26ZqV9BvS47hrLmV' @ 72057594037927935 : 1 .. '!journal.pages!26ZqV9BvS47hrLmV.ZS4936SEQUT9IA8i' @ 0 : 0; will stop at (end)
|
||||
2026/07/25-16:34:16.350280 7fb394b4f6c0 Manual compaction at level-1 from '!journal!26ZqV9BvS47hrLmV' @ 72057594037927935 : 1 .. '!journal.pages!26ZqV9BvS47hrLmV.ZS4936SEQUT9IA8i' @ 0 : 0; will stop at (end)
|
||||
|
||||
Binary file not shown.
@@ -1 +1 @@
|
||||
MANIFEST-000119
|
||||
MANIFEST-000224
|
||||
|
||||
@@ -1,15 +1,8 @@
|
||||
2026/05/24-16:50:54.573746 7fdf5bfff6c0 Recovering log #117
|
||||
2026/05/24-16:50:54.583876 7fdf5bfff6c0 Delete type=3 #115
|
||||
2026/05/24-16:50:54.583933 7fdf5bfff6c0 Delete type=0 #117
|
||||
2026/05/24-17:30:55.026316 7fdf5affd6c0 Level-0 table #122: started
|
||||
2026/05/24-17:30:55.029368 7fdf5affd6c0 Level-0 table #122: 1988 bytes OK
|
||||
2026/05/24-17:30:55.035351 7fdf5affd6c0 Delete type=0 #120
|
||||
2026/05/24-17:30:55.052192 7fdf5affd6c0 Manual compaction at level-0 from '!items!QHovFMj93BC7bqBu' @ 72057594037927935 : 1 .. '!items!yleVHgRqGoYLvzxT' @ 0 : 0; will stop at (end)
|
||||
2026/05/24-17:30:55.062793 7fdf5affd6c0 Manual compaction at level-1 from '!items!QHovFMj93BC7bqBu' @ 72057594037927935 : 1 .. '!items!yleVHgRqGoYLvzxT' @ 0 : 0; will stop at '!items!yleVHgRqGoYLvzxT' @ 56 : 1
|
||||
2026/05/24-17:30:55.062796 7fdf5affd6c0 Compacting 1@1 + 1@2 files
|
||||
2026/05/24-17:30:55.065855 7fdf5affd6c0 Generated table #123@1: 8 keys, 1988 bytes
|
||||
2026/05/24-17:30:55.065865 7fdf5affd6c0 Compacted 1@1 + 1@2 files => 1988 bytes
|
||||
2026/05/24-17:30:55.071780 7fdf5affd6c0 compacted to: files[ 0 0 1 0 0 0 0 ]
|
||||
2026/05/24-17:30:55.071820 7fdf5affd6c0 Delete type=2 #114
|
||||
2026/05/24-17:30:55.071877 7fdf5affd6c0 Delete type=2 #122
|
||||
2026/05/24-17:30:55.087630 7fdf5affd6c0 Manual compaction at level-1 from '!items!yleVHgRqGoYLvzxT' @ 56 : 1 .. '!items!yleVHgRqGoYLvzxT' @ 0 : 0; will stop at (end)
|
||||
2026/07/25-16:54:40.134268 7fb3e4fff6c0 Recovering log #222
|
||||
2026/07/25-16:54:40.144763 7fb3e4fff6c0 Delete type=3 #220
|
||||
2026/07/25-16:54:40.144868 7fb3e4fff6c0 Delete type=0 #222
|
||||
2026/07/25-17:22:36.302800 7fb394b4f6c0 Level-0 table #227: started
|
||||
2026/07/25-17:22:36.302838 7fb394b4f6c0 Level-0 table #227: 0 bytes OK
|
||||
2026/07/25-17:22:36.309558 7fb394b4f6c0 Delete type=0 #225
|
||||
2026/07/25-17:22:36.324180 7fb394b4f6c0 Manual compaction at level-0 from '!items!QHovFMj93BC7bqBu' @ 72057594037927935 : 1 .. '!items!yleVHgRqGoYLvzxT' @ 0 : 0; will stop at (end)
|
||||
2026/07/25-17:22:36.334192 7fb394b4f6c0 Manual compaction at level-1 from '!items!QHovFMj93BC7bqBu' @ 72057594037927935 : 1 .. '!items!yleVHgRqGoYLvzxT' @ 0 : 0; will stop at (end)
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
2026/05/18-20:27:59.461881 7f5a46ffd6c0 Recovering log #112
|
||||
2026/05/18-20:27:59.517849 7f5a46ffd6c0 Delete type=3 #110
|
||||
2026/05/18-20:27:59.517983 7f5a46ffd6c0 Delete type=0 #112
|
||||
2026/05/18-20:29:47.438640 7f5a467fc6c0 Level-0 table #118: started
|
||||
2026/05/18-20:29:47.438693 7f5a467fc6c0 Level-0 table #118: 0 bytes OK
|
||||
2026/05/18-20:29:47.445247 7f5a467fc6c0 Delete type=0 #116
|
||||
2026/05/18-20:29:47.445955 7f5a467fc6c0 Manual compaction at level-0 from '!items!QHovFMj93BC7bqBu' @ 72057594037927935 : 1 .. '!items!yleVHgRqGoYLvzxT' @ 0 : 0; will stop at (end)
|
||||
2026/05/18-20:29:47.446012 7f5a467fc6c0 Manual compaction at level-1 from '!items!QHovFMj93BC7bqBu' @ 72057594037927935 : 1 .. '!items!yleVHgRqGoYLvzxT' @ 0 : 0; will stop at (end)
|
||||
2026/07/25-16:21:45.362950 7fb397fff6c0 Recovering log #218
|
||||
2026/07/25-16:21:45.374396 7fb397fff6c0 Delete type=3 #216
|
||||
2026/07/25-16:21:45.374487 7fb397fff6c0 Delete type=0 #218
|
||||
2026/07/25-16:34:16.294555 7fb394b4f6c0 Level-0 table #223: started
|
||||
2026/07/25-16:34:16.294610 7fb394b4f6c0 Level-0 table #223: 0 bytes OK
|
||||
2026/07/25-16:34:16.301357 7fb394b4f6c0 Delete type=0 #221
|
||||
2026/07/25-16:34:16.316155 7fb394b4f6c0 Manual compaction at level-0 from '!items!QHovFMj93BC7bqBu' @ 72057594037927935 : 1 .. '!items!yleVHgRqGoYLvzxT' @ 0 : 0; will stop at (end)
|
||||
2026/07/25-16:34:16.322906 7fb394b4f6c0 Manual compaction at level-1 from '!items!QHovFMj93BC7bqBu' @ 72057594037927935 : 1 .. '!items!yleVHgRqGoYLvzxT' @ 0 : 0; will stop at (end)
|
||||
|
||||
Binary file not shown.
Binary file not shown.
+1
-1
@@ -1 +1 @@
|
||||
MANIFEST-000112
|
||||
MANIFEST-000216
|
||||
|
||||
+7
-7
@@ -1,7 +1,7 @@
|
||||
2026/05/24-16:50:54.586100 7fdfa8dfe6c0 Recovering log #110
|
||||
2026/05/24-16:50:54.595631 7fdfa8dfe6c0 Delete type=3 #108
|
||||
2026/05/24-16:50:54.595694 7fdfa8dfe6c0 Delete type=0 #110
|
||||
2026/05/24-17:30:55.035470 7fdf5affd6c0 Level-0 table #115: started
|
||||
2026/05/24-17:30:55.035483 7fdf5affd6c0 Level-0 table #115: 0 bytes OK
|
||||
2026/05/24-17:30:55.041734 7fdf5affd6c0 Delete type=0 #113
|
||||
2026/05/24-17:30:55.052200 7fdf5affd6c0 Manual compaction at level-0 from 'undefined' @ 72057594037927935 : 1 .. 'undefined' @ 0 : 0; will stop at (end)
|
||||
2026/07/25-16:54:40.148506 7fb3977fe6c0 Recovering log #214
|
||||
2026/07/25-16:54:40.159742 7fb3977fe6c0 Delete type=3 #212
|
||||
2026/07/25-16:54:40.159842 7fb3977fe6c0 Delete type=0 #214
|
||||
2026/07/25-17:22:36.317424 7fb394b4f6c0 Level-0 table #219: started
|
||||
2026/07/25-17:22:36.317453 7fb394b4f6c0 Level-0 table #219: 0 bytes OK
|
||||
2026/07/25-17:22:36.324008 7fb394b4f6c0 Delete type=0 #217
|
||||
2026/07/25-17:22:36.334172 7fb394b4f6c0 Manual compaction at level-0 from 'undefined' @ 72057594037927935 : 1 .. 'undefined' @ 0 : 0; will stop at (end)
|
||||
|
||||
+7
-7
@@ -1,7 +1,7 @@
|
||||
2026/05/18-20:27:59.526598 7f5a94bff6c0 Recovering log #106
|
||||
2026/05/18-20:27:59.589070 7f5a94bff6c0 Delete type=3 #104
|
||||
2026/05/18-20:27:59.589252 7f5a94bff6c0 Delete type=0 #106
|
||||
2026/05/18-20:29:47.448116 7f5a467fc6c0 Level-0 table #111: started
|
||||
2026/05/18-20:29:47.448187 7f5a467fc6c0 Level-0 table #111: 0 bytes OK
|
||||
2026/05/18-20:29:47.455433 7f5a467fc6c0 Delete type=0 #109
|
||||
2026/05/18-20:29:47.455684 7f5a467fc6c0 Manual compaction at level-0 from 'undefined' @ 72057594037927935 : 1 .. 'undefined' @ 0 : 0; will stop at (end)
|
||||
2026/07/25-16:21:45.377631 7fb3e4fff6c0 Recovering log #210
|
||||
2026/07/25-16:21:45.388254 7fb3e4fff6c0 Delete type=3 #208
|
||||
2026/07/25-16:21:45.388347 7fb3e4fff6c0 Delete type=0 #210
|
||||
2026/07/25-16:34:16.301508 7fb394b4f6c0 Level-0 table #215: started
|
||||
2026/07/25-16:34:16.301533 7fb394b4f6c0 Level-0 table #215: 0 bytes OK
|
||||
2026/07/25-16:34:16.308270 7fb394b4f6c0 Delete type=0 #213
|
||||
2026/07/25-16:34:16.322878 7fb394b4f6c0 Manual compaction at level-0 from 'undefined' @ 72057594037927935 : 1 .. 'undefined' @ 0 : 0; will stop at (end)
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -1 +1 @@
|
||||
MANIFEST-000119
|
||||
MANIFEST-000224
|
||||
|
||||
+8
-15
@@ -1,15 +1,8 @@
|
||||
2026/05/24-16:50:54.610807 7fdfa95ff6c0 Recovering log #117
|
||||
2026/05/24-16:50:54.620344 7fdfa95ff6c0 Delete type=3 #115
|
||||
2026/05/24-16:50:54.620394 7fdfa95ff6c0 Delete type=0 #117
|
||||
2026/05/24-17:30:55.071908 7fdf5affd6c0 Level-0 table #122: started
|
||||
2026/05/24-17:30:55.075519 7fdf5affd6c0 Level-0 table #122: 5396 bytes OK
|
||||
2026/05/24-17:30:55.081331 7fdf5affd6c0 Delete type=0 #120
|
||||
2026/05/24-17:30:55.097948 7fdf5affd6c0 Manual compaction at level-0 from '!folders!qrqRBmTP6UuS30DF' @ 72057594037927935 : 1 .. '!items!yFvuDyV00NdojxGt' @ 0 : 0; will stop at (end)
|
||||
2026/05/24-17:30:55.104470 7fdf5affd6c0 Manual compaction at level-1 from '!folders!qrqRBmTP6UuS30DF' @ 72057594037927935 : 1 .. '!items!yFvuDyV00NdojxGt' @ 0 : 0; will stop at '!items!yFvuDyV00NdojxGt' @ 93 : 1
|
||||
2026/05/24-17:30:55.104477 7fdf5affd6c0 Compacting 1@1 + 1@2 files
|
||||
2026/05/24-17:30:55.108502 7fdf5affd6c0 Generated table #123@1: 15 keys, 5574 bytes
|
||||
2026/05/24-17:30:55.108520 7fdf5affd6c0 Compacted 1@1 + 1@2 files => 5574 bytes
|
||||
2026/05/24-17:30:55.114469 7fdf5affd6c0 compacted to: files[ 0 0 1 0 0 0 0 ]
|
||||
2026/05/24-17:30:55.114575 7fdf5affd6c0 Delete type=2 #114
|
||||
2026/05/24-17:30:55.114702 7fdf5affd6c0 Delete type=2 #122
|
||||
2026/05/24-17:30:55.131396 7fdf5affd6c0 Manual compaction at level-1 from '!items!yFvuDyV00NdojxGt' @ 93 : 1 .. '!items!yFvuDyV00NdojxGt' @ 0 : 0; will stop at (end)
|
||||
2026/07/25-16:54:40.177967 7fb397fff6c0 Recovering log #222
|
||||
2026/07/25-16:54:40.189174 7fb397fff6c0 Delete type=3 #220
|
||||
2026/07/25-16:54:40.189264 7fb397fff6c0 Delete type=0 #222
|
||||
2026/07/25-17:22:36.351191 7fb394b4f6c0 Level-0 table #227: started
|
||||
2026/07/25-17:22:36.351222 7fb394b4f6c0 Level-0 table #227: 0 bytes OK
|
||||
2026/07/25-17:22:36.358358 7fb394b4f6c0 Delete type=0 #225
|
||||
2026/07/25-17:22:36.358960 7fb394b4f6c0 Manual compaction at level-0 from '!folders!qrqRBmTP6UuS30DF' @ 72057594037927935 : 1 .. '!items!yFvuDyV00NdojxGt' @ 0 : 0; will stop at (end)
|
||||
2026/07/25-17:22:36.379865 7fb394b4f6c0 Manual compaction at level-1 from '!folders!qrqRBmTP6UuS30DF' @ 72057594037927935 : 1 .. '!items!yFvuDyV00NdojxGt' @ 0 : 0; will stop at (end)
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
2026/05/18-20:27:59.682456 7f5a46ffd6c0 Recovering log #112
|
||||
2026/05/18-20:27:59.750017 7f5a46ffd6c0 Delete type=3 #110
|
||||
2026/05/18-20:27:59.750123 7f5a46ffd6c0 Delete type=0 #112
|
||||
2026/05/18-20:29:47.464929 7f5a467fc6c0 Level-0 table #118: started
|
||||
2026/05/18-20:29:47.465002 7f5a467fc6c0 Level-0 table #118: 0 bytes OK
|
||||
2026/05/18-20:29:47.471758 7f5a467fc6c0 Delete type=0 #116
|
||||
2026/05/18-20:29:47.472004 7f5a467fc6c0 Manual compaction at level-0 from '!folders!qrqRBmTP6UuS30DF' @ 72057594037927935 : 1 .. '!items!yFvuDyV00NdojxGt' @ 0 : 0; will stop at (end)
|
||||
2026/05/18-20:29:47.472035 7f5a467fc6c0 Manual compaction at level-1 from '!folders!qrqRBmTP6UuS30DF' @ 72057594037927935 : 1 .. '!items!yFvuDyV00NdojxGt' @ 0 : 0; will stop at (end)
|
||||
2026/07/25-16:21:45.404647 7fb3e4fff6c0 Recovering log #218
|
||||
2026/07/25-16:21:45.415371 7fb3e4fff6c0 Delete type=3 #216
|
||||
2026/07/25-16:21:45.415456 7fb3e4fff6c0 Delete type=0 #218
|
||||
2026/07/25-16:34:16.323056 7fb394b4f6c0 Level-0 table #223: started
|
||||
2026/07/25-16:34:16.323083 7fb394b4f6c0 Level-0 table #223: 0 bytes OK
|
||||
2026/07/25-16:34:16.329677 7fb394b4f6c0 Delete type=0 #221
|
||||
2026/07/25-16:34:16.343438 7fb394b4f6c0 Manual compaction at level-0 from '!folders!qrqRBmTP6UuS30DF' @ 72057594037927935 : 1 .. '!items!yFvuDyV00NdojxGt' @ 0 : 0; will stop at (end)
|
||||
2026/07/25-16:34:16.350140 7fb394b4f6c0 Manual compaction at level-1 from '!folders!qrqRBmTP6UuS30DF' @ 72057594037927935 : 1 .. '!items!yFvuDyV00NdojxGt' @ 0 : 0; will stop at (end)
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1 @@
|
||||
MANIFEST-000062
|
||||
@@ -0,0 +1,8 @@
|
||||
2026/07/25-16:54:40.546836 7fb3e4fff6c0 Recovering log #60
|
||||
2026/07/25-16:54:40.559140 7fb3e4fff6c0 Delete type=3 #58
|
||||
2026/07/25-16:54:40.559230 7fb3e4fff6c0 Delete type=0 #60
|
||||
2026/07/25-17:22:36.806586 7fb394b4f6c0 Level-0 table #65: started
|
||||
2026/07/25-17:22:36.806624 7fb394b4f6c0 Level-0 table #65: 0 bytes OK
|
||||
2026/07/25-17:22:36.813457 7fb394b4f6c0 Delete type=0 #63
|
||||
2026/07/25-17:22:36.832126 7fb394b4f6c0 Manual compaction at level-0 from '!actors!DL3zXfXxWMOQhXJY' @ 72057594037927935 : 1 .. '!actors.items!JAHYXFedTxNlGYX8.nmIgA3CQkOSEpCSP' @ 0 : 0; will stop at (end)
|
||||
2026/07/25-17:22:36.880816 7fb394b4f6c0 Manual compaction at level-1 from '!actors!DL3zXfXxWMOQhXJY' @ 72057594037927935 : 1 .. '!actors.items!JAHYXFedTxNlGYX8.nmIgA3CQkOSEpCSP' @ 0 : 0; will stop at (end)
|
||||
@@ -0,0 +1,8 @@
|
||||
2026/07/25-16:21:45.739454 7fb397fff6c0 Recovering log #56
|
||||
2026/07/25-16:21:45.751415 7fb397fff6c0 Delete type=3 #54
|
||||
2026/07/25-16:21:45.751507 7fb397fff6c0 Delete type=0 #56
|
||||
2026/07/25-16:34:16.722283 7fb394b4f6c0 Level-0 table #61: started
|
||||
2026/07/25-16:34:16.722319 7fb394b4f6c0 Level-0 table #61: 0 bytes OK
|
||||
2026/07/25-16:34:16.729649 7fb394b4f6c0 Delete type=0 #59
|
||||
2026/07/25-16:34:16.800931 7fb394b4f6c0 Manual compaction at level-0 from '!actors!DL3zXfXxWMOQhXJY' @ 72057594037927935 : 1 .. '!actors.items!JAHYXFedTxNlGYX8.nmIgA3CQkOSEpCSP' @ 0 : 0; will stop at (end)
|
||||
2026/07/25-16:34:16.860353 7fb394b4f6c0 Manual compaction at level-1 from '!actors!DL3zXfXxWMOQhXJY' @ 72057594037927935 : 1 .. '!actors.items!JAHYXFedTxNlGYX8.nmIgA3CQkOSEpCSP' @ 0 : 0; will stop at (end)
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1 +1 @@
|
||||
MANIFEST-000021
|
||||
MANIFEST-000530
|
||||
|
||||
+63
-50
@@ -1,50 +1,63 @@
|
||||
2026/05/24-16:50:54.697724 7fdfa8dfe6c0 Recovering log #18
|
||||
2026/05/24-16:50:54.707598 7fdfa8dfe6c0 Delete type=3 #16
|
||||
2026/05/24-16:50:54.707634 7fdfa8dfe6c0 Delete type=0 #18
|
||||
2026/05/24-17:00:32.390913 7fdf5affd6c0 Level-0 table #24: started
|
||||
2026/05/24-17:00:32.409568 7fdf5affd6c0 Level-0 table #24: 1225651 bytes OK
|
||||
2026/05/24-17:00:32.416341 7fdf5affd6c0 Delete type=0 #22
|
||||
2026/05/24-17:03:56.805332 7fdf5affd6c0 Level-0 table #26: started
|
||||
2026/05/24-17:03:56.824851 7fdf5affd6c0 Level-0 table #26: 1099794 bytes OK
|
||||
2026/05/24-17:03:56.831981 7fdf5affd6c0 Delete type=0 #23
|
||||
2026/05/24-17:12:00.516549 7fdf5affd6c0 Level-0 table #28: started
|
||||
2026/05/24-17:12:00.550743 7fdf5affd6c0 Level-0 table #28: 1268131 bytes OK
|
||||
2026/05/24-17:12:00.582730 7fdf5affd6c0 Delete type=0 #25
|
||||
2026/05/24-17:16:09.186372 7fdf5affd6c0 Level-0 table #30: started
|
||||
2026/05/24-17:16:09.219830 7fdf5affd6c0 Level-0 table #30: 1432074 bytes OK
|
||||
2026/05/24-17:16:09.258561 7fdf5affd6c0 Delete type=0 #27
|
||||
2026/05/24-17:18:30.349891 7fdf5affd6c0 Level-0 table #32: started
|
||||
2026/05/24-17:18:30.379065 7fdf5affd6c0 Level-0 table #32: 1608171 bytes OK
|
||||
2026/05/24-17:18:30.388404 7fdf5affd6c0 Delete type=0 #29
|
||||
2026/05/24-17:18:30.388776 7fdf5affd6c0 Compacting 4@0 + 1@1 files
|
||||
2026/05/24-17:18:30.411581 7fdf5affd6c0 Generated table #33@0: 6650 keys, 986248 bytes
|
||||
2026/05/24-17:18:30.411611 7fdf5affd6c0 Compacted 4@0 + 1@1 files => 986248 bytes
|
||||
2026/05/24-17:18:30.420963 7fdf5affd6c0 compacted to: files[ 0 1 1 0 0 0 0 ]
|
||||
2026/05/24-17:18:30.421191 7fdf5affd6c0 Delete type=2 #24
|
||||
2026/05/24-17:18:30.421480 7fdf5affd6c0 Delete type=2 #26
|
||||
2026/05/24-17:18:30.421601 7fdf5affd6c0 Delete type=2 #28
|
||||
2026/05/24-17:18:30.421786 7fdf5affd6c0 Delete type=2 #30
|
||||
2026/05/24-17:18:30.422133 7fdf5affd6c0 Delete type=2 #32
|
||||
2026/05/24-17:21:12.979159 7fdf5affd6c0 Level-0 table #35: started
|
||||
2026/05/24-17:21:13.003011 7fdf5affd6c0 Level-0 table #35: 1764850 bytes OK
|
||||
2026/05/24-17:21:13.009270 7fdf5affd6c0 Delete type=0 #31
|
||||
2026/05/24-17:30:55.160858 7fdf5affd6c0 Level-0 table #37: started
|
||||
2026/05/24-17:30:55.180790 7fdf5affd6c0 Level-0 table #37: 1929143 bytes OK
|
||||
2026/05/24-17:30:55.187168 7fdf5affd6c0 Delete type=0 #34
|
||||
2026/05/24-17:30:55.187713 7fdf5affd6c0 Manual compaction at level-0 from '!tables!BbXMbmHKcLJrBCmk' @ 72057594037927935 : 1 .. '!tables.results!xe7x4qufBpzLaEby.zyJ49IY9JAmeIucJ' @ 0 : 0; will stop at '!tables.results!xe7x4qufBpzLaEby.zyJ49IY9JAmeIucJ' @ 70890 : 1
|
||||
2026/05/24-17:30:55.187715 7fdf5affd6c0 Compacting 2@0 + 1@1 files
|
||||
2026/05/24-17:30:55.203256 7fdf5affd6c0 Generated table #38@0: 7978 keys, 1186513 bytes
|
||||
2026/05/24-17:30:55.203267 7fdf5affd6c0 Compacted 2@0 + 1@1 files => 1186513 bytes
|
||||
2026/05/24-17:30:55.209485 7fdf5affd6c0 compacted to: files[ 0 1 1 0 0 0 0 ]
|
||||
2026/05/24-17:30:55.209584 7fdf5affd6c0 Delete type=2 #33
|
||||
2026/05/24-17:30:55.209874 7fdf5affd6c0 Delete type=2 #35
|
||||
2026/05/24-17:30:55.210245 7fdf5affd6c0 Delete type=2 #37
|
||||
2026/05/24-17:30:55.237542 7fdf5affd6c0 Manual compaction at level-0 from '!tables.results!xe7x4qufBpzLaEby.zyJ49IY9JAmeIucJ' @ 70890 : 1 .. '!tables.results!xe7x4qufBpzLaEby.zyJ49IY9JAmeIucJ' @ 0 : 0; will stop at (end)
|
||||
2026/05/24-17:30:55.237576 7fdf5affd6c0 Manual compaction at level-1 from '!tables!BbXMbmHKcLJrBCmk' @ 72057594037927935 : 1 .. '!tables.results!xe7x4qufBpzLaEby.zyJ49IY9JAmeIucJ' @ 0 : 0; will stop at '!tables.results!xe7x4qufBpzLaEby.zyJ49IY9JAmeIucJ' @ 92964 : 1
|
||||
2026/05/24-17:30:55.237582 7fdf5affd6c0 Compacting 1@1 + 1@2 files
|
||||
2026/05/24-17:30:55.258486 7fdf5affd6c0 Generated table #39@1: 7978 keys, 1186513 bytes
|
||||
2026/05/24-17:30:55.258511 7fdf5affd6c0 Compacted 1@1 + 1@2 files => 1186513 bytes
|
||||
2026/05/24-17:30:55.264533 7fdf5affd6c0 compacted to: files[ 0 0 1 0 0 0 0 ]
|
||||
2026/05/24-17:30:55.264684 7fdf5affd6c0 Delete type=2 #20
|
||||
2026/05/24-17:30:55.264949 7fdf5affd6c0 Delete type=2 #38
|
||||
2026/05/24-17:30:55.283063 7fdf5affd6c0 Manual compaction at level-1 from '!tables.results!xe7x4qufBpzLaEby.zyJ49IY9JAmeIucJ' @ 92964 : 1 .. '!tables.results!xe7x4qufBpzLaEby.zyJ49IY9JAmeIucJ' @ 0 : 0; will stop at (end)
|
||||
2026/07/25-16:54:40.280606 7fb3e4fff6c0 Recovering log #517
|
||||
2026/07/25-16:54:40.291187 7fb3e4fff6c0 Delete type=3 #513
|
||||
2026/07/25-16:54:40.291276 7fb3e4fff6c0 Delete type=0 #517
|
||||
2026/07/25-16:55:19.321188 7fb394b4f6c0 Level-0 table #533: started
|
||||
2026/07/25-16:55:19.444275 7fb394b4f6c0 Level-0 table #533: 8047048 bytes OK
|
||||
2026/07/25-16:55:19.451577 7fb394b4f6c0 Delete type=0 #531
|
||||
2026/07/25-17:21:46.121006 7fb394b4f6c0 Level-0 table #535: started
|
||||
2026/07/25-17:21:46.222937 7fb394b4f6c0 Level-0 table #535: 8120620 bytes OK
|
||||
2026/07/25-17:21:46.230171 7fb394b4f6c0 Delete type=0 #532
|
||||
2026/07/25-17:22:03.264081 7fb394b4f6c0 Level-0 table #537: started
|
||||
2026/07/25-17:22:03.358383 7fb394b4f6c0 Level-0 table #537: 8159715 bytes OK
|
||||
2026/07/25-17:22:03.366011 7fb394b4f6c0 Delete type=0 #534
|
||||
2026/07/25-17:22:36.394386 7fb394b4f6c0 Level-0 table #539: started
|
||||
2026/07/25-17:22:36.518263 7fb394b4f6c0 Level-0 table #539: 8197558 bytes OK
|
||||
2026/07/25-17:22:36.525099 7fb394b4f6c0 Delete type=0 #536
|
||||
2026/07/25-17:22:36.535793 7fb394b4f6c0 Manual compaction at level-0 from '!tables!BbXMbmHKcLJrBCmk' @ 72057594037927935 : 1 .. '!tables.results!xe7x4qufBpzLaEby.zzqLG98O4eFQZHp0' @ 0 : 0; will stop at '!tables.results!xe7x4qufBpzLaEby.zzqLG98O4eFQZHp0' @ 4024266 : 1
|
||||
2026/07/25-17:22:36.535803 7fb394b4f6c0 Compacting 3@0 + 1@1 files
|
||||
2026/07/25-17:22:36.589302 7fb394b4f6c0 Generated table #540@0: 7833 keys, 2132558 bytes
|
||||
2026/07/25-17:22:36.667506 7fb394b4f6c0 Generated table #541@0: 15560 keys, 2160278 bytes
|
||||
2026/07/25-17:22:36.735222 7fb394b4f6c0 Generated table #542@0: 16090 keys, 2162299 bytes
|
||||
2026/07/25-17:22:36.791787 7fb394b4f6c0 Generated table #543@0: 12983 keys, 1738102 bytes
|
||||
2026/07/25-17:22:36.791824 7fb394b4f6c0 Compacted 3@0 + 1@1 files => 8193237 bytes
|
||||
2026/07/25-17:22:36.798979 7fb394b4f6c0 compacted to: files[ 0 4 4 0 0 0 0 ]
|
||||
2026/07/25-17:22:36.799753 7fb394b4f6c0 Delete type=2 #533
|
||||
2026/07/25-17:22:36.801735 7fb394b4f6c0 Delete type=2 #535
|
||||
2026/07/25-17:22:36.803482 7fb394b4f6c0 Delete type=2 #537
|
||||
2026/07/25-17:22:36.805232 7fb394b4f6c0 Delete type=2 #539
|
||||
2026/07/25-17:22:36.813620 7fb394b4f6c0 Manual compaction at level-0 from '!tables.results!xe7x4qufBpzLaEby.zzqLG98O4eFQZHp0' @ 4024266 : 1 .. '!tables.results!xe7x4qufBpzLaEby.zzqLG98O4eFQZHp0' @ 0 : 0; will stop at (end)
|
||||
2026/07/25-17:22:36.832161 7fb394b4f6c0 Manual compaction at level-1 from '!tables!BbXMbmHKcLJrBCmk' @ 72057594037927935 : 1 .. '!tables.results!xe7x4qufBpzLaEby.zzqLG98O4eFQZHp0' @ 0 : 0; will stop at '!tables.results!Eg3PdOfCx9R54Tm6.NHK48nIoycLq56X4' @ 4160142 : 1
|
||||
2026/07/25-17:22:36.832171 7fb394b4f6c0 Compacting 1@1 + 1@2 files
|
||||
2026/07/25-17:22:36.867333 7fb394b4f6c0 Generated table #544@1: 7833 keys, 2132558 bytes
|
||||
2026/07/25-17:22:36.872505 7fb394b4f6c0 Generated table #545@1: 338 keys, 55239 bytes
|
||||
2026/07/25-17:22:36.872544 7fb394b4f6c0 Compacted 1@1 + 1@2 files => 2187797 bytes
|
||||
2026/07/25-17:22:36.879490 7fb394b4f6c0 compacted to: files[ 0 3 5 0 0 0 0 ]
|
||||
2026/07/25-17:22:36.879931 7fb394b4f6c0 Delete type=2 #523
|
||||
2026/07/25-17:22:36.880474 7fb394b4f6c0 Delete type=2 #540
|
||||
2026/07/25-17:22:36.880920 7fb394b4f6c0 Manual compaction at level-1 from '!tables.results!Eg3PdOfCx9R54Tm6.NHK48nIoycLq56X4' @ 4160142 : 1 .. '!tables.results!xe7x4qufBpzLaEby.zzqLG98O4eFQZHp0' @ 0 : 0; will stop at '!tables.results!bQ64721XzgOetD2v.6a2Kk3rl0H7Rij2U' @ 4171077 : 1
|
||||
2026/07/25-17:22:36.880928 7fb394b4f6c0 Compacting 1@1 + 2@2 files
|
||||
2026/07/25-17:22:36.931840 7fb394b4f6c0 Generated table #546@1: 15560 keys, 2160278 bytes
|
||||
2026/07/25-17:22:36.938177 7fb394b4f6c0 Generated table #547@1: 737 keys, 105748 bytes
|
||||
2026/07/25-17:22:36.938217 7fb394b4f6c0 Compacted 1@1 + 2@2 files => 2266026 bytes
|
||||
2026/07/25-17:22:36.945137 7fb394b4f6c0 compacted to: files[ 0 2 5 0 0 0 0 ]
|
||||
2026/07/25-17:22:36.945519 7fb394b4f6c0 Delete type=2 #525
|
||||
2026/07/25-17:22:36.946090 7fb394b4f6c0 Delete type=2 #541
|
||||
2026/07/25-17:22:36.946379 7fb394b4f6c0 Delete type=2 #545
|
||||
2026/07/25-17:22:36.965952 7fb394b4f6c0 Manual compaction at level-1 from '!tables.results!bQ64721XzgOetD2v.6a2Kk3rl0H7Rij2U' @ 4171077 : 1 .. '!tables.results!xe7x4qufBpzLaEby.zzqLG98O4eFQZHp0' @ 0 : 0; will stop at '!tables.results!gXa1mHCjJYOtPiRx.w274XsrKfEGnYr0a' @ 4145219 : 1
|
||||
2026/07/25-17:22:36.965988 7fb394b4f6c0 Compacting 1@1 + 2@2 files
|
||||
2026/07/25-17:22:37.021652 7fb394b4f6c0 Generated table #548@1: 16090 keys, 2162299 bytes
|
||||
2026/07/25-17:22:37.028936 7fb394b4f6c0 Generated table #549@1: 1170 keys, 156119 bytes
|
||||
2026/07/25-17:22:37.028974 7fb394b4f6c0 Compacted 1@1 + 2@2 files => 2318418 bytes
|
||||
2026/07/25-17:22:37.035841 7fb394b4f6c0 compacted to: files[ 0 1 5 0 0 0 0 ]
|
||||
2026/07/25-17:22:37.036188 7fb394b4f6c0 Delete type=2 #527
|
||||
2026/07/25-17:22:37.036784 7fb394b4f6c0 Delete type=2 #542
|
||||
2026/07/25-17:22:37.037237 7fb394b4f6c0 Delete type=2 #547
|
||||
2026/07/25-17:22:37.044891 7fb394b4f6c0 Manual compaction at level-1 from '!tables.results!gXa1mHCjJYOtPiRx.w274XsrKfEGnYr0a' @ 4145219 : 1 .. '!tables.results!xe7x4qufBpzLaEby.zzqLG98O4eFQZHp0' @ 0 : 0; will stop at '!tables.results!xe7x4qufBpzLaEby.zzqLG98O4eFQZHp0' @ 4128290 : 1
|
||||
2026/07/25-17:22:37.044907 7fb394b4f6c0 Compacting 1@1 + 2@2 files
|
||||
2026/07/25-17:22:37.084375 7fb394b4f6c0 Generated table #550@1: 12983 keys, 1738102 bytes
|
||||
2026/07/25-17:22:37.084414 7fb394b4f6c0 Compacted 1@1 + 2@2 files => 1738102 bytes
|
||||
2026/07/25-17:22:37.091282 7fb394b4f6c0 compacted to: files[ 0 0 4 0 0 0 0 ]
|
||||
2026/07/25-17:22:37.091499 7fb394b4f6c0 Delete type=2 #529
|
||||
2026/07/25-17:22:37.091903 7fb394b4f6c0 Delete type=2 #543
|
||||
2026/07/25-17:22:37.092142 7fb394b4f6c0 Delete type=2 #549
|
||||
2026/07/25-17:22:37.106687 7fb394b4f6c0 Manual compaction at level-1 from '!tables.results!xe7x4qufBpzLaEby.zzqLG98O4eFQZHp0' @ 4128290 : 1 .. '!tables.results!xe7x4qufBpzLaEby.zzqLG98O4eFQZHp0' @ 0 : 0; will stop at (end)
|
||||
|
||||
+55
-15
@@ -1,15 +1,55 @@
|
||||
2026/05/18-20:28:00.247967 7f5a94bff6c0 Recovering log #13
|
||||
2026/05/18-20:28:00.322431 7f5a94bff6c0 Delete type=3 #11
|
||||
2026/05/18-20:28:00.322531 7f5a94bff6c0 Delete type=0 #13
|
||||
2026/05/18-20:29:47.524056 7f5a467fc6c0 Level-0 table #19: started
|
||||
2026/05/18-20:29:47.536717 7f5a467fc6c0 Level-0 table #19: 417426 bytes OK
|
||||
2026/05/18-20:29:47.544323 7f5a467fc6c0 Delete type=0 #17
|
||||
2026/05/18-20:29:47.545004 7f5a467fc6c0 Manual compaction at level-0 from '!tables!BbXMbmHKcLJrBCmk' @ 72057594037927935 : 1 .. '!tables.results!xe7x4qufBpzLaEby.zyJ49IY9JAmeIucJ' @ 0 : 0; will stop at (end)
|
||||
2026/05/18-20:29:47.545055 7f5a467fc6c0 Manual compaction at level-1 from '!tables!BbXMbmHKcLJrBCmk' @ 72057594037927935 : 1 .. '!tables.results!xe7x4qufBpzLaEby.zyJ49IY9JAmeIucJ' @ 0 : 0; will stop at '!tables.results!xe7x4qufBpzLaEby.zyJ49IY9JAmeIucJ' @ 12474 : 1
|
||||
2026/05/18-20:29:47.545064 7f5a467fc6c0 Compacting 1@1 + 1@2 files
|
||||
2026/05/18-20:29:47.560513 7f5a467fc6c0 Generated table #20@1: 2998 keys, 417426 bytes
|
||||
2026/05/18-20:29:47.560554 7f5a467fc6c0 Compacted 1@1 + 1@2 files => 417426 bytes
|
||||
2026/05/18-20:29:47.567200 7f5a467fc6c0 compacted to: files[ 0 0 1 0 0 0 0 ]
|
||||
2026/05/18-20:29:47.567433 7f5a467fc6c0 Delete type=2 #15
|
||||
2026/05/18-20:29:47.567841 7f5a467fc6c0 Delete type=2 #19
|
||||
2026/05/18-20:29:47.568160 7f5a467fc6c0 Manual compaction at level-1 from '!tables.results!xe7x4qufBpzLaEby.zyJ49IY9JAmeIucJ' @ 12474 : 1 .. '!tables.results!xe7x4qufBpzLaEby.zyJ49IY9JAmeIucJ' @ 0 : 0; will stop at (end)
|
||||
2026/07/25-16:21:45.501792 7fb3e4fff6c0 Recovering log #500
|
||||
2026/07/25-16:21:45.512008 7fb3e4fff6c0 Delete type=3 #496
|
||||
2026/07/25-16:21:45.512073 7fb3e4fff6c0 Delete type=0 #500
|
||||
2026/07/25-16:24:19.128277 7fb394b4f6c0 Level-0 table #516: started
|
||||
2026/07/25-16:24:19.244728 7fb394b4f6c0 Level-0 table #516: 7956529 bytes OK
|
||||
2026/07/25-16:24:19.251153 7fb394b4f6c0 Delete type=0 #514
|
||||
2026/07/25-16:34:16.371434 7fb394b4f6c0 Level-0 table #518: started
|
||||
2026/07/25-16:34:16.500326 7fb394b4f6c0 Level-0 table #518: 7998817 bytes OK
|
||||
2026/07/25-16:34:16.508005 7fb394b4f6c0 Delete type=0 #515
|
||||
2026/07/25-16:34:16.510322 7fb394b4f6c0 Manual compaction at level-0 from '!tables!BbXMbmHKcLJrBCmk' @ 72057594037927935 : 1 .. '!tables.results!xe7x4qufBpzLaEby.zzqLG98O4eFQZHp0' @ 0 : 0; will stop at '!tables.results!xe7x4qufBpzLaEby.zzqLG98O4eFQZHp0' @ 3921570 : 1
|
||||
2026/07/25-16:34:16.510331 7fb394b4f6c0 Compacting 1@0 + 1@1 files
|
||||
2026/07/25-16:34:16.542074 7fb394b4f6c0 Generated table #519@0: 7972 keys, 2131647 bytes
|
||||
2026/07/25-16:34:16.588781 7fb394b4f6c0 Generated table #520@0: 15567 keys, 2160383 bytes
|
||||
2026/07/25-16:34:16.635707 7fb394b4f6c0 Generated table #521@0: 16112 keys, 2162117 bytes
|
||||
2026/07/25-16:34:16.671030 7fb394b4f6c0 Generated table #522@0: 11487 keys, 1540844 bytes
|
||||
2026/07/25-16:34:16.671069 7fb394b4f6c0 Compacted 1@0 + 1@1 files => 7994991 bytes
|
||||
2026/07/25-16:34:16.677382 7fb394b4f6c0 compacted to: files[ 0 4 4 0 0 0 0 ]
|
||||
2026/07/25-16:34:16.678276 7fb394b4f6c0 Delete type=2 #516
|
||||
2026/07/25-16:34:16.679572 7fb394b4f6c0 Delete type=2 #518
|
||||
2026/07/25-16:34:16.680429 7fb394b4f6c0 Manual compaction at level-0 from '!tables.results!xe7x4qufBpzLaEby.zzqLG98O4eFQZHp0' @ 3921570 : 1 .. '!tables.results!xe7x4qufBpzLaEby.zzqLG98O4eFQZHp0' @ 0 : 0; will stop at (end)
|
||||
2026/07/25-16:34:16.680597 7fb394b4f6c0 Manual compaction at level-1 from '!tables!BbXMbmHKcLJrBCmk' @ 72057594037927935 : 1 .. '!tables.results!xe7x4qufBpzLaEby.zzqLG98O4eFQZHp0' @ 0 : 0; will stop at '!tables.results!Eg3PdOfCx9R54Tm6.QmTmqRtZ2zqUbNDK' @ 3951925 : 1
|
||||
2026/07/25-16:34:16.680618 7fb394b4f6c0 Compacting 1@1 + 1@2 files
|
||||
2026/07/25-16:34:16.710701 7fb394b4f6c0 Generated table #523@1: 7972 keys, 2131647 bytes
|
||||
2026/07/25-16:34:16.714887 7fb394b4f6c0 Generated table #524@1: 166 keys, 27091 bytes
|
||||
2026/07/25-16:34:16.714917 7fb394b4f6c0 Compacted 1@1 + 1@2 files => 2158738 bytes
|
||||
2026/07/25-16:34:16.721082 7fb394b4f6c0 compacted to: files[ 0 3 5 0 0 0 0 ]
|
||||
2026/07/25-16:34:16.721504 7fb394b4f6c0 Delete type=2 #506
|
||||
2026/07/25-16:34:16.722019 7fb394b4f6c0 Delete type=2 #519
|
||||
2026/07/25-16:34:16.743211 7fb394b4f6c0 Manual compaction at level-1 from '!tables.results!Eg3PdOfCx9R54Tm6.QmTmqRtZ2zqUbNDK' @ 3951925 : 1 .. '!tables.results!xe7x4qufBpzLaEby.zzqLG98O4eFQZHp0' @ 0 : 0; will stop at '!tables.results!bQ64721XzgOetD2v.EReJqu3wyM6vwWR7' @ 3963654 : 1
|
||||
2026/07/25-16:34:16.743231 7fb394b4f6c0 Compacting 1@1 + 2@2 files
|
||||
2026/07/25-16:34:16.788469 7fb394b4f6c0 Generated table #525@1: 15567 keys, 2160383 bytes
|
||||
2026/07/25-16:34:16.793007 7fb394b4f6c0 Generated table #526@1: 370 keys, 53494 bytes
|
||||
2026/07/25-16:34:16.793036 7fb394b4f6c0 Compacted 1@1 + 2@2 files => 2213877 bytes
|
||||
2026/07/25-16:34:16.799791 7fb394b4f6c0 compacted to: files[ 0 2 5 0 0 0 0 ]
|
||||
2026/07/25-16:34:16.800112 7fb394b4f6c0 Delete type=2 #508
|
||||
2026/07/25-16:34:16.800586 7fb394b4f6c0 Delete type=2 #520
|
||||
2026/07/25-16:34:16.800854 7fb394b4f6c0 Delete type=2 #524
|
||||
2026/07/25-16:34:16.801124 7fb394b4f6c0 Manual compaction at level-1 from '!tables.results!bQ64721XzgOetD2v.EReJqu3wyM6vwWR7' @ 3963654 : 1 .. '!tables.results!xe7x4qufBpzLaEby.zzqLG98O4eFQZHp0' @ 0 : 0; will stop at '!tables.results!jup6vzXHR8WYariQ.9MLFLfBZxah8tU5d' @ 3930763 : 1
|
||||
2026/07/25-16:34:16.801134 7fb394b4f6c0 Compacting 1@1 + 2@2 files
|
||||
2026/07/25-16:34:16.847533 7fb394b4f6c0 Generated table #527@1: 16112 keys, 2162117 bytes
|
||||
2026/07/25-16:34:16.852860 7fb394b4f6c0 Generated table #528@1: 669 keys, 88745 bytes
|
||||
2026/07/25-16:34:16.852890 7fb394b4f6c0 Compacted 1@1 + 2@2 files => 2250862 bytes
|
||||
2026/07/25-16:34:16.859163 7fb394b4f6c0 compacted to: files[ 0 1 5 0 0 0 0 ]
|
||||
2026/07/25-16:34:16.859513 7fb394b4f6c0 Delete type=2 #510
|
||||
2026/07/25-16:34:16.859993 7fb394b4f6c0 Delete type=2 #521
|
||||
2026/07/25-16:34:16.860259 7fb394b4f6c0 Delete type=2 #526
|
||||
2026/07/25-16:34:16.868258 7fb394b4f6c0 Manual compaction at level-1 from '!tables.results!jup6vzXHR8WYariQ.9MLFLfBZxah8tU5d' @ 3930763 : 1 .. '!tables.results!xe7x4qufBpzLaEby.zzqLG98O4eFQZHp0' @ 0 : 0; will stop at '!tables.results!xe7x4qufBpzLaEby.zzqLG98O4eFQZHp0' @ 3921570 : 1
|
||||
2026/07/25-16:34:16.868275 7fb394b4f6c0 Compacting 1@1 + 2@2 files
|
||||
2026/07/25-16:34:16.902985 7fb394b4f6c0 Generated table #529@1: 11487 keys, 1540844 bytes
|
||||
2026/07/25-16:34:16.903023 7fb394b4f6c0 Compacted 1@1 + 2@2 files => 1540844 bytes
|
||||
2026/07/25-16:34:16.910466 7fb394b4f6c0 compacted to: files[ 0 0 4 0 0 0 0 ]
|
||||
2026/07/25-16:34:16.910669 7fb394b4f6c0 Delete type=2 #512
|
||||
2026/07/25-16:34:16.911042 7fb394b4f6c0 Delete type=2 #522
|
||||
2026/07/25-16:34:16.911269 7fb394b4f6c0 Delete type=2 #528
|
||||
2026/07/25-16:34:16.928914 7fb394b4f6c0 Manual compaction at level-1 from '!tables.results!xe7x4qufBpzLaEby.zzqLG98O4eFQZHp0' @ 3921570 : 1 .. '!tables.results!xe7x4qufBpzLaEby.zzqLG98O4eFQZHp0' @ 0 : 0; will stop at (end)
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -1 +1 @@
|
||||
MANIFEST-000065
|
||||
MANIFEST-000170
|
||||
|
||||
@@ -1,15 +1,8 @@
|
||||
2026/05/24-16:50:54.673462 7fdfa95ff6c0 Recovering log #63
|
||||
2026/05/24-16:50:54.683865 7fdfa95ff6c0 Delete type=3 #61
|
||||
2026/05/24-16:50:54.683923 7fdfa95ff6c0 Delete type=0 #63
|
||||
2026/05/24-17:30:55.141699 7fdf5affd6c0 Level-0 table #68: started
|
||||
2026/05/24-17:30:55.144973 7fdf5affd6c0 Level-0 table #68: 18651 bytes OK
|
||||
2026/05/24-17:30:55.150867 7fdf5affd6c0 Delete type=0 #66
|
||||
2026/05/24-17:30:55.187701 7fdf5affd6c0 Manual compaction at level-0 from '!items!0ZfAXacF6oWS120o' @ 72057594037927935 : 1 .. '!items!xFUyR7XECD8QJcIw' @ 0 : 0; will stop at (end)
|
||||
2026/05/24-17:30:55.227041 7fdf5affd6c0 Manual compaction at level-1 from '!items!0ZfAXacF6oWS120o' @ 72057594037927935 : 1 .. '!items!xFUyR7XECD8QJcIw' @ 0 : 0; will stop at '!items!xFUyR7XECD8QJcIw' @ 231 : 1
|
||||
2026/05/24-17:30:55.227053 7fdf5affd6c0 Compacting 1@1 + 1@2 files
|
||||
2026/05/24-17:30:55.230678 7fdf5affd6c0 Generated table #69@1: 33 keys, 18651 bytes
|
||||
2026/05/24-17:30:55.230696 7fdf5affd6c0 Compacted 1@1 + 1@2 files => 18651 bytes
|
||||
2026/05/24-17:30:55.237297 7fdf5affd6c0 compacted to: files[ 0 0 1 0 0 0 0 ]
|
||||
2026/05/24-17:30:55.237359 7fdf5affd6c0 Delete type=2 #60
|
||||
2026/05/24-17:30:55.237471 7fdf5affd6c0 Delete type=2 #68
|
||||
2026/05/24-17:30:55.265203 7fdf5affd6c0 Manual compaction at level-1 from '!items!xFUyR7XECD8QJcIw' @ 231 : 1 .. '!items!xFUyR7XECD8QJcIw' @ 0 : 0; will stop at (end)
|
||||
2026/07/25-16:54:40.250077 7fb3977fe6c0 Recovering log #168
|
||||
2026/07/25-16:54:40.261282 7fb3977fe6c0 Delete type=3 #166
|
||||
2026/07/25-16:54:40.261388 7fb3977fe6c0 Delete type=0 #168
|
||||
2026/07/25-17:22:36.372487 7fb394b4f6c0 Level-0 table #173: started
|
||||
2026/07/25-17:22:36.372517 7fb394b4f6c0 Level-0 table #173: 0 bytes OK
|
||||
2026/07/25-17:22:36.379686 7fb394b4f6c0 Delete type=0 #171
|
||||
2026/07/25-17:22:36.379949 7fb394b4f6c0 Manual compaction at level-0 from '!items!0ZfAXacF6oWS120o' @ 72057594037927935 : 1 .. '!items!xFUyR7XECD8QJcIw' @ 0 : 0; will stop at (end)
|
||||
2026/07/25-17:22:36.379970 7fb394b4f6c0 Manual compaction at level-1 from '!items!0ZfAXacF6oWS120o' @ 72057594037927935 : 1 .. '!items!xFUyR7XECD8QJcIw' @ 0 : 0; will stop at (end)
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
2026/05/18-20:28:00.088714 7f5a94bff6c0 Recovering log #58
|
||||
2026/05/18-20:28:00.147839 7f5a94bff6c0 Delete type=3 #56
|
||||
2026/05/18-20:28:00.147945 7f5a94bff6c0 Delete type=0 #58
|
||||
2026/05/18-20:29:47.507007 7f5a467fc6c0 Level-0 table #64: started
|
||||
2026/05/18-20:29:47.507077 7f5a467fc6c0 Level-0 table #64: 0 bytes OK
|
||||
2026/05/18-20:29:47.513818 7f5a467fc6c0 Delete type=0 #62
|
||||
2026/05/18-20:29:47.514115 7f5a467fc6c0 Manual compaction at level-0 from '!items!0ZfAXacF6oWS120o' @ 72057594037927935 : 1 .. '!items!xFUyR7XECD8QJcIw' @ 0 : 0; will stop at (end)
|
||||
2026/05/18-20:29:47.514158 7f5a467fc6c0 Manual compaction at level-1 from '!items!0ZfAXacF6oWS120o' @ 72057594037927935 : 1 .. '!items!xFUyR7XECD8QJcIw' @ 0 : 0; will stop at (end)
|
||||
2026/07/25-16:21:45.473663 7fb3e4fff6c0 Recovering log #164
|
||||
2026/07/25-16:21:45.484922 7fb3e4fff6c0 Delete type=3 #162
|
||||
2026/07/25-16:21:45.484999 7fb3e4fff6c0 Delete type=0 #164
|
||||
2026/07/25-16:34:16.364464 7fb394b4f6c0 Level-0 table #169: started
|
||||
2026/07/25-16:34:16.364495 7fb394b4f6c0 Level-0 table #169: 0 bytes OK
|
||||
2026/07/25-16:34:16.371260 7fb394b4f6c0 Delete type=0 #167
|
||||
2026/07/25-16:34:16.510187 7fb394b4f6c0 Manual compaction at level-0 from '!items!0ZfAXacF6oWS120o' @ 72057594037927935 : 1 .. '!items!xFUyR7XECD8QJcIw' @ 0 : 0; will stop at (end)
|
||||
2026/07/25-16:34:16.680263 7fb394b4f6c0 Manual compaction at level-1 from '!items!0ZfAXacF6oWS120o' @ 72057594037927935 : 1 .. '!items!xFUyR7XECD8QJcIw' @ 0 : 0; will stop at (end)
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,95 @@
|
||||
import { formatImperialDate } from './calendarDate.js';
|
||||
|
||||
const { ApplicationV2, HandlebarsApplicationMixin } = foundry.applications.api;
|
||||
const MODULE_ID = 'mgt2-compendium-amiral-denisov';
|
||||
|
||||
export class CalendarApp extends HandlebarsApplicationMixin(ApplicationV2) {
|
||||
static DEFAULT_OPTIONS = {
|
||||
id: 'mgt2-calendar',
|
||||
classes: ['mgt2-calendar'],
|
||||
position: { width: 260, height: 'auto' },
|
||||
window: {
|
||||
icon: 'fas fa-calendar-alt',
|
||||
title: 'Calendrier Impérial',
|
||||
resizable: false,
|
||||
},
|
||||
};
|
||||
|
||||
static PARTS = {
|
||||
main: {
|
||||
template: `modules/${MODULE_ID}/templates/calendar-app.hbs`,
|
||||
root: true,
|
||||
},
|
||||
};
|
||||
|
||||
constructor({ onConfig, onClose, onNote } = {}) {
|
||||
super();
|
||||
const saved = game.settings?.get(MODULE_ID, 'calendarPosition');
|
||||
if (saved?.left != null && saved?.top != null) {
|
||||
this.position.left = saved.left;
|
||||
this.position.top = saved.top;
|
||||
}
|
||||
this._onConfig = onConfig;
|
||||
this._onClose = onClose;
|
||||
this._onNote = onNote;
|
||||
this._data = { year: 1116, day: 1, hour: 12, minute: 0, planet: '' };
|
||||
}
|
||||
|
||||
get title() {
|
||||
return 'Calendrier Impérial';
|
||||
}
|
||||
|
||||
async _prepareContext() {
|
||||
return {
|
||||
dateLabel: formatImperialDate(this._data),
|
||||
isGM: game.user?.isGM ?? false,
|
||||
};
|
||||
}
|
||||
|
||||
async _onRender(context, options) {
|
||||
await super._onRender(context, options);
|
||||
const html = $(this.element);
|
||||
html.find('.mgt2-cal-config-btn').on('click', () => {
|
||||
this._onConfig?.();
|
||||
});
|
||||
html.find('.mgt2-cal-note-btn').on('click', () => {
|
||||
this._onNote?.();
|
||||
});
|
||||
}
|
||||
|
||||
setPosition(position) {
|
||||
const result = super.setPosition(position);
|
||||
this._debouncedSavePos();
|
||||
return result;
|
||||
}
|
||||
|
||||
_debouncedSavePos() {
|
||||
if (this._savePosTimeout) clearTimeout(this._savePosTimeout);
|
||||
this._savePosTimeout = setTimeout(() => {
|
||||
game.settings?.set(MODULE_ID, 'calendarPosition', {
|
||||
left: this.position.left,
|
||||
top: this.position.top,
|
||||
});
|
||||
this._savePosTimeout = null;
|
||||
}, 300);
|
||||
}
|
||||
|
||||
updateDisplay(data) {
|
||||
this._data = { ...this._data, ...data };
|
||||
this.render();
|
||||
}
|
||||
|
||||
async close() {
|
||||
if (game.settings) {
|
||||
await game.settings.set(MODULE_ID, 'calendarPosition', {
|
||||
left: this.position.left,
|
||||
top: this.position.top,
|
||||
});
|
||||
}
|
||||
this._onConfig = null;
|
||||
this._onNote = null;
|
||||
this._onClose?.();
|
||||
this._onClose = null;
|
||||
return super.close();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
import { getDayLabel, computeConversions } from './calendarDate.js';
|
||||
|
||||
const { ApplicationV2, HandlebarsApplicationMixin } = foundry.applications.api;
|
||||
const MODULE_ID = 'mgt2-compendium-amiral-denisov';
|
||||
|
||||
export class CalendarConfigDialog extends HandlebarsApplicationMixin(ApplicationV2) {
|
||||
static DEFAULT_OPTIONS = {
|
||||
id: 'mgt2-calendar-config',
|
||||
classes: ['mgt2-calendar'],
|
||||
position: { width: 300, height: 'auto' },
|
||||
window: {
|
||||
icon: 'fas fa-cog',
|
||||
title: 'Configurer le calendrier',
|
||||
resizable: false,
|
||||
},
|
||||
};
|
||||
|
||||
static PARTS = {
|
||||
main: {
|
||||
template: `modules/${MODULE_ID}/templates/calendar-config.hbs`,
|
||||
root: true,
|
||||
},
|
||||
};
|
||||
|
||||
constructor({ data, onApply } = {}) {
|
||||
super();
|
||||
this._data = { ...data };
|
||||
this._onApply = onApply;
|
||||
}
|
||||
|
||||
get title() {
|
||||
return 'Configurer le calendrier';
|
||||
}
|
||||
|
||||
async _prepareContext() {
|
||||
return {
|
||||
year: this._data.year,
|
||||
day: this._data.day,
|
||||
hour: this._data.hour,
|
||||
minute: this._data.minute,
|
||||
planet: this._data.planet ?? '',
|
||||
dayLabel: getDayLabel(this._data.day),
|
||||
conversions: computeConversions(this._data.year),
|
||||
};
|
||||
}
|
||||
|
||||
async _onRender(context, options) {
|
||||
await super._onRender(context, options);
|
||||
const html = $(this.element);
|
||||
|
||||
html.find('[name="day"]').on('input', () => {
|
||||
const day = parseInt(html.find('[name="day"]').val(), 10);
|
||||
if (day >= 1 && day <= 365) {
|
||||
html.find('.mgt2-cal-day-label').text(getDayLabel(day));
|
||||
}
|
||||
});
|
||||
|
||||
html.find('[name="year"]').on('input', () => {
|
||||
const year = parseInt(html.find('[name="year"]').val(), 10) || 0;
|
||||
const conv = computeConversions(year);
|
||||
html.find('.mgt2-cal-conv-val[data-cal="solomani"]').text(conv.solomani);
|
||||
html.find('.mgt2-cal-conv-val[data-cal="vilani"]').text(conv.vilani);
|
||||
html.find('.mgt2-cal-conv-val[data-cal="zhodani"]').text(conv.zhodani);
|
||||
html.find('.mgt2-cal-conv-val[data-cal="aslan"]').text(conv.aslan);
|
||||
html.find('.mgt2-cal-conv-val[data-cal="kkree"]').text(conv.kkree);
|
||||
html.find('.mgt2-cal-conv-val[data-cal="hiver"]').text(conv.hiver);
|
||||
});
|
||||
|
||||
html.find('[data-action="day-inc"]').on('click', () => {
|
||||
const input = html.find('[name="day"]');
|
||||
let day = parseInt(input.val(), 10) || 1;
|
||||
day = day >= 365 ? 1 : day + 1;
|
||||
input.val(day);
|
||||
html.find('.mgt2-cal-day-label').text(getDayLabel(day));
|
||||
});
|
||||
|
||||
html.find('[data-action="hour-inc"]').on('click', () => {
|
||||
const dayInput = html.find('[name="day"]');
|
||||
const hourInput = html.find('[name="hour"]');
|
||||
const minuteInput = html.find('[name="minute"]');
|
||||
let day = parseInt(dayInput.val(), 10) || 1;
|
||||
let hour = parseInt(hourInput.val(), 10) || 0;
|
||||
let minute = parseInt(minuteInput.val(), 10) || 0;
|
||||
|
||||
hour += 1;
|
||||
if (hour >= 24) {
|
||||
hour = 0;
|
||||
day = day >= 365 ? 1 : day + 1;
|
||||
}
|
||||
|
||||
hourInput.val(hour);
|
||||
dayInput.val(day);
|
||||
html.find('.mgt2-cal-day-label').text(getDayLabel(day));
|
||||
});
|
||||
|
||||
html.find('[data-action="apply"]').on('click', () => {
|
||||
this._readAndApply(html);
|
||||
});
|
||||
}
|
||||
|
||||
_readAndApply(html) {
|
||||
const year = parseInt(html.find('[name="year"]').val(), 10) || 1116;
|
||||
const day = Math.min(365, Math.max(1, parseInt(html.find('[name="day"]').val(), 10) || 1));
|
||||
const hour = Math.min(23, Math.max(0, parseInt(html.find('[name="hour"]').val(), 10) || 0));
|
||||
const minute = Math.min(59, Math.max(0, parseInt(html.find('[name="minute"]').val(), 10) || 0));
|
||||
const planet = html.find('[name="planet"]').val()?.trim() ?? '';
|
||||
|
||||
const data = { year, day, hour, minute, planet };
|
||||
this._onApply?.(data);
|
||||
}
|
||||
|
||||
close() {
|
||||
this._onApply = null;
|
||||
return super.close();
|
||||
}
|
||||
}
|
||||
@@ -51,15 +51,36 @@ export class CommerceDialog extends HandlebarsApplicationMixin(ApplicationV2) {
|
||||
},
|
||||
};
|
||||
this._tradeGoods = null;
|
||||
this._worldNames = {};
|
||||
|
||||
if (options.defaultWorld) {
|
||||
const w = options.defaultWorld;
|
||||
this._defaultWorld = w;
|
||||
this._worldNames['pax.uwpDep'] = w.name || '';
|
||||
this._worldNames['cargo.uwpDep'] = w.name || '';
|
||||
this._worldNames['trade.uwp'] = w.name || '';
|
||||
if (w.uwp) this._formData.pax.uwpDep = w.uwp;
|
||||
if (w.zone) this._formData.pax.zoneDep = w.zone;
|
||||
if (w.uwp) this._formData.cargo.uwpDep = w.uwp;
|
||||
if (w.zone) this._formData.cargo.zoneDep = w.zone;
|
||||
if (w.uwp) this._formData.trade.uwp = w.uwp;
|
||||
if (w.zone) this._formData.trade.zone = w.zone;
|
||||
this._activeTab = 'trade';
|
||||
}
|
||||
}
|
||||
|
||||
async _prepareContext() {
|
||||
_registerHandlebarsHelpers();
|
||||
return {
|
||||
const ctx = {
|
||||
...this._formData,
|
||||
activeActor: buildActiveActorContext(),
|
||||
activeTab: this._activeTab,
|
||||
};
|
||||
if (this._defaultWorld) {
|
||||
ctx.defaultWorldName = this._defaultWorld.name;
|
||||
ctx.defaultWorldLoc = `${this._defaultWorld.sector || ''} ${this._defaultWorld.hex || ''}`.trim();
|
||||
}
|
||||
return ctx;
|
||||
}
|
||||
|
||||
async _onRender(context, options) {
|
||||
@@ -128,6 +149,12 @@ export class CommerceDialog extends HandlebarsApplicationMixin(ApplicationV2) {
|
||||
|
||||
this._bindWorldSearch(html);
|
||||
|
||||
// Pré-remplir les champs recherche avec le nom du monde
|
||||
if (this._defaultWorld?.name) {
|
||||
html.find('.world-search-widget[data-role="dep"] .world-search-input, .world-block-full .world-search-input')
|
||||
.val(this._defaultWorld.name);
|
||||
}
|
||||
|
||||
html.on('click', (ev) => {
|
||||
if (!$(ev.target).closest('.world-search-widget').length) {
|
||||
html.find('.world-search-results').empty();
|
||||
@@ -204,6 +231,7 @@ export class CommerceDialog extends HandlebarsApplicationMixin(ApplicationV2) {
|
||||
$li.on('click', async () => {
|
||||
$results.empty();
|
||||
$input.val(w.name);
|
||||
if (uwpTarget) this._worldNames[uwpTarget] = w.name;
|
||||
const [detail, coords] = await Promise.all([
|
||||
fetchWorldDetail(w.sector, w.hex).catch(() => null),
|
||||
fetchWorldCoordinates(w.sector, w.hex).catch(() => null),
|
||||
@@ -222,11 +250,13 @@ export class CommerceDialog extends HandlebarsApplicationMixin(ApplicationV2) {
|
||||
html.find('[name="cargo.uwpDep"]').val(resolvedUwp);
|
||||
html.find('[name="cargo.zoneDep"]').val(resolvedZone);
|
||||
$cargoDep.data('coords', coords);
|
||||
this._worldNames['cargo.uwpDep'] = w.name;
|
||||
|
||||
const $tradeWorld = html.find('.world-search-widget[data-uwp-target="trade.uwp"]');
|
||||
$tradeWorld.find('.world-search-input').val(w.name);
|
||||
html.find('[name="trade.uwp"]').val(resolvedUwp);
|
||||
html.find('[name="trade.zone"]').val(resolvedZone);
|
||||
this._worldNames['trade.uwp'] = w.name;
|
||||
}
|
||||
|
||||
if (parsecsTarget) {
|
||||
@@ -370,6 +400,8 @@ export class CommerceDialog extends HandlebarsApplicationMixin(ApplicationV2) {
|
||||
});
|
||||
|
||||
if (!result.success) return ui.notifications.error(result.errors.join(' | '));
|
||||
result.dep = { ...result.dep, name: this._worldNames['pax.uwpDep'] || '' };
|
||||
result.dest = { ...result.dest, name: this._worldNames['pax.uwpDest'] || '' };
|
||||
await this._postToChatResult(result);
|
||||
}
|
||||
|
||||
@@ -394,6 +426,8 @@ export class CommerceDialog extends HandlebarsApplicationMixin(ApplicationV2) {
|
||||
|
||||
if (!result.success) return ui.notifications.error(result.errors.join(' | '));
|
||||
result.cargoRevenue = result.lots.reduce((s, l) => s + l.revenue, 0);
|
||||
result.dep = { ...result.dep, name: this._worldNames['cargo.uwpDep'] || '' };
|
||||
result.dest = { ...result.dest, name: this._worldNames['cargo.uwpDest'] || '' };
|
||||
await this._postToChatResult(result);
|
||||
}
|
||||
|
||||
@@ -413,6 +447,7 @@ export class CommerceDialog extends HandlebarsApplicationMixin(ApplicationV2) {
|
||||
|
||||
if (!result.success) return ui.notifications.error(result.errors.join(' | '));
|
||||
|
||||
result.world = { ...result.world, name: this._worldNames['trade.uwp'] || '' };
|
||||
this._tradeGoods = result;
|
||||
const goodsDiv = html.find('.trade-goods-result');
|
||||
const listDiv = html.find('.trade-goods-list');
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
const { ApplicationV2, HandlebarsApplicationMixin } = foundry.applications.api;
|
||||
const MODULE_ID = 'mgt2-compendium-amiral-denisov';
|
||||
|
||||
export class JournalNoteDialog extends HandlebarsApplicationMixin(ApplicationV2) {
|
||||
static DEFAULT_OPTIONS = {
|
||||
id: 'mgt2-journal-note',
|
||||
classes: ['mgt2-calendar'],
|
||||
position: { width: 320, height: 'auto' },
|
||||
window: {
|
||||
icon: 'fas fa-pen',
|
||||
title: 'Note de bord',
|
||||
resizable: false,
|
||||
},
|
||||
};
|
||||
|
||||
static PARTS = {
|
||||
main: {
|
||||
template: `modules/${MODULE_ID}/templates/journal-note-dialog.hbs`,
|
||||
root: true,
|
||||
},
|
||||
};
|
||||
|
||||
constructor({ imperialDate, realDate, onSave } = {}) {
|
||||
super();
|
||||
this._imperialDate = imperialDate;
|
||||
this._realDate = realDate;
|
||||
this._onSave = onSave;
|
||||
}
|
||||
|
||||
get title() {
|
||||
return 'Note de bord';
|
||||
}
|
||||
|
||||
async _prepareContext() {
|
||||
return {
|
||||
imperialDate: this._imperialDate,
|
||||
realDate: this._realDate,
|
||||
};
|
||||
}
|
||||
|
||||
async _onRender(context, options) {
|
||||
await super._onRender(context, options);
|
||||
const html = $(this.element);
|
||||
|
||||
html.find('[data-action="save"]').on('click', async () => {
|
||||
const content = html.find('[name="content"]').val()?.trim();
|
||||
try {
|
||||
await this._onSave?.(content);
|
||||
} catch (err) {
|
||||
console.error(`${MODULE_ID} | Erreur sauvegarde note:`, err);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
close() {
|
||||
this._onSave = null;
|
||||
return super.close();
|
||||
}
|
||||
}
|
||||
+274
-3
@@ -1,6 +1,21 @@
|
||||
import { formatCredits } from './tradeHelper.js';
|
||||
import { createNpcActor, generateClientMission, generateEncounter, generateQuickNpc } from './npcHelper.js';
|
||||
import { createNpcActor, generateClientMission, generateEncounter, generateQuickNpc, formatSigned } from './npcHelper.js';
|
||||
import { generateAllyEnemy } from './allyEnemyGenerator.js';
|
||||
import { NPC_RELATIONS } from './data/npcTables.js';
|
||||
import { generateAndCreateTravellerNpc } from './travellerNpcGenerator.js';
|
||||
import { generateRandomName } from './data/travellerNpcGenerator.js';
|
||||
import { localizeSkill } from './mgt2eSkills.js';
|
||||
import {
|
||||
CITIZEN_CATEGORY_LIST,
|
||||
EXPERIENCE_LEVEL_LIST,
|
||||
ROLE_LIST,
|
||||
GENDER_LIST,
|
||||
DEFAULT_OPTIONS,
|
||||
CITIZEN_CATEGORY_LABELS_FR,
|
||||
EXPERIENCE_LEVEL_LABELS_FR,
|
||||
ROLE_LABELS_FR,
|
||||
GENDER_LABELS_FR
|
||||
} from './data/travellerNpcGenerator.js';
|
||||
|
||||
const { ApplicationV2, HandlebarsApplicationMixin } = foundry.applications.api;
|
||||
const MODULE_ID = 'mgt2-compendium-amiral-denisov';
|
||||
@@ -41,6 +56,26 @@ export class NpcDialog extends HandlebarsApplicationMixin(ApplicationV2) {
|
||||
context: options.context ?? 'starport',
|
||||
includeFollowUp: true,
|
||||
},
|
||||
mission: {},
|
||||
traveller: {
|
||||
citizenCategory: DEFAULT_OPTIONS.citizenCategory,
|
||||
experience: DEFAULT_OPTIONS.experience,
|
||||
role: DEFAULT_OPTIONS.role,
|
||||
gender: DEFAULT_OPTIONS.gender,
|
||||
firstName: '',
|
||||
surname: '',
|
||||
useRandomName: true,
|
||||
createActor: DEFAULT_OPTIONS.createActor,
|
||||
actorName: '',
|
||||
openCreatedActor: DEFAULT_OPTIONS.openCreatedActor,
|
||||
},
|
||||
ae: {
|
||||
relation: options.relation ?? 'contact',
|
||||
includeSpecial: true,
|
||||
createActor: false,
|
||||
actorName: '',
|
||||
openCreatedActor: true,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
@@ -50,6 +85,25 @@ export class NpcDialog extends HandlebarsApplicationMixin(ApplicationV2) {
|
||||
...this._formData,
|
||||
activeTab: this._activeTab,
|
||||
relations: Object.entries(NPC_RELATIONS).map(([key, value]) => ({ key, label: value.label })),
|
||||
citizenCategories: CITIZEN_CATEGORY_LIST.map(c => ({
|
||||
key: c.key,
|
||||
label: CITIZEN_CATEGORY_LABELS_FR[c.key] || c.label,
|
||||
description: c.description
|
||||
})),
|
||||
experienceLevels: EXPERIENCE_LEVEL_LIST.map(e => ({
|
||||
key: e.key,
|
||||
label: EXPERIENCE_LEVEL_LABELS_FR[e.key] || e.label,
|
||||
description: e.description
|
||||
})),
|
||||
roles: ROLE_LIST.map(r => ({
|
||||
key: r.key,
|
||||
label: ROLE_LABELS_FR[r.key] || r.label,
|
||||
description: r.description
|
||||
})),
|
||||
genders: GENDER_LIST.map(g => ({
|
||||
key: g.key,
|
||||
label: GENDER_LABELS_FR[g.key] || g.label
|
||||
})),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -84,6 +138,33 @@ export class NpcDialog extends HandlebarsApplicationMixin(ApplicationV2) {
|
||||
this._readForm(html);
|
||||
this._activateTab($(event.currentTarget).data('tab'));
|
||||
});
|
||||
|
||||
// Gestion des événements pour l'onglet PNJ Détaillé (Traveller)
|
||||
html.find('[data-action="generate-traveller-npc"]').on('click', async (event) => {
|
||||
event.preventDefault();
|
||||
this._readForm(html);
|
||||
await this._handleTravellerNpc();
|
||||
});
|
||||
|
||||
html.find('[data-action="generate-ally-enemy"]').on('click', async (event) => {
|
||||
event.preventDefault();
|
||||
this._readForm(html);
|
||||
await this._handleAllyEnemy();
|
||||
});
|
||||
|
||||
html.find('[data-action="randomize-name"]').on('click', (event) => {
|
||||
event.preventDefault();
|
||||
this._randomizeTravellerName(html);
|
||||
});
|
||||
|
||||
html.find('[name="traveller.useRandomName"]').on('change', (event) => {
|
||||
const useRandom = event.target.checked;
|
||||
this._formData.traveller.useRandomName = useRandom;
|
||||
html.find('.traveller-name-fields').toggleClass('hidden', useRandom);
|
||||
});
|
||||
|
||||
// Initialiser l'affichage des champs de nom pour l'onglet Traveller
|
||||
html.find('.traveller-name-fields').toggleClass('hidden', this._formData.traveller.useRandomName);
|
||||
}
|
||||
|
||||
_getForm() {
|
||||
@@ -137,6 +218,25 @@ export class NpcDialog extends HandlebarsApplicationMixin(ApplicationV2) {
|
||||
this._formData.npc.openCreatedActor = html.find('[name="npc.openCreatedActor"]').is(':checked');
|
||||
this._formData.encounter.context = html.find('[name="encounter.context"]').val();
|
||||
this._formData.encounter.includeFollowUp = html.find('[name="encounter.includeFollowUp"]').is(':checked');
|
||||
|
||||
// Données pour l'onglet Alliés/Ennemis
|
||||
this._formData.ae.relation = html.find('[name="ae.relation"]').val();
|
||||
this._formData.ae.includeSpecial = html.find('[name="ae.includeSpecial"]').is(':checked');
|
||||
this._formData.ae.createActor = html.find('[name="ae.createActor"]').is(':checked');
|
||||
this._formData.ae.actorName = html.find('[name="ae.actorName"]').val();
|
||||
this._formData.ae.openCreatedActor = html.find('[name="ae.openCreatedActor"]').is(':checked');
|
||||
|
||||
// Données pour l'onglet PNJ Détaillé (Traveller)
|
||||
this._formData.traveller.citizenCategory = html.find('[name="traveller.citizenCategory"]').val();
|
||||
this._formData.traveller.experience = html.find('[name="traveller.experience"]').val();
|
||||
this._formData.traveller.role = html.find('[name="traveller.role"]').val();
|
||||
this._formData.traveller.gender = html.find('[name="traveller.gender"]').val();
|
||||
this._formData.traveller.firstName = html.find('[name="traveller.firstName"]').val();
|
||||
this._formData.traveller.surname = html.find('[name="traveller.surname"]').val();
|
||||
this._formData.traveller.useRandomName = html.find('[name="traveller.useRandomName"]').is(':checked');
|
||||
this._formData.traveller.createActor = html.find('[name="traveller.createActor"]').is(':checked');
|
||||
this._formData.traveller.actorName = html.find('[name="traveller.actorName"]').val();
|
||||
this._formData.traveller.openCreatedActor = html.find('[name="traveller.openCreatedActor"]').is(':checked');
|
||||
}
|
||||
|
||||
async _handleNpc() {
|
||||
@@ -162,14 +262,131 @@ export class NpcDialog extends HandlebarsApplicationMixin(ApplicationV2) {
|
||||
await this._postToChatResult(result);
|
||||
}
|
||||
|
||||
async _handleTravellerNpc() {
|
||||
const button = $(this.element).find('[data-action="generate-traveller-npc"]');
|
||||
const originalLabel = button.html();
|
||||
|
||||
try {
|
||||
button.prop('disabled', true).html('<i class="fas fa-spinner fa-spin"></i> Génération...');
|
||||
|
||||
const generateOptions = {
|
||||
citizenCategory: this._formData.traveller.citizenCategory,
|
||||
experience: this._formData.traveller.experience,
|
||||
role: this._formData.traveller.role,
|
||||
gender: this._formData.traveller.gender,
|
||||
createActor: this._formData.traveller.createActor,
|
||||
actorName: this._formData.traveller.actorName,
|
||||
openCreatedActor: this._formData.traveller.openCreatedActor
|
||||
};
|
||||
|
||||
if (!this._formData.traveller.useRandomName && this._formData.traveller.firstName && this._formData.traveller.surname) {
|
||||
generateOptions.firstName = this._formData.traveller.firstName;
|
||||
generateOptions.surname = this._formData.traveller.surname;
|
||||
}
|
||||
|
||||
const result = await generateAndCreateTravellerNpc(generateOptions);
|
||||
|
||||
if (result.success) {
|
||||
await this._postToChatResult(result);
|
||||
if (result.createdActor) {
|
||||
ui.notifications.info(`Fiche PNJ Traveller créée : ${result.createdActor.name}`);
|
||||
}
|
||||
} else {
|
||||
ui.notifications.error('Erreur lors de la génération du PNJ Traveller');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(`${MODULE_ID} | Erreur lors de la génération du PNJ Traveller:`, error);
|
||||
ui.notifications.error(`Erreur: ${error.message}`);
|
||||
} finally {
|
||||
button.prop('disabled', false).html(originalLabel);
|
||||
}
|
||||
}
|
||||
|
||||
async _handleAllyEnemy() {
|
||||
const button = $(this.element).find('[data-action="generate-ally-enemy"]');
|
||||
const originalLabel = button.html();
|
||||
|
||||
try {
|
||||
button.prop('disabled', true).html('<i class="fas fa-spinner fa-spin"></i> Génération...');
|
||||
|
||||
const result = await generateAllyEnemy(this._formData.ae.relation, {
|
||||
includeSpecial: this._formData.ae.includeSpecial,
|
||||
});
|
||||
|
||||
if (result.success) {
|
||||
if (this._formData.ae.createActor) {
|
||||
const ae = this._formData.ae;
|
||||
const actorName = ae.actorName?.trim() || `PNJ — ${result.relation.label}`;
|
||||
const baseActorSystem = game.system?.id === 'mgt2e'
|
||||
? await (await import('./travellerNpcGenerator.js')).getMgt2eBaseActorSystem()
|
||||
: null;
|
||||
const actorData = {
|
||||
name: actorName,
|
||||
type: 'npc',
|
||||
img: 'systems/mgt2e/icons/cargo/passenger-middle.svg',
|
||||
system: {
|
||||
settings: foundry.utils.mergeObject(foundry.utils.deepClone(baseActorSystem?.settings ?? {}), {
|
||||
hideUntrained: true, lockCharacteristics: true,
|
||||
}),
|
||||
sophont: foundry.utils.mergeObject(foundry.utils.deepClone(baseActorSystem?.sophont ?? {}), {
|
||||
age: 18, homeworld: '', profession: result.relation.label,
|
||||
}),
|
||||
characteristics: foundry.utils.deepClone(baseActorSystem?.characteristics ?? {}),
|
||||
hits: foundry.utils.deepClone(baseActorSystem?.hits ?? {}),
|
||||
skills: foundry.utils.deepClone(baseActorSystem?.skills ?? {}),
|
||||
},
|
||||
flags: {
|
||||
[MODULE_ID]: { generatedAllyEnemy: { relation: result.relation.key } },
|
||||
},
|
||||
};
|
||||
const actor = await Actor.create(actorData, { renderSheet: false });
|
||||
result.createdActor = { id: actor.id, name: actor.name };
|
||||
if (ae.openCreatedActor) actor.sheet?.render(true);
|
||||
ui.notifications.info(`Fiche PNJ créée : ${actor.name}`);
|
||||
}
|
||||
await this._postToChatResult(result);
|
||||
} else {
|
||||
ui.notifications.error('Erreur lors de la génération de la relation');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(`${MODULE_ID} | Erreur AE:`, error);
|
||||
ui.notifications.error(`Erreur: ${error.message}`);
|
||||
} finally {
|
||||
button.prop('disabled', false).html(originalLabel);
|
||||
}
|
||||
}
|
||||
|
||||
_randomizeTravellerName(html) {
|
||||
const name = generateRandomName(this._formData.traveller.gender);
|
||||
html.find('[name="traveller.firstName"]').val(name.firstName);
|
||||
html.find('[name="traveller.surname"]').val(name.surname);
|
||||
this._formData.traveller.firstName = name.firstName;
|
||||
this._formData.traveller.surname = name.surname;
|
||||
this._formData.traveller.useRandomName = false;
|
||||
html.find('[name="traveller.useRandomName"]').prop('checked', false);
|
||||
html.find('.traveller-name-fields').removeClass('hidden');
|
||||
}
|
||||
|
||||
async _postToChatResult(data) {
|
||||
registerHandlebarsHelpers();
|
||||
const html = await foundry.applications.handlebars.renderTemplate(`modules/${MODULE_ID}/templates/npc-result.hbs`, data);
|
||||
|
||||
let template = `modules/${MODULE_ID}/templates/npc-result.hbs`;
|
||||
let resultType = 'npc-result';
|
||||
|
||||
if (data.type === 'traveller-npc' || data?.flags?.[MODULE_ID]?.type === 'traveller-npc-result') {
|
||||
template = `modules/${MODULE_ID}/templates/traveller-npc-result.hbs`;
|
||||
resultType = 'traveller-npc-result';
|
||||
} else if (data.type === 'ally-enemy') {
|
||||
template = `modules/${MODULE_ID}/templates/ally-enemy-result.hbs`;
|
||||
resultType = 'ally-enemy-result';
|
||||
}
|
||||
|
||||
const html = await foundry.applications.handlebars.renderTemplate(template, data);
|
||||
|
||||
await ChatMessage.create({
|
||||
content: html,
|
||||
speaker: ChatMessage.getSpeaker(),
|
||||
flags: { [MODULE_ID]: { type: 'npc-result' } },
|
||||
flags: { [MODULE_ID]: { type: resultType } },
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -180,8 +397,62 @@ function registerHandlebarsHelpers() {
|
||||
if (helpersRegistered) return;
|
||||
helpersRegistered = true;
|
||||
|
||||
// Helpers existants pour NPC
|
||||
Handlebars.registerHelper('eq', (a, b) => a === b);
|
||||
Handlebars.registerHelper('join', (arr, sep) => (Array.isArray(arr) ? arr.join(sep) : ''));
|
||||
Handlebars.registerHelper('formatCredits', (amount) => formatCredits(amount));
|
||||
Handlebars.registerHelper('contains', (text, search) => String(text ?? '').includes(search));
|
||||
|
||||
// Helper pour localiser une compétence (ex: 'pilot' -> 'Pilote')
|
||||
Handlebars.registerHelper('localizeSkill', (skillFqn) => {
|
||||
if (!skillFqn) return '';
|
||||
return localizeSkill(String(skillFqn));
|
||||
});
|
||||
|
||||
// Helper pour joindre un tableau de compétences en les localisant
|
||||
Handlebars.registerHelper('joinLocalizedSkills', (arr, sep = ', ') => {
|
||||
if (!Array.isArray(arr)) return '';
|
||||
return arr.map(skill => localizeSkill(String(skill))).join(sep);
|
||||
});
|
||||
|
||||
// Helpers pour Traveller NPC
|
||||
Handlebars.registerHelper('gt', (a, b) => a > b);
|
||||
|
||||
// Helper pour afficher le niveau de compétence avec un symbole
|
||||
Handlebars.registerHelper('skillLevelSymbol', (level) => {
|
||||
if (level === 0) return '';
|
||||
if (level === 1) return '★';
|
||||
if (level === 2) return '★★';
|
||||
if (level === 3) return '★★★';
|
||||
return `+${level}`;
|
||||
});
|
||||
|
||||
// Helper pour formater le DM (Difficulté Modificateur)
|
||||
Handlebars.registerHelper('formatDm', (value) => {
|
||||
const dm = Math.floor((value - 6) / 3);
|
||||
return dm >= 0 ? `+${dm}` : `${dm}`;
|
||||
});
|
||||
|
||||
// Helper pour obtenir la classe CSS du niveau de compétence
|
||||
Handlebars.registerHelper('skillLevelClass', (level) => {
|
||||
if (level === 3) return 'skill-level-3';
|
||||
if (level === 2) return 'skill-level-2';
|
||||
if (level === 1) return 'skill-level-1';
|
||||
return 'skill-level-0';
|
||||
});
|
||||
|
||||
// Helper pour lookup dans un objet
|
||||
Handlebars.registerHelper('lookup', (obj, key) => {
|
||||
if (!obj || !key) return '';
|
||||
return obj[key] !== undefined ? obj[key] : '';
|
||||
});
|
||||
|
||||
const RELATION_LABELS = Object.entries(NPC_RELATIONS).reduce((acc, [key, val]) => {
|
||||
acc[key] = val.label;
|
||||
return acc;
|
||||
}, {});
|
||||
|
||||
Handlebars.registerHelper('lookupRelationKey', (key) => RELATION_LABELS[key] || key);
|
||||
|
||||
Handlebars.registerHelper('formatSigned', (value) => formatSigned(value));
|
||||
}
|
||||
|
||||
@@ -0,0 +1,647 @@
|
||||
/**
|
||||
* MGT2 – SectorMapApp
|
||||
*
|
||||
* Application interactive affichant une carte Traveller Map dans un IFRAME.
|
||||
* Les clics sur la carte affichent les détails du monde dans le chat.
|
||||
*/
|
||||
|
||||
import { searchWorlds } from './travellerMapApi.js';
|
||||
import { TravelDialog } from './travelDialog.js';
|
||||
|
||||
const { ApplicationV2 } = foundry.applications.api;
|
||||
const MODULE_ID = 'mgt2-compendium-amiral-denisov';
|
||||
|
||||
export class SectorMapApp extends ApplicationV2 {
|
||||
static DEFAULT_OPTIONS = {
|
||||
id: 'mgt2-sector-map',
|
||||
classes: ['mgt2-sector-map'],
|
||||
position: { width: 960, height: 720 },
|
||||
window: { icon: 'fas fa-map', resizable: true, controls: [] },
|
||||
};
|
||||
|
||||
constructor(sector, subsector, { readOnly = false } = {}) {
|
||||
super();
|
||||
this._sector = sector;
|
||||
this._subsector = subsector;
|
||||
this._readOnly = readOnly;
|
||||
this._handler = null;
|
||||
this._mapHex = null;
|
||||
this._mapCenter = null;
|
||||
this._mapScale = null;
|
||||
this._searchTimeout = null;
|
||||
}
|
||||
|
||||
get title() {
|
||||
if (!this._sector) return 'Carte stellaire — Traveller Map';
|
||||
return this._subsector
|
||||
? `Sous-secteur ${this._subsector} — ${this._sector}`
|
||||
: `Secteur ${this._sector}`;
|
||||
}
|
||||
|
||||
get _mapUrl() {
|
||||
const base = 'https://travellermap.com';
|
||||
const cb = this._readOnly ? '' : '&callback=postmessage';
|
||||
if (!this._sector) return `${base}/?style=mongoose&hideui=1`;
|
||||
if (this._subsector) {
|
||||
return `${base}/?sector=${encodeURIComponent(this._sector)}&subsector=${encodeURIComponent(this._subsector)}&style=mongoose&hideui=1${cb}`;
|
||||
}
|
||||
let url = `${base}/?sector=${encodeURIComponent(this._sector)}&style=mongoose&hideui=1${cb}`;
|
||||
if (this._mapHex) {
|
||||
url += `&hex=${this._mapHex}&scale=512`;
|
||||
} else if (this._mapCenter && this._mapScale) {
|
||||
url += `¢er=${this._mapCenter}&scale=${this._mapScale}`;
|
||||
}
|
||||
return url;
|
||||
}
|
||||
|
||||
/* ───── Rendu ───── */
|
||||
|
||||
_replaceHTML(result, config) {
|
||||
const content = this.element?.querySelector('.window-content');
|
||||
if (!content) return;
|
||||
const html = typeof result === 'string' ? result : this._lastHTML;
|
||||
content.innerHTML = typeof html === 'string' ? html : '';
|
||||
}
|
||||
|
||||
_renderHTML() {
|
||||
if (this._readOnly) {
|
||||
return `<div class="mgt2-sector-map-outer">
|
||||
<div class="mgt2-sector-map-toolbar mgt2-sector-map-toolbar--ro">
|
||||
<span class="mgt2-sector-map-label">${SectorMapApp._escapeAttr(this.title)}</span>
|
||||
<span class="mgt2-sector-map-hint">Carte partagée par le MJ</span>
|
||||
</div>
|
||||
<iframe
|
||||
src="${this._mapUrl}"
|
||||
class="mgt2-sector-map-frame"
|
||||
allow="clipboard-write"
|
||||
referrerpolicy="no-referrer">
|
||||
</iframe>
|
||||
</div>`;
|
||||
}
|
||||
return `<div class="mgt2-sector-map-outer">
|
||||
<div class="mgt2-sector-map-toolbar">
|
||||
<div class="mgt2-sector-map-search">
|
||||
<input type="text" class="mgt2-sector-map-input" placeholder="Rechercher un monde…" autocomplete="off">
|
||||
<ul class="mgt2-sector-map-results"></ul>
|
||||
</div>
|
||||
<span class="mgt2-sector-map-label">${this._sector ? `${this._sector}${this._subsector ? ` — ss.${this._subsector}` : ''}` : 'Toute la carte'}</span>
|
||||
<span class="mgt2-sector-map-hint">Cliquez sur un hex pour voir les détails du monde</span>
|
||||
<button type="button" class="mgt2-sector-map-sync" disabled title="Cliquez d'abord sur un hex pour définir la position à synchroniser"><i class="fas fa-users"></i> Synchroniser</button>
|
||||
<button type="button" class="mgt2-sector-map-travel" title="Planifier un voyage"><i class="fas fa-route"></i> Voyage</button>
|
||||
</div>
|
||||
<iframe
|
||||
src="${this._mapUrl}"
|
||||
class="mgt2-sector-map-frame"
|
||||
allow="clipboard-write"
|
||||
referrerpolicy="no-referrer">
|
||||
</iframe>
|
||||
</div>`;
|
||||
}
|
||||
|
||||
async _onRender(context, options) {
|
||||
if (this._readOnly) {
|
||||
this._listen();
|
||||
return;
|
||||
}
|
||||
this._listen();
|
||||
this.element?.querySelector('.mgt2-sector-map-sync')?.addEventListener('click', () => {
|
||||
this._syncAll();
|
||||
});
|
||||
this.element?.querySelector('.mgt2-sector-map-travel')?.addEventListener('click', () => {
|
||||
this._openTravelDialog();
|
||||
});
|
||||
|
||||
const input = this.element?.querySelector('.mgt2-sector-map-input');
|
||||
const results = this.element?.querySelector('.mgt2-sector-map-results');
|
||||
if (input && results) {
|
||||
input.addEventListener('input', () => {
|
||||
if (this._searchTimeout) clearTimeout(this._searchTimeout);
|
||||
this._searchTimeout = setTimeout(() => this._doSearch(input, results), 300);
|
||||
});
|
||||
input.addEventListener('blur', () => {
|
||||
setTimeout(() => { results.innerHTML = ''; }, 200);
|
||||
});
|
||||
input.addEventListener('focus', () => {
|
||||
if (input.value.trim().length >= 2) this._doSearch(input, results);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/* ───── Écoute des clics IFRAME ───── */
|
||||
|
||||
_listen() {
|
||||
if (this._handler) return;
|
||||
this._handler = (event) => {
|
||||
const d = event.data || {};
|
||||
if (d.type === 'viewport') {
|
||||
this._sector = d.sector || this._sector;
|
||||
this._subsector = d.subsector || this._subsector;
|
||||
this._mapHex = d.hex || null;
|
||||
this._mapCenter = (d.x != null && d.y != null) ? `${d.x},${d.y}` : null;
|
||||
this._mapScale = d.scale || null;
|
||||
return;
|
||||
}
|
||||
|
||||
// Click on map
|
||||
const wx = d.x ?? d.location?.x;
|
||||
const wy = d.y ?? d.location?.y;
|
||||
if (wx == null || wy == null) return;
|
||||
const x = Number(wx);
|
||||
const y = Number(wy);
|
||||
if (isNaN(x) || isNaN(y)) return;
|
||||
this._onMapClick({ x, y }).catch(err => {
|
||||
console.error('SectorMapApp | click handler failed:', err);
|
||||
});
|
||||
};
|
||||
window.addEventListener('message', this._handler);
|
||||
}
|
||||
|
||||
async _onMapClick(loc) {
|
||||
const wx = loc?.x;
|
||||
const wy = loc?.y;
|
||||
if (wx == null || wy == null) return;
|
||||
|
||||
const coordResp = await fetch(
|
||||
`https://travellermap.com/api/coordinates?x=${wx}&y=${wy}`
|
||||
);
|
||||
if (!coordResp.ok) { console.error('SectorMapApp | /api/coordinates failed', coordResp.status); return; }
|
||||
const coord = await coordResp.json();
|
||||
const { sx, sy, hx, hy } = coord;
|
||||
if (sx == null || hx == null || hy == null) { console.error('SectorMapApp | no sx/hx/hy in', coord); return; }
|
||||
|
||||
const metaResp = await fetch(
|
||||
`https://travellermap.com/api/metadata?sx=${sx}&sy=${sy}`
|
||||
);
|
||||
if (!metaResp.ok) { console.error('SectorMapApp | /api/metadata failed', metaResp.status); return; }
|
||||
const meta = await metaResp.json();
|
||||
const sectorName = meta.Names?.[0]?.Text;
|
||||
if (!sectorName) { console.error('SectorMapApp | no Names[0].Text in metadata', meta); return; }
|
||||
|
||||
// Store click position for sync
|
||||
this._sector = sectorName;
|
||||
this._subsector = null;
|
||||
this._mapHex = String(hx).padStart(2, '0') + String(hy).padStart(2, '0');
|
||||
this._mapCenter = `${wx},${wy}`;
|
||||
this._mapScale = loc.scale || 512;
|
||||
|
||||
const hex = String(hx).padStart(2, '0') + String(hy).padStart(2, '0');
|
||||
const resp = await fetch(
|
||||
`https://travellermap.com/data/${encodeURIComponent(sectorName)}/${hex}`
|
||||
);
|
||||
if (!resp.ok) { console.error('SectorMapApp | /data failed', resp.status, sectorName, hex); return; }
|
||||
|
||||
const data = await resp.json();
|
||||
const world = data.Worlds?.[0];
|
||||
if (!world) { console.error('SectorMapApp | no Worlds in data', data); return; }
|
||||
|
||||
this._enableSyncButton(world.Name || hex);
|
||||
|
||||
this._postWorldCard(world);
|
||||
}
|
||||
|
||||
_enableSyncButton(worldName) {
|
||||
const btn = this.element?.querySelector('.mgt2-sector-map-sync');
|
||||
if (btn) {
|
||||
btn.disabled = false;
|
||||
btn.title = worldName ? `Synchroniser la vue sur ${worldName}` : 'Ouvrir la carte interactive chez tous les joueurs';
|
||||
}
|
||||
}
|
||||
|
||||
/* ───── Carte de chat ───── */
|
||||
|
||||
static _STARPORT = { A:'Excellent', B:'Bon', C:'Routinier', D:'Médiocre', E:'Frontière', X:'Aucun' };
|
||||
static _SIZE = ['Aucun (Astéroïde)','1 600 km','3 200 km','4 800 km','6 400 km','8 000 km','9 600 km','11 200 km','12 800 km','14 400 km','16 000 km'];
|
||||
static _ATMO = [
|
||||
'Aucune (vide)','Trace','Très ténue (polluée)','Très ténue','Ténue (polluée)','Ténue','Standard','Standard (polluée)','Dense','Dense (polluée)',
|
||||
'Exotique','Corrosive','Insidieuse','','',''];
|
||||
static _HYDRO = [ '0–5% (désert)','6–15%','16–25%','26–35%','36–45%','46–55%','56–65%','66–75%','76–85%','86–95%','96–100%' ];
|
||||
static _POP = ['','Dizaines','Centaines','Milliers','Dizaines de milliers','Centaines de milliers','Millions','Dizaines de millions','Centaines de millions','Milliards','Dizaines de milliards','','','','','',''];
|
||||
static _GOV = [
|
||||
'Aucun','Compagnie / Corporation','Démocratie participative','Oligarchie auto-perpétuée',
|
||||
'Démocratie représentative','Technocratie féodale','Gouvernement captif / Colonie',
|
||||
'Balkanisation','Bureaucratie de service civil','Bureaucratie impersonnelle',
|
||||
'Dictature charismatique','Dictature non-charismatique','Oligarchie charismatique',
|
||||
'Dictature religieuse','Oligarchie religieuse','Gouvernement tribal'];
|
||||
static _LAW = [
|
||||
'Aucune', 'Armes de poing, explosifs, poison','Armes à énergie portatives','Mitrailleuses, armes auto',
|
||||
'Armes d\'assaut légères, PM','Armes de poing individuelles','Toutes les armes à feu sauf neutralisateur',
|
||||
'Fusils, neutralisateur','Armes blanches, neutralisateur','Armes hors du domicile','Armes interdites',
|
||||
'Contrôle rigide','Aucune arme','Contrôle militariste sévère'];
|
||||
static _TL = [
|
||||
'Âge de pierre','Âge du bronze/fer','Médiéval','Grandes découvertes','Révolution industrielle',
|
||||
'Production mécanisée','Ère nucléaire','Pré-stellaire (ère de l\'information)','Propulsion à saut (1re gen)',
|
||||
'Propulsion à saut-2','Propulsion à saut-3','Propulsion à saut-4','Propulsion à saut-5',
|
||||
'Propulsion à saut-6','Transporteur','Moyenne stellaire'];
|
||||
|
||||
static _hexVal(ch) {
|
||||
const n = parseInt(ch, 36);
|
||||
if (isNaN(n)) return -1;
|
||||
return n;
|
||||
}
|
||||
|
||||
static _uwpDigit(desc, val) {
|
||||
return `<span class="uwp-dig" title="${desc}">${val}</span>`;
|
||||
}
|
||||
|
||||
static _uwpBreakdown(uwp) {
|
||||
if (!uwp || uwp.length < 2) return '';
|
||||
const d = SectorMapApp._hexVal;
|
||||
const s = d(uwp[0]), sz = d(uwp[1]), a = d(uwp[2]), h = d(uwp[3]);
|
||||
const p = d(uwp[4]), g = d(uwp[5]), l = d(uwp[6]);
|
||||
const t = uwp.length > 8 ? d(uwp[8]) : -1;
|
||||
|
||||
const lines = [];
|
||||
|
||||
const starport = SectorMapApp._STARPORT[uwp[0]];
|
||||
lines.push(`<tr><td>${uwp[0]}</td><td>Starport</td><td>${starport ?? '—'}</td></tr>`);
|
||||
|
||||
if (uwp[1] === 'F' || uwp[1] === 'f') {
|
||||
lines.push(`<tr><td>${uwp[1]}</td><td>Taille</td><td>Gaz géant</td></tr>`);
|
||||
} else if (sz >= 0 && sz <= 10) {
|
||||
const km = SectorMapApp._SIZE[sz];
|
||||
const grav = sz === 0 ? '0g' : (sz < 10 ? `0.${sz}g` : '1.0g+');
|
||||
lines.push(`<tr><td>${uwp[1]}</td><td>Taille</td><td>${km} (${grav})</td></tr>`);
|
||||
}
|
||||
|
||||
if (a >= 0 && a <= 15) {
|
||||
const atmo = SectorMapApp._ATMO[a] ?? '—';
|
||||
lines.push(`<tr><td>${uwp[2]}</td><td>Atmosphère</td><td>${atmo}</td></tr>`);
|
||||
}
|
||||
|
||||
if (h >= 0 && h <= 10) {
|
||||
lines.push(`<tr><td>${uwp[3]}</td><td>Hydrosphère</td><td>${SectorMapApp._HYDRO[h]}</td></tr>`);
|
||||
}
|
||||
|
||||
if (p >= 0 && p <= 15) {
|
||||
lines.push(`<tr><td>${uwp[4]}</td><td>Population</td><td>${SectorMapApp._POP[p] ?? '—'}</td></tr>`);
|
||||
}
|
||||
|
||||
if (g >= 0 && g <= 15) {
|
||||
lines.push(`<tr><td>${uwp[5]}</td><td>Gouvernement</td><td>${SectorMapApp._GOV[g] ?? '—'}</td></tr>`);
|
||||
}
|
||||
|
||||
if (l >= 0 && l <= 15) {
|
||||
lines.push(`<tr><td>${uwp[6]}</td><td>Niveau légal</td><td>${SectorMapApp._LAW[l] ?? '—'}</td></tr>`);
|
||||
}
|
||||
|
||||
if (t >= 0 && t <= 15) {
|
||||
lines.push(`<tr><td>${uwp[8]}</td><td>Technologie</td><td>${SectorMapApp._TL[t] ?? '—'}</td></tr>`);
|
||||
}
|
||||
|
||||
return `<table class="uwp-breakdown"><tbody>${lines.join('')}</tbody></table>`;
|
||||
}
|
||||
|
||||
static _REMARKS_HELP = {
|
||||
AB:'Anneau (ceinture)', AG:'Agricole', AN:'Site ancien', AS:'Astéroïde',
|
||||
BA:'Bande astéroïdale', CP:'Sous-secteur capitale', CS:'Colonie',
|
||||
CX:'Chasseur (Croiseur)', CY:'Colonie', DA:'Déchu', DE:'Désertique',
|
||||
DI:'Interdit (Diebar)', FL:'Fluides Lo', FO:'Interdit (Forbidden)',
|
||||
FR:'Gelé (Frozen)', GA:'Jardin (Garden)', HE:'Helios', HI:'Haute population',
|
||||
HT:'Haute technologie', IC:'Mondes gelés (Ice)', IN:'Industrialisé',
|
||||
LI:'Faible population', LO:'Faible population (Low)', LT:'Basse technologie (Low Tech)',
|
||||
MI:'Militaire', MR:'Mine (ressources)', NA:'Non-agricole',
|
||||
NI:'Non-industrialisé', OC:'Océanique', OX:'Oxydant',
|
||||
PA:'Pré-agricole (Pre-Agricultural)', PH:'Phosphore',
|
||||
PO:'Pauvre (Poor)', PR:'Pré-industriel (Pre-Industrial)',
|
||||
PX:'Prisonnier (exil)', PZ:'Puzzle (énigmatique)',
|
||||
RE:'Religieux (Religious)', RI:'Riche (Rich)',
|
||||
SA:'Bande d\'astéroïdes (Satellite)', SC:'Sainte (colonie)',
|
||||
SL:'Esclavage (Slave)', SO:'Soleil (Sol)', SP:'Désert (Despoiled)',
|
||||
SR:'Réserve (Reserve)', ST:'Base stellaire', SU:'Secteur capitale',
|
||||
TR:'Traces (Trace)', TU:'Tucannides', TZ:'Mondes Tz',
|
||||
UN:'Inhabité (Uninhabited)', VA:'Vide (Vacuum)',
|
||||
WA:'Monde aquatique (Water)', WT:'Monde d\'eau (Watery)',
|
||||
};
|
||||
|
||||
static _STAR_TYPES = { O:'Bleu (hypergéante)', B:'Bleu-blanc', A:'Blanc', F:'Blanc-jaune', G:'Jaune (naine)', K:'Orange (naine)', M:'Rouge (naine)', L:'Brune', T:'Brune', Y:'Brune' };
|
||||
static _STAR_CLASS = { 'I':'Supergéante', 'II':'Géante brillante', 'III':'Géante', 'IV':'Sous-géante', 'V':'Naine (séquence principale)', 'VI':'Sous-naine', 'VII':'Naine blanche' };
|
||||
|
||||
static _BASES_HELP = {
|
||||
N:'Base navale', S:'Base scout', W:'Relais', D:'Dépôt naval',
|
||||
T:'Base TAS', C:'Consulat', P:'Base pirate', R:'Base de réparation',
|
||||
K:'Base navale (K.)', X:'Relais Xboat',
|
||||
};
|
||||
|
||||
static _NOBILITY = {
|
||||
B:'Chevalier (Baronet)', C:'Baron', D:'Marquis', E:'Comte', F:'Duc', G:'Archiduc', H:'Empereur',
|
||||
};
|
||||
|
||||
static _IMPORTANCE = {
|
||||
'-5':'Très mineur', '-4':'Mineur', '-3':'Mineur', '-2':'Très secondaire', '-1':'Secondaire',
|
||||
'0':'Ordinaire', '1':'Important', '2':'Important', '3':'Très important', '4':'Majeure',
|
||||
'5':'Majeure', '6':'Capitale',
|
||||
};
|
||||
|
||||
static _foldRow(label, value, detail, titleAttr) {
|
||||
const valAttr = titleAttr ? ` title="${titleAttr}"` : '';
|
||||
return `<tr><td colspan="2">
|
||||
<details>
|
||||
<summary><span class="fold-label">${label}</span><span class="fold-value"${valAttr}>${value}</span></summary>
|
||||
<div class="fold-content">${detail}</div>
|
||||
</details>
|
||||
</td></tr>`;
|
||||
}
|
||||
|
||||
static _decodeImportance(ix) {
|
||||
if (!ix) return '';
|
||||
const m = String(ix).match(/\{?\s*(-?\d+)\s*\}?/);
|
||||
if (!m) return SectorMapApp._foldRow('Importance', ix, '');
|
||||
const val = m[1];
|
||||
const desc = SectorMapApp._IMPORTANCE[val] || '—';
|
||||
const detail = `<div class="fold-desc">Valeur d’importance économique et stratégique du monde.<br>${val} = ${desc}</div>`;
|
||||
return SectorMapApp._foldRow('Importance', `{ ${val} } ${desc}`, detail);
|
||||
}
|
||||
|
||||
static _decodeEconomics(ex) {
|
||||
if (!ex) return '';
|
||||
let s = String(ex).replace(/[()\s]/g, '');
|
||||
const m = s.match(/^([\dA-F])([\dA-F])([\dA-F])([+-]\d+)$/i);
|
||||
if (!m) return SectorMapApp._foldRow('Économie', ex, '');
|
||||
const res = m[1], lab = m[2], inf = m[3], eff = m[4];
|
||||
const detail = `<table class="fold-subtable">
|
||||
<tr><td>Ressources</td><td>${res}</td></tr>
|
||||
<tr><td>Main-d’œuvre</td><td>${lab}</td></tr>
|
||||
<tr><td>Infrastructure</td><td>${inf}</td></tr>
|
||||
<tr><td>Efficacité</td><td>${eff}</td></tr>
|
||||
</table>`;
|
||||
return SectorMapApp._foldRow('Économie', `( ${res} ${lab} ${inf} ${eff} )`, detail);
|
||||
}
|
||||
|
||||
static _decodeCulture(cx) {
|
||||
if (!cx) return '';
|
||||
const s = String(cx).replace(/[\[\]\s]/g, '');
|
||||
if (s.length < 4) return SectorMapApp._foldRow('Culture', cx, '');
|
||||
const h = s[0].toUpperCase(), t = s[1].toUpperCase(), p = s[2].toUpperCase(), a = s[3].toUpperCase();
|
||||
const detail = `<table class="fold-subtable">
|
||||
<tr><td>Hétérogénéité</td><td>${h}</td></tr>
|
||||
<tr><td>Traditionalisme</td><td>${t}</td></tr>
|
||||
<tr><td>Progressisme</td><td>${p}</td></tr>
|
||||
<tr><td>Agressivité</td><td>${a}</td></tr>
|
||||
</table>`;
|
||||
return SectorMapApp._foldRow('Culture', `[ ${h} ${t} ${p} ${a} ]`, detail);
|
||||
}
|
||||
|
||||
static _decodePopulation(uwp, pbg) {
|
||||
if (!uwp || uwp.length < 5) return '';
|
||||
const popUwp = SectorMapApp._hexVal(uwp[4]);
|
||||
if (popUwp < 0) return '';
|
||||
const popPbg = pbg ? parseInt(pbg[0], 10) : null;
|
||||
const multiplier = popPbg != null && !isNaN(popPbg) ? popPbg : 1;
|
||||
const base = Math.pow(10, popUwp);
|
||||
const total = multiplier * base;
|
||||
const fmtBase = `10<sup>${popUwp}</sup>`;
|
||||
const fmtMult = multiplier;
|
||||
const fmtTotal = total >= 1e9 ? `${(total / 1e9).toFixed(1)} milliards`
|
||||
: total >= 1e6 ? `${(total / 1e6).toFixed(1)} millions`
|
||||
: total >= 1e3 ? `${(total / 1e3).toFixed(0)} 000`
|
||||
: String(total);
|
||||
const belts = pbg ? parseInt(pbg[1], 10) : null;
|
||||
const gas = pbg ? parseInt(pbg[2], 10) : null;
|
||||
const detail = `<div class="fold-desc">Population = multiplicateur (PBG: <b>${popPbg}</b>) × 10<sup>chiffre UWP (${uwp[4]})</sup><br>
|
||||
Ceintures d’astéroïdes : <b>${belts ?? '?'}</b> | Géantes gazeuses : <b>${gas ?? '?'}</b></div>`;
|
||||
return SectorMapApp._foldRow('Population', `${fmtMult} × ${fmtBase} = ${fmtTotal}`, detail);
|
||||
}
|
||||
|
||||
static _decodeNobility(nob) {
|
||||
if (!nob) return '';
|
||||
const titles = [];
|
||||
for (const ch of nob) {
|
||||
const desc = SectorMapApp._NOBILITY[ch.toUpperCase()];
|
||||
if (desc) titles.push(`${ch} (${desc})`);
|
||||
}
|
||||
if (!titles.length) return SectorMapApp._foldRow('Noblesse', nob, '');
|
||||
const detail = `<div class="fold-desc">Titres de noblesse impériale présents sur ce monde.</div>`;
|
||||
return SectorMapApp._foldRow('Noblesse', titles.join(', '), detail);
|
||||
}
|
||||
|
||||
static _buildWorldCardHTML(w) {
|
||||
const sector = w.Sector || '';
|
||||
const hex = w.Hex || '';
|
||||
const name = w.Name || '—';
|
||||
const uwp = w.UWP || '???????-?';
|
||||
const bases = w.Bases || '';
|
||||
const remarks = w.Remarks || '';
|
||||
const allegiance = w.Allegiance || '';
|
||||
const stellar = w.Stellar || '';
|
||||
const zone = w.Zone || '';
|
||||
const pbg = w.PBG || '';
|
||||
|
||||
const zoneLabel = zone === 'R' ? 'Rouge'
|
||||
: zone === 'A' ? 'Ambre'
|
||||
: 'Verte';
|
||||
|
||||
const lines = [];
|
||||
|
||||
const uwpDetail = SectorMapApp._uwpBreakdown(uwp);
|
||||
lines.push(SectorMapApp._foldRow('UWP', `<span class="mono">${uwp}</span>`, uwpDetail));
|
||||
|
||||
const ixRow = SectorMapApp._decodeImportance(w.Ix);
|
||||
if (ixRow) lines.push(ixRow);
|
||||
const exRow = SectorMapApp._decodeEconomics(w.Ex);
|
||||
if (exRow) lines.push(exRow);
|
||||
const cxRow = SectorMapApp._decodeCulture(w.Cx);
|
||||
if (cxRow) lines.push(cxRow);
|
||||
const popRow = SectorMapApp._decodePopulation(uwp, pbg);
|
||||
if (popRow) lines.push(popRow);
|
||||
const nobRow = SectorMapApp._decodeNobility(w.Nobility);
|
||||
if (nobRow) lines.push(nobRow);
|
||||
|
||||
if (bases) {
|
||||
const bCodes = bases.split(/[\s,;]+/);
|
||||
const bList = bCodes.map(c => {
|
||||
const desc = SectorMapApp._BASES_HELP[c.toUpperCase()];
|
||||
return `<tr><td class="mono">${c}</td><td>${desc || '—'}</td></tr>`;
|
||||
}).join('');
|
||||
const bDetail = `<table class="fold-subtable"><tbody>${bList}</tbody></table>`;
|
||||
lines.push(SectorMapApp._foldRow('Bases', bases, bDetail));
|
||||
}
|
||||
|
||||
if (remarks) {
|
||||
const rCodes = remarks.split(/[\s,;]+/);
|
||||
const rList = rCodes.map(c => {
|
||||
const desc = SectorMapApp._REMARKS_HELP[c.toUpperCase()];
|
||||
return `<tr><td class="mono">${c}</td><td>${desc || '—'}</td></tr>`;
|
||||
}).join('');
|
||||
const rDetail = `<table class="fold-subtable"><tbody>${rList}</tbody></table>`;
|
||||
lines.push(SectorMapApp._foldRow('Remarques', remarks, rDetail));
|
||||
}
|
||||
|
||||
if (allegiance) {
|
||||
const allegFull = w.AllegianceName || '';
|
||||
const aDetail = `<div class="fold-desc">${allegFull || allegiance}</div>`;
|
||||
lines.push(SectorMapApp._foldRow('Allégeance', allegFull ? `${allegiance} (${allegFull})` : allegiance, aDetail));
|
||||
}
|
||||
|
||||
if (stellar) {
|
||||
const sList = [];
|
||||
let remaining = stellar.trim();
|
||||
const reStar = /^([OBAFGKMLTY])(\d)\s*(VII|VI|V|IV|III|II|I)\s*/i;
|
||||
while (remaining) {
|
||||
const m = remaining.match(reStar);
|
||||
if (m) {
|
||||
const type = SectorMapApp._STAR_TYPES[m[1].toUpperCase()] || m[1];
|
||||
const cls = SectorMapApp._STAR_CLASS[m[3]] || m[3];
|
||||
sList.push(`<tr><td class="mono">${m[1]}${m[2]} ${m[3]}</td><td>${type} · ${cls}</td></tr>`);
|
||||
remaining = remaining.slice(m[0].length).trimStart();
|
||||
} else {
|
||||
const next = remaining.indexOf(' ');
|
||||
if (next < 0) break;
|
||||
remaining = remaining.slice(next + 1).trimStart();
|
||||
}
|
||||
}
|
||||
const sDetail = sList.length ? `<table class="fold-subtable"><tbody>${sList.join('')}</tbody></table>` : `<div class="fold-desc">${stellar}</div>`;
|
||||
lines.push(SectorMapApp._foldRow('Étoile', `<span class="mono">${stellar}</span>`, sDetail));
|
||||
}
|
||||
|
||||
return `<section class="mgt2-world-card">
|
||||
<div class="mgt2-world-card-header">
|
||||
<span class="mgt2-world-name">${name}</span>
|
||||
<span class="mgt2-world-hex">${sector} ${hex}</span>
|
||||
<span class="mgt2-world-zone zone-${zone.toLowerCase() || 'g'}">${zoneLabel}</span>
|
||||
</div>
|
||||
<table class="mgt2-world-card-body"><tbody>${lines.join('')}</tbody></table>
|
||||
<div class="mgt2-world-card-actions">
|
||||
<a class="mgt2-world-commerce" data-sector="${this._escapeAttr(sector)}" data-hex="${hex}" data-uwp="${uwp}" data-zone="${zone || 'normal'}" data-name="${this._escapeAttr(name)}">
|
||||
<i class="fas fa-balance-scale"></i> Commerce
|
||||
</a>
|
||||
</div>
|
||||
</section>`;
|
||||
}
|
||||
|
||||
static _escapeAttr(str) {
|
||||
if (!str) return '';
|
||||
return String(str).replace(/&/g, '&').replace(/"/g, '"').replace(/'/g, ''');
|
||||
}
|
||||
|
||||
_postWorldCard(w) {
|
||||
const html = SectorMapApp._buildWorldCardHTML(w);
|
||||
ChatMessage.create({
|
||||
content: html,
|
||||
whisper: [game.user.id],
|
||||
});
|
||||
}
|
||||
|
||||
/* ───── Recherche de monde ───── */
|
||||
|
||||
async _doSearch(input, results) {
|
||||
const query = input.value.trim();
|
||||
if (query.length < 2) { results.innerHTML = ''; return; }
|
||||
const worlds = await searchWorlds(query);
|
||||
if (!worlds.length) {
|
||||
results.innerHTML = '<li class="no-result">Aucun monde trouvé</li>';
|
||||
return;
|
||||
}
|
||||
results.innerHTML = worlds.slice(0, 12).map(w =>
|
||||
`<li data-sector="${w.sector}" data-hex="${w.hex}" data-name="${w.name}">
|
||||
<span class="world-name">${w.name}</span>
|
||||
<span class="world-uwp">${w.uwp}</span>
|
||||
<span class="world-sector">${w.sector}</span>
|
||||
</li>`
|
||||
).join('');
|
||||
results.querySelectorAll('li[data-sector]').forEach(li => {
|
||||
li.addEventListener('click', () => this._selectWorld(li, input, results));
|
||||
});
|
||||
}
|
||||
|
||||
async _selectWorld(li, input, results) {
|
||||
const sector = li.dataset.sector;
|
||||
const hex = li.dataset.hex;
|
||||
const name = li.dataset.name;
|
||||
results.innerHTML = '';
|
||||
input.value = name;
|
||||
|
||||
this._sector = sector;
|
||||
this._subsector = null;
|
||||
this._mapHex = hex;
|
||||
this._mapCenter = null;
|
||||
this._mapScale = null;
|
||||
this._enableSyncButton(name);
|
||||
|
||||
const iframe = this.element?.querySelector('.mgt2-sector-map-frame');
|
||||
if (iframe) iframe.src = this._mapUrl;
|
||||
|
||||
ui.notifications.info(`Carte centrée sur ${name} (${sector} ${hex})`);
|
||||
}
|
||||
|
||||
/* ───── Partage ───── */
|
||||
|
||||
async _syncAll() {
|
||||
if (!game.socket?.emit) {
|
||||
ui.notifications.warn('Socket indisponible — impossible de synchroniser');
|
||||
return;
|
||||
}
|
||||
try {
|
||||
// Tentative de récupération du zoom via getViewport
|
||||
const viewport = await new Promise((resolve) => {
|
||||
const handler = (event) => {
|
||||
if (event.data?.type === 'viewport') {
|
||||
window.removeEventListener('message', handler);
|
||||
resolve(event.data);
|
||||
}
|
||||
};
|
||||
window.addEventListener('message', handler);
|
||||
const iframe = this.element?.querySelector('.mgt2-sector-map-frame');
|
||||
if (iframe?.contentWindow) {
|
||||
iframe.contentWindow.postMessage(
|
||||
{ source: 'travellermap', type: 'getViewport' },
|
||||
'*'
|
||||
);
|
||||
}
|
||||
setTimeout(() => {
|
||||
window.removeEventListener('message', handler);
|
||||
resolve(null);
|
||||
}, 1000);
|
||||
});
|
||||
|
||||
if (viewport) {
|
||||
this._sector = viewport.sector || this._sector;
|
||||
this._subsector = viewport.subsector || this._subsector;
|
||||
this._mapHex = viewport.hex || this._mapHex;
|
||||
this._mapCenter = (viewport.x != null && viewport.y != null) ? `${viewport.x},${viewport.y}` : this._mapCenter;
|
||||
this._mapScale = viewport.scale || this._mapScale;
|
||||
}
|
||||
|
||||
const payload = {
|
||||
_type: 'sectorMapSync',
|
||||
sector: this._sector,
|
||||
subsector: this._subsector,
|
||||
mapHex: this._mapHex,
|
||||
mapCenter: this._mapCenter,
|
||||
mapScale: this._mapScale,
|
||||
};
|
||||
const players = game.users.filter(u => !u.isGM && u.active);
|
||||
for (const player of players) {
|
||||
game.socket.emit(`module.${MODULE_ID}`, payload);
|
||||
}
|
||||
ui.notifications.info(`Vue synchronisée chez ${players.length} joueur(s)`);
|
||||
} catch (err) {
|
||||
console.error(`${MODULE_ID} | Erreur socket sync:`, err);
|
||||
ui.notifications.error('Erreur lors de la synchronisation');
|
||||
}
|
||||
}
|
||||
|
||||
updatePosition(sector, subsector, mapHex, mapUrl) {
|
||||
this._sector = sector;
|
||||
this._subsector = subsector;
|
||||
this._mapHex = mapHex || null;
|
||||
const iframe = this.element?.querySelector('.mgt2-sector-map-frame');
|
||||
if (iframe) iframe.src = mapUrl || this._mapUrl;
|
||||
}
|
||||
|
||||
_openTravelDialog() {
|
||||
const existing = Object.values(ui.windows).find(w => w.id === 'mgt2-travel-dialog');
|
||||
if (existing) { existing.bringToTop(); return; }
|
||||
const dialog = new TravelDialog();
|
||||
dialog.render({ force: true });
|
||||
}
|
||||
|
||||
/* ───── Nettoyage ───── */
|
||||
|
||||
close() {
|
||||
if (this._handler) {
|
||||
window.removeEventListener('message', this._handler);
|
||||
this._handler = null;
|
||||
}
|
||||
return super.close();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,281 @@
|
||||
/**
|
||||
* Traveller NPC Generator - Dialogue de génération
|
||||
*
|
||||
* Ce fichier contient le dialogue pour générer des PNJ Traveller.
|
||||
*/
|
||||
|
||||
import { generateAndCreateTravellerNpc } from './travellerNpcGenerator.js';
|
||||
import {
|
||||
CITIZEN_CATEGORY_LIST,
|
||||
EXPERIENCE_LEVEL_LIST,
|
||||
ROLE_LIST,
|
||||
GENDER_LIST,
|
||||
DEFAULT_OPTIONS,
|
||||
generateRandomName,
|
||||
CITIZEN_CATEGORY_LABELS_FR,
|
||||
EXPERIENCE_LEVEL_LABELS_FR,
|
||||
ROLE_LABELS_FR,
|
||||
GENDER_LABELS_FR
|
||||
} from './data/travellerNpcGenerator.js';
|
||||
|
||||
const { ApplicationV2, HandlebarsApplicationMixin } = foundry.applications.api;
|
||||
const MODULE_ID = 'mgt2-compendium-amiral-denisov';
|
||||
|
||||
export class TravellerNpcDialog extends HandlebarsApplicationMixin(ApplicationV2) {
|
||||
static DEFAULT_OPTIONS = {
|
||||
id: 'mgt2-traveller-npc',
|
||||
classes: ['mgt2-npc-dialog', 'mgt2-traveller-npc-dialog'],
|
||||
position: {
|
||||
width: 700,
|
||||
height: 'auto',
|
||||
},
|
||||
window: {
|
||||
title: 'Générateur de PNJ Traveller – MgT2e',
|
||||
resizable: true,
|
||||
},
|
||||
};
|
||||
|
||||
static PARTS = {
|
||||
main: {
|
||||
template: `modules/${MODULE_ID}/templates/traveller-npc-dialog.hbs`,
|
||||
root: true,
|
||||
},
|
||||
};
|
||||
|
||||
constructor(options = {}) {
|
||||
super(options);
|
||||
|
||||
// Form data avec valeurs par défaut
|
||||
this._formData = {
|
||||
citizenCategory: options.citizenCategory || DEFAULT_OPTIONS.citizenCategory,
|
||||
experience: options.experience || DEFAULT_OPTIONS.experience,
|
||||
role: options.role || DEFAULT_OPTIONS.role,
|
||||
gender: options.gender || DEFAULT_OPTIONS.gender,
|
||||
firstName: options.firstName || '',
|
||||
surname: options.surname || '',
|
||||
useRandomName: options.useRandomName !== false,
|
||||
createActor: options.createActor !== undefined ? options.createActor : DEFAULT_OPTIONS.createActor,
|
||||
actorName: options.actorName || '',
|
||||
openCreatedActor: options.openCreatedActor !== undefined ? options.openCreatedActor : DEFAULT_OPTIONS.openCreatedActor,
|
||||
};
|
||||
|
||||
// Bind les méthodes pour éviter les problèmes de contexte
|
||||
this._readForm = this._readForm.bind(this);
|
||||
this._handleGenerate = this._handleGenerate.bind(this);
|
||||
this._randomizeName = this._randomizeName.bind(this);
|
||||
this._applyThemeStyles = this._applyThemeStyles.bind(this);
|
||||
this._getForm = this._getForm.bind(this);
|
||||
}
|
||||
|
||||
async _prepareContext() {
|
||||
registerHandlebarsHelpers();
|
||||
return {
|
||||
...this._formData,
|
||||
citizenCategories: CITIZEN_CATEGORY_LIST.map(c => ({
|
||||
key: c.key,
|
||||
label: CITIZEN_CATEGORY_LABELS_FR[c.key] || c.label,
|
||||
description: c.description
|
||||
})),
|
||||
experienceLevels: EXPERIENCE_LEVEL_LIST.map(e => ({
|
||||
key: e.key,
|
||||
label: EXPERIENCE_LEVEL_LABELS_FR[e.key] || e.label,
|
||||
description: e.description
|
||||
})),
|
||||
roles: ROLE_LIST.map(r => ({
|
||||
key: r.key,
|
||||
label: ROLE_LABELS_FR[r.key] || r.label,
|
||||
description: r.description
|
||||
})),
|
||||
genders: GENDER_LIST.map(g => ({
|
||||
key: g.key,
|
||||
label: GENDER_LABELS_FR[g.key] || g.label
|
||||
}))
|
||||
};
|
||||
}
|
||||
|
||||
async _onRender(context, options) {
|
||||
await super._onRender(context, options);
|
||||
const html = this._getForm();
|
||||
if (!html?.length) return;
|
||||
|
||||
html.addClass('mgt2-traveller-npc-form');
|
||||
this._applyThemeStyles(html);
|
||||
|
||||
// Gestion des événements
|
||||
html.find('[data-action="generate-traveller-npc"]').on('click', async (event) => {
|
||||
event.preventDefault();
|
||||
this._readForm(html);
|
||||
await this._handleGenerate();
|
||||
});
|
||||
|
||||
html.find('[data-action="randomize-name"]').on('click', (event) => {
|
||||
event.preventDefault();
|
||||
this._randomizeName(html);
|
||||
});
|
||||
|
||||
// Gestion du basculement entre nom aléatoire et nom personnalisé
|
||||
html.find('[name="useRandomName"]').on('change', (event) => {
|
||||
const useRandom = event.target.checked;
|
||||
this._formData.useRandomName = useRandom;
|
||||
html.find('.name-fields').toggleClass('hidden', useRandom);
|
||||
});
|
||||
|
||||
// Initialiser l'affichage des champs de nom
|
||||
html.find('.name-fields').toggleClass('hidden', this._formData.useRandomName);
|
||||
}
|
||||
|
||||
_getForm() {
|
||||
return $(this.element).find('.window-content');
|
||||
}
|
||||
|
||||
_applyThemeStyles(html) {
|
||||
// Les styles sont maintenant gérés par CSS, cette méthode peut être vide
|
||||
// ou utilisée pour des ajustements spécifiques si nécessaire
|
||||
// Les styles de base sont cohérents avec mgt2-npc-dialog et mgt2-commerce-dialog
|
||||
}
|
||||
|
||||
_readForm(html) {
|
||||
this._formData.citizenCategory = html.find('[name="citizenCategory"]').val();
|
||||
this._formData.experience = html.find('[name="experience"]').val();
|
||||
this._formData.role = html.find('[name="role"]').val();
|
||||
this._formData.gender = html.find('[name="gender"]').val();
|
||||
this._formData.firstName = html.find('[name="firstName"]').val();
|
||||
this._formData.surname = html.find('[name="surname"]').val();
|
||||
this._formData.useRandomName = html.find('[name="useRandomName"]').is(':checked');
|
||||
this._formData.createActor = html.find('[name="createActor"]').is(':checked');
|
||||
this._formData.actorName = html.find('[name="actorName"]').val();
|
||||
this._formData.openCreatedActor = html.find('[name="openCreatedActor"]').is(':checked');
|
||||
}
|
||||
|
||||
_randomizeName(html) {
|
||||
const name = generateRandomName(this._formData.gender);
|
||||
html.find('[name="firstName"]').val(name.firstName);
|
||||
html.find('[name="surname"]').val(name.surname);
|
||||
this._formData.firstName = name.firstName;
|
||||
this._formData.surname = name.surname;
|
||||
this._formData.useRandomName = false;
|
||||
html.find('[name="useRandomName"]').prop('checked', false);
|
||||
html.find('.name-fields').removeClass('hidden');
|
||||
}
|
||||
|
||||
async _handleGenerate() {
|
||||
const button = $(this.element).find('[data-action="generate-traveller-npc"]');
|
||||
const originalLabel = button.html();
|
||||
|
||||
try {
|
||||
// Désactiver le bouton pendant la génération
|
||||
button.prop('disabled', true).html('<i class="fas fa-spinner fa-spin"></i> Génération...');
|
||||
|
||||
// Préparer les options de génération
|
||||
const generateOptions = {
|
||||
citizenCategory: this._formData.citizenCategory,
|
||||
experience: this._formData.experience,
|
||||
role: this._formData.role,
|
||||
gender: this._formData.gender,
|
||||
createActor: this._formData.createActor,
|
||||
actorName: this._formData.actorName,
|
||||
openCreatedActor: this._formData.openCreatedActor
|
||||
};
|
||||
|
||||
// Si on n'utilise pas de nom aléatoire, passer le nom personnalisé
|
||||
if (!this._formData.useRandomName && this._formData.firstName && this._formData.surname) {
|
||||
generateOptions.firstName = this._formData.firstName;
|
||||
generateOptions.surname = this._formData.surname;
|
||||
}
|
||||
|
||||
// Générer le PNJ
|
||||
const result = await generateAndCreateTravellerNpc(generateOptions);
|
||||
|
||||
if (result.success) {
|
||||
// Afficher le résultat dans le chat
|
||||
await this._postToChatResult(result);
|
||||
|
||||
if (result.createdActor) {
|
||||
ui.notifications.info(`Fiche PNJ Traveller créée : ${result.createdActor.name}`);
|
||||
}
|
||||
} else {
|
||||
ui.notifications.error('Erreur lors de la génération du PNJ Traveller');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(`${MODULE_ID} | Erreur lors de la génération du PNJ Traveller:`, error);
|
||||
ui.notifications.error(`Erreur: ${error.message}`);
|
||||
} finally {
|
||||
// Réactiver le bouton
|
||||
button.prop('disabled', false).html(originalLabel);
|
||||
}
|
||||
}
|
||||
|
||||
async _postToChatResult(data) {
|
||||
registerHandlebarsHelpers();
|
||||
const html = await foundry.applications.handlebars.renderTemplate(
|
||||
`modules/${MODULE_ID}/templates/traveller-npc-result.hbs`,
|
||||
data
|
||||
);
|
||||
|
||||
await ChatMessage.create({
|
||||
content: html,
|
||||
speaker: ChatMessage.getSpeaker(),
|
||||
flags: { [MODULE_ID]: { type: 'traveller-npc-result' } },
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Helper functions
|
||||
// ============================================================================
|
||||
|
||||
// Import des données pour les helpers
|
||||
import { CHARACTERISTIC_LIST, UPP_ORDER } from './data/travellerNpcGenerator.js';
|
||||
|
||||
let helpersRegistered = false;
|
||||
|
||||
function registerHandlebarsHelpers() {
|
||||
if (helpersRegistered) return;
|
||||
helpersRegistered = true;
|
||||
|
||||
// Helper pour comparer deux valeurs
|
||||
Handlebars.registerHelper('eq', (a, b) => a === b);
|
||||
|
||||
// Helper pour rejoindre un tableau
|
||||
Handlebars.registerHelper('join', (arr, sep) => (Array.isArray(arr) ? arr.join(sep) : ''));
|
||||
|
||||
// Helper pour vérifier si une valeur contient du texte
|
||||
Handlebars.registerHelper('contains', (text, search) => String(text ?? '').includes(search));
|
||||
|
||||
// Helper pour vérifier si a > b
|
||||
Handlebars.registerHelper('gt', (a, b) => a > b);
|
||||
|
||||
// Helper pour afficher le niveau de compétence avec un symbole
|
||||
Handlebars.registerHelper('skillLevelSymbol', (level) => {
|
||||
if (level === 0) return '';
|
||||
if (level === 1) return '★';
|
||||
if (level === 2) return '★★';
|
||||
if (level === 3) return '★★★';
|
||||
return `+${level}`;
|
||||
});
|
||||
|
||||
// Helper pour formater le DM
|
||||
Handlebars.registerHelper('formatDm', (value) => {
|
||||
const dm = Math.floor((value - 6) / 3);
|
||||
return dm >= 0 ? `+${dm}` : `${dm}`;
|
||||
});
|
||||
|
||||
// Helper pour obtenir la classe CSS du niveau de compétence
|
||||
Handlebars.registerHelper('skillLevelClass', (level) => {
|
||||
if (level === 3) return 'skill-level-3';
|
||||
if (level === 2) return 'skill-level-2';
|
||||
if (level === 1) return 'skill-level-1';
|
||||
return 'skill-level-0';
|
||||
});
|
||||
|
||||
// Helper pour lookup dans un objet
|
||||
Handlebars.registerHelper('lookup', (obj, key) => {
|
||||
if (!obj || !key) return '';
|
||||
return obj[key] !== undefined ? obj[key] : '';
|
||||
});
|
||||
}
|
||||
|
||||
// Exporter pour pouvoir l'ouvrir depuis d'autres modules
|
||||
export function openTravellerNpcDialog(options = {}) {
|
||||
new TravellerNpcDialog(options).render({ force: true });
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user