"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getErrNodeId = exports.isExternalLinkId = exports.isMetaLinkId = exports.isDatumLinkId = exports.isPinLinkId = exports.isLinkId = exports.getUnitIdFromNodeId = exports.isPinId = exports.isUnitNodeId = exports.isOutputPinId = exports.isInternalNodeId = exports.isNodeId = exports.getPinLinkIdFromPinNodeId = exports.getPinLinkId = exports.getLinkId = exports.getSelfPinNodeId = exports.getOutputNodeId = exports.getInputNodeId = exports.getPinNodeId__ = exports.getPinNodeId_ = exports.getPinNodeId = exports.getPinIdClass = exports.getIdFromDatumNodeId = exports.getPinIdFromLinkPinNodeId = exports.getTypeFromLinkPinNodeId = exports.getDatumNodeIdFromDatumLinkId = exports.linkRegex = exports.internalRegex = exports.externalRegex = exports.mergeRegex = exports.metadataRegex = exports.dataRegex = exports.outputIdRegex = exports.inputIdRegex = exports.pinIdRegex = exports.unitIdRegex = exports.nodeIdRegex = exports.idRegex = exports.ERR = exports.INTERNAL = exports.EXTERNAL = exports.TYPE = exports.DATA = exports.MERGE = exports.O = exports.I = exports.OUTPUT = exports.INPUT = exports.LINK_SEPARATOR = exports.SEPARATOR = void 0;
exports.kebabCase = exports.camelToDashed = exports.camelToSnake = exports.camelToKebab = exports.kebabToCamel = exports.numberOrDefault = exports.isBaseSpec = exports.isBaseSpecId = exports.harmonicArray = exports.rangeArray = exports.segmentInternalNodeId = exports.segmentPlugNodeId = exports.isExternalNodeId = exports.getIntNodeId = exports.getIntNodeIdFromExtNodeId = exports.getExtNodeIdFromIntNodeId = exports.getExtNodeId = exports.getIdFromMergeNodeId = exports.segmentMergeNodeId = exports.isMergeNodeId = exports.getMergeNodeId = exports.segmentMetadataId = exports.isMetadataNodeId = exports.getTypeNodeId = exports.getMetadataNodeId = exports.segmentDatumNodeId = exports.isDatumNodeId = exports.getDatumNodeId = exports.sameUnit = exports.getSelectionId = exports.segmentCount = exports.isErrPinId = exports.isLinkPinNodeId = exports.isPinNodeId = exports.isInputPinId = exports.getUnitIdFromPinLinkId = exports.getPinNodeIdFromPinLinkId = exports.segmentExternalLinkId = exports.segmentMetaLinkId = exports.segmentDatumLinkId = exports.segmentPinLinkId = exports.segmentLinkId = exports.segmentLinkPinNodeId = exports.segmentErrNodeId = void 0;
const SELF_1 = require("../../constant/SELF");
const string_1 = require("../../util/string");
exports.SEPARATOR = '/';
exports.LINK_SEPARATOR = '_';
exports.INPUT = 'input';
exports.OUTPUT = 'output';
exports.I = 'i';
exports.O = 'o';
exports.MERGE = '@';
exports.DATA = '#';
exports.TYPE = '$';
exports.EXTERNAL = '%';
exports.INTERNAL = '^';
exports.ERR = '!';
const UNIT_ID_REGEX = `[^${exports.SEPARATOR}${exports.MERGE}${exports.DATA}${exports.TYPE}${exports.EXTERNAL}${exports.INTERNAL}]+`;
const PIN_ID_REGEX = `[^]+`;
const UNIT_NODE_ID_REGEX = `^(${UNIT_ID_REGEX})$`;
const PIN_NODE_ID_REGEX = `^(${UNIT_ID_REGEX})/(input|output)/(${PIN_ID_REGEX})$`;
const NODE_ID_REGEX = `((${UNIT_ID_REGEX})|(${UNIT_ID_REGEX})/(input|output)/(${PIN_ID_REGEX})|(${exports.MERGE}/${UNIT_ID_REGEX}))`;
const INPUT_NODE_ID_REGEX = `^(${UNIT_ID_REGEX})/input/(${PIN_ID_REGEX})$`;
const OUTPUT_NODE_ID_REGEX = `^(${UNIT_ID_REGEX})/output/(${PIN_ID_REGEX})$`;
exports.idRegex = new RegExp(`^${UNIT_ID_REGEX}$`);
exports.nodeIdRegex = new RegExp(`^${NODE_ID_REGEX}$`);
exports.unitIdRegex = new RegExp(UNIT_NODE_ID_REGEX);
exports.pinIdRegex = new RegExp(PIN_NODE_ID_REGEX);
exports.inputIdRegex = new RegExp(INPUT_NODE_ID_REGEX);
exports.outputIdRegex = new RegExp(OUTPUT_NODE_ID_REGEX);
exports.dataRegex = new RegExp(`^${exports.DATA}/[^#_]+$`);
exports.metadataRegex = new RegExp(`^\\$/[^]+/${UNIT_ID_REGEX}$`);
exports.mergeRegex = new RegExp(`^${exports.MERGE}/[^/#$]+$`);
exports.externalRegex = new RegExp(`^${exports.EXTERNAL}/(input|output)/[^${exports.SEPARATOR}${exports.DATA}${exports.MERGE}]+$`);
exports.internalRegex = new RegExp(`^\\${exports.INTERNAL}/(input|output)/${PIN_ID_REGEX}/[^${exports.SEPARATOR}${exports.DATA}${exports.MERGE}]+$`);
exports.linkRegex = new RegExp(`^(.+)${exports.LINK_SEPARATOR}(.+)$`);
function tail(array) {
    return array.slice(1, array.length);
}
function dropLast(array) {
    return array.slice(0, array.length - 1);
}
function last(array) {
    return array[array.length - 1];
}
function getDatumNodeIdFromDatumLinkId(linkId) {
    const { source, target } = segmentLinkId(linkId);
    return isDatumNodeId(source) ? source : target;
}
exports.getDatumNodeIdFromDatumLinkId = getDatumNodeIdFromDatumLinkId;
function getTypeFromLinkPinNodeId(linkPinNodeId) {
    return linkPinNodeId.split('/')[1];
}
exports.getTypeFromLinkPinNodeId = getTypeFromLinkPinNodeId;
function getPinIdFromLinkPinNodeId(nodeId) {
    return nodeId.split('/')[2];
}
exports.getPinIdFromLinkPinNodeId = getPinIdFromLinkPinNodeId;
function getIdFromDatumNodeId(nodeId) {
    const { datumId: id } = segmentDatumNodeId(nodeId);
    return id;
}
exports.getIdFromDatumNodeId = getIdFromDatumNodeId;
function getPinIdClass(pinNodeId) {
    if (isOutputPinId(pinNodeId)) {
        return 'output';
    }
    if (isInputPinId(pinNodeId)) {
        return 'input';
    }
    throw `Input with id "${pinNodeId}" was not found`;
}
exports.getPinIdClass = getPinIdClass;
const getPinNodeId = (unitId, type, pinId) => {
    return `${unitId}/${type}/${pinId}`;
};
exports.getPinNodeId = getPinNodeId;
const getPinNodeId_ = (unitId) => {
    return (type, pinId) => `${unitId}/${type}/${pinId}`;
};
exports.getPinNodeId_ = getPinNodeId_;
const getPinNodeId__ = (unitId, type) => {
    return (pinId) => `${unitId}/${type}/${pinId}`;
};
exports.getPinNodeId__ = getPinNodeId__;
function getInputNodeId(unitId, pinId) {
    return `${unitId}/input/${pinId}`;
}
exports.getInputNodeId = getInputNodeId;
function getOutputNodeId(unitId, pinId) {
    return `${unitId}/output/${pinId}`;
}
exports.getOutputNodeId = getOutputNodeId;
function getSelfPinNodeId(unitId) {
    return getOutputNodeId(unitId, SELF_1.SELF);
}
exports.getSelfPinNodeId = getSelfPinNodeId;
function getLinkId(source, targetId) {
    return `${source}${exports.LINK_SEPARATOR}${targetId}`;
}
exports.getLinkId = getLinkId;
function getPinLinkId(unitId, type, pinId) {
    const pinNodeId = (0, exports.getPinNodeId)(unitId, type, pinId);
    if (type === 'input') {
        return getLinkId(pinNodeId, unitId);
    }
    else {
        return getLinkId(unitId, pinNodeId);
    }
}
exports.getPinLinkId = getPinLinkId;
function getPinLinkIdFromPinNodeId(pinNodeId) {
    const { unitId, type, pinId } = segmentLinkPinNodeId(pinNodeId);
    return getPinLinkId(unitId, type, pinId);
}
exports.getPinLinkIdFromPinNodeId = getPinLinkIdFromPinNodeId;
function isNodeId(text) {
    return isUnitNodeId(text) || isPinNodeId(text);
}
exports.isNodeId = isNodeId;
function isInternalNodeId(nodeId) {
    return exports.internalRegex.test(nodeId);
}
exports.isInternalNodeId = isInternalNodeId;
function isOutputPinId(nodeId) {
    return exports.outputIdRegex.test(nodeId);
}
exports.isOutputPinId = isOutputPinId;
function isUnitNodeId(nodeId) {
    return !!exports.unitIdRegex.exec(nodeId);
}
exports.isUnitNodeId = isUnitNodeId;
function isPinId(nodeId) {
    if (nodeId) {
        return isInputPinId(nodeId) || isOutputPinId(nodeId);
    }
    else {
        return false;
    }
}
exports.isPinId = isPinId;
function getUnitIdFromNodeId(nodeId) {
    if (isUnitNodeId(nodeId)) {
        return nodeId;
    }
    else {
        const [unitId] = nodeId.split('/');
        return unitId;
    }
}
exports.getUnitIdFromNodeId = getUnitIdFromNodeId;
function isLinkId(linkId) {
    return !!exports.linkRegex.exec(linkId);
}
exports.isLinkId = isLinkId;
function isPinLinkId(linkId) {
    const [source, target] = linkId.split(exports.LINK_SEPARATOR);
    return ((isUnitNodeId(source) && isPinId(target)) ||
        (isPinId(source) && isUnitNodeId(target)));
}
exports.isPinLinkId = isPinLinkId;
function isDatumLinkId(linkId) {
    const [source, target] = linkId.split(exports.LINK_SEPARATOR);
    return ((isPinNodeId(source) && isDatumNodeId(target)) ||
        (isDatumNodeId(source) && isPinNodeId(target)));
}
exports.isDatumLinkId = isDatumLinkId;
function isMetaLinkId(linkId) {
    const [source, target] = linkId.split(exports.LINK_SEPARATOR);
    return isMetadataNodeId(source);
}
exports.isMetaLinkId = isMetaLinkId;
function isExternalLinkId(linkId) {
    const [source, target] = linkId.split(exports.LINK_SEPARATOR);
    return (isExternalNodeId(source) ||
        isExternalNodeId(target) ||
        isInternalNodeId(source) ||
        isInternalNodeId(target));
}
exports.isExternalLinkId = isExternalLinkId;
function getErrNodeId(unit_id) {
    return `${exports.ERR}/${unit_id}`;
}
exports.getErrNodeId = getErrNodeId;
function segmentErrNodeId(errNodeId) {
    const unitId = errNodeId.substr(2, errNodeId.length);
    return {
        unitId,
    };
}
exports.segmentErrNodeId = segmentErrNodeId;
function segmentLinkPinNodeId(pinNodeId) {
    const [unitId, type, pinId] = pinNodeId.split('/');
    return {
        unitId,
        type,
        pinId,
    };
}
exports.segmentLinkPinNodeId = segmentLinkPinNodeId;
function segmentLinkId(linkId) {
    const [source, target] = linkId.split(exports.LINK_SEPARATOR);
    return {
        source,
        target,
    };
}
exports.segmentLinkId = segmentLinkId;
function segmentPinLinkId(linkId) {
    const { source, target } = segmentLinkId(linkId);
    const unitId = isUnitNodeId(source) ? source : target;
    const pinNodeId = isUnitNodeId(source) ? target : source;
    return {
        unitId,
        pinNodeId,
    };
}
exports.segmentPinLinkId = segmentPinLinkId;
function segmentDatumLinkId(linkId) {
    const { source, target } = segmentLinkId(linkId);
    const sourceIsDatum = isDatumNodeId(source);
    const datumNodeId = sourceIsDatum ? source : target;
    const pinNodeId = sourceIsDatum ? target : source;
    return {
        datumNodeId,
        pinNodeId,
    };
}
exports.segmentDatumLinkId = segmentDatumLinkId;
function segmentMetaLinkId(linkId) {
    const { source, target } = segmentLinkId(linkId);
    const nodeId = target;
    const metadataNodeId = source;
    return {
        nodeId,
        metadataNodeId,
    };
}
exports.segmentMetaLinkId = segmentMetaLinkId;
function segmentExternalLinkId(linkId) {
    const { source, target } = segmentLinkId(linkId);
    const sourceExternal = isExternalNodeId(source);
    const externalNodeId = sourceExternal ? target : source;
    const nodeId = sourceExternal ? source : target;
    return {
        nodeId,
        externalNodeId,
    };
}
exports.segmentExternalLinkId = segmentExternalLinkId;
function getPinNodeIdFromPinLinkId(linkId) {
    const { source, target } = segmentLinkId(linkId);
    return isUnitNodeId(source) ? target : source;
}
exports.getPinNodeIdFromPinLinkId = getPinNodeIdFromPinLinkId;
function getUnitIdFromPinLinkId(linkId) {
    const { source, target } = segmentLinkId(linkId);
    return isUnitNodeId(source) ? source : target;
}
exports.getUnitIdFromPinLinkId = getUnitIdFromPinLinkId;
function isInputPinId(nodeId) {
    return exports.inputIdRegex.test(nodeId);
}
exports.isInputPinId = isInputPinId;
function isPinNodeId(nodeId) {
    // return isLinkPinNodeId(id) || isMergeNodeId(id) || isExternalNodeId(id)
    return isLinkPinNodeId(nodeId) || isMergeNodeId(nodeId);
}
exports.isPinNodeId = isPinNodeId;
function isLinkPinNodeId(nodeId) {
    return exports.pinIdRegex.test(nodeId);
}
exports.isLinkPinNodeId = isLinkPinNodeId;
function isErrPinId(pinNodeId) {
    return (isOutputPinId(pinNodeId) && segmentLinkPinNodeId(pinNodeId).pinId === 'err');
}
exports.isErrPinId = isErrPinId;
function segmentCount(path) {
    return path.split('/').length;
}
exports.segmentCount = segmentCount;
function getSelectionId(nodeId, type) {
    return `${nodeId}/selection/${type}`;
}
exports.getSelectionId = getSelectionId;
function sameUnit(pinId0, pinId1) {
    return getUnitIdFromNodeId(pinId0) === getUnitIdFromNodeId(pinId1);
}
exports.sameUnit = sameUnit;
function getDatumNodeId(nodeId) {
    return `${exports.DATA}/${nodeId}`;
}
exports.getDatumNodeId = getDatumNodeId;
function isDatumNodeId(nodeId) {
    return !!exports.dataRegex.exec(nodeId);
}
exports.isDatumNodeId = isDatumNodeId;
function segmentDatumNodeId(datumNodeId) {
    const id = datumNodeId.substr(2, datumNodeId.length);
    return {
        datumId: id,
    };
}
exports.segmentDatumNodeId = segmentDatumNodeId;
function getMetadataNodeId(nodeId, name) {
    return `${exports.TYPE}/${nodeId}/${name}`;
}
exports.getMetadataNodeId = getMetadataNodeId;
function getTypeNodeId(nodeId) {
    return `${exports.TYPE}/${nodeId}`;
}
exports.getTypeNodeId = getTypeNodeId;
function isMetadataNodeId(nodeId) {
    return !!exports.metadataRegex.exec(nodeId);
}
exports.isMetadataNodeId = isMetadataNodeId;
function segmentMetadataId(metadataNodeId) {
    const segments = tail(metadataNodeId.split('/'));
    const id = last(segments);
    const nodeId = dropLast(segments).join('/');
    return {
        nodeId,
        id,
    };
}
exports.segmentMetadataId = segmentMetadataId;
function getMergeNodeId(mergeId) {
    return `${exports.MERGE}/${mergeId}`;
}
exports.getMergeNodeId = getMergeNodeId;
function isMergeNodeId(nodeId) {
    return exports.mergeRegex.test(nodeId);
}
exports.isMergeNodeId = isMergeNodeId;
function segmentMergeNodeId(mergeNodeId) {
    // remove '@/'
    const mergeId = mergeNodeId.substring(2, mergeNodeId.length);
    return {
        mergeId,
    };
}
exports.segmentMergeNodeId = segmentMergeNodeId;
function getIdFromMergeNodeId(mergeNodeId) {
    const { mergeId } = segmentMergeNodeId(mergeNodeId);
    return mergeId;
}
exports.getIdFromMergeNodeId = getIdFromMergeNodeId;
function getExtNodeId(type, pinId, subPinId) {
    return `${exports.EXTERNAL}/${type}/${pinId}/${subPinId}`;
}
exports.getExtNodeId = getExtNodeId;
function getExtNodeIdFromIntNodeId(intNodeId) {
    const { type, pinId, subPinId } = segmentInternalNodeId(intNodeId);
    return getExtNodeId(type, pinId, subPinId);
}
exports.getExtNodeIdFromIntNodeId = getExtNodeIdFromIntNodeId;
function getIntNodeIdFromExtNodeId(ext_node_id) {
    const { type, pinId, subPinId } = segmentPlugNodeId(ext_node_id);
    return getIntNodeId(type, pinId, subPinId);
}
exports.getIntNodeIdFromExtNodeId = getIntNodeIdFromExtNodeId;
function getIntNodeId(type, pinId, subPinId) {
    return `${exports.INTERNAL}/${type}/${pinId}/${subPinId}`;
}
exports.getIntNodeId = getIntNodeId;
function isExternalNodeId(pinId) {
    return exports.externalRegex.test(pinId);
}
exports.isExternalNodeId = isExternalNodeId;
function segmentPlugNodeId(exposedNodeId) {
    const [_, type, pinId, subPinId] = exposedNodeId.split('/');
    return {
        type,
        pinId,
        subPinId,
    };
}
exports.segmentPlugNodeId = segmentPlugNodeId;
function segmentInternalNodeId(internalNodeId) {
    const [_, type, pinId, subPinId] = internalNodeId.split('/');
    return {
        type,
        pinId,
        subPinId,
    };
}
exports.segmentInternalNodeId = segmentInternalNodeId;
const rangeArray = (n) => {
    const range = [];
    for (let i = 0; i < n; i++) {
        range.push(i);
    }
    return range;
};
exports.rangeArray = rangeArray;
const harmonicArray = (n) => {
    if (n === 0) {
        return [];
    }
    const array = [0];
    for (let i = 1; i < n; i++) {
        array.push(array[i - 1] + 1 / i);
    }
    return array;
};
exports.harmonicArray = harmonicArray;
function isBaseSpecId(specs, id) {
    const spec = specs[id];
    return isBaseSpec(spec);
}
exports.isBaseSpecId = isBaseSpecId;
function isBaseSpec(spec) {
    const { base } = spec;
    return !!base;
}
exports.isBaseSpec = isBaseSpec;
const numberOrDefault = (n, def) => {
    if (typeof n === 'number') {
        return n;
    }
    return def;
};
exports.numberOrDefault = numberOrDefault;
function kebabToCamel(str) {
    const segments = str.split(/\s*-\s*/);
    const first_segment = segments[0];
    const segments_tail = segments.slice(1);
    const camelled_segments_tail = segments_tail.map((_str) => (0, string_1.upperCaseFirstLetter)(_str));
    const camel = first_segment + camelled_segments_tail.join('');
    return camel;
}
exports.kebabToCamel = kebabToCamel;
function camelToKebab(str) {
    const segments = str.split(/(?=[A-Z])/);
    const kebab = segments.map((_str) => _str.toLowerCase()).join('-');
    return kebab;
}
exports.camelToKebab = camelToKebab;
function camelToSnake(str) {
    const segments = str.split(/(?=[A-Z])/);
    const kebab = segments.map((_str) => _str.toLowerCase()).join('_');
    return kebab;
}
exports.camelToSnake = camelToSnake;
function camelToDashed(str) {
    const segments = str.split(/(?=[A-Z])/);
    const kebab = segments.map((_str) => _str.toLowerCase()).join('-');
    return kebab;
}
exports.camelToDashed = camelToDashed;
function kebabCase(str) {
    return str.toLowerCase().replace(' ', '-');
}
exports.kebabCase = kebabCase;
//# sourceMappingURL=index.js.map