function _array_like_to_array(arr, len) {
    if (len == null || len > arr.length) len = arr.length;
    for(var i = 0, arr2 = new Array(len); i < len; i++)arr2[i] = arr[i];
    return arr2;
}
function _array_with_holes(arr) {
    if (Array.isArray(arr)) return arr;
}
function _array_without_holes(arr) {
    if (Array.isArray(arr)) return _array_like_to_array(arr);
}
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
    try {
        var info = gen[key](arg);
        var value = info.value;
    } catch (error) {
        reject(error);
        return;
    }
    if (info.done) {
        resolve(value);
    } else {
        Promise.resolve(value).then(_next, _throw);
    }
}
function _async_to_generator(fn) {
    return function() {
        var self = this, args = arguments;
        return new Promise(function(resolve, reject) {
            var gen = fn.apply(self, args);
            function _next(value) {
                asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value);
            }
            function _throw(err) {
                asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err);
            }
            _next(undefined);
        });
    };
}
function _class_call_check(instance, Constructor) {
    if (!(instance instanceof Constructor)) {
        throw new TypeError("Cannot call a class as a function");
    }
}
function _defineProperties(target, props) {
    for(var i = 0; i < props.length; i++){
        var descriptor = props[i];
        descriptor.enumerable = descriptor.enumerable || false;
        descriptor.configurable = true;
        if ("value" in descriptor) descriptor.writable = true;
        Object.defineProperty(target, descriptor.key, descriptor);
    }
}
function _create_class(Constructor, protoProps, staticProps) {
    if (protoProps) _defineProperties(Constructor.prototype, protoProps);
    if (staticProps) _defineProperties(Constructor, staticProps);
    return Constructor;
}
function _define_property(obj, key, value) {
    if (key in obj) {
        Object.defineProperty(obj, key, {
            value: value,
            enumerable: true,
            configurable: true,
            writable: true
        });
    } else {
        obj[key] = value;
    }
    return obj;
}
function _iterable_to_array(iter) {
    if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter);
}
function _iterable_to_array_limit(arr, i) {
    var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"];
    if (_i == null) return;
    var _arr = [];
    var _n = true;
    var _d = false;
    var _s, _e;
    try {
        for(_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true){
            _arr.push(_s.value);
            if (i && _arr.length === i) break;
        }
    } catch (err) {
        _d = true;
        _e = err;
    } finally{
        try {
            if (!_n && _i["return"] != null) _i["return"]();
        } finally{
            if (_d) throw _e;
        }
    }
    return _arr;
}
function _non_iterable_rest() {
    throw new TypeError("Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
}
function _non_iterable_spread() {
    throw new TypeError("Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
}
function _sliced_to_array(arr, i) {
    return _array_with_holes(arr) || _iterable_to_array_limit(arr, i) || _unsupported_iterable_to_array(arr, i) || _non_iterable_rest();
}
function _to_consumable_array(arr) {
    return _array_without_holes(arr) || _iterable_to_array(arr) || _unsupported_iterable_to_array(arr) || _non_iterable_spread();
}
function _unsupported_iterable_to_array(o, minLen) {
    if (!o) return;
    if (typeof o === "string") return _array_like_to_array(o, minLen);
    var n = Object.prototype.toString.call(o).slice(8, -1);
    if (n === "Object" && o.constructor) n = o.constructor.name;
    if (n === "Map" || n === "Set") return Array.from(n);
    if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array(o, minLen);
}
function _ts_generator(thisArg, body) {
    var f, y, t, _ = {
        label: 0,
        sent: function() {
            if (t[0] & 1) throw t[1];
            return t[1];
        },
        trys: [],
        ops: []
    }, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype), d = Object.defineProperty;
    return d(g, "next", {
        value: verb(0)
    }), d(g, "throw", {
        value: verb(1)
    }), d(g, "return", {
        value: verb(2)
    }), typeof Symbol === "function" && d(g, Symbol.iterator, {
        value: function() {
            return this;
        }
    }), g;
    function verb(n) {
        return function(v) {
            return step([
                n,
                v
            ]);
        };
    }
    function step(op) {
        if (f) throw new TypeError("Generator is already executing.");
        while(g && (g = 0, op[0] && (_ = 0)), _)try {
            if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
            if (y = 0, t) op = [
                op[0] & 2,
                t.value
            ];
            switch(op[0]){
                case 0:
                case 1:
                    t = op;
                    break;
                case 4:
                    _.label++;
                    return {
                        value: op[1],
                        done: false
                    };
                case 5:
                    _.label++;
                    y = op[1];
                    op = [
                        0
                    ];
                    continue;
                case 7:
                    op = _.ops.pop();
                    _.trys.pop();
                    continue;
                default:
                    if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) {
                        _ = 0;
                        continue;
                    }
                    if (op[0] === 3 && (!t || op[1] > t[0] && op[1] < t[3])) {
                        _.label = op[1];
                        break;
                    }
                    if (op[0] === 6 && _.label < t[1]) {
                        _.label = t[1];
                        t = op;
                        break;
                    }
                    if (t && _.label < t[2]) {
                        _.label = t[2];
                        _.ops.push(op);
                        break;
                    }
                    if (t[2]) _.ops.pop();
                    _.trys.pop();
                    continue;
            }
            op = body.call(thisArg, _);
        } catch (e) {
            op = [
                6,
                e
            ];
            y = 0;
        } finally{
            f = t = 0;
        }
        if (op[0] & 5) throw op[1];
        return {
            value: op[0] ? op[1] : void 0,
            done: true
        };
    }
}
import { message } from "antd";
import copy from "copy-to-clipboard";
import isHotkey from "is-hotkey";
import { useEffect, useMemo } from "react";
import { Editor, Element, Node, Path, Range, Transforms } from "slate";
import { ReactEditor } from "slate-react";
import { useRefFunction } from "../../../Hooks/useRefFunction";
import { useSubject } from "../../hooks/subscribe";
import { convertToParagraph, createList, decreaseHeadingLevel, increaseHeadingLevel, insertCodeBlock, insertHorizontalLine, insertTable as insertTableCommand, setHeading, toggleQuote } from "./editorCommands";
import { EditorUtils } from "./editorUtils";
export var KeyboardTask = /*#__PURE__*/ function() {
    "use strict";
    function KeyboardTask(store, props) {
        _class_call_check(this, KeyboardTask);
        _define_property(this, "store", void 0);
        _define_property(this, "editor", void 0);
        _define_property(this, "props", void 0);
        this.store = store;
        this.editor = store === null || store === void 0 ? void 0 : store.editor;
        this.props = props;
    }
    _create_class(KeyboardTask, [
        {
            key: "curNodes",
            get: /**
   * 获取当前编辑器中的最低层级元素节点
   *
   * @returns 编辑器中所有匹配的元素节点及其路径
   */ function get() {
                return Editor.nodes(this.editor, {
                    mode: 'lowest',
                    match: function(m) {
                        return Element.isElement(m);
                    }
                });
            }
        },
        {
            /**
   * 全选编辑器内容
   *
   * 如果当前位于表格单元格内，则选中整个表格；
   * 否则选中编辑器中的所有内容
   */ key: "selectAll",
            value: function selectAll() {
                Transforms.select(this.editor, {
                    anchor: Editor.start(this.editor, []),
                    focus: Editor.end(this.editor, [])
                });
            }
        },
        {
            /**
   * 选择当前行的文本。
   *
   * 如果编辑器中有选区，则选择当前行的文本，并打开浮动工具栏。
   *
   * @remarks
   * 该方法首先检查编辑器中是否有选区。如果有选区，则选择当前行的文本路径。
   * 然后获取当前行的文本内容，如果文本内容存在，则打开浮动工具栏。
   */ key: "selectLine",
            value: function selectLine() {
                if (this.editor.selection) {
                    Transforms.select(this.editor, Path.parent(this.editor.selection.anchor.path));
                }
            }
        },
        {
            /**
   * 将选中文本转换为行内代码
   *
   * 如果编辑器存在选区，将选中的文本转换为行内代码格式
   */ key: "selectFormatToCode",
            value: function selectFormatToCode() {
                if (this.editor.selection) {
                    EditorUtils.toggleFormat(this.editor, 'code');
                }
            }
        },
        {
            /**
   * 选择当前光标所在的单词或汉字。
   *
   * 如果当前选区是折叠的（即光标没有选中任何文本），则会尝试选择光标所在位置的整个单词或汉字。
   *
   * 具体步骤如下：
   * 1. 获取当前选区，如果选区是折叠的，则继续。
   * 2. 获取光标所在位置的文本内容。
   * 3. 根据光标位置，向前和向后查找单词或汉字的边界。
   * 4. 更新选区，使其包含整个单词或汉字。
   * 5. 如果选区不再是折叠的，则打开浮动工具栏。
   *
   * @remarks
   * 该方法支持英文单词和中文汉字的选择。
   */ key: "selectWord",
            value: function selectWord() {
                var sel = this.editor.selection;
                if (sel && Range.isCollapsed(sel)) {
                    var text = Node.leaf(this.editor, sel.anchor.path).text || '';
                    var start = sel.anchor.offset;
                    var end = start;
                    var next = text.slice(start);
                    var pre = text.slice(0, start);
                    var m1 = next.match(/^(\w+)/);
                    if (m1) {
                        end += m1[1].length;
                        var m2 = pre.match(/(\w+)$/);
                        if (m2) start = start - m2[1].length;
                    } else {
                        m1 = next.match(/^([\u4e00-\u9fa5]+)/);
                        if (m1) {
                            end += m1[1].length;
                            var m21 = pre.match(/([\u4e00-\u9fa5]+)$/);
                            if (m21) start = start - m21[1].length;
                        } else {
                            var m22 = pre.match(/(\w+)$/);
                            if (!m22) m22 = pre.match(/([\u4e00-\u9fa5]+)$/);
                            if (m22) start -= m22[1].length;
                        }
                    }
                    if (start === sel.anchor.offset && end === sel.anchor.offset && next) {
                        end = start + 1;
                    }
                    Transforms.select(this.editor, {
                        anchor: {
                            path: sel.anchor.path,
                            offset: start
                        },
                        focus: {
                            path: sel.anchor.path,
                            offset: end
                        }
                    });
                }
            }
        },
        {
            key: "pastePlainText",
            value: /**
   * 从剪贴板粘贴纯文本内容到编辑器中。
   *
   * 该方法首先从剪贴板读取文本内容，然后根据当前节点的类型决定如何插入文本。
   * 如果当前节点是表格单元格类型，则将换行符替换为空格后插入文本；
   * 否则，直接插入文本。
   *
   * @returns {Promise<void>} 一个表示异步操作的 Promise 对象。
   */ function pastePlainText() {
                return _async_to_generator(function() {
                    var text, _node_, _this_curNodes, node;
                    return _ts_generator(this, function(_state) {
                        switch(_state.label){
                            case 0:
                                return [
                                    4,
                                    navigator.clipboard.readText()
                                ];
                            case 1:
                                text = _state.sent();
                                if (text) {
                                    ;
                                    _this_curNodes = _sliced_to_array(this.curNodes, 1), node = _this_curNodes[0];
                                    if ((node === null || node === void 0 ? void 0 : (_node_ = node[0]) === null || _node_ === void 0 ? void 0 : _node_.type) === 'table-cell') {
                                        Editor.insertText(this.editor, text.replace(/\n/g, ' '));
                                    } else {
                                        Editor.insertText(this.editor, text);
                                    }
                                }
                                return [
                                    2
                                ];
                        }
                    });
                }).call(this);
            }
        },
        {
            /**
   * 上传图片
   *
   * 创建文件上传输入框，允许用户选择图片文件上传，
   * 然后根据当前节点位置将图片插入到编辑器中适当的位置。
   * 支持列单元格、普通节点和空编辑器的不同插入逻辑。
   */ key: "uploadImage",
            value: function uploadImage() {
                var _this = this;
                var input = document.createElement('input');
                var _this_curNodes = _sliced_to_array(this.curNodes, 1), node = _this_curNodes[0];
                input.id = 'uploadImage' + '_' + Math.random();
                input.type = 'file';
                input.accept = 'image/*';
                var insertMedia = function(url) {
                    return _async_to_generator(function() {
                        return _ts_generator(this, function(_state) {
                            if (node && [
                                'column-cell'
                            ].includes(node[0].type)) {
                                Transforms.insertNodes(this.editor, [
                                    EditorUtils.createMediaNode(url, 'image', {})
                                ], {
                                    at: _to_consumable_array(node[1]).concat([
                                        0
                                    ])
                                });
                                return [
                                    2
                                ];
                            }
                            if (node) {
                                Transforms.insertNodes(this.editor, [
                                    EditorUtils.createMediaNode(url, 'image', {})
                                ], {
                                    at: Path.next(node[1])
                                });
                            } else {
                                Transforms.insertNodes(this.editor, [
                                    EditorUtils.createMediaNode(url, 'image', {})
                                ], {
                                    select: true
                                });
                            }
                            return [
                                2
                            ];
                        });
                    }).call(_this);
                };
                input.onchange = function(e) {
                    return _async_to_generator(function() {
                        var hideLoading, _this_props_image, _this_props, url, error;
                        return _ts_generator(this, function(_state) {
                            switch(_state.label){
                                case 0:
                                    if (input.dataset.readonly) {
                                        return [
                                            2
                                        ];
                                    }
                                    input.dataset.readonly = 'true';
                                    hideLoading = message.loading('上传中...');
                                    _state.label = 1;
                                case 1:
                                    _state.trys.push([
                                        1,
                                        3,
                                        4,
                                        5
                                    ]);
                                    if (!((_this_props = this.props) === null || _this_props === void 0 ? void 0 : (_this_props_image = _this_props.image) === null || _this_props_image === void 0 ? void 0 : _this_props_image.upload)) {
                                        message.error('图片上传功能未配置');
                                        return [
                                            2
                                        ];
                                    }
                                    return [
                                        4,
                                        this.props.image.upload(Array.from(e.target.files) || [])
                                    ];
                                case 2:
                                    url = _state.sent() || [];
                                    [
                                        url
                                    ].flat().forEach(function(u) {
                                        if (u) {
                                            insertMedia(u);
                                        }
                                    });
                                    message.success('上传成功');
                                    return [
                                        3,
                                        5
                                    ];
                                case 3:
                                    error = _state.sent();
                                    console.error('图片上传失败:', error);
                                    message.error('图片上传失败');
                                    return [
                                        3,
                                        5
                                    ];
                                case 4:
                                    hideLoading();
                                    input.value = '';
                                    return [
                                        7
                                    ];
                                case 5:
                                    return [
                                        2
                                    ];
                            }
                        });
                    }).call(_this);
                };
                if (input.dataset.readonly) {
                    return;
                }
                input.click();
                input.remove();
            }
        },
        {
            /**
   * 设置标题级别
   *
   * 将当前段落或标题节点转换为指定级别的标题。
   * 如果级别为4，则转换为普通段落。
   *
   * @param level 标题级别（1-3）或4（表示普通段落）
   */ key: "head",
            value: function head(level) {
                if (level === 4) {
                    this.paragraph();
                    return;
                }
                setHeading(this.editor, level);
            }
        },
        {
            /**
   * 将标题转换为普通段落
   *
   * 如果当前节点是标题类型，将其转换为普通段落
   */ key: "paragraph",
            value: function paragraph() {
                convertToParagraph(this.editor);
            }
        },
        {
            /**
   * 增加标题级别（使标题变小）
   *
   * 将段落转换为4级标题，
   * 或将标题级别从1级改为普通段落，
   * 或将其他级别标题升级一级（数字变小）
   */ key: "increaseHead",
            value: function increaseHead() {
                increaseHeadingLevel(this.editor);
            }
        },
        {
            /**
   * 降低标题级别（使标题变大）
   *
   * 将段落转换为1级标题，
   * 或将4级标题改为普通段落，
   * 或将其他级别标题降级一级（数字变大）
   */ key: "decreaseHead",
            value: function decreaseHead() {
                decreaseHeadingLevel(this.editor);
            }
        },
        {
            /**
   * 插入或移除引用块
   *
   * 如果当前节点已在引用块中，则移除引用块；
   * 否则，将当前节点转换为引用块。
   * 如果当前节点是标题，先将其转换为普通段落。
   */ key: "insertQuote",
            value: function insertQuote() {
                var _this_curNodes = _sliced_to_array(this.curNodes, 1), node = _this_curNodes[0];
                toggleQuote(this.editor, node);
            }
        },
        {
            /**
   * 插入表格
   *
   * 在当前位置插入一个3x3的表格（包含表头行）。
   * 根据当前节点类型（段落、标题或列单元格）
   * 决定在何处插入表格及如何处理现有内容。
   */ key: "insertTable",
            value: function insertTable() {
                var _this_curNodes = _sliced_to_array(this.curNodes, 1), node = _this_curNodes[0];
                insertTableCommand(this.editor, node);
            }
        },
        {
            /**
   * 插入分栏组
   *
   * 在当前位置插入一个两列的分栏布局。
   * 如果当前节点是空段落，会被删除。
   */ /**
   * 插入代码块
   *
   * 在当前位置插入代码块，并根据传入的类型设置语言和渲染模式。
   * 支持在列单元格内或普通段落/标题后插入代码块。
   *
   * @param type 可选的代码块类型，'mermaid'表示流程图，'html'表示HTML渲染
   */ key: "insertCode",
            value: function insertCode(type) {
                var _this_curNodes = _sliced_to_array(this.curNodes, 1), node = _this_curNodes[0];
                insertCodeBlock(this.editor, type, node);
            }
        },
        {
            /**
   * 插入水平分割线
   *
   * 在当前位置插入水平分割线，并将光标定位到分割线后的位置。
   * 如果分割线后没有内容，则自动插入一个空段落并将光标定位到该段落。
   */ key: "horizontalLine",
            value: function horizontalLine() {
                var _this_curNodes = _sliced_to_array(this.curNodes, 1), node = _this_curNodes[0];
                insertHorizontalLine(this.editor, node);
            }
        },
        {
            /**
   * 创建或转换列表
   *
   * 将当前段落或标题转换为指定类型的列表。
   * 如果已经是列表项，则更改列表类型。
   *
   * @param mode 列表类型 'ordered'(有序列表), 'unordered'(无序列表), 'task'(任务列表)
   */ key: "list",
            value: function list(mode) {
                createList(this.editor, mode);
            }
        },
        {
            /**
   * 切换文本格式
   *
   * 在当前选区上应用或取消指定的文本格式（如加粗、斜体等）
   *
   * @param type 要应用的格式类型（'bold'、'italic'、'strikethrough'等）
   */ key: "format",
            value: function format(type) {
                EditorUtils.toggleFormat(this.editor, type);
            }
        },
        {
            /**
   * 清除文本格式
   *
   * 移除当前选区中的所有格式标记。
   * 如果选区是折叠的（只有光标），则清除光标所在位置的所有标记
   */ key: "clear",
            value: function clear() {
                if (this.editor.selection) EditorUtils.clearMarks(this.editor, !Range.isCollapsed(this.editor.selection));
            }
        },
        {
            /**
   * 撤销上一步操作
   *
   * 调用编辑器的undo方法，回退到上一个历史状态
   */ key: "undo",
            value: function undo() {
                try {
                    var _this_store;
                    (_this_store = this.store) === null || _this_store === void 0 ? void 0 : _this_store.editor.undo();
                } catch (e) {}
            }
        },
        {
            /**
   * 重做上一步被撤销的操作
   *
   * 调用编辑器的redo方法，前进到下一个历史状态
   */ key: "redo",
            value: function redo() {
                try {
                    var _this_store;
                    (_this_store = this.store) === null || _this_store === void 0 ? void 0 : _this_store.editor.redo();
                } catch (e) {}
            }
        }
    ]);
    return KeyboardTask;
}();
/**
 * 
以下是 Markdown 编辑器快捷键列表及其功能说明：

| 快捷键 | 功能 |
|-------|------|
| `Cmd/Ctrl+Shift+L` | 选择当前行文本 |
| `Cmd/Ctrl+E` | 选择当前格式化的文本 |
| `Cmd/Ctrl+D` | 选择当前光标所在的单词或汉字 |
| `Cmd/Ctrl+A` | 全选编辑器内容 |
| `Cmd/Ctrl+Shift+V` | 粘贴纯文本内容（无格式） |
| `Cmd/Ctrl+1` | 设置为一级标题 (H1) |
| `Cmd/Ctrl+2` | 设置为二级标题 (H2) |
| `Cmd/Ctrl+3` | 设置为三级标题 (H3) |
| `Cmd/Ctrl+4` | 转换为普通段落 |
| `Cmd/Ctrl+0` | 转换为普通段落 |
| `Cmd/Ctrl+]` | 增加标题级别（标题变小） |
| `Cmd/Ctrl+[` | 降低标题级别（标题变大） |
| `Option/Alt+Q` | 插入或移除引用块 |
| `Cmd/Ctrl+Option/Alt+T` | 插入表格 |
| `Cmd/Ctrl+Option/Alt+C` | 插入代码块 |
| `Cmd/Ctrl+Option/Alt+/` | 插入水平分割线 |
| `Cmd/Ctrl+Option/Alt+O` | 创建有序列表 |
| `Cmd/Ctrl+Option/Alt+U` | 创建无序列表 |
| `Cmd/Ctrl+Option/Alt+S` | 创建任务列表 |
| `Cmd/Ctrl+B` | 切换文本加粗格式 |
| `Cmd/Ctrl+I` | 切换文本斜体格式 |
| `Cmd/Ctrl+Shift+S` | 切换文本删除线格式 |
| `Option/Alt+`` | 切换行内代码格式 |
| `Cmd/Ctrl+\` | 清除所有文本格式 |
| `Cmd/Ctrl+Option/Alt+M` | 插入流程图(Mermaid)代码块 |
注：`Cmd` 键在 Windows 系统上对应 `Ctrl` 键，`Option` 键在 Windows 系统上对应 `Alt` 键。
 */ var keyMap = [
    [
        'mod+shift+l',
        'selectLine'
    ],
    [
        'mod+e',
        'selectFormatToCode'
    ],
    [
        'mod+d',
        'selectWord'
    ],
    [
        'mod+a',
        'selectAll'
    ],
    [
        'mod+shift+v',
        'pastePlainText'
    ],
    [
        'mod+1',
        'head',
        [
            1
        ]
    ],
    [
        'mod+2',
        'head',
        [
            2
        ]
    ],
    [
        'mod+3',
        'head',
        [
            3
        ]
    ],
    [
        'mod+4',
        'head',
        [
            4
        ]
    ],
    [
        'mod+0',
        'paragraph'
    ],
    [
        'mod+]',
        'increaseHead'
    ],
    [
        'mod+[',
        'decreaseHead'
    ],
    [
        'option+q',
        'insertQuote'
    ],
    [
        'mod+option+t',
        'insertTable'
    ],
    [
        'mod+option+c',
        'insertCode'
    ],
    [
        'mod+option+/',
        'horizontalLine'
    ],
    [
        'mod+option+o',
        'list',
        [
            'ordered'
        ]
    ],
    [
        'mod+option+u',
        'list',
        [
            'unordered'
        ]
    ],
    [
        'mod+option+s',
        'list',
        [
            'task'
        ]
    ],
    [
        'mod+b',
        'format',
        [
            'bold'
        ]
    ],
    [
        'mod+i',
        'format',
        [
            'italic'
        ]
    ],
    [
        'mod+shift+s',
        'format',
        [
            'strikethrough'
        ]
    ],
    [
        'option+`',
        'format',
        [
            'code'
        ]
    ],
    [
        'mod+\\',
        'clear'
    ],
    [
        'mod+option+m',
        'insertCode',
        [
            'mermaid'
        ]
    ]
];
export var useSystemKeyboard = function(keyTask$, store, props, markdownContainerRef) {
    var task = useMemo(function() {
        return new KeyboardTask(store, props);
    }, [
        props.readonly
    ]);
    useSubject(keyTask$, function(param) {
        var key = param.key, args = param.args;
        var // @ts-ignore
        _task;
        (_task = task)[key].apply(_task, _to_consumable_array(args || []));
    });
    // eslint-disable-next-line react-hooks/exhaustive-deps
    var keydown = useRefFunction(function(e) {
        if (!store) return;
        if (isHotkey('mod+c', e) || isHotkey('mod+x', e)) {
            var _node_, _node_1, _node_2;
            var _Editor_nodes = _sliced_to_array(Editor.nodes(store === null || store === void 0 ? void 0 : store.editor, {
                mode: 'lowest',
                match: function(m) {
                    return Element.isElement(m) && (m.type === 'media' || m.type === 'attach');
                }
            }), 1), node = _Editor_nodes[0];
            if (!node) return;
            var readlUrl = (_node_ = node[0]) === null || _node_ === void 0 ? void 0 : _node_.url;
            if ((node === null || node === void 0 ? void 0 : (_node_1 = node[0]) === null || _node_1 === void 0 ? void 0 : _node_1.type) === 'media') {
                var url = "media://file?url=".concat(readlUrl, "&height=").concat(node[0].height || '');
                try {
                    copy(url);
                } catch (error) {}
                if (isHotkey('mod+x', e)) {
                    Transforms.delete(store === null || store === void 0 ? void 0 : store.editor, {
                        at: node[1]
                    });
                    ReactEditor.focus(store === null || store === void 0 ? void 0 : store.editor);
                }
            }
            if ((node === null || node === void 0 ? void 0 : (_node_2 = node[0]) === null || _node_2 === void 0 ? void 0 : _node_2.type) === 'attach') {
                var _node_3;
                var url1 = "attach://file?size=".concat(node[0].size, "&name=").concat(node[0].name, "&url=").concat((_node_3 = node[0]) === null || _node_3 === void 0 ? void 0 : _node_3.url);
                try {
                    copy(url1);
                } catch (error) {}
                if (isHotkey('mod+x', e)) {
                    Transforms.delete(store === null || store === void 0 ? void 0 : store.editor, {
                        at: node[1]
                    });
                    ReactEditor.focus(store === null || store === void 0 ? void 0 : store.editor);
                }
            }
        }
        if (isHotkey('backspace', e)) {
            var _task_curNodes = _sliced_to_array(task.curNodes, 1), node1 = _task_curNodes[0];
            if ((node1 === null || node1 === void 0 ? void 0 : node1[0].type) === 'media') {
                e.preventDefault();
                Transforms.removeNodes(task.editor, {
                    at: node1[1]
                });
                Transforms.insertNodes(task.editor, EditorUtils.p, {
                    at: node1[1],
                    select: true
                });
                ReactEditor.focus(task.editor);
            }
        }
        if (isHotkey('arrowUp', e) || isHotkey('arrowDown', e)) {
            var _task_curNodes1 = _sliced_to_array(task.curNodes, 1), node2 = _task_curNodes1[0];
            if ((node2 === null || node2 === void 0 ? void 0 : node2[0].type) === 'media') {
                e.preventDefault();
                if (isHotkey('arrowUp', e)) {
                    Transforms.select(task.editor, Editor.end(task.editor, EditorUtils.findPrev(task.editor, node2[1])));
                } else if (EditorUtils.findNext(task.editor, node2[1])) {
                    Transforms.select(task.editor, Editor.start(task.editor, EditorUtils.findNext(task.editor, node2[1])));
                }
                ReactEditor.focus(task.editor);
            }
        }
        var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
        try {
            for(var _iterator = keyMap[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
                var key = _step.value;
                if (isHotkey(key[0], e)) {
                    var // @ts-ignore
                    _task;
                    e.preventDefault();
                    e.stopPropagation();
                    (_task = task)[key[1]].apply(_task, _to_consumable_array(key[2] || []));
                    break;
                }
            }
        } catch (err) {
            _didIteratorError = true;
            _iteratorError = err;
        } finally{
            try {
                if (!_iteratorNormalCompletion && _iterator.return != null) {
                    _iterator.return();
                }
            } finally{
                if (_didIteratorError) {
                    throw _iteratorError;
                }
            }
        }
    });
    useEffect(function() {
        var _markdownContainerRef_current;
        if (props.readonly) return;
        if (!store) return;
        if (typeof window === 'undefined') return;
        markdownContainerRef === null || markdownContainerRef === void 0 ? void 0 : (_markdownContainerRef_current = markdownContainerRef.current) === null || _markdownContainerRef_current === void 0 ? void 0 : _markdownContainerRef_current.addEventListener('keydown', keydown);
        return function() {
            var _markdownContainerRef_current;
            markdownContainerRef === null || markdownContainerRef === void 0 ? void 0 : (_markdownContainerRef_current = markdownContainerRef.current) === null || _markdownContainerRef_current === void 0 ? void 0 : _markdownContainerRef_current.removeEventListener('keydown', keydown);
        };
    }, []);
};
