From 63d83b5e10c33e8f6a055ddb0547a5aa4866933d Mon Sep 17 00:00:00 2001 From: Egor Savkin Date: Wed, 6 Dec 2023 16:27:43 +0800 Subject: [PATCH] Add other warnings for the cards Signed-off-by: Egor Savkin --- README.md | 6 +- .../shop/{Warnings.jsx => CardWarnings.jsx} | 14 +- static/js/shop/OrderSummary.jsx | 9 +- static/js/shop/ProductCartItem.jsx | 4 +- static/js/shop/count_resources.js | 18 +- static/js/shop/warnings.js | 13 +- static/js/shop_data.js | 601 ++++++------------ 7 files changed, 241 insertions(+), 424 deletions(-) rename static/js/shop/{Warnings.jsx => CardWarnings.jsx} (69%) diff --git a/README.md b/README.md index c7ca6a72..a24c7472 100644 --- a/README.md +++ b/README.md @@ -18,8 +18,10 @@ Start: zola serve ``` -To update the .bundle.js and .jsx file: +To build the .bundle.js from .jsx files: ``` - nix-shell -p nodejs --run "npm run build" + nix-shell -p nodejs + npm install + npm run build ``` diff --git a/static/js/shop/Warnings.jsx b/static/js/shop/CardWarnings.jsx similarity index 69% rename from static/js/shop/Warnings.jsx rename to static/js/shop/CardWarnings.jsx index f3849f2b..8333a887 100644 --- a/static/js/shop/Warnings.jsx +++ b/static/js/shop/CardWarnings.jsx @@ -3,7 +3,7 @@ import React from "react"; import {MaxLevel} from "./warnings"; -export function Warnings({warnings}) { +export function CardWarnings({warnings, prefix}) { const max_level = MaxLevel(warnings); return ( {warnings.map((warning, _i) => { return ( -

+

{warning.message}

) @@ -26,4 +26,14 @@ export function Warnings({warnings}) {
) +} + +export function WarningIndicator({warnings}) { + const max_level = MaxLevel(warnings); + return ( + + ) } \ No newline at end of file diff --git a/static/js/shop/OrderSummary.jsx b/static/js/shop/OrderSummary.jsx index a3f0a4ba..68bb421b 100644 --- a/static/js/shop/OrderSummary.jsx +++ b/static/js/shop/OrderSummary.jsx @@ -2,6 +2,7 @@ import React, {PureComponent} from 'react'; import PropTypes from "prop-types"; import {SummaryPopup} from "./options/SummaryPopup.jsx"; import {formatMoney} from "./utils"; +import {WarningIndicator} from "./CardWarnings.jsx"; /** @@ -132,6 +133,7 @@ export class OrderSummary extends PureComponent { } options = itemsData[index] && itemsData[index].options; options_data = itemsData[index] && itemsData[index].options_data; + const warnings = itemsData[index] && itemsData[index].show_warnings; return (
- {(warning ? ( - + {(warnings && warnings.length > 0 ? ( + ) : ( {warnings && warnings.length > 0 && - () + () } {options && ( diff --git a/static/js/shop/count_resources.js b/static/js/shop/count_resources.js index f80bc0ab..e4f955db 100644 --- a/static/js/shop/count_resources.js +++ b/static/js/shop/count_resources.js @@ -4,7 +4,7 @@ const count_item_occupied_eem = (item) => { || item.options_data.ext_pwr === false || item.options_data.mono_eem === false ) - return item.slotOccupied; + return (item.consumes && item.consumes.eem) || 0; else if (item.options_data.ext_pwr === true) return 0; else if (item.options_data.mono_eem === true || item.options_data.n_eem === "1 EEM") @@ -12,29 +12,34 @@ const count_item_occupied_eem = (item) => { else if (item.options_data.n_eem === "3 EEM") return 3; - return item.slotOccupied || 0; + return (item.consumes && item.consumes.eem) || 0; } const count_item_occupied_clock = (item) => { - return (item.options_data && item.options_data.ext_clk === true) ? 0 : (item.clockOccupied || 0); + return (item.options_data && (item.options_data.ext_clk === true || (item.options_data.ext_clk && item.options_data.ext_clk.checked === true)) ) ? 0 : ((item.consumes && item.consumes.clk) || 0); } const count_item_occupied_idc = (item) => { - return item.idcOccupied || 0; + return (item.consumes && item.consumes.idc) || 0; +} + +const count_item_occupied_hp = (item) => { + return (item.consumes && item.consumes.hp) || 0; } export const item_occupied_counters = { "eem": count_item_occupied_eem, "clk": count_item_occupied_clock, "idc": count_item_occupied_idc, + "hp": count_item_occupied_hp, } function CounterFactory(name) { return (data, index) => { let count = 0; for (let i = index + 1; i < data.length; i++) { - if (data[i].resources && !!data[i].resources.find((value, _i) => value.name === name)) break; count += item_occupied_counters[name](data[i]); + if (data[i].resources && !!data[i].resources.find((value, _i) => value.name === name)) break; } return count; } @@ -43,7 +48,8 @@ function CounterFactory(name) { const resource_counters = { "eem": CounterFactory("eem"), "clk": CounterFactory("clk"), - "idc": CounterFactory("idc") + "idc": CounterFactory("idc"), + "hp": CounterFactory("hp"), } function CountResources(data, index) { diff --git a/static/js/shop/warnings.js b/static/js/shop/warnings.js index 907301f6..9a861570 100644 --- a/static/js/shop/warnings.js +++ b/static/js/shop/warnings.js @@ -51,10 +51,6 @@ const wiring_constraint = (name) => { } } -const crate_overload = (data, index, _counters) => { - // TODO -} - const Types = { "eem_resource": { level: "warning", @@ -91,11 +87,6 @@ const Types = { trigger: wiring_constraint("eem"), message: "Due to wiring constraints, the carrier can only connect to EEM cards immediately at its right, without crossing another carrier." }, - "crate_overload": { - level: "warning", - trigger: crate_overload, - message: 'This card needs either a card that provides a clock source (e.g. Kasli or Clocker) at its left or use an external clock source.' - }, "default": { level: "warning", trigger: (_a, _b, _c) => { @@ -112,9 +103,9 @@ export function TriggerWarnings(data) { element.show_warnings = element.warnings .map((warning, _) => { if (!!Types[warning]) - return Types[warning].trigger(data, index, element.counted_resources) ? {trigger: undefined, ...Types[warning]} : null; + return Types[warning].trigger(data, index, element.counted_resources) ? {trigger: undefined, name: warning, ...Types[warning]} : null; else - return Types.default.trigger(data, index, element.counted_resources); + return Types.default; }) .filter((warning, _) => { return !!warning diff --git a/static/js/shop_data.js b/static/js/shop_data.js index 92fbff23..5db2cdcc 100644 --- a/static/js/shop_data.js +++ b/static/js/shop_data.js @@ -56,14 +56,6 @@ const shop_data = { ], size: 'big', type: 'kasli', - hp: 8, - nbrSlotMin: 0, - nbrSlotMax: 12, - nbrCurrentSlot: 0, - nbrClockMax: 4, - nbrCurrentClock: 0, - slotOccupied: 1, - clockOccupied: 0, options: [ {type: "Radio", args: {title: "DRTIO role", outvar: "drtio_role", variants: ["standalone", "master", "satellite"], tip: "Distributed Real Time Input/Output allows ARTIQ RTIO channels to be distributed among several satellite devices synchronized and controlled by a central core(master) device. Standalone option disables this feature."}}, { @@ -92,14 +84,17 @@ const shop_data = { } ], resources: [ - {name: "eem", max: 5}, + {name: "eem", max: 12}, {name: "clk", max: 4}, ], warnings: [ "eem_resource", "clk_resource", "eem_wiring_constraint" - ] + ], + consumes: { + hp: 8 + } }, 'kaslisoc': { id: 'kaslisoc', @@ -156,38 +151,18 @@ const shop_data = { ] } ], - rules: { - maxSlot: { - type: 'kaslisoc-max-slot', - icon: '/shop/icon-reminder.svg', - name: 'Kasli-SoC', - message: 'Insufficient EEM connectors.', - }, - maxSlotWarning: { - type: 'kaslisoc-max-slot-warning', - icon: '/shop/icon-warning.svg', - name: 'Kasli-SoC', - message: 'Insufficient EEM connectors', - }, - maxClock: { - type: 'kaslisoc-max-clock', - icon: '/shop/icon-reminder.svg', - name: 'Kasli-SoC', - message: 'Insufficient clock connectors. Kasli-SoC has at most 4 clock connections.', - }, - maxClockWarning: { - type: 'kaslisoc-max-clock-warning', - icon: '/shop/icon-warning.svg', - name: 'Kasli-SoC', - message: 'Insufficient clock connectors.', - }, - follow: { - type: 'kaslisoc-follow', - icon: '/shop/icon-reminder.svg', - name: 'Kasli-SoC', - message: 'Due to wiring constraints, a Kasli-SoC can only connect to EEM cards immediately at its right, without crossing another carrier.', - }, - }, + resources: [ + {name: "eem", max: 12}, + {name: "clk", max: 4}, + ], + warnings: [ + "eem_resource", + "clk_resource", + "eem_wiring_constraint" + ], + consumes: { + hp: 8 + } }, 'vhdcicarrier': { id: 'vhdcicarrier', @@ -204,46 +179,17 @@ const shop_data = { ], size: 'big', type: 'vhdcicarrier', - hp: 8, - nbrSlotMin: 0, - nbrSlotMax: 8, - nbrCurrentSlot: 0, - nbrClockMax: 0, - nbrCurrentClock: 0, - slotOccupied: 1, - clockOccupied: 0, - rules: { - maxSlot: { - type: 'vhdcicarrier-max-slot', - icon: '/shop/icon-reminder.svg', - name: 'VHDCI carrier', - message: 'Insufficient EEM connectors.', - }, - maxSlotWarning: { - type: 'vhdcicarrier-max-slot-warning', - icon: '/shop/icon-warning.svg', - name: 'VHDCI carrier', - message: 'Insufficient EEM connectors', - }, - maxClock: { - type: 'vhdcicarrier-max-clock', - icon: '/shop/icon-reminder.svg', - name: 'VHDCI carrier', - message: 'The VHDCI carrier lacks clock connectors.', - }, - maxClockWarning: { - type: 'vhdcicarrier-max-clock-warning', - icon: '/shop/icon-warning.svg', - name: 'VHDCI carrier', - message: 'The VHDCI carrier lacks clock connectors.', - }, - follow: { - type: 'vhdcicarrier-follow', - icon: '/shop/icon-reminder.svg', - name: 'VHDCI carrier', - message: 'Due to wiring constraints, a VHDCI carrier can only connect to EEM cards immediately at its right, without crossing another carrier.', - }, - }, + resources: [ + {name: "eem", max: 8}, + ], + warnings: [ + "eem_resource", + "clk_resource", + "eem_wiring_constraint" + ], + consumes: { + hp: 8 + } }, 'bnc-dio': { id: 'bnc-dio', @@ -265,12 +211,6 @@ const shop_data = { datasheet_name: '2118/2128 BNC/SMA-TTL datasheet', size: 'big', type: null, - hp: 8, - nbrSlotMin: 0, - nbrSlotMax: 0, - nbrClockMax: 0, - slotOccupied: 1, - clockOccupied: 0, options: [ { "if": [ @@ -317,7 +257,11 @@ const shop_data = { ], warnings: [ "no_eem_source" - ] + ], + consumes: { + hp: 8, + eem: 1 + } }, 'sma-dio': { id: 'sma-dio', @@ -377,15 +321,13 @@ const shop_data = { ], size: 'small', type: null, - hp: 4, - nbrSlotMin: 0, - nbrSlotMax: 0, - nbrClockMax: 0, - slotOccupied: 1, - clockOccupied: 0, warnings: [ "no_eem_source" - ] + ], + consumes: { + hp: 4, + eem: 1 + } }, 'mcx-dio': { id: 'mcx-dio', @@ -471,20 +413,13 @@ const shop_data = { ], size: 'small', type: null, - hp: 4, - nbrSlotMin: 0, - nbrSlotMax: 0, - nbrClockMax: 0, - slotOccupied: 2, - clockOccupied: 0, - rules: { - resources: { - type: 'mcx-dio', - icon: '/shop/icon-warning.svg', - name: 'MCX-DIO', - message: 'This card needs a card that provides two EEM connectors (e.g. Kasli) at its left.', - }, - }, + warnings: [ + "no_eem_source" + ], + consumes: { + hp: 4, + eem: 2 + } }, 'rj45-dio': { id: 'rj45-dio', @@ -565,20 +500,13 @@ const shop_data = { ], size: 'small', type: null, - hp: 4, - nbrSlotMin: 0, - nbrSlotMax: 0, - nbrClockMax: 0, - slotOccupied: 2, - clockOccupied: 0, - rules: { - resources: { - type: 'rj45-dio', - icon: '/shop/icon-warning.svg', - name: 'RJ45-DIO', - message: 'This card needs a card that provides two EEM connectors (e.g. Kasli) at its left.', - }, - }, + warnings: [ + "no_eem_source" + ], + consumes: { + hp: 4, + eem: 2 + } }, 'urukul': { id: 'urukul', @@ -631,20 +559,15 @@ const shop_data = { ], size: 'small', type: 'urukul', - hp: 4, - nbrSlotMin: 0, - nbrSlotMax: 0, - nbrClockMax: 0, - slotOccupied: 2, - clockOccupied: 1, - rules: { - resources: { - type: 'urukul', - icon: '/shop/icon-warning.svg', - name: 'Urukul', - message: 'This card needs a card that provides EEM and clocking connectors (e.g. Kasli) at its left.', - }, - }, + warnings: [ + "no_eem_source", + "no_clk_source" + ], + consumes: { + hp: 4, + eem: 2, + clk: 1 + } }, 'urukul_4412': { id: 'urukul_4412', @@ -672,20 +595,15 @@ const shop_data = { ], size: 'small', type: 'urukul', - hp: 4, - nbrSlotMin: 0, - nbrSlotMax: 0, - nbrClockMax: 0, - slotOccupied: 2, - clockOccupied: 1, - rules: { - resources: { - type: 'urukul', - icon: '/shop/icon-warning.svg', - name: 'Urukul', - message: 'This card needs a card that provides EEM and clocking connectors (e.g. Kasli) at its left.', - }, - }, + warnings: [ + "no_eem_source", + "no_clk_source" + ], + consumes: { + hp: 4, + eem: 2, + clk: 1 + } }, 'phaser': { id: 'phaser', @@ -709,20 +627,15 @@ const shop_data = { ], size: 'small', type: 'urukul', - hp: 4, - nbrSlotMin: 0, - nbrSlotMax: 0, - nbrClockMax: 0, - slotOccupied: 1, - clockOccupied: 1, - rules: { - resources: { - type: 'phaser', - icon: '/shop/icon-warning.svg', - name: 'Phaser', - message: 'This card needs a card that provides EEM and clocking connectors (e.g. Kasli) at its left.', - }, - }, + warnings: [ + "no_eem_source", + "no_clk_source" + ], + consumes: { + hp: 4, + eem: 1, + clk: 1 + } }, 'zotino': { id: 'zotino', @@ -747,33 +660,17 @@ const shop_data = { datasheet_name: '5432 Zotino datasheet', size: 'small', type: 'zotino', - hp: 4, - nbrSlotMin: 0, - nbrSlotMax: 4, - nbrCurrentSlot: 0, - nbrClockMax: 0, - slotOccupied: 1, - clockOccupied: 0, - rules: { - maxSlot: { - type: 'zotino', - icon: '/shop/icon-reminder.svg', - name: 'Zotino', - message: 'Zotino has at most 4 IDC-BNC adapters.', - }, - maxSlotWarning: { - type: 'zotino-max-slot-warning', - icon: '/shop/icon-warning.svg', - name: 'Zotino', - message: 'Insufficient connectors.', - }, - resources: { - type: 'zotino', - icon: '/shop/icon-warning.svg', - name: 'Zotino', - message: 'This card needs a card that provides a EEM connector (e.g. Kasli) at its left.', - }, + warnings: [ + "no_eem_source", + "idc_resource" + ], + consumes: { + hp: 4, + eem: 1 }, + resources: [ + {name: "idc", max: 4} + ] }, 'fastino': { id: 'fastino', @@ -792,33 +689,17 @@ const shop_data = { ], size: 'small', type: 'zotino', - hp: 4, - nbrSlotMin: 0, - nbrSlotMax: 4, - nbrCurrentSlot: 0, - nbrClockMax: 0, - slotOccupied: 2, - clockOccupied: 0, - rules: { - maxSlot: { - type: 'fastino', - icon: '/shop/icon-reminder.svg', - name: 'Fastino', - message: 'Fastino has at most 4 IDC-BNC adapters.', - }, - maxSlotWarning: { - type: 'fastino-max-slot-warning', - icon: '/shop/icon-warning.svg', - name: 'Fastino', - message: 'Insufficient connectors.', - }, - resources: { - type: 'fastino', - icon: '/shop/icon-warning.svg', - name: 'Fastino', - message: 'This card needs a card that provides a EEM connector (e.g. Kasli) at its left.', - }, + warnings: [ + "no_eem_source", + "idc_resource", + ], + consumes: { + hp: 4, + eem: 1 }, + resources: [ + {name: "idc", max: 4} + ] }, 'idc-bnc-adapter': { id: 'idc-bnc-adapter', @@ -834,20 +715,13 @@ const shop_data = { ], size: 'big', type: 'idc-bnc', - hp: 8, - nbrSlotMin: 0, - nbrSlotMax: 0, - nbrClockMax: 0, - slotOccupied: 1, - clockOccupied: 0, - rules: { - wrong: { - type: 'idc-bnc', - icon: '/shop/icon-warning.svg', - name: 'IDC-BNC', - message: 'Should be after a Zotino or a HD68-IDC or with another IDC-BNC.', - } - }, + warnings: [ + "no_idc_source" + ], + consumes: { + hp: 8, + idc: 1 + } }, 'idc-sma-adapter': { id: 'idc-sma-adapter', @@ -863,20 +737,13 @@ const shop_data = { ], size: 'small', type: 'idc-bnc', - hp: 4, - nbrSlotMin: 0, - nbrSlotMax: 0, - nbrClockMax: 0, - slotOccupied: 1, - clockOccupied: 0, - rules: { - wrong: { - type: 'idc-sma', - icon: '/shop/icon-warning.svg', - name: 'SMA-IDC', - message: 'Should be after a Zotino or a HD68-IDC or with another SMA-IDC.', - } - }, + warnings: [ + "no_idc_source" + ], + consumes: { + hp: 4, + idc: 1 + } }, 'idc-mcx-adapter': { id: 'idc-mcx-adapter', @@ -892,20 +759,13 @@ const shop_data = { ], size: 'big', type: 'idc-bnc', - hp: 8, - nbrSlotMin: 0, - nbrSlotMax: 0, - nbrClockMax: 0, - slotOccupied: 1, - clockOccupied: 0, - rules: { - wrong: { - type: 'idc-mcx', - icon: '/shop/icon-warning.svg', - name: 'MCX-IDC', - message: 'Should be after a Zotino or a HD68-IDC or with another MCX-IDC.', - } - }, + warnings: [ + "no_idc_source" + ], + consumes: { + hp: 8, + idc: 1 + } }, 'hd68-idc-adapter': { id:'hd68-idc-adapter', @@ -919,37 +779,19 @@ const shop_data = { ], size: 'small', type: 'hd68', - hp: 4, options: [ {type: "Radio", args: {title: "Cable length", outvar: "cable_len", variants: ["1 M", "2 M", "3 M"], tip: "The desired length of the HD68 cable", fallback: 1}}, ], options_class: "hd68-idc", - nbrSlotMin: 1, - nbrSlotMax: 4, - nbrCurrentSlot: 0, - nbrClockMax: 0, - slotOccupied: 0, - clockOccupied: 0, - rules: { - minAdapter: { - type: 'hd68-min-adapter', - icon: '/shop/icon-warning.svg', - name: 'HD68-IDC', - message: 'Need at least one IDC-BNC Adapter at its right.', - }, - maxSlot: { - type: 'hd68-max-slot', - icon: '/shop/icon-reminder.svg', - name: 'HD68-IDC', - message: null, - }, - maxSlotWarning: { - type: 'hd68-max-slot-warning', - icon: '/shop/icon-warning.svg', - name: 'HD68-IDC', - message: 'Insufficient connectors.', - }, + warnings: [ + "idc_resource" + ], + consumes: { + hp: 4 }, + resources: [ + {name: "idc", max: 4} + ] }, 'novo': { id: 'novo', @@ -994,19 +836,12 @@ const shop_data = { ], size: 'big', type: 'novo', - hp: 8, - nbrSlotMin: 0, - nbrSlotMax: 0, - nbrClockMax: 0, - slotOccupied: 2, - clockOccupied: 0, - rules: { - resources: { - type: 'novo', - icon: '/shop/icon-warning.svg', - name: 'Sampler', - message: 'This card needs a card that provides EEM connectors (e.g. Kasli) at its left.', - }, + warnings: [ + "no_eem_source" + ], + consumes: { + hp: 8, + eem: 2 } }, 'koster': { @@ -1028,19 +863,12 @@ const shop_data = { ], size: 'small', type: 'koster', - hp: 4, - nbrSlotMin: 0, - nbrSlotMax: 0, - nbrClockMax: 0, - slotOccupied: 2, - clockOccupied: 0, - rules: { - resources: { - type: 'koster', - icon: '/shop/icon-warning.svg', - name: 'Grabber', - message: 'This card needs a card that provides EEM connectors (e.g. Kasli) at its left.', - }, + warnings: [ + "no_eem_source" + ], + consumes: { + hp: 4, + eem: 2 } }, 'clocker': { @@ -1064,26 +892,19 @@ const shop_data = { options_class: "clocker", size: 'small', type: 'clocker', - hp: 4, - nbrSlotMin: 0, - nbrSlotMax: 0, - nbrClockMax: 6, - slotOccupied: 1, - clockOccupied: 1, - rules: { - maxClock: { - type: 'clocker-max-clock', - icon: '/shop/icon-reminder.svg', - name: 'Clocker', - message: 'Clocker has at most 6 clock connections.', - }, - maxClockWarning: { - type: 'clocker-max-clock-warning', - icon: '/shop/icon-warning.svg', - name: 'Clocker', - message: 'Insufficient clock connectors.', - }, + warnings: [ + "no_eem_source", + "no_clk_source", + "clk_resource" + ], + consumes: { + hp: 4, + eem: 1, + clk: 1 }, + resources: [ + {name: "clk", max: 6} + ] }, 'stabilizer': { id: 'stabilizer', @@ -1109,12 +930,13 @@ const shop_data = { options_class: "stabilizer", size: 'small', type: null, - hp: 4, - nbrSlotMin: 0, - nbrSlotMax: 0, - nbrClockMax: 0, - slotOccupied: 1, - clockOccupied: 0, + warnings: [ + "no_eem_source" + ], + consumes: { + hp: 4, + eem: 1 + }, }, 'mirny': { id: 'mirny', @@ -1136,19 +958,14 @@ const shop_data = { ], size: 'small', type: null, - hp: 4, - nbrSlotMin: 0, - nbrSlotMax: 0, - nbrClockMax: 0, - slotOccupied: 1, - clockOccupied: 1, - rules: { - resources: { - type: 'mirny', - icon: '/shop/icon-warning.svg', - name: 'Mirny', - message: 'This card needs a card that provides a EEM connector (e.g. Kasli) at its left.', - }, + warnings: [ + "no_eem_source", + "no_clk_source" + ], + consumes: { + hp: 4, + eem: 1, + clk: 1 }, }, 'almazny': { @@ -1168,20 +985,15 @@ const shop_data = { ], size: 'big', type: null, - hp: 8, - nbrSlotMin: 0, - nbrSlotMax: 0, - nbrClockMax: 0, - slotOccupied: 1, - clockOccupied: 1, - rules: { - resources: { - type: 'almazny', - icon: '/shop/icon-warning.svg', - name: 'Almazny', - message: 'This card needs a card that provides a EEM connector (e.g. Kasli) at its left.', - }, - } + warnings: [ + "no_eem_source", + "no_clk_source" + ], + consumes: { + hp: 8, + eem: 1, + clk: 1 + }, }, 'thermostat-eem': { id: 'thermostat-eem', @@ -1203,12 +1015,13 @@ const shop_data = { ], size: 'small', type: null, - hp: 4, - nbrSlotMin: 0, - nbrSlotMax: 0, - nbrClockMax: 0, - slotOccupied: 1, - clockOccupied: 0 + warnings: [ + "no_eem_source" + ], + consumes: { + hp: 4, + eem: 1, + } }, 'shuttler': { id: 'shuttler', @@ -1227,20 +1040,15 @@ const shop_data = { ], size: 'big', type: null, - hp: 8, - nbrSlotMin: 0, - nbrSlotMax: 0, - nbrClockMax: 0, - slotOccupied: 1, - clockOccupied: 1, - rules: { - resources: { - type: 'shuttler', - icon: '/shop/icon-warning.svg', - name: 'Shuttler', - message: 'This card needs a card that provides a EEM connector (e.g. Kasli) at its left.', - }, - } + warnings: [ + "no_eem_source", + "no_clk_source" + ], + consumes: { + hp: 8, + eem: 1, + clk: 1 + }, }, 'pounder': { id: 'pounder', @@ -1263,12 +1071,15 @@ const shop_data = { ], size: 'big', type: null, - hp: 8, - nbrSlotMin: 0, - nbrSlotMax: 0, - nbrClockMax: 0, - slotOccupied: 1, - clockOccupied: 1, + warnings: [ + "no_eem_source", + "no_clk_source" + ], + consumes: { + hp: 4, + eem: 1, + clk: 1 + } }, 'eem_pwr_mod': { id: 'eem_pwr_mod', @@ -1290,12 +1101,10 @@ const shop_data = { ], size: 'big', type: null, - hp: 8, - nbrSlotMin: 0, - nbrSlotMax: 0, - nbrClockMax: 0, - slotOccupied: 0, - clockOccupied: 0, + warnings: [], + consumes: { + hp: 4, + }, }, },