`;
+ const UNIT_BULLET = noBullets ? '' : '• ';
+
+ const rawUnits = Array.isArray(data.units) ? data.units : [];
+ const units = maybeCombineUnits(rawUnits, hideSubunits, combineIdenticalUnits);
+
+ const renderUnit = (unit, prefix = '') => {
+ let outHtml = '', outPlain = '';
+ const hideSubunitsForThisUnit = hideSubunits || shouldHideSubunitsForUnit(unit, showMode);
+ const G = (unit.__groupCount !== undefined) ? unit.__groupCount : 1;
+ const M = (unit.__unitSize !== undefined) ? unit.__unitSize : getModelsCount(unit);
+ let qtyDisplay = '';
+ if (G > 1) {
+ qtyDisplay = M > 1 ? `${G}x${M} ` : `${G}x `;
+ } else {
+ qtyDisplay = M > 1 ? `${M} ` : '';
+ }
+
+ const categorySuffix = '';
+
+ if (useAbbreviations) {
+ const itemsString = getInlineItemsString(unit, useAbbreviations, wargearAbbrMap, summary, skippableWargearMap, showMandatoryWargear, hideSubunitsForThisUnit, showMode, hideBrackets);
+ const pointsString = hidePoints ? '' : (hideBrackets ? ` ${unit.points}` : ` [${unit.points}]`);
+ const finalUnitName = abbreviateUnitNames ? (findAbbreviationForItem(unit.name, wargearAbbrMap, summary) || makeAbbrevForName(unit.name)) : unit.name;
+ const unitText = `${prefix}${qtyDisplay}${finalUnitName}${categorySuffix}${itemsString}${pointsString}`;
+ outHtml += `
${unitText}
`;
+ outPlain += `${UNIT_BULLET}${unitText}\n`;
+
+ if (!hideSubunitsForThisUnit && Array.isArray(unit.subunits) && unit.subunits.length > 0) {
+ outHtml += `
`;
+ unit.subunits.forEach(sub => {
+ const subQty = parseInt((sub.quantity || '1').toString().replace('x', ''), 10) || 1;
+ const subQtyDisplay = subQty > 1 ? `${subQty} ` : '';
+
+ const filteredItems = (sub.wargear || []).filter(wg => {
+ if (showMode === 'show-all') return true;
+ if (showMode === 'hide-all') return false;
+ return !wg.skippable;
+ });
+
+ let subItemsText = '';
+ if (filteredItems.length > 0) {
+ const subItemsArr = filteredItems.map(wg => {
+ const wgQty = parseInt(wg.quantity || 1, 10);
+ const qtyStr = wgQty > 1 ? `${wgQty}x ` : '';
+ let abbr = null;
+ abbr = findAbbreviationForItem(wg.name, wargearAbbrMap, summary);
+ if (!abbr) abbr = makeAbbrevForName(wg.name);
+ return `${qtyStr}${abbr || wg.name}`;
+ });
+ subItemsText = hideBrackets ? ` ${subItemsArr.join(', ')}` : ` (${subItemsArr.join(', ')})`;
+ }
+
+ const finalSubName = abbreviateUnitNames ? (findAbbreviationForItem(sub.name, wargearAbbrMap, summary) || makeAbbrevForName(sub.name)) : sub.name;
+ outHtml += `
${subQtyDisplay}${finalSubName}${subItemsText}
`;
+ outPlain += ` * ${subQtyDisplay}${finalSubName}${subItemsText}\n`;
+ });
+ outHtml += `
`;
+ }
+ outHtml += `
`;
+ return { html: outHtml, plainText: outPlain };
+ }
+
+ const pointsString = hidePoints ? '' : (hideBrackets ? ` ${unit.points}` : ` [${unit.points}]`);
+ const finalUnitName = (useAbbreviations && abbreviateUnitNames) ? (findAbbreviationForItem(unit.name, wargearAbbrMap, summary) || makeAbbrevForName(unit.name)) : unit.name;
+ const unitText = `${prefix}${qtyDisplay}${finalUnitName}${categorySuffix}${pointsString}`;
+ outHtml += `
${unitText}
`;
+ outPlain += `${UNIT_BULLET}${unitText}\n`;
+
+ if (hideSubunitsForThisUnit) {
+ const aggregated = aggregateWargear(unit);
+ const visibleAggregated = aggregated.filter(it => {
+ if (showMode === 'show-all') return true;
+ if (showMode === 'hide-all') return false;
+ return !it.skippable;
+ });
+ if (visibleAggregated.length > 0) {
+ outHtml += `
`;
+ visibleAggregated.forEach(it => {
+ outHtml += `
${it.quantity} ${it.name}
`;
+ outPlain += ` - ${it.quantity} ${it.name}\n`;
+ });
+ outHtml += `
`;
+ }
+ } else {
+ // Render enhancements
+ if (Array.isArray(unit.enhancements) && unit.enhancements.length > 0) {
+ outHtml += `
`;
+ unit.enhancements.forEach(enh => {
+ const ptsStr = enh.points ? ` (+${enh.points})` : '';
+ outHtml += `
Enhancement: ${enh.name}${ptsStr}
`;
+ outPlain += ` - Enhancement: ${enh.name}${ptsStr}\n`;
+ });
+ outHtml += `
`;
+ }
+
+ // Render top-level wargear
+ if (Array.isArray(unit.wargear) && unit.wargear.length > 0) {
+ const visibleWargear = unit.wargear.filter(wg => {
+ if (showMode === 'show-all') return true;
+ if (showMode === 'hide-all') return false;
+ return !wg.skippable;
+ });
+ if (visibleWargear.length > 0) {
+ outHtml += `
`;
+ visibleWargear.forEach(wg => {
+ const wgQty = parseInt(wg.quantity || 1, 10);
+ const qtyStr = wgQty > 1 ? `${wgQty}x ` : '';
+ outHtml += `
${qtyStr}${wg.name}
`;
+ outPlain += ` - ${qtyStr}${wg.name}\n`;
+ });
+ outHtml += `
`;
+ }
+ }
+
+ // Render subunits
+ if (Array.isArray(unit.subunits) && unit.subunits.length > 0) {
+ outHtml += `
`;
+ unit.subunits.forEach(sub => {
+ const subQty = parseInt(sub.quantity || 1, 10);
+ const qtyStr = subQty > 1 ? `${subQty}x ` : '';
+
+ const visibleWargear = (sub.wargear || []).filter(wg => {
+ if (showMode === 'show-all') return true;
+ if (showMode === 'hide-all') return false;
+ return !wg.skippable;
+ });
+
+ const finalSubName = (useAbbreviations && abbreviateUnitNames) ? (findAbbreviationForItem(sub.name, wargearAbbrMap, summary) || makeAbbrevForName(sub.name)) : sub.name;
+ outHtml += `
${qtyStr}${finalSubName}
`;
+ outPlain += ` * ${qtyStr}${finalSubName}\n`;
+
+ visibleWargear.forEach(wg => {
+ const wgQty = parseInt(wg.quantity || 1, 10);
+ const wqtyStr = wgQty > 1 ? `${wgQty}x ` : '';
+ outHtml += `
${wqtyStr}${wg.name}
`;
+ outPlain += ` - ${wqtyStr}${wg.name}\n`;
+ });
+ });
+ outHtml += `
`;
+ }
+ }
+ outHtml += `
`;
+ return { html: outHtml, plainText: outPlain };
+ };
+
+ let attachedIndex = 0;
+ units.forEach(unit => {
+ if (unit.isAttached) {
+ attachedIndex++;
+ unit.attachedParts.forEach(part => {
+ const tag = getRoleTag(part, attachedIndex, hideBrackets);
+ const wTag = getWarlordTag(part, hideBrackets);
+ const tags = [tag, wTag].filter(Boolean).join('');
+ const prefix = tags ? `${tags} ` : '';
+ const rendered = renderUnit(part, prefix);
+ html += rendered.html;
+ plainText += rendered.plainText;
+ });
+ } else {
+ const wTag = getWarlordTag(unit, hideBrackets);
+ const prefix = wTag ? `${wTag} ` : '';
+ const rendered = renderUnit(unit, prefix);
+ html += rendered.html;
+ plainText += rendered.plainText;
+ }
+ });
+
+
+
+ html += `
`;
+ return { html, plainText };
+}
+
+export function generateDiscordText(data, plain, useAbbreviations = true, wargearAbbrMap, hideSubunits, skippableWargearMap, combineIdenticalUnits = false, options, noBullets = false, hidePoints = false) {
+ const hasDOM = (typeof document !== 'undefined' && document.querySelector);
+ let useColor = false;
+ const defaultColors = { unit: '#FFFFFF', subunit: '#808080', wargear: '#FFFFFF', points: '#FFFF00', header: '#FFFF00', attached: '#FFFF00' };
+ const colors = { ...defaultColors };
+ const summary = data.metadata || {};
+ const hideBrackets = !!(options && options.hideBrackets);
+
+ if (!plain) {
+ const mode = (options && options.colorMode) || (hasDOM ? ((document.querySelector('input[name="colorMode"]:checked') || {}).value || 'none') : 'none');
+ useColor = mode && mode !== 'none';
+ if (useColor && mode === 'custom') {
+ if (options && options.colors) {
+ const src = options.colors || {};
+ if (src.unit) colors.unit = src.unit;
+ if (src.subunit) colors.subunit = src.subunit;
+ if (src.wargear) colors.wargear = src.wargear;
+ if (src.points) colors.points = src.points;
+ if (src.header) colors.header = src.header;
+ if (src.attached) colors.attached = src.attached;
+ } else if (hasDOM) {
+ const u = document.getElementById('unitColor');
+ const s = document.getElementById('subunitColor');
+ const w = document.getElementById('wargearColor');
+ const p = document.getElementById('pointsColor');
+ const h = document.getElementById('headerColor');
+ const a = document.getElementById('attachedColor');
+ if (u && u.value) colors.unit = u.value;
+ if (s && s.value) colors.subunit = s.value;
+ if (w && w.value) colors.wargear = w.value;
+ if (p && p.value) colors.points = p.value;
+ if (h && h.value) colors.header = h.value;
+ if (a && a.value) colors.attached = a.value;
+ }
+ }
+ if (useColor && mode === 'faction') {
+ const factionMap = buildFactionColorMap(skippableWargearMap || {});
+ const rawFaction = summary.faction || null;
+ const factionKey = getCanonicalFactionName(rawFaction);
+ const normalizeKeyLookup = (s) => {
+ if (!s) return null;
+ try { return s.toString().normalize('NFD').replace(/\p{M}/gu, '').replace(/[\u2018\u2019\u201B\u2032]/g, "'").replace(/[^\w\s'\-]/g, '').toLowerCase().trim(); } catch (e) { return s.toString().toLowerCase(); }
+ };
+ const nfk = factionKey ? normalizeKeyLookup(factionKey) : null;
+ if (factionKey && (factionMap[factionKey] || factionMap[factionKey.toString().toLowerCase()] || (nfk && factionMap[nfk]))) {
+ const fm = factionMap[factionKey] || factionMap[factionKey.toString().toLowerCase()] || factionMap[nfk];
+ if (fm.unit) colors.unit = fm.unit;
+ if (fm.subunit) colors.subunit = fm.subunit;
+ if (fm.wargear) colors.wargear = fm.wargear;
+ if (fm.points) colors.points = fm.points;
+ if (fm.header) colors.header = fm.header;
+ if (fm.attached) colors.attached = fm.attached;
+ }
+ }
+ }
+
+ const toAnsi = (txt, hex, bold = false) => {
+ if (!useColor || !hex) return txt;
+ if (typeof hex === 'number' || (typeof hex === 'string' && /^\d+$/.test(hex))) {
+ const boldPart = bold ? '1;' : '';
+ return `\u001b[${boldPart}${hex}m${txt}\u001b[0m`;
+ }
+ const forcePalette = !!(options && options.forcePalette);
+ if (hasDOM && !forcePalette) {
+ const rgb = hexToRgb(hex);
+ if (!rgb) return txt;
+ const boldPart = bold ? '1;' : '';
+ return `\u001b[${boldPart}38;2;${rgb.r};${rgb.g};${rgb.b}m${txt}\u001b[0m`;
+ }
+ const code = findClosestAnsi(hex);
+ const boldPart = bold ? '1;' : '';
+ return `\u001b[${boldPart}${code}m${txt}\u001b[0m`;
+ };
+
+ const UNIT_BULLET = noBullets ? '' : (plain ? '• ' : '* ');
+ const SUB_BULLET = noBullets ? ' ' : (plain ? ' ◦ ' : ' + ');
+
+ const abbreviateHeader = !!(options && options.abbreviateHeader);
+ const showMandatoryWargear = !!(options && options.showMandatoryWargear);
+ const showMode = (options && options.wargearShowMode) || (showMandatoryWargear ? 'show-all' : 'hide-mandatory');
+ let out = '';
+ if (!plain) out += useColor ? '```ansi\n' : '```\n';
+
+ const headerParts = [];
+ const listName = summary.title || summary.armyName || '';
+ if (listName) headerParts.push(listName);
+ if (summary.faction) headerParts.push(summary.faction);
+
+ let dets = '';
+ if (Array.isArray(summary.detachments) && summary.detachments.length > 0) {
+ if (abbreviateHeader) {
+ dets = summary.detachments.map(d => abbreviateWords(d)).join(' & ');
+ } else {
+ dets = summary.detachments.join(' and ');
+ }
+ } else if (summary.detachment) {
+ if (abbreviateHeader) {
+ dets = abbreviateDetachment(summary.detachment);
+ } else {
+ dets = summary.detachment;
+ }
+ }
+ if (dets) headerParts.push(dets);
+
+ let disps = '';
+ if (Array.isArray(summary.forceDispositions) && summary.forceDispositions.length > 0) {
+ if (abbreviateHeader) {
+ disps = summary.forceDispositions.map(d => abbreviateWords(d)).join(', ');
+ } else {
+ disps = summary.forceDispositions.join(', ');
+ }
+ } else if (summary.forceDisposition) {
+ if (abbreviateHeader) {
+ disps = abbreviateForceDisposition(summary.forceDisposition);
+ } else {
+ disps = summary.forceDisposition;
+ }
+ }
+ if (disps) headerParts.push(disps);
+
+ const totalPts = summary.pointsTotal || summary.totalPoints || 0;
+ if (totalPts) {
+ const limit = summary.pointsLimit || 0;
+ const limitStr = limit ? ` / ${limit}pts` : 'pts';
+ headerParts.push(`${totalPts}${limitStr}`);
+ }
+
+ if (headerParts.length) {
+ const multiline = (options && options.multilineHeader !== undefined) ? options.multilineHeader : false;
+ const header = headerParts.join(multiline ? '\n' : ' | ');
+ out += useColor ? toAnsi(header, colors.header, true) + '\n\n' : header + '\n\n';
+ }
+
+ const rawUnits = Array.isArray(data.units) ? data.units : [];
+ const units = maybeCombineUnits(rawUnits, hideSubunits, combineIdenticalUnits);
+
+ const renderDiscordUnit = (unit, prefixText = '') => {
+ const hideSubunitsForThisUnit = hideSubunits || shouldHideSubunitsForUnit(unit, showMode);
+ const G = (unit.__groupCount !== undefined) ? unit.__groupCount : 1;
+ const M = (unit.__unitSize !== undefined) ? unit.__unitSize : getModelsCount(unit);
+ let qtyDisplay = '';
+ if (G > 1) {
+ qtyDisplay = M > 1 ? `${G}x${M} ` : `${G}x `;
+ } else {
+ qtyDisplay = M > 1 ? `${M} ` : '';
+ }
+
+ const categorySuffix = '';
+
+ const itemsString = getInlineItemsString(unit, useAbbreviations, wargearAbbrMap, summary, skippableWargearMap, showMandatoryWargear, hideSubunitsForThisUnit, showMode, hideBrackets);
+
+ const abbreviateUnitNames = !!(options && options.abbreviateUnitNames);
+ const finalUnitName = (useAbbreviations && abbreviateUnitNames) ? (findAbbreviationForItem(unit.name, wargearAbbrMap, summary) || makeAbbrevForName(unit.name)) : unit.name;
+
+ const unitNameText = useColor ? toAnsi(finalUnitName, colors.unit, true) : finalUnitName;
+ const unitText = `${prefixText}${qtyDisplay}${unitNameText}${categorySuffix}`;
+ const itemsText = (useColor && itemsString) ? toAnsi(itemsString, colors.wargear, false) : itemsString;
+ const pointsRaw = hideBrackets ? `${unit.points}` : `[${unit.points}]`;
+ const pointsText = useColor ? toAnsi(pointsRaw, colors.points, true) : pointsRaw;
+
+ let line = `${UNIT_BULLET}${unitText}${itemsText}`;
+ if (!hidePoints) {
+ line += ` ${pointsText}`;
+ }
+ out += `${line}\n`;
+
+ if (!hideSubunitsForThisUnit && Array.isArray(unit.subunits)) {
+ unit.subunits.forEach(sub => {
+ const subQty = parseInt((sub.quantity || '1').toString().replace('x', ''), 10) || 1;
+ const subQtyDisplay = subQty > 1 ? `${subQty} ` : '';
+ const finalSubName = (useAbbreviations && abbreviateUnitNames) ? (findAbbreviationForItem(sub.name, wargearAbbrMap, summary) || makeAbbrevForName(sub.name)) : sub.name;
+ const subRaw = `${subQtyDisplay}${finalSubName}`;
+ const subName = useColor ? toAnsi(subRaw, colors.subunit, false) : subRaw;
+
+ const filteredItems = (sub.wargear || []).filter(wg => {
+ if (showMode === 'show-all') return true;
+ if (showMode === 'hide-all') return false;
+ return !wg.skippable;
+ });
+
+ if (filteredItems.length === 0) {
+ out += `${SUB_BULLET}${subName}\n`;
+ return;
+ }
+
+ // Format subunit wargear
+ const subItemsArr = filteredItems.map(wg => {
+ const wgQty = parseInt(wg.quantity || 1, 10);
+ const qtyStr = wgQty > 1 ? `${wgQty}x ` : '';
+ let abbr = null;
+ if (useAbbreviations) {
+ abbr = findAbbreviationForItem(wg.name, wargearAbbrMap, summary);
+ if (!abbr) abbr = makeAbbrevForName(wg.name);
+ }
+ return `${qtyStr}${abbr || wg.name}`;
+ });
+ const subItems = hideBrackets ? ` ${subItemsArr.join(', ')}` : ` (${subItemsArr.join(', ')})`;
+ const subItemsText = (useColor && subItems) ? toAnsi(subItems, colors.wargear, false) : subItems;
+ out += `${SUB_BULLET}${subName}${subItemsText}\n`;
+ });
+ }
+ };
+
+ let attachedIndex = 0;
+ units.forEach(unit => {
+ if (unit.isAttached) {
+ attachedIndex++;
+ unit.attachedParts.forEach(part => {
+ const tag = getRoleTag(part, attachedIndex, hideBrackets);
+ const wTag = getWarlordTag(part, hideBrackets);
+ const tagText = useColor ? toAnsi(tag, colors.attached, true) : tag;
+ const wTagText = useColor && wTag ? toAnsi(wTag, colors.attached, true) : wTag;
+ const parts = [tagText, wTagText].filter(Boolean);
+ const prefixText = parts.length ? `${parts.join('')} ` : '';
+ renderDiscordUnit(part, prefixText);
+ });
+ } else {
+ const wTag = getWarlordTag(unit, hideBrackets);
+ const wTagText = useColor && wTag ? toAnsi(wTag, colors.attached, true) : wTag;
+ const prefixText = wTag ? `${wTagText} ` : '';
+ renderDiscordUnit(unit, prefixText);
+ }
+ });
+
+ if (!plain) out += '```';
+ return out;
+}
+
+export function resolveFactionColors(data, skippableWargearMap) {
+ const factionMap = buildFactionColorMap(skippableWargearMap || {});
+ const summary = data.metadata || {};
+ const rawFaction = summary.faction || null;
+ const factionKey = getCanonicalFactionName(rawFaction);
+ if (!factionKey) return null;
+ const normalizeKeyLookup = (s) => {
+ if (!s) return null;
+ try { return s.toString().normalize('NFD').replace(/\p{M}/gu, '').replace(/[\u2018\u2019\u201B\u2032]/g, "'").replace(/[^\w\s'\-]/g, '').toLowerCase().trim(); } catch (e) { return s.toString().toLowerCase(); }
+ };
+ const nfk = normalizeKeyLookup(factionKey);
+ const fm = factionMap[factionKey] || factionMap[factionKey.toString().toLowerCase()] || (nfk && factionMap[nfk]);
+ return fm || null;
+}
\ No newline at end of file
diff --git a/sites/scouting/src/vendor/40k-compactor/modules/utils.js b/sites/scouting/src/vendor/40k-compactor/modules/utils.js
new file mode 100644
index 0000000..3f9610a
--- /dev/null
+++ b/sites/scouting/src/vendor/40k-compactor/modules/utils.js
@@ -0,0 +1,524 @@
+// Normalize a wargear name for comparison/grouping purposes. Treats hyphens the same
+// as spaces so inconsistent source formatting (e.g. "Close Combat Weapon" vs
+// "Close-Combat Weapon") is recognized as the same item.
+export function normalizeWargearName(name) {
+ if (!name) return '';
+ let normalized = name.toString().replace(/[\u2018\u2019\u201B\u2032]/g, "'");
+ try {
+ normalized = normalized.normalize('NFD').replace(/\p{M}/gu, '');
+ } catch (e) {}
+ return normalized
+ .replace(/-/g, ' ')
+ .replace(/\s+/g, ' ')
+ .trim()
+ .toLowerCase();
+}
+
+// Sort wargear/special item arrays in-place: descending numeric quantity, then by name (A-Z)
+export function sortItemsByQuantityThenName(items) {
+ if (!Array.isArray(items)) return items;
+ items.sort((a, b) => {
+ const aq = parseInt(String((a && a.quantity) || '1x').replace(/x/i, ''), 10) || 1;
+ const bq = parseInt(String((b && b.quantity) || '1x').replace(/x/i, ''), 10) || 1;
+ // descending quantity
+ if (aq !== bq) return bq - aq;
+ const an = (a && a.name) ? a.name.toString().toLowerCase() : '';
+ const bn = (b && b.name) ? b.name.toString().toLowerCase() : '';
+ if (an < bn) return -1;
+ if (an > bn) return 1;
+ return 0;
+ });
+ return items;
+}
+
+export function getCanonicalFactionName(faction) {
+ if (!faction) return faction;
+
+ // Combined "Parent - Subfaction" strings (e.g. "Space Marines - Dark Angels")
+ // should resolve off the subfaction segment, since that's the more specific
+ // identity for coloring/skippable-wargear lookups.
+ const combinedMatch = faction.toString().match(/^(.+?)\s+-\s+(.+)$/);
+ if (combinedMatch) {
+ return getCanonicalFactionName(combinedMatch[2].trim());
+ }
+
+ // Normalize curly apostrophes to straight ones
+ let normalized = faction.toString()
+ .replace(/[\u2018\u2019\u201B\u2032]/g, "'");
+
+ // Normalize text (remove accents/diacritics)
+ try {
+ normalized = normalized.normalize('NFD').replace(/\p{M}/gu, '');
+ } catch (e) {
+ // Fallback
+ }
+
+ normalized = normalized.toLowerCase().trim();
+
+ const mapping = {
+ // T'au Empire
+ "empire t'au": "T'au Empire",
+ "imperio t'au": "T'au Empire",
+ "t'au-imperium": "T'au Empire",
+ "tau-imperium": "T'au Empire",
+ "tau imperium": "T'au Empire",
+ "impero t'au": "T'au Empire",
+ "sternenreich der t'au": "T'au Empire",
+ "sternenreich der tau": "T'au Empire",
+ "t'au empire": "T'au Empire",
+ "tau empire": "T'au Empire",
+ "imperio tau": "T'au Empire",
+ "impero tau": "T'au Empire",
+
+ // Chaos Daemons
+ "demons du chaos": "Chaos Daemons",
+ "demonios del caos": "Chaos Daemons",
+ "chaosdaemonen": "Chaos Daemons",
+ "chaos-daemonen": "Chaos Daemons",
+ "chaosdämonen": "Chaos Daemons",
+ "chaos-dämonen": "Chaos Daemons",
+ "demoni del caos": "Chaos Daemons",
+ "chaos daemons": "Chaos Daemons",
+
+ // Genestealer Cults
+ "cultes genestealers": "Genestealer Cults",
+ "culte genestealers": "Genestealer Cults",
+ "cultos genestealer": "Genestealer Cults",
+ "culto genestealer": "Genestealer Cults",
+ "symbiontenkulte": "Genestealer Cults",
+ "symbiontenkult": "Genestealer Cults",
+ "culti di genestealer": "Genestealer Cults",
+ "culto dei genestealer": "Genestealer Cults",
+ "culti dei genestealer": "Genestealer Cults",
+ "genestealer cults": "Genestealer Cults",
+
+ // Grey Knights
+ "chevaliers gris": "Grey Knights",
+ "caballeros grises": "Grey Knights",
+ "graue ritter": "Grey Knights",
+ "cavalieri grigi": "Grey Knights",
+ "grey knights": "Grey Knights",
+
+ // Imperial Knights
+ "chevaliers imperiaux": "Imperial Knights",
+ "caballeros imperiales": "Imperial Knights",
+ "imperiale ritter": "Imperial Knights",
+ "cavalieri imperiali": "Imperial Knights",
+ "imperial knights": "Imperial Knights",
+
+ // Leagues of Votann
+ "ligues de votann": "Leagues of Votann",
+ "ligas de votann": "Leagues of Votann",
+ "ligen von votann": "Leagues of Votann",
+ "leghe di votann": "Leagues of Votann",
+ "leagues of votann": "Leagues of Votann",
+
+ // Necrons
+ "necrons": "Necrons",
+ "necrones": "Necrons",
+ "necroni": "Necrons",
+ "necron": "Necrons",
+
+ // Salamanders
+ "salamandres": "Salamanders",
+ "salamandras": "Salamanders",
+ "salamandre": "Salamanders",
+ "salamanders": "Salamanders",
+
+ // Tyranids
+ "tyranides": "Tyranids",
+ "tiranidos": "Tyranids",
+ "tyraniden": "Tyranids",
+ "tiranidi": "Tyranids",
+ "tyranids": "Tyranids",
+
+ // Agents of the Imperium
+ "agents de l'imperium": "Agents of the Imperium",
+ "agentes del imperio": "Agents of the Imperium",
+ "agenten des imperiums": "Agents of the Imperium",
+ "agenti dell'imperium": "Agents of the Imperium",
+ "agents of the imperium": "Agents of the Imperium",
+ "agents imperiaux": "Agents of the Imperium",
+ "agentes imperiales": "Agents of the Imperium",
+ "imperiale agenten": "Agents of the Imperium",
+ "agenti imperiali": "Agents of the Imperium",
+ "imperial agents": "Agents of the Imperium",
+
+ // Space Marines
+ "marines espaciales": "Space Marines",
+ "marines spaziali": "Space Marines",
+ "space marines": "Space Marines",
+ "weltraummarines": "Space Marines",
+
+ // World Eaters
+ "devoradores de mundos": "World Eaters",
+ "divoratori di mondi": "World Eaters",
+ "mangeurs de mondes": "World Eaters",
+ "weltenfresser": "World Eaters",
+ "world eaters": "World Eaters",
+
+ // Death Guard
+ "guardia de la muerte": "Death Guard",
+ "guardia della morte": "Death Guard",
+ "garde de la mort": "Death Guard",
+ "todesgarde": "Death Guard",
+ "death guard": "Death Guard",
+
+ // Thousand Sons
+ "mil hijos": "Thousand Sons",
+ "mille figli": "Thousand Sons",
+ "mille fils": "Thousand Sons",
+ "tausend sohne": "Thousand Sons",
+ "thousand sons": "Thousand Sons",
+
+ // Chaos Space Marines
+ "marines espaciales del caos": "Chaos Space Marines",
+ "space marines del caos": "Chaos Space Marines",
+ "space marines du chaos": "Chaos Space Marines",
+ "chaos space marines": "Chaos Space Marines",
+
+ // Chaos Knights
+ "caballeros del caos": "Chaos Knights",
+ "cavalieri del caos": "Chaos Knights",
+ "chevaliers du chaos": "Chaos Knights",
+ "chaosritter": "Chaos Knights",
+ "chaos knights": "Chaos Knights",
+
+ // Dark Angels
+ "angeles oscuros": "Dark Angels",
+ "angeli oscuri": "Dark Angels",
+ "anges sombres": "Dark Angels",
+ "dunkle engel": "Dark Angels",
+ "dark angels": "Dark Angels",
+
+ // Blood Angels
+ "angeles sangrientos": "Blood Angels",
+ "angeli sanguinari": "Blood Angels",
+ "anges sanguins": "Blood Angels",
+ "blutengel": "Blood Angels",
+ "blood angels": "Blood Angels",
+
+ // Black Templars
+ "templarios negros": "Black Templars",
+ "templari neri": "Black Templars",
+ "templiers noirs": "Black Templars",
+ "schwarze templer": "Black Templars",
+ "black templars": "Black Templars",
+
+ // Space Wolves
+ "lobos espaciales": "Space Wolves",
+ "lupi spaziali": "Space Wolves",
+ "loups spatiaux": "Space Wolves",
+ "weltraumwolfe": "Space Wolves",
+ "space wolves": "Space Wolves",
+
+ // Adepta Sororitas
+ "sisters of battle": "Adepta Sororitas",
+ "soeurs de bataille": "Adepta Sororitas",
+ "hermanas de batalla": "Adepta Sororitas",
+ "schwestern des kampfes": "Adepta Sororitas",
+ "sororitas": "Adepta Sororitas",
+ "sorelle della battaglia": "Adepta Sororitas",
+ "adepta sororitas": "Adepta Sororitas",
+
+ // Astra Militarum
+ "imperial guard": "Astra Militarum",
+ "garde imperiale": "Astra Militarum",
+ "guardia imperial": "Astra Militarum",
+ "imperiale armee": "Astra Militarum",
+ "imperiale garde": "Astra Militarum",
+ "guardia imperiale": "Astra Militarum",
+ "astra militarum": "Astra Militarum",
+
+ // Deathwatch
+ "todeswache": "Deathwatch",
+ "guet de la mort": "Deathwatch",
+ "guardianes de la muerte": "Deathwatch",
+ "veglia della morte": "Deathwatch",
+ "deathwatch": "Deathwatch",
+
+ // Drukhari
+ "dark eldar": "Drukhari",
+ "eldars noirs": "Drukhari",
+ "eldar noirs": "Drukhari",
+ "eldars oscuros": "Drukhari",
+ "eldar oscuros": "Drukhari",
+ "dunkle eldar": "Drukhari",
+ "eldar oscuri": "Drukhari",
+ "drukhari": "Drukhari",
+
+ // Emperor's Children
+ "enfants de l'empereur": "Emperor's Children",
+ "hijos del emperador": "Emperor's Children",
+ "kinder des imperators": "Emperor's Children",
+ "figli dell'imperatore": "Emperor's Children",
+ "emperor's children": "Emperor's Children",
+
+ // Imperial Fists
+ "poings imperiaux": "Imperial Fists",
+ "punos imperiales": "Imperial Fists",
+ "imperiale fauste": "Imperial Fists",
+ "magli imperiali": "Imperial Fists",
+ "pugni imperiali": "Imperial Fists",
+ "imperial fists": "Imperial Fists",
+
+ // Iron Hands
+ "mains de fer": "Iron Hands",
+ "manos de hierro": "Iron Hands",
+ "eiserne hande": "Iron Hands",
+ "mani di ferro": "Iron Hands",
+ "iron hands": "Iron Hands",
+
+ // Orks
+ "orcs": "Orks",
+ "orkos": "Orks",
+ "orki": "Orks",
+ "orks": "Orks",
+
+ // Raven Guard
+ "garde du corbeau": "Raven Guard",
+ "guardia del cuervo": "Raven Guard",
+ "rabengarde": "Raven Guard",
+ "guardia del corvo": "Raven Guard",
+ "raven guard": "Raven Guard",
+
+ // White Scars
+ "cicatrices blanches": "White Scars",
+ "cicatrices blancas": "White Scars",
+ "weisse narben": "White Scars",
+ "cicatrici bianche": "White Scars",
+ "white scars": "White Scars"
+ };
+
+ if (mapping[normalized]) {
+ return mapping[normalized];
+ }
+
+ return faction;
+}
+
+export function isWargearSkippable(skippableWargearMap, faction, unitName, wargearName) {
+ if (!skippableWargearMap || !faction || !unitName || !wargearName) return false;
+
+ const normalizeKey = (s) => {
+ if (!s) return '';
+ try {
+ return s.toString().normalize('NFD')
+ .replace(/\p{M}/gu, '')
+ .replace(/[\u2018\u2019\u201B\u2032]/g, "'")
+ .replace(/[^\w\s'\-]/g, '')
+ .toLowerCase().trim();
+ } catch (e) {
+ return s.toString().toLowerCase().trim();
+ }
+ };
+
+ const unitKey = normalizeKey(unitName);
+ const unitAlt = unitKey.endsWith('s') ? unitKey.slice(0, -1) : unitKey + 's';
+ const wargearKey = normalizeWargearName(wargearName);
+
+ // A combined "Parent - Subfaction" faction (e.g. "Space Marines - Dark Angels")
+ // resolves to the subfaction for coloring, but skippable-wargear rules are often
+ // only defined once at the parent level. Try the subfaction first so any
+ // chapter-specific overrides win, then fall back to the parent when the
+ // subfaction's data has no entry at all for this unit.
+ const rawFaction = faction.toString();
+ const combinedMatch = rawFaction.match(/^(.+?)\s+-\s+(.+)$/);
+ const candidateFactions = combinedMatch ? [combinedMatch[2].trim(), combinedMatch[1].trim()] : [rawFaction];
+
+ for (const candidateFaction of candidateFactions) {
+ const canonicalFaction = getCanonicalFactionName(candidateFaction);
+ const factionKey = normalizeKey(canonicalFaction);
+
+ // Find faction entry
+ let factionData;
+ for (const [k, v] of Object.entries(skippableWargearMap)) {
+ if (normalizeKey(k) === factionKey) {
+ factionData = v;
+ break;
+ }
+ }
+ if (!factionData) continue;
+
+ // Find unit entry
+ let unitData;
+ const tryUnitKeys = [unitName, unitKey, unitAlt];
+ for (const uk of tryUnitKeys) {
+ if (Object.prototype.hasOwnProperty.call(factionData, uk)) {
+ unitData = factionData[uk];
+ break;
+ }
+ }
+ if (unitData === undefined) {
+ for (const [k, v] of Object.entries(factionData)) {
+ if (normalizeKey(k) === unitKey || normalizeKey(k) === unitAlt) {
+ unitData = v;
+ break;
+ }
+ }
+ }
+ if (unitData === undefined) continue;
+
+ if (unitData === true) return true;
+ if (Array.isArray(unitData)) {
+ return unitData.map(s => normalizeWargearName(s)).includes(wargearKey);
+ }
+ return false;
+ }
+
+ return false;
+}
+
+export function shouldHideSubunitsForUnit(unit, showMode) {
+ if (!unit || !Array.isArray(unit.subunits) || unit.subunits.length === 0) return false;
+ return unit.subunits.every(sub => {
+ const visibleWargear = (sub.wargear || []).filter(wg => {
+ if (showMode === 'show-all') return true;
+ if (showMode === 'hide-all') return false;
+ return !wg.skippable;
+ });
+ return visibleWargear.length === 0;
+ });
+}
+
+export function getModelsCount(unit) {
+ if (!unit) return 1;
+ if (Array.isArray(unit.subunits) && unit.subunits.length > 0) {
+ return unit.subunits.reduce((sum, sub) => sum + (parseInt(sub.quantity, 10) || 0), 0);
+ }
+ const q = parseInt((unit.quantity || '1').toString().replace('x', ''), 10);
+ return isNaN(q) ? 1 : q;
+}
+
+export function parseNewRecruitHeader(lines) {
+ const metadata = {
+ title: '',
+ armyName: '',
+ faction: '',
+ detachment: '',
+ detachments: [],
+ pointsTotal: 0,
+ totalPoints: 0,
+ pointsLimit: 0,
+ forceDispositions: [],
+ warlordName: '',
+ warlordId: '',
+ enhancements: []
+ };
+
+ let i = 0;
+ while (i < lines.length && !lines[i].trim()) {
+ i++;
+ }
+ if (i < lines.length && lines[i].trim().startsWith('+++')) {
+ i++; // skip opening +++
+ while (i < lines.length && !lines[i].trim().startsWith('+++')) {
+ const line = lines[i].trim();
+ if (line.startsWith('+') || line.startsWith('&')) {
+ const isAmp = line.startsWith('&');
+ const content = line.substring(1).trim();
+
+ if (isAmp) {
+ // Continuing enhancement or other field
+ const match = content.match(/^(.*?)\s*\(on\s+(Char\d+|Infa\d+|[A-Za-z]+\d+)?\s*:?\s*(.*)\)$/i);
+ if (match) {
+ metadata.enhancements.push({
+ name: match[1].trim(),
+ onId: match[2] ? match[2].trim() : '',
+ onName: match[3] ? match[3].trim() : ''
+ });
+ } else {
+ metadata.enhancements.push({
+ name: content,
+ onId: '',
+ onName: ''
+ });
+ }
+ i++;
+ continue;
+ }
+
+ const factionMatch = content.match(/^FACTION KEYWORD:\s*(.*)$/i);
+ if (factionMatch) {
+ let facVal = factionMatch[1].trim();
+ const hyphenIdx = facVal.indexOf('-');
+ if (hyphenIdx !== -1) {
+ facVal = facVal.substring(hyphenIdx + 1).trim();
+ }
+ metadata.faction = facVal;
+ i++;
+ continue;
+ }
+
+ const detachmentMatch = content.match(/^DETACHMENT:\s*(.*)$/i);
+ if (detachmentMatch) {
+ let detVal = detachmentMatch[1].trim();
+ detVal = detVal.replace(/\s*\(.*?\)/g, '').trim();
+ metadata.detachment = detVal;
+ metadata.detachments = detVal.split(',').map(d => d.trim()).filter(Boolean);
+ i++;
+ continue;
+ }
+
+ const forceDispositionMatch = content.match(/^FORCE DISPOSITION:\s*(.*)$/i);
+ if (forceDispositionMatch) {
+ const dispVal = forceDispositionMatch[1].trim();
+ metadata.forceDispositions = dispVal.split(',').map(d => d.trim()).filter(Boolean);
+ i++;
+ continue;
+ }
+
+ const pointsMatch = content.match(/^TOTAL ARMY POINTS:\s*(\d+)/i);
+ if (pointsMatch) {
+ const pts = parseInt(pointsMatch[1], 10) || 0;
+ metadata.pointsTotal = pts;
+ metadata.totalPoints = pts;
+ i++;
+ continue;
+ }
+
+ const warlordMatch = content.match(/^WARLORD:\s*(Char\d+|Infa\d+|[A-Za-z]+\d+)?\s*:?\s*(.*)$/i);
+ if (warlordMatch) {
+ if (warlordMatch[1]) {
+ metadata.warlordId = warlordMatch[1].trim();
+ }
+ metadata.warlordName = warlordMatch[2].trim();
+ i++;
+ continue;
+ }
+
+ const enhancementMatch = content.match(/^ENHANCEMENT:\s*(.*)$/i);
+ if (enhancementMatch) {
+ const enhContent = enhancementMatch[1].trim();
+ const match = enhContent.match(/^(.*?)\s*\(on\s+(Char\d+|Infa\d+|[A-Za-z]+\d+)?\s*:?\s*(.*)\)$/i);
+ if (match) {
+ metadata.enhancements.push({
+ name: match[1].trim(),
+ onId: match[2] ? match[2].trim() : '',
+ onName: match[3] ? match[3].trim() : ''
+ });
+ } else {
+ metadata.enhancements.push({
+ name: enhContent,
+ onId: '',
+ onName: ''
+ });
+ }
+ i++;
+ continue;
+ }
+
+ const secondaryMatch = content.match(/^SECONDARY:\s*(.*)$/i);
+ if (secondaryMatch) {
+ i++;
+ continue;
+ }
+ }
+ i++;
+ }
+ if (i < lines.length && lines[i].trim().startsWith('+++')) {
+ i++;
+ }
+ }
+ return { metadata, nextIndex: i };
+}
\ No newline at end of file
diff --git a/sites/scouting/src/vendor/40k-compactor/skippable_wargear.json b/sites/scouting/src/vendor/40k-compactor/skippable_wargear.json
new file mode 100644
index 0000000..06eaa5a
--- /dev/null
+++ b/sites/scouting/src/vendor/40k-compactor/skippable_wargear.json
@@ -0,0 +1,3137 @@
+{
+ "Adepta Sororitas": {
+ "Aestred Thurga and Agathae Dolan": true,
+ "Arco-Flagellants": true,
+ "Battle Sisters Squad": [
+ "Close Combat Weapon"
+ ],
+ "Canoness": [],
+ "Canoness with Jump Pack": [],
+ "Castigator": [
+ "Heavy Bolter",
+ "Armoured Tracks"
+ ],
+ "Celestian Sacresants": [],
+ "Daemonifuge": true,
+ "Dialogus": true,
+ "Dogmata": true,
+ "Dominion Squad": [
+ "Close Combat Weapon"
+ ],
+ "Exorcist": [
+ "Heavy Bolter",
+ "Armoured Tracks"
+ ],
+ "Hospitaller": true,
+ "Imagifier": true,
+ "Immolator": [
+ "Armoured Tracks"
+ ],
+ "Intranzia Fraye": [
+ "Heavy Bolter",
+ "Melta Missile Array",
+ "Ministorum Heavy Flamer",
+ "Mace of Saint Praxedes",
+ "Throne of Blame"
+ ],
+ "Junith Eruita": true,
+ "Ministorum Priest": [],
+ "Mortifiers": [],
+ "Morvenn Vahl": true,
+ "Palatine": [
+ "Palatine Blade"
+ ],
+ "Paragon Warsuits": [
+ "Bolt Pistol"
+ ],
+ "Penitent Engines": [
+ "Penitent Flamers"
+ ],
+ "Repentia Squad": true,
+ "Retributor Squad": [
+ "Close Combat Weapon"
+ ],
+ "Saint Celestine": true,
+ "Sanctifiers": [
+ "Ministorum Flamer",
+ "Burning Hands",
+ "Death Cult Blades",
+ "Salvationist Medikit"
+ ],
+ "Seraphim Squad": [
+ "Close Combat Weapon"
+ ],
+ "Sisters Novitiate Squad": [
+ "Autopistol"
+ ],
+ "Sororitas Rhino": [
+ "Storm Bolter",
+ "Armoured Tracks"
+ ],
+ "Triumph of Saint Katherine": true,
+ "Zephyrim Squad": [
+ "Power Weapon"
+ ]
+ },
+ "Adeptus Custodes": {
+ "Agamatus Custodians": [
+ "Interceptor Lance"
+ ],
+ "Aleya": true,
+ "Allarus Custodians": [
+ "Balistus Grenade Launcher"
+ ],
+ "Anathema Psykana Rhino": [
+ "Storm Bolter",
+ "Armoured Tracks"
+ ],
+ "Aquilon Custodians": [],
+ "Ares Gunship": [
+ "Arachnus Heavy Blaze Cannon",
+ "Arachnus Magna-blaze Cannon",
+ "Armoured Hull"
+ ],
+ "Blade Champion": true,
+ "Caladius Grav-tank": [
+ "Twin Lastrum Bolt Cannon",
+ "Armoured Hull"
+ ],
+ "Contemptor-Achillus Dreadnought": [
+ "Achillus Dreadspear"
+ ],
+ "Contemptor-galatus Dreadnought": [
+ "Galatus Warblade"
+ ],
+ "Contemptor-Galatus Dreadnought": true,
+ "Coronus Grav-carrier": [
+ "Twin Arachnus Blaze Cannon",
+ "Twin Lastrum Bolt Cannon",
+ "Armoured Hull"
+ ],
+ "Custodian Guard": [],
+ "Custodian Guard with Adrasite and Pyrithite Spears": [],
+ "Custodian Wardens": [],
+ "Knight-Centura": [],
+ "Orion Assault Dropship": [
+ "Arachnus Heavy Blaze Cannon",
+ "Spiculus Heavy Bolt Launcher",
+ "Twin Lastrum Bolt Cannon",
+ "Armoured Hull"
+ ],
+ "Pallas Grav-attack": [
+ "Twin Arachnus Blaze Cannon",
+ "Armoured Hull"
+ ],
+ "Prosecutors": true,
+ "Sagittarum Custodians": [
+ "Adrastus Bolt Caliver",
+ "Misericordia"
+ ],
+ "Shield-Captain": [],
+ "Shield-captain In Allarus Terminator Armour": [
+ "Balistus Grenade Launcher"
+ ],
+ "Shield-captain on Dawneagle Jetbike": [
+ "Interceptor Lance"
+ ],
+ "Telemon Heavy Dreadnought": [
+ "Spiculus Bolt Launcher",
+ "Armoured Feet"
+ ],
+ "Trajann Valoris": true,
+ "Valerian": true,
+ "Venatari Custodians": [
+ "Tarsis Buckler"
+ ],
+ "Venerable Contemptor Dreadnought": [
+ "Combi-Bolter",
+ "Contemptor Combat Weapon"
+ ],
+ "Venerable Land Raider": [
+ "Godhammer Lascannon",
+ "Twin Heavy Bolter",
+ "Armoured Tracks"
+ ],
+ "Vertus Praetors": [
+ "Interceptor Lance"
+ ],
+ "Vigilators": true,
+ "Witchseekers": [
+ "Witchseeker Flamer",
+ "Close Combat Weapon"
+ ]
+ },
+ "Adeptus Mechanicus": {
+ "Archaeopter Fusilave": [
+ "Cognis Heavy Stubber Array",
+ "Armoured Hull"
+ ],
+ "Archaeopter Stratoraptor": [
+ "Cognis Heavy Stubber",
+ "Heavy phosphor blaster",
+ "Twin Cognis Lascannon",
+ "Armoured Hull"
+ ],
+ "Archaeopter Transvector": [
+ "Cognis Heavy Stubber Array",
+ "Armoured Hull"
+ ],
+ "Belisarius Cawl": true,
+ "Corpuscarii Electro-priests": true,
+ "Cybernetica Datasmith": true,
+ "Fulgurite Electro-priests": true,
+ "Hastarii Exterminators": [
+ "Hastarii Arc Blaster",
+ "Eradication Caster",
+ "Close-combat Weapon",
+ "Power Weapon"
+ ],
+ "Hastarii Fusiliers": [
+ "Neutron Fusil",
+ "Hastarii Phosphor Blaster",
+ "Close-combat Weapon",
+ "Power Weapon"
+ ],
+ "Ironstrider Ballistarii": [
+ "Ironstrider Feet"
+ ],
+ "Kastelan Robots": [],
+ "Kataphron Breachers": [],
+ "Kataphron Destroyers": [
+ "Close Combat Weapon"
+ ],
+ "Onager Dunecrawler": [
+ "Dunecrawler Legs"
+ ],
+ "Pteraxii Skystalkers": true,
+ "Pteraxii Sterylizors": true,
+ "Serberys Raiders": [
+ "Mechanicus Pistol",
+ "Galvanic Carbine",
+ "Cavalry Sabre and Clawed Limbs"
+ ],
+ "Serberys Sulphurhounds": [
+ "Mechanicus Pistol",
+ "Sulphur Breath",
+ "Cavalry Arc Maul",
+ "Clawed Limbs"
+ ],
+ "Servitor Battleclade": [
+ "Heavy Arc Rifle",
+ "Heavy Bolter",
+ "Mechanicus Pistol",
+ "Dataspikes",
+ "Servo-claw"
+ ],
+ "Sicarian Ruststalkers": [],
+ "Skitarii Marshal": true,
+ "Skitarii Rangers": [
+ "Close Combat Weapon"
+ ],
+ "Skitarii Vanguard": [
+ "Close Combat Weapon"
+ ],
+ "Skorpius Disintegrator": [
+ "Cognis Heavy Stubber",
+ "Disruptor Missile Launcher",
+ "Armoured Hull"
+ ],
+ "Skorpius Dunerider": true,
+ "Sydonian Dragoons with Radium Jezzails": true,
+ "sydonian Dragoons with Taser Lances": true,
+ "Sydonian Skatros": [
+ "Mechanicus Pistol",
+ "Sydonian Feet"
+ ],
+ "Tech-Priest Dominus": [
+ "Omnissian Axe"
+ ],
+ "Tech-Priest Enginseer": true,
+ "Tech-Priest Manipulus": [
+ "Omnissian Staff"
+ ],
+ "Technoarcheologist": true,
+ "Thulia Ghuld": true
+ },
+ "Adeptus Titanicus": {
+ "Reaver Titan": [
+ "Reaver apocalypse launcher",
+ "reaver feet"
+ ],
+ "Warbringer Nemesis Titan": [
+ "Anvillus Defence Battery",
+ "Ardex-defensor Mauler",
+ "Nemesis Feet"
+ ],
+ "Warhound Titan": [
+ "Warhound Feet"
+ ],
+ "Warlord Titan": [
+ "Ardex-defensor Mauler",
+ "Ardex-defensor Lascannon",
+ "Warlord Feet"
+ ]
+ },
+ "Aeldari": {
+ "Asurmen": true,
+ "Autarch": [],
+ "Avatar of Khaine": true,
+ "Baharroth": true,
+ "Corsair Voidreavers": [
+ "Close Combat Weapon"
+ ],
+ "Corsair Voidscarred": [
+ "Close Combat Weapon",
+ "Executioner",
+ "Paired Hekatarii Blades",
+ "Witch Staff",
+ "Channeller Stones"
+ ],
+ "Crimson Hunter": [
+ "Pulse laser",
+ "Wraithbone Hull"
+ ],
+ "D-Cannon Platform": true,
+ "Dark Reapers": [
+ "Close Combat Weapon"
+ ],
+ "Death Jester": true,
+ "Dire Avengers": [
+ "Close Combat Weapon"
+ ],
+ "Eldrad Ulthran": true,
+ "Falcon": [
+ "Pulse laser",
+ "Wraithbone Hull"
+ ],
+ "Farseer": [
+ "Eldritch Storm",
+ "Shuriken Pistol"
+ ],
+ "Farseer Skyrunner": [
+ "Eldritch Storm",
+ "Shuriken Pistol",
+ "Twin Shuriken Catapult"
+ ],
+ "Fire Dragons": [
+ "Close Combat Weapon"
+ ],
+ "Fire Prism": [
+ "Prism Cannon",
+ "Wraithbone Hull"
+ ],
+ "Fuegan": true,
+ "Guardian Defenders": [
+ "Shuriken Catapult",
+ "Close Combat Weapon"
+ ],
+ "Hemlock Wraithfighter": true,
+ "Jain Zar": true,
+ "Kharseth": [
+ "Dread of the Deep Void",
+ "Waystave"
+ ],
+ "Lhykhis": true,
+ "Maugan Ra": true,
+ "Night Spinner": [
+ "Doomweaver",
+ "Wraithbone Hull"
+ ],
+ "Phantom Titan": [
+ "Voidstorm Missile Launcher",
+ "Phantom Feet"
+ ],
+ "Prince Yriel": [
+ "Eye of Wrath",
+ "Shuriken Pistol",
+ "Spear of Twilight"
+ ],
+ "Rangers": [
+ "Long Rifle",
+ "Shuriken Pistol",
+ "Close Combat Weapon"
+ ],
+ "Revenant Titan": [
+ "Cloudburst Missile Launcher",
+ "Revenant Feet"
+ ],
+ "Shadow Weaver Platform": true,
+ "Shadowseer": [
+ "Miststave",
+ "Flip Belt"
+ ],
+ "Shining Spears": [],
+ "Shroud Runners": true,
+ "Skyweavers": [
+ "Close Combat Weapon"
+ ],
+ "Solitaire": true,
+ "Spiritseer": true,
+ "Starfangs": [
+ "Disintegrator Cannon",
+ "Starfang Grenade Launcher",
+ "Wraithbone Hull"
+ ],
+ "Starweaver": true,
+ "Storm Guardians": [
+ "Serpent Shield"
+ ],
+ "Striking Scorpions": [],
+ "Swooping Hawks": [
+ "Close Combat Weapon"
+ ],
+ "The Visarch": true,
+ "The Yncarne": true,
+ "Troupe": [
+ "Flip Belt"
+ ],
+ "Troupe Master": [
+ "Flip Belt"
+ ],
+ "Vibro Cannon Platform": true,
+ "Voidweaver": [
+ "Shuriken Cannon",
+ "Close Combat Weapon"
+ ],
+ "Vypers": [
+ "Wraithbone Hull"
+ ],
+ "War Walkers": [
+ "War Walker Feet"
+ ],
+ "Warlock": [
+ "Destructor",
+ "Shuriken Pistol"
+ ],
+ "Warlock Conclave": [
+ "Destructor",
+ "Shuriken Pistol"
+ ],
+ "Warlock Skyrunners": [
+ "Destructor",
+ "Shuriken Pistol",
+ "Twin Shuriken Catapult"
+ ],
+ "Warp Spiders": [
+ "Close Combat Weapon"
+ ],
+ "Wave Serpent": [
+ "Wraithbone Hull"
+ ],
+ "Windriders": [
+ "Close Combat Weapon"
+ ],
+ "Wraithguard": [
+ "Close Combat Weapon"
+ ],
+ "Wraithknight": [
+ "Titanic Feet"
+ ],
+ "Wraithknight with Ghostglaive": [
+ "Titanic Ghostglaive"
+ ],
+ "Wraithlord": [
+ "Wraithbone Fists"
+ ],
+ "Ynnari Archon": [
+ "Huskblade",
+ "Shadow Field"
+ ],
+ "Ynnari Incubi": [
+ "Demiklaives"
+ ],
+ "Ynnari Raider": [
+ "Bladevanes"
+ ],
+ "Ynnari Reavers": [
+ "Splinter Pistol",
+ "Bladevanes"
+ ],
+ "Ynnari Succubus": [
+ "Succubus Weapons"
+ ],
+ "Ynnari Venom": [
+ "Bladevanes"
+ ],
+ "Ynnari Wyches": [
+ "Hekatarii Blade"
+ ],
+ "Yvraine": true
+ },
+ "Agents of the Imperium": {
+ "Aquila Kill Team": [
+ "Bolt Pistol",
+ "Plasma Pistol",
+ "Special-issue Bolt Pistol",
+ "Close Combat Weapon",
+ "Xenophase Blade"
+ ],
+ "Callidus Assassin": true,
+ "Corvus Blackstar": [
+ "Armoured Hull"
+ ],
+ "Culexus Assassin": true,
+ "Deathwatch Kill Team": [],
+ "Eversor Assassin": true,
+ "Exaction Squad": [
+ "Arbites Shotpistol",
+ "Close Combat Weapon",
+ "Mechanical Bite"
+ ],
+ "Grey Knights Terminator Squad": [
+ "Nemesis Force Weapon"
+ ],
+ "Imperial Navy Breachers": [
+ "Close Combat Weapon",
+ "Endurant Shield",
+ "Navis Heavy Shotgun"
+ ],
+ "Imperial Rhino": [
+ "Storm Bolter",
+ "Armoured Tracks"
+ ],
+ "Inquisitor Coteaz": true,
+ "Inquisitor Draxus": true,
+ "Inquisitor Greyfax": true,
+ "Inquisitor Kroyle": [
+ "Jindarii Tox-cycler",
+ "Stubcarbine",
+ "Butcher Blade",
+ "Garralisk's Claws and Teeth"
+ ],
+ "Inquisitorial Agents": [
+ "Agent Firearm",
+ "Agent Melee Weapon"
+ ],
+ "Inquisitorial Chimera": [
+ "Armoured Tracks",
+ "Lasgun Array"
+ ],
+ "Ministorum Priest": [],
+ "Navigator": true,
+ "Rogue Trader Entourage": true,
+ "Sanctifiers": [
+ "Ministorum Flamer",
+ "Burning Hands",
+ "Death Cult Blades",
+ "Salvationist Medikit"
+ ],
+ "Sisters of Battle Immolator": [
+ "Armoured Tracks"
+ ],
+ "Sisters of Battle Squad": [
+ "Close Combat Weapon",
+ "Simulacrum Imperials"
+ ],
+ "Subductor Squad": [
+ "Arbites Shotpistol",
+ "Shock maul",
+ "Mechanical Bite"
+ ],
+ "Vigilant Squad": [
+ "Arbites Shotpistol",
+ "Close Combat Weapon",
+ "Mechanical Bite"
+ ],
+ "Vindicare Assassin": true,
+ "Voidsmen-at-Arms": true,
+ "Watch Captain Artemis": true,
+ "Watch Master": true
+ },
+ "Astra Militarum": {
+ "Aegis Defence Line": [],
+ "Armoured Sentinels": [
+ "Close Combat Weapon"
+ ],
+ "Artillery Team": [
+ "Lasgun",
+ "Crew Close Combat Weapons"
+ ],
+ "Attilan Rough Riders": [
+ "Steed's hooves",
+ "Lasgun",
+ "Laspistol"
+ ],
+ "Avenger Strike Fighter": [
+ "Avenger Bolt Cannon",
+ "Heavy Stubber",
+ "Lascannon",
+ "Armoured Hull"
+ ],
+ "Baneblade": [
+ "Baneblade Cannon",
+ "Coaxial Autocannon",
+ "Demolisher Cannon",
+ "Armoured Tracks",
+ "Heavy Stubber"
+ ],
+ "Banehammer": [
+ "Tremor Cannon",
+ "Armoured Tracks"
+ ],
+ "Banesword": [
+ "Quake Cannon",
+ "Armoured Tracks"
+ ],
+ "Basilisk": [
+ "Earthshaker Cannon",
+ "Armoured Tracks"
+ ],
+ "Bullgryn Squad": [
+ "Close Combat Weapon"
+ ],
+ "Cadian Command Squad": [
+ "Medi-pack",
+ "Master Vox"
+ ],
+ "Cadian Heavy Weapons Squad": [
+ "Weapons Team Close Combat Weapons",
+ "Laspistol"
+ ],
+ "Cadian Recon Squad": [
+ "Close Combat Weapon"
+ ],
+ "Catachan Command Squad": [
+ "Close Combat Weapon"
+ ],
+ "Catachan Heavy Weapons Squad": [
+ "Weapons Team Close Combat Weapons",
+ "Lasgun"
+ ],
+ "Catachan Jungle Fighters": [
+ "Laspistol",
+ "Close Combat Weapon"
+ ],
+ "Centaur RSV": [
+ "Pintle-mounted Heavy Stubber",
+ "Armoured Hull"
+ ],
+ "Chimera": [
+ "Armoured Tracks",
+ "Lasgun Array"
+ ],
+ "Commissar Graves": [
+ "Chiron Gatling Cannon",
+ "Prefectus Heavy Stubber",
+ "Armoured Hull",
+ "Enforcer Crew",
+ "Power Sword and Manus Mortis",
+ "Aquiline Prow"
+ ],
+ "Commissar Graves on Foot": [
+ "Bolt Pistol",
+ "Power Sword and Manus Mortis"
+ ],
+ "Commissar Yarrick": [
+ "Bale Eye",
+ "Laspistol",
+ "Storm Bolter",
+ "Power Klaw",
+ "Power Sword"
+ ],
+ "Cyclops Demolition Vehicle": [],
+ "Death Korps of Krieg": [
+ "Laspistol",
+ "Chainsword",
+ "Lasgun",
+ "Close Combat Weapon"
+ ],
+ "Death Riders": true,
+ "Deathstrike": [
+ "Deathstrike Missile",
+ "Armoured Tracks"
+ ],
+ "Doomhammer": [
+ "Magma Cannon",
+ "Armoured Tracks"
+ ],
+ "Field Ordnance Battery": [
+ "Battery Close Combat Weapons",
+ "Lasgun",
+ "Laspistol"
+ ],
+ "Gaunt's Ghosts": true,
+ "Hellhammer": [
+ "Coaxial Autocannon",
+ "Demolisher Cannon",
+ "Hellhammer Cannon",
+ "Armoured Tracks",
+ "Heavy Stubber"
+ ],
+ "Hellhound": [
+ "Armoured Tracks"
+ ],
+ "Hippogriff AFV": [
+ "Armoured Hull"
+ ],
+ "Hydra": [
+ "Hydra Autocannon",
+ "Armoured Tracks"
+ ],
+ "Kasrkin": [
+ "Close Combat Weapon"
+ ],
+ "Krieg Command Squad": [
+ "Servo-Scribes",
+ "Master Vox",
+ "Regimental Standard",
+ "Lasgun",
+ "Close Combat Weapon"
+ ],
+ "Krieg Heavy Weapons Squad": [
+ "Laspistol",
+ "Close Combat Weapon"
+ ],
+ "Leman Russ Battle Tank": [
+ "Leman Russ Battle Cannon",
+ "Armoured Tracks"
+ ],
+ "Leman Russ Commander": [
+ "Armoured Tracks"
+ ],
+ "Leman Russ Demolisher": [
+ "Demolisher Battle Cannon",
+ "Armoured Tracks"
+ ],
+ "Leman Russ Eradicator": [
+ "Eradicator Nova Cannon",
+ "Armoured Tracks"
+ ],
+ "Leman Russ Executioner": [
+ "Executioner Plasma Cannon",
+ "Armoured Tracks"
+ ],
+ "Leman Russ Exterminator": [
+ "Exterminator Autocannon",
+ "Armoured Tracks"
+ ],
+ "Leman Russ Punisher": [
+ "Punisher Gatling Cannon",
+ "Armoured Tracks"
+ ],
+ "Leman Russ Vanquisher": [
+ "Vanquisher Battle Cannon",
+ "Armoured Tracks"
+ ],
+ "Lord Marshal Dreir": true,
+ "Lord Solar Leontus": true,
+ "Manticore": [
+ "Storm Eagle Rockets",
+ "Armoured Tracks"
+ ],
+ "Militarum Tempestus Command squad": [
+ "Hot-Shot Lasgun",
+ "Tempestus Dagger"
+ ],
+ "Militarum Tempestus Command Squad": [
+ "Close Combat Weapon"
+ ],
+ "Ministorum Priest": [],
+ "Nork Deddog": true,
+ "Ogryn Bodyguard": [
+ "Close Combat Weapon"
+ ],
+ "Ogryn Squad": [
+ "Ripper Gun"
+ ],
+ "Primaris Psyker": true,
+ "Ratlings": [
+ "Close Combat Weapon"
+ ],
+ "Rogal Dorn Battle Tank": [
+ "Armoured Tracks"
+ ],
+ "Rogal Dorn Commander": [
+ "Armoured Tracks"
+ ],
+ "Scout Sentinels": [
+ "Close Combat Weapon"
+ ],
+ "Shadowsword": [
+ "Volcano Cannon",
+ "Armoured Tracks"
+ ],
+ "Sly Marbo": true,
+ "Stormlord": [
+ "Vulcan Mega-bolter",
+ "Armoured Tracks",
+ "Heavy Stubber"
+ ],
+ "StormSword": [
+ "Stormsword Siege Cannon",
+ "Armoured Tracks"
+ ],
+ "Taurox": [
+ "Twin Autocannon",
+ "Armoured Tracks"
+ ],
+ "Taurox Prime": [
+ "Armoured Tracks"
+ ],
+ "Tech-Priest Enginseer": [
+ "Mechanicus Pistol",
+ "Enginseer Axe",
+ "Servo-arm"
+ ],
+ "Tempestus Aquilons": [
+ "Close Combat Weapon"
+ ],
+ "Tempestus Scions": [
+ "Close Combat Weapon"
+ ],
+ "Ursula Creed": true,
+ "Valkyrie": [
+ "Armoured Hull"
+ ],
+ "Wyvern": [
+ "Wyvern Quad Stormshard Mortar",
+ "Armoured Tracks"
+ ]
+ },
+ "Black Templars": {
+ "Black Templars Gladiator Lancer": [
+ "Lancer Laser Destroyer",
+ "Armoured Hull"
+ ],
+ "Black Templars Gladiator Reaper": [
+ "Tempest Bolter",
+ "Twin Heavy Onslaught Gatling Cannon",
+ "Armoured Hull"
+ ],
+ "Black Templars Gladiator Valiant": [
+ "Twin Las-Talon",
+ "Armored Hull"
+ ],
+ "Black Templars Impulsor": [
+ "Armoured Hull"
+ ],
+ "Black Templars Repulsor": [
+ "Heavy Onslaught Gatling Cannon",
+ "Hunter-Slayer Missile",
+ "Repulsor Defensive Array",
+ "Armoured Hull"
+ ],
+ "Black Templars Repulsor Executioner": [
+ "Heavy Onslaught Gatling Cannon",
+ "Repulsor Executioner Defensive Array",
+ "Twin Heavy Bolter",
+ "Twin Icarus Ironhail Heavy Stubber",
+ "Armoured Hull"
+ ],
+ "Castellan": [],
+ "Chaplain Grimaldus": true,
+ "Crusade Ancient": true,
+ "Crusader Squad": [
+ "Master-crafted Power Weapon"
+ ],
+ "Emperor’s Champion": true,
+ "Execrator": [
+ "Crozius Arcanum"
+ ],
+ "Gladiator Lancer": [
+ "Lancer Laser Destroyer",
+ "Armoured Hull"
+ ],
+ "Gladiator Reaper": [
+ "Tempest Bolter",
+ "Twin Heavy Onslaught Gatling Cannon",
+ "Armoured Hull"
+ ],
+ "Gladiator Valiant": [
+ "Twin Las-talon",
+ "Armoured Hull"
+ ],
+ "High Marshal Helbrecht": [
+ "Ferocity",
+ "Sword of the High Marshals"
+ ],
+ "Impulsor": [
+ "Armoured Hull"
+ ],
+ "Land Raider Crusader": [
+ "Hurricane Bolter",
+ "Twin Assault Cannon",
+ "Armoured Tracks"
+ ],
+ "Marshal": [
+ "Master-Crafted Power Weapon"
+ ],
+ "Primaris Crusader Squad": [],
+ "Primaris Sword Bretheren": [],
+ "Repulsor": [
+ "Hunter-slayer Missile",
+ "Repulsor Defensive Array",
+ "Armoured Hull"
+ ],
+ "Repulsor Executioner": [
+ "Heavy Onslaught Gatling Cannon",
+ "Repulsor Executioner Defensive Array",
+ "Twin Heavy Bolter",
+ "Twin Icarus Ironhail Heavy Stubber",
+ "Armoured Hull"
+ ],
+ "Sternguard Veteran Squad": [
+ "Sternguard Bolt Pistol",
+ "Close Combat Weapon"
+ ],
+ "The Emperor's Champion": true
+ },
+ "Blood Angels": {
+ "Astorath": true,
+ "Baal Predator": [
+ "Armoured Tracks"
+ ],
+ "Blood Angels Captain": [],
+ "Chief Librarian Mephiston": true,
+ "Commander Dante": true,
+ "Death Company Captain": [],
+ "Death Company Captain with Jump Pack": [],
+ "Death Company Dreadnought": [
+ "Twin Icarus Ironhail Heavy Stubber"
+ ],
+ "Death Company Marines": [],
+ "Death Company Marines with Bolt Rifles": [
+ "Bolt Pistol"
+ ],
+ "Death Company Marines with Jump Packs": [],
+ "Lemartes": true,
+ "Sanguinary Guard": [],
+ "Sanguinary Priest": true,
+ "The Sanguinor": true
+ },
+ "Chaos Daemons": {
+ "Accursed Cultists": true,
+ "Be'Lakor": [
+ "Betraying Shades",
+ "The Blade of Shadows"
+ ],
+ "Be’lakor": true,
+ "Beasts of Nurgle": [
+ "Putrid Appendages"
+ ],
+ "Beasts Of Nurgle": true,
+ "Bloodcrushers": [
+ "Hellblade",
+ "Juggernaut's Bladed Horn"
+ ],
+ "Bloodletters": [
+ "Hellblade"
+ ],
+ "Bloodmaster": [
+ "Blade of Blood"
+ ],
+ "Bloodthirster": [
+ "Hellfire Breath"
+ ],
+ "Blue Horrors": [
+ "Coruscating Blue Flames",
+ "Coruscating Yellow Flames",
+ "Blue Claws",
+ "Yellow Claws"
+ ],
+ "Burning Chariot": [
+ "Fire of Tzeentch",
+ "Flamer Mouths",
+ "Screamer Bites"
+ ],
+ "Changecaster": [
+ "Arcane Fireball",
+ "Herald Combat Weapon"
+ ],
+ "Chaos Lord": [
+ "Astartes Chainblade"
+ ],
+ "Contorted Epitome": [
+ "Coiled Tentacles",
+ "Ravaging Claws"
+ ],
+ "Cultist Firebrand": true,
+ "Cultist Mob": [
+ "Brutal Assault Weapon"
+ ],
+ "Daemon Prince of Chaos": [
+ "Infernal Cannon",
+ "Hellforged Weapons"
+ ],
+ "Daemon Prince of Chaos With Wings": [
+ "Hellforged Weapons",
+ "Infernal Cannon"
+ ],
+ "Daemon Prince Of Chaos With Wings": true,
+ "Daemonettes": [
+ "Slashing Claws"
+ ],
+ "Dark Apostle": true,
+ "Dark Commune": true,
+ "Epidemius": [
+ "Balesword and Nurgling Attendants"
+ ],
+ "Exalted Flamer": [
+ "Fire of Tzeentch",
+ "Flamer Mouths"
+ ],
+ "Fateskimmer": [
+ "Arcane Fireball",
+ "Herald Combat Weapon",
+ "Screamer Bites"
+ ],
+ "Fellgor Beastmen": [
+ "Autopistol",
+ "Chainsword"
+ ],
+ "Fiends": [
+ "Barbed Tail and Dissecting Claws"
+ ],
+ "Flamers": [
+ "Flickering Flames",
+ "Flamer Mouths"
+ ],
+ "Flesh Hounds": [
+ "Burning Roar",
+ "Gore-drenched Fangs",
+ "Collar of Khorne"
+ ],
+ "Fluxmaster": [
+ "Arcane Fireball",
+ "Herald Combat Weapon"
+ ],
+ "Great Unclean One": [
+ "Putrid Vomit"
+ ],
+ "Havocs": [
+ "Close Combat Weapon"
+ ],
+ "Hellflayers": [
+ "Lashes of Torment",
+ "Seeker Tongues",
+ "Slashing Claws"
+ ],
+ "Horticulous Slimux": [
+ "Acidic Maw",
+ "Lopping Shears"
+ ],
+ "Infernal Enrapturess": [
+ "Heartstring Lyre",
+ "Ravaging Claws"
+ ],
+ "Kairos Fateweaver": [
+ "Infernal Gateway",
+ "Staff of Tomorrow"
+ ],
+ "Karanak": [
+ "Scalding Roar",
+ "Soul-rending Fangs",
+ "Brass Collar of Bloody Vengeance"
+ ],
+ "Keeper of Secrets": [
+ "Phantasmagoria",
+ "Snapping Claws",
+ "Witstealer Sword"
+ ],
+ "Legionaries": [
+ "Close Combat Weapon"
+ ],
+ "Lord of Change": [
+ "Bolt of Change",
+ "Staff of Tzeentch"
+ ],
+ "Master Of Possession": true,
+ "Nurglings": [
+ "Diseased Claws and Teeth"
+ ],
+ "Pink Horrors": [
+ "Coruscating Blue Flames",
+ "Coruscating Yellow Flames",
+ "Coruscating Pink Flames",
+ "Pink Claws",
+ "Blue Claws",
+ "Yellow Claws"
+ ],
+ "Plague Drones": [
+ "Death's Heads",
+ "Foul Mouthparts",
+ "Plaguesword"
+ ],
+ "Plaguebearers": [
+ "Plaguesword"
+ ],
+ "Possessed": [
+ "Hideous Mutations"
+ ],
+ "Poxbringer": [
+ "Foul Balesword"
+ ],
+ "Rendmaster on Blood Throne": [
+ "Attendants' Hellblades",
+ "Blade of Blood"
+ ],
+ "Rendmaster On Blood Throne": true,
+ "Rotigus": [
+ "Streams of Brackish Filth",
+ "Gnarlrod"
+ ],
+ "Screamers": [
+ "Lamprey Bite"
+ ],
+ "Seekers": [
+ "Lashing Tongue",
+ "Slashing Claws"
+ ],
+ "Shalaxi Helbane": [
+ "Lash of Slaanesh",
+ "Pavane of Slaanesh",
+ "Snapping Claws",
+ "Soulpiercer"
+ ],
+ "Skarbrand": [
+ "Bellow of Endless Fury",
+ "Slaughter and Carnage"
+ ],
+ "Skull Cannon": [
+ "Skull Cannon",
+ "Attendants’ Hellblades",
+ "Biting Maw"
+ ],
+ "Skullmaster": [
+ "Blade of Blood",
+ "Juggernaut’s Bladed Horn"
+ ],
+ "Skulltaker": [
+ "The Slayer Sword"
+ ],
+ "Sloppity Bilepiper": [
+ "Marotter"
+ ],
+ "Sorcerer": true,
+ "Sorcerer In Terminator Armour": [
+ "Infernal Gaze",
+ "Force Weapon"
+ ],
+ "Soul Grinder": [
+ "Harvester Cannon",
+ "Iron Claw",
+ "Torrent of Burning Blood",
+ "Phlegm Bombardment",
+ "Scream of Despair",
+ "Warp Gaze"
+ ],
+ "Spoilpox Scrivener": [
+ "Disgusting Sneezes",
+ "Plaguesword and Distended Maw"
+ ],
+ "Syll'esske": [
+ "Cacophonic Choir",
+ "Scourging Whip",
+ "Axe of Dominion"
+ ],
+ "Syll’esske": true,
+ "The Blue Scribes": [
+ "Sharp Quills"
+ ],
+ "The Changeling": [
+ "Infernal Flames",
+ "The Trickster’s Staff"
+ ],
+ "The masque of Slaanesh": [
+ "Serrated Claws"
+ ],
+ "The Masque Of Slaanesh": true,
+ "Tormentbringer": [
+ "Lashes of Torment",
+ "Seeker Tongues",
+ "Slashing Claws"
+ ],
+ "Traitor Enforcer": [
+ "Bolt Pistol",
+ "Ogryn Weapons",
+ "Power Fist"
+ ],
+ "Tranceweaver": [
+ "Ravaging Claws"
+ ],
+ "Warp Talons": [
+ "Warp Claws"
+ ]
+ },
+ "Chaos Knights": {
+ "Accursed Cultists": true,
+ "Chaos Acastus Knight Asterius": [
+ "Asterius Volkite Culverin",
+ "Karacnos Mortar Battery",
+ "Twin Conversion Beam Cannon",
+ "Titanic Feet"
+ ],
+ "Chaos Acastus Knight Porphyrion": [
+ "Twin Magna Lascannon",
+ "Titanic Feet"
+ ],
+ "Chaos Cerastus Knight Acheron": [
+ "Acheron Flame Cannon",
+ "Twin Heavy Bolter",
+ "Reaper Chainfist"
+ ],
+ "Chaos Cerastus Knight Atrapos": [
+ "Atrapos Lascutter",
+ "Graviton Singularity Cannon"
+ ],
+ "Chaos Cerastus Knight Castigator": [
+ "Castigator Bolt Cannon",
+ "Tempest Warblade"
+ ],
+ "Chaos Cerastus Knight Lancer": [
+ "Cerastus Shock Lance"
+ ],
+ "Chaos Questoris Knight Magaera": [
+ "Lightning cannon",
+ "Phased Plasma-fusil"
+ ],
+ "Chaos Questoris Knight Styrix": [
+ "Graviton Crusher",
+ "Volkite Chierovile"
+ ],
+ "Cultist Firebrand": true,
+ "Cultist Mob": [
+ "Brutal Assault Weapon"
+ ],
+ "Dark Commune": true,
+ "Fellgor Beastmen": [
+ "Autopistol",
+ "Chainsword"
+ ],
+ "Knight Abominant": true,
+ "Knight Desecrator": [
+ "Diabolus Heavy Stubber",
+ "Desecrator Laser Destructor"
+ ],
+ "Knight Despoiler": [
+ "Titanic Feet"
+ ],
+ "Knight Rampager": true,
+ "Knight Ruinator": true,
+ "Knight Tyrant": [
+ "Titanic Feet",
+ "Twin Daemonbreath Meltagun"
+ ],
+ "Traitor Enforcer": [
+ "Bolt Pistol",
+ "Ogryn Weapons",
+ "Power Fist"
+ ],
+ "War Dog Brigand": [
+ "Avenger Chaincannon",
+ "Daemonbreath Spear",
+ "Armoured Feet"
+ ],
+ "War Dog Executioner": [
+ "War Dog Autocannon",
+ "Armoured Feet"
+ ],
+ "War Dog Huntsman": [
+ "Reaper Chaintalon",
+ "Daemonbreath Spear"
+ ],
+ "War Dog Karnivore": [
+ "Reaper Chaintalon",
+ "Slaughterclaw"
+ ],
+ "War Dog Moirax": [
+ "Armoured Feet"
+ ],
+ "War Dog Stalker": []
+ },
+ "Chaos Space Marines": {
+ "Abaddon The Despoiler": true,
+ "Abbadon the Despoiler": true,
+ "Accursed Cultists": true,
+ "Chaos Bikers": [
+ "Close Combat Weapon"
+ ],
+ "Chaos Land Raider": [
+ "Soulshatter Lascannon",
+ "Twin Heavy Bolter",
+ "Armoured Tracks"
+ ],
+ "Chaos Lord": [
+ "Astartes Chainblade"
+ ],
+ "Chaos Lord in Terminator Armour": [],
+ "Chaos Lord with Jump Pack": [],
+ "Chaos Predator Annihilator": [
+ "Predator Twin Lascannon",
+ "Armoured Tracks"
+ ],
+ "Chaos Predator Destructor": [
+ "Predator Autocannon",
+ "Armoured Tracks"
+ ],
+ "Chaos Rhino": [
+ "Armoured Tracks"
+ ],
+ "Chaos Spawn": [
+ "Hideous Mutations"
+ ],
+ "Chaos Terminator Squad": [],
+ "Chaos Vindicator": [
+ "Demolisher Cannon",
+ "Armoured Tracks"
+ ],
+ "Chosen": [],
+ "Cultist Firebrand": true,
+ "Cultist Mob": [
+ "Brutal Assault Weapon"
+ ],
+ "Cypher": true,
+ "Dark Apostle": true,
+ "Dark Commune": true,
+ "Defiler": [
+ "Shearing Claws"
+ ],
+ "Fabius Bile": true,
+ "Fellgor Beastmen": [
+ "Chainsword",
+ "Autopistol"
+ ],
+ "Forgefiend": [],
+ "Haarken Worldclaimer": true,
+ "Havocs": [
+ "Close Combat Weapon"
+ ],
+ "Helbrute": [
+ "Close Combat Weapon"
+ ],
+ "Heldrake": [
+ "Heldrake Claws"
+ ],
+ "Heretic Astartes Daemon Prince": true,
+ "Heretic Astartes Daemon Prince With Wings": true,
+ "Huron Blackheart": [
+ "Tyrant’s Claw Heavy Flamer",
+ "Tyrant’s Claw and Exalted Power Weapon"
+ ],
+ "Khorne Berzerkers": [],
+ "Khorne Lord of Skulls": [
+ "Great Cleaver of Khorne"
+ ],
+ "Kravek Morne": [
+ "Baleflamer",
+ "Combi-bolter",
+ "Last Argument and Power Fist",
+ "Servo-harness"
+ ],
+ "Legionaries": [
+ "Close Combat Weapon"
+ ],
+ "Lord Discordant on Helstalker": [
+ "bladed limbs",
+ "impaler chainglaive"
+ ],
+ "Lord Discordant On Helstalker": [
+ "Bolt Pistol"
+ ],
+ "Master of Executions": true,
+ "Master of Posession": true,
+ "Master Of Possession": true,
+ "Masters of the Maelstrom": true,
+ "Maulerfiend": [
+ "Maulerfiend Fists"
+ ],
+ "Mutilators": [
+ "Fleshmetal Weapons"
+ ],
+ "Nemesis Claw": [
+ "Close Combat Weapon"
+ ],
+ "Noctilith Crown": true,
+ "Noise Marines": [],
+ "Obliterators": true,
+ "Plague Marines": [],
+ "Possessed": [
+ "Hideous Mutations"
+ ],
+ "Raptors": [],
+ "Red Corsairs Reave-Captain": [
+ "Bolt Pistol"
+ ],
+ "Rubric Marines": [
+ "Malefic Curse",
+ "Close Combat Weapon",
+ "Force Weapon"
+ ],
+ "Sorcerer": true,
+ "Sorcerer in Terminator Armour": [
+ "Infernal Gaze",
+ "Force Weapon"
+ ],
+ "Traitor Enforcer": [
+ "Bolt Pistol",
+ "Ogryn Weapons",
+ "Power Fist"
+ ],
+ "Traitor Guardsmen Squad": [],
+ "Vashtorr the Arkifane": true,
+ "Venomcrawler": true,
+ "Warp Talons": [
+ "Warp Claws"
+ ],
+ "Warpsmith": true
+ },
+ "Dark Angels": {
+ "Asmodai": true,
+ "Azrael": true,
+ "Belial": true,
+ "Deathwing Knights": [],
+ "Deathwing Terminator Squad": [
+ "Power Weapon"
+ ],
+ "Ezekiel": true,
+ "Inner Circle Companions": true,
+ "Land Speeder Vengeance": [
+ "Plasma Storm Battery",
+ "Close Combat Weapon"
+ ],
+ "Lazarus": true,
+ "Lion El'Jonson": true,
+ "Lion El’jonson": [
+ "Arma Luminis",
+ "Fealty"
+ ],
+ "Nephilim Jetfighter": [
+ "Blacksword Missiles",
+ "Twin Heavy Bolter",
+ "Armoured Hull"
+ ],
+ "Ravenwind Darkshroud": [
+ "Close Combat Weapon"
+ ],
+ "Ravenwing Black Knights": [
+ "Bolt Pistol",
+ "Black Knight Combat Weapon"
+ ],
+ "Ravenwing Command Squad": [
+ "Bolt Pistol",
+ "Black Knight Combat Weapon",
+ "Master-Crafted Power Weapon"
+ ],
+ "Ravenwing Dark Talon": true,
+ "Ravenwing Darkshroud": [
+ "Close Combat Weapon"
+ ],
+ "Sammael": true
+ },
+ "Death Guard": {
+ "Beasts of Nurgle": true,
+ "Biologus Putrifier": true,
+ "Chaos Land Raider": [
+ "Soulshatter Lascannon",
+ "Twin Heavy Bolter",
+ "Armoured Tracks"
+ ],
+ "Chaos Predator Annihilator": [
+ "Predator Twin Lascannon",
+ "Armoured Tracks"
+ ],
+ "Chaos Predator Destructor": [
+ "Predator Autocannon",
+ "Armoured Tracks"
+ ],
+ "Chaos Rhino": [
+ "Armoured Tracks"
+ ],
+ "Chaos Spawn": true,
+ "Daemon Prince of Nurgle": true,
+ "Daemon Prince of Nurgle With Wings": true,
+ "Deathshroud Terminators": [
+ "Manreaper"
+ ],
+ "Defiler": [
+ "Shearing Claws"
+ ],
+ "Foetid Bloat Drone": [
+ "Plague Probe"
+ ],
+ "Foetid Bloat Drone with Heavy Blight Launcher": true,
+ "Foul Blightspawn": true,
+ "Great Unclean One": [
+ "Putrid Vomit"
+ ],
+ "Helbrute": [
+ "Close Combat Weapon"
+ ],
+ "Icon Bearer": true,
+ "Lord of Contagion": true,
+ "Lord of Poxes": true,
+ "Lord of Virulence": true,
+ "Malignant Plaguecaster": true,
+ "Miasmic Malignifier": true,
+ "Mortarion": true,
+ "Myphitic Blight-hauler": true,
+ "Myphitic Blight-Haulers": true,
+ "Noxious Blightbringer": true,
+ "Nurglings": true,
+ "Plague Drones": [
+ "Death's Heads",
+ "Foul Mouthparts",
+ "Plaguesword"
+ ],
+ "Plague Marines": [],
+ "Plague Surgeon": true,
+ "Plaguebearers": [
+ "Plaguesword"
+ ],
+ "Plagueburst Crawler": [
+ "Plagueburst Mortar",
+ "Armoured Tracks"
+ ],
+ "Poxwalkers": true,
+ "Rotigus": true,
+ "Tallyman": true,
+ "Typhus": true
+ },
+ "Deathwatch": {
+ "Corvus Blackstar": [
+ "Armoured Hull"
+ ],
+ "Deathwatch Terminator Squad": [],
+ "Deathwatch Veterans": [],
+ "Decimus Kill Team": [
+ "Bolt Pistol",
+ "Plasma Pistol",
+ "Special-issue Bolt Pistol",
+ "Close Combat Weapon",
+ "Xenophase Blade"
+ ],
+ "Fortis Kill Team": [
+ "Castellan Launcher",
+ "Heavy Bolt Pistol",
+ "Pyreblaster"
+ ],
+ "Indomitor Kill Team": [
+ "Bolt Pistol",
+ "Close Combat Weapon",
+ "Twin Power Fists"
+ ],
+ "Spectrus Kill Team": [
+ "Bolt Pistol",
+ "Deathwatch Occulus Bolt Carbine",
+ "Special-issue Bolt Pistol",
+ "Paired Combat Blades"
+ ],
+ "Talonstrike Kill Team": [
+ "Close Combat Weapon"
+ ],
+ "Watch Captain Artemis": [
+ "Hellfire Extremis",
+ "Master-crafted Power Weapon"
+ ],
+ "Watch Master": [
+ "Vigil Spear"
+ ]
+ },
+ "Drukhari": {
+ "Archon": [
+ "Shadowfield"
+ ],
+ "Beastmaster": true,
+ "Corsair Voidreavers": [
+ "Close Combat Weapon"
+ ],
+ "Corsair Voidscarred": [
+ "Executioner",
+ "Close Combat Weapon",
+ "Paired Hekatarii Blades",
+ "Witch Staff",
+ "Channeller Stones"
+ ],
+ "Court of the Archon": true,
+ "Cronos": [
+ "Spirit Syphon",
+ "Spirit-Leech Tentacles"
+ ],
+ "Death Jester": true,
+ "Drazhar": true,
+ "Grotesques": [
+ "Monstrous Weapons"
+ ],
+ "Haemonculus": true,
+ "Hellions": [
+ "Splinter Pods"
+ ],
+ "Kharseth": [
+ "Dread of the Deep Void",
+ "Waystave"
+ ],
+ "Lady Malys": true,
+ "Lelith Hesperax": true,
+ "Mandrakes": true,
+ "Prince Yriel": [
+ "Eye of Wrath",
+ "Shuriken Pistol",
+ "Spear of Twilight"
+ ],
+ "Raider": [
+ "Bladevanes and Chainsnares"
+ ],
+ "Ravager": [
+ "Bladevanes"
+ ],
+ "Razorwing Jetfighter": [
+ "Razorwing Missiles",
+ "Bladed Wings"
+ ],
+ "Reavers": [
+ "Splinter Pistol",
+ "Bladevanes"
+ ],
+ "Scourges": [
+ "Close Combat Weapon"
+ ],
+ "Scourges with Heavy Weapons": [
+ "Close Combat Weapon"
+ ],
+ "Scourges with Shardcarbines": [
+ "Close Combat Weapon"
+ ],
+ "Shadowseer": [
+ "Miststave",
+ "Flip Belt"
+ ],
+ "Skyweavers": [
+ "Close Combat Weapon"
+ ],
+ "Solitaire": true,
+ "Starfangs": [
+ "Disintegrator Cannon",
+ "Starfang Grenade Launcher",
+ "Wraithbone Hull"
+ ],
+ "Starweaver": true,
+ "Succubus": true,
+ "Talos": [],
+ "Troupe": [
+ "Flip Belt"
+ ],
+ "Troupe Master": [
+ "Flip Belt"
+ ],
+ "Urien Rakarth": true,
+ "Venom": [
+ "Bladevanes"
+ ],
+ "Voidraven Bomber": [
+ "Bladed Wings"
+ ],
+ "Voidweaver": [
+ "Shuriken Cannon",
+ "Close Combat Weapon"
+ ]
+ },
+ "Emperor's Children": {
+ "Chaos Land Raider": [
+ "Soulshatter Lascannon",
+ "Twin Heavy Bolter",
+ "Armoured Tracks"
+ ],
+ "Chaos Rhino": [
+ "Armoured Tracks"
+ ],
+ "Chaos Spawn": true,
+ "Chaos Terminators": [],
+ "Daemon Prince of Slaanesh": true,
+ "Daemon Prince of Slaanesh with Wings": true,
+ "Daemonettes": [
+ "Slashing Claws"
+ ],
+ "Fiends": true,
+ "Flawless Blades": true,
+ "Fulgrim": true,
+ "Heldrake": [
+ "Heldrake Claws"
+ ],
+ "Infractors": [
+ "Duelling Sabre"
+ ],
+ "Keeper of Secrets": [
+ "Phantasmagoria",
+ "Snapping Claws",
+ "Witstealer Sword"
+ ],
+ "Lord Exultant": [],
+ "Lucius the Eternal": true,
+ "Maulerfiend": [
+ "Maulerfiend Fists"
+ ],
+ "Noise Marines": [
+ "Close Combat Weapon"
+ ],
+ "Seekers": [
+ "Lashing Tongue",
+ "Slashing Claws"
+ ],
+ "Shalaxi Helbane": true,
+ "Sorcerer": true,
+ "Tormentors": []
+ },
+ "Genestealer Cults": {
+ "Aberrants": true,
+ "Abominant": true,
+ "Achilles Ridgerunners": [
+ "Armoured Hull",
+ "Twin Heavy Stubber"
+ ],
+ "Acolyte Hybrids with Autopistols": [],
+ "Acolyte Hybrids with Hand Flamers": [],
+ "Acolyte Iconward": true,
+ "Armoured Sentinels": [
+ "Close Combat Weapon"
+ ],
+ "Artillery Team": [
+ "Lasgun",
+ "Crew Close Combat Weapons"
+ ],
+ "Attilan Rough Riders": [
+ "Lasgun",
+ "Laspistol",
+ "Steed’s Hooves"
+ ],
+ "Baneblade": [
+ "Baneblade Cannon",
+ "Coaxial Autocannon",
+ "Demolisher Cannon",
+ "Heavy Stubber",
+ "Armoured Tracks"
+ ],
+ "Banehammer": [
+ "Tremor Cannon",
+ "Armoured Tracks"
+ ],
+ "Banesword": [
+ "Quake Cannon",
+ "Armoured Tracks"
+ ],
+ "Basilisk": [
+ "Earthshaker Cannon",
+ "Armoured Tracks"
+ ],
+ "Benefictus": true,
+ "Biophagus": true,
+ "Cadian Command Squad": [
+ "Master Vox",
+ "Medi-pack"
+ ],
+ "Cadian Heavy Weapons Squad": [
+ "Laspistol",
+ "Weapons Team Close Combat Weapons"
+ ],
+ "Catachan Command Squad": [
+ "Close Combat Weapon"
+ ],
+ "Catachan Heavy Weapons Squad": [
+ "Lasgun",
+ "Weapons Team Close Combat Weapons"
+ ],
+ "Catachan Jungle Fighters": [
+ "Laspistol",
+ "Close Combat Weapon"
+ ],
+ "Centaur RSV": [
+ "Pintle-mounted Heavy Stubber",
+ "Armoured Hull"
+ ],
+ "Chimera": [
+ "Lasgun Array",
+ "Armoured Tracks"
+ ],
+ "Clamavus": true,
+ "Death Riders": true,
+ "Deathleaper": true,
+ "Deathstrike": [
+ "Deathstrike Missile",
+ "Armoured Tracks"
+ ],
+ "Doomhammer": [
+ "Magma Cannon",
+ "Armoured Tracks"
+ ],
+ "Field Ordnance Battery": [
+ "Lasgun",
+ "Laspistol",
+ "Battery Close Combat Weapons"
+ ],
+ "Gargoyles": true,
+ "Goliath Rockgrinder": [
+ "Heavy Stubber",
+ "Drilldozer blade",
+ "Demolition Charge Cache"
+ ],
+ "Goliath Truck": true,
+ "Hellhammer": [
+ "Coaxial Autocannon",
+ "Demolisher Cannon",
+ "Heavy Stubber",
+ "Hellhammer Cannon",
+ "Armoured Tracks"
+ ],
+ "Hellhound": [
+ "Armoured Tracks"
+ ],
+ "Hippogriff AFV": [
+ "Armoured Hull"
+ ],
+ "Hybrid Metamorphs": [
+ "Leader's Bio-weapons",
+ "Metamorph Mutations"
+ ],
+ "Hydra": [
+ "Hydra Autocannon",
+ "Armoured Tracks"
+ ],
+ "Hyperadapted Raveners": true,
+ "Jackal Alphus": true,
+ "Kasrkin": [
+ "Close Combat Weapon"
+ ],
+ "Kelermorph": true,
+ "Krieg Command Squad": [
+ "Lasgun",
+ "Close Combat Weapon",
+ "Master Vox",
+ "Regimental Standard",
+ "Servo-scribes"
+ ],
+ "Krieg Heavy Weapons Squad": [
+ "Laspistol",
+ "Close Combat Weapon"
+ ],
+ "Leman Russ Battle Tank": [
+ "Leman Russ Battle Cannon",
+ "Armoured Tracks"
+ ],
+ "Leman Russ Commander": [
+ "Armoured Tracks"
+ ],
+ "Leman Russ Demolisher": [
+ "Demolisher Battle Cannon",
+ "Armoured Tracks"
+ ],
+ "Leman Russ Eradicator": [
+ "Eradicator Nova Cannon",
+ "Armoured Tracks"
+ ],
+ "Leman Russ Executioner": [
+ "Executioner Plasma Cannon",
+ "Armoured Tracks"
+ ],
+ "Leman Russ Exterminator": [
+ "Exterminator Autocannon",
+ "Armoured Tracks"
+ ],
+ "Leman Russ Punisher": [
+ "Punisher Gatling Cannon",
+ "Armoured Tracks"
+ ],
+ "Leman Russ Vanquisher": [
+ "Vanquisher Battle Cannon",
+ "Armoured Tracks"
+ ],
+ "Lictor": true,
+ "Locus": true,
+ "Magus": true,
+ "Manticore": [
+ "Storm Eagle Rockets",
+ "Armoured Tracks"
+ ],
+ "Mawloc": true,
+ "Neophyte Hybrids": [
+ "Autopistol"
+ ],
+ "Neurolictor": true,
+ "Nexos": true,
+ "Parasite Of Mortrex": true,
+ "Patriarch": true,
+ "Primaris Psyker": true,
+ "Primus": true,
+ "Purestrain Genestealers": true,
+ "Raveners": [
+ "Ravener Claws and Talons"
+ ],
+ "Reductus Saboteur": true,
+ "Rogal Dorn Battle Tank": [
+ "Armoured Tracks"
+ ],
+ "Rogal Dorn Commander": [
+ "Armoured Tracks"
+ ],
+ "Sanctus": [],
+ "Scout Sentinels": [
+ "Close Combat Weapon"
+ ],
+ "Shadowsword": [
+ "Volcano Cannon",
+ "Armoured Tracks"
+ ],
+ "Stormlord": [
+ "Heavy Stubber",
+ "Vulcan Mega-bolter",
+ "Armoured Tracks"
+ ],
+ "Stormsword": [
+ "Stormsword Siege Cannon",
+ "Armoured Tracks"
+ ],
+ "Taurox": [
+ "Twin Autocannon",
+ "Armoured Tracks"
+ ],
+ "Taurox Prime": [
+ "Armoured Tracks"
+ ],
+ "The Red Terror": [
+ "Gaping Maw",
+ "Scything Talons"
+ ],
+ "Trygon": true,
+ "Tyrannocyte": true,
+ "Von Ryan’s Leapers": true,
+ "Winged Hive Tyrant": [
+ "Tyrant Talons"
+ ],
+ "Winged Tyranid Prime": [
+ "Prime Talons"
+ ],
+ "Wyvern": [
+ "Wyvern Quad Stormshard Mortar",
+ "Armoured Tracks"
+ ]
+ },
+ "Grey Knights": {
+ "Brother-captain": [
+ "Nemesis Force Weapon"
+ ],
+ "Brother-Captain Stern": true,
+ "Brotherhood Champion": true,
+ "Brotherhood Chaplain": true,
+ "Brotherhood Librarian": [
+ "Vortex of Doom",
+ "Nemesis Force Weapon"
+ ],
+ "Brotherhood Techmarine": true,
+ "Brotherhood Terminator Squad": [
+ "Nemesis Force Weapon"
+ ],
+ "Castellan Crowe": true,
+ "Grand Master": [
+ "Nemesis Force Weapon"
+ ],
+ "Grand Master in Nemesis Dreadknight": [
+ "Fragstorm Grenade Launcher"
+ ],
+ "Grand Master Voldus": true,
+ "Grey Knights Thunderhawk Gunship": [
+ "Lascannon",
+ "Twin Heavy Bolter",
+ "Armoured Hull"
+ ],
+ "Kaldor Draigo": true,
+ "Land Raider": [
+ "Godhammer Lascannon",
+ "Twin Heavy Bolter",
+ "Armoured Tracks"
+ ],
+ "Land Raider Banisher": [
+ "Armoured Tracks"
+ ],
+ "Land Raider Crusader": [
+ "Hurricane Bolter",
+ "Twin Assault Cannon",
+ "Armoured Tracks"
+ ],
+ "Land Raider Redeemer": [
+ "Flamestorm Cannon",
+ "Twin Assault Cannon",
+ "Armoured Tracks"
+ ],
+ "Nemesis Dreadknight": [],
+ "Paladin Squad": [
+ "Nemesis Force Weapon"
+ ],
+ "Purifier squad": [
+ "Purifying Flame",
+ "Close Combat Weapon"
+ ],
+ "Razorback": [
+ "Armoured Tracks"
+ ],
+ "Rhino": [
+ "Armoured Tracks"
+ ],
+ "Servitors": [
+ "Servitor's Servo-arm",
+ "Servitor's Tools"
+ ],
+ "Stormhawk Interceptor": [
+ "Armoured Hull",
+ "Twin Assault Cannon"
+ ],
+ "Stormraven Gunship": [
+ "Stormstrike Missile Launcher",
+ "Armoured Hull"
+ ],
+ "Stormtalon Gunship": [
+ "Twin Assault Cannon",
+ "Armoured Hull"
+ ],
+ "Venerable Dreadnought": [
+ "Dreadnought Combat Weapon"
+ ]
+ },
+ "Imperial Fists": {
+ "Darnath Lysander": true,
+ "Pedro Kantor": true,
+ "Tor Garadon": true
+ },
+ "Imperial Knights": {
+ "Acastus Knight Asterius": [
+ "Asterius Volkite Culverin",
+ "Karacnos Mortar Battery",
+ "Twin Conversion Beam Cannon",
+ "Titanic Feet"
+ ],
+ "Acastus Knight Porphyrion": [
+ "Twin Magna Lascannon",
+ "Titanic Feet"
+ ],
+ "Armiger Helverin": [
+ "Armiger Autocannon",
+ "Armoured Feet"
+ ],
+ "Armiger Moirax": [
+ "Armoured Feet"
+ ],
+ "Armiger Warglaive": [
+ "Reaper Chain-cleaver",
+ "Thermal Spear"
+ ],
+ "Canis Rex": true,
+ "Cerastus Knight Acheron": [
+ "Acheron Flame Cannon",
+ "Twin Heavy Bolter",
+ "Reaper Chainfist"
+ ],
+ "Cerastus Knight Atrapos": [
+ "Atrapos Lascutter",
+ "Graviton Singularity Cannon"
+ ],
+ "Cerastus Knight Castigator": [
+ "Castigator Bolt Cannon",
+ "Tempest Warblade"
+ ],
+ "Cerastus Knight Lancer": [
+ "Cerastus Shock Lance"
+ ],
+ "Knight Castellan": [
+ "Plasma Decimator",
+ "Twin Meltagun",
+ "Volcano Lance",
+ "Titanic Feet"
+ ],
+ "Knight Crusader": [
+ "Avenger Gatling Cannon",
+ "Titanic Feet",
+ "Heavy Flamer"
+ ],
+ "Knight Defender": true,
+ "Knight Destrier": [
+ "Titanic Feet",
+ "Questoris Heavy Stubber"
+ ],
+ "Knight Errant": [
+ "Thermal Cannon"
+ ],
+ "Knight Gallant": [
+ "Thunderstrike Gauntlet",
+ "Reaper Chainsword"
+ ],
+ "Knight Paladin": [
+ "Rapid-Fire Battle Cannon"
+ ],
+ "Knight Preceptor": [
+ "Las-Impulsor"
+ ],
+ "Knight Valiant": [
+ "Conflagration Cannon",
+ "Thundercoil Harpoon",
+ "Twin Meltagun",
+ "Titanic Feet"
+ ],
+ "Knight Warden": [
+ "Avenger Gatling Cannon",
+ "Heavy Flamer"
+ ],
+ "Questoris Knight Magaera": [
+ "Lightning Cannon",
+ "Phased Plasma-fusil"
+ ],
+ "Questoris Knight Styrix": [
+ "Graviton Crusher",
+ "Volkite Chierovile"
+ ],
+ "Sir Hekhtur": true,
+ "Skitarii Marshal": true,
+ "Skitarii Rangers": [
+ "Close Combat Weapon"
+ ],
+ "Skitarii Vanguard": [
+ "Close Combat Weapon"
+ ],
+ "Tech-priest Dominus": [
+ "Omnissian Axe"
+ ],
+ "Tech-priest Manipulus": [
+ "Omnissian Staff"
+ ]
+ },
+ "Iron Hands": {
+ "Caanok Var": true,
+ "Iron Father Feirros": true
+ },
+ "Leagues of Votann": {
+ "Arcanyst Evaluator": true,
+ "Arkanyst Evaluator": true,
+ "Berehk Stornbröw": [
+ "Kromlôk’s Revenge",
+ "Warforge Gauntlets"
+ ],
+ "Brôkhyr Iron-master": true,
+ "Brôkhyr Thunderkyn": [
+ "Close combat weapon"
+ ],
+ "Buri Aegnirssen": true,
+ "Cthonian Earthshakers": [
+ "Autoch-pattern bolt pistol",
+ "Plasma picks"
+ ],
+ "Einhyr Champion": [
+ "Autoch-pattern combi-bolter"
+ ],
+ "Einhyr Hearthguard": [
+ "Exoarmour Grenade Launcher"
+ ],
+ "Grimnyr": true,
+ "Hearthkyn Warriors": [
+ "Weavefield crest",
+ "Autoch-pattern bolt pistol",
+ "Close combat weapon"
+ ],
+ "Hekaton Land Fortress": [
+ "Armoured wheels",
+ "MATR autocannon"
+ ],
+ "Hernkyn Pioneers": [
+ "Bolt Revolver",
+ "Bolt Shotgun",
+ "Magna-coil autocannon",
+ "Plasma knife"
+ ],
+ "Hernkyn Yaegirs": [
+ "Close combat weapon"
+ ],
+ "Ironkin Steeljacks with Heavy Volkanite Disintegrators": [
+ "Preymark crest"
+ ],
+ "Ironkin Steeljacks with Melee Weapons": [
+ "Preymark crest",
+ "Autoch-pattern bolter"
+ ],
+ "Kâhl": [
+ "Autoch-pattern Combi-bolter"
+ ],
+ "Kapricus Carrier": [
+ "Armoured hull",
+ "Magna-coil autocannon",
+ "Twin magna-coil autocannon"
+ ],
+ "Kapricus Defenders": [
+ "Armoured hull",
+ "Twin magna-coil autocannon"
+ ],
+ "Memnyr Strategist": true,
+ "Sagitaur": [
+ "Armoured wheels",
+ "Twin bolt cannon"
+ ],
+ "Ûthar the Destined": true
+ },
+ "Necrons": {
+ "Annihilation Barge": [
+ "Twin Tesla Destructor",
+ "Armoured Bulk"
+ ],
+ "C'tan Shard of the Deceiver": true,
+ "C'tan Shard of the Nightbringer": true,
+ "C'tan Shard of the Void Dragon": true,
+ "Canoptek Doomstalker": true,
+ "Canoptek Macrocytes": [
+ "Claws"
+ ],
+ "Canoptek Reanimator": true,
+ "Canoptek Scarab Swarms": true,
+ "Canoptek Spyders": [
+ "Automaton Claws"
+ ],
+ "Canoptek Tomb Crawlers": [
+ "Claws"
+ ],
+ "Canoptek Wraiths": [],
+ "Catacomb Command Barge": [],
+ "Chronomancer": true,
+ "Convergence of Dominion": true,
+ "Cryptothralls": true,
+ "Deathmarks": true,
+ "Doom Scythe": true,
+ "Doomsday Ark": true,
+ "Flayed Ones": true,
+ "Geomancer": true,
+ "Ghost Ark": true,
+ "Hexmark Destroyer": true,
+ "Illuminor Szeras": true,
+ "Immortals": [
+ "Close Combat Weapon"
+ ],
+ "Imotekh the Stormlord": true,
+ "Lokhust Destroyers": true,
+ "Lokhust Heavy Destroyers": [
+ "Close Combat Weapon"
+ ],
+ "Lychguard": [],
+ "Monolith": [
+ "Particle Whip",
+ "Portal of Exile"
+ ],
+ "Necron Warriors": [
+ "Close Combat Weapon"
+ ],
+ "Nekrosor Ammentar": true,
+ "Night Scythe": true,
+ "Obelisk": true,
+ "Ophydian Destroyers": [
+ "Ophydian Hyperphase Weapons"
+ ],
+ "Orikan the Diviner": true,
+ "Overlord": [],
+ "Overlord with Translocation Shroud": true,
+ "Plasmancer": true,
+ "Psychomancer": true,
+ "Royal Warden": true,
+ "Seraptek Heavy Construct": [
+ "Titanic Forelimbs"
+ ],
+ "Skorpekh Destroyers": [
+ "Skorpekh Hyperphase Weapons"
+ ],
+ "Skorpekh Lord": true,
+ "Technomancer": true,
+ "Tesseract Vault": true,
+ "The Silent king": true,
+ "Tomb Blades": [
+ "Close Combat Weapon"
+ ],
+ "Transcendent C'tan": true,
+ "Trazyn the Infinite": true,
+ "Triarch Praetorians": [],
+ "Triarch Stalker": [
+ "Stalker's Forelimbs"
+ ]
+ },
+ "Orks": {
+ "Battlewagon": [],
+ "Beast Snagga Boyz": [
+ "Power Snappa"
+ ],
+ "Beastboss": true,
+ "Beastboss on Squigosaur": [
+ "Slugga",
+ "Beastchoppa",
+ "Squigosaur's Jaws"
+ ],
+ "Big Mek": [],
+ "Big Mek in Mega Armour": [],
+ "Big Mek In Mega Armour": [
+ "Power Klaw"
+ ],
+ "Big Mek with Shokk Attack Gun": [
+ "Close Combat Weapon",
+ "Shokk Attack Gun"
+ ],
+ "Big'ed Bossbunka": [
+ "Gaze of Gork"
+ ],
+ "Blitza-Bommer": true,
+ "Boomdakka Snazzwagon": true,
+ "Boss Snikrot": true,
+ "Boyz": [],
+ "Breaka Boyz": [
+ "Choppa"
+ ],
+ "Burna Boyz": [
+ "Burna",
+ "Cuttin' Flames",
+ "Close Combat Weapon"
+ ],
+ "Burna-Bommer": [
+ "Twin Big Shoota",
+ "Twin Supa-Shoota",
+ "Armoured Hull"
+ ],
+ "Dakkajet": [
+ "Armoured Hull"
+ ],
+ "Deff Dread": [
+ "Stompy Feet"
+ ],
+ "Deffkilla Wartrike": true,
+ "Deffkoptas": [
+ "Slugga",
+ "Spinnin' Blades"
+ ],
+ "Flash Gitz": [
+ "Snazzgun",
+ "Choppa"
+ ],
+ "Gargantuan Squiggoth": [
+ "Huge Tusks"
+ ],
+ "Ghazghkull Thraka": true,
+ "Gorkanaut": true,
+ "Gretchin": true,
+ "Hunta Rig": true,
+ "Kill Rig": true,
+ "Killa Kans": [
+ "Kan Klaw"
+ ],
+ "Kommandos": [
+ "Bomb Squigs"
+ ],
+ "Kustom Boosta-Blasta": true,
+ "Lootas": [
+ "Close Combat Weapon",
+ "Deffgun"
+ ],
+ "Meganobz": [],
+ "Megatrakk Scrapjet": true,
+ "Mek": [
+ "Kustom-Mega Slugga"
+ ],
+ "Mek Gunz": [
+ "Grot Crew"
+ ],
+ "Morkanaut": true,
+ "Mozrog Skragbad": true,
+ "Nobz": [],
+ "Painboss": [
+ "Beast Snagga klaw"
+ ],
+ "Painboy": [
+ "Power Klaw",
+ "urty Syringe"
+ ],
+ "Rukkatrukk Squigbuggy": true,
+ "Shokkjump Dragsta": true,
+ "Squighog Boyz": [
+ "Saddlegit Weapons",
+ "Slugga",
+ "Stikka",
+ "Big Choppa",
+ "Squig Jaws",
+ "Bomb Squigs"
+ ],
+ "Stompa": true,
+ "Stormboyz": [
+ "Slugga"
+ ],
+ "Tankbustas": [
+ "Choppa",
+ "Close Combat Weapon"
+ ],
+ "Trukk": [
+ "Big Shoota",
+ "Spiked Wheels"
+ ],
+ "Warbikers": [
+ "Twin Dakkagun",
+ "Close Combat Weapon"
+ ],
+ "Warboss": [
+ "Kombi-weapon",
+ "Twin Slugga"
+ ],
+ "Warboss in Mega Armour": true,
+ "Wazbom Blastajet": [
+ "Smasha Gun",
+ "Armoured Hull"
+ ],
+ "Wazdakka Gutsmek": true,
+ "Weirdboy": true,
+ "Wurrboy": true,
+ "Zodgrod Wortsnagga": true
+ },
+ "Raven Guard": {
+ "Aethon Shaan": true,
+ "Kayvaan Shrike": true
+ },
+ "Salamanders": {
+ "Adrax Agatone": true,
+ "Vulkan He'stan": true
+ },
+ "Space Marines": {
+ "Aggressor Squad": [
+ "Twin Power Fists"
+ ],
+ "Ancient": [
+ "Bolt Pistol"
+ ],
+ "Ancient in Terminator Armour": [],
+ "Apothecary": true,
+ "Apothecary Biologis": true,
+ "Assault Intercessors with Jump Packs": [
+ "Heavy Bolt Pistol",
+ "Astartes Chainsword"
+ ],
+ "Astraeus": [
+ "Storm Bolter",
+ "Twin Macro-Accelerator Cannon",
+ "Armoured Hull"
+ ],
+ "Ballistus Dreadnought": true,
+ "Bladeguard Ancient": true,
+ "Bladeguard Veteran Squad": [
+ "Master-Crafted Power Weapon"
+ ],
+ "Brutalis Dreadnought": [
+ "Twin Icarus Ironhail Heavy Stubber"
+ ],
+ "Captain": [],
+ "Captain in Gravis Armour": [],
+ "Captain in Phobos Armour": true,
+ "Captain in Terminator Armour": [],
+ "Captain with Jump Pack": [],
+ "Centurion Assault Squad": [
+ "Siege Drills"
+ ],
+ "Centurion Devastator Squad": [
+ "Centurion Fists"
+ ],
+ "Chaplain": true,
+ "Chaplain in Terminator Armour": [
+ "Crozius Arcanum"
+ ],
+ "Chaplain Kastiel": true,
+ "Chaplain on Bike": true,
+ "Chaplain with Jump pack": [
+ "Crozius Arcanum"
+ ],
+ "Company Heroes": true,
+ "Desolation Squad": [
+ "Bolt Pistol",
+ "Castellan Launcher",
+ "Close Combat Weapon"
+ ],
+ "Devastator Squad": [
+ "Close Combat Weapon",
+ "Storm Bolter",
+ "Astartes Chainsword"
+ ],
+ "Dreadnought": [],
+ "Drop Pod": [],
+ "Eliminator Squad": [
+ "Bolt Pistol",
+ "Close Combat Weapon"
+ ],
+ "Eradicator Squad": [
+ "Bolt Pistol",
+ "Close Combat Weapon"
+ ],
+ "Firestrike Servo Turrets": [
+ "Close Combat Weapon"
+ ],
+ "Gladiator Lancer": [
+ "Lancer Laser Destroyer",
+ "Armoured Hull"
+ ],
+ "Gladiator Reaper": [
+ "Tempest Bolter",
+ "Twin Heavy Onslaught Gatling Cannon",
+ "Armoured Hull"
+ ],
+ "Gladiator Valiant": [
+ "Twin Las-Talon",
+ "Multi-melta",
+ "Armoured Hull"
+ ],
+ "Hammerfall Bunker": [
+ "Hammerfall Missile Launcher"
+ ],
+ "Heavy Intercessor Squad": [
+ "Bolt Pistol",
+ "Close Combat Weapon"
+ ],
+ "Hellblaster Squad": [
+ "Plasma Incinerator",
+ "Close Combat Weapon"
+ ],
+ "Impulsor": [
+ "Armoured Hull"
+ ],
+ "Inceptor Squad": [
+ "Close Combat Weapon"
+ ],
+ "Incursor Squad": [
+ "Bolt Pistol",
+ "Occulus Bolt Carbine",
+ "Paired Combat Blades"
+ ],
+ "Infernus Squad": true,
+ "Infiltrator Squad": [
+ "Bolt Pistol",
+ "Marksman Bolt carbine",
+ "Close Combat Weapon"
+ ],
+ "Intercessor Squad": [
+ "Bolt Pistol"
+ ],
+ "Invader ATV": [
+ "Bolt Pistol",
+ "Twin Bolt Rifle",
+ "Close Combat Weapon"
+ ],
+ "Invictor Tactical Warsuit": [
+ "Fragstorm Grenade Launcher",
+ "Heavy Bolter",
+ "Twin Ironhail Heavy Stubber",
+ "Invictor Fist"
+ ],
+ "Judiciar": true,
+ "Judiciar Xacharus": true,
+ "Land Raider": [
+ "Godhammer Lascannon",
+ "Twin Heavy Bolter",
+ "Armoured Tracks"
+ ],
+ "Land Raider Crusader": [
+ "Hurricane Bolter",
+ "Twin Assault Cannon",
+ "Armoured Tracks"
+ ],
+ "Land Raider Redeemer": [
+ "Flamestorm Cannon",
+ "Twin Assault Cannon",
+ "Armoured Tracks"
+ ],
+ "Librarian": true,
+ "Librarian in Phobos Armour": true,
+ "Librarian in Terminator Armour": [
+ "Force Weapon",
+ "Smite"
+ ],
+ "Lieutenant": [],
+ "Lieutenant in Phobos Armour": true,
+ "Lieutenant in Reiver Armour": true,
+ "Lieutenant with Combi-weapon": true,
+ "Outrider Squad": [
+ "Bolt Pistol",
+ "Twin Bolt Rifle",
+ "Close Combat Weapon",
+ "Heavy Bolt Pistol",
+ "Astartes Chainsword"
+ ],
+ "Predator Annihilator": [
+ "Predator Twin Lascannon",
+ "Armoured Tracks"
+ ],
+ "Predator Destructor": [
+ "Predator Autocannon",
+ "Armoured Tracks"
+ ],
+ "Razorback": [
+ "Armoured Tracks"
+ ],
+ "Redemptor Dreadnought": [
+ "Redemptor Fist"
+ ],
+ "Reiver Squad": [
+ "Special Issue Bolt Pistol"
+ ],
+ "Repulsor": [
+ "Hunter-Slayer Missile",
+ "Repulsor Defensive Array",
+ "Armoured Hull"
+ ],
+ "Repulsor Executioner": [
+ "Heavy Onslaught Gatling Cannon",
+ "Repulsor Executioner Defensive Array",
+ "Twin Heavy Bolter",
+ "Twin Icarus Ironhail Heavy Stubber",
+ "Armoured Hull"
+ ],
+ "Rhino": [
+ "Armoured Tracks",
+ "Storm Bolter"
+ ],
+ "Scout Squad": [
+ "Bolt Pistol",
+ "Close Combat Weapon"
+ ],
+ "Sternguard Veteran Squad": [
+ "Sternguard Bolt Pistol",
+ "Close Combat Weapon"
+ ],
+ "Storm Speeder Hailstrike": true,
+ "Storm Speeder Hammerstrike": true,
+ "Storm Speeder Thunderstrike": true,
+ "Stormhawk Interceptor": [
+ "Armoured Hull",
+ "Twin Assault Cannon"
+ ],
+ "Stormraven Gunship": [
+ "Stormstrike Missile Launcher",
+ "Armoured Hull"
+ ],
+ "Stormtalon Gunship": [
+ "Twin Assault Cannon",
+ "Armoured Hull"
+ ],
+ "Suppressor Squad": true,
+ "Tactical Squad": [
+ "Close Combat Weapon"
+ ],
+ "Techmarine": true,
+ "Terminator Assault Squad": [],
+ "Terminator Squad": [],
+ "Thunderhawk Gunship": [
+ "Lascannon",
+ "Twin Heavy Bolter",
+ "Armoured Hull"
+ ],
+ "Vanguard Veteran Squad": [
+ "Bolt Pistol",
+ "Vanguard Veteran Weapon"
+ ],
+ "Vanguard Veteran Squad with Jump Packs": [
+ "Bolt Pistol",
+ "Vanguard Veteran Weapon"
+ ],
+ "Vindicator": [
+ "Demolisher Cannon",
+ "Armoured Tracks"
+ ],
+ "Whirlwind": [
+ "Whirlwind Vengeance Launcher",
+ "Armoured Tracks"
+ ]
+ },
+ "Space Wolves": {
+ "Arjac Rockfist": true,
+ "Bjorn the Fell-Handed": [
+ "Heavy Flamer",
+ "Trueclaw"
+ ],
+ "Blood Claws": [],
+ "Fenrisian Wolves": true,
+ "Grey Hunters": [
+ "Bolt Pistol"
+ ],
+ "Iron Priest": true,
+ "Logan Grimnar": true,
+ "Murderfang": true,
+ "Njal Stormcaller": true,
+ "Ragnar Blackmane": true,
+ "Thunderwolf Cavalry": [
+ "Teeth and Claws",
+ "Wolf Guard Weapon"
+ ],
+ "Ulrik the Slayer": true,
+ "Venerable Dreadnought": [],
+ "Wolf Guard Battle Leader": [],
+ "Wolf Guard Headtakers": [
+ "Heavy Bolt Pistol",
+ "Teeth and Claws"
+ ],
+ "Wolf Guard Terminators": [
+ "Power Fist"
+ ],
+ "Wolf Priest": true,
+ "Wolf Scouts": [
+ "Power Weapon",
+ "Teeth and Claws"
+ ],
+ "Wulfen": [
+ "Wulfen Weapons"
+ ],
+ "Wulfen Dreadnought": [],
+ "Wulfen with Storm Shields": [
+ "Thunder Hammer"
+ ]
+ },
+ "T'au Empire": {
+ "AX-1-0 Tiger Shark": [
+ "Twin Heavy Rail Cannon",
+ "Armoured Hull",
+ "Missile Pod"
+ ],
+ "Breacher Team": [
+ "Pulse Blaster",
+ "Pulse Pistol",
+ "Support Turret",
+ "Close Combat Weapon"
+ ],
+ "Broadside Battlesuits": [
+ "Crushing Bulk"
+ ],
+ "Cadre Fireblade": [
+ "Fireblade Pulse Rifle",
+ "Close Combat Weapon"
+ ],
+ "Commander Farsight": true,
+ "Commander in Coldstar Battlesuit": [
+ "Battlesuit fists"
+ ],
+ "Commander in Enforcer Battlesuit": [
+ "Battlesuit fists"
+ ],
+ "Commander Shadowsun": true,
+ "Crisis Fireknife Battlesuits": [
+ "Battlesuit Fists"
+ ],
+ "Crisis Starscythe Battlesuits": [
+ "Battlesuit Fists"
+ ],
+ "Crisis Sunforge Battlesuits": [
+ "Fusion Blaster",
+ "Battlesuit Fists"
+ ],
+ "Darkstrider": true,
+ "Devilfish": [
+ "Accelerator Burst Cannon",
+ "Armoured Hull"
+ ],
+ "Ethereal": [
+ "Honour Stave"
+ ],
+ "Firesight Team": [
+ "Longshot Pulse Rifles",
+ "Pulse Pistol",
+ "Close Combat Weapons"
+ ],
+ "Ghostkeel Battlesuit": [
+ "Ghostkeel Fists"
+ ],
+ "Hammerhead Gunship": [
+ "Armoured Hull"
+ ],
+ "Kroot Carnivores": [
+ "Close Combat Weapon",
+ "Kroot Pistol",
+ "Kroot Pistol",
+ "Kroot Pistol",
+ "Kroot Pistol",
+ "Kroot Pistol",
+ "Kroot Pistol",
+ "Kroot Pistol"
+ ],
+ "Kroot Farstalkers": [
+ "Ritual Blade",
+ "Close Combat Weapon",
+ "Ripping Fangs",
+ "Kroot Pistol"
+ ],
+ "Kroot Flesh Shaper": true,
+ "Kroot Hounds": true,
+ "Kroot Lone Spear": [
+ "Kalamandra's Bite",
+ "Close Combat Weapon"
+ ],
+ "Kroot Lone-Spear": [
+ "Kalamandra's Bite",
+ "Close Combat Weapon"
+ ],
+ "Kroot Trail Shaper": true,
+ "Kroot War Shaper": [
+ "Kroot Pistol",
+ "Shaper's blade",
+ "Dart-bow and Tri-blade"
+ ],
+ "Krootox rampagers": true,
+ "Krootox Riders": [
+ "Close Combat Weapon",
+ "Krootox Fists"
+ ],
+ "Manta": [
+ "Heavy Rail Cannon",
+ "Ion Cannon",
+ "Long-barrelled Burst Cannon Array",
+ "Missile Pod",
+ "Seeker Missile",
+ "Armoured Hull"
+ ],
+ "Pathfinder Team": [
+ "Pulse Pistol",
+ "Close Combat Weapon",
+ "Drone burst cannon"
+ ],
+ "Piranha": [
+ "Twin Pulse Carbine",
+ "Armoured hull"
+ ],
+ "Piranhas": [
+ "Twin Pulse Carbine",
+ "Armoured Hull"
+ ],
+ "Razorshark Strike Fighter": [
+ "Quad Ion Turret",
+ "Armoured Hull",
+ "Seeker Missile"
+ ],
+ "Riptide Battlesuit": [
+ "Riptide Fists"
+ ],
+ "Sky Ray Gunship": [
+ "Seeker missile Rack",
+ "Armoured Hull"
+ ],
+ "Stealth Battlesuits": [
+ "Battlesuit Fists"
+ ],
+ "Stormsurge": [
+ "Cluster Rocket System",
+ "Destroyer Missiles",
+ "Thunderous Footfalls",
+ "Twin Smart Missile System"
+ ],
+ "Strike Team": [
+ "Close Combat Weapon",
+ "Support turret",
+ "Pulse Pistol"
+ ],
+ "Sun Shark Bomber": [
+ "Twin Ion Rifle",
+ "Armoured Hull",
+ "Seeker Missile"
+ ],
+ "Ta'unar Supremacy Armour": [
+ "Crushing Feet",
+ "Burst Cannon",
+ "Smart Missile System"
+ ],
+ "The Twin Lance": [
+ "Fusion Eliminator",
+ "Ion Scattercannon",
+ "Shardstorm Burst System",
+ "Twin Pulse Blaster",
+ "XV Pulse Pistol",
+ "MV15 Gun Drone"
+ ],
+ "Tidewall Droneport": [
+ "Drone Defenders"
+ ],
+ "Tidewall Gunrig": [
+ "Supremacy Railgun"
+ ],
+ "Tidewall Shieldline": [],
+ "Tiger Shark": [
+ "Armoured Hull",
+ "Missile Pod"
+ ],
+ "Vespid Stingwings": [
+ "Stingwing Claws"
+ ]
+ },
+ "Thousand Sons": {
+ "Ahriman": true,
+ "Blue Horrors": true,
+ "Chaos Land Raider": [
+ "Soulshatter Lascannon",
+ "Twin Inferno Heavy Bolter",
+ "Armoured Tracks"
+ ],
+ "Chaos Predator Annihilator": [
+ "Predator Twin Lascannon",
+ "Armoured Tracks"
+ ],
+ "Chaos Predator Destructor": [
+ "Predator Autocannon",
+ "Armoured Tracks"
+ ],
+ "Chaos Rhino": [
+ "Armoured Tracks"
+ ],
+ "Chaos Spawn": true,
+ "Chaos Vindicator": [
+ "Demolisher Cannon",
+ "Armoured Tracks"
+ ],
+ "Daemon Prince of Tzeentch": true,
+ "Daemon Prince of Tzeentch with Wings": true,
+ "Defiler": [
+ "Shearing Claws"
+ ],
+ "Exalted Sorcerer": [
+ "Inferno Bolt Pistol",
+ "Astral Blast",
+ "Force Weapon"
+ ],
+ "Exalted Sorcerer on Disc of Tzeentch": [
+ "Arcane Fire",
+ "Inferno Bolt Pistol",
+ "Force Weapon"
+ ],
+ "Flamers": true,
+ "Forgefiend": [],
+ "Helbrute": [
+ "Close Combat Weapon"
+ ],
+ "Heldrake": [
+ "Heldrake Claws"
+ ],
+ "Infernal Master": true,
+ "Kairos Fateweaver": true,
+ "Lord of Change": [
+ "Bolt of Change",
+ "Staff of Tzeentch"
+ ],
+ "Magnus the Red": true,
+ "Maulerfiend": [
+ "Maulerfiend Fists"
+ ],
+ "Mutalith Vortex Beast": true,
+ "Pink Horrors": [
+ "Coruscating Pink Flames",
+ "Coruscating Blue Flames",
+ "Coruscating Yellow Flames",
+ "Pink Claws",
+ "Blue Claws",
+ "Yellow Claws"
+ ],
+ "Rubric Marines": [
+ "Malefic Curse",
+ "Close Combat Weapon",
+ "Force Weapon"
+ ],
+ "Scarab Occult Terminators": [
+ "Malefic Curse",
+ "Force Weapon"
+ ],
+ "Screamers": true,
+ "Sekhetar Robots": [
+ "Heavy Warpflamer",
+ "Hellfyre Missile Rack",
+ "Close Combat Weapon"
+ ],
+ "Sorcerer": [
+ "Pandaemonic Delusion",
+ "Inferno Bolt Pistol",
+ "Force Weapon"
+ ],
+ "Sorcerer in Terminator Armour": [
+ "Gaze of Hate"
+ ],
+ "Sorcerer In Terminator Armour": [
+ "Force Weapon"
+ ],
+ "Tzaangor Enlightened": [],
+ "Tzaangor Enlightened with Fatecaster Greatbows": true,
+ "Tzaangor Shaman": true,
+ "Tzaangors": []
+ },
+ "Tyranids": {
+ "Barbgaunts": true,
+ "Biovores": true,
+ "Broodlord": true,
+ "Carnifexes": [
+ "Chitinous Claws and Teeth"
+ ],
+ "Deathleaper": true,
+ "Exocrine": true,
+ "Gargoyles": true,
+ "Genestealers": true,
+ "Harpy": [
+ "Stinger Salvoes",
+ "Scything Wings"
+ ],
+ "Harridan": [
+ "Dire Bio-cannon",
+ "Gargantuan Scything Talons"
+ ],
+ "Haruspex": true,
+ "Hierophant": [
+ "Bio-plasma Torrent",
+ "Dire Bio-cannon",
+ "Lashwhip Pods",
+ "Titanic Scything Talons"
+ ],
+ "Hive Crone": true,
+ "Hive Guard": [
+ "Chitinous Claws and Teeth"
+ ],
+ "Hive Tyrant": [],
+ "Hormagaunts": true,
+ "Hyperadapted Raveners": true,
+ "Lictor": true,
+ "Maleceptor": true,
+ "Mawloc": true,
+ "Mucolid Spores": [],
+ "Neurogaunts": true,
+ "Neurolictor": true,
+ "Neurotyrant": [
+ "Psychic Scream",
+ "Neurotyrant Claws and Lashes"
+ ],
+ "Norn Assimilator": true,
+ "Norn Emissary": true,
+ "Old One Eye": true,
+ "Parasite of Mortrex": true,
+ "Psychophage": true,
+ "Pyrovores": true,
+ "Raveners": [
+ "Ravener Claws and Talons"
+ ],
+ "Ripper Swarms": [
+ "Chitinous Claws and Teeth"
+ ],
+ "Screamer-Killer": true,
+ "Spore Mines": [],
+ "Sporocyst": true,
+ "Termagants": [
+ "Chitinous Claws and Teeth"
+ ],
+ "Tervigon": [
+ "Stinger Salvoes"
+ ],
+ "The Red Terror": [
+ "Gaping Maw",
+ "Scything Talons"
+ ],
+ "The Swarmlord": true,
+ "Toxicrene": true,
+ "Trygon": true,
+ "Tyranid Prime with Lash Whip": [
+ "Rending Claw",
+ "Lash Whip",
+ "Scything Talons"
+ ],
+ "Tyranid Warriors with Melee Bio-Weapons": true,
+ "Tyranid Warriors with Ranged Bio-weapons": [
+ "Tyranid Warrior claws and talons"
+ ],
+ "Tyrannocyte": true,
+ "Tyrannofex": [
+ "Stinger Salvoes",
+ "Powerful Limbs"
+ ],
+ "Tyrant Guard": [],
+ "Venomthropes": true,
+ "Von Ryan's Leapers": true,
+ "Winged Hive Tyrant": [
+ "Tyrant talons"
+ ],
+ "Winged Tyranid Prime": [
+ "Prime Talons"
+ ],
+ "Zoanthropes": true
+ },
+ "Ultramarines": {
+ "Captain Sicarius": true,
+ "Captain Titus": true,
+ "Cato Sicarius": true,
+ "Chief Librarian Tigurius": true,
+ "Lieutenant Titus": true,
+ "Marneus Calgar": true,
+ "Marneus Calgar in Armour of Antilochus": true,
+ "Roboute Guilliman": true,
+ "Uriel Ventris": true,
+ "Victrix Honour Guard": true,
+ "Wardens of Ultramar": true
+ },
+ "White Scars": {
+ "Kor'sarro Khan": true,
+ "Suboden Khan": true
+ },
+ "World Eaters": {
+ "Angron": true,
+ "Bloodcrushers": [
+ "Hellblade",
+ "Bladed Horn"
+ ],
+ "Bloodletters": [
+ "Hellblade"
+ ],
+ "Bloodthirster": [
+ "Hellfire Breath"
+ ],
+ "Chaos Land Raider": [
+ "Soulshatter Lascannon",
+ "Armoured Tracks",
+ "Twin Heavy Bolter"
+ ],
+ "Chaos Predator Annihilator": [
+ "Predator Twin Lascannon",
+ "Armoured Tracks"
+ ],
+ "Chaos Predator Destructor": [
+ "Predator Autocannon",
+ "Armoured Tracks"
+ ],
+ "Chaos Rhino": [
+ "Armoured Tracks"
+ ],
+ "Chaos Spawn": true,
+ "Daemon Prince": true,
+ "Daemon Prince of Khorne": true,
+ "Daemon Prince of Khorne with Wings": true,
+ "Defiler": [
+ "Shearing Claws"
+ ],
+ "Eightbound": true,
+ "Exalted Eightbound": true,
+ "Flesh Hounds": [
+ "Burning Roar",
+ "Gore-drenched Fangs",
+ "Collar of Khorne"
+ ],
+ "Goremongers": [
+ "Close Combat Weapon"
+ ],
+ "Helbrute": [
+ "Close Combat Weapon"
+ ],
+ "Heldrake": [
+ "Heldrake Claws"
+ ],
+ "Jakhals": [
+ "Autopistol"
+ ],
+ "Khârn The Betrayer": true,
+ "Khorne Berserkers": [
+ "Bolt Pistol",
+ "Khorne Berserker",
+ "Chainblade",
+ "Berserker Chainblade"
+ ],
+ "Khorne Berzerkers": [
+ "Bolt Pistol",
+ "Khorne Berzerker",
+ "Chainblade",
+ "Berzerker Chainblade",
+ "Close Combat Weapon"
+ ],
+ "Khorne Lord of Skulls": [
+ "Great Cleaver of Khorne"
+ ],
+ "Lord Invocatus": true,
+ "Lord on Juggernaut": true,
+ "Master of Executions": true,
+ "Maulerfiend": [
+ "Maulerfiend fists"
+ ],
+ "Skarbrand": true,
+ "Slaughterbound": true
+ }
+}