@umbraci/jsmind 0.10.14 → 0.10.17

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.
Files changed (70) hide show
  1. package/LICENSE +24 -24
  2. package/README.md +116 -116
  3. package/dist/jsmind.copy-paste.js +9 -0
  4. package/dist/jsmind.copy-paste.js.map +1 -0
  5. package/dist/jsmind.draggable-node.js +1 -1
  6. package/dist/jsmind.draggable-node.js.map +1 -1
  7. package/dist/jsmind.history.js +1 -1
  8. package/dist/jsmind.history.js.map +1 -1
  9. package/dist/jsmind.js +1 -1
  10. package/dist/jsmind.js.map +1 -1
  11. package/dist/jsmind.multi-select.js +1 -1
  12. package/dist/jsmind.multi-select.js.map +1 -1
  13. package/dist/jsmind.multiline-text.js +1 -1
  14. package/dist/jsmind.multiline-text.js.map +1 -1
  15. package/dist/jsmind.screenshot.js +1 -1
  16. package/dist/jsmind.screenshot.js.map +1 -1
  17. package/es/jsmind.copy-paste.js +9 -0
  18. package/es/jsmind.copy-paste.js.map +1 -0
  19. package/es/jsmind.draggable-node.js +1 -1
  20. package/es/jsmind.draggable-node.js.map +1 -1
  21. package/es/jsmind.history.js +1 -1
  22. package/es/jsmind.history.js.map +1 -1
  23. package/es/jsmind.js +1 -1
  24. package/es/jsmind.js.map +1 -1
  25. package/es/jsmind.multi-select.js +1 -1
  26. package/es/jsmind.multi-select.js.map +1 -1
  27. package/es/jsmind.multiline-text.js +1 -1
  28. package/es/jsmind.multiline-text.js.map +1 -1
  29. package/es/jsmind.screenshot.js +1 -1
  30. package/es/jsmind.screenshot.js.map +1 -1
  31. package/lib/jsmind.copy-paste.js +9 -0
  32. package/lib/jsmind.copy-paste.js.map +1 -0
  33. package/lib/jsmind.draggable-node.js +1 -1
  34. package/lib/jsmind.draggable-node.js.map +1 -1
  35. package/lib/jsmind.history.js +1 -1
  36. package/lib/jsmind.history.js.map +1 -1
  37. package/lib/jsmind.js +1 -1
  38. package/lib/jsmind.js.map +1 -1
  39. package/lib/jsmind.multi-select.js +1 -1
  40. package/lib/jsmind.multi-select.js.map +1 -1
  41. package/lib/jsmind.multiline-text.js +1 -1
  42. package/lib/jsmind.multiline-text.js.map +1 -1
  43. package/lib/jsmind.screenshot.js +1 -1
  44. package/lib/jsmind.screenshot.js.map +1 -1
  45. package/package.json +115 -115
  46. package/style/jsmind.css +408 -408
  47. package/types/generated/index.d.ts +8 -0
  48. package/types/generated/jsmind.common.d.ts +68 -0
  49. package/types/generated/jsmind.d.ts +438 -0
  50. package/types/generated/jsmind.data_provider.d.ts +56 -0
  51. package/types/generated/jsmind.dom.d.ts +59 -0
  52. package/types/generated/jsmind.enhanced-plugin.d.ts +103 -0
  53. package/types/generated/jsmind.format.d.ts +113 -0
  54. package/types/generated/jsmind.graph.d.ts +180 -0
  55. package/types/generated/jsmind.layout_provider.d.ts +182 -0
  56. package/types/generated/jsmind.mind.d.ts +121 -0
  57. package/types/generated/jsmind.node.d.ts +69 -0
  58. package/types/generated/jsmind.option.d.ts +73 -0
  59. package/types/generated/jsmind.plugin.d.ts +21 -0
  60. package/types/generated/jsmind.shortcut_provider.d.ts +52 -0
  61. package/types/generated/jsmind.util.d.ts +26 -0
  62. package/types/generated/jsmind.view_provider.d.ts +347 -0
  63. package/types/generated/plugins/history/history-diff.d.ts +297 -0
  64. package/types/generated/plugins/history/jsmind.history.d.ts +87 -0
  65. package/types/generated/plugins/jsmind.draggable-node.d.ts +262 -0
  66. package/types/generated/plugins/jsmind.multi-select.d.ts +238 -0
  67. package/types/generated/plugins/jsmind.multiline-text-v2.d.ts +58 -0
  68. package/types/generated/plugins/jsmind.multiline-text.d.ts +43 -0
  69. package/types/generated/plugins/jsmind.screenshot.d.ts +83 -0
  70. package/types/tsconfig.declaration.json +19 -19
@@ -1 +1 @@
1
- {"version":3,"file":"jsmind.draggable-node.js","sources":["../src/plugins/jsmind.draggable-node.js"],"sourcesContent":["/**\r\n * @license BSD\r\n * @copyright 2014-2025 UmbraCi\r\n *\r\n * Project Home:\r\n * https://github.com/UmbraCi/jsmind/\r\n */\r\n\r\nimport jsMind from '@umbraci/jsmind';\r\n\r\nif (!jsMind) {\r\n throw new Error('jsMind is not defined');\r\n}\r\n\r\nconst $ = jsMind.$;\r\n\r\nconst clear_selection =\r\n 'getSelection' in $.w\r\n ? function () {\r\n $.w.getSelection().removeAllRanges();\r\n }\r\n : function () {\r\n $.d.selection.empty();\r\n };\r\n\r\n/**\r\n * Default options for draggable node plugin.\r\n * @typedef {Object} DraggableNodeOptions\r\n * @property {number} [line_width]\r\n * @property {string} [line_color]\r\n * @property {string} [line_color_invalid]\r\n * @property {number} [lookup_delay]\r\n * @property {number} [lookup_interval]\r\n * @property {number} [scrolling_trigger_width]\r\n * @property {number} [scrolling_step_length]\r\n * @property {string} [shadow_node_class_name]\r\n * @property {(draggedNode:import('../jsmind.node.js').Node, targetNode:import('../jsmind.node.js').Node|null)=>boolean} [validate_drag]\r\n */\r\nconst DEFAULT_OPTIONS = {\r\n line_width: 5,\r\n line_color: 'rgba(0,0,0,0.3)',\r\n line_color_invalid: 'rgba(255,51,51,0.6)',\r\n lookup_delay: 200,\r\n lookup_interval: 100,\r\n scrolling_trigger_width: 20,\r\n scrolling_step_length: 10,\r\n shadow_node_class_name: 'jsmind-draggable-shadow-node',\r\n};\r\n\r\n/**\r\n * Draggable node plugin for jsMind.\r\n */\r\nexport class DraggableNode {\r\n /**\r\n * Create draggable node plugin instance.\r\n * @param {import('../jsmind.js').default} jm - jsMind instance\r\n * @param {Partial<DraggableNodeOptions>} options - Plugin options\r\n */\r\n constructor(jm, options) {\r\n var opts = {};\r\n jsMind.util.json.merge(opts, DEFAULT_OPTIONS);\r\n jsMind.util.json.merge(opts, options);\r\n\r\n this.version = '0.4.0';\r\n /** @type {import('../jsmind.js').default} */\r\n this.jm = jm;\r\n /** @type {DraggableNodeOptions} */\r\n this.options = opts;\r\n /** @type {boolean} */\r\n this.is_svg_engine = jm.view.opts.engine === 'svg';\r\n /** @type {HTMLCanvasElement|SVGSVGElement|null} */\r\n this.e_canvas = null;\r\n /** @type {CanvasRenderingContext2D|null} */\r\n this.canvas_ctx = null;\r\n /** @type {SVGPathElement|null} */\r\n this.helper_line = null;\r\n /** @type {HTMLElement|null} */\r\n this.shadow = null;\r\n /** @type {number} */\r\n this.shadow_p_x = 0;\r\n /** @type {number} */\r\n this.shadow_p_y = 0;\r\n /** @type {number} */\r\n this.shadow_w = 0;\r\n /** @type {number} */\r\n this.shadow_h = 0;\r\n /** @type {import('../jsmind.node.js').Node|null} */\r\n this.active_node = null;\r\n /** @type {import('../jsmind.node.js').Node|null} */\r\n this.target_node = null;\r\n /** @type {number|null} */\r\n this.target_direct = null;\r\n /** @type {number} */\r\n this.client_w = 0;\r\n /** @type {number} */\r\n this.client_h = 0;\r\n /** @type {number} */\r\n this.offset_x = 0;\r\n /** @type {number} */\r\n this.offset_y = 0;\r\n /** @type {number} */\r\n this.hlookup_delay = 0;\r\n /** @type {number} */\r\n this.hlookup_timer = 0;\r\n /** @type {boolean} */\r\n this.capture = false;\r\n /** @type {boolean} */\r\n this.moved = false;\r\n /** @type {boolean} */\r\n this.canvas_draggable = jm.get_view_draggable();\r\n /** @type {HTMLElement} */\r\n this.view_panel = jm.view.e_panel;\r\n /** @type {DOMRect|null} */\r\n this.view_panel_rect = null;\r\n }\r\n /** Initialize the draggable node plugin. */\r\n init() {\r\n this.create_canvas();\r\n this.create_shadow();\r\n this.event_bind();\r\n }\r\n /** Resize canvas/SVG and shadow elements. */\r\n resize() {\r\n this.jm.view.e_nodes.appendChild(this.shadow);\r\n if (this.is_svg_engine) {\r\n this.e_canvas.setAttribute('width', this.jm.view.size.w);\r\n this.e_canvas.setAttribute('height', this.jm.view.size.h);\r\n } else {\r\n this.e_canvas.width = this.jm.view.size.w;\r\n this.e_canvas.height = this.jm.view.size.h;\r\n }\r\n }\r\n /** Create canvas or SVG for drawing drag lines. */\r\n create_canvas() {\r\n if (this.is_svg_engine) {\r\n // Create SVG element for helper lines\r\n var svg = this._create_svg_element('svg');\r\n svg.setAttribute('class', 'jsmind-draggable-helper');\r\n svg.setAttribute('style', 'position: absolute; top: 0; left: 0; pointer-events: none;');\r\n this.jm.view.e_panel.appendChild(svg);\r\n this.e_canvas = svg;\r\n } else {\r\n // Create Canvas element for helper lines\r\n var c = $.c('canvas');\r\n this.jm.view.e_panel.appendChild(c);\r\n var ctx = c.getContext('2d');\r\n this.e_canvas = c;\r\n this.canvas_ctx = ctx;\r\n }\r\n }\r\n /**\r\n * Create SVG element with proper namespace.\r\n * @param {string} tag - SVG tag name\r\n * @returns {SVGElement}\r\n * @private\r\n */\r\n _create_svg_element(tag) {\r\n return $.d.createElementNS('http://www.w3.org/2000/svg', tag);\r\n }\r\n create_shadow() {\r\n var s = $.c('jmnode');\r\n s.style.visibility = 'hidden';\r\n s.style.zIndex = '3';\r\n s.style.cursor = 'move';\r\n s.style.opacity = '0.7';\r\n s.className = this.options.shadow_node_class_name;\r\n this.shadow = s;\r\n }\r\n /**\r\n * Reset shadow element style and cache its size.\r\n * @param {HTMLElement} el - The node element to mirror as shadow\r\n */\r\n reset_shadow(el) {\r\n var s = this.shadow.style;\r\n this.shadow.innerHTML = el.innerHTML;\r\n s.left = el.style.left;\r\n s.top = el.style.top;\r\n s.width = el.style.width;\r\n s.height = el.style.height;\r\n s.backgroundImage = el.style.backgroundImage;\r\n s.backgroundSize = el.style.backgroundSize;\r\n s.transform = el.style.transform;\r\n this.shadow_w = this.shadow.clientWidth;\r\n this.shadow_h = this.shadow.clientHeight;\r\n }\r\n /** Show the shadow element. */\r\n show_shadow() {\r\n if (!this.moved) {\r\n this.shadow.style.visibility = 'visible';\r\n }\r\n }\r\n /** Hide the shadow element. */\r\n hide_shadow() {\r\n this.shadow.style.visibility = 'hidden';\r\n }\r\n /**\r\n * Draw a helper line between the shadow and target node.\r\n * @param {{x:number,y:number}} shadow_p - Shadow anchor point\r\n * @param {{x:number,y:number}} node_p - Target node anchor point\r\n * @param {boolean} invalid - Whether current target is invalid\r\n */\r\n magnet_shadow(shadow_p, node_p, invalid) {\r\n this.clear_lines();\r\n var color = invalid ? this.options.line_color_invalid : this.options.line_color;\r\n\r\n if (this.is_svg_engine) {\r\n this.svg_draw_line(shadow_p.x, shadow_p.y, node_p.x, node_p.y, color);\r\n } else {\r\n this.canvas_ctx.lineWidth = this.options.line_width;\r\n this.canvas_ctx.strokeStyle = color;\r\n this.canvas_ctx.lineCap = 'round';\r\n this.canvas_lineto(shadow_p.x, shadow_p.y, node_p.x, node_p.y);\r\n }\r\n }\r\n /** Clear helper lines from canvas or SVG. */\r\n clear_lines() {\r\n if (this.is_svg_engine) {\r\n if (this.helper_line && this.helper_line.parentNode) {\r\n this.e_canvas.removeChild(this.helper_line);\r\n this.helper_line = null;\r\n }\r\n } else {\r\n this.canvas_ctx.clearRect(0, 0, this.jm.view.size.w, this.jm.view.size.h);\r\n }\r\n }\r\n /**\r\n * Draw a straight helper line on canvas.\r\n * @param {number} x1\r\n * @param {number} y1\r\n * @param {number} x2\r\n * @param {number} y2\r\n */\r\n canvas_lineto(x1, y1, x2, y2) {\r\n this.canvas_ctx.beginPath();\r\n this.canvas_ctx.moveTo(x1, y1);\r\n this.canvas_ctx.lineTo(x2, y2);\r\n this.canvas_ctx.stroke();\r\n }\r\n /**\r\n * Draw a helper line on SVG using bezier curve.\r\n * Reuses the line drawing logic from SvgGraph.\r\n * @param {number} x1 - Start x coordinate\r\n * @param {number} y1 - Start y coordinate\r\n * @param {number} x2 - End x coordinate\r\n * @param {number} y2 - End y coordinate\r\n * @param {string} color - Line color\r\n */\r\n svg_draw_line(x1, y1, x2, y2, color) {\r\n // Create SVG path element for helper line\r\n this.helper_line = this._create_svg_element('path');\r\n this.helper_line.setAttribute('stroke', color);\r\n this.helper_line.setAttribute('stroke-width', this.options.line_width);\r\n this.helper_line.setAttribute('fill', 'transparent');\r\n this.helper_line.setAttribute('stroke-linecap', 'round');\r\n\r\n // Draw bezier curve (same as SvgGraph._bezier_to)\r\n this._svg_bezier_to(this.helper_line, x1, y1, x2, y2);\r\n\r\n // Add to SVG container\r\n this.e_canvas.appendChild(this.helper_line);\r\n }\r\n /**\r\n * Draw bezier curve to SVG path element.\r\n * Reuses logic from SvgGraph._bezier_to.\r\n * @param {SVGPathElement} path - SVG path element\r\n * @param {number} x1 - Start x coordinate\r\n * @param {number} y1 - Start y coordinate\r\n * @param {number} x2 - End x coordinate\r\n * @param {number} y2 - End y coordinate\r\n * @private\r\n */\r\n _svg_bezier_to(path, x1, y1, x2, y2) {\r\n path.setAttribute(\r\n 'd',\r\n 'M ' +\r\n x1 +\r\n ' ' +\r\n y1 +\r\n ' C ' +\r\n (x1 + ((x2 - x1) * 2) / 3) +\r\n ' ' +\r\n y1 +\r\n ', ' +\r\n x1 +\r\n ' ' +\r\n y2 +\r\n ', ' +\r\n x2 +\r\n ' ' +\r\n y2\r\n );\r\n }\r\n /** Bind mouse/touch events for dragging. */\r\n event_bind() {\r\n var jd = this;\r\n var container = this.jm.view.container;\r\n $.on(container, 'mousedown', function (e) {\r\n if (e.button === 0) {\r\n jd.dragstart.call(jd, e);\r\n }\r\n });\r\n $.on(container, 'mousemove', function (e) {\r\n if (e.movementX !== 0 || e.movementY !== 0) {\r\n jd.drag.call(jd, e);\r\n }\r\n });\r\n $.on(container, 'mouseup', function (e) {\r\n jd.dragend.call(jd, e);\r\n });\r\n $.on(container, 'touchstart', function (e) {\r\n jd.dragstart.call(jd, e);\r\n });\r\n $.on(container, 'touchmove', function (e) {\r\n jd.drag.call(jd, e);\r\n });\r\n $.on(container, 'touchend', function (e) {\r\n jd.dragend.call(jd, e);\r\n });\r\n }\r\n /**\r\n * Begin dragging interaction.\r\n * @param {MouseEvent|TouchEvent} e - Pointer down event\r\n */\r\n dragstart(e) {\r\n if (!this.jm.get_editable()) {\r\n return;\r\n }\r\n if (this.capture) {\r\n return;\r\n }\r\n var jview = this.jm.view;\r\n if (jview.is_editing()) {\r\n return;\r\n }\r\n this.active_node = null;\r\n this.view_draggable = this.jm.get_view_draggable();\r\n\r\n var el = this.find_node_element(e.target);\r\n if (!el) {\r\n return;\r\n }\r\n if (this.view_draggable) {\r\n this.jm.disable_view_draggable();\r\n }\r\n var nodeid = jview.get_binded_nodeid(el);\r\n if (!!nodeid) {\r\n var node = this.jm.get_node(nodeid);\r\n if (!node.isroot) {\r\n // 检查节点是否允许拖拽\r\n if (node.data && node.data.draggable === false) {\r\n return;\r\n }\r\n this.reset_shadow(el);\r\n this.view_panel_rect = this.view_panel.getBoundingClientRect();\r\n this.active_node = node;\r\n this.offset_x =\r\n (e.clientX || e.touches[0].clientX) / jview.zoom_current - el.offsetLeft;\r\n this.offset_y =\r\n (e.clientY || e.touches[0].clientY) / jview.zoom_current - el.offsetTop;\r\n this.client_hw = Math.floor(el.clientWidth / 2);\r\n this.client_hh = Math.floor(el.clientHeight / 2);\r\n if (this.hlookup_delay != 0) {\r\n $.w.clearTimeout(this.hlookup_delay);\r\n }\r\n if (this.hlookup_timer != 0) {\r\n $.w.clearInterval(this.hlookup_timer);\r\n }\r\n var jd = this;\r\n this.hlookup_delay = $.w.setTimeout(function () {\r\n jd.hlookup_delay = 0;\r\n jd.hlookup_timer = $.w.setInterval(function () {\r\n jd.lookup_target_node.call(jd);\r\n }, jd.options.lookup_interval);\r\n }, this.options.lookup_delay);\r\n jd.capture = true;\r\n }\r\n }\r\n }\r\n /**\r\n * Drag handler to move shadow and auto-scroll container.\r\n * @param {MouseEvent|TouchEvent} e - Pointer move event\r\n */\r\n drag(e) {\r\n if (!this.jm.get_editable()) {\r\n return;\r\n }\r\n if (this.capture) {\r\n e.preventDefault();\r\n this.show_shadow();\r\n this.moved = true;\r\n clear_selection();\r\n var jview = this.jm.view;\r\n var px = (e.clientX || e.touches[0].clientX) / jview.zoom_current - this.offset_x;\r\n var py = (e.clientY || e.touches[0].clientY) / jview.zoom_current - this.offset_y;\r\n // scrolling container axisY if drag nodes exceeding container\r\n if (\r\n e.clientY - this.view_panel_rect.top < this.options.scrolling_trigger_width &&\r\n this.view_panel.scrollTop > this.options.scrolling_step_length\r\n ) {\r\n this.view_panel.scrollBy(0, -this.options.scrolling_step_length);\r\n this.offset_y += this.options.scrolling_step_length / jview.zoom_current;\r\n } else if (\r\n this.view_panel_rect.bottom - e.clientY < this.options.scrolling_trigger_width &&\r\n this.view_panel.scrollTop <\r\n this.view_panel.scrollHeight -\r\n this.view_panel_rect.height -\r\n this.options.scrolling_step_length\r\n ) {\r\n this.view_panel.scrollBy(0, this.options.scrolling_step_length);\r\n this.offset_y -= this.options.scrolling_step_length / jview.zoom_current;\r\n }\r\n // scrolling container axisX if drag nodes exceeding container\r\n if (\r\n e.clientX - this.view_panel_rect.left < this.options.scrolling_trigger_width &&\r\n this.view_panel.scrollLeft > this.options.scrolling_step_length\r\n ) {\r\n this.view_panel.scrollBy(-this.options.scrolling_step_length, 0);\r\n this.offset_x += this.options.scrolling_step_length / jview.zoom_current;\r\n } else if (\r\n this.view_panel_rect.right - e.clientX < this.options.scrolling_trigger_width &&\r\n this.view_panel.scrollLeft <\r\n this.view_panel.scrollWidth -\r\n this.view_panel_rect.width -\r\n this.options.scrolling_step_length\r\n ) {\r\n this.view_panel.scrollBy(this.options.scrolling_step_length, 0);\r\n this.offset_x -= this.options.scrolling_step_length / jview.zoom_current;\r\n }\r\n this.shadow.style.left = px + 'px';\r\n this.shadow.style.top = py + 'px';\r\n clear_selection();\r\n }\r\n }\r\n /**\r\n * Finish dragging, move the node if applicable.\r\n * @param {MouseEvent|TouchEvent} e - Pointer up event\r\n */\r\n dragend(e) {\r\n if (!this.jm.get_editable()) {\r\n return;\r\n }\r\n if (this.view_draggable) {\r\n this.jm.enable_view_draggable();\r\n }\r\n if (this.capture) {\r\n if (this.hlookup_delay != 0) {\r\n $.w.clearTimeout(this.hlookup_delay);\r\n this.hlookup_delay = 0;\r\n this.clear_lines();\r\n }\r\n if (this.hlookup_timer != 0) {\r\n $.w.clearInterval(this.hlookup_timer);\r\n this.hlookup_timer = 0;\r\n this.clear_lines();\r\n }\r\n if (this.moved) {\r\n var src_node = this.active_node;\r\n var target_node = this.target_node;\r\n var target_direct = this.target_direct;\r\n this.move_node(src_node, target_node, target_direct);\r\n }\r\n this.hide_shadow();\r\n }\r\n this.view_panel_rect = null;\r\n this.moved = false;\r\n this.capture = false;\r\n }\r\n /**\r\n * Find the closest node element from an event target.\r\n * @param {HTMLElement} el - Current DOM element\r\n * @returns {HTMLElement|null} Matched node element or null\r\n */\r\n find_node_element(el) {\r\n if (\r\n el === this.jm.view.e_nodes ||\r\n el === this.jm.view.e_panel ||\r\n el === this.jm.view.container\r\n ) {\r\n return null;\r\n }\r\n if (el.tagName.toLowerCase() === 'jmnode') {\r\n return el;\r\n }\r\n return this.find_node_element(el.parentNode);\r\n }\r\n /** Recompute target node under the shadow and draw helper. */\r\n lookup_target_node() {\r\n let sx = this.shadow.offsetLeft;\r\n let sy = this.shadow.offsetTop;\r\n if (sx === this.shadow_p_x && sy === this.shadow_p_y) {\r\n return;\r\n }\r\n this.shadow_p_x = sx;\r\n this.shadow_p_y = sy;\r\n\r\n let target_direction =\r\n this.shadow_p_x + this.shadow_w / 2 >= this.get_root_x()\r\n ? jsMind.direction.right\r\n : jsMind.direction.left;\r\n let overlapping_node = this.lookup_overlapping_node_parent(target_direction);\r\n let target_node = overlapping_node || this.lookup_close_node(target_direction);\r\n if (!!target_node) {\r\n let points = this.calc_point_of_node(target_node, target_direction);\r\n let invalid = jsMind.node.inherited(this.active_node, target_node);\r\n this.magnet_shadow(points.sp, points.np, invalid);\r\n this.target_node = target_node;\r\n this.target_direct = target_direction;\r\n }\r\n }\r\n /**\r\n * Get X coordinate of root node center.\r\n * @returns {number}\r\n */\r\n get_root_x() {\r\n let root = this.jm.get_root();\r\n let root_location = root.get_location();\r\n let root_size = root.get_size();\r\n return root_location.x + root_size.w / 2;\r\n }\r\n\r\n /**\r\n * Lookup overlapping node's parent near the shadow position.\r\n * @param {number} direction - Direction constant\r\n * @returns {import('../jsmind.node.js').Node|null}\r\n */\r\n lookup_overlapping_node_parent(direction) {\r\n let shadowRect = this.shadow.getBoundingClientRect();\r\n let x = shadowRect.x + (shadowRect.width * (1 - direction)) / 2;\r\n let deltaX = (this.jm.options.layout.hspace + this.jm.options.layout.pspace) * direction;\r\n let deltaY = shadowRect.height;\r\n let points = [\r\n [x, shadowRect.y],\r\n [x, shadowRect.y + deltaY / 2],\r\n [x, shadowRect.y + deltaY],\r\n [x + deltaX / 2, shadowRect.y],\r\n [x + deltaX / 2, shadowRect.y + deltaY / 2],\r\n [x + deltaX / 2, shadowRect.y + deltaY],\r\n [x + deltaX, shadowRect.y],\r\n [x + deltaX, shadowRect.y + deltaY / 2],\r\n [x + deltaX, shadowRect.y + deltaY],\r\n ];\r\n for (const p of points) {\r\n let n = this.lookup_node_parent_by_location(p[0], p[1]);\r\n if (!!n) {\r\n return n;\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Find node's parent by a screen location.\r\n * @param {number} x - Client X\r\n * @param {number} y - Client Y\r\n * @returns {import('../jsmind.node.js').Node|null}\r\n */\r\n lookup_node_parent_by_location(x, y) {\r\n return $.d\r\n .elementsFromPoint(x, y)\r\n .filter(\r\n x => x.tagName === 'JMNODE' && x.className !== this.options.shadow_node_class_name\r\n )\r\n .map(el => this.jm.view.get_binded_nodeid(el))\r\n .map(id => id && this.jm.mind.nodes[id])\r\n .map(n => n && n.parent)\r\n .find(n => n);\r\n }\r\n\r\n /**\r\n * Lookup the closest node along a direction.\r\n * @param {number} direction\r\n * @returns {import('../jsmind.node.js').Node}\r\n */\r\n lookup_close_node(direction) {\r\n return Object.values(this.jm.mind.nodes)\r\n .filter(n => n.direction == direction || n.isroot)\r\n .filter(n => this.jm.layout.is_visible(n))\r\n .filter(n => this.shadow_on_target_side(n, direction))\r\n .map(n => ({ node: n, distance: this.shadow_to_node(n, direction) }))\r\n .reduce(\r\n (prev, curr) => {\r\n return prev.distance < curr.distance ? prev : curr;\r\n },\r\n { node: this.jm.get_root(), distance: Number.MAX_VALUE }\r\n ).node;\r\n }\r\n\r\n /**\r\n * Check if shadow is on the target side of a node.\r\n * @param {import('../jsmind.node.js').Node} node\r\n * @param {number} dir\r\n * @returns {boolean}\r\n */\r\n shadow_on_target_side(node, dir) {\r\n return (\r\n (dir == jsMind.direction.right && this.shadow_to_right_of_node(node) > 0) ||\r\n (dir == jsMind.direction.left && this.shadow_to_left_of_node(node) > 0)\r\n );\r\n }\r\n\r\n /**\r\n * Distance from shadow to the right side of a node.\r\n * @param {import('../jsmind.node.js').Node} node\r\n * @returns {number}\r\n */\r\n shadow_to_right_of_node(node) {\r\n return this.shadow_p_x - node.get_location().x - node.get_size().w;\r\n }\r\n\r\n /**\r\n * Distance from shadow to the left side of a node.\r\n * @param {import('../jsmind.node.js').Node} node\r\n * @returns {number}\r\n */\r\n shadow_to_left_of_node(node) {\r\n return node.get_location().x - this.shadow_p_x - this.shadow_w;\r\n }\r\n\r\n /**\r\n * Vertical distance between shadow centerline and node centerline.\r\n * @param {import('../jsmind.node.js').Node} node\r\n * @returns {number}\r\n */\r\n shadow_to_base_line_of_node(node) {\r\n return this.shadow_p_y + this.shadow_h / 2 - node.get_location().y - node.get_size().h / 2;\r\n }\r\n\r\n /**\r\n * Manhattan distance to a node along a direction.\r\n * @param {import('../jsmind.node.js').Node} node\r\n * @param {number} dir\r\n * @returns {number}\r\n */\r\n shadow_to_node(node, dir) {\r\n let distance_x =\r\n dir === jsMind.direction.right\r\n ? Math.abs(this.shadow_to_right_of_node(node))\r\n : Math.abs(this.shadow_to_left_of_node(node));\r\n let distance_y = Math.abs(this.shadow_to_base_line_of_node(node));\r\n return distance_x + distance_y;\r\n }\r\n\r\n /**\r\n * Calculate connection points of a node and the shadow.\r\n * @param {import('../jsmind.node.js').Node} node\r\n * @param {number} dir\r\n * @returns {{sp:{x:number,y:number}, np:{x:number,y:number}}}\r\n */\r\n calc_point_of_node(node, dir) {\r\n let ns = node.get_size();\r\n let nl = node.get_location();\r\n let node_x = node.isroot\r\n ? nl.x + ns.w / 2\r\n : nl.x + (ns.w * (1 + dir)) / 2 + this.options.line_width * dir;\r\n let node_y = nl.y + ns.h / 2;\r\n let shadow_x =\r\n this.shadow_p_x + (this.shadow_w * (1 - dir)) / 2 - this.options.line_width * dir;\r\n let shadow_y = this.shadow_p_y + this.shadow_h / 2;\r\n return {\r\n sp: { x: shadow_x, y: shadow_y },\r\n np: { x: node_x, y: node_y },\r\n };\r\n }\r\n\r\n /**\r\n * Move a node to a new parent/position.\r\n * @param {import('../jsmind.node.js').Node} src_node\r\n * @param {import('../jsmind.node.js').Node|null} target_node\r\n * @param {number|null} target_direct\r\n */\r\n move_node(src_node, target_node, target_direct) {\r\n var shadow_h = this.shadow.offsetTop;\r\n if (!!target_node && !!src_node && !jsMind.node.inherited(src_node, target_node)) {\r\n // Call validate_drag function if provided, to validate the drag operation\r\n if (this.options.validate_drag && typeof this.options.validate_drag === 'function') {\r\n const isValid = this.options.validate_drag(src_node, target_node);\r\n if (!isValid) {\r\n // Drag operation is not allowed, cleanup and return\r\n this.active_node = null;\r\n this.target_node = null;\r\n this.target_direct = null;\r\n return;\r\n }\r\n }\r\n\r\n // lookup before_node\r\n var sibling_nodes = target_node.children;\r\n var sc = sibling_nodes.length;\r\n var node = null;\r\n var delta_y = Number.MAX_VALUE;\r\n var node_before = null;\r\n var beforeid = '_last_';\r\n while (sc--) {\r\n node = sibling_nodes[sc];\r\n if (node.direction == target_direct && node.id != src_node.id) {\r\n var dy = node.get_location().y - shadow_h;\r\n if (dy > 0 && dy < delta_y) {\r\n delta_y = dy;\r\n node_before = node;\r\n beforeid = '_first_';\r\n }\r\n }\r\n }\r\n if (!!node_before) {\r\n beforeid = node_before.id;\r\n }\r\n this.jm.move_node(src_node.id, beforeid, target_node.id, target_direct);\r\n }\r\n this.active_node = null;\r\n this.target_node = null;\r\n this.target_direct = null;\r\n }\r\n /**\r\n * Handle jsMind events.\r\n * @param {number|string} type - Event type\r\n * @param {object} [data] - Event data\r\n */\r\n jm_event_handle(type, data) {\r\n if (type === jsMind.event_type.resize) {\r\n this.resize();\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Draggable node plugin registration.\r\n * @type {import('../jsmind.plugin.js').Plugin<Partial<DraggableNodeOptions>>}\r\n */\r\nexport const draggable_plugin = new jsMind.plugin('draggable_node', function (jm, options) {\r\n var jd = new DraggableNode(jm, options);\r\n jd.init();\r\n jm.add_event_listener(function (type, data) {\r\n jd.jm_event_handle.call(jd, type, data);\r\n });\r\n});\r\n\r\njsMind.register_plugin(draggable_plugin);\r\n\r\nexport default DraggableNode;\r\n"],"names":["jsMind","Error","$","clear_selection","w","getSelection","removeAllRanges","d","selection","empty","DEFAULT_OPTIONS","line_width","line_color","line_color_invalid","lookup_delay","lookup_interval","scrolling_trigger_width","scrolling_step_length","shadow_node_class_name","DraggableNode","constructor","jm","options","opts","util","json","merge","this","version","is_svg_engine","view","engine","e_canvas","canvas_ctx","helper_line","shadow","shadow_p_x","shadow_p_y","shadow_w","shadow_h","active_node","target_node","target_direct","client_w","client_h","offset_x","offset_y","hlookup_delay","hlookup_timer","capture","moved","canvas_draggable","get_view_draggable","view_panel","e_panel","view_panel_rect","init","create_canvas","create_shadow","event_bind","resize","e_nodes","appendChild","setAttribute","size","h","width","height","svg","_create_svg_element","c","ctx","getContext","tag","createElementNS","s","style","visibility","zIndex","cursor","opacity","className","reset_shadow","el","innerHTML","left","top","backgroundImage","backgroundSize","transform","clientWidth","clientHeight","show_shadow","hide_shadow","magnet_shadow","shadow_p","node_p","invalid","clear_lines","color","svg_draw_line","x","y","lineWidth","strokeStyle","lineCap","canvas_lineto","parentNode","removeChild","clearRect","x1","y1","x2","y2","beginPath","moveTo","lineTo","stroke","_svg_bezier_to","path","jd","container","on","e","button","dragstart","call","movementX","movementY","drag","dragend","get_editable","jview","is_editing","view_draggable","find_node_element","target","disable_view_draggable","nodeid","get_binded_nodeid","node","get_node","isroot","data","draggable","getBoundingClientRect","clientX","touches","zoom_current","offsetLeft","clientY","offsetTop","client_hw","Math","floor","client_hh","clearTimeout","clearInterval","setTimeout","setInterval","lookup_target_node","preventDefault","px","py","scrollTop","scrollBy","bottom","scrollHeight","scrollLeft","right","scrollWidth","enable_view_draggable","src_node","move_node","tagName","toLowerCase","sx","sy","target_direction","get_root_x","direction","lookup_overlapping_node_parent","lookup_close_node","points","calc_point_of_node","inherited","sp","np","root","get_root","root_location","get_location","root_size","get_size","shadowRect","deltaX","layout","hspace","pspace","deltaY","p","n","lookup_node_parent_by_location","elementsFromPoint","filter","map","id","mind","nodes","parent","find","Object","values","is_visible","shadow_on_target_side","distance","shadow_to_node","reduce","prev","curr","Number","MAX_VALUE","dir","shadow_to_right_of_node","shadow_to_left_of_node","shadow_to_base_line_of_node","abs","ns","nl","node_x","node_y","validate_drag","sibling_nodes","children","sc","length","delta_y","node_before","beforeid","dy","jm_event_handle","type","event_type","draggable_plugin","plugin","add_event_listener","register_plugin"],"mappings":";;;;;;;sYAUA,IAAKA,UACD,MAAM,IAAIC,MAAM,yBAGpB,MAAMC,EAAIF,EAAM,QAACE,EAEXC,EACF,iBAAkBD,EAAEE,EACd,WACIF,EAAEE,EAAEC,eAAeC,iBACtB,EACD,WACIJ,EAAEK,EAAEC,UAAUC,OAC5B,EAeMC,EAAkB,CACpBC,WAAY,EACZC,WAAY,kBACZC,mBAAoB,sBACpBC,aAAc,IACdC,gBAAiB,IACjBC,wBAAyB,GACzBC,sBAAuB,GACvBC,uBAAwB,gCAMrB,MAAMC,EAMT,WAAAC,CAAYC,EAAIC,GACZ,IAAIC,EAAO,CAAA,EACXvB,EAAM,QAACwB,KAAKC,KAAKC,MAAMH,EAAMb,GAC7BV,EAAM,QAACwB,KAAKC,KAAKC,MAAMH,EAAMD,GAE7BK,KAAKC,QAAU,QAEfD,KAAKN,GAAKA,EAEVM,KAAKL,QAAUC,EAEfI,KAAKE,cAAwC,QAAxBR,EAAGS,KAAKP,KAAKQ,OAElCJ,KAAKK,SAAW,KAEhBL,KAAKM,WAAa,KAElBN,KAAKO,YAAc,KAEnBP,KAAKQ,OAAS,KAEdR,KAAKS,WAAa,EAElBT,KAAKU,WAAa,EAElBV,KAAKW,SAAW,EAEhBX,KAAKY,SAAW,EAEhBZ,KAAKa,YAAc,KAEnBb,KAAKc,YAAc,KAEnBd,KAAKe,cAAgB,KAErBf,KAAKgB,SAAW,EAEhBhB,KAAKiB,SAAW,EAEhBjB,KAAKkB,SAAW,EAEhBlB,KAAKmB,SAAW,EAEhBnB,KAAKoB,cAAgB,EAErBpB,KAAKqB,cAAgB,EAErBrB,KAAKsB,SAAU,EAEftB,KAAKuB,OAAQ,EAEbvB,KAAKwB,iBAAmB9B,EAAG+B,qBAE3BzB,KAAK0B,WAAahC,EAAGS,KAAKwB,QAE1B3B,KAAK4B,gBAAkB,IAC1B,CAED,IAAAC,GACI7B,KAAK8B,gBACL9B,KAAK+B,gBACL/B,KAAKgC,YACR,CAED,MAAAC,GACIjC,KAAKN,GAAGS,KAAK+B,QAAQC,YAAYnC,KAAKQ,QAClCR,KAAKE,eACLF,KAAKK,SAAS+B,aAAa,QAASpC,KAAKN,GAAGS,KAAKkC,KAAK5D,GACtDuB,KAAKK,SAAS+B,aAAa,SAAUpC,KAAKN,GAAGS,KAAKkC,KAAKC,KAEvDtC,KAAKK,SAASkC,MAAQvC,KAAKN,GAAGS,KAAKkC,KAAK5D,EACxCuB,KAAKK,SAASmC,OAASxC,KAAKN,GAAGS,KAAKkC,KAAKC,EAEhD,CAED,aAAAR,GACI,GAAI9B,KAAKE,cAAe,CAEpB,IAAIuC,EAAMzC,KAAK0C,oBAAoB,OACnCD,EAAIL,aAAa,QAAS,2BAC1BK,EAAIL,aAAa,QAAS,8DAC1BpC,KAAKN,GAAGS,KAAKwB,QAAQQ,YAAYM,GACjCzC,KAAKK,SAAWoC,CAC5B,KAAe,CAEH,IAAIE,EAAIpE,EAAEoE,EAAE,UACZ3C,KAAKN,GAAGS,KAAKwB,QAAQQ,YAAYQ,GACjC,IAAIC,EAAMD,EAAEE,WAAW,MACvB7C,KAAKK,SAAWsC,EAChB3C,KAAKM,WAAasC,CACrB,CACJ,CAOD,mBAAAF,CAAoBI,GAChB,OAAOvE,EAAEK,EAAEmE,gBAAgB,6BAA8BD,EAC5D,CACD,aAAAf,GACI,IAAIiB,EAAIzE,EAAEoE,EAAE,UACZK,EAAEC,MAAMC,WAAa,SACrBF,EAAEC,MAAME,OAAS,IACjBH,EAAEC,MAAMG,OAAS,OACjBJ,EAAEC,MAAMI,QAAU,MAClBL,EAAEM,UAAYtD,KAAKL,QAAQJ,uBAC3BS,KAAKQ,OAASwC,CACjB,CAKD,YAAAO,CAAaC,GACT,IAAIR,EAAIhD,KAAKQ,OAAOyC,MACpBjD,KAAKQ,OAAOiD,UAAYD,EAAGC,UAC3BT,EAAEU,KAAOF,EAAGP,MAAMS,KAClBV,EAAEW,IAAMH,EAAGP,MAAMU,IACjBX,EAAET,MAAQiB,EAAGP,MAAMV,MACnBS,EAAER,OAASgB,EAAGP,MAAMT,OACpBQ,EAAEY,gBAAkBJ,EAAGP,MAAMW,gBAC7BZ,EAAEa,eAAiBL,EAAGP,MAAMY,eAC5Bb,EAAEc,UAAYN,EAAGP,MAAMa,UACvB9D,KAAKW,SAAWX,KAAKQ,OAAOuD,YAC5B/D,KAAKY,SAAWZ,KAAKQ,OAAOwD,YAC/B,CAED,WAAAC,GACSjE,KAAKuB,QACNvB,KAAKQ,OAAOyC,MAAMC,WAAa,UAEtC,CAED,WAAAgB,GACIlE,KAAKQ,OAAOyC,MAAMC,WAAa,QAClC,CAOD,aAAAiB,CAAcC,EAAUC,EAAQC,GAC5BtE,KAAKuE,cACL,IAAIC,EAAQF,EAAUtE,KAAKL,QAAQT,mBAAqBc,KAAKL,QAAQV,WAEjEe,KAAKE,cACLF,KAAKyE,cAAcL,EAASM,EAAGN,EAASO,EAAGN,EAAOK,EAAGL,EAAOM,EAAGH,IAE/DxE,KAAKM,WAAWsE,UAAY5E,KAAKL,QAAQX,WACzCgB,KAAKM,WAAWuE,YAAcL,EAC9BxE,KAAKM,WAAWwE,QAAU,QAC1B9E,KAAK+E,cAAcX,EAASM,EAAGN,EAASO,EAAGN,EAAOK,EAAGL,EAAOM,GAEnE,CAED,WAAAJ,GACQvE,KAAKE,cACDF,KAAKO,aAAeP,KAAKO,YAAYyE,aACrChF,KAAKK,SAAS4E,YAAYjF,KAAKO,aAC/BP,KAAKO,YAAc,MAGvBP,KAAKM,WAAW4E,UAAU,EAAG,EAAGlF,KAAKN,GAAGS,KAAKkC,KAAK5D,EAAGuB,KAAKN,GAAGS,KAAKkC,KAAKC,EAE9E,CAQD,aAAAyC,CAAcI,EAAIC,EAAIC,EAAIC,GACtBtF,KAAKM,WAAWiF,YAChBvF,KAAKM,WAAWkF,OAAOL,EAAIC,GAC3BpF,KAAKM,WAAWmF,OAAOJ,EAAIC,GAC3BtF,KAAKM,WAAWoF,QACnB,CAUD,aAAAjB,CAAcU,EAAIC,EAAIC,EAAIC,EAAId,GAE1BxE,KAAKO,YAAcP,KAAK0C,oBAAoB,QAC5C1C,KAAKO,YAAY6B,aAAa,SAAUoC,GACxCxE,KAAKO,YAAY6B,aAAa,eAAgBpC,KAAKL,QAAQX,YAC3DgB,KAAKO,YAAY6B,aAAa,OAAQ,eACtCpC,KAAKO,YAAY6B,aAAa,iBAAkB,SAGhDpC,KAAK2F,eAAe3F,KAAKO,YAAa4E,EAAIC,EAAIC,EAAIC,GAGlDtF,KAAKK,SAAS8B,YAAYnC,KAAKO,YAClC,CAWD,cAAAoF,CAAeC,EAAMT,EAAIC,EAAIC,EAAIC,GAC7BM,EAAKxD,aACD,IACA,KACI+C,EACA,IACAC,EACA,OACCD,EAAkB,GAAXE,EAAKF,GAAW,GACxB,IACAC,EACA,KACAD,EACA,IACAG,EACA,KACAD,EACA,IACAC,EAEX,CAED,UAAAtD,GACI,IAAI6D,EAAK7F,KACL8F,EAAY9F,KAAKN,GAAGS,KAAK2F,UAC7BvH,EAAEwH,GAAGD,EAAW,aAAa,SAAUE,GAClB,IAAbA,EAAEC,QACFJ,EAAGK,UAAUC,KAAKN,EAAIG,EAEtC,IACQzH,EAAEwH,GAAGD,EAAW,aAAa,SAAUE,GACf,IAAhBA,EAAEI,WAAmC,IAAhBJ,EAAEK,WACvBR,EAAGS,KAAKH,KAAKN,EAAIG,EAEjC,IACQzH,EAAEwH,GAAGD,EAAW,WAAW,SAAUE,GACjCH,EAAGU,QAAQJ,KAAKN,EAAIG,EAChC,IACQzH,EAAEwH,GAAGD,EAAW,cAAc,SAAUE,GACpCH,EAAGK,UAAUC,KAAKN,EAAIG,EAClC,IACQzH,EAAEwH,GAAGD,EAAW,aAAa,SAAUE,GACnCH,EAAGS,KAAKH,KAAKN,EAAIG,EAC7B,IACQzH,EAAEwH,GAAGD,EAAW,YAAY,SAAUE,GAClCH,EAAGU,QAAQJ,KAAKN,EAAIG,EAChC,GACK,CAKD,SAAAE,CAAUF,GACN,GAAKhG,KAAKN,GAAG8G,iBAGTxG,KAAKsB,QAAT,CAGA,IAAImF,EAAQzG,KAAKN,GAAGS,KACpB,IAAIsG,EAAMC,aAAV,CAGA1G,KAAKa,YAAc,KACnBb,KAAK2G,eAAiB3G,KAAKN,GAAG+B,qBAE9B,IAAI+B,EAAKxD,KAAK4G,kBAAkBZ,EAAEa,QAClC,GAAKrD,EAAL,CAGIxD,KAAK2G,gBACL3G,KAAKN,GAAGoH,yBAEZ,IAAIC,EAASN,EAAMO,kBAAkBxD,GACrC,GAAMuD,EAAQ,CACV,IAAIE,EAAOjH,KAAKN,GAAGwH,SAASH,GAC5B,IAAKE,EAAKE,OAAQ,CAEd,GAAIF,EAAKG,OAAgC,IAAxBH,EAAKG,KAAKC,UACvB,OAEJrH,KAAKuD,aAAaC,GAClBxD,KAAK4B,gBAAkB5B,KAAK0B,WAAW4F,wBACvCtH,KAAKa,YAAcoG,EACnBjH,KAAKkB,UACA8E,EAAEuB,SAAWvB,EAAEwB,QAAQ,GAAGD,SAAWd,EAAMgB,aAAejE,EAAGkE,WAClE1H,KAAKmB,UACA6E,EAAE2B,SAAW3B,EAAEwB,QAAQ,GAAGG,SAAWlB,EAAMgB,aAAejE,EAAGoE,UAClE5H,KAAK6H,UAAYC,KAAKC,MAAMvE,EAAGO,YAAc,GAC7C/D,KAAKgI,UAAYF,KAAKC,MAAMvE,EAAGQ,aAAe,GACpB,GAAtBhE,KAAKoB,eACL7C,EAAEE,EAAEwJ,aAAajI,KAAKoB,eAEA,GAAtBpB,KAAKqB,eACL9C,EAAEE,EAAEyJ,cAAclI,KAAKqB,eAE3B,IAAIwE,EAAK7F,KACTA,KAAKoB,cAAgB7C,EAAEE,EAAE0J,YAAW,WAChCtC,EAAGzE,cAAgB,EACnByE,EAAGxE,cAAgB9C,EAAEE,EAAE2J,aAAY,WAC/BvC,EAAGwC,mBAAmBlC,KAAKN,EACnD,GAAuBA,EAAGlG,QAAQP,gBAClC,GAAmBY,KAAKL,QAAQR,cAChB0G,EAAGvE,SAAU,CAChB,CACJ,CApCA,CAPA,CAJA,CAgDJ,CAKD,IAAAgF,CAAKN,GACD,GAAKhG,KAAKN,GAAG8G,gBAGTxG,KAAKsB,QAAS,CACd0E,EAAEsC,iBACFtI,KAAKiE,cACLjE,KAAKuB,OAAQ,EACb/C,IACA,IAAIiI,EAAQzG,KAAKN,GAAGS,KAChBoI,GAAMvC,EAAEuB,SAAWvB,EAAEwB,QAAQ,GAAGD,SAAWd,EAAMgB,aAAezH,KAAKkB,SACrEsH,GAAMxC,EAAE2B,SAAW3B,EAAEwB,QAAQ,GAAGG,SAAWlB,EAAMgB,aAAezH,KAAKmB,SAGrE6E,EAAE2B,QAAU3H,KAAK4B,gBAAgB+B,IAAM3D,KAAKL,QAAQN,yBACpDW,KAAK0B,WAAW+G,UAAYzI,KAAKL,QAAQL,uBAEzCU,KAAK0B,WAAWgH,SAAS,GAAI1I,KAAKL,QAAQL,uBAC1CU,KAAKmB,UAAYnB,KAAKL,QAAQL,sBAAwBmH,EAAMgB,cAE5DzH,KAAK4B,gBAAgB+G,OAAS3C,EAAE2B,QAAU3H,KAAKL,QAAQN,yBACvDW,KAAK0B,WAAW+G,UACZzI,KAAK0B,WAAWkH,aACZ5I,KAAK4B,gBAAgBY,OACrBxC,KAAKL,QAAQL,wBAErBU,KAAK0B,WAAWgH,SAAS,EAAG1I,KAAKL,QAAQL,uBACzCU,KAAKmB,UAAYnB,KAAKL,QAAQL,sBAAwBmH,EAAMgB,cAI5DzB,EAAEuB,QAAUvH,KAAK4B,gBAAgB8B,KAAO1D,KAAKL,QAAQN,yBACrDW,KAAK0B,WAAWmH,WAAa7I,KAAKL,QAAQL,uBAE1CU,KAAK0B,WAAWgH,UAAU1I,KAAKL,QAAQL,sBAAuB,GAC9DU,KAAKkB,UAAYlB,KAAKL,QAAQL,sBAAwBmH,EAAMgB,cAE5DzH,KAAK4B,gBAAgBkH,MAAQ9C,EAAEuB,QAAUvH,KAAKL,QAAQN,yBACtDW,KAAK0B,WAAWmH,WACZ7I,KAAK0B,WAAWqH,YACZ/I,KAAK4B,gBAAgBW,MACrBvC,KAAKL,QAAQL,wBAErBU,KAAK0B,WAAWgH,SAAS1I,KAAKL,QAAQL,sBAAuB,GAC7DU,KAAKkB,UAAYlB,KAAKL,QAAQL,sBAAwBmH,EAAMgB,cAEhEzH,KAAKQ,OAAOyC,MAAMS,KAAO6E,EAAK,KAC9BvI,KAAKQ,OAAOyC,MAAMU,IAAM6E,EAAK,KAC7BhK,GACH,CACJ,CAKD,OAAA+H,CAAQP,GACJ,GAAKhG,KAAKN,GAAG8G,eAAb,CAMA,GAHIxG,KAAK2G,gBACL3G,KAAKN,GAAGsJ,wBAERhJ,KAAKsB,QAAS,CAWd,GAV0B,GAAtBtB,KAAKoB,gBACL7C,EAAEE,EAAEwJ,aAAajI,KAAKoB,eACtBpB,KAAKoB,cAAgB,EACrBpB,KAAKuE,eAEiB,GAAtBvE,KAAKqB,gBACL9C,EAAEE,EAAEyJ,cAAclI,KAAKqB,eACvBrB,KAAKqB,cAAgB,EACrBrB,KAAKuE,eAELvE,KAAKuB,MAAO,CACZ,IAAI0H,EAAWjJ,KAAKa,YAChBC,EAAcd,KAAKc,YACnBC,EAAgBf,KAAKe,cACzBf,KAAKkJ,UAAUD,EAAUnI,EAAaC,EACzC,CACDf,KAAKkE,aACR,CACDlE,KAAK4B,gBAAkB,KACvB5B,KAAKuB,OAAQ,EACbvB,KAAKsB,SAAU,CAzBd,CA0BJ,CAMD,iBAAAsF,CAAkBpD,GACd,OACIA,IAAOxD,KAAKN,GAAGS,KAAK+B,SACpBsB,IAAOxD,KAAKN,GAAGS,KAAKwB,SACpB6B,IAAOxD,KAAKN,GAAGS,KAAK2F,UAEb,KAEsB,WAA7BtC,EAAG2F,QAAQC,cACJ5F,EAEJxD,KAAK4G,kBAAkBpD,EAAGwB,WACpC,CAED,kBAAAqD,GACI,IAAIgB,EAAKrJ,KAAKQ,OAAOkH,WACjB4B,EAAKtJ,KAAKQ,OAAOoH,UACrB,GAAIyB,IAAOrJ,KAAKS,YAAc6I,IAAOtJ,KAAKU,WACtC,OAEJV,KAAKS,WAAa4I,EAClBrJ,KAAKU,WAAa4I,EAElB,IAAIC,EACAvJ,KAAKS,WAAaT,KAAKW,SAAW,GAAKX,KAAKwJ,aACtCnL,EAAM,QAACoL,UAAUX,MACjBzK,EAAM,QAACoL,UAAU/F,KAEvB5C,EADmBd,KAAK0J,+BAA+BH,IACrBvJ,KAAK2J,kBAAkBJ,GAC7D,GAAMzI,EAAa,CACf,IAAI8I,EAAS5J,KAAK6J,mBAAmB/I,EAAayI,GAC9CjF,EAAUjG,EAAAA,QAAO4I,KAAK6C,UAAU9J,KAAKa,YAAaC,GACtDd,KAAKmE,cAAcyF,EAAOG,GAAIH,EAAOI,GAAI1F,GACzCtE,KAAKc,YAAcA,EACnBd,KAAKe,cAAgBwI,CACxB,CACJ,CAKD,UAAAC,GACI,IAAIS,EAAOjK,KAAKN,GAAGwK,WACfC,EAAgBF,EAAKG,eACrBC,EAAYJ,EAAKK,WACrB,OAAOH,EAAczF,EAAI2F,EAAU5L,EAAI,CAC1C,CAOD,8BAAAiL,CAA+BD,GAC3B,IAAIc,EAAavK,KAAKQ,OAAO8G,wBACzB5C,EAAI6F,EAAW7F,EAAK6F,EAAWhI,OAAS,EAAIkH,GAAc,EAC1De,GAAUxK,KAAKN,GAAGC,QAAQ8K,OAAOC,OAAS1K,KAAKN,GAAGC,QAAQ8K,OAAOE,QAAUlB,EAC3EmB,EAASL,EAAW/H,OACpBoH,EAAS,CACT,CAAClF,EAAG6F,EAAW5F,GACf,CAACD,EAAG6F,EAAW5F,EAAIiG,EAAS,GAC5B,CAAClG,EAAG6F,EAAW5F,EAAIiG,GACnB,CAAClG,EAAI8F,EAAS,EAAGD,EAAW5F,GAC5B,CAACD,EAAI8F,EAAS,EAAGD,EAAW5F,EAAIiG,EAAS,GACzC,CAAClG,EAAI8F,EAAS,EAAGD,EAAW5F,EAAIiG,GAChC,CAAClG,EAAI8F,EAAQD,EAAW5F,GACxB,CAACD,EAAI8F,EAAQD,EAAW5F,EAAIiG,EAAS,GACrC,CAAClG,EAAI8F,EAAQD,EAAW5F,EAAIiG,IAEhC,IAAK,MAAMC,KAAKjB,EAAQ,CACpB,IAAIkB,EAAI9K,KAAK+K,+BAA+BF,EAAE,GAAIA,EAAE,IACpD,GAAMC,EACF,OAAOA,CAEd,CACJ,CAQD,8BAAAC,CAA+BrG,EAAGC,GAC9B,OAAOpG,EAAEK,EACJoM,kBAAkBtG,EAAGC,GACrBsG,QACGvG,GAAmB,WAAdA,EAAEyE,SAAwBzE,EAAEpB,YAActD,KAAKL,QAAQJ,yBAE/D2L,KAAI1H,GAAMxD,KAAKN,GAAGS,KAAK6G,kBAAkBxD,KACzC0H,KAAIC,GAAMA,GAAMnL,KAAKN,GAAG0L,KAAKC,MAAMF,KACnCD,KAAIJ,GAAKA,GAAKA,EAAEQ,SAChBC,MAAKT,GAAKA,GAClB,CAOD,iBAAAnB,CAAkBF,GACd,OAAO+B,OAAOC,OAAOzL,KAAKN,GAAG0L,KAAKC,OAC7BJ,QAAOH,GAAKA,EAAErB,WAAaA,GAAaqB,EAAE3D,SAC1C8D,QAAOH,GAAK9K,KAAKN,GAAG+K,OAAOiB,WAAWZ,KACtCG,QAAOH,GAAK9K,KAAK2L,sBAAsBb,EAAGrB,KAC1CyB,KAAIJ,IAAC,CAAO7D,KAAM6D,EAAGc,SAAU5L,KAAK6L,eAAef,EAAGrB,OACtDqC,QACG,CAACC,EAAMC,IACID,EAAKH,SAAWI,EAAKJ,SAAWG,EAAOC,GAElD,CAAE/E,KAAMjH,KAAKN,GAAGwK,WAAY0B,SAAUK,OAAOC,YAC/CjF,IACT,CAQD,qBAAA0E,CAAsB1E,EAAMkF,GACxB,OACKA,GAAO9N,EAAM,QAACoL,UAAUX,OAAS9I,KAAKoM,wBAAwBnF,GAAQ,GACtEkF,GAAO9N,EAAAA,QAAOoL,UAAU/F,MAAQ1D,KAAKqM,uBAAuBpF,GAAQ,CAE5E,CAOD,uBAAAmF,CAAwBnF,GACpB,OAAOjH,KAAKS,WAAawG,EAAKmD,eAAe1F,EAAIuC,EAAKqD,WAAW7L,CACpE,CAOD,sBAAA4N,CAAuBpF,GACnB,OAAOA,EAAKmD,eAAe1F,EAAI1E,KAAKS,WAAaT,KAAKW,QACzD,CAOD,2BAAA2L,CAA4BrF,GACxB,OAAOjH,KAAKU,WAAaV,KAAKY,SAAW,EAAIqG,EAAKmD,eAAezF,EAAIsC,EAAKqD,WAAWhI,EAAI,CAC5F,CAQD,cAAAuJ,CAAe5E,EAAMkF,GAMjB,OAJIA,IAAQ9N,EAAAA,QAAOoL,UAAUX,MACnBhB,KAAKyE,IAAIvM,KAAKoM,wBAAwBnF,IACtCa,KAAKyE,IAAIvM,KAAKqM,uBAAuBpF,KAC9Ba,KAAKyE,IAAIvM,KAAKsM,4BAA4BrF,GAE9D,CAQD,kBAAA4C,CAAmB5C,EAAMkF,GACrB,IAAIK,EAAKvF,EAAKqD,WACVmC,EAAKxF,EAAKmD,eACVsC,EAASzF,EAAKE,OACZsF,EAAG/H,EAAI8H,EAAG/N,EAAI,EACdgO,EAAG/H,EAAK8H,EAAG/N,GAAK,EAAI0N,GAAQ,EAAInM,KAAKL,QAAQX,WAAamN,EAC5DQ,EAASF,EAAG9H,EAAI6H,EAAGlK,EAAI,EAI3B,MAAO,CACHyH,GAAI,CAAErF,EAHN1E,KAAKS,WAAcT,KAAKW,UAAY,EAAIwL,GAAQ,EAAInM,KAAKL,QAAQX,WAAamN,EAG3DxH,EAFR3E,KAAKU,WAAaV,KAAKY,SAAW,GAG7CoJ,GAAI,CAAEtF,EAAGgI,EAAQ/H,EAAGgI,GAE3B,CAQD,SAAAzD,CAAUD,EAAUnI,EAAaC,GAC7B,IAAIH,EAAWZ,KAAKQ,OAAOoH,UAC3B,GAAM9G,GAAiBmI,IAAa5K,UAAO4I,KAAK6C,UAAUb,EAAUnI,GAAc,CAE9E,GAAId,KAAKL,QAAQiN,eAAuD,mBAA/B5M,KAAKL,QAAQiN,cAA8B,CAEhF,IADgB5M,KAAKL,QAAQiN,cAAc3D,EAAUnI,GAMjD,OAHAd,KAAKa,YAAc,KACnBb,KAAKc,YAAc,UACnBd,KAAKe,cAAgB,KAG5B,CASD,IANA,IAAI8L,EAAgB/L,EAAYgM,SAC5BC,EAAKF,EAAcG,OACnB/F,EAAO,KACPgG,EAAUhB,OAAOC,UACjBgB,EAAc,KACdC,EAAW,SACRJ,KAEH,IADA9F,EAAO4F,EAAcE,IACZtD,WAAa1I,GAAiBkG,EAAKkE,IAAMlC,EAASkC,GAAI,CAC3D,IAAIiC,EAAKnG,EAAKmD,eAAezF,EAAI/D,EAC7BwM,EAAK,GAAKA,EAAKH,IACfA,EAAUG,EACVF,EAAcjG,EACdkG,EAAW,UAElB,CAECD,IACFC,EAAWD,EAAY/B,IAE3BnL,KAAKN,GAAGwJ,UAAUD,EAASkC,GAAIgC,EAAUrM,EAAYqK,GAAIpK,EAC5D,CACDf,KAAKa,YAAc,KACnBb,KAAKc,YAAc,KACnBd,KAAKe,cAAgB,IACxB,CAMD,eAAAsM,CAAgBC,EAAMlG,GACdkG,IAASjP,EAAAA,QAAOkP,WAAWtL,QAC3BjC,KAAKiC,QAEZ,EAOO,MAACuL,EAAmB,IAAInP,EAAAA,QAAOoP,OAAO,kBAAkB,SAAU/N,EAAIC,GAC9E,IAAIkG,EAAK,IAAIrG,EAAcE,EAAIC,GAC/BkG,EAAGhE,OACHnC,EAAGgO,oBAAmB,SAAUJ,EAAMlG,GAClCvB,EAAGwH,gBAAgBlH,KAAKN,EAAIyH,EAAMlG,EAC1C,GACA,IAEA/I,EAAAA,QAAOsP,gBAAgBH"}
1
+ {"version":3,"file":"jsmind.draggable-node.js","sources":["../src/plugins/jsmind.draggable-node.js"],"sourcesContent":["/**\n * @license BSD\n * @copyright 2014-2025 UmbraCi\n *\n * Project Home:\n * https://github.com/UmbraCi/jsmind/\n */\n\nimport jsMind from '@umbraci/jsmind';\n\nif (!jsMind) {\n throw new Error('jsMind is not defined');\n}\n\nconst $ = jsMind.$;\n\nconst clear_selection =\n 'getSelection' in $.w\n ? function () {\n $.w.getSelection().removeAllRanges();\n }\n : function () {\n $.d.selection.empty();\n };\n\n/**\n * Default options for draggable node plugin.\n * @typedef {Object} DraggableNodeOptions\n * @property {number} [line_width]\n * @property {string} [line_color]\n * @property {string} [line_color_invalid]\n * @property {number} [lookup_delay]\n * @property {number} [lookup_interval]\n * @property {number} [scrolling_trigger_width]\n * @property {number} [scrolling_step_length]\n * @property {string} [shadow_node_class_name]\n * @property {(draggedNode:import('../jsmind.node.js').Node, targetNode:import('../jsmind.node.js').Node|null)=>boolean} [validate_drag]\n */\nconst DEFAULT_OPTIONS = {\n line_width: 5,\n line_color: 'rgba(0,0,0,0.3)',\n line_color_invalid: 'rgba(255,51,51,0.6)',\n lookup_delay: 200,\n lookup_interval: 100,\n scrolling_trigger_width: 20,\n scrolling_step_length: 10,\n shadow_node_class_name: 'jsmind-draggable-shadow-node',\n};\n\n/**\n * Draggable node plugin for jsMind.\n */\nexport class DraggableNode {\n /**\n * Create draggable node plugin instance.\n * @param {import('../jsmind.js').default} jm - jsMind instance\n * @param {Partial<DraggableNodeOptions>} options - Plugin options\n */\n constructor(jm, options) {\n var opts = {};\n jsMind.util.json.merge(opts, DEFAULT_OPTIONS);\n jsMind.util.json.merge(opts, options);\n\n this.version = '0.4.0';\n /** @type {import('../jsmind.js').default} */\n this.jm = jm;\n /** @type {DraggableNodeOptions} */\n this.options = opts;\n /** @type {boolean} */\n this.is_svg_engine = jm.view.opts.engine === 'svg';\n /** @type {HTMLCanvasElement|SVGSVGElement|null} */\n this.e_canvas = null;\n /** @type {CanvasRenderingContext2D|null} */\n this.canvas_ctx = null;\n /** @type {SVGPathElement|null} */\n this.helper_line = null;\n /** @type {HTMLElement|null} */\n this.shadow = null;\n /** @type {number} */\n this.shadow_p_x = 0;\n /** @type {number} */\n this.shadow_p_y = 0;\n /** @type {number} */\n this.shadow_w = 0;\n /** @type {number} */\n this.shadow_h = 0;\n /** @type {import('../jsmind.node.js').Node|null} */\n this.active_node = null;\n /** @type {import('../jsmind.node.js').Node|null} */\n this.target_node = null;\n /** @type {number|null} */\n this.target_direct = null;\n /** @type {number} */\n this.client_w = 0;\n /** @type {number} */\n this.client_h = 0;\n /** @type {number} */\n this.offset_x = 0;\n /** @type {number} */\n this.offset_y = 0;\n /** @type {number} */\n this.hlookup_delay = 0;\n /** @type {number} */\n this.hlookup_timer = 0;\n /** @type {boolean} */\n this.capture = false;\n /** @type {boolean} */\n this.moved = false;\n /** @type {boolean} */\n this.canvas_draggable = jm.get_view_draggable();\n /** @type {HTMLElement} */\n this.view_panel = jm.view.e_panel;\n /** @type {DOMRect|null} */\n this.view_panel_rect = null;\n }\n /** Initialize the draggable node plugin. */\n init() {\n this.create_canvas();\n this.create_shadow();\n this.event_bind();\n }\n /** Resize canvas/SVG and shadow elements. */\n resize() {\n this.jm.view.e_nodes.appendChild(this.shadow);\n if (this.is_svg_engine) {\n this.e_canvas.setAttribute('width', this.jm.view.size.w);\n this.e_canvas.setAttribute('height', this.jm.view.size.h);\n } else {\n this.e_canvas.width = this.jm.view.size.w;\n this.e_canvas.height = this.jm.view.size.h;\n }\n }\n /** Create canvas or SVG for drawing drag lines. */\n create_canvas() {\n if (this.is_svg_engine) {\n // Create SVG element for helper lines\n var svg = this._create_svg_element('svg');\n svg.setAttribute('class', 'jsmind-draggable-helper');\n svg.setAttribute('style', 'position: absolute; top: 0; left: 0; pointer-events: none;');\n this.jm.view.e_panel.appendChild(svg);\n this.e_canvas = svg;\n } else {\n // Create Canvas element for helper lines\n var c = $.c('canvas');\n this.jm.view.e_panel.appendChild(c);\n var ctx = c.getContext('2d');\n this.e_canvas = c;\n this.canvas_ctx = ctx;\n }\n }\n /**\n * Create SVG element with proper namespace.\n * @param {string} tag - SVG tag name\n * @returns {SVGElement}\n * @private\n */\n _create_svg_element(tag) {\n return $.d.createElementNS('http://www.w3.org/2000/svg', tag);\n }\n create_shadow() {\n var s = $.c('jmnode');\n s.style.visibility = 'hidden';\n s.style.zIndex = '3';\n s.style.cursor = 'move';\n s.style.opacity = '0.7';\n s.className = this.options.shadow_node_class_name;\n this.shadow = s;\n }\n /**\n * Reset shadow element style and cache its size.\n * @param {HTMLElement} el - The node element to mirror as shadow\n */\n reset_shadow(el) {\n var s = this.shadow.style;\n this.shadow.innerHTML = el.innerHTML;\n s.left = el.style.left;\n s.top = el.style.top;\n s.width = el.style.width;\n s.height = el.style.height;\n s.backgroundImage = el.style.backgroundImage;\n s.backgroundSize = el.style.backgroundSize;\n s.transform = el.style.transform;\n this.shadow_w = this.shadow.clientWidth;\n this.shadow_h = this.shadow.clientHeight;\n }\n /** Show the shadow element. */\n show_shadow() {\n if (!this.moved) {\n this.shadow.style.visibility = 'visible';\n }\n }\n /** Hide the shadow element. */\n hide_shadow() {\n this.shadow.style.visibility = 'hidden';\n }\n /**\n * Draw a helper line between the shadow and target node.\n * @param {{x:number,y:number}} shadow_p - Shadow anchor point\n * @param {{x:number,y:number}} node_p - Target node anchor point\n * @param {boolean} invalid - Whether current target is invalid\n */\n magnet_shadow(shadow_p, node_p, invalid) {\n this.clear_lines();\n var color = invalid ? this.options.line_color_invalid : this.options.line_color;\n\n if (this.is_svg_engine) {\n this.svg_draw_line(shadow_p.x, shadow_p.y, node_p.x, node_p.y, color);\n } else {\n this.canvas_ctx.lineWidth = this.options.line_width;\n this.canvas_ctx.strokeStyle = color;\n this.canvas_ctx.lineCap = 'round';\n this.canvas_lineto(shadow_p.x, shadow_p.y, node_p.x, node_p.y);\n }\n }\n /** Clear helper lines from canvas or SVG. */\n clear_lines() {\n if (this.is_svg_engine) {\n if (this.helper_line && this.helper_line.parentNode) {\n this.e_canvas.removeChild(this.helper_line);\n this.helper_line = null;\n }\n } else {\n this.canvas_ctx.clearRect(0, 0, this.jm.view.size.w, this.jm.view.size.h);\n }\n }\n /**\n * Draw a straight helper line on canvas.\n * @param {number} x1\n * @param {number} y1\n * @param {number} x2\n * @param {number} y2\n */\n canvas_lineto(x1, y1, x2, y2) {\n this.canvas_ctx.beginPath();\n this.canvas_ctx.moveTo(x1, y1);\n this.canvas_ctx.lineTo(x2, y2);\n this.canvas_ctx.stroke();\n }\n /**\n * Draw a helper line on SVG using bezier curve.\n * Reuses the line drawing logic from SvgGraph.\n * @param {number} x1 - Start x coordinate\n * @param {number} y1 - Start y coordinate\n * @param {number} x2 - End x coordinate\n * @param {number} y2 - End y coordinate\n * @param {string} color - Line color\n */\n svg_draw_line(x1, y1, x2, y2, color) {\n // Create SVG path element for helper line\n this.helper_line = this._create_svg_element('path');\n this.helper_line.setAttribute('stroke', color);\n this.helper_line.setAttribute('stroke-width', this.options.line_width);\n this.helper_line.setAttribute('fill', 'transparent');\n this.helper_line.setAttribute('stroke-linecap', 'round');\n\n // Draw bezier curve (same as SvgGraph._bezier_to)\n this._svg_bezier_to(this.helper_line, x1, y1, x2, y2);\n\n // Add to SVG container\n this.e_canvas.appendChild(this.helper_line);\n }\n /**\n * Draw bezier curve to SVG path element.\n * Reuses logic from SvgGraph._bezier_to.\n * @param {SVGPathElement} path - SVG path element\n * @param {number} x1 - Start x coordinate\n * @param {number} y1 - Start y coordinate\n * @param {number} x2 - End x coordinate\n * @param {number} y2 - End y coordinate\n * @private\n */\n _svg_bezier_to(path, x1, y1, x2, y2) {\n path.setAttribute(\n 'd',\n 'M ' +\n x1 +\n ' ' +\n y1 +\n ' C ' +\n (x1 + ((x2 - x1) * 2) / 3) +\n ' ' +\n y1 +\n ', ' +\n x1 +\n ' ' +\n y2 +\n ', ' +\n x2 +\n ' ' +\n y2\n );\n }\n /** Bind mouse/touch events for dragging. */\n event_bind() {\n var jd = this;\n var container = this.jm.view.container;\n $.on(container, 'mousedown', function (e) {\n if (e.button === 0) {\n jd.dragstart.call(jd, e);\n }\n });\n $.on(container, 'mousemove', function (e) {\n if (e.movementX !== 0 || e.movementY !== 0) {\n jd.drag.call(jd, e);\n }\n });\n $.on(container, 'mouseup', function (e) {\n jd.dragend.call(jd, e);\n });\n $.on(container, 'touchstart', function (e) {\n jd.dragstart.call(jd, e);\n });\n $.on(container, 'touchmove', function (e) {\n jd.drag.call(jd, e);\n });\n $.on(container, 'touchend', function (e) {\n jd.dragend.call(jd, e);\n });\n }\n /**\n * Begin dragging interaction.\n * @param {MouseEvent|TouchEvent} e - Pointer down event\n */\n dragstart(e) {\n if (!this.jm.get_editable()) {\n return;\n }\n if (this.capture) {\n return;\n }\n var jview = this.jm.view;\n if (jview.is_editing()) {\n return;\n }\n this.active_node = null;\n this.view_draggable = this.jm.get_view_draggable();\n\n var el = this.find_node_element(e.target);\n if (!el) {\n return;\n }\n if (this.view_draggable) {\n this.jm.disable_view_draggable();\n }\n var nodeid = jview.get_binded_nodeid(el);\n if (!!nodeid) {\n var node = this.jm.get_node(nodeid);\n if (!node.isroot) {\n // 检查节点是否允许拖拽\n if (node.data && node.data.draggable === false) {\n return;\n }\n this.reset_shadow(el);\n this.view_panel_rect = this.view_panel.getBoundingClientRect();\n this.active_node = node;\n this.offset_x =\n (e.clientX || e.touches[0].clientX) / jview.zoom_current - el.offsetLeft;\n this.offset_y =\n (e.clientY || e.touches[0].clientY) / jview.zoom_current - el.offsetTop;\n this.client_hw = Math.floor(el.clientWidth / 2);\n this.client_hh = Math.floor(el.clientHeight / 2);\n if (this.hlookup_delay != 0) {\n $.w.clearTimeout(this.hlookup_delay);\n }\n if (this.hlookup_timer != 0) {\n $.w.clearInterval(this.hlookup_timer);\n }\n var jd = this;\n this.hlookup_delay = $.w.setTimeout(function () {\n jd.hlookup_delay = 0;\n jd.hlookup_timer = $.w.setInterval(function () {\n jd.lookup_target_node.call(jd);\n }, jd.options.lookup_interval);\n }, this.options.lookup_delay);\n jd.capture = true;\n }\n }\n }\n /**\n * Drag handler to move shadow and auto-scroll container.\n * @param {MouseEvent|TouchEvent} e - Pointer move event\n */\n drag(e) {\n if (!this.jm.get_editable()) {\n return;\n }\n if (this.capture) {\n e.preventDefault();\n this.show_shadow();\n this.moved = true;\n clear_selection();\n var jview = this.jm.view;\n var px = (e.clientX || e.touches[0].clientX) / jview.zoom_current - this.offset_x;\n var py = (e.clientY || e.touches[0].clientY) / jview.zoom_current - this.offset_y;\n // scrolling container axisY if drag nodes exceeding container\n if (\n e.clientY - this.view_panel_rect.top < this.options.scrolling_trigger_width &&\n this.view_panel.scrollTop > this.options.scrolling_step_length\n ) {\n this.view_panel.scrollBy(0, -this.options.scrolling_step_length);\n this.offset_y += this.options.scrolling_step_length / jview.zoom_current;\n } else if (\n this.view_panel_rect.bottom - e.clientY < this.options.scrolling_trigger_width &&\n this.view_panel.scrollTop <\n this.view_panel.scrollHeight -\n this.view_panel_rect.height -\n this.options.scrolling_step_length\n ) {\n this.view_panel.scrollBy(0, this.options.scrolling_step_length);\n this.offset_y -= this.options.scrolling_step_length / jview.zoom_current;\n }\n // scrolling container axisX if drag nodes exceeding container\n if (\n e.clientX - this.view_panel_rect.left < this.options.scrolling_trigger_width &&\n this.view_panel.scrollLeft > this.options.scrolling_step_length\n ) {\n this.view_panel.scrollBy(-this.options.scrolling_step_length, 0);\n this.offset_x += this.options.scrolling_step_length / jview.zoom_current;\n } else if (\n this.view_panel_rect.right - e.clientX < this.options.scrolling_trigger_width &&\n this.view_panel.scrollLeft <\n this.view_panel.scrollWidth -\n this.view_panel_rect.width -\n this.options.scrolling_step_length\n ) {\n this.view_panel.scrollBy(this.options.scrolling_step_length, 0);\n this.offset_x -= this.options.scrolling_step_length / jview.zoom_current;\n }\n this.shadow.style.left = px + 'px';\n this.shadow.style.top = py + 'px';\n clear_selection();\n }\n }\n /**\n * Finish dragging, move the node if applicable.\n * @param {MouseEvent|TouchEvent} e - Pointer up event\n */\n dragend(e) {\n if (!this.jm.get_editable()) {\n return;\n }\n if (this.view_draggable) {\n this.jm.enable_view_draggable();\n }\n if (this.capture) {\n if (this.hlookup_delay != 0) {\n $.w.clearTimeout(this.hlookup_delay);\n this.hlookup_delay = 0;\n this.clear_lines();\n }\n if (this.hlookup_timer != 0) {\n $.w.clearInterval(this.hlookup_timer);\n this.hlookup_timer = 0;\n this.clear_lines();\n }\n if (this.moved) {\n var src_node = this.active_node;\n var target_node = this.target_node;\n var target_direct = this.target_direct;\n this.move_node(src_node, target_node, target_direct);\n }\n this.hide_shadow();\n }\n this.view_panel_rect = null;\n this.moved = false;\n this.capture = false;\n }\n /**\n * Find the closest node element from an event target.\n * @param {HTMLElement} el - Current DOM element\n * @returns {HTMLElement|null} Matched node element or null\n */\n find_node_element(el) {\n if (\n el === this.jm.view.e_nodes ||\n el === this.jm.view.e_panel ||\n el === this.jm.view.container\n ) {\n return null;\n }\n if (el.tagName.toLowerCase() === 'jmnode') {\n return el;\n }\n return this.find_node_element(el.parentNode);\n }\n /** Recompute target node under the shadow and draw helper. */\n lookup_target_node() {\n let sx = this.shadow.offsetLeft;\n let sy = this.shadow.offsetTop;\n if (sx === this.shadow_p_x && sy === this.shadow_p_y) {\n return;\n }\n this.shadow_p_x = sx;\n this.shadow_p_y = sy;\n\n let target_direction =\n this.shadow_p_x + this.shadow_w / 2 >= this.get_root_x()\n ? jsMind.direction.right\n : jsMind.direction.left;\n let overlapping_node = this.lookup_overlapping_node_parent(target_direction);\n let target_node = overlapping_node || this.lookup_close_node(target_direction);\n if (!!target_node) {\n let points = this.calc_point_of_node(target_node, target_direction);\n let invalid = jsMind.node.inherited(this.active_node, target_node);\n this.magnet_shadow(points.sp, points.np, invalid);\n this.target_node = target_node;\n this.target_direct = target_direction;\n }\n }\n /**\n * Get X coordinate of root node center.\n * @returns {number}\n */\n get_root_x() {\n let root = this.jm.get_root();\n let root_location = root.get_location();\n let root_size = root.get_size();\n return root_location.x + root_size.w / 2;\n }\n\n /**\n * Lookup overlapping node's parent near the shadow position.\n * @param {number} direction - Direction constant\n * @returns {import('../jsmind.node.js').Node|null}\n */\n lookup_overlapping_node_parent(direction) {\n let shadowRect = this.shadow.getBoundingClientRect();\n let x = shadowRect.x + (shadowRect.width * (1 - direction)) / 2;\n let deltaX = (this.jm.options.layout.hspace + this.jm.options.layout.pspace) * direction;\n let deltaY = shadowRect.height;\n let points = [\n [x, shadowRect.y],\n [x, shadowRect.y + deltaY / 2],\n [x, shadowRect.y + deltaY],\n [x + deltaX / 2, shadowRect.y],\n [x + deltaX / 2, shadowRect.y + deltaY / 2],\n [x + deltaX / 2, shadowRect.y + deltaY],\n [x + deltaX, shadowRect.y],\n [x + deltaX, shadowRect.y + deltaY / 2],\n [x + deltaX, shadowRect.y + deltaY],\n ];\n for (const p of points) {\n let n = this.lookup_node_parent_by_location(p[0], p[1]);\n if (!!n) {\n return n;\n }\n }\n }\n\n /**\n * Find node's parent by a screen location.\n * @param {number} x - Client X\n * @param {number} y - Client Y\n * @returns {import('../jsmind.node.js').Node|null}\n */\n lookup_node_parent_by_location(x, y) {\n return $.d\n .elementsFromPoint(x, y)\n .filter(\n x => x.tagName === 'JMNODE' && x.className !== this.options.shadow_node_class_name\n )\n .map(el => this.jm.view.get_binded_nodeid(el))\n .map(id => id && this.jm.mind.nodes[id])\n .map(n => n && n.parent)\n .find(n => n);\n }\n\n /**\n * Lookup the closest node along a direction.\n * @param {number} direction\n * @returns {import('../jsmind.node.js').Node}\n */\n lookup_close_node(direction) {\n return Object.values(this.jm.mind.nodes)\n .filter(n => n.direction == direction || n.isroot)\n .filter(n => this.jm.layout.is_visible(n))\n .filter(n => this.shadow_on_target_side(n, direction))\n .map(n => ({ node: n, distance: this.shadow_to_node(n, direction) }))\n .reduce(\n (prev, curr) => {\n return prev.distance < curr.distance ? prev : curr;\n },\n { node: this.jm.get_root(), distance: Number.MAX_VALUE }\n ).node;\n }\n\n /**\n * Check if shadow is on the target side of a node.\n * @param {import('../jsmind.node.js').Node} node\n * @param {number} dir\n * @returns {boolean}\n */\n shadow_on_target_side(node, dir) {\n return (\n (dir == jsMind.direction.right && this.shadow_to_right_of_node(node) > 0) ||\n (dir == jsMind.direction.left && this.shadow_to_left_of_node(node) > 0)\n );\n }\n\n /**\n * Distance from shadow to the right side of a node.\n * @param {import('../jsmind.node.js').Node} node\n * @returns {number}\n */\n shadow_to_right_of_node(node) {\n return this.shadow_p_x - node.get_location().x - node.get_size().w;\n }\n\n /**\n * Distance from shadow to the left side of a node.\n * @param {import('../jsmind.node.js').Node} node\n * @returns {number}\n */\n shadow_to_left_of_node(node) {\n return node.get_location().x - this.shadow_p_x - this.shadow_w;\n }\n\n /**\n * Vertical distance between shadow centerline and node centerline.\n * @param {import('../jsmind.node.js').Node} node\n * @returns {number}\n */\n shadow_to_base_line_of_node(node) {\n return this.shadow_p_y + this.shadow_h / 2 - node.get_location().y - node.get_size().h / 2;\n }\n\n /**\n * Manhattan distance to a node along a direction.\n * @param {import('../jsmind.node.js').Node} node\n * @param {number} dir\n * @returns {number}\n */\n shadow_to_node(node, dir) {\n let distance_x =\n dir === jsMind.direction.right\n ? Math.abs(this.shadow_to_right_of_node(node))\n : Math.abs(this.shadow_to_left_of_node(node));\n let distance_y = Math.abs(this.shadow_to_base_line_of_node(node));\n return distance_x + distance_y;\n }\n\n /**\n * Calculate connection points of a node and the shadow.\n * @param {import('../jsmind.node.js').Node} node\n * @param {number} dir\n * @returns {{sp:{x:number,y:number}, np:{x:number,y:number}}}\n */\n calc_point_of_node(node, dir) {\n let ns = node.get_size();\n let nl = node.get_location();\n let node_x = node.isroot\n ? nl.x + ns.w / 2\n : nl.x + (ns.w * (1 + dir)) / 2 + this.options.line_width * dir;\n let node_y = nl.y + ns.h / 2;\n let shadow_x =\n this.shadow_p_x + (this.shadow_w * (1 - dir)) / 2 - this.options.line_width * dir;\n let shadow_y = this.shadow_p_y + this.shadow_h / 2;\n return {\n sp: { x: shadow_x, y: shadow_y },\n np: { x: node_x, y: node_y },\n };\n }\n\n /**\n * Move a node to a new parent/position.\n * @param {import('../jsmind.node.js').Node} src_node\n * @param {import('../jsmind.node.js').Node|null} target_node\n * @param {number|null} target_direct\n */\n move_node(src_node, target_node, target_direct) {\n var shadow_h = this.shadow.offsetTop;\n if (!!target_node && !!src_node && !jsMind.node.inherited(src_node, target_node)) {\n // Call validate_drag function if provided, to validate the drag operation\n if (this.options.validate_drag && typeof this.options.validate_drag === 'function') {\n const isValid = this.options.validate_drag(src_node, target_node);\n if (!isValid) {\n // Drag operation is not allowed, cleanup and return\n this.active_node = null;\n this.target_node = null;\n this.target_direct = null;\n return;\n }\n }\n\n // lookup before_node\n var sibling_nodes = target_node.children;\n var sc = sibling_nodes.length;\n var node = null;\n var delta_y = Number.MAX_VALUE;\n var node_before = null;\n var beforeid = '_last_';\n while (sc--) {\n node = sibling_nodes[sc];\n if (node.direction == target_direct && node.id != src_node.id) {\n var dy = node.get_location().y - shadow_h;\n if (dy > 0 && dy < delta_y) {\n delta_y = dy;\n node_before = node;\n beforeid = '_first_';\n }\n }\n }\n if (!!node_before) {\n beforeid = node_before.id;\n }\n this.jm.move_node(src_node.id, beforeid, target_node.id, target_direct);\n }\n this.active_node = null;\n this.target_node = null;\n this.target_direct = null;\n }\n /**\n * Handle jsMind events.\n * @param {number|string} type - Event type\n * @param {object} [data] - Event data\n */\n jm_event_handle(type, data) {\n if (type === jsMind.event_type.resize) {\n this.resize();\n }\n }\n}\n\n/**\n * Draggable node plugin registration.\n * @type {import('../jsmind.plugin.js').Plugin<Partial<DraggableNodeOptions>>}\n */\nexport const draggable_plugin = new jsMind.plugin('draggable_node', function (jm, options) {\n var jd = new DraggableNode(jm, options);\n jd.init();\n jm.add_event_listener(function (type, data) {\n jd.jm_event_handle.call(jd, type, data);\n });\n});\n\njsMind.register_plugin(draggable_plugin);\n\nexport default DraggableNode;\n"],"names":["jsMind","Error","$","clear_selection","w","getSelection","removeAllRanges","d","selection","empty","DEFAULT_OPTIONS","line_width","line_color","line_color_invalid","lookup_delay","lookup_interval","scrolling_trigger_width","scrolling_step_length","shadow_node_class_name","DraggableNode","constructor","jm","options","opts","util","json","merge","this","version","is_svg_engine","view","engine","e_canvas","canvas_ctx","helper_line","shadow","shadow_p_x","shadow_p_y","shadow_w","shadow_h","active_node","target_node","target_direct","client_w","client_h","offset_x","offset_y","hlookup_delay","hlookup_timer","capture","moved","canvas_draggable","get_view_draggable","view_panel","e_panel","view_panel_rect","init","create_canvas","create_shadow","event_bind","resize","e_nodes","appendChild","setAttribute","size","h","width","height","svg","_create_svg_element","c","ctx","getContext","tag","createElementNS","s","style","visibility","zIndex","cursor","opacity","className","reset_shadow","el","innerHTML","left","top","backgroundImage","backgroundSize","transform","clientWidth","clientHeight","show_shadow","hide_shadow","magnet_shadow","shadow_p","node_p","invalid","clear_lines","color","svg_draw_line","x","y","lineWidth","strokeStyle","lineCap","canvas_lineto","parentNode","removeChild","clearRect","x1","y1","x2","y2","beginPath","moveTo","lineTo","stroke","_svg_bezier_to","path","jd","container","on","e","button","dragstart","call","movementX","movementY","drag","dragend","get_editable","jview","is_editing","view_draggable","find_node_element","target","disable_view_draggable","nodeid","get_binded_nodeid","node","get_node","isroot","data","draggable","getBoundingClientRect","clientX","touches","zoom_current","offsetLeft","clientY","offsetTop","client_hw","Math","floor","client_hh","clearTimeout","clearInterval","setTimeout","setInterval","lookup_target_node","preventDefault","px","py","scrollTop","scrollBy","bottom","scrollHeight","scrollLeft","right","scrollWidth","enable_view_draggable","src_node","move_node","tagName","toLowerCase","sx","sy","target_direction","get_root_x","direction","lookup_overlapping_node_parent","lookup_close_node","points","calc_point_of_node","inherited","sp","np","root","get_root","root_location","get_location","root_size","get_size","shadowRect","deltaX","layout","hspace","pspace","deltaY","p","n","lookup_node_parent_by_location","elementsFromPoint","filter","map","id","mind","nodes","parent","find","Object","values","is_visible","shadow_on_target_side","distance","shadow_to_node","reduce","prev","curr","Number","MAX_VALUE","dir","shadow_to_right_of_node","shadow_to_left_of_node","shadow_to_base_line_of_node","abs","ns","nl","node_x","node_y","validate_drag","sibling_nodes","children","sc","length","delta_y","node_before","beforeid","dy","jm_event_handle","type","event_type","draggable_plugin","plugin","add_event_listener","register_plugin"],"mappings":"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"}
@@ -5,5 +5,5 @@
5
5
  * Project Home:
6
6
  * https://github.com/hizzgdev/jsmind/
7
7
  */
8
- !function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).jsMindHistory={})}(this,(function(t){"use strict";"function"!=typeof String.prototype.startsWith&&(String.prototype.startsWith=function(t){return this.slice(0,t.length)===t});const e=1,r=3,i=6,n=1,o=2,s=3,a=4;var u=function(){};let h="undefined"==typeof console?{level:u,log:u,debug:u,info:u,warn:u,error:u}:{level:function(t){h.debug=t>n?u:console.debug;h.info=t>o?u:console.info;h.warn=t>s?u:console.warn;h.error=t>a?u:console.error},log:console.log,debug:console.debug,info:console.info,warn:console.warn,error:console.error};class c{static instanceName="";static preload=!1;constructor({jm:t,pluginOpt:e}){this.jm=t,this.options=e||{}}beforePluginRemove(){}beforePluginDestroy(){this.beforePluginRemove()}}var d=Object.getOwnPropertyNames,l=Object.getOwnPropertySymbols,f=Object.prototype.hasOwnProperty;function p(t,e){return function(r,i,n){return t(r,i,n)&&e(r,i,n)}}function y(t){return function(e,r,i){if(!e||!r||"object"!=typeof e||"object"!=typeof r)return t(e,r,i);var n=i.cache,o=n.get(e),s=n.get(r);if(o&&s)return o===r&&s===e;n.set(e,r),n.set(r,e);var a=t(e,r,i);return n.delete(e),n.delete(r),a}}function g(t){return d(t).concat(l(t))}var m=Object.hasOwn||function(t,e){return f.call(t,e)};function _(t,e){return t===e||!t&&!e&&t!=t&&e!=e}var b=Object.getOwnPropertyDescriptor,v=Object.keys;function x(t,e,r){var i=t.length;if(e.length!==i)return!1;for(;i-- >0;)if(!r.equals(t[i],e[i],i,i,t,e,r))return!1;return!0}function j(t,e){return _(t.getTime(),e.getTime())}function S(t,e){return t.name===e.name&&t.message===e.message&&t.cause===e.cause&&t.stack===e.stack}function w(t,e){return t===e}function k(t,e,r){var i=t.size;if(i!==e.size)return!1;if(!i)return!0;for(var n,o,s=new Array(i),a=t.entries(),u=0;(n=a.next())&&!n.done;){for(var h=e.entries(),c=!1,d=0;(o=h.next())&&!o.done;)if(s[d])d++;else{var l=n.value,f=o.value;if(r.equals(l[0],f[0],u,d,t,e,r)&&r.equals(l[1],f[1],l[0],f[0],t,e,r)){c=s[d]=!0;break}d++}if(!c)return!1;u++}return!0}var M=_;function O(t,e,r){var i=v(t),n=i.length;if(v(e).length!==n)return!1;for(;n-- >0;)if(!T(t,e,r,i[n]))return!1;return!0}function q(t,e,r){var i,n,o,s=g(t),a=s.length;if(g(e).length!==a)return!1;for(;a-- >0;){if(!T(t,e,r,i=s[a]))return!1;if(n=b(t,i),o=b(e,i),(n||o)&&(!n||!o||n.configurable!==o.configurable||n.enumerable!==o.enumerable||n.writable!==o.writable))return!1}return!0}function A(t,e){return _(t.valueOf(),e.valueOf())}function E(t,e){return t.source===e.source&&t.flags===e.flags}function P(t,e,r){var i=t.size;if(i!==e.size)return!1;if(!i)return!0;for(var n,o,s=new Array(i),a=t.values();(n=a.next())&&!n.done;){for(var u=e.values(),h=!1,c=0;(o=u.next())&&!o.done;){if(!s[c]&&r.equals(n.value,o.value,n.value,o.value,t,e,r)){h=s[c]=!0;break}c++}if(!h)return!1}return!0}function C(t,e){var r=t.length;if(e.length!==r)return!1;for(;r-- >0;)if(t[r]!==e[r])return!1;return!0}function N(t,e){return t.hostname===e.hostname&&t.pathname===e.pathname&&t.protocol===e.protocol&&t.port===e.port&&t.hash===e.hash&&t.username===e.username&&t.password===e.password}function T(t,e,r,i){return!("_owner"!==i&&"__o"!==i&&"__v"!==i||!t.$$typeof&&!e.$$typeof)||m(e,i)&&r.equals(t[i],e[i],i,i,t,e,r)}var D=Array.isArray,I="undefined"!=typeof ArrayBuffer&&"function"==typeof ArrayBuffer.isView?ArrayBuffer.isView:null,F=Object.assign,z=Object.prototype.toString.call.bind(Object.prototype.toString);function K(t){var e=t.areArraysEqual,r=t.areDatesEqual,i=t.areErrorsEqual,n=t.areFunctionsEqual,o=t.areMapsEqual,s=t.areNumbersEqual,a=t.areObjectsEqual,u=t.arePrimitiveWrappersEqual,h=t.areRegExpsEqual,c=t.areSetsEqual,d=t.areTypedArraysEqual,l=t.areUrlsEqual,f=t.unknownTagComparators;return function(t,p,y){if(t===p)return!0;if(null==t||null==p)return!1;var g=typeof t;if(g!==typeof p)return!1;if("object"!==g)return"number"===g?s(t,p,y):"function"===g&&n(t,p,y);var m=t.constructor;if(m!==p.constructor)return!1;if(m===Object)return a(t,p,y);if(D(t))return e(t,p,y);if(null!=I&&I(t))return d(t,p,y);if(m===Date)return r(t,p,y);if(m===RegExp)return h(t,p,y);if(m===Map)return o(t,p,y);if(m===Set)return c(t,p,y);var _,b=z(t);if("[object Date]"===b)return r(t,p,y);if("[object RegExp]"===b)return h(t,p,y);if("[object Map]"===b)return o(t,p,y);if("[object Set]"===b)return c(t,p,y);if("[object Object]"===b)return"function"!=typeof t.then&&"function"!=typeof p.then&&a(t,p,y);if("[object URL]"===b)return l(t,p,y);if("[object Error]"===b)return i(t,p,y);if("[object Arguments]"===b)return a(t,p,y);if("[object Boolean]"===b||"[object Number]"===b||"[object String]"===b)return u(t,p,y);if(f){var v=f[b];if(!v){var x=null!=(_=t)?_[Symbol.toStringTag]:void 0;x&&(v=f[x])}if(v)return v(t,p,y)}return!1}}var R=B();function B(t){void 0===t&&(t={});var e,r=t.circular,i=void 0!==r&&r,n=t.createInternalComparator,o=t.createState,s=t.strict,a=void 0!==s&&s,u=function(t){var e=t.circular,r=t.createCustomConfig,i=t.strict,n={areArraysEqual:i?q:x,areDatesEqual:j,areErrorsEqual:S,areFunctionsEqual:w,areMapsEqual:i?p(k,q):k,areNumbersEqual:M,areObjectsEqual:i?q:O,arePrimitiveWrappersEqual:A,areRegExpsEqual:E,areSetsEqual:i?p(P,q):P,areTypedArraysEqual:i?q:C,areUrlsEqual:N,unknownTagComparators:void 0};if(r&&(n=F({},n,r(n))),e){var o=y(n.areArraysEqual),s=y(n.areMapsEqual),a=y(n.areObjectsEqual),u=y(n.areSetsEqual);n=F({},n,{areArraysEqual:o,areMapsEqual:s,areObjectsEqual:a,areSetsEqual:u})}return n}(t),h=K(u);return function(t){var e=t.circular,r=t.comparator,i=t.createState,n=t.equals,o=t.strict;if(i)return function(t,s){var a=i(),u=a.cache,h=void 0===u?e?new WeakMap:void 0:u,c=a.meta;return r(t,s,{cache:h,equals:n,meta:c,strict:o})};if(e)return function(t,e){return r(t,e,{cache:new WeakMap,equals:n,meta:void 0,strict:o})};var s={cache:void 0,equals:n,meta:void 0,strict:o};return function(t,e){return r(t,e,s)}}({circular:i,comparator:h,createState:o,equals:n?n(h):(e=h,function(t,r,i,n,o,s,a){return e(t,r,a)}),strict:a})}function H(t,e){const r=function(t){return(e=t)&&"object"==typeof e&&"data"in e?t.data:t;var e}(t),i=e&&Array.isArray(e.fields)?e.fields:["topic","data","id"],n=e&&e.idKey?e.idKey:"id",o=e&&e.childrenKey?e.childrenKey:"children",s=!e||!1!==e.includeStructure,a=new Map;return r&&r[n]&&function t(e,r,u){const h=function(t){const e={};n in t&&(e[n]=t[n]);const r=new Set([n,o,"direction","expanded","parentid","index","isroot"]);i.includes("data");for(const o of i)if("data"===o){const n={};let o=!1;for(const e in t)r.has(e)||i.includes(e)||(n[e]=t[e],o=!0);o&&(e.data=n)}else o in t&&o!==n&&(e[o]=t[o]);return e}(e),c=e[n];s&&(h.parentid=r||null,h.index="number"==typeof u?u:0),a.set(c,h);const d=e[o];d&&Array.isArray(d)&&d.forEach(((e,r)=>t(e,c,r)))}(r,null,0),a}function U(t,e){if(t===e)return!0;if(!t||!e)return!1;const r=Object.keys(t),i=Object.keys(e);if(r.length!==i.length)return!1;for(const i of r){const r=t[i],n=e[i];if(r===n)continue;if(r&&n&&"object"==typeof r&&"object"==typeof n){if(!R(r,n))return!1}else if(r!==n)return!1}return!0}function W(t,e){const r=[];if(!t||!e)return r;const i=new Set([...Object.keys(t),...Object.keys(e)]);i.delete("id");for(const n of i){const i=t[n],o=e[n];if(i===o)continue;(i&&o&&"object"==typeof i&&"object"==typeof o?!R(i,o):i!==o)&&r.push({key:n,before:i,after:o})}return r}function $(t){let e=!1,r=!1;for(const i of t)"parentid"===i.key&&(e=!0),"index"===i.key&&(r=!0);return{moved:e||r,parentChanged:e,orderChanged:r}}function J(t,e,r,i,n,o){if(n<=o)return!1;const s=[],a=[];for(const[e,r]of t)r.parentid===i&&s.push({id:e,index:r.index});for(const[t,r]of e)r.parentid===i&&a.push({id:t,index:r.index});s.sort(((t,e)=>t.index-e.index)),a.sort(((t,e)=>t.index-e.index));let u=0;for(const t of s)if(t.index<n){a.some((e=>e.id===t.id))||u++}return n-o===u}function Y(t,e,r={}){const{fields:i,idKey:n,childrenKey:o,includeStructure:s=!0,maxSize:a=5e3,categorize:u=!1,ignoreDeletionShift:h=!1}=r,c=H(t,{fields:i,idKey:n,childrenKey:o,includeStructure:s}),d=H(e,{fields:i,idKey:n,childrenKey:o,includeStructure:s}),l=[],f=[],p=[];for(const[t,e]of d){if(!c.has(t)){l.push(e);continue}const r=c.get(t);if(!U(r,e)){const i=W(r,e);if(h&&!i.some((t=>"parentid"===t.key))){if(i.some((t=>"index"===t.key))){const t=i.find((t=>"index"===t.key));if(J(c,d,0,r.parentid,t.before,t.after)){const t=i.filter((t=>"index"!==t.key));if(0===t.length)continue;i.length=0,i.push(...t)}}}f.push({id:t,before:r,after:e,changes:i})}}for(const[t,e]of c)d.has(t)||p.push(e);let y=!1;const g=l.length+f.length+p.length;if(g>a){y=!0;const t=Math.max(0,a),e=Math.min(l.length,Math.floor(t*(l.length/g))),r=Math.min(f.length,Math.floor(t*(f.length/g))),i=Math.min(p.length,Math.max(0,t-e-r));l.length=e,f.length=r,p.length=i}if(u&&s){const t=function(t){const e=[],r=[],i=[];for(const n of t){const{id:t,before:o,after:s,changes:a}=n,u=$(a);if(u.moved){const r={parentChanged:u.parentChanged,orderChanged:u.orderChanged,fromParent:o.parentid,toParent:s.parentid,fromOrder:o.index,toOrder:s.index},n=a.filter((t=>"parentid"!==t.key&&"index"!==t.key));n.length>0?i.push({id:t,before:o,after:s,changes:n,moveInfo:r}):e.push({id:t,before:o,after:s,moveInfo:r})}else r.push({id:t,before:o,after:s,changes:a})}return{moved:e,modified:r,movedAndModified:i}}(f);return{created:l,updated:f,deleted:p,truncated:y,moved:t.moved,modified:t.modified,movedAndModified:t.movedAndModified}}return{created:l,updated:f,deleted:p,truncated:y}}B({strict:!0}),B({circular:!0}),B({circular:!0,strict:!0}),B({createInternalComparator:function(){return _}}),B({strict:!0,createInternalComparator:function(){return _}}),B({circular:!0,createInternalComparator:function(){return _}}),B({circular:!0,createInternalComparator:function(){return _},strict:!0});const V={enabled:!0,throttleMs:100,maxHistory:500,storageMode:"object",autoSwitchThreshold:0,keymap:{enabled:!1,redoUsesY:!1},detail:{enabled:!1},diff:{flat:!0,fields:void 0,maxSize:5e3}};class L extends c{static instanceName="historyPlugin";static preload=!0;constructor({jm:t,pluginOpt:e}){super({jm:t,pluginOpt:e}),this.options=function(t){const e=Object.assign({},V,t||{});return e.keymap||(e.keymap={enabled:!1,redoUsesY:!1}),e.detail||(e.detail={enabled:!1}),e.diff||(e.diff={flat:!0,fields:void 0,maxSize:5e3}),e}(e),this._mounted=!1,this._core=null,this._mountAPI(),this._initCore()}beforePluginDestroy(){h.debug("[history] beforePluginDestroy: clearing history stack"),this._core&&this._core.clear()}_initCore(){const t=this.jm,i=this.options;i.keymap&&i.keymap.enabled&&t.options&&t.options.shortcut&&this._injectShortcuts(t.options.shortcut,!!i.keymap.redoUsesY);const n=new G(t,i);this._core=n,t.history&&(t.history.add=(t,e)=>n.add(t,e),t.history.pause=()=>n.pause(),t.history.resume=t=>n.resume(!!t),t.history.clear=()=>n.clear(),t.history.canBack=()=>n.canBack(),t.history.canForward=()=>n.canForward(),t.history.back=t=>n.back("number"==typeof t?t:1),t.history.forward=t=>n.forward("number"==typeof t?t:1),t.history.length=()=>n.length(),t.history.index=()=>n.index(),t.history.setMax=t=>n.setMax(t),t.history.setThrottle=t=>n.setThrottle(t),t.history.exportSnapshot=()=>n.exportSnapshot(),t.history.importSnapshot=(t,e)=>n.importSnapshot(t,e),t.history.getStack=()=>n.getStackMeta(),t.history.diff=(t,e,r)=>{const i=this.jm.options.fieldNames,n=i?.id||"id";return Y(t,e,{fields:[i?.topic||"topic","data",n],idKey:n,childrenKey:i?.children||"children",...r})},this._listener=(t,i)=>{try{if(t===e&&i&&"data"in i){let t=null;const e=i.data&&i.data[0];if(e)if(e.data)if(Array.isArray(e.data)){const r=e.data.find((t=>t.isroot));t=r&&r.id}else t=e.data.id;else e.id&&(t=e.id);return void(t&&t!==n._lastRootId&&(h.debug("[history] root id changed, clearing stack and pausing"),n.clear(),n._lastRootId=t,setTimeout((()=>{try{h.debug("[history] adding bootstrap snapshot after show"),n._addNow&&n._addNow("bootstrap"),h.debug("[history] resuming history recording")}catch(t){h.warn("[history] failed to add bootstrap snapshot",t)}}),100)))}t===r&&i&&i.evt&&n.add(i.evt,i)}catch(t){h.warn("[history] listener error",t)}},t.add_event_listener(this._listener))}_injectShortcuts(t,e){const r=[4186,8282],i=e?[4185,8281]:[5210,9306];t.handles.history_back=(t,e)=>{t.history&&t.history.back()&&(e.preventDefault(),e.stopPropagation&&e.stopPropagation())},t.handles.history_forward=(t,e)=>{t.history&&t.history.forward()&&(e.preventDefault(),e.stopPropagation&&e.stopPropagation())},t.mapping.history_back=r,t.mapping.history_forward=i}_mountAPI(){if(this._mounted)return;const t=this.jm,e={add:()=>{},pause:()=>{},resume:t=>{},clear:()=>{},canBack:()=>!1,canForward:()=>!1,back:t=>!1,forward:t=>!1,length:()=>0,index:()=>-1,setMax:t=>{},setThrottle:t=>{},exportSnapshot:()=>null,importSnapshot:(t,e)=>{},getStack:()=>({items:[],index:-1}),diff:(t,e,r)=>{const i=this.jm.options.fieldNames,n=i?.id||"id";return Y(t,e,{fields:[i?.topic||"topic","data",n],idKey:n,childrenKey:i?.children||"children",...r})},getOptions:()=>Object.assign({},this.options)};Object.defineProperty(t,"history",{value:e,configurable:!0,enumerable:!1,writable:!1}),this._mounted=!0,h.info("[history] API mounted (preload).")}beforePluginRemove(){try{if(this._listener&&this.jm&&Array.isArray(this.jm.event_handles)){const t=this.jm.event_handles.indexOf(this._listener);t>=0&&this.jm.event_handles.splice(t,1)}this.jm&&Object.prototype.hasOwnProperty.call(this.jm,"history")&&delete this.jm.history,this._mounted=!1}catch(t){h.error("[history] remove failed:",t)}}beforePluginDestroy(){h.error("beforePluginDestroy"),this.beforePluginRemove()}}class G{constructor(t,e){this.jm=t,this.options=e,this.enabled=!!e.enabled,this.maxHistory=Math.max(1,0|e.maxHistory),this.throttleMs=Math.max(0,0|e.throttleMs),this.storageMode=e.storageMode||"object",this.autoSwitchThreshold=Math.max(0,0|e.autoSwitchThreshold),this._history=[],this._idx=-1,this._paused=!1,this._lastAddAt=0,this._timer=0,this._pending=!1,this._pendingMeta=void 0,this._lastSig=null,this._lastRootId=null}add(t="manual",e){if(!this.enabled||this._paused)return;const r=Date.now()-this._lastAddAt;if(r>=this.throttleMs)return this._addNow(t,e),void(this._lastAddAt=Date.now());if(this._pending=!0,this._pendingMeta=e,this._timer)return;const i=Math.max(0,this.throttleMs-r);this._timer=setTimeout((()=>{this._timer=0,!this._paused&&this.enabled&&(this._addNow(t,this._pendingMeta),this._lastAddAt=Date.now()),this._pending=!1,this._pendingMeta=void 0}),i)}pause(){this._paused=!0}resume(t=!1){this._paused=!1,t&&this._pending&&(clearTimeout(this._timer),this._timer=0,this._addNow("resume-flush",this._pendingMeta),this._lastAddAt=Date.now(),this._pending=!1,this._pendingMeta=void 0)}clear(){this._history=[],this._idx=-1,this._lastSig=null,this._notifyChange()}canBack(){return this._idx>0}canForward(){return this._idx>=0&&this._idx<this._history.length-1}back(t=1){if((!Number.isFinite(t)||t<=0)&&(t=1),this._idx-t<0)return!1;this._idx-=t;const e=this._applyIndex();return e&&this._notifyChange(),e}forward(t=1){if((!Number.isFinite(t)||t<=0)&&(t=1),this._idx+t>=this._history.length)return!1;this._idx+=t;const e=this._applyIndex();return e&&this._notifyChange(),e}length(){return this._history.length}index(){return this._idx}setMax(t){this.maxHistory=Math.max(1,0|t)}setThrottle(t){this.throttleMs=Math.max(0,0|t)}exportSnapshot(){return this._takeSnapshot()}importSnapshot(t,e){return this._applySnapshot(t,e)}getStackMeta(){return{items:this._history.slice(),index:this._idx}}_notifyChange(){try{this.jm.invoke_event_handle(i,{index:this._idx,length:this._history.length,canBack:this.canBack(),canForward:this.canForward()})}catch(t){h.warn("[history] failed to notify change",t)}}_addNow(t,e){const r=this._takeSnapshot();let i=this.storageMode;if(this.autoSwitchThreshold>0&&"object"===i){const t=this._countNodes(r);t>this.autoSwitchThreshold&&(i="string",h.debug(`[history] auto-switched to string mode (${t} nodes > ${this.autoSwitchThreshold})`))}let n=null;try{n=JSON.stringify(r)}catch{}if(!n||!this._lastSig||n!==this._lastSig){if(this._idx<this._history.length-1&&(this._history=this._history.slice(0,this._idx+1)),this._history.length>=this.maxHistory&&(this._history.shift(),this._idx=Math.max(-1,this._idx-1)),"string"===i)this._history.push(n);else{const t=this._deepFreeze(r);this._history.push(t)}this._idx=this._history.length-1,this._lastSig=n,this._notifyChange()}}_applyIndex(){const t=this._history[this._idx];if(!t)return!1;try{let e;if("string"==typeof t)e=JSON.parse(t),this._lastSig=t;else{e=this._cloneSnapshot(t);try{this._lastSig=JSON.stringify(t)}catch{this._lastSig=null}}return this._applySnapshot(e,{skipCentering:!0}),!0}catch(t){return h.error("[history] apply snapshot failed",t),!1}}_takeSnapshot(){return this.jm.get_data("node_tree")}_applySnapshot(t,e){const r=!(!e||!e.skipCentering);return this.jm.show(t,r),!0}_countNodes(t){let e=0;return function t(r){if(r&&(e++,r.children&&Array.isArray(r.children)))for(const e of r.children)t(e)}(t&&t.data?t.data:t),e}_deepFreeze(t){if(!t||"object"!=typeof t)return t;if(Object.isFrozen(t))return t;if(Object.freeze(t),Array.isArray(t))for(const e of t)this._deepFreeze(e);else for(const e of Object.keys(t))this._deepFreeze(t[e]);return t}_cloneSnapshot(t){if("function"==typeof structuredClone)try{return structuredClone(t)}catch{}try{return JSON.parse(JSON.stringify(t))}catch{return t}}}t.HistoryPlugin=L,t.default=L,Object.defineProperty(t,"__esModule",{value:!0})}));
8
+ !function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).jsMindHistory={})}(this,function(t){"use strict";"function"!=typeof String.prototype.startsWith&&(String.prototype.startsWith=function(t){return this.slice(0,t.length)===t});const e=1,r=3,n=6,i=1,o=2,s=3,a=4;var h=function(){};let c="undefined"==typeof console?{level:h,log:h,debug:h,info:h,warn:h,error:h}:{level:function(t){c.debug=t>i?h:console.debug;c.info=t>o?h:console.info;c.warn=t>s?h:console.warn;c.error=t>a?h:console.error},log:console.log,debug:console.debug,info:console.info,warn:console.warn,error:console.error};class u{static instanceName="";static preload=!1;constructor({jm:t,pluginOpt:e}){this.jm=t,this.options=e||{}}beforePluginRemove(){}beforePluginDestroy(){this.beforePluginRemove()}}var d=Object.getOwnPropertyNames,l=Object.getOwnPropertySymbols,f=Object.prototype.hasOwnProperty;function p(t,e){return function(r,n,i){return t(r,n,i)&&e(r,n,i)}}function y(t){return function(e,r,n){if(!e||!r||"object"!=typeof e||"object"!=typeof r)return t(e,r,n);var i=n.cache,o=i.get(e),s=i.get(r);if(o&&s)return o===r&&s===e;i.set(e,r),i.set(r,e);var a=t(e,r,n);return i.delete(e),i.delete(r),a}}function g(t){return d(t).concat(l(t))}var m=Object.hasOwn||function(t,e){return f.call(t,e)};function _(t,e){return t===e||!t&&!e&&t!=t&&e!=e}var b=Object.getOwnPropertyDescriptor,v=Object.keys;function x(t,e,r){var n=t.length;if(e.length!==n)return!1;for(;n-- >0;)if(!r.equals(t[n],e[n],n,n,t,e,r))return!1;return!0}function j(t,e){return _(t.getTime(),e.getTime())}function S(t,e){return t.name===e.name&&t.message===e.message&&t.cause===e.cause&&t.stack===e.stack}function w(t,e){return t===e}function M(t,e,r){var n=t.size;if(n!==e.size)return!1;if(!n)return!0;for(var i,o,s=new Array(n),a=t.entries(),h=0;(i=a.next())&&!i.done;){for(var c=e.entries(),u=!1,d=0;(o=c.next())&&!o.done;)if(s[d])d++;else{var l=i.value,f=o.value;if(r.equals(l[0],f[0],h,d,t,e,r)&&r.equals(l[1],f[1],l[0],f[0],t,e,r)){u=s[d]=!0;break}d++}if(!u)return!1;h++}return!0}var k=_;function O(t,e,r){var n=v(t),i=n.length;if(v(e).length!==i)return!1;for(;i-- >0;)if(!T(t,e,r,n[i]))return!1;return!0}function A(t,e,r){var n,i,o,s=g(t),a=s.length;if(g(e).length!==a)return!1;for(;a-- >0;){if(!T(t,e,r,n=s[a]))return!1;if(i=b(t,n),o=b(e,n),(i||o)&&(!i||!o||i.configurable!==o.configurable||i.enumerable!==o.enumerable||i.writable!==o.writable))return!1}return!0}function q(t,e){return _(t.valueOf(),e.valueOf())}function E(t,e){return t.source===e.source&&t.flags===e.flags}function C(t,e,r){var n=t.size;if(n!==e.size)return!1;if(!n)return!0;for(var i,o,s=new Array(n),a=t.values();(i=a.next())&&!i.done;){for(var h=e.values(),c=!1,u=0;(o=h.next())&&!o.done;){if(!s[u]&&r.equals(i.value,o.value,i.value,o.value,t,e,r)){c=s[u]=!0;break}u++}if(!c)return!1}return!0}function P(t,e){var r=t.length;if(e.length!==r)return!1;for(;r-- >0;)if(t[r]!==e[r])return!1;return!0}function N(t,e){return t.hostname===e.hostname&&t.pathname===e.pathname&&t.protocol===e.protocol&&t.port===e.port&&t.hash===e.hash&&t.username===e.username&&t.password===e.password}function T(t,e,r,n){return!("_owner"!==n&&"__o"!==n&&"__v"!==n||!t.$$typeof&&!e.$$typeof)||m(e,n)&&r.equals(t[n],e[n],n,n,t,e,r)}var D=Array.isArray,I="function"==typeof ArrayBuffer&&ArrayBuffer.isView?ArrayBuffer.isView:null,F=Object.assign,K=Object.prototype.toString.call.bind(Object.prototype.toString);function z(t){var e=t.areArraysEqual,r=t.areDatesEqual,n=t.areErrorsEqual,i=t.areFunctionsEqual,o=t.areMapsEqual,s=t.areNumbersEqual,a=t.areObjectsEqual,h=t.arePrimitiveWrappersEqual,c=t.areRegExpsEqual,u=t.areSetsEqual,d=t.areTypedArraysEqual,l=t.areUrlsEqual,f=t.unknownTagComparators;return function(t,p,y){if(t===p)return!0;if(null==t||null==p)return!1;var g=typeof t;if(g!==typeof p)return!1;if("object"!==g)return"number"===g?s(t,p,y):"function"===g&&i(t,p,y);var m=t.constructor;if(m!==p.constructor)return!1;if(m===Object)return a(t,p,y);if(D(t))return e(t,p,y);if(null!=I&&I(t))return d(t,p,y);if(m===Date)return r(t,p,y);if(m===RegExp)return c(t,p,y);if(m===Map)return o(t,p,y);if(m===Set)return u(t,p,y);var _,b=K(t);if("[object Date]"===b)return r(t,p,y);if("[object RegExp]"===b)return c(t,p,y);if("[object Map]"===b)return o(t,p,y);if("[object Set]"===b)return u(t,p,y);if("[object Object]"===b)return"function"!=typeof t.then&&"function"!=typeof p.then&&a(t,p,y);if("[object URL]"===b)return l(t,p,y);if("[object Error]"===b)return n(t,p,y);if("[object Arguments]"===b)return a(t,p,y);if("[object Boolean]"===b||"[object Number]"===b||"[object String]"===b)return h(t,p,y);if(f){var v=f[b];if(!v){var x=null!=(_=t)?_[Symbol.toStringTag]:void 0;x&&(v=f[x])}if(v)return v(t,p,y)}return!1}}var R=B();function B(t){void 0===t&&(t={});var e,r=t.circular,n=void 0!==r&&r,i=t.createInternalComparator,o=t.createState,s=t.strict,a=void 0!==s&&s,h=function(t){var e=t.circular,r=t.createCustomConfig,n=t.strict,i={areArraysEqual:n?A:x,areDatesEqual:j,areErrorsEqual:S,areFunctionsEqual:w,areMapsEqual:n?p(M,A):M,areNumbersEqual:k,areObjectsEqual:n?A:O,arePrimitiveWrappersEqual:q,areRegExpsEqual:E,areSetsEqual:n?p(C,A):C,areTypedArraysEqual:n?A:P,areUrlsEqual:N,unknownTagComparators:void 0};if(r&&(i=F({},i,r(i))),e){var o=y(i.areArraysEqual),s=y(i.areMapsEqual),a=y(i.areObjectsEqual),h=y(i.areSetsEqual);i=F({},i,{areArraysEqual:o,areMapsEqual:s,areObjectsEqual:a,areSetsEqual:h})}return i}(t),c=z(h);return function(t){var e=t.circular,r=t.comparator,n=t.createState,i=t.equals,o=t.strict;if(n)return function(t,s){var a=n(),h=a.cache,c=void 0===h?e?new WeakMap:void 0:h,u=a.meta;return r(t,s,{cache:c,equals:i,meta:u,strict:o})};if(e)return function(t,e){return r(t,e,{cache:new WeakMap,equals:i,meta:void 0,strict:o})};var s={cache:void 0,equals:i,meta:void 0,strict:o};return function(t,e){return r(t,e,s)}}({circular:n,comparator:c,createState:o,equals:i?i(c):(e=c,function(t,r,n,i,o,s,a){return e(t,r,a)}),strict:a})}function H(t,e){const r=function(t){return(e=t)&&"object"==typeof e&&"data"in e?t.data:t;var e}(t),n=e&&Array.isArray(e.fields)?e.fields:["topic","data","id"],i=e&&e.idKey?e.idKey:"id",o=e&&e.childrenKey?e.childrenKey:"children",s=!e||!1!==e.includeStructure,a=new Map;return r&&r[i]&&function t(e,r,h){const c=function(t){const e={};i in t&&(e[i]=t[i]);const r=new Set([i,o,"direction","expanded","parentid","index","isroot"]);n.includes("data");for(const o of n)if("data"===o){const i={};let o=!1;for(const e in t)r.has(e)||n.includes(e)||(i[e]=t[e],o=!0);o&&(e.data=i)}else o in t&&o!==i&&(e[o]=t[o]);return e}(e),u=e[i];s&&(c.parentid=r||null,c.index="number"==typeof h?h:0),a.set(u,c);const d=e[o];d&&Array.isArray(d)&&d.forEach((e,r)=>t(e,u,r))}(r,null,0),a}function U(t,e){if(t===e)return!0;if(!t||!e)return!1;const r=Object.keys(t),n=Object.keys(e);if(r.length!==n.length)return!1;for(const n of r){const r=t[n],i=e[n];if(r===i)continue;if(r&&i&&"object"==typeof r&&"object"==typeof i){if(!R(r,i))return!1}else if(r!==i)return!1}return!0}function W(t,e){const r=[];if(!t||!e)return r;const n=new Set([...Object.keys(t),...Object.keys(e)]);n.delete("id");for(const i of n){const n=t[i],o=e[i];if(n===o)continue;(n&&o&&"object"==typeof n&&"object"==typeof o?!R(n,o):n!==o)&&r.push({key:i,before:n,after:o})}return r}function $(t){let e=!1,r=!1;for(const n of t)"parentid"===n.key&&(e=!0),"index"===n.key&&(r=!0);return{moved:e||r,parentChanged:e,orderChanged:r}}function J(t){const e=new Map;for(const[r,n]of t){const t=n.parentid;e.has(t)||e.set(t,[]),e.get(t).push({id:r,index:n.index})}for(const t of e.values())t.sort((t,e)=>t.index-e.index);return e}function Y(t,e,r){const n=new Set,i=new Map;e.forEach((t,e)=>i.set(t.id,e));const o=[],s=[];for(const e of t)i.has(e.id)&&(o.push(e.id),s.push(i.get(e.id)));if(o.length<=1)return n;const a=function(t){const e=t.slice(),r=[0];let n,i,o,s,a;const h=t.length;for(n=0;n<h;n++){const h=t[n];if(0!==h||0===n){if(i=r[r.length-1],t[i]<h){e[n]=i,r.push(n);continue}for(o=0,s=r.length-1;o<s;)a=o+s>>1,t[r[a]]<h?o=a+1:s=a;h<t[r[o]]&&(o>0&&(e[n]=r[o-1]),r[o]=n)}}for(o=r.length,s=r[o-1];o-- >0;)r[o]=s,s=e[s];return r}(s),h=new Set(a);return o.forEach((t,e)=>{h.has(e)||n.add(t)}),n}function V(t,e,r={}){const{fields:n,idKey:i,childrenKey:o,includeStructure:s=!0,maxSize:a=5e3}=r,h=H(t,{fields:n,idKey:i,childrenKey:o,includeStructure:s}),c=H(e,{fields:n,idKey:i,childrenKey:o,includeStructure:s}),u=[],d=[],l=[];for(const[t,e]of c){if(!h.has(t)){u.push(e);continue}const r=h.get(t);if(!U(r,e)){const n=W(r,e);d.push({id:t,before:r,after:e,changes:n})}}for(const[t,e]of h)c.has(t)||l.push(e);let f=!1;const p=u.length+d.length+l.length;if(p>a){f=!0;const t=Math.max(0,a),e=Math.min(u.length,Math.floor(t*(u.length/p))),r=Math.min(d.length,Math.floor(t*(d.length/p))),n=Math.min(l.length,Math.max(0,t-e-r));u.length=e,d.length=r,l.length=n}if(s){const t=function(t,e,r){const n=[],i=[],o=[],s=new Set,a=J(e),h=J(r);for(const[t,e]of h){const r=Y(a.get(t)||[],e);for(const t of r)s.add(t)}for(const e of t){const{id:t,before:r,after:a,changes:h}=e,c=$(h),u=c.parentChanged,d=!u&&c.orderChanged&&s.has(t);if(u||d){const e={moveType:u?"cross-parent":"reorder",parentChanged:c.parentChanged,orderChanged:c.orderChanged,fromParent:r.parentid,toParent:a.parentid,fromOrder:r.index,toOrder:a.index},i=h.filter(t=>"parentid"!==t.key&&"index"!==t.key);i.length>0?o.push({id:t,before:r,after:a,changes:i,moveInfo:e}):n.push({id:t,before:r,after:a,moveInfo:e})}else if(c.orderChanged){const e=h.filter(t=>"parentid"!==t.key&&"index"!==t.key);e.length>0&&i.push({id:t,before:r,after:a,changes:e})}else i.push({id:t,before:r,after:a,changes:h})}return{moved:n,modified:i,movedAndModified:o}}(d,h,c);return{created:u,deleted:l,truncated:f,moved:t.moved,modified:t.modified,movedAndModified:t.movedAndModified}}return{created:u,deleted:l,moved:[],modified:d,movedAndModified:[],truncated:f}}B({strict:!0}),B({circular:!0}),B({circular:!0,strict:!0}),B({createInternalComparator:function(){return _}}),B({strict:!0,createInternalComparator:function(){return _}}),B({circular:!0,createInternalComparator:function(){return _}}),B({circular:!0,createInternalComparator:function(){return _},strict:!0});const L={enabled:!0,throttleMs:100,maxHistory:500,storageMode:"object",autoSwitchThreshold:0,keymap:{enabled:!1,redoUsesY:!1},detail:{enabled:!1},diff:{flat:!0,fields:void 0,maxSize:5e3}};class G extends u{static instanceName="historyPlugin";static preload=!0;constructor({jm:t,pluginOpt:e}){super({jm:t,pluginOpt:e}),this.options=function(t){const e=Object.assign({},L,t||{});return e.keymap||(e.keymap={enabled:!1,redoUsesY:!1}),e.detail||(e.detail={enabled:!1}),e.diff||(e.diff={flat:!0,fields:void 0,maxSize:5e3}),e}(e),this._mounted=!1,this._core=null,this._mountAPI(),this._initCore()}beforePluginDestroy(){c.debug("[history] beforePluginDestroy: clearing history stack"),this._core&&this._core.clear()}_initCore(){const t=this.jm,n=this.options;n.keymap&&n.keymap.enabled&&t.options&&t.options.shortcut&&this._injectShortcuts(t.options.shortcut,!!n.keymap.redoUsesY);const i=new Q(t,n);this._core=i,t.history&&(t.history.add=(t,e)=>i.add(t,e),t.history.pause=()=>i.pause(),t.history.resume=t=>i.resume(!!t),t.history.clear=()=>i.clear(),t.history.canBack=()=>i.canBack(),t.history.canForward=()=>i.canForward(),t.history.back=t=>i.back("number"==typeof t?t:1),t.history.forward=t=>i.forward("number"==typeof t?t:1),t.history.length=()=>i.length(),t.history.index=()=>i.index(),t.history.setMax=t=>i.setMax(t),t.history.setThrottle=t=>i.setThrottle(t),t.history.exportSnapshot=()=>i.exportSnapshot(),t.history.importSnapshot=(t,e)=>i.importSnapshot(t,e),t.history.getStack=()=>i.getStackMeta(),t.history.diff=(t,e,r)=>{const n=this.jm.options.fieldNames,i=n?.id||"id";return V(t,e,{fields:[n?.topic||"topic","data",i],idKey:i,childrenKey:n?.children||"children",...r})},this._listener=(t,n)=>{try{if(t===e&&n&&"data"in n){let t=null;const e=n.data&&n.data[0];if(e)if(e.data)if(Array.isArray(e.data)){const r=e.data.find(t=>t.isroot);t=r&&r.id}else t=e.data.id;else e.id&&(t=e.id);return void(t&&t!==i._lastRootId&&(c.debug("[history] root id changed, clearing stack and pausing"),i.clear(),i._lastRootId=t,setTimeout(()=>{try{c.debug("[history] adding bootstrap snapshot after show"),i._addNow&&i._addNow("bootstrap"),c.debug("[history] resuming history recording")}catch(t){c.warn("[history] failed to add bootstrap snapshot",t)}},100)))}t===r&&n&&n.evt&&i.add(n.evt,n)}catch(t){c.warn("[history] listener error",t)}},t.add_event_listener(this._listener))}_injectShortcuts(t,e){const r=[4186,8282],n=e?[4185,8281]:[5210,9306];t.handles.history_back=(t,e)=>{t.history&&t.history.back()&&(e.preventDefault(),e.stopPropagation&&e.stopPropagation())},t.handles.history_forward=(t,e)=>{t.history&&t.history.forward()&&(e.preventDefault(),e.stopPropagation&&e.stopPropagation())},t.mapping.history_back=r,t.mapping.history_forward=n}_mountAPI(){if(this._mounted)return;const t=this.jm,e={add:()=>{},pause:()=>{},resume:t=>{},clear:()=>{},canBack:()=>!1,canForward:()=>!1,back:t=>!1,forward:t=>!1,length:()=>0,index:()=>-1,setMax:t=>{},setThrottle:t=>{},exportSnapshot:()=>null,importSnapshot:(t,e)=>{},getStack:()=>({items:[],index:-1}),diff:(t,e,r)=>{const n=this.jm.options.fieldNames,i=n?.id||"id";return V(t,e,{fields:[n?.topic||"topic","data",i],idKey:i,childrenKey:n?.children||"children",...r})},getOptions:()=>Object.assign({},this.options)};Object.defineProperty(t,"history",{value:e,configurable:!0,enumerable:!1,writable:!1}),this._mounted=!0,c.info("[history] API mounted (preload).")}beforePluginRemove(){try{if(this._listener&&this.jm&&Array.isArray(this.jm.event_handles)){const t=this.jm.event_handles.indexOf(this._listener);t>=0&&this.jm.event_handles.splice(t,1)}this.jm&&Object.prototype.hasOwnProperty.call(this.jm,"history")&&delete this.jm.history,this._mounted=!1}catch(t){c.error("[history] remove failed:",t)}}beforePluginDestroy(){c.error("beforePluginDestroy"),this.beforePluginRemove()}}class Q{constructor(t,e){this.jm=t,this.options=e,this.enabled=!!e.enabled,this.maxHistory=Math.max(1,0|e.maxHistory),this.throttleMs=Math.max(0,0|e.throttleMs),this.storageMode=e.storageMode||"object",this.autoSwitchThreshold=Math.max(0,0|e.autoSwitchThreshold),this._history=[],this._idx=-1,this._paused=!1,this._lastAddAt=0,this._timer=0,this._pending=!1,this._pendingMeta=void 0,this._lastSig=null,this._lastRootId=null}add(t="manual",e){if(!this.enabled||this._paused)return;const r=Date.now()-this._lastAddAt;if(r>=this.throttleMs)return this._addNow(t,e),void(this._lastAddAt=Date.now());if(this._pending=!0,this._pendingMeta=e,this._timer)return;const n=Math.max(0,this.throttleMs-r);this._timer=setTimeout(()=>{this._timer=0,!this._paused&&this.enabled&&(this._addNow(t,this._pendingMeta),this._lastAddAt=Date.now()),this._pending=!1,this._pendingMeta=void 0},n)}pause(){this._paused=!0}resume(t=!1){this._paused=!1,t&&this._pending&&(clearTimeout(this._timer),this._timer=0,this._addNow("resume-flush",this._pendingMeta),this._lastAddAt=Date.now(),this._pending=!1,this._pendingMeta=void 0)}clear(){this._history=[],this._idx=-1,this._lastSig=null,this._notifyChange()}canBack(){return this._idx>0}canForward(){return this._idx>=0&&this._idx<this._history.length-1}back(t=1){if((!Number.isFinite(t)||t<=0)&&(t=1),this._idx-t<0)return!1;this._idx-=t;const e=this._applyIndex();return e&&this._notifyChange(),e}forward(t=1){if((!Number.isFinite(t)||t<=0)&&(t=1),this._idx+t>=this._history.length)return!1;this._idx+=t;const e=this._applyIndex();return e&&this._notifyChange(),e}length(){return this._history.length}index(){return this._idx}setMax(t){this.maxHistory=Math.max(1,0|t)}setThrottle(t){this.throttleMs=Math.max(0,0|t)}exportSnapshot(){return this._takeSnapshot()}importSnapshot(t,e){return this._applySnapshot(t,e)}getStackMeta(){return{items:this._history.slice(),index:this._idx}}_notifyChange(){try{this.jm.invoke_event_handle(n,{index:this._idx,length:this._history.length,canBack:this.canBack(),canForward:this.canForward()})}catch(t){c.warn("[history] failed to notify change",t)}}_addNow(t,e){const r=this._takeSnapshot();let n=this.storageMode;if(this.autoSwitchThreshold>0&&"object"===n){const t=this._countNodes(r);t>this.autoSwitchThreshold&&(n="string",c.debug(`[history] auto-switched to string mode (${t} nodes > ${this.autoSwitchThreshold})`))}let i=null;try{i=JSON.stringify(r)}catch{}if(!i||!this._lastSig||i!==this._lastSig){if(this._idx<this._history.length-1&&(this._history=this._history.slice(0,this._idx+1)),this._history.length>=this.maxHistory&&(this._history.shift(),this._idx=Math.max(-1,this._idx-1)),"string"===n)this._history.push(i);else{const t=this._deepFreeze(r);this._history.push(t)}this._idx=this._history.length-1,this._lastSig=i,this._notifyChange()}}_applyIndex(){const t=this._history[this._idx];if(!t)return!1;try{let e;if("string"==typeof t)e=JSON.parse(t),this._lastSig=t;else{e=this._cloneSnapshot(t);try{this._lastSig=JSON.stringify(t)}catch{this._lastSig=null}}return this._applySnapshot(e,{skipCentering:!0}),!0}catch(t){return c.error("[history] apply snapshot failed",t),!1}}_takeSnapshot(){return this.jm.get_data("node_tree")}_applySnapshot(t,e){const r=!(!e||!e.skipCentering);return this.jm.show(t,r),!0}_countNodes(t){let e=0;return function t(r){if(r&&(e++,r.children&&Array.isArray(r.children)))for(const e of r.children)t(e)}(t&&t.data?t.data:t),e}_deepFreeze(t){if(!t||"object"!=typeof t)return t;if(Object.isFrozen(t))return t;if(Object.freeze(t),Array.isArray(t))for(const e of t)this._deepFreeze(e);else for(const e of Object.keys(t))this._deepFreeze(t[e]);return t}_cloneSnapshot(t){if("function"==typeof structuredClone)try{return structuredClone(t)}catch{}try{return JSON.parse(JSON.stringify(t))}catch{return t}}}t.HistoryPlugin=G,t.default=G,Object.defineProperty(t,"__esModule",{value:!0})});
9
9
  //# sourceMappingURL=jsmind.history.js.map