"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.isProductOfTypeSmm = exports.getNumberOfEncoderPortsByProductId = exports.resolveProductId = exports.getEncoderPortName = exports.isInternalEncoderPortUsable = exports.isEncoderPortUsable = exports.isEncoderPortInternal = exports.somanetCirculoVariants = exports.usableCirculoEncoderPortProductIds = exports.ECDB_E1_IDS = exports.ECDL_IDS = exports.ECNN_IDS = exports.ECBN_IDS = exports.ECAN_IDS = exports.ECDN_E1_IDS = exports.isSomanetProductIdInRange = exports.isProductIdOfType = exports.findSomanetProductById = exports.findSomanetProductRangeByProductId = exports.somanetProductRanges = exports.somanetProducts = exports.somanetProductRangeNames = exports.productGroups = exports.productFamilies = exports.productCategories = void 0;
const hardware_description_1 = require("./hardware-description");
exports.productCategories = ['SOMANET', 'ACTILINK', 'OBLAC', 'MOTORCORTEX'];
exports.productFamilies = [
    'Node',
    'Circulo',
    'Integro',
    'Core',
    'ACTILINK-S Integro',
    'ACTILINK-JD',
    'ACTILINK-JD Duo',
];
exports.productGroups = [
    'Node 400',
    'Node 1000',
    'Node 2000',
    'Circulo 7',
    'Circulo 9',
    'Integro 60',
    'Integro 80',
    'ACTILINK-S Integro 60',
    'ACTILINK-S Integro 80',
    'ACTILINK-JD 8',
    'ACTILINK-JD 9',
    'ACTILINK-JD 10',
    'ACTILINK-JD 12',
    'ACTILINK-JD Duo 10',
    'ACTILINK-JD Duo 12',
];
exports.somanetProductRangeNames = [
    'Circulo',
    'Circulo Safe Motion',
    'Integro',
    'Node',
    'Node Safety',
    'ACTILINK-S',
    'ACTILINK-JD',
    'ACTILINK-JD Duo',
];
exports.somanetProducts = [
    { category: 'SOMANET', family: 'Node', group: 'Node 1000', id: 9500, name: 'Node 1000 EtherCAT' },
    { category: 'SOMANET', family: 'Node', group: 'Node 400', id: 9501, name: 'Node 400 EtherCAT' },
    { category: 'SOMANET', family: 'Node', group: 'Node 2000', id: 9502, name: 'Node 2000 EtherCAT' },
    { category: 'SOMANET', family: 'Node', group: 'Node 1000', id: 9506, name: 'Node 1000 CAN' },
    { category: 'SOMANET', family: 'Node', group: 'Node 400', id: 9507, name: 'Node 400 CAN' },
    { category: 'SOMANET', family: 'Node', group: 'Node 2000', id: 9508, name: 'Node 2000 CAN' },
    { category: 'SOMANET', family: 'Node', group: 'Node 1000', id: 9503, name: 'Node 1000 EtherNET' },
    { category: 'SOMANET', family: 'Node', group: 'Node 1000', id: 9600, name: 'Node Safety 1000 EtherCAT' },
    { category: 'SOMANET', family: 'Node', group: 'Node 400', id: 9601, name: 'Node Safety 400 EtherCAT' },
    { category: 'SOMANET', family: 'Node', group: 'Node 2000', id: 9602, name: 'Node Safety 2000 EtherCAT' },
    { category: 'SOMANET', family: 'Node', group: 'Node 1000', id: 9606, name: 'Node Safety 1000 CAN' },
    { category: 'SOMANET', family: 'Node', group: 'Node 400', id: 9607, name: 'Node Safety 400 CAN' },
    { category: 'SOMANET', family: 'Node', group: 'Node 2000', id: 9608, name: 'Node Safety 2000 CAN' },
    {
        category: 'SOMANET',
        family: 'Node',
        group: 'Node 1000',
        id: 9609,
        name: 'Node Safety 1000 EtherCAT',
    },
    {
        category: 'SOMANET',
        family: 'Node',
        group: 'Node 2000',
        id: 9611,
        name: 'Node Safety 2000 EtherCAT',
    },
    {
        category: 'SOMANET',
        family: 'Node',
        group: 'Node 1000',
        id: 9612,
        name: 'Node Safety 1000 CAN',
    },
    {
        category: 'SOMANET',
        family: 'Node',
        group: 'Node 2000',
        id: 9614,
        name: 'Node Safety 2000 CAN',
    },
    { category: 'SOMANET', family: 'Circulo', group: 'Circulo 7', id: 8500, mpns: ['ECNN'], name: 'Circulo 7 - 700' },
    { category: 'SOMANET', family: 'Circulo', group: 'Circulo 9', id: 8501, mpns: ['ECNN'], name: 'Circulo 9 - 1800' },
    {
        category: 'SOMANET',
        family: 'Circulo',
        group: 'Circulo 7',
        id: 8502,
        mpns: ['ECDN-E1'],
        name: 'Circulo 7 - 700, Magnetic Rings (pos.1&2), with port 2 transceivers',
    },
    {
        category: 'SOMANET',
        family: 'Circulo',
        group: 'Circulo 9',
        id: 8503,
        mpns: ['ECDN-E1'],
        name: 'Circulo 9 - 1800, Magnetic Rings (pos.1&2), with port 2 transceivers',
    },
    {
        category: 'SOMANET',
        family: 'Circulo',
        group: 'Circulo 7',
        id: 8504,
        mpns: ['ECAN'],
        name: 'Circulo 7 - 700, Magnetic Ring (pos.1)',
    },
    {
        category: 'SOMANET',
        family: 'Circulo',
        group: 'Circulo 9',
        id: 8505,
        mpns: ['ECAN'],
        name: 'Circulo 9 - 1800, Magnetic Ring (pos.1)',
    },
    {
        category: 'SOMANET',
        family: 'Circulo',
        group: 'Circulo 7',
        id: 8506,
        mpns: ['ECBN'],
        name: 'Circulo 7 - 700, Magnetic Ring (pos.2)',
    },
    {
        category: 'SOMANET',
        family: 'Circulo',
        group: 'Circulo 9',
        id: 8507,
        mpns: ['ECBN'],
        name: 'Circulo 9 - 1800, Magnetic Ring (pos.2)',
    },
    {
        category: 'SOMANET',
        family: 'Circulo',
        group: 'Circulo 7',
        id: 8508,
        mpns: ['ECDN-E2 (patched)', 'ECDB-E1'],
        name: 'Circulo 7 - 700, Magnetic Rings (pos.1&2), with port 2 transceivers, 3rd BiSS interface',
    },
    {
        category: 'SOMANET',
        family: 'Circulo',
        group: 'Circulo 9',
        id: 8509,
        mpns: ['ECDN-E2 (patched)', 'ECDB-E1'],
        name: 'Circulo 9 - 1800, Magnetic Rings (pos.1&2), with port 2 transceivers, 3rd BiSS interface',
    },
    {
        category: 'SOMANET',
        family: 'Circulo',
        group: 'Circulo 7',
        id: 8510,
        mpns: [],
        name: 'Circulo 7 - 700, Magnetic Rings (pos.1&2), with single brake',
    },
    {
        category: 'SOMANET',
        family: 'Circulo',
        group: 'Circulo 9',
        id: 8511,
        mpns: [],
        name: 'Circulo 9 - 1800, Magnetic Rings (pos.1&2), with single brake',
    },
    {
        category: 'SOMANET',
        family: 'Circulo',
        group: 'Circulo 7',
        id: 8512,
        mpns: ['ECDN', 'ECDL'],
        name: 'Circulo 7 - 700, Magnetic Rings (pos.1&2), no external encoders',
    },
    {
        category: 'SOMANET',
        family: 'Circulo',
        group: 'Circulo 9',
        id: 8513,
        mpns: ['ECDN', 'ECDL'],
        name: 'Circulo 9 - 1800, Magnetic Rings (pos.1&2), no external encoders',
    },
    {
        category: 'SOMANET',
        family: 'Circulo',
        group: 'Circulo 7',
        id: 8514,
        mpns: ['ECNN'],
        name: 'Circulo 7 32A - No internal encoder',
    },
    {
        category: 'SOMANET',
        family: 'Circulo',
        group: 'Circulo 7',
        id: 8516,
        mpns: ['ECDN-E1'],
        name: 'Circulo 7 - 32A, Magnetic Rings (pos.1&2), with port 2 transceivers',
    },
    {
        category: 'SOMANET',
        family: 'Circulo',
        group: 'Circulo 7',
        id: 8518,
        mpns: ['ECAN'],
        name: 'Circulo 7 - 32A, Magnetic Ring (pos.1) ',
    },
    {
        category: 'SOMANET',
        family: 'Circulo',
        group: 'Circulo 7',
        id: 8520,
        mpns: ['ECBN'],
        name: 'Circulo 7 - 32A, Magnetic Ring (pos.2) ',
    },
    {
        category: 'SOMANET',
        family: 'Circulo',
        group: 'Circulo 7',
        id: 8522,
        mpns: ['ECDB-E1'],
        name: 'Circulo 7 - 32A, Magnetic Rings (pos.1&2), with port 2 transceivers, 3rd BiSS interface',
    },
    {
        category: 'SOMANET',
        family: 'Circulo',
        group: 'Circulo 7',
        id: 8524,
        mpns: ['ECDL'],
        name: 'Circulo 7 - 32A, Magnetic Rings (pos.1&2), no external encoders',
    },
    {
        category: 'SOMANET',
        family: 'Circulo',
        group: 'Circulo 7',
        id: 8600,
        mpns: ['ECNNSM'],
        name: 'Circulo 7 Safe Motion - 700, Safe Motion',
    },
    {
        category: 'SOMANET',
        family: 'Circulo',
        group: 'Circulo 9',
        id: 8601,
        mpns: ['ECNNSM'],
        name: 'Circulo 9 Safe Motion - 1800, Safe Motion',
    },
    {
        category: 'SOMANET',
        family: 'Circulo',
        group: 'Circulo 7',
        id: 8602,
        mpns: ['ECDNSM-E1'],
        name: 'Circulo 7 Safe Motion - 700, Safe Motion, Magnetic Rings (pos.1&2), with port 2 transceivers',
    },
    {
        category: 'SOMANET',
        family: 'Circulo',
        group: 'Circulo 9',
        id: 8603,
        mpns: ['ECDNSM-E1'],
        name: 'Circulo 9 Safe Motion - 1800, Safe Motion, Magnetic Rings (pos.1&2), with port 2 transceivers',
    },
    {
        category: 'SOMANET',
        family: 'Circulo',
        group: 'Circulo 7',
        id: 8604,
        mpns: ['ECANSM'],
        name: 'Circulo 7 Safe Motion - 700, Safe Motion, Magnetic Ring (pos.1)',
    },
    {
        category: 'SOMANET',
        family: 'Circulo',
        group: 'Circulo 9',
        id: 8605,
        mpns: ['ECANSM'],
        name: 'Circulo 9 Safe Motion - 1800, Safe Motion, Magnetic Ring (pos.1)',
    },
    {
        category: 'SOMANET',
        family: 'Circulo',
        group: 'Circulo 7',
        id: 8606,
        mpns: ['ECBNSM'],
        name: 'Circulo 7 Safe Motion - 700, Magnetic Ring (pos.2)',
    },
    {
        category: 'SOMANET',
        family: 'Circulo',
        group: 'Circulo 9',
        id: 8607,
        mpns: ['ECBNSM'],
        name: 'Circulo 9 Safe Motion - 1800, Magnetic Ring (pos.2)',
    },
    {
        category: 'SOMANET',
        family: 'Circulo',
        group: 'Circulo 7',
        id: 8608,
        mpns: ['ECDBSM-E1'],
        name: 'Circulo 7 Safe Motion - 700, Magnetic Rings (pos.1&2), with port 2 transceivers, 3rd BiSS interface',
    },
    {
        category: 'SOMANET',
        family: 'Circulo',
        group: 'Circulo 9',
        id: 8609,
        mpns: ['ECDBSM-E1'],
        name: 'Circulo 9 Safe Motion - 1800, Magnetic Rings (pos.1&2), with port 2 transceivers, 3rd BiSS interface',
    },
    { category: 'SOMANET', family: 'Circulo', group: 'Circulo 7', id: 8610, mpns: [], name: '' },
    { category: 'SOMANET', family: 'Circulo', group: 'Circulo 9', id: 8611, mpns: [], name: '' },
    {
        category: 'SOMANET',
        family: 'Circulo',
        group: 'Circulo 7',
        id: 8612,
        mpns: ['ECDNSM', 'ECDLSM'],
        name: 'Circulo 7 Safe Motion - 700, Magnetic Rings (pos.1&2), no external encoders',
    },
    {
        category: 'SOMANET',
        family: 'Circulo',
        group: 'Circulo 9',
        id: 8613,
        mpns: ['ECDNSM', 'ECDLSM'],
        name: 'Circulo 9 Safe Motion - 1800, Magnetic Rings (pos.1&2), no external encoders',
    },
    {
        category: 'SOMANET',
        family: 'Circulo',
        group: 'Circulo 7',
        id: 8614,
        mpns: ['ECNNSM'],
        name: 'Circulo 7 Safe Motion - 32A - No internal encoder',
    },
    {
        category: 'SOMANET',
        family: 'Circulo',
        group: 'Circulo 7',
        id: 8616,
        mpns: ['ECDNSM-E1'],
        name: 'Circulo 7 Safe Motion - 32A, Magnetic Rings (pos.1&2), with port 2 transceivers',
    },
    {
        category: 'SOMANET',
        family: 'Circulo',
        group: 'Circulo 7',
        id: 8618,
        mpns: ['ECANSM'],
        name: 'Circulo 7 Safe Motion - 32A, Magnetic Ring (pos.1) ',
    },
    {
        category: 'SOMANET',
        family: 'Circulo',
        group: 'Circulo 7',
        id: 8620,
        mpns: ['ECBNSM'],
        name: 'Circulo 7 Safe Motion - 32A, Magnetic Ring (pos.2) ',
    },
    {
        category: 'SOMANET',
        family: 'Circulo',
        group: 'Circulo 7',
        id: 8622,
        mpns: ['ECDBSM-E1'],
        name: 'Circulo 7 Safe Motion - 32A, Magnetic Rings (pos.1&2), with port 2 transceivers, 3rd BiSS interface',
    },
    {
        category: 'SOMANET',
        family: 'Circulo',
        group: 'Circulo 7',
        id: 8624,
        mpns: ['ECDLSM'],
        name: 'Circulo 7 Safe Motion - 32A, Magnetic Rings (pos.1&2), no external encoders',
    },
    { category: 'SOMANET', family: 'Integro', group: 'Integro 60', id: 9000, name: 'Integro-60 R1.0' },
    { category: 'SOMANET', family: 'Integro', group: 'Integro 80', id: 9001, name: 'Integro-80 R1.0' },
    {
        category: 'SOMANET',
        family: 'Integro',
        group: 'Integro 60',
        id: 9002,
        name: 'Integro-60 R1.5 (600 W, EtherCAT, STO, 18 bit + MT + IOs)',
    },
    {
        category: 'SOMANET',
        family: 'Integro',
        group: 'Integro 80',
        id: 9003,
        name: 'Integro-80 R1.5 (1200 W, EtherCAT, STO, 18 bit + MT + IOs)',
    },
    {
        category: 'SOMANET',
        family: 'Integro',
        group: 'Integro 60',
        id: 9004,
        name: 'Integro 60 R1.6 and onwards, HW variant, multi-turn, all functionality',
    },
    {
        category: 'SOMANET',
        family: 'Integro',
        group: 'Integro 60',
        id: 9005,
        name: 'Integro 60 R1.6 and onwards, HW variant, single-turn,metric one M12, 2DI',
    },
    {
        category: 'SOMANET',
        family: 'Integro',
        group: 'Integro 60',
        id: 9006,
        name: 'Integro 60 metric low entry variant without late differentiation',
    },
    {
        category: 'SOMANET',
        family: 'Integro',
        group: 'Integro 80',
        id: 9007,
        name: 'Integro 80 R1.6 and onwards, HW variant, multi-turn, all functionality',
    },
    {
        category: 'SOMANET',
        family: 'Integro',
        group: 'Integro 80',
        id: 9008,
        name: 'Integro 80 R1.6 and onwards, HW variant, single-turn,metric one M12, 2DI',
    },
    {
        category: 'SOMANET',
        family: 'Integro',
        group: 'Integro 60',
        id: 9009,
        name: 'Integro 60 HW variant, multi-turn, metric, all GPIO',
    },
    {
        category: 'SOMANET',
        family: 'Integro',
        group: 'Integro 60',
        id: 9010,
        name: 'Integro 60 HW variant, single-turn, metric one M12, 2DI',
    },
    {
        category: 'SOMANET',
        family: 'Integro',
        group: 'Integro 80',
        id: 9011,
        name: 'Integro 80 HW variant, multi-turn, metric, all GPIO',
    },
    {
        category: 'SOMANET',
        family: 'Integro',
        group: 'Integro 80',
        id: 9012,
        name: 'Integro 80 HW variant, single-turn, metric one M12, 2DI',
    },
    {
        category: 'ACTILINK',
        family: 'ACTILINK-S Integro',
        group: 'ACTILINK-S Integro 60',
        id: 6000,
        name: 'ACTILINK-S C-Line 60mm',
    },
    {
        category: 'ACTILINK',
        family: 'ACTILINK-S Integro',
        group: 'ACTILINK-S Integro 80',
        id: 6001,
        name: 'ACTILINK-S C-Line 80mm',
    },
    {
        category: 'ACTILINK',
        family: 'ACTILINK-JD',
        group: 'ACTILINK-JD 8',
        id: 6400,
        name: 'ACTILINK-JD 8, standard config, STO/SBC',
    },
    {
        category: 'ACTILINK',
        family: 'ACTILINK-JD',
        group: 'ACTILINK-JD 8',
        id: 6401,
        name: 'ACTILINK-JD 8, standard config, SMM',
    },
    {
        category: 'ACTILINK',
        family: 'ACTILINK-JD',
        group: 'ACTILINK-JD 9',
        id: 6402,
        name: 'ACTILINK-JD 9, standard config, STO/SBC',
    },
    {
        category: 'ACTILINK',
        family: 'ACTILINK-JD',
        group: 'ACTILINK-JD 9',
        id: 6403,
        name: 'ACTILINK-JD 9, standard config, SMM',
    },
    {
        category: 'ACTILINK',
        family: 'ACTILINK-JD',
        group: 'ACTILINK-JD 10',
        id: 6404,
        name: 'ACTILINK-JD 10, standard config, STO/SBC',
    },
    {
        category: 'ACTILINK',
        family: 'ACTILINK-JD',
        group: 'ACTILINK-JD 10',
        id: 6405,
        name: 'ACTILINK-JD 10, standard config, SMM',
    },
    {
        category: 'ACTILINK',
        family: 'ACTILINK-JD',
        group: 'ACTILINK-JD 12',
        id: 6406,
        name: 'ACTILINK-JD 12, standard config, STO/SBC',
    },
    {
        category: 'ACTILINK',
        family: 'ACTILINK-JD',
        group: 'ACTILINK-JD 12',
        id: 6407,
        name: 'ACTILINK-JD 12, standard config, SMM',
    },
    {
        category: 'ACTILINK',
        family: 'ACTILINK-JD Duo',
        group: 'ACTILINK-JD Duo 10',
        id: 6504,
        name: 'ACTILINK-JD Duo 10, STO/SBC',
    },
    {
        category: 'ACTILINK',
        family: 'ACTILINK-JD Duo',
        group: 'ACTILINK-JD Duo 10',
        id: 6505,
        name: 'ACTILINK-JD Duo 10, SMM',
    },
    {
        category: 'ACTILINK',
        family: 'ACTILINK-JD Duo',
        group: 'ACTILINK-JD Duo 12',
        id: 6506,
        name: 'ACTILINK-JD Duo 12, STO/SBC',
    },
    {
        category: 'ACTILINK',
        family: 'ACTILINK-JD Duo',
        group: 'ACTILINK-JD Duo 12',
        id: 6507,
        name: 'ACTILINK-JD Duo 12, SMM',
    },
];
/**
 * List of all defined SOMANET product ranges with their corresponding firmware ID bounds.
 *
 * Each entry maps a `SomanetProductRangeName` to a numeric range that represents
 * the inclusive firmware IDs associated with that product range.
 *
 * These ranges are used for:
 * - Validating firmware IDs for a given product.
 * - Filtering or grouping products by range.
 * - Mapping devices to their logical product ranges in the UI or API.
 */
exports.somanetProductRanges = [
    { name: 'Node', bounds: [9500, 9599] },
    { name: 'Node Safety', bounds: [9600, 9998] },
    { name: 'Circulo', bounds: [8500, 8599] },
    { name: 'Circulo Safe Motion', bounds: [8600, 8699] },
    { name: 'Integro', bounds: [9000, 9099] },
    { name: 'ACTILINK-S', bounds: [6000, 6099] },
    { name: 'ACTILINK-JD', bounds: [6400, 6499] },
    { name: 'ACTILINK-JD Duo', bounds: [6500, 6599] },
];
/**
 * Finds the Somanet product range corresponding to a given product ID.
 *
 * The function resolves the product ID (number, string, or `HardwareDescription`)
 * to a numeric ID, and then searches through `somanetProductRanges` to find
 * the range whose bounds include the ID.
 *
 * @param productId - The product identifier to look up. Can be:
 *   - A numeric product ID
 *   - A string representation of the ID
 *   - A `HardwareDescription` object
 *   - `null` or `undefined`, in which case the function returns `undefined`
 *
 * @returns The `SomanetProductRange` whose bounds contain the resolved ID,
 *   or `undefined` if no matching range is found or the input is invalid.
 */
function findSomanetProductRangeByProductId(productId) {
    const id = resolveProductId(productId);
    if (!id) {
        return;
    }
    return exports.somanetProductRanges.find(({ bounds }) => id >= bounds[0] && id <= bounds[1]);
}
exports.findSomanetProductRangeByProductId = findSomanetProductRangeByProductId;
/**
 * Finds a SOMANET product by its product ID.
 *
 * This function resolves the input `productId` (number, string, or `HardwareDescription`)
 * to a numeric ID and searches the `somanetProducts` array for a product with a matching ID.
 *
 * @param productId - The product identifier to look up. Can be:
 *   - A numeric product ID
 *   - A string representing the product ID
 *   - A `HardwareDescription` object
 *   - `null` or `undefined`, in which case the function returns `undefined`
 *
 * @returns The matching `SomanetProduct` object if found, or `undefined` if no match exists
 *   or if the input is invalid.
 */
function findSomanetProductById(productId) {
    const id = resolveProductId(productId);
    return exports.somanetProducts.find((somanetProduct) => somanetProduct.id === id);
}
exports.findSomanetProductById = findSomanetProductById;
/**
 * @deprecated use isSomanetProductIdInRange instead
 */
function isProductIdOfType(productId, type) {
    return isSomanetProductIdInRange(productId, type);
}
exports.isProductIdOfType = isProductIdOfType;
/**
 * Checks whether a given product ID belongs to a specified SOMANET product range.
 *
 * This function resolves the `productId` to a numeric ID, determines the corresponding
 * `SomanetProductRange`, and checks if it matches the provided `rangeName`.
 *
 * Special aggregate ranges (`Circulo All` and `Node All`) are supported:
 * - `"Circulo All"` includes: `"Circulo"`, `"Circulo Safe Motion"`, `"ACTILINK-JD"`, `"ACTILINK-JD Duo"`
 * - `"Node All"` includes: `"Node"`, `"Node Safety"`
 *
 * @param productId - The product identifier to check. Can be:
 *   - A numeric product ID
 *   - A string representing the product ID
 *   - A `HardwareDescription` object
 *   - `null` or `undefined`, in which case the function returns `false`
 *
 * @param rangeName - The product range to check against. Can be any `SomanetProductRangeName`
 *   or the aggregate values `"Circulo All"` / `"Node All"`.
 *
 * @returns `true` if the product belongs to the specified range; otherwise, `false`.
 */
function isSomanetProductIdInRange(productId, rangeName) {
    const productRange = findSomanetProductRangeByProductId(productId);
    if (!productRange) {
        return false;
    }
    if (rangeName === 'Circulo All') {
        return (productRange.name === 'Circulo' ||
            productRange.name === 'Circulo Safe Motion' ||
            productRange.name === 'ACTILINK-JD' ||
            productRange.name === 'ACTILINK-JD Duo');
    }
    else if (rangeName === 'Node All') {
        return productRange.name === 'Node' || productRange.name === 'Node Safety';
    }
    else {
        return productRange.name === rangeName;
    }
}
exports.isSomanetProductIdInRange = isSomanetProductIdInRange;
exports.ECDN_E1_IDS = [8502, 8503, 8602, 8603, 8516, 8616];
exports.ECAN_IDS = [8504, 8505, 8604, 8605, 8518, 8618];
exports.ECBN_IDS = [8506, 8507, 8606, 8607, 8520, 8620];
exports.ECNN_IDS = [8500, 8501, 8600, 8601, 8514, 8614];
exports.ECDL_IDS = [8512, 8513, 8612, 8613, 8524, 8624];
exports.ECDB_E1_IDS = [8508, 8509, 8608, 8609, 8522, 8622];
exports.usableCirculoEncoderPortProductIds = [
    [...exports.ECDN_E1_IDS, ...exports.ECAN_IDS, ...exports.ECDL_IDS, ...exports.ECDB_E1_IDS],
    [...exports.ECDN_E1_IDS, ...exports.ECBN_IDS, ...exports.ECDL_IDS, ...exports.ECDB_E1_IDS],
    [...exports.ECDN_E1_IDS, ...exports.ECBN_IDS, ...exports.ECNN_IDS, ...exports.ECDB_E1_IDS],
    [...exports.ECDN_E1_IDS, ...exports.ECAN_IDS, ...exports.ECNN_IDS, ...exports.ECDB_E1_IDS], // External 2
];
exports.somanetCirculoVariants = [
    { id: 'ECDN_E1', productIds: exports.ECDN_E1_IDS },
    { id: 'ECAN', productIds: exports.ECAN_IDS },
    { id: 'ECBN', productIds: exports.ECBN_IDS },
    { id: 'ECNN', productIds: exports.ECNN_IDS },
    { id: 'ECDL', productIds: exports.ECDL_IDS },
    { id: 'ECDB_E1', productIds: exports.ECDB_E1_IDS },
];
/**
 * Determines whether a given encoder port on a device is an internal port
 * based on the product type and port number.
 *
 * The function checks:
 * - If the product belongs to specific Somanet ranges (`Integro` or `ACTILINK-S`) and the port is 1.
 * - If the product ID matches known Circulo variants for specific ports (ECAN, ECBN, ECDN_E1, ECDL, ECDB_E1).
 * - Special case product IDs (8510, 8511, 8610, 8611) on ports 1 or 2.
 *
 * @param port - The encoder port number (1-based index).
 * @param productId - Optional product identifier. Can be a number, string, `HardwareDescription`, or `null`.
 *                    If omitted, the function returns `false`.
 * @returns `true` if the specified port is considered internal for the given product, otherwise `false`.
 */
function isEncoderPortInternal(port, productId) {
    const id = resolveProductId(productId);
    if (isSomanetProductIdInRange(id, 'Integro') && port === 1) {
        return true;
    }
    if (isSomanetProductIdInRange(id, 'ACTILINK-S') && port === 1) {
        return true;
    }
    if (id) {
        if (port === 1 && exports.ECAN_IDS.includes(id)) {
            return true;
        }
        if (port === 2 && exports.ECBN_IDS.includes(id)) {
            return true;
        }
        if (0 < port && port < 3 && [...exports.ECDN_E1_IDS, ...exports.ECDB_E1_IDS, ...exports.ECDL_IDS, 8510, 8511, 8610, 8611].includes(id)) {
            return true;
        }
    }
    return false;
}
exports.isEncoderPortInternal = isEncoderPortInternal;
/**
 * Determines whether a specific encoder port on a device is usable for a given product.
 *
 * The function checks:
 * - If no product ID is provided or resolved, the port is considered usable (`true`).
 * - For products in the SOMANET Circulo family (`Circulo All`):
 *   - Port 5 is always usable as a Digital I/O port.
 *   - Ports 1–4 are checked against the known usable product IDs for each internal/external port.
 *   - If a Circulo product ID is unrecognized, the port is considered usable by default.
 *
 * @param port - The encoder port number (1-based index).
 * @param productId - Optional product identifier. Can be a number, string, `HardwareDescription`, or `null`.
 *                    If omitted, the function assumes the port is usable.
 * @returns `true` if the port is usable for the specified product, otherwise `false`.
 */
function isEncoderPortUsable(port, productId) {
    const id = resolveProductId(productId);
    if (!id) {
        return true;
    }
    if (isSomanetProductIdInRange(id, 'Circulo All')) {
        if (port === 5) {
            // Digital I/O
            return true;
        }
        else if (0 < port && port < 5) {
            if (exports.usableCirculoEncoderPortProductIds.flat().find((value) => value === id)) {
                return exports.usableCirculoEncoderPortProductIds[port - 1].includes(id);
            }
            else {
                return true; // Case when Circulo product ID is unrecognized
            }
        }
    }
    return true;
}
exports.isEncoderPortUsable = isEncoderPortUsable;
/**
 * Determines whether a given internal encoder port is usable for a specific product.
 *
 * Checks:
 * - Circulo products: ports 1 and 2 are considered internal and checked via `isEncoderPortUsable`.
 * - Integro products: port 1 is always usable.
 *
 * @param port - The encoder port number (1-based index).
 * @param productId - Optional product identifier (number, string, or `HardwareDescription`).
 * @returns `true` if the port is an internal port and usable, otherwise `false`.
 */
function isInternalEncoderPortUsable(port, productId) {
    if (isSomanetProductIdInRange(productId, 'Circulo All') && (port === 1 || port === 2)) {
        return isEncoderPortUsable(port, productId);
    }
    else if (isSomanetProductIdInRange(productId, 'Integro') && port === 1) {
        return true;
    }
    return false;
}
exports.isInternalEncoderPortUsable = isInternalEncoderPortUsable;
/**
 * Returns a human-readable name for an encoder port for a given product.
 *
 * Circulo products:
 * - Ports 1–2 → "Integrated encoder 1/2"
 * - Ports 3–4 → "External encoder 1/2"
 * - Port 5 → "Digital I/O"
 *
 * Other products: returns `"Port X"`.
 *
 * @param port - The encoder port number (1-based index).
 * @param productId - Optional product identifier (number, string, or `HardwareDescription`).
 * @returns The display name for the encoder port.
 */
function getEncoderPortName(port, productId) {
    if (isSomanetProductIdInRange(productId, 'Circulo All')) {
        if (port === 1 || port === 2) {
            return `Integrated encoder ${port}`;
        }
        else if (port === 3 || port === 4) {
            return `External encoder ${port - 2}`;
        }
        else if (port === 5) {
            return 'Digital I/O';
        }
    }
    return `Port ${port}`;
}
exports.getEncoderPortName = getEncoderPortName;
/**
 * Resolves a product ID from different possible representations.
 *
 * Supports:
 * - Numbers → returned as-is
 * - Strings → serial number format or 4-digit product ID
 * - `HardwareDescription` objects → uses `getIdFromHardwareDescription`
 *
 * @param value - The value to resolve into a numeric product ID.
 * @returns The numeric product ID, or `undefined` if it cannot be resolved.
 */
function resolveProductId(value) {
    if (value === undefined || value === null) {
        return;
    }
    if (typeof value === 'number') {
        return value;
    }
    if (typeof value === 'string' && (hardware_description_1.synapticonSerialNumberRegExp.test(value) || /^\d{4}$/.test(value))) {
        return Number(value.slice(0, 4));
    }
    if (typeof value === 'object') {
        return Number((0, hardware_description_1.getIdFromHardwareDescription)(value));
    }
    return;
}
exports.resolveProductId = resolveProductId;
/**
 * Returns the number of encoder ports available for a given product.
 *
 * Mapping of product families to encoder ports:
 * - **Circulo All** → 5 ports
 * - **Integro** → 2 ports
 * - **Node All** → 3 ports
 * - **ACTILINK-S** → 2 ports
 * - **Others** → 5 ports (fallback for unrecognized products)
 *
 * @param productId - Optional product identifier. Can be a number, string, or `HardwareDescription`.
 * @returns The number of encoder ports for the specified product.
 */
function getNumberOfEncoderPortsByProductId(productId) {
    if (isSomanetProductIdInRange(productId, 'Circulo All')) {
        return 5;
    }
    else if (isSomanetProductIdInRange(productId, 'Integro')) {
        return 2;
    }
    else if (isSomanetProductIdInRange(productId, 'Node All')) {
        return 3;
    }
    else if (isSomanetProductIdInRange(productId, 'ACTILINK-S')) {
        return 2;
    }
    else {
        return 5; // Default fallback for unrecognized products
    }
}
exports.getNumberOfEncoderPortsByProductId = getNumberOfEncoderPortsByProductId;
/**
 * Determines whether a given product is a Safe Motion Module (SMM) type
 * based on its product ID.
 *
 * @param value - The product identifier, which can be a numeric ID,
 * a string, a {@link HardwareDescription} object, or null/undefined.
 * @returns `true` if the product is identified as an SMM type; otherwise, `false`.
 * @remarks
 * The identification logic follows these hardware rules:
 * - **Circulo 7 / Circulo 9:** IDs in the range [8600, 8699] are always SMM.
 * - **ACTILINK-JD:** IDs in the range [6400, 6599] are SMM only if the ID is odd.
 * - All other IDs (or unresolved values) are considered non-SMM.
 */
function isProductOfTypeSmm(value) {
    const id = resolveProductId(value);
    if (id === null || id === undefined) {
        return false;
    }
    // Range for Circulo 7 or Circulo 9 Safe Motion products
    if (id >= 8600 && id <= 8699) {
        return true;
    }
    // Range for ACTILINK-JD (SMM products have odd IDs)
    if (id >= 6400 && id <= 6599) {
        return id % 2 !== 0; // Odd IDs are SMM products
    }
    return false;
}
exports.isProductOfTypeSmm = isProductOfTypeSmm;
//# sourceMappingURL=product.js.map