@elite-dangerous-almanac/core 0.1.0-beta.3 → 0.1.0-beta.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/PROVENANCE/i18n/SOURCES.md +88 -0
- package/PROVENANCE/ships/SOURCES.md +113 -13
- package/README.md +19 -3
- package/THIRD_PARTY_NOTICES.md +38 -13
- package/dist/chunk-24INI4U7.js +1 -0
- package/dist/chunk-24INI4U7.js.map +1 -0
- package/dist/chunk-3IMWUYXJ.js +1 -0
- package/dist/{chunk-A3NM7SAJ.js.map → chunk-3IMWUYXJ.js.map} +1 -1
- package/dist/chunk-5W43EQEQ.js +1 -0
- package/dist/chunk-5W43EQEQ.js.map +1 -0
- package/dist/chunk-7MKYFCFF.js +1 -0
- package/dist/chunk-7MKYFCFF.js.map +1 -0
- package/dist/chunk-BUV3MXGK.js +1 -0
- package/dist/chunk-BUV3MXGK.js.map +1 -0
- package/dist/chunk-DHOCTGWB.js +1 -0
- package/dist/chunk-DHOCTGWB.js.map +1 -0
- package/dist/{chunk-XH7WDPS2.js → chunk-DMCFX6VO.js} +1 -1
- package/dist/chunk-DYFUHGJQ.js +1 -0
- package/dist/chunk-DYFUHGJQ.js.map +1 -0
- package/dist/chunk-ESEM3LPU.js +1 -0
- package/dist/chunk-ESEM3LPU.js.map +1 -0
- package/dist/chunk-HOKW2EWE.js +1 -0
- package/dist/chunk-HOKW2EWE.js.map +1 -0
- package/dist/{chunk-A6XPYSVR.js → chunk-IHHS5Q5S.js} +1 -1
- package/dist/{chunk-A6XPYSVR.js.map → chunk-IHHS5Q5S.js.map} +1 -1
- package/dist/chunk-IJRKEODR.js +1 -0
- package/dist/{chunk-NEVMA6RJ.js.map → chunk-IJRKEODR.js.map} +1 -1
- package/dist/chunk-KPETDYQX.js +1 -0
- package/dist/chunk-KPETDYQX.js.map +1 -0
- package/dist/{chunk-Q22LXT53.js → chunk-NQ2ID6BF.js} +1 -1
- package/dist/chunk-NSSWYRHN.js +1 -0
- package/dist/{chunk-Y2MUIE5W.js.map → chunk-NSSWYRHN.js.map} +1 -1
- package/dist/chunk-O72KI7RP.js +1 -0
- package/dist/{chunk-K3AMV27L.js.map → chunk-O72KI7RP.js.map} +1 -1
- package/dist/{chunk-INNFH37U.js → chunk-PDE4YOFT.js} +1 -1
- package/dist/{chunk-INNFH37U.js.map → chunk-PDE4YOFT.js.map} +1 -1
- package/dist/chunk-QMQHIZGS.js +1 -0
- package/dist/chunk-QMQHIZGS.js.map +1 -0
- package/dist/chunk-RF2IKLWQ.js +1 -0
- package/dist/chunk-RF2IKLWQ.js.map +1 -0
- package/dist/chunk-T24FTOEU.js +1 -0
- package/dist/{chunk-3ZX45CZJ.js.map → chunk-T24FTOEU.js.map} +1 -1
- package/dist/chunk-TLA6LHLN.js +1 -0
- package/dist/{chunk-V4C6FIE2.js.map → chunk-TLA6LHLN.js.map} +1 -1
- package/dist/chunk-TXT2LOZI.js +1 -0
- package/dist/chunk-TXT2LOZI.js.map +1 -0
- package/dist/{chunk-LFVHJT6D.js → chunk-VQQ6WHAL.js} +1 -1
- package/dist/{chunk-LFVHJT6D.js.map → chunk-VQQ6WHAL.js.map} +1 -1
- package/dist/i18n/blueprints.d.ts +30 -0
- package/dist/i18n/blueprints.js +1 -0
- package/dist/i18n/blueprints.js.map +1 -0
- package/dist/i18n/experimental-effects.d.ts +30 -0
- package/dist/i18n/experimental-effects.js +1 -0
- package/dist/i18n/experimental-effects.js.map +1 -0
- package/dist/i18n/index.d.ts +7 -0
- package/dist/i18n/index.js +1 -0
- package/dist/i18n/index.js.map +1 -0
- package/dist/i18n/modules.d.ts +32 -0
- package/dist/i18n/modules.js +1 -0
- package/dist/i18n/modules.js.map +1 -0
- package/dist/materials/index.js +1 -1
- package/dist/materials/materials-all.js +1 -1
- package/dist/materials/materials.js +1 -1
- package/dist/{ship-loadout-CWpORI0v.d.ts → ship-loadout-BAU7scrE.d.ts} +207 -12
- package/dist/ships/heat.d.ts +383 -0
- package/dist/ships/heat.js +1 -0
- package/dist/ships/heat.js.map +1 -0
- package/dist/ships/index.d.ts +11 -6
- package/dist/ships/index.js +1 -1
- package/dist/ships/loadout-calculations.d.ts +2 -0
- package/dist/ships/loadout-calculations.js +1 -1
- package/dist/ships/loadout-validation.d.ts +29 -2
- package/dist/ships/loadout-validation.js +1 -1
- package/dist/ships/mobility.d.ts +139 -0
- package/dist/ships/mobility.js +1 -0
- package/dist/ships/mobility.js.map +1 -0
- package/dist/ships/module-limits.d.ts +79 -0
- package/dist/ships/module-limits.js +1 -0
- package/dist/ships/module-limits.js.map +1 -0
- package/dist/ships/modules-all.js +1 -1
- package/dist/ships/modules-core.js +1 -1
- package/dist/ships/modules-hardpoint.js +1 -1
- package/dist/ships/modules-internal.js +1 -1
- package/dist/ships/modules-utility.js +1 -1
- package/dist/ships/modules.d.ts +55 -2
- package/dist/ships/modules.js +1 -1
- package/dist/ships/pre-engineered-stats.js +1 -1
- package/dist/ships/shield-recovery.d.ts +116 -0
- package/dist/ships/shield-recovery.js +1 -0
- package/dist/ships/shield-recovery.js.map +1 -0
- package/dist/ships/ship-loadout.d.ts +4 -1
- package/dist/ships/ship-loadout.js +1 -1
- package/dist/ships/ships.d.ts +49 -21
- package/dist/ships/ships.js +1 -1
- package/dist/ships/slef.d.ts +7 -1
- package/dist/ships/slef.js +1 -1
- package/dist/ships/weapons.d.ts +10 -0
- package/dist/ships/weapons.js +1 -1
- package/package.json +36 -3
- package/dist/chunk-3ZX45CZJ.js +0 -1
- package/dist/chunk-A3NM7SAJ.js +0 -1
- package/dist/chunk-COE5ADYJ.js +0 -1
- package/dist/chunk-COE5ADYJ.js.map +0 -1
- package/dist/chunk-K3AMV27L.js +0 -1
- package/dist/chunk-NEVMA6RJ.js +0 -1
- package/dist/chunk-PP2VSA6M.js +0 -1
- package/dist/chunk-PP2VSA6M.js.map +0 -1
- package/dist/chunk-R4OD62HV.js +0 -1
- package/dist/chunk-R4OD62HV.js.map +0 -1
- package/dist/chunk-V4C6FIE2.js +0 -1
- package/dist/chunk-Y2DXFWOH.js +0 -1
- package/dist/chunk-Y2DXFWOH.js.map +0 -1
- package/dist/chunk-Y2MUIE5W.js +0 -1
- /package/dist/{chunk-XH7WDPS2.js.map → chunk-DMCFX6VO.js.map} +0 -0
- /package/dist/{chunk-Q22LXT53.js.map → chunk-NQ2ID6BF.js.map} +0 -0
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
# Localized game-name catalogues
|
|
2
|
+
|
|
3
|
+
These catalogues keep the canonical English display names already published by the
|
|
4
|
+
ships data domain and add only localized values carried explicitly by the pinned community
|
|
5
|
+
sources. They are deliberately sparse: absence means that no accepted source carried a
|
|
6
|
+
value, and the lookup API returns `null` for that locale rather than treating English as
|
|
7
|
+
a translation.
|
|
8
|
+
|
|
9
|
+
## `module-names.jsonc`
|
|
10
|
+
|
|
11
|
+
- **Acquired:** 2026-08-14 UTC.
|
|
12
|
+
- **EDDI revision:** commit `fdc1f47933bd930464610111fa11fc9dae264414`.
|
|
13
|
+
- **EDSY revision:** commit `e446fbe6e4597dea7ab0bd3105b9a36642388040`;
|
|
14
|
+
database version `424009901`, last-modified marker `20260810`.
|
|
15
|
+
- **Derivation:** all 1,199 current module symbols and English names come from the four
|
|
16
|
+
`data/ships/modules-*.jsonc` catalogues. EDDI's `ModuleDefinitions.cs` joins a symbol
|
|
17
|
+
to a resource key; `Properties/Modules.resx` and its localized siblings supply names.
|
|
18
|
+
An EDDI value is accepted only when its base English resource exactly equals the
|
|
19
|
+
Almanac's canonical English name. This prevents broad EDDI families such as
|
|
20
|
+
`CargoRack`, `MissileRack` and `PlanetaryApproachSuite` from erasing the distinct Mk II,
|
|
21
|
+
seeker and advanced names the Almanac carries. EDSY's module `fdname` and effective
|
|
22
|
+
`namekey` fill a missing `de`, `es`, `fr`, `pt` or `ru` value only when EDSY's English
|
|
23
|
+
module name also exactly equals the canonical name. Values shared by modules with one
|
|
24
|
+
canonical name are retained only when they agree, then stored once under that name.
|
|
25
|
+
- **Coverage:** English covers all 1,199 symbols. The explicit translations cover 1,120
|
|
26
|
+
in German, 1,090 in Spanish, 1,088 in French, 767 in Hungarian, 1,028 in Italian,
|
|
27
|
+
822 in Portuguese, 1,029 in Brazilian Portuguese, 1,153 in Russian and 1,028 in
|
|
28
|
+
Simplified Chinese.
|
|
29
|
+
- **Manual corrections:** none.
|
|
30
|
+
|
|
31
|
+
## `blueprint-names.jsonc`
|
|
32
|
+
|
|
33
|
+
- **Acquired:** 2026-08-14 UTC.
|
|
34
|
+
- **EDSY revision:** commit `e446fbe6e4597dea7ab0bd3105b9a36642388040`;
|
|
35
|
+
database version `424009901`, last-modified marker `20260810`.
|
|
36
|
+
- **Derivation:** each of the 107 current keys and its English name comes from
|
|
37
|
+
`data/ships/blueprints.jsonc`. The Frontier `fdname` joins directly to EDSY's
|
|
38
|
+
`blueprint.fdname`; that record's id selects an explicit `blueprint-<id>` entry from
|
|
39
|
+
each language file. Names remain keyed per blueprint because a single English phrase
|
|
40
|
+
can have different grammatical translations for different module families.
|
|
41
|
+
- **Coverage:** English covers all 107 blueprints; EDSY covers 55 in German and 59 each
|
|
42
|
+
in Spanish, French, Portuguese and Russian. The remaining recipes include Operations
|
|
43
|
+
and other newer records EDSY does not identify or translate.
|
|
44
|
+
- **Manual corrections:** EDSY's French `FSD_FastBoot` value ends in one accidental
|
|
45
|
+
ASCII space; the stored display name removes it so a successful lookup is already
|
|
46
|
+
trimmed like every other catalogue name.
|
|
47
|
+
|
|
48
|
+
## `experimental-effect-names.jsonc`
|
|
49
|
+
|
|
50
|
+
- **Acquired:** 2026-08-14 UTC.
|
|
51
|
+
- **EDSY revision:** commit `e446fbe6e4597dea7ab0bd3105b9a36642388040`;
|
|
52
|
+
database version `424009901`, last-modified marker `20260810`.
|
|
53
|
+
- **Derivation:** each of the 86 current keys and its English name comes from
|
|
54
|
+
`data/ships/experimental-effects.jsonc`. The Frontier `fdname` joins directly to
|
|
55
|
+
EDSY's `expeffect.fdname`; that record's id selects an explicit `expeffect-<id>` entry
|
|
56
|
+
from each language file.
|
|
57
|
+
- **Coverage:** English covers all 86 effects; EDSY covers 84 in German and 85 each in
|
|
58
|
+
Spanish, French, Portuguese and Russian.
|
|
59
|
+
- **Manual corrections:** none.
|
|
60
|
+
|
|
61
|
+
## Deliberate absence: ship names
|
|
62
|
+
|
|
63
|
+
- **Acquired:** 2026-08-14 UTC.
|
|
64
|
+
- **Odyssey Materials Helper revision:** commit
|
|
65
|
+
`23343c453938e724f317c56e9eb7db0dbfa71f78`;
|
|
66
|
+
`application/src/main/resources/locale/ships/ships.csv` has SHA-256
|
|
67
|
+
`6785f7cea00f36ca0a853091fd88f8ed5481a60f55c269643bff1ab0c3d6993d`.
|
|
68
|
+
- **EDSY revision:** commit `e446fbe6e4597dea7ab0bd3105b9a36642388040`;
|
|
69
|
+
database version `424009901`, last-modified marker `20260810`.
|
|
70
|
+
- **Evaluation:** each of the 48 current ship symbols is joined to Odyssey Materials
|
|
71
|
+
Helper's `ships.name.*` key after removing punctuation and folding case. EDSY's
|
|
72
|
+
`eddb.js` `ship.fdname` supplies the second join, with explicit `ship-<id>` language
|
|
73
|
+
entries filling locales absent from the CSV. The resulting source-backed coverage is
|
|
74
|
+
44 ships in Spanish, 42 in French, 38 in Portuguese, 45 in Russian and 44 in Chinese;
|
|
75
|
+
no accepted source carries a German ship-name table.
|
|
76
|
+
- **Standing conclusion:** all 213 resulting non-English values are byte-for-byte equal
|
|
77
|
+
to the canonical English ship names. A ship-name localization catalogue would
|
|
78
|
+
therefore publish no translated information and is deliberately absent. A source
|
|
79
|
+
carrying at least one genuinely localized ship name would justify revisiting this
|
|
80
|
+
conclusion.
|
|
81
|
+
- **Manual corrections:** none.
|
|
82
|
+
|
|
83
|
+
## Known gaps
|
|
84
|
+
|
|
85
|
+
Localized coverage follows the pinned sources and is not complete for every catalogue or
|
|
86
|
+
locale. Missing values are observable as `null`, never an English fallback. Expanding
|
|
87
|
+
source-backed coverage, localized slot labels and higher-level generated text remains
|
|
88
|
+
tracked by [#245](https://github.com/DarkSession/Elite-Dangerous-Almanac/issues/245).
|
|
@@ -15,7 +15,7 @@ Referred to throughout by source name; the pin is here, once.
|
|
|
15
15
|
| Odyssey Materials Helper CAPI fixture `application/src/test/resources/parser/capifc/test9.json` | commit `2c652a2349b754f1dde1a58b6daaac5a04e421a6` | 2026-08-09 UTC |
|
|
16
16
|
| EDCD/Coriolis — the application, for its formulas | commit `68c042ca6e3db62372cbbb2077cf972345511712` | 2026-08-01 UTC |
|
|
17
17
|
| msarilar/EDEngineer `EDEngineer/Resources/Data/blueprints.json` | SHA-256 `787e6bd0579264d7b4615a281318792cb212285786f4ae07f61ec1cc464cdec0` — read from the branch tip, so pinned by digest | 2026-08-08 UTC |
|
|
18
|
-
| Elite Dangerous in-game verification |
|
|
18
|
+
| Elite Dangerous in-game verification | game version `4.4.0.3`; direct in-game observation | 2026-08-14 UTC |
|
|
19
19
|
|
|
20
20
|
Every `eddb.js` derivation uses the baseline snapshot unless its catalogue note names
|
|
21
21
|
the Vessel Hangar snapshot.
|
|
@@ -37,15 +37,84 @@ identity from FDevIDs, stats and slots from coriolis-data, joined on `symbol`.
|
|
|
37
37
|
numeric ship-type `id` column is dropped — hulls are keyed by `symbol`.
|
|
38
38
|
`entitlement` is FDevIDs' DLC/grant token, kept only where the CSV gives one (28 of
|
|
39
39
|
the 48 hulls carry no entitlement, so the field is omitted rather than stored empty).
|
|
40
|
-
- **Stats + slots source:** coriolis-data `ships/*.json` — `properties` for
|
|
40
|
+
- **Stats + slots source:** coriolis-data `ships/*.json` — `properties` for manufacturer,
|
|
41
|
+
numeric size class and stats,
|
|
41
42
|
`slots` + `bulkheads` for the layout.
|
|
43
|
+
- **Manufacturer and size derivation:** `properties.manufacturer` is copied, with
|
|
44
|
+
coriolis-data's abbreviated `Lakon` normalized to the shipyard name `Lakon Spaceways`;
|
|
45
|
+
numeric `properties.class` maps `1`/`2`/`3` to `small`/`medium`/`large`, the game's
|
|
46
|
+
landing-pad classes. The Lynx Highliner instead takes Zorgon Peterson and class 2
|
|
47
|
+
(`medium`) from Frontier's update notes and EDSY's `class:2` record.
|
|
42
48
|
- **Stats derivation:** acquisition normalization looks up each hull's coriolis
|
|
43
49
|
record by display name (normalized; coriolis "Viper" ⇒ registry "Viper MkIII") and
|
|
44
|
-
copies a fixed whitelist of `properties` fields (`hullMass`, `speed
|
|
45
|
-
`baseArmour`, …). The repository's
|
|
50
|
+
copies a fixed whitelist of `properties` fields (`hullMass`, source `speed` as
|
|
51
|
+
`maximumSpeed`, `boost`, `baseArmour`, …). The repository's
|
|
46
52
|
`scripts/data/ships/merge-normalized-catalogues.mjs` then performs the deterministic
|
|
47
53
|
symbol join, preserving registry order and rejecting duplicate or unmatched input.
|
|
48
|
-
Masses are tonnes, speeds m/s, rotation rates deg/s.
|
|
54
|
+
Masses are tonnes, speeds m/s, rotation rates deg/s. The in-game hull audit below
|
|
55
|
+
overrides registry values where they disagree.
|
|
56
|
+
- **Speed is stored as installed endpoints.** An Elite Dangerous `4.4.0.3` hull audit
|
|
57
|
+
recorded 2026-08-14 UTC supplies `minimumSpeed` and `maximumSpeed` directly for all 48
|
|
58
|
+
hulls.
|
|
59
|
+
The game's ratio values carry no independent information:
|
|
60
|
+
`minThrust = 100 * minimumSpeed / maximumSpeed` and
|
|
61
|
+
`pipSpeed = (maximumSpeed - minimumSpeed) / (4 * maximumSpeed)`. The ratios are
|
|
62
|
+
therefore not retained; reconstructing an endpoint from rounded ratios can disagree
|
|
63
|
+
with the installed whole-number value (the Lynx's `73.75%` ratio produces
|
|
64
|
+
`210.1875` m/s rather than its installed `210` m/s).
|
|
65
|
+
- **Angular rates are stored as zero- and four-ENG-PIP endpoints.** The same game audit
|
|
66
|
+
supplies `minPitch`, `minRoll` and `minYaw` from each flight-default block. The
|
|
67
|
+
selected full-rate words come from the hull overrides; an exact `-1.0` override
|
|
68
|
+
sentinel selects the corresponding flight-default word. This structure holds for all
|
|
69
|
+
48 player hulls. EDSY's public handling implementation independently identifies these
|
|
70
|
+
minima as zero-ENG-PIP values and linearly interpolates each axis to its full rate.
|
|
71
|
+
- **Installed English display names are taken verbatim from the game.** The Elite
|
|
72
|
+
Dangerous `4.4.0.3` localisation audit recorded 2026-08-14 UTC replaces eight compact
|
|
73
|
+
registry spellings:
|
|
74
|
+
|
|
75
|
+
| Symbol | Registry name | Stored game name |
|
|
76
|
+
| ------------- | ---------------------- | ----------------------- |
|
|
77
|
+
| `Viper` | `Viper MkIII` | `Viper Mk III` |
|
|
78
|
+
| `CobraMkIII` | `Cobra MkIII` | `Cobra Mk III` |
|
|
79
|
+
| `Viper_MkIV` | `Viper MkIV` | `Viper Mk IV` |
|
|
80
|
+
| `CobraMkIV` | `Cobra MkIV` | `Cobra Mk IV` |
|
|
81
|
+
| `Krait_MkII` | `Krait MkII` | `Krait Mk II` |
|
|
82
|
+
| `Python_NX` | `Python MkII` | `Python Mk II` |
|
|
83
|
+
| `CobraMkV` | `Cobra MkV` | `Cobra Mk V` |
|
|
84
|
+
| `PantherMkII` | `Panther Clipper MkII` | `Panther Clipper Mk II` |
|
|
85
|
+
|
|
86
|
+
The same display-name corrections are propagated to the matching armour-module
|
|
87
|
+
`ship` foreign keys in `modules-core.jsonc`.
|
|
88
|
+
|
|
89
|
+
- **In-game hull-stat audit corrections.** Live game readings from Elite Dangerous
|
|
90
|
+
`4.4.0.3`, recorded 2026-08-14 UTC, govern the following registry disagreements and
|
|
91
|
+
omissions. Values are transcribed directly, subject only to the established numeric
|
|
92
|
+
precision described above.
|
|
93
|
+
|
|
94
|
+
| Field | Registry value → stored game value |
|
|
95
|
+
| --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
96
|
+
| `baseShieldStrength` | `Type7` 155→156 |
|
|
97
|
+
| `masslock` | `Orca` 16→15; `Cutter` 27→26; `Viper_MkIV` 7→8; `Asp_Scout` 8→9; `Mandalay` 11→12; `PantherMkII` 27→25; `LakonMiner` 16→15; `Explorer_NX` 19→21; `SmallCombat01_NX` 10→11; `MediumTransport01` absent→16 |
|
|
98
|
+
| `reserveFuelCapacity` | `Mandalay` 0.52→0.5; `PantherMkII` 1.16→1.11; `LakonMiner` 0.77→0.6; `SmallCombat01_NX` 0.57→0.61 |
|
|
99
|
+
| `heatCapacity` | `Dolphin` 165→245; `Python_NX` 316→260; `Type8` 226→236; `Mandalay` 250→245; `Corsair` 230→280; `PantherMkII` 250→329; `LakonMiner` 289→300; `Explorer_NX` 250→341; `SmallCombat01_NX` 237→263; `MediumTransport01` absent→279 |
|
|
100
|
+
| `heatDissipation` | `Python_NX` 52→52.05; `Type8` 36.5→36.45; `CobraMkV` 40.5→40.63; `Corsair` 52→52.05; `PantherMkII` 62.5→62.45; `LakonMiner` 52.15→52.05; `Explorer_NX` 72.1→71.93; `SmallCombat01_NX` 39.85→37.93; `MediumTransport01` absent→49.35 |
|
|
101
|
+
| `maximumSpeed` | `Type9_Military` 179→180; `TypeX_3` 204→200; `CobraMkV` 291→290; `PantherMkII` 181→180; `LakonMiner` 272→270; `SmallCombat01_NX` 271→270 |
|
|
102
|
+
| `boost` | `Type9_Military` 219→220; `CobraMkV` 412→410; `LakonMiner` 367→365 |
|
|
103
|
+
| `pitch` | `Type9_Military` 20→22; `Krait_MkII` 26→31; `TypeX` 39→38; `TypeX_3` 32→35; `Krait_Light` 26→31; `Mamba` 27→30; `Python_NX` 37.72→37; `CobraMkV` 45.61→45; `SmallCombat01_NX` 51.4→50 |
|
|
104
|
+
| `roll` | `Type9_Military` 20→40; `TypeX` 92→90; `Mamba` 80→75; `Python_NX` 92.76→91; `CobraMkV` 121.62→120; `SmallCombat01_NX` 123.36→120 |
|
|
105
|
+
| `yaw` | `Python_NX` 12.74→12.5; `CobraMkV` 33.45→33; `SmallCombat01_NX` 24.67→24 |
|
|
106
|
+
|
|
107
|
+
- **`heatDissipation` is the hull's audited maximum cooling rate.** Coriolis-data carries no
|
|
108
|
+
dissipation figure at all, and the game shows a player none: it is a community
|
|
109
|
+
measurement of Frontier's game rather than a stat the game displays. The baseline is
|
|
110
|
+
EDSY `eddb.js` `ship[…].heatdismax` from the pinned snapshot, joined by
|
|
111
|
+
case-insensitive `fdname` / `symbol`. A complete maintainer-supplied thermal audit
|
|
112
|
+
from Elite Dangerous `4.4.0.3`, recorded 2026-08-14 UTC, governs all 48 values and
|
|
113
|
+
supplies the nine corrections and omissions listed above. The other 39 values agree
|
|
114
|
+
with EDSY exactly.
|
|
115
|
+
Each value is the load in thermal-load units per second shed at heat level 1. The
|
|
116
|
+
stored catalogue range is Hauler `16.2` through Cutter `72.58`.
|
|
117
|
+
|
|
49
118
|
- **Slots derivation:** coriolis's fixed-order `slots.standard` seven-array becomes
|
|
50
119
|
the seven named `core` sizes (power plant, thrusters, frame shift drive, life
|
|
51
120
|
support, power distributor, sensors, fuel tank); `slots.hardpoints` splits into
|
|
@@ -223,17 +292,20 @@ slots are outside the hull layout.
|
|
|
223
292
|
Inara's ship page 68, read 2026-08-02 UTC, listing
|
|
224
293
|
1 Large Mining, 1 Medium, 2 Medium Mining, 3 Small and 1 Small Mining. The four
|
|
225
294
|
unrestricted mounts are exactly the `[2, 1, 1, 1]` the record already had.
|
|
226
|
-
- **Lynx Highliner (`MediumTransport01`) — from EDSY, Frontier's Lynx update notes
|
|
227
|
-
a Frontier journal capture:**
|
|
295
|
+
- **Lynx Highliner (`MediumTransport01`) — from EDSY, Frontier's Lynx update notes,
|
|
296
|
+
a Frontier journal capture and in-game verification:**
|
|
228
297
|
the Lynx has no coriolis hull entry, so its stats and slot layout are sourced instead
|
|
229
298
|
from EDSY's ship data and Frontier's Lynx update notes (hull mass 260 t, 285/350 m/s,
|
|
230
299
|
200/350 base shield/armour, hardness 55, 2 crew, rotation 26/60/19 deg/s, min thrust
|
|
231
300
|
73.75%; core PP5/thr6/FSD5/LS6/dist5/sen3/tank5; hardpoints 1 large + 4 medium;
|
|
232
301
|
4 utilities; unrestricted/passenger optionals 6/6/6/5/5/4/4/3/2/1; its five armour
|
|
233
302
|
options at 0/26/53/53/53 t, carried on the `MediumTransport01_Armour_*` module
|
|
234
|
-
records).
|
|
235
|
-
|
|
236
|
-
`heatCapacity`, `
|
|
303
|
+
records). EDSY independently gives the 23 deg/s zero-ENG-PIP pitch rate. A maintainer's
|
|
304
|
+
Elite Dangerous `4.4.0.3` game audit recorded 2026-08-14 UTC supplies `masslock: 16`,
|
|
305
|
+
`heatCapacity: 279`, `heatDissipation: 49.35`, the installed `minimumSpeed: 210` /
|
|
306
|
+
`maximumSpeed: 285` pair, and the complete angular endpoints `23/26` pitch, `60/60`
|
|
307
|
+
roll and `19/19` yaw. Values the static catalogue does not expose are omitted rather
|
|
308
|
+
than invented: acceleration and the boost-energy figures.
|
|
237
309
|
Its two size-6 and one size-5 passenger mounts carry `"restriction": "passenger"` and
|
|
238
310
|
the names `Passenger01`–`Passenger03`, sourced above. A final size-1
|
|
239
311
|
`planetaryApproachSuite` mount named `PlanetaryApproachSuite` comes directly from
|
|
@@ -603,7 +675,7 @@ account for 300 fields on 135 modules in addition to the Resource Siphon:
|
|
|
603
675
|
| Records | Fields | Stored in-game values |
|
|
604
676
|
| ----------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------- | ------------------------------------------------------------------ |
|
|
605
677
|
| `Int_Engine_Size4_Class{2,4}`, `Int_Hyperdrive_Size4_Class4` | thruster min/max mass; FSD optimal mass | 158/473, 193/578 and 438 t |
|
|
606
|
-
| `Int_Engine_Size{2,3}_Class5_Fast` | optimal/maximum multiplier
|
|
678
|
+
| `Int_Engine_Size{2,3}_Class5_Fast` | acceleration optimal/maximum multiplier | 1.1 / 1.2 on both |
|
|
607
679
|
| `Int_GuardianShieldReinforcement_Size{1..5}_Class{1,2}` | integrity | 36/42, 40/48, 45/55, 51/63, 58/72 |
|
|
608
680
|
| `Int_MetaAlloyHullReinforcement_Size{1..5}_Class{1,2}` | caustic resistance | 0.02 on all ten |
|
|
609
681
|
| shield generators | regeneration / broken regeneration | observed 1.06–5.76 values per symbol |
|
|
@@ -615,8 +687,11 @@ account for 300 fields on 135 modules in addition to the Resource Siphon:
|
|
|
615
687
|
| AX missiles, subsurface displacement missiles and seismic charge launchers | projectile boundary parameters; misleading ordinary ranges absent | ten records and 16 absences |
|
|
616
688
|
|
|
617
689
|
In-game verification gives the integer thruster/FSD masses, 1.1/1.2 enhanced-thruster
|
|
618
|
-
multipliers and the rising Guardian Shield Reinforcement integrity ladder.
|
|
619
|
-
|
|
690
|
+
acceleration multipliers and the rising Guardian Shield Reinforcement integrity ladder.
|
|
691
|
+
The enhanced thrusters additionally retain Coriolis's separately sourced 0.9/1.25/1.6
|
|
692
|
+
speed curve and 0.9/1.1/1.3 rotation curve; its mobility calculation applies those
|
|
693
|
+
curves instead of treating the outfitting panel's acceleration curve as all three.
|
|
694
|
+
These values take precedence over family-shaped inference and registry agreement.
|
|
620
695
|
|
|
621
696
|
**The two fixed Guardian Shard Cannons' damage is derived from a panel reading, not read
|
|
622
697
|
off one.** Individual outfitting panels observed **2026-08-10 UTC**, with grade-1
|
|
@@ -819,6 +894,31 @@ and bulkhead name because those records carry no symbol upstream.
|
|
|
819
894
|
restriction, so it is wrong on anything the game also sells for an ordinary
|
|
820
895
|
optional: a plain cargo rack fits a `cargo` mount _and_ every unrestricted one, and
|
|
821
896
|
does not carry it. The set of five is pinned, so widening it is a deliberate act.
|
|
897
|
+
- **`exclusionGroup`** carries EDSY's one-per-ship `limit` families, renamed from its
|
|
898
|
+
compact ids to stable descriptive values. EDSY has 17 one-per-ship source families;
|
|
899
|
+
the stored set covers 194 internal and utility records in 16 of them: shield
|
|
900
|
+
generators (standard, bi-weave and prismatic
|
|
901
|
+
share one group), fuel scoops, refineries, frame-shift-drive interdictors, Guardian
|
|
902
|
+
FSD boosters, vessel hangars, docking computers, supercruise assist, multi-limpet
|
|
903
|
+
controllers, the two scanner families, experimental module stabilisers, and the five
|
|
904
|
+
one-per-ship utility families. EDSY sets every one of those limits to `1`. EDSY's
|
|
905
|
+
three legacy discovery scanners are absent because they
|
|
906
|
+
are not current outfitting records; `Int_SupercruiseAssist` matches EDSY's
|
|
907
|
+
`Int_SuperCruiseAssist` case-insensitively, as Frontier symbols are matched elsewhere.
|
|
908
|
+
The three Mk I bundle-granted and all six Mk II Vessel Hangars are absent from the
|
|
909
|
+
baseline table; they join to the separately pinned Vessel Hangar snapshot, where all
|
|
910
|
+
nine carry the same `limit:'ifh'` as the ordinary Mk I records.
|
|
911
|
+
- **`limitGroup` / `limitIncrease` preserve EDSY's non-exclusive fitting limit.** All
|
|
912
|
+
33 current hardpoint records whose EDSY module carries `limit:'hex'` store
|
|
913
|
+
`limitGroup:'experimentalWeapon'`; the source's `eddb.limit.hex` is `4`. This is the
|
|
914
|
+
shared AX/Guardian experimental-weapon allowance, not a name-based classification:
|
|
915
|
+
the marked set is exactly the source set, including the Caustic Missile Rack and
|
|
916
|
+
excluding the two Guardian Nanite Torpedo Pylons, which EDSY does not limit. The
|
|
917
|
+
class-3 and class-5 Experimental Weapon Stabilisers carry EDSY's
|
|
918
|
+
`unlimit:'hex'` / `unlimitcount:1` and `2` as `limitIncrease`. EDSY's fitting logic
|
|
919
|
+
adds those increases to the base allowance and counts every fitted stabiliser; both
|
|
920
|
+
source records have effective `powerDraw:0`, so power state does not alter the
|
|
921
|
+
structural allowance.
|
|
822
922
|
- **Pre-engineered/duplicate drives share a `symbol`** in coriolis (e.g. the V1
|
|
823
923
|
FSDs); the first (primary) occurrence wins, and any baked engineering is expected
|
|
824
924
|
to arrive as SLEF `Engineering.Modifiers` instead.
|
package/README.md
CHANGED
|
@@ -24,7 +24,7 @@ Use a feature barrel when a bundler will tree-shake it:
|
|
|
24
24
|
import { ProceduralSystem } from '@elite-dangerous-almanac/core/astro';
|
|
25
25
|
```
|
|
26
26
|
|
|
27
|
-
There is no package-wide root entry; choose one of the
|
|
27
|
+
There is no package-wide root entry; choose one of the six feature areas or a leaf.
|
|
28
28
|
|
|
29
29
|
Use leaf subpaths to avoid evaluating unrelated data modules in native ESM:
|
|
30
30
|
|
|
@@ -36,11 +36,12 @@ import { ShipLoadout } from '@elite-dangerous-almanac/core/ships/ship-loadout';
|
|
|
36
36
|
The heavyweight module registries, planetary/combined nebula catalogues and codex-region
|
|
37
37
|
coordinate lookup are only exported from their leaf subpaths, not the feature barrels.
|
|
38
38
|
|
|
39
|
-
The package has
|
|
39
|
+
The package has six feature areas:
|
|
40
40
|
|
|
41
41
|
- `astro`: procedural names, id64 addresses, regions, nebulae and permit locks;
|
|
42
42
|
- `ships`: ships, modules, SLEF loadouts, engineering and build metrics;
|
|
43
43
|
- `equipment`: Odyssey suits, handheld weapons, grade upgrades and modifications;
|
|
44
|
+
- `i18n`: sparse localized module, blueprint and experimental-effect names;
|
|
44
45
|
- `materials`: ship engineering materials and Odyssey micro resources;
|
|
45
46
|
- `commodities`: standard and rare market goods.
|
|
46
47
|
|
|
@@ -92,7 +93,7 @@ build.toSlefString({
|
|
|
92
93
|
`ShipLoadout` imports every ship and module catalogue so it can resolve any build.
|
|
93
94
|
When only one calculation is required, use the data-free leaf modules under
|
|
94
95
|
`ships/jump-range`, `ships/power`, `ships/shields`, `ships/armour`, `ships/weapons`,
|
|
95
|
-
`ships/ammunition` or `ships/resistances`.
|
|
96
|
+
`ships/ammunition`, `ships/heat` or `ships/resistances`.
|
|
96
97
|
|
|
97
98
|
`build.validation` reports validity and operational completeness. Potentially incomplete
|
|
98
99
|
aggregates are nullable and have a diagnostic counterpart (`cargoCapacityResult`,
|
|
@@ -112,6 +113,21 @@ getCommodityByName('lavian brandy')?.rare; // -> true
|
|
|
112
113
|
getPersonalWeaponByName('Karma AR-50')?.grades['5'].damage; // -> 2.8
|
|
113
114
|
```
|
|
114
115
|
|
|
116
|
+
Localized game names live on their own subpath, so applications that use only English
|
|
117
|
+
do not bundle them. English names are complete; other locales return `null` where the
|
|
118
|
+
pinned sources carry no translation instead of silently substituting English:
|
|
119
|
+
|
|
120
|
+
```ts
|
|
121
|
+
import { getBlueprintName, getModuleName } from '@elite-dangerous-almanac/core/i18n';
|
|
122
|
+
|
|
123
|
+
getModuleName('Int_Hyperdrive_Size6_Class5', 'de-DE'); // -> "Frameshiftantrieb"
|
|
124
|
+
getBlueprintName('FSD_LongRange', 'fr-FR'); // -> "Portée FSD améliorée"
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
Unqualified `zh` selects the source's Simplified Chinese (`zh-CN`) module names.
|
|
128
|
+
Explicitly different Chinese scripts or regions such as `zh-TW` do not fall back to
|
|
129
|
+
Simplified Chinese and return `null` unless a matching source is added.
|
|
130
|
+
|
|
115
131
|
Registry lookups ignore case and surrounding whitespace. Material, commodity and
|
|
116
132
|
module lookups search their complete registry by default and accept an optional
|
|
117
133
|
catalogue to narrow the results. Nebula queries require an explicit catalogue so the
|
package/THIRD_PARTY_NOTICES.md
CHANGED
|
@@ -29,15 +29,30 @@ a verbatim copy produced at build time — edit this file, never the copy.
|
|
|
29
29
|
- **[EDCD/Coriolis](https://github.com/EDCD/coriolis)** — the Coriolis _application_, by
|
|
30
30
|
the **Coriolis contributors**, whose code is **MIT**-licensed. (Its data repository is a
|
|
31
31
|
separate credit, under Data below.) The **build-metric algorithms** are ported as fact
|
|
32
|
-
(our own implementation) from it: the power budget and its priority groups,
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
32
|
+
(our own implementation) from it: the power budget and its priority groups; loaded speed,
|
|
33
|
+
boost and rotation through the thruster-mass and ENG-pip curves; shield strength and its
|
|
34
|
+
mass curve; shield collapse delay, regeneration and SYS-capacitor recovery timing; armour
|
|
35
|
+
hit points; resistance stacking with its diminishing returns; and weapon DPS / capacitor
|
|
36
|
+
draw / heat. It credits the original Frontier-forum research the formulas come from.
|
|
37
|
+
- **The heat model** — the equilibrium heat level a thermal load settles at, how heat
|
|
38
|
+
moves towards it over time, and the multiplier a drained weapons capacitor puts on a
|
|
39
|
+
weapon's thermal load — is ported as fact from EDSY's `edsy.js`
|
|
40
|
+
(`getEquilibriumHeatLevel`, `getTimeUntilHeatLevel`, `getHeatLevelAtTime`,
|
|
41
|
+
`getEffectiveWeaponThermalLoad`, `updateUIStatsThm`), which credits the Frontier-forum
|
|
42
|
+
research thread
|
|
43
|
+
[Research: detailed heat mechanics](https://forums.frontier.co.uk/threads/research-detailed-heat-mechanics.286628/)
|
|
44
|
+
the mechanics were reverse-engineered in. Frontier publishes no heat formula and
|
|
45
|
+
coriolis-data models none, so the model is community reverse-engineering, and the
|
|
46
|
+
per-hull dissipation figures it reads (credited with EDSY's other data and the
|
|
47
|
+
running-game audits below) are community _measurements_ of the game rather than stats
|
|
48
|
+
the game displays. Both
|
|
49
|
+
describe Frontier's game and fall under the same Frontier notice as every other stat
|
|
50
|
+
here; what differs is how they were arrived at, not who owns them.
|
|
51
|
+
- **The jump-range and fuel algorithm**, **per-axis ENG-pip handling**, the **engineered
|
|
52
|
+
ammunition rounding** rule and the **build metrics above** are cross-checked against, or
|
|
53
|
+
ported as fact from, EDSY (credited under Data below). The jump-range model derives from
|
|
54
|
+
Frontier's "mass effect on hyperspace range" description; Coriolis carries the same maths
|
|
55
|
+
for the metrics, and a clip round-up that omits EDSY's burst step, where EDSY is followed.
|
|
41
56
|
- **Galactic codex region lookup** — resolving a region from galactic coordinates or from a
|
|
42
57
|
boxel, ported as fact (our own implementation) from `RegionMap.js` in
|
|
43
58
|
EliteDangerousRegionMap, whose region tables are credited under Data below.
|
|
@@ -61,8 +76,17 @@ a verbatim copy produced at build time — edit this file, never the copy.
|
|
|
61
76
|
`eddb.js` and `edsy.js`. Supplies the values coriolis-data leaves blank or carries
|
|
62
77
|
wrongly (module mass, integrity, power draw, boot time, the base stats engineering
|
|
63
78
|
recipes scale), the experimental-effect modifiers and their recipes, the module-group
|
|
64
|
-
engineering menus,
|
|
65
|
-
|
|
79
|
+
engineering menus, per-ship module-count limits and fitted stabiliser increases, the
|
|
80
|
+
baseline per-hull maximum heat dissipation, the
|
|
81
|
+
Lynx Highliner's hull/slot figures and zero-pip minimum pitch, the journal slot names,
|
|
82
|
+
localized module, blueprint and experimental-effect names, and the
|
|
83
|
+
attribute-to-journal-Label mapping. The values are Elite Dangerous game data — see the
|
|
84
|
+
Frontier notice below. Heat dissipation is the one entry the game never shows a player:
|
|
85
|
+
it is community measurement of Frontier's game, described under Algorithms above, and
|
|
86
|
+
carried here on the same terms as the rest.
|
|
87
|
+
- **[EDDI](https://github.com/EDCD/EDDI)** by the **EDDI contributors**, **Apache 2.0**
|
|
88
|
+
for its code — its module definitions and resource tables supply localized outfitting
|
|
89
|
+
names. The names are factual Elite Dangerous game data; no EDDI code is incorporated.
|
|
66
90
|
- **[Inara](https://inara.cz/)** — the blueprint and outfitting registries behind the
|
|
67
91
|
Operations pre-engineered blueprints and shop rows, the ship pages used to corroborate
|
|
68
92
|
hull layouts, and the component pages that grade the Thargoid caustic / Titan materials
|
|
@@ -92,8 +116,8 @@ a verbatim copy produced at build time — edit this file, never the copy.
|
|
|
92
116
|
**Jixxed**, **MIT** — supplies the personal suit and handheld-weapon identities, stats,
|
|
93
117
|
journal symbols, grade-upgrade recipes and engineer-applied modification recipes. A
|
|
94
118
|
CAPI response in its test resources also corroborates the six bundle-granted Vessel
|
|
95
|
-
Hangar variants. The values and response are factual Elite Dangerous game data. Its
|
|
96
|
-
|
|
119
|
+
Hangar variants. The values and response are factual Elite Dangerous game data. Its MIT
|
|
120
|
+
notice is reproduced below.
|
|
97
121
|
- **[msarilar/EDEngineer](https://github.com/msarilar/EDEngineer)**, **MIT** for its code
|
|
98
122
|
— its `blueprints.json` corroborates which weapons the Overcharged recipe gives a clip
|
|
99
123
|
penalty to. The values are game data.
|
|
@@ -160,6 +184,7 @@ derived and every manual correction are recorded with the data itself, in
|
|
|
160
184
|
[`data/astro/SOURCES.md`](https://github.com/DarkSession/Elite-Dangerous-Almanac/blob/main/data/astro/SOURCES.md),
|
|
161
185
|
[`data/materials/SOURCES.md`](https://github.com/DarkSession/Elite-Dangerous-Almanac/blob/main/data/materials/SOURCES.md),
|
|
162
186
|
[`data/equipment/SOURCES.md`](https://github.com/DarkSession/Elite-Dangerous-Almanac/blob/main/data/equipment/SOURCES.md),
|
|
187
|
+
[`data/i18n/SOURCES.md`](https://github.com/DarkSession/Elite-Dangerous-Almanac/blob/main/data/i18n/SOURCES.md),
|
|
163
188
|
[`data/ships/SOURCES.md`](https://github.com/DarkSession/Elite-Dangerous-Almanac/blob/main/data/ships/SOURCES.md)
|
|
164
189
|
and
|
|
165
190
|
[`data/commodities/SOURCES.md`](https://github.com/DarkSession/Elite-Dangerous-Almanac/blob/main/data/commodities/SOURCES.md),
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var requireFiniteNonNegative=(scope,name,value)=>{if(!Number.isFinite(value)||value<0){throw new RangeError(`${scope}: ${name} must be a finite non-negative number`)}};var requireFiniteRange=(scope,name,value,minimum,maximum)=>{if(!Number.isFinite(value)||value<minimum||value>maximum){throw new RangeError(`${scope}: ${name} must be a finite number from ${minimum} to ${maximum}`)}};var validateCurve=(scope,curve)=>{for(const field of["minMass","optMass","maxMass"]){requireFiniteNonNegative(scope,field,curve[field])}const allMassesEqual=curve.minMass===curve.optMass&&curve.optMass===curve.maxMass;if(!allMassesEqual&&!(curve.minMass<curve.optMass&&curve.optMass<curve.maxMass)){throw new RangeError(`${scope}: masses must be strictly ordered minMass < optMass < maxMass, or all equal`)}for(const field of["minMultiplier","optMultiplier","maxMultiplier"]){requireFiniteNonNegative(scope,field,curve[field])}const allMultipliersEqual=curve.minMultiplier===curve.optMultiplier&&curve.optMultiplier===curve.maxMultiplier;const strictlyOrderedMultipliers=curve.minMultiplier<curve.optMultiplier&&curve.optMultiplier<curve.maxMultiplier;if(!allMultipliersEqual&&!strictlyOrderedMultipliers){throw new RangeError(`${scope}: multipliers must be strictly ordered minMultiplier < optMultiplier < maxMultiplier, or all equal`)}if(allMassesEqual&&!allMultipliersEqual){throw new RangeError(`${scope}: an all-equal mass curve must have equal multipliers`)}};var curveMultiplier=(scope,mass,thrusters)=>{requireFiniteNonNegative(scope,"mass",mass);validateCurve(`${scope}: thrusters`,thrusters);if(mass>thrusters.maxMass)return 0;const span=thrusters.maxMass-thrusters.minMass;if(span<=0||thrusters.maxMultiplier===thrusters.minMultiplier){return thrusters.optMultiplier}const normalised=Math.max(0,Math.min(1,(thrusters.maxMass-mass)/span));const optNormalised=Math.min(1,(thrusters.maxMass-thrusters.optMass)/span);const exponent=Math.log((thrusters.optMultiplier-thrusters.minMultiplier)/(thrusters.maxMultiplier-thrusters.minMultiplier))/Math.log(optNormalised);if(!Number.isFinite(exponent)){throw new RangeError(`${scope}: curve values do not produce a finite exponent`)}return thrusters.minMultiplier+Math.pow(normalised,exponent)*(thrusters.maxMultiplier-thrusters.minMultiplier)};function thrusterMassCurveMultiplier(mass,thrusters){return curveMultiplier("thrusterMassCurveMultiplier",mass,thrusters)}function mobilityMetrics(input){const pips=input.enginesPips??4;requireFiniteRange("mobilityMetrics","enginesPips",pips,0,4);for(const field of["minimumSpeed","maximumSpeed","boost","pitch","roll","yaw","mass"]){requireFiniteNonNegative("mobilityMetrics",field,input[field])}if(input.minimumSpeed>input.maximumSpeed){throw new RangeError("mobilityMetrics: minimumSpeed must not exceed maximumSpeed")}for(const[minimum,maximum]of[["minPitch","pitch"],["minRoll","roll"],["minYaw","yaw"]]){requireFiniteRange("mobilityMetrics",minimum,input[minimum],0,input[maximum])}if(!input.thrusters)return null;validateCurve("mobilityMetrics: thrusters",input.thrusters);const massCurveMultiplier=curveMultiplier("mobilityMetrics: speed curve",input.mass,input.thrusters.speedCurve??input.thrusters);const rotationMassCurveMultiplier=curveMultiplier("mobilityMetrics: rotation curve",input.mass,input.thrusters.rotationCurve??input.thrusters);const pipMultiplier=pips/4;const speedAtPips=input.minimumSpeed+(input.maximumSpeed-input.minimumSpeed)*pipMultiplier;const handlingAtPips=(maximum,minimum)=>minimum+(maximum-minimum)*pipMultiplier;return{speed:speedAtPips*massCurveMultiplier,boost:input.boost*massCurveMultiplier,pitch:handlingAtPips(input.pitch,input.minPitch)*rotationMassCurveMultiplier,roll:handlingAtPips(input.roll,input.minRoll)*rotationMassCurveMultiplier,yaw:handlingAtPips(input.yaw,input.minYaw)*rotationMassCurveMultiplier,massCurveMultiplier:massCurveMultiplier,rotationMassCurveMultiplier:rotationMassCurveMultiplier}}export{mobilityMetrics,thrusterMassCurveMultiplier};//# sourceMappingURL=chunk-24INI4U7.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/ships/mobility.ts"],"names":["requireFiniteNonNegative","scope","name","value","Number","isFinite","RangeError","requireFiniteRange","minimum","maximum","validateCurve","curve","field","allMassesEqual","minMass","optMass","maxMass","allMultipliersEqual","minMultiplier","optMultiplier","maxMultiplier","strictlyOrderedMultipliers","curveMultiplier","mass","thrusters","span","normalised","Math","max","min","optNormalised","exponent","log","pow","thrusterMassCurveMultiplier","mobilityMetrics","input","pips","enginesPips","minimumSpeed","maximumSpeed","massCurveMultiplier","speedCurve","rotationMassCurveMultiplier","rotationCurve","pipMultiplier","speedAtPips","handlingAtPips","speed","boost","pitch","minPitch","roll","minRoll","yaw","minYaw"],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{buildModuleCatalogue}from"./chunk-E45EDCYH.js";var modules_utility_default=[{symbol:"Hpt_ChaffLauncher_Tiny",kind:"chaffLaunchers",name:"Chaff Launcher",class:0,rating:"I",mass:1.3,integrity:20,powerDraw:.2,bootTime:0,alwaysPowered:true,rateOfFire:1,burstInterval:1,clipSize:1,ammoMaximum:10,reloadTime:10,distributorDraw:4,thermalLoad:4,cost:8500},{symbol:"Hpt_ElectronicCountermeasure_Tiny",kind:"ecms",name:"Electronic Countermeasure",class:0,rating:"F",mass:1.3,integrity:20,powerDraw:.2,bootTime:0,reloadTime:10,thermalLoad:4,maximumRange:3e3,cost:12500},{symbol:"Hpt_HeatSinkLauncher_Turret_Tiny",kind:"heatSinkLaunchers",name:"Heat Sink Launcher",class:0,rating:"I",mass:1.3,integrity:45,powerDraw:.2,bootTime:0,alwaysPowered:true,rateOfFire:.2,burstInterval:5,clipSize:1,ammoMaximum:2,reloadTime:10,distributorDraw:2,cost:3500},{symbol:"Hpt_PlasmaPointDefence_Turret_Tiny",kind:"pointDefence",name:"Point Defence",class:0,rating:"I",mass:.5,integrity:30,powerDraw:.2,bootTime:0,alwaysPowered:true,damage:.2,damageDistribution:{kinetic:1},rateOfFire:10,burstInterval:.2,burstRounds:4,burstRateOfFire:15,clipSize:12,ammoMaximum:1e4,reloadTime:.4,thermalLoad:.07,maximumRange:2500,shotSpeed:1e3,jitter:1.5,cost:18550},{symbol:"Hpt_CargoScanner_Size0_Class1",kind:"manifestScanners",name:"Cargo Scanner",class:0,rating:"E",exclusionGroup:"cargoScanner",mass:1.3,integrity:32,powerDraw:.2,bootTime:3,scannerRange:2e3,scanAngle:15,scanTime:10,cost:13544},{symbol:"Hpt_CargoScanner_Size0_Class2",kind:"manifestScanners",name:"Cargo Scanner",class:0,rating:"D",exclusionGroup:"cargoScanner",mass:1.3,integrity:24,powerDraw:.4,bootTime:3,scannerRange:2500,scanAngle:15,scanTime:10,cost:40633},{symbol:"Hpt_CargoScanner_Size0_Class3",kind:"manifestScanners",name:"Cargo Scanner",class:0,rating:"C",exclusionGroup:"cargoScanner",mass:1.3,integrity:40,powerDraw:.8,bootTime:3,scannerRange:3e3,scanAngle:15,scanTime:10,cost:121899},{symbol:"Hpt_CargoScanner_Size0_Class4",kind:"manifestScanners",name:"Cargo Scanner",class:0,rating:"B",exclusionGroup:"cargoScanner",mass:1.3,integrity:56,powerDraw:1.6,bootTime:3,scannerRange:3500,scanAngle:15,scanTime:10,cost:365698},{symbol:"Hpt_CargoScanner_Size0_Class5",kind:"manifestScanners",name:"Cargo Scanner",class:0,rating:"A",exclusionGroup:"cargoScanner",mass:1.3,integrity:48,powerDraw:3.2,bootTime:3,scannerRange:4e3,scanAngle:15,scanTime:10,cost:1097095},{symbol:"Hpt_CloudScanner_Size0_Class1",kind:"wakeScanners",name:"Frame Shift Wake Scanner",class:0,rating:"E",exclusionGroup:"frameShiftWakeScanner",mass:1.3,integrity:32,powerDraw:.2,bootTime:1,scannerRange:2e3,scanAngle:15,scanTime:10,cost:13544},{symbol:"Hpt_CloudScanner_Size0_Class2",kind:"wakeScanners",name:"Frame Shift Wake Scanner",class:0,rating:"D",exclusionGroup:"frameShiftWakeScanner",mass:1.3,integrity:24,powerDraw:.4,bootTime:1,scannerRange:2500,scanAngle:15,scanTime:10,cost:40633},{symbol:"Hpt_CloudScanner_Size0_Class3",kind:"wakeScanners",name:"Frame Shift Wake Scanner",class:0,rating:"C",exclusionGroup:"frameShiftWakeScanner",mass:1.3,integrity:40,powerDraw:.8,bootTime:1,scannerRange:3e3,scanAngle:15,scanTime:10,cost:121899},{symbol:"Hpt_CloudScanner_Size0_Class4",kind:"wakeScanners",name:"Frame Shift Wake Scanner",class:0,rating:"B",exclusionGroup:"frameShiftWakeScanner",mass:1.3,integrity:56,powerDraw:1.6,bootTime:1,scannerRange:3500,scanAngle:15,scanTime:10,cost:365698},{symbol:"Hpt_CloudScanner_Size0_Class5",kind:"wakeScanners",name:"Frame Shift Wake Scanner",class:0,rating:"A",exclusionGroup:"frameShiftWakeScanner",mass:1.3,integrity:48,powerDraw:3.2,bootTime:1,scannerRange:4e3,scanAngle:15,scanTime:10,cost:1097095},{symbol:"Hpt_CrimeScanner_Size0_Class1",kind:"killWarrantScanners",name:"Kill Warrant Scanner",class:0,rating:"E",exclusionGroup:"killWarrantScanner",mass:1.3,integrity:32,powerDraw:.2,bootTime:2,scannerRange:2e3,scanAngle:15,scanTime:10,cost:13544},{symbol:"Hpt_CrimeScanner_Size0_Class2",kind:"killWarrantScanners",name:"Kill Warrant Scanner",class:0,rating:"D",exclusionGroup:"killWarrantScanner",mass:1.3,integrity:24,powerDraw:.4,bootTime:2,scannerRange:2500,scanAngle:15,scanTime:10,cost:40633},{symbol:"Hpt_CrimeScanner_Size0_Class3",kind:"killWarrantScanners",name:"Kill Warrant Scanner",class:0,rating:"C",exclusionGroup:"killWarrantScanner",mass:1.3,integrity:40,powerDraw:.8,bootTime:2,scannerRange:3e3,scanAngle:15,scanTime:10,cost:121899},{symbol:"Hpt_CrimeScanner_Size0_Class4",kind:"killWarrantScanners",name:"Kill Warrant Scanner",class:0,rating:"B",exclusionGroup:"killWarrantScanner",mass:1.3,integrity:56,powerDraw:1.6,bootTime:2,scannerRange:3500,scanAngle:15,scanTime:10,cost:365698},{symbol:"Hpt_CrimeScanner_Size0_Class5",kind:"killWarrantScanners",name:"Kill Warrant Scanner",class:0,rating:"A",exclusionGroup:"killWarrantScanner",mass:1.3,integrity:48,powerDraw:3.2,bootTime:2,scannerRange:4e3,scanAngle:15,scanTime:10,cost:1097095},{symbol:"Hpt_ShieldBooster_Size0_Class1",kind:"shieldBoosters",name:"Shield Booster",class:0,rating:"E",mass:.5,integrity:25,powerDraw:.2,bootTime:0,shieldBoost:.04,kineticResistance:0,thermalResistance:0,explosiveResistance:0,alwaysPowered:true,cost:1e4},{symbol:"Hpt_ShieldBooster_Size0_Class2",kind:"shieldBoosters",name:"Shield Booster",class:0,rating:"D",mass:1,integrity:35,powerDraw:.5,bootTime:0,shieldBoost:.08,kineticResistance:0,thermalResistance:0,explosiveResistance:0,alwaysPowered:true,cost:23e3},{symbol:"Hpt_ShieldBooster_Size0_Class3",kind:"shieldBoosters",name:"Shield Booster",class:0,rating:"C",mass:2,integrity:40,powerDraw:.7,bootTime:0,shieldBoost:.12,kineticResistance:0,thermalResistance:0,explosiveResistance:0,alwaysPowered:true,cost:53e3},{symbol:"Hpt_ShieldBooster_Size0_Class4",kind:"shieldBoosters",name:"Shield Booster",class:0,rating:"B",mass:3,integrity:45,powerDraw:1,bootTime:0,shieldBoost:.16,kineticResistance:0,thermalResistance:0,explosiveResistance:0,alwaysPowered:true,cost:122e3},{symbol:"Hpt_ShieldBooster_Size0_Class5",kind:"shieldBoosters",name:"Shield Booster",class:0,rating:"A",mass:3.5,integrity:48,powerDraw:1.2,bootTime:0,shieldBoost:.2,kineticResistance:0,thermalResistance:0,explosiveResistance:0,alwaysPowered:true,cost:281e3},{symbol:"Hpt_AntiUnknownShutdown_Tiny",name:"Shutdown Field Neutraliser",class:0,rating:"F",entitlement:"ELITE_HORIZONS_V_PLANETARY_LANDINGS",mass:1.3,integrity:35,powerDraw:.2,bootTime:0,alwaysPowered:true,maximumRange:3e3,cost:63e3},{symbol:"Hpt_XenoScanner_Basic_Tiny",name:"Xeno Scanner",class:0,rating:"E",exclusionGroup:"experimentalUtility",entitlement:"ELITE_HORIZONS_V_PLANETARY_LANDINGS",mass:1.3,integrity:56,powerDraw:.2,bootTime:2,scannerRange:500,scanAngle:23,scanTime:10,cost:365698},{symbol:"Hpt_XenoScannerMk2_Basic_Tiny",name:"Enhanced Xeno Scanner",class:0,rating:"C",exclusionGroup:"experimentalUtility",entitlement:"ELITE_HORIZONS_V_PLANETARY_LANDINGS",mass:1.3,integrity:56,powerDraw:.8,bootTime:2,scannerRange:2e3,scanAngle:23,scanTime:10,cost:745948},{symbol:"Hpt_MRAScanner_Size0_Class1",name:"Pulse Wave Analyser",class:0,rating:"E",exclusionGroup:"pulseWaveAnalyser",mass:1.3,integrity:32,powerDraw:.2,bootTime:3,scannerRange:12e3,scanAngle:15,scanTime:3,cost:13544},{symbol:"Hpt_MRAScanner_Size0_Class2",name:"Pulse Wave Analyser",class:0,rating:"D",exclusionGroup:"pulseWaveAnalyser",mass:1.3,integrity:24,powerDraw:.4,bootTime:3,scannerRange:15e3,scanAngle:15,scanTime:3,cost:40633},{symbol:"Hpt_MRAScanner_Size0_Class3",name:"Pulse Wave Analyser",class:0,rating:"C",exclusionGroup:"pulseWaveAnalyser",mass:1.3,integrity:40,powerDraw:.8,bootTime:3,scannerRange:18e3,scanAngle:15,scanTime:3,cost:121899},{symbol:"Hpt_MRAScanner_Size0_Class4",name:"Pulse Wave Analyser",class:0,rating:"B",exclusionGroup:"pulseWaveAnalyser",mass:1.3,integrity:56,powerDraw:1.6,bootTime:3,scannerRange:21e3,scanAngle:15,scanTime:3,cost:365698},{symbol:"Hpt_MRAScanner_Size0_Class5",name:"Pulse Wave Analyser",class:0,rating:"A",exclusionGroup:"pulseWaveAnalyser",mass:1.3,integrity:48,powerDraw:3.2,bootTime:3,scannerRange:24e3,scanAngle:15,scanTime:3,cost:1097095},{symbol:"Hpt_CausticSinkLauncher_Turret_Tiny",kind:"heatSinkLaunchers",name:"Caustic Sink Launcher",class:0,rating:"I",mass:1.7,integrity:45,powerDraw:.6,bootTime:0,alwaysPowered:true,rateOfFire:.2,burstInterval:5,clipSize:1,ammoMaximum:5,reloadTime:10,distributorDraw:2,cost:5e4},{symbol:"Hpt_AntiUnknownShutdown_Tiny_V2",name:"Thargoid Pulse Neutraliser",class:0,rating:"E",mass:3,integrity:70,powerDraw:.4,bootTime:0,alwaysPowered:true,maximumRange:0,cost:15e4},{symbol:"Hpt_XenoScanner_Advanced_Tiny",name:"Pulse Wave Xeno Scanner",class:0,rating:"C",exclusionGroup:"experimentalUtility",mass:3,integrity:100,powerDraw:1,bootTime:2,scannerRange:1e3,scanAngle:23,scanTime:10,cost:85e4}];var UTILITY_MODULES=buildModuleCatalogue(modules_utility_default,"utility");export{UTILITY_MODULES};//# sourceMappingURL=chunk-3IMWUYXJ.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/ships/modules-utility.ts"],"names":["buildModuleCatalogue","modules_utility_default","UTILITY_MODULES"],"mappings":"O,
|
|
1
|
+
{"version":3,"sources":["../src/ships/modules-utility.ts"],"names":["buildModuleCatalogue","modules_utility_default","UTILITY_MODULES"],"mappings":"O,8jRAqCO,IAAME,gBAA+CF,qBACxDC,wBACA,kBACJC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{calculateModuleLimits}from"./chunk-KPETDYQX.js";import{truncate}from"./chunk-B5TT26XE.js";function validateLoadout(input){const issues=[];const seen=/* @__PURE__ */new Map;for(const module of input.modules){const normalized=module.slot.toLowerCase();const previous=seen.get(normalized);if(previous!==void 0){issues.push({code:"duplicateSlot",severity:"error",slot:module.slot,symbol:module.symbol,params:{slot:module.slot,previousSlot:previous,symbol:module.symbol},message:`Slot ${truncate(module.slot)} occurs more than once (also ${truncate(previous)})`})}else{seen.set(normalized,module.slot)}}const exclusive=/* @__PURE__ */new Map;for(const module of input.modules){if(!module.exclusionGroup)continue;const previous=exclusive.get(module.exclusionGroup);if(previous){issues.push({code:"duplicateExclusiveModule",severity:"error",slot:module.slot,symbol:module.symbol,params:{exclusionGroup:module.exclusionGroup,slot:module.slot,symbol:module.symbol,previousSlot:previous.slot,previousSymbol:previous.symbol},message:`${truncate(module.slot)}: ${truncate(module.symbol)} conflicts with ${truncate(previous.symbol)} in ${truncate(previous.slot)} (${module.exclusionGroup} is limited to one per ship)`})}else{exclusive.set(module.exclusionGroup,module)}}for(const usage of calculateModuleLimits(input.modules)){if(usage.excess===0)continue;issues.push({code:"moduleLimitExceeded",severity:"error",params:{group:usage.group,count:usage.count,limit:usage.limit},message:`${usage.group} has ${usage.count} fitted modules but the ship allows ${usage.limit}`})}if(input.slots===null){issues.push({code:"unknownHull",severity:"incomplete",message:`No slot layout is known for hull ${truncate(input.shipSymbol)}`,params:{shipSymbol:input.shipSymbol}})}else{const knownSlots=new Map(input.slots.map(slot=>[slot.key.toLowerCase(),slot]));for(const module of input.modules){if(module.requiresKnownSlot!==false&&!knownSlots.has(module.slot.toLowerCase())){issues.push({code:"unknownSlot",severity:"error",slot:module.slot,symbol:module.symbol,message:`${truncate(module.slot)} is not a slot on ${truncate(input.shipSymbol)}`,params:{shipSymbol:input.shipSymbol,slot:module.slot,symbol:module.symbol}})}}for(const slot of input.slots){if((slot.kind==="core"||slot.kind==="armour")&&!seen.has(slot.key.toLowerCase())){issues.push({code:"missingRequiredSlot",severity:"incomplete",slot:slot.key,message:`${truncate(slot.key)} is required for an operational build`,params:{slot:slot.key}})}}}for(const module of input.modules){if(!module.known){issues.push({code:"unknownModule",severity:"incomplete",slot:module.slot,symbol:module.symbol,message:`${truncate(module.slot)}: ${truncate(module.symbol)} is not in the module catalogue`,params:{slot:module.slot,symbol:module.symbol}})}else if(module.fitError!==null){issues.push({code:"incompatibleModule",severity:"error",slot:module.slot,symbol:module.symbol,message:`${truncate(module.slot)}: ${truncate(module.symbol)} ${truncate(module.fitError)}`,params:{...module.fitParams,slot:module.slot,symbol:module.symbol,constraint:module.fitConstraint??"unknownConstraint"}})}}const frozen=Object.freeze(issues.map(issue=>Object.freeze({...issue,...issue.params?{params:Object.freeze(Object.fromEntries(Object.entries(issue.params).map(([key,value])=>[key,Array.isArray(value)?Object.freeze([...value]):value])))}:{}})));return Object.freeze({valid:!issues.some(issue=>issue.severity==="error"),complete:issues.length===0,issues:frozen})}export{validateLoadout};//# sourceMappingURL=chunk-5W43EQEQ.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/ships/loadout-validation.ts"],"names":["calculateModuleLimits","truncate","validateLoadout","input","issues","seen","Map","module","modules","normalized","slot","toLowerCase","previous","get","push","code","severity","symbol","params","previousSlot","message","set","exclusive","exclusionGroup","previousSymbol","usage","excess","group","count","limit","slots","shipSymbol","knownSlots","map","key","requiresKnownSlot","has","kind","known","fitError","fitParams","constraint","fitConstraint","frozen","Object","freeze","issue","fromEntries","entries","value","Array","isArray","valid","some","complete","length"],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{normalizeKey}from"./chunk-S4DBNX2B.js";import{truncate}from"./chunk-B5TT26XE.js";var SYNTHETIC_HEADER=Object.freeze({appName:"",appVersion:""});var isRecord=value=>typeof value==="object"&&value!==null&&!Array.isArray(value);var isOptionalString=value=>value===void 0||typeof value==="string";var isOptionalFiniteNumber=value=>value===void 0||typeof value==="number"&&Number.isFinite(value);var isOptionalNumberInRange=(value,minimum,maximum=Number.POSITIVE_INFINITY)=>value===void 0||typeof value==="number"&&Number.isFinite(value)&&value>=minimum&&value<=maximum;var isOptionalIntegerInRange=(value,minimum,maximum)=>{if(value===void 0)return true;return typeof value==="number"&&Number.isInteger(value)&&value>=minimum&&value<=maximum};var CONSTRAINT_MESSAGES={objectRequired:"must be an object",stringRequired:"must be a string",booleanRequired:"must be a boolean",arrayRequired:"must be an array",finiteNumberRequired:"must be a finite number",nonNegativeNumberRequired:"must be a non-negative number",priorityRange:"must be an integer from 0 to 4",engineeringLevelRange:"must be an integer from 1 to 5",unitInterval:"must be a number from 0 to 1",binaryInteger:"must be 0 or 1",versionRequired:"must be a string or finite number",loadoutEventRequired:'must be "Loadout"',validLoadoutRequired:"is not a valid Loadout event"};var invalid=(code,path,constraint)=>({code:code,path:path,constraint:constraint,reason:CONSTRAINT_MESSAGES[constraint]});function diagnoseEngineering(value,path){if(!isRecord(value))return invalid("invalidEngineering",path,"objectRequired");if(typeof value.BlueprintName!=="string")return invalid("invalidEngineering",`${path}.BlueprintName`,"stringRequired");if(!isOptionalIntegerInRange(value.Level,1,5)||value.Level===void 0)return invalid("invalidEngineering",`${path}.Level`,"engineeringLevelRange");if(!isOptionalNumberInRange(value.Quality,0,1)||value.Quality===void 0)return invalid("invalidEngineering",`${path}.Quality`,"unitInterval");if(!isOptionalString(value.ExperimentalEffect))return invalid("invalidEngineering",`${path}.ExperimentalEffect`,"stringRequired");if(!isOptionalString(value.ExperimentalEffect_Localised))return invalid("invalidEngineering",`${path}.ExperimentalEffect_Localised`,"stringRequired");if(value.Modifiers!==void 0){if(!Array.isArray(value.Modifiers))return invalid("invalidEngineering",`${path}.Modifiers`,"arrayRequired");for(let index=0;index<value.Modifiers.length;index+=1){const modifier=value.Modifiers[index];const modifierPath=`${path}.Modifiers[${index}]`;if(!isRecord(modifier))return invalid("invalidEngineering",modifierPath,"objectRequired");if(typeof modifier.Label!=="string")return invalid("invalidEngineering",`${modifierPath}.Label`,"stringRequired");if(!isOptionalFiniteNumber(modifier.Value))return invalid("invalidEngineering",`${modifierPath}.Value`,"finiteNumberRequired");if(!isOptionalFiniteNumber(modifier.OriginalValue))return invalid("invalidEngineering",`${modifierPath}.OriginalValue`,"finiteNumberRequired");if(!isOptionalString(modifier.ValueStr))return invalid("invalidEngineering",`${modifierPath}.ValueStr`,"stringRequired");if(!isOptionalIntegerInRange(modifier.LessIsGood,0,1))return invalid("invalidEngineering",`${modifierPath}.LessIsGood`,"binaryInteger")}}return null}function diagnoseModule(value,path){if(!isRecord(value))return invalid("invalidModule",path,"objectRequired");if(typeof value.Slot!=="string")return invalid("invalidModule",`${path}.Slot`,"stringRequired");if(typeof value.Item!=="string")return invalid("invalidModule",`${path}.Item`,"stringRequired");if(value.On!==void 0&&typeof value.On!=="boolean")return invalid("invalidModule",`${path}.On`,"booleanRequired");if(!isOptionalIntegerInRange(value.Priority,0,4))return invalid("invalidModule",`${path}.Priority`,"priorityRange");if(!isOptionalNumberInRange(value.Health,0,1))return invalid("invalidModule",`${path}.Health`,"unitInterval");if(!isOptionalNumberInRange(value.Value,0))return invalid("invalidModule",`${path}.Value`,"nonNegativeNumberRequired");if(value.Engineering!==void 0)return diagnoseEngineering(value.Engineering,`${path}.Engineering`);return null}function diagnoseHeader(value,path){if(!isRecord(value))return invalid("invalidHeader",path,"objectRequired");if(typeof value.appName!=="string")return invalid("invalidHeader",`${path}.appName`,"stringRequired");if(typeof value.appVersion!=="string"&&!(typeof value.appVersion==="number"&&Number.isFinite(value.appVersion)))return invalid("invalidHeader",`${path}.appVersion`,"versionRequired");if(!isOptionalString(value.appURL))return invalid("invalidHeader",`${path}.appURL`,"stringRequired");if(value.appCustomProperties!==void 0&&!isRecord(value.appCustomProperties))return invalid("invalidHeader",`${path}.appCustomProperties`,"objectRequired");return null}function diagnoseLoadout(value,path){if(!isRecord(value))return invalid("invalidLoadout",path,"objectRequired");if(typeof value.Ship!=="string")return invalid("invalidLoadout",`${path}.Ship`,"stringRequired");if(!Array.isArray(value.Modules))return invalid("invalidLoadout",`${path}.Modules`,"arrayRequired");if(value.event!==void 0&&value.event!=="Loadout")return invalid("invalidLoadout",`${path}.event`,"loadoutEventRequired");for(const field of["ShipName","ShipIdent"]){if(!isOptionalString(value[field]))return invalid("invalidLoadout",`${path}.${field}`,"stringRequired")}for(const field of["HullValue","ModulesValue","UnladenMass","CargoCapacity","MaxJumpRange","Rebuy"]){if(!isOptionalNumberInRange(value[field],0))return invalid("invalidLoadout",`${path}.${field}`,"nonNegativeNumberRequired")}if(value.FuelCapacity!==void 0){if(!isRecord(value.FuelCapacity))return invalid("invalidLoadout",`${path}.FuelCapacity`,"objectRequired");for(const field of["Main","Reserve"]){if(!isOptionalNumberInRange(value.FuelCapacity[field],0)||value.FuelCapacity[field]===void 0)return invalid("invalidLoadout",`${path}.FuelCapacity.${field}`,"nonNegativeNumberRequired")}}for(let index=0;index<value.Modules.length;index+=1){const moduleDiagnostic=diagnoseModule(value.Modules[index],`${path}.Modules[${index}]`);if(moduleDiagnostic!==null)return moduleDiagnostic}return null}function isSlefHeader(value){return diagnoseHeader(value,"header")===null}function isLoadout(value){return diagnoseLoadout(value,"loadout")===null}function duplicateSlot(loadout){const seen=/* @__PURE__ */new Set;for(let moduleIndex=0;moduleIndex<loadout.Modules.length;moduleIndex+=1){const module=loadout.Modules[moduleIndex];const slot=module.Slot.toLowerCase();if(seen.has(slot))return{slot:module.Slot,moduleIndex:moduleIndex};seen.add(slot)}return null}function inspectSlef(input){const root=typeof input==="string"?JSON.parse(input):input;const rawEntries=Array.isArray(root)?root:[root];const entries=[];const diagnostics=[];rawEntries.forEach((raw,index)=>{const entryPath=`entries[${index}]`;let header=null;let loadout=null;if(isLoadout(raw)){header=SYNTHETIC_HEADER;loadout=raw}else if(isRecord(raw)&&isLoadout(raw.data)){if(isSlefHeader(raw.header)){header=raw.header;loadout=raw.data}}if(header===null||loadout===null){const envelope=isRecord(raw)&&("header"in raw||"data"in raw);const detail=envelope?diagnoseHeader(isRecord(raw)?raw.header:null,`${entryPath}.header`)??diagnoseLoadout(isRecord(raw)?raw.data:null,`${entryPath}.data`):diagnoseLoadout(raw,entryPath);diagnostics.push({index:index,code:detail?.code??"invalidLoadout",path:detail?.path??entryPath,constraint:detail?.constraint??"validLoadoutRequired",message:`${detail?.path??entryPath} ${detail?.reason??"is not a valid Loadout event"}`,params:{path:detail?.path??entryPath,constraint:detail?.constraint??"validLoadoutRequired"}});return}const duplicate=duplicateSlot(loadout);if(duplicate!==null){diagnostics.push({index:index,code:"duplicateSlot",path:`${entryPath}${isLoadout(raw)?"":".data"}.Modules[${duplicate.moduleIndex}].Slot`,constraint:"uniqueSlot",message:`Entry ${index} contains duplicate slot "${truncate(duplicate.slot)}"`,params:{index:index,slot:duplicate.slot}});return}entries.push({header:header,data:loadout})});return Object.freeze({entries:Object.freeze(entries),diagnostics:Object.freeze(diagnostics.map(diagnostic=>Object.freeze({...diagnostic,...diagnostic.params?{params:Object.freeze({...diagnostic.params})}:{}})))})}function parseSlef(input){const inspected=inspectSlef(input);if(inspected.diagnostics.length>0){throw new TypeError(`parseSlef: ${inspected.diagnostics[0].message}`)}if(inspected.entries.length===0){throw new TypeError("parseSlef: input holds no entries")}return[...inspected.entries]}function toSlef(data,header){if(!isSlefHeader(header)){throw new TypeError("toSlef: header needs a string `appName` and an `appVersion`")}const events=Array.isArray(data)?data:[data];if(events.length===0){throw new TypeError("toSlef: needs at least one Loadout")}return events.map((event,index)=>{if(!isLoadout(event)){throw new TypeError(`toSlef: entry ${index} is not a valid Loadout (needs a \`Ship\` and \`Modules\`)`)}const duplicate=duplicateSlot(event);if(duplicate!==null){throw new TypeError(`toSlef: entry ${index} contains duplicate slot "${truncate(duplicate.slot)}"`)}return{header:header,data:event}})}function stringifySlef(slef,options={}){return JSON.stringify(slef,null,options.indent??0)}function getLoadoutModifier(module,label){const wanted=normalizeKey(label,"getLoadoutModifier: label");const mod=module.Engineering?.Modifiers?.find(m=>m.Label.toLowerCase()===wanted);return typeof mod?.Value==="number"?mod.Value:null}export{getLoadoutModifier,inspectSlef,parseSlef,stringifySlef,toSlef};//# sourceMappingURL=chunk-7MKYFCFF.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/ships/slef.ts"],"names":["normalizeKey","truncate","SYNTHETIC_HEADER","Object","freeze","appName","appVersion","isRecord","value","Array","isArray","isOptionalString","isOptionalFiniteNumber","Number","isFinite","isOptionalNumberInRange","minimum","maximum","POSITIVE_INFINITY","isOptionalIntegerInRange","isInteger","CONSTRAINT_MESSAGES","objectRequired","stringRequired","booleanRequired","arrayRequired","finiteNumberRequired","nonNegativeNumberRequired","priorityRange","engineeringLevelRange","unitInterval","binaryInteger","versionRequired","loadoutEventRequired","validLoadoutRequired","invalid","code","path","constraint","reason","diagnoseEngineering","BlueprintName","Level","Quality","ExperimentalEffect","ExperimentalEffect_Localised","Modifiers","index","length","modifier","modifierPath","Label","Value","OriginalValue","ValueStr","LessIsGood","diagnoseModule","Slot","Item","On","Priority","Health","Engineering","diagnoseHeader","appURL","appCustomProperties","diagnoseLoadout","Ship","Modules","event","field","FuelCapacity","moduleDiagnostic","isSlefHeader","isLoadout","duplicateSlot","loadout","seen","Set","moduleIndex","module","slot","toLowerCase","has","add","inspectSlef","input","root","JSON","parse","rawEntries","entries","diagnostics","forEach","raw","entryPath","header","data","envelope","detail","push","message","params","duplicate","map","diagnostic","parseSlef","inspected","TypeError","toSlef","events","stringifySlef","slef","options","stringify","indent","getLoadoutModifier","label","wanted","mod","find","m"],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var phaseTime=(megajoules,rate,draw,capacity,recharge)=>{if(megajoules<=0)return 0;if(rate<=0)return Infinity;if(draw<=0)return megajoules/rate;const drain=rate*draw-recharge;if(drain<=0)return megajoules/rate;const capacitorLifetime=capacity/drain;const beforeEmpty=capacitorLifetime*rate;if(megajoules<=beforeEmpty)return megajoules/rate;if(recharge<=0)return Infinity;return capacitorLifetime+(megajoules-beforeEmpty)/(recharge/draw)};var requireFiniteNonNegative=(name,value)=>{if(!Number.isFinite(value)||value<0){throw new RangeError(`shieldRecovery: ${name} must be a finite non-negative number`)}};function shieldRecovery(input){const pips=input.systemsPips??4;if(!Number.isFinite(pips)||pips<0||pips>4){throw new RangeError("shieldRecovery: systemsPips must be a finite number from 0 to 4")}for(const field of["strength","regenRate","brokenRegenRate","distributorDraw","systemsCapacity","systemsRecharge"]){requireFiniteNonNegative(field,input[field])}const recharge=input.systemsRecharge*Math.pow(pips/4,1.1);const half=input.strength/2;return{regenRate:input.regenRate,brokenRegenRate:input.brokenRegenRate,recoveryTime:16+phaseTime(half,input.brokenRegenRate,input.distributorDraw,input.systemsCapacity,recharge),regenTime:phaseTime(half,input.regenRate,input.distributorDraw,input.systemsCapacity,recharge)}}function cellBankSummary(banks){const metrics=banks.map(bank=>Object.freeze({slot:bank.slot,symbol:bank.symbol,reinforcement:bank.reinforcementRate*bank.duration,cells:bank.cells,spinUp:bank.spinUp,duration:bank.duration,heat:bank.heat}));return Object.freeze({banks:Object.freeze(metrics),totalRestorable:metrics.reduce((sum,bank)=>sum+bank.reinforcement*bank.cells,0),totalCells:metrics.reduce((sum,bank)=>sum+bank.cells,0)})}export{cellBankSummary,shieldRecovery};//# sourceMappingURL=chunk-BUV3MXGK.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/ships/shield-recovery.ts"],"names":["phaseTime","megajoules","rate","draw","capacity","recharge","Infinity","drain","capacitorLifetime","beforeEmpty","requireFiniteNonNegative","name","value","Number","isFinite","RangeError","shieldRecovery","input","pips","systemsPips","field","systemsRecharge","Math","pow","half","strength","regenRate","brokenRegenRate","recoveryTime","distributorDraw","systemsCapacity","regenTime","cellBankSummary","banks","metrics","map","bank","Object","freeze","slot","symbol","reinforcement","reinforcementRate","duration","cells","spinUp","heat","totalRestorable","reduce","sum","totalCells"],"mappings":"AAsFA,IAAMA,UAAY,CACdC,WACAC,KACAC,KACAC,SACAC,YAEA,GAAIJ,YAAc,EAAG,OAAO,EAC5B,GAAIC,MAAQ,EAAG,OAAOI,SACtB,GAAIH,MAAQ,EAAG,OAAOF,WAAaC,KACnC,MAAMK,MAAQL,KAAOC,KAAOE,SAC5B,GAAIE,OAAS,EAAG,OAAON,WAAaC,KACpC,MAAMM,kBAAoBJ,SAAWG,MACrC,MAAME,YAAcD,kBAAoBN,KACxC,GAAID,YAAcQ,YAAa,OAAOR,WAAaC,KACnD,GAAIG,UAAY,EAAG,OAAOC,SAC1B,OAAOE,mBAAqBP,WAAaQ,cAAgBJ,SAAWF,OAGxE,IAAMO,yBAA2B,CAACC,KAAcC,SAC5C,IAAKC,OAAOC,SAASF,QAAUA,MAAQ,EAAG,CACtC,MAAM,IAAIG,WAAW,mBAAmBJ,4CAC5C,GAoBG,SAASK,eAAeC,OAC3B,MAAMC,KAAOD,MAAME,aAAe,EAClC,IAAKN,OAAOC,SAASI,OAASA,KAAO,GAAKA,KAAO,EAAG,CAChD,MAAM,IAAIH,WAAW,kEACzB,CACA,IAAA,MAAWK,QAAS,CAChB,WACA,YACA,kBACA,kBACA,kBACA,mBACQ,CACRV,yBAAyBU,MAAOH,MAAMG,OAC1C,CACA,MAAMf,SAAWY,MAAMI,gBAAkBC,KAAKC,IAAIL,KAAO,EAAG,KAC5D,MAAMM,KAAOP,MAAMQ,SAAW,EAC9B,MAAO,CACHC,UAAWT,MAAMS,UACjBC,gBAAiBV,MAAMU,gBACvBC,aACI,GACA5B,UACIwB,KACAP,MAAMU,gBACNV,MAAMY,gBACNZ,MAAMa,gBACNzB,UAER0B,UAAW/B,UACPwB,KACAP,MAAMS,UACNT,MAAMY,gBACNZ,MAAMa,gBACNzB,UAGZ,CAiBO,SAAS2B,gBAAgBC,OAC5B,MAAMC,QAAUD,MAAME,IAAKC,MACvBC,OAAOC,OAAO,CACVC,KAAMH,KAAKG,KACXC,OAAQJ,KAAKI,OACbC,cAAeL,KAAKM,kBAAoBN,KAAKO,SAC7CC,MAAOR,KAAKQ,MACZC,OAAQT,KAAKS,OACbF,SAAUP,KAAKO,SACfG,KAAMV,KAAKU,QAGnB,OAAOT,OAAOC,OAAO,CACjBL,MAAOI,OAAOC,OAAOJ,SACrBa,gBAAiBb,QAAQc,OAAO,CAACC,IAAKb,OAASa,IAAMb,KAAKK,cAAgBL,KAAKQ,MAAO,GACtFM,WAAYhB,QAAQc,OAAO,CAACC,IAAKb,OAASa,IAAMb,KAAKQ,MAAO,IAEpE,QAAAZ,gBAAAhB"}
|