ketcher-react 2.8.0-rc.2-dev → 2.8.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/index.js CHANGED
@@ -3069,7 +3069,7 @@ var zoom = {
3069
3069
 
3070
3070
  var openHelpLink = function openHelpLink() {
3071
3071
  var _window$open;
3072
- return (_window$open = window.open("https://github.com/epam/ketcher/blob/".concat("v2.8.0-rc.2-dev\n", "/documentation/help.md#ketcher-overview"))) === null || _window$open === void 0 ? void 0 : _window$open.focus();
3072
+ return (_window$open = window.open("https://github.com/epam/ketcher/blob/".concat("v2.8.0-rc.3\n", "/documentation/help.md#ketcher-overview"))) === null || _window$open === void 0 ? void 0 : _window$open.focus();
3073
3073
  };
3074
3074
  var help = {
3075
3075
  help: {
@@ -10212,7 +10212,7 @@ var APointTool = function () {
10212
10212
  var closestItem = this.editor.findItem(event, ['atoms']);
10213
10213
  if (closestItem) {
10214
10214
  var atom = struct.atoms.get(closestItem.id);
10215
- if ((atom === null || atom === void 0 ? void 0 : atom.label) !== 'R#' && (atom === null || atom === void 0 ? void 0 : atom.rglabel) === null) this.editor.hover(closestItem);
10215
+ if ((atom === null || atom === void 0 ? void 0 : atom.label) !== 'R#' && (atom === null || atom === void 0 ? void 0 : atom.rglabel) === null) this.editor.hover(closestItem, null, event);
10216
10216
  } else {
10217
10217
  this.editor.hover(null);
10218
10218
  }
@@ -11755,7 +11755,7 @@ var SGroupTool = function () {
11755
11755
  if (this.lassoHelper.running(event)) {
11756
11756
  this.editor.selection(this.lassoHelper.addPoint(event));
11757
11757
  } else {
11758
- this.editor.hover(this.editor.findItem(event, searchMaps));
11758
+ this.editor.hover(this.editor.findItem(event, searchMaps), null, event);
11759
11759
  }
11760
11760
  }
11761
11761
  }, {
@@ -12079,6 +12079,68 @@ function countOfSelectedComponents(restruct, atoms) {
12079
12079
  }, 0);
12080
12080
  }
12081
12081
 
12082
+ function isAtomsArray(selectedElements) {
12083
+ return Array.isArray(selectedElements) && (selectedElements === null || selectedElements === void 0 ? void 0 : selectedElements.every(function (element) {
12084
+ return element instanceof ketcherCore.Atom;
12085
+ }));
12086
+ }
12087
+ function generateCommonProperties(selectedElements) {
12088
+ var normalizedAtom = fromElement(selectedElements[0]);
12089
+ var properties = Object.getOwnPropertyNames(normalizedAtom);
12090
+ var resultAtomAttributes = {};
12091
+ properties.forEach(function (property) {
12092
+ var uniqueValues = new Set();
12093
+ selectedElements.forEach(function (element) {
12094
+ uniqueValues.add(element[property]);
12095
+ });
12096
+ var allAtomsHaveTheSameValue = uniqueValues.size === 1;
12097
+ if (allAtomsHaveTheSameValue) {
12098
+ resultAtomAttributes[property] = normalizedAtom[property];
12099
+ } else {
12100
+ resultAtomAttributes[property] = '';
12101
+ }
12102
+ });
12103
+ return resultAtomAttributes;
12104
+ }
12105
+ function updateOnlyChangedProperties(atomId, userChangedAtom, molecule) {
12106
+ var unchangedAtom = molecule.atoms.get(atomId);
12107
+ var updatedKeys = Object.getOwnPropertyNames(userChangedAtom).filter(function (key) {
12108
+ return userChangedAtom[key] !== '';
12109
+ });
12110
+ return Object.getOwnPropertyNames(unchangedAtom).reduce(function (updatedAtom, key) {
12111
+ var isPropertyChanged = updatedKeys.includes(key);
12112
+ if (isPropertyChanged) {
12113
+ updatedAtom[key] = userChangedAtom[key];
12114
+ if (key === 'charge') {
12115
+ updatedAtom[key] = Number(updatedAtom[key]);
12116
+ }
12117
+ } else {
12118
+ updatedAtom[key] = unchangedAtom[key];
12119
+ }
12120
+ return updatedAtom;
12121
+ }, {});
12122
+ }
12123
+ function updateSelectedAtoms(_ref) {
12124
+ var selection = _ref.selection,
12125
+ changeAtomPromise = _ref.changeAtomPromise,
12126
+ editor = _ref.editor;
12127
+ var action = new ketcherCore.Action();
12128
+ var struct = editor.render.ctab;
12129
+ var molecule = struct.molecule;
12130
+ if (selection !== null && selection !== void 0 && selection.atoms) {
12131
+ var selectionAtoms = selection.atoms;
12132
+ Promise.resolve(changeAtomPromise).then(function (userChangedAtom) {
12133
+ selectionAtoms.forEach(function (atomId) {
12134
+ var atomWithChangedProperties = updateOnlyChangedProperties(atomId, userChangedAtom, molecule);
12135
+ action.mergeWith(ketcherCore.fromAtomsAttrs(struct, atomId, atomWithChangedProperties, false));
12136
+ });
12137
+ editor.update(action);
12138
+ })["catch"](function () {
12139
+ return null;
12140
+ });
12141
+ }
12142
+ }
12143
+
12082
12144
  function ownKeys$M(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
12083
12145
  function _objectSpread$M(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys$M(Object(source), !0).forEach(function (key) { _defineProperty__default["default"](target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys$M(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
12084
12146
  function _createForOfIteratorHelper$9(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray$9(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it["return"] != null) it["return"](); } finally { if (didErr) throw err; } } }; }
@@ -12456,32 +12518,25 @@ var SelectTool = function () {
12456
12518
  if (!ci) return true;
12457
12519
  var selection = this.editor.selection();
12458
12520
  if (ci.map === 'atoms') {
12459
- var action = new ketcherCore.Action();
12460
- var atom = molecule.atoms.get(ci.id);
12461
- var ra = editor.event.elementEdit.dispatch(atom);
12462
- if (selection !== null && selection !== void 0 && selection.atoms) {
12463
- var selectionAtoms = selection.atoms;
12464
- Promise.resolve(ra).then(function (newatom) {
12465
- selectionAtoms.forEach(function (aid) {
12466
- action.mergeWith(ketcherCore.fromAtomsAttrs(struct, aid, newatom, false));
12467
- });
12468
- editor.update(action);
12469
- })["catch"](function () {
12470
- return null;
12471
- });
12472
- }
12521
+ var atoms = getSelectedAtoms(selection, molecule);
12522
+ var changeAtomPromise = editor.event.elementEdit.dispatch(atoms);
12523
+ updateSelectedAtoms({
12524
+ selection: selection,
12525
+ editor: editor,
12526
+ changeAtomPromise: changeAtomPromise
12527
+ });
12473
12528
  } else if (ci.map === 'bonds') {
12474
12529
  var _rnd$ctab$bonds$get;
12475
12530
  var bond = (_rnd$ctab$bonds$get = rnd.ctab.bonds.get(ci.id)) === null || _rnd$ctab$bonds$get === void 0 ? void 0 : _rnd$ctab$bonds$get.b;
12476
12531
  var rb = editor.event.bondEdit.dispatch(bond);
12477
12532
  if (selection !== null && selection !== void 0 && selection.bonds) {
12478
- var _action = new ketcherCore.Action();
12533
+ var action = new ketcherCore.Action();
12479
12534
  var bondsSelection = selection.bonds;
12480
12535
  Promise.resolve(rb).then(function (newbond) {
12481
12536
  bondsSelection.forEach(function (bid) {
12482
- _action.mergeWith(ketcherCore.fromBondsAttrs(struct, bid, newbond));
12537
+ action.mergeWith(ketcherCore.fromBondsAttrs(struct, bid, newbond));
12483
12538
  });
12484
- editor.update(_action);
12539
+ editor.update(action);
12485
12540
  })["catch"](function () {
12486
12541
  return null;
12487
12542
  });
@@ -12566,6 +12621,18 @@ function selMerge(selection, add, reversible) {
12566
12621
  function isSelected(selection, item) {
12567
12622
  return selection && selection[item.map] && selection[item.map].includes(item.id);
12568
12623
  }
12624
+ function getSelectedAtoms(selection, molecule) {
12625
+ if (selection !== null && selection !== void 0 && selection.atoms) {
12626
+ return mapAtomIdsToAtoms(selection === null || selection === void 0 ? void 0 : selection.atoms, molecule);
12627
+ }
12628
+ return [];
12629
+ }
12630
+ function mapAtomIdsToAtoms(atomsIds, molecule) {
12631
+ return atomsIds.map(function (atomId) {
12632
+ var atomOrReAtom = molecule.atoms.get(atomId);
12633
+ return atomOrReAtom.a || atomOrReAtom;
12634
+ });
12635
+ }
12569
12636
  function uniqArray(dest, add, reversible) {
12570
12637
  return add.reduce(function (_, item) {
12571
12638
  if (reversible) dest = fp.xor(dest, [item]);else if (!dest.includes(item)) dest.push(item);
@@ -12614,7 +12681,7 @@ var EraserTool = function () {
12614
12681
  if (this.lassoHelper.running()) {
12615
12682
  this.editor.selection(this.lassoHelper.addPoint(event));
12616
12683
  } else {
12617
- this.editor.hover(this.editor.findItem(event, this.maps));
12684
+ this.editor.hover(this.editor.findItem(event, this.maps), null, event);
12618
12685
  }
12619
12686
  }
12620
12687
  }, {
@@ -12750,9 +12817,8 @@ var EraserTool = function () {
12750
12817
  value: function click(event) {
12751
12818
  var rnd = this.editor.render;
12752
12819
  var restruct = rnd.ctab;
12753
- var struct = this.editor.render.ctab;
12754
- var sgroups = struct.sgroups;
12755
- var molecule = struct.molecule;
12820
+ var sgroups = restruct.sgroups;
12821
+ var molecule = restruct.molecule;
12756
12822
  var functionalGroups = molecule.functionalGroups;
12757
12823
  var ci = this.editor.findItem(event, this.maps);
12758
12824
  var atomResult = [];
@@ -12764,16 +12830,16 @@ var EraserTool = function () {
12764
12830
  result.push(ci.id);
12765
12831
  }
12766
12832
  } else if (ci && functionalGroups && ci.map === 'atoms') {
12767
- var _struct$atoms$get2;
12833
+ var _restruct$atoms$get;
12768
12834
  var atomId = ketcherCore.FunctionalGroup.atomsInFunctionalGroup(functionalGroups, ci.id);
12769
- var atomFromStruct = atomId !== null && ((_struct$atoms$get2 = struct.atoms.get(atomId)) === null || _struct$atoms$get2 === void 0 ? void 0 : _struct$atoms$get2.a);
12835
+ var atomFromStruct = atomId !== null && ((_restruct$atoms$get = restruct.atoms.get(atomId)) === null || _restruct$atoms$get === void 0 ? void 0 : _restruct$atoms$get.a);
12770
12836
  if (atomFromStruct && !ketcherCore.FunctionalGroup.isAtomInContractedFunctionalGroup(atomFromStruct, sgroups, functionalGroups, true)) {
12771
12837
  atomResult.push(atomId);
12772
12838
  }
12773
12839
  } else if (ci && functionalGroups && ci.map === 'bonds') {
12774
- var _struct$bonds$get2;
12840
+ var _restruct$bonds$get;
12775
12841
  var bondId = ketcherCore.FunctionalGroup.bondsInFunctionalGroup(molecule, functionalGroups, ci.id);
12776
- var bondFromStruct = bondId !== null && ((_struct$bonds$get2 = struct.bonds.get(bondId)) === null || _struct$bonds$get2 === void 0 ? void 0 : _struct$bonds$get2.b);
12842
+ var bondFromStruct = bondId !== null && ((_restruct$bonds$get = restruct.bonds.get(bondId)) === null || _restruct$bonds$get === void 0 ? void 0 : _restruct$bonds$get.b);
12777
12843
  if (bondFromStruct && !ketcherCore.FunctionalGroup.isBondInContractedFunctionalGroup(bondFromStruct, sgroups, functionalGroups, true)) {
12778
12844
  bondResult.push(bondId);
12779
12845
  }
@@ -12901,7 +12967,10 @@ var HandTool = function () {
12901
12967
  this.editor.event.cursor.dispatch({
12902
12968
  status: 'move'
12903
12969
  });
12904
- if (this.begPos == null) return;
12970
+ this.editor.hover(this.editor.findItem(event, ['atoms', 'bonds'], null), null, event);
12971
+ if (this.begPos == null) {
12972
+ return;
12973
+ }
12905
12974
  var clientX = event.clientX,
12906
12975
  clientY = event.clientY;
12907
12976
  this.endPos = new ketcherCore.Vec2(clientX, clientY);
@@ -13122,7 +13191,7 @@ var RGroupAtomTool = function () {
13122
13191
  var ci = this.editor.findItem(event, ['atoms']);
13123
13192
  if (ci) {
13124
13193
  var atom = struct.atoms.get(ci.id);
13125
- if ((atom === null || atom === void 0 ? void 0 : atom.attpnt) === null) this.editor.hover(ci);
13194
+ if ((atom === null || atom === void 0 ? void 0 : atom.attpnt) === null) this.editor.hover(ci, null, event);
13126
13195
  } else {
13127
13196
  this.editor.hover(null);
13128
13197
  }
@@ -13220,7 +13289,7 @@ var RGroupFragmentTool = function () {
13220
13289
  _createClass__default["default"](RGroupFragmentTool, [{
13221
13290
  key: "mousemove",
13222
13291
  value: function mousemove(event) {
13223
- this.editor.hover(this.editor.findItem(event, ['frags', 'rgroups']));
13292
+ this.editor.hover(this.editor.findItem(event, ['frags', 'rgroups']), null, event);
13224
13293
  }
13225
13294
  }, {
13226
13295
  key: "click",
@@ -13487,7 +13556,7 @@ var ReactionMapTool = function () {
13487
13556
  this.updateLine((_atoms$get3 = atoms.get(this.dragCtx.item.id)) === null || _atoms$get3 === void 0 ? void 0 : _atoms$get3.pp, rnd.page2obj(event));
13488
13557
  }
13489
13558
  } else {
13490
- editor.hover(editor.findItem(event, ['atoms']));
13559
+ editor.hover(editor.findItem(event, ['atoms']), null, event);
13491
13560
  }
13492
13561
  }
13493
13562
  }, {
@@ -13585,7 +13654,7 @@ var ReactionPlusTool = function () {
13585
13654
  this.dragCtx.action = ketcherCore.fromMultipleMove(rnd.ctab, this.editor.selection() || {}, rnd.page2obj(event).sub(this.dragCtx.xy0));
13586
13655
  editor.update(this.dragCtx.action, true);
13587
13656
  } else {
13588
- editor.hover(editor.findItem(event, ['rxnPluses']));
13657
+ editor.hover(editor.findItem(event, ['rxnPluses']), null, event);
13589
13658
  }
13590
13659
  }
13591
13660
  }, {
@@ -13625,7 +13694,7 @@ var ReactionUnmapTool = function () {
13625
13694
  var ci = this.editor.findItem(event, ['atoms']);
13626
13695
  if (ci && ci.map === 'atoms') {
13627
13696
  var _this$editor$render$c;
13628
- this.editor.hover((_this$editor$render$c = this.editor.render.ctab.molecule.atoms.get(ci.id)) !== null && _this$editor$render$c !== void 0 && _this$editor$render$c.aam ? ci : null);
13697
+ this.editor.hover((_this$editor$render$c = this.editor.render.ctab.molecule.atoms.get(ci.id)) !== null && _this$editor$render$c !== void 0 && _this$editor$render$c.aam ? ci : null, null, event);
13629
13698
  } else {
13630
13699
  this.editor.hover(null);
13631
13700
  }
@@ -13740,6 +13809,7 @@ var RotateTool = function () {
13740
13809
  key: "mousemove",
13741
13810
  value: function mousemove(event) {
13742
13811
  if (!this.dragCtx) {
13812
+ this.editor.hover(null, null, event);
13743
13813
  return true;
13744
13814
  }
13745
13815
  var rnd = this.editor.render;
@@ -13763,7 +13833,7 @@ var RotateTool = function () {
13763
13833
  });
13764
13834
  var expSel = this.editor.explicitSelected();
13765
13835
  dragCtx.mergeItems = ketcherCore.getItemsToFuse(this.editor, expSel);
13766
- this.editor.hover(ketcherCore.getHoverToFuse(dragCtx.mergeItems));
13836
+ this.editor.hover(ketcherCore.getHoverToFuse(dragCtx.mergeItems), null, event);
13767
13837
  this.editor.update(dragCtx.action, true);
13768
13838
  return true;
13769
13839
  }
@@ -13861,7 +13931,7 @@ var SimpleObjectTool = function () {
13861
13931
  }
13862
13932
  } else {
13863
13933
  var items = this.editor.findItem(event, ['simpleObjects']);
13864
- this.editor.hover(items);
13934
+ this.editor.hover(items, null, event);
13865
13935
  }
13866
13936
  }
13867
13937
  }, {
@@ -13892,7 +13962,7 @@ var TemplateTool = function () {
13892
13962
  function TemplateTool(editor, tmpl) {
13893
13963
  _classCallCheck__default["default"](this, TemplateTool);
13894
13964
  this.editor = editor;
13895
- this.mode = tmpl.mode;
13965
+ this.mode = getTemplateMode(tmpl);
13896
13966
  this.editor.selection(null);
13897
13967
  this.template = {
13898
13968
  aid: parseInt(tmpl.aid) || 0,
@@ -13907,6 +13977,7 @@ var TemplateTool = function () {
13907
13977
  this.template.molecule = frag;
13908
13978
  this.findItems = [];
13909
13979
  this.template.xy0 = xy0.scaled(1 / (frag.atoms.size || 1));
13980
+ this.findItems.push('functionalGroups');
13910
13981
  var atom = frag.atoms.get(this.template.aid);
13911
13982
  if (atom) {
13912
13983
  this.template.angle0 = utils.calcAngle(atom.pp, this.template.xy0);
@@ -13997,7 +14068,7 @@ var TemplateTool = function () {
13997
14068
  _iterator3.f();
13998
14069
  }
13999
14070
  }
14000
- if (result.length) {
14071
+ if (result.length && (this.mode !== 'fg' || ketcherCore.SGroup.isSaltOrSolvent(this.template.molecule.name))) {
14001
14072
  this.editor.event.removeFG.dispatch({
14002
14073
  fgIds: result
14003
14074
  });
@@ -14103,6 +14174,9 @@ var TemplateTool = function () {
14103
14174
  extraBond = this.mode === 'fg' ? true : ketcherCore.Vec2.dist(pos0, pos1) > 1;
14104
14175
  }
14105
14176
  }
14177
+ if (!pos0) {
14178
+ return true;
14179
+ }
14106
14180
  var angle = utils.calcAngle(pos0, pos1);
14107
14181
  if (!event.ctrlKey) {
14108
14182
  angle = utils.fracAngle(angle, null);
@@ -14147,8 +14221,10 @@ var TemplateTool = function () {
14147
14221
  }
14148
14222
  delete this.dragCtx;
14149
14223
  var restruct = this.editor.render.ctab;
14224
+ var sgroups = restruct.sgroups;
14150
14225
  var struct = restruct.molecule;
14151
14226
  var ci = dragCtx.item;
14227
+ var functionalGroups = struct.functionalGroups;
14152
14228
  if (dragCtx.action && ci && ci.map === 'bonds' && this.mode !== 'fg') {
14153
14229
  dragCtx.action.perform(restruct);
14154
14230
  var promise = ketcherCore.fromTemplateOnBondAction(restruct, this.template, ci.id, this.editor.event, dragCtx.sign1 * dragCtx.sign2 > 0, true);
@@ -14164,12 +14240,20 @@ var TemplateTool = function () {
14164
14240
  }
14165
14241
  var action;
14166
14242
  var pasteItems = null;
14243
+ var isFunctionalGroupReplace = false;
14167
14244
  if (ketcherCore.SGroup.isSaltOrSolvent(this.template.molecule.name)) {
14168
14245
  addSaltsAndSolventsOnCanvasWithoutMerge(restruct, this.template, dragCtx, this.editor);
14169
14246
  return true;
14247
+ } else if ((ci === null || ci === void 0 ? void 0 : ci.map) === 'functionalGroups' && ketcherCore.FunctionalGroup.isContractedFunctionalGroup(ci.id, functionalGroups) && this.mode === 'fg') {
14248
+ var sGroup = sgroups.get(ci.id);
14249
+ this.editor.update(ketcherCore.fromFragmentDeletion(this.editor.render.ctab, {
14250
+ atoms: _toConsumableArray__default["default"](ketcherCore.SGroup.getAtoms(struct, sGroup === null || sGroup === void 0 ? void 0 : sGroup.item)),
14251
+ bonds: _toConsumableArray__default["default"](ketcherCore.SGroup.getBonds(struct, sGroup === null || sGroup === void 0 ? void 0 : sGroup.item))
14252
+ }));
14253
+ isFunctionalGroupReplace = true;
14170
14254
  }
14171
14255
  if (!dragCtx.action) {
14172
- if (!ci) {
14256
+ if (!ci || isFunctionalGroupReplace) {
14173
14257
  var _fromTemplateOnCanvas = ketcherCore.fromTemplateOnCanvas(restruct, this.template, dragCtx.xy0, 0);
14174
14258
  var _fromTemplateOnCanvas2 = _slicedToArray__default["default"](_fromTemplateOnCanvas, 2);
14175
14259
  action = _fromTemplateOnCanvas2[0];
@@ -14219,14 +14303,15 @@ var TemplateTool = function () {
14219
14303
  dragCtx.mergeItems = ketcherCore.getItemsToFuse(this.editor, pasteItems);
14220
14304
  }
14221
14305
  dragCtx.action = dragCtx.action ? ketcherCore.fromItemsFuse(restruct, dragCtx.mergeItems).mergeWith(dragCtx.action) : ketcherCore.fromItemsFuse(restruct, dragCtx.mergeItems);
14222
- this.editor.hover(null);
14223
14306
  var completeAction = dragCtx.action;
14224
14307
  if (completeAction && !completeAction.isDummy()) {
14225
14308
  this.editor.update(completeAction);
14226
14309
  }
14310
+ this.editor.event.showInfo.dispatch(null);
14227
14311
  this.editor.event.message.dispatch({
14228
14312
  info: false
14229
14313
  });
14314
+ this.editor.hover(this.editor.findItem(event, this.findItems), null, event);
14230
14315
  return true;
14231
14316
  }
14232
14317
  }, {
@@ -14253,6 +14338,12 @@ function addSaltsAndSolventsOnCanvasWithoutMerge(restruct, template, dragCtx, ed
14253
14338
  info: false
14254
14339
  });
14255
14340
  }
14341
+ function getTemplateMode(tmpl) {
14342
+ var _tmpl$props;
14343
+ if (tmpl.mode) return tmpl.mode;
14344
+ if (['Functional Groups', 'Salts and Solvents'].includes((_tmpl$props = tmpl.props) === null || _tmpl$props === void 0 ? void 0 : _tmpl$props.group)) return 'fg';
14345
+ return null;
14346
+ }
14256
14347
  function getSign(molecule, bond, v) {
14257
14348
  var begin = molecule.atoms.get(bond.begin).pp;
14258
14349
  var end = molecule.atoms.get(bond.end).pp;
@@ -14907,7 +14998,9 @@ var Dialog = function Dialog(props) {
14907
14998
  };
14908
14999
  var exit = function exit(mode) {
14909
15000
  var key = isButtonOk(mode) ? 'onOk' : 'onCancel';
14910
- if (params && key in params && (key !== 'onOk' || valid())) params[key](result());
15001
+ if (params && key in params && (key !== 'onOk' || valid())) {
15002
+ params[key](result());
15003
+ }
14911
15004
  };
14912
15005
  var keyDown = function keyDown(event) {
14913
15006
  var key = KN__namespace.keyName(event);
@@ -16388,42 +16481,27 @@ var AtomBatchEdit = function AtomBatchEdit(props) {
16388
16481
  getKetcherInstance = _useAppContext2.getKetcherInstance;
16389
16482
  var isDisabled = useDisabled$1();
16390
16483
  var handleClick = React.useCallback( _asyncToGenerator__default["default"]( _regeneratorRuntime__default["default"].mark(function _callee() {
16391
- var editor, defaultAtom, _editor$selection2, newAtom, selectedAtomIds;
16484
+ var editor, molecule, selection, selectedAtoms, newAtom;
16392
16485
  return _regeneratorRuntime__default["default"].wrap(function _callee$(_context) {
16393
16486
  while (1) {
16394
16487
  switch (_context.prev = _context.next) {
16395
16488
  case 0:
16396
16489
  editor = getKetcherInstance().editor;
16397
- defaultAtom = toElement({
16398
- label: 'C',
16399
- charge: 0,
16400
- isotope: 0,
16401
- explicitValence: -1,
16402
- radical: 0,
16403
- invRet: 0,
16404
- ringBondCount: 0,
16405
- substitutionCount: 0,
16406
- hCount: 0,
16407
- stereoParity: 0
16490
+ molecule = editor.render.ctab;
16491
+ selection = editor.selection();
16492
+ selectedAtoms = getSelectedAtoms(selection, molecule);
16493
+ newAtom = editor.event.elementEdit.dispatch(selectedAtoms);
16494
+ updateSelectedAtoms({
16495
+ selection: selection,
16496
+ changeAtomPromise: newAtom,
16497
+ editor: editor
16408
16498
  });
16409
- _context.prev = 2;
16410
- _context.next = 5;
16411
- return editor.event.elementEdit.dispatch(defaultAtom);
16412
- case 5:
16413
- newAtom = _context.sent;
16414
- selectedAtomIds = (_editor$selection2 = editor.selection()) === null || _editor$selection2 === void 0 ? void 0 : _editor$selection2.atoms;
16415
- editor.update(ketcherCore.fromAtomsAttrs(editor.render.ctab, selectedAtomIds, newAtom, false));
16416
- _context.next = 13;
16417
- break;
16418
- case 10:
16419
- _context.prev = 10;
16420
- _context.t0 = _context["catch"](2);
16421
- case 13:
16499
+ case 6:
16422
16500
  case "end":
16423
16501
  return _context.stop();
16424
16502
  }
16425
16503
  }
16426
- }, _callee, null, [[2, 10]]);
16504
+ }, _callee);
16427
16505
  })), [getKetcherInstance]);
16428
16506
  return jsxRuntime.jsx(reactContexify.Item, _objectSpread$I(_objectSpread$I({}, props), {}, {
16429
16507
  hidden: isBatchOperationHidden,
@@ -16469,7 +16547,7 @@ var AtomStereoBatchEdit = function AtomStereoBatchEdit(props) {
16469
16547
  }, _callee2, null, [[3, 10]]);
16470
16548
  })), [getKetcherInstance]);
16471
16549
  var isStereoDisabled = React.useCallback(function (_ref4) {
16472
- var _editor$selection3;
16550
+ var _editor$selection2;
16473
16551
  var props = _ref4.props,
16474
16552
  triggerEvent = _ref4.triggerEvent;
16475
16553
  if (isDisabled({
@@ -16479,7 +16557,7 @@ var AtomStereoBatchEdit = function AtomStereoBatchEdit(props) {
16479
16557
  return true;
16480
16558
  }
16481
16559
  var editor = getKetcherInstance().editor;
16482
- var selectedAtomIds = (_editor$selection3 = editor.selection()) === null || _editor$selection3 === void 0 ? void 0 : _editor$selection3.atoms;
16560
+ var selectedAtomIds = (_editor$selection2 = editor.selection()) === null || _editor$selection2 === void 0 ? void 0 : _editor$selection2.atoms;
16483
16561
  var stereoAtomIds = ketcherCore.findStereoAtoms(editor.struct(), selectedAtomIds);
16484
16562
  stereoAtomIdsRef.current = stereoAtomIds;
16485
16563
  if (Array.isArray(stereoAtomIds) && stereoAtomIds.length !== 0) {
@@ -16831,11 +16909,23 @@ var ContextMenu = function ContextMenu() {
16831
16909
  return jsxRuntime.jsxs(reactContexify.Menu, {
16832
16910
  id: CONTEXT_MENU_ID,
16833
16911
  animation: false,
16834
- className: styles$b.contextMenu,
16912
+ className: "".concat(CONTEXT_MENU_ID, " ").concat(styles$b.contextMenu),
16835
16913
  children: [jsxRuntime.jsx(BondSingleOperations, {}), jsxRuntime.jsx(AtomSingleOperations, {}), jsxRuntime.jsx(BondBatchEdit, {}), jsxRuntime.jsx(AtomBatchEdit, {}), jsxRuntime.jsx(BondTypeBatchChange, {}), jsxRuntime.jsx(AtomStereoBatchEdit, {}), jsxRuntime.jsx(BatchDelete, {})]
16836
16914
  });
16837
16915
  };
16838
16916
 
16917
+ var fixContextMenuPosition = function fixContextMenuPosition() {
16918
+ var contextMenu = document.querySelector(".".concat(CONTEXT_MENU_ID));
16919
+ if (contextMenu) {
16920
+ var computedStyles = getComputedStyle(contextMenu);
16921
+ var contextMenuHeight = parseInt(computedStyles.height);
16922
+ var currentTopPosition = parseInt(contextMenu.style.top);
16923
+ var screenSize = document.body.clientHeight;
16924
+ if (currentTopPosition + contextMenuHeight > screenSize) {
16925
+ contextMenu.style.top = screenSize - contextMenuHeight + 'px';
16926
+ }
16927
+ }
16928
+ };
16839
16929
  var ContextMenuTrigger = function ContextMenuTrigger(_ref) {
16840
16930
  var children = _ref.children;
16841
16931
  var _useAppContext = useAppContext(),
@@ -16906,6 +16996,7 @@ var ContextMenuTrigger = function ContextMenuTrigger(_ref) {
16906
16996
  }
16907
16997
  });
16908
16998
  }
16999
+ fixContextMenuPosition();
16909
17000
  }, [getKetcherInstance, hasConflictWithFunctionalGroupMenu, hideAll, show]);
16910
17001
  return jsxRuntime.jsx("div", {
16911
17002
  style: {
@@ -17551,7 +17642,7 @@ var _excluded$p = ["schema", "value", "onChange", "innerRef", "type", "isFocused
17551
17642
  _excluded3$1 = ["schema", "value", "onChange", "innerRef"],
17552
17643
  _excluded4$1 = ["schema", "value", "selected", "onSelect", "type", "checked"],
17553
17644
  _excluded5$1 = ["value", "onChange", "name"],
17554
- _excluded6 = ["Component"],
17645
+ _excluded6$1 = ["Component"],
17555
17646
  _excluded7 = ["children", "onChange"];
17556
17647
  function _createSuper$8(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$8(); return function _createSuperInternal() { var Super = _getPrototypeOf__default["default"](Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf__default["default"](this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn__default["default"](this, result); }; }
17557
17648
  function _isNativeReflectConstruct$8() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
@@ -17568,9 +17659,9 @@ function GenericInput(_ref) {
17568
17659
  _ref$isFocused = _ref.isFocused,
17569
17660
  isFocused = _ref$isFocused === void 0 ? false : _ref$isFocused,
17570
17661
  props = _objectWithoutProperties__default["default"](_ref, _excluded$p);
17571
- var inputRef = React.useRef(null);
17662
+ var inputRef = React.useRef(innerRef);
17572
17663
  React.useEffect(function () {
17573
- if (innerRef !== null && innerRef !== void 0 && innerRef.current && inputRef.current) {
17664
+ if (innerRef && inputRef.current) {
17574
17665
  innerRef.current = inputRef.current;
17575
17666
  }
17576
17667
  }, [innerRef]);
@@ -17617,9 +17708,9 @@ function CheckBox(_ref3) {
17617
17708
  _ref3.schema;
17618
17709
  var _ref3$value = _ref3.value,
17619
17710
  value = _ref3$value === void 0 ? '' : _ref3$value,
17620
- onChange = _ref3.onChange;
17621
- _ref3.innerRef;
17622
- var rest = _objectWithoutProperties__default["default"](_ref3, _excluded3$1);
17711
+ onChange = _ref3.onChange,
17712
+ innerRef = _ref3.innerRef,
17713
+ rest = _objectWithoutProperties__default["default"](_ref3, _excluded3$1);
17623
17714
  return jsxRuntime.jsxs("div", {
17624
17715
  className: classes$A.fieldSetItem,
17625
17716
  children: [jsxRuntime.jsx("input", _objectSpread$A({
@@ -17627,7 +17718,8 @@ function CheckBox(_ref3) {
17627
17718
  checked: Boolean(value),
17628
17719
  onClick: onChange,
17629
17720
  onChange: onChange,
17630
- className: classes$A.input
17721
+ className: classes$A.input,
17722
+ ref: innerRef
17631
17723
  }, rest)), jsxRuntime.jsx("span", {
17632
17724
  className: classes$A.checkbox
17633
17725
  })]
@@ -17816,7 +17908,7 @@ function componentMap(props) {
17816
17908
  }
17817
17909
  var AnyComponentWithRef = React__default["default"].forwardRef(function (_ref7, ref) {
17818
17910
  var Component = _ref7.Component,
17819
- props = _objectWithoutProperties__default["default"](_ref7, _excluded6);
17911
+ props = _objectWithoutProperties__default["default"](_ref7, _excluded6$1);
17820
17912
  return jsxRuntime.jsx(Component, _objectSpread$A(_objectSpread$A({}, props), {}, {
17821
17913
  innerRef: ref
17822
17914
  }));
@@ -17911,7 +18003,8 @@ var _excluded$o = ["schema", "result", "customValid"],
17911
18003
  _excluded2$3 = ["labelPos", "title", "children"],
17912
18004
  _excluded3 = ["name", "onChange", "component", "labelPos", "className"],
17913
18005
  _excluded4 = ["dataError"],
17914
- _excluded5 = ["title", "name", "schema"];
18006
+ _excluded5 = ["title", "name", "schema"],
18007
+ _excluded6 = ["pattern", "maxLength", "enum", "enumNames"];
17915
18008
  function ownKeys$z(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
17916
18009
  function _objectSpread$z(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys$z(Object(source), !0).forEach(function (key) { _defineProperty__default["default"](target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys$z(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
17917
18010
  function _createSuper$7(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$7(); return function _createSuperInternal() { var Super = _getPrototypeOf__default["default"](Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf__default["default"](this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn__default["default"](this, result); }; }
@@ -18110,23 +18203,31 @@ function propSchema(schema, _ref2) {
18110
18203
  verbose: true,
18111
18204
  strictSchema: false
18112
18205
  });
18206
+ var schemaCopy = lodash.cloneDeep(schema);
18113
18207
  if (customValid) {
18114
- schema = Object.assign({}, schema);
18115
- schema.properties = Object.keys(customValid).reduce(function (res, prop) {
18116
- ajv.addFormat(customValid[prop].name, customValid[prop]);
18117
- res[prop] = _objectSpread$z({
18118
- format: prop
18119
- }, res[prop]);
18120
- return res;
18121
- }, schema.properties);
18208
+ Object.entries(customValid).forEach(function (_ref3) {
18209
+ var _ref4 = _slicedToArray__default["default"](_ref3, 2),
18210
+ formatName = _ref4[0],
18211
+ formatValidator = _ref4[1];
18212
+ ajv.addFormat(formatName, formatValidator);
18213
+ var _schemaCopy$propertie = schemaCopy.properties[formatName];
18214
+ _schemaCopy$propertie.pattern;
18215
+ _schemaCopy$propertie.maxLength;
18216
+ _schemaCopy$propertie["enum"];
18217
+ _schemaCopy$propertie.enumNames;
18218
+ var rest = _objectWithoutProperties__default["default"](_schemaCopy$propertie, _excluded6);
18219
+ schemaCopy.properties[formatName] = _objectSpread$z(_objectSpread$z({}, rest), {}, {
18220
+ format: formatName
18221
+ });
18222
+ });
18122
18223
  }
18123
- var validate = ajv.compile(schema);
18224
+ var validate = ajv.compile(schemaCopy);
18124
18225
  return {
18125
18226
  key: schema.key || '',
18126
18227
  serialize: function serialize(inst) {
18127
18228
  validate(inst);
18128
18229
  return {
18129
- instance: serializeRewrite(_serialize, inst, schema),
18230
+ instance: serializeRewrite(_serialize, inst, schemaCopy),
18130
18231
  valid: validate(inst),
18131
18232
  errors: validate.errors || []
18132
18233
  };
@@ -19706,14 +19807,16 @@ var ElementNumber = function ElementNumber(props) {
19706
19807
 
19707
19808
  var classes$r = {"button-common-styles":"Atom-module_button-common-styles__ipWaI","scrollbar":"Atom-module_scrollbar__z5cVx","atomProps":"Atom-module_atomProps__pqBjY","accordionWrapper":"Atom-module_accordionWrapper__MSuU7","expandIcon":"Atom-module_expandIcon__mPszC","turnedIcon":"Atom-module_turnedIcon__0Kzwy","accordionSummaryWrapper":"Atom-module_accordionSummaryWrapper__MGqsq","accordionSummary":"Atom-module_accordionSummary__HMKzl","accordionDetailsWrapper":"Atom-module_accordionDetailsWrapper__p6EI7","hiddenAccordion":"Atom-module_hiddenAccordion__pDNdM","accordionDetails":"Atom-module_accordionDetails__-B3jK","checkbox":"Atom-module_checkbox__Vup40","reactionFlags":"Atom-module_reactionFlags__gdNb1","querySpecific":"Atom-module_querySpecific__7XxMr"};
19708
19809
 
19709
- var _excluded$g = ["formState", "stereoParity"];
19810
+ var _excluded$g = ["formState", "stereoParity", "isMultipleAtoms"];
19710
19811
  function ownKeys$t(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
19711
19812
  function _objectSpread$t(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys$t(Object(source), !0).forEach(function (key) { _defineProperty__default["default"](target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys$t(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
19712
19813
  var atomProps = atom.properties;
19713
19814
  var Atom = function Atom(props) {
19714
19815
  var formState = props.formState;
19715
19816
  props.stereoParity;
19716
- var rest = _objectWithoutProperties__default["default"](props, _excluded$g);
19817
+ var _props$isMultipleAtom = props.isMultipleAtoms,
19818
+ isMultipleAtoms = _props$isMultipleAtom === void 0 ? false : _props$isMultipleAtom,
19819
+ rest = _objectWithoutProperties__default["default"](props, _excluded$g);
19717
19820
  var _useState = React.useState(rest.label),
19718
19821
  _useState2 = _slicedToArray__default["default"](_useState, 2),
19719
19822
  currentLabel = _useState2[0],
@@ -19815,10 +19918,10 @@ var Atom = function Atom(props) {
19815
19918
  schema: atom,
19816
19919
  customValid: {
19817
19920
  label: function label(_label) {
19818
- return atomValid(_label);
19921
+ return atomValid(_label, isMultipleAtoms);
19819
19922
  },
19820
19923
  charge: function charge(_charge) {
19821
- return chargeValid(_charge);
19924
+ return chargeValid(_charge, isMultipleAtoms);
19822
19925
  }
19823
19926
  },
19824
19927
  init: rest
@@ -19856,13 +19959,21 @@ var Atom = function Atom(props) {
19856
19959
  }))
19857
19960
  });
19858
19961
  };
19859
- function atomValid(label) {
19860
- return label && !!ketcherCore.Elements.get(fp.capitalize(label));
19962
+ function atomValid(label, isMultipleAtoms) {
19963
+ var isChemicalElement = !!ketcherCore.Elements.get(fp.capitalize(label));
19964
+ if (isMultipleAtoms) {
19965
+ return label === '' || isChemicalElement;
19966
+ }
19967
+ return label && isChemicalElement;
19861
19968
  }
19862
- function chargeValid(charge) {
19969
+ function chargeValid(charge, isMultipleAtoms) {
19863
19970
  var regex = new RegExp(atom.properties.charge.pattern);
19864
19971
  var result = regex.exec(charge);
19865
- return result && (result[1] === '' || result[3] === '');
19972
+ var isValidCharge = result && (result[1] === '' || result[3] === '');
19973
+ if (isMultipleAtoms) {
19974
+ return charge === '0' || charge === 0 || charge === '' || isValidCharge;
19975
+ }
19976
+ return isValidCharge;
19866
19977
  }
19867
19978
 
19868
19979
  var mapStateToProps$9 = function mapStateToProps(state) {
@@ -23254,6 +23365,12 @@ function initEditor(dispatch, getState) {
23254
23365
  updateAction();
23255
23366
  },
23256
23367
  onElementEdit: function onElementEdit(selem) {
23368
+ if (isAtomsArray(selem)) {
23369
+ var atomAttributes = generateCommonProperties(selem);
23370
+ return openDialog(dispatch, 'atomProps', _objectSpread$1(_objectSpread$1({}, atomAttributes), {}, {
23371
+ isMultipleAtoms: true
23372
+ })).then(toElement);
23373
+ }
23257
23374
  var elem = selem.type === 'text' ? selem : fromElement(selem);
23258
23375
  var dlg = null;
23259
23376
  if (elem.type === 'text') {
@@ -23535,8 +23652,8 @@ var KetcherBuilder = function () {
23535
23652
  initApp(element, staticResourcesUrl, {
23536
23653
  buttons: buttons || {},
23537
23654
  errorHandler: errorHandler || null,
23538
- version: "2.8.0-rc.2-dev" ,
23539
- buildDate: "2023-02-07T14:35:38" ,
23655
+ version: "2.8.0-rc.3" ,
23656
+ buildDate: "2023-02-15T12:49:59" ,
23540
23657
  buildNumber: ''
23541
23658
  }, structService, resolve);
23542
23659
  });