ketcher-react 2.23.0-rc.4 → 2.24.0-rc.2

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.
@@ -24,7 +24,7 @@ import _asyncToGenerator from '@babel/runtime/helpers/asyncToGenerator';
24
24
  import _regeneratorRuntime from '@babel/runtime/regenerator';
25
25
  import _classCallCheck$2 from '@babel/runtime/helpers/classCallCheck';
26
26
  import _createClass$2 from '@babel/runtime/helpers/createClass';
27
- import { KetSerializer, MolSerializer, KetcherLogger, Ketcher, defaultBondThickness, FormatterFactory, isClipboardAPIAvailable, notifyCopyCut, notifyRequestCompleted, isControlKey, StereLabelStyleType, StereoColoringType, ShowHydrogenLabels, ShowHydrogenLabelNames, SettingsManager, SdfSerializer, KETCHER_SAVED_OPTIONS_KEY, Bond as Bond$2, Elements, AtomList, getAtomType, StereoLabel, isAttachmentBond, Atom as Atom$2, findStereoAtoms, RxnArrowMode, SimpleObjectMode, SGroup as SGroup$1, Pile, getStereoAtomsMap, identifyStructFormat, SupportedFormat, ChemicalMimeType, RenderStruct, Struct, shortcutStr, MonomerMicromolecule, UnresolvedMonomer, FunctionalGroupsProvider, SaltsAndSolventsProvider, KetcherAsyncEvents, ElementColor, generateMenuShortcuts, Vec2, Scale, fromMultipleMove, FunctionalGroup, fromSgroupDeletion, fromFragmentDeletion, mergeMapOfItemsToSet, vectorUtils, fromBondAddition, Action, fromAtomAddition, fromAtomsAttrs, checkOverlapping, fromSeveralSgroupAddition, expandSGroupWithMultipleAttachmentPoint, SgContexts, fromSgroupAction, fromItemsFuse, ReBond, setExpandSGroup, fromBondsAttrs, OperationType, ReStruct, fromSimpleObjectResizing, fromArrowResizing, getItemsToFuse, getHoverToFuse, fromTextDeletion, fromTextUpdating, CoordinateTransformation, fromTemplateOnCanvas, fromTemplateOnBondAction, fromTemplateOnAtom, BondAttr, AtomAttr, formatProperties, ketcherProvider, runAsyncAction, getStructStringFromClipboardData, getStructure, initHotKeys, keyNorm, Fragment as Fragment$1, fromRGroupAttachmentPointUpdate, fromOneBondDeletion, bondChangingAction, fromChain, fromStereoFlagUpdate, fromOneAtomDeletion, fromArrowDeletion, fromPlusDeletion, fromSimpleObjectDeletion, fromRGroupAttachmentPointDeletion, notifyItemsToMergeInitializationComplete, fromPaste, RGroup as RGroup$2, fromRGroupFragment, fromUpdateIfThen, fromRGroupAttrs, fromArrowAddition, fromPlusAddition, fromRotate, fromFlip, fromSimpleObjectAddition, fromTextCreation, fromHighlightCreate, fromHighlightClear, provideEditorSettings, fromNewCanvas, Render, fromDescriptorsAlign, fromSgroupAttachmentPointAddition, SGroupAttachmentPoint, fromSgroupAddition, atomGetAttr, genericsList, getAtomCustomQuery, getFormatMimeTypeByFileName, getPropertiesByFormat, StereoFlag, getPropertiesByImgFormat, b64toBlob, Generics, TextCommand, DefaultStructServiceOptions } from 'ketcher-core';
27
+ import { KetSerializer, MolSerializer, KetcherLogger, Ketcher, defaultBondThickness, FormatterFactory, isClipboardAPIAvailable, notifyCopyCut, notifyRequestCompleted, isControlKey, StereLabelStyleType, StereoColoringType, ShowHydrogenLabels, ShowHydrogenLabelNames, SettingsManager, SdfSerializer, KETCHER_SAVED_OPTIONS_KEY, Bond as Bond$2, Elements, AtomList, getAtomType, StereoLabel, isAttachmentBond, Atom as Atom$2, findStereoAtoms, RxnArrowMode, SimpleObjectMode, IMAGE_KEY, SGroup as SGroup$1, Pile, getStereoAtomsMap, identifyStructFormat, SupportedFormat, ChemicalMimeType, RenderStruct, Struct, shortcutStr, MonomerMicromolecule, UnresolvedMonomer, FunctionalGroupsProvider, SaltsAndSolventsProvider, KetcherAsyncEvents, ElementColor, generateMenuShortcuts, Vec2, Scale, fromMultipleMove, FunctionalGroup, fromSgroupDeletion, fromFragmentDeletion, mergeMapOfItemsToSet, vectorUtils, fromBondAddition, Action, fromAtomAddition, fromAtomsAttrs, checkOverlapping, fromSeveralSgroupAddition, expandSGroupWithMultipleAttachmentPoint, SgContexts, fromSgroupAction, fromItemsFuse, ReBond, setExpandSGroup, fromBondsAttrs, OperationType, ReStruct, CoordinateTransformation, fromImageResize, fromSimpleObjectResizing, fromArrowResizing, getItemsToFuse, getHoverToFuse, imageReferencePositionToCursor, fromTextDeletion, fromTextUpdating, fromTemplateOnCanvas, fromTemplateOnBondAction, fromTemplateOnAtom, BondAttr, AtomAttr, formatProperties, ketcherProvider, runAsyncAction, getStructStringFromClipboardData, getStructure, initHotKeys, keyNorm, Fragment as Fragment$1, fromRGroupAttachmentPointUpdate, fromOneBondDeletion, bondChangingAction, fromChain, fromStereoFlagUpdate, fromOneAtomDeletion, fromArrowDeletion, fromPlusDeletion, fromSimpleObjectDeletion, fromRGroupAttachmentPointDeletion, fromImageDeletion, notifyItemsToMergeInitializationComplete, fromPaste, RGroup as RGroup$2, fromRGroupFragment, fromUpdateIfThen, fromRGroupAttrs, fromArrowAddition, fromPlusAddition, fromRotate, fromFlip, fromSimpleObjectAddition, fromTextCreation, fromImageMove, fromImageCreation, fromHighlightCreate, fromHighlightClear, provideEditorSettings, fromNewCanvas, Render, fromDescriptorsAlign, fromSgroupAttachmentPointAddition, SGroupAttachmentPoint, fromSgroupAddition, atomGetAttr, genericsList, getAtomCustomQuery, getFormatMimeTypeByFileName, getPropertiesByFormat, StereoFlag, getPropertiesByImgFormat, b64toBlob, Generics, TextCommand, DefaultStructServiceOptions } from 'ketcher-core';
28
28
  import * as React from 'react';
29
29
  import React__default, { createRef, Component, useRef, useEffect, useLayoutEffect, useState, useMemo, createElement, forwardRef, useCallback, Fragment as Fragment$2, PureComponent, lazy, Suspense } from 'react';
30
30
  import _objectWithoutProperties from '@babel/runtime/helpers/objectWithoutProperties';
@@ -76,11 +76,12 @@ import 'draft-js/dist/Draft.css';
76
76
  import { Modifier, EditorState, convertFromRaw, RichUtils, Editor as Editor$4, convertToRaw, getDefaultKeyBinding } from 'draft-js';
77
77
  import createStyles from 'draft-js-custom-styles';
78
78
  import _objectDestructuringEmpty from '@babel/runtime/helpers/objectDestructuringEmpty';
79
- import _extends$3j from '@babel/runtime/helpers/extends';
79
+ import _extends$3k from '@babel/runtime/helpers/extends';
80
80
  import MuiAutocomplete from '@mui/material/Autocomplete';
81
81
  import { createRoot } from 'react-dom/client';
82
82
 
83
83
  function createApi(structServiceProvider, defaultOptions) {
84
+ var _structService$destro;
84
85
  var structService = structServiceProvider.createStructService(defaultOptions);
85
86
  var info = structService.info();
86
87
  return Object.assign(info, {
@@ -97,7 +98,8 @@ function createApi(structServiceProvider, defaultOptions) {
97
98
  recognize: structService.recognize.bind(structService),
98
99
  generateImageAsBase64: structService.generateImageAsBase64.bind(structService),
99
100
  getInChIKey: structService.getInChIKey.bind(structService),
100
- toggleExplicitHydrogens: structService.toggleExplicitHydrogens.bind(structService)
101
+ toggleExplicitHydrogens: structService.toggleExplicitHydrogens.bind(structService),
102
+ destroy: (_structService$destro = structService.destroy) === null || _structService$destro === void 0 ? void 0 : _structService$destro.bind(structService)
101
103
  });
102
104
  }
103
105
 
@@ -276,7 +278,7 @@ function _unsupportedIterableToArray$g(o, minLen) { if (!o) return; if (typeof o
276
278
  function _arrayLikeToArray$g(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
277
279
  function _callSuper$b(t, o, e) { return o = _getPrototypeOf$2(o), _possibleConstructorReturn$2(t, _isNativeReflectConstruct$d() ? Reflect.construct(o, e || [], _getPrototypeOf$2(t).constructor) : o.apply(t, e)); }
278
280
  function _isNativeReflectConstruct$d() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct$d = function _isNativeReflectConstruct() { return !!t; })(); }
279
- var ieCb = window.clipboardData;
281
+ var ieCb = typeof window !== 'undefined' ? window.clipboardData : {};
280
282
  var CLIP_AREA_BASE_CLASS = 'cliparea';
281
283
  var needSkipCopyEvent = false;
282
284
  var ClipArea = function (_Component) {
@@ -489,7 +491,7 @@ function _copy(_x3) {
489
491
  }
490
492
  function _copy2() {
491
493
  _copy2 = _asyncToGenerator( _regeneratorRuntime.mark(function _callee3(data) {
492
- var clipboardItemData, clipboardItem, textData;
494
+ var clipboardItemData;
493
495
  return _regeneratorRuntime.wrap(function _callee3$(_context3) {
494
496
  while (1) switch (_context3.prev = _context3.next) {
495
497
  case 0:
@@ -501,36 +503,20 @@ function _copy2() {
501
503
  type: mimeTypeToSet
502
504
  }));
503
505
  });
504
- clipboardItem = new ClipboardItem(clipboardItemData);
505
- if (!(clipboardItem.presentationStyle && clipboardItem.presentationStyle === 'unspecified')) {
506
- _context3.next = 11;
507
- break;
508
- }
509
- if (!navigator.clipboard.writeText) {
510
- _context3.next = 9;
511
- break;
512
- }
513
- textData = data['text/plain'] || JSON.stringify(data);
514
- _context3.next = 9;
515
- return navigator.clipboard.writeText(textData);
516
- case 9:
517
- _context3.next = 13;
518
- break;
519
- case 11:
520
- _context3.next = 13;
521
- return navigator.clipboard.write([clipboardItem]);
522
- case 13:
523
- _context3.next = 19;
506
+ _context3.next = 5;
507
+ return navigator.clipboard.write([new ClipboardItem(clipboardItemData)]);
508
+ case 5:
509
+ _context3.next = 11;
524
510
  break;
525
- case 15:
526
- _context3.prev = 15;
511
+ case 7:
512
+ _context3.prev = 7;
527
513
  _context3.t0 = _context3["catch"](0);
528
514
  KetcherLogger.error('cliparea.jsx::copy', _context3.t0);
529
- case 19:
515
+ case 11:
530
516
  case "end":
531
517
  return _context3.stop();
532
518
  }
533
- }, _callee3, null, [[0, 15]]);
519
+ }, _callee3, null, [[0, 7]]);
534
520
  }));
535
521
  return _copy2.apply(this, arguments);
536
522
  }
@@ -2555,7 +2541,7 @@ function isFlipDisabled(editor) {
2555
2541
  return getAmountOfAttachmentBonds() > 1;
2556
2542
  }
2557
2543
 
2558
- var toolActions = {
2544
+ var toolActions = _defineProperty$1({
2559
2545
  hand: {
2560
2546
  title: 'Hand tool',
2561
2547
  shortcut: 'Mod+Alt+h',
@@ -2986,7 +2972,15 @@ var toolActions = {
2986
2972
  return isHidden(options, 'bonds');
2987
2973
  }
2988
2974
  }
2989
- };
2975
+ }, IMAGE_KEY, {
2976
+ title: 'Add Image',
2977
+ action: {
2978
+ tool: IMAGE_KEY
2979
+ },
2980
+ hidden: function hidden(options) {
2981
+ return isHidden(options, IMAGE_KEY);
2982
+ }
2983
+ });
2990
2984
  var bondCuts = {
2991
2985
  single: '1',
2992
2986
  "double": '2',
@@ -3345,7 +3339,7 @@ function serverCall(editor, server, method, options, struct) {
3345
3339
  var selectedBonds = [];
3346
3340
  var aidMap = new Map();
3347
3341
  var bidMap = new Map();
3348
- var currentStruct = (struct || editor.struct()).clone(null, null, false, aidMap, null, null, null, bidMap);
3342
+ var currentStruct = (struct || editor.struct()).clone(null, null, false, aidMap, null, null, null, null, bidMap);
3349
3343
  var expSel = editor.explicitSelected();
3350
3344
  if (selection) {
3351
3345
  selectedAtoms = (selection.atoms ? selection.atoms : expSel.atoms).map(function (aid) {
@@ -3611,7 +3605,7 @@ var zoom = {
3611
3605
 
3612
3606
  var openHelpLink = function openHelpLink() {
3613
3607
  var _window$open;
3614
- return (_window$open = window.open("https://github.com/epam/ketcher/blob/".concat("v2.23.0-rc.4\n", "/documentation/help.md#ketcher-overview"))) === null || _window$open === void 0 ? void 0 : _window$open.focus();
3608
+ return (_window$open = window.open("https://github.com/epam/ketcher/blob/".concat("v2.24.0-rc.2\n", "/documentation/help.md#ketcher-overview"))) === null || _window$open === void 0 ? void 0 : _window$open.focus();
3615
3609
  };
3616
3610
  var help = {
3617
3611
  help: {
@@ -3639,6 +3633,8 @@ var KETCHER_ROOT_NODE_CLASS_NAME = 'Ketcher-root';
3639
3633
  var KETCHER_ROOT_NODE_CSS_SELECTOR = ".".concat(KETCHER_ROOT_NODE_CLASS_NAME);
3640
3634
  var EditorClassName = 'Ketcher-polymer-editor-root';
3641
3635
  var KETCHER_MACROMOLECULES_ROOT_NODE_SELECTOR = ".".concat(EditorClassName);
3636
+ var STRUCT_SERVICE_NO_RENDER_INITIALIZED_EVENT = 'struct-service-no-render-initialized';
3637
+ var STRUCT_SERVICE_INITIALIZED_EVENT = 'struct-service-initialized';
3642
3638
 
3643
3639
  var functionalGroupsLib = {
3644
3640
  'functional-groups': {
@@ -3999,16 +3995,16 @@ function hasSelection(editor) {
3999
3995
 
4000
3996
  var classes$Q = {"button-common-styles":"ActionButton-module_button-common-styles__y-hng","scrollbar":"ActionButton-module_scrollbar__lD3MH","button":"ActionButton-module_button__nfoWQ","selected":"ActionButton-module_selected__kPCxA"};
4001
3997
 
4002
- var _path$3c, _rect$4, _rect2$3;
4003
- function _extends$3i() { _extends$3i = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends$3i.apply(this, arguments); }
3998
+ var _path$3d, _rect$4, _rect2$3;
3999
+ function _extends$3j() { _extends$3j = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends$3j.apply(this, arguments); }
4004
4000
  function SvgAbout(props) {
4005
- return /*#__PURE__*/React.createElement("svg", _extends$3i({
4001
+ return /*#__PURE__*/React.createElement("svg", _extends$3j({
4006
4002
  width: 24,
4007
4003
  height: 24,
4008
4004
  viewBox: "0 0 24 24",
4009
4005
  fill: "none",
4010
4006
  xmlns: "http://www.w3.org/2000/svg"
4011
- }, props), _path$3c || (_path$3c = /*#__PURE__*/React.createElement("path", {
4007
+ }, props), _path$3d || (_path$3d = /*#__PURE__*/React.createElement("path", {
4012
4008
  d: "M12 4.5a7.5 7.5 0 100 15 7.5 7.5 0 000-15zM12 18c-3.307 0-6-2.693-6-6s2.693-6 6-6 6 2.693 6 6-2.693 6-6 6z",
4013
4009
  fill: "currentcolor"
4014
4010
  })), _rect$4 || (_rect$4 = /*#__PURE__*/React.createElement("rect", {
@@ -4028,6 +4024,20 @@ function SvgAbout(props) {
4028
4024
  })));
4029
4025
  }
4030
4026
 
4027
+ var _path$3c;
4028
+ function _extends$3i() { _extends$3i = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends$3i.apply(this, arguments); }
4029
+ function SvgAddImage(props) {
4030
+ return /*#__PURE__*/React.createElement("svg", _extends$3i({
4031
+ width: 16,
4032
+ height: 16,
4033
+ viewBox: "0 0 16 16",
4034
+ xmlns: "http://www.w3.org/2000/svg"
4035
+ }, props), _path$3c || (_path$3c = /*#__PURE__*/React.createElement("path", {
4036
+ d: "M12.19 14.476H1.524V3.81H8.38V2.286H1.524C.686 2.286 0 2.97 0 3.81v10.666C0 15.314.686 16 1.524 16H12.19c.839 0 1.524-.686 1.524-1.524V7.62H12.19v6.857zm-5.935-2.415l-1.493-1.798-2.095 2.69h8.38L8.35 9.362l-2.095 2.698zm7.46-9.775V0H12.19v2.286H9.905c.007.007 0 1.524 0 1.524h2.286v2.278c.007.007 1.523 0 1.523 0V3.81H16V2.286h-2.286z",
4037
+ fill: "currentColor"
4038
+ })));
4039
+ }
4040
+
4031
4041
  var _path$3b;
4032
4042
  function _extends$3h() { _extends$3h = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends$3h.apply(this, arguments); }
4033
4043
  function SvgAnalyse(props) {
@@ -7599,7 +7609,8 @@ function SvgNucleotide(props) {
7599
7609
  })));
7600
7610
  }
7601
7611
 
7602
- var iconNameToIcon = {
7612
+ var _iconNameToIcon;
7613
+ var iconNameToIcon = (_iconNameToIcon = {
7603
7614
  α: Svg$n,
7604
7615
  β: Svg$m,
7605
7616
  γ: Svg$l,
@@ -7751,67 +7762,8 @@ var iconNameToIcon = {
7751
7762
  'template-dialog': SvgTemplateDialog,
7752
7763
  'template-lib': SvgTemplateLib,
7753
7764
  'snake-mode': SvgSnakeMode,
7754
- text: SvgText,
7755
- 'text-bold': SvgTextBold,
7756
- 'text-italic': SvgTextItalic,
7757
- 'text-subscript': SvgTextSubscript,
7758
- 'text-superscript': SvgTextSuperscript,
7759
- 'transform-flip-h': SvgTransformFlipH,
7760
- 'transform-flip-v': SvgTransformFlipV,
7761
- undo: SvgUndo,
7762
- 'zoom-in': SvgZoomIn,
7763
- 'zoom-out': SvgZoomOut,
7764
- 'zoom-reset': SvgZoomReset,
7765
- 'shape-ellipse': SvgShapeEllipse,
7766
- 'shape-rectangle': SvgShapeRectangle,
7767
- 'shape-polyline': SvgShapePolyline,
7768
- 'shape-line': SvgShapeLine,
7769
- 'not-found': SvgNotFound,
7770
- 'save-1': SvgSave1,
7771
- 'open-1': SvgOpen1,
7772
- reset: SvgReset,
7773
- close: SvgClose,
7774
- general: SvgGeneral,
7775
- 'general-white': SvgGeneralWhite,
7776
- stereo: SvgStereo,
7777
- 'stereo-white': SvgStereoWhite,
7778
- atoms: SvgAtoms,
7779
- 'atoms-white': SvgAtomsWhite,
7780
- bonds: SvgBonds,
7781
- 'bonds-white': SvgBondsWhite,
7782
- server: SvgServer,
7783
- 'server-white': SvgServerWhite,
7784
- '3dviewer': Svg3D,
7785
- '3dviewer-white': Svg3DWhite,
7786
- debugging: SvgDebugging,
7787
- 'debugging-white': SvgDebuggingWhite,
7788
- 'dropdown-indicator': SvgDropdownIndicator,
7789
- 'text-special-symbols': SvgTextSpecialSymbols,
7790
- chevron: SvgChevron,
7791
- 'open-window-paste-icon': SvgOpenWindowPasteIcon,
7792
- 'open-window-upload-icon': SvgOpenWindowUploadIcon,
7793
- bracket: SvgBracket,
7794
- error: SvgError,
7795
- 'rap-left-link': SvgRapLeftLink,
7796
- 'rap-middle-link': SvgRapMiddleLink,
7797
- 'rap-right-link': SvgRapRightLink,
7798
- 'arrows-left': SvgArrowsLeft,
7799
- 'arrows-right': SvgArrowsRight,
7800
- sugar: SvgSugar,
7801
- base: SvgBase,
7802
- phosphate: SvgPhosphate,
7803
- preset: SvgPreset,
7804
- nucleotide: SvgNucleotide,
7805
- 'edit-filled': SvgEditFilled,
7806
- 'vertical-dots': SvgVerticalDots,
7807
- expand: SvgExpand,
7808
- 'minimize-expansion': SvgMinimizeExpantion,
7809
- 'explicit-hydrogens': SvgExplicitHydrogens,
7810
- 'flex-layout-mode': SvgFlexLayoutMode,
7811
- 'snake-layout-mode': SvgSnakeLayoutMode,
7812
- 'sequence-layout-mode': SvgSequenceLayoutMode,
7813
- questionMark: SvgQuestionMark
7814
- };
7765
+ text: SvgText
7766
+ }, _defineProperty$1(_defineProperty$1(_defineProperty$1(_defineProperty$1(_defineProperty$1(_defineProperty$1(_defineProperty$1(_defineProperty$1(_defineProperty$1(_defineProperty$1(_iconNameToIcon, IMAGE_KEY, SvgAddImage), 'text-bold', SvgTextBold), 'text-italic', SvgTextItalic), 'text-subscript', SvgTextSubscript), 'text-superscript', SvgTextSuperscript), 'transform-flip-h', SvgTransformFlipH), 'transform-flip-v', SvgTransformFlipV), "undo", SvgUndo), 'zoom-in', SvgZoomIn), 'zoom-out', SvgZoomOut), _defineProperty$1(_defineProperty$1(_defineProperty$1(_defineProperty$1(_defineProperty$1(_defineProperty$1(_defineProperty$1(_defineProperty$1(_defineProperty$1(_defineProperty$1(_iconNameToIcon, 'zoom-reset', SvgZoomReset), 'shape-ellipse', SvgShapeEllipse), 'shape-rectangle', SvgShapeRectangle), 'shape-polyline', SvgShapePolyline), 'shape-line', SvgShapeLine), 'not-found', SvgNotFound), 'save-1', SvgSave1), 'open-1', SvgOpen1), "reset", SvgReset), "close", SvgClose), _defineProperty$1(_defineProperty$1(_defineProperty$1(_defineProperty$1(_defineProperty$1(_defineProperty$1(_defineProperty$1(_defineProperty$1(_defineProperty$1(_defineProperty$1(_iconNameToIcon, "general", SvgGeneral), 'general-white', SvgGeneralWhite), "stereo", SvgStereo), 'stereo-white', SvgStereoWhite), "atoms", SvgAtoms), 'atoms-white', SvgAtomsWhite), "bonds", SvgBonds), 'bonds-white', SvgBondsWhite), "server", SvgServer), 'server-white', SvgServerWhite), _defineProperty$1(_defineProperty$1(_defineProperty$1(_defineProperty$1(_defineProperty$1(_defineProperty$1(_defineProperty$1(_defineProperty$1(_defineProperty$1(_defineProperty$1(_iconNameToIcon, '3dviewer', Svg3D), '3dviewer-white', Svg3DWhite), "debugging", SvgDebugging), 'debugging-white', SvgDebuggingWhite), 'dropdown-indicator', SvgDropdownIndicator), 'text-special-symbols', SvgTextSpecialSymbols), "chevron", SvgChevron), 'open-window-paste-icon', SvgOpenWindowPasteIcon), 'open-window-upload-icon', SvgOpenWindowUploadIcon), "bracket", SvgBracket), _defineProperty$1(_defineProperty$1(_defineProperty$1(_defineProperty$1(_defineProperty$1(_defineProperty$1(_defineProperty$1(_defineProperty$1(_defineProperty$1(_defineProperty$1(_iconNameToIcon, "error", SvgError), 'rap-left-link', SvgRapLeftLink), 'rap-middle-link', SvgRapMiddleLink), 'rap-right-link', SvgRapRightLink), 'arrows-left', SvgArrowsLeft), 'arrows-right', SvgArrowsRight), "sugar", SvgSugar), "base", SvgBase), "phosphate", SvgPhosphate), "preset", SvgPreset), _defineProperty$1(_defineProperty$1(_defineProperty$1(_defineProperty$1(_defineProperty$1(_defineProperty$1(_defineProperty$1(_defineProperty$1(_defineProperty$1(_defineProperty$1(_iconNameToIcon, "nucleotide", SvgNucleotide), 'edit-filled', SvgEditFilled), 'vertical-dots', SvgVerticalDots), "expand", SvgExpand), 'minimize-expansion', SvgMinimizeExpantion), 'explicit-hydrogens', SvgExplicitHydrogens), 'flex-layout-mode', SvgFlexLayoutMode), 'snake-layout-mode', SvgSnakeLayoutMode), 'sequence-layout-mode', SvgSequenceLayoutMode), "questionMark", SvgQuestionMark));
7815
7767
 
7816
7768
  var getIconByName = function getIconByName(name) {
7817
7769
  return iconNameToIcon[name];
@@ -14040,6 +13992,7 @@ var _excluded$t = ["type"],
14040
13992
  _excluded2$5 = ["buttons"];
14041
13993
  function ownKeys$12(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; }
14042
13994
  function _objectSpread$12(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys$12(Object(t), !0).forEach(function (r) { _defineProperty$1(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys$12(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
13995
+ var SET_SERVER = 'SET_SERVER';
14043
13996
  var shared = combineReducers({
14044
13997
  common: commonReducer,
14045
13998
  actionState: actionStateReducer,
@@ -14074,6 +14027,12 @@ function getRootReducer(setEditor) {
14074
14027
  var data = _objectWithoutProperties(action, _excluded$t);
14075
14028
  if (data) state = _objectSpread$12(_objectSpread$12({}, state), data);
14076
14029
  }
14030
+ case SET_SERVER:
14031
+ {
14032
+ state = _objectSpread$12(_objectSpread$12({}, state), {}, {
14033
+ server: action.server || state.server
14034
+ });
14035
+ }
14077
14036
  }
14078
14037
  var sh = shared(state, _objectSpread$12(_objectSpread$12({}, action), pick(['editor', 'server', 'options'], state)));
14079
14038
  var finalState = sh === state.shared ? state : _objectSpread$12(_objectSpread$12({}, state), sh);
@@ -14100,6 +14059,12 @@ function createStore (options, server, setEditor) {
14100
14059
  var rootReducer = getRootReducer(setEditor);
14101
14060
  return createStore$1(rootReducer, initState, applyMiddleware.apply(void 0, middleware));
14102
14061
  }
14062
+ function setServer(server) {
14063
+ return {
14064
+ type: SET_SERVER,
14065
+ server: server
14066
+ };
14067
+ }
14103
14068
 
14104
14069
  var disableableButtons$3 = [];
14105
14070
  var mapStateToProps$l = function mapStateToProps(state) {
@@ -14526,6 +14491,8 @@ var LeftToolbar = function LeftToolbar(props) {
14526
14491
  options: shapeOptions
14527
14492
  }, {
14528
14493
  id: 'text'
14494
+ }, {
14495
+ id: IMAGE_KEY
14529
14496
  }]
14530
14497
  })
14531
14498
  })]
@@ -15663,11 +15630,17 @@ function getElementsInRectangle(restruct, p0, p1) {
15663
15630
  var x1 = Math.max(p0.x, p1.x);
15664
15631
  var y0 = Math.min(p0.y, p1.y);
15665
15632
  var y1 = Math.max(p0.y, p1.y);
15633
+ var topLeftPosition = new Vec2(x0, y0);
15634
+ var topRightPosition = new Vec2(x1, y0);
15635
+ var bottomRightPosition = new Vec2(x1, y1);
15636
+ var bottomLeftPosition = new Vec2(x0, y1);
15666
15637
  restruct.bonds.forEach(function (bond, bid) {
15667
15638
  if (struct.isBondFromMacromolecule(bid)) {
15668
15639
  return;
15669
15640
  }
15670
- var centre = Vec2.lc2(restruct.atoms.get(bond.b.begin).a.pp, 0.5, restruct.atoms.get(bond.b.end).a.pp, 0.5);
15641
+ var centre = Vec2.lc2(
15642
+ restruct.atoms.get(bond.b.begin).a.pp, 0.5,
15643
+ restruct.atoms.get(bond.b.end).a.pp, 0.5);
15671
15644
  if (centre.x > x0 && centre.x < x1 && centre.y > y0 && centre.y < y1 && !FunctionalGroup.isBondInContractedFunctionalGroup(bond.b, sGroups, functionalGroups)) {
15672
15645
  bondList.push(bid);
15673
15646
  }
@@ -15675,7 +15648,8 @@ function getElementsInRectangle(restruct, p0, p1) {
15675
15648
  restruct.atoms.forEach(function (atom, aid) {
15676
15649
  var relatedFGId = FunctionalGroup.findFunctionalGroupByAtom(functionalGroups, aid);
15677
15650
  var reSGroup = restruct.sgroups.get(relatedFGId);
15678
- if (!((reSGroup === null || reSGroup === void 0 ? void 0 : reSGroup.item) instanceof MonomerMicromolecule) && atom.a.pp.x > x0 && atom.a.pp.x < x1 && atom.a.pp.y > y0 && atom.a.pp.y < y1 && (!FunctionalGroup.isAtomInContractedFunctionalGroup(atom.a, sGroups, functionalGroups, true) || aid === reSGroup.item.atoms[0])) {
15651
+ if (!((reSGroup === null || reSGroup === void 0 ? void 0 : reSGroup.item) instanceof MonomerMicromolecule) && atom.a.pp.x > x0 && atom.a.pp.x < x1 && atom.a.pp.y > y0 && atom.a.pp.y < y1 && (!FunctionalGroup.isAtomInContractedFunctionalGroup(atom.a, sGroups, functionalGroups, true) ||
15652
+ aid === reSGroup.item.atoms[0])) {
15679
15653
  atomList.push(aid);
15680
15654
  }
15681
15655
  });
@@ -15730,7 +15704,18 @@ function getElementsInRectangle(restruct, p0, p1) {
15730
15704
  rgroupAttachmentPointList.push(id);
15731
15705
  }
15732
15706
  });
15733
- return {
15707
+ var reImages = Array.from(restruct.images.entries()).reduce(function (acc, _ref) {
15708
+ var _ref2 = _slicedToArray$1(_ref, 2),
15709
+ id = _ref2[0],
15710
+ item = _ref2[1];
15711
+ if (Object.values(item.image.getReferencePositions()).some(function (point) {
15712
+ return point.isInsidePolygon([topLeftPosition, topRightPosition, bottomRightPosition, bottomLeftPosition]);
15713
+ })) {
15714
+ return acc.concat(id);
15715
+ }
15716
+ return acc;
15717
+ }, []);
15718
+ return _defineProperty$1({
15734
15719
  atoms: atomList,
15735
15720
  bonds: bondList,
15736
15721
  rxnArrows: rxnArrowsList,
@@ -15740,7 +15725,7 @@ function getElementsInRectangle(restruct, p0, p1) {
15740
15725
  simpleObjects: simpleObjectsList,
15741
15726
  texts: textsList,
15742
15727
  rgroupAttachmentPoints: rgroupAttachmentPointList
15743
- };
15728
+ }, IMAGE_KEY, reImages);
15744
15729
  }
15745
15730
  function getElementsInPolygon(restruct, rr) {
15746
15731
  var bondList = [];
@@ -15756,7 +15741,9 @@ function getElementsInPolygon(restruct, rr) {
15756
15741
  if (struct.isAtomFromMacromolecule(bond.b.begin) || struct.isAtomFromMacromolecule(bond.b.end)) {
15757
15742
  return;
15758
15743
  }
15759
- var centre = Vec2.lc2(restruct.atoms.get(bond.b.begin).a.pp, 0.5, restruct.atoms.get(bond.b.end).a.pp, 0.5);
15744
+ var centre = Vec2.lc2(
15745
+ restruct.atoms.get(bond.b.begin).a.pp, 0.5,
15746
+ restruct.atoms.get(bond.b.end).a.pp, 0.5);
15760
15747
  if (isPointInPolygon(r, centre) && !FunctionalGroup.isBondInContractedFunctionalGroup(bond.b, sGroups, functionalGroups)) {
15761
15748
  bondList.push(bid);
15762
15749
  }
@@ -15764,7 +15751,8 @@ function getElementsInPolygon(restruct, rr) {
15764
15751
  restruct.atoms.forEach(function (atom, aid) {
15765
15752
  var relatedFGId = FunctionalGroup.findFunctionalGroupByAtom(functionalGroups, aid);
15766
15753
  var reSGroup = restruct.sgroups.get(relatedFGId);
15767
- if (!((reSGroup === null || reSGroup === void 0 ? void 0 : reSGroup.item) instanceof MonomerMicromolecule) && isPointInPolygon(r, atom.a.pp) && (!FunctionalGroup.isAtomInContractedFunctionalGroup(atom.a, sGroups, functionalGroups, true) || aid === reSGroup.item.atoms[0])) {
15754
+ if (!((reSGroup === null || reSGroup === void 0 ? void 0 : reSGroup.item) instanceof MonomerMicromolecule) && isPointInPolygon(r, atom.a.pp) && (!FunctionalGroup.isAtomInContractedFunctionalGroup(atom.a, sGroups, functionalGroups, true) ||
15755
+ aid === reSGroup.item.atoms[0])) {
15768
15756
  atomList.push(aid);
15769
15757
  }
15770
15758
  });
@@ -15773,7 +15761,7 @@ function getElementsInPolygon(restruct, rr) {
15773
15761
  var simpleObjectsList = [];
15774
15762
  var textsList = [];
15775
15763
  restruct.rxnArrows.forEach(function (item, id) {
15776
- var referencePoints = item.getReferencePoints(true);
15764
+ var referencePoints = item.getReferencePoints();
15777
15765
  var referencePointInPolygon = referencePoints.find(function (point) {
15778
15766
  return isPointInPolygon(r, point);
15779
15767
  });
@@ -15822,7 +15810,18 @@ function getElementsInPolygon(restruct, rr) {
15822
15810
  rgroupAttachmentPointList.push(id);
15823
15811
  }
15824
15812
  });
15825
- return {
15813
+ var reImages = Array.from(restruct.images.entries()).reduce(function (acc, _ref4) {
15814
+ var _ref5 = _slicedToArray$1(_ref4, 2),
15815
+ id = _ref5[0],
15816
+ item = _ref5[1];
15817
+ if (Object.values(item.image.getReferencePositions()).some(function (point) {
15818
+ return isPointInPolygon(r, point);
15819
+ })) {
15820
+ return acc.concat(id);
15821
+ }
15822
+ return acc;
15823
+ }, []);
15824
+ return _defineProperty$1({
15826
15825
  atoms: atomList,
15827
15826
  bonds: bondList,
15828
15827
  rxnArrows: rxnArrowsList,
@@ -15832,7 +15831,7 @@ function getElementsInPolygon(restruct, rr) {
15832
15831
  simpleObjects: simpleObjectsList,
15833
15832
  texts: textsList,
15834
15833
  rgroupAttachmentPoints: rgroupAttachmentPointList
15835
- };
15834
+ }, IMAGE_KEY, reImages);
15836
15835
  }
15837
15836
  function isPointInPolygon(r, p) {
15838
15837
  var d = new Vec2(0, 1);
@@ -17183,8 +17182,8 @@ function getSelectionMap(structure) {
17183
17182
  return result;
17184
17183
  }, {});
17185
17184
  }
17186
- function getStructCenter(ReStruct, selection) {
17187
- var bb = ReStruct.getVBoxObj(selection || {});
17185
+ function getStructCenter(reStruct, selection) {
17186
+ var bb = reStruct.getVBoxObj(selection || {});
17188
17187
  return Vec2.lc2(bb.p0, 0.5, bb.p1, 0.5);
17189
17188
  }
17190
17189
 
@@ -17193,7 +17192,7 @@ var handleMovingPosibilityCursor = function handleMovingPosibilityCursor(item, c
17193
17192
  if (!item && isCursorShown) {
17194
17193
  canvas.removeAttribute('cursor');
17195
17194
  }
17196
- if (item && !isCursorShown) {
17195
+ if (item) {
17197
17196
  canvas.setAttribute('cursor', cursor);
17198
17197
  }
17199
17198
  };
@@ -17327,6 +17326,13 @@ var SelectTool = function () {
17327
17326
  info: degrees + 'º'
17328
17327
  });
17329
17328
  }
17329
+ if (dragCtx.item.map === IMAGE_KEY && dragCtx.item.ref) {
17330
+ if (dragCtx.action) dragCtx.action.perform(rnd.ctab);
17331
+ var position = CoordinateTransformation.pageToModel(event, rnd);
17332
+ dragCtx.action = fromImageResize(rnd.ctab, dragCtx.item.id, position, dragCtx.item.ref);
17333
+ editor.update(dragCtx.action, true);
17334
+ return true;
17335
+ }
17330
17336
  if (dragCtx.item.map === 'simpleObjects' && dragCtx.item.ref) {
17331
17337
  if (dragCtx.action) dragCtx.action.perform(rnd.ctab);
17332
17338
  var props = getResizingProps(editor, dragCtx, event);
@@ -17365,7 +17371,13 @@ var SelectTool = function () {
17365
17371
  var maps = getMapsForClosestItem(_classPrivateFieldGet(this, _lassoHelper).fragment || event.ctrlKey);
17366
17372
  var item = editor.findItem(event, maps, null);
17367
17373
  editor.hover(item, null, event);
17368
- handleMovingPosibilityCursor(item, this.editor.render.paper.canvas, this.editor.render.options.movingStyle.cursor);
17374
+ if ((item === null || item === void 0 ? void 0 : item.map) === IMAGE_KEY && item.ref) {
17375
+ var referencePositionInfo = item.ref;
17376
+ handleMovingPosibilityCursor(item, this.editor.render.paper.canvas,
17377
+ imageReferencePositionToCursor[referencePositionInfo.name]);
17378
+ } else {
17379
+ handleMovingPosibilityCursor(item, this.editor.render.paper.canvas, this.editor.render.options.movingStyle.cursor);
17380
+ }
17369
17381
  return true;
17370
17382
  }
17371
17383
  }, {
@@ -17708,7 +17720,7 @@ function preventSaltAndSolventsMerge(struct, dragCtx, editor) {
17708
17720
  });
17709
17721
  }
17710
17722
  function getMapsForClosestItem(selectFragment) {
17711
- return ['sgroups', 'functionalGroups', 'sgroupData', 'rgroups', 'rgroupAttachmentPoints', 'rxnArrows', 'rxnPluses', 'enhancedFlags', 'simpleObjects', 'texts'].concat(_toConsumableArray(selectFragment ? ['frags'] : ['atoms', 'bonds']));
17723
+ return ['sgroups', 'functionalGroups', 'sgroupData', 'rgroups', 'rgroupAttachmentPoints', 'rxnArrows', 'rxnPluses', 'enhancedFlags', 'simpleObjects', 'texts', IMAGE_KEY].concat(_toConsumableArray(selectFragment ? ['frags'] : ['atoms', 'bonds']));
17712
17724
  }
17713
17725
  function getResizingProps(editor, dragCtx, event) {
17714
17726
  var current = editor.render.page2obj(event);
@@ -18781,12 +18793,21 @@ function _isChangingFunctionalGroup() {
18781
18793
  return _isChangingFunctionalGroup.apply(this, arguments);
18782
18794
  }
18783
18795
 
18796
+ var keydownListener = null;
18784
18797
  function initKeydownListener(element) {
18785
18798
  return function (dispatch, getState) {
18786
18799
  var hotKeys = initHotKeys(config);
18787
- element.addEventListener('keydown', function (event) {
18800
+ keydownListener = function keydownListener(event) {
18788
18801
  return keyHandle(dispatch, getState, hotKeys, event);
18789
- });
18802
+ };
18803
+ element.addEventListener('keydown', keydownListener);
18804
+ };
18805
+ }
18806
+ function removeKeydownListener(element) {
18807
+ return function () {
18808
+ if (keydownListener) {
18809
+ element.removeEventListener('keydown', keydownListener);
18810
+ }
18790
18811
  };
18791
18812
  }
18792
18813
  function removeNotRenderedStruct(actionTool, group, dispatch) {
@@ -19242,7 +19263,7 @@ function _unsupportedIterableToArray$9(o, minLen) { if (!o) return; if (typeof o
19242
19263
  function _arrayLikeToArray$9(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
19243
19264
  var SELECTION_DISTANCE_COEFFICIENT = 0.4;
19244
19265
  var SELECTION_WITHIN_TEXT = 0;
19245
- var findMaps = {
19266
+ var findMaps = _defineProperty$1({
19246
19267
  atoms: findClosestAtom,
19247
19268
  bonds: findClosestBond,
19248
19269
  enhancedFlags: findClosestEnhancedFlag,
@@ -19256,15 +19277,15 @@ var findMaps = {
19256
19277
  rgroupAttachmentPoints: findClosestRgroupAttachmentPoints,
19257
19278
  simpleObjects: findClosestSimpleObject,
19258
19279
  texts: findClosestText
19259
- };
19280
+ }, IMAGE_KEY, findClosestImage);
19260
19281
  function rectangleContainsPoint(startX, startY, width, height, x, y) {
19261
19282
  return startX <= x && x <= startX + width && startY <= y && y <= startY + height;
19262
19283
  }
19263
19284
  function findClosestText(restruct, cursorPosition) {
19264
- var minDist = null;
19285
+ var minDist = Number.POSITIVE_INFINITY;
19265
19286
  var ret = null;
19266
19287
  restruct.texts.forEach(function (text, id) {
19267
- var referencePoints = text.getReferencePoints(restruct);
19288
+ var referencePoints = text.getReferencePoints();
19268
19289
  var topX = referencePoints[0].x;
19269
19290
  var topY = referencePoints[0].y;
19270
19291
  var bottomX = referencePoints[2].x;
@@ -19312,7 +19333,7 @@ function findClosestText(restruct, cursorPosition) {
19312
19333
  return ret;
19313
19334
  }
19314
19335
  function findClosestSimpleObject(restruct, pos) {
19315
- var minDist = null;
19336
+ var minDist = Number.POSITIVE_INFINITY;
19316
19337
  var refPoint = null;
19317
19338
  var ret = null;
19318
19339
  restruct.simpleObjects.forEach(function (simpleObject, id) {
@@ -19339,7 +19360,7 @@ function findClosestAtom(restruct, pos, skip, minDist) {
19339
19360
  minDist = Math.min(minDist, maxMinDist);
19340
19361
  restruct.atoms.forEach(function (atom, aid) {
19341
19362
  if (FunctionalGroup.isAtomInContractedFunctionalGroup(atom.a, sGroups, functionalGroups, true) || Atom$2.isHiddenLeavingGroupAtom(restruct.molecule, aid)) {
19342
- return null;
19363
+ return;
19343
19364
  }
19344
19365
  var isSkippedAtom = aid === skipId || atom.a.isPreview;
19345
19366
  if (isSkippedAtom) {
@@ -19377,7 +19398,7 @@ function findClosestBond(restruct, pos, skip, minDist, options) {
19377
19398
  var p1 = restruct.atoms.get(bond.b.begin).a.pp;
19378
19399
  var p2 = restruct.atoms.get(bond.b.end).a.pp;
19379
19400
  if (FunctionalGroup.isBondInContractedFunctionalGroup(bond.b, sGroups, functionalGroups) || SGroup$1.isBondInContractedSGroup(bond.b, sGroups) || Bond$2.isBondToHiddenLeavingGroup(restruct.molecule, bond.b)) {
19380
- return null;
19401
+ return;
19381
19402
  }
19382
19403
  var mid = Vec2.lc2(p1, 0.5, p2, 0.5);
19383
19404
  var cdist = Vec2.dist(pos, mid);
@@ -19415,10 +19436,10 @@ function findClosestBond(restruct, pos, skip, minDist, options) {
19415
19436
  }
19416
19437
  return null;
19417
19438
  }
19418
- function findClosestEnhancedFlag(restruct, pos, skip, _minDist, options) {
19439
+ function findClosestEnhancedFlag(restruct, pos, _skip, _minDist, options) {
19419
19440
  var minDist;
19420
19441
  var ret = null;
19421
- restruct.enhancedFlags.forEach(function (item, id) {
19442
+ restruct.enhancedFlags.forEach(function (_item, id) {
19422
19443
  var fragment = restruct.molecule.frags.get(id);
19423
19444
  if (!fragment || !fragment.enhancedStereoFlag || !options.showStereoFlags) return;
19424
19445
  var p = fragment.stereoFlagPosition ? new Vec2(fragment.stereoFlagPosition.x, fragment.stereoFlagPosition.y) : Fragment$1.getDefaultStereoFlagPosition(restruct.molecule, id);
@@ -19435,7 +19456,7 @@ function findClosestEnhancedFlag(restruct, pos, skip, _minDist, options) {
19435
19456
  return ret;
19436
19457
  }
19437
19458
  function findClosestDataSGroupData(restruct, pos) {
19438
- var minDist = null;
19459
+ var minDist = Number.POSITIVE_INFINITY;
19439
19460
  var ret = null;
19440
19461
  restruct.sgroupData.forEach(function (item, id) {
19441
19462
  if (item.sgroup.type !== 'DAT') throw new Error('Data group expected');
@@ -19495,7 +19516,7 @@ function findClosestRgroupAttachmentPoints(restruct, cursorPosition, _skip, minD
19495
19516
  var minDist = minDistToOtherItems !== null && minDistToOtherItems !== void 0 ? minDistToOtherItems : Number.POSITIVE_INFINITY;
19496
19517
  var closestItemId;
19497
19518
  restruct.visibleRGroupAttachmentPoints.forEach(function (reItem, id) {
19498
- var itemOutlinePoints = reItem.getOutlinePoints();
19519
+ var itemOutlinePoints = _toConsumableArray(reItem.getOutlinePoints());
19499
19520
  var isCursorInsideOutline = cursorPosition.isInsidePolygon(itemOutlinePoints);
19500
19521
  if (isCursorInsideOutline) {
19501
19522
  var dist = reItem.getDistanceTo(cursorPosition);
@@ -19511,7 +19532,7 @@ function findClosestRgroupAttachmentPoints(restruct, cursorPosition, _skip, minD
19511
19532
  };
19512
19533
  }
19513
19534
  function findClosestRxnArrow(restruct, pos) {
19514
- var minDist = null;
19535
+ var minDist = Number.POSITIVE_INFINITY;
19515
19536
  var refPoint = null;
19516
19537
  var ret = null;
19517
19538
  restruct.rxnArrows.forEach(function (rxnArrow, id) {
@@ -19529,7 +19550,7 @@ function findClosestRxnArrow(restruct, pos) {
19529
19550
  return ret;
19530
19551
  }
19531
19552
  function findClosestRxnPlus(restruct, pos) {
19532
- var minDist = null;
19553
+ var minDist = Number.POSITIVE_INFINITY;
19533
19554
  var ret = null;
19534
19555
  restruct.rxnPluses.forEach(function (plus, id) {
19535
19556
  var p = plus.item.pp;
@@ -19548,7 +19569,7 @@ function findClosestSGroup(restruct, pos) {
19548
19569
  var ret = null;
19549
19570
  var minDist = SELECTION_DISTANCE_COEFFICIENT;
19550
19571
  restruct.molecule.sgroups.forEach(function (sg, sgid) {
19551
- if (sg.isContracted() || sg.isSuperatomWithoutLabel) return null;
19572
+ if (sg.isContracted() || sg.isSuperatomWithoutLabel) return;
19552
19573
  var d = sg.bracketDirection;
19553
19574
  var n = d.rotateSC(1, 0);
19554
19575
  var pg = new Vec2(Vec2.dot(pos, d), Vec2.dot(pos, n));
@@ -19641,7 +19662,9 @@ function findCloseMerge(restruct, selected) {
19641
19662
  });
19642
19663
  selected.bonds.forEach(function (bid) {
19643
19664
  var bond = struct.bonds.get(bid);
19644
- pos.bonds.set(bid, Vec2.lc2(struct.atoms.get(bond.begin).pp, 0.5, struct.atoms.get(bond.end).pp, 0.5));
19665
+ pos.bonds.set(bid, Vec2.lc2(
19666
+ struct.atoms.get(bond.begin).pp, 0.5,
19667
+ struct.atoms.get(bond.end).pp, 0.5));
19645
19668
  });
19646
19669
  var result = {
19647
19670
  atoms: new Map(),
@@ -19654,7 +19677,8 @@ function findCloseMerge(restruct, selected) {
19654
19677
  mergeAtomToAtom(atomId, restruct, atomPosition, selected, result) || mergeAtomToFunctionalGroup(atomId, restruct, atomPosition, result);
19655
19678
  });
19656
19679
  } else {
19657
- result[map] = Array.from(pos[map].keys()).reduce(function (res, srcId) {
19680
+ result[map] = Array.from(pos[map].keys()).reduce(
19681
+ function (res, srcId) {
19658
19682
  var skip = {
19659
19683
  map: map,
19660
19684
  id: srcId
@@ -19694,6 +19718,31 @@ function mergeAtomToFunctionalGroup(atomId, restruct, atomPosition, result) {
19694
19718
  }
19695
19719
  return false;
19696
19720
  }
19721
+ function findClosestImage(reStruct, cursorPosition) {
19722
+ var renderOptions = reStruct.render.options;
19723
+ var canvasScaledPosition = Scale.modelToCanvas(cursorPosition, renderOptions);
19724
+ var maxDistance = renderOptions.microModeScale * SELECTION_DISTANCE_COEFFICIENT;
19725
+ return Array.from(reStruct.images.entries()).reduce(function (acc, _ref) {
19726
+ var _ref2 = _slicedToArray$1(_ref, 2),
19727
+ id = _ref2[0],
19728
+ item = _ref2[1];
19729
+ var distanceToPoint = item.calculateDistanceToPoint(canvasScaledPosition, renderOptions);
19730
+ if (distanceToPoint <= maxDistance) {
19731
+ if (acc && acc.dist < distanceToPoint) {
19732
+ return acc;
19733
+ }
19734
+ var dist = Math.max(distanceToPoint, maxDistance / 3);
19735
+ var closestPosition = item.calculateClosestReferencePosition(canvasScaledPosition, renderOptions);
19736
+ var includeRef = closestPosition.distance < maxDistance;
19737
+ return {
19738
+ id: id,
19739
+ dist: dist / renderOptions.microModeScale,
19740
+ ref: includeRef ? closestPosition.ref : null
19741
+ };
19742
+ }
19743
+ return acc;
19744
+ }, null);
19745
+ }
19697
19746
  var closest = {
19698
19747
  atom: findClosestAtom,
19699
19748
  item: findClosestItem,
@@ -20622,7 +20671,7 @@ var EraserTool = function () {
20622
20671
  function EraserTool(editor, mode) {
20623
20672
  _classCallCheck$2(this, EraserTool);
20624
20673
  this.editor = editor;
20625
- this.maps = ['atoms', 'bonds', 'rxnArrows', 'rxnPluses', 'sgroups', 'functionalGroups', 'sgroupData', 'simpleObjects', 'texts', 'rgroupAttachmentPoints'];
20674
+ this.maps = ['atoms', 'bonds', 'rxnArrows', 'rxnPluses', 'sgroups', 'functionalGroups', 'sgroupData', 'simpleObjects', 'texts', 'rgroupAttachmentPoints', IMAGE_KEY];
20626
20675
  this.lassoHelper = new LassoHelper(mode || 0, editor, null);
20627
20676
  if (editor.selection()) {
20628
20677
  var action = fromFragmentDeletion(editor.render.ctab, editor.selection());
@@ -20900,6 +20949,8 @@ var EraserTool = function () {
20900
20949
  this.editor.update(fromTextDeletion(restruct, ci.id));
20901
20950
  } else if (ci.map === 'rgroupAttachmentPoints') {
20902
20951
  this.editor.update(fromRGroupAttachmentPointDeletion(restruct, ci.id));
20952
+ } else if (ci.map === IMAGE_KEY) {
20953
+ this.editor.update(fromImageDeletion(restruct, ci.id));
20903
20954
  } else {
20904
20955
  return;
20905
20956
  }
@@ -22349,7 +22400,157 @@ function propsDialog(editor, id, position, pos) {
22349
22400
  });
22350
22401
  }
22351
22402
 
22352
- var toolsMap = {
22403
+ var TAG = 'tool/image.ts';
22404
+ var supportedMimes = ['png', 'svg+xml'];
22405
+ var supportedMimesForRegex = supportedMimes.map(function (item) {
22406
+ return item.replace('+', '\\+');
22407
+ }).join('|');
22408
+ var allowList = new RegExp("^image/(".concat(supportedMimesForRegex, ")$"));
22409
+ var MIN_DIMENSION_SIZE = 16;
22410
+ var ImageTool = function () {
22411
+ function ImageTool(editor) {
22412
+ _classCallCheck$2(this, ImageTool);
22413
+ _defineProperty$1(this, "dragCtx", null);
22414
+ this.editor = editor;
22415
+ this.element = this.getElement();
22416
+ }
22417
+ _createClass$2(ImageTool, [{
22418
+ key: "mousedown",
22419
+ value: function mousedown(event) {
22420
+ var render = this.editor.render;
22421
+ var closestItem = this.editor.findItem(event, [IMAGE_KEY]);
22422
+ this.editor.selection(null);
22423
+ if (closestItem) {
22424
+ this.editor.hover(null);
22425
+ this.editor.selection(_defineProperty$1({}, IMAGE_KEY, [closestItem.id]));
22426
+ this.dragCtx = {
22427
+ center: CoordinateTransformation.pageToModel(event, render),
22428
+ action: new Action(),
22429
+ closestItem: closestItem
22430
+ };
22431
+ }
22432
+ }
22433
+ }, {
22434
+ key: "click",
22435
+ value: function click(event) {
22436
+ var closestItem = this.editor.findItem(event, [IMAGE_KEY]);
22437
+ this.editor.hover(null);
22438
+ if (closestItem) {
22439
+ return;
22440
+ }
22441
+ var position = CoordinateTransformation.pageToModel(event, this.editor.render);
22442
+ this.element.onchange = this.onFileUpload.bind(this, position);
22443
+ this.element.click();
22444
+ }
22445
+ }, {
22446
+ key: "mousemove",
22447
+ value: function mousemove(event) {
22448
+ var render = this.editor.render;
22449
+ if (this.dragCtx) {
22450
+ this.dragCtx.action.perform(render.ctab);
22451
+ var click = CoordinateTransformation.pageToModel(event, render);
22452
+ this.dragCtx.action = this.dragCtx.closestItem.ref ? fromImageResize(render.ctab, this.dragCtx.closestItem.id, click, this.dragCtx.closestItem.ref) : fromImageMove(render.ctab, this.dragCtx.closestItem.id, click.sub(this.dragCtx.center));
22453
+ this.editor.update(this.dragCtx.action, true);
22454
+ } else {
22455
+ var item = this.editor.findItem(event, [IMAGE_KEY]);
22456
+ var _render = this.editor.render;
22457
+ if (item !== null && item !== void 0 && item.ref) {
22458
+ handleMovingPosibilityCursor(item, _render.paper.canvas, imageReferencePositionToCursor[item.ref.name]);
22459
+ } else {
22460
+ handleMovingPosibilityCursor(item, _render.paper.canvas, _render.options.movingStyle.cursor);
22461
+ }
22462
+ this.editor.hover(item, null, event);
22463
+ }
22464
+ }
22465
+ }, {
22466
+ key: "mouseup",
22467
+ value: function mouseup() {
22468
+ if (this.dragCtx) {
22469
+ this.editor.update(this.dragCtx.action);
22470
+ this.dragCtx = null;
22471
+ }
22472
+ return true;
22473
+ }
22474
+ }, {
22475
+ key: "onFileUpload",
22476
+ value: function onFileUpload(clickPosition) {
22477
+ var _this = this;
22478
+ var errorHandler = this.editor.errorHandler;
22479
+ this.element.onchange = null;
22480
+ if (this.element.files && this.element.files[0]) {
22481
+ var file = this.element.files[0];
22482
+ var image = new Image();
22483
+ var reader = new FileReader();
22484
+ if (!file.type || !file.type.match(allowList)) {
22485
+ var errorMessage = "Unsupported image type";
22486
+ KetcherLogger.error("".concat(TAG, ":onFileUpload"), errorMessage);
22487
+ if (errorHandler) {
22488
+ errorHandler(errorMessage);
22489
+ }
22490
+ this.resetElementValue();
22491
+ return;
22492
+ }
22493
+ reader.addEventListener('load', function () {
22494
+ image.src = reader.result;
22495
+ });
22496
+ image.onload = function () {
22497
+ _this.resetElementValue();
22498
+ if (image.width < MIN_DIMENSION_SIZE || image.height < MIN_DIMENSION_SIZE) {
22499
+ var _errorMessage = 'Image should be at least 16x16 pixels';
22500
+ KetcherLogger.error("".concat(TAG, ":onLoad"), _errorMessage);
22501
+ if (errorHandler) {
22502
+ errorHandler(_errorMessage);
22503
+ }
22504
+ return;
22505
+ }
22506
+ var halfSize = Scale.canvasToModel(new Vec2(image.width / 2, image.height / 2), _this.editor.render.options);
22507
+ _this.editor.update(fromImageCreation(_this.editor.render.ctab, image.src, clickPosition, halfSize));
22508
+ };
22509
+ image.onerror = function (e) {
22510
+ _this.resetElementValue();
22511
+ var errorMessage = 'Cannot load image';
22512
+ KetcherLogger.error("".concat(TAG, ":onerror"), errorMessage, e);
22513
+ if (errorHandler) {
22514
+ errorHandler(errorMessage);
22515
+ }
22516
+ };
22517
+ reader.readAsDataURL(this.element.files[0]);
22518
+ }
22519
+ }
22520
+ }, {
22521
+ key: "createElement",
22522
+ value: function createElement() {
22523
+ var uploader = document.createElement('input');
22524
+ uploader.style.display = 'none';
22525
+ uploader.id = ImageTool.INPUT_ID;
22526
+ uploader.type = 'file';
22527
+ uploader.accept = supportedMimes.map(function (item) {
22528
+ return "image/".concat(item);
22529
+ }).join(',');
22530
+ document.body.appendChild(uploader);
22531
+ return uploader;
22532
+ }
22533
+ }, {
22534
+ key: "getElement",
22535
+ value: function getElement() {
22536
+ var element = document.getElementById(ImageTool.INPUT_ID);
22537
+ if (element instanceof HTMLInputElement) {
22538
+ return element;
22539
+ }
22540
+ element === null || element === void 0 || element.remove();
22541
+ return this.createElement();
22542
+ }
22543
+ }, {
22544
+ key: "resetElementValue",
22545
+ value: function resetElementValue() {
22546
+ this.getElement().value = '';
22547
+ }
22548
+ }]);
22549
+ return ImageTool;
22550
+ }();
22551
+ _defineProperty$1(ImageTool, "INPUT_ID", 'image-upload');
22552
+
22553
+ var toolsMap = _defineProperty$1({
22353
22554
  hand: HandTool,
22354
22555
  rgroupatom: RGroupAtomTool,
22355
22556
  select: SelectTool,
@@ -22372,7 +22573,7 @@ var toolsMap = {
22372
22573
  enhancedStereo: EnhancedStereoTool,
22373
22574
  simpleobject: SimpleObjectTool,
22374
22575
  text: TextTool
22375
- };
22576
+ }, IMAGE_KEY, ImageTool);
22376
22577
 
22377
22578
  var Highlighter = function () {
22378
22579
  function Highlighter(editor) {
@@ -23243,8 +23444,8 @@ function _classPrivateFieldInitSpec(obj, privateMap, value) { _checkPrivateRedec
23243
23444
  function _checkPrivateRedeclaration(obj, privateCollection) { if (privateCollection.has(obj)) { throw new TypeError("Cannot initialize the same private elements twice on an object"); } }
23244
23445
  var SCALE = provideEditorSettings().microModeScale;
23245
23446
  var HISTORY_SIZE = 32;
23246
- var structObjects = ['atoms', 'bonds', 'frags', 'sgroups', 'sgroupData', 'rgroups', 'rxnArrows', 'rxnPluses', 'enhancedFlags', 'simpleObjects', 'texts'];
23247
- var highlightTargets = ['atoms', 'bonds', 'rxnArrows', 'rxnPluses', 'functionalGroups', 'frags', 'merge', 'rgroups', 'rgroupAttachmentPoints', 'sgroups', 'sgroupData', 'enhancedFlags', 'simpleObjects', 'texts'];
23447
+ var structObjects = ['atoms', 'bonds', 'frags', 'sgroups', 'sgroupData', 'rgroups', 'rxnArrows', 'rxnPluses', 'enhancedFlags', 'simpleObjects', 'texts', IMAGE_KEY];
23448
+ var highlightTargets = ['atoms', 'bonds', 'rxnArrows', 'rxnPluses', 'functionalGroups', 'frags', 'merge', 'rgroups', 'rgroupAttachmentPoints', 'sgroups', 'sgroupData', 'enhancedFlags', 'simpleObjects', 'texts', IMAGE_KEY];
23248
23449
  function selectStereoFlagsIfNecessary(atoms, expAtoms) {
23249
23450
  var atomsOfFragments = {};
23250
23451
  atoms.forEach(function (atom, atomId) {
@@ -23674,7 +23875,7 @@ var Editor$3 = function () {
23674
23875
  value: function structSelected() {
23675
23876
  var struct = this.render.ctab.molecule;
23676
23877
  var selection = this.explicitSelected();
23677
- var dst = struct.clone(new Pile(selection.atoms), new Pile(selection.bonds), true, null, new Pile(selection.simpleObjects), new Pile(selection.texts));
23878
+ var dst = struct.clone(new Pile(selection.atoms), new Pile(selection.bonds), true, null, new Pile(selection.simpleObjects), new Pile(selection.texts), null, new Pile(selection.images));
23678
23879
  struct.rxnArrows.forEach(function (item, id) {
23679
23880
  if (selection.rxnArrows.indexOf(id) !== -1) dst.rxnArrows.add(item.clone());
23680
23881
  });
@@ -24034,6 +24235,10 @@ function ButtonGroup(_ref) {
24034
24235
  }, [onClick]);
24035
24236
  return jsx(ToggleButtonGroup, {
24036
24237
  exclusive: true,
24238
+ style: {
24239
+ overflowX: 'hidden',
24240
+ flexWrap: 'wrap'
24241
+ },
24037
24242
  children: buttons.map(function (_ref2) {
24038
24243
  var label = _ref2.label,
24039
24244
  buttonValue = _ref2.value;
@@ -24044,6 +24249,11 @@ function ButtonGroup(_ref) {
24044
24249
  return handleChange(event, buttonValue);
24045
24250
  },
24046
24251
  className: clsx(classes$F.button, _defineProperty$1({}, classes$F.selected, buttonValue === value)),
24252
+ style: {
24253
+ flex: '1 0 25%',
24254
+ margin: '2px',
24255
+ borderRadius: '3px'
24256
+ },
24047
24257
  children: label || 'none'
24048
24258
  }, label);
24049
24259
  })
@@ -24495,7 +24705,11 @@ var useBondTypeChange = function useBondTypeChange() {
24495
24705
  var disabled = useCallback(function (_ref2) {
24496
24706
  var props = _ref2.props;
24497
24707
  var selectedBondIds = props === null || props === void 0 ? void 0 : props.bondIds;
24708
+ var editor = getKetcherInstance().editor;
24498
24709
  if (Array.isArray(selectedBondIds) && selectedBondIds.length !== 0) {
24710
+ if (editor.struct().isBondFromMacromolecule(selectedBondIds[0])) {
24711
+ return true;
24712
+ }
24499
24713
  return false;
24500
24714
  }
24501
24715
  return true;
@@ -24512,8 +24726,9 @@ var BondMenuItems = function BondMenuItems(props) {
24512
24726
  _useBondEdit2 = _slicedToArray$1(_useBondEdit, 1),
24513
24727
  handleEdit = _useBondEdit2[0];
24514
24728
  var _useBondTypeChange = useBondTypeChange(),
24515
- _useBondTypeChange2 = _slicedToArray$1(_useBondTypeChange, 1),
24516
- handleTypeChange = _useBondTypeChange2[0];
24729
+ _useBondTypeChange2 = _slicedToArray$1(_useBondTypeChange, 2),
24730
+ handleTypeChange = _useBondTypeChange2[0],
24731
+ disabled = _useBondTypeChange2[1];
24517
24732
  var _useBondSGroupAttach = useBondSGroupAttach(),
24518
24733
  _useBondSGroupAttach2 = _slicedToArray$1(_useBondSGroupAttach, 2),
24519
24734
  handleSGroupAttach = _useBondSGroupAttach2[0],
@@ -24525,9 +24740,13 @@ var BondMenuItems = function BondMenuItems(props) {
24525
24740
  sGroupEditHidden = _useBondSGroupEdit2[2];
24526
24741
  var handleDelete = useDelete$1();
24527
24742
  var bondNamesWithoutEmptyValue = nonQueryBondNames.slice(1);
24743
+ var isDisabled = disabled({
24744
+ props: props.propsFromTrigger
24745
+ });
24528
24746
  return jsxs(Fragment, {
24529
24747
  children: [jsx(Item, _objectSpread$L(_objectSpread$L({}, props), {}, {
24530
24748
  onClick: handleEdit,
24749
+ disabled: isDisabled,
24531
24750
  children: (_props$propsFromTrigg = props.propsFromTrigger) !== null && _props$propsFromTrigg !== void 0 && _props$propsFromTrigg.extraItemsSelected ? 'Edit selected bonds...' : 'Edit...'
24532
24751
  })), bondNamesWithoutEmptyValue.map(function (name, i) {
24533
24752
  var iconName = getIconName(name);
@@ -24537,7 +24756,8 @@ var BondMenuItems = function BondMenuItems(props) {
24537
24756
  }, props), {}, {
24538
24757
  id: name,
24539
24758
  onClick: handleTypeChange,
24540
- key: name
24759
+ key: name,
24760
+ disabled: isDisabled
24541
24761
  }), iconName && jsx(Icon, {
24542
24762
  name: iconName,
24543
24763
  className: styles$e.icon
@@ -24553,6 +24773,7 @@ var BondMenuItems = function BondMenuItems(props) {
24553
24773
  className: styles$e.sameGroup,
24554
24774
  id: name,
24555
24775
  onClick: handleTypeChange,
24776
+ disabled: isDisabled,
24556
24777
  children: [iconName && jsx(Icon, {
24557
24778
  name: iconName,
24558
24779
  className: styles$e.icon
@@ -24843,19 +25064,62 @@ var props = {
24843
25064
  var ContextMenu = function ContextMenu() {
24844
25065
  var _useAppContext = useAppContext(),
24845
25066
  getKetcherInstance = _useAppContext.getKetcherInstance;
24846
- var resetMenuPosition = function resetMenuPosition() {
24847
- var contextMenuElement = document.querySelector('.contexify:last-of-type');
25067
+ var adjustSubmenuPosition = function adjustSubmenuPosition(submenuElement) {
25068
+ var rect = submenuElement.getBoundingClientRect();
25069
+ var ketcherRootElement = document.querySelector(KETCHER_ROOT_NODE_CSS_SELECTOR);
25070
+ var ketcherRootElementRect = ketcherRootElement === null || ketcherRootElement === void 0 ? void 0 : ketcherRootElement.getBoundingClientRect();
25071
+ var ketcherEditorWidth = (ketcherRootElementRect === null || ketcherRootElementRect === void 0 ? void 0 : ketcherRootElementRect.width) || 0;
25072
+ var ketcherEditorHeight = (ketcherRootElementRect === null || ketcherRootElementRect === void 0 ? void 0 : ketcherRootElementRect.height) || 0;
25073
+ var ketcherEditorLeft = (ketcherRootElementRect === null || ketcherRootElementRect === void 0 ? void 0 : ketcherRootElementRect.left) || 0;
25074
+ var ketcherEditorTop = (ketcherRootElementRect === null || ketcherRootElementRect === void 0 ? void 0 : ketcherRootElementRect.top) || 0;
25075
+ if (rect.right - ketcherEditorLeft > ketcherEditorWidth) {
25076
+ submenuElement.style.left = 'auto';
25077
+ submenuElement.style.right = '100%';
25078
+ } else {
25079
+ submenuElement.style.left = '100%';
25080
+ submenuElement.style.right = 'auto';
25081
+ }
25082
+ if (rect.bottom - ketcherEditorTop > ketcherEditorHeight) {
25083
+ submenuElement.style.top = 'auto';
25084
+ submenuElement.style.bottom = '0';
25085
+ } else {
25086
+ submenuElement.style.top = '0';
25087
+ submenuElement.style.bottom = 'auto';
25088
+ }
25089
+ };
25090
+ var resetMenuPosition = function resetMenuPosition(menuElement) {
25091
+ var contextMenuElement = menuElement;
24848
25092
  var ketcherRootElement = document.querySelector(KETCHER_ROOT_NODE_CSS_SELECTOR);
24849
25093
  if (!contextMenuElement || !ketcherRootElement) {
24850
25094
  return;
24851
25095
  }
24852
25096
  var contextMenuElementBoundingBox = contextMenuElement.getBoundingClientRect();
24853
25097
  var ketcherRootElementBoundingBox = ketcherRootElement.getBoundingClientRect();
25098
+ var viewportWidth = window.innerWidth;
25099
+ var viewportHeight = window.innerHeight;
24854
25100
  if (!contextMenuElementBoundingBox || !ketcherRootElementBoundingBox) {
24855
25101
  return;
24856
25102
  }
24857
- var left = contextMenuElementBoundingBox.right > ketcherRootElementBoundingBox.right ? contextMenuElementBoundingBox.x - (contextMenuElementBoundingBox.right - ketcherRootElementBoundingBox.right) : contextMenuElementBoundingBox.x;
24858
- var top = contextMenuElementBoundingBox.bottom > ketcherRootElementBoundingBox.bottom ? contextMenuElementBoundingBox.y - (contextMenuElementBoundingBox.bottom - ketcherRootElementBoundingBox.bottom) : contextMenuElementBoundingBox.y;
25103
+ var left = contextMenuElementBoundingBox.left;
25104
+ var top = contextMenuElementBoundingBox.top;
25105
+ if (contextMenuElementBoundingBox.right > ketcherRootElementBoundingBox.right) {
25106
+ left = ketcherRootElementBoundingBox.right - contextMenuElementBoundingBox.width;
25107
+ }
25108
+ if (contextMenuElementBoundingBox.bottom > ketcherRootElementBoundingBox.bottom) {
25109
+ top = ketcherRootElementBoundingBox.bottom - contextMenuElementBoundingBox.height;
25110
+ }
25111
+ if (left < 0) {
25112
+ left = 0;
25113
+ }
25114
+ if (top < 0) {
25115
+ top = 0;
25116
+ }
25117
+ if (contextMenuElementBoundingBox.right > viewportWidth) {
25118
+ left = viewportWidth - contextMenuElementBoundingBox.width - 10;
25119
+ }
25120
+ if (contextMenuElementBoundingBox.bottom > viewportHeight) {
25121
+ top = viewportHeight - contextMenuElementBoundingBox.height - 10;
25122
+ }
24859
25123
  contextMenuElement.style.left = "".concat(left, "px");
24860
25124
  contextMenuElement.style.top = "".concat(top, "px");
24861
25125
  };
@@ -24863,7 +25127,18 @@ var ContextMenu = function ContextMenu() {
24863
25127
  var editor = getKetcherInstance().editor;
24864
25128
  if (visible) {
24865
25129
  editor.hoverIcon.hide();
24866
- resetMenuPosition();
25130
+ var contextMenuElement = document.querySelector('.contexify:last-of-type');
25131
+ var submenuElements = document.querySelectorAll('.contexify_submenu');
25132
+ if (contextMenuElement) {
25133
+ setTimeout(function () {
25134
+ return resetMenuPosition(contextMenuElement);
25135
+ }, 0);
25136
+ }
25137
+ if (submenuElements.length) {
25138
+ submenuElements.forEach(function (submenuElement) {
25139
+ adjustSubmenuPosition(submenuElement);
25140
+ });
25141
+ }
24867
25142
  }
24868
25143
  editor.contextMenu[id] = visible;
24869
25144
  }, [getKetcherInstance]);
@@ -28242,13 +28517,14 @@ function AtomListValid(value, atomType, isCustomQuery) {
28242
28517
  }
28243
28518
  return value.length >= 1;
28244
28519
  }
28245
- function pseudoAtomValid(value, atomType, isCustomQuery) {
28246
- genericsList.includes(capitalize$1(value));
28247
- var isGenericElement = genericsList.includes(value);
28248
- if (atomType !== 'pseudo' || isCustomQuery) {
28249
- return true;
28520
+ function pseudoAtomValid(value, atomType, isCustomQuery, disableQueryElements) {
28521
+ var capitalizedValue = capitalize$1(value);
28522
+ var isDisabledQueryElement = disableQueryElements === null || disableQueryElements === void 0 ? void 0 : disableQueryElements.includes(capitalizedValue);
28523
+ if (atomType === 'pseudo' && isDisabledQueryElement) {
28524
+ return false;
28250
28525
  }
28251
- return value && isGenericElement;
28526
+ var isGenericElement = genericsList.includes(capitalizedValue);
28527
+ return atomType !== 'pseudo' || isCustomQuery || value && isGenericElement;
28252
28528
  }
28253
28529
  function chargeValid(charge, isMultipleAtoms, isCustomQuery) {
28254
28530
  var result = matchCharge(charge);
@@ -28425,12 +28701,13 @@ var Atom = function Atom(props) {
28425
28701
  };
28426
28702
  var customValid = useMemo(function () {
28427
28703
  var atomType = formState.result.atomType;
28704
+ var disableQueryElements = SettingsManager.getOptions().disableQueryElements;
28428
28705
  return {
28429
28706
  label: function label(_label) {
28430
28707
  return atomValid(_label, isMultipleAtoms, atomType, isCustomQuery);
28431
28708
  },
28432
28709
  pseudo: function pseudo(value) {
28433
- return pseudoAtomValid(value, atomType, isCustomQuery);
28710
+ return pseudoAtomValid(value, atomType, isCustomQuery, disableQueryElements);
28434
28711
  },
28435
28712
  atomList: function atomList(value) {
28436
28713
  return AtomListValid(value, atomType, isCustomQuery);
@@ -30916,11 +31193,8 @@ function mapSelectionToProps(editor) {
30916
31193
  }
30917
31194
  return {};
30918
31195
  }
30919
- var mapStateToProps$2 = function mapStateToProps(state, ownProps) {
31196
+ var mapStateToProps$2 = function mapStateToProps(state) {
30920
31197
  var editor = state.editor;
30921
- if (ownProps.values || ownProps.label) {
30922
- return {};
30923
- }
30924
31198
  var disabledQueryElements = editor.render.options.disableQueryElements;
30925
31199
  return _objectSpread$c({
30926
31200
  disabledQueryElements: disabledQueryElements
@@ -32504,7 +32778,7 @@ function initEditor(dispatch, getState) {
32504
32778
  return dlg.then(toElement);
32505
32779
  },
32506
32780
  onEnhancedStereoEdit: function onEnhancedStereoEdit(_ref3) {
32507
- var init = _extends$3j({}, (_objectDestructuringEmpty(_ref3), _ref3));
32781
+ var init = _extends$3k({}, (_objectDestructuringEmpty(_ref3), _ref3));
32508
32782
  return sleep(0).then(function () {
32509
32783
  init = fromStereoLabel(init.stereoLabel);
32510
32784
  return openDialog(dispatch, 'enhancedStereo', {
@@ -32980,18 +33254,32 @@ var MOUSE_MOVE_THROTTLE_TIMEOUT = 300;
32980
33254
  var handleMouseMove = function handleMouseMove(dispatch, event) {
32981
33255
  dispatch(updateCursorPosition(event.clientX, event.clientY));
32982
33256
  };
33257
+ var pointerMoveListener = null;
33258
+ var mouseDownListener = null;
32983
33259
  function initMouseListener(element) {
32984
33260
  return function (dispatch, getState) {
32985
33261
  var throttledHandleMouseMove = throttle$1(handleMouseMove, MOUSE_MOVE_THROTTLE_TIMEOUT);
32986
- element.addEventListener('pointermove', function (event) {
33262
+ pointerMoveListener = function pointerMoveListener(event) {
32987
33263
  return throttledHandleMouseMove(dispatch, event);
32988
- });
32989
- element.addEventListener('mousedown', function (event) {
33264
+ };
33265
+ mouseDownListener = function mouseDownListener(event) {
32990
33266
  var areBothLeftAndRightButtonsClicked = event.buttons === 3;
32991
33267
  if (areBothLeftAndRightButtonsClicked) {
32992
33268
  handleRightClick(getState);
32993
33269
  }
32994
- }, true);
33270
+ };
33271
+ element.addEventListener('pointermove', pointerMoveListener);
33272
+ element.addEventListener('mousedown', mouseDownListener, true);
33273
+ };
33274
+ }
33275
+ function removeMouseListeners(element) {
33276
+ return function () {
33277
+ if (pointerMoveListener) {
33278
+ element.removeEventListener('pointermove', pointerMoveListener);
33279
+ }
33280
+ if (mouseDownListener) {
33281
+ element.addEventListener('mousedown', mouseDownListener, true);
33282
+ }
32995
33283
  };
32996
33284
  }
32997
33285
  function handleRightClick(getState) {
@@ -33008,14 +33296,22 @@ function initApp(element, appRoot, staticResourcesUrl, options, server, resolve,
33008
33296
  ketcherRef = ketcher;
33009
33297
  };
33010
33298
  var ketcherId = uniqueId();
33299
+ var getServerSetter;
33011
33300
  var setEditor = function setEditor(editor) {
33301
+ var setServer = getServerSetter();
33012
33302
  resolve({
33013
33303
  editor: editor,
33014
33304
  setKetcher: setKetcher,
33015
- ketcherId: ketcherId
33305
+ ketcherId: ketcherId,
33306
+ setServer: setServer
33016
33307
  });
33017
33308
  };
33018
33309
  var store = createStore(options, server, setEditor);
33310
+ getServerSetter = function getServerSetter() {
33311
+ return function (structService) {
33312
+ store.dispatch(setServer(structService));
33313
+ };
33314
+ };
33019
33315
  store.dispatch(initKeydownListener(element));
33020
33316
  store.dispatch(initMouseListener(element));
33021
33317
  store.dispatch(initResize());
@@ -33043,6 +33339,10 @@ function initApp(element, appRoot, staticResourcesUrl, options, server, resolve,
33043
33339
  })
33044
33340
  })
33045
33341
  }));
33342
+ return function () {
33343
+ store.dispatch(removeKeydownListener(element));
33344
+ store.dispatch(removeMouseListeners(element));
33345
+ };
33046
33346
  }
33047
33347
 
33048
33348
  var indigo;
@@ -33091,6 +33391,28 @@ var KetcherBuilder = function () {
33091
33391
  }
33092
33392
  return appendApiAsync;
33093
33393
  }()
33394
+ }, {
33395
+ key: "reinitializeApi",
33396
+ value: function reinitializeApi(structServiceProvider, setStructServiceToStore) {
33397
+ var _this = this;
33398
+ var oldStructService = this.structService;
33399
+ this.structService = createApi(structServiceProvider, DefaultStructServiceOptions);
33400
+ window.addEventListener(STRUCT_SERVICE_INITIALIZED_EVENT, function () {
33401
+ var _oldStructService$des;
33402
+ oldStructService === null || oldStructService === void 0 || (_oldStructService$des = oldStructService.destroy) === null || _oldStructService$des === void 0 || _oldStructService$des.call(oldStructService);
33403
+ if (!_this.structService) {
33404
+ KetcherLogger.warn('Structure service is not reinitialized');
33405
+ return;
33406
+ }
33407
+ var ketcher = ketcherProvider.getKetcher();
33408
+ ketcher.reinitializeIndigo(_this.structService);
33409
+ IndigoProvider.setIndigo(_this.structService);
33410
+ setStructServiceToStore(_this.structService);
33411
+ }, {
33412
+ once: true
33413
+ });
33414
+ return this.structService;
33415
+ }
33094
33416
  }, {
33095
33417
  key: "appendServiceMode",
33096
33418
  value: function appendServiceMode(mode) {
@@ -33100,35 +33422,39 @@ var KetcherBuilder = function () {
33100
33422
  key: "appendUiAsync",
33101
33423
  value: function () {
33102
33424
  var _appendUiAsync = _asyncToGenerator( _regeneratorRuntime.mark(function _callee2(element, appRoot, staticResourcesUrl, errorHandler, buttons, togglerComponent) {
33103
- var structService, _yield$Promise, editor, setKetcher, ketcherId;
33425
+ var structService, cleanup, _yield$Promise, editor, setKetcher, ketcherId, setServer;
33104
33426
  return _regeneratorRuntime.wrap(function _callee2$(_context2) {
33105
33427
  while (1) switch (_context2.prev = _context2.next) {
33106
33428
  case 0:
33107
33429
  structService = this.structService;
33108
- _context2.next = 3;
33430
+ cleanup = null;
33431
+ _context2.next = 4;
33109
33432
  return new Promise(function (resolve) {
33110
- initApp(element, appRoot, staticResourcesUrl, {
33433
+ cleanup = initApp(element, appRoot, staticResourcesUrl, {
33111
33434
  buttons: buttons || {},
33112
33435
  errorHandler: errorHandler || null,
33113
- version: "2.23.0-rc.4" ,
33114
- buildDate: "2024-08-14T15:07:42" ,
33436
+ version: "2.24.0-rc.2" ,
33437
+ buildDate: "2024-08-14T18:22:51" ,
33115
33438
  buildNumber: ''
33116
33439
  }, structService, resolve, togglerComponent);
33117
33440
  });
33118
- case 3:
33441
+ case 4:
33119
33442
  _yield$Promise = _context2.sent;
33120
33443
  editor = _yield$Promise.editor;
33121
33444
  setKetcher = _yield$Promise.setKetcher;
33122
33445
  ketcherId = _yield$Promise.ketcherId;
33446
+ setServer = _yield$Promise.setServer;
33123
33447
  this.editor = editor;
33124
33448
  this.editor.errorHandler = errorHandler && typeof errorHandler === 'function' ? errorHandler :
33125
33449
  function () {};
33126
33450
  this.formatterFactory = new FormatterFactory(structService);
33127
33451
  return _context2.abrupt("return", {
33128
33452
  setKetcher: setKetcher,
33129
- ketcherId: ketcherId
33453
+ ketcherId: ketcherId,
33454
+ cleanup: cleanup,
33455
+ setServer: setServer
33130
33456
  });
33131
- case 11:
33457
+ case 13:
33132
33458
  case "end":
33133
33459
  return _context2.stop();
33134
33460
  }
@@ -33175,7 +33501,7 @@ function buildKetcherAsync(_x) {
33175
33501
  }
33176
33502
  function _buildKetcherAsync() {
33177
33503
  _buildKetcherAsync = _asyncToGenerator( _regeneratorRuntime.mark(function _callee(_ref) {
33178
- var element, appRoot, staticResourcesUrl, structServiceProvider, buttons, errorHandler, togglerComponent, builder, _yield$builder$append, setKetcher, ketcherId, ketcher;
33504
+ var element, appRoot, staticResourcesUrl, structServiceProvider, buttons, errorHandler, togglerComponent, builder, _yield$builder$append, setKetcher, ketcherId, cleanup, setServer, ketcher;
33179
33505
  return _regeneratorRuntime.wrap(function _callee$(_context) {
33180
33506
  while (1) switch (_context.prev = _context.next) {
33181
33507
  case 0:
@@ -33191,15 +33517,20 @@ function _buildKetcherAsync() {
33191
33517
  _yield$builder$append = _context.sent;
33192
33518
  setKetcher = _yield$builder$append.setKetcher;
33193
33519
  ketcherId = _yield$builder$append.ketcherId;
33520
+ cleanup = _yield$builder$append.cleanup;
33521
+ setServer = _yield$builder$append.setServer;
33194
33522
  ketcher = builder.build();
33195
33523
  if (ketcher) {
33196
33524
  setKetcher(ketcher);
33197
33525
  }
33198
33526
  return _context.abrupt("return", {
33199
33527
  ketcher: ketcher,
33200
- ketcherId: ketcherId
33528
+ ketcherId: ketcherId,
33529
+ cleanup: cleanup,
33530
+ builder: builder,
33531
+ setServer: setServer
33201
33532
  });
33202
- case 13:
33533
+ case 15:
33203
33534
  case "end":
33204
33535
  return _context.stop();
33205
33536
  }
@@ -33217,30 +33548,60 @@ var mediaSizes = {
33217
33548
  smallHeight: 600
33218
33549
  };
33219
33550
  function Editor(props) {
33551
+ var initPromiseRef = useRef(null);
33552
+ var appRootRef = useRef(null);
33553
+ var cleanupRef = useRef(null);
33554
+ var ketcherBuilderRef = useRef(null);
33555
+ var setServerRef = useRef(function () {});
33556
+ var structServiceProvider = props.structServiceProvider;
33220
33557
  var rootElRef = useRef(null);
33221
- var onInit = props.onInit;
33222
33558
  var _useResizeObserver = useThrottleResizeObserver({
33223
33559
  ref: rootElRef
33224
33560
  }),
33225
33561
  height = _useResizeObserver.height,
33226
33562
  width = _useResizeObserver.width;
33227
33563
  useEffect(function () {
33228
- var appRoot = createRoot(rootElRef.current);
33229
- buildKetcherAsync(_objectSpread(_objectSpread({}, props), {}, {
33564
+ var _ketcherBuilderRef$cu;
33565
+ (_ketcherBuilderRef$cu = ketcherBuilderRef.current) === null || _ketcherBuilderRef$cu === void 0 || _ketcherBuilderRef$cu.reinitializeApi(props.structServiceProvider, setServerRef.current);
33566
+ }, [structServiceProvider]);
33567
+ var initKetcher = function initKetcher() {
33568
+ var _initPromiseRef$curre;
33569
+ appRootRef.current = createRoot(rootElRef.current);
33570
+ initPromiseRef.current = buildKetcherAsync(_objectSpread(_objectSpread({}, props), {}, {
33230
33571
  element: rootElRef.current,
33231
- appRoot: appRoot
33232
- })).then(function (_ref) {
33572
+ appRoot: appRootRef.current
33573
+ }));
33574
+ (_initPromiseRef$curre = initPromiseRef.current) === null || _initPromiseRef$curre === void 0 || _initPromiseRef$curre.then(function (_ref) {
33233
33575
  var ketcher = _ref.ketcher,
33234
- ketcherId = _ref.ketcherId;
33235
- if (typeof onInit === 'function' && ketcher) {
33236
- onInit(ketcher);
33576
+ ketcherId = _ref.ketcherId,
33577
+ cleanup = _ref.cleanup,
33578
+ builder = _ref.builder,
33579
+ setServer = _ref.setServer;
33580
+ cleanupRef.current = cleanup;
33581
+ ketcherBuilderRef.current = builder;
33582
+ setServerRef.current = setServer;
33583
+ if (typeof props.onInit === 'function' && ketcher) {
33584
+ props.onInit(ketcher);
33237
33585
  var ketcherInitEvent = new Event(ketcherInitEventName(ketcherId));
33238
33586
  window.dispatchEvent(ketcherInitEvent);
33239
33587
  }
33240
33588
  });
33589
+ };
33590
+ useEffect(function () {
33591
+ if (initPromiseRef.current === null) {
33592
+ initKetcher();
33593
+ } else {
33594
+ var _initPromiseRef$curre2;
33595
+ (_initPromiseRef$curre2 = initPromiseRef.current) === null || _initPromiseRef$curre2 === void 0 || _initPromiseRef$curre2["finally"](function () {
33596
+ initKetcher();
33597
+ });
33598
+ }
33241
33599
  return function () {
33242
- setTimeout(function () {
33243
- appRoot.unmount();
33600
+ var _initPromiseRef$curre3;
33601
+ (_initPromiseRef$curre3 = initPromiseRef.current) === null || _initPromiseRef$curre3 === void 0 || _initPromiseRef$curre3.then(function () {
33602
+ var _cleanupRef$current, _appRootRef$current;
33603
+ (_cleanupRef$current = cleanupRef.current) === null || _cleanupRef$current === void 0 || _cleanupRef$current.call(cleanupRef);
33604
+ (_appRootRef$current = appRootRef.current) === null || _appRootRef$current === void 0 || _appRootRef$current.unmount();
33244
33605
  });
33245
33606
  };
33246
33607
  }, []);
@@ -33250,5 +33611,5 @@ function Editor(props) {
33250
33611
  });
33251
33612
  }
33252
33613
 
33253
- export { Accordion$1 as Accordion, appContext as AppContext, Button, Dialog, Editor, EditorClassName, Icon, IconButton, IndigoProvider, InfoModal$1 as InfoModal, Input$2 as Input, KETCHER_MACROMOLECULES_ROOT_NODE_SELECTOR, KETCHER_ROOT_NODE_CLASS_NAME, KETCHER_ROOT_NODE_CSS_SELECTOR, MODES, STRUCT_TYPE, StructRender, getIconName, ketcherInitEventName };
33614
+ export { Accordion$1 as Accordion, appContext as AppContext, Button, Dialog, Editor, EditorClassName, Icon, IconButton, IndigoProvider, InfoModal$1 as InfoModal, Input$2 as Input, KETCHER_MACROMOLECULES_ROOT_NODE_SELECTOR, KETCHER_ROOT_NODE_CLASS_NAME, KETCHER_ROOT_NODE_CSS_SELECTOR, MODES, STRUCT_SERVICE_INITIALIZED_EVENT, STRUCT_SERVICE_NO_RENDER_INITIALIZED_EVENT, STRUCT_TYPE, StructRender, getIconName, ketcherInitEventName };
33254
33615
  //# sourceMappingURL=index.modern.js.map