in packages/ketcher-core/src/domain/serializers/mol/v2000.js [131:276]
function parsePropertyLines(ctab, ctabLines, shift, end, sGroups, rLogic) {
// eslint-disable-line max-statements, max-params
/* reader */
const props = new Pool();
while (shift < end) {
const line = ctabLines[shift];
if (line.charAt(0) === 'A') {
const propValue = ctabLines[++shift];
// TODO: Atom entity only have pseudo getter. Check during refactoring
// this type of pseudo labeling is not used in current BIOVIA products. See ctab documentation 2020
// https://discover.3ds.com/sites/default/files/2020-08/biovia_ctfileformats_2020.pdf (page 47)
const isPseudo = /'.+'/.test(propValue);
if (isPseudo && !props.get('pseudo')) {
props.set('pseudo', new Pool());
}
if (!isPseudo && !props.get('alias')) {
props.set('alias', new Pool());
}
props
.get(isPseudo ? 'pseudo' : 'alias')
.set(utils.parseDecimalInt(line.slice(3)) - 1, propValue);
} else if (line.charAt(0) === 'M') {
const type = line.slice(3, 6);
let propertyData = line.slice(6);
if (type === 'END') {
break;
} else if (type === 'CHG') {
if (!props.get('charge')) {
props.set('charge', sGroup.readKeyValuePairs(propertyData));
}
} else if (type === 'RAD') {
if (!props.get('radical')) {
props.set('radical', sGroup.readKeyValuePairs(propertyData));
}
} else if (type === 'ISO') {
if (!props.get('isotope')) {
props.set('isotope', sGroup.readKeyValuePairs(propertyData));
}
} else if (type === 'RBC') {
if (!props.get('ringBondCount')) {
props.set('ringBondCount', sGroup.readKeyValuePairs(propertyData));
}
} else if (type === 'SUB') {
if (!props.get('substitutionCount'))
props.set('substitutionCount', new Pool());
const subLabels = props.get('substitutionCount');
const arrs = sGroup.readKeyMultiValuePairs(propertyData);
for (let arri = 0; arri < arrs.length; arri++) {
const a2r = arrs[arri];
subLabels.set(a2r[0], a2r[1]);
}
} else if (type === 'UNS') {
if (!props.get('unsaturatedAtom')) {
props.set('unsaturatedAtom', sGroup.readKeyValuePairs(propertyData));
}
// else if (type == "LIN") // link atom
} else if (type === 'RGP') {
// rgroup atom
if (!props.get('rglabel')) props.set('rglabel', new Pool());
const rglabels = props.get('rglabel');
const a2rs = sGroup.readKeyMultiValuePairs(propertyData);
for (let a2ri = 0; a2ri < a2rs.length; a2ri++) {
const a2r = a2rs[a2ri];
rglabels.set(
a2r[0],
(rglabels.get(a2r[0]) || 0) | (1 << (a2r[1] - 1)),
);
}
} else if (type === 'LOG') {
// rgroup atom
propertyData = propertyData.slice(4);
const rgid = utils.parseDecimalInt(propertyData.slice(0, 3).trim());
const iii = utils.parseDecimalInt(propertyData.slice(4, 7).trim());
const hhh = utils.parseDecimalInt(propertyData.slice(8, 11).trim());
const ooo = propertyData.slice(12).trim();
const logic = {};
if (iii > 0) logic.ifthen = iii;
logic.resth = hhh === 1;
logic.range = ooo;
rLogic[rgid] = logic;
} else if (type === 'APO') {
if (!props.get('attachmentPoints')) {
props.set('attachmentPoints', sGroup.readKeyValuePairs(propertyData));
}
} else if (type === 'ALS') {
// atom list
const pool = parsePropertyLineAtomList(
utils.partitionLine(propertyData, [1, 3, 3, 1, 1, 1]),
utils.partitionLineFixed(propertyData.slice(10), 4, false),
);
if (!props.get('atomList')) props.set('atomList', new Pool());
if (!props.get('label')) props.set('label', new Pool());
pool.forEach((atomList, aid) => {
props.get('label').set(aid, 'L#');
props.get('atomList').set(aid, atomList);
});
} else if (type === 'STY') {
// introduce s-group
sGroup.initSGroup(sGroups, propertyData);
} else if (type === 'SST') {
sGroup.applySGroupProp(sGroups, 'subtype', propertyData);
} else if (type === 'SLB') {
sGroup.applySGroupProp(sGroups, 'label', propertyData, true);
} else if (type === 'SPL') {
sGroup.applySGroupProp(sGroups, 'parent', propertyData, true, true);
} else if (type === 'SCN') {
sGroup.applySGroupProp(sGroups, 'connectivity', propertyData);
} else if (type === 'SAL') {
sGroup.applySGroupArrayProp(sGroups, 'atoms', propertyData, -1);
} else if (type === 'SBL') {
sGroup.applySGroupArrayProp(sGroups, 'bonds', propertyData, -1);
} else if (type === 'SPA') {
sGroup.applySGroupArrayProp(sGroups, 'patoms', propertyData, -1);
} else if (type === 'SMT') {
const sid = utils.parseDecimalInt(propertyData.slice(0, 4)) - 1;
sGroups[sid].data.subscript = propertyData.slice(4).trim();
} else if (type === 'SDT') {
sGroup.applyDataSGroupDesc(sGroups, propertyData);
} else if (type === 'SDD') {
sGroup.applyDataSGroupInfoLine(sGroups, propertyData);
} else if (type === 'SCD') {
sGroup.applyDataSGroupDataLine(sGroups, propertyData, false);
} else if (type === 'SED') {
sGroup.applyDataSGroupDataLine(sGroups, propertyData, true);
} else if (type === 'SDS') {
const expandedSGroups = propertyData.slice(7).trim().split(' ');
expandedSGroups.forEach((eg) => {
const sGroupId = Number(eg) - 1;
sGroups[sGroupId].data.expanded = true;
});
} else if (type === 'SAP') {
const { sGroupId, attachmentPoints } =
sGroup.parseSGroupSAPLineV2000(propertyData);
attachmentPoints.forEach((attachmentPoint) => {
sGroups[sGroupId].addAttachmentPoint(attachmentPoint);
});
}
}
++shift;
}
return props;
}