@alpaca-software/40kdc-data 0.5.14 → 0.5.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.
- package/dist/abilities-resolver/resolver.d.ts.map +1 -1
- package/dist/abilities-resolver/resolver.js +6 -2
- package/dist/abilities-resolver/resolver.js.map +1 -1
- package/dist/audit-coverage.d.ts.map +1 -1
- package/dist/audit-coverage.js +90 -1
- package/dist/audit-coverage.js.map +1 -1
- package/dist/audit-phrasing.d.ts +64 -0
- package/dist/audit-phrasing.d.ts.map +1 -0
- package/dist/audit-phrasing.js +208 -0
- package/dist/audit-phrasing.js.map +1 -0
- package/dist/build-share-registry.d.ts +2 -0
- package/dist/build-share-registry.d.ts.map +1 -0
- package/dist/build-share-registry.js +115 -0
- package/dist/build-share-registry.js.map +1 -0
- package/dist/cli.js +7 -0
- package/dist/cli.js.map +1 -1
- package/dist/codegen-data.js +23 -0
- package/dist/codegen-data.js.map +1 -1
- package/dist/commands/translate.d.ts.map +1 -1
- package/dist/commands/translate.js +2 -5
- package/dist/commands/translate.js.map +1 -1
- package/dist/commands/validate-all.d.ts.map +1 -1
- package/dist/commands/validate-all.js +8 -3
- package/dist/commands/validate-all.js.map +1 -1
- package/dist/data/bundle.generated.js +1 -1
- package/dist/data/bundle.generated.js.map +1 -1
- package/dist/data/dataset.d.ts +33 -1
- package/dist/data/dataset.d.ts.map +1 -1
- package/dist/data/dataset.js +107 -1
- package/dist/data/dataset.js.map +1 -1
- package/dist/data/index.d.ts +4 -0
- package/dist/data/index.d.ts.map +1 -1
- package/dist/data/index.js +4 -0
- package/dist/data/index.js.map +1 -1
- package/dist/data/types.d.ts +3 -1
- package/dist/data/types.d.ts.map +1 -1
- package/dist/data/types.js +1 -0
- package/dist/data/types.js.map +1 -1
- package/dist/gen-conformance.js +162 -0
- package/dist/gen-conformance.js.map +1 -1
- package/dist/generated.d.ts +125 -0
- package/dist/generated.d.ts.map +1 -1
- package/dist/generated.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/integrity.d.ts +32 -0
- package/dist/integrity.d.ts.map +1 -0
- package/dist/integrity.js +120 -0
- package/dist/integrity.js.map +1 -0
- package/dist/report.d.ts +1 -1
- package/dist/report.d.ts.map +1 -1
- package/dist/report.js +2 -2
- package/dist/report.js.map +1 -1
- package/dist/runner.d.ts.map +1 -1
- package/dist/runner.js +42 -0
- package/dist/runner.js.map +1 -1
- package/dist/share/codec.d.ts +83 -0
- package/dist/share/codec.d.ts.map +1 -0
- package/dist/share/codec.js +230 -0
- package/dist/share/codec.js.map +1 -0
- package/dist/share/index.d.ts +30 -0
- package/dist/share/index.d.ts.map +1 -0
- package/dist/share/index.js +36 -0
- package/dist/share/index.js.map +1 -0
- package/dist/share/registry.d.ts +42 -0
- package/dist/share/registry.d.ts.map +1 -0
- package/dist/share/registry.generated.d.ts +4 -0
- package/dist/share/registry.generated.d.ts.map +1 -0
- package/dist/share/registry.generated.js +4 -0
- package/dist/share/registry.generated.js.map +1 -0
- package/dist/share/registry.js +68 -0
- package/dist/share/registry.js.map +1 -0
- package/dist/terrain/index.d.ts +2 -2
- package/dist/terrain/index.d.ts.map +1 -1
- package/dist/terrain/index.js +1 -1
- package/dist/terrain/index.js.map +1 -1
- package/dist/terrain/solve.d.ts +76 -0
- package/dist/terrain/solve.d.ts.map +1 -1
- package/dist/terrain/solve.js +138 -0
- package/dist/terrain/solve.js.map +1 -1
- package/dist/translate/condition.d.ts +1 -0
- package/dist/translate/condition.d.ts.map +1 -1
- package/dist/translate/condition.js +101 -7
- package/dist/translate/condition.js.map +1 -1
- package/dist/translate/effect.d.ts +28 -20
- package/dist/translate/effect.d.ts.map +1 -1
- package/dist/translate/effect.js +483 -114
- package/dist/translate/effect.js.map +1 -1
- package/dist/validate.d.ts.map +1 -1
- package/dist/validate.js +1 -0
- package/dist/validate.js.map +1 -1
- package/package.json +3 -1
- package/schemas/core/allied-rule.schema.json +115 -0
- package/schemas/core/detachment.schema.json +38 -1
package/dist/data/dataset.d.ts
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
*
|
|
6
6
|
* @packageDocumentation
|
|
7
7
|
*/
|
|
8
|
-
import type { DeploymentPattern, Detachment, Enhancement, ForceDisposition, GameVersion, HullShape, InteractionFlag, LeaderAttachment, Mission, MissionMatchup, Phase, ResourcePool, SecondaryCard, Stratagem, TargetProfile, TerrainLayout, TerrainTemplate, TimingFlag, Unit, UnitComposition, Wargear, WargearOption, WeaponKeyword } from "../generated.js";
|
|
8
|
+
import type { AlliedRule, DeploymentPattern, Detachment, Enhancement, ForceDisposition, GameVersion, HullShape, InteractionFlag, LeaderAttachment, Mission, MissionMatchup, Phase, ResourcePool, SecondaryCard, Stratagem, TargetProfile, TerrainLayout, TerrainTemplate, TimingFlag, Unit, UnitComposition, Wargear, WargearOption, WeaponKeyword } from "../generated.js";
|
|
9
9
|
import { Collection } from "./collection.js";
|
|
10
10
|
import { AbilityView, FactionView, UnitView, WeaponKeywordView, WeaponView } from "./entities.js";
|
|
11
11
|
import { type RawData } from "./types.js";
|
|
@@ -51,6 +51,7 @@ export declare class Dataset {
|
|
|
51
51
|
readonly abilities: Collection<RawData["abilities"][number], AbilityView>;
|
|
52
52
|
readonly targetProfiles: Collection<TargetProfile, TargetProfile>;
|
|
53
53
|
readonly detachments: Collection<Detachment, Detachment>;
|
|
54
|
+
readonly alliedRules: Collection<AlliedRule, AlliedRule>;
|
|
54
55
|
readonly enhancements: Collection<Enhancement, Enhancement>;
|
|
55
56
|
readonly stratagems: Collection<Stratagem, Stratagem>;
|
|
56
57
|
readonly wargearOptions: Collection<WargearOption, WargearOption>;
|
|
@@ -78,6 +79,8 @@ export declare class Dataset {
|
|
|
78
79
|
private readonly unitsByWeapon;
|
|
79
80
|
/** weapon-keyword id → weapons whose profiles reference it. */
|
|
80
81
|
private readonly weaponsByKeyword;
|
|
82
|
+
/** lowercased keyword → units carrying it (in `keywords` or `faction_keywords`). */
|
|
83
|
+
private readonly unitsByKeyword;
|
|
81
84
|
/** unit id → wargear options authored for it (declared order preserved). */
|
|
82
85
|
private readonly wargearOptionsByUnit;
|
|
83
86
|
constructor(raw?: RawData);
|
|
@@ -103,6 +106,35 @@ export declare class Dataset {
|
|
|
103
106
|
unitsWithWeapon(weaponId: string): UnitView[];
|
|
104
107
|
/** Weapons whose profiles reference the given weapon-keyword id. */
|
|
105
108
|
weaponsWithKeyword(keywordId: string): WeaponView[];
|
|
109
|
+
/**
|
|
110
|
+
* Units carrying the given keyword, matched case-insensitively against the
|
|
111
|
+
* union of each unit's `keywords` and `faction_keywords`. Powers a list
|
|
112
|
+
* builder's keyword search bar (type "Khorne" to find every Khorne unit),
|
|
113
|
+
* across the whole dataset — so it also surfaces cross-faction ally pools.
|
|
114
|
+
* Returns each faction's copy of a shared unit id separately.
|
|
115
|
+
*/
|
|
116
|
+
unitsWithKeyword(keyword: string): UnitView[];
|
|
117
|
+
/**
|
|
118
|
+
* The allied-rules **offered** for an army of `factionId` running the given
|
|
119
|
+
* detachments. A rule applies when both its gates pass: the **army gate**
|
|
120
|
+
* (`army_keywords_any` empty, or intersecting the faction's keywords) and the
|
|
121
|
+
* **detachment gate** (`detachment_id` null, or among `detachmentIds`). Order
|
|
122
|
+
* follows the allied-rules data file. The strict "every *model* carries an
|
|
123
|
+
* army keyword" check (for soup lists) is a builder/validation concern — this
|
|
124
|
+
* offers the candidate rules a faction qualifies for. Mirror of Rust
|
|
125
|
+
* `Dataset::allies_for`; pinned by the `allies_for` conformance query.
|
|
126
|
+
*/
|
|
127
|
+
alliesFor(factionId: string, detachmentIds?: string[]): AlliedRule[];
|
|
128
|
+
/**
|
|
129
|
+
* The unit pool an allied-rule grants, sorted by name. Starts from the rule's
|
|
130
|
+
* `source_faction_id` (if set, to keep that faction's copy of shared ids) or
|
|
131
|
+
* the whole dataset, narrows to units carrying any `source_keywords`, then
|
|
132
|
+
* applies `required_keywords` (all present), `excluded_keywords` (none
|
|
133
|
+
* present), and `roles`. Empty for an unknown rule id or a pool that resolves
|
|
134
|
+
* to nothing. Mirror of Rust `Dataset::ally_units_for`; pinned by the
|
|
135
|
+
* `ally_units_for` conformance query.
|
|
136
|
+
*/
|
|
137
|
+
allyUnitsFor(ruleId: string): UnitView[];
|
|
106
138
|
/**
|
|
107
139
|
* Wargear options authored for the given unit, in declared order. Mirror of
|
|
108
140
|
* Rust `Dataset::wargear_options_of`. Empty for a unit with no options.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dataset.d.ts","sourceRoot":"","sources":["../../src/data/dataset.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"dataset.d.ts","sourceRoot":"","sources":["../../src/data/dataset.ts"],"names":[],"mappings":"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"}
|
package/dist/data/dataset.js
CHANGED
|
@@ -15,6 +15,7 @@ export class Dataset {
|
|
|
15
15
|
// Id-bearing collections without bespoke views (records returned as-is).
|
|
16
16
|
targetProfiles;
|
|
17
17
|
detachments;
|
|
18
|
+
alliedRules;
|
|
18
19
|
enhancements;
|
|
19
20
|
stratagems;
|
|
20
21
|
wargearOptions;
|
|
@@ -43,6 +44,8 @@ export class Dataset {
|
|
|
43
44
|
unitsByWeapon = new Map();
|
|
44
45
|
/** weapon-keyword id → weapons whose profiles reference it. */
|
|
45
46
|
weaponsByKeyword = new Map();
|
|
47
|
+
/** lowercased keyword → units carrying it (in `keywords` or `faction_keywords`). */
|
|
48
|
+
unitsByKeyword = new Map();
|
|
46
49
|
/** unit id → wargear options authored for it (declared order preserved). */
|
|
47
50
|
wargearOptionsByUnit = new Map();
|
|
48
51
|
constructor(raw = emptyRawData()) {
|
|
@@ -82,7 +85,24 @@ export class Dataset {
|
|
|
82
85
|
wrap: (a) => new AbilityView(a, this),
|
|
83
86
|
});
|
|
84
87
|
this.targetProfiles = idCollection(raw.targetProfiles, (p) => p.faction_id);
|
|
85
|
-
|
|
88
|
+
// A detachment id is shared across factions: the generic Codex Space Marine
|
|
89
|
+
// detachments are replicated into every Codex-compatible chapter/supplement
|
|
90
|
+
// (each as its own faction view), so keep each faction's copy and collapse
|
|
91
|
+
// only true within-faction duplicates — mirroring the unit collection. Use
|
|
92
|
+
// {@link Collection.getInFaction} / {@link Collection.byFaction} when a
|
|
93
|
+
// faction context is known; bare {@link Collection.get} returns whichever
|
|
94
|
+
// copy was registered first.
|
|
95
|
+
this.detachments = new Collection({
|
|
96
|
+
items: raw.detachments,
|
|
97
|
+
idOf: (d) => d.id,
|
|
98
|
+
nameOf: (d) => d.name,
|
|
99
|
+
dedupeKeyOf: (d) => `${d.faction_id}::${d.id}`,
|
|
100
|
+
factionOf: (d) => d.faction_id,
|
|
101
|
+
wrap: (d) => d,
|
|
102
|
+
});
|
|
103
|
+
// Allied rules aren't owned by one faction (Daemonic Pact is shared by
|
|
104
|
+
// Chaos Knights and CSM); `alliesFor` matches on `army_keywords_any` instead.
|
|
105
|
+
this.alliedRules = idCollection(raw.alliedRules);
|
|
86
106
|
this.enhancements = idCollection(raw.enhancements);
|
|
87
107
|
this.stratagems = idCollection(raw.stratagems);
|
|
88
108
|
this.wargearOptions = idCollection(raw.wargearOptions);
|
|
@@ -144,6 +164,73 @@ export class Dataset {
|
|
|
144
164
|
weaponsWithKeyword(keywordId) {
|
|
145
165
|
return (this.weaponsByKeyword.get(keywordId) ?? []).map((w) => new WeaponView(w, this));
|
|
146
166
|
}
|
|
167
|
+
/**
|
|
168
|
+
* Units carrying the given keyword, matched case-insensitively against the
|
|
169
|
+
* union of each unit's `keywords` and `faction_keywords`. Powers a list
|
|
170
|
+
* builder's keyword search bar (type "Khorne" to find every Khorne unit),
|
|
171
|
+
* across the whole dataset — so it also surfaces cross-faction ally pools.
|
|
172
|
+
* Returns each faction's copy of a shared unit id separately.
|
|
173
|
+
*/
|
|
174
|
+
unitsWithKeyword(keyword) {
|
|
175
|
+
return (this.unitsByKeyword.get(keyword.toLowerCase()) ?? []).map((u) => new UnitView(u, this));
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* The allied-rules **offered** for an army of `factionId` running the given
|
|
179
|
+
* detachments. A rule applies when both its gates pass: the **army gate**
|
|
180
|
+
* (`army_keywords_any` empty, or intersecting the faction's keywords) and the
|
|
181
|
+
* **detachment gate** (`detachment_id` null, or among `detachmentIds`). Order
|
|
182
|
+
* follows the allied-rules data file. The strict "every *model* carries an
|
|
183
|
+
* army keyword" check (for soup lists) is a builder/validation concern — this
|
|
184
|
+
* offers the candidate rules a faction qualifies for. Mirror of Rust
|
|
185
|
+
* `Dataset::allies_for`; pinned by the `allies_for` conformance query.
|
|
186
|
+
*/
|
|
187
|
+
alliesFor(factionId, detachmentIds = []) {
|
|
188
|
+
const faction = this.factions.get(factionId);
|
|
189
|
+
if (!faction)
|
|
190
|
+
return [];
|
|
191
|
+
const factionKeywords = new Set((faction.raw.keywords ?? []).map((k) => k.toLowerCase()));
|
|
192
|
+
const detachmentSet = new Set(detachmentIds);
|
|
193
|
+
return this.alliedRules.all.filter((rule) => {
|
|
194
|
+
const armyGate = (rule.army_keywords_any ?? []).length === 0 ||
|
|
195
|
+
(rule.army_keywords_any ?? []).some((k) => factionKeywords.has(k.toLowerCase()));
|
|
196
|
+
const detachmentGate = rule.detachment_id == null || detachmentSet.has(rule.detachment_id);
|
|
197
|
+
return armyGate && detachmentGate;
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* The unit pool an allied-rule grants, sorted by name. Starts from the rule's
|
|
202
|
+
* `source_faction_id` (if set, to keep that faction's copy of shared ids) or
|
|
203
|
+
* the whole dataset, narrows to units carrying any `source_keywords`, then
|
|
204
|
+
* applies `required_keywords` (all present), `excluded_keywords` (none
|
|
205
|
+
* present), and `roles`. Empty for an unknown rule id or a pool that resolves
|
|
206
|
+
* to nothing. Mirror of Rust `Dataset::ally_units_for`; pinned by the
|
|
207
|
+
* `ally_units_for` conformance query.
|
|
208
|
+
*/
|
|
209
|
+
allyUnitsFor(ruleId) {
|
|
210
|
+
const rule = this.alliedRules.get(ruleId);
|
|
211
|
+
if (!rule)
|
|
212
|
+
return [];
|
|
213
|
+
const base = rule.source_faction_id
|
|
214
|
+
? this.units.byFaction(rule.source_faction_id)
|
|
215
|
+
: this.units.all;
|
|
216
|
+
const sourceKeywords = (rule.source_keywords ?? []).map((k) => k.toLowerCase());
|
|
217
|
+
const required = (rule.required_keywords ?? []).map((k) => k.toLowerCase());
|
|
218
|
+
const excluded = (rule.excluded_keywords ?? []).map((k) => k.toLowerCase());
|
|
219
|
+
const roles = new Set(rule.roles ?? []);
|
|
220
|
+
const out = base.filter((u) => {
|
|
221
|
+
const have = unitKeywordSet(u.raw);
|
|
222
|
+
if (sourceKeywords.length > 0 && !sourceKeywords.some((k) => have.has(k)))
|
|
223
|
+
return false;
|
|
224
|
+
if (required.length > 0 && !required.every((k) => have.has(k)))
|
|
225
|
+
return false;
|
|
226
|
+
if (excluded.some((k) => have.has(k)))
|
|
227
|
+
return false;
|
|
228
|
+
if (roles.size > 0 && !(u.raw.role && roles.has(u.raw.role)))
|
|
229
|
+
return false;
|
|
230
|
+
return true;
|
|
231
|
+
});
|
|
232
|
+
return out.sort((a, b) => a.name.localeCompare(b.name));
|
|
233
|
+
}
|
|
147
234
|
/**
|
|
148
235
|
* Wargear options authored for the given unit, in declared order. Mirror of
|
|
149
236
|
* Rust `Dataset::wargear_options_of`. Empty for a unit with no options.
|
|
@@ -359,6 +446,16 @@ export class Dataset {
|
|
|
359
446
|
push(this.unitsByAbility, abilityId, unit);
|
|
360
447
|
for (const weaponId of unit.weapon_ids ?? [])
|
|
361
448
|
push(this.unitsByWeapon, weaponId, unit);
|
|
449
|
+
// Index every keyword the unit carries (unit keywords ∪ faction keywords),
|
|
450
|
+
// lowercased, deduped per-unit so an overlap doesn't list the unit twice.
|
|
451
|
+
const seenKw = new Set();
|
|
452
|
+
for (const kw of [...(unit.keywords ?? []), ...(unit.faction_keywords ?? [])]) {
|
|
453
|
+
const key = kw.toLowerCase();
|
|
454
|
+
if (seenKw.has(key))
|
|
455
|
+
continue;
|
|
456
|
+
seenKw.add(key);
|
|
457
|
+
push(this.unitsByKeyword, key, unit);
|
|
458
|
+
}
|
|
362
459
|
}
|
|
363
460
|
for (const option of raw.wargearOptions) {
|
|
364
461
|
push(this.wargearOptionsByUnit, option.unit_id, option);
|
|
@@ -398,6 +495,15 @@ function push(map, key, value) {
|
|
|
398
495
|
else
|
|
399
496
|
map.set(key, [value]);
|
|
400
497
|
}
|
|
498
|
+
/** Lowercased union of a unit's `keywords` and `faction_keywords`, for membership tests. */
|
|
499
|
+
function unitKeywordSet(unit) {
|
|
500
|
+
const out = new Set();
|
|
501
|
+
for (const k of unit.keywords ?? [])
|
|
502
|
+
out.add(k.toLowerCase());
|
|
503
|
+
for (const k of unit.faction_keywords ?? [])
|
|
504
|
+
out.add(k.toLowerCase());
|
|
505
|
+
return out;
|
|
506
|
+
}
|
|
401
507
|
/** Map an EligibleAbility back to the BuffSource the translator expects. */
|
|
402
508
|
function bufferSourceFromEligible(entry) {
|
|
403
509
|
const abilityId = entry.ability.id;
|
package/dist/data/dataset.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dataset.js","sourceRoot":"","sources":["../../src/data/dataset.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * {@link Dataset} ties the embedded records together: it owns every\n * {@link Collection}, builds the cross-entity indexes once, and is the `this`\n * the linked views resolve against.\n *\n * @packageDocumentation\n */\nimport type {\n DeploymentPattern,\n Detachment,\n Enhancement,\n ForceDisposition,\n GameVersion,\n HullShape,\n InteractionFlag,\n LeaderAttachment,\n Mission,\n MissionMatchup,\n Phase,\n ResourcePool,\n SecondaryCard,\n Stratagem,\n TargetProfile,\n TerrainLayout,\n TerrainTemplate,\n TimingFlag,\n Unit,\n UnitComposition,\n Wargear,\n WargearOption,\n WeaponKeyword,\n} from \"../generated.js\";\nimport { Collection } from \"./collection.js\";\nimport {\n AbilityView,\n FactionView,\n UnitView,\n WeaponKeywordView,\n WeaponView,\n} from \"./entities.js\";\nimport { emptyRawData, type RawData } from \"./types.js\";\nimport { RAW_DATA } from \"./bundle.generated.js\";\nimport { resolveLayout, type ResolvedPiece } from \"../terrain/resolve.js\";\nimport type { Buff, BuffSource, EngineContext } from \"../cruncher/buffs.js\";\nimport {\n resolveEligibleAbilities,\n type EligibilityInput,\n type EligibleAbility,\n} from \"../abilities-resolver/index.js\";\n\n/**\n * One toggleable buff lever for damage analysis: the contributions it adds and\n * whether it's on by default. `enabled` is `true` for buffs that always apply\n * (intrinsic keywords, unconditional abilities) and `false` for player\n * decisions — stratagems (CP cost) and activatable gates (dice-pool options,\n * `choice` branches, timing-gated activations). A consumer flips `enabled`,\n * then crunches the enabled subset; an optimizer searches it.\n *\n * @see {@link Dataset.stackableBuffsFor}\n */\nexport type StackableBuff = {\n /** Stable toggle id (stable across re-enumeration of the same input). */\n id: string;\n /** Human label for the lever. */\n label: string;\n /** Contributions this lever adds when enabled (≥1). */\n buffs: Buff[];\n /** Default selection state. */\n enabled: boolean;\n /** Where the lever came from. */\n source: BuffSource;\n /** Id of the mutually-limited {@link StackableBuffGroup} this belongs to, if any. */\n group?: string;\n};\n\n/** A pool of {@link StackableBuff} levers limited to `maxActivations` at once. */\nexport type StackableBuffGroup = {\n id: string;\n label: string;\n maxActivations: number;\n};\n\n/** The whole dataset, with linked accessors over every entity collection. */\nexport class Dataset {\n // Richly-linked collections.\n readonly units: Collection<Unit, UnitView>;\n readonly weapons: Collection<RawData[\"weapons\"][number], WeaponView>;\n readonly weaponKeywords: Collection<WeaponKeyword, WeaponKeywordView>;\n readonly factions: Collection<RawData[\"factions\"][number], FactionView>;\n readonly abilities: Collection<RawData[\"abilities\"][number], AbilityView>;\n\n // Id-bearing collections without bespoke views (records returned as-is).\n readonly targetProfiles: Collection<TargetProfile, TargetProfile>;\n readonly detachments: Collection<Detachment, Detachment>;\n readonly enhancements: Collection<Enhancement, Enhancement>;\n readonly stratagems: Collection<Stratagem, Stratagem>;\n readonly wargearOptions: Collection<WargearOption, WargearOption>;\n readonly wargear: Collection<Wargear, Wargear>;\n readonly missions: Collection<Mission, Mission>;\n readonly missionMatchups: Collection<MissionMatchup, MissionMatchup>;\n readonly missionCards: Collection<SecondaryCard, SecondaryCard>;\n readonly deploymentPatterns: Collection<DeploymentPattern, DeploymentPattern>;\n readonly forceDispositions: Collection<ForceDisposition, ForceDisposition>;\n readonly terrainTemplates: Collection<TerrainTemplate, TerrainTemplate>;\n readonly terrainLayouts: Collection<TerrainLayout, TerrainLayout>;\n readonly hullShapes: Collection<HullShape, HullShape>;\n readonly resourcePools: Collection<ResourcePool, ResourcePool>;\n\n // Id-less collections, exposed as plain arrays.\n readonly leaderAttachments: readonly LeaderAttachment[];\n readonly unitCompositions: readonly UnitComposition[];\n readonly gameVersions: readonly GameVersion[];\n readonly timingFlags: readonly TimingFlag[];\n readonly interactionFlags: readonly InteractionFlag[];\n readonly phaseMappings: readonly RawData[\"phaseMappings\"][number][];\n\n /** `source_type:source_id` → unioned phases. */\n private readonly phaseIndex = new Map<string, Phase[]>();\n /** ability id → units that list it. */\n private readonly unitsByAbility = new Map<string, Unit[]>();\n /** weapon id → units that list it. */\n private readonly unitsByWeapon = new Map<string, Unit[]>();\n /** weapon-keyword id → weapons whose profiles reference it. */\n private readonly weaponsByKeyword = new Map<string, RawData[\"weapons\"][number][]>();\n /** unit id → wargear options authored for it (declared order preserved). */\n private readonly wargearOptionsByUnit = new Map<string, WargearOption[]>();\n\n constructor(raw: RawData = emptyRawData()) {\n this.units = new Collection({\n items: raw.units,\n idOf: (u) => u.id,\n // The same unit id is shared across factions (e.g. ministorum-priest);\n // keep each faction's copy, collapse only true within-faction duplicates.\n dedupeKeyOf: (u) => `${u.faction_id}::${u.id}`,\n nameOf: (u) => u.name,\n factionOf: (u) => u.faction_id,\n wrap: (u) => new UnitView(u, this),\n });\n this.weapons = new Collection({\n items: raw.weapons,\n idOf: (w) => w.id,\n nameOf: (w) => w.name,\n wrap: (w) => new WeaponView(w, this),\n });\n this.weaponKeywords = new Collection({\n items: raw.weaponKeywords,\n idOf: (k) => k.id,\n nameOf: (k) => k.name,\n wrap: (k) => new WeaponKeywordView(k, this),\n });\n this.factions = new Collection({\n items: raw.factions,\n idOf: (f) => f.id,\n nameOf: (f) => f.name,\n wrap: (f) => new FactionView(f, this),\n });\n this.abilities = new Collection({\n items: raw.abilities,\n idOf: (a) => a.ability_id,\n nameOf: (a) => a.name,\n factionOf: (a) => a.faction_id,\n wrap: (a) => new AbilityView(a, this),\n });\n\n this.targetProfiles = idCollection(raw.targetProfiles, (p) => p.faction_id);\n this.detachments = idCollection(raw.detachments, (d) => d.faction_id);\n this.enhancements = idCollection(raw.enhancements);\n this.stratagems = idCollection(raw.stratagems);\n this.wargearOptions = idCollection(raw.wargearOptions);\n this.wargear = idCollection(raw.wargear);\n this.missions = idCollection(raw.missions);\n this.missionMatchups = idCollection(raw.missionMatchups);\n this.missionCards = idCollection(raw.missionCards);\n this.deploymentPatterns = idCollection(raw.deploymentPatterns);\n this.forceDispositions = idCollection(raw.forceDispositions);\n this.terrainTemplates = idCollection(raw.terrainTemplates);\n this.terrainLayouts = idCollection(raw.terrainLayouts);\n this.hullShapes = idCollection(raw.hullShapes);\n this.resourcePools = idCollection(raw.resourcePools);\n\n this.leaderAttachments = raw.leaderAttachments;\n this.unitCompositions = raw.unitCompositions;\n this.gameVersions = raw.gameVersions;\n this.timingFlags = raw.timingFlags;\n this.interactionFlags = raw.interactionFlags;\n this.phaseMappings = raw.phaseMappings;\n\n this.buildIndexes(raw);\n }\n\n /** The dataset built from the package's embedded data. */\n static embedded(): Dataset {\n return new Dataset(RAW_DATA);\n }\n\n /** Phases a source acts in, unioned across its phase-mappings. */\n phasesFor(sourceType: string, sourceId: string): Phase[] {\n return this.phaseIndex.get(`${sourceType}:${sourceId}`) ?? [];\n }\n\n /**\n * Resolve a terrain layout to absolute board-space vertices using this\n * dataset's embedded terrain-template catalog — the layout-id →\n * renderable-geometry hop. Mirror of Rust `Dataset::resolve_terrain`; the\n * geometry is pinned by the `terrain-resolver` conformance corpus.\n */\n resolveTerrain(layout: TerrainLayout): ResolvedPiece[] {\n // The resolver takes its own structurally-identical input types, decoupled\n // from the generated `anyOf`/newtype shapes; the underlying JSON is the same.\n return resolveLayout(layout as never, this.terrainTemplates.all as never);\n }\n\n /**\n * The terrain layouts a deployment pattern recommends, in declared order,\n * skipping any ids absent from the dataset.\n */\n recommendedTerrainLayouts(pattern: DeploymentPattern): TerrainLayout[] {\n return (pattern.recommended_terrain_layout_ids ?? [])\n .map((id) => this.terrainLayouts.get(id))\n .filter((l): l is TerrainLayout => l !== undefined);\n }\n\n /** Units that list the given ability id. */\n unitsWithAbility(abilityId: string): UnitView[] {\n return (this.unitsByAbility.get(abilityId) ?? []).map((u) => new UnitView(u, this));\n }\n\n /** Units that list the given weapon id. */\n unitsWithWeapon(weaponId: string): UnitView[] {\n return (this.unitsByWeapon.get(weaponId) ?? []).map((u) => new UnitView(u, this));\n }\n\n /** Weapons whose profiles reference the given weapon-keyword id. */\n weaponsWithKeyword(keywordId: string): WeaponView[] {\n return (this.weaponsByKeyword.get(keywordId) ?? []).map((w) => new WeaponView(w, this));\n }\n\n /**\n * Wargear options authored for the given unit, in declared order. Mirror of\n * Rust `Dataset::wargear_options_of`. Empty for a unit with no options.\n */\n wargearOptionsOf(unit: Unit): WargearOption[] {\n return this.wargearOptionsByUnit.get(unit.id) ?? [];\n }\n\n /**\n * Leaders whose leader-attachment data lists `bodyguardUnitId` among its\n * eligible body units, sorted by name. The attachment is stored on the\n * leader pointing down to its bodyguards, so answering \"which leaders can\n * attach to this unit?\" means scanning the attachment list. Returns an empty\n * array for a unit that no leader can attach to (including leader units).\n */\n leadersAttachableTo(bodyguardUnitId: string): UnitView[] {\n return this.leaderAttachments\n .filter((la) => la.eligible_bodyguard_ids.includes(bodyguardUnitId))\n .map((la) => this.units.get(la.leader_id))\n .filter((u): u is UnitView => u !== undefined)\n .sort((a, b) => a.name.localeCompare(b.name));\n }\n\n /**\n * The inverse of {@link leadersAttachableTo}: the body units the given\n * leader can attach to, sorted by name. Scans the same leader-attachment\n * data from the leader's side (`leader_id` matches; resolve each\n * `eligible_bodyguard_ids` entry), deduped by id. Empty for a non-leader\n * unit. Together the two queries give the bidirectional attachment graph the\n * SPA needs to offer a partner dropdown from either end.\n */\n bodyguardsAttachableFrom(leaderUnitId: string): UnitView[] {\n const seen = new Set<string>();\n const out: UnitView[] = [];\n for (const la of this.leaderAttachments) {\n if (la.leader_id !== leaderUnitId) continue;\n for (const bodyguardId of la.eligible_bodyguard_ids) {\n if (seen.has(bodyguardId)) continue;\n const unit = this.units.get(bodyguardId);\n if (!unit) continue;\n seen.add(bodyguardId);\n out.push(unit);\n }\n }\n return out.sort((a, b) => a.name.localeCompare(b.name));\n }\n\n /**\n * Enumerate every ability that could apply to the given unit in `phase`,\n * grouped by source. The SPA uses this to render the abilities pane.\n */\n eligibleAbilities(input: EligibilityInput, phase: Phase): EligibleAbility[] {\n return resolveEligibleAbilities(this, input, phase);\n }\n\n /**\n * Attacker-perspective {@link Buff} stack for a (unit, phase) combination:\n * intrinsic weapon-profile keywords plus every eligible ability whose DSL\n * effect translates to an attacker-side buff (army, detachment, unit,\n * attached members, support, plus any stratagems the caller has opted into).\n *\n * The result includes only buffs the buff layer can express today — the\n * `unsupported` half of the DSL→Buff translation is dropped here so callers\n * who just want the stack don't need to thread diagnostics through. Use\n * {@link AbilityView.describeBuffs} when you need the diagnostics for an\n * individual ability. Symmetric to {@link defensiveBuffsFor}, which walks\n * the same eligibility set under target perspective.\n */\n buffsFor(\n input: EligibilityInput & {\n weaponProfiles?: { weaponId: string; profileIndex: number }[];\n /** Stratagem ids the caller has opted into spending CP on. */\n optedInStratagemIds?: string[];\n },\n context: EngineContext,\n ): Buff[] {\n return this.collectBuffs(input, context, \"attacker\");\n }\n\n /**\n * Defender-perspective buff stack for the chosen unit: walks the same\n * eligible-abilities set as {@link buffsFor} but translates each ability's\n * DSL effect as defensive (FNP, save mods from `stat-modifier Sv`,\n * toughness mods from `stat-modifier T`, save rerolls, incoming hit\n * penalties from `bs-modifier`). Use this when the chosen unit is being\n * crunched as the *target* — the engine reads `feelNoPain`/`saveMod`/\n * `toughnessMod` out of `resolveBuffs` so wiring the result into `crunch`\n * just means concatenating onto the existing `buffs` array.\n *\n * `weaponProfiles` are ignored under target perspective — weapon-keyword\n * effects ride with the firing weapon, not the receiving unit.\n */\n defensiveBuffsFor(\n input: EligibilityInput & { optedInStratagemIds?: string[] },\n context: EngineContext,\n ): Buff[] {\n return this.collectBuffs(input, context, \"target\");\n }\n\n /**\n * Enumerate every attacker-side buff a unit could stack in `context` as a\n * list of toggleable levers, plus the activation groups that limit them.\n *\n * Unlike {@link buffsFor} — which returns only the buffs that auto-apply —\n * this surfaces the *player decisions* too: stratagems, and the activatable\n * gates the DSL models as dice-pool options, `choice` branches, or\n * timing-gated activations (e.g. Blessings of Khorne's three keyword grants).\n * Each lever carries `enabled` (its default state) and, where it's part of a\n * limited pool, a `group` id whose {@link StackableBuffGroup} caps how many\n * can fire at once. The intended loop:\n *\n * ```ts\n * const { buffs } = ds.stackableBuffsFor(input, ctx);\n * const chosen = buffs.filter(b => b.enabled).flatMap(b => b.buffs);\n * crunch({ ...profiles, buffs: chosen, context: ctx }, ds);\n * ```\n *\n * Target/phase conditions a lever still carries (e.g. \"vs Infantry\") ride on\n * each buff's `applicableWhen`, so toggling it on is always safe — the\n * resolver gates it per-target.\n */\n stackableBuffsFor(\n input: EligibilityInput & {\n weaponProfiles?: { weaponId: string; profileIndex: number }[];\n },\n context: EngineContext,\n ): { buffs: StackableBuff[]; groups: StackableBuffGroup[] } {\n const buffs: StackableBuff[] = [];\n const groups = new Map<string, StackableBuffGroup>();\n\n // Surface the attachment fact to the DSL translator so `is-attached` /\n // `model-is-leader` conditions can evaluate. Clone — never mutate the\n // caller's context. An explicitly-set flag wins over the derivation.\n const ctx: EngineContext = {\n ...context,\n attackerAttached: context.attackerAttached ?? (input.attachedUnitIds?.length ?? 0) > 0,\n };\n\n // Intrinsic weapon-profile keywords — always on.\n for (const ref of input.weaponProfiles ?? []) {\n const weapon = this.weapons.get(ref.weaponId);\n if (!weapon) continue;\n const wk = weapon.profileBuffs(ref.profileIndex, ctx);\n if (wk.length === 0) continue;\n buffs.push({\n id: `weapon:${ref.weaponId}:${ref.profileIndex}`,\n label: `${weapon.name} keywords`,\n buffs: wk,\n enabled: true,\n source: wk[0].source,\n });\n }\n\n for (const entry of this.eligibleAbilities(input, ctx.phase)) {\n const source = bufferSourceFromEligible(entry);\n const { applied, activatable } = entry.ability.describeBuffs(source, ctx, \"attacker\");\n // Stratagems cost CP — opt-in, not on by default.\n const isStratagem = entry.source.kind === \"detachment-stratagem\";\n\n if (applied.length > 0) {\n buffs.push({\n id: `${entry.source.kind}:${entry.ability.id}`,\n label: entry.ability.name,\n buffs: applied,\n enabled: !isStratagem,\n source,\n });\n }\n\n for (const act of activatable) {\n let groupId: string | undefined;\n if (act.group) {\n groupId = act.group.id;\n if (!groups.has(groupId)) {\n groups.set(groupId, {\n id: groupId,\n label: entry.ability.name,\n maxActivations: act.group.maxActivations,\n });\n }\n }\n buffs.push({\n id: act.id,\n label: `${entry.ability.name} — ${act.label}`,\n buffs: act.buffs,\n enabled: false,\n source,\n group: groupId,\n });\n }\n }\n\n return { buffs, groups: [...groups.values()] };\n }\n\n /** Shared implementation for buffsFor / defensiveBuffsFor. */\n private collectBuffs(\n input: EligibilityInput & {\n weaponProfiles?: { weaponId: string; profileIndex: number }[];\n optedInStratagemIds?: string[];\n },\n context: EngineContext,\n perspective: \"attacker\" | \"target\",\n ): Buff[] {\n const out: Buff[] = [];\n\n // Surface the attachment fact to the DSL translator (see stackableBuffsFor).\n // Clone — never mutate the caller's context; explicit flag wins.\n const ctx: EngineContext = {\n ...context,\n attackerAttached: context.attackerAttached ?? (input.attachedUnitIds?.length ?? 0) > 0,\n };\n\n // Weapon-profile keywords are attacker-only.\n if (perspective === \"attacker\") {\n for (const ref of input.weaponProfiles ?? []) {\n const weapon = this.weapons.get(ref.weaponId);\n if (!weapon) continue;\n out.push(...weapon.profileBuffs(ref.profileIndex, ctx));\n }\n }\n\n const optedIn = new Set(input.optedInStratagemIds ?? []);\n for (const entry of this.eligibleAbilities(input, ctx.phase)) {\n if (entry.source.kind === \"detachment-stratagem\" && !optedIn.has(entry.source.stratagemId)) {\n continue;\n }\n const source = bufferSourceFromEligible(entry);\n out.push(...entry.ability.getBuffs(source, ctx, perspective));\n }\n\n return out;\n }\n\n private buildIndexes(raw: RawData): void {\n for (const pm of raw.phaseMappings) {\n const key = `${pm.source_type}:${pm.source_id}`;\n const existing = this.phaseIndex.get(key) ?? [];\n for (const phase of pm.phases) {\n if (!existing.includes(phase)) existing.push(phase);\n }\n this.phaseIndex.set(key, existing);\n }\n for (const unit of raw.units) {\n for (const abilityId of unit.ability_ids ?? []) push(this.unitsByAbility, abilityId, unit);\n for (const weaponId of unit.weapon_ids ?? []) push(this.unitsByWeapon, weaponId, unit);\n }\n for (const option of raw.wargearOptions) {\n push(this.wargearOptionsByUnit, option.unit_id, option);\n }\n const seenByKeyword = new Map<string, Set<string>>();\n for (const weapon of raw.weapons) {\n for (const profile of weapon.profiles) {\n for (const ref of profile.keywords ?? []) {\n let seen = seenByKeyword.get(ref.keyword_id);\n if (!seen) {\n seen = new Set();\n seenByKeyword.set(ref.keyword_id, seen);\n }\n if (seen.has(weapon.id)) continue;\n seen.add(weapon.id);\n push(this.weaponsByKeyword, ref.keyword_id, weapon);\n }\n }\n }\n }\n}\n\n/** Build a passthrough collection for an id-bearing record type. */\nfunction idCollection<T extends { id: string }>(\n items: T[],\n factionOf?: (item: T) => string | null | undefined,\n): Collection<T, T> {\n return new Collection<T, T>({\n items,\n idOf: (i) => i.id,\n nameOf: (i) => (i as { name?: string }).name,\n factionOf,\n wrap: (i) => i,\n });\n}\n\nfunction push<T>(map: Map<string, T[]>, key: string, value: T): void {\n const existing = map.get(key);\n if (existing) existing.push(value);\n else map.set(key, [value]);\n}\n\n/** Map an EligibleAbility back to the BuffSource the translator expects. */\nfunction bufferSourceFromEligible(entry: EligibleAbility): BuffSource {\n const abilityId = entry.ability.id;\n switch (entry.source.kind) {\n case \"army\":\n return { kind: \"ability\", abilityId, abilityKind: \"army\" };\n case \"detachment\":\n return { kind: \"ability\", abilityId, abilityKind: \"detachment\" };\n case \"detachment-stratagem\":\n return { kind: \"ability\", abilityId, abilityKind: \"detachment-stratagem\" };\n case \"unit\":\n return { kind: \"ability\", abilityId, abilityKind: \"unit\" };\n case \"attached\":\n return {\n kind: \"ability\",\n abilityId,\n abilityKind: \"attached\",\n sourceUnitId: entry.source.unitId,\n };\n case \"support\":\n return { kind: \"ability\", abilityId, abilityKind: \"support\" };\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"dataset.js","sourceRoot":"","sources":["../../src/data/dataset.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * {@link Dataset} ties the embedded records together: it owns every\n * {@link Collection}, builds the cross-entity indexes once, and is the `this`\n * the linked views resolve against.\n *\n * @packageDocumentation\n */\nimport type {\n AlliedRule,\n DeploymentPattern,\n Detachment,\n Enhancement,\n ForceDisposition,\n GameVersion,\n HullShape,\n InteractionFlag,\n LeaderAttachment,\n Mission,\n MissionMatchup,\n Phase,\n ResourcePool,\n SecondaryCard,\n Stratagem,\n TargetProfile,\n TerrainLayout,\n TerrainTemplate,\n TimingFlag,\n Unit,\n UnitComposition,\n Wargear,\n WargearOption,\n WeaponKeyword,\n} from \"../generated.js\";\nimport { Collection } from \"./collection.js\";\nimport {\n AbilityView,\n FactionView,\n UnitView,\n WeaponKeywordView,\n WeaponView,\n} from \"./entities.js\";\nimport { emptyRawData, type RawData } from \"./types.js\";\nimport { RAW_DATA } from \"./bundle.generated.js\";\nimport { resolveLayout, type ResolvedPiece } from \"../terrain/resolve.js\";\nimport type { Buff, BuffSource, EngineContext } from \"../cruncher/buffs.js\";\nimport {\n resolveEligibleAbilities,\n type EligibilityInput,\n type EligibleAbility,\n} from \"../abilities-resolver/index.js\";\n\n/**\n * One toggleable buff lever for damage analysis: the contributions it adds and\n * whether it's on by default. `enabled` is `true` for buffs that always apply\n * (intrinsic keywords, unconditional abilities) and `false` for player\n * decisions — stratagems (CP cost) and activatable gates (dice-pool options,\n * `choice` branches, timing-gated activations). A consumer flips `enabled`,\n * then crunches the enabled subset; an optimizer searches it.\n *\n * @see {@link Dataset.stackableBuffsFor}\n */\nexport type StackableBuff = {\n /** Stable toggle id (stable across re-enumeration of the same input). */\n id: string;\n /** Human label for the lever. */\n label: string;\n /** Contributions this lever adds when enabled (≥1). */\n buffs: Buff[];\n /** Default selection state. */\n enabled: boolean;\n /** Where the lever came from. */\n source: BuffSource;\n /** Id of the mutually-limited {@link StackableBuffGroup} this belongs to, if any. */\n group?: string;\n};\n\n/** A pool of {@link StackableBuff} levers limited to `maxActivations` at once. */\nexport type StackableBuffGroup = {\n id: string;\n label: string;\n maxActivations: number;\n};\n\n/** The whole dataset, with linked accessors over every entity collection. */\nexport class Dataset {\n // Richly-linked collections.\n readonly units: Collection<Unit, UnitView>;\n readonly weapons: Collection<RawData[\"weapons\"][number], WeaponView>;\n readonly weaponKeywords: Collection<WeaponKeyword, WeaponKeywordView>;\n readonly factions: Collection<RawData[\"factions\"][number], FactionView>;\n readonly abilities: Collection<RawData[\"abilities\"][number], AbilityView>;\n\n // Id-bearing collections without bespoke views (records returned as-is).\n readonly targetProfiles: Collection<TargetProfile, TargetProfile>;\n readonly detachments: Collection<Detachment, Detachment>;\n readonly alliedRules: Collection<AlliedRule, AlliedRule>;\n readonly enhancements: Collection<Enhancement, Enhancement>;\n readonly stratagems: Collection<Stratagem, Stratagem>;\n readonly wargearOptions: Collection<WargearOption, WargearOption>;\n readonly wargear: Collection<Wargear, Wargear>;\n readonly missions: Collection<Mission, Mission>;\n readonly missionMatchups: Collection<MissionMatchup, MissionMatchup>;\n readonly missionCards: Collection<SecondaryCard, SecondaryCard>;\n readonly deploymentPatterns: Collection<DeploymentPattern, DeploymentPattern>;\n readonly forceDispositions: Collection<ForceDisposition, ForceDisposition>;\n readonly terrainTemplates: Collection<TerrainTemplate, TerrainTemplate>;\n readonly terrainLayouts: Collection<TerrainLayout, TerrainLayout>;\n readonly hullShapes: Collection<HullShape, HullShape>;\n readonly resourcePools: Collection<ResourcePool, ResourcePool>;\n\n // Id-less collections, exposed as plain arrays.\n readonly leaderAttachments: readonly LeaderAttachment[];\n readonly unitCompositions: readonly UnitComposition[];\n readonly gameVersions: readonly GameVersion[];\n readonly timingFlags: readonly TimingFlag[];\n readonly interactionFlags: readonly InteractionFlag[];\n readonly phaseMappings: readonly RawData[\"phaseMappings\"][number][];\n\n /** `source_type:source_id` → unioned phases. */\n private readonly phaseIndex = new Map<string, Phase[]>();\n /** ability id → units that list it. */\n private readonly unitsByAbility = new Map<string, Unit[]>();\n /** weapon id → units that list it. */\n private readonly unitsByWeapon = new Map<string, Unit[]>();\n /** weapon-keyword id → weapons whose profiles reference it. */\n private readonly weaponsByKeyword = new Map<string, RawData[\"weapons\"][number][]>();\n /** lowercased keyword → units carrying it (in `keywords` or `faction_keywords`). */\n private readonly unitsByKeyword = new Map<string, Unit[]>();\n /** unit id → wargear options authored for it (declared order preserved). */\n private readonly wargearOptionsByUnit = new Map<string, WargearOption[]>();\n\n constructor(raw: RawData = emptyRawData()) {\n this.units = new Collection({\n items: raw.units,\n idOf: (u) => u.id,\n // The same unit id is shared across factions (e.g. ministorum-priest);\n // keep each faction's copy, collapse only true within-faction duplicates.\n dedupeKeyOf: (u) => `${u.faction_id}::${u.id}`,\n nameOf: (u) => u.name,\n factionOf: (u) => u.faction_id,\n wrap: (u) => new UnitView(u, this),\n });\n this.weapons = new Collection({\n items: raw.weapons,\n idOf: (w) => w.id,\n nameOf: (w) => w.name,\n wrap: (w) => new WeaponView(w, this),\n });\n this.weaponKeywords = new Collection({\n items: raw.weaponKeywords,\n idOf: (k) => k.id,\n nameOf: (k) => k.name,\n wrap: (k) => new WeaponKeywordView(k, this),\n });\n this.factions = new Collection({\n items: raw.factions,\n idOf: (f) => f.id,\n nameOf: (f) => f.name,\n wrap: (f) => new FactionView(f, this),\n });\n this.abilities = new Collection({\n items: raw.abilities,\n idOf: (a) => a.ability_id,\n nameOf: (a) => a.name,\n factionOf: (a) => a.faction_id,\n wrap: (a) => new AbilityView(a, this),\n });\n\n this.targetProfiles = idCollection(raw.targetProfiles, (p) => p.faction_id);\n // A detachment id is shared across factions: the generic Codex Space Marine\n // detachments are replicated into every Codex-compatible chapter/supplement\n // (each as its own faction view), so keep each faction's copy and collapse\n // only true within-faction duplicates — mirroring the unit collection. Use\n // {@link Collection.getInFaction} / {@link Collection.byFaction} when a\n // faction context is known; bare {@link Collection.get} returns whichever\n // copy was registered first.\n this.detachments = new Collection({\n items: raw.detachments,\n idOf: (d) => d.id,\n nameOf: (d) => d.name,\n dedupeKeyOf: (d) => `${d.faction_id}::${d.id}`,\n factionOf: (d) => d.faction_id,\n wrap: (d) => d,\n });\n // Allied rules aren't owned by one faction (Daemonic Pact is shared by\n // Chaos Knights and CSM); `alliesFor` matches on `army_keywords_any` instead.\n this.alliedRules = idCollection(raw.alliedRules);\n this.enhancements = idCollection(raw.enhancements);\n this.stratagems = idCollection(raw.stratagems);\n this.wargearOptions = idCollection(raw.wargearOptions);\n this.wargear = idCollection(raw.wargear);\n this.missions = idCollection(raw.missions);\n this.missionMatchups = idCollection(raw.missionMatchups);\n this.missionCards = idCollection(raw.missionCards);\n this.deploymentPatterns = idCollection(raw.deploymentPatterns);\n this.forceDispositions = idCollection(raw.forceDispositions);\n this.terrainTemplates = idCollection(raw.terrainTemplates);\n this.terrainLayouts = idCollection(raw.terrainLayouts);\n this.hullShapes = idCollection(raw.hullShapes);\n this.resourcePools = idCollection(raw.resourcePools);\n\n this.leaderAttachments = raw.leaderAttachments;\n this.unitCompositions = raw.unitCompositions;\n this.gameVersions = raw.gameVersions;\n this.timingFlags = raw.timingFlags;\n this.interactionFlags = raw.interactionFlags;\n this.phaseMappings = raw.phaseMappings;\n\n this.buildIndexes(raw);\n }\n\n /** The dataset built from the package's embedded data. */\n static embedded(): Dataset {\n return new Dataset(RAW_DATA);\n }\n\n /** Phases a source acts in, unioned across its phase-mappings. */\n phasesFor(sourceType: string, sourceId: string): Phase[] {\n return this.phaseIndex.get(`${sourceType}:${sourceId}`) ?? [];\n }\n\n /**\n * Resolve a terrain layout to absolute board-space vertices using this\n * dataset's embedded terrain-template catalog — the layout-id →\n * renderable-geometry hop. Mirror of Rust `Dataset::resolve_terrain`; the\n * geometry is pinned by the `terrain-resolver` conformance corpus.\n */\n resolveTerrain(layout: TerrainLayout): ResolvedPiece[] {\n // The resolver takes its own structurally-identical input types, decoupled\n // from the generated `anyOf`/newtype shapes; the underlying JSON is the same.\n return resolveLayout(layout as never, this.terrainTemplates.all as never);\n }\n\n /**\n * The terrain layouts a deployment pattern recommends, in declared order,\n * skipping any ids absent from the dataset.\n */\n recommendedTerrainLayouts(pattern: DeploymentPattern): TerrainLayout[] {\n return (pattern.recommended_terrain_layout_ids ?? [])\n .map((id) => this.terrainLayouts.get(id))\n .filter((l): l is TerrainLayout => l !== undefined);\n }\n\n /** Units that list the given ability id. */\n unitsWithAbility(abilityId: string): UnitView[] {\n return (this.unitsByAbility.get(abilityId) ?? []).map((u) => new UnitView(u, this));\n }\n\n /** Units that list the given weapon id. */\n unitsWithWeapon(weaponId: string): UnitView[] {\n return (this.unitsByWeapon.get(weaponId) ?? []).map((u) => new UnitView(u, this));\n }\n\n /** Weapons whose profiles reference the given weapon-keyword id. */\n weaponsWithKeyword(keywordId: string): WeaponView[] {\n return (this.weaponsByKeyword.get(keywordId) ?? []).map((w) => new WeaponView(w, this));\n }\n\n /**\n * Units carrying the given keyword, matched case-insensitively against the\n * union of each unit's `keywords` and `faction_keywords`. Powers a list\n * builder's keyword search bar (type \"Khorne\" to find every Khorne unit),\n * across the whole dataset — so it also surfaces cross-faction ally pools.\n * Returns each faction's copy of a shared unit id separately.\n */\n unitsWithKeyword(keyword: string): UnitView[] {\n return (this.unitsByKeyword.get(keyword.toLowerCase()) ?? []).map((u) => new UnitView(u, this));\n }\n\n /**\n * The allied-rules **offered** for an army of `factionId` running the given\n * detachments. A rule applies when both its gates pass: the **army gate**\n * (`army_keywords_any` empty, or intersecting the faction's keywords) and the\n * **detachment gate** (`detachment_id` null, or among `detachmentIds`). Order\n * follows the allied-rules data file. The strict \"every *model* carries an\n * army keyword\" check (for soup lists) is a builder/validation concern — this\n * offers the candidate rules a faction qualifies for. Mirror of Rust\n * `Dataset::allies_for`; pinned by the `allies_for` conformance query.\n */\n alliesFor(factionId: string, detachmentIds: string[] = []): AlliedRule[] {\n const faction = this.factions.get(factionId);\n if (!faction) return [];\n const factionKeywords = new Set((faction.raw.keywords ?? []).map((k) => k.toLowerCase()));\n const detachmentSet = new Set(detachmentIds);\n return this.alliedRules.all.filter((rule) => {\n const armyGate =\n (rule.army_keywords_any ?? []).length === 0 ||\n (rule.army_keywords_any ?? []).some((k) => factionKeywords.has(k.toLowerCase()));\n const detachmentGate =\n rule.detachment_id == null || detachmentSet.has(rule.detachment_id);\n return armyGate && detachmentGate;\n });\n }\n\n /**\n * The unit pool an allied-rule grants, sorted by name. Starts from the rule's\n * `source_faction_id` (if set, to keep that faction's copy of shared ids) or\n * the whole dataset, narrows to units carrying any `source_keywords`, then\n * applies `required_keywords` (all present), `excluded_keywords` (none\n * present), and `roles`. Empty for an unknown rule id or a pool that resolves\n * to nothing. Mirror of Rust `Dataset::ally_units_for`; pinned by the\n * `ally_units_for` conformance query.\n */\n allyUnitsFor(ruleId: string): UnitView[] {\n const rule = this.alliedRules.get(ruleId);\n if (!rule) return [];\n const base = rule.source_faction_id\n ? this.units.byFaction(rule.source_faction_id)\n : this.units.all;\n const sourceKeywords = (rule.source_keywords ?? []).map((k) => k.toLowerCase());\n const required = (rule.required_keywords ?? []).map((k) => k.toLowerCase());\n const excluded = (rule.excluded_keywords ?? []).map((k) => k.toLowerCase());\n const roles = new Set(rule.roles ?? []);\n const out = base.filter((u) => {\n const have = unitKeywordSet(u.raw);\n if (sourceKeywords.length > 0 && !sourceKeywords.some((k) => have.has(k))) return false;\n if (required.length > 0 && !required.every((k) => have.has(k))) return false;\n if (excluded.some((k) => have.has(k))) return false;\n if (roles.size > 0 && !(u.raw.role && roles.has(u.raw.role))) return false;\n return true;\n });\n return out.sort((a, b) => a.name.localeCompare(b.name));\n }\n\n /**\n * Wargear options authored for the given unit, in declared order. Mirror of\n * Rust `Dataset::wargear_options_of`. Empty for a unit with no options.\n */\n wargearOptionsOf(unit: Unit): WargearOption[] {\n return this.wargearOptionsByUnit.get(unit.id) ?? [];\n }\n\n /**\n * Leaders whose leader-attachment data lists `bodyguardUnitId` among its\n * eligible body units, sorted by name. The attachment is stored on the\n * leader pointing down to its bodyguards, so answering \"which leaders can\n * attach to this unit?\" means scanning the attachment list. Returns an empty\n * array for a unit that no leader can attach to (including leader units).\n */\n leadersAttachableTo(bodyguardUnitId: string): UnitView[] {\n return this.leaderAttachments\n .filter((la) => la.eligible_bodyguard_ids.includes(bodyguardUnitId))\n .map((la) => this.units.get(la.leader_id))\n .filter((u): u is UnitView => u !== undefined)\n .sort((a, b) => a.name.localeCompare(b.name));\n }\n\n /**\n * The inverse of {@link leadersAttachableTo}: the body units the given\n * leader can attach to, sorted by name. Scans the same leader-attachment\n * data from the leader's side (`leader_id` matches; resolve each\n * `eligible_bodyguard_ids` entry), deduped by id. Empty for a non-leader\n * unit. Together the two queries give the bidirectional attachment graph the\n * SPA needs to offer a partner dropdown from either end.\n */\n bodyguardsAttachableFrom(leaderUnitId: string): UnitView[] {\n const seen = new Set<string>();\n const out: UnitView[] = [];\n for (const la of this.leaderAttachments) {\n if (la.leader_id !== leaderUnitId) continue;\n for (const bodyguardId of la.eligible_bodyguard_ids) {\n if (seen.has(bodyguardId)) continue;\n const unit = this.units.get(bodyguardId);\n if (!unit) continue;\n seen.add(bodyguardId);\n out.push(unit);\n }\n }\n return out.sort((a, b) => a.name.localeCompare(b.name));\n }\n\n /**\n * Enumerate every ability that could apply to the given unit in `phase`,\n * grouped by source. The SPA uses this to render the abilities pane.\n */\n eligibleAbilities(input: EligibilityInput, phase: Phase): EligibleAbility[] {\n return resolveEligibleAbilities(this, input, phase);\n }\n\n /**\n * Attacker-perspective {@link Buff} stack for a (unit, phase) combination:\n * intrinsic weapon-profile keywords plus every eligible ability whose DSL\n * effect translates to an attacker-side buff (army, detachment, unit,\n * attached members, support, plus any stratagems the caller has opted into).\n *\n * The result includes only buffs the buff layer can express today — the\n * `unsupported` half of the DSL→Buff translation is dropped here so callers\n * who just want the stack don't need to thread diagnostics through. Use\n * {@link AbilityView.describeBuffs} when you need the diagnostics for an\n * individual ability. Symmetric to {@link defensiveBuffsFor}, which walks\n * the same eligibility set under target perspective.\n */\n buffsFor(\n input: EligibilityInput & {\n weaponProfiles?: { weaponId: string; profileIndex: number }[];\n /** Stratagem ids the caller has opted into spending CP on. */\n optedInStratagemIds?: string[];\n },\n context: EngineContext,\n ): Buff[] {\n return this.collectBuffs(input, context, \"attacker\");\n }\n\n /**\n * Defender-perspective buff stack for the chosen unit: walks the same\n * eligible-abilities set as {@link buffsFor} but translates each ability's\n * DSL effect as defensive (FNP, save mods from `stat-modifier Sv`,\n * toughness mods from `stat-modifier T`, save rerolls, incoming hit\n * penalties from `bs-modifier`). Use this when the chosen unit is being\n * crunched as the *target* — the engine reads `feelNoPain`/`saveMod`/\n * `toughnessMod` out of `resolveBuffs` so wiring the result into `crunch`\n * just means concatenating onto the existing `buffs` array.\n *\n * `weaponProfiles` are ignored under target perspective — weapon-keyword\n * effects ride with the firing weapon, not the receiving unit.\n */\n defensiveBuffsFor(\n input: EligibilityInput & { optedInStratagemIds?: string[] },\n context: EngineContext,\n ): Buff[] {\n return this.collectBuffs(input, context, \"target\");\n }\n\n /**\n * Enumerate every attacker-side buff a unit could stack in `context` as a\n * list of toggleable levers, plus the activation groups that limit them.\n *\n * Unlike {@link buffsFor} — which returns only the buffs that auto-apply —\n * this surfaces the *player decisions* too: stratagems, and the activatable\n * gates the DSL models as dice-pool options, `choice` branches, or\n * timing-gated activations (e.g. Blessings of Khorne's three keyword grants).\n * Each lever carries `enabled` (its default state) and, where it's part of a\n * limited pool, a `group` id whose {@link StackableBuffGroup} caps how many\n * can fire at once. The intended loop:\n *\n * ```ts\n * const { buffs } = ds.stackableBuffsFor(input, ctx);\n * const chosen = buffs.filter(b => b.enabled).flatMap(b => b.buffs);\n * crunch({ ...profiles, buffs: chosen, context: ctx }, ds);\n * ```\n *\n * Target/phase conditions a lever still carries (e.g. \"vs Infantry\") ride on\n * each buff's `applicableWhen`, so toggling it on is always safe — the\n * resolver gates it per-target.\n */\n stackableBuffsFor(\n input: EligibilityInput & {\n weaponProfiles?: { weaponId: string; profileIndex: number }[];\n },\n context: EngineContext,\n ): { buffs: StackableBuff[]; groups: StackableBuffGroup[] } {\n const buffs: StackableBuff[] = [];\n const groups = new Map<string, StackableBuffGroup>();\n\n // Surface the attachment fact to the DSL translator so `is-attached` /\n // `model-is-leader` conditions can evaluate. Clone — never mutate the\n // caller's context. An explicitly-set flag wins over the derivation.\n const ctx: EngineContext = {\n ...context,\n attackerAttached: context.attackerAttached ?? (input.attachedUnitIds?.length ?? 0) > 0,\n };\n\n // Intrinsic weapon-profile keywords — always on.\n for (const ref of input.weaponProfiles ?? []) {\n const weapon = this.weapons.get(ref.weaponId);\n if (!weapon) continue;\n const wk = weapon.profileBuffs(ref.profileIndex, ctx);\n if (wk.length === 0) continue;\n buffs.push({\n id: `weapon:${ref.weaponId}:${ref.profileIndex}`,\n label: `${weapon.name} keywords`,\n buffs: wk,\n enabled: true,\n source: wk[0].source,\n });\n }\n\n for (const entry of this.eligibleAbilities(input, ctx.phase)) {\n const source = bufferSourceFromEligible(entry);\n const { applied, activatable } = entry.ability.describeBuffs(source, ctx, \"attacker\");\n // Stratagems cost CP — opt-in, not on by default.\n const isStratagem = entry.source.kind === \"detachment-stratagem\";\n\n if (applied.length > 0) {\n buffs.push({\n id: `${entry.source.kind}:${entry.ability.id}`,\n label: entry.ability.name,\n buffs: applied,\n enabled: !isStratagem,\n source,\n });\n }\n\n for (const act of activatable) {\n let groupId: string | undefined;\n if (act.group) {\n groupId = act.group.id;\n if (!groups.has(groupId)) {\n groups.set(groupId, {\n id: groupId,\n label: entry.ability.name,\n maxActivations: act.group.maxActivations,\n });\n }\n }\n buffs.push({\n id: act.id,\n label: `${entry.ability.name} — ${act.label}`,\n buffs: act.buffs,\n enabled: false,\n source,\n group: groupId,\n });\n }\n }\n\n return { buffs, groups: [...groups.values()] };\n }\n\n /** Shared implementation for buffsFor / defensiveBuffsFor. */\n private collectBuffs(\n input: EligibilityInput & {\n weaponProfiles?: { weaponId: string; profileIndex: number }[];\n optedInStratagemIds?: string[];\n },\n context: EngineContext,\n perspective: \"attacker\" | \"target\",\n ): Buff[] {\n const out: Buff[] = [];\n\n // Surface the attachment fact to the DSL translator (see stackableBuffsFor).\n // Clone — never mutate the caller's context; explicit flag wins.\n const ctx: EngineContext = {\n ...context,\n attackerAttached: context.attackerAttached ?? (input.attachedUnitIds?.length ?? 0) > 0,\n };\n\n // Weapon-profile keywords are attacker-only.\n if (perspective === \"attacker\") {\n for (const ref of input.weaponProfiles ?? []) {\n const weapon = this.weapons.get(ref.weaponId);\n if (!weapon) continue;\n out.push(...weapon.profileBuffs(ref.profileIndex, ctx));\n }\n }\n\n const optedIn = new Set(input.optedInStratagemIds ?? []);\n for (const entry of this.eligibleAbilities(input, ctx.phase)) {\n if (entry.source.kind === \"detachment-stratagem\" && !optedIn.has(entry.source.stratagemId)) {\n continue;\n }\n const source = bufferSourceFromEligible(entry);\n out.push(...entry.ability.getBuffs(source, ctx, perspective));\n }\n\n return out;\n }\n\n private buildIndexes(raw: RawData): void {\n for (const pm of raw.phaseMappings) {\n const key = `${pm.source_type}:${pm.source_id}`;\n const existing = this.phaseIndex.get(key) ?? [];\n for (const phase of pm.phases) {\n if (!existing.includes(phase)) existing.push(phase);\n }\n this.phaseIndex.set(key, existing);\n }\n for (const unit of raw.units) {\n for (const abilityId of unit.ability_ids ?? []) push(this.unitsByAbility, abilityId, unit);\n for (const weaponId of unit.weapon_ids ?? []) push(this.unitsByWeapon, weaponId, unit);\n // Index every keyword the unit carries (unit keywords ∪ faction keywords),\n // lowercased, deduped per-unit so an overlap doesn't list the unit twice.\n const seenKw = new Set<string>();\n for (const kw of [...(unit.keywords ?? []), ...(unit.faction_keywords ?? [])]) {\n const key = kw.toLowerCase();\n if (seenKw.has(key)) continue;\n seenKw.add(key);\n push(this.unitsByKeyword, key, unit);\n }\n }\n for (const option of raw.wargearOptions) {\n push(this.wargearOptionsByUnit, option.unit_id, option);\n }\n const seenByKeyword = new Map<string, Set<string>>();\n for (const weapon of raw.weapons) {\n for (const profile of weapon.profiles) {\n for (const ref of profile.keywords ?? []) {\n let seen = seenByKeyword.get(ref.keyword_id);\n if (!seen) {\n seen = new Set();\n seenByKeyword.set(ref.keyword_id, seen);\n }\n if (seen.has(weapon.id)) continue;\n seen.add(weapon.id);\n push(this.weaponsByKeyword, ref.keyword_id, weapon);\n }\n }\n }\n }\n}\n\n/** Build a passthrough collection for an id-bearing record type. */\nfunction idCollection<T extends { id: string }>(\n items: T[],\n factionOf?: (item: T) => string | null | undefined,\n): Collection<T, T> {\n return new Collection<T, T>({\n items,\n idOf: (i) => i.id,\n nameOf: (i) => (i as { name?: string }).name,\n factionOf,\n wrap: (i) => i,\n });\n}\n\nfunction push<T>(map: Map<string, T[]>, key: string, value: T): void {\n const existing = map.get(key);\n if (existing) existing.push(value);\n else map.set(key, [value]);\n}\n\n/** Lowercased union of a unit's `keywords` and `faction_keywords`, for membership tests. */\nfunction unitKeywordSet(unit: Unit): Set<string> {\n const out = new Set<string>();\n for (const k of unit.keywords ?? []) out.add(k.toLowerCase());\n for (const k of unit.faction_keywords ?? []) out.add(k.toLowerCase());\n return out;\n}\n\n/** Map an EligibleAbility back to the BuffSource the translator expects. */\nfunction bufferSourceFromEligible(entry: EligibleAbility): BuffSource {\n const abilityId = entry.ability.id;\n switch (entry.source.kind) {\n case \"army\":\n return { kind: \"ability\", abilityId, abilityKind: \"army\" };\n case \"detachment\":\n return { kind: \"ability\", abilityId, abilityKind: \"detachment\" };\n case \"detachment-stratagem\":\n return { kind: \"ability\", abilityId, abilityKind: \"detachment-stratagem\" };\n case \"unit\":\n return { kind: \"ability\", abilityId, abilityKind: \"unit\" };\n case \"attached\":\n return {\n kind: \"ability\",\n abilityId,\n abilityKind: \"attached\",\n sourceUnitId: entry.source.unitId,\n };\n case \"support\":\n return { kind: \"ability\", abilityId, abilityKind: \"support\" };\n }\n}\n"]}
|
package/dist/data/index.d.ts
CHANGED
|
@@ -33,6 +33,8 @@ export * from "../cruncher/index.js";
|
|
|
33
33
|
export { effectToBuffs, parseKeywordGrant } from "../cruncher/from-dsl.js";
|
|
34
34
|
export type { ActivatableBuff, ActivatableGroupRef, EffectTranslation, TranslationPerspective, UnsupportedFragment, } from "../cruncher/from-dsl.js";
|
|
35
35
|
export * from "../abilities-resolver/index.js";
|
|
36
|
+
export { encodeShareToken, decodeShareToken, shareRegistryVersion, ShareRegistryIndex, SHARE_FORMAT_VERSION, SHARE_KINDS, } from "../share/index.js";
|
|
37
|
+
export type { DecodeResult, ShareBattleSize, ShareList, ShareLoadoutEntry, ShareUnit, ShareKind, ShareRegistry, } from "../share/index.js";
|
|
36
38
|
export { resolveRosterUnit, resolveRosterWargear, resolveAttachedLeader, resolveAttachmentPartners, primaryDetachment, primaryDetachmentId, } from "./roster-resolve.js";
|
|
37
39
|
import { Dataset } from "./dataset.js";
|
|
38
40
|
/** The dataset built from this package's embedded data. */
|
|
@@ -51,6 +53,8 @@ export declare const factions: import("./collection.js").Collection<import("../g
|
|
|
51
53
|
export declare const abilities: import("./collection.js").Collection<import("../generated.js").AbilityDSLEntry, import("./entities.js").AbilityView>;
|
|
52
54
|
/** All detachments. */
|
|
53
55
|
export declare const detachments: import("./collection.js").Collection<import("../generated.js").Detachment, import("../generated.js").Detachment>;
|
|
56
|
+
/** All allied-detachment / 'soup' rules. */
|
|
57
|
+
export declare const alliedRules: import("./collection.js").Collection<import("../generated.js").AlliedRule, import("../generated.js").AlliedRule>;
|
|
54
58
|
/** All enhancements. */
|
|
55
59
|
export declare const enhancements: import("./collection.js").Collection<import("../generated.js").Enhancement, import("../generated.js").Enhancement>;
|
|
56
60
|
/** All stratagems. */
|
package/dist/data/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/data/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,YAAY,EAAE,aAAa,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AACtE,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,YAAY,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACxD,OAAO,EACL,QAAQ,EACR,WAAW,EACX,UAAU,EACV,iBAAiB,EACjB,WAAW,GACZ,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,YAAY,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAG1C,OAAO,EACL,SAAS,EACT,cAAc,EACd,YAAY,EACZ,gBAAgB,EAChB,eAAe,GAChB,MAAM,cAAc,CAAC;AACtB,YAAY,EAAE,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAKpE,cAAc,sBAAsB,CAAC;AAGrC,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC3E,YAAY,EACV,eAAe,EACf,mBAAmB,EACnB,iBAAiB,EACjB,sBAAsB,EACtB,mBAAmB,GACpB,MAAM,yBAAyB,CAAC;AAGjC,cAAc,gCAAgC,CAAC;AAG/C,OAAO,EACL,iBAAiB,EACjB,oBAAoB,EACpB,qBAAqB,EACrB,yBAAyB,EACzB,iBAAiB,EACjB,mBAAmB,GACpB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAEvC,2DAA2D;AAC3D,eAAO,MAAM,OAAO,SAAqB,CAAC;AAE1C,kEAAkE;AAClE,eAAO,MAAM,KAAK,wGAAgB,CAAC;AACnC,6EAA6E;AAC7E,eAAO,MAAM,cAAc,wHAAyB,CAAC;AACrD,wDAAwD;AACxD,eAAO,MAAM,OAAO,4GAAkB,CAAC;AACvC,kFAAkF;AAClF,eAAO,MAAM,cAAc,0HAAyB,CAAC;AACrD,mEAAmE;AACnE,eAAO,MAAM,QAAQ,8GAAmB,CAAC;AACzC,0EAA0E;AAC1E,eAAO,MAAM,SAAS,sHAAoB,CAAC;AAC3C,uBAAuB;AACvB,eAAO,MAAM,WAAW,kHAAsB,CAAC;AAC/C,wBAAwB;AACxB,eAAO,MAAM,YAAY,oHAAuB,CAAC;AACjD,sBAAsB;AACtB,eAAO,MAAM,UAAU,gHAAqB,CAAC;AAC7C,2BAA2B;AAC3B,eAAO,MAAM,cAAc,wHAAyB,CAAC;AACrD,yDAAyD;AACzD,eAAO,MAAM,OAAO,4GAAkB,CAAC;AACvC,oBAAoB;AACpB,eAAO,MAAM,QAAQ,4GAAmB,CAAC;AACzC,4BAA4B;AAC5B,eAAO,MAAM,eAAe,0HAA0B,CAAC;AACvD,mCAAmC;AACnC,eAAO,MAAM,YAAY,wHAAuB,CAAC;AACjD,+BAA+B;AAC/B,eAAO,MAAM,kBAAkB,gIAA6B,CAAC;AAC7D,8BAA8B;AAC9B,eAAO,MAAM,iBAAiB,8HAA4B,CAAC;AAC3D,qEAAqE;AACrE,eAAO,MAAM,gBAAgB,4HAA2B,CAAC;AACzD,2BAA2B;AAC3B,eAAO,MAAM,cAAc,wHAAyB,CAAC;AACrD,4EAA4E;AAC5E,eAAO,MAAM,UAAU,gHAAqB,CAAC;AAC7C,0BAA0B;AAC1B,eAAO,MAAM,aAAa,sHAAwB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/data/index.ts"],"names":[],"mappings":"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"}
|
package/dist/data/index.js
CHANGED
|
@@ -34,6 +34,8 @@ export * from "../cruncher/index.js";
|
|
|
34
34
|
export { effectToBuffs, parseKeywordGrant } from "../cruncher/from-dsl.js";
|
|
35
35
|
// The eligible-abilities resolver (also reachable as Dataset.eligibleAbilities).
|
|
36
36
|
export * from "../abilities-resolver/index.js";
|
|
37
|
+
// Compact, URL-safe list sharing (registry-indexed `share-v1` tokens).
|
|
38
|
+
export { encodeShareToken, decodeShareToken, shareRegistryVersion, ShareRegistryIndex, SHARE_FORMAT_VERSION, SHARE_KINDS, } from "../share/index.js";
|
|
37
39
|
// Bridge helpers from the importer's RosterUnit → linked views.
|
|
38
40
|
export { resolveRosterUnit, resolveRosterWargear, resolveAttachedLeader, resolveAttachmentPartners, primaryDetachment, primaryDetachmentId, } from "./roster-resolve.js";
|
|
39
41
|
import { Dataset } from "./dataset.js";
|
|
@@ -53,6 +55,8 @@ export const factions = dataset.factions;
|
|
|
53
55
|
export const abilities = dataset.abilities;
|
|
54
56
|
/** All detachments. */
|
|
55
57
|
export const detachments = dataset.detachments;
|
|
58
|
+
/** All allied-detachment / 'soup' rules. */
|
|
59
|
+
export const alliedRules = dataset.alliedRules;
|
|
56
60
|
/** All enhancements. */
|
|
57
61
|
export const enhancements = dataset.enhancements;
|
|
58
62
|
/** All stratagems. */
|
package/dist/data/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/data/index.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * The linked, typed 40kdc dataset.\n *\n * The default {@link dataset} is built once from the data embedded in this\n * package; the top-level collections below are its accessors, re-exported for\n * the ergonomic one-liner form.\n *\n * @packageDocumentation\n *\n * @example\n * import { units } from \"@alpaca-software/40kdc-data\";\n *\n * units.find(\"Kharn\")!.abilities\n * .filter(a => a.phases.includes(\"shooting\"))\n * .map(a => a.id); // [\"berzerker-frenzy\"]\n *\n * @example\n * import { factions } from \"@alpaca-software/40kdc-data\";\n *\n * factions.find(\"World Eaters\")!.units.length;\n */\nexport { Dataset } from \"./dataset.js\";\nexport type { StackableBuff, StackableBuffGroup } from \"./dataset.js\";\nexport { Collection } from \"./collection.js\";\nexport type { CollectionConfig } from \"./collection.js\";\nexport {\n UnitView,\n AbilityView,\n WeaponView,\n WeaponKeywordView,\n FactionView,\n} from \"./entities.js\";\nexport { normalizeName } from \"./normalize.js\";\nexport { emptyRawData } from \"./types.js\";\nexport type { RawData } from \"./types.js\";\n\n// Wargear-loadout maths: maximal default loadout, per-weapon bounds, validation.\nexport {\n optionCap,\n maximalLoadout,\n weaponBounds,\n clampWeaponCount,\n validateLoadout,\n} from \"./loadout.js\";\nexport type { Loadout, WeaponBound, Violation } from \"./loadout.js\";\n\n// The cruncher surface — buff types + the engine — re-exported from the data\n// package so downstream callers can import their whole 40kdc API from\n// `@alpaca-software/40kdc-data` without reaching into subpaths.\nexport * from \"../cruncher/index.js\";\n\n// The DSL→Buff translator that powers AbilityView.getBuffs / describeBuffs.\nexport { effectToBuffs, parseKeywordGrant } from \"../cruncher/from-dsl.js\";\nexport type {\n ActivatableBuff,\n ActivatableGroupRef,\n EffectTranslation,\n TranslationPerspective,\n UnsupportedFragment,\n} from \"../cruncher/from-dsl.js\";\n\n// The eligible-abilities resolver (also reachable as Dataset.eligibleAbilities).\nexport * from \"../abilities-resolver/index.js\";\n\n// Bridge helpers from the importer's RosterUnit → linked views.\nexport {\n resolveRosterUnit,\n resolveRosterWargear,\n resolveAttachedLeader,\n resolveAttachmentPartners,\n primaryDetachment,\n primaryDetachmentId,\n} from \"./roster-resolve.js\";\n\nimport { Dataset } from \"./dataset.js\";\n\n/** The dataset built from this package's embedded data. */\nexport const dataset = Dataset.embedded();\n\n/** All units, linked to their faction, weapons, and abilities. */\nexport const units = dataset.units;\n/** Named target archetypes referencing real units (faction_id + unit_id). */\nexport const targetProfiles = dataset.targetProfiles;\n/** All weapons, linked to the units that carry them. */\nexport const weapons = dataset.weapons;\n/** Catalog of weapon keywords (Lethal Hits, Sustained Hits N, Anti-X N+, ...). */\nexport const weaponKeywords = dataset.weaponKeywords;\n/** All factions, linked to their units, abilities, and weapons. */\nexport const factions = dataset.factions;\n/** All abilities, linked to their phases and the units that have them. */\nexport const abilities = dataset.abilities;\n/** All detachments. */\nexport const detachments = dataset.detachments;\n/** All enhancements. */\nexport const enhancements = dataset.enhancements;\n/** All stratagems. */\nexport const stratagems = dataset.stratagems;\n/** All wargear options. */\nexport const wargearOptions = dataset.wargearOptions;\n/** All non-weapon wargear items (icons, attachments). */\nexport const wargear = dataset.wargear;\n/** All missions. */\nexport const missions = dataset.missions;\n/** All mission matchups. */\nexport const missionMatchups = dataset.missionMatchups;\n/** All secondary mission cards. */\nexport const missionCards = dataset.missionCards;\n/** All deployment patterns. */\nexport const deploymentPatterns = dataset.deploymentPatterns;\n/** All force dispositions. */\nexport const forceDispositions = dataset.forceDispositions;\n/** Reusable terrain catalog: standard areas and scenery features. */\nexport const terrainTemplates = dataset.terrainTemplates;\n/** All terrain layouts. */\nexport const terrainLayouts = dataset.terrainLayouts;\n/** Reusable model collision hulls (polygon footprints) referenced by id. */\nexport const hullShapes = dataset.hullShapes;\n/** All resource pools. */\nexport const resourcePools = dataset.resourcePools;\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/data/index.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * The linked, typed 40kdc dataset.\n *\n * The default {@link dataset} is built once from the data embedded in this\n * package; the top-level collections below are its accessors, re-exported for\n * the ergonomic one-liner form.\n *\n * @packageDocumentation\n *\n * @example\n * import { units } from \"@alpaca-software/40kdc-data\";\n *\n * units.find(\"Kharn\")!.abilities\n * .filter(a => a.phases.includes(\"shooting\"))\n * .map(a => a.id); // [\"berzerker-frenzy\"]\n *\n * @example\n * import { factions } from \"@alpaca-software/40kdc-data\";\n *\n * factions.find(\"World Eaters\")!.units.length;\n */\nexport { Dataset } from \"./dataset.js\";\nexport type { StackableBuff, StackableBuffGroup } from \"./dataset.js\";\nexport { Collection } from \"./collection.js\";\nexport type { CollectionConfig } from \"./collection.js\";\nexport {\n UnitView,\n AbilityView,\n WeaponView,\n WeaponKeywordView,\n FactionView,\n} from \"./entities.js\";\nexport { normalizeName } from \"./normalize.js\";\nexport { emptyRawData } from \"./types.js\";\nexport type { RawData } from \"./types.js\";\n\n// Wargear-loadout maths: maximal default loadout, per-weapon bounds, validation.\nexport {\n optionCap,\n maximalLoadout,\n weaponBounds,\n clampWeaponCount,\n validateLoadout,\n} from \"./loadout.js\";\nexport type { Loadout, WeaponBound, Violation } from \"./loadout.js\";\n\n// The cruncher surface — buff types + the engine — re-exported from the data\n// package so downstream callers can import their whole 40kdc API from\n// `@alpaca-software/40kdc-data` without reaching into subpaths.\nexport * from \"../cruncher/index.js\";\n\n// The DSL→Buff translator that powers AbilityView.getBuffs / describeBuffs.\nexport { effectToBuffs, parseKeywordGrant } from \"../cruncher/from-dsl.js\";\nexport type {\n ActivatableBuff,\n ActivatableGroupRef,\n EffectTranslation,\n TranslationPerspective,\n UnsupportedFragment,\n} from \"../cruncher/from-dsl.js\";\n\n// The eligible-abilities resolver (also reachable as Dataset.eligibleAbilities).\nexport * from \"../abilities-resolver/index.js\";\n\n// Compact, URL-safe list sharing (registry-indexed `share-v1` tokens).\nexport {\n encodeShareToken,\n decodeShareToken,\n shareRegistryVersion,\n ShareRegistryIndex,\n SHARE_FORMAT_VERSION,\n SHARE_KINDS,\n} from \"../share/index.js\";\nexport type {\n DecodeResult,\n ShareBattleSize,\n ShareList,\n ShareLoadoutEntry,\n ShareUnit,\n ShareKind,\n ShareRegistry,\n} from \"../share/index.js\";\n\n// Bridge helpers from the importer's RosterUnit → linked views.\nexport {\n resolveRosterUnit,\n resolveRosterWargear,\n resolveAttachedLeader,\n resolveAttachmentPartners,\n primaryDetachment,\n primaryDetachmentId,\n} from \"./roster-resolve.js\";\n\nimport { Dataset } from \"./dataset.js\";\n\n/** The dataset built from this package's embedded data. */\nexport const dataset = Dataset.embedded();\n\n/** All units, linked to their faction, weapons, and abilities. */\nexport const units = dataset.units;\n/** Named target archetypes referencing real units (faction_id + unit_id). */\nexport const targetProfiles = dataset.targetProfiles;\n/** All weapons, linked to the units that carry them. */\nexport const weapons = dataset.weapons;\n/** Catalog of weapon keywords (Lethal Hits, Sustained Hits N, Anti-X N+, ...). */\nexport const weaponKeywords = dataset.weaponKeywords;\n/** All factions, linked to their units, abilities, and weapons. */\nexport const factions = dataset.factions;\n/** All abilities, linked to their phases and the units that have them. */\nexport const abilities = dataset.abilities;\n/** All detachments. */\nexport const detachments = dataset.detachments;\n/** All allied-detachment / 'soup' rules. */\nexport const alliedRules = dataset.alliedRules;\n/** All enhancements. */\nexport const enhancements = dataset.enhancements;\n/** All stratagems. */\nexport const stratagems = dataset.stratagems;\n/** All wargear options. */\nexport const wargearOptions = dataset.wargearOptions;\n/** All non-weapon wargear items (icons, attachments). */\nexport const wargear = dataset.wargear;\n/** All missions. */\nexport const missions = dataset.missions;\n/** All mission matchups. */\nexport const missionMatchups = dataset.missionMatchups;\n/** All secondary mission cards. */\nexport const missionCards = dataset.missionCards;\n/** All deployment patterns. */\nexport const deploymentPatterns = dataset.deploymentPatterns;\n/** All force dispositions. */\nexport const forceDispositions = dataset.forceDispositions;\n/** Reusable terrain catalog: standard areas and scenery features. */\nexport const terrainTemplates = dataset.terrainTemplates;\n/** All terrain layouts. */\nexport const terrainLayouts = dataset.terrainLayouts;\n/** Reusable model collision hulls (polygon footprints) referenced by id. */\nexport const hullShapes = dataset.hullShapes;\n/** All resource pools. */\nexport const resourcePools = dataset.resourcePools;\n"]}
|
package/dist/data/types.d.ts
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
*
|
|
8
8
|
* @packageDocumentation
|
|
9
9
|
*/
|
|
10
|
-
import type { AbilityDSLEntry, DeploymentPattern, Detachment, Enhancement, Faction, ForceDisposition, GameVersion, HullShape, InteractionFlag, LeaderAttachment, Mission, MissionMatchup, PhaseMapping, ResourcePool, SecondaryCard, Stratagem, TerrainLayout, TargetProfile, TerrainTemplate, TimingFlag, Unit, UnitComposition, Wargear, WargearOption, Weapon, WeaponKeyword } from "../generated.js";
|
|
10
|
+
import type { AbilityDSLEntry, AlliedRule, DeploymentPattern, Detachment, Enhancement, Faction, ForceDisposition, GameVersion, HullShape, InteractionFlag, LeaderAttachment, Mission, MissionMatchup, PhaseMapping, ResourcePool, SecondaryCard, Stratagem, TerrainLayout, TargetProfile, TerrainTemplate, TimingFlag, Unit, UnitComposition, Wargear, WargearOption, Weapon, WeaponKeyword } from "../generated.js";
|
|
11
11
|
/**
|
|
12
12
|
* Every entity collection in the dataset, keyed by camelCase collection name.
|
|
13
13
|
*
|
|
@@ -28,6 +28,8 @@ export interface RawData {
|
|
|
28
28
|
/** Phase assignments, joined to abilities/stratagems/etc. via `source_id`. */
|
|
29
29
|
phaseMappings: PhaseMapping[];
|
|
30
30
|
detachments: Detachment[];
|
|
31
|
+
/** Allied-detachment / 'soup' rules: how units lacking the army faction keyword may be included. */
|
|
32
|
+
alliedRules: AlliedRule[];
|
|
31
33
|
stratagems: Stratagem[];
|
|
32
34
|
enhancements: Enhancement[];
|
|
33
35
|
leaderAttachments: LeaderAttachment[];
|
package/dist/data/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/data/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,KAAK,EACV,eAAe,EACf,iBAAiB,EACjB,UAAU,EACV,WAAW,EACX,OAAO,EACP,gBAAgB,EAChB,WAAW,EACX,SAAS,EACT,eAAe,EACf,gBAAgB,EAChB,OAAO,EACP,cAAc,EACd,YAAY,EACZ,YAAY,EACZ,aAAa,EACb,SAAS,EACT,aAAa,EACb,aAAa,EACb,eAAe,EACf,UAAU,EACV,IAAI,EACJ,eAAe,EACf,OAAO,EACP,aAAa,EACb,MAAM,EACN,aAAa,EACd,MAAM,iBAAiB,CAAC;AAEzB;;;;;;GAMG;AACH,MAAM,WAAW,OAAO;IACtB,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,6EAA6E;IAC7E,cAAc,EAAE,aAAa,EAAE,CAAC;IAChC,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,kFAAkF;IAClF,cAAc,EAAE,aAAa,EAAE,CAAC;IAChC,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,4EAA4E;IAC5E,SAAS,EAAE,eAAe,EAAE,CAAC;IAC7B,8EAA8E;IAC9E,aAAa,EAAE,YAAY,EAAE,CAAC;IAC9B,WAAW,EAAE,UAAU,EAAE,CAAC;IAC1B,UAAU,EAAE,SAAS,EAAE,CAAC;IACxB,YAAY,EAAE,WAAW,EAAE,CAAC;IAC5B,iBAAiB,EAAE,gBAAgB,EAAE,CAAC;IACtC,gBAAgB,EAAE,eAAe,EAAE,CAAC;IACpC,cAAc,EAAE,aAAa,EAAE,CAAC;IAChC,mFAAmF;IACnF,OAAO,EAAE,OAAO,EAAE,CAAC;IACnB,YAAY,EAAE,WAAW,EAAE,CAAC;IAC5B,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,eAAe,EAAE,cAAc,EAAE,CAAC;IAClC,YAAY,EAAE,aAAa,EAAE,CAAC;IAC9B,kBAAkB,EAAE,iBAAiB,EAAE,CAAC;IACxC,iBAAiB,EAAE,gBAAgB,EAAE,CAAC;IACtC,qEAAqE;IACrE,gBAAgB,EAAE,eAAe,EAAE,CAAC;IACpC,2EAA2E;IAC3E,cAAc,EAAE,aAAa,EAAE,CAAC;IAChC,4EAA4E;IAC5E,UAAU,EAAE,SAAS,EAAE,CAAC;IACxB,aAAa,EAAE,YAAY,EAAE,CAAC;IAC9B,WAAW,EAAE,UAAU,EAAE,CAAC;IAC1B,gBAAgB,EAAE,eAAe,EAAE,CAAC;CACrC;AAED,uEAAuE;AACvE,wBAAgB,YAAY,IAAI,OAAO,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/data/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,KAAK,EACV,eAAe,EACf,UAAU,EACV,iBAAiB,EACjB,UAAU,EACV,WAAW,EACX,OAAO,EACP,gBAAgB,EAChB,WAAW,EACX,SAAS,EACT,eAAe,EACf,gBAAgB,EAChB,OAAO,EACP,cAAc,EACd,YAAY,EACZ,YAAY,EACZ,aAAa,EACb,SAAS,EACT,aAAa,EACb,aAAa,EACb,eAAe,EACf,UAAU,EACV,IAAI,EACJ,eAAe,EACf,OAAO,EACP,aAAa,EACb,MAAM,EACN,aAAa,EACd,MAAM,iBAAiB,CAAC;AAEzB;;;;;;GAMG;AACH,MAAM,WAAW,OAAO;IACtB,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,6EAA6E;IAC7E,cAAc,EAAE,aAAa,EAAE,CAAC;IAChC,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,kFAAkF;IAClF,cAAc,EAAE,aAAa,EAAE,CAAC;IAChC,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,4EAA4E;IAC5E,SAAS,EAAE,eAAe,EAAE,CAAC;IAC7B,8EAA8E;IAC9E,aAAa,EAAE,YAAY,EAAE,CAAC;IAC9B,WAAW,EAAE,UAAU,EAAE,CAAC;IAC1B,oGAAoG;IACpG,WAAW,EAAE,UAAU,EAAE,CAAC;IAC1B,UAAU,EAAE,SAAS,EAAE,CAAC;IACxB,YAAY,EAAE,WAAW,EAAE,CAAC;IAC5B,iBAAiB,EAAE,gBAAgB,EAAE,CAAC;IACtC,gBAAgB,EAAE,eAAe,EAAE,CAAC;IACpC,cAAc,EAAE,aAAa,EAAE,CAAC;IAChC,mFAAmF;IACnF,OAAO,EAAE,OAAO,EAAE,CAAC;IACnB,YAAY,EAAE,WAAW,EAAE,CAAC;IAC5B,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,eAAe,EAAE,cAAc,EAAE,CAAC;IAClC,YAAY,EAAE,aAAa,EAAE,CAAC;IAC9B,kBAAkB,EAAE,iBAAiB,EAAE,CAAC;IACxC,iBAAiB,EAAE,gBAAgB,EAAE,CAAC;IACtC,qEAAqE;IACrE,gBAAgB,EAAE,eAAe,EAAE,CAAC;IACpC,2EAA2E;IAC3E,cAAc,EAAE,aAAa,EAAE,CAAC;IAChC,4EAA4E;IAC5E,UAAU,EAAE,SAAS,EAAE,CAAC;IACxB,aAAa,EAAE,YAAY,EAAE,CAAC;IAC9B,WAAW,EAAE,UAAU,EAAE,CAAC;IAC1B,gBAAgB,EAAE,eAAe,EAAE,CAAC;CACrC;AAED,uEAAuE;AACvE,wBAAgB,YAAY,IAAI,OAAO,CA8BtC"}
|
package/dist/data/types.js
CHANGED
package/dist/data/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/data/types.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/data/types.ts"],"names":[],"mappings":"AAqFA,uEAAuE;AACvE,MAAM,UAAU,YAAY;IAC1B,OAAO;QACL,KAAK,EAAE,EAAE;QACT,cAAc,EAAE,EAAE;QAClB,OAAO,EAAE,EAAE;QACX,cAAc,EAAE,EAAE;QAClB,QAAQ,EAAE,EAAE;QACZ,SAAS,EAAE,EAAE;QACb,aAAa,EAAE,EAAE;QACjB,WAAW,EAAE,EAAE;QACf,WAAW,EAAE,EAAE;QACf,UAAU,EAAE,EAAE;QACd,YAAY,EAAE,EAAE;QAChB,iBAAiB,EAAE,EAAE;QACrB,gBAAgB,EAAE,EAAE;QACpB,cAAc,EAAE,EAAE;QAClB,OAAO,EAAE,EAAE;QACX,YAAY,EAAE,EAAE;QAChB,QAAQ,EAAE,EAAE;QACZ,eAAe,EAAE,EAAE;QACnB,YAAY,EAAE,EAAE;QAChB,kBAAkB,EAAE,EAAE;QACtB,iBAAiB,EAAE,EAAE;QACrB,gBAAgB,EAAE,EAAE;QACpB,cAAc,EAAE,EAAE;QAClB,UAAU,EAAE,EAAE;QACd,aAAa,EAAE,EAAE;QACjB,WAAW,EAAE,EAAE;QACf,gBAAgB,EAAE,EAAE;KACrB,CAAC;AACJ,CAAC","sourcesContent":["/**\n * The shape of the embedded data bundle: one named array per entity collection.\n *\n * `RawData` is the boundary between the generated JSON-Schema types and the\n * linked view layer. The codegen ({@link file://../codegen-data.ts}) emits a\n * `RAW_DATA: RawData` constant; {@link Dataset} wraps it with linked accessors.\n *\n * @packageDocumentation\n */\nimport type {\n AbilityDSLEntry,\n AlliedRule,\n DeploymentPattern,\n Detachment,\n Enhancement,\n Faction,\n ForceDisposition,\n GameVersion,\n HullShape,\n InteractionFlag,\n LeaderAttachment,\n Mission,\n MissionMatchup,\n PhaseMapping,\n ResourcePool,\n SecondaryCard,\n Stratagem,\n TerrainLayout,\n TargetProfile,\n TerrainTemplate,\n TimingFlag,\n Unit,\n UnitComposition,\n Wargear,\n WargearOption,\n Weapon,\n WeaponKeyword,\n} from \"../generated.js\";\n\n/**\n * Every entity collection in the dataset, keyed by camelCase collection name.\n *\n * Collections with no authored data yet (e.g. `interactionFlags`) are present\n * as empty arrays so the API surface is stable and new data flows through\n * automatically once authored.\n */\nexport interface RawData {\n units: Unit[];\n /** Named target archetypes referencing real units (faction_id + unit_id). */\n targetProfiles: TargetProfile[];\n weapons: Weapon[];\n /** Catalog of weapon keywords (Lethal Hits, Sustained Hits N, Anti-X N+, ...). */\n weaponKeywords: WeaponKeyword[];\n factions: Faction[];\n /** Community-authored ability mechanics (key is `ability_id`, not `id`). */\n abilities: AbilityDSLEntry[];\n /** Phase assignments, joined to abilities/stratagems/etc. via `source_id`. */\n phaseMappings: PhaseMapping[];\n detachments: Detachment[];\n /** Allied-detachment / 'soup' rules: how units lacking the army faction keyword may be included. */\n alliedRules: AlliedRule[];\n stratagems: Stratagem[];\n enhancements: Enhancement[];\n leaderAttachments: LeaderAttachment[];\n unitCompositions: UnitComposition[];\n wargearOptions: WargearOption[];\n /** Non-weapon wargear items (icons, attachments) referenced by wargear options. */\n wargear: Wargear[];\n gameVersions: GameVersion[];\n missions: Mission[];\n missionMatchups: MissionMatchup[];\n missionCards: SecondaryCard[];\n deploymentPatterns: DeploymentPattern[];\n forceDispositions: ForceDisposition[];\n /** Reusable terrain catalog: standard areas and scenery features. */\n terrainTemplates: TerrainTemplate[];\n /** Terrain layouts: arrangements of catalog/inline pieces on the board. */\n terrainLayouts: TerrainLayout[];\n /** Reusable model collision hulls (polygon footprints) referenced by id. */\n hullShapes: HullShape[];\n resourcePools: ResourcePool[];\n timingFlags: TimingFlag[];\n interactionFlags: InteractionFlag[];\n}\n\n/** A `RawData` with every collection initialised to an empty array. */\nexport function emptyRawData(): RawData {\n return {\n units: [],\n targetProfiles: [],\n weapons: [],\n weaponKeywords: [],\n factions: [],\n abilities: [],\n phaseMappings: [],\n detachments: [],\n alliedRules: [],\n stratagems: [],\n enhancements: [],\n leaderAttachments: [],\n unitCompositions: [],\n wargearOptions: [],\n wargear: [],\n gameVersions: [],\n missions: [],\n missionMatchups: [],\n missionCards: [],\n deploymentPatterns: [],\n forceDispositions: [],\n terrainTemplates: [],\n terrainLayouts: [],\n hullShapes: [],\n resourcePools: [],\n timingFlags: [],\n interactionFlags: [],\n };\n}\n"]}
|