@fieldnotes/core 0.53.0 → 0.54.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.
- package/dist/index.cjs +243 -15
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +148 -33
- package/dist/index.d.ts +148 -33
- package/dist/index.js +239 -15
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -30,6 +30,7 @@ __export(index_exports, {
|
|
|
30
30
|
HistoryStack: () => HistoryStack,
|
|
31
31
|
ImageTool: () => ImageTool,
|
|
32
32
|
IndexedDBAdapter: () => IndexedDBAdapter,
|
|
33
|
+
LASER_TRAIL_PRESENCE_KIND: () => LASER_TRAIL_PRESENCE_KIND,
|
|
33
34
|
LaserTool: () => LaserTool,
|
|
34
35
|
LayerManager: () => LayerManager,
|
|
35
36
|
LocalStorageAdapter: () => LocalStorageAdapter,
|
|
@@ -37,6 +38,7 @@ __export(index_exports, {
|
|
|
37
38
|
MemoryAdapter: () => MemoryAdapter,
|
|
38
39
|
NoteTool: () => NoteTool,
|
|
39
40
|
PencilTool: () => PencilTool,
|
|
41
|
+
RemoteLaserOverlay: () => RemoteLaserOverlay,
|
|
40
42
|
SelectTool: () => SelectTool,
|
|
41
43
|
ShapeTool: () => ShapeTool,
|
|
42
44
|
TemplateTool: () => TemplateTool,
|
|
@@ -72,12 +74,14 @@ __export(index_exports, {
|
|
|
72
74
|
getHexCellsInRectangle: () => getHexCellsInRectangle,
|
|
73
75
|
getHexCellsInSquare: () => getHexCellsInSquare,
|
|
74
76
|
getHexDistance: () => getHexDistance,
|
|
77
|
+
isLaserTrailPresence: () => isLaserTrailPresence,
|
|
75
78
|
isNearBezier: () => isNearBezier,
|
|
76
79
|
setFontSize: () => setFontSize,
|
|
77
80
|
smartSnap: () => smartSnap,
|
|
78
81
|
snapPoint: () => snapPoint,
|
|
79
82
|
snapToHexCenter: () => snapToHexCenter,
|
|
80
83
|
styleToPatch: () => styleToPatch,
|
|
84
|
+
toLaserTrailPresence: () => toLaserTrailPresence,
|
|
81
85
|
toggleBold: () => toggleBold,
|
|
82
86
|
toggleItalic: () => toggleItalic,
|
|
83
87
|
toggleStrikethrough: () => toggleStrikethrough,
|
|
@@ -6922,6 +6926,7 @@ var RenderLoop = class {
|
|
|
6922
6926
|
// set on recenter/viewport-change; consumed by the grid block
|
|
6923
6927
|
stats = new RenderStats();
|
|
6924
6928
|
layerGroups = /* @__PURE__ */ new Map();
|
|
6929
|
+
overlays = /* @__PURE__ */ new Set();
|
|
6925
6930
|
gridCacheCanvas = null;
|
|
6926
6931
|
gridCacheCtx = null;
|
|
6927
6932
|
lastGridRefs = [];
|
|
@@ -6980,6 +6985,29 @@ var RenderLoop = class {
|
|
|
6980
6985
|
getStats() {
|
|
6981
6986
|
return this.stats.getSnapshot();
|
|
6982
6987
|
}
|
|
6988
|
+
/**
|
|
6989
|
+
* Registers a viewport overlay drawn beneath the active tool's own overlay.
|
|
6990
|
+
* Returns an idempotent unsubscribe that also erases the overlay's last
|
|
6991
|
+
* frame.
|
|
6992
|
+
*/
|
|
6993
|
+
registerOverlay(draw) {
|
|
6994
|
+
this.overlays.add(draw);
|
|
6995
|
+
this.requestRender();
|
|
6996
|
+
return () => {
|
|
6997
|
+
if (this.overlays.delete(draw)) this.requestRender();
|
|
6998
|
+
};
|
|
6999
|
+
}
|
|
7000
|
+
drawRegisteredOverlays(ctx) {
|
|
7001
|
+
for (const draw of this.overlays) {
|
|
7002
|
+
ctx.save();
|
|
7003
|
+
try {
|
|
7004
|
+
draw(ctx);
|
|
7005
|
+
} catch {
|
|
7006
|
+
} finally {
|
|
7007
|
+
ctx.restore();
|
|
7008
|
+
}
|
|
7009
|
+
}
|
|
7010
|
+
}
|
|
6983
7011
|
compositeLayerCache(ctx, layerId, opacity) {
|
|
6984
7012
|
const cached = this.layerCache.getCanvas(layerId);
|
|
6985
7013
|
const offset = this.marginViewport.compositeOffset(
|
|
@@ -7113,7 +7141,8 @@ var RenderLoop = class {
|
|
|
7113
7141
|
}
|
|
7114
7142
|
const activeTool = this.toolManager.activeTool;
|
|
7115
7143
|
const overlayOrder = visibleElements.length + 1;
|
|
7116
|
-
|
|
7144
|
+
const hasOverlay = activeTool?.renderOverlay !== void 0 || this.overlays.size > 0;
|
|
7145
|
+
if (hybridActive && hasOverlay) hybridOrders.add(overlayOrder);
|
|
7117
7146
|
this.hybridSurface.beginFrame(hybridOrders, this.canvasEl.width, this.canvasEl.height);
|
|
7118
7147
|
for (const [layerId, elements] of this.layerGroups) {
|
|
7119
7148
|
const isActiveDrawingLayer = layerId === this.activeDrawingLayerId;
|
|
@@ -7223,7 +7252,7 @@ var RenderLoop = class {
|
|
|
7223
7252
|
hybridCtx.restore();
|
|
7224
7253
|
}
|
|
7225
7254
|
const overlayT0 = performance.now();
|
|
7226
|
-
if (hybridActive &&
|
|
7255
|
+
if (hybridActive && hasOverlay) {
|
|
7227
7256
|
const overlayCtx = this.hybridSurface.getContext(overlayOrder);
|
|
7228
7257
|
if (overlayCtx) {
|
|
7229
7258
|
overlayCtx.clearRect(0, 0, this.canvasEl.width, this.canvasEl.height);
|
|
@@ -7231,11 +7260,13 @@ var RenderLoop = class {
|
|
|
7231
7260
|
overlayCtx.scale(dpr, dpr);
|
|
7232
7261
|
overlayCtx.translate(this.camera.position.x, this.camera.position.y);
|
|
7233
7262
|
overlayCtx.scale(this.camera.zoom, this.camera.zoom);
|
|
7234
|
-
|
|
7263
|
+
this.drawRegisteredOverlays(overlayCtx);
|
|
7264
|
+
if (activeTool?.renderOverlay) activeTool.renderOverlay(overlayCtx);
|
|
7235
7265
|
overlayCtx.restore();
|
|
7236
7266
|
}
|
|
7237
|
-
} else if (
|
|
7238
|
-
|
|
7267
|
+
} else if (hasOverlay) {
|
|
7268
|
+
this.drawRegisteredOverlays(ctx);
|
|
7269
|
+
if (activeTool?.renderOverlay) activeTool.renderOverlay(ctx);
|
|
7239
7270
|
}
|
|
7240
7271
|
const overlayMs = performance.now() - overlayT0;
|
|
7241
7272
|
ctx.restore();
|
|
@@ -8229,6 +8260,17 @@ var Viewport = class {
|
|
|
8229
8260
|
requestRender() {
|
|
8230
8261
|
this.renderLoop.requestRender();
|
|
8231
8262
|
}
|
|
8263
|
+
/**
|
|
8264
|
+
* Registers a world-space overlay drawn above elements on every frame,
|
|
8265
|
+
* regardless of the active tool — the surface for remote presence visuals
|
|
8266
|
+
* such as laser trails, cursors, pings, and shared rulers. Overlays draw
|
|
8267
|
+
* beneath the active tool's own `renderOverlay` and never touch elements,
|
|
8268
|
+
* history, or persisted state. Returns an idempotent unsubscribe that also
|
|
8269
|
+
* erases the overlay's last frame.
|
|
8270
|
+
*/
|
|
8271
|
+
registerOverlay(draw) {
|
|
8272
|
+
return this.renderLoop.registerOverlay(draw);
|
|
8273
|
+
}
|
|
8232
8274
|
exportState() {
|
|
8233
8275
|
return exportState(
|
|
8234
8276
|
this.store.snapshot(),
|
|
@@ -8576,6 +8618,154 @@ var Viewport = class {
|
|
|
8576
8618
|
}
|
|
8577
8619
|
};
|
|
8578
8620
|
|
|
8621
|
+
// src/canvas/remote-laser-overlay.ts
|
|
8622
|
+
var LASER_TRAIL_PRESENCE_KIND = "laser";
|
|
8623
|
+
function isFinitePoint(value) {
|
|
8624
|
+
if (typeof value !== "object" || value === null) return false;
|
|
8625
|
+
const point = value;
|
|
8626
|
+
return typeof point.x === "number" && Number.isFinite(point.x) && typeof point.y === "number" && Number.isFinite(point.y);
|
|
8627
|
+
}
|
|
8628
|
+
function isLaserTrailPresence(data) {
|
|
8629
|
+
if (typeof data !== "object" || data === null) return false;
|
|
8630
|
+
const payload = data;
|
|
8631
|
+
if (payload.kind !== LASER_TRAIL_PRESENCE_KIND) return false;
|
|
8632
|
+
if (!Array.isArray(payload.points) || !payload.points.every(isFinitePoint)) return false;
|
|
8633
|
+
if (payload.color !== void 0 && typeof payload.color !== "string") return false;
|
|
8634
|
+
if (payload.width !== void 0 && !(typeof payload.width === "number" && payload.width > 0)) {
|
|
8635
|
+
return false;
|
|
8636
|
+
}
|
|
8637
|
+
if (payload.fadeMs !== void 0 && !(typeof payload.fadeMs === "number" && payload.fadeMs > 0)) {
|
|
8638
|
+
return false;
|
|
8639
|
+
}
|
|
8640
|
+
return true;
|
|
8641
|
+
}
|
|
8642
|
+
function toLaserTrailPresence(emission) {
|
|
8643
|
+
return {
|
|
8644
|
+
kind: LASER_TRAIL_PRESENCE_KIND,
|
|
8645
|
+
points: emission.points.map((point) => ({ x: point.x, y: point.y })),
|
|
8646
|
+
color: emission.color,
|
|
8647
|
+
width: emission.width,
|
|
8648
|
+
fadeMs: emission.fadeMs
|
|
8649
|
+
};
|
|
8650
|
+
}
|
|
8651
|
+
var DEFAULT_COLOR = "#ff3b30";
|
|
8652
|
+
var DEFAULT_WIDTH = 4;
|
|
8653
|
+
var DEFAULT_FADE_MS = 1200;
|
|
8654
|
+
var DEFAULT_MAX_POINTS = 512;
|
|
8655
|
+
var RemoteLaserOverlay = class {
|
|
8656
|
+
host;
|
|
8657
|
+
color;
|
|
8658
|
+
width;
|
|
8659
|
+
fadeMs;
|
|
8660
|
+
maxPointsPerSender;
|
|
8661
|
+
trails = /* @__PURE__ */ new Map();
|
|
8662
|
+
unregister;
|
|
8663
|
+
rafId = null;
|
|
8664
|
+
disposed = false;
|
|
8665
|
+
constructor(host, options = {}) {
|
|
8666
|
+
this.host = host;
|
|
8667
|
+
this.color = options.color ?? DEFAULT_COLOR;
|
|
8668
|
+
this.width = options.width ?? DEFAULT_WIDTH;
|
|
8669
|
+
this.fadeMs = options.fadeMs ?? DEFAULT_FADE_MS;
|
|
8670
|
+
this.maxPointsPerSender = options.maxPointsPerSender ?? DEFAULT_MAX_POINTS;
|
|
8671
|
+
this.unregister = host.registerOverlay((ctx) => this.renderTrails(ctx));
|
|
8672
|
+
}
|
|
8673
|
+
now() {
|
|
8674
|
+
return performance.now();
|
|
8675
|
+
}
|
|
8676
|
+
/**
|
|
8677
|
+
* Applies a presence payload from `sender` (any opaque per-sender key, e.g.
|
|
8678
|
+
* the envelope `from`). Non-laser or malformed payloads are ignored and
|
|
8679
|
+
* reported as `false`, so hosts can feed every presence frame through.
|
|
8680
|
+
*/
|
|
8681
|
+
apply(sender, data) {
|
|
8682
|
+
if (this.disposed || !isLaserTrailPresence(data)) return false;
|
|
8683
|
+
let trail = this.trails.get(sender);
|
|
8684
|
+
if (!trail) {
|
|
8685
|
+
trail = { points: [], color: this.color, width: this.width, fadeMs: this.fadeMs };
|
|
8686
|
+
this.trails.set(sender, trail);
|
|
8687
|
+
}
|
|
8688
|
+
trail.color = data.color ?? this.color;
|
|
8689
|
+
trail.width = data.width ?? this.width;
|
|
8690
|
+
trail.fadeMs = data.fadeMs ?? this.fadeMs;
|
|
8691
|
+
const t = this.now();
|
|
8692
|
+
for (const point of data.points) {
|
|
8693
|
+
trail.points.push({ x: point.x, y: point.y, t });
|
|
8694
|
+
}
|
|
8695
|
+
const excess = trail.points.length - this.maxPointsPerSender;
|
|
8696
|
+
if (excess > 0) trail.points.splice(0, excess);
|
|
8697
|
+
this.ensureAnimating();
|
|
8698
|
+
this.host.requestRender();
|
|
8699
|
+
return true;
|
|
8700
|
+
}
|
|
8701
|
+
/** Removes a sender's trail immediately (presence-leave/disconnect). */
|
|
8702
|
+
remove(sender) {
|
|
8703
|
+
if (this.trails.delete(sender)) this.host.requestRender();
|
|
8704
|
+
}
|
|
8705
|
+
/** Removes every trail immediately. */
|
|
8706
|
+
clear() {
|
|
8707
|
+
if (this.trails.size === 0) return;
|
|
8708
|
+
this.trails.clear();
|
|
8709
|
+
this.host.requestRender();
|
|
8710
|
+
}
|
|
8711
|
+
/** Number of senders with a live (unfaded) trail. */
|
|
8712
|
+
get activeSenderCount() {
|
|
8713
|
+
return this.trails.size;
|
|
8714
|
+
}
|
|
8715
|
+
/** Unregisters the overlay and stops the fade loop. Idempotent. */
|
|
8716
|
+
dispose() {
|
|
8717
|
+
if (this.disposed) return;
|
|
8718
|
+
this.disposed = true;
|
|
8719
|
+
if (this.rafId !== null) {
|
|
8720
|
+
cancelAnimationFrame(this.rafId);
|
|
8721
|
+
this.rafId = null;
|
|
8722
|
+
}
|
|
8723
|
+
this.trails.clear();
|
|
8724
|
+
this.unregister?.();
|
|
8725
|
+
this.unregister = null;
|
|
8726
|
+
}
|
|
8727
|
+
ensureAnimating() {
|
|
8728
|
+
if (this.rafId === null) {
|
|
8729
|
+
this.rafId = requestAnimationFrame(() => this.tick());
|
|
8730
|
+
}
|
|
8731
|
+
}
|
|
8732
|
+
tick() {
|
|
8733
|
+
if (this.disposed) return;
|
|
8734
|
+
const now = this.now();
|
|
8735
|
+
for (const [sender, trail] of this.trails) {
|
|
8736
|
+
const cutoff = now - trail.fadeMs;
|
|
8737
|
+
trail.points = trail.points.filter((point) => point.t >= cutoff);
|
|
8738
|
+
if (trail.points.length === 0) this.trails.delete(sender);
|
|
8739
|
+
}
|
|
8740
|
+
this.host.requestRender();
|
|
8741
|
+
this.rafId = this.trails.size > 0 ? requestAnimationFrame(() => this.tick()) : null;
|
|
8742
|
+
}
|
|
8743
|
+
renderTrails(ctx) {
|
|
8744
|
+
if (this.trails.size === 0) return;
|
|
8745
|
+
const now = this.now();
|
|
8746
|
+
for (const trail of this.trails.values()) {
|
|
8747
|
+
if (trail.points.length < 2) continue;
|
|
8748
|
+
ctx.save();
|
|
8749
|
+
ctx.strokeStyle = trail.color;
|
|
8750
|
+
ctx.lineWidth = trail.width;
|
|
8751
|
+
ctx.lineCap = "round";
|
|
8752
|
+
ctx.lineJoin = "round";
|
|
8753
|
+
for (let i = 0; i < trail.points.length - 1; i++) {
|
|
8754
|
+
const a = trail.points[i];
|
|
8755
|
+
const b = trail.points[i + 1];
|
|
8756
|
+
if (!a || !b) continue;
|
|
8757
|
+
const age = now - b.t;
|
|
8758
|
+
ctx.globalAlpha = Math.max(0, 1 - age / trail.fadeMs);
|
|
8759
|
+
ctx.beginPath();
|
|
8760
|
+
ctx.moveTo(a.x, a.y);
|
|
8761
|
+
ctx.lineTo(b.x, b.y);
|
|
8762
|
+
ctx.stroke();
|
|
8763
|
+
}
|
|
8764
|
+
ctx.restore();
|
|
8765
|
+
}
|
|
8766
|
+
}
|
|
8767
|
+
};
|
|
8768
|
+
|
|
8579
8769
|
// src/tools/hand-tool.ts
|
|
8580
8770
|
var HandTool = class {
|
|
8581
8771
|
name = "hand";
|
|
@@ -11132,9 +11322,9 @@ var TemplateTool = class {
|
|
|
11132
11322
|
};
|
|
11133
11323
|
|
|
11134
11324
|
// src/tools/laser-tool.ts
|
|
11135
|
-
var
|
|
11136
|
-
var
|
|
11137
|
-
var
|
|
11325
|
+
var DEFAULT_COLOR2 = "#ff3b30";
|
|
11326
|
+
var DEFAULT_WIDTH2 = 4;
|
|
11327
|
+
var DEFAULT_FADE_MS2 = 1200;
|
|
11138
11328
|
var LaserTool = class {
|
|
11139
11329
|
name;
|
|
11140
11330
|
color;
|
|
@@ -11144,11 +11334,13 @@ var LaserTool = class {
|
|
|
11144
11334
|
rafId = null;
|
|
11145
11335
|
drawing = false;
|
|
11146
11336
|
optionListeners = /* @__PURE__ */ new Set();
|
|
11337
|
+
trailListeners = /* @__PURE__ */ new Set();
|
|
11338
|
+
pendingEmission = [];
|
|
11147
11339
|
constructor(options = {}) {
|
|
11148
11340
|
this.name = options.name ?? "laser";
|
|
11149
|
-
this.color = options.color ??
|
|
11150
|
-
this.width = options.width ??
|
|
11151
|
-
this.fadeMs = options.fadeMs ??
|
|
11341
|
+
this.color = options.color ?? DEFAULT_COLOR2;
|
|
11342
|
+
this.width = options.width ?? DEFAULT_WIDTH2;
|
|
11343
|
+
this.fadeMs = options.fadeMs ?? DEFAULT_FADE_MS2;
|
|
11152
11344
|
}
|
|
11153
11345
|
now() {
|
|
11154
11346
|
return performance.now();
|
|
@@ -11163,6 +11355,7 @@ var LaserTool = class {
|
|
|
11163
11355
|
}
|
|
11164
11356
|
this.trail = [];
|
|
11165
11357
|
this.drawing = false;
|
|
11358
|
+
this.pendingEmission = [];
|
|
11166
11359
|
ctx.setCursor?.("default");
|
|
11167
11360
|
ctx.requestRender();
|
|
11168
11361
|
}
|
|
@@ -11178,6 +11371,16 @@ var LaserTool = class {
|
|
|
11178
11371
|
this.optionListeners.add(listener);
|
|
11179
11372
|
return () => this.optionListeners.delete(listener);
|
|
11180
11373
|
}
|
|
11374
|
+
/**
|
|
11375
|
+
* Subscribes to coalesced trail emissions. Points recorded by pointer input
|
|
11376
|
+
* are batched and delivered at most once per animation frame, keeping
|
|
11377
|
+
* outgoing presence packets small. Listeners must not throw; a throwing
|
|
11378
|
+
* listener is isolated so it cannot stall the fade loop.
|
|
11379
|
+
*/
|
|
11380
|
+
onTrail(listener) {
|
|
11381
|
+
this.trailListeners.add(listener);
|
|
11382
|
+
return () => this.trailListeners.delete(listener);
|
|
11383
|
+
}
|
|
11181
11384
|
setOptions(options) {
|
|
11182
11385
|
if (options.color !== void 0) this.color = options.color;
|
|
11183
11386
|
if (options.width !== void 0) this.width = options.width;
|
|
@@ -11186,14 +11389,18 @@ var LaserTool = class {
|
|
|
11186
11389
|
}
|
|
11187
11390
|
onPointerDown(state, ctx) {
|
|
11188
11391
|
this.drawing = true;
|
|
11189
|
-
|
|
11190
|
-
this.trail.push({ x: world.x, y: world.y, t: this.now() });
|
|
11191
|
-
this.ensureAnimating(ctx);
|
|
11392
|
+
this.recordPoint(state, ctx);
|
|
11192
11393
|
}
|
|
11193
11394
|
onPointerMove(state, ctx) {
|
|
11194
11395
|
if (!this.drawing) return;
|
|
11396
|
+
this.recordPoint(state, ctx);
|
|
11397
|
+
}
|
|
11398
|
+
recordPoint(state, ctx) {
|
|
11195
11399
|
const world = ctx.camera.screenToWorld({ x: state.x, y: state.y });
|
|
11196
11400
|
this.trail.push({ x: world.x, y: world.y, t: this.now() });
|
|
11401
|
+
if (this.trailListeners.size > 0) {
|
|
11402
|
+
this.pendingEmission.push({ x: world.x, y: world.y });
|
|
11403
|
+
}
|
|
11197
11404
|
this.ensureAnimating(ctx);
|
|
11198
11405
|
}
|
|
11199
11406
|
onPointerUp(_state, _ctx) {
|
|
@@ -11225,7 +11432,24 @@ var LaserTool = class {
|
|
|
11225
11432
|
this.rafId = requestAnimationFrame(() => this.tick(ctx));
|
|
11226
11433
|
}
|
|
11227
11434
|
}
|
|
11435
|
+
flushEmission() {
|
|
11436
|
+
if (this.pendingEmission.length === 0) return;
|
|
11437
|
+
const emission = {
|
|
11438
|
+
points: this.pendingEmission,
|
|
11439
|
+
color: this.color,
|
|
11440
|
+
width: this.width,
|
|
11441
|
+
fadeMs: this.fadeMs
|
|
11442
|
+
};
|
|
11443
|
+
this.pendingEmission = [];
|
|
11444
|
+
for (const listener of this.trailListeners) {
|
|
11445
|
+
try {
|
|
11446
|
+
listener(emission);
|
|
11447
|
+
} catch {
|
|
11448
|
+
}
|
|
11449
|
+
}
|
|
11450
|
+
}
|
|
11228
11451
|
tick(ctx) {
|
|
11452
|
+
this.flushEmission();
|
|
11229
11453
|
const cutoff = this.now() - this.fadeMs;
|
|
11230
11454
|
this.trail = this.trail.filter((p) => p.t >= cutoff);
|
|
11231
11455
|
if (this.trail.length > 0) {
|
|
@@ -11242,7 +11466,7 @@ var LaserTool = class {
|
|
|
11242
11466
|
};
|
|
11243
11467
|
|
|
11244
11468
|
// src/index.ts
|
|
11245
|
-
var VERSION = "0.
|
|
11469
|
+
var VERSION = "0.54.0";
|
|
11246
11470
|
// Annotate the CommonJS export names for ESM import in node:
|
|
11247
11471
|
0 && (module.exports = {
|
|
11248
11472
|
ArrowTool,
|
|
@@ -11255,6 +11479,7 @@ var VERSION = "0.53.0";
|
|
|
11255
11479
|
HistoryStack,
|
|
11256
11480
|
ImageTool,
|
|
11257
11481
|
IndexedDBAdapter,
|
|
11482
|
+
LASER_TRAIL_PRESENCE_KIND,
|
|
11258
11483
|
LaserTool,
|
|
11259
11484
|
LayerManager,
|
|
11260
11485
|
LocalStorageAdapter,
|
|
@@ -11262,6 +11487,7 @@ var VERSION = "0.53.0";
|
|
|
11262
11487
|
MemoryAdapter,
|
|
11263
11488
|
NoteTool,
|
|
11264
11489
|
PencilTool,
|
|
11490
|
+
RemoteLaserOverlay,
|
|
11265
11491
|
SelectTool,
|
|
11266
11492
|
ShapeTool,
|
|
11267
11493
|
TemplateTool,
|
|
@@ -11297,12 +11523,14 @@ var VERSION = "0.53.0";
|
|
|
11297
11523
|
getHexCellsInRectangle,
|
|
11298
11524
|
getHexCellsInSquare,
|
|
11299
11525
|
getHexDistance,
|
|
11526
|
+
isLaserTrailPresence,
|
|
11300
11527
|
isNearBezier,
|
|
11301
11528
|
setFontSize,
|
|
11302
11529
|
smartSnap,
|
|
11303
11530
|
snapPoint,
|
|
11304
11531
|
snapToHexCenter,
|
|
11305
11532
|
styleToPatch,
|
|
11533
|
+
toLaserTrailPresence,
|
|
11306
11534
|
toggleBold,
|
|
11307
11535
|
toggleItalic,
|
|
11308
11536
|
toggleStrikethrough,
|