@elite-dangerous-almanac/core 0.2.14 → 0.2.15

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.
Files changed (108) hide show
  1. package/PROVENANCE/galaxy-map/SOURCES.md +8 -6
  2. package/PROVENANCE/i18n/SOURCES.md +9 -11
  3. package/PROVENANCE/ships/SOURCES.md +17 -15
  4. package/README.md +20 -7
  5. package/THIRD_PARTY_NOTICES.md +11 -9
  6. package/assets/galaxy-map/bookmark.svg +5 -0
  7. package/assets/galaxy-map/community-goal.svg +12 -0
  8. package/assets/galaxy-map/conflict-zone.svg +15 -0
  9. package/assets/galaxy-map/destination.svg +13 -0
  10. package/assets/galaxy-map/engineer.svg +6 -0
  11. package/assets/galaxy-map/fleet-carrier.svg +5 -0
  12. package/assets/galaxy-map/front-line.svg +10 -0
  13. package/assets/galaxy-map/mission.svg +15 -0
  14. package/assets/galaxy-map/squadron-carrier.svg +10 -0
  15. package/assets/galaxy-map/starter-zone.svg +20 -0
  16. package/assets/galaxy-map/station-abandoned.svg +6 -0
  17. package/assets/galaxy-map/station-damaged.svg +19 -0
  18. package/assets/galaxy-map/station-repairing.svg +7 -0
  19. package/assets/galaxy-map/station-under-attack.svg +21 -0
  20. package/assets/galaxy-map/titan.svg +18 -0
  21. package/assets/galaxy-map/waypoint.svg +5 -0
  22. package/dist/astro/body-orbit.d.ts +1 -1
  23. package/dist/astro/body-physics.d.ts +1 -1
  24. package/dist/astro/body-rings.d.ts +1 -1
  25. package/dist/astro/codex-region-lookup.d.ts +2 -2
  26. package/dist/astro/codex-region.d.ts +1 -1
  27. package/dist/astro/hand-authored-regions.d.ts +2 -2
  28. package/dist/astro/index.d.ts +1 -1
  29. package/dist/astro/naming-region-origins.d.ts +1 -1
  30. package/dist/astro/nebulae-all.d.ts +1 -1
  31. package/dist/astro/nebulae-planetary.d.ts +1 -1
  32. package/dist/astro/nebulae-procgen.d.ts +1 -1
  33. package/dist/astro/nebulae-real.d.ts +1 -1
  34. package/dist/astro/nebulae.d.ts +1 -1
  35. package/dist/astro/permit-locked-systems.d.ts +1 -1
  36. package/dist/astro/permit-locks.d.ts +1 -1
  37. package/dist/astro/sector-name.d.ts +1 -1
  38. package/dist/astro/star-physics.d.ts +1 -1
  39. package/dist/astro/system-address.d.ts +1 -1
  40. package/dist/{chunk-EXHZ4CFB.js → chunk-EE25IDB7.js} +1 -1
  41. package/dist/{chunk-EXHZ4CFB.js.map → chunk-EE25IDB7.js.map} +1 -1
  42. package/dist/{chunk-RA4YJBU5.js → chunk-F53MPXZY.js} +1 -1
  43. package/dist/{chunk-RA4YJBU5.js.map → chunk-F53MPXZY.js.map} +1 -1
  44. package/dist/{chunk-P5SIDTV5.js → chunk-JQ4OPZZ4.js} +1 -1
  45. package/dist/{chunk-P5SIDTV5.js.map → chunk-JQ4OPZZ4.js.map} +1 -1
  46. package/dist/{chunk-QNHGTVMZ.js → chunk-LLLFK3D5.js} +1 -1
  47. package/dist/{chunk-S4BZ64WE.js → chunk-N4YDIODB.js} +1 -1
  48. package/dist/{chunk-XCLOOKC2.js → chunk-U4MML7U6.js} +1 -1
  49. package/dist/commodities/commodities-rare.d.ts +1 -1
  50. package/dist/commodities/commodities-standard.d.ts +1 -1
  51. package/dist/equipment/modifications.d.ts +1 -1
  52. package/dist/galaxy-map/index.d.ts +9 -2
  53. package/dist/galaxy-map/markers.d.ts +1 -1
  54. package/dist/i18n/index.d.ts +1 -1
  55. package/dist/i18n/index.js +1 -1
  56. package/dist/i18n/module-families.d.ts +3 -3
  57. package/dist/i18n/suits.d.ts +1 -2
  58. package/dist/i18n/suits.js +1 -1
  59. package/dist/materials/materials-encoded.d.ts +1 -1
  60. package/dist/materials/materials-manufactured.d.ts +1 -1
  61. package/dist/materials/materials-raw.d.ts +1 -1
  62. package/dist/materials/materials.d.ts +1 -1
  63. package/dist/materials/micro-resources-component.d.ts +1 -1
  64. package/dist/materials/micro-resources-consumable.d.ts +1 -1
  65. package/dist/materials/micro-resources-data.d.ts +1 -1
  66. package/dist/materials/micro-resources-item.d.ts +1 -1
  67. package/dist/materials/micro-resources.d.ts +1 -1
  68. package/dist/ships/armour.d.ts +1 -1
  69. package/dist/ships/blueprint-costs.d.ts +1 -1
  70. package/dist/ships/blueprint-journal.d.ts +1 -1
  71. package/dist/ships/blueprints.d.ts +1 -1
  72. package/dist/ships/build-metrics.js +1 -1
  73. package/dist/ships/default-loadouts.d.ts +1 -1
  74. package/dist/ships/distributor.d.ts +1 -1
  75. package/dist/ships/engineering.d.ts +1 -1
  76. package/dist/ships/experimental-effect-costs.d.ts +1 -1
  77. package/dist/ships/experimental-effects.d.ts +1 -1
  78. package/dist/ships/gunsights.d.ts +1 -1
  79. package/dist/ships/heat.d.ts +2 -2
  80. package/dist/ships/index.d.ts +1 -1
  81. package/dist/ships/index.js +1 -1
  82. package/dist/ships/jump-range.d.ts +1 -1
  83. package/dist/ships/mobility-capacitor.d.ts +1 -1
  84. package/dist/ships/mobility.d.ts +1 -1
  85. package/dist/ships/module-limits.d.ts +2 -2
  86. package/dist/ships/modules-all.d.ts +1 -1
  87. package/dist/ships/modules-core.d.ts +1 -1
  88. package/dist/ships/modules-hardpoint.d.ts +1 -1
  89. package/dist/ships/modules-internal.d.ts +1 -1
  90. package/dist/ships/modules-utility.d.ts +1 -1
  91. package/dist/ships/modules.d.ts +1 -1
  92. package/dist/ships/power.d.ts +1 -1
  93. package/dist/ships/pre-engineered-stats.js +1 -1
  94. package/dist/ships/pre-engineered.d.ts +0 -5
  95. package/dist/ships/pre-engineered.js +1 -1
  96. package/dist/ships/resistances.d.ts +1 -1
  97. package/dist/ships/shield-capacitor.d.ts +1 -1
  98. package/dist/ships/shield-recovery.d.ts +2 -2
  99. package/dist/ships/shields.d.ts +1 -1
  100. package/dist/ships/ship-loadout.js +1 -1
  101. package/dist/ships/ships.d.ts +1 -1
  102. package/dist/ships/weapons-capacitor.d.ts +1 -1
  103. package/dist/ships/weapons.d.ts +1 -1
  104. package/dist/{system-address-DmzXRD48.d.ts → system-address-CveshmDX.d.ts} +2 -2
  105. package/package.json +4 -4
  106. /package/dist/{chunk-QNHGTVMZ.js.map → chunk-LLLFK3D5.js.map} +0 -0
  107. /package/dist/{chunk-S4BZ64WE.js.map → chunk-N4YDIODB.js.map} +0 -0
  108. /package/dist/{chunk-XCLOOKC2.js.map → chunk-U4MML7U6.js.map} +0 -0
@@ -1 +1 @@
1
- import{weaponMetrics}from"./chunk-Z266X4JF.js";import{shieldMetrics}from"./chunk-SRPCHXW2.js";import{getShipBySymbol,getShipByName,getShipSlots}from"./chunk-C4FUV6GF.js";import{getLoadoutModifier}from"./chunk-T4MKUKYS.js";import{sourcePurchaseFromLoadout}from"./chunk-NIURLW2F.js";import{isBuiltInHullSymbol,identifyPreEngineeredVariant,unrollableFixedArticle,cloneLoadoutModule,isNonOutfittingSlot,isBuiltInHullModule,matchingKeyIn,ownKeyIn,getPreEngineeredStats,getPreEngineeredModifiers,cloneModuleStats,isFinalGuardianWeaponEngineering,scaleDamageComponents}from"./chunk-QNHGTVMZ.js";import{builtInModuleBySymbol,getBulkheadsForShip}from"./chunk-FMPHK3L5.js";import{getPreEngineeredVariants}from"./chunk-EXHZ4CFB.js";import{CORE_MODULES}from"./chunk-ZZTDEDXJ.js";import{getExperimentalEffect}from"./chunk-77I24V6B.js";import{stockedMountKind}from"./chunk-M6J7KP7G.js";import{getDefaultLoadout}from"./chunk-KY7KSPU6.js";import{fieldForLabel,scaleForLabel,labelsForField,capabilityValueForLabel,damageTypeForLabel}from"./chunk-U73MBQ45.js";import{BURST_PATTERN_LABELS,journalRateOfFire,preciseValueFor}from"./chunk-EFQOUATZ.js";import{ammunitionCapacity}from"./chunk-AA3K5XUE.js";import{parseSlotName,SLOT_RESTRICTION_LABELS,enumerateSlots}from"./chunk-RAO35XDF.js";import{normalizeKey}from"./chunk-BKWLI44T.js";import{truncate,requireString,describeValue,requireStringIfPresent}from"./chunk-PKWVG2JY.js";import{deepFreeze}from"./chunk-DURKO7JU.js";var MILITARY_PREFIXES=["int_hullreinforcement","int_metaalloyhullreinforcement","int_modulereinforcement","int_shieldcellbank","int_guardianhullreinforcement","int_guardianmodulereinforcement","int_guardianshieldreinforcement"];var MINING_PREFIXES=["hpt_mininglaser","hpt_mining_abrblstr","hpt_mining_seismchrgwarhd","hpt_mining_subsurfdispmisle","hpt_human_extraction","hpt_miningtoolv2"];var CARGO_PREFIXES=["int_cargorack","int_largecargorack","int_corrosionproofcargorack","int_fueltank"];var RESTRICTED_SLOT_PREFIXES={mining:MINING_PREFIXES,military:MILITARY_PREFIXES,cargo:CARGO_PREFIXES,limpetController:["int_dronecontrol","int_multidronecontrol"],vesselHangar:["int_fighterbay","int_largebuggybay","int_mkiilargebuggybay"],passenger:["int_passengercabin","int_mkii_passengercabin"],planetaryApproachSuite:["int_planetapproachsuite"]};var problem=(constraint,message,params)=>({constraint:constraint,message:message,...params===void 0?{}:{params:params}});function restrictionProblem(slot,symbol){const restriction=slot.restriction;if(!restriction)return null;if(RESTRICTED_SLOT_PREFIXES[restriction].some(prefix=>symbol.startsWith(prefix))){return null}return problem("restrictedMount",`slot only takes ${SLOT_RESTRICTION_LABELS[restriction]}`,{restriction:restriction})}function moduleSlotProblem(slot,module){const required=module.restrictedToSlot;if(!required||slot.restriction===required)return null;return problem("restrictedMount",`module only fits a mount that takes ${SLOT_RESTRICTION_LABELS[required]}`,{restriction:required})}function moduleFitProblem(shipSymbol,slot,module){if(slot.kind==="cargoHatch"){return problem("immutableSlot","the cargoHatch slot cannot be changed")}if(isBuiltInHullSymbol(module.symbol)){return problem("builtInHullModule","the cargo hatch is part of the hull, not an outfitting module")}if(slot.kind==="armour"){const hull=getShipBySymbol(shipSymbol);if(module.slot!=="armour"||module.ship===void 0){return problem("armourRequired","not a ship armour module")}if(!hull||module.ship.toLowerCase()!==hull.name.toLowerCase()){const armourHull=getShipByName(module.ship);return problem("wrongHullArmour",`armour belongs to ${truncate(module.ship)}, not ${truncate(hull?.name??shipSymbol)}`,{armourShipName:module.ship,...armourHull===null?{}:{armourShipSymbol:armourHull.symbol},shipSymbol:shipSymbol,...hull===null?{}:{shipName:hull.name}})}return null}const restricted=module.restrictedToShips;if(restricted&&!restricted.some(symbol2=>symbol2.toLowerCase()===shipSymbol.toLowerCase())){const allowedShipNames=restricted.map(symbol2=>{const hull=getShipBySymbol(symbol2);return hull?.name??symbol2});const labels=restricted.map((symbol2,index)=>{const name=allowedShipNames[index];return name===symbol2?symbol2:`${name} (${symbol2})`});return problem("restrictedHull",`module is restricted to ${truncate(labels.join(", "))}`,{allowedShipNames:allowedShipNames,allowedShipSymbols:[...restricted],shipSymbol:shipSymbol})}const wrongMount=moduleSlotProblem(slot,module);if(wrongMount)return wrongMount;const symbol=module.symbol.toLowerCase();const moduleSlot=module.slot;switch(slot.kind){case"core":if(moduleSlot!==slot.core){return problem("wrongCoreType",`not a ${slot.core} module`,{requiredCore:slot.core,moduleSlot:moduleSlot??"none"})}break;case"hardpoint":{if(module.category!=="hardpoint"){return problem("hardpointRequired","not a hardpoint weapon")}const restricted2=restrictionProblem(slot,symbol);if(restricted2)return restricted2;break}case"utility":if(module.category!=="utility"){return problem("utilityRequired","not a utility module")}return null;case"optional":{const isFuelTank=moduleSlot==="fuelTank";if(module.category!=="internal"&&!isFuelTank){return problem("optionalInternalRequired","not an optional-internal module")}if(moduleSlot&&!isFuelTank){return problem("coreModuleInOptionalSlot","a core module only fits its core slot")}const restricted2=restrictionProblem(slot,symbol);if(restricted2)return restricted2;break}}if(module.class>slot.size){return problem("oversized",`module size ${truncate(module.class)} exceeds slot size ${slot.size}`,{moduleClass:module.class,slotSize:slot.size})}if(module.supercruiseOvercharge===true&&module.class<slot.size){return problem("exactSizeRequired",`an SCO drive fits a size ${truncate(module.class)} mount only, not size ${slot.size}`,{moduleClass:module.class,slotSize:slot.size})}return null}function moduleFitError(shipSymbol,slot,module){return moduleFitProblem(shipSymbol,slot,module)?.message??null}function preEngineeredVariantFor(module){return identifyPreEngineeredVariant(module)??(module.Engineering?unrollableFixedArticle(module.Item,module.Engineering):null)}function captureLoadoutEvent(event){const modules=event.Modules;const shipName=event.ShipName;const shipIdent=event.ShipIdent;const hullValue=event.HullValue;const modulesValue=event.ModulesValue;const rebuy=event.Rebuy;const unladenMass=event.UnladenMass;const cargoCapacity=event.CargoCapacity;const fuelCapacity=event.FuelCapacity;return{Ship:event.Ship,Modules:Array.isArray(modules)?captureEach(modules,captureModule):modules,...shipName===void 0?{}:{ShipName:shipName},...shipIdent===void 0?{}:{ShipIdent:shipIdent},...hullValue===void 0?{}:{HullValue:hullValue},...modulesValue===void 0?{}:{ModulesValue:modulesValue},...rebuy===void 0?{}:{Rebuy:rebuy},...unladenMass===void 0?{}:{UnladenMass:unladenMass},...cargoCapacity===void 0?{}:{CargoCapacity:cargoCapacity},...fuelCapacity===void 0?{}:{FuelCapacity:{...fuelCapacity}}}}function captureEach(values,capture){const captured=[];const{length:length}=values;for(let index=0;index<length;index++)captured.push(capture(values[index]));return captured}function captureModule(module){if(module===null||typeof module!=="object")return module;const on=module.On;const priority=module.Priority;const health=module.Health;const value=module.Value;const engineering=module.Engineering;return{Slot:module.Slot,Item:module.Item,...on===void 0?{}:{On:on},...priority===void 0?{}:{Priority:priority},...health===void 0?{}:{Health:health},...value===void 0?{}:{Value:value},...engineering===void 0?{}:{Engineering:captureEngineering(engineering)}}}function captureEngineering(engineering){if(engineering===null||typeof engineering!=="object")return engineering;const experimental=engineering.ExperimentalEffect;const experimentalLocalised=engineering.ExperimentalEffect_Localised;const modifiers=engineering.Modifiers;return{BlueprintName:engineering.BlueprintName,Level:engineering.Level,Quality:engineering.Quality,...experimental===void 0?{}:{ExperimentalEffect:experimental},...experimentalLocalised===void 0?{}:{ExperimentalEffect_Localised:experimentalLocalised},...modifiers===void 0?{}:{Modifiers:Array.isArray(modifiers)?captureEach(modifiers,modifier=>modifier!==null&&typeof modifier==="object"?{...modifier}:modifier):modifiers}}}function hullLayout(shipSymbol){const slots=getShipSlots(shipSymbol);return slots?enumerateSlots(slots):[]}function stockedMountRejects(shipSymbol,layout,slot,stats){const mount=layout.find(candidate=>candidate.key.toLowerCase()===slot.toLowerCase());return mount!==void 0&&moduleFitProblem(shipSymbol,mount,stats)!==null}function normalizeLoadoutEvent(rawEvent){const event=captureLoadoutEvent(rawEvent);requireString(event.Ship,"ShipLoadout.fromLoadout: event.Ship");if(!Array.isArray(event.Modules)){throw new TypeError(`ShipLoadout.fromLoadout: event.Modules must be an array, received ${describeValue(event.Modules)}`)}const modules=/* @__PURE__ */new Map;const slots=/* @__PURE__ */new Set;for(const module of event.Modules){if(module===null||typeof module!=="object"){throw new TypeError(`ShipLoadout.fromLoadout: event.Modules[] must hold module objects, received ${describeValue(module)}`)}requireString(module.Slot,"ShipLoadout.fromLoadout: module.Slot");requireString(module.Item,"ShipLoadout.fromLoadout: module.Item");if(module.Engineering!==void 0){if(module.Engineering===null||typeof module.Engineering!=="object"){throw new TypeError(`ShipLoadout.fromLoadout: module.Engineering must be an object, received ${describeValue(module.Engineering)}`)}requireStringIfPresent(module.Engineering.BlueprintName,"ShipLoadout.fromLoadout: module.Engineering.BlueprintName");requireStringIfPresent(module.Engineering.ExperimentalEffect,"ShipLoadout.fromLoadout: module.Engineering.ExperimentalEffect");if(module.Engineering.Modifiers!==void 0&&!Array.isArray(module.Engineering.Modifiers)){throw new TypeError(`ShipLoadout.fromLoadout: module.Engineering.Modifiers must be an array, received ${describeValue(module.Engineering.Modifiers)}`)}for(const[index,modifier]of(module.Engineering.Modifiers??[]).entries()){if(modifier===null||typeof modifier!=="object"){throw new TypeError(`ShipLoadout.fromLoadout: module.Engineering.Modifiers[${index}] must be an object, received ${describeValue(modifier)}`)}requireString(modifier.Label,`ShipLoadout.fromLoadout: module.Engineering.Modifiers[${index}].Label`)}}const normalizedSlot=module.Slot.toLowerCase();if(slots.has(normalizedSlot)){throw new TypeError(`ShipLoadout.fromLoadout: duplicate slot "${truncate(module.Slot)}"`)}slots.add(normalizedSlot);modules.set(module.Slot,cloneLoadoutModule(module))}const top={};if(event.ShipName!==void 0)top.ShipName=event.ShipName;if(event.ShipIdent!==void 0)top.ShipIdent=event.ShipIdent;if(event.HullValue!==void 0)top.HullValue=event.HullValue;if(event.ModulesValue!==void 0)top.ModulesValue=event.ModulesValue;if(event.Rebuy!==void 0)top.Rebuy=event.Rebuy;if(event.UnladenMass!==void 0)top.UnladenMass=event.UnladenMass;if(event.CargoCapacity!==void 0)top.CargoCapacity=event.CargoCapacity;if(event.FuelCapacity!==void 0)top.FuelCapacity={...event.FuelCapacity};let invalidatesAggregates=false;const outcomes=[];const defaults=getDefaultLoadout(event.Ship)?.modules??[];let layout;for(const[slot,module]of modules){if(isNonOutfittingSlot(slot)||isBuiltInHullModule(module))continue;const stats=builtInModuleBySymbol(module.Item,"ShipLoadout.fromLoadout: module.Item");const parsed=parseSlotName(slot);const stocked=parsed===null?null:stockedMountKind(parsed);const fallback=stocked===null?void 0:defaults.find(candidate=>candidate.slot.toLowerCase()===slot.toLowerCase());const rejected=fallback!==void 0&&(stats===null||stocked==="cargoHatch"||stockedMountRejects(event.Ship,layout??=hullLayout(event.Ship),slot,stats));if(stats!==null&&!rejected)continue;if(fallback){modules.set(slot,{Slot:slot,Item:fallback.symbol,...module.On===void 0?{}:{On:module.On},...module.Priority===void 0?{}:{Priority:module.Priority},...module.Health===void 0?{}:{Health:module.Health}});outcomes.push({action:"defaulted",slot:slot,sourceSymbol:module.Item,replacementSymbol:fallback.symbol})}else{modules.delete(slot);outcomes.push({action:"emptied",slot:slot,sourceSymbol:module.Item})}invalidatesAggregates=true}for(const fallback of defaults){const parsed=parseSlotName(fallback.slot);const stocked=parsed===null?null:stockedMountKind(parsed);if(stocked===null||matchingKeyIn(modules,fallback.slot)!==null)continue;const slot=ownKeyIn(modules,fallback.slot);modules.set(slot,{Slot:slot,Item:fallback.symbol});outcomes.push({action:"defaulted",slot:slot,sourceSymbol:null,replacementSymbol:fallback.symbol});if(stocked==="core")invalidatesAggregates=true}if(invalidatesAggregates){delete top.ModulesValue;delete top.Rebuy;delete top.UnladenMass;delete top.CargoCapacity;delete top.FuelCapacity}const moduleStats=/* @__PURE__ */new Map;const primitiveModifiers=/* @__PURE__ */new Map;for(const module of modules.values()){const engineering=module.Engineering;const variant=preEngineeredVariantFor(module);const catalogueVariantStats=variant?getPreEngineeredStats(variant):null;let variantStats=catalogueVariantStats;const retainsBakedExperimental=variant?.experimentalEffectSymbol!==void 0&&typeof engineering?.ExperimentalEffect==="string"&&variant.experimentalEffectSymbol.trim().toLowerCase()===engineering.ExperimentalEffect.trim().toLowerCase();if(variant&&catalogueVariantStats&&!catalogueVariantStats.engineeringLocked&&!retainsBakedExperimental){const{experimentalEffectSymbol:originalExperimental,...withoutExperimental}=variant;const currentExperimental=engineering?.ExperimentalEffect;const currentVariant=typeof currentExperimental==="string"?{...withoutExperimental,experimentalEffectSymbol:currentExperimental}:withoutExperimental;variantStats=getPreEngineeredStats(withoutExperimental);primitiveModifiers.set(module.Slot,[...engineering?.Modifiers??[],...getPreEngineeredModifiers(currentVariant)])}if(variantStats)moduleStats.set(module.Slot,cloneModuleStats(variantStats));const guardianFinal=typeof engineering?.BlueprintName==="string"&&isFinalGuardianWeaponEngineering(module.Item,engineering.BlueprintName);if(variantStats?.engineeringLocked||typeof engineering?.BlueprintName!=="string"||!guardianFinal){continue}const normalizedBlueprint=normalizeKey(engineering.BlueprintName,"ShipLoadout.fromLoadout: module.Engineering.BlueprintName");const normalizedExperimental=normalizeKey(engineering.ExperimentalEffect,"ShipLoadout.fromLoadout: module.Engineering.ExperimentalEffect");const variants=getPreEngineeredVariants(module.Item);const exact=variants.find(candidate=>candidate.engineeringLocked===true&&candidate.blueprintSymbol.toLowerCase()===normalizedBlueprint&&candidate.grade===engineering.Level&&candidate.experimentalEffectSymbol?.toLowerCase()===normalizedExperimental);const guardianBase=variants.find(candidate=>candidate.engineeringLocked===true&&candidate.blueprintSymbol.toLowerCase()===normalizedBlueprint&&candidate.grade===engineering.Level&&candidate.experimentalEffectSymbol===void 0);const stats=exact?getPreEngineeredStats(exact):guardianBase&&engineering.ExperimentalEffect!==void 0?getPreEngineeredStats({...guardianBase,experimentalEffectSymbol:engineering.ExperimentalEffect}):builtInModuleBySymbol(module.Item,"ShipLoadout.fromLoadout: module.Item");if(stats){moduleStats.set(module.Slot,cloneModuleStats({...stats,engineeringLocked:true}))}}return{shipSymbol:event.Ship,modules:modules,moduleStats:moduleStats,primitiveModifiers:primitiveModifiers,top:top,sourcePurchase:sourcePurchaseFromLoadout(event),outcomes:deepFreeze(outcomes)}}var NO_ISSUES=Object.freeze([]);function completeResult(value){return Object.freeze({value:value,complete:true,issues:NO_ISSUES})}function incompleteResult(issues){return Object.freeze({value:null,complete:false,issues:Object.freeze(issues.map(issue=>Object.freeze({...issue,...issue.params?{params:Object.freeze({...issue.params})}:{}})))})}var PREFIX={powerPlant:["int_powerplant","int_guardianpowerplant"],thrusters:["int_engine","int_mkiiagileboost_engine"],frameShiftDrive:["int_hyperdrive"],powerDistributor:["int_powerdistributor","int_guardianpowerdistributor"],shieldGenerator:["int_shieldgenerator"],shieldCellBank:["int_shieldcellbank"],shieldBooster:["hpt_shieldbooster"],shieldReinforcement:["int_guardianshieldreinforcement"],hullReinforcement:["int_hullreinforcement","int_guardianhullreinforcement","int_metaalloyhullreinforcement"],moduleReinforcement:["int_modulereinforcement","int_guardianmodulereinforcement"]};var startsWithAny=(symbol,prefixes)=>prefixes.some(prefix=>symbol.toLowerCase().startsWith(prefix));function isPowerDistributor(module,stats){return stats?.slot?stats.slot==="powerDistributor":startsWithAny(module.Item,PREFIX.powerDistributor)}function isPowerPlant(module,stats){const parsed=parseSlotName(module.Slot);if(parsed?.kind==="core"&&parsed.core==="powerPlant")return true;return stats?.slot?stats.slot==="powerPlant":startsWithAny(module.Item,PREFIX.powerPlant)}function isThruster(module,stats){const parsed=parseSlotName(module.Slot);if(parsed?.kind==="core"&&parsed.core==="thrusters")return true;return stats?.slot?stats.slot==="thrusters":startsWithAny(module.Item,PREFIX.thrusters)}function isFrameShiftDrive(module,stats){const parsed=parseSlotName(module.Slot);if(parsed?.kind==="core"&&parsed.core==="frameShiftDrive")return true;return stats?.slot?stats.slot==="frameShiftDrive":startsWithAny(module.Item,PREFIX.frameShiftDrive)}function isEnabled(module){return module.On!==false}function priorityOf(module){return(module.Priority??0)+1}function effectiveStat(module,field,stats){const stated=statedModifier(module,field);if(stated!==void 0)return stated;const base=stats?.[field];return typeof base==="number"?base:void 0}function statedModifier(module,field){for(const label of labelsForField(field)){if(capabilityValueForLabel(label)!==null)continue;const modified=getLoadoutModifier(module,label);if(modified!==null)return modified/scaleForLabel(label)}return void 0}function effectiveCapability(module,field,stats){for(const label of labelsForField(field)){if(capabilityValueForLabel(label)===null)continue;if(module.Engineering?.Modifiers?.some(modifier=>modifier.Label.toLowerCase()===label.toLowerCase())){return true}}const base=stats[field];return typeof base==="boolean"?base:void 0}function effectiveDamageDistribution(module,stats){const fromEffect=module.Engineering?.ExperimentalEffect?getExperimentalEffect(module.Engineering.ExperimentalEffect)?.damageDistribution:void 0;const distribution={...fromEffect??stats.damageDistribution};let resolved=fromEffect!==void 0||stats.damageDistribution!==void 0;const seen=/* @__PURE__ */new Set;for(const modifier of module.Engineering?.Modifiers??[]){const type=damageTypeForLabel(modifier.Label);if(type===null||seen.has(type))continue;seen.add(type);if(modifier.Value===void 0)continue;distribution[type]=modifier.Value/scaleForLabel(modifier.Label);resolved=true}return resolved?distribution:void 0}function convertsDamage(module){if(module.Engineering?.ExperimentalEffect&&getExperimentalEffect(module.Engineering.ExperimentalEffect)?.damageDistribution){return true}return(module.Engineering?.Modifiers??[]).some(modifier=>damageTypeForLabel(modifier.Label)!==null)}function modifierRatio(module,stats,field){const base=stats?.[field];if(typeof base!=="number"||base===0)return 1;const effective=effectiveStat(module,field,stats);return effective===void 0?1:effective/base}function relatedStat(module,stats,field,ratio){const stated=statedModifier(module,field);if(stated!==void 0)return stated;const base=stats?.[field];return typeof base==="number"?base*ratio:void 0}function carriesMassCurve(stats){return(stats.minMass??stats.maxMass??stats.minMultiplier??stats.maxMultiplier)!==void 0}function maxMassRatio(thrusters,ratio){return thrusters?ratio:Math.max(1,ratio)}function effectiveModule(module,stats){if(!stats||!module.Engineering)return stats;const merged={...stats};const fields=new Set(Object.keys(stats));for(const modifier of module.Engineering.Modifiers??[]){const field=fieldForLabel(modifier.Label,stats);if(field)fields.add(field)}for(const key of fields){const capability=effectiveCapability(module,key,stats);if(capability!==void 0){merged[key]=capability;continue}const value=effectiveStat(module,key,stats);if(value!==void 0)merged[key]=value}if(carriesMassCurve(stats)){const thrusters=stats.slot==="thrusters";const massRatio=modifierRatio(module,stats,"optMass");const minMass=relatedStat(module,stats,"minMass",massRatio);const maxMass=relatedStat(module,stats,"maxMass",maxMassRatio(thrusters,massRatio));if(minMass!==void 0)merged.minMass=minMass;if(maxMass!==void 0)merged.maxMass=maxMass;const performanceRatio=modifierRatio(module,stats,"optMultiplier");const minMultiplier=relatedStat(module,stats,"minMultiplier",performanceRatio);const maxMultiplier=relatedStat(module,stats,"maxMultiplier",performanceRatio);if(minMultiplier!==void 0)merged.minMultiplier=minMultiplier;if(maxMultiplier!==void 0)merged.maxMultiplier=maxMultiplier;if(thrusters){for(const field of["minSpeedMultiplier","optSpeedMultiplier","maxSpeedMultiplier","minRotationMultiplier","optRotationMultiplier","maxRotationMultiplier"]){const value=stats[field];if(value!==void 0)merged[field]=value*performanceRatio}}}const damageDistribution=effectiveDamageDistribution(module,stats);if(damageDistribution)merged.damageDistribution=damageDistribution;if(stats.category==="hardpoint")normalizeEffectiveWeapon(module,merged);if(convertsDamage(module)){delete merged.damageComponents}else if(stats.damageComponents){merged.damageComponents=scaleDamageComponents(stats.damageComponents,stats.damage,typeof merged.damage==="number"?merged.damage:void 0)}return merged}function powerConsumerFor(module,stats){const draw=effectiveStat(module,"powerDraw",stats);if(draw===void 0||draw===0)return null;const mounted=stats?.category==="hardpoint"||stats?.category==="utility";return{draw:draw,priority:priorityOf(module),enabled:isEnabled(module),deployedOnly:mounted&&stats?.alwaysPowered!==true,label:module.Slot,symbol:module.Item}}function powerAvailable(modules,statsFor){for(const module of modules){const stats=statsFor(module);if(!isPowerPlant(module,stats))continue;if(!isEnabled(module))return 0;return effectiveStat(module,"powerCapacity",stats)??0}return 0}var DEFAULT_SLOT={powerCapacity:"PowerPlant",heatEfficiency:"PowerPlant",thrusters:"MainEngines",powerDistributor:"PowerDistributor"};var UNRESOLVED_FACT={thrusters:"thruster stats",shieldGenerator:"shield-generator stats",powerCapacity:"power capacity",heatEfficiency:"heat efficiency",powerDistributor:"power-distributor stats"};var NOTHING_FITTED={powerCapacity:"PowerPlant: no power plant is fitted",heatEfficiency:"PowerPlant: no power plant is fitted",thrusters:"MainEngines: no thrusters are fitted",powerDistributor:"PowerDistributor: no power distributor is fitted"};function metricIssue(field,reason,module){const defaultSlot=DEFAULT_SLOT[field];const slot=module?.Slot??defaultSlot;const symbol=module?.Item;const params={field:field,reason:reason,...slot===void 0?{}:{slot:slot},...symbol===void 0?{}:{symbol:symbol}};let message;if(reason==="missing"){message=NOTHING_FITTED[field]??"no shield generator is fitted"}else if(reason==="unresolved"){const unavailable=UNRESOLVED_FACT[field]??field;message=`${truncate(slot??field)}: ${unavailable} unavailable for ${truncate(symbol??field)}`}else if(reason==="disabled"){message=`${truncate(slot??field)}: ${truncate(symbol??field)} is switched off`}else if(reason==="invalid"){message=`${truncate(slot??field)}: ${truncate(symbol??field)} has invalid ${field}`}else{message=`${truncate(slot??field)}: ${truncate(symbol??field)} is not powered with hardpoints retracted`}return{field:field,reason:reason,...slot===void 0?{}:{slot:slot},...symbol===void 0?{}:{symbol:symbol},message:message,params:params}}function powerPlantIssueFor(modules,statsFor){for(const module of modules){const stats=statsFor(module);if(!isPowerPlant(module,stats))continue;if(!isEnabled(module))return metricIssue("powerCapacity","disabled",module);const capacity=effectiveStat(module,"powerCapacity",stats);if(capacity===void 0)return metricIssue("powerCapacity","unresolved",module);return!Number.isFinite(capacity)||capacity<=0?metricIssue("powerCapacity","invalid",module):null}return metricIssue("powerCapacity","missing")}function powerDrawIssueFor(modules,statsFor){for(const module of modules){const consumer=powerConsumerFor(module,statsFor(module));if(consumer&&(!Number.isFinite(consumer.draw)||consumer.draw<0)){return metricIssue("powerDraw","invalid",module)}}return null}function poweredMetricBudgetFor(field,module,stats,modules,getBudget,statsFor){if(!isEnabled(module))return incompleteResult([metricIssue(field,"disabled",module)]);const plantIssue=powerPlantIssueFor(modules,statsFor);if(plantIssue)return incompleteResult([plantIssue]);const drawIssue=powerDrawIssueFor(modules,statsFor);if(drawIssue)return incompleteResult([drawIssue]);const budget=getBudget();return budget.available>0&&poweredStates(module,stats,budget).retracted?completeResult(budget):incompleteResult([metricIssue(field,"shed",module)])}function poweredShieldGeneratorResultFor(modules,getBudget,statsFor){for(const module of modules){if(!startsWithAny(module.Item,PREFIX.shieldGenerator))continue;const stats=statsFor(module);const powered=poweredMetricBudgetFor("shieldGenerator",module,stats,modules,getBudget,statsFor);if(!powered.complete)return powered;return stats===null?incompleteResult([metricIssue("shieldGenerator","unresolved",module)]):completeResult({module:module,budget:powered.value})}return incompleteResult([metricIssue("shieldGenerator","missing")])}function mapResistanceFields(read){return{kineticResistance:read("kineticResistance")??0,thermalResistance:read("thermalResistance")??0,explosiveResistance:read("explosiveResistance")??0,causticResistance:read("causticResistance")??0}}function resistancesOf(module,stats){return mapResistanceFields(field=>effectiveStat(module,field,stats))}function shieldInputFor(ship,modules,budget,statsFor){let generator=null;const boosters=[];let reinforcement=0;for(const module of modules){if(!isEnabled(module))continue;const stats=statsFor(module);if(!(budget.available>0&&poweredStates(module,stats,budget).retracted))continue;if(!generator&&startsWithAny(module.Item,PREFIX.shieldGenerator)){const effective=effectiveModule(module,stats);const{optMass:optMass,minMass:minMass,maxMass:maxMass,optMultiplier:optMultiplier,minMultiplier:minMultiplier,maxMultiplier:maxMultiplier}=effective??{};generator={...optMass===void 0?{}:{optMass:optMass},...minMass===void 0?{}:{minMass:minMass},...maxMass===void 0?{}:{maxMass:maxMass},...optMultiplier===void 0?{}:{optMultiplier:optMultiplier},...minMultiplier===void 0?{}:{minMultiplier:minMultiplier},...maxMultiplier===void 0?{}:{maxMultiplier:maxMultiplier},...resistancesOf(module,stats)}}else if(startsWithAny(module.Item,PREFIX.shieldBooster)){boosters.push({shieldBoost:effectiveStat(module,"shieldBoost",stats)??0,...resistancesOf(module,stats)})}else if(startsWithAny(module.Item,PREFIX.shieldReinforcement)){reinforcement+=effectiveStat(module,"shieldAddition",stats)??0}}return{hullMass:ship.hullMass,baseShieldStrength:ship.baseShieldStrength,generator:generator,boosters:boosters,reinforcement:reinforcement}}function shieldInputResultFor(ship,modules,getBudget,statsFor){const fitted=poweredShieldGeneratorResultFor(modules,getBudget,statsFor);if(!fitted.complete)return fitted;return completeResult(shieldInputFor(ship,modules,fitted.value.budget,statsFor))}function shieldCapacitorInputResultFor(ship,modules,getBudget,systemsPips,statsFor){const fitted=poweredShieldGeneratorResultFor(modules,getBudget,statsFor);if(!fitted.complete)return fitted;const budget=fitted.value.budget;const capacitor=systemsCapacitorResultFor(modules,budget,statsFor);if(!capacitor.complete)return capacitor;const shields=shieldMetrics(shieldInputFor(ship,modules,budget,statsFor));return completeResult({strength:shields.strength,resistances:shields.resistances,systemsCapacity:capacitor.value.systemsCapacity,systemsRecharge:capacitor.value.systemsRecharge,systemsPips:systemsPips})}function systemsCapacitorResultFor(modules,budget,statsFor){let distributor=null;for(const module of modules){const stats2=statsFor(module);if(isPowerDistributor(module,stats2)&&isEnabled(module)&&budget.available>0&&poweredStates(module,stats2,budget).retracted)distributor=module}if(!distributor)return completeResult({systemsCapacity:0,systemsRecharge:0});const stats=statsFor(distributor);const systemsCapacity=effectiveStat(distributor,"systemsCapacity",stats);const systemsRecharge=effectiveStat(distributor,"systemsRecharge",stats);return systemsCapacity===void 0||systemsRecharge===void 0?incompleteResult([metricIssue("powerDistributor","unresolved",distributor)]):completeResult({systemsCapacity:systemsCapacity,systemsRecharge:systemsRecharge})}function thrusterCurveFor(module,stats){const effective=effectiveModule(module,stats);const minMass=effective?.minMass;const optMass=effective?.optMass;const maxMass=effective?.maxMass;const minMultiplier=effective?.minMultiplier;const optMultiplier=effective?.optMultiplier;const maxMultiplier=effective?.maxMultiplier;if(minMass===void 0||optMass===void 0||maxMass===void 0||minMultiplier===void 0||optMultiplier===void 0||maxMultiplier===void 0){return null}return{minMass:minMass,optMass:optMass,maxMass:maxMass,minMultiplier:minMultiplier,optMultiplier:optMultiplier,maxMultiplier:maxMultiplier,...effective?.optSpeedMultiplier===void 0?{}:{speedCurve:{minMass:minMass,optMass:optMass,maxMass:maxMass,minMultiplier:effective.minSpeedMultiplier??minMultiplier,optMultiplier:effective.optSpeedMultiplier,maxMultiplier:effective.maxSpeedMultiplier??maxMultiplier}},...effective?.optRotationMultiplier===void 0?{}:{rotationCurve:{minMass:minMass,optMass:optMass,maxMass:maxMass,minMultiplier:effective.minRotationMultiplier??minMultiplier,optMultiplier:effective.optRotationMultiplier,maxMultiplier:effective.maxRotationMultiplier??maxMultiplier}}}}function fittedThrusterParamsFor(modules,statsFor){for(const module of modules){const stats=statsFor(module);if(isThruster(module,stats))return thrusterCurveFor(module,stats)}return null}function mobilityInputResultFor(ship,modules,getBudget,mass,statsFor){let thrusters=null;for(const module of modules){const stats=statsFor(module);if(!isThruster(module,stats))continue;const powered=poweredMetricBudgetFor("thrusters",module,stats,modules,getBudget,statsFor);if(!powered.complete)return powered;thrusters=thrusterCurveFor(module,stats);if(!thrusters)return incompleteResult([metricIssue("thrusters","unresolved",module)]);break}if(!thrusters)return incompleteResult([metricIssue("thrusters","missing")]);return completeResult({minimumSpeed:ship.minimumSpeed,maximumSpeed:ship.maximumSpeed,boost:ship.boost,minPitch:ship.minPitch,pitch:ship.pitch,minRoll:ship.minRoll,roll:ship.roll,minYaw:ship.minYaw,yaw:ship.yaw,mass:typeof mass==="function"?mass():mass,thrusters:thrusters})}function shieldRecoveryInputResultFor(ship,modules,getBudget,systemsPips,statsFor){const generator=poweredShieldGeneratorResultFor(modules,getBudget,statsFor);if(!generator.complete)return generator;const{module:generatorModule,budget:budget}=generator.value;const generatorStats=statsFor(generatorModule);const distributorDraw=effectiveStat(generatorModule,"distributorDraw",generatorStats);const regenRate=effectiveStat(generatorModule,"shieldRegenRate",generatorStats);const brokenRegenRate=effectiveStat(generatorModule,"shieldBrokenRegenRate",generatorStats);if(distributorDraw===void 0||regenRate===void 0||brokenRegenRate===void 0){return incompleteResult([metricIssue("shieldGenerator","unresolved",generatorModule)])}const capacitor=systemsCapacitorResultFor(modules,budget,statsFor);if(!capacitor.complete)return capacitor;const strength=shieldMetrics(shieldInputFor(ship,modules,budget,statsFor)).strength;return completeResult({strength:strength,regenRate:regenRate,brokenRegenRate:brokenRegenRate,distributorDraw:distributorDraw,systemsCapacity:capacitor.value.systemsCapacity,systemsRecharge:capacitor.value.systemsRecharge,systemsPips:systemsPips})}function weaponsCapacitorInputFor(modules,weaponsPips,budget,statsFor){let weaponsCapacity=0;let weaponsRecharge=0;let sustainedEnergyPerSecond=0;for(const module of modules){if(!isEnabled(module))continue;const stats=statsFor(module);if(!poweredStates(module,stats,budget).deployed)continue;if(isPowerDistributor(module,stats)){weaponsCapacity=effectiveStat(module,"weaponsCapacity",stats)??0;weaponsRecharge=effectiveStat(module,"weaponsRecharge",stats)??0}const weapon=weaponStatsFor(module,stats);if(weapon){sustainedEnergyPerSecond+=weaponMetrics(weapon).sustainedEnergyPerSecond}}return{weaponsCapacity:weaponsCapacity,weaponsRecharge:weaponsRecharge,sustainedEnergyPerSecond:sustainedEnergyPerSecond,weaponsPips:weaponsPips}}function distributorInputResultFor(modules,pips,budget,statsFor){let disabled=null;for(const module of modules){const stats=statsFor(module);if(!isPowerDistributor(module,stats))continue;if(!isEnabled(module)){disabled??=module;continue}if(!poweredStates(module,stats,budget).retracted){return incompleteResult([metricIssue("powerDistributor","shed",module)])}const systemsCapacity=effectiveStat(module,"systemsCapacity",stats);const systemsRecharge=effectiveStat(module,"systemsRecharge",stats);const enginesCapacity=effectiveStat(module,"enginesCapacity",stats);const enginesRecharge=effectiveStat(module,"enginesRecharge",stats);const weaponsCapacity=effectiveStat(module,"weaponsCapacity",stats);const weaponsRecharge=effectiveStat(module,"weaponsRecharge",stats);if(systemsCapacity===void 0||systemsRecharge===void 0||enginesCapacity===void 0||enginesRecharge===void 0||weaponsCapacity===void 0||weaponsRecharge===void 0){return incompleteResult([metricIssue("powerDistributor","unresolved",module)])}return completeResult({systemsCapacity:systemsCapacity,systemsRecharge:systemsRecharge,enginesCapacity:enginesCapacity,enginesRecharge:enginesRecharge,weaponsCapacity:weaponsCapacity,weaponsRecharge:weaponsRecharge,...pips})}return incompleteResult([disabled===null?metricIssue("powerDistributor","missing"):metricIssue("powerDistributor","disabled",disabled)])}function heatInputResultFor(ship,modules,budget,statsFor){let plant=null;let heatEfficiency;let thrusterHeatRate=0;let deployedThrusterHeatRate=0;let fsdHeatRate=0;let weaponsCapacity=0;const weapons=[];for(const module of modules){const stats=statsFor(module);if(isPowerPlant(module,stats)){if(!isEnabled(module)){return incompleteResult([metricIssue("powerCapacity","disabled",module)])}plant=module;heatEfficiency=effectiveStat(module,"heatEfficiency",stats);continue}if(!isEnabled(module))continue;const running=poweredStates(module,stats,budget);if(isThruster(module,stats)){const heat=effectiveStat(module,"engineHeatRate",stats)??0;if(running.retracted)thrusterHeatRate+=heat;if(running.deployed)deployedThrusterHeatRate+=heat}else if(isFrameShiftDrive(module,stats)){if(running.retracted)fsdHeatRate+=effectiveStat(module,"fsdHeatRate",stats)??0}else if(isPowerDistributor(module,stats)){if(running.deployed){weaponsCapacity=effectiveStat(module,"weaponsCapacity",stats)??0}}const weapon=weaponStatsFor(module,stats);if(!running.deployed)continue;if(!weapon)continue;weapons.push({heatPerSecond:weaponMetrics(weapon).sustainedHeatPerSecond,distributorDraw:weapon.distributorDraw??0})}if(heatEfficiency===void 0){return incompleteResult([plant===null?metricIssue("powerCapacity","missing"):metricIssue("heatEfficiency","unresolved",plant)])}return completeResult({heatCapacity:ship.heatCapacity,heatDissipation:ship.heatDissipation,heatEfficiency:heatEfficiency,retractedPowerDraw:poweredDraw(budget,"retracted"),deployedPowerDraw:poweredDraw(budget,"deployed"),thrusterHeatRate:thrusterHeatRate,deployedThrusterHeatRate:deployedThrusterHeatRate,fsdHeatRate:fsdHeatRate,weaponsCapacity:weaponsCapacity,weapons:weapons})}function poweredDraw(budget,state){const powered=state==="retracted"?"poweredRetracted":"poweredDeployed";return budget.bands.reduce((total,band)=>band[powered]?total+band[state]:total,0)}function poweredStates(module,stats,budget){const draw=effectiveStat(module,"powerDraw",stats);if(draw===void 0||draw===0)return{retracted:true,deployed:true};const band=budget.bands[Math.min(budget.bands.length,Math.max(1,priorityOf(module)))-1];if(!band)return{retracted:true,deployed:true};return{retracted:band.poweredRetracted,deployed:band.poweredDeployed}}function cellBankInputsFor(modules,budget,statsFor){const banks=[];for(const module of modules){if(!startsWithAny(module.Item,PREFIX.shieldCellBank))continue;const stats=statsFor(module);const effective=effectiveModule(module,stats);const ammunition=effective?ammunitionCapacity(effective):null;banks.push({slot:module.Slot,symbol:module.Item,reinforcementRate:effective?.shieldBankReinforcement??0,cells:ammunition?.total??0,spinUp:effective?.shieldBankSpinUp??0,duration:effective?.shieldBankDuration??0,heat:effective?.shieldBankHeat??0,powered:budget.available>0&&isEnabled(module)&&poweredStates(module,stats,budget).deployed})}return banks}function stockBulkhead(ship){const variants=getBulkheadsForShip(ship.name,CORE_MODULES);return variants.find(v=>v.symbol.toLowerCase().endsWith("_default"))??variants.find(v=>v.mass===0)??variants[0]??null}function armourInputFor(ship,modules,statsFor){const reinforcements=[];const moduleReinforcements=[];let bulkhead=null;for(const module of modules){if(!isEnabled(module))continue;const stats=statsFor(module);if(module.Slot.toLowerCase()==="armour"){bulkhead={hullBoost:effectiveStat(module,"hullBoost",stats)??0,...resistancesOf(module,stats)}}else if(startsWithAny(module.Item,PREFIX.hullReinforcement)){const boost=getLoadoutModifier(module,"DefenceModifierHealthMultiplier");reinforcements.push({hullReinforcement:effectiveStat(module,"hullReinforcement",stats)??0,hullBoost:boost===null?0:boost/scaleForLabel("DefenceModifierHealthMultiplier"),...resistancesOf(module,stats)})}else if(startsWithAny(module.Item,PREFIX.moduleReinforcement)){moduleReinforcements.push({moduleProtection:effectiveStat(module,"moduleProtection",stats)??0,integrity:effectiveStat(module,"integrity",stats)??0})}}if(!bulkhead){const stock=stockBulkhead(ship);bulkhead=stock?{hullBoost:stock.hullBoost??0,...mapResistanceFields(field=>stock[field])}:null}return{baseArmour:ship.baseArmour,bulkhead:bulkhead,reinforcements:reinforcements,moduleReinforcements:moduleReinforcements}}var WEAPON_FIELDS=["damage","roundsPerShot","rateOfFire","burstInterval","burstRounds","burstRateOfFire","chargeTime","clipSize","ammoMaximum","reloadTime","distributorDraw","thermalLoad","powerDraw","maximumRange","falloffRange","armourPiercing"];function weaponStatsFor(module,stats){if(!stats||stats.category!=="hardpoint")return null;const weapon={};for(const field of WEAPON_FIELDS){const value=effectiveStat(module,field,stats);if(value!==void 0)weapon[field]=value}normalizeEffectiveWeapon(module,weapon);const damageDistribution=effectiveDamageDistribution(module,stats);if(damageDistribution)weapon.damageDistribution=damageDistribution;if(stats.damageComponents&&!convertsDamage(module)){weapon.damageComponents=scaleDamageComponents(stats.damageComponents,stats.damage,typeof weapon.damage==="number"?weapon.damage:void 0)}if(stats.projectileRange)weapon.projectileRange={...stats.projectileRange};return weapon}function burstAdjustedRateOfFire(module,weapon){if(getLoadoutModifier(module,"RateOfFire")!==null)return void 0;const modifiers=module.Engineering?.Modifiers;const touched=BURST_PATTERN_LABELS.some(label=>getLoadoutModifier(module,label)!==null);if(!touched)return void 0;const stated=(label,field)=>preciseValueFor(modifiers,label)??weapon[field];return journalRateOfFire(stated("BurstInterval","burstInterval"),stated("BurstSize","burstRounds"),stated("BurstRateOfFire","burstRateOfFire"))}var FIRING_RATE_LABELS=["RateOfFire","BurstRateOfFire","BurstSize","BurstInterval","RoundsPerShot","Rounds"];function readsDamageFromPerSecond(module){return getLoadoutModifier(module,"Damage")===null&&FIRING_RATE_LABELS.every(label=>getLoadoutModifier(module,label)===null)}function normalizeEffectiveWeapon(module,weapon){const rate=burstAdjustedRateOfFire(module,weapon);if(rate!==void 0)weapon.rateOfFire=rate;if(readsDamageFromPerSecond(module)){const statedDamagePerSecond=getLoadoutModifier(module,"DamagePerSecond");const firingFactor=Number(weapon.roundsPerShot??1)*Number(weapon.rateOfFire??1);if(statedDamagePerSecond!==null&&firingFactor>0){weapon.damage=statedDamagePerSecond/firingFactor}}const{maximumRange:maximumRange,falloffRange:falloffRange}=weapon;if(maximumRange!==void 0&&falloffRange!==void 0&&falloffRange>maximumRange){weapon.falloffRange=maximumRange}}var INTERNALS=/* @__PURE__ */new WeakMap;function publishLoadoutInternals(build,internals){INTERNALS.set(build,internals)}function loadoutInternals(build,label){const internals=typeof build==="object"&&build!==null?INTERNALS.get(build):void 0;if(internals===void 0){throw new TypeError(`${label} must be a ShipLoadout, received ${describeValue(build)}`)}return internals}export{armourInputFor,cellBankInputsFor,completeResult,distributorInputResultFor,effectiveModule,fittedThrusterParamsFor,heatInputResultFor,incompleteResult,loadoutInternals,mobilityInputResultFor,moduleFitError,moduleFitProblem,normalizeLoadoutEvent,powerAvailable,powerConsumerFor,preEngineeredVariantFor,publishLoadoutInternals,shieldCapacitorInputResultFor,shieldInputResultFor,shieldRecoveryInputResultFor,weaponStatsFor,weaponsCapacitorInputFor};//# sourceMappingURL=chunk-XCLOOKC2.js.map
1
+ import{weaponMetrics}from"./chunk-Z266X4JF.js";import{shieldMetrics}from"./chunk-SRPCHXW2.js";import{getShipBySymbol,getShipByName,getShipSlots}from"./chunk-C4FUV6GF.js";import{getLoadoutModifier}from"./chunk-T4MKUKYS.js";import{sourcePurchaseFromLoadout}from"./chunk-NIURLW2F.js";import{isBuiltInHullSymbol,identifyPreEngineeredVariant,unrollableFixedArticle,cloneLoadoutModule,isNonOutfittingSlot,isBuiltInHullModule,matchingKeyIn,ownKeyIn,getPreEngineeredStats,getPreEngineeredModifiers,cloneModuleStats,isFinalGuardianWeaponEngineering,scaleDamageComponents}from"./chunk-LLLFK3D5.js";import{builtInModuleBySymbol,getBulkheadsForShip}from"./chunk-FMPHK3L5.js";import{getPreEngineeredVariants}from"./chunk-EE25IDB7.js";import{CORE_MODULES}from"./chunk-ZZTDEDXJ.js";import{getExperimentalEffect}from"./chunk-77I24V6B.js";import{stockedMountKind}from"./chunk-M6J7KP7G.js";import{getDefaultLoadout}from"./chunk-KY7KSPU6.js";import{fieldForLabel,scaleForLabel,labelsForField,capabilityValueForLabel,damageTypeForLabel}from"./chunk-U73MBQ45.js";import{BURST_PATTERN_LABELS,journalRateOfFire,preciseValueFor}from"./chunk-EFQOUATZ.js";import{ammunitionCapacity}from"./chunk-AA3K5XUE.js";import{parseSlotName,SLOT_RESTRICTION_LABELS,enumerateSlots}from"./chunk-RAO35XDF.js";import{normalizeKey}from"./chunk-BKWLI44T.js";import{truncate,requireString,describeValue,requireStringIfPresent}from"./chunk-PKWVG2JY.js";import{deepFreeze}from"./chunk-DURKO7JU.js";var MILITARY_PREFIXES=["int_hullreinforcement","int_metaalloyhullreinforcement","int_modulereinforcement","int_shieldcellbank","int_guardianhullreinforcement","int_guardianmodulereinforcement","int_guardianshieldreinforcement"];var MINING_PREFIXES=["hpt_mininglaser","hpt_mining_abrblstr","hpt_mining_seismchrgwarhd","hpt_mining_subsurfdispmisle","hpt_human_extraction","hpt_miningtoolv2"];var CARGO_PREFIXES=["int_cargorack","int_largecargorack","int_corrosionproofcargorack","int_fueltank"];var RESTRICTED_SLOT_PREFIXES={mining:MINING_PREFIXES,military:MILITARY_PREFIXES,cargo:CARGO_PREFIXES,limpetController:["int_dronecontrol","int_multidronecontrol"],vesselHangar:["int_fighterbay","int_largebuggybay","int_mkiilargebuggybay"],passenger:["int_passengercabin","int_mkii_passengercabin"],planetaryApproachSuite:["int_planetapproachsuite"]};var problem=(constraint,message,params)=>({constraint:constraint,message:message,...params===void 0?{}:{params:params}});function restrictionProblem(slot,symbol){const restriction=slot.restriction;if(!restriction)return null;if(RESTRICTED_SLOT_PREFIXES[restriction].some(prefix=>symbol.startsWith(prefix))){return null}return problem("restrictedMount",`slot only takes ${SLOT_RESTRICTION_LABELS[restriction]}`,{restriction:restriction})}function moduleSlotProblem(slot,module){const required=module.restrictedToSlot;if(!required||slot.restriction===required)return null;return problem("restrictedMount",`module only fits a mount that takes ${SLOT_RESTRICTION_LABELS[required]}`,{restriction:required})}function moduleFitProblem(shipSymbol,slot,module){if(slot.kind==="cargoHatch"){return problem("immutableSlot","the cargoHatch slot cannot be changed")}if(isBuiltInHullSymbol(module.symbol)){return problem("builtInHullModule","the cargo hatch is part of the hull, not an outfitting module")}if(slot.kind==="armour"){const hull=getShipBySymbol(shipSymbol);if(module.slot!=="armour"||module.ship===void 0){return problem("armourRequired","not a ship armour module")}if(!hull||module.ship.toLowerCase()!==hull.name.toLowerCase()){const armourHull=getShipByName(module.ship);return problem("wrongHullArmour",`armour belongs to ${truncate(module.ship)}, not ${truncate(hull?.name??shipSymbol)}`,{armourShipName:module.ship,...armourHull===null?{}:{armourShipSymbol:armourHull.symbol},shipSymbol:shipSymbol,...hull===null?{}:{shipName:hull.name}})}return null}const restricted=module.restrictedToShips;if(restricted&&!restricted.some(symbol2=>symbol2.toLowerCase()===shipSymbol.toLowerCase())){const allowedShipNames=restricted.map(symbol2=>{const hull=getShipBySymbol(symbol2);return hull?.name??symbol2});const labels=restricted.map((symbol2,index)=>{const name=allowedShipNames[index];return name===symbol2?symbol2:`${name} (${symbol2})`});return problem("restrictedHull",`module is restricted to ${truncate(labels.join(", "))}`,{allowedShipNames:allowedShipNames,allowedShipSymbols:[...restricted],shipSymbol:shipSymbol})}const wrongMount=moduleSlotProblem(slot,module);if(wrongMount)return wrongMount;const symbol=module.symbol.toLowerCase();const moduleSlot=module.slot;switch(slot.kind){case"core":if(moduleSlot!==slot.core){return problem("wrongCoreType",`not a ${slot.core} module`,{requiredCore:slot.core,moduleSlot:moduleSlot??"none"})}break;case"hardpoint":{if(module.category!=="hardpoint"){return problem("hardpointRequired","not a hardpoint weapon")}const restricted2=restrictionProblem(slot,symbol);if(restricted2)return restricted2;break}case"utility":if(module.category!=="utility"){return problem("utilityRequired","not a utility module")}return null;case"optional":{const isFuelTank=moduleSlot==="fuelTank";if(module.category!=="internal"&&!isFuelTank){return problem("optionalInternalRequired","not an optional-internal module")}if(moduleSlot&&!isFuelTank){return problem("coreModuleInOptionalSlot","a core module only fits its core slot")}const restricted2=restrictionProblem(slot,symbol);if(restricted2)return restricted2;break}}if(module.class>slot.size){return problem("oversized",`module size ${truncate(module.class)} exceeds slot size ${slot.size}`,{moduleClass:module.class,slotSize:slot.size})}if(module.supercruiseOvercharge===true&&module.class<slot.size){return problem("exactSizeRequired",`an SCO drive fits a size ${truncate(module.class)} mount only, not size ${slot.size}`,{moduleClass:module.class,slotSize:slot.size})}return null}function moduleFitError(shipSymbol,slot,module){return moduleFitProblem(shipSymbol,slot,module)?.message??null}function preEngineeredVariantFor(module){return identifyPreEngineeredVariant(module)??(module.Engineering?unrollableFixedArticle(module.Item,module.Engineering):null)}function captureLoadoutEvent(event){const modules=event.Modules;const shipName=event.ShipName;const shipIdent=event.ShipIdent;const hullValue=event.HullValue;const modulesValue=event.ModulesValue;const rebuy=event.Rebuy;const unladenMass=event.UnladenMass;const cargoCapacity=event.CargoCapacity;const fuelCapacity=event.FuelCapacity;return{Ship:event.Ship,Modules:Array.isArray(modules)?captureEach(modules,captureModule):modules,...shipName===void 0?{}:{ShipName:shipName},...shipIdent===void 0?{}:{ShipIdent:shipIdent},...hullValue===void 0?{}:{HullValue:hullValue},...modulesValue===void 0?{}:{ModulesValue:modulesValue},...rebuy===void 0?{}:{Rebuy:rebuy},...unladenMass===void 0?{}:{UnladenMass:unladenMass},...cargoCapacity===void 0?{}:{CargoCapacity:cargoCapacity},...fuelCapacity===void 0?{}:{FuelCapacity:{...fuelCapacity}}}}function captureEach(values,capture){const captured=[];const{length:length}=values;for(let index=0;index<length;index++)captured.push(capture(values[index]));return captured}function captureModule(module){if(module===null||typeof module!=="object")return module;const on=module.On;const priority=module.Priority;const health=module.Health;const value=module.Value;const engineering=module.Engineering;return{Slot:module.Slot,Item:module.Item,...on===void 0?{}:{On:on},...priority===void 0?{}:{Priority:priority},...health===void 0?{}:{Health:health},...value===void 0?{}:{Value:value},...engineering===void 0?{}:{Engineering:captureEngineering(engineering)}}}function captureEngineering(engineering){if(engineering===null||typeof engineering!=="object")return engineering;const experimental=engineering.ExperimentalEffect;const experimentalLocalised=engineering.ExperimentalEffect_Localised;const modifiers=engineering.Modifiers;return{BlueprintName:engineering.BlueprintName,Level:engineering.Level,Quality:engineering.Quality,...experimental===void 0?{}:{ExperimentalEffect:experimental},...experimentalLocalised===void 0?{}:{ExperimentalEffect_Localised:experimentalLocalised},...modifiers===void 0?{}:{Modifiers:Array.isArray(modifiers)?captureEach(modifiers,modifier=>modifier!==null&&typeof modifier==="object"?{...modifier}:modifier):modifiers}}}function hullLayout(shipSymbol){const slots=getShipSlots(shipSymbol);return slots?enumerateSlots(slots):[]}function stockedMountRejects(shipSymbol,layout,slot,stats){const mount=layout.find(candidate=>candidate.key.toLowerCase()===slot.toLowerCase());return mount!==void 0&&moduleFitProblem(shipSymbol,mount,stats)!==null}function normalizeLoadoutEvent(rawEvent){const event=captureLoadoutEvent(rawEvent);requireString(event.Ship,"ShipLoadout.fromLoadout: event.Ship");if(!Array.isArray(event.Modules)){throw new TypeError(`ShipLoadout.fromLoadout: event.Modules must be an array, received ${describeValue(event.Modules)}`)}const modules=/* @__PURE__ */new Map;const slots=/* @__PURE__ */new Set;for(const module of event.Modules){if(module===null||typeof module!=="object"){throw new TypeError(`ShipLoadout.fromLoadout: event.Modules[] must hold module objects, received ${describeValue(module)}`)}requireString(module.Slot,"ShipLoadout.fromLoadout: module.Slot");requireString(module.Item,"ShipLoadout.fromLoadout: module.Item");if(module.Engineering!==void 0){if(module.Engineering===null||typeof module.Engineering!=="object"){throw new TypeError(`ShipLoadout.fromLoadout: module.Engineering must be an object, received ${describeValue(module.Engineering)}`)}requireStringIfPresent(module.Engineering.BlueprintName,"ShipLoadout.fromLoadout: module.Engineering.BlueprintName");requireStringIfPresent(module.Engineering.ExperimentalEffect,"ShipLoadout.fromLoadout: module.Engineering.ExperimentalEffect");if(module.Engineering.Modifiers!==void 0&&!Array.isArray(module.Engineering.Modifiers)){throw new TypeError(`ShipLoadout.fromLoadout: module.Engineering.Modifiers must be an array, received ${describeValue(module.Engineering.Modifiers)}`)}for(const[index,modifier]of(module.Engineering.Modifiers??[]).entries()){if(modifier===null||typeof modifier!=="object"){throw new TypeError(`ShipLoadout.fromLoadout: module.Engineering.Modifiers[${index}] must be an object, received ${describeValue(modifier)}`)}requireString(modifier.Label,`ShipLoadout.fromLoadout: module.Engineering.Modifiers[${index}].Label`)}}const normalizedSlot=module.Slot.toLowerCase();if(slots.has(normalizedSlot)){throw new TypeError(`ShipLoadout.fromLoadout: duplicate slot "${truncate(module.Slot)}"`)}slots.add(normalizedSlot);modules.set(module.Slot,cloneLoadoutModule(module))}const top={};if(event.ShipName!==void 0)top.ShipName=event.ShipName;if(event.ShipIdent!==void 0)top.ShipIdent=event.ShipIdent;if(event.HullValue!==void 0)top.HullValue=event.HullValue;if(event.ModulesValue!==void 0)top.ModulesValue=event.ModulesValue;if(event.Rebuy!==void 0)top.Rebuy=event.Rebuy;if(event.UnladenMass!==void 0)top.UnladenMass=event.UnladenMass;if(event.CargoCapacity!==void 0)top.CargoCapacity=event.CargoCapacity;if(event.FuelCapacity!==void 0)top.FuelCapacity={...event.FuelCapacity};let invalidatesAggregates=false;const outcomes=[];const defaults=getDefaultLoadout(event.Ship)?.modules??[];let layout;for(const[slot,module]of modules){if(isNonOutfittingSlot(slot)||isBuiltInHullModule(module))continue;const stats=builtInModuleBySymbol(module.Item,"ShipLoadout.fromLoadout: module.Item");const parsed=parseSlotName(slot);const stocked=parsed===null?null:stockedMountKind(parsed);const fallback=stocked===null?void 0:defaults.find(candidate=>candidate.slot.toLowerCase()===slot.toLowerCase());const rejected=fallback!==void 0&&(stats===null||stocked==="cargoHatch"||stockedMountRejects(event.Ship,layout??=hullLayout(event.Ship),slot,stats));if(stats!==null&&!rejected)continue;if(fallback){modules.set(slot,{Slot:slot,Item:fallback.symbol,...module.On===void 0?{}:{On:module.On},...module.Priority===void 0?{}:{Priority:module.Priority},...module.Health===void 0?{}:{Health:module.Health}});outcomes.push({action:"defaulted",slot:slot,sourceSymbol:module.Item,replacementSymbol:fallback.symbol})}else{modules.delete(slot);outcomes.push({action:"emptied",slot:slot,sourceSymbol:module.Item})}invalidatesAggregates=true}for(const fallback of defaults){const parsed=parseSlotName(fallback.slot);const stocked=parsed===null?null:stockedMountKind(parsed);if(stocked===null||matchingKeyIn(modules,fallback.slot)!==null)continue;const slot=ownKeyIn(modules,fallback.slot);modules.set(slot,{Slot:slot,Item:fallback.symbol});outcomes.push({action:"defaulted",slot:slot,sourceSymbol:null,replacementSymbol:fallback.symbol});if(stocked==="core")invalidatesAggregates=true}if(invalidatesAggregates){delete top.ModulesValue;delete top.Rebuy;delete top.UnladenMass;delete top.CargoCapacity;delete top.FuelCapacity}const moduleStats=/* @__PURE__ */new Map;const primitiveModifiers=/* @__PURE__ */new Map;for(const module of modules.values()){const engineering=module.Engineering;const variant=preEngineeredVariantFor(module);const catalogueVariantStats=variant?getPreEngineeredStats(variant):null;let variantStats=catalogueVariantStats;const retainsBakedExperimental=variant?.experimentalEffectSymbol!==void 0&&typeof engineering?.ExperimentalEffect==="string"&&variant.experimentalEffectSymbol.trim().toLowerCase()===engineering.ExperimentalEffect.trim().toLowerCase();if(variant&&catalogueVariantStats&&!catalogueVariantStats.engineeringLocked&&!retainsBakedExperimental){const{experimentalEffectSymbol:originalExperimental,...withoutExperimental}=variant;const currentExperimental=engineering?.ExperimentalEffect;const currentVariant=typeof currentExperimental==="string"?{...withoutExperimental,experimentalEffectSymbol:currentExperimental}:withoutExperimental;variantStats=getPreEngineeredStats(withoutExperimental);primitiveModifiers.set(module.Slot,[...engineering?.Modifiers??[],...getPreEngineeredModifiers(currentVariant)])}if(variantStats)moduleStats.set(module.Slot,cloneModuleStats(variantStats));const guardianFinal=typeof engineering?.BlueprintName==="string"&&isFinalGuardianWeaponEngineering(module.Item,engineering.BlueprintName);if(variantStats?.engineeringLocked||typeof engineering?.BlueprintName!=="string"||!guardianFinal){continue}const normalizedBlueprint=normalizeKey(engineering.BlueprintName,"ShipLoadout.fromLoadout: module.Engineering.BlueprintName");const normalizedExperimental=normalizeKey(engineering.ExperimentalEffect,"ShipLoadout.fromLoadout: module.Engineering.ExperimentalEffect");const variants=getPreEngineeredVariants(module.Item);const exact=variants.find(candidate=>candidate.engineeringLocked===true&&candidate.blueprintSymbol.toLowerCase()===normalizedBlueprint&&candidate.grade===engineering.Level&&candidate.experimentalEffectSymbol?.toLowerCase()===normalizedExperimental);const guardianBase=variants.find(candidate=>candidate.engineeringLocked===true&&candidate.blueprintSymbol.toLowerCase()===normalizedBlueprint&&candidate.grade===engineering.Level&&candidate.experimentalEffectSymbol===void 0);const stats=exact?getPreEngineeredStats(exact):guardianBase&&engineering.ExperimentalEffect!==void 0?getPreEngineeredStats({...guardianBase,experimentalEffectSymbol:engineering.ExperimentalEffect}):builtInModuleBySymbol(module.Item,"ShipLoadout.fromLoadout: module.Item");if(stats){moduleStats.set(module.Slot,cloneModuleStats({...stats,engineeringLocked:true}))}}return{shipSymbol:event.Ship,modules:modules,moduleStats:moduleStats,primitiveModifiers:primitiveModifiers,top:top,sourcePurchase:sourcePurchaseFromLoadout(event),outcomes:deepFreeze(outcomes)}}var NO_ISSUES=Object.freeze([]);function completeResult(value){return Object.freeze({value:value,complete:true,issues:NO_ISSUES})}function incompleteResult(issues){return Object.freeze({value:null,complete:false,issues:Object.freeze(issues.map(issue=>Object.freeze({...issue,...issue.params?{params:Object.freeze({...issue.params})}:{}})))})}var PREFIX={powerPlant:["int_powerplant","int_guardianpowerplant"],thrusters:["int_engine","int_mkiiagileboost_engine"],frameShiftDrive:["int_hyperdrive"],powerDistributor:["int_powerdistributor","int_guardianpowerdistributor"],shieldGenerator:["int_shieldgenerator"],shieldCellBank:["int_shieldcellbank"],shieldBooster:["hpt_shieldbooster"],shieldReinforcement:["int_guardianshieldreinforcement"],hullReinforcement:["int_hullreinforcement","int_guardianhullreinforcement","int_metaalloyhullreinforcement"],moduleReinforcement:["int_modulereinforcement","int_guardianmodulereinforcement"]};var startsWithAny=(symbol,prefixes)=>prefixes.some(prefix=>symbol.toLowerCase().startsWith(prefix));function isPowerDistributor(module,stats){return stats?.slot?stats.slot==="powerDistributor":startsWithAny(module.Item,PREFIX.powerDistributor)}function isPowerPlant(module,stats){const parsed=parseSlotName(module.Slot);if(parsed?.kind==="core"&&parsed.core==="powerPlant")return true;return stats?.slot?stats.slot==="powerPlant":startsWithAny(module.Item,PREFIX.powerPlant)}function isThruster(module,stats){const parsed=parseSlotName(module.Slot);if(parsed?.kind==="core"&&parsed.core==="thrusters")return true;return stats?.slot?stats.slot==="thrusters":startsWithAny(module.Item,PREFIX.thrusters)}function isFrameShiftDrive(module,stats){const parsed=parseSlotName(module.Slot);if(parsed?.kind==="core"&&parsed.core==="frameShiftDrive")return true;return stats?.slot?stats.slot==="frameShiftDrive":startsWithAny(module.Item,PREFIX.frameShiftDrive)}function isEnabled(module){return module.On!==false}function priorityOf(module){return(module.Priority??0)+1}function effectiveStat(module,field,stats){const stated=statedModifier(module,field);if(stated!==void 0)return stated;const base=stats?.[field];return typeof base==="number"?base:void 0}function statedModifier(module,field){for(const label of labelsForField(field)){if(capabilityValueForLabel(label)!==null)continue;const modified=getLoadoutModifier(module,label);if(modified!==null)return modified/scaleForLabel(label)}return void 0}function effectiveCapability(module,field,stats){for(const label of labelsForField(field)){if(capabilityValueForLabel(label)===null)continue;if(module.Engineering?.Modifiers?.some(modifier=>modifier.Label.toLowerCase()===label.toLowerCase())){return true}}const base=stats[field];return typeof base==="boolean"?base:void 0}function effectiveDamageDistribution(module,stats){const fromEffect=module.Engineering?.ExperimentalEffect?getExperimentalEffect(module.Engineering.ExperimentalEffect)?.damageDistribution:void 0;const distribution={...fromEffect??stats.damageDistribution};let resolved=fromEffect!==void 0||stats.damageDistribution!==void 0;const seen=/* @__PURE__ */new Set;for(const modifier of module.Engineering?.Modifiers??[]){const type=damageTypeForLabel(modifier.Label);if(type===null||seen.has(type))continue;seen.add(type);if(modifier.Value===void 0)continue;distribution[type]=modifier.Value/scaleForLabel(modifier.Label);resolved=true}return resolved?distribution:void 0}function convertsDamage(module){if(module.Engineering?.ExperimentalEffect&&getExperimentalEffect(module.Engineering.ExperimentalEffect)?.damageDistribution){return true}return(module.Engineering?.Modifiers??[]).some(modifier=>damageTypeForLabel(modifier.Label)!==null)}function modifierRatio(module,stats,field){const base=stats?.[field];if(typeof base!=="number"||base===0)return 1;const effective=effectiveStat(module,field,stats);return effective===void 0?1:effective/base}function relatedStat(module,stats,field,ratio){const stated=statedModifier(module,field);if(stated!==void 0)return stated;const base=stats?.[field];return typeof base==="number"?base*ratio:void 0}function carriesMassCurve(stats){return(stats.minMass??stats.maxMass??stats.minMultiplier??stats.maxMultiplier)!==void 0}function maxMassRatio(thrusters,ratio){return thrusters?ratio:Math.max(1,ratio)}function effectiveModule(module,stats){if(!stats||!module.Engineering)return stats;const merged={...stats};const fields=new Set(Object.keys(stats));for(const modifier of module.Engineering.Modifiers??[]){const field=fieldForLabel(modifier.Label,stats);if(field)fields.add(field)}for(const key of fields){const capability=effectiveCapability(module,key,stats);if(capability!==void 0){merged[key]=capability;continue}const value=effectiveStat(module,key,stats);if(value!==void 0)merged[key]=value}if(carriesMassCurve(stats)){const thrusters=stats.slot==="thrusters";const massRatio=modifierRatio(module,stats,"optMass");const minMass=relatedStat(module,stats,"minMass",massRatio);const maxMass=relatedStat(module,stats,"maxMass",maxMassRatio(thrusters,massRatio));if(minMass!==void 0)merged.minMass=minMass;if(maxMass!==void 0)merged.maxMass=maxMass;const performanceRatio=modifierRatio(module,stats,"optMultiplier");const minMultiplier=relatedStat(module,stats,"minMultiplier",performanceRatio);const maxMultiplier=relatedStat(module,stats,"maxMultiplier",performanceRatio);if(minMultiplier!==void 0)merged.minMultiplier=minMultiplier;if(maxMultiplier!==void 0)merged.maxMultiplier=maxMultiplier;if(thrusters){for(const field of["minSpeedMultiplier","optSpeedMultiplier","maxSpeedMultiplier","minRotationMultiplier","optRotationMultiplier","maxRotationMultiplier"]){const value=stats[field];if(value!==void 0)merged[field]=value*performanceRatio}}}const damageDistribution=effectiveDamageDistribution(module,stats);if(damageDistribution)merged.damageDistribution=damageDistribution;if(stats.category==="hardpoint")normalizeEffectiveWeapon(module,merged);if(convertsDamage(module)){delete merged.damageComponents}else if(stats.damageComponents){merged.damageComponents=scaleDamageComponents(stats.damageComponents,stats.damage,typeof merged.damage==="number"?merged.damage:void 0)}return merged}function powerConsumerFor(module,stats){const draw=effectiveStat(module,"powerDraw",stats);if(draw===void 0||draw===0)return null;const mounted=stats?.category==="hardpoint"||stats?.category==="utility";return{draw:draw,priority:priorityOf(module),enabled:isEnabled(module),deployedOnly:mounted&&stats?.alwaysPowered!==true,label:module.Slot,symbol:module.Item}}function powerAvailable(modules,statsFor){for(const module of modules){const stats=statsFor(module);if(!isPowerPlant(module,stats))continue;if(!isEnabled(module))return 0;return effectiveStat(module,"powerCapacity",stats)??0}return 0}var DEFAULT_SLOT={powerCapacity:"PowerPlant",heatEfficiency:"PowerPlant",thrusters:"MainEngines",powerDistributor:"PowerDistributor"};var UNRESOLVED_FACT={thrusters:"thruster stats",shieldGenerator:"shield-generator stats",powerCapacity:"power capacity",heatEfficiency:"heat efficiency",powerDistributor:"power-distributor stats"};var NOTHING_FITTED={powerCapacity:"PowerPlant: no power plant is fitted",heatEfficiency:"PowerPlant: no power plant is fitted",thrusters:"MainEngines: no thrusters are fitted",powerDistributor:"PowerDistributor: no power distributor is fitted"};function metricIssue(field,reason,module){const defaultSlot=DEFAULT_SLOT[field];const slot=module?.Slot??defaultSlot;const symbol=module?.Item;const params={field:field,reason:reason,...slot===void 0?{}:{slot:slot},...symbol===void 0?{}:{symbol:symbol}};let message;if(reason==="missing"){message=NOTHING_FITTED[field]??"no shield generator is fitted"}else if(reason==="unresolved"){const unavailable=UNRESOLVED_FACT[field]??field;message=`${truncate(slot??field)}: ${unavailable} unavailable for ${truncate(symbol??field)}`}else if(reason==="disabled"){message=`${truncate(slot??field)}: ${truncate(symbol??field)} is switched off`}else if(reason==="invalid"){message=`${truncate(slot??field)}: ${truncate(symbol??field)} has invalid ${field}`}else{message=`${truncate(slot??field)}: ${truncate(symbol??field)} is not powered with hardpoints retracted`}return{field:field,reason:reason,...slot===void 0?{}:{slot:slot},...symbol===void 0?{}:{symbol:symbol},message:message,params:params}}function powerPlantIssueFor(modules,statsFor){for(const module of modules){const stats=statsFor(module);if(!isPowerPlant(module,stats))continue;if(!isEnabled(module))return metricIssue("powerCapacity","disabled",module);const capacity=effectiveStat(module,"powerCapacity",stats);if(capacity===void 0)return metricIssue("powerCapacity","unresolved",module);return!Number.isFinite(capacity)||capacity<=0?metricIssue("powerCapacity","invalid",module):null}return metricIssue("powerCapacity","missing")}function powerDrawIssueFor(modules,statsFor){for(const module of modules){const consumer=powerConsumerFor(module,statsFor(module));if(consumer&&(!Number.isFinite(consumer.draw)||consumer.draw<0)){return metricIssue("powerDraw","invalid",module)}}return null}function poweredMetricBudgetFor(field,module,stats,modules,getBudget,statsFor){if(!isEnabled(module))return incompleteResult([metricIssue(field,"disabled",module)]);const plantIssue=powerPlantIssueFor(modules,statsFor);if(plantIssue)return incompleteResult([plantIssue]);const drawIssue=powerDrawIssueFor(modules,statsFor);if(drawIssue)return incompleteResult([drawIssue]);const budget=getBudget();return budget.available>0&&poweredStates(module,stats,budget).retracted?completeResult(budget):incompleteResult([metricIssue(field,"shed",module)])}function poweredShieldGeneratorResultFor(modules,getBudget,statsFor){for(const module of modules){if(!startsWithAny(module.Item,PREFIX.shieldGenerator))continue;const stats=statsFor(module);const powered=poweredMetricBudgetFor("shieldGenerator",module,stats,modules,getBudget,statsFor);if(!powered.complete)return powered;return stats===null?incompleteResult([metricIssue("shieldGenerator","unresolved",module)]):completeResult({module:module,budget:powered.value})}return incompleteResult([metricIssue("shieldGenerator","missing")])}function mapResistanceFields(read){return{kineticResistance:read("kineticResistance")??0,thermalResistance:read("thermalResistance")??0,explosiveResistance:read("explosiveResistance")??0,causticResistance:read("causticResistance")??0}}function resistancesOf(module,stats){return mapResistanceFields(field=>effectiveStat(module,field,stats))}function shieldInputFor(ship,modules,budget,statsFor){let generator=null;const boosters=[];let reinforcement=0;for(const module of modules){if(!isEnabled(module))continue;const stats=statsFor(module);if(!(budget.available>0&&poweredStates(module,stats,budget).retracted))continue;if(!generator&&startsWithAny(module.Item,PREFIX.shieldGenerator)){const effective=effectiveModule(module,stats);const{optMass:optMass,minMass:minMass,maxMass:maxMass,optMultiplier:optMultiplier,minMultiplier:minMultiplier,maxMultiplier:maxMultiplier}=effective??{};generator={...optMass===void 0?{}:{optMass:optMass},...minMass===void 0?{}:{minMass:minMass},...maxMass===void 0?{}:{maxMass:maxMass},...optMultiplier===void 0?{}:{optMultiplier:optMultiplier},...minMultiplier===void 0?{}:{minMultiplier:minMultiplier},...maxMultiplier===void 0?{}:{maxMultiplier:maxMultiplier},...resistancesOf(module,stats)}}else if(startsWithAny(module.Item,PREFIX.shieldBooster)){boosters.push({shieldBoost:effectiveStat(module,"shieldBoost",stats)??0,...resistancesOf(module,stats)})}else if(startsWithAny(module.Item,PREFIX.shieldReinforcement)){reinforcement+=effectiveStat(module,"shieldAddition",stats)??0}}return{hullMass:ship.hullMass,baseShieldStrength:ship.baseShieldStrength,generator:generator,boosters:boosters,reinforcement:reinforcement}}function shieldInputResultFor(ship,modules,getBudget,statsFor){const fitted=poweredShieldGeneratorResultFor(modules,getBudget,statsFor);if(!fitted.complete)return fitted;return completeResult(shieldInputFor(ship,modules,fitted.value.budget,statsFor))}function shieldCapacitorInputResultFor(ship,modules,getBudget,systemsPips,statsFor){const fitted=poweredShieldGeneratorResultFor(modules,getBudget,statsFor);if(!fitted.complete)return fitted;const budget=fitted.value.budget;const capacitor=systemsCapacitorResultFor(modules,budget,statsFor);if(!capacitor.complete)return capacitor;const shields=shieldMetrics(shieldInputFor(ship,modules,budget,statsFor));return completeResult({strength:shields.strength,resistances:shields.resistances,systemsCapacity:capacitor.value.systemsCapacity,systemsRecharge:capacitor.value.systemsRecharge,systemsPips:systemsPips})}function systemsCapacitorResultFor(modules,budget,statsFor){let distributor=null;for(const module of modules){const stats2=statsFor(module);if(isPowerDistributor(module,stats2)&&isEnabled(module)&&budget.available>0&&poweredStates(module,stats2,budget).retracted)distributor=module}if(!distributor)return completeResult({systemsCapacity:0,systemsRecharge:0});const stats=statsFor(distributor);const systemsCapacity=effectiveStat(distributor,"systemsCapacity",stats);const systemsRecharge=effectiveStat(distributor,"systemsRecharge",stats);return systemsCapacity===void 0||systemsRecharge===void 0?incompleteResult([metricIssue("powerDistributor","unresolved",distributor)]):completeResult({systemsCapacity:systemsCapacity,systemsRecharge:systemsRecharge})}function thrusterCurveFor(module,stats){const effective=effectiveModule(module,stats);const minMass=effective?.minMass;const optMass=effective?.optMass;const maxMass=effective?.maxMass;const minMultiplier=effective?.minMultiplier;const optMultiplier=effective?.optMultiplier;const maxMultiplier=effective?.maxMultiplier;if(minMass===void 0||optMass===void 0||maxMass===void 0||minMultiplier===void 0||optMultiplier===void 0||maxMultiplier===void 0){return null}return{minMass:minMass,optMass:optMass,maxMass:maxMass,minMultiplier:minMultiplier,optMultiplier:optMultiplier,maxMultiplier:maxMultiplier,...effective?.optSpeedMultiplier===void 0?{}:{speedCurve:{minMass:minMass,optMass:optMass,maxMass:maxMass,minMultiplier:effective.minSpeedMultiplier??minMultiplier,optMultiplier:effective.optSpeedMultiplier,maxMultiplier:effective.maxSpeedMultiplier??maxMultiplier}},...effective?.optRotationMultiplier===void 0?{}:{rotationCurve:{minMass:minMass,optMass:optMass,maxMass:maxMass,minMultiplier:effective.minRotationMultiplier??minMultiplier,optMultiplier:effective.optRotationMultiplier,maxMultiplier:effective.maxRotationMultiplier??maxMultiplier}}}}function fittedThrusterParamsFor(modules,statsFor){for(const module of modules){const stats=statsFor(module);if(isThruster(module,stats))return thrusterCurveFor(module,stats)}return null}function mobilityInputResultFor(ship,modules,getBudget,mass,statsFor){let thrusters=null;for(const module of modules){const stats=statsFor(module);if(!isThruster(module,stats))continue;const powered=poweredMetricBudgetFor("thrusters",module,stats,modules,getBudget,statsFor);if(!powered.complete)return powered;thrusters=thrusterCurveFor(module,stats);if(!thrusters)return incompleteResult([metricIssue("thrusters","unresolved",module)]);break}if(!thrusters)return incompleteResult([metricIssue("thrusters","missing")]);return completeResult({minimumSpeed:ship.minimumSpeed,maximumSpeed:ship.maximumSpeed,boost:ship.boost,minPitch:ship.minPitch,pitch:ship.pitch,minRoll:ship.minRoll,roll:ship.roll,minYaw:ship.minYaw,yaw:ship.yaw,mass:typeof mass==="function"?mass():mass,thrusters:thrusters})}function shieldRecoveryInputResultFor(ship,modules,getBudget,systemsPips,statsFor){const generator=poweredShieldGeneratorResultFor(modules,getBudget,statsFor);if(!generator.complete)return generator;const{module:generatorModule,budget:budget}=generator.value;const generatorStats=statsFor(generatorModule);const distributorDraw=effectiveStat(generatorModule,"distributorDraw",generatorStats);const regenRate=effectiveStat(generatorModule,"shieldRegenRate",generatorStats);const brokenRegenRate=effectiveStat(generatorModule,"shieldBrokenRegenRate",generatorStats);if(distributorDraw===void 0||regenRate===void 0||brokenRegenRate===void 0){return incompleteResult([metricIssue("shieldGenerator","unresolved",generatorModule)])}const capacitor=systemsCapacitorResultFor(modules,budget,statsFor);if(!capacitor.complete)return capacitor;const strength=shieldMetrics(shieldInputFor(ship,modules,budget,statsFor)).strength;return completeResult({strength:strength,regenRate:regenRate,brokenRegenRate:brokenRegenRate,distributorDraw:distributorDraw,systemsCapacity:capacitor.value.systemsCapacity,systemsRecharge:capacitor.value.systemsRecharge,systemsPips:systemsPips})}function weaponsCapacitorInputFor(modules,weaponsPips,budget,statsFor){let weaponsCapacity=0;let weaponsRecharge=0;let sustainedEnergyPerSecond=0;for(const module of modules){if(!isEnabled(module))continue;const stats=statsFor(module);if(!poweredStates(module,stats,budget).deployed)continue;if(isPowerDistributor(module,stats)){weaponsCapacity=effectiveStat(module,"weaponsCapacity",stats)??0;weaponsRecharge=effectiveStat(module,"weaponsRecharge",stats)??0}const weapon=weaponStatsFor(module,stats);if(weapon){sustainedEnergyPerSecond+=weaponMetrics(weapon).sustainedEnergyPerSecond}}return{weaponsCapacity:weaponsCapacity,weaponsRecharge:weaponsRecharge,sustainedEnergyPerSecond:sustainedEnergyPerSecond,weaponsPips:weaponsPips}}function distributorInputResultFor(modules,pips,budget,statsFor){let disabled=null;for(const module of modules){const stats=statsFor(module);if(!isPowerDistributor(module,stats))continue;if(!isEnabled(module)){disabled??=module;continue}if(!poweredStates(module,stats,budget).retracted){return incompleteResult([metricIssue("powerDistributor","shed",module)])}const systemsCapacity=effectiveStat(module,"systemsCapacity",stats);const systemsRecharge=effectiveStat(module,"systemsRecharge",stats);const enginesCapacity=effectiveStat(module,"enginesCapacity",stats);const enginesRecharge=effectiveStat(module,"enginesRecharge",stats);const weaponsCapacity=effectiveStat(module,"weaponsCapacity",stats);const weaponsRecharge=effectiveStat(module,"weaponsRecharge",stats);if(systemsCapacity===void 0||systemsRecharge===void 0||enginesCapacity===void 0||enginesRecharge===void 0||weaponsCapacity===void 0||weaponsRecharge===void 0){return incompleteResult([metricIssue("powerDistributor","unresolved",module)])}return completeResult({systemsCapacity:systemsCapacity,systemsRecharge:systemsRecharge,enginesCapacity:enginesCapacity,enginesRecharge:enginesRecharge,weaponsCapacity:weaponsCapacity,weaponsRecharge:weaponsRecharge,...pips})}return incompleteResult([disabled===null?metricIssue("powerDistributor","missing"):metricIssue("powerDistributor","disabled",disabled)])}function heatInputResultFor(ship,modules,budget,statsFor){let plant=null;let heatEfficiency;let thrusterHeatRate=0;let deployedThrusterHeatRate=0;let fsdHeatRate=0;let weaponsCapacity=0;const weapons=[];for(const module of modules){const stats=statsFor(module);if(isPowerPlant(module,stats)){if(!isEnabled(module)){return incompleteResult([metricIssue("powerCapacity","disabled",module)])}plant=module;heatEfficiency=effectiveStat(module,"heatEfficiency",stats);continue}if(!isEnabled(module))continue;const running=poweredStates(module,stats,budget);if(isThruster(module,stats)){const heat=effectiveStat(module,"engineHeatRate",stats)??0;if(running.retracted)thrusterHeatRate+=heat;if(running.deployed)deployedThrusterHeatRate+=heat}else if(isFrameShiftDrive(module,stats)){if(running.retracted)fsdHeatRate+=effectiveStat(module,"fsdHeatRate",stats)??0}else if(isPowerDistributor(module,stats)){if(running.deployed){weaponsCapacity=effectiveStat(module,"weaponsCapacity",stats)??0}}const weapon=weaponStatsFor(module,stats);if(!running.deployed)continue;if(!weapon)continue;weapons.push({heatPerSecond:weaponMetrics(weapon).sustainedHeatPerSecond,distributorDraw:weapon.distributorDraw??0})}if(heatEfficiency===void 0){return incompleteResult([plant===null?metricIssue("powerCapacity","missing"):metricIssue("heatEfficiency","unresolved",plant)])}return completeResult({heatCapacity:ship.heatCapacity,heatDissipation:ship.heatDissipation,heatEfficiency:heatEfficiency,retractedPowerDraw:poweredDraw(budget,"retracted"),deployedPowerDraw:poweredDraw(budget,"deployed"),thrusterHeatRate:thrusterHeatRate,deployedThrusterHeatRate:deployedThrusterHeatRate,fsdHeatRate:fsdHeatRate,weaponsCapacity:weaponsCapacity,weapons:weapons})}function poweredDraw(budget,state){const powered=state==="retracted"?"poweredRetracted":"poweredDeployed";return budget.bands.reduce((total,band)=>band[powered]?total+band[state]:total,0)}function poweredStates(module,stats,budget){const draw=effectiveStat(module,"powerDraw",stats);if(draw===void 0||draw===0)return{retracted:true,deployed:true};const band=budget.bands[Math.min(budget.bands.length,Math.max(1,priorityOf(module)))-1];if(!band)return{retracted:true,deployed:true};return{retracted:band.poweredRetracted,deployed:band.poweredDeployed}}function cellBankInputsFor(modules,budget,statsFor){const banks=[];for(const module of modules){if(!startsWithAny(module.Item,PREFIX.shieldCellBank))continue;const stats=statsFor(module);const effective=effectiveModule(module,stats);const ammunition=effective?ammunitionCapacity(effective):null;banks.push({slot:module.Slot,symbol:module.Item,reinforcementRate:effective?.shieldBankReinforcement??0,cells:ammunition?.total??0,spinUp:effective?.shieldBankSpinUp??0,duration:effective?.shieldBankDuration??0,heat:effective?.shieldBankHeat??0,powered:budget.available>0&&isEnabled(module)&&poweredStates(module,stats,budget).deployed})}return banks}function stockBulkhead(ship){const variants=getBulkheadsForShip(ship.name,CORE_MODULES);return variants.find(v=>v.symbol.toLowerCase().endsWith("_default"))??variants.find(v=>v.mass===0)??variants[0]??null}function armourInputFor(ship,modules,statsFor){const reinforcements=[];const moduleReinforcements=[];let bulkhead=null;for(const module of modules){if(!isEnabled(module))continue;const stats=statsFor(module);if(module.Slot.toLowerCase()==="armour"){bulkhead={hullBoost:effectiveStat(module,"hullBoost",stats)??0,...resistancesOf(module,stats)}}else if(startsWithAny(module.Item,PREFIX.hullReinforcement)){const boost=getLoadoutModifier(module,"DefenceModifierHealthMultiplier");reinforcements.push({hullReinforcement:effectiveStat(module,"hullReinforcement",stats)??0,hullBoost:boost===null?0:boost/scaleForLabel("DefenceModifierHealthMultiplier"),...resistancesOf(module,stats)})}else if(startsWithAny(module.Item,PREFIX.moduleReinforcement)){moduleReinforcements.push({moduleProtection:effectiveStat(module,"moduleProtection",stats)??0,integrity:effectiveStat(module,"integrity",stats)??0})}}if(!bulkhead){const stock=stockBulkhead(ship);bulkhead=stock?{hullBoost:stock.hullBoost??0,...mapResistanceFields(field=>stock[field])}:null}return{baseArmour:ship.baseArmour,bulkhead:bulkhead,reinforcements:reinforcements,moduleReinforcements:moduleReinforcements}}var WEAPON_FIELDS=["damage","roundsPerShot","rateOfFire","burstInterval","burstRounds","burstRateOfFire","chargeTime","clipSize","ammoMaximum","reloadTime","distributorDraw","thermalLoad","powerDraw","maximumRange","falloffRange","armourPiercing"];function weaponStatsFor(module,stats){if(!stats||stats.category!=="hardpoint")return null;const weapon={};for(const field of WEAPON_FIELDS){const value=effectiveStat(module,field,stats);if(value!==void 0)weapon[field]=value}normalizeEffectiveWeapon(module,weapon);const damageDistribution=effectiveDamageDistribution(module,stats);if(damageDistribution)weapon.damageDistribution=damageDistribution;if(stats.damageComponents&&!convertsDamage(module)){weapon.damageComponents=scaleDamageComponents(stats.damageComponents,stats.damage,typeof weapon.damage==="number"?weapon.damage:void 0)}if(stats.projectileRange)weapon.projectileRange={...stats.projectileRange};return weapon}function burstAdjustedRateOfFire(module,weapon){if(getLoadoutModifier(module,"RateOfFire")!==null)return void 0;const modifiers=module.Engineering?.Modifiers;const touched=BURST_PATTERN_LABELS.some(label=>getLoadoutModifier(module,label)!==null);if(!touched)return void 0;const stated=(label,field)=>preciseValueFor(modifiers,label)??weapon[field];return journalRateOfFire(stated("BurstInterval","burstInterval"),stated("BurstSize","burstRounds"),stated("BurstRateOfFire","burstRateOfFire"))}var FIRING_RATE_LABELS=["RateOfFire","BurstRateOfFire","BurstSize","BurstInterval","RoundsPerShot","Rounds"];function readsDamageFromPerSecond(module){return getLoadoutModifier(module,"Damage")===null&&FIRING_RATE_LABELS.every(label=>getLoadoutModifier(module,label)===null)}function normalizeEffectiveWeapon(module,weapon){const rate=burstAdjustedRateOfFire(module,weapon);if(rate!==void 0)weapon.rateOfFire=rate;if(readsDamageFromPerSecond(module)){const statedDamagePerSecond=getLoadoutModifier(module,"DamagePerSecond");const firingFactor=Number(weapon.roundsPerShot??1)*Number(weapon.rateOfFire??1);if(statedDamagePerSecond!==null&&firingFactor>0){weapon.damage=statedDamagePerSecond/firingFactor}}const{maximumRange:maximumRange,falloffRange:falloffRange}=weapon;if(maximumRange!==void 0&&falloffRange!==void 0&&falloffRange>maximumRange){weapon.falloffRange=maximumRange}}var INTERNALS=/* @__PURE__ */new WeakMap;function publishLoadoutInternals(build,internals){INTERNALS.set(build,internals)}function loadoutInternals(build,label){const internals=typeof build==="object"&&build!==null?INTERNALS.get(build):void 0;if(internals===void 0){throw new TypeError(`${label} must be a ShipLoadout, received ${describeValue(build)}`)}return internals}export{armourInputFor,cellBankInputsFor,completeResult,distributorInputResultFor,effectiveModule,fittedThrusterParamsFor,heatInputResultFor,incompleteResult,loadoutInternals,mobilityInputResultFor,moduleFitError,moduleFitProblem,normalizeLoadoutEvent,powerAvailable,powerConsumerFor,preEngineeredVariantFor,publishLoadoutInternals,shieldCapacitorInputResultFor,shieldInputResultFor,shieldRecoveryInputResultFor,weaponStatsFor,weaponsCapacitorInputFor};//# sourceMappingURL=chunk-U4MML7U6.js.map
@@ -8,7 +8,7 @@ import { Commodity } from './commodities.js';
8
8
  * live in `./commodities-standard`. Search it with the query functions in
9
9
  * `./commodities`.
10
10
  *
11
- * Data from EDCD FDevIDs (`rare_commodity.csv`); see [`data/commodities/SOURCES.md`](https://github.com/DarkSession/Elite-Dangerous-Almanac/blob/main/data/commodities/SOURCES.md).
11
+ * Data from EDCD FDevIDs (`rare_commodity.csv`); see [`data/commodities/SOURCES.md`](https://github.com/Elite-Dangerous-Almanac/Almanac-Core/blob/main/data/commodities/SOURCES.md).
12
12
  *
13
13
  * @packageDocumentation
14
14
  */
@@ -11,7 +11,7 @@ import { Commodity } from './commodities.js';
11
11
  * in-game category check, and from two readings of the running game's own commodity
12
12
  * registry, whose difference is a batch of mineral, metal and chemical goods the FDevIDs
13
13
  * snapshot does not carry; see
14
- * [`data/commodities/SOURCES.md`](https://github.com/DarkSession/Elite-Dangerous-Almanac/blob/main/data/commodities/SOURCES.md).
14
+ * [`data/commodities/SOURCES.md`](https://github.com/Elite-Dangerous-Almanac/Almanac-Core/blob/main/data/commodities/SOURCES.md).
15
15
  *
16
16
  * @packageDocumentation
17
17
  */
@@ -51,7 +51,7 @@ interface PersonalModification {
51
51
  * weapon's two reload times are on its own `reloadTime`. Faster Handling, Improved
52
52
  * Hip Fire Accuracy, Stability and Improved Jump Assist do change stats, ones the
53
53
  * personal stats panel does not put a number on; see
54
- * [`data/equipment/SOURCES.md`](https://github.com/DarkSession/Elite-Dangerous-Almanac/blob/main/data/equipment/SOURCES.md).
54
+ * [`data/equipment/SOURCES.md`](https://github.com/Elite-Dangerous-Almanac/Almanac-Core/blob/main/data/equipment/SOURCES.md).
55
55
  */
56
56
  readonly modifiers: readonly PersonalModifier[];
57
57
  }
@@ -11,8 +11,8 @@
11
11
  * GALAXY_MAP_MARKERS[0].symbol; // -> 'bookmark'
12
12
  * ```
13
13
  *
14
- * A symbol also names the marker's vector asset, so a consumer that ships the
15
- * shared `assets/galaxy-map/` directory builds the path from the same string:
14
+ * A symbol also names the marker's vector asset, which the package carries under
15
+ * `assets/galaxy-map/`, so one string gives both the colour and the file:
16
16
  *
17
17
  * ```ts
18
18
  * import { getGalaxyMapMarker } from '@elite-dangerous-almanac/core/galaxy-map';
@@ -27,6 +27,13 @@
27
27
  * colour. `front-line.svg` is the exception: its frame holds the literal
28
28
  * {@link GalaxyMapMarker.frameColor}, which no `color` declaration reaches.
29
29
  *
30
+ * A marker is safe to embed inline as supplied: it holds only static `svg`, `title`,
31
+ * `defs`, `mask`, `filter`, `feGaussianBlur`, `g`, `use`, `path`, `rect`, `circle` and
32
+ * `ellipse` elements, and every `href`, `mask` and `filter` points inside the same
33
+ * file. There are no scripts, styles, event-handler attributes, foreign or media
34
+ * elements, links or external references. Every definition id is unique across the
35
+ * set, so a page can inline all of them.
36
+ *
30
37
  * The catalogue carries no display name. Each asset's `<title>` holds the English
31
38
  * label, which is also what a screen reader announces for an inline-embedded marker.
32
39
  *
@@ -6,7 +6,7 @@
6
6
  * whose root `<svg>` carries the same `color` this catalogue reports.
7
7
  *
8
8
  * Read from the in-game galaxy map; see
9
- * [ATTRIBUTIONS.md](https://github.com/DarkSession/Elite-Dangerous-Almanac/blob/main/ATTRIBUTIONS.md)
9
+ * [ATTRIBUTIONS.md](https://github.com/Elite-Dangerous-Almanac/Almanac-Core/blob/main/ATTRIBUTIONS.md)
10
10
  * for credit and licence terms.
11
11
  *
12
12
  * @packageDocumentation
@@ -22,7 +22,7 @@
22
22
  * most datasets are complete in every locale, while the outfitting families the game
23
23
  * does not name separately have no locale at all. Plan fallback per
24
24
  * lookup rather than per application. The table is generated from the
25
- * [`data/i18n/` catalogues](https://github.com/DarkSession/Elite-Dangerous-Almanac/tree/main/data/i18n),
25
+ * [`data/i18n/` catalogues](https://github.com/Elite-Dangerous-Almanac/Almanac-Core/tree/main/data/i18n),
26
26
  * so it moves when the data does.
27
27
  *
28
28
  * <!-- generated by scripts/i18n-coverage.mjs -->
@@ -1 +1 @@
1
- export{getLoadoutSlotName,getSlotRestrictionLabel}from"../chunk-ZRG35JSH.js"; export{getPersonalMountName,getSuitDescription,getSuitName}from"../chunk-RA4YJBU5.js";export{getMaterialName}from"../chunk-UE22QU7A.js";export{getMicroResourceName}from"../chunk-WZIBBJHA.js";export{getOutfittingFamilyName}from"../chunk-YBE5M27G.js";export{getModuleName}from"../chunk-URRPEUIK.js";export{getPersonalModificationDescription,getPersonalModificationName}from"../chunk-SS7HVNP5.js";export{getPersonalToolName}from"../chunk-E2HDF6PJ.js";export{getPersonalWeaponDescription}from"../chunk-7C7NJWCF.js";export{getPreEngineeredVariantName}from"../chunk-FRG7MKSJ.js";export{getBlueprintName}from"../chunk-KR664YI3.js";export{getCodexRegionName}from"../chunk-O4NIJDL4.js";export{getCommodityName}from"../chunk-TRGHPX2O.js";export{getCalculationIssueMessage,getLoadoutEditErrorMessage,getLoadoutIssueMessage,getSlefDiagnosticMessage}from"../chunk-6G6TYW2D.js";export{getExperimentalEffectDescription}from"../chunk-RJ3ZLQRB.js";export{getExperimentalEffectName}from"../chunk-QPT2WJYN.js"; //# sourceMappingURL=index.js.map
1
+ export{getLoadoutSlotName,getSlotRestrictionLabel}from"../chunk-ZRG35JSH.js"; export{getPersonalMountName,getSuitDescription,getSuitName}from"../chunk-F53MPXZY.js";export{getMaterialName}from"../chunk-UE22QU7A.js";export{getMicroResourceName}from"../chunk-WZIBBJHA.js";export{getOutfittingFamilyName}from"../chunk-YBE5M27G.js";export{getModuleName}from"../chunk-URRPEUIK.js";export{getPersonalModificationDescription,getPersonalModificationName}from"../chunk-SS7HVNP5.js";export{getPersonalToolName}from"../chunk-E2HDF6PJ.js";export{getPersonalWeaponDescription}from"../chunk-7C7NJWCF.js";export{getPreEngineeredVariantName}from"../chunk-FRG7MKSJ.js";export{getBlueprintName}from"../chunk-KR664YI3.js";export{getCodexRegionName}from"../chunk-O4NIJDL4.js";export{getCommodityName}from"../chunk-TRGHPX2O.js";export{getCalculationIssueMessage,getLoadoutEditErrorMessage,getLoadoutIssueMessage,getSlefDiagnosticMessage}from"../chunk-6G6TYW2D.js";export{getExperimentalEffectDescription}from"../chunk-RJ3ZLQRB.js";export{getExperimentalEffectName}from"../chunk-QPT2WJYN.js"; //# sourceMappingURL=index.js.map
@@ -12,9 +12,9 @@
12
12
  * @remarks
13
13
  * Every module carries a family, so an outfitting list can group and label every choice
14
14
  * `ShipLoadout.modulesForSlot()` returns from this lookup alone. The table bundles no
15
- * module stats. Missing translations never silently fall back to English: some
16
- * families have no source-backed label in any locale, tracked by
17
- * [#320](https://github.com/DarkSession/Elite-Dangerous-Almanac/issues/320).
15
+ * module stats. Missing translations never silently fall back to English: a family the
16
+ * game does not name separately in its outfitting menu carries its canonical English
17
+ * alone, until a source publishes the other five locales.
18
18
  * @throws {TypeError} If `familyId` is present and not a string, or `locale` is not a
19
19
  * string. A nullish `familyId` is a lookup miss and returns `null`.
20
20
  * @example
@@ -72,8 +72,7 @@ declare function getSuitDescription(suit: string, locale: string): string | null
72
72
  * The label reads the Frontier journal `SlotName` the mount carries, so it distinguishes
73
73
  * a suit's primary mounts from each other. A consumer needs no table of its own.
74
74
  *
75
- * No locale but English answers, although the game itself publishes all six:
76
- * https://github.com/DarkSession/Elite-Dangerous-Almanac/issues/26
75
+ * No locale but English answers, although the game itself publishes all six.
77
76
  * @example
78
77
  * ```ts
79
78
  * import { getSuitByFamily } from '@elite-dangerous-almanac/core/equipment/suits';
@@ -1 +1 @@
1
- export{getPersonalMountName,getSuitDescription,getSuitName}from"../chunk-RA4YJBU5.js"; //# sourceMappingURL=suits.js.map
1
+ export{getPersonalMountName,getSuitDescription,getSuitName}from"../chunk-F53MPXZY.js"; //# sourceMappingURL=suits.js.map
@@ -8,7 +8,7 @@ import { Material } from './materials.js';
8
8
  * Search it with the query functions in `./materials`.
9
9
  *
10
10
  * Data from EDCD FDevIDs, with Thargoid materials absent from that pinned source
11
- * graded by INARA; see [`data/materials/SOURCES.md`](https://github.com/DarkSession/Elite-Dangerous-Almanac/blob/main/data/materials/SOURCES.md).
11
+ * graded by INARA; see [`data/materials/SOURCES.md`](https://github.com/Elite-Dangerous-Almanac/Almanac-Core/blob/main/data/materials/SOURCES.md).
12
12
  *
13
13
  * @packageDocumentation
14
14
  */
@@ -8,7 +8,7 @@ import { Material } from './materials.js';
8
8
  * Search it with the query functions in `./materials`.
9
9
  *
10
10
  * Data from EDCD FDevIDs, with Thargoid materials absent from that pinned source
11
- * graded by INARA; see [`data/materials/SOURCES.md`](https://github.com/DarkSession/Elite-Dangerous-Almanac/blob/main/data/materials/SOURCES.md).
11
+ * graded by INARA; see [`data/materials/SOURCES.md`](https://github.com/Elite-Dangerous-Almanac/Almanac-Core/blob/main/data/materials/SOURCES.md).
12
12
  *
13
13
  * @packageDocumentation
14
14
  */
@@ -7,7 +7,7 @@ import { Material } from './materials.js';
7
7
  * Each line is named after its grade-1 element: Carbon, Phosphorus, Sulphur, Iron,
8
8
  * Nickel, Rhenium, Lead. Search it with the query functions in `./materials`.
9
9
  *
10
- * Data from EDCD FDevIDs; see [`data/materials/SOURCES.md`](https://github.com/DarkSession/Elite-Dangerous-Almanac/blob/main/data/materials/SOURCES.md).
10
+ * Data from EDCD FDevIDs; see [`data/materials/SOURCES.md`](https://github.com/Elite-Dangerous-Almanac/Almanac-Core/blob/main/data/materials/SOURCES.md).
11
11
  *
12
12
  * @packageDocumentation
13
13
  */
@@ -45,7 +45,7 @@
45
45
  * one is `.filter()` on the result or on the subset you already imported.
46
46
  *
47
47
  * Data originates from EDCD FDevIDs, with Thargoid materials absent from that
48
- * pinned source supplied by INARA; see [`data/materials/SOURCES.md`](https://github.com/DarkSession/Elite-Dangerous-Almanac/blob/main/data/materials/SOURCES.md).
48
+ * pinned source supplied by INARA; see [`data/materials/SOURCES.md`](https://github.com/Elite-Dangerous-Almanac/Almanac-Core/blob/main/data/materials/SOURCES.md).
49
49
  *
50
50
  * @example
51
51
  * ```ts
@@ -6,7 +6,7 @@ import { MicroResource } from './micro-resources.js';
6
6
  *
7
7
  * Search it with the query functions in `./micro-resources`.
8
8
  *
9
- * Data from EDCD FDevIDs (`microresources.csv`); see [`data/materials/SOURCES.md`](https://github.com/DarkSession/Elite-Dangerous-Almanac/blob/main/data/materials/SOURCES.md).
9
+ * Data from EDCD FDevIDs (`microresources.csv`); see [`data/materials/SOURCES.md`](https://github.com/Elite-Dangerous-Almanac/Almanac-Core/blob/main/data/materials/SOURCES.md).
10
10
  *
11
11
  * @packageDocumentation
12
12
  */
@@ -6,7 +6,7 @@ import { MicroResource } from './micro-resources.js';
6
6
  *
7
7
  * Search it with the query functions in `./micro-resources`.
8
8
  *
9
- * Data from EDCD FDevIDs (`microresources.csv`); see [`data/materials/SOURCES.md`](https://github.com/DarkSession/Elite-Dangerous-Almanac/blob/main/data/materials/SOURCES.md).
9
+ * Data from EDCD FDevIDs (`microresources.csv`); see [`data/materials/SOURCES.md`](https://github.com/Elite-Dangerous-Almanac/Almanac-Core/blob/main/data/materials/SOURCES.md).
10
10
  *
11
11
  * @packageDocumentation
12
12
  */
@@ -6,7 +6,7 @@ import { MicroResource } from './micro-resources.js';
6
6
  *
7
7
  * Search it with the query functions in `./micro-resources`.
8
8
  *
9
- * Data from EDCD FDevIDs (`microresources.csv`), in-game verification and Inara; see [`data/materials/SOURCES.md`](https://github.com/DarkSession/Elite-Dangerous-Almanac/blob/main/data/materials/SOURCES.md).
9
+ * Data from EDCD FDevIDs (`microresources.csv`), in-game verification and Inara; see [`data/materials/SOURCES.md`](https://github.com/Elite-Dangerous-Almanac/Almanac-Core/blob/main/data/materials/SOURCES.md).
10
10
  *
11
11
  * @packageDocumentation
12
12
  */
@@ -6,7 +6,7 @@ import { MicroResource } from './micro-resources.js';
6
6
  *
7
7
  * Search it with the query functions in `./micro-resources`.
8
8
  *
9
- * Data from EDCD FDevIDs (`microresources.csv`) and in-game verification; see [`data/materials/SOURCES.md`](https://github.com/DarkSession/Elite-Dangerous-Almanac/blob/main/data/materials/SOURCES.md).
9
+ * Data from EDCD FDevIDs (`microresources.csv`) and in-game verification; see [`data/materials/SOURCES.md`](https://github.com/Elite-Dangerous-Almanac/Almanac-Core/blob/main/data/materials/SOURCES.md).
10
10
  *
11
11
  * @packageDocumentation
12
12
  */
@@ -43,7 +43,7 @@
43
43
  * narrowing it is `.filter()` on the result or on the subset you already imported.
44
44
  *
45
45
  * Data originates from EDCD FDevIDs (`microresources.csv`), in-game verification and
46
- * Inara; see [`data/materials/SOURCES.md`](https://github.com/DarkSession/Elite-Dangerous-Almanac/blob/main/data/materials/SOURCES.md).
46
+ * Inara; see [`data/materials/SOURCES.md`](https://github.com/Elite-Dangerous-Almanac/Almanac-Core/blob/main/data/materials/SOURCES.md).
47
47
  *
48
48
  * @example
49
49
  * ```ts
@@ -21,7 +21,7 @@ import { DamageResistanceParams, DamageResistances, DamageTypeValues } from './r
21
21
  * @remarks
22
22
  * Reference implementation: EDCD/Coriolis, `src/app/shipyard/Calculations.js`
23
23
  * (`armourMetrics`), commit `68c042ca6e3db62372cbbb2077cf972345511712`. The algorithm
24
- * is ported as fact, not code; credit and licence terms are in [ATTRIBUTIONS.md](https://github.com/DarkSession/Elite-Dangerous-Almanac/blob/main/ATTRIBUTIONS.md).
24
+ * is ported as fact, not code; credit and licence terms are in [ATTRIBUTIONS.md](https://github.com/Elite-Dangerous-Almanac/Almanac-Core/blob/main/ATTRIBUTIONS.md).
25
25
  *
26
26
  * @example
27
27
  * ```ts
@@ -19,7 +19,7 @@ import './slots.js';
19
19
  *
20
20
  * Data from EDCD/coriolis-data (`modifications/blueprints.json`), with Operations and
21
21
  * Anti-Guardian recipes from the Inara registry and Frontier update notes; see
22
- * [`data/ships/SOURCES.md`](https://github.com/DarkSession/Elite-Dangerous-Almanac/blob/main/data/ships/SOURCES.md).
22
+ * [`data/ships/SOURCES.md`](https://github.com/Elite-Dangerous-Almanac/Almanac-Core/blob/main/data/ships/SOURCES.md).
23
23
  *
24
24
  * @packageDocumentation
25
25
  */
@@ -29,7 +29,7 @@
29
29
  * The clip penalty is folded only where a module's menu offers the multi-cannon recipe —
30
30
  * anti-xeno multi-cannons have no ordinary menu, and cannons, fragment cannons and plasma
31
31
  * accelerators take no clip leg. See
32
- * [`data/ships/SOURCES.md`](https://github.com/DarkSession/Elite-Dangerous-Almanac/blob/main/data/ships/SOURCES.md)
32
+ * [`data/ships/SOURCES.md`](https://github.com/Elite-Dangerous-Almanac/Almanac-Core/blob/main/data/ships/SOURCES.md)
33
33
  * § "Multi-cannon Overcharged" for the captures.
34
34
  *
35
35
  * Only the module can settle it, which is why this takes one, and it resolves **into** a
@@ -42,7 +42,7 @@ import './slots.js';
42
42
  *
43
43
  * Data from EDCD/coriolis-data (`modifications/blueprints.json`): `features` from the
44
44
  * grade with journal Labels resolved via EDSY; see
45
- * [`data/ships/SOURCES.md`](https://github.com/DarkSession/Elite-Dangerous-Almanac/blob/main/data/ships/SOURCES.md).
45
+ * [`data/ships/SOURCES.md`](https://github.com/Elite-Dangerous-Almanac/Almanac-Core/blob/main/data/ships/SOURCES.md).
46
46
  *
47
47
  * @packageDocumentation
48
48
  */
@@ -1 +1 @@
1
- export{BuildMetrics}from"../chunk-S4BZ64WE.js"; //# sourceMappingURL=build-metrics.js.map
1
+ export{BuildMetrics}from"../chunk-N4YDIODB.js"; //# sourceMappingURL=build-metrics.js.map
@@ -8,7 +8,7 @@
8
8
  *
9
9
  * Stock builds come from EDSY, with coriolis-data and captured Frontier journal
10
10
  * loadouts supplying or corroborating the advanced planetary approach suite and cargo
11
- * hatches; see [`data/ships/SOURCES.md`](https://github.com/DarkSession/Elite-Dangerous-Almanac/blob/main/data/ships/SOURCES.md).
11
+ * hatches; see [`data/ships/SOURCES.md`](https://github.com/Elite-Dangerous-Almanac/Almanac-Core/blob/main/data/ships/SOURCES.md).
12
12
  *
13
13
  * @packageDocumentation
14
14
  */
@@ -11,7 +11,7 @@
11
11
  * @remarks
12
12
  * The SYS and WEP curves follow EDCD/Coriolis; the ENG curve is cross-checked
13
13
  * against EDSY's boost-frequency calculation. Credit and licence terms are in
14
- * [ATTRIBUTIONS.md](https://github.com/DarkSession/Elite-Dangerous-Almanac/blob/main/ATTRIBUTIONS.md).
14
+ * [ATTRIBUTIONS.md](https://github.com/Elite-Dangerous-Almanac/Almanac-Core/blob/main/ATTRIBUTIONS.md).
15
15
  *
16
16
  * @packageDocumentation
17
17
  */
@@ -68,7 +68,7 @@ interface BlueprintFeature {
68
68
  * These are the journal's own labels, with one deliberate exception: the recipes
69
69
  * that shorten a weapon's fire interval carry `"BurstInterval"`, the stat they
70
70
  * change, where a journal reports the resulting `"RateOfFire"` instead. See
71
- * [`data/ships/SOURCES.md`](https://github.com/DarkSession/Elite-Dangerous-Almanac/blob/main/data/ships/SOURCES.md).
71
+ * [`data/ships/SOURCES.md`](https://github.com/Elite-Dangerous-Almanac/Almanac-Core/blob/main/data/ships/SOURCES.md).
72
72
  * `"GuardianModuleResistance"` is the other non-scalar case: it grants the
73
73
  * `guardianZoneResistance` capability, and its displayed bounds are not arithmetic.
74
74
  */
@@ -14,7 +14,7 @@ import './slots.js';
14
14
  * `ships/experimental-effects`.
15
15
  *
16
16
  * Data from EDSY (`eddb.js` `expeffect`), with combat-effect costs from the Inara
17
- * registry; see [`data/ships/SOURCES.md`](https://github.com/DarkSession/Elite-Dangerous-Almanac/blob/main/data/ships/SOURCES.md).
17
+ * registry; see [`data/ships/SOURCES.md`](https://github.com/Elite-Dangerous-Almanac/Almanac-Core/blob/main/data/ships/SOURCES.md).
18
18
  *
19
19
  * @packageDocumentation
20
20
  */
@@ -23,7 +23,7 @@ import './slots.js';
23
23
  * display names. Enumerate the available effects with `Object.keys(EXPERIMENTAL_EFFECTS)`.
24
24
  *
25
25
  * Data from EDSY (`eddb.js` `expeffect`) — coriolis-data does not carry the numeric
26
- * experimental modifiers; see [`data/ships/SOURCES.md`](https://github.com/DarkSession/Elite-Dangerous-Almanac/blob/main/data/ships/SOURCES.md).
26
+ * experimental modifiers; see [`data/ships/SOURCES.md`](https://github.com/Elite-Dangerous-Almanac/Almanac-Core/blob/main/data/ships/SOURCES.md).
27
27
  *
28
28
  * @packageDocumentation
29
29
  */
@@ -7,7 +7,7 @@
7
7
  * tangents suitable for a renderer.
8
8
  *
9
9
  * The offsets are observed in-game; see
10
- * [`data/ships/SOURCES.md`](https://github.com/DarkSession/Elite-Dangerous-Almanac/blob/main/data/ships/SOURCES.md).
10
+ * [`data/ships/SOURCES.md`](https://github.com/Elite-Dangerous-Almanac/Almanac-Core/blob/main/data/ships/SOURCES.md).
11
11
  *
12
12
  * @packageDocumentation
13
13
  */
@@ -45,9 +45,9 @@
45
45
  * the model was reverse-engineered in. Frontier publishes no heat formula and shows a
46
46
  * player no dissipation figure, so both the model and the per-hull `heatDissipation` it
47
47
  * reads are community measurements of the game rather than stats the game states — see
48
- * [data/ships/SOURCES.md](https://github.com/DarkSession/Elite-Dangerous-Almanac/blob/main/data/ships/SOURCES.md).
48
+ * [data/ships/SOURCES.md](https://github.com/Elite-Dangerous-Almanac/Almanac-Core/blob/main/data/ships/SOURCES.md).
49
49
  * The algorithm is ported as fact, not code; credit and licence terms are in
50
- * [ATTRIBUTIONS.md](https://github.com/DarkSession/Elite-Dangerous-Almanac/blob/main/ATTRIBUTIONS.md).
50
+ * [ATTRIBUTIONS.md](https://github.com/Elite-Dangerous-Almanac/Almanac-Core/blob/main/ATTRIBUTIONS.md).
51
51
  *
52
52
  * @example
53
53
  * ```ts
@@ -88,7 +88,7 @@
88
88
  *
89
89
  * Identity primarily from EDCD FDevIDs (`shipyard.csv`, `outfitting.csv`), with
90
90
  * supplemental module identities documented in the source record; stats and slot
91
- * layouts from EDCD/coriolis-data and EDSY. See [`data/ships/SOURCES.md`](https://github.com/DarkSession/Elite-Dangerous-Almanac/blob/main/data/ships/SOURCES.md).
91
+ * layouts from EDCD/coriolis-data and EDSY. See [`data/ships/SOURCES.md`](https://github.com/Elite-Dangerous-Almanac/Almanac-Core/blob/main/data/ships/SOURCES.md).
92
92
  *
93
93
  * @example
94
94
  * **The whole-build layer.** {@link ShipLoadout} reads a capture and answers the
@@ -1 +1 @@
1
- export{LoadoutEditError,ShipLoadout}from"../chunk-P5SIDTV5.js";export{hasFrameShiftDriveJumpStats,hasMassCurveStats,hasPowerDistributorStats,hasPowerGenerationStats,hasShieldRegenerationStats,hasWeaponDamageStats}from"../chunk-JTQVWIGL.js";export{OUTFITTING_FAMILIES}from"../chunk-M6G3UDTX.js";export{SHIP_GUNSIGHTS,getShipGunsight,projectGunsight}from"../chunk-XSN53F7W.js";export{validateLoadout}from"../chunk-T6BIFKPU.js";export{SHIP_MODULE_LIMITS,calculateModuleLimits}from"../chunk-KPETDYQX.js";export{BuildMetrics}from"../chunk-S4BZ64WE.js";export{cellBankSummary,shieldRecovery}from"../chunk-JMAXSXXQ.js"; export{armourPiercingFactor,combinedRateOfFire,damageFalloff,damagePerSecond,energyPerSecond,heatPerSecond,splitDamage,sumWeaponMetrics,sustainedDamagePerSecond,sustainedFireFactor,weaponMetrics}from"../chunk-Z266X4JF.js";export{shieldMassCurveMultiplier,shieldMetrics,shieldStrength}from"../chunk-SRPCHXW2.js";export{SHIPS,getShipByName,getShipBySymbol,getShipSlots}from"../chunk-C4FUV6GF.js";export{getLoadoutModifier,inspectSlef,parseSlef,stringifySlef,toSlef}from"../chunk-T4MKUKYS.js";export{getSourceModuleValue,sourcePurchaseFromLoadout,sumSourceModuleValues}from"../chunk-NIURLW2F.js";export{weaponsCapacitorMetrics}from"../chunk-M4FZRDAH.js";export{powerBudget}from"../chunk-GGQMIQPC.js";export{getPreEngineeredJournalModifiers,getPreEngineeredModifiers,getPreEngineeredStats,identifyPreEngineeredVariant,unresolvedModifiers}from"../chunk-QNHGTVMZ.js";export{getBulkheadsForShip,getModuleBySymbol,getModulesByName}from"../chunk-FMPHK3L5.js";export{PRE_ENGINEERED_MODULES,getPreEngineeredVariants,isPreEngineered}from"../chunk-EXHZ4CFB.js";export{shieldCapacitorMetrics}from"../chunk-HWOP7QWK.js";export{mobilityCapacitorMetrics}from"../chunk-VEEBJFJ7.js";export{mobilityMetrics,thrusterMassCurveMultiplier}from"../chunk-A4QKXXZD.js"; export{EXPERIMENTAL_EFFECTS,getExperimentalEffect}from"../chunk-77I24V6B.js";export{OVERHEAT_HEAT_LEVEL,effectiveWeaponThermalLoad,equilibriumHeatLevel,heatLevelAtTime,heatMetrics,secondsToHeatLevel}from"../chunk-6HA2YIKW.js";export{frameShiftDriveMassFactor,fuelPerJump,singleJumpRange,totalRange}from"../chunk-VTMCSCXV.js";export{calculateCargoCapacity,calculateFuelCapacity,calculatePassengerCapacity,calculateUnladenMass}from"../chunk-C3LLPLLD.js"; export{resolveBlueprintForModule}from"../chunk-2J6NNI3Y.js";export{BLUEPRINTS,getBlueprint,getBlueprintGrade}from"../chunk-WDAYRHXR.js"; export{distributorMetrics}from"../chunk-M2TCZKRT.js"; export{ENGINEERING_OPTION_GROUPS,getBlueprintsForModule,getEngineeringGroup,getExperimentalsForBlueprint,getExperimentalsForModule}from"../chunk-M4STXLXO.js";export{computeModifiers,sumMaterials}from"../chunk-U73MBQ45.js"; export{ammunitionCapacity}from"../chunk-AA3K5XUE.js";export{armourMetrics}from"../chunk-3I2I5KG4.js";export{effectiveHitPoints,mapDamageTypes,stackArmourResistance,stackShieldResistance,systemsResistance}from"../chunk-Q75JSMU6.js"; export{SLOT_RESTRICTION_LABELS,enumerateSlots,parseSlotName}from"../chunk-RAO35XDF.js"; //# sourceMappingURL=index.js.map
1
+ export{LoadoutEditError,ShipLoadout}from"../chunk-JQ4OPZZ4.js";export{hasFrameShiftDriveJumpStats,hasMassCurveStats,hasPowerDistributorStats,hasPowerGenerationStats,hasShieldRegenerationStats,hasWeaponDamageStats}from"../chunk-JTQVWIGL.js";export{OUTFITTING_FAMILIES}from"../chunk-M6G3UDTX.js";export{SHIP_GUNSIGHTS,getShipGunsight,projectGunsight}from"../chunk-XSN53F7W.js";export{validateLoadout}from"../chunk-T6BIFKPU.js";export{SHIP_MODULE_LIMITS,calculateModuleLimits}from"../chunk-KPETDYQX.js";export{BuildMetrics}from"../chunk-N4YDIODB.js";export{cellBankSummary,shieldRecovery}from"../chunk-JMAXSXXQ.js"; export{armourPiercingFactor,combinedRateOfFire,damageFalloff,damagePerSecond,energyPerSecond,heatPerSecond,splitDamage,sumWeaponMetrics,sustainedDamagePerSecond,sustainedFireFactor,weaponMetrics}from"../chunk-Z266X4JF.js";export{shieldMassCurveMultiplier,shieldMetrics,shieldStrength}from"../chunk-SRPCHXW2.js";export{SHIPS,getShipByName,getShipBySymbol,getShipSlots}from"../chunk-C4FUV6GF.js";export{getLoadoutModifier,inspectSlef,parseSlef,stringifySlef,toSlef}from"../chunk-T4MKUKYS.js";export{getSourceModuleValue,sourcePurchaseFromLoadout,sumSourceModuleValues}from"../chunk-NIURLW2F.js";export{weaponsCapacitorMetrics}from"../chunk-M4FZRDAH.js";export{powerBudget}from"../chunk-GGQMIQPC.js";export{getPreEngineeredJournalModifiers,getPreEngineeredModifiers,getPreEngineeredStats,identifyPreEngineeredVariant,unresolvedModifiers}from"../chunk-LLLFK3D5.js";export{getBulkheadsForShip,getModuleBySymbol,getModulesByName}from"../chunk-FMPHK3L5.js";export{PRE_ENGINEERED_MODULES,getPreEngineeredVariants,isPreEngineered}from"../chunk-EE25IDB7.js";export{shieldCapacitorMetrics}from"../chunk-HWOP7QWK.js";export{mobilityCapacitorMetrics}from"../chunk-VEEBJFJ7.js";export{mobilityMetrics,thrusterMassCurveMultiplier}from"../chunk-A4QKXXZD.js"; export{EXPERIMENTAL_EFFECTS,getExperimentalEffect}from"../chunk-77I24V6B.js";export{OVERHEAT_HEAT_LEVEL,effectiveWeaponThermalLoad,equilibriumHeatLevel,heatLevelAtTime,heatMetrics,secondsToHeatLevel}from"../chunk-6HA2YIKW.js";export{frameShiftDriveMassFactor,fuelPerJump,singleJumpRange,totalRange}from"../chunk-VTMCSCXV.js";export{calculateCargoCapacity,calculateFuelCapacity,calculatePassengerCapacity,calculateUnladenMass}from"../chunk-C3LLPLLD.js"; export{resolveBlueprintForModule}from"../chunk-2J6NNI3Y.js";export{BLUEPRINTS,getBlueprint,getBlueprintGrade}from"../chunk-WDAYRHXR.js"; export{distributorMetrics}from"../chunk-M2TCZKRT.js"; export{ENGINEERING_OPTION_GROUPS,getBlueprintsForModule,getEngineeringGroup,getExperimentalsForBlueprint,getExperimentalsForModule}from"../chunk-M4STXLXO.js";export{computeModifiers,sumMaterials}from"../chunk-U73MBQ45.js"; export{ammunitionCapacity}from"../chunk-AA3K5XUE.js";export{armourMetrics}from"../chunk-3I2I5KG4.js";export{effectiveHitPoints,mapDamageTypes,stackArmourResistance,stackShieldResistance,systemsResistance}from"../chunk-Q75JSMU6.js"; export{SLOT_RESTRICTION_LABELS,enumerateSlots,parseSlotName}from"../chunk-RAO35XDF.js"; //# sourceMappingURL=index.js.map
@@ -14,7 +14,7 @@
14
14
  *
15
15
  * @remarks
16
16
  * Reference implementation: EDSY. The algorithm is ported as fact, not code; credit and
17
- * licence terms are in [ATTRIBUTIONS.md](https://github.com/DarkSession/Elite-Dangerous-Almanac/blob/main/ATTRIBUTIONS.md).
17
+ * licence terms are in [ATTRIBUTIONS.md](https://github.com/Elite-Dangerous-Almanac/Almanac-Core/blob/main/ATTRIBUTIONS.md).
18
18
  *
19
19
  * @packageDocumentation
20
20
  */