remons-markdown-editor 1.0.0 → 2.0.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -6,6 +6,7 @@ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
6
  var __getOwnPropNames = Object.getOwnPropertyNames;
7
7
  var __getProtoOf = Object.getPrototypeOf;
8
8
  var __hasOwnProp = Object.prototype.hasOwnProperty;
9
+ var __commonJSMin = (cb, mod) => () => (mod || (cb((mod = { exports: {} }).exports, mod), cb = null), mod.exports);
9
10
  var __copyProps = (to, from, except, desc) => {
10
11
  if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
11
12
  key = keys[i];
@@ -36,83 +37,1195 @@ let remons_render_markdown = require("remons-render-markdown");
36
37
  remons_render_markdown = __toESM(remons_render_markdown, 1);
37
38
  require("remons-render-markdown/dist/index.css");
38
39
  let _ant_design_icons = require("@ant-design/icons");
39
- //#region src/utils/parseContainer.ts
40
- /**
41
- * 解析容器属性 JSON 字符串。
42
- * 支持标准 JSON 和宽松格式: { key: 'value', key2: 'value2' }
43
- */
44
- function parseContainerProps(jsonStr) {
45
- try {
46
- const props = {};
47
- const trimmed = jsonStr.trim();
48
- if (trimmed.startsWith("{") && trimmed.endsWith("}")) {
49
- const inner = trimmed.slice(1, -1).trim();
50
- if (!inner) return props;
51
- const matches = inner.matchAll(/(?:["']?)(\w+)(?:["']?)\s*:\s*(?:"([^"]*)"|'([^']*)'|(\d+))/g);
52
- for (const m of matches) props[m[1]] = m[2] ?? m[3] ?? m[4] ?? "";
40
+ //#endregion
41
+ //#region src/registry/componentRegistry.tsx
42
+ var import_dist = /* @__PURE__ */ __toESM((/* @__PURE__ */ __commonJSMin(((exports, module) => {
43
+ (function(global, factory) {
44
+ typeof exports === "object" && typeof module !== "undefined" ? module.exports = factory() : typeof define === "function" && define.amd ? define(factory) : global.JSON5 = factory();
45
+ })(exports, (function() {
46
+ "use strict";
47
+ function createCommonjsModule(fn, module$1) {
48
+ return module$1 = { exports: {} }, fn(module$1, module$1.exports), module$1.exports;
53
49
  }
54
- return props;
55
- } catch {
56
- return {};
57
- }
58
- }
59
- function findContainers(docText) {
60
- const containers = [];
61
- const lines = docText.split("\n");
62
- let i = 0;
63
- while (i < lines.length) {
64
- const line = lines[i];
65
- const match = line.match(/^:::(\w+)$/);
66
- if (match) {
67
- const typeName = match[1];
68
- let charPos = 0;
69
- for (let l = 0; l < i; l++) charPos += lines[l].length + 1;
70
- let props = {};
71
- let propsLineFrom = 0;
72
- let propsLineTo = 0;
73
- let propsLineIndex = i + 1;
74
- if (propsLineIndex < lines.length) {
75
- const propsLine = lines[propsLineIndex].trim();
76
- if (propsLine.match(/^\{[\s\S]*\}$/)) {
77
- props = parseContainerProps(propsLine);
78
- propsLineFrom = charPos + line.length + 1;
79
- propsLineTo = propsLineFrom + lines[propsLineIndex].length;
50
+ var _global = createCommonjsModule(function(module$2) {
51
+ var global = module$2.exports = typeof window != "undefined" && window.Math == Math ? window : typeof self != "undefined" && self.Math == Math ? self : Function("return this")();
52
+ if (typeof __g == "number") __g = global;
53
+ });
54
+ var _core = createCommonjsModule(function(module$3) {
55
+ var core = module$3.exports = { version: "2.6.5" };
56
+ if (typeof __e == "number") __e = core;
57
+ });
58
+ _core.version;
59
+ var _isObject = function(it) {
60
+ return typeof it === "object" ? it !== null : typeof it === "function";
61
+ };
62
+ var _anObject = function(it) {
63
+ if (!_isObject(it)) throw TypeError(it + " is not an object!");
64
+ return it;
65
+ };
66
+ var _fails = function(exec) {
67
+ try {
68
+ return !!exec();
69
+ } catch (e) {
70
+ return true;
71
+ }
72
+ };
73
+ var _descriptors = !_fails(function() {
74
+ return Object.defineProperty({}, "a", { get: function() {
75
+ return 7;
76
+ } }).a != 7;
77
+ });
78
+ var document = _global.document;
79
+ var is = _isObject(document) && _isObject(document.createElement);
80
+ var _domCreate = function(it) {
81
+ return is ? document.createElement(it) : {};
82
+ };
83
+ var _ie8DomDefine = !_descriptors && !_fails(function() {
84
+ return Object.defineProperty(_domCreate("div"), "a", { get: function() {
85
+ return 7;
86
+ } }).a != 7;
87
+ });
88
+ var _toPrimitive = function(it, S) {
89
+ if (!_isObject(it)) return it;
90
+ var fn, val;
91
+ if (S && typeof (fn = it.toString) == "function" && !_isObject(val = fn.call(it))) return val;
92
+ if (typeof (fn = it.valueOf) == "function" && !_isObject(val = fn.call(it))) return val;
93
+ if (!S && typeof (fn = it.toString) == "function" && !_isObject(val = fn.call(it))) return val;
94
+ throw TypeError("Can't convert object to primitive value");
95
+ };
96
+ var dP = Object.defineProperty;
97
+ var _objectDp = { f: _descriptors ? Object.defineProperty : function defineProperty(O, P, Attributes) {
98
+ _anObject(O);
99
+ P = _toPrimitive(P, true);
100
+ _anObject(Attributes);
101
+ if (_ie8DomDefine) try {
102
+ return dP(O, P, Attributes);
103
+ } catch (e) {}
104
+ if ("get" in Attributes || "set" in Attributes) throw TypeError("Accessors not supported!");
105
+ if ("value" in Attributes) O[P] = Attributes.value;
106
+ return O;
107
+ } };
108
+ var _propertyDesc = function(bitmap, value) {
109
+ return {
110
+ enumerable: !(bitmap & 1),
111
+ configurable: !(bitmap & 2),
112
+ writable: !(bitmap & 4),
113
+ value
114
+ };
115
+ };
116
+ var _hide = _descriptors ? function(object, key, value) {
117
+ return _objectDp.f(object, key, _propertyDesc(1, value));
118
+ } : function(object, key, value) {
119
+ object[key] = value;
120
+ return object;
121
+ };
122
+ var hasOwnProperty = {}.hasOwnProperty;
123
+ var _has = function(it, key) {
124
+ return hasOwnProperty.call(it, key);
125
+ };
126
+ var id = 0;
127
+ var px = Math.random();
128
+ var _uid = function(key) {
129
+ return "Symbol(".concat(key === void 0 ? "" : key, ")_", (++id + px).toString(36));
130
+ };
131
+ var _library = false;
132
+ var _functionToString = createCommonjsModule(function(module$4) {
133
+ var SHARED = "__core-js_shared__";
134
+ var store = _global[SHARED] || (_global[SHARED] = {});
135
+ (module$4.exports = function(key, value) {
136
+ return store[key] || (store[key] = value !== void 0 ? value : {});
137
+ })("versions", []).push({
138
+ version: _core.version,
139
+ mode: _library ? "pure" : "global",
140
+ copyright: "© 2019 Denis Pushkarev (zloirock.ru)"
141
+ });
142
+ })("native-function-to-string", Function.toString);
143
+ var _redefine = createCommonjsModule(function(module$5) {
144
+ var SRC = _uid("src");
145
+ var TO_STRING = "toString";
146
+ var TPL = ("" + _functionToString).split(TO_STRING);
147
+ _core.inspectSource = function(it) {
148
+ return _functionToString.call(it);
149
+ };
150
+ (module$5.exports = function(O, key, val, safe) {
151
+ var isFunction = typeof val == "function";
152
+ if (isFunction) _has(val, "name") || _hide(val, "name", key);
153
+ if (O[key] === val) return;
154
+ if (isFunction) _has(val, SRC) || _hide(val, SRC, O[key] ? "" + O[key] : TPL.join(String(key)));
155
+ if (O === _global) O[key] = val;
156
+ else if (!safe) {
157
+ delete O[key];
158
+ _hide(O, key, val);
159
+ } else if (O[key]) O[key] = val;
160
+ else _hide(O, key, val);
161
+ })(Function.prototype, TO_STRING, function toString() {
162
+ return typeof this == "function" && this[SRC] || _functionToString.call(this);
163
+ });
164
+ });
165
+ var _aFunction = function(it) {
166
+ if (typeof it != "function") throw TypeError(it + " is not a function!");
167
+ return it;
168
+ };
169
+ var _ctx = function(fn, that, length) {
170
+ _aFunction(fn);
171
+ if (that === void 0) return fn;
172
+ switch (length) {
173
+ case 1: return function(a) {
174
+ return fn.call(that, a);
175
+ };
176
+ case 2: return function(a, b) {
177
+ return fn.call(that, a, b);
178
+ };
179
+ case 3: return function(a, b, c) {
180
+ return fn.call(that, a, b, c);
181
+ };
182
+ }
183
+ return function() {
184
+ return fn.apply(that, arguments);
185
+ };
186
+ };
187
+ var PROTOTYPE = "prototype";
188
+ var $export = function(type, name, source) {
189
+ var IS_FORCED = type & $export.F;
190
+ var IS_GLOBAL = type & $export.G;
191
+ var IS_STATIC = type & $export.S;
192
+ var IS_PROTO = type & $export.P;
193
+ var IS_BIND = type & $export.B;
194
+ var target = IS_GLOBAL ? _global : IS_STATIC ? _global[name] || (_global[name] = {}) : (_global[name] || {})[PROTOTYPE];
195
+ var exports$1 = IS_GLOBAL ? _core : _core[name] || (_core[name] = {});
196
+ var expProto = exports$1[PROTOTYPE] || (exports$1[PROTOTYPE] = {});
197
+ var key, own, out, exp;
198
+ if (IS_GLOBAL) source = name;
199
+ for (key in source) {
200
+ own = !IS_FORCED && target && target[key] !== void 0;
201
+ out = (own ? target : source)[key];
202
+ exp = IS_BIND && own ? _ctx(out, _global) : IS_PROTO && typeof out == "function" ? _ctx(Function.call, out) : out;
203
+ if (target) _redefine(target, key, out, type & $export.U);
204
+ if (exports$1[key] != out) _hide(exports$1, key, exp);
205
+ if (IS_PROTO && expProto[key] != out) expProto[key] = out;
206
+ }
207
+ };
208
+ _global.core = _core;
209
+ $export.F = 1;
210
+ $export.G = 2;
211
+ $export.S = 4;
212
+ $export.P = 8;
213
+ $export.B = 16;
214
+ $export.W = 32;
215
+ $export.U = 64;
216
+ $export.R = 128;
217
+ var _export = $export;
218
+ var ceil = Math.ceil;
219
+ var floor = Math.floor;
220
+ var _toInteger = function(it) {
221
+ return isNaN(it = +it) ? 0 : (it > 0 ? floor : ceil)(it);
222
+ };
223
+ var _defined = function(it) {
224
+ if (it == void 0) throw TypeError("Can't call method on " + it);
225
+ return it;
226
+ };
227
+ var _stringAt = function(TO_STRING) {
228
+ return function(that, pos) {
229
+ var s = String(_defined(that));
230
+ var i = _toInteger(pos);
231
+ var l = s.length;
232
+ var a, b;
233
+ if (i < 0 || i >= l) return TO_STRING ? "" : void 0;
234
+ a = s.charCodeAt(i);
235
+ return a < 55296 || a > 56319 || i + 1 === l || (b = s.charCodeAt(i + 1)) < 56320 || b > 57343 ? TO_STRING ? s.charAt(i) : a : TO_STRING ? s.slice(i, i + 2) : (a - 55296 << 10) + (b - 56320) + 65536;
236
+ };
237
+ };
238
+ var $at = _stringAt(false);
239
+ _export(_export.P, "String", { codePointAt: function codePointAt(pos) {
240
+ return $at(this, pos);
241
+ } });
242
+ _core.String.codePointAt;
243
+ var max = Math.max;
244
+ var min = Math.min;
245
+ var _toAbsoluteIndex = function(index, length) {
246
+ index = _toInteger(index);
247
+ return index < 0 ? max(index + length, 0) : min(index, length);
248
+ };
249
+ var fromCharCode = String.fromCharCode;
250
+ var $fromCodePoint = String.fromCodePoint;
251
+ _export(_export.S + _export.F * (!!$fromCodePoint && $fromCodePoint.length != 1), "String", { fromCodePoint: function fromCodePoint(x) {
252
+ var arguments$1 = arguments;
253
+ var res = [];
254
+ var aLen = arguments.length;
255
+ var i = 0;
256
+ var code;
257
+ while (aLen > i) {
258
+ code = +arguments$1[i++];
259
+ if (_toAbsoluteIndex(code, 1114111) !== code) throw RangeError(code + " is not a valid code point");
260
+ res.push(code < 65536 ? fromCharCode(code) : fromCharCode(((code -= 65536) >> 10) + 55296, code % 1024 + 56320));
261
+ }
262
+ return res.join("");
263
+ } });
264
+ _core.String.fromCodePoint;
265
+ var unicode = {
266
+ Space_Separator: /[\u1680\u2000-\u200A\u202F\u205F\u3000]/,
267
+ ID_Start: /[\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u0860-\u086A\u08A0-\u08B4\u08B6-\u08BD\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u09FC\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0AF9\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D\u0C58-\u0C5A\u0C60\u0C61\u0C80\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D54-\u0D56\u0D5F-\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u1820-\u1877\u1880-\u1884\u1887-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191E\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u1A00-\u1A16\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1C80-\u1C88\u1CE9-\u1CEC\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303C\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312E\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FEA\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA67F-\uA69D\uA6A0-\uA6EF\uA717-\uA71F\uA722-\uA788\uA78B-\uA7AE\uA7B0-\uA7B7\uA7F7-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA8FD\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uA9E0-\uA9E4\uA9E6-\uA9EF\uA9FA-\uA9FE\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA7E-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB65\uAB70-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD40-\uDD74\uDE80-\uDE9C\uDEA0-\uDED0\uDF00-\uDF1F\uDF2D-\uDF4A\uDF50-\uDF75\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDCB0-\uDCD3\uDCD8-\uDCFB\uDD00-\uDD27\uDD30-\uDD63\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDCE0-\uDCF2\uDCF4\uDCF5\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00\uDE10-\uDE13\uDE15-\uDE17\uDE19-\uDE33\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE4\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48\uDC80-\uDCB2\uDCC0-\uDCF2]|\uD804[\uDC03-\uDC37\uDC83-\uDCAF\uDCD0-\uDCE8\uDD03-\uDD26\uDD50-\uDD72\uDD76\uDD83-\uDDB2\uDDC1-\uDDC4\uDDDA\uDDDC\uDE00-\uDE11\uDE13-\uDE2B\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEDE\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3D\uDF50\uDF5D-\uDF61]|\uD805[\uDC00-\uDC34\uDC47-\uDC4A\uDC80-\uDCAF\uDCC4\uDCC5\uDCC7\uDD80-\uDDAE\uDDD8-\uDDDB\uDE00-\uDE2F\uDE44\uDE80-\uDEAA\uDF00-\uDF19]|\uD806[\uDCA0-\uDCDF\uDCFF\uDE00\uDE0B-\uDE32\uDE3A\uDE50\uDE5C-\uDE83\uDE86-\uDE89\uDEC0-\uDEF8]|\uD807[\uDC00-\uDC08\uDC0A-\uDC2E\uDC40\uDC72-\uDC8F\uDD00-\uDD06\uDD08\uDD09\uDD0B-\uDD30\uDD46]|\uD808[\uDC00-\uDF99]|\uD809[\uDC00-\uDC6E\uDC80-\uDD43]|[\uD80C\uD81C-\uD820\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872\uD874-\uD879][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD811[\uDC00-\uDE46]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDED0-\uDEED\uDF00-\uDF2F\uDF40-\uDF43\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDF00-\uDF44\uDF50\uDF93-\uDF9F\uDFE0\uDFE1]|\uD821[\uDC00-\uDFEC]|\uD822[\uDC00-\uDEF2]|\uD82C[\uDC00-\uDD1E\uDD70-\uDEFB]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB]|\uD83A[\uDC00-\uDCC4\uDD00-\uDD43]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1\uDEB0-\uDFFF]|\uD87A[\uDC00-\uDFE0]|\uD87E[\uDC00-\uDE1D]/,
268
+ ID_Continue: /[\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0300-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u0483-\u0487\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u05D0-\u05EA\u05F0-\u05F2\u0610-\u061A\u0620-\u0669\u066E-\u06D3\u06D5-\u06DC\u06DF-\u06E8\u06EA-\u06FC\u06FF\u0710-\u074A\u074D-\u07B1\u07C0-\u07F5\u07FA\u0800-\u082D\u0840-\u085B\u0860-\u086A\u08A0-\u08B4\u08B6-\u08BD\u08D4-\u08E1\u08E3-\u0963\u0966-\u096F\u0971-\u0983\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BC-\u09C4\u09C7\u09C8\u09CB-\u09CE\u09D7\u09DC\u09DD\u09DF-\u09E3\u09E6-\u09F1\u09FC\u0A01-\u0A03\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A3C\u0A3E-\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A59-\u0A5C\u0A5E\u0A66-\u0A75\u0A81-\u0A83\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABC-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD\u0AD0\u0AE0-\u0AE3\u0AE6-\u0AEF\u0AF9-\u0AFF\u0B01-\u0B03\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3C-\u0B44\u0B47\u0B48\u0B4B-\u0B4D\u0B56\u0B57\u0B5C\u0B5D\u0B5F-\u0B63\u0B66-\u0B6F\u0B71\u0B82\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD0\u0BD7\u0BE6-\u0BEF\u0C00-\u0C03\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C58-\u0C5A\u0C60-\u0C63\u0C66-\u0C6F\u0C80-\u0C83\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBC-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCD\u0CD5\u0CD6\u0CDE\u0CE0-\u0CE3\u0CE6-\u0CEF\u0CF1\u0CF2\u0D00-\u0D03\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D44\u0D46-\u0D48\u0D4A-\u0D4E\u0D54-\u0D57\u0D5F-\u0D63\u0D66-\u0D6F\u0D7A-\u0D7F\u0D82\u0D83\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0DCA\u0DCF-\u0DD4\u0DD6\u0DD8-\u0DDF\u0DE6-\u0DEF\u0DF2\u0DF3\u0E01-\u0E3A\u0E40-\u0E4E\u0E50-\u0E59\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB9\u0EBB-\u0EBD\u0EC0-\u0EC4\u0EC6\u0EC8-\u0ECD\u0ED0-\u0ED9\u0EDC-\u0EDF\u0F00\u0F18\u0F19\u0F20-\u0F29\u0F35\u0F37\u0F39\u0F3E-\u0F47\u0F49-\u0F6C\u0F71-\u0F84\u0F86-\u0F97\u0F99-\u0FBC\u0FC6\u1000-\u1049\u1050-\u109D\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u135D-\u135F\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1714\u1720-\u1734\u1740-\u1753\u1760-\u176C\u176E-\u1770\u1772\u1773\u1780-\u17D3\u17D7\u17DC\u17DD\u17E0-\u17E9\u180B-\u180D\u1810-\u1819\u1820-\u1877\u1880-\u18AA\u18B0-\u18F5\u1900-\u191E\u1920-\u192B\u1930-\u193B\u1946-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u19D0-\u19D9\u1A00-\u1A1B\u1A20-\u1A5E\u1A60-\u1A7C\u1A7F-\u1A89\u1A90-\u1A99\u1AA7\u1AB0-\u1ABD\u1B00-\u1B4B\u1B50-\u1B59\u1B6B-\u1B73\u1B80-\u1BF3\u1C00-\u1C37\u1C40-\u1C49\u1C4D-\u1C7D\u1C80-\u1C88\u1CD0-\u1CD2\u1CD4-\u1CF9\u1D00-\u1DF9\u1DFB-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u203F\u2040\u2054\u2071\u207F\u2090-\u209C\u20D0-\u20DC\u20E1\u20E5-\u20F0\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D7F-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2DE0-\u2DFF\u2E2F\u3005-\u3007\u3021-\u302F\u3031-\u3035\u3038-\u303C\u3041-\u3096\u3099\u309A\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312E\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FEA\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA62B\uA640-\uA66F\uA674-\uA67D\uA67F-\uA6F1\uA717-\uA71F\uA722-\uA788\uA78B-\uA7AE\uA7B0-\uA7B7\uA7F7-\uA827\uA840-\uA873\uA880-\uA8C5\uA8D0-\uA8D9\uA8E0-\uA8F7\uA8FB\uA8FD\uA900-\uA92D\uA930-\uA953\uA960-\uA97C\uA980-\uA9C0\uA9CF-\uA9D9\uA9E0-\uA9FE\uAA00-\uAA36\uAA40-\uAA4D\uAA50-\uAA59\uAA60-\uAA76\uAA7A-\uAAC2\uAADB-\uAADD\uAAE0-\uAAEF\uAAF2-\uAAF6\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB65\uAB70-\uABEA\uABEC\uABED\uABF0-\uABF9\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE00-\uFE0F\uFE20-\uFE2F\uFE33\uFE34\uFE4D-\uFE4F\uFE70-\uFE74\uFE76-\uFEFC\uFF10-\uFF19\uFF21-\uFF3A\uFF3F\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD40-\uDD74\uDDFD\uDE80-\uDE9C\uDEA0-\uDED0\uDEE0\uDF00-\uDF1F\uDF2D-\uDF4A\uDF50-\uDF7A\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDCA0-\uDCA9\uDCB0-\uDCD3\uDCD8-\uDCFB\uDD00-\uDD27\uDD30-\uDD63\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDCE0-\uDCF2\uDCF4\uDCF5\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00-\uDE03\uDE05\uDE06\uDE0C-\uDE13\uDE15-\uDE17\uDE19-\uDE33\uDE38-\uDE3A\uDE3F\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE6\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48\uDC80-\uDCB2\uDCC0-\uDCF2]|\uD804[\uDC00-\uDC46\uDC66-\uDC6F\uDC7F-\uDCBA\uDCD0-\uDCE8\uDCF0-\uDCF9\uDD00-\uDD34\uDD36-\uDD3F\uDD50-\uDD73\uDD76\uDD80-\uDDC4\uDDCA-\uDDCC\uDDD0-\uDDDA\uDDDC\uDE00-\uDE11\uDE13-\uDE37\uDE3E\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEEA\uDEF0-\uDEF9\uDF00-\uDF03\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3C-\uDF44\uDF47\uDF48\uDF4B-\uDF4D\uDF50\uDF57\uDF5D-\uDF63\uDF66-\uDF6C\uDF70-\uDF74]|\uD805[\uDC00-\uDC4A\uDC50-\uDC59\uDC80-\uDCC5\uDCC7\uDCD0-\uDCD9\uDD80-\uDDB5\uDDB8-\uDDC0\uDDD8-\uDDDD\uDE00-\uDE40\uDE44\uDE50-\uDE59\uDE80-\uDEB7\uDEC0-\uDEC9\uDF00-\uDF19\uDF1D-\uDF2B\uDF30-\uDF39]|\uD806[\uDCA0-\uDCE9\uDCFF\uDE00-\uDE3E\uDE47\uDE50-\uDE83\uDE86-\uDE99\uDEC0-\uDEF8]|\uD807[\uDC00-\uDC08\uDC0A-\uDC36\uDC38-\uDC40\uDC50-\uDC59\uDC72-\uDC8F\uDC92-\uDCA7\uDCA9-\uDCB6\uDD00-\uDD06\uDD08\uDD09\uDD0B-\uDD36\uDD3A\uDD3C\uDD3D\uDD3F-\uDD47\uDD50-\uDD59]|\uD808[\uDC00-\uDF99]|\uD809[\uDC00-\uDC6E\uDC80-\uDD43]|[\uD80C\uD81C-\uD820\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872\uD874-\uD879][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD811[\uDC00-\uDE46]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDE60-\uDE69\uDED0-\uDEED\uDEF0-\uDEF4\uDF00-\uDF36\uDF40-\uDF43\uDF50-\uDF59\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDF00-\uDF44\uDF50-\uDF7E\uDF8F-\uDF9F\uDFE0\uDFE1]|\uD821[\uDC00-\uDFEC]|\uD822[\uDC00-\uDEF2]|\uD82C[\uDC00-\uDD1E\uDD70-\uDEFB]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99\uDC9D\uDC9E]|\uD834[\uDD65-\uDD69\uDD6D-\uDD72\uDD7B-\uDD82\uDD85-\uDD8B\uDDAA-\uDDAD\uDE42-\uDE44]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB\uDFCE-\uDFFF]|\uD836[\uDE00-\uDE36\uDE3B-\uDE6C\uDE75\uDE84\uDE9B-\uDE9F\uDEA1-\uDEAF]|\uD838[\uDC00-\uDC06\uDC08-\uDC18\uDC1B-\uDC21\uDC23\uDC24\uDC26-\uDC2A]|\uD83A[\uDC00-\uDCC4\uDCD0-\uDCD6\uDD00-\uDD4A\uDD50-\uDD59]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1\uDEB0-\uDFFF]|\uD87A[\uDC00-\uDFE0]|\uD87E[\uDC00-\uDE1D]|\uDB40[\uDD00-\uDDEF]/
269
+ };
270
+ var util = {
271
+ isSpaceSeparator: function isSpaceSeparator(c) {
272
+ return typeof c === "string" && unicode.Space_Separator.test(c);
273
+ },
274
+ isIdStartChar: function isIdStartChar(c) {
275
+ return typeof c === "string" && (c >= "a" && c <= "z" || c >= "A" && c <= "Z" || c === "$" || c === "_" || unicode.ID_Start.test(c));
276
+ },
277
+ isIdContinueChar: function isIdContinueChar(c) {
278
+ return typeof c === "string" && (c >= "a" && c <= "z" || c >= "A" && c <= "Z" || c >= "0" && c <= "9" || c === "$" || c === "_" || c === "‌" || c === "‍" || unicode.ID_Continue.test(c));
279
+ },
280
+ isDigit: function isDigit(c) {
281
+ return typeof c === "string" && /[0-9]/.test(c);
282
+ },
283
+ isHexDigit: function isHexDigit(c) {
284
+ return typeof c === "string" && /[0-9A-Fa-f]/.test(c);
285
+ }
286
+ };
287
+ var source;
288
+ var parseState;
289
+ var stack;
290
+ var pos;
291
+ var line;
292
+ var column;
293
+ var token;
294
+ var key;
295
+ var root;
296
+ var parse = function parse(text, reviver) {
297
+ source = String(text);
298
+ parseState = "start";
299
+ stack = [];
300
+ pos = 0;
301
+ line = 1;
302
+ column = 0;
303
+ token = void 0;
304
+ key = void 0;
305
+ root = void 0;
306
+ do {
307
+ token = lex();
308
+ parseStates[parseState]();
309
+ } while (token.type !== "eof");
310
+ if (typeof reviver === "function") return internalize({ "": root }, "", reviver);
311
+ return root;
312
+ };
313
+ function internalize(holder, name, reviver) {
314
+ var value = holder[name];
315
+ if (value != null && typeof value === "object") {
316
+ if (Array.isArray(value)) for (var i = 0; i < value.length; i++) {
317
+ var key = String(i);
318
+ var replacement = internalize(value, key, reviver);
319
+ if (replacement === void 0) delete value[key];
320
+ else Object.defineProperty(value, key, {
321
+ value: replacement,
322
+ writable: true,
323
+ enumerable: true,
324
+ configurable: true
325
+ });
326
+ }
327
+ else for (var key$1 in value) {
328
+ var replacement$1 = internalize(value, key$1, reviver);
329
+ if (replacement$1 === void 0) delete value[key$1];
330
+ else Object.defineProperty(value, key$1, {
331
+ value: replacement$1,
332
+ writable: true,
333
+ enumerable: true,
334
+ configurable: true
335
+ });
80
336
  }
81
337
  }
82
- let endPos = 0;
83
- for (let j = i + 1; j < lines.length; j++) if (lines[j].trim() === ":::") {
84
- let endCharPos = 0;
85
- for (let l = 0; l < j; l++) endCharPos += lines[l].length + 1;
86
- endPos = endCharPos;
87
- i = j + 1;
88
- break;
338
+ return reviver.call(holder, name, value);
339
+ }
340
+ var lexState;
341
+ var buffer;
342
+ var doubleQuote;
343
+ var sign;
344
+ var c;
345
+ function lex() {
346
+ lexState = "default";
347
+ buffer = "";
348
+ doubleQuote = false;
349
+ sign = 1;
350
+ for (;;) {
351
+ c = peek();
352
+ var token = lexStates[lexState]();
353
+ if (token) return token;
89
354
  }
90
- containers.push({
91
- startPos: charPos,
92
- typeName,
93
- propsLineFrom,
94
- propsLineTo,
95
- props,
96
- endPos
97
- });
98
355
  }
99
- i++;
100
- }
101
- return containers;
102
- }
103
- //#endregion
104
- //#region src/registry/componentRegistry.tsx
105
- /**
106
- * 组件注册中心,用于管理自定义组件的 schema。
107
- * 每个容器组件(如 :::linkCard)在此注册其可编辑字段。
108
- */
356
+ function peek() {
357
+ if (source[pos]) return String.fromCodePoint(source.codePointAt(pos));
358
+ }
359
+ function read() {
360
+ var c = peek();
361
+ if (c === "\n") {
362
+ line++;
363
+ column = 0;
364
+ } else if (c) column += c.length;
365
+ else column++;
366
+ if (c) pos += c.length;
367
+ return c;
368
+ }
369
+ var lexStates = {
370
+ default: function default$1() {
371
+ switch (c) {
372
+ case " ":
373
+ case "\v":
374
+ case "\f":
375
+ case " ":
376
+ case "\xA0":
377
+ case "":
378
+ case "\n":
379
+ case "\r":
380
+ case "\u2028":
381
+ case "\u2029":
382
+ read();
383
+ return;
384
+ case "/":
385
+ read();
386
+ lexState = "comment";
387
+ return;
388
+ case void 0:
389
+ read();
390
+ return newToken("eof");
391
+ }
392
+ if (util.isSpaceSeparator(c)) {
393
+ read();
394
+ return;
395
+ }
396
+ return lexStates[parseState]();
397
+ },
398
+ comment: function comment() {
399
+ switch (c) {
400
+ case "*":
401
+ read();
402
+ lexState = "multiLineComment";
403
+ return;
404
+ case "/":
405
+ read();
406
+ lexState = "singleLineComment";
407
+ return;
408
+ }
409
+ throw invalidChar(read());
410
+ },
411
+ multiLineComment: function multiLineComment() {
412
+ switch (c) {
413
+ case "*":
414
+ read();
415
+ lexState = "multiLineCommentAsterisk";
416
+ return;
417
+ case void 0: throw invalidChar(read());
418
+ }
419
+ read();
420
+ },
421
+ multiLineCommentAsterisk: function multiLineCommentAsterisk() {
422
+ switch (c) {
423
+ case "*":
424
+ read();
425
+ return;
426
+ case "/":
427
+ read();
428
+ lexState = "default";
429
+ return;
430
+ case void 0: throw invalidChar(read());
431
+ }
432
+ read();
433
+ lexState = "multiLineComment";
434
+ },
435
+ singleLineComment: function singleLineComment() {
436
+ switch (c) {
437
+ case "\n":
438
+ case "\r":
439
+ case "\u2028":
440
+ case "\u2029":
441
+ read();
442
+ lexState = "default";
443
+ return;
444
+ case void 0:
445
+ read();
446
+ return newToken("eof");
447
+ }
448
+ read();
449
+ },
450
+ value: function value() {
451
+ switch (c) {
452
+ case "{":
453
+ case "[": return newToken("punctuator", read());
454
+ case "n":
455
+ read();
456
+ literal("ull");
457
+ return newToken("null", null);
458
+ case "t":
459
+ read();
460
+ literal("rue");
461
+ return newToken("boolean", true);
462
+ case "f":
463
+ read();
464
+ literal("alse");
465
+ return newToken("boolean", false);
466
+ case "-":
467
+ case "+":
468
+ if (read() === "-") sign = -1;
469
+ lexState = "sign";
470
+ return;
471
+ case ".":
472
+ buffer = read();
473
+ lexState = "decimalPointLeading";
474
+ return;
475
+ case "0":
476
+ buffer = read();
477
+ lexState = "zero";
478
+ return;
479
+ case "1":
480
+ case "2":
481
+ case "3":
482
+ case "4":
483
+ case "5":
484
+ case "6":
485
+ case "7":
486
+ case "8":
487
+ case "9":
488
+ buffer = read();
489
+ lexState = "decimalInteger";
490
+ return;
491
+ case "I":
492
+ read();
493
+ literal("nfinity");
494
+ return newToken("numeric", Infinity);
495
+ case "N":
496
+ read();
497
+ literal("aN");
498
+ return newToken("numeric", NaN);
499
+ case "\"":
500
+ case "'":
501
+ doubleQuote = read() === "\"";
502
+ buffer = "";
503
+ lexState = "string";
504
+ return;
505
+ }
506
+ throw invalidChar(read());
507
+ },
508
+ identifierNameStartEscape: function identifierNameStartEscape() {
509
+ if (c !== "u") throw invalidChar(read());
510
+ read();
511
+ var u = unicodeEscape();
512
+ switch (u) {
513
+ case "$":
514
+ case "_": break;
515
+ default: if (!util.isIdStartChar(u)) throw invalidIdentifier();
516
+ }
517
+ buffer += u;
518
+ lexState = "identifierName";
519
+ },
520
+ identifierName: function identifierName() {
521
+ switch (c) {
522
+ case "$":
523
+ case "_":
524
+ case "‌":
525
+ case "‍":
526
+ buffer += read();
527
+ return;
528
+ case "\\":
529
+ read();
530
+ lexState = "identifierNameEscape";
531
+ return;
532
+ }
533
+ if (util.isIdContinueChar(c)) {
534
+ buffer += read();
535
+ return;
536
+ }
537
+ return newToken("identifier", buffer);
538
+ },
539
+ identifierNameEscape: function identifierNameEscape() {
540
+ if (c !== "u") throw invalidChar(read());
541
+ read();
542
+ var u = unicodeEscape();
543
+ switch (u) {
544
+ case "$":
545
+ case "_":
546
+ case "‌":
547
+ case "‍": break;
548
+ default: if (!util.isIdContinueChar(u)) throw invalidIdentifier();
549
+ }
550
+ buffer += u;
551
+ lexState = "identifierName";
552
+ },
553
+ sign: function sign$1() {
554
+ switch (c) {
555
+ case ".":
556
+ buffer = read();
557
+ lexState = "decimalPointLeading";
558
+ return;
559
+ case "0":
560
+ buffer = read();
561
+ lexState = "zero";
562
+ return;
563
+ case "1":
564
+ case "2":
565
+ case "3":
566
+ case "4":
567
+ case "5":
568
+ case "6":
569
+ case "7":
570
+ case "8":
571
+ case "9":
572
+ buffer = read();
573
+ lexState = "decimalInteger";
574
+ return;
575
+ case "I":
576
+ read();
577
+ literal("nfinity");
578
+ return newToken("numeric", sign * Infinity);
579
+ case "N":
580
+ read();
581
+ literal("aN");
582
+ return newToken("numeric", NaN);
583
+ }
584
+ throw invalidChar(read());
585
+ },
586
+ zero: function zero() {
587
+ switch (c) {
588
+ case ".":
589
+ buffer += read();
590
+ lexState = "decimalPoint";
591
+ return;
592
+ case "e":
593
+ case "E":
594
+ buffer += read();
595
+ lexState = "decimalExponent";
596
+ return;
597
+ case "x":
598
+ case "X":
599
+ buffer += read();
600
+ lexState = "hexadecimal";
601
+ return;
602
+ }
603
+ return newToken("numeric", sign * 0);
604
+ },
605
+ decimalInteger: function decimalInteger() {
606
+ switch (c) {
607
+ case ".":
608
+ buffer += read();
609
+ lexState = "decimalPoint";
610
+ return;
611
+ case "e":
612
+ case "E":
613
+ buffer += read();
614
+ lexState = "decimalExponent";
615
+ return;
616
+ }
617
+ if (util.isDigit(c)) {
618
+ buffer += read();
619
+ return;
620
+ }
621
+ return newToken("numeric", sign * Number(buffer));
622
+ },
623
+ decimalPointLeading: function decimalPointLeading() {
624
+ if (util.isDigit(c)) {
625
+ buffer += read();
626
+ lexState = "decimalFraction";
627
+ return;
628
+ }
629
+ throw invalidChar(read());
630
+ },
631
+ decimalPoint: function decimalPoint() {
632
+ switch (c) {
633
+ case "e":
634
+ case "E":
635
+ buffer += read();
636
+ lexState = "decimalExponent";
637
+ return;
638
+ }
639
+ if (util.isDigit(c)) {
640
+ buffer += read();
641
+ lexState = "decimalFraction";
642
+ return;
643
+ }
644
+ return newToken("numeric", sign * Number(buffer));
645
+ },
646
+ decimalFraction: function decimalFraction() {
647
+ switch (c) {
648
+ case "e":
649
+ case "E":
650
+ buffer += read();
651
+ lexState = "decimalExponent";
652
+ return;
653
+ }
654
+ if (util.isDigit(c)) {
655
+ buffer += read();
656
+ return;
657
+ }
658
+ return newToken("numeric", sign * Number(buffer));
659
+ },
660
+ decimalExponent: function decimalExponent() {
661
+ switch (c) {
662
+ case "+":
663
+ case "-":
664
+ buffer += read();
665
+ lexState = "decimalExponentSign";
666
+ return;
667
+ }
668
+ if (util.isDigit(c)) {
669
+ buffer += read();
670
+ lexState = "decimalExponentInteger";
671
+ return;
672
+ }
673
+ throw invalidChar(read());
674
+ },
675
+ decimalExponentSign: function decimalExponentSign() {
676
+ if (util.isDigit(c)) {
677
+ buffer += read();
678
+ lexState = "decimalExponentInteger";
679
+ return;
680
+ }
681
+ throw invalidChar(read());
682
+ },
683
+ decimalExponentInteger: function decimalExponentInteger() {
684
+ if (util.isDigit(c)) {
685
+ buffer += read();
686
+ return;
687
+ }
688
+ return newToken("numeric", sign * Number(buffer));
689
+ },
690
+ hexadecimal: function hexadecimal() {
691
+ if (util.isHexDigit(c)) {
692
+ buffer += read();
693
+ lexState = "hexadecimalInteger";
694
+ return;
695
+ }
696
+ throw invalidChar(read());
697
+ },
698
+ hexadecimalInteger: function hexadecimalInteger() {
699
+ if (util.isHexDigit(c)) {
700
+ buffer += read();
701
+ return;
702
+ }
703
+ return newToken("numeric", sign * Number(buffer));
704
+ },
705
+ string: function string() {
706
+ switch (c) {
707
+ case "\\":
708
+ read();
709
+ buffer += escape();
710
+ return;
711
+ case "\"":
712
+ if (doubleQuote) {
713
+ read();
714
+ return newToken("string", buffer);
715
+ }
716
+ buffer += read();
717
+ return;
718
+ case "'":
719
+ if (!doubleQuote) {
720
+ read();
721
+ return newToken("string", buffer);
722
+ }
723
+ buffer += read();
724
+ return;
725
+ case "\n":
726
+ case "\r": throw invalidChar(read());
727
+ case "\u2028":
728
+ case "\u2029":
729
+ separatorChar(c);
730
+ break;
731
+ case void 0: throw invalidChar(read());
732
+ }
733
+ buffer += read();
734
+ },
735
+ start: function start() {
736
+ switch (c) {
737
+ case "{":
738
+ case "[": return newToken("punctuator", read());
739
+ }
740
+ lexState = "value";
741
+ },
742
+ beforePropertyName: function beforePropertyName() {
743
+ switch (c) {
744
+ case "$":
745
+ case "_":
746
+ buffer = read();
747
+ lexState = "identifierName";
748
+ return;
749
+ case "\\":
750
+ read();
751
+ lexState = "identifierNameStartEscape";
752
+ return;
753
+ case "}": return newToken("punctuator", read());
754
+ case "\"":
755
+ case "'":
756
+ doubleQuote = read() === "\"";
757
+ lexState = "string";
758
+ return;
759
+ }
760
+ if (util.isIdStartChar(c)) {
761
+ buffer += read();
762
+ lexState = "identifierName";
763
+ return;
764
+ }
765
+ throw invalidChar(read());
766
+ },
767
+ afterPropertyName: function afterPropertyName() {
768
+ if (c === ":") return newToken("punctuator", read());
769
+ throw invalidChar(read());
770
+ },
771
+ beforePropertyValue: function beforePropertyValue() {
772
+ lexState = "value";
773
+ },
774
+ afterPropertyValue: function afterPropertyValue() {
775
+ switch (c) {
776
+ case ",":
777
+ case "}": return newToken("punctuator", read());
778
+ }
779
+ throw invalidChar(read());
780
+ },
781
+ beforeArrayValue: function beforeArrayValue() {
782
+ if (c === "]") return newToken("punctuator", read());
783
+ lexState = "value";
784
+ },
785
+ afterArrayValue: function afterArrayValue() {
786
+ switch (c) {
787
+ case ",":
788
+ case "]": return newToken("punctuator", read());
789
+ }
790
+ throw invalidChar(read());
791
+ },
792
+ end: function end() {
793
+ throw invalidChar(read());
794
+ }
795
+ };
796
+ function newToken(type, value) {
797
+ return {
798
+ type,
799
+ value,
800
+ line,
801
+ column
802
+ };
803
+ }
804
+ function literal(s) {
805
+ for (var i = 0, list = s; i < list.length; i += 1) {
806
+ var c = list[i];
807
+ if (peek() !== c) throw invalidChar(read());
808
+ read();
809
+ }
810
+ }
811
+ function escape() {
812
+ switch (peek()) {
813
+ case "b":
814
+ read();
815
+ return "\b";
816
+ case "f":
817
+ read();
818
+ return "\f";
819
+ case "n":
820
+ read();
821
+ return "\n";
822
+ case "r":
823
+ read();
824
+ return "\r";
825
+ case "t":
826
+ read();
827
+ return " ";
828
+ case "v":
829
+ read();
830
+ return "\v";
831
+ case "0":
832
+ read();
833
+ if (util.isDigit(peek())) throw invalidChar(read());
834
+ return "\0";
835
+ case "x":
836
+ read();
837
+ return hexEscape();
838
+ case "u":
839
+ read();
840
+ return unicodeEscape();
841
+ case "\n":
842
+ case "\u2028":
843
+ case "\u2029":
844
+ read();
845
+ return "";
846
+ case "\r":
847
+ read();
848
+ if (peek() === "\n") read();
849
+ return "";
850
+ case "1":
851
+ case "2":
852
+ case "3":
853
+ case "4":
854
+ case "5":
855
+ case "6":
856
+ case "7":
857
+ case "8":
858
+ case "9": throw invalidChar(read());
859
+ case void 0: throw invalidChar(read());
860
+ }
861
+ return read();
862
+ }
863
+ function hexEscape() {
864
+ var buffer = "";
865
+ var c = peek();
866
+ if (!util.isHexDigit(c)) throw invalidChar(read());
867
+ buffer += read();
868
+ c = peek();
869
+ if (!util.isHexDigit(c)) throw invalidChar(read());
870
+ buffer += read();
871
+ return String.fromCodePoint(parseInt(buffer, 16));
872
+ }
873
+ function unicodeEscape() {
874
+ var buffer = "";
875
+ var count = 4;
876
+ while (count-- > 0) {
877
+ var c = peek();
878
+ if (!util.isHexDigit(c)) throw invalidChar(read());
879
+ buffer += read();
880
+ }
881
+ return String.fromCodePoint(parseInt(buffer, 16));
882
+ }
883
+ var parseStates = {
884
+ start: function start() {
885
+ if (token.type === "eof") throw invalidEOF();
886
+ push();
887
+ },
888
+ beforePropertyName: function beforePropertyName() {
889
+ switch (token.type) {
890
+ case "identifier":
891
+ case "string":
892
+ key = token.value;
893
+ parseState = "afterPropertyName";
894
+ return;
895
+ case "punctuator":
896
+ pop();
897
+ return;
898
+ case "eof": throw invalidEOF();
899
+ }
900
+ },
901
+ afterPropertyName: function afterPropertyName() {
902
+ if (token.type === "eof") throw invalidEOF();
903
+ parseState = "beforePropertyValue";
904
+ },
905
+ beforePropertyValue: function beforePropertyValue() {
906
+ if (token.type === "eof") throw invalidEOF();
907
+ push();
908
+ },
909
+ beforeArrayValue: function beforeArrayValue() {
910
+ if (token.type === "eof") throw invalidEOF();
911
+ if (token.type === "punctuator" && token.value === "]") {
912
+ pop();
913
+ return;
914
+ }
915
+ push();
916
+ },
917
+ afterPropertyValue: function afterPropertyValue() {
918
+ if (token.type === "eof") throw invalidEOF();
919
+ switch (token.value) {
920
+ case ",":
921
+ parseState = "beforePropertyName";
922
+ return;
923
+ case "}": pop();
924
+ }
925
+ },
926
+ afterArrayValue: function afterArrayValue() {
927
+ if (token.type === "eof") throw invalidEOF();
928
+ switch (token.value) {
929
+ case ",":
930
+ parseState = "beforeArrayValue";
931
+ return;
932
+ case "]": pop();
933
+ }
934
+ },
935
+ end: function end() {}
936
+ };
937
+ function push() {
938
+ var value;
939
+ switch (token.type) {
940
+ case "punctuator":
941
+ switch (token.value) {
942
+ case "{":
943
+ value = {};
944
+ break;
945
+ case "[": value = [];
946
+ }
947
+ break;
948
+ case "null":
949
+ case "boolean":
950
+ case "numeric":
951
+ case "string": value = token.value;
952
+ }
953
+ if (root === void 0) root = value;
954
+ else {
955
+ var parent = stack[stack.length - 1];
956
+ if (Array.isArray(parent)) parent.push(value);
957
+ else Object.defineProperty(parent, key, {
958
+ value,
959
+ writable: true,
960
+ enumerable: true,
961
+ configurable: true
962
+ });
963
+ }
964
+ if (value !== null && typeof value === "object") {
965
+ stack.push(value);
966
+ if (Array.isArray(value)) parseState = "beforeArrayValue";
967
+ else parseState = "beforePropertyName";
968
+ } else {
969
+ var current = stack[stack.length - 1];
970
+ if (current == null) parseState = "end";
971
+ else if (Array.isArray(current)) parseState = "afterArrayValue";
972
+ else parseState = "afterPropertyValue";
973
+ }
974
+ }
975
+ function pop() {
976
+ stack.pop();
977
+ var current = stack[stack.length - 1];
978
+ if (current == null) parseState = "end";
979
+ else if (Array.isArray(current)) parseState = "afterArrayValue";
980
+ else parseState = "afterPropertyValue";
981
+ }
982
+ function invalidChar(c) {
983
+ if (c === void 0) return syntaxError("JSON5: invalid end of input at " + line + ":" + column);
984
+ return syntaxError("JSON5: invalid character '" + formatChar(c) + "' at " + line + ":" + column);
985
+ }
986
+ function invalidEOF() {
987
+ return syntaxError("JSON5: invalid end of input at " + line + ":" + column);
988
+ }
989
+ function invalidIdentifier() {
990
+ column -= 5;
991
+ return syntaxError("JSON5: invalid identifier character at " + line + ":" + column);
992
+ }
993
+ function separatorChar(c) {
994
+ console.warn("JSON5: '" + formatChar(c) + "' in strings is not valid ECMAScript; consider escaping");
995
+ }
996
+ function formatChar(c) {
997
+ var replacements = {
998
+ "'": "\\'",
999
+ "\"": "\\\"",
1000
+ "\\": "\\\\",
1001
+ "\b": "\\b",
1002
+ "\f": "\\f",
1003
+ "\n": "\\n",
1004
+ "\r": "\\r",
1005
+ " ": "\\t",
1006
+ "\v": "\\v",
1007
+ "\0": "\\0",
1008
+ "\u2028": "\\u2028",
1009
+ "\u2029": "\\u2029"
1010
+ };
1011
+ if (replacements[c]) return replacements[c];
1012
+ if (c < " ") {
1013
+ var hexString = c.charCodeAt(0).toString(16);
1014
+ return "\\x" + ("00" + hexString).substring(hexString.length);
1015
+ }
1016
+ return c;
1017
+ }
1018
+ function syntaxError(message) {
1019
+ var err = new SyntaxError(message);
1020
+ err.lineNumber = line;
1021
+ err.columnNumber = column;
1022
+ return err;
1023
+ }
1024
+ return {
1025
+ parse,
1026
+ stringify: function stringify(value, replacer, space) {
1027
+ var stack = [];
1028
+ var indent = "";
1029
+ var propertyList;
1030
+ var replacerFunc;
1031
+ var gap = "";
1032
+ var quote;
1033
+ if (replacer != null && typeof replacer === "object" && !Array.isArray(replacer)) {
1034
+ space = replacer.space;
1035
+ quote = replacer.quote;
1036
+ replacer = replacer.replacer;
1037
+ }
1038
+ if (typeof replacer === "function") replacerFunc = replacer;
1039
+ else if (Array.isArray(replacer)) {
1040
+ propertyList = [];
1041
+ for (var i = 0, list = replacer; i < list.length; i += 1) {
1042
+ var v = list[i];
1043
+ var item = void 0;
1044
+ if (typeof v === "string") item = v;
1045
+ else if (typeof v === "number" || v instanceof String || v instanceof Number) item = String(v);
1046
+ if (item !== void 0 && propertyList.indexOf(item) < 0) propertyList.push(item);
1047
+ }
1048
+ }
1049
+ if (space instanceof Number) space = Number(space);
1050
+ else if (space instanceof String) space = String(space);
1051
+ if (typeof space === "number") {
1052
+ if (space > 0) {
1053
+ space = Math.min(10, Math.floor(space));
1054
+ gap = " ".substr(0, space);
1055
+ }
1056
+ } else if (typeof space === "string") gap = space.substr(0, 10);
1057
+ return serializeProperty("", { "": value });
1058
+ function serializeProperty(key, holder) {
1059
+ var value = holder[key];
1060
+ if (value != null) {
1061
+ if (typeof value.toJSON5 === "function") value = value.toJSON5(key);
1062
+ else if (typeof value.toJSON === "function") value = value.toJSON(key);
1063
+ }
1064
+ if (replacerFunc) value = replacerFunc.call(holder, key, value);
1065
+ if (value instanceof Number) value = Number(value);
1066
+ else if (value instanceof String) value = String(value);
1067
+ else if (value instanceof Boolean) value = value.valueOf();
1068
+ switch (value) {
1069
+ case null: return "null";
1070
+ case true: return "true";
1071
+ case false: return "false";
1072
+ }
1073
+ if (typeof value === "string") return quoteString(value, false);
1074
+ if (typeof value === "number") return String(value);
1075
+ if (typeof value === "object") return Array.isArray(value) ? serializeArray(value) : serializeObject(value);
1076
+ }
1077
+ function quoteString(value) {
1078
+ var quotes = {
1079
+ "'": .1,
1080
+ "\"": .2
1081
+ };
1082
+ var replacements = {
1083
+ "'": "\\'",
1084
+ "\"": "\\\"",
1085
+ "\\": "\\\\",
1086
+ "\b": "\\b",
1087
+ "\f": "\\f",
1088
+ "\n": "\\n",
1089
+ "\r": "\\r",
1090
+ " ": "\\t",
1091
+ "\v": "\\v",
1092
+ "\0": "\\0",
1093
+ "\u2028": "\\u2028",
1094
+ "\u2029": "\\u2029"
1095
+ };
1096
+ var product = "";
1097
+ for (var i = 0; i < value.length; i++) {
1098
+ var c = value[i];
1099
+ switch (c) {
1100
+ case "'":
1101
+ case "\"":
1102
+ quotes[c]++;
1103
+ product += c;
1104
+ continue;
1105
+ case "\0": if (util.isDigit(value[i + 1])) {
1106
+ product += "\\x00";
1107
+ continue;
1108
+ }
1109
+ }
1110
+ if (replacements[c]) {
1111
+ product += replacements[c];
1112
+ continue;
1113
+ }
1114
+ if (c < " ") {
1115
+ var hexString = c.charCodeAt(0).toString(16);
1116
+ product += "\\x" + ("00" + hexString).substring(hexString.length);
1117
+ continue;
1118
+ }
1119
+ product += c;
1120
+ }
1121
+ var quoteChar = quote || Object.keys(quotes).reduce(function(a, b) {
1122
+ return quotes[a] < quotes[b] ? a : b;
1123
+ });
1124
+ product = product.replace(new RegExp(quoteChar, "g"), replacements[quoteChar]);
1125
+ return quoteChar + product + quoteChar;
1126
+ }
1127
+ function serializeObject(value) {
1128
+ if (stack.indexOf(value) >= 0) throw TypeError("Converting circular structure to JSON5");
1129
+ stack.push(value);
1130
+ var stepback = indent;
1131
+ indent = indent + gap;
1132
+ var keys = propertyList || Object.keys(value);
1133
+ var partial = [];
1134
+ for (var i = 0, list = keys; i < list.length; i += 1) {
1135
+ var key = list[i];
1136
+ var propertyString = serializeProperty(key, value);
1137
+ if (propertyString !== void 0) {
1138
+ var member = serializeKey(key) + ":";
1139
+ if (gap !== "") member += " ";
1140
+ member += propertyString;
1141
+ partial.push(member);
1142
+ }
1143
+ }
1144
+ var final;
1145
+ if (partial.length === 0) final = "{}";
1146
+ else {
1147
+ var properties;
1148
+ if (gap === "") {
1149
+ properties = partial.join(",");
1150
+ final = "{" + properties + "}";
1151
+ } else {
1152
+ var separator = ",\n" + indent;
1153
+ properties = partial.join(separator);
1154
+ final = "{\n" + indent + properties + ",\n" + stepback + "}";
1155
+ }
1156
+ }
1157
+ stack.pop();
1158
+ indent = stepback;
1159
+ return final;
1160
+ }
1161
+ function serializeKey(key) {
1162
+ if (key.length === 0) return quoteString(key, true);
1163
+ var firstChar = String.fromCodePoint(key.codePointAt(0));
1164
+ if (!util.isIdStartChar(firstChar)) return quoteString(key, true);
1165
+ for (var i = firstChar.length; i < key.length; i++) if (!util.isIdContinueChar(String.fromCodePoint(key.codePointAt(i)))) return quoteString(key, true);
1166
+ return key;
1167
+ }
1168
+ function serializeArray(value) {
1169
+ if (stack.indexOf(value) >= 0) throw TypeError("Converting circular structure to JSON5");
1170
+ stack.push(value);
1171
+ var stepback = indent;
1172
+ indent = indent + gap;
1173
+ var partial = [];
1174
+ for (var i = 0; i < value.length; i++) {
1175
+ var propertyString = serializeProperty(String(i), value);
1176
+ partial.push(propertyString !== void 0 ? propertyString : "null");
1177
+ }
1178
+ var final;
1179
+ if (partial.length === 0) final = "[]";
1180
+ else if (gap === "") final = "[" + partial.join(",") + "]";
1181
+ else {
1182
+ var separator = ",\n" + indent;
1183
+ var properties$1 = partial.join(separator);
1184
+ final = "[\n" + indent + properties$1 + ",\n" + stepback + "]";
1185
+ }
1186
+ stack.pop();
1187
+ indent = stepback;
1188
+ return final;
1189
+ }
1190
+ }
1191
+ };
1192
+ }));
1193
+ })))(), 1);
109
1194
  var ComponentRegistry = class {
110
1195
  schemas = /* @__PURE__ */ new Map();
1196
+ listeners = /* @__PURE__ */ new Set();
1197
+ version = 0;
111
1198
  /**
112
1199
  * 注册组件 schema
113
1200
  */
114
1201
  register(name, schema) {
115
1202
  this.schemas.set(name, schema);
1203
+ this.emit();
1204
+ }
1205
+ /**
1206
+ * 移除组件注册
1207
+ */
1208
+ unregister(name) {
1209
+ if (this.schemas.delete(name)) this.emit();
1210
+ }
1211
+ /**
1212
+ * 当前版本号,任意注册变更都会自增
1213
+ */
1214
+ getVersion() {
1215
+ return this.version;
1216
+ }
1217
+ /**
1218
+ * 订阅注册变更,返回退订函数
1219
+ */
1220
+ subscribe(listener) {
1221
+ this.listeners.add(listener);
1222
+ return () => {
1223
+ this.listeners.delete(listener);
1224
+ };
1225
+ }
1226
+ emit() {
1227
+ this.version += 1;
1228
+ this.listeners.forEach((listener) => listener(this.version));
116
1229
  }
117
1230
  /**
118
1231
  * 根据组件名获取已注册的 schema
@@ -138,47 +1251,164 @@ var ComponentRegistry = class {
138
1251
  getAll() {
139
1252
  return Array.from(this.schemas.values());
140
1253
  }
141
- /**
142
- * 移除组件注册
143
- */
144
- unregister(name) {
145
- this.schemas.delete(name);
146
- }
147
1254
  };
148
1255
  var componentRegistry = new ComponentRegistry();
149
1256
  //#endregion
1257
+ //#region src/utils/parseContainer.ts
1258
+ /**
1259
+ * 解析容器属性行。
1260
+ * 优先按 JSON5 解析(兼容标准 JSON 与 { key: 'value' } 宽松写法),
1261
+ * 失败时返回空对象,保证往返编辑不丢数据。
1262
+ */
1263
+ function parseContainerProps(line) {
1264
+ const trimmed = line.trim();
1265
+ if (!trimmed.startsWith("{") || !trimmed.endsWith("}")) return {};
1266
+ try {
1267
+ const parsed = import_dist.default.parse(trimmed);
1268
+ if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) return {};
1269
+ const props = {};
1270
+ for (const [key, value] of Object.entries(parsed)) {
1271
+ if (value === null || value === void 0) continue;
1272
+ if (typeof value === "object") continue;
1273
+ props[key] = value;
1274
+ }
1275
+ return props;
1276
+ } catch {
1277
+ return {};
1278
+ }
1279
+ }
1280
+ /**
1281
+ * 解析行首的引用(blockquote)嵌套前缀。
1282
+ * markdown-it 解析引用内部内容时会剥掉一层 "> ",因此 "> :::badge" 在渲染侧
1283
+ * 等同于 ":::badge";编辑器侧需同样识别,否则嵌套引用的容器匹配不到标签。
1284
+ * 返回 [前缀文本(含 "> " 及尾随空格), 去掉前缀后的内容],无前缀时返回 ['', 原文本]。
1285
+ */
1286
+ function splitQuotePrefix(line) {
1287
+ const m = line.match(/^((?:>\s*)+)(\S.*)$/);
1288
+ if (!m) return ["", line];
1289
+ return [m[1], m[2]];
1290
+ }
1291
+ /** 引用嵌套深度("> > x" 为 2,无前缀为 0) */
1292
+ function quoteDepth(prefix) {
1293
+ return (prefix.match(/>/g) ?? []).length;
1294
+ }
1295
+ /**
1296
+ * 在编辑器文档中查找容器块。
1297
+ * 单次遍历 + 预累计行偏移,复杂度 O(行数)。
1298
+ * 支持整体嵌套在引用中的容器:头行、属性行、闭合行需具有相同的 "> " 前缀深度,
1299
+ * 避免跨引用层级错误配对。闭合 ::: 改为按栈配对,嵌套容器不会被内层闭合误截断。
1300
+ */
1301
+ function findContainers(docText) {
1302
+ const containers = [];
1303
+ const lines = docText.split("\n");
1304
+ const offsets = new Array(lines.length);
1305
+ let pos = 0;
1306
+ for (let i = 0; i < lines.length; i++) {
1307
+ offsets[i] = pos;
1308
+ pos += lines[i].length + 1;
1309
+ }
1310
+ const stack = [];
1311
+ for (let i = 0; i < lines.length; i++) {
1312
+ const [prefix, body] = splitQuotePrefix(lines[i]);
1313
+ const depth = quoteDepth(prefix);
1314
+ if (/^:::$/.test(body)) {
1315
+ let top = stack.length - 1;
1316
+ while (top >= 0 && stack[top].depth !== depth) top--;
1317
+ if (top >= 0) {
1318
+ stack[top].block.endPos = offsets[i];
1319
+ stack.length = top;
1320
+ }
1321
+ continue;
1322
+ }
1323
+ const match = body.match(/^:::(\w+)$/);
1324
+ if (!match) continue;
1325
+ const typeName = match[1];
1326
+ const headerPos = offsets[i];
1327
+ let props = {};
1328
+ let propsLineFrom = 0;
1329
+ let propsLineTo = 0;
1330
+ let propsQuotePrefix = "";
1331
+ const nextLine = lines[i + 1];
1332
+ if (nextLine) {
1333
+ const [nextPrefix, nextBody] = splitQuotePrefix(nextLine);
1334
+ if ((quoteDepth(nextPrefix) === depth || nextPrefix === "") && nextBody.trimStart().startsWith("{") && nextBody.trimEnd().endsWith("}")) {
1335
+ props = parseContainerProps(nextBody);
1336
+ propsLineFrom = offsets[i + 1];
1337
+ propsLineTo = propsLineFrom + nextLine.length;
1338
+ propsQuotePrefix = nextPrefix;
1339
+ i += 1;
1340
+ }
1341
+ }
1342
+ const block = {
1343
+ startPos: headerPos,
1344
+ typeName,
1345
+ propsLineFrom,
1346
+ propsLineTo,
1347
+ props,
1348
+ endPos: 0,
1349
+ registered: componentRegistry.has(typeName),
1350
+ quotePrefix: prefix,
1351
+ propsQuotePrefix
1352
+ };
1353
+ containers.push(block);
1354
+ stack.push({
1355
+ block,
1356
+ depth
1357
+ });
1358
+ }
1359
+ return containers;
1360
+ }
1361
+ //#endregion
150
1362
  //#region src/components/Editor/containerWidget.ts
151
1363
  /**
1364
+ * 唤醒容器装饰重建的状态 effect(不改变文档)。
1365
+ * 编辑按钮是否展示取决于容器类型是否已注册,而宿主常在编辑器挂载之后才
1366
+ * 通过 useRegisterToolbar 异步注册 schema;注册不是 CodeMirror 事务,默认不会触发
1367
+ * ViewPlugin.update,导致初始化时烘焙的 registered=false 无法刷新(需手动改一个字才出现)。
1368
+ * 宿主在注册中心版本变化时 dispatch 本 effect,驱动插件重新求值 registered。
1369
+ */
1370
+ var refreshContainers = _codemirror_state.StateEffect.define();
1371
+ /**
152
1372
  * 自定义 facet 用于传递编辑回调
153
1373
  */
154
- var containerEditCallback = _codemirror_state.Facet.define({ combine: (values) => values[0] });
1374
+ var containerEditCallback = _codemirror_state.Facet.define({ combine: (values) => values.length ? values[values.length - 1] : null });
155
1375
  /**
156
1376
  * 只读的容器头行 Widget(显示 :::typeName + 编辑按钮)
157
- * 使用 Decoration.replace 替换原始文本,使其不可直接编辑
1377
+ * 使用 Decoration.replace 替换原始文本,使其不可直接编辑。
1378
+ * widget 直接携带所属容器索引与类型,点击时无需再做位置猜测。
158
1379
  */
159
1380
  var ContainerHeaderWidget = class extends _codemirror_view.WidgetType {
160
1381
  typeName;
161
- constructor(typeName) {
1382
+ containerIndex;
1383
+ registered;
1384
+ quotePrefix;
1385
+ constructor(typeName, containerIndex, registered, quotePrefix) {
162
1386
  super();
163
1387
  this.typeName = typeName;
1388
+ this.containerIndex = containerIndex;
1389
+ this.registered = registered;
1390
+ this.quotePrefix = quotePrefix;
164
1391
  }
165
1392
  toDOM() {
166
1393
  const container = document.createElement("span");
167
1394
  container.className = "container-widget-header";
168
1395
  const text = document.createElement("span");
169
1396
  text.className = "container-widget-text";
170
- text.textContent = `:::${this.typeName}`;
171
- const button = document.createElement("button");
172
- button.className = "container-edit-btn";
173
- button.title = `编辑 ${componentRegistry.get(this.typeName)?.label ?? this.typeName}`;
174
- button.textContent = "✎";
175
- button.__typeName = this.typeName;
1397
+ text.textContent = `${this.quotePrefix}:::${this.typeName}`;
176
1398
  container.appendChild(text);
177
- container.appendChild(button);
1399
+ if (this.registered) {
1400
+ const button = document.createElement("button");
1401
+ button.className = "container-edit-btn";
1402
+ button.title = `编辑 ${this.typeName}`;
1403
+ button.textContent = "✎";
1404
+ button.dataset.containerIndex = String(this.containerIndex);
1405
+ button.dataset.typeName = this.typeName;
1406
+ container.appendChild(button);
1407
+ }
178
1408
  return container;
179
1409
  }
180
1410
  eq(other) {
181
- return this.typeName === other.typeName;
1411
+ return this.typeName === other.typeName && this.containerIndex === other.containerIndex && this.registered === other.registered && this.quotePrefix === other.quotePrefix;
182
1412
  }
183
1413
  ignoreEvent() {
184
1414
  return false;
@@ -186,40 +1416,46 @@ var ContainerHeaderWidget = class extends _codemirror_view.WidgetType {
186
1416
  };
187
1417
  /**
188
1418
  * 只读的容器属性行 Widget(显示 { key: value, ... })
189
- * 使用 Decoration.replace 替换原始文本,使其不可直接编辑
1419
+ * 嵌套在引用中时原始行带 "> " 前缀,展示时剔除,与头行 widget 风格一致
190
1420
  */
191
1421
  var ContainerPropsWidget = class extends _codemirror_view.WidgetType {
192
1422
  propsText;
193
- constructor(propsText) {
1423
+ quotePrefix;
1424
+ constructor(propsText, quotePrefix) {
194
1425
  super();
195
1426
  this.propsText = propsText;
1427
+ this.quotePrefix = quotePrefix;
196
1428
  }
197
1429
  toDOM() {
198
1430
  const span = document.createElement("span");
199
1431
  span.className = "container-widget-props";
200
- span.textContent = this.propsText;
1432
+ span.textContent = this.propsText.startsWith(this.quotePrefix) ? this.propsText.slice(this.quotePrefix.length) : this.propsText;
201
1433
  return span;
202
1434
  }
203
1435
  eq(other) {
204
- return this.propsText === other.propsText;
1436
+ return this.propsText === other.propsText && this.quotePrefix === other.quotePrefix;
205
1437
  }
206
1438
  ignoreEvent() {
207
1439
  return false;
208
1440
  }
209
1441
  };
210
1442
  /**
211
- * 只读的容器结束行 Widget(显示 :::)
212
- * 使用 Decoration.replace 替换原始文本,使其不可直接编辑
1443
+ * 只读的容器结束行 Widget(显示 :::,嵌套引用时保留 "> " 前缀)
213
1444
  */
214
1445
  var ContainerCloseWidget = class extends _codemirror_view.WidgetType {
1446
+ text;
1447
+ constructor(text) {
1448
+ super();
1449
+ this.text = text;
1450
+ }
215
1451
  toDOM() {
216
1452
  const span = document.createElement("span");
217
1453
  span.className = "container-widget-text";
218
- span.textContent = ":::";
1454
+ span.textContent = this.text;
219
1455
  return span;
220
1456
  }
221
- eq() {
222
- return true;
1457
+ eq(other) {
1458
+ return this.text === other.text;
223
1459
  }
224
1460
  ignoreEvent() {
225
1461
  return false;
@@ -232,20 +1468,19 @@ var ContainerCloseWidget = class extends _codemirror_view.WidgetType {
232
1468
  function findContainerDecorations(state) {
233
1469
  const containers = findContainers(state.doc.toString());
234
1470
  const decorations = [];
235
- for (const container of containers) {
1471
+ containers.forEach((container, index) => {
236
1472
  const headerLine = state.doc.lineAt(container.startPos);
237
1473
  decorations.push({
238
1474
  from: headerLine.from,
239
1475
  to: headerLine.to,
240
- value: _codemirror_view.Decoration.replace({ widget: new ContainerHeaderWidget(container.typeName) })
1476
+ value: _codemirror_view.Decoration.replace({ widget: new ContainerHeaderWidget(container.typeName, index, container.registered, container.quotePrefix ?? "") })
241
1477
  });
242
1478
  if (container.propsLineFrom > 0 && container.propsLineTo > 0) {
243
1479
  const propsLine = state.doc.lineAt(container.propsLineFrom);
244
- const propsText = propsLine.text;
245
1480
  decorations.push({
246
1481
  from: propsLine.from,
247
1482
  to: propsLine.to,
248
- value: _codemirror_view.Decoration.replace({ widget: new ContainerPropsWidget(propsText) })
1483
+ value: _codemirror_view.Decoration.replace({ widget: new ContainerPropsWidget(propsLine.text, container.quotePrefix ?? "") })
249
1484
  });
250
1485
  }
251
1486
  if (container.endPos > 0) {
@@ -253,55 +1488,64 @@ function findContainerDecorations(state) {
253
1488
  decorations.push({
254
1489
  from: endLine.from,
255
1490
  to: endLine.to,
256
- value: _codemirror_view.Decoration.replace({ widget: new ContainerCloseWidget() })
1491
+ value: _codemirror_view.Decoration.replace({ widget: new ContainerCloseWidget(endLine.text) })
257
1492
  });
258
1493
  }
259
- }
1494
+ });
1495
+ decorations.sort((a, b) => a.from - b.from || b.to - a.to);
260
1496
  return decorations;
261
1497
  }
262
1498
  /**
1499
+ * 点击编辑按钮时,依据按钮携带的容器索引回查最新属性并触发回调
1500
+ */
1501
+ function handleEditButtonClick(event, view) {
1502
+ const target = event.target;
1503
+ if (!target.classList.contains("container-edit-btn")) return false;
1504
+ event.preventDefault();
1505
+ event.stopPropagation();
1506
+ const indexAttr = target.dataset.containerIndex;
1507
+ if (indexAttr === void 0) return false;
1508
+ const container = findContainers(view.state.doc.toString())[Number(indexAttr)];
1509
+ if (!container || !container.registered) return false;
1510
+ const callback = view.state.facet(containerEditCallback);
1511
+ if (callback) callback(view, {
1512
+ ...container,
1513
+ props: { ...container.props }
1514
+ });
1515
+ return true;
1516
+ }
1517
+ /**
263
1518
  * 容器编辑 ViewPlugin
264
- * 将容器的 ::: 头行和 {} 属性行替换为只读 widget,使其无法在编辑器中直接编辑
1519
+ * 将容器的 ::: 头行和 {} 属性行替换为只读 widget,使其无法在编辑器中直接编辑。
1520
+ * 仅在文档内容变化时重建装饰,光标移动不触发全文扫描。
265
1521
  */
266
1522
  var containerWidgetPlugin = _codemirror_view.ViewPlugin.fromClass(class {
267
1523
  decorations;
1524
+ /** 上次构建装饰时的注册中心版本,用于感知异步注册(不能标 private,否则导出匿名类的 dts 报 TS4094) */
1525
+ registryVersion;
268
1526
  constructor(view) {
1527
+ this.registryVersion = componentRegistry.getVersion();
269
1528
  this.decorations = _codemirror_view.Decoration.set(findContainerDecorations(view.state), true);
270
1529
  }
271
1530
  update(update) {
272
- if (update.docChanged || update.selectionSet) this.decorations = _codemirror_view.Decoration.set(findContainerDecorations(update.state), true);
1531
+ const registryChanged = componentRegistry.getVersion() !== this.registryVersion;
1532
+ const woken = update.transactions.some((tr) => tr.effects.some((e) => e.is(refreshContainers)));
1533
+ if (update.docChanged || registryChanged || woken) {
1534
+ this.registryVersion = componentRegistry.getVersion();
1535
+ this.decorations = _codemirror_view.Decoration.set(findContainerDecorations(update.state), true);
1536
+ }
273
1537
  }
274
1538
  }, {
275
1539
  decorations: (value) => value.decorations,
276
1540
  eventHandlers: {
277
- mousedown: (event, view) => {
1541
+ mousedown: (event, _view) => {
278
1542
  if (event.target.classList.contains("container-edit-btn")) {
279
1543
  event.preventDefault();
280
1544
  return true;
281
1545
  }
282
1546
  return false;
283
1547
  },
284
- click: (event, view) => {
285
- const target = event.target;
286
- if (target.classList.contains("container-edit-btn")) {
287
- event.preventDefault();
288
- event.stopPropagation();
289
- if (target.__typeName) {
290
- const containers = findContainers(view.state.doc.toString());
291
- const buttonPos = view.posAtDOM(target);
292
- for (const container of containers) {
293
- const headerLine = view.state.doc.lineAt(container.startPos);
294
- if (buttonPos >= headerLine.from - 5 && buttonPos <= headerLine.to + 5) {
295
- const callback = view.state.facet(containerEditCallback);
296
- if (callback) callback(view, container.typeName, container.propsLineFrom, container.propsLineTo, { ...container.props });
297
- return true;
298
- }
299
- }
300
- }
301
- return false;
302
- }
303
- return false;
304
- }
1548
+ click: handleEditButtonClick
305
1549
  }
306
1550
  });
307
1551
  //#endregion
@@ -399,7 +1643,11 @@ function toggleTaskList(view) {
399
1643
  });
400
1644
  }
401
1645
  }
402
- view.dispatch({ changes });
1646
+ const anchor = view.state.changes(changes).mapPos(from, 1);
1647
+ view.dispatch({
1648
+ changes,
1649
+ selection: { anchor }
1650
+ });
403
1651
  }
404
1652
  /**
405
1653
  * 切换行首前缀(支持多行选区)
@@ -429,7 +1677,11 @@ function toggleLinePrefix(view, pattern, insertText) {
429
1677
  insert: insertText
430
1678
  });
431
1679
  }
432
- view.dispatch({ changes });
1680
+ const anchor = view.state.changes(changes).mapPos(from, 1);
1681
+ view.dispatch({
1682
+ changes,
1683
+ selection: { anchor }
1684
+ });
433
1685
  }
434
1686
  /** Markdown 列表行:缩进 + 列表标记(无序/有序)+ 空白 */
435
1687
  var LIST_LINE_RE = /^(\s*)([-*+]|\d+\.)([ \t]+)/;
@@ -542,28 +1794,32 @@ function dedentMarkdownList(view) {
542
1794
  return true;
543
1795
  }
544
1796
  /**
545
- * 上传图片
1797
+ * 上传图片:失败(含网络异常)统一返回 null,不抛错
546
1798
  * @param file - 要上传的文件
547
1799
  * @param uploadConfig - 上传配置
548
1800
  */
549
1801
  async function uploadFileToServer(file, uploadConfig) {
550
- if (uploadConfig.onUploadImage) return uploadConfig.onUploadImage(file);
551
- if (uploadConfig.uploadUrl) {
552
- const formData = new FormData();
553
- formData.append("file", file);
554
- const response = await fetch(uploadConfig.uploadUrl, {
555
- method: "POST",
556
- body: formData
557
- });
558
- if (!response.ok) return null;
559
- const result = await response.json();
560
- if (uploadConfig.onGetUploadUrl) return uploadConfig.onGetUploadUrl(result);
561
- return result.data?.path || null;
1802
+ try {
1803
+ if (uploadConfig.onUploadImage) return await uploadConfig.onUploadImage(file);
1804
+ if (uploadConfig.uploadUrl) {
1805
+ const formData = new FormData();
1806
+ formData.append("file", file);
1807
+ const response = await fetch(uploadConfig.uploadUrl, {
1808
+ method: "POST",
1809
+ body: formData
1810
+ });
1811
+ if (!response.ok) return null;
1812
+ const result = await response.json();
1813
+ if (uploadConfig.onGetUploadUrl) return uploadConfig.onGetUploadUrl(result);
1814
+ return result?.data?.path ?? null;
1815
+ }
1816
+ return null;
1817
+ } catch {
1818
+ return null;
562
1819
  }
563
- return null;
564
1820
  }
565
1821
  /**
566
- * 判断是否配置了图片上传
1822
+ * 判断是否配置了图片上传(类型谓词,守卫后可安全访问配置)
567
1823
  */
568
1824
  function isUploadConfigured(uploadConfig) {
569
1825
  return !!(uploadConfig?.uploadUrl || uploadConfig?.onUploadImage);
@@ -577,7 +1833,6 @@ function uploadImage(view, uploadConfig) {
577
1833
  const input = document.createElement("input");
578
1834
  input.type = "file";
579
1835
  input.accept = "image/*";
580
- input.style.display = "none";
581
1836
  input.addEventListener("change", async () => {
582
1837
  if (!input.files || input.files.length === 0) return;
583
1838
  const file = input.files[0];
@@ -594,7 +1849,6 @@ function uploadImage(view, uploadConfig) {
594
1849
  }
595
1850
  input.remove();
596
1851
  });
597
- document.body.appendChild(input);
598
1852
  input.click();
599
1853
  }
600
1854
  /**
@@ -652,10 +1906,14 @@ function toggleWrap(view, openTag, closeTag) {
652
1906
  }
653
1907
  //#endregion
654
1908
  //#region src/components/Editor/codemirrorExtensions.ts
655
- /** 图片上传配置 facet */
656
- var uploadConfigFacet = _codemirror_state.Facet.define({ combine: (values) => values[values.length - 1] });
657
- /** 未配置上传时的提示回调 facet */
658
- var messageFacet = _codemirror_state.Facet.define({ combine: (values) => values[values.length - 1] });
1909
+ /**
1910
+ * 图片上传配置 facet。
1911
+ * 传入 getter 而非配置本身:扩展只在 mount 时创建一次,
1912
+ * 运行期通过 getter 读取最新配置,避免闭包过期。
1913
+ */
1914
+ var uploadConfigFacet = _codemirror_state.Facet.define({ combine: (values) => values.length ? values[values.length - 1] : null });
1915
+ /** 未配置上传时的提示回调 facet(同为 getter 形式) */
1916
+ var messageFacet = _codemirror_state.Facet.define({ combine: (values) => values.length ? values[values.length - 1] : null });
659
1917
  /** 粘贴事件处理:拦截图片并上传 */
660
1918
  var pasteHandler = _codemirror_view.EditorView.domEventHandlers({ paste: (event, view) => {
661
1919
  const files = event.clipboardData?.files;
@@ -663,23 +1921,38 @@ var pasteHandler = _codemirror_view.EditorView.domEventHandlers({ paste: (event,
663
1921
  const imageFiles = Array.from(files).filter((f) => f.type.startsWith("image/"));
664
1922
  if (imageFiles.length === 0) return false;
665
1923
  event.preventDefault();
666
- const uploadConfig = view.state.facet(uploadConfigFacet);
667
- const showMessage = view.state.facet(messageFacet);
1924
+ const uploadConfig = view.state.facet(uploadConfigFacet)?.();
1925
+ const showMessage = view.state.facet(messageFacet)?.();
668
1926
  if (!isUploadConfigured(uploadConfig)) {
669
1927
  showMessage?.();
670
1928
  return true;
671
1929
  }
672
- const { from, to } = view.state.selection.main;
673
- let offset = 0;
674
- for (const file of imageFiles) uploadFileToServer(file, uploadConfig).then((url) => {
675
- if (url) {
676
- const insert = `![${file.name.replace(/\.[^.]+$/, "")}](${url})`;
677
- view.dispatch({ changes: {
678
- from: from + offset,
679
- to: to + offset,
680
- insert
681
- } });
682
- offset += insert.length;
1930
+ const config = uploadConfig;
1931
+ let isFirst = true;
1932
+ for (const file of imageFiles) uploadFileToServer(file, config).then((url) => {
1933
+ if (!url) return;
1934
+ const insert = `![${file.name.replace(/\.[^.]+$/, "")}](${url})`;
1935
+ const { state } = view;
1936
+ if (isFirst) {
1937
+ isFirst = false;
1938
+ const { from, to } = state.selection.main;
1939
+ view.dispatch({
1940
+ changes: {
1941
+ from,
1942
+ to,
1943
+ insert
1944
+ },
1945
+ selection: { anchor: from + insert.length }
1946
+ });
1947
+ } else {
1948
+ const end = state.doc.length;
1949
+ view.dispatch({
1950
+ changes: {
1951
+ from: end,
1952
+ insert: `\n${insert}`
1953
+ },
1954
+ selection: { anchor: end + insert.length + 1 }
1955
+ });
683
1956
  }
684
1957
  });
685
1958
  return true;
@@ -739,8 +2012,8 @@ var getCodeMirrorExtensions = (opts) => {
739
2012
  ];
740
2013
  extensions.push(containerWidgetPlugin);
741
2014
  if (opts?.onEditContainer) extensions.push(containerEditCallback.of(opts.onEditContainer));
742
- if (opts?.uploadConfig) extensions.push(uploadConfigFacet.of(opts.uploadConfig));
743
- if (opts?.onMessageNoUploadConfig) extensions.push(messageFacet.of(opts.onMessageNoUploadConfig));
2015
+ if (opts?.getUploadConfig) extensions.push(uploadConfigFacet.of(opts.getUploadConfig));
2016
+ if (opts?.getOnMessageNoUploadConfig) extensions.push(messageFacet.of(opts.getOnMessageNoUploadConfig));
744
2017
  return extensions;
745
2018
  };
746
2019
  //#endregion
@@ -748,17 +2021,29 @@ var getCodeMirrorExtensions = (opts) => {
748
2021
  function Editor({ value, onChange, onScrollReady, onViewReady, onEditContainer, uploadConfig, onMessageNoUploadConfig }) {
749
2022
  const editorRef = (0, react.useRef)(null);
750
2023
  const viewRef = (0, react.useRef)(null);
2024
+ const latestRef = (0, react.useRef)({
2025
+ onChange,
2026
+ onEditContainer,
2027
+ uploadConfig,
2028
+ onMessageNoUploadConfig
2029
+ });
2030
+ latestRef.current = {
2031
+ onChange,
2032
+ onEditContainer,
2033
+ uploadConfig,
2034
+ onMessageNoUploadConfig
2035
+ };
751
2036
  (0, react.useEffect)(() => {
752
2037
  if (!editorRef.current) return;
753
2038
  const extensions = [
754
2039
  codemirror.basicSetup,
755
2040
  ...getCodeMirrorExtensions({
756
- onEditContainer,
757
- uploadConfig,
758
- onMessageNoUploadConfig
2041
+ getUploadConfig: () => latestRef.current.uploadConfig,
2042
+ getOnMessageNoUploadConfig: () => latestRef.current.onMessageNoUploadConfig,
2043
+ onEditContainer: (view, container) => latestRef.current.onEditContainer?.(view, container)
759
2044
  }),
760
2045
  codemirror.EditorView.updateListener.of((update) => {
761
- if (update.docChanged) onChange(update.state.doc.toString());
2046
+ if (update.docChanged) latestRef.current.onChange(update.state.doc.toString());
762
2047
  })
763
2048
  ];
764
2049
  const state = _codemirror_state.EditorState.create({
@@ -769,18 +2054,26 @@ function Editor({ value, onChange, onScrollReady, onViewReady, onEditContainer,
769
2054
  state,
770
2055
  parent: editorRef.current
771
2056
  });
772
- if (onScrollReady && viewRef.current) onScrollReady(viewRef.current.scrollDOM);
773
- if (onViewReady) onViewReady(viewRef.current);
2057
+ if (viewRef.current) {
2058
+ onScrollReady?.(viewRef.current.scrollDOM);
2059
+ onViewReady?.(viewRef.current);
2060
+ }
774
2061
  return () => {
775
2062
  viewRef.current?.destroy();
2063
+ viewRef.current = null;
776
2064
  };
777
2065
  }, []);
778
2066
  (0, react.useEffect)(() => {
779
- if (viewRef.current && viewRef.current.state.doc.toString() !== value) viewRef.current.dispatch({ changes: {
780
- from: 0,
781
- to: viewRef.current.state.doc.length,
782
- insert: value
783
- } });
2067
+ const view = viewRef.current;
2068
+ if (view && view.state.doc.toString() !== value) view.dispatch({
2069
+ changes: {
2070
+ from: 0,
2071
+ to: view.state.doc.length,
2072
+ insert: value
2073
+ },
2074
+ effects: view.scrollSnapshot(),
2075
+ scrollIntoView: false
2076
+ });
784
2077
  }, [value]);
785
2078
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
786
2079
  ref: editorRef,
@@ -789,23 +2082,25 @@ function Editor({ value, onChange, onScrollReady, onViewReady, onEditContainer,
789
2082
  }
790
2083
  //#endregion
791
2084
  //#region src/components/Preview/index.tsx
792
- var Preview = (0, react.forwardRef)(({ content, previewOptions }, ref) => {
2085
+ var Preview = (0, react.forwardRef)(({ content, previewOptions, languages }, ref) => {
793
2086
  (0, react.useEffect)(() => {
794
2087
  (0, remons_render_markdown.initHighlighter)({
795
2088
  ...remons_render_markdown.languagesCommon,
796
- ...previewOptions?.languages ? previewOptions?.languages : {}
2089
+ ...languages ?? {}
797
2090
  });
798
- }, [previewOptions?.languages]);
2091
+ }, [languages]);
2092
+ const { languages: _ignored, ...restOptions } = previewOptions ?? {};
799
2093
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
800
2094
  ref,
801
2095
  className: "preview",
802
2096
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(remons_render_markdown.default, {
803
2097
  content,
804
- ...previewOptions
2098
+ ...restOptions
805
2099
  })
806
2100
  });
807
2101
  });
808
2102
  Preview.displayName = "Preview";
2103
+ var Preview_default = (0, react.memo)(Preview);
809
2104
  //#endregion
810
2105
  //#region src/components/Panel/SplitPanels.tsx
811
2106
  var { Panel } = antd.Splitter;
@@ -821,9 +2116,31 @@ function SplitPanels({ leftPanel, rightPanel }) {
821
2116
  });
822
2117
  }
823
2118
  //#endregion
2119
+ //#region src/components/Icon/config.ts
2120
+ var scriptUrl = "https://at.alicdn.com/t/c/font_5241307_xoojyr52dqn.js";
2121
+ var IconComp = null;
2122
+ /**
2123
+ * 配置 iconfont 脚本地址(宿主在应用入口调用),需在首次渲染前设置;
2124
+ * 变更后重置内部缓存,下次渲染时以新地址重建图标组件。
2125
+ */
2126
+ function setIconfontScriptUrl(url) {
2127
+ if (url === scriptUrl) return;
2128
+ scriptUrl = url;
2129
+ IconComp = null;
2130
+ }
2131
+ /** 读取当前 iconfont 脚本地址 */
2132
+ function getIconfontScriptUrl() {
2133
+ return scriptUrl;
2134
+ }
2135
+ /** 懒创建图标组件:首次渲染时才注入 iconfont 脚本,避免模块层副作用 */
2136
+ function getIconComponent() {
2137
+ if (!IconComp) IconComp = (0, _ant_design_icons.createFromIconfontCN)({ scriptUrl });
2138
+ return IconComp;
2139
+ }
2140
+ //#endregion
824
2141
  //#region src/components/Icon/index.tsx
825
- var Icon = (0, _ant_design_icons.createFromIconfontCN)({ scriptUrl: "https://at.alicdn.com/t/c/font_5241307_xoojyr52dqn.js" });
826
2142
  function IconComponent(type, className) {
2143
+ const Icon = getIconComponent();
827
2144
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Icon, {
828
2145
  type: `icon-${type}`,
829
2146
  className
@@ -844,7 +2161,8 @@ var UPLOAD_CONFIG_MISSING_MESSAGE = "请先配置图片上传功能";
844
2161
  * @param options - 配置选项
845
2162
  */
846
2163
  function createToolbarConfig(options) {
847
- const hasUploadConfig = isUploadConfigured(options);
2164
+ const hasUploadConfig = isUploadConfigured(options?.upload);
2165
+ const notify = options?.notify;
848
2166
  return [
849
2167
  {
850
2168
  id: "heading",
@@ -938,7 +2256,7 @@ function createToolbarConfig(options) {
938
2256
  id: "image",
939
2257
  label: "图片",
940
2258
  icon: _ant_design_icons.PictureOutlined,
941
- handler: hasUploadConfig && options ? (v) => uploadImage(v, options) : () => antd.message.warning(UPLOAD_CONFIG_MISSING_MESSAGE)
2259
+ handler: hasUploadConfig && options?.upload ? (v) => uploadImage(v, options.upload) : () => notify?.("warning", UPLOAD_CONFIG_MISSING_MESSAGE)
942
2260
  },
943
2261
  { separatorBefore: true },
944
2262
  {
@@ -985,11 +2303,14 @@ function createToolbarConfig(options) {
985
2303
  //#endregion
986
2304
  //#region src/components/Toolbar/hooks/useToolbar.ts
987
2305
  function useToolbar(editorView, options) {
988
- const { extraItems, uploadConfig } = options || {};
2306
+ const { extraItems, uploadConfig, notify } = options || {};
989
2307
  return {
990
2308
  config: (0, react.useMemo)(() => {
991
- return createToolbarConfig(uploadConfig);
992
- }, [uploadConfig]),
2309
+ return createToolbarConfig({
2310
+ upload: uploadConfig,
2311
+ notify
2312
+ });
2313
+ }, [uploadConfig, notify]),
993
2314
  extraItemsConfig: (0, react.useMemo)(() => {
994
2315
  return extraItems || [];
995
2316
  }, [extraItems]),
@@ -1009,34 +2330,52 @@ function useToolbar(editorView, options) {
1009
2330
  }
1010
2331
  //#endregion
1011
2332
  //#region src/components/Toolbar/renderers/ToolbarItemRenderer.tsx
2333
+ /**
2334
+ * 渲染图标:统一接受组件类型;兼容传入 ReactNode 的旧用法。
2335
+ * 组件类型不仅指函数/class,也包括 forwardRef、memo 包装出的对象
2336
+ * (@ant-design/icons 即为 forwardRef,不能当作普通 child 直接渲染)。
2337
+ */
2338
+ var REACT_FORWARD_REF = Symbol.for("react.forward_ref");
2339
+ var REACT_MEMO = Symbol.for("react.memo");
2340
+ function isComponentType(icon) {
2341
+ if (typeof icon === "function") return true;
2342
+ if (typeof icon === "object" && icon !== null) {
2343
+ const t = icon.$$typeof;
2344
+ return t === REACT_FORWARD_REF || t === REACT_MEMO;
2345
+ }
2346
+ return false;
2347
+ }
2348
+ function renderIcon(icon) {
2349
+ if (isComponentType(icon)) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(icon, {});
2350
+ return icon;
2351
+ }
1012
2352
  function ToolbarItemRenderer({ item, onClick }) {
1013
- const Icon = item.icon;
1014
2353
  if (item.children && item.children.length > 0) return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [item.separatorBefore && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { className: "toolbar-separator" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
1015
2354
  className: "toolbar-group",
1016
2355
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Tooltip, {
1017
2356
  title: item.label,
1018
2357
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Dropdown, {
1019
- menu: { items: item.children.map((child) => ({
1020
- type: "item",
1021
- key: child.id ?? "",
1022
- label: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
1023
- onClick: () => onClick(child),
1024
- children: [
1025
- child.icon && (() => {
1026
- const ChildIcon = child.icon;
1027
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ChildIcon, {});
1028
- })(),
2358
+ menu: {
2359
+ items: item.children.map((child) => ({
2360
+ key: child.id ?? "",
2361
+ label: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", { children: [
2362
+ child.icon && renderIcon(child.icon),
1029
2363
  " ",
1030
2364
  child.label
1031
- ]
1032
- })
1033
- })) },
2365
+ ] }),
2366
+ disabled: child.disabled
2367
+ })),
2368
+ onClick: ({ key }) => {
2369
+ const child = item.children?.find((c) => c.id === key);
2370
+ if (child && !child.disabled) onClick(child);
2371
+ }
2372
+ },
1034
2373
  placement: "bottomLeft",
1035
2374
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(antd.Button, {
1036
2375
  className: "toolbar-button",
1037
2376
  type: "text",
1038
2377
  size: "small",
1039
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Icon, {}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_ant_design_icons.DownOutlined, { style: { fontSize: 10 } })]
2378
+ children: [item.icon && renderIcon(item.icon), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_ant_design_icons.DownOutlined, { style: { fontSize: 10 } })]
1040
2379
  })
1041
2380
  })
1042
2381
  })
@@ -1053,7 +2392,7 @@ function ToolbarItemRenderer({ item, onClick }) {
1053
2392
  size: "small",
1054
2393
  disabled: isDisabled,
1055
2394
  onClick: () => !isDisabled && onClick(item),
1056
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Icon, {})
2395
+ children: item.icon && renderIcon(item.icon)
1057
2396
  })
1058
2397
  })
1059
2398
  })] });
@@ -1071,125 +2410,81 @@ var index_module_default = {
1071
2410
  var MAX_ROW = 8;
1072
2411
  var MAX_COL = 8;
1073
2412
  function TablePicker({ onSelect }) {
1074
- const [hoverSize, setHoverSize] = (0, react.useState)({
1075
- row: 0,
1076
- col: 0
2413
+ /** 当前高亮区域(rows x cols),渲染唯一依赖此状态 */
2414
+ const [size, setSize] = (0, react.useState)({
2415
+ rows: 0,
2416
+ cols: 0
1077
2417
  });
1078
- const [confirmedSize, setConfirmedSize] = (0, react.useState)({
1079
- row: 0,
1080
- col: 0
1081
- });
1082
- const maxColRef = (0, react.useRef)(0);
2418
+ /** 鼠标回撤(向上/向左)后需要重置列跟踪,prevRow 与 pending 成对出现,仅事件处理内使用 */
1083
2419
  const prevRowRef = (0, react.useRef)(0);
1084
- const timerIdRef = (0, react.useRef)(null);
1085
- const refreshTimerRef = (0, react.useRef)(null);
1086
- const commitRef = (0, react.useRef)(null);
1087
- const clearTimer = (0, react.useCallback)(() => {
1088
- if (timerIdRef.current) {
1089
- clearTimeout(timerIdRef.current);
1090
- timerIdRef.current = null;
1091
- }
1092
- }, []);
2420
+ const pendingColsRef = (0, react.useRef)(0);
2421
+ const flashTimerRef = (0, react.useRef)(null);
1093
2422
  const clearFlash = (0, react.useCallback)(() => {
1094
- if (refreshTimerRef.current) {
1095
- clearInterval(refreshTimerRef.current);
1096
- refreshTimerRef.current = null;
2423
+ if (flashTimerRef.current) {
2424
+ clearInterval(flashTimerRef.current);
2425
+ flashTimerRef.current = null;
1097
2426
  }
1098
2427
  }, []);
1099
2428
  (0, react.useEffect)(() => () => {
1100
- if (timerIdRef.current) clearTimeout(timerIdRef.current);
1101
- if (refreshTimerRef.current) clearInterval(refreshTimerRef.current);
1102
- }, []);
2429
+ clearFlash();
2430
+ }, [clearFlash]);
1103
2431
  /**
1104
2432
  * 扩展选中区域至 (col, row)
1105
2433
  */
1106
2434
  function extend(col, row) {
1107
- if (row < prevRowRef.current || col < maxColRef.current) maxColRef.current = 0;
1108
- if (col > maxColRef.current) maxColRef.current = col;
1109
- setHoverSize({
1110
- row,
1111
- col
1112
- });
1113
- setConfirmedSize({
1114
- row,
1115
- col: maxColRef.current
2435
+ if (row < prevRowRef.current || col < pendingColsRef.current) pendingColsRef.current = 0;
2436
+ if (col > pendingColsRef.current) pendingColsRef.current = col;
2437
+ const cols = pendingColsRef.current;
2438
+ setSize({
2439
+ rows: row,
2440
+ cols
1116
2441
  });
1117
- if (row === 1) commitRef.current = {
1118
- cols: maxColRef.current,
1119
- rows: 1
1120
- };
2442
+ prevRowRef.current = row;
1121
2443
  }
1122
2444
  /**
1123
- * 跳跃动画效果
2445
+ * 跳跃动画效果:逐行推进高亮,结束后落到 (col, limit)
1124
2446
  */
1125
- function flash(col, dir, limit, finalCallback) {
2447
+ function flash(col, dir, limit) {
2448
+ clearFlash();
1126
2449
  let current = dir === 1 ? 1 : limit;
1127
2450
  const step = dir === 1 ? 1 : -1;
1128
- refreshTimerRef.current = setInterval(() => {
1129
- setHoverSize({
1130
- row: current,
1131
- col
1132
- });
1133
- if (current > confirmedSize.row || dir === -1) maxColRef.current = Math.min(MAX_COL, col);
1134
- current += step;
2451
+ flashTimerRef.current = setInterval(() => {
1135
2452
  if (dir === 1 && current > limit || dir === -1 && current < 1) {
1136
- clearInterval(refreshTimerRef.current);
1137
- refreshTimerRef.current = null;
2453
+ clearFlash();
1138
2454
  const finalRow = current - step;
1139
- setHoverSize({
1140
- row: finalRow,
1141
- col
2455
+ setSize({
2456
+ rows: finalRow,
2457
+ cols: col
1142
2458
  });
1143
- finalCallback(col, finalRow);
2459
+ return;
1144
2460
  }
2461
+ setSize({
2462
+ rows: current,
2463
+ cols: col
2464
+ });
2465
+ current += step;
1145
2466
  }, 50);
1146
2467
  }
1147
2468
  /**
1148
2469
  * 核心逻辑:鼠标进入格子
1149
2470
  */
1150
- function onCellEnterCheck(index) {
1151
- clearTimer();
2471
+ function onCellEnter(index) {
1152
2472
  clearFlash();
1153
2473
  const row = Math.floor(index / MAX_COL) + 1;
1154
2474
  const col = index % MAX_COL + 1;
1155
- const prevRow = prevRowRef.current;
1156
- const isJump = Math.abs(row - prevRow) > 1;
1157
- const isDown = row > prevRow;
2475
+ const maxCol = pendingColsRef.current;
2476
+ const isJump = Math.abs(row - prevRowRef.current) > 1;
1158
2477
  prevRowRef.current = row;
1159
2478
  if (!isJump) extend(col, row);
1160
- else if (isDown) {
1161
- if (col > maxColRef.current || maxColRef.current >= MAX_COL) flash(col, 1, Math.min(row, MAX_ROW), (c, r) => {
1162
- setConfirmedSize({
1163
- row: r,
1164
- col: c
1165
- });
1166
- });
1167
- else extend(col, row);
2479
+ else if (row > 0 && (col > maxCol || maxCol >= MAX_COL)) {
2480
+ pendingColsRef.current = Math.min(MAX_COL, col);
2481
+ flash(Math.min(MAX_COL, col), 1, Math.min(row, MAX_ROW));
1168
2482
  } else {
1169
- maxColRef.current = 0;
1170
- flash(col, -1, row, (c, r) => {
1171
- setConfirmedSize({
1172
- row: r,
1173
- col: c
1174
- });
1175
- if (r === 1) {
1176
- commitRef.current = {
1177
- cols: Math.min(MAX_COL, col),
1178
- rows: 1
1179
- };
1180
- setConfirmedSize({
1181
- row: 1,
1182
- col: Math.min(MAX_COL, col)
1183
- });
1184
- }
1185
- });
2483
+ pendingColsRef.current = 0;
2484
+ extend(col, row);
1186
2485
  }
1187
2486
  }
1188
2487
  function onMouseDown() {
1189
- const size = commitRef.current || {
1190
- cols: maxColRef.current,
1191
- rows: confirmedSize.row
1192
- };
1193
2488
  if (size.rows > 0 && size.cols > 0) onSelect(size);
1194
2489
  }
1195
2490
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
@@ -1201,18 +2496,18 @@ function TablePicker({ onSelect }) {
1201
2496
  children: Array.from({ length: 64 }).map((_, i) => {
1202
2497
  const row = Math.floor(i / MAX_COL) + 1;
1203
2498
  const col = i % MAX_COL + 1;
1204
- const isSelected = row <= hoverSize.row && col <= maxColRef.current;
2499
+ const isSelected = row <= size.rows && col <= size.cols;
1205
2500
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
1206
2501
  className: `${index_module_default.cell} ${isSelected ? index_module_default.cellActive : ""}`,
1207
- onMouseEnter: () => onCellEnterCheck(i)
2502
+ onMouseEnter: () => onCellEnter(i)
1208
2503
  }, i);
1209
2504
  })
1210
2505
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1211
2506
  className: index_module_default.label,
1212
2507
  children: [
1213
- hoverSize.row,
2508
+ size.rows,
1214
2509
  " x ",
1215
- maxColRef.current || 1
2510
+ size.cols || 1
1216
2511
  ]
1217
2512
  })]
1218
2513
  });
@@ -1220,8 +2515,10 @@ function TablePicker({ onSelect }) {
1220
2515
  //#endregion
1221
2516
  //#region src/components/Toolbar/renderers/TablePicker/TableDropdown.tsx
1222
2517
  function TableDropdown({ editorView }) {
1223
- const [open, setOpen] = react.default.useState(false);
1224
- const openCountRef = (0, react.useRef)(0);
2518
+ const [open, setOpen] = (0, react.useState)(false);
2519
+ const handleOpenChange = (0, react.useCallback)((next) => {
2520
+ setOpen(next);
2521
+ }, []);
1225
2522
  const handleTableSelect = (0, react.useCallback)((rows, cols) => {
1226
2523
  if (!editorView || rows <= 0 || cols <= 0) return;
1227
2524
  editorView.focus();
@@ -1238,18 +2535,15 @@ function TableDropdown({ editorView }) {
1238
2535
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Dropdown, {
1239
2536
  trigger: ["click"],
1240
2537
  open,
1241
- onOpenChange: setOpen,
1242
- popupRender: () => {
1243
- openCountRef.current++;
1244
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
1245
- style: { padding: 4 },
1246
- onClick: (e) => e.stopPropagation(),
1247
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TablePicker, { onSelect: (size) => {
1248
- handleTableSelect(size.rows, size.cols);
1249
- setOpen(false);
1250
- } }, openCountRef.current)
1251
- });
1252
- },
2538
+ onOpenChange: handleOpenChange,
2539
+ destroyOnHidden: true,
2540
+ popupRender: () => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
2541
+ style: { padding: 4 },
2542
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TablePicker, { onSelect: (size) => {
2543
+ handleTableSelect(size.rows, size.cols);
2544
+ setOpen(false);
2545
+ } })
2546
+ }),
1253
2547
  placement: "bottomLeft",
1254
2548
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Button, {
1255
2549
  className: "toolbar-button",
@@ -1262,10 +2556,11 @@ function TableDropdown({ editorView }) {
1262
2556
  }
1263
2557
  //#endregion
1264
2558
  //#region src/components/Toolbar/index.tsx
1265
- function Toolbar({ editorView, fullscreen = true, onToggleFullscreen, extraItems, uploadConfig }) {
2559
+ function Toolbar({ editorView, fullscreen = true, onToggleFullscreen, extraItems, uploadConfig, notify }) {
1266
2560
  const { config, extraItemsConfig, handleClick } = useToolbar(editorView, {
1267
2561
  extraItems,
1268
- uploadConfig
2562
+ uploadConfig,
2563
+ notify
1269
2564
  });
1270
2565
  const renderFullscreen = (0, react.useCallback)(() => {
1271
2566
  if (!onToggleFullscreen) return null;
@@ -1305,8 +2600,305 @@ function Toolbar({ editorView, fullscreen = true, onToggleFullscreen, extraItems
1305
2600
  ]
1306
2601
  });
1307
2602
  }
2603
+ var Toolbar_default = (0, react.memo)(Toolbar);
1308
2604
  //#endregion
1309
2605
  //#region src/components/Dialog/EditDialog.tsx
2606
+ var import_dayjs_min = /* @__PURE__ */ __toESM((/* @__PURE__ */ __commonJSMin(((exports, module) => {
2607
+ (function(t, e) {
2608
+ "object" == typeof exports && "undefined" != typeof module ? module.exports = e() : "function" == typeof define && define.amd ? define(e) : (t = "undefined" != typeof globalThis ? globalThis : t || self).dayjs = e();
2609
+ })(exports, (function() {
2610
+ "use strict";
2611
+ var t = 1e3, e = 6e4, n = 36e5, r = "millisecond", i = "second", s = "minute", u = "hour", a = "day", o = "week", c = "month", f = "quarter", h = "year", d = "date", l = "Invalid Date", $ = /^(\d{4})[-/]?(\d{1,2})?[-/]?(\d{0,2})[Tt\s]*(\d{1,2})?:?(\d{1,2})?:?(\d{1,2})?[.:]?(\d+)?$/, y = /\[([^\]]+)]|YYYY|YY|M{1,4}|D{1,2}|d{1,4}|H{1,2}|h{1,2}|a|A|m{1,2}|s{1,2}|Z{1,2}|SSS/g, M = {
2612
+ name: "en",
2613
+ weekdays: "Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),
2614
+ months: "January_February_March_April_May_June_July_August_September_October_November_December".split("_"),
2615
+ ordinal: function(t) {
2616
+ var e = [
2617
+ "th",
2618
+ "st",
2619
+ "nd",
2620
+ "rd"
2621
+ ], n = t % 100;
2622
+ return "[" + t + (e[(n - 20) % 10] || e[n] || e[0]) + "]";
2623
+ }
2624
+ }, m = function(t, e, n) {
2625
+ var r = String(t);
2626
+ return !r || r.length >= e ? t : "" + Array(e + 1 - r.length).join(n) + t;
2627
+ }, v = {
2628
+ s: m,
2629
+ z: function(t) {
2630
+ var e = -t.utcOffset(), n = Math.abs(e), r = Math.floor(n / 60), i = n % 60;
2631
+ return (e <= 0 ? "+" : "-") + m(r, 2, "0") + ":" + m(i, 2, "0");
2632
+ },
2633
+ m: function t(e, n) {
2634
+ if (e.date() < n.date()) return -t(n, e);
2635
+ var r = 12 * (n.year() - e.year()) + (n.month() - e.month()), i = e.clone().add(r, c), s = n - i < 0, u = e.clone().add(r + (s ? -1 : 1), c);
2636
+ return +(-(r + (n - i) / (s ? i - u : u - i)) || 0);
2637
+ },
2638
+ a: function(t) {
2639
+ return t < 0 ? Math.ceil(t) || 0 : Math.floor(t);
2640
+ },
2641
+ p: function(t) {
2642
+ return {
2643
+ M: c,
2644
+ y: h,
2645
+ w: o,
2646
+ d: a,
2647
+ D: d,
2648
+ h: u,
2649
+ m: s,
2650
+ s: i,
2651
+ ms: r,
2652
+ Q: f
2653
+ }[t] || String(t || "").toLowerCase().replace(/s$/, "");
2654
+ },
2655
+ u: function(t) {
2656
+ return void 0 === t;
2657
+ }
2658
+ }, g = "en", D = {};
2659
+ D[g] = M;
2660
+ var p = "$isDayjsObject", S = function(t) {
2661
+ return t instanceof _ || !(!t || !t[p]);
2662
+ }, w = function t(e, n, r) {
2663
+ var i;
2664
+ if (!e) return g;
2665
+ if ("string" == typeof e) {
2666
+ var s = e.toLowerCase();
2667
+ D[s] && (i = s), n && (D[s] = n, i = s);
2668
+ var u = e.split("-");
2669
+ if (!i && u.length > 1) return t(u[0]);
2670
+ } else {
2671
+ var a = e.name;
2672
+ D[a] = e, i = a;
2673
+ }
2674
+ return !r && i && (g = i), i || !r && g;
2675
+ }, O = function(t, e) {
2676
+ if (S(t)) return t.clone();
2677
+ var n = "object" == typeof e ? e : {};
2678
+ return n.date = t, n.args = arguments, new _(n);
2679
+ }, b = v;
2680
+ b.l = w, b.i = S, b.w = function(t, e) {
2681
+ return O(t, {
2682
+ locale: e.$L,
2683
+ utc: e.$u,
2684
+ x: e.$x,
2685
+ $offset: e.$offset
2686
+ });
2687
+ };
2688
+ var _ = function() {
2689
+ function M(t) {
2690
+ this.$L = w(t.locale, null, !0), this.parse(t), this.$x = this.$x || t.x || {}, this[p] = !0;
2691
+ }
2692
+ var m = M.prototype;
2693
+ return m.parse = function(t) {
2694
+ this.$d = function(t) {
2695
+ var e = t.date, n = t.utc;
2696
+ if (null === e) return /* @__PURE__ */ new Date(NaN);
2697
+ if (b.u(e)) return /* @__PURE__ */ new Date();
2698
+ if (e instanceof Date) return new Date(e);
2699
+ if ("string" == typeof e && !/Z$/i.test(e)) {
2700
+ var r = e.match($);
2701
+ if (r) {
2702
+ var i = r[2] - 1 || 0, s = (r[7] || "0").substring(0, 3);
2703
+ return n ? new Date(Date.UTC(r[1], i, r[3] || 1, r[4] || 0, r[5] || 0, r[6] || 0, s)) : new Date(r[1], i, r[3] || 1, r[4] || 0, r[5] || 0, r[6] || 0, s);
2704
+ }
2705
+ }
2706
+ return new Date(e);
2707
+ }(t), this.init();
2708
+ }, m.init = function() {
2709
+ var t = this.$d;
2710
+ this.$y = t.getFullYear(), this.$M = t.getMonth(), this.$D = t.getDate(), this.$W = t.getDay(), this.$H = t.getHours(), this.$m = t.getMinutes(), this.$s = t.getSeconds(), this.$ms = t.getMilliseconds();
2711
+ }, m.$utils = function() {
2712
+ return b;
2713
+ }, m.isValid = function() {
2714
+ return !(this.$d.toString() === l);
2715
+ }, m.isSame = function(t, e) {
2716
+ var n = O(t);
2717
+ return this.startOf(e) <= n && n <= this.endOf(e);
2718
+ }, m.isAfter = function(t, e) {
2719
+ return O(t) < this.startOf(e);
2720
+ }, m.isBefore = function(t, e) {
2721
+ return this.endOf(e) < O(t);
2722
+ }, m.$g = function(t, e, n) {
2723
+ return b.u(t) ? this[e] : this.set(n, t);
2724
+ }, m.unix = function() {
2725
+ return Math.floor(this.valueOf() / 1e3);
2726
+ }, m.valueOf = function() {
2727
+ return this.$d.getTime();
2728
+ }, m.startOf = function(t, e) {
2729
+ var n = this, r = !!b.u(e) || e, f = b.p(t), l = function(t, e) {
2730
+ var i = b.w(n.$u ? Date.UTC(n.$y, e, t) : new Date(n.$y, e, t), n);
2731
+ return r ? i : i.endOf(a);
2732
+ }, $ = function(t, e) {
2733
+ return b.w(n.toDate()[t].apply(n.toDate("s"), (r ? [
2734
+ 0,
2735
+ 0,
2736
+ 0,
2737
+ 0
2738
+ ] : [
2739
+ 23,
2740
+ 59,
2741
+ 59,
2742
+ 999
2743
+ ]).slice(e)), n);
2744
+ }, y = this.$W, M = this.$M, m = this.$D, v = "set" + (this.$u ? "UTC" : "");
2745
+ switch (f) {
2746
+ case h: return r ? l(1, 0) : l(31, 11);
2747
+ case c: return r ? l(1, M) : l(0, M + 1);
2748
+ case o:
2749
+ var g = this.$locale().weekStart || 0, D = (y < g ? y + 7 : y) - g;
2750
+ return l(r ? m - D : m + (6 - D), M);
2751
+ case a:
2752
+ case d: return $(v + "Hours", 0);
2753
+ case u: return $(v + "Minutes", 1);
2754
+ case s: return $(v + "Seconds", 2);
2755
+ case i: return $(v + "Milliseconds", 3);
2756
+ default: return this.clone();
2757
+ }
2758
+ }, m.endOf = function(t) {
2759
+ return this.startOf(t, !1);
2760
+ }, m.$set = function(t, e) {
2761
+ var n, o = b.p(t), f = "set" + (this.$u ? "UTC" : ""), l = (n = {}, n[a] = f + "Date", n[d] = f + "Date", n[c] = f + "Month", n[h] = f + "FullYear", n[u] = f + "Hours", n[s] = f + "Minutes", n[i] = f + "Seconds", n[r] = f + "Milliseconds", n)[o], $ = o === a ? this.$D + (e - this.$W) : e;
2762
+ if (o === c || o === h) {
2763
+ var y = this.clone().set(d, 1);
2764
+ y.$d[l]($), y.init(), this.$d = y.set(d, Math.min(this.$D, y.daysInMonth())).$d;
2765
+ } else l && this.$d[l]($);
2766
+ return this.init(), this;
2767
+ }, m.set = function(t, e) {
2768
+ return this.clone().$set(t, e);
2769
+ }, m.get = function(t) {
2770
+ return this[b.p(t)]();
2771
+ }, m.add = function(r, f) {
2772
+ var d, l = this;
2773
+ r = Number(r);
2774
+ var $ = b.p(f), y = function(t) {
2775
+ var e = O(l);
2776
+ return b.w(e.date(e.date() + Math.round(t * r)), l);
2777
+ };
2778
+ if ($ === c) return this.set(c, this.$M + r);
2779
+ if ($ === h) return this.set(h, this.$y + r);
2780
+ if ($ === a) return y(1);
2781
+ if ($ === o) return y(7);
2782
+ var M = (d = {}, d[s] = e, d[u] = n, d[i] = t, d)[$] || 1, m = this.$d.getTime() + r * M;
2783
+ return b.w(m, this);
2784
+ }, m.subtract = function(t, e) {
2785
+ return this.add(-1 * t, e);
2786
+ }, m.format = function(t) {
2787
+ var e = this, n = this.$locale();
2788
+ if (!this.isValid()) return n.invalidDate || l;
2789
+ var r = t || "YYYY-MM-DDTHH:mm:ssZ", i = b.z(this), s = this.$H, u = this.$m, a = this.$M, o = n.weekdays, c = n.months, f = n.meridiem, h = function(t, n, i, s) {
2790
+ return t && (t[n] || t(e, r)) || i[n].slice(0, s);
2791
+ }, d = function(t) {
2792
+ return b.s(s % 12 || 12, t, "0");
2793
+ }, $ = f || function(t, e, n) {
2794
+ var r = t < 12 ? "AM" : "PM";
2795
+ return n ? r.toLowerCase() : r;
2796
+ };
2797
+ return r.replace(y, (function(t, r) {
2798
+ return r || function(t) {
2799
+ switch (t) {
2800
+ case "YY": return String(e.$y).slice(-2);
2801
+ case "YYYY": return b.s(e.$y, 4, "0");
2802
+ case "M": return a + 1;
2803
+ case "MM": return b.s(a + 1, 2, "0");
2804
+ case "MMM": return h(n.monthsShort, a, c, 3);
2805
+ case "MMMM": return h(c, a);
2806
+ case "D": return e.$D;
2807
+ case "DD": return b.s(e.$D, 2, "0");
2808
+ case "d": return String(e.$W);
2809
+ case "dd": return h(n.weekdaysMin, e.$W, o, 2);
2810
+ case "ddd": return h(n.weekdaysShort, e.$W, o, 3);
2811
+ case "dddd": return o[e.$W];
2812
+ case "H": return String(s);
2813
+ case "HH": return b.s(s, 2, "0");
2814
+ case "h": return d(1);
2815
+ case "hh": return d(2);
2816
+ case "a": return $(s, u, !0);
2817
+ case "A": return $(s, u, !1);
2818
+ case "m": return String(u);
2819
+ case "mm": return b.s(u, 2, "0");
2820
+ case "s": return String(e.$s);
2821
+ case "ss": return b.s(e.$s, 2, "0");
2822
+ case "SSS": return b.s(e.$ms, 3, "0");
2823
+ case "Z": return i;
2824
+ }
2825
+ return null;
2826
+ }(t) || i.replace(":", "");
2827
+ }));
2828
+ }, m.utcOffset = function() {
2829
+ return 15 * -Math.round(this.$d.getTimezoneOffset() / 15);
2830
+ }, m.diff = function(r, d, l) {
2831
+ var $, y = this, M = b.p(d), m = O(r), v = (m.utcOffset() - this.utcOffset()) * e, g = this - m, D = function() {
2832
+ return b.m(y, m);
2833
+ };
2834
+ switch (M) {
2835
+ case h:
2836
+ $ = D() / 12;
2837
+ break;
2838
+ case c:
2839
+ $ = D();
2840
+ break;
2841
+ case f:
2842
+ $ = D() / 3;
2843
+ break;
2844
+ case o:
2845
+ $ = (g - v) / 6048e5;
2846
+ break;
2847
+ case a:
2848
+ $ = (g - v) / 864e5;
2849
+ break;
2850
+ case u:
2851
+ $ = g / n;
2852
+ break;
2853
+ case s:
2854
+ $ = g / e;
2855
+ break;
2856
+ case i:
2857
+ $ = g / t;
2858
+ break;
2859
+ default: $ = g;
2860
+ }
2861
+ return l ? $ : b.a($);
2862
+ }, m.daysInMonth = function() {
2863
+ return this.endOf(c).$D;
2864
+ }, m.$locale = function() {
2865
+ return D[this.$L];
2866
+ }, m.locale = function(t, e) {
2867
+ if (!t) return this.$L;
2868
+ var n = this.clone(), r = w(t, e, !0);
2869
+ return r && (n.$L = r), n;
2870
+ }, m.clone = function() {
2871
+ return b.w(this.$d, this);
2872
+ }, m.toDate = function() {
2873
+ return new Date(this.valueOf());
2874
+ }, m.toJSON = function() {
2875
+ return this.isValid() ? this.toISOString() : null;
2876
+ }, m.toISOString = function() {
2877
+ return this.$d.toISOString();
2878
+ }, m.toString = function() {
2879
+ return this.$d.toUTCString();
2880
+ }, M;
2881
+ }(), Y = _.prototype;
2882
+ return O.prototype = Y, [
2883
+ ["$ms", r],
2884
+ ["$s", i],
2885
+ ["$m", s],
2886
+ ["$H", u],
2887
+ ["$W", a],
2888
+ ["$M", c],
2889
+ ["$y", h],
2890
+ ["$D", d]
2891
+ ].forEach((function(t) {
2892
+ Y[t[1]] = function(e) {
2893
+ return this.$g(e, t[0], t[1]);
2894
+ };
2895
+ })), O.extend = function(t, e) {
2896
+ return t.$i || (t(e, _, O), t.$i = !0), O;
2897
+ }, O.locale = w, O.isDayjs = S, O.unix = function(t) {
2898
+ return O(1e3 * t);
2899
+ }, O.en = D[g], O.Ls = D, O.p = {}, O;
2900
+ }));
2901
+ })))(), 1);
1310
2902
  /**
1311
2903
  * 组件类型到 antd 表单组件的映射
1312
2904
  */
@@ -1323,7 +2915,7 @@ var FormComponents = {
1323
2915
  dateRange: antd.DatePicker.RangePicker
1324
2916
  };
1325
2917
  /**
1326
- * 渲染对应类型的 antd 表单组件
2918
+ * 渲染对应类型的 antd 表单组件(仅接收 componentProps,不再与 Form.Item props 混用)
1327
2919
  */
1328
2920
  function renderFormItemComponent(field) {
1329
2921
  const props = field.componentProps || {};
@@ -1332,32 +2924,70 @@ function renderFormItemComponent(field) {
1332
2924
  }
1333
2925
  /**
1334
2926
  * 根据 fields 自动生成 Form.Item 列表
2927
+ * 初始值走 <Form initialValues> + 按次打开的 key:
2928
+ * initialValues 在字段实体注册时消费,天然避开“Modal 首次挂载前 setFieldsValue 落空”的时序竞态;
2929
+ * key 每次打开变化触发 Form 重挂载,确保切换到不同容器时重新取值。
1335
2930
  */
1336
- function renderAutoForm(form, fields) {
2931
+ function renderAutoForm(form, fields, initialValues, initKey) {
1337
2932
  if (!fields || fields.length === 0) return null;
1338
2933
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Form, {
1339
2934
  form,
1340
2935
  layout: "vertical",
2936
+ preserve: false,
2937
+ initialValues,
1341
2938
  children: fields.map((field) => {
1342
2939
  if (!field.componentType) return null;
1343
2940
  const formItemProps = {
1344
2941
  name: field.key,
1345
2942
  label: field.name || field.key,
1346
2943
  valuePropName: field.componentType === "switch" ? "checked" : void 0,
1347
- ...field.componentProps
2944
+ ...field.formItemProps
1348
2945
  };
1349
2946
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Form.Item, {
1350
2947
  ...formItemProps,
1351
2948
  children: renderFormItemComponent(field)
1352
2949
  }, field.key);
1353
2950
  })
1354
- });
2951
+ }, initKey);
2952
+ }
2953
+ /** 字符串形式的历史属性值('true'/'false')还原为布尔,供 Switch 初始化 */
2954
+ function toFormInitialValue(field, value) {
2955
+ if (value === void 0) return field.defaultValue ?? (field.componentType === "switch" ? false : void 0);
2956
+ if (field.componentType === "switch") {
2957
+ if (typeof value === "boolean") return value;
2958
+ return value === "true" || value === 1 || value === "1";
2959
+ }
2960
+ if (field.componentType === "number" || field.componentType === "slider" || field.componentType === "rate") {
2961
+ const num = Number(value);
2962
+ return Number.isNaN(num) ? void 0 : num;
2963
+ }
2964
+ if (field.componentType === "date") {
2965
+ const d = (0, import_dayjs_min.default)(typeof value === "boolean" ? String(value) : value);
2966
+ return d.isValid() ? d : void 0;
2967
+ }
2968
+ if (field.componentType === "dateRange") {
2969
+ const parts = String(value).split(",").map((s) => s.trim()).filter(Boolean);
2970
+ if (parts.length !== 2) return void 0;
2971
+ const [start, end] = parts.map((p) => (0, import_dayjs_min.default)(p));
2972
+ return start.isValid() && end.isValid() ? [start, end] : void 0;
2973
+ }
2974
+ return value;
2975
+ }
2976
+ /** 表单控件值归一化为容器属性可存储的字符串(容器语法仅支持扁平原始值) */
2977
+ function normalizeValue(field, value) {
2978
+ if (value === null || value === void 0) return "";
2979
+ if (field?.componentType === "date" && import_dayjs_min.default.isDayjs(value)) return value.format("YYYY-MM-DD");
2980
+ if (field?.componentType === "dateRange" && Array.isArray(value)) return value.filter((v) => import_dayjs_min.default.isDayjs(v)).map((v) => v.format("YYYY-MM-DD")).join(", ");
2981
+ const colorLike = value;
2982
+ if (colorLike && typeof colorLike === "object" && typeof colorLike.toHexString === "function") return colorLike.toHexString();
2983
+ if (typeof value === "boolean" || typeof value === "number") return value;
2984
+ return String(value);
1355
2985
  }
1356
2986
  /**
1357
2987
  * 属性编辑弹窗组件
1358
2988
  * 根据组件 schema 的 renderDialog 函数渲染弹窗内容
1359
2989
  */
1360
- function EditDialog({ visible, typeName, currentProps, onSave, onClose }) {
2990
+ function EditDialog({ visible, typeName, currentProps, initKey, onSave, onClose }) {
1361
2991
  const schema = componentRegistry.get(typeName);
1362
2992
  const [formProps, setFormProps] = (0, react.useState)({});
1363
2993
  const [form] = antd.Form.useForm();
@@ -1366,46 +2996,57 @@ function EditDialog({ visible, typeName, currentProps, onSave, onClose }) {
1366
2996
  const dirtyRef = (0, react.useRef)(false);
1367
2997
  const mergedProps = (0, react.useMemo)(() => {
1368
2998
  if (!schema) return currentProps;
1369
- const defaults = {};
1370
- for (const field of schema.fields || []) defaults[field.key] = field.defaultValue ?? "";
2999
+ const merged = {};
3000
+ for (const field of schema.fields || []) if (field.defaultValue !== void 0) merged[field.key] = field.defaultValue;
1371
3001
  return {
1372
- ...defaults,
3002
+ ...merged,
1373
3003
  ...currentProps
1374
3004
  };
1375
3005
  }, [schema, currentProps]);
3006
+ const initialValues = (0, react.useMemo)(() => {
3007
+ const initial = {};
3008
+ for (const [key, value] of Object.entries(mergedProps)) {
3009
+ const field = schema?.fields?.find((f) => f.key === key);
3010
+ const formValue = toFormInitialValue(field ?? { key }, value);
3011
+ if (formValue !== void 0) initial[key] = formValue;
3012
+ }
3013
+ return initial;
3014
+ }, [mergedProps, schema]);
1376
3015
  (0, react.useEffect)(() => {
1377
3016
  if (visible) {
1378
- form.setFieldsValue(mergedProps);
1379
3017
  setFormProps({});
3018
+ form.setFieldsValue(initialValues);
3019
+ dirtyRef.current = false;
1380
3020
  }
1381
- }, [
1382
- visible,
1383
- mergedProps,
1384
- form
1385
- ]);
3021
+ }, [visible, form]);
1386
3022
  const handleDialogChange = (key, value) => {
1387
3023
  setFormProps((prev) => ({
1388
3024
  ...prev,
1389
3025
  [key]: value
1390
3026
  }));
3027
+ dirtyRef.current = true;
1391
3028
  };
1392
3029
  const handleOk = async () => {
1393
- let finalProps = visible ? {
1394
- ...mergedProps,
1395
- ...formProps
1396
- } : mergedProps;
1397
3030
  try {
1398
3031
  const formValues = await form.validateFields();
1399
- finalProps = {
1400
- ...finalProps,
1401
- ...formValues
1402
- };
1403
- } catch {}
3032
+ for (const [key, value] of Object.entries(formValues)) formProps[key] = value;
3033
+ } catch {
3034
+ return;
3035
+ }
3036
+ const finalProps = {};
3037
+ for (const [key, value] of Object.entries({
3038
+ ...mergedProps,
3039
+ ...formProps
3040
+ })) {
3041
+ const field = schema?.fields?.find((f) => f.key === key);
3042
+ finalProps[key] = normalizeValue(field, value);
3043
+ }
1404
3044
  onSaveRef.current(finalProps);
1405
3045
  dirtyRef.current = false;
1406
3046
  onClose();
1407
3047
  };
1408
3048
  const handleClose = () => {
3049
+ if (dirtyRef.current && !window.confirm("属性修改尚未保存,确定关闭吗?")) return;
1409
3050
  setFormProps({});
1410
3051
  dirtyRef.current = false;
1411
3052
  onClose();
@@ -1419,14 +3060,17 @@ function EditDialog({ visible, typeName, currentProps, onSave, onClose }) {
1419
3060
  dirtyRef.current = true;
1420
3061
  };
1421
3062
  const context = {
1422
- props: mergedProps,
3063
+ props: {
3064
+ ...mergedProps,
3065
+ ...formProps
3066
+ },
1423
3067
  form,
1424
3068
  onChange: handleDialogChange,
1425
3069
  onSave: contextSave
1426
3070
  };
1427
3071
  const renderDialogContent = () => {
1428
3072
  if (schema.renderDialog) return schema.renderDialog(context);
1429
- if (schema.fields?.some((f) => f.componentType) && schema.fields) return renderAutoForm(form, schema.fields);
3073
+ if (schema.fields?.some((f) => f.componentType) && schema.fields) return renderAutoForm(form, schema.fields, initialValues, initKey);
1430
3074
  return null;
1431
3075
  };
1432
3076
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.Modal, {
@@ -1442,36 +3086,47 @@ function EditDialog({ visible, typeName, currentProps, onSave, onClose }) {
1442
3086
  //#endregion
1443
3087
  //#region src/utils/writeContainer.ts
1444
3088
  /**
1445
- * 从属性对象生成 JSON 属性行。
1446
- * 格式: { key: 'value', key2: 'value2' }
3089
+ * 从属性对象生成属性行。
3090
+ * 使用 JSON5 序列化:单引号风格与旧格式兼容,特殊字符会被正确转义,
3091
+ * 配合 parseContainerProps 保证读写往返无损。
1447
3092
  */
1448
3093
  function writeContainerProps(props) {
1449
- const entries = Object.entries(props).map(([k, v]) => `${k}: '${v}'`).join(", ");
1450
- return entries ? `{ ${entries} }` : "{}";
3094
+ return import_dist.default.stringify(props) ?? "{}";
1451
3095
  }
1452
3096
  /**
1453
3097
  * 更新编辑器文档中的容器属性。
1454
- * 替换 JSON 属性行(::: 打开行之后的一行)为新属性。
3098
+ * 已有属性行则整行替换;没有属性行则在容器头行后插入一行。
3099
+ * @param headerPos 容器头行(:::type)任意位置,用于无属性行时定位插入点
3100
+ * @param quotePrefix 容器所处的引用前缀(如 "> "),嵌套在引用中时插入的属性行需保持一致
1455
3101
  */
1456
- function updateContainerProps(view, propsLineFrom, propsLineTo, newProps) {
3102
+ function updateContainerProps(view, headerPos, propsLineFrom, propsLineTo, newProps, quotePrefix = "") {
1457
3103
  const newPropsLine = writeContainerProps(newProps);
1458
- view.dispatch({ changes: {
3104
+ if (propsLineTo > propsLineFrom) view.dispatch({ changes: {
1459
3105
  from: propsLineFrom,
1460
3106
  to: propsLineTo,
1461
- insert: newPropsLine
3107
+ insert: `${quotePrefix}${newPropsLine}`
1462
3108
  } });
3109
+ else {
3110
+ const headerLine = view.state.doc.lineAt(headerPos);
3111
+ view.dispatch({ changes: {
3112
+ from: headerLine.to,
3113
+ insert: `\n${quotePrefix}${newPropsLine}`
3114
+ } });
3115
+ }
1463
3116
  }
1464
3117
  /**
1465
3118
  * 在当前光标位置插入新容器。
1466
- * 创建 :::type 打开行 + JSON 属性 + ::: 关闭行的结构。
3119
+ * 创建 :::type 打开行 + 属性行 + ::: 关闭行的结构。
1467
3120
  */
1468
3121
  function insertContainer(view, typeName, defaultProps) {
1469
3122
  const { from } = view.state.selection.main;
1470
- const container = `:::${typeName}\n${writeContainerProps(defaultProps)}\n:::\n`;
3123
+ const propsLine = writeContainerProps(defaultProps);
3124
+ const container = `\n:::${typeName}\n${propsLine}\n:::\n`;
1471
3125
  view.dispatch({ changes: {
1472
3126
  from,
1473
3127
  insert: container
1474
3128
  } });
3129
+ view.dispatch({ selection: { anchor: from + `\n:::${typeName}\n${propsLine}\n`.length } });
1475
3130
  }
1476
3131
  //#endregion
1477
3132
  //#region src/hooks/useFullscreen.ts
@@ -1510,9 +3165,12 @@ function useFullscreen() {
1510
3165
  /**
1511
3166
  * 双向滚动同步 Hook
1512
3167
  * 编辑器与预览区互相同步滚动位置(基于比例)
1513
- * 使用 síncing 锁防止双向循环触发
3168
+ * 使用 syncing 锁防止双向循环触发
3169
+ *
3170
+ * 直接接收滚动容器元素(而非 ref):元素变化时 effect 重新执行并重新绑定监听,
3171
+ * 避免"挂载时容器尚未就绪 / 编辑器 view 被重建"导致监听永久失效或绑到旧节点。
1514
3172
  */
1515
- function useScrollSync(sourceRef, targetRef) {
3173
+ function useScrollSync(source, target) {
1516
3174
  const rafIdRef = (0, react.useRef)(null);
1517
3175
  const syncingRef = (0, react.useRef)(null);
1518
3176
  const syncScroll = (from, fromEl, toEl) => {
@@ -1537,132 +3195,164 @@ function useScrollSync(sourceRef, targetRef) {
1537
3195
  });
1538
3196
  };
1539
3197
  (0, react.useEffect)(() => {
1540
- const source = sourceRef.current;
1541
- const target = targetRef.current;
1542
3198
  if (!source || !target) return;
1543
3199
  const onSourceScroll = () => {
1544
3200
  if (syncingRef.current !== null) return;
1545
- const s = sourceRef.current;
1546
- const t = targetRef.current;
1547
- syncScroll("source", s, t);
3201
+ syncScroll("source", source, target);
1548
3202
  };
1549
3203
  const onTargetScroll = () => {
1550
3204
  if (syncingRef.current !== null) return;
1551
- const s = sourceRef.current;
1552
- const t = targetRef.current;
1553
- syncScroll("target", t, s);
3205
+ syncScroll("target", target, source);
1554
3206
  };
1555
3207
  source.addEventListener("scroll", onSourceScroll, { passive: true });
1556
3208
  target.addEventListener("scroll", onTargetScroll, { passive: true });
1557
3209
  return () => {
1558
3210
  source.removeEventListener("scroll", onSourceScroll);
1559
3211
  target.removeEventListener("scroll", onTargetScroll);
1560
- if (rafIdRef.current) cancelAnimationFrame(rafIdRef.current);
3212
+ if (rafIdRef.current) {
3213
+ cancelAnimationFrame(rafIdRef.current);
3214
+ rafIdRef.current = null;
3215
+ }
3216
+ syncingRef.current = null;
1561
3217
  };
1562
- }, [sourceRef, targetRef]);
3218
+ }, [source, target]);
1563
3219
  }
1564
3220
  //#endregion
1565
3221
  //#region src/MarkdownEditor.tsx
1566
- var MarkdownEditor_default = (0, react.forwardRef)(function MarkdownEditor({ defaultValue = "", value, onChange, showPreview = true, fullscreen: fullscreenProp = true, previewOptions, uploadConfig }, ref) {
3222
+ /** 订阅注册中心版本,注册变化时触发重渲染 */
3223
+ function useRegistryVersion() {
3224
+ const subscribe = (0, react.useCallback)((onChange) => componentRegistry.subscribe(onChange), []);
3225
+ const getSnapshot = (0, react.useCallback)(() => componentRegistry.getVersion(), []);
3226
+ return (0, react.useSyncExternalStore)(subscribe, getSnapshot, getSnapshot);
3227
+ }
3228
+ var MarkdownEditorInner = ({ defaultValue = "", value, onChange, showPreview = true, fullscreen: fullscreenProp = true, previewOptions, uploadConfig, schemas, onNotify }, ref) => {
1567
3229
  const [content, setContent] = (0, react.useState)(value ?? defaultValue);
1568
3230
  const [editorView, setEditorView] = (0, react.useState)(null);
1569
- const scrollDOMRef = (0, react.useRef)(null);
1570
- const previewElRef = (0, react.useRef)(null);
3231
+ const [scrollDOM, setScrollDOM] = (0, react.useState)(null);
3232
+ const [previewEl, setPreviewEl] = (0, react.useState)(null);
1571
3233
  const { fullscreen, toggleFullscreen } = useFullscreen();
1572
- useScrollSync(scrollDOMRef, previewElRef);
3234
+ useScrollSync(scrollDOM, previewEl);
1573
3235
  const [dialogVisible, setDialogVisible] = (0, react.useState)(false);
1574
3236
  const [dialogTypeName, setDialogTypeName] = (0, react.useState)("");
1575
- const [dialogProps, setDialogProps] = (0, react.useState)({});
1576
- const [dialogPropsRange, setDialogPropsRange] = (0, react.useState)([0, 0]);
3237
+ const [dialogContainer, setDialogContainer] = (0, react.useState)(null);
3238
+ const [dialogSeq, setDialogSeq] = (0, react.useState)(0);
3239
+ const app = antd.App.useApp();
3240
+ const notify = (0, react.useCallback)((type, text) => {
3241
+ if (onNotify) {
3242
+ onNotify(type, text);
3243
+ return;
3244
+ }
3245
+ (app?.message ?? antd.message)[type](text);
3246
+ }, [onNotify, app]);
3247
+ const lastEmittedRef = (0, react.useRef)(void 0);
1577
3248
  (0, react.useEffect)(() => {
1578
- if (value !== void 0) setContent(value);
3249
+ if (value !== void 0 && value !== lastEmittedRef.current) setContent(value);
1579
3250
  }, [value]);
1580
3251
  const internalSetContent = (0, react.useCallback)((newContent) => {
1581
3252
  setContent(newContent);
3253
+ lastEmittedRef.current = newContent;
1582
3254
  onChange?.(newContent);
1583
3255
  }, [onChange]);
1584
3256
  (0, react.useImperativeHandle)(ref, () => ({ getContent: () => content }), [content]);
1585
- const extraToolbarItems = componentRegistry.getAll().flatMap((schema) => {
1586
- if (schema.wrapTags) return {
1587
- id: `wrap-${schema.name}`,
1588
- label: schema.label,
1589
- icon: () => schema.icon ?? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_ant_design_icons.ReadOutlined, {}),
1590
- wrapTags: schema.wrapTags
1591
- };
1592
- const defaultProps = {};
1593
- for (const field of schema?.fields ?? []) defaultProps[field.key] = field.defaultValue ?? "";
1594
- return {
1595
- id: `container-${schema.name}`,
1596
- label: schema.label,
1597
- icon: () => schema.icon ?? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_ant_design_icons.ReadOutlined, {}),
1598
- handler: (view, _state) => insertContainer(view, schema.name, defaultProps)
1599
- };
1600
- });
1601
- const handleScrollReady = (0, react.useCallback)((scrollDOM) => {
1602
- scrollDOMRef.current = scrollDOM;
3257
+ const registryVersion = useRegistryVersion();
3258
+ (0, react.useEffect)(() => {
3259
+ editorView?.dispatch({ effects: refreshContainers.of(null) });
3260
+ }, [registryVersion, editorView]);
3261
+ const extraToolbarItems = (0, react.useMemo)(() => {
3262
+ const merged = /* @__PURE__ */ new Map();
3263
+ for (const schema of componentRegistry.getAll()) merged.set(schema.name, schema);
3264
+ for (const schema of schemas ?? []) merged.set(schema.name, schema);
3265
+ return [...merged.values()].flatMap((schema) => {
3266
+ if (schema.wrapTags) return {
3267
+ id: `wrap-${schema.name}`,
3268
+ label: schema.label,
3269
+ icon: schema.icon ?? _ant_design_icons.ReadOutlined,
3270
+ wrapTags: schema.wrapTags
3271
+ };
3272
+ const defaultProps = {};
3273
+ for (const field of schema.fields ?? []) if (field.defaultValue !== void 0) defaultProps[field.key] = field.defaultValue;
3274
+ return {
3275
+ id: `container-${schema.name}`,
3276
+ label: schema.label,
3277
+ icon: schema.icon ?? _ant_design_icons.ReadOutlined,
3278
+ handler: (view) => insertContainer(view, schema.name, defaultProps)
3279
+ };
3280
+ });
3281
+ }, [registryVersion, schemas]);
3282
+ const handleScrollReady = (0, react.useCallback)((dom) => {
3283
+ setScrollDOM(dom);
1603
3284
  }, []);
1604
3285
  const handlePreviewRef = (0, react.useCallback)((node) => {
1605
- previewElRef.current = node;
3286
+ setPreviewEl(node);
1606
3287
  }, []);
1607
3288
  const handleViewReady = (0, react.useCallback)((view) => {
1608
3289
  setEditorView(view);
1609
3290
  }, []);
1610
- const handleEditContainer = (0, react.useCallback)((_view, typeName, propsLineFrom, propsLineTo, currentProps) => {
1611
- setDialogTypeName(typeName);
1612
- setDialogProps({ ...currentProps });
1613
- setDialogPropsRange([propsLineFrom, propsLineTo]);
3291
+ const handleEditContainer = (0, react.useCallback)((_view, container) => {
3292
+ setDialogTypeName(container.typeName);
3293
+ setDialogContainer(container);
3294
+ setDialogSeq((seq) => seq + 1);
1614
3295
  setDialogVisible(true);
1615
3296
  }, []);
1616
3297
  const handleDialogSave = (0, react.useCallback)((newProps) => {
1617
- if (editorView) updateContainerProps(editorView, dialogPropsRange[0], dialogPropsRange[1], newProps);
1618
- }, [editorView, dialogPropsRange]);
3298
+ if (editorView && dialogContainer) updateContainerProps(editorView, dialogContainer.startPos, dialogContainer.propsLineFrom, dialogContainer.propsLineTo, newProps, dialogContainer.quotePrefix);
3299
+ }, [editorView, dialogContainer]);
1619
3300
  const handleDialogClose = (0, react.useCallback)(() => {
1620
3301
  setDialogVisible(false);
1621
3302
  }, []);
3303
+ const editorNode = /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Editor, {
3304
+ value: content,
3305
+ onChange: internalSetContent,
3306
+ onScrollReady: handleScrollReady,
3307
+ onViewReady: handleViewReady,
3308
+ onEditContainer: handleEditContainer,
3309
+ uploadConfig,
3310
+ onMessageNoUploadConfig: () => notify("warning", "请先配置图片上传功能")
3311
+ });
1622
3312
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1623
3313
  className: fullscreen ? "markdown-editor-app fullscreen" : "markdown-editor-app",
1624
3314
  children: [
1625
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Toolbar, {
3315
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Toolbar_default, {
1626
3316
  editorView,
1627
3317
  fullscreen,
1628
3318
  onToggleFullscreen: fullscreenProp ? toggleFullscreen : void 0,
1629
3319
  extraItems: extraToolbarItems,
1630
- uploadConfig
3320
+ uploadConfig,
3321
+ notify
1631
3322
  }),
1632
3323
  showPreview ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SplitPanels, {
1633
- leftPanel: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Editor, {
1634
- value: content,
1635
- onChange: internalSetContent,
1636
- onScrollReady: handleScrollReady,
1637
- onViewReady: handleViewReady,
1638
- onEditContainer: handleEditContainer,
1639
- uploadConfig,
1640
- onMessageNoUploadConfig: () => antd.message.warning("请先配置图片上传功能")
1641
- }),
1642
- rightPanel: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Preview, {
3324
+ leftPanel: editorNode,
3325
+ rightPanel: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Preview_default, {
1643
3326
  content,
1644
3327
  ref: handlePreviewRef,
1645
3328
  previewOptions
1646
3329
  })
1647
- }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Editor, {
1648
- value: content,
1649
- onChange: internalSetContent,
1650
- onScrollReady: handleScrollReady,
1651
- onViewReady: handleViewReady,
1652
- onEditContainer: handleEditContainer,
1653
- uploadConfig,
1654
- onMessageNoUploadConfig: () => antd.message.warning("请先配置图片上传功能")
1655
- }),
3330
+ }) : editorNode,
1656
3331
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(EditDialog, {
1657
3332
  visible: dialogVisible,
1658
3333
  typeName: dialogTypeName,
1659
- currentProps: dialogProps,
3334
+ currentProps: dialogContainer?.props ?? {},
3335
+ initKey: dialogSeq,
1660
3336
  onSave: handleDialogSave,
1661
3337
  onClose: handleDialogClose
1662
3338
  })
1663
3339
  ]
1664
3340
  });
1665
- });
3341
+ };
3342
+ var MarkdownEditor = (0, react.forwardRef)(MarkdownEditorInner);
3343
+ /**
3344
+ * 包一层 antd App:为库内部的 message 等反馈组件提供上下文;
3345
+ * 宿主已有 App 包裹时内层仅作兜底(component={false} 不额外渲染 DOM)。
3346
+ */
3347
+ function MarkdownEditorWithApp({ ref, ...props }) {
3348
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(antd.App, {
3349
+ component: false,
3350
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(MarkdownEditor, {
3351
+ ...props,
3352
+ ref
3353
+ })
3354
+ });
3355
+ }
1666
3356
  //#endregion
1667
3357
  //#region src/hooks/useRegisterToolbar.ts
1668
3358
  /**
@@ -1759,14 +3449,17 @@ var MarkdownEditor_default = (0, react.forwardRef)(function MarkdownEditor({ def
1759
3449
  * @example 批量注册
1760
3450
  * ```tsx
1761
3451
  * function MyPage() {
3452
+ * // 注意:schema 需声明为稳定引用(组件外常量或 useMemo),
3453
+ * // 否则每次渲染都会重新注册;多实例互不干扰的场景请改用
3454
+ * // <MarkdownEditor schemas={[...]} /> 局部注册
1762
3455
  * useRegisterToolbar([schema1, schema2, schema3])
1763
3456
  * return <MarkdownEditor />
1764
3457
  * }
1765
3458
  * ```
1766
3459
  */
1767
3460
  function useRegisterToolbar(schemas) {
1768
- const schemaList = Array.isArray(schemas) ? schemas : [schemas];
1769
3461
  (0, react.useEffect)(() => {
3462
+ const schemaList = Array.isArray(schemas) ? schemas : [schemas];
1770
3463
  schemaList.forEach((schema) => {
1771
3464
  componentRegistry.register(schema.name, schema);
1772
3465
  });
@@ -1775,10 +3468,12 @@ function useRegisterToolbar(schemas) {
1775
3468
  componentRegistry.unregister(schema.name);
1776
3469
  });
1777
3470
  };
1778
- }, [schemaList]);
3471
+ }, [schemas]);
1779
3472
  }
1780
3473
  //#endregion
1781
- exports.MarkdownEditor = MarkdownEditor_default;
3474
+ exports.MarkdownEditor = MarkdownEditorWithApp;
3475
+ exports.getIconfontScriptUrl = getIconfontScriptUrl;
3476
+ exports.setIconfontScriptUrl = setIconfontScriptUrl;
1782
3477
  exports.useRegisterToolbar = useRegisterToolbar;
1783
3478
 
1784
3479
  //# sourceMappingURL=index.cjs.map