@elite-dangerous-almanac/core 0.2.14 → 0.2.16

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 (112) 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 +36 -10
  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-T3WRI2U2.js → chunk-B5ZKDHBW.js} +1 -1
  41. package/dist/{chunk-T3WRI2U2.js.map → chunk-B5ZKDHBW.js.map} +1 -1
  42. package/dist/{chunk-EXHZ4CFB.js → chunk-EE25IDB7.js} +1 -1
  43. package/dist/{chunk-EXHZ4CFB.js.map → chunk-EE25IDB7.js.map} +1 -1
  44. package/dist/{chunk-RA4YJBU5.js → chunk-F53MPXZY.js} +1 -1
  45. package/dist/{chunk-RA4YJBU5.js.map → chunk-F53MPXZY.js.map} +1 -1
  46. package/dist/{chunk-P5SIDTV5.js → chunk-JQ4OPZZ4.js} +1 -1
  47. package/dist/{chunk-P5SIDTV5.js.map → chunk-JQ4OPZZ4.js.map} +1 -1
  48. package/dist/{chunk-QNHGTVMZ.js → chunk-LLLFK3D5.js} +1 -1
  49. package/dist/{chunk-S4BZ64WE.js → chunk-N4YDIODB.js} +1 -1
  50. package/dist/{chunk-XCLOOKC2.js → chunk-U4MML7U6.js} +1 -1
  51. package/dist/commodities/commodities-rare.d.ts +1 -1
  52. package/dist/commodities/commodities-standard.d.ts +1 -1
  53. package/dist/equipment/modifications.d.ts +1 -1
  54. package/dist/galaxy-map/index.d.ts +14 -2
  55. package/dist/galaxy-map/index.js +1 -1
  56. package/dist/galaxy-map/markers.d.ts +4 -3
  57. package/dist/galaxy-map/markers.js +1 -1
  58. package/dist/i18n/index.d.ts +1 -1
  59. package/dist/i18n/index.js +1 -1
  60. package/dist/i18n/module-families.d.ts +3 -3
  61. package/dist/i18n/suits.d.ts +1 -2
  62. package/dist/i18n/suits.js +1 -1
  63. package/dist/materials/materials-encoded.d.ts +1 -1
  64. package/dist/materials/materials-manufactured.d.ts +1 -1
  65. package/dist/materials/materials-raw.d.ts +1 -1
  66. package/dist/materials/materials.d.ts +1 -1
  67. package/dist/materials/micro-resources-component.d.ts +1 -1
  68. package/dist/materials/micro-resources-consumable.d.ts +1 -1
  69. package/dist/materials/micro-resources-data.d.ts +1 -1
  70. package/dist/materials/micro-resources-item.d.ts +1 -1
  71. package/dist/materials/micro-resources.d.ts +1 -1
  72. package/dist/ships/armour.d.ts +1 -1
  73. package/dist/ships/blueprint-costs.d.ts +1 -1
  74. package/dist/ships/blueprint-journal.d.ts +1 -1
  75. package/dist/ships/blueprints.d.ts +1 -1
  76. package/dist/ships/build-metrics.js +1 -1
  77. package/dist/ships/default-loadouts.d.ts +1 -1
  78. package/dist/ships/distributor.d.ts +1 -1
  79. package/dist/ships/engineering.d.ts +1 -1
  80. package/dist/ships/experimental-effect-costs.d.ts +1 -1
  81. package/dist/ships/experimental-effects.d.ts +1 -1
  82. package/dist/ships/gunsights.d.ts +1 -1
  83. package/dist/ships/heat.d.ts +2 -2
  84. package/dist/ships/index.d.ts +1 -1
  85. package/dist/ships/index.js +1 -1
  86. package/dist/ships/jump-range.d.ts +1 -1
  87. package/dist/ships/mobility-capacitor.d.ts +1 -1
  88. package/dist/ships/mobility.d.ts +1 -1
  89. package/dist/ships/module-limits.d.ts +2 -2
  90. package/dist/ships/modules-all.d.ts +1 -1
  91. package/dist/ships/modules-core.d.ts +1 -1
  92. package/dist/ships/modules-hardpoint.d.ts +1 -1
  93. package/dist/ships/modules-internal.d.ts +1 -1
  94. package/dist/ships/modules-utility.d.ts +1 -1
  95. package/dist/ships/modules.d.ts +1 -1
  96. package/dist/ships/power.d.ts +1 -1
  97. package/dist/ships/pre-engineered-stats.js +1 -1
  98. package/dist/ships/pre-engineered.d.ts +0 -5
  99. package/dist/ships/pre-engineered.js +1 -1
  100. package/dist/ships/resistances.d.ts +1 -1
  101. package/dist/ships/shield-capacitor.d.ts +1 -1
  102. package/dist/ships/shield-recovery.d.ts +2 -2
  103. package/dist/ships/shields.d.ts +1 -1
  104. package/dist/ships/ship-loadout.js +1 -1
  105. package/dist/ships/ships.d.ts +1 -1
  106. package/dist/ships/weapons-capacitor.d.ts +1 -1
  107. package/dist/ships/weapons.d.ts +1 -1
  108. package/dist/{system-address-DmzXRD48.d.ts → system-address-CveshmDX.d.ts} +2 -2
  109. package/package.json +5 -4
  110. /package/dist/{chunk-QNHGTVMZ.js.map → chunk-LLLFK3D5.js.map} +0 -0
  111. /package/dist/{chunk-S4BZ64WE.js.map → chunk-N4YDIODB.js.map} +0 -0
  112. /package/dist/{chunk-XCLOOKC2.js.map → chunk-U4MML7U6.js.map} +0 -0
@@ -1 +1 @@
1
- import{cellBankSummary,shieldRecovery}from"./chunk-JMAXSXXQ.js";import{loadoutInternals,fittedThrusterParamsFor,preEngineeredVariantFor,powerConsumerFor,powerAvailable,heatInputResultFor,completeResult,cellBankInputsFor,armourInputFor,weaponStatsFor,weaponsCapacitorInputFor,mobilityInputResultFor,shieldInputResultFor,shieldCapacitorInputResultFor,shieldRecoveryInputResultFor,distributorInputResultFor,incompleteResult}from"./chunk-XCLOOKC2.js";import{weaponMetrics,sumWeaponMetrics}from"./chunk-Z266X4JF.js";import{shieldMetrics}from"./chunk-SRPCHXW2.js";import{weaponsCapacitorMetrics}from"./chunk-M4FZRDAH.js";import{powerBudget}from"./chunk-GGQMIQPC.js";import{isNonOutfittingSlot,isBuiltInHullModule,orderBySlotLayout}from"./chunk-QNHGTVMZ.js";import{shieldCapacitorMetrics}from"./chunk-HWOP7QWK.js";import{mobilityCapacitorMetrics}from"./chunk-VEEBJFJ7.js";import{mobilityMetrics}from"./chunk-A4QKXXZD.js";import{getExperimentalEffectCost}from"./chunk-CJK2IBI2.js";import{heatMetrics}from"./chunk-6HA2YIKW.js";import{frameShiftDriveMassFactor,singleJumpRange,fuelPerJump,totalRange}from"./chunk-VTMCSCXV.js";import{calculateUnladenMass}from"./chunk-C3LLPLLD.js";import{getBlueprintCost}from"./chunk-ARG6ESYB.js";import{distributorMetrics}from"./chunk-M2TCZKRT.js";import{sumMaterials}from"./chunk-U73MBQ45.js";import{ammunitionCapacity}from"./chunk-AA3K5XUE.js";import{armourMetrics}from"./chunk-3I2I5KG4.js";import{requirePips,requireFiniteNonNegative}from"./chunk-65FZECUX.js";import{deepFreeze}from"./chunk-DURKO7JU.js";var FACADE="BuildMetrics";function requireLoadOptions(scope,options){for(const field of["fuel","cargo"]){const value=options[field];if(value!==void 0)requireFiniteNonNegative(scope,field,value)}}var BuildMetrics=class _BuildMetrics{#build;#state;constructor(build,state){this.#build=build;this.#state=state}static of(build){return new _BuildMetrics(build,loadoutInternals(build,`${FACADE}.of: build`))}loadout(){return this.#build}frameShiftDrive(){const drive=this.#state.resolveDrive();if(drive===null){throw new TypeError(`${FACADE}: build has no frame shift drive`)}return drive}thrusters(){return fittedThrusterParamsFor(this.#state.modules(),this.#state.statsFor)}frameShiftDriveMassFactor(options={}){requireLoadOptions(`${FACADE}.frameShiftDriveMassFactor`,options);return frameShiftDriveMassFactor(this.#loadedMass(options.cargo??0),options.fuel??this.#build.fuelCapacity.main,this.frameShiftDrive())}maxJumpRange(){const fsd=this.frameShiftDrive();return singleJumpRange(this.#loadedMass(0),this.#maxJumpFuel(fsd),fsd)}jumpRange(options={}){requireLoadOptions(`${FACADE}.jumpRange`,options);return singleJumpRange(this.#loadedMass(options.cargo??0),options.fuel??this.#build.fuelCapacity.main,this.frameShiftDrive())}ladenJumpRange(){return this.jumpRange({cargo:this.#build.cargoCapacity})}fuelPerJump(distance,options={}){requireLoadOptions(`${FACADE}.fuelPerJump`,options);return fuelPerJump(distance,this.#loadedMass(options.cargo??0),options.fuel??this.#build.fuelCapacity.main,this.frameShiftDrive())}totalRange(options={}){requireLoadOptions(`${FACADE}.totalRange`,options);return totalRange(this.#loadedMass(options.cargo??0),options.fuel??this.#build.fuelCapacity.main,this.frameShiftDrive())}standardLoadResult(load){return this.#standardLoad(load)}jumpRangeSummary(){const maximum=this.#require(this.standardLoadResult("maximum"),"maximum load");const unladen=this.#require(this.standardLoadResult("unladen"),"unladen load");const laden=this.#require(this.standardLoadResult("laden"),"laden load");return{max:this.jumpRange(maximum),unladen:this.jumpRange(unladen),laden:this.jumpRange(laden),totalMax:this.totalRange(maximum),totalUnladen:this.totalRange(unladen),totalLaden:this.totalRange(laden)}}buildMass(options={}){requireLoadOptions(`${FACADE}.buildMass`,options);const unladen=this.#build.unladenMass;const fuel=options.fuel??this.#build.fuelCapacity.main;const cargo=options.cargo??0;return Object.freeze({hull:this.#state.ship.hullMass,modules:calculateUnladenMass(0,this.#state.calculationModules()),unladen:unladen,fuel:fuel,cargo:cargo,total:unladen+fuel+cargo})}buildCost(){const hull=this.#state.ship.hullCost;let modules=0;let mercCoins=0;const unpriced=[];const materials=[];for(const module of this.#state.modules()){const stats=this.#state.statsFor(module);if(stats?.cost!==void 0){modules+=stats.cost}else if(stats!==null||!isNonOutfittingSlot(module.Slot)&&!isBuiltInHullModule(module)){unpriced.push({slot:module.Slot,symbol:module.Item})}const variant=preEngineeredVariantFor(module);mercCoins+=variant?.mercCoinCost??0;const engineering=module.Engineering;if(!engineering)continue;const grade=engineering.Level;const bought=variant?.grade??0;if(Number.isInteger(grade)&&grade>bought&&grade<=5){const climb=getBlueprintCost(engineering.BlueprintName,grade,bought);if(climb){materials.push(climb.materials);mercCoins+=climb.mercCoins}}const experimental=engineering.ExperimentalEffect;if(experimental!==void 0&&experimental.toLowerCase()!==variant?.experimentalEffectSymbol?.toLowerCase()){const cost=getExperimentalEffectCost(experimental);if(cost)materials.push(cost)}}return deepFreeze({credits:{total:hull+modules,hull:hull,modules:modules,rebuy:Math.trunc((hull+modules)*.05),unpriced:unpriced},mercCoins:mercCoins,materials:sumMaterials(...materials)})}powerBudget(){const modules=this.#state.modules();const consumers=[];for(const module of modules){const consumer=powerConsumerFor(module,this.#state.statsFor(module));if(consumer)consumers.push(consumer)}return powerBudget(powerAvailable(modules,this.#state.statsFor),consumers)}heatMetricsResult(){const input=heatInputResultFor(this.#state.ship,this.#state.effectiveModules(),this.powerBudget(),this.#state.statsFor);return input.complete?completeResult(heatMetrics(input.value)):input}mobilityMetricsResult(options={}){return this.#mobility(options)}mobilityCapacitorMetricsResult(options={}){return this.#mobilityCapacitor(options)}shieldMetricsResult(){return this.#shields()}shieldCapacitorMetricsResult(options={}){return this.#shieldCapacitor(options)}shieldRecoveryResult(options={}){return this.#recovery(options)}cellBanks(){return cellBankSummary(orderBySlotLayout(cellBankInputsFor(this.#state.modules(),this.powerBudget(),this.#state.statsFor),this.#state.layout(),bank=>bank.slot))}armourMetrics(){return armourMetrics(armourInputFor(this.#state.ship,this.#state.modules(),this.#state.statsFor))}weaponMetrics(){const weapons=[];for(const module of this.#state.modules()){const record=this.#state.statsFor(module);const stats=weaponStatsFor(this.#state.effectiveModule(module),record);if(!stats)continue;weapons.push({slot:module.Slot,symbol:module.Item,name:record?.name??module.Item,enabled:module.On!==false,metrics:weaponMetrics(stats),ammunition:ammunitionCapacity(stats),...stats.maximumRange===void 0?{}:{maximumRange:stats.maximumRange},...stats.falloffRange===void 0?{}:{falloffRange:stats.falloffRange},...stats.projectileRange===void 0?{}:{projectileRange:{...stats.projectileRange}},...stats.armourPiercing===void 0?{}:{armourPiercing:stats.armourPiercing}})}const orderedWeapons=orderBySlotLayout(weapons,this.#state.layout(),weapon=>weapon.slot);return{weapons:orderedWeapons,total:sumWeaponMetrics(orderedWeapons.filter(weapon=>weapon.enabled).map(weapon=>weapon.metrics))}}weaponsCapacitorMetrics(options={}){const weaponsPips=requirePips(`${FACADE}.weaponsCapacitorMetrics`,"weaponsPips",options.weaponsPips??4);return weaponsCapacitorMetrics(weaponsCapacitorInputFor(this.#state.effectiveModules(),weaponsPips,this.powerBudget(),this.#state.statsFor))}distributorMetricsResult(options={}){return this.#distributor(options)}#mobility(options){const input=this.#mobilityInput(`${FACADE}.mobilityMetricsResult`,options);return input.complete?completeResult(mobilityMetrics(input.value)):input}#mobilityCapacitor(options){const scope=`${FACADE}.mobilityCapacitorMetricsResult`;const enginesPips=requirePips(scope,"enginesPips",options.enginesPips??4);const input=this.#mobilityInput(scope,options);return input.complete?completeResult(mobilityCapacitorMetrics({...input.value,enginesPips:enginesPips})):input}#mobilityInput(scope,options){requireLoadOptions(scope,options);return mobilityInputResultFor(this.#state.ship,this.#state.modules(),()=>this.powerBudget(),()=>this.#loadedMass(options.cargo??0)+(options.fuel??this.#state.statedMainFuel()??this.#build.fuelCapacity.main),this.#state.statsFor)}#shields(){const input=shieldInputResultFor(this.#state.ship,this.#state.modules(),()=>this.powerBudget(),this.#state.statsFor);return input.complete?completeResult(shieldMetrics(input.value)):input}#shieldCapacitor(options){const systemsPips=requirePips(`${FACADE}.shieldCapacitorMetricsResult`,"systemsPips",options.systemsPips??4);const input=shieldCapacitorInputResultFor(this.#state.ship,this.#state.modules(),()=>this.powerBudget(),systemsPips,this.#state.statsFor);return input.complete?completeResult(shieldCapacitorMetrics(input.value)):input}#recovery(options){const systemsPips=requirePips(`${FACADE}.shieldRecoveryResult`,"systemsPips",options.systemsPips??4);const input=shieldRecoveryInputResultFor(this.#state.ship,this.#state.modules(),()=>this.powerBudget(),systemsPips,this.#state.statsFor);return input.complete?completeResult(shieldRecovery(input.value)):input}#distributor(options){const scope=`${FACADE}.distributorMetricsResult`;const pips={systemsPips:requirePips(scope,"systemsPips",options.systemsPips??4),enginesPips:requirePips(scope,"enginesPips",options.enginesPips??4),weaponsPips:requirePips(scope,"weaponsPips",options.weaponsPips??4)};const input=distributorInputResultFor(this.#state.effectiveModules(),pips,this.powerBudget(),this.#state.statsFor);return input.complete?completeResult(distributorMetrics(input.value)):input}#standardLoad(load){if(load!=="maximum"&&load!=="unladen"&&load!=="laden"){throw new RangeError(`${FACADE}.standardLoadResult: load must be 'maximum', 'unladen', or 'laden'`)}const fuel=this.#build.fuelCapacity;const cargo=load==="laden"?this.#build.cargoCapacity:0;const mass=load==="maximum"?this.#build.unladenMass:0;let drive=null;let maximumFuel=null;if(load==="maximum"){const fitted=this.#state.frameShiftDriveModule();let driveError=null;try{drive=this.#state.resolveDrive();maximumFuel=drive?.maxFuel??null}catch(error){if(!(error instanceof Error))throw error;driveError=error}if(maximumFuel===null){return incompleteResult([{field:"frameShiftDrive",reason:fitted?"unresolved":"missing",slot:fitted?.Slot??"FrameShiftDrive",...fitted?{symbol:fitted.Item}:{},message:driveError?.message??"FrameShiftDrive: no frame shift drive is fitted",params:fitted?{field:"frameShiftDrive",reason:"unresolved",slot:fitted.Slot,symbol:fitted.Item}:{field:"frameShiftDrive",reason:"missing",slot:"FrameShiftDrive"}}])}}const carriedFuel=load==="maximum"?Math.min(fuel.main,maximumFuel):fuel.main;const value=Object.freeze({fuel:carriedFuel,cargo:cargo,mass:this.#build.unladenMass+carriedFuel+cargo});if(load==="maximum"){try{this.jumpRange(value)}catch(error){if(!(error instanceof RangeError))throw error;const fitted=this.#state.frameShiftDriveModule();const field=drive!==null&&(!Number.isFinite(drive.maxFuel)||drive.maxFuel<0)?"frameShiftDrive":!Number.isFinite(value.fuel)||value.fuel<0?"fuelCapacity":!Number.isFinite(mass)||mass<0?"mass":"frameShiftDrive";const driveParams=field==="frameShiftDrive"&&fitted?{slot:fitted.Slot,symbol:fitted.Item}:{};return incompleteResult([{field:field,reason:"invalid",...driveParams,message:error.message,params:{field:field,reason:"invalid",...driveParams}}])}}return completeResult(value)}#require(result,what){if(result.value===null){throw new TypeError(`${FACADE}: cannot determine ${what} (${result.issues.map(issue=>issue.message).join("; ")})`)}return result.value}#loadedMass(cargo){return this.#build.unladenMass+cargo}#maxJumpFuel(fsd){return Math.min(this.#build.fuelCapacity.main,fsd.maxFuel)}};export{BuildMetrics};//# sourceMappingURL=chunk-S4BZ64WE.js.map
1
+ import{cellBankSummary,shieldRecovery}from"./chunk-JMAXSXXQ.js";import{loadoutInternals,fittedThrusterParamsFor,preEngineeredVariantFor,powerConsumerFor,powerAvailable,heatInputResultFor,completeResult,cellBankInputsFor,armourInputFor,weaponStatsFor,weaponsCapacitorInputFor,mobilityInputResultFor,shieldInputResultFor,shieldCapacitorInputResultFor,shieldRecoveryInputResultFor,distributorInputResultFor,incompleteResult}from"./chunk-U4MML7U6.js";import{weaponMetrics,sumWeaponMetrics}from"./chunk-Z266X4JF.js";import{shieldMetrics}from"./chunk-SRPCHXW2.js";import{weaponsCapacitorMetrics}from"./chunk-M4FZRDAH.js";import{powerBudget}from"./chunk-GGQMIQPC.js";import{isNonOutfittingSlot,isBuiltInHullModule,orderBySlotLayout}from"./chunk-LLLFK3D5.js";import{shieldCapacitorMetrics}from"./chunk-HWOP7QWK.js";import{mobilityCapacitorMetrics}from"./chunk-VEEBJFJ7.js";import{mobilityMetrics}from"./chunk-A4QKXXZD.js";import{getExperimentalEffectCost}from"./chunk-CJK2IBI2.js";import{heatMetrics}from"./chunk-6HA2YIKW.js";import{frameShiftDriveMassFactor,singleJumpRange,fuelPerJump,totalRange}from"./chunk-VTMCSCXV.js";import{calculateUnladenMass}from"./chunk-C3LLPLLD.js";import{getBlueprintCost}from"./chunk-ARG6ESYB.js";import{distributorMetrics}from"./chunk-M2TCZKRT.js";import{sumMaterials}from"./chunk-U73MBQ45.js";import{ammunitionCapacity}from"./chunk-AA3K5XUE.js";import{armourMetrics}from"./chunk-3I2I5KG4.js";import{requirePips,requireFiniteNonNegative}from"./chunk-65FZECUX.js";import{deepFreeze}from"./chunk-DURKO7JU.js";var FACADE="BuildMetrics";function requireLoadOptions(scope,options){for(const field of["fuel","cargo"]){const value=options[field];if(value!==void 0)requireFiniteNonNegative(scope,field,value)}}var BuildMetrics=class _BuildMetrics{#build;#state;constructor(build,state){this.#build=build;this.#state=state}static of(build){return new _BuildMetrics(build,loadoutInternals(build,`${FACADE}.of: build`))}loadout(){return this.#build}frameShiftDrive(){const drive=this.#state.resolveDrive();if(drive===null){throw new TypeError(`${FACADE}: build has no frame shift drive`)}return drive}thrusters(){return fittedThrusterParamsFor(this.#state.modules(),this.#state.statsFor)}frameShiftDriveMassFactor(options={}){requireLoadOptions(`${FACADE}.frameShiftDriveMassFactor`,options);return frameShiftDriveMassFactor(this.#loadedMass(options.cargo??0),options.fuel??this.#build.fuelCapacity.main,this.frameShiftDrive())}maxJumpRange(){const fsd=this.frameShiftDrive();return singleJumpRange(this.#loadedMass(0),this.#maxJumpFuel(fsd),fsd)}jumpRange(options={}){requireLoadOptions(`${FACADE}.jumpRange`,options);return singleJumpRange(this.#loadedMass(options.cargo??0),options.fuel??this.#build.fuelCapacity.main,this.frameShiftDrive())}ladenJumpRange(){return this.jumpRange({cargo:this.#build.cargoCapacity})}fuelPerJump(distance,options={}){requireLoadOptions(`${FACADE}.fuelPerJump`,options);return fuelPerJump(distance,this.#loadedMass(options.cargo??0),options.fuel??this.#build.fuelCapacity.main,this.frameShiftDrive())}totalRange(options={}){requireLoadOptions(`${FACADE}.totalRange`,options);return totalRange(this.#loadedMass(options.cargo??0),options.fuel??this.#build.fuelCapacity.main,this.frameShiftDrive())}standardLoadResult(load){return this.#standardLoad(load)}jumpRangeSummary(){const maximum=this.#require(this.standardLoadResult("maximum"),"maximum load");const unladen=this.#require(this.standardLoadResult("unladen"),"unladen load");const laden=this.#require(this.standardLoadResult("laden"),"laden load");return{max:this.jumpRange(maximum),unladen:this.jumpRange(unladen),laden:this.jumpRange(laden),totalMax:this.totalRange(maximum),totalUnladen:this.totalRange(unladen),totalLaden:this.totalRange(laden)}}buildMass(options={}){requireLoadOptions(`${FACADE}.buildMass`,options);const unladen=this.#build.unladenMass;const fuel=options.fuel??this.#build.fuelCapacity.main;const cargo=options.cargo??0;return Object.freeze({hull:this.#state.ship.hullMass,modules:calculateUnladenMass(0,this.#state.calculationModules()),unladen:unladen,fuel:fuel,cargo:cargo,total:unladen+fuel+cargo})}buildCost(){const hull=this.#state.ship.hullCost;let modules=0;let mercCoins=0;const unpriced=[];const materials=[];for(const module of this.#state.modules()){const stats=this.#state.statsFor(module);if(stats?.cost!==void 0){modules+=stats.cost}else if(stats!==null||!isNonOutfittingSlot(module.Slot)&&!isBuiltInHullModule(module)){unpriced.push({slot:module.Slot,symbol:module.Item})}const variant=preEngineeredVariantFor(module);mercCoins+=variant?.mercCoinCost??0;const engineering=module.Engineering;if(!engineering)continue;const grade=engineering.Level;const bought=variant?.grade??0;if(Number.isInteger(grade)&&grade>bought&&grade<=5){const climb=getBlueprintCost(engineering.BlueprintName,grade,bought);if(climb){materials.push(climb.materials);mercCoins+=climb.mercCoins}}const experimental=engineering.ExperimentalEffect;if(experimental!==void 0&&experimental.toLowerCase()!==variant?.experimentalEffectSymbol?.toLowerCase()){const cost=getExperimentalEffectCost(experimental);if(cost)materials.push(cost)}}return deepFreeze({credits:{total:hull+modules,hull:hull,modules:modules,rebuy:Math.trunc((hull+modules)*.05),unpriced:unpriced},mercCoins:mercCoins,materials:sumMaterials(...materials)})}powerBudget(){const modules=this.#state.modules();const consumers=[];for(const module of modules){const consumer=powerConsumerFor(module,this.#state.statsFor(module));if(consumer)consumers.push(consumer)}return powerBudget(powerAvailable(modules,this.#state.statsFor),consumers)}heatMetricsResult(){const input=heatInputResultFor(this.#state.ship,this.#state.effectiveModules(),this.powerBudget(),this.#state.statsFor);return input.complete?completeResult(heatMetrics(input.value)):input}mobilityMetricsResult(options={}){return this.#mobility(options)}mobilityCapacitorMetricsResult(options={}){return this.#mobilityCapacitor(options)}shieldMetricsResult(){return this.#shields()}shieldCapacitorMetricsResult(options={}){return this.#shieldCapacitor(options)}shieldRecoveryResult(options={}){return this.#recovery(options)}cellBanks(){return cellBankSummary(orderBySlotLayout(cellBankInputsFor(this.#state.modules(),this.powerBudget(),this.#state.statsFor),this.#state.layout(),bank=>bank.slot))}armourMetrics(){return armourMetrics(armourInputFor(this.#state.ship,this.#state.modules(),this.#state.statsFor))}weaponMetrics(){const weapons=[];for(const module of this.#state.modules()){const record=this.#state.statsFor(module);const stats=weaponStatsFor(this.#state.effectiveModule(module),record);if(!stats)continue;weapons.push({slot:module.Slot,symbol:module.Item,name:record?.name??module.Item,enabled:module.On!==false,metrics:weaponMetrics(stats),ammunition:ammunitionCapacity(stats),...stats.maximumRange===void 0?{}:{maximumRange:stats.maximumRange},...stats.falloffRange===void 0?{}:{falloffRange:stats.falloffRange},...stats.projectileRange===void 0?{}:{projectileRange:{...stats.projectileRange}},...stats.armourPiercing===void 0?{}:{armourPiercing:stats.armourPiercing}})}const orderedWeapons=orderBySlotLayout(weapons,this.#state.layout(),weapon=>weapon.slot);return{weapons:orderedWeapons,total:sumWeaponMetrics(orderedWeapons.filter(weapon=>weapon.enabled).map(weapon=>weapon.metrics))}}weaponsCapacitorMetrics(options={}){const weaponsPips=requirePips(`${FACADE}.weaponsCapacitorMetrics`,"weaponsPips",options.weaponsPips??4);return weaponsCapacitorMetrics(weaponsCapacitorInputFor(this.#state.effectiveModules(),weaponsPips,this.powerBudget(),this.#state.statsFor))}distributorMetricsResult(options={}){return this.#distributor(options)}#mobility(options){const input=this.#mobilityInput(`${FACADE}.mobilityMetricsResult`,options);return input.complete?completeResult(mobilityMetrics(input.value)):input}#mobilityCapacitor(options){const scope=`${FACADE}.mobilityCapacitorMetricsResult`;const enginesPips=requirePips(scope,"enginesPips",options.enginesPips??4);const input=this.#mobilityInput(scope,options);return input.complete?completeResult(mobilityCapacitorMetrics({...input.value,enginesPips:enginesPips})):input}#mobilityInput(scope,options){requireLoadOptions(scope,options);return mobilityInputResultFor(this.#state.ship,this.#state.modules(),()=>this.powerBudget(),()=>this.#loadedMass(options.cargo??0)+(options.fuel??this.#state.statedMainFuel()??this.#build.fuelCapacity.main),this.#state.statsFor)}#shields(){const input=shieldInputResultFor(this.#state.ship,this.#state.modules(),()=>this.powerBudget(),this.#state.statsFor);return input.complete?completeResult(shieldMetrics(input.value)):input}#shieldCapacitor(options){const systemsPips=requirePips(`${FACADE}.shieldCapacitorMetricsResult`,"systemsPips",options.systemsPips??4);const input=shieldCapacitorInputResultFor(this.#state.ship,this.#state.modules(),()=>this.powerBudget(),systemsPips,this.#state.statsFor);return input.complete?completeResult(shieldCapacitorMetrics(input.value)):input}#recovery(options){const systemsPips=requirePips(`${FACADE}.shieldRecoveryResult`,"systemsPips",options.systemsPips??4);const input=shieldRecoveryInputResultFor(this.#state.ship,this.#state.modules(),()=>this.powerBudget(),systemsPips,this.#state.statsFor);return input.complete?completeResult(shieldRecovery(input.value)):input}#distributor(options){const scope=`${FACADE}.distributorMetricsResult`;const pips={systemsPips:requirePips(scope,"systemsPips",options.systemsPips??4),enginesPips:requirePips(scope,"enginesPips",options.enginesPips??4),weaponsPips:requirePips(scope,"weaponsPips",options.weaponsPips??4)};const input=distributorInputResultFor(this.#state.effectiveModules(),pips,this.powerBudget(),this.#state.statsFor);return input.complete?completeResult(distributorMetrics(input.value)):input}#standardLoad(load){if(load!=="maximum"&&load!=="unladen"&&load!=="laden"){throw new RangeError(`${FACADE}.standardLoadResult: load must be 'maximum', 'unladen', or 'laden'`)}const fuel=this.#build.fuelCapacity;const cargo=load==="laden"?this.#build.cargoCapacity:0;const mass=load==="maximum"?this.#build.unladenMass:0;let drive=null;let maximumFuel=null;if(load==="maximum"){const fitted=this.#state.frameShiftDriveModule();let driveError=null;try{drive=this.#state.resolveDrive();maximumFuel=drive?.maxFuel??null}catch(error){if(!(error instanceof Error))throw error;driveError=error}if(maximumFuel===null){return incompleteResult([{field:"frameShiftDrive",reason:fitted?"unresolved":"missing",slot:fitted?.Slot??"FrameShiftDrive",...fitted?{symbol:fitted.Item}:{},message:driveError?.message??"FrameShiftDrive: no frame shift drive is fitted",params:fitted?{field:"frameShiftDrive",reason:"unresolved",slot:fitted.Slot,symbol:fitted.Item}:{field:"frameShiftDrive",reason:"missing",slot:"FrameShiftDrive"}}])}}const carriedFuel=load==="maximum"?Math.min(fuel.main,maximumFuel):fuel.main;const value=Object.freeze({fuel:carriedFuel,cargo:cargo,mass:this.#build.unladenMass+carriedFuel+cargo});if(load==="maximum"){try{this.jumpRange(value)}catch(error){if(!(error instanceof RangeError))throw error;const fitted=this.#state.frameShiftDriveModule();const field=drive!==null&&(!Number.isFinite(drive.maxFuel)||drive.maxFuel<0)?"frameShiftDrive":!Number.isFinite(value.fuel)||value.fuel<0?"fuelCapacity":!Number.isFinite(mass)||mass<0?"mass":"frameShiftDrive";const driveParams=field==="frameShiftDrive"&&fitted?{slot:fitted.Slot,symbol:fitted.Item}:{};return incompleteResult([{field:field,reason:"invalid",...driveParams,message:error.message,params:{field:field,reason:"invalid",...driveParams}}])}}return completeResult(value)}#require(result,what){if(result.value===null){throw new TypeError(`${FACADE}: cannot determine ${what} (${result.issues.map(issue=>issue.message).join("; ")})`)}return result.value}#loadedMass(cargo){return this.#build.unladenMass+cargo}#maxJumpFuel(fsd){return Math.min(this.#build.fuelCapacity.main,fsd.maxFuel)}};export{BuildMetrics};//# sourceMappingURL=chunk-N4YDIODB.js.map
@@ -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, so one string gives both the colour
15
+ * and the file:
16
16
  *
17
17
  * ```ts
18
18
  * import { getGalaxyMapMarker } from '@elite-dangerous-almanac/core/galaxy-map';
@@ -21,12 +21,24 @@
21
21
  * `assets/galaxy-map/${symbol}.svg`; // -> 'assets/galaxy-map/titan.svg'
22
22
  * ```
23
23
  *
24
+ * The package exports that path under `@elite-dangerous-almanac/core/assets/`. A
25
+ * bundler resolves an asset import statically, so write the whole specifier as a
26
+ * literal — `@elite-dangerous-almanac/core/assets/galaxy-map/titan.svg` — rather than
27
+ * building it from a symbol at run time.
28
+ *
24
29
  * Every shape in an asset paints with `currentColor`, and the root `<svg>` carries the
25
30
  * marker's own colour. A host that embeds the file inline therefore recolours it with
26
31
  * one CSS `color` declaration, and one that loads it with `<img>` keeps the game's
27
32
  * colour. `front-line.svg` is the exception: its frame holds the literal
28
33
  * {@link GalaxyMapMarker.frameColor}, which no `color` declaration reaches.
29
34
  *
35
+ * A marker is safe to embed inline as supplied: it holds only static `svg`, `title`,
36
+ * `defs`, `mask`, `filter`, `feGaussianBlur`, `g`, `use`, `path`, `rect`, `circle` and
37
+ * `ellipse` elements, and every `href`, `mask` and `filter` points inside the same
38
+ * file. There are no scripts, styles, event-handler attributes, foreign or media
39
+ * elements, links or external references. Every definition id is unique across the
40
+ * set, so a page can inline all of them.
41
+ *
30
42
  * The catalogue carries no display name. Each asset's `<title>` holds the English
31
43
  * label, which is also what a screen reader announces for an inline-embedded marker.
32
44
  *
@@ -1 +1 @@
1
- export{GALAXY_MAP_MARKERS,getGalaxyMapMarker,getGalaxyMapMarkerColor}from"../chunk-T3WRI2U2.js"; //# sourceMappingURL=index.js.map
1
+ export{GALAXY_MAP_MARKERS,getGalaxyMapMarker,getGalaxyMapMarkerColor}from"../chunk-B5ZKDHBW.js"; //# sourceMappingURL=index.js.map
@@ -2,11 +2,12 @@
2
2
  * The galaxy map's location markers and the colours the game draws them in.
3
3
  *
4
4
  * @remarks
5
- * Each marker's `symbol` also names its vector asset, `assets/galaxy-map/<symbol>.svg`,
6
- * whose root `<svg>` carries the same `color` this catalogue reports.
5
+ * Each marker's `symbol` also names its vector asset, which the package exports as
6
+ * `@elite-dangerous-almanac/core/assets/galaxy-map/<symbol>.svg` and whose root
7
+ * `<svg>` carries the same `color` this catalogue reports.
7
8
  *
8
9
  * Read from the in-game galaxy map; see
9
- * [ATTRIBUTIONS.md](https://github.com/DarkSession/Elite-Dangerous-Almanac/blob/main/ATTRIBUTIONS.md)
10
+ * [ATTRIBUTIONS.md](https://github.com/Elite-Dangerous-Almanac/Almanac-Core/blob/main/ATTRIBUTIONS.md)
10
11
  * for credit and licence terms.
11
12
  *
12
13
  * @packageDocumentation
@@ -1 +1 @@
1
- export{GALAXY_MAP_MARKERS,getGalaxyMapMarker,getGalaxyMapMarkerColor}from"../chunk-T3WRI2U2.js"; //# sourceMappingURL=markers.js.map
1
+ export{GALAXY_MAP_MARKERS,getGalaxyMapMarker,getGalaxyMapMarkerColor}from"../chunk-B5ZKDHBW.js"; //# sourceMappingURL=markers.js.map
@@ -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
  */