ketcher-react 3.9.0-rc.1 → 3.9.0-rc.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cjs/index.js CHANGED
@@ -44,7 +44,6 @@ var _ = require('lodash');
44
44
  var _taggedTemplateLiteral = require('@babel/runtime/helpers/taggedTemplateLiteral');
45
45
  var styled = require('@emotion/styled');
46
46
  var react = require('@emotion/react');
47
- var KN = require('w3c-keyname');
48
47
  var require$$0$3 = require('util');
49
48
  var ReactDOM = require('react-dom');
50
49
  var reactRedux = require('react-redux');
@@ -122,7 +121,6 @@ var _toConsumableArray__default = /*#__PURE__*/_interopDefaultLegacy(_toConsumab
122
121
  var ___default = /*#__PURE__*/_interopDefaultLegacy(_);
123
122
  var _taggedTemplateLiteral__default = /*#__PURE__*/_interopDefaultLegacy(_taggedTemplateLiteral);
124
123
  var styled__default = /*#__PURE__*/_interopDefaultLegacy(styled);
125
- var KN__namespace = /*#__PURE__*/_interopNamespace(KN);
126
124
  var require$$0__default = /*#__PURE__*/_interopDefaultLegacy(require$$0$3);
127
125
  var ReactDOM__default = /*#__PURE__*/_interopDefaultLegacy(ReactDOM);
128
126
  var CFB__namespace = /*#__PURE__*/_interopNamespace(CFB);
@@ -2854,7 +2852,7 @@ var toolActions = (_toolActions = {
2854
2852
  }
2855
2853
  },
2856
2854
  'charge-plus': {
2857
- shortcut: '+',
2855
+ shortcut: ['Equal', 'Shift+Equal', 'NumpadAdd'],
2858
2856
  title: 'Charge Plus',
2859
2857
  action: {
2860
2858
  tool: 'charge',
@@ -2865,7 +2863,7 @@ var toolActions = (_toolActions = {
2865
2863
  }
2866
2864
  },
2867
2865
  'charge-minus': {
2868
- shortcut: '-',
2866
+ shortcut: ['Minus', 'NumpadSubtract'],
2869
2867
  title: 'Charge Minus',
2870
2868
  action: {
2871
2869
  tool: 'charge',
@@ -3266,6 +3264,9 @@ var toolActions = (_toolActions = {
3266
3264
  },
3267
3265
  disabled: function disabled(editor) {
3268
3266
  return editor.isMonomerCreationWizardActive || !editor.isMonomerCreationWizardEnabled;
3267
+ },
3268
+ hidden: function hidden(options) {
3269
+ return isHidden(options, ketcherCore.CREATE_MONOMER_TOOL_NAME);
3269
3270
  }
3270
3271
  }), _defineProperty__default["default"](_defineProperty__default["default"](_defineProperty__default["default"](_defineProperty__default["default"](_defineProperty__default["default"](_defineProperty__default["default"](_defineProperty__default["default"](_toolActions, "shapes", {
3271
3272
  disabled: function disabled(editor) {
@@ -3902,7 +3903,7 @@ var zoom = {
3902
3903
  }
3903
3904
  },
3904
3905
  'zoom-out': {
3905
- shortcut: ['Ctrl+_', 'Ctrl+-'],
3906
+ shortcut: ['Mod+Minus', 'Mod+NumpadSubtract'],
3906
3907
  title: 'Zoom Out',
3907
3908
  enabledInViewOnly: true,
3908
3909
  disabled: function disabled(editor) {
@@ -3924,7 +3925,7 @@ var zoom = {
3924
3925
  }
3925
3926
  },
3926
3927
  'zoom-in': {
3927
- shortcut: ['Ctrl+=', 'Ctrl++'],
3928
+ shortcut: ['Mod+Equal', 'Mod+NumpadAdd'],
3928
3929
  title: 'Zoom In',
3929
3930
  enabledInViewOnly: true,
3930
3931
  disabled: function disabled(editor) {
@@ -3955,7 +3956,7 @@ var zoom = {
3955
3956
 
3956
3957
  var openHelpLink = function openHelpLink() {
3957
3958
  var _window$open;
3958
- return (_window$open = window.open("https://github.com/epam/ketcher/blob/".concat("v3.9.0-rc.1\n", "/documentation/help.md#ketcher-overview"))) === null || _window$open === void 0 ? void 0 : _window$open.focus();
3959
+ return (_window$open = window.open("https://github.com/epam/ketcher/blob/".concat("v3.9.0-rc.3\n", "/documentation/help.md#ketcher-overview"))) === null || _window$open === void 0 ? void 0 : _window$open.focus();
3959
3960
  };
3960
3961
  var help = {
3961
3962
  help: {
@@ -8916,7 +8917,7 @@ var Dialog = function Dialog(props) {
8916
8917
  }
8917
8918
  };
8918
8919
  var keyDown = function keyDown(event) {
8919
- var key = KN__namespace.keyName(event);
8920
+ var key = event.key;
8920
8921
  var active = document.activeElement;
8921
8922
  var activeTextarea = active && active.tagName === 'TEXTAREA';
8922
8923
  if (key === 'Escape' || key === 'Enter' && !activeTextarea) {
@@ -20416,8 +20417,8 @@ function keyHandle(dispatch, getState, hotKeys, event) {
20416
20417
  var hoveredItem = getHoveredItem(render.ctab);
20417
20418
  if (key && key.length === 1 && !hoveredItem) {
20418
20419
  var currentlyPressedKeys = selectAbbreviationLookupValue(state);
20419
- var isShortcutKey = shortcutKeys.includes(key === null || key === void 0 ? void 0 : key.toLowerCase());
20420
- var isTheSameKey = key === currentlyPressedKeys;
20420
+ var isShortcutKey = shortcutKeys.includes(key.toLowerCase());
20421
+ var isTheSameKey = key.toLowerCase() === currentlyPressedKeys;
20421
20422
  var isAbbreviationLookupShown = (!isTheSameKey || !isShortcutKey) && currentlyPressedKeys;
20422
20423
  if (isAbbreviationLookupShown) {
20423
20424
  dispatch(showAbbreviationLookup(event.key));
@@ -20435,7 +20436,7 @@ function keyHandle(dispatch, getState, hotKeys, event) {
20435
20436
  dispatch(initAbbreviationLookup(event.key));
20436
20437
  }
20437
20438
  }
20438
- if (key && key.length === 1 && key.match('/')) {
20439
+ if (key === 'Slash') {
20439
20440
  var hotkeyDialogTypes = {
20440
20441
  atoms: configWithNonViewOnlyActionsDisabled['atom-props'].action,
20441
20442
  bonds: configWithNonViewOnlyActionsDisabled['bond-props'].action
@@ -25641,11 +25642,35 @@ var Editor$3 = function () {
25641
25642
  }
25642
25643
  return false;
25643
25644
  }
25645
+ }, {
25646
+ key: "isMinimalViableStructure",
25647
+ value: function isMinimalViableStructure() {
25648
+ var _this = this;
25649
+ var nonLeavingAtoms = this.struct().atoms.filter(function (atomId) {
25650
+ assert_1(_this.monomerCreationState);
25651
+ return Array.from(_this.monomerCreationState.assignedAttachmentPoints.values()).every(function (atomPair) {
25652
+ return atomPair[1] !== atomId;
25653
+ });
25654
+ });
25655
+ if (nonLeavingAtoms.size < 2) {
25656
+ return false;
25657
+ }
25658
+ var nonLeavingAtomBonds = this.struct().bonds.filter(function (_, bond) {
25659
+ return nonLeavingAtoms.has(bond.begin) && nonLeavingAtoms.has(bond.end);
25660
+ });
25661
+ if (nonLeavingAtomBonds.size < 1) {
25662
+ return false;
25663
+ }
25664
+ var simpleSingleBonds = nonLeavingAtomBonds.filter(function (_, bond) {
25665
+ return bond.type === ketcherCore.Bond.PATTERN.TYPE.SINGLE && bond.stereo === ketcherCore.Bond.PATTERN.STEREO.NONE;
25666
+ });
25667
+ return simpleSingleBonds.size >= 1;
25668
+ }
25644
25669
  }, {
25645
25670
  key: "openMonomerCreationWizard",
25646
25671
  value: function openMonomerCreationWizard() {
25647
25672
  var _selection$atoms2,
25648
- _this = this;
25673
+ _this2 = this;
25649
25674
  var currentStruct = this.render.ctab.molecule;
25650
25675
  var selection = this.selection();
25651
25676
  assert_1(selection);
@@ -25657,7 +25682,7 @@ var Editor$3 = function () {
25657
25682
  return a - b;
25658
25683
  }).forEach(function (atomId, i) {
25659
25684
  originalToSelectedAtomsIdMap.set(atomId, i);
25660
- _this.selectedToOriginalAtomsIdMap.set(i, atomId);
25685
+ _this2.selectedToOriginalAtomsIdMap.set(i, atomId);
25661
25686
  });
25662
25687
  var assignedAttachmentPoints = new Map();
25663
25688
  var sideTerminalSGroupAtoms = this.terminalRGroupAtoms.filter(function (_ref) {
@@ -25726,10 +25751,10 @@ var Editor$3 = function () {
25726
25751
  pp: leavingAtom.pp
25727
25752
  });
25728
25753
  var selectedStructLeavingAtomId = selectedStruct.atoms.add(selectedStructLeavingAtom);
25729
- _this.selectedToOriginalAtomsIdMap.set(selectedStructLeavingAtomId, atomId);
25754
+ _this2.selectedToOriginalAtomsIdMap.set(selectedStructLeavingAtomId, atomId);
25730
25755
  var selectedStructAttachmentAtomId = originalToSelectedAtomsIdMap.get(attachmentAtomId);
25731
25756
  assert_1(selectedStructAttachmentAtomId !== undefined);
25732
- _this.selectedToOriginalAtomsIdMap.set(selectedStructAttachmentAtomId, attachmentAtomId);
25757
+ _this2.selectedToOriginalAtomsIdMap.set(selectedStructAttachmentAtomId, attachmentAtomId);
25733
25758
  var newBond = new ketcherCore.Bond({
25734
25759
  type: ketcherCore.Bond.PATTERN.TYPE.SINGLE,
25735
25760
  begin: selectedStructAttachmentAtomId,
@@ -25823,7 +25848,7 @@ var Editor$3 = function () {
25823
25848
  }, {
25824
25849
  key: "assignConnectionPointAtom",
25825
25850
  value: function assignConnectionPointAtom(atomId) {
25826
- var _this2 = this;
25851
+ var _this3 = this;
25827
25852
  assert_1(this.monomerCreationState);
25828
25853
  var potentialLeavingAtoms = this.monomerCreationState.potentialAttachmentPoints.get(atomId);
25829
25854
  var leavingAtomId;
@@ -25832,7 +25857,7 @@ var Editor$3 = function () {
25832
25857
  return a - b;
25833
25858
  }).reduce(function (acc, currentAtomId) {
25834
25859
  var _Elements$get;
25835
- var atom = _this2.struct().atoms.get(currentAtomId);
25860
+ var atom = _this3.struct().atoms.get(currentAtomId);
25836
25861
  assert_1(atom);
25837
25862
  var atomicNumber = (_Elements$get = ketcherCore.Elements.get(atom.label)) === null || _Elements$get === void 0 ? void 0 : _Elements$get.number;
25838
25863
  if (atomicNumber !== undefined) {
@@ -25888,14 +25913,16 @@ var Editor$3 = function () {
25888
25913
  assert_1(_.isNumber(originalLeavingAtomId));
25889
25914
  var originalLeavingAtom = this.originalStruct.atoms.get(originalLeavingAtomId);
25890
25915
  assert_1(originalLeavingAtom);
25891
- originalLeavingAtom.rglabel = null;
25892
- originalLeavingAtom.label = leavingAtom.label;
25893
- this.originalStruct.calcImplicitHydrogen(originalLeavingAtomId);
25916
+ if (originalLeavingAtom.rglabel !== null) {
25917
+ originalLeavingAtom.rglabel = null;
25918
+ originalLeavingAtom.label = leavingAtom.label;
25919
+ this.originalStruct.calcImplicitHydrogen(originalLeavingAtomId);
25920
+ }
25894
25921
  }
25895
25922
  }, {
25896
25923
  key: "saveNewMonomer",
25897
25924
  value: function saveNewMonomer(data) {
25898
- var _this3 = this,
25925
+ var _this4 = this,
25899
25926
  _this$originalSelecti;
25900
25927
  if (!this.monomerCreationState) {
25901
25928
  throw new Error('Monomer creation wizard is not active, cannot save new monomer');
@@ -25952,25 +25979,25 @@ var Editor$3 = function () {
25952
25979
  this.monomerCreationState.assignedAttachmentPoints.forEach(function (_ref11) {
25953
25980
  var _ref12 = _slicedToArray__default["default"](_ref11, 2),
25954
25981
  leavingAtomId = _ref12[1];
25955
- return _this3.cleanupAttachmentPoint(leavingAtomId);
25982
+ return _this4.cleanupAttachmentPoint(leavingAtomId);
25956
25983
  });
25957
25984
  this.monomerCreationState.potentialAttachmentPoints.forEach(function (leavingAtomIds) {
25958
25985
  return Array.from(leavingAtomIds.values()).forEach(function (leavingAtomId) {
25959
- return _this3.cleanupAttachmentPoint(leavingAtomId);
25986
+ return _this4.cleanupAttachmentPoint(leavingAtomId);
25960
25987
  });
25961
25988
  });
25962
25989
  this.closeMonomerCreationWizard();
25963
25990
  (_this$originalSelecti = this.originalSelection.atoms) === null || _this$originalSelecti === void 0 || _this$originalSelecti.forEach(function (atomId) {
25964
- var atom = _this3.render.ctab.molecule.atoms.get(atomId);
25991
+ var atom = _this4.render.ctab.molecule.atoms.get(atomId);
25965
25992
  if (atom) {
25966
25993
  atom.fragment = -1;
25967
25994
  }
25968
25995
  });
25969
25996
  var sGroupAttachmentPoints = ketcherCore.MacromoleculesConverter.convertMonomerAttachmentPointsToSGroupAttachmentPoints(monomer, this.selectedToOriginalAtomsIdMap);
25970
25997
  sGroupAttachmentPoints.forEach(function (ap) {
25971
- _this3.render.ctab.molecule.bonds.forEach(function (bond) {
25972
- var _this3$originalSelect, _this3$originalSelect2;
25973
- if ((bond.begin === ap.atomId || bond.end === ap.atomId) && (!((_this3$originalSelect = _this3.originalSelection.atoms) !== null && _this3$originalSelect !== void 0 && _this3$originalSelect.includes(bond.begin)) || !((_this3$originalSelect2 = _this3.originalSelection.atoms) !== null && _this3$originalSelect2 !== void 0 && _this3$originalSelect2.includes(bond.end)))) {
25998
+ _this4.render.ctab.molecule.bonds.forEach(function (bond) {
25999
+ var _this4$originalSelect, _this4$originalSelect2;
26000
+ if ((bond.begin === ap.atomId || bond.end === ap.atomId) && (!((_this4$originalSelect = _this4.originalSelection.atoms) !== null && _this4$originalSelect !== void 0 && _this4$originalSelect.includes(bond.begin)) || !((_this4$originalSelect2 = _this4.originalSelection.atoms) !== null && _this4$originalSelect2 !== void 0 && _this4$originalSelect2.includes(bond.end)))) {
25974
26001
  bond.beginSuperatomAttachmentPointNumber = ap.attachmentPointNumber;
25975
26002
  }
25976
26003
  });
@@ -26039,6 +26066,7 @@ var Editor$3 = function () {
26039
26066
  }, {
26040
26067
  key: "removeAttachmentPoint",
26041
26068
  value: function removeAttachmentPoint(name) {
26069
+ var _this5 = this;
26042
26070
  assert_1(this.monomerCreationState);
26043
26071
  var atomPair = this.monomerCreationState.assignedAttachmentPoints.get(name);
26044
26072
  assert_1(atomPair);
@@ -26055,8 +26083,18 @@ var Editor$3 = function () {
26055
26083
  var action = ketcherCore.fromOneBondDeletion(this.render.ctab, preservedBondId).mergeWith(ketcherCore.fromOneAtomDeletion(this.render.ctab, preservedLeavingAtomId));
26056
26084
  this.update(action, true);
26057
26085
  }
26086
+ this.preservedConnectionPointData["delete"](attachmentAtomId);
26087
+ } else {
26088
+ var leavingAtoms = this.findPotentialLeavingAtoms(attachmentAtomId);
26089
+ var leavingAtomIdsSet = new Set();
26090
+ leavingAtoms.forEach(function (atom) {
26091
+ var atomId = _this5.struct().atoms.keyOf(atom);
26092
+ if (atomId !== null) {
26093
+ leavingAtomIdsSet.add(atomId);
26094
+ }
26095
+ });
26096
+ this.monomerCreationState.potentialAttachmentPoints.set(attachmentAtomId, leavingAtomIdsSet);
26058
26097
  }
26059
- this.preservedConnectionPointData["delete"](attachmentAtomId);
26060
26098
  this.monomerCreationState.assignedAttachmentPoints["delete"](name);
26061
26099
  this.monomerCreationState = Object.assign({}, this.monomerCreationState);
26062
26100
  this.render.update(true);
@@ -26105,7 +26143,7 @@ var Editor$3 = function () {
26105
26143
  }, {
26106
26144
  key: "findPotentialLeavingAtoms",
26107
26145
  value: function findPotentialLeavingAtoms(attachmentAtomId) {
26108
- var _this4 = this;
26146
+ var _this6 = this;
26109
26147
  var bondsToOutside = this.struct().bonds.filter(function (_, bond) {
26110
26148
  return attachmentAtomId === bond.begin && attachmentAtomId !== bond.end || attachmentAtomId === bond.end && attachmentAtomId !== bond.begin;
26111
26149
  });
@@ -26115,7 +26153,7 @@ var Editor$3 = function () {
26115
26153
  return;
26116
26154
  }
26117
26155
  var atomIdToUse = attachmentAtomId === bond.begin ? bond.end : bond.begin;
26118
- var atom = _this4.struct().atoms.get(atomIdToUse);
26156
+ var atom = _this6.struct().atoms.get(atomIdToUse);
26119
26157
  assert_1(atom);
26120
26158
  if (atom.neighbors.length === 1) {
26121
26159
  potentialLeavingAtoms.push(atom);
@@ -26126,15 +26164,15 @@ var Editor$3 = function () {
26126
26164
  }, {
26127
26165
  key: "subscribeToChangeEventInMonomerCreationWizard",
26128
26166
  value: function subscribeToChangeEventInMonomerCreationWizard() {
26129
- var _this5 = this;
26167
+ var _this7 = this;
26130
26168
  if (this.changeEventSubscriber) {
26131
26169
  return;
26132
26170
  }
26133
26171
  var handleChangeEvent = function handleChangeEvent(data) {
26134
- if (!_this5.isMonomerCreationWizardActive || data.length === 0) {
26172
+ if (!_this7.isMonomerCreationWizardActive || data.length === 0) {
26135
26173
  return;
26136
26174
  }
26137
- _this5.collectChangesForMonomerCreationStateInvalidation(data);
26175
+ _this7.collectChangesForMonomerCreationStateInvalidation(data);
26138
26176
  };
26139
26177
  this.changeEventSubscriber = this.subscribe('change', handleChangeEvent);
26140
26178
  }
@@ -26177,7 +26215,7 @@ var Editor$3 = function () {
26177
26215
  }, {
26178
26216
  key: "invalidateMonomerCreationWizardState",
26179
26217
  value: function invalidateMonomerCreationWizardState(changesMap) {
26180
- var _this6 = this;
26218
+ var _this8 = this;
26181
26219
  if (!this.monomerCreationState) {
26182
26220
  return;
26183
26221
  }
@@ -26191,7 +26229,7 @@ var Editor$3 = function () {
26191
26229
  switch (operation) {
26192
26230
  case ketcherCore.OperationType.ATOM_DELETE:
26193
26231
  {
26194
- var attachmentPointsToInvalidate = Array.from(_this6.monomerCreationState.assignedAttachmentPoints.entries()).filter(function (_ref13) {
26232
+ var attachmentPointsToInvalidate = Array.from(_this8.monomerCreationState.assignedAttachmentPoints.entries()).filter(function (_ref13) {
26195
26233
  var _ref14 = _slicedToArray__default["default"](_ref13, 2),
26196
26234
  atomPair = _ref14[1];
26197
26235
  return ids.has(atomPair[0]) || ids.has(atomPair[1]);
@@ -26207,18 +26245,39 @@ var Editor$3 = function () {
26207
26245
  attachmentAtomId = _atomPair4[0],
26208
26246
  leavingAtomId = _atomPair4[1];
26209
26247
  if (ids.has(attachmentAtomId)) {
26210
- var _this6$monomerCreatio;
26211
- (_this6$monomerCreatio = _this6.monomerCreationState) === null || _this6$monomerCreatio === void 0 || _this6$monomerCreatio.assignedAttachmentPoints["delete"](attachmentPointName);
26248
+ var _this8$monomerCreatio;
26249
+ (_this8$monomerCreatio = _this8.monomerCreationState) === null || _this8$monomerCreatio === void 0 || _this8$monomerCreatio.assignedAttachmentPoints["delete"](attachmentPointName);
26212
26250
  } else if (ids.has(leavingAtomId)) {
26213
- var potentialLeavingAtoms = _this6.findPotentialLeavingAtoms(attachmentAtomId);
26251
+ var potentialLeavingAtoms = _this8.findPotentialLeavingAtoms(attachmentAtomId);
26214
26252
  if (potentialLeavingAtoms.length === 0) {
26215
- var _this6$monomerCreatio2;
26216
- (_this6$monomerCreatio2 = _this6.monomerCreationState) === null || _this6$monomerCreatio2 === void 0 || _this6$monomerCreatio2.assignedAttachmentPoints["delete"](attachmentPointName);
26253
+ var _this8$monomerCreatio2;
26254
+ (_this8$monomerCreatio2 = _this8.monomerCreationState) === null || _this8$monomerCreatio2 === void 0 || _this8$monomerCreatio2.assignedAttachmentPoints["delete"](attachmentPointName);
26217
26255
  } else {
26218
- var _this6$monomerCreatio3;
26219
- var newLeavingAtomId = _this6.struct().atoms.keyOf(potentialLeavingAtoms[0]);
26256
+ var _this8$monomerCreatio3;
26257
+ var newLeavingAtomId = _this8.struct().atoms.keyOf(potentialLeavingAtoms[0]);
26220
26258
  assert_1(newLeavingAtomId !== null);
26221
- (_this6$monomerCreatio3 = _this6.monomerCreationState) === null || _this6$monomerCreatio3 === void 0 || _this6$monomerCreatio3.assignedAttachmentPoints.set(attachmentPointName, [attachmentAtomId, newLeavingAtomId]);
26259
+ (_this8$monomerCreatio3 = _this8.monomerCreationState) === null || _this8$monomerCreatio3 === void 0 || _this8$monomerCreatio3.assignedAttachmentPoints.set(attachmentPointName, [attachmentAtomId, newLeavingAtomId]);
26260
+ }
26261
+ }
26262
+ });
26263
+ var potentialAttachmentPointsToInvalidate = Array.from(_this8.monomerCreationState.potentialAttachmentPoints.entries());
26264
+ potentialAttachmentPointsToInvalidate.forEach(function (_ref17) {
26265
+ var _ref18 = _slicedToArray__default["default"](_ref17, 2),
26266
+ attachmentAtomId = _ref18[0],
26267
+ leavingAtomIds = _ref18[1];
26268
+ if (ids.has(attachmentAtomId)) {
26269
+ var _this8$monomerCreatio4;
26270
+ (_this8$monomerCreatio4 = _this8.monomerCreationState) === null || _this8$monomerCreatio4 === void 0 || _this8$monomerCreatio4.potentialAttachmentPoints["delete"](attachmentAtomId);
26271
+ } else {
26272
+ var updatedLeavingAtomIds = new Set(Array.from(leavingAtomIds).filter(function (id) {
26273
+ return !ids.has(id);
26274
+ }));
26275
+ if (updatedLeavingAtomIds.size === 0) {
26276
+ var _this8$monomerCreatio5;
26277
+ (_this8$monomerCreatio5 = _this8.monomerCreationState) === null || _this8$monomerCreatio5 === void 0 || _this8$monomerCreatio5.potentialAttachmentPoints["delete"](attachmentAtomId);
26278
+ } else {
26279
+ var _this8$monomerCreatio6;
26280
+ (_this8$monomerCreatio6 = _this8.monomerCreationState) === null || _this8$monomerCreatio6 === void 0 || _this8$monomerCreatio6.potentialAttachmentPoints.set(attachmentAtomId, updatedLeavingAtomIds);
26222
26281
  }
26223
26282
  }
26224
26283
  });
@@ -26231,24 +26290,40 @@ var Editor$3 = function () {
26231
26290
  try {
26232
26291
  var _loop2 = function _loop2() {
26233
26292
  var id = _step3.value;
26234
- var bond = _this6.struct().bonds.get(id);
26293
+ var bond = _this8.struct().bonds.get(id);
26235
26294
  assert_1(bond);
26236
- var attachmentPointWithBond = Array.from(_this6.monomerCreationState.assignedAttachmentPoints.entries()).find(function (_ref17) {
26237
- var _ref18 = _slicedToArray__default["default"](_ref17, 2),
26238
- atomPair = _ref18[1];
26295
+ var attachmentPointWithBond = Array.from(_this8.monomerCreationState.assignedAttachmentPoints.entries()).find(function (_ref19) {
26296
+ var _ref20 = _slicedToArray__default["default"](_ref19, 2),
26297
+ atomPair = _ref20[1];
26239
26298
  return bond.begin === atomPair[0] && bond.end === atomPair[1] || bond.begin === atomPair[1] && bond.end === atomPair[0];
26240
26299
  });
26241
- if (!attachmentPointWithBond) {
26242
- return 1;
26300
+ if (attachmentPointWithBond) {
26301
+ if (bond.type !== ketcherCore.Bond.PATTERN.TYPE.SINGLE || bond.stereo !== ketcherCore.Bond.PATTERN.STEREO.NONE) {
26302
+ _this8.monomerCreationState.problematicAttachmentPoints.add(attachmentPointWithBond[0]);
26303
+ } else {
26304
+ _this8.monomerCreationState.problematicAttachmentPoints["delete"](attachmentPointWithBond[0]);
26305
+ }
26243
26306
  }
26244
26307
  if (bond.type !== ketcherCore.Bond.PATTERN.TYPE.SINGLE || bond.stereo !== ketcherCore.Bond.PATTERN.STEREO.NONE) {
26245
- _this6.monomerCreationState.problematicAttachmentPoints.add(attachmentPointWithBond[0]);
26246
- } else {
26247
- _this6.monomerCreationState.problematicAttachmentPoints["delete"](attachmentPointWithBond[0]);
26308
+ _this8.monomerCreationState.potentialAttachmentPoints.forEach(function (leavingAtomIds, attachmentAtomId) {
26309
+ var updatedLeavingAtomIds = new Set(leavingAtomIds);
26310
+ var bondFromAttachmentAtom = bond.begin === attachmentAtomId && leavingAtomIds.has(bond.end);
26311
+ var bondToAttachmentAtom = bond.end === attachmentAtomId && leavingAtomIds.has(bond.begin);
26312
+ if (bondFromAttachmentAtom || bondToAttachmentAtom) {
26313
+ updatedLeavingAtomIds["delete"](bondFromAttachmentAtom ? bond.end : bond.begin);
26314
+ }
26315
+ if (updatedLeavingAtomIds.size === 0) {
26316
+ var _this8$monomerCreatio7;
26317
+ (_this8$monomerCreatio7 = _this8.monomerCreationState) === null || _this8$monomerCreatio7 === void 0 || _this8$monomerCreatio7.potentialAttachmentPoints["delete"](attachmentAtomId);
26318
+ } else {
26319
+ var _this8$monomerCreatio8;
26320
+ (_this8$monomerCreatio8 = _this8.monomerCreationState) === null || _this8$monomerCreatio8 === void 0 || _this8$monomerCreatio8.potentialAttachmentPoints.set(attachmentAtomId, updatedLeavingAtomIds);
26321
+ }
26322
+ });
26248
26323
  }
26249
26324
  };
26250
26325
  for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
26251
- if (_loop2()) continue;
26326
+ _loop2();
26252
26327
  }
26253
26328
  } catch (err) {
26254
26329
  _iterator3.e(err);
@@ -26264,23 +26339,44 @@ var Editor$3 = function () {
26264
26339
  try {
26265
26340
  var _loop3 = function _loop3() {
26266
26341
  var id = _step4.value;
26267
- var bond = _this6.struct().bonds.get(id);
26342
+ var bond = _this8.struct().bonds.get(id);
26268
26343
  assert_1(bond);
26269
- var attachmentPointWithBondToLeavingAtom = Array.from(_this6.monomerCreationState.assignedAttachmentPoints.entries()).find(function (_ref19) {
26270
- var _ref20 = _slicedToArray__default["default"](_ref19, 2),
26271
- _ref20$ = _slicedToArray__default["default"](_ref20[1], 2),
26272
- leavingAtomId = _ref20$[1];
26344
+ var attachmentPointWithBondToLeavingAtom = Array.from(_this8.monomerCreationState.assignedAttachmentPoints.entries()).find(function (_ref21) {
26345
+ var _ref22 = _slicedToArray__default["default"](_ref21, 2),
26346
+ _ref22$ = _slicedToArray__default["default"](_ref22[1], 2),
26347
+ leavingAtomId = _ref22$[1];
26273
26348
  return bond.begin === leavingAtomId || bond.end === leavingAtomId;
26274
26349
  });
26275
- if (!attachmentPointWithBondToLeavingAtom) {
26276
- return 1;
26350
+ if (attachmentPointWithBondToLeavingAtom) {
26351
+ var _attachmentPointWithB = _slicedToArray__default["default"](attachmentPointWithBondToLeavingAtom, 1),
26352
+ attachmentPointName = _attachmentPointWithB[0];
26353
+ _this8.monomerCreationState.assignedAttachmentPoints["delete"](attachmentPointName);
26354
+ }
26355
+ if (bond.type === ketcherCore.Bond.PATTERN.TYPE.SINGLE && bond.stereo === ketcherCore.Bond.PATTERN.STEREO.NONE) {
26356
+ if (_this8.monomerCreationState.potentialAttachmentPoints.has(bond.begin)) {
26357
+ var leavingAtomIds = _this8.monomerCreationState.potentialAttachmentPoints.get(bond.begin);
26358
+ assert_1(leavingAtomIds);
26359
+ var endAtom = _this8.struct().atoms.get(bond.end);
26360
+ if (endAtom && endAtom.neighbors.length === 1) {
26361
+ var updatedLeavingAtomIds = new Set(leavingAtomIds);
26362
+ updatedLeavingAtomIds.add(bond.end);
26363
+ _this8.monomerCreationState.potentialAttachmentPoints.set(bond.begin, updatedLeavingAtomIds);
26364
+ }
26365
+ }
26366
+ if (_this8.monomerCreationState.potentialAttachmentPoints.has(bond.end)) {
26367
+ var _leavingAtomIds = _this8.monomerCreationState.potentialAttachmentPoints.get(bond.end);
26368
+ assert_1(_leavingAtomIds);
26369
+ var beginAtom = _this8.struct().atoms.get(bond.begin);
26370
+ if (beginAtom && beginAtom.neighbors.length === 1) {
26371
+ var _updatedLeavingAtomIds = new Set(_leavingAtomIds);
26372
+ _updatedLeavingAtomIds.add(bond.begin);
26373
+ _this8.monomerCreationState.potentialAttachmentPoints.set(bond.end, _updatedLeavingAtomIds);
26374
+ }
26375
+ }
26277
26376
  }
26278
- var _attachmentPointWithB = _slicedToArray__default["default"](attachmentPointWithBondToLeavingAtom, 1),
26279
- attachmentPointName = _attachmentPointWithB[0];
26280
- _this6.monomerCreationState.assignedAttachmentPoints["delete"](attachmentPointName);
26281
26377
  };
26282
26378
  for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
26283
- if (_loop3()) continue;
26379
+ _loop3();
26284
26380
  }
26285
26381
  } catch (err) {
26286
26382
  _iterator4.e(err);
@@ -26655,6 +26751,17 @@ var Editor$3 = function () {
26655
26751
  }
26656
26752
  return visited.size === atomIds.length;
26657
26753
  }
26754
+ }, {
26755
+ key: "isStructureImpure",
26756
+ value: function isStructureImpure(struct) {
26757
+ var atoms = struct.atoms,
26758
+ sgroups = struct.sgroups,
26759
+ rgroups = struct.rgroups,
26760
+ functionalGroups = struct.functionalGroups;
26761
+ return sgroups.size > 0 || rgroups.size > 0 || functionalGroups.size > 0 || Array.from(atoms.values()).some(function (atom) {
26762
+ return ketcherCore.genericsList.includes(atom.label);
26763
+ });
26764
+ }
26658
26765
  }]);
26659
26766
  return Editor;
26660
26767
  }();
@@ -26730,10 +26837,10 @@ function domEventSetup(editor, clientArea) {
26730
26837
  eventName: 'mouseover',
26731
26838
  toolEventHandler: 'mouseover'
26732
26839
  }];
26733
- trackedDomEvents.forEach(function (_ref21) {
26734
- var target = _ref21.target,
26735
- eventName = _ref21.eventName,
26736
- toolEventHandler = _ref21.toolEventHandler;
26840
+ trackedDomEvents.forEach(function (_ref23) {
26841
+ var target = _ref23.target,
26842
+ eventName = _ref23.eventName,
26843
+ toolEventHandler = _ref23.toolEventHandler;
26737
26844
  editor.event[eventName] = new subscription.DOMSubscription();
26738
26845
  var subs = editor.event[eventName];
26739
26846
  target.addEventListener(eventName, function () {
@@ -27895,6 +28002,10 @@ var useCreateMonomer = function useCreateMonomer() {
27895
28002
  return [handler, disabled];
27896
28003
  };
27897
28004
 
28005
+ var optionsSelector = function optionsSelector(state) {
28006
+ return state.options;
28007
+ };
28008
+
27898
28009
  function ownKeys$O(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
27899
28010
  function _objectSpread$O(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys$O(Object(t), !0).forEach(function (r) { _defineProperty__default["default"](e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys$O(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
27900
28011
  var bondNames = getBondNames(tools);
@@ -27935,6 +28046,7 @@ var SelectionMenuItems = function SelectionMenuItems(props) {
27935
28046
  color: color === '' ? 'transparent' : color
27936
28047
  });
27937
28048
  };
28049
+ var options = reactRedux.useSelector(optionsSelector);
27938
28050
  return jsxRuntime.jsxs(jsxRuntime.Fragment, {
27939
28051
  children: [jsxRuntime.jsx(reactContexify.Item, _objectSpread$O(_objectSpread$O({}, props), {}, {
27940
28052
  "data-testid": "Edit selected bonds...-option",
@@ -27964,7 +28076,7 @@ var SelectionMenuItems = function SelectionMenuItems(props) {
27964
28076
  })]
27965
28077
  }, name);
27966
28078
  })
27967
- })), jsxRuntime.jsx(reactContexify.Item, _objectSpread$O(_objectSpread$O({}, props), {}, {
28079
+ })), !isHidden(options, ketcherCore.CREATE_MONOMER_TOOL_NAME) && jsxRuntime.jsx(reactContexify.Item, _objectSpread$O(_objectSpread$O({}, props), {}, {
27968
28080
  "data-testid": "Create a monomer-option",
27969
28081
  onClick: handleCreateMonomer,
27970
28082
  disabled: createMonomerDisabled,
@@ -29439,9 +29551,11 @@ var useAttachmentPointSelectsData = function useAttachmentPointSelectsData(edito
29439
29551
  leavingAtomId = _atomPair[1];
29440
29552
  var attachmentAtom = editor.struct().atoms.get(attachmentAtomId);
29441
29553
  assert_1(attachmentAtom);
29442
- var attachmentPointNameOptionsLength = Math.max.apply(Math, _toConsumableArray__default["default"](Array.from(assignedAttachmentPoints.keys()).map(function (name) {
29554
+ var usedNumbers = Array.from(assignedAttachmentPoints.keys()).map(function (name) {
29443
29555
  return ketcherCore.getAttachmentPointNumberFromLabel(name);
29444
- })));
29556
+ });
29557
+ var maxUsedNumber = Math.max.apply(Math, _toConsumableArray__default["default"](usedNumbers));
29558
+ var attachmentPointNameOptionsLength = maxUsedNumber <= 3 ? 3 : Math.min(maxUsedNumber, 8);
29445
29559
  var nameOptions = Array.from({
29446
29560
  length: attachmentPointNameOptionsLength
29447
29561
  }).map(function (_, i) {
@@ -29601,7 +29715,9 @@ var NotificationMessages = {
29601
29715
  noAttachmentPoints: 'The monomer must have at least one attachment point.',
29602
29716
  incorrectAttachmentPointsOrder: 'Attachment point numbers must be in order, but R1 and R2 may be skipped.',
29603
29717
  creationSuccessful: 'The monomer was successfully added to the library.',
29604
- incontinuousStructure: 'All monomers must have a continuous structure.'
29718
+ incontinuousStructure: 'All monomers must have a continuous structure.',
29719
+ notMinimalViableStructure: 'Minimal monomer structure is two atoms connected via a single bond.',
29720
+ impureStructure: 'Monomer structure cannot contain S-groups, R-groups, special atoms, or any other query properties.'
29605
29721
  };
29606
29722
  var NotificationTypes = {
29607
29723
  defaultAttachmentPoints: 'info',
@@ -29612,7 +29728,9 @@ var NotificationTypes = {
29612
29728
  noAttachmentPoints: 'error',
29613
29729
  incorrectAttachmentPointsOrder: 'error',
29614
29730
  creationSuccessful: 'info',
29615
- incontinuousStructure: 'error'
29731
+ incontinuousStructure: 'error',
29732
+ notMinimalViableStructure: 'error',
29733
+ impureStructure: 'error'
29616
29734
  };
29617
29735
  var MonomerCreationExternalNotificationAction = 'MonomerCreationExternalNotification';
29618
29736
 
@@ -29867,6 +29985,21 @@ var validateAttachmentPoints = function validateAttachmentPoints(attachmentPoint
29867
29985
  };
29868
29986
  var validateStructure = function validateStructure(editor) {
29869
29987
  var notifications = new Map();
29988
+ var isStructureImpure = Editor$3.isStructureImpure(editor.struct());
29989
+ if (isStructureImpure) {
29990
+ notifications.set('impureStructure', {
29991
+ type: 'error',
29992
+ message: NotificationMessages.impureStructure
29993
+ });
29994
+ }
29995
+ var isMinimalViableStructure = editor.isMinimalViableStructure();
29996
+ if (!isMinimalViableStructure) {
29997
+ notifications.set('notMinimalViableStructure', {
29998
+ type: 'error',
29999
+ message: NotificationMessages.notMinimalViableStructure
30000
+ });
30001
+ return notifications;
30002
+ }
29870
30003
  var isStructureContinuous = Editor$3.isStructureContinuous(editor.struct());
29871
30004
  if (!isStructureContinuous) {
29872
30005
  notifications.set('incontinuousStructure', {
@@ -36704,6 +36837,11 @@ var TemplateDialog = function TemplateDialog(props) {
36704
36837
  onTabChange(initialTab);
36705
36838
  }
36706
36839
  }, [initialTab, onTabChange]);
36840
+ React.useEffect(function () {
36841
+ if (isMonomerCreationWizardActive && tab === TemplateTabs.FunctionalGroupLibrary) {
36842
+ onTabChange(TemplateTabs.TemplateLibrary);
36843
+ }
36844
+ }, [isMonomerCreationWizardActive, tab, onTabChange]);
36707
36845
  var handleAccordionChange = function handleAccordionChange(accordion) {
36708
36846
  return function (_, isExpanded) {
36709
36847
  setExpandedAccordions(isExpanded ? [].concat(_toConsumableArray__default["default"](expandedAccordions), [accordion]) : _toConsumableArray__default["default"](expandedAccordions).filter(function (expandedAccordion) {
@@ -37911,12 +38049,12 @@ var AbbreviationLookup = function AbbreviationLookup(_ref) {
37911
38049
  });
37912
38050
  },
37913
38051
  renderOption: function renderOption(props, option) {
37914
- return jsxRuntime.jsx("li", _objectSpread$2(_objectSpread$2({}, props), {}, {
38052
+ return React.createElement("li", _objectSpread$2(_objectSpread$2({}, props), {}, {
37915
38053
  title: option.label,
37916
- children: jsxRuntime.jsx("div", {
37917
- className: classes.optionItemContent,
37918
- children: highlightOptionLabel(option, loweredLookupValue)
37919
- })
38054
+ key: option.label
38055
+ }), jsxRuntime.jsx("div", {
38056
+ className: classes.optionItemContent,
38057
+ children: highlightOptionLabel(option, loweredLookupValue)
37920
38058
  }));
37921
38059
  },
37922
38060
  "data-testid": ABBREVIATION_LOOKUP_TEST_ID
@@ -38194,8 +38332,8 @@ var KetcherBuilder = function () {
38194
38332
  cleanup = initApp(prevKetcherId, ketcherId, element, appRoot, staticResourcesUrl, {
38195
38333
  buttons: buttons || {},
38196
38334
  errorHandler: errorHandler || null,
38197
- version: "3.9.0-rc.1" ,
38198
- buildDate: "2025-10-02T16:45:46" ,
38335
+ version: "3.9.0-rc.3" ,
38336
+ buildDate: "2025-10-22T18:27:52" ,
38199
38337
  buildNumber: '',
38200
38338
  customButtons: customButtons || []
38201
38339
  }, structService, resolve, togglerComponent);
@@ -38490,7 +38628,7 @@ var ModeControl = function ModeControl(_ref3) {
38490
38628
  function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
38491
38629
  function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty__default["default"](e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
38492
38630
  var MacromoleculesEditorComponent = React.lazy(function () {
38493
- return Promise.resolve().then(function () { return require('./index.modern-798ecc56.js'); });
38631
+ return Promise.resolve().then(function () { return require('./index.modern-1f472704.js'); });
38494
38632
  });
38495
38633
  var Editor = function Editor(props) {
38496
38634
  var _useState = React.useState(false),