@fieldnotes/core 0.52.2 → 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 +273 -15
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +157 -33
- package/dist/index.d.ts +157 -33
- package/dist/index.js +269 -15
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -6835,6 +6835,7 @@ var RenderLoop = class {
|
|
|
6835
6835
|
// set on recenter/viewport-change; consumed by the grid block
|
|
6836
6836
|
stats = new RenderStats();
|
|
6837
6837
|
layerGroups = /* @__PURE__ */ new Map();
|
|
6838
|
+
overlays = /* @__PURE__ */ new Set();
|
|
6838
6839
|
gridCacheCanvas = null;
|
|
6839
6840
|
gridCacheCtx = null;
|
|
6840
6841
|
lastGridRefs = [];
|
|
@@ -6893,6 +6894,29 @@ var RenderLoop = class {
|
|
|
6893
6894
|
getStats() {
|
|
6894
6895
|
return this.stats.getSnapshot();
|
|
6895
6896
|
}
|
|
6897
|
+
/**
|
|
6898
|
+
* Registers a viewport overlay drawn beneath the active tool's own overlay.
|
|
6899
|
+
* Returns an idempotent unsubscribe that also erases the overlay's last
|
|
6900
|
+
* frame.
|
|
6901
|
+
*/
|
|
6902
|
+
registerOverlay(draw) {
|
|
6903
|
+
this.overlays.add(draw);
|
|
6904
|
+
this.requestRender();
|
|
6905
|
+
return () => {
|
|
6906
|
+
if (this.overlays.delete(draw)) this.requestRender();
|
|
6907
|
+
};
|
|
6908
|
+
}
|
|
6909
|
+
drawRegisteredOverlays(ctx) {
|
|
6910
|
+
for (const draw of this.overlays) {
|
|
6911
|
+
ctx.save();
|
|
6912
|
+
try {
|
|
6913
|
+
draw(ctx);
|
|
6914
|
+
} catch {
|
|
6915
|
+
} finally {
|
|
6916
|
+
ctx.restore();
|
|
6917
|
+
}
|
|
6918
|
+
}
|
|
6919
|
+
}
|
|
6896
6920
|
compositeLayerCache(ctx, layerId, opacity) {
|
|
6897
6921
|
const cached = this.layerCache.getCanvas(layerId);
|
|
6898
6922
|
const offset = this.marginViewport.compositeOffset(
|
|
@@ -7026,7 +7050,8 @@ var RenderLoop = class {
|
|
|
7026
7050
|
}
|
|
7027
7051
|
const activeTool = this.toolManager.activeTool;
|
|
7028
7052
|
const overlayOrder = visibleElements.length + 1;
|
|
7029
|
-
|
|
7053
|
+
const hasOverlay = activeTool?.renderOverlay !== void 0 || this.overlays.size > 0;
|
|
7054
|
+
if (hybridActive && hasOverlay) hybridOrders.add(overlayOrder);
|
|
7030
7055
|
this.hybridSurface.beginFrame(hybridOrders, this.canvasEl.width, this.canvasEl.height);
|
|
7031
7056
|
for (const [layerId, elements] of this.layerGroups) {
|
|
7032
7057
|
const isActiveDrawingLayer = layerId === this.activeDrawingLayerId;
|
|
@@ -7136,7 +7161,7 @@ var RenderLoop = class {
|
|
|
7136
7161
|
hybridCtx.restore();
|
|
7137
7162
|
}
|
|
7138
7163
|
const overlayT0 = performance.now();
|
|
7139
|
-
if (hybridActive &&
|
|
7164
|
+
if (hybridActive && hasOverlay) {
|
|
7140
7165
|
const overlayCtx = this.hybridSurface.getContext(overlayOrder);
|
|
7141
7166
|
if (overlayCtx) {
|
|
7142
7167
|
overlayCtx.clearRect(0, 0, this.canvasEl.width, this.canvasEl.height);
|
|
@@ -7144,11 +7169,13 @@ var RenderLoop = class {
|
|
|
7144
7169
|
overlayCtx.scale(dpr, dpr);
|
|
7145
7170
|
overlayCtx.translate(this.camera.position.x, this.camera.position.y);
|
|
7146
7171
|
overlayCtx.scale(this.camera.zoom, this.camera.zoom);
|
|
7147
|
-
|
|
7172
|
+
this.drawRegisteredOverlays(overlayCtx);
|
|
7173
|
+
if (activeTool?.renderOverlay) activeTool.renderOverlay(overlayCtx);
|
|
7148
7174
|
overlayCtx.restore();
|
|
7149
7175
|
}
|
|
7150
|
-
} else if (
|
|
7151
|
-
|
|
7176
|
+
} else if (hasOverlay) {
|
|
7177
|
+
this.drawRegisteredOverlays(ctx);
|
|
7178
|
+
if (activeTool?.renderOverlay) activeTool.renderOverlay(ctx);
|
|
7152
7179
|
}
|
|
7153
7180
|
const overlayMs = performance.now() - overlayT0;
|
|
7154
7181
|
ctx.restore();
|
|
@@ -8097,6 +8124,7 @@ var Viewport = class {
|
|
|
8097
8124
|
noteEditor;
|
|
8098
8125
|
arrowLabelEditor;
|
|
8099
8126
|
historyRecorder;
|
|
8127
|
+
transactionDepth = 0;
|
|
8100
8128
|
selectionOps;
|
|
8101
8129
|
toolContext;
|
|
8102
8130
|
marginViewport;
|
|
@@ -8141,6 +8169,17 @@ var Viewport = class {
|
|
|
8141
8169
|
requestRender() {
|
|
8142
8170
|
this.renderLoop.requestRender();
|
|
8143
8171
|
}
|
|
8172
|
+
/**
|
|
8173
|
+
* Registers a world-space overlay drawn above elements on every frame,
|
|
8174
|
+
* regardless of the active tool — the surface for remote presence visuals
|
|
8175
|
+
* such as laser trails, cursors, pings, and shared rulers. Overlays draw
|
|
8176
|
+
* beneath the active tool's own `renderOverlay` and never touch elements,
|
|
8177
|
+
* history, or persisted state. Returns an idempotent unsubscribe that also
|
|
8178
|
+
* erases the overlay's last frame.
|
|
8179
|
+
*/
|
|
8180
|
+
registerOverlay(draw) {
|
|
8181
|
+
return this.renderLoop.registerOverlay(draw);
|
|
8182
|
+
}
|
|
8144
8183
|
exportState() {
|
|
8145
8184
|
return exportState(
|
|
8146
8185
|
this.store.snapshot(),
|
|
@@ -8210,6 +8249,35 @@ var Viewport = class {
|
|
|
8210
8249
|
get shortcuts() {
|
|
8211
8250
|
return this.inputHandler.shortcuts;
|
|
8212
8251
|
}
|
|
8252
|
+
/**
|
|
8253
|
+
* Groups synchronous local store and layer mutations into one undo step.
|
|
8254
|
+
* Nested calls join the outer transaction. If the callback throws, mutations
|
|
8255
|
+
* already applied remain undoable and the original error is rethrown.
|
|
8256
|
+
*/
|
|
8257
|
+
transaction(operation) {
|
|
8258
|
+
const isOuterTransaction = this.transactionDepth === 0;
|
|
8259
|
+
if (isOuterTransaction) {
|
|
8260
|
+
this.inputHandler.flushPendingHistory();
|
|
8261
|
+
this.historyRecorder.begin();
|
|
8262
|
+
}
|
|
8263
|
+
this.transactionDepth += 1;
|
|
8264
|
+
try {
|
|
8265
|
+
return operation();
|
|
8266
|
+
} finally {
|
|
8267
|
+
this.transactionDepth -= 1;
|
|
8268
|
+
if (isOuterTransaction) this.historyRecorder.commit();
|
|
8269
|
+
}
|
|
8270
|
+
}
|
|
8271
|
+
/** Removes existing elements as one undoable operation and returns the number removed. */
|
|
8272
|
+
removeElements(ids) {
|
|
8273
|
+
const existingIds = [...new Set(ids)].filter((id) => this.store.getById(id) !== void 0);
|
|
8274
|
+
if (existingIds.length === 0) return 0;
|
|
8275
|
+
this.transaction(() => {
|
|
8276
|
+
for (const id of existingIds) this.store.remove(id);
|
|
8277
|
+
});
|
|
8278
|
+
this.requestRender();
|
|
8279
|
+
return existingIds.length;
|
|
8280
|
+
}
|
|
8213
8281
|
undo() {
|
|
8214
8282
|
this.inputHandler.flushPendingHistory();
|
|
8215
8283
|
this.historyRecorder.pause();
|
|
@@ -8459,6 +8527,154 @@ var Viewport = class {
|
|
|
8459
8527
|
}
|
|
8460
8528
|
};
|
|
8461
8529
|
|
|
8530
|
+
// src/canvas/remote-laser-overlay.ts
|
|
8531
|
+
var LASER_TRAIL_PRESENCE_KIND = "laser";
|
|
8532
|
+
function isFinitePoint(value) {
|
|
8533
|
+
if (typeof value !== "object" || value === null) return false;
|
|
8534
|
+
const point = value;
|
|
8535
|
+
return typeof point.x === "number" && Number.isFinite(point.x) && typeof point.y === "number" && Number.isFinite(point.y);
|
|
8536
|
+
}
|
|
8537
|
+
function isLaserTrailPresence(data) {
|
|
8538
|
+
if (typeof data !== "object" || data === null) return false;
|
|
8539
|
+
const payload = data;
|
|
8540
|
+
if (payload.kind !== LASER_TRAIL_PRESENCE_KIND) return false;
|
|
8541
|
+
if (!Array.isArray(payload.points) || !payload.points.every(isFinitePoint)) return false;
|
|
8542
|
+
if (payload.color !== void 0 && typeof payload.color !== "string") return false;
|
|
8543
|
+
if (payload.width !== void 0 && !(typeof payload.width === "number" && payload.width > 0)) {
|
|
8544
|
+
return false;
|
|
8545
|
+
}
|
|
8546
|
+
if (payload.fadeMs !== void 0 && !(typeof payload.fadeMs === "number" && payload.fadeMs > 0)) {
|
|
8547
|
+
return false;
|
|
8548
|
+
}
|
|
8549
|
+
return true;
|
|
8550
|
+
}
|
|
8551
|
+
function toLaserTrailPresence(emission) {
|
|
8552
|
+
return {
|
|
8553
|
+
kind: LASER_TRAIL_PRESENCE_KIND,
|
|
8554
|
+
points: emission.points.map((point) => ({ x: point.x, y: point.y })),
|
|
8555
|
+
color: emission.color,
|
|
8556
|
+
width: emission.width,
|
|
8557
|
+
fadeMs: emission.fadeMs
|
|
8558
|
+
};
|
|
8559
|
+
}
|
|
8560
|
+
var DEFAULT_COLOR = "#ff3b30";
|
|
8561
|
+
var DEFAULT_WIDTH = 4;
|
|
8562
|
+
var DEFAULT_FADE_MS = 1200;
|
|
8563
|
+
var DEFAULT_MAX_POINTS = 512;
|
|
8564
|
+
var RemoteLaserOverlay = class {
|
|
8565
|
+
host;
|
|
8566
|
+
color;
|
|
8567
|
+
width;
|
|
8568
|
+
fadeMs;
|
|
8569
|
+
maxPointsPerSender;
|
|
8570
|
+
trails = /* @__PURE__ */ new Map();
|
|
8571
|
+
unregister;
|
|
8572
|
+
rafId = null;
|
|
8573
|
+
disposed = false;
|
|
8574
|
+
constructor(host, options = {}) {
|
|
8575
|
+
this.host = host;
|
|
8576
|
+
this.color = options.color ?? DEFAULT_COLOR;
|
|
8577
|
+
this.width = options.width ?? DEFAULT_WIDTH;
|
|
8578
|
+
this.fadeMs = options.fadeMs ?? DEFAULT_FADE_MS;
|
|
8579
|
+
this.maxPointsPerSender = options.maxPointsPerSender ?? DEFAULT_MAX_POINTS;
|
|
8580
|
+
this.unregister = host.registerOverlay((ctx) => this.renderTrails(ctx));
|
|
8581
|
+
}
|
|
8582
|
+
now() {
|
|
8583
|
+
return performance.now();
|
|
8584
|
+
}
|
|
8585
|
+
/**
|
|
8586
|
+
* Applies a presence payload from `sender` (any opaque per-sender key, e.g.
|
|
8587
|
+
* the envelope `from`). Non-laser or malformed payloads are ignored and
|
|
8588
|
+
* reported as `false`, so hosts can feed every presence frame through.
|
|
8589
|
+
*/
|
|
8590
|
+
apply(sender, data) {
|
|
8591
|
+
if (this.disposed || !isLaserTrailPresence(data)) return false;
|
|
8592
|
+
let trail = this.trails.get(sender);
|
|
8593
|
+
if (!trail) {
|
|
8594
|
+
trail = { points: [], color: this.color, width: this.width, fadeMs: this.fadeMs };
|
|
8595
|
+
this.trails.set(sender, trail);
|
|
8596
|
+
}
|
|
8597
|
+
trail.color = data.color ?? this.color;
|
|
8598
|
+
trail.width = data.width ?? this.width;
|
|
8599
|
+
trail.fadeMs = data.fadeMs ?? this.fadeMs;
|
|
8600
|
+
const t = this.now();
|
|
8601
|
+
for (const point of data.points) {
|
|
8602
|
+
trail.points.push({ x: point.x, y: point.y, t });
|
|
8603
|
+
}
|
|
8604
|
+
const excess = trail.points.length - this.maxPointsPerSender;
|
|
8605
|
+
if (excess > 0) trail.points.splice(0, excess);
|
|
8606
|
+
this.ensureAnimating();
|
|
8607
|
+
this.host.requestRender();
|
|
8608
|
+
return true;
|
|
8609
|
+
}
|
|
8610
|
+
/** Removes a sender's trail immediately (presence-leave/disconnect). */
|
|
8611
|
+
remove(sender) {
|
|
8612
|
+
if (this.trails.delete(sender)) this.host.requestRender();
|
|
8613
|
+
}
|
|
8614
|
+
/** Removes every trail immediately. */
|
|
8615
|
+
clear() {
|
|
8616
|
+
if (this.trails.size === 0) return;
|
|
8617
|
+
this.trails.clear();
|
|
8618
|
+
this.host.requestRender();
|
|
8619
|
+
}
|
|
8620
|
+
/** Number of senders with a live (unfaded) trail. */
|
|
8621
|
+
get activeSenderCount() {
|
|
8622
|
+
return this.trails.size;
|
|
8623
|
+
}
|
|
8624
|
+
/** Unregisters the overlay and stops the fade loop. Idempotent. */
|
|
8625
|
+
dispose() {
|
|
8626
|
+
if (this.disposed) return;
|
|
8627
|
+
this.disposed = true;
|
|
8628
|
+
if (this.rafId !== null) {
|
|
8629
|
+
cancelAnimationFrame(this.rafId);
|
|
8630
|
+
this.rafId = null;
|
|
8631
|
+
}
|
|
8632
|
+
this.trails.clear();
|
|
8633
|
+
this.unregister?.();
|
|
8634
|
+
this.unregister = null;
|
|
8635
|
+
}
|
|
8636
|
+
ensureAnimating() {
|
|
8637
|
+
if (this.rafId === null) {
|
|
8638
|
+
this.rafId = requestAnimationFrame(() => this.tick());
|
|
8639
|
+
}
|
|
8640
|
+
}
|
|
8641
|
+
tick() {
|
|
8642
|
+
if (this.disposed) return;
|
|
8643
|
+
const now = this.now();
|
|
8644
|
+
for (const [sender, trail] of this.trails) {
|
|
8645
|
+
const cutoff = now - trail.fadeMs;
|
|
8646
|
+
trail.points = trail.points.filter((point) => point.t >= cutoff);
|
|
8647
|
+
if (trail.points.length === 0) this.trails.delete(sender);
|
|
8648
|
+
}
|
|
8649
|
+
this.host.requestRender();
|
|
8650
|
+
this.rafId = this.trails.size > 0 ? requestAnimationFrame(() => this.tick()) : null;
|
|
8651
|
+
}
|
|
8652
|
+
renderTrails(ctx) {
|
|
8653
|
+
if (this.trails.size === 0) return;
|
|
8654
|
+
const now = this.now();
|
|
8655
|
+
for (const trail of this.trails.values()) {
|
|
8656
|
+
if (trail.points.length < 2) continue;
|
|
8657
|
+
ctx.save();
|
|
8658
|
+
ctx.strokeStyle = trail.color;
|
|
8659
|
+
ctx.lineWidth = trail.width;
|
|
8660
|
+
ctx.lineCap = "round";
|
|
8661
|
+
ctx.lineJoin = "round";
|
|
8662
|
+
for (let i = 0; i < trail.points.length - 1; i++) {
|
|
8663
|
+
const a = trail.points[i];
|
|
8664
|
+
const b = trail.points[i + 1];
|
|
8665
|
+
if (!a || !b) continue;
|
|
8666
|
+
const age = now - b.t;
|
|
8667
|
+
ctx.globalAlpha = Math.max(0, 1 - age / trail.fadeMs);
|
|
8668
|
+
ctx.beginPath();
|
|
8669
|
+
ctx.moveTo(a.x, a.y);
|
|
8670
|
+
ctx.lineTo(b.x, b.y);
|
|
8671
|
+
ctx.stroke();
|
|
8672
|
+
}
|
|
8673
|
+
ctx.restore();
|
|
8674
|
+
}
|
|
8675
|
+
}
|
|
8676
|
+
};
|
|
8677
|
+
|
|
8462
8678
|
// src/tools/hand-tool.ts
|
|
8463
8679
|
var HandTool = class {
|
|
8464
8680
|
name = "hand";
|
|
@@ -11015,9 +11231,9 @@ var TemplateTool = class {
|
|
|
11015
11231
|
};
|
|
11016
11232
|
|
|
11017
11233
|
// src/tools/laser-tool.ts
|
|
11018
|
-
var
|
|
11019
|
-
var
|
|
11020
|
-
var
|
|
11234
|
+
var DEFAULT_COLOR2 = "#ff3b30";
|
|
11235
|
+
var DEFAULT_WIDTH2 = 4;
|
|
11236
|
+
var DEFAULT_FADE_MS2 = 1200;
|
|
11021
11237
|
var LaserTool = class {
|
|
11022
11238
|
name;
|
|
11023
11239
|
color;
|
|
@@ -11027,11 +11243,13 @@ var LaserTool = class {
|
|
|
11027
11243
|
rafId = null;
|
|
11028
11244
|
drawing = false;
|
|
11029
11245
|
optionListeners = /* @__PURE__ */ new Set();
|
|
11246
|
+
trailListeners = /* @__PURE__ */ new Set();
|
|
11247
|
+
pendingEmission = [];
|
|
11030
11248
|
constructor(options = {}) {
|
|
11031
11249
|
this.name = options.name ?? "laser";
|
|
11032
|
-
this.color = options.color ??
|
|
11033
|
-
this.width = options.width ??
|
|
11034
|
-
this.fadeMs = options.fadeMs ??
|
|
11250
|
+
this.color = options.color ?? DEFAULT_COLOR2;
|
|
11251
|
+
this.width = options.width ?? DEFAULT_WIDTH2;
|
|
11252
|
+
this.fadeMs = options.fadeMs ?? DEFAULT_FADE_MS2;
|
|
11035
11253
|
}
|
|
11036
11254
|
now() {
|
|
11037
11255
|
return performance.now();
|
|
@@ -11046,6 +11264,7 @@ var LaserTool = class {
|
|
|
11046
11264
|
}
|
|
11047
11265
|
this.trail = [];
|
|
11048
11266
|
this.drawing = false;
|
|
11267
|
+
this.pendingEmission = [];
|
|
11049
11268
|
ctx.setCursor?.("default");
|
|
11050
11269
|
ctx.requestRender();
|
|
11051
11270
|
}
|
|
@@ -11061,6 +11280,16 @@ var LaserTool = class {
|
|
|
11061
11280
|
this.optionListeners.add(listener);
|
|
11062
11281
|
return () => this.optionListeners.delete(listener);
|
|
11063
11282
|
}
|
|
11283
|
+
/**
|
|
11284
|
+
* Subscribes to coalesced trail emissions. Points recorded by pointer input
|
|
11285
|
+
* are batched and delivered at most once per animation frame, keeping
|
|
11286
|
+
* outgoing presence packets small. Listeners must not throw; a throwing
|
|
11287
|
+
* listener is isolated so it cannot stall the fade loop.
|
|
11288
|
+
*/
|
|
11289
|
+
onTrail(listener) {
|
|
11290
|
+
this.trailListeners.add(listener);
|
|
11291
|
+
return () => this.trailListeners.delete(listener);
|
|
11292
|
+
}
|
|
11064
11293
|
setOptions(options) {
|
|
11065
11294
|
if (options.color !== void 0) this.color = options.color;
|
|
11066
11295
|
if (options.width !== void 0) this.width = options.width;
|
|
@@ -11069,14 +11298,18 @@ var LaserTool = class {
|
|
|
11069
11298
|
}
|
|
11070
11299
|
onPointerDown(state, ctx) {
|
|
11071
11300
|
this.drawing = true;
|
|
11072
|
-
|
|
11073
|
-
this.trail.push({ x: world.x, y: world.y, t: this.now() });
|
|
11074
|
-
this.ensureAnimating(ctx);
|
|
11301
|
+
this.recordPoint(state, ctx);
|
|
11075
11302
|
}
|
|
11076
11303
|
onPointerMove(state, ctx) {
|
|
11077
11304
|
if (!this.drawing) return;
|
|
11305
|
+
this.recordPoint(state, ctx);
|
|
11306
|
+
}
|
|
11307
|
+
recordPoint(state, ctx) {
|
|
11078
11308
|
const world = ctx.camera.screenToWorld({ x: state.x, y: state.y });
|
|
11079
11309
|
this.trail.push({ x: world.x, y: world.y, t: this.now() });
|
|
11310
|
+
if (this.trailListeners.size > 0) {
|
|
11311
|
+
this.pendingEmission.push({ x: world.x, y: world.y });
|
|
11312
|
+
}
|
|
11080
11313
|
this.ensureAnimating(ctx);
|
|
11081
11314
|
}
|
|
11082
11315
|
onPointerUp(_state, _ctx) {
|
|
@@ -11108,7 +11341,24 @@ var LaserTool = class {
|
|
|
11108
11341
|
this.rafId = requestAnimationFrame(() => this.tick(ctx));
|
|
11109
11342
|
}
|
|
11110
11343
|
}
|
|
11344
|
+
flushEmission() {
|
|
11345
|
+
if (this.pendingEmission.length === 0) return;
|
|
11346
|
+
const emission = {
|
|
11347
|
+
points: this.pendingEmission,
|
|
11348
|
+
color: this.color,
|
|
11349
|
+
width: this.width,
|
|
11350
|
+
fadeMs: this.fadeMs
|
|
11351
|
+
};
|
|
11352
|
+
this.pendingEmission = [];
|
|
11353
|
+
for (const listener of this.trailListeners) {
|
|
11354
|
+
try {
|
|
11355
|
+
listener(emission);
|
|
11356
|
+
} catch {
|
|
11357
|
+
}
|
|
11358
|
+
}
|
|
11359
|
+
}
|
|
11111
11360
|
tick(ctx) {
|
|
11361
|
+
this.flushEmission();
|
|
11112
11362
|
const cutoff = this.now() - this.fadeMs;
|
|
11113
11363
|
this.trail = this.trail.filter((p) => p.t >= cutoff);
|
|
11114
11364
|
if (this.trail.length > 0) {
|
|
@@ -11125,7 +11375,7 @@ var LaserTool = class {
|
|
|
11125
11375
|
};
|
|
11126
11376
|
|
|
11127
11377
|
// src/index.ts
|
|
11128
|
-
var VERSION = "0.
|
|
11378
|
+
var VERSION = "0.54.0";
|
|
11129
11379
|
export {
|
|
11130
11380
|
ArrowTool,
|
|
11131
11381
|
AutoSave,
|
|
@@ -11137,6 +11387,7 @@ export {
|
|
|
11137
11387
|
HistoryStack,
|
|
11138
11388
|
ImageTool,
|
|
11139
11389
|
IndexedDBAdapter,
|
|
11390
|
+
LASER_TRAIL_PRESENCE_KIND,
|
|
11140
11391
|
LaserTool,
|
|
11141
11392
|
LayerManager,
|
|
11142
11393
|
LocalStorageAdapter,
|
|
@@ -11144,6 +11395,7 @@ export {
|
|
|
11144
11395
|
MemoryAdapter,
|
|
11145
11396
|
NoteTool,
|
|
11146
11397
|
PencilTool,
|
|
11398
|
+
RemoteLaserOverlay,
|
|
11147
11399
|
SelectTool,
|
|
11148
11400
|
ShapeTool,
|
|
11149
11401
|
TemplateTool,
|
|
@@ -11179,12 +11431,14 @@ export {
|
|
|
11179
11431
|
getHexCellsInRectangle,
|
|
11180
11432
|
getHexCellsInSquare,
|
|
11181
11433
|
getHexDistance,
|
|
11434
|
+
isLaserTrailPresence,
|
|
11182
11435
|
isNearBezier,
|
|
11183
11436
|
setFontSize,
|
|
11184
11437
|
smartSnap,
|
|
11185
11438
|
snapPoint,
|
|
11186
11439
|
snapToHexCenter,
|
|
11187
11440
|
styleToPatch,
|
|
11441
|
+
toLaserTrailPresence,
|
|
11188
11442
|
toggleBold,
|
|
11189
11443
|
toggleItalic,
|
|
11190
11444
|
toggleStrikethrough,
|