@hankchen/canvas-editor-vue 0.1.2 → 0.1.4

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.
@@ -0,0 +1,1674 @@
1
+ import { t as e } from "./createLucideIcon-SCvtEGVf.js";
2
+ import { c as t, d as n, f as r, l as i, o as a, p as o, s, u as c } from "./dist-DGtNmLwo.js";
3
+ import { i as l, n as u, o as d } from "./layerPath-uy2ywyld.js";
4
+ import { i as f, r as p } from "./completionAnchor-CDR5YZhu.js";
5
+ import { c as m, n as h, r as g, s as _, t as v, u as y } from "./useTransientFeedback-CTjmMmFF.js";
6
+ import { i as b, n as x, r as S, t as C } from "./uploadFile-BOfv8aLG.js";
7
+ import { n as w, t as T } from "./useViewport-D9Ipevzs.js";
8
+ import { Fragment as E, computed as D, createBlock as O, createCommentVNode as k, createElementBlock as A, createElementVNode as j, createVNode as M, defineComponent as N, mergeProps as P, nextTick as F, normalizeClass as I, normalizeStyle as L, onBeforeUnmount as R, onMounted as z, onScopeDispose as B, openBlock as V, ref as H, renderList as U, shallowRef as W, toDisplayString as G, unref as K, vModelText as ee, vShow as q, watch as J, withDirectives as Y, withKeys as X, withModifiers as Z } from "vue";
9
+ var Q = e({
10
+ name: "arrow-down-left",
11
+ size: 24,
12
+ node: [["path", {
13
+ d: "M17 7 7 17",
14
+ key: "15tmo1"
15
+ }], ["path", {
16
+ d: "M17 17H7V7",
17
+ key: "1org7z"
18
+ }]]
19
+ }), te = e({
20
+ name: "arrow-down-right",
21
+ size: 24,
22
+ node: [["path", {
23
+ d: "m7 7 10 10",
24
+ key: "1fmybs"
25
+ }], ["path", {
26
+ d: "M17 7v10H7",
27
+ key: "6fjiku"
28
+ }]]
29
+ }), ne = e({
30
+ name: "arrow-up-left",
31
+ size: 24,
32
+ node: [["path", {
33
+ d: "M7 17V7h10",
34
+ key: "11bw93"
35
+ }], ["path", {
36
+ d: "M17 17 7 7",
37
+ key: "2786uv"
38
+ }]]
39
+ }), re = e({
40
+ name: "arrow-up-right",
41
+ size: 24,
42
+ node: [["path", {
43
+ d: "M7 7h10v10",
44
+ key: "1tivn9"
45
+ }], ["path", {
46
+ d: "M7 17 17 7",
47
+ key: "1vkiza"
48
+ }]]
49
+ }), ie = e({
50
+ name: "chevron-up",
51
+ size: 24,
52
+ node: [["path", {
53
+ d: "m18 15-6-6-6 6",
54
+ key: "153udz"
55
+ }]]
56
+ }), ae = e({
57
+ name: "x",
58
+ size: 24,
59
+ node: [["path", {
60
+ d: "M18 6 6 18",
61
+ key: "1bl5f8"
62
+ }], ["path", {
63
+ d: "m6 6 12 12",
64
+ key: "d8bk6v"
65
+ }]]
66
+ });
67
+ //#endregion
68
+ //#region ../canvas-editor/src/spatial/camera.ts
69
+ function oe(e, t) {
70
+ if (!(t > 0)) return e;
71
+ let n = e.zoom * t;
72
+ return {
73
+ x: Math.round(e.x * n) / n,
74
+ y: Math.round(e.y * n) / n,
75
+ zoom: e.zoom
76
+ };
77
+ }
78
+ function se(e) {
79
+ return 6 / e;
80
+ }
81
+ function ce(e, t, n) {
82
+ let r = [];
83
+ for (let i = 0; i < e.layers.length; i += 1) {
84
+ if (t !== null && i === t) continue;
85
+ let o = e.layers[i];
86
+ o.visible !== !1 && r.push(a(o, 0, 0, e.width, e.height, n));
87
+ }
88
+ return r;
89
+ }
90
+ function le(e, t, n, r) {
91
+ let i = [];
92
+ for (let e of n) i.push({
93
+ orientation: "vertical",
94
+ position: e.x,
95
+ source: "layer"
96
+ }, {
97
+ orientation: "vertical",
98
+ position: e.x + e.width / 2,
99
+ source: "layer"
100
+ }, {
101
+ orientation: "vertical",
102
+ position: e.x + e.width,
103
+ source: "layer"
104
+ }, {
105
+ orientation: "horizontal",
106
+ position: e.y,
107
+ source: "layer"
108
+ }, {
109
+ orientation: "horizontal",
110
+ position: e.y + e.height / 2,
111
+ source: "layer"
112
+ }, {
113
+ orientation: "horizontal",
114
+ position: e.y + e.height,
115
+ source: "layer"
116
+ });
117
+ i.push({
118
+ orientation: "vertical",
119
+ position: e / 2,
120
+ source: "canvas-center"
121
+ }, {
122
+ orientation: "horizontal",
123
+ position: t / 2,
124
+ source: "canvas-center"
125
+ });
126
+ for (let e of r) i.push({
127
+ orientation: e.orientation,
128
+ position: e.position,
129
+ source: "guide"
130
+ });
131
+ return i;
132
+ }
133
+ function ue(e, t, n, r) {
134
+ let i = null;
135
+ for (let a of t) if (a.orientation === n) for (let t of e) {
136
+ let e = a.position - t, n = Math.abs(e);
137
+ n > r || (i === null || n < Math.abs(i.delta)) && (i = {
138
+ delta: e,
139
+ axis: a
140
+ });
141
+ }
142
+ return i;
143
+ }
144
+ function de(e, t, n) {
145
+ let r = ue(e.vertical, t, "vertical", n), i = ue(e.horizontal, t, "horizontal", n);
146
+ return {
147
+ dx: r ? r.delta : 0,
148
+ dy: i ? i.delta : 0,
149
+ axes: [...r ? [r.axis] : [], ...i ? [i.axis] : []]
150
+ };
151
+ }
152
+ function fe(e, t, n) {
153
+ return de({
154
+ vertical: [
155
+ e.x,
156
+ e.x + e.width / 2,
157
+ e.x + e.width
158
+ ],
159
+ horizontal: [
160
+ e.y,
161
+ e.y + e.height / 2,
162
+ e.y + e.height
163
+ ]
164
+ }, t, n);
165
+ }
166
+ //#endregion
167
+ //#region ../canvas-editor/src/spatial/resize.ts
168
+ function pe(e, t) {
169
+ let n = e.x + e.width, r = e.y + e.height;
170
+ switch (t) {
171
+ case "nw": return {
172
+ x: e.x,
173
+ y: e.y
174
+ };
175
+ case "n": return {
176
+ x: e.x + e.width / 2,
177
+ y: e.y
178
+ };
179
+ case "ne": return {
180
+ x: n,
181
+ y: e.y
182
+ };
183
+ case "e": return {
184
+ x: n,
185
+ y: e.y + e.height / 2
186
+ };
187
+ case "se": return {
188
+ x: n,
189
+ y: r
190
+ };
191
+ case "s": return {
192
+ x: e.x + e.width / 2,
193
+ y: r
194
+ };
195
+ case "sw": return {
196
+ x: e.x,
197
+ y: r
198
+ };
199
+ case "w": return {
200
+ x: e.x,
201
+ y: e.y + e.height / 2
202
+ };
203
+ }
204
+ }
205
+ //#endregion
206
+ //#region ../canvas-editor/src/spatial/wheel.ts
207
+ function me(e) {
208
+ return e.ctrlKey || e.metaKey ? "zoom" : e.shiftKey ? "pan-x" : "pan";
209
+ }
210
+ //#endregion
211
+ //#region ../canvas-browser-renderer/src/fonts.ts
212
+ function he(e) {
213
+ return e === "" || /^[+-]?(?:\d+(?:\.\d*)?|\.\d+)(?:[eE][+-]?\d+)?$/.test(e.trim());
214
+ }
215
+ function ge(e) {
216
+ return he(e) ? "sans-serif" : `${_e(e)}, sans-serif`;
217
+ }
218
+ function _e(e) {
219
+ let t = 2166136261;
220
+ for (let n = 0; n < e.length; n++) t ^= e.charCodeAt(n), t = Math.imul(t, 16777619);
221
+ return `canvas-font-${(t >>> 0).toString(36)}`;
222
+ }
223
+ //#endregion
224
+ //#region src/canvas/AlignFloatBar.vue?vue&type=script&setup=true&lang.ts
225
+ var ve = ["aria-disabled"], ye = {
226
+ key: 0,
227
+ class: "cn-align-float__divider",
228
+ "aria-hidden": "true"
229
+ }, be = { class: "cn-align-float__group" }, xe = [
230
+ "disabled",
231
+ "title",
232
+ "aria-label",
233
+ "onClick"
234
+ ], Se = /*#__PURE__*/ y(/* @__PURE__ */ N({
235
+ __name: "AlignFloatBar",
236
+ props: { editor: {} },
237
+ setup(e) {
238
+ let a = e, s = w(a.editor), l = D(() => s.value !== null), u = (e) => `贴${e}角(边距 40px)`, d = [
239
+ { keys: [{
240
+ mode: "h-center",
241
+ icon: r,
242
+ title: "水平居中"
243
+ }, {
244
+ mode: "v-center",
245
+ icon: o,
246
+ title: "垂直居中"
247
+ }] },
248
+ { keys: [
249
+ {
250
+ mode: "left",
251
+ icon: t,
252
+ title: "贴左"
253
+ },
254
+ {
255
+ mode: "right",
256
+ icon: c,
257
+ title: "贴右"
258
+ },
259
+ {
260
+ mode: "top",
261
+ icon: i,
262
+ title: "贴顶"
263
+ },
264
+ {
265
+ mode: "bottom",
266
+ icon: n,
267
+ title: "贴底"
268
+ }
269
+ ] },
270
+ { keys: [
271
+ {
272
+ mode: "corner-tl",
273
+ icon: ne,
274
+ title: u("左上")
275
+ },
276
+ {
277
+ mode: "corner-tr",
278
+ icon: re,
279
+ title: u("右上")
280
+ },
281
+ {
282
+ mode: "corner-bl",
283
+ icon: Q,
284
+ title: u("左下")
285
+ },
286
+ {
287
+ mode: "corner-br",
288
+ icon: te,
289
+ title: u("右下")
290
+ }
291
+ ] }
292
+ ];
293
+ function p(e) {
294
+ return { [`data-align-${e}`]: "" };
295
+ }
296
+ function m(e) {
297
+ let t = s.value;
298
+ t && (e.startsWith("corner-") ? a.editor.alignToCanvas(t, e, { margin: 40 }) : a.editor.alignToCanvas(t, e));
299
+ }
300
+ return (e, t) => (V(), A("div", {
301
+ class: I(["cn-align-float", { "cn-align-float--disabled": !l.value }]),
302
+ role: "toolbar",
303
+ "aria-label": "对齐画布",
304
+ "data-align-float": "",
305
+ "aria-disabled": l.value ? void 0 : "true"
306
+ }, [(V(), A(E, null, U(d, (e, t) => (V(), A(E, { key: t }, [t > 0 ? (V(), A("span", ye)) : k("", !0), j("span", be, [(V(!0), A(E, null, U(e.keys, (e) => (V(), A("button", P({
307
+ key: e.mode,
308
+ type: "button",
309
+ class: "cn-align-float__key",
310
+ disabled: !l.value,
311
+ title: e.title,
312
+ "aria-label": e.title
313
+ }, { ref_for: !0 }, p(e.mode), { onClick: (t) => m(e.mode) }), [M(f, { icon: e.icon }, null, 8, ["icon"])], 16, xe))), 128))])], 64))), 64))], 10, ve));
314
+ }
315
+ }), [["__scopeId", "data-v-9a761d37"]]), Ce = {
316
+ key: 0,
317
+ class: "cn-context-menu__form"
318
+ }, we = { class: "cn-context-menu__hint" }, Te = ["onKeydown"], Ee = {
319
+ key: 0,
320
+ class: "cn-context-menu__hint cn-context-menu__hint--error"
321
+ }, De = [
322
+ "disabled",
323
+ "title",
324
+ "onClick"
325
+ ], Oe = /*#__PURE__*/ y(/* @__PURE__ */ N({
326
+ __name: "ContextMenu",
327
+ props: { editor: {} },
328
+ setup(e, { expose: t }) {
329
+ let n = e, r = H(null), i = H(!1), a = H({
330
+ x: 0,
331
+ y: 0
332
+ }), o = _(), s = `先 ${m("copyStyle", o)} 复制样式`, c = `图层已锁定(${m("toggleLayerLock", o)} 解锁后可删除)`, l = w(n.editor), f = D(() => l.value !== null && u(l.value)), p = D(() => l.value !== null && n.editor.canCopySelection), h = D(() => (i.value, l.value !== null && n.editor.canCopyStyle)), g = D(() => (i.value, l.value !== null && n.editor.canPasteStyle)), v = D(() => {
333
+ let e = l.value, t = n.editor.store.doc;
334
+ return !e || !t || !u(e) ? !0 : d(t, e)?.visible ?? !0;
335
+ }), y = D(() => {
336
+ let e = l.value, t = n.editor.store.doc;
337
+ return !e || !t ? null : d(t, e);
338
+ });
339
+ function b() {
340
+ let e = l.value;
341
+ return !e || typeof e[1] != "number" ? null : ["layers", e[1]];
342
+ }
343
+ let x = D(() => y.value?.type === "TableLayer" && y.value.template !== null), S = D(() => l.value?.[l.value.length - 1] === "template"), C = D(() => l.value !== null && n.editor.isLocked(l.value)), T = D(() => {
344
+ let e = y.value;
345
+ if (!e || e.type !== "TableLayer" || e.template !== null) return !1;
346
+ let t = e.rows[e.rows.length - 1];
347
+ return t !== void 0 && t.cells.length > 0;
348
+ }), O = D(() => {
349
+ let e = y.value;
350
+ return !e || e.type !== "TableLayer" ? "" : `模板取自末行,其余 ${Math.max(e.rows.length - 1, 0)} 行将移除(可撤销)`;
351
+ }), M = H(!1), N = H(""), P = H(!1);
352
+ function R() {
353
+ M.value = !0, N.value = "", P.value = !1;
354
+ }
355
+ function z() {
356
+ let e = b(), t = N.value.trim();
357
+ if (!e || t === "") {
358
+ P.value = !0;
359
+ return;
360
+ }
361
+ n.editor.convertTableToTemplate(e, t), K();
362
+ }
363
+ let B = D(() => [
364
+ {
365
+ key: "visibility",
366
+ label: v.value ? "隐藏" : "显示",
367
+ enabled: f.value,
368
+ title: f.value ? void 0 : "显示/隐藏仅作用于根图层",
369
+ run: () => {
370
+ let e = l.value;
371
+ e && n.editor.toggleLayerVisibility(e);
372
+ }
373
+ },
374
+ {
375
+ key: "duplicate",
376
+ label: "创建副本",
377
+ enabled: p.value,
378
+ title: p.value ? void 0 : "行/格/行模板是容器内结构,不可复制",
379
+ run: () => n.editor.duplicateSelection()
380
+ },
381
+ {
382
+ key: "copy-style",
383
+ label: "复制样式",
384
+ enabled: h.value,
385
+ title: !h.value && S.value ? "行模板替身无样式可复制" : void 0,
386
+ run: () => {
387
+ let e = l.value;
388
+ e && n.editor.copyStyle(e);
389
+ }
390
+ },
391
+ {
392
+ key: "paste-style",
393
+ label: "粘贴样式",
394
+ enabled: g.value,
395
+ title: g.value ? void 0 : s,
396
+ run: () => {
397
+ let e = l.value;
398
+ e && n.editor.pasteStyle(e);
399
+ }
400
+ },
401
+ {
402
+ key: "forward",
403
+ label: "前移一层",
404
+ enabled: f.value,
405
+ title: f.value ? void 0 : "前移/后移仅对根图层生效",
406
+ run: () => n.editor.bringForward()
407
+ },
408
+ {
409
+ key: "backward",
410
+ label: "后移一层",
411
+ enabled: f.value,
412
+ title: f.value ? void 0 : "前移/后移仅对根图层生效",
413
+ run: () => n.editor.sendBackward()
414
+ },
415
+ {
416
+ key: "front",
417
+ label: "置顶",
418
+ enabled: f.value,
419
+ title: f.value ? void 0 : "置顶/置底仅对根图层生效",
420
+ run: () => n.editor.bringToFront()
421
+ },
422
+ {
423
+ key: "back",
424
+ label: "置底",
425
+ enabled: f.value,
426
+ title: f.value ? void 0 : "置顶/置底仅对根图层生效",
427
+ run: () => n.editor.sendToBack()
428
+ },
429
+ ...x.value ? [{
430
+ key: "to-rows",
431
+ label: "转回普通表",
432
+ enabled: !0,
433
+ title: "行模板实例化为单行,恢复普通表格编辑",
434
+ run: () => {
435
+ let e = b();
436
+ e && n.editor.convertTableToRows(e);
437
+ }
438
+ }] : y.value?.type === "TableLayer" ? [{
439
+ key: "to-template",
440
+ label: "转为模板表…",
441
+ enabled: T.value,
442
+ title: T.value ? O.value : y.value.rows.length === 0 ? "空表无可转换行" : "末行为空——先为末行加格",
443
+ keepsOpen: !0,
444
+ run: () => R()
445
+ }] : [],
446
+ {
447
+ key: "delete",
448
+ label: "删除",
449
+ enabled: l.value !== null && !S.value && !C.value,
450
+ title: S.value ? "行模板由表持有——转换回普通表请用 V2 转换入口" : C.value ? c : void 0,
451
+ run: () => {
452
+ let e = l.value;
453
+ e && n.editor.deleteLayer(e);
454
+ }
455
+ }
456
+ ]);
457
+ async function W(e, t) {
458
+ a.value = {
459
+ x: e,
460
+ y: t
461
+ }, i.value = !0, await F();
462
+ let n = r.value, o = n?.parentElement;
463
+ if (!n || !o) return;
464
+ let s = n.getBoundingClientRect(), c = o.clientWidth - s.width - 2, l = o.clientHeight - s.height - 2;
465
+ a.value = {
466
+ x: Math.max(2, Math.min(a.value.x, c)),
467
+ y: Math.max(2, Math.min(a.value.y, l))
468
+ };
469
+ }
470
+ function K() {
471
+ i.value = !1, M.value = !1, N.value = "", P.value = !1;
472
+ }
473
+ function q(e) {
474
+ e.run(), e.keepsOpen !== !0 && K();
475
+ }
476
+ return t({
477
+ openAt: W,
478
+ close: K
479
+ }), (e, t) => i.value ? (V(), A("div", {
480
+ key: 0,
481
+ ref_key: "rootRef",
482
+ ref: r,
483
+ class: "cn-context-menu",
484
+ role: "menu",
485
+ "aria-label": "图层操作菜单",
486
+ style: L({
487
+ left: `${a.value.x}px`,
488
+ top: `${a.value.y}px`
489
+ }),
490
+ onPointerdown: t[1] ||= Z(() => {}, ["stop"]),
491
+ onContextmenu: t[2] ||= Z(() => {}, ["prevent"])
492
+ }, [M.value ? (V(), A("div", Ce, [
493
+ j("p", we, G(O.value), 1),
494
+ Y(j("input", {
495
+ "onUpdate:modelValue": t[0] ||= (e) => N.value = e,
496
+ "data-convert-rows-path": "",
497
+ type: "text",
498
+ placeholder: "数据行路径,如 order.items",
499
+ class: I(["cn-context-menu__input", { "cn-context-menu__input--invalid": P.value }]),
500
+ onKeydown: X(Z(z, ["prevent"]), ["enter"])
501
+ }, null, 42, Te), [[ee, N.value]]),
502
+ P.value ? (V(), A("p", Ee, " rowsPath 必填 ")) : k("", !0),
503
+ j("div", { class: "cn-context-menu__form-actions" }, [j("button", {
504
+ type: "button",
505
+ class: "cn-context-menu__item cn-context-menu__item--confirm",
506
+ onClick: z
507
+ }, " 确认转换 "), j("button", {
508
+ type: "button",
509
+ class: "cn-context-menu__item",
510
+ onClick: K
511
+ }, "取消")])
512
+ ])) : (V(!0), A(E, { key: 1 }, U(B.value, (e) => (V(), A("button", {
513
+ key: e.key,
514
+ type: "button",
515
+ role: "menuitem",
516
+ class: I(["cn-context-menu__item", [`cn-context-menu__item--${e.key}`]]),
517
+ disabled: !e.enabled,
518
+ title: e.title,
519
+ onClick: (t) => q(e)
520
+ }, G(e.label), 11, De))), 128))], 36)) : k("", !0);
521
+ }
522
+ }), [["__scopeId", "data-v-e554ef38"]]);
523
+ //#endregion
524
+ //#region src/canvas/useFindSession.ts
525
+ function ke(e) {
526
+ let t = W(e.store.ui.find.open), n = W(e.store.ui.find.query), r = W(e.store.ui.find.replacement), i = W(e.listFindMatches()), a = W(e.findCursor), o = () => {
527
+ let o = e.store.ui.find;
528
+ t.value = o.open, n.value = o.query, r.value = o.replacement, i.value = e.listFindMatches(), a.value = e.findCursor;
529
+ }, s = e.subscribe((e) => {
530
+ (e.scope === "doc" || e.scope === "ui" && e.branch === "find") && o();
531
+ });
532
+ return B(s, !0), {
533
+ open: t,
534
+ query: n,
535
+ replacement: r,
536
+ matches: i,
537
+ cursor: a
538
+ };
539
+ }
540
+ //#endregion
541
+ //#region src/canvas/FindBar.vue?vue&type=script&setup=true&lang.ts
542
+ var Ae = ["value"], je = ["value"], Me = {
543
+ class: "cn-find-bar__count",
544
+ "data-find-count": ""
545
+ }, Ne = {
546
+ key: 0,
547
+ class: "cn-find-bar__note",
548
+ "data-find-note": ""
549
+ }, Pe = ["disabled"], Fe = ["disabled"], Ie = ["disabled"], Le = ["disabled"], Re = /*#__PURE__*/ y(/* @__PURE__ */ N({
550
+ __name: "FindBar",
551
+ props: { editor: {} },
552
+ setup(e, { expose: t }) {
553
+ let n = e, { open: r, query: i, replacement: a, matches: o, cursor: c } = ke(n.editor), l = H(null), u = H(null), d = D(() => {
554
+ let e = o.value.length;
555
+ return e === 0 ? i.value === "" ? "" : "无结果" : `第 ${c.value + 1}/${e} 处`;
556
+ }), p = D(() => o.value.length > 0), m = D(() => p.value && c.value > 0), g = D(() => p.value && c.value < o.value.length - 1);
557
+ function _(e) {
558
+ let t = o.value[e];
559
+ if (!t) return;
560
+ n.editor.setSelection(t.path);
561
+ let r = n.editor.layerBoxAt(t.path);
562
+ r && n.editor.panToBox(r);
563
+ }
564
+ function v(e) {
565
+ let t = o.value.length;
566
+ if (t === 0) return;
567
+ let r = Math.min(Math.max(c.value + e, 0), t - 1);
568
+ n.editor.setFindCursor(r), _(r);
569
+ }
570
+ function y() {
571
+ n.editor.replaceOne() && _(c.value);
572
+ }
573
+ function b() {
574
+ let e = n.editor.replaceAll();
575
+ e !== 0 && (u.value = `已替换 ${e} 处`, _(c.value));
576
+ }
577
+ function x() {
578
+ n.editor.closeFind(), u.value = null;
579
+ }
580
+ function S(e) {
581
+ if (!(e.isComposing || e.keyCode === 229)) {
582
+ if (e.key === "Escape") {
583
+ e.preventDefault(), x();
584
+ return;
585
+ }
586
+ e.key === "Enter" && (e.preventDefault(), v(e.shiftKey ? -1 : 1));
587
+ }
588
+ }
589
+ function C(e) {
590
+ n.editor.setFindQuery(e.target.value);
591
+ }
592
+ function w(e) {
593
+ n.editor.setFindReplacement(e.target.value);
594
+ }
595
+ J(r, (e) => {
596
+ e && l.value?.focus({ preventScroll: !0 });
597
+ }, {
598
+ immediate: !0,
599
+ flush: "post"
600
+ });
601
+ function T(e) {
602
+ r.value && (e.key.toLowerCase() !== "f" || !(e.metaKey || e.ctrlKey) || e.shiftKey || e.altKey || h(e.target) || l.value?.focus({ preventScroll: !0 }));
603
+ }
604
+ return window.addEventListener("keydown", T), R(() => window.removeEventListener("keydown", T)), J(i, () => {
605
+ u.value = null;
606
+ }), t({ close: x }), (e, t) => K(r) ? (V(), A("div", {
607
+ key: 0,
608
+ class: "cn-find-bar",
609
+ "data-find-bar": "",
610
+ role: "search",
611
+ "aria-label": "查找替换",
612
+ onPointerdown: t[2] ||= Z(() => {}, ["stop"])
613
+ }, [
614
+ j("input", {
615
+ ref_key: "queryInput",
616
+ ref: l,
617
+ class: "cn-find-bar__input",
618
+ "data-find-query": "",
619
+ type: "text",
620
+ value: K(i),
621
+ placeholder: "查找",
622
+ "aria-label": "查找",
623
+ spellcheck: "false",
624
+ autocomplete: "off",
625
+ onInput: C,
626
+ onKeydown: S
627
+ }, null, 40, Ae),
628
+ j("input", {
629
+ class: "cn-find-bar__input",
630
+ "data-find-replace": "",
631
+ type: "text",
632
+ value: K(a),
633
+ placeholder: "替换",
634
+ "aria-label": "替换",
635
+ spellcheck: "false",
636
+ autocomplete: "off",
637
+ onInput: w,
638
+ onKeydown: S
639
+ }, null, 40, je),
640
+ j("span", Me, G(d.value), 1),
641
+ u.value ? (V(), A("span", Ne, G(u.value), 1)) : k("", !0),
642
+ j("button", {
643
+ type: "button",
644
+ class: "cn-find-bar__key",
645
+ "data-find-prev": "",
646
+ disabled: !m.value,
647
+ title: "上一处(Shift+Enter)",
648
+ "aria-label": "上一处",
649
+ onClick: t[0] ||= (e) => v(-1)
650
+ }, [M(f, { icon: K(ie) }, null, 8, ["icon"])], 8, Pe),
651
+ j("button", {
652
+ type: "button",
653
+ class: "cn-find-bar__key",
654
+ "data-find-next": "",
655
+ disabled: !g.value,
656
+ title: "下一处(Enter)",
657
+ "aria-label": "下一处",
658
+ onClick: t[1] ||= (e) => v(1)
659
+ }, [M(f, { icon: K(s) }, null, 8, ["icon"])], 8, Fe),
660
+ j("button", {
661
+ type: "button",
662
+ class: "cn-find-bar__action",
663
+ "data-find-replace-one": "",
664
+ disabled: !p.value,
665
+ title: "替换当前处",
666
+ onClick: y
667
+ }, " 替换 ", 8, Ie),
668
+ j("button", {
669
+ type: "button",
670
+ class: "cn-find-bar__action",
671
+ "data-find-replace-all": "",
672
+ disabled: !p.value,
673
+ title: "全部替换",
674
+ onClick: b
675
+ }, " 全部替换 ", 8, Le),
676
+ j("button", {
677
+ type: "button",
678
+ class: "cn-find-bar__key",
679
+ "data-find-close": "",
680
+ title: "关闭(Esc)",
681
+ "aria-label": "关闭查找替换",
682
+ onClick: x
683
+ }, [M(f, { icon: K(ae) }, null, 8, ["icon"])])
684
+ ], 32)) : k("", !0);
685
+ }
686
+ }), [["__scopeId", "data-v-71f0a3ae"]]), ze = {
687
+ nw: "nwse-resize",
688
+ se: "nwse-resize",
689
+ ne: "nesw-resize",
690
+ sw: "nesw-resize",
691
+ n: "ns-resize",
692
+ s: "ns-resize",
693
+ e: "ew-resize",
694
+ w: "ew-resize"
695
+ }, Be = [
696
+ "aria-pressed",
697
+ "data-pill-static",
698
+ "data-pill-expression",
699
+ "onClick"
700
+ ], Ve = /*#__PURE__*/ y(/* @__PURE__ */ N({
701
+ __name: "ContentTypePill",
702
+ props: { mode: {} },
703
+ emits: ["change"],
704
+ setup(e, { expose: t, emit: n }) {
705
+ let r = e, i = n, a = H(null);
706
+ t({ rootEl: a });
707
+ let o = [{
708
+ value: "static",
709
+ label: "静态"
710
+ }, {
711
+ value: "expression",
712
+ label: "表达式"
713
+ }];
714
+ function s(e) {
715
+ e !== r.mode && i("change", e);
716
+ }
717
+ return (t, n) => (V(), A("div", {
718
+ ref_key: "rootRef",
719
+ ref: a,
720
+ class: "cn-content-pill",
721
+ role: "group",
722
+ "aria-label": "内容类型",
723
+ "data-content-pill": "",
724
+ onPointerdown: n[0] ||= Z(() => {}, ["prevent"])
725
+ }, [(V(), A(E, null, U(o, (t) => j("button", {
726
+ key: t.value,
727
+ type: "button",
728
+ class: I(["cn-content-pill__item", { "cn-content-pill__item--active": t.value === e.mode }]),
729
+ "aria-pressed": t.value === e.mode,
730
+ "data-pill-static": t.value === "static" || void 0,
731
+ "data-pill-expression": t.value === "expression" || void 0,
732
+ onClick: (e) => s(t.value)
733
+ }, G(t.label), 11, Be)), 64))], 544));
734
+ }
735
+ }), [["__scopeId", "data-v-d99d2c13"]]);
736
+ //#endregion
737
+ //#region src/canvas/useDpr.ts
738
+ function $(e) {
739
+ let t = null, n = () => {
740
+ t?.removeEventListener("change", n), e(window.devicePixelRatio || 1), t = window.matchMedia(`(resolution: ${window.devicePixelRatio}dppx)`), t.addEventListener("change", n);
741
+ };
742
+ return n(), () => t?.removeEventListener("change", n);
743
+ }
744
+ function He() {
745
+ let e = W(window.devicePixelRatio || 1), t = $((t) => {
746
+ e.value = t;
747
+ });
748
+ return B(t, !0), e;
749
+ }
750
+ //#endregion
751
+ //#region src/canvas/useTextEditing.ts
752
+ var Ue = /* @__PURE__ */ new Map();
753
+ function We(e, t) {
754
+ let n = `${e}|${t}`, r = Ue.get(n);
755
+ if (r !== void 0) return r;
756
+ let i = t * 1.2;
757
+ try {
758
+ let n = document.createElement("canvas").getContext("2d");
759
+ if (n) {
760
+ n.font = `${t}px ${ge(e)}`;
761
+ let r = n.measureText("字"), a = (r.fontBoundingBoxAscent ?? r.actualBoundingBoxAscent) + (r.fontBoundingBoxDescent ?? r.actualBoundingBoxDescent);
762
+ a > 0 && (i = a);
763
+ }
764
+ } catch {}
765
+ return Ue.set(n, i), i;
766
+ }
767
+ function Ge(e, t) {
768
+ let n = W(e.store.ui.editing), r = e.subscribe((t) => {
769
+ (t.scope === "doc" || t.scope === "ui" && t.branch === "editing") && (n.value = e.store.ui.editing);
770
+ });
771
+ B(r, !0);
772
+ let i = D(() => n.value?.path ?? null), a = He(), o = T(e), s = D(() => {
773
+ let t = n.value;
774
+ return t ? e.textEditLayout(t.path) : null;
775
+ }), c = D(() => oe(o.value, a.value));
776
+ function l(e, t) {
777
+ let { x: n, y: r, zoom: i } = c.value;
778
+ return {
779
+ left: (e - n) * i,
780
+ top: (t - r) * i,
781
+ zoom: i
782
+ };
783
+ }
784
+ let u = D(() => {
785
+ let e = s.value;
786
+ if (!e) return null;
787
+ let { left: t, top: n, zoom: r } = l(e.box.x, e.box.y);
788
+ return {
789
+ transform: `translate(${t}px, ${n}px) scale(${r})`,
790
+ transformOrigin: "0 0",
791
+ width: `${e.box.width}px`,
792
+ height: `${e.box.height}px`,
793
+ color: e.fontColor,
794
+ fontFamily: ge(e.font),
795
+ fontSize: `${e.fontSize}px`,
796
+ lineHeight: `${e.lineHeightPx}px`,
797
+ ...f(e),
798
+ textAlign: e.horizontalAlign,
799
+ whiteSpace: e.autowrap ? "pre-wrap" : "pre"
800
+ };
801
+ }), d = D(() => {
802
+ let e = s.value;
803
+ if (!e) return null;
804
+ let { left: t, top: n, zoom: r } = l(e.box.x + e.box.width / 2, e.box.y);
805
+ return {
806
+ transform: `translate(${t}px, ${n}px) scale(${r}) translate(-50%, -100%)`,
807
+ transformOrigin: "0 0"
808
+ };
809
+ });
810
+ function f(e) {
811
+ let t = e.padding.top + e.verticalAnchorY, n = e.lineHeightPx, r = We(e.font, e.fontSize), i;
812
+ return i = e.verticalAlign === "center" ? t - n / 2 : e.verticalAlign === "bottom" ? t - (n + r) / 2 : t - (n - r) / 2, {
813
+ paddingTop: `${Math.max(0, i)}px`,
814
+ paddingRight: `${e.padding.right}px`,
815
+ paddingBottom: `${e.padding.bottom}px`,
816
+ paddingLeft: `${e.padding.left}px`
817
+ };
818
+ }
819
+ let p = (t, n) => {
820
+ let r = e.hitTest(t, n);
821
+ return r !== null && e.beginTextEdit(r);
822
+ }, m = (t) => e.beginTextEdit(t), h = (t) => {
823
+ let n = e.store.ui.editing;
824
+ n && n.expression !== t && e.store.setEditing({
825
+ path: n.path,
826
+ expression: t
827
+ });
828
+ }, g = null, _ = !1, v = !1, y = () => {
829
+ e.commitTextEdit(t.getTextarea()?.value ?? "");
830
+ }, b = () => {
831
+ g !== null && clearTimeout(g), g = null;
832
+ }, x = () => {
833
+ if (b(), S.value) {
834
+ v = !0;
835
+ return;
836
+ }
837
+ y();
838
+ }, S = W(!1), C = (e) => {
839
+ S.value = e, !e && v && (v = !1, i.value !== null && y());
840
+ }, w = () => {
841
+ if (i.value !== null) {
842
+ if (b(), _) {
843
+ _ = !1;
844
+ return;
845
+ }
846
+ g = setTimeout(() => {
847
+ g = null;
848
+ let e = t.getTextarea();
849
+ if (e === null || document.activeElement !== e) {
850
+ if (S.value) {
851
+ v = !0;
852
+ return;
853
+ }
854
+ y();
855
+ }
856
+ }, 0);
857
+ }
858
+ }, E = (e) => {
859
+ if (!(e instanceof Node)) return !1;
860
+ let n = t.getPill?.() ?? null;
861
+ if (n !== null && n.contains(e)) return !0;
862
+ let r = t.getTextarea();
863
+ return r !== null && r.contains(e);
864
+ }, O = (e) => {
865
+ if (i.value === null || E(e.target)) return;
866
+ let n = t.getHost();
867
+ n !== null && n.contains(e.target) || (_ = !0);
868
+ }, k = () => {
869
+ _ = !1;
870
+ };
871
+ return window.addEventListener("pointerdown", O, !0), window.addEventListener("pointerup", k, !0), B(() => {
872
+ window.removeEventListener("pointerdown", O, !0), window.removeEventListener("pointerup", k, !0), b();
873
+ }, !0), {
874
+ editing: i,
875
+ layout: s,
876
+ style: u,
877
+ pillStyle: d,
878
+ scale: D(() => c.value.zoom),
879
+ composing: D(() => S.value),
880
+ setComposing: C,
881
+ beginAt: p,
882
+ beginTextEdit: m,
883
+ commitNow: x,
884
+ setExpressionMode: h,
885
+ armBlurCommit: w,
886
+ ownsEventTarget: E
887
+ };
888
+ }
889
+ //#endregion
890
+ //#region src/canvas/TextEditingOverlay.vue?vue&type=script&setup=true&lang.ts
891
+ var Ke = ["wrap"], qe = /*#__PURE__*/ y(/* @__PURE__ */ N({
892
+ __name: "TextEditingOverlay",
893
+ props: { editor: {} },
894
+ setup(e, { expose: t }) {
895
+ let n = e, r = H(null), i = H(null), a = H(null), o = H(null), s = Ge(n.editor, {
896
+ getTextarea: () => i.value,
897
+ getHost: () => r.value?.parentElement ?? null,
898
+ getPill: () => a.value?.rootEl ?? null
899
+ }), { editing: c, style: l, composing: u, pillStyle: d } = s, f = s.layout, m = D(() => f.value?.expressionMode === !0), { popup: h, accept: g } = x({
900
+ target: i,
901
+ enabled: m,
902
+ resolve: (e) => {
903
+ let t = n.editor.store.ui.dataSourceSchema, r = c.value;
904
+ if (t === null || r === null) return null;
905
+ let i = S(t, b(t, n.editor.store.doc, r));
906
+ return i === null ? null : i(e);
907
+ },
908
+ popupEl: () => o.value?.rootEl ?? null,
909
+ scale: s.scale
910
+ });
911
+ J(c, async (e) => {
912
+ if (!e) return;
913
+ await F();
914
+ let t = i.value, n = s.layout.value;
915
+ t && n && (t.value = n.text, t.focus({ preventScroll: !0 }), t.select());
916
+ }), J(l, async (e, t) => {
917
+ if (!t || !e) return;
918
+ let n = i.value;
919
+ if (!n || u.value) return;
920
+ let r = n.selectionStart, a = n.selectionEnd;
921
+ await F(), i.value === n && (n.selectionStart !== r || n.selectionEnd !== a) && n.setSelectionRange(r, a);
922
+ }, { flush: "post" });
923
+ let _ = (e) => {
924
+ e.isComposing || e.keyCode === 229 || (e.key === "Escape" || e.key === "Enter" && (e.ctrlKey || e.metaKey)) && (e.key === "Escape" && h.open || (e.preventDefault(), s.commitNow()));
925
+ }, v = () => s.armBlurCommit();
926
+ return t({
927
+ beginAt: s.beginAt,
928
+ beginTextEdit: s.beginTextEdit,
929
+ commitEditing: () => s.commitNow(),
930
+ isEditing: () => c.value !== null,
931
+ ownsEventTarget: (e) => s.ownsEventTarget(e)
932
+ }), (e, t) => (V(), A("div", {
933
+ ref_key: "rootRef",
934
+ ref: r,
935
+ class: "cn-text-overlay"
936
+ }, [
937
+ K(c) && K(l) ? (V(), A("textarea", {
938
+ key: K(c).join(""),
939
+ ref_key: "textareaRef",
940
+ ref: i,
941
+ class: "cn-text-overlay__textarea",
942
+ style: L(K(l)),
943
+ wrap: K(l).whiteSpace === "pre" ? "off" : "soft",
944
+ spellcheck: "false",
945
+ autocomplete: "off",
946
+ onKeydown: _,
947
+ onBlur: v,
948
+ onCompositionstart: t[0] ||= (e) => K(s).setComposing(!0),
949
+ onCompositionend: t[1] ||= (e) => K(s).setComposing(!1)
950
+ }, null, 44, Ke)) : k("", !0),
951
+ K(c) && K(d) ? (V(), O(Ve, {
952
+ key: 1,
953
+ ref_key: "pillRef",
954
+ ref: a,
955
+ style: L(K(d)),
956
+ mode: m.value ? "expression" : "static",
957
+ onChange: t[2] ||= (e) => K(s).setExpressionMode(e === "expression")
958
+ }, null, 8, ["style", "mode"])) : k("", !0),
959
+ M(p, {
960
+ ref_key: "popupRef",
961
+ ref: o,
962
+ state: K(h),
963
+ onSelect: K(g)
964
+ }, null, 8, ["state", "onSelect"])
965
+ ], 512));
966
+ }
967
+ }), [["__scopeId", "data-v-bc9281f8"]]), Je = {
968
+ key: 0,
969
+ class: "cn-surface__drop-hint",
970
+ "data-drop-hint": ""
971
+ }, Ye = 16, Xe = /*#__PURE__*/ y(/* @__PURE__ */ N({
972
+ __name: "CanvasSurface",
973
+ props: { editor: {} },
974
+ emits: ["ready"],
975
+ setup(e, { emit: t }) {
976
+ let n = e, r = t, i = H(null), a = H(null), o = H(null), s = H(null), c = H(null), l = H(null), u = H(!1), d = H(!1), f = H(null), p = H(null), m = H(n.editor.store.ui.armedCreate), _ = H(!1), y = D(() => d.value ? "cn-surface--panning" : u.value ? "cn-surface--pannable" : ""), b = D(() => {
977
+ if (d.value) return;
978
+ if (m.value !== null || _.value) return u.value ? void 0 : { cursor: "crosshair" };
979
+ let e = p.value ?? f.value;
980
+ return e === null ? void 0 : { cursor: ze[e] };
981
+ }), x = H(!1), S = v();
982
+ function w(e) {
983
+ return new Promise((t, n) => {
984
+ let r = URL.createObjectURL(e), i = new Image();
985
+ i.onload = () => {
986
+ URL.revokeObjectURL(r), t({
987
+ width: i.naturalWidth,
988
+ height: i.naturalHeight
989
+ });
990
+ }, i.onerror = () => {
991
+ URL.revokeObjectURL(r), n(/* @__PURE__ */ Error(`无法解码图片:${e.name}`));
992
+ }, i.src = r;
993
+ });
994
+ }
995
+ let T = [];
996
+ return z(() => {
997
+ let e = i.value, t = a.value, v = o.value;
998
+ if (!e || !t || !v) return;
999
+ let y = n.editor, b = () => {
1000
+ let n = window.devicePixelRatio, r = Math.max(1, Math.round(e.clientWidth * n)), i = Math.max(1, Math.round(e.clientHeight * n));
1001
+ for (let e of [t, v]) e.width !== r && (e.width = r), e.height !== i && (e.height = i);
1002
+ y.flushPendingFrames();
1003
+ }, E = () => {
1004
+ y.setSurfaceSize(e.clientWidth, e.clientHeight), b();
1005
+ };
1006
+ y.setDevicePixelRatio(window.devicePixelRatio), E();
1007
+ let D = y.subscribe((e) => {
1008
+ (e.scope === "doc" || e.scope === "ui" && e.branch === "armedCreate") && (m.value = y.store.ui.armedCreate);
1009
+ });
1010
+ T.push(D);
1011
+ let O = new ResizeObserver(E);
1012
+ O.observe(e), T.push(() => O.disconnect());
1013
+ let k = $(() => {
1014
+ y.setDevicePixelRatio(window.devicePixelRatio), b();
1015
+ });
1016
+ T.push(k);
1017
+ let A = (t) => {
1018
+ let n = e.getBoundingClientRect();
1019
+ return {
1020
+ x: t.clientX - n.left,
1021
+ y: t.clientY - n.top
1022
+ };
1023
+ }, j = (e) => e.deltaMode === 1 ? 16 : e.deltaMode === 2 ? 100 : 1, M = (e) => {
1024
+ e.preventDefault();
1025
+ let t = j(e), n = A(e), r = me(e);
1026
+ r === "zoom" ? y.zoomByWheel(n.x, n.y, e.deltaY * t) : r === "pan-x" ? y.panBy(-(e.deltaY || e.deltaX) * t, 0) : y.panBy(-e.deltaX * t, -e.deltaY * t);
1027
+ };
1028
+ e.addEventListener("wheel", M, { passive: !1 }), T.push(() => e.removeEventListener("wheel", M));
1029
+ let N = null, P = {
1030
+ x: 0,
1031
+ y: 0
1032
+ }, F = (e) => {
1033
+ let t = A(e);
1034
+ return y.toScenePoint(t.x, t.y);
1035
+ }, I = (t) => {
1036
+ if (c.value?.close(), N !== null) return;
1037
+ if (t.button === 1 || t.button === 0 && u.value) {
1038
+ t.preventDefault(), N = {
1039
+ id: t.pointerId,
1040
+ mode: "pan"
1041
+ }, P = {
1042
+ x: t.clientX,
1043
+ y: t.clientY
1044
+ }, d.value = !0, e.setPointerCapture(t.pointerId);
1045
+ return;
1046
+ }
1047
+ if (t.button !== 0) return;
1048
+ if (s.value?.isEditing()) {
1049
+ if (s.value.ownsEventTarget(t.target)) return;
1050
+ s.value.commitEditing();
1051
+ }
1052
+ t.preventDefault();
1053
+ let n = F(t);
1054
+ if (y.beginLayerCreate(n.x, n.y)) {
1055
+ N = {
1056
+ id: t.pointerId,
1057
+ mode: "create"
1058
+ }, _.value = !0, f.value = null, e.setPointerCapture(t.pointerId);
1059
+ return;
1060
+ }
1061
+ let r = y.resizeHandleAt(n.x, n.y);
1062
+ if (r !== null && y.beginResize(y.store.ui.selection, r, n.x, n.y)) {
1063
+ N = {
1064
+ id: t.pointerId,
1065
+ mode: "resize"
1066
+ }, p.value = r, f.value = null, e.setPointerCapture(t.pointerId);
1067
+ return;
1068
+ }
1069
+ let i = F(t), a = y.selectAt(i.x, i.y);
1070
+ if (a && y.beginDrag(a, i.x, i.y, { copy: t.altKey && y.canCopyLayerAt(a) })) {
1071
+ N = {
1072
+ id: t.pointerId,
1073
+ mode: "drag"
1074
+ }, e.setPointerCapture(t.pointerId);
1075
+ return;
1076
+ }
1077
+ a === null && (N = {
1078
+ id: t.pointerId,
1079
+ mode: "pan"
1080
+ }, P = {
1081
+ x: t.clientX,
1082
+ y: t.clientY
1083
+ }, d.value = !0, e.setPointerCapture(t.pointerId));
1084
+ }, L = (e) => {
1085
+ if (N !== null) {
1086
+ if (e.pointerId !== N.id) return;
1087
+ if (N.mode === "pan") y.panBy(e.clientX - P.x, e.clientY - P.y), P = {
1088
+ x: e.clientX,
1089
+ y: e.clientY
1090
+ };
1091
+ else if (N.mode === "resize") {
1092
+ let t = F(e);
1093
+ y.resizeTo(t.x, t.y);
1094
+ } else if (N.mode === "create") {
1095
+ let t = F(e);
1096
+ y.createTo(t.x, t.y);
1097
+ } else {
1098
+ let t = F(e);
1099
+ y.dragTo(t.x, t.y);
1100
+ }
1101
+ return;
1102
+ }
1103
+ let t = F(e), n = y.resizeHandleAt(t.x, t.y);
1104
+ if (f.value = n, n !== null) {
1105
+ y.setHovered(null);
1106
+ return;
1107
+ }
1108
+ y.hoverAt(t.x, t.y);
1109
+ }, R = (t) => {
1110
+ if (N !== null && t.pointerId === N.id) {
1111
+ if (N.mode === "drag") y.endDrag();
1112
+ else if (N.mode === "resize") y.endResize(), p.value = null;
1113
+ else if (N.mode === "create") {
1114
+ _.value = !1;
1115
+ let e = y.endCreate();
1116
+ e !== null && s.value?.beginTextEdit(e);
1117
+ } else d.value = !1;
1118
+ N = null, e.hasPointerCapture(t.pointerId) && e.releasePointerCapture(t.pointerId);
1119
+ }
1120
+ }, z = (e) => {
1121
+ e.button === 1 && e.preventDefault();
1122
+ }, B = (e) => {
1123
+ let t = A(e), n = y.toScenePoint(t.x, t.y);
1124
+ s.value?.beginAt(n.x, n.y);
1125
+ }, V = (e) => {
1126
+ if (s.value?.isEditing()) {
1127
+ if (s.value.ownsEventTarget(e.target)) return;
1128
+ s.value.commitEditing();
1129
+ }
1130
+ e.preventDefault();
1131
+ let t = A(e), n = y.toScenePoint(t.x, t.y);
1132
+ if (y.selectAt(n.x, n.y) === null) {
1133
+ c.value?.close();
1134
+ return;
1135
+ }
1136
+ c.value?.openAt(t.x, t.y);
1137
+ }, H = () => {
1138
+ N === null && (y.setHovered(null), f.value = null);
1139
+ };
1140
+ e.addEventListener("pointerdown", I), e.addEventListener("pointermove", L), e.addEventListener("pointerup", R), e.addEventListener("pointercancel", R), e.addEventListener("pointerleave", H), e.addEventListener("mousedown", z), e.addEventListener("dblclick", B), T.push(() => {
1141
+ e.removeEventListener("pointerdown", I), e.removeEventListener("pointermove", L), e.removeEventListener("pointerup", R), e.removeEventListener("pointercancel", R), e.removeEventListener("pointerleave", H), e.removeEventListener("mousedown", z), e.removeEventListener("dblclick", B);
1142
+ });
1143
+ let U = h, W = (e) => {
1144
+ e.code !== "Space" || e.repeat || U(e.target) || (e.preventDefault(), u.value = !0);
1145
+ }, G = (e) => {
1146
+ e.code === "Space" && (u.value = !1);
1147
+ }, K = (e) => {
1148
+ if (!(e.key !== "Escape" || g(e.target))) {
1149
+ if (y.store.ui.armedCreate !== null || y.store.ui.create !== null) {
1150
+ y.cancelCreate();
1151
+ return;
1152
+ }
1153
+ c.value?.close(), l.value?.close(), y.escapeSelection();
1154
+ }
1155
+ };
1156
+ window.addEventListener("keydown", W), window.addEventListener("keyup", G), window.addEventListener("keydown", K), T.push(() => {
1157
+ window.removeEventListener("keydown", W), window.removeEventListener("keyup", G), window.removeEventListener("keydown", K);
1158
+ }), e.addEventListener("contextmenu", V), T.push(() => e.removeEventListener("contextmenu", V));
1159
+ let ee = (e) => {
1160
+ let t = e.dataTransfer?.items;
1161
+ if (!t) return !1;
1162
+ for (let e = 0; e < t.length; e += 1) {
1163
+ let n = t[e];
1164
+ if (n !== void 0 && n.kind === "file" && n.type.startsWith("image/")) return !0;
1165
+ }
1166
+ return !1;
1167
+ }, q = (e) => {
1168
+ ee(e) && (e.preventDefault(), e.dataTransfer && (e.dataTransfer.dropEffect = "copy"), x.value = !0);
1169
+ }, J = (t) => {
1170
+ t.relatedTarget !== null && e.contains(t.relatedTarget) || (x.value = !1);
1171
+ }, Y = (e) => {
1172
+ e.preventDefault(), x.value = !1;
1173
+ let t = [], n = e.dataTransfer?.files;
1174
+ for (let e = 0; n !== void 0 && e < n.length; e += 1) {
1175
+ let r = n[e];
1176
+ r !== void 0 && r.type.startsWith("image/") && t.push(r);
1177
+ }
1178
+ if (t.length !== 0) {
1179
+ if (!y.canUpload) {
1180
+ S.show("上传不可用:未接入上传实现,图片未添加");
1181
+ return;
1182
+ }
1183
+ s.value?.isEditing() && s.value.commitEditing(), X(t, A(e));
1184
+ }
1185
+ }, X = async (e, t) => {
1186
+ let n = y.toScenePoint(t.x, t.y);
1187
+ for (let t = 0; t < e.length; t += 1) {
1188
+ let r = e[t];
1189
+ if (r) try {
1190
+ let e = await w(r);
1191
+ await y.uploadImageAsLayer(await C(r), {
1192
+ at: {
1193
+ x: n.x + t * Ye,
1194
+ y: n.y + t * Ye
1195
+ },
1196
+ size: e
1197
+ });
1198
+ } catch (e) {
1199
+ S.show(`上传失败:${e instanceof Error ? e.message : String(e)}`);
1200
+ return;
1201
+ }
1202
+ }
1203
+ };
1204
+ e.addEventListener("dragover", q), e.addEventListener("dragleave", J), e.addEventListener("drop", Y), T.push(() => {
1205
+ e.removeEventListener("dragover", q), e.removeEventListener("dragleave", J), e.removeEventListener("drop", Y);
1206
+ });
1207
+ let Z = () => y.invalidate("both"), Q = (e) => e.preventDefault();
1208
+ t.addEventListener("contextlost", Q), t.addEventListener("contextrestored", Z), v.addEventListener("contextlost", Q), v.addEventListener("contextrestored", Z), T.push(() => {
1209
+ t.removeEventListener("contextlost", Q), t.removeEventListener("contextrestored", Z), v.removeEventListener("contextlost", Q), v.removeEventListener("contextrestored", Z);
1210
+ }), r("ready", {
1211
+ contentCanvas: t,
1212
+ overlayCanvas: v
1213
+ });
1214
+ }), R(() => {
1215
+ T.forEach((e) => e()), T.length = 0, n.editor.detachSurfaces();
1216
+ }), (t, n) => (V(), A("div", {
1217
+ ref_key: "hostRef",
1218
+ ref: i,
1219
+ class: I(["cn-surface", y.value]),
1220
+ style: L(b.value)
1221
+ }, [
1222
+ j("canvas", {
1223
+ ref_key: "contentRef",
1224
+ ref: a,
1225
+ class: "cn-surface__canvas"
1226
+ }, null, 512),
1227
+ j("canvas", {
1228
+ ref_key: "overlayRef",
1229
+ ref: o,
1230
+ class: "cn-surface__canvas cn-surface__canvas--overlay"
1231
+ }, null, 512),
1232
+ M(qe, {
1233
+ ref_key: "textEditRef",
1234
+ ref: s,
1235
+ editor: e.editor
1236
+ }, null, 8, ["editor"]),
1237
+ M(Oe, {
1238
+ ref_key: "contextMenuRef",
1239
+ ref: c,
1240
+ editor: e.editor
1241
+ }, null, 8, ["editor"]),
1242
+ M(Re, {
1243
+ ref_key: "findBarRef",
1244
+ ref: l,
1245
+ editor: e.editor
1246
+ }, null, 8, ["editor"]),
1247
+ x.value ? (V(), A("div", Je, [...n[0] ||= [j("span", { class: "cn-surface__drop-hint-text" }, "松开以上传图片", -1)]])) : k("", !0)
1248
+ ], 6));
1249
+ }
1250
+ }), [["__scopeId", "data-v-f2b89db2"]]);
1251
+ //#endregion
1252
+ //#region src/canvas/guideSnap.ts
1253
+ function Ze(e, t, n, r) {
1254
+ let i = e.store.doc;
1255
+ if (!i) return n;
1256
+ let a = r === void 0 ? e.listGuides() : e.listGuides().filter((e) => e.id !== r), o = fe({
1257
+ x: n,
1258
+ y: n,
1259
+ width: 0,
1260
+ height: 0
1261
+ }, le(i.width, i.height, ce(i, -1, e.textPolicies), a), se(e.store.ui.viewport.zoom));
1262
+ return t === "vertical" ? n + o.dx : n + o.dy;
1263
+ }
1264
+ //#endregion
1265
+ //#region src/canvas/GuidesOverlay.vue?vue&type=script&setup=true&lang.ts
1266
+ var Qe = [
1267
+ "data-snap-orientation",
1268
+ "data-snap-position",
1269
+ "data-snap-source"
1270
+ ], $e = [
1271
+ "data-guide-line",
1272
+ "data-guide-orientation",
1273
+ "data-guide-position",
1274
+ "data-guide-dragging",
1275
+ "onPointerdown"
1276
+ ], et = ["data-guide-orientation", "data-guide-position"], tt = /*#__PURE__*/ y(/* @__PURE__ */ N({
1277
+ __name: "GuidesOverlay",
1278
+ props: { editor: {} },
1279
+ setup(e, { expose: t }) {
1280
+ let n = e, r = T(n.editor), i = W(n.editor.store.doc), a = W(n.editor.listGuides()), o = W(n.editor.listSnapAxes()), s = n.editor.subscribe((e) => {
1281
+ if (e.scope === "doc") {
1282
+ i.value = n.editor.store.doc, a.value = n.editor.listGuides(), o.value = n.editor.listSnapAxes();
1283
+ return;
1284
+ }
1285
+ e.branch === "guides" ? a.value = n.editor.listGuides() : e.branch === "snapAxes" && (o.value = n.editor.listSnapAxes());
1286
+ });
1287
+ B(s, !0);
1288
+ function c(e, t) {
1289
+ let n = i.value, a = r.value;
1290
+ return n ? e === "vertical" ? {
1291
+ left: `${(t - a.x) * a.zoom}px`,
1292
+ top: "0px",
1293
+ height: "100%"
1294
+ } : {
1295
+ top: `${(t - a.y) * a.zoom}px`,
1296
+ left: "0px",
1297
+ width: "100%"
1298
+ } : { display: "none" };
1299
+ }
1300
+ function l(e) {
1301
+ return String(Math.round(e * 100) / 100);
1302
+ }
1303
+ let u = H(null);
1304
+ function d(e) {
1305
+ return {
1306
+ orientation: e.orientation,
1307
+ position: Ze(n.editor, e.orientation, e.position)
1308
+ };
1309
+ }
1310
+ function f(e) {
1311
+ u.value = d(e);
1312
+ }
1313
+ function p(e) {
1314
+ u.value !== null && u.value.orientation === e.orientation && (u.value = d(e));
1315
+ }
1316
+ function m(e) {
1317
+ if (u.value === null) return;
1318
+ u.value = null;
1319
+ let { orientation: t, position: r } = d(e);
1320
+ n.editor.listGuides().some((e) => e.orientation === t && Math.abs(e.position - r) < 1e-6) || n.editor.addGuide({
1321
+ orientation: t,
1322
+ position: r
1323
+ });
1324
+ }
1325
+ function h() {
1326
+ u.value = null;
1327
+ }
1328
+ t({
1329
+ beginGuideDrag: f,
1330
+ moveGuideDrag: p,
1331
+ endGuideDrag: m,
1332
+ cancelGuideDrag: h
1333
+ });
1334
+ let g = H(null), _ = D(() => a.value.map((e) => {
1335
+ let t = g.value;
1336
+ return t !== null && t.id === e.id ? {
1337
+ id: e.id,
1338
+ orientation: e.orientation,
1339
+ position: t.current,
1340
+ dragging: !0,
1341
+ overRuler: t.overRuler
1342
+ } : {
1343
+ id: e.id,
1344
+ orientation: e.orientation,
1345
+ position: e.position,
1346
+ dragging: !1,
1347
+ overRuler: !1
1348
+ };
1349
+ })), v = H(null);
1350
+ function y(e, t) {
1351
+ let n = v.value?.getBoundingClientRect(), i = r.value, a = n?.left ?? 0, o = n?.top ?? 0;
1352
+ return t === "vertical" ? i.x + (e.clientX - a) / i.zoom : i.y + (e.clientY - o) / i.zoom;
1353
+ }
1354
+ function b(e, t) {
1355
+ let n = document.elementFromPoint(e, t);
1356
+ return n !== null && n.closest("[data-ruler-top], [data-ruler-left]") !== null;
1357
+ }
1358
+ function x(e) {
1359
+ try {
1360
+ e.currentTarget.setPointerCapture(e.pointerId);
1361
+ } catch {}
1362
+ }
1363
+ function S(e) {
1364
+ try {
1365
+ e.currentTarget.releasePointerCapture(e.pointerId);
1366
+ } catch {}
1367
+ }
1368
+ function C(e, t) {
1369
+ e.button === 0 && g.value === null && (e.preventDefault(), g.value = {
1370
+ id: t.id,
1371
+ orientation: t.orientation,
1372
+ pointerId: e.pointerId,
1373
+ current: t.position,
1374
+ overRuler: !1
1375
+ }, x(e));
1376
+ }
1377
+ function w(e) {
1378
+ let t = g.value;
1379
+ t !== null && e.pointerId === t.pointerId && (g.value = {
1380
+ ...t,
1381
+ current: Ze(n.editor, t.orientation, y(e, t.orientation), t.id),
1382
+ overRuler: b(e.clientX, e.clientY)
1383
+ });
1384
+ }
1385
+ function O(e) {
1386
+ let t = g.value;
1387
+ if (t !== null && e.pointerId === t.pointerId) {
1388
+ if (g.value = null, S(e), b(e.clientX, e.clientY)) {
1389
+ n.editor.removeGuide(t.id);
1390
+ return;
1391
+ }
1392
+ n.editor.listGuides().some((e) => e.id !== t.id && e.orientation === t.orientation && Math.abs(e.position - t.current) < 1e-6) ? n.editor.removeGuide(t.id) : n.editor.updateGuide(t.id, t.current);
1393
+ }
1394
+ }
1395
+ function j(e) {
1396
+ let t = g.value;
1397
+ t !== null && e.pointerId === t.pointerId && (g.value = null, S(e));
1398
+ }
1399
+ return (e, t) => (V(), A("div", {
1400
+ ref_key: "rootRef",
1401
+ ref: v,
1402
+ class: "cn-guides",
1403
+ "data-guide-overlay": ""
1404
+ }, [
1405
+ (V(!0), A(E, null, U(o.value, (e, t) => (V(), A("div", {
1406
+ key: `${e.orientation}-${e.position}-${t}`,
1407
+ class: I(["cn-guides__snap", `cn-guides__snap--${e.orientation}`]),
1408
+ "data-snap-line": "",
1409
+ "data-snap-orientation": e.orientation,
1410
+ "data-snap-position": l(e.position),
1411
+ "data-snap-source": e.source,
1412
+ style: L(c(e.orientation, e.position))
1413
+ }, null, 14, Qe))), 128)),
1414
+ (V(!0), A(E, null, U(_.value, (e) => (V(), A("div", {
1415
+ key: e.id,
1416
+ class: I(["cn-guides__guide", [`cn-guides__guide--${e.orientation}`, {
1417
+ "cn-guides__guide--grabbed": e.dragging,
1418
+ "cn-guides__guide--will-delete": e.overRuler
1419
+ }]]),
1420
+ "data-guide-line": e.id,
1421
+ "data-guide-orientation": e.orientation,
1422
+ "data-guide-position": l(e.position),
1423
+ "data-guide-dragging": e.dragging ? "" : void 0,
1424
+ style: L(c(e.orientation, e.position)),
1425
+ onPointerdown: (t) => C(t, e),
1426
+ onPointermove: w,
1427
+ onPointerup: O,
1428
+ onPointercancel: j
1429
+ }, null, 46, $e))), 128)),
1430
+ u.value ? (V(), A("div", {
1431
+ key: 0,
1432
+ class: I(["cn-guides__guide cn-guides__guide--preview", `cn-guides__guide--${u.value.orientation}`]),
1433
+ "data-guide-preview": "",
1434
+ "data-guide-orientation": u.value.orientation,
1435
+ "data-guide-position": l(u.value.position),
1436
+ style: L(c(u.value.orientation, u.value.position))
1437
+ }, null, 14, et)) : k("", !0)
1438
+ ], 512));
1439
+ }
1440
+ }), [["__scopeId", "data-v-61872121"]]), nt = {
1441
+ class: "cn-ruler",
1442
+ "data-ruler": ""
1443
+ }, rt = {
1444
+ key: 0,
1445
+ class: "cn-ruler__label"
1446
+ }, it = {
1447
+ key: 0,
1448
+ class: "cn-ruler__label"
1449
+ }, at = 10, ot = 5, st = /*#__PURE__*/ y(/* @__PURE__ */ N({
1450
+ __name: "Ruler",
1451
+ props: { editor: {} },
1452
+ emits: [
1453
+ "guide-drag-start",
1454
+ "guide-drag-move",
1455
+ "guide-drag-end",
1456
+ "guide-drag-cancel"
1457
+ ],
1458
+ setup(e, { emit: t }) {
1459
+ let n = e, r = t, i = T(n.editor), a = W(n.editor.store.ui.rulersVisible), o = n.editor.subscribe((e) => {
1460
+ e.scope === "ui" && e.branch === "rulersVisible" && (a.value = n.editor.store.ui.rulersVisible);
1461
+ });
1462
+ B(o, !0);
1463
+ let s = [
1464
+ 1,
1465
+ 2,
1466
+ 5,
1467
+ 10,
1468
+ 20,
1469
+ 50,
1470
+ 100,
1471
+ 200,
1472
+ 500,
1473
+ 1e3,
1474
+ 2e3,
1475
+ 5e3,
1476
+ 1e4
1477
+ ];
1478
+ function c(e, t, n) {
1479
+ if (!(t > 0) || !(n > 0) || !Number.isFinite(e)) return [];
1480
+ let r = s[s.length - 1];
1481
+ for (let e of s) if (e * n >= at) {
1482
+ r = e;
1483
+ break;
1484
+ }
1485
+ let i = r * ot, a = Math.floor(e / r) * r, o = [];
1486
+ for (let s = 0;; s++) {
1487
+ let c = a + s * r, l = (c - e) * n;
1488
+ if (l > t) break;
1489
+ if (l >= 0) {
1490
+ let e = c / i, t = Math.abs(e - Math.round(e)) < 1e-6;
1491
+ o.push({
1492
+ scene: c,
1493
+ position: l,
1494
+ label: t ? String(Math.round(c)) : null
1495
+ });
1496
+ }
1497
+ }
1498
+ return o;
1499
+ }
1500
+ let l = H(null), u = H(null), d = H(0), f = H(0), p = () => {
1501
+ d.value = l.value?.clientWidth ?? 0, f.value = u.value?.clientHeight ?? 0;
1502
+ }, m = null;
1503
+ z(() => {
1504
+ p(), m = new ResizeObserver(() => p()), l.value && m.observe(l.value), u.value && m.observe(u.value);
1505
+ }), R(() => m?.disconnect());
1506
+ let h = D(() => c(i.value.x, d.value, i.value.zoom)), g = D(() => c(i.value.y, f.value, i.value.zoom)), _ = H(null);
1507
+ function v(e, t, n) {
1508
+ let r = e.getBoundingClientRect(), a = i.value;
1509
+ return {
1510
+ orientation: t,
1511
+ position: t === "vertical" ? a.x + (n.clientX - r.left) / a.zoom : a.y + (n.clientY - r.top) / a.zoom
1512
+ };
1513
+ }
1514
+ function y(e, t) {
1515
+ let n = e.currentTarget;
1516
+ if (n instanceof HTMLElement && e.button === 0 && _.value === null) {
1517
+ e.preventDefault(), _.value = {
1518
+ pointerId: e.pointerId,
1519
+ orientation: t
1520
+ };
1521
+ try {
1522
+ n.setPointerCapture(e.pointerId);
1523
+ } catch {}
1524
+ r("guide-drag-start", v(n, t, e));
1525
+ }
1526
+ }
1527
+ function b(e) {
1528
+ let t = e.currentTarget, n = _.value;
1529
+ t instanceof HTMLElement && n !== null && e.pointerId === n.pointerId && r("guide-drag-move", v(t, n.orientation, e));
1530
+ }
1531
+ function x(e, t) {
1532
+ let n = e.currentTarget, i = _.value;
1533
+ if (!(n instanceof HTMLElement) || i === null || e.pointerId !== i.pointerId) return;
1534
+ _.value = null;
1535
+ try {
1536
+ n.releasePointerCapture(e.pointerId);
1537
+ } catch {}
1538
+ let a = v(n, i.orientation, e);
1539
+ r(t === "guide-drag-end" ? "guide-drag-end" : "guide-drag-cancel", a);
1540
+ }
1541
+ return (e, t) => Y((V(), A("div", nt, [
1542
+ j("div", {
1543
+ ref_key: "topRef",
1544
+ ref: l,
1545
+ class: "cn-ruler__bar cn-ruler__bar--top",
1546
+ "data-ruler-top": "",
1547
+ role: "img",
1548
+ "aria-label": "水平标尺",
1549
+ title: "水平标尺(拖出垂直参考线)",
1550
+ onPointerdown: t[0] ||= (e) => y(e, "vertical"),
1551
+ onPointermove: t[1] ||= (e) => b(e),
1552
+ onPointerup: t[2] ||= (e) => x(e, "guide-drag-end"),
1553
+ onPointercancel: t[3] ||= (e) => x(e, "guide-drag-cancel")
1554
+ }, [(V(!0), A(E, null, U(h.value, (e) => (V(), A("span", {
1555
+ key: e.scene,
1556
+ class: I(["cn-ruler__tick", { "cn-ruler__tick--major": e.label !== null }]),
1557
+ style: L({ left: `${e.position}px` })
1558
+ }, [e.label === null ? k("", !0) : (V(), A("span", rt, G(e.label), 1))], 6))), 128))], 544),
1559
+ j("div", {
1560
+ ref_key: "leftRef",
1561
+ ref: u,
1562
+ class: "cn-ruler__bar cn-ruler__bar--left",
1563
+ "data-ruler-left": "",
1564
+ role: "img",
1565
+ "aria-label": "垂直标尺",
1566
+ title: "垂直标尺(拖出水平参考线)",
1567
+ onPointerdown: t[4] ||= (e) => y(e, "horizontal"),
1568
+ onPointermove: t[5] ||= (e) => b(e),
1569
+ onPointerup: t[6] ||= (e) => x(e, "guide-drag-end"),
1570
+ onPointercancel: t[7] ||= (e) => x(e, "guide-drag-cancel")
1571
+ }, [(V(!0), A(E, null, U(g.value, (e) => (V(), A("span", {
1572
+ key: e.scene,
1573
+ class: I(["cn-ruler__tick", { "cn-ruler__tick--major": e.label !== null }]),
1574
+ style: L({ top: `${e.position}px` })
1575
+ }, [e.label === null ? k("", !0) : (V(), A("span", it, G(e.label), 1))], 6))), 128))], 544),
1576
+ t[8] ||= j("div", {
1577
+ class: "cn-ruler__corner",
1578
+ "data-ruler-corner": "",
1579
+ "aria-hidden": "true"
1580
+ }, null, -1)
1581
+ ], 512)), [[q, a.value]]);
1582
+ }
1583
+ }), [["__scopeId", "data-v-5bd7248c"]]), ct = "#2563eb", lt = "rgba(37, 99, 235, 0.08)", ut = [4, 3], dt = 1, ft = "rgba(11, 18, 32, 0.9)", pt = "#ffffff", mt = 11, ht = 6, gt = 3, _t = 3, vt = 6;
1584
+ function yt(e, t, n) {
1585
+ let r = t.store.ui.create;
1586
+ if (!r) return;
1587
+ let { x: i, y: a, width: o, height: s } = r.rect;
1588
+ if (o === 0 && s === 0) return;
1589
+ let c = n.viewport.zoom;
1590
+ e.fillStyle = lt, e.fillRect(i, a, o, s), e.strokeStyle = ct, e.lineWidth = dt / c, e.setLineDash(ut.map((e) => e / c)), e.strokeRect(i, a, o, s), e.setLineDash([]);
1591
+ let l = mt / c, u = ht / c, d = gt / c;
1592
+ e.font = `${l}px system-ui, sans-serif`;
1593
+ let f = `${Math.round(o)} × ${Math.round(s)}`, p = e.measureText(f).width + u * 2, m = l + d * 2, h = i + o + vt / c, g = a + s + vt / c;
1594
+ e.fillStyle = ft, e.beginPath(), e.roundRect(h, g, p, m, _t / c), e.fill(), e.fillStyle = pt, e.textBaseline = "middle", e.fillText(f, h + u, g + m / 2);
1595
+ }
1596
+ //#endregion
1597
+ //#region src/canvas/findHighlight.ts
1598
+ var bt = {
1599
+ matchColor: "#f59e0b",
1600
+ currentColor: "#38bdf8",
1601
+ currentFill: "rgba(56, 189, 248, 0.12)",
1602
+ lineWidth: 2
1603
+ };
1604
+ function xt(e, t, n, r) {
1605
+ if (!n.doc || !t.store.ui.find.open) return;
1606
+ let i = {
1607
+ ...bt,
1608
+ ...r
1609
+ }, a = t.listFindMatches();
1610
+ if (a.length === 0) return;
1611
+ let o = t.findCursor;
1612
+ for (let r = 0; r < a.length; r += 1) {
1613
+ let s = t.layerBoxAt(a[r].path);
1614
+ if (!s) continue;
1615
+ let c = r === o;
1616
+ c && i.currentFill && (e.fillStyle = i.currentFill, e.fillRect(s.x, s.y, s.width, s.height)), e.strokeStyle = c ? i.currentColor : i.matchColor, e.lineWidth = (c ? i.lineWidth * 1.5 : i.lineWidth) / n.viewport.zoom, e.strokeRect(s.x, s.y, s.width, s.height);
1617
+ }
1618
+ }
1619
+ //#endregion
1620
+ //#region src/canvas/gizmo.ts
1621
+ var St = {
1622
+ selectionColor: "#2563eb",
1623
+ hoverColor: "rgba(37, 99, 235, 0.55)",
1624
+ selectionWidth: 2,
1625
+ handleSize: 8,
1626
+ handleFill: "#ffffff"
1627
+ };
1628
+ function Ct(e, t) {
1629
+ return d(e, t)?.visible === !1;
1630
+ }
1631
+ function wt(e, t, n, r) {
1632
+ let i = {
1633
+ ...St,
1634
+ ...r
1635
+ }, { selection: a, hovered: o } = t.store.ui, s = n.doc;
1636
+ if (s) {
1637
+ if (o && !l(o, a) && !Ct(s, o) && !t.isLocked(o)) {
1638
+ let r = t.layerBoxAt(o);
1639
+ r && (e.strokeStyle = i.hoverColor, e.lineWidth = i.selectionWidth / 2 / n.viewport.zoom, e.strokeRect(r.x, r.y, r.width, r.height));
1640
+ }
1641
+ if (a && !Ct(s, a)) {
1642
+ let r = t.layerBoxAt(a);
1643
+ r && (e.strokeStyle = i.selectionColor, e.lineWidth = i.selectionWidth / n.viewport.zoom, e.strokeRect(r.x, r.y, r.width, r.height), Tt(e, t, a, r, n.viewport.zoom, i));
1644
+ }
1645
+ }
1646
+ }
1647
+ function Tt(e, t, n, r, i, a) {
1648
+ let o = t.resizeHandlesAt(n);
1649
+ if (o.length === 0) return;
1650
+ let s = a.handleSize / i, c = s / 2;
1651
+ e.fillStyle = a.handleFill, e.strokeStyle = a.selectionColor, e.lineWidth = a.selectionWidth / i;
1652
+ for (let t of o) {
1653
+ let n = pe(r, t);
1654
+ e.fillRect(n.x - c, n.y - c, s, s), e.strokeRect(n.x - c, n.y - c, s, s);
1655
+ }
1656
+ }
1657
+ function Et(e, t, n) {
1658
+ return (r) => {
1659
+ if (!t) return;
1660
+ t.setTransform(1, 0, 0, 1, 0, 0), t.clearRect(0, 0, t.canvas.width, t.canvas.height);
1661
+ let i = r.dpr * r.viewport.zoom;
1662
+ t.setTransform(i, 0, 0, i, -r.viewport.x * i, -r.viewport.y * i), wt(t, e, r, n);
1663
+ };
1664
+ }
1665
+ //#endregion
1666
+ //#region src/canvas/scheduler.ts
1667
+ function Dt() {
1668
+ return (e) => {
1669
+ let t = window.requestAnimationFrame(() => e());
1670
+ return () => window.cancelAnimationFrame(t);
1671
+ };
1672
+ }
1673
+ //#endregion
1674
+ export { Se as _, yt as a, Xe as c, He as d, $ as f, Oe as g, ke as h, xt as i, qe as l, Re as m, Et as n, st as o, Ve as p, wt as r, tt as s, Dt as t, Ge as u };