@umbraci/jsmind 0.9.7 → 0.9.9

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 (43) hide show
  1. package/README.md +44 -0
  2. package/dist/jsmind.draggable-node.js +9 -0
  3. package/dist/jsmind.draggable-node.js.map +1 -0
  4. package/{es6 → dist}/jsmind.js +1 -1
  5. package/dist/jsmind.js.map +1 -0
  6. package/dist/jsmind.multiline-text.js +9 -0
  7. package/dist/jsmind.multiline-text.js.map +1 -0
  8. package/es/jsmind.draggable-node.js +9 -0
  9. package/es/jsmind.draggable-node.js.map +1 -0
  10. package/es/jsmind.js +9 -0
  11. package/es/jsmind.js.map +1 -0
  12. package/es/jsmind.multiline-text.js +9 -0
  13. package/es/jsmind.multiline-text.js.map +1 -0
  14. package/es/jsmind.screenshot.js +9 -0
  15. package/es/jsmind.screenshot.js.map +1 -0
  16. package/lib/jsmind.draggable-node.js +9 -0
  17. package/lib/jsmind.draggable-node.js.map +1 -0
  18. package/lib/jsmind.js +9 -0
  19. package/lib/jsmind.js.map +1 -0
  20. package/lib/jsmind.multiline-text.js +9 -0
  21. package/lib/jsmind.multiline-text.js.map +1 -0
  22. package/lib/jsmind.screenshot.js +9 -0
  23. package/lib/jsmind.screenshot.js.map +1 -0
  24. package/package.json +16 -11
  25. package/types/generated/jsmind.common.d.ts +2 -2
  26. package/types/generated/jsmind.d.ts +66 -4
  27. package/types/generated/jsmind.dom.d.ts +2 -2
  28. package/types/generated/jsmind.enhanced-plugin.d.ts +103 -0
  29. package/types/generated/jsmind.graph.d.ts +0 -2
  30. package/types/generated/jsmind.option.d.ts +0 -2
  31. package/types/generated/jsmind.view_provider.d.ts +1 -26
  32. package/types/generated/plugins/jsmind.multiline-text-v2.d.ts +58 -0
  33. package/types/generated/plugins/jsmind.multiline-text.d.ts +43 -0
  34. package/es6/README-en.md +0 -37
  35. package/es6/README.md +0 -34
  36. package/es6/jsmind-esm.js +0 -16
  37. package/es6/jsmind.draggable-node.js +0 -9
  38. package/es6/jsmind.draggable-node.js.map +0 -1
  39. package/es6/jsmind.js.map +0 -1
  40. package/es6/jsmind.multiline-text.js +0 -9
  41. package/es6/jsmind.multiline-text.js.map +0 -1
  42. /package/{es6 → dist}/jsmind.screenshot.js +0 -0
  43. /package/{es6 → dist}/jsmind.screenshot.js.map +0 -0
@@ -1,9 +0,0 @@
1
- /**
2
- * @license BSD-3-Clause
3
- * @copyright 2014-2025 hizzgdev@163.com
4
- *
5
- * Project Home:
6
- * https://github.com/hizzgdev/jsmind/
7
- */
8
- !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("@umbraci/jsmind")):"function"==typeof define&&define.amd?define(["exports","@umbraci/jsmind"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).jsMindMultilineText={},e.jsMind)}(this,function(e,t){"use strict";function i(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var n=i(t);if(!n.default)throw new Error("jsMind is not defined");const o=n.default.$,s={text_width:200,editor_border_color:"#4CAF50",editor_border_width:"2px",save_shortcut:"Enter",cancel_shortcut:"Escape",newline_shortcut:"Shift+Enter",auto_resize:!0,min_height:20,line_height:1.2},r={tagName:"span",clearElement:!0,applyStyles:!0,customClasses:[],customAttributes:{},customStyles:{},supportHtml:!1,preserveWhitespace:!0};function l(e,t,i={}){if(!(e&&e instanceof HTMLElement))throw new Error("renderTextToElement: element must be a valid DOM element");if(null==t)return console.warn("renderTextToElement: text is null or undefined, skipping render"),e;const s={};n.default.util.json.merge(s,r),n.default.util.json.merge(s,i),s.clearElement&&(e.innerHTML="");const l=String(t);if(s.customAttributes&&"object"==typeof s.customAttributes)for(const[t,i]of Object.entries(s.customAttributes))try{e.setAttribute(t,String(i))}catch(e){console.warn(`renderTextToElement: Failed to set attribute ${t}:`,e)}if(s.customClasses&&Array.isArray(s.customClasses))for(const t of s.customClasses)"string"==typeof t&&t.trim()&&e.classList.add(t.trim());if(l.includes("\n")?(e.textContent=l,s.applyStyles&&(e.style.whiteSpace="pre-wrap",e.style.wordBreak="break-word")):(s.applyStyles&&(e.style.whiteSpace="",e.style.wordBreak=""),s.supportHtml?o.h(e,l):o.t(e,l)),s.customStyles&&"object"==typeof s.customStyles)for(const[t,i]of Object.entries(s.customStyles))try{if(l.includes("\n")&&s.applyStyles){if("whiteSpace"===t||"white-space"===t){console.warn("renderTextToElement: Ignoring whiteSpace override for multiline text");continue}if("wordBreak"===t||"word-break"===t){console.warn("renderTextToElement: Ignoring wordBreak override for multiline text");continue}}e.style[t]=String(i)}catch(e){console.warn(`renderTextToElement: Failed to set style ${t}:`,e)}return e}function d(e,t={}){const i={};n.default.util.json.merge(i,r),n.default.util.json.merge(i,t);return l(o.c(i.tagName||"span"),e,{...i,clearElement:!1})}class _{constructor(e,t){var i={};n.default.util.json.merge(i,s),n.default.util.json.merge(i,t),this.version="0.1.0",this.jm=e,this.options=i,this.original_methods={},this.editing_node=null,this.multiline_editor=null}init(){this.override_view_methods(),this.setup_event_listeners(),this.initialized=!0,console.log("Multiline text plugin initialized - ready for first render")}override_view_methods(){const e=this.jm.view;this.original_methods.edit_node_begin=e.edit_node_begin.bind(e),this.original_methods.edit_node_end=e.edit_node_end.bind(e),this.original_methods.render_node=e.render_node.bind(e),this.original_methods.show=e.show.bind(e),this.original_methods._custom_node_render=e._custom_node_render?e._custom_node_render.bind(e):null,this.original_methods._default_node_render=e._default_node_render?e._default_node_render.bind(e):null;try{e.edit_node_begin=this.edit_node_begin.bind(this),e.edit_node_end=this.edit_node_end.bind(this),e.render_node=this._render_multiline_node_wrapper.bind(this),e.show=this._show_wrapper.bind(this),console.log("Multiline text plugin: Successfully overrode view methods")}catch(e){console.error("Multiline text plugin: Failed to override methods",e),this.restore_original_methods()}}restore_original_methods(){const e=this.jm.view;["edit_node_begin","edit_node_end","render_node","show","_custom_node_render","_default_node_render"].forEach(t=>{this.original_methods[t]&&(e[t]=this.original_methods[t])})}setup_event_listeners(){this.jm.add_event_listener((e,t)=>{this.jm_event_handle(e,t)})}_render_multiline_node_wrapper(e,t){try{this._render_multiline_node(e,t)}catch(i){console.error("Multiline text plugin: Error in render_node",i),this.original_methods.render_node&&this.original_methods.render_node(e,t)}}_show_wrapper(e){try{this.original_methods.show(!1)}catch(t){console.error("Multiline text plugin: Error in show",t),this.original_methods.show&&this.original_methods.show(e)}}_render_multiline_node(e,t){if(!t.topic)return;const i=t.topic.includes("\n"),n=i?e.clientHeight:0;let o=!1;if(this.jm.view.opts.custom_node_render&&"function"==typeof this.jm.view.opts.custom_node_render)try{o=this.jm.view.opts.custom_node_render(this.jm,e,t)}catch(e){console.error("Multiline text plugin: Error in custom_node_render",e),o=!1}if(!o)if(i)l(e,t.topic,{clearElement:!0,applyStyles:!0,supportHtml:this.jm.view.opts.support_html||!1});else{if(this.original_methods.render_node)return void this.original_methods.render_node(e,t);l(e,t.topic,{clearElement:!0,applyStyles:!1,supportHtml:this.jm.view.opts.support_html||!1})}if(i&&n>0){n!==e.clientHeight&&setTimeout(()=>{this.recalculate_layout(t)},0)}}renderMultilineText(e,t,i={}){const o={supportHtml:this.jm.view.opts.support_html||!1},s={};return n.default.util.json.merge(s,o),n.default.util.json.merge(s,i),l(e,t,s)}createMultilineElement(e,t={}){const i={supportHtml:this.jm.view.opts.support_html||!1},o={};return n.default.util.json.merge(o,i),n.default.util.json.merge(o,t),d(e,o)}renderMultilineText(e,t,i={}){const o={supportHtml:this.jm.view.opts.support_html||!1},s={};return n.default.util.json.merge(s,o),n.default.util.json.merge(s,i),l(e,t,s)}createMultilineElement(e,t={}){const i={supportHtml:this.jm.view.opts.support_html||!1},o={};return n.default.util.json.merge(o,i),n.default.util.json.merge(o,t),d(e,o)}edit_node_begin(e){e.topic?(null!=this.editing_node&&this.edit_node_end(),this.editing_node=e,this.jm.view.editing_node=e,this.create_multiline_editor(e._data.view.element,e.topic)):console.warn("don't edit image nodes")}create_multiline_editor(e,t){this.multiline_editor=o.c("div"),this.multiline_editor.contentEditable="plaintext-only",this.multiline_editor.className="jsmind-multiline-editor",this.multiline_editor.textContent=t,this.style_multiline_editor(e),this.setup_editor_events(),e.innerHTML="",e.appendChild(this.multiline_editor),e.style.zIndex=5,this.multiline_editor.focus(),this.select_all_text()}style_multiline_editor(e){const t=getComputedStyle(e),i=this.multiline_editor;i.style.width=Math.max(e.clientWidth-parseInt(t.getPropertyValue("padding-left"))-parseInt(t.getPropertyValue("padding-right")),this.options.text_width)+"px",i.style.minHeight=this.options.min_height+"px",i.style.lineHeight=this.options.line_height,i.style.border=this.options.editor_border_width+" solid "+this.options.editor_border_color,i.style.borderRadius="4px",i.style.padding="4px",i.style.outline="none",i.style.resize="none",i.style.overflow="hidden",i.style.whiteSpace="pre-wrap",i.style.wordBreak="break-word"}setup_editor_events(){const e=this.multiline_editor;o.on(e,"keydown",e=>{this.handle_editor_keydown(e)}),o.on(e,"blur",()=>{setTimeout(()=>{this.editing_node&&this.edit_node_end()},100)}),o.on(e,"input",()=>{this.auto_resize_editor()})}handle_editor_keydown(e){const t=e.key,i=e.shiftKey;if("Enter"===t){if(i)return;e.preventDefault(),this.edit_node_end()}else"Escape"===t?(e.preventDefault(),this.cancel_editing()):"Tab"===t&&(e.preventDefault(),this.edit_node_end())}auto_resize_editor(){if(!this.options.auto_resize||!this.multiline_editor)return;const e=this.multiline_editor;e.style.height="auto";const t=e.scrollHeight,i=this.options.min_height;e.style.height=Math.max(t,i)+"px"}select_all_text(){if(!this.multiline_editor)return;const e=o.d.createRange();e.selectNodeContents(this.multiline_editor);const t=o.w.getSelection();t.removeAllRanges(),t.addRange(e)}_reset_editing_state(){this.editing_node=null,this.jm.view.editing_node=null,this.multiline_editor=null,this.jm.view.e_panel.focus()}edit_node_end(){if(null==this.editing_node||!this.multiline_editor)return;const e=this.editing_node,t=e._data.view.element,i=this.multiline_editor.textContent||"";this.cleanup_editor(t);const o=this.process_multiline_text(i);n.default.util.text.is_empty(o)||e.topic===o?this._render_multiline_node(t,e):this.jm.update_node(e.id,o),this.recalculate_layout(e),this._reset_editing_state()}cancel_editing(){if(null==this.editing_node||!this.multiline_editor)return;const e=this.editing_node,t=e._data.view.element;this.cleanup_editor(t),this._render_multiline_node(t,e),this._reset_editing_state()}cleanup_editor(e){this.multiline_editor&&this.multiline_editor.parentNode&&this.multiline_editor.parentNode.removeChild(this.multiline_editor),e.style.zIndex="auto"}process_multiline_text(e){return e?e=(e=(e=e.trim()).replace(/\r\n/g,"\n").replace(/\r/g,"\n")).replace(/\n{3,}/g,"\n\n"):""}rerender_multiline_nodes_only(){if(!this.jm.mind||!this.jm.mind.nodes)return;let e=0;const t=this.jm.mind.nodes;for(const i in t){const n=t[i];if(n.topic&&n.topic.includes("\n")){const t=n._data.view;t&&t.element&&(this._render_multiline_node(t.element,n),e++)}}console.log(`Multiline text plugin: Re-rendered ${e} multiline nodes`)}rerender_existing_nodes(){this.rerender_multiline_nodes_only()}recalculate_layout(e){this.jm.layout.cache_valid=!1;const t=this.jm.mind.nodes;for(let e in t){const i=t[e];i._data.layout&&(delete i._data.layout._offset_,delete i._data.layout._pout_)}this.jm.view.update_node(e),this.jm.layout.layout(),this.jm.view.show()}jm_event_handle(e,t){n.default.event_type.resize}}const u=new n.default.plugin("multiline_text",function(e,t){var i=new _(e,t);i.init(),e.multiline_text=i});n.default.register_plugin(u),e.MultilineText=_,e.createTextElement=d,e.default=_,e.multiline_text_plugin=u,e.renderTextToElement=l,Object.defineProperty(e,"__esModule",{value:!0})});
9
- //# sourceMappingURL=jsmind.multiline-text.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"jsmind.multiline-text.js","sources":["../src/plugins/jsmind.multiline-text.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\n/**\n * Default options for multiline text plugin.\n * @typedef {Object} MultilineTextOptions\n * @property {number} [text_width] - Maximum text width in pixels\n * @property {string} [editor_border_color] - Border color for active editor\n * @property {string} [editor_border_width] - Border width for active editor\n * @property {string} [save_shortcut] - Key to save (without Shift)\n * @property {string} [cancel_shortcut] - Key to cancel editing\n * @property {string} [newline_shortcut] - Key combination for new line\n * @property {boolean} [auto_resize] - Auto-resize nodes for multiline text\n * @property {number} [min_height] - Minimum node height\n * @property {number} [line_height] - Line height multiplier\n */\nconst DEFAULT_OPTIONS = {\n text_width: 200,\n editor_border_color: '#4CAF50',\n editor_border_width: '2px',\n save_shortcut: 'Enter',\n cancel_shortcut: 'Escape',\n newline_shortcut: 'Shift+Enter',\n auto_resize: true,\n min_height: 20,\n line_height: 1.2,\n};\n\n/**\n * Default options for text rendering functions.\n * @typedef {Object} TextRenderOptions\n * @property {string} [tagName='span'] - HTML tag name for created elements\n * @property {boolean} [clearElement=true] - Whether to clear existing element content\n * @property {boolean} [applyStyles=true] - Whether to apply multiline CSS styles\n * @property {string[]} [customClasses=[]] - Array of CSS class names to add\n * @property {Object} [customAttributes={}] - Object of HTML attributes to set\n * @property {Object} [customStyles={}] - Object of inline styles to apply\n * @property {boolean} [supportHtml=false] - Whether to support HTML content\n * @property {boolean} [preserveWhitespace=true] - Whether to preserve whitespace in multiline text\n */\nconst DEFAULT_RENDER_OPTIONS = {\n tagName: 'span',\n clearElement: true,\n applyStyles: true,\n customClasses: [],\n customAttributes: {},\n customStyles: {},\n supportHtml: false,\n preserveWhitespace: true,\n};\n\n/**\n * Static utility function to render text content into an existing DOM element.\n *\n * This function handles both single-line and multiline text rendering with proper CSS styling.\n * For multiline text (containing \\n), it applies 'white-space: pre-wrap' and 'word-break: break-word'.\n * For single-line text, it uses standard text or HTML rendering based on supportHtml option.\n *\n * @param {HTMLElement} element - Target DOM element to render text into\n * @param {string} text - Text content to render (supports \\n for line breaks)\n * @param {Partial<TextRenderOptions>} [options={}] - Rendering options\n * @param {string} [options.tagName='span'] - HTML tag name (only used when creating new elements)\n * @param {boolean} [options.clearElement=true] - Whether to clear existing element content\n * @param {boolean} [options.applyStyles=true] - Whether to apply multiline CSS styles\n * @param {string[]} [options.customClasses=[]] - Array of CSS class names to add\n * @param {Object} [options.customAttributes={}] - Object of HTML attributes to set\n * @param {Object} [options.customStyles={}] - Object of inline styles to apply\n * @param {boolean} [options.supportHtml=false] - Whether to support HTML content in single-line text\n * @param {boolean} [options.preserveWhitespace=true] - Whether to preserve whitespace in multiline text\n * @returns {HTMLElement} The element with rendered text content\n * @throws {Error} If element is not a valid DOM element\n *\n * @example\n * // Basic multiline text rendering\n * const element = document.createElement('div');\n * renderTextToElement(element, 'Line 1\\nLine 2\\nLine 3');\n *\n * @example\n * // Custom styling and attributes\n * renderTextToElement(element, 'Custom text', {\n * customClasses: ['highlight', 'bold'],\n * customAttributes: { 'data-id': '123' },\n * customStyles: { color: 'red', fontSize: '14px' }\n * });\n *\n * @example\n * // HTML support for single-line text\n * renderTextToElement(element, '<strong>Bold text</strong>', {\n * supportHtml: true\n * });\n */\nexport function renderTextToElement(element, text, options = {}) {\n // Validate parameters\n if (!element || !(element instanceof HTMLElement)) {\n throw new Error('renderTextToElement: element must be a valid DOM element');\n }\n\n if (text == null) {\n console.warn('renderTextToElement: text is null or undefined, skipping render');\n return element;\n }\n\n // Merge options with defaults\n const opts = {};\n jsMind.util.json.merge(opts, DEFAULT_RENDER_OPTIONS);\n jsMind.util.json.merge(opts, options);\n\n // Clear element content if requested\n if (opts.clearElement) {\n element.innerHTML = '';\n }\n\n // Convert text to string\n const textContent = String(text);\n\n // Apply custom attributes\n if (opts.customAttributes && typeof opts.customAttributes === 'object') {\n for (const [key, value] of Object.entries(opts.customAttributes)) {\n try {\n element.setAttribute(key, String(value));\n } catch (error) {\n console.warn(`renderTextToElement: Failed to set attribute ${key}:`, error);\n }\n }\n }\n\n // Apply custom classes\n if (opts.customClasses && Array.isArray(opts.customClasses)) {\n for (const className of opts.customClasses) {\n if (typeof className === 'string' && className.trim()) {\n element.classList.add(className.trim());\n }\n }\n }\n\n // Render text content\n if (textContent.includes('\\n')) {\n // Handle multiline text\n element.textContent = textContent;\n\n if (opts.applyStyles) {\n // Apply multiline styles (these take precedence over custom styles)\n element.style.whiteSpace = 'pre-wrap';\n element.style.wordBreak = 'break-word';\n }\n } else {\n // Handle single-line text\n if (opts.applyStyles) {\n // Reset multiline styles for single-line text\n element.style.whiteSpace = '';\n element.style.wordBreak = '';\n }\n\n // Render based on HTML support\n if (opts.supportHtml) {\n $.h(element, textContent);\n } else {\n $.t(element, textContent);\n }\n }\n\n // Apply custom styles (after multiline styles to allow overrides where appropriate)\n if (opts.customStyles && typeof opts.customStyles === 'object') {\n for (const [property, value] of Object.entries(opts.customStyles)) {\n try {\n // Don't override critical multiline styles if text is multiline\n if (textContent.includes('\\n') && opts.applyStyles) {\n if (property === 'whiteSpace' || property === 'white-space') {\n console.warn(\n 'renderTextToElement: Ignoring whiteSpace override for multiline text'\n );\n continue;\n }\n if (property === 'wordBreak' || property === 'word-break') {\n console.warn(\n 'renderTextToElement: Ignoring wordBreak override for multiline text'\n );\n continue;\n }\n }\n element.style[property] = String(value);\n } catch (error) {\n console.warn(`renderTextToElement: Failed to set style ${property}:`, error);\n }\n }\n }\n\n return element;\n}\n\n/**\n * Static utility function to create a new DOM element with rendered text content.\n *\n * This function creates a new DOM element and renders text content into it using the same\n * logic as renderTextToElement. It's useful when you need a new element rather than\n * modifying an existing one.\n *\n * @param {string} text - Text content to render (supports \\n for line breaks)\n * @param {Partial<TextRenderOptions>} [options={}] - Rendering options\n * @param {string} [options.tagName='span'] - HTML tag name for the created element\n * @param {boolean} [options.applyStyles=true] - Whether to apply multiline CSS styles\n * @param {string[]} [options.customClasses=[]] - Array of CSS class names to add\n * @param {Object} [options.customAttributes={}] - Object of HTML attributes to set\n * @param {Object} [options.customStyles={}] - Object of inline styles to apply\n * @param {boolean} [options.supportHtml=false] - Whether to support HTML content in single-line text\n * @returns {HTMLElement} New DOM element with rendered text content\n *\n * @example\n * // Create a div with multiline text\n * const textDiv = createTextElement('Line 1\\nLine 2', {\n * tagName: 'div',\n * customClasses: ['multiline-text']\n * });\n *\n * @example\n * // Create a span with custom styling\n * const styledSpan = createTextElement('Styled text', {\n * customStyles: {\n * backgroundColor: '#f0f0f0',\n * padding: '4px',\n * borderRadius: '4px'\n * }\n * });\n */\nexport function createTextElement(text, options = {}) {\n // Merge options with defaults\n const opts = {};\n jsMind.util.json.merge(opts, DEFAULT_RENDER_OPTIONS);\n jsMind.util.json.merge(opts, options);\n\n // Create new element\n const element = $.c(opts.tagName || 'span');\n\n // Use renderTextToElement to handle the rendering\n return renderTextToElement(element, text, { ...opts, clearElement: false });\n}\n\n/**\n * Multiline text plugin for jsMind.\n */\nexport class MultilineText {\n /**\n * Create multiline text plugin instance.\n * @param {import('../jsmind.js').default} jm - jsMind instance\n * @param {Partial<MultilineTextOptions>} 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.1.0';\n /** @type {import('../jsmind.js').default} */\n this.jm = jm;\n /** @type {MultilineTextOptions} */\n this.options = opts;\n\n // Store original methods for restoration if needed\n this.original_methods = {};\n\n // Current editing state\n this.editing_node = null;\n this.multiline_editor = null;\n }\n\n /** Initialize the multiline text plugin. */\n init() {\n this.override_view_methods();\n this.setup_event_listeners();\n this.initialized = true;\n console.log('Multiline text plugin initialized - ready for first render');\n }\n\n /**\n * Override ViewProvider methods to support multiline text.\n */\n override_view_methods() {\n const view = this.jm.view;\n\n // Store original methods for fallback\n this.original_methods.edit_node_begin = view.edit_node_begin.bind(view);\n this.original_methods.edit_node_end = view.edit_node_end.bind(view);\n this.original_methods.render_node = view.render_node.bind(view);\n this.original_methods.show = view.show.bind(view);\n\n // Store original custom render methods if they exist\n this.original_methods._custom_node_render = view._custom_node_render\n ? view._custom_node_render.bind(view)\n : null;\n this.original_methods._default_node_render = view._default_node_render\n ? view._default_node_render.bind(view)\n : null;\n\n // Override methods with error handling\n try {\n view.edit_node_begin = this.edit_node_begin.bind(this);\n view.edit_node_end = this.edit_node_end.bind(this);\n view.render_node = this._render_multiline_node_wrapper.bind(this);\n view.show = this._show_wrapper.bind(this);\n console.log('Multiline text plugin: Successfully overrode view methods');\n } catch (error) {\n console.error('Multiline text plugin: Failed to override methods', error);\n // Restore original methods if override fails\n this.restore_original_methods();\n }\n }\n\n /**\n * Restore original methods if override fails.\n */\n restore_original_methods() {\n const view = this.jm.view;\n const methods = [\n 'edit_node_begin',\n 'edit_node_end',\n 'render_node',\n 'show',\n '_custom_node_render',\n '_default_node_render',\n ];\n\n methods.forEach(method => {\n if (this.original_methods[method]) {\n view[method] = this.original_methods[method];\n }\n });\n }\n\n /**\n * Set up event listeners for the plugin.\n */\n setup_event_listeners() {\n this.jm.add_event_listener((type, data) => {\n this.jm_event_handle(type, data);\n });\n }\n\n /**\n * Wrapper for render_node method with error handling.\n * @param {HTMLElement} element - Node element\n * @param {import('../jsmind.node.js').Node} node - Node data\n */\n _render_multiline_node_wrapper(element, node) {\n try {\n this._render_multiline_node(element, node);\n } catch (error) {\n console.error('Multiline text plugin: Error in render_node', error);\n // Fall back to original method\n if (this.original_methods.render_node) {\n this.original_methods.render_node(element, node);\n }\n }\n }\n\n /**\n * Wrapper for show method to prevent unwanted view resets.\n * @param {boolean} keep_center - Whether to center on root node\n */\n _show_wrapper(keep_center) {\n try {\n // Always call show without centering to prevent view jumps\n this.original_methods.show(false);\n } catch (error) {\n console.error('Multiline text plugin: Error in show', error);\n // Fall back to original method\n if (this.original_methods.show) {\n this.original_methods.show(keep_center);\n }\n }\n }\n\n /**\n * Render multiline text in node display with custom_node_render support.\n * @param {HTMLElement} element - Node element\n * @param {import('../jsmind.node.js').Node} node - Node data\n */\n _render_multiline_node(element, node) {\n if (!node.topic) {\n return;\n }\n\n const hasMultilineText = node.topic.includes('\\n');\n const originalHeight = hasMultilineText ? element.clientHeight : 0;\n\n // Check if we have custom node render function\n const hasCustomRender =\n this.jm.view.opts.custom_node_render &&\n typeof this.jm.view.opts.custom_node_render === 'function';\n\n let customRendered = false;\n\n if (hasCustomRender) {\n try {\n customRendered = this.jm.view.opts.custom_node_render(this.jm, element, node);\n } catch (error) {\n console.error('Multiline text plugin: Error in custom_node_render', error);\n customRendered = false;\n }\n }\n\n // If custom render didn't handle it, use appropriate rendering strategy\n if (!customRendered) {\n if (hasMultilineText) {\n renderTextToElement(element, node.topic, {\n clearElement: true,\n applyStyles: true,\n supportHtml: this.jm.view.opts.support_html || false,\n });\n } else {\n if (this.original_methods.render_node) {\n this.original_methods.render_node(element, node);\n return;\n } else {\n renderTextToElement(element, node.topic, {\n clearElement: true,\n applyStyles: false,\n supportHtml: this.jm.view.opts.support_html || false,\n });\n }\n }\n }\n\n // Recalculate layout only if multiline text height changed\n if (hasMultilineText && originalHeight > 0) {\n const newHeight = element.clientHeight;\n if (originalHeight !== newHeight) {\n setTimeout(() => {\n this.recalculate_layout(node);\n }, 0);\n }\n }\n }\n\n /**\n * Plugin instance method to render text content into an existing DOM element.\n *\n * This method automatically uses jsMind configuration settings (like support_html)\n * and provides a convenient way to render multiline text within custom node renderers.\n *\n * @param {HTMLElement} element - Target DOM element to render text into\n * @param {string} text - Text content to render (supports \\n for line breaks)\n * @param {Partial<TextRenderOptions>} [options={}] - Additional rendering options\n * @returns {HTMLElement} The element with rendered text content\n *\n * @example\n * // In a custom node render function\n * customNodeRender(jm, element, node) {\n * const wrapper = document.createElement('div');\n * wrapper.style.backgroundColor = '#f0f0f0';\n * wrapper.style.padding = '4px';\n *\n * const textElement = document.createElement('span');\n * jm.multiline_text.renderMultilineText(textElement, node.topic);\n *\n * wrapper.appendChild(textElement);\n * element.appendChild(wrapper);\n * return true;\n * }\n */\n renderMultilineText(element, text, options = {}) {\n // Prepare options with jsMind configuration\n const defaultOptions = {\n supportHtml: this.jm.view.opts.support_html || false,\n };\n\n // Merge with provided options\n const mergedOptions = {};\n jsMind.util.json.merge(mergedOptions, defaultOptions);\n jsMind.util.json.merge(mergedOptions, options);\n\n // Use static function with merged options\n return renderTextToElement(element, text, mergedOptions);\n }\n\n /**\n * Plugin instance method to create a new DOM element with rendered text content.\n *\n * This method automatically uses jsMind configuration settings and creates a new\n * element with properly rendered multiline text. Useful for building complex\n * custom node structures.\n *\n * @param {string} text - Text content to render (supports \\n for line breaks)\n * @param {Partial<TextRenderOptions>} [options={}] - Additional rendering options\n * @returns {HTMLElement} New DOM element with rendered text content\n *\n * @example\n * // Create a text element for insertion into custom structure\n * customNodeRender(jm, element, node) {\n * const container = document.createElement('div');\n * container.className = 'custom-node';\n *\n * // Add priority indicator\n * if (node.data?.priority) {\n * const priority = document.createElement('span');\n * priority.className = 'priority-badge';\n * priority.textContent = node.data.priority;\n * container.appendChild(priority);\n * }\n *\n * // Add multiline text content\n * const textElement = jm.multiline_text.createMultilineElement(node.topic, {\n * tagName: 'div',\n * customClasses: ['node-text']\n * });\n * container.appendChild(textElement);\n *\n * element.appendChild(container);\n * return true;\n * }\n */\n createMultilineElement(text, options = {}) {\n // Prepare options with jsMind configuration\n const defaultOptions = {\n supportHtml: this.jm.view.opts.support_html || false,\n };\n\n // Merge with provided options\n const mergedOptions = {};\n jsMind.util.json.merge(mergedOptions, defaultOptions);\n jsMind.util.json.merge(mergedOptions, options);\n\n // Use static function with merged options\n return createTextElement(text, mergedOptions);\n }\n\n /**\n * Plugin instance method to render text content into an existing DOM element.\n *\n * This method automatically uses jsMind configuration settings (like support_html)\n * and provides a convenient way to render multiline text within custom node renderers.\n *\n * @param {HTMLElement} element - Target DOM element to render text into\n * @param {string} text - Text content to render (supports \\n for line breaks)\n * @param {Partial<TextRenderOptions>} [options={}] - Additional rendering options\n * @returns {HTMLElement} The element with rendered text content\n *\n * @example\n * // In a custom node render function\n * customNodeRender(jm, element, node) {\n * const wrapper = document.createElement('div');\n * wrapper.style.backgroundColor = '#f0f0f0';\n * wrapper.style.padding = '4px';\n *\n * const textElement = document.createElement('span');\n * jm.multiline_text.renderMultilineText(textElement, node.topic);\n *\n * wrapper.appendChild(textElement);\n * element.appendChild(wrapper);\n * return true;\n * }\n */\n renderMultilineText(element, text, options = {}) {\n // Prepare options with jsMind configuration\n const defaultOptions = {\n supportHtml: this.jm.view.opts.support_html || false,\n };\n\n // Merge with provided options\n const mergedOptions = {};\n jsMind.util.json.merge(mergedOptions, defaultOptions);\n jsMind.util.json.merge(mergedOptions, options);\n\n // Use static function with merged options\n return renderTextToElement(element, text, mergedOptions);\n }\n\n /**\n * Plugin instance method to create a new DOM element with rendered text content.\n *\n * This method automatically uses jsMind configuration settings and creates a new\n * element with properly rendered multiline text. Useful for building complex\n * custom node structures.\n *\n * @param {string} text - Text content to render (supports \\n for line breaks)\n * @param {Partial<TextRenderOptions>} [options={}] - Additional rendering options\n * @returns {HTMLElement} New DOM element with rendered text content\n *\n * @example\n * // Create a text element for insertion into custom structure\n * customNodeRender(jm, element, node) {\n * const container = document.createElement('div');\n * container.className = 'custom-node';\n *\n * // Add priority indicator\n * if (node.data?.priority) {\n * const priority = document.createElement('span');\n * priority.className = 'priority-badge';\n * priority.textContent = node.data.priority;\n * container.appendChild(priority);\n * }\n *\n * // Add multiline text content\n * const textElement = jm.multiline_text.createMultilineElement(node.topic, {\n * tagName: 'div',\n * customClasses: ['node-text']\n * });\n * container.appendChild(textElement);\n *\n * element.appendChild(container);\n * return true;\n * }\n */\n createMultilineElement(text, options = {}) {\n // Prepare options with jsMind configuration\n const defaultOptions = {\n supportHtml: this.jm.view.opts.support_html || false,\n };\n\n // Merge with provided options\n const mergedOptions = {};\n jsMind.util.json.merge(mergedOptions, defaultOptions);\n jsMind.util.json.merge(mergedOptions, options);\n\n // Use static function with merged options\n return createTextElement(text, mergedOptions);\n }\n\n /**\n * Begin editing a node with multiline support.\n * @param {import('../jsmind.node.js').Node} node - Node to edit\n */\n edit_node_begin(node) {\n if (!node.topic) {\n console.warn(\"don't edit image nodes\");\n return;\n }\n\n if (this.editing_node != null) {\n this.edit_node_end();\n }\n\n this.editing_node = node;\n this.jm.view.editing_node = node;\n\n this.create_multiline_editor(node._data.view.element, node.topic);\n }\n\n /**\n * Create contentEditable multiline editor.\n * @param {HTMLElement} element - Node element\n * @param {string} topic - Current text content\n */\n create_multiline_editor(element, topic) {\n // Create contentEditable div\n this.multiline_editor = $.c('div');\n this.multiline_editor.contentEditable = 'plaintext-only';\n this.multiline_editor.className = 'jsmind-multiline-editor';\n\n // Set initial content\n this.multiline_editor.textContent = topic;\n\n // Style the editor\n this.style_multiline_editor(element);\n\n // Add keyboard event handling\n this.setup_editor_events();\n\n // Replace element content with editor\n element.innerHTML = '';\n element.appendChild(this.multiline_editor);\n element.style.zIndex = 5;\n\n // Focus and select content\n this.multiline_editor.focus();\n this.select_all_text();\n }\n\n /**\n * Style the multiline editor.\n * @param {HTMLElement} element - Original node element\n */\n style_multiline_editor(element) {\n const ncs = getComputedStyle(element);\n const editor = this.multiline_editor;\n\n // Copy styles from original element\n editor.style.width =\n Math.max(\n element.clientWidth -\n parseInt(ncs.getPropertyValue('padding-left')) -\n parseInt(ncs.getPropertyValue('padding-right')),\n this.options.text_width\n ) + 'px';\n\n editor.style.minHeight = this.options.min_height + 'px';\n editor.style.lineHeight = this.options.line_height;\n editor.style.border =\n this.options.editor_border_width + ' solid ' + this.options.editor_border_color;\n editor.style.borderRadius = '4px';\n editor.style.padding = '4px';\n editor.style.outline = 'none';\n editor.style.resize = 'none';\n editor.style.overflow = 'hidden';\n editor.style.whiteSpace = 'pre-wrap';\n editor.style.wordBreak = 'break-word';\n }\n\n /**\n * Set up keyboard event handling for the editor.\n */\n setup_editor_events() {\n const editor = this.multiline_editor;\n\n $.on(editor, 'keydown', e => {\n this.handle_editor_keydown(e);\n });\n\n $.on(editor, 'blur', () => {\n // Delay to allow other events to process first\n setTimeout(() => {\n if (this.editing_node) {\n this.edit_node_end();\n }\n }, 100);\n });\n\n // Auto-resize editor as user types\n $.on(editor, 'input', () => {\n this.auto_resize_editor();\n });\n }\n\n /**\n * Handle keyboard events in the editor.\n * @param {KeyboardEvent} e - Keyboard event\n */\n handle_editor_keydown(e) {\n const key = e.key;\n const shiftKey = e.shiftKey;\n\n if (key === 'Enter') {\n if (shiftKey) {\n // Shift+Enter: Allow line break (default behavior)\n return;\n } else {\n // Enter: Save and exit\n e.preventDefault();\n this.edit_node_end();\n }\n } else if (key === 'Escape') {\n // Escape: Cancel editing\n e.preventDefault();\n this.cancel_editing();\n } else if (key === 'Tab') {\n // Tab: Save and exit (like Enter)\n e.preventDefault();\n this.edit_node_end();\n }\n }\n\n /**\n * Auto-resize editor based on content.\n */\n auto_resize_editor() {\n if (!this.options.auto_resize || !this.multiline_editor) {\n return;\n }\n\n const editor = this.multiline_editor;\n\n // Reset height to auto to get natural height\n editor.style.height = 'auto';\n\n // Set height to scroll height to fit content\n const scrollHeight = editor.scrollHeight;\n const minHeight = this.options.min_height;\n\n editor.style.height = Math.max(scrollHeight, minHeight) + 'px';\n }\n\n /**\n * Select all text in the editor.\n */\n select_all_text() {\n if (!this.multiline_editor) return;\n\n const range = $.d.createRange();\n range.selectNodeContents(this.multiline_editor);\n\n const selection = $.w.getSelection();\n selection.removeAllRanges();\n selection.addRange(range);\n }\n\n /**\n * Reset editing state and return focus to panel.\n */\n _reset_editing_state() {\n this.editing_node = null;\n this.jm.view.editing_node = null;\n this.multiline_editor = null;\n this.jm.view.e_panel.focus();\n }\n\n /**\n * End editing and save changes.\n */\n edit_node_end() {\n if (this.editing_node == null || !this.multiline_editor) {\n return;\n }\n\n const node = this.editing_node;\n const element = node._data.view.element;\n const topic = this.multiline_editor.textContent || '';\n\n this.cleanup_editor(element);\n\n const processed_topic = this.process_multiline_text(topic);\n\n if (jsMind.util.text.is_empty(processed_topic) || node.topic === processed_topic) {\n this._render_multiline_node(element, node);\n } else {\n this.jm.update_node(node.id, processed_topic);\n }\n\n this.recalculate_layout(node);\n this._reset_editing_state();\n }\n\n /**\n * Cancel editing without saving changes.\n */\n cancel_editing() {\n if (this.editing_node == null || !this.multiline_editor) {\n return;\n }\n\n const node = this.editing_node;\n const element = node._data.view.element;\n\n this.cleanup_editor(element);\n this._render_multiline_node(element, node);\n this._reset_editing_state();\n }\n\n /**\n * Clean up editor and restore element state.\n * @param {HTMLElement} element - Node element\n */\n cleanup_editor(element) {\n if (this.multiline_editor && this.multiline_editor.parentNode) {\n this.multiline_editor.parentNode.removeChild(this.multiline_editor);\n }\n element.style.zIndex = 'auto';\n }\n\n /**\n * Process and validate multiline text.\n * @param {string} text - Raw text from editor\n * @returns {string} Processed text\n */\n process_multiline_text(text) {\n if (!text) return '';\n\n // Trim whitespace but preserve internal line breaks\n text = text.trim();\n\n // Normalize line breaks to \\n\n text = text.replace(/\\r\\n/g, '\\n').replace(/\\r/g, '\\n');\n\n // Remove excessive consecutive line breaks (more than 2)\n text = text.replace(/\\n{3,}/g, '\\n\\n');\n\n return text;\n }\n\n /**\n * Re-render only nodes that contain multiline text for better performance.\n */\n rerender_multiline_nodes_only() {\n if (!this.jm.mind || !this.jm.mind.nodes) {\n return;\n }\n\n let rerendered_count = 0;\n const nodes = this.jm.mind.nodes;\n\n for (const node_id in nodes) {\n const node = nodes[node_id];\n if (node.topic && node.topic.includes('\\n')) {\n const view_data = node._data.view;\n if (view_data && view_data.element) {\n this._render_multiline_node(view_data.element, node);\n rerendered_count++;\n }\n }\n }\n\n console.log(`Multiline text plugin: Re-rendered ${rerendered_count} multiline nodes`);\n }\n\n /**\n * @deprecated Use rerender_multiline_nodes_only() for better performance\n */\n rerender_existing_nodes() {\n this.rerender_multiline_nodes_only();\n }\n\n /**\n * Recalculate layout after text changes.\n * @param {import('../jsmind.node.js').Node} node - Updated node\n */\n recalculate_layout(node) {\n // Clear layout cache to force recalculation\n this.jm.layout.cache_valid = false;\n\n // Clear any cached offset and point data for all nodes\n const nodes = this.jm.mind.nodes;\n for (let nodeid in nodes) {\n const n = nodes[nodeid];\n if (n._data.layout) {\n delete n._data.layout._offset_;\n delete n._data.layout._pout_;\n }\n }\n\n // Update node size first\n this.jm.view.update_node(node);\n\n // Trigger complete layout recalculation\n this.jm.layout.layout();\n\n // Redraw view with updated layout and lines\n this.jm.view.show();\n }\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 // Handle resize events if needed\n }\n void data; // Suppress unused parameter warning\n }\n}\n\n/**\n * Multiline text plugin registration.\n * @type {import('../jsmind.plugin.js').Plugin<Partial<MultilineTextOptions>>}\n */\nexport const multiline_text_plugin = new jsMind.plugin('multiline_text', function (jm, options) {\n var mt = new MultilineText(jm, options);\n mt.init();\n jm.multiline_text = mt;\n});\n\njsMind.register_plugin(multiline_text_plugin);\n\nexport default MultilineText;\n"],"names":["jsMind","Error","$","DEFAULT_OPTIONS","text_width","editor_border_color","editor_border_width","save_shortcut","cancel_shortcut","newline_shortcut","auto_resize","min_height","line_height","DEFAULT_RENDER_OPTIONS","tagName","clearElement","applyStyles","customClasses","customAttributes","customStyles","supportHtml","preserveWhitespace","renderTextToElement","element","text","options","HTMLElement","console","warn","opts","util","json","merge","innerHTML","textContent","String","key","value","Object","entries","setAttribute","error","Array","isArray","className","trim","classList","add","includes","style","whiteSpace","wordBreak","h","t","property","createTextElement","c","MultilineText","constructor","jm","this","version","original_methods","editing_node","multiline_editor","init","override_view_methods","setup_event_listeners","initialized","log","view","edit_node_begin","bind","edit_node_end","render_node","show","_custom_node_render","_default_node_render","_render_multiline_node_wrapper","_show_wrapper","restore_original_methods","forEach","method","add_event_listener","type","data","jm_event_handle","node","_render_multiline_node","keep_center","topic","hasMultilineText","originalHeight","clientHeight","customRendered","custom_node_render","support_html","setTimeout","recalculate_layout","renderMultilineText","defaultOptions","mergedOptions","createMultilineElement","create_multiline_editor","_data","contentEditable","style_multiline_editor","setup_editor_events","appendChild","zIndex","focus","select_all_text","ncs","getComputedStyle","editor","width","Math","max","clientWidth","parseInt","getPropertyValue","minHeight","lineHeight","border","borderRadius","padding","outline","resize","overflow","on","e","handle_editor_keydown","auto_resize_editor","shiftKey","preventDefault","cancel_editing","height","scrollHeight","range","d","createRange","selectNodeContents","selection","w","getSelection","removeAllRanges","addRange","_reset_editing_state","e_panel","cleanup_editor","processed_topic","process_multiline_text","is_empty","update_node","id","parentNode","removeChild","replace","rerender_multiline_nodes_only","mind","nodes","rerendered_count","node_id","view_data","rerender_existing_nodes","layout","cache_valid","nodeid","n","_offset_","_pout_","event_type","multiline_text_plugin","plugin","mt","multiline_text","register_plugin"],"mappings":";;;;;;;qYAUA,IAAKA,UACD,MAAM,IAAIC,MAAM,yBAGpB,MAAMC,EAAIF,EAAM,QAACE,EAeXC,EAAkB,CACpBC,WAAY,IACZC,oBAAqB,UACrBC,oBAAqB,MACrBC,cAAe,QACfC,gBAAiB,SACjBC,iBAAkB,cAClBC,aAAa,EACbC,WAAY,GACZC,YAAa,KAeXC,EAAyB,CAC3BC,QAAS,OACTC,cAAc,EACdC,aAAa,EACbC,cAAe,GACfC,iBAAkB,CAAE,EACpBC,aAAc,CAAE,EAChBC,aAAa,EACbC,oBAAoB,GA2CjB,SAASC,EAAoBC,EAASC,EAAMC,EAAU,CAAA,GAEzD,KAAKF,GAAaA,aAAmBG,aACjC,MAAM,IAAIzB,MAAM,4DAGpB,GAAY,MAARuB,EAEA,OADAG,QAAQC,KAAK,mEACNL,EAIX,MAAMM,EAAO,CAAA,EACb7B,EAAM,QAAC8B,KAAKC,KAAKC,MAAMH,EAAMhB,GAC7Bb,EAAM,QAAC8B,KAAKC,KAAKC,MAAMH,EAAMJ,GAGzBI,EAAKd,eACLQ,EAAQU,UAAY,IAIxB,MAAMC,EAAcC,OAAOX,GAG3B,GAAIK,EAAKX,kBAAqD,iBAA1BW,EAAKX,iBACrC,IAAK,MAAOkB,EAAKC,KAAUC,OAAOC,QAAQV,EAAKX,kBAC3C,IACIK,EAAQiB,aAAaJ,EAAKD,OAAOE,GACpC,CAAC,MAAOI,GACLd,QAAQC,KAAK,gDAAgDQ,KAAQK,EACxE,CAKT,GAAIZ,EAAKZ,eAAiByB,MAAMC,QAAQd,EAAKZ,eACzC,IAAK,MAAM2B,KAAaf,EAAKZ,cACA,iBAAd2B,GAA0BA,EAAUC,QAC3CtB,EAAQuB,UAAUC,IAAIH,EAAUC,QAgC5C,GA1BIX,EAAYc,SAAS,OAErBzB,EAAQW,YAAcA,EAElBL,EAAKb,cAELO,EAAQ0B,MAAMC,WAAa,WAC3B3B,EAAQ0B,MAAME,UAAY,gBAI1BtB,EAAKb,cAELO,EAAQ0B,MAAMC,WAAa,GAC3B3B,EAAQ0B,MAAME,UAAY,IAI1BtB,EAAKT,YACLlB,EAAEkD,EAAE7B,EAASW,GAEbhC,EAAEmD,EAAE9B,EAASW,IAKjBL,EAAKV,cAA6C,iBAAtBU,EAAKV,aACjC,IAAK,MAAOmC,EAAUjB,KAAUC,OAAOC,QAAQV,EAAKV,cAChD,IAEI,GAAIe,EAAYc,SAAS,OAASnB,EAAKb,YAAa,CAChD,GAAiB,eAAbsC,GAA0C,gBAAbA,EAA4B,CACzD3B,QAAQC,KACJ,wEAEJ,QACH,CACD,GAAiB,cAAb0B,GAAyC,eAAbA,EAA2B,CACvD3B,QAAQC,KACJ,uEAEJ,QACH,CACJ,CACDL,EAAQ0B,MAAMK,GAAYnB,OAAOE,EACpC,CAAC,MAAOI,GACLd,QAAQC,KAAK,4CAA4C0B,KAAab,EACzE,CAIT,OAAOlB,CACX,CAoCO,SAASgC,EAAkB/B,EAAMC,EAAU,IAE9C,MAAMI,EAAO,CAAA,EACb7B,EAAM,QAAC8B,KAAKC,KAAKC,MAAMH,EAAMhB,GAC7Bb,EAAM,QAAC8B,KAAKC,KAAKC,MAAMH,EAAMJ,GAM7B,OAAOH,EAHSpB,EAAEsD,EAAE3B,EAAKf,SAAW,QAGAU,EAAM,IAAKK,EAAMd,cAAc,GACvE,CAKO,MAAM0C,EAMT,WAAAC,CAAYC,EAAIlC,GACZ,IAAII,EAAO,CAAA,EACX7B,EAAM,QAAC8B,KAAKC,KAAKC,MAAMH,EAAM1B,GAC7BH,EAAM,QAAC8B,KAAKC,KAAKC,MAAMH,EAAMJ,GAE7BmC,KAAKC,QAAU,QAEfD,KAAKD,GAAKA,EAEVC,KAAKnC,QAAUI,EAGf+B,KAAKE,iBAAmB,GAGxBF,KAAKG,aAAe,KACpBH,KAAKI,iBAAmB,IAC3B,CAGD,IAAAC,GACIL,KAAKM,wBACLN,KAAKO,wBACLP,KAAKQ,aAAc,EACnBzC,QAAQ0C,IAAI,6DACf,CAKD,qBAAAH,GACI,MAAMI,EAAOV,KAAKD,GAAGW,KAGrBV,KAAKE,iBAAiBS,gBAAkBD,EAAKC,gBAAgBC,KAAKF,GAClEV,KAAKE,iBAAiBW,cAAgBH,EAAKG,cAAcD,KAAKF,GAC9DV,KAAKE,iBAAiBY,YAAcJ,EAAKI,YAAYF,KAAKF,GAC1DV,KAAKE,iBAAiBa,KAAOL,EAAKK,KAAKH,KAAKF,GAG5CV,KAAKE,iBAAiBc,oBAAsBN,EAAKM,oBAC3CN,EAAKM,oBAAoBJ,KAAKF,GAC9B,KACNV,KAAKE,iBAAiBe,qBAAuBP,EAAKO,qBAC5CP,EAAKO,qBAAqBL,KAAKF,GAC/B,KAGN,IACIA,EAAKC,gBAAkBX,KAAKW,gBAAgBC,KAAKZ,MACjDU,EAAKG,cAAgBb,KAAKa,cAAcD,KAAKZ,MAC7CU,EAAKI,YAAcd,KAAKkB,+BAA+BN,KAAKZ,MAC5DU,EAAKK,KAAOf,KAAKmB,cAAcP,KAAKZ,MACpCjC,QAAQ0C,IAAI,4DACf,CAAC,MAAO5B,GACLd,QAAQc,MAAM,oDAAqDA,GAEnEmB,KAAKoB,0BACR,CACJ,CAKD,wBAAAA,GACI,MAAMV,EAAOV,KAAKD,GAAGW,KACL,CACZ,kBACA,gBACA,cACA,OACA,sBACA,wBAGIW,QAAQC,IACRtB,KAAKE,iBAAiBoB,KACtBZ,EAAKY,GAAUtB,KAAKE,iBAAiBoB,KAGhD,CAKD,qBAAAf,GACIP,KAAKD,GAAGwB,mBAAmB,CAACC,EAAMC,KAC9BzB,KAAK0B,gBAAgBF,EAAMC,IAElC,CAOD,8BAAAP,CAA+BvD,EAASgE,GACpC,IACI3B,KAAK4B,uBAAuBjE,EAASgE,EACxC,CAAC,MAAO9C,GACLd,QAAQc,MAAM,8CAA+CA,GAEzDmB,KAAKE,iBAAiBY,aACtBd,KAAKE,iBAAiBY,YAAYnD,EAASgE,EAElD,CACJ,CAMD,aAAAR,CAAcU,GACV,IAEI7B,KAAKE,iBAAiBa,MAAK,EAC9B,CAAC,MAAOlC,GACLd,QAAQc,MAAM,uCAAwCA,GAElDmB,KAAKE,iBAAiBa,MACtBf,KAAKE,iBAAiBa,KAAKc,EAElC,CACJ,CAOD,sBAAAD,CAAuBjE,EAASgE,GAC5B,IAAKA,EAAKG,MACN,OAGJ,MAAMC,EAAmBJ,EAAKG,MAAM1C,SAAS,MACvC4C,EAAiBD,EAAmBpE,EAAQsE,aAAe,EAOjE,IAAIC,GAAiB,EAErB,GALIlC,KAAKD,GAAGW,KAAKzC,KAAKkE,oBAC8B,mBAAzCnC,KAAKD,GAAGW,KAAKzC,KAAKkE,mBAKzB,IACID,EAAiBlC,KAAKD,GAAGW,KAAKzC,KAAKkE,mBAAmBnC,KAAKD,GAAIpC,EAASgE,EAC3E,CAAC,MAAO9C,GACLd,QAAQc,MAAM,qDAAsDA,GACpEqD,GAAiB,CACpB,CAIL,IAAKA,EACD,GAAIH,EACArE,EAAoBC,EAASgE,EAAKG,MAAO,CACrC3E,cAAc,EACdC,aAAa,EACbI,YAAawC,KAAKD,GAAGW,KAAKzC,KAAKmE,eAAgB,QAEhD,CACH,GAAIpC,KAAKE,iBAAiBY,YAEtB,YADAd,KAAKE,iBAAiBY,YAAYnD,EAASgE,GAG3CjE,EAAoBC,EAASgE,EAAKG,MAAO,CACrC3E,cAAc,EACdC,aAAa,EACbI,YAAawC,KAAKD,GAAGW,KAAKzC,KAAKmE,eAAgB,GAG1D,CAIL,GAAIL,GAAoBC,EAAiB,EAAG,CAEpCA,IADcrE,EAAQsE,cAEtBI,WAAW,KACPrC,KAAKsC,mBAAmBX,IACzB,EAEV,CACJ,CA4BD,mBAAAY,CAAoB5E,EAASC,EAAMC,EAAU,CAAA,GAEzC,MAAM2E,EAAiB,CACnBhF,YAAawC,KAAKD,GAAGW,KAAKzC,KAAKmE,eAAgB,GAI7CK,EAAgB,CAAA,EAKtB,OAJArG,EAAM,QAAC8B,KAAKC,KAAKC,MAAMqE,EAAeD,GACtCpG,EAAM,QAAC8B,KAAKC,KAAKC,MAAMqE,EAAe5E,GAG/BH,EAAoBC,EAASC,EAAM6E,EAC7C,CAsCD,sBAAAC,CAAuB9E,EAAMC,EAAU,IAEnC,MAAM2E,EAAiB,CACnBhF,YAAawC,KAAKD,GAAGW,KAAKzC,KAAKmE,eAAgB,GAI7CK,EAAgB,CAAA,EAKtB,OAJArG,EAAM,QAAC8B,KAAKC,KAAKC,MAAMqE,EAAeD,GACtCpG,EAAM,QAAC8B,KAAKC,KAAKC,MAAMqE,EAAe5E,GAG/B8B,EAAkB/B,EAAM6E,EAClC,CA4BD,mBAAAF,CAAoB5E,EAASC,EAAMC,EAAU,CAAA,GAEzC,MAAM2E,EAAiB,CACnBhF,YAAawC,KAAKD,GAAGW,KAAKzC,KAAKmE,eAAgB,GAI7CK,EAAgB,CAAA,EAKtB,OAJArG,EAAM,QAAC8B,KAAKC,KAAKC,MAAMqE,EAAeD,GACtCpG,EAAM,QAAC8B,KAAKC,KAAKC,MAAMqE,EAAe5E,GAG/BH,EAAoBC,EAASC,EAAM6E,EAC7C,CAsCD,sBAAAC,CAAuB9E,EAAMC,EAAU,IAEnC,MAAM2E,EAAiB,CACnBhF,YAAawC,KAAKD,GAAGW,KAAKzC,KAAKmE,eAAgB,GAI7CK,EAAgB,CAAA,EAKtB,OAJArG,EAAM,QAAC8B,KAAKC,KAAKC,MAAMqE,EAAeD,GACtCpG,EAAM,QAAC8B,KAAKC,KAAKC,MAAMqE,EAAe5E,GAG/B8B,EAAkB/B,EAAM6E,EAClC,CAMD,eAAA9B,CAAgBgB,GACPA,EAAKG,OAKe,MAArB9B,KAAKG,cACLH,KAAKa,gBAGTb,KAAKG,aAAewB,EACpB3B,KAAKD,GAAGW,KAAKP,aAAewB,EAE5B3B,KAAK2C,wBAAwBhB,EAAKiB,MAAMlC,KAAK/C,QAASgE,EAAKG,QAXvD/D,QAAQC,KAAK,yBAYpB,CAOD,uBAAA2E,CAAwBhF,EAASmE,GAE7B9B,KAAKI,iBAAmB9D,EAAEsD,EAAE,OAC5BI,KAAKI,iBAAiByC,gBAAkB,iBACxC7C,KAAKI,iBAAiBpB,UAAY,0BAGlCgB,KAAKI,iBAAiB9B,YAAcwD,EAGpC9B,KAAK8C,uBAAuBnF,GAG5BqC,KAAK+C,sBAGLpF,EAAQU,UAAY,GACpBV,EAAQqF,YAAYhD,KAAKI,kBACzBzC,EAAQ0B,MAAM4D,OAAS,EAGvBjD,KAAKI,iBAAiB8C,QACtBlD,KAAKmD,iBACR,CAMD,sBAAAL,CAAuBnF,GACnB,MAAMyF,EAAMC,iBAAiB1F,GACvB2F,EAAStD,KAAKI,iBAGpBkD,EAAOjE,MAAMkE,MACTC,KAAKC,IACD9F,EAAQ+F,YACJC,SAASP,EAAIQ,iBAAiB,iBAC9BD,SAASP,EAAIQ,iBAAiB,kBAClC5D,KAAKnC,QAAQrB,YACb,KAER8G,EAAOjE,MAAMwE,UAAY7D,KAAKnC,QAAQd,WAAa,KACnDuG,EAAOjE,MAAMyE,WAAa9D,KAAKnC,QAAQb,YACvCsG,EAAOjE,MAAM0E,OACT/D,KAAKnC,QAAQnB,oBAAsB,UAAYsD,KAAKnC,QAAQpB,oBAChE6G,EAAOjE,MAAM2E,aAAe,MAC5BV,EAAOjE,MAAM4E,QAAU,MACvBX,EAAOjE,MAAM6E,QAAU,OACvBZ,EAAOjE,MAAM8E,OAAS,OACtBb,EAAOjE,MAAM+E,SAAW,SACxBd,EAAOjE,MAAMC,WAAa,WAC1BgE,EAAOjE,MAAME,UAAY,YAC5B,CAKD,mBAAAwD,GACI,MAAMO,EAAStD,KAAKI,iBAEpB9D,EAAE+H,GAAGf,EAAQ,UAAWgB,IACpBtE,KAAKuE,sBAAsBD,KAG/BhI,EAAE+H,GAAGf,EAAQ,OAAQ,KAEjBjB,WAAW,KACHrC,KAAKG,cACLH,KAAKa,iBAEV,OAIPvE,EAAE+H,GAAGf,EAAQ,QAAS,KAClBtD,KAAKwE,sBAEZ,CAMD,qBAAAD,CAAsBD,GAClB,MAAM9F,EAAM8F,EAAE9F,IACRiG,EAAWH,EAAEG,SAEnB,GAAY,UAARjG,EAAiB,CACjB,GAAIiG,EAEA,OAGAH,EAAEI,iBACF1E,KAAKa,eAErB,KAA2B,WAARrC,GAEP8F,EAAEI,iBACF1E,KAAK2E,kBACU,QAARnG,IAEP8F,EAAEI,iBACF1E,KAAKa,gBAEZ,CAKD,kBAAA2D,GACI,IAAKxE,KAAKnC,QAAQf,cAAgBkD,KAAKI,iBACnC,OAGJ,MAAMkD,EAAStD,KAAKI,iBAGpBkD,EAAOjE,MAAMuF,OAAS,OAGtB,MAAMC,EAAevB,EAAOuB,aACtBhB,EAAY7D,KAAKnC,QAAQd,WAE/BuG,EAAOjE,MAAMuF,OAASpB,KAAKC,IAAIoB,EAAchB,GAAa,IAC7D,CAKD,eAAAV,GACI,IAAKnD,KAAKI,iBAAkB,OAE5B,MAAM0E,EAAQxI,EAAEyI,EAAEC,cAClBF,EAAMG,mBAAmBjF,KAAKI,kBAE9B,MAAM8E,EAAY5I,EAAE6I,EAAEC,eACtBF,EAAUG,kBACVH,EAAUI,SAASR,EACtB,CAKD,oBAAAS,GACIvF,KAAKG,aAAe,KACpBH,KAAKD,GAAGW,KAAKP,aAAe,KAC5BH,KAAKI,iBAAmB,KACxBJ,KAAKD,GAAGW,KAAK8E,QAAQtC,OACxB,CAKD,aAAArC,GACI,GAAyB,MAArBb,KAAKG,eAAyBH,KAAKI,iBACnC,OAGJ,MAAMuB,EAAO3B,KAAKG,aACZxC,EAAUgE,EAAKiB,MAAMlC,KAAK/C,QAC1BmE,EAAQ9B,KAAKI,iBAAiB9B,aAAe,GAEnD0B,KAAKyF,eAAe9H,GAEpB,MAAM+H,EAAkB1F,KAAK2F,uBAAuB7D,GAEhD1F,EAAM,QAAC8B,KAAKN,KAAKgI,SAASF,IAAoB/D,EAAKG,QAAU4D,EAC7D1F,KAAK4B,uBAAuBjE,EAASgE,GAErC3B,KAAKD,GAAG8F,YAAYlE,EAAKmE,GAAIJ,GAGjC1F,KAAKsC,mBAAmBX,GACxB3B,KAAKuF,sBACR,CAKD,cAAAZ,GACI,GAAyB,MAArB3E,KAAKG,eAAyBH,KAAKI,iBACnC,OAGJ,MAAMuB,EAAO3B,KAAKG,aACZxC,EAAUgE,EAAKiB,MAAMlC,KAAK/C,QAEhCqC,KAAKyF,eAAe9H,GACpBqC,KAAK4B,uBAAuBjE,EAASgE,GACrC3B,KAAKuF,sBACR,CAMD,cAAAE,CAAe9H,GACPqC,KAAKI,kBAAoBJ,KAAKI,iBAAiB2F,YAC/C/F,KAAKI,iBAAiB2F,WAAWC,YAAYhG,KAAKI,kBAEtDzC,EAAQ0B,MAAM4D,OAAS,MAC1B,CAOD,sBAAA0C,CAAuB/H,GACnB,OAAKA,EASLA,GAHAA,GAHAA,EAAOA,EAAKqB,QAGAgH,QAAQ,QAAS,MAAMA,QAAQ,MAAO,OAGtCA,QAAQ,UAAW,QATb,EAYrB,CAKD,6BAAAC,GACI,IAAKlG,KAAKD,GAAGoG,OAASnG,KAAKD,GAAGoG,KAAKC,MAC/B,OAGJ,IAAIC,EAAmB,EACvB,MAAMD,EAAQpG,KAAKD,GAAGoG,KAAKC,MAE3B,IAAK,MAAME,KAAWF,EAAO,CACzB,MAAMzE,EAAOyE,EAAME,GACnB,GAAI3E,EAAKG,OAASH,EAAKG,MAAM1C,SAAS,MAAO,CACzC,MAAMmH,EAAY5E,EAAKiB,MAAMlC,KACzB6F,GAAaA,EAAU5I,UACvBqC,KAAK4B,uBAAuB2E,EAAU5I,QAASgE,GAC/C0E,IAEP,CACJ,CAEDtI,QAAQ0C,IAAI,sCAAsC4F,oBACrD,CAKD,uBAAAG,GACIxG,KAAKkG,+BACR,CAMD,kBAAA5D,CAAmBX,GAEf3B,KAAKD,GAAG0G,OAAOC,aAAc,EAG7B,MAAMN,EAAQpG,KAAKD,GAAGoG,KAAKC,MAC3B,IAAK,IAAIO,KAAUP,EAAO,CACtB,MAAMQ,EAAIR,EAAMO,GACZC,EAAEhE,MAAM6D,gBACDG,EAAEhE,MAAM6D,OAAOI,gBACfD,EAAEhE,MAAM6D,OAAOK,OAE7B,CAGD9G,KAAKD,GAAGW,KAAKmF,YAAYlE,GAGzB3B,KAAKD,GAAG0G,OAAOA,SAGfzG,KAAKD,GAAGW,KAAKK,MAChB,CAOD,eAAAW,CAAgBF,EAAMC,GACLrF,EAAAA,QAAO2K,WAAW5C,MAIlC,EAOO,MAAC6C,EAAwB,IAAI5K,EAAAA,QAAO6K,OAAO,iBAAkB,SAAUlH,EAAIlC,GACnF,IAAIqJ,EAAK,IAAIrH,EAAcE,EAAIlC,GAC/BqJ,EAAG7G,OACHN,EAAGoH,eAAiBD,CACxB,GAEA9K,EAAAA,QAAOgL,gBAAgBJ"}
File without changes
File without changes