@weasel-js/core 1.4.0-pre.1 → 1.4.0

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.
@@ -1,4 +1,4 @@
1
- import { ActionDisabledReason, useOptionalDepRegistry, DepRegistryProvider, useActionsRegistry, ActionsProvider, useDepRegistry, reportRouteConflicts, buildDepsFromRequires, useDepSource, actionBindings } from './chunk-H6E6KPTU.js';
1
+ import { ActionDisabledReason, useOptionalDepRegistry, DepRegistryProvider, useActionsRegistry, ActionsProvider, useDepRegistry, reportRouteConflicts, buildDepsFromRequires, useDepSource, actionBindings } from './chunk-UTIFY2UU.js';
2
2
  import { scratchKey, createTransformOp, snap, getScratch, createReparentOp, setScratch } from './chunk-Y5KS66G7.js';
3
3
  import { fixedCornerOf, DEFAULT_RESIZE_BEHAVIORS, CORNER_ANCHORS, cornerPoint } from './chunk-BLJNRMKB.js';
4
4
  import { AUTO_POSE_DESCRIPTOR, resolveUnit, polylineFromPoints, starPath, regularPolygonPath, linePath, ellipsePath, rectPath, polygonFromPoints, PATH_M, PATH_L, PATH_Z, RECT_POSE_DESCRIPTOR, pathPoseDescriptor, withinPxRadius, boundsOfPath, PATH_Q, PATH_C, DEFAULT_FLATTEN_TOLERANCE, flattenQuadratic, flattenCubic, PathBuilder, pointInPath, strokeHitTest, transformPath, translatePath, pxExtent, remapRotatedLeaf, withinPxBox, flattenCubicWithArcLen, flattenQuadraticWithArcLen, PATH_CMD_LENGTHS, pointToGridCell } from './chunk-SBFC6J3C.js';
@@ -6,7 +6,7 @@ import { dispatchApplyBatch, dlog, dwarn, usePointerContext, PointerContextProvi
6
6
  import { createSetSelectionOp } from './chunk-ZB7UYJVG.js';
7
7
  import { registerOpFactory, createDeleteOp, createInsertOp, rebuildOp } from './chunk-2KKYDDDD.js';
8
8
  import { getTexture, chunks, dots, crosshatch, hatch } from './chunk-BJN5ZRIJ.js';
9
- import { createContext, createElement, forwardRef, useMemo, useRef, useCallback, useState, useImperativeHandle, useSyncExternalStore, useEffect, useLayoutEffect, useContext, useId, useReducer } from 'react';
9
+ import { createContext, createElement, forwardRef, useMemo, useRef, useCallback, useState, useEffect, useImperativeHandle, useSyncExternalStore, useLayoutEffect, useContext, useId, useReducer } from 'react';
10
10
  import { subscribeGlyphReady, DEFAULT_BAKE_BUDGET, TEXT_VERT_SRC, TEXT_FRAG_SRC, TEXT_SDF_UNIFORMS, TEXT_SDF_ATTRIBUTES, TEXT_FRAG_R8_SRC, markAllFontsNotUploaded, resetBakeBudget, syncDynamicPageTexture, ensureFontTexture, dynamicPageTextureId, textureCacheKey } from '@weasel-js/font';
11
11
  export { canQueryLocalFonts, canQueryLocalFonts as canQueryLocalFonts2, enableLocalFontOutlines, enableLocalFontOutlines as enableLocalFontOutlines2, hasFontOutlines, hasFontOutlines as hasFontOutlines2, isCanvasFont, isCanvasFont as isCanvasFont2, listFontOutlines, listFontOutlines as listFontOutlines2, outlineStatus, outlineStatus as outlineStatus2, registerCanvasFont, registerCanvasFont as registerCanvasFont2, registerFont, registerFont as registerFont2, registerFontOutlines, registerFontOutlines as registerFontOutlines2, subscribeGlyphReady, subscribeGlyphReady as subscribeGlyphReady2, unregisterCanvasFont, unregisterCanvasFont as unregisterCanvasFont2, unregisterFontOutlines, unregisterFontOutlines as unregisterFontOutlines2 } from '@weasel-js/font';
12
12
  import { resolveTextStyle, resolveAlign, resolveRuns, cachedLayoutRuns, verticalAlignOffset, runsToPlainText, toRuns, fontString, textLineBoxes } from '@weasel-js/text';
@@ -19,12 +19,13 @@ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
19
19
  import polygonClipping from 'polygon-clipping';
20
20
  import { matchSpec, RESERVED_ID_PREFIXES, RESERVED_ID_NAMES, parseTargetSpec, mimeMatchesGlob } from '@weasel-js/gestures';
21
21
  import { NORMAL, IMPLICIT_TAGS } from '@weasel-js/modes';
22
- import { cursorFor } from '@weasel-js/cursor';
22
+ import { GLYPHS, cursorWorldSize, cursorPaintOps, chromeLineWidthScale, cursorPaintMatrix, resolveCursorTier, cursorFor, resolveCursor } from '@weasel-js/cursor';
23
+ export { bakeCursor, cursorFor, resolveCursor, resolveCursorTier } from '@weasel-js/cursor';
23
24
  import { createHistory } from '@weasel-js/history';
24
25
  export * from '@weasel-js/history';
25
26
 
26
27
  // src/version.ts
27
- var VERSION = "1.4.0-pre.1" ;
28
+ var VERSION = "1.4.0" ;
28
29
 
29
30
  // src/features/grid/roundToCell.ts
30
31
  function roundToCell(value, cellSize) {
@@ -6732,8 +6733,8 @@ function runLayoutPass(scratch, moveCtx) {
6732
6733
  for (const [cid, pose] of srcLayout.childPoses(srcContainer, srcChildren)) {
6733
6734
  const cur = composeWorldPose(poseAdapter, cid, pc.compose);
6734
6735
  const next = pose;
6735
- const same = cur.x === next.x && cur.y === next.y && cur.width === next.width && cur.height === next.height;
6736
- if (same) continue;
6736
+ const same2 = cur.x === next.x && cur.y === next.y && cur.width === next.width && cur.height === next.height;
6737
+ if (same2) continue;
6737
6738
  sourceReflow.set(cid, pose);
6738
6739
  const parent = scene.get(asNodeId(cid))?.parent ?? null;
6739
6740
  scratch.previews.set(asNodeId(cid), rebaseLocalPose(poseAdapter, pose, parent, pc.compose, pc.decompose));
@@ -8126,6 +8127,11 @@ var cloneAction = {
8126
8127
  id: "clone",
8127
8128
  label: "Clone",
8128
8129
  defaultBinding: { kind: "drag" },
8130
+ // The platform's duplicate cursor, and the whole reason this field is
8131
+ // modifier-aware: the select tool binds clone behind `mods: { alt: true }`,
8132
+ // so the pump predicts it — and shows this — only while Alt is down.
8133
+ cursor: "copy",
8134
+ activeCursor: "copy",
8129
8135
  eligible: { capability: ["edits-page", "creates-selection"] },
8130
8136
  requires: ["selection", "scene", "applyOps"],
8131
8137
  invoker: {
@@ -12286,8 +12292,6 @@ function useHoverTracking(args) {
12286
12292
  }, [canvasRef, enabled]);
12287
12293
  return () => hoverRef.current;
12288
12294
  }
12289
-
12290
- // src/interactions/dispatcher/dispatcher.ts
12291
12295
  function pointerGestureId(pointerId) {
12292
12296
  return `pointer-${pointerId ?? "mouse"}`;
12293
12297
  }
@@ -12792,7 +12796,7 @@ function createDispatcher(opts) {
12792
12796
  }
12793
12797
  function inFlightCursor() {
12794
12798
  for (const action of inFlightActions.values()) {
12795
- const cursor = action.activeCursor ?? action.cursor;
12799
+ const cursor = resolveCursor(action.activeCursor ?? action.cursor);
12796
12800
  if (cursor) return cursor;
12797
12801
  }
12798
12802
  return null;
@@ -12975,8 +12979,6 @@ function itemsFromClipboardData(cd) {
12975
12979
  }
12976
12980
  return out;
12977
12981
  }
12978
-
12979
- // src/interactions/dispatcher/useGestureDispatcher.tsx
12980
12982
  var DROPOVER_CLASS = "weasel-dropover";
12981
12983
  function stylusOf(e) {
12982
12984
  return {
@@ -13018,7 +13020,7 @@ function computeMultiTouchGeometry(positions) {
13018
13020
  return { centroid, spread };
13019
13021
  }
13020
13022
  function useGestureDispatcher(opts) {
13021
- const { canvasRef, actions, toolsById, enabled = true, keyboard = true, affordanceAt, classifyTarget, dispatcher: dispatcherOpt, clientToWorld: clientToWorld2, requestRedraw, getRuleCtx, onDoubleClick, views } = opts;
13023
+ const { canvasRef, actions, toolsById, enabled = true, keyboard = true, affordanceAt, classifyTarget, dispatcher: dispatcherOpt, clientToWorld: clientToWorld2, requestRedraw, paintedCursor, getRuleCtx, onDoubleClick, views } = opts;
13022
13024
  const onDoubleClickRef = useRef(onDoubleClick);
13023
13025
  onDoubleClickRef.current = onDoubleClick;
13024
13026
  const activeTool = useActiveToolContext();
@@ -13067,6 +13069,8 @@ function useGestureDispatcher(opts) {
13067
13069
  ];
13068
13070
  const requestRedrawRef = useRef(requestRedraw);
13069
13071
  requestRedrawRef.current = requestRedraw;
13072
+ const paintedCursorRef = useRef(paintedCursor);
13073
+ paintedCursorRef.current = paintedCursor;
13070
13074
  const lastClickRef = useRef(null);
13071
13075
  const prevActiveRef = useRef(activeTool.active);
13072
13076
  useEffect(() => {
@@ -13406,20 +13410,39 @@ function useGestureDispatcher(opts) {
13406
13410
  let lastHover = null;
13407
13411
  let cursorOverridden = false;
13408
13412
  const clearHoverCursor = () => {
13413
+ paintedCursorRef.current?.()?.setOverride(null);
13409
13414
  if (cursorOverridden && canvas) {
13410
13415
  canvas.style.cursor = "";
13411
13416
  cursorOverridden = false;
13412
13417
  }
13413
13418
  };
13414
- const applyHoverCursor = (cursor) => {
13415
- if (cursor && canvas) {
13416
- canvas.style.cursor = cursor;
13417
- cursorOverridden = true;
13418
- } else {
13419
+ const applyHoverCursor = (spec) => {
13420
+ const tier = spec === null ? null : resolveCursorTier(spec);
13421
+ if (!tier || !canvas) {
13419
13422
  clearHoverCursor();
13423
+ return;
13420
13424
  }
13425
+ const painted = tier.kind === "painted" ? tier : null;
13426
+ paintedCursorRef.current?.()?.setOverride(painted);
13427
+ const cursor = tier.kind === "css" ? tier.css : "none";
13428
+ if (!cursor) {
13429
+ clearHoverCursor();
13430
+ return;
13431
+ }
13432
+ canvas.style.cursor = cursor;
13433
+ cursorOverridden = true;
13421
13434
  };
13435
+ function pushPaintedPointer() {
13436
+ const painted = paintedCursorRef.current?.();
13437
+ if (!painted?.active() || !canvas || !lastHover) return;
13438
+ const r = canvas.getBoundingClientRect();
13439
+ painted.setPointer(lastHover.clientX - r.left, lastHover.clientY - r.top);
13440
+ }
13422
13441
  function refreshHoverCursor() {
13442
+ resolveHoverCursor();
13443
+ pushPaintedPointer();
13444
+ }
13445
+ function resolveHoverCursor() {
13423
13446
  if (!canvas || !lastHover) return;
13424
13447
  if (activePointers.size > 0 || dispatcherNow().inFlight().size > 0) {
13425
13448
  applyHoverCursor(dispatcherNow().inFlightCursor());
@@ -13471,6 +13494,7 @@ function useGestureDispatcher(opts) {
13471
13494
  };
13472
13495
  const onHoverPointerLeave = () => {
13473
13496
  lastHover = null;
13497
+ paintedCursorRef.current?.()?.clearPointer();
13474
13498
  clearHoverCursor();
13475
13499
  };
13476
13500
  const onPointerUp = (e) => {
@@ -15200,7 +15224,7 @@ function validateId(id, kind) {
15200
15224
  }
15201
15225
  function defineTool(def) {
15202
15226
  validateId(def.id, "tool");
15203
- const resolveCursor = (ctx) => {
15227
+ const resolveCursor3 = (ctx) => {
15204
15228
  if (def.cursor == null) return "";
15205
15229
  return typeof def.cursor === "function" ? def.cursor(ctx) : def.cursor;
15206
15230
  };
@@ -15218,7 +15242,7 @@ function defineTool(def) {
15218
15242
  onActivate: def.onActivate,
15219
15243
  onDeactivate: def.onDeactivate,
15220
15244
  initScratch: def.initScratch ?? (() => null),
15221
- cursor: resolveCursor,
15245
+ cursor: resolveCursor3,
15222
15246
  bindings: def.bindings,
15223
15247
  overlay: def.overlay,
15224
15248
  overlayPosition: def.overlayPosition
@@ -17288,6 +17312,9 @@ function transformOf(state, targetId) {
17288
17312
  identity: false
17289
17313
  };
17290
17314
  }
17315
+ function angleOf(xf) {
17316
+ return xf.identity ? 0 : Math.atan2(xf.sin, xf.cos);
17317
+ }
17291
17318
  function localToWorld(xf, lx, ly) {
17292
17319
  if (xf.identity) return { x: lx, y: ly };
17293
17320
  const dx = lx - xf.cx;
@@ -17591,11 +17618,7 @@ var DEFAULT_PAINT = {
17591
17618
  insetPx: 10
17592
17619
  };
17593
17620
  function createRotationAffordance(opts = {}) {
17594
- const {
17595
- bandPx = 24,
17596
- paint = DEFAULT_PAINT,
17597
- cursor = "grab"
17598
- } = opts;
17621
+ const { bandPx = 24, paint = DEFAULT_PAINT, cursor } = opts;
17599
17622
  const annulusPaint = (() => {
17600
17623
  if (!paint) return null;
17601
17624
  if ("paint" in paint) {
@@ -17633,7 +17656,14 @@ function createRotationAffordance(opts = {}) {
17633
17656
  },
17634
17657
  ...annulusPaint ? { paint: annulusPaint } : {},
17635
17658
  hitKind: "rotate-handle",
17636
- cursor,
17659
+ // Turned with the target, so the arc follows the selection it rotates.
17660
+ // Resolved per region rather than defaulted in the option list because
17661
+ // the angle is only known once a target is picked.
17662
+ cursor: cursor ?? {
17663
+ glyph: "rotate",
17664
+ angle: angleOf(transformOf(state, target.id)),
17665
+ fallback: "grab"
17666
+ },
17637
17667
  bind: () => ({
17638
17668
  initialScratch: {
17639
17669
  targetId: target.id,
@@ -18116,7 +18146,7 @@ function useRectTool() {
18116
18146
  id: "rect",
18117
18147
  capabilities: ["creates-shapes"],
18118
18148
  hookName: "useRectTool",
18119
- cursor: "crosshair",
18149
+ cursor: cursorFor("crosshairRect", { fallback: "crosshair" }),
18120
18150
  presentation: {
18121
18151
  label: "Rectangle",
18122
18152
  icon: createElement(RectIcon),
@@ -18142,7 +18172,7 @@ function useEllipseTool() {
18142
18172
  id: "ellipse",
18143
18173
  capabilities: ["creates-shapes"],
18144
18174
  hookName: "useEllipseTool",
18145
- cursor: "crosshair",
18175
+ cursor: cursorFor("crosshairEllipse", { fallback: "crosshair" }),
18146
18176
  presentation: {
18147
18177
  label: "Ellipse",
18148
18178
  group: "shape",
@@ -18250,7 +18280,7 @@ function useLineTool() {
18250
18280
  id: "line",
18251
18281
  capabilities: ["creates-shapes"],
18252
18282
  hookName: "useLineTool",
18253
- cursor: "crosshair",
18283
+ cursor: cursorFor("crosshairLine", { fallback: "crosshair" }),
18254
18284
  presentation: {
18255
18285
  label: "Line",
18256
18286
  group: "shape",
@@ -18365,7 +18395,7 @@ function usePolygonTool(options = {}) {
18365
18395
  id: "polygon",
18366
18396
  capabilities: ["creates-shapes"],
18367
18397
  hookName: "usePolygonTool",
18368
- cursor: "crosshair",
18398
+ cursor: cursorFor("crosshairPolygon", { fallback: "crosshair" }),
18369
18399
  // Registered by <ToolActionsMounter>, inside the ActionsProvider —
18370
18400
  // see `ToolDef.actions` for why the hook can't register it itself.
18371
18401
  actions: [adjustSidesAction],
@@ -18465,7 +18495,7 @@ function useStarTool(options = {}) {
18465
18495
  id: "star",
18466
18496
  capabilities: ["creates-shapes"],
18467
18497
  hookName: "useStarTool",
18468
- cursor: "crosshair",
18498
+ cursor: cursorFor("crosshairStar", { fallback: "crosshair" }),
18469
18499
  // Registered by <ToolActionsMounter>, inside the ActionsProvider —
18470
18500
  // see `ToolDef.actions` for why the hook can't register it itself.
18471
18501
  actions: [adjustPointsAction],
@@ -19592,6 +19622,113 @@ function buildSceneTree(adapter, drawOne, view, forLayer, derivedPathOf) {
19592
19622
  }
19593
19623
  return out;
19594
19624
  }
19625
+
19626
+ // src/features/cursor/paintedCursorState.ts
19627
+ function same(a, b) {
19628
+ if (a === b) return true;
19629
+ if (!a || !b) return false;
19630
+ return a.glyph === b.glyph && a.angle === b.angle && a.size === b.size && a.worldRadius === b.worldRadius;
19631
+ }
19632
+ function createPaintedCursorState() {
19633
+ let base = null;
19634
+ let override = null;
19635
+ let at = null;
19636
+ const subs = /* @__PURE__ */ new Set();
19637
+ const notify2 = () => {
19638
+ for (const fn of subs) fn();
19639
+ };
19640
+ return {
19641
+ setBase(cursor) {
19642
+ if (same(base, cursor)) return;
19643
+ base = cursor;
19644
+ notify2();
19645
+ },
19646
+ setOverride(cursor) {
19647
+ if (same(override, cursor)) return;
19648
+ override = cursor;
19649
+ notify2();
19650
+ },
19651
+ setPointer(x, y) {
19652
+ if (at && at.x === x && at.y === y) return;
19653
+ at = { x, y };
19654
+ if (override ?? base) notify2();
19655
+ },
19656
+ clearPointer() {
19657
+ if (at === null) return;
19658
+ at = null;
19659
+ notify2();
19660
+ },
19661
+ active() {
19662
+ return (override ?? base) !== null;
19663
+ },
19664
+ current() {
19665
+ const cursor = override ?? base;
19666
+ if (!cursor || !at) return null;
19667
+ return { cursor, at };
19668
+ },
19669
+ subscribe(fn) {
19670
+ subs.add(fn);
19671
+ return () => {
19672
+ subs.delete(fn);
19673
+ };
19674
+ }
19675
+ };
19676
+ }
19677
+ var PAINTED_CURSOR_LAYER_ID = "painted-cursor";
19678
+ var pathCache = /* @__PURE__ */ new Map();
19679
+ function pathFor(d) {
19680
+ let p = pathCache.get(d);
19681
+ if (p === void 0) {
19682
+ p = pathFromD(d);
19683
+ pathCache.set(d, p);
19684
+ }
19685
+ return p;
19686
+ }
19687
+ function commandFor2(op) {
19688
+ return {
19689
+ kind: "path",
19690
+ path: pathFor(op.d),
19691
+ ...op.fill !== void 0 ? { fill: { color: op.fill } } : {},
19692
+ ...op.stroke !== void 0 ? {
19693
+ stroke: {
19694
+ paint: { color: op.stroke.color },
19695
+ width: op.stroke.width,
19696
+ cap: "round",
19697
+ join: "round"
19698
+ }
19699
+ } : {}
19700
+ };
19701
+ }
19702
+ function createPaintedCursorLayer(state) {
19703
+ return {
19704
+ id: PAINTED_CURSOR_LAYER_ID,
19705
+ label: "Painted cursor",
19706
+ space: "screen",
19707
+ draw: (_data, view) => {
19708
+ const frame = state.current();
19709
+ if (!frame) return [];
19710
+ const { cursor, at } = frame;
19711
+ const glyph = GLYPHS[cursor.glyph];
19712
+ if (!glyph) return [];
19713
+ const scale2 = (view.scale.x + view.scale.y) / 2;
19714
+ const worldSized = cursor.worldRadius !== void 0;
19715
+ const size = worldSized ? cursorWorldSize(glyph, cursor.worldRadius, scale2) : cursor.size ?? 24;
19716
+ if (!(size > 0) || !Number.isFinite(size)) return [];
19717
+ const ops = cursorPaintOps(
19718
+ glyph,
19719
+ worldSized ? { lineWidthScale: chromeLineWidthScale(glyph, size) } : {}
19720
+ );
19721
+ const [a, b, c, d, e, f] = cursorPaintMatrix(glyph, {
19722
+ size,
19723
+ angle: cursor.angle,
19724
+ at
19725
+ });
19726
+ const transform = new Float32Array([a, b, 0, c, d, 0, e, f, 1]);
19727
+ const children = ops.map(commandFor2);
19728
+ return [{ kind: "group", transform, children }];
19729
+ }
19730
+ };
19731
+ }
19595
19732
  function mat3ToRenderMatrix(m) {
19596
19733
  return new Float32Array([m[0], m[1], 0, m[2], m[3], 0, m[4], m[5], 1]);
19597
19734
  }
@@ -19972,11 +20109,11 @@ function resolveToolsCursor(tools, ctxBase) {
19972
20109
  const id = tools.hotkeyEngaged ?? tools.active;
19973
20110
  const tool = tools.registry[id];
19974
20111
  if (!tool?.cursor) return void 0;
19975
- if (typeof tool.cursor === "string") return tool.cursor;
20112
+ if (typeof tool.cursor !== "function") return resolveCursorTier(tool.cursor);
19976
20113
  if (!ctxBase) return void 0;
19977
20114
  try {
19978
20115
  const base = ctxBase();
19979
- return tool.cursor({ ...base, scratch: null });
20116
+ return resolveCursorTier(tool.cursor({ ...base, scratch: null }));
19980
20117
  } catch {
19981
20118
  return void 0;
19982
20119
  }
@@ -20141,6 +20278,14 @@ function CanvasInner(props, ref) {
20141
20278
  viewSubsRef.current.delete(fn);
20142
20279
  };
20143
20280
  }, []);
20281
+ const paintedCursor = useMemo(() => createPaintedCursorState(), []);
20282
+ const paintedCursorLayer = useMemo(
20283
+ () => createPaintedCursorLayer(paintedCursor),
20284
+ [paintedCursor]
20285
+ );
20286
+ useEffect(() => paintedCursor.subscribe(() => {
20287
+ requestRedraw();
20288
+ }), [paintedCursor, requestRedraw]);
20144
20289
  useImperativeHandle(ref, () => ({
20145
20290
  // Named rather than read off `canvasRef` so the handle rebuilds when a
20146
20291
  // detached surface's input element arrives, which is a render later.
@@ -20153,7 +20298,8 @@ function CanvasInner(props, ref) {
20153
20298
  getView,
20154
20299
  setView,
20155
20300
  subscribeView,
20156
- getPaintedVersion
20301
+ getPaintedVersion,
20302
+ paintedCursor
20157
20303
  }), [
20158
20304
  canvasRef,
20159
20305
  ownCanvasRef,
@@ -20167,7 +20313,8 @@ function CanvasInner(props, ref) {
20167
20313
  getView,
20168
20314
  setView,
20169
20315
  subscribeView,
20170
- getPaintedVersion
20316
+ getPaintedVersion,
20317
+ paintedCursor
20171
20318
  ]);
20172
20319
  const glRendererRef = useRef(null);
20173
20320
  const layerCacheRef = useRef(/* @__PURE__ */ new Map());
@@ -20431,8 +20578,16 @@ function CanvasInner(props, ref) {
20431
20578
  const layersWithDebug = useMemo(() => {
20432
20579
  const withViews = viewRegistry ? [...layers, ...viewRegistry.list().map((r) => r.layer)] : layers;
20433
20580
  const base = debugSink && resolvedDebugConfig ? [...withViews, createDebugOverlayLayer({ sink: debugSink, config: resolvedDebugConfig })] : withViews;
20434
- return [...base, ...extrasRef.current];
20435
- }, [layers, debugSink, resolvedDebugConfig, extrasVersion, viewRegistry, viewRegistryVersion]);
20581
+ return [...base, ...extrasRef.current, paintedCursorLayer];
20582
+ }, [
20583
+ layers,
20584
+ debugSink,
20585
+ resolvedDebugConfig,
20586
+ extrasVersion,
20587
+ viewRegistry,
20588
+ viewRegistryVersion,
20589
+ paintedCursorLayer
20590
+ ]);
20436
20591
  const shaderIdKey = shaders?.map((h) => h.id).join("|") ?? "";
20437
20592
  const paintInputsRef = useRef({
20438
20593
  layers: layersWithDebug,
@@ -20554,8 +20709,14 @@ function CanvasInner(props, ref) {
20554
20709
  if (!renderer) return;
20555
20710
  registerShadersOnRenderer(renderer, shaders);
20556
20711
  }, [shaderIdKey]);
20557
- const toolsCursor = tools ? resolveToolsCursor(tools, toolsCtxBase) : void 0;
20712
+ const toolsCursorTier = tools ? resolveToolsCursor(tools, toolsCtxBase) : void 0;
20713
+ const toolsCursor = toolsCursorTier === void 0 ? void 0 : toolsCursorTier.kind === "css" ? toolsCursorTier.css : "none";
20558
20714
  const effectiveStyle = toolsCursor ? { ...style, cursor: toolsCursor } : style;
20715
+ const toolsPainted = toolsCursorTier?.kind === "painted" ? toolsCursorTier : null;
20716
+ const toolsPaintedKey = toolsPainted ? `${toolsPainted.glyph}|${toolsPainted.angle}|${toolsPainted.size}|${toolsPainted.worldRadius}` : "";
20717
+ useEffect(() => {
20718
+ paintedCursor.setBase(toolsPainted);
20719
+ }, [paintedCursor, toolsPaintedKey]);
20559
20720
  const layersForMoveRef = useRef(layersWithDebug);
20560
20721
  layersForMoveRef.current = layersWithDebug;
20561
20722
  useEffect(() => {
@@ -21894,10 +22055,16 @@ function createCornerResizeAffordance(opts = {}) {
21894
22055
  hitKind: c.kind,
21895
22056
  // Diagonal by fixed-corner parity: a matched-axis anchor (min-min /
21896
22057
  // max-max fixed) means the dragged corner sits on the ↘ diagonal;
21897
- // mixed axes sit on the ↗ diagonal. Not rotation-aware — a rotated
21898
- // target keeps the unrotated hint, the same policy as every
21899
- // mainstream editor short of Figma.
21900
- cursor: c.anchor.x === c.anchor.y ? "nwse-resize" : "nesw-resize",
22058
+ // mixed axes sit on the ↗ diagonal. The glyph is horizontal at angle
22059
+ // 0, so the diagonal is a half-quarter-turn either way, plus the
22060
+ // target's own rotation. The keyword is the fallback rather than the
22061
+ // answer: CSS has four of them, which cannot express a target
22062
+ // rotated to anything but a multiple of 45°.
22063
+ cursor: {
22064
+ glyph: "resize",
22065
+ angle: (c.anchor.x === c.anchor.y ? Math.PI / 4 : -Math.PI / 4) + angleOf(xf),
22066
+ fallback: c.anchor.x === c.anchor.y ? "nwse-resize" : "nesw-resize"
22067
+ },
21901
22068
  bind: () => ({
21902
22069
  initialScratch: {
21903
22070
  anchor: c.anchor,
@@ -25920,6 +26087,10 @@ function GestureDispatcherMounter({
25920
26087
  const requestRedraw = useCallback(() => {
25921
26088
  canvasApiRef?.current?.requestRedraw?.();
25922
26089
  }, [canvasApiRef]);
26090
+ const paintedCursor = useCallback(
26091
+ () => canvasApiRef?.current?.paintedCursor,
26092
+ [canvasApiRef]
26093
+ );
25923
26094
  const views = useMemo(() => {
25924
26095
  if (!viewRegistry) return void 0;
25925
26096
  return {
@@ -25938,6 +26109,7 @@ function GestureDispatcherMounter({
25938
26109
  dispatcher,
25939
26110
  clientToWorld: clientToWorld2,
25940
26111
  requestRedraw,
26112
+ paintedCursor,
25941
26113
  getRuleCtx,
25942
26114
  onDoubleClick,
25943
26115
  ...views ? { views } : {}
@@ -30684,6 +30856,6 @@ function mergeContributions(...bundles) {
30684
30856
  return out;
30685
30857
  }
30686
30858
 
30687
- export { ALWAYS, ANCHOR_HIT_BASE_PX, ActionsProviderIfRoot, ActiveToolContextProvider, ActiveToolContextProviderIfRoot, ArrowIcon, BUILTIN_MARKERS, BUNDLE_TOOLS, COARSE_TARGET_SCALE, CURVE_REPS, CanvasView, ColorOverrideRegistry, CropIcon, CursorCoordsHud, DEFAULT_ALPHA_DECAY, DEFAULT_ALPHA_MIN, DEFAULT_DEBUG_STROKES, DEFAULT_DEBUG_THEME, DEFAULT_DEVICE_PROFILE, DEFAULT_FILL_COLOR, DEFAULT_HANDLE_SIZE2 as DEFAULT_HANDLE_SIZE, DEFAULT_MAX_ZOOM, DEFAULT_MIN_ZOOM, DEFAULT_PALETTE, DEFAULT_ROTATION_HANDLE_DISTANCE, DEFAULT_SHAPE_FILL, DEFAULT_STROKE_COLOR, DEFAULT_VELOCITY_DECAY, DepRegistryProviderIfRoot, DeviceProfileProvider, DivideIcon, EASINGS, EllipseIcon, ExcludeIcon, EyedropperIcon, FALLBACK_FIT_VIEW, GHOST_STROKE, HANDLE_BASE_PX, HandIcon, IDENTITY_COLOR_MATRIX, IDENTITY_JOINT, IDENTITY_POSE_COMPOSITION, ImageIcon, IntersectIcon, KIT_SHAPE_KINDS, LassoIcon, LineIcon, MIXED, MOVE_ANCHORS, MinimapCanvas, NEVER, OUTLINE_MIN_SCREEN_PX, PATH_ANCHOR_CHROME_ID, PenIcon, PencilIcon, PickHud, PointerProviderIfRoot, PolygonIcon, RECT_ALIGN_PROJECTION, ROTATION_HANDLE_BASE_PX, RectIcon, SPRING_PRESETS, SceneCanvas, SceneViewCanvas, SelectIcon, SelectionContextProvider, SelectionContextProviderIfRoot, ShaderCompileError, StarIcon, SubtractIcon, TOOL_PREF_KINDS, TextIcon, UnionIcon, UnknownIcon, VERSION, VIEW_ANIMATION_KEY, WeaselProvider, WeaselRenderer, _resetMarkersForTests, _resetPaintKindsForTests, aabbCenter, actionIs, actionShortcuts, alignDeltaFor, alignInsertBehavior, alignMoveBehavior, alignResizeBehavior, always, and, animateLifecycle, animateOnSetPose, annulusSemiAxes, applyBooleanOp, applyStyleToRange, areaSelectAction, arrayAdapter, asNodeId, asPaint, axisAlignedBounds, bezierCubic, bezierQuadratic, blendPoses, buildChromeCtx, buildGradientRamp, buildRuleCtx, buildSceneViewCommands, canBringForward, canHover, canSendBackward, capabilityAll, capabilityIn, capabilityIs, capabilityNot, caretIndexAt, cellAt, charOffsetToDomPosition, clampView, clearSelectionAction, clientToCanvas, clipboardCopyAction, clipboardCutAction, cloneAction, coarsePointer, composeAffordanceLayer, composePath, composeRectPose, composeSelectionPose, composeWorldPose, computeFitView, computeFitViewport, computeIndicatorCommand, computeWheelAction, cond, constrainTo45, containedThenNearest, countPathAnchors, createCellHighlightLayer, createChildrenLayer, createCornerResizeAffordance, createDebugOverlayLayer, createDebugSink, createDispatcher, createGridLayer, createGuidesLayer, createHistory2 as createHistory, createMoveToIndexOp, createNodeProperties, createNodeRouting, createParallaxLayer, createPathAnchorAffordances, createPathEditingOverlayLayer, createPathLayer, createPenPreviewLayer, createReorderOp, createRotationAffordance, createScene, createSelectionHandlesLayer, createSelectionOutlineLayer, createSelectionOverlayLayer, createSetDataOp, createSetLayerOp, createSetPathOp, createSetTextOp, createTextLayer, createViewResolver, createViewportLayer, cubicBezierEasing, cycleVertexColors, decomposePath, decomposeRectPose, defaultCommitAdapter, defaultDrawOne, defaultLabelTextRenderer, defaultNodeProperties, defaultNodeRouting, defaultVisibilityRules, defineTool, defineViewportTool, deriveAlignmentGuides, deriveParallaxView, describeRule, domPositionToCharOffset, domToRuns, drawLayers, drawOneLayer, easeIn, easeInBack, easeInBounce, easeInCirc, easeInCubic, easeInElastic, easeInExpo, easeInOut, easeInOutBack, easeInOutBounce, easeInOutCirc, easeInOutCubic, easeInOutElastic, easeInOutExpo, easeInOutQuad, easeInOutQuart, easeInOutQuint, easeInOutSine, easeInQuad, easeInQuart, easeInQuint, easeInSine, easeOut, easeOutBack, easeOutBounce, easeOutCirc, easeOutCubic, easeOutElastic, easeOutExpo, easeOutQuad, easeOutQuart, easeOutQuint, easeOutSine, editAnchorsAction, enterTextEditAction, enumerateAnchors, evaluate, fillInPoseFrame, fillToBoundsFrame, findNodeShape, findShapeInk, findShapeSilhouette, fitTextPose, fitToBounds, fitViewToBounds, fitZoom, focused, forEachCoalesced, frameRect, freeform, gateLayer, gesturing, getAlpha01, getImageBitmap, getMarker, getNodeShapes, getPaintKind, getStylusData, gradientForBounds, gradientGeometry, hexToRgba, hitAffordanceRegions, hitAnchor, hitRotationHandle, hostAnchorCss, hostAnchorRect, hovering, hoveringSelected, imageStatus, inferredNodeProperties, inferredNodeRouting, insertAction, interpolateView, isBuiltinToolPref, isEditableTarget2 as isEditableTarget, isGradientFill, isLayerPainted, isLayerVisible, isPatternSpec, keySpecShortcut, lassoSelectAction, lerpColorArray, lerpOklab, lerpOklch, linear, listMarkers, listPaintKinds, liveScope, makePinchZoomAction, makeViewportZoomAction, markerDrawCommands, markerInset, markerKeyOf, markerSites, mat3, matchAlignment, matchesKeyBinding, meanScale, mergeAlphaFromPrev, mergeContributions, modeIn, modeIs, modeNot, modifierHeld, momentum, moveAction, multiActive, nearest, nearestWithin, nestedHitTester, never, nodeHasFlag, none, normalizeHex, not, nurbs, oklabToOklch, oklabToSrgbU8, oklchToOklab, openFilePicker, or, paintAlpha, paintKindOf, paintWithAlpha, paintWithColor, parseColor, parseColorToRgba255, parseDebugFlags, pathContainsPoint, pathContainsPolygon, pathContainsRect, pathDistanceToPoint, pathDivide, pathExclude, pathFromD, pathInPoseFrame, pathInWorld, pathIntersect, pathIntersectsPolygon, pathIntersectsRect, pathOriginProjection, pathSubtract, pathToAnchors, pathUnion, pickTopMostHit, pinchZoomAction, planPixelRender, pointInRotatedRect, pointInTextPose, poseRotationOf, pressureToWidth, rainbowVertexColors, rebaseLocalPose, rectCorners, registerContentHandler, registerMarker, registerNodeShape, registerPaintKind, registerProgram, renderLabel, renderSceneToCanvas, renderSceneToPixels, resizeAction, resolveColor, resolveDeviceProfile, resolveEasing, resolveFillPattern, resolveMarkerSize, resolveParams, resolvePatternSpec, resolveSkeleton, resolveStrokeWidth, resolveVisibility, rgbaToHex, rotateAction, rotateAroundAABBCenter, rotatePathAround, rotatePoint, rotatedRectCorners, rotationDegreesUnit, rotationHandle, roundToCell, runsToDom, sampleGradientStops, sampleTrack, sceneFromJSON, sceneNodeClientRect, sceneSelectionStore, sceneToAdapter, scopeBindings, screenToWorld, selectFromLasso, selectionAtLeast, selectionEmpty, selectionIs, setFlagOverRange, shapeCoversPoint, sliceAction, snapPoint, solid, solidVertexColors, specificity, spiro, splitPathByLine, splitSubpaths, springPose, springVertexColors, srgbU8ToOklab, staggerVertexColors, startThresholdDrag, strokeInsets, strokeOf, strokeWith, styleAtRange, subscribeImageReady, tessellate, tessellateStroke, textCommand, textCommandFromRuns, tileGrid, toHex8, translatePoseViaDescriptor, translateRectPose, trimPolyline, tweenPose, tweenVertexColors, unionAABB, unionBounds, unionBoundsPath, useActiveToolContext, useAlign, useAnimator, useArrayAdapter, useAutoCenter, useBooleans, useBooleansAdapter, useCanvasFocus, useCanvasSize, useDecayLoop, useDeviceProfile, useDistribute, useDragGesture, useDragHandle, useDragRadial, useDragRect, useDropZone, useEllipseTool, useEyedropperTool, useGestureDispatcher, useGridCellHover, useGuides, useHandTool, useHandleDrag, useHostAnchor, useHoverTracking, useImageTool, useKeybindings, useLassoTool, useLineTool, useNodeOverlayFrame, useOptionalActiveToolContext, usePenTool, usePencilTool, usePinchGesture, usePinchZoomTool, usePointerStylus, usePolygonTool, usePublishSelection, useRectTool, useResizePolicy, useRotateTool, useScene, useSceneAdapter, useSceneTextEdit, useSelectTool, useSelection, useSelectionContext, useSimulation, useSliceDep, useStandardActions, useStarTool, useTextEdit, useTextTool, useTools, useVelocityTracker, useViewAnimation, useVisibleRaf, useZoom, viewToMat3, viewToTransform, viewportDragPanAction, viewportZoomAction, viewportsAt, visualBoundsViaDescriptor, when, withAlpha01, withCoord, withGradientKind, worldEditToStorage, worldPoseLookup, worldToScreen, zoomAt, zoomAtLeast };
30688
- //# sourceMappingURL=chunk-FUQWXDG3.js.map
30689
- //# sourceMappingURL=chunk-FUQWXDG3.js.map
30859
+ export { ALWAYS, ANCHOR_HIT_BASE_PX, ActionsProviderIfRoot, ActiveToolContextProvider, ActiveToolContextProviderIfRoot, ArrowIcon, BUILTIN_MARKERS, BUNDLE_TOOLS, COARSE_TARGET_SCALE, CURVE_REPS, CanvasView, ColorOverrideRegistry, CropIcon, CursorCoordsHud, DEFAULT_ALPHA_DECAY, DEFAULT_ALPHA_MIN, DEFAULT_DEBUG_STROKES, DEFAULT_DEBUG_THEME, DEFAULT_DEVICE_PROFILE, DEFAULT_FILL_COLOR, DEFAULT_HANDLE_SIZE2 as DEFAULT_HANDLE_SIZE, DEFAULT_MAX_ZOOM, DEFAULT_MIN_ZOOM, DEFAULT_PALETTE, DEFAULT_ROTATION_HANDLE_DISTANCE, DEFAULT_SHAPE_FILL, DEFAULT_STROKE_COLOR, DEFAULT_VELOCITY_DECAY, DepRegistryProviderIfRoot, DeviceProfileProvider, DivideIcon, EASINGS, EllipseIcon, ExcludeIcon, EyedropperIcon, FALLBACK_FIT_VIEW, GHOST_STROKE, HANDLE_BASE_PX, HandIcon, IDENTITY_COLOR_MATRIX, IDENTITY_JOINT, IDENTITY_POSE_COMPOSITION, ImageIcon, IntersectIcon, KIT_SHAPE_KINDS, LassoIcon, LineIcon, MIXED, MOVE_ANCHORS, MinimapCanvas, NEVER, OUTLINE_MIN_SCREEN_PX, PAINTED_CURSOR_LAYER_ID, PATH_ANCHOR_CHROME_ID, PenIcon, PencilIcon, PickHud, PointerProviderIfRoot, PolygonIcon, RECT_ALIGN_PROJECTION, ROTATION_HANDLE_BASE_PX, RectIcon, SPRING_PRESETS, SceneCanvas, SceneViewCanvas, SelectIcon, SelectionContextProvider, SelectionContextProviderIfRoot, ShaderCompileError, StarIcon, SubtractIcon, TOOL_PREF_KINDS, TextIcon, UnionIcon, UnknownIcon, VERSION, VIEW_ANIMATION_KEY, WeaselProvider, WeaselRenderer, _resetMarkersForTests, _resetPaintKindsForTests, aabbCenter, actionIs, actionShortcuts, alignDeltaFor, alignInsertBehavior, alignMoveBehavior, alignResizeBehavior, always, and, animateLifecycle, animateOnSetPose, annulusSemiAxes, applyBooleanOp, applyStyleToRange, areaSelectAction, arrayAdapter, asNodeId, asPaint, axisAlignedBounds, bezierCubic, bezierQuadratic, blendPoses, buildChromeCtx, buildGradientRamp, buildRuleCtx, buildSceneViewCommands, canBringForward, canHover, canSendBackward, capabilityAll, capabilityIn, capabilityIs, capabilityNot, caretIndexAt, cellAt, charOffsetToDomPosition, clampView, clearSelectionAction, clientToCanvas, clipboardCopyAction, clipboardCutAction, cloneAction, coarsePointer, composeAffordanceLayer, composePath, composeRectPose, composeSelectionPose, composeWorldPose, computeFitView, computeFitViewport, computeIndicatorCommand, computeWheelAction, cond, constrainTo45, containedThenNearest, countPathAnchors, createCellHighlightLayer, createChildrenLayer, createCornerResizeAffordance, createDebugOverlayLayer, createDebugSink, createDispatcher, createGridLayer, createGuidesLayer, createHistory2 as createHistory, createMoveToIndexOp, createNodeProperties, createNodeRouting, createPaintedCursorLayer, createPaintedCursorState, createParallaxLayer, createPathAnchorAffordances, createPathEditingOverlayLayer, createPathLayer, createPenPreviewLayer, createReorderOp, createRotationAffordance, createScene, createSelectionHandlesLayer, createSelectionOutlineLayer, createSelectionOverlayLayer, createSetDataOp, createSetLayerOp, createSetPathOp, createSetTextOp, createTextLayer, createViewResolver, createViewportLayer, cubicBezierEasing, cycleVertexColors, decomposePath, decomposeRectPose, defaultCommitAdapter, defaultDrawOne, defaultLabelTextRenderer, defaultNodeProperties, defaultNodeRouting, defaultVisibilityRules, defineTool, defineViewportTool, deriveAlignmentGuides, deriveParallaxView, describeRule, domPositionToCharOffset, domToRuns, drawLayers, drawOneLayer, easeIn, easeInBack, easeInBounce, easeInCirc, easeInCubic, easeInElastic, easeInExpo, easeInOut, easeInOutBack, easeInOutBounce, easeInOutCirc, easeInOutCubic, easeInOutElastic, easeInOutExpo, easeInOutQuad, easeInOutQuart, easeInOutQuint, easeInOutSine, easeInQuad, easeInQuart, easeInQuint, easeInSine, easeOut, easeOutBack, easeOutBounce, easeOutCirc, easeOutCubic, easeOutElastic, easeOutExpo, easeOutQuad, easeOutQuart, easeOutQuint, easeOutSine, editAnchorsAction, enterTextEditAction, enumerateAnchors, evaluate, fillInPoseFrame, fillToBoundsFrame, findNodeShape, findShapeInk, findShapeSilhouette, fitTextPose, fitToBounds, fitViewToBounds, fitZoom, focused, forEachCoalesced, frameRect, freeform, gateLayer, gesturing, getAlpha01, getImageBitmap, getMarker, getNodeShapes, getPaintKind, getStylusData, gradientForBounds, gradientGeometry, hexToRgba, hitAffordanceRegions, hitAnchor, hitRotationHandle, hostAnchorCss, hostAnchorRect, hovering, hoveringSelected, imageStatus, inferredNodeProperties, inferredNodeRouting, insertAction, interpolateView, isBuiltinToolPref, isEditableTarget2 as isEditableTarget, isGradientFill, isLayerPainted, isLayerVisible, isPatternSpec, keySpecShortcut, lassoSelectAction, lerpColorArray, lerpOklab, lerpOklch, linear, listMarkers, listPaintKinds, liveScope, makePinchZoomAction, makeViewportZoomAction, markerDrawCommands, markerInset, markerKeyOf, markerSites, mat3, matchAlignment, matchesKeyBinding, meanScale, mergeAlphaFromPrev, mergeContributions, modeIn, modeIs, modeNot, modifierHeld, momentum, moveAction, multiActive, nearest, nearestWithin, nestedHitTester, never, nodeHasFlag, none, normalizeHex, not, nurbs, oklabToOklch, oklabToSrgbU8, oklchToOklab, openFilePicker, or, paintAlpha, paintKindOf, paintWithAlpha, paintWithColor, parseColor, parseColorToRgba255, parseDebugFlags, pathContainsPoint, pathContainsPolygon, pathContainsRect, pathDistanceToPoint, pathDivide, pathExclude, pathFromD, pathInPoseFrame, pathInWorld, pathIntersect, pathIntersectsPolygon, pathIntersectsRect, pathOriginProjection, pathSubtract, pathToAnchors, pathUnion, pickTopMostHit, pinchZoomAction, planPixelRender, pointInRotatedRect, pointInTextPose, poseRotationOf, pressureToWidth, rainbowVertexColors, rebaseLocalPose, rectCorners, registerContentHandler, registerMarker, registerNodeShape, registerPaintKind, registerProgram, renderLabel, renderSceneToCanvas, renderSceneToPixels, resizeAction, resolveColor, resolveDeviceProfile, resolveEasing, resolveFillPattern, resolveMarkerSize, resolveParams, resolvePatternSpec, resolveSkeleton, resolveStrokeWidth, resolveVisibility, rgbaToHex, rotateAction, rotateAroundAABBCenter, rotatePathAround, rotatePoint, rotatedRectCorners, rotationDegreesUnit, rotationHandle, roundToCell, runsToDom, sampleGradientStops, sampleTrack, sceneFromJSON, sceneNodeClientRect, sceneSelectionStore, sceneToAdapter, scopeBindings, screenToWorld, selectFromLasso, selectionAtLeast, selectionEmpty, selectionIs, setFlagOverRange, shapeCoversPoint, sliceAction, snapPoint, solid, solidVertexColors, specificity, spiro, splitPathByLine, splitSubpaths, springPose, springVertexColors, srgbU8ToOklab, staggerVertexColors, startThresholdDrag, strokeInsets, strokeOf, strokeWith, styleAtRange, subscribeImageReady, tessellate, tessellateStroke, textCommand, textCommandFromRuns, tileGrid, toHex8, translatePoseViaDescriptor, translateRectPose, trimPolyline, tweenPose, tweenVertexColors, unionAABB, unionBounds, unionBoundsPath, useActiveToolContext, useAlign, useAnimator, useArrayAdapter, useAutoCenter, useBooleans, useBooleansAdapter, useCanvasFocus, useCanvasSize, useDecayLoop, useDeviceProfile, useDistribute, useDragGesture, useDragHandle, useDragRadial, useDragRect, useDropZone, useEllipseTool, useEyedropperTool, useGestureDispatcher, useGridCellHover, useGuides, useHandTool, useHandleDrag, useHostAnchor, useHoverTracking, useImageTool, useKeybindings, useLassoTool, useLineTool, useNodeOverlayFrame, useOptionalActiveToolContext, usePenTool, usePencilTool, usePinchGesture, usePinchZoomTool, usePointerStylus, usePolygonTool, usePublishSelection, useRectTool, useResizePolicy, useRotateTool, useScene, useSceneAdapter, useSceneTextEdit, useSelectTool, useSelection, useSelectionContext, useSimulation, useSliceDep, useStandardActions, useStarTool, useTextEdit, useTextTool, useTools, useVelocityTracker, useViewAnimation, useVisibleRaf, useZoom, viewToMat3, viewToTransform, viewportDragPanAction, viewportZoomAction, viewportsAt, visualBoundsViaDescriptor, when, withAlpha01, withCoord, withGradientKind, worldEditToStorage, worldPoseLookup, worldToScreen, zoomAt, zoomAtLeast };
30860
+ //# sourceMappingURL=chunk-HYJL7OOJ.js.map
30861
+ //# sourceMappingURL=chunk-HYJL7OOJ.js.map