From be9bde3b508cf59f7eceaca85f26ea661634347b Mon Sep 17 00:00:00 2001 From: jon-dez <48642222+jon-dez@users.noreply.github.com> Date: Mon, 18 Nov 2024 21:29:56 -0500 Subject: [PATCH] Update tldraw package to 3.4.1 --- manifest.json | 2 +- package-lock.json | 97 +- package.json | 2 +- patches/@tldraw+editor+3.2.0.patch | 31218 --------------------------- patches/@tldraw+editor+3.4.1.patch | 174 + patches/tldraw+3.2.0.patch | 760 - patches/tldraw+3.4.1.patch | 503 + src/utils/constants.ts | 2 +- 8 files changed, 729 insertions(+), 32029 deletions(-) delete mode 100644 patches/@tldraw+editor+3.2.0.patch create mode 100644 patches/@tldraw+editor+3.4.1.patch delete mode 100644 patches/tldraw+3.2.0.patch create mode 100644 patches/tldraw+3.4.1.patch diff --git a/manifest.json b/manifest.json index c2504b6..a1a4b06 100644 --- a/manifest.json +++ b/manifest.json @@ -1,7 +1,7 @@ { "id": "tldraw", "name": "Tldraw", - "version": "1.14.1", + "version": "1.15.0", "minAppVersion": "0.15.0", "description": "Integrates Tldraw into Obsidian, allowing users to draw and edit content on a virtual whiteboard.", "author": "Sam Alhaqab", diff --git a/package-lock.json b/package-lock.json index 7c09671..965a432 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,7 +13,7 @@ "patch-package": "^8.0.0", "react": "^18.3.1", "react-dom": "^18.3.1", - "tldraw": "^3.2.0", + "tldraw": "^3.4.1", "use-debounce": "^9.0.4", "zustand": "^4.3.9" }, @@ -2008,23 +2008,24 @@ "integrity": "sha512-A9+lCBZoaMJlVKcRBz2YByCG+Cp2t6nAnMnNba+XiWxnj6r4JUFqfsgwocMBZU9LPtdxC6wB56ySYpc7LQIoJg==" }, "node_modules/@tldraw/editor": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/@tldraw/editor/-/editor-3.2.0.tgz", - "integrity": "sha512-2HAIAh4qw7g5varnnxzJVyVjS4AzcbzY8ZegqFETQxBxxprGrxRXKf+kYxhA4ac5XAyAt5UV52b+qQ6tvpKHuw==", - "dependencies": { - "@tldraw/state": "3.2.0", - "@tldraw/state-react": "3.2.0", - "@tldraw/store": "3.2.0", - "@tldraw/tlschema": "3.2.0", - "@tldraw/utils": "3.2.0", - "@tldraw/validate": "3.2.0", + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/@tldraw/editor/-/editor-3.4.1.tgz", + "integrity": "sha512-LYa02QbwVgCrNmW79jDxijaYjly/TqvuMm8BwIlHwAU9sId8mkkqzICFqZbfc8YIWTDFQppQtQjVlRZR/0YWkQ==", + "dependencies": { + "@tldraw/state": "3.4.1", + "@tldraw/state-react": "3.4.1", + "@tldraw/store": "3.4.1", + "@tldraw/tlschema": "3.4.1", + "@tldraw/utils": "3.4.1", + "@tldraw/validate": "3.4.1", "@types/core-js": "^2.5.5", "@use-gesture/react": "^10.2.27", "classnames": "^2.3.2", "core-js": "^3.31.1", "eventemitter3": "^4.0.7", "idb": "^7.1.1", - "is-plain-object": "^5.0.0" + "is-plain-object": "^5.0.0", + "lodash.isequal": "^4.5.0" }, "peerDependencies": { "react": "^18.2.0", @@ -2032,20 +2033,20 @@ } }, "node_modules/@tldraw/state": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/@tldraw/state/-/state-3.2.0.tgz", - "integrity": "sha512-JGXkrmbq+ffyEVsstvxljEhubTxDDVoXU+xk/wlsD0/ug/UMxynGyIkfUmsn18rc8l6aM14SeThg1knKB2K/uQ==", + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/@tldraw/state/-/state-3.4.1.tgz", + "integrity": "sha512-IviSzQcSgG/dtyDNyIhhuLhmAQSjUf7B/ou99q3Rd//x1Z6FsAxWM4r64Egp62LWpEmUUaFBJMFt8BXHewBHVg==", "dependencies": { - "@tldraw/utils": "3.2.0" + "@tldraw/utils": "3.4.1" } }, "node_modules/@tldraw/state-react": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/@tldraw/state-react/-/state-react-3.2.0.tgz", - "integrity": "sha512-OTc8J9G8+8R/1MhaBkEM9PGt6g9QRD1ExGiL7+bZiNkz3mGMvgKTBjcUKkVE8JT9bd1myQDWI4MHmFSXWD17+w==", + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/@tldraw/state-react/-/state-react-3.4.1.tgz", + "integrity": "sha512-w1qUpejI4zmfshnb8RBfCbMrHD6rUQ1HXEpPHfSz4Jd5QqYW6Tlhm0nSCap0iUjRWQf4N6DvKzPcv53MI+KbTA==", "dependencies": { - "@tldraw/state": "3.2.0", - "@tldraw/utils": "3.2.0" + "@tldraw/state": "3.4.1", + "@tldraw/utils": "3.4.1" }, "peerDependencies": { "react": "^18.2.0", @@ -2053,12 +2054,12 @@ } }, "node_modules/@tldraw/store": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/@tldraw/store/-/store-3.2.0.tgz", - "integrity": "sha512-kS66jGzZw28qARnWqGoj446Wzrxhzh6tq+YZakXNmO5FxegghstpGLkitoFkOlpSPUqAIqlvbiy6S2RjzuB43A==", + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/@tldraw/store/-/store-3.4.1.tgz", + "integrity": "sha512-Jaq/6Nh8HOkH/GtJXlN7y1QSvcrO9+OkVrrJ6zeKZ5ESuJPu8lFVI6rGvt9fkLyKuNv7/lTH6nNNeY/Rek9LZg==", "dependencies": { - "@tldraw/state": "3.2.0", - "@tldraw/utils": "3.2.0", + "@tldraw/state": "3.4.1", + "@tldraw/utils": "3.4.1", "lodash.isequal": "^4.5.0" }, "peerDependencies": { @@ -2066,23 +2067,23 @@ } }, "node_modules/@tldraw/tlschema": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/@tldraw/tlschema/-/tlschema-3.2.0.tgz", - "integrity": "sha512-cG+EiuFRk074KW4RDLQNHPn3PU8sVjwmx9kthl58fkVYEssqHPxnFUcz1EOFGs7HvSXMRXJD3758CVtKB4WZug==", + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/@tldraw/tlschema/-/tlschema-3.4.1.tgz", + "integrity": "sha512-OE2GaK3UbtvPpIuPKuuLEp1wZdTgyEazYS16Whb84yi7670wh79qpNjC8701c79qXyxjmx8o8PN8bLkFh4hV2w==", "dependencies": { - "@tldraw/state": "3.2.0", - "@tldraw/store": "3.2.0", - "@tldraw/utils": "3.2.0", - "@tldraw/validate": "3.2.0" + "@tldraw/state": "3.4.1", + "@tldraw/store": "3.4.1", + "@tldraw/utils": "3.4.1", + "@tldraw/validate": "3.4.1" }, "peerDependencies": { "react": "^18.2.0" } }, "node_modules/@tldraw/utils": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/@tldraw/utils/-/utils-3.2.0.tgz", - "integrity": "sha512-YXDFYfN0zIFDi+zq8UUQizFqBIvl072hKX4c04K0jDn6K7Ox9G9tmMwbA3RyFHvzfHYGV8IEY/pLEjHCH/SRoQ==", + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/@tldraw/utils/-/utils-3.4.1.tgz", + "integrity": "sha512-9xulZB3jNwzV8yKVABEQ1iFV9uG4rqZblVeEX3EOZUF81/neZxsKxqPpYj3ExRurAtAxvJ12MVFSiMah7HNkZA==", "dependencies": { "fractional-indexing-jittered": "^0.9.1", "lodash.throttle": "^4.1.1", @@ -2090,11 +2091,11 @@ } }, "node_modules/@tldraw/validate": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/@tldraw/validate/-/validate-3.2.0.tgz", - "integrity": "sha512-UFt5P5kiAYoL6bX+pq2WGxfMj+ntBpLEmZhIjAa9kscAF5rDKVFrWl5BRn7Dy39+mx/+DEy/348kxgu/55lA6Q==", + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/@tldraw/validate/-/validate-3.4.1.tgz", + "integrity": "sha512-W2yOYnhi30EPOkBWKWNh0Bo44qbZ3DVkD4fI7YAFMKM/bjTYAuwK1o4TQYQ3QVRGkfngAcrG7xz3V/0IZRt6dA==", "dependencies": { - "@tldraw/utils": "3.2.0" + "@tldraw/utils": "3.4.1" } }, "node_modules/@types/codemirror": { @@ -2601,9 +2602,9 @@ "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" }, "node_modules/core-js": { - "version": "3.38.1", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.38.1.tgz", - "integrity": "sha512-OP35aUorbU3Zvlx7pjsFdu1rGNnD4pgw/CWoYzRY3t2EzoVT7shKHY1dlAy3f41cGIO7ZDPQimhGFTlEYkG/Hw==", + "version": "3.39.0", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.39.0.tgz", + "integrity": "sha512-raM0ew0/jJUqkJ0E6e8UDtl+y/7ktFivgWvqw8dNSQeNWoSDLvQ1H/RN3aPXB9tBd4/FhyR4RDPGhsNIMsAn7g==", "hasInstallScript": true, "funding": { "type": "opencollective", @@ -4005,9 +4006,9 @@ "peer": true }, "node_modules/tldraw": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/tldraw/-/tldraw-3.2.0.tgz", - "integrity": "sha512-bu5vByx5g6JtBht7cYvOiv42W5uFcNCr8lCZxqIgORMCkg8EoWxDnxbkah2ZNJzG+cOkm/0G9JJlDfdKyaLy0A==", + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/tldraw/-/tldraw-3.4.1.tgz", + "integrity": "sha512-V8oMcNqNx+aI7TG/oVeBL2RyH+wB66sfjqegW/a+Vx4PrvANsQqz/adU/WckBWqaU6JctpN/N5V14yXBnrKh7A==", "dependencies": { "@radix-ui/react-alert-dialog": "^1.0.5", "@radix-ui/react-context-menu": "^2.1.5", @@ -4017,8 +4018,8 @@ "@radix-ui/react-select": "^1.2.0", "@radix-ui/react-slider": "^1.1.0", "@radix-ui/react-toast": "^1.1.1", - "@tldraw/editor": "3.2.0", - "@tldraw/store": "3.2.0", + "@tldraw/editor": "3.4.1", + "@tldraw/store": "3.4.1", "canvas-size": "^1.2.6", "classnames": "^2.3.2", "hotkeys-js": "^3.11.2", diff --git a/package.json b/package.json index a380086..1bfeead 100644 --- a/package.json +++ b/package.json @@ -36,7 +36,7 @@ "patch-package": "^8.0.0", "react": "^18.3.1", "react-dom": "^18.3.1", - "tldraw": "^3.2.0", + "tldraw": "^3.4.1", "use-debounce": "^9.0.4", "zustand": "^4.3.9" } diff --git a/patches/@tldraw+editor+3.2.0.patch b/patches/@tldraw+editor+3.2.0.patch deleted file mode 100644 index ad3936b..0000000 --- a/patches/@tldraw+editor+3.2.0.patch +++ /dev/null @@ -1,31218 +0,0 @@ -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/index.d.mts b/node_modules/@tldraw/editor/dist-cjs/dist-esm/index.d.mts -new file mode 100644 -index 0000000..d6747f5 ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/index.d.mts -@@ -0,0 +1,6877 @@ -+/// -+ -+import { Atom } from '@tldraw/state'; -+import { atom } from '@tldraw/state'; -+import { BoxModel } from '@tldraw/tlschema'; -+import { ComponentType } from 'react'; -+import { Computed } from '@tldraw/state'; -+import { computed } from '@tldraw/state'; -+import { Dispatch } from 'react'; -+import { EffectScheduler } from '@tldraw/state'; -+import { EMPTY_ARRAY } from '@tldraw/state'; -+import EventEmitter from 'eventemitter3'; -+import { HistoryEntry } from '@tldraw/store'; -+import { IndexKey } from '@tldraw/utils'; -+import { JsonObject } from '@tldraw/utils'; -+import { JSX as JSX_2 } from 'react/jsx-runtime'; -+import { LegacyMigrations } from '@tldraw/store'; -+import { MigrationSequence } from '@tldraw/store'; -+import { NamedExoticComponent } from 'react'; -+import { PerformanceTracker } from '@tldraw/utils'; -+import { PointerEventHandler } from 'react'; -+import { react } from '@tldraw/state'; -+import { default as React_2 } from 'react'; -+import * as React_3 from 'react'; -+import { ReactElement } from 'react'; -+import { ReactNode } from 'react'; -+import { RecordProps } from '@tldraw/tlschema'; -+import { RecordsDiff } from '@tldraw/store'; -+import { SerializedSchema } from '@tldraw/store'; -+import { SerializedStore } from '@tldraw/store'; -+import { SetStateAction } from 'react'; -+import { Signal } from '@tldraw/state'; -+import { Store } from '@tldraw/store'; -+import { StoreSchema } from '@tldraw/store'; -+import { StoreSideEffects } from '@tldraw/store'; -+import { StyleProp } from '@tldraw/tlschema'; -+import { StylePropValue } from '@tldraw/tlschema'; -+import { Timers } from '@tldraw/utils'; -+import { TLAsset } from '@tldraw/tlschema'; -+import { TLAssetId } from '@tldraw/tlschema'; -+import { TLAssetPartial } from '@tldraw/tlschema'; -+import { TLAssetStore } from '@tldraw/tlschema'; -+import { TLBaseShape } from '@tldraw/tlschema'; -+import { TLBinding } from '@tldraw/tlschema'; -+import { TLBindingCreate } from '@tldraw/tlschema'; -+import { TLBindingId } from '@tldraw/tlschema'; -+import { TLBindingUpdate } from '@tldraw/tlschema'; -+import { TLBookmarkAsset } from '@tldraw/tlschema'; -+import { TLCamera } from '@tldraw/tlschema'; -+import { TLCursor } from '@tldraw/tlschema'; -+import { TLCursorType } from '@tldraw/tlschema'; -+import { TLDefaultDashStyle } from '@tldraw/tlschema'; -+import { TLDefaultHorizontalAlignStyle } from '@tldraw/tlschema'; -+import { TLDocument } from '@tldraw/tlschema'; -+import { TLGroupShape } from '@tldraw/tlschema'; -+import { TLHandle } from '@tldraw/tlschema'; -+import { TLImageAsset } from '@tldraw/tlschema'; -+import { TLInstance } from '@tldraw/tlschema'; -+import { TLInstancePageState } from '@tldraw/tlschema'; -+import { TLInstancePresence } from '@tldraw/tlschema'; -+import { TLPage } from '@tldraw/tlschema'; -+import { TLPageId } from '@tldraw/tlschema'; -+import { TLParentId } from '@tldraw/tlschema'; -+import { TLPropsMigrations } from '@tldraw/tlschema'; -+import { TLRecord } from '@tldraw/tlschema'; -+import { TLScribble } from '@tldraw/tlschema'; -+import { TLShape } from '@tldraw/tlschema'; -+import { TLShapeId } from '@tldraw/tlschema'; -+import { TLShapePartial } from '@tldraw/tlschema'; -+import { TLStore } from '@tldraw/tlschema'; -+import { TLStoreProps } from '@tldraw/tlschema'; -+import { TLStoreSnapshot } from '@tldraw/tlschema'; -+import { TLUnknownBinding } from '@tldraw/tlschema'; -+import { TLUnknownShape } from '@tldraw/tlschema'; -+import { TLVideoAsset } from '@tldraw/tlschema'; -+import { track } from '@tldraw/state-react'; -+import { transact } from '@tldraw/state'; -+import { transaction } from '@tldraw/state'; -+import { UnknownRecord } from '@tldraw/store'; -+import { useAtom } from '@tldraw/state-react'; -+import { useComputed } from '@tldraw/state-react'; -+import { useQuickReactor } from '@tldraw/state-react'; -+import { useReactor } from '@tldraw/state-react'; -+import { useStateTracking } from '@tldraw/state-react'; -+import { useValue } from '@tldraw/state-react'; -+import { VecModel } from '@tldraw/tlschema'; -+import { whyAmIRunning } from '@tldraw/state'; -+ -+/** -+ * Get the angle of a point on an arc. -+ * @param fromAngle - The angle from center to arc's start point (A) on the circle -+ * @param toAngle - The angle from center to arc's end point (B) on the circle -+ * @param direction - The direction of the arc (1 = counter-clockwise, -1 = clockwise) -+ * @returns The distance in radians between the two angles according to the direction -+ * @public -+ */ -+export declare function angleDistance(fromAngle: number, toAngle: number, direction: number): number; -+ -+/* Excluded from this release type: applyRotationToSnapshotShapes */ -+ -+/** -+ * Whether two numbers numbers a and b are approximately equal. -+ * -+ * @param a - The first point. -+ * @param b - The second point. -+ * @public -+ */ -+export declare function approximately(a: number, b: number, precision?: number): boolean; -+ -+/** @public */ -+export declare class Arc2d extends Geometry2d { -+ _center: Vec; -+ radius: number; -+ start: Vec; -+ end: Vec; -+ largeArcFlag: number; -+ sweepFlag: number; -+ measure: number; -+ angleStart: number; -+ angleEnd: number; -+ constructor(config: Omit & { -+ center: Vec; -+ end: Vec; -+ largeArcFlag: number; -+ start: Vec; -+ sweepFlag: number; -+ }); -+ nearestPoint(point: Vec): Vec; -+ hitTestLineSegment(A: Vec, B: Vec): boolean; -+ getVertices(): Vec[]; -+ getSvgPathData(first?: boolean): string; -+ getLength(): number; -+} -+ -+/** -+ * Checks whether two angles are approximately at right-angles or parallel to each other -+ * -+ * @param a - Angle a (radians) -+ * @param b - Angle b (radians) -+ * @returns True iff the angles are approximately at right-angles or parallel to each other -+ * @public -+ */ -+export declare function areAnglesCompatible(a: number, b: number): boolean; -+ -+export { Atom } -+ -+export { atom } -+ -+/** @public */ -+export declare function average(A: VecLike, B: VecLike): string; -+ -+/** @public */ -+export declare abstract class BaseBoxShapeTool extends StateNode { -+ static id: string; -+ static initial: string; -+ static children(): TLStateNodeConstructor[]; -+ abstract shapeType: string; -+ onCreate?(_shape: null | TLShape): null | void; -+} -+ -+/** @public */ -+export declare abstract class BaseBoxShapeUtil extends ShapeUtil { -+ getGeometry(shape: Shape): Geometry2d; -+ onResize(shape: any, info: TLResizeInfo): any; -+ getHandleSnapGeometry(shape: Shape): HandleSnapGeometry; -+ getInterpolatedProps(startShape: Shape, endShape: Shape, t: number): Shape['props']; -+} -+ -+/** -+ * Options passed to {@link BindingUtil.onBeforeChange} and {@link BindingUtil.onAfterChange}, -+ * describing the data associated with a binding being changed. -+ * -+ * @public -+ */ -+export declare interface BindingOnChangeOptions { -+ /** The binding record before the change is made. */ -+ bindingBefore: Binding; -+ /** The binding record after the change is made. */ -+ bindingAfter: Binding; -+} -+ -+/** -+ * Options passed to {@link BindingUtil.onBeforeCreate} and {@link BindingUtil.onAfterCreate}, -+ * describing a the creating a binding. -+ * -+ * @public -+ */ -+export declare interface BindingOnCreateOptions { -+ /** The binding being created. */ -+ binding: Binding; -+} -+ -+/** -+ * Options passed to {@link BindingUtil.onBeforeDelete} and {@link BindingUtil.onAfterDelete}, -+ * describing a binding being deleted. -+ * -+ * @public -+ */ -+export declare interface BindingOnDeleteOptions { -+ /** The binding being deleted. */ -+ binding: Binding; -+} -+ -+/** -+ * Options passed to {@link BindingUtil.onAfterChangeFromShape} and -+ * {@link BindingUtil.onAfterChangeToShape}, describing a bound shape being changed. -+ * -+ * @public -+ */ -+export declare interface BindingOnShapeChangeOptions { -+ /** The binding record linking these two shapes. */ -+ binding: Binding; -+ /** The shape record before the change is made. */ -+ shapeBefore: TLShape; -+ /** The shape record after the change is made. */ -+ shapeAfter: TLShape; -+} -+ -+/** -+ * Options passed to {@link BindingUtil.onBeforeDeleteFromShape} and -+ * {@link BindingUtil.onBeforeDeleteToShape}, describing a bound shape that is about to be deleted. -+ * -+ * See {@link BindingOnShapeIsolateOptions} for discussion on when to use the delete vs. the isolate -+ * callbacks. -+ * -+ * @public -+ */ -+export declare interface BindingOnShapeDeleteOptions { -+ /** The binding record that refers to the shape in question. */ -+ binding: Binding; -+ /** The shape that is about to be deleted. */ -+ shape: TLShape; -+} -+ -+/** -+ * Options passed to {@link BindingUtil.onBeforeIsolateFromShape} and -+ * {@link BindingUtil.onBeforeIsolateToShape}, describing a shape that is about to be isolated from -+ * the one that it's bound to. -+ * -+ * Isolation happens whenever two bound shapes are separated. For example -+ * 1. One is deleted, but the other is not. -+ * 1. One is copied, but the other is not. -+ * 1. One is duplicated, but the other is not. -+ * -+ * In each of these cases, if the remaining shape depends on the binding for its rendering, it may -+ * now be in an inconsistent state. For example, tldraw's arrow shape depends on the binding to know -+ * where the end of the arrow is. If we removed the binding without doing anything else, the arrow -+ * would suddenly be pointing to the wrong location. Instead, when the shape the arrow is pointing -+ * to is deleted, or the arrow is copied/duplicated, we use an isolation callback. The callback -+ * updates the arrow based on the binding that's about to be removed, so it doesn't end up pointing -+ * to the wrong place. -+ * -+ * For this style of consistency update, use isolation callbacks. For actions specific to deletion -+ * (like deleting a sticker when the shape it's bound to is removed), use the delete callbacks -+ * ({@link BindingUtil.onBeforeDeleteFromShape} and {@link BindingUtil.onBeforeDeleteToShape}) -+ * instead. -+ * -+ * @public -+ */ -+export declare interface BindingOnShapeIsolateOptions { -+ /** The binding record that refers to the shape in question. */ -+ binding: Binding; -+ /** -+ * The shape being removed. For deletion, this is the deleted shape. For copy/duplicate, this is -+ * the shape that _isn't_ being copied/duplicated and is getting left behind. -+ */ -+ removedShape: TLShape; -+} -+ -+/** @public */ -+export declare abstract class BindingUtil { -+ editor: Editor; -+ constructor(editor: Editor); -+ static props?: RecordProps; -+ static migrations?: TLPropsMigrations; -+ /** -+ * The type of the binding util, which should match the binding's type. -+ * -+ * @public -+ */ -+ static type: string; -+ /** -+ * Get the default props for a binding. -+ * -+ * @public -+ */ -+ abstract getDefaultProps(): Partial; -+ /** -+ * Called whenever a store operation involving this binding type has completed. This is useful -+ * for working with networks of related bindings that may need to update together. -+ * -+ * @example -+ * ```ts -+ * class MyBindingUtil extends BindingUtil { -+ * changedBindingIds = new Set() -+ * -+ * onOperationComplete() { -+ * doSomethingWithChangedBindings(this.changedBindingIds) -+ * this.changedBindingIds.clear() -+ * } -+ * -+ * onAfterChange({ bindingAfter }: BindingOnChangeOptions) { -+ * this.changedBindingIds.add(bindingAfter.id) -+ * } -+ * } -+ * ``` -+ * -+ * @public -+ */ -+ onOperationComplete?(): void; -+ /** -+ * Called when a binding is about to be created. See {@link BindingOnCreateOptions} for details. -+ * -+ * You can optionally return a new binding to replace the one being created - for example, to -+ * set different initial props. -+ * -+ * @public -+ */ -+ onBeforeCreate?(options: BindingOnCreateOptions): Binding | void; -+ /** -+ * Called after a binding has been created. See {@link BindingOnCreateOptions} for details. -+ * -+ * @public -+ */ -+ onAfterCreate?(options: BindingOnCreateOptions): void; -+ /** -+ * Called when a binding is about to be changed. See {@link BindingOnChangeOptions} for details. -+ * -+ * Note that this only fires when the binding record is changing, not when the shapes -+ * associated change. Use {@link BindingUtil.onAfterChangeFromShape} and -+ * {@link BindingUtil.onAfterChangeToShape} for that. -+ * -+ * You can optionally return a new binding to replace the one being changed - for example, to -+ * enforce constraints on the binding's props. -+ * -+ * @public -+ */ -+ onBeforeChange?(options: BindingOnChangeOptions): Binding | void; -+ /** -+ * Called after a binding has been changed. See {@link BindingOnChangeOptions} for details. -+ * -+ * Note that this only fires when the binding record is changing, not when the shapes -+ * associated change. Use {@link BindingUtil.onAfterChangeFromShape} and -+ * {@link BindingUtil.onAfterChangeToShape} for that. -+ * -+ * @public -+ */ -+ onAfterChange?(options: BindingOnChangeOptions): void; -+ /** -+ * Called when a binding is about to be deleted. See {@link BindingOnDeleteOptions} for details. -+ * -+ * @public -+ */ -+ onBeforeDelete?(options: BindingOnDeleteOptions): void; -+ /** -+ * Called after a binding has been deleted. See {@link BindingOnDeleteOptions} for details. -+ * -+ * @public -+ */ -+ onAfterDelete?(options: BindingOnDeleteOptions): void; -+ /** -+ * Called after the shape referenced in a binding's `fromId` is changed. Use this to propagate -+ * any changes to the binding itself or the other shape as needed. See -+ * {@link BindingOnShapeChangeOptions} for details. -+ * -+ * @public -+ */ -+ onAfterChangeFromShape?(options: BindingOnShapeChangeOptions): void; -+ /** -+ * Called after the shape referenced in a binding's `toId` is changed. Use this to propagate any -+ * changes to the binding itself or the other shape as needed. See -+ * {@link BindingOnShapeChangeOptions} for details. -+ * -+ * @public -+ */ -+ onAfterChangeToShape?(options: BindingOnShapeChangeOptions): void; -+ /** -+ * Called before the shape referenced in a binding's `fromId` is about to be deleted. Use this -+ * with care - you may want to use {@link BindingUtil.onBeforeIsolateToShape} instead. See -+ * {@link BindingOnShapeDeleteOptions} for details. -+ * -+ * @public -+ */ -+ onBeforeDeleteFromShape?(options: BindingOnShapeDeleteOptions): void; -+ /** -+ * Called before the shape referenced in a binding's `toId` is about to be deleted. Use this -+ * with care - you may want to use {@link BindingUtil.onBeforeIsolateFromShape} instead. See -+ * {@link BindingOnShapeDeleteOptions} for details. -+ * -+ * @public -+ */ -+ onBeforeDeleteToShape?(options: BindingOnShapeDeleteOptions): void; -+ /** -+ * Called before the shape referenced in a binding's `fromId` is about to be isolated from the -+ * shape referenced in `toId`. See {@link BindingOnShapeIsolateOptions} for discussion on what -+ * isolation means, and when/how to use this callback. -+ */ -+ onBeforeIsolateFromShape?(options: BindingOnShapeIsolateOptions): void; -+ /** -+ * Called before the shape referenced in a binding's `toId` is about to be isolated from the -+ * shape referenced in `fromId`. See {@link BindingOnShapeIsolateOptions} for discussion on what -+ * isolation means, and when/how to use this callback. -+ */ -+ onBeforeIsolateToShape?(options: BindingOnShapeIsolateOptions): void; -+} -+ -+/** -+ * When moving or resizing shapes, the bounds of the shape can snap to key geometry on other nearby -+ * shapes. Customize how a shape snaps to others with {@link ShapeUtil.getBoundsSnapGeometry}. -+ * -+ * @public -+ */ -+export declare interface BoundsSnapGeometry { -+ /** -+ * Points that this shape will snap to. By default, this will be the corners and center of the -+ * shapes bounding box. To disable snapping to a specific point, use an empty array. -+ */ -+ points?: VecModel[]; -+} -+ -+/** @public */ -+export declare interface BoundsSnapPoint { -+ id: string; -+ x: number; -+ y: number; -+ handle?: SelectionCorner; -+} -+ -+/** @public */ -+export declare class BoundsSnaps { -+ readonly manager: SnapManager; -+ readonly editor: Editor; -+ constructor(manager: SnapManager); -+ private getSnapPointsCache; -+ getSnapPoints(shapeId: TLShapeId): BoundsSnapPoint[]; -+ private getSnappablePoints; -+ private getSnappableGapNodes; -+ private getVisibleGaps; -+ snapTranslateShapes({ lockedAxis, initialSelectionPageBounds, initialSelectionSnapPoints, dragDelta, }: { -+ dragDelta: Vec; -+ initialSelectionPageBounds: Box; -+ initialSelectionSnapPoints: BoundsSnapPoint[]; -+ lockedAxis: 'x' | 'y' | null; -+ }): SnapData; -+ snapResizeShapes({ initialSelectionPageBounds, dragDelta, handle: originalHandle, isAspectRatioLocked, isResizingFromCenter, }: { -+ dragDelta: Vec; -+ handle: SelectionCorner | SelectionEdge; -+ initialSelectionPageBounds: Box; -+ isAspectRatioLocked: boolean; -+ isResizingFromCenter: boolean; -+ }): SnapData; -+ private collectPointSnaps; -+ private collectGapSnaps; -+ private getPointSnapLines; -+ private getGapSnapLines; -+} -+ -+/** @public */ -+export declare class Box { -+ constructor(x?: number, y?: number, w?: number, h?: number); -+ x: number; -+ y: number; -+ w: number; -+ h: number; -+ get point(): Vec; -+ set point(val: Vec); -+ get minX(): number; -+ set minX(n: number); -+ get midX(): number; -+ get maxX(): number; -+ get minY(): number; -+ set minY(n: number); -+ get midY(): number; -+ get maxY(): number; -+ get width(): number; -+ set width(n: number); -+ get height(): number; -+ set height(n: number); -+ get aspectRatio(): number; -+ get center(): Vec; -+ set center(v: Vec); -+ get corners(): Vec[]; -+ get cornersAndCenter(): Vec[]; -+ get sides(): Array<[Vec, Vec]>; -+ get size(): Vec; -+ toFixed(): this; -+ setTo(B: Box): this; -+ set(x?: number, y?: number, w?: number, h?: number): this; -+ expand(A: Box): this; -+ expandBy(n: number): this; -+ scale(n: number): this; -+ clone(): Box; -+ translate(delta: VecLike): this; -+ snapToGrid(size: number): void; -+ collides(B: Box): boolean; -+ contains(B: Box): boolean; -+ includes(B: Box): boolean; -+ containsPoint(V: VecLike, margin?: number): boolean; -+ getHandlePoint(handle: SelectionCorner | SelectionEdge): Vec; -+ toJson(): BoxModel; -+ resize(handle: SelectionCorner | SelectionEdge | string, dx: number, dy: number): void; -+ union(box: BoxModel): this; -+ static From(box: BoxModel): Box; -+ static FromCenter(center: VecLike, size: VecLike): Box; -+ static FromPoints(points: VecLike[]): Box; -+ static Expand(A: Box, B: Box): Box; -+ static ExpandBy(A: Box, n: number): Box; -+ static Collides(A: Box, B: Box): boolean; -+ static Contains(A: Box, B: Box): boolean; -+ static Includes(A: Box, B: Box): boolean; -+ static ContainsPoint(A: Box, B: VecLike, margin?: number): boolean; -+ static Common(boxes: Box[]): Box; -+ static Sides(A: Box, inset?: number): Vec[][]; -+ static Resize(box: Box, handle: SelectionCorner | SelectionEdge | string, dx: number, dy: number, isAspectRatioLocked?: boolean): { -+ box: Box; -+ scaleX: number; -+ scaleY: number; -+ }; -+ equals(other: Box | BoxModel): boolean; -+ static Equals(a: Box | BoxModel, b: Box | BoxModel): boolean; -+ zeroFix(): this; -+ static ZeroFix(other: Box | BoxModel): Box; -+} -+ -+/** @public */ -+export declare type BoxLike = Box | BoxModel; -+ -+/** -+ * @param a - Any angle in radians -+ * @returns A number between 0 and 2 * PI -+ * @public -+ */ -+export declare function canonicalizeRotation(a: number): number; -+ -+/** -+ * Get the center of a circle from three points. -+ * -+ * @param a - The first point -+ * @param b - The second point -+ * @param c - The third point -+ * -+ * @returns The center of the circle or null if the points are collinear -+ * -+ * @public -+ */ -+export declare function centerOfCircleFromThreePoints(a: VecLike, b: VecLike, c: VecLike): null | Vec; -+ -+/** @public */ -+export declare class Circle2d extends Geometry2d { -+ config: Omit & { -+ isFilled: boolean; -+ radius: number; -+ x?: number; -+ y?: number; -+ }; -+ _center: Vec; -+ radius: number; -+ x: number; -+ y: number; -+ constructor(config: Omit & { -+ isFilled: boolean; -+ radius: number; -+ x?: number; -+ y?: number; -+ }); -+ getBounds(): Box; -+ getVertices(): Vec[]; -+ nearestPoint(point: Vec): Vec; -+ hitTestLineSegment(A: Vec, B: Vec, distance?: number): boolean; -+ getSvgPathData(): string; -+} -+ -+/** -+ * Clamp a value into a range. -+ * -+ * @example -+ * -+ * ```ts -+ * const A = clamp(0, 1) // 1 -+ * ``` -+ * -+ * @param n - The number to clamp. -+ * @param min - The minimum value. -+ * @public -+ */ -+export declare function clamp(n: number, min: number): number; -+ -+/** -+ * Clamp a value into a range. -+ * -+ * @example -+ * -+ * ```ts -+ * const A = clamp(0, 1, 10) // 1 -+ * const B = clamp(11, 1, 10) // 10 -+ * const C = clamp(5, 1, 10) // 5 -+ * ``` -+ * -+ * @param n - The number to clamp. -+ * @param min - The minimum value. -+ * @param max - The maximum value. -+ * @public -+ */ -+export declare function clamp(n: number, min: number, max: number): number; -+ -+/** -+ * Clamp radians within 0 and 2PI -+ * -+ * @param r - The radian value. -+ * @public -+ */ -+export declare function clampRadians(r: number): number; -+ -+/** @public */ -+export declare class ClickManager { -+ editor: Editor; -+ constructor(editor: Editor); -+ private _clickId; -+ private _clickTimeout?; -+ private _clickScreenPoint?; -+ private _previousScreenPoint?; -+ _getClickTimeout(state: TLClickState, id?: string): void; -+ /* Excluded from this release type: _clickState */ -+ /** -+ * The current click state. -+ * -+ * @public -+ */ -+ get clickState(): TLClickState | undefined; -+ lastPointerInfo: TLPointerEventInfo; -+ handlePointerEvent(info: TLPointerEventInfo): TLClickEventInfo | TLPointerEventInfo; -+ /* Excluded from this release type: cancelDoubleClickTimeout */ -+} -+ -+/** -+ * Get the clockwise angle distance between two angles. -+ * -+ * @param a0 - The first angle. -+ * @param a1 - The second angle. -+ * @public -+ */ -+export declare function clockwiseAngleDist(a0: number, a1: number): number; -+ -+export { computed } -+ -+/* Excluded from this release type: ContainerProvider */ -+ -+/** @public */ -+export declare const coreShapes: readonly [typeof GroupShapeUtil]; -+ -+/** -+ * Get the counter-clockwise angle distance between two angles. -+ * -+ * @param a0 - The first angle. -+ * @param a1 - The second angle. -+ * @public -+ */ -+export declare function counterClockwiseAngleDist(a0: number, a1: number): number; -+ -+/** -+ * Converts a deep link descriptor to a url-safe string -+ * -+ * @example -+ * ```ts -+ * const url = `https://example.com?d=${createDeepLinkString({ type: 'shapes', shapeIds: ['shape:1', 'shape:2'] })}` -+ * navigator.clipboard.writeText(url) -+ * ``` -+ * -+ * @param deepLink - the deep link descriptor -+ * @returns a url-safe string -+ * -+ * @public -+ */ -+export declare function createDeepLinkString(deepLink: TLDeepLink): string; -+ -+/** -+ * Creates a signal of the instance state for a given store. -+ * @public -+ * @param store - The store to create the instance state snapshot signal for -+ * @returns -+ */ -+export declare function createSessionStateSnapshotSignal(store: TLStore): Signal; -+ -+/** -+ * A helper for creating a TLStore schema from either an object with shapeUtils, bindingUtils, and -+ * migrations, or a schema. -+ * -+ * @param opts - Options for creating the schema. -+ * -+ * @public -+ */ -+export declare function createTLSchemaFromUtils(opts: TLStoreSchemaOptions): StoreSchema; -+ -+/** -+ * A helper for creating a TLStore. -+ * -+ * @param opts - Options for creating the store. -+ * -+ * @public -+ */ -+export declare function createTLStore({ initialData, defaultName, id, assets, onMount, collaboration, ...rest }?: TLStoreOptions): TLStore; -+ -+/** @public */ -+export declare function createTLUser(opts?: { -+ setUserPreferences?: ((userPreferences: TLUserPreferences) => void) | undefined; -+ userPreferences?: Signal | undefined; -+}): TLUser; -+ -+/** @public */ -+export declare class CubicBezier2d extends Polyline2d { -+ a: Vec; -+ b: Vec; -+ c: Vec; -+ d: Vec; -+ constructor(config: Omit & { -+ cp1: Vec; -+ cp2: Vec; -+ end: Vec; -+ start: Vec; -+ }); -+ getVertices(): Vec[]; -+ midPoint(): Vec; -+ nearestPoint(A: Vec): Vec; -+ getSvgPathData(first?: boolean): string; -+ static GetAtT(segment: CubicBezier2d, t: number): Vec; -+ getLength(precision?: number): number; -+} -+ -+/** @public */ -+export declare class CubicSpline2d extends Geometry2d { -+ points: Vec[]; -+ constructor(config: Omit & { -+ points: Vec[]; -+ }); -+ _segments?: CubicBezier2d[]; -+ get segments(): CubicBezier2d[]; -+ getLength(): number; -+ getVertices(): Vec[]; -+ nearestPoint(A: Vec): Vec; -+ hitTestLineSegment(A: Vec, B: Vec): boolean; -+ getSvgPathData(): string; -+} -+ -+/** @public */ -+export declare function dataUrlToFile(url: string, filename: string, mimeType: string): Promise; -+ -+/** -+ * @deprecated Licensing is now enabled in the tldraw SDK. -+ * @public */ -+export declare function debugEnableLicensing(): void; -+ -+/* Excluded from this release type: DebugFlag */ -+ -+/* Excluded from this release type: DebugFlagDef */ -+ -+/* Excluded from this release type: DebugFlagDefaults */ -+ -+/* Excluded from this release type: debugFlags */ -+ -+/* Excluded from this release type: DEFAULT_ANIMATION_OPTIONS */ -+ -+/* Excluded from this release type: DEFAULT_CAMERA_OPTIONS */ -+ -+/** @public @react */ -+export declare function DefaultBackground(): JSX_2.Element; -+ -+/** @public @react */ -+export declare const DefaultBrush: ({ brush, color, opacity, className }: TLBrushProps) => JSX_2.Element; -+ -+/** @public @react */ -+export declare function DefaultCanvas({ className }: TLCanvasComponentProps): JSX_2.Element; -+ -+/** @public @react */ -+export declare function DefaultCollaboratorHint({ className, zoom, point, color, viewport, opacity, }: TLCollaboratorHintProps): JSX_2.Element; -+ -+/** @public @react */ -+export declare const DefaultCursor: NamedExoticComponent; -+ -+/** @public @react */ -+export declare const DefaultErrorFallback: TLErrorFallbackComponent; -+ -+/** @public @react */ -+export declare function DefaultGrid({ x, y, z, size }: TLGridProps): JSX_2.Element; -+ -+/** @public @react */ -+export declare function DefaultHandle({ handle, isCoarse, className, zoom }: TLHandleProps): JSX_2.Element; -+ -+/** @public @react */ -+export declare const DefaultHandles: ({ children }: TLHandlesProps) => JSX_2.Element; -+ -+/** @public @react */ -+export declare function DefaultScribble({ scribble, zoom, color, opacity, className }: TLScribbleProps): JSX_2.Element | null; -+ -+/** @public @react */ -+export declare function DefaultSelectionBackground({ bounds, rotation }: TLSelectionBackgroundProps): JSX_2.Element; -+ -+/** @public @react */ -+export declare function DefaultSelectionForeground({ bounds, rotation }: TLSelectionForegroundProps): JSX_2.Element; -+ -+/** @public @react */ -+export declare const DefaultShapeIndicator: NamedExoticComponent; -+ -+/** @public @react */ -+export declare const DefaultShapeIndicators: NamedExoticComponent; -+ -+/** @public @react */ -+export declare function DefaultSnapIndicator({ className, line, zoom }: TLSnapIndicatorProps): JSX_2.Element; -+ -+/** @public @react */ -+export declare function DefaultSpinner(): JSX_2.Element; -+ -+/** @public @react */ -+export declare const DefaultSvgDefs: () => null; -+ -+/** @public */ -+export declare const defaultTldrawOptions: { -+ readonly adjacentShapeMargin: 10; -+ readonly animationMediumMs: 320; -+ readonly cameraMovingTimeoutMs: 64; -+ readonly cameraSlideFriction: 0.09; -+ readonly coarseDragDistanceSquared: 36; -+ readonly coarseHandleRadius: 20; -+ readonly coarsePointerWidth: 12; -+ readonly collaboratorCheckIntervalMs: 1200; -+ readonly collaboratorIdleTimeoutMs: 3000; -+ readonly collaboratorInactiveTimeoutMs: 60000; -+ readonly defaultSvgPadding: 32; -+ readonly doubleClickDurationMs: 450; -+ readonly dragDistanceSquared: 16; -+ readonly edgeScrollDelay: 200; -+ readonly edgeScrollDistance: 8; -+ readonly edgeScrollEaseDuration: 200; -+ readonly edgeScrollSpeed: 25; -+ readonly flattenImageBoundsExpand: 64; -+ readonly flattenImageBoundsPadding: 16; -+ readonly followChaseViewportSnap: 2; -+ readonly gridSteps: readonly [{ -+ readonly mid: 0.15; -+ readonly min: -1; -+ readonly step: 64; -+ }, { -+ readonly mid: 0.375; -+ readonly min: 0.05; -+ readonly step: 16; -+ }, { -+ readonly mid: 1; -+ readonly min: 0.15; -+ readonly step: 4; -+ }, { -+ readonly mid: 2.5; -+ readonly min: 0.7; -+ readonly step: 1; -+ }]; -+ readonly handleRadius: 12; -+ readonly hitTestMargin: 8; -+ readonly laserDelayMs: 1200; -+ readonly longPressDurationMs: 500; -+ readonly maxExportDelayMs: 5000; -+ readonly maxFilesAtOnce: 100; -+ readonly maxPages: 40; -+ readonly maxPointsPerDrawShape: 500; -+ readonly maxShapesPerPage: 4000; -+ readonly multiClickDurationMs: 200; -+ readonly temporaryAssetPreviewLifetimeMs: 180000; -+ readonly textShadowLod: 0.35; -+}; -+ -+/** @public */ -+export declare const defaultUserPreferences: Readonly<{ -+ animationSpeed: 0 | 1; -+ color: "#02B1CC" | "#11B3A3" | "#39B178" | "#55B467" | "#7B66DC" | "#9D5BD2" | "#BD54C6" | "#E34BA9" | "#EC5E41" | "#F04F88" | "#F2555A" | "#FF802B"; -+ colorScheme: "system"; -+ edgeScrollSpeed: 1; -+ isDynamicSizeMode: false; -+ isPasteAtCursorMode: false; -+ isSnapMode: false; -+ isWrapMode: false; -+ locale: "ar" | "ca" | "cs" | "da" | "de" | "en" | "es" | "fa" | "fi" | "fr" | "gl" | "he" | "hi-in" | "hr" | "hu" | "id" | "it" | "ja" | "ko-kr" | "ku" | "my" | "ne" | "no" | "pl" | "pt-br" | "pt-pt" | "ro" | "ru" | "sl" | "sv" | "te" | "th" | "tr" | "uk" | "vi" | "zh-cn" | "zh-tw"; -+ name: "New User"; -+}>; -+ -+/** -+ * Convert degrees to radians. -+ * -+ * @param d - The degree in degrees. -+ * @public -+ */ -+export declare function degreesToRadians(d: number): number; -+ -+/** @public */ -+export declare const EASINGS: { -+ readonly easeInCubic: (t: number) => number; -+ readonly easeInExpo: (t: number) => number; -+ readonly easeInOutCubic: (t: number) => number; -+ readonly easeInOutExpo: (t: number) => number; -+ readonly easeInOutQuad: (t: number) => number; -+ readonly easeInOutQuart: (t: number) => number; -+ readonly easeInOutQuint: (t: number) => number; -+ readonly easeInOutSine: (t: number) => number; -+ readonly easeInQuad: (t: number) => number; -+ readonly easeInQuart: (t: number) => number; -+ readonly easeInQuint: (t: number) => number; -+ readonly easeInSine: (t: number) => number; -+ readonly easeOutCubic: (t: number) => number; -+ readonly easeOutExpo: (t: number) => number; -+ readonly easeOutQuad: (t: number) => number; -+ readonly easeOutQuart: (t: number) => number; -+ readonly easeOutQuint: (t: number) => number; -+ readonly easeOutSine: (t: number) => number; -+ readonly linear: (t: number) => number; -+}; -+ -+/** @public */ -+export declare class Edge2d extends Geometry2d { -+ start: Vec; -+ end: Vec; -+ d: Vec; -+ u: Vec; -+ ul: number; -+ constructor(config: { -+ end: Vec; -+ start: Vec; -+ }); -+ getLength(): number; -+ midPoint(): Vec; -+ getVertices(): Vec[]; -+ nearestPoint(point: Vec): Vec; -+ hitTestLineSegment(A: Vec, B: Vec, distance?: number): boolean; -+ getSvgPathData(first?: boolean): string; -+} -+ -+/** @public */ -+export declare class EdgeScrollManager { -+ editor: Editor; -+ constructor(editor: Editor); -+ private _isEdgeScrolling; -+ private _edgeScrollDuration; -+ /** -+ * Update the camera position when the mouse is close to the edge of the screen. -+ * Run this on every tick when in a state where edge scrolling is enabled. -+ * -+ * @public -+ */ -+ updateEdgeScrolling(elapsed: number): void; -+ /* Excluded from this release type: getEdgeProximityFactors */ -+ private getEdgeScroll; -+ /** -+ * Moves the camera when the mouse is close to the edge of the screen. -+ * @public -+ */ -+ private moveCameraWhenCloseToEdge; -+} -+ -+/** @public */ -+export declare class Editor extends EventEmitter { -+ constructor({ store, user, shapeUtils, bindingUtils, tools, getContainer, cameraOptions, initialState, autoFocus, inferDarkMode, options, isShapeHidden, }: TLEditorOptions); -+ private readonly _isShapeHiddenPredicate?; -+ private getIsShapeHiddenCache; -+ isShapeHidden(shapeOrId: TLShape | TLShapeId): boolean; -+ readonly options: TldrawOptions; -+ /** -+ * The editor's store -+ * -+ * @public -+ */ -+ readonly store: TLStore; -+ /** -+ * The root state of the statechart. -+ * -+ * @public -+ */ -+ readonly root: StateNode; -+ /** -+ * A set of functions to call when the app is disposed. -+ * -+ * @public -+ */ -+ readonly disposables: Set<() => void>; -+ /** -+ * Whether the editor is disposed. -+ * -+ * @public -+ */ -+ isDisposed: boolean; -+ /* Excluded from this release type: _tickManager */ -+ /** -+ * A manager for the app's snapping feature. -+ * -+ * @public -+ */ -+ readonly snaps: SnapManager; -+ /** -+ * A manager for the any asynchronous events and making sure they're -+ * cleaned up upon disposal. -+ * -+ * @public -+ */ -+ readonly timers: Timers; -+ /** -+ * A manager for the user and their preferences. -+ * -+ * @public -+ */ -+ readonly user: UserPreferencesManager; -+ /** -+ * A helper for measuring text. -+ * -+ * @public -+ */ -+ readonly textMeasure: TextManager; -+ /** -+ * A manager for the editor's environment. -+ * -+ * @public -+ */ -+ readonly environment: EnvironmentManager; -+ /** -+ * A manager for the editor's scribbles. -+ * -+ * @public -+ */ -+ readonly scribbles: ScribbleManager; -+ /** -+ * A manager for side effects and correct state enforcement. See {@link @tldraw/store#StoreSideEffects} for details. -+ * -+ * @public -+ */ -+ readonly sideEffects: StoreSideEffects; -+ /** -+ * A manager for moving the camera when the mouse is at the edge of the screen. -+ * -+ * @public -+ */ -+ edgeScrollManager: EdgeScrollManager; -+ /* Excluded from this release type: focusManager */ -+ /** -+ * The current HTML element containing the editor. -+ * -+ * @example -+ * ```ts -+ * const container = editor.getContainer() -+ * ``` -+ * -+ * @public -+ */ -+ getContainer: () => HTMLElement; -+ /** -+ * Dispose the editor. -+ * -+ * @public -+ */ -+ dispose(): void; -+ /** -+ * A map of shape utility classes (TLShapeUtils) by shape type. -+ * -+ * @public -+ */ -+ shapeUtils: { -+ readonly [K in string]?: ShapeUtil; -+ }; -+ styleProps: { -+ [key: string]: Map, string>; -+ }; -+ /** -+ * Get a shape util from a shape itself. -+ * -+ * @example -+ * ```ts -+ * const util = editor.getShapeUtil(myArrowShape) -+ * const util = editor.getShapeUtil('arrow') -+ * const util = editor.getShapeUtil(myArrowShape) -+ * const util = editor.getShapeUtil(TLArrowShape)('arrow') -+ * ``` -+ * -+ * @param shape - A shape, shape partial, or shape type. -+ * -+ * @public -+ */ -+ getShapeUtil(shape: S | TLShapePartial): ShapeUtil; -+ getShapeUtil(type: S['type']): ShapeUtil; -+ getShapeUtil(type: T extends ShapeUtil ? R['type'] : string): T; -+ /** -+ * A map of shape utility classes (TLShapeUtils) by shape type. -+ * -+ * @public -+ */ -+ bindingUtils: { -+ readonly [K in string]?: BindingUtil; -+ }; -+ /** -+ * Get a binding util from a binding itself. -+ * -+ * @example -+ * ```ts -+ * const util = editor.getBindingUtil(myArrowBinding) -+ * const util = editor.getBindingUtil('arrow') -+ * const util = editor.getBindingUtil(myArrowBinding) -+ * const util = editor.getBindingUtil(TLArrowBinding)('arrow') -+ * ``` -+ * -+ * @param binding - A binding, binding partial, or binding type. -+ * -+ * @public -+ */ -+ getBindingUtil(binding: { -+ type: S['type']; -+ } | S): BindingUtil; -+ getBindingUtil(type: S['type']): BindingUtil; -+ getBindingUtil(type: T extends BindingUtil ? R['type'] : string): T; -+ /** -+ * A manager for the app's history. -+ * -+ * @readonly -+ */ -+ protected readonly history: HistoryManager; -+ /** -+ * Undo to the last mark. -+ * -+ * @example -+ * ```ts -+ * editor.undo() -+ * ``` -+ * -+ * @public -+ */ -+ undo(): this; -+ /** -+ * Whether the app can undo. -+ * -+ * @public -+ */ -+ getCanUndo(): boolean; -+ /** -+ * Redo to the next mark. -+ * -+ * @example -+ * ```ts -+ * editor.redo() -+ * ``` -+ * -+ * @public -+ */ -+ redo(): this; -+ clearHistory(): this; -+ /** -+ * Whether the app can redo. -+ * -+ * @public -+ */ -+ getCanRedo(): boolean; -+ /** -+ * Create a new "mark", or stopping point, in the undo redo history. Creating a mark will clear -+ * any redos. -+ * -+ * @example -+ * ```ts -+ * editor.mark() -+ * editor.mark('flip shapes') -+ * ``` -+ * -+ * @param markId - The mark's id, usually the reason for adding the mark. -+ * -+ * @public -+ * @deprecated use {@link Editor.markHistoryStoppingPoint} instead -+ */ -+ mark(markId?: string): this; -+ /** -+ * Create a new "mark", or stopping point, in the undo redo history. Creating a mark will clear -+ * any redos. You typically want to do this just before a user interaction begins or is handled. -+ * -+ * @example -+ * ```ts -+ * editor.markHistoryStoppingPoint() -+ * editor.flipShapes(editor.getSelectedShapes()) -+ * ``` -+ * @example -+ * ```ts -+ * const beginRotateMark = editor.markHistoryStoppingPoint() -+ * // if the use cancels the rotation, you can bail back to this mark -+ * editor.bailToMark(beginRotateMark) -+ * ``` -+ * -+ * @public -+ * @param name - The name of the mark, useful for debugging the undo/redo stacks -+ * @returns a unique id for the mark that can be used with `squashToMark` or `bailToMark`. -+ */ -+ markHistoryStoppingPoint(name?: string): string; -+ /* Excluded from this release type: getMarkIdMatching */ -+ /** -+ * Coalesces all changes since the given mark into a single change, removing any intermediate marks. -+ * -+ * This is useful if you need to 'compress' the recent history to simplify the undo/redo experience of a complex interaction. -+ * -+ * @example -+ * ```ts -+ * const bumpShapesMark = editor.markHistoryStoppingPoint() -+ * // ... some changes -+ * editor.squashToMark(bumpShapesMark) -+ * ``` -+ * -+ * @param markId - The mark id to squash to. -+ */ -+ squashToMark(markId: string): this; -+ /** -+ * Undo to the closest mark, discarding the changes so they cannot be redone. -+ * -+ * @example -+ * ```ts -+ * editor.bail() -+ * ``` -+ * -+ * @public -+ */ -+ bail(): this; -+ /** -+ * Undo to the given mark, discarding the changes so they cannot be redone. -+ * -+ * @example -+ * ```ts -+ * const beginDrag = editor.markHistoryStoppingPoint() -+ * // ... some changes -+ * editor.bailToMark(beginDrag) -+ * ``` -+ * -+ * @public -+ */ -+ bailToMark(id: string): this; -+ private _shouldIgnoreShapeLock; -+ /** -+ * Run a function in a transaction with optional options for context. -+ * You can use the options to change the way that history is treated -+ * or allow changes to locked shapes. -+ * -+ * @example -+ * ```ts -+ * // updating with -+ * editor.run(() => { -+ * editor.updateShape({ ...myShape, x: 100 }) -+ * }, { history: "ignore" }) -+ * -+ * // forcing changes / deletions for locked shapes -+ * editor.toggleLock([myShape]) -+ * editor.run(() => { -+ * editor.updateShape({ ...myShape, x: 100 }) -+ * editor.deleteShape(myShape) -+ * }, { ignoreShapeLock: true }, ) -+ * ``` -+ * -+ * @param fn - The callback function to run. -+ * @param opts - The options for the batch. -+ * -+ * -+ * @public -+ */ -+ run(fn: () => void, opts?: TLEditorRunOptions): this; -+ /** -+ * @deprecated Use `Editor.run` instead. -+ */ -+ batch(fn: () => void, opts?: TLEditorRunOptions): this; -+ /* Excluded from this release type: annotateError */ -+ /* Excluded from this release type: createErrorAnnotations */ -+ /* Excluded from this release type: _crashingError */ -+ /* Excluded from this release type: getCrashingError */ -+ /* Excluded from this release type: crash */ -+ /** -+ * The editor's current path of active states. -+ * -+ * @example -+ * ```ts -+ * editor.getPath() // "select.idle" -+ * ``` -+ * -+ * @public -+ */ -+ getPath(): string; -+ /** -+ * Get whether a certain tool (or other state node) is currently active. -+ * -+ * @example -+ * ```ts -+ * editor.isIn('select') -+ * editor.isIn('select.brushing') -+ * ``` -+ * -+ * @param path - The path of active states, separated by periods. -+ * -+ * @public -+ */ -+ isIn(path: string): boolean; -+ /** -+ * Get whether the state node is in any of the given active paths. -+ * -+ * @example -+ * ```ts -+ * state.isInAny('select', 'erase') -+ * state.isInAny('select.brushing', 'erase.idle') -+ * ``` -+ * -+ * @public -+ */ -+ isInAny(...paths: string[]): boolean; -+ /** -+ * Set the selected tool. -+ * -+ * @example -+ * ```ts -+ * editor.setCurrentTool('hand') -+ * editor.setCurrentTool('hand', { date: Date.now() }) -+ * ``` -+ * -+ * @param id - The id of the tool to select. -+ * @param info - Arbitrary data to pass along into the transition. -+ * -+ * @public -+ */ -+ setCurrentTool(id: string, info?: {}): this; -+ /** -+ * The current selected tool. -+ * -+ * @public -+ */ -+ getCurrentTool(): StateNode; -+ /** -+ * The id of the current selected tool. -+ * -+ * @public -+ */ -+ getCurrentToolId(): string; -+ /** -+ * Get a descendant by its path. -+ * -+ * @example -+ * ```ts -+ * state.getStateDescendant('select') -+ * state.getStateDescendant('select.brushing') -+ * ``` -+ * -+ * @param path - The descendant's path of state ids, separated by periods. -+ * -+ * @public -+ */ -+ getStateDescendant(path: string): T | undefined; -+ /** -+ * The global document settings that apply to all users. -+ * -+ * @public -+ **/ -+ getDocumentSettings(): TLDocument; -+ /** -+ * Update the global document settings that apply to all users. -+ * -+ * @public -+ **/ -+ updateDocumentSettings(settings: Partial): this; -+ /** -+ * The current instance's state. -+ * -+ * @public -+ */ -+ getInstanceState(): TLInstance; -+ /** -+ * Update the instance's state. -+ * -+ * @param partial - A partial object to update the instance state with. -+ * -+ * @public -+ */ -+ updateInstanceState(partial: Partial>, historyOptions?: TLHistoryBatchOptions): this; -+ /* Excluded from this release type: _updateInstanceState */ -+ /* Excluded from this release type: _isChangingStyleTimeout */ -+ /** -+ * A set of strings representing any open menus. When menus are open, -+ * certain interactions will behave differently; for example, when a -+ * draw tool is selected and a menu is open, a pointer-down will not -+ * create a dot (because the user is probably trying to close the menu) -+ * however a pointer-down event followed by a drag will begin drawing -+ * a line (because the user is BOTH trying to close the menu AND start -+ * drawing a line). -+ * -+ * @public -+ */ -+ getOpenMenus(): string[]; -+ /** -+ * Add an open menu. -+ * -+ * @example -+ * ```ts -+ * editor.addOpenMenu('menu-id') -+ * ``` -+ * -+ * @public -+ */ -+ addOpenMenu(id: string): this; -+ /** -+ * Delete an open menu. -+ * -+ * @example -+ * ```ts -+ * editor.deleteOpenMenu('menu-id') -+ * ``` -+ * -+ * @public -+ */ -+ deleteOpenMenu(id: string): this; -+ /** -+ * Clear all open menus. -+ * -+ * @example -+ * ```ts -+ * editor.clearOpenMenus() -+ * ``` -+ * -+ * @public -+ */ -+ clearOpenMenus(): this; -+ /** -+ * Get whether any menus are open. -+ * -+ * @example -+ * ```ts -+ * editor.getIsMenuOpen() -+ * ``` -+ * -+ * @public -+ */ -+ getIsMenuOpen(): boolean; -+ /** -+ * Set the cursor. -+ * -+ * @param type - The cursor type. -+ * @param rotation - The cursor rotation. -+ * -+ * @public -+ */ -+ setCursor(cursor: Partial): this; -+ /** -+ * Page states. -+ * -+ * @public -+ */ -+ getPageStates(): TLInstancePageState[]; -+ /* Excluded from this release type: _getPageStatesQuery */ -+ /** -+ * The current page state. -+ * -+ * @public -+ */ -+ getCurrentPageState(): TLInstancePageState; -+ /* Excluded from this release type: _getCurrentPageStateId */ -+ /** -+ * Update this instance's page state. -+ * -+ * @example -+ * ```ts -+ * editor.updateCurrentPageState({ id: 'page1', editingShapeId: 'shape:123' }) -+ * ``` -+ * -+ * @param partial - The partial of the page state object containing the changes. -+ * -+ * @public -+ */ -+ updateCurrentPageState(partial: Partial>): this; -+ _updateCurrentPageState(partial: Partial>): void; -+ /** -+ * The current selected ids. -+ * -+ * @public -+ */ -+ getSelectedShapeIds(): TLShapeId[]; -+ /** -+ * An array containing all of the currently selected shapes. -+ * -+ * @public -+ * @readonly -+ */ -+ getSelectedShapes(): TLShape[]; -+ /** -+ * Select one or more shapes. -+ * -+ * @example -+ * ```ts -+ * editor.setSelectedShapes(['id1']) -+ * editor.setSelectedShapes(['id1', 'id2']) -+ * ``` -+ * -+ * @param ids - The ids to select. -+ * -+ * @public -+ */ -+ setSelectedShapes(shapes: TLShape[] | TLShapeId[]): this; -+ /** -+ * Determine whether or not any of a shape's ancestors are selected. -+ * -+ * @param id - The id of the shape to check. -+ * -+ * @public -+ */ -+ isAncestorSelected(shape: TLShape | TLShapeId): boolean; -+ /** -+ * Select one or more shapes. -+ * -+ * @example -+ * ```ts -+ * editor.select('id1') -+ * editor.select('id1', 'id2') -+ * ``` -+ * -+ * @param ids - The ids to select. -+ * -+ * @public -+ */ -+ select(...shapes: TLShape[] | TLShapeId[]): this; -+ /** -+ * Remove a shape from the existing set of selected shapes. -+ * -+ * @example -+ * ```ts -+ * editor.deselect(shape.id) -+ * ``` -+ * -+ * @public -+ */ -+ deselect(...shapes: TLShape[] | TLShapeId[]): this; -+ /** -+ * Select all direct children of the current page. -+ * -+ * @example -+ * ```ts -+ * editor.selectAll() -+ * ``` -+ * -+ * @public -+ */ -+ selectAll(): this; -+ /** -+ * Clear the selection. -+ * -+ * @example -+ * ```ts -+ * editor.selectNone() -+ * ``` -+ * -+ * @public -+ */ -+ selectNone(): this; -+ /** -+ * The id of the app's only selected shape. -+ * -+ * @returns Null if there is no shape or more than one selected shape, otherwise the selected shape's id. -+ * -+ * @public -+ * @readonly -+ */ -+ getOnlySelectedShapeId(): null | TLShapeId; -+ /** -+ * The app's only selected shape. -+ * -+ * @returns Null if there is no shape or more than one selected shape, otherwise the selected shape. -+ * -+ * @public -+ * @readonly -+ */ -+ getOnlySelectedShape(): null | TLShape; -+ /* Excluded from this release type: getShapesPageBounds */ -+ /** -+ * The current page bounds of all the selected shapes. If the -+ * selection is rotated, then these bounds are the axis-aligned -+ * box that the rotated bounds would fit inside of. -+ * -+ * @readonly -+ * -+ * @public -+ */ -+ getSelectionPageBounds(): Box | null; -+ /* Excluded from this release type: getShapesSharedRotation */ -+ /** -+ * The rotation of the selection bounding box in the current page space. -+ * -+ * @readonly -+ * @public -+ */ -+ getSelectionRotation(): number; -+ /* Excluded from this release type: getShapesRotatedPageBounds */ -+ /** -+ * The bounds of the selection bounding box in the current page space. -+ * -+ * @readonly -+ * @public -+ */ -+ getSelectionRotatedPageBounds(): Box | undefined; -+ /** -+ * The bounds of the selection bounding box in the current page space. -+ * -+ * @readonly -+ * @public -+ */ -+ getSelectionRotatedScreenBounds(): Box | undefined; -+ /** -+ * The current focused group id. -+ * -+ * @public -+ */ -+ getFocusedGroupId(): TLPageId | TLShapeId; -+ /** -+ * The current focused group. -+ * -+ * @public -+ */ -+ getFocusedGroup(): TLShape | undefined; -+ /** -+ * Set the current focused group shape. -+ * -+ * @param shape - The group shape id (or group shape's id) to set as the focused group shape. -+ * -+ * @public -+ */ -+ setFocusedGroup(shape: null | TLGroupShape | TLShapeId): this; -+ /** -+ * Exit the current focused group, moving up to the next parent group if there is one. -+ * -+ * @public -+ */ -+ popFocusedGroupId(): this; -+ /** -+ * The current editing shape's id. -+ * -+ * @public -+ */ -+ getEditingShapeId(): null | TLShapeId; -+ /** -+ * The current editing shape. -+ * -+ * @public -+ */ -+ getEditingShape(): TLShape | undefined; -+ /** -+ * Set the current editing shape. -+ * -+ * @example -+ * ```ts -+ * editor.setEditingShape(myShape) -+ * editor.setEditingShape(myShape.id) -+ * ``` -+ * -+ * @param shape - The shape (or shape id) to set as editing. -+ * -+ * @public -+ */ -+ setEditingShape(shape: null | TLShape | TLShapeId): this; -+ /** -+ * The current hovered shape id. -+ * -+ * @readonly -+ * @public -+ */ -+ getHoveredShapeId(): null | TLShapeId; -+ /** -+ * The current hovered shape. -+ * -+ * @public -+ */ -+ getHoveredShape(): TLShape | undefined; -+ /** -+ * Set the editor's current hovered shape. -+ * -+ * @example -+ * ```ts -+ * editor.setHoveredShape(myShape) -+ * editor.setHoveredShape(myShape.id) -+ * ``` -+ * -+ * @param shapes - The shape (or shape id) to set as hovered. -+ * -+ * @public -+ */ -+ setHoveredShape(shape: null | TLShape | TLShapeId): this; -+ /** -+ * The editor's current hinting shape ids. -+ * -+ * @public -+ */ -+ getHintingShapeIds(): TLShapeId[]; -+ /** -+ * The editor's current hinting shapes. -+ * -+ * @public -+ */ -+ getHintingShape(): NonNullable[]; -+ /** -+ * Set the editor's current hinting shapes. -+ * -+ * @example -+ * ```ts -+ * editor.setHintingShapes([myShape]) -+ * editor.setHintingShapes([myShape.id]) -+ * ``` -+ * -+ * @param shapes - The shapes (or shape ids) to set as hinting. -+ * -+ * @public -+ */ -+ setHintingShapes(shapes: TLShape[] | TLShapeId[]): this; -+ /** -+ * The editor's current erasing ids. -+ * -+ * @public -+ */ -+ getErasingShapeIds(): TLShapeId[]; -+ /** -+ * The editor's current erasing shapes. -+ * -+ * @public -+ */ -+ getErasingShapes(): NonNullable[]; -+ /** -+ * Set the editor's current erasing shapes. -+ * -+ * @example -+ * ```ts -+ * editor.setErasingShapes([myShape]) -+ * editor.setErasingShapes([myShape.id]) -+ * ``` -+ * -+ * @param shapes - The shapes (or shape ids) to set as hinting. -+ * -+ * @public -+ */ -+ setErasingShapes(shapes: TLShape[] | TLShapeId[]): this; -+ /** -+ * The current cropping shape's id. -+ * -+ * @public -+ */ -+ getCroppingShapeId(): null | TLShapeId; -+ /** -+ * Set the current cropping shape. -+ * -+ * @example -+ * ```ts -+ * editor.setCroppingShape(myShape) -+ * editor.setCroppingShape(myShape.id) -+ * ``` -+ * -+ * -+ * @param shape - The shape (or shape id) to set as cropping. -+ * -+ * @public -+ */ -+ setCroppingShape(shape: null | TLShape | TLShapeId): this; -+ /* Excluded from this release type: _unsafe_getCameraId */ -+ /** -+ * The current camera. -+ * -+ * @public -+ */ -+ getCamera(): TLCamera; -+ private getViewportPageBoundsForFollowing; -+ private getCameraForFollowing; -+ /** -+ * The current camera zoom level. -+ * -+ * @public -+ */ -+ getZoomLevel(): number; -+ /** -+ * Get the camera's initial or reset zoom level. -+ * -+ * @example -+ * ```ts -+ * editor.getInitialZoom() -+ * ``` -+ * -+ * @public */ -+ getInitialZoom(): number; -+ /** -+ * Get the camera's base level for calculating actual zoom levels based on the zoom steps. -+ * -+ * @example -+ * ```ts -+ * editor.getBaseZoom() -+ * ``` -+ * -+ * @public */ -+ getBaseZoom(): number; -+ private _cameraOptions; -+ /** -+ * Get the current camera options. -+ * -+ * @example -+ * ```ts -+ * editor.getCameraOptions() -+ * ``` -+ * -+ * @public */ -+ getCameraOptions(): TLCameraOptions; -+ /** -+ * Set the camera options. Changing the options won't immediately change the camera itself, so you may want to call `setCamera` after changing the options. -+ * -+ * @example -+ * ```ts -+ * editor.setCameraOptions(myCameraOptions) -+ * editor.setCamera(editor.getCamera()) -+ * ``` -+ * -+ * @param options - The camera options to set. -+ * -+ * @public */ -+ setCameraOptions(options: Partial): this; -+ /* Excluded from this release type: getConstrainedCamera */ -+ /* Excluded from this release type: _setCamera */ -+ /** -+ * Set the current camera. -+ * -+ * @example -+ * ```ts -+ * editor.setCamera({ x: 0, y: 0}) -+ * editor.setCamera({ x: 0, y: 0, z: 1.5}) -+ * editor.setCamera({ x: 0, y: 0, z: 1.5}, { animation: { duration: 1000, easing: (t) => t * t } }) -+ * ``` -+ * -+ * @param point - The new camera position. -+ * @param opts - The camera move options. -+ * -+ * @public -+ */ -+ setCamera(point: VecLike, opts?: TLCameraMoveOptions): this; -+ /** -+ * Center the camera on a point (in the current page space). -+ * -+ * @example -+ * ```ts -+ * editor.centerOnPoint({ x: 100, y: 100 }) -+ * editor.centerOnPoint({ x: 100, y: 100 }, { animation: { duration: 200 } }) -+ * ``` -+ * -+ * @param point - The point in the current page space to center on. -+ * @param animation - The camera move options. -+ * -+ * @public -+ */ -+ centerOnPoint(point: VecLike, opts?: TLCameraMoveOptions): this; -+ /** -+ * Zoom the camera to fit the current page's content in the viewport. -+ * -+ * @example -+ * ```ts -+ * editor.zoomToFit() -+ * editor.zoomToFit({ animation: { duration: 200 } }) -+ * ``` -+ * -+ * @param opts - The camera move options. -+ * -+ * @public -+ */ -+ zoomToFit(opts?: TLCameraMoveOptions): this; -+ /** -+ * Set the zoom back to 100%. -+ * -+ * @example -+ * ```ts -+ * editor.resetZoom() -+ * editor.resetZoom(editor.getViewportScreenCenter(), { animation: { duration: 200 } }) -+ * editor.resetZoom(editor.getViewportScreenCenter(), { animation: { duration: 200 } }) -+ * ``` -+ * -+ * @param point - The screen point to zoom out on. Defaults to the viewport screen center. -+ * @param opts - The camera move options. -+ * -+ * @public -+ */ -+ resetZoom(point?: Vec, opts?: TLCameraMoveOptions): this; -+ /** -+ * Zoom the camera in. -+ * -+ * @example -+ * ```ts -+ * editor.zoomIn() -+ * editor.zoomIn(editor.getViewportScreenCenter(), { animation: { duration: 200 } }) -+ * editor.zoomIn(editor.inputs.currentScreenPoint, { animation: { duration: 200 } }) -+ * ``` -+ * -+ * @param point - The screen point to zoom in on. Defaults to the screen center -+ * @param opts - The camera move options. -+ * -+ * @public -+ */ -+ zoomIn(point?: Vec, opts?: TLCameraMoveOptions): this; -+ /** -+ * Zoom the camera out. -+ * -+ * @example -+ * ```ts -+ * editor.zoomOut() -+ * editor.zoomOut(editor.getViewportScreenCenter(), { animation: { duration: 120 } }) -+ * editor.zoomOut(editor.inputs.currentScreenPoint, { animation: { duration: 120 } }) -+ * ``` -+ * -+ * @param point - The point to zoom out on. Defaults to the viewport screen center. -+ * @param opts - The camera move options. -+ * -+ * @public -+ */ -+ zoomOut(point?: Vec, opts?: TLCameraMoveOptions): this; -+ /** -+ * Zoom the camera to fit the current selection in the viewport. -+ * -+ * @example -+ * ```ts -+ * editor.zoomToSelection() -+ * editor.zoomToSelection({ animation: { duration: 200 } }) -+ * ``` -+ * -+ * @param animation - The camera move options. -+ * -+ * @public -+ */ -+ zoomToSelection(opts?: TLCameraMoveOptions): this; -+ /** -+ * Zoom the camera to fit a bounding box (in the current page space). -+ * -+ * @example -+ * ```ts -+ * editor.zoomToBounds(myBounds) -+ * editor.zoomToBounds(myBounds, { animation: { duration: 200 } }) -+ * editor.zoomToBounds(myBounds, { animation: { duration: 200 }, inset: 0, targetZoom: 1 }) -+ * ``` -+ * -+ * @param bounds - The bounding box. -+ * @param opts - The camera move options, target zoom, or custom inset amount. -+ * -+ * @public -+ */ -+ zoomToBounds(bounds: BoxLike, opts?: { -+ inset?: number; -+ targetZoom?: number; -+ } & TLCameraMoveOptions): this; -+ /** -+ * Stop the current camera animation, if any. -+ * -+ * @example -+ * ```ts -+ * editor.stopCameraAnimation() -+ * ``` -+ * -+ * @public -+ */ -+ stopCameraAnimation(): this; -+ /* Excluded from this release type: _viewportAnimation */ -+ /* Excluded from this release type: _animateViewport */ -+ /* Excluded from this release type: _animateToViewport */ -+ /** -+ * Slide the camera in a certain direction. -+ * -+ * @example -+ * ```ts -+ * editor.slideCamera({ speed: 1, direction: { x: 1, y: 0 }, friction: 0.1 }) -+ * ``` -+ * -+ * @param opts - Options for the slide -+ * @public -+ */ -+ slideCamera(opts?: { -+ direction: VecLike; -+ force?: boolean | undefined; -+ friction?: number | undefined; -+ speed: number; -+ speedThreshold?: number | undefined; -+ }): this; -+ /** -+ * Animate the camera to a user's cursor position. This also briefly show the user's cursor if it's not currently visible. -+ * -+ * @example -+ * ```ts -+ * editor.zoomToUser(myUserId) -+ * editor.zoomToUser(myUserId, { animation: { duration: 200 } }) -+ * ``` -+ * -+ * @param userId - The id of the user to animate to. -+ * @param opts - The camera move options. -+ * @public -+ */ -+ zoomToUser(userId: string, opts?: TLCameraMoveOptions): this; -+ /* Excluded from this release type: _willSetInitialBounds */ -+ /** -+ * Update the viewport. The viewport will measure the size and screen position of its container -+ * element. This should be done whenever the container's position on the screen changes. -+ * -+ * @example -+ * ```ts -+ * editor.updateViewportScreenBounds(new Box(0, 0, 1280, 1024)) -+ * editor.updateViewportScreenBounds(new Box(0, 0, 1280, 1024), true) -+ * ``` -+ * -+ * @param center - Whether to preserve the viewport page center as the viewport changes. -+ * -+ * @public -+ */ -+ updateViewportScreenBounds(screenBounds: Box | HTMLElement, center?: boolean): this; -+ /** -+ * The bounds of the editor's viewport in screen space. -+ * -+ * @public -+ */ -+ getViewportScreenBounds(): Box; -+ /** -+ * The center of the editor's viewport in screen space. -+ * -+ * @public -+ */ -+ getViewportScreenCenter(): Vec; -+ /** -+ * The current viewport in the current page space. -+ * -+ * @public -+ */ -+ getViewportPageBounds(): Box; -+ /** -+ * Convert a point in screen space to a point in the current page space. -+ * -+ * @example -+ * ```ts -+ * editor.screenToPage({ x: 100, y: 100 }) -+ * ``` -+ * -+ * @param point - The point in screen space. -+ * -+ * @public -+ */ -+ screenToPage(point: VecLike): Vec; -+ /** -+ * Convert a point in the current page space to a point in current screen space. -+ * -+ * @example -+ * ```ts -+ * editor.pageToScreen({ x: 100, y: 100 }) -+ * ``` -+ * -+ * @param point - The point in page space. -+ * -+ * @public -+ */ -+ pageToScreen(point: VecLike): Vec; -+ /** -+ * Convert a point in the current page space to a point in current viewport space. -+ * -+ * @example -+ * ```ts -+ * editor.pageToViewport({ x: 100, y: 100 }) -+ * ``` -+ * -+ * @param point - The point in page space. -+ * -+ * @public -+ */ -+ pageToViewport(point: VecLike): Vec; -+ private _getCollaboratorsQuery; -+ /** -+ * Returns a list of presence records for all peer collaborators. -+ * This will return the latest presence record for each connected user. -+ * -+ * @public -+ */ -+ getCollaborators(): TLInstancePresence[]; -+ /** -+ * Returns a list of presence records for all peer collaborators on the current page. -+ * This will return the latest presence record for each connected user. -+ * -+ * @public -+ */ -+ getCollaboratorsOnCurrentPage(): TLInstancePresence[]; -+ private _isLockedOnFollowingUser; -+ /** -+ * Start viewport-following a user. -+ * -+ * @example -+ * ```ts -+ * editor.startFollowingUser(myUserId) -+ * ``` -+ * -+ * @param userId - The id of the user to follow. -+ * @param opts - Options for starting to follow a user. -+ * -+ * @public -+ */ -+ startFollowingUser(userId: string): this; -+ /** -+ * Stop viewport-following a user. -+ * -+ * @example -+ * ```ts -+ * editor.stopFollowingUser() -+ * ``` -+ * @public -+ */ -+ stopFollowingUser(): this; -+ /* Excluded from this release type: getUnorderedRenderingShapes */ -+ private _cameraState; -+ private _cameraStateTimeoutRemaining; -+ _decayCameraStateTimeout(elapsed: number): void; -+ _tickCameraState(): void; -+ /** -+ * Whether the camera is moving or idle. -+ * -+ * @example -+ * ```ts -+ * editor.getCameraState() -+ * ``` -+ * -+ * @public -+ */ -+ getCameraState(): "idle" | "moving"; -+ /** -+ * Get the shapes that should be displayed in the current viewport. -+ * -+ * @example -+ * ```ts -+ * editor.getRenderingShapes() -+ * ``` -+ * -+ * @public -+ */ -+ getRenderingShapes(): TLRenderingShape[]; -+ private _getAllPagesQuery; -+ /** -+ * Info about the project's current pages. -+ * -+ * @example -+ * ```ts -+ * editor.getPages() -+ * ``` -+ * -+ * @public -+ */ -+ getPages(): TLPage[]; -+ /** -+ * The current page. -+ * -+ * @example -+ * ```ts -+ * editor.getCurrentPage() -+ * ``` -+ * -+ * @public -+ */ -+ getCurrentPage(): TLPage; -+ /** -+ * The current page id. -+ * -+ * @example -+ * ```ts -+ * editor.getCurrentPageId() -+ * ``` -+ * -+ * @public -+ */ -+ getCurrentPageId(): TLPageId; -+ /** -+ * Get a page. -+ * -+ * @example -+ * ```ts -+ * editor.getPage(myPage.id) -+ * editor.getPage(myPage) -+ * ``` -+ * -+ * @param page - The page (or page id) to get. -+ * -+ * @public -+ */ -+ getPage(page: TLPage | TLPageId): TLPage | undefined; -+ private readonly _currentPageShapeIds; -+ /** -+ * An array of all of the shapes on the current page. -+ * -+ * @example -+ * ```ts -+ * editor.getCurrentPageIds() -+ * ``` -+ * -+ * @public -+ */ -+ getCurrentPageShapeIds(): Set; -+ /* Excluded from this release type: getCurrentPageShapeIdsSorted */ -+ /** -+ * Get the ids of shapes on a page. -+ * -+ * @example -+ * ```ts -+ * const idsOnPage1 = editor.getPageShapeIds('page1') -+ * const idsOnPage2 = editor.getPageShapeIds(myPage2) -+ * ``` -+ * -+ * @param page - The page (or page id) to get. -+ * -+ * @public -+ **/ -+ getPageShapeIds(page: TLPage | TLPageId): Set; -+ /** -+ * Set the current page. -+ * -+ * @example -+ * ```ts -+ * editor.setCurrentPage('page1') -+ * editor.setCurrentPage(myPage1) -+ * ``` -+ * -+ * @param page - The page (or page id) to set as the current page. -+ * -+ * @public -+ */ -+ setCurrentPage(page: TLPage | TLPageId): this; -+ /** -+ * Update a page. -+ * -+ * @example -+ * ```ts -+ * editor.updatePage({ id: 'page2', name: 'Page 2' }) -+ * ``` -+ * -+ * @param partial - The partial of the shape to update. -+ * -+ * @public -+ */ -+ updatePage(partial: RequiredKeys, 'id'>): this; -+ /** -+ * Create a page. -+ * -+ * @example -+ * ```ts -+ * editor.createPage(myPage) -+ * editor.createPage({ name: 'Page 2' }) -+ * ``` -+ * -+ * @param page - The page (or page partial) to create. -+ * -+ * @public -+ */ -+ createPage(page: Partial): this; -+ /** -+ * Delete a page. -+ * -+ * @example -+ * ```ts -+ * editor.deletePage('page1') -+ * ``` -+ * -+ * @param id - The id of the page to delete. -+ * -+ * @public -+ */ -+ deletePage(page: TLPage | TLPageId): this; -+ /** -+ * Duplicate a page. -+ * -+ * @param id - The id of the page to duplicate. Defaults to the current page. -+ * @param createId - The id of the new page. Defaults to a new id. -+ * -+ * @public -+ */ -+ duplicatePage(page: TLPage | TLPageId, createId?: TLPageId): this; -+ /** -+ * Rename a page. -+ * -+ * @example -+ * ```ts -+ * editor.renamePage('page1', 'My Page') -+ * ``` -+ * -+ * @param id - The id of the page to rename. -+ * @param name - The new name. -+ * -+ * @public -+ */ -+ renamePage(page: TLPage | TLPageId, name: string): this; -+ /* Excluded from this release type: _getAllAssetsQuery */ -+ /** -+ * Get all assets in the editor. -+ * -+ * @public -+ */ -+ getAssets(): (TLBookmarkAsset | TLImageAsset | TLVideoAsset)[]; -+ /** -+ * Create one or more assets. -+ * -+ * @example -+ * ```ts -+ * editor.createAssets([...myAssets]) -+ * ``` -+ * -+ * @param assets - The assets to create. -+ * -+ * @public -+ */ -+ createAssets(assets: TLAsset[]): this; -+ /** -+ * Update one or more assets. -+ * -+ * @example -+ * ```ts -+ * editor.updateAssets([{ id: 'asset1', name: 'New name' }]) -+ * ``` -+ * -+ * @param assets - The assets to update. -+ * -+ * @public -+ */ -+ updateAssets(assets: TLAssetPartial[]): this; -+ /** -+ * Delete one or more assets. -+ * -+ * @example -+ * ```ts -+ * editor.deleteAssets(['asset1', 'asset2']) -+ * ``` -+ * -+ * @param ids - The assets to delete. -+ * -+ * @public -+ */ -+ deleteAssets(assets: TLAsset[] | TLAssetId[]): this; -+ /** -+ * Get an asset by its id. -+ * -+ * @example -+ * ```ts -+ * editor.getAsset('asset1') -+ * ``` -+ * -+ * @param asset - The asset (or asset id) to get. -+ * -+ * @public -+ */ -+ getAsset(asset: TLAsset | TLAssetId): TLAsset | undefined; -+ resolveAssetUrl(assetId: null | TLAssetId, context: { -+ screenScale?: number; -+ shouldResolveToOriginal?: boolean; -+ }): Promise; -+ /** -+ * Upload an asset to the store's asset service, returning a URL that can be used to resolve the -+ * asset. -+ */ -+ uploadAsset(asset: TLAsset, file: File): Promise; -+ private _getShapeGeometryCache; -+ /** -+ * Get the geometry of a shape. -+ * -+ * @example -+ * ```ts -+ * editor.getShapeGeometry(myShape) -+ * editor.getShapeGeometry(myShapeId) -+ * ``` -+ * -+ * @param shape - The shape (or shape id) to get the geometry for. -+ * -+ * @public -+ */ -+ getShapeGeometry(shape: TLShape | TLShapeId): T; -+ /* Excluded from this release type: _getShapeHandlesCache */ -+ /** -+ * Get the handles (if any) for a shape. -+ * -+ * @example -+ * ```ts -+ * editor.getShapeHandles(myShape) -+ * editor.getShapeHandles(myShapeId) -+ * ``` -+ * -+ * @param shape - The shape (or shape id) to get the handles for. -+ * @public -+ */ -+ getShapeHandles(shape: T | T['id']): TLHandle[] | undefined; -+ /** -+ * Get the local transform for a shape as a matrix model. This transform reflects both its -+ * translation (x, y) from from either its parent's top left corner, if the shape's parent is -+ * another shape, or else from the 0,0 of the page, if the shape's parent is the page; and the -+ * shape's rotation. -+ * -+ * @example -+ * ```ts -+ * editor.getShapeLocalTransform(myShape) -+ * ``` -+ * -+ * @param shape - The shape to get the local transform for. -+ * -+ * @public -+ */ -+ getShapeLocalTransform(shape: TLShape | TLShapeId): Mat; -+ /* Excluded from this release type: _getShapePageTransformCache */ -+ /** -+ * Get the local transform of a shape's parent as a matrix model. -+ * -+ * @example -+ * ```ts -+ * editor.getShapeParentTransform(myShape) -+ * ``` -+ * -+ * @param shape - The shape (or shape id) to get the parent transform for. -+ * -+ * @public -+ */ -+ getShapeParentTransform(shape: TLShape | TLShapeId): Mat; -+ /** -+ * Get the transform of a shape in the current page space. -+ * -+ * @example -+ * ```ts -+ * editor.getShapePageTransform(myShape) -+ * editor.getShapePageTransform(myShapeId) -+ * ``` -+ * -+ * @param shape - The shape (or shape id) to get the page transform for. -+ * -+ * @public -+ */ -+ getShapePageTransform(shape: TLShape | TLShapeId): Mat; -+ /* Excluded from this release type: _getShapePageBoundsCache */ -+ /** -+ * Get the bounds of a shape in the current page space. -+ * -+ * @example -+ * ```ts -+ * editor.getShapePageBounds(myShape) -+ * editor.getShapePageBounds(myShapeId) -+ * ``` -+ * -+ * @param shape - The shape (or shape id) to get the bounds for. -+ * -+ * @public -+ */ -+ getShapePageBounds(shape: TLShape | TLShapeId): Box | undefined; -+ /* Excluded from this release type: _getShapeClipPathCache */ -+ /** -+ * Get the clip path for a shape. -+ * -+ * @example -+ * ```ts -+ * const clipPath = editor.getShapeClipPath(shape) -+ * const clipPath = editor.getShapeClipPath(shape.id) -+ * ``` -+ * -+ * @param shape - The shape (or shape id) to get the clip path for. -+ * -+ * @returns The clip path or undefined. -+ * -+ * @public -+ */ -+ getShapeClipPath(shape: TLShape | TLShapeId): string | undefined; -+ /* Excluded from this release type: _getShapeMaskCache */ -+ /** -+ * Get the mask (in the current page space) for a shape. -+ * -+ * @example -+ * ```ts -+ * const pageMask = editor.getShapeMask(shape.id) -+ * ``` -+ * -+ * @param id - The id of the shape to get the mask for. -+ * -+ * @returns The mask for the shape. -+ * -+ * @public -+ */ -+ getShapeMask(shape: TLShape | TLShapeId): undefined | VecLike[]; -+ /** -+ * Get the bounds of a shape in the current page space, incorporating any masks. For example, if the -+ * shape were the child of a frame and was half way out of the frame, the bounds would be the half -+ * of the shape that was in the frame. -+ * -+ * @example -+ * ```ts -+ * editor.getShapeMaskedPageBounds(myShape) -+ * editor.getShapeMaskedPageBounds(myShapeId) -+ * ``` -+ * -+ * @param shape - The shape to get the masked bounds for. -+ * -+ * @public -+ */ -+ getShapeMaskedPageBounds(shape: TLShape | TLShapeId): Box | undefined; -+ /* Excluded from this release type: _getShapeMaskedPageBoundsCache */ -+ /** -+ * Get the ancestors of a shape. -+ * -+ * @example -+ * ```ts -+ * const ancestors = editor.getShapeAncestors(myShape) -+ * const ancestors = editor.getShapeAncestors(myShapeId) -+ * ``` -+ * -+ * @param shape - The shape (or shape id) to get the ancestors for. -+ * -+ * @public -+ */ -+ getShapeAncestors(shape: TLShape | TLShapeId, acc?: TLShape[]): TLShape[]; -+ /** -+ * Find the first ancestor matching the given predicate -+ * -+ * @example -+ * ```ts -+ * const ancestor = editor.findShapeAncestor(myShape) -+ * const ancestor = editor.findShapeAncestor(myShape.id) -+ * const ancestor = editor.findShapeAncestor(myShape.id, (shape) => shape.type === 'frame') -+ * ``` -+ * -+ * @param shape - The shape to check the ancestors for. -+ * -+ * @public -+ */ -+ findShapeAncestor(shape: TLShape | TLShapeId, predicate: (parent: TLShape) => boolean): TLShape | undefined; -+ /** -+ * Returns true if the the given shape has the given ancestor. -+ * -+ * @param shape - The shape. -+ * @param ancestorId - The id of the ancestor. -+ * -+ * @public -+ */ -+ hasAncestor(shape: TLShape | TLShapeId | undefined, ancestorId: TLShapeId): boolean; -+ /** -+ * Get the common ancestor of two or more shapes that matches a predicate. -+ * -+ * @param shapes - The shapes (or shape ids) to check. -+ * @param predicate - The predicate to match. -+ */ -+ findCommonAncestor(shapes: TLShape[] | TLShapeId[], predicate?: (shape: TLShape) => boolean): TLShapeId | undefined; -+ /** -+ * Check whether a shape or its parent is locked. -+ * -+ * @param shape - The shape (or shape id) to check. -+ * -+ * @public -+ */ -+ isShapeOrAncestorLocked(shape?: TLShape): boolean; -+ isShapeOrAncestorLocked(id?: TLShapeId): boolean; -+ private _notVisibleShapes; -+ /** -+ * Get culled shapes. -+ * -+ * @public -+ */ -+ getCulledShapes(): Set; -+ /** -+ * The bounds of the current page (the common bounds of all of the shapes on the page). -+ * -+ * @public -+ */ -+ getCurrentPageBounds(): Box | undefined; -+ /** -+ * Get the top-most selected shape at the given point, ignoring groups. -+ * -+ * @param point - The point to check. -+ * -+ * @returns The top-most selected shape at the given point, or undefined if there is no shape at the point. -+ */ -+ getSelectedShapeAtPoint(point: VecLike): TLShape | undefined; -+ /** -+ * Get the shape at the current point. -+ * -+ * @param point - The point to check. -+ * @param opts - Options for the check: `hitInside` to check if the point is inside the shape, `margin` to check if the point is within a margin of the shape, `hitFrameInside` to check if the point is inside the frame, and `filter` to filter the shapes to check. -+ * -+ * @returns The shape at the given point, or undefined if there is no shape at the point. -+ */ -+ getShapeAtPoint(point: VecLike, opts?: { -+ filter?(shape: TLShape): boolean; -+ hitFrameInside?: boolean | undefined; -+ hitInside?: boolean | undefined; -+ hitLabels?: boolean | undefined; -+ hitLocked?: boolean | undefined; -+ margin?: number | undefined; -+ renderingOnly?: boolean | undefined; -+ }): TLShape | undefined; -+ /** -+ * Get the shapes, if any, at a given page point. -+ * -+ * @example -+ * ```ts -+ * editor.getShapesAtPoint({ x: 100, y: 100 }) -+ * editor.getShapesAtPoint({ x: 100, y: 100 }, { hitInside: true, exact: true }) -+ * ``` -+ * -+ * @param point - The page point to test. -+ * -+ * @public -+ */ -+ getShapesAtPoint(point: VecLike, opts?: { -+ hitInside?: boolean | undefined; -+ margin?: number | undefined; -+ }): TLShape[]; -+ /** -+ * Test whether a point (in the current page space) will will a shape. This method takes into account masks, -+ * such as when a shape is the child of a frame and is partially clipped by the frame. -+ * -+ * @example -+ * ```ts -+ * editor.isPointInShape({ x: 100, y: 100 }, myShape) -+ * ``` -+ * -+ * @param shape - The shape to test against. -+ * @param point - The page point to test (in the current page space). -+ * @param hitInside - Whether to count as a hit if the point is inside of a closed shape. -+ * -+ * @public -+ */ -+ isPointInShape(shape: TLShape | TLShapeId, point: VecLike, opts?: { -+ hitInside?: boolean | undefined; -+ margin?: number | undefined; -+ }): boolean; -+ /** -+ * Convert a point in the current page space to a point in the local space of a shape. For example, if a -+ * shape's page point were `{ x: 100, y: 100 }`, a page point at `{ x: 110, y: 110 }` would be at -+ * `{ x: 10, y: 10 }` in the shape's local space. -+ * -+ * @example -+ * ```ts -+ * editor.getPointInShapeSpace(myShape, { x: 100, y: 100 }) -+ * ``` -+ * -+ * @param shape - The shape to get the point in the local space of. -+ * @param point - The page point to get in the local space of the shape. -+ * -+ * @public -+ */ -+ getPointInShapeSpace(shape: TLShape | TLShapeId, point: VecLike): Vec; -+ /** -+ * Convert a delta in the current page space to a point in the local space of a shape's parent. -+ * -+ * @example -+ * ```ts -+ * editor.getPointInParentSpace(myShape.id, { x: 100, y: 100 }) -+ * ``` -+ * -+ * @param shape - The shape to get the point in the local space of. -+ * @param point - The page point to get in the local space of the shape. -+ * -+ * @public -+ */ -+ getPointInParentSpace(shape: TLShape | TLShapeId, point: VecLike): Vec; -+ /** -+ * An array containing all of the shapes in the current page. -+ * -+ * @public -+ */ -+ getCurrentPageShapes(): TLShape[]; -+ /** -+ * An array containing all of the shapes in the current page, sorted in z-index order (accounting -+ * for nested shapes): e.g. A, B, BA, BB, C. -+ * -+ * @public -+ */ -+ getCurrentPageShapesSorted(): TLShape[]; -+ /** -+ * An array containing all of the rendering shapes in the current page, sorted in z-index order (accounting -+ * for nested shapes): e.g. A, B, BA, BB, C. -+ * -+ * @public -+ */ -+ getCurrentPageRenderingShapesSorted(): TLShape[]; -+ /** -+ * Get whether a shape matches the type of a TLShapeUtil. -+ * -+ * @example -+ * ```ts -+ * const isArrowShape = isShapeOfType(someShape, 'arrow') -+ * ``` -+ * -+ * @param util - the TLShapeUtil constructor to test against -+ * @param shape - the shape to test -+ * -+ * @public -+ */ -+ isShapeOfType(shape: TLUnknownShape, type: T['type']): shape is T; -+ isShapeOfType(shapeId: TLUnknownShape['id'], type: T['type']): shapeId is T['id']; -+ /** -+ * Get a shape by its id. -+ * -+ * @example -+ * ```ts -+ * editor.getShape('box1') -+ * ``` -+ * -+ * @param id - The id of the shape to get. -+ * -+ * @public -+ */ -+ getShape(shape: TLParentId | TLShape): T | undefined; -+ /** -+ * Get the parent shape for a given shape. Returns undefined if the shape is the direct child of -+ * the page. -+ * -+ * @example -+ * ```ts -+ * editor.getShapeParent(myShape) -+ * ``` -+ * -+ * @public -+ */ -+ getShapeParent(shape?: TLShape | TLShapeId): TLShape | undefined; -+ /* Excluded from this release type: getShapeNearestSibling */ -+ /** -+ * Get whether the given shape is the descendant of the given page. -+ * -+ * @example -+ * ```ts -+ * editor.isShapeInPage(myShape) -+ * editor.isShapeInPage(myShape, 'page1') -+ * ``` -+ * -+ * @param shape - The shape to check. -+ * @param pageId - The id of the page to check against. Defaults to the current page. -+ * -+ * @public -+ */ -+ isShapeInPage(shape: TLShape | TLShapeId, pageId?: TLPageId): boolean; -+ /** -+ * Get the id of the containing page for a given shape. -+ * -+ * @param shape - The shape to get the page id for. -+ * -+ * @returns The id of the page that contains the shape, or undefined if the shape is undefined. -+ * -+ * @public -+ */ -+ getAncestorPageId(shape?: TLShape | TLShapeId): TLPageId | undefined; -+ /* Excluded from this release type: _parentIdsToChildIds */ -+ /** -+ * Reparent shapes to a new parent. This operation preserves the shape's current page positions / -+ * rotations. -+ * -+ * @example -+ * ```ts -+ * editor.reparentShapes([box1, box2], 'frame1') -+ * editor.reparentShapes([box1.id, box2.id], 'frame1') -+ * editor.reparentShapes([box1.id, box2.id], 'frame1', 4) -+ * ``` -+ * -+ * @param shapes - The shapes (or shape ids) of the shapes to reparent. -+ * @param parentId - The id of the new parent shape. -+ * @param insertIndex - The index to insert the children. -+ * -+ * @public -+ */ -+ reparentShapes(shapes: TLShape[] | TLShapeId[], parentId: TLParentId, insertIndex?: IndexKey): this; -+ /** -+ * Get the index above the highest child of a given parent. -+ * -+ * @param parentId - The id of the parent. -+ * -+ * @returns The index. -+ * -+ * @public -+ */ -+ getHighestIndexForParent(parent: TLPage | TLParentId | TLShape): IndexKey; -+ /** -+ * Get an array of all the children of a shape. -+ * -+ * @example -+ * ```ts -+ * editor.getSortedChildIdsForParent('frame1') -+ * ``` -+ * -+ * @param parentId - The id of the parent shape. -+ * -+ * @public -+ */ -+ getSortedChildIdsForParent(parent: TLPage | TLParentId | TLShape): TLShapeId[]; -+ /** -+ * Run a visitor function for all descendants of a shape. -+ * -+ * @example -+ * ```ts -+ * editor.visitDescendants('frame1', myCallback) -+ * ``` -+ * -+ * @param parentId - The id of the parent shape. -+ * @param visitor - The visitor function. -+ * -+ * @public -+ */ -+ visitDescendants(parent: TLPage | TLParentId | TLShape, visitor: (id: TLShapeId) => false | void): this; -+ /** -+ * Get the shape ids of all descendants of the given shapes (including the shapes themselves). IDs are returned in z-index order. -+ * -+ * @param ids - The ids of the shapes to get descendants of. -+ * -+ * @returns The descendant ids. -+ * -+ * @public -+ */ -+ getShapeAndDescendantIds(ids: TLShapeId[]): Set; -+ /** -+ * Get the shape that some shapes should be dropped on at a given point. -+ * -+ * @param point - The point to find the parent for. -+ * @param droppingShapes - The shapes that are being dropped. -+ * -+ * @returns The shape to drop on. -+ * -+ * @public -+ */ -+ getDroppingOverShape(point: VecLike, droppingShapes?: TLShape[]): TLUnknownShape | undefined; -+ /** -+ * Get the shape that should be selected when you click on a given shape, assuming there is -+ * nothing already selected. It will not return anything higher than or including the current -+ * focus layer. -+ * -+ * @param shape - The shape to get the outermost selectable shape for. -+ * @param filter - A function to filter the selectable shapes. -+ * -+ * @returns The outermost selectable shape. -+ * -+ * @public -+ */ -+ getOutermostSelectableShape(shape: TLShape | TLShapeId, filter?: (shape: TLShape) => boolean): TLShape; -+ private _getBindingsIndexCache; -+ /** -+ * Get a binding from the store by its ID if it exists. -+ */ -+ getBinding(id: TLBindingId): TLBinding | undefined; -+ /** -+ * Get all bindings of a certain type _from_ a particular shape. These are the bindings whose -+ * `fromId` matched the shape's ID. -+ */ -+ getBindingsFromShape(shape: TLShape | TLShapeId, type: Binding['type']): Binding[]; -+ /** -+ * Get all bindings of a certain type _to_ a particular shape. These are the bindings whose -+ * `toId` matches the shape's ID. -+ */ -+ getBindingsToShape(shape: TLShape | TLShapeId, type: Binding['type']): Binding[]; -+ /** -+ * Get all bindings involving a particular shape. This includes bindings where the shape is the -+ * `fromId` or `toId`. If a type is provided, only bindings of that type are returned. -+ */ -+ getBindingsInvolvingShape(shape: TLShape | TLShapeId, type?: Binding['type']): Binding[]; -+ /** -+ * Create bindings from a list of partial bindings. You can omit the ID and most props of a -+ * binding, but the `type`, `toId`, and `fromId` must all be provided. -+ */ -+ createBindings(partials: TLBindingCreate[]): this; -+ /** -+ * Create a single binding from a partial. You can omit the ID and most props of a binding, but -+ * the `type`, `toId`, and `fromId` must all be provided. -+ */ -+ createBinding(partial: TLBindingCreate): this; -+ /** -+ * Update bindings from a list of partial bindings. Each partial must include an ID, which will -+ * be used to match the binding to it's existing record. If there is no existing record, that -+ * binding is skipped. The changes from the partial are merged into the existing record. -+ */ -+ updateBindings(partials: (null | TLBindingUpdate | undefined)[]): this; -+ /** -+ * Update a binding from a partial binding. Each partial must include an ID, which will be used -+ * to match the binding to it's existing record. If there is no existing record, that binding is -+ * skipped. The changes from the partial are merged into the existing record. -+ */ -+ updateBinding(partial: TLBindingUpdate): this; -+ /** -+ * Delete several bindings by their IDs. If a binding ID doesn't exist, it's ignored. -+ */ -+ deleteBindings(bindings: (TLBinding | TLBindingId)[], { isolateShapes }?: { -+ isolateShapes?: boolean | undefined; -+ }): this; -+ /** -+ * Delete a binding by its ID. If the binding doesn't exist, it's ignored. -+ */ -+ deleteBinding(binding: TLBinding | TLBindingId, opts?: Parameters[1]): this; -+ canBindShapes({ fromShape, toShape, binding, }: { -+ binding: { -+ type: TLBinding['type']; -+ } | TLBinding | TLBinding['type']; -+ fromShape: { -+ type: TLShape['type']; -+ } | TLShape | TLShape['type']; -+ toShape: { -+ type: TLShape['type']; -+ } | TLShape | TLShape['type']; -+ }): boolean; -+ /** -+ * Rotate shapes by a delta in radians. -+ * -+ * @example -+ * ```ts -+ * editor.rotateShapesBy(editor.getSelectedShapeIds(), Math.PI) -+ * editor.rotateShapesBy(editor.getSelectedShapeIds(), Math.PI / 2) -+ * ``` -+ * -+ * @param shapes - The shapes (or shape ids) of the shapes to move. -+ * @param delta - The delta in radians to apply to the selection rotation. -+ */ -+ rotateShapesBy(shapes: TLShape[] | TLShapeId[], delta: number, opts?: { -+ center?: VecLike; -+ }): this; -+ private getChangesToTranslateShape; -+ /** -+ * Move shapes by a delta. -+ * -+ * @example -+ * ```ts -+ * editor.nudgeShapes(['box1', 'box2'], { x: 8, y: 8 }) -+ * ``` -+ * -+ * @param shapes - The shapes (or shape ids) to move. -+ * @param direction - The direction in which to move the shapes. -+ * @param historyOptions - The history options for the change. -+ */ -+ nudgeShapes(shapes: TLShape[] | TLShapeId[], offset: VecLike): this; -+ /** -+ * Duplicate shapes. -+ * -+ * @example -+ * ```ts -+ * editor.duplicateShapes(['box1', 'box2'], { x: 8, y: 8 }) -+ * editor.duplicateShapes(editor.getSelectedShapes(), { x: 8, y: 8 }) -+ * ``` -+ * -+ * @param shapes - The shapes (or shape ids) to duplicate. -+ * @param offset - The offset (in pixels) to apply to the duplicated shapes. -+ * -+ * @public -+ */ -+ duplicateShapes(shapes: TLShape[] | TLShapeId[], offset?: VecLike): this; -+ /** -+ * Move shapes to page. -+ * -+ * @example -+ * ```ts -+ * editor.moveShapesToPage(['box1', 'box2'], 'page1') -+ * ``` -+ * -+ * @param shapes - The shapes (or shape ids) of the shapes to move. -+ * @param pageId - The id of the page where the shapes will be moved. -+ * -+ * @public -+ */ -+ moveShapesToPage(shapes: TLShape[] | TLShapeId[], pageId: TLPageId): this; -+ /** -+ * Toggle the lock state of one or more shapes. If there is a mix of locked and unlocked shapes, all shapes will be locked. -+ * -+ * @param shapes - The shapes (or shape ids) to toggle. -+ * -+ * @public -+ */ -+ toggleLock(shapes: TLShape[] | TLShapeId[]): this; -+ /** -+ * Send shapes to the back of the page's object list. -+ * -+ * @example -+ * ```ts -+ * editor.sendToBack(['id1', 'id2']) -+ * editor.sendToBack(box1, box2) -+ * ``` -+ * -+ * @param shapes - The shapes (or shape ids) to move. -+ * -+ * @public -+ */ -+ sendToBack(shapes: TLShape[] | TLShapeId[]): this; -+ /** -+ * Send shapes backward in the page's object list. -+ * -+ * @example -+ * ```ts -+ * editor.sendBackward(['id1', 'id2']) -+ * editor.sendBackward([box1, box2]) -+ * ``` -+ * -+ * @param shapes - The shapes (or shape ids) to move. -+ * -+ * @public -+ */ -+ sendBackward(shapes: TLShape[] | TLShapeId[]): this; -+ /** -+ * Bring shapes forward in the page's object list. -+ * -+ * @example -+ * ```ts -+ * editor.bringForward(['id1', 'id2']) -+ * editor.bringForward(box1, box2) -+ * ``` -+ * -+ * @param shapes - The shapes (or shape ids) to move. -+ * -+ * @public -+ */ -+ bringForward(shapes: TLShape[] | TLShapeId[]): this; -+ /** -+ * Bring shapes to the front of the page's object list. -+ * -+ * @example -+ * ```ts -+ * editor.bringToFront(['id1', 'id2']) -+ * editor.bringToFront([box1, box2]) -+ * ``` -+ * -+ * @param shapes - The shapes (or shape ids) to move. -+ * -+ * @public -+ */ -+ bringToFront(shapes: TLShape[] | TLShapeId[]): this; -+ /** -+ * Flip shape positions. -+ * -+ * @example -+ * ```ts -+ * editor.flipShapes([box1, box2], 'horizontal', 32) -+ * editor.flipShapes(editor.getSelectedShapeIds(), 'horizontal', 32) -+ * ``` -+ * -+ * @param shapes - The ids of the shapes to flip. -+ * @param operation - Whether to flip horizontally or vertically. -+ * -+ * @public -+ */ -+ flipShapes(shapes: TLShape[] | TLShapeId[], operation: 'horizontal' | 'vertical'): this; -+ /** -+ * Stack shape. -+ * -+ * @example -+ * ```ts -+ * editor.stackShapes([box1, box2], 'horizontal', 32) -+ * editor.stackShapes(editor.getSelectedShapeIds(), 'horizontal', 32) -+ * ``` -+ * -+ * @param shapes - The shapes (or shape ids) to stack. -+ * @param operation - Whether to stack horizontally or vertically. -+ * @param gap - The gap to leave between shapes. -+ * -+ * @public -+ */ -+ stackShapes(shapes: TLShape[] | TLShapeId[], operation: 'horizontal' | 'vertical', gap: number): this; -+ /** -+ * Pack shapes into a grid centered on their current position. Based on potpack (https://github.com/mapbox/potpack). -+ * -+ * @example -+ * ```ts -+ * editor.packShapes([box1, box2], 32) -+ * editor.packShapes(editor.getSelectedShapeIds(), 32) -+ * ``` -+ * -+ * -+ * @param shapes - The shapes (or shape ids) to pack. -+ * @param gap - The padding to apply to the packed shapes. Defaults to 16. -+ */ -+ packShapes(shapes: TLShape[] | TLShapeId[], gap: number): this; -+ /** -+ * Align shape positions. -+ * -+ * @example -+ * ```ts -+ * editor.alignShapes([box1, box2], 'left') -+ * editor.alignShapes(editor.getSelectedShapeIds(), 'left') -+ * ``` -+ * -+ * @param shapes - The shapes (or shape ids) to align. -+ * @param operation - The align operation to apply. -+ * -+ * @public -+ */ -+ alignShapes(shapes: TLShape[] | TLShapeId[], operation: 'bottom' | 'center-horizontal' | 'center-vertical' | 'left' | 'right' | 'top'): this; -+ /** -+ * Distribute shape positions. -+ * -+ * @example -+ * ```ts -+ * editor.distributeShapes([box1, box2], 'horizontal') -+ * editor.distributeShapes(editor.getSelectedShapeIds(), 'horizontal') -+ * ``` -+ * -+ * @param shapes - The shapes (or shape ids) to distribute. -+ * @param operation - Whether to distribute shapes horizontally or vertically. -+ * -+ * @public -+ */ -+ distributeShapes(shapes: TLShape[] | TLShapeId[], operation: 'horizontal' | 'vertical'): this; -+ /** -+ * Stretch shape sizes and positions to fill their common bounding box. -+ * -+ * @example -+ * ```ts -+ * editor.stretchShapes([box1, box2], 'horizontal') -+ * editor.stretchShapes(editor.getSelectedShapeIds(), 'horizontal') -+ * ``` -+ * -+ * @param shapes - The shapes (or shape ids) to stretch. -+ * @param operation - Whether to stretch shapes horizontally or vertically. -+ * -+ * @public -+ */ -+ stretchShapes(shapes: TLShape[] | TLShapeId[], operation: 'horizontal' | 'vertical'): this; -+ /** -+ * Resize a shape. -+ * -+ * @param id - The id of the shape to resize. -+ * @param scale - The scale factor to apply to the shape. -+ * @param options - Additional options. -+ * -+ * @public -+ */ -+ resizeShape(shape: TLShape | TLShapeId, scale: VecLike, options?: TLResizeShapeOptions): this; -+ /* Excluded from this release type: _scalePagePoint */ -+ /* Excluded from this release type: _resizeUnalignedShape */ -+ /** -+ * Get the initial meta value for a shape. -+ * -+ * @example -+ * ```ts -+ * editor.getInitialMetaForShape = (shape) => { -+ * if (shape.type === 'note') { -+ * return { createdBy: myCurrentUser.id } -+ * } -+ * } -+ * ``` -+ * -+ * @param shape - The shape to get the initial meta for. -+ * -+ * @public -+ */ -+ getInitialMetaForShape(_shape: TLShape): JsonObject; -+ /** -+ * Create a single shape. -+ * -+ * @example -+ * ```ts -+ * editor.createShape(myShape) -+ * editor.createShape({ id: 'box1', type: 'text', props: { text: "ok" } }) -+ * ``` -+ * -+ * @param shape - The shape (or shape partial) to create. -+ * -+ * @public -+ */ -+ createShape(shape: OptionalKeys, 'id'>): this; -+ /** -+ * Create shapes. -+ * -+ * @example -+ * ```ts -+ * editor.createShapes([myShape]) -+ * editor.createShapes([{ id: 'box1', type: 'text', props: { text: "ok" } }]) -+ * ``` -+ * -+ * @param shapes - The shapes (or shape partials) to create. -+ * @param select - Whether to select the created shapes. Defaults to false. -+ * -+ * @public -+ */ -+ createShapes(shapes: OptionalKeys, 'id'>[]): this; -+ private animatingShapes; -+ /** -+ * Animate a shape. -+ * -+ * @example -+ * ```ts -+ * editor.animateShape({ id: 'box1', type: 'box', x: 100, y: 100 }) -+ * editor.animateShape({ id: 'box1', type: 'box', x: 100, y: 100 }, { animation: { duration: 100, ease: t => t*t } }) -+ * ``` -+ * -+ * @param partial - The shape partial to update. -+ * @param options - The animation's options. -+ * -+ * @public -+ */ -+ animateShape(partial: null | TLShapePartial | undefined, opts?: TLCameraMoveOptions): this; -+ /** -+ * Animate shapes. -+ * -+ * @example -+ * ```ts -+ * editor.animateShapes([{ id: 'box1', type: 'box', x: 100, y: 100 }]) -+ * editor.animateShapes([{ id: 'box1', type: 'box', x: 100, y: 100 }], { animation: { duration: 100, ease: t => t*t } }) -+ * ``` -+ * -+ * @param partials - The shape partials to update. -+ * @param options - The animation's options. -+ * -+ * @public -+ */ -+ animateShapes(partials: (null | TLShapePartial | undefined)[], opts?: TLCameraMoveOptions): this; -+ /** -+ * Create a group containing the provided shapes. -+ * -+ * @example -+ * ```ts -+ * editor.groupShapes([myShape, myOtherShape]) -+ * editor.groupShapes([myShape, myOtherShape], { groupId: myGroupId, select: false }) -+ * ``` -+ * -+ * @param shapes - The shapes (or shape ids) to group. Defaults to the selected shapes. -+ * @param options - An options object. -+ * -+ * @public -+ */ -+ groupShapes(shapes: TLShape[], options?: Partial<{ -+ groupId: TLShapeId; -+ select: boolean; -+ }>): this; -+ groupShapes(ids: TLShapeId[], options?: Partial<{ -+ groupId: TLShapeId; -+ select: boolean; -+ }>): this; -+ /** -+ * Ungroup some shapes. -+ * -+ * @example -+ * ```ts -+ * editor.ungroupShapes([myGroup, myOtherGroup]) -+ * editor.ungroupShapes([myGroup], { select: false }) -+ * ``` -+ * -+ * @param shapes - The group shapes (or shape ids) to ungroup. -+ * @param options - An options object. -+ * -+ * @public -+ */ -+ ungroupShapes(ids: TLShapeId[], options?: Partial<{ -+ select: boolean; -+ }>): this; -+ ungroupShapes(shapes: TLShape[], options?: Partial<{ -+ select: boolean; -+ }>): this; -+ /** -+ * Update a shape using a partial of the shape. -+ * -+ * @example -+ * ```ts -+ * editor.updateShape({ id: 'box1', type: 'geo', props: { w: 100, h: 100 } }) -+ * ``` -+ * -+ * @param partial - The shape partial to update. -+ * -+ * @public -+ */ -+ updateShape(partial: null | TLShapePartial | undefined): this; -+ /** -+ * Update shapes using partials of each shape. -+ * -+ * @example -+ * ```ts -+ * editor.updateShapes([{ id: 'box1', type: 'geo', props: { w: 100, h: 100 } }]) -+ * ``` -+ * -+ * @param partials - The shape partials to update. -+ * -+ * @public -+ */ -+ updateShapes(partials: (null | TLShapePartial | undefined)[]): this; -+ /* Excluded from this release type: _updateShapes */ -+ /* Excluded from this release type: _getUnlockedShapeIds */ -+ /** -+ * Delete shapes. -+ * -+ * @example -+ * ```ts -+ * editor.deleteShapes(['box1', 'box2']) -+ * ``` -+ * -+ * @param ids - The ids of the shapes to delete. -+ * -+ * @public -+ */ -+ deleteShapes(ids: TLShapeId[]): this; -+ deleteShapes(shapes: TLShape[]): this; -+ /** -+ * Delete a shape. -+ * -+ * @example -+ * ```ts -+ * editor.deleteShape(shape.id) -+ * ``` -+ * -+ * @param id - The id of the shape to delete. -+ * -+ * @public -+ */ -+ deleteShape(id: TLShapeId): this; -+ deleteShape(shape: TLShape): this; -+ /* Excluded from this release type: _extractSharedStyles */ -+ /* Excluded from this release type: _getSelectionSharedStyles */ -+ /** -+ * Get the style for the next shape. -+ * -+ * @example -+ * ```ts -+ * const color = editor.getStyleForNextShape(DefaultColorStyle) -+ * ``` -+ * -+ * @param style - The style to get. -+ * -+ * @public */ -+ getStyleForNextShape(style: StyleProp): T; -+ getShapeStyleIfExists(shape: TLShape, style: StyleProp): T | undefined; -+ /** -+ * A map of all the current styles either in the current selection, or that are relevant to the -+ * current tool. -+ * -+ * @example -+ * ```ts -+ * const color = editor.getSharedStyles().get(DefaultColorStyle) -+ * if (color && color.type === 'shared') { -+ * print('All selected shapes have the same color:', color.value) -+ * } -+ * ``` -+ * -+ * @public -+ */ -+ getSharedStyles(): ReadonlySharedStyleMap; -+ /** -+ * Get the currently selected shared opacity. -+ * If any shapes are selected, this returns the shared opacity of the selected shapes. -+ * Otherwise, this returns the chosen opacity for the next shape. -+ * -+ * @public -+ */ -+ getSharedOpacity(): SharedStyle; -+ /** -+ * Set the opacity for the next shapes. This will effect subsequently created shapes. -+ * -+ * @example -+ * ```ts -+ * editor.setOpacityForNextShapes(0.5) -+ * ``` -+ * -+ * @param opacity - The opacity to set. Must be a number between 0 and 1 inclusive. -+ * @param historyOptions - The history options for the change. -+ */ -+ setOpacityForNextShapes(opacity: number, historyOptions?: TLHistoryBatchOptions): this; -+ /** -+ * Set the current opacity. This will effect any selected shapes. -+ * -+ * @example -+ * ```ts -+ * editor.setOpacityForSelectedShapes(0.5) -+ * ``` -+ * -+ * @param opacity - The opacity to set. Must be a number between 0 and 1 inclusive. -+ */ -+ setOpacityForSelectedShapes(opacity: number): this; -+ /** -+ * Set the value of a {@link @tldraw/tlschema#StyleProp} for the next shapes. This change will be applied to subsequently created shapes. -+ * -+ * @example -+ * ```ts -+ * editor.setStyleForNextShapes(DefaultColorStyle, 'red') -+ * editor.setStyleForNextShapes(DefaultColorStyle, 'red', { ephemeral: true }) -+ * ``` -+ * -+ * @param style - The style to set. -+ * @param value - The value to set. -+ * @param historyOptions - The history options for the change. -+ * -+ * @public -+ */ -+ setStyleForNextShapes(style: StyleProp, value: T, historyOptions?: TLHistoryBatchOptions): this; -+ /** -+ * Set the value of a {@link @tldraw/tlschema#StyleProp}. This change will be applied to the currently selected shapes. -+ * -+ * @example -+ * ```ts -+ * editor.setStyleForSelectedShapes(DefaultColorStyle, 'red') -+ * ``` -+ * -+ * @param style - The style to set. -+ * @param value - The value to set. -+ * @param historyOptions - The history options for the change. -+ * -+ * @public -+ */ -+ setStyleForSelectedShapes>(style: S, value: StylePropValue): this; -+ /* Excluded from this release type: externalAssetContentHandlers */ -+ /* Excluded from this release type: temporaryAssetPreview */ -+ /** -+ * Register an external asset handler. This handler will be called when the editor needs to -+ * create an asset for some external content, like an image/video file or a bookmark URL. For -+ * example, the 'file' type handler will be called when a user drops an image onto the canvas. -+ * -+ * The handler should extract any relevant metadata for the asset, upload it to blob storage -+ * using {@link Editor.uploadAsset} if needed, and return the asset with the metadata & uploaded -+ * URL. -+ * -+ * @example -+ * ```ts -+ * editor.registerExternalAssetHandler('file', myHandler) -+ * ``` -+ * -+ * @param type - The type of external content. -+ * @param handler - The handler to use for this content type. -+ * -+ * @public -+ */ -+ registerExternalAssetHandler(type: T, handler: ((info: TLExternalAssetContent & { -+ type: T; -+ }) => Promise) | null): this; -+ /** -+ * Register a temporary preview of an asset. This is useful for showing a ghost image of -+ * something that is being uploaded. Retrieve the placeholder with -+ * {@link Editor.getTemporaryAssetPreview}. Placeholders last for 3 minutes by default, but this -+ * can be configured using -+ * -+ * @example -+ * ```ts -+ * editor.createTemporaryAssetPreview(assetId, file) -+ * ``` -+ * -+ * @param assetId - The asset's id. -+ * @param file - The raw file. -+ * -+ * @public -+ */ -+ createTemporaryAssetPreview(assetId: TLAssetId, file: File): string | undefined; -+ /** -+ * Get temporary preview of an asset. This is useful for showing a ghost -+ * image of something that is being uploaded. -+ * -+ * @example -+ * ```ts -+ * editor.getTemporaryAssetPreview('someId') -+ * ``` -+ * -+ * @param assetId - The asset's id. -+ * -+ * @public -+ */ -+ getTemporaryAssetPreview(assetId: TLAssetId): string | undefined; -+ /** -+ * Get an asset for an external asset content type. -+ * -+ * @example -+ * ```ts -+ * const asset = await editor.getAssetForExternalContent({ type: 'file', file: myFile }) -+ * const asset = await editor.getAssetForExternalContent({ type: 'url', url: myUrl }) -+ * ``` -+ * -+ * @param info - Info about the external content. -+ * @returns The asset. -+ */ -+ getAssetForExternalContent(info: TLExternalAssetContent): Promise; -+ hasExternalAssetHandler(type: TLExternalAssetContent['type']): boolean; -+ /* Excluded from this release type: externalContentHandlers */ -+ /** -+ * Register an external content handler. This handler will be called when the editor receives -+ * external content of the provided type. For example, the 'image' type handler will be called -+ * when a user drops an image onto the canvas. -+ * -+ * @example -+ * ```ts -+ * editor.registerExternalContentHandler('text', myHandler) -+ * ``` -+ * @example -+ * ```ts -+ * editor.registerExternalContentHandler<'embed', MyEmbedType>('embed', myHandler) -+ * ``` -+ * -+ * @param type - The type of external content. -+ * @param handler - The handler to use for this content type. -+ * -+ * @public -+ */ -+ registerExternalContentHandler['type'], E>(type: T, handler: ((info: T extends TLExternalContent['type'] ? TLExternalContent & { -+ type: T; -+ } : TLExternalContent) => void) | null): this; -+ /** -+ * Handle external content, such as files, urls, embeds, or plain text which has been put into the app, for example by pasting external text or dropping external images onto canvas. -+ * -+ * @param info - Info about the external content. -+ */ -+ putExternalContent(info: TLExternalContent): Promise; -+ /** -+ * Get content that can be exported for the given shape ids. -+ * -+ * @param shapes - The shapes (or shape ids) to get content for. -+ * -+ * @returns The exported content. -+ * -+ * @public -+ */ -+ getContentFromCurrentPage(shapes: TLShape[] | TLShapeId[]): TLContent | undefined; -+ resolveAssetsInContent(content: TLContent | undefined): Promise; -+ /** -+ * Place content into the editor. -+ * -+ * @param content - The content. -+ * @param options - Options for placing the content. -+ * -+ * @public -+ */ -+ putContentOntoCurrentPage(content: TLContent, options?: { -+ point?: VecLike; -+ preserveIds?: boolean; -+ preservePosition?: boolean; -+ select?: boolean; -+ }): this; -+ /** -+ * Get an exported SVG element of the given shapes. -+ * -+ * @param ids - The shapes (or shape ids) to export. -+ * @param opts - Options for the export. -+ * -+ * @returns The SVG element. -+ * -+ * @public -+ */ -+ getSvgElement(shapes: TLShape[] | TLShapeId[], opts?: TLImageExportOptions): Promise<{ -+ height: number; -+ svg: SVGSVGElement; -+ width: number; -+ } | undefined>; -+ /** -+ * Get an exported SVG string of the given shapes. -+ * -+ * @param ids - The shapes (or shape ids) to export. -+ * @param opts - Options for the export. -+ * -+ * @returns The SVG element. -+ * -+ * @public -+ */ -+ getSvgString(shapes: TLShape[] | TLShapeId[], opts?: TLImageExportOptions): Promise<{ -+ height: number; -+ svg: string; -+ width: number; -+ } | undefined>; -+ /** @deprecated Use {@link Editor.getSvgString} or {@link Editor.getSvgElement} instead. */ -+ getSvg(shapes: TLShape[] | TLShapeId[], opts?: TLImageExportOptions): Promise; -+ /** -+ * The app's current input state. -+ * -+ * @public -+ */ -+ inputs: { -+ /** A set containing the currently pressed buttons. */ -+ buttons: Set; -+ /** A set containing the currently pressed keys. */ -+ keys: Set; -+ /** The most recent pointer down's position in screen space. */ -+ originScreenPoint: Vec; -+ /** The most recent pointer down's position in the current page space. */ -+ originPagePoint: Vec; -+ /** The most recent pointer position in screen space. */ -+ currentScreenPoint: Vec; -+ /** The most recent pointer position in the current page space. */ -+ currentPagePoint: Vec; -+ /** The previous pointer position in screen space. */ -+ previousScreenPoint: Vec; -+ /** The previous pointer position in the current page space. */ -+ previousPagePoint: Vec; -+ /** Velocity of mouse pointer, in pixels per millisecond */ -+ pointerVelocity: Vec; -+ /** Whether the alt or option key is currently pressed. */ -+ altKey: boolean; -+ /** Whether the control or command key is currently pressed. */ -+ ctrlKey: boolean; -+ /** Whether the input is from a pe. */ -+ isPen: boolean; -+ /** Whether the shift key is currently pressed. */ -+ shiftKey: boolean; -+ /** Whether the user is dragging. */ -+ isDragging: boolean; -+ /** Whether the user is editing. */ -+ isEditing: boolean; -+ /** Whether the user is panning. */ -+ isPanning: boolean; -+ /** Whether the user is pinching. */ -+ isPinching: boolean; -+ /** Whether the user is pointing. */ -+ isPointing: boolean; -+ /** Whether the user is spacebar panning. */ -+ isSpacebarPanning: boolean; -+ }; -+ /** -+ * Update the input points from a pointer, pinch, or wheel event. -+ * -+ * @param info - The event info. -+ */ -+ private _updateInputsFromEvent; -+ /** -+ * Dispatch a cancel event. -+ * -+ * @example -+ * ```ts -+ * editor.cancel() -+ * ``` -+ * -+ * @public -+ */ -+ cancel(): this; -+ /** -+ * Dispatch an interrupt event. -+ * -+ * @example -+ * ```ts -+ * editor.interrupt() -+ * ``` -+ * -+ * @public -+ */ -+ interrupt(): this; -+ /** -+ * Dispatch a complete event. -+ * -+ * @example -+ * ```ts -+ * editor.complete() -+ * ``` -+ * -+ * @public -+ */ -+ complete(): this; -+ /** -+ * Puts the editor into focused mode. -+ * -+ * This makes the editor eligible to receive keyboard events and some pointer events (move, wheel). -+ * -+ * @example -+ * ```ts -+ * editor.focus() -+ * ``` -+ * -+ * By default this also dispatches a 'focus' event to the container element. To prevent this, pass `focusContainer: false`. -+ * -+ * @example -+ * ```ts -+ * editor.focus({ focusContainer: false }) -+ * ``` -+ * -+ * @public -+ */ -+ focus({ focusContainer }?: { -+ focusContainer?: boolean | undefined; -+ }): this; -+ /** -+ * Switches off the editor's focused mode. -+ * -+ * This makes the editor ignore keyboard events and some pointer events (move, wheel). -+ * -+ * @example -+ * ```ts -+ * editor.blur() -+ * ``` -+ * By default this also dispatches a 'blur' event to the container element. To prevent this, pass `blurContainer: false`. -+ * -+ * @example -+ * ```ts -+ * editor.blur({ blurContainer: false }) -+ * ``` -+ * -+ * @public -+ */ -+ blur({ blurContainer }?: { -+ blurContainer?: boolean | undefined; -+ }): this; -+ /** -+ * @public -+ * @returns true if the editor is focused -+ */ -+ getIsFocused(): boolean; -+ /** -+ * @public -+ * @returns a snapshot of the store's UI and document state -+ */ -+ getSnapshot(): TLEditorSnapshot; -+ /** -+ * Loads a snapshot into the editor. -+ * @param snapshot - the snapshot to load -+ * @returns -+ */ -+ loadSnapshot(snapshot: Partial | TLStoreSnapshot, opts?: TLLoadSnapshotOptions): this; -+ private _zoomToFitPageContentAt100Percent; -+ private _navigateToDeepLink; -+ /** -+ * Handles navigating to the content specified by the query param in the given URL. -+ * -+ * Use {@link Editor#createDeepLink} to create a URL with a deep link query param. -+ * -+ * If no URL is provided, it will look for the param in the current `window.location.href`. -+ * -+ * @example -+ * ```ts -+ * editor.navigateToDeepLink() -+ * ``` -+ * -+ * The default parameter name is 'd'. You can override this by providing the `param` option. -+ * -+ * @example -+ * ```ts -+ * // disable page parameter and change viewport parameter to 'c' -+ * editor.navigateToDeepLink({ -+ * param: 'x', -+ * url: 'https://my-app.com/my-document?x=200.12.454.23.xyz123', -+ * }) -+ * ``` -+ * -+ * @param opts - Options for loading the state from the URL. -+ */ -+ navigateToDeepLink(opts?: { -+ param?: string; -+ url?: string | URL; -+ } | TLDeepLink): Editor; -+ /** -+ * Turns the given URL into a deep link by adding a query parameter. -+ * -+ * e.g. `https://my-app.com/my-document?d=100.100.200.200.xyz123` -+ * -+ * If no URL is provided, it will use the current `window.location.href`. -+ * -+ * @example -+ * ```ts -+ * // create a deep link to the current page + viewport -+ * navigator.clipboard.writeText(editor.createDeepLink()) -+ * ``` -+ * -+ * You can link to a particular set of shapes by providing a `to` parameter. -+ * -+ * @example -+ * ```ts -+ * // create a deep link to the set of currently selected shapes -+ * navigator.clipboard.writeText(editor.createDeepLink({ -+ * to: { type: 'selection', shapeIds: editor.getSelectedShapeIds() } -+ * })) -+ * ``` -+ * -+ * The default query param is 'd'. You can override this by providing a `param` parameter. -+ * -+ * @example -+ * ```ts -+ * // Use `x` as the param name instead -+ * editor.createDeepLink({ param: 'x' }) -+ * ``` -+ * -+ * @param opts - Options for adding the state to the URL. -+ * @returns the updated URL -+ */ -+ createDeepLink(opts?: { -+ param?: string; -+ to?: TLDeepLink; -+ url?: string | URL; -+ }): URL; -+ /** -+ * Register a listener for changes to a deep link for the current document. -+ * -+ * You'll typically want to use this indirectly via the {@link TldrawEditorBaseProps.deepLinks} prop on the `` component. -+ * -+ * By default this will update `window.location` in place, but you can provide a custom callback -+ * to handle state changes on your own. -+ * -+ * @example -+ * ```ts -+ * editor.registerDeepLinkListener({ -+ * onChange(url) { -+ * window.history.replaceState({}, document.title, url.toString()) -+ * } -+ * }) -+ * ``` -+ * -+ * You can also provide a custom URL to update, in which case you must also provide `onChange`. -+ * -+ * @example -+ * ```ts -+ * editor.registerDeepLinkListener({ -+ * getUrl: () => `https://my-app.com/my-document`, -+ * onChange(url) { -+ * setShareUrl(url.toString()) -+ * } -+ * }) -+ * ``` -+ * -+ * By default this will update with a debounce interval of 500ms, but you can provide a custom interval. -+ * -+ * @example -+ * ```ts -+ * editor.registerDeepLinkListener({ debounceMs: 1000 }) -+ * ``` -+ * The default parameter name is `d`. You can override this by providing a `param` option. -+ * -+ * @example -+ * ```ts -+ * editor.registerDeepLinkListener({ param: 'x' }) -+ * ``` -+ * @param opts - Options for setting up the listener. -+ * @returns a function that will stop the listener. -+ */ -+ registerDeepLinkListener(opts?: TLDeepLinkOptions): () => void; -+ /* Excluded from this release type: _clickManager */ -+ /** -+ * Prevent a double click event from firing the next time the user clicks -+ * -+ * @public -+ */ -+ cancelDoubleClick(): void; -+ /* Excluded from this release type: _prevCursor */ -+ /* Excluded from this release type: _shiftKeyTimeout */ -+ /* Excluded from this release type: _setShiftKeyTimeout */ -+ /* Excluded from this release type: _altKeyTimeout */ -+ /* Excluded from this release type: _setAltKeyTimeout */ -+ /* Excluded from this release type: _ctrlKeyTimeout */ -+ /* Excluded from this release type: _setCtrlKeyTimeout */ -+ /* Excluded from this release type: _restoreToolId */ -+ /* Excluded from this release type: _pinchStart */ -+ /* Excluded from this release type: _didPinch */ -+ /* Excluded from this release type: _selectedShapeIdsAtPointerDown */ -+ /* Excluded from this release type: _longPressTimeout */ -+ /* Excluded from this release type: capturedPointerId */ -+ /* Excluded from this release type: performanceTracker */ -+ /* Excluded from this release type: performanceTrackerTimeout */ -+ /** -+ * Dispatch an event to the editor. -+ * -+ * @example -+ * ```ts -+ * editor.dispatch(myPointerEvent) -+ * ``` -+ * -+ * @param info - The event info. -+ * -+ * @public -+ */ -+ dispatch(info: TLEventInfo): this; -+ private _pendingEventsForNextTick; -+ private _flushEventsForTick; -+ _flushEventForTick(info: TLEventInfo): this | undefined; -+ /* Excluded from this release type: maybeTrackPerformance */ -+} -+ -+export { EffectScheduler } -+ -+/** @public */ -+export declare class Ellipse2d extends Geometry2d { -+ config: Omit & { -+ height: number; -+ width: number; -+ }; -+ w: number; -+ h: number; -+ constructor(config: Omit & { -+ height: number; -+ width: number; -+ }); -+ _edges?: Edge2d[]; -+ get edges(): Edge2d[]; -+ getVertices(): any[]; -+ nearestPoint(A: Vec): Vec; -+ hitTestLineSegment(A: Vec, B: Vec): boolean; -+ getBounds(): Box; -+ getLength(): number; -+ getSvgPathData(first?: boolean): string; -+} -+ -+export { EMPTY_ARRAY } -+ -+/** @public */ -+export declare class EnvironmentManager { -+ editor: Editor; -+ constructor(editor: Editor); -+ /** -+ * Whether the editor is running in Safari. -+ * -+ * @public -+ */ -+ readonly isSafari: boolean; -+ /** -+ * Whether the editor is running on iOS. -+ * -+ * @public -+ */ -+ readonly isIos: boolean; -+ /** -+ * Whether the editor is running on iOS. -+ * -+ * @public -+ */ -+ readonly isChromeForIos: boolean; -+ /** -+ * Whether the editor is running on Firefox. -+ * -+ * @public -+ */ -+ readonly isFirefox: boolean; -+ /** -+ * Whether the editor is running on Android. -+ * -+ * @public -+ */ -+ readonly isAndroid: boolean; -+} -+ -+/** @public */ -+export declare class ErrorBoundary extends React_3.Component>, { -+ error: Error | null; -+}> { -+ static getDerivedStateFromError(error: Error): { -+ error: Error; -+ }; -+ state: { -+ error: null; -+ }; -+ componentDidCatch(error: unknown): void; -+ render(): boolean | JSX_2.Element | Iterable | null | number | string | undefined; -+} -+ -+/** @public @react */ -+export declare function ErrorScreen({ children }: LoadingScreenProps): JSX_2.Element; -+ -+/** @public */ -+export declare const EVENT_NAME_MAP: Record, keyof TLEventHandlers>; -+ -+/* Excluded from this release type: extractSessionStateFromLegacySnapshot */ -+ -+/* Excluded from this release type: featureFlags */ -+ -+/** @public */ -+export declare interface GapsSnapIndicator { -+ id: string; -+ type: 'gaps'; -+ direction: 'horizontal' | 'vertical'; -+ gaps: Array<{ -+ endEdge: [VecLike, VecLike]; -+ startEdge: [VecLike, VecLike]; -+ }>; -+} -+ -+/** @public */ -+export declare abstract class Geometry2d { -+ isFilled: boolean; -+ isClosed: boolean; -+ isLabel: boolean; -+ debugColor?: string; -+ ignore?: boolean; -+ constructor(opts: Geometry2dOptions); -+ abstract getVertices(): Vec[]; -+ abstract nearestPoint(point: Vec): Vec; -+ hitTestPoint(point: Vec, margin?: number, hitInside?: boolean): boolean; -+ distanceToPoint(point: Vec, hitInside?: boolean): number; -+ distanceToLineSegment(A: Vec, B: Vec): number; -+ hitTestLineSegment(A: Vec, B: Vec, distance?: number): boolean; -+ nearestPointOnLineSegment(A: Vec, B: Vec): Vec; -+ isPointInBounds(point: Vec, margin?: number): boolean; -+ private _vertices; -+ get vertices(): Vec[]; -+ getBounds(): Box; -+ private _bounds; -+ get bounds(): Box; -+ get center(): Vec; -+ private _area; -+ get area(): number; -+ getArea(): number; -+ toSimpleSvgPath(): string; -+ private _length?; -+ get length(): number; -+ getLength(): number; -+ abstract getSvgPathData(first: boolean): string; -+} -+ -+/** @public */ -+export declare interface Geometry2dOptions { -+ isFilled: boolean; -+ isClosed: boolean; -+ isLabel?: boolean; -+ debugColor?: string; -+ ignore?: boolean; -+} -+ -+/** -+ * Get the measure of an arc. -+ * -+ * @param A - The angle from center to arc's start point (A) on the circle -+ * @param B - The angle from center to arc's end point (B) on the circle -+ * @param sweepFlag - 1 if the arc is clockwise, 0 if counter-clockwise -+ * @param largeArcFlag - 1 if the arc is greater than 180 degrees, 0 if less than 180 degrees -+ * -+ * @returns The measure of the arc, negative if counter-clockwise -+ * -+ * @public -+ */ -+export declare function getArcMeasure(A: number, B: number, sweepFlag: number, largeArcFlag: number): number; -+ -+/** @public */ -+export declare function getCursor(cursor: TLCursorType, rotation?: number, color?: string): string; -+ -+/** @public */ -+export declare function getDefaultCdnBaseUrl(): string; -+ -+/** @public */ -+export declare function getFreshUserPreferences(): TLUserPreferences; -+ -+/** -+ * Get an incremented name (e.g. New page (2)) from a name (e.g. New page), based on an array of -+ * existing names. -+ * -+ * @param name - The name to increment. -+ * @param others - The array of existing names. -+ * @public -+ */ -+export declare function getIncrementedName(name: string, others: string[]): string; -+ -+/** @public */ -+export declare function getPerfectDashProps(totalLength: number, strokeWidth: number, opts?: Partial<{ -+ closed: boolean; -+ end: 'none' | 'outset' | 'skip'; -+ forceSolid: boolean; -+ lengthRatio: number; -+ snap: number; -+ start: 'none' | 'outset' | 'skip'; -+ style: TLDefaultDashStyle; -+}>): { -+ strokeDasharray: string; -+ strokeDashoffset: string; -+}; -+ -+/** @public */ -+export declare function getPointerInfo(e: PointerEvent | React.PointerEvent): { -+ altKey: boolean; -+ button: number; -+ ctrlKey: boolean; -+ isPen: boolean; -+ point: { -+ x: number; -+ y: number; -+ z: number; -+ }; -+ pointerId: number; -+ shiftKey: boolean; -+}; -+ -+/** -+ * Returns the t value of the point on the arc. -+ * -+ * @param mAB - The measure of the arc from A to B, negative if counter-clockwise -+ * @param A - The angle from center to arc's start point (A) on the circle -+ * @param B - The angle from center to arc's end point (B) on the circle -+ * @param P - The angle on the circle (P) to find the t value for -+ * -+ * @returns The t value of the point on the arc, with 0 being the start and 1 being the end -+ * -+ * @public -+ */ -+export declare function getPointInArcT(mAB: number, A: number, B: number, P: number): number; -+ -+/** -+ * Get a point on the perimeter of a circle. -+ * -+ * @param center - The center of the circle. -+ * @param r - The radius of the circle. -+ * @param a - The angle in radians. -+ * @public -+ */ -+export declare function getPointOnCircle(center: VecLike, r: number, a: number): Vec; -+ -+/** @public */ -+export declare function getPointsOnArc(startPoint: VecLike, endPoint: VecLike, center: null | VecLike, radius: number, numPoints: number): Vec[]; -+ -+/** @public */ -+export declare function getPolygonVertices(width: number, height: number, sides: number): Vec[]; -+ -+/* Excluded from this release type: getRotationSnapshot */ -+ -+/** @public */ -+export declare function getSnapshot(store: TLStore): TLEditorSnapshot; -+ -+/** -+ * Turn an array of points into a path of quadradic curves. -+ * -+ * @param points - The points returned from perfect-freehand -+ * @param closed - Whether the stroke is closed -+ * -+ * @public -+ */ -+export declare function getSvgPathFromPoints(points: VecLike[], closed?: boolean): string; -+ -+/** @public */ -+export declare function getUserPreferences(): TLUserPreferences; -+ -+/** @public */ -+export declare class Group2d extends Geometry2d { -+ children: Geometry2d[]; -+ ignoredChildren: Geometry2d[]; -+ constructor(config: Omit & { -+ children: Geometry2d[]; -+ }); -+ getVertices(): Vec[]; -+ nearestPoint(point: Vec): Vec; -+ distanceToPoint(point: Vec, hitInside?: boolean): number; -+ hitTestPoint(point: Vec, margin: number, hitInside: boolean): boolean; -+ hitTestLineSegment(A: Vec, B: Vec, zoom: number): boolean; -+ getArea(): number; -+ toSimpleSvgPath(): string; -+ getLength(): number; -+ getSvgPathData(): string; -+} -+ -+/** @public */ -+export declare class GroupShapeUtil extends ShapeUtil { -+ static type: "group"; -+ static props: RecordProps; -+ static migrations: TLPropsMigrations; -+ hideSelectionBoundsFg(): boolean; -+ canBind(): boolean; -+ getDefaultProps(): TLGroupShape['props']; -+ getGeometry(shape: TLGroupShape): Geometry2d; -+ component(shape: TLGroupShape): JSX_2.Element | null; -+ indicator(shape: TLGroupShape): JSX_2.Element; -+ onChildrenChange(group: TLGroupShape): void; -+} -+ -+/** @public */ -+export declare const HALF_PI: number; -+ -+/** -+ * When dragging a handle, users can snap the handle to key geometry on other nearby shapes. -+ * Customize how handles snap to a shape by returning this from -+ * {@link ShapeUtil.getHandleSnapGeometry}. -+ * -+ * Any co-ordinates here should be in the shape's local space. -+ * -+ * @public -+ */ -+export declare interface HandleSnapGeometry { -+ /** -+ * A `Geometry2d` that describe the outline of the shape that the handle will snap to - fills -+ * are ignored. By default, this is the same geometry returned by {@link ShapeUtil.getGeometry}. -+ * Set this to `null` to disable handle snapping to this shape's outline. -+ */ -+ outline?: Geometry2d | null; -+ /** -+ * Key points on the shape that the handle will snap to. For example, the corners of a -+ * rectangle, or the centroid of a triangle. By default, no points are used. -+ */ -+ points?: VecModel[]; -+ /** -+ * By default, handles can't snap to their own shape because moving the handle might change the -+ * snapping location which can cause feedback loops. You can override this by returning a -+ * version of `outline` that won't be affected by the current handle's position to use for -+ * self-snapping. -+ */ -+ getSelfSnapOutline?(handle: TLHandle): Geometry2d | null; -+ /** -+ * By default, handles can't snap to their own shape because moving the handle might change the -+ * snapping location which can cause feedback loops. You can override this by returning a -+ * version of `points` that won't be affected by the current handle's position to use for -+ * self-snapping. -+ */ -+ getSelfSnapPoints?(handle: TLHandle): VecModel[]; -+} -+ -+/** @public */ -+export declare class HandleSnaps { -+ readonly manager: SnapManager; -+ readonly editor: Editor; -+ constructor(manager: SnapManager); -+ private getSnapGeometryCache; -+ private iterateSnapPointsInPageSpace; -+ private iterateSnapOutlines; -+ private getHandleSnapPosition; -+ snapHandle({ currentShapeId, handle, }: { -+ currentShapeId: TLShapeId; -+ handle: TLHandle; -+ }): null | SnapData; -+} -+ -+/** -+ * Clear the database of all data associated with tldraw. -+ * -+ * @public */ -+export declare function hardReset({ shouldReload }?: { -+ shouldReload?: boolean | undefined; -+}): Promise; -+ -+/** @public */ -+export declare function hardResetEditor(): void; -+ -+/** @public */ -+export declare class HistoryManager { -+ private readonly store; -+ readonly dispose: () => void; -+ private state; -+ private readonly pendingDiff; -+ private stacks; -+ private readonly annotateError; -+ constructor(opts: { -+ annotateError?(error: unknown): void; -+ store: Store; -+ }); -+ private flushPendingDiff; -+ getNumUndos(): number; -+ getNumRedos(): number; -+ /* Excluded from this release type: _isInBatch */ -+ batch(fn: () => void, opts?: TLHistoryBatchOptions): this; -+ _undo({ pushToRedoStack, toMark }: { -+ pushToRedoStack: boolean; -+ toMark?: string; -+ }): this; -+ undo(): this; -+ redo(): this; -+ bail(): this; -+ bailToMark(id: string): this; -+ squashToMark(id: string): this; -+ /* Excluded from this release type: _mark */ -+ clear(): void; -+ /* Excluded from this release type: getMarkIdMatching */ -+ /* Excluded from this release type: debug */ -+} -+ -+/** @public @react */ -+export declare function HTMLContainer({ children, className, ...rest }: HTMLContainerProps): JSX_2.Element; -+ -+/** @public */ -+export declare type HTMLContainerProps = React_3.HTMLAttributes; -+ -+/** @public */ -+export declare const inlineBase64AssetStore: TLAssetStore; -+ -+/** -+ * Find the intersections between a circle and a circle. -+ * -+ * @param c1 - The first circle's center. -+ * @param r1 - The first circle's radius. -+ * @param c2 - The second circle's center. -+ * @param r2 - The second circle's radius. -+ * @public -+ */ -+export declare function intersectCircleCircle(c1: VecLike, r1: number, c2: VecLike, r2: number): Vec[]; -+ -+/** -+ * Find the intersections between a circle and a bounding box. -+ * -+ * @param c - The circle's center. -+ * @param r - The circle's radius. -+ * @param points - The points in the polygon. -+ * @public -+ */ -+export declare function intersectCirclePolygon(c: VecLike, r: number, points: VecLike[]): null | VecLike[]; -+ -+/** -+ * Find the intersections between a circle and a bounding box. -+ * -+ * @param c - The circle's center. -+ * @param r - The circle's radius. -+ * @param points - The points in the polyline. -+ * @public -+ */ -+export declare function intersectCirclePolyline(c: VecLike, r: number, points: VecLike[]): null | VecLike[]; -+ -+/** -+ * Find the intersections between a line segment and a circle. -+ * -+ * @param a1 - The segment's first point. -+ * @param a2 - The segment's second point. -+ * @param c - The circle's center. -+ * @param r - The circle's radius. -+ * @public -+ */ -+export declare function intersectLineSegmentCircle(a1: VecLike, a2: VecLike, c: VecLike, r: number): null | VecLike[]; -+ -+/** -+ * Find the intersection between a line segment and a line segment. -+ * -+ * @param a1 - The first segment's first point. -+ * @param a2 - The first segment's second point. -+ * @param b1 - The second segment's first point. -+ * @param b2 - The second segment's second point. -+ * @public -+ */ -+export declare function intersectLineSegmentLineSegment(a1: VecLike, a2: VecLike, b1: VecLike, b2: VecLike): null | Vec; -+ -+/** -+ * Find the intersections between a line segment and a closed polygon. -+ * -+ * @param a1 - The segment's first point. -+ * @param a2 - The segment's second point. -+ * @param points - The points in the polygon. -+ * @public -+ */ -+export declare function intersectLineSegmentPolygon(a1: VecLike, a2: VecLike, points: VecLike[]): null | VecLike[]; -+ -+/** -+ * Find the intersections between a line segment and a polyline. -+ * -+ * @param a1 - The segment's first point. -+ * @param a2 - The segment's second point. -+ * @param points - The points in the polyline. -+ * @public -+ */ -+export declare function intersectLineSegmentPolyline(a1: VecLike, a2: VecLike, points: VecLike[]): null | VecLike[]; -+ -+/** -+ * Find the intersections between a polygon and a bounding box. -+ * -+ * @public -+ */ -+export declare function intersectPolygonBounds(points: VecLike[], bounds: Box): null | VecLike[]; -+ -+/** -+ * Create a new convex polygon as the intersection of two convex polygons. -+ * -+ * @param polygonA - An array of points representing the first polygon. -+ * @param polygonB - An array of points representing the second polygon. -+ * @public -+ */ -+export declare function intersectPolygonPolygon(polygonA: VecLike[], polygonB: VecLike[]): null | VecLike[]; -+ -+/* Excluded from this release type: InvalidLicenseKeyResult */ -+ -+/* Excluded from this release type: InvalidLicenseReason */ -+ -+/** -+ * Check if a float is safe to use. ie: Not too big or small. -+ * @public -+ */ -+export declare const isSafeFloat: (n: number) => boolean; -+ -+/* Excluded from this release type: LicenseFromKeyResult */ -+ -+/* Excluded from this release type: LicenseInfo */ -+ -+/* Excluded from this release type: LicenseManager */ -+ -+/** @public */ -+export declare function linesIntersect(A: VecLike, B: VecLike, C: VecLike, D: VecLike): boolean; -+ -+/** @public @react */ -+export declare function LoadingScreen({ children }: LoadingScreenProps): JSX_2.Element; -+ -+/** @public */ -+export declare interface LoadingScreenProps { -+ children: ReactNode; -+} -+ -+/** -+ * Loads a snapshot of the editor's instance state into the store of a new editor instance. -+ * -+ * @public -+ * @param store - The store to load the instance state into -+ * @param snapshot - The instance state snapshot to load -+ * @returns -+ */ -+export declare function loadSessionStateSnapshotIntoStore(store: TLStore, snapshot: TLSessionStateSnapshot, opts?: TLLoadSessionStateSnapshotOptions): void; -+ -+/** -+ * Loads a snapshot into a store. -+ * @public -+ */ -+export declare function loadSnapshot(store: TLStore, _snapshot: Partial | TLStoreSnapshot, opts?: TLLoadSnapshotOptions): void; -+ -+/** @public */ -+export declare function loopToHtmlElement(elm: Element): HTMLElement; -+ -+/** @public */ -+export declare class Mat { -+ constructor(a: number, b: number, c: number, d: number, e: number, f: number); -+ a: number; -+ b: number; -+ c: number; -+ d: number; -+ e: number; -+ f: number; -+ equals(m: Mat | MatModel): boolean; -+ identity(): this; -+ multiply(m: Mat | MatModel): this; -+ rotate(r: number, cx?: number, cy?: number): Mat; -+ translate(x: number, y: number): Mat; -+ scale(x: number, y: number): this; -+ invert(): this; -+ applyToPoint(point: VecLike): Vec; -+ applyToPoints(points: VecLike[]): Vec[]; -+ rotation(): number; -+ point(): Vec; -+ decomposed(): { -+ rotation: number; -+ scaleX: number; -+ scaleY: number; -+ x: number; -+ y: number; -+ }; -+ toCssString(): string; -+ setTo(model: MatModel): this; -+ decompose(): { -+ rotation: number; -+ scaleX: number; -+ scaleY: number; -+ x: number; -+ y: number; -+ }; -+ clone(): Mat; -+ static Identity(): Mat; -+ static Translate(x: number, y: number): Mat; -+ static Rotate(r: number, cx?: number, cy?: number): Mat; -+ static Scale(x: number, y: number): MatModel; -+ static Scale(x: number, y: number, cx: number, cy: number): MatModel; -+ static Multiply(m1: MatModel, m2: MatModel): MatModel; -+ static Inverse(m: MatModel): MatModel; -+ static Absolute(m: MatLike): MatModel; -+ static Compose(...matrices: MatLike[]): Mat; -+ static Point(m: MatLike): Vec; -+ static Rotation(m: MatLike): number; -+ static Decompose(m: MatLike): { -+ rotation: number; -+ scaleX: number; -+ scaleY: number; -+ x: number; -+ y: number; -+ }; -+ static Smooth(m: MatLike, precision?: number): MatLike; -+ static toCssString(m: MatLike): string; -+ static applyToPoint(m: MatLike, point: VecLike): Vec; -+ static applyToXY(m: MatLike, x: number, y: number): number[]; -+ static applyToPoints(m: MatLike, points: VecLike[]): Vec[]; -+ static applyToBounds(m: MatLike, box: Box): Box; -+ static From(m: MatLike): Mat; -+ static Cast(m: MatLike): Mat; -+} -+ -+/** @public */ -+export declare type MatLike = Mat | MatModel; -+ -+/** @public */ -+export declare interface MatModel { -+ a: number; -+ b: number; -+ c: number; -+ d: number; -+ e: number; -+ f: number; -+} -+ -+/* Excluded from this release type: normalizeWheel */ -+ -+/** @public */ -+export declare function openWindow(url: string, target?: string): void; -+ -+/* Excluded from this release type: OptionalErrorBoundary */ -+ -+/** @public */ -+export declare type OptionalKeys = Omit & Partial>; -+ -+/** -+ * Parses a string created by {@link createDeepLinkString} back into a deep link descriptor. -+ * -+ * @param deepLinkString - the deep link string -+ * @returns a deep link descriptor -+ * -+ * @public -+ */ -+export declare function parseDeepLinkString(deepLinkString: string): TLDeepLink; -+ -+/** -+ * Find the approximate perimeter of an ellipse. -+ * -+ * @param rx - The ellipse's x radius. -+ * @param ry - The ellipse's y radius. -+ * @public -+ */ -+export declare function perimeterOfEllipse(rx: number, ry: number): number; -+ -+/** @public */ -+export declare const PI: number; -+ -+/** @public */ -+export declare const PI2: number; -+ -+/** @public */ -+export declare class Point2d extends Geometry2d { -+ point: Vec; -+ constructor(config: Omit & { -+ margin: number; -+ point: Vec; -+ }); -+ getVertices(): Vec[]; -+ nearestPoint(): Vec; -+ hitTestLineSegment(A: Vec, B: Vec, margin: number): boolean; -+ getSvgPathData(): string; -+} -+ -+/** -+ * Get whether a point is inside of a polygon. -+ * -+ * ```ts -+ * const result = pointInPolygon(myPoint, myPoints) -+ * ``` -+ * -+ * @public -+ */ -+export declare function pointInPolygon(A: VecLike, points: VecLike[]): boolean; -+ -+/** @public */ -+export declare interface PointsSnapIndicator { -+ id: string; -+ type: 'points'; -+ points: VecLike[]; -+} -+ -+/** @public */ -+export declare class Polygon2d extends Polyline2d { -+ constructor(config: Omit & { -+ points: Vec[]; -+ }); -+} -+ -+/** @public */ -+export declare function polygonIntersectsPolyline(polygon: VecLike[], polyline: VecLike[]): boolean; -+ -+/** @public */ -+export declare function polygonsIntersect(a: VecLike[], b: VecLike[]): boolean; -+ -+/** @public */ -+export declare class Polyline2d extends Geometry2d { -+ points: Vec[]; -+ constructor(config: Omit & { -+ points: Vec[]; -+ }); -+ _segments?: Edge2d[]; -+ get segments(): Edge2d[]; -+ getLength(): number; -+ getVertices(): Vec[]; -+ nearestPoint(A: Vec): Vec; -+ hitTestLineSegment(A: Vec, B: Vec, distance?: number): boolean; -+ getSvgPathData(): string; -+} -+ -+/** @public */ -+export declare function precise(A: VecLike): string; -+ -+/** -+ * This function calls `event.preventDefault()` for you. Why is that useful? -+ * -+ * Beacuase if you enable `window.preventDefaultLogging = true` it'll log out a message when it -+ * happens. Because we use console.warn rather than (log) you'll get a stack trace in the inspector -+ * telling you exactly where it happened. This is important because `e.preventDefault()` is the -+ * source of many bugs, but unfortuantly it can't be avoided because it also stops a lot of default -+ * behaviour which doesn't make sense in our UI -+ * -+ * @param event - To prevent default on -+ * @public -+ */ -+export declare function preventDefault(event: Event | React_2.BaseSyntheticEvent): void; -+ -+/** -+ * Convert radians to degrees. -+ * -+ * @param r - The degree in radians. -+ * @public -+ */ -+export declare function radiansToDegrees(r: number): number; -+ -+/** -+ * Finds the intersection of two ranges. -+ * -+ * @param a0 - The start point in the A range -+ * @param a1 - The end point in the A range -+ * @param b0 - The start point in the B range -+ * @param b1 - The end point in the B range -+ * @returns The intersection of the ranges, or null if no intersection -+ * @public -+ */ -+export declare function rangeIntersection(a0: number, a1: number, b0: number, b1: number): [number, number] | null; -+ -+export { react } -+ -+/** -+ * A map of {@link @tldraw/tlschema#StyleProp | StyleProps} to their {@link SharedStyle} values. See -+ * {@link Editor.getSharedStyles}. -+ * -+ * @public -+ */ -+export declare class ReadonlySharedStyleMap { -+ /* Excluded from this release type: map */ -+ constructor(entries?: Iterable<[StyleProp, SharedStyle]>); -+ get(prop: StyleProp): SharedStyle | undefined; -+ getAsKnownValue(prop: StyleProp): T | undefined; -+ get size(): number; -+ equals(other: ReadonlySharedStyleMap): boolean; -+ keys(): IterableIterator>; -+ values(): IterableIterator>; -+ entries(): IterableIterator<[StyleProp, SharedStyle]>; -+ [Symbol.iterator](): IterableIterator<[StyleProp, SharedStyle]>; -+} -+ -+/** @public */ -+export declare class Rectangle2d extends Polygon2d { -+ x: number; -+ y: number; -+ w: number; -+ h: number; -+ constructor(config: Omit & { -+ height: number; -+ width: number; -+ x?: number; -+ y?: number; -+ }); -+ getBounds(): Box; -+ getSvgPathData(): string; -+} -+ -+/** @public */ -+export declare function refreshPage(): void; -+ -+/** @public */ -+export declare function releasePointerCapture(element: Element, event: PointerEvent | React_2.PointerEvent): void; -+ -+/** @public */ -+export declare type RequiredKeys = Required> & Omit; -+ -+/** @public */ -+export declare function resizeBox(shape: T, info: { -+ handle: TLResizeHandle; -+ initialBounds: Box; -+ initialShape: T; -+ mode: TLResizeMode; -+ newPoint: VecModel; -+ scaleX: number; -+ scaleY: number; -+}, opts?: ResizeBoxOptions): T; -+ -+/** @public */ -+export declare interface ResizeBoxOptions { -+ minWidth?: number; -+ maxWidth?: number; -+ minHeight?: number; -+ maxHeight?: number; -+} -+ -+/** @public */ -+export declare const ROTATE_CORNER_TO_SELECTION_CORNER: { -+ readonly bottom_left_rotate: "bottom_left"; -+ readonly bottom_right_rotate: "bottom_right"; -+ readonly mobile_rotate: "top_left"; -+ readonly top_left_rotate: "top_left"; -+ readonly top_right_rotate: "top_right"; -+}; -+ -+/** @public */ -+export declare type RotateCorner = 'bottom_left_rotate' | 'bottom_right_rotate' | 'mobile_rotate' | 'top_left_rotate' | 'top_right_rotate'; -+ -+/** @public */ -+export declare function rotateSelectionHandle(handle: SelectionHandle, rotation: number): SelectionHandle; -+ -+/** @public */ -+export declare const runtime: { -+ hardReset(): void; -+ openWindow(url: string, target: string): void; -+ refreshPage(): void; -+}; -+ -+/** @public */ -+export declare interface ScribbleItem { -+ id: string; -+ scribble: TLScribble; -+ timeoutMs: number; -+ delayRemaining: number; -+ prev: null | VecModel; -+ next: null | VecModel; -+} -+ -+/** @public */ -+export declare class ScribbleManager { -+ private editor; -+ scribbleItems: Map; -+ state: "paused" | "running"; -+ constructor(editor: Editor); -+ addScribble(scribble: Partial, id?: string): ScribbleItem; -+ reset(): void; -+ /** -+ * Start stopping the scribble. The scribble won't be removed until its last point is cleared. -+ * -+ * @public -+ */ -+ stop(id: ScribbleItem['id']): ScribbleItem; -+ /** -+ * Set the scribble's next point. -+ * -+ * @param point - The point to add. -+ * @public -+ */ -+ addPoint(id: ScribbleItem['id'], x: number, y: number, z?: number): ScribbleItem; -+ /** -+ * Update on each animation frame. -+ * -+ * @param elapsed - The number of milliseconds since the last tick. -+ * @public -+ */ -+ tick(elapsed: number): void; -+} -+ -+/** @public */ -+export declare type SelectionCorner = 'bottom_left' | 'bottom_right' | 'top_left' | 'top_right'; -+ -+/** @public */ -+export declare type SelectionEdge = 'bottom' | 'left' | 'right' | 'top'; -+ -+/** @public */ -+export declare type SelectionHandle = SelectionCorner | SelectionEdge; -+ -+/** @public */ -+export declare function setPointerCapture(element: Element, event: PointerEvent | React_2.PointerEvent): void; -+ -+/** @public */ -+export declare function setRuntimeOverrides(input: Partial): void; -+ -+/** @public */ -+export declare function setUserPreferences(user: TLUserPreferences): void; -+ -+/** @public */ -+export declare abstract class ShapeUtil { -+ editor: Editor; -+ constructor(editor: Editor); -+ /** -+ * Props allow you to define the shape's properties in a way that the editor can understand. -+ * This has two main uses: -+ * -+ * 1. Validation. Shapes will be validated using these props to stop bad data from being saved. -+ * 2. Styles. Each {@link @tldraw/tlschema#StyleProp} in the props can be set on many shapes at -+ * once, and will be remembered from one shape to the next. -+ * -+ * @example -+ * ```tsx -+ * import {T, TLBaseShape, TLDefaultColorStyle, DefaultColorStyle, ShapeUtil} from 'tldraw' -+ * -+ * type MyShape = TLBaseShape<'mine', { -+ * color: TLDefaultColorStyle, -+ * text: string, -+ * }> -+ * -+ * class MyShapeUtil extends ShapeUtil { -+ * static props = { -+ * // we use tldraw's built-in color style: -+ * color: DefaultColorStyle, -+ * // validate that the text prop is a string: -+ * text: T.string, -+ * } -+ * } -+ * ``` -+ */ -+ static props?: RecordProps; -+ /** -+ * Migrations allow you to make changes to a shape's props over time. Read the -+ * {@link https://www.tldraw.dev/docs/persistence#Shape-props-migrations | shape prop migrations} -+ * guide for more information. -+ */ -+ static migrations?: LegacyMigrations | MigrationSequence | TLPropsMigrations; -+ /** -+ * The type of the shape util, which should match the shape's type. -+ * -+ * @public -+ */ -+ static type: string; -+ /** -+ * Get the default props for a shape. -+ * -+ * @public -+ */ -+ abstract getDefaultProps(): Shape['props']; -+ /** -+ * Get the shape's geometry. -+ * -+ * @param shape - The shape. -+ * @public -+ */ -+ abstract getGeometry(shape: Shape): Geometry2d; -+ /** -+ * Get a JSX element for the shape (as an HTML element). -+ * -+ * @param shape - The shape. -+ * @public -+ */ -+ abstract component(shape: Shape): any; -+ /** -+ * Get JSX describing the shape's indicator (as an SVG element). -+ * -+ * @param shape - The shape. -+ * @public -+ */ -+ abstract indicator(shape: Shape): any; -+ /** -+ * Whether the shape can be snapped to by another shape. -+ * -+ * @public -+ */ -+ canSnap(_shape: Shape): boolean; -+ /** -+ * Whether the shape can be scrolled while editing. -+ * -+ * @public -+ */ -+ canScroll(_shape: Shape): boolean; -+ /** -+ * Whether the shape can be bound to. See {@link TLShapeUtilCanBindOpts} for details. -+ * -+ * @public -+ */ -+ canBind(_opts: TLShapeUtilCanBindOpts): boolean; -+ /** -+ * Whether the shape can be double clicked to edit. -+ * -+ * @public -+ */ -+ canEdit(_shape: Shape): boolean; -+ /** -+ * Whether the shape can be resized. -+ * -+ * @public -+ */ -+ canResize(_shape: Shape): boolean; -+ /** -+ * Whether the shape can be edited in read-only mode. -+ * -+ * @public -+ */ -+ canEditInReadOnly(_shape: Shape): boolean; -+ /** -+ * Whether the shape can be cropped. -+ * -+ * @public -+ */ -+ canCrop(_shape: Shape): boolean; -+ /** -+ * Whether the shape participates in stacking, aligning, and distributing. -+ * -+ * @public -+ */ -+ canBeLaidOut(_shape: Shape): boolean; -+ /* Excluded from this release type: providesBackgroundForChildren */ -+ /** -+ * Whether the shape should hide its resize handles when selected. -+ * -+ * @public -+ */ -+ hideResizeHandles(_shape: Shape): boolean; -+ /** -+ * Whether the shape should hide its rotation handles when selected. -+ * -+ * @public -+ */ -+ hideRotateHandle(_shape: Shape): boolean; -+ /** -+ * Whether the shape should hide its selection bounds background when selected. -+ * -+ * @public -+ */ -+ hideSelectionBoundsBg(_shape: Shape): boolean; -+ /** -+ * Whether the shape should hide its selection bounds foreground when selected. -+ * -+ * @public -+ */ -+ hideSelectionBoundsFg(_shape: Shape): boolean; -+ /** -+ * Whether the shape's aspect ratio is locked. -+ * -+ * @public -+ */ -+ isAspectRatioLocked(_shape: Shape): boolean; -+ /* Excluded from this release type: backgroundComponent */ -+ /** -+ * Get the interpolated props for an animating shape. This is an optional method. -+ * -+ * @example -+ * -+ * ```ts -+ * util.getInterpolatedProps?.(startShape, endShape, t) -+ * ``` -+ * -+ * @param startShape - The initial shape. -+ * @param endShape - The initial shape. -+ * @param progress - The normalized progress between zero (start) and 1 (end). -+ * @public -+ */ -+ getInterpolatedProps?(startShape: Shape, endShape: Shape, progress: number): Shape['props']; -+ /** -+ * Get an array of handle models for the shape. This is an optional method. -+ * -+ * @example -+ * -+ * ```ts -+ * util.getHandles?.(myShape) -+ * ``` -+ * -+ * @param shape - The shape. -+ * @public -+ */ -+ getHandles?(shape: Shape): TLHandle[]; -+ /** -+ * Get whether the shape can receive children of a given type. -+ * -+ * @param type - The shape type. -+ * @public -+ */ -+ canReceiveNewChildrenOfType(_shape: Shape, _type: TLShape['type']): boolean; -+ /** -+ * Get whether the shape can receive children of a given type. -+ * -+ * @param shape - The shape type. -+ * @param shapes - The shapes that are being dropped. -+ * @public -+ */ -+ canDropShapes(_shape: Shape, _shapes: TLShape[]): boolean; -+ /** -+ * Get the shape as an SVG object. -+ * -+ * @param shape - The shape. -+ * @param ctx - The export context for the SVG - used for adding e.g. \s -+ * @returns An SVG element. -+ * @public -+ */ -+ toSvg?(shape: Shape, ctx: SvgExportContext): null | Promise | ReactElement; -+ /** -+ * Get the shape's background layer as an SVG object. -+ * -+ * @param shape - The shape. -+ * @param ctx - ctx - The export context for the SVG - used for adding e.g. \s -+ * @returns An SVG element. -+ * @public -+ */ -+ toBackgroundSvg?(shape: Shape, ctx: SvgExportContext): null | Promise | ReactElement; -+ /* Excluded from this release type: expandSelectionOutlinePx */ -+ /** -+ * Return elements to be added to the \ section of the canvases SVG context. This can be -+ * used to define SVG content (e.g. patterns & masks) that can be referred to by ID from svg -+ * elements returned by `component`. -+ * -+ * Each def should have a unique `key`. If multiple defs from different shapes all have the same -+ * key, only one will be used. -+ */ -+ getCanvasSvgDefs(): TLShapeUtilCanvasSvgDef[]; -+ /** -+ * Get the geometry to use when snapping to this this shape in translate/resize operations. See -+ * {@link BoundsSnapGeometry} for details. -+ */ -+ getBoundsSnapGeometry(_shape: Shape): BoundsSnapGeometry; -+ /** -+ * Get the geometry to use when snapping handles to this shape. See {@link HandleSnapGeometry} -+ * for details. -+ */ -+ getHandleSnapGeometry(_shape: Shape): HandleSnapGeometry; -+ getText(_shape: Shape): string | undefined; -+ /** -+ * A callback called just before a shape is created. This method provides a last chance to modify -+ * the created shape. -+ * -+ * @example -+ * -+ * ```ts -+ * onBeforeCreate = (next) => { -+ * return { ...next, x: next.x + 1 } -+ * } -+ * ``` -+ * -+ * @param next - The next shape. -+ * @returns The next shape or void. -+ * @public -+ */ -+ onBeforeCreate?(next: Shape): Shape | void; -+ /** -+ * A callback called just before a shape is updated. This method provides a last chance to modify -+ * the updated shape. -+ * -+ * @example -+ * -+ * ```ts -+ * onBeforeUpdate = (prev, next) => { -+ * if (prev.x === next.x) { -+ * return { ...next, x: next.x + 1 } -+ * } -+ * } -+ * ``` -+ * -+ * @param prev - The previous shape. -+ * @param next - The next shape. -+ * @returns The next shape or void. -+ * @public -+ */ -+ onBeforeUpdate?(prev: Shape, next: Shape): Shape | void; -+ /** -+ * A callback called when some other shapes are dragged over this one. -+ * -+ * @example -+ * -+ * ```ts -+ * onDragShapesOver = (shape, shapes) => { -+ * this.editor.reparentShapes(shapes, shape.id) -+ * } -+ * ``` -+ * -+ * @param shape - The shape. -+ * @param shapes - The shapes that are being dragged over this one. -+ * @public -+ */ -+ onDragShapesOver?(shape: Shape, shapes: TLShape[]): void; -+ /** -+ * A callback called when some other shapes are dragged out of this one. -+ * -+ * @param shape - The shape. -+ * @param shapes - The shapes that are being dragged out. -+ * @public -+ */ -+ onDragShapesOut?(shape: Shape, shapes: TLShape[]): void; -+ /** -+ * A callback called when some other shapes are dropped over this one. -+ * -+ * @param shape - The shape. -+ * @param shapes - The shapes that are being dropped over this one. -+ * @public -+ */ -+ onDropShapesOver?(shape: Shape, shapes: TLShape[]): void; -+ /** -+ * A callback called when a shape starts being resized. -+ * -+ * @param shape - The shape. -+ * @returns A change to apply to the shape, or void. -+ * @public -+ */ -+ onResizeStart?(shape: Shape): TLShapePartial | void; -+ /** -+ * A callback called when a shape changes from a resize. -+ * -+ * @param shape - The shape at the start of the resize. -+ * @param info - Info about the resize. -+ * @returns A change to apply to the shape, or void. -+ * @public -+ */ -+ onResize?(shape: Shape, info: TLResizeInfo): Omit, 'id' | 'type'> | undefined | void; -+ /** -+ * A callback called when a shape finishes resizing. -+ * -+ * @param initial - The shape at the start of the resize. -+ * @param current - The current shape. -+ * @returns A change to apply to the shape, or void. -+ * @public -+ */ -+ onResizeEnd?(initial: Shape, current: Shape): TLShapePartial | void; -+ /** -+ * A callback called when a shape starts being translated. -+ * -+ * @param shape - The shape. -+ * @returns A change to apply to the shape, or void. -+ * @public -+ */ -+ onTranslateStart?(shape: Shape): TLShapePartial | void; -+ /** -+ * A callback called when a shape changes from a translation. -+ * -+ * @param initial - The shape at the start of the translation. -+ * @param current - The current shape. -+ * @returns A change to apply to the shape, or void. -+ * @public -+ */ -+ onTranslate?(initial: Shape, current: Shape): TLShapePartial | void; -+ /** -+ * A callback called when a shape finishes translating. -+ * -+ * @param initial - The shape at the start of the translation. -+ * @param current - The current shape. -+ * @returns A change to apply to the shape, or void. -+ * @public -+ */ -+ onTranslateEnd?(initial: Shape, current: Shape): TLShapePartial | void; -+ /** -+ * A callback called when a shape's handle changes. -+ * -+ * @param shape - The current shape. -+ * @param info - An object containing the handle and whether the handle is 'precise' or not. -+ * @returns A change to apply to the shape, or void. -+ * @public -+ */ -+ onHandleDrag?(shape: Shape, info: TLHandleDragInfo): TLShapePartial | void; -+ /** -+ * A callback called when a shape starts being rotated. -+ * -+ * @param shape - The shape. -+ * @returns A change to apply to the shape, or void. -+ * @public -+ */ -+ onRotateStart?(shape: Shape): TLShapePartial | void; -+ /** -+ * A callback called when a shape changes from a rotation. -+ * -+ * @param initial - The shape at the start of the rotation. -+ * @param current - The current shape. -+ * @returns A change to apply to the shape, or void. -+ * @public -+ */ -+ onRotate?(initial: Shape, current: Shape): TLShapePartial | void; -+ /** -+ * A callback called when a shape finishes rotating. -+ * -+ * @param initial - The shape at the start of the rotation. -+ * @param current - The current shape. -+ * @returns A change to apply to the shape, or void. -+ * @public -+ */ -+ onRotateEnd?(initial: Shape, current: Shape): TLShapePartial | void; -+ /* Excluded from this release type: onBindingChange */ -+ /** -+ * A callback called when a shape's children change. -+ * -+ * @param shape - The shape. -+ * @returns An array of shape updates, or void. -+ * @public -+ */ -+ onChildrenChange?(shape: Shape): TLShapePartial[] | void; -+ /** -+ * A callback called when a shape's handle is double clicked. -+ * -+ * @param shape - The shape. -+ * @param handle - The handle that is double-clicked. -+ * @returns A change to apply to the shape, or void. -+ * @public -+ */ -+ onDoubleClickHandle?(shape: Shape, handle: TLHandle): TLShapePartial | void; -+ /** -+ * A callback called when a shape's edge is double clicked. -+ * -+ * @param shape - The shape. -+ * @returns A change to apply to the shape, or void. -+ * @public -+ */ -+ onDoubleClickEdge?(shape: Shape): TLShapePartial | void; -+ /** -+ * A callback called when a shape is double clicked. -+ * -+ * @param shape - The shape. -+ * @returns A change to apply to the shape, or void. -+ * @public -+ */ -+ onDoubleClick?(shape: Shape): TLShapePartial | void; -+ /** -+ * A callback called when a shape is clicked. -+ * -+ * @param shape - The shape. -+ * @returns A change to apply to the shape, or void. -+ * @public -+ */ -+ onClick?(shape: Shape): TLShapePartial | void; -+ /** -+ * A callback called when a shape finishes being editing. -+ * -+ * @param shape - The shape. -+ * @public -+ */ -+ onEditEnd?(shape: Shape): void; -+} -+ -+/** -+ * The value of a particular {@link @tldraw/tlschema#StyleProp}. -+ * -+ * A `mixed` style means that in the current selection, there are lots of different values for the -+ * same style prop - e.g. a red and a blue shape are selected. -+ * -+ * A `shared` style means that all shapes in the selection share the same value for this style prop. -+ * -+ * @public -+ */ -+export declare type SharedStyle = { -+ readonly type: 'mixed'; -+} | { -+ readonly type: 'shared'; -+ readonly value: T; -+}; -+ -+/* Excluded from this release type: SharedStyleMap */ -+ -+/** -+ * Get the short angle distance between two angles. -+ * -+ * @param a0 - The first angle. -+ * @param a1 - The second angle. -+ * @public -+ */ -+export declare function shortAngleDist(a0: number, a1: number): number; -+ -+/** @public */ -+export declare const SIDES: readonly ["top", "right", "bottom", "left"]; -+ -+export { Signal } -+ -+/** @public */ -+export declare const SIN: (x: number) => number; -+ -+/** -+ * Clamp rotation to even segments. -+ * -+ * @param r - The rotation in radians. -+ * @param segments - The number of segments. -+ * @public -+ */ -+export declare function snapAngle(r: number, segments: number): number; -+ -+/** @public */ -+export declare interface SnapData { -+ nudge: Vec; -+} -+ -+/** @public */ -+export declare type SnapIndicator = GapsSnapIndicator | PointsSnapIndicator; -+ -+/** @public */ -+export declare class SnapManager { -+ readonly editor: Editor; -+ readonly shapeBounds: BoundsSnaps; -+ readonly handles: HandleSnaps; -+ private _snapIndicators; -+ constructor(editor: Editor); -+ getIndicators(): SnapIndicator[]; -+ clearIndicators(): void; -+ setIndicators(indicators: SnapIndicator[]): void; -+ getSnapThreshold(): number; -+ getSnappableShapes(): Set; -+ getCurrentCommonAncestor(): TLShapeId | undefined; -+} -+ -+/** @public */ -+export declare class Stadium2d extends Geometry2d { -+ config: Omit & { -+ height: number; -+ width: number; -+ }; -+ w: number; -+ h: number; -+ a: Arc2d; -+ b: Edge2d; -+ c: Arc2d; -+ d: Edge2d; -+ constructor(config: Omit & { -+ height: number; -+ width: number; -+ }); -+ nearestPoint(A: Vec): Vec; -+ hitTestLineSegment(A: Vec, B: Vec): boolean; -+ getVertices(): Vec[]; -+ getBounds(): Box; -+ getLength(): number; -+ getSvgPathData(): string; -+} -+ -+/** @public */ -+export declare abstract class StateNode implements Partial { -+ editor: Editor; -+ performanceTracker: PerformanceTracker; -+ constructor(editor: Editor, parent?: StateNode); -+ static id: string; -+ static initial?: string; -+ static children?: () => TLStateNodeConstructor[]; -+ static isLockable: boolean; -+ id: string; -+ type: 'branch' | 'leaf' | 'root'; -+ shapeType?: string; -+ initial?: string; -+ children?: Record; -+ isLockable: boolean; -+ parent: StateNode; -+ /** -+ * This node's path of active state nodes -+ * -+ * @public -+ */ -+ getPath(): string; -+ _path: Computed; -+ /** -+ * This node's current active child node, if any. -+ * -+ * @public -+ */ -+ getCurrent(): StateNode | undefined; -+ private _current; -+ /** -+ * Whether this node is active. -+ * -+ * @public -+ */ -+ getIsActive(): boolean; -+ private _isActive; -+ /** -+ * Transition to a new active child state node. -+ * -+ * @example -+ * ```ts -+ * parentState.transition('childStateA') -+ * parentState.transition('childStateB', { myData: 4 }) -+ *``` -+ * -+ * @param id - The id of the child state node to transition to. -+ * @param info - Any data to pass to the `onEnter` and `onExit` handlers. -+ * -+ * @public -+ */ -+ transition(id: string, info?: any): this; -+ handleEvent(info: Exclude): void; -+ enter(info: any, from: string): void; -+ exit(info: any, from: string): void; -+ /** -+ * This is a hack / escape hatch that will tell the editor to -+ * report a different state as active (in `getCurrentToolId()`) when -+ * this state is active. This is usually used when a tool transitions -+ * to a child of a different state for a certain interaction and then -+ * returns to the original tool when that interaction completes; and -+ * where we would want to show the original tool as active in the UI. -+ * -+ * @public -+ */ -+ _currentToolIdMask: Atom; -+ getCurrentToolIdMask(): string | undefined; -+ setCurrentToolIdMask(id: string | undefined): void; -+ onWheel?(info: TLWheelEventInfo): void; -+ onPointerDown?(info: TLPointerEventInfo): void; -+ onPointerMove?(info: TLPointerEventInfo): void; -+ onLongPress?(info: TLPointerEventInfo): void; -+ onPointerUp?(info: TLPointerEventInfo): void; -+ onDoubleClick?(info: TLClickEventInfo): void; -+ onTripleClick?(info: TLClickEventInfo): void; -+ onQuadrupleClick?(info: TLClickEventInfo): void; -+ onRightClick?(info: TLPointerEventInfo): void; -+ onMiddleClick?(info: TLPointerEventInfo): void; -+ onKeyDown?(info: TLKeyboardEventInfo): void; -+ onKeyUp?(info: TLKeyboardEventInfo): void; -+ onKeyRepeat?(info: TLKeyboardEventInfo): void; -+ onCancel?(info: TLCancelEventInfo): void; -+ onComplete?(info: TLCompleteEventInfo): void; -+ onInterrupt?(info: TLInterruptEventInfo): void; -+ onTick?(info: TLTickEventInfo): void; -+ onEnter?(info: any, from: string): void; -+ onExit?(info: any, to: string): void; -+} -+ -+/** @public */ -+export declare const stopEventPropagation: (e: any) => any; -+ -+/** @public @react */ -+export declare function SVGContainer({ children, className, ...rest }: SVGContainerProps): JSX_2.Element; -+ -+/** @public */ -+export declare type SVGContainerProps = React_3.HTMLAttributes; -+ -+/** @public */ -+export declare interface SvgExportContext { -+ /** -+ * Add contents to the `` section of the export SVG. Each export def should have a unique -+ * key. If multiple defs come with the same key, only one will be added. -+ */ -+ addExportDef(def: SvgExportDef): void; -+ /** -+ * Cause the SVG export to be delayed until the returned promise is resolved. This is useful if -+ * e.g. your shape loads data dynamically, and you need to prevent the export from happening -+ * until after the data is loaded. -+ * -+ * See also the {@link useDelaySvgExport} hook, which may be a more convenient way to use this -+ * method depending on your use-case. -+ */ -+ waitUntil(promise: Promise): void; -+ /** -+ * Whether the export should be in dark mode. -+ */ -+ readonly isDarkMode: boolean; -+} -+ -+/** @public */ -+export declare interface SvgExportDef { -+ key: string; -+ getElement(): null | Promise | ReactElement; -+} -+ -+/** -+ * A string that is unique per browser tab -+ * @public -+ */ -+export declare const TAB_ID: string; -+ -+/* Excluded from this release type: TestEnvironment */ -+ -+/** @public */ -+export declare class TextManager { -+ editor: Editor; -+ baseElm: HTMLDivElement; -+ constructor(editor: Editor); -+ measureText(textToMeasure: string, opts: { -+ /** -+ * When maxWidth is a number, the text will be wrapped to that maxWidth. When maxWidth -+ * is null, the text will be measured without wrapping, but explicit line breaks and -+ * space are preserved. -+ */ -+ maxWidth: null | number; -+ disableOverflowWrapBreaking?: boolean; -+ fontFamily: string; -+ fontSize: number; -+ fontStyle: string; -+ fontWeight: string; -+ lineHeight: number; -+ minWidth?: null | number; -+ padding: string; -+ }): BoxModel & { -+ scrollWidth: number; -+ }; -+ /** -+ * Given an html element, measure the position of each span of unbroken -+ * word/white-space characters within any text nodes it contains. -+ */ -+ measureElementTextNodeSpans(element: HTMLElement, { shouldTruncateToFirstLine }?: { -+ shouldTruncateToFirstLine?: boolean; -+ }): { -+ didTruncate: boolean; -+ spans: { -+ box: BoxModel; -+ text: string; -+ }[]; -+ }; -+ /** -+ * Measure text into individual spans. Spans are created by rendering the -+ * text, then dividing it up according to line breaks and word boundaries. -+ * -+ * It works by having the browser render the text, then measuring the -+ * position of each character. You can use this to replicate the text-layout -+ * algorithm of the current browser in e.g. an SVG export. -+ */ -+ measureTextSpans(textToMeasure: string, opts: TLMeasureTextSpanOpts): { -+ box: BoxModel; -+ text: string; -+ }[]; -+} -+ -+/** @public */ -+export declare type TLAnyBindingUtilConstructor = TLBindingUtilConstructor; -+ -+/** @public */ -+export declare type TLAnyShapeUtilConstructor = TLShapeUtilConstructor; -+ -+/** @public */ -+export declare type TLBaseBoxShape = TLBaseShape; -+ -+/** @public */ -+export declare interface TLBaseEventInfo { -+ type: UiEventType; -+ shiftKey: boolean; -+ altKey: boolean; -+ ctrlKey: boolean; -+} -+ -+/** @public */ -+export declare interface TLBindingUtilConstructor = BindingUtil> { -+ new (editor: Editor): U; -+ type: T['type']; -+ /** Validations for this binding's props. */ -+ props?: RecordProps; -+ /** Migrations for this binding's props. */ -+ migrations?: TLPropsMigrations; -+} -+ -+/** @public */ -+export declare interface TLBrushProps { -+ brush: BoxModel; -+ color?: string; -+ opacity?: number; -+ className?: string; -+} -+ -+/** @public */ -+export declare interface TLCameraConstraints { -+ /** The bounds (in page space) of the constrained space */ -+ bounds: BoxModel; -+ /** The padding inside of the viewport (in screen space) */ -+ padding: VecLike; -+ /** The origin for placement. Used to position the bounds within the viewport when an axis is fixed or contained and zoom is below the axis fit. */ -+ origin: VecLike; -+ /** The camera's initial zoom, used also when the camera is reset. -+ * -+ * - `default`: Sets the initial zoom to 100%. -+ * - `fit-x`: The x axis will completely fill the viewport bounds. -+ * - `fit-y`: The y axis will completely fill the viewport bounds. -+ * - `fit-min`: The smaller axis will completely fill the viewport bounds. -+ * - `fit-max`: The larger axis will completely fill the viewport bounds. -+ * - `fit-x-100`: The x axis will completely fill the viewport bounds, or 100% zoom, whichever is smaller. -+ * - `fit-y-100`: The y axis will completely fill the viewport bounds, or 100% zoom, whichever is smaller. -+ * - `fit-min-100`: The smaller axis will completely fill the viewport bounds, or 100% zoom, whichever is smaller. -+ * - `fit-max-100`: The larger axis will completely fill the viewport bounds, or 100% zoom, whichever is smaller. -+ */ -+ initialZoom: 'default' | 'fit-max-100' | 'fit-max' | 'fit-min-100' | 'fit-min' | 'fit-x-100' | 'fit-x' | 'fit-y-100' | 'fit-y'; -+ /** The camera's base for its zoom steps. -+ * -+ * - `default`: Sets the initial zoom to 100%. -+ * - `fit-x`: The x axis will completely fill the viewport bounds. -+ * - `fit-y`: The y axis will completely fill the viewport bounds. -+ * - `fit-min`: The smaller axis will completely fill the viewport bounds. -+ * - `fit-max`: The larger axis will completely fill the viewport bounds. -+ * - `fit-x-100`: The x axis will completely fill the viewport bounds, or 100% zoom, whichever is smaller. -+ * - `fit-y-100`: The y axis will completely fill the viewport bounds, or 100% zoom, whichever is smaller. -+ * - `fit-min-100`: The smaller axis will completely fill the viewport bounds, or 100% zoom, whichever is smaller. -+ * - `fit-max-100`: The larger axis will completely fill the viewport bounds, or 100% zoom, whichever is smaller. -+ */ -+ baseZoom: 'default' | 'fit-max-100' | 'fit-max' | 'fit-min-100' | 'fit-min' | 'fit-x-100' | 'fit-x' | 'fit-y-100' | 'fit-y'; -+ /** The behavior for the constraints for both axes or each axis individually. -+ * -+ * - `free`: The bounds are ignored when moving the camera. -+ * - 'fixed': The bounds will be positioned within the viewport based on the origin -+ * - `contain`: The 'fixed' behavior will be used when the zoom is below the zoom level at which the bounds would fill the viewport; and when above this zoom, the bounds will use the 'inside' behavior. -+ * - `inside`: The bounds will stay completely within the viewport. -+ * - `outside`: The bounds will stay touching the viewport. -+ */ -+ behavior: 'contain' | 'fixed' | 'free' | 'inside' | 'outside' | { -+ x: 'contain' | 'fixed' | 'free' | 'inside' | 'outside'; -+ y: 'contain' | 'fixed' | 'free' | 'inside' | 'outside'; -+ }; -+} -+ -+/** @public */ -+export declare interface TLCameraMoveOptions { -+ /** Whether to move the camera immediately, rather than on the next tick. */ -+ immediate?: boolean; -+ /** Whether to force the camera to move, even if the user's camera options have locked the camera. */ -+ force?: boolean; -+ /** Whether to reset the camera to its default position and zoom. */ -+ reset?: boolean; -+ /** An (optional) animation to use. */ -+ animation?: { -+ /** An easing function to apply to the animation's progress from start to end. */ -+ easing?(t: number): number; -+ /** The time the animation should take to arrive at the specified camera coordinates. */ -+ duration?: number; -+ }; -+} -+ -+/** @public */ -+export declare interface TLCameraOptions { -+ /** Whether the camera is locked. */ -+ isLocked: boolean; -+ /** The speed of a scroll wheel / trackpad pan. Default is 1. */ -+ panSpeed: number; -+ /** The speed of a scroll wheel / trackpad zoom. Default is 1. */ -+ zoomSpeed: number; -+ /** The steps that a user can zoom between with zoom in / zoom out. The first and last value will determine the min and max zoom. */ -+ zoomSteps: number[]; -+ /** Controls whether the wheel pans or zooms. -+ * -+ * - `zoom`: The wheel will zoom in and out. -+ * - `pan`: The wheel will pan the camera. -+ * - `none`: The wheel will do nothing. -+ */ -+ wheelBehavior: 'none' | 'pan' | 'zoom'; -+ /** The camera constraints. */ -+ constraints?: TLCameraConstraints; -+} -+ -+/** @public */ -+export declare type TLCancelEvent = (info: TLCancelEventInfo) => void; -+ -+/** @public */ -+export declare interface TLCancelEventInfo { -+ type: 'misc'; -+ name: 'cancel'; -+} -+ -+/** @public */ -+export declare interface TLCanvasComponentProps { -+ className?: string; -+} -+ -+/** @public */ -+export declare type TLClickEvent = (info: TLClickEventInfo) => void; -+ -+/** @public */ -+export declare type TLClickEventInfo = TLBaseEventInfo & { -+ button: number; -+ name: TLCLickEventName; -+ phase: 'down' | 'settle' | 'up'; -+ point: VecLike; -+ pointerId: number; -+ type: 'click'; -+} & TLPointerEventTarget; -+ -+/** @public */ -+export declare type TLCLickEventName = 'double_click' | 'quadruple_click' | 'triple_click'; -+ -+/** @public */ -+export declare type TLClickState = 'idle' | 'overflow' | 'pendingDouble' | 'pendingOverflow' | 'pendingQuadruple' | 'pendingTriple'; -+ -+/** @public */ -+export declare interface TLCollaboratorHintProps { -+ className?: string; -+ point: VecModel; -+ viewport: Box; -+ zoom: number; -+ opacity?: number; -+ color: string; -+} -+ -+/** @public */ -+export declare type TLCompleteEvent = (info: TLCompleteEventInfo) => void; -+ -+/** @public */ -+export declare interface TLCompleteEventInfo { -+ type: 'misc'; -+ name: 'complete'; -+} -+ -+/** @public */ -+export declare interface TLContent { -+ shapes: TLShape[]; -+ bindings: TLBinding[] | undefined; -+ rootShapeIds: TLShapeId[]; -+ assets: TLAsset[]; -+ schema: SerializedSchema; -+} -+ -+/** @public */ -+export declare interface TLCursorProps { -+ className?: string; -+ point: null | VecModel; -+ zoom: number; -+ color?: string; -+ name: null | string; -+ chatMessage: string; -+} -+ -+/** @public */ -+export declare type TLDeepLink = { -+ bounds: BoxModel; -+ pageId?: TLPageId; -+ type: 'viewport'; -+} | { -+ pageId: TLPageId; -+ type: 'page'; -+} | { -+ shapeIds: TLShapeId[]; -+ type: 'shapes'; -+}; -+ -+/** @public */ -+export declare interface TLDeepLinkOptions { -+ /** -+ * The name of the url search param to use for the deep link. -+ * -+ * Defaults to `'d'` -+ */ -+ param?: string; -+ /** -+ * The debounce time in ms for updating the url. -+ */ -+ debounceMs?: number; -+ /** -+ * Should return the current url to augment with a deep link query parameter. -+ * If you supply this function, you must also supply an `onChange` function. -+ */ -+ getUrl?(editor: Editor): string | URL; -+ /** -+ * Should return the current deep link target. -+ * Defaults to returning the current page and viewport position. -+ */ -+ getTarget?(editor: Editor): TLDeepLink; -+ /** -+ * This is fired when the URL is updated. -+ * -+ * If not supplied, the default behavior is to update `window.location`. -+ * -+ * @param url - the updated URL -+ */ -+ onChange?(url: URL, editor: Editor): void; -+} -+ -+/** @public @react */ -+export declare const TldrawEditor: React_2.NamedExoticComponent; -+ -+/** -+ * Base props for the {@link tldraw#Tldraw} and {@link TldrawEditor} components. -+ * -+ * @public -+ */ -+export declare interface TldrawEditorBaseProps { -+ /** -+ * The component's children. -+ */ -+ children?: ReactNode; -+ /** -+ * An array of shape utils to use in the editor. -+ */ -+ shapeUtils?: readonly TLAnyShapeUtilConstructor[]; -+ /** -+ * An array of binding utils to use in the editor. -+ */ -+ bindingUtils?: readonly TLAnyBindingUtilConstructor[]; -+ /** -+ * An array of tools to add to the editor's state chart. -+ */ -+ tools?: readonly TLStateNodeConstructor[]; -+ /** -+ * Whether to automatically focus the editor when it mounts. -+ */ -+ autoFocus?: boolean; -+ /** -+ * Overrides for the editor's components, such as handles, collaborator cursors, etc. -+ */ -+ components?: TLEditorComponents; -+ /** -+ * Called when the editor has mounted. -+ */ -+ onMount?: TLOnMountHandler; -+ /** -+ * The editor's initial state (usually the id of the first active tool). -+ */ -+ initialState?: string; -+ /** -+ * A classname to pass to the editor's container. -+ */ -+ className?: string; -+ /** -+ * The user interacting with the editor. -+ */ -+ user?: TLUser; -+ /** -+ * Whether to infer dark mode from the user's OS. Defaults to false. -+ */ -+ inferDarkMode?: boolean; -+ /** -+ * Camera options for the editor. -+ */ -+ cameraOptions?: Partial; -+ /** -+ * Options for the editor. -+ */ -+ options?: Partial; -+ /** -+ * The license key. -+ */ -+ licenseKey?: string; -+ /** -+ * Options for syncing the editor's camera state with the URL. -+ */ -+ deepLinks?: TLDeepLinkOptions | true; -+ /** -+ * Predicate for whether or not a shape should be hidden. -+ * -+ * Hidden shapes will not render in the editor, and they will not be eligible for hit test via -+ * {@link Editor#getShapeAtPoint} and {@link Editor#getShapesAtPoint}. But otherwise they will -+ * remain in the store and participate in all other operations. -+ */ -+ isShapeHidden?(shape: TLShape, editor: Editor): boolean; -+} -+ -+/** -+ * Props for the {@link tldraw#Tldraw} and {@link TldrawEditor} components. -+ * -+ * @public -+ **/ -+export declare type TldrawEditorProps = TldrawEditorBaseProps & TldrawEditorStoreProps; -+ -+/** @public */ -+export declare type TldrawEditorStoreProps = TldrawEditorWithoutStoreProps | TldrawEditorWithStoreProps; -+ -+/** -+ * Props for the {@link tldraw#Tldraw} and {@link TldrawEditor} components, when not passing in a -+ * {@link store#TLStore} directly. If you would like to pass in a store directly, use -+ * {@link TldrawEditorWithStoreProps}. -+ * -+ * @public -+ */ -+export declare interface TldrawEditorWithoutStoreProps extends TLStoreBaseOptions { -+ store?: undefined; -+ /** -+ * Additional migrations to use in the store -+ */ -+ migrations?: readonly MigrationSequence[]; -+ /** -+ * A starting snapshot of data to pre-populate the store. Do not supply both this and -+ * `initialData`. -+ */ -+ snapshot?: TLEditorSnapshot | TLStoreSnapshot; -+ /** -+ * If you would like to persist the store to the browser's local IndexedDB storage and sync it -+ * across tabs, provide a key here. Each key represents a single tldraw document. -+ */ -+ persistenceKey?: string; -+ sessionId?: string; -+} -+ -+/** -+ * Props for the {@link tldraw#Tldraw} and {@link TldrawEditor} components, when passing in a -+ * {@link store#TLStore} directly. If you would like tldraw to create a store for you, use -+ * {@link TldrawEditorWithoutStoreProps}. -+ * -+ * @public -+ */ -+export declare interface TldrawEditorWithStoreProps { -+ /** -+ * The store to use in the editor. -+ */ -+ store: TLStore | TLStoreWithStatus; -+} -+ -+/** -+ * Options for configuring tldraw. For defaults, see {@link defaultTldrawOptions}. -+ * -+ * @example -+ * ```tsx -+ * const options: Partial = { -+ * maxPages: 3, -+ * maxShapesPerPage: 1000, -+ * } -+ * -+ * function MyTldrawComponent() { -+ * return -+ * } -+ * ``` -+ * -+ * @public -+ */ -+export declare interface TldrawOptions { -+ readonly maxShapesPerPage: number; -+ readonly maxFilesAtOnce: number; -+ readonly maxPages: number; -+ readonly animationMediumMs: number; -+ readonly followChaseViewportSnap: number; -+ readonly doubleClickDurationMs: number; -+ readonly multiClickDurationMs: number; -+ readonly coarseDragDistanceSquared: number; -+ readonly dragDistanceSquared: number; -+ readonly defaultSvgPadding: number; -+ readonly cameraSlideFriction: number; -+ readonly maxPointsPerDrawShape: number; -+ readonly gridSteps: readonly { -+ readonly mid: number; -+ readonly min: number; -+ readonly step: number; -+ }[]; -+ readonly collaboratorInactiveTimeoutMs: number; -+ readonly collaboratorIdleTimeoutMs: number; -+ readonly collaboratorCheckIntervalMs: number; -+ readonly cameraMovingTimeoutMs: number; -+ readonly hitTestMargin: number; -+ readonly edgeScrollDelay: number; -+ readonly edgeScrollEaseDuration: number; -+ readonly edgeScrollSpeed: number; -+ readonly edgeScrollDistance: number; -+ readonly coarsePointerWidth: number; -+ readonly coarseHandleRadius: number; -+ readonly handleRadius: number; -+ readonly longPressDurationMs: number; -+ readonly textShadowLod: number; -+ readonly adjacentShapeMargin: number; -+ readonly flattenImageBoundsExpand: number; -+ readonly flattenImageBoundsPadding: number; -+ readonly laserDelayMs: number; -+ readonly maxExportDelayMs: number; -+ /** -+ * How long should previews created by {@link Editor.createTemporaryAssetPreview} last before -+ * they expire? Defaults to 3 minutes. -+ */ -+ readonly temporaryAssetPreviewLifetimeMs: number; -+} -+ -+/** @public */ -+export declare interface TLEditorComponents { -+ Background?: ComponentType | null; -+ SvgDefs?: ComponentType | null; -+ Brush?: ComponentType | null; -+ ZoomBrush?: ComponentType | null; -+ ShapeIndicators?: ComponentType | null; -+ ShapeIndicator?: ComponentType | null; -+ Cursor?: ComponentType | null; -+ Canvas?: ComponentType | null; -+ CollaboratorBrush?: ComponentType | null; -+ CollaboratorCursor?: ComponentType | null; -+ CollaboratorHint?: ComponentType | null; -+ CollaboratorShapeIndicator?: ComponentType | null; -+ Grid?: ComponentType | null; -+ Scribble?: ComponentType | null; -+ CollaboratorScribble?: ComponentType | null; -+ SnapIndicator?: ComponentType | null; -+ Handles?: ComponentType | null; -+ Handle?: ComponentType | null; -+ Spinner?: ComponentType | null; -+ SelectionForeground?: ComponentType | null; -+ SelectionBackground?: ComponentType | null; -+ OnTheCanvas?: ComponentType | null; -+ InFrontOfTheCanvas?: ComponentType | null; -+ LoadingScreen?: ComponentType | null; -+ ErrorFallback?: TLErrorFallbackComponent; -+ ShapeErrorFallback?: TLShapeErrorFallbackComponent; -+ ShapeIndicatorErrorFallback?: TLShapeIndicatorErrorFallbackComponent; -+} -+ -+/** @public */ -+export declare interface TLEditorOptions { -+ /** -+ * The Store instance to use for keeping the app's data. This may be prepopulated, e.g. by loading -+ * from a server or database. -+ */ -+ store: TLStore; -+ /** -+ * An array of shapes to use in the editor. These will be used to create and manage shapes in the editor. -+ */ -+ shapeUtils: readonly TLAnyShapeUtilConstructor[]; -+ /** -+ * An array of bindings to use in the editor. These will be used to create and manage bindings in the editor. -+ */ -+ bindingUtils: readonly TLAnyBindingUtilConstructor[]; -+ /** -+ * An array of tools to use in the editor. These will be used to handle events and manage user interactions in the editor. -+ */ -+ tools: readonly TLStateNodeConstructor[]; -+ /** -+ * Should return a containing html element which has all the styles applied to the editor. If not -+ * given, the body element will be used. -+ */ -+ getContainer(): HTMLElement; -+ /** -+ * A user defined externally to replace the default user. -+ */ -+ user?: TLUser; -+ /** -+ * The editor's initial active tool (or other state node id). -+ */ -+ initialState?: string; -+ /** -+ * Whether to automatically focus the editor when it mounts. -+ */ -+ autoFocus?: boolean; -+ /** -+ * Whether to infer dark mode from the user's system preferences. Defaults to false. -+ */ -+ inferDarkMode?: boolean; -+ /** -+ * Options for the editor's camera. -+ */ -+ cameraOptions?: Partial; -+ options?: Partial; -+ licenseKey?: string; -+ /** -+ * A predicate that should return true if the given shape should be hidden. -+ * @param shape - The shape to check. -+ * @param editor - The editor instance. -+ */ -+ isShapeHidden?(shape: TLShape, editor: Editor): boolean; -+} -+ -+/** -+ * Options for {@link Editor.(run:1)}. -+ * @public -+ */ -+export declare interface TLEditorRunOptions extends TLHistoryBatchOptions { -+ ignoreShapeLock?: boolean; -+} -+ -+/** @public */ -+export declare interface TLEditorSnapshot { -+ document: TLStoreSnapshot; -+ session: TLSessionStateSnapshot; -+} -+ -+/** @public */ -+export declare type TLEnterEventHandler = (info: any, from: string) => void; -+ -+/** @public */ -+export declare interface TLErrorBoundaryProps { -+ children: React_3.ReactNode; -+ onError?: ((error: unknown) => void) | null; -+ fallback: TLErrorFallbackComponent; -+} -+ -+/** @public */ -+export declare type TLErrorFallbackComponent = ComponentType<{ -+ editor?: Editor; -+ error: unknown; -+}>; -+ -+/** @public */ -+export declare interface TLEventHandlers { -+ onPointerDown: TLPointerEvent; -+ onPointerMove: TLPointerEvent; -+ onLongPress: TLPointerEvent; -+ onRightClick: TLPointerEvent; -+ onDoubleClick: TLClickEvent; -+ onTripleClick: TLClickEvent; -+ onQuadrupleClick: TLClickEvent; -+ onMiddleClick: TLPointerEvent; -+ onPointerUp: TLPointerEvent; -+ onKeyDown: TLKeyboardEvent; -+ onKeyUp: TLKeyboardEvent; -+ onKeyRepeat: TLKeyboardEvent; -+ onWheel: TLWheelEvent; -+ onCancel: TLCancelEvent; -+ onComplete: TLCompleteEvent; -+ onInterrupt: TLInterruptEvent; -+ onTick: TLTickEvent; -+} -+ -+/** @public */ -+export declare type TLEventInfo = TLCancelEventInfo | TLClickEventInfo | TLCompleteEventInfo | TLInterruptEventInfo | TLKeyboardEventInfo | TLPinchEventInfo | TLPointerEventInfo | TLTickEventInfo | TLWheelEventInfo; -+ -+/** @public */ -+export declare interface TLEventMap { -+ mount: []; -+ 'max-shapes': [{ -+ count: number; -+ name: string; -+ pageId: TLPageId; -+ }]; -+ change: [HistoryEntry]; -+ update: []; -+ crash: [{ -+ error: unknown; -+ }]; -+ 'stop-camera-animation': []; -+ 'stop-following': []; -+ event: [TLEventInfo]; -+ tick: [number]; -+ frame: [number]; -+ 'select-all-text': [{ -+ shapeId: TLShapeId; -+ }]; -+} -+ -+/** @public */ -+export declare type TLEventMapHandler = (...args: TLEventMap[T]) => void; -+ -+/** @public */ -+export declare type TLEventName = 'cancel' | 'complete' | 'interrupt' | 'tick' | 'wheel' | TLCLickEventName | TLKeyboardEventName | TLPinchEventName | TLPointerEventName; -+ -+/** @public */ -+export declare type TLExitEventHandler = (info: any, to: string) => void; -+ -+/** @public */ -+export declare type TLExternalAssetContent = { -+ assetId?: TLAssetId; -+ file: File; -+ type: 'file'; -+} | { -+ type: 'url'; -+ url: string; -+}; -+ -+/** @public */ -+export declare type TLExternalContent = { -+ point?: VecLike; -+ sources?: TLExternalContentSource[]; -+} & ({ -+ embed: EmbedDefinition; -+ type: 'embed'; -+ url: string; -+} | { -+ files: File[]; -+ ignoreParent: boolean; -+ type: 'files'; -+} | { -+ text: string; -+ type: 'svg-text'; -+} | { -+ text: string; -+ type: 'text'; -+} | { -+ type: 'url'; -+ url: string; -+}); -+ -+/** @public */ -+export declare type TLExternalContentSource = { -+ data: any; -+ type: 'excalidraw'; -+} | { -+ data: null | string; -+ reason: string; -+ type: 'error'; -+} | { -+ data: string; -+ subtype: 'html' | 'json' | 'text' | 'url'; -+ type: 'text'; -+} | { -+ data: TLContent; -+ type: 'tldraw'; -+}; -+ -+/** @public */ -+export declare interface TLGridProps { -+ x: number; -+ y: number; -+ z: number; -+ size: number; -+} -+ -+/** @public */ -+export declare interface TLHandleDragInfo { -+ handle: TLHandle; -+ isPrecise: boolean; -+ initial?: T | undefined; -+} -+ -+/** @public */ -+export declare interface TLHandleProps { -+ shapeId: TLShapeId; -+ handle: TLHandle; -+ zoom: number; -+ isCoarse: boolean; -+ className?: string; -+} -+ -+/** @public */ -+export declare interface TLHandlesProps { -+ children: ReactNode; -+} -+ -+/** @public */ -+export declare interface TLHistoryBatchOptions { -+ /** -+ * How should this change interact with the history stack? -+ * - record: Add to the undo stack and clear the redo stack -+ * - record-preserveRedoStack: Add to the undo stack but do not clear the redo stack -+ * - ignore: Do not add to the undo stack or the redo stack -+ */ -+ history?: 'ignore' | 'record-preserveRedoStack' | 'record'; -+} -+ -+/** @public */ -+export declare interface TLHistoryDiff { -+ type: 'diff'; -+ diff: RecordsDiff; -+} -+ -+/** @public */ -+export declare type TLHistoryEntry = TLHistoryDiff | TLHistoryMark; -+ -+/** @public */ -+export declare interface TLHistoryMark { -+ type: 'stop'; -+ id: string; -+} -+ -+/** @public */ -+export declare interface TLImageExportOptions { -+ bounds?: Box; -+ scale?: number; -+ background?: boolean; -+ padding?: number; -+ darkMode?: boolean; -+ preserveAspectRatio?: React.SVGAttributes['preserveAspectRatio']; -+} -+ -+/** @public */ -+export declare type TLInterruptEvent = (info: TLInterruptEventInfo) => void; -+ -+/** @public */ -+export declare interface TLInterruptEventInfo { -+ type: 'misc'; -+ name: 'interrupt'; -+} -+ -+/** @public */ -+export declare type TLKeyboardEvent = (info: TLKeyboardEventInfo) => void; -+ -+/** @public */ -+export declare type TLKeyboardEventInfo = TLBaseEventInfo & { -+ code: string; -+ key: string; -+ name: TLKeyboardEventName; -+ type: 'keyboard'; -+}; -+ -+/** @public */ -+export declare type TLKeyboardEventName = 'key_down' | 'key_repeat' | 'key_up'; -+ -+/** -+ * Options for {@link loadSessionStateSnapshotIntoStore} -+ * @public -+ */ -+export declare interface TLLoadSessionStateSnapshotOptions { -+ /** -+ * By default, some session state flags like `isDebugMode` are not overwritten when loading a snapshot. -+ * These are usually considered "sticky" by users while the document data is not. -+ * If you want to overwrite these flags, set this to `true`. -+ */ -+ forceOverwrite?: boolean; -+} -+ -+/** -+ * Options for {@link loadSnapshot} -+ * @public -+ */ -+export declare interface TLLoadSnapshotOptions { -+ /** -+ * By default, some session state flags like `isDebugMode` are not overwritten when loading a snapshot. -+ * These are usually considered "sticky" by users while the document data is not. -+ * If you want to overwrite these flags, set this to `true`. -+ */ -+ forceOverwriteSessionState?: boolean; -+} -+ -+/** @public */ -+export declare interface TLMeasureTextSpanOpts { -+ overflow: 'truncate-clip' | 'truncate-ellipsis' | 'wrap'; -+ width: number; -+ height: number; -+ padding: number; -+ fontSize: number; -+ fontWeight: string; -+ fontFamily: string; -+ fontStyle: string; -+ lineHeight: number; -+ textAlign: TLDefaultHorizontalAlignStyle; -+} -+ -+/** -+ * Called when the editor has mounted. -+ * @example -+ * ```ts -+ * editor.selectAll()} /> -+ * ``` -+ * @param editor - The editor instance. -+ * -+ * @public -+ */ -+export declare type TLOnMountHandler = (editor: Editor) => (() => undefined | void) | undefined | void; -+ -+/** @public */ -+export declare type TLPinchEvent = (info: TLPinchEventInfo) => void; -+ -+/** @public */ -+export declare type TLPinchEventInfo = TLBaseEventInfo & { -+ delta: VecModel; -+ name: TLPinchEventName; -+ point: VecModel; -+ type: 'pinch'; -+}; -+ -+/** @public */ -+export declare type TLPinchEventName = 'pinch_end' | 'pinch_start' | 'pinch'; -+ -+/** @public */ -+export declare type TLPointerEvent = (info: TLPointerEventInfo) => void; -+ -+/** @public */ -+export declare type TLPointerEventInfo = TLBaseEventInfo & { -+ button: number; -+ isPen: boolean; -+ name: TLPointerEventName; -+ point: VecLike; -+ pointerId: number; -+ type: 'pointer'; -+} & TLPointerEventTarget; -+ -+/** @public */ -+export declare type TLPointerEventName = 'long_press' | 'middle_click' | 'pointer_down' | 'pointer_move' | 'pointer_up' | 'right_click'; -+ -+/** @public */ -+export declare type TLPointerEventTarget = { -+ handle: TLHandle; -+ shape: TLShape; -+ target: 'handle'; -+} | { -+ handle?: TLSelectionHandle; -+ shape?: undefined; -+ target: 'selection'; -+} | { -+ shape: TLShape; -+ target: 'shape'; -+} | { -+ shape?: undefined; -+ target: 'canvas'; -+}; -+ -+/** @public */ -+export declare interface TLRenderingShape { -+ id: TLShapeId; -+ shape: TLShape; -+ util: ShapeUtil; -+ index: number; -+ backgroundIndex: number; -+ opacity: number; -+} -+ -+/** @public */ -+export declare type TLResizeHandle = SelectionCorner | SelectionEdge; -+ -+/** -+ * Info about a resize. -+ * @param newPoint - The new local position of the shape. -+ * @param handle - The handle being dragged. -+ * @param mode - The type of resize. -+ * @param scaleX - The scale in the x-axis. -+ * @param scaleY - The scale in the y-axis. -+ * @param initialBounds - The bounds of the shape at the start of the resize. -+ * @param initialShape - The shape at the start of the resize. -+ * @public -+ */ -+export declare interface TLResizeInfo { -+ newPoint: Vec; -+ handle: TLResizeHandle; -+ mode: TLResizeMode; -+ scaleX: number; -+ scaleY: number; -+ initialBounds: Box; -+ initialShape: T; -+} -+ -+/** -+ * The type of resize. -+ * -+ * 'scale_shape' - The shape is being scaled, usually as part of a larger selection. -+ * -+ * 'resize_bounds' - The user is directly manipulating an individual shape's bounds using a resize -+ * handle. It is up to shape util implementers to decide how they want to handle the two -+ * situations. -+ * -+ * @public -+ */ -+export declare type TLResizeMode = 'resize_bounds' | 'scale_shape'; -+ -+/** @public */ -+export declare type TLResizeShapeOptions = Partial<{ -+ dragHandle: TLResizeHandle; -+ initialBounds: Box; -+ initialPageTransform: MatLike; -+ initialShape: TLShape; -+ isAspectRatioLocked: boolean; -+ mode: TLResizeMode; -+ scaleAxisRotation: number; -+ scaleOrigin: VecLike; -+ skipStartAndEndCallbacks: boolean; -+}>; -+ -+/* Excluded from this release type: TLRotationSnapshot */ -+ -+/** @public */ -+export declare interface TLScribbleProps { -+ scribble: TLScribble; -+ zoom: number; -+ color?: string; -+ opacity?: number; -+ className?: string; -+} -+ -+/** @public */ -+export declare interface TLSelectionBackgroundProps { -+ bounds: Box; -+ rotation: number; -+} -+ -+/** @public */ -+export declare interface TLSelectionForegroundProps { -+ bounds: Box; -+ rotation: number; -+} -+ -+/** @public */ -+export declare type TLSelectionHandle = RotateCorner | SelectionCorner | SelectionEdge; -+ -+/** -+ * The state of the editor instance, not including any document state. -+ * -+ * @public -+ */ -+export declare interface TLSessionStateSnapshot { -+ version: number; -+ currentPageId?: TLPageId; -+ isFocusMode?: boolean; -+ exportBackground?: boolean; -+ isDebugMode?: boolean; -+ isToolLocked?: boolean; -+ isGridMode?: boolean; -+ pageStates?: Array<{ -+ camera?: { -+ x: number; -+ y: number; -+ z: number; -+ }; -+ focusedGroupId?: null | TLShapeId; -+ pageId: TLPageId; -+ selectedShapeIds?: TLShapeId[]; -+ }>; -+} -+ -+/** @public */ -+export declare type TLShapeErrorFallbackComponent = ComponentType<{ -+ error: any; -+}>; -+ -+/** @public */ -+export declare type TLShapeIndicatorErrorFallbackComponent = ComponentType<{ -+ error: unknown; -+}>; -+ -+/** @public */ -+export declare interface TLShapeIndicatorProps { -+ shapeId: TLShapeId; -+ color?: string | undefined; -+ opacity?: number; -+ className?: string; -+ hidden?: boolean; -+} -+ -+/** -+ * Options passed to {@link ShapeUtil.canBind}. A binding that could be made. At least one of -+ * `fromShapeType` or `toShapeType` will belong to this shape util. -+ * -+ * @public -+ */ -+export declare interface TLShapeUtilCanBindOpts { -+ /** The type of shape referenced by the `fromId` of the binding. */ -+ fromShapeType: string; -+ /** The type of shape referenced by the `toId` of the binding. */ -+ toShapeType: string; -+ /** The type of binding. */ -+ bindingType: string; -+} -+ -+/** @public */ -+export declare interface TLShapeUtilCanvasSvgDef { -+ key: string; -+ component: React.ComponentType; -+} -+ -+/** @public */ -+export declare interface TLShapeUtilConstructor = ShapeUtil> { -+ new (editor: Editor): U; -+ type: T['type']; -+ props?: RecordProps; -+ migrations?: LegacyMigrations | MigrationSequence | TLPropsMigrations; -+} -+ -+/** @public */ -+export declare interface TLSnapIndicatorProps { -+ className?: string; -+ line: SnapIndicator; -+ zoom: number; -+} -+ -+/** @public */ -+export declare interface TLStateNodeConstructor { -+ new (editor: Editor, parent?: StateNode): StateNode; -+ id: string; -+ initial?: string; -+ children?(): TLStateNodeConstructor[]; -+ isLockable: boolean; -+} -+ -+/** @public */ -+export declare interface TLStoreBaseOptions { -+ /** The initial data for the store. */ -+ initialData?: SerializedStore; -+ /** A snapshot of initial data to migrate and load into the store. */ -+ snapshot?: Partial | TLStoreSnapshot; -+ /** The default name for the store. */ -+ defaultName?: string; -+ /** How should this store upload & resolve assets? */ -+ assets?: TLAssetStore; -+ /** Called when the store is connected to an {@link Editor}. */ -+ onMount?(editor: Editor): (() => void) | void; -+} -+ -+/** @public */ -+export declare type TLStoreEventInfo = HistoryEntry; -+ -+/** @public */ -+export declare type TLStoreOptions = TLStoreBaseOptions & { -+ /** Collaboration options for the store. */ -+ collaboration?: { -+ status: null | Signal<'offline' | 'online'>; -+ }; -+ id?: string; -+} & TLStoreSchemaOptions; -+ -+/** @public */ -+export declare type TLStoreSchemaOptions = { -+ bindingUtils?: readonly TLAnyBindingUtilConstructor[]; -+ migrations?: readonly MigrationSequence[]; -+ shapeUtils?: readonly TLAnyShapeUtilConstructor[]; -+} | { -+ schema?: StoreSchema; -+}; -+ -+/** @public */ -+export declare type TLStoreWithStatus = { -+ readonly connectionStatus: 'offline' | 'online'; -+ readonly error?: undefined; -+ readonly status: 'synced-remote'; -+ readonly store: TLStore; -+} | { -+ readonly error: Error; -+ readonly status: 'error'; -+ readonly store?: undefined; -+} | { -+ readonly error?: undefined; -+ readonly status: 'loading'; -+ readonly store?: undefined; -+} | { -+ readonly error?: undefined; -+ readonly status: 'not-synced'; -+ readonly store: TLStore; -+} | { -+ readonly error?: undefined; -+ readonly status: 'synced-local'; -+ readonly store: TLStore; -+}; -+ -+/** -+ * @public -+ * @deprecated use {@link TLImageExportOptions} instead -+ */ -+export declare type TLSvgOptions = TLImageExportOptions; -+ -+/** @public */ -+export declare type TLTickEvent = (info: TLTickEventInfo) => void; -+ -+/** @public */ -+export declare interface TLTickEventInfo { -+ type: 'misc'; -+ name: 'tick'; -+ elapsed: number; -+} -+ -+/** @public */ -+export declare interface TLUser { -+ readonly userPreferences: Signal; -+ readonly setUserPreferences: (userPreferences: TLUserPreferences) => void; -+} -+ -+/** -+ * A user of tldraw -+ * -+ * @public -+ */ -+export declare interface TLUserPreferences { -+ id: string; -+ name?: null | string; -+ locale?: null | string; -+ color?: null | string; -+ animationSpeed?: null | number; -+ edgeScrollSpeed?: null | number; -+ colorScheme?: 'dark' | 'light' | 'system'; -+ isSnapMode?: boolean | null; -+ isWrapMode?: boolean | null; -+ isDynamicSizeMode?: boolean | null; -+ isPasteAtCursorMode?: boolean | null; -+} -+ -+/** @public */ -+export declare type TLWheelEvent = (info: TLWheelEventInfo) => void; -+ -+/** @public */ -+export declare type TLWheelEventInfo = TLBaseEventInfo & { -+ delta: VecModel; -+ name: 'wheel'; -+ point: VecModel; -+ type: 'wheel'; -+}; -+ -+/** -+ * The DOM likes values to be fixed to 3 decimal places -+ * -+ * @public -+ */ -+export declare function toDomPrecision(v: number): number; -+ -+/** -+ * @public -+ */ -+export declare function toFixed(v: number): number; -+ -+/** -+ * Get a number to a precision. -+ * -+ * @param n - The number. -+ * @param precision - The precision. -+ * @public -+ */ -+export declare function toPrecision(n: number, precision?: number): number; -+ -+export { track } -+ -+export { transact } -+ -+export { transaction } -+ -+/** @public */ -+export declare type UiEvent = TLCancelEvent | TLClickEvent | TLCompleteEvent | TLKeyboardEvent | TLPinchEvent | TLPointerEvent; -+ -+/** @public */ -+export declare type UiEventType = 'click' | 'keyboard' | 'pinch' | 'pointer' | 'wheel' | 'zoom'; -+ -+/** @public */ -+export declare function uniq(array: { -+ readonly [n: number]: T; -+ readonly length: number; -+} | null | undefined): T[]; -+ -+export { useAtom } -+ -+export { useComputed } -+ -+/** @public */ -+export declare function useContainer(): HTMLElement; -+ -+/** -+ * Delay an SVG export until the returned function is called. This is useful if e.g. your shape -+ * loads data dynamically, and you need to prevent the export from happening until after the data is -+ * loaded. -+ * -+ * If used outside of an SVG export, this hook has no effect. -+ * -+ * @example -+ * ```tsx -+ * const readyForExport = useDelaySvgExport() -+ * -+ * return readyForExport()} /> -+ * ``` -+ * -+ * @public -+ */ -+export declare function useDelaySvgExport(): () => void; -+ -+/** @public */ -+export declare function useEditor(): Editor; -+ -+/** @public */ -+export declare function useEditorComponents(): Required; -+ -+/* Excluded from this release type: useEvent */ -+ -+/** @public */ -+export declare function useIsCropping(shapeId: TLShapeId): boolean; -+ -+/** @public */ -+export declare function useIsDarkMode(): boolean; -+ -+/** @public */ -+export declare function useIsEditing(shapeId: TLShapeId): boolean; -+ -+/* Excluded from this release type: useLocalStore */ -+ -+/* Excluded from this release type: useOnMount */ -+ -+/* Excluded from this release type: usePeerIds */ -+ -+/* Excluded from this release type: usePresence */ -+export { useQuickReactor } -+ -+/* Excluded from this release type: USER_COLORS */ -+export { useReactor } -+ -+/* Excluded from this release type: useRefState */ -+ -+/** @public */ -+export declare class UserPreferencesManager { -+ private readonly user; -+ private readonly inferDarkMode; -+ systemColorScheme: Atom<"dark" | "light", unknown>; -+ constructor(user: TLUser, inferDarkMode: boolean); -+ updateUserPreferences(userPreferences: Partial): void; -+ getUserPreferences(): { -+ animationSpeed: number; -+ color: string; -+ colorScheme: "dark" | "light" | "system" | undefined; -+ id: string; -+ isDarkMode: boolean; -+ isDynamicResizeMode: boolean; -+ isSnapMode: boolean; -+ isWrapMode: boolean; -+ locale: string; -+ name: string; -+ }; -+ getIsDarkMode(): boolean; -+ /** -+ * The speed at which the user can scroll by dragging toward the edge of the screen. -+ */ -+ getEdgeScrollSpeed(): number; -+ getAnimationSpeed(): number; -+ getId(): string; -+ getName(): string; -+ getLocale(): string; -+ getColor(): string; -+ getIsSnapMode(): boolean; -+ getIsWrapMode(): boolean; -+ getIsDynamicResizeMode(): boolean; -+ getIsPasteAtCursorMode(): boolean; -+} -+ -+/* Excluded from this release type: useSafeId */ -+ -+/** @public */ -+export declare function useSelectionEvents(handle: TLSelectionHandle): { -+ onPointerDown: PointerEventHandler; -+ onPointerMove: (e: React.PointerEvent) => void; -+ onPointerUp: PointerEventHandler; -+}; -+ -+/* Excluded from this release type: useShallowArrayIdentity */ -+ -+/* Excluded from this release type: useShallowObjectIdentity */ -+export { useStateTracking } -+ -+/** -+ * Returns the current SVG export context. Returns null if the component isn't being rendered for an -+ * SVG export. -+ * -+ * @public -+ */ -+export declare function useSvgExportContext(): null | SvgExportContext; -+ -+/** -+ * @public -+ */ -+export declare function useTldrawUser(opts: { -+ setUserPreferences?: (userPreferences: TLUserPreferences) => void; -+ userPreferences?: Signal | TLUserPreferences; -+}): TLUser; -+ -+/** @public */ -+export declare function useTLSchemaFromUtils(opts: TLStoreSchemaOptions): StoreSchema; -+ -+/** @public */ -+export declare function useTLStore(opts: TLStoreOptions): TLStore; -+ -+/** @public */ -+export declare function useTransform(ref: React.RefObject, x?: number, y?: number, scale?: number, rotate?: number, additionalOffset?: VecLike): void; -+ -+export { useValue } -+ -+/* Excluded from this release type: ValidLicenseKeyResult */ -+ -+/** @public */ -+export declare class Vec { -+ x: number; -+ y: number; -+ z: number; -+ constructor(x?: number, y?: number, z?: number); -+ get pressure(): number; -+ set(x?: number, y?: number, z?: number): this; -+ setTo({ x, y, z }: VecLike): this; -+ rot(r: number): this; -+ rotWith(C: VecLike, r: number): this; -+ clone(): Vec; -+ sub(V: VecLike): this; -+ subXY(x: number, y: number): this; -+ subScalar(n: number): this; -+ add(V: VecLike): this; -+ addXY(x: number, y: number): this; -+ addScalar(n: number): this; -+ clamp(min: number, max?: number): this; -+ div(t: number): this; -+ divV(V: VecLike): this; -+ mul(t: number): this; -+ mulV(V: VecLike): this; -+ abs(): this; -+ nudge(B: VecLike, distance: number): this; -+ neg(): this; -+ cross(V: VecLike): this; -+ dpr(V: VecLike): number; -+ cpr(V: VecLike): number; -+ len2(): number; -+ len(): number; -+ pry(V: VecLike): number; -+ per(): this; -+ uni(): Vec; -+ tan(V: VecLike): Vec; -+ dist(V: VecLike): number; -+ distanceToLineSegment(A: VecLike, B: VecLike): number; -+ slope(B: VecLike): number; -+ snapToGrid(gridSize: number): this; -+ angle(B: VecLike): number; -+ toAngle(): number; -+ lrp(B: VecLike, t: number): Vec; -+ equals(B: VecLike): boolean; -+ equalsXY(x: number, y: number): boolean; -+ norm(): this; -+ toFixed(): Vec; -+ toString(): string; -+ toJson(): VecModel; -+ toArray(): number[]; -+ static Add(A: VecLike, B: VecLike): Vec; -+ static AddXY(A: VecLike, x: number, y: number): Vec; -+ static Sub(A: VecLike, B: VecLike): Vec; -+ static SubXY(A: VecLike, x: number, y: number): Vec; -+ static AddScalar(A: VecLike, n: number): Vec; -+ static SubScalar(A: VecLike, n: number): Vec; -+ static Div(A: VecLike, t: number): Vec; -+ static Mul(A: VecLike, t: number): Vec; -+ static DivV(A: VecLike, B: VecLike): Vec; -+ static MulV(A: VecLike, B: VecLike): Vec; -+ static Neg(A: VecLike): Vec; -+ /** -+ * Get the perpendicular vector to A. -+ */ -+ static Per(A: VecLike): Vec; -+ static Abs(A: VecLike): Vec; -+ static Dist(A: VecLike, B: VecLike): number; -+ static DistMin(A: VecLike, B: VecLike, n: number): boolean; -+ static Dist2(A: VecLike, B: VecLike): number; -+ /** -+ * Dot product of two vectors which is used to calculate the angle between them. -+ */ -+ static Dpr(A: VecLike, B: VecLike): number; -+ static Cross(A: VecLike, V: VecLike): Vec; -+ /** -+ * Cross product of two vectors which is used to calculate the area of a parallelogram. -+ */ -+ static Cpr(A: VecLike, B: VecLike): number; -+ static Len2(A: VecLike): number; -+ static Len(A: VecLike): number; -+ /** -+ * Get the projection of A onto B. -+ */ -+ static Pry(A: VecLike, B: VecLike): number; -+ /** -+ * Get the unit vector of A. -+ */ -+ static Uni(A: VecLike): Vec; -+ static Tan(A: VecLike, B: VecLike): Vec; -+ static Min(A: VecLike, B: VecLike): Vec; -+ static Max(A: VecLike, B: VecLike): Vec; -+ static From({ x, y, z }: VecModel): Vec; -+ static FromArray(v: number[]): Vec; -+ static Rot(A: VecLike, r?: number): Vec; -+ static RotWith(A: VecLike, C: VecLike, r: number): Vec; -+ /** -+ * Get the nearest point on a line with a known unit vector that passes through point A -+ * -+ * ```ts -+ * Vec.nearestPointOnLineThroughPoint(A, u, Point) -+ * ``` -+ * -+ * @param A - Any point on the line -+ * @param u - The unit vector for the line. -+ * @param P - A point not on the line to test. -+ */ -+ static NearestPointOnLineThroughPoint(A: VecLike, u: VecLike, P: VecLike): Vec; -+ static NearestPointOnLineSegment(A: VecLike, B: VecLike, P: VecLike, clamp?: boolean): Vec; -+ static DistanceToLineThroughPoint(A: VecLike, u: VecLike, P: VecLike): number; -+ static DistanceToLineSegment(A: VecLike, B: VecLike, P: VecLike, clamp?: boolean): number; -+ static Snap(A: VecLike, step?: number): Vec; -+ static Cast(A: VecLike): Vec; -+ static Slope(A: VecLike, B: VecLike): number; -+ static IsNaN(A: VecLike): boolean; -+ static Angle(A: VecLike, B: VecLike): number; -+ /** -+ * Linearly interpolate between two points. -+ * @param A - The first point. -+ * @param B - The second point. -+ * @param t - The interpolation value between 0 and 1. -+ * @returns The interpolated point. -+ */ -+ static Lrp(A: VecLike, B: VecLike, t: number): Vec; -+ static Med(A: VecLike, B: VecLike): Vec; -+ static Equals(A: VecLike, B: VecLike): boolean; -+ static EqualsXY(A: VecLike, x: number, y: number): boolean; -+ static Clockwise(A: VecLike, B: VecLike, C: VecLike): boolean; -+ static Rescale(A: VecLike, n: number): Vec; -+ static ScaleWithOrigin(A: VecLike, scale: number, origin: VecLike): Vec; -+ static ToFixed(A: VecLike): Vec; -+ static ToInt(A: VecLike): Vec; -+ static ToCss(A: VecLike): string; -+ static Nudge(A: VecLike, B: VecLike, distance: number): Vec; -+ static ToString(A: VecLike): string; -+ static ToAngle(A: VecLike): number; -+ static FromAngle(r: number, length?: number): Vec; -+ static ToArray(A: VecLike): number[]; -+ static ToJson(A: VecLike): { -+ x: number; -+ y: number; -+ z: number | undefined; -+ }; -+ static Average(arr: VecLike[]): Vec; -+ static Clamp(A: Vec, min: number, max?: number): Vec; -+ /** -+ * Get an array of points (with simulated pressure) between two points. -+ * -+ * @param A - The first point. -+ * @param B - The second point. -+ * @param steps - The number of points to return. -+ */ -+ static PointsBetween(A: VecModel, B: VecModel, steps?: number): Vec[]; -+ static SnapToGrid(A: VecLike, gridSize?: number): Vec; -+} -+ -+/** @public */ -+export declare type VecLike = Vec | VecModel; -+ -+export { whyAmIRunning } -+ -+ -+export * from "@tldraw/store"; -+export * from "@tldraw/tlschema"; -+export * from "@tldraw/utils"; -+export * from "@tldraw/validate"; -+ -+export { } -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/index.mjs b/node_modules/@tldraw/editor/dist-cjs/dist-esm/index.mjs -new file mode 100644 -index 0000000..f6e6d84 ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/index.mjs -@@ -0,0 +1,468 @@ -+import { registerTldrawLibraryVersion } from "@tldraw/utils"; -+import "core-js/stable/array/at.js"; -+import "core-js/stable/array/flat-map.js"; -+import "core-js/stable/array/flat.js"; -+import "core-js/stable/string/at.js"; -+import "core-js/stable/string/replace-all.js"; -+export * from "@tldraw/store"; -+export * from "@tldraw/tlschema"; -+export * from "@tldraw/utils"; -+export * from "@tldraw/validate"; -+import { -+ EMPTY_ARRAY, -+ EffectScheduler, -+ atom, -+ computed, -+ react, -+ transact, -+ transaction, -+ whyAmIRunning -+} from "@tldraw/state"; -+import { -+ track, -+ useAtom, -+ useComputed, -+ useQuickReactor, -+ useReactor, -+ useStateTracking, -+ useValue -+} from "@tldraw/state-react"; -+import { -+ ErrorScreen, -+ LoadingScreen, -+ TldrawEditor, -+ useOnMount -+} from "./lib/TldrawEditor.mjs"; -+import { -+ ErrorBoundary, -+ OptionalErrorBoundary -+} from "./lib/components/ErrorBoundary.mjs"; -+import { HTMLContainer } from "./lib/components/HTMLContainer.mjs"; -+import { SVGContainer } from "./lib/components/SVGContainer.mjs"; -+import { DefaultBackground } from "./lib/components/default-components/DefaultBackground.mjs"; -+import { DefaultBrush } from "./lib/components/default-components/DefaultBrush.mjs"; -+import { -+ DefaultCanvas -+} from "./lib/components/default-components/DefaultCanvas.mjs"; -+import { -+ DefaultCollaboratorHint -+} from "./lib/components/default-components/DefaultCollaboratorHint.mjs"; -+import { -+ DefaultCursor -+} from "./lib/components/default-components/DefaultCursor.mjs"; -+import { -+ DefaultErrorFallback -+} from "./lib/components/default-components/DefaultErrorFallback.mjs"; -+import { DefaultGrid } from "./lib/components/default-components/DefaultGrid.mjs"; -+import { -+ DefaultHandle -+} from "./lib/components/default-components/DefaultHandle.mjs"; -+import { -+ DefaultHandles -+} from "./lib/components/default-components/DefaultHandles.mjs"; -+import { -+ DefaultScribble -+} from "./lib/components/default-components/DefaultScribble.mjs"; -+import { -+ DefaultSelectionBackground -+} from "./lib/components/default-components/DefaultSelectionBackground.mjs"; -+import { -+ DefaultSelectionForeground -+} from "./lib/components/default-components/DefaultSelectionForeground.mjs"; -+import { -+ DefaultShapeIndicator -+} from "./lib/components/default-components/DefaultShapeIndicator.mjs"; -+import { DefaultShapeIndicators } from "./lib/components/default-components/DefaultShapeIndicators.mjs"; -+import { -+ DefaultSnapIndicator -+} from "./lib/components/default-components/DefaultSnapIndictor.mjs"; -+import { DefaultSpinner } from "./lib/components/default-components/DefaultSpinner.mjs"; -+import { DefaultSvgDefs } from "./lib/components/default-components/DefaultSvgDefs.mjs"; -+import { -+ getSnapshot, -+ loadSnapshot -+} from "./lib/config/TLEditorSnapshot.mjs"; -+import { -+ TAB_ID, -+ createSessionStateSnapshotSignal, -+ extractSessionStateFromLegacySnapshot, -+ loadSessionStateSnapshotIntoStore -+} from "./lib/config/TLSessionStateSnapshot.mjs"; -+import { -+ USER_COLORS, -+ defaultUserPreferences, -+ getFreshUserPreferences, -+ getUserPreferences, -+ setUserPreferences -+} from "./lib/config/TLUserPreferences.mjs"; -+import { -+ createTLSchemaFromUtils, -+ createTLStore, -+ inlineBase64AssetStore -+} from "./lib/config/createTLStore.mjs"; -+import { createTLUser, useTldrawUser } from "./lib/config/createTLUser.mjs"; -+import { coreShapes } from "./lib/config/defaultShapes.mjs"; -+import { DEFAULT_ANIMATION_OPTIONS, DEFAULT_CAMERA_OPTIONS, SIDES } from "./lib/constants.mjs"; -+import { -+ Editor -+} from "./lib/editor/Editor.mjs"; -+import { -+ BindingUtil -+} from "./lib/editor/bindings/BindingUtil.mjs"; -+import { ClickManager } from "./lib/editor/managers/ClickManager.mjs"; -+import { EdgeScrollManager } from "./lib/editor/managers/EdgeScrollManager.mjs"; -+import { EnvironmentManager } from "./lib/editor/managers/EnvironmentManager.mjs"; -+import { HistoryManager } from "./lib/editor/managers/HistoryManager.mjs"; -+import { ScribbleManager } from "./lib/editor/managers/ScribbleManager.mjs"; -+import { -+ BoundsSnaps -+} from "./lib/editor/managers/SnapManager/BoundsSnaps.mjs"; -+import { HandleSnaps } from "./lib/editor/managers/SnapManager/HandleSnaps.mjs"; -+import { -+ SnapManager -+} from "./lib/editor/managers/SnapManager/SnapManager.mjs"; -+import { TextManager } from "./lib/editor/managers/TextManager.mjs"; -+import { UserPreferencesManager } from "./lib/editor/managers/UserPreferencesManager.mjs"; -+import { BaseBoxShapeUtil } from "./lib/editor/shapes/BaseBoxShapeUtil.mjs"; -+import { -+ ShapeUtil -+} from "./lib/editor/shapes/ShapeUtil.mjs"; -+import { GroupShapeUtil } from "./lib/editor/shapes/group/GroupShapeUtil.mjs"; -+import { getPerfectDashProps } from "./lib/editor/shapes/shared/getPerfectDashProps.mjs"; -+import { resizeBox } from "./lib/editor/shapes/shared/resizeBox.mjs"; -+import { BaseBoxShapeTool } from "./lib/editor/tools/BaseBoxShapeTool/BaseBoxShapeTool.mjs"; -+import { StateNode } from "./lib/editor/tools/StateNode.mjs"; -+import { -+ useDelaySvgExport, -+ useSvgExportContext -+} from "./lib/editor/types/SvgExportContext.mjs"; -+import { -+ EVENT_NAME_MAP -+} from "./lib/editor/types/event-types.mjs"; -+import { ContainerProvider, useContainer } from "./lib/hooks/useContainer.mjs"; -+import { getCursor } from "./lib/hooks/useCursor.mjs"; -+import { useEditor } from "./lib/hooks/useEditor.mjs"; -+import { useEditorComponents } from "./lib/hooks/useEditorComponents.mjs"; -+import { useEvent } from "./lib/hooks/useEvent.mjs"; -+import { useShallowArrayIdentity, useShallowObjectIdentity } from "./lib/hooks/useIdentity.mjs"; -+import { useIsCropping } from "./lib/hooks/useIsCropping.mjs"; -+import { useIsDarkMode } from "./lib/hooks/useIsDarkMode.mjs"; -+import { useIsEditing } from "./lib/hooks/useIsEditing.mjs"; -+import { useLocalStore } from "./lib/hooks/useLocalStore.mjs"; -+import { usePeerIds } from "./lib/hooks/usePeerIds.mjs"; -+import { usePresence } from "./lib/hooks/usePresence.mjs"; -+import { useRefState } from "./lib/hooks/useRefState.mjs"; -+import { useSafeId } from "./lib/hooks/useSafeId.mjs"; -+import { useSelectionEvents } from "./lib/hooks/useSelectionEvents.mjs"; -+import { useTLSchemaFromUtils, useTLStore } from "./lib/hooks/useTLStore.mjs"; -+import { useTransform } from "./lib/hooks/useTransform.mjs"; -+import { -+ LicenseManager -+} from "./lib/license/LicenseManager.mjs"; -+import { defaultTldrawOptions } from "./lib/options.mjs"; -+import { -+ Box, -+ ROTATE_CORNER_TO_SELECTION_CORNER, -+ rotateSelectionHandle -+} from "./lib/primitives/Box.mjs"; -+import { Mat } from "./lib/primitives/Mat.mjs"; -+import { Vec } from "./lib/primitives/Vec.mjs"; -+import { EASINGS } from "./lib/primitives/easings.mjs"; -+import { Arc2d } from "./lib/primitives/geometry/Arc2d.mjs"; -+import { Circle2d } from "./lib/primitives/geometry/Circle2d.mjs"; -+import { CubicBezier2d } from "./lib/primitives/geometry/CubicBezier2d.mjs"; -+import { CubicSpline2d } from "./lib/primitives/geometry/CubicSpline2d.mjs"; -+import { Edge2d } from "./lib/primitives/geometry/Edge2d.mjs"; -+import { Ellipse2d } from "./lib/primitives/geometry/Ellipse2d.mjs"; -+import { Geometry2d } from "./lib/primitives/geometry/Geometry2d.mjs"; -+import { Group2d } from "./lib/primitives/geometry/Group2d.mjs"; -+import { Point2d } from "./lib/primitives/geometry/Point2d.mjs"; -+import { Polygon2d } from "./lib/primitives/geometry/Polygon2d.mjs"; -+import { Polyline2d } from "./lib/primitives/geometry/Polyline2d.mjs"; -+import { Rectangle2d } from "./lib/primitives/geometry/Rectangle2d.mjs"; -+import { Stadium2d } from "./lib/primitives/geometry/Stadium2d.mjs"; -+import { -+ intersectCircleCircle, -+ intersectCirclePolygon, -+ intersectCirclePolyline, -+ intersectLineSegmentCircle, -+ intersectLineSegmentLineSegment, -+ intersectLineSegmentPolygon, -+ intersectLineSegmentPolyline, -+ intersectPolygonBounds, -+ intersectPolygonPolygon, -+ linesIntersect, -+ polygonIntersectsPolyline, -+ polygonsIntersect -+} from "./lib/primitives/intersect.mjs"; -+import { -+ HALF_PI, -+ PI, -+ PI2, -+ SIN, -+ angleDistance, -+ approximately, -+ areAnglesCompatible, -+ average, -+ canonicalizeRotation, -+ centerOfCircleFromThreePoints, -+ clamp, -+ clampRadians, -+ clockwiseAngleDist, -+ counterClockwiseAngleDist, -+ degreesToRadians, -+ getArcMeasure, -+ getPointInArcT, -+ getPointOnCircle, -+ getPointsOnArc, -+ getPolygonVertices, -+ isSafeFloat, -+ perimeterOfEllipse, -+ pointInPolygon, -+ precise, -+ radiansToDegrees, -+ rangeIntersection, -+ shortAngleDist, -+ snapAngle, -+ toDomPrecision, -+ toFixed, -+ toPrecision -+} from "./lib/primitives/utils.mjs"; -+import { -+ ReadonlySharedStyleMap, -+ SharedStyleMap -+} from "./lib/utils/SharedStylesMap.mjs"; -+import { dataUrlToFile, getDefaultCdnBaseUrl } from "./lib/utils/assets.mjs"; -+import { -+ debugFlags, -+ featureFlags -+} from "./lib/utils/debug-flags.mjs"; -+import { -+ createDeepLinkString, -+ parseDeepLinkString -+} from "./lib/utils/deepLinks.mjs"; -+import { -+ loopToHtmlElement, -+ preventDefault, -+ releasePointerCapture, -+ setPointerCapture, -+ stopEventPropagation -+} from "./lib/utils/dom.mjs"; -+import { getIncrementedName } from "./lib/utils/getIncrementedName.mjs"; -+import { getPointerInfo } from "./lib/utils/getPointerInfo.mjs"; -+import { getSvgPathFromPoints } from "./lib/utils/getSvgPathFromPoints.mjs"; -+import { hardResetEditor } from "./lib/utils/hardResetEditor.mjs"; -+import { normalizeWheel } from "./lib/utils/normalizeWheel.mjs"; -+import { refreshPage } from "./lib/utils/refreshPage.mjs"; -+import { -+ applyRotationToSnapshotShapes, -+ getRotationSnapshot -+} from "./lib/utils/rotation.mjs"; -+import { runtime, setRuntimeOverrides } from "./lib/utils/runtime.mjs"; -+import { hardReset } from "./lib/utils/sync/hardReset.mjs"; -+import { uniq } from "./lib/utils/uniq.mjs"; -+import { openWindow } from "./lib/utils/window-open.mjs"; -+function debugEnableLicensing() { -+ return; -+} -+registerTldrawLibraryVersion( -+ "@tldraw/editor", -+ "3.2.0", -+ "esm" -+); -+export { -+ Arc2d, -+ BaseBoxShapeTool, -+ BaseBoxShapeUtil, -+ BindingUtil, -+ BoundsSnaps, -+ Box, -+ Circle2d, -+ ClickManager, -+ ContainerProvider, -+ CubicBezier2d, -+ CubicSpline2d, -+ DEFAULT_ANIMATION_OPTIONS, -+ DEFAULT_CAMERA_OPTIONS, -+ DefaultBackground, -+ DefaultBrush, -+ DefaultCanvas, -+ DefaultCollaboratorHint, -+ DefaultCursor, -+ DefaultErrorFallback, -+ DefaultGrid, -+ DefaultHandle, -+ DefaultHandles, -+ DefaultScribble, -+ DefaultSelectionBackground, -+ DefaultSelectionForeground, -+ DefaultShapeIndicator, -+ DefaultShapeIndicators, -+ DefaultSnapIndicator, -+ DefaultSpinner, -+ DefaultSvgDefs, -+ EASINGS, -+ EMPTY_ARRAY, -+ EVENT_NAME_MAP, -+ Edge2d, -+ EdgeScrollManager, -+ Editor, -+ EffectScheduler, -+ Ellipse2d, -+ EnvironmentManager, -+ ErrorBoundary, -+ ErrorScreen, -+ Geometry2d, -+ Group2d, -+ GroupShapeUtil, -+ HALF_PI, -+ HTMLContainer, -+ HandleSnaps, -+ HistoryManager, -+ LicenseManager, -+ LoadingScreen, -+ Mat, -+ OptionalErrorBoundary, -+ PI, -+ PI2, -+ Point2d, -+ Polygon2d, -+ Polyline2d, -+ ROTATE_CORNER_TO_SELECTION_CORNER, -+ ReadonlySharedStyleMap, -+ Rectangle2d, -+ SIDES, -+ SIN, -+ SVGContainer, -+ ScribbleManager, -+ ShapeUtil, -+ SharedStyleMap, -+ SnapManager, -+ Stadium2d, -+ StateNode, -+ TAB_ID, -+ TextManager, -+ TldrawEditor, -+ USER_COLORS, -+ UserPreferencesManager, -+ Vec, -+ angleDistance, -+ applyRotationToSnapshotShapes, -+ approximately, -+ areAnglesCompatible, -+ atom, -+ average, -+ canonicalizeRotation, -+ centerOfCircleFromThreePoints, -+ clamp, -+ clampRadians, -+ clockwiseAngleDist, -+ computed, -+ coreShapes, -+ counterClockwiseAngleDist, -+ createDeepLinkString, -+ createSessionStateSnapshotSignal, -+ createTLSchemaFromUtils, -+ createTLStore, -+ createTLUser, -+ dataUrlToFile, -+ debugEnableLicensing, -+ debugFlags, -+ defaultTldrawOptions, -+ defaultUserPreferences, -+ degreesToRadians, -+ extractSessionStateFromLegacySnapshot, -+ featureFlags, -+ getArcMeasure, -+ getCursor, -+ getDefaultCdnBaseUrl, -+ getFreshUserPreferences, -+ getIncrementedName, -+ getPerfectDashProps, -+ getPointInArcT, -+ getPointOnCircle, -+ getPointerInfo, -+ getPointsOnArc, -+ getPolygonVertices, -+ getRotationSnapshot, -+ getSnapshot, -+ getSvgPathFromPoints, -+ getUserPreferences, -+ hardReset, -+ hardResetEditor, -+ inlineBase64AssetStore, -+ intersectCircleCircle, -+ intersectCirclePolygon, -+ intersectCirclePolyline, -+ intersectLineSegmentCircle, -+ intersectLineSegmentLineSegment, -+ intersectLineSegmentPolygon, -+ intersectLineSegmentPolyline, -+ intersectPolygonBounds, -+ intersectPolygonPolygon, -+ isSafeFloat, -+ linesIntersect, -+ loadSessionStateSnapshotIntoStore, -+ loadSnapshot, -+ loopToHtmlElement, -+ normalizeWheel, -+ openWindow, -+ parseDeepLinkString, -+ perimeterOfEllipse, -+ pointInPolygon, -+ polygonIntersectsPolyline, -+ polygonsIntersect, -+ precise, -+ preventDefault, -+ radiansToDegrees, -+ rangeIntersection, -+ react, -+ refreshPage, -+ releasePointerCapture, -+ resizeBox, -+ rotateSelectionHandle, -+ runtime, -+ setPointerCapture, -+ setRuntimeOverrides, -+ setUserPreferences, -+ shortAngleDist, -+ snapAngle, -+ stopEventPropagation, -+ toDomPrecision, -+ toFixed, -+ toPrecision, -+ track, -+ transact, -+ transaction, -+ uniq, -+ useAtom, -+ useComputed, -+ useContainer, -+ useDelaySvgExport, -+ useEditor, -+ useEditorComponents, -+ useEvent, -+ useIsCropping, -+ useIsDarkMode, -+ useIsEditing, -+ useLocalStore, -+ useOnMount, -+ usePeerIds, -+ usePresence, -+ useQuickReactor, -+ useReactor, -+ useRefState, -+ useSafeId, -+ useSelectionEvents, -+ useShallowArrayIdentity, -+ useShallowObjectIdentity, -+ useStateTracking, -+ useSvgExportContext, -+ useTLSchemaFromUtils, -+ useTLStore, -+ useTldrawUser, -+ useTransform, -+ useValue, -+ whyAmIRunning -+}; -+//# sourceMappingURL=index.mjs.map -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/index.mjs.map b/node_modules/@tldraw/editor/dist-cjs/dist-esm/index.mjs.map -new file mode 100644 -index 0000000..f848006 ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/index.mjs.map -@@ -0,0 +1,7 @@ -+{ -+ "version": 3, -+ "sources": ["../src/index.ts"], -+ "sourcesContent": ["import { registerTldrawLibraryVersion } from '@tldraw/utils'\nimport 'core-js/stable/array/at.js'\nimport 'core-js/stable/array/flat-map.js'\nimport 'core-js/stable/array/flat.js'\nimport 'core-js/stable/string/at.js'\nimport 'core-js/stable/string/replace-all.js'\n\n// eslint-disable-next-line local/no-export-star\nexport * from '@tldraw/store'\n// eslint-disable-next-line local/no-export-star\nexport * from '@tldraw/tlschema'\n// eslint-disable-next-line local/no-export-star\nexport * from '@tldraw/utils'\n// eslint-disable-next-line local/no-export-star\nexport * from '@tldraw/validate'\n\nexport {\n\tEMPTY_ARRAY,\n\tEffectScheduler,\n\tatom,\n\tcomputed,\n\treact,\n\ttransact,\n\ttransaction,\n\twhyAmIRunning,\n\ttype Atom,\n\ttype Signal,\n} from '@tldraw/state'\nexport {\n\ttrack,\n\tuseAtom,\n\tuseComputed,\n\tuseQuickReactor,\n\tuseReactor,\n\tuseStateTracking,\n\tuseValue,\n} from '@tldraw/state-react'\nexport {\n\tErrorScreen,\n\tLoadingScreen,\n\tTldrawEditor,\n\tuseOnMount,\n\ttype LoadingScreenProps,\n\ttype TLOnMountHandler,\n\ttype TldrawEditorBaseProps,\n\ttype TldrawEditorProps,\n\ttype TldrawEditorStoreProps,\n\ttype TldrawEditorWithStoreProps,\n\ttype TldrawEditorWithoutStoreProps,\n} from './lib/TldrawEditor'\nexport {\n\tErrorBoundary,\n\tOptionalErrorBoundary,\n\ttype TLErrorBoundaryProps,\n} from './lib/components/ErrorBoundary'\nexport { HTMLContainer, type HTMLContainerProps } from './lib/components/HTMLContainer'\nexport { SVGContainer, type SVGContainerProps } from './lib/components/SVGContainer'\nexport { DefaultBackground } from './lib/components/default-components/DefaultBackground'\nexport { DefaultBrush, type TLBrushProps } from './lib/components/default-components/DefaultBrush'\nexport {\n\tDefaultCanvas,\n\ttype TLCanvasComponentProps,\n} from './lib/components/default-components/DefaultCanvas'\nexport {\n\tDefaultCollaboratorHint,\n\ttype TLCollaboratorHintProps,\n} from './lib/components/default-components/DefaultCollaboratorHint'\nexport {\n\tDefaultCursor,\n\ttype TLCursorProps,\n} from './lib/components/default-components/DefaultCursor'\nexport {\n\tDefaultErrorFallback,\n\ttype TLErrorFallbackComponent,\n} from './lib/components/default-components/DefaultErrorFallback'\nexport { DefaultGrid, type TLGridProps } from './lib/components/default-components/DefaultGrid'\nexport {\n\tDefaultHandle,\n\ttype TLHandleProps,\n} from './lib/components/default-components/DefaultHandle'\nexport {\n\tDefaultHandles,\n\ttype TLHandlesProps,\n} from './lib/components/default-components/DefaultHandles'\nexport {\n\tDefaultScribble,\n\ttype TLScribbleProps,\n} from './lib/components/default-components/DefaultScribble'\nexport {\n\tDefaultSelectionBackground,\n\ttype TLSelectionBackgroundProps,\n} from './lib/components/default-components/DefaultSelectionBackground'\nexport {\n\tDefaultSelectionForeground,\n\ttype TLSelectionForegroundProps,\n} from './lib/components/default-components/DefaultSelectionForeground'\nexport { type TLShapeErrorFallbackComponent } from './lib/components/default-components/DefaultShapeErrorFallback'\nexport {\n\tDefaultShapeIndicator,\n\ttype TLShapeIndicatorProps,\n} from './lib/components/default-components/DefaultShapeIndicator'\nexport { type TLShapeIndicatorErrorFallbackComponent } from './lib/components/default-components/DefaultShapeIndicatorErrorFallback'\nexport { DefaultShapeIndicators } from './lib/components/default-components/DefaultShapeIndicators'\nexport {\n\tDefaultSnapIndicator,\n\ttype TLSnapIndicatorProps,\n} from './lib/components/default-components/DefaultSnapIndictor'\nexport { DefaultSpinner } from './lib/components/default-components/DefaultSpinner'\nexport { DefaultSvgDefs } from './lib/components/default-components/DefaultSvgDefs'\nexport {\n\tgetSnapshot,\n\tloadSnapshot,\n\ttype TLEditorSnapshot,\n\ttype TLLoadSnapshotOptions,\n} from './lib/config/TLEditorSnapshot'\nexport {\n\tTAB_ID,\n\tcreateSessionStateSnapshotSignal,\n\textractSessionStateFromLegacySnapshot,\n\tloadSessionStateSnapshotIntoStore,\n\ttype TLLoadSessionStateSnapshotOptions,\n\ttype TLSessionStateSnapshot,\n} from './lib/config/TLSessionStateSnapshot'\nexport {\n\tUSER_COLORS,\n\tdefaultUserPreferences,\n\tgetFreshUserPreferences,\n\tgetUserPreferences,\n\tsetUserPreferences,\n\ttype TLUserPreferences,\n} from './lib/config/TLUserPreferences'\nexport {\n\tcreateTLSchemaFromUtils,\n\tcreateTLStore,\n\tinlineBase64AssetStore,\n\ttype TLStoreBaseOptions,\n\ttype TLStoreEventInfo,\n\ttype TLStoreOptions,\n\ttype TLStoreSchemaOptions,\n} from './lib/config/createTLStore'\nexport { createTLUser, useTldrawUser, type TLUser } from './lib/config/createTLUser'\nexport { type TLAnyBindingUtilConstructor } from './lib/config/defaultBindings'\nexport { coreShapes, type TLAnyShapeUtilConstructor } from './lib/config/defaultShapes'\nexport { DEFAULT_ANIMATION_OPTIONS, DEFAULT_CAMERA_OPTIONS, SIDES } from './lib/constants'\nexport {\n\tEditor,\n\ttype TLEditorOptions,\n\ttype TLEditorRunOptions,\n\ttype TLRenderingShape,\n\ttype TLResizeShapeOptions,\n} from './lib/editor/Editor'\nexport {\n\tBindingUtil,\n\ttype BindingOnChangeOptions,\n\ttype BindingOnCreateOptions,\n\ttype BindingOnDeleteOptions,\n\ttype BindingOnShapeChangeOptions,\n\ttype BindingOnShapeDeleteOptions,\n\ttype BindingOnShapeIsolateOptions,\n\ttype TLBindingUtilConstructor,\n} from './lib/editor/bindings/BindingUtil'\nexport { ClickManager, type TLClickState } from './lib/editor/managers/ClickManager'\nexport { EdgeScrollManager } from './lib/editor/managers/EdgeScrollManager'\nexport { EnvironmentManager } from './lib/editor/managers/EnvironmentManager'\nexport { HistoryManager } from './lib/editor/managers/HistoryManager'\nexport { ScribbleManager, type ScribbleItem } from './lib/editor/managers/ScribbleManager'\nexport {\n\tBoundsSnaps,\n\ttype BoundsSnapGeometry,\n\ttype BoundsSnapPoint,\n} from './lib/editor/managers/SnapManager/BoundsSnaps'\nexport { HandleSnaps, type HandleSnapGeometry } from './lib/editor/managers/SnapManager/HandleSnaps'\nexport {\n\tSnapManager,\n\ttype GapsSnapIndicator,\n\ttype PointsSnapIndicator,\n\ttype SnapData,\n\ttype SnapIndicator,\n} from './lib/editor/managers/SnapManager/SnapManager'\nexport { TextManager, type TLMeasureTextSpanOpts } from './lib/editor/managers/TextManager'\nexport { UserPreferencesManager } from './lib/editor/managers/UserPreferencesManager'\nexport { BaseBoxShapeUtil, type TLBaseBoxShape } from './lib/editor/shapes/BaseBoxShapeUtil'\nexport {\n\tShapeUtil,\n\ttype TLHandleDragInfo,\n\ttype TLResizeInfo,\n\ttype TLResizeMode,\n\ttype TLShapeUtilCanBindOpts,\n\ttype TLShapeUtilCanvasSvgDef,\n\ttype TLShapeUtilConstructor,\n} from './lib/editor/shapes/ShapeUtil'\nexport { GroupShapeUtil } from './lib/editor/shapes/group/GroupShapeUtil'\nexport { getPerfectDashProps } from './lib/editor/shapes/shared/getPerfectDashProps'\nexport { resizeBox, type ResizeBoxOptions } from './lib/editor/shapes/shared/resizeBox'\nexport { BaseBoxShapeTool } from './lib/editor/tools/BaseBoxShapeTool/BaseBoxShapeTool'\nexport { StateNode, type TLStateNodeConstructor } from './lib/editor/tools/StateNode'\nexport {\n\tuseDelaySvgExport,\n\tuseSvgExportContext,\n\ttype SvgExportContext,\n\ttype SvgExportDef,\n} from './lib/editor/types/SvgExportContext'\nexport { type TLContent } from './lib/editor/types/clipboard-types'\nexport { type TLEventMap, type TLEventMapHandler } from './lib/editor/types/emit-types'\nexport {\n\tEVENT_NAME_MAP,\n\ttype TLBaseEventInfo,\n\ttype TLCLickEventName,\n\ttype TLCancelEvent,\n\ttype TLCancelEventInfo,\n\ttype TLClickEvent,\n\ttype TLClickEventInfo,\n\ttype TLCompleteEvent,\n\ttype TLCompleteEventInfo,\n\ttype TLEnterEventHandler,\n\ttype TLEventHandlers,\n\ttype TLEventInfo,\n\ttype TLEventName,\n\ttype TLExitEventHandler,\n\ttype TLInterruptEvent,\n\ttype TLInterruptEventInfo,\n\ttype TLKeyboardEvent,\n\ttype TLKeyboardEventInfo,\n\ttype TLKeyboardEventName,\n\ttype TLPinchEvent,\n\ttype TLPinchEventInfo,\n\ttype TLPinchEventName,\n\ttype TLPointerEvent,\n\ttype TLPointerEventInfo,\n\ttype TLPointerEventName,\n\ttype TLPointerEventTarget,\n\ttype TLTickEvent,\n\ttype TLTickEventInfo,\n\ttype TLWheelEvent,\n\ttype TLWheelEventInfo,\n\ttype UiEvent,\n\ttype UiEventType,\n} from './lib/editor/types/event-types'\nexport {\n\ttype TLExternalAssetContent,\n\ttype TLExternalContent,\n\ttype TLExternalContentSource,\n} from './lib/editor/types/external-content'\nexport {\n\ttype TLHistoryBatchOptions,\n\ttype TLHistoryDiff,\n\ttype TLHistoryEntry,\n\ttype TLHistoryMark,\n} from './lib/editor/types/history-types'\nexport {\n\ttype OptionalKeys,\n\ttype RequiredKeys,\n\ttype TLCameraConstraints,\n\ttype TLCameraMoveOptions,\n\ttype TLCameraOptions,\n\ttype TLImageExportOptions,\n\t// eslint-disable-next-line deprecation/deprecation\n\ttype TLSvgOptions,\n} from './lib/editor/types/misc-types'\nexport { type TLResizeHandle, type TLSelectionHandle } from './lib/editor/types/selection-types'\nexport { ContainerProvider, useContainer } from './lib/hooks/useContainer'\nexport { getCursor } from './lib/hooks/useCursor'\nexport { useEditor } from './lib/hooks/useEditor'\nexport { useEditorComponents } from './lib/hooks/useEditorComponents'\nexport type { TLEditorComponents } from './lib/hooks/useEditorComponents'\nexport { useEvent } from './lib/hooks/useEvent'\nexport { useShallowArrayIdentity, useShallowObjectIdentity } from './lib/hooks/useIdentity'\nexport { useIsCropping } from './lib/hooks/useIsCropping'\nexport { useIsDarkMode } from './lib/hooks/useIsDarkMode'\nexport { useIsEditing } from './lib/hooks/useIsEditing'\nexport { useLocalStore } from './lib/hooks/useLocalStore'\nexport { usePeerIds } from './lib/hooks/usePeerIds'\nexport { usePresence } from './lib/hooks/usePresence'\nexport { useRefState } from './lib/hooks/useRefState'\nexport { useSafeId } from './lib/hooks/useSafeId'\nexport { useSelectionEvents } from './lib/hooks/useSelectionEvents'\nexport { useTLSchemaFromUtils, useTLStore } from './lib/hooks/useTLStore'\nexport { useTransform } from './lib/hooks/useTransform'\nexport {\n\tLicenseManager,\n\ttype InvalidLicenseKeyResult,\n\ttype InvalidLicenseReason,\n\ttype LicenseFromKeyResult,\n\ttype LicenseInfo,\n\ttype TestEnvironment,\n\ttype ValidLicenseKeyResult,\n} from './lib/license/LicenseManager'\nexport { defaultTldrawOptions, type TldrawOptions } from './lib/options'\nexport {\n\tBox,\n\tROTATE_CORNER_TO_SELECTION_CORNER,\n\trotateSelectionHandle,\n\ttype BoxLike,\n\ttype RotateCorner,\n\ttype SelectionCorner,\n\ttype SelectionEdge,\n\ttype SelectionHandle,\n} from './lib/primitives/Box'\nexport { Mat, type MatLike, type MatModel } from './lib/primitives/Mat'\nexport { Vec, type VecLike } from './lib/primitives/Vec'\nexport { EASINGS } from './lib/primitives/easings'\nexport { Arc2d } from './lib/primitives/geometry/Arc2d'\nexport { Circle2d } from './lib/primitives/geometry/Circle2d'\nexport { CubicBezier2d } from './lib/primitives/geometry/CubicBezier2d'\nexport { CubicSpline2d } from './lib/primitives/geometry/CubicSpline2d'\nexport { Edge2d } from './lib/primitives/geometry/Edge2d'\nexport { Ellipse2d } from './lib/primitives/geometry/Ellipse2d'\nexport { Geometry2d, type Geometry2dOptions } from './lib/primitives/geometry/Geometry2d'\nexport { Group2d } from './lib/primitives/geometry/Group2d'\nexport { Point2d } from './lib/primitives/geometry/Point2d'\nexport { Polygon2d } from './lib/primitives/geometry/Polygon2d'\nexport { Polyline2d } from './lib/primitives/geometry/Polyline2d'\nexport { Rectangle2d } from './lib/primitives/geometry/Rectangle2d'\nexport { Stadium2d } from './lib/primitives/geometry/Stadium2d'\nexport {\n\tintersectCircleCircle,\n\tintersectCirclePolygon,\n\tintersectCirclePolyline,\n\tintersectLineSegmentCircle,\n\tintersectLineSegmentLineSegment,\n\tintersectLineSegmentPolygon,\n\tintersectLineSegmentPolyline,\n\tintersectPolygonBounds,\n\tintersectPolygonPolygon,\n\tlinesIntersect,\n\tpolygonIntersectsPolyline,\n\tpolygonsIntersect,\n} from './lib/primitives/intersect'\nexport {\n\tHALF_PI,\n\tPI,\n\tPI2,\n\tSIN,\n\tangleDistance,\n\tapproximately,\n\tareAnglesCompatible,\n\taverage,\n\tcanonicalizeRotation,\n\tcenterOfCircleFromThreePoints,\n\tclamp,\n\tclampRadians,\n\tclockwiseAngleDist,\n\tcounterClockwiseAngleDist,\n\tdegreesToRadians,\n\tgetArcMeasure,\n\tgetPointInArcT,\n\tgetPointOnCircle,\n\tgetPointsOnArc,\n\tgetPolygonVertices,\n\tisSafeFloat,\n\tperimeterOfEllipse,\n\tpointInPolygon,\n\tprecise,\n\tradiansToDegrees,\n\trangeIntersection,\n\tshortAngleDist,\n\tsnapAngle,\n\ttoDomPrecision,\n\ttoFixed,\n\ttoPrecision,\n} from './lib/primitives/utils'\nexport {\n\tReadonlySharedStyleMap,\n\tSharedStyleMap,\n\ttype SharedStyle,\n} from './lib/utils/SharedStylesMap'\nexport { dataUrlToFile, getDefaultCdnBaseUrl } from './lib/utils/assets'\nexport {\n\tdebugFlags,\n\tfeatureFlags,\n\ttype DebugFlag,\n\ttype DebugFlagDef,\n\ttype DebugFlagDefaults,\n} from './lib/utils/debug-flags'\nexport {\n\tcreateDeepLinkString,\n\tparseDeepLinkString,\n\ttype TLDeepLink,\n\ttype TLDeepLinkOptions,\n} from './lib/utils/deepLinks'\nexport {\n\tloopToHtmlElement,\n\tpreventDefault,\n\treleasePointerCapture,\n\tsetPointerCapture,\n\tstopEventPropagation,\n} from './lib/utils/dom'\nexport { getIncrementedName } from './lib/utils/getIncrementedName'\nexport { getPointerInfo } from './lib/utils/getPointerInfo'\nexport { getSvgPathFromPoints } from './lib/utils/getSvgPathFromPoints'\nexport { hardResetEditor } from './lib/utils/hardResetEditor'\nexport { normalizeWheel } from './lib/utils/normalizeWheel'\nexport { refreshPage } from './lib/utils/refreshPage'\nexport {\n\tapplyRotationToSnapshotShapes,\n\tgetRotationSnapshot,\n\ttype TLRotationSnapshot,\n} from './lib/utils/rotation'\nexport { runtime, setRuntimeOverrides } from './lib/utils/runtime'\nexport { type TLStoreWithStatus } from './lib/utils/sync/StoreWithStatus'\nexport { hardReset } from './lib/utils/sync/hardReset'\nexport { uniq } from './lib/utils/uniq'\nexport { openWindow } from './lib/utils/window-open'\n\n/**\n * @deprecated Licensing is now enabled in the tldraw SDK.\n * @public */\nexport function debugEnableLicensing() {\n\t// noop\n\treturn\n}\n\nregisterTldrawLibraryVersion(\n\t(globalThis as any).TLDRAW_LIBRARY_NAME,\n\t(globalThis as any).TLDRAW_LIBRARY_VERSION,\n\t(globalThis as any).TLDRAW_LIBRARY_MODULES\n)\n"], -+ "mappings": "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", -+ "names": [] -+} -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/TldrawEditor.mjs b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/TldrawEditor.mjs -new file mode 100644 -index 0000000..3b737dc ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/TldrawEditor.mjs -@@ -0,0 +1,349 @@ -+import { jsx, jsxs } from "react/jsx-runtime"; -+import { Store } from "@tldraw/store"; -+import { annotateError } from "@tldraw/utils"; -+import React, { -+ memo, -+ useCallback, -+ useEffect, -+ useLayoutEffect, -+ useMemo, -+ useRef, -+ useState, -+ useSyncExternalStore -+} from "react"; -+import classNames from "classnames"; -+import { version } from "../version.mjs"; -+import { OptionalErrorBoundary } from "./components/ErrorBoundary.mjs"; -+import { DefaultErrorFallback } from "./components/default-components/DefaultErrorFallback.mjs"; -+import { createTLUser } from "./config/createTLUser.mjs"; -+import { Editor } from "./editor/Editor.mjs"; -+import { ContainerProvider, useContainer } from "./hooks/useContainer.mjs"; -+import { useCursor } from "./hooks/useCursor.mjs"; -+import { useDarkMode } from "./hooks/useDarkMode.mjs"; -+import { EditorContext, useEditor } from "./hooks/useEditor.mjs"; -+import { -+ EditorComponentsProvider, -+ useEditorComponents -+} from "./hooks/useEditorComponents.mjs"; -+import { useEvent } from "./hooks/useEvent.mjs"; -+import { useForceUpdate } from "./hooks/useForceUpdate.mjs"; -+import { useShallowObjectIdentity } from "./hooks/useIdentity.mjs"; -+import { useLocalStore } from "./hooks/useLocalStore.mjs"; -+import { useRefState } from "./hooks/useRefState.mjs"; -+import { useZoomCss } from "./hooks/useZoomCss.mjs"; -+import { LicenseProvider } from "./license/LicenseProvider.mjs"; -+import { Watermark } from "./license/Watermark.mjs"; -+import { stopEventPropagation } from "./utils/dom.mjs"; -+const EMPTY_SHAPE_UTILS_ARRAY = []; -+const EMPTY_BINDING_UTILS_ARRAY = []; -+const EMPTY_TOOLS_ARRAY = []; -+const TL_CONTAINER_CLASS = "tl-container"; -+const TldrawEditor = memo(function TldrawEditor2({ -+ store, -+ components, -+ className, -+ user: _user, -+ ...rest -+}) { -+ const [container, setContainer] = useState(null); -+ const user = useMemo(() => _user ?? createTLUser(), [_user]); -+ const ErrorFallback = components?.ErrorFallback === void 0 ? DefaultErrorFallback : components?.ErrorFallback; -+ const withDefaults = { -+ ...rest, -+ shapeUtils: rest.shapeUtils ?? EMPTY_SHAPE_UTILS_ARRAY, -+ bindingUtils: rest.bindingUtils ?? EMPTY_BINDING_UTILS_ARRAY, -+ tools: rest.tools ?? EMPTY_TOOLS_ARRAY, -+ components -+ }; -+ return ( -+ /* @__PURE__ */ jsx( -+ "div", -+ { -+ ref: setContainer, -+ "data-tldraw": version, -+ draggable: false, -+ className: classNames(`${TL_CONTAINER_CLASS} tl-theme__light`, className), -+ onPointerDown: stopEventPropagation, -+ tabIndex: -1, -+ children: /* @__PURE__ */ jsx( -+ OptionalErrorBoundary, -+ { -+ fallback: ErrorFallback, -+ onError: (error) => annotateError(error, { tags: { origin: "react.tldraw-before-app" } }), -+ children: container && /* @__PURE__ */ jsx(LicenseProvider, { licenseKey: rest.licenseKey, children: /* @__PURE__ */ jsx(ContainerProvider, { container, children: /* @__PURE__ */ jsx(EditorComponentsProvider, { overrides: components, children: store ? store instanceof Store ? ( -+ // Store is ready to go, whether externally synced or not -+ /* @__PURE__ */ (jsx(TldrawEditorWithReadyStore, { ...withDefaults, store, user })) -+ ) : ( -+ // Store is a synced store, so handle syncing stages internally -+ /* @__PURE__ */ (jsx(TldrawEditorWithLoadingStore, { ...withDefaults, store, user })) -+ ) : ( -+ // We have no store (it's undefined) so create one and possibly sync it -+ /* @__PURE__ */ (jsx(TldrawEditorWithOwnStore, { ...withDefaults, store, user })) -+ ) }) }) }) -+ } -+ ) -+ } -+ ) -+ ); -+}); -+function TldrawEditorWithOwnStore(props) { -+ const { -+ defaultName, -+ snapshot, -+ initialData, -+ shapeUtils, -+ bindingUtils, -+ persistenceKey, -+ sessionId, -+ user, -+ assets -+ } = props; -+ const syncedStore = useLocalStore({ -+ shapeUtils, -+ bindingUtils, -+ initialData, -+ persistenceKey, -+ sessionId, -+ defaultName, -+ snapshot, -+ assets -+ }); -+ return /* @__PURE__ */ jsx(TldrawEditorWithLoadingStore, { ...props, store: syncedStore, user }); -+} -+const TldrawEditorWithLoadingStore = memo(function TldrawEditorBeforeLoading({ -+ store, -+ user, -+ ...rest -+}) { -+ const container = useContainer(); -+ useLayoutEffect(() => { -+ if (user.userPreferences.get().colorScheme === "dark") { -+ container.classList.remove("tl-theme__light"); -+ container.classList.add("tl-theme__dark"); -+ } -+ }, [container, user]); -+ const { LoadingScreen: LoadingScreen2 } = useEditorComponents(); -+ switch (store.status) { -+ case "error": { -+ throw store.error; -+ } -+ case "loading": { -+ return LoadingScreen2 ? /* @__PURE__ */ jsx(LoadingScreen2, {}) : null; -+ } -+ case "not-synced": { -+ break; -+ } -+ case "synced-local": { -+ break; -+ } -+ case "synced-remote": { -+ break; -+ } -+ } -+ return /* @__PURE__ */ jsx(TldrawEditorWithReadyStore, { ...rest, store: store.store, user }); -+}); -+const noAutoFocus = () => document.location.search.includes("tldraw_preserve_focus"); -+function TldrawEditorWithReadyStore({ -+ onMount, -+ children, -+ store, -+ tools, -+ shapeUtils, -+ bindingUtils, -+ user, -+ initialState, -+ autoFocus = true, -+ inferDarkMode, -+ cameraOptions, -+ options, -+ licenseKey, -+ deepLinks: _deepLinks, -+ isShapeHidden -+}) { -+ const { ErrorFallback } = useEditorComponents(); -+ const container = useContainer(); -+ const [editor, setEditor] = useRefState(null); -+ const canvasRef = useRef(null); -+ const deepLinks = useShallowObjectIdentity(_deepLinks === true ? {} : _deepLinks); -+ const editorOptionsRef = useRef({ -+ // for these, it's because they're only used when the editor first mounts: -+ autoFocus: autoFocus && !noAutoFocus(), -+ inferDarkMode, -+ initialState, -+ // for these, it's because we keep them up to date in a separate effect: -+ cameraOptions, -+ deepLinks -+ }); -+ useLayoutEffect(() => { -+ editorOptionsRef.current = { -+ autoFocus: autoFocus && !noAutoFocus(), -+ inferDarkMode, -+ initialState, -+ cameraOptions, -+ deepLinks -+ }; -+ }, [autoFocus, inferDarkMode, initialState, cameraOptions, deepLinks]); -+ useLayoutEffect( -+ () => { -+ const { autoFocus: autoFocus2, inferDarkMode: inferDarkMode2, initialState: initialState2, cameraOptions: cameraOptions2, deepLinks: deepLinks2 } = editorOptionsRef.current; -+ const editor2 = new Editor({ -+ store, -+ shapeUtils, -+ bindingUtils, -+ tools, -+ getContainer: () => container, -+ user, -+ initialState: initialState2, -+ // we should check for some kind of query parameter that turns off autofocus -+ autoFocus: autoFocus2, -+ inferDarkMode: inferDarkMode2, -+ cameraOptions: cameraOptions2, -+ options, -+ licenseKey, -+ isShapeHidden -+ }); -+ editor2.updateViewportScreenBounds(canvasRef.current ?? container); -+ if (deepLinks2) { -+ if (!deepLinks2?.getUrl) { -+ editor2.navigateToDeepLink(deepLinks2); -+ } else { -+ editor2.navigateToDeepLink({ ...deepLinks2, url: deepLinks2.getUrl(editor2) }); -+ } -+ } -+ setEditor(editor2); -+ return () => { -+ editor2.dispose(); -+ }; -+ }, -+ // if any of these change, we need to recreate the editor. -+ [ -+ bindingUtils, -+ container, -+ options, -+ shapeUtils, -+ store, -+ tools, -+ user, -+ setEditor, -+ licenseKey, -+ isShapeHidden -+ ] -+ ); -+ useLayoutEffect(() => { -+ if (!editor) return; -+ if (deepLinks) { -+ return editor.registerDeepLinkListener(deepLinks); -+ } -+ }, [editor, deepLinks]); -+ useLayoutEffect(() => { -+ if (editor && cameraOptions) { -+ editor.setCameraOptions(cameraOptions); -+ } -+ }, [editor, cameraOptions]); -+ const crashingError = useSyncExternalStore( -+ useCallback( -+ (onStoreChange) => { -+ if (editor) { -+ editor.on("crash", onStoreChange); -+ return () => editor.off("crash", onStoreChange); -+ } -+ return () => { -+ }; -+ }, -+ [editor] -+ ), -+ () => editor?.getCrashingError() ?? null -+ ); -+ useEffect( -+ function handleFocusOnPointerDownForPreserveFocusMode() { -+ if (!editor) return; -+ function handleFocusOnPointerDown() { -+ if (!editor) return; -+ editor.focus(); -+ } -+ function handleBlurOnPointerDown() { -+ if (!editor) return; -+ editor.blur(); -+ } -+ if (autoFocus && noAutoFocus()) { -+ editor.getContainer().addEventListener("pointerdown", handleFocusOnPointerDown); -+ document.body.addEventListener("pointerdown", handleBlurOnPointerDown); -+ return () => { -+ editor.getContainer()?.removeEventListener("pointerdown", handleFocusOnPointerDown); -+ document.body.removeEventListener("pointerdown", handleBlurOnPointerDown); -+ }; -+ } -+ }, -+ [editor, autoFocus] -+ ); -+ const { Canvas } = useEditorComponents(); -+ if (!editor) { -+ return /* @__PURE__ */ jsx("div", { className: "tl-canvas", ref: canvasRef }); -+ } -+ return ( -+ // the top-level tldraw component also renders an error boundary almost -+ // identical to this one. the reason we have two is because this one has -+ // access to `App`, which means that here we can enrich errors with data -+ // from app for reporting, and also still attempt to render the user's -+ // document in the event of an error to reassure them that their work is -+ // not lost. -+ /* @__PURE__ */ (jsx(OptionalErrorBoundary, { -+ fallback: ErrorFallback, -+ onError: (error) => editor.annotateError(error, { origin: "react.tldraw", willCrashApp: true }), -+ children: crashingError ? /* @__PURE__ */ jsx(Crash, { crashingError }) : /* @__PURE__ */ jsx(EditorContext.Provider, { value: editor, children: /* @__PURE__ */ jsxs(Layout, { onMount, children: [ -+ children ?? (Canvas ? /* @__PURE__ */ jsx(Canvas, {}) : null), -+ /* @__PURE__ */ jsx(Watermark, {}) -+ ] }) }) -+ })) -+ ); -+} -+function Layout({ children, onMount }) { -+ useZoomCss(); -+ useCursor(); -+ useDarkMode(); -+ useForceUpdate(); -+ useOnMount((editor) => { -+ const teardownStore = editor.store.props.onMount(editor); -+ const teardownCallback = onMount?.(editor); -+ return () => { -+ teardownStore?.(); -+ teardownCallback?.(); -+ }; -+ }); -+ return children; -+} -+function Crash({ crashingError }) { -+ throw crashingError; -+} -+function LoadingScreen({ children }) { -+ return /* @__PURE__ */ jsx("div", { className: "tl-loading", children }); -+} -+function ErrorScreen({ children }) { -+ return /* @__PURE__ */ jsx("div", { className: "tl-loading", children }); -+} -+function useOnMount(onMount) { -+ const editor = useEditor(); -+ const onMountEvent = useEvent((editor2) => { -+ let teardown = void 0; -+ editor2.run( -+ () => { -+ teardown = onMount?.(editor2); -+ editor2.emit("mount"); -+ }, -+ { history: "ignore" } -+ ); -+ window.tldrawReady = true; -+ return teardown; -+ }); -+ React.useLayoutEffect(() => { -+ if (editor) return onMountEvent?.(editor); -+ }, [editor, onMountEvent]); -+} -+export { -+ ErrorScreen, -+ LoadingScreen, -+ TL_CONTAINER_CLASS, -+ TldrawEditor, -+ useOnMount -+}; -+//# sourceMappingURL=TldrawEditor.mjs.map -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/TldrawEditor.mjs.map b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/TldrawEditor.mjs.map -new file mode 100644 -index 0000000..1f2e15a ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/TldrawEditor.mjs.map -@@ -0,0 +1,7 @@ -+{ -+ "version": 3, -+ "sources": ["../../src/lib/TldrawEditor.tsx"], -+ "sourcesContent": ["import { MigrationSequence, Store } from '@tldraw/store'\nimport { TLShape, TLStore, TLStoreSnapshot } from '@tldraw/tlschema'\nimport { Required, annotateError } from '@tldraw/utils'\nimport React, {\n\tReactNode,\n\tmemo,\n\tuseCallback,\n\tuseEffect,\n\tuseLayoutEffect,\n\tuseMemo,\n\tuseRef,\n\tuseState,\n\tuseSyncExternalStore,\n} from 'react'\n\nimport classNames from 'classnames'\nimport { TLDeepLinkOptions } from '..'\nimport { version } from '../version'\nimport { OptionalErrorBoundary } from './components/ErrorBoundary'\nimport { DefaultErrorFallback } from './components/default-components/DefaultErrorFallback'\nimport { TLEditorSnapshot } from './config/TLEditorSnapshot'\nimport { TLStoreBaseOptions } from './config/createTLStore'\nimport { TLUser, createTLUser } from './config/createTLUser'\nimport { TLAnyBindingUtilConstructor } from './config/defaultBindings'\nimport { TLAnyShapeUtilConstructor } from './config/defaultShapes'\nimport { Editor } from './editor/Editor'\nimport { TLStateNodeConstructor } from './editor/tools/StateNode'\nimport { TLCameraOptions } from './editor/types/misc-types'\nimport { ContainerProvider, useContainer } from './hooks/useContainer'\nimport { useCursor } from './hooks/useCursor'\nimport { useDarkMode } from './hooks/useDarkMode'\nimport { EditorContext, useEditor } from './hooks/useEditor'\nimport {\n\tEditorComponentsProvider,\n\tTLEditorComponents,\n\tuseEditorComponents,\n} from './hooks/useEditorComponents'\nimport { useEvent } from './hooks/useEvent'\nimport { useForceUpdate } from './hooks/useForceUpdate'\nimport { useShallowObjectIdentity } from './hooks/useIdentity'\nimport { useLocalStore } from './hooks/useLocalStore'\nimport { useRefState } from './hooks/useRefState'\nimport { useZoomCss } from './hooks/useZoomCss'\nimport { LicenseProvider } from './license/LicenseProvider'\nimport { Watermark } from './license/Watermark'\nimport { TldrawOptions } from './options'\nimport { stopEventPropagation } from './utils/dom'\nimport { TLStoreWithStatus } from './utils/sync/StoreWithStatus'\n\n/**\n * Props for the {@link tldraw#Tldraw} and {@link TldrawEditor} components, when passing in a\n * {@link store#TLStore} directly. If you would like tldraw to create a store for you, use\n * {@link TldrawEditorWithoutStoreProps}.\n *\n * @public\n */\nexport interface TldrawEditorWithStoreProps {\n\t/**\n\t * The store to use in the editor.\n\t */\n\tstore: TLStore | TLStoreWithStatus\n}\n\n/**\n * Props for the {@link tldraw#Tldraw} and {@link TldrawEditor} components, when not passing in a\n * {@link store#TLStore} directly. If you would like to pass in a store directly, use\n * {@link TldrawEditorWithStoreProps}.\n *\n * @public\n */\nexport interface TldrawEditorWithoutStoreProps extends TLStoreBaseOptions {\n\tstore?: undefined\n\n\t/**\n\t * Additional migrations to use in the store\n\t */\n\tmigrations?: readonly MigrationSequence[]\n\n\t/**\n\t * A starting snapshot of data to pre-populate the store. Do not supply both this and\n\t * `initialData`.\n\t */\n\tsnapshot?: TLEditorSnapshot | TLStoreSnapshot\n\n\t/**\n\t * If you would like to persist the store to the browser's local IndexedDB storage and sync it\n\t * across tabs, provide a key here. Each key represents a single tldraw document.\n\t */\n\tpersistenceKey?: string\n\n\tsessionId?: string\n}\n\n/** @public */\nexport type TldrawEditorStoreProps = TldrawEditorWithStoreProps | TldrawEditorWithoutStoreProps\n\n/**\n * Props for the {@link tldraw#Tldraw} and {@link TldrawEditor} components.\n *\n * @public\n **/\nexport type TldrawEditorProps = TldrawEditorBaseProps & TldrawEditorStoreProps\n\n/**\n * Base props for the {@link tldraw#Tldraw} and {@link TldrawEditor} components.\n *\n * @public\n */\nexport interface TldrawEditorBaseProps {\n\t/**\n\t * The component's children.\n\t */\n\tchildren?: ReactNode\n\n\t/**\n\t * An array of shape utils to use in the editor.\n\t */\n\tshapeUtils?: readonly TLAnyShapeUtilConstructor[]\n\n\t/**\n\t * An array of binding utils to use in the editor.\n\t */\n\tbindingUtils?: readonly TLAnyBindingUtilConstructor[]\n\n\t/**\n\t * An array of tools to add to the editor's state chart.\n\t */\n\ttools?: readonly TLStateNodeConstructor[]\n\n\t/**\n\t * Whether to automatically focus the editor when it mounts.\n\t */\n\tautoFocus?: boolean\n\n\t/**\n\t * Overrides for the editor's components, such as handles, collaborator cursors, etc.\n\t */\n\tcomponents?: TLEditorComponents\n\n\t/**\n\t * Called when the editor has mounted.\n\t */\n\tonMount?: TLOnMountHandler\n\n\t/**\n\t * The editor's initial state (usually the id of the first active tool).\n\t */\n\tinitialState?: string\n\n\t/**\n\t * A classname to pass to the editor's container.\n\t */\n\tclassName?: string\n\n\t/**\n\t * The user interacting with the editor.\n\t */\n\tuser?: TLUser\n\n\t/**\n\t * Whether to infer dark mode from the user's OS. Defaults to false.\n\t */\n\tinferDarkMode?: boolean\n\n\t/**\n\t * Camera options for the editor.\n\t */\n\tcameraOptions?: Partial\n\n\t/**\n\t * Options for the editor.\n\t */\n\toptions?: Partial\n\n\t/**\n\t * The license key.\n\t */\n\tlicenseKey?: string\n\n\t/**\n\t * Options for syncing the editor's camera state with the URL.\n\t */\n\tdeepLinks?: true | TLDeepLinkOptions\n\n\t/**\n\t * Predicate for whether or not a shape should be hidden.\n\t *\n\t * Hidden shapes will not render in the editor, and they will not be eligible for hit test via\n\t * {@link Editor#getShapeAtPoint} and {@link Editor#getShapesAtPoint}. But otherwise they will\n\t * remain in the store and participate in all other operations.\n\t */\n\tisShapeHidden?(shape: TLShape, editor: Editor): boolean\n}\n\n/**\n * Called when the editor has mounted.\n * @example\n * ```ts\n * editor.selectAll()} />\n * ```\n * @param editor - The editor instance.\n *\n * @public\n */\nexport type TLOnMountHandler = (editor: Editor) => (() => void | undefined) | undefined | void\n\ndeclare global {\n\tinterface Window {\n\t\ttldrawReady: boolean\n\t}\n}\n\nconst EMPTY_SHAPE_UTILS_ARRAY = [] as const\nconst EMPTY_BINDING_UTILS_ARRAY = [] as const\nconst EMPTY_TOOLS_ARRAY = [] as const\n/** @internal */\nexport const TL_CONTAINER_CLASS = 'tl-container'\n\n/** @public @react */\nexport const TldrawEditor = memo(function TldrawEditor({\n\tstore,\n\tcomponents,\n\tclassName,\n\tuser: _user,\n\t...rest\n}: TldrawEditorProps) {\n\tconst [container, setContainer] = useState(null)\n\tconst user = useMemo(() => _user ?? createTLUser(), [_user])\n\n\tconst ErrorFallback =\n\t\tcomponents?.ErrorFallback === undefined ? DefaultErrorFallback : components?.ErrorFallback\n\n\t// apply defaults. if you're using the bare @tldraw/editor package, we\n\t// default these to the \"tldraw zero\" configuration. We have different\n\t// defaults applied in tldraw.\n\tconst withDefaults = {\n\t\t...rest,\n\t\tshapeUtils: rest.shapeUtils ?? EMPTY_SHAPE_UTILS_ARRAY,\n\t\tbindingUtils: rest.bindingUtils ?? EMPTY_BINDING_UTILS_ARRAY,\n\t\ttools: rest.tools ?? EMPTY_TOOLS_ARRAY,\n\t\tcomponents,\n\t}\n\n\treturn (\n\t\t\n\t\t\t annotateError(error, { tags: { origin: 'react.tldraw-before-app' } })}\n\t\t\t>\n\t\t\t\t{container && (\n\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t{store ? (\n\t\t\t\t\t\t\t\t\tstore instanceof Store ? (\n\t\t\t\t\t\t\t\t\t\t// Store is ready to go, whether externally synced or not\n\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t\t\t// Store is a synced store, so handle syncing stages internally\n\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t\t// We have no store (it's undefined) so create one and possibly sync it\n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t)}\n\t\t\t\n\t\t\n\t)\n})\n\nfunction TldrawEditorWithOwnStore(\n\tprops: Required<\n\t\tTldrawEditorProps & { store: undefined; user: TLUser },\n\t\t'shapeUtils' | 'bindingUtils' | 'tools'\n\t>\n) {\n\tconst {\n\t\tdefaultName,\n\t\tsnapshot,\n\t\tinitialData,\n\t\tshapeUtils,\n\t\tbindingUtils,\n\t\tpersistenceKey,\n\t\tsessionId,\n\t\tuser,\n\t\tassets,\n\t} = props\n\n\tconst syncedStore = useLocalStore({\n\t\tshapeUtils,\n\t\tbindingUtils,\n\t\tinitialData,\n\t\tpersistenceKey,\n\t\tsessionId,\n\t\tdefaultName,\n\t\tsnapshot,\n\t\tassets,\n\t})\n\n\treturn \n}\n\nconst TldrawEditorWithLoadingStore = memo(function TldrawEditorBeforeLoading({\n\tstore,\n\tuser,\n\t...rest\n}: Required<\n\tTldrawEditorProps & { store: TLStoreWithStatus; user: TLUser },\n\t'shapeUtils' | 'bindingUtils' | 'tools'\n>) {\n\tconst container = useContainer()\n\n\tuseLayoutEffect(() => {\n\t\tif (user.userPreferences.get().colorScheme === 'dark') {\n\t\t\tcontainer.classList.remove('tl-theme__light')\n\t\t\tcontainer.classList.add('tl-theme__dark')\n\t\t}\n\t}, [container, user])\n\n\tconst { LoadingScreen } = useEditorComponents()\n\n\tswitch (store.status) {\n\t\tcase 'error': {\n\t\t\t// for error handling, we fall back to the default error boundary.\n\t\t\t// if users want to handle this error differently, they can render\n\t\t\t// their own error screen before the TldrawEditor component\n\t\t\tthrow store.error\n\t\t}\n\t\tcase 'loading': {\n\t\t\treturn LoadingScreen ? : null\n\t\t}\n\t\tcase 'not-synced': {\n\t\t\tbreak\n\t\t}\n\t\tcase 'synced-local': {\n\t\t\tbreak\n\t\t}\n\t\tcase 'synced-remote': {\n\t\t\tbreak\n\t\t}\n\t}\n\n\treturn \n})\n\nconst noAutoFocus = () => document.location.search.includes('tldraw_preserve_focus') // || !document.hasFocus() // breaks in nextjs\n\nfunction TldrawEditorWithReadyStore({\n\tonMount,\n\tchildren,\n\tstore,\n\ttools,\n\tshapeUtils,\n\tbindingUtils,\n\tuser,\n\tinitialState,\n\tautoFocus = true,\n\tinferDarkMode,\n\tcameraOptions,\n\toptions,\n\tlicenseKey,\n\tdeepLinks: _deepLinks,\n\tisShapeHidden,\n}: Required<\n\tTldrawEditorProps & {\n\t\tstore: TLStore\n\t\tuser: TLUser\n\t},\n\t'shapeUtils' | 'bindingUtils' | 'tools'\n>) {\n\tconst { ErrorFallback } = useEditorComponents()\n\tconst container = useContainer()\n\n\tconst [editor, setEditor] = useRefState(null)\n\n\tconst canvasRef = useRef(null)\n\n\tconst deepLinks = useShallowObjectIdentity(_deepLinks === true ? {} : _deepLinks)\n\n\t// props in this ref can be changed without causing the editor to be recreated.\n\tconst editorOptionsRef = useRef({\n\t\t// for these, it's because they're only used when the editor first mounts:\n\t\tautoFocus: autoFocus && !noAutoFocus(),\n\t\tinferDarkMode,\n\t\tinitialState,\n\n\t\t// for these, it's because we keep them up to date in a separate effect:\n\t\tcameraOptions,\n\t\tdeepLinks,\n\t})\n\n\tuseLayoutEffect(() => {\n\t\teditorOptionsRef.current = {\n\t\t\tautoFocus: autoFocus && !noAutoFocus(),\n\t\t\tinferDarkMode,\n\t\t\tinitialState,\n\t\t\tcameraOptions,\n\t\t\tdeepLinks,\n\t\t}\n\t}, [autoFocus, inferDarkMode, initialState, cameraOptions, deepLinks])\n\n\tuseLayoutEffect(\n\t\t() => {\n\t\t\tconst { autoFocus, inferDarkMode, initialState, cameraOptions, deepLinks } =\n\t\t\t\teditorOptionsRef.current\n\t\t\tconst editor = new Editor({\n\t\t\t\tstore,\n\t\t\t\tshapeUtils,\n\t\t\t\tbindingUtils,\n\t\t\t\ttools,\n\t\t\t\tgetContainer: () => container,\n\t\t\t\tuser,\n\t\t\t\tinitialState,\n\t\t\t\t// we should check for some kind of query parameter that turns off autofocus\n\t\t\t\tautoFocus,\n\t\t\t\tinferDarkMode,\n\t\t\t\tcameraOptions,\n\t\t\t\toptions,\n\t\t\t\tlicenseKey,\n\t\t\t\tisShapeHidden,\n\t\t\t})\n\n\t\t\teditor.updateViewportScreenBounds(canvasRef.current ?? container)\n\n\t\t\t// Use the ref here because we only want to do this once when the editor is created.\n\t\t\t// We don't want changes to the urlStateSync prop to trigger creating new editors.\n\t\t\tif (deepLinks) {\n\t\t\t\tif (!deepLinks?.getUrl) {\n\t\t\t\t\t// load the state from window.location\n\t\t\t\t\teditor.navigateToDeepLink(deepLinks)\n\t\t\t\t} else {\n\t\t\t\t\t// load the state from the provided URL\n\t\t\t\t\teditor.navigateToDeepLink({ ...deepLinks, url: deepLinks.getUrl(editor) })\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tsetEditor(editor)\n\n\t\t\treturn () => {\n\t\t\t\teditor.dispose()\n\t\t\t}\n\t\t},\n\t\t// if any of these change, we need to recreate the editor.\n\t\t[\n\t\t\tbindingUtils,\n\t\t\tcontainer,\n\t\t\toptions,\n\t\t\tshapeUtils,\n\t\t\tstore,\n\t\t\ttools,\n\t\t\tuser,\n\t\t\tsetEditor,\n\t\t\tlicenseKey,\n\t\t\tisShapeHidden,\n\t\t]\n\t)\n\n\tuseLayoutEffect(() => {\n\t\tif (!editor) return\n\t\tif (deepLinks) {\n\t\t\treturn editor.registerDeepLinkListener(deepLinks)\n\t\t}\n\t}, [editor, deepLinks])\n\n\t// keep the editor up to date with the latest camera options\n\tuseLayoutEffect(() => {\n\t\tif (editor && cameraOptions) {\n\t\t\teditor.setCameraOptions(cameraOptions)\n\t\t}\n\t}, [editor, cameraOptions])\n\n\tconst crashingError = useSyncExternalStore(\n\t\tuseCallback(\n\t\t\t(onStoreChange) => {\n\t\t\t\tif (editor) {\n\t\t\t\t\teditor.on('crash', onStoreChange)\n\t\t\t\t\treturn () => editor.off('crash', onStoreChange)\n\t\t\t\t}\n\t\t\t\treturn () => {\n\t\t\t\t\t// noop\n\t\t\t\t}\n\t\t\t},\n\t\t\t[editor]\n\t\t),\n\t\t() => editor?.getCrashingError() ?? null\n\t)\n\n\t// For our examples site, we want autoFocus to be true on the examples site, but not\n\t// when embedded in our docs site. If present, the `tldraw_preserve_focus` search param\n\t// overrides the `autoFocus` prop and prevents the editor from focusing immediately,\n\t// however here we also add some logic to focus the editor when the user clicks\n\t// on it and unfocus it when the user clicks away from it.\n\tuseEffect(\n\t\tfunction handleFocusOnPointerDownForPreserveFocusMode() {\n\t\t\tif (!editor) return\n\n\t\t\tfunction handleFocusOnPointerDown() {\n\t\t\t\tif (!editor) return\n\t\t\t\teditor.focus()\n\t\t\t}\n\n\t\t\tfunction handleBlurOnPointerDown() {\n\t\t\t\tif (!editor) return\n\t\t\t\teditor.blur()\n\t\t\t}\n\n\t\t\tif (autoFocus && noAutoFocus()) {\n\t\t\t\teditor.getContainer().addEventListener('pointerdown', handleFocusOnPointerDown)\n\t\t\t\tdocument.body.addEventListener('pointerdown', handleBlurOnPointerDown)\n\n\t\t\t\treturn () => {\n\t\t\t\t\teditor.getContainer()?.removeEventListener('pointerdown', handleFocusOnPointerDown)\n\t\t\t\t\tdocument.body.removeEventListener('pointerdown', handleBlurOnPointerDown)\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t[editor, autoFocus]\n\t)\n\n\tconst { Canvas } = useEditorComponents()\n\n\tif (!editor) {\n\t\treturn
\n\t}\n\n\treturn (\n\t\t// the top-level tldraw component also renders an error boundary almost\n\t\t// identical to this one. the reason we have two is because this one has\n\t\t// access to `App`, which means that here we can enrich errors with data\n\t\t// from app for reporting, and also still attempt to render the user's\n\t\t// document in the event of an error to reassure them that their work is\n\t\t// not lost.\n\t\t\n\t\t\t\teditor.annotateError(error, { origin: 'react.tldraw', willCrashApp: true })\n\t\t\t}\n\t\t>\n\t\t\t{crashingError ? (\n\t\t\t\t\n\t\t\t) : (\n\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\t{children ?? (Canvas ? : null)}\n\t\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\n\t\t\t)}\n\t\t\n\t)\n}\n\nfunction Layout({ children, onMount }: { children: ReactNode; onMount?: TLOnMountHandler }) {\n\tuseZoomCss()\n\tuseCursor()\n\tuseDarkMode()\n\tuseForceUpdate()\n\tuseOnMount((editor) => {\n\t\tconst teardownStore = editor.store.props.onMount(editor)\n\t\tconst teardownCallback = onMount?.(editor)\n\n\t\treturn () => {\n\t\t\tteardownStore?.()\n\t\t\tteardownCallback?.()\n\t\t}\n\t})\n\n\treturn children\n}\n\nfunction Crash({ crashingError }: { crashingError: unknown }): null {\n\tthrow crashingError\n}\n\n/** @public */\nexport interface LoadingScreenProps {\n\tchildren: ReactNode\n}\n\n/** @public @react */\nexport function LoadingScreen({ children }: LoadingScreenProps) {\n\treturn
{children}
\n}\n\n/** @public @react */\nexport function ErrorScreen({ children }: LoadingScreenProps) {\n\treturn
{children}
\n}\n\n/** @internal */\nexport function useOnMount(onMount?: TLOnMountHandler) {\n\tconst editor = useEditor()\n\n\tconst onMountEvent = useEvent((editor: Editor) => {\n\t\tlet teardown: (() => void) | void = undefined\n\t\t// If the user wants to do something when the editor mounts, we make sure it doesn't effect the history.\n\t\t// todo: is this reeeeally what we want to do, or should we leave it up to the caller?\n\t\teditor.run(\n\t\t\t() => {\n\t\t\t\tteardown = onMount?.(editor)\n\t\t\t\teditor.emit('mount')\n\t\t\t},\n\t\t\t{ history: 'ignore' }\n\t\t)\n\t\twindow.tldrawReady = true\n\t\treturn teardown\n\t})\n\n\tReact.useLayoutEffect(() => {\n\t\tif (editor) return onMountEvent?.(editor)\n\t}, [editor, onMountEvent])\n}\n"], -+ "mappings": "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", -+ "names": ["TldrawEditor", "LoadingScreen", "autoFocus", "inferDarkMode", "initialState", "cameraOptions", "deepLinks", "editor"] -+} -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/components/ErrorBoundary.mjs b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/components/ErrorBoundary.mjs -new file mode 100644 -index 0000000..3603b47 ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/components/ErrorBoundary.mjs -@@ -0,0 +1,35 @@ -+import { jsx } from "react/jsx-runtime"; -+import * as React from "react"; -+const initialState = { error: null }; -+class ErrorBoundary extends React.Component { -+ static getDerivedStateFromError(error) { -+ return { error }; -+ } -+ state = initialState; -+ componentDidCatch(error) { -+ this.props.onError?.(error); -+ } -+ render() { -+ const { error } = this.state; -+ if (error !== null) { -+ const { fallback: Fallback } = this.props; -+ return /* @__PURE__ */ jsx(Fallback, { error }); -+ } -+ return this.props.children; -+ } -+} -+function OptionalErrorBoundary({ -+ children, -+ fallback, -+ ...props -+}) { -+ if (fallback === null) { -+ return children; -+ } -+ return /* @__PURE__ */ jsx(ErrorBoundary, { fallback, ...props, children }); -+} -+export { -+ ErrorBoundary, -+ OptionalErrorBoundary -+}; -+//# sourceMappingURL=ErrorBoundary.mjs.map -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/components/ErrorBoundary.mjs.map b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/components/ErrorBoundary.mjs.map -new file mode 100644 -index 0000000..b382a71 ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/components/ErrorBoundary.mjs.map -@@ -0,0 +1,7 @@ -+{ -+ "version": 3, -+ "sources": ["../../../src/lib/components/ErrorBoundary.tsx"], -+ "sourcesContent": ["import * as React from 'react'\nimport { TLErrorFallbackComponent } from './default-components/DefaultErrorFallback'\n\n/** @public */\nexport interface TLErrorBoundaryProps {\n\tchildren: React.ReactNode\n\tonError?: ((error: unknown) => void) | null\n\tfallback: TLErrorFallbackComponent\n}\n\nconst initialState = { error: null }\n\n/** @public */\nexport class ErrorBoundary extends React.Component<\n\tReact.PropsWithRef>,\n\t{ error: Error | null }\n> {\n\tstatic getDerivedStateFromError(error: Error) {\n\t\treturn { error }\n\t}\n\n\toverride state = initialState\n\n\toverride componentDidCatch(error: unknown) {\n\t\tthis.props.onError?.(error)\n\t}\n\n\toverride render() {\n\t\tconst { error } = this.state\n\n\t\tif (error !== null) {\n\t\t\tconst { fallback: Fallback } = this.props\n\t\t\treturn \n\t\t}\n\n\t\treturn this.props.children\n\t}\n}\n\n/** @internal */\nexport function OptionalErrorBoundary({\n\tchildren,\n\tfallback,\n\t...props\n}: Omit & {\n\tfallback: TLErrorFallbackComponent\n}) {\n\tif (fallback === null) {\n\t\treturn children\n\t}\n\n\treturn (\n\t\t\n\t\t\t{children}\n\t\t\n\t)\n}\n"], -+ "mappings": "AAgCU;AAhCV,YAAY,WAAW;AAUvB,MAAM,eAAe,EAAE,OAAO,KAAK;AAG5B,MAAM,sBAAsB,MAAM,UAGvC;AAAA,EACD,OAAO,yBAAyB,OAAc;AAC7C,WAAO,EAAE,MAAM;AAAA,EAChB;AAAA,EAES,QAAQ;AAAA,EAER,kBAAkB,OAAgB;AAC1C,SAAK,MAAM,UAAU,KAAK;AAAA,EAC3B;AAAA,EAES,SAAS;AACjB,UAAM,EAAE,MAAM,IAAI,KAAK;AAEvB,QAAI,UAAU,MAAM;AACnB,YAAM,EAAE,UAAU,SAAS,IAAI,KAAK;AACpC,aAAO,oBAAC,YAAS,OAAc;AAAA,IAChC;AAEA,WAAO,KAAK,MAAM;AAAA,EACnB;AACD;AAGO,SAAS,sBAAsB;AAAA,EACrC;AAAA,EACA;AAAA,EACA,GAAG;AACJ,GAEG;AACF,MAAI,aAAa,MAAM;AACtB,WAAO;AAAA,EACR;AAEA,SACC,oBAAC,iBAAc,UAA4B,GAAG,OAC5C,UACF;AAEF;", -+ "names": [] -+} -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/components/GeometryDebuggingView.mjs b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/components/GeometryDebuggingView.mjs -new file mode 100644 -index 0000000..dd4d7a1 ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/components/GeometryDebuggingView.mjs -@@ -0,0 +1,111 @@ -+import { Fragment, jsx, jsxs } from "react/jsx-runtime"; -+import { track } from "@tldraw/state-react"; -+import { modulate } from "@tldraw/utils"; -+import { useEffect, useState } from "react"; -+import { useEditor } from "../hooks/useEditor.mjs"; -+import { Group2d } from "../primitives/geometry/Group2d.mjs"; -+function useTick(isEnabled = true) { -+ const [_, setTick] = useState(0); -+ const editor = useEditor(); -+ useEffect(() => { -+ if (!isEnabled) return; -+ const update = () => setTick((tick) => tick + 1); -+ editor.on("tick", update); -+ return () => { -+ editor.off("tick", update); -+ }; -+ }, [editor, isEnabled]); -+} -+const GeometryDebuggingView = track(function GeometryDebuggingView2({ -+ showStroke = true, -+ showVertices = true, -+ showClosestPointOnOutline = true -+}) { -+ const editor = useEditor(); -+ useTick(showClosestPointOnOutline); -+ const zoomLevel = editor.getZoomLevel(); -+ const renderingShapes = editor.getRenderingShapes(); -+ const { -+ inputs: { currentPagePoint } -+ } = editor; -+ return /* @__PURE__ */ jsx( -+ "svg", -+ { -+ style: { -+ position: "absolute", -+ pointerEvents: "none", -+ zIndex: 999999999, -+ top: 0, -+ left: 0, -+ overflow: "visible" -+ }, -+ children: renderingShapes.map((result) => { -+ const shape = editor.getShape(result.id); -+ if (shape.type === "group") return null; -+ const geometry = editor.getShapeGeometry(shape); -+ const pageTransform = editor.getShapePageTransform(shape); -+ const pointInShapeSpace = editor.getPointInShapeSpace(shape, currentPagePoint); -+ const nearestPointOnShape = geometry.nearestPoint(pointInShapeSpace); -+ const distanceToPoint = geometry.distanceToPoint(pointInShapeSpace, true); -+ const dist = Math.abs(distanceToPoint) * zoomLevel; -+ const hitInside = distanceToPoint < 0; -+ const { vertices } = geometry; -+ return /* @__PURE__ */ jsxs( -+ "g", -+ { -+ transform: pageTransform.toCssString(), -+ strokeLinecap: "round", -+ strokeLinejoin: "round", -+ children: [ -+ showStroke && /* @__PURE__ */ jsx( -+ "g", -+ { -+ stroke: geometry.debugColor ?? "red", -+ opacity: "1", -+ strokeWidth: 2 / zoomLevel, -+ fill: "none", -+ children: /* @__PURE__ */ jsx(GeometryStroke, { geometry }) -+ } -+ ), -+ showVertices && vertices.map((v, i) => /* @__PURE__ */ jsx( -+ "circle", -+ { -+ cx: v.x, -+ cy: v.y, -+ r: 2 / zoomLevel, -+ fill: `hsl(${modulate(i, [0, vertices.length - 1], [120, 200])}, 100%, 50%)`, -+ stroke: "black", -+ strokeWidth: 1 / zoomLevel -+ }, -+ `v${i}` -+ )), -+ showClosestPointOnOutline && dist < 150 && /* @__PURE__ */ jsx( -+ "line", -+ { -+ x1: nearestPointOnShape.x, -+ y1: nearestPointOnShape.y, -+ x2: pointInShapeSpace.x, -+ y2: pointInShapeSpace.y, -+ opacity: 1 - dist / 150, -+ stroke: hitInside ? "goldenrod" : "dodgerblue", -+ strokeWidth: 2 / zoomLevel -+ } -+ ) -+ ] -+ }, -+ result.id + "_outline" -+ ); -+ }) -+ } -+ ); -+}); -+function GeometryStroke({ geometry }) { -+ if (geometry instanceof Group2d) { -+ return /* @__PURE__ */ jsx(Fragment, { children: [...geometry.children, ...geometry.ignoredChildren].map((child, i) => /* @__PURE__ */ jsx(GeometryStroke, { geometry: child }, i)) }); -+ } -+ return /* @__PURE__ */ jsx("path", { d: geometry.toSimpleSvgPath() }); -+} -+export { -+ GeometryDebuggingView -+}; -+//# sourceMappingURL=GeometryDebuggingView.mjs.map -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/components/GeometryDebuggingView.mjs.map b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/components/GeometryDebuggingView.mjs.map -new file mode 100644 -index 0000000..fab5729 ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/components/GeometryDebuggingView.mjs.map -@@ -0,0 +1,7 @@ -+{ -+ "version": 3, -+ "sources": ["../../../src/lib/components/GeometryDebuggingView.tsx"], -+ "sourcesContent": ["import { track } from '@tldraw/state-react'\nimport { modulate } from '@tldraw/utils'\nimport { useEffect, useState } from 'react'\nimport { useEditor } from '../hooks/useEditor'\nimport { Geometry2d } from '../primitives/geometry/Geometry2d'\nimport { Group2d } from '../primitives/geometry/Group2d'\n\nfunction useTick(isEnabled = true) {\n\tconst [_, setTick] = useState(0)\n\tconst editor = useEditor()\n\tuseEffect(() => {\n\t\tif (!isEnabled) return\n\t\tconst update = () => setTick((tick) => tick + 1)\n\t\teditor.on('tick', update)\n\t\treturn () => {\n\t\t\teditor.off('tick', update)\n\t\t}\n\t}, [editor, isEnabled])\n}\n\nexport const GeometryDebuggingView = track(function GeometryDebuggingView({\n\tshowStroke = true,\n\tshowVertices = true,\n\tshowClosestPointOnOutline = true,\n}: {\n\tshowStroke?: boolean\n\tshowVertices?: boolean\n\tshowClosestPointOnOutline?: boolean\n}) {\n\tconst editor = useEditor()\n\n\tuseTick(showClosestPointOnOutline)\n\n\tconst zoomLevel = editor.getZoomLevel()\n\tconst renderingShapes = editor.getRenderingShapes()\n\tconst {\n\t\tinputs: { currentPagePoint },\n\t} = editor\n\n\treturn (\n\t\t\n\t\t\t{renderingShapes.map((result) => {\n\t\t\t\tconst shape = editor.getShape(result.id)!\n\n\t\t\t\tif (shape.type === 'group') return null\n\n\t\t\t\tconst geometry = editor.getShapeGeometry(shape)\n\t\t\t\tconst pageTransform = editor.getShapePageTransform(shape)!\n\n\t\t\t\tconst pointInShapeSpace = editor.getPointInShapeSpace(shape, currentPagePoint)\n\t\t\t\tconst nearestPointOnShape = geometry.nearestPoint(pointInShapeSpace)\n\t\t\t\tconst distanceToPoint = geometry.distanceToPoint(pointInShapeSpace, true)\n\t\t\t\tconst dist = Math.abs(distanceToPoint) * zoomLevel\n\t\t\t\tconst hitInside = distanceToPoint < 0\n\n\t\t\t\tconst { vertices } = geometry\n\n\t\t\t\treturn (\n\t\t\t\t\t\n\t\t\t\t\t\t{showStroke && (\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t)}\n\t\t\t\t\t\t{showVertices &&\n\t\t\t\t\t\t\tvertices.map((v, i) => (\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t{showClosestPointOnOutline && dist < 150 && (\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t)}\n\t\t\t\t\t\n\t\t\t\t)\n\t\t\t})}\n\t\t\n\t)\n})\n\nfunction GeometryStroke({ geometry }: { geometry: Geometry2d }) {\n\tif (geometry instanceof Group2d) {\n\t\treturn (\n\t\t\t<>\n\t\t\t\t{[...geometry.children, ...geometry.ignoredChildren].map((child, i) => (\n\t\t\t\t\t\n\t\t\t\t))}\n\t\t\t\n\t\t)\n\t}\n\n\treturn \n}\n"], -+ "mappings": "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", -+ "names": ["GeometryDebuggingView"] -+} -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/components/HTMLContainer.mjs b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/components/HTMLContainer.mjs -new file mode 100644 -index 0000000..2723ca1 ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/components/HTMLContainer.mjs -@@ -0,0 +1,9 @@ -+import { jsx } from "react/jsx-runtime"; -+import classNames from "classnames"; -+function HTMLContainer({ children, className = "", ...rest }) { -+ return /* @__PURE__ */ jsx("div", { ...rest, className: classNames("tl-html-container", className), children }); -+} -+export { -+ HTMLContainer -+}; -+//# sourceMappingURL=HTMLContainer.mjs.map -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/components/HTMLContainer.mjs.map b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/components/HTMLContainer.mjs.map -new file mode 100644 -index 0000000..721a688 ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/components/HTMLContainer.mjs.map -@@ -0,0 +1,7 @@ -+{ -+ "version": 3, -+ "sources": ["../../../src/lib/components/HTMLContainer.tsx"], -+ "sourcesContent": ["import classNames from 'classnames'\nimport * as React from 'react'\n\n/** @public */\nexport type HTMLContainerProps = React.HTMLAttributes\n\n/** @public @react */\nexport function HTMLContainer({ children, className = '', ...rest }: HTMLContainerProps) {\n\treturn (\n\t\t
\n\t\t\t{children}\n\t\t
\n\t)\n}\n"], -+ "mappings": "AASE;AATF,OAAO,gBAAgB;AAOhB,SAAS,cAAc,EAAE,UAAU,YAAY,IAAI,GAAG,KAAK,GAAuB;AACxF,SACC,oBAAC,SAAK,GAAG,MAAM,WAAW,WAAW,qBAAqB,SAAS,GACjE,UACF;AAEF;", -+ "names": [] -+} -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/components/LiveCollaborators.mjs b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/components/LiveCollaborators.mjs -new file mode 100644 -index 0000000..f9a5896 ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/components/LiveCollaborators.mjs -@@ -0,0 +1,135 @@ -+import { Fragment, jsx, jsxs } from "react/jsx-runtime"; -+import { track } from "@tldraw/state-react"; -+import { useEffect, useRef, useState } from "react"; -+import { useEditor } from "../hooks/useEditor.mjs"; -+import { useEditorComponents } from "../hooks/useEditorComponents.mjs"; -+import { usePeerIds } from "../hooks/usePeerIds.mjs"; -+import { usePresence } from "../hooks/usePresence.mjs"; -+const LiveCollaborators = track(function Collaborators() { -+ const peerIds = usePeerIds(); -+ return peerIds.map((id) => /* @__PURE__ */ jsx(CollaboratorGuard, { collaboratorId: id }, id)); -+}); -+const CollaboratorGuard = track(function CollaboratorGuard2({ -+ collaboratorId -+}) { -+ const editor = useEditor(); -+ const presence = usePresence(collaboratorId); -+ const collaboratorState = useCollaboratorState(editor, presence); -+ if (!(presence && presence.currentPageId === editor.getCurrentPageId())) { -+ return null; -+ } -+ switch (collaboratorState) { -+ case "inactive": { -+ const { followingUserId, highlightedUserIds } = editor.getInstanceState(); -+ if (!(followingUserId === presence.userId || highlightedUserIds.includes(presence.userId))) { -+ return null; -+ } -+ break; -+ } -+ case "idle": { -+ const { highlightedUserIds } = editor.getInstanceState(); -+ if (presence.followingUserId === editor.user.getId() && !(presence.chatMessage || highlightedUserIds.includes(presence.userId))) { -+ return null; -+ } -+ break; -+ } -+ case "active": { -+ break; -+ } -+ } -+ return /* @__PURE__ */ jsx(Collaborator, { latestPresence: presence }); -+}); -+const Collaborator = track(function Collaborator2({ -+ latestPresence -+}) { -+ const editor = useEditor(); -+ const { -+ CollaboratorBrush, -+ CollaboratorScribble, -+ CollaboratorCursor, -+ CollaboratorHint, -+ CollaboratorShapeIndicator -+ } = useEditorComponents(); -+ const zoomLevel = editor.getZoomLevel(); -+ const viewportPageBounds = editor.getViewportPageBounds(); -+ const { userId, chatMessage, brush, scribbles, selectedShapeIds, userName, cursor, color } = latestPresence; -+ const isCursorInViewport = !(cursor.x < viewportPageBounds.minX - 12 / zoomLevel || cursor.y < viewportPageBounds.minY - 16 / zoomLevel || cursor.x > viewportPageBounds.maxX - 12 / zoomLevel || cursor.y > viewportPageBounds.maxY - 16 / zoomLevel); -+ return /* @__PURE__ */ jsxs(Fragment, { children: [ -+ brush && CollaboratorBrush ? /* @__PURE__ */ jsx( -+ CollaboratorBrush, -+ { -+ className: "tl-collaborator__brush", -+ brush, -+ color, -+ opacity: 0.1 -+ }, -+ userId + "_brush" -+ ) : null, -+ isCursorInViewport && CollaboratorCursor ? /* @__PURE__ */ jsx( -+ CollaboratorCursor, -+ { -+ className: "tl-collaborator__cursor", -+ point: cursor, -+ color, -+ zoom: zoomLevel, -+ name: userName !== "New User" ? userName : null, -+ chatMessage -+ }, -+ userId + "_cursor" -+ ) : CollaboratorHint ? /* @__PURE__ */ jsx( -+ CollaboratorHint, -+ { -+ className: "tl-collaborator__cursor-hint", -+ point: cursor, -+ color, -+ zoom: zoomLevel, -+ viewport: viewportPageBounds -+ }, -+ userId + "_cursor_hint" -+ ) : null, -+ CollaboratorScribble && scribbles.length ? /* @__PURE__ */ jsx(Fragment, { children: scribbles.map((scribble) => /* @__PURE__ */ jsx( -+ CollaboratorScribble, -+ { -+ className: "tl-collaborator__scribble", -+ scribble, -+ color, -+ zoom: zoomLevel, -+ opacity: scribble.color === "laser" ? 0.5 : 0.1 -+ }, -+ userId + "_scribble_" + scribble.id -+ )) }) : null, -+ CollaboratorShapeIndicator && selectedShapeIds.filter((id) => !editor.isShapeHidden(id)).map((shapeId) => /* @__PURE__ */ jsx( -+ CollaboratorShapeIndicator, -+ { -+ className: "tl-collaborator__shape-indicator", -+ shapeId, -+ color, -+ opacity: 0.5 -+ }, -+ userId + "_" + shapeId -+ )) -+ ] }); -+}); -+function getStateFromElapsedTime(editor, elapsed) { -+ return elapsed > editor.options.collaboratorInactiveTimeoutMs ? "inactive" : elapsed > editor.options.collaboratorIdleTimeoutMs ? "idle" : "active"; -+} -+function useCollaboratorState(editor, latestPresence) { -+ const rLastActivityTimestamp = useRef(latestPresence?.lastActivityTimestamp ?? -1); -+ const [state, setState] = useState( -+ () => getStateFromElapsedTime(editor, Date.now() - rLastActivityTimestamp.current) -+ ); -+ useEffect(() => { -+ const interval = editor.timers.setInterval(() => { -+ setState(getStateFromElapsedTime(editor, Date.now() - rLastActivityTimestamp.current)); -+ }, editor.options.collaboratorCheckIntervalMs); -+ return () => clearInterval(interval); -+ }, [editor]); -+ if (latestPresence) { -+ rLastActivityTimestamp.current = latestPresence.lastActivityTimestamp; -+ } -+ return state; -+} -+export { -+ LiveCollaborators -+}; -+//# sourceMappingURL=LiveCollaborators.mjs.map -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/components/LiveCollaborators.mjs.map b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/components/LiveCollaborators.mjs.map -new file mode 100644 -index 0000000..43e1430 ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/components/LiveCollaborators.mjs.map -@@ -0,0 +1,7 @@ -+{ -+ "version": 3, -+ "sources": ["../../../src/lib/components/LiveCollaborators.tsx"], -+ "sourcesContent": ["import { track } from '@tldraw/state-react'\nimport { TLInstancePresence } from '@tldraw/tlschema'\nimport { useEffect, useRef, useState } from 'react'\nimport { Editor } from '../editor/Editor'\nimport { useEditor } from '../hooks/useEditor'\nimport { useEditorComponents } from '../hooks/useEditorComponents'\nimport { usePeerIds } from '../hooks/usePeerIds'\nimport { usePresence } from '../hooks/usePresence'\n\nexport const LiveCollaborators = track(function Collaborators() {\n\tconst peerIds = usePeerIds()\n\treturn peerIds.map((id) => )\n})\n\nconst CollaboratorGuard = track(function CollaboratorGuard({\n\tcollaboratorId,\n}: {\n\tcollaboratorId: string\n}) {\n\tconst editor = useEditor()\n\tconst presence = usePresence(collaboratorId)\n\tconst collaboratorState = useCollaboratorState(editor, presence)\n\n\tif (!(presence && presence.currentPageId === editor.getCurrentPageId())) {\n\t\t// No need to render if we don't have a presence or if they're on a different page\n\t\treturn null\n\t}\n\n\tswitch (collaboratorState) {\n\t\tcase 'inactive': {\n\t\t\tconst { followingUserId, highlightedUserIds } = editor.getInstanceState()\n\t\t\t// If they're inactive and unless we're following them or they're highlighted, hide them\n\t\t\tif (!(followingUserId === presence.userId || highlightedUserIds.includes(presence.userId))) {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\tbreak\n\t\t}\n\t\tcase 'idle': {\n\t\t\tconst { highlightedUserIds } = editor.getInstanceState()\n\t\t\t// If they're idle and following us and unless they have a chat message or are highlighted, hide them\n\t\t\tif (\n\t\t\t\tpresence.followingUserId === editor.user.getId() &&\n\t\t\t\t!(presence.chatMessage || highlightedUserIds.includes(presence.userId))\n\t\t\t) {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\tbreak\n\t\t}\n\t\tcase 'active': {\n\t\t\t// If they're active, show them\n\t\t\tbreak\n\t\t}\n\t}\n\n\treturn \n})\n\nconst Collaborator = track(function Collaborator({\n\tlatestPresence,\n}: {\n\tlatestPresence: TLInstancePresence\n}) {\n\tconst editor = useEditor()\n\n\tconst {\n\t\tCollaboratorBrush,\n\t\tCollaboratorScribble,\n\t\tCollaboratorCursor,\n\t\tCollaboratorHint,\n\t\tCollaboratorShapeIndicator,\n\t} = useEditorComponents()\n\n\tconst zoomLevel = editor.getZoomLevel()\n\tconst viewportPageBounds = editor.getViewportPageBounds()\n\tconst { userId, chatMessage, brush, scribbles, selectedShapeIds, userName, cursor, color } =\n\t\tlatestPresence\n\n\t// Add a little padding to the top-left of the viewport\n\t// so that the cursor doesn't get cut off\n\tconst isCursorInViewport = !(\n\t\tcursor.x < viewportPageBounds.minX - 12 / zoomLevel ||\n\t\tcursor.y < viewportPageBounds.minY - 16 / zoomLevel ||\n\t\tcursor.x > viewportPageBounds.maxX - 12 / zoomLevel ||\n\t\tcursor.y > viewportPageBounds.maxY - 16 / zoomLevel\n\t)\n\n\treturn (\n\t\t<>\n\t\t\t{brush && CollaboratorBrush ? (\n\t\t\t\t\n\t\t\t) : null}\n\t\t\t{isCursorInViewport && CollaboratorCursor ? (\n\t\t\t\t\n\t\t\t) : CollaboratorHint ? (\n\t\t\t\t\n\t\t\t) : null}\n\t\t\t{CollaboratorScribble && scribbles.length ? (\n\t\t\t\t<>\n\t\t\t\t\t{scribbles.map((scribble) => (\n\t\t\t\t\t\t\n\t\t\t\t\t))}\n\t\t\t\t\n\t\t\t) : null}\n\t\t\t{CollaboratorShapeIndicator &&\n\t\t\t\tselectedShapeIds\n\t\t\t\t\t.filter((id) => !editor.isShapeHidden(id))\n\t\t\t\t\t.map((shapeId) => (\n\t\t\t\t\t\t\n\t\t\t\t\t))}\n\t\t\n\t)\n})\n\nfunction getStateFromElapsedTime(editor: Editor, elapsed: number) {\n\treturn elapsed > editor.options.collaboratorInactiveTimeoutMs\n\t\t? 'inactive'\n\t\t: elapsed > editor.options.collaboratorIdleTimeoutMs\n\t\t\t? 'idle'\n\t\t\t: 'active'\n}\n\nfunction useCollaboratorState(editor: Editor, latestPresence: TLInstancePresence | null) {\n\tconst rLastActivityTimestamp = useRef(latestPresence?.lastActivityTimestamp ?? -1)\n\n\tconst [state, setState] = useState<'active' | 'idle' | 'inactive'>(() =>\n\t\tgetStateFromElapsedTime(editor, Date.now() - rLastActivityTimestamp.current)\n\t)\n\n\tuseEffect(() => {\n\t\tconst interval = editor.timers.setInterval(() => {\n\t\t\tsetState(getStateFromElapsedTime(editor, Date.now() - rLastActivityTimestamp.current))\n\t\t}, editor.options.collaboratorCheckIntervalMs)\n\n\t\treturn () => clearInterval(interval)\n\t}, [editor])\n\n\tif (latestPresence) {\n\t\t// We can do this on every render, it's free and cheaper than an effect\n\t\t// remember, there can be lots and lots of cursors moving around all the time\n\t\trLastActivityTimestamp.current = latestPresence.lastActivityTimestamp\n\t}\n\n\treturn state\n}\n"], -+ "mappings": "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", -+ "names": ["CollaboratorGuard", "Collaborator"] -+} -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/components/SVGContainer.mjs b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/components/SVGContainer.mjs -new file mode 100644 -index 0000000..cc6d74a ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/components/SVGContainer.mjs -@@ -0,0 +1,9 @@ -+import { jsx } from "react/jsx-runtime"; -+import classNames from "classnames"; -+function SVGContainer({ children, className = "", ...rest }) { -+ return /* @__PURE__ */ jsx("svg", { ...rest, className: classNames("tl-svg-container", className), children }); -+} -+export { -+ SVGContainer -+}; -+//# sourceMappingURL=SVGContainer.mjs.map -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/components/SVGContainer.mjs.map b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/components/SVGContainer.mjs.map -new file mode 100644 -index 0000000..f337da7 ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/components/SVGContainer.mjs.map -@@ -0,0 +1,7 @@ -+{ -+ "version": 3, -+ "sources": ["../../../src/lib/components/SVGContainer.tsx"], -+ "sourcesContent": ["import classNames from 'classnames'\nimport * as React from 'react'\n\n/** @public */\nexport type SVGContainerProps = React.HTMLAttributes\n\n/** @public @react */\nexport function SVGContainer({ children, className = '', ...rest }: SVGContainerProps) {\n\treturn (\n\t\t\n\t\t\t{children}\n\t\t\n\t)\n}\n"], -+ "mappings": "AASE;AATF,OAAO,gBAAgB;AAOhB,SAAS,aAAa,EAAE,UAAU,YAAY,IAAI,GAAG,KAAK,GAAsB;AACtF,SACC,oBAAC,SAAK,GAAG,MAAM,WAAW,WAAW,oBAAoB,SAAS,GAChE,UACF;AAEF;", -+ "names": [] -+} -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/components/Shape.mjs b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/components/Shape.mjs -new file mode 100644 -index 0000000..5bce2d3 ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/components/Shape.mjs -@@ -0,0 +1,154 @@ -+import { Fragment, jsx, jsxs } from "react/jsx-runtime"; -+import { useQuickReactor, useStateTracking } from "@tldraw/state-react"; -+import { memo, useCallback, useRef } from "react"; -+import { useEditor } from "../hooks/useEditor.mjs"; -+import { useEditorComponents } from "../hooks/useEditorComponents.mjs"; -+import { Mat } from "../primitives/Mat.mjs"; -+import { setStyleProperty } from "../utils/dom.mjs"; -+import { OptionalErrorBoundary } from "./ErrorBoundary.mjs"; -+const Shape = memo(function Shape2({ -+ id, -+ shape, -+ util, -+ index, -+ backgroundIndex, -+ opacity -+}) { -+ const editor = useEditor(); -+ const { ShapeErrorFallback } = useEditorComponents(); -+ const containerRef = useRef(null); -+ const bgContainerRef = useRef(null); -+ const memoizedStuffRef = useRef({ -+ transform: "", -+ clipPath: "none", -+ width: 0, -+ height: 0, -+ x: 0, -+ y: 0, -+ isCulled: false -+ }); -+ useQuickReactor( -+ "set shape stuff", -+ () => { -+ const shape2 = editor.getShape(id); -+ if (!shape2) return; -+ const prev = memoizedStuffRef.current; -+ const clipPath = editor.getShapeClipPath(id) ?? "none"; -+ if (clipPath !== prev.clipPath) { -+ setStyleProperty(containerRef.current, "clip-path", clipPath); -+ setStyleProperty(bgContainerRef.current, "clip-path", clipPath); -+ prev.clipPath = clipPath; -+ } -+ const pageTransform = editor.getShapePageTransform(id); -+ const transform = Mat.toCssString(pageTransform); -+ const bounds = editor.getShapeGeometry(shape2).bounds; -+ if (transform !== prev.transform) { -+ setStyleProperty(containerRef.current, "transform", transform); -+ setStyleProperty(bgContainerRef.current, "transform", transform); -+ prev.transform = transform; -+ } -+ const width = Math.max(bounds.width, 1); -+ const height = Math.max(bounds.height, 1); -+ if (width !== prev.width || height !== prev.height) { -+ setStyleProperty(containerRef.current, "width", width + "px"); -+ setStyleProperty(containerRef.current, "height", height + "px"); -+ setStyleProperty(bgContainerRef.current, "width", width + "px"); -+ setStyleProperty(bgContainerRef.current, "height", height + "px"); -+ prev.width = width; -+ prev.height = height; -+ } -+ }, -+ [editor] -+ ); -+ useQuickReactor( -+ "set opacity and z-index", -+ () => { -+ const container = containerRef.current; -+ const bgContainer = bgContainerRef.current; -+ setStyleProperty(container, "opacity", opacity); -+ setStyleProperty(bgContainer, "opacity", opacity); -+ setStyleProperty(container, "z-index", index); -+ setStyleProperty(bgContainer, "z-index", backgroundIndex); -+ }, -+ [opacity, index, backgroundIndex] -+ ); -+ useQuickReactor( -+ "set display", -+ () => { -+ const shape2 = editor.getShape(id); -+ if (!shape2) return; -+ const culledShapes = editor.getCulledShapes(); -+ const isCulled = culledShapes.has(id); -+ if (isCulled !== memoizedStuffRef.current.isCulled) { -+ setStyleProperty(containerRef.current, "display", isCulled ? "none" : "block"); -+ setStyleProperty(bgContainerRef.current, "display", isCulled ? "none" : "block"); -+ memoizedStuffRef.current.isCulled = isCulled; -+ } -+ }, -+ [editor] -+ ); -+ const annotateError = useCallback( -+ (error) => editor.annotateError(error, { origin: "shape", willCrashApp: false }), -+ [editor] -+ ); -+ if (!shape) return null; -+ const isFilledShape = "fill" in shape.props && shape.props.fill !== "none"; -+ return /* @__PURE__ */ jsxs(Fragment, { children: [ -+ util.backgroundComponent && /* @__PURE__ */ jsx( -+ "div", -+ { -+ ref: bgContainerRef, -+ className: "tl-shape tl-shape-background", -+ "data-shape-type": shape.type, -+ draggable: false, -+ children: /* @__PURE__ */ jsx(OptionalErrorBoundary, { fallback: ShapeErrorFallback, onError: annotateError, children: /* @__PURE__ */ jsx(InnerShapeBackground, { shape, util }) }) -+ } -+ ), -+ /* @__PURE__ */ jsx( -+ "div", -+ { -+ ref: containerRef, -+ className: "tl-shape", -+ "data-shape-type": shape.type, -+ "data-shape-is-filled": isFilledShape, -+ draggable: false, -+ children: /* @__PURE__ */ jsx(OptionalErrorBoundary, { fallback: ShapeErrorFallback, onError: annotateError, children: /* @__PURE__ */ jsx(InnerShape, { shape, util }) }) -+ } -+ ) -+ ] }); -+}); -+const InnerShape = memo( -+ function InnerShape2({ shape, util }) { -+ return useStateTracking( -+ "InnerShape:" + shape.type, -+ () => ( -+ // always fetch the latest shape from the store even if the props/meta have not changed, to avoid -+ // calling the render method with stale data. -+ (util.component(util.editor.store.unsafeGetWithoutCapture(shape.id))) -+ ) -+ ); -+ }, -+ (prev, next) => prev.shape.props === next.shape.props && prev.shape.meta === next.shape.meta -+); -+const InnerShapeBackground = memo( -+ function InnerShapeBackground2({ -+ shape, -+ util -+ }) { -+ return useStateTracking( -+ "InnerShape:" + shape.type, -+ () => ( -+ // always fetch the latest shape from the store even if the props/meta have not changed, to avoid -+ // calling the render method with stale data. -+ (util.backgroundComponent?.(util.editor.store.unsafeGetWithoutCapture(shape.id))) -+ ) -+ ); -+ }, -+ (prev, next) => prev.shape.props === next.shape.props && prev.shape.meta === next.shape.meta -+); -+export { -+ InnerShape, -+ InnerShapeBackground, -+ Shape -+}; -+//# sourceMappingURL=Shape.mjs.map -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/components/Shape.mjs.map b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/components/Shape.mjs.map -new file mode 100644 -index 0000000..4821149 ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/components/Shape.mjs.map -@@ -0,0 +1,7 @@ -+{ -+ "version": 3, -+ "sources": ["../../../src/lib/components/Shape.tsx"], -+ "sourcesContent": ["import { useQuickReactor, useStateTracking } from '@tldraw/state-react'\nimport { TLShape, TLShapeId } from '@tldraw/tlschema'\nimport { memo, useCallback, useRef } from 'react'\nimport { ShapeUtil } from '../editor/shapes/ShapeUtil'\nimport { useEditor } from '../hooks/useEditor'\nimport { useEditorComponents } from '../hooks/useEditorComponents'\nimport { Mat } from '../primitives/Mat'\nimport { setStyleProperty } from '../utils/dom'\nimport { OptionalErrorBoundary } from './ErrorBoundary'\n\n/*\nThis component renders shapes on the canvas. There are two stages: positioning\nand styling the shape's container using CSS, and then rendering the shape's \nJSX using its shape util's render method. Rendering the \"inside\" of a shape is\nmore expensive than positioning it or changing its color, so we use memo\nto wrap the inner shape and only re-render it when the shape's props change. \n\nThe shape also receives props for its index and opacity. The index is used to\ndetermine the z-index of the shape, and the opacity is used to set the shape's\nopacity based on its own opacity and that of its parent's.\n*/\nexport const Shape = memo(function Shape({\n\tid,\n\tshape,\n\tutil,\n\tindex,\n\tbackgroundIndex,\n\topacity,\n}: {\n\tid: TLShapeId\n\tshape: TLShape\n\tutil: ShapeUtil\n\tindex: number\n\tbackgroundIndex: number\n\topacity: number\n}) {\n\tconst editor = useEditor()\n\n\tconst { ShapeErrorFallback } = useEditorComponents()\n\n\tconst containerRef = useRef(null)\n\tconst bgContainerRef = useRef(null)\n\n\tconst memoizedStuffRef = useRef({\n\t\ttransform: '',\n\t\tclipPath: 'none',\n\t\twidth: 0,\n\t\theight: 0,\n\t\tx: 0,\n\t\ty: 0,\n\t\tisCulled: false,\n\t})\n\n\tuseQuickReactor(\n\t\t'set shape stuff',\n\t\t() => {\n\t\t\tconst shape = editor.getShape(id)\n\t\t\tif (!shape) return // probably the shape was just deleted\n\n\t\t\tconst prev = memoizedStuffRef.current\n\n\t\t\t// Clip path\n\t\t\tconst clipPath = editor.getShapeClipPath(id) ?? 'none'\n\t\t\tif (clipPath !== prev.clipPath) {\n\t\t\t\tsetStyleProperty(containerRef.current, 'clip-path', clipPath)\n\t\t\t\tsetStyleProperty(bgContainerRef.current, 'clip-path', clipPath)\n\t\t\t\tprev.clipPath = clipPath\n\t\t\t}\n\n\t\t\t// Page transform\n\t\t\tconst pageTransform = editor.getShapePageTransform(id)\n\t\t\tconst transform = Mat.toCssString(pageTransform)\n\t\t\tconst bounds = editor.getShapeGeometry(shape).bounds\n\n\t\t\t// Update if the tranform has changed\n\t\t\tif (transform !== prev.transform) {\n\t\t\t\tsetStyleProperty(containerRef.current, 'transform', transform)\n\t\t\t\tsetStyleProperty(bgContainerRef.current, 'transform', transform)\n\t\t\t\tprev.transform = transform\n\t\t\t}\n\n\t\t\t// Width / Height\n\t\t\tconst width = Math.max(bounds.width, 1)\n\t\t\tconst height = Math.max(bounds.height, 1)\n\n\t\t\tif (width !== prev.width || height !== prev.height) {\n\t\t\t\tsetStyleProperty(containerRef.current, 'width', width + 'px')\n\t\t\t\tsetStyleProperty(containerRef.current, 'height', height + 'px')\n\t\t\t\tsetStyleProperty(bgContainerRef.current, 'width', width + 'px')\n\t\t\t\tsetStyleProperty(bgContainerRef.current, 'height', height + 'px')\n\t\t\t\tprev.width = width\n\t\t\t\tprev.height = height\n\t\t\t}\n\t\t},\n\t\t[editor]\n\t)\n\n\t// This stuff changes pretty infrequently, so we can change them together\n\tuseQuickReactor(\n\t\t'set opacity and z-index',\n\t\t() => {\n\t\t\tconst container = containerRef.current\n\t\t\tconst bgContainer = bgContainerRef.current\n\n\t\t\t// Opacity\n\t\t\tsetStyleProperty(container, 'opacity', opacity)\n\t\t\tsetStyleProperty(bgContainer, 'opacity', opacity)\n\n\t\t\t// Z-Index\n\t\t\tsetStyleProperty(container, 'z-index', index)\n\t\t\tsetStyleProperty(bgContainer, 'z-index', backgroundIndex)\n\t\t},\n\t\t[opacity, index, backgroundIndex]\n\t)\n\n\tuseQuickReactor(\n\t\t'set display',\n\t\t() => {\n\t\t\tconst shape = editor.getShape(id)\n\t\t\tif (!shape) return // probably the shape was just deleted\n\n\t\t\tconst culledShapes = editor.getCulledShapes()\n\t\t\tconst isCulled = culledShapes.has(id)\n\t\t\tif (isCulled !== memoizedStuffRef.current.isCulled) {\n\t\t\t\tsetStyleProperty(containerRef.current, 'display', isCulled ? 'none' : 'block')\n\t\t\t\tsetStyleProperty(bgContainerRef.current, 'display', isCulled ? 'none' : 'block')\n\t\t\t\tmemoizedStuffRef.current.isCulled = isCulled\n\t\t\t}\n\t\t},\n\t\t[editor]\n\t)\n\tconst annotateError = useCallback(\n\t\t(error: any) => editor.annotateError(error, { origin: 'shape', willCrashApp: false }),\n\t\t[editor]\n\t)\n\n\tif (!shape) return null\n\n\tconst isFilledShape = 'fill' in shape.props && shape.props.fill !== 'none'\n\n\treturn (\n\t\t<>\n\t\t\t{util.backgroundComponent && (\n\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t
\n\t\t\t)}\n\t\t\t\n\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\n\t\t\t\n\t\t\n\t)\n})\n\nexport const InnerShape = memo(\n\tfunction InnerShape({ shape, util }: { shape: T; util: ShapeUtil }) {\n\t\treturn useStateTracking('InnerShape:' + shape.type, () =>\n\t\t\t// always fetch the latest shape from the store even if the props/meta have not changed, to avoid\n\t\t\t// calling the render method with stale data.\n\t\t\tutil.component(util.editor.store.unsafeGetWithoutCapture(shape.id) as T)\n\t\t)\n\t},\n\t(prev, next) => prev.shape.props === next.shape.props && prev.shape.meta === next.shape.meta\n)\n\nexport const InnerShapeBackground = memo(\n\tfunction InnerShapeBackground({\n\t\tshape,\n\t\tutil,\n\t}: {\n\t\tshape: T\n\t\tutil: ShapeUtil\n\t}) {\n\t\treturn useStateTracking('InnerShape:' + shape.type, () =>\n\t\t\t// always fetch the latest shape from the store even if the props/meta have not changed, to avoid\n\t\t\t// calling the render method with stale data.\n\t\t\tutil.backgroundComponent?.(util.editor.store.unsafeGetWithoutCapture(shape.id) as T)\n\t\t)\n\t},\n\t(prev, next) => prev.shape.props === next.shape.props && prev.shape.meta === next.shape.meta\n)\n"], -+ "mappings": "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", -+ "names": ["Shape", "shape", "InnerShape", "InnerShapeBackground"] -+} -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/components/default-components/DefaultBackground.mjs b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/components/default-components/DefaultBackground.mjs -new file mode 100644 -index 0000000..c402ce7 ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/components/default-components/DefaultBackground.mjs -@@ -0,0 +1,8 @@ -+import { jsx } from "react/jsx-runtime"; -+function DefaultBackground() { -+ return /* @__PURE__ */ jsx("div", { className: "tl-background" }); -+} -+export { -+ DefaultBackground -+}; -+//# sourceMappingURL=DefaultBackground.mjs.map -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/components/default-components/DefaultBackground.mjs.map b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/components/default-components/DefaultBackground.mjs.map -new file mode 100644 -index 0000000..317a0ba ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/components/default-components/DefaultBackground.mjs.map -@@ -0,0 +1,7 @@ -+{ -+ "version": 3, -+ "sources": ["../../../../src/lib/components/default-components/DefaultBackground.tsx"], -+ "sourcesContent": ["/** @public @react */\nexport function DefaultBackground() {\n\treturn
\n}\n"], -+ "mappings": "AAEQ;AADD,SAAS,oBAAoB;AACnC,SAAO,oBAAC,SAAI,WAAU,iBAAgB;AACvC;", -+ "names": [] -+} -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/components/default-components/DefaultBrush.mjs b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/components/default-components/DefaultBrush.mjs -new file mode 100644 -index 0000000..b2ebec7 ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/components/default-components/DefaultBrush.mjs -@@ -0,0 +1,18 @@ -+import { jsx, jsxs } from "react/jsx-runtime"; -+import { useRef } from "react"; -+import { useTransform } from "../../hooks/useTransform.mjs"; -+import { toDomPrecision } from "../../primitives/utils.mjs"; -+const DefaultBrush = ({ brush, color, opacity, className }) => { -+ const rSvg = useRef(null); -+ useTransform(rSvg, brush.x, brush.y); -+ const w = toDomPrecision(Math.max(1, brush.w)); -+ const h = toDomPrecision(Math.max(1, brush.h)); -+ return /* @__PURE__ */ jsx("svg", { className: "tl-overlays__item", ref: rSvg, children: color ? /* @__PURE__ */ jsxs("g", { className: "tl-brush", opacity, children: [ -+ /* @__PURE__ */ jsx("rect", { width: w, height: h, fill: color, opacity: 0.75 }), -+ /* @__PURE__ */ jsx("rect", { width: w, height: h, fill: "none", stroke: color, opacity: 0.1 }) -+ ] }) : /* @__PURE__ */ jsx("rect", { className: `tl-brush tl-brush__default ${className}`, width: w, height: h }) }); -+}; -+export { -+ DefaultBrush -+}; -+//# sourceMappingURL=DefaultBrush.mjs.map -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/components/default-components/DefaultBrush.mjs.map b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/components/default-components/DefaultBrush.mjs.map -new file mode 100644 -index 0000000..d449ff4 ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/components/default-components/DefaultBrush.mjs.map -@@ -0,0 +1,7 @@ -+{ -+ "version": 3, -+ "sources": ["../../../../src/lib/components/default-components/DefaultBrush.tsx"], -+ "sourcesContent": ["import { BoxModel } from '@tldraw/tlschema'\nimport { useRef } from 'react'\nimport { useTransform } from '../../hooks/useTransform'\nimport { toDomPrecision } from '../../primitives/utils'\n\n/** @public */\nexport interface TLBrushProps {\n\tbrush: BoxModel\n\tcolor?: string\n\topacity?: number\n\tclassName?: string\n}\n\n/** @public @react */\nexport const DefaultBrush = ({ brush, color, opacity, className }: TLBrushProps) => {\n\tconst rSvg = useRef(null)\n\tuseTransform(rSvg, brush.x, brush.y)\n\n\tconst w = toDomPrecision(Math.max(1, brush.w))\n\tconst h = toDomPrecision(Math.max(1, brush.h))\n\n\treturn (\n\t\t\n\t\t\t{color ? (\n\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\n\t\t\t) : (\n\t\t\t\t\n\t\t\t)}\n\t\t\n\t)\n}\n"], -+ "mappings": "AAwBI,SACC,KADD;AAvBJ,SAAS,cAAc;AACvB,SAAS,oBAAoB;AAC7B,SAAS,sBAAsB;AAWxB,MAAM,eAAe,CAAC,EAAE,OAAO,OAAO,SAAS,UAAU,MAAoB;AACnF,QAAM,OAAO,OAAsB,IAAI;AACvC,eAAa,MAAM,MAAM,GAAG,MAAM,CAAC;AAEnC,QAAM,IAAI,eAAe,KAAK,IAAI,GAAG,MAAM,CAAC,CAAC;AAC7C,QAAM,IAAI,eAAe,KAAK,IAAI,GAAG,MAAM,CAAC,CAAC;AAE7C,SACC,oBAAC,SAAI,WAAU,qBAAoB,KAAK,MACtC,kBACA,qBAAC,OAAE,WAAU,YAAW,SACvB;AAAA,wBAAC,UAAK,OAAO,GAAG,QAAQ,GAAG,MAAM,OAAO,SAAS,MAAM;AAAA,IACvD,oBAAC,UAAK,OAAO,GAAG,QAAQ,GAAG,MAAK,QAAO,QAAQ,OAAO,SAAS,KAAK;AAAA,KACrE,IAEA,oBAAC,UAAK,WAAW,8BAA8B,SAAS,IAAI,OAAO,GAAG,QAAQ,GAAG,GAEnF;AAEF;", -+ "names": [] -+} -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/components/default-components/DefaultCanvas.mjs b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/components/default-components/DefaultCanvas.mjs -new file mode 100644 -index 0000000..500c646 ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/components/default-components/DefaultCanvas.mjs -@@ -0,0 +1,446 @@ -+import { Fragment, jsx, jsxs } from "react/jsx-runtime"; -+import { react } from "@tldraw/state"; -+import { useQuickReactor, useValue } from "@tldraw/state-react"; -+import { dedupe, modulate, objectMapValues } from "@tldraw/utils"; -+import classNames from "classnames"; -+import { Fragment as Fragment2, useEffect, useRef, useState } from "react"; -+import { useCanvasEvents } from "../../hooks/useCanvasEvents.mjs"; -+import { useCoarsePointer } from "../../hooks/useCoarsePointer.mjs"; -+import { useContainer } from "../../hooks/useContainer.mjs"; -+import { useDocumentEvents } from "../../hooks/useDocumentEvents.mjs"; -+import { useEditor } from "../../hooks/useEditor.mjs"; -+import { useEditorComponents } from "../../hooks/useEditorComponents.mjs"; -+import { useFixSafariDoubleTapZoomPencilEvents } from "../../hooks/useFixSafariDoubleTapZoomPencilEvents.mjs"; -+import { useGestureEvents } from "../../hooks/useGestureEvents.mjs"; -+import { useHandleEvents } from "../../hooks/useHandleEvents.mjs"; -+import { useScreenBounds } from "../../hooks/useScreenBounds.mjs"; -+import { Mat } from "../../primitives/Mat.mjs"; -+import { Vec } from "../../primitives/Vec.mjs"; -+import { toDomPrecision } from "../../primitives/utils.mjs"; -+import { debugFlags } from "../../utils/debug-flags.mjs"; -+import { setStyleProperty } from "../../utils/dom.mjs"; -+import { GeometryDebuggingView } from "../GeometryDebuggingView.mjs"; -+import { LiveCollaborators } from "../LiveCollaborators.mjs"; -+import { Shape } from "../Shape.mjs"; -+function DefaultCanvas({ className }) { -+ const editor = useEditor(); -+ const { Background, SvgDefs, ShapeIndicators } = useEditorComponents(); -+ const rCanvas = useRef(null); -+ const rHtmlLayer = useRef(null); -+ const rHtmlLayer2 = useRef(null); -+ const container = useContainer(); -+ useScreenBounds(rCanvas); -+ useDocumentEvents(); -+ useCoarsePointer(); -+ useGestureEvents(rCanvas); -+ useFixSafariDoubleTapZoomPencilEvents(rCanvas); -+ const rMemoizedStuff = useRef({ lodDisableTextOutline: false, allowTextOutline: true }); -+ useQuickReactor( -+ "position layers", -+ function positionLayersWhenCameraMoves() { -+ const { x, y, z } = editor.getCamera(); -+ if (rMemoizedStuff.current.allowTextOutline && editor.environment.isSafari) { -+ container.style.setProperty("--tl-text-outline", "none"); -+ rMemoizedStuff.current.allowTextOutline = false; -+ } -+ if (rMemoizedStuff.current.allowTextOutline && z < editor.options.textShadowLod !== rMemoizedStuff.current.lodDisableTextOutline) { -+ const lodDisableTextOutline = z < editor.options.textShadowLod; -+ container.style.setProperty( -+ "--tl-text-outline", -+ lodDisableTextOutline ? "none" : `var(--tl-text-outline-reference)` -+ ); -+ rMemoizedStuff.current.lodDisableTextOutline = lodDisableTextOutline; -+ } -+ const offset = z >= 1 ? modulate(z, [1, 8], [0.125, 0.5], true) : modulate(z, [0.1, 1], [-2, 0.125], true); -+ const transform = `scale(${toDomPrecision(z)}) translate(${toDomPrecision( -+ x + offset -+ )}px,${toDomPrecision(y + offset)}px)`; -+ setStyleProperty(rHtmlLayer.current, "transform", transform); -+ setStyleProperty(rHtmlLayer2.current, "transform", transform); -+ }, -+ [editor, container] -+ ); -+ const events = useCanvasEvents(); -+ const shapeSvgDefs = useValue( -+ "shapeSvgDefs", -+ () => { -+ const shapeSvgDefsByKey = /* @__PURE__ */ new Map(); -+ for (const util of objectMapValues(editor.shapeUtils)) { -+ if (!util) return; -+ const defs = util.getCanvasSvgDefs(); -+ for (const { key, component: Component } of defs) { -+ if (shapeSvgDefsByKey.has(key)) continue; -+ shapeSvgDefsByKey.set(key, /* @__PURE__ */ jsx(Component, {}, key)); -+ } -+ } -+ return [...shapeSvgDefsByKey.values()]; -+ }, -+ [editor] -+ ); -+ const hideShapes = useValue("debug_shapes", () => debugFlags.hideShapes.get(), [debugFlags]); -+ const debugSvg = useValue("debug_svg", () => debugFlags.debugSvg.get(), [debugFlags]); -+ const debugGeometry = useValue("debug_geometry", () => debugFlags.debugGeometry.get(), [ -+ debugFlags -+ ]); -+ const isEditingAnything = useValue( -+ "isEditingAnything", -+ () => editor.getEditingShapeId() !== null, -+ [editor] -+ ); -+ const isSelectingAnything = useValue( -+ "isSelectingAnything", -+ () => !!editor.getSelectedShapeIds().length, -+ [editor] -+ ); -+ return /* @__PURE__ */ jsxs(Fragment, { children: [ -+ /* @__PURE__ */ jsxs( -+ "div", -+ { -+ ref: rCanvas, -+ draggable: false, -+ "data-iseditinganything": isEditingAnything, -+ "data-isselectinganything": isSelectingAnything, -+ className: classNames("tl-canvas", className), -+ "data-testid": "canvas", -+ ...events, -+ children: [ -+ /* @__PURE__ */ jsx("svg", { className: "tl-svg-context", children: /* @__PURE__ */ jsxs("defs", { children: [ -+ shapeSvgDefs, -+ /* @__PURE__ */ jsx(CursorDef, {}), -+ /* @__PURE__ */ jsx(CollaboratorHintDef, {}), -+ SvgDefs && /* @__PURE__ */ jsx(SvgDefs, {}) -+ ] }) }), -+ Background && /* @__PURE__ */ jsx("div", { className: "tl-background__wrapper", children: /* @__PURE__ */ jsx(Background, {}) }), -+ /* @__PURE__ */ jsx(GridWrapper, {}), -+ /* @__PURE__ */ jsxs("div", { ref: rHtmlLayer, className: "tl-html-layer tl-shapes", draggable: false, children: [ -+ /* @__PURE__ */ jsx(OnTheCanvasWrapper, {}), -+ /* @__PURE__ */ jsx(SelectionBackgroundWrapper, {}), -+ hideShapes ? null : debugSvg ? /* @__PURE__ */ jsx(ShapesWithSVGs, {}) : /* @__PURE__ */ jsx(ShapesToDisplay, {}) -+ ] }), -+ /* @__PURE__ */ jsx("div", { className: "tl-overlays", children: /* @__PURE__ */ jsxs("div", { ref: rHtmlLayer2, className: "tl-html-layer", children: [ -+ debugGeometry ? /* @__PURE__ */ jsx(GeometryDebuggingView, {}) : null, -+ /* @__PURE__ */ jsx(HandlesWrapper, {}), -+ /* @__PURE__ */ jsx(BrushWrapper, {}), -+ /* @__PURE__ */ jsx(ScribbleWrapper, {}), -+ /* @__PURE__ */ jsx(ZoomBrushWrapper, {}), -+ ShapeIndicators && /* @__PURE__ */ jsx(ShapeIndicators, {}), -+ /* @__PURE__ */ jsx(HintedShapeIndicator, {}), -+ /* @__PURE__ */ jsx(SnapIndicatorWrapper, {}), -+ /* @__PURE__ */ jsx(SelectionForegroundWrapper, {}), -+ /* @__PURE__ */ jsx(LiveCollaborators, {}) -+ ] }) }), -+ /* @__PURE__ */ jsx(MovingCameraHitTestBlocker, {}) -+ ] -+ } -+ ), -+ /* @__PURE__ */ jsx(InFrontOfTheCanvasWrapper, {}) -+ ] }); -+} -+function InFrontOfTheCanvasWrapper() { -+ const { InFrontOfTheCanvas } = useEditorComponents(); -+ if (!InFrontOfTheCanvas) return null; -+ return /* @__PURE__ */ jsx(InFrontOfTheCanvas, {}); -+} -+function GridWrapper() { -+ const editor = useEditor(); -+ const gridSize = useValue("gridSize", () => editor.getDocumentSettings().gridSize, [editor]); -+ const { x, y, z } = useValue("camera", () => editor.getCamera(), [editor]); -+ const isGridMode = useValue("isGridMode", () => editor.getInstanceState().isGridMode, [editor]); -+ const { Grid } = useEditorComponents(); -+ if (!(Grid && isGridMode)) return null; -+ return /* @__PURE__ */ jsx(Grid, { x, y, z, size: gridSize }); -+} -+function ScribbleWrapper() { -+ const editor = useEditor(); -+ const scribbles = useValue("scribbles", () => editor.getInstanceState().scribbles, [editor]); -+ const zoomLevel = useValue("zoomLevel", () => editor.getZoomLevel(), [editor]); -+ const { Scribble } = useEditorComponents(); -+ if (!(Scribble && scribbles.length)) return null; -+ return scribbles.map((scribble) => /* @__PURE__ */ jsx(Scribble, { className: "tl-user-scribble", scribble, zoom: zoomLevel }, scribble.id)); -+} -+function BrushWrapper() { -+ const editor = useEditor(); -+ const brush = useValue("brush", () => editor.getInstanceState().brush, [editor]); -+ const { Brush } = useEditorComponents(); -+ if (!(Brush && brush)) return null; -+ return /* @__PURE__ */ jsx(Brush, { className: "tl-user-brush", brush }); -+} -+function ZoomBrushWrapper() { -+ const editor = useEditor(); -+ const zoomBrush = useValue("zoomBrush", () => editor.getInstanceState().zoomBrush, [editor]); -+ const { ZoomBrush } = useEditorComponents(); -+ if (!(ZoomBrush && zoomBrush)) return null; -+ return /* @__PURE__ */ jsx(ZoomBrush, { className: "tl-user-brush tl-zoom-brush", brush: zoomBrush }); -+} -+function SnapIndicatorWrapper() { -+ const editor = useEditor(); -+ const lines = useValue("snapLines", () => editor.snaps.getIndicators(), [editor]); -+ const zoomLevel = useValue("zoomLevel", () => editor.getZoomLevel(), [editor]); -+ const { SnapIndicator } = useEditorComponents(); -+ if (!(SnapIndicator && lines.length > 0)) return null; -+ return lines.map((line) => /* @__PURE__ */ jsx(SnapIndicator, { className: "tl-user-snapline", line, zoom: zoomLevel }, line.id)); -+} -+function HandlesWrapper() { -+ const editor = useEditor(); -+ const shapeIdWithHandles = useValue( -+ "handles shapeIdWithHandles", -+ () => { -+ const { isReadonly, isChangingStyle } = editor.getInstanceState(); -+ if (isReadonly || isChangingStyle) return false; -+ const onlySelectedShape = editor.getOnlySelectedShape(); -+ if (!onlySelectedShape) return false; -+ const handles = editor.getShapeHandles(onlySelectedShape); -+ if (!handles) return false; -+ return onlySelectedShape.id; -+ }, -+ [editor] -+ ); -+ if (!shapeIdWithHandles) return null; -+ return /* @__PURE__ */ jsx(HandlesWrapperInner, { shapeId: shapeIdWithHandles }); -+} -+function HandlesWrapperInner({ shapeId }) { -+ const editor = useEditor(); -+ const { Handles } = useEditorComponents(); -+ const zoomLevel = useValue("zoomLevel", () => editor.getZoomLevel(), [editor]); -+ const isCoarse = useValue("coarse pointer", () => editor.getInstanceState().isCoarsePointer, [ -+ editor -+ ]); -+ const transform = useValue("handles transform", () => editor.getShapePageTransform(shapeId), [ -+ editor, -+ shapeId -+ ]); -+ const handles = useValue( -+ "handles", -+ () => { -+ const handles2 = editor.getShapeHandles(shapeId); -+ if (!handles2) return null; -+ const minDistBetweenVirtualHandlesAndRegularHandles = (isCoarse ? editor.options.coarseHandleRadius : editor.options.handleRadius) / zoomLevel * 2; -+ return handles2.filter( -+ (handle) => ( -+ // if the handle isn't a virtual handle, we'll display it -+ (// but for virtual handles, we'll only display them if they're far enough away from vertex handles -+ handle.type !== "virtual" || !handles2.some( -+ (h) => ( -+ // skip the handle we're checking against -+ (// and check that their distance isn't below the minimum distance -+ h !== handle && // only check against vertex handles -+ h.type === "vertex" && Vec.Dist(handle, h) < minDistBetweenVirtualHandlesAndRegularHandles) -+ ) -+ )) -+ ) -+ ).sort((a) => a.type === "vertex" ? 1 : -1); -+ }, -+ [editor, zoomLevel, isCoarse, shapeId] -+ ); -+ const isHidden = useValue("isHidden", () => editor.isShapeHidden(shapeId), [editor, shapeId]); -+ if (!Handles || !handles || !transform || isHidden) { -+ return null; -+ } -+ return /* @__PURE__ */ jsx(Handles, { children: /* @__PURE__ */ jsx("g", { transform: Mat.toCssString(transform), children: handles.map((handle) => { -+ return /* @__PURE__ */ jsx( -+ HandleWrapper, -+ { -+ shapeId, -+ handle, -+ zoom: zoomLevel, -+ isCoarse -+ }, -+ handle.id -+ ); -+ }) }) }); -+} -+function HandleWrapper({ -+ shapeId, -+ handle, -+ zoom, -+ isCoarse -+}) { -+ const events = useHandleEvents(shapeId, handle.id); -+ const { Handle } = useEditorComponents(); -+ if (!Handle) return null; -+ return /* @__PURE__ */ jsx("g", { "aria-label": "handle", transform: `translate(${handle.x}, ${handle.y})`, ...events, children: /* @__PURE__ */ jsx(Handle, { shapeId, handle, zoom, isCoarse }) }); -+} -+function ShapesWithSVGs() { -+ const editor = useEditor(); -+ const renderingShapes = useValue("rendering shapes", () => editor.getRenderingShapes(), [editor]); -+ return renderingShapes.map((result) => /* @__PURE__ */ jsxs(Fragment2, { children: [ -+ /* @__PURE__ */ jsx(Shape, { ...result }), -+ /* @__PURE__ */ jsx(DebugSvgCopy, { id: result.id, mode: "iframe" }) -+ ] }, result.id + "_fragment")); -+} -+function ReflowIfNeeded() { -+ const editor = useEditor(); -+ const culledShapesRef = useRef(/* @__PURE__ */ new Set()); -+ useQuickReactor( -+ "reflow for culled shapes", -+ () => { -+ const culledShapes = editor.getCulledShapes(); -+ if (culledShapesRef.current.size === culledShapes.size && [...culledShapes].every((id) => culledShapesRef.current.has(id))) -+ return; -+ culledShapesRef.current = culledShapes; -+ const canvas = document.getElementsByClassName("tl-canvas"); -+ if (canvas.length === 0) return; -+ const _height = canvas[0].offsetHeight; -+ }, -+ [editor] -+ ); -+ return null; -+} -+function ShapesToDisplay() { -+ const editor = useEditor(); -+ const renderingShapes = useValue("rendering shapes", () => editor.getRenderingShapes(), [editor]); -+ return /* @__PURE__ */ jsxs(Fragment, { children: [ -+ renderingShapes.map((result) => /* @__PURE__ */ jsx(Shape, { ...result }, result.id + "_shape")), -+ editor.environment.isSafari && /* @__PURE__ */ jsx(ReflowIfNeeded, {}) -+ ] }); -+} -+function HintedShapeIndicator() { -+ const editor = useEditor(); -+ const { ShapeIndicator } = useEditorComponents(); -+ const ids = useValue("hinting shape ids", () => dedupe(editor.getHintingShapeIds()), [editor]); -+ if (!ids.length) return null; -+ if (!ShapeIndicator) return null; -+ return ids.map((id) => /* @__PURE__ */ jsx(ShapeIndicator, { className: "tl-user-indicator__hint", shapeId: id }, id + "_hinting")); -+} -+function CursorDef() { -+ return /* @__PURE__ */ jsxs("g", { id: "cursor", children: [ -+ /* @__PURE__ */ jsxs("g", { fill: "rgba(0,0,0,.2)", transform: "translate(-11,-11)", children: [ -+ /* @__PURE__ */ jsx("path", { d: "m12 24.4219v-16.015l11.591 11.619h-6.781l-.411.124z" }), -+ /* @__PURE__ */ jsx("path", { d: "m21.0845 25.0962-3.605 1.535-4.682-11.089 3.686-1.553z" }) -+ ] }), -+ /* @__PURE__ */ jsxs("g", { fill: "white", transform: "translate(-12,-12)", children: [ -+ /* @__PURE__ */ jsx("path", { d: "m12 24.4219v-16.015l11.591 11.619h-6.781l-.411.124z" }), -+ /* @__PURE__ */ jsx("path", { d: "m21.0845 25.0962-3.605 1.535-4.682-11.089 3.686-1.553z" }) -+ ] }), -+ /* @__PURE__ */ jsxs("g", { fill: "currentColor", transform: "translate(-12,-12)", children: [ -+ /* @__PURE__ */ jsx("path", { d: "m19.751 24.4155-1.844.774-3.1-7.374 1.841-.775z" }), -+ /* @__PURE__ */ jsx("path", { d: "m13 10.814v11.188l2.969-2.866.428-.139h4.768z" }) -+ ] }) -+ ] }); -+} -+function CollaboratorHintDef() { -+ return /* @__PURE__ */ jsx("path", { id: "cursor_hint", fill: "currentColor", d: "M -2,-5 2,0 -2,5 Z" }); -+} -+function DebugSvgCopy({ id, mode }) { -+ const editor = useEditor(); -+ const [image, setImage] = useState(null); -+ const isInRoot = useValue( -+ "is in root", -+ () => { -+ const shape = editor.getShape(id); -+ return shape?.parentId === editor.getCurrentPageId(); -+ }, -+ [editor, id] -+ ); -+ useEffect(() => { -+ if (!isInRoot) return; -+ let latest = null; -+ const unsubscribe = react("shape to svg", async () => { -+ const renderId = Math.random(); -+ latest = renderId; -+ const isSingleFrame = editor.isShapeOfType(id, "frame"); -+ const padding = isSingleFrame ? 0 : 10; -+ let bounds = editor.getShapePageBounds(id); -+ if (!bounds) return; -+ bounds = bounds.clone().expandBy(padding); -+ const result = await editor.getSvgString([id], { -+ padding, -+ background: editor.getInstanceState().exportBackground -+ }); -+ if (latest !== renderId || !result) return; -+ const svgDataUrl = `data:image/svg+xml;utf8,${encodeURIComponent(result.svg)}`; -+ setImage({ src: svgDataUrl, bounds }); -+ }); -+ return () => { -+ latest = null; -+ unsubscribe(); -+ }; -+ }, [editor, id, isInRoot]); -+ if (!isInRoot || !image) return null; -+ if (mode === "iframe") { -+ return /* @__PURE__ */ jsx( -+ "iframe", -+ { -+ src: image.src, -+ width: image.bounds.width, -+ height: image.bounds.height, -+ referrerPolicy: "no-referrer", -+ style: { -+ position: "absolute", -+ top: 0, -+ left: 0, -+ border: "none", -+ transform: `translate(${image.bounds.x}px, ${image.bounds.maxY + 12}px)`, -+ outline: "1px solid black", -+ maxWidth: "none" -+ } -+ } -+ ); -+ } -+ return /* @__PURE__ */ jsx( -+ "img", -+ { -+ src: image.src, -+ width: image.bounds.width, -+ height: image.bounds.height, -+ referrerPolicy: "no-referrer", -+ style: { -+ position: "absolute", -+ top: 0, -+ left: 0, -+ transform: `translate(${image.bounds.x}px, ${image.bounds.maxY + 12}px)`, -+ outline: "1px solid black", -+ maxWidth: "none" -+ } -+ } -+ ); -+} -+function SelectionForegroundWrapper() { -+ const editor = useEditor(); -+ const selectionRotation = useValue("selection rotation", () => editor.getSelectionRotation(), [ -+ editor -+ ]); -+ const selectionBounds = useValue( -+ "selection bounds", -+ () => editor.getSelectionRotatedPageBounds(), -+ [editor] -+ ); -+ const { SelectionForeground } = useEditorComponents(); -+ if (!selectionBounds || !SelectionForeground) return null; -+ return /* @__PURE__ */ jsx(SelectionForeground, { bounds: selectionBounds, rotation: selectionRotation }); -+} -+function SelectionBackgroundWrapper() { -+ const editor = useEditor(); -+ const selectionRotation = useValue("selection rotation", () => editor.getSelectionRotation(), [ -+ editor -+ ]); -+ const selectionBounds = useValue( -+ "selection bounds", -+ () => editor.getSelectionRotatedPageBounds(), -+ [editor] -+ ); -+ const { SelectionBackground } = useEditorComponents(); -+ if (!selectionBounds || !SelectionBackground) return null; -+ return /* @__PURE__ */ jsx(SelectionBackground, { bounds: selectionBounds, rotation: selectionRotation }); -+} -+function OnTheCanvasWrapper() { -+ const { OnTheCanvas } = useEditorComponents(); -+ if (!OnTheCanvas) return null; -+ return /* @__PURE__ */ jsx(OnTheCanvas, {}); -+} -+function MovingCameraHitTestBlocker() { -+ const editor = useEditor(); -+ const cameraState = useValue("camera state", () => editor.getCameraState(), [editor]); -+ return /* @__PURE__ */ jsx( -+ "div", -+ { -+ className: classNames("tl-hit-test-blocker", { -+ "tl-hit-test-blocker__hidden": cameraState === "idle" -+ }) -+ } -+ ); -+} -+export { -+ DefaultCanvas -+}; -+//# sourceMappingURL=DefaultCanvas.mjs.map -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/components/default-components/DefaultCanvas.mjs.map b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/components/default-components/DefaultCanvas.mjs.map -new file mode 100644 -index 0000000..2e6080b ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/components/default-components/DefaultCanvas.mjs.map -@@ -0,0 +1,7 @@ -+{ -+ "version": 3, -+ "sources": ["../../../../src/lib/components/default-components/DefaultCanvas.tsx"], -+ "sourcesContent": ["import { react } from '@tldraw/state'\nimport { useQuickReactor, useValue } from '@tldraw/state-react'\nimport { TLHandle, TLShapeId } from '@tldraw/tlschema'\nimport { dedupe, modulate, objectMapValues } from '@tldraw/utils'\nimport classNames from 'classnames'\nimport { Fragment, JSX, useEffect, useRef, useState } from 'react'\nimport { useCanvasEvents } from '../../hooks/useCanvasEvents'\nimport { useCoarsePointer } from '../../hooks/useCoarsePointer'\nimport { useContainer } from '../../hooks/useContainer'\nimport { useDocumentEvents } from '../../hooks/useDocumentEvents'\nimport { useEditor } from '../../hooks/useEditor'\nimport { useEditorComponents } from '../../hooks/useEditorComponents'\nimport { useFixSafariDoubleTapZoomPencilEvents } from '../../hooks/useFixSafariDoubleTapZoomPencilEvents'\nimport { useGestureEvents } from '../../hooks/useGestureEvents'\nimport { useHandleEvents } from '../../hooks/useHandleEvents'\nimport { useScreenBounds } from '../../hooks/useScreenBounds'\nimport { Box } from '../../primitives/Box'\nimport { Mat } from '../../primitives/Mat'\nimport { Vec } from '../../primitives/Vec'\nimport { toDomPrecision } from '../../primitives/utils'\nimport { debugFlags } from '../../utils/debug-flags'\nimport { setStyleProperty } from '../../utils/dom'\nimport { GeometryDebuggingView } from '../GeometryDebuggingView'\nimport { LiveCollaborators } from '../LiveCollaborators'\nimport { Shape } from '../Shape'\n\n/** @public */\nexport interface TLCanvasComponentProps {\n\tclassName?: string\n}\n\n/** @public @react */\nexport function DefaultCanvas({ className }: TLCanvasComponentProps) {\n\tconst editor = useEditor()\n\n\tconst { Background, SvgDefs, ShapeIndicators } = useEditorComponents()\n\n\tconst rCanvas = useRef(null)\n\tconst rHtmlLayer = useRef(null)\n\tconst rHtmlLayer2 = useRef(null)\n\tconst container = useContainer()\n\n\tuseScreenBounds(rCanvas)\n\tuseDocumentEvents()\n\tuseCoarsePointer()\n\n\tuseGestureEvents(rCanvas)\n\tuseFixSafariDoubleTapZoomPencilEvents(rCanvas)\n\n\tconst rMemoizedStuff = useRef({ lodDisableTextOutline: false, allowTextOutline: true })\n\n\tuseQuickReactor(\n\t\t'position layers',\n\t\tfunction positionLayersWhenCameraMoves() {\n\t\t\tconst { x, y, z } = editor.getCamera()\n\n\t\t\t// This should only run once on first load\n\t\t\tif (rMemoizedStuff.current.allowTextOutline && editor.environment.isSafari) {\n\t\t\t\tcontainer.style.setProperty('--tl-text-outline', 'none')\n\t\t\t\trMemoizedStuff.current.allowTextOutline = false\n\t\t\t}\n\n\t\t\t// And this should only run if we're not in Safari;\n\t\t\t// If we're below the lod distance for text shadows, turn them off\n\t\t\tif (\n\t\t\t\trMemoizedStuff.current.allowTextOutline &&\n\t\t\t\tz < editor.options.textShadowLod !== rMemoizedStuff.current.lodDisableTextOutline\n\t\t\t) {\n\t\t\t\tconst lodDisableTextOutline = z < editor.options.textShadowLod\n\t\t\t\tcontainer.style.setProperty(\n\t\t\t\t\t'--tl-text-outline',\n\t\t\t\t\tlodDisableTextOutline ? 'none' : `var(--tl-text-outline-reference)`\n\t\t\t\t)\n\t\t\t\trMemoizedStuff.current.lodDisableTextOutline = lodDisableTextOutline\n\t\t\t}\n\n\t\t\t// Because the html container has a width/height of 1px, we\n\t\t\t// need to create a small offset when zoomed to ensure that\n\t\t\t// the html container and svg container are lined up exactly.\n\t\t\tconst offset =\n\t\t\t\tz >= 1 ? modulate(z, [1, 8], [0.125, 0.5], true) : modulate(z, [0.1, 1], [-2, 0.125], true)\n\n\t\t\tconst transform = `scale(${toDomPrecision(z)}) translate(${toDomPrecision(\n\t\t\t\tx + offset\n\t\t\t)}px,${toDomPrecision(y + offset)}px)`\n\t\t\tsetStyleProperty(rHtmlLayer.current, 'transform', transform)\n\t\t\tsetStyleProperty(rHtmlLayer2.current, 'transform', transform)\n\t\t},\n\t\t[editor, container]\n\t)\n\n\tconst events = useCanvasEvents()\n\n\tconst shapeSvgDefs = useValue(\n\t\t'shapeSvgDefs',\n\t\t() => {\n\t\t\tconst shapeSvgDefsByKey = new Map()\n\t\t\tfor (const util of objectMapValues(editor.shapeUtils)) {\n\t\t\t\tif (!util) return\n\t\t\t\tconst defs = util.getCanvasSvgDefs()\n\t\t\t\tfor (const { key, component: Component } of defs) {\n\t\t\t\t\tif (shapeSvgDefsByKey.has(key)) continue\n\t\t\t\t\tshapeSvgDefsByKey.set(key, )\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn [...shapeSvgDefsByKey.values()]\n\t\t},\n\t\t[editor]\n\t)\n\n\tconst hideShapes = useValue('debug_shapes', () => debugFlags.hideShapes.get(), [debugFlags])\n\tconst debugSvg = useValue('debug_svg', () => debugFlags.debugSvg.get(), [debugFlags])\n\tconst debugGeometry = useValue('debug_geometry', () => debugFlags.debugGeometry.get(), [\n\t\tdebugFlags,\n\t])\n\tconst isEditingAnything = useValue(\n\t\t'isEditingAnything',\n\t\t() => editor.getEditingShapeId() !== null,\n\t\t[editor]\n\t)\n\tconst isSelectingAnything = useValue(\n\t\t'isSelectingAnything',\n\t\t() => !!editor.getSelectedShapeIds().length,\n\t\t[editor]\n\t)\n\n\treturn (\n\t\t<>\n\t\t\t\n\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\t{shapeSvgDefs}\n\t\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t\t{SvgDefs && }\n\t\t\t\t\t\n\t\t\t\t\n\t\t\t\t{Background && (\n\t\t\t\t\t
\n\t\t\t\t\t\t\n\t\t\t\t\t
\n\t\t\t\t)}\n\t\t\t\t\n\t\t\t\t
\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t{hideShapes ? null : debugSvg ? : }\n\t\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t\t\t\t{debugGeometry ? : null}\n\t\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t\t{ShapeIndicators && }\n\t\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t
\n\t\t\t\t
\n\t\t\t\t\n\t\t\t
\n\t\t\t\n\t\t\n\t)\n}\n\nfunction InFrontOfTheCanvasWrapper() {\n\tconst { InFrontOfTheCanvas } = useEditorComponents()\n\tif (!InFrontOfTheCanvas) return null\n\treturn \n}\n\nfunction GridWrapper() {\n\tconst editor = useEditor()\n\tconst gridSize = useValue('gridSize', () => editor.getDocumentSettings().gridSize, [editor])\n\tconst { x, y, z } = useValue('camera', () => editor.getCamera(), [editor])\n\tconst isGridMode = useValue('isGridMode', () => editor.getInstanceState().isGridMode, [editor])\n\tconst { Grid } = useEditorComponents()\n\n\tif (!(Grid && isGridMode)) return null\n\n\treturn \n}\n\nfunction ScribbleWrapper() {\n\tconst editor = useEditor()\n\tconst scribbles = useValue('scribbles', () => editor.getInstanceState().scribbles, [editor])\n\tconst zoomLevel = useValue('zoomLevel', () => editor.getZoomLevel(), [editor])\n\tconst { Scribble } = useEditorComponents()\n\n\tif (!(Scribble && scribbles.length)) return null\n\n\treturn scribbles.map((scribble) => (\n\t\t\n\t))\n}\n\nfunction BrushWrapper() {\n\tconst editor = useEditor()\n\tconst brush = useValue('brush', () => editor.getInstanceState().brush, [editor])\n\tconst { Brush } = useEditorComponents()\n\n\tif (!(Brush && brush)) return null\n\n\treturn \n}\n\nfunction ZoomBrushWrapper() {\n\tconst editor = useEditor()\n\tconst zoomBrush = useValue('zoomBrush', () => editor.getInstanceState().zoomBrush, [editor])\n\tconst { ZoomBrush } = useEditorComponents()\n\n\tif (!(ZoomBrush && zoomBrush)) return null\n\n\treturn \n}\n\nfunction SnapIndicatorWrapper() {\n\tconst editor = useEditor()\n\tconst lines = useValue('snapLines', () => editor.snaps.getIndicators(), [editor])\n\tconst zoomLevel = useValue('zoomLevel', () => editor.getZoomLevel(), [editor])\n\tconst { SnapIndicator } = useEditorComponents()\n\n\tif (!(SnapIndicator && lines.length > 0)) return null\n\n\treturn lines.map((line) => (\n\t\t\n\t))\n}\n\nfunction HandlesWrapper() {\n\tconst editor = useEditor()\n\n\t// We don't want this to update every time the shape changes\n\tconst shapeIdWithHandles = useValue(\n\t\t'handles shapeIdWithHandles',\n\t\t() => {\n\t\t\tconst { isReadonly, isChangingStyle } = editor.getInstanceState()\n\t\t\tif (isReadonly || isChangingStyle) return false\n\n\t\t\tconst onlySelectedShape = editor.getOnlySelectedShape()\n\t\t\tif (!onlySelectedShape) return false\n\n\t\t\t// slightly redundant but saves us from updating the handles every time the shape changes\n\t\t\tconst handles = editor.getShapeHandles(onlySelectedShape)\n\t\t\tif (!handles) return false\n\n\t\t\treturn onlySelectedShape.id\n\t\t},\n\t\t[editor]\n\t)\n\n\tif (!shapeIdWithHandles) return null\n\n\treturn \n}\n\nfunction HandlesWrapperInner({ shapeId }: { shapeId: TLShapeId }) {\n\tconst editor = useEditor()\n\tconst { Handles } = useEditorComponents()\n\n\tconst zoomLevel = useValue('zoomLevel', () => editor.getZoomLevel(), [editor])\n\n\tconst isCoarse = useValue('coarse pointer', () => editor.getInstanceState().isCoarsePointer, [\n\t\teditor,\n\t])\n\n\tconst transform = useValue('handles transform', () => editor.getShapePageTransform(shapeId), [\n\t\teditor,\n\t\tshapeId,\n\t])\n\n\tconst handles = useValue(\n\t\t'handles',\n\t\t() => {\n\t\t\tconst handles = editor.getShapeHandles(shapeId)\n\t\t\tif (!handles) return null\n\n\t\t\tconst minDistBetweenVirtualHandlesAndRegularHandles =\n\t\t\t\t((isCoarse ? editor.options.coarseHandleRadius : editor.options.handleRadius) / zoomLevel) *\n\t\t\t\t2\n\n\t\t\treturn (\n\t\t\t\thandles\n\t\t\t\t\t.filter(\n\t\t\t\t\t\t(handle) =>\n\t\t\t\t\t\t\t// if the handle isn't a virtual handle, we'll display it\n\t\t\t\t\t\t\thandle.type !== 'virtual' ||\n\t\t\t\t\t\t\t// but for virtual handles, we'll only display them if they're far enough away from vertex handles\n\t\t\t\t\t\t\t!handles.some(\n\t\t\t\t\t\t\t\t(h) =>\n\t\t\t\t\t\t\t\t\t// skip the handle we're checking against\n\t\t\t\t\t\t\t\t\th !== handle &&\n\t\t\t\t\t\t\t\t\t// only check against vertex handles\n\t\t\t\t\t\t\t\t\th.type === 'vertex' &&\n\t\t\t\t\t\t\t\t\t// and check that their distance isn't below the minimum distance\n\t\t\t\t\t\t\t\t\tVec.Dist(handle, h) < minDistBetweenVirtualHandlesAndRegularHandles\n\t\t\t\t\t\t\t)\n\t\t\t\t\t)\n\t\t\t\t\t// We want vertex handles in front of all other handles\n\t\t\t\t\t.sort((a) => (a.type === 'vertex' ? 1 : -1))\n\t\t\t)\n\t\t},\n\t\t[editor, zoomLevel, isCoarse, shapeId]\n\t)\n\n\tconst isHidden = useValue('isHidden', () => editor.isShapeHidden(shapeId), [editor, shapeId])\n\n\tif (!Handles || !handles || !transform || isHidden) {\n\t\treturn null\n\t}\n\n\treturn (\n\t\t\n\t\t\t\n\t\t\t\t{handles.map((handle) => {\n\t\t\t\t\treturn (\n\t\t\t\t\t\t\n\t\t\t\t\t)\n\t\t\t\t})}\n\t\t\t\n\t\t\n\t)\n}\n\nfunction HandleWrapper({\n\tshapeId,\n\thandle,\n\tzoom,\n\tisCoarse,\n}: {\n\tshapeId: TLShapeId\n\thandle: TLHandle\n\tzoom: number\n\tisCoarse: boolean\n}) {\n\tconst events = useHandleEvents(shapeId, handle.id)\n\tconst { Handle } = useEditorComponents()\n\n\tif (!Handle) return null\n\n\treturn (\n\t\t\n\t\t\t\n\t\t\n\t)\n}\n\nfunction ShapesWithSVGs() {\n\tconst editor = useEditor()\n\n\tconst renderingShapes = useValue('rendering shapes', () => editor.getRenderingShapes(), [editor])\n\n\treturn renderingShapes.map((result) => (\n\t\t\n\t\t\t\n\t\t\t\n\t\t\n\t))\n}\nfunction ReflowIfNeeded() {\n\tconst editor = useEditor()\n\tconst culledShapesRef = useRef>(new Set())\n\tuseQuickReactor(\n\t\t'reflow for culled shapes',\n\t\t() => {\n\t\t\tconst culledShapes = editor.getCulledShapes()\n\t\t\tif (\n\t\t\t\tculledShapesRef.current.size === culledShapes.size &&\n\t\t\t\t[...culledShapes].every((id) => culledShapesRef.current.has(id))\n\t\t\t)\n\t\t\t\treturn\n\n\t\t\tculledShapesRef.current = culledShapes\n\t\t\tconst canvas = document.getElementsByClassName('tl-canvas')\n\t\t\tif (canvas.length === 0) return\n\t\t\t// This causes a reflow\n\t\t\t// https://gist.github.com/paulirish/5d52fb081b3570c81e3a\n\t\t\tconst _height = (canvas[0] as HTMLDivElement).offsetHeight\n\t\t},\n\t\t[editor]\n\t)\n\treturn null\n}\n\nfunction ShapesToDisplay() {\n\tconst editor = useEditor()\n\n\tconst renderingShapes = useValue('rendering shapes', () => editor.getRenderingShapes(), [editor])\n\n\treturn (\n\t\t<>\n\t\t\t{renderingShapes.map((result) => (\n\t\t\t\t\n\t\t\t))}\n\t\t\t{editor.environment.isSafari && }\n\t\t\n\t)\n}\n\nfunction HintedShapeIndicator() {\n\tconst editor = useEditor()\n\tconst { ShapeIndicator } = useEditorComponents()\n\n\tconst ids = useValue('hinting shape ids', () => dedupe(editor.getHintingShapeIds()), [editor])\n\n\tif (!ids.length) return null\n\tif (!ShapeIndicator) return null\n\n\treturn ids.map((id) => (\n\t\t\n\t))\n}\n\nfunction CursorDef() {\n\treturn (\n\t\t\n\t\t\t\n\t\t\t\t\n\t\t\t\t\n\t\t\t\n\t\t\t\n\t\t\t\t\n\t\t\t\t\n\t\t\t\n\t\t\t\n\t\t\t\t\n\t\t\t\t\n\t\t\t\n\t\t\n\t)\n}\n\nfunction CollaboratorHintDef() {\n\treturn \n}\n\nfunction DebugSvgCopy({ id, mode }: { id: TLShapeId; mode: 'img' | 'iframe' }) {\n\tconst editor = useEditor()\n\n\tconst [image, setImage] = useState<{ src: string; bounds: Box } | null>(null)\n\n\tconst isInRoot = useValue(\n\t\t'is in root',\n\t\t() => {\n\t\t\tconst shape = editor.getShape(id)\n\t\t\treturn shape?.parentId === editor.getCurrentPageId()\n\t\t},\n\t\t[editor, id]\n\t)\n\n\tuseEffect(() => {\n\t\tif (!isInRoot) return\n\n\t\tlet latest = null\n\t\tconst unsubscribe = react('shape to svg', async () => {\n\t\t\tconst renderId = Math.random()\n\t\t\tlatest = renderId\n\n\t\t\tconst isSingleFrame = editor.isShapeOfType(id, 'frame')\n\t\t\tconst padding = isSingleFrame ? 0 : 10\n\t\t\tlet bounds = editor.getShapePageBounds(id)\n\t\t\tif (!bounds) return\n\t\t\tbounds = bounds.clone().expandBy(padding)\n\n\t\t\tconst result = await editor.getSvgString([id], {\n\t\t\t\tpadding,\n\t\t\t\tbackground: editor.getInstanceState().exportBackground,\n\t\t\t})\n\n\t\t\tif (latest !== renderId || !result) return\n\n\t\t\tconst svgDataUrl = `data:image/svg+xml;utf8,${encodeURIComponent(result.svg)}`\n\t\t\tsetImage({ src: svgDataUrl, bounds })\n\t\t})\n\n\t\treturn () => {\n\t\t\tlatest = null\n\t\t\tunsubscribe()\n\t\t}\n\t}, [editor, id, isInRoot])\n\n\tif (!isInRoot || !image) return null\n\n\tif (mode === 'iframe') {\n\t\treturn (\n\t\t\t\n\t\t)\n\t}\n\treturn (\n\t\t\n\t)\n}\n\nfunction SelectionForegroundWrapper() {\n\tconst editor = useEditor()\n\tconst selectionRotation = useValue('selection rotation', () => editor.getSelectionRotation(), [\n\t\teditor,\n\t])\n\tconst selectionBounds = useValue(\n\t\t'selection bounds',\n\t\t() => editor.getSelectionRotatedPageBounds(),\n\t\t[editor]\n\t)\n\tconst { SelectionForeground } = useEditorComponents()\n\tif (!selectionBounds || !SelectionForeground) return null\n\treturn \n}\n\nfunction SelectionBackgroundWrapper() {\n\tconst editor = useEditor()\n\tconst selectionRotation = useValue('selection rotation', () => editor.getSelectionRotation(), [\n\t\teditor,\n\t])\n\tconst selectionBounds = useValue(\n\t\t'selection bounds',\n\t\t() => editor.getSelectionRotatedPageBounds(),\n\t\t[editor]\n\t)\n\tconst { SelectionBackground } = useEditorComponents()\n\tif (!selectionBounds || !SelectionBackground) return null\n\treturn \n}\n\nfunction OnTheCanvasWrapper() {\n\tconst { OnTheCanvas } = useEditorComponents()\n\tif (!OnTheCanvas) return null\n\treturn \n}\n\nfunction MovingCameraHitTestBlocker() {\n\tconst editor = useEditor()\n\tconst cameraState = useValue('camera state', () => editor.getCameraState(), [editor])\n\n\treturn (\n\t\t\n\t)\n}\n"], -+ "mappings": "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", -+ "names": ["Fragment", "handles"] -+} -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/components/default-components/DefaultCollaboratorHint.mjs b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/components/default-components/DefaultCollaboratorHint.mjs -new file mode 100644 -index 0000000..67df30d ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/components/default-components/DefaultCollaboratorHint.mjs -@@ -0,0 +1,31 @@ -+import { jsx, jsxs } from "react/jsx-runtime"; -+import classNames from "classnames"; -+import { useRef } from "react"; -+import { useTransform } from "../../hooks/useTransform.mjs"; -+import { Vec } from "../../primitives/Vec.mjs"; -+import { clamp } from "../../primitives/utils.mjs"; -+function DefaultCollaboratorHint({ -+ className, -+ zoom, -+ point, -+ color, -+ viewport, -+ opacity = 1 -+}) { -+ const rSvg = useRef(null); -+ useTransform( -+ rSvg, -+ clamp(point.x, viewport.minX + 5 / zoom, viewport.maxX - 5 / zoom), -+ clamp(point.y, viewport.minY + 5 / zoom, viewport.maxY - 5 / zoom), -+ 1 / zoom, -+ Vec.Angle(viewport.center, point) -+ ); -+ return /* @__PURE__ */ jsxs("svg", { ref: rSvg, className: classNames("tl-overlays__item", className), children: [ -+ /* @__PURE__ */ jsx("use", { href: "#cursor_hint", color, strokeWidth: 3, stroke: "var(--color-background)" }), -+ /* @__PURE__ */ jsx("use", { href: "#cursor_hint", color, opacity }) -+ ] }); -+} -+export { -+ DefaultCollaboratorHint -+}; -+//# sourceMappingURL=DefaultCollaboratorHint.mjs.map -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/components/default-components/DefaultCollaboratorHint.mjs.map b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/components/default-components/DefaultCollaboratorHint.mjs.map -new file mode 100644 -index 0000000..4bdae74 ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/components/default-components/DefaultCollaboratorHint.mjs.map -@@ -0,0 +1,7 @@ -+{ -+ "version": 3, -+ "sources": ["../../../../src/lib/components/default-components/DefaultCollaboratorHint.tsx"], -+ "sourcesContent": ["import { VecModel } from '@tldraw/tlschema'\nimport classNames from 'classnames'\nimport { useRef } from 'react'\nimport { useTransform } from '../../hooks/useTransform'\nimport { Box } from '../../primitives/Box'\nimport { Vec } from '../../primitives/Vec'\nimport { clamp } from '../../primitives/utils'\n\n/** @public */\nexport interface TLCollaboratorHintProps {\n\tclassName?: string\n\tpoint: VecModel\n\tviewport: Box\n\tzoom: number\n\topacity?: number\n\tcolor: string\n}\n\n/** @public @react */\nexport function DefaultCollaboratorHint({\n\tclassName,\n\tzoom,\n\tpoint,\n\tcolor,\n\tviewport,\n\topacity = 1,\n}: TLCollaboratorHintProps) {\n\tconst rSvg = useRef(null)\n\n\tuseTransform(\n\t\trSvg,\n\t\tclamp(point.x, viewport.minX + 5 / zoom, viewport.maxX - 5 / zoom),\n\t\tclamp(point.y, viewport.minY + 5 / zoom, viewport.maxY - 5 / zoom),\n\t\t1 / zoom,\n\t\tVec.Angle(viewport.center, point)\n\t)\n\n\treturn (\n\t\t\n\t\t\t\n\t\t\t\n\t\t\n\t)\n}\n"], -+ "mappings": "AAsCE,SACC,KADD;AArCF,OAAO,gBAAgB;AACvB,SAAS,cAAc;AACvB,SAAS,oBAAoB;AAE7B,SAAS,WAAW;AACpB,SAAS,aAAa;AAaf,SAAS,wBAAwB;AAAA,EACvC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,UAAU;AACX,GAA4B;AAC3B,QAAM,OAAO,OAAsB,IAAI;AAEvC;AAAA,IACC;AAAA,IACA,MAAM,MAAM,GAAG,SAAS,OAAO,IAAI,MAAM,SAAS,OAAO,IAAI,IAAI;AAAA,IACjE,MAAM,MAAM,GAAG,SAAS,OAAO,IAAI,MAAM,SAAS,OAAO,IAAI,IAAI;AAAA,IACjE,IAAI;AAAA,IACJ,IAAI,MAAM,SAAS,QAAQ,KAAK;AAAA,EACjC;AAEA,SACC,qBAAC,SAAI,KAAK,MAAM,WAAW,WAAW,qBAAqB,SAAS,GACnE;AAAA,wBAAC,SAAI,MAAK,gBAAe,OAAc,aAAa,GAAG,QAAO,2BAA0B;AAAA,IACxF,oBAAC,SAAI,MAAK,gBAAe,OAAc,SAAkB;AAAA,KAC1D;AAEF;", -+ "names": [] -+} -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/components/default-components/DefaultCursor.mjs b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/components/default-components/DefaultCursor.mjs -new file mode 100644 -index 0000000..80d2674 ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/components/default-components/DefaultCursor.mjs -@@ -0,0 +1,27 @@ -+import { Fragment, jsx, jsxs } from "react/jsx-runtime"; -+import classNames from "classnames"; -+import { memo, useRef } from "react"; -+import { useTransform } from "../../hooks/useTransform.mjs"; -+const DefaultCursor = memo(function DefaultCursor2({ -+ className, -+ zoom, -+ point, -+ color, -+ name, -+ chatMessage -+}) { -+ const rCursor = useRef(null); -+ useTransform(rCursor, point?.x, point?.y, 1 / zoom); -+ if (!point) return null; -+ return /* @__PURE__ */ jsxs("div", { ref: rCursor, className: classNames("tl-overlays__item", className), children: [ -+ /* @__PURE__ */ jsx("svg", { className: "tl-cursor", children: /* @__PURE__ */ jsx("use", { href: "#cursor", color }) }), -+ chatMessage ? /* @__PURE__ */ jsxs(Fragment, { children: [ -+ name && /* @__PURE__ */ jsx("div", { className: "tl-nametag-title", style: { color }, children: name }), -+ /* @__PURE__ */ jsx("div", { className: "tl-nametag-chat", style: { backgroundColor: color }, children: chatMessage }) -+ ] }) : name && /* @__PURE__ */ jsx("div", { className: "tl-nametag", style: { backgroundColor: color }, children: name }) -+ ] }); -+}); -+export { -+ DefaultCursor -+}; -+//# sourceMappingURL=DefaultCursor.mjs.map -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/components/default-components/DefaultCursor.mjs.map b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/components/default-components/DefaultCursor.mjs.map -new file mode 100644 -index 0000000..ccfe601 ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/components/default-components/DefaultCursor.mjs.map -@@ -0,0 +1,7 @@ -+{ -+ "version": 3, -+ "sources": ["../../../../src/lib/components/default-components/DefaultCursor.tsx"], -+ "sourcesContent": ["import { VecModel } from '@tldraw/tlschema'\nimport classNames from 'classnames'\nimport { memo, useRef } from 'react'\nimport { useTransform } from '../../hooks/useTransform'\n\n/** @public */\nexport interface TLCursorProps {\n\tclassName?: string\n\tpoint: VecModel | null\n\tzoom: number\n\tcolor?: string\n\tname: string | null\n\tchatMessage: string\n}\n\n/** @public @react */\nexport const DefaultCursor = memo(function DefaultCursor({\n\tclassName,\n\tzoom,\n\tpoint,\n\tcolor,\n\tname,\n\tchatMessage,\n}: TLCursorProps) {\n\tconst rCursor = useRef(null)\n\tuseTransform(rCursor, point?.x, point?.y, 1 / zoom)\n\n\tif (!point) return null\n\n\treturn (\n\t\t
\n\t\t\t\n\t\t\t\t\n\t\t\t\n\t\t\t{chatMessage ? (\n\t\t\t\t<>\n\t\t\t\t\t{name && (\n\t\t\t\t\t\t
\n\t\t\t\t\t\t\t{name}\n\t\t\t\t\t\t
\n\t\t\t\t\t)}\n\t\t\t\t\t
\n\t\t\t\t\t\t{chatMessage}\n\t\t\t\t\t
\n\t\t\t\t\n\t\t\t) : (\n\t\t\t\tname && (\n\t\t\t\t\t
\n\t\t\t\t\t\t{name}\n\t\t\t\t\t
\n\t\t\t\t)\n\t\t\t)}\n\t\t
\n\t)\n})\n"], -+ "mappings": "AAgCI,SAGA,UAHA,KAGA,YAHA;AA/BJ,OAAO,gBAAgB;AACvB,SAAS,MAAM,cAAc;AAC7B,SAAS,oBAAoB;AAatB,MAAM,gBAAgB,KAAK,SAASA,eAAc;AAAA,EACxD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACD,GAAkB;AACjB,QAAM,UAAU,OAAuB,IAAI;AAC3C,eAAa,SAAS,OAAO,GAAG,OAAO,GAAG,IAAI,IAAI;AAElD,MAAI,CAAC,MAAO,QAAO;AAEnB,SACC,qBAAC,SAAI,KAAK,SAAS,WAAW,WAAW,qBAAqB,SAAS,GACtE;AAAA,wBAAC,SAAI,WAAU,aACd,8BAAC,SAAI,MAAK,WAAU,OAAc,GACnC;AAAA,IACC,cACA,iCACE;AAAA,cACA,oBAAC,SAAI,WAAU,oBAAmB,OAAO,EAAE,MAAM,GAC/C,gBACF;AAAA,MAED,oBAAC,SAAI,WAAU,mBAAkB,OAAO,EAAE,iBAAiB,MAAM,GAC/D,uBACF;AAAA,OACD,IAEA,QACC,oBAAC,SAAI,WAAU,cAAa,OAAO,EAAE,iBAAiB,MAAM,GAC1D,gBACF;AAAA,KAGH;AAEF,CAAC;", -+ "names": ["DefaultCursor"] -+} -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/components/default-components/DefaultErrorFallback.mjs b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/components/default-components/DefaultErrorFallback.mjs -new file mode 100644 -index 0000000..928288b ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/components/default-components/DefaultErrorFallback.mjs -@@ -0,0 +1,172 @@ -+import { Fragment, jsx, jsxs } from "react/jsx-runtime"; -+import { useValue } from "@tldraw/state-react"; -+import { noop } from "@tldraw/utils"; -+import classNames from "classnames"; -+import { useEffect, useLayoutEffect, useRef, useState } from "react"; -+import { EditorContext } from "../../hooks/useEditor.mjs"; -+import { useEditorComponents } from "../../hooks/useEditorComponents.mjs"; -+import { hardResetEditor } from "../../utils/hardResetEditor.mjs"; -+import { refreshPage } from "../../utils/refreshPage.mjs"; -+import { ErrorBoundary } from "../ErrorBoundary.mjs"; -+const BASE_ERROR_URL = "https://github.com/tldraw/tldraw/issues/new"; -+const DefaultErrorFallback = ({ error, editor }) => { -+ const containerRef = useRef(null); -+ const [shouldShowError, setShouldShowError] = useState(process.env.NODE_ENV === "development"); -+ const [didCopy, setDidCopy] = useState(false); -+ const [shouldShowResetConfirmation, setShouldShowResetConfirmation] = useState(false); -+ let Canvas = null; -+ try { -+ const components = useEditorComponents(); -+ Canvas = components.Canvas ?? null; -+ } catch (e) { -+ } -+ const errorMessage = error instanceof Error ? error.message : String(error); -+ const errorStack = error instanceof Error ? error.stack : null; -+ const isDarkModeFromApp = useValue( -+ "isDarkMode", -+ () => { -+ try { -+ if (editor) { -+ return editor.user.getIsDarkMode(); -+ } -+ } catch { -+ } -+ return null; -+ }, -+ [editor] -+ ); -+ const [isDarkMode, setIsDarkMode] = useState(null); -+ useLayoutEffect(() => { -+ if (isDarkModeFromApp !== null) { -+ setIsDarkMode(isDarkModeFromApp); -+ } -+ let parent = containerRef.current?.parentElement; -+ let foundParentThemeClass = false; -+ while (parent) { -+ if (parent.classList.contains("tl-theme__dark") || parent.classList.contains("tl-theme__light")) { -+ foundParentThemeClass = true; -+ break; -+ } -+ parent = parent.parentElement; -+ } -+ if (foundParentThemeClass) { -+ setIsDarkMode(null); -+ return; -+ } -+ if (typeof window !== "undefined" && "matchMedia" in window) { -+ setIsDarkMode(window.matchMedia("(prefers-color-scheme: dark)").matches); -+ } -+ }, [isDarkModeFromApp]); -+ useEffect(() => { -+ if (didCopy) { -+ const timeout = editor?.timers.setTimeout(() => { -+ setDidCopy(false); -+ }, 2e3); -+ return () => clearTimeout(timeout); -+ } -+ }, [didCopy, editor]); -+ const copyError = () => { -+ const textarea = document.createElement("textarea"); -+ textarea.value = errorStack ?? errorMessage; -+ document.body.appendChild(textarea); -+ textarea.select(); -+ document.execCommand("copy"); -+ textarea.remove(); -+ setDidCopy(true); -+ }; -+ const refresh = () => { -+ refreshPage(); -+ }; -+ const resetLocalState = async () => { -+ hardResetEditor(); -+ }; -+ const url = new URL(BASE_ERROR_URL); -+ url.searchParams.set("title", errorMessage); -+ url.searchParams.set("labels", `bug`); -+ url.searchParams.set( -+ "body", -+ `Hey, I ran into an error while using tldraw: -+ -+\`\`\`js -+${errorStack ?? errorMessage} -+\`\`\` -+ -+My browser: ${navigator.userAgent}` -+ ); -+ return /* @__PURE__ */ jsxs( -+ "div", -+ { -+ ref: containerRef, -+ className: classNames( -+ "tl-container tl-error-boundary", -+ // error-boundary is sometimes used outside of the theme -+ // container, so we need to provide it with a theme for our -+ // styles to work correctly -+ isDarkMode === null ? "" : isDarkMode ? "tl-theme__dark" : "tl-theme__light" -+ ), -+ children: [ -+ /* @__PURE__ */ jsx("div", { className: "tl-error-boundary__overlay" }), -+ editor && // opportunistically attempt to render the canvas to reassure -+ // the user that their document is still there. there's a good -+ // chance this won't work (ie the error that we're currently -+ // notifying the user about originates in the canvas) so it's -+ // not a big deal if it doesn't work - in that case we just have -+ // a plain grey background. -+ /* @__PURE__ */ jsx(ErrorBoundary, { onError: noop, fallback: () => null, children: /* @__PURE__ */ jsx(EditorContext.Provider, { value: editor, children: /* @__PURE__ */ jsx("div", { className: "tl-overlay tl-error-boundary__canvas", children: Canvas ? /* @__PURE__ */ jsx(Canvas, {}) : null }) }) }), -+ /* @__PURE__ */ jsx( -+ "div", -+ { -+ className: classNames("tl-modal", "tl-error-boundary__content", { -+ "tl-error-boundary__content__expanded": shouldShowError && !shouldShowResetConfirmation -+ }), -+ children: shouldShowResetConfirmation ? /* @__PURE__ */ jsxs(Fragment, { children: [ -+ /* @__PURE__ */ jsx("h2", { children: "Are you sure?" }), -+ /* @__PURE__ */ jsx("p", { children: "Resetting your data will delete your drawing and cannot be undone." }), -+ /* @__PURE__ */ jsxs("div", { className: "tl-error-boundary__content__actions", children: [ -+ /* @__PURE__ */ jsx("button", { onClick: () => setShouldShowResetConfirmation(false), children: "Cancel" }), -+ /* @__PURE__ */ jsx("button", { className: "tl-error-boundary__reset", onClick: resetLocalState, children: "Reset data" }) -+ ] }) -+ ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [ -+ /* @__PURE__ */ jsx("h2", { children: "Something's gone wrong." }), -+ /* @__PURE__ */ jsxs("p", { children: [ -+ "Sorry, we encountered an error. Please refresh the page to continue. If you keep seeing this error, you can ", -+ /* @__PURE__ */ jsx("a", { href: url.toString(), children: "create a GitHub issue" }), -+ " or", -+ " ", -+ /* @__PURE__ */ jsx("a", { href: "https://discord.gg/Cq6cPsTfNy", children: "ask for help on Discord" }), -+ "." -+ ] }), -+ shouldShowError && /* @__PURE__ */ jsxs(Fragment, { children: [ -+ "Message:", -+ /* @__PURE__ */ jsx("h4", { children: /* @__PURE__ */ jsx("code", { children: errorMessage }) }), -+ "Stack trace:", -+ /* @__PURE__ */ jsxs("div", { className: "tl-error-boundary__content__error", children: [ -+ /* @__PURE__ */ jsx("pre", { children: /* @__PURE__ */ jsx("code", { children: errorStack ?? errorMessage }) }), -+ /* @__PURE__ */ jsx("button", { onClick: copyError, children: didCopy ? "Copied!" : "Copy" }) -+ ] }) -+ ] }), -+ /* @__PURE__ */ jsxs("div", { className: "tl-error-boundary__content__actions", children: [ -+ /* @__PURE__ */ jsx("button", { onClick: () => setShouldShowError(!shouldShowError), children: shouldShowError ? "Hide details" : "Show details" }), -+ /* @__PURE__ */ jsxs("div", { className: "tl-error-boundary__content__actions__group", children: [ -+ /* @__PURE__ */ jsx( -+ "button", -+ { -+ className: "tl-error-boundary__reset", -+ onClick: () => setShouldShowResetConfirmation(true), -+ children: "Reset data" -+ } -+ ), -+ /* @__PURE__ */ jsx("button", { className: "tl-error-boundary__refresh", onClick: refresh, children: "Refresh Page" }) -+ ] }) -+ ] }) -+ ] }) -+ } -+ ) -+ ] -+ } -+ ); -+}; -+export { -+ DefaultErrorFallback -+}; -+//# sourceMappingURL=DefaultErrorFallback.mjs.map -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/components/default-components/DefaultErrorFallback.mjs.map b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/components/default-components/DefaultErrorFallback.mjs.map -new file mode 100644 -index 0000000..c4003b8 ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/components/default-components/DefaultErrorFallback.mjs.map -@@ -0,0 +1,7 @@ -+{ -+ "version": 3, -+ "sources": ["../../../../src/lib/components/default-components/DefaultErrorFallback.tsx"], -+ "sourcesContent": ["import { useValue } from '@tldraw/state-react'\nimport { noop } from '@tldraw/utils'\nimport classNames from 'classnames'\nimport { ComponentType, useEffect, useLayoutEffect, useRef, useState } from 'react'\nimport { Editor } from '../../editor/Editor'\nimport { EditorContext } from '../../hooks/useEditor'\nimport { useEditorComponents } from '../../hooks/useEditorComponents'\nimport { hardResetEditor } from '../../utils/hardResetEditor'\nimport { refreshPage } from '../../utils/refreshPage'\nimport { ErrorBoundary } from '../ErrorBoundary'\n\nconst BASE_ERROR_URL = 'https://github.com/tldraw/tldraw/issues/new'\n\n/** @public */\nexport type TLErrorFallbackComponent = ComponentType<{ error: unknown; editor?: Editor }>\n\n/** @public @react */\nexport const DefaultErrorFallback: TLErrorFallbackComponent = ({ error, editor }) => {\n\tconst containerRef = useRef(null)\n\tconst [shouldShowError, setShouldShowError] = useState(process.env.NODE_ENV === 'development')\n\tconst [didCopy, setDidCopy] = useState(false)\n\tconst [shouldShowResetConfirmation, setShouldShowResetConfirmation] = useState(false)\n\n\tlet Canvas: React.ComponentType | null = null\n\ttry {\n\t\tconst components = useEditorComponents()\n\t\tCanvas = components.Canvas ?? null\n\t} catch (e) {\n\t\t// allow this to fail silently\n\t}\n\n\tconst errorMessage = error instanceof Error ? error.message : String(error)\n\tconst errorStack = error instanceof Error ? error.stack : null\n\n\tconst isDarkModeFromApp = useValue(\n\t\t'isDarkMode',\n\t\t() => {\n\t\t\ttry {\n\t\t\t\tif (editor) {\n\t\t\t\t\treturn editor.user.getIsDarkMode()\n\t\t\t\t}\n\t\t\t} catch {\n\t\t\t\t// we're in a funky error state so this might not work for spooky\n\t\t\t\t// reasons. if not, we'll have another attempt later:\n\t\t\t}\n\t\t\treturn null\n\t\t},\n\t\t[editor]\n\t)\n\tconst [isDarkMode, setIsDarkMode] = useState(null)\n\tuseLayoutEffect(() => {\n\t\t// if we found a theme class from the app, we can just use that\n\t\tif (isDarkModeFromApp !== null) {\n\t\t\tsetIsDarkMode(isDarkModeFromApp)\n\t\t}\n\n\t\t// do any of our parents have a theme class? if yes then we can just\n\t\t// rely on that and don't need to set our own class\n\t\tlet parent = containerRef.current?.parentElement\n\t\tlet foundParentThemeClass = false\n\t\twhile (parent) {\n\t\t\tif (\n\t\t\t\tparent.classList.contains('tl-theme__dark') ||\n\t\t\t\tparent.classList.contains('tl-theme__light')\n\t\t\t) {\n\t\t\t\tfoundParentThemeClass = true\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tparent = parent.parentElement\n\t\t}\n\t\tif (foundParentThemeClass) {\n\t\t\tsetIsDarkMode(null)\n\t\t\treturn\n\t\t}\n\n\t\t// if we can't find a theme class from the app or from a parent, we have\n\t\t// to fall back on using a media query:\n\t\tif (typeof window !== 'undefined' && 'matchMedia' in window) {\n\t\t\tsetIsDarkMode(window.matchMedia('(prefers-color-scheme: dark)').matches)\n\t\t}\n\t}, [isDarkModeFromApp])\n\n\tuseEffect(() => {\n\t\tif (didCopy) {\n\t\t\tconst timeout = editor?.timers.setTimeout(() => {\n\t\t\t\tsetDidCopy(false)\n\t\t\t}, 2000)\n\t\t\treturn () => clearTimeout(timeout)\n\t\t}\n\t}, [didCopy, editor])\n\n\tconst copyError = () => {\n\t\tconst textarea = document.createElement('textarea')\n\t\ttextarea.value = errorStack ?? errorMessage\n\t\tdocument.body.appendChild(textarea)\n\t\ttextarea.select()\n\t\t// eslint-disable-next-line deprecation/deprecation\n\t\tdocument.execCommand('copy')\n\t\ttextarea.remove()\n\t\tsetDidCopy(true)\n\t}\n\n\tconst refresh = () => {\n\t\trefreshPage()\n\t}\n\n\tconst resetLocalState = async () => {\n\t\thardResetEditor()\n\t}\n\n\tconst url = new URL(BASE_ERROR_URL)\n\turl.searchParams.set('title', errorMessage)\n\turl.searchParams.set('labels', `bug`)\n\turl.searchParams.set(\n\t\t'body',\n\t\t`Hey, I ran into an error while using tldraw:\n\n\\`\\`\\`js\n${errorStack ?? errorMessage}\n\\`\\`\\`\n\nMy browser: ${navigator.userAgent}`\n\t)\n\n\treturn (\n\t\t\n\t\t\t
\n\t\t\t{editor && (\n\t\t\t\t// opportunistically attempt to render the canvas to reassure\n\t\t\t\t// the user that their document is still there. there's a good\n\t\t\t\t// chance this won't work (ie the error that we're currently\n\t\t\t\t// notifying the user about originates in the canvas) so it's\n\t\t\t\t// not a big deal if it doesn't work - in that case we just have\n\t\t\t\t// a plain grey background.\n\t\t\t\t null}>\n\t\t\t\t\t\n\t\t\t\t\t\t
{Canvas ? : null}
\n\t\t\t\t\t
\n\t\t\t\t
\n\t\t\t)}\n\t\t\t\n\t\t\t\t{shouldShowResetConfirmation ? (\n\t\t\t\t\t<>\n\t\t\t\t\t\t

Are you sure?

\n\t\t\t\t\t\t

Resetting your data will delete your drawing and cannot be undone.

\n\t\t\t\t\t\t
\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t
\n\t\t\t\t\t\n\t\t\t\t) : (\n\t\t\t\t\t<>\n\t\t\t\t\t\t

Something's gone wrong.

\n\t\t\t\t\t\t

\n\t\t\t\t\t\t\tSorry, we encountered an error. Please refresh the page to continue. If you keep\n\t\t\t\t\t\t\tseeing this error, you can create a GitHub issue or{' '}\n\t\t\t\t\t\t\task for help on Discord.\n\t\t\t\t\t\t

\n\t\t\t\t\t\t{shouldShowError && (\n\t\t\t\t\t\t\t<>\n\t\t\t\t\t\t\t\tMessage:\n\t\t\t\t\t\t\t\t

\n\t\t\t\t\t\t\t\t\t{errorMessage}\n\t\t\t\t\t\t\t\t

\n\t\t\t\t\t\t\t\tStack trace:\n\t\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t\t\t\t{errorStack ?? errorMessage}\n\t\t\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t)}\n\t\t\t\t\t\t
\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t\t setShouldShowResetConfirmation(true)}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\tReset data\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t
\n\t\t\t\t\t\t
\n\t\t\t\t\t\n\t\t\t\t)}\n\t\t\t
\n\t\t\n\t)\n}\n"], -+ "mappings": "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", -+ "names": [] -+} -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/components/default-components/DefaultGrid.mjs b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/components/default-components/DefaultGrid.mjs -new file mode 100644 -index 0000000..6462898 ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/components/default-components/DefaultGrid.mjs -@@ -0,0 +1,35 @@ -+import { jsx, jsxs } from "react/jsx-runtime"; -+import { modulate } from "@tldraw/utils"; -+import { useEditor } from "../../hooks/useEditor.mjs"; -+import { useSafeId } from "../../hooks/useSafeId.mjs"; -+function DefaultGrid({ x, y, z, size }) { -+ const id = `grid_${useSafeId()}`; -+ const editor = useEditor(); -+ const { gridSteps } = editor.options; -+ return /* @__PURE__ */ jsxs("svg", { className: "tl-grid", version: "1.1", xmlns: "http://www.w3.org/2000/svg", children: [ -+ /* @__PURE__ */ jsx("defs", { children: gridSteps.map(({ min, mid, step }, i) => { -+ const s = step * size * z; -+ const xo = 0.5 + x * z; -+ const yo = 0.5 + y * z; -+ const gxo = xo > 0 ? xo % s : s + xo % s; -+ const gyo = yo > 0 ? yo % s : s + yo % s; -+ const opacity = z < mid ? modulate(z, [min, mid], [0, 1]) : 1; -+ return /* @__PURE__ */ jsx( -+ "pattern", -+ { -+ id: `${id}_${step}`, -+ width: s, -+ height: s, -+ patternUnits: "userSpaceOnUse", -+ children: /* @__PURE__ */ jsx("circle", { className: "tl-grid-dot", cx: gxo, cy: gyo, r: 1, opacity }) -+ }, -+ i -+ ); -+ }) }), -+ gridSteps.map(({ step }, i) => /* @__PURE__ */ jsx("rect", { width: "100%", height: "100%", fill: `url(#${id}_${step})` }, i)) -+ ] }); -+} -+export { -+ DefaultGrid -+}; -+//# sourceMappingURL=DefaultGrid.mjs.map -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/components/default-components/DefaultGrid.mjs.map b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/components/default-components/DefaultGrid.mjs.map -new file mode 100644 -index 0000000..adb20ac ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/components/default-components/DefaultGrid.mjs.map -@@ -0,0 +1,7 @@ -+{ -+ "version": 3, -+ "sources": ["../../../../src/lib/components/default-components/DefaultGrid.tsx"], -+ "sourcesContent": ["import { modulate } from '@tldraw/utils'\nimport { useEditor } from '../../hooks/useEditor'\nimport { useSafeId } from '../../hooks/useSafeId'\n\n/** @public */\nexport interface TLGridProps {\n\tx: number\n\ty: number\n\tz: number\n\tsize: number\n}\n\n/** @public @react */\nexport function DefaultGrid({ x, y, z, size }: TLGridProps) {\n\tconst id = `grid_${useSafeId()}`\n\tconst editor = useEditor()\n\tconst { gridSteps } = editor.options\n\treturn (\n\t\t\n\t\t\t\n\t\t\t\t{gridSteps.map(({ min, mid, step }, i) => {\n\t\t\t\t\tconst s = step * size * z\n\t\t\t\t\tconst xo = 0.5 + x * z\n\t\t\t\t\tconst yo = 0.5 + y * z\n\t\t\t\t\tconst gxo = xo > 0 ? xo % s : s + (xo % s)\n\t\t\t\t\tconst gyo = yo > 0 ? yo % s : s + (yo % s)\n\t\t\t\t\tconst opacity = z < mid ? modulate(z, [min, mid], [0, 1]) : 1\n\n\t\t\t\t\treturn (\n\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t)\n\t\t\t\t})}\n\t\t\t\n\t\t\t{gridSteps.map(({ step }, i) => (\n\t\t\t\t\n\t\t\t))}\n\t\t\n\t)\n}\n"], -+ "mappings": "AAkBE,SAkBK,KAlBL;AAlBF,SAAS,gBAAgB;AACzB,SAAS,iBAAiB;AAC1B,SAAS,iBAAiB;AAWnB,SAAS,YAAY,EAAE,GAAG,GAAG,GAAG,KAAK,GAAgB;AAC3D,QAAM,KAAK,QAAQ,UAAU,CAAC;AAC9B,QAAM,SAAS,UAAU;AACzB,QAAM,EAAE,UAAU,IAAI,OAAO;AAC7B,SACC,qBAAC,SAAI,WAAU,WAAU,SAAQ,OAAM,OAAM,8BAC5C;AAAA,wBAAC,UACC,oBAAU,IAAI,CAAC,EAAE,KAAK,KAAK,KAAK,GAAG,MAAM;AACzC,YAAM,IAAI,OAAO,OAAO;AACxB,YAAM,KAAK,MAAM,IAAI;AACrB,YAAM,KAAK,MAAM,IAAI;AACrB,YAAM,MAAM,KAAK,IAAI,KAAK,IAAI,IAAK,KAAK;AACxC,YAAM,MAAM,KAAK,IAAI,KAAK,IAAI,IAAK,KAAK;AACxC,YAAM,UAAU,IAAI,MAAM,SAAS,GAAG,CAAC,KAAK,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC,IAAI;AAE5D,aACC;AAAA,QAAC;AAAA;AAAA,UAEA,IAAI,GAAG,EAAE,IAAI,IAAI;AAAA,UACjB,OAAO;AAAA,UACP,QAAQ;AAAA,UACR,cAAa;AAAA,UAEb,8BAAC,YAAO,WAAU,eAAc,IAAI,KAAK,IAAI,KAAK,GAAG,GAAG,SAAkB;AAAA;AAAA,QANrE;AAAA,MAON;AAAA,IAEF,CAAC,GACF;AAAA,IACC,UAAU,IAAI,CAAC,EAAE,KAAK,GAAG,MACzB,oBAAC,UAAa,OAAM,QAAO,QAAO,QAAO,MAAM,QAAQ,EAAE,IAAI,IAAI,OAAtD,CAA2D,CACtE;AAAA,KACF;AAEF;", -+ "names": [] -+} -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/components/default-components/DefaultHandle.mjs b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/components/default-components/DefaultHandle.mjs -new file mode 100644 -index 0000000..6d2d379 ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/components/default-components/DefaultHandle.mjs -@@ -0,0 +1,26 @@ -+import { jsx, jsxs } from "react/jsx-runtime"; -+import classNames from "classnames"; -+import { SIDES } from "../../constants.mjs"; -+import { useEditor } from "../../hooks/useEditor.mjs"; -+function DefaultHandle({ handle, isCoarse, className, zoom }) { -+ const editor = useEditor(); -+ const br = (isCoarse ? editor.options.coarseHandleRadius : editor.options.handleRadius) / zoom; -+ if (handle.type === "clone") { -+ const fr2 = 3 / zoom; -+ const path = `M0,${-fr2} A${fr2},${fr2} 0 0,1 0,${fr2}`; -+ const index = SIDES.indexOf(handle.id); -+ return /* @__PURE__ */ jsxs("g", { className: classNames(`tl-handle tl-handle__${handle.type}`, className), children: [ -+ /* @__PURE__ */ jsx("circle", { className: "tl-handle__bg", r: br }), -+ /* @__PURE__ */ jsx("path", { className: "tl-handle__fg", d: path, transform: `rotate(${-90 + 90 * index})` }) -+ ] }); -+ } -+ const fr = (handle.type === "create" && isCoarse ? 3 : 4) / Math.max(zoom, 0.25); -+ return /* @__PURE__ */ jsxs("g", { className: classNames(`tl-handle tl-handle__${handle.type}`, className), children: [ -+ /* @__PURE__ */ jsx("circle", { className: "tl-handle__bg", r: br }), -+ /* @__PURE__ */ jsx("circle", { className: "tl-handle__fg", r: fr }) -+ ] }); -+} -+export { -+ DefaultHandle -+}; -+//# sourceMappingURL=DefaultHandle.mjs.map -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/components/default-components/DefaultHandle.mjs.map b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/components/default-components/DefaultHandle.mjs.map -new file mode 100644 -index 0000000..eac9421 ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/components/default-components/DefaultHandle.mjs.map -@@ -0,0 +1,7 @@ -+{ -+ "version": 3, -+ "sources": ["../../../../src/lib/components/default-components/DefaultHandle.tsx"], -+ "sourcesContent": ["import { TLHandle, TLShapeId } from '@tldraw/tlschema'\nimport classNames from 'classnames'\nimport { SIDES } from '../../constants'\nimport { useEditor } from '../../hooks/useEditor'\n\n/** @public */\nexport interface TLHandleProps {\n\tshapeId: TLShapeId\n\thandle: TLHandle\n\tzoom: number\n\tisCoarse: boolean\n\tclassName?: string\n}\n\n/** @public @react */\nexport function DefaultHandle({ handle, isCoarse, className, zoom }: TLHandleProps) {\n\tconst editor = useEditor()\n\tconst br = (isCoarse ? editor.options.coarseHandleRadius : editor.options.handleRadius) / zoom\n\n\tif (handle.type === 'clone') {\n\t\t// bouba\n\t\tconst fr = 3 / zoom\n\t\tconst path = `M0,${-fr} A${fr},${fr} 0 0,1 0,${fr}`\n\n\t\tconst index = SIDES.indexOf(handle.id as (typeof SIDES)[number])\n\t\treturn (\n\t\t\t\n\t\t\t\t\n\t\t\t\t{/* Half circle */}\n\t\t\t\t\n\t\t\t\n\t\t)\n\t}\n\n\tconst fr = (handle.type === 'create' && isCoarse ? 3 : 4) / Math.max(zoom, 0.25)\n\treturn (\n\t\t\n\t\t\t\n\t\t\t\n\t\t\n\t)\n}\n"], -+ "mappings": "AA0BG,SACC,KADD;AAzBH,OAAO,gBAAgB;AACvB,SAAS,aAAa;AACtB,SAAS,iBAAiB;AAYnB,SAAS,cAAc,EAAE,QAAQ,UAAU,WAAW,KAAK,GAAkB;AACnF,QAAM,SAAS,UAAU;AACzB,QAAM,MAAM,WAAW,OAAO,QAAQ,qBAAqB,OAAO,QAAQ,gBAAgB;AAE1F,MAAI,OAAO,SAAS,SAAS;AAE5B,UAAMA,MAAK,IAAI;AACf,UAAM,OAAO,MAAM,CAACA,GAAE,KAAKA,GAAE,IAAIA,GAAE,YAAYA,GAAE;AAEjD,UAAM,QAAQ,MAAM,QAAQ,OAAO,EAA4B;AAC/D,WACC,qBAAC,OAAE,WAAW,WAAW,wBAAwB,OAAO,IAAI,IAAI,SAAS,GACxE;AAAA,0BAAC,YAAO,WAAU,iBAAgB,GAAG,IAAI;AAAA,MAEzC,oBAAC,UAAK,WAAU,iBAAgB,GAAG,MAAM,WAAW,UAAU,MAAM,KAAK,KAAK,KAAK;AAAA,OACpF;AAAA,EAEF;AAEA,QAAM,MAAM,OAAO,SAAS,YAAY,WAAW,IAAI,KAAK,KAAK,IAAI,MAAM,IAAI;AAC/E,SACC,qBAAC,OAAE,WAAW,WAAW,wBAAwB,OAAO,IAAI,IAAI,SAAS,GACxE;AAAA,wBAAC,YAAO,WAAU,iBAAgB,GAAG,IAAI;AAAA,IACzC,oBAAC,YAAO,WAAU,iBAAgB,GAAG,IAAI;AAAA,KAC1C;AAEF;", -+ "names": ["fr"] -+} -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/components/default-components/DefaultHandles.mjs b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/components/default-components/DefaultHandles.mjs -new file mode 100644 -index 0000000..2b17295 ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/components/default-components/DefaultHandles.mjs -@@ -0,0 +1,8 @@ -+import { jsx } from "react/jsx-runtime"; -+const DefaultHandles = ({ children }) => { -+ return /* @__PURE__ */ jsx("svg", { className: "tl-user-handles tl-overlays__item", children }); -+}; -+export { -+ DefaultHandles -+}; -+//# sourceMappingURL=DefaultHandles.mjs.map -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/components/default-components/DefaultHandles.mjs.map b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/components/default-components/DefaultHandles.mjs.map -new file mode 100644 -index 0000000..cfc9096 ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/components/default-components/DefaultHandles.mjs.map -@@ -0,0 +1,7 @@ -+{ -+ "version": 3, -+ "sources": ["../../../../src/lib/components/default-components/DefaultHandles.tsx"], -+ "sourcesContent": ["import { ReactNode } from 'react'\n\n/** @public */\nexport interface TLHandlesProps {\n\tchildren: ReactNode\n}\n\n/** @public @react */\nexport const DefaultHandles = ({ children }: TLHandlesProps) => {\n\treturn {children}\n}\n"], -+ "mappings": "AASQ;AADD,MAAM,iBAAiB,CAAC,EAAE,SAAS,MAAsB;AAC/D,SAAO,oBAAC,SAAI,WAAU,qCAAqC,UAAS;AACrE;", -+ "names": [] -+} -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/components/default-components/DefaultLoadingScreen.mjs b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/components/default-components/DefaultLoadingScreen.mjs -new file mode 100644 -index 0000000..c2261de ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/components/default-components/DefaultLoadingScreen.mjs -@@ -0,0 +1,11 @@ -+import { jsx } from "react/jsx-runtime"; -+import { LoadingScreen } from "../../TldrawEditor.mjs"; -+import { useEditorComponents } from "../../hooks/useEditorComponents.mjs"; -+const DefaultLoadingScreen = () => { -+ const { Spinner } = useEditorComponents(); -+ return /* @__PURE__ */ jsx(LoadingScreen, { children: Spinner ? /* @__PURE__ */ jsx(Spinner, {}) : null }); -+}; -+export { -+ DefaultLoadingScreen -+}; -+//# sourceMappingURL=DefaultLoadingScreen.mjs.map -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/components/default-components/DefaultLoadingScreen.mjs.map b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/components/default-components/DefaultLoadingScreen.mjs.map -new file mode 100644 -index 0000000..460a1cc ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/components/default-components/DefaultLoadingScreen.mjs.map -@@ -0,0 +1,7 @@ -+{ -+ "version": 3, -+ "sources": ["../../../../src/lib/components/default-components/DefaultLoadingScreen.tsx"], -+ "sourcesContent": ["import { LoadingScreen } from '../../TldrawEditor'\nimport { useEditorComponents } from '../../hooks/useEditorComponents'\n\n/** @public @react */\nexport const DefaultLoadingScreen = () => {\n\tconst { Spinner } = useEditorComponents()\n\treturn {Spinner ? : null}\n}\n"], -+ "mappings": "AAMkC;AANlC,SAAS,qBAAqB;AAC9B,SAAS,2BAA2B;AAG7B,MAAM,uBAAuB,MAAM;AACzC,QAAM,EAAE,QAAQ,IAAI,oBAAoB;AACxC,SAAO,oBAAC,iBAAe,oBAAU,oBAAC,WAAQ,IAAK,MAAK;AACrD;", -+ "names": [] -+} -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/components/default-components/DefaultScribble.mjs b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/components/default-components/DefaultScribble.mjs -new file mode 100644 -index 0000000..6358a39 ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/components/default-components/DefaultScribble.mjs -@@ -0,0 +1,21 @@ -+import { jsx } from "react/jsx-runtime"; -+import classNames from "classnames"; -+import { getSvgPathFromPoints } from "../../utils/getSvgPathFromPoints.mjs"; -+function DefaultScribble({ scribble, zoom, color, opacity, className }) { -+ if (!scribble.points.length) return null; -+ return /* @__PURE__ */ jsx("svg", { className: className ? classNames("tl-overlays__item", className) : className, children: /* @__PURE__ */ jsx( -+ "path", -+ { -+ className: "tl-scribble", -+ d: getSvgPathFromPoints(scribble.points, false), -+ stroke: color ?? `var(--color-${scribble.color})`, -+ fill: "none", -+ strokeWidth: 8 / zoom, -+ opacity: opacity ?? scribble.opacity -+ } -+ ) }); -+} -+export { -+ DefaultScribble -+}; -+//# sourceMappingURL=DefaultScribble.mjs.map -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/components/default-components/DefaultScribble.mjs.map b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/components/default-components/DefaultScribble.mjs.map -new file mode 100644 -index 0000000..84c0175 ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/components/default-components/DefaultScribble.mjs.map -@@ -0,0 +1,7 @@ -+{ -+ "version": 3, -+ "sources": ["../../../../src/lib/components/default-components/DefaultScribble.tsx"], -+ "sourcesContent": ["import { TLScribble } from '@tldraw/tlschema'\nimport classNames from 'classnames'\nimport { getSvgPathFromPoints } from '../../utils/getSvgPathFromPoints'\n\n/** @public */\nexport interface TLScribbleProps {\n\tscribble: TLScribble\n\tzoom: number\n\tcolor?: string\n\topacity?: number\n\tclassName?: string\n}\n\n/** @public @react */\nexport function DefaultScribble({ scribble, zoom, color, opacity, className }: TLScribbleProps) {\n\tif (!scribble.points.length) return null\n\n\treturn (\n\t\t\n\t\t\t\n\t\t\n\t)\n}\n"], -+ "mappings": "AAmBG;AAlBH,OAAO,gBAAgB;AACvB,SAAS,4BAA4B;AAY9B,SAAS,gBAAgB,EAAE,UAAU,MAAM,OAAO,SAAS,UAAU,GAAoB;AAC/F,MAAI,CAAC,SAAS,OAAO,OAAQ,QAAO;AAEpC,SACC,oBAAC,SAAI,WAAW,YAAY,WAAW,qBAAqB,SAAS,IAAI,WACxE;AAAA,IAAC;AAAA;AAAA,MACA,WAAU;AAAA,MACV,GAAG,qBAAqB,SAAS,QAAQ,KAAK;AAAA,MAC9C,QAAQ,SAAS,eAAe,SAAS,KAAK;AAAA,MAC9C,MAAK;AAAA,MACL,aAAa,IAAI;AAAA,MACjB,SAAS,WAAW,SAAS;AAAA;AAAA,EAC9B,GACD;AAEF;", -+ "names": [] -+} -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/components/default-components/DefaultSelectionBackground.mjs b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/components/default-components/DefaultSelectionBackground.mjs -new file mode 100644 -index 0000000..23dbf72 ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/components/default-components/DefaultSelectionBackground.mjs -@@ -0,0 +1,19 @@ -+import { jsx } from "react/jsx-runtime"; -+import * as React from "react"; -+import { useTransform } from "../../hooks/useTransform.mjs"; -+import { toDomPrecision } from "../../primitives/utils.mjs"; -+function DefaultSelectionBackground({ bounds, rotation }) { -+ const rDiv = React.useRef(null); -+ useTransform(rDiv, bounds.x, bounds.y, 1, rotation); -+ React.useLayoutEffect(() => { -+ const div = rDiv.current; -+ if (!div) return; -+ div.style.width = toDomPrecision(Math.max(1, bounds.width)) + "px"; -+ div.style.height = toDomPrecision(Math.max(1, bounds.height)) + "px"; -+ }, [bounds.width, bounds.height]); -+ return /* @__PURE__ */ jsx("div", { ref: rDiv, className: "tl-selection__bg", draggable: false }); -+} -+export { -+ DefaultSelectionBackground -+}; -+//# sourceMappingURL=DefaultSelectionBackground.mjs.map -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/components/default-components/DefaultSelectionBackground.mjs.map b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/components/default-components/DefaultSelectionBackground.mjs.map -new file mode 100644 -index 0000000..0de28c8 ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/components/default-components/DefaultSelectionBackground.mjs.map -@@ -0,0 +1,7 @@ -+{ -+ "version": 3, -+ "sources": ["../../../../src/lib/components/default-components/DefaultSelectionBackground.tsx"], -+ "sourcesContent": ["import * as React from 'react'\nimport { useTransform } from '../../hooks/useTransform'\nimport { Box } from '../../primitives/Box'\nimport { toDomPrecision } from '../../primitives/utils'\n\n/** @public */\nexport interface TLSelectionBackgroundProps {\n\tbounds: Box\n\trotation: number\n}\n\n/** @public @react */\nexport function DefaultSelectionBackground({ bounds, rotation }: TLSelectionBackgroundProps) {\n\tconst rDiv = React.useRef(null)\n\tuseTransform(rDiv, bounds.x, bounds.y, 1, rotation)\n\n\tReact.useLayoutEffect(() => {\n\t\tconst div = rDiv.current\n\t\tif (!div) return\n\t\tdiv.style.width = toDomPrecision(Math.max(1, bounds.width)) + 'px'\n\t\tdiv.style.height = toDomPrecision(Math.max(1, bounds.height)) + 'px'\n\t}, [bounds.width, bounds.height])\n\n\treturn
\n}\n"], -+ "mappings": "AAuBQ;AAvBR,YAAY,WAAW;AACvB,SAAS,oBAAoB;AAE7B,SAAS,sBAAsB;AASxB,SAAS,2BAA2B,EAAE,QAAQ,SAAS,GAA+B;AAC5F,QAAM,OAAO,MAAM,OAAuB,IAAI;AAC9C,eAAa,MAAM,OAAO,GAAG,OAAO,GAAG,GAAG,QAAQ;AAElD,QAAM,gBAAgB,MAAM;AAC3B,UAAM,MAAM,KAAK;AACjB,QAAI,CAAC,IAAK;AACV,QAAI,MAAM,QAAQ,eAAe,KAAK,IAAI,GAAG,OAAO,KAAK,CAAC,IAAI;AAC9D,QAAI,MAAM,SAAS,eAAe,KAAK,IAAI,GAAG,OAAO,MAAM,CAAC,IAAI;AAAA,EACjE,GAAG,CAAC,OAAO,OAAO,OAAO,MAAM,CAAC;AAEhC,SAAO,oBAAC,SAAI,KAAK,MAAM,WAAU,oBAAmB,WAAW,OAAO;AACvE;", -+ "names": [] -+} -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/components/default-components/DefaultSelectionForeground.mjs b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/components/default-components/DefaultSelectionForeground.mjs -new file mode 100644 -index 0000000..cc03dbe ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/components/default-components/DefaultSelectionForeground.mjs -@@ -0,0 +1,38 @@ -+import { jsx } from "react/jsx-runtime"; -+import { useValue } from "@tldraw/state-react"; -+import classNames from "classnames"; -+import { useRef } from "react"; -+import { useEditor } from "../../hooks/useEditor.mjs"; -+import { useTransform } from "../../hooks/useTransform.mjs"; -+import { toDomPrecision } from "../../primitives/utils.mjs"; -+function DefaultSelectionForeground({ bounds, rotation }) { -+ const editor = useEditor(); -+ const rSvg = useRef(null); -+ const onlyShape = useValue("only selected shape", () => editor.getOnlySelectedShape(), [editor]); -+ const expandOutlineBy = onlyShape ? editor.getShapeUtil(onlyShape).expandSelectionOutlinePx(onlyShape) : 0; -+ useTransform(rSvg, bounds?.x, bounds?.y, 1, rotation, { -+ x: -expandOutlineBy, -+ y: -expandOutlineBy -+ }); -+ bounds = bounds.clone().expandBy(expandOutlineBy).zeroFix(); -+ return /* @__PURE__ */ jsx( -+ "svg", -+ { -+ ref: rSvg, -+ className: "tl-overlays__item tl-selection__fg", -+ "data-testid": "selection-foreground", -+ children: /* @__PURE__ */ jsx( -+ "rect", -+ { -+ className: classNames("tl-selection__fg__outline"), -+ width: toDomPrecision(bounds.width), -+ height: toDomPrecision(bounds.height) -+ } -+ ) -+ } -+ ); -+} -+export { -+ DefaultSelectionForeground -+}; -+//# sourceMappingURL=DefaultSelectionForeground.mjs.map -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/components/default-components/DefaultSelectionForeground.mjs.map b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/components/default-components/DefaultSelectionForeground.mjs.map -new file mode 100644 -index 0000000..ee622f0 ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/components/default-components/DefaultSelectionForeground.mjs.map -@@ -0,0 +1,7 @@ -+{ -+ "version": 3, -+ "sources": ["../../../../src/lib/components/default-components/DefaultSelectionForeground.tsx"], -+ "sourcesContent": ["import { useValue } from '@tldraw/state-react'\nimport classNames from 'classnames'\nimport { useRef } from 'react'\nimport { useEditor } from '../../hooks/useEditor'\nimport { useTransform } from '../../hooks/useTransform'\nimport { Box } from '../../primitives/Box'\nimport { toDomPrecision } from '../../primitives/utils'\n\n/** @public */\nexport interface TLSelectionForegroundProps {\n\tbounds: Box\n\trotation: number\n}\n\n/** @public @react */\nexport function DefaultSelectionForeground({ bounds, rotation }: TLSelectionForegroundProps) {\n\tconst editor = useEditor()\n\tconst rSvg = useRef(null)\n\n\tconst onlyShape = useValue('only selected shape', () => editor.getOnlySelectedShape(), [editor])\n\n\t// if all shapes have an expandBy for the selection outline, we can expand by the l\n\tconst expandOutlineBy = onlyShape\n\t\t? editor.getShapeUtil(onlyShape).expandSelectionOutlinePx(onlyShape)\n\t\t: 0\n\n\tuseTransform(rSvg, bounds?.x, bounds?.y, 1, rotation, {\n\t\tx: -expandOutlineBy,\n\t\ty: -expandOutlineBy,\n\t})\n\n\tbounds = bounds.clone().expandBy(expandOutlineBy).zeroFix()\n\n\treturn (\n\t\t\n\t\t\t\n\t\t\n\t)\n}\n"], -+ "mappings": "AAuCG;AAvCH,SAAS,gBAAgB;AACzB,OAAO,gBAAgB;AACvB,SAAS,cAAc;AACvB,SAAS,iBAAiB;AAC1B,SAAS,oBAAoB;AAE7B,SAAS,sBAAsB;AASxB,SAAS,2BAA2B,EAAE,QAAQ,SAAS,GAA+B;AAC5F,QAAM,SAAS,UAAU;AACzB,QAAM,OAAO,OAAsB,IAAI;AAEvC,QAAM,YAAY,SAAS,uBAAuB,MAAM,OAAO,qBAAqB,GAAG,CAAC,MAAM,CAAC;AAG/F,QAAM,kBAAkB,YACrB,OAAO,aAAa,SAAS,EAAE,yBAAyB,SAAS,IACjE;AAEH,eAAa,MAAM,QAAQ,GAAG,QAAQ,GAAG,GAAG,UAAU;AAAA,IACrD,GAAG,CAAC;AAAA,IACJ,GAAG,CAAC;AAAA,EACL,CAAC;AAED,WAAS,OAAO,MAAM,EAAE,SAAS,eAAe,EAAE,QAAQ;AAE1D,SACC;AAAA,IAAC;AAAA;AAAA,MACA,KAAK;AAAA,MACL,WAAU;AAAA,MACV,eAAY;AAAA,MAEZ;AAAA,QAAC;AAAA;AAAA,UACA,WAAW,WAAW,2BAA2B;AAAA,UACjD,OAAO,eAAe,OAAO,KAAK;AAAA,UAClC,QAAQ,eAAe,OAAO,MAAM;AAAA;AAAA,MACrC;AAAA;AAAA,EACD;AAEF;", -+ "names": [] -+} -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/components/default-components/DefaultShapeErrorFallback.mjs b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/components/default-components/DefaultShapeErrorFallback.mjs -new file mode 100644 -index 0000000..bb70371 ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/components/default-components/DefaultShapeErrorFallback.mjs -@@ -0,0 +1,8 @@ -+import { jsx } from "react/jsx-runtime"; -+const DefaultShapeErrorFallback = () => { -+ return /* @__PURE__ */ jsx("div", { className: "tl-shape-error-boundary" }); -+}; -+export { -+ DefaultShapeErrorFallback -+}; -+//# sourceMappingURL=DefaultShapeErrorFallback.mjs.map -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/components/default-components/DefaultShapeErrorFallback.mjs.map b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/components/default-components/DefaultShapeErrorFallback.mjs.map -new file mode 100644 -index 0000000..59c5294 ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/components/default-components/DefaultShapeErrorFallback.mjs.map -@@ -0,0 +1,7 @@ -+{ -+ "version": 3, -+ "sources": ["../../../../src/lib/components/default-components/DefaultShapeErrorFallback.tsx"], -+ "sourcesContent": ["import { ComponentType } from 'react'\n\n/** @public */\nexport type TLShapeErrorFallbackComponent = ComponentType<{ error: any }>\n\n/** @internal */\nexport const DefaultShapeErrorFallback: TLShapeErrorFallbackComponent = () => {\n\treturn
\n}\n"], -+ "mappings": "AAOQ;AADD,MAAM,4BAA2D,MAAM;AAC7E,SAAO,oBAAC,SAAI,WAAU,2BAA0B;AACjD;", -+ "names": [] -+} -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/components/default-components/DefaultShapeIndicator.mjs b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/components/default-components/DefaultShapeIndicator.mjs -new file mode 100644 -index 0000000..adeb5fc ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/components/default-components/DefaultShapeIndicator.mjs -@@ -0,0 +1,61 @@ -+import { jsx } from "react/jsx-runtime"; -+import { useQuickReactor, useStateTracking, useValue } from "@tldraw/state-react"; -+import classNames from "classnames"; -+import { memo, useLayoutEffect, useRef } from "react"; -+import { useEditor } from "../../hooks/useEditor.mjs"; -+import { useEditorComponents } from "../../hooks/useEditorComponents.mjs"; -+import { OptionalErrorBoundary } from "../ErrorBoundary.mjs"; -+const EvenInnererIndicator = ({ shape, util }) => { -+ return useStateTracking( -+ "Indicator: " + shape.type, -+ () => ( -+ // always fetch the latest shape from the store even if the props/meta have not changed, to avoid -+ // calling the render method with stale data. -+ (util.indicator(util.editor.store.unsafeGetWithoutCapture(shape.id))) -+ ) -+ ); -+}; -+const InnerIndicator = ({ editor, id }) => { -+ const shape = useValue("shape for indicator", () => editor.store.get(id), [editor, id]); -+ const { ShapeIndicatorErrorFallback } = useEditorComponents(); -+ if (!shape || shape.isLocked) return null; -+ return /* @__PURE__ */ jsx( -+ OptionalErrorBoundary, -+ { -+ fallback: ShapeIndicatorErrorFallback, -+ onError: (error) => editor.annotateError(error, { origin: "react.shapeIndicator", willCrashApp: false }), -+ children: /* @__PURE__ */ jsx(EvenInnererIndicator, { shape, util: editor.getShapeUtil(shape) }, shape.id) -+ } -+ ); -+}; -+const DefaultShapeIndicator = memo(function DefaultShapeIndicator2({ -+ shapeId, -+ className, -+ color, -+ hidden, -+ opacity -+}) { -+ const editor = useEditor(); -+ const rIndicator = useRef(null); -+ useQuickReactor( -+ "indicator transform", -+ () => { -+ const elm = rIndicator.current; -+ if (!elm) return; -+ const pageTransform = editor.getShapePageTransform(shapeId); -+ if (!pageTransform) return; -+ elm.style.setProperty("transform", pageTransform.toCssString()); -+ }, -+ [editor, shapeId] -+ ); -+ useLayoutEffect(() => { -+ const elm = rIndicator.current; -+ if (!elm) return; -+ elm.style.setProperty("display", hidden ? "none" : "block"); -+ }, [hidden]); -+ return /* @__PURE__ */ jsx("svg", { ref: rIndicator, className: classNames("tl-overlays__item", className), children: /* @__PURE__ */ jsx("g", { className: "tl-shape-indicator", stroke: color ?? "var(--color-selected)", opacity, children: /* @__PURE__ */ jsx(InnerIndicator, { editor, id: shapeId }) }) }); -+}); -+export { -+ DefaultShapeIndicator -+}; -+//# sourceMappingURL=DefaultShapeIndicator.mjs.map -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/components/default-components/DefaultShapeIndicator.mjs.map b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/components/default-components/DefaultShapeIndicator.mjs.map -new file mode 100644 -index 0000000..f7b4edc ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/components/default-components/DefaultShapeIndicator.mjs.map -@@ -0,0 +1,7 @@ -+{ -+ "version": 3, -+ "sources": ["../../../../src/lib/components/default-components/DefaultShapeIndicator.tsx"], -+ "sourcesContent": ["import { useQuickReactor, useStateTracking, useValue } from '@tldraw/state-react'\nimport { TLShape, TLShapeId } from '@tldraw/tlschema'\nimport classNames from 'classnames'\nimport { memo, useLayoutEffect, useRef } from 'react'\nimport type { Editor } from '../../editor/Editor'\nimport { ShapeUtil } from '../../editor/shapes/ShapeUtil'\nimport { useEditor } from '../../hooks/useEditor'\nimport { useEditorComponents } from '../../hooks/useEditorComponents'\nimport { OptionalErrorBoundary } from '../ErrorBoundary'\n\n// need an extra layer of indirection here to allow hooks to be used inside the indicator render\nconst EvenInnererIndicator = ({ shape, util }: { shape: TLShape; util: ShapeUtil }) => {\n\treturn useStateTracking('Indicator: ' + shape.type, () =>\n\t\t// always fetch the latest shape from the store even if the props/meta have not changed, to avoid\n\t\t// calling the render method with stale data.\n\t\tutil.indicator(util.editor.store.unsafeGetWithoutCapture(shape.id) as TLShape)\n\t)\n}\n\nconst InnerIndicator = ({ editor, id }: { editor: Editor; id: TLShapeId }) => {\n\tconst shape = useValue('shape for indicator', () => editor.store.get(id), [editor, id])\n\n\tconst { ShapeIndicatorErrorFallback } = useEditorComponents()\n\n\tif (!shape || shape.isLocked) return null\n\n\treturn (\n\t\t\n\t\t\t\teditor.annotateError(error, { origin: 'react.shapeIndicator', willCrashApp: false })\n\t\t\t}\n\t\t>\n\t\t\t\n\t\t\n\t)\n}\n\n/** @public */\nexport interface TLShapeIndicatorProps {\n\tshapeId: TLShapeId\n\tcolor?: string | undefined\n\topacity?: number\n\tclassName?: string\n\thidden?: boolean\n}\n\n/** @public @react */\nexport const DefaultShapeIndicator = memo(function DefaultShapeIndicator({\n\tshapeId,\n\tclassName,\n\tcolor,\n\thidden,\n\topacity,\n}: TLShapeIndicatorProps) {\n\tconst editor = useEditor()\n\n\tconst rIndicator = useRef(null)\n\n\tuseQuickReactor(\n\t\t'indicator transform',\n\t\t() => {\n\t\t\tconst elm = rIndicator.current\n\t\t\tif (!elm) return\n\t\t\tconst pageTransform = editor.getShapePageTransform(shapeId)\n\t\t\tif (!pageTransform) return\n\t\t\telm.style.setProperty('transform', pageTransform.toCssString())\n\t\t},\n\t\t[editor, shapeId]\n\t)\n\n\tuseLayoutEffect(() => {\n\t\tconst elm = rIndicator.current\n\t\tif (!elm) return\n\t\telm.style.setProperty('display', hidden ? 'none' : 'block')\n\t}, [hidden])\n\n\treturn (\n\t\t\n\t\t\t\n\t\t\t\t\n\t\t\t\n\t\t\n\t)\n})\n"], -+ "mappings": "AAiCG;AAjCH,SAAS,iBAAiB,kBAAkB,gBAAgB;AAE5D,OAAO,gBAAgB;AACvB,SAAS,MAAM,iBAAiB,cAAc;AAG9C,SAAS,iBAAiB;AAC1B,SAAS,2BAA2B;AACpC,SAAS,6BAA6B;AAGtC,MAAM,uBAAuB,CAAC,EAAE,OAAO,KAAK,MAAgD;AAC3F,SAAO;AAAA,IAAiB,gBAAgB,MAAM;AAAA,IAAM;AAAA;AAAA;AAAA,MAGnD,KAAK,UAAU,KAAK,OAAO,MAAM,wBAAwB,MAAM,EAAE,CAAY;AAAA;AAAA,EAC9E;AACD;AAEA,MAAM,iBAAiB,CAAC,EAAE,QAAQ,GAAG,MAAyC;AAC7E,QAAM,QAAQ,SAAS,uBAAuB,MAAM,OAAO,MAAM,IAAI,EAAE,GAAG,CAAC,QAAQ,EAAE,CAAC;AAEtF,QAAM,EAAE,4BAA4B,IAAI,oBAAoB;AAE5D,MAAI,CAAC,SAAS,MAAM,SAAU,QAAO;AAErC,SACC;AAAA,IAAC;AAAA;AAAA,MACA,UAAU;AAAA,MACV,SAAS,CAAC,UACT,OAAO,cAAc,OAAO,EAAE,QAAQ,wBAAwB,cAAc,MAAM,CAAC;AAAA,MAGpF,8BAAC,wBAAoC,OAAc,MAAM,OAAO,aAAa,KAAK,KAAvD,MAAM,EAAoD;AAAA;AAAA,EACtF;AAEF;AAYO,MAAM,wBAAwB,KAAK,SAASA,uBAAsB;AAAA,EACxE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACD,GAA0B;AACzB,QAAM,SAAS,UAAU;AAEzB,QAAM,aAAa,OAAsB,IAAI;AAE7C;AAAA,IACC;AAAA,IACA,MAAM;AACL,YAAM,MAAM,WAAW;AACvB,UAAI,CAAC,IAAK;AACV,YAAM,gBAAgB,OAAO,sBAAsB,OAAO;AAC1D,UAAI,CAAC,cAAe;AACpB,UAAI,MAAM,YAAY,aAAa,cAAc,YAAY,CAAC;AAAA,IAC/D;AAAA,IACA,CAAC,QAAQ,OAAO;AAAA,EACjB;AAEA,kBAAgB,MAAM;AACrB,UAAM,MAAM,WAAW;AACvB,QAAI,CAAC,IAAK;AACV,QAAI,MAAM,YAAY,WAAW,SAAS,SAAS,OAAO;AAAA,EAC3D,GAAG,CAAC,MAAM,CAAC;AAEX,SACC,oBAAC,SAAI,KAAK,YAAY,WAAW,WAAW,qBAAqB,SAAS,GACzE,8BAAC,OAAE,WAAU,sBAAqB,QAAQ,SAAS,yBAAyB,SAC3E,8BAAC,kBAAe,QAAgB,IAAI,SAAS,GAC9C,GACD;AAEF,CAAC;", -+ "names": ["DefaultShapeIndicator"] -+} -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/components/default-components/DefaultShapeIndicatorErrorFallback.mjs b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/components/default-components/DefaultShapeIndicatorErrorFallback.mjs -new file mode 100644 -index 0000000..f997b77 ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/components/default-components/DefaultShapeIndicatorErrorFallback.mjs -@@ -0,0 +1,8 @@ -+import { jsx } from "react/jsx-runtime"; -+const DefaultShapeIndicatorErrorFallback = () => { -+ return /* @__PURE__ */ jsx("circle", { cx: 4, cy: 4, r: 8, strokeWidth: "1", stroke: "red" }); -+}; -+export { -+ DefaultShapeIndicatorErrorFallback -+}; -+//# sourceMappingURL=DefaultShapeIndicatorErrorFallback.mjs.map -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/components/default-components/DefaultShapeIndicatorErrorFallback.mjs.map b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/components/default-components/DefaultShapeIndicatorErrorFallback.mjs.map -new file mode 100644 -index 0000000..2cf2cb7 ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/components/default-components/DefaultShapeIndicatorErrorFallback.mjs.map -@@ -0,0 +1,7 @@ -+{ -+ "version": 3, -+ "sources": ["../../../../src/lib/components/default-components/DefaultShapeIndicatorErrorFallback.tsx"], -+ "sourcesContent": ["import { ComponentType } from 'react'\n\n/** @public */\nexport type TLShapeIndicatorErrorFallbackComponent = ComponentType<{ error: unknown }>\n\n/** @internal */\nexport const DefaultShapeIndicatorErrorFallback: TLShapeIndicatorErrorFallbackComponent = () => {\n\treturn \n}\n"], -+ "mappings": "AAOQ;AADD,MAAM,qCAA6E,MAAM;AAC/F,SAAO,oBAAC,YAAO,IAAI,GAAG,IAAI,GAAG,GAAG,GAAG,aAAY,KAAI,QAAO,OAAM;AACjE;", -+ "names": [] -+} -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/components/default-components/DefaultShapeIndicators.mjs b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/components/default-components/DefaultShapeIndicators.mjs -new file mode 100644 -index 0000000..7d43717 ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/components/default-components/DefaultShapeIndicators.mjs -@@ -0,0 +1,61 @@ -+import { jsx } from "react/jsx-runtime"; -+import { useValue } from "@tldraw/state-react"; -+import { memo, useRef } from "react"; -+import { useEditor } from "../../hooks/useEditor.mjs"; -+import { useEditorComponents } from "../../hooks/useEditorComponents.mjs"; -+const DefaultShapeIndicators = memo(function DefaultShapeIndicators2() { -+ const editor = useEditor(); -+ const rPreviousSelectedShapeIds = useRef(/* @__PURE__ */ new Set()); -+ const idsToDisplay = useValue( -+ "should display selected ids", -+ () => { -+ const prev = rPreviousSelectedShapeIds.current; -+ const next = /* @__PURE__ */ new Set(); -+ if ( -+ // We only show indicators when in the following states... -+ editor.isInAny( -+ "select.idle", -+ "select.brushing", -+ "select.scribble_brushing", -+ "select.editing_shape", -+ "select.pointing_shape", -+ "select.pointing_selection", -+ "select.pointing_handle" -+ ) && // ...but we hide indicators when we've just changed a style (so that the user can see the change) -+ !editor.getInstanceState().isChangingStyle -+ ) { -+ const selected = editor.getSelectedShapeIds(); -+ for (const id of selected) { -+ next.add(id); -+ } -+ if (editor.isInAny("select.idle", "select.editing_shape")) { -+ const instanceState = editor.getInstanceState(); -+ if (instanceState.isHoveringCanvas && !instanceState.isCoarsePointer) { -+ const hovered = editor.getHoveredShapeId(); -+ if (hovered) next.add(hovered); -+ } -+ } -+ } -+ if (prev.size !== next.size) { -+ rPreviousSelectedShapeIds.current = next; -+ return next; -+ } -+ for (const id of next) { -+ if (!prev.has(id)) { -+ rPreviousSelectedShapeIds.current = next; -+ return next; -+ } -+ } -+ return prev; -+ }, -+ [editor] -+ ); -+ const renderingShapes = useValue("rendering shapes", () => editor.getRenderingShapes(), [editor]); -+ const { ShapeIndicator } = useEditorComponents(); -+ if (!ShapeIndicator) return null; -+ return renderingShapes.map(({ id }) => /* @__PURE__ */ jsx(ShapeIndicator, { shapeId: id, hidden: !idsToDisplay.has(id) }, id + "_indicator")); -+}); -+export { -+ DefaultShapeIndicators -+}; -+//# sourceMappingURL=DefaultShapeIndicators.mjs.map -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/components/default-components/DefaultShapeIndicators.mjs.map b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/components/default-components/DefaultShapeIndicators.mjs.map -new file mode 100644 -index 0000000..81ba1a7 ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/components/default-components/DefaultShapeIndicators.mjs.map -@@ -0,0 +1,7 @@ -+{ -+ "version": 3, -+ "sources": ["../../../../src/lib/components/default-components/DefaultShapeIndicators.tsx"], -+ "sourcesContent": ["import { useValue } from '@tldraw/state-react'\nimport { TLShapeId } from '@tldraw/tlschema'\nimport { memo, useRef } from 'react'\nimport { useEditor } from '../../hooks/useEditor'\nimport { useEditorComponents } from '../../hooks/useEditorComponents'\n\n/** @public @react */\nexport const DefaultShapeIndicators = memo(function DefaultShapeIndicators() {\n\tconst editor = useEditor()\n\n\tconst rPreviousSelectedShapeIds = useRef>(new Set())\n\n\tconst idsToDisplay = useValue(\n\t\t'should display selected ids',\n\t\t() => {\n\t\t\tconst prev = rPreviousSelectedShapeIds.current\n\t\t\tconst next = new Set()\n\n\t\t\tif (\n\t\t\t\t// We only show indicators when in the following states...\n\t\t\t\teditor.isInAny(\n\t\t\t\t\t'select.idle',\n\t\t\t\t\t'select.brushing',\n\t\t\t\t\t'select.scribble_brushing',\n\t\t\t\t\t'select.editing_shape',\n\t\t\t\t\t'select.pointing_shape',\n\t\t\t\t\t'select.pointing_selection',\n\t\t\t\t\t'select.pointing_handle'\n\t\t\t\t) &&\n\t\t\t\t// ...but we hide indicators when we've just changed a style (so that the user can see the change)\n\t\t\t\t!editor.getInstanceState().isChangingStyle\n\t\t\t) {\n\t\t\t\t// We always want to show indicators for the selected shapes, if any\n\t\t\t\tconst selected = editor.getSelectedShapeIds()\n\t\t\t\tfor (const id of selected) {\n\t\t\t\t\tnext.add(id)\n\t\t\t\t}\n\n\t\t\t\t// If we're idle or editing a shape, we want to also show an indicator for the hovered shape, if any\n\t\t\t\tif (editor.isInAny('select.idle', 'select.editing_shape')) {\n\t\t\t\t\tconst instanceState = editor.getInstanceState()\n\t\t\t\t\tif (instanceState.isHoveringCanvas && !instanceState.isCoarsePointer) {\n\t\t\t\t\t\tconst hovered = editor.getHoveredShapeId()\n\t\t\t\t\t\tif (hovered) next.add(hovered)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Ok, has anything changed?\n\n\t\t\t// If the number of items in the set is different, then the selection has changed. This catches most changes.\n\t\t\tif (prev.size !== next.size) {\n\t\t\t\trPreviousSelectedShapeIds.current = next\n\t\t\t\treturn next\n\t\t\t}\n\n\t\t\t// If any of the new ids are not in the previous set, then the selection has changed\n\t\t\tfor (const id of next) {\n\t\t\t\tif (!prev.has(id)) {\n\t\t\t\t\trPreviousSelectedShapeIds.current = next\n\t\t\t\t\treturn next\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// If nothing has changed, then return the previous value\n\t\t\treturn prev\n\t\t},\n\t\t[editor]\n\t)\n\n\t// Show indicators only for the shapes that are currently being rendered (ie that are on screen)\n\tconst renderingShapes = useValue('rendering shapes', () => editor.getRenderingShapes(), [editor])\n\n\tconst { ShapeIndicator } = useEditorComponents()\n\tif (!ShapeIndicator) return null\n\n\treturn renderingShapes.map(({ id }) => (\n\t\t
\n\t)\n})\n\nconst LicenseStyles = memo(function LicenseStyles() {\n\tconst className = LicenseManager.className\n\n\tconst CSS = `/* ------------------- SEE LICENSE -------------------\nThe tldraw watermark is part of tldraw's license. It is shown for unlicensed\nor \"licensed-with-watermark\" users. By using this library, you agree to\npreserve the watermark's behavior, keeping it visible, unobscured, and\navailable to user-interaction.\n\nTo remove the watermark, please purchase a license at tldraw.dev.\n*/\n\n\t.${className} {\n\t\tposition: absolute;\n\t\tbottom: var(--space-2);\n\t\tright: var(--space-2);\n\t\twidth: 96px;\n\t\theight: 32px;\n\t\tdisplay: flex;\n\t\talign-items: center;\n\t\tjustify-content: center;\n\t\tz-index: 2147483647 !important;\n\t\tbackground-color: color-mix(in srgb, var(--color-background) 62%, transparent);\n\t\topacity: 1;\n\t\tborder-radius: 5px;\n\t\tpointer-events: all;\n\t\tpadding: 2px;\n\t\tbox-sizing: content-box;\n\t}\n\t\n\t.${className} > a {\n\t\tposition: absolute;\n\t\twidth: 96px;\n\t\theight: 32px;\n\t\tpointer-events: all;\n\t\tcursor: inherit;\n\t\tcolor: var(--color-text);\n\t\topacity: .38;\n\t\tbackground-color: currentColor;\n\t}\n\n\t\n\t.${className}[data-menu='true'] {\n\t\tpointer-events: none;\n\t}\n\n\t.${className}[data-debug='true'] {\n\t\tbottom: 46px;\n\t}\n\t\n\t.${className}[data-mobile='true'] {\n\t\tborder-radius: 4px 0px 0px 4px;\n\t\tright: -2px;\n\t\twidth: 8px;\n\t\theight: 48px;\n\t}\n\n\t.${className}[data-mobile='true'] > a {\n\t\twidth: 8px;\n\t\theight: 32px;\n\t}\n\t\n\t@media (hover: hover) {\n\t\t.${className} > a {\n\t\t\tpointer-events: none;\n\t\t}\n\n\t\t.${className}:hover {\n\t\t\tbackground-color: var(--color-background);\n\t\t\ttransition: background-color 0.2s ease-in-out;\n\t\t\ttransition-delay: 0.32s;\n\t\t}\n\t\t\t\n\t\t.${className}:hover > a {\n\t\t\tanimation: delayed_link 0.2s forwards ease-in-out;\n\t\t\tanimation-delay: 0.32s;\n\t\t}\n\t}\n\t\n\n\t@keyframes delayed_link {\n\t\t0% {\n\t\t\tcursor: inherit;\n\t\t\topacity: .38;\n\t\t\tpointer-events: none;\n\t\t}\n\t\t100% {\n\t\t\tcursor: pointer;\n\t\t\topacity: 1;\n\t\t\tpointer-events: all;\n\t\t}\n\t}`\n\n\treturn \n})\n"], -+ "mappings": "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", -+ "names": ["Watermark", "WatermarkInner", "LicenseStyles"] -+} -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/options.mjs b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/options.mjs -new file mode 100644 -index 0000000..9507829 ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/options.mjs -@@ -0,0 +1,46 @@ -+const defaultTldrawOptions = { -+ maxShapesPerPage: 4e3, -+ maxFilesAtOnce: 100, -+ maxPages: 40, -+ animationMediumMs: 320, -+ followChaseViewportSnap: 2, -+ doubleClickDurationMs: 450, -+ multiClickDurationMs: 200, -+ coarseDragDistanceSquared: 36, -+ // 6 squared -+ dragDistanceSquared: 16, -+ // 4 squared -+ defaultSvgPadding: 32, -+ cameraSlideFriction: 0.09, -+ maxPointsPerDrawShape: 500, -+ gridSteps: [ -+ { min: -1, mid: 0.15, step: 64 }, -+ { min: 0.05, mid: 0.375, step: 16 }, -+ { min: 0.15, mid: 1, step: 4 }, -+ { min: 0.7, mid: 2.5, step: 1 } -+ ], -+ collaboratorInactiveTimeoutMs: 6e4, -+ collaboratorIdleTimeoutMs: 3e3, -+ collaboratorCheckIntervalMs: 1200, -+ cameraMovingTimeoutMs: 64, -+ hitTestMargin: 8, -+ edgeScrollDelay: 200, -+ edgeScrollEaseDuration: 200, -+ edgeScrollSpeed: 25, -+ edgeScrollDistance: 8, -+ coarsePointerWidth: 12, -+ coarseHandleRadius: 20, -+ handleRadius: 12, -+ longPressDurationMs: 500, -+ textShadowLod: 0.35, -+ adjacentShapeMargin: 10, -+ flattenImageBoundsExpand: 64, -+ flattenImageBoundsPadding: 16, -+ laserDelayMs: 1200, -+ maxExportDelayMs: 5e3, -+ temporaryAssetPreviewLifetimeMs: 18e4 -+}; -+export { -+ defaultTldrawOptions -+}; -+//# sourceMappingURL=options.mjs.map -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/options.mjs.map b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/options.mjs.map -new file mode 100644 -index 0000000..d74e9b5 ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/options.mjs.map -@@ -0,0 +1,7 @@ -+{ -+ "version": 3, -+ "sources": ["../../src/lib/options.ts"], -+ "sourcesContent": ["/**\n * Options for configuring tldraw. For defaults, see {@link defaultTldrawOptions}.\n *\n * @example\n * ```tsx\n * const options: Partial = {\n * maxPages: 3,\n * maxShapesPerPage: 1000,\n * }\n *\n * function MyTldrawComponent() {\n * return \n * }\n * ```\n *\n * @public\n */\nexport interface TldrawOptions {\n\treadonly maxShapesPerPage: number\n\treadonly maxFilesAtOnce: number\n\treadonly maxPages: number\n\treadonly animationMediumMs: number\n\treadonly followChaseViewportSnap: number\n\treadonly doubleClickDurationMs: number\n\treadonly multiClickDurationMs: number\n\treadonly coarseDragDistanceSquared: number\n\treadonly dragDistanceSquared: number\n\treadonly defaultSvgPadding: number\n\treadonly cameraSlideFriction: number\n\treadonly maxPointsPerDrawShape: number\n\treadonly gridSteps: readonly {\n\t\treadonly min: number\n\t\treadonly mid: number\n\t\treadonly step: number\n\t}[]\n\treadonly collaboratorInactiveTimeoutMs: number\n\treadonly collaboratorIdleTimeoutMs: number\n\treadonly collaboratorCheckIntervalMs: number\n\treadonly cameraMovingTimeoutMs: number\n\treadonly hitTestMargin: number\n\treadonly edgeScrollDelay: number\n\treadonly edgeScrollEaseDuration: number\n\treadonly edgeScrollSpeed: number\n\treadonly edgeScrollDistance: number\n\treadonly coarsePointerWidth: number\n\treadonly coarseHandleRadius: number\n\treadonly handleRadius: number\n\treadonly longPressDurationMs: number\n\treadonly textShadowLod: number\n\treadonly adjacentShapeMargin: number\n\treadonly flattenImageBoundsExpand: number\n\treadonly flattenImageBoundsPadding: number\n\treadonly laserDelayMs: number\n\treadonly maxExportDelayMs: number\n\t/**\n\t * How long should previews created by {@link Editor.createTemporaryAssetPreview} last before\n\t * they expire? Defaults to 3 minutes.\n\t */\n\treadonly temporaryAssetPreviewLifetimeMs: number\n}\n\n/** @public */\nexport const defaultTldrawOptions = {\n\tmaxShapesPerPage: 4000,\n\tmaxFilesAtOnce: 100,\n\tmaxPages: 40,\n\tanimationMediumMs: 320,\n\tfollowChaseViewportSnap: 2,\n\tdoubleClickDurationMs: 450,\n\tmultiClickDurationMs: 200,\n\tcoarseDragDistanceSquared: 36, // 6 squared\n\tdragDistanceSquared: 16, // 4 squared\n\tdefaultSvgPadding: 32,\n\tcameraSlideFriction: 0.09,\n\tmaxPointsPerDrawShape: 500,\n\tgridSteps: [\n\t\t{ min: -1, mid: 0.15, step: 64 },\n\t\t{ min: 0.05, mid: 0.375, step: 16 },\n\t\t{ min: 0.15, mid: 1, step: 4 },\n\t\t{ min: 0.7, mid: 2.5, step: 1 },\n\t],\n\tcollaboratorInactiveTimeoutMs: 60000,\n\tcollaboratorIdleTimeoutMs: 3000,\n\tcollaboratorCheckIntervalMs: 1200,\n\tcameraMovingTimeoutMs: 64,\n\thitTestMargin: 8,\n\tedgeScrollDelay: 200,\n\tedgeScrollEaseDuration: 200,\n\tedgeScrollSpeed: 25,\n\tedgeScrollDistance: 8,\n\tcoarsePointerWidth: 12,\n\tcoarseHandleRadius: 20,\n\thandleRadius: 12,\n\tlongPressDurationMs: 500,\n\ttextShadowLod: 0.35,\n\tadjacentShapeMargin: 10,\n\tflattenImageBoundsExpand: 64,\n\tflattenImageBoundsPadding: 16,\n\tlaserDelayMs: 1200,\n\tmaxExportDelayMs: 5000,\n\ttemporaryAssetPreviewLifetimeMs: 180000,\n} as const satisfies TldrawOptions\n"], -+ "mappings": "AA8DO,MAAM,uBAAuB;AAAA,EACnC,kBAAkB;AAAA,EAClB,gBAAgB;AAAA,EAChB,UAAU;AAAA,EACV,mBAAmB;AAAA,EACnB,yBAAyB;AAAA,EACzB,uBAAuB;AAAA,EACvB,sBAAsB;AAAA,EACtB,2BAA2B;AAAA;AAAA,EAC3B,qBAAqB;AAAA;AAAA,EACrB,mBAAmB;AAAA,EACnB,qBAAqB;AAAA,EACrB,uBAAuB;AAAA,EACvB,WAAW;AAAA,IACV,EAAE,KAAK,IAAI,KAAK,MAAM,MAAM,GAAG;AAAA,IAC/B,EAAE,KAAK,MAAM,KAAK,OAAO,MAAM,GAAG;AAAA,IAClC,EAAE,KAAK,MAAM,KAAK,GAAG,MAAM,EAAE;AAAA,IAC7B,EAAE,KAAK,KAAK,KAAK,KAAK,MAAM,EAAE;AAAA,EAC/B;AAAA,EACA,+BAA+B;AAAA,EAC/B,2BAA2B;AAAA,EAC3B,6BAA6B;AAAA,EAC7B,uBAAuB;AAAA,EACvB,eAAe;AAAA,EACf,iBAAiB;AAAA,EACjB,wBAAwB;AAAA,EACxB,iBAAiB;AAAA,EACjB,oBAAoB;AAAA,EACpB,oBAAoB;AAAA,EACpB,oBAAoB;AAAA,EACpB,cAAc;AAAA,EACd,qBAAqB;AAAA,EACrB,eAAe;AAAA,EACf,qBAAqB;AAAA,EACrB,0BAA0B;AAAA,EAC1B,2BAA2B;AAAA,EAC3B,cAAc;AAAA,EACd,kBAAkB;AAAA,EAClB,iCAAiC;AAClC;", -+ "names": [] -+} -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/primitives/Box.mjs b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/primitives/Box.mjs -new file mode 100644 -index 0000000..a6e676d ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/primitives/Box.mjs -@@ -0,0 +1,530 @@ -+import { Vec } from "./Vec.mjs"; -+import { PI, PI2, toPrecision } from "./utils.mjs"; -+class Box { -+ constructor(x = 0, y = 0, w = 0, h = 0) { -+ this.x = x; -+ this.y = y; -+ this.w = w; -+ this.h = h; -+ } -+ x = 0; -+ y = 0; -+ w = 0; -+ h = 0; -+ // eslint-disable-next-line no-restricted-syntax -+ get point() { -+ return new Vec(this.x, this.y); -+ } -+ // eslint-disable-next-line no-restricted-syntax -+ set point(val) { -+ this.x = val.x; -+ this.y = val.y; -+ } -+ // eslint-disable-next-line no-restricted-syntax -+ get minX() { -+ return this.x; -+ } -+ // eslint-disable-next-line no-restricted-syntax -+ set minX(n) { -+ this.x = n; -+ } -+ // eslint-disable-next-line no-restricted-syntax -+ get midX() { -+ return this.x + this.w / 2; -+ } -+ // eslint-disable-next-line no-restricted-syntax -+ get maxX() { -+ return this.x + this.w; -+ } -+ // eslint-disable-next-line no-restricted-syntax -+ get minY() { -+ return this.y; -+ } -+ // eslint-disable-next-line no-restricted-syntax -+ set minY(n) { -+ this.y = n; -+ } -+ // eslint-disable-next-line no-restricted-syntax -+ get midY() { -+ return this.y + this.h / 2; -+ } -+ // eslint-disable-next-line no-restricted-syntax -+ get maxY() { -+ return this.y + this.h; -+ } -+ // eslint-disable-next-line no-restricted-syntax -+ get width() { -+ return this.w; -+ } -+ // eslint-disable-next-line no-restricted-syntax -+ set width(n) { -+ this.w = n; -+ } -+ // eslint-disable-next-line no-restricted-syntax -+ get height() { -+ return this.h; -+ } -+ // eslint-disable-next-line no-restricted-syntax -+ set height(n) { -+ this.h = n; -+ } -+ // eslint-disable-next-line no-restricted-syntax -+ get aspectRatio() { -+ return this.width / this.height; -+ } -+ // eslint-disable-next-line no-restricted-syntax -+ get center() { -+ return new Vec(this.midX, this.midY); -+ } -+ // eslint-disable-next-line no-restricted-syntax -+ set center(v) { -+ this.minX = v.x - this.width / 2; -+ this.minY = v.y - this.height / 2; -+ } -+ // eslint-disable-next-line no-restricted-syntax -+ get corners() { -+ return [ -+ new Vec(this.minX, this.minY), -+ new Vec(this.maxX, this.minY), -+ new Vec(this.maxX, this.maxY), -+ new Vec(this.minX, this.maxY) -+ ]; -+ } -+ // eslint-disable-next-line no-restricted-syntax -+ get cornersAndCenter() { -+ return [ -+ new Vec(this.minX, this.minY), -+ new Vec(this.maxX, this.minY), -+ new Vec(this.maxX, this.maxY), -+ new Vec(this.minX, this.maxY), -+ this.center -+ ]; -+ } -+ // eslint-disable-next-line no-restricted-syntax -+ get sides() { -+ const { corners } = this; -+ return [ -+ [corners[0], corners[1]], -+ [corners[1], corners[2]], -+ [corners[2], corners[3]], -+ [corners[3], corners[0]] -+ ]; -+ } -+ // eslint-disable-next-line no-restricted-syntax -+ get size() { -+ return new Vec(this.w, this.h); -+ } -+ toFixed() { -+ this.x = toPrecision(this.x); -+ this.y = toPrecision(this.y); -+ this.w = toPrecision(this.w); -+ this.h = toPrecision(this.h); -+ return this; -+ } -+ setTo(B) { -+ this.x = B.x; -+ this.y = B.y; -+ this.w = B.w; -+ this.h = B.h; -+ return this; -+ } -+ set(x = 0, y = 0, w = 0, h = 0) { -+ this.x = x; -+ this.y = y; -+ this.w = w; -+ this.h = h; -+ return this; -+ } -+ expand(A) { -+ const minX = Math.min(this.minX, A.minX); -+ const minY = Math.min(this.minY, A.minY); -+ const maxX = Math.max(this.maxX, A.maxX); -+ const maxY = Math.max(this.maxY, A.maxY); -+ this.x = minX; -+ this.y = minY; -+ this.w = maxX - minX; -+ this.h = maxY - minY; -+ return this; -+ } -+ expandBy(n) { -+ this.x -= n; -+ this.y -= n; -+ this.w += n * 2; -+ this.h += n * 2; -+ return this; -+ } -+ scale(n) { -+ this.x /= n; -+ this.y /= n; -+ this.w /= n; -+ this.h /= n; -+ return this; -+ } -+ clone() { -+ const { x, y, w, h } = this; -+ return new Box(x, y, w, h); -+ } -+ translate(delta) { -+ this.x += delta.x; -+ this.y += delta.y; -+ return this; -+ } -+ snapToGrid(size) { -+ const minX = Math.round(this.minX / size) * size; -+ const minY = Math.round(this.minY / size) * size; -+ const maxX = Math.round(this.maxX / size) * size; -+ const maxY = Math.round(this.maxY / size) * size; -+ this.minX = minX; -+ this.minY = minY; -+ this.width = Math.max(1, maxX - minX); -+ this.height = Math.max(1, maxY - minY); -+ } -+ collides(B) { -+ return Box.Collides(this, B); -+ } -+ contains(B) { -+ return Box.Contains(this, B); -+ } -+ includes(B) { -+ return Box.Includes(this, B); -+ } -+ containsPoint(V, margin = 0) { -+ return Box.ContainsPoint(this, V, margin); -+ } -+ getHandlePoint(handle) { -+ switch (handle) { -+ case "top_left": -+ return new Vec(this.minX, this.minY); -+ case "top_right": -+ return new Vec(this.maxX, this.minY); -+ case "bottom_left": -+ return new Vec(this.minX, this.maxY); -+ case "bottom_right": -+ return new Vec(this.maxX, this.maxY); -+ case "top": -+ return new Vec(this.midX, this.minY); -+ case "right": -+ return new Vec(this.maxX, this.midY); -+ case "bottom": -+ return new Vec(this.midX, this.maxY); -+ case "left": -+ return new Vec(this.minX, this.midY); -+ } -+ } -+ toJson() { -+ return { x: this.minX, y: this.minY, w: this.w, h: this.h }; -+ } -+ resize(handle, dx, dy) { -+ const { minX: a0x, minY: a0y, maxX: a1x, maxY: a1y } = this; -+ let { minX: b0x, minY: b0y, maxX: b1x, maxY: b1y } = this; -+ switch (handle) { -+ case "left": -+ case "top_left": -+ case "bottom_left": { -+ b0x += dx; -+ break; -+ } -+ case "right": -+ case "top_right": -+ case "bottom_right": { -+ b1x += dx; -+ break; -+ } -+ } -+ switch (handle) { -+ case "top": -+ case "top_left": -+ case "top_right": { -+ b0y += dy; -+ break; -+ } -+ case "bottom": -+ case "bottom_left": -+ case "bottom_right": { -+ b1y += dy; -+ break; -+ } -+ } -+ const scaleX = (b1x - b0x) / (a1x - a0x); -+ const scaleY = (b1y - b0y) / (a1y - a0y); -+ const flipX = scaleX < 0; -+ const flipY = scaleY < 0; -+ if (flipX) { -+ const t = b1x; -+ b1x = b0x; -+ b0x = t; -+ } -+ if (flipY) { -+ const t = b1y; -+ b1y = b0y; -+ b0y = t; -+ } -+ this.minX = b0x; -+ this.minY = b0y; -+ this.width = Math.abs(b1x - b0x); -+ this.height = Math.abs(b1y - b0y); -+ } -+ union(box) { -+ const minX = Math.min(this.minX, box.x); -+ const minY = Math.min(this.minY, box.y); -+ const maxX = Math.max(this.maxX, box.w + box.x); -+ const maxY = Math.max(this.maxY, box.h + box.y); -+ this.x = minX; -+ this.y = minY; -+ this.width = maxX - minX; -+ this.height = maxY - minY; -+ return this; -+ } -+ static From(box) { -+ return new Box(box.x, box.y, box.w, box.h); -+ } -+ static FromCenter(center, size) { -+ return new Box(center.x - size.x / 2, center.y - size.y / 2, size.x, size.y); -+ } -+ static FromPoints(points) { -+ if (points.length === 0) return new Box(); -+ let minX = Infinity; -+ let minY = Infinity; -+ let maxX = -Infinity; -+ let maxY = -Infinity; -+ let point; -+ for (let i = 0, n = points.length; i < n; i++) { -+ point = points[i]; -+ minX = Math.min(point.x, minX); -+ minY = Math.min(point.y, minY); -+ maxX = Math.max(point.x, maxX); -+ maxY = Math.max(point.y, maxY); -+ } -+ return new Box(minX, minY, maxX - minX, maxY - minY); -+ } -+ static Expand(A, B) { -+ const minX = Math.min(B.minX, A.minX); -+ const minY = Math.min(B.minY, A.minY); -+ const maxX = Math.max(B.maxX, A.maxX); -+ const maxY = Math.max(B.maxY, A.maxY); -+ return new Box(minX, minY, maxX - minX, maxY - minY); -+ } -+ static ExpandBy(A, n) { -+ return new Box(A.minX - n, A.minY - n, A.width + n * 2, A.height + n * 2); -+ } -+ static Collides(A, B) { -+ return !(A.maxX < B.minX || A.minX > B.maxX || A.maxY < B.minY || A.minY > B.maxY); -+ } -+ static Contains(A, B) { -+ return A.minX < B.minX && A.minY < B.minY && A.maxY > B.maxY && A.maxX > B.maxX; -+ } -+ static Includes(A, B) { -+ return Box.Collides(A, B) || Box.Contains(A, B); -+ } -+ static ContainsPoint(A, B, margin = 0) { -+ return !(B.x < A.minX - margin || B.y < A.minY - margin || B.x > A.maxX + margin || B.y > A.maxY + margin); -+ } -+ static Common(boxes) { -+ let minX = Infinity; -+ let minY = Infinity; -+ let maxX = -Infinity; -+ let maxY = -Infinity; -+ for (let i = 0; i < boxes.length; i++) { -+ const B = boxes[i]; -+ minX = Math.min(minX, B.minX); -+ minY = Math.min(minY, B.minY); -+ maxX = Math.max(maxX, B.maxX); -+ maxY = Math.max(maxY, B.maxY); -+ } -+ return new Box(minX, minY, maxX - minX, maxY - minY); -+ } -+ static Sides(A, inset = 0) { -+ const { corners } = A; -+ if (inset) { -+ } -+ return [ -+ [corners[0], corners[1]], -+ [corners[1], corners[2]], -+ [corners[2], corners[3]], -+ [corners[3], corners[0]] -+ ]; -+ } -+ static Resize(box, handle, dx, dy, isAspectRatioLocked = false) { -+ const { minX: a0x, minY: a0y, maxX: a1x, maxY: a1y } = box; -+ let { minX: b0x, minY: b0y, maxX: b1x, maxY: b1y } = box; -+ switch (handle) { -+ case "left": -+ case "top_left": -+ case "bottom_left": { -+ b0x += dx; -+ break; -+ } -+ case "right": -+ case "top_right": -+ case "bottom_right": { -+ b1x += dx; -+ break; -+ } -+ } -+ switch (handle) { -+ case "top": -+ case "top_left": -+ case "top_right": { -+ b0y += dy; -+ break; -+ } -+ case "bottom": -+ case "bottom_left": -+ case "bottom_right": { -+ b1y += dy; -+ break; -+ } -+ } -+ const scaleX = (b1x - b0x) / (a1x - a0x); -+ const scaleY = (b1y - b0y) / (a1y - a0y); -+ const flipX = scaleX < 0; -+ const flipY = scaleY < 0; -+ if (isAspectRatioLocked) { -+ const aspectRatio = (a1x - a0x) / (a1y - a0y); -+ const bw = Math.abs(b1x - b0x); -+ const bh = Math.abs(b1y - b0y); -+ const tw = bw * (scaleY < 0 ? 1 : -1) * (1 / aspectRatio); -+ const th = bh * (scaleX < 0 ? 1 : -1) * aspectRatio; -+ const isTall = aspectRatio < bw / bh; -+ switch (handle) { -+ case "top_left": { -+ if (isTall) b0y = b1y + tw; -+ else b0x = b1x + th; -+ break; -+ } -+ case "top_right": { -+ if (isTall) b0y = b1y + tw; -+ else b1x = b0x - th; -+ break; -+ } -+ case "bottom_right": { -+ if (isTall) b1y = b0y - tw; -+ else b1x = b0x - th; -+ break; -+ } -+ case "bottom_left": { -+ if (isTall) b1y = b0y - tw; -+ else b0x = b1x + th; -+ break; -+ } -+ case "bottom": -+ case "top": { -+ const m = (b0x + b1x) / 2; -+ const w = bh * aspectRatio; -+ b0x = m - w / 2; -+ b1x = m + w / 2; -+ break; -+ } -+ case "left": -+ case "right": { -+ const m = (b0y + b1y) / 2; -+ const h = bw / aspectRatio; -+ b0y = m - h / 2; -+ b1y = m + h / 2; -+ break; -+ } -+ } -+ } -+ if (flipX) { -+ const t = b1x; -+ b1x = b0x; -+ b0x = t; -+ } -+ if (flipY) { -+ const t = b1y; -+ b1y = b0y; -+ b0y = t; -+ } -+ const final = new Box(b0x, b0y, Math.abs(b1x - b0x), Math.abs(b1y - b0y)); -+ return { -+ box: final, -+ scaleX: +(final.width / box.width * (scaleX > 0 ? 1 : -1)).toFixed(5), -+ scaleY: +(final.height / box.height * (scaleY > 0 ? 1 : -1)).toFixed(5) -+ }; -+ } -+ equals(other) { -+ return Box.Equals(this, other); -+ } -+ static Equals(a, b) { -+ return b.x === a.x && b.y === a.y && b.w === a.w && b.h === a.h; -+ } -+ zeroFix() { -+ this.w = Math.max(1, this.w); -+ this.h = Math.max(1, this.h); -+ return this; -+ } -+ static ZeroFix(other) { -+ return new Box(other.x, other.y, Math.max(1, other.w), Math.max(1, other.h)); -+ } -+} -+function flipSelectionHandleY(handle) { -+ switch (handle) { -+ case "top": -+ return "bottom"; -+ case "bottom": -+ return "top"; -+ case "top_left": -+ return "bottom_left"; -+ case "top_right": -+ return "bottom_right"; -+ case "bottom_left": -+ return "top_left"; -+ case "bottom_right": -+ return "top_right"; -+ default: -+ return handle; -+ } -+} -+function flipSelectionHandleX(handle) { -+ switch (handle) { -+ case "left": -+ return "right"; -+ case "right": -+ return "left"; -+ case "top_left": -+ return "top_right"; -+ case "top_right": -+ return "top_left"; -+ case "bottom_left": -+ return "bottom_right"; -+ case "bottom_right": -+ return "bottom_left"; -+ default: -+ return handle; -+ } -+} -+const ORDERED_SELECTION_HANDLES = [ -+ "top", -+ "top_right", -+ "right", -+ "bottom_right", -+ "bottom", -+ "bottom_left", -+ "left", -+ "top_left" -+]; -+function rotateSelectionHandle(handle, rotation) { -+ rotation = rotation % PI2; -+ const numSteps = Math.round(rotation / (PI / 4)); -+ const currentIndex = ORDERED_SELECTION_HANDLES.indexOf(handle); -+ return ORDERED_SELECTION_HANDLES[(currentIndex + numSteps) % ORDERED_SELECTION_HANDLES.length]; -+} -+function isSelectionCorner(selection) { -+ return selection === "top_left" || selection === "top_right" || selection === "bottom_right" || selection === "bottom_left"; -+} -+const ROTATE_CORNER_TO_SELECTION_CORNER = { -+ top_left_rotate: "top_left", -+ top_right_rotate: "top_right", -+ bottom_right_rotate: "bottom_right", -+ bottom_left_rotate: "bottom_left", -+ mobile_rotate: "top_left" -+}; -+export { -+ Box, -+ ROTATE_CORNER_TO_SELECTION_CORNER, -+ flipSelectionHandleX, -+ flipSelectionHandleY, -+ isSelectionCorner, -+ rotateSelectionHandle -+}; -+//# sourceMappingURL=Box.mjs.map -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/primitives/Box.mjs.map b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/primitives/Box.mjs.map -new file mode 100644 -index 0000000..8c652ba ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/primitives/Box.mjs.map -@@ -0,0 +1,7 @@ -+{ -+ "version": 3, -+ "sources": ["../../../src/lib/primitives/Box.ts"], -+ "sourcesContent": ["import { BoxModel } from '@tldraw/tlschema'\nimport { Vec, VecLike } from './Vec'\nimport { PI, PI2, toPrecision } from './utils'\n\n/** @public */\nexport type BoxLike = BoxModel | Box\n\n/** @public */\nexport type SelectionEdge = 'top' | 'right' | 'bottom' | 'left'\n\n/** @public */\nexport type SelectionCorner = 'top_left' | 'top_right' | 'bottom_right' | 'bottom_left'\n\n/** @public */\nexport type SelectionHandle = SelectionEdge | SelectionCorner\n\n/** @public */\nexport type RotateCorner =\n\t| 'top_left_rotate'\n\t| 'top_right_rotate'\n\t| 'bottom_right_rotate'\n\t| 'bottom_left_rotate'\n\t| 'mobile_rotate'\n\n/** @public */\nexport class Box {\n\tconstructor(x = 0, y = 0, w = 0, h = 0) {\n\t\tthis.x = x\n\t\tthis.y = y\n\t\tthis.w = w\n\t\tthis.h = h\n\t}\n\n\tx = 0\n\ty = 0\n\tw = 0\n\th = 0\n\n\t// eslint-disable-next-line no-restricted-syntax\n\tget point() {\n\t\treturn new Vec(this.x, this.y)\n\t}\n\n\t// eslint-disable-next-line no-restricted-syntax\n\tset point(val: Vec) {\n\t\tthis.x = val.x\n\t\tthis.y = val.y\n\t}\n\n\t// eslint-disable-next-line no-restricted-syntax\n\tget minX() {\n\t\treturn this.x\n\t}\n\n\t// eslint-disable-next-line no-restricted-syntax\n\tset minX(n: number) {\n\t\tthis.x = n\n\t}\n\n\t// eslint-disable-next-line no-restricted-syntax\n\tget midX() {\n\t\treturn this.x + this.w / 2\n\t}\n\n\t// eslint-disable-next-line no-restricted-syntax\n\tget maxX() {\n\t\treturn this.x + this.w\n\t}\n\n\t// eslint-disable-next-line no-restricted-syntax\n\tget minY() {\n\t\treturn this.y\n\t}\n\n\t// eslint-disable-next-line no-restricted-syntax\n\tset minY(n: number) {\n\t\tthis.y = n\n\t}\n\n\t// eslint-disable-next-line no-restricted-syntax\n\tget midY() {\n\t\treturn this.y + this.h / 2\n\t}\n\n\t// eslint-disable-next-line no-restricted-syntax\n\tget maxY() {\n\t\treturn this.y + this.h\n\t}\n\n\t// eslint-disable-next-line no-restricted-syntax\n\tget width() {\n\t\treturn this.w\n\t}\n\n\t// eslint-disable-next-line no-restricted-syntax\n\tset width(n: number) {\n\t\tthis.w = n\n\t}\n\n\t// eslint-disable-next-line no-restricted-syntax\n\tget height() {\n\t\treturn this.h\n\t}\n\n\t// eslint-disable-next-line no-restricted-syntax\n\tset height(n: number) {\n\t\tthis.h = n\n\t}\n\n\t// eslint-disable-next-line no-restricted-syntax\n\tget aspectRatio() {\n\t\treturn this.width / this.height\n\t}\n\n\t// eslint-disable-next-line no-restricted-syntax\n\tget center() {\n\t\treturn new Vec(this.midX, this.midY)\n\t}\n\n\t// eslint-disable-next-line no-restricted-syntax\n\tset center(v: Vec) {\n\t\tthis.minX = v.x - this.width / 2\n\t\tthis.minY = v.y - this.height / 2\n\t}\n\n\t// eslint-disable-next-line no-restricted-syntax\n\tget corners() {\n\t\treturn [\n\t\t\tnew Vec(this.minX, this.minY),\n\t\t\tnew Vec(this.maxX, this.minY),\n\t\t\tnew Vec(this.maxX, this.maxY),\n\t\t\tnew Vec(this.minX, this.maxY),\n\t\t]\n\t}\n\n\t// eslint-disable-next-line no-restricted-syntax\n\tget cornersAndCenter() {\n\t\treturn [\n\t\t\tnew Vec(this.minX, this.minY),\n\t\t\tnew Vec(this.maxX, this.minY),\n\t\t\tnew Vec(this.maxX, this.maxY),\n\t\t\tnew Vec(this.minX, this.maxY),\n\t\t\tthis.center,\n\t\t]\n\t}\n\n\t// eslint-disable-next-line no-restricted-syntax\n\tget sides(): Array<[Vec, Vec]> {\n\t\tconst { corners } = this\n\t\treturn [\n\t\t\t[corners[0], corners[1]],\n\t\t\t[corners[1], corners[2]],\n\t\t\t[corners[2], corners[3]],\n\t\t\t[corners[3], corners[0]],\n\t\t]\n\t}\n\n\t// eslint-disable-next-line no-restricted-syntax\n\tget size(): Vec {\n\t\treturn new Vec(this.w, this.h)\n\t}\n\n\ttoFixed() {\n\t\tthis.x = toPrecision(this.x)\n\t\tthis.y = toPrecision(this.y)\n\t\tthis.w = toPrecision(this.w)\n\t\tthis.h = toPrecision(this.h)\n\t\treturn this\n\t}\n\n\tsetTo(B: Box) {\n\t\tthis.x = B.x\n\t\tthis.y = B.y\n\t\tthis.w = B.w\n\t\tthis.h = B.h\n\t\treturn this\n\t}\n\n\tset(x = 0, y = 0, w = 0, h = 0) {\n\t\tthis.x = x\n\t\tthis.y = y\n\t\tthis.w = w\n\t\tthis.h = h\n\t\treturn this\n\t}\n\n\texpand(A: Box) {\n\t\tconst minX = Math.min(this.minX, A.minX)\n\t\tconst minY = Math.min(this.minY, A.minY)\n\t\tconst maxX = Math.max(this.maxX, A.maxX)\n\t\tconst maxY = Math.max(this.maxY, A.maxY)\n\n\t\tthis.x = minX\n\t\tthis.y = minY\n\t\tthis.w = maxX - minX\n\t\tthis.h = maxY - minY\n\t\treturn this\n\t}\n\n\texpandBy(n: number) {\n\t\tthis.x -= n\n\t\tthis.y -= n\n\t\tthis.w += n * 2\n\t\tthis.h += n * 2\n\t\treturn this\n\t}\n\n\tscale(n: number) {\n\t\tthis.x /= n\n\t\tthis.y /= n\n\t\tthis.w /= n\n\t\tthis.h /= n\n\t\treturn this\n\t}\n\n\tclone() {\n\t\tconst { x, y, w, h } = this\n\t\treturn new Box(x, y, w, h)\n\t}\n\n\ttranslate(delta: VecLike) {\n\t\tthis.x += delta.x\n\t\tthis.y += delta.y\n\t\treturn this\n\t}\n\n\tsnapToGrid(size: number) {\n\t\tconst minX = Math.round(this.minX / size) * size\n\t\tconst minY = Math.round(this.minY / size) * size\n\t\tconst maxX = Math.round(this.maxX / size) * size\n\t\tconst maxY = Math.round(this.maxY / size) * size\n\t\tthis.minX = minX\n\t\tthis.minY = minY\n\t\tthis.width = Math.max(1, maxX - minX)\n\t\tthis.height = Math.max(1, maxY - minY)\n\t}\n\n\tcollides(B: Box) {\n\t\treturn Box.Collides(this, B)\n\t}\n\n\tcontains(B: Box) {\n\t\treturn Box.Contains(this, B)\n\t}\n\n\tincludes(B: Box) {\n\t\treturn Box.Includes(this, B)\n\t}\n\n\tcontainsPoint(V: VecLike, margin = 0) {\n\t\treturn Box.ContainsPoint(this, V, margin)\n\t}\n\n\tgetHandlePoint(handle: SelectionCorner | SelectionEdge) {\n\t\tswitch (handle) {\n\t\t\tcase 'top_left':\n\t\t\t\treturn new Vec(this.minX, this.minY)\n\t\t\tcase 'top_right':\n\t\t\t\treturn new Vec(this.maxX, this.minY)\n\t\t\tcase 'bottom_left':\n\t\t\t\treturn new Vec(this.minX, this.maxY)\n\t\t\tcase 'bottom_right':\n\t\t\t\treturn new Vec(this.maxX, this.maxY)\n\t\t\tcase 'top':\n\t\t\t\treturn new Vec(this.midX, this.minY)\n\t\t\tcase 'right':\n\t\t\t\treturn new Vec(this.maxX, this.midY)\n\t\t\tcase 'bottom':\n\t\t\t\treturn new Vec(this.midX, this.maxY)\n\t\t\tcase 'left':\n\t\t\t\treturn new Vec(this.minX, this.midY)\n\t\t}\n\t}\n\n\ttoJson(): BoxModel {\n\t\treturn { x: this.minX, y: this.minY, w: this.w, h: this.h }\n\t}\n\n\tresize(handle: SelectionCorner | SelectionEdge | string, dx: number, dy: number) {\n\t\tconst { minX: a0x, minY: a0y, maxX: a1x, maxY: a1y } = this\n\t\tlet { minX: b0x, minY: b0y, maxX: b1x, maxY: b1y } = this\n\n\t\t// Use the delta to adjust the new box by changing its corners.\n\t\t// The dragging handle (corner or edge) will determine which\n\t\t// corners should change.\n\t\tswitch (handle) {\n\t\t\tcase 'left':\n\t\t\tcase 'top_left':\n\t\t\tcase 'bottom_left': {\n\t\t\t\tb0x += dx\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'right':\n\t\t\tcase 'top_right':\n\t\t\tcase 'bottom_right': {\n\t\t\t\tb1x += dx\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tswitch (handle) {\n\t\t\tcase 'top':\n\t\t\tcase 'top_left':\n\t\t\tcase 'top_right': {\n\t\t\t\tb0y += dy\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'bottom':\n\t\t\tcase 'bottom_left':\n\t\t\tcase 'bottom_right': {\n\t\t\t\tb1y += dy\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\n\t\tconst scaleX = (b1x - b0x) / (a1x - a0x)\n\t\tconst scaleY = (b1y - b0y) / (a1y - a0y)\n\n\t\tconst flipX = scaleX < 0\n\t\tconst flipY = scaleY < 0\n\n\t\tif (flipX) {\n\t\t\tconst t = b1x\n\t\t\tb1x = b0x\n\t\t\tb0x = t\n\t\t}\n\n\t\tif (flipY) {\n\t\t\tconst t = b1y\n\t\t\tb1y = b0y\n\t\t\tb0y = t\n\t\t}\n\n\t\tthis.minX = b0x\n\t\tthis.minY = b0y\n\t\tthis.width = Math.abs(b1x - b0x)\n\t\tthis.height = Math.abs(b1y - b0y)\n\t}\n\n\tunion(box: BoxModel) {\n\t\tconst minX = Math.min(this.minX, box.x)\n\t\tconst minY = Math.min(this.minY, box.y)\n\t\tconst maxX = Math.max(this.maxX, box.w + box.x)\n\t\tconst maxY = Math.max(this.maxY, box.h + box.y)\n\n\t\tthis.x = minX\n\t\tthis.y = minY\n\t\tthis.width = maxX - minX\n\t\tthis.height = maxY - minY\n\n\t\treturn this\n\t}\n\n\tstatic From(box: BoxModel) {\n\t\treturn new Box(box.x, box.y, box.w, box.h)\n\t}\n\n\tstatic FromCenter(center: VecLike, size: VecLike) {\n\t\treturn new Box(center.x - size.x / 2, center.y - size.y / 2, size.x, size.y)\n\t}\n\n\tstatic FromPoints(points: VecLike[]) {\n\t\tif (points.length === 0) return new Box()\n\t\tlet minX = Infinity\n\t\tlet minY = Infinity\n\t\tlet maxX = -Infinity\n\t\tlet maxY = -Infinity\n\t\tlet point: VecLike\n\t\tfor (let i = 0, n = points.length; i < n; i++) {\n\t\t\tpoint = points[i]\n\t\t\tminX = Math.min(point.x, minX)\n\t\t\tminY = Math.min(point.y, minY)\n\t\t\tmaxX = Math.max(point.x, maxX)\n\t\t\tmaxY = Math.max(point.y, maxY)\n\t\t}\n\n\t\treturn new Box(minX, minY, maxX - minX, maxY - minY)\n\t}\n\n\tstatic Expand(A: Box, B: Box) {\n\t\tconst minX = Math.min(B.minX, A.minX)\n\t\tconst minY = Math.min(B.minY, A.minY)\n\t\tconst maxX = Math.max(B.maxX, A.maxX)\n\t\tconst maxY = Math.max(B.maxY, A.maxY)\n\n\t\treturn new Box(minX, minY, maxX - minX, maxY - minY)\n\t}\n\n\tstatic ExpandBy(A: Box, n: number) {\n\t\treturn new Box(A.minX - n, A.minY - n, A.width + n * 2, A.height + n * 2)\n\t}\n\n\tstatic Collides(A: Box, B: Box) {\n\t\treturn !(A.maxX < B.minX || A.minX > B.maxX || A.maxY < B.minY || A.minY > B.maxY)\n\t}\n\n\tstatic Contains(A: Box, B: Box) {\n\t\treturn A.minX < B.minX && A.minY < B.minY && A.maxY > B.maxY && A.maxX > B.maxX\n\t}\n\n\tstatic Includes(A: Box, B: Box) {\n\t\treturn Box.Collides(A, B) || Box.Contains(A, B)\n\t}\n\n\tstatic ContainsPoint(A: Box, B: VecLike, margin = 0) {\n\t\treturn !(\n\t\t\tB.x < A.minX - margin ||\n\t\t\tB.y < A.minY - margin ||\n\t\t\tB.x > A.maxX + margin ||\n\t\t\tB.y > A.maxY + margin\n\t\t)\n\t}\n\n\tstatic Common(boxes: Box[]) {\n\t\tlet minX = Infinity\n\t\tlet minY = Infinity\n\t\tlet maxX = -Infinity\n\t\tlet maxY = -Infinity\n\n\t\tfor (let i = 0; i < boxes.length; i++) {\n\t\t\tconst B = boxes[i]\n\t\t\tminX = Math.min(minX, B.minX)\n\t\t\tminY = Math.min(minY, B.minY)\n\t\t\tmaxX = Math.max(maxX, B.maxX)\n\t\t\tmaxY = Math.max(maxY, B.maxY)\n\t\t}\n\n\t\treturn new Box(minX, minY, maxX - minX, maxY - minY)\n\t}\n\n\tstatic Sides(A: Box, inset = 0) {\n\t\tconst { corners } = A\n\t\tif (inset) {\n\t\t\t// TODO: Inset the corners by the inset amount.\n\t\t}\n\n\t\treturn [\n\t\t\t[corners[0], corners[1]],\n\t\t\t[corners[1], corners[2]],\n\t\t\t[corners[2], corners[3]],\n\t\t\t[corners[3], corners[0]],\n\t\t]\n\t}\n\n\tstatic Resize(\n\t\tbox: Box,\n\t\thandle: SelectionCorner | SelectionEdge | string,\n\t\tdx: number,\n\t\tdy: number,\n\t\tisAspectRatioLocked = false\n\t) {\n\t\tconst { minX: a0x, minY: a0y, maxX: a1x, maxY: a1y } = box\n\t\tlet { minX: b0x, minY: b0y, maxX: b1x, maxY: b1y } = box\n\n\t\t// Use the delta to adjust the new box by changing its corners.\n\t\t// The dragging handle (corner or edge) will determine which\n\t\t// corners should change.\n\t\tswitch (handle) {\n\t\t\tcase 'left':\n\t\t\tcase 'top_left':\n\t\t\tcase 'bottom_left': {\n\t\t\t\tb0x += dx\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'right':\n\t\t\tcase 'top_right':\n\t\t\tcase 'bottom_right': {\n\t\t\t\tb1x += dx\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tswitch (handle) {\n\t\t\tcase 'top':\n\t\t\tcase 'top_left':\n\t\t\tcase 'top_right': {\n\t\t\t\tb0y += dy\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'bottom':\n\t\t\tcase 'bottom_left':\n\t\t\tcase 'bottom_right': {\n\t\t\t\tb1y += dy\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\n\t\tconst scaleX = (b1x - b0x) / (a1x - a0x)\n\t\tconst scaleY = (b1y - b0y) / (a1y - a0y)\n\n\t\tconst flipX = scaleX < 0\n\t\tconst flipY = scaleY < 0\n\n\t\t/*\n 2. Aspect ratio\n If the aspect ratio is locked, adjust the corners so that the\n new box's aspect ratio matches the original aspect ratio.\n */\n\t\tif (isAspectRatioLocked) {\n\t\t\tconst aspectRatio = (a1x - a0x) / (a1y - a0y)\n\t\t\tconst bw = Math.abs(b1x - b0x)\n\t\t\tconst bh = Math.abs(b1y - b0y)\n\t\t\tconst tw = bw * (scaleY < 0 ? 1 : -1) * (1 / aspectRatio)\n\t\t\tconst th = bh * (scaleX < 0 ? 1 : -1) * aspectRatio\n\t\t\tconst isTall = aspectRatio < bw / bh\n\n\t\t\tswitch (handle) {\n\t\t\t\tcase 'top_left': {\n\t\t\t\t\tif (isTall) b0y = b1y + tw\n\t\t\t\t\telse b0x = b1x + th\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase 'top_right': {\n\t\t\t\t\tif (isTall) b0y = b1y + tw\n\t\t\t\t\telse b1x = b0x - th\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase 'bottom_right': {\n\t\t\t\t\tif (isTall) b1y = b0y - tw\n\t\t\t\t\telse b1x = b0x - th\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase 'bottom_left': {\n\t\t\t\t\tif (isTall) b1y = b0y - tw\n\t\t\t\t\telse b0x = b1x + th\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase 'bottom':\n\t\t\t\tcase 'top': {\n\t\t\t\t\tconst m = (b0x + b1x) / 2\n\t\t\t\t\tconst w = bh * aspectRatio\n\t\t\t\t\tb0x = m - w / 2\n\t\t\t\t\tb1x = m + w / 2\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase 'left':\n\t\t\t\tcase 'right': {\n\t\t\t\t\tconst m = (b0y + b1y) / 2\n\t\t\t\t\tconst h = bw / aspectRatio\n\t\t\t\t\tb0y = m - h / 2\n\t\t\t\t\tb1y = m + h / 2\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (flipX) {\n\t\t\tconst t = b1x\n\t\t\tb1x = b0x\n\t\t\tb0x = t\n\t\t}\n\n\t\tif (flipY) {\n\t\t\tconst t = b1y\n\t\t\tb1y = b0y\n\t\t\tb0y = t\n\t\t}\n\n\t\tconst final = new Box(b0x, b0y, Math.abs(b1x - b0x), Math.abs(b1y - b0y))\n\n\t\treturn {\n\t\t\tbox: final,\n\t\t\tscaleX: +((final.width / box.width) * (scaleX > 0 ? 1 : -1)).toFixed(5),\n\t\t\tscaleY: +((final.height / box.height) * (scaleY > 0 ? 1 : -1)).toFixed(5),\n\t\t}\n\t}\n\n\tequals(other: Box | BoxModel) {\n\t\treturn Box.Equals(this, other)\n\t}\n\n\tstatic Equals(a: Box | BoxModel, b: Box | BoxModel) {\n\t\treturn b.x === a.x && b.y === a.y && b.w === a.w && b.h === a.h\n\t}\n\n\tzeroFix() {\n\t\tthis.w = Math.max(1, this.w)\n\t\tthis.h = Math.max(1, this.h)\n\t\treturn this\n\t}\n\n\tstatic ZeroFix(other: Box | BoxModel) {\n\t\treturn new Box(other.x, other.y, Math.max(1, other.w), Math.max(1, other.h))\n\t}\n}\n\n/** @public */\nexport function flipSelectionHandleY(handle: SelectionHandle) {\n\tswitch (handle) {\n\t\tcase 'top':\n\t\t\treturn 'bottom'\n\t\tcase 'bottom':\n\t\t\treturn 'top'\n\t\tcase 'top_left':\n\t\t\treturn 'bottom_left'\n\t\tcase 'top_right':\n\t\t\treturn 'bottom_right'\n\t\tcase 'bottom_left':\n\t\t\treturn 'top_left'\n\t\tcase 'bottom_right':\n\t\t\treturn 'top_right'\n\t\tdefault:\n\t\t\treturn handle\n\t}\n}\n\n/** @public */\nexport function flipSelectionHandleX(handle: SelectionHandle) {\n\tswitch (handle) {\n\t\tcase 'left':\n\t\t\treturn 'right'\n\t\tcase 'right':\n\t\t\treturn 'left'\n\t\tcase 'top_left':\n\t\t\treturn 'top_right'\n\t\tcase 'top_right':\n\t\t\treturn 'top_left'\n\t\tcase 'bottom_left':\n\t\t\treturn 'bottom_right'\n\t\tcase 'bottom_right':\n\t\t\treturn 'bottom_left'\n\t\tdefault:\n\t\t\treturn handle\n\t}\n}\n\nconst ORDERED_SELECTION_HANDLES = [\n\t'top',\n\t'top_right',\n\t'right',\n\t'bottom_right',\n\t'bottom',\n\t'bottom_left',\n\t'left',\n\t'top_left',\n] as const\n\n/** @public */\nexport function rotateSelectionHandle(handle: SelectionHandle, rotation: number): SelectionHandle {\n\t// first find out how many tau we need to rotate by\n\trotation = rotation % PI2\n\tconst numSteps = Math.round(rotation / (PI / 4))\n\n\tconst currentIndex = ORDERED_SELECTION_HANDLES.indexOf(handle)\n\treturn ORDERED_SELECTION_HANDLES[(currentIndex + numSteps) % ORDERED_SELECTION_HANDLES.length]\n}\n\n/** @public */\nexport function isSelectionCorner(selection: string): selection is SelectionCorner {\n\treturn (\n\t\tselection === 'top_left' ||\n\t\tselection === 'top_right' ||\n\t\tselection === 'bottom_right' ||\n\t\tselection === 'bottom_left'\n\t)\n}\n\n/** @public */\nexport const ROTATE_CORNER_TO_SELECTION_CORNER = {\n\ttop_left_rotate: 'top_left',\n\ttop_right_rotate: 'top_right',\n\tbottom_right_rotate: 'bottom_right',\n\tbottom_left_rotate: 'bottom_left',\n\tmobile_rotate: 'top_left',\n} as const\n"], -+ "mappings": "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", -+ "names": [] -+} -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/primitives/Mat.mjs b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/primitives/Mat.mjs -new file mode 100644 -index 0000000..5744714 ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/primitives/Mat.mjs -@@ -0,0 +1,244 @@ -+import { Box } from "./Box.mjs"; -+import { clampRadians, HALF_PI, toDomPrecision } from "./utils.mjs"; -+import { Vec } from "./Vec.mjs"; -+class Mat { -+ constructor(a, b, c, d, e, f) { -+ this.a = a; -+ this.b = b; -+ this.c = c; -+ this.d = d; -+ this.e = e; -+ this.f = f; -+ } -+ a = 1; -+ b = 0; -+ c = 0; -+ d = 1; -+ e = 0; -+ f = 0; -+ equals(m) { -+ return this === m || this.a === m.a && this.b === m.b && this.c === m.c && this.d === m.d && this.e === m.e && this.f === m.f; -+ } -+ identity() { -+ this.a = 1; -+ this.b = 0; -+ this.c = 0; -+ this.d = 1; -+ this.e = 0; -+ this.f = 0; -+ return this; -+ } -+ multiply(m) { -+ const m2 = m; -+ const { a, b, c, d, e, f } = this; -+ this.a = a * m2.a + c * m2.b; -+ this.c = a * m2.c + c * m2.d; -+ this.e = a * m2.e + c * m2.f + e; -+ this.b = b * m2.a + d * m2.b; -+ this.d = b * m2.c + d * m2.d; -+ this.f = b * m2.e + d * m2.f + f; -+ return this; -+ } -+ rotate(r, cx, cy) { -+ if (r === 0) return this; -+ if (cx === void 0) return this.multiply(Mat.Rotate(r)); -+ return this.translate(cx, cy).multiply(Mat.Rotate(r)).translate(-cx, -cy); -+ } -+ translate(x, y) { -+ return this.multiply(Mat.Translate(x, y)); -+ } -+ scale(x, y) { -+ return this.multiply(Mat.Scale(x, y)); -+ } -+ invert() { -+ const { a, b, c, d, e, f } = this; -+ const denom = a * d - b * c; -+ this.a = d / denom; -+ this.b = b / -denom; -+ this.c = c / -denom; -+ this.d = a / denom; -+ this.e = (d * e - c * f) / -denom; -+ this.f = (b * e - a * f) / denom; -+ return this; -+ } -+ applyToPoint(point) { -+ return Mat.applyToPoint(this, point); -+ } -+ applyToPoints(points) { -+ return Mat.applyToPoints(this, points); -+ } -+ rotation() { -+ return Mat.Rotation(this); -+ } -+ point() { -+ return Mat.Point(this); -+ } -+ decomposed() { -+ return Mat.Decompose(this); -+ } -+ toCssString() { -+ return Mat.toCssString(this); -+ } -+ setTo(model) { -+ Object.assign(this, model); -+ return this; -+ } -+ decompose() { -+ return Mat.Decompose(this); -+ } -+ clone() { -+ return new Mat(this.a, this.b, this.c, this.d, this.e, this.f); -+ } -+ /* --------------------- Static --------------------- */ -+ static Identity() { -+ return new Mat(1, 0, 0, 1, 0, 0); -+ } -+ static Translate(x, y) { -+ return new Mat(1, 0, 0, 1, x, y); -+ } -+ static Rotate(r, cx, cy) { -+ if (r === 0) return Mat.Identity(); -+ const cosAngle = Math.cos(r); -+ const sinAngle = Math.sin(r); -+ const rotationMatrix = new Mat(cosAngle, sinAngle, -sinAngle, cosAngle, 0, 0); -+ if (cx === void 0) return rotationMatrix; -+ return Mat.Compose(Mat.Translate(cx, cy), rotationMatrix, Mat.Translate(-cx, -cy)); -+ } -+ static Scale(x, y, cx, cy) { -+ const scaleMatrix = new Mat(x, 0, 0, y, 0, 0); -+ if (cx === void 0) return scaleMatrix; -+ return Mat.Compose(Mat.Translate(cx, cy), scaleMatrix, Mat.Translate(-cx, -cy)); -+ } -+ static Multiply(m1, m2) { -+ return { -+ a: m1.a * m2.a + m1.c * m2.b, -+ c: m1.a * m2.c + m1.c * m2.d, -+ e: m1.a * m2.e + m1.c * m2.f + m1.e, -+ b: m1.b * m2.a + m1.d * m2.b, -+ d: m1.b * m2.c + m1.d * m2.d, -+ f: m1.b * m2.e + m1.d * m2.f + m1.f -+ }; -+ } -+ static Inverse(m) { -+ const denom = m.a * m.d - m.b * m.c; -+ return { -+ a: m.d / denom, -+ b: m.b / -denom, -+ c: m.c / -denom, -+ d: m.a / denom, -+ e: (m.d * m.e - m.c * m.f) / -denom, -+ f: (m.b * m.e - m.a * m.f) / denom -+ }; -+ } -+ static Absolute(m) { -+ const denom = m.a * m.d - m.b * m.c; -+ return { -+ a: m.d / denom, -+ b: m.b / -denom, -+ c: m.c / -denom, -+ d: m.a / denom, -+ e: (m.d * m.e - m.c * m.f) / denom, -+ f: (m.b * m.e - m.a * m.f) / -denom -+ }; -+ } -+ static Compose(...matrices) { -+ const matrix = Mat.Identity(); -+ for (let i = 0, n = matrices.length; i < n; i++) { -+ matrix.multiply(matrices[i]); -+ } -+ return matrix; -+ } -+ static Point(m) { -+ return new Vec(m.e, m.f); -+ } -+ static Rotation(m) { -+ let rotation; -+ if (m.a !== 0 || m.c !== 0) { -+ const hypotAc = (m.a * m.a + m.c * m.c) ** 0.5; -+ rotation = Math.acos(m.a / hypotAc) * (m.c > 0 ? -1 : 1); -+ } else if (m.b !== 0 || m.d !== 0) { -+ const hypotBd = (m.b * m.b + m.d * m.d) ** 0.5; -+ rotation = HALF_PI + Math.acos(m.b / hypotBd) * (m.d > 0 ? -1 : 1); -+ } else { -+ rotation = 0; -+ } -+ return clampRadians(rotation); -+ } -+ static Decompose(m) { -+ let scaleX, scaleY, rotation; -+ if (m.a !== 0 || m.c !== 0) { -+ const hypotAc = (m.a * m.a + m.c * m.c) ** 0.5; -+ scaleX = hypotAc; -+ scaleY = (m.a * m.d - m.b * m.c) / hypotAc; -+ rotation = Math.acos(m.a / hypotAc) * (m.c > 0 ? -1 : 1); -+ } else if (m.b !== 0 || m.d !== 0) { -+ const hypotBd = (m.b * m.b + m.d * m.d) ** 0.5; -+ scaleX = (m.a * m.d - m.b * m.c) / hypotBd; -+ scaleY = hypotBd; -+ rotation = HALF_PI + Math.acos(m.b / hypotBd) * (m.d > 0 ? -1 : 1); -+ } else { -+ scaleX = 0; -+ scaleY = 0; -+ rotation = 0; -+ } -+ return { -+ x: m.e, -+ y: m.f, -+ scaleX, -+ scaleY, -+ rotation: clampRadians(rotation) -+ }; -+ } -+ static Smooth(m, precision = 1e10) { -+ m.a = Math.round(m.a * precision) / precision; -+ m.b = Math.round(m.b * precision) / precision; -+ m.c = Math.round(m.c * precision) / precision; -+ m.d = Math.round(m.d * precision) / precision; -+ m.e = Math.round(m.e * precision) / precision; -+ m.f = Math.round(m.f * precision) / precision; -+ return m; -+ } -+ static toCssString(m) { -+ return `matrix(${toDomPrecision(m.a)}, ${toDomPrecision(m.b)}, ${toDomPrecision( -+ m.c -+ )}, ${toDomPrecision(m.d)}, ${toDomPrecision(m.e)}, ${toDomPrecision(m.f)})`; -+ } -+ static applyToPoint(m, point) { -+ return new Vec( -+ m.a * point.x + m.c * point.y + m.e, -+ m.b * point.x + m.d * point.y + m.f, -+ point.z -+ ); -+ } -+ static applyToXY(m, x, y) { -+ return [m.a * x + m.c * y + m.e, m.b * x + m.d * y + m.f]; -+ } -+ static applyToPoints(m, points) { -+ return points.map( -+ (point) => new Vec(m.a * point.x + m.c * point.y + m.e, m.b * point.x + m.d * point.y + m.f, point.z) -+ ); -+ } -+ static applyToBounds(m, box) { -+ return new Box(m.e + box.minX, m.f + box.minY, box.width, box.height); -+ } -+ static From(m) { -+ return new Mat(m.a, m.b, m.c, m.d, m.e, m.f); -+ } -+ static Cast(m) { -+ return m instanceof Mat ? m : Mat.From(m); -+ } -+} -+function decomposeMatrix(m) { -+ return { -+ x: m.e, -+ y: m.f, -+ scaleX: Math.sqrt(m.a * m.a + m.b * m.b), -+ scaleY: Math.sqrt(m.c * m.c + m.d * m.d), -+ rotation: Math.atan2(m.b, m.a) -+ }; -+} -+export { -+ Mat, -+ decomposeMatrix -+}; -+//# sourceMappingURL=Mat.mjs.map -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/primitives/Mat.mjs.map b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/primitives/Mat.mjs.map -new file mode 100644 -index 0000000..c4a423e ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/primitives/Mat.mjs.map -@@ -0,0 +1,7 @@ -+{ -+ "version": 3, -+ "sources": ["../../../src/lib/primitives/Mat.ts"], -+ "sourcesContent": ["import { Box } from './Box'\nimport { clampRadians, HALF_PI, toDomPrecision } from './utils'\nimport { Vec, VecLike } from './Vec'\n\n/** @public */\nexport type MatLike = MatModel | Mat\n\n/** @public */\nexport interface MatModel {\n\ta: number\n\tb: number\n\tc: number\n\td: number\n\te: number\n\tf: number\n}\n\n// function getIdentity() {\n// return new Mat(1.0, 0.0, 0.0, 1.0, 0.0, 0.0)\n// }\n\n/** @public */\nexport class Mat {\n\tconstructor(a: number, b: number, c: number, d: number, e: number, f: number) {\n\t\tthis.a = a\n\t\tthis.b = b\n\t\tthis.c = c\n\t\tthis.d = d\n\t\tthis.e = e\n\t\tthis.f = f\n\t}\n\n\ta = 1.0\n\tb = 0.0\n\tc = 0.0\n\td = 1.0\n\te = 0.0\n\tf = 0.0\n\n\tequals(m: Mat | MatModel) {\n\t\treturn (\n\t\t\tthis === m ||\n\t\t\t(this.a === m.a &&\n\t\t\t\tthis.b === m.b &&\n\t\t\t\tthis.c === m.c &&\n\t\t\t\tthis.d === m.d &&\n\t\t\t\tthis.e === m.e &&\n\t\t\t\tthis.f === m.f)\n\t\t)\n\t}\n\n\tidentity() {\n\t\tthis.a = 1.0\n\t\tthis.b = 0.0\n\t\tthis.c = 0.0\n\t\tthis.d = 1.0\n\t\tthis.e = 0.0\n\t\tthis.f = 0.0\n\t\treturn this\n\t}\n\n\tmultiply(m: Mat | MatModel) {\n\t\tconst m2: MatModel = m\n\t\tconst { a, b, c, d, e, f } = this\n\t\tthis.a = a * m2.a + c * m2.b\n\t\tthis.c = a * m2.c + c * m2.d\n\t\tthis.e = a * m2.e + c * m2.f + e\n\t\tthis.b = b * m2.a + d * m2.b\n\t\tthis.d = b * m2.c + d * m2.d\n\t\tthis.f = b * m2.e + d * m2.f + f\n\t\treturn this\n\t}\n\n\trotate(r: number, cx?: number, cy?: number) {\n\t\tif (r === 0) return this\n\t\tif (cx === undefined) return this.multiply(Mat.Rotate(r))\n\t\treturn this.translate(cx, cy!).multiply(Mat.Rotate(r)).translate(-cx, -cy!)\n\t}\n\n\ttranslate(x: number, y: number): Mat {\n\t\treturn this.multiply(Mat.Translate(x, y!))\n\t}\n\n\tscale(x: number, y: number) {\n\t\treturn this.multiply(Mat.Scale(x, y))\n\t}\n\n\tinvert() {\n\t\tconst { a, b, c, d, e, f } = this\n\t\tconst denom = a * d - b * c\n\t\tthis.a = d / denom\n\t\tthis.b = b / -denom\n\t\tthis.c = c / -denom\n\t\tthis.d = a / denom\n\t\tthis.e = (d * e - c * f) / -denom\n\t\tthis.f = (b * e - a * f) / denom\n\t\treturn this\n\t}\n\n\tapplyToPoint(point: VecLike) {\n\t\treturn Mat.applyToPoint(this, point)\n\t}\n\n\tapplyToPoints(points: VecLike[]) {\n\t\treturn Mat.applyToPoints(this, points)\n\t}\n\n\trotation() {\n\t\treturn Mat.Rotation(this)\n\t}\n\n\tpoint() {\n\t\treturn Mat.Point(this)\n\t}\n\n\tdecomposed() {\n\t\treturn Mat.Decompose(this)\n\t}\n\n\ttoCssString() {\n\t\treturn Mat.toCssString(this)\n\t}\n\n\tsetTo(model: MatModel) {\n\t\tObject.assign(this, model)\n\t\treturn this\n\t}\n\n\tdecompose() {\n\t\treturn Mat.Decompose(this)\n\t}\n\n\tclone() {\n\t\treturn new Mat(this.a, this.b, this.c, this.d, this.e, this.f)\n\t}\n\n\t/* --------------------- Static --------------------- */\n\n\tstatic Identity() {\n\t\treturn new Mat(1.0, 0.0, 0.0, 1.0, 0.0, 0.0)\n\t}\n\n\tstatic Translate(x: number, y: number) {\n\t\treturn new Mat(1.0, 0.0, 0.0, 1.0, x, y)\n\t}\n\n\tstatic Rotate(r: number, cx?: number, cy?: number) {\n\t\tif (r === 0) return Mat.Identity()\n\n\t\tconst cosAngle = Math.cos(r)\n\t\tconst sinAngle = Math.sin(r)\n\n\t\tconst rotationMatrix = new Mat(cosAngle, sinAngle, -sinAngle, cosAngle, 0.0, 0.0)\n\n\t\tif (cx === undefined) return rotationMatrix\n\n\t\treturn Mat.Compose(Mat.Translate(cx, cy!), rotationMatrix, Mat.Translate(-cx, -cy!))\n\t}\n\n\tstatic Scale(x: number, y: number): MatModel\n\tstatic Scale(x: number, y: number, cx: number, cy: number): MatModel\n\tstatic Scale(x: number, y: number, cx?: number, cy?: number): MatModel {\n\t\tconst scaleMatrix = new Mat(x, 0, 0, y, 0, 0)\n\t\tif (cx === undefined) return scaleMatrix\n\t\treturn Mat.Compose(Mat.Translate(cx, cy!), scaleMatrix, Mat.Translate(-cx, -cy!))\n\t}\n\tstatic Multiply(m1: MatModel, m2: MatModel): MatModel {\n\t\treturn {\n\t\t\ta: m1.a * m2.a + m1.c * m2.b,\n\t\t\tc: m1.a * m2.c + m1.c * m2.d,\n\t\t\te: m1.a * m2.e + m1.c * m2.f + m1.e,\n\t\t\tb: m1.b * m2.a + m1.d * m2.b,\n\t\t\td: m1.b * m2.c + m1.d * m2.d,\n\t\t\tf: m1.b * m2.e + m1.d * m2.f + m1.f,\n\t\t}\n\t}\n\n\tstatic Inverse(m: MatModel): MatModel {\n\t\tconst denom = m.a * m.d - m.b * m.c\n\t\treturn {\n\t\t\ta: m.d / denom,\n\t\t\tb: m.b / -denom,\n\t\t\tc: m.c / -denom,\n\t\t\td: m.a / denom,\n\t\t\te: (m.d * m.e - m.c * m.f) / -denom,\n\t\t\tf: (m.b * m.e - m.a * m.f) / denom,\n\t\t}\n\t}\n\n\tstatic Absolute(m: MatLike): MatModel {\n\t\tconst denom = m.a * m.d - m.b * m.c\n\t\treturn {\n\t\t\ta: m.d / denom,\n\t\t\tb: m.b / -denom,\n\t\t\tc: m.c / -denom,\n\t\t\td: m.a / denom,\n\t\t\te: (m.d * m.e - m.c * m.f) / denom,\n\t\t\tf: (m.b * m.e - m.a * m.f) / -denom,\n\t\t}\n\t}\n\n\tstatic Compose(...matrices: MatLike[]) {\n\t\tconst matrix = Mat.Identity()\n\t\tfor (let i = 0, n = matrices.length; i < n; i++) {\n\t\t\tmatrix.multiply(matrices[i])\n\t\t}\n\t\treturn matrix\n\t}\n\n\tstatic Point(m: MatLike) {\n\t\treturn new Vec(m.e, m.f)\n\t}\n\n\tstatic Rotation(m: MatLike): number {\n\t\tlet rotation\n\n\t\tif (m.a !== 0 || m.c !== 0) {\n\t\t\tconst hypotAc = (m.a * m.a + m.c * m.c) ** 0.5\n\t\t\trotation = Math.acos(m.a / hypotAc) * (m.c > 0 ? -1 : 1)\n\t\t} else if (m.b !== 0 || m.d !== 0) {\n\t\t\tconst hypotBd = (m.b * m.b + m.d * m.d) ** 0.5\n\t\t\trotation = HALF_PI + Math.acos(m.b / hypotBd) * (m.d > 0 ? -1 : 1)\n\t\t} else {\n\t\t\trotation = 0\n\t\t}\n\n\t\treturn clampRadians(rotation)\n\t}\n\n\tstatic Decompose(m: MatLike) {\n\t\tlet scaleX, scaleY, rotation\n\n\t\tif (m.a !== 0 || m.c !== 0) {\n\t\t\tconst hypotAc = (m.a * m.a + m.c * m.c) ** 0.5\n\t\t\tscaleX = hypotAc\n\t\t\tscaleY = (m.a * m.d - m.b * m.c) / hypotAc\n\t\t\trotation = Math.acos(m.a / hypotAc) * (m.c > 0 ? -1 : 1)\n\t\t} else if (m.b !== 0 || m.d !== 0) {\n\t\t\tconst hypotBd = (m.b * m.b + m.d * m.d) ** 0.5\n\t\t\tscaleX = (m.a * m.d - m.b * m.c) / hypotBd\n\t\t\tscaleY = hypotBd\n\t\t\trotation = HALF_PI + Math.acos(m.b / hypotBd) * (m.d > 0 ? -1 : 1)\n\t\t} else {\n\t\t\tscaleX = 0\n\t\t\tscaleY = 0\n\t\t\trotation = 0\n\t\t}\n\n\t\treturn {\n\t\t\tx: m.e,\n\t\t\ty: m.f,\n\t\t\tscaleX,\n\t\t\tscaleY,\n\t\t\trotation: clampRadians(rotation),\n\t\t}\n\t}\n\n\tstatic Smooth(m: MatLike, precision = 10000000000) {\n\t\tm.a = Math.round(m.a * precision) / precision\n\t\tm.b = Math.round(m.b * precision) / precision\n\t\tm.c = Math.round(m.c * precision) / precision\n\t\tm.d = Math.round(m.d * precision) / precision\n\t\tm.e = Math.round(m.e * precision) / precision\n\t\tm.f = Math.round(m.f * precision) / precision\n\t\treturn m\n\t}\n\n\tstatic toCssString(m: MatLike) {\n\t\treturn `matrix(${toDomPrecision(m.a)}, ${toDomPrecision(m.b)}, ${toDomPrecision(\n\t\t\tm.c\n\t\t)}, ${toDomPrecision(m.d)}, ${toDomPrecision(m.e)}, ${toDomPrecision(m.f)})`\n\t}\n\n\tstatic applyToPoint(m: MatLike, point: VecLike) {\n\t\treturn new Vec(\n\t\t\tm.a * point.x + m.c * point.y + m.e,\n\t\t\tm.b * point.x + m.d * point.y + m.f,\n\t\t\tpoint.z\n\t\t)\n\t}\n\n\tstatic applyToXY(m: MatLike, x: number, y: number) {\n\t\treturn [m.a * x + m.c * y + m.e, m.b * x + m.d * y + m.f]\n\t}\n\n\tstatic applyToPoints(m: MatLike, points: VecLike[]): Vec[] {\n\t\treturn points.map(\n\t\t\t(point) =>\n\t\t\t\tnew Vec(m.a * point.x + m.c * point.y + m.e, m.b * point.x + m.d * point.y + m.f, point.z)\n\t\t)\n\t}\n\n\tstatic applyToBounds(m: MatLike, box: Box) {\n\t\treturn new Box(m.e + box.minX, m.f + box.minY, box.width, box.height)\n\t}\n\n\tstatic From(m: MatLike) {\n\t\treturn new Mat(m.a, m.b, m.c, m.d, m.e, m.f)\n\t}\n\n\tstatic Cast(m: MatLike) {\n\t\treturn m instanceof Mat ? m : Mat.From(m)\n\t}\n}\n\n/** @public */\nexport function decomposeMatrix(m: MatLike) {\n\treturn {\n\t\tx: m.e,\n\t\ty: m.f,\n\t\tscaleX: Math.sqrt(m.a * m.a + m.b * m.b),\n\t\tscaleY: Math.sqrt(m.c * m.c + m.d * m.d),\n\t\trotation: Math.atan2(m.b, m.a),\n\t}\n}\n"], -+ "mappings": "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", -+ "names": [] -+} -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/primitives/Vec.mjs b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/primitives/Vec.mjs -new file mode 100644 -index 0000000..a695029 ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/primitives/Vec.mjs -@@ -0,0 +1,475 @@ -+import { EASINGS } from "./easings.mjs"; -+import { toFixed } from "./utils.mjs"; -+class Vec { -+ constructor(x = 0, y = 0, z = 1) { -+ this.x = x; -+ this.y = y; -+ this.z = z; -+ } -+ // eslint-disable-next-line no-restricted-syntax -+ get pressure() { -+ return this.z; -+ } -+ set(x = this.x, y = this.y, z = this.z) { -+ this.x = x; -+ this.y = y; -+ this.z = z; -+ return this; -+ } -+ setTo({ x = 0, y = 0, z = 1 }) { -+ this.x = x; -+ this.y = y; -+ this.z = z; -+ return this; -+ } -+ rot(r) { -+ if (r === 0) return this; -+ const { x, y } = this; -+ const s = Math.sin(r); -+ const c = Math.cos(r); -+ this.x = x * c - y * s; -+ this.y = x * s + y * c; -+ return this; -+ } -+ rotWith(C, r) { -+ if (r === 0) return this; -+ const x = this.x - C.x; -+ const y = this.y - C.y; -+ const s = Math.sin(r); -+ const c = Math.cos(r); -+ this.x = C.x + (x * c - y * s); -+ this.y = C.y + (x * s + y * c); -+ return this; -+ } -+ clone() { -+ const { x, y, z } = this; -+ return new Vec(x, y, z); -+ } -+ sub(V) { -+ this.x -= V.x; -+ this.y -= V.y; -+ return this; -+ } -+ subXY(x, y) { -+ this.x -= x; -+ this.y -= y; -+ return this; -+ } -+ subScalar(n) { -+ this.x -= n; -+ this.y -= n; -+ return this; -+ } -+ add(V) { -+ this.x += V.x; -+ this.y += V.y; -+ return this; -+ } -+ addXY(x, y) { -+ this.x += x; -+ this.y += y; -+ return this; -+ } -+ addScalar(n) { -+ this.x += n; -+ this.y += n; -+ return this; -+ } -+ clamp(min, max) { -+ this.x = Math.max(this.x, min); -+ this.y = Math.max(this.y, min); -+ if (max !== void 0) { -+ this.x = Math.min(this.x, max); -+ this.y = Math.min(this.y, max); -+ } -+ return this; -+ } -+ div(t) { -+ this.x /= t; -+ this.y /= t; -+ return this; -+ } -+ divV(V) { -+ this.x /= V.x; -+ this.y /= V.y; -+ return this; -+ } -+ mul(t) { -+ this.x *= t; -+ this.y *= t; -+ return this; -+ } -+ mulV(V) { -+ this.x *= V.x; -+ this.y *= V.y; -+ return this; -+ } -+ abs() { -+ this.x = Math.abs(this.x); -+ this.y = Math.abs(this.y); -+ return this; -+ } -+ nudge(B, distance) { -+ const tan = Vec.Tan(B, this); -+ return this.add(tan.mul(distance)); -+ } -+ neg() { -+ this.x *= -1; -+ this.y *= -1; -+ return this; -+ } -+ cross(V) { -+ this.x = this.y * V.z - this.z * V.y; -+ this.y = this.z * V.x - this.x * V.z; -+ return this; -+ } -+ dpr(V) { -+ return Vec.Dpr(this, V); -+ } -+ cpr(V) { -+ return Vec.Cpr(this, V); -+ } -+ len2() { -+ return Vec.Len2(this); -+ } -+ len() { -+ return Vec.Len(this); -+ } -+ pry(V) { -+ return Vec.Pry(this, V); -+ } -+ per() { -+ const { x, y } = this; -+ this.x = y; -+ this.y = -x; -+ return this; -+ } -+ uni() { -+ return Vec.Uni(this); -+ } -+ tan(V) { -+ return Vec.Tan(this, V); -+ } -+ dist(V) { -+ return Vec.Dist(this, V); -+ } -+ distanceToLineSegment(A, B) { -+ return Vec.DistanceToLineSegment(A, B, this); -+ } -+ slope(B) { -+ return Vec.Slope(this, B); -+ } -+ snapToGrid(gridSize) { -+ this.x = Math.round(this.x / gridSize) * gridSize; -+ this.y = Math.round(this.y / gridSize) * gridSize; -+ return this; -+ } -+ angle(B) { -+ return Vec.Angle(this, B); -+ } -+ toAngle() { -+ return Vec.ToAngle(this); -+ } -+ lrp(B, t) { -+ this.x = this.x + (B.x - this.x) * t; -+ this.y = this.y + (B.y - this.y) * t; -+ return this; -+ } -+ equals(B) { -+ return Vec.Equals(this, B); -+ } -+ equalsXY(x, y) { -+ return Vec.EqualsXY(this, x, y); -+ } -+ norm() { -+ const l = this.len(); -+ this.x = l === 0 ? 0 : this.x / l; -+ this.y = l === 0 ? 0 : this.y / l; -+ return this; -+ } -+ toFixed() { -+ return Vec.ToFixed(this); -+ } -+ toString() { -+ return Vec.ToString(Vec.ToFixed(this)); -+ } -+ toJson() { -+ return Vec.ToJson(this); -+ } -+ toArray() { -+ return Vec.ToArray(this); -+ } -+ static Add(A, B) { -+ return new Vec(A.x + B.x, A.y + B.y); -+ } -+ static AddXY(A, x, y) { -+ return new Vec(A.x + x, A.y + y); -+ } -+ static Sub(A, B) { -+ return new Vec(A.x - B.x, A.y - B.y); -+ } -+ static SubXY(A, x, y) { -+ return new Vec(A.x - x, A.y - y); -+ } -+ static AddScalar(A, n) { -+ return new Vec(A.x + n, A.y + n); -+ } -+ static SubScalar(A, n) { -+ return new Vec(A.x - n, A.y - n); -+ } -+ static Div(A, t) { -+ return new Vec(A.x / t, A.y / t); -+ } -+ static Mul(A, t) { -+ return new Vec(A.x * t, A.y * t); -+ } -+ static DivV(A, B) { -+ return new Vec(A.x / B.x, A.y / B.y); -+ } -+ static MulV(A, B) { -+ return new Vec(A.x * B.x, A.y * B.y); -+ } -+ static Neg(A) { -+ return new Vec(-A.x, -A.y); -+ } -+ /** -+ * Get the perpendicular vector to A. -+ */ -+ static Per(A) { -+ return new Vec(A.y, -A.x); -+ } -+ static Abs(A) { -+ return new Vec(Math.abs(A.x), Math.abs(A.y)); -+ } -+ // Get the distance between two points. -+ static Dist(A, B) { -+ return ((A.y - B.y) ** 2 + (A.x - B.x) ** 2) ** 0.5; -+ } -+ // Get whether a distance between two points is less than a number. This is faster to calulate than using `Vec.Dist(a, b) < n`. -+ static DistMin(A, B, n) { -+ return (A.x - B.x) * (A.x - B.x) + (A.y - B.y) * (A.y - B.y) < n ** 2; -+ } -+ // Get the squared distance between two points. This is faster to calculate (no square root) so useful for "minimum distance" checks where the actual measurement does not matter. -+ static Dist2(A, B) { -+ return (A.x - B.x) * (A.x - B.x) + (A.y - B.y) * (A.y - B.y); -+ } -+ /** -+ * Dot product of two vectors which is used to calculate the angle between them. -+ */ -+ static Dpr(A, B) { -+ return A.x * B.x + A.y * B.y; -+ } -+ static Cross(A, V) { -+ return new Vec( -+ A.y * V.z - A.z * V.y, -+ A.z * V.x - A.x * V.z -+ // A.z = A.x * V.y - A.y * V.x -+ ); -+ } -+ /** -+ * Cross product of two vectors which is used to calculate the area of a parallelogram. -+ */ -+ static Cpr(A, B) { -+ return A.x * B.y - B.x * A.y; -+ } -+ static Len2(A) { -+ return A.x * A.x + A.y * A.y; -+ } -+ static Len(A) { -+ return (A.x * A.x + A.y * A.y) ** 0.5; -+ } -+ /** -+ * Get the projection of A onto B. -+ */ -+ static Pry(A, B) { -+ return Vec.Dpr(A, B) / Vec.Len(B); -+ } -+ /** -+ * Get the unit vector of A. -+ */ -+ static Uni(A) { -+ return Vec.Div(A, Vec.Len(A)); -+ } -+ static Tan(A, B) { -+ return Vec.Uni(Vec.Sub(A, B)); -+ } -+ static Min(A, B) { -+ return new Vec(Math.min(A.x, B.x), Math.min(A.y, B.y)); -+ } -+ static Max(A, B) { -+ return new Vec(Math.max(A.x, B.x), Math.max(A.y, B.y)); -+ } -+ static From({ x, y, z = 1 }) { -+ return new Vec(x, y, z); -+ } -+ static FromArray(v) { -+ return new Vec(v[0], v[1]); -+ } -+ static Rot(A, r = 0) { -+ const s = Math.sin(r); -+ const c = Math.cos(r); -+ return new Vec(A.x * c - A.y * s, A.x * s + A.y * c); -+ } -+ static RotWith(A, C, r) { -+ const x = A.x - C.x; -+ const y = A.y - C.y; -+ const s = Math.sin(r); -+ const c = Math.cos(r); -+ return new Vec(C.x + (x * c - y * s), C.y + (x * s + y * c)); -+ } -+ /** -+ * Get the nearest point on a line with a known unit vector that passes through point A -+ * -+ * ```ts -+ * Vec.nearestPointOnLineThroughPoint(A, u, Point) -+ * ``` -+ * -+ * @param A - Any point on the line -+ * @param u - The unit vector for the line. -+ * @param P - A point not on the line to test. -+ */ -+ static NearestPointOnLineThroughPoint(A, u, P) { -+ return Vec.Mul(u, Vec.Sub(P, A).pry(u)).add(A); -+ } -+ static NearestPointOnLineSegment(A, B, P, clamp = true) { -+ if (Vec.Equals(A, P)) return Vec.From(P); -+ if (Vec.Equals(B, P)) return Vec.From(P); -+ const u = Vec.Tan(B, A); -+ const C = Vec.Add(A, Vec.Mul(u, Vec.Sub(P, A).pry(u))); -+ if (clamp) { -+ if (C.x < Math.min(A.x, B.x)) return Vec.Cast(A.x < B.x ? A : B); -+ if (C.x > Math.max(A.x, B.x)) return Vec.Cast(A.x > B.x ? A : B); -+ if (C.y < Math.min(A.y, B.y)) return Vec.Cast(A.y < B.y ? A : B); -+ if (C.y > Math.max(A.y, B.y)) return Vec.Cast(A.y > B.y ? A : B); -+ } -+ return C; -+ } -+ static DistanceToLineThroughPoint(A, u, P) { -+ return Vec.Dist(P, Vec.NearestPointOnLineThroughPoint(A, u, P)); -+ } -+ static DistanceToLineSegment(A, B, P, clamp = true) { -+ return Vec.Dist(P, Vec.NearestPointOnLineSegment(A, B, P, clamp)); -+ } -+ static Snap(A, step = 1) { -+ return new Vec(Math.round(A.x / step) * step, Math.round(A.y / step) * step); -+ } -+ static Cast(A) { -+ if (A instanceof Vec) return A; -+ return Vec.From(A); -+ } -+ static Slope(A, B) { -+ if (A.x === B.y) return NaN; -+ return (A.y - B.y) / (A.x - B.x); -+ } -+ static IsNaN(A) { -+ return isNaN(A.x) || isNaN(A.y); -+ } -+ static Angle(A, B) { -+ return Math.atan2(B.y - A.y, B.x - A.x); -+ } -+ /** -+ * Linearly interpolate between two points. -+ * @param A - The first point. -+ * @param B - The second point. -+ * @param t - The interpolation value between 0 and 1. -+ * @returns The interpolated point. -+ */ -+ static Lrp(A, B, t) { -+ return Vec.Sub(B, A).mul(t).add(A); -+ } -+ static Med(A, B) { -+ return new Vec((A.x + B.x) / 2, (A.y + B.y) / 2); -+ } -+ static Equals(A, B) { -+ return Math.abs(A.x - B.x) < 1e-4 && Math.abs(A.y - B.y) < 1e-4; -+ } -+ static EqualsXY(A, x, y) { -+ return A.x === x && A.y === y; -+ } -+ static Clockwise(A, B, C) { -+ return (C.x - A.x) * (B.y - A.y) - (B.x - A.x) * (C.y - A.y) < 0; -+ } -+ static Rescale(A, n) { -+ const l = Vec.Len(A); -+ return new Vec(n * A.x / l, n * A.y / l); -+ } -+ static ScaleWithOrigin(A, scale, origin) { -+ return Vec.Sub(A, origin).mul(scale).add(origin); -+ } -+ static ToFixed(A) { -+ return new Vec(toFixed(A.x), toFixed(A.y)); -+ } -+ static ToInt(A) { -+ return new Vec( -+ parseInt(A.x.toFixed(0)), -+ parseInt(A.y.toFixed(0)), -+ parseInt((A.z ?? 0).toFixed(0)) -+ ); -+ } -+ static ToCss(A) { -+ return `${A.x},${A.y}`; -+ } -+ static Nudge(A, B, distance) { -+ return Vec.Add(A, Vec.Tan(B, A).mul(distance)); -+ } -+ static ToString(A) { -+ return `${A.x}, ${A.y}`; -+ } -+ static ToAngle(A) { -+ let r = Math.atan2(A.y, A.x); -+ if (r < 0) r += Math.PI * 2; -+ return r; -+ } -+ static FromAngle(r, length = 1) { -+ return new Vec(Math.cos(r) * length, Math.sin(r) * length); -+ } -+ static ToArray(A) { -+ return [A.x, A.y, A.z]; -+ } -+ static ToJson(A) { -+ const { x, y, z } = A; -+ return { x, y, z }; -+ } -+ static Average(arr) { -+ const len = arr.length; -+ const avg = new Vec(0, 0); -+ if (len === 0) { -+ return avg; -+ } -+ for (let i = 0; i < len; i++) { -+ avg.add(arr[i]); -+ } -+ return avg.div(len); -+ } -+ static Clamp(A, min, max) { -+ if (max === void 0) { -+ return new Vec(Math.min(Math.max(A.x, min)), Math.min(Math.max(A.y, min))); -+ } -+ return new Vec(Math.min(Math.max(A.x, min), max), Math.min(Math.max(A.y, min), max)); -+ } -+ /** -+ * Get an array of points (with simulated pressure) between two points. -+ * -+ * @param A - The first point. -+ * @param B - The second point. -+ * @param steps - The number of points to return. -+ */ -+ static PointsBetween(A, B, steps = 6) { -+ const results = []; -+ for (let i = 0; i < steps; i++) { -+ const t = EASINGS.easeInQuad(i / (steps - 1)); -+ const point = Vec.Lrp(A, B, t); -+ point.z = Math.min(1, 0.5 + Math.abs(0.5 - ease(t)) * 0.65); -+ results.push(point); -+ } -+ return results; -+ } -+ static SnapToGrid(A, gridSize = 8) { -+ return new Vec(Math.round(A.x / gridSize) * gridSize, Math.round(A.y / gridSize) * gridSize); -+ } -+} -+const ease = (t) => t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t; -+export { -+ Vec -+}; -+//# sourceMappingURL=Vec.mjs.map -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/primitives/Vec.mjs.map b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/primitives/Vec.mjs.map -new file mode 100644 -index 0000000..57090a3 ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/primitives/Vec.mjs.map -@@ -0,0 +1,7 @@ -+{ -+ "version": 3, -+ "sources": ["../../../src/lib/primitives/Vec.ts"], -+ "sourcesContent": ["import { VecModel } from '@tldraw/tlschema'\nimport { EASINGS } from './easings'\nimport { toFixed } from './utils'\n\n/** @public */\nexport type VecLike = Vec | VecModel\n\n/** @public */\nexport class Vec {\n\tconstructor(\n\t\tpublic x = 0,\n\t\tpublic y = 0,\n\t\tpublic z = 1\n\t) {}\n\n\t// eslint-disable-next-line no-restricted-syntax\n\tget pressure() {\n\t\treturn this.z\n\t}\n\n\tset(x = this.x, y = this.y, z = this.z) {\n\t\tthis.x = x\n\t\tthis.y = y\n\t\tthis.z = z\n\t\treturn this\n\t}\n\n\tsetTo({ x = 0, y = 0, z = 1 }: VecLike) {\n\t\tthis.x = x\n\t\tthis.y = y\n\t\tthis.z = z\n\t\treturn this\n\t}\n\n\trot(r: number) {\n\t\tif (r === 0) return this\n\t\tconst { x, y } = this\n\t\tconst s = Math.sin(r)\n\t\tconst c = Math.cos(r)\n\t\tthis.x = x * c - y * s\n\t\tthis.y = x * s + y * c\n\t\treturn this\n\t}\n\n\trotWith(C: VecLike, r: number) {\n\t\tif (r === 0) return this\n\t\tconst x = this.x - C.x\n\t\tconst y = this.y - C.y\n\t\tconst s = Math.sin(r)\n\t\tconst c = Math.cos(r)\n\t\tthis.x = C.x + (x * c - y * s)\n\t\tthis.y = C.y + (x * s + y * c)\n\t\treturn this\n\t}\n\n\tclone(): Vec {\n\t\tconst { x, y, z } = this\n\t\treturn new Vec(x, y, z)\n\t}\n\n\tsub(V: VecLike) {\n\t\tthis.x -= V.x\n\t\tthis.y -= V.y\n\t\treturn this\n\t}\n\n\tsubXY(x: number, y: number) {\n\t\tthis.x -= x\n\t\tthis.y -= y\n\t\treturn this\n\t}\n\n\tsubScalar(n: number) {\n\t\tthis.x -= n\n\t\tthis.y -= n\n\t\t// this.z -= n\n\n\t\treturn this\n\t}\n\n\tadd(V: VecLike) {\n\t\tthis.x += V.x\n\t\tthis.y += V.y\n\t\treturn this\n\t}\n\n\taddXY(x: number, y: number) {\n\t\tthis.x += x\n\t\tthis.y += y\n\t\treturn this\n\t}\n\n\taddScalar(n: number) {\n\t\tthis.x += n\n\t\tthis.y += n\n\t\t// this.z += n\n\n\t\treturn this\n\t}\n\n\tclamp(min: number, max?: number) {\n\t\tthis.x = Math.max(this.x, min)\n\t\tthis.y = Math.max(this.y, min)\n\t\tif (max !== undefined) {\n\t\t\tthis.x = Math.min(this.x, max)\n\t\t\tthis.y = Math.min(this.y, max)\n\t\t}\n\t\treturn this\n\t}\n\n\tdiv(t: number) {\n\t\tthis.x /= t\n\t\tthis.y /= t\n\t\t// this.z /= t\n\t\treturn this\n\t}\n\n\tdivV(V: VecLike) {\n\t\tthis.x /= V.x\n\t\tthis.y /= V.y\n\t\t// this.z /= V.z\n\t\treturn this\n\t}\n\n\tmul(t: number) {\n\t\tthis.x *= t\n\t\tthis.y *= t\n\t\t// this.z *= t\n\t\treturn this\n\t}\n\n\tmulV(V: VecLike) {\n\t\tthis.x *= V.x\n\t\tthis.y *= V.y\n\t\t// this.z *= V.z\n\t\treturn this\n\t}\n\n\tabs() {\n\t\tthis.x = Math.abs(this.x)\n\t\tthis.y = Math.abs(this.y)\n\t\treturn this\n\t}\n\n\tnudge(B: VecLike, distance: number) {\n\t\tconst tan = Vec.Tan(B, this)\n\t\treturn this.add(tan.mul(distance))\n\t}\n\n\tneg() {\n\t\tthis.x *= -1\n\t\tthis.y *= -1\n\t\t// this.z *= -1\n\t\treturn this\n\t}\n\n\tcross(V: VecLike) {\n\t\tthis.x = this.y * V.z! - this.z * V.y\n\t\tthis.y = this.z * V.x - this.x * V.z!\n\t\t// this.z = this.x * V.y - this.y * V.x\n\t\treturn this\n\t}\n\n\tdpr(V: VecLike): number {\n\t\treturn Vec.Dpr(this, V)\n\t}\n\n\tcpr(V: VecLike) {\n\t\treturn Vec.Cpr(this, V)\n\t}\n\n\tlen2(): number {\n\t\treturn Vec.Len2(this)\n\t}\n\n\tlen(): number {\n\t\treturn Vec.Len(this)\n\t}\n\n\tpry(V: VecLike): number {\n\t\treturn Vec.Pry(this, V)\n\t}\n\n\tper() {\n\t\tconst { x, y } = this\n\t\tthis.x = y\n\t\tthis.y = -x\n\t\treturn this\n\t}\n\n\tuni() {\n\t\treturn Vec.Uni(this)\n\t}\n\n\ttan(V: VecLike): Vec {\n\t\treturn Vec.Tan(this, V)\n\t}\n\n\tdist(V: VecLike): number {\n\t\treturn Vec.Dist(this, V)\n\t}\n\n\tdistanceToLineSegment(A: VecLike, B: VecLike): number {\n\t\treturn Vec.DistanceToLineSegment(A, B, this)\n\t}\n\n\tslope(B: VecLike): number {\n\t\treturn Vec.Slope(this, B)\n\t}\n\n\tsnapToGrid(gridSize: number) {\n\t\tthis.x = Math.round(this.x / gridSize) * gridSize\n\t\tthis.y = Math.round(this.y / gridSize) * gridSize\n\t\treturn this\n\t}\n\n\tangle(B: VecLike): number {\n\t\treturn Vec.Angle(this, B)\n\t}\n\n\ttoAngle() {\n\t\treturn Vec.ToAngle(this)\n\t}\n\n\tlrp(B: VecLike, t: number): Vec {\n\t\tthis.x = this.x + (B.x - this.x) * t\n\t\tthis.y = this.y + (B.y - this.y) * t\n\t\treturn this\n\t}\n\n\tequals(B: VecLike) {\n\t\treturn Vec.Equals(this, B)\n\t}\n\n\tequalsXY(x: number, y: number) {\n\t\treturn Vec.EqualsXY(this, x, y)\n\t}\n\n\tnorm() {\n\t\tconst l = this.len()\n\t\tthis.x = l === 0 ? 0 : this.x / l\n\t\tthis.y = l === 0 ? 0 : this.y / l\n\t\treturn this\n\t}\n\n\ttoFixed() {\n\t\treturn Vec.ToFixed(this)\n\t}\n\n\ttoString() {\n\t\treturn Vec.ToString(Vec.ToFixed(this))\n\t}\n\n\ttoJson(): VecModel {\n\t\treturn Vec.ToJson(this)\n\t}\n\n\ttoArray(): number[] {\n\t\treturn Vec.ToArray(this)\n\t}\n\n\tstatic Add(A: VecLike, B: VecLike): Vec {\n\t\treturn new Vec(A.x + B.x, A.y + B.y)\n\t}\n\n\tstatic AddXY(A: VecLike, x: number, y: number): Vec {\n\t\treturn new Vec(A.x + x, A.y + y)\n\t}\n\n\tstatic Sub(A: VecLike, B: VecLike): Vec {\n\t\treturn new Vec(A.x - B.x, A.y - B.y)\n\t}\n\n\tstatic SubXY(A: VecLike, x: number, y: number): Vec {\n\t\treturn new Vec(A.x - x, A.y - y)\n\t}\n\n\tstatic AddScalar(A: VecLike, n: number): Vec {\n\t\treturn new Vec(A.x + n, A.y + n)\n\t}\n\n\tstatic SubScalar(A: VecLike, n: number): Vec {\n\t\treturn new Vec(A.x - n, A.y - n)\n\t}\n\n\tstatic Div(A: VecLike, t: number): Vec {\n\t\treturn new Vec(A.x / t, A.y / t)\n\t}\n\n\tstatic Mul(A: VecLike, t: number): Vec {\n\t\treturn new Vec(A.x * t, A.y * t)\n\t}\n\n\tstatic DivV(A: VecLike, B: VecLike): Vec {\n\t\treturn new Vec(A.x / B.x, A.y / B.y)\n\t}\n\n\tstatic MulV(A: VecLike, B: VecLike): Vec {\n\t\treturn new Vec(A.x * B.x, A.y * B.y)\n\t}\n\n\tstatic Neg(A: VecLike): Vec {\n\t\treturn new Vec(-A.x, -A.y)\n\t}\n\n\t/**\n\t * Get the perpendicular vector to A.\n\t */\n\tstatic Per(A: VecLike): Vec {\n\t\treturn new Vec(A.y, -A.x)\n\t}\n\n\tstatic Abs(A: VecLike): Vec {\n\t\treturn new Vec(Math.abs(A.x), Math.abs(A.y))\n\t}\n\n\t// Get the distance between two points.\n\tstatic Dist(A: VecLike, B: VecLike): number {\n\t\treturn ((A.y - B.y) ** 2 + (A.x - B.x) ** 2) ** 0.5\n\t}\n\n\t// Get whether a distance between two points is less than a number. This is faster to calulate than using `Vec.Dist(a, b) < n`.\n\tstatic DistMin(A: VecLike, B: VecLike, n: number): boolean {\n\t\treturn (A.x - B.x) * (A.x - B.x) + (A.y - B.y) * (A.y - B.y) < n ** 2\n\t}\n\n\t// Get the squared distance between two points. This is faster to calculate (no square root) so useful for \"minimum distance\" checks where the actual measurement does not matter.\n\tstatic Dist2(A: VecLike, B: VecLike): number {\n\t\treturn (A.x - B.x) * (A.x - B.x) + (A.y - B.y) * (A.y - B.y)\n\t}\n\n\t/**\n\t * Dot product of two vectors which is used to calculate the angle between them.\n\t */\n\tstatic Dpr(A: VecLike, B: VecLike): number {\n\t\treturn A.x * B.x + A.y * B.y\n\t}\n\n\tstatic Cross(A: VecLike, V: VecLike) {\n\t\treturn new Vec(\n\t\t\tA.y * V.z! - A.z! * V.y,\n\t\t\tA.z! * V.x - A.x * V.z!\n\t\t\t// A.z = A.x * V.y - A.y * V.x\n\t\t)\n\t}\n\n\t/**\n\t * Cross product of two vectors which is used to calculate the area of a parallelogram.\n\t */\n\tstatic Cpr(A: VecLike, B: VecLike) {\n\t\treturn A.x * B.y - B.x * A.y\n\t}\n\n\tstatic Len2(A: VecLike): number {\n\t\treturn A.x * A.x + A.y * A.y\n\t}\n\n\tstatic Len(A: VecLike): number {\n\t\treturn (A.x * A.x + A.y * A.y) ** 0.5\n\t}\n\n\t/**\n\t * Get the projection of A onto B.\n\t */\n\tstatic Pry(A: VecLike, B: VecLike): number {\n\t\treturn Vec.Dpr(A, B) / Vec.Len(B)\n\t}\n\n\t/**\n\t * Get the unit vector of A.\n\t */\n\tstatic Uni(A: VecLike) {\n\t\treturn Vec.Div(A, Vec.Len(A))\n\t}\n\n\tstatic Tan(A: VecLike, B: VecLike): Vec {\n\t\treturn Vec.Uni(Vec.Sub(A, B))\n\t}\n\n\tstatic Min(A: VecLike, B: VecLike): Vec {\n\t\treturn new Vec(Math.min(A.x, B.x), Math.min(A.y, B.y))\n\t}\n\n\tstatic Max(A: VecLike, B: VecLike): Vec {\n\t\treturn new Vec(Math.max(A.x, B.x), Math.max(A.y, B.y))\n\t}\n\n\tstatic From({ x, y, z = 1 }: VecModel) {\n\t\treturn new Vec(x, y, z)\n\t}\n\n\tstatic FromArray(v: number[]): Vec {\n\t\treturn new Vec(v[0], v[1])\n\t}\n\n\tstatic Rot(A: VecLike, r = 0): Vec {\n\t\tconst s = Math.sin(r)\n\t\tconst c = Math.cos(r)\n\t\treturn new Vec(A.x * c - A.y * s, A.x * s + A.y * c)\n\t}\n\n\tstatic RotWith(A: VecLike, C: VecLike, r: number): Vec {\n\t\tconst x = A.x - C.x\n\t\tconst y = A.y - C.y\n\t\tconst s = Math.sin(r)\n\t\tconst c = Math.cos(r)\n\t\treturn new Vec(C.x + (x * c - y * s), C.y + (x * s + y * c))\n\t}\n\n\t/**\n\t * Get the nearest point on a line with a known unit vector that passes through point A\n\t *\n\t * ```ts\n\t * Vec.nearestPointOnLineThroughPoint(A, u, Point)\n\t * ```\n\t *\n\t * @param A - Any point on the line\n\t * @param u - The unit vector for the line.\n\t * @param P - A point not on the line to test.\n\t */\n\tstatic NearestPointOnLineThroughPoint(A: VecLike, u: VecLike, P: VecLike): Vec {\n\t\treturn Vec.Mul(u, Vec.Sub(P, A).pry(u)).add(A)\n\t}\n\n\tstatic NearestPointOnLineSegment(A: VecLike, B: VecLike, P: VecLike, clamp = true): Vec {\n\t\tif (Vec.Equals(A, P)) return Vec.From(P)\n\t\tif (Vec.Equals(B, P)) return Vec.From(P)\n\n\t\tconst u = Vec.Tan(B, A)\n\t\tconst C = Vec.Add(A, Vec.Mul(u, Vec.Sub(P, A).pry(u)))\n\n\t\tif (clamp) {\n\t\t\tif (C.x < Math.min(A.x, B.x)) return Vec.Cast(A.x < B.x ? A : B)\n\t\t\tif (C.x > Math.max(A.x, B.x)) return Vec.Cast(A.x > B.x ? A : B)\n\t\t\tif (C.y < Math.min(A.y, B.y)) return Vec.Cast(A.y < B.y ? A : B)\n\t\t\tif (C.y > Math.max(A.y, B.y)) return Vec.Cast(A.y > B.y ? A : B)\n\t\t}\n\n\t\treturn C\n\t}\n\n\tstatic DistanceToLineThroughPoint(A: VecLike, u: VecLike, P: VecLike): number {\n\t\treturn Vec.Dist(P, Vec.NearestPointOnLineThroughPoint(A, u, P))\n\t}\n\n\tstatic DistanceToLineSegment(A: VecLike, B: VecLike, P: VecLike, clamp = true): number {\n\t\treturn Vec.Dist(P, Vec.NearestPointOnLineSegment(A, B, P, clamp))\n\t}\n\n\tstatic Snap(A: VecLike, step = 1) {\n\t\treturn new Vec(Math.round(A.x / step) * step, Math.round(A.y / step) * step)\n\t}\n\n\tstatic Cast(A: VecLike): Vec {\n\t\tif (A instanceof Vec) return A\n\t\treturn Vec.From(A)\n\t}\n\n\tstatic Slope(A: VecLike, B: VecLike): number {\n\t\tif (A.x === B.y) return NaN\n\t\treturn (A.y - B.y) / (A.x - B.x)\n\t}\n\n\tstatic IsNaN(A: VecLike): boolean {\n\t\treturn isNaN(A.x) || isNaN(A.y)\n\t}\n\n\tstatic Angle(A: VecLike, B: VecLike): number {\n\t\treturn Math.atan2(B.y - A.y, B.x - A.x)\n\t}\n\n\t/**\n\t * Linearly interpolate between two points.\n\t * @param A - The first point.\n\t * @param B - The second point.\n\t * @param t - The interpolation value between 0 and 1.\n\t * @returns The interpolated point.\n\t */\n\tstatic Lrp(A: VecLike, B: VecLike, t: number): Vec {\n\t\treturn Vec.Sub(B, A).mul(t).add(A)\n\t}\n\n\tstatic Med(A: VecLike, B: VecLike): Vec {\n\t\treturn new Vec((A.x + B.x) / 2, (A.y + B.y) / 2)\n\t}\n\n\tstatic Equals(A: VecLike, B: VecLike): boolean {\n\t\treturn Math.abs(A.x - B.x) < 0.0001 && Math.abs(A.y - B.y) < 0.0001\n\t}\n\n\tstatic EqualsXY(A: VecLike, x: number, y: number): boolean {\n\t\treturn A.x === x && A.y === y\n\t}\n\n\tstatic Clockwise(A: VecLike, B: VecLike, C: VecLike): boolean {\n\t\treturn (C.x - A.x) * (B.y - A.y) - (B.x - A.x) * (C.y - A.y) < 0\n\t}\n\n\tstatic Rescale(A: VecLike, n: number) {\n\t\tconst l = Vec.Len(A)\n\t\treturn new Vec((n * A.x) / l, (n * A.y) / l)\n\t}\n\n\tstatic ScaleWithOrigin(A: VecLike, scale: number, origin: VecLike) {\n\t\treturn Vec.Sub(A, origin).mul(scale).add(origin)\n\t}\n\n\tstatic ToFixed(A: VecLike) {\n\t\treturn new Vec(toFixed(A.x), toFixed(A.y))\n\t}\n\n\tstatic ToInt(A: VecLike) {\n\t\treturn new Vec(\n\t\t\tparseInt(A.x.toFixed(0)),\n\t\t\tparseInt(A.y.toFixed(0)),\n\t\t\tparseInt((A.z ?? 0).toFixed(0))\n\t\t)\n\t}\n\n\tstatic ToCss(A: VecLike) {\n\t\treturn `${A.x},${A.y}`\n\t}\n\n\tstatic Nudge(A: VecLike, B: VecLike, distance: number) {\n\t\treturn Vec.Add(A, Vec.Tan(B, A).mul(distance))\n\t}\n\n\tstatic ToString(A: VecLike) {\n\t\treturn `${A.x}, ${A.y}`\n\t}\n\n\tstatic ToAngle(A: VecLike) {\n\t\tlet r = Math.atan2(A.y, A.x)\n\t\tif (r < 0) r += Math.PI * 2\n\n\t\treturn r\n\t}\n\n\tstatic FromAngle(r: number, length = 1) {\n\t\treturn new Vec(Math.cos(r) * length, Math.sin(r) * length)\n\t}\n\n\tstatic ToArray(A: VecLike) {\n\t\treturn [A.x, A.y, A.z!]\n\t}\n\n\tstatic ToJson(A: VecLike) {\n\t\tconst { x, y, z } = A\n\t\treturn { x, y, z }\n\t}\n\n\tstatic Average(arr: VecLike[]) {\n\t\tconst len = arr.length\n\t\tconst avg = new Vec(0, 0)\n\t\tif (len === 0) {\n\t\t\treturn avg\n\t\t}\n\t\tfor (let i = 0; i < len; i++) {\n\t\t\tavg.add(arr[i])\n\t\t}\n\t\treturn avg.div(len)\n\t}\n\n\tstatic Clamp(A: Vec, min: number, max?: number) {\n\t\tif (max === undefined) {\n\t\t\treturn new Vec(Math.min(Math.max(A.x, min)), Math.min(Math.max(A.y, min)))\n\t\t}\n\n\t\treturn new Vec(Math.min(Math.max(A.x, min), max), Math.min(Math.max(A.y, min), max))\n\t}\n\n\t/**\n\t * Get an array of points (with simulated pressure) between two points.\n\t *\n\t * @param A - The first point.\n\t * @param B - The second point.\n\t * @param steps - The number of points to return.\n\t */\n\tstatic PointsBetween(A: VecModel, B: VecModel, steps = 6): Vec[] {\n\t\tconst results: Vec[] = []\n\n\t\tfor (let i = 0; i < steps; i++) {\n\t\t\tconst t = EASINGS.easeInQuad(i / (steps - 1))\n\t\t\tconst point = Vec.Lrp(A, B, t)\n\t\t\tpoint.z = Math.min(1, 0.5 + Math.abs(0.5 - ease(t)) * 0.65)\n\t\t\tresults.push(point)\n\t\t}\n\n\t\treturn results\n\t}\n\n\tstatic SnapToGrid(A: VecLike, gridSize = 8) {\n\t\treturn new Vec(Math.round(A.x / gridSize) * gridSize, Math.round(A.y / gridSize) * gridSize)\n\t}\n}\n\nconst ease = (t: number) => (t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t)\n"], -+ "mappings": "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", -+ "names": [] -+} -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/primitives/easings.mjs b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/primitives/easings.mjs -new file mode 100644 -index 0000000..78f7f14 ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/primitives/easings.mjs -@@ -0,0 +1,25 @@ -+const EASINGS = { -+ linear: (t) => t, -+ easeInQuad: (t) => t * t, -+ easeOutQuad: (t) => t * (2 - t), -+ easeInOutQuad: (t) => t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t, -+ easeInCubic: (t) => t * t * t, -+ easeOutCubic: (t) => --t * t * t + 1, -+ easeInOutCubic: (t) => t < 0.5 ? 4 * t * t * t : (t - 1) * (2 * t - 2) * (2 * t - 2) + 1, -+ easeInQuart: (t) => t * t * t * t, -+ easeOutQuart: (t) => 1 - --t * t * t * t, -+ easeInOutQuart: (t) => t < 0.5 ? 8 * t * t * t * t : 1 - 8 * --t * t * t * t, -+ easeInQuint: (t) => t * t * t * t * t, -+ easeOutQuint: (t) => 1 + --t * t * t * t * t, -+ easeInOutQuint: (t) => t < 0.5 ? 16 * t * t * t * t * t : 1 + 16 * --t * t * t * t * t, -+ easeInSine: (t) => 1 - Math.cos(t * Math.PI / 2), -+ easeOutSine: (t) => Math.sin(t * Math.PI / 2), -+ easeInOutSine: (t) => -(Math.cos(Math.PI * t) - 1) / 2, -+ easeInExpo: (t) => t <= 0 ? 0 : Math.pow(2, 10 * t - 10), -+ easeOutExpo: (t) => t >= 1 ? 1 : 1 - Math.pow(2, -10 * t), -+ easeInOutExpo: (t) => t <= 0 ? 0 : t >= 1 ? 1 : t < 0.5 ? Math.pow(2, 20 * t - 10) / 2 : (2 - Math.pow(2, -20 * t + 10)) / 2 -+}; -+export { -+ EASINGS -+}; -+//# sourceMappingURL=easings.mjs.map -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/primitives/easings.mjs.map b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/primitives/easings.mjs.map -new file mode 100644 -index 0000000..a645977 ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/primitives/easings.mjs.map -@@ -0,0 +1,7 @@ -+{ -+ "version": 3, -+ "sources": ["../../../src/lib/primitives/easings.ts"], -+ "sourcesContent": ["/** @public */\nexport const EASINGS = {\n\tlinear: (t: number) => t,\n\teaseInQuad: (t: number) => t * t,\n\teaseOutQuad: (t: number) => t * (2 - t),\n\teaseInOutQuad: (t: number) => (t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t),\n\teaseInCubic: (t: number) => t * t * t,\n\teaseOutCubic: (t: number) => --t * t * t + 1,\n\teaseInOutCubic: (t: number) =>\n\t\tt < 0.5 ? 4 * t * t * t : (t - 1) * (2 * t - 2) * (2 * t - 2) + 1,\n\teaseInQuart: (t: number) => t * t * t * t,\n\teaseOutQuart: (t: number) => 1 - --t * t * t * t,\n\teaseInOutQuart: (t: number) => (t < 0.5 ? 8 * t * t * t * t : 1 - 8 * --t * t * t * t),\n\teaseInQuint: (t: number) => t * t * t * t * t,\n\teaseOutQuint: (t: number) => 1 + --t * t * t * t * t,\n\teaseInOutQuint: (t: number) => (t < 0.5 ? 16 * t * t * t * t * t : 1 + 16 * --t * t * t * t * t),\n\teaseInSine: (t: number) => 1 - Math.cos((t * Math.PI) / 2),\n\teaseOutSine: (t: number) => Math.sin((t * Math.PI) / 2),\n\teaseInOutSine: (t: number) => -(Math.cos(Math.PI * t) - 1) / 2,\n\teaseInExpo: (t: number) => (t <= 0 ? 0 : Math.pow(2, 10 * t - 10)),\n\teaseOutExpo: (t: number) => (t >= 1 ? 1 : 1 - Math.pow(2, -10 * t)),\n\teaseInOutExpo: (t: number) =>\n\t\tt <= 0\n\t\t\t? 0\n\t\t\t: t >= 1\n\t\t\t\t? 1\n\t\t\t\t: t < 0.5\n\t\t\t\t\t? Math.pow(2, 20 * t - 10) / 2\n\t\t\t\t\t: (2 - Math.pow(2, -20 * t + 10)) / 2,\n} as const\n\n/** @public */\nexport type EasingType = keyof typeof EASINGS\n"], -+ "mappings": "AACO,MAAM,UAAU;AAAA,EACtB,QAAQ,CAAC,MAAc;AAAA,EACvB,YAAY,CAAC,MAAc,IAAI;AAAA,EAC/B,aAAa,CAAC,MAAc,KAAK,IAAI;AAAA,EACrC,eAAe,CAAC,MAAe,IAAI,MAAM,IAAI,IAAI,IAAI,MAAM,IAAI,IAAI,KAAK;AAAA,EACxE,aAAa,CAAC,MAAc,IAAI,IAAI;AAAA,EACpC,cAAc,CAAC,MAAc,EAAE,IAAI,IAAI,IAAI;AAAA,EAC3C,gBAAgB,CAAC,MAChB,IAAI,MAAM,IAAI,IAAI,IAAI,KAAK,IAAI,MAAM,IAAI,IAAI,MAAM,IAAI,IAAI,KAAK;AAAA,EACjE,aAAa,CAAC,MAAc,IAAI,IAAI,IAAI;AAAA,EACxC,cAAc,CAAC,MAAc,IAAI,EAAE,IAAI,IAAI,IAAI;AAAA,EAC/C,gBAAgB,CAAC,MAAe,IAAI,MAAM,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,EAAE,IAAI,IAAI,IAAI;AAAA,EACpF,aAAa,CAAC,MAAc,IAAI,IAAI,IAAI,IAAI;AAAA,EAC5C,cAAc,CAAC,MAAc,IAAI,EAAE,IAAI,IAAI,IAAI,IAAI;AAAA,EACnD,gBAAgB,CAAC,MAAe,IAAI,MAAM,KAAK,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,KAAK,EAAE,IAAI,IAAI,IAAI,IAAI;AAAA,EAC9F,YAAY,CAAC,MAAc,IAAI,KAAK,IAAK,IAAI,KAAK,KAAM,CAAC;AAAA,EACzD,aAAa,CAAC,MAAc,KAAK,IAAK,IAAI,KAAK,KAAM,CAAC;AAAA,EACtD,eAAe,CAAC,MAAc,EAAE,KAAK,IAAI,KAAK,KAAK,CAAC,IAAI,KAAK;AAAA,EAC7D,YAAY,CAAC,MAAe,KAAK,IAAI,IAAI,KAAK,IAAI,GAAG,KAAK,IAAI,EAAE;AAAA,EAChE,aAAa,CAAC,MAAe,KAAK,IAAI,IAAI,IAAI,KAAK,IAAI,GAAG,MAAM,CAAC;AAAA,EACjE,eAAe,CAAC,MACf,KAAK,IACF,IACA,KAAK,IACJ,IACA,IAAI,MACH,KAAK,IAAI,GAAG,KAAK,IAAI,EAAE,IAAI,KAC1B,IAAI,KAAK,IAAI,GAAG,MAAM,IAAI,EAAE,KAAK;AACzC;", -+ "names": [] -+} -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/primitives/geometry/Arc2d.mjs b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/primitives/geometry/Arc2d.mjs -new file mode 100644 -index 0000000..1153578 ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/primitives/geometry/Arc2d.mjs -@@ -0,0 +1,79 @@ -+import { Vec } from "../Vec.mjs"; -+import { intersectLineSegmentCircle } from "../intersect.mjs"; -+import { getArcMeasure, getPointInArcT, getPointOnCircle } from "../utils.mjs"; -+import { Geometry2d } from "./Geometry2d.mjs"; -+import { getVerticesCountForLength } from "./geometry-constants.mjs"; -+class Arc2d extends Geometry2d { -+ _center; -+ radius; -+ start; -+ end; -+ largeArcFlag; -+ sweepFlag; -+ measure; -+ angleStart; -+ angleEnd; -+ constructor(config) { -+ super({ ...config, isFilled: false, isClosed: false }); -+ const { center, sweepFlag, largeArcFlag, start, end } = config; -+ if (start.equals(end)) throw Error(`Arc must have different start and end points.`); -+ this.angleStart = Vec.Angle(center, start); -+ this.angleEnd = Vec.Angle(center, end); -+ this.radius = Vec.Dist(center, start); -+ this.measure = getArcMeasure(this.angleStart, this.angleEnd, sweepFlag, largeArcFlag); -+ this.start = start; -+ this.end = end; -+ this.sweepFlag = sweepFlag; -+ this.largeArcFlag = largeArcFlag; -+ this._center = center; -+ } -+ nearestPoint(point) { -+ const { _center, measure, radius, angleEnd, angleStart, start: A, end: B } = this; -+ const t = getPointInArcT(measure, angleStart, angleEnd, _center.angle(point)); -+ if (t <= 0) return A; -+ if (t >= 1) return B; -+ const P = _center.clone().add(point.clone().sub(_center).uni().mul(radius)); -+ let nearest; -+ let dist = Infinity; -+ let d; -+ for (const p of [A, B, P]) { -+ d = Vec.Dist2(point, p); -+ if (d < dist) { -+ nearest = p; -+ dist = d; -+ } -+ } -+ if (!nearest) throw Error("nearest point not found"); -+ return nearest; -+ } -+ hitTestLineSegment(A, B) { -+ const { _center, radius, measure, angleStart, angleEnd } = this; -+ const intersection = intersectLineSegmentCircle(A, B, _center, radius); -+ if (intersection === null) return false; -+ return intersection.some((p) => { -+ const result = getPointInArcT(measure, angleStart, angleEnd, _center.angle(p)); -+ return result >= 0 && result <= 1; -+ }); -+ } -+ getVertices() { -+ const { _center, measure, length, radius, angleStart } = this; -+ const vertices = []; -+ for (let i = 0, n = getVerticesCountForLength(Math.abs(length)); i < n + 1; i++) { -+ const t = i / n * measure; -+ const angle = angleStart + t; -+ vertices.push(getPointOnCircle(_center, radius, angle)); -+ } -+ return vertices; -+ } -+ getSvgPathData(first = true) { -+ const { start, end, radius, largeArcFlag, sweepFlag } = this; -+ return `${first ? `M${start.toFixed()}` : ``} A${radius} ${radius} 0 ${largeArcFlag} ${sweepFlag} ${end.toFixed()}`; -+ } -+ getLength() { -+ return this.measure * this.radius; -+ } -+} -+export { -+ Arc2d -+}; -+//# sourceMappingURL=Arc2d.mjs.map -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/primitives/geometry/Arc2d.mjs.map b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/primitives/geometry/Arc2d.mjs.map -new file mode 100644 -index 0000000..434b52a ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/primitives/geometry/Arc2d.mjs.map -@@ -0,0 +1,7 @@ -+{ -+ "version": 3, -+ "sources": ["../../../../src/lib/primitives/geometry/Arc2d.ts"], -+ "sourcesContent": ["import { Vec } from '../Vec'\nimport { intersectLineSegmentCircle } from '../intersect'\nimport { getArcMeasure, getPointInArcT, getPointOnCircle } from '../utils'\nimport { Geometry2d, Geometry2dOptions } from './Geometry2d'\nimport { getVerticesCountForLength } from './geometry-constants'\n\n/** @public */\nexport class Arc2d extends Geometry2d {\n\t_center: Vec\n\tradius: number\n\tstart: Vec\n\tend: Vec\n\tlargeArcFlag: number\n\tsweepFlag: number\n\n\tmeasure: number\n\tangleStart: number\n\tangleEnd: number\n\n\tconstructor(\n\t\tconfig: Omit & {\n\t\t\tcenter: Vec\n\t\t\tstart: Vec\n\t\t\tend: Vec\n\t\t\tsweepFlag: number\n\t\t\tlargeArcFlag: number\n\t\t}\n\t) {\n\t\tsuper({ ...config, isFilled: false, isClosed: false })\n\t\tconst { center, sweepFlag, largeArcFlag, start, end } = config\n\t\tif (start.equals(end)) throw Error(`Arc must have different start and end points.`)\n\n\t\t// ensure that the start and end are clockwise\n\t\tthis.angleStart = Vec.Angle(center, start)\n\t\tthis.angleEnd = Vec.Angle(center, end)\n\t\tthis.radius = Vec.Dist(center, start)\n\t\tthis.measure = getArcMeasure(this.angleStart, this.angleEnd, sweepFlag, largeArcFlag)\n\n\t\tthis.start = start\n\t\tthis.end = end\n\n\t\tthis.sweepFlag = sweepFlag\n\t\tthis.largeArcFlag = largeArcFlag\n\t\tthis._center = center\n\t}\n\n\tnearestPoint(point: Vec): Vec {\n\t\tconst { _center, measure, radius, angleEnd, angleStart, start: A, end: B } = this\n\t\tconst t = getPointInArcT(measure, angleStart, angleEnd, _center.angle(point))\n\t\tif (t <= 0) return A\n\t\tif (t >= 1) return B\n\n\t\t// Get the point (P) on the arc, then pick the nearest of A, B, and P\n\t\tconst P = _center.clone().add(point.clone().sub(_center).uni().mul(radius))\n\n\t\tlet nearest: Vec | undefined\n\t\tlet dist = Infinity\n\t\tlet d: number\n\t\tfor (const p of [A, B, P]) {\n\t\t\td = Vec.Dist2(point, p)\n\t\t\tif (d < dist) {\n\t\t\t\tnearest = p\n\t\t\t\tdist = d\n\t\t\t}\n\t\t}\n\t\tif (!nearest) throw Error('nearest point not found')\n\t\treturn nearest\n\t}\n\n\thitTestLineSegment(A: Vec, B: Vec): boolean {\n\t\tconst { _center, radius, measure, angleStart, angleEnd } = this\n\t\tconst intersection = intersectLineSegmentCircle(A, B, _center, radius)\n\t\tif (intersection === null) return false\n\n\t\treturn intersection.some((p) => {\n\t\t\tconst result = getPointInArcT(measure, angleStart, angleEnd, _center.angle(p))\n\t\t\treturn result >= 0 && result <= 1\n\t\t})\n\t}\n\n\tgetVertices(): Vec[] {\n\t\tconst { _center, measure, length, radius, angleStart } = this\n\t\tconst vertices: Vec[] = []\n\t\tfor (let i = 0, n = getVerticesCountForLength(Math.abs(length)); i < n + 1; i++) {\n\t\t\tconst t = (i / n) * measure\n\t\t\tconst angle = angleStart + t\n\t\t\tvertices.push(getPointOnCircle(_center, radius, angle))\n\t\t}\n\t\treturn vertices\n\t}\n\n\tgetSvgPathData(first = true) {\n\t\tconst { start, end, radius, largeArcFlag, sweepFlag } = this\n\t\treturn `${first ? `M${start.toFixed()}` : ``} A${radius} ${radius} 0 ${largeArcFlag} ${sweepFlag} ${end.toFixed()}`\n\t}\n\n\toverride getLength() {\n\t\treturn this.measure * this.radius\n\t}\n}\n"], -+ "mappings": "AAAA,SAAS,WAAW;AACpB,SAAS,kCAAkC;AAC3C,SAAS,eAAe,gBAAgB,wBAAwB;AAChE,SAAS,kBAAqC;AAC9C,SAAS,iCAAiC;AAGnC,MAAM,cAAc,WAAW;AAAA,EACrC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAEA;AAAA,EACA;AAAA,EACA;AAAA,EAEA,YACC,QAOC;AACD,UAAM,EAAE,GAAG,QAAQ,UAAU,OAAO,UAAU,MAAM,CAAC;AACrD,UAAM,EAAE,QAAQ,WAAW,cAAc,OAAO,IAAI,IAAI;AACxD,QAAI,MAAM,OAAO,GAAG,EAAG,OAAM,MAAM,+CAA+C;AAGlF,SAAK,aAAa,IAAI,MAAM,QAAQ,KAAK;AACzC,SAAK,WAAW,IAAI,MAAM,QAAQ,GAAG;AACrC,SAAK,SAAS,IAAI,KAAK,QAAQ,KAAK;AACpC,SAAK,UAAU,cAAc,KAAK,YAAY,KAAK,UAAU,WAAW,YAAY;AAEpF,SAAK,QAAQ;AACb,SAAK,MAAM;AAEX,SAAK,YAAY;AACjB,SAAK,eAAe;AACpB,SAAK,UAAU;AAAA,EAChB;AAAA,EAEA,aAAa,OAAiB;AAC7B,UAAM,EAAE,SAAS,SAAS,QAAQ,UAAU,YAAY,OAAO,GAAG,KAAK,EAAE,IAAI;AAC7E,UAAM,IAAI,eAAe,SAAS,YAAY,UAAU,QAAQ,MAAM,KAAK,CAAC;AAC5E,QAAI,KAAK,EAAG,QAAO;AACnB,QAAI,KAAK,EAAG,QAAO;AAGnB,UAAM,IAAI,QAAQ,MAAM,EAAE,IAAI,MAAM,MAAM,EAAE,IAAI,OAAO,EAAE,IAAI,EAAE,IAAI,MAAM,CAAC;AAE1E,QAAI;AACJ,QAAI,OAAO;AACX,QAAI;AACJ,eAAW,KAAK,CAAC,GAAG,GAAG,CAAC,GAAG;AAC1B,UAAI,IAAI,MAAM,OAAO,CAAC;AACtB,UAAI,IAAI,MAAM;AACb,kBAAU;AACV,eAAO;AAAA,MACR;AAAA,IACD;AACA,QAAI,CAAC,QAAS,OAAM,MAAM,yBAAyB;AACnD,WAAO;AAAA,EACR;AAAA,EAEA,mBAAmB,GAAQ,GAAiB;AAC3C,UAAM,EAAE,SAAS,QAAQ,SAAS,YAAY,SAAS,IAAI;AAC3D,UAAM,eAAe,2BAA2B,GAAG,GAAG,SAAS,MAAM;AACrE,QAAI,iBAAiB,KAAM,QAAO;AAElC,WAAO,aAAa,KAAK,CAAC,MAAM;AAC/B,YAAM,SAAS,eAAe,SAAS,YAAY,UAAU,QAAQ,MAAM,CAAC,CAAC;AAC7E,aAAO,UAAU,KAAK,UAAU;AAAA,IACjC,CAAC;AAAA,EACF;AAAA,EAEA,cAAqB;AACpB,UAAM,EAAE,SAAS,SAAS,QAAQ,QAAQ,WAAW,IAAI;AACzD,UAAM,WAAkB,CAAC;AACzB,aAAS,IAAI,GAAG,IAAI,0BAA0B,KAAK,IAAI,MAAM,CAAC,GAAG,IAAI,IAAI,GAAG,KAAK;AAChF,YAAM,IAAK,IAAI,IAAK;AACpB,YAAM,QAAQ,aAAa;AAC3B,eAAS,KAAK,iBAAiB,SAAS,QAAQ,KAAK,CAAC;AAAA,IACvD;AACA,WAAO;AAAA,EACR;AAAA,EAEA,eAAe,QAAQ,MAAM;AAC5B,UAAM,EAAE,OAAO,KAAK,QAAQ,cAAc,UAAU,IAAI;AACxD,WAAO,GAAG,QAAQ,IAAI,MAAM,QAAQ,CAAC,KAAK,EAAE,KAAK,MAAM,IAAI,MAAM,MAAM,YAAY,IAAI,SAAS,IAAI,IAAI,QAAQ,CAAC;AAAA,EAClH;AAAA,EAES,YAAY;AACpB,WAAO,KAAK,UAAU,KAAK;AAAA,EAC5B;AACD;", -+ "names": [] -+} -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/primitives/geometry/Circle2d.mjs b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/primitives/geometry/Circle2d.mjs -new file mode 100644 -index 0000000..5c5f4a0 ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/primitives/geometry/Circle2d.mjs -@@ -0,0 +1,51 @@ -+import { Box } from "../Box.mjs"; -+import { Vec } from "../Vec.mjs"; -+import { intersectLineSegmentCircle } from "../intersect.mjs"; -+import { PI2, getPointOnCircle } from "../utils.mjs"; -+import { Geometry2d } from "./Geometry2d.mjs"; -+import { getVerticesCountForLength } from "./geometry-constants.mjs"; -+class Circle2d extends Geometry2d { -+ constructor(config) { -+ super({ isClosed: true, ...config }); -+ this.config = config; -+ const { x = 0, y = 0, radius } = config; -+ this.x = x; -+ this.y = y; -+ this._center = new Vec(radius + x, radius + y); -+ this.radius = radius; -+ } -+ _center; -+ radius; -+ x; -+ y; -+ getBounds() { -+ return new Box(this.x, this.y, this.radius * 2, this.radius * 2); -+ } -+ getVertices() { -+ const { _center, radius } = this; -+ const perimeter = PI2 * radius; -+ const vertices = []; -+ for (let i = 0, n = getVerticesCountForLength(perimeter); i < n; i++) { -+ const angle = i / n * PI2; -+ vertices.push(getPointOnCircle(_center, radius, angle)); -+ } -+ return vertices; -+ } -+ nearestPoint(point) { -+ const { _center, radius } = this; -+ if (_center.equals(point)) return Vec.AddXY(_center, radius, 0); -+ return _center.clone().add(point.clone().sub(_center).uni().mul(radius)); -+ } -+ hitTestLineSegment(A, B, distance = 0) { -+ const { _center, radius } = this; -+ return intersectLineSegmentCircle(A, B, _center, radius + distance) !== null; -+ } -+ getSvgPathData() { -+ const { _center, radius } = this; -+ return `M${_center.x + radius},${_center.y} a${radius},${radius} 0 1,0 ${radius * 2},0a${radius},${radius} 0 1,0 -${radius * 2},0`; -+ } -+} -+export { -+ Circle2d -+}; -+//# sourceMappingURL=Circle2d.mjs.map -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/primitives/geometry/Circle2d.mjs.map b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/primitives/geometry/Circle2d.mjs.map -new file mode 100644 -index 0000000..ff35675 ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/primitives/geometry/Circle2d.mjs.map -@@ -0,0 +1,7 @@ -+{ -+ "version": 3, -+ "sources": ["../../../../src/lib/primitives/geometry/Circle2d.ts"], -+ "sourcesContent": ["import { Box } from '../Box'\nimport { Vec } from '../Vec'\nimport { intersectLineSegmentCircle } from '../intersect'\nimport { PI2, getPointOnCircle } from '../utils'\nimport { Geometry2d, Geometry2dOptions } from './Geometry2d'\nimport { getVerticesCountForLength } from './geometry-constants'\n\n/** @public */\nexport class Circle2d extends Geometry2d {\n\t_center: Vec\n\tradius: number\n\tx: number\n\ty: number\n\n\tconstructor(\n\t\tpublic config: Omit & {\n\t\t\tx?: number\n\t\t\ty?: number\n\t\t\tradius: number\n\t\t\tisFilled: boolean\n\t\t}\n\t) {\n\t\tsuper({ isClosed: true, ...config })\n\t\tconst { x = 0, y = 0, radius } = config\n\t\tthis.x = x\n\t\tthis.y = y\n\t\tthis._center = new Vec(radius + x, radius + y)\n\t\tthis.radius = radius\n\t}\n\n\tgetBounds() {\n\t\treturn new Box(this.x, this.y, this.radius * 2, this.radius * 2)\n\t}\n\n\tgetVertices(): Vec[] {\n\t\tconst { _center, radius } = this\n\t\tconst perimeter = PI2 * radius\n\t\tconst vertices: Vec[] = []\n\t\tfor (let i = 0, n = getVerticesCountForLength(perimeter); i < n; i++) {\n\t\t\tconst angle = (i / n) * PI2\n\t\t\tvertices.push(getPointOnCircle(_center, radius, angle))\n\t\t}\n\t\treturn vertices\n\t}\n\n\tnearestPoint(point: Vec): Vec {\n\t\tconst { _center, radius } = this\n\t\tif (_center.equals(point)) return Vec.AddXY(_center, radius, 0)\n\t\treturn _center.clone().add(point.clone().sub(_center).uni().mul(radius))\n\t}\n\n\thitTestLineSegment(A: Vec, B: Vec, distance = 0): boolean {\n\t\tconst { _center, radius } = this\n\t\treturn intersectLineSegmentCircle(A, B, _center, radius + distance) !== null\n\t}\n\n\tgetSvgPathData(): string {\n\t\tconst { _center, radius } = this\n\t\treturn `M${_center.x + radius},${_center.y} a${radius},${radius} 0 1,0 ${radius * 2},0a${radius},${radius} 0 1,0 -${radius * 2},0`\n\t}\n}\n"], -+ "mappings": "AAAA,SAAS,WAAW;AACpB,SAAS,WAAW;AACpB,SAAS,kCAAkC;AAC3C,SAAS,KAAK,wBAAwB;AACtC,SAAS,kBAAqC;AAC9C,SAAS,iCAAiC;AAGnC,MAAM,iBAAiB,WAAW;AAAA,EAMxC,YACQ,QAMN;AACD,UAAM,EAAE,UAAU,MAAM,GAAG,OAAO,CAAC;AAP5B;AAQP,UAAM,EAAE,IAAI,GAAG,IAAI,GAAG,OAAO,IAAI;AACjC,SAAK,IAAI;AACT,SAAK,IAAI;AACT,SAAK,UAAU,IAAI,IAAI,SAAS,GAAG,SAAS,CAAC;AAC7C,SAAK,SAAS;AAAA,EACf;AAAA,EAnBA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAkBA,YAAY;AACX,WAAO,IAAI,IAAI,KAAK,GAAG,KAAK,GAAG,KAAK,SAAS,GAAG,KAAK,SAAS,CAAC;AAAA,EAChE;AAAA,EAEA,cAAqB;AACpB,UAAM,EAAE,SAAS,OAAO,IAAI;AAC5B,UAAM,YAAY,MAAM;AACxB,UAAM,WAAkB,CAAC;AACzB,aAAS,IAAI,GAAG,IAAI,0BAA0B,SAAS,GAAG,IAAI,GAAG,KAAK;AACrE,YAAM,QAAS,IAAI,IAAK;AACxB,eAAS,KAAK,iBAAiB,SAAS,QAAQ,KAAK,CAAC;AAAA,IACvD;AACA,WAAO;AAAA,EACR;AAAA,EAEA,aAAa,OAAiB;AAC7B,UAAM,EAAE,SAAS,OAAO,IAAI;AAC5B,QAAI,QAAQ,OAAO,KAAK,EAAG,QAAO,IAAI,MAAM,SAAS,QAAQ,CAAC;AAC9D,WAAO,QAAQ,MAAM,EAAE,IAAI,MAAM,MAAM,EAAE,IAAI,OAAO,EAAE,IAAI,EAAE,IAAI,MAAM,CAAC;AAAA,EACxE;AAAA,EAEA,mBAAmB,GAAQ,GAAQ,WAAW,GAAY;AACzD,UAAM,EAAE,SAAS,OAAO,IAAI;AAC5B,WAAO,2BAA2B,GAAG,GAAG,SAAS,SAAS,QAAQ,MAAM;AAAA,EACzE;AAAA,EAEA,iBAAyB;AACxB,UAAM,EAAE,SAAS,OAAO,IAAI;AAC5B,WAAO,IAAI,QAAQ,IAAI,MAAM,IAAI,QAAQ,CAAC,KAAK,MAAM,IAAI,MAAM,UAAU,SAAS,CAAC,MAAM,MAAM,IAAI,MAAM,WAAW,SAAS,CAAC;AAAA,EAC/H;AACD;", -+ "names": [] -+} -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/primitives/geometry/CubicBezier2d.mjs b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/primitives/geometry/CubicBezier2d.mjs -new file mode 100644 -index 0000000..36ca3e5 ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/primitives/geometry/CubicBezier2d.mjs -@@ -0,0 +1,73 @@ -+import { Vec } from "../Vec.mjs"; -+import { Polyline2d } from "./Polyline2d.mjs"; -+class CubicBezier2d extends Polyline2d { -+ a; -+ b; -+ c; -+ d; -+ constructor(config) { -+ const { start: a, cp1: b, cp2: c, end: d } = config; -+ super({ ...config, points: [a, d] }); -+ this.a = a; -+ this.b = b; -+ this.c = c; -+ this.d = d; -+ } -+ getVertices() { -+ const vertices = []; -+ const { a, b, c, d } = this; -+ for (let i = 0, n = 10; i <= n; i++) { -+ const t = i / n; -+ vertices.push( -+ new Vec( -+ (1 - t) * (1 - t) * (1 - t) * a.x + 3 * ((1 - t) * (1 - t)) * t * b.x + 3 * (1 - t) * (t * t) * c.x + t * t * t * d.x, -+ (1 - t) * (1 - t) * (1 - t) * a.y + 3 * ((1 - t) * (1 - t)) * t * b.y + 3 * (1 - t) * (t * t) * c.y + t * t * t * d.y -+ ) -+ ); -+ } -+ return vertices; -+ } -+ midPoint() { -+ return CubicBezier2d.GetAtT(this, 0.5); -+ } -+ nearestPoint(A) { -+ let nearest; -+ let dist = Infinity; -+ let d; -+ let p; -+ for (const edge of this.segments) { -+ p = edge.nearestPoint(A); -+ d = Vec.Dist2(p, A); -+ if (d < dist) { -+ nearest = p; -+ dist = d; -+ } -+ } -+ if (!nearest) throw Error("nearest point not found"); -+ return nearest; -+ } -+ getSvgPathData(first = true) { -+ const { a, b, c, d } = this; -+ return `${first ? `M ${a.toFixed()} ` : ``} C${b.toFixed()} ${c.toFixed()} ${d.toFixed()}`; -+ } -+ static GetAtT(segment, t) { -+ const { a, b, c, d } = segment; -+ return new Vec( -+ (1 - t) * (1 - t) * (1 - t) * a.x + 3 * ((1 - t) * (1 - t)) * t * b.x + 3 * (1 - t) * (t * t) * c.x + t * t * t * d.x, -+ (1 - t) * (1 - t) * (1 - t) * a.y + 3 * ((1 - t) * (1 - t)) * t * b.y + 3 * (1 - t) * (t * t) * c.y + t * t * t * d.y -+ ); -+ } -+ getLength(precision = 32) { -+ let n1, p1 = this.a, length = 0; -+ for (let i = 1; i <= precision; i++) { -+ n1 = CubicBezier2d.GetAtT(this, i / precision); -+ length += Vec.Dist(p1, n1); -+ p1 = n1; -+ } -+ return length; -+ } -+} -+export { -+ CubicBezier2d -+}; -+//# sourceMappingURL=CubicBezier2d.mjs.map -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/primitives/geometry/CubicBezier2d.mjs.map b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/primitives/geometry/CubicBezier2d.mjs.map -new file mode 100644 -index 0000000..c888b36 ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/primitives/geometry/CubicBezier2d.mjs.map -@@ -0,0 +1,7 @@ -+{ -+ "version": 3, -+ "sources": ["../../../../src/lib/primitives/geometry/CubicBezier2d.ts"], -+ "sourcesContent": ["import { Vec } from '../Vec'\nimport { Geometry2dOptions } from './Geometry2d'\nimport { Polyline2d } from './Polyline2d'\n\n/** @public */\nexport class CubicBezier2d extends Polyline2d {\n\ta: Vec\n\tb: Vec\n\tc: Vec\n\td: Vec\n\n\tconstructor(\n\t\tconfig: Omit & {\n\t\t\tstart: Vec\n\t\t\tcp1: Vec\n\t\t\tcp2: Vec\n\t\t\tend: Vec\n\t\t}\n\t) {\n\t\tconst { start: a, cp1: b, cp2: c, end: d } = config\n\t\tsuper({ ...config, points: [a, d] })\n\n\t\tthis.a = a\n\t\tthis.b = b\n\t\tthis.c = c\n\t\tthis.d = d\n\t}\n\n\toverride getVertices() {\n\t\tconst vertices = [] as Vec[]\n\t\tconst { a, b, c, d } = this\n\t\t// we'll always use ten vertices for each bezier curve\n\t\tfor (let i = 0, n = 10; i <= n; i++) {\n\t\t\tconst t = i / n\n\t\t\tvertices.push(\n\t\t\t\tnew Vec(\n\t\t\t\t\t(1 - t) * (1 - t) * (1 - t) * a.x +\n\t\t\t\t\t\t3 * ((1 - t) * (1 - t)) * t * b.x +\n\t\t\t\t\t\t3 * (1 - t) * (t * t) * c.x +\n\t\t\t\t\t\tt * t * t * d.x,\n\t\t\t\t\t(1 - t) * (1 - t) * (1 - t) * a.y +\n\t\t\t\t\t\t3 * ((1 - t) * (1 - t)) * t * b.y +\n\t\t\t\t\t\t3 * (1 - t) * (t * t) * c.y +\n\t\t\t\t\t\tt * t * t * d.y\n\t\t\t\t)\n\t\t\t)\n\t\t}\n\t\treturn vertices\n\t}\n\n\tmidPoint() {\n\t\treturn CubicBezier2d.GetAtT(this, 0.5)\n\t}\n\n\tnearestPoint(A: Vec): Vec {\n\t\tlet nearest: Vec | undefined\n\t\tlet dist = Infinity\n\t\tlet d: number\n\t\tlet p: Vec\n\t\tfor (const edge of this.segments) {\n\t\t\tp = edge.nearestPoint(A)\n\t\t\td = Vec.Dist2(p, A)\n\t\t\tif (d < dist) {\n\t\t\t\tnearest = p\n\t\t\t\tdist = d\n\t\t\t}\n\t\t}\n\n\t\tif (!nearest) throw Error('nearest point not found')\n\t\treturn nearest\n\t}\n\n\tgetSvgPathData(first = true) {\n\t\tconst { a, b, c, d } = this\n\t\treturn `${first ? `M ${a.toFixed()} ` : ``} C${b.toFixed()} ${c.toFixed()} ${d.toFixed()}`\n\t}\n\n\tstatic GetAtT(segment: CubicBezier2d, t: number) {\n\t\tconst { a, b, c, d } = segment\n\t\treturn new Vec(\n\t\t\t(1 - t) * (1 - t) * (1 - t) * a.x +\n\t\t\t\t3 * ((1 - t) * (1 - t)) * t * b.x +\n\t\t\t\t3 * (1 - t) * (t * t) * c.x +\n\t\t\t\tt * t * t * d.x,\n\t\t\t(1 - t) * (1 - t) * (1 - t) * a.y +\n\t\t\t\t3 * ((1 - t) * (1 - t)) * t * b.y +\n\t\t\t\t3 * (1 - t) * (t * t) * c.y +\n\t\t\t\tt * t * t * d.y\n\t\t)\n\t}\n\n\toverride getLength(precision = 32) {\n\t\tlet n1: Vec,\n\t\t\tp1 = this.a,\n\t\t\tlength = 0\n\t\tfor (let i = 1; i <= precision; i++) {\n\t\t\tn1 = CubicBezier2d.GetAtT(this, i / precision)\n\t\t\tlength += Vec.Dist(p1, n1)\n\t\t\tp1 = n1\n\t\t}\n\t\treturn length\n\t}\n}\n"], -+ "mappings": "AAAA,SAAS,WAAW;AAEpB,SAAS,kBAAkB;AAGpB,MAAM,sBAAsB,WAAW;AAAA,EAC7C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAEA,YACC,QAMC;AACD,UAAM,EAAE,OAAO,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,EAAE,IAAI;AAC7C,UAAM,EAAE,GAAG,QAAQ,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;AAEnC,SAAK,IAAI;AACT,SAAK,IAAI;AACT,SAAK,IAAI;AACT,SAAK,IAAI;AAAA,EACV;AAAA,EAES,cAAc;AACtB,UAAM,WAAW,CAAC;AAClB,UAAM,EAAE,GAAG,GAAG,GAAG,EAAE,IAAI;AAEvB,aAAS,IAAI,GAAG,IAAI,IAAI,KAAK,GAAG,KAAK;AACpC,YAAM,IAAI,IAAI;AACd,eAAS;AAAA,QACR,IAAI;AAAA,WACF,IAAI,MAAM,IAAI,MAAM,IAAI,KAAK,EAAE,IAC/B,MAAM,IAAI,MAAM,IAAI,MAAM,IAAI,EAAE,IAChC,KAAK,IAAI,MAAM,IAAI,KAAK,EAAE,IAC1B,IAAI,IAAI,IAAI,EAAE;AAAA,WACd,IAAI,MAAM,IAAI,MAAM,IAAI,KAAK,EAAE,IAC/B,MAAM,IAAI,MAAM,IAAI,MAAM,IAAI,EAAE,IAChC,KAAK,IAAI,MAAM,IAAI,KAAK,EAAE,IAC1B,IAAI,IAAI,IAAI,EAAE;AAAA,QAChB;AAAA,MACD;AAAA,IACD;AACA,WAAO;AAAA,EACR;AAAA,EAEA,WAAW;AACV,WAAO,cAAc,OAAO,MAAM,GAAG;AAAA,EACtC;AAAA,EAEA,aAAa,GAAa;AACzB,QAAI;AACJ,QAAI,OAAO;AACX,QAAI;AACJ,QAAI;AACJ,eAAW,QAAQ,KAAK,UAAU;AACjC,UAAI,KAAK,aAAa,CAAC;AACvB,UAAI,IAAI,MAAM,GAAG,CAAC;AAClB,UAAI,IAAI,MAAM;AACb,kBAAU;AACV,eAAO;AAAA,MACR;AAAA,IACD;AAEA,QAAI,CAAC,QAAS,OAAM,MAAM,yBAAyB;AACnD,WAAO;AAAA,EACR;AAAA,EAEA,eAAe,QAAQ,MAAM;AAC5B,UAAM,EAAE,GAAG,GAAG,GAAG,EAAE,IAAI;AACvB,WAAO,GAAG,QAAQ,KAAK,EAAE,QAAQ,CAAC,MAAM,EAAE,KAAK,EAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;AAAA,EACzF;AAAA,EAEA,OAAO,OAAO,SAAwB,GAAW;AAChD,UAAM,EAAE,GAAG,GAAG,GAAG,EAAE,IAAI;AACvB,WAAO,IAAI;AAAA,OACT,IAAI,MAAM,IAAI,MAAM,IAAI,KAAK,EAAE,IAC/B,MAAM,IAAI,MAAM,IAAI,MAAM,IAAI,EAAE,IAChC,KAAK,IAAI,MAAM,IAAI,KAAK,EAAE,IAC1B,IAAI,IAAI,IAAI,EAAE;AAAA,OACd,IAAI,MAAM,IAAI,MAAM,IAAI,KAAK,EAAE,IAC/B,MAAM,IAAI,MAAM,IAAI,MAAM,IAAI,EAAE,IAChC,KAAK,IAAI,MAAM,IAAI,KAAK,EAAE,IAC1B,IAAI,IAAI,IAAI,EAAE;AAAA,IAChB;AAAA,EACD;AAAA,EAES,UAAU,YAAY,IAAI;AAClC,QAAI,IACH,KAAK,KAAK,GACV,SAAS;AACV,aAAS,IAAI,GAAG,KAAK,WAAW,KAAK;AACpC,WAAK,cAAc,OAAO,MAAM,IAAI,SAAS;AAC7C,gBAAU,IAAI,KAAK,IAAI,EAAE;AACzB,WAAK;AAAA,IACN;AACA,WAAO;AAAA,EACR;AACD;", -+ "names": [] -+} -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/primitives/geometry/CubicSpline2d.mjs b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/primitives/geometry/CubicSpline2d.mjs -new file mode 100644 -index 0000000..a5d9122 ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/primitives/geometry/CubicSpline2d.mjs -@@ -0,0 +1,73 @@ -+import { Vec } from "../Vec.mjs"; -+import { CubicBezier2d } from "./CubicBezier2d.mjs"; -+import { Geometry2d } from "./Geometry2d.mjs"; -+class CubicSpline2d extends Geometry2d { -+ points; -+ constructor(config) { -+ super({ ...config, isClosed: false, isFilled: false }); -+ const { points } = config; -+ this.points = points; -+ } -+ _segments; -+ // eslint-disable-next-line no-restricted-syntax -+ get segments() { -+ if (!this._segments) { -+ this._segments = []; -+ const { points } = this; -+ const len = points.length; -+ const last = len - 2; -+ const k = 1.25; -+ for (let i = 0; i < len - 1; i++) { -+ const p0 = i === 0 ? points[0] : points[i - 1]; -+ const p1 = points[i]; -+ const p2 = points[i + 1]; -+ const p3 = i === last ? p2 : points[i + 2]; -+ const start = p1, cp1 = i === 0 ? p0 : new Vec(p1.x + (p2.x - p0.x) / 6 * k, p1.y + (p2.y - p0.y) / 6 * k), cp2 = i === last ? p2 : new Vec(p2.x - (p3.x - p1.x) / 6 * k, p2.y - (p3.y - p1.y) / 6 * k), end = p2; -+ this._segments.push(new CubicBezier2d({ start, cp1, cp2, end })); -+ } -+ } -+ return this._segments; -+ } -+ getLength() { -+ return this.segments.reduce((acc, segment) => acc + segment.length, 0); -+ } -+ getVertices() { -+ const vertices = this.segments.reduce((acc, segment) => { -+ return acc.concat(segment.vertices); -+ }, []); -+ vertices.push(this.points[this.points.length - 1]); -+ return vertices; -+ } -+ nearestPoint(A) { -+ let nearest; -+ let dist = Infinity; -+ let d; -+ let p; -+ for (const segment of this.segments) { -+ p = segment.nearestPoint(A); -+ d = Vec.Dist2(p, A); -+ if (d < dist) { -+ nearest = p; -+ dist = d; -+ } -+ } -+ if (!nearest) throw Error("nearest point not found"); -+ return nearest; -+ } -+ hitTestLineSegment(A, B) { -+ return this.segments.some((segment) => segment.hitTestLineSegment(A, B)); -+ } -+ getSvgPathData() { -+ let d = this.segments.reduce((d2, segment, i) => { -+ return d2 + segment.getSvgPathData(i === 0); -+ }, ""); -+ if (this.isClosed) { -+ d += "Z"; -+ } -+ return d; -+ } -+} -+export { -+ CubicSpline2d -+}; -+//# sourceMappingURL=CubicSpline2d.mjs.map -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/primitives/geometry/CubicSpline2d.mjs.map b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/primitives/geometry/CubicSpline2d.mjs.map -new file mode 100644 -index 0000000..da175d0 ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/primitives/geometry/CubicSpline2d.mjs.map -@@ -0,0 +1,7 @@ -+{ -+ "version": 3, -+ "sources": ["../../../../src/lib/primitives/geometry/CubicSpline2d.ts"], -+ "sourcesContent": ["import { Vec } from '../Vec'\nimport { CubicBezier2d } from './CubicBezier2d'\nimport { Geometry2d, Geometry2dOptions } from './Geometry2d'\n\n/** @public */\nexport class CubicSpline2d extends Geometry2d {\n\tpoints: Vec[]\n\n\tconstructor(config: Omit & { points: Vec[] }) {\n\t\tsuper({ ...config, isClosed: false, isFilled: false })\n\t\tconst { points } = config\n\n\t\tthis.points = points\n\t}\n\n\t_segments?: CubicBezier2d[]\n\n\t// eslint-disable-next-line no-restricted-syntax\n\tget segments() {\n\t\tif (!this._segments) {\n\t\t\tthis._segments = []\n\t\t\tconst { points } = this\n\n\t\t\tconst len = points.length\n\t\t\tconst last = len - 2\n\t\t\tconst k = 1.25\n\n\t\t\tfor (let i = 0; i < len - 1; i++) {\n\t\t\t\tconst p0 = i === 0 ? points[0] : points[i - 1]\n\t\t\t\tconst p1 = points[i]\n\t\t\t\tconst p2 = points[i + 1]\n\t\t\t\tconst p3 = i === last ? p2 : points[i + 2]\n\t\t\t\tconst start = p1,\n\t\t\t\t\tcp1 =\n\t\t\t\t\t\ti === 0 ? p0 : new Vec(p1.x + ((p2.x - p0.x) / 6) * k, p1.y + ((p2.y - p0.y) / 6) * k),\n\t\t\t\t\tcp2 =\n\t\t\t\t\t\ti === last\n\t\t\t\t\t\t\t? p2\n\t\t\t\t\t\t\t: new Vec(p2.x - ((p3.x - p1.x) / 6) * k, p2.y - ((p3.y - p1.y) / 6) * k),\n\t\t\t\t\tend = p2\n\n\t\t\t\tthis._segments.push(new CubicBezier2d({ start, cp1, cp2, end }))\n\t\t\t}\n\t\t}\n\n\t\treturn this._segments\n\t}\n\n\toverride getLength() {\n\t\treturn this.segments.reduce((acc, segment) => acc + segment.length, 0)\n\t}\n\n\tgetVertices() {\n\t\tconst vertices = this.segments.reduce((acc, segment) => {\n\t\t\treturn acc.concat(segment.vertices)\n\t\t}, [] as Vec[])\n\t\tvertices.push(this.points[this.points.length - 1])\n\t\treturn vertices\n\t}\n\n\tnearestPoint(A: Vec): Vec {\n\t\tlet nearest: Vec | undefined\n\t\tlet dist = Infinity\n\t\tlet d: number\n\t\tlet p: Vec\n\t\tfor (const segment of this.segments) {\n\t\t\tp = segment.nearestPoint(A)\n\t\t\td = Vec.Dist2(p, A)\n\t\t\tif (d < dist) {\n\t\t\t\tnearest = p\n\t\t\t\tdist = d\n\t\t\t}\n\t\t}\n\t\tif (!nearest) throw Error('nearest point not found')\n\t\treturn nearest\n\t}\n\n\thitTestLineSegment(A: Vec, B: Vec): boolean {\n\t\treturn this.segments.some((segment) => segment.hitTestLineSegment(A, B))\n\t}\n\n\tgetSvgPathData() {\n\t\tlet d = this.segments.reduce((d, segment, i) => {\n\t\t\treturn d + segment.getSvgPathData(i === 0)\n\t\t}, '')\n\n\t\tif (this.isClosed) {\n\t\t\td += 'Z'\n\t\t}\n\n\t\treturn d\n\t}\n}\n"], -+ "mappings": "AAAA,SAAS,WAAW;AACpB,SAAS,qBAAqB;AAC9B,SAAS,kBAAqC;AAGvC,MAAM,sBAAsB,WAAW;AAAA,EAC7C;AAAA,EAEA,YAAY,QAA8E;AACzF,UAAM,EAAE,GAAG,QAAQ,UAAU,OAAO,UAAU,MAAM,CAAC;AACrD,UAAM,EAAE,OAAO,IAAI;AAEnB,SAAK,SAAS;AAAA,EACf;AAAA,EAEA;AAAA;AAAA,EAGA,IAAI,WAAW;AACd,QAAI,CAAC,KAAK,WAAW;AACpB,WAAK,YAAY,CAAC;AAClB,YAAM,EAAE,OAAO,IAAI;AAEnB,YAAM,MAAM,OAAO;AACnB,YAAM,OAAO,MAAM;AACnB,YAAM,IAAI;AAEV,eAAS,IAAI,GAAG,IAAI,MAAM,GAAG,KAAK;AACjC,cAAM,KAAK,MAAM,IAAI,OAAO,CAAC,IAAI,OAAO,IAAI,CAAC;AAC7C,cAAM,KAAK,OAAO,CAAC;AACnB,cAAM,KAAK,OAAO,IAAI,CAAC;AACvB,cAAM,KAAK,MAAM,OAAO,KAAK,OAAO,IAAI,CAAC;AACzC,cAAM,QAAQ,IACb,MACC,MAAM,IAAI,KAAK,IAAI,IAAI,GAAG,KAAM,GAAG,IAAI,GAAG,KAAK,IAAK,GAAG,GAAG,KAAM,GAAG,IAAI,GAAG,KAAK,IAAK,CAAC,GACtF,MACC,MAAM,OACH,KACA,IAAI,IAAI,GAAG,KAAM,GAAG,IAAI,GAAG,KAAK,IAAK,GAAG,GAAG,KAAM,GAAG,IAAI,GAAG,KAAK,IAAK,CAAC,GAC1E,MAAM;AAEP,aAAK,UAAU,KAAK,IAAI,cAAc,EAAE,OAAO,KAAK,KAAK,IAAI,CAAC,CAAC;AAAA,MAChE;AAAA,IACD;AAEA,WAAO,KAAK;AAAA,EACb;AAAA,EAES,YAAY;AACpB,WAAO,KAAK,SAAS,OAAO,CAAC,KAAK,YAAY,MAAM,QAAQ,QAAQ,CAAC;AAAA,EACtE;AAAA,EAEA,cAAc;AACb,UAAM,WAAW,KAAK,SAAS,OAAO,CAAC,KAAK,YAAY;AACvD,aAAO,IAAI,OAAO,QAAQ,QAAQ;AAAA,IACnC,GAAG,CAAC,CAAU;AACd,aAAS,KAAK,KAAK,OAAO,KAAK,OAAO,SAAS,CAAC,CAAC;AACjD,WAAO;AAAA,EACR;AAAA,EAEA,aAAa,GAAa;AACzB,QAAI;AACJ,QAAI,OAAO;AACX,QAAI;AACJ,QAAI;AACJ,eAAW,WAAW,KAAK,UAAU;AACpC,UAAI,QAAQ,aAAa,CAAC;AAC1B,UAAI,IAAI,MAAM,GAAG,CAAC;AAClB,UAAI,IAAI,MAAM;AACb,kBAAU;AACV,eAAO;AAAA,MACR;AAAA,IACD;AACA,QAAI,CAAC,QAAS,OAAM,MAAM,yBAAyB;AACnD,WAAO;AAAA,EACR;AAAA,EAEA,mBAAmB,GAAQ,GAAiB;AAC3C,WAAO,KAAK,SAAS,KAAK,CAAC,YAAY,QAAQ,mBAAmB,GAAG,CAAC,CAAC;AAAA,EACxE;AAAA,EAEA,iBAAiB;AAChB,QAAI,IAAI,KAAK,SAAS,OAAO,CAACA,IAAG,SAAS,MAAM;AAC/C,aAAOA,KAAI,QAAQ,eAAe,MAAM,CAAC;AAAA,IAC1C,GAAG,EAAE;AAEL,QAAI,KAAK,UAAU;AAClB,WAAK;AAAA,IACN;AAEA,WAAO;AAAA,EACR;AACD;", -+ "names": ["d"] -+} -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/primitives/geometry/Edge2d.mjs b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/primitives/geometry/Edge2d.mjs -new file mode 100644 -index 0000000..8d9d0b0 ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/primitives/geometry/Edge2d.mjs -@@ -0,0 +1,51 @@ -+import { Vec } from "../Vec.mjs"; -+import { linesIntersect } from "../intersect.mjs"; -+import { Geometry2d } from "./Geometry2d.mjs"; -+class Edge2d extends Geometry2d { -+ start; -+ end; -+ d; -+ u; -+ ul; -+ constructor(config) { -+ super({ ...config, isClosed: false, isFilled: false }); -+ const { start, end } = config; -+ this.start = start; -+ this.end = end; -+ this.d = start.clone().sub(end); -+ this.u = this.d.clone().uni(); -+ this.ul = this.u.len(); -+ } -+ getLength() { -+ return this.d.len(); -+ } -+ midPoint() { -+ return this.start.lrp(this.end, 0.5); -+ } -+ getVertices() { -+ return [this.start, this.end]; -+ } -+ nearestPoint(point) { -+ const { start, end, u, ul: l } = this; -+ if (l === 0) return start; -+ const k = Vec.Sub(point, start).dpr(u) / l; -+ const cx = start.x + u.x * k; -+ if (cx < Math.min(start.x, end.x)) return start.x < end.x ? start : end; -+ if (cx > Math.max(start.x, end.x)) return start.x > end.x ? start : end; -+ const cy = start.y + u.y * k; -+ if (cy < Math.min(start.y, end.y)) return start.y < end.y ? start : end; -+ if (cy > Math.max(start.y, end.y)) return start.y > end.y ? start : end; -+ return new Vec(cx, cy); -+ } -+ hitTestLineSegment(A, B, distance = 0) { -+ return linesIntersect(A, B, this.start, this.end) || this.distanceToLineSegment(A, B) <= distance; -+ } -+ getSvgPathData(first = true) { -+ const { start, end } = this; -+ return `${first ? `M${start.toFixed()}` : ``} L${end.toFixed()}`; -+ } -+} -+export { -+ Edge2d -+}; -+//# sourceMappingURL=Edge2d.mjs.map -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/primitives/geometry/Edge2d.mjs.map b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/primitives/geometry/Edge2d.mjs.map -new file mode 100644 -index 0000000..062305e ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/primitives/geometry/Edge2d.mjs.map -@@ -0,0 +1,7 @@ -+{ -+ "version": 3, -+ "sources": ["../../../../src/lib/primitives/geometry/Edge2d.ts"], -+ "sourcesContent": ["import { Vec } from '../Vec'\nimport { linesIntersect } from '../intersect'\nimport { Geometry2d } from './Geometry2d'\n\n/** @public */\nexport class Edge2d extends Geometry2d {\n\tstart: Vec\n\tend: Vec\n\td: Vec\n\tu: Vec\n\tul: number\n\n\tconstructor(config: { start: Vec; end: Vec }) {\n\t\tsuper({ ...config, isClosed: false, isFilled: false })\n\t\tconst { start, end } = config\n\n\t\tthis.start = start\n\t\tthis.end = end\n\n\t\tthis.d = start.clone().sub(end) // the delta from start to end\n\t\tthis.u = this.d.clone().uni() // the unit vector of the edge\n\t\tthis.ul = this.u.len() // the length of the unit vector\n\t}\n\n\toverride getLength() {\n\t\treturn this.d.len()\n\t}\n\n\tmidPoint(): Vec {\n\t\treturn this.start.lrp(this.end, 0.5)\n\t}\n\n\toverride getVertices(): Vec[] {\n\t\treturn [this.start, this.end]\n\t}\n\n\toverride nearestPoint(point: Vec): Vec {\n\t\tconst { start, end, u, ul: l } = this\n\t\tif (l === 0) return start // no length in the unit vector\n\t\tconst k = Vec.Sub(point, start).dpr(u) / l\n\t\tconst cx = start.x + u.x * k\n\t\tif (cx < Math.min(start.x, end.x)) return start.x < end.x ? start : end\n\t\tif (cx > Math.max(start.x, end.x)) return start.x > end.x ? start : end\n\t\tconst cy = start.y + u.y * k\n\t\tif (cy < Math.min(start.y, end.y)) return start.y < end.y ? start : end\n\t\tif (cy > Math.max(start.y, end.y)) return start.y > end.y ? start : end\n\t\treturn new Vec(cx, cy)\n\t}\n\n\toverride hitTestLineSegment(A: Vec, B: Vec, distance = 0): boolean {\n\t\treturn (\n\t\t\tlinesIntersect(A, B, this.start, this.end) || this.distanceToLineSegment(A, B) <= distance\n\t\t)\n\t}\n\n\tgetSvgPathData(first = true) {\n\t\tconst { start, end } = this\n\t\treturn `${first ? `M${start.toFixed()}` : ``} L${end.toFixed()}`\n\t}\n}\n"], -+ "mappings": "AAAA,SAAS,WAAW;AACpB,SAAS,sBAAsB;AAC/B,SAAS,kBAAkB;AAGpB,MAAM,eAAe,WAAW;AAAA,EACtC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAEA,YAAY,QAAkC;AAC7C,UAAM,EAAE,GAAG,QAAQ,UAAU,OAAO,UAAU,MAAM,CAAC;AACrD,UAAM,EAAE,OAAO,IAAI,IAAI;AAEvB,SAAK,QAAQ;AACb,SAAK,MAAM;AAEX,SAAK,IAAI,MAAM,MAAM,EAAE,IAAI,GAAG;AAC9B,SAAK,IAAI,KAAK,EAAE,MAAM,EAAE,IAAI;AAC5B,SAAK,KAAK,KAAK,EAAE,IAAI;AAAA,EACtB;AAAA,EAES,YAAY;AACpB,WAAO,KAAK,EAAE,IAAI;AAAA,EACnB;AAAA,EAEA,WAAgB;AACf,WAAO,KAAK,MAAM,IAAI,KAAK,KAAK,GAAG;AAAA,EACpC;AAAA,EAES,cAAqB;AAC7B,WAAO,CAAC,KAAK,OAAO,KAAK,GAAG;AAAA,EAC7B;AAAA,EAES,aAAa,OAAiB;AACtC,UAAM,EAAE,OAAO,KAAK,GAAG,IAAI,EAAE,IAAI;AACjC,QAAI,MAAM,EAAG,QAAO;AACpB,UAAM,IAAI,IAAI,IAAI,OAAO,KAAK,EAAE,IAAI,CAAC,IAAI;AACzC,UAAM,KAAK,MAAM,IAAI,EAAE,IAAI;AAC3B,QAAI,KAAK,KAAK,IAAI,MAAM,GAAG,IAAI,CAAC,EAAG,QAAO,MAAM,IAAI,IAAI,IAAI,QAAQ;AACpE,QAAI,KAAK,KAAK,IAAI,MAAM,GAAG,IAAI,CAAC,EAAG,QAAO,MAAM,IAAI,IAAI,IAAI,QAAQ;AACpE,UAAM,KAAK,MAAM,IAAI,EAAE,IAAI;AAC3B,QAAI,KAAK,KAAK,IAAI,MAAM,GAAG,IAAI,CAAC,EAAG,QAAO,MAAM,IAAI,IAAI,IAAI,QAAQ;AACpE,QAAI,KAAK,KAAK,IAAI,MAAM,GAAG,IAAI,CAAC,EAAG,QAAO,MAAM,IAAI,IAAI,IAAI,QAAQ;AACpE,WAAO,IAAI,IAAI,IAAI,EAAE;AAAA,EACtB;AAAA,EAES,mBAAmB,GAAQ,GAAQ,WAAW,GAAY;AAClE,WACC,eAAe,GAAG,GAAG,KAAK,OAAO,KAAK,GAAG,KAAK,KAAK,sBAAsB,GAAG,CAAC,KAAK;AAAA,EAEpF;AAAA,EAEA,eAAe,QAAQ,MAAM;AAC5B,UAAM,EAAE,OAAO,IAAI,IAAI;AACvB,WAAO,GAAG,QAAQ,IAAI,MAAM,QAAQ,CAAC,KAAK,EAAE,KAAK,IAAI,QAAQ,CAAC;AAAA,EAC/D;AACD;", -+ "names": [] -+} -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/primitives/geometry/Ellipse2d.mjs b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/primitives/geometry/Ellipse2d.mjs -new file mode 100644 -index 0000000..2c3fcec ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/primitives/geometry/Ellipse2d.mjs -@@ -0,0 +1,98 @@ -+import { Box } from "../Box.mjs"; -+import { Vec } from "../Vec.mjs"; -+import { PI, PI2, perimeterOfEllipse } from "../utils.mjs"; -+import { Edge2d } from "./Edge2d.mjs"; -+import { Geometry2d } from "./Geometry2d.mjs"; -+import { getVerticesCountForLength } from "./geometry-constants.mjs"; -+class Ellipse2d extends Geometry2d { -+ constructor(config) { -+ super({ ...config, isClosed: true }); -+ this.config = config; -+ const { width, height } = config; -+ this.w = width; -+ this.h = height; -+ } -+ w; -+ h; -+ _edges; -+ // eslint-disable-next-line no-restricted-syntax -+ get edges() { -+ if (!this._edges) { -+ const { vertices } = this; -+ this._edges = []; -+ for (let i = 0, n = vertices.length; i < n; i++) { -+ const start = vertices[i]; -+ const end = vertices[(i + 1) % n]; -+ this._edges.push(new Edge2d({ start, end })); -+ } -+ } -+ return this._edges; -+ } -+ getVertices() { -+ const w = Math.max(1, this.w); -+ const h = Math.max(1, this.h); -+ const cx = w / 2; -+ const cy = h / 2; -+ const q = Math.pow(cx - cy, 2) / Math.pow(cx + cy, 2); -+ const p = PI * (cx + cy) * (1 + 3 * q / (10 + Math.sqrt(4 - 3 * q))); -+ const len = getVerticesCountForLength(p); -+ const step = PI2 / len; -+ const a = Math.cos(step); -+ const b = Math.sin(step); -+ let sin = 0; -+ let cos = 1; -+ let ts = 0; -+ let tc = 1; -+ const vertices = Array(len); -+ for (let i = 0; i < len; i++) { -+ vertices[i] = new Vec(cx + cx * cos, cy + cy * sin); -+ ts = b * cos + a * sin; -+ tc = a * cos - b * sin; -+ sin = ts; -+ cos = tc; -+ } -+ return vertices; -+ } -+ nearestPoint(A) { -+ let nearest; -+ let dist = Infinity; -+ let d; -+ let p; -+ for (const edge of this.edges) { -+ p = edge.nearestPoint(A); -+ d = Vec.Dist2(p, A); -+ if (d < dist) { -+ nearest = p; -+ dist = d; -+ } -+ } -+ if (!nearest) throw Error("nearest point not found"); -+ return nearest; -+ } -+ hitTestLineSegment(A, B) { -+ return this.edges.some((edge) => edge.hitTestLineSegment(A, B)); -+ } -+ getBounds() { -+ return new Box(0, 0, this.w, this.h); -+ } -+ getLength() { -+ const { w, h } = this; -+ const cx = w / 2; -+ const cy = h / 2; -+ const rx = Math.max(0, cx); -+ const ry = Math.max(0, cy); -+ return perimeterOfEllipse(rx, ry); -+ } -+ getSvgPathData(first = false) { -+ const { w, h } = this; -+ const cx = w / 2; -+ const cy = h / 2; -+ const rx = Math.max(0, cx); -+ const ry = Math.max(0, cy); -+ return `${first ? `M${cx - rx},${cy}` : ``} a${rx},${ry},0,1,1,${rx * 2},0a${rx},${ry},0,1,1,-${rx * 2},0`; -+ } -+} -+export { -+ Ellipse2d -+}; -+//# sourceMappingURL=Ellipse2d.mjs.map -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/primitives/geometry/Ellipse2d.mjs.map b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/primitives/geometry/Ellipse2d.mjs.map -new file mode 100644 -index 0000000..aa91a37 ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/primitives/geometry/Ellipse2d.mjs.map -@@ -0,0 +1,7 @@ -+{ -+ "version": 3, -+ "sources": ["../../../../src/lib/primitives/geometry/Ellipse2d.ts"], -+ "sourcesContent": ["import { Box } from '../Box'\nimport { Vec } from '../Vec'\nimport { PI, PI2, perimeterOfEllipse } from '../utils'\nimport { Edge2d } from './Edge2d'\nimport { Geometry2d, Geometry2dOptions } from './Geometry2d'\nimport { getVerticesCountForLength } from './geometry-constants'\n\n/** @public */\nexport class Ellipse2d extends Geometry2d {\n\tw: number\n\th: number\n\n\tconstructor(\n\t\tpublic config: Omit & {\n\t\t\twidth: number\n\t\t\theight: number\n\t\t}\n\t) {\n\t\tsuper({ ...config, isClosed: true })\n\t\tconst { width, height } = config\n\t\tthis.w = width\n\t\tthis.h = height\n\t}\n\n\t_edges?: Edge2d[]\n\n\t// eslint-disable-next-line no-restricted-syntax\n\tget edges() {\n\t\tif (!this._edges) {\n\t\t\tconst { vertices } = this\n\t\t\tthis._edges = []\n\t\t\tfor (let i = 0, n = vertices.length; i < n; i++) {\n\t\t\t\tconst start = vertices[i]\n\t\t\t\tconst end = vertices[(i + 1) % n]\n\t\t\t\tthis._edges.push(new Edge2d({ start, end }))\n\t\t\t}\n\t\t}\n\n\t\treturn this._edges\n\t}\n\n\tgetVertices() {\n\t\t// Perimeter of the ellipse\n\t\tconst w = Math.max(1, this.w)\n\t\tconst h = Math.max(1, this.h)\n\t\tconst cx = w / 2\n\t\tconst cy = h / 2\n\t\tconst q = Math.pow(cx - cy, 2) / Math.pow(cx + cy, 2)\n\t\tconst p = PI * (cx + cy) * (1 + (3 * q) / (10 + Math.sqrt(4 - 3 * q)))\n\t\t// Number of points\n\t\tconst len = getVerticesCountForLength(p)\n\t\t// Size of step\n\t\tconst step = PI2 / len\n\n\t\tconst a = Math.cos(step)\n\t\tconst b = Math.sin(step)\n\n\t\tlet sin = 0\n\t\tlet cos = 1\n\t\tlet ts = 0\n\t\tlet tc = 1\n\n\t\tconst vertices = Array(len)\n\n\t\tfor (let i = 0; i < len; i++) {\n\t\t\tvertices[i] = new Vec(cx + cx * cos, cy + cy * sin)\n\t\t\tts = b * cos + a * sin\n\t\t\ttc = a * cos - b * sin\n\t\t\tsin = ts\n\t\t\tcos = tc\n\t\t}\n\n\t\treturn vertices\n\t}\n\n\tnearestPoint(A: Vec): Vec {\n\t\tlet nearest: Vec | undefined\n\t\tlet dist = Infinity\n\t\tlet d: number\n\t\tlet p: Vec\n\t\tfor (const edge of this.edges) {\n\t\t\tp = edge.nearestPoint(A)\n\t\t\td = Vec.Dist2(p, A)\n\t\t\tif (d < dist) {\n\t\t\t\tnearest = p\n\t\t\t\tdist = d\n\t\t\t}\n\t\t}\n\t\tif (!nearest) throw Error('nearest point not found')\n\t\treturn nearest\n\t}\n\n\thitTestLineSegment(A: Vec, B: Vec): boolean {\n\t\treturn this.edges.some((edge) => edge.hitTestLineSegment(A, B))\n\t}\n\n\tgetBounds() {\n\t\treturn new Box(0, 0, this.w, this.h)\n\t}\n\n\tgetLength(): number {\n\t\tconst { w, h } = this\n\t\tconst cx = w / 2\n\t\tconst cy = h / 2\n\t\tconst rx = Math.max(0, cx)\n\t\tconst ry = Math.max(0, cy)\n\t\treturn perimeterOfEllipse(rx, ry)\n\t}\n\n\tgetSvgPathData(first = false) {\n\t\tconst { w, h } = this\n\t\tconst cx = w / 2\n\t\tconst cy = h / 2\n\t\tconst rx = Math.max(0, cx)\n\t\tconst ry = Math.max(0, cy)\n\t\treturn `${first ? `M${cx - rx},${cy}` : ``} a${rx},${ry},0,1,1,${rx * 2},0a${rx},${ry},0,1,1,-${rx * 2},0`\n\t}\n}\n"], -+ "mappings": "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", -+ "names": [] -+} -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/primitives/geometry/Geometry2d.mjs b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/primitives/geometry/Geometry2d.mjs -new file mode 100644 -index 0000000..e86cf49 ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/primitives/geometry/Geometry2d.mjs -@@ -0,0 +1,151 @@ -+import { Box } from "../Box.mjs"; -+import { Vec } from "../Vec.mjs"; -+import { pointInPolygon } from "../utils.mjs"; -+class Geometry2d { -+ isFilled = false; -+ isClosed = true; -+ isLabel = false; -+ debugColor; -+ ignore; -+ constructor(opts) { -+ this.isFilled = opts.isFilled; -+ this.isClosed = opts.isClosed; -+ this.isLabel = opts.isLabel ?? false; -+ this.debugColor = opts.debugColor; -+ this.ignore = opts.ignore; -+ } -+ // hitTestPoint(point: Vec, margin = 0, hitInside = false) { -+ // // We've removed the broad phase here; that should be done outside of the call -+ // return this.distanceToPoint(point, hitInside) <= margin -+ // } -+ hitTestPoint(point, margin = 0, hitInside = false) { -+ if (this.isClosed && (this.isFilled || hitInside) && pointInPolygon(point, this.vertices)) { -+ return true; -+ } -+ return Vec.Dist2(point, this.nearestPoint(point)) <= margin * margin; -+ } -+ distanceToPoint(point, hitInside = false) { -+ return point.dist(this.nearestPoint(point)) * (this.isClosed && (this.isFilled || hitInside) && pointInPolygon(point, this.vertices) ? -1 : 1); -+ } -+ distanceToLineSegment(A, B) { -+ if (A.equals(B)) return this.distanceToPoint(A); -+ const { vertices } = this; -+ let nearest; -+ let dist = Infinity; -+ let d, p, q; -+ for (let i = 0; i < vertices.length; i++) { -+ p = vertices[i]; -+ q = Vec.NearestPointOnLineSegment(A, B, p, true); -+ d = Vec.Dist2(p, q); -+ if (d < dist) { -+ dist = d; -+ nearest = q; -+ } -+ } -+ if (!nearest) throw Error("nearest point not found"); -+ return this.isClosed && this.isFilled && pointInPolygon(nearest, this.vertices) ? -dist : dist; -+ } -+ hitTestLineSegment(A, B, distance = 0) { -+ return this.distanceToLineSegment(A, B) <= distance; -+ } -+ nearestPointOnLineSegment(A, B) { -+ const { vertices } = this; -+ let nearest; -+ let dist = Infinity; -+ let d, p, q; -+ for (let i = 0; i < vertices.length; i++) { -+ p = vertices[i]; -+ q = Vec.NearestPointOnLineSegment(A, B, p, true); -+ d = Vec.Dist2(p, q); -+ if (d < dist) { -+ dist = d; -+ nearest = q; -+ } -+ } -+ if (!nearest) throw Error("nearest point not found"); -+ return nearest; -+ } -+ isPointInBounds(point, margin = 0) { -+ const { bounds } = this; -+ return !(point.x < bounds.minX - margin || point.y < bounds.minY - margin || point.x > bounds.maxX + margin || point.y > bounds.maxY + margin); -+ } -+ _vertices; -+ // eslint-disable-next-line no-restricted-syntax -+ get vertices() { -+ if (!this._vertices) { -+ this._vertices = this.getVertices(); -+ } -+ return this._vertices; -+ } -+ getBounds() { -+ return Box.FromPoints(this.vertices); -+ } -+ _bounds; -+ // eslint-disable-next-line no-restricted-syntax -+ get bounds() { -+ if (!this._bounds) { -+ this._bounds = this.getBounds(); -+ } -+ return this._bounds; -+ } -+ // eslint-disable-next-line no-restricted-syntax -+ get center() { -+ return this.bounds.center; -+ } -+ _area; -+ // eslint-disable-next-line no-restricted-syntax -+ get area() { -+ if (!this._area) { -+ this._area = this.getArea(); -+ } -+ return this._area; -+ } -+ getArea() { -+ if (!this.isClosed) { -+ return 0; -+ } -+ const { vertices } = this; -+ let area = 0; -+ for (let i = 0, n = vertices.length; i < n; i++) { -+ const curr = vertices[i]; -+ const next = vertices[(i + 1) % n]; -+ area += curr.x * next.y - next.x * curr.y; -+ } -+ return area / 2; -+ } -+ toSimpleSvgPath() { -+ let path = ""; -+ const { vertices } = this; -+ const n = vertices.length; -+ if (n === 0) return path; -+ path += `M${vertices[0].x},${vertices[0].y}`; -+ for (let i = 1; i < n; i++) { -+ path += `L${vertices[i].x},${vertices[i].y}`; -+ } -+ if (this.isClosed) { -+ path += "Z"; -+ } -+ return path; -+ } -+ _length; -+ // eslint-disable-next-line no-restricted-syntax -+ get length() { -+ if (this._length) return this._length; -+ this._length = this.getLength(); -+ return this._length; -+ } -+ getLength() { -+ const { vertices } = this; -+ let n1, p1 = vertices[0], length = 0; -+ for (let i = 1; i < vertices.length; i++) { -+ n1 = vertices[i]; -+ length += Vec.Dist2(p1, n1); -+ p1 = n1; -+ } -+ return Math.sqrt(length); -+ } -+} -+export { -+ Geometry2d -+}; -+//# sourceMappingURL=Geometry2d.mjs.map -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/primitives/geometry/Geometry2d.mjs.map b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/primitives/geometry/Geometry2d.mjs.map -new file mode 100644 -index 0000000..9022eac ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/primitives/geometry/Geometry2d.mjs.map -@@ -0,0 +1,7 @@ -+{ -+ "version": 3, -+ "sources": ["../../../../src/lib/primitives/geometry/Geometry2d.ts"], -+ "sourcesContent": ["import { Box } from '../Box'\nimport { Vec } from '../Vec'\nimport { pointInPolygon } from '../utils'\n\n/** @public */\nexport interface Geometry2dOptions {\n\tisFilled: boolean\n\tisClosed: boolean\n\tisLabel?: boolean\n\tdebugColor?: string\n\tignore?: boolean\n}\n\n/** @public */\nexport abstract class Geometry2d {\n\tisFilled = false\n\tisClosed = true\n\tisLabel = false\n\tdebugColor?: string\n\tignore?: boolean\n\n\tconstructor(opts: Geometry2dOptions) {\n\t\tthis.isFilled = opts.isFilled\n\t\tthis.isClosed = opts.isClosed\n\t\tthis.isLabel = opts.isLabel ?? false\n\t\tthis.debugColor = opts.debugColor\n\t\tthis.ignore = opts.ignore\n\t}\n\n\tabstract getVertices(): Vec[]\n\n\tabstract nearestPoint(point: Vec): Vec\n\n\t// hitTestPoint(point: Vec, margin = 0, hitInside = false) {\n\t// \t// We've removed the broad phase here; that should be done outside of the call\n\t// \treturn this.distanceToPoint(point, hitInside) <= margin\n\t// }\n\n\thitTestPoint(point: Vec, margin = 0, hitInside = false) {\n\t\t// First check whether the point is inside\n\t\tif (this.isClosed && (this.isFilled || hitInside) && pointInPolygon(point, this.vertices)) {\n\t\t\treturn true\n\t\t}\n\t\t// Then check whether the distance is within the margin\n\t\treturn Vec.Dist2(point, this.nearestPoint(point)) <= margin * margin\n\t}\n\n\tdistanceToPoint(point: Vec, hitInside = false) {\n\t\treturn (\n\t\t\tpoint.dist(this.nearestPoint(point)) *\n\t\t\t(this.isClosed && (this.isFilled || hitInside) && pointInPolygon(point, this.vertices)\n\t\t\t\t? -1\n\t\t\t\t: 1)\n\t\t)\n\t}\n\n\tdistanceToLineSegment(A: Vec, B: Vec) {\n\t\tif (A.equals(B)) return this.distanceToPoint(A)\n\t\tconst { vertices } = this\n\t\tlet nearest: Vec | undefined\n\t\tlet dist = Infinity\n\t\tlet d: number, p: Vec, q: Vec\n\t\tfor (let i = 0; i < vertices.length; i++) {\n\t\t\tp = vertices[i]\n\t\t\tq = Vec.NearestPointOnLineSegment(A, B, p, true)\n\t\t\td = Vec.Dist2(p, q)\n\t\t\tif (d < dist) {\n\t\t\t\tdist = d\n\t\t\t\tnearest = q\n\t\t\t}\n\t\t}\n\t\tif (!nearest) throw Error('nearest point not found')\n\t\treturn this.isClosed && this.isFilled && pointInPolygon(nearest, this.vertices) ? -dist : dist\n\t}\n\n\thitTestLineSegment(A: Vec, B: Vec, distance = 0): boolean {\n\t\treturn this.distanceToLineSegment(A, B) <= distance\n\t}\n\n\tnearestPointOnLineSegment(A: Vec, B: Vec): Vec {\n\t\tconst { vertices } = this\n\t\tlet nearest: Vec | undefined\n\t\tlet dist = Infinity\n\t\tlet d: number, p: Vec, q: Vec\n\t\tfor (let i = 0; i < vertices.length; i++) {\n\t\t\tp = vertices[i]\n\t\t\tq = Vec.NearestPointOnLineSegment(A, B, p, true)\n\t\t\td = Vec.Dist2(p, q)\n\t\t\tif (d < dist) {\n\t\t\t\tdist = d\n\t\t\t\tnearest = q\n\t\t\t}\n\t\t}\n\t\tif (!nearest) throw Error('nearest point not found')\n\t\treturn nearest\n\t}\n\n\tisPointInBounds(point: Vec, margin = 0) {\n\t\tconst { bounds } = this\n\t\treturn !(\n\t\t\tpoint.x < bounds.minX - margin ||\n\t\t\tpoint.y < bounds.minY - margin ||\n\t\t\tpoint.x > bounds.maxX + margin ||\n\t\t\tpoint.y > bounds.maxY + margin\n\t\t)\n\t}\n\n\tprivate _vertices: Vec[] | undefined\n\n\t// eslint-disable-next-line no-restricted-syntax\n\tget vertices(): Vec[] {\n\t\tif (!this._vertices) {\n\t\t\tthis._vertices = this.getVertices()\n\t\t}\n\n\t\treturn this._vertices\n\t}\n\n\tgetBounds() {\n\t\treturn Box.FromPoints(this.vertices)\n\t}\n\n\tprivate _bounds: Box | undefined\n\n\t// eslint-disable-next-line no-restricted-syntax\n\tget bounds(): Box {\n\t\tif (!this._bounds) {\n\t\t\tthis._bounds = this.getBounds()\n\t\t}\n\t\treturn this._bounds\n\t}\n\n\t// eslint-disable-next-line no-restricted-syntax\n\tget center() {\n\t\treturn this.bounds.center\n\t}\n\n\tprivate _area: number | undefined\n\n\t// eslint-disable-next-line no-restricted-syntax\n\tget area() {\n\t\tif (!this._area) {\n\t\t\tthis._area = this.getArea()\n\t\t}\n\t\treturn this._area\n\t}\n\n\tgetArea() {\n\t\tif (!this.isClosed) {\n\t\t\treturn 0\n\t\t}\n\t\tconst { vertices } = this\n\t\tlet area = 0\n\t\tfor (let i = 0, n = vertices.length; i < n; i++) {\n\t\t\tconst curr = vertices[i]\n\t\t\tconst next = vertices[(i + 1) % n]\n\t\t\tarea += curr.x * next.y - next.x * curr.y\n\t\t}\n\t\treturn area / 2\n\t}\n\n\ttoSimpleSvgPath() {\n\t\tlet path = ''\n\n\t\tconst { vertices } = this\n\t\tconst n = vertices.length\n\n\t\tif (n === 0) return path\n\n\t\tpath += `M${vertices[0].x},${vertices[0].y}`\n\n\t\tfor (let i = 1; i < n; i++) {\n\t\t\tpath += `L${vertices[i].x},${vertices[i].y}`\n\t\t}\n\n\t\tif (this.isClosed) {\n\t\t\tpath += 'Z'\n\t\t}\n\n\t\treturn path\n\t}\n\n\tprivate _length?: number\n\n\t// eslint-disable-next-line no-restricted-syntax\n\tget length() {\n\t\tif (this._length) return this._length\n\t\tthis._length = this.getLength()\n\t\treturn this._length\n\t}\n\n\tgetLength() {\n\t\tconst { vertices } = this\n\t\tlet n1: Vec,\n\t\t\tp1 = vertices[0],\n\t\t\tlength = 0\n\t\tfor (let i = 1; i < vertices.length; i++) {\n\t\t\tn1 = vertices[i]\n\t\t\tlength += Vec.Dist2(p1, n1)\n\t\t\tp1 = n1\n\t\t}\n\t\treturn Math.sqrt(length)\n\t}\n\n\tabstract getSvgPathData(first: boolean): string\n}\n"], -+ "mappings": "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", -+ "names": [] -+} -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/primitives/geometry/Group2d.mjs b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/primitives/geometry/Group2d.mjs -new file mode 100644 -index 0000000..e4b125d ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/primitives/geometry/Group2d.mjs -@@ -0,0 +1,82 @@ -+import { Box } from "../Box.mjs"; -+import { Vec } from "../Vec.mjs"; -+import { Geometry2d } from "./Geometry2d.mjs"; -+class Group2d extends Geometry2d { -+ children = []; -+ ignoredChildren = []; -+ constructor(config) { -+ super({ ...config, isClosed: true, isFilled: false }); -+ for (const child of config.children) { -+ if (child.ignore) { -+ this.ignoredChildren.push(child); -+ } else { -+ this.children.push(child); -+ } -+ } -+ if (this.children.length === 0) throw Error("Group2d must have at least one child"); -+ } -+ getVertices() { -+ return this.children.filter((c) => !c.isLabel).flatMap((c) => c.vertices); -+ } -+ nearestPoint(point) { -+ let dist = Infinity; -+ let nearest; -+ const { children } = this; -+ if (children.length === 0) { -+ throw Error("no children"); -+ } -+ let p; -+ let d; -+ for (const child of children) { -+ p = child.nearestPoint(point); -+ d = Vec.Dist2(p, point); -+ if (d < dist) { -+ dist = d; -+ nearest = p; -+ } -+ } -+ if (!nearest) throw Error("nearest point not found"); -+ return nearest; -+ } -+ distanceToPoint(point, hitInside = false) { -+ return Math.min(...this.children.map((c, i) => c.distanceToPoint(point, hitInside || i > 0))); -+ } -+ hitTestPoint(point, margin, hitInside) { -+ return !!this.children.filter((c) => !c.isLabel).find((c) => c.hitTestPoint(point, margin, hitInside)); -+ } -+ hitTestLineSegment(A, B, zoom) { -+ return !!this.children.filter((c) => !c.isLabel).find((c) => c.hitTestLineSegment(A, B, zoom)); -+ } -+ getArea() { -+ return this.children[0].area; -+ } -+ toSimpleSvgPath() { -+ let path = ""; -+ for (const child of this.children) { -+ path += child.toSimpleSvgPath(); -+ } -+ const corners = Box.FromPoints(this.vertices).corners; -+ for (let i = 0, n = corners.length; i < n; i++) { -+ const corner = corners[i]; -+ const prevCorner = corners[(i - 1 + n) % n]; -+ const prevDist = corner.dist(prevCorner); -+ const nextCorner = corners[(i + 1) % n]; -+ const nextDist = corner.dist(nextCorner); -+ const A = corner.clone().lrp(prevCorner, 4 / prevDist); -+ const B = corner; -+ const C = corner.clone().lrp(nextCorner, 4 / nextDist); -+ path += `M${A.x},${A.y} L${B.x},${B.y} L${C.x},${C.y} `; -+ } -+ return path; -+ } -+ getLength() { -+ return this.children.reduce((a, c) => c.isLabel ? a : a + c.length, 0); -+ } -+ getSvgPathData() { -+ return this.children.map((c, i) => c.isLabel ? "" : c.getSvgPathData(i === 0)).join(" "); -+ } -+} -+export { -+ Group2d -+}; -+//# sourceMappingURL=Group2d.mjs.map -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/primitives/geometry/Group2d.mjs.map b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/primitives/geometry/Group2d.mjs.map -new file mode 100644 -index 0000000..f7b16c9 ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/primitives/geometry/Group2d.mjs.map -@@ -0,0 +1,7 @@ -+{ -+ "version": 3, -+ "sources": ["../../../../src/lib/primitives/geometry/Group2d.ts"], -+ "sourcesContent": ["import { Box } from '../Box'\nimport { Vec } from '../Vec'\nimport { Geometry2d, Geometry2dOptions } from './Geometry2d'\n\n/** @public */\nexport class Group2d extends Geometry2d {\n\tchildren: Geometry2d[] = []\n\tignoredChildren: Geometry2d[] = []\n\n\tconstructor(\n\t\tconfig: Omit & {\n\t\t\tchildren: Geometry2d[]\n\t\t}\n\t) {\n\t\tsuper({ ...config, isClosed: true, isFilled: false })\n\n\t\tfor (const child of config.children) {\n\t\t\tif (child.ignore) {\n\t\t\t\tthis.ignoredChildren.push(child)\n\t\t\t} else {\n\t\t\t\tthis.children.push(child)\n\t\t\t}\n\t\t}\n\n\t\tif (this.children.length === 0) throw Error('Group2d must have at least one child')\n\t}\n\n\toverride getVertices(): Vec[] {\n\t\treturn this.children.filter((c) => !c.isLabel).flatMap((c) => c.vertices)\n\t}\n\n\toverride nearestPoint(point: Vec): Vec {\n\t\tlet dist = Infinity\n\t\tlet nearest: Vec | undefined\n\n\t\tconst { children } = this\n\n\t\tif (children.length === 0) {\n\t\t\tthrow Error('no children')\n\t\t}\n\n\t\tlet p: Vec\n\t\tlet d: number\n\t\tfor (const child of children) {\n\t\t\tp = child.nearestPoint(point)\n\t\t\td = Vec.Dist2(p, point)\n\t\t\tif (d < dist) {\n\t\t\t\tdist = d\n\t\t\t\tnearest = p\n\t\t\t}\n\t\t}\n\t\tif (!nearest) throw Error('nearest point not found')\n\t\treturn nearest\n\t}\n\n\toverride distanceToPoint(point: Vec, hitInside = false) {\n\t\treturn Math.min(...this.children.map((c, i) => c.distanceToPoint(point, hitInside || i > 0)))\n\t}\n\n\toverride hitTestPoint(point: Vec, margin: number, hitInside: boolean): boolean {\n\t\treturn !!this.children\n\t\t\t.filter((c) => !c.isLabel)\n\t\t\t.find((c) => c.hitTestPoint(point, margin, hitInside))\n\t}\n\n\toverride hitTestLineSegment(A: Vec, B: Vec, zoom: number): boolean {\n\t\treturn !!this.children.filter((c) => !c.isLabel).find((c) => c.hitTestLineSegment(A, B, zoom))\n\t}\n\n\tgetArea() {\n\t\t// todo: this is a temporary solution, assuming that the first child defines the group size; we would want to flatten the group and then find the area of the hull polygon\n\t\treturn this.children[0].area\n\t}\n\n\ttoSimpleSvgPath() {\n\t\tlet path = ''\n\t\tfor (const child of this.children) {\n\t\t\tpath += child.toSimpleSvgPath()\n\t\t}\n\n\t\tconst corners = Box.FromPoints(this.vertices).corners\n\t\t// draw just a few pixels around each corner, e.g. an L shape for the bottom left\n\n\t\tfor (let i = 0, n = corners.length; i < n; i++) {\n\t\t\tconst corner = corners[i]\n\t\t\tconst prevCorner = corners[(i - 1 + n) % n]\n\t\t\tconst prevDist = corner.dist(prevCorner)\n\t\t\tconst nextCorner = corners[(i + 1) % n]\n\t\t\tconst nextDist = corner.dist(nextCorner)\n\n\t\t\tconst A = corner.clone().lrp(prevCorner, 4 / prevDist)\n\t\t\tconst B = corner\n\t\t\tconst C = corner.clone().lrp(nextCorner, 4 / nextDist)\n\n\t\t\tpath += `M${A.x},${A.y} L${B.x},${B.y} L${C.x},${C.y} `\n\t\t}\n\t\treturn path\n\t}\n\n\tgetLength(): number {\n\t\treturn this.children.reduce((a, c) => (c.isLabel ? a : a + c.length), 0)\n\t}\n\n\tgetSvgPathData(): string {\n\t\treturn this.children.map((c, i) => (c.isLabel ? '' : c.getSvgPathData(i === 0))).join(' ')\n\t}\n}\n"], -+ "mappings": "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", -+ "names": [] -+} -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/primitives/geometry/Point2d.mjs b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/primitives/geometry/Point2d.mjs -new file mode 100644 -index 0000000..b60653e ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/primitives/geometry/Point2d.mjs -@@ -0,0 +1,27 @@ -+import { Vec } from "../Vec.mjs"; -+import { Geometry2d } from "./Geometry2d.mjs"; -+class Point2d extends Geometry2d { -+ point; -+ constructor(config) { -+ super({ ...config, isClosed: true, isFilled: true }); -+ const { point } = config; -+ this.point = point; -+ } -+ getVertices() { -+ return [this.point]; -+ } -+ nearestPoint() { -+ return this.point; -+ } -+ hitTestLineSegment(A, B, margin) { -+ return Vec.DistanceToLineSegment(A, B, this.point) < margin; -+ } -+ getSvgPathData() { -+ const { point } = this; -+ return `M${point.toFixed()}`; -+ } -+} -+export { -+ Point2d -+}; -+//# sourceMappingURL=Point2d.mjs.map -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/primitives/geometry/Point2d.mjs.map b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/primitives/geometry/Point2d.mjs.map -new file mode 100644 -index 0000000..2b0155c ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/primitives/geometry/Point2d.mjs.map -@@ -0,0 +1,7 @@ -+{ -+ "version": 3, -+ "sources": ["../../../../src/lib/primitives/geometry/Point2d.ts"], -+ "sourcesContent": ["import { Vec } from '../Vec'\nimport { Geometry2d, Geometry2dOptions } from './Geometry2d'\n\n/** @public */\nexport class Point2d extends Geometry2d {\n\tpoint: Vec\n\n\tconstructor(\n\t\tconfig: Omit & { margin: number; point: Vec }\n\t) {\n\t\tsuper({ ...config, isClosed: true, isFilled: true })\n\t\tconst { point } = config\n\n\t\tthis.point = point\n\t}\n\n\tgetVertices() {\n\t\treturn [this.point]\n\t}\n\n\tnearestPoint(): Vec {\n\t\treturn this.point\n\t}\n\n\thitTestLineSegment(A: Vec, B: Vec, margin: number): boolean {\n\t\treturn Vec.DistanceToLineSegment(A, B, this.point) < margin\n\t}\n\n\tgetSvgPathData() {\n\t\tconst { point } = this\n\t\treturn `M${point.toFixed()}`\n\t}\n}\n"], -+ "mappings": "AAAA,SAAS,WAAW;AACpB,SAAS,kBAAqC;AAGvC,MAAM,gBAAgB,WAAW;AAAA,EACvC;AAAA,EAEA,YACC,QACC;AACD,UAAM,EAAE,GAAG,QAAQ,UAAU,MAAM,UAAU,KAAK,CAAC;AACnD,UAAM,EAAE,MAAM,IAAI;AAElB,SAAK,QAAQ;AAAA,EACd;AAAA,EAEA,cAAc;AACb,WAAO,CAAC,KAAK,KAAK;AAAA,EACnB;AAAA,EAEA,eAAoB;AACnB,WAAO,KAAK;AAAA,EACb;AAAA,EAEA,mBAAmB,GAAQ,GAAQ,QAAyB;AAC3D,WAAO,IAAI,sBAAsB,GAAG,GAAG,KAAK,KAAK,IAAI;AAAA,EACtD;AAAA,EAEA,iBAAiB;AAChB,UAAM,EAAE,MAAM,IAAI;AAClB,WAAO,IAAI,MAAM,QAAQ,CAAC;AAAA,EAC3B;AACD;", -+ "names": [] -+} -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/primitives/geometry/Polygon2d.mjs b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/primitives/geometry/Polygon2d.mjs -new file mode 100644 -index 0000000..d9b1015 ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/primitives/geometry/Polygon2d.mjs -@@ -0,0 +1,11 @@ -+import { Polyline2d } from "./Polyline2d.mjs"; -+class Polygon2d extends Polyline2d { -+ constructor(config) { -+ super({ ...config }); -+ this.isClosed = true; -+ } -+} -+export { -+ Polygon2d -+}; -+//# sourceMappingURL=Polygon2d.mjs.map -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/primitives/geometry/Polygon2d.mjs.map b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/primitives/geometry/Polygon2d.mjs.map -new file mode 100644 -index 0000000..7760921 ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/primitives/geometry/Polygon2d.mjs.map -@@ -0,0 +1,7 @@ -+{ -+ "version": 3, -+ "sources": ["../../../../src/lib/primitives/geometry/Polygon2d.ts"], -+ "sourcesContent": ["import { Vec } from '../Vec'\nimport { Geometry2dOptions } from './Geometry2d'\nimport { Polyline2d } from './Polyline2d'\n\n/** @public */\nexport class Polygon2d extends Polyline2d {\n\tconstructor(config: Omit & { points: Vec[] }) {\n\t\tsuper({ ...config })\n\t\tthis.isClosed = true\n\t}\n}\n"], -+ "mappings": "AAEA,SAAS,kBAAkB;AAGpB,MAAM,kBAAkB,WAAW;AAAA,EACzC,YAAY,QAAiE;AAC5E,UAAM,EAAE,GAAG,OAAO,CAAC;AACnB,SAAK,WAAW;AAAA,EACjB;AACD;", -+ "names": [] -+} -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/primitives/geometry/Polyline2d.mjs b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/primitives/geometry/Polyline2d.mjs -new file mode 100644 -index 0000000..a332612 ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/primitives/geometry/Polyline2d.mjs -@@ -0,0 +1,72 @@ -+import { Vec } from "../Vec.mjs"; -+import { Edge2d } from "./Edge2d.mjs"; -+import { Geometry2d } from "./Geometry2d.mjs"; -+class Polyline2d extends Geometry2d { -+ points; -+ constructor(config) { -+ super({ isClosed: false, isFilled: false, ...config }); -+ const { points } = config; -+ this.points = points; -+ } -+ _segments; -+ // eslint-disable-next-line no-restricted-syntax -+ get segments() { -+ if (!this._segments) { -+ this._segments = []; -+ const { vertices } = this; -+ for (let i = 0, n = vertices.length - 1; i < n; i++) { -+ const start = vertices[i]; -+ const end = vertices[i + 1]; -+ this._segments.push(new Edge2d({ start, end })); -+ } -+ if (this.isClosed) { -+ this._segments.push(new Edge2d({ start: vertices[vertices.length - 1], end: vertices[0] })); -+ } -+ } -+ return this._segments; -+ } -+ getLength() { -+ return this.segments.reduce((acc, segment) => acc + segment.length, 0); -+ } -+ getVertices() { -+ return this.points; -+ } -+ nearestPoint(A) { -+ const { segments } = this; -+ let nearest = this.points[0]; -+ let dist = Infinity; -+ let p; -+ let d; -+ for (let i = 0; i < segments.length; i++) { -+ p = segments[i].nearestPoint(A); -+ d = Vec.Dist2(p, A); -+ if (d < dist) { -+ nearest = p; -+ dist = d; -+ } -+ } -+ if (!nearest) throw Error("nearest point not found"); -+ return nearest; -+ } -+ hitTestLineSegment(A, B, distance = 0) { -+ const { segments } = this; -+ for (let i = 0, n = segments.length; i < n; i++) { -+ if (segments[i].hitTestLineSegment(A, B, distance)) { -+ return true; -+ } -+ } -+ return false; -+ } -+ getSvgPathData() { -+ const { vertices } = this; -+ if (vertices.length < 2) return ""; -+ return vertices.reduce((acc, vertex, i) => { -+ if (i === 0) return `M ${vertex.x} ${vertex.y}`; -+ return `${acc} L ${vertex.x} ${vertex.y}`; -+ }, ""); -+ } -+} -+export { -+ Polyline2d -+}; -+//# sourceMappingURL=Polyline2d.mjs.map -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/primitives/geometry/Polyline2d.mjs.map b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/primitives/geometry/Polyline2d.mjs.map -new file mode 100644 -index 0000000..309c2c5 ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/primitives/geometry/Polyline2d.mjs.map -@@ -0,0 +1,7 @@ -+{ -+ "version": 3, -+ "sources": ["../../../../src/lib/primitives/geometry/Polyline2d.ts"], -+ "sourcesContent": ["import { Vec } from '../Vec'\nimport { Edge2d } from './Edge2d'\nimport { Geometry2d, Geometry2dOptions } from './Geometry2d'\n\n/** @public */\nexport class Polyline2d extends Geometry2d {\n\tpoints: Vec[]\n\n\tconstructor(config: Omit & { points: Vec[] }) {\n\t\tsuper({ isClosed: false, isFilled: false, ...config })\n\t\tconst { points } = config\n\t\tthis.points = points\n\t}\n\n\t_segments?: Edge2d[]\n\n\t// eslint-disable-next-line no-restricted-syntax\n\tget segments() {\n\t\tif (!this._segments) {\n\t\t\tthis._segments = []\n\t\t\tconst { vertices } = this\n\t\t\tfor (let i = 0, n = vertices.length - 1; i < n; i++) {\n\t\t\t\tconst start = vertices[i]\n\t\t\t\tconst end = vertices[i + 1]\n\t\t\t\tthis._segments.push(new Edge2d({ start, end }))\n\t\t\t}\n\n\t\t\tif (this.isClosed) {\n\t\t\t\tthis._segments.push(new Edge2d({ start: vertices[vertices.length - 1], end: vertices[0] }))\n\t\t\t}\n\t\t}\n\n\t\treturn this._segments\n\t}\n\n\toverride getLength() {\n\t\treturn this.segments.reduce((acc, segment) => acc + segment.length, 0)\n\t}\n\n\tgetVertices() {\n\t\treturn this.points\n\t}\n\n\tnearestPoint(A: Vec): Vec {\n\t\tconst { segments } = this\n\t\tlet nearest = this.points[0]\n\t\tlet dist = Infinity\n\t\tlet p: Vec // current point on segment\n\t\tlet d: number // distance from A to p\n\t\tfor (let i = 0; i < segments.length; i++) {\n\t\t\tp = segments[i].nearestPoint(A)\n\t\t\td = Vec.Dist2(p, A)\n\t\t\tif (d < dist) {\n\t\t\t\tnearest = p\n\t\t\t\tdist = d\n\t\t\t}\n\t\t}\n\t\tif (!nearest) throw Error('nearest point not found')\n\t\treturn nearest\n\t}\n\n\thitTestLineSegment(A: Vec, B: Vec, distance = 0): boolean {\n\t\tconst { segments } = this\n\t\tfor (let i = 0, n = segments.length; i < n; i++) {\n\t\t\tif (segments[i].hitTestLineSegment(A, B, distance)) {\n\t\t\t\treturn true\n\t\t\t}\n\t\t}\n\t\treturn false\n\t}\n\n\tgetSvgPathData(): string {\n\t\tconst { vertices } = this\n\t\tif (vertices.length < 2) return ''\n\t\treturn vertices.reduce((acc, vertex, i) => {\n\t\t\tif (i === 0) return `M ${vertex.x} ${vertex.y}`\n\t\t\treturn `${acc} L ${vertex.x} ${vertex.y}`\n\t\t}, '')\n\t}\n}\n"], -+ "mappings": "AAAA,SAAS,WAAW;AACpB,SAAS,cAAc;AACvB,SAAS,kBAAqC;AAGvC,MAAM,mBAAmB,WAAW;AAAA,EAC1C;AAAA,EAEA,YAAY,QAA8E;AACzF,UAAM,EAAE,UAAU,OAAO,UAAU,OAAO,GAAG,OAAO,CAAC;AACrD,UAAM,EAAE,OAAO,IAAI;AACnB,SAAK,SAAS;AAAA,EACf;AAAA,EAEA;AAAA;AAAA,EAGA,IAAI,WAAW;AACd,QAAI,CAAC,KAAK,WAAW;AACpB,WAAK,YAAY,CAAC;AAClB,YAAM,EAAE,SAAS,IAAI;AACrB,eAAS,IAAI,GAAG,IAAI,SAAS,SAAS,GAAG,IAAI,GAAG,KAAK;AACpD,cAAM,QAAQ,SAAS,CAAC;AACxB,cAAM,MAAM,SAAS,IAAI,CAAC;AAC1B,aAAK,UAAU,KAAK,IAAI,OAAO,EAAE,OAAO,IAAI,CAAC,CAAC;AAAA,MAC/C;AAEA,UAAI,KAAK,UAAU;AAClB,aAAK,UAAU,KAAK,IAAI,OAAO,EAAE,OAAO,SAAS,SAAS,SAAS,CAAC,GAAG,KAAK,SAAS,CAAC,EAAE,CAAC,CAAC;AAAA,MAC3F;AAAA,IACD;AAEA,WAAO,KAAK;AAAA,EACb;AAAA,EAES,YAAY;AACpB,WAAO,KAAK,SAAS,OAAO,CAAC,KAAK,YAAY,MAAM,QAAQ,QAAQ,CAAC;AAAA,EACtE;AAAA,EAEA,cAAc;AACb,WAAO,KAAK;AAAA,EACb;AAAA,EAEA,aAAa,GAAa;AACzB,UAAM,EAAE,SAAS,IAAI;AACrB,QAAI,UAAU,KAAK,OAAO,CAAC;AAC3B,QAAI,OAAO;AACX,QAAI;AACJ,QAAI;AACJ,aAAS,IAAI,GAAG,IAAI,SAAS,QAAQ,KAAK;AACzC,UAAI,SAAS,CAAC,EAAE,aAAa,CAAC;AAC9B,UAAI,IAAI,MAAM,GAAG,CAAC;AAClB,UAAI,IAAI,MAAM;AACb,kBAAU;AACV,eAAO;AAAA,MACR;AAAA,IACD;AACA,QAAI,CAAC,QAAS,OAAM,MAAM,yBAAyB;AACnD,WAAO;AAAA,EACR;AAAA,EAEA,mBAAmB,GAAQ,GAAQ,WAAW,GAAY;AACzD,UAAM,EAAE,SAAS,IAAI;AACrB,aAAS,IAAI,GAAG,IAAI,SAAS,QAAQ,IAAI,GAAG,KAAK;AAChD,UAAI,SAAS,CAAC,EAAE,mBAAmB,GAAG,GAAG,QAAQ,GAAG;AACnD,eAAO;AAAA,MACR;AAAA,IACD;AACA,WAAO;AAAA,EACR;AAAA,EAEA,iBAAyB;AACxB,UAAM,EAAE,SAAS,IAAI;AACrB,QAAI,SAAS,SAAS,EAAG,QAAO;AAChC,WAAO,SAAS,OAAO,CAAC,KAAK,QAAQ,MAAM;AAC1C,UAAI,MAAM,EAAG,QAAO,KAAK,OAAO,CAAC,IAAI,OAAO,CAAC;AAC7C,aAAO,GAAG,GAAG,MAAM,OAAO,CAAC,IAAI,OAAO,CAAC;AAAA,IACxC,GAAG,EAAE;AAAA,EACN;AACD;", -+ "names": [] -+} -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/primitives/geometry/Rectangle2d.mjs b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/primitives/geometry/Rectangle2d.mjs -new file mode 100644 -index 0000000..fb50263 ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/primitives/geometry/Rectangle2d.mjs -@@ -0,0 +1,36 @@ -+import { Box } from "../Box.mjs"; -+import { Vec } from "../Vec.mjs"; -+import { Polygon2d } from "./Polygon2d.mjs"; -+class Rectangle2d extends Polygon2d { -+ x; -+ y; -+ w; -+ h; -+ constructor(config) { -+ const { x = 0, y = 0, width, height } = config; -+ super({ -+ ...config, -+ points: [ -+ new Vec(x, y), -+ new Vec(x + width, y), -+ new Vec(x + width, y + height), -+ new Vec(x, y + height) -+ ] -+ }); -+ this.x = x; -+ this.y = y; -+ this.w = width; -+ this.h = height; -+ } -+ getBounds() { -+ return new Box(this.x, this.y, this.w, this.h); -+ } -+ getSvgPathData() { -+ const { x, y, w, h } = this; -+ return `M${x},${y} h${w} v${h} h-${w}z`; -+ } -+} -+export { -+ Rectangle2d -+}; -+//# sourceMappingURL=Rectangle2d.mjs.map -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/primitives/geometry/Rectangle2d.mjs.map b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/primitives/geometry/Rectangle2d.mjs.map -new file mode 100644 -index 0000000..aadfefb ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/primitives/geometry/Rectangle2d.mjs.map -@@ -0,0 +1,7 @@ -+{ -+ "version": 3, -+ "sources": ["../../../../src/lib/primitives/geometry/Rectangle2d.ts"], -+ "sourcesContent": ["import { Box } from '../Box'\nimport { Vec } from '../Vec'\nimport { Geometry2dOptions } from './Geometry2d'\nimport { Polygon2d } from './Polygon2d'\n\n/** @public */\nexport class Rectangle2d extends Polygon2d {\n\tx: number\n\ty: number\n\tw: number\n\th: number\n\n\tconstructor(\n\t\tconfig: Omit & {\n\t\t\tx?: number\n\t\t\ty?: number\n\t\t\twidth: number\n\t\t\theight: number\n\t\t}\n\t) {\n\t\tconst { x = 0, y = 0, width, height } = config\n\t\tsuper({\n\t\t\t...config,\n\t\t\tpoints: [\n\t\t\t\tnew Vec(x, y),\n\t\t\t\tnew Vec(x + width, y),\n\t\t\t\tnew Vec(x + width, y + height),\n\t\t\t\tnew Vec(x, y + height),\n\t\t\t],\n\t\t})\n\t\tthis.x = x\n\t\tthis.y = y\n\t\tthis.w = width\n\t\tthis.h = height\n\t}\n\n\tgetBounds() {\n\t\treturn new Box(this.x, this.y, this.w, this.h)\n\t}\n\n\tgetSvgPathData(): string {\n\t\tconst { x, y, w, h } = this\n\t\treturn `M${x},${y} h${w} v${h} h-${w}z`\n\t}\n}\n"], -+ "mappings": "AAAA,SAAS,WAAW;AACpB,SAAS,WAAW;AAEpB,SAAS,iBAAiB;AAGnB,MAAM,oBAAoB,UAAU;AAAA,EAC1C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAEA,YACC,QAMC;AACD,UAAM,EAAE,IAAI,GAAG,IAAI,GAAG,OAAO,OAAO,IAAI;AACxC,UAAM;AAAA,MACL,GAAG;AAAA,MACH,QAAQ;AAAA,QACP,IAAI,IAAI,GAAG,CAAC;AAAA,QACZ,IAAI,IAAI,IAAI,OAAO,CAAC;AAAA,QACpB,IAAI,IAAI,IAAI,OAAO,IAAI,MAAM;AAAA,QAC7B,IAAI,IAAI,GAAG,IAAI,MAAM;AAAA,MACtB;AAAA,IACD,CAAC;AACD,SAAK,IAAI;AACT,SAAK,IAAI;AACT,SAAK,IAAI;AACT,SAAK,IAAI;AAAA,EACV;AAAA,EAEA,YAAY;AACX,WAAO,IAAI,IAAI,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,CAAC;AAAA,EAC9C;AAAA,EAEA,iBAAyB;AACxB,UAAM,EAAE,GAAG,GAAG,GAAG,EAAE,IAAI;AACvB,WAAO,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC;AAAA,EACrC;AACD;", -+ "names": [] -+} -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/primitives/geometry/Stadium2d.mjs b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/primitives/geometry/Stadium2d.mjs -new file mode 100644 -index 0000000..8bfa41f ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/primitives/geometry/Stadium2d.mjs -@@ -0,0 +1,102 @@ -+import { Box } from "../Box.mjs"; -+import { Vec } from "../Vec.mjs"; -+import { PI } from "../utils.mjs"; -+import { Arc2d } from "./Arc2d.mjs"; -+import { Edge2d } from "./Edge2d.mjs"; -+import { Geometry2d } from "./Geometry2d.mjs"; -+class Stadium2d extends Geometry2d { -+ constructor(config) { -+ super({ ...config, isClosed: true }); -+ this.config = config; -+ const { width: w, height: h } = config; -+ this.w = w; -+ this.h = h; -+ if (h > w) { -+ const r = w / 2; -+ this.a = new Arc2d({ -+ start: new Vec(0, r), -+ end: new Vec(w, r), -+ center: new Vec(w / 2, r), -+ sweepFlag: 1, -+ largeArcFlag: 1 -+ }); -+ this.b = new Edge2d({ start: new Vec(w, r), end: new Vec(w, h - r) }); -+ this.c = new Arc2d({ -+ start: new Vec(w, h - r), -+ end: new Vec(0, h - r), -+ center: new Vec(w / 2, h - r), -+ sweepFlag: 1, -+ largeArcFlag: 1 -+ }); -+ this.d = new Edge2d({ start: new Vec(0, h - r), end: new Vec(0, r) }); -+ } else { -+ const r = h / 2; -+ this.a = new Arc2d({ -+ start: new Vec(r, h), -+ end: new Vec(r, 0), -+ center: new Vec(r, r), -+ sweepFlag: 1, -+ largeArcFlag: 1 -+ }); -+ this.b = new Edge2d({ start: new Vec(r, 0), end: new Vec(w - r, 0) }); -+ this.c = new Arc2d({ -+ start: new Vec(w - r, 0), -+ end: new Vec(w - r, h), -+ center: new Vec(w - r, r), -+ sweepFlag: 1, -+ largeArcFlag: 1 -+ }); -+ this.d = new Edge2d({ start: new Vec(w - r, h), end: new Vec(r, h) }); -+ } -+ } -+ w; -+ h; -+ a; -+ b; -+ c; -+ d; -+ nearestPoint(A) { -+ let nearest; -+ let dist = Infinity; -+ let _d; -+ let p; -+ const { a, b, c, d } = this; -+ for (const part of [a, b, c, d]) { -+ p = part.nearestPoint(A); -+ _d = Vec.Dist2(p, A); -+ if (_d < dist) { -+ nearest = p; -+ dist = _d; -+ } -+ } -+ if (!nearest) throw Error("nearest point not found"); -+ return nearest; -+ } -+ hitTestLineSegment(A, B) { -+ const { a, b, c, d } = this; -+ return [a, b, c, d].some((edge) => edge.hitTestLineSegment(A, B)); -+ } -+ getVertices() { -+ const { a, b, c, d } = this; -+ return [a, b, c, d].reduce((a2, p) => { -+ a2.push(...p.vertices); -+ return a2; -+ }, []); -+ } -+ getBounds() { -+ return new Box(0, 0, this.w, this.h); -+ } -+ getLength() { -+ const { h, w } = this; -+ if (h > w) return (PI * (w / 2) + (h - w)) * 2; -+ else return (PI * (h / 2) + (w - h)) * 2; -+ } -+ getSvgPathData() { -+ const { a, b, c, d } = this; -+ return [a, b, c, d].map((p, i) => p.getSvgPathData(i === 0)).join(" ") + " Z"; -+ } -+} -+export { -+ Stadium2d -+}; -+//# sourceMappingURL=Stadium2d.mjs.map -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/primitives/geometry/Stadium2d.mjs.map b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/primitives/geometry/Stadium2d.mjs.map -new file mode 100644 -index 0000000..cf60d7d ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/primitives/geometry/Stadium2d.mjs.map -@@ -0,0 +1,7 @@ -+{ -+ "version": 3, -+ "sources": ["../../../../src/lib/primitives/geometry/Stadium2d.ts"], -+ "sourcesContent": ["import { Box } from '../Box'\nimport { Vec } from '../Vec'\nimport { PI } from '../utils'\nimport { Arc2d } from './Arc2d'\nimport { Edge2d } from './Edge2d'\nimport { Geometry2d, Geometry2dOptions } from './Geometry2d'\n\n/** @public */\nexport class Stadium2d extends Geometry2d {\n\tw: number\n\th: number\n\n\ta: Arc2d\n\tb: Edge2d\n\tc: Arc2d\n\td: Edge2d\n\n\tconstructor(\n\t\tpublic config: Omit & {\n\t\t\twidth: number\n\t\t\theight: number\n\t\t}\n\t) {\n\t\tsuper({ ...config, isClosed: true })\n\t\tconst { width: w, height: h } = config\n\t\tthis.w = w\n\t\tthis.h = h\n\n\t\tif (h > w) {\n\t\t\tconst r = w / 2\n\t\t\tthis.a = new Arc2d({\n\t\t\t\tstart: new Vec(0, r),\n\t\t\t\tend: new Vec(w, r),\n\t\t\t\tcenter: new Vec(w / 2, r),\n\t\t\t\tsweepFlag: 1,\n\t\t\t\tlargeArcFlag: 1,\n\t\t\t})\n\t\t\tthis.b = new Edge2d({ start: new Vec(w, r), end: new Vec(w, h - r) })\n\t\t\tthis.c = new Arc2d({\n\t\t\t\tstart: new Vec(w, h - r),\n\t\t\t\tend: new Vec(0, h - r),\n\t\t\t\tcenter: new Vec(w / 2, h - r),\n\t\t\t\tsweepFlag: 1,\n\t\t\t\tlargeArcFlag: 1,\n\t\t\t})\n\t\t\tthis.d = new Edge2d({ start: new Vec(0, h - r), end: new Vec(0, r) })\n\t\t} else {\n\t\t\tconst r = h / 2\n\t\t\tthis.a = new Arc2d({\n\t\t\t\tstart: new Vec(r, h),\n\t\t\t\tend: new Vec(r, 0),\n\t\t\t\tcenter: new Vec(r, r),\n\t\t\t\tsweepFlag: 1,\n\t\t\t\tlargeArcFlag: 1,\n\t\t\t})\n\t\t\tthis.b = new Edge2d({ start: new Vec(r, 0), end: new Vec(w - r, 0) })\n\t\t\tthis.c = new Arc2d({\n\t\t\t\tstart: new Vec(w - r, 0),\n\t\t\t\tend: new Vec(w - r, h),\n\t\t\t\tcenter: new Vec(w - r, r),\n\t\t\t\tsweepFlag: 1,\n\t\t\t\tlargeArcFlag: 1,\n\t\t\t})\n\t\t\tthis.d = new Edge2d({ start: new Vec(w - r, h), end: new Vec(r, h) })\n\t\t}\n\t}\n\n\tnearestPoint(A: Vec): Vec {\n\t\tlet nearest: Vec | undefined\n\t\tlet dist = Infinity\n\t\tlet _d: number\n\t\tlet p: Vec\n\n\t\tconst { a, b, c, d } = this\n\t\tfor (const part of [a, b, c, d]) {\n\t\t\tp = part.nearestPoint(A)\n\t\t\t_d = Vec.Dist2(p, A)\n\t\t\tif (_d < dist) {\n\t\t\t\tnearest = p\n\t\t\t\tdist = _d\n\t\t\t}\n\t\t}\n\t\tif (!nearest) throw Error('nearest point not found')\n\t\treturn nearest\n\t}\n\n\thitTestLineSegment(A: Vec, B: Vec): boolean {\n\t\tconst { a, b, c, d } = this\n\t\treturn [a, b, c, d].some((edge) => edge.hitTestLineSegment(A, B))\n\t}\n\n\tgetVertices() {\n\t\tconst { a, b, c, d } = this\n\t\treturn [a, b, c, d].reduce((a, p) => {\n\t\t\ta.push(...p.vertices)\n\t\t\treturn a\n\t\t}, [])\n\t}\n\n\tgetBounds() {\n\t\treturn new Box(0, 0, this.w, this.h)\n\t}\n\n\tgetLength() {\n\t\tconst { h, w } = this\n\t\tif (h > w) return (PI * (w / 2) + (h - w)) * 2\n\t\telse return (PI * (h / 2) + (w - h)) * 2\n\t}\n\n\tgetSvgPathData() {\n\t\tconst { a, b, c, d } = this\n\t\treturn [a, b, c, d].map((p, i) => p.getSvgPathData(i === 0)).join(' ') + ' Z'\n\t}\n}\n"], -+ "mappings": "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", -+ "names": ["a"] -+} -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/primitives/geometry/geometry-constants.mjs b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/primitives/geometry/geometry-constants.mjs -new file mode 100644 -index 0000000..acbf7a3 ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/primitives/geometry/geometry-constants.mjs -@@ -0,0 +1,9 @@ -+const SPACING = 20; -+const MIN_COUNT = 8; -+function getVerticesCountForLength(length, spacing = SPACING) { -+ return Math.max(MIN_COUNT, Math.ceil(length / spacing)); -+} -+export { -+ getVerticesCountForLength -+}; -+//# sourceMappingURL=geometry-constants.mjs.map -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/primitives/geometry/geometry-constants.mjs.map b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/primitives/geometry/geometry-constants.mjs.map -new file mode 100644 -index 0000000..14af3cc ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/primitives/geometry/geometry-constants.mjs.map -@@ -0,0 +1,7 @@ -+{ -+ "version": 3, -+ "sources": ["../../../../src/lib/primitives/geometry/geometry-constants.ts"], -+ "sourcesContent": ["const SPACING = 20\nconst MIN_COUNT = 8\n\nexport function getVerticesCountForLength(length: number, spacing = SPACING) {\n\treturn Math.max(MIN_COUNT, Math.ceil(length / spacing))\n}\n"], -+ "mappings": "AAAA,MAAM,UAAU;AAChB,MAAM,YAAY;AAEX,SAAS,0BAA0B,QAAgB,UAAU,SAAS;AAC5E,SAAO,KAAK,IAAI,WAAW,KAAK,KAAK,SAAS,OAAO,CAAC;AACvD;", -+ "names": [] -+} -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/primitives/intersect.mjs b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/primitives/intersect.mjs -new file mode 100644 -index 0000000..d7e27ee ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/primitives/intersect.mjs -@@ -0,0 +1,205 @@ -+import { pointInPolygon } from "./utils.mjs"; -+import { Vec } from "./Vec.mjs"; -+function intersectLineSegmentLineSegment(a1, a2, b1, b2) { -+ const ABx = a1.x - b1.x; -+ const ABy = a1.y - b1.y; -+ const BVx = b2.x - b1.x; -+ const BVy = b2.y - b1.y; -+ const AVx = a2.x - a1.x; -+ const AVy = a2.y - a1.y; -+ const ua_t = BVx * ABy - BVy * ABx; -+ const ub_t = AVx * ABy - AVy * ABx; -+ const u_b = BVy * AVx - BVx * AVy; -+ if (ua_t === 0 || ub_t === 0) return null; -+ if (u_b === 0) return null; -+ if (u_b !== 0) { -+ const ua = ua_t / u_b; -+ const ub = ub_t / u_b; -+ if (0 <= ua && ua <= 1 && 0 <= ub && ub <= 1) { -+ return Vec.AddXY(a1, ua * AVx, ua * AVy); -+ } -+ } -+ return null; -+} -+function intersectLineSegmentCircle(a1, a2, c, r) { -+ const a = (a2.x - a1.x) * (a2.x - a1.x) + (a2.y - a1.y) * (a2.y - a1.y); -+ const b = 2 * ((a2.x - a1.x) * (a1.x - c.x) + (a2.y - a1.y) * (a1.y - c.y)); -+ const cc = c.x * c.x + c.y * c.y + a1.x * a1.x + a1.y * a1.y - 2 * (c.x * a1.x + c.y * a1.y) - r * r; -+ const deter = b * b - 4 * a * cc; -+ if (deter < 0) return null; -+ if (deter === 0) return null; -+ const e = Math.sqrt(deter); -+ const u1 = (-b + e) / (2 * a); -+ const u2 = (-b - e) / (2 * a); -+ if ((u1 < 0 || u1 > 1) && (u2 < 0 || u2 > 1)) { -+ return null; -+ } -+ const result = []; -+ if (0 <= u1 && u1 <= 1) result.push(Vec.Lrp(a1, a2, u1)); -+ if (0 <= u2 && u2 <= 1) result.push(Vec.Lrp(a1, a2, u2)); -+ if (result.length === 0) return null; -+ return result; -+} -+function intersectLineSegmentPolyline(a1, a2, points) { -+ const result = []; -+ let segmentIntersection; -+ for (let i = 0, n = points.length - 1; i < n; i++) { -+ segmentIntersection = intersectLineSegmentLineSegment(a1, a2, points[i], points[i + 1]); -+ if (segmentIntersection) result.push(segmentIntersection); -+ } -+ if (result.length === 0) return null; -+ return result; -+} -+function intersectLineSegmentPolygon(a1, a2, points) { -+ const result = []; -+ let segmentIntersection; -+ for (let i = 1, n = points.length; i < n + 1; i++) { -+ segmentIntersection = intersectLineSegmentLineSegment( -+ a1, -+ a2, -+ points[i - 1], -+ points[i % points.length] -+ ); -+ if (segmentIntersection) result.push(segmentIntersection); -+ } -+ if (result.length === 0) return null; -+ return result; -+} -+function intersectCircleCircle(c1, r1, c2, r2) { -+ let dx = c2.x - c1.x; -+ let dy = c2.y - c1.y; -+ const d = Math.sqrt(dx * dx + dy * dy), x = (d * d - r2 * r2 + r1 * r1) / (2 * d), y = Math.sqrt(r1 * r1 - x * x); -+ dx /= d; -+ dy /= d; -+ return [ -+ new Vec(c1.x + dx * x - dy * y, c1.y + dy * x + dx * y), -+ new Vec(c1.x + dx * x + dy * y, c1.y + dy * x - dx * y) -+ ]; -+} -+function intersectCirclePolygon(c, r, points) { -+ const result = []; -+ let a, b, int; -+ for (let i = 0, n = points.length; i < n; i++) { -+ a = points[i]; -+ b = points[(i + 1) % points.length]; -+ int = intersectLineSegmentCircle(a, b, c, r); -+ if (int) result.push(...int); -+ } -+ if (result.length === 0) return null; -+ return result; -+} -+function intersectCirclePolyline(c, r, points) { -+ const result = []; -+ let a, b, int; -+ for (let i = 1, n = points.length; i < n; i++) { -+ a = points[i - 1]; -+ b = points[i]; -+ int = intersectLineSegmentCircle(a, b, c, r); -+ if (int) result.push(...int); -+ } -+ if (result.length === 0) return null; -+ return result; -+} -+function intersectPolygonBounds(points, bounds) { -+ const result = []; -+ let segmentIntersection; -+ for (const side of bounds.sides) { -+ segmentIntersection = intersectLineSegmentPolygon(side[0], side[1], points); -+ if (segmentIntersection) result.push(...segmentIntersection); -+ } -+ if (result.length === 0) return null; -+ return result; -+} -+function ccw(A, B, C) { -+ return (C.y - A.y) * (B.x - A.x) > (B.y - A.y) * (C.x - A.x); -+} -+function linesIntersect(A, B, C, D) { -+ return ccw(A, C, D) !== ccw(B, C, D) && ccw(A, B, C) !== ccw(A, B, D); -+} -+function intersectPolygonPolygon(polygonA, polygonB) { -+ const result = /* @__PURE__ */ new Map(); -+ let a, b, c, d; -+ for (let i = 0, n = polygonA.length; i < n; i++) { -+ a = polygonA[i]; -+ if (pointInPolygon(a, polygonB)) { -+ const id = getPointId(a); -+ if (!result.has(id)) { -+ result.set(id, a); -+ } -+ } -+ } -+ for (let i = 0, n = polygonB.length; i < n; i++) { -+ a = polygonB[i]; -+ if (pointInPolygon(a, polygonA)) { -+ const id = getPointId(a); -+ if (!result.has(id)) { -+ result.set(id, a); -+ } -+ } -+ } -+ for (let i = 0, n = polygonA.length; i < n; i++) { -+ a = polygonA[i]; -+ b = polygonA[(i + 1) % polygonA.length]; -+ for (let j = 0, m = polygonB.length; j < m; j++) { -+ c = polygonB[j]; -+ d = polygonB[(j + 1) % polygonB.length]; -+ const intersection = intersectLineSegmentLineSegment(a, b, c, d); -+ if (intersection !== null) { -+ const id = getPointId(intersection); -+ if (!result.has(id)) { -+ result.set(id, intersection); -+ } -+ } -+ } -+ } -+ if (result.size === 0) return null; -+ return orderClockwise([...result.values()]); -+} -+function getPointId(point) { -+ return `${point.x},${point.y}`; -+} -+function orderClockwise(points) { -+ const C = Vec.Average(points); -+ return points.sort((A, B) => Vec.Angle(C, A) - Vec.Angle(C, B)); -+} -+function polygonsIntersect(a, b) { -+ let a0, a1, b0, b1; -+ for (let i = 0, n = a.length; i < n; i++) { -+ a0 = a[i]; -+ a1 = a[(i + 1) % n]; -+ for (let j = 0, m = b.length; j < m; j++) { -+ b0 = b[j]; -+ b1 = b[(j + 1) % m]; -+ if (linesIntersect(a0, a1, b0, b1)) return true; -+ } -+ } -+ return false; -+} -+function polygonIntersectsPolyline(polygon, polyline) { -+ let a, b, c, d; -+ for (let i = 0, n = polygon.length; i < n; i++) { -+ a = polygon[i]; -+ b = polygon[(i + 1) % n]; -+ for (let j = 1, m = polyline.length; j < m; j++) { -+ c = polyline[j - 1]; -+ d = polyline[j]; -+ if (linesIntersect(a, b, c, d)) return true; -+ } -+ } -+ return false; -+} -+export { -+ intersectCircleCircle, -+ intersectCirclePolygon, -+ intersectCirclePolyline, -+ intersectLineSegmentCircle, -+ intersectLineSegmentLineSegment, -+ intersectLineSegmentPolygon, -+ intersectLineSegmentPolyline, -+ intersectPolygonBounds, -+ intersectPolygonPolygon, -+ linesIntersect, -+ polygonIntersectsPolyline, -+ polygonsIntersect -+}; -+//# sourceMappingURL=intersect.mjs.map -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/primitives/intersect.mjs.map b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/primitives/intersect.mjs.map -new file mode 100644 -index 0000000..4f1b85f ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/primitives/intersect.mjs.map -@@ -0,0 +1,7 @@ -+{ -+ "version": 3, -+ "sources": ["../../../src/lib/primitives/intersect.ts"], -+ "sourcesContent": ["import { Box } from './Box'\nimport { pointInPolygon } from './utils'\nimport { Vec, VecLike } from './Vec'\n\n// need even more intersections? See https://gist.github.com/steveruizok/35c02d526c707003a5c79761bfb89a52\n\n/**\n * Find the intersection between a line segment and a line segment.\n *\n * @param a1 - The first segment's first point.\n * @param a2 - The first segment's second point.\n * @param b1 - The second segment's first point.\n * @param b2 - The second segment's second point.\n * @public\n */\nexport function intersectLineSegmentLineSegment(\n\ta1: VecLike,\n\ta2: VecLike,\n\tb1: VecLike,\n\tb2: VecLike\n) {\n\tconst ABx = a1.x - b1.x\n\tconst ABy = a1.y - b1.y\n\tconst BVx = b2.x - b1.x\n\tconst BVy = b2.y - b1.y\n\tconst AVx = a2.x - a1.x\n\tconst AVy = a2.y - a1.y\n\tconst ua_t = BVx * ABy - BVy * ABx\n\tconst ub_t = AVx * ABy - AVy * ABx\n\tconst u_b = BVy * AVx - BVx * AVy\n\n\tif (ua_t === 0 || ub_t === 0) return null // coincident\n\n\tif (u_b === 0) return null // parallel\n\n\tif (u_b !== 0) {\n\t\tconst ua = ua_t / u_b\n\t\tconst ub = ub_t / u_b\n\t\tif (0 <= ua && ua <= 1 && 0 <= ub && ub <= 1) {\n\t\t\treturn Vec.AddXY(a1, ua * AVx, ua * AVy)\n\t\t}\n\t}\n\n\treturn null // no intersection\n}\n\n/**\n * Find the intersections between a line segment and a circle.\n *\n * @param a1 - The segment's first point.\n * @param a2 - The segment's second point.\n * @param c - The circle's center.\n * @param r - The circle's radius.\n * @public\n */\nexport function intersectLineSegmentCircle(a1: VecLike, a2: VecLike, c: VecLike, r: number) {\n\tconst a = (a2.x - a1.x) * (a2.x - a1.x) + (a2.y - a1.y) * (a2.y - a1.y)\n\tconst b = 2 * ((a2.x - a1.x) * (a1.x - c.x) + (a2.y - a1.y) * (a1.y - c.y))\n\tconst cc =\n\t\tc.x * c.x + c.y * c.y + a1.x * a1.x + a1.y * a1.y - 2 * (c.x * a1.x + c.y * a1.y) - r * r\n\tconst deter = b * b - 4 * a * cc\n\n\tif (deter < 0) return null // outside\n\tif (deter === 0) return null // tangent\n\n\tconst e = Math.sqrt(deter)\n\tconst u1 = (-b + e) / (2 * a)\n\tconst u2 = (-b - e) / (2 * a)\n\n\tif ((u1 < 0 || u1 > 1) && (u2 < 0 || u2 > 1)) {\n\t\treturn null // outside or inside\n\t\t// if ((u1 < 0 && u2 < 0) || (u1 > 1 && u2 > 1)) {\n\t\t// \treturn null // outside\n\t\t// } else return null // inside'\n\t}\n\n\tconst result: VecLike[] = []\n\n\tif (0 <= u1 && u1 <= 1) result.push(Vec.Lrp(a1, a2, u1))\n\tif (0 <= u2 && u2 <= 1) result.push(Vec.Lrp(a1, a2, u2))\n\n\tif (result.length === 0) return null // no intersection\n\n\treturn result\n}\n\n/**\n * Find the intersections between a line segment and a polyline.\n *\n * @param a1 - The segment's first point.\n * @param a2 - The segment's second point.\n * @param points - The points in the polyline.\n * @public\n */\nexport function intersectLineSegmentPolyline(a1: VecLike, a2: VecLike, points: VecLike[]) {\n\tconst result: VecLike[] = []\n\tlet segmentIntersection: VecLike | null\n\n\tfor (let i = 0, n = points.length - 1; i < n; i++) {\n\t\tsegmentIntersection = intersectLineSegmentLineSegment(a1, a2, points[i], points[i + 1])\n\t\tif (segmentIntersection) result.push(segmentIntersection)\n\t}\n\n\tif (result.length === 0) return null // no intersection\n\n\treturn result\n}\n\n/**\n * Find the intersections between a line segment and a closed polygon.\n *\n * @param a1 - The segment's first point.\n * @param a2 - The segment's second point.\n * @param points - The points in the polygon.\n * @public\n */\nexport function intersectLineSegmentPolygon(a1: VecLike, a2: VecLike, points: VecLike[]) {\n\tconst result: VecLike[] = []\n\tlet segmentIntersection: VecLike | null\n\n\tfor (let i = 1, n = points.length; i < n + 1; i++) {\n\t\tsegmentIntersection = intersectLineSegmentLineSegment(\n\t\t\ta1,\n\t\t\ta2,\n\t\t\tpoints[i - 1],\n\t\t\tpoints[i % points.length]\n\t\t)\n\t\tif (segmentIntersection) result.push(segmentIntersection)\n\t}\n\n\tif (result.length === 0) return null // no intersection\n\n\treturn result\n}\n\n/**\n * Find the intersections between a circle and a circle.\n *\n * @param c1 - The first circle's center.\n * @param r1 - The first circle's radius.\n * @param c2 - The second circle's center.\n * @param r2 - The second circle's radius.\n * @public\n */\nexport function intersectCircleCircle(c1: VecLike, r1: number, c2: VecLike, r2: number) {\n\tlet dx = c2.x - c1.x\n\tlet dy = c2.y - c1.y\n\tconst d = Math.sqrt(dx * dx + dy * dy),\n\t\tx = (d * d - r2 * r2 + r1 * r1) / (2 * d),\n\t\ty = Math.sqrt(r1 * r1 - x * x)\n\tdx /= d\n\tdy /= d\n\treturn [\n\t\tnew Vec(c1.x + dx * x - dy * y, c1.y + dy * x + dx * y),\n\t\tnew Vec(c1.x + dx * x + dy * y, c1.y + dy * x - dx * y),\n\t]\n}\n\n/**\n * Find the intersections between a circle and a bounding box.\n *\n * @param c - The circle's center.\n * @param r - The circle's radius.\n * @param points - The points in the polygon.\n * @public\n */\nexport function intersectCirclePolygon(c: VecLike, r: number, points: VecLike[]) {\n\tconst result: VecLike[] = []\n\tlet a: VecLike, b: VecLike, int: VecLike[] | null\n\n\tfor (let i = 0, n = points.length; i < n; i++) {\n\t\ta = points[i]\n\t\tb = points[(i + 1) % points.length]\n\t\tint = intersectLineSegmentCircle(a, b, c, r)\n\t\tif (int) result.push(...int)\n\t}\n\n\tif (result.length === 0) return null // no intersection\n\n\treturn result\n}\n\n/**\n * Find the intersections between a circle and a bounding box.\n *\n * @param c - The circle's center.\n * @param r - The circle's radius.\n * @param points - The points in the polyline.\n * @public\n */\nexport function intersectCirclePolyline(c: VecLike, r: number, points: VecLike[]) {\n\tconst result: VecLike[] = []\n\tlet a: VecLike, b: VecLike, int: VecLike[] | null\n\n\tfor (let i = 1, n = points.length; i < n; i++) {\n\t\ta = points[i - 1]\n\t\tb = points[i]\n\t\tint = intersectLineSegmentCircle(a, b, c, r)\n\t\tif (int) result.push(...int)\n\t}\n\n\tif (result.length === 0) return null // no intersection\n\n\treturn result\n}\n\n/**\n * Find the intersections between a polygon and a bounding box.\n *\n * @public\n */\nexport function intersectPolygonBounds(points: VecLike[], bounds: Box) {\n\tconst result: VecLike[] = []\n\tlet segmentIntersection: VecLike[] | null\n\n\tfor (const side of bounds.sides) {\n\t\tsegmentIntersection = intersectLineSegmentPolygon(side[0], side[1], points)\n\t\tif (segmentIntersection) result.push(...segmentIntersection)\n\t}\n\n\tif (result.length === 0) return null // no intersection\n\n\treturn result\n}\n\nfunction ccw(A: VecLike, B: VecLike, C: VecLike) {\n\treturn (C.y - A.y) * (B.x - A.x) > (B.y - A.y) * (C.x - A.x)\n}\n\n/** @public */\nexport function linesIntersect(A: VecLike, B: VecLike, C: VecLike, D: VecLike) {\n\treturn ccw(A, C, D) !== ccw(B, C, D) && ccw(A, B, C) !== ccw(A, B, D)\n}\n\n/**\n * Create a new convex polygon as the intersection of two convex polygons.\n *\n * @param polygonA - An array of points representing the first polygon.\n * @param polygonB - An array of points representing the second polygon.\n * @public\n */\nexport function intersectPolygonPolygon(\n\tpolygonA: VecLike[],\n\tpolygonB: VecLike[]\n): VecLike[] | null {\n\t// Create an empty polygon as result\n\tconst result: Map = new Map()\n\tlet a: VecLike, b: VecLike, c: VecLike, d: VecLike\n\n\t// Add all corners of PolygonA that is inside PolygonB to result\n\tfor (let i = 0, n = polygonA.length; i < n; i++) {\n\t\ta = polygonA[i]\n\t\tif (pointInPolygon(a, polygonB)) {\n\t\t\tconst id = getPointId(a)\n\t\t\tif (!result.has(id)) {\n\t\t\t\tresult.set(id, a)\n\t\t\t}\n\t\t}\n\t}\n\t// Add all corners of PolygonB that is inside PolygonA to result\n\tfor (let i = 0, n = polygonB.length; i < n; i++) {\n\t\ta = polygonB[i]\n\t\tif (pointInPolygon(a, polygonA)) {\n\t\t\tconst id = getPointId(a)\n\t\t\tif (!result.has(id)) {\n\t\t\t\tresult.set(id, a)\n\t\t\t}\n\t\t}\n\t}\n\n\t// Add all intersection points to result\n\tfor (let i = 0, n = polygonA.length; i < n; i++) {\n\t\ta = polygonA[i]\n\t\tb = polygonA[(i + 1) % polygonA.length]\n\n\t\tfor (let j = 0, m = polygonB.length; j < m; j++) {\n\t\t\tc = polygonB[j]\n\t\t\td = polygonB[(j + 1) % polygonB.length]\n\t\t\tconst intersection = intersectLineSegmentLineSegment(a, b, c, d)\n\n\t\t\tif (intersection !== null) {\n\t\t\t\tconst id = getPointId(intersection)\n\t\t\t\tif (!result.has(id)) {\n\t\t\t\t\tresult.set(id, intersection)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tif (result.size === 0) return null // no intersection\n\n\t// Order all points in the result counter-clockwise.\n\treturn orderClockwise([...result.values()])\n}\n\nfunction getPointId(point: VecLike) {\n\treturn `${point.x},${point.y}`\n}\n\nfunction orderClockwise(points: VecLike[]): VecLike[] {\n\tconst C = Vec.Average(points)\n\treturn points.sort((A, B) => Vec.Angle(C, A) - Vec.Angle(C, B))\n}\n\n/** @public */\nexport function polygonsIntersect(a: VecLike[], b: VecLike[]) {\n\tlet a0: VecLike, a1: VecLike, b0: VecLike, b1: VecLike\n\tfor (let i = 0, n = a.length; i < n; i++) {\n\t\ta0 = a[i]\n\t\ta1 = a[(i + 1) % n]\n\t\tfor (let j = 0, m = b.length; j < m; j++) {\n\t\t\tb0 = b[j]\n\t\t\tb1 = b[(j + 1) % m]\n\t\t\tif (linesIntersect(a0, a1, b0, b1)) return true\n\t\t}\n\t}\n\treturn false\n}\n\n/** @public */\nexport function polygonIntersectsPolyline(polygon: VecLike[], polyline: VecLike[]) {\n\tlet a: VecLike, b: VecLike, c: VecLike, d: VecLike\n\tfor (let i = 0, n = polygon.length; i < n; i++) {\n\t\ta = polygon[i]\n\t\tb = polygon[(i + 1) % n]\n\n\t\tfor (let j = 1, m = polyline.length; j < m; j++) {\n\t\t\tc = polyline[j - 1]\n\t\t\td = polyline[j]\n\t\t\tif (linesIntersect(a, b, c, d)) return true\n\t\t}\n\t}\n\treturn false\n}\n"], -+ "mappings": "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", -+ "names": [] -+} -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/primitives/utils.mjs b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/primitives/utils.mjs -new file mode 100644 -index 0000000..8a1b0b7 ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/primitives/utils.mjs -@@ -0,0 +1,233 @@ -+import { Vec } from "./Vec.mjs"; -+function precise(A) { -+ return `${toDomPrecision(A.x)},${toDomPrecision(A.y)} `; -+} -+function average(A, B) { -+ return `${toDomPrecision((A.x + B.x) / 2)},${toDomPrecision((A.y + B.y) / 2)} `; -+} -+const PI = Math.PI; -+const HALF_PI = PI / 2; -+const PI2 = PI * 2; -+const SIN = Math.sin; -+function clamp(n, min, max) { -+ return Math.max(min, typeof max !== "undefined" ? Math.min(n, max) : n); -+} -+function toPrecision(n, precision = 1e10) { -+ if (!n) return 0; -+ return Math.round(n * precision) / precision; -+} -+function approximately(a, b, precision = 1e-6) { -+ return Math.abs(a - b) <= precision; -+} -+function perimeterOfEllipse(rx, ry) { -+ const h = Math.pow(rx - ry, 2) / Math.pow(rx + ry, 2); -+ return PI * (rx + ry) * (1 + 3 * h / (10 + Math.sqrt(4 - 3 * h))); -+} -+function canonicalizeRotation(a) { -+ a = a % PI2; -+ if (a < 0) { -+ a = a + PI2; -+ } else if (a === 0) { -+ a = 0; -+ } -+ return a; -+} -+function clockwiseAngleDist(a0, a1) { -+ a0 = canonicalizeRotation(a0); -+ a1 = canonicalizeRotation(a1); -+ if (a0 > a1) { -+ a1 += PI2; -+ } -+ return a1 - a0; -+} -+function counterClockwiseAngleDist(a0, a1) { -+ return PI2 - clockwiseAngleDist(a0, a1); -+} -+function shortAngleDist(a0, a1) { -+ const da = (a1 - a0) % PI2; -+ return 2 * da % PI2 - da; -+} -+function clampRadians(r) { -+ return (PI2 + r) % PI2; -+} -+function snapAngle(r, segments) { -+ const seg = PI2 / segments; -+ let ang = Math.floor((clampRadians(r) + seg / 2) / seg) * seg % PI2; -+ if (ang < PI) ang += PI2; -+ if (ang > PI) ang -= PI2; -+ return ang; -+} -+function areAnglesCompatible(a, b) { -+ return a === b || approximately(a % (Math.PI / 2) - b % (Math.PI / 2), 0); -+} -+function degreesToRadians(d) { -+ return d * PI / 180; -+} -+function radiansToDegrees(r) { -+ return r * 180 / PI; -+} -+function getPointOnCircle(center, r, a) { -+ return new Vec(center.x, center.y).add(Vec.FromAngle(a, r)); -+} -+function getPolygonVertices(width, height, sides) { -+ const cx = width / 2; -+ const cy = height / 2; -+ const pointsOnPerimeter = []; -+ let minX = Infinity; -+ let maxX = -Infinity; -+ let minY = Infinity; -+ let maxY = -Infinity; -+ for (let i = 0; i < sides; i++) { -+ const step = PI2 / sides; -+ const t = -HALF_PI + i * step; -+ const x = cx + cx * Math.cos(t); -+ const y = cy + cy * Math.sin(t); -+ if (x < minX) minX = x; -+ if (y < minY) minY = y; -+ if (x > maxX) maxX = x; -+ if (y > maxY) maxY = y; -+ pointsOnPerimeter.push(new Vec(x, y)); -+ } -+ const w = maxX - minX; -+ const h = maxY - minY; -+ const dx = width - w; -+ const dy = height - h; -+ if (dx !== 0 || dy !== 0) { -+ for (let i = 0; i < pointsOnPerimeter.length; i++) { -+ const pt = pointsOnPerimeter[i]; -+ pt.x = (pt.x - minX) / w * width; -+ pt.y = (pt.y - minY) / h * height; -+ } -+ } -+ return pointsOnPerimeter; -+} -+function rangesOverlap(a0, a1, b0, b1) { -+ return a0 < b1 && b0 < a1; -+} -+function rangeIntersection(a0, a1, b0, b1) { -+ const min = Math.max(a0, b0); -+ const max = Math.min(a1, b1); -+ if (min <= max) { -+ return [min, max]; -+ } -+ return null; -+} -+function cross(x, y, z) { -+ return (y.x - x.x) * (z.y - x.y) - (z.x - x.x) * (y.y - x.y); -+} -+function pointInPolygon(A, points) { -+ let windingNumber = 0; -+ let a; -+ let b; -+ for (let i = 0; i < points.length; i++) { -+ a = points[i]; -+ if (a.x === A.x && a.y === A.y) return true; -+ b = points[(i + 1) % points.length]; -+ if (Vec.Dist(A, a) + Vec.Dist(A, b) === Vec.Dist(a, b)) return true; -+ if (a.y <= A.y) { -+ if (b.y > A.y && cross(a, b, A) > 0) { -+ windingNumber += 1; -+ } -+ } else if (b.y <= A.y && cross(a, b, A) < 0) { -+ windingNumber -= 1; -+ } -+ } -+ return windingNumber !== 0; -+} -+function toDomPrecision(v) { -+ return Math.round(v * 1e4) / 1e4; -+} -+function toFixed(v) { -+ return Math.round(v * 100) / 100; -+} -+const isSafeFloat = (n) => { -+ return Math.abs(n) < Number.MAX_SAFE_INTEGER; -+}; -+function angleDistance(fromAngle, toAngle, direction) { -+ const dist = direction < 0 ? clockwiseAngleDist(fromAngle, toAngle) : counterClockwiseAngleDist(fromAngle, toAngle); -+ return dist; -+} -+function getPointInArcT(mAB, A, B, P) { -+ let mAP; -+ if (Math.abs(mAB) > PI) { -+ mAP = shortAngleDist(A, P); -+ const mPB = shortAngleDist(P, B); -+ if (Math.abs(mAP) < Math.abs(mPB)) { -+ return mAP / mAB; -+ } else { -+ return (mAB - mPB) / mAB; -+ } -+ } else { -+ mAP = shortAngleDist(A, P); -+ const t = mAP / mAB; -+ if (Math.sign(mAP) !== Math.sign(mAB)) { -+ return Math.abs(t) > 0.5 ? 1 : 0; -+ } -+ return t; -+ } -+} -+function getArcMeasure(A, B, sweepFlag, largeArcFlag) { -+ const m = 2 * ((B - A) % PI2) % PI2 - (B - A) % PI2; -+ if (!largeArcFlag) return m; -+ return (PI2 - Math.abs(m)) * (sweepFlag ? 1 : -1); -+} -+function centerOfCircleFromThreePoints(a, b, c) { -+ const u = -2 * (a.x * (b.y - c.y) - a.y * (b.x - c.x) + b.x * c.y - c.x * b.y); -+ const x = ((a.x * a.x + a.y * a.y) * (c.y - b.y) + (b.x * b.x + b.y * b.y) * (a.y - c.y) + (c.x * c.x + c.y * c.y) * (b.y - a.y)) / u; -+ const y = ((a.x * a.x + a.y * a.y) * (b.x - c.x) + (b.x * b.x + b.y * b.y) * (c.x - a.x) + (c.x * c.x + c.y * c.y) * (a.x - b.x)) / u; -+ if (!Number.isFinite(x) || !Number.isFinite(y)) { -+ return null; -+ } -+ return new Vec(x, y); -+} -+function getPointsOnArc(startPoint, endPoint, center, radius, numPoints) { -+ if (center === null) { -+ return [Vec.From(startPoint), Vec.From(endPoint)]; -+ } -+ const results = []; -+ const startAngle = Vec.Angle(center, startPoint); -+ const endAngle = Vec.Angle(center, endPoint); -+ const l = clockwiseAngleDist(startAngle, endAngle); -+ for (let i = 0; i < numPoints; i++) { -+ const t = i / (numPoints - 1); -+ const angle = startAngle + l * t; -+ const point = getPointOnCircle(center, radius, angle); -+ results.push(point); -+ } -+ return results; -+} -+export { -+ HALF_PI, -+ PI, -+ PI2, -+ SIN, -+ angleDistance, -+ approximately, -+ areAnglesCompatible, -+ average, -+ canonicalizeRotation, -+ centerOfCircleFromThreePoints, -+ clamp, -+ clampRadians, -+ clockwiseAngleDist, -+ counterClockwiseAngleDist, -+ degreesToRadians, -+ getArcMeasure, -+ getPointInArcT, -+ getPointOnCircle, -+ getPointsOnArc, -+ getPolygonVertices, -+ isSafeFloat, -+ perimeterOfEllipse, -+ pointInPolygon, -+ precise, -+ radiansToDegrees, -+ rangeIntersection, -+ rangesOverlap, -+ shortAngleDist, -+ snapAngle, -+ toDomPrecision, -+ toFixed, -+ toPrecision -+}; -+//# sourceMappingURL=utils.mjs.map -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/primitives/utils.mjs.map b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/primitives/utils.mjs.map -new file mode 100644 -index 0000000..9d88811 ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/primitives/utils.mjs.map -@@ -0,0 +1,7 @@ -+{ -+ "version": 3, -+ "sources": ["../../../src/lib/primitives/utils.ts"], -+ "sourcesContent": ["import { Vec, VecLike } from './Vec'\n\n/** @public */\nexport function precise(A: VecLike) {\n\treturn `${toDomPrecision(A.x)},${toDomPrecision(A.y)} `\n}\n\n/** @public */\nexport function average(A: VecLike, B: VecLike) {\n\treturn `${toDomPrecision((A.x + B.x) / 2)},${toDomPrecision((A.y + B.y) / 2)} `\n}\n\n/** @public */\nexport const PI = Math.PI\n/** @public */\nexport const HALF_PI = PI / 2\n/** @public */\nexport const PI2 = PI * 2\n/** @public */\nexport const SIN = Math.sin\n\n/**\n * Clamp a value into a range.\n *\n * @example\n *\n * ```ts\n * const A = clamp(0, 1) // 1\n * ```\n *\n * @param n - The number to clamp.\n * @param min - The minimum value.\n * @public\n */\nexport function clamp(n: number, min: number): number\n/**\n * Clamp a value into a range.\n *\n * @example\n *\n * ```ts\n * const A = clamp(0, 1, 10) // 1\n * const B = clamp(11, 1, 10) // 10\n * const C = clamp(5, 1, 10) // 5\n * ```\n *\n * @param n - The number to clamp.\n * @param min - The minimum value.\n * @param max - The maximum value.\n * @public\n */\nexport function clamp(n: number, min: number, max: number): number\nexport function clamp(n: number, min: number, max?: number): number {\n\treturn Math.max(min, typeof max !== 'undefined' ? Math.min(n, max) : n)\n}\n\n/**\n * Get a number to a precision.\n *\n * @param n - The number.\n * @param precision - The precision.\n * @public\n */\nexport function toPrecision(n: number, precision = 10000000000) {\n\tif (!n) return 0\n\treturn Math.round(n * precision) / precision\n}\n\n/**\n * Whether two numbers numbers a and b are approximately equal.\n *\n * @param a - The first point.\n * @param b - The second point.\n * @public\n */\nexport function approximately(a: number, b: number, precision = 0.000001) {\n\treturn Math.abs(a - b) <= precision\n}\n\n/**\n * Find the approximate perimeter of an ellipse.\n *\n * @param rx - The ellipse's x radius.\n * @param ry - The ellipse's y radius.\n * @public\n */\nexport function perimeterOfEllipse(rx: number, ry: number): number {\n\tconst h = Math.pow(rx - ry, 2) / Math.pow(rx + ry, 2)\n\treturn PI * (rx + ry) * (1 + (3 * h) / (10 + Math.sqrt(4 - 3 * h)))\n}\n\n/**\n * @param a - Any angle in radians\n * @returns A number between 0 and 2 * PI\n * @public\n */\nexport function canonicalizeRotation(a: number) {\n\ta = a % PI2\n\tif (a < 0) {\n\t\ta = a + PI2\n\t} else if (a === 0) {\n\t\t// prevent negative zero\n\t\ta = 0\n\t}\n\treturn a\n}\n\n/**\n * Get the clockwise angle distance between two angles.\n *\n * @param a0 - The first angle.\n * @param a1 - The second angle.\n * @public\n */\nexport function clockwiseAngleDist(a0: number, a1: number): number {\n\ta0 = canonicalizeRotation(a0)\n\ta1 = canonicalizeRotation(a1)\n\tif (a0 > a1) {\n\t\ta1 += PI2\n\t}\n\treturn a1 - a0\n}\n\n/**\n * Get the counter-clockwise angle distance between two angles.\n *\n * @param a0 - The first angle.\n * @param a1 - The second angle.\n * @public\n */\nexport function counterClockwiseAngleDist(a0: number, a1: number): number {\n\treturn PI2 - clockwiseAngleDist(a0, a1)\n}\n\n/**\n * Get the short angle distance between two angles.\n *\n * @param a0 - The first angle.\n * @param a1 - The second angle.\n * @public\n */\nexport function shortAngleDist(a0: number, a1: number): number {\n\tconst da = (a1 - a0) % PI2\n\treturn ((2 * da) % PI2) - da\n}\n\n/**\n * Clamp radians within 0 and 2PI\n *\n * @param r - The radian value.\n * @public\n */\nexport function clampRadians(r: number): number {\n\treturn (PI2 + r) % PI2\n}\n\n/**\n * Clamp rotation to even segments.\n *\n * @param r - The rotation in radians.\n * @param segments - The number of segments.\n * @public\n */\nexport function snapAngle(r: number, segments: number): number {\n\tconst seg = PI2 / segments\n\tlet ang = (Math.floor((clampRadians(r) + seg / 2) / seg) * seg) % PI2\n\tif (ang < PI) ang += PI2\n\tif (ang > PI) ang -= PI2\n\treturn ang\n}\n\n/**\n * Checks whether two angles are approximately at right-angles or parallel to each other\n *\n * @param a - Angle a (radians)\n * @param b - Angle b (radians)\n * @returns True iff the angles are approximately at right-angles or parallel to each other\n * @public\n */\nexport function areAnglesCompatible(a: number, b: number) {\n\treturn a === b || approximately((a % (Math.PI / 2)) - (b % (Math.PI / 2)), 0)\n}\n\n/**\n * Convert degrees to radians.\n *\n * @param d - The degree in degrees.\n * @public\n */\nexport function degreesToRadians(d: number): number {\n\treturn (d * PI) / 180\n}\n\n/**\n * Convert radians to degrees.\n *\n * @param r - The degree in radians.\n * @public\n */\nexport function radiansToDegrees(r: number): number {\n\treturn (r * 180) / PI\n}\n\n/**\n * Get a point on the perimeter of a circle.\n *\n * @param center - The center of the circle.\n * @param r - The radius of the circle.\n * @param a - The angle in radians.\n * @public\n */\nexport function getPointOnCircle(center: VecLike, r: number, a: number) {\n\treturn new Vec(center.x, center.y).add(Vec.FromAngle(a, r))\n}\n\n/** @public */\nexport function getPolygonVertices(width: number, height: number, sides: number) {\n\tconst cx = width / 2\n\tconst cy = height / 2\n\tconst pointsOnPerimeter: Vec[] = []\n\n\tlet minX = Infinity\n\tlet maxX = -Infinity\n\tlet minY = Infinity\n\tlet maxY = -Infinity\n\tfor (let i = 0; i < sides; i++) {\n\t\tconst step = PI2 / sides\n\t\tconst t = -HALF_PI + i * step\n\t\tconst x = cx + cx * Math.cos(t)\n\t\tconst y = cy + cy * Math.sin(t)\n\t\tif (x < minX) minX = x\n\t\tif (y < minY) minY = y\n\t\tif (x > maxX) maxX = x\n\t\tif (y > maxY) maxY = y\n\t\tpointsOnPerimeter.push(new Vec(x, y))\n\t}\n\n\t// Bounds of calculated points\n\tconst w = maxX - minX\n\tconst h = maxY - minY\n\n\t// Difference between input bounds and calculated bounds\n\tconst dx = width - w\n\tconst dy = height - h\n\n\t// If there's a difference, scale the points to the input bounds\n\tif (dx !== 0 || dy !== 0) {\n\t\tfor (let i = 0; i < pointsOnPerimeter.length; i++) {\n\t\t\tconst pt = pointsOnPerimeter[i]\n\t\t\tpt.x = ((pt.x - minX) / w) * width\n\t\t\tpt.y = ((pt.y - minY) / h) * height\n\t\t}\n\t}\n\n\treturn pointsOnPerimeter\n}\n\n/**\n * @param a0 - The start point in the A range\n * @param a1 - The end point in the A range\n * @param b0 - The start point in the B range\n * @param b1 - The end point in the B range\n * @returns True if the ranges overlap\n * @public\n */\nexport function rangesOverlap(a0: number, a1: number, b0: number, b1: number): boolean {\n\treturn a0 < b1 && b0 < a1\n}\n\n/**\n * Finds the intersection of two ranges.\n *\n * @param a0 - The start point in the A range\n * @param a1 - The end point in the A range\n * @param b0 - The start point in the B range\n * @param b1 - The end point in the B range\n * @returns The intersection of the ranges, or null if no intersection\n * @public\n */\nexport function rangeIntersection(\n\ta0: number,\n\ta1: number,\n\tb0: number,\n\tb1: number\n): [number, number] | null {\n\tconst min = Math.max(a0, b0)\n\tconst max = Math.min(a1, b1)\n\tif (min <= max) {\n\t\treturn [min, max]\n\t}\n\treturn null\n}\n\n/** Helper for point in polygon */\nfunction cross(x: VecLike, y: VecLike, z: VecLike): number {\n\treturn (y.x - x.x) * (z.y - x.y) - (z.x - x.x) * (y.y - x.y)\n}\n\n/**\n * Get whether a point is inside of a polygon.\n *\n * ```ts\n * const result = pointInPolygon(myPoint, myPoints)\n * ```\n *\n * @public\n */\nexport function pointInPolygon(A: VecLike, points: VecLike[]): boolean {\n\tlet windingNumber = 0\n\tlet a: VecLike\n\tlet b: VecLike\n\n\tfor (let i = 0; i < points.length; i++) {\n\t\ta = points[i]\n\t\t// Point is the same as one of the corners of the polygon\n\t\tif (a.x === A.x && a.y === A.y) return true\n\n\t\tb = points[(i + 1) % points.length]\n\n\t\t// Point is on the polygon edge\n\t\tif (Vec.Dist(A, a) + Vec.Dist(A, b) === Vec.Dist(a, b)) return true\n\n\t\tif (a.y <= A.y) {\n\t\t\tif (b.y > A.y && cross(a, b, A) > 0) {\n\t\t\t\twindingNumber += 1\n\t\t\t}\n\t\t} else if (b.y <= A.y && cross(a, b, A) < 0) {\n\t\t\twindingNumber -= 1\n\t\t}\n\t}\n\n\treturn windingNumber !== 0\n}\n\n/**\n * The DOM likes values to be fixed to 3 decimal places\n *\n * @public\n */\nexport function toDomPrecision(v: number) {\n\treturn Math.round(v * 1e4) / 1e4\n}\n\n/**\n * @public\n */\nexport function toFixed(v: number) {\n\treturn Math.round(v * 1e2) / 1e2\n}\n\n/**\n * Check if a float is safe to use. ie: Not too big or small.\n * @public\n */\nexport const isSafeFloat = (n: number) => {\n\treturn Math.abs(n) < Number.MAX_SAFE_INTEGER\n}\n\n/**\n * Get the angle of a point on an arc.\n * @param fromAngle - The angle from center to arc's start point (A) on the circle\n * @param toAngle - The angle from center to arc's end point (B) on the circle\n * @param direction - The direction of the arc (1 = counter-clockwise, -1 = clockwise)\n * @returns The distance in radians between the two angles according to the direction\n * @public\n */\nexport function angleDistance(fromAngle: number, toAngle: number, direction: number) {\n\tconst dist =\n\t\tdirection < 0\n\t\t\t? clockwiseAngleDist(fromAngle, toAngle)\n\t\t\t: counterClockwiseAngleDist(fromAngle, toAngle)\n\treturn dist\n}\n\n/**\n * Returns the t value of the point on the arc.\n *\n * @param mAB - The measure of the arc from A to B, negative if counter-clockwise\n * @param A - The angle from center to arc's start point (A) on the circle\n * @param B - The angle from center to arc's end point (B) on the circle\n * @param P - The angle on the circle (P) to find the t value for\n *\n * @returns The t value of the point on the arc, with 0 being the start and 1 being the end\n *\n * @public\n */\nexport function getPointInArcT(mAB: number, A: number, B: number, P: number): number {\n\tlet mAP: number\n\tif (Math.abs(mAB) > PI) {\n\t\tmAP = shortAngleDist(A, P)\n\t\tconst mPB = shortAngleDist(P, B)\n\t\tif (Math.abs(mAP) < Math.abs(mPB)) {\n\t\t\treturn mAP / mAB\n\t\t} else {\n\t\t\treturn (mAB - mPB) / mAB\n\t\t}\n\t} else {\n\t\tmAP = shortAngleDist(A, P)\n\t\tconst t = mAP / mAB\n\n\t\t// If the arc is something like -2.8 to 2.2, then we'll get a weird bug\n\t\t// where the measurement to the center is negative but measure to points\n\t\t// near the end are positive\n\t\tif (Math.sign(mAP) !== Math.sign(mAB)) {\n\t\t\treturn Math.abs(t) > 0.5 ? 1 : 0\n\t\t}\n\n\t\treturn t\n\t}\n}\n\n/**\n * Get the measure of an arc.\n *\n * @param A - The angle from center to arc's start point (A) on the circle\n * @param B - The angle from center to arc's end point (B) on the circle\n * @param sweepFlag - 1 if the arc is clockwise, 0 if counter-clockwise\n * @param largeArcFlag - 1 if the arc is greater than 180 degrees, 0 if less than 180 degrees\n *\n * @returns The measure of the arc, negative if counter-clockwise\n *\n * @public\n */\nexport function getArcMeasure(A: number, B: number, sweepFlag: number, largeArcFlag: number) {\n\tconst m = ((2 * ((B - A) % PI2)) % PI2) - ((B - A) % PI2)\n\tif (!largeArcFlag) return m\n\treturn (PI2 - Math.abs(m)) * (sweepFlag ? 1 : -1)\n}\n\n/**\n * Get the center of a circle from three points.\n *\n * @param a - The first point\n * @param b - The second point\n * @param c - The third point\n *\n * @returns The center of the circle or null if the points are collinear\n *\n * @public\n */\nexport function centerOfCircleFromThreePoints(a: VecLike, b: VecLike, c: VecLike) {\n\tconst u = -2 * (a.x * (b.y - c.y) - a.y * (b.x - c.x) + b.x * c.y - c.x * b.y)\n\tconst x =\n\t\t((a.x * a.x + a.y * a.y) * (c.y - b.y) +\n\t\t\t(b.x * b.x + b.y * b.y) * (a.y - c.y) +\n\t\t\t(c.x * c.x + c.y * c.y) * (b.y - a.y)) /\n\t\tu\n\tconst y =\n\t\t((a.x * a.x + a.y * a.y) * (b.x - c.x) +\n\t\t\t(b.x * b.x + b.y * b.y) * (c.x - a.x) +\n\t\t\t(c.x * c.x + c.y * c.y) * (a.x - b.x)) /\n\t\tu\n\tif (!Number.isFinite(x) || !Number.isFinite(y)) {\n\t\treturn null\n\t}\n\treturn new Vec(x, y)\n}\n\n/** @public */\nexport function getPointsOnArc(\n\tstartPoint: VecLike,\n\tendPoint: VecLike,\n\tcenter: VecLike | null,\n\tradius: number,\n\tnumPoints: number\n): Vec[] {\n\tif (center === null) {\n\t\treturn [Vec.From(startPoint), Vec.From(endPoint)]\n\t}\n\tconst results: Vec[] = []\n\tconst startAngle = Vec.Angle(center, startPoint)\n\tconst endAngle = Vec.Angle(center, endPoint)\n\tconst l = clockwiseAngleDist(startAngle, endAngle)\n\tfor (let i = 0; i < numPoints; i++) {\n\t\tconst t = i / (numPoints - 1)\n\t\tconst angle = startAngle + l * t\n\t\tconst point = getPointOnCircle(center, radius, angle)\n\t\tresults.push(point)\n\t}\n\treturn results\n}\n"], -+ "mappings": "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", -+ "names": [] -+} -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/utils/SharedStylesMap.mjs b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/utils/SharedStylesMap.mjs -new file mode 100644 -index 0000000..6cdab4d ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/utils/SharedStylesMap.mjs -@@ -0,0 +1,85 @@ -+import { exhaustiveSwitchError } from "@tldraw/utils"; -+function sharedStyleEquals(a, b) { -+ if (!b) return false; -+ switch (a.type) { -+ case "mixed": -+ return b.type === "mixed"; -+ case "shared": -+ return b.type === "shared" && a.value === b.value; -+ default: -+ throw exhaustiveSwitchError(a); -+ } -+} -+class ReadonlySharedStyleMap { -+ /** @internal */ -+ map; -+ constructor(entries) { -+ this.map = new Map(entries); -+ } -+ get(prop) { -+ return this.map.get(prop); -+ } -+ getAsKnownValue(prop) { -+ const value = this.get(prop); -+ if (!value) return void 0; -+ if (value.type === "mixed") return void 0; -+ return value.value; -+ } -+ // eslint-disable-next-line no-restricted-syntax -+ get size() { -+ return this.map.size; -+ } -+ equals(other) { -+ if (this.size !== other.size) return false; -+ const checkedKeys = /* @__PURE__ */ new Set(); -+ for (const [styleProp, value] of this) { -+ if (!sharedStyleEquals(value, other.get(styleProp))) return false; -+ checkedKeys.add(styleProp); -+ } -+ for (const [styleProp, value] of other) { -+ if (checkedKeys.has(styleProp)) continue; -+ if (!sharedStyleEquals(value, this.get(styleProp))) return false; -+ } -+ return true; -+ } -+ keys() { -+ return this.map.keys(); -+ } -+ values() { -+ return this.map.values(); -+ } -+ entries() { -+ return this.map.entries(); -+ } -+ [Symbol.iterator]() { -+ return this.map[Symbol.iterator](); -+ } -+} -+class SharedStyleMap extends ReadonlySharedStyleMap { -+ set(prop, value) { -+ this.map.set(prop, value); -+ } -+ applyValue(prop, value) { -+ const existingValue = this.get(prop); -+ if (!existingValue) { -+ this.set(prop, { type: "shared", value }); -+ return; -+ } -+ switch (existingValue.type) { -+ case "mixed": -+ return; -+ case "shared": -+ if (existingValue.value !== value) { -+ this.set(prop, { type: "mixed" }); -+ } -+ return; -+ default: -+ exhaustiveSwitchError(existingValue, "type"); -+ } -+ } -+} -+export { -+ ReadonlySharedStyleMap, -+ SharedStyleMap -+}; -+//# sourceMappingURL=SharedStylesMap.mjs.map -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/utils/SharedStylesMap.mjs.map b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/utils/SharedStylesMap.mjs.map -new file mode 100644 -index 0000000..c4d98d7 ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/utils/SharedStylesMap.mjs.map -@@ -0,0 +1,7 @@ -+{ -+ "version": 3, -+ "sources": ["../../../src/lib/utils/SharedStylesMap.ts"], -+ "sourcesContent": ["import { StyleProp } from '@tldraw/tlschema'\nimport { exhaustiveSwitchError } from '@tldraw/utils'\n\n/**\n * The value of a particular {@link @tldraw/tlschema#StyleProp}.\n *\n * A `mixed` style means that in the current selection, there are lots of different values for the\n * same style prop - e.g. a red and a blue shape are selected.\n *\n * A `shared` style means that all shapes in the selection share the same value for this style prop.\n *\n * @public\n */\nexport type SharedStyle =\n\t| { readonly type: 'mixed' }\n\t| { readonly type: 'shared'; readonly value: T }\n\nfunction sharedStyleEquals(a: SharedStyle, b: SharedStyle | undefined) {\n\tif (!b) return false\n\tswitch (a.type) {\n\t\tcase 'mixed':\n\t\t\treturn b.type === 'mixed'\n\t\tcase 'shared':\n\t\t\treturn b.type === 'shared' && a.value === b.value\n\t\tdefault:\n\t\t\tthrow exhaustiveSwitchError(a)\n\t}\n}\n\n/**\n * A map of {@link @tldraw/tlschema#StyleProp | StyleProps} to their {@link SharedStyle} values. See\n * {@link Editor.getSharedStyles}.\n *\n * @public\n */\nexport class ReadonlySharedStyleMap {\n\t/** @internal */\n\tprotected map: Map, SharedStyle>\n\n\tconstructor(entries?: Iterable<[StyleProp, SharedStyle]>) {\n\t\tthis.map = new Map(entries)\n\t}\n\n\tget(prop: StyleProp): SharedStyle | undefined {\n\t\treturn this.map.get(prop) as SharedStyle | undefined\n\t}\n\n\tgetAsKnownValue(prop: StyleProp): T | undefined {\n\t\tconst value = this.get(prop)\n\t\tif (!value) return undefined\n\t\tif (value.type === 'mixed') return undefined\n\t\treturn value.value\n\t}\n\n\t// eslint-disable-next-line no-restricted-syntax\n\tget size() {\n\t\treturn this.map.size\n\t}\n\n\tequals(other: ReadonlySharedStyleMap) {\n\t\tif (this.size !== other.size) return false\n\n\t\tconst checkedKeys = new Set()\n\t\tfor (const [styleProp, value] of this) {\n\t\t\tif (!sharedStyleEquals(value, other.get(styleProp))) return false\n\t\t\tcheckedKeys.add(styleProp)\n\t\t}\n\t\tfor (const [styleProp, value] of other) {\n\t\t\tif (checkedKeys.has(styleProp)) continue\n\t\t\tif (!sharedStyleEquals(value, this.get(styleProp))) return false\n\t\t}\n\n\t\treturn true\n\t}\n\n\tkeys() {\n\t\treturn this.map.keys()\n\t}\n\n\tvalues() {\n\t\treturn this.map.values()\n\t}\n\n\tentries() {\n\t\treturn this.map.entries()\n\t}\n\n\t[Symbol.iterator]() {\n\t\treturn this.map[Symbol.iterator]()\n\t}\n}\n\n/** @internal */\nexport class SharedStyleMap extends ReadonlySharedStyleMap {\n\tset(prop: StyleProp, value: SharedStyle) {\n\t\tthis.map.set(prop, value)\n\t}\n\n\tapplyValue(prop: StyleProp, value: T) {\n\t\tconst existingValue = this.get(prop)\n\n\t\t// if we don't have a value yet, set it\n\t\tif (!existingValue) {\n\t\t\tthis.set(prop, { type: 'shared', value })\n\t\t\treturn\n\t\t}\n\n\t\tswitch (existingValue.type) {\n\t\t\tcase 'mixed':\n\t\t\t\t// we're already mixed, adding new values won't help\n\t\t\t\treturn\n\t\t\tcase 'shared':\n\t\t\t\tif (existingValue.value !== value) {\n\t\t\t\t\t// if the value is different, we're now mixed:\n\t\t\t\t\tthis.set(prop, { type: 'mixed' })\n\t\t\t\t}\n\t\t\t\treturn\n\t\t\tdefault:\n\t\t\t\texhaustiveSwitchError(existingValue, 'type')\n\t\t}\n\t}\n}\n"], -+ "mappings": "AACA,SAAS,6BAA6B;AAgBtC,SAAS,kBAAqB,GAAmB,GAA+B;AAC/E,MAAI,CAAC,EAAG,QAAO;AACf,UAAQ,EAAE,MAAM;AAAA,IACf,KAAK;AACJ,aAAO,EAAE,SAAS;AAAA,IACnB,KAAK;AACJ,aAAO,EAAE,SAAS,YAAY,EAAE,UAAU,EAAE;AAAA,IAC7C;AACC,YAAM,sBAAsB,CAAC;AAAA,EAC/B;AACD;AAQO,MAAM,uBAAuB;AAAA;AAAA,EAEzB;AAAA,EAEV,YAAY,SAAgE;AAC3E,SAAK,MAAM,IAAI,IAAI,OAAO;AAAA,EAC3B;AAAA,EAEA,IAAO,MAAgD;AACtD,WAAO,KAAK,IAAI,IAAI,IAAI;AAAA,EACzB;AAAA,EAEA,gBAAmB,MAAmC;AACrD,UAAM,QAAQ,KAAK,IAAI,IAAI;AAC3B,QAAI,CAAC,MAAO,QAAO;AACnB,QAAI,MAAM,SAAS,QAAS,QAAO;AACnC,WAAO,MAAM;AAAA,EACd;AAAA;AAAA,EAGA,IAAI,OAAO;AACV,WAAO,KAAK,IAAI;AAAA,EACjB;AAAA,EAEA,OAAO,OAA+B;AACrC,QAAI,KAAK,SAAS,MAAM,KAAM,QAAO;AAErC,UAAM,cAAc,oBAAI,IAAI;AAC5B,eAAW,CAAC,WAAW,KAAK,KAAK,MAAM;AACtC,UAAI,CAAC,kBAAkB,OAAO,MAAM,IAAI,SAAS,CAAC,EAAG,QAAO;AAC5D,kBAAY,IAAI,SAAS;AAAA,IAC1B;AACA,eAAW,CAAC,WAAW,KAAK,KAAK,OAAO;AACvC,UAAI,YAAY,IAAI,SAAS,EAAG;AAChC,UAAI,CAAC,kBAAkB,OAAO,KAAK,IAAI,SAAS,CAAC,EAAG,QAAO;AAAA,IAC5D;AAEA,WAAO;AAAA,EACR;AAAA,EAEA,OAAO;AACN,WAAO,KAAK,IAAI,KAAK;AAAA,EACtB;AAAA,EAEA,SAAS;AACR,WAAO,KAAK,IAAI,OAAO;AAAA,EACxB;AAAA,EAEA,UAAU;AACT,WAAO,KAAK,IAAI,QAAQ;AAAA,EACzB;AAAA,EAEA,CAAC,OAAO,QAAQ,IAAI;AACnB,WAAO,KAAK,IAAI,OAAO,QAAQ,EAAE;AAAA,EAClC;AACD;AAGO,MAAM,uBAAuB,uBAAuB;AAAA,EAC1D,IAAO,MAAoB,OAAuB;AACjD,SAAK,IAAI,IAAI,MAAM,KAAK;AAAA,EACzB;AAAA,EAEA,WAAc,MAAoB,OAAU;AAC3C,UAAM,gBAAgB,KAAK,IAAI,IAAI;AAGnC,QAAI,CAAC,eAAe;AACnB,WAAK,IAAI,MAAM,EAAE,MAAM,UAAU,MAAM,CAAC;AACxC;AAAA,IACD;AAEA,YAAQ,cAAc,MAAM;AAAA,MAC3B,KAAK;AAEJ;AAAA,MACD,KAAK;AACJ,YAAI,cAAc,UAAU,OAAO;AAElC,eAAK,IAAI,MAAM,EAAE,MAAM,QAAQ,CAAC;AAAA,QACjC;AACA;AAAA,MACD;AACC,8BAAsB,eAAe,MAAM;AAAA,IAC7C;AAAA,EACD;AACD;", -+ "names": [] -+} -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/utils/assets.mjs b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/utils/assets.mjs -new file mode 100644 -index 0000000..e57e315 ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/utils/assets.mjs -@@ -0,0 +1,18 @@ -+import { fetch } from "@tldraw/utils"; -+import { version } from "../../version.mjs"; -+function dataUrlToFile(url, filename, mimeType) { -+ return fetch(url).then(function(res) { -+ return res.arrayBuffer(); -+ }).then(function(buf) { -+ return new File([buf], filename, { type: mimeType }); -+ }); -+} -+const CDN_BASE_URL = "https://cdn.tldraw.com"; -+function getDefaultCdnBaseUrl() { -+ return `${CDN_BASE_URL}/${version}`; -+} -+export { -+ dataUrlToFile, -+ getDefaultCdnBaseUrl -+}; -+//# sourceMappingURL=assets.mjs.map -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/utils/assets.mjs.map b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/utils/assets.mjs.map -new file mode 100644 -index 0000000..c73a1cc ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/utils/assets.mjs.map -@@ -0,0 +1,7 @@ -+{ -+ "version": 3, -+ "sources": ["../../../src/lib/utils/assets.ts"], -+ "sourcesContent": ["import { fetch } from '@tldraw/utils'\nimport { version } from '../../version'\n\n/** @public */\nexport function dataUrlToFile(url: string, filename: string, mimeType: string) {\n\treturn fetch(url)\n\t\t.then(function (res) {\n\t\t\treturn res.arrayBuffer()\n\t\t})\n\t\t.then(function (buf) {\n\t\t\treturn new File([buf], filename, { type: mimeType })\n\t\t})\n}\n\n/** @internal */\nconst CDN_BASE_URL = 'https://cdn.tldraw.com'\n\n/** @public */\nexport function getDefaultCdnBaseUrl() {\n\treturn `${CDN_BASE_URL}/${version}`\n}\n"], -+ "mappings": "AAAA,SAAS,aAAa;AACtB,SAAS,eAAe;AAGjB,SAAS,cAAc,KAAa,UAAkB,UAAkB;AAC9E,SAAO,MAAM,GAAG,EACd,KAAK,SAAU,KAAK;AACpB,WAAO,IAAI,YAAY;AAAA,EACxB,CAAC,EACA,KAAK,SAAU,KAAK;AACpB,WAAO,IAAI,KAAK,CAAC,GAAG,GAAG,UAAU,EAAE,MAAM,SAAS,CAAC;AAAA,EACpD,CAAC;AACH;AAGA,MAAM,eAAe;AAGd,SAAS,uBAAuB;AACtC,SAAO,GAAG,YAAY,IAAI,OAAO;AAClC;", -+ "names": [] -+} -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/utils/debug-flags.mjs b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/utils/debug-flags.mjs -new file mode 100644 -index 0000000..d72bd5e ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/utils/debug-flags.mjs -@@ -0,0 +1,127 @@ -+import { atom, react } from "@tldraw/state"; -+import { deleteFromSessionStorage, getFromSessionStorage, setInSessionStorage } from "@tldraw/utils"; -+const featureFlags = {}; -+const pointerCaptureTrackingObject = createDebugValue( -+ "pointerCaptureTrackingObject", -+ // ideally we wouldn't store this mutable value in an atom but it's not -+ // a big deal for debug values -+ { -+ defaults: { all: /* @__PURE__ */ new Map() }, -+ shouldStoreForSession: false -+ } -+); -+const debugFlags = { -+ // --- DEBUG VALUES --- -+ logPreventDefaults: createDebugValue("logPreventDefaults", { -+ defaults: { all: false } -+ }), -+ logPointerCaptures: createDebugValue("logPointerCaptures", { -+ defaults: { all: false } -+ }), -+ logElementRemoves: createDebugValue("logElementRemoves", { -+ defaults: { all: false } -+ }), -+ debugSvg: createDebugValue("debugSvg", { -+ defaults: { all: false } -+ }), -+ showFps: createDebugValue("showFps", { -+ defaults: { all: false } -+ }), -+ measurePerformance: createDebugValue("measurePerformance", { defaults: { all: false } }), -+ throwToBlob: createDebugValue("throwToBlob", { -+ defaults: { all: false } -+ }), -+ reconnectOnPing: createDebugValue("reconnectOnPing", { -+ defaults: { all: false } -+ }), -+ debugCursors: createDebugValue("debugCursors", { -+ defaults: { all: false } -+ }), -+ forceSrgb: createDebugValue("forceSrgbColors", { defaults: { all: false } }), -+ debugGeometry: createDebugValue("debugGeometry", { defaults: { all: false } }), -+ hideShapes: createDebugValue("hideShapes", { defaults: { all: false } }), -+ editOnType: createDebugValue("editOnType", { defaults: { all: false } }) -+}; -+if (typeof Element !== "undefined") { -+ const nativeElementRemoveChild = Element.prototype.removeChild; -+ react("element removal logging", () => { -+ if (debugFlags.logElementRemoves.get()) { -+ Element.prototype.removeChild = function(child) { -+ console.warn("[tldraw] removing child:", child); -+ return nativeElementRemoveChild.call(this, child); -+ }; -+ } else { -+ Element.prototype.removeChild = nativeElementRemoveChild; -+ } -+ }); -+} -+function createDebugValue(name, { -+ defaults, -+ shouldStoreForSession = true -+}) { -+ return createDebugValueBase({ -+ name, -+ defaults, -+ shouldStoreForSession -+ }); -+} -+function createDebugValueBase(def) { -+ const defaultValue = getDefaultValue(def); -+ const storedValue = def.shouldStoreForSession ? getStoredInitialValue(def.name) : null; -+ const valueAtom = atom(`debug:${def.name}`, storedValue ?? defaultValue); -+ if (typeof window !== "undefined") { -+ if (def.shouldStoreForSession) { -+ react(`debug:${def.name}`, () => { -+ const currentValue = valueAtom.get(); -+ if (currentValue === defaultValue) { -+ deleteFromSessionStorage(`tldraw_debug:${def.name}`); -+ } else { -+ setInSessionStorage(`tldraw_debug:${def.name}`, JSON.stringify(currentValue)); -+ } -+ }); -+ } -+ Object.defineProperty(window, `tldraw${def.name.replace(/^[a-z]/, (l) => l.toUpperCase())}`, { -+ get() { -+ return valueAtom.get(); -+ }, -+ set(newValue) { -+ valueAtom.set(newValue); -+ }, -+ configurable: true -+ }); -+ } -+ return Object.assign(valueAtom, def); -+} -+function getStoredInitialValue(name) { -+ try { -+ return JSON.parse(getFromSessionStorage(`tldraw_debug:${name}`) ?? "null"); -+ } catch (err) { -+ return null; -+ } -+} -+function readEnv(fn) { -+ try { -+ return fn(); -+ } catch { -+ return null; -+ } -+} -+function getDefaultValue(def) { -+ const env = readEnv(() => process.env.TLDRAW_ENV) ?? readEnv(() => process.env.VERCEL_PUBLIC_TLDRAW_ENV) ?? readEnv(() => process.env.NEXT_PUBLIC_TLDRAW_ENV) ?? // default to production because if we don't have one of these, this is probably a library use -+ "production"; -+ switch (env) { -+ case "production": -+ return def.defaults.production ?? def.defaults.all; -+ case "preview": -+ case "staging": -+ return def.defaults.staging ?? def.defaults.all; -+ default: -+ return def.defaults.development ?? def.defaults.all; -+ } -+} -+export { -+ debugFlags, -+ featureFlags, -+ pointerCaptureTrackingObject -+}; -+//# sourceMappingURL=debug-flags.mjs.map -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/utils/debug-flags.mjs.map b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/utils/debug-flags.mjs.map -new file mode 100644 -index 0000000..3fab59c ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/utils/debug-flags.mjs.map -@@ -0,0 +1,7 @@ -+{ -+ "version": 3, -+ "sources": ["../../../src/lib/utils/debug-flags.ts"], -+ "sourcesContent": ["import { Atom, atom, react } from '@tldraw/state'\nimport { deleteFromSessionStorage, getFromSessionStorage, setInSessionStorage } from '@tldraw/utils'\n\n// --- 1. DEFINE ---\n//\n// Define your debug values and feature flags here. Use `createDebugValue` to\n// create an arbitrary value with defaults for production, staging, and\n// development. Use `createFeatureFlag` to create a boolean flag which will be\n// `true` by default in development and staging, and `false` in production.\n/** @internal */\nexport const featureFlags: Record> = {}\n\n/** @internal */\nexport const pointerCaptureTrackingObject = createDebugValue(\n\t'pointerCaptureTrackingObject',\n\t// ideally we wouldn't store this mutable value in an atom but it's not\n\t// a big deal for debug values\n\t{\n\t\tdefaults: { all: new Map() },\n\t\tshouldStoreForSession: false,\n\t}\n)\n\n/** @internal */\nexport const debugFlags = {\n\t// --- DEBUG VALUES ---\n\tlogPreventDefaults: createDebugValue('logPreventDefaults', {\n\t\tdefaults: { all: false },\n\t}),\n\tlogPointerCaptures: createDebugValue('logPointerCaptures', {\n\t\tdefaults: { all: false },\n\t}),\n\tlogElementRemoves: createDebugValue('logElementRemoves', {\n\t\tdefaults: { all: false },\n\t}),\n\tdebugSvg: createDebugValue('debugSvg', {\n\t\tdefaults: { all: false },\n\t}),\n\tshowFps: createDebugValue('showFps', {\n\t\tdefaults: { all: false },\n\t}),\n\tmeasurePerformance: createDebugValue('measurePerformance', { defaults: { all: false } }),\n\tthrowToBlob: createDebugValue('throwToBlob', {\n\t\tdefaults: { all: false },\n\t}),\n\treconnectOnPing: createDebugValue('reconnectOnPing', {\n\t\tdefaults: { all: false },\n\t}),\n\tdebugCursors: createDebugValue('debugCursors', {\n\t\tdefaults: { all: false },\n\t}),\n\tforceSrgb: createDebugValue('forceSrgbColors', { defaults: { all: false } }),\n\tdebugGeometry: createDebugValue('debugGeometry', { defaults: { all: false } }),\n\thideShapes: createDebugValue('hideShapes', { defaults: { all: false } }),\n\teditOnType: createDebugValue('editOnType', { defaults: { all: false } }),\n} as const\n\ndeclare global {\n\tinterface Window {\n\t\ttldrawLog(message: any): void\n\t}\n}\n\n// --- 2. USE ---\n// In normal code, read from debug flags directly by calling .value on them:\n// if (debugFlags.preventDefaultLogging.value) { ... }\n//\n// In react, wrap your reads in `useValue` (or your component in `track`)\n// so they react to changes:\n// const shouldLog = useValue(debugFlags.preventDefaultLogging)\n\n// --- 3. GET FUNKY ---\n// If you need to do fun stuff like monkey-patching in response to flag changes,\n// add that here. Make sure you wrap your code in `react` so it runs\n// automatically when values change!\n\nif (typeof Element !== 'undefined') {\n\tconst nativeElementRemoveChild = Element.prototype.removeChild\n\treact('element removal logging', () => {\n\t\tif (debugFlags.logElementRemoves.get()) {\n\t\t\tElement.prototype.removeChild = function (this: any, child: Node): T {\n\t\t\t\tconsole.warn('[tldraw] removing child:', child)\n\t\t\t\treturn nativeElementRemoveChild.call(this, child) as T\n\t\t\t}\n\t\t} else {\n\t\t\tElement.prototype.removeChild = nativeElementRemoveChild\n\t\t}\n\t})\n}\n\n// --- IMPLEMENTATION ---\n// you probably don't need to read this if you're just using the debug values system\nfunction createDebugValue(\n\tname: string,\n\t{\n\t\tdefaults,\n\t\tshouldStoreForSession = true,\n\t}: { defaults: DebugFlagDefaults; shouldStoreForSession?: boolean }\n) {\n\treturn createDebugValueBase({\n\t\tname,\n\t\tdefaults,\n\t\tshouldStoreForSession,\n\t})\n}\n\n// function createFeatureFlag(\n// \tname: string,\n// \t{\n// \t\tdefaults,\n// \t\tshouldStoreForSession = true,\n// \t}: { defaults: DebugFlagDefaults; shouldStoreForSession?: boolean }\n// ) {\n// \treturn createDebugValueBase({\n// \t\tname,\n// \t\tdefaults,\n// \t\tshouldStoreForSession,\n// \t})\n// }\n\nfunction createDebugValueBase(def: DebugFlagDef): DebugFlag {\n\tconst defaultValue = getDefaultValue(def)\n\tconst storedValue = def.shouldStoreForSession\n\t\t? (getStoredInitialValue(def.name) as T | null)\n\t\t: null\n\tconst valueAtom = atom(`debug:${def.name}`, storedValue ?? defaultValue)\n\n\tif (typeof window !== 'undefined') {\n\t\tif (def.shouldStoreForSession) {\n\t\t\treact(`debug:${def.name}`, () => {\n\t\t\t\tconst currentValue = valueAtom.get()\n\t\t\t\tif (currentValue === defaultValue) {\n\t\t\t\t\tdeleteFromSessionStorage(`tldraw_debug:${def.name}`)\n\t\t\t\t} else {\n\t\t\t\t\tsetInSessionStorage(`tldraw_debug:${def.name}`, JSON.stringify(currentValue))\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\n\t\tObject.defineProperty(window, `tldraw${def.name.replace(/^[a-z]/, (l) => l.toUpperCase())}`, {\n\t\t\tget() {\n\t\t\t\treturn valueAtom.get()\n\t\t\t},\n\t\t\tset(newValue) {\n\t\t\t\tvalueAtom.set(newValue)\n\t\t\t},\n\t\t\tconfigurable: true,\n\t\t})\n\t}\n\n\treturn Object.assign(valueAtom, def)\n}\n\nfunction getStoredInitialValue(name: string) {\n\ttry {\n\t\treturn JSON.parse(getFromSessionStorage(`tldraw_debug:${name}`) ?? 'null')\n\t} catch (err) {\n\t\treturn null\n\t}\n}\n\n// process.env might not be defined, but we can't access it using optional\n// chaining because some bundlers search for `process.env.SOMETHING` as a string\n// and replace it with its value.\nfunction readEnv(fn: () => string | undefined) {\n\ttry {\n\t\treturn fn()\n\t} catch {\n\t\treturn null\n\t}\n}\n\nfunction getDefaultValue(def: DebugFlagDef): T {\n\tconst env =\n\t\treadEnv(() => process.env.TLDRAW_ENV) ??\n\t\treadEnv(() => process.env.VERCEL_PUBLIC_TLDRAW_ENV) ??\n\t\treadEnv(() => process.env.NEXT_PUBLIC_TLDRAW_ENV) ??\n\t\t// default to production because if we don't have one of these, this is probably a library use\n\t\t'production'\n\n\tswitch (env) {\n\t\tcase 'production':\n\t\t\treturn def.defaults.production ?? def.defaults.all\n\t\tcase 'preview':\n\t\tcase 'staging':\n\t\t\treturn def.defaults.staging ?? def.defaults.all\n\t\tdefault:\n\t\t\treturn def.defaults.development ?? def.defaults.all\n\t}\n}\n\n/** @internal */\nexport interface DebugFlagDefaults {\n\tdevelopment?: T\n\tstaging?: T\n\tproduction?: T\n\tall: T\n}\n\n/** @internal */\nexport interface DebugFlagDef {\n\tname: string\n\tdefaults: DebugFlagDefaults\n\tshouldStoreForSession: boolean\n}\n\n/** @internal */\nexport type DebugFlag = DebugFlagDef & Atom\n"], -+ "mappings": "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", -+ "names": [] -+} -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/utils/deepLinks.mjs b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/utils/deepLinks.mjs -new file mode 100644 -index 0000000..5415830 ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/utils/deepLinks.mjs -@@ -0,0 +1,55 @@ -+import { PageRecordType, createShapeId } from "@tldraw/tlschema"; -+import { exhaustiveSwitchError } from "@tldraw/utils"; -+import { Box } from "../primitives/Box.mjs"; -+function createDeepLinkString(deepLink) { -+ switch (deepLink.type) { -+ case "shapes": { -+ const ids = deepLink.shapeIds.map((id) => encodeId(id.slice("shape:".length))); -+ return `s${ids.join(".")}`; -+ } -+ case "page": { -+ return "p" + encodeId(PageRecordType.parseId(deepLink.pageId)); -+ } -+ case "viewport": { -+ const { bounds, pageId } = deepLink; -+ let res = `v${Math.round(bounds.x)}.${Math.round(bounds.y)}.${Math.round(bounds.w)}.${Math.round(bounds.h)}`; -+ if (pageId) { -+ res += "." + encodeId(PageRecordType.parseId(pageId)); -+ } -+ return res; -+ } -+ default: -+ exhaustiveSwitchError(deepLink); -+ } -+} -+function parseDeepLinkString(deepLinkString) { -+ const type = deepLinkString[0]; -+ switch (type) { -+ case "s": { -+ const shapeIds = deepLinkString.slice(1).split(".").filter(Boolean).map((id) => createShapeId(decodeURIComponent(id))); -+ return { type: "shapes", shapeIds }; -+ } -+ case "p": { -+ const pageId = PageRecordType.createId(decodeURIComponent(deepLinkString.slice(1))); -+ return { type: "page", pageId }; -+ } -+ case "v": { -+ const [x, y, w, h, pageId] = deepLinkString.slice(1).split("."); -+ return { -+ type: "viewport", -+ bounds: new Box(Number(x), Number(y), Number(w), Number(h)), -+ pageId: pageId ? PageRecordType.createId(decodeURIComponent(pageId)) : void 0 -+ }; -+ } -+ default: -+ throw Error("Invalid deep link string"); -+ } -+} -+function encodeId(str) { -+ return encodeURIComponent(str).replace(/\./g, "%2E"); -+} -+export { -+ createDeepLinkString, -+ parseDeepLinkString -+}; -+//# sourceMappingURL=deepLinks.mjs.map -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/utils/deepLinks.mjs.map b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/utils/deepLinks.mjs.map -new file mode 100644 -index 0000000..4847aac ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/utils/deepLinks.mjs.map -@@ -0,0 +1,7 @@ -+{ -+ "version": 3, -+ "sources": ["../../../src/lib/utils/deepLinks.ts"], -+ "sourcesContent": ["import { BoxModel, PageRecordType, TLPageId, TLShapeId, createShapeId } from '@tldraw/tlschema'\nimport { exhaustiveSwitchError } from '@tldraw/utils'\nimport { Editor } from '../editor/Editor'\nimport { Box } from '../primitives/Box'\n\n/** @public */\nexport type TLDeepLink =\n\t| {\n\t\t\ttype: 'shapes'\n\t\t\tshapeIds: TLShapeId[]\n\t }\n\t| { type: 'viewport'; bounds: BoxModel; pageId?: TLPageId }\n\t| { type: 'page'; pageId: TLPageId }\n\n/**\n * Converts a deep link descriptor to a url-safe string\n *\n * @example\n * ```ts\n * const url = `https://example.com?d=${createDeepLinkString({ type: 'shapes', shapeIds: ['shape:1', 'shape:2'] })}`\n * navigator.clipboard.writeText(url)\n * ```\n *\n * @param deepLink - the deep link descriptor\n * @returns a url-safe string\n *\n * @public\n */\nexport function createDeepLinkString(deepLink: TLDeepLink): string {\n\tswitch (deepLink.type) {\n\t\tcase 'shapes': {\n\t\t\tconst ids = deepLink.shapeIds.map((id) => encodeId(id.slice('shape:'.length)))\n\t\t\treturn `s${ids.join('.')}`\n\t\t}\n\t\tcase 'page': {\n\t\t\treturn 'p' + encodeId(PageRecordType.parseId(deepLink.pageId))\n\t\t}\n\t\tcase 'viewport': {\n\t\t\tconst { bounds, pageId } = deepLink\n\t\t\tlet res = `v${Math.round(bounds.x)}.${Math.round(bounds.y)}.${Math.round(bounds.w)}.${Math.round(bounds.h)}`\n\t\t\tif (pageId) {\n\t\t\t\tres += '.' + encodeId(PageRecordType.parseId(pageId))\n\t\t\t}\n\t\t\treturn res\n\t\t}\n\t\tdefault:\n\t\t\texhaustiveSwitchError(deepLink)\n\t}\n}\n\n/**\n * Parses a string created by {@link createDeepLinkString} back into a deep link descriptor.\n *\n * @param deepLinkString - the deep link string\n * @returns a deep link descriptor\n *\n * @public\n */\nexport function parseDeepLinkString(deepLinkString: string): TLDeepLink {\n\tconst type = deepLinkString[0]\n\tswitch (type) {\n\t\tcase 's': {\n\t\t\tconst shapeIds = deepLinkString\n\t\t\t\t.slice(1)\n\t\t\t\t.split('.')\n\t\t\t\t.filter(Boolean)\n\t\t\t\t.map((id) => createShapeId(decodeURIComponent(id)))\n\t\t\treturn { type: 'shapes', shapeIds }\n\t\t}\n\t\tcase 'p': {\n\t\t\tconst pageId = PageRecordType.createId(decodeURIComponent(deepLinkString.slice(1)))\n\t\t\treturn { type: 'page', pageId }\n\t\t}\n\t\tcase 'v': {\n\t\t\tconst [x, y, w, h, pageId] = deepLinkString.slice(1).split('.')\n\t\t\treturn {\n\t\t\t\ttype: 'viewport',\n\t\t\t\tbounds: new Box(Number(x), Number(y), Number(w), Number(h)),\n\t\t\t\tpageId: pageId ? PageRecordType.createId(decodeURIComponent(pageId)) : undefined,\n\t\t\t}\n\t\t}\n\t\tdefault:\n\t\t\tthrow Error('Invalid deep link string')\n\t}\n}\n\nfunction encodeId(str: string): string {\n\t// need to encode dots because they are used as separators\n\treturn encodeURIComponent(str).replace(/\\./g, '%2E')\n}\n\n/** @public */\nexport interface TLDeepLinkOptions {\n\t/**\n\t * The name of the url search param to use for the deep link.\n\t *\n\t * Defaults to `'d'`\n\t */\n\tparam?: string\n\t/**\n\t * The debounce time in ms for updating the url.\n\t */\n\tdebounceMs?: number\n\t/**\n\t * Should return the current url to augment with a deep link query parameter.\n\t * If you supply this function, you must also supply an `onChange` function.\n\t */\n\tgetUrl?(editor: Editor): string | URL\n\t/**\n\t * Should return the current deep link target.\n\t * Defaults to returning the current page and viewport position.\n\t */\n\tgetTarget?(editor: Editor): TLDeepLink\n\t/**\n\t * This is fired when the URL is updated.\n\t *\n\t * If not supplied, the default behavior is to update `window.location`.\n\t *\n\t * @param url - the updated URL\n\t */\n\tonChange?(url: URL, editor: Editor): void\n}\n"], -+ "mappings": "AAAA,SAAmB,gBAAqC,qBAAqB;AAC7E,SAAS,6BAA6B;AAEtC,SAAS,WAAW;AAyBb,SAAS,qBAAqB,UAA8B;AAClE,UAAQ,SAAS,MAAM;AAAA,IACtB,KAAK,UAAU;AACd,YAAM,MAAM,SAAS,SAAS,IAAI,CAAC,OAAO,SAAS,GAAG,MAAM,SAAS,MAAM,CAAC,CAAC;AAC7E,aAAO,IAAI,IAAI,KAAK,GAAG,CAAC;AAAA,IACzB;AAAA,IACA,KAAK,QAAQ;AACZ,aAAO,MAAM,SAAS,eAAe,QAAQ,SAAS,MAAM,CAAC;AAAA,IAC9D;AAAA,IACA,KAAK,YAAY;AAChB,YAAM,EAAE,QAAQ,OAAO,IAAI;AAC3B,UAAI,MAAM,IAAI,KAAK,MAAM,OAAO,CAAC,CAAC,IAAI,KAAK,MAAM,OAAO,CAAC,CAAC,IAAI,KAAK,MAAM,OAAO,CAAC,CAAC,IAAI,KAAK,MAAM,OAAO,CAAC,CAAC;AAC1G,UAAI,QAAQ;AACX,eAAO,MAAM,SAAS,eAAe,QAAQ,MAAM,CAAC;AAAA,MACrD;AACA,aAAO;AAAA,IACR;AAAA,IACA;AACC,4BAAsB,QAAQ;AAAA,EAChC;AACD;AAUO,SAAS,oBAAoB,gBAAoC;AACvE,QAAM,OAAO,eAAe,CAAC;AAC7B,UAAQ,MAAM;AAAA,IACb,KAAK,KAAK;AACT,YAAM,WAAW,eACf,MAAM,CAAC,EACP,MAAM,GAAG,EACT,OAAO,OAAO,EACd,IAAI,CAAC,OAAO,cAAc,mBAAmB,EAAE,CAAC,CAAC;AACnD,aAAO,EAAE,MAAM,UAAU,SAAS;AAAA,IACnC;AAAA,IACA,KAAK,KAAK;AACT,YAAM,SAAS,eAAe,SAAS,mBAAmB,eAAe,MAAM,CAAC,CAAC,CAAC;AAClF,aAAO,EAAE,MAAM,QAAQ,OAAO;AAAA,IAC/B;AAAA,IACA,KAAK,KAAK;AACT,YAAM,CAAC,GAAG,GAAG,GAAG,GAAG,MAAM,IAAI,eAAe,MAAM,CAAC,EAAE,MAAM,GAAG;AAC9D,aAAO;AAAA,QACN,MAAM;AAAA,QACN,QAAQ,IAAI,IAAI,OAAO,CAAC,GAAG,OAAO,CAAC,GAAG,OAAO,CAAC,GAAG,OAAO,CAAC,CAAC;AAAA,QAC1D,QAAQ,SAAS,eAAe,SAAS,mBAAmB,MAAM,CAAC,IAAI;AAAA,MACxE;AAAA,IACD;AAAA,IACA;AACC,YAAM,MAAM,0BAA0B;AAAA,EACxC;AACD;AAEA,SAAS,SAAS,KAAqB;AAEtC,SAAO,mBAAmB,GAAG,EAAE,QAAQ,OAAO,KAAK;AACpD;", -+ "names": [] -+} -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/utils/dom.mjs b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/utils/dom.mjs -new file mode 100644 -index 0000000..216dfdd ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/utils/dom.mjs -@@ -0,0 +1,51 @@ -+import { debugFlags, pointerCaptureTrackingObject } from "./debug-flags.mjs"; -+function loopToHtmlElement(elm) { -+ if (elm.instanceOf(HTMLElement)) return elm; -+ if (elm.parentElement) return loopToHtmlElement(elm.parentElement); -+ else throw Error("Could not find a parent element of an HTML type!"); -+} -+function preventDefault(event) { -+ event.preventDefault(); -+ if (debugFlags.logPreventDefaults.get()) { -+ console.warn("preventDefault called on event:", event); -+ } -+} -+function setPointerCapture(element, event) { -+ element.setPointerCapture(event.pointerId); -+ if (debugFlags.logPointerCaptures.get()) { -+ const trackingObj = pointerCaptureTrackingObject.get(); -+ trackingObj.set(element, (trackingObj.get(element) ?? 0) + 1); -+ console.warn("setPointerCapture called on element:", element, event); -+ } -+} -+function releasePointerCapture(element, event) { -+ if (!element.hasPointerCapture(event.pointerId)) { -+ return; -+ } -+ element.releasePointerCapture(event.pointerId); -+ if (debugFlags.logPointerCaptures.get()) { -+ const trackingObj = pointerCaptureTrackingObject.get(); -+ if (trackingObj.get(element) === 1) { -+ trackingObj.delete(element); -+ } else if (trackingObj.has(element)) { -+ trackingObj.set(element, trackingObj.get(element) - 1); -+ } else { -+ console.warn("Release without capture"); -+ } -+ console.warn("releasePointerCapture called on element:", element, event); -+ } -+} -+const stopEventPropagation = (e) => e.stopPropagation(); -+const setStyleProperty = (elm, property, value) => { -+ if (!elm) return; -+ elm.style.setProperty(property, value); -+}; -+export { -+ loopToHtmlElement, -+ preventDefault, -+ releasePointerCapture, -+ setPointerCapture, -+ setStyleProperty, -+ stopEventPropagation -+}; -+//# sourceMappingURL=dom.mjs.map -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/utils/dom.mjs.map b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/utils/dom.mjs.map -new file mode 100644 -index 0000000..e08d616 ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/utils/dom.mjs.map -@@ -0,0 +1,7 @@ -+{ -+ "version": 3, -+ "sources": ["../../../src/lib/utils/dom.ts"], -+ "sourcesContent": ["/*\nThis is used to facilitate double clicking and pointer capture on elements.\n\nThe events in this file are possibly set on individual SVG elements, \nsuch as handles or corner handles, rather than on HTML elements or \nSVGSVGElements. Raw SVG elemnets do not support pointerCapture in \nmost cases, meaning that in order for pointer capture to work, we \nneed to crawl up the DOM tree to find the nearest HTML element. Then,\nin order for that element to also call the `onPointerUp` event from\nthis file, we need to manually set that event on that element and\nlater remove it when the pointerup occurs. This is a potential leak\nif the user clicks on a handle but the pointerup does not fire for\nwhatever reason.\n*/\n\nimport React from 'react'\nimport { debugFlags, pointerCaptureTrackingObject } from './debug-flags'\n\ndeclare global {\n\tinterface Node {\n\t\t/**\n * Cross-window capable instanceof check, a drop-in replacement\n * for instanceof checks on DOM Nodes. Remember to also check\n * for nulls when necessary.\n\t\t * \n\t\t * #NOTE: Copied from Obsidian.md API https://github.com/obsidianmd/obsidian-api/blob/master/obsidian.d.ts\n\t\t * \n * @param type\n */\n instanceOf(type: {\n new (): T;\n }): this is T;\n /**\n\t\t * The window object this node belongs to, or the global window.\n\t\t * \n\t\t * #NOTE: Copied from Obsidian.md API\n */\n win: Window;\n\t}\n}\n\n/** @public */\nexport function loopToHtmlElement(elm: Element): HTMLElement {\n\tif (elm.instanceOf(HTMLElement)) return elm\n\tif (elm.parentElement) return loopToHtmlElement(elm.parentElement)\n\telse throw Error('Could not find a parent element of an HTML type!')\n}\n\n/**\n * This function calls `event.preventDefault()` for you. Why is that useful?\n *\n * Beacuase if you enable `window.preventDefaultLogging = true` it'll log out a message when it\n * happens. Because we use console.warn rather than (log) you'll get a stack trace in the inspector\n * telling you exactly where it happened. This is important because `e.preventDefault()` is the\n * source of many bugs, but unfortuantly it can't be avoided because it also stops a lot of default\n * behaviour which doesn't make sense in our UI\n *\n * @param event - To prevent default on\n * @public\n */\nexport function preventDefault(event: React.BaseSyntheticEvent | Event) {\n\tevent.preventDefault()\n\tif (debugFlags.logPreventDefaults.get()) {\n\t\tconsole.warn('preventDefault called on event:', event)\n\t}\n}\n\n/** @public */\nexport function setPointerCapture(\n\telement: Element,\n\tevent: React.PointerEvent | PointerEvent\n) {\n\telement.setPointerCapture(event.pointerId)\n\tif (debugFlags.logPointerCaptures.get()) {\n\t\tconst trackingObj = pointerCaptureTrackingObject.get()\n\t\ttrackingObj.set(element, (trackingObj.get(element) ?? 0) + 1)\n\t\tconsole.warn('setPointerCapture called on element:', element, event)\n\t}\n}\n\n/** @public */\nexport function releasePointerCapture(\n\telement: Element,\n\tevent: React.PointerEvent | PointerEvent\n) {\n\tif (!element.hasPointerCapture(event.pointerId)) {\n\t\treturn\n\t}\n\n\telement.releasePointerCapture(event.pointerId)\n\tif (debugFlags.logPointerCaptures.get()) {\n\t\tconst trackingObj = pointerCaptureTrackingObject.get()\n\t\tif (trackingObj.get(element) === 1) {\n\t\t\ttrackingObj.delete(element)\n\t\t} else if (trackingObj.has(element)) {\n\t\t\ttrackingObj.set(element, trackingObj.get(element)! - 1)\n\t\t} else {\n\t\t\tconsole.warn('Release without capture')\n\t\t}\n\t\tconsole.warn('releasePointerCapture called on element:', element, event)\n\t}\n}\n\n/** @public */\nexport const stopEventPropagation = (e: any) => e.stopPropagation()\n\n/** @internal */\nexport const setStyleProperty = (\n\telm: HTMLElement | null,\n\tproperty: string,\n\tvalue: string | number\n) => {\n\tif (!elm) return\n\telm.style.setProperty(property, value as string)\n}\n"], -+ "mappings": "AAgBA,SAAS,YAAY,oCAAoC;AA0BlD,SAAS,kBAAkB,KAA2B;AAC5D,MAAI,IAAI,WAAW,WAAW,EAAG,QAAO;AACxC,MAAI,IAAI,cAAe,QAAO,kBAAkB,IAAI,aAAa;AAAA,MAC5D,OAAM,MAAM,kDAAkD;AACpE;AAcO,SAAS,eAAe,OAAyC;AACvE,QAAM,eAAe;AACrB,MAAI,WAAW,mBAAmB,IAAI,GAAG;AACxC,YAAQ,KAAK,mCAAmC,KAAK;AAAA,EACtD;AACD;AAGO,SAAS,kBACf,SACA,OACC;AACD,UAAQ,kBAAkB,MAAM,SAAS;AACzC,MAAI,WAAW,mBAAmB,IAAI,GAAG;AACxC,UAAM,cAAc,6BAA6B,IAAI;AACrD,gBAAY,IAAI,UAAU,YAAY,IAAI,OAAO,KAAK,KAAK,CAAC;AAC5D,YAAQ,KAAK,wCAAwC,SAAS,KAAK;AAAA,EACpE;AACD;AAGO,SAAS,sBACf,SACA,OACC;AACD,MAAI,CAAC,QAAQ,kBAAkB,MAAM,SAAS,GAAG;AAChD;AAAA,EACD;AAEA,UAAQ,sBAAsB,MAAM,SAAS;AAC7C,MAAI,WAAW,mBAAmB,IAAI,GAAG;AACxC,UAAM,cAAc,6BAA6B,IAAI;AACrD,QAAI,YAAY,IAAI,OAAO,MAAM,GAAG;AACnC,kBAAY,OAAO,OAAO;AAAA,IAC3B,WAAW,YAAY,IAAI,OAAO,GAAG;AACpC,kBAAY,IAAI,SAAS,YAAY,IAAI,OAAO,IAAK,CAAC;AAAA,IACvD,OAAO;AACN,cAAQ,KAAK,yBAAyB;AAAA,IACvC;AACA,YAAQ,KAAK,4CAA4C,SAAS,KAAK;AAAA,EACxE;AACD;AAGO,MAAM,uBAAuB,CAAC,MAAW,EAAE,gBAAgB;AAG3D,MAAM,mBAAmB,CAC/B,KACA,UACA,UACI;AACJ,MAAI,CAAC,IAAK;AACV,MAAI,MAAM,YAAY,UAAU,KAAe;AAChD;", -+ "names": [] -+} -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/utils/getIncrementedName.mjs b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/utils/getIncrementedName.mjs -new file mode 100644 -index 0000000..cf0ec7c ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/utils/getIncrementedName.mjs -@@ -0,0 +1,14 @@ -+function getIncrementedName(name, others) { -+ let result = name; -+ const set = new Set(others); -+ while (set.has(result)) { -+ result = /^.*(\d+)$/.exec(result)?.[1] ? result.replace(/(\d+)(?=\D?)$/, (m) => { -+ return (+m + 1).toString(); -+ }) : `${result} 1`; -+ } -+ return result; -+} -+export { -+ getIncrementedName -+}; -+//# sourceMappingURL=getIncrementedName.mjs.map -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/utils/getIncrementedName.mjs.map b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/utils/getIncrementedName.mjs.map -new file mode 100644 -index 0000000..171f74d ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/utils/getIncrementedName.mjs.map -@@ -0,0 +1,7 @@ -+{ -+ "version": 3, -+ "sources": ["../../../src/lib/utils/getIncrementedName.ts"], -+ "sourcesContent": ["/**\n * Get an incremented name (e.g. New page (2)) from a name (e.g. New page), based on an array of\n * existing names.\n *\n * @param name - The name to increment.\n * @param others - The array of existing names.\n * @public\n */\nexport function getIncrementedName(name: string, others: string[]) {\n\tlet result = name\n\tconst set = new Set(others)\n\n\twhile (set.has(result)) {\n\t\tresult = /^.*(\\d+)$/.exec(result)?.[1]\n\t\t\t? result.replace(/(\\d+)(?=\\D?)$/, (m) => {\n\t\t\t\t\treturn (+m + 1).toString()\n\t\t\t\t})\n\t\t\t: `${result} 1`\n\t}\n\n\treturn result\n}\n"], -+ "mappings": "AAQO,SAAS,mBAAmB,MAAc,QAAkB;AAClE,MAAI,SAAS;AACb,QAAM,MAAM,IAAI,IAAI,MAAM;AAE1B,SAAO,IAAI,IAAI,MAAM,GAAG;AACvB,aAAS,YAAY,KAAK,MAAM,IAAI,CAAC,IAClC,OAAO,QAAQ,iBAAiB,CAAC,MAAM;AACvC,cAAQ,CAAC,IAAI,GAAG,SAAS;AAAA,IAC1B,CAAC,IACA,GAAG,MAAM;AAAA,EACb;AAEA,SAAO;AACR;", -+ "names": [] -+} -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/utils/getPointerInfo.mjs b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/utils/getPointerInfo.mjs -new file mode 100644 -index 0000000..6c3aa65 ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/utils/getPointerInfo.mjs -@@ -0,0 +1,21 @@ -+function getPointerInfo(e) { -+ ; -+ e.isKilled = true; -+ return { -+ point: { -+ x: e.clientX, -+ y: e.clientY, -+ z: e.pressure -+ }, -+ shiftKey: e.shiftKey, -+ altKey: e.altKey, -+ ctrlKey: e.metaKey || e.ctrlKey, -+ pointerId: e.pointerId, -+ button: e.button, -+ isPen: e.pointerType === "pen" -+ }; -+} -+export { -+ getPointerInfo -+}; -+//# sourceMappingURL=getPointerInfo.mjs.map -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/utils/getPointerInfo.mjs.map b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/utils/getPointerInfo.mjs.map -new file mode 100644 -index 0000000..ab3c508 ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/utils/getPointerInfo.mjs.map -@@ -0,0 +1,7 @@ -+{ -+ "version": 3, -+ "sources": ["../../../src/lib/utils/getPointerInfo.ts"], -+ "sourcesContent": ["/** @public */\nexport function getPointerInfo(e: React.PointerEvent | PointerEvent) {\n\t;(e as any).isKilled = true\n\n\treturn {\n\t\tpoint: {\n\t\t\tx: e.clientX,\n\t\t\ty: e.clientY,\n\t\t\tz: e.pressure,\n\t\t},\n\t\tshiftKey: e.shiftKey,\n\t\taltKey: e.altKey,\n\t\tctrlKey: e.metaKey || e.ctrlKey,\n\t\tpointerId: e.pointerId,\n\t\tbutton: e.button,\n\t\tisPen: e.pointerType === 'pen',\n\t}\n}\n"], -+ "mappings": "AACO,SAAS,eAAe,GAAsC;AACpE;AAAC,EAAC,EAAU,WAAW;AAEvB,SAAO;AAAA,IACN,OAAO;AAAA,MACN,GAAG,EAAE;AAAA,MACL,GAAG,EAAE;AAAA,MACL,GAAG,EAAE;AAAA,IACN;AAAA,IACA,UAAU,EAAE;AAAA,IACZ,QAAQ,EAAE;AAAA,IACV,SAAS,EAAE,WAAW,EAAE;AAAA,IACxB,WAAW,EAAE;AAAA,IACb,QAAQ,EAAE;AAAA,IACV,OAAO,EAAE,gBAAgB;AAAA,EAC1B;AACD;", -+ "names": [] -+} -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/utils/getSvgPathFromPoints.mjs b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/utils/getSvgPathFromPoints.mjs -new file mode 100644 -index 0000000..fb40223 ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/utils/getSvgPathFromPoints.mjs -@@ -0,0 +1,30 @@ -+import { average, precise } from "../primitives/utils.mjs"; -+function getSvgPathFromPoints(points, closed = true) { -+ const len = points.length; -+ if (len < 2) { -+ return ""; -+ } -+ let a = points[0]; -+ let b = points[1]; -+ if (len === 2) { -+ return `M${precise(a)}L${precise(b)}`; -+ } -+ let result = ""; -+ for (let i = 2, max = len - 1; i < max; i++) { -+ a = points[i]; -+ b = points[i + 1]; -+ result += average(a, b); -+ } -+ if (closed) { -+ return `M${average(points[0], points[1])}Q${precise(points[1])}${average( -+ points[1], -+ points[2] -+ )}T${result}${average(points[len - 1], points[0])}${average(points[0], points[1])}Z`; -+ } else { -+ return `M${precise(points[0])}Q${precise(points[1])}${average(points[1], points[2])}${points.length > 3 ? "T" : ""}${result}L${precise(points[len - 1])}`; -+ } -+} -+export { -+ getSvgPathFromPoints -+}; -+//# sourceMappingURL=getSvgPathFromPoints.mjs.map -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/utils/getSvgPathFromPoints.mjs.map b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/utils/getSvgPathFromPoints.mjs.map -new file mode 100644 -index 0000000..3ba4937 ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/utils/getSvgPathFromPoints.mjs.map -@@ -0,0 +1,7 @@ -+{ -+ "version": 3, -+ "sources": ["../../../src/lib/utils/getSvgPathFromPoints.ts"], -+ "sourcesContent": ["import { VecLike } from '../primitives/Vec'\nimport { average, precise } from '../primitives/utils'\n\n/**\n * Turn an array of points into a path of quadradic curves.\n *\n * @param points - The points returned from perfect-freehand\n * @param closed - Whether the stroke is closed\n *\n * @public\n */\nexport function getSvgPathFromPoints(points: VecLike[], closed = true): string {\n\tconst len = points.length\n\n\tif (len < 2) {\n\t\treturn ''\n\t}\n\n\tlet a = points[0]\n\tlet b = points[1]\n\n\tif (len === 2) {\n\t\t// If only two points, just draw a line\n\t\treturn `M${precise(a)}L${precise(b)}`\n\t}\n\n\tlet result = ''\n\n\tfor (let i = 2, max = len - 1; i < max; i++) {\n\t\ta = points[i]\n\t\tb = points[i + 1]\n\t\tresult += average(a, b)\n\t}\n\n\tif (closed) {\n\t\t// If closed, draw a curve from the last point to the first\n\t\treturn `M${average(points[0], points[1])}Q${precise(points[1])}${average(\n\t\t\tpoints[1],\n\t\t\tpoints[2]\n\t\t)}T${result}${average(points[len - 1], points[0])}${average(points[0], points[1])}Z`\n\t} else {\n\t\t// If not closed, draw a curve starting at the first point and\n\t\t// ending at the midpoint of the last and second-last point, then\n\t\t// complete the curve with a line segment to the last point.\n\t\treturn `M${precise(points[0])}Q${precise(points[1])}${average(points[1], points[2])}${\n\t\t\tpoints.length > 3 ? 'T' : ''\n\t\t}${result}L${precise(points[len - 1])}`\n\t}\n}\n"], -+ "mappings": "AACA,SAAS,SAAS,eAAe;AAU1B,SAAS,qBAAqB,QAAmB,SAAS,MAAc;AAC9E,QAAM,MAAM,OAAO;AAEnB,MAAI,MAAM,GAAG;AACZ,WAAO;AAAA,EACR;AAEA,MAAI,IAAI,OAAO,CAAC;AAChB,MAAI,IAAI,OAAO,CAAC;AAEhB,MAAI,QAAQ,GAAG;AAEd,WAAO,IAAI,QAAQ,CAAC,CAAC,IAAI,QAAQ,CAAC,CAAC;AAAA,EACpC;AAEA,MAAI,SAAS;AAEb,WAAS,IAAI,GAAG,MAAM,MAAM,GAAG,IAAI,KAAK,KAAK;AAC5C,QAAI,OAAO,CAAC;AACZ,QAAI,OAAO,IAAI,CAAC;AAChB,cAAU,QAAQ,GAAG,CAAC;AAAA,EACvB;AAEA,MAAI,QAAQ;AAEX,WAAO,IAAI,QAAQ,OAAO,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,IAAI,QAAQ,OAAO,CAAC,CAAC,CAAC,GAAG;AAAA,MAChE,OAAO,CAAC;AAAA,MACR,OAAO,CAAC;AAAA,IACT,CAAC,IAAI,MAAM,GAAG,QAAQ,OAAO,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,GAAG,QAAQ,OAAO,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;AAAA,EAClF,OAAO;AAIN,WAAO,IAAI,QAAQ,OAAO,CAAC,CAAC,CAAC,IAAI,QAAQ,OAAO,CAAC,CAAC,CAAC,GAAG,QAAQ,OAAO,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,GAClF,OAAO,SAAS,IAAI,MAAM,EAC3B,GAAG,MAAM,IAAI,QAAQ,OAAO,MAAM,CAAC,CAAC,CAAC;AAAA,EACtC;AACD;", -+ "names": [] -+} -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/utils/hardResetEditor.mjs b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/utils/hardResetEditor.mjs -new file mode 100644 -index 0000000..ff6c02f ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/utils/hardResetEditor.mjs -@@ -0,0 +1,8 @@ -+import { runtime } from "./runtime.mjs"; -+function hardResetEditor() { -+ runtime.hardReset(); -+} -+export { -+ hardResetEditor -+}; -+//# sourceMappingURL=hardResetEditor.mjs.map -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/utils/hardResetEditor.mjs.map b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/utils/hardResetEditor.mjs.map -new file mode 100644 -index 0000000..fa6714c ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/utils/hardResetEditor.mjs.map -@@ -0,0 +1,7 @@ -+{ -+ "version": 3, -+ "sources": ["../../../src/lib/utils/hardResetEditor.ts"], -+ "sourcesContent": ["import { runtime } from './runtime'\n\n/** @public */\nexport function hardResetEditor() {\n\truntime.hardReset()\n}\n"], -+ "mappings": "AAAA,SAAS,eAAe;AAGjB,SAAS,kBAAkB;AACjC,UAAQ,UAAU;AACnB;", -+ "names": [] -+} -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/utils/licensing.mjs b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/utils/licensing.mjs -new file mode 100644 -index 0000000..8512c9e ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/utils/licensing.mjs -@@ -0,0 +1,27 @@ -+function str2ab(str) { -+ const buf = new ArrayBuffer(str.length); -+ const bufView = new Uint8Array(buf); -+ for (let i = 0, strLen = str.length; i < strLen; i++) { -+ bufView[i] = str.charCodeAt(i); -+ } -+ return buf; -+} -+function importPublicKey(pemContents) { -+ const binaryDerString = atob(pemContents); -+ const binaryDer = str2ab(binaryDerString); -+ return crypto.subtle.importKey( -+ "spki", -+ new Uint8Array(binaryDer), -+ { -+ name: "ECDSA", -+ namedCurve: "P-256" -+ }, -+ true, -+ ["verify"] -+ ); -+} -+export { -+ importPublicKey, -+ str2ab -+}; -+//# sourceMappingURL=licensing.mjs.map -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/utils/licensing.mjs.map b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/utils/licensing.mjs.map -new file mode 100644 -index 0000000..fc48bf2 ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/utils/licensing.mjs.map -@@ -0,0 +1,7 @@ -+{ -+ "version": 3, -+ "sources": ["../../../src/lib/utils/licensing.ts"], -+ "sourcesContent": ["/*\n Convert a string into an ArrayBuffer\n from https://developers.google.com/web/updates/2012/06/How-to-convert-ArrayBuffer-to-and-from-String\n*/\nexport function str2ab(str: string) {\n\tconst buf = new ArrayBuffer(str.length)\n\tconst bufView = new Uint8Array(buf)\n\tfor (let i = 0, strLen = str.length; i < strLen; i++) {\n\t\tbufView[i] = str.charCodeAt(i)\n\t}\n\treturn buf\n}\n\nexport function importPublicKey(pemContents: string) {\n\t// base64 decode the string to get the binary data\n\tconst binaryDerString = atob(pemContents)\n\t// convert from a binary string to an ArrayBuffer\n\tconst binaryDer = str2ab(binaryDerString)\n\n\treturn crypto.subtle.importKey(\n\t\t'spki',\n\t\tnew Uint8Array(binaryDer),\n\t\t{\n\t\t\tname: 'ECDSA',\n\t\t\tnamedCurve: 'P-256',\n\t\t},\n\t\ttrue,\n\t\t['verify']\n\t)\n}\n"], -+ "mappings": "AAIO,SAAS,OAAO,KAAa;AACnC,QAAM,MAAM,IAAI,YAAY,IAAI,MAAM;AACtC,QAAM,UAAU,IAAI,WAAW,GAAG;AAClC,WAAS,IAAI,GAAG,SAAS,IAAI,QAAQ,IAAI,QAAQ,KAAK;AACrD,YAAQ,CAAC,IAAI,IAAI,WAAW,CAAC;AAAA,EAC9B;AACA,SAAO;AACR;AAEO,SAAS,gBAAgB,aAAqB;AAEpD,QAAM,kBAAkB,KAAK,WAAW;AAExC,QAAM,YAAY,OAAO,eAAe;AAExC,SAAO,OAAO,OAAO;AAAA,IACpB;AAAA,IACA,IAAI,WAAW,SAAS;AAAA,IACxB;AAAA,MACC,MAAM;AAAA,MACN,YAAY;AAAA,IACb;AAAA,IACA;AAAA,IACA,CAAC,QAAQ;AAAA,EACV;AACD;", -+ "names": [] -+} -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/utils/normalizeWheel.mjs b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/utils/normalizeWheel.mjs -new file mode 100644 -index 0000000..97da1ac ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/utils/normalizeWheel.mjs -@@ -0,0 +1,22 @@ -+const MAX_ZOOM_STEP = 10; -+const IS_DARWIN = /Mac|iPod|iPhone|iPad/.test( -+ // eslint-disable-next-line deprecation/deprecation -+ typeof window === "undefined" ? "node" : window.navigator.platform -+); -+function normalizeWheel(event) { -+ let { deltaY, deltaX } = event; -+ let deltaZ = 0; -+ if (event.ctrlKey || event.altKey || event.metaKey) { -+ deltaZ = (Math.abs(deltaY) > MAX_ZOOM_STEP ? MAX_ZOOM_STEP * Math.sign(deltaY) : deltaY) / 100; -+ } else { -+ if (event.shiftKey && !IS_DARWIN) { -+ deltaX = deltaY; -+ deltaY = 0; -+ } -+ } -+ return { x: -deltaX, y: -deltaY, z: -deltaZ }; -+} -+export { -+ normalizeWheel -+}; -+//# sourceMappingURL=normalizeWheel.mjs.map -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/utils/normalizeWheel.mjs.map b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/utils/normalizeWheel.mjs.map -new file mode 100644 -index 0000000..d3c65d0 ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/utils/normalizeWheel.mjs.map -@@ -0,0 +1,7 @@ -+{ -+ "version": 3, -+ "sources": ["../../../src/lib/utils/normalizeWheel.ts"], -+ "sourcesContent": ["// Reasonable defaults\nconst MAX_ZOOM_STEP = 10\nconst IS_DARWIN = /Mac|iPod|iPhone|iPad/.test(\n\t// eslint-disable-next-line deprecation/deprecation\n\ttypeof window === 'undefined' ? 'node' : window.navigator.platform\n)\n\n// Adapted from https://stackoverflow.com/a/13650579\n/** @internal */\nexport function normalizeWheel(event: WheelEvent | React.WheelEvent) {\n\tlet { deltaY, deltaX } = event\n\tlet deltaZ = 0\n\n\t// wheeling\n\tif (event.ctrlKey || event.altKey || event.metaKey) {\n\t\tdeltaZ = (Math.abs(deltaY) > MAX_ZOOM_STEP ? MAX_ZOOM_STEP * Math.sign(deltaY) : deltaY) / 100\n\t} else {\n\t\tif (event.shiftKey && !IS_DARWIN) {\n\t\t\tdeltaX = deltaY\n\t\t\tdeltaY = 0\n\t\t}\n\t}\n\n\treturn { x: -deltaX, y: -deltaY, z: -deltaZ }\n}\n"], -+ "mappings": "AACA,MAAM,gBAAgB;AACtB,MAAM,YAAY,uBAAuB;AAAA;AAAA,EAExC,OAAO,WAAW,cAAc,SAAS,OAAO,UAAU;AAC3D;AAIO,SAAS,eAAe,OAAmD;AACjF,MAAI,EAAE,QAAQ,OAAO,IAAI;AACzB,MAAI,SAAS;AAGb,MAAI,MAAM,WAAW,MAAM,UAAU,MAAM,SAAS;AACnD,cAAU,KAAK,IAAI,MAAM,IAAI,gBAAgB,gBAAgB,KAAK,KAAK,MAAM,IAAI,UAAU;AAAA,EAC5F,OAAO;AACN,QAAI,MAAM,YAAY,CAAC,WAAW;AACjC,eAAS;AACT,eAAS;AAAA,IACV;AAAA,EACD;AAEA,SAAO,EAAE,GAAG,CAAC,QAAQ,GAAG,CAAC,QAAQ,GAAG,CAAC,OAAO;AAC7C;", -+ "names": [] -+} -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/utils/refreshPage.mjs b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/utils/refreshPage.mjs -new file mode 100644 -index 0000000..2c3ea7f ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/utils/refreshPage.mjs -@@ -0,0 +1,8 @@ -+import { runtime } from "./runtime.mjs"; -+function refreshPage() { -+ runtime.refreshPage(); -+} -+export { -+ refreshPage -+}; -+//# sourceMappingURL=refreshPage.mjs.map -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/utils/refreshPage.mjs.map b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/utils/refreshPage.mjs.map -new file mode 100644 -index 0000000..12d936d ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/utils/refreshPage.mjs.map -@@ -0,0 +1,7 @@ -+{ -+ "version": 3, -+ "sources": ["../../../src/lib/utils/refreshPage.ts"], -+ "sourcesContent": ["import { runtime } from './runtime'\n\n/** @public */\nexport function refreshPage() {\n\truntime.refreshPage()\n}\n"], -+ "mappings": "AAAA,SAAS,eAAe;AAGjB,SAAS,cAAc;AAC7B,UAAQ,YAAY;AACrB;", -+ "names": [] -+} -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/utils/reorderShapes.mjs b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/utils/reorderShapes.mjs -new file mode 100644 -index 0000000..8043a5f ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/utils/reorderShapes.mjs -@@ -0,0 +1,138 @@ -+import { compact, getIndicesBetween, sortByIndex } from "@tldraw/utils"; -+function getReorderingShapesChanges(editor, operation, ids) { -+ if (ids.length === 0) return []; -+ const parents = /* @__PURE__ */ new Map(); -+ for (const shape of compact(ids.map((id) => editor.getShape(id)))) { -+ const { parentId } = shape; -+ if (!parents.has(parentId)) { -+ parents.set(parentId, { -+ children: compact( -+ editor.getSortedChildIdsForParent(parentId).map((id) => editor.getShape(id)) -+ ), -+ moving: /* @__PURE__ */ new Set() -+ }); -+ } -+ parents.get(parentId).moving.add(shape); -+ } -+ const changes = []; -+ switch (operation) { -+ case "toBack": { -+ parents.forEach(({ moving, children }) => reorderToBack(moving, children, changes)); -+ break; -+ } -+ case "toFront": { -+ parents.forEach(({ moving, children }) => reorderToFront(moving, children, changes)); -+ break; -+ } -+ case "forward": { -+ parents.forEach(({ moving, children }) => reorderForward(moving, children, changes)); -+ break; -+ } -+ case "backward": { -+ parents.forEach(({ moving, children }) => reorderBackward(moving, children, changes)); -+ break; -+ } -+ } -+ return changes; -+} -+function reorderToBack(moving, children, changes) { -+ const len = children.length; -+ if (moving.size === len) return; -+ let below; -+ let above; -+ for (let i = 0; i < len; i++) { -+ const shape = children[i]; -+ if (moving.has(shape)) { -+ below = shape.index; -+ moving.delete(shape); -+ } else { -+ above = shape.index; -+ break; -+ } -+ } -+ if (moving.size === 0) { -+ return; -+ } else { -+ const indices = getIndicesBetween(below, above, moving.size); -+ changes.push( -+ ...Array.from(moving.values()).sort(sortByIndex).map((shape, i) => ({ ...shape, index: indices[i] })) -+ ); -+ } -+} -+function reorderToFront(moving, children, changes) { -+ const len = children.length; -+ if (moving.size === len) return; -+ let below; -+ let above; -+ for (let i = len - 1; i > -1; i--) { -+ const shape = children[i]; -+ if (moving.has(shape)) { -+ above = shape.index; -+ moving.delete(shape); -+ } else { -+ below = shape.index; -+ break; -+ } -+ } -+ if (moving.size === 0) { -+ return; -+ } else { -+ const indices = getIndicesBetween(below, above, moving.size); -+ changes.push( -+ ...Array.from(moving.values()).sort(sortByIndex).map((shape, i) => ({ ...shape, index: indices[i] })) -+ ); -+ } -+} -+function reorderForward(moving, children, changes) { -+ const len = children.length; -+ if (moving.size === len) return; -+ let state = { name: "skipping" }; -+ for (let i = 0; i < len; i++) { -+ const isMoving = moving.has(children[i]); -+ switch (state.name) { -+ case "skipping": { -+ if (!isMoving) continue; -+ state = { name: "selecting", selectIndex: i }; -+ break; -+ } -+ case "selecting": { -+ if (isMoving) continue; -+ const { selectIndex } = state; -+ getIndicesBetween(children[i].index, children[i + 1]?.index, i - selectIndex).forEach( -+ (index, k) => changes.push({ ...children[selectIndex + k], index }) -+ ); -+ state = { name: "skipping" }; -+ break; -+ } -+ } -+ } -+} -+function reorderBackward(moving, children, changes) { -+ const len = children.length; -+ if (moving.size === len) return; -+ let state = { name: "skipping" }; -+ for (let i = len - 1; i > -1; i--) { -+ const isMoving = moving.has(children[i]); -+ switch (state.name) { -+ case "skipping": { -+ if (!isMoving) continue; -+ state = { name: "selecting", selectIndex: i }; -+ break; -+ } -+ case "selecting": { -+ if (isMoving) continue; -+ getIndicesBetween(children[i - 1]?.index, children[i].index, state.selectIndex - i).forEach( -+ (index, k) => { -+ changes.push({ ...children[i + k + 1], index }); -+ } -+ ); -+ state = { name: "skipping" }; -+ break; -+ } -+ } -+ } -+} -+export { -+ getReorderingShapesChanges -+}; -+//# sourceMappingURL=reorderShapes.mjs.map -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/utils/reorderShapes.mjs.map b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/utils/reorderShapes.mjs.map -new file mode 100644 -index 0000000..2020791 ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/utils/reorderShapes.mjs.map -@@ -0,0 +1,7 @@ -+{ -+ "version": 3, -+ "sources": ["../../../src/lib/utils/reorderShapes.ts"], -+ "sourcesContent": ["import { TLParentId, TLShape, TLShapeId, TLShapePartial } from '@tldraw/tlschema'\nimport { IndexKey, compact, getIndicesBetween, sortByIndex } from '@tldraw/utils'\nimport { Editor } from '../editor/Editor'\n\nexport function getReorderingShapesChanges(\n\teditor: Editor,\n\toperation: 'toBack' | 'toFront' | 'forward' | 'backward',\n\tids: TLShapeId[]\n) {\n\tif (ids.length === 0) return []\n\n\t// From the ids that are moving, collect the parents, their children, and which of those children are moving\n\tconst parents = new Map; children: TLShape[] }>()\n\n\tfor (const shape of compact(ids.map((id) => editor.getShape(id)))) {\n\t\tconst { parentId } = shape\n\t\tif (!parents.has(parentId)) {\n\t\t\tparents.set(parentId, {\n\t\t\t\tchildren: compact(\n\t\t\t\t\teditor.getSortedChildIdsForParent(parentId).map((id) => editor.getShape(id))\n\t\t\t\t),\n\t\t\t\tmoving: new Set(),\n\t\t\t})\n\t\t}\n\t\tparents.get(parentId)!.moving.add(shape)\n\t}\n\n\tconst changes: TLShapePartial[] = []\n\n\tswitch (operation) {\n\t\tcase 'toBack': {\n\t\t\tparents.forEach(({ moving, children }) => reorderToBack(moving, children, changes))\n\t\t\tbreak\n\t\t}\n\t\tcase 'toFront': {\n\t\t\tparents.forEach(({ moving, children }) => reorderToFront(moving, children, changes))\n\t\t\tbreak\n\t\t}\n\t\tcase 'forward': {\n\t\t\tparents.forEach(({ moving, children }) => reorderForward(moving, children, changes))\n\t\t\tbreak\n\t\t}\n\t\tcase 'backward': {\n\t\t\tparents.forEach(({ moving, children }) => reorderBackward(moving, children, changes))\n\t\t\tbreak\n\t\t}\n\t}\n\n\treturn changes\n}\n\n/**\n * Reorders the moving shapes to the back of the parent's children.\n *\n * @param moving The set of shapes that are moving\n * @param children The parent's children\n * @param changes The changes array to push changes to\n */\nfunction reorderToBack(moving: Set, children: TLShape[], changes: TLShapePartial[]) {\n\tconst len = children.length\n\n\t// If all of the children are moving, there's nothing to do\n\tif (moving.size === len) return\n\n\tlet below: IndexKey | undefined\n\tlet above: IndexKey | undefined\n\n\t// Starting at the bottom of this parent's children...\n\tfor (let i = 0; i < len; i++) {\n\t\tconst shape = children[i]\n\n\t\tif (moving.has(shape)) {\n\t\t\t// If we've found a moving shape before we've found a non-moving shape,\n\t\t\t// then that shape is already at the back; we can remove it from the\n\t\t\t// moving set and mark it as the shape that will be below the moved shapes.\n\t\t\tbelow = shape.index\n\t\t\tmoving.delete(shape)\n\t\t} else {\n\t\t\t// The first non-moving shape we find will be above our moved shapes; we'll\n\t\t\t// put our moving shapes between it and the shape marked as below (if any).\n\t\t\tabove = shape.index\n\t\t\tbreak\n\t\t}\n\t}\n\n\tif (moving.size === 0) {\n\t\t// If our moving set is empty, there's nothing to do; all of our shapes were\n\t\t// already at the back of the parent's children.\n\t\treturn\n\t} else {\n\t\t// Sort the moving shapes by their current index, then apply the new indices\n\t\tconst indices = getIndicesBetween(below, above, moving.size)\n\t\tchanges.push(\n\t\t\t...Array.from(moving.values())\n\t\t\t\t.sort(sortByIndex)\n\t\t\t\t.map((shape, i) => ({ ...shape, index: indices[i] }))\n\t\t)\n\t}\n}\n\n/**\n * Reorders the moving shapes to the front of the parent's children.\n *\n * @param moving The set of shapes that are moving\n * @param children The parent's children\n * @param changes The changes array to push changes to\n */\nfunction reorderToFront(moving: Set, children: TLShape[], changes: TLShapePartial[]) {\n\tconst len = children.length\n\n\t// If all of the children are moving, there's nothing to do\n\tif (moving.size === len) return\n\n\tlet below: IndexKey | undefined\n\tlet above: IndexKey | undefined\n\n\t// Starting at the top of this parent's children...\n\tfor (let i = len - 1; i > -1; i--) {\n\t\tconst shape = children[i]\n\n\t\tif (moving.has(shape)) {\n\t\t\t// If we've found a moving shape before we've found a non-moving shape,\n\t\t\t// then that shape is already at the front; we can remove it from the\n\t\t\t// moving set and mark it as the shape that will be above the moved shapes.\n\t\t\tabove = shape.index\n\t\t\tmoving.delete(shape)\n\t\t} else {\n\t\t\t// The first non-moving shape we find will be below our moved shapes; we'll\n\t\t\t// put our moving shapes between it and the shape marked as above (if any).\n\t\t\tbelow = shape.index\n\t\t\tbreak\n\t\t}\n\t}\n\n\tif (moving.size === 0) {\n\t\t// If our moving set is empty, there's nothing to do; all of our shapes were\n\t\t// already at the front of the parent's children.\n\t\treturn\n\t} else {\n\t\t// Sort the moving shapes by their current index, then apply the new indices\n\t\tconst indices = getIndicesBetween(below, above, moving.size)\n\t\tchanges.push(\n\t\t\t...Array.from(moving.values())\n\t\t\t\t.sort(sortByIndex)\n\t\t\t\t.map((shape, i) => ({ ...shape, index: indices[i] }))\n\t\t)\n\t}\n}\n\n/**\n * Reorders the moving shapes forward in the parent's children.\n *\n * @param moving The set of shapes that are moving\n * @param children The parent's children\n * @param changes The changes array to push changes to\n */\nfunction reorderForward(moving: Set, children: TLShape[], changes: TLShapePartial[]) {\n\tconst len = children.length\n\n\t// If all of the children are moving, there's nothing to do\n\tif (moving.size === len) return\n\n\tlet state = { name: 'skipping' } as\n\t\t| { name: 'skipping' }\n\t\t| { name: 'selecting'; selectIndex: number }\n\n\t// Starting at the bottom of this parent's children...\n\tfor (let i = 0; i < len; i++) {\n\t\tconst isMoving = moving.has(children[i])\n\n\t\tswitch (state.name) {\n\t\t\tcase 'skipping': {\n\t\t\t\tif (!isMoving) continue\n\t\t\t\t// If we find a moving shape while skipping, start selecting\n\t\t\t\tstate = { name: 'selecting', selectIndex: i }\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'selecting': {\n\t\t\t\tif (isMoving) continue\n\t\t\t\t// if we find a non-moving shape while selecting, move all selected\n\t\t\t\t// shapes in front of the not moving shape; and start skipping\n\t\t\t\tconst { selectIndex } = state\n\t\t\t\tgetIndicesBetween(children[i].index, children[i + 1]?.index, i - selectIndex).forEach(\n\t\t\t\t\t(index, k) => changes.push({ ...children[selectIndex + k], index })\n\t\t\t\t)\n\t\t\t\tstate = { name: 'skipping' }\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n}\n\n/**\n * Reorders the moving shapes backward in the parent's children.\n *\n * @param moving The set of shapes that are moving\n * @param children The parent's children\n * @param changes The changes array to push changes to\n */\nfunction reorderBackward(moving: Set, children: TLShape[], changes: TLShapePartial[]) {\n\tconst len = children.length\n\n\tif (moving.size === len) return\n\n\tlet state = { name: 'skipping' } as\n\t\t| { name: 'skipping' }\n\t\t| { name: 'selecting'; selectIndex: number }\n\n\t// Starting at the top of this parent's children...\n\tfor (let i = len - 1; i > -1; i--) {\n\t\tconst isMoving = moving.has(children[i])\n\n\t\tswitch (state.name) {\n\t\t\tcase 'skipping': {\n\t\t\t\tif (!isMoving) continue\n\t\t\t\t// If we find a moving shape while skipping, start selecting\n\t\t\t\tstate = { name: 'selecting', selectIndex: i }\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'selecting': {\n\t\t\t\tif (isMoving) continue\n\t\t\t\t// if we find a non-moving shape while selecting, move all selected\n\t\t\t\t// shapes in behind of the not moving shape; and start skipping\n\t\t\t\tgetIndicesBetween(children[i - 1]?.index, children[i].index, state.selectIndex - i).forEach(\n\t\t\t\t\t(index, k) => {\n\t\t\t\t\t\tchanges.push({ ...children[i + k + 1], index })\n\t\t\t\t\t}\n\t\t\t\t)\n\t\t\t\tstate = { name: 'skipping' }\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n}\n"], -+ "mappings": "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", -+ "names": [] -+} -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/utils/rotation.mjs b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/utils/rotation.mjs -new file mode 100644 -index 0000000..b03e061 ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/utils/rotation.mjs -@@ -0,0 +1,79 @@ -+import { isShapeId } from "@tldraw/tlschema"; -+import { compact } from "@tldraw/utils"; -+import { Mat } from "../primitives/Mat.mjs"; -+import { canonicalizeRotation } from "../primitives/utils.mjs"; -+import { Vec } from "../primitives/Vec.mjs"; -+function getRotationSnapshot({ -+ editor, -+ ids -+}) { -+ const shapes = compact(ids.map((id) => editor.getShape(id))); -+ const rotation = editor.getShapesSharedRotation(ids); -+ const rotatedPageBounds = editor.getShapesRotatedPageBounds(ids); -+ if (!rotatedPageBounds) { -+ return null; -+ } -+ const pageCenter = rotatedPageBounds.center.clone().rotWith(rotatedPageBounds.point, rotation); -+ return { -+ pageCenter, -+ initialCursorAngle: pageCenter.angle(editor.inputs.originPagePoint), -+ initialShapesRotation: rotation, -+ shapeSnapshots: shapes.map((shape) => ({ -+ shape, -+ initialPagePoint: editor.getShapePageTransform(shape.id).point() -+ })) -+ }; -+} -+function applyRotationToSnapshotShapes({ -+ delta, -+ editor, -+ snapshot, -+ stage, -+ centerOverride -+}) { -+ const { pageCenter, shapeSnapshots } = snapshot; -+ editor.updateShapes( -+ shapeSnapshots.map(({ shape, initialPagePoint }) => { -+ const parentTransform = isShapeId(shape.parentId) ? editor.getShapePageTransform(shape.parentId) : Mat.Identity(); -+ const newPagePoint = Vec.RotWith(initialPagePoint, centerOverride ?? pageCenter, delta); -+ const newLocalPoint = Mat.applyToPoint( -+ // use the current parent transform in case it has moved/resized since the start -+ // (e.g. if rotating a shape at the edge of a group) -+ Mat.Inverse(parentTransform), -+ newPagePoint -+ ); -+ const newRotation = canonicalizeRotation(shape.rotation + delta); -+ return { -+ id: shape.id, -+ type: shape.type, -+ x: newLocalPoint.x, -+ y: newLocalPoint.y, -+ rotation: newRotation -+ }; -+ }) -+ ); -+ const changes = []; -+ shapeSnapshots.forEach(({ shape }) => { -+ const current = editor.getShape(shape.id); -+ if (!current) return; -+ const util = editor.getShapeUtil(shape); -+ if (stage === "start" || stage === "one-off") { -+ const changeStart = util.onRotateStart?.(shape); -+ if (changeStart) changes.push(changeStart); -+ } -+ const changeUpdate = util.onRotate?.(shape, current); -+ if (changeUpdate) changes.push(changeUpdate); -+ if (stage === "end" || stage === "one-off") { -+ const changeEnd = util.onRotateEnd?.(shape, current); -+ if (changeEnd) changes.push(changeEnd); -+ } -+ }); -+ if (changes.length > 0) { -+ editor.updateShapes(changes); -+ } -+} -+export { -+ applyRotationToSnapshotShapes, -+ getRotationSnapshot -+}; -+//# sourceMappingURL=rotation.mjs.map -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/utils/rotation.mjs.map b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/utils/rotation.mjs.map -new file mode 100644 -index 0000000..2a9be1b ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/utils/rotation.mjs.map -@@ -0,0 +1,7 @@ -+{ -+ "version": 3, -+ "sources": ["../../../src/lib/utils/rotation.ts"], -+ "sourcesContent": ["import { isShapeId, TLShape, TLShapeId, TLShapePartial } from '@tldraw/tlschema'\nimport { compact } from '@tldraw/utils'\nimport { Editor } from '../editor/Editor'\nimport { Mat } from '../primitives/Mat'\nimport { canonicalizeRotation } from '../primitives/utils'\nimport { Vec, VecLike } from '../primitives/Vec'\n\n/** @internal */\nexport function getRotationSnapshot({\n\teditor,\n\tids,\n}: {\n\teditor: Editor\n\tids: TLShapeId[]\n}): TLRotationSnapshot | null {\n\tconst shapes = compact(ids.map((id) => editor.getShape(id)))\n\tconst rotation = editor.getShapesSharedRotation(ids)\n\tconst rotatedPageBounds = editor.getShapesRotatedPageBounds(ids)\n\n\t// todo: this assumes we're rotating the selected shapes\n\t// if we try to rotate shapes that aren't selected, this\n\t// will produce the wrong results\n\n\t// Return null if there are no selected shapes\n\tif (!rotatedPageBounds) {\n\t\treturn null\n\t}\n\n\tconst pageCenter = rotatedPageBounds.center.clone().rotWith(rotatedPageBounds.point, rotation)\n\n\treturn {\n\t\tpageCenter,\n\t\tinitialCursorAngle: pageCenter.angle(editor.inputs.originPagePoint),\n\t\tinitialShapesRotation: rotation,\n\t\tshapeSnapshots: shapes.map((shape) => ({\n\t\t\tshape,\n\t\t\tinitialPagePoint: editor.getShapePageTransform(shape.id)!.point(),\n\t\t})),\n\t}\n}\n\n/**\n * @internal\n **/\nexport interface TLRotationSnapshot {\n\tpageCenter: Vec\n\tinitialCursorAngle: number\n\tinitialShapesRotation: number\n\tshapeSnapshots: {\n\t\tshape: TLShape\n\t\tinitialPagePoint: Vec\n\t}[]\n}\n\n/** @internal */\nexport function applyRotationToSnapshotShapes({\n\tdelta,\n\teditor,\n\tsnapshot,\n\tstage,\n\tcenterOverride,\n}: {\n\tdelta: number\n\tsnapshot: TLRotationSnapshot\n\teditor: Editor\n\tstage: 'start' | 'update' | 'end' | 'one-off'\n\tcenterOverride?: VecLike\n}) {\n\tconst { pageCenter, shapeSnapshots } = snapshot\n\n\teditor.updateShapes(\n\t\tshapeSnapshots.map(({ shape, initialPagePoint }) => {\n\t\t\t// We need to both rotate each shape individually and rotate the shapes\n\t\t\t// around the pivot point (the average center of all rotating shapes.)\n\n\t\t\tconst parentTransform = isShapeId(shape.parentId)\n\t\t\t\t? editor.getShapePageTransform(shape.parentId)!\n\t\t\t\t: Mat.Identity()\n\n\t\t\tconst newPagePoint = Vec.RotWith(initialPagePoint, centerOverride ?? pageCenter, delta)\n\n\t\t\tconst newLocalPoint = Mat.applyToPoint(\n\t\t\t\t// use the current parent transform in case it has moved/resized since the start\n\t\t\t\t// (e.g. if rotating a shape at the edge of a group)\n\t\t\t\tMat.Inverse(parentTransform),\n\t\t\t\tnewPagePoint\n\t\t\t)\n\t\t\tconst newRotation = canonicalizeRotation(shape.rotation + delta)\n\n\t\t\treturn {\n\t\t\t\tid: shape.id,\n\t\t\t\ttype: shape.type,\n\t\t\t\tx: newLocalPoint.x,\n\t\t\t\ty: newLocalPoint.y,\n\t\t\t\trotation: newRotation,\n\t\t\t}\n\t\t})\n\t)\n\n\t// Handle change\n\n\tconst changes: TLShapePartial[] = []\n\n\tshapeSnapshots.forEach(({ shape }) => {\n\t\tconst current = editor.getShape(shape.id)\n\t\tif (!current) return\n\t\tconst util = editor.getShapeUtil(shape)\n\n\t\tif (stage === 'start' || stage === 'one-off') {\n\t\t\tconst changeStart = util.onRotateStart?.(shape)\n\t\t\tif (changeStart) changes.push(changeStart)\n\t\t}\n\n\t\tconst changeUpdate = util.onRotate?.(shape, current)\n\t\tif (changeUpdate) changes.push(changeUpdate)\n\n\t\tif (stage === 'end' || stage === 'one-off') {\n\t\t\tconst changeEnd = util.onRotateEnd?.(shape, current)\n\t\t\tif (changeEnd) changes.push(changeEnd)\n\t\t}\n\t})\n\n\tif (changes.length > 0) {\n\t\teditor.updateShapes(changes)\n\t}\n}\n"], -+ "mappings": "AAAA,SAAS,iBAAqD;AAC9D,SAAS,eAAe;AAExB,SAAS,WAAW;AACpB,SAAS,4BAA4B;AACrC,SAAS,WAAoB;AAGtB,SAAS,oBAAoB;AAAA,EACnC;AAAA,EACA;AACD,GAG8B;AAC7B,QAAM,SAAS,QAAQ,IAAI,IAAI,CAAC,OAAO,OAAO,SAAS,EAAE,CAAC,CAAC;AAC3D,QAAM,WAAW,OAAO,wBAAwB,GAAG;AACnD,QAAM,oBAAoB,OAAO,2BAA2B,GAAG;AAO/D,MAAI,CAAC,mBAAmB;AACvB,WAAO;AAAA,EACR;AAEA,QAAM,aAAa,kBAAkB,OAAO,MAAM,EAAE,QAAQ,kBAAkB,OAAO,QAAQ;AAE7F,SAAO;AAAA,IACN;AAAA,IACA,oBAAoB,WAAW,MAAM,OAAO,OAAO,eAAe;AAAA,IAClE,uBAAuB;AAAA,IACvB,gBAAgB,OAAO,IAAI,CAAC,WAAW;AAAA,MACtC;AAAA,MACA,kBAAkB,OAAO,sBAAsB,MAAM,EAAE,EAAG,MAAM;AAAA,IACjE,EAAE;AAAA,EACH;AACD;AAgBO,SAAS,8BAA8B;AAAA,EAC7C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACD,GAMG;AACF,QAAM,EAAE,YAAY,eAAe,IAAI;AAEvC,SAAO;AAAA,IACN,eAAe,IAAI,CAAC,EAAE,OAAO,iBAAiB,MAAM;AAInD,YAAM,kBAAkB,UAAU,MAAM,QAAQ,IAC7C,OAAO,sBAAsB,MAAM,QAAQ,IAC3C,IAAI,SAAS;AAEhB,YAAM,eAAe,IAAI,QAAQ,kBAAkB,kBAAkB,YAAY,KAAK;AAEtF,YAAM,gBAAgB,IAAI;AAAA;AAAA;AAAA,QAGzB,IAAI,QAAQ,eAAe;AAAA,QAC3B;AAAA,MACD;AACA,YAAM,cAAc,qBAAqB,MAAM,WAAW,KAAK;AAE/D,aAAO;AAAA,QACN,IAAI,MAAM;AAAA,QACV,MAAM,MAAM;AAAA,QACZ,GAAG,cAAc;AAAA,QACjB,GAAG,cAAc;AAAA,QACjB,UAAU;AAAA,MACX;AAAA,IACD,CAAC;AAAA,EACF;AAIA,QAAM,UAA4B,CAAC;AAEnC,iBAAe,QAAQ,CAAC,EAAE,MAAM,MAAM;AACrC,UAAM,UAAU,OAAO,SAAS,MAAM,EAAE;AACxC,QAAI,CAAC,QAAS;AACd,UAAM,OAAO,OAAO,aAAa,KAAK;AAEtC,QAAI,UAAU,WAAW,UAAU,WAAW;AAC7C,YAAM,cAAc,KAAK,gBAAgB,KAAK;AAC9C,UAAI,YAAa,SAAQ,KAAK,WAAW;AAAA,IAC1C;AAEA,UAAM,eAAe,KAAK,WAAW,OAAO,OAAO;AACnD,QAAI,aAAc,SAAQ,KAAK,YAAY;AAE3C,QAAI,UAAU,SAAS,UAAU,WAAW;AAC3C,YAAM,YAAY,KAAK,cAAc,OAAO,OAAO;AACnD,UAAI,UAAW,SAAQ,KAAK,SAAS;AAAA,IACtC;AAAA,EACD,CAAC;AAED,MAAI,QAAQ,SAAS,GAAG;AACvB,WAAO,aAAa,OAAO;AAAA,EAC5B;AACD;", -+ "names": [] -+} -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/utils/runtime.mjs b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/utils/runtime.mjs -new file mode 100644 -index 0000000..b4c383d ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/utils/runtime.mjs -@@ -0,0 +1,19 @@ -+const runtime = { -+ openWindow(url, target) { -+ window.open(url, target, "noopener noreferrer"); -+ }, -+ refreshPage() { -+ window.location.reload(); -+ }, -+ async hardReset() { -+ return await window.__tldraw__hardReset?.(); -+ } -+}; -+function setRuntimeOverrides(input) { -+ Object.assign(runtime, input); -+} -+export { -+ runtime, -+ setRuntimeOverrides -+}; -+//# sourceMappingURL=runtime.mjs.map -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/utils/runtime.mjs.map b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/utils/runtime.mjs.map -new file mode 100644 -index 0000000..40fe91b ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/utils/runtime.mjs.map -@@ -0,0 +1,7 @@ -+{ -+ "version": 3, -+ "sources": ["../../../src/lib/utils/runtime.ts"], -+ "sourcesContent": ["/** @public */\nexport const runtime: {\n\topenWindow(url: string, target: string): void\n\trefreshPage(): void\n\thardReset(): void\n} = {\n\topenWindow(url, target) {\n\t\twindow.open(url, target, 'noopener noreferrer')\n\t},\n\trefreshPage() {\n\t\twindow.location.reload()\n\t},\n\tasync hardReset() {\n\t\treturn await (window as any).__tldraw__hardReset?.()\n\t},\n}\n\n/** @public */\nexport function setRuntimeOverrides(input: Partial) {\n\tObject.assign(runtime, input)\n}\n"], -+ "mappings": "AACO,MAAM,UAIT;AAAA,EACH,WAAW,KAAK,QAAQ;AACvB,WAAO,KAAK,KAAK,QAAQ,qBAAqB;AAAA,EAC/C;AAAA,EACA,cAAc;AACb,WAAO,SAAS,OAAO;AAAA,EACxB;AAAA,EACA,MAAM,YAAY;AACjB,WAAO,MAAO,OAAe,sBAAsB;AAAA,EACpD;AACD;AAGO,SAAS,oBAAoB,OAAgC;AACnE,SAAO,OAAO,SAAS,KAAK;AAC7B;", -+ "names": [] -+} -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/utils/sync/LocalIndexedDb.mjs b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/utils/sync/LocalIndexedDb.mjs -new file mode 100644 -index 0000000..bcc6ea0 ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/utils/sync/LocalIndexedDb.mjs -@@ -0,0 +1,246 @@ -+import { assert, getFromLocalStorage, noop, setInLocalStorage } from "@tldraw/utils"; -+import { deleteDB, openDB } from "idb"; -+const STORE_PREFIX = "TLDRAW_DOCUMENT_v2"; -+const LEGACY_ASSET_STORE_PREFIX = "TLDRAW_ASSET_STORE_v1"; -+const dbNameIndexKey = "TLDRAW_DB_NAME_INDEX_v2"; -+const Table = { -+ Records: "records", -+ Schema: "schema", -+ SessionState: "session_state", -+ Assets: "assets" -+}; -+async function openLocalDb(persistenceKey) { -+ const storeId = STORE_PREFIX + persistenceKey; -+ addDbName(storeId); -+ return await openDB(storeId, 4, { -+ upgrade(database) { -+ if (!database.objectStoreNames.contains(Table.Records)) { -+ database.createObjectStore(Table.Records); -+ } -+ if (!database.objectStoreNames.contains(Table.Schema)) { -+ database.createObjectStore(Table.Schema); -+ } -+ if (!database.objectStoreNames.contains(Table.SessionState)) { -+ database.createObjectStore(Table.SessionState); -+ } -+ if (!database.objectStoreNames.contains(Table.Assets)) { -+ database.createObjectStore(Table.Assets); -+ } -+ } -+ }); -+} -+async function migrateLegacyAssetDbIfNeeded(persistenceKey) { -+ const databases = window.indexedDB.databases ? (await window.indexedDB.databases()).map((db) => db.name) : getAllIndexDbNames(); -+ const oldStoreId = LEGACY_ASSET_STORE_PREFIX + persistenceKey; -+ const existing = databases.find((dbName) => dbName === oldStoreId); -+ if (!existing) return; -+ const oldAssetDb = await openDB(oldStoreId, 1, { -+ upgrade(database) { -+ if (!database.objectStoreNames.contains("assets")) { -+ database.createObjectStore("assets"); -+ } -+ } -+ }); -+ if (!oldAssetDb.objectStoreNames.contains("assets")) return; -+ const oldTx = oldAssetDb.transaction(["assets"], "readonly"); -+ const oldAssetStore = oldTx.objectStore("assets"); -+ const oldAssetsKeys = await oldAssetStore.getAllKeys(); -+ const oldAssets = await Promise.all( -+ oldAssetsKeys.map(async (key) => [key, await oldAssetStore.get(key)]) -+ ); -+ await oldTx.done; -+ const newDb = await openLocalDb(persistenceKey); -+ const newTx = newDb.transaction([Table.Assets], "readwrite"); -+ const newAssetTable = newTx.objectStore(Table.Assets); -+ for (const [key, value] of oldAssets) { -+ newAssetTable.put(value, key); -+ } -+ await newTx.done; -+ oldAssetDb.close(); -+ newDb.close(); -+ await deleteDB(oldStoreId); -+} -+class LocalIndexedDb { -+ getDbPromise; -+ isClosed = false; -+ pendingTransactionSet = /* @__PURE__ */ new Set(); -+ /** @internal */ -+ static connectedInstances = /* @__PURE__ */ new Set(); -+ constructor(persistenceKey) { -+ LocalIndexedDb.connectedInstances.add(this); -+ this.getDbPromise = (async () => { -+ await migrateLegacyAssetDbIfNeeded(persistenceKey); -+ return await openLocalDb(persistenceKey); -+ })(); -+ } -+ getDb() { -+ return this.getDbPromise; -+ } -+ /** -+ * Wait for any pending transactions to be completed. Useful for tests. -+ * -+ * @internal -+ */ -+ pending() { -+ return Promise.allSettled([this.getDbPromise, ...this.pendingTransactionSet]).then(noop); -+ } -+ async close() { -+ if (this.isClosed) return; -+ this.isClosed = true; -+ await this.pending(); -+ (await this.getDb()).close(); -+ LocalIndexedDb.connectedInstances.delete(this); -+ } -+ tx(mode, names, cb) { -+ const txPromise = (async () => { -+ assert(!this.isClosed, "db is closed"); -+ const db = await this.getDb(); -+ const tx = db.transaction(names, mode); -+ const done = tx.done.catch((e) => { -+ if (!this.isClosed) { -+ throw e; -+ } -+ }); -+ try { -+ return await cb(tx); -+ } finally { -+ if (!this.isClosed) { -+ await done; -+ } else { -+ tx.abort(); -+ } -+ } -+ })(); -+ this.pendingTransactionSet.add(txPromise); -+ txPromise.finally(() => this.pendingTransactionSet.delete(txPromise)); -+ return txPromise; -+ } -+ async load({ sessionId } = {}) { -+ return await this.tx( -+ "readonly", -+ [Table.Records, Table.Schema, Table.SessionState], -+ async (tx) => { -+ const recordsStore = tx.objectStore(Table.Records); -+ const schemaStore = tx.objectStore(Table.Schema); -+ const sessionStateStore = tx.objectStore(Table.SessionState); -+ let sessionStateSnapshot = sessionId ? (await sessionStateStore.get(sessionId))?.snapshot : null; -+ if (!sessionStateSnapshot) { -+ const all = await sessionStateStore.getAll(); -+ sessionStateSnapshot = all.sort((a, b) => a.updatedAt - b.updatedAt).pop()?.snapshot; -+ } -+ const result = { -+ records: await recordsStore.getAll(), -+ schema: await schemaStore.get(Table.Schema), -+ sessionStateSnapshot -+ }; -+ return result; -+ } -+ ); -+ } -+ async storeChanges({ -+ schema, -+ changes, -+ sessionId, -+ sessionStateSnapshot -+ }) { -+ await this.tx("readwrite", [Table.Records, Table.Schema, Table.SessionState], async (tx) => { -+ const recordsStore = tx.objectStore(Table.Records); -+ const schemaStore = tx.objectStore(Table.Schema); -+ const sessionStateStore = tx.objectStore(Table.SessionState); -+ for (const [id, record] of Object.entries(changes.added)) { -+ await recordsStore.put(record, id); -+ } -+ for (const [_prev, updated] of Object.values(changes.updated)) { -+ await recordsStore.put(updated, updated.id); -+ } -+ for (const id of Object.keys(changes.removed)) { -+ await recordsStore.delete(id); -+ } -+ schemaStore.put(schema.serialize(), Table.Schema); -+ if (sessionStateSnapshot && sessionId) { -+ sessionStateStore.put( -+ { -+ snapshot: sessionStateSnapshot, -+ updatedAt: Date.now(), -+ id: sessionId -+ }, -+ sessionId -+ ); -+ } else if (sessionStateSnapshot || sessionId) { -+ console.error("sessionStateSnapshot and instanceId must be provided together"); -+ } -+ }); -+ } -+ async storeSnapshot({ -+ schema, -+ snapshot, -+ sessionId, -+ sessionStateSnapshot -+ }) { -+ await this.tx("readwrite", [Table.Records, Table.Schema, Table.SessionState], async (tx) => { -+ const recordsStore = tx.objectStore(Table.Records); -+ const schemaStore = tx.objectStore(Table.Schema); -+ const sessionStateStore = tx.objectStore(Table.SessionState); -+ await recordsStore.clear(); -+ for (const [id, record] of Object.entries(snapshot)) { -+ await recordsStore.put(record, id); -+ } -+ schemaStore.put(schema.serialize(), Table.Schema); -+ if (sessionStateSnapshot && sessionId) { -+ sessionStateStore.put( -+ { -+ snapshot: sessionStateSnapshot, -+ updatedAt: Date.now(), -+ id: sessionId -+ }, -+ sessionId -+ ); -+ } else if (sessionStateSnapshot || sessionId) { -+ console.error("sessionStateSnapshot and instanceId must be provided together"); -+ } -+ }); -+ } -+ async pruneSessions() { -+ await this.tx("readwrite", [Table.SessionState], async (tx) => { -+ const sessionStateStore = tx.objectStore(Table.SessionState); -+ const all = (await sessionStateStore.getAll()).sort((a, b) => a.updatedAt - b.updatedAt); -+ if (all.length < 10) { -+ await tx.done; -+ return; -+ } -+ const toDelete = all.slice(0, all.length - 10); -+ for (const { id } of toDelete) { -+ await sessionStateStore.delete(id); -+ } -+ }); -+ } -+ async getAsset(assetId) { -+ return await this.tx("readonly", [Table.Assets], async (tx) => { -+ const assetsStore = tx.objectStore(Table.Assets); -+ return await assetsStore.get(assetId); -+ }); -+ } -+ async storeAsset(assetId, blob) { -+ await this.tx("readwrite", [Table.Assets], async (tx) => { -+ const assetsStore = tx.objectStore(Table.Assets); -+ await assetsStore.put(blob, assetId); -+ }); -+ } -+} -+function getAllIndexDbNames() { -+ const result = JSON.parse(getFromLocalStorage(dbNameIndexKey) || "[]") ?? []; -+ if (!Array.isArray(result)) { -+ return []; -+ } -+ return result; -+} -+function addDbName(name) { -+ const all = new Set(getAllIndexDbNames()); -+ all.add(name); -+ setInLocalStorage(dbNameIndexKey, JSON.stringify([...all])); -+} -+export { -+ LocalIndexedDb, -+ getAllIndexDbNames -+}; -+//# sourceMappingURL=LocalIndexedDb.mjs.map -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/utils/sync/LocalIndexedDb.mjs.map b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/utils/sync/LocalIndexedDb.mjs.map -new file mode 100644 -index 0000000..6a735aa ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/utils/sync/LocalIndexedDb.mjs.map -@@ -0,0 +1,7 @@ -+{ -+ "version": 3, -+ "sources": ["../../../../src/lib/utils/sync/LocalIndexedDb.ts"], -+ "sourcesContent": ["import { RecordsDiff, SerializedSchema, SerializedStore } from '@tldraw/store'\nimport { TLRecord, TLStoreSchema } from '@tldraw/tlschema'\nimport { assert, getFromLocalStorage, noop, setInLocalStorage } from '@tldraw/utils'\nimport { IDBPDatabase, IDBPTransaction, deleteDB, openDB } from 'idb'\nimport { TLSessionStateSnapshot } from '../../config/TLSessionStateSnapshot'\n\n// DO NOT CHANGE THESE WITHOUT ADDING MIGRATION LOGIC. DOING SO WOULD WIPE ALL EXISTING DATA.\nconst STORE_PREFIX = 'TLDRAW_DOCUMENT_v2'\nconst LEGACY_ASSET_STORE_PREFIX = 'TLDRAW_ASSET_STORE_v1'\nconst dbNameIndexKey = 'TLDRAW_DB_NAME_INDEX_v2'\n\nconst Table = {\n\tRecords: 'records',\n\tSchema: 'schema',\n\tSessionState: 'session_state',\n\tAssets: 'assets',\n} as const\n\ntype StoreName = (typeof Table)[keyof typeof Table]\n\nasync function openLocalDb(persistenceKey: string) {\n\tconst storeId = STORE_PREFIX + persistenceKey\n\n\taddDbName(storeId)\n\n\treturn await openDB(storeId, 4, {\n\t\tupgrade(database) {\n\t\t\tif (!database.objectStoreNames.contains(Table.Records)) {\n\t\t\t\tdatabase.createObjectStore(Table.Records)\n\t\t\t}\n\t\t\tif (!database.objectStoreNames.contains(Table.Schema)) {\n\t\t\t\tdatabase.createObjectStore(Table.Schema)\n\t\t\t}\n\t\t\tif (!database.objectStoreNames.contains(Table.SessionState)) {\n\t\t\t\tdatabase.createObjectStore(Table.SessionState)\n\t\t\t}\n\t\t\tif (!database.objectStoreNames.contains(Table.Assets)) {\n\t\t\t\tdatabase.createObjectStore(Table.Assets)\n\t\t\t}\n\t\t},\n\t})\n}\n\nasync function migrateLegacyAssetDbIfNeeded(persistenceKey: string) {\n\tconst databases = window.indexedDB.databases\n\t\t? (await window.indexedDB.databases()).map((db) => db.name)\n\t\t: getAllIndexDbNames()\n\tconst oldStoreId = LEGACY_ASSET_STORE_PREFIX + persistenceKey\n\tconst existing = databases.find((dbName) => dbName === oldStoreId)\n\tif (!existing) return\n\n\tconst oldAssetDb = await openDB(oldStoreId, 1, {\n\t\tupgrade(database) {\n\t\t\tif (!database.objectStoreNames.contains('assets')) {\n\t\t\t\tdatabase.createObjectStore('assets')\n\t\t\t}\n\t\t},\n\t})\n\tif (!oldAssetDb.objectStoreNames.contains('assets')) return\n\n\tconst oldTx = oldAssetDb.transaction(['assets'], 'readonly')\n\tconst oldAssetStore = oldTx.objectStore('assets')\n\tconst oldAssetsKeys = await oldAssetStore.getAllKeys()\n\tconst oldAssets = await Promise.all(\n\t\toldAssetsKeys.map(async (key) => [key, await oldAssetStore.get(key)] as const)\n\t)\n\tawait oldTx.done\n\n\tconst newDb = await openLocalDb(persistenceKey)\n\tconst newTx = newDb.transaction([Table.Assets], 'readwrite')\n\tconst newAssetTable = newTx.objectStore(Table.Assets)\n\tfor (const [key, value] of oldAssets) {\n\t\tnewAssetTable.put(value, key)\n\t}\n\tawait newTx.done\n\n\toldAssetDb.close()\n\tnewDb.close()\n\n\tawait deleteDB(oldStoreId)\n}\n\ninterface LoadResult {\n\trecords: TLRecord[]\n\tschema?: SerializedSchema\n\tsessionStateSnapshot?: TLSessionStateSnapshot | null\n}\n\ninterface SessionStateSnapshotRow {\n\tid: string\n\tsnapshot: TLSessionStateSnapshot\n\tupdatedAt: number\n}\n\n/** @internal */\nexport class LocalIndexedDb {\n\tprivate getDbPromise: Promise>\n\tprivate isClosed = false\n\tprivate pendingTransactionSet = new Set>()\n\n\t/** @internal */\n\tstatic connectedInstances = new Set()\n\n\tconstructor(persistenceKey: string) {\n\t\tLocalIndexedDb.connectedInstances.add(this)\n\t\tthis.getDbPromise = (async () => {\n\t\t\tawait migrateLegacyAssetDbIfNeeded(persistenceKey)\n\t\t\treturn await openLocalDb(persistenceKey)\n\t\t})()\n\t}\n\n\tgetDb() {\n\t\treturn this.getDbPromise\n\t}\n\n\t/**\n\t * Wait for any pending transactions to be completed. Useful for tests.\n\t *\n\t * @internal\n\t */\n\tpending(): Promise {\n\t\treturn Promise.allSettled([this.getDbPromise, ...this.pendingTransactionSet]).then(noop)\n\t}\n\n\tasync close() {\n\t\tif (this.isClosed) return\n\t\tthis.isClosed = true\n\t\tawait this.pending()\n\t\t;(await this.getDb()).close()\n\t\tLocalIndexedDb.connectedInstances.delete(this)\n\t}\n\n\tprivate tx(\n\t\tmode: Mode,\n\t\tnames: Names,\n\t\tcb: (tx: IDBPTransaction) => Promise\n\t): Promise {\n\t\tconst txPromise = (async () => {\n\t\t\tassert(!this.isClosed, 'db is closed')\n\t\t\tconst db = await this.getDb()\n\t\t\tconst tx = db.transaction(names, mode)\n\t\t\t// need to add a catch here early to prevent unhandled promise rejection\n\t\t\t// during react-strict-mode where this tx.done promise can be rejected\n\t\t\t// before we have a chance to await on it\n\t\t\tconst done = tx.done.catch((e: unknown) => {\n\t\t\t\tif (!this.isClosed) {\n\t\t\t\t\tthrow e\n\t\t\t\t}\n\t\t\t})\n\t\t\ttry {\n\t\t\t\treturn await cb(tx)\n\t\t\t} finally {\n\t\t\t\tif (!this.isClosed) {\n\t\t\t\t\tawait done\n\t\t\t\t} else {\n\t\t\t\t\ttx.abort()\n\t\t\t\t}\n\t\t\t}\n\t\t})()\n\t\tthis.pendingTransactionSet.add(txPromise)\n\t\ttxPromise.finally(() => this.pendingTransactionSet.delete(txPromise))\n\t\treturn txPromise\n\t}\n\n\tasync load({ sessionId }: { sessionId?: string } = {}) {\n\t\treturn await this.tx(\n\t\t\t'readonly',\n\t\t\t[Table.Records, Table.Schema, Table.SessionState],\n\t\t\tasync (tx) => {\n\t\t\t\tconst recordsStore = tx.objectStore(Table.Records)\n\t\t\t\tconst schemaStore = tx.objectStore(Table.Schema)\n\t\t\t\tconst sessionStateStore = tx.objectStore(Table.SessionState)\n\t\t\t\tlet sessionStateSnapshot = sessionId\n\t\t\t\t\t? ((await sessionStateStore.get(sessionId)) as SessionStateSnapshotRow | undefined)\n\t\t\t\t\t\t\t?.snapshot\n\t\t\t\t\t: null\n\t\t\t\tif (!sessionStateSnapshot) {\n\t\t\t\t\t// get the most recent session state\n\t\t\t\t\tconst all = (await sessionStateStore.getAll()) as SessionStateSnapshotRow[]\n\t\t\t\t\tsessionStateSnapshot = all.sort((a, b) => a.updatedAt - b.updatedAt).pop()?.snapshot\n\t\t\t\t}\n\t\t\t\tconst result = {\n\t\t\t\t\trecords: await recordsStore.getAll(),\n\t\t\t\t\tschema: await schemaStore.get(Table.Schema),\n\t\t\t\t\tsessionStateSnapshot,\n\t\t\t\t} satisfies LoadResult\n\n\t\t\t\treturn result\n\t\t\t}\n\t\t)\n\t}\n\n\tasync storeChanges({\n\t\tschema,\n\t\tchanges,\n\t\tsessionId,\n\t\tsessionStateSnapshot,\n\t}: {\n\t\tschema: TLStoreSchema\n\t\tchanges: RecordsDiff\n\t\tsessionId?: string | null\n\t\tsessionStateSnapshot?: TLSessionStateSnapshot | null\n\t}) {\n\t\tawait this.tx('readwrite', [Table.Records, Table.Schema, Table.SessionState], async (tx) => {\n\t\t\tconst recordsStore = tx.objectStore(Table.Records)\n\t\t\tconst schemaStore = tx.objectStore(Table.Schema)\n\t\t\tconst sessionStateStore = tx.objectStore(Table.SessionState)\n\n\t\t\tfor (const [id, record] of Object.entries(changes.added)) {\n\t\t\t\tawait recordsStore.put(record, id)\n\t\t\t}\n\n\t\t\tfor (const [_prev, updated] of Object.values(changes.updated)) {\n\t\t\t\tawait recordsStore.put(updated, updated.id)\n\t\t\t}\n\n\t\t\tfor (const id of Object.keys(changes.removed)) {\n\t\t\t\tawait recordsStore.delete(id)\n\t\t\t}\n\n\t\t\tschemaStore.put(schema.serialize(), Table.Schema)\n\t\t\tif (sessionStateSnapshot && sessionId) {\n\t\t\t\tsessionStateStore.put(\n\t\t\t\t\t{\n\t\t\t\t\t\tsnapshot: sessionStateSnapshot,\n\t\t\t\t\t\tupdatedAt: Date.now(),\n\t\t\t\t\t\tid: sessionId,\n\t\t\t\t\t} satisfies SessionStateSnapshotRow,\n\t\t\t\t\tsessionId\n\t\t\t\t)\n\t\t\t} else if (sessionStateSnapshot || sessionId) {\n\t\t\t\tconsole.error('sessionStateSnapshot and instanceId must be provided together')\n\t\t\t}\n\t\t})\n\t}\n\n\tasync storeSnapshot({\n\t\tschema,\n\t\tsnapshot,\n\t\tsessionId,\n\t\tsessionStateSnapshot,\n\t}: {\n\t\tschema: TLStoreSchema\n\t\tsnapshot: SerializedStore\n\t\tsessionId?: string | null\n\t\tsessionStateSnapshot?: TLSessionStateSnapshot | null\n\t}) {\n\t\tawait this.tx('readwrite', [Table.Records, Table.Schema, Table.SessionState], async (tx) => {\n\t\t\tconst recordsStore = tx.objectStore(Table.Records)\n\t\t\tconst schemaStore = tx.objectStore(Table.Schema)\n\t\t\tconst sessionStateStore = tx.objectStore(Table.SessionState)\n\n\t\t\tawait recordsStore.clear()\n\n\t\t\tfor (const [id, record] of Object.entries(snapshot)) {\n\t\t\t\tawait recordsStore.put(record, id)\n\t\t\t}\n\n\t\t\tschemaStore.put(schema.serialize(), Table.Schema)\n\n\t\t\tif (sessionStateSnapshot && sessionId) {\n\t\t\t\tsessionStateStore.put(\n\t\t\t\t\t{\n\t\t\t\t\t\tsnapshot: sessionStateSnapshot,\n\t\t\t\t\t\tupdatedAt: Date.now(),\n\t\t\t\t\t\tid: sessionId,\n\t\t\t\t\t} satisfies SessionStateSnapshotRow,\n\t\t\t\t\tsessionId\n\t\t\t\t)\n\t\t\t} else if (sessionStateSnapshot || sessionId) {\n\t\t\t\tconsole.error('sessionStateSnapshot and instanceId must be provided together')\n\t\t\t}\n\t\t})\n\t}\n\n\tasync pruneSessions() {\n\t\tawait this.tx('readwrite', [Table.SessionState], async (tx) => {\n\t\t\tconst sessionStateStore = tx.objectStore(Table.SessionState)\n\t\t\tconst all = (await sessionStateStore.getAll()).sort((a, b) => a.updatedAt - b.updatedAt)\n\t\t\tif (all.length < 10) {\n\t\t\t\tawait tx.done\n\t\t\t\treturn\n\t\t\t}\n\t\t\tconst toDelete = all.slice(0, all.length - 10)\n\t\t\tfor (const { id } of toDelete) {\n\t\t\t\tawait sessionStateStore.delete(id)\n\t\t\t}\n\t\t})\n\t}\n\n\tasync getAsset(assetId: string): Promise {\n\t\treturn await this.tx('readonly', [Table.Assets], async (tx) => {\n\t\t\tconst assetsStore = tx.objectStore(Table.Assets)\n\t\t\treturn await assetsStore.get(assetId)\n\t\t})\n\t}\n\n\tasync storeAsset(assetId: string, blob: Blob) {\n\t\tawait this.tx('readwrite', [Table.Assets], async (tx) => {\n\t\t\tconst assetsStore = tx.objectStore(Table.Assets)\n\t\t\tawait assetsStore.put(blob, assetId)\n\t\t})\n\t}\n}\n\n/** @internal */\nexport function getAllIndexDbNames(): string[] {\n\tconst result = JSON.parse(getFromLocalStorage(dbNameIndexKey) || '[]') ?? []\n\tif (!Array.isArray(result)) {\n\t\treturn []\n\t}\n\treturn result\n}\n\nfunction addDbName(name: string) {\n\tconst all = new Set(getAllIndexDbNames())\n\tall.add(name)\n\tsetInLocalStorage(dbNameIndexKey, JSON.stringify([...all]))\n}\n"], -+ "mappings": "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", -+ "names": [] -+} -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/utils/sync/StoreWithStatus.mjs b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/utils/sync/StoreWithStatus.mjs -new file mode 100644 -index 0000000..9feab39 ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/utils/sync/StoreWithStatus.mjs -@@ -0,0 +1 @@ -+//# sourceMappingURL=StoreWithStatus.mjs.map -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/utils/sync/StoreWithStatus.mjs.map b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/utils/sync/StoreWithStatus.mjs.map -new file mode 100644 -index 0000000..9865211 ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/utils/sync/StoreWithStatus.mjs.map -@@ -0,0 +1,7 @@ -+{ -+ "version": 3, -+ "sources": [], -+ "sourcesContent": [], -+ "mappings": "", -+ "names": [] -+} -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/utils/sync/TLLocalSyncClient.mjs b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/utils/sync/TLLocalSyncClient.mjs -new file mode 100644 -index 0000000..2815ced ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/utils/sync/TLLocalSyncClient.mjs -@@ -0,0 +1,282 @@ -+import { transact } from "@tldraw/state"; -+import { squashRecordDiffs } from "@tldraw/store"; -+import { assert } from "@tldraw/utils"; -+import { -+ TAB_ID, -+ createSessionStateSnapshotSignal, -+ extractSessionStateFromLegacySnapshot, -+ loadSessionStateSnapshotIntoStore -+} from "../../config/TLSessionStateSnapshot.mjs"; -+import { LocalIndexedDb } from "./LocalIndexedDb.mjs"; -+import { showCantReadFromIndexDbAlert, showCantWriteToIndexDbAlert } from "./alerts.mjs"; -+const PERSIST_THROTTLE_MS = 350; -+const PERSIST_RETRY_THROTTLE_MS = 1e4; -+const UPDATE_INSTANCE_STATE = Symbol("UPDATE_INSTANCE_STATE"); -+const msg = (msg2) => msg2; -+class BroadcastChannelMock { -+ onmessage; -+ constructor(_name) { -+ } -+ postMessage(_msg) { -+ } -+ close() { -+ } -+} -+const BC = typeof BroadcastChannel === "undefined" ? BroadcastChannelMock : BroadcastChannel; -+class TLLocalSyncClient { -+ constructor(store, { -+ persistenceKey, -+ sessionId = TAB_ID, -+ onLoad, -+ onLoadError -+ }, channel = new BC(`tldraw-tab-sync-${persistenceKey}`)) { -+ this.store = store; -+ this.channel = channel; -+ if (typeof window !== "undefined") { -+ ; -+ window.tlsync = this; -+ } -+ this.persistenceKey = persistenceKey; -+ this.sessionId = sessionId; -+ this.db = new LocalIndexedDb(persistenceKey); -+ this.disposables.add(() => this.db.close()); -+ this.serializedSchema = this.store.schema.serialize(); -+ this.$sessionStateSnapshot = createSessionStateSnapshotSignal(this.store); -+ this.disposables.add( -+ // Set up a subscription to changes from the store: When -+ // the store changes (and if the change was made by the user) -+ // then immediately send the diff to other tabs via postMessage -+ // and schedule a persist. -+ store.listen( -+ ({ changes }) => { -+ this.diffQueue.push(changes); -+ this.channel.postMessage( -+ msg({ -+ type: "diff", -+ storeId: this.store.id, -+ changes, -+ schema: this.serializedSchema -+ }) -+ ); -+ this.schedulePersist(); -+ }, -+ { source: "user", scope: "document" } -+ ) -+ ); -+ this.disposables.add( -+ store.listen( -+ () => { -+ this.diffQueue.push(UPDATE_INSTANCE_STATE); -+ this.schedulePersist(); -+ }, -+ { scope: "session" } -+ ) -+ ); -+ this.connect(onLoad, onLoadError); -+ this.documentTypes = new Set( -+ Object.values(this.store.schema.types).filter((t) => t.scope === "document").map((t) => t.typeName) -+ ); -+ } -+ disposables = /* @__PURE__ */ new Set(); -+ diffQueue = []; -+ didDispose = false; -+ shouldDoFullDBWrite = true; -+ isReloading = false; -+ persistenceKey; -+ sessionId; -+ serializedSchema; -+ isDebugging = false; -+ documentTypes; -+ $sessionStateSnapshot; -+ /** @internal */ -+ db; -+ initTime = Date.now(); -+ debug(...args) { -+ if (this.isDebugging) { -+ console.debug(...args); -+ } -+ } -+ async connect(onLoad, onLoadError) { -+ this.debug("connecting"); -+ let data; -+ try { -+ data = await this.db.load({ sessionId: this.sessionId }); -+ } catch (error) { -+ onLoadError(error); -+ showCantReadFromIndexDbAlert(); -+ return; -+ } -+ this.debug("loaded data from store", data, "didDispose", this.didDispose); -+ if (this.didDispose) return; -+ try { -+ if (data) { -+ const documentSnapshot = Object.fromEntries(data.records.map((r) => [r.id, r])); -+ const sessionStateSnapshot = data.sessionStateSnapshot ?? extractSessionStateFromLegacySnapshot(documentSnapshot); -+ const migrationResult = this.store.schema.migrateStoreSnapshot({ -+ store: documentSnapshot, -+ // eslint-disable-next-line deprecation/deprecation -+ schema: data.schema ?? this.store.schema.serializeEarliestVersion() -+ }); -+ if (migrationResult.type === "error") { -+ console.error("failed to migrate store", migrationResult); -+ onLoadError(new Error(`Failed to migrate store: ${migrationResult.reason}`)); -+ return; -+ } -+ this.store.mergeRemoteChanges(() => { -+ this.store.put( -+ Object.values(migrationResult.value).filter((r) => this.documentTypes.has(r.typeName)), -+ "initialize" -+ ); -+ }); -+ if (sessionStateSnapshot) { -+ loadSessionStateSnapshotIntoStore(this.store, sessionStateSnapshot); -+ } -+ } -+ this.channel.onmessage = ({ data: data2 }) => { -+ this.debug("got message", data2); -+ const msg2 = data2; -+ const res = this.store.schema.getMigrationsSince(msg2.schema); -+ if (!res.ok) { -+ const timeSinceInit = Date.now() - this.initTime; -+ if (timeSinceInit < 5e3) { -+ onLoadError(new Error("Schema mismatch, please close other tabs and reload the page")); -+ return; -+ } -+ this.debug("reloading"); -+ this.isReloading = true; -+ window?.location?.reload?.(); -+ return; -+ } else if (res.value.length > 0) { -+ this.debug("telling them to reload"); -+ this.channel.postMessage({ type: "announce", schema: this.serializedSchema }); -+ this.shouldDoFullDBWrite = true; -+ this.persistIfNeeded(); -+ return; -+ } -+ if (msg2.type === "diff") { -+ this.debug("applying diff"); -+ transact(() => { -+ this.store.mergeRemoteChanges(() => { -+ this.store.applyDiff(msg2.changes); -+ this.store.ensureStoreIsUsable(); -+ }); -+ }); -+ } -+ }; -+ this.channel.postMessage({ type: "announce", schema: this.serializedSchema }); -+ this.disposables.add(() => { -+ this.channel.close(); -+ }); -+ onLoad(this); -+ } catch (e) { -+ this.debug("error loading data from store", e); -+ if (this.didDispose) return; -+ onLoadError(e); -+ return; -+ } -+ } -+ close() { -+ this.debug("closing"); -+ this.didDispose = true; -+ this.disposables.forEach((d) => d()); -+ } -+ isPersisting = false; -+ didLastWriteError = false; -+ // eslint-disable-next-line no-restricted-globals -+ scheduledPersistTimeout = null; -+ /** -+ * Schedule a persist. Persists don't happen immediately: they are throttled to avoid writing too -+ * often, and will retry if failed. -+ * -+ * @internal -+ */ -+ schedulePersist() { -+ this.debug("schedulePersist", this.scheduledPersistTimeout); -+ if (this.scheduledPersistTimeout) return; -+ this.scheduledPersistTimeout = setTimeout( -+ () => { -+ this.scheduledPersistTimeout = null; -+ this.persistIfNeeded(); -+ }, -+ this.didLastWriteError ? PERSIST_RETRY_THROTTLE_MS : PERSIST_THROTTLE_MS -+ ); -+ } -+ /** -+ * Persist to IndexedDB only under certain circumstances: -+ * -+ * - If we're not already persisting -+ * - If we're not reloading the page -+ * - And we have something to persist (a full db write scheduled or changes in the diff queue) -+ * -+ * @internal -+ */ -+ persistIfNeeded() { -+ this.debug("persistIfNeeded", { -+ isPersisting: this.isPersisting, -+ isReloading: this.isReloading, -+ shouldDoFullDBWrite: this.shouldDoFullDBWrite, -+ diffQueueLength: this.diffQueue.length, -+ storeIsPossiblyCorrupt: this.store.isPossiblyCorrupted() -+ }); -+ if (this.scheduledPersistTimeout) { -+ clearTimeout(this.scheduledPersistTimeout); -+ this.scheduledPersistTimeout = null; -+ } -+ if (this.isPersisting) return; -+ if (this.isReloading) return; -+ if (this.store.isPossiblyCorrupted()) return; -+ if (this.shouldDoFullDBWrite || this.diffQueue.length > 0) { -+ this.doPersist(); -+ } -+ } -+ /** -+ * Actually persist to IndexedDB. If the write fails, then we'll retry with a full db write after -+ * a short delay. -+ */ -+ async doPersist() { -+ assert(!this.isPersisting, "persist already in progress"); -+ if (this.didDispose) return; -+ this.isPersisting = true; -+ this.debug("doPersist start"); -+ const diffQueue = this.diffQueue; -+ this.diffQueue = []; -+ try { -+ if (this.shouldDoFullDBWrite) { -+ this.shouldDoFullDBWrite = false; -+ await this.db.storeSnapshot({ -+ schema: this.store.schema, -+ snapshot: this.store.serialize(), -+ sessionId: this.sessionId, -+ sessionStateSnapshot: this.$sessionStateSnapshot.get() -+ }); -+ } else { -+ const diffs = squashRecordDiffs( -+ diffQueue.filter((d) => d !== UPDATE_INSTANCE_STATE) -+ ); -+ await this.db.storeChanges({ -+ changes: diffs, -+ schema: this.store.schema, -+ sessionId: this.sessionId, -+ sessionStateSnapshot: this.$sessionStateSnapshot.get() -+ }); -+ } -+ this.didLastWriteError = false; -+ } catch (e) { -+ this.shouldDoFullDBWrite = true; -+ this.didLastWriteError = true; -+ console.error("failed to store changes in indexed db", e); -+ showCantWriteToIndexDbAlert(); -+ if (typeof window !== "undefined") { -+ window.location.reload(); -+ } -+ } -+ this.isPersisting = false; -+ this.debug("doPersist end"); -+ this.schedulePersist(); -+ } -+} -+export { -+ BroadcastChannelMock, -+ TLLocalSyncClient -+}; -+//# sourceMappingURL=TLLocalSyncClient.mjs.map -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/utils/sync/TLLocalSyncClient.mjs.map b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/utils/sync/TLLocalSyncClient.mjs.map -new file mode 100644 -index 0000000..9eabf0f ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/utils/sync/TLLocalSyncClient.mjs.map -@@ -0,0 +1,7 @@ -+{ -+ "version": 3, -+ "sources": ["../../../../src/lib/utils/sync/TLLocalSyncClient.ts"], -+ "sourcesContent": ["import { Signal, transact } from '@tldraw/state'\nimport { RecordsDiff, SerializedSchema, UnknownRecord, squashRecordDiffs } from '@tldraw/store'\nimport { TLStore } from '@tldraw/tlschema'\nimport { assert } from '@tldraw/utils'\nimport {\n\tTAB_ID,\n\tTLSessionStateSnapshot,\n\tcreateSessionStateSnapshotSignal,\n\textractSessionStateFromLegacySnapshot,\n\tloadSessionStateSnapshotIntoStore,\n} from '../../config/TLSessionStateSnapshot'\nimport { LocalIndexedDb } from './LocalIndexedDb'\nimport { showCantReadFromIndexDbAlert, showCantWriteToIndexDbAlert } from './alerts'\n\n/** How should we debounce persists? */\nconst PERSIST_THROTTLE_MS = 350\n/** If we're in an error state, how long should we wait before retrying a write? */\nconst PERSIST_RETRY_THROTTLE_MS = 10_000\n\nconst UPDATE_INSTANCE_STATE = Symbol('UPDATE_INSTANCE_STATE')\n\n/**\n * IMPORTANT!!!\n *\n * This is just a quick-n-dirty temporary solution that will be replaced with the remote sync client\n * once it has the db integrated\n */\n\ninterface SyncMessage {\n\ttype: 'diff'\n\tstoreId: string\n\tchanges: RecordsDiff\n\tschema: SerializedSchema\n}\n\n// Sent by new clients when they connect\n// If another client is on the channel with a newer schema version\n// It will\ninterface AnnounceMessage {\n\ttype: 'announce'\n\tschema: SerializedSchema\n}\n\ntype Message = SyncMessage | AnnounceMessage\n\ntype UnpackPromise = T extends Promise ? U : T\n\nconst msg = (msg: Message) => msg\n\n/** @internal */\nexport class BroadcastChannelMock {\n\tonmessage?: (e: MessageEvent) => void\n\tconstructor(_name: string) {\n\t\t// noop\n\t}\n\tpostMessage(_msg: Message) {\n\t\t// noop\n\t}\n\tclose() {\n\t\t// noop\n\t}\n}\n\nconst BC = typeof BroadcastChannel === 'undefined' ? BroadcastChannelMock : BroadcastChannel\n\n/** @internal */\nexport class TLLocalSyncClient {\n\tprivate disposables = new Set<() => void>()\n\tprivate diffQueue: Array | typeof UPDATE_INSTANCE_STATE> = []\n\tprivate didDispose = false\n\tprivate shouldDoFullDBWrite = true\n\tprivate isReloading = false\n\treadonly persistenceKey: string\n\treadonly sessionId: string\n\treadonly serializedSchema: SerializedSchema\n\tprivate isDebugging = false\n\tprivate readonly documentTypes: ReadonlySet\n\tprivate readonly $sessionStateSnapshot: Signal\n\t/** @internal */\n\treadonly db: LocalIndexedDb\n\n\tinitTime = Date.now()\n\tprivate debug(...args: any[]) {\n\t\tif (this.isDebugging) {\n\t\t\t// eslint-disable-next-line no-console\n\t\t\tconsole.debug(...args)\n\t\t}\n\t}\n\tconstructor(\n\t\tpublic readonly store: TLStore,\n\t\t{\n\t\t\tpersistenceKey,\n\t\t\tsessionId = TAB_ID,\n\t\t\tonLoad,\n\t\t\tonLoadError,\n\t\t}: {\n\t\t\tpersistenceKey: string\n\t\t\tsessionId?: string\n\t\t\tonLoad(self: TLLocalSyncClient): void\n\t\t\tonLoadError(error: Error): void\n\t\t},\n\t\tpublic readonly channel = new BC(`tldraw-tab-sync-${persistenceKey}`)\n\t) {\n\t\tif (typeof window !== 'undefined') {\n\t\t\t;(window as any).tlsync = this\n\t\t}\n\t\tthis.persistenceKey = persistenceKey\n\t\tthis.sessionId = sessionId\n\t\tthis.db = new LocalIndexedDb(persistenceKey)\n\t\tthis.disposables.add(() => this.db.close())\n\n\t\tthis.serializedSchema = this.store.schema.serialize()\n\t\tthis.$sessionStateSnapshot = createSessionStateSnapshotSignal(this.store)\n\n\t\tthis.disposables.add(\n\t\t\t// Set up a subscription to changes from the store: When\n\t\t\t// the store changes (and if the change was made by the user)\n\t\t\t// then immediately send the diff to other tabs via postMessage\n\t\t\t// and schedule a persist.\n\t\t\tstore.listen(\n\t\t\t\t({ changes }) => {\n\t\t\t\t\tthis.diffQueue.push(changes)\n\t\t\t\t\tthis.channel.postMessage(\n\t\t\t\t\t\tmsg({\n\t\t\t\t\t\t\ttype: 'diff',\n\t\t\t\t\t\t\tstoreId: this.store.id,\n\t\t\t\t\t\t\tchanges,\n\t\t\t\t\t\t\tschema: this.serializedSchema,\n\t\t\t\t\t\t})\n\t\t\t\t\t)\n\t\t\t\t\tthis.schedulePersist()\n\t\t\t\t},\n\t\t\t\t{ source: 'user', scope: 'document' }\n\t\t\t)\n\t\t)\n\t\tthis.disposables.add(\n\t\t\tstore.listen(\n\t\t\t\t() => {\n\t\t\t\t\tthis.diffQueue.push(UPDATE_INSTANCE_STATE)\n\t\t\t\t\tthis.schedulePersist()\n\t\t\t\t},\n\t\t\t\t{ scope: 'session' }\n\t\t\t)\n\t\t)\n\n\t\tthis.connect(onLoad, onLoadError)\n\n\t\tthis.documentTypes = new Set(\n\t\t\tObject.values(this.store.schema.types)\n\t\t\t\t.filter((t) => t.scope === 'document')\n\t\t\t\t.map((t) => t.typeName)\n\t\t)\n\t}\n\n\tprivate async connect(onLoad: (client: this) => void, onLoadError: (error: Error) => void) {\n\t\tthis.debug('connecting')\n\t\tlet data: UnpackPromise> | undefined\n\n\t\ttry {\n\t\t\tdata = await this.db.load({ sessionId: this.sessionId })\n\t\t} catch (error: any) {\n\t\t\tonLoadError(error)\n\t\t\tshowCantReadFromIndexDbAlert()\n\t\t\treturn\n\t\t}\n\n\t\tthis.debug('loaded data from store', data, 'didDispose', this.didDispose)\n\t\tif (this.didDispose) return\n\n\t\ttry {\n\t\t\tif (data) {\n\t\t\t\tconst documentSnapshot = Object.fromEntries(data.records.map((r) => [r.id, r]))\n\t\t\t\tconst sessionStateSnapshot =\n\t\t\t\t\tdata.sessionStateSnapshot ?? extractSessionStateFromLegacySnapshot(documentSnapshot)\n\t\t\t\tconst migrationResult = this.store.schema.migrateStoreSnapshot({\n\t\t\t\t\tstore: documentSnapshot,\n\t\t\t\t\t// eslint-disable-next-line deprecation/deprecation\n\t\t\t\t\tschema: data.schema ?? this.store.schema.serializeEarliestVersion(),\n\t\t\t\t})\n\n\t\t\t\tif (migrationResult.type === 'error') {\n\t\t\t\t\tconsole.error('failed to migrate store', migrationResult)\n\t\t\t\t\tonLoadError(new Error(`Failed to migrate store: ${migrationResult.reason}`))\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\t// 3. Merge the changes into the REAL STORE\n\t\t\t\tthis.store.mergeRemoteChanges(() => {\n\t\t\t\t\t// Calling put will validate the records!\n\t\t\t\t\tthis.store.put(\n\t\t\t\t\t\tObject.values(migrationResult.value).filter((r) => this.documentTypes.has(r.typeName)),\n\t\t\t\t\t\t'initialize'\n\t\t\t\t\t)\n\t\t\t\t})\n\n\t\t\t\tif (sessionStateSnapshot) {\n\t\t\t\t\tloadSessionStateSnapshotIntoStore(this.store, sessionStateSnapshot)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tthis.channel.onmessage = ({ data }) => {\n\t\t\t\tthis.debug('got message', data)\n\t\t\t\tconst msg = data as Message\n\t\t\t\t// if their schema is earlier than ours, we need to tell them so they can refresh\n\t\t\t\t// if their schema is later than ours, we need to refresh\n\t\t\t\tconst res = this.store.schema.getMigrationsSince(msg.schema)\n\n\t\t\t\tif (!res.ok) {\n\t\t\t\t\t// we are older, refresh\n\t\t\t\t\t// but add a safety check to make sure we don't get in an infinite loop\n\t\t\t\t\tconst timeSinceInit = Date.now() - this.initTime\n\t\t\t\t\tif (timeSinceInit < 5000) {\n\t\t\t\t\t\t// This tab was just reloaded, but is out of date compared to other tabs.\n\t\t\t\t\t\t// Not expecting this to ever happen. It should only happen if we roll back a release that incremented\n\t\t\t\t\t\t// the schema version (which we should never do)\n\t\t\t\t\t\t// Or maybe during development if you have multiple local tabs open running the app on prod mode and you\n\t\t\t\t\t\t// check out an older commit. Dev server should be fine.\n\t\t\t\t\t\tonLoadError(new Error('Schema mismatch, please close other tabs and reload the page'))\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t\tthis.debug('reloading')\n\t\t\t\t\tthis.isReloading = true\n\t\t\t\t\twindow?.location?.reload?.()\n\t\t\t\t\treturn\n\t\t\t\t} else if (res.value.length > 0) {\n\t\t\t\t\t// they are older, tell them to refresh and not write any more data\n\t\t\t\t\tthis.debug('telling them to reload')\n\t\t\t\t\tthis.channel.postMessage({ type: 'announce', schema: this.serializedSchema })\n\t\t\t\t\t// schedule a full db write in case they wrote data anyway\n\t\t\t\t\tthis.shouldDoFullDBWrite = true\n\t\t\t\t\tthis.persistIfNeeded()\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\t// otherwise, all good, same version :)\n\t\t\t\tif (msg.type === 'diff') {\n\t\t\t\t\tthis.debug('applying diff')\n\t\t\t\t\ttransact(() => {\n\t\t\t\t\t\tthis.store.mergeRemoteChanges(() => {\n\t\t\t\t\t\t\tthis.store.applyDiff(msg.changes as any)\n\t\t\t\t\t\t\tthis.store.ensureStoreIsUsable()\n\t\t\t\t\t\t})\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis.channel.postMessage({ type: 'announce', schema: this.serializedSchema })\n\t\t\tthis.disposables.add(() => {\n\t\t\t\tthis.channel.close()\n\t\t\t})\n\t\t\tonLoad(this)\n\t\t} catch (e: any) {\n\t\t\tthis.debug('error loading data from store', e)\n\t\t\tif (this.didDispose) return\n\t\t\tonLoadError(e)\n\t\t\treturn\n\t\t}\n\t}\n\n\tclose() {\n\t\tthis.debug('closing')\n\t\tthis.didDispose = true\n\t\tthis.disposables.forEach((d) => d())\n\t}\n\n\tprivate isPersisting = false\n\tprivate didLastWriteError = false\n\t// eslint-disable-next-line no-restricted-globals\n\tprivate scheduledPersistTimeout: ReturnType | null = null\n\n\t/**\n\t * Schedule a persist. Persists don't happen immediately: they are throttled to avoid writing too\n\t * often, and will retry if failed.\n\t *\n\t * @internal\n\t */\n\tprivate schedulePersist() {\n\t\tthis.debug('schedulePersist', this.scheduledPersistTimeout)\n\t\tif (this.scheduledPersistTimeout) return\n\t\t// eslint-disable-next-line no-restricted-globals\n\t\tthis.scheduledPersistTimeout = setTimeout(\n\t\t\t() => {\n\t\t\t\tthis.scheduledPersistTimeout = null\n\t\t\t\tthis.persistIfNeeded()\n\t\t\t},\n\t\t\tthis.didLastWriteError ? PERSIST_RETRY_THROTTLE_MS : PERSIST_THROTTLE_MS\n\t\t)\n\t}\n\n\t/**\n\t * Persist to IndexedDB only under certain circumstances:\n\t *\n\t * - If we're not already persisting\n\t * - If we're not reloading the page\n\t * - And we have something to persist (a full db write scheduled or changes in the diff queue)\n\t *\n\t * @internal\n\t */\n\tprivate persistIfNeeded() {\n\t\tthis.debug('persistIfNeeded', {\n\t\t\tisPersisting: this.isPersisting,\n\t\t\tisReloading: this.isReloading,\n\t\t\tshouldDoFullDBWrite: this.shouldDoFullDBWrite,\n\t\t\tdiffQueueLength: this.diffQueue.length,\n\t\t\tstoreIsPossiblyCorrupt: this.store.isPossiblyCorrupted(),\n\t\t})\n\n\t\t// if we've scheduled a persist for the future, that's no longer needed\n\t\tif (this.scheduledPersistTimeout) {\n\t\t\tclearTimeout(this.scheduledPersistTimeout)\n\t\t\tthis.scheduledPersistTimeout = null\n\t\t}\n\n\t\t// if a persist is already in progress, we don't need to do anything -\n\t\t// if there are still outstanding changes once it's finished, it'll\n\t\t// schedule another persist\n\t\tif (this.isPersisting) return\n\n\t\t// if we're reloading the page, it's because there's a newer client\n\t\t// present so lets not overwrite their changes\n\t\tif (this.isReloading) return\n\n\t\t// if the store is possibly corrupted, we don't want to persist\n\t\tif (this.store.isPossiblyCorrupted()) return\n\n\t\t// if we're scheduled for a full write or if we have changes outstanding, let's persist them!\n\t\tif (this.shouldDoFullDBWrite || this.diffQueue.length > 0) {\n\t\t\tthis.doPersist()\n\t\t}\n\t}\n\n\t/**\n\t * Actually persist to IndexedDB. If the write fails, then we'll retry with a full db write after\n\t * a short delay.\n\t */\n\tprivate async doPersist() {\n\t\tassert(!this.isPersisting, 'persist already in progress')\n\t\tif (this.didDispose) return\n\t\tthis.isPersisting = true\n\n\t\tthis.debug('doPersist start')\n\n\t\t// instantly empty the diff queue, but keep our own copy of it. this way\n\t\t// diffs that come in during the persist will still get tracked\n\t\tconst diffQueue = this.diffQueue\n\t\tthis.diffQueue = []\n\n\t\ttry {\n\t\t\tif (this.shouldDoFullDBWrite) {\n\t\t\t\tthis.shouldDoFullDBWrite = false\n\t\t\t\tawait this.db.storeSnapshot({\n\t\t\t\t\tschema: this.store.schema,\n\t\t\t\t\tsnapshot: this.store.serialize(),\n\t\t\t\t\tsessionId: this.sessionId,\n\t\t\t\t\tsessionStateSnapshot: this.$sessionStateSnapshot.get(),\n\t\t\t\t})\n\t\t\t} else {\n\t\t\t\tconst diffs = squashRecordDiffs(\n\t\t\t\t\tdiffQueue.filter((d): d is RecordsDiff => d !== UPDATE_INSTANCE_STATE)\n\t\t\t\t)\n\t\t\t\tawait this.db.storeChanges({\n\t\t\t\t\tchanges: diffs,\n\t\t\t\t\tschema: this.store.schema,\n\t\t\t\t\tsessionId: this.sessionId,\n\t\t\t\t\tsessionStateSnapshot: this.$sessionStateSnapshot.get(),\n\t\t\t\t})\n\t\t\t}\n\t\t\tthis.didLastWriteError = false\n\t\t} catch (e) {\n\t\t\t// set this.shouldDoFullDBWrite because we clear the diffQueue no matter what,\n\t\t\t// so if this is just a temporary error, we will still persist all changes\n\t\t\tthis.shouldDoFullDBWrite = true\n\t\t\tthis.didLastWriteError = true\n\t\t\tconsole.error('failed to store changes in indexed db', e)\n\n\t\t\tshowCantWriteToIndexDbAlert()\n\t\t\tif (typeof window !== 'undefined') {\n\t\t\t\t// adios\n\t\t\t\twindow.location.reload()\n\t\t\t}\n\t\t}\n\n\t\tthis.isPersisting = false\n\t\tthis.debug('doPersist end')\n\n\t\t// changes might have come in between when we started the persist and\n\t\t// now. we request another persist so any new changes can get written\n\t\tthis.schedulePersist()\n\t}\n}\n"], -+ "mappings": "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", -+ "names": ["msg", "data"] -+} -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/utils/sync/alerts.mjs b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/utils/sync/alerts.mjs -new file mode 100644 -index 0000000..3232d98 ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/utils/sync/alerts.mjs -@@ -0,0 +1,22 @@ -+function showCantWriteToIndexDbAlert() { -+ window.alert( -+ `Oops! We could not save changes to your browser's storage. We now need to reload the page and try again. -+ -+Keep seeing this message? -+\u2022 If you're using tldraw in a private or "incognito" window, try loading tldraw in a regular window or in a different browser. -+\u2022 If your hard disk is full, try clearing up some space and then reload the page.` -+ ); -+} -+function showCantReadFromIndexDbAlert() { -+ window.alert( -+ `Oops! We could not access your browser's storage\u2014and the app won't work correctly without that. We now need to reload the page and try again. -+ -+Keep seeing this message? -+\u2022 If you're using tldraw in a private or "incognito" window, try loading tldraw in a regular window or in a different browser.` -+ ); -+} -+export { -+ showCantReadFromIndexDbAlert, -+ showCantWriteToIndexDbAlert -+}; -+//# sourceMappingURL=alerts.mjs.map -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/utils/sync/alerts.mjs.map b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/utils/sync/alerts.mjs.map -new file mode 100644 -index 0000000..9eea804 ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/utils/sync/alerts.mjs.map -@@ -0,0 +1,7 @@ -+{ -+ "version": 3, -+ "sources": ["../../../../src/lib/utils/sync/alerts.ts"], -+ "sourcesContent": ["/** @internal */\nexport function showCantWriteToIndexDbAlert() {\n\twindow.alert(\n\t\t`Oops! We could not save changes to your browser's storage. We now need to reload the page and try again.\n\nKeep seeing this message?\n\u2022 If you're using tldraw in a private or \"incognito\" window, try loading tldraw in a regular window or in a different browser.\n\u2022 If your hard disk is full, try clearing up some space and then reload the page.`\n\t)\n}\n\n/** @internal */\nexport function showCantReadFromIndexDbAlert() {\n\twindow.alert(\n\t\t`Oops! We could not access your browser's storage\u2014and the app won't work correctly without that. We now need to reload the page and try again.\n\nKeep seeing this message?\n\u2022 If you're using tldraw in a private or \"incognito\" window, try loading tldraw in a regular window or in a different browser.`\n\t)\n}\n"], -+ "mappings": "AACO,SAAS,8BAA8B;AAC7C,SAAO;AAAA,IACN;AAAA;AAAA;AAAA;AAAA;AAAA,EAKD;AACD;AAGO,SAAS,+BAA+B;AAC9C,SAAO;AAAA,IACN;AAAA;AAAA;AAAA;AAAA,EAID;AACD;", -+ "names": [] -+} -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/utils/sync/hardReset.mjs b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/utils/sync/hardReset.mjs -new file mode 100644 -index 0000000..3552107 ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/utils/sync/hardReset.mjs -@@ -0,0 +1,26 @@ -+import { clearLocalStorage, clearSessionStorage } from "@tldraw/utils"; -+import { deleteDB } from "idb"; -+import { LocalIndexedDb, getAllIndexDbNames } from "./LocalIndexedDb.mjs"; -+async function hardReset({ shouldReload = true } = {}) { -+ clearSessionStorage(); -+ for (const instance of LocalIndexedDb.connectedInstances) { -+ await instance.close(); -+ } -+ await Promise.all(getAllIndexDbNames().map((db) => deleteDB(db))); -+ clearLocalStorage(); -+ if (shouldReload) { -+ window.location.reload(); -+ } -+} -+if (typeof window !== "undefined") { -+ if (process.env.NODE_ENV === "development") { -+ ; -+ window.hardReset = hardReset; -+ } -+ ; -+ window.__tldraw__hardReset = hardReset; -+} -+export { -+ hardReset -+}; -+//# sourceMappingURL=hardReset.mjs.map -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/utils/sync/hardReset.mjs.map b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/utils/sync/hardReset.mjs.map -new file mode 100644 -index 0000000..269b289 ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/utils/sync/hardReset.mjs.map -@@ -0,0 +1,7 @@ -+{ -+ "version": 3, -+ "sources": ["../../../../src/lib/utils/sync/hardReset.ts"], -+ "sourcesContent": ["import { clearLocalStorage, clearSessionStorage } from '@tldraw/utils'\nimport { deleteDB } from 'idb'\nimport { LocalIndexedDb, getAllIndexDbNames } from './LocalIndexedDb'\n\n/**\n * Clear the database of all data associated with tldraw.\n *\n * @public */\nexport async function hardReset({ shouldReload = true } = {}) {\n\tclearSessionStorage()\n\n\tfor (const instance of LocalIndexedDb.connectedInstances) {\n\t\tawait instance.close()\n\t}\n\tawait Promise.all(getAllIndexDbNames().map((db) => deleteDB(db)))\n\n\tclearLocalStorage()\n\tif (shouldReload) {\n\t\twindow.location.reload()\n\t}\n}\n\nif (typeof window !== 'undefined') {\n\tif (process.env.NODE_ENV === 'development') {\n\t\t;(window as any).hardReset = hardReset\n\t}\n\t// window.__tldraw__hardReset is used to inject the logic into the tldraw library\n\t;(window as any).__tldraw__hardReset = hardReset\n}\n"], -+ "mappings": "AAAA,SAAS,mBAAmB,2BAA2B;AACvD,SAAS,gBAAgB;AACzB,SAAS,gBAAgB,0BAA0B;AAMnD,eAAsB,UAAU,EAAE,eAAe,KAAK,IAAI,CAAC,GAAG;AAC7D,sBAAoB;AAEpB,aAAW,YAAY,eAAe,oBAAoB;AACzD,UAAM,SAAS,MAAM;AAAA,EACtB;AACA,QAAM,QAAQ,IAAI,mBAAmB,EAAE,IAAI,CAAC,OAAO,SAAS,EAAE,CAAC,CAAC;AAEhE,oBAAkB;AAClB,MAAI,cAAc;AACjB,WAAO,SAAS,OAAO;AAAA,EACxB;AACD;AAEA,IAAI,OAAO,WAAW,aAAa;AAClC,MAAI,QAAQ,IAAI,aAAa,eAAe;AAC3C;AAAC,IAAC,OAAe,YAAY;AAAA,EAC9B;AAEA;AAAC,EAAC,OAAe,sBAAsB;AACxC;", -+ "names": [] -+} -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/utils/uniq.mjs b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/utils/uniq.mjs -new file mode 100644 -index 0000000..d0a521c ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/utils/uniq.mjs -@@ -0,0 +1,8 @@ -+import { uniq as _uniq } from "@tldraw/utils"; -+function uniq(array) { -+ return _uniq(array); -+} -+export { -+ uniq -+}; -+//# sourceMappingURL=uniq.mjs.map -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/utils/uniq.mjs.map b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/utils/uniq.mjs.map -new file mode 100644 -index 0000000..d0a7d48 ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/utils/uniq.mjs.map -@@ -0,0 +1,7 @@ -+{ -+ "version": 3, -+ "sources": ["../../../src/lib/utils/uniq.ts"], -+ "sourcesContent": ["import { uniq as _uniq } from '@tldraw/utils'\n\n/** @public */\nexport function uniq(\n\tarray:\n\t\t| {\n\t\t\t\treadonly length: number\n\t\t\t\treadonly [n: number]: T\n\t\t }\n\t\t| null\n\t\t| undefined\n): T[] {\n\treturn _uniq(array)\n}\n"], -+ "mappings": "AAAA,SAAS,QAAQ,aAAa;AAGvB,SAAS,KACf,OAOM;AACN,SAAO,MAAM,KAAK;AACnB;", -+ "names": [] -+} -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/utils/window-open.mjs b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/utils/window-open.mjs -new file mode 100644 -index 0000000..2f4b706 ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/utils/window-open.mjs -@@ -0,0 +1,8 @@ -+import { runtime } from "./runtime.mjs"; -+function openWindow(url, target = "_blank") { -+ runtime.openWindow(url, target); -+} -+export { -+ openWindow -+}; -+//# sourceMappingURL=window-open.mjs.map -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/utils/window-open.mjs.map b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/utils/window-open.mjs.map -new file mode 100644 -index 0000000..8ed5a34 ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/utils/window-open.mjs.map -@@ -0,0 +1,7 @@ -+{ -+ "version": 3, -+ "sources": ["../../../src/lib/utils/window-open.ts"], -+ "sourcesContent": ["import { runtime } from './runtime'\n\n/** @public */\nexport function openWindow(url: string, target = '_blank') {\n\truntime.openWindow(url, target)\n}\n"], -+ "mappings": "AAAA,SAAS,eAAe;AAGjB,SAAS,WAAW,KAAa,SAAS,UAAU;AAC1D,UAAQ,WAAW,KAAK,MAAM;AAC/B;", -+ "names": [] -+} -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/watermarks.mjs b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/watermarks.mjs -new file mode 100644 -index 0000000..2577376 ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/watermarks.mjs -@@ -0,0 +1,9 @@ -+const watermarkDesktopSvg = ''; -+const watermarkMobileSvg = ''; -+const watermarkTrackSvg = ''; -+export { -+ watermarkDesktopSvg, -+ watermarkMobileSvg, -+ watermarkTrackSvg -+}; -+//# sourceMappingURL=watermarks.mjs.map -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/watermarks.mjs.map b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/watermarks.mjs.map -new file mode 100644 -index 0000000..9b6502d ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/lib/watermarks.mjs.map -@@ -0,0 +1,7 @@ -+{ -+ "version": 3, -+ "sources": ["../../src/lib/watermarks.ts"], -+ "sourcesContent": ["// This file is automatically generated by internal/scripts/refresh-assets.ts.\n// Do not edit manually. Or do, I'm a comment, not a cop.\n\nexport const watermarkDesktopSvg =\n\t''\nexport const watermarkMobileSvg =\n\t''\nexport const watermarkTrackSvg = ''\n"], -+ "mappings": "AAGO,MAAM,sBACZ;AACM,MAAM,qBACZ;AACM,MAAM,oBAAoB;", -+ "names": [] -+} -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/version.mjs b/node_modules/@tldraw/editor/dist-cjs/dist-esm/version.mjs -new file mode 100644 -index 0000000..bd29a3a ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/version.mjs -@@ -0,0 +1,11 @@ -+const version = "3.2.0"; -+const publishDates = { -+ major: "2024-09-13T14:36:29.063Z", -+ minor: "2024-09-26T10:41:32.405Z", -+ patch: "2024-09-26T10:41:32.405Z" -+}; -+export { -+ publishDates, -+ version -+}; -+//# sourceMappingURL=version.mjs.map -diff --git a/node_modules/@tldraw/editor/dist-cjs/dist-esm/version.mjs.map b/node_modules/@tldraw/editor/dist-cjs/dist-esm/version.mjs.map -new file mode 100644 -index 0000000..8660278 ---- /dev/null -+++ b/node_modules/@tldraw/editor/dist-cjs/dist-esm/version.mjs.map -@@ -0,0 +1,7 @@ -+{ -+ "version": 3, -+ "sources": ["../src/version.ts"], -+ "sourcesContent": ["// This file is automatically generated by internal/scripts/refresh-assets.ts.\n// Do not edit manually. Or do, I'm a comment, not a cop.\n\nexport const version = '3.2.0'\nexport const publishDates = {\n\tmajor: '2024-09-13T14:36:29.063Z',\n\tminor: '2024-09-26T10:41:32.405Z',\n\tpatch: '2024-09-26T10:41:32.405Z',\n}\n"], -+ "mappings": "AAGO,MAAM,UAAU;AAChB,MAAM,eAAe;AAAA,EAC3B,OAAO;AAAA,EACP,OAAO;AAAA,EACP,OAAO;AACR;", -+ "names": [] -+} -diff --git a/node_modules/@tldraw/editor/dist-cjs/lib/editor/Editor.js b/node_modules/@tldraw/editor/dist-cjs/lib/editor/Editor.js -index 0516a52..4463471 100644 ---- a/node_modules/@tldraw/editor/dist-cjs/lib/editor/Editor.js -+++ b/node_modules/@tldraw/editor/dist-cjs/lib/editor/Editor.js -@@ -2489,7 +2489,7 @@ class Editor extends (_a = import_eventemitter3.default, _getIsShapeHiddenCache_ - * @public - */ - updateViewportScreenBounds(screenBounds, center = false) { -- if (screenBounds instanceof HTMLElement) { -+ if (!(screenBounds instanceof import_Box.Box)) { - const rect = screenBounds.getBoundingClientRect(); - screenBounds = new import_Box.Box( - rect.left || rect.x, -diff --git a/node_modules/@tldraw/editor/dist-cjs/lib/editor/Editor.js.map b/node_modules/@tldraw/editor/dist-cjs/lib/editor/Editor.js.map -index 31c8e1e..7829aab 100644 ---- a/node_modules/@tldraw/editor/dist-cjs/lib/editor/Editor.js.map -+++ b/node_modules/@tldraw/editor/dist-cjs/lib/editor/Editor.js.map -@@ -1,7 +1,7 @@ - { - "version": 3, - "sources": ["../../../src/lib/editor/Editor.ts"], -- "sourcesContent": ["import { EMPTY_ARRAY, atom, computed, react, transact, unsafe__withoutCapture } from '@tldraw/state'\nimport {\n\tComputedCache,\n\tRecordType,\n\tStoreSideEffects,\n\tStoreSnapshot,\n\tUnknownRecord,\n\treverseRecordsDiff,\n} from '@tldraw/store'\nimport {\n\tCameraRecordType,\n\tInstancePageStateRecordType,\n\tPageRecordType,\n\tStyleProp,\n\tStylePropValue,\n\tTLArrowShape,\n\tTLAsset,\n\tTLAssetId,\n\tTLAssetPartial,\n\tTLBinding,\n\tTLBindingCreate,\n\tTLBindingId,\n\tTLBindingUpdate,\n\tTLCamera,\n\tTLCursor,\n\tTLCursorType,\n\tTLDOCUMENT_ID,\n\tTLDocument,\n\tTLFrameShape,\n\tTLGeoShape,\n\tTLGroupShape,\n\tTLHandle,\n\tTLINSTANCE_ID,\n\tTLImageAsset,\n\tTLInstance,\n\tTLInstancePageState,\n\tTLPOINTER_ID,\n\tTLPage,\n\tTLPageId,\n\tTLParentId,\n\tTLRecord,\n\tTLShape,\n\tTLShapeId,\n\tTLShapePartial,\n\tTLStore,\n\tTLStoreSnapshot,\n\tTLUnknownBinding,\n\tTLUnknownShape,\n\tTLVideoAsset,\n\tcreateBindingId,\n\tcreateShapeId,\n\tgetShapePropKeysByStyle,\n\tisPageId,\n\tisShapeId,\n} from '@tldraw/tlschema'\nimport {\n\tFileHelpers,\n\tIndexKey,\n\tJsonObject,\n\tPerformanceTracker,\n\tResult,\n\tTimers,\n\tannotateError,\n\tassert,\n\tassertExists,\n\tbind,\n\tcompact,\n\tdebounce,\n\tdedupe,\n\texhaustiveSwitchError,\n\tfetch,\n\tgetIndexAbove,\n\tgetIndexBetween,\n\tgetIndices,\n\tgetIndicesAbove,\n\tgetIndicesBetween,\n\tgetOwnProperty,\n\thasOwnProperty,\n\tlast,\n\tlerp,\n\tsortById,\n\tsortByIndex,\n\tstructuredClone,\n\tuniqueId,\n} from '@tldraw/utils'\nimport EventEmitter from 'eventemitter3'\nimport {\n\tTLEditorSnapshot,\n\tTLLoadSnapshotOptions,\n\tgetSnapshot,\n\tloadSnapshot,\n} from '../config/TLEditorSnapshot'\nimport { TLUser, createTLUser } from '../config/createTLUser'\nimport { TLAnyBindingUtilConstructor, checkBindings } from '../config/defaultBindings'\nimport { TLAnyShapeUtilConstructor, checkShapesAndAddCore } from '../config/defaultShapes'\nimport {\n\tDEFAULT_ANIMATION_OPTIONS,\n\tDEFAULT_CAMERA_OPTIONS,\n\tINTERNAL_POINTER_IDS,\n\tLEFT_MOUSE_BUTTON,\n\tMIDDLE_MOUSE_BUTTON,\n\tRIGHT_MOUSE_BUTTON,\n\tSTYLUS_ERASER_BUTTON,\n\tZOOM_TO_FIT_PADDING,\n} from '../constants'\nimport { exportToSvg } from '../exports/exportToSvg'\nimport { TldrawOptions, defaultTldrawOptions } from '../options'\nimport { Box, BoxLike } from '../primitives/Box'\nimport { Mat, MatLike } from '../primitives/Mat'\nimport { Vec, VecLike } from '../primitives/Vec'\nimport { EASINGS } from '../primitives/easings'\nimport { Geometry2d } from '../primitives/geometry/Geometry2d'\nimport { Group2d } from '../primitives/geometry/Group2d'\nimport { intersectPolygonPolygon } from '../primitives/intersect'\nimport { PI2, approximately, areAnglesCompatible, clamp, pointInPolygon } from '../primitives/utils'\nimport { ReadonlySharedStyleMap, SharedStyle, SharedStyleMap } from '../utils/SharedStylesMap'\nimport { dataUrlToFile } from '../utils/assets'\nimport { debugFlags } from '../utils/debug-flags'\nimport {\n\tTLDeepLink,\n\tTLDeepLinkOptions,\n\tcreateDeepLinkString,\n\tparseDeepLinkString,\n} from '../utils/deepLinks'\nimport { getIncrementedName } from '../utils/getIncrementedName'\nimport { getReorderingShapesChanges } from '../utils/reorderShapes'\nimport { applyRotationToSnapshotShapes, getRotationSnapshot } from '../utils/rotation'\nimport { BindingOnDeleteOptions, BindingUtil } from './bindings/BindingUtil'\nimport { bindingsIndex } from './derivations/bindingsIndex'\nimport { notVisibleShapes } from './derivations/notVisibleShapes'\nimport { parentsToChildren } from './derivations/parentsToChildren'\nimport { deriveShapeIdsInCurrentPage } from './derivations/shapeIdsInCurrentPage'\nimport { ClickManager } from './managers/ClickManager'\nimport { EdgeScrollManager } from './managers/EdgeScrollManager'\nimport { EnvironmentManager } from './managers/EnvironmentManager'\nimport { FocusManager } from './managers/FocusManager'\nimport { HistoryManager } from './managers/HistoryManager'\nimport { ScribbleManager } from './managers/ScribbleManager'\nimport { SnapManager } from './managers/SnapManager/SnapManager'\nimport { TextManager } from './managers/TextManager'\nimport { TickManager } from './managers/TickManager'\nimport { UserPreferencesManager } from './managers/UserPreferencesManager'\nimport { ShapeUtil, TLResizeMode } from './shapes/ShapeUtil'\nimport { RootState } from './tools/RootState'\nimport { StateNode, TLStateNodeConstructor } from './tools/StateNode'\nimport { TLContent } from './types/clipboard-types'\nimport { TLEventMap } from './types/emit-types'\nimport {\n\tTLEventInfo,\n\tTLPinchEventInfo,\n\tTLPointerEventInfo,\n\tTLWheelEventInfo,\n} from './types/event-types'\nimport { TLExternalAssetContent, TLExternalContent } from './types/external-content'\nimport { TLHistoryBatchOptions } from './types/history-types'\nimport {\n\tOptionalKeys,\n\tRequiredKeys,\n\tTLCameraMoveOptions,\n\tTLCameraOptions,\n\tTLImageExportOptions,\n} from './types/misc-types'\nimport { TLResizeHandle } from './types/selection-types'\n\n/** @public */\nexport type TLResizeShapeOptions = Partial<{\n\tinitialBounds: Box\n\tscaleOrigin: VecLike\n\tscaleAxisRotation: number\n\tinitialShape: TLShape\n\tinitialPageTransform: MatLike\n\tdragHandle: TLResizeHandle\n\tisAspectRatioLocked: boolean\n\tmode: TLResizeMode\n\tskipStartAndEndCallbacks: boolean\n}>\n\n/** @public */\nexport interface TLEditorOptions {\n\t/**\n\t * The Store instance to use for keeping the app's data. This may be prepopulated, e.g. by loading\n\t * from a server or database.\n\t */\n\tstore: TLStore\n\t/**\n\t * An array of shapes to use in the editor. These will be used to create and manage shapes in the editor.\n\t */\n\tshapeUtils: readonly TLAnyShapeUtilConstructor[]\n\t/**\n\t * An array of bindings to use in the editor. These will be used to create and manage bindings in the editor.\n\t */\n\tbindingUtils: readonly TLAnyBindingUtilConstructor[]\n\t/**\n\t * An array of tools to use in the editor. These will be used to handle events and manage user interactions in the editor.\n\t */\n\ttools: readonly TLStateNodeConstructor[]\n\t/**\n\t * Should return a containing html element which has all the styles applied to the editor. If not\n\t * given, the body element will be used.\n\t */\n\tgetContainer(): HTMLElement\n\t/**\n\t * A user defined externally to replace the default user.\n\t */\n\tuser?: TLUser\n\t/**\n\t * The editor's initial active tool (or other state node id).\n\t */\n\tinitialState?: string\n\t/**\n\t * Whether to automatically focus the editor when it mounts.\n\t */\n\tautoFocus?: boolean\n\t/**\n\t * Whether to infer dark mode from the user's system preferences. Defaults to false.\n\t */\n\tinferDarkMode?: boolean\n\t/**\n\t * Options for the editor's camera.\n\t */\n\tcameraOptions?: Partial\n\toptions?: Partial\n\tlicenseKey?: string\n\t/**\n\t * A predicate that should return true if the given shape should be hidden.\n\t * @param shape - The shape to check.\n\t * @param editor - The editor instance.\n\t */\n\tisShapeHidden?(shape: TLShape, editor: Editor): boolean\n}\n\n/**\n * Options for {@link Editor.(run:1)}.\n * @public\n */\nexport interface TLEditorRunOptions extends TLHistoryBatchOptions {\n\tignoreShapeLock?: boolean\n}\n\n/** @public */\nexport interface TLRenderingShape {\n\tid: TLShapeId\n\tshape: TLShape\n\tutil: ShapeUtil\n\tindex: number\n\tbackgroundIndex: number\n\topacity: number\n}\n\n/** @public */\nexport class Editor extends EventEmitter {\n\tconstructor({\n\t\tstore,\n\t\tuser,\n\t\tshapeUtils,\n\t\tbindingUtils,\n\t\ttools,\n\t\tgetContainer,\n\t\tcameraOptions,\n\t\tinitialState,\n\t\tautoFocus,\n\t\tinferDarkMode,\n\t\toptions,\n\t\tisShapeHidden,\n\t}: TLEditorOptions) {\n\t\tsuper()\n\n\t\tthis._isShapeHiddenPredicate = isShapeHidden\n\n\t\tthis.options = { ...defaultTldrawOptions, ...options }\n\t\tthis.store = store\n\t\tthis.disposables.add(this.store.dispose.bind(this.store))\n\t\tthis.history = new HistoryManager({\n\t\t\tstore,\n\t\t\tannotateError: (error) => {\n\t\t\t\tthis.annotateError(error, { origin: 'history.batch', willCrashApp: true })\n\t\t\t\tthis.crash(error)\n\t\t\t},\n\t\t})\n\n\t\tthis.snaps = new SnapManager(this)\n\n\t\tthis.timers = new Timers()\n\t\tthis.disposables.add(this.timers.dispose.bind(this.timers))\n\n\t\tthis._cameraOptions.set({ ...DEFAULT_CAMERA_OPTIONS, ...cameraOptions })\n\n\t\tthis.user = new UserPreferencesManager(user ?? createTLUser(), inferDarkMode ?? false)\n\n\t\tthis.getContainer = getContainer\n\n\t\tthis.textMeasure = new TextManager(this)\n\t\tthis._tickManager = new TickManager(this)\n\n\t\tclass NewRoot extends RootState {\n\t\t\tstatic override initial = initialState ?? ''\n\t\t}\n\n\t\tthis.root = new NewRoot(this)\n\t\tthis.root.children = {}\n\n\t\tconst allShapeUtils = checkShapesAndAddCore(shapeUtils)\n\n\t\tconst _shapeUtils = {} as Record>\n\t\tconst _styleProps = {} as Record, string>>\n\t\tconst allStylesById = new Map>()\n\n\t\tfor (const Util of allShapeUtils) {\n\t\t\tconst util = new Util(this)\n\t\t\t_shapeUtils[Util.type] = util\n\n\t\t\tconst propKeysByStyle = getShapePropKeysByStyle(Util.props ?? {})\n\t\t\t_styleProps[Util.type] = propKeysByStyle\n\n\t\t\tfor (const style of propKeysByStyle.keys()) {\n\t\t\t\tif (!allStylesById.has(style.id)) {\n\t\t\t\t\tallStylesById.set(style.id, style)\n\t\t\t\t} else if (allStylesById.get(style.id) !== style) {\n\t\t\t\t\tthrow Error(\n\t\t\t\t\t\t`Multiple style props with id \"${style.id}\" in use. Style prop IDs must be unique.`\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tthis.shapeUtils = _shapeUtils\n\t\tthis.styleProps = _styleProps\n\n\t\tconst allBindingUtils = checkBindings(bindingUtils)\n\t\tconst _bindingUtils = {} as Record>\n\t\tfor (const Util of allBindingUtils) {\n\t\t\tconst util = new Util(this)\n\t\t\t_bindingUtils[Util.type] = util\n\t\t}\n\t\tthis.bindingUtils = _bindingUtils\n\n\t\t// Tools.\n\t\t// Accept tools from constructor parameters which may not conflict with the root note's default or\n\t\t// \"baked in\" tools, select and zoom.\n\t\tfor (const Tool of [...tools]) {\n\t\t\tif (hasOwnProperty(this.root.children!, Tool.id)) {\n\t\t\t\tthrow Error(`Can't override tool with id \"${Tool.id}\"`)\n\t\t\t}\n\t\t\tthis.root.children![Tool.id] = new Tool(this, this.root)\n\t\t}\n\n\t\tthis.environment = new EnvironmentManager(this)\n\t\tthis.scribbles = new ScribbleManager(this)\n\n\t\t// Cleanup\n\n\t\tconst cleanupInstancePageState = (\n\t\t\tprevPageState: TLInstancePageState,\n\t\t\tshapesNoLongerInPage: Set\n\t\t) => {\n\t\t\tlet nextPageState = null as null | TLInstancePageState\n\n\t\t\tconst selectedShapeIds = prevPageState.selectedShapeIds.filter(\n\t\t\t\t(id) => !shapesNoLongerInPage.has(id)\n\t\t\t)\n\t\t\tif (selectedShapeIds.length !== prevPageState.selectedShapeIds.length) {\n\t\t\t\tif (!nextPageState) nextPageState = { ...prevPageState }\n\t\t\t\tnextPageState.selectedShapeIds = selectedShapeIds\n\t\t\t}\n\n\t\t\tconst erasingShapeIds = prevPageState.erasingShapeIds.filter(\n\t\t\t\t(id) => !shapesNoLongerInPage.has(id)\n\t\t\t)\n\t\t\tif (erasingShapeIds.length !== prevPageState.erasingShapeIds.length) {\n\t\t\t\tif (!nextPageState) nextPageState = { ...prevPageState }\n\t\t\t\tnextPageState.erasingShapeIds = erasingShapeIds\n\t\t\t}\n\n\t\t\tif (prevPageState.hoveredShapeId && shapesNoLongerInPage.has(prevPageState.hoveredShapeId)) {\n\t\t\t\tif (!nextPageState) nextPageState = { ...prevPageState }\n\t\t\t\tnextPageState.hoveredShapeId = null\n\t\t\t}\n\n\t\t\tif (prevPageState.editingShapeId && shapesNoLongerInPage.has(prevPageState.editingShapeId)) {\n\t\t\t\tif (!nextPageState) nextPageState = { ...prevPageState }\n\t\t\t\tnextPageState.editingShapeId = null\n\t\t\t}\n\n\t\t\tconst hintingShapeIds = prevPageState.hintingShapeIds.filter(\n\t\t\t\t(id) => !shapesNoLongerInPage.has(id)\n\t\t\t)\n\t\t\tif (hintingShapeIds.length !== prevPageState.hintingShapeIds.length) {\n\t\t\t\tif (!nextPageState) nextPageState = { ...prevPageState }\n\t\t\t\tnextPageState.hintingShapeIds = hintingShapeIds\n\t\t\t}\n\n\t\t\tif (prevPageState.focusedGroupId && shapesNoLongerInPage.has(prevPageState.focusedGroupId)) {\n\t\t\t\tif (!nextPageState) nextPageState = { ...prevPageState }\n\t\t\t\tnextPageState.focusedGroupId = null\n\t\t\t}\n\t\t\treturn nextPageState\n\t\t}\n\n\t\tthis.sideEffects = this.store.sideEffects\n\n\t\tlet deletedBindings = new Map>()\n\t\tconst deletedShapeIds = new Set()\n\t\tconst invalidParents = new Set()\n\t\tlet invalidBindingTypes = new Set()\n\t\tthis.disposables.add(\n\t\t\tthis.sideEffects.registerOperationCompleteHandler(() => {\n\t\t\t\t// this needs to be cleared here because further effects may delete more shapes\n\t\t\t\t// and we want the next invocation of this handler to handle those separately\n\t\t\t\tdeletedShapeIds.clear()\n\n\t\t\t\tfor (const parentId of invalidParents) {\n\t\t\t\t\tinvalidParents.delete(parentId)\n\t\t\t\t\tconst parent = this.getShape(parentId)\n\t\t\t\t\tif (!parent) continue\n\n\t\t\t\t\tconst util = this.getShapeUtil(parent)\n\t\t\t\t\tconst changes = util.onChildrenChange?.(parent)\n\n\t\t\t\t\tif (changes?.length) {\n\t\t\t\t\t\tthis.updateShapes(changes)\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (invalidBindingTypes.size) {\n\t\t\t\t\tconst t = invalidBindingTypes\n\t\t\t\t\tinvalidBindingTypes = new Set()\n\t\t\t\t\tfor (const type of t) {\n\t\t\t\t\t\tconst util = this.getBindingUtil(type)\n\t\t\t\t\t\tutil.onOperationComplete?.()\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (deletedBindings.size) {\n\t\t\t\t\tconst t = deletedBindings\n\t\t\t\t\tdeletedBindings = new Map()\n\t\t\t\t\tfor (const opts of t.values()) {\n\t\t\t\t\t\tthis.getBindingUtil(opts.binding).onAfterDelete?.(opts)\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tthis.emit('update')\n\t\t\t})\n\t\t)\n\n\t\tthis.disposables.add(\n\t\t\tthis.sideEffects.register({\n\t\t\t\tshape: {\n\t\t\t\t\tafterChange: (shapeBefore, shapeAfter) => {\n\t\t\t\t\t\tfor (const binding of this.getBindingsInvolvingShape(shapeAfter)) {\n\t\t\t\t\t\t\tinvalidBindingTypes.add(binding.type)\n\t\t\t\t\t\t\tif (binding.fromId === shapeAfter.id) {\n\t\t\t\t\t\t\t\tthis.getBindingUtil(binding).onAfterChangeFromShape?.({\n\t\t\t\t\t\t\t\t\tbinding,\n\t\t\t\t\t\t\t\t\tshapeBefore,\n\t\t\t\t\t\t\t\t\tshapeAfter,\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (binding.toId === shapeAfter.id) {\n\t\t\t\t\t\t\t\tthis.getBindingUtil(binding).onAfterChangeToShape?.({\n\t\t\t\t\t\t\t\t\tbinding,\n\t\t\t\t\t\t\t\t\tshapeBefore,\n\t\t\t\t\t\t\t\t\tshapeAfter,\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// if the shape's parent changed and it has a binding, update the binding\n\t\t\t\t\t\tif (shapeBefore.parentId !== shapeAfter.parentId) {\n\t\t\t\t\t\t\tconst notifyBindingAncestryChange = (id: TLShapeId) => {\n\t\t\t\t\t\t\t\tconst descendantShape = this.getShape(id)\n\t\t\t\t\t\t\t\tif (!descendantShape) return\n\n\t\t\t\t\t\t\t\tfor (const binding of this.getBindingsInvolvingShape(descendantShape)) {\n\t\t\t\t\t\t\t\t\tinvalidBindingTypes.add(binding.type)\n\n\t\t\t\t\t\t\t\t\tif (binding.fromId === descendantShape.id) {\n\t\t\t\t\t\t\t\t\t\tthis.getBindingUtil(binding).onAfterChangeFromShape?.({\n\t\t\t\t\t\t\t\t\t\t\tbinding,\n\t\t\t\t\t\t\t\t\t\t\tshapeBefore: descendantShape,\n\t\t\t\t\t\t\t\t\t\t\tshapeAfter: descendantShape,\n\t\t\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tif (binding.toId === descendantShape.id) {\n\t\t\t\t\t\t\t\t\t\tthis.getBindingUtil(binding).onAfterChangeToShape?.({\n\t\t\t\t\t\t\t\t\t\t\tbinding,\n\t\t\t\t\t\t\t\t\t\t\tshapeBefore: descendantShape,\n\t\t\t\t\t\t\t\t\t\t\tshapeAfter: descendantShape,\n\t\t\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tnotifyBindingAncestryChange(shapeAfter.id)\n\t\t\t\t\t\t\tthis.visitDescendants(shapeAfter.id, notifyBindingAncestryChange)\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// if this shape moved to a new page, clean up any previous page's instance state\n\t\t\t\t\t\tif (shapeBefore.parentId !== shapeAfter.parentId && isPageId(shapeAfter.parentId)) {\n\t\t\t\t\t\t\tconst allMovingIds = new Set([shapeBefore.id])\n\t\t\t\t\t\t\tthis.visitDescendants(shapeBefore.id, (id) => {\n\t\t\t\t\t\t\t\tallMovingIds.add(id)\n\t\t\t\t\t\t\t})\n\n\t\t\t\t\t\t\tfor (const instancePageState of this.getPageStates()) {\n\t\t\t\t\t\t\t\tif (instancePageState.pageId === shapeAfter.parentId) continue\n\t\t\t\t\t\t\t\tconst nextPageState = cleanupInstancePageState(instancePageState, allMovingIds)\n\n\t\t\t\t\t\t\t\tif (nextPageState) {\n\t\t\t\t\t\t\t\t\tthis.store.put([nextPageState])\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (shapeBefore.parentId && isShapeId(shapeBefore.parentId)) {\n\t\t\t\t\t\t\tinvalidParents.add(shapeBefore.parentId)\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (shapeAfter.parentId !== shapeBefore.parentId && isShapeId(shapeAfter.parentId)) {\n\t\t\t\t\t\t\tinvalidParents.add(shapeAfter.parentId)\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t\tbeforeDelete: (shape) => {\n\t\t\t\t\t\t// if we triggered this delete with a recursive call, don't do anything\n\t\t\t\t\t\tif (deletedShapeIds.has(shape.id)) return\n\t\t\t\t\t\t// if the deleted shape has a parent shape make sure we call it's onChildrenChange callback\n\t\t\t\t\t\tif (shape.parentId && isShapeId(shape.parentId)) {\n\t\t\t\t\t\t\tinvalidParents.add(shape.parentId)\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tdeletedShapeIds.add(shape.id)\n\n\t\t\t\t\t\tconst deleteBindingIds: TLBindingId[] = []\n\t\t\t\t\t\tfor (const binding of this.getBindingsInvolvingShape(shape)) {\n\t\t\t\t\t\t\tinvalidBindingTypes.add(binding.type)\n\t\t\t\t\t\t\tdeleteBindingIds.push(binding.id)\n\t\t\t\t\t\t\tconst util = this.getBindingUtil(binding)\n\t\t\t\t\t\t\tif (binding.fromId === shape.id) {\n\t\t\t\t\t\t\t\tutil.onBeforeIsolateToShape?.({ binding, removedShape: shape })\n\t\t\t\t\t\t\t\tutil.onBeforeDeleteFromShape?.({ binding, shape })\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tutil.onBeforeIsolateFromShape?.({ binding, removedShape: shape })\n\t\t\t\t\t\t\t\tutil.onBeforeDeleteToShape?.({ binding, shape })\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (deleteBindingIds.length) {\n\t\t\t\t\t\t\tthis.deleteBindings(deleteBindingIds)\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst deletedIds = new Set([shape.id])\n\t\t\t\t\t\tconst updates = compact(\n\t\t\t\t\t\t\tthis.getPageStates().map((pageState) => {\n\t\t\t\t\t\t\t\treturn cleanupInstancePageState(pageState, deletedIds)\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t)\n\n\t\t\t\t\t\tif (updates.length) {\n\t\t\t\t\t\t\tthis.store.put(updates)\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tbinding: {\n\t\t\t\t\tbeforeCreate: (binding) => {\n\t\t\t\t\t\tconst next = this.getBindingUtil(binding).onBeforeCreate?.({ binding })\n\t\t\t\t\t\tif (next) return next\n\t\t\t\t\t\treturn binding\n\t\t\t\t\t},\n\t\t\t\t\tafterCreate: (binding) => {\n\t\t\t\t\t\tinvalidBindingTypes.add(binding.type)\n\t\t\t\t\t\tthis.getBindingUtil(binding).onAfterCreate?.({ binding })\n\t\t\t\t\t},\n\t\t\t\t\tbeforeChange: (bindingBefore, bindingAfter) => {\n\t\t\t\t\t\tconst updated = this.getBindingUtil(bindingAfter).onBeforeChange?.({\n\t\t\t\t\t\t\tbindingBefore,\n\t\t\t\t\t\t\tbindingAfter,\n\t\t\t\t\t\t})\n\t\t\t\t\t\tif (updated) return updated\n\t\t\t\t\t\treturn bindingAfter\n\t\t\t\t\t},\n\t\t\t\t\tafterChange: (bindingBefore, bindingAfter) => {\n\t\t\t\t\t\tinvalidBindingTypes.add(bindingAfter.type)\n\t\t\t\t\t\tthis.getBindingUtil(bindingAfter).onAfterChange?.({ bindingBefore, bindingAfter })\n\t\t\t\t\t},\n\t\t\t\t\tbeforeDelete: (binding) => {\n\t\t\t\t\t\tthis.getBindingUtil(binding).onBeforeDelete?.({ binding })\n\t\t\t\t\t},\n\t\t\t\t\tafterDelete: (binding) => {\n\t\t\t\t\t\tthis.getBindingUtil(binding).onAfterDelete?.({ binding })\n\t\t\t\t\t\tinvalidBindingTypes.add(binding.type)\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tpage: {\n\t\t\t\t\tafterCreate: (record) => {\n\t\t\t\t\t\tconst cameraId = CameraRecordType.createId(record.id)\n\t\t\t\t\t\tconst _pageStateId = InstancePageStateRecordType.createId(record.id)\n\t\t\t\t\t\tif (!this.store.has(cameraId)) {\n\t\t\t\t\t\t\tthis.store.put([CameraRecordType.create({ id: cameraId })])\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (!this.store.has(_pageStateId)) {\n\t\t\t\t\t\t\tthis.store.put([\n\t\t\t\t\t\t\t\tInstancePageStateRecordType.create({ id: _pageStateId, pageId: record.id }),\n\t\t\t\t\t\t\t])\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t\tafterDelete: (record, source) => {\n\t\t\t\t\t\t// page was deleted, need to check whether it's the current page and select another one if so\n\t\t\t\t\t\tif (this.getInstanceState()?.currentPageId === record.id) {\n\t\t\t\t\t\t\tconst backupPageId = this.getPages().find((p) => p.id !== record.id)?.id\n\t\t\t\t\t\t\tif (backupPageId) {\n\t\t\t\t\t\t\t\tthis.store.put([{ ...this.getInstanceState(), currentPageId: backupPageId }])\n\t\t\t\t\t\t\t} else if (source === 'user') {\n\t\t\t\t\t\t\t\t// fall back to ensureStoreIsUsable:\n\t\t\t\t\t\t\t\tthis.store.ensureStoreIsUsable()\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// delete the camera and state for the page if necessary\n\t\t\t\t\t\tconst cameraId = CameraRecordType.createId(record.id)\n\t\t\t\t\t\tconst instance_PageStateId = InstancePageStateRecordType.createId(record.id)\n\t\t\t\t\t\tthis.store.remove([cameraId, instance_PageStateId])\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tinstance: {\n\t\t\t\t\tafterChange: (prev, next, source) => {\n\t\t\t\t\t\t// instance should never be updated to a page that no longer exists (this can\n\t\t\t\t\t\t// happen when undoing a change that involves switching to a page that has since\n\t\t\t\t\t\t// been deleted by another user)\n\t\t\t\t\t\tif (!this.store.has(next.currentPageId)) {\n\t\t\t\t\t\t\tconst backupPageId = this.store.has(prev.currentPageId)\n\t\t\t\t\t\t\t\t? prev.currentPageId\n\t\t\t\t\t\t\t\t: this.getPages()[0]?.id\n\t\t\t\t\t\t\tif (backupPageId) {\n\t\t\t\t\t\t\t\tthis.store.update(next.id, (instance) => ({\n\t\t\t\t\t\t\t\t\t...instance,\n\t\t\t\t\t\t\t\t\tcurrentPageId: backupPageId,\n\t\t\t\t\t\t\t\t}))\n\t\t\t\t\t\t\t} else if (source === 'user') {\n\t\t\t\t\t\t\t\t// fall back to ensureStoreIsUsable:\n\t\t\t\t\t\t\t\tthis.store.ensureStoreIsUsable()\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tinstance_page_state: {\n\t\t\t\t\tafterChange: (prev, next) => {\n\t\t\t\t\t\tif (prev?.selectedShapeIds !== next?.selectedShapeIds) {\n\t\t\t\t\t\t\t// ensure that descendants and ancestors are not selected at the same time\n\t\t\t\t\t\t\tconst filtered = next.selectedShapeIds.filter((id) => {\n\t\t\t\t\t\t\t\tlet parentId = this.getShape(id)?.parentId\n\t\t\t\t\t\t\t\twhile (isShapeId(parentId)) {\n\t\t\t\t\t\t\t\t\tif (next.selectedShapeIds.includes(parentId)) {\n\t\t\t\t\t\t\t\t\t\treturn false\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tparentId = this.getShape(parentId)?.parentId\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\treturn true\n\t\t\t\t\t\t\t})\n\n\t\t\t\t\t\t\tlet nextFocusedGroupId: null | TLShapeId = null\n\n\t\t\t\t\t\t\tif (filtered.length > 0) {\n\t\t\t\t\t\t\t\tconst commonGroupAncestor = this.findCommonAncestor(\n\t\t\t\t\t\t\t\t\tcompact(filtered.map((id) => this.getShape(id))),\n\t\t\t\t\t\t\t\t\t(shape) => this.isShapeOfType(shape, 'group')\n\t\t\t\t\t\t\t\t)\n\n\t\t\t\t\t\t\t\tif (commonGroupAncestor) {\n\t\t\t\t\t\t\t\t\tnextFocusedGroupId = commonGroupAncestor\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tif (next?.focusedGroupId) {\n\t\t\t\t\t\t\t\t\tnextFocusedGroupId = next.focusedGroupId\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\tfiltered.length !== next.selectedShapeIds.length ||\n\t\t\t\t\t\t\t\tnextFocusedGroupId !== next.focusedGroupId\n\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\tthis.store.put([\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t...next,\n\t\t\t\t\t\t\t\t\t\tselectedShapeIds: filtered,\n\t\t\t\t\t\t\t\t\t\tfocusedGroupId: nextFocusedGroupId ?? null,\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t])\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t})\n\t\t)\n\n\t\tthis._currentPageShapeIds = deriveShapeIdsInCurrentPage(this.store, () =>\n\t\t\tthis.getCurrentPageId()\n\t\t)\n\t\tthis._parentIdsToChildIds = parentsToChildren(this.store)\n\n\t\tthis.disposables.add(\n\t\t\tthis.store.listen((changes) => {\n\t\t\t\tthis.emit('change', changes)\n\t\t\t})\n\t\t)\n\t\tthis.disposables.add(this.history.dispose)\n\n\t\tthis.run(\n\t\t\t() => {\n\t\t\t\tthis.store.ensureStoreIsUsable()\n\n\t\t\t\t// clear ephemeral state\n\t\t\t\tthis._updateCurrentPageState({\n\t\t\t\t\teditingShapeId: null,\n\t\t\t\t\thoveredShapeId: null,\n\t\t\t\t\terasingShapeIds: [],\n\t\t\t\t})\n\t\t\t},\n\t\t\t{ history: 'ignore' }\n\t\t)\n\n\t\tif (initialState && this.root.children[initialState] === undefined) {\n\t\t\tthrow Error(`No state found for initialState \"${initialState}\".`)\n\t\t}\n\n\t\tthis.root.enter(undefined, 'initial')\n\n\t\tthis.edgeScrollManager = new EdgeScrollManager(this)\n\t\tthis.focusManager = new FocusManager(this, autoFocus)\n\t\tthis.disposables.add(this.focusManager.dispose.bind(this.focusManager))\n\n\t\tif (this.getInstanceState().followingUserId) {\n\t\t\tthis.stopFollowingUser()\n\t\t}\n\n\t\tthis.on('tick', this._flushEventsForTick)\n\n\t\tthis.timers.requestAnimationFrame(() => {\n\t\t\tthis._tickManager.start()\n\t\t})\n\n\t\tthis.performanceTracker = new PerformanceTracker()\n\t}\n\n\tprivate readonly _isShapeHiddenPredicate?: (shape: TLShape, editor: Editor) => boolean\n\t@computed\n\tprivate getIsShapeHiddenCache() {\n\t\tif (!this._isShapeHiddenPredicate) return null\n\t\treturn this.store.createComputedCache('isShapeHidden', (shape: TLShape) => {\n\t\t\tconst hiddenParent = this.findShapeAncestor(shape, (p) => this.isShapeHidden(p))\n\t\t\tif (hiddenParent) return true\n\t\t\treturn this._isShapeHiddenPredicate!(shape, this) ?? false\n\t\t})\n\t}\n\tisShapeHidden(shapeOrId: TLShape | TLShapeId): boolean {\n\t\tif (!this._isShapeHiddenPredicate) return false\n\t\treturn !!this.getIsShapeHiddenCache!()!.get(\n\t\t\ttypeof shapeOrId === 'string' ? shapeOrId : shapeOrId.id\n\t\t)\n\t}\n\n\treadonly options: TldrawOptions\n\n\t/**\n\t * The editor's store\n\t *\n\t * @public\n\t */\n\treadonly store: TLStore\n\n\t/**\n\t * The root state of the statechart.\n\t *\n\t * @public\n\t */\n\treadonly root: StateNode\n\n\t/**\n\t * A set of functions to call when the app is disposed.\n\t *\n\t * @public\n\t */\n\treadonly disposables = new Set<() => void>()\n\n\t/**\n\t * Whether the editor is disposed.\n\t *\n\t * @public\n\t */\n\tisDisposed = false\n\n\t/** @internal */\n\tprivate readonly _tickManager\n\n\t/**\n\t * A manager for the app's snapping feature.\n\t *\n\t * @public\n\t */\n\treadonly snaps: SnapManager\n\n\t/**\n\t * A manager for the any asynchronous events and making sure they're\n\t * cleaned up upon disposal.\n\t *\n\t * @public\n\t */\n\treadonly timers: Timers\n\n\t/**\n\t * A manager for the user and their preferences.\n\t *\n\t * @public\n\t */\n\treadonly user: UserPreferencesManager\n\n\t/**\n\t * A helper for measuring text.\n\t *\n\t * @public\n\t */\n\treadonly textMeasure: TextManager\n\n\t/**\n\t * A manager for the editor's environment.\n\t *\n\t * @public\n\t */\n\treadonly environment: EnvironmentManager\n\n\t/**\n\t * A manager for the editor's scribbles.\n\t *\n\t * @public\n\t */\n\treadonly scribbles: ScribbleManager\n\n\t/**\n\t * A manager for side effects and correct state enforcement. See {@link @tldraw/store#StoreSideEffects} for details.\n\t *\n\t * @public\n\t */\n\treadonly sideEffects: StoreSideEffects\n\n\t/**\n\t * A manager for moving the camera when the mouse is at the edge of the screen.\n\t *\n\t * @public\n\t */\n\tedgeScrollManager: EdgeScrollManager\n\n\t/**\n\t * A manager for ensuring correct focus. See FocusManager for details.\n\t *\n\t * @internal\n\t */\n\tprivate focusManager: FocusManager\n\n\t/**\n\t * The current HTML element containing the editor.\n\t *\n\t * @example\n\t * ```ts\n\t * const container = editor.getContainer()\n\t * ```\n\t *\n\t * @public\n\t */\n\tgetContainer: () => HTMLElement\n\n\t/**\n\t * Dispose the editor.\n\t *\n\t * @public\n\t */\n\tdispose() {\n\t\tthis.disposables.forEach((dispose) => dispose())\n\t\tthis.disposables.clear()\n\t\tthis.isDisposed = true\n\t}\n\n\t/* ------------------- Shape Utils ------------------ */\n\n\t/**\n\t * A map of shape utility classes (TLShapeUtils) by shape type.\n\t *\n\t * @public\n\t */\n\tshapeUtils: { readonly [K in string]?: ShapeUtil }\n\n\tstyleProps: { [key: string]: Map, string> }\n\n\t/**\n\t * Get a shape util from a shape itself.\n\t *\n\t * @example\n\t * ```ts\n\t * const util = editor.getShapeUtil(myArrowShape)\n\t * const util = editor.getShapeUtil('arrow')\n\t * const util = editor.getShapeUtil(myArrowShape)\n\t * const util = editor.getShapeUtil(TLArrowShape)('arrow')\n\t * ```\n\t *\n\t * @param shape - A shape, shape partial, or shape type.\n\t *\n\t * @public\n\t */\n\tgetShapeUtil(shape: S | TLShapePartial): ShapeUtil\n\tgetShapeUtil(type: S['type']): ShapeUtil\n\tgetShapeUtil(type: T extends ShapeUtil ? R['type'] : string): T\n\tgetShapeUtil(arg: string | { type: string }) {\n\t\tconst type = typeof arg === 'string' ? arg : arg.type\n\t\tconst shapeUtil = getOwnProperty(this.shapeUtils, type)\n\t\tassert(shapeUtil, `No shape util found for type \"${type}\"`)\n\t\treturn shapeUtil\n\t}\n\n\t/* ------------------- Binding Utils ------------------ */\n\t/**\n\t * A map of shape utility classes (TLShapeUtils) by shape type.\n\t *\n\t * @public\n\t */\n\tbindingUtils: { readonly [K in string]?: BindingUtil }\n\n\t/**\n\t * Get a binding util from a binding itself.\n\t *\n\t * @example\n\t * ```ts\n\t * const util = editor.getBindingUtil(myArrowBinding)\n\t * const util = editor.getBindingUtil('arrow')\n\t * const util = editor.getBindingUtil(myArrowBinding)\n\t * const util = editor.getBindingUtil(TLArrowBinding)('arrow')\n\t * ```\n\t *\n\t * @param binding - A binding, binding partial, or binding type.\n\t *\n\t * @public\n\t */\n\tgetBindingUtil(binding: S | { type: S['type'] }): BindingUtil\n\tgetBindingUtil(type: S['type']): BindingUtil\n\tgetBindingUtil(\n\t\ttype: T extends BindingUtil ? R['type'] : string\n\t): T\n\tgetBindingUtil(arg: string | { type: string }) {\n\t\tconst type = typeof arg === 'string' ? arg : arg.type\n\t\tconst bindingUtil = getOwnProperty(this.bindingUtils, type)\n\t\tassert(bindingUtil, `No binding util found for type \"${type}\"`)\n\t\treturn bindingUtil\n\t}\n\n\t/* --------------------- History -------------------- */\n\n\t/**\n\t * A manager for the app's history.\n\t *\n\t * @readonly\n\t */\n\tprotected readonly history: HistoryManager\n\n\t/**\n\t * Undo to the last mark.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.undo()\n\t * ```\n\t *\n\t * @public\n\t */\n\tundo(): this {\n\t\tthis._flushEventsForTick(0)\n\t\tthis.complete()\n\t\tthis.history.undo()\n\t\treturn this\n\t}\n\n\t/**\n\t * Whether the app can undo.\n\t *\n\t * @public\n\t */\n\t@computed getCanUndo(): boolean {\n\t\treturn this.history.getNumUndos() > 0\n\t}\n\n\t/**\n\t * Redo to the next mark.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.redo()\n\t * ```\n\t *\n\t * @public\n\t */\n\tredo(): this {\n\t\tthis._flushEventsForTick(0)\n\t\tthis.complete()\n\t\tthis.history.redo()\n\t\treturn this\n\t}\n\n\tclearHistory() {\n\t\tthis.history.clear()\n\t\treturn this\n\t}\n\n\t/**\n\t * Whether the app can redo.\n\t *\n\t * @public\n\t */\n\t@computed getCanRedo(): boolean {\n\t\treturn this.history.getNumRedos() > 0\n\t}\n\n\t/**\n\t * Create a new \"mark\", or stopping point, in the undo redo history. Creating a mark will clear\n\t * any redos.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.mark()\n\t * editor.mark('flip shapes')\n\t * ```\n\t *\n\t * @param markId - The mark's id, usually the reason for adding the mark.\n\t *\n\t * @public\n\t * @deprecated use {@link Editor.markHistoryStoppingPoint} instead\n\t */\n\tmark(markId?: string): this {\n\t\tif (typeof markId === 'string') {\n\t\t\tconsole.warn(\n\t\t\t\t`[tldraw] \\`editor.history.mark(\"${markId}\")\\` is deprecated. Please use \\`const myMarkId = editor.markHistoryStoppingPoint()\\` instead.`\n\t\t\t)\n\t\t} else {\n\t\t\tconsole.warn(\n\t\t\t\t'[tldraw] `editor.mark()` is deprecated. Use `editor.markHistoryStoppingPoint()` instead.'\n\t\t\t)\n\t\t}\n\t\tthis.history._mark(markId ?? uniqueId())\n\t\treturn this\n\t}\n\n\t/**\n\t * Create a new \"mark\", or stopping point, in the undo redo history. Creating a mark will clear\n\t * any redos. You typically want to do this just before a user interaction begins or is handled.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.markHistoryStoppingPoint()\n\t * editor.flipShapes(editor.getSelectedShapes())\n\t * ```\n\t * @example\n\t * ```ts\n\t * const beginRotateMark = editor.markHistoryStoppingPoint()\n\t * // if the use cancels the rotation, you can bail back to this mark\n\t * editor.bailToMark(beginRotateMark)\n\t * ```\n\t *\n\t * @public\n\t * @param name - The name of the mark, useful for debugging the undo/redo stacks\n\t * @returns a unique id for the mark that can be used with `squashToMark` or `bailToMark`.\n\t */\n\tmarkHistoryStoppingPoint(name?: string): string {\n\t\tconst id = `[${name ?? 'stop'}]_${uniqueId()}`\n\t\tthis.history._mark(id)\n\t\treturn id\n\t}\n\n\t/**\n\t * @internal this is only used to implement some backwards-compatibility logic. Should be fine to delete after 6 months or whatever.\n\t */\n\tgetMarkIdMatching(idSubstring: string) {\n\t\treturn this.history.getMarkIdMatching(idSubstring)\n\t}\n\n\t/**\n\t * Coalesces all changes since the given mark into a single change, removing any intermediate marks.\n\t *\n\t * This is useful if you need to 'compress' the recent history to simplify the undo/redo experience of a complex interaction.\n\t *\n\t * @example\n\t * ```ts\n\t * const bumpShapesMark = editor.markHistoryStoppingPoint()\n\t * // ... some changes\n\t * editor.squashToMark(bumpShapesMark)\n\t * ```\n\t *\n\t * @param markId - The mark id to squash to.\n\t */\n\tsquashToMark(markId: string): this {\n\t\tthis.history.squashToMark(markId)\n\t\treturn this\n\t}\n\n\t/**\n\t * Undo to the closest mark, discarding the changes so they cannot be redone.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.bail()\n\t * ```\n\t *\n\t * @public\n\t */\n\tbail() {\n\t\tthis.history.bail()\n\t\treturn this\n\t}\n\n\t/**\n\t * Undo to the given mark, discarding the changes so they cannot be redone.\n\t *\n\t * @example\n\t * ```ts\n\t * const beginDrag = editor.markHistoryStoppingPoint()\n\t * // ... some changes\n\t * editor.bailToMark(beginDrag)\n\t * ```\n\t *\n\t * @public\n\t */\n\tbailToMark(id: string): this {\n\t\tthis.history.bailToMark(id)\n\t\treturn this\n\t}\n\n\tprivate _shouldIgnoreShapeLock = false\n\n\t/**\n\t * Run a function in a transaction with optional options for context.\n\t * You can use the options to change the way that history is treated\n\t * or allow changes to locked shapes.\n\t *\n\t * @example\n\t * ```ts\n\t * // updating with\n\t * editor.run(() => {\n\t * \teditor.updateShape({ ...myShape, x: 100 })\n\t * }, { history: \"ignore\" })\n\t *\n\t * // forcing changes / deletions for locked shapes\n\t * editor.toggleLock([myShape])\n\t * editor.run(() => {\n\t * \teditor.updateShape({ ...myShape, x: 100 })\n\t * \teditor.deleteShape(myShape)\n\t * }, { ignoreShapeLock: true }, )\n\t * ```\n\t *\n\t * @param fn - The callback function to run.\n\t * @param opts - The options for the batch.\n\t *\n\t *\n\t * @public\n\t */\n\trun(fn: () => void, opts?: TLEditorRunOptions): this {\n\t\tconst previousIgnoreShapeLock = this._shouldIgnoreShapeLock\n\t\tthis._shouldIgnoreShapeLock = opts?.ignoreShapeLock ?? previousIgnoreShapeLock\n\n\t\ttry {\n\t\t\tthis.history.batch(fn, opts)\n\t\t} finally {\n\t\t\tthis._shouldIgnoreShapeLock = previousIgnoreShapeLock\n\t\t}\n\n\t\treturn this\n\t}\n\n\t/**\n\t * @deprecated Use `Editor.run` instead.\n\t */\n\tbatch(fn: () => void, opts?: TLEditorRunOptions): this {\n\t\treturn this.run(fn, opts)\n\t}\n\n\t/* --------------------- Errors --------------------- */\n\n\t/** @internal */\n\tannotateError(\n\t\terror: unknown,\n\t\t{\n\t\t\torigin,\n\t\t\twillCrashApp,\n\t\t\ttags,\n\t\t\textras,\n\t\t}: {\n\t\t\torigin: string\n\t\t\twillCrashApp: boolean\n\t\t\ttags?: Record\n\t\t\textras?: Record\n\t\t}\n\t): this {\n\t\tconst defaultAnnotations = this.createErrorAnnotations(origin, willCrashApp)\n\t\tannotateError(error, {\n\t\t\ttags: { ...defaultAnnotations.tags, ...tags },\n\t\t\textras: { ...defaultAnnotations.extras, ...extras },\n\t\t})\n\t\tif (willCrashApp) {\n\t\t\tthis.store.markAsPossiblyCorrupted()\n\t\t}\n\t\treturn this\n\t}\n\n\t/** @internal */\n\tcreateErrorAnnotations(\n\t\torigin: string,\n\t\twillCrashApp: boolean | 'unknown'\n\t): {\n\t\ttags: { origin: string; willCrashApp: boolean | 'unknown' }\n\t\textras: {\n\t\t\tactiveStateNode?: string\n\t\t\tselectedShapes?: TLUnknownShape[]\n\t\t\teditingShape?: TLUnknownShape\n\t\t\tinputs?: Record\n\t\t}\n\t} {\n\t\ttry {\n\t\t\tconst editingShapeId = this.getEditingShapeId()\n\t\t\treturn {\n\t\t\t\ttags: {\n\t\t\t\t\torigin: origin,\n\t\t\t\t\twillCrashApp,\n\t\t\t\t},\n\t\t\t\textras: {\n\t\t\t\t\tactiveStateNode: this.root.getPath(),\n\t\t\t\t\tselectedShapes: this.getSelectedShapes(),\n\t\t\t\t\teditingShape: editingShapeId ? this.getShape(editingShapeId) : undefined,\n\t\t\t\t\tinputs: this.inputs,\n\t\t\t\t},\n\t\t\t}\n\t\t} catch {\n\t\t\treturn {\n\t\t\t\ttags: {\n\t\t\t\t\torigin: origin,\n\t\t\t\t\twillCrashApp,\n\t\t\t\t},\n\t\t\t\textras: {},\n\t\t\t}\n\t\t}\n\t}\n\n\t/** @internal */\n\tprivate _crashingError: unknown | null = null\n\n\t/**\n\t * We can't use an `atom` here because there's a chance that when `crashAndReportError` is called,\n\t * we're in a transaction that's about to be rolled back due to the same error we're currently\n\t * reporting.\n\t *\n\t * Instead, to listen to changes to this value, you need to listen to app's `crash` event.\n\t *\n\t * @internal\n\t */\n\tgetCrashingError() {\n\t\treturn this._crashingError\n\t}\n\n\t/** @internal */\n\tcrash(error: unknown): this {\n\t\tthis._crashingError = error\n\t\tthis.store.markAsPossiblyCorrupted()\n\t\tthis.emit('crash', { error })\n\t\treturn this\n\t}\n\n\t/* ------------------- Statechart ------------------- */\n\n\t/**\n\t * The editor's current path of active states.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getPath() // \"select.idle\"\n\t * ```\n\t *\n\t * @public\n\t */\n\t@computed getPath() {\n\t\treturn this.root.getPath().split('root.')[1]\n\t}\n\n\t/**\n\t * Get whether a certain tool (or other state node) is currently active.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.isIn('select')\n\t * editor.isIn('select.brushing')\n\t * ```\n\t *\n\t * @param path - The path of active states, separated by periods.\n\t *\n\t * @public\n\t */\n\tisIn(path: string): boolean {\n\t\tconst ids = path.split('.').reverse()\n\t\tlet state = this.root as StateNode\n\t\twhile (ids.length > 0) {\n\t\t\tconst id = ids.pop()\n\t\t\tif (!id) return true\n\t\t\tconst current = state.getCurrent()\n\t\t\tif (current?.id === id) {\n\t\t\t\tif (ids.length === 0) return true\n\t\t\t\tstate = current\n\t\t\t\tcontinue\n\t\t\t} else return false\n\t\t}\n\t\treturn false\n\t}\n\n\t/**\n\t * Get whether the state node is in any of the given active paths.\n\t *\n\t * @example\n\t * ```ts\n\t * state.isInAny('select', 'erase')\n\t * state.isInAny('select.brushing', 'erase.idle')\n\t * ```\n\t *\n\t * @public\n\t */\n\tisInAny(...paths: string[]): boolean {\n\t\treturn paths.some((path) => this.isIn(path))\n\t}\n\n\t/**\n\t * Set the selected tool.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.setCurrentTool('hand')\n\t * editor.setCurrentTool('hand', { date: Date.now() })\n\t * ```\n\t *\n\t * @param id - The id of the tool to select.\n\t * @param info - Arbitrary data to pass along into the transition.\n\t *\n\t * @public\n\t */\n\tsetCurrentTool(id: string, info = {}): this {\n\t\tthis.root.transition(id, info)\n\t\treturn this\n\t}\n\n\t/**\n\t * The current selected tool.\n\t *\n\t * @public\n\t */\n\t@computed getCurrentTool(): StateNode {\n\t\treturn this.root.getCurrent()!\n\t}\n\n\t/**\n\t * The id of the current selected tool.\n\t *\n\t * @public\n\t */\n\t@computed getCurrentToolId(): string {\n\t\tconst currentTool = this.getCurrentTool()\n\t\tif (!currentTool) return ''\n\t\treturn currentTool.getCurrentToolIdMask() ?? currentTool.id\n\t}\n\n\t/**\n\t * Get a descendant by its path.\n\t *\n\t * @example\n\t * ```ts\n\t * state.getStateDescendant('select')\n\t * state.getStateDescendant('select.brushing')\n\t * ```\n\t *\n\t * @param path - The descendant's path of state ids, separated by periods.\n\t *\n\t * @public\n\t */\n\tgetStateDescendant(path: string): T | undefined {\n\t\tconst ids = path.split('.').reverse()\n\t\tlet state = this.root as StateNode\n\t\twhile (ids.length > 0) {\n\t\t\tconst id = ids.pop()\n\t\t\tif (!id) return state as T\n\t\t\tconst childState = state.children?.[id]\n\t\t\tif (!childState) return undefined\n\t\t\tstate = childState\n\t\t}\n\t\treturn state as T\n\t}\n\n\t/* ---------------- Document Settings --------------- */\n\n\t/**\n\t * The global document settings that apply to all users.\n\t *\n\t * @public\n\t **/\n\t@computed getDocumentSettings() {\n\t\treturn this.store.get(TLDOCUMENT_ID)!\n\t}\n\n\t/**\n\t * Update the global document settings that apply to all users.\n\t *\n\t * @public\n\t **/\n\tupdateDocumentSettings(settings: Partial): this {\n\t\tthis.run(\n\t\t\t() => {\n\t\t\t\tthis.store.put([{ ...this.getDocumentSettings(), ...settings }])\n\t\t\t},\n\t\t\t{ history: 'ignore' }\n\t\t)\n\t\treturn this\n\t}\n\n\t/* ----------------- Instance State ----------------- */\n\n\t/**\n\t * The current instance's state.\n\t *\n\t * @public\n\t */\n\t@computed getInstanceState(): TLInstance {\n\t\treturn this.store.get(TLINSTANCE_ID)!\n\t}\n\n\t/**\n\t * Update the instance's state.\n\t *\n\t * @param partial - A partial object to update the instance state with.\n\t *\n\t * @public\n\t */\n\tupdateInstanceState(\n\t\tpartial: Partial>,\n\t\thistoryOptions?: TLHistoryBatchOptions\n\t): this {\n\t\tthis._updateInstanceState(partial, { history: 'ignore', ...historyOptions })\n\n\t\tif (partial.isChangingStyle !== undefined) {\n\t\t\tclearTimeout(this._isChangingStyleTimeout)\n\t\t\tif (partial.isChangingStyle === true) {\n\t\t\t\t// If we've set to true, set a new reset timeout to change the value back to false after 2 seconds\n\t\t\t\tthis._isChangingStyleTimeout = this.timers.setTimeout(() => {\n\t\t\t\t\tthis._updateInstanceState({ isChangingStyle: false }, { history: 'ignore' })\n\t\t\t\t}, 2000)\n\t\t\t}\n\t\t}\n\n\t\treturn this\n\t}\n\n\t/** @internal */\n\t_updateInstanceState(\n\t\tpartial: Partial>,\n\t\topts?: TLHistoryBatchOptions\n\t) {\n\t\tthis.run(() => {\n\t\t\tthis.store.put([\n\t\t\t\t{\n\t\t\t\t\t...this.getInstanceState(),\n\t\t\t\t\t...partial,\n\t\t\t\t},\n\t\t\t])\n\t\t}, opts)\n\t}\n\n\t/** @internal */\n\tprivate _isChangingStyleTimeout = -1 as any\n\n\t// Menus\n\n\t/**\n\t * A set of strings representing any open menus. When menus are open,\n\t * certain interactions will behave differently; for example, when a\n\t * draw tool is selected and a menu is open, a pointer-down will not\n\t * create a dot (because the user is probably trying to close the menu)\n\t * however a pointer-down event followed by a drag will begin drawing\n\t * a line (because the user is BOTH trying to close the menu AND start\n\t * drawing a line).\n\t *\n\t * @public\n\t */\n\t@computed getOpenMenus(): string[] {\n\t\treturn this.getInstanceState().openMenus\n\t}\n\n\t/**\n\t * Add an open menu.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.addOpenMenu('menu-id')\n\t * ```\n\t *\n\t * @public\n\t */\n\taddOpenMenu(id: string): this {\n\t\tconst menus = new Set(this.getOpenMenus())\n\t\tif (!menus.has(id)) {\n\t\t\tmenus.add(id)\n\t\t\tthis.updateInstanceState({ openMenus: [...menus] })\n\t\t}\n\t\treturn this\n\t}\n\n\t/**\n\t * Delete an open menu.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.deleteOpenMenu('menu-id')\n\t * ```\n\t *\n\t * @public\n\t */\n\tdeleteOpenMenu(id: string): this {\n\t\tconst menus = new Set(this.getOpenMenus())\n\t\tif (menus.has(id)) {\n\t\t\tmenus.delete(id)\n\t\t\tthis.updateInstanceState({ openMenus: [...menus] })\n\t\t}\n\t\treturn this\n\t}\n\n\t/**\n\t * Clear all open menus.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.clearOpenMenus()\n\t * ```\n\t *\n\t * @public\n\t */\n\tclearOpenMenus(): this {\n\t\tif (this.getOpenMenus().length) {\n\t\t\tthis.updateInstanceState({ openMenus: [] })\n\t\t}\n\t\treturn this\n\t}\n\n\t/**\n\t * Get whether any menus are open.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getIsMenuOpen()\n\t * ```\n\t *\n\t * @public\n\t */\n\t@computed getIsMenuOpen(): boolean {\n\t\treturn this.getOpenMenus().length > 0\n\t}\n\n\t/* --------------------- Cursor --------------------- */\n\n\t/**\n\t * Set the cursor.\n\t *\n\t * @param type - The cursor type.\n\t * @param rotation - The cursor rotation.\n\t *\n\t * @public\n\t */\n\tsetCursor(cursor: Partial) {\n\t\tthis.updateInstanceState({ cursor: { ...this.getInstanceState().cursor, ...cursor } })\n\t\treturn this\n\t}\n\n\t/* ------------------- Page State ------------------- */\n\n\t/**\n\t * Page states.\n\t *\n\t * @public\n\t */\n\t@computed getPageStates(): TLInstancePageState[] {\n\t\treturn this._getPageStatesQuery().get()\n\t}\n\n\t/** @internal */\n\t@computed private _getPageStatesQuery() {\n\t\treturn this.store.query.records('instance_page_state')\n\t}\n\n\t/**\n\t * The current page state.\n\t *\n\t * @public\n\t */\n\t@computed getCurrentPageState(): TLInstancePageState {\n\t\treturn this.store.get(this._getCurrentPageStateId())!\n\t}\n\n\t/** @internal */\n\t@computed private _getCurrentPageStateId() {\n\t\treturn InstancePageStateRecordType.createId(this.getCurrentPageId())\n\t}\n\n\t/**\n\t * Update this instance's page state.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.updateCurrentPageState({ id: 'page1', editingShapeId: 'shape:123' })\n\t * ```\n\t *\n\t * @param partial - The partial of the page state object containing the changes.\n\t *\n\t * @public\n\t */\n\tupdateCurrentPageState(\n\t\tpartial: Partial<\n\t\t\tOmit\n\t\t>\n\t): this {\n\t\tthis._updateCurrentPageState(partial)\n\t\treturn this\n\t}\n\t_updateCurrentPageState(partial: Partial>) {\n\t\tthis.store.update(partial.id ?? this.getCurrentPageState().id, (state) => ({\n\t\t\t...state,\n\t\t\t...partial,\n\t\t}))\n\t}\n\n\t/**\n\t * The current selected ids.\n\t *\n\t * @public\n\t */\n\t@computed getSelectedShapeIds() {\n\t\treturn this.getCurrentPageState().selectedShapeIds\n\t}\n\n\t/**\n\t * An array containing all of the currently selected shapes.\n\t *\n\t * @public\n\t * @readonly\n\t */\n\t@computed getSelectedShapes(): TLShape[] {\n\t\tconst { selectedShapeIds } = this.getCurrentPageState()\n\t\treturn compact(selectedShapeIds.map((id) => this.store.get(id)))\n\t}\n\n\t/**\n\t * Select one or more shapes.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.setSelectedShapes(['id1'])\n\t * editor.setSelectedShapes(['id1', 'id2'])\n\t * ```\n\t *\n\t * @param ids - The ids to select.\n\t *\n\t * @public\n\t */\n\tsetSelectedShapes(shapes: TLShapeId[] | TLShape[]): this {\n\t\treturn this.run(\n\t\t\t() => {\n\t\t\t\tconst ids = shapes.map((shape) => (typeof shape === 'string' ? shape : shape.id))\n\t\t\t\tconst { selectedShapeIds: prevSelectedShapeIds } = this.getCurrentPageState()\n\t\t\t\tconst prevSet = new Set(prevSelectedShapeIds)\n\n\t\t\t\tif (ids.length === prevSet.size && ids.every((id) => prevSet.has(id))) return null\n\n\t\t\t\tthis.store.put([{ ...this.getCurrentPageState(), selectedShapeIds: ids }])\n\t\t\t},\n\t\t\t{ history: 'record-preserveRedoStack' }\n\t\t)\n\t}\n\n\t/**\n\t * Determine whether or not any of a shape's ancestors are selected.\n\t *\n\t * @param id - The id of the shape to check.\n\t *\n\t * @public\n\t */\n\tisAncestorSelected(shape: TLShape | TLShapeId): boolean {\n\t\tconst id = typeof shape === 'string' ? shape : shape?.id ?? null\n\t\tconst _shape = this.getShape(id)\n\t\tif (!_shape) return false\n\t\tconst selectedShapeIds = this.getSelectedShapeIds()\n\t\treturn !!this.findShapeAncestor(_shape, (parent) => selectedShapeIds.includes(parent.id))\n\t}\n\n\t/**\n\t * Select one or more shapes.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.select('id1')\n\t * editor.select('id1', 'id2')\n\t * ```\n\t *\n\t * @param ids - The ids to select.\n\t *\n\t * @public\n\t */\n\tselect(...shapes: TLShapeId[] | TLShape[]): this {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((shape) => shape.id)\n\t\tthis.setSelectedShapes(ids)\n\t\treturn this\n\t}\n\n\t/**\n\t * Remove a shape from the existing set of selected shapes.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.deselect(shape.id)\n\t * ```\n\t *\n\t * @public\n\t */\n\tdeselect(...shapes: TLShapeId[] | TLShape[]): this {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((shape) => shape.id)\n\t\tconst selectedShapeIds = this.getSelectedShapeIds()\n\t\tif (selectedShapeIds.length > 0 && ids.length > 0) {\n\t\t\tthis.setSelectedShapes(selectedShapeIds.filter((id) => !ids.includes(id)))\n\t\t}\n\t\treturn this\n\t}\n\n\t/**\n\t * Select all direct children of the current page.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.selectAll()\n\t * ```\n\t *\n\t * @public\n\t */\n\tselectAll(): this {\n\t\tconst ids = this.getSortedChildIdsForParent(this.getCurrentPageId())\n\t\t// page might have no shapes\n\t\tif (ids.length <= 0) return this\n\t\tthis.setSelectedShapes(this._getUnlockedShapeIds(ids))\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Clear the selection.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.selectNone()\n\t * ```\n\t *\n\t * @public\n\t */\n\tselectNone(): this {\n\t\tif (this.getSelectedShapeIds().length > 0) {\n\t\t\tthis.setSelectedShapes([])\n\t\t}\n\n\t\treturn this\n\t}\n\n\t/**\n\t * The id of the app's only selected shape.\n\t *\n\t * @returns Null if there is no shape or more than one selected shape, otherwise the selected shape's id.\n\t *\n\t * @public\n\t * @readonly\n\t */\n\t@computed getOnlySelectedShapeId(): TLShapeId | null {\n\t\treturn this.getOnlySelectedShape()?.id ?? null\n\t}\n\n\t/**\n\t * The app's only selected shape.\n\t *\n\t * @returns Null if there is no shape or more than one selected shape, otherwise the selected shape.\n\t *\n\t * @public\n\t * @readonly\n\t */\n\t@computed getOnlySelectedShape(): TLShape | null {\n\t\tconst selectedShapes = this.getSelectedShapes()\n\t\treturn selectedShapes.length === 1 ? selectedShapes[0] : null\n\t}\n\n\t/**\n\t * @internal\n\t */\n\tgetShapesPageBounds(shapeIds: TLShapeId[]): Box | null {\n\t\tconst bounds = compact(shapeIds.map((id) => this.getShapePageBounds(id)))\n\t\tif (bounds.length === 0) return null\n\t\treturn Box.Common(bounds)\n\t}\n\n\t/**\n\t * The current page bounds of all the selected shapes. If the\n\t * selection is rotated, then these bounds are the axis-aligned\n\t * box that the rotated bounds would fit inside of.\n\t *\n\t * @readonly\n\t *\n\t * @public\n\t */\n\t@computed getSelectionPageBounds(): Box | null {\n\t\treturn this.getShapesPageBounds(this.getSelectedShapeIds())\n\t}\n\n\t/**\n\t * @internal\n\t */\n\tgetShapesSharedRotation(shapeIds: TLShapeId[]) {\n\t\tlet foundFirst = false // annoying but we can't use an i===0 check because we need to skip over undefineds\n\t\tlet rotation = 0\n\t\tfor (let i = 0, n = shapeIds.length; i < n; i++) {\n\t\t\tconst pageTransform = this.getShapePageTransform(shapeIds[i])\n\t\t\tif (!pageTransform) continue\n\t\t\tif (foundFirst) {\n\t\t\t\tif (pageTransform.rotation() !== rotation) {\n\t\t\t\t\t// There are at least 2 different rotations, so the common rotation is zero\n\t\t\t\t\treturn 0\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// First rotation found\n\t\t\t\tfoundFirst = true\n\t\t\t\trotation = pageTransform.rotation()\n\t\t\t}\n\t\t}\n\n\t\treturn rotation\n\t}\n\n\t/**\n\t * The rotation of the selection bounding box in the current page space.\n\t *\n\t * @readonly\n\t * @public\n\t */\n\t@computed getSelectionRotation(): number {\n\t\treturn this.getShapesSharedRotation(this.getSelectedShapeIds())\n\t}\n\n\t/**\n\t * @internal\n\t */\n\tgetShapesRotatedPageBounds(shapeIds: TLShapeId[]): Box | undefined {\n\t\tif (shapeIds.length === 0) {\n\t\t\treturn undefined\n\t\t}\n\n\t\tconst selectionRotation = this.getShapesSharedRotation(shapeIds)\n\t\tif (selectionRotation === 0) {\n\t\t\treturn this.getShapesPageBounds(shapeIds) ?? undefined\n\t\t}\n\n\t\tif (shapeIds.length === 1) {\n\t\t\tconst bounds = this.getShapeGeometry(shapeIds[0]).bounds.clone()\n\t\t\tconst pageTransform = this.getShapePageTransform(shapeIds[0])!\n\t\t\tbounds.point = pageTransform.applyToPoint(bounds.point)\n\t\t\treturn bounds\n\t\t}\n\n\t\t// need to 'un-rotate' all the outlines of the existing nodes so we can fit them inside a box\n\t\tconst boxFromRotatedVertices = Box.FromPoints(\n\t\t\tshapeIds\n\t\t\t\t.flatMap((id) => {\n\t\t\t\t\tconst pageTransform = this.getShapePageTransform(id)\n\t\t\t\t\tif (!pageTransform) return []\n\t\t\t\t\treturn pageTransform.applyToPoints(this.getShapeGeometry(id).bounds.corners)\n\t\t\t\t})\n\t\t\t\t.map((p) => p.rot(-selectionRotation))\n\t\t)\n\t\t// now position box so that it's top-left corner is in the right place\n\t\tboxFromRotatedVertices.point = boxFromRotatedVertices.point.rot(selectionRotation)\n\t\treturn boxFromRotatedVertices\n\t}\n\n\t/**\n\t * The bounds of the selection bounding box in the current page space.\n\t *\n\t * @readonly\n\t * @public\n\t */\n\t@computed getSelectionRotatedPageBounds(): Box | undefined {\n\t\treturn this.getShapesRotatedPageBounds(this.getSelectedShapeIds())\n\t}\n\n\t/**\n\t * The bounds of the selection bounding box in the current page space.\n\t *\n\t * @readonly\n\t * @public\n\t */\n\t@computed getSelectionRotatedScreenBounds(): Box | undefined {\n\t\tconst bounds = this.getSelectionRotatedPageBounds()\n\t\tif (!bounds) return undefined\n\t\tconst { x, y } = this.pageToScreen(bounds.point)\n\t\tconst zoom = this.getZoomLevel()\n\t\treturn new Box(x, y, bounds.width * zoom, bounds.height * zoom)\n\t}\n\n\t// Focus Group\n\n\t/**\n\t * The current focused group id.\n\t *\n\t * @public\n\t */\n\t@computed getFocusedGroupId(): TLShapeId | TLPageId {\n\t\treturn this.getCurrentPageState().focusedGroupId ?? this.getCurrentPageId()\n\t}\n\n\t/**\n\t * The current focused group.\n\t *\n\t * @public\n\t */\n\t@computed getFocusedGroup(): TLShape | undefined {\n\t\tconst focusedGroupId = this.getFocusedGroupId()\n\t\treturn focusedGroupId ? this.getShape(focusedGroupId) : undefined\n\t}\n\n\t/**\n\t * Set the current focused group shape.\n\t *\n\t * @param shape - The group shape id (or group shape's id) to set as the focused group shape.\n\t *\n\t * @public\n\t */\n\tsetFocusedGroup(shape: TLShapeId | TLGroupShape | null): this {\n\t\tconst id = typeof shape === 'string' ? shape : shape?.id ?? null\n\n\t\tif (id !== null) {\n\t\t\tconst shape = this.getShape(id)\n\t\t\tif (!shape) {\n\t\t\t\tthrow Error(`Editor.setFocusedGroup: Shape with id ${id} does not exist`)\n\t\t\t}\n\n\t\t\tif (!this.isShapeOfType(shape, 'group')) {\n\t\t\t\tthrow Error(\n\t\t\t\t\t`Editor.setFocusedGroup: Cannot set focused group to shape of type ${shape.type}`\n\t\t\t\t)\n\t\t\t}\n\t\t}\n\n\t\tif (id === this.getFocusedGroupId()) return this\n\n\t\treturn this.run(\n\t\t\t() => {\n\t\t\t\tthis.store.update(this.getCurrentPageState().id, (s) => ({ ...s, focusedGroupId: id }))\n\t\t\t},\n\t\t\t{ history: 'record-preserveRedoStack' }\n\t\t)\n\t}\n\n\t/**\n\t * Exit the current focused group, moving up to the next parent group if there is one.\n\t *\n\t * @public\n\t */\n\tpopFocusedGroupId(): this {\n\t\tconst focusedGroup = this.getFocusedGroup()\n\n\t\tif (focusedGroup) {\n\t\t\t// If we have a focused layer, look for an ancestor of the focused shape that is a group\n\t\t\tconst match = this.findShapeAncestor(focusedGroup, (shape) =>\n\t\t\t\tthis.isShapeOfType(shape, 'group')\n\t\t\t)\n\t\t\t// If we have an ancestor that can become a focused layer, set it as the focused layer\n\t\t\tthis.setFocusedGroup(match?.id ?? null)\n\t\t\tthis.select(focusedGroup.id)\n\t\t} else {\n\t\t\t// If there's no parent focused group, then clear the focus layer and clear selection\n\t\t\tthis.setFocusedGroup(null)\n\t\t\tthis.selectNone()\n\t\t}\n\n\t\treturn this\n\t}\n\n\t/**\n\t * The current editing shape's id.\n\t *\n\t * @public\n\t */\n\t@computed getEditingShapeId(): TLShapeId | null {\n\t\treturn this.getCurrentPageState().editingShapeId\n\t}\n\n\t/**\n\t * The current editing shape.\n\t *\n\t * @public\n\t */\n\t@computed getEditingShape(): TLShape | undefined {\n\t\tconst editingShapeId = this.getEditingShapeId()\n\t\treturn editingShapeId ? this.getShape(editingShapeId) : undefined\n\t}\n\n\t/**\n\t * Set the current editing shape.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.setEditingShape(myShape)\n\t * editor.setEditingShape(myShape.id)\n\t * ```\n\t *\n\t * @param shape - The shape (or shape id) to set as editing.\n\t *\n\t * @public\n\t */\n\tsetEditingShape(shape: TLShapeId | TLShape | null): this {\n\t\tconst id = typeof shape === 'string' ? shape : shape?.id ?? null\n\t\tif (id !== this.getEditingShapeId()) {\n\t\t\tif (id) {\n\t\t\t\tconst shape = this.getShape(id)\n\t\t\t\tif (shape && this.getShapeUtil(shape).canEdit(shape)) {\n\t\t\t\t\tthis.run(\n\t\t\t\t\t\t() => {\n\t\t\t\t\t\t\tthis._updateCurrentPageState({ editingShapeId: id })\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{ history: 'ignore' }\n\t\t\t\t\t)\n\t\t\t\t\treturn this\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Either we just set the editing id to null, or the shape was missing or not editable\n\t\t\tthis.run(\n\t\t\t\t() => {\n\t\t\t\t\tthis._updateCurrentPageState({ editingShapeId: null })\n\t\t\t\t},\n\t\t\t\t{ history: 'ignore' }\n\t\t\t)\n\t\t}\n\t\treturn this\n\t}\n\n\t// Hovered\n\n\t/**\n\t * The current hovered shape id.\n\t *\n\t * @readonly\n\t * @public\n\t */\n\t@computed getHoveredShapeId(): TLShapeId | null {\n\t\treturn this.getCurrentPageState().hoveredShapeId\n\t}\n\n\t/**\n\t * The current hovered shape.\n\t *\n\t * @public\n\t */\n\t@computed getHoveredShape(): TLShape | undefined {\n\t\tconst hoveredShapeId = this.getHoveredShapeId()\n\t\treturn hoveredShapeId ? this.getShape(hoveredShapeId) : undefined\n\t}\n\t/**\n\t * Set the editor's current hovered shape.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.setHoveredShape(myShape)\n\t * editor.setHoveredShape(myShape.id)\n\t * ```\n\t *\n\t * @param shapes - The shape (or shape id) to set as hovered.\n\t *\n\t * @public\n\t */\n\tsetHoveredShape(shape: TLShapeId | TLShape | null): this {\n\t\tconst id = typeof shape === 'string' ? shape : shape?.id ?? null\n\t\tif (id === this.getHoveredShapeId()) return this\n\t\tthis.run(\n\t\t\t() => {\n\t\t\t\tthis.updateCurrentPageState({ hoveredShapeId: id })\n\t\t\t},\n\t\t\t{ history: 'ignore' }\n\t\t)\n\t\treturn this\n\t}\n\n\t// Hinting\n\n\t/**\n\t * The editor's current hinting shape ids.\n\t *\n\t * @public\n\t */\n\t@computed getHintingShapeIds() {\n\t\treturn this.getCurrentPageState().hintingShapeIds\n\t}\n\t/**\n\t * The editor's current hinting shapes.\n\t *\n\t * @public\n\t */\n\t@computed getHintingShape() {\n\t\tconst hintingShapeIds = this.getHintingShapeIds()\n\t\treturn compact(hintingShapeIds.map((id) => this.getShape(id)))\n\t}\n\n\t/**\n\t * Set the editor's current hinting shapes.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.setHintingShapes([myShape])\n\t * editor.setHintingShapes([myShape.id])\n\t * ```\n\t *\n\t * @param shapes - The shapes (or shape ids) to set as hinting.\n\t *\n\t * @public\n\t */\n\tsetHintingShapes(shapes: TLShapeId[] | TLShape[]): this {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((shape) => shape.id)\n\t\t// always ephemeral\n\t\tthis.run(\n\t\t\t() => {\n\t\t\t\tthis._updateCurrentPageState({ hintingShapeIds: dedupe(ids) })\n\t\t\t},\n\t\t\t{ history: 'ignore' }\n\t\t)\n\t\treturn this\n\t}\n\n\t// Erasing\n\n\t/**\n\t * The editor's current erasing ids.\n\t *\n\t * @public\n\t */\n\t@computed getErasingShapeIds() {\n\t\treturn this.getCurrentPageState().erasingShapeIds\n\t}\n\n\t/**\n\t * The editor's current erasing shapes.\n\t *\n\t * @public\n\t */\n\t@computed getErasingShapes() {\n\t\tconst erasingShapeIds = this.getErasingShapeIds()\n\t\treturn compact(erasingShapeIds.map((id) => this.getShape(id)))\n\t}\n\n\t/**\n\t * Set the editor's current erasing shapes.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.setErasingShapes([myShape])\n\t * editor.setErasingShapes([myShape.id])\n\t * ```\n\t *\n\t * @param shapes - The shapes (or shape ids) to set as hinting.\n\t *\n\t * @public\n\t */\n\tsetErasingShapes(shapes: TLShapeId[] | TLShape[]): this {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((shape) => shape.id)\n\t\tids.sort() // sort the incoming ids\n\t\tconst erasingShapeIds = this.getErasingShapeIds()\n\t\tthis.run(\n\t\t\t() => {\n\t\t\t\tif (ids.length === erasingShapeIds.length) {\n\t\t\t\t\t// if the new ids are the same length as the current ids, they might be the same.\n\t\t\t\t\t// presuming the current ids are also sorted, check each item to see if it's the same;\n\t\t\t\t\t// if we find any unequal, then we know the new ids are different.\n\t\t\t\t\tfor (let i = 0; i < ids.length; i++) {\n\t\t\t\t\t\tif (ids[i] !== erasingShapeIds[i]) {\n\t\t\t\t\t\t\tthis._updateCurrentPageState({ erasingShapeIds: ids })\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t// if the ids are a different length, then we know they're different.\n\t\t\t\t\tthis._updateCurrentPageState({ erasingShapeIds: ids })\n\t\t\t\t}\n\t\t\t},\n\t\t\t{ history: 'ignore' }\n\t\t)\n\n\t\treturn this\n\t}\n\n\t// Cropping\n\n\t/**\n\t * The current cropping shape's id.\n\t *\n\t * @public\n\t */\n\tgetCroppingShapeId() {\n\t\treturn this.getCurrentPageState().croppingShapeId\n\t}\n\n\t/**\n\t * Set the current cropping shape.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.setCroppingShape(myShape)\n\t * editor.setCroppingShape(myShape.id)\n\t * ```\n\t *\n\t *\n\t * @param shape - The shape (or shape id) to set as cropping.\n\t *\n\t * @public\n\t */\n\tsetCroppingShape(shape: TLShapeId | TLShape | null): this {\n\t\tconst id = typeof shape === 'string' ? shape : shape?.id ?? null\n\t\tif (id !== this.getCroppingShapeId()) {\n\t\t\tthis.run(\n\t\t\t\t() => {\n\t\t\t\t\tif (!id) {\n\t\t\t\t\t\tthis.updateCurrentPageState({ croppingShapeId: null })\n\t\t\t\t\t} else {\n\t\t\t\t\t\tconst shape = this.getShape(id)!\n\t\t\t\t\t\tconst util = this.getShapeUtil(shape)\n\t\t\t\t\t\tif (shape && util.canCrop(shape)) {\n\t\t\t\t\t\t\tthis.updateCurrentPageState({ croppingShapeId: id })\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\t{ history: 'ignore' }\n\t\t\t)\n\t\t}\n\t\treturn this\n\t}\n\n\t/* --------------------- Camera --------------------- */\n\n\t/** @internal */\n\t@computed\n\tprivate _unsafe_getCameraId() {\n\t\treturn CameraRecordType.createId(this.getCurrentPageId())\n\t}\n\n\t/**\n\t * The current camera.\n\t *\n\t * @public\n\t */\n\t@computed getCamera(): TLCamera {\n\t\tconst baseCamera = this.store.get(this._unsafe_getCameraId())!\n\t\tif (this._isLockedOnFollowingUser.get()) {\n\t\t\tconst followingCamera = this.getCameraForFollowing()\n\t\t\tif (followingCamera) {\n\t\t\t\treturn { ...baseCamera, ...followingCamera }\n\t\t\t}\n\t\t}\n\t\treturn baseCamera\n\t}\n\n\t@computed\n\tprivate getViewportPageBoundsForFollowing(): null | Box {\n\t\tconst followingUserId = this.getInstanceState().followingUserId\n\t\tif (!followingUserId) return null\n\t\tconst leaderPresence = this.getCollaborators().find((c) => c.userId === followingUserId)\n\t\tif (!leaderPresence) return null\n\n\t\t// Fit their viewport inside of our screen bounds\n\t\t// 1. calculate their viewport in page space\n\t\tconst { w: lw, h: lh } = leaderPresence.screenBounds\n\t\tconst { x: lx, y: ly, z: lz } = leaderPresence.camera\n\t\tconst theirViewport = new Box(-lx, -ly, lw / lz, lh / lz)\n\n\t\t// resize our screenBounds to contain their viewport\n\t\tconst ourViewport = this.getViewportScreenBounds().clone()\n\t\tconst ourAspectRatio = ourViewport.width / ourViewport.height\n\n\t\tourViewport.width = theirViewport.width\n\t\tourViewport.height = ourViewport.width / ourAspectRatio\n\t\tif (ourViewport.height < theirViewport.height) {\n\t\t\tourViewport.height = theirViewport.height\n\t\t\tourViewport.width = ourViewport.height * ourAspectRatio\n\t\t}\n\n\t\tourViewport.center = theirViewport.center\n\t\treturn ourViewport\n\t}\n\n\t@computed\n\tprivate getCameraForFollowing(): null | { x: number; y: number; z: number } {\n\t\tconst viewport = this.getViewportPageBoundsForFollowing()\n\t\tif (!viewport) return null\n\n\t\treturn {\n\t\t\tx: -viewport.x,\n\t\t\ty: -viewport.y,\n\t\t\tz: this.getViewportScreenBounds().w / viewport.width,\n\t\t}\n\t}\n\n\t/**\n\t * The current camera zoom level.\n\t *\n\t * @public\n\t */\n\t@computed getZoomLevel() {\n\t\treturn this.getCamera().z\n\t}\n\n\t/**\n\t * Get the camera's initial or reset zoom level.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getInitialZoom()\n\t * ```\n\t *\n\t * @public */\n\tgetInitialZoom() {\n\t\tconst cameraOptions = this.getCameraOptions()\n\t\t// If no camera constraints are provided, the default zoom is 100%\n\t\tif (!cameraOptions.constraints) return 1\n\n\t\t// When defaultZoom is default, the default zoom is 100%\n\t\tif (cameraOptions.constraints.initialZoom === 'default') return 1\n\n\t\tconst { zx, zy } = getCameraFitXFitY(this, cameraOptions)\n\n\t\tswitch (cameraOptions.constraints.initialZoom) {\n\t\t\tcase 'fit-min': {\n\t\t\t\treturn Math.max(zx, zy)\n\t\t\t}\n\t\t\tcase 'fit-max': {\n\t\t\t\treturn Math.min(zx, zy)\n\t\t\t}\n\t\t\tcase 'fit-x': {\n\t\t\t\treturn zx\n\t\t\t}\n\t\t\tcase 'fit-y': {\n\t\t\t\treturn zy\n\t\t\t}\n\t\t\tcase 'fit-min-100': {\n\t\t\t\treturn Math.min(1, Math.max(zx, zy))\n\t\t\t}\n\t\t\tcase 'fit-max-100': {\n\t\t\t\treturn Math.min(1, Math.min(zx, zy))\n\t\t\t}\n\t\t\tcase 'fit-x-100': {\n\t\t\t\treturn Math.min(1, zx)\n\t\t\t}\n\t\t\tcase 'fit-y-100': {\n\t\t\t\treturn Math.min(1, zy)\n\t\t\t}\n\t\t\tdefault: {\n\t\t\t\tthrow exhaustiveSwitchError(cameraOptions.constraints.initialZoom)\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Get the camera's base level for calculating actual zoom levels based on the zoom steps.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getBaseZoom()\n\t * ```\n\t *\n\t * @public */\n\tgetBaseZoom() {\n\t\tconst cameraOptions = this.getCameraOptions()\n\t\t// If no camera constraints are provided, the default zoom is 100%\n\t\tif (!cameraOptions.constraints) return 1\n\n\t\t// When defaultZoom is default, the default zoom is 100%\n\t\tif (cameraOptions.constraints.baseZoom === 'default') return 1\n\n\t\tconst { zx, zy } = getCameraFitXFitY(this, cameraOptions)\n\n\t\tswitch (cameraOptions.constraints.baseZoom) {\n\t\t\tcase 'fit-min': {\n\t\t\t\treturn Math.max(zx, zy)\n\t\t\t}\n\t\t\tcase 'fit-max': {\n\t\t\t\treturn Math.min(zx, zy)\n\t\t\t}\n\t\t\tcase 'fit-x': {\n\t\t\t\treturn zx\n\t\t\t}\n\t\t\tcase 'fit-y': {\n\t\t\t\treturn zy\n\t\t\t}\n\t\t\tcase 'fit-min-100': {\n\t\t\t\treturn Math.min(1, Math.max(zx, zy))\n\t\t\t}\n\t\t\tcase 'fit-max-100': {\n\t\t\t\treturn Math.min(1, Math.min(zx, zy))\n\t\t\t}\n\t\t\tcase 'fit-x-100': {\n\t\t\t\treturn Math.min(1, zx)\n\t\t\t}\n\t\t\tcase 'fit-y-100': {\n\t\t\t\treturn Math.min(1, zy)\n\t\t\t}\n\t\t\tdefault: {\n\t\t\t\tthrow exhaustiveSwitchError(cameraOptions.constraints.baseZoom)\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate _cameraOptions = atom('camera options', DEFAULT_CAMERA_OPTIONS)\n\n\t/**\n\t * Get the current camera options.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getCameraOptions()\n\t * ```\n\t *\n\t * @public */\n\tgetCameraOptions() {\n\t\treturn this._cameraOptions.get()\n\t}\n\n\t/**\n\t * Set the camera options. Changing the options won't immediately change the camera itself, so you may want to call `setCamera` after changing the options.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.setCameraOptions(myCameraOptions)\n\t * editor.setCamera(editor.getCamera())\n\t * ```\n\t *\n\t * @param options - The camera options to set.\n\t *\n\t * @public */\n\tsetCameraOptions(options: Partial) {\n\t\tconst next = structuredClone({\n\t\t\t...this._cameraOptions.__unsafe__getWithoutCapture(),\n\t\t\t...options,\n\t\t})\n\t\tif (next.zoomSteps?.length < 1) next.zoomSteps = [1]\n\t\tthis._cameraOptions.set(next)\n\t\treturn this\n\t}\n\n\t/** @internal */\n\tprivate getConstrainedCamera(\n\t\tpoint: VecLike,\n\t\topts?: TLCameraMoveOptions\n\t): {\n\t\tx: number\n\t\ty: number\n\t\tz: number\n\t} {\n\t\tconst currentCamera = this.getCamera()\n\n\t\tlet { x, y, z = currentCamera.z } = point\n\n\t\t// If force is true, then we'll set the camera to the point regardless of\n\t\t// the camera options, so that we can handle gestures that permit elasticity\n\t\t// or decay, or animations that occur while the camera is locked.\n\t\tif (!opts?.force) {\n\t\t\t// Apply any adjustments based on the camera options\n\n\t\t\tconst cameraOptions = this.getCameraOptions()\n\n\t\t\tconst zoomMin = cameraOptions.zoomSteps[0]\n\t\t\tconst zoomMax = last(cameraOptions.zoomSteps)!\n\n\t\t\tconst vsb = this.getViewportScreenBounds()\n\n\t\t\t// If bounds are provided, then we'll keep those bounds on screen\n\t\t\tif (cameraOptions.constraints) {\n\t\t\t\tconst { constraints } = cameraOptions\n\n\t\t\t\t// Clamp padding to half the viewport size on either dimension\n\t\t\t\tconst py = Math.min(constraints.padding.y, vsb.w / 2)\n\t\t\t\tconst px = Math.min(constraints.padding.x, vsb.h / 2)\n\n\t\t\t\t// Expand the bounds by the padding\n\t\t\t\tconst bounds = Box.From(cameraOptions.constraints.bounds)\n\n\t\t\t\t// For each axis, the \"natural zoom\" is the zoom at\n\t\t\t\t// which the expanded bounds (with padding) would fit\n\t\t\t\t// the current viewport screen bounds. Paddings are\n\t\t\t\t// equal to screen pixels at 100%\n\t\t\t\t// The min and max zooms are factors of the smaller natural zoom axis\n\n\t\t\t\tconst zx = (vsb.w - px * 2) / bounds.w\n\t\t\t\tconst zy = (vsb.h - py * 2) / bounds.h\n\n\t\t\t\tconst baseZoom = this.getBaseZoom()\n\t\t\t\tconst maxZ = zoomMax * baseZoom\n\t\t\t\tconst minZ = zoomMin * baseZoom\n\n\t\t\t\tif (opts?.reset) {\n\t\t\t\t\tz = this.getInitialZoom()\n\t\t\t\t}\n\n\t\t\t\tif (z < minZ || z > maxZ) {\n\t\t\t\t\t// We're trying to zoom out past the minimum zoom level,\n\t\t\t\t\t// or in past the maximum zoom level, so stop the camera\n\t\t\t\t\t// but keep the current center\n\t\t\t\t\tconst { x: cx, y: cy, z: cz } = currentCamera\n\t\t\t\t\tconst cxA = -cx + vsb.w / cz / 2\n\t\t\t\t\tconst cyA = -cy + vsb.h / cz / 2\n\t\t\t\t\tz = clamp(z, minZ, maxZ)\n\t\t\t\t\tconst cxB = -cx + vsb.w / z / 2\n\t\t\t\t\tconst cyB = -cy + vsb.h / z / 2\n\t\t\t\t\tx = cx + cxB - cxA\n\t\t\t\t\ty = cy + cyB - cyA\n\t\t\t\t}\n\n\t\t\t\t// Calculate available space\n\t\t\t\tconst minX = px / z - bounds.x\n\t\t\t\tconst minY = py / z - bounds.y\n\t\t\t\tconst freeW = (vsb.w - px * 2) / z - bounds.w\n\t\t\t\tconst freeH = (vsb.h - py * 2) / z - bounds.h\n\t\t\t\tconst originX = minX + freeW * constraints.origin.x\n\t\t\t\tconst originY = minY + freeH * constraints.origin.y\n\n\t\t\t\tconst behaviorX =\n\t\t\t\t\ttypeof constraints.behavior === 'string' ? constraints.behavior : constraints.behavior.x\n\t\t\t\tconst behaviorY =\n\t\t\t\t\ttypeof constraints.behavior === 'string' ? constraints.behavior : constraints.behavior.y\n\n\t\t\t\t// x axis\n\n\t\t\t\tif (opts?.reset) {\n\t\t\t\t\t// Reset the camera according to the origin\n\t\t\t\t\tx = originX\n\t\t\t\t\ty = originY\n\t\t\t\t} else {\n\t\t\t\t\t// Apply constraints to the camera\n\t\t\t\t\tswitch (behaviorX) {\n\t\t\t\t\t\tcase 'fixed': {\n\t\t\t\t\t\t\t// Center according to the origin\n\t\t\t\t\t\t\tx = originX\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcase 'contain': {\n\t\t\t\t\t\t\t// When below fit zoom, center the camera\n\t\t\t\t\t\t\tif (z < zx) x = originX\n\t\t\t\t\t\t\t// When above fit zoom, keep the bounds within padding distance of the viewport edge\n\t\t\t\t\t\t\telse x = clamp(x, minX + freeW, minX)\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcase 'inside': {\n\t\t\t\t\t\t\t// When below fit zoom, constrain the camera so that the bounds stay completely within the viewport\n\t\t\t\t\t\t\tif (z < zx) x = clamp(x, minX, (vsb.w - px) / z - bounds.w)\n\t\t\t\t\t\t\t// When above fit zoom, keep the bounds within padding distance of the viewport edge\n\t\t\t\t\t\t\telse x = clamp(x, minX + freeW, minX)\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcase 'outside': {\n\t\t\t\t\t\t\t// Constrain the camera so that the bounds never leaves the viewport\n\t\t\t\t\t\t\tx = clamp(x, px / z - bounds.w, (vsb.w - px) / z)\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcase 'free': {\n\t\t\t\t\t\t\t// noop, use whatever x is provided\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t\tdefault: {\n\t\t\t\t\t\t\tthrow exhaustiveSwitchError(behaviorX)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// y axis\n\n\t\t\t\t\tswitch (behaviorY) {\n\t\t\t\t\t\tcase 'fixed': {\n\t\t\t\t\t\t\ty = originY\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcase 'contain': {\n\t\t\t\t\t\t\tif (z < zy) y = originY\n\t\t\t\t\t\t\telse y = clamp(y, minY + freeH, minY)\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcase 'inside': {\n\t\t\t\t\t\t\tif (z < zy) y = clamp(y, minY, (vsb.h - py) / z - bounds.h)\n\t\t\t\t\t\t\telse y = clamp(y, minY + freeH, minY)\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcase 'outside': {\n\t\t\t\t\t\t\ty = clamp(y, py / z - bounds.h, (vsb.h - py) / z)\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcase 'free': {\n\t\t\t\t\t\t\t// noop, use whatever x is provided\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t\tdefault: {\n\t\t\t\t\t\t\tthrow exhaustiveSwitchError(behaviorY)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// constrain the zoom, preserving the center\n\t\t\t\tif (z > zoomMax || z < zoomMin) {\n\t\t\t\t\tconst { x: cx, y: cy, z: cz } = currentCamera\n\t\t\t\t\tz = clamp(z, zoomMin, zoomMax)\n\t\t\t\t\tx = cx + (-cx + vsb.w / z / 2) - (-cx + vsb.w / cz / 2)\n\t\t\t\t\ty = cy + (-cy + vsb.h / z / 2) - (-cy + vsb.h / cz / 2)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn { x, y, z }\n\t}\n\n\t/** @internal */\n\tprivate _setCamera(point: VecLike, opts?: TLCameraMoveOptions): this {\n\t\tconst currentCamera = this.getCamera()\n\n\t\tconst { x, y, z } = this.getConstrainedCamera(point, opts)\n\n\t\tif (currentCamera.x === x && currentCamera.y === y && currentCamera.z === z) {\n\t\t\treturn this\n\t\t}\n\n\t\ttransact(() => {\n\t\t\tconst camera = { ...currentCamera, x, y, z }\n\t\t\tthis.run(\n\t\t\t\t() => {\n\t\t\t\t\tthis.store.put([camera]) // include id and meta here\n\t\t\t\t},\n\t\t\t\t{ history: 'ignore' }\n\t\t\t)\n\n\t\t\t// Dispatch a new pointer move because the pointer's page will have changed\n\t\t\t// (its screen position will compute to a new page position given the new camera position)\n\t\t\tconst { currentScreenPoint, currentPagePoint } = this.inputs\n\t\t\tconst { screenBounds } = this.store.unsafeGetWithoutCapture(TLINSTANCE_ID)!\n\n\t\t\t// compare the next page point (derived from the current camera) to the current page point\n\t\t\tif (\n\t\t\t\tcurrentScreenPoint.x / z - x !== currentPagePoint.x ||\n\t\t\t\tcurrentScreenPoint.y / z - y !== currentPagePoint.y\n\t\t\t) {\n\t\t\t\t// If it's changed, dispatch a pointer event\n\t\t\t\tconst event: TLPointerEventInfo = {\n\t\t\t\t\ttype: 'pointer',\n\t\t\t\t\ttarget: 'canvas',\n\t\t\t\t\tname: 'pointer_move',\n\t\t\t\t\t// weird but true: we need to put the screen point back into client space\n\t\t\t\t\tpoint: Vec.AddXY(currentScreenPoint, screenBounds.x, screenBounds.y),\n\t\t\t\t\tpointerId: INTERNAL_POINTER_IDS.CAMERA_MOVE,\n\t\t\t\t\tctrlKey: this.inputs.ctrlKey,\n\t\t\t\t\taltKey: this.inputs.altKey,\n\t\t\t\t\tshiftKey: this.inputs.shiftKey,\n\t\t\t\t\tbutton: 0,\n\t\t\t\t\tisPen: this.getInstanceState().isPenMode ?? false,\n\t\t\t\t}\n\n\t\t\t\tif (opts?.immediate) {\n\t\t\t\t\tthis._flushEventForTick(event)\n\t\t\t\t} else {\n\t\t\t\t\tthis.dispatch(event)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tthis._tickCameraState()\n\t\t})\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Set the current camera.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.setCamera({ x: 0, y: 0})\n\t * editor.setCamera({ x: 0, y: 0, z: 1.5})\n\t * editor.setCamera({ x: 0, y: 0, z: 1.5}, { animation: { duration: 1000, easing: (t) => t * t } })\n\t * ```\n\t *\n\t * @param point - The new camera position.\n\t * @param opts - The camera move options.\n\t *\n\t * @public\n\t */\n\tsetCamera(point: VecLike, opts?: TLCameraMoveOptions): this {\n\t\tconst { isLocked } = this._cameraOptions.__unsafe__getWithoutCapture()\n\t\tif (isLocked && !opts?.force) return this\n\n\t\t// Stop any camera animations\n\t\tthis.stopCameraAnimation()\n\n\t\t// Stop following any user\n\t\tif (this.getInstanceState().followingUserId) {\n\t\t\tthis.stopFollowingUser()\n\t\t}\n\n\t\tconst _point = Vec.Cast(point)\n\n\t\tif (!Number.isFinite(_point.x)) _point.x = 0\n\t\tif (!Number.isFinite(_point.y)) _point.y = 0\n\t\tif (_point.z === undefined || !Number.isFinite(_point.z)) point.z = this.getZoomLevel()\n\n\t\tconst camera = this.getConstrainedCamera(_point, opts)\n\n\t\tif (opts?.animation) {\n\t\t\tconst { width, height } = this.getViewportScreenBounds()\n\t\t\tthis._animateToViewport(\n\t\t\t\tnew Box(-camera.x, -camera.y, width / camera.z, height / camera.z),\n\t\t\t\topts\n\t\t\t)\n\t\t} else {\n\t\t\tthis._setCamera(camera, {\n\t\t\t\t...opts,\n\t\t\t\t// we already did the constraining, so we don't need to do it again\n\t\t\t\tforce: true,\n\t\t\t})\n\t\t}\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Center the camera on a point (in the current page space).\n\t *\n\t * @example\n\t * ```ts\n\t * editor.centerOnPoint({ x: 100, y: 100 })\n\t * editor.centerOnPoint({ x: 100, y: 100 }, { animation: { duration: 200 } })\n\t * ```\n\t *\n\t * @param point - The point in the current page space to center on.\n\t * @param animation - The camera move options.\n\t *\n\t * @public\n\t */\n\tcenterOnPoint(point: VecLike, opts?: TLCameraMoveOptions): this {\n\t\tconst { isLocked } = this.getCameraOptions()\n\t\tif (isLocked && !opts?.force) return this\n\n\t\tconst { width: pw, height: ph } = this.getViewportPageBounds()\n\t\tthis.setCamera(new Vec(-(point.x - pw / 2), -(point.y - ph / 2), this.getCamera().z), opts)\n\t\treturn this\n\t}\n\n\t/**\n\t * Zoom the camera to fit the current page's content in the viewport.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.zoomToFit()\n\t * editor.zoomToFit({ animation: { duration: 200 } })\n\t * ```\n\t *\n\t * @param opts - The camera move options.\n\t *\n\t * @public\n\t */\n\tzoomToFit(opts?: TLCameraMoveOptions): this {\n\t\tconst ids = [...this.getCurrentPageShapeIds()]\n\t\tif (ids.length <= 0) return this\n\t\tconst pageBounds = Box.Common(compact(ids.map((id) => this.getShapePageBounds(id))))\n\t\tthis.zoomToBounds(pageBounds, opts)\n\t\treturn this\n\t}\n\n\t/**\n\t * Set the zoom back to 100%.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.resetZoom()\n\t * editor.resetZoom(editor.getViewportScreenCenter(), { animation: { duration: 200 } })\n\t * editor.resetZoom(editor.getViewportScreenCenter(), { animation: { duration: 200 } })\n\t * ```\n\t *\n\t * @param point - The screen point to zoom out on. Defaults to the viewport screen center.\n\t * @param opts - The camera move options.\n\t *\n\t * @public\n\t */\n\tresetZoom(point = this.getViewportScreenCenter(), opts?: TLCameraMoveOptions): this {\n\t\tconst { isLocked, constraints: constraints } = this.getCameraOptions()\n\t\tif (isLocked && !opts?.force) return this\n\n\t\tconst currentCamera = this.getCamera()\n\t\tconst { x: cx, y: cy, z: cz } = currentCamera\n\t\tconst { x, y } = point\n\n\t\tlet z = 1\n\n\t\tif (constraints) {\n\t\t\t// For non-infinite fit, we'll set the camera to the natural zoom level...\n\t\t\t// unless it's already there, in which case we'll set zoom to 100%\n\t\t\tconst initialZoom = this.getInitialZoom()\n\t\t\tif (cz !== initialZoom) {\n\t\t\t\tz = initialZoom\n\t\t\t}\n\t\t}\n\n\t\tthis.setCamera(\n\t\t\tnew Vec(cx + (x / z - x) - (x / cz - x), cy + (y / z - y) - (y / cz - y), z),\n\t\t\topts\n\t\t)\n\t\treturn this\n\t}\n\n\t/**\n\t * Zoom the camera in.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.zoomIn()\n\t * editor.zoomIn(editor.getViewportScreenCenter(), { animation: { duration: 200 } })\n\t * editor.zoomIn(editor.inputs.currentScreenPoint, { animation: { duration: 200 } })\n\t * ```\n\t *\n\t * @param point - The screen point to zoom in on. Defaults to the screen center\n\t * @param opts - The camera move options.\n\t *\n\t * @public\n\t */\n\tzoomIn(point = this.getViewportScreenCenter(), opts?: TLCameraMoveOptions): this {\n\t\tconst { isLocked } = this.getCameraOptions()\n\t\tif (isLocked && !opts?.force) return this\n\n\t\tconst { x: cx, y: cy, z: cz } = this.getCamera()\n\n\t\tconst { zoomSteps } = this.getCameraOptions()\n\t\tif (zoomSteps !== null && zoomSteps.length > 1) {\n\t\t\tconst baseZoom = this.getBaseZoom()\n\t\t\tlet zoom = last(zoomSteps)! * baseZoom\n\t\t\tfor (let i = 1; i < zoomSteps.length; i++) {\n\t\t\t\tconst z1 = zoomSteps[i - 1] * baseZoom\n\t\t\t\tconst z2 = zoomSteps[i] * baseZoom\n\t\t\t\tif (z2 - cz <= (z2 - z1) / 2) continue\n\t\t\t\tzoom = z2\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tthis.setCamera(\n\t\t\t\tnew Vec(\n\t\t\t\t\tcx + (point.x / zoom - point.x) - (point.x / cz - point.x),\n\t\t\t\t\tcy + (point.y / zoom - point.y) - (point.y / cz - point.y),\n\t\t\t\t\tzoom\n\t\t\t\t),\n\t\t\t\topts\n\t\t\t)\n\t\t}\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Zoom the camera out.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.zoomOut()\n\t * editor.zoomOut(editor.getViewportScreenCenter(), { animation: { duration: 120 } })\n\t * editor.zoomOut(editor.inputs.currentScreenPoint, { animation: { duration: 120 } })\n\t * ```\n\t *\n\t * @param point - The point to zoom out on. Defaults to the viewport screen center.\n\t * @param opts - The camera move options.\n\t *\n\t * @public\n\t */\n\tzoomOut(point = this.getViewportScreenCenter(), opts?: TLCameraMoveOptions): this {\n\t\tconst { isLocked } = this.getCameraOptions()\n\t\tif (isLocked && !opts?.force) return this\n\n\t\tconst { zoomSteps } = this.getCameraOptions()\n\t\tif (zoomSteps !== null && zoomSteps.length > 1) {\n\t\t\tconst baseZoom = this.getBaseZoom()\n\t\t\tconst { x: cx, y: cy, z: cz } = this.getCamera()\n\t\t\t// start at the max\n\t\t\tlet zoom = zoomSteps[0] * baseZoom\n\t\t\tfor (let i = zoomSteps.length - 1; i > 0; i--) {\n\t\t\t\tconst z1 = zoomSteps[i - 1] * baseZoom\n\t\t\t\tconst z2 = zoomSteps[i] * baseZoom\n\t\t\t\tif (z2 - cz >= (z2 - z1) / 2) continue\n\t\t\t\tzoom = z1\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tthis.setCamera(\n\t\t\t\tnew Vec(\n\t\t\t\t\tcx + (point.x / zoom - point.x) - (point.x / cz - point.x),\n\t\t\t\t\tcy + (point.y / zoom - point.y) - (point.y / cz - point.y),\n\t\t\t\t\tzoom\n\t\t\t\t),\n\t\t\t\topts\n\t\t\t)\n\t\t}\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Zoom the camera to fit the current selection in the viewport.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.zoomToSelection()\n\t * editor.zoomToSelection({ animation: { duration: 200 } })\n\t * ```\n\t *\n\t * @param animation - The camera move options.\n\t *\n\t * @public\n\t */\n\tzoomToSelection(opts?: TLCameraMoveOptions): this {\n\t\tconst { isLocked } = this.getCameraOptions()\n\t\tif (isLocked && !opts?.force) return this\n\n\t\tconst selectionPageBounds = this.getSelectionPageBounds()\n\t\tif (selectionPageBounds) {\n\t\t\tthis.zoomToBounds(selectionPageBounds, {\n\t\t\t\ttargetZoom: Math.max(1, this.getZoomLevel()),\n\t\t\t\t...opts,\n\t\t\t})\n\t\t}\n\t\treturn this\n\t}\n\n\t/**\n\t * Zoom the camera to fit a bounding box (in the current page space).\n\t *\n\t * @example\n\t * ```ts\n\t * editor.zoomToBounds(myBounds)\n\t * editor.zoomToBounds(myBounds, { animation: { duration: 200 } })\n\t * editor.zoomToBounds(myBounds, { animation: { duration: 200 }, inset: 0, targetZoom: 1 })\n\t * ```\n\t *\n\t * @param bounds - The bounding box.\n\t * @param opts - The camera move options, target zoom, or custom inset amount.\n\t *\n\t * @public\n\t */\n\tzoomToBounds(\n\t\tbounds: BoxLike,\n\t\topts?: { targetZoom?: number; inset?: number } & TLCameraMoveOptions\n\t): this {\n\t\tconst cameraOptions = this._cameraOptions.__unsafe__getWithoutCapture()\n\t\tif (cameraOptions.isLocked && !opts?.force) return this\n\n\t\tconst viewportScreenBounds = this.getViewportScreenBounds()\n\n\t\tconst inset = opts?.inset ?? Math.min(ZOOM_TO_FIT_PADDING, viewportScreenBounds.width * 0.28)\n\n\t\tconst baseZoom = this.getBaseZoom()\n\t\tconst zoomMin = cameraOptions.zoomSteps[0]\n\t\tconst zoomMax = last(cameraOptions.zoomSteps)!\n\n\t\tlet zoom = clamp(\n\t\t\tMath.min(\n\t\t\t\t(viewportScreenBounds.width - inset) / bounds.w,\n\t\t\t\t(viewportScreenBounds.height - inset) / bounds.h\n\t\t\t),\n\t\t\tzoomMin * baseZoom,\n\t\t\tzoomMax * baseZoom\n\t\t)\n\n\t\tif (opts?.targetZoom !== undefined) {\n\t\t\tzoom = Math.min(opts.targetZoom, zoom)\n\t\t}\n\n\t\tthis.setCamera(\n\t\t\tnew Vec(\n\t\t\t\t-bounds.x + (viewportScreenBounds.width - bounds.w * zoom) / 2 / zoom,\n\t\t\t\t-bounds.y + (viewportScreenBounds.height - bounds.h * zoom) / 2 / zoom,\n\t\t\t\tzoom\n\t\t\t),\n\t\t\topts\n\t\t)\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Stop the current camera animation, if any.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.stopCameraAnimation()\n\t * ```\n\t *\n\t * @public\n\t */\n\tstopCameraAnimation(): this {\n\t\tthis.emit('stop-camera-animation')\n\t\treturn this\n\t}\n\n\t/** @internal */\n\tprivate _viewportAnimation = null as null | {\n\t\telapsed: number\n\t\tduration: number\n\t\teasing(t: number): number\n\t\tstart: Box\n\t\tend: Box\n\t}\n\n\t/** @internal */\n\tprivate _animateViewport(ms: number): void {\n\t\tif (!this._viewportAnimation) return\n\n\t\tthis._viewportAnimation.elapsed += ms\n\n\t\tconst { elapsed, easing, duration, start, end } = this._viewportAnimation\n\n\t\tif (elapsed > duration) {\n\t\t\tthis.off('tick', this._animateViewport)\n\t\t\tthis._viewportAnimation = null\n\t\t\tthis._setCamera(new Vec(-end.x, -end.y, this.getViewportScreenBounds().width / end.width))\n\t\t\treturn\n\t\t}\n\n\t\tconst remaining = duration - elapsed\n\t\tconst t = easing(1 - remaining / duration)\n\n\t\tconst left = start.minX + (end.minX - start.minX) * t\n\t\tconst top = start.minY + (end.minY - start.minY) * t\n\t\tconst right = start.maxX + (end.maxX - start.maxX) * t\n\n\t\tthis._setCamera(new Vec(-left, -top, this.getViewportScreenBounds().width / (right - left)), {\n\t\t\tforce: true,\n\t\t})\n\t}\n\n\t/** @internal */\n\tprivate _animateToViewport(\n\t\ttargetViewportPage: Box,\n\t\topts = { animation: DEFAULT_ANIMATION_OPTIONS } as TLCameraMoveOptions\n\t) {\n\t\tconst { animation, ...rest } = opts\n\t\tif (!animation) return\n\t\tconst { duration = 0, easing = EASINGS.easeInOutCubic } = animation\n\t\tconst animationSpeed = this.user.getAnimationSpeed()\n\t\tconst viewportPageBounds = this.getViewportPageBounds()\n\n\t\t// If we have an existing animation, then stop it\n\t\tthis.stopCameraAnimation()\n\n\t\t// also stop following any user\n\t\tif (this.getInstanceState().followingUserId) {\n\t\t\tthis.stopFollowingUser()\n\t\t}\n\n\t\tif (duration === 0 || animationSpeed === 0) {\n\t\t\t// If we have no animation, then skip the animation and just set the camera\n\t\t\treturn this._setCamera(\n\t\t\t\tnew Vec(\n\t\t\t\t\t-targetViewportPage.x,\n\t\t\t\t\t-targetViewportPage.y,\n\t\t\t\t\tthis.getViewportScreenBounds().width / targetViewportPage.width\n\t\t\t\t),\n\t\t\t\t{ ...rest }\n\t\t\t)\n\t\t}\n\n\t\t// Set our viewport animation\n\t\tthis._viewportAnimation = {\n\t\t\telapsed: 0,\n\t\t\tduration: duration / animationSpeed,\n\t\t\teasing,\n\t\t\tstart: viewportPageBounds.clone(),\n\t\t\tend: targetViewportPage.clone(),\n\t\t}\n\n\t\t// If we ever get a \"stop-camera-animation\" event, we stop\n\t\tthis.once('stop-camera-animation', () => {\n\t\t\tthis.off('tick', this._animateViewport)\n\t\t\tthis._viewportAnimation = null\n\t\t})\n\n\t\t// On each tick, animate the viewport\n\t\tthis.on('tick', this._animateViewport)\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Slide the camera in a certain direction.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.slideCamera({ speed: 1, direction: { x: 1, y: 0 }, friction: 0.1 })\n\t * ```\n\t *\n\t * @param opts - Options for the slide\n\t * @public\n\t */\n\tslideCamera(\n\t\topts = {} as {\n\t\t\tspeed: number\n\t\t\tdirection: VecLike\n\t\t\tfriction?: number\n\t\t\tspeedThreshold?: number\n\t\t\tforce?: boolean\n\t\t}\n\t): this {\n\t\tconst { isLocked } = this.getCameraOptions()\n\t\tif (isLocked && !opts?.force) return this\n\n\t\tconst animationSpeed = this.user.getAnimationSpeed()\n\t\tif (animationSpeed === 0) return this\n\n\t\tthis.stopCameraAnimation()\n\n\t\tconst {\n\t\t\tspeed,\n\t\t\tfriction = this.options.cameraSlideFriction,\n\t\t\tdirection,\n\t\t\tspeedThreshold = 0.01,\n\t\t} = opts\n\t\tlet currentSpeed = Math.min(speed, 1)\n\n\t\tconst cancel = () => {\n\t\t\tthis.off('tick', moveCamera)\n\t\t\tthis.off('stop-camera-animation', cancel)\n\t\t}\n\n\t\tthis.once('stop-camera-animation', cancel)\n\n\t\tconst moveCamera = (elapsed: number) => {\n\t\t\tconst { x: cx, y: cy, z: cz } = this.getCamera()\n\t\t\tconst movementVec = Vec.Mul(direction, (currentSpeed * elapsed) / cz)\n\n\t\t\t// Apply friction\n\t\t\tcurrentSpeed *= 1 - friction\n\t\t\tif (currentSpeed < speedThreshold) {\n\t\t\t\tcancel()\n\t\t\t} else {\n\t\t\t\tthis._setCamera(new Vec(cx + movementVec.x, cy + movementVec.y, cz))\n\t\t\t}\n\t\t}\n\n\t\tthis.on('tick', moveCamera)\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Animate the camera to a user's cursor position. This also briefly show the user's cursor if it's not currently visible.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.zoomToUser(myUserId)\n\t * editor.zoomToUser(myUserId, { animation: { duration: 200 } })\n\t * ```\n\t *\n\t * @param userId - The id of the user to animate to.\n\t * @param opts - The camera move options.\n\t * @public\n\t */\n\tzoomToUser(userId: string, opts: TLCameraMoveOptions = { animation: { duration: 500 } }): this {\n\t\tconst presence = this.getCollaborators().find((c) => c.userId === userId)\n\n\t\tif (!presence) return this\n\n\t\tthis.run(() => {\n\t\t\t// If we're following someone, stop following them\n\t\t\tif (this.getInstanceState().followingUserId !== null) {\n\t\t\t\tthis.stopFollowingUser()\n\t\t\t}\n\n\t\t\t// If we're not on the same page, move to the page they're on\n\t\t\tconst isOnSamePage = presence.currentPageId === this.getCurrentPageId()\n\t\t\tif (!isOnSamePage) {\n\t\t\t\tthis.setCurrentPage(presence.currentPageId)\n\t\t\t}\n\n\t\t\t// Only animate the camera if the user is on the same page as us\n\t\t\tif (opts && opts.animation && !isOnSamePage) {\n\t\t\t\topts.animation = undefined\n\t\t\t}\n\n\t\t\tthis.centerOnPoint(presence.cursor, opts)\n\n\t\t\t// Highlight the user's cursor\n\t\t\tconst { highlightedUserIds } = this.getInstanceState()\n\t\t\tthis.updateInstanceState({ highlightedUserIds: [...highlightedUserIds, userId] })\n\n\t\t\t// Unhighlight the user's cursor after a few seconds\n\t\t\tthis.timers.setTimeout(() => {\n\t\t\t\tconst highlightedUserIds = [...this.getInstanceState().highlightedUserIds]\n\t\t\t\tconst index = highlightedUserIds.indexOf(userId)\n\t\t\t\tif (index < 0) return\n\t\t\t\thighlightedUserIds.splice(index, 1)\n\t\t\t\tthis.updateInstanceState({ highlightedUserIds })\n\t\t\t}, this.options.collaboratorIdleTimeoutMs)\n\t\t})\n\n\t\treturn this\n\t}\n\n\t// Viewport\n\n\t/** @internal */\n\tprivate _willSetInitialBounds = true\n\n\t/**\n\t * Update the viewport. The viewport will measure the size and screen position of its container\n\t * element. This should be done whenever the container's position on the screen changes.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.updateViewportScreenBounds(new Box(0, 0, 1280, 1024))\n\t * editor.updateViewportScreenBounds(new Box(0, 0, 1280, 1024), true)\n\t * ```\n\t *\n\t * @param center - Whether to preserve the viewport page center as the viewport changes.\n\t *\n\t * @public\n\t */\n\tupdateViewportScreenBounds(screenBounds: Box | HTMLElement, center = false): this {\n\t\tif (screenBounds instanceof HTMLElement) {\n\t\t\tconst rect = screenBounds.getBoundingClientRect()\n\t\t\tscreenBounds = new Box(\n\t\t\t\trect.left || rect.x,\n\t\t\t\trect.top || rect.y,\n\t\t\t\tMath.max(rect.width, 1),\n\t\t\t\tMath.max(rect.height, 1)\n\t\t\t)\n\t\t} else {\n\t\t\tscreenBounds.width = Math.max(screenBounds.width, 1)\n\t\t\tscreenBounds.height = Math.max(screenBounds.height, 1)\n\t\t}\n\n\t\tconst insets = [\n\t\t\t// top\n\t\t\tscreenBounds.minY !== 0,\n\t\t\t// right\n\t\t\t!approximately(document.body.scrollWidth, screenBounds.maxX, 1),\n\t\t\t// bottom\n\t\t\t!approximately(document.body.scrollHeight, screenBounds.maxY, 1),\n\t\t\t// left\n\t\t\tscreenBounds.minX !== 0,\n\t\t]\n\n\t\tconst { _willSetInitialBounds } = this\n\n\t\tthis._willSetInitialBounds = false\n\n\t\tconst { screenBounds: prevScreenBounds, insets: prevInsets } = this.getInstanceState()\n\t\tif (screenBounds.equals(prevScreenBounds) && insets.every((v, i) => v === prevInsets[i])) {\n\t\t\t// nothing to do\n\t\t\treturn this\n\t\t}\n\n\t\tif (_willSetInitialBounds) {\n\t\t\t// If we have just received the initial bounds, don't center the camera.\n\t\t\tthis.updateInstanceState({ screenBounds: screenBounds.toJson(), insets })\n\t\t\tthis.setCamera(this.getCamera())\n\t\t} else {\n\t\t\tif (center && !this.getInstanceState().followingUserId) {\n\t\t\t\t// Get the page center before the change, make the change, and restore it\n\t\t\t\tconst before = this.getViewportPageBounds().center\n\t\t\t\tthis.updateInstanceState({ screenBounds: screenBounds.toJson(), insets })\n\t\t\t\tthis.centerOnPoint(before)\n\t\t\t} else {\n\t\t\t\t// Otherwise,\n\t\t\t\tthis.updateInstanceState({ screenBounds: screenBounds.toJson(), insets })\n\t\t\t\tthis._setCamera(Vec.From({ ...this.getCamera() }))\n\t\t\t}\n\t\t}\n\n\t\tthis._tickCameraState()\n\n\t\treturn this\n\t}\n\n\t/**\n\t * The bounds of the editor's viewport in screen space.\n\t *\n\t * @public\n\t */\n\t@computed getViewportScreenBounds() {\n\t\tconst { x, y, w, h } = this.getInstanceState().screenBounds\n\t\treturn new Box(x, y, w, h)\n\t}\n\n\t/**\n\t * The center of the editor's viewport in screen space.\n\t *\n\t * @public\n\t */\n\t@computed getViewportScreenCenter() {\n\t\tconst viewportScreenBounds = this.getViewportScreenBounds()\n\t\treturn new Vec(\n\t\t\tviewportScreenBounds.midX - viewportScreenBounds.minX,\n\t\t\tviewportScreenBounds.midY - viewportScreenBounds.minY\n\t\t)\n\t}\n\n\t/**\n\t * The current viewport in the current page space.\n\t *\n\t * @public\n\t */\n\t@computed getViewportPageBounds() {\n\t\tconst { w, h } = this.getViewportScreenBounds()\n\t\tconst { x: cx, y: cy, z: cz } = this.getCamera()\n\t\treturn new Box(-cx, -cy, w / cz, h / cz)\n\t}\n\n\t/**\n\t * Convert a point in screen space to a point in the current page space.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.screenToPage({ x: 100, y: 100 })\n\t * ```\n\t *\n\t * @param point - The point in screen space.\n\t *\n\t * @public\n\t */\n\tscreenToPage(point: VecLike) {\n\t\tconst { screenBounds } = this.store.unsafeGetWithoutCapture(TLINSTANCE_ID)!\n\t\tconst { x: cx, y: cy, z: cz = 1 } = this.getCamera()\n\t\treturn new Vec(\n\t\t\t(point.x - screenBounds.x) / cz - cx,\n\t\t\t(point.y - screenBounds.y) / cz - cy,\n\t\t\tpoint.z ?? 0.5\n\t\t)\n\t}\n\n\t/**\n\t * Convert a point in the current page space to a point in current screen space.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.pageToScreen({ x: 100, y: 100 })\n\t * ```\n\t *\n\t * @param point - The point in page space.\n\t *\n\t * @public\n\t */\n\tpageToScreen(point: VecLike) {\n\t\tconst { screenBounds } = this.store.unsafeGetWithoutCapture(TLINSTANCE_ID)!\n\t\tconst { x: cx, y: cy, z: cz = 1 } = this.getCamera()\n\t\treturn new Vec(\n\t\t\t(point.x + cx) * cz + screenBounds.x,\n\t\t\t(point.y + cy) * cz + screenBounds.y,\n\t\t\tpoint.z ?? 0.5\n\t\t)\n\t}\n\n\t/**\n\t * Convert a point in the current page space to a point in current viewport space.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.pageToViewport({ x: 100, y: 100 })\n\t * ```\n\t *\n\t * @param point - The point in page space.\n\t *\n\t * @public\n\t */\n\tpageToViewport(point: VecLike) {\n\t\tconst { x: cx, y: cy, z: cz = 1 } = this.getCamera()\n\t\treturn new Vec((point.x + cx) * cz, (point.y + cy) * cz, point.z ?? 0.5)\n\t}\n\t// Collaborators\n\n\t@computed\n\tprivate _getCollaboratorsQuery() {\n\t\treturn this.store.query.records('instance_presence', () => ({\n\t\t\tuserId: { neq: this.user.getId() },\n\t\t}))\n\t}\n\n\t/**\n\t * Returns a list of presence records for all peer collaborators.\n\t * This will return the latest presence record for each connected user.\n\t *\n\t * @public\n\t */\n\t@computed\n\tgetCollaborators() {\n\t\tconst allPresenceRecords = this._getCollaboratorsQuery().get()\n\t\tif (!allPresenceRecords.length) return EMPTY_ARRAY\n\t\tconst userIds = [...new Set(allPresenceRecords.map((c) => c.userId))].sort()\n\t\treturn userIds.map((id) => {\n\t\t\tconst latestPresence = allPresenceRecords\n\t\t\t\t.filter((c) => c.userId === id)\n\t\t\t\t.sort((a, b) => b.lastActivityTimestamp - a.lastActivityTimestamp)[0]\n\t\t\treturn latestPresence\n\t\t})\n\t}\n\n\t/**\n\t * Returns a list of presence records for all peer collaborators on the current page.\n\t * This will return the latest presence record for each connected user.\n\t *\n\t * @public\n\t */\n\t@computed\n\tgetCollaboratorsOnCurrentPage() {\n\t\tconst currentPageId = this.getCurrentPageId()\n\t\treturn this.getCollaborators().filter((c) => c.currentPageId === currentPageId)\n\t}\n\n\t// Following\n\n\t// When we are 'locked on' to a user, our camera is derived from their camera.\n\tprivate _isLockedOnFollowingUser = atom('isLockedOnFollowingUser', false)\n\n\t/**\n\t * Start viewport-following a user.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.startFollowingUser(myUserId)\n\t * ```\n\t *\n\t * @param userId - The id of the user to follow.\n\t * @param opts - Options for starting to follow a user.\n\t *\n\t * @public\n\t */\n\tstartFollowingUser(userId: string): this {\n\t\t// if we were already following someone, stop following them\n\t\tthis.stopFollowingUser()\n\n\t\tconst leaderPresences = this._getCollaboratorsQuery()\n\t\t\t.get()\n\t\t\t.filter((p) => p.userId === userId)\n\n\t\tif (!leaderPresences.length) {\n\t\t\tconsole.warn('User not found')\n\t\t\treturn this\n\t\t}\n\n\t\tconst thisUserId = this.user.getId()\n\n\t\tif (!thisUserId) {\n\t\t\tconsole.warn('You should set the userId for the current instance before following a user')\n\t\t\t// allow to continue since it's probably fine most of the time.\n\t\t}\n\n\t\t// If the leader is following us, then we can't follow them\n\t\tif (leaderPresences.some((p) => p.followingUserId === thisUserId)) {\n\t\t\treturn this\n\t\t}\n\n\t\tconst latestLeaderPresence = computed('latestLeaderPresence', () => {\n\t\t\treturn this.getCollaborators().find((p) => p.userId === userId)\n\t\t})\n\n\t\ttransact(() => {\n\t\t\tthis.updateInstanceState({ followingUserId: userId }, { history: 'ignore' })\n\n\t\t\t// we listen for page changes separately from the 'moveTowardsUser' tick\n\t\t\tconst dispose = react('update current page', () => {\n\t\t\t\tconst leaderPresence = latestLeaderPresence.get()\n\t\t\t\tif (!leaderPresence) {\n\t\t\t\t\tthis.stopFollowingUser()\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tif (\n\t\t\t\t\tleaderPresence.currentPageId !== this.getCurrentPageId() &&\n\t\t\t\t\tthis.getPage(leaderPresence.currentPageId)\n\t\t\t\t) {\n\t\t\t\t\t// if the page changed, switch page\n\t\t\t\t\tthis.run(\n\t\t\t\t\t\t() => {\n\t\t\t\t\t\t\t// sneaky store.put here, we can't go through setCurrentPage because it calls stopFollowingUser\n\t\t\t\t\t\t\tthis.store.put([\n\t\t\t\t\t\t\t\t{ ...this.getInstanceState(), currentPageId: leaderPresence.currentPageId },\n\t\t\t\t\t\t\t])\n\t\t\t\t\t\t\tthis._isLockedOnFollowingUser.set(true)\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{ history: 'ignore' }\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t})\n\n\t\t\tconst cancel = () => {\n\t\t\t\tdispose()\n\t\t\t\tthis._isLockedOnFollowingUser.set(false)\n\t\t\t\tthis.off('frame', moveTowardsUser)\n\t\t\t\tthis.off('stop-following', cancel)\n\t\t\t}\n\n\t\t\tconst moveTowardsUser = () => {\n\t\t\t\t// Stop following if we can't find the user\n\t\t\t\tconst leaderPresence = latestLeaderPresence.get()\n\t\t\t\tif (!leaderPresence) {\n\t\t\t\t\tthis.stopFollowingUser()\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\tif (this._isLockedOnFollowingUser.get()) return\n\n\t\t\t\tconst animationSpeed = this.user.getAnimationSpeed()\n\n\t\t\t\tif (animationSpeed === 0) {\n\t\t\t\t\tthis._isLockedOnFollowingUser.set(true)\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\tconst targetViewport = this.getViewportPageBoundsForFollowing()\n\t\t\t\tif (!targetViewport) {\n\t\t\t\t\tthis.stopFollowingUser()\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tconst currentViewport = this.getViewportPageBounds()\n\n\t\t\t\tconst diffX =\n\t\t\t\t\tMath.abs(targetViewport.minX - currentViewport.minX) +\n\t\t\t\t\tMath.abs(targetViewport.maxX - currentViewport.maxX)\n\t\t\t\tconst diffY =\n\t\t\t\t\tMath.abs(targetViewport.minY - currentViewport.minY) +\n\t\t\t\t\tMath.abs(targetViewport.maxY - currentViewport.maxY)\n\n\t\t\t\t// Stop chasing if we're close enough!\n\t\t\t\tif (\n\t\t\t\t\tdiffX < this.options.followChaseViewportSnap &&\n\t\t\t\t\tdiffY < this.options.followChaseViewportSnap\n\t\t\t\t) {\n\t\t\t\t\tthis._isLockedOnFollowingUser.set(true)\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\t// Chase the user's viewport!\n\t\t\t\t// Interpolate between the current viewport and the target viewport based on animation speed.\n\t\t\t\t// This will produce an 'ease-out' effect.\n\t\t\t\tconst t = clamp(animationSpeed * 0.5, 0.1, 0.8)\n\n\t\t\t\tconst nextViewport = new Box(\n\t\t\t\t\tlerp(currentViewport.minX, targetViewport.minX, t),\n\t\t\t\t\tlerp(currentViewport.minY, targetViewport.minY, t),\n\t\t\t\t\tlerp(currentViewport.width, targetViewport.width, t),\n\t\t\t\t\tlerp(currentViewport.height, targetViewport.height, t)\n\t\t\t\t)\n\n\t\t\t\tconst nextCamera = new Vec(\n\t\t\t\t\t-nextViewport.x,\n\t\t\t\t\t-nextViewport.y,\n\t\t\t\t\tthis.getViewportScreenBounds().width / nextViewport.width\n\t\t\t\t)\n\n\t\t\t\t// Update the camera!\n\t\t\t\tthis.stopCameraAnimation()\n\t\t\t\tthis._setCamera(nextCamera)\n\t\t\t}\n\n\t\t\tthis.once('stop-following', cancel)\n\t\t\tthis.addListener('frame', moveTowardsUser)\n\n\t\t\t// call once to start synchronously\n\t\t\tmoveTowardsUser()\n\t\t})\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Stop viewport-following a user.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.stopFollowingUser()\n\t * ```\n\t * @public\n\t */\n\tstopFollowingUser(): this {\n\t\tthis.run(\n\t\t\t() => {\n\t\t\t\t// commit the current camera to the store\n\t\t\t\tthis.store.put([this.getCamera()])\n\t\t\t\t// this must happen after the camera is committed\n\t\t\t\tthis._isLockedOnFollowingUser.set(false)\n\t\t\t\tthis.updateInstanceState({ followingUserId: null })\n\t\t\t\tthis.emit('stop-following')\n\t\t\t},\n\t\t\t{ history: 'ignore' }\n\t\t)\n\t\treturn this\n\t}\n\n\t/** @internal */\n\tgetUnorderedRenderingShapes(\n\t\t// The rendering state. We use this method both for rendering, which\n\t\t// is based on other state, and for computing order for SVG export,\n\t\t// which should work even when things are for example off-screen.\n\t\tuseEditorState: boolean\n\t): TLRenderingShape[] {\n\t\t// Here we get the shape as well as any of its children, as well as their\n\t\t// opacities. If the shape is being erased, and none of its ancestors are\n\t\t// being erased, then we reduce the opacity of the shape and all of its\n\t\t// ancestors; but we don't apply this effect more than once among a set\n\t\t// of descendants so that it does not compound.\n\n\t\t// This is designed to keep all the shapes in a single list which\n\t\t// allows the DOM nodes to be reused even when they become children\n\t\t// of other nodes.\n\n\t\tconst renderingShapes: TLRenderingShape[] = []\n\n\t\tlet nextIndex = this.options.maxShapesPerPage * 2\n\t\tlet nextBackgroundIndex = this.options.maxShapesPerPage\n\n\t\tconst erasingShapeIds = this.getErasingShapeIds()\n\n\t\tconst addShapeById = (id: TLShapeId, opacity: number, isAncestorErasing: boolean) => {\n\t\t\tconst shape = this.getShape(id)\n\t\t\tif (!shape) return\n\t\t\tif (this.isShapeHidden(shape)) return\n\n\t\t\topacity *= shape.opacity\n\t\t\tlet isShapeErasing = false\n\t\t\tconst util = this.getShapeUtil(shape)\n\n\t\t\tif (useEditorState) {\n\t\t\t\tisShapeErasing = !isAncestorErasing && erasingShapeIds.includes(id)\n\t\t\t\tif (isShapeErasing) {\n\t\t\t\t\topacity *= 0.32\n\t\t\t\t}\n\t\t\t}\n\n\t\t\trenderingShapes.push({\n\t\t\t\tid,\n\t\t\t\tshape,\n\t\t\t\tutil,\n\t\t\t\tindex: nextIndex,\n\t\t\t\tbackgroundIndex: nextBackgroundIndex,\n\t\t\t\topacity,\n\t\t\t})\n\n\t\t\tnextIndex += 1\n\t\t\tnextBackgroundIndex += 1\n\n\t\t\tconst childIds = this.getSortedChildIdsForParent(id)\n\t\t\tif (!childIds.length) return\n\n\t\t\tlet backgroundIndexToRestore = null\n\t\t\tif (util.providesBackgroundForChildren(shape)) {\n\t\t\t\tbackgroundIndexToRestore = nextBackgroundIndex\n\t\t\t\tnextBackgroundIndex = nextIndex\n\t\t\t\tnextIndex += this.options.maxShapesPerPage\n\t\t\t}\n\n\t\t\tfor (const childId of childIds) {\n\t\t\t\taddShapeById(childId, opacity, isAncestorErasing || isShapeErasing)\n\t\t\t}\n\n\t\t\tif (backgroundIndexToRestore !== null) {\n\t\t\t\tnextBackgroundIndex = backgroundIndexToRestore\n\t\t\t}\n\t\t}\n\n\t\t// If we're using editor state, then we're only interested in on-screen shapes.\n\t\t// If we're not using the editor state, then we're interested in ALL shapes, even those from other pages.\n\t\tconst pages = useEditorState ? [this.getCurrentPage()] : this.getPages()\n\t\tfor (const page of pages) {\n\t\t\tfor (const childId of this.getSortedChildIdsForParent(page.id)) {\n\t\t\t\taddShapeById(childId, 1, false)\n\t\t\t}\n\t\t}\n\n\t\treturn renderingShapes\n\t}\n\n\t// Camera state\n\t// Camera state does two things: first, it allows us to subscribe to whether\n\t// the camera is moving or not; and second, it allows us to update the rendering\n\t// shapes on the canvas. Changing the rendering shapes may cause shapes to\n\t// unmount / remount in the DOM, which is expensive; and computing visibility is\n\t// also expensive in large projects. For this reason, we use a second bounding\n\t// box just for rendering, and we only update after the camera stops moving.\n\tprivate _cameraState = atom('camera state', 'idle' as 'idle' | 'moving')\n\tprivate _cameraStateTimeoutRemaining = 0\n\t_decayCameraStateTimeout(elapsed: number) {\n\t\tthis._cameraStateTimeoutRemaining -= elapsed\n\t\tif (this._cameraStateTimeoutRemaining > 0) return\n\t\tthis.off('tick', this._decayCameraStateTimeout)\n\t\tthis._cameraState.set('idle')\n\t}\n\t_tickCameraState() {\n\t\t// always reset the timeout\n\t\tthis._cameraStateTimeoutRemaining = this.options.cameraMovingTimeoutMs\n\t\t// If the state is idle, then start the tick\n\t\tif (this._cameraState.__unsafe__getWithoutCapture() !== 'idle') return\n\t\tthis._cameraState.set('moving')\n\t\tthis.on('tick', this._decayCameraStateTimeout)\n\t}\n\n\t/**\n\t * Whether the camera is moving or idle.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getCameraState()\n\t * ```\n\t *\n\t * @public\n\t */\n\tgetCameraState() {\n\t\treturn this._cameraState.get()\n\t}\n\n\t/**\n\t * Get the shapes that should be displayed in the current viewport.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getRenderingShapes()\n\t * ```\n\t *\n\t * @public\n\t */\n\t@computed getRenderingShapes() {\n\t\tconst renderingShapes = this.getUnorderedRenderingShapes(true)\n\n\t\t// Its IMPORTANT that the result be sorted by id AND include the index\n\t\t// that the shape should be displayed at. Steve, this is the past you\n\t\t// telling the present you not to change this.\n\n\t\t// We want to sort by id because moving elements about in the DOM will\n\t\t// cause the element to get removed by react as it moves the DOM node. This\n\t\t// causes to re-render which is hella annoying and a perf\n\t\t// drain. By always sorting by 'id' we keep the shapes always in the\n\t\t// same order; but we later use index to set the element's 'z-index'\n\t\t// to change the \"rendered\" position in z-space.\n\t\treturn renderingShapes.sort(sortById)\n\t}\n\n\t/* --------------------- Pages ---------------------- */\n\n\t@computed private _getAllPagesQuery() {\n\t\treturn this.store.query.records('page')\n\t}\n\n\t/**\n\t * Info about the project's current pages.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getPages()\n\t * ```\n\t *\n\t * @public\n\t */\n\t@computed getPages(): TLPage[] {\n\t\treturn this._getAllPagesQuery().get().sort(sortByIndex)\n\t}\n\n\t/**\n\t * The current page.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getCurrentPage()\n\t * ```\n\t *\n\t * @public\n\t */\n\tgetCurrentPage(): TLPage {\n\t\treturn this.getPage(this.getCurrentPageId())!\n\t}\n\n\t/**\n\t * The current page id.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getCurrentPageId()\n\t * ```\n\t *\n\t * @public\n\t */\n\t@computed getCurrentPageId(): TLPageId {\n\t\treturn this.getInstanceState().currentPageId\n\t}\n\n\t/**\n\t * Get a page.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getPage(myPage.id)\n\t * editor.getPage(myPage)\n\t * ```\n\t *\n\t * @param page - The page (or page id) to get.\n\t *\n\t * @public\n\t */\n\tgetPage(page: TLPageId | TLPage): TLPage | undefined {\n\t\treturn this.store.get(typeof page === 'string' ? page : page.id)\n\t}\n\n\t/* @internal */\n\tprivate readonly _currentPageShapeIds: ReturnType\n\n\t/**\n\t * An array of all of the shapes on the current page.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getCurrentPageIds()\n\t * ```\n\t *\n\t * @public\n\t */\n\tgetCurrentPageShapeIds() {\n\t\treturn this._currentPageShapeIds.get()\n\t}\n\n\t/**\n\t * @internal\n\t */\n\t@computed\n\tgetCurrentPageShapeIdsSorted() {\n\t\treturn Array.from(this.getCurrentPageShapeIds()).sort()\n\t}\n\n\t/**\n\t * Get the ids of shapes on a page.\n\t *\n\t * @example\n\t * ```ts\n\t * const idsOnPage1 = editor.getPageShapeIds('page1')\n\t * const idsOnPage2 = editor.getPageShapeIds(myPage2)\n\t * ```\n\t *\n\t * @param page - The page (or page id) to get.\n\t *\n\t * @public\n\t **/\n\tgetPageShapeIds(page: TLPageId | TLPage): Set {\n\t\tconst pageId = typeof page === 'string' ? page : page.id\n\t\tconst result = this.store.query.exec('shape', { parentId: { eq: pageId } })\n\t\treturn this.getShapeAndDescendantIds(result.map((s) => s.id))\n\t}\n\n\t/**\n\t * Set the current page.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.setCurrentPage('page1')\n\t * editor.setCurrentPage(myPage1)\n\t * ```\n\t *\n\t * @param page - The page (or page id) to set as the current page.\n\t *\n\t * @public\n\t */\n\tsetCurrentPage(page: TLPageId | TLPage): this {\n\t\tconst pageId = typeof page === 'string' ? page : page.id\n\t\tif (!this.store.has(pageId)) {\n\t\t\tconsole.error(\"Tried to set the current page id to a page that doesn't exist.\")\n\t\t\treturn this\n\t\t}\n\n\t\tthis.stopFollowingUser()\n\t\t// finish off any in-progress interactions\n\t\tthis.complete()\n\n\t\treturn this.run(\n\t\t\t() => {\n\t\t\t\tthis.store.put([{ ...this.getInstanceState(), currentPageId: pageId }])\n\t\t\t},\n\t\t\t{ history: 'record-preserveRedoStack' }\n\t\t)\n\t}\n\n\t/**\n\t * Update a page.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.updatePage({ id: 'page2', name: 'Page 2' })\n\t * ```\n\t *\n\t * @param partial - The partial of the shape to update.\n\t *\n\t * @public\n\t */\n\tupdatePage(partial: RequiredKeys, 'id'>): this {\n\t\tif (this.getInstanceState().isReadonly) return this\n\n\t\tconst prev = this.getPage(partial.id)\n\t\tif (!prev) return this\n\n\t\treturn this.run(() => this.store.update(partial.id, (page) => ({ ...page, ...partial })))\n\t}\n\n\t/**\n\t * Create a page.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.createPage(myPage)\n\t * editor.createPage({ name: 'Page 2' })\n\t * ```\n\t *\n\t * @param page - The page (or page partial) to create.\n\t *\n\t * @public\n\t */\n\tcreatePage(page: Partial): this {\n\t\tthis.run(() => {\n\t\t\tif (this.getInstanceState().isReadonly) return\n\t\t\tif (this.getPages().length >= this.options.maxPages) return\n\t\t\tconst pages = this.getPages()\n\n\t\t\tconst name = getIncrementedName(\n\t\t\t\tpage.name ?? 'Page 1',\n\t\t\t\tpages.map((p) => p.name)\n\t\t\t)\n\n\t\t\tlet index = page.index\n\n\t\t\tif (!index || pages.some((p) => p.index === index)) {\n\t\t\t\tindex = getIndexAbove(pages[pages.length - 1].index)\n\t\t\t}\n\n\t\t\tconst newPage = PageRecordType.create({\n\t\t\t\tmeta: {},\n\t\t\t\t...page,\n\t\t\t\tname,\n\t\t\t\tindex,\n\t\t\t})\n\n\t\t\tthis.store.put([newPage])\n\t\t})\n\t\treturn this\n\t}\n\n\t/**\n\t * Delete a page.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.deletePage('page1')\n\t * ```\n\t *\n\t * @param id - The id of the page to delete.\n\t *\n\t * @public\n\t */\n\tdeletePage(page: TLPageId | TLPage): this {\n\t\tconst id = typeof page === 'string' ? page : page.id\n\t\tthis.run(() => {\n\t\t\tif (this.getInstanceState().isReadonly) return\n\t\t\tconst pages = this.getPages()\n\t\t\tif (pages.length === 1) return\n\n\t\t\tconst deletedPage = this.getPage(id)\n\t\t\tif (!deletedPage) return\n\n\t\t\tif (id === this.getCurrentPageId()) {\n\t\t\t\tconst index = pages.findIndex((page) => page.id === id)\n\t\t\t\tconst next = pages[index - 1] ?? pages[index + 1]\n\t\t\t\tthis.setCurrentPage(next.id)\n\t\t\t}\n\t\t\tthis.store.remove([deletedPage.id])\n\t\t})\n\t\treturn this\n\t}\n\n\t/**\n\t * Duplicate a page.\n\t *\n\t * @param id - The id of the page to duplicate. Defaults to the current page.\n\t * @param createId - The id of the new page. Defaults to a new id.\n\t *\n\t * @public\n\t */\n\tduplicatePage(page: TLPageId | TLPage, createId: TLPageId = PageRecordType.createId()): this {\n\t\tif (this.getPages().length >= this.options.maxPages) return this\n\t\tconst id = typeof page === 'string' ? page : page.id\n\t\tconst freshPage = this.getPage(id) // get the most recent version of the page anyway\n\t\tif (!freshPage) return this\n\n\t\tconst prevCamera = { ...this.getCamera() }\n\t\tconst content = this.getContentFromCurrentPage(this.getSortedChildIdsForParent(freshPage.id))\n\n\t\tthis.run(() => {\n\t\t\tconst pages = this.getPages()\n\t\t\tconst index = getIndexBetween(freshPage.index, pages[pages.indexOf(freshPage) + 1]?.index)\n\n\t\t\t// create the page (also creates the pagestate and camera for the new page)\n\t\t\tthis.createPage({ name: freshPage.name + ' Copy', id: createId, index })\n\t\t\t// set the new page as the current page\n\t\t\tthis.setCurrentPage(createId)\n\t\t\t// update the new page's camera to the previous page's camera\n\t\t\tthis.setCamera(prevCamera)\n\n\t\t\tif (content) {\n\t\t\t\t// If we had content on the previous page, put it on the new page\n\t\t\t\treturn this.putContentOntoCurrentPage(content)\n\t\t\t}\n\t\t})\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Rename a page.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.renamePage('page1', 'My Page')\n\t * ```\n\t *\n\t * @param id - The id of the page to rename.\n\t * @param name - The new name.\n\t *\n\t * @public\n\t */\n\trenamePage(page: TLPageId | TLPage, name: string) {\n\t\tconst id = typeof page === 'string' ? page : page.id\n\t\tif (this.getInstanceState().isReadonly) return this\n\t\tthis.updatePage({ id, name })\n\t\treturn this\n\t}\n\n\t/* --------------------- Assets --------------------- */\n\n\t/** @internal */\n\t@computed private _getAllAssetsQuery() {\n\t\treturn this.store.query.records('asset')\n\t}\n\n\t/**\n\t * Get all assets in the editor.\n\t *\n\t * @public\n\t */\n\tgetAssets() {\n\t\treturn this._getAllAssetsQuery().get()\n\t}\n\n\t/**\n\t * Create one or more assets.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.createAssets([...myAssets])\n\t * ```\n\t *\n\t * @param assets - The assets to create.\n\t *\n\t * @public\n\t */\n\tcreateAssets(assets: TLAsset[]): this {\n\t\tif (this.getInstanceState().isReadonly) return this\n\t\tif (assets.length <= 0) return this\n\t\tthis.run(() => this.store.put(assets), { history: 'ignore' })\n\t\treturn this\n\t}\n\n\t/**\n\t * Update one or more assets.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.updateAssets([{ id: 'asset1', name: 'New name' }])\n\t * ```\n\t *\n\t * @param assets - The assets to update.\n\t *\n\t * @public\n\t */\n\tupdateAssets(assets: TLAssetPartial[]): this {\n\t\tif (this.getInstanceState().isReadonly) return this\n\t\tif (assets.length <= 0) return this\n\t\tthis.run(\n\t\t\t() => {\n\t\t\t\tthis.store.put(\n\t\t\t\t\tassets.map((partial) => ({\n\t\t\t\t\t\t...this.store.get(partial.id)!,\n\t\t\t\t\t\t...partial,\n\t\t\t\t\t}))\n\t\t\t\t)\n\t\t\t},\n\t\t\t{ history: 'ignore' }\n\t\t)\n\t\treturn this\n\t}\n\n\t/**\n\t * Delete one or more assets.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.deleteAssets(['asset1', 'asset2'])\n\t * ```\n\t *\n\t * @param ids - The assets to delete.\n\t *\n\t * @public\n\t */\n\tdeleteAssets(assets: TLAssetId[] | TLAsset[]): this {\n\t\tif (this.getInstanceState().isReadonly) return this\n\n\t\tconst ids =\n\t\t\ttypeof assets[0] === 'string'\n\t\t\t\t? (assets as TLAssetId[])\n\t\t\t\t: (assets as TLAsset[]).map((a) => a.id)\n\t\tif (ids.length <= 0) return this\n\n\t\tthis.run(() => this.store.remove(ids), { history: 'ignore' })\n\t\treturn this\n\t}\n\n\t/**\n\t * Get an asset by its id.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getAsset('asset1')\n\t * ```\n\t *\n\t * @param asset - The asset (or asset id) to get.\n\t *\n\t * @public\n\t */\n\tgetAsset(asset: TLAssetId | TLAsset): TLAsset | undefined {\n\t\treturn this.store.get(typeof asset === 'string' ? asset : asset.id) as TLAsset | undefined\n\t}\n\n\tasync resolveAssetUrl(\n\t\tassetId: TLAssetId | null,\n\t\tcontext: {\n\t\t\tscreenScale?: number\n\t\t\tshouldResolveToOriginal?: boolean\n\t\t}\n\t): Promise {\n\t\tif (!assetId) return null\n\t\tconst asset = this.getAsset(assetId)\n\t\tif (!asset) return null\n\n\t\tconst { screenScale = 1, shouldResolveToOriginal = false } = context\n\n\t\t// We only look at the zoom level at powers of 2.\n\t\tconst zoomStepFunction = (zoom: number) => Math.pow(2, Math.ceil(Math.log2(zoom)))\n\t\tconst steppedScreenScale = Math.max(0.125, zoomStepFunction(screenScale))\n\t\tconst networkEffectiveType: string | null =\n\t\t\t'connection' in navigator ? (navigator as any).connection.effectiveType : null\n\t\tconst dpr = this.getInstanceState().devicePixelRatio\n\n\t\treturn await this.store.props.assets.resolve(asset, {\n\t\t\tscreenScale: screenScale || 1,\n\t\t\tsteppedScreenScale,\n\t\t\tdpr,\n\t\t\tnetworkEffectiveType,\n\t\t\tshouldResolveToOriginal,\n\t\t})\n\t}\n\t/**\n\t * Upload an asset to the store's asset service, returning a URL that can be used to resolve the\n\t * asset.\n\t */\n\tasync uploadAsset(asset: TLAsset, file: File): Promise {\n\t\treturn await this.store.props.assets.upload(asset, file)\n\t}\n\n\t/* --------------------- Shapes --------------------- */\n\n\t@computed\n\tprivate _getShapeGeometryCache(): ComputedCache {\n\t\treturn this.store.createComputedCache(\n\t\t\t'bounds',\n\t\t\t(shape) => this.getShapeUtil(shape).getGeometry(shape),\n\t\t\t(a, b) => a.props === b.props\n\t\t)\n\t}\n\n\t/**\n\t * Get the geometry of a shape.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getShapeGeometry(myShape)\n\t * editor.getShapeGeometry(myShapeId)\n\t * ```\n\t *\n\t * @param shape - The shape (or shape id) to get the geometry for.\n\t *\n\t * @public\n\t */\n\tgetShapeGeometry(shape: TLShape | TLShapeId): T {\n\t\treturn this._getShapeGeometryCache().get(typeof shape === 'string' ? shape : shape.id)! as T\n\t}\n\n\t/** @internal */\n\t@computed private _getShapeHandlesCache(): ComputedCache {\n\t\treturn this.store.createComputedCache('handles', (shape) => {\n\t\t\treturn this.getShapeUtil(shape).getHandles?.(shape)\n\t\t})\n\t}\n\n\t/**\n\t * Get the handles (if any) for a shape.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getShapeHandles(myShape)\n\t * editor.getShapeHandles(myShapeId)\n\t * ```\n\t *\n\t * @param shape - The shape (or shape id) to get the handles for.\n\t * @public\n\t */\n\tgetShapeHandles(shape: T | T['id']): TLHandle[] | undefined {\n\t\treturn this._getShapeHandlesCache().get(typeof shape === 'string' ? shape : shape.id)\n\t}\n\n\t/**\n\t * Get the local transform for a shape as a matrix model. This transform reflects both its\n\t * translation (x, y) from from either its parent's top left corner, if the shape's parent is\n\t * another shape, or else from the 0,0 of the page, if the shape's parent is the page; and the\n\t * shape's rotation.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getShapeLocalTransform(myShape)\n\t * ```\n\t *\n\t * @param shape - The shape to get the local transform for.\n\t *\n\t * @public\n\t */\n\tgetShapeLocalTransform(shape: TLShape | TLShapeId): Mat {\n\t\tconst id = typeof shape === 'string' ? shape : shape.id\n\t\tconst freshShape = this.getShape(id)\n\t\tif (!freshShape) throw Error('Editor.getTransform: shape not found')\n\t\treturn Mat.Identity().translate(freshShape.x, freshShape.y).rotate(freshShape.rotation)\n\t}\n\n\t/**\n\t * A cache of page transforms.\n\t *\n\t * @internal\n\t */\n\t@computed private _getShapePageTransformCache(): ComputedCache {\n\t\treturn this.store.createComputedCache('pageTransformCache', (shape) => {\n\t\t\tif (isPageId(shape.parentId)) {\n\t\t\t\treturn this.getShapeLocalTransform(shape)\n\t\t\t}\n\n\t\t\t// If the shape's parent doesn't exist yet (e.g. when merging in changes from remote in the wrong order)\n\t\t\t// then we can't compute the transform yet, so just return the identity matrix.\n\t\t\t// In the future we should look at creating a store update mechanism that understands and preserves\n\t\t\t// ordering.\n\t\t\tconst parentTransform =\n\t\t\t\tthis._getShapePageTransformCache().get(shape.parentId) ?? Mat.Identity()\n\t\t\treturn Mat.Compose(parentTransform, this.getShapeLocalTransform(shape)!)\n\t\t})\n\t}\n\n\t/**\n\t * Get the local transform of a shape's parent as a matrix model.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getShapeParentTransform(myShape)\n\t * ```\n\t *\n\t * @param shape - The shape (or shape id) to get the parent transform for.\n\t *\n\t * @public\n\t */\n\tgetShapeParentTransform(shape: TLShape | TLShapeId): Mat {\n\t\tconst id = typeof shape === 'string' ? shape : shape.id\n\t\tconst freshShape = this.getShape(id)\n\t\tif (!freshShape || isPageId(freshShape.parentId)) return Mat.Identity()\n\t\treturn this._getShapePageTransformCache().get(freshShape.parentId) ?? Mat.Identity()\n\t}\n\n\t/**\n\t * Get the transform of a shape in the current page space.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getShapePageTransform(myShape)\n\t * editor.getShapePageTransform(myShapeId)\n\t * ```\n\t *\n\t * @param shape - The shape (or shape id) to get the page transform for.\n\t *\n\t * @public\n\t */\n\tgetShapePageTransform(shape: TLShape | TLShapeId): Mat {\n\t\tconst id = typeof shape === 'string' ? shape : shape.id\n\t\treturn this._getShapePageTransformCache().get(id) ?? Mat.Identity()\n\t}\n\n\t/** @internal */\n\t@computed private _getShapePageBoundsCache(): ComputedCache {\n\t\treturn this.store.createComputedCache('pageBoundsCache', (shape) => {\n\t\t\tconst pageTransform = this._getShapePageTransformCache().get(shape.id)\n\n\t\t\tif (!pageTransform) return new Box()\n\n\t\t\tconst result = Box.FromPoints(\n\t\t\t\tMat.applyToPoints(pageTransform, this.getShapeGeometry(shape).vertices)\n\t\t\t)\n\n\t\t\treturn result\n\t\t})\n\t}\n\n\t/**\n\t * Get the bounds of a shape in the current page space.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getShapePageBounds(myShape)\n\t * editor.getShapePageBounds(myShapeId)\n\t * ```\n\t *\n\t * @param shape - The shape (or shape id) to get the bounds for.\n\t *\n\t * @public\n\t */\n\tgetShapePageBounds(shape: TLShape | TLShapeId): Box | undefined {\n\t\treturn this._getShapePageBoundsCache().get(typeof shape === 'string' ? shape : shape.id)\n\t}\n\n\t/**\n\t * A cache of clip paths used for clipping.\n\t *\n\t * @internal\n\t */\n\t@computed private _getShapeClipPathCache(): ComputedCache {\n\t\treturn this.store.createComputedCache('clipPathCache', (shape) => {\n\t\t\tconst pageMask = this._getShapeMaskCache().get(shape.id)\n\t\t\tif (!pageMask) return undefined\n\t\t\tif (pageMask.length === 0) {\n\t\t\t\treturn `polygon(0px 0px, 0px 0px, 0px 0px)`\n\t\t\t}\n\n\t\t\tconst pageTransform = this._getShapePageTransformCache().get(shape.id)\n\t\t\tif (!pageTransform) return undefined\n\n\t\t\tconst localMask = Mat.applyToPoints(Mat.Inverse(pageTransform), pageMask)\n\n\t\t\treturn `polygon(${localMask.map((p) => `${p.x}px ${p.y}px`).join(',')})`\n\t\t})\n\t}\n\n\t/**\n\t * Get the clip path for a shape.\n\t *\n\t * @example\n\t * ```ts\n\t * const clipPath = editor.getShapeClipPath(shape)\n\t * const clipPath = editor.getShapeClipPath(shape.id)\n\t * ```\n\t *\n\t * @param shape - The shape (or shape id) to get the clip path for.\n\t *\n\t * @returns The clip path or undefined.\n\t *\n\t * @public\n\t */\n\tgetShapeClipPath(shape: TLShape | TLShapeId): string | undefined {\n\t\treturn this._getShapeClipPathCache().get(typeof shape === 'string' ? shape : shape.id)\n\t}\n\n\t/** @internal */\n\t@computed private _getShapeMaskCache(): ComputedCache {\n\t\treturn this.store.createComputedCache('pageMaskCache', (shape) => {\n\t\t\tif (isPageId(shape.parentId)) return undefined\n\n\t\t\tconst frameAncestors = this.getShapeAncestors(shape.id).filter((shape) =>\n\t\t\t\tthis.isShapeOfType(shape, 'frame')\n\t\t\t)\n\n\t\t\tif (frameAncestors.length === 0) return undefined\n\n\t\t\tconst pageMask = frameAncestors\n\t\t\t\t.map((s) =>\n\t\t\t\t\t// Apply the frame transform to the frame outline to get the frame outline in the current page space\n\t\t\t\t\tthis._getShapePageTransformCache()\n\t\t\t\t\t\t.get(s.id)!\n\t\t\t\t\t\t.applyToPoints(this.getShapeGeometry(s).vertices)\n\t\t\t\t)\n\t\t\t\t.reduce((acc, b) => {\n\t\t\t\t\tif (!(b && acc)) return undefined\n\t\t\t\t\tconst intersection = intersectPolygonPolygon(acc, b)\n\t\t\t\t\tif (intersection) {\n\t\t\t\t\t\treturn intersection.map(Vec.Cast)\n\t\t\t\t\t}\n\t\t\t\t\treturn []\n\t\t\t\t})\n\n\t\t\treturn pageMask\n\t\t})\n\t}\n\n\t/**\n\t * Get the mask (in the current page space) for a shape.\n\t *\n\t * @example\n\t * ```ts\n\t * const pageMask = editor.getShapeMask(shape.id)\n\t * ```\n\t *\n\t * @param id - The id of the shape to get the mask for.\n\t *\n\t * @returns The mask for the shape.\n\t *\n\t * @public\n\t */\n\tgetShapeMask(shape: TLShapeId | TLShape): VecLike[] | undefined {\n\t\treturn this._getShapeMaskCache().get(typeof shape === 'string' ? shape : shape.id)\n\t}\n\n\t/**\n\t * Get the bounds of a shape in the current page space, incorporating any masks. For example, if the\n\t * shape were the child of a frame and was half way out of the frame, the bounds would be the half\n\t * of the shape that was in the frame.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getShapeMaskedPageBounds(myShape)\n\t * editor.getShapeMaskedPageBounds(myShapeId)\n\t * ```\n\t *\n\t * @param shape - The shape to get the masked bounds for.\n\t *\n\t * @public\n\t */\n\tgetShapeMaskedPageBounds(shape: TLShapeId | TLShape): Box | undefined {\n\t\tif (typeof shape !== 'string') shape = shape.id\n\t\treturn this._getShapeMaskedPageBoundsCache().get(shape)\n\t}\n\n\t/** @internal */\n\t@computed private _getShapeMaskedPageBoundsCache(): ComputedCache {\n\t\treturn this.store.createComputedCache('shapeMaskedPageBoundsCache', (shape) => {\n\t\t\tconst pageBounds = this._getShapePageBoundsCache().get(shape.id)\n\t\t\tif (!pageBounds) return\n\t\t\tconst pageMask = this._getShapeMaskCache().get(shape.id)\n\t\t\tif (pageMask) {\n\t\t\t\tif (pageMask.length === 0) return undefined\n\t\t\t\tconst { corners } = pageBounds\n\t\t\t\tif (corners.every((p, i) => p && Vec.Equals(p, pageMask[i]))) return pageBounds.clone()\n\t\t\t\tconst intersection = intersectPolygonPolygon(pageMask, corners)\n\t\t\t\tif (!intersection) return\n\t\t\t\treturn Box.FromPoints(intersection)\n\t\t\t}\n\t\t\treturn pageBounds\n\t\t})\n\t}\n\n\t/**\n\t * Get the ancestors of a shape.\n\t *\n\t * @example\n\t * ```ts\n\t * const ancestors = editor.getShapeAncestors(myShape)\n\t * const ancestors = editor.getShapeAncestors(myShapeId)\n\t * ```\n\t *\n\t * @param shape - The shape (or shape id) to get the ancestors for.\n\t *\n\t * @public\n\t */\n\tgetShapeAncestors(shape: TLShapeId | TLShape, acc: TLShape[] = []): TLShape[] {\n\t\tconst id = typeof shape === 'string' ? shape : shape.id\n\t\tconst freshShape = this.getShape(id)\n\t\tif (!freshShape) return acc\n\t\tconst parentId = freshShape.parentId\n\t\tif (isPageId(parentId)) {\n\t\t\tacc.reverse()\n\t\t\treturn acc\n\t\t}\n\n\t\tconst parent = this.store.get(parentId)\n\t\tif (!parent) return acc\n\t\tacc.push(parent)\n\t\treturn this.getShapeAncestors(parent, acc)\n\t}\n\n\t/**\n\t * Find the first ancestor matching the given predicate\n\t *\n\t * @example\n\t * ```ts\n\t * const ancestor = editor.findShapeAncestor(myShape)\n\t * const ancestor = editor.findShapeAncestor(myShape.id)\n\t * const ancestor = editor.findShapeAncestor(myShape.id, (shape) => shape.type === 'frame')\n\t * ```\n\t *\n\t * @param shape - The shape to check the ancestors for.\n\t *\n\t * @public\n\t */\n\tfindShapeAncestor(\n\t\tshape: TLShape | TLShapeId,\n\t\tpredicate: (parent: TLShape) => boolean\n\t): TLShape | undefined {\n\t\tconst id = typeof shape === 'string' ? shape : shape.id\n\t\tconst freshShape = this.getShape(id)\n\t\tif (!freshShape) return\n\n\t\tconst parentId = freshShape.parentId\n\t\tif (isPageId(parentId)) return\n\n\t\tconst parent = this.getShape(parentId)\n\t\tif (!parent) return\n\t\treturn predicate(parent) ? parent : this.findShapeAncestor(parent, predicate)\n\t}\n\n\t/**\n\t * Returns true if the the given shape has the given ancestor.\n\t *\n\t * @param shape - The shape.\n\t * @param ancestorId - The id of the ancestor.\n\t *\n\t * @public\n\t */\n\thasAncestor(shape: TLShape | TLShapeId | undefined, ancestorId: TLShapeId): boolean {\n\t\tconst id = typeof shape === 'string' ? shape : shape?.id\n\t\tconst freshShape = id && this.getShape(id)\n\t\tif (!freshShape) return false\n\t\tif (freshShape.parentId === ancestorId) return true\n\t\treturn this.hasAncestor(this.getShapeParent(freshShape), ancestorId)\n\t}\n\n\t/**\n\t * Get the common ancestor of two or more shapes that matches a predicate.\n\t *\n\t * @param shapes - The shapes (or shape ids) to check.\n\t * @param predicate - The predicate to match.\n\t */\n\tfindCommonAncestor(\n\t\tshapes: TLShape[] | TLShapeId[],\n\t\tpredicate?: (shape: TLShape) => boolean\n\t): TLShapeId | undefined {\n\t\tif (shapes.length === 0) {\n\t\t\treturn\n\t\t}\n\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\t\tconst freshShapes = compact(ids.map((id) => this.getShape(id)))\n\n\t\tif (freshShapes.length === 1) {\n\t\t\tconst parentId = freshShapes[0].parentId\n\t\t\tif (isPageId(parentId)) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\treturn predicate ? this.findShapeAncestor(freshShapes[0], predicate)?.id : parentId\n\t\t}\n\n\t\tconst [nodeA, ...others] = freshShapes\n\t\tlet ancestor = this.getShapeParent(nodeA)\n\t\twhile (ancestor) {\n\t\t\t// TODO: this is not ideal, optimize\n\t\t\tif (predicate && !predicate(ancestor)) {\n\t\t\t\tancestor = this.getShapeParent(ancestor)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif (others.every((shape) => this.hasAncestor(shape, ancestor!.id))) {\n\t\t\t\treturn ancestor!.id\n\t\t\t}\n\t\t\tancestor = this.getShapeParent(ancestor)\n\t\t}\n\t\treturn undefined\n\t}\n\n\t/**\n\t * Check whether a shape or its parent is locked.\n\t *\n\t * @param shape - The shape (or shape id) to check.\n\t *\n\t * @public\n\t */\n\tisShapeOrAncestorLocked(shape?: TLShape): boolean\n\tisShapeOrAncestorLocked(id?: TLShapeId): boolean\n\tisShapeOrAncestorLocked(arg?: TLShape | TLShapeId): boolean {\n\t\tconst shape = typeof arg === 'string' ? this.getShape(arg) : arg\n\t\tif (shape === undefined) return false\n\t\tif (shape.isLocked) return true\n\t\treturn this.isShapeOrAncestorLocked(this.getShapeParent(shape))\n\t}\n\n\t@computed\n\tprivate _notVisibleShapes() {\n\t\treturn notVisibleShapes(this)\n\t}\n\n\t/**\n\t * Get culled shapes.\n\t *\n\t * @public\n\t */\n\t@computed\n\tgetCulledShapes() {\n\t\tconst notVisibleShapes = this._notVisibleShapes().get()\n\t\tconst selectedShapeIds = this.getSelectedShapeIds()\n\t\tconst editingId = this.getEditingShapeId()\n\t\tconst culledShapes = new Set(notVisibleShapes)\n\t\t// we don't cull the shape we are editing\n\t\tif (editingId) {\n\t\t\tculledShapes.delete(editingId)\n\t\t}\n\t\t// we also don't cull selected shapes\n\t\tselectedShapeIds.forEach((id) => {\n\t\t\tculledShapes.delete(id)\n\t\t})\n\t\treturn culledShapes\n\t}\n\n\t/**\n\t * The bounds of the current page (the common bounds of all of the shapes on the page).\n\t *\n\t * @public\n\t */\n\t@computed getCurrentPageBounds(): Box | undefined {\n\t\tlet commonBounds: Box | undefined\n\n\t\tthis.getCurrentPageShapeIdsSorted().forEach((shapeId) => {\n\t\t\tconst bounds = this.getShapeMaskedPageBounds(shapeId)\n\t\t\tif (!bounds) return\n\t\t\tif (!commonBounds) {\n\t\t\t\tcommonBounds = bounds.clone()\n\t\t\t} else {\n\t\t\t\tcommonBounds = commonBounds.expand(bounds)\n\t\t\t}\n\t\t})\n\n\t\treturn commonBounds\n\t}\n\n\t/**\n\t * Get the top-most selected shape at the given point, ignoring groups.\n\t *\n\t * @param point - The point to check.\n\t *\n\t * @returns The top-most selected shape at the given point, or undefined if there is no shape at the point.\n\t */\n\tgetSelectedShapeAtPoint(point: VecLike): TLShape | undefined {\n\t\tconst selectedShapeIds = this.getSelectedShapeIds()\n\t\treturn this.getCurrentPageShapesSorted()\n\t\t\t.filter((shape) => shape.type !== 'group' && selectedShapeIds.includes(shape.id))\n\t\t\t.reverse() // find last\n\t\t\t.find((shape) => this.isPointInShape(shape, point, { hitInside: true, margin: 0 }))\n\t}\n\n\t/**\n\t * Get the shape at the current point.\n\t *\n\t * @param point - The point to check.\n\t * @param opts - Options for the check: `hitInside` to check if the point is inside the shape, `margin` to check if the point is within a margin of the shape, `hitFrameInside` to check if the point is inside the frame, and `filter` to filter the shapes to check.\n\t *\n\t * @returns The shape at the given point, or undefined if there is no shape at the point.\n\t */\n\tgetShapeAtPoint(\n\t\tpoint: VecLike,\n\t\topts = {} as {\n\t\t\trenderingOnly?: boolean\n\t\t\tmargin?: number\n\t\t\thitInside?: boolean\n\t\t\thitLocked?: boolean\n\t\t\t// TODO: we probably need to rename this, we don't quite _always_\n\t\t\t// respect this esp. in the part below that does \"Check labels first\"\n\t\t\thitLabels?: boolean\n\t\t\thitFrameInside?: boolean\n\t\t\tfilter?(shape: TLShape): boolean\n\t\t}\n\t): TLShape | undefined {\n\t\tconst zoomLevel = this.getZoomLevel()\n\t\tconst viewportPageBounds = this.getViewportPageBounds()\n\t\tconst {\n\t\t\tfilter,\n\t\t\tmargin = 0,\n\t\t\thitLocked = false,\n\t\t\thitLabels = false,\n\t\t\thitInside = false,\n\t\t\thitFrameInside = false,\n\t\t} = opts\n\n\t\tlet inHollowSmallestArea = Infinity\n\t\tlet inHollowSmallestAreaHit: TLShape | null = null\n\n\t\tlet inMarginClosestToEdgeDistance = Infinity\n\t\tlet inMarginClosestToEdgeHit: TLShape | null = null\n\n\t\tconst shapesToCheck = (\n\t\t\topts.renderingOnly\n\t\t\t\t? this.getCurrentPageRenderingShapesSorted()\n\t\t\t\t: this.getCurrentPageShapesSorted()\n\t\t).filter((shape) => {\n\t\t\tif (\n\t\t\t\t(shape.isLocked && !hitLocked) ||\n\t\t\t\tthis.isShapeHidden(shape) ||\n\t\t\t\tthis.isShapeOfType(shape, 'group')\n\t\t\t)\n\t\t\t\treturn false\n\t\t\tconst pageMask = this.getShapeMask(shape)\n\t\t\tif (pageMask && !pointInPolygon(point, pageMask)) return false\n\t\t\tif (filter) return filter(shape)\n\t\t\treturn true\n\t\t})\n\n\t\tfor (let i = shapesToCheck.length - 1; i >= 0; i--) {\n\t\t\tconst shape = shapesToCheck[i]\n\t\t\tconst geometry = this.getShapeGeometry(shape)\n\t\t\tconst isGroup = geometry instanceof Group2d\n\n\t\t\tconst pointInShapeSpace = this.getPointInShapeSpace(shape, point)\n\n\t\t\t// Check labels first\n\t\t\tif (\n\t\t\t\tthis.isShapeOfType(shape, 'arrow') ||\n\t\t\t\t(this.isShapeOfType(shape, 'geo') && shape.props.fill === 'none')\n\t\t\t) {\n\t\t\t\tif (shape.props.text.trim()) {\n\t\t\t\t\t// let's check whether the shape has a label and check that\n\t\t\t\t\tfor (const childGeometry of (geometry as Group2d).children) {\n\t\t\t\t\t\tif (childGeometry.isLabel && childGeometry.isPointInBounds(pointInShapeSpace)) {\n\t\t\t\t\t\t\treturn shape\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (this.isShapeOfType(shape, 'frame')) {\n\t\t\t\t// On the rare case that we've hit a frame, test again hitInside to be forced true;\n\t\t\t\t// this prevents clicks from passing through the body of a frame to shapes behind it.\n\n\t\t\t\t// If the hit is within the frame's outer margin, then select the frame\n\t\t\t\tconst distance = geometry.distanceToPoint(pointInShapeSpace, hitInside)\n\t\t\t\tif (Math.abs(distance) <= margin) {\n\t\t\t\t\treturn inMarginClosestToEdgeHit || shape\n\t\t\t\t}\n\n\t\t\t\tif (geometry.hitTestPoint(pointInShapeSpace, 0, true)) {\n\t\t\t\t\t// Once we've hit a frame, we want to end the search. If we have hit a shape\n\t\t\t\t\t// already, then this would either be above the frame or a child of the frame,\n\t\t\t\t\t// so we want to return that. Otherwise, the point is in the empty space of the\n\t\t\t\t\t// frame. If `hitFrameInside` is true (e.g. used drawing an arrow into the\n\t\t\t\t\t// frame) we the frame itself; other wise, (e.g. when hovering or pointing)\n\t\t\t\t\t// we would want to return null.\n\t\t\t\t\treturn (\n\t\t\t\t\t\tinMarginClosestToEdgeHit ||\n\t\t\t\t\t\tinHollowSmallestAreaHit ||\n\t\t\t\t\t\t(hitFrameInside ? shape : undefined)\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tlet distance: number\n\n\t\t\tif (isGroup) {\n\t\t\t\tlet minDistance = Infinity\n\t\t\t\tfor (const childGeometry of geometry.children) {\n\t\t\t\t\tif (childGeometry.isLabel && !hitLabels) continue\n\n\t\t\t\t\t// hit test the all of the child geometries that aren't labels\n\t\t\t\t\tconst tDistance = childGeometry.distanceToPoint(pointInShapeSpace, hitInside)\n\t\t\t\t\tif (tDistance < minDistance) {\n\t\t\t\t\t\tminDistance = tDistance\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tdistance = minDistance\n\t\t\t} else {\n\t\t\t\t// If the margin is zero and the geometry has a very small width or height,\n\t\t\t\t// then check the actual distance. This is to prevent a bug where straight\n\t\t\t\t// lines would never pass the broad phase (point-in-bounds) check.\n\t\t\t\tif (margin === 0 && (geometry.bounds.w < 1 || geometry.bounds.h < 1)) {\n\t\t\t\t\tdistance = geometry.distanceToPoint(pointInShapeSpace, hitInside)\n\t\t\t\t} else {\n\t\t\t\t\t// Broad phase\n\t\t\t\t\tif (geometry.bounds.containsPoint(pointInShapeSpace, margin)) {\n\t\t\t\t\t\t// Narrow phase (actual distance)\n\t\t\t\t\t\tdistance = geometry.distanceToPoint(pointInShapeSpace, hitInside)\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// Failed the broad phase, geddafugaotta'ere!\n\t\t\t\t\t\tdistance = Infinity\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (geometry.isClosed) {\n\t\t\t\t// For closed shapes, the distance will be positive if outside of\n\t\t\t\t// the shape or negative if inside of the shape. If the distance\n\t\t\t\t// is greater than the margin, then it's a miss. Otherwise...\n\n\t\t\t\tif (distance <= margin) {\n\t\t\t\t\tif (geometry.isFilled || (isGroup && geometry.children[0].isFilled)) {\n\t\t\t\t\t\t// If the shape is filled, then it's a hit. Remember, we're\n\t\t\t\t\t\t// starting from the TOP-MOST shape in z-index order, so any\n\t\t\t\t\t\t// other hits would be occluded by the shape.\n\t\t\t\t\t\treturn inMarginClosestToEdgeHit || shape\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// If the shape is bigger than the viewport, then skip it.\n\t\t\t\t\t\tif (this.getShapePageBounds(shape)!.contains(viewportPageBounds)) continue\n\n\t\t\t\t\t\t// For hollow shapes...\n\t\t\t\t\t\tif (Math.abs(distance) < margin) {\n\t\t\t\t\t\t\t// We want to preference shapes where we're inside of the\n\t\t\t\t\t\t\t// shape margin; and we would want to hit the shape with the\n\t\t\t\t\t\t\t// edge closest to the point.\n\t\t\t\t\t\t\tif (Math.abs(distance) < inMarginClosestToEdgeDistance) {\n\t\t\t\t\t\t\t\tinMarginClosestToEdgeDistance = Math.abs(distance)\n\t\t\t\t\t\t\t\tinMarginClosestToEdgeHit = shape\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else if (!inMarginClosestToEdgeHit) {\n\t\t\t\t\t\t\t// If we're not within margin distance to any edge, and if the\n\t\t\t\t\t\t\t// shape is hollow, then we want to hit the shape with the\n\t\t\t\t\t\t\t// smallest area. (There's a bug here with self-intersecting\n\t\t\t\t\t\t\t// shapes, like a closed drawing of an \"8\", but that's a bigger\n\t\t\t\t\t\t\t// problem to solve.)\n\t\t\t\t\t\t\tconst { area } = geometry\n\t\t\t\t\t\t\tif (area < inHollowSmallestArea) {\n\t\t\t\t\t\t\t\tinHollowSmallestArea = area\n\t\t\t\t\t\t\t\tinHollowSmallestAreaHit = shape\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// For open shapes (e.g. lines or draw shapes) always use the margin.\n\t\t\t\t// If the distance is less than the margin, return the shape as the hit.\n\t\t\t\tif (distance < this.options.hitTestMargin / zoomLevel) {\n\t\t\t\t\treturn shape\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// If we haven't hit any filled shapes or frames, then return either\n\t\t// the shape who we hit within the margin (and of those, the one that\n\t\t// had the shortest distance between the point and the shape edge),\n\t\t// or else the hollow shape with the smallest area\u2014or if we didn't hit\n\t\t// any margins or any hollow shapes, then null.\n\t\treturn inMarginClosestToEdgeHit || inHollowSmallestAreaHit || undefined\n\t}\n\n\t/**\n\t * Get the shapes, if any, at a given page point.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getShapesAtPoint({ x: 100, y: 100 })\n\t * editor.getShapesAtPoint({ x: 100, y: 100 }, { hitInside: true, exact: true })\n\t * ```\n\t *\n\t * @param point - The page point to test.\n\t *\n\t * @public\n\t */\n\tgetShapesAtPoint(\n\t\tpoint: VecLike,\n\t\topts = {} as { margin?: number; hitInside?: boolean }\n\t): TLShape[] {\n\t\treturn this.getCurrentPageShapes().filter(\n\t\t\t(shape) => !this.isShapeHidden(shape) && this.isPointInShape(shape, point, opts)\n\t\t)\n\t}\n\n\t/**\n\t * Test whether a point (in the current page space) will will a shape. This method takes into account masks,\n\t * such as when a shape is the child of a frame and is partially clipped by the frame.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.isPointInShape({ x: 100, y: 100 }, myShape)\n\t * ```\n\t *\n\t * @param shape - The shape to test against.\n\t * @param point - The page point to test (in the current page space).\n\t * @param hitInside - Whether to count as a hit if the point is inside of a closed shape.\n\t *\n\t * @public\n\t */\n\tisPointInShape(\n\t\tshape: TLShape | TLShapeId,\n\t\tpoint: VecLike,\n\t\topts = {} as {\n\t\t\tmargin?: number\n\t\t\thitInside?: boolean\n\t\t}\n\t): boolean {\n\t\tconst { hitInside = false, margin = 0 } = opts\n\t\tconst id = typeof shape === 'string' ? shape : shape.id\n\t\t// If the shape is masked, and if the point falls outside of that\n\t\t// mask, then it's definitely a miss\u2014we don't need to test further.\n\t\tconst pageMask = this.getShapeMask(id)\n\t\tif (pageMask && !pointInPolygon(point, pageMask)) return false\n\n\t\treturn this.getShapeGeometry(id).hitTestPoint(\n\t\t\tthis.getPointInShapeSpace(shape, point),\n\t\t\tmargin,\n\t\t\thitInside\n\t\t)\n\t}\n\n\t/**\n\t * Convert a point in the current page space to a point in the local space of a shape. For example, if a\n\t * shape's page point were `{ x: 100, y: 100 }`, a page point at `{ x: 110, y: 110 }` would be at\n\t * `{ x: 10, y: 10 }` in the shape's local space.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getPointInShapeSpace(myShape, { x: 100, y: 100 })\n\t * ```\n\t *\n\t * @param shape - The shape to get the point in the local space of.\n\t * @param point - The page point to get in the local space of the shape.\n\t *\n\t * @public\n\t */\n\tgetPointInShapeSpace(shape: TLShape | TLShapeId, point: VecLike): Vec {\n\t\tconst id = typeof shape === 'string' ? shape : shape.id\n\t\treturn this._getShapePageTransformCache().get(id)!.clone().invert().applyToPoint(point)\n\t}\n\n\t/**\n\t * Convert a delta in the current page space to a point in the local space of a shape's parent.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getPointInParentSpace(myShape.id, { x: 100, y: 100 })\n\t * ```\n\t *\n\t * @param shape - The shape to get the point in the local space of.\n\t * @param point - The page point to get in the local space of the shape.\n\t *\n\t * @public\n\t */\n\tgetPointInParentSpace(shape: TLShapeId | TLShape, point: VecLike): Vec {\n\t\tconst id = typeof shape === 'string' ? shape : shape.id\n\t\tconst freshShape = this.getShape(id)\n\t\tif (!freshShape) return new Vec(0, 0)\n\t\tif (isPageId(freshShape.parentId)) return Vec.From(point)\n\n\t\tconst parentTransform = this.getShapePageTransform(freshShape.parentId)\n\t\tif (!parentTransform) return Vec.From(point)\n\t\treturn parentTransform.clone().invert().applyToPoint(point)\n\t}\n\n\t/**\n\t * An array containing all of the shapes in the current page.\n\t *\n\t * @public\n\t */\n\t@computed getCurrentPageShapes(): TLShape[] {\n\t\treturn Array.from(this.getCurrentPageShapeIds(), (id) => this.store.get(id)! as TLShape)\n\t}\n\n\t/**\n\t * An array containing all of the shapes in the current page, sorted in z-index order (accounting\n\t * for nested shapes): e.g. A, B, BA, BB, C.\n\t *\n\t * @public\n\t */\n\t@computed getCurrentPageShapesSorted(): TLShape[] {\n\t\tconst result: TLShape[] = []\n\t\tconst topLevelShapes = this.getSortedChildIdsForParent(this.getCurrentPageId())\n\n\t\tfor (let i = 0, n = topLevelShapes.length; i < n; i++) {\n\t\t\tpushShapeWithDescendants(this, topLevelShapes[i], result)\n\t\t}\n\n\t\treturn result\n\t}\n\n\t/**\n\t * An array containing all of the rendering shapes in the current page, sorted in z-index order (accounting\n\t * for nested shapes): e.g. A, B, BA, BB, C.\n\t *\n\t * @public\n\t */\n\t@computed getCurrentPageRenderingShapesSorted(): TLShape[] {\n\t\tconst culledShapes = this.getCulledShapes()\n\t\treturn this.getCurrentPageShapesSorted().filter(\n\t\t\t({ id }) => !culledShapes.has(id) && !this.isShapeHidden(id)\n\t\t)\n\t}\n\n\t/**\n\t * Get whether a shape matches the type of a TLShapeUtil.\n\t *\n\t * @example\n\t * ```ts\n\t * const isArrowShape = isShapeOfType(someShape, 'arrow')\n\t * ```\n\t *\n\t * @param util - the TLShapeUtil constructor to test against\n\t * @param shape - the shape to test\n\t *\n\t * @public\n\t */\n\tisShapeOfType(shape: TLUnknownShape, type: T['type']): shape is T\n\tisShapeOfType(\n\t\tshapeId: TLUnknownShape['id'],\n\t\ttype: T['type']\n\t): shapeId is T['id']\n\tisShapeOfType(\n\t\targ: TLUnknownShape | TLUnknownShape['id'],\n\t\ttype: T['type']\n\t) {\n\t\tconst shape = typeof arg === 'string' ? this.getShape(arg) : arg\n\t\tif (!shape) return false\n\t\treturn shape.type === type\n\t}\n\n\t/**\n\t * Get a shape by its id.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getShape('box1')\n\t * ```\n\t *\n\t * @param id - The id of the shape to get.\n\t *\n\t * @public\n\t */\n\tgetShape(shape: TLShape | TLParentId): T | undefined {\n\t\tconst id = typeof shape === 'string' ? shape : shape.id\n\t\tif (!isShapeId(id)) return undefined\n\t\treturn this.store.get(id) as T\n\t}\n\n\t/**\n\t * Get the parent shape for a given shape. Returns undefined if the shape is the direct child of\n\t * the page.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getShapeParent(myShape)\n\t * ```\n\t *\n\t * @public\n\t */\n\tgetShapeParent(shape?: TLShape | TLShapeId): TLShape | undefined {\n\t\tconst id = typeof shape === 'string' ? shape : shape?.id\n\t\tif (!id) return undefined\n\t\tconst freshShape = this.getShape(id)\n\t\tif (freshShape === undefined || !isShapeId(freshShape.parentId)) return undefined\n\t\treturn this.store.get(freshShape.parentId)\n\t}\n\n\t/**\n\t * If siblingShape and targetShape are siblings, this returns targetShape. If targetShape has an\n\t * ancestor who is a sibling of siblingShape, this returns that ancestor. Otherwise, this returns\n\t * undefined.\n\t *\n\t * @internal\n\t */\n\tgetShapeNearestSibling(\n\t\tsiblingShape: TLShape,\n\t\ttargetShape: TLShape | undefined\n\t): TLShape | undefined {\n\t\tif (!targetShape) {\n\t\t\treturn undefined\n\t\t}\n\t\tif (targetShape.parentId === siblingShape.parentId) {\n\t\t\treturn targetShape\n\t\t}\n\n\t\tconst ancestor = this.findShapeAncestor(\n\t\t\ttargetShape,\n\t\t\t(ancestor) => ancestor.parentId === siblingShape.parentId\n\t\t)\n\n\t\treturn ancestor\n\t}\n\n\t/**\n\t * Get whether the given shape is the descendant of the given page.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.isShapeInPage(myShape)\n\t * editor.isShapeInPage(myShape, 'page1')\n\t * ```\n\t *\n\t * @param shape - The shape to check.\n\t * @param pageId - The id of the page to check against. Defaults to the current page.\n\t *\n\t * @public\n\t */\n\tisShapeInPage(shape: TLShape | TLShapeId, pageId = this.getCurrentPageId()): boolean {\n\t\tconst id = typeof shape === 'string' ? shape : shape.id\n\t\tconst shapeToCheck = this.getShape(id)\n\t\tif (!shapeToCheck) return false\n\n\t\tlet shapeIsInPage = false\n\n\t\tif (shapeToCheck.parentId === pageId) {\n\t\t\tshapeIsInPage = true\n\t\t} else {\n\t\t\tlet parent = this.getShape(shapeToCheck.parentId)\n\t\t\tisInPageSearch: while (parent) {\n\t\t\t\tif (parent.parentId === pageId) {\n\t\t\t\t\tshapeIsInPage = true\n\t\t\t\t\tbreak isInPageSearch\n\t\t\t\t}\n\t\t\t\tparent = this.getShape(parent.parentId)\n\t\t\t}\n\t\t}\n\n\t\treturn shapeIsInPage\n\t}\n\n\t/**\n\t * Get the id of the containing page for a given shape.\n\t *\n\t * @param shape - The shape to get the page id for.\n\t *\n\t * @returns The id of the page that contains the shape, or undefined if the shape is undefined.\n\t *\n\t * @public\n\t */\n\tgetAncestorPageId(shape?: TLShape | TLShapeId): TLPageId | undefined {\n\t\tconst id = typeof shape === 'string' ? shape : shape?.id\n\t\tconst _shape = id && this.getShape(id)\n\t\tif (!_shape) return undefined\n\t\tif (isPageId(_shape.parentId)) {\n\t\t\treturn _shape.parentId\n\t\t} else {\n\t\t\treturn this.getAncestorPageId(this.getShape(_shape.parentId))\n\t\t}\n\t}\n\n\t// Parents and children\n\n\t/**\n\t * A cache of parents to children.\n\t *\n\t * @internal\n\t */\n\tprivate readonly _parentIdsToChildIds: ReturnType\n\n\t/**\n\t * Reparent shapes to a new parent. This operation preserves the shape's current page positions /\n\t * rotations.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.reparentShapes([box1, box2], 'frame1')\n\t * editor.reparentShapes([box1.id, box2.id], 'frame1')\n\t * editor.reparentShapes([box1.id, box2.id], 'frame1', 4)\n\t * ```\n\t *\n\t * @param shapes - The shapes (or shape ids) of the shapes to reparent.\n\t * @param parentId - The id of the new parent shape.\n\t * @param insertIndex - The index to insert the children.\n\t *\n\t * @public\n\t */\n\treparentShapes(shapes: TLShapeId[] | TLShape[], parentId: TLParentId, insertIndex?: IndexKey) {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string' ? (shapes as TLShapeId[]) : shapes.map((s) => (s as TLShape).id)\n\t\tif (ids.length === 0) return this\n\n\t\tconst changes: TLShapePartial[] = []\n\n\t\tconst parentTransform = isPageId(parentId)\n\t\t\t? Mat.Identity()\n\t\t\t: this.getShapePageTransform(parentId)!\n\n\t\tconst parentPageRotation = parentTransform.rotation()\n\n\t\tlet indices: IndexKey[] = []\n\n\t\tconst sibs = compact(this.getSortedChildIdsForParent(parentId).map((id) => this.getShape(id)))\n\n\t\tif (insertIndex) {\n\t\t\tconst sibWithInsertIndex = sibs.find((s) => s.index === insertIndex)\n\t\t\tif (sibWithInsertIndex) {\n\t\t\t\t// If there's a sibling with the same index as the insert index...\n\t\t\t\tconst sibAbove = sibs[sibs.indexOf(sibWithInsertIndex) + 1]\n\t\t\t\tif (sibAbove) {\n\t\t\t\t\t// If the sibling has a sibling above it, insert the shapes\n\t\t\t\t\t// between the sibling and its sibling above it.\n\t\t\t\t\tindices = getIndicesBetween(insertIndex, sibAbove.index, ids.length)\n\t\t\t\t} else {\n\t\t\t\t\t// Or if the sibling is the top sibling, insert the shapes\n\t\t\t\t\t// above the sibling\n\t\t\t\t\tindices = getIndicesAbove(insertIndex, ids.length)\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// If there's no collision, then we can start at the insert index\n\t\t\t\tconst sibAbove = sibs.sort(sortByIndex).find((s) => s.index > insertIndex)\n\n\t\t\t\tif (sibAbove) {\n\t\t\t\t\t// If the siblings include a sibling with a higher index, insert the shapes\n\t\t\t\t\t// between the insert index and the sibling with the higher index.\n\t\t\t\t\tindices = getIndicesBetween(insertIndex, sibAbove.index, ids.length)\n\t\t\t\t} else {\n\t\t\t\t\t// Otherwise, we're at the top of the order, so insert the shapes above\n\t\t\t\t\t// the insert index.\n\t\t\t\t\tindices = getIndicesAbove(insertIndex, ids.length)\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\t// If insert index is not specified, start the index at the top.\n\t\t\tconst sib = sibs.length && sibs[sibs.length - 1]\n\t\t\tindices = sib ? getIndicesAbove(sib.index, ids.length) : getIndices(ids.length)\n\t\t}\n\n\t\tconst invertedParentTransform = parentTransform.clone().invert()\n\n\t\tconst shapesToReparent = compact(ids.map((id) => this.getShape(id)))\n\n\t\t// Ignore locked shapes so that we can reparent locked shapes, for example\n\t\t// when a locked shape's parent is deleted.\n\t\tthis.run(\n\t\t\t() => {\n\t\t\t\tfor (let i = 0; i < shapesToReparent.length; i++) {\n\t\t\t\t\tconst shape = shapesToReparent[i]\n\n\t\t\t\t\tconst pageTransform = this.getShapePageTransform(shape)!\n\t\t\t\t\tif (!pageTransform) continue\n\n\t\t\t\t\tconst pagePoint = pageTransform.point()\n\t\t\t\t\tif (!pagePoint) continue\n\n\t\t\t\t\tconst newPoint = invertedParentTransform.applyToPoint(pagePoint)\n\t\t\t\t\tconst newRotation = pageTransform.rotation() - parentPageRotation\n\n\t\t\t\t\tchanges.push({\n\t\t\t\t\t\tid: shape.id,\n\t\t\t\t\t\ttype: shape.type,\n\t\t\t\t\t\tparentId: parentId,\n\t\t\t\t\t\tx: newPoint.x,\n\t\t\t\t\t\ty: newPoint.y,\n\t\t\t\t\t\trotation: newRotation,\n\t\t\t\t\t\tindex: indices[i],\n\t\t\t\t\t})\n\t\t\t\t}\n\n\t\t\t\tthis.updateShapes(changes)\n\t\t\t},\n\t\t\t{ ignoreShapeLock: true }\n\t\t)\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Get the index above the highest child of a given parent.\n\t *\n\t * @param parentId - The id of the parent.\n\t *\n\t * @returns The index.\n\t *\n\t * @public\n\t */\n\tgetHighestIndexForParent(parent: TLParentId | TLPage | TLShape): IndexKey {\n\t\tconst parentId = typeof parent === 'string' ? parent : parent.id\n\t\tconst children = this._parentIdsToChildIds.get()[parentId]\n\n\t\tif (!children || children.length === 0) {\n\t\t\treturn 'a1' as IndexKey\n\t\t}\n\t\tconst shape = this.getShape(children[children.length - 1])!\n\t\treturn getIndexAbove(shape.index)\n\t}\n\n\t/**\n\t * Get an array of all the children of a shape.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getSortedChildIdsForParent('frame1')\n\t * ```\n\t *\n\t * @param parentId - The id of the parent shape.\n\t *\n\t * @public\n\t */\n\tgetSortedChildIdsForParent(parent: TLParentId | TLPage | TLShape): TLShapeId[] {\n\t\tconst parentId = typeof parent === 'string' ? parent : parent.id\n\t\tconst ids = this._parentIdsToChildIds.get()[parentId]\n\t\tif (!ids) return EMPTY_ARRAY\n\t\treturn ids\n\t}\n\n\t/**\n\t * Run a visitor function for all descendants of a shape.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.visitDescendants('frame1', myCallback)\n\t * ```\n\t *\n\t * @param parentId - The id of the parent shape.\n\t * @param visitor - The visitor function.\n\t *\n\t * @public\n\t */\n\tvisitDescendants(\n\t\tparent: TLParentId | TLPage | TLShape,\n\t\tvisitor: (id: TLShapeId) => void | false\n\t): this {\n\t\tconst parentId = typeof parent === 'string' ? parent : parent.id\n\t\tconst children = this.getSortedChildIdsForParent(parentId)\n\t\tfor (const id of children) {\n\t\t\tif (visitor(id) === false) continue\n\t\t\tthis.visitDescendants(id, visitor)\n\t\t}\n\t\treturn this\n\t}\n\n\t/**\n\t * Get the shape ids of all descendants of the given shapes (including the shapes themselves). IDs are returned in z-index order.\n\t *\n\t * @param ids - The ids of the shapes to get descendants of.\n\t *\n\t * @returns The descendant ids.\n\t *\n\t * @public\n\t */\n\tgetShapeAndDescendantIds(ids: TLShapeId[]): Set {\n\t\tconst shapeIds = new Set()\n\t\tfor (const shape of ids.map((id) => this.getShape(id)!).sort(sortByIndex)) {\n\t\t\tshapeIds.add(shape.id)\n\t\t\tthis.visitDescendants(shape, (descendantId) => {\n\t\t\t\tshapeIds.add(descendantId)\n\t\t\t})\n\t\t}\n\t\treturn shapeIds\n\t}\n\n\t/**\n\t * Get the shape that some shapes should be dropped on at a given point.\n\t *\n\t * @param point - The point to find the parent for.\n\t * @param droppingShapes - The shapes that are being dropped.\n\t *\n\t * @returns The shape to drop on.\n\t *\n\t * @public\n\t */\n\tgetDroppingOverShape(point: VecLike, droppingShapes: TLShape[] = []) {\n\t\t// starting from the top...\n\t\tconst currentPageShapesSorted = this.getCurrentPageShapesSorted()\n\t\tfor (let i = currentPageShapesSorted.length - 1; i >= 0; i--) {\n\t\t\tconst shape = currentPageShapesSorted[i]\n\n\t\t\tif (\n\t\t\t\t// ignore hidden shapes\n\t\t\t\tthis.isShapeHidden(shape) ||\n\t\t\t\t// don't allow dropping on selected shapes\n\t\t\t\tthis.getSelectedShapeIds().includes(shape.id) ||\n\t\t\t\t// only allow shapes that can receive children\n\t\t\t\t!this.getShapeUtil(shape).canDropShapes(shape, droppingShapes) ||\n\t\t\t\t// don't allow dropping a shape on itself or one of it's children\n\t\t\t\tdroppingShapes.find((s) => s.id === shape.id || this.hasAncestor(shape, s.id))\n\t\t\t) {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\t// Only allow dropping into the masked page bounds of the shape, e.g. when a frame is\n\t\t\t// partially clipped by its own parent frame\n\t\t\tconst maskedPageBounds = this.getShapeMaskedPageBounds(shape.id)\n\n\t\t\tif (\n\t\t\t\tmaskedPageBounds &&\n\t\t\t\tmaskedPageBounds.containsPoint(point) &&\n\t\t\t\tthis.getShapeGeometry(shape).hitTestPoint(this.getPointInShapeSpace(shape, point), 0, true)\n\t\t\t) {\n\t\t\t\treturn shape\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Get the shape that should be selected when you click on a given shape, assuming there is\n\t * nothing already selected. It will not return anything higher than or including the current\n\t * focus layer.\n\t *\n\t * @param shape - The shape to get the outermost selectable shape for.\n\t * @param filter - A function to filter the selectable shapes.\n\t *\n\t * @returns The outermost selectable shape.\n\t *\n\t * @public\n\t */\n\tgetOutermostSelectableShape(\n\t\tshape: TLShape | TLShapeId,\n\t\tfilter?: (shape: TLShape) => boolean\n\t): TLShape {\n\t\tconst id = typeof shape === 'string' ? shape : shape.id\n\t\tconst freshShape = this.getShape(id)!\n\t\tlet match = freshShape\n\t\tlet node = freshShape as TLShape | undefined\n\n\t\tconst focusedGroup = this.getFocusedGroup()\n\n\t\twhile (node) {\n\t\t\tif (\n\t\t\t\tthis.isShapeOfType(node, 'group') &&\n\t\t\t\tfocusedGroup?.id !== node.id &&\n\t\t\t\t!this.hasAncestor(focusedGroup, node.id) &&\n\t\t\t\t(filter?.(node) ?? true)\n\t\t\t) {\n\t\t\t\tmatch = node\n\t\t\t} else if (focusedGroup?.id === node.id) {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tnode = this.getShapeParent(node)\n\t\t}\n\n\t\treturn match\n\t}\n\n\t/* -------------------- Bindings -------------------- */\n\n\t@computed\n\tprivate _getBindingsIndexCache() {\n\t\tconst index = bindingsIndex(this)\n\t\treturn this.store.createComputedCache('bindingsIndex', (shape) => {\n\t\t\treturn index.get().get(shape.id)\n\t\t})\n\t}\n\n\t/**\n\t * Get a binding from the store by its ID if it exists.\n\t */\n\tgetBinding(id: TLBindingId): TLBinding | undefined {\n\t\treturn this.store.get(id) as TLBinding | undefined\n\t}\n\n\t/**\n\t * Get all bindings of a certain type _from_ a particular shape. These are the bindings whose\n\t * `fromId` matched the shape's ID.\n\t */\n\tgetBindingsFromShape(\n\t\tshape: TLShape | TLShapeId,\n\t\ttype: Binding['type']\n\t): Binding[] {\n\t\tconst id = typeof shape === 'string' ? shape : shape.id\n\t\treturn this.getBindingsInvolvingShape(id).filter(\n\t\t\t(b) => b.fromId === id && b.type === type\n\t\t) as Binding[]\n\t}\n\n\t/**\n\t * Get all bindings of a certain type _to_ a particular shape. These are the bindings whose\n\t * `toId` matches the shape's ID.\n\t */\n\tgetBindingsToShape(\n\t\tshape: TLShape | TLShapeId,\n\t\ttype: Binding['type']\n\t): Binding[] {\n\t\tconst id = typeof shape === 'string' ? shape : shape.id\n\t\treturn this.getBindingsInvolvingShape(id).filter(\n\t\t\t(b) => b.toId === id && b.type === type\n\t\t) as Binding[]\n\t}\n\n\t/**\n\t * Get all bindings involving a particular shape. This includes bindings where the shape is the\n\t * `fromId` or `toId`. If a type is provided, only bindings of that type are returned.\n\t */\n\tgetBindingsInvolvingShape(\n\t\tshape: TLShape | TLShapeId,\n\t\ttype?: Binding['type']\n\t): Binding[] {\n\t\tconst id = typeof shape === 'string' ? shape : shape.id\n\t\tconst result = this._getBindingsIndexCache().get(id) ?? EMPTY_ARRAY\n\t\tif (!type) return result as Binding[]\n\t\treturn result.filter((b) => b.type === type) as Binding[]\n\t}\n\n\t/**\n\t * Create bindings from a list of partial bindings. You can omit the ID and most props of a\n\t * binding, but the `type`, `toId`, and `fromId` must all be provided.\n\t */\n\tcreateBindings(partials: TLBindingCreate[]) {\n\t\tconst bindings: TLBinding[] = []\n\t\tfor (const partial of partials) {\n\t\t\tconst fromShape = this.getShape(partial.fromId)\n\t\t\tconst toShape = this.getShape(partial.toId)\n\t\t\tif (!fromShape || !toShape) continue\n\t\t\tif (!this.canBindShapes({ fromShape, toShape, binding: partial })) continue\n\n\t\t\tconst util = this.getBindingUtil(partial.type)\n\t\t\tconst defaultProps = util.getDefaultProps()\n\t\t\tconst binding = this.store.schema.types.binding.create({\n\t\t\t\t...partial,\n\t\t\t\tid: partial.id ?? createBindingId(),\n\t\t\t\tprops: {\n\t\t\t\t\t...defaultProps,\n\t\t\t\t\t...partial.props,\n\t\t\t\t},\n\t\t\t}) as TLBinding\n\n\t\t\tbindings.push(binding)\n\t\t}\n\n\t\tthis.store.put(bindings)\n\t\treturn this\n\t}\n\n\t/**\n\t * Create a single binding from a partial. You can omit the ID and most props of a binding, but\n\t * the `type`, `toId`, and `fromId` must all be provided.\n\t */\n\tcreateBinding(partial: TLBindingCreate) {\n\t\treturn this.createBindings([partial])\n\t}\n\n\t/**\n\t * Update bindings from a list of partial bindings. Each partial must include an ID, which will\n\t * be used to match the binding to it's existing record. If there is no existing record, that\n\t * binding is skipped. The changes from the partial are merged into the existing record.\n\t */\n\tupdateBindings(partials: (TLBindingUpdate | null | undefined)[]) {\n\t\tconst updated: TLBinding[] = []\n\n\t\tfor (const partial of partials) {\n\t\t\tif (!partial) continue\n\n\t\t\tconst current = this.getBinding(partial.id)\n\t\t\tif (!current) continue\n\n\t\t\tconst updatedBinding = applyPartialToRecordWithProps(current, partial)\n\t\t\tif (updatedBinding === current) continue\n\n\t\t\tconst fromShape = this.getShape(updatedBinding.fromId)\n\t\t\tconst toShape = this.getShape(updatedBinding.toId)\n\t\t\tif (!fromShape || !toShape) continue\n\t\t\tif (!this.canBindShapes({ fromShape, toShape, binding: updatedBinding })) continue\n\n\t\t\tupdated.push(updatedBinding)\n\t\t}\n\n\t\tthis.store.put(updated)\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Update a binding from a partial binding. Each partial must include an ID, which will be used\n\t * to match the binding to it's existing record. If there is no existing record, that binding is\n\t * skipped. The changes from the partial are merged into the existing record.\n\t */\n\tupdateBinding(partial: TLBindingUpdate) {\n\t\treturn this.updateBindings([partial])\n\t}\n\n\t/**\n\t * Delete several bindings by their IDs. If a binding ID doesn't exist, it's ignored.\n\t */\n\tdeleteBindings(bindings: (TLBinding | TLBindingId)[], { isolateShapes = false } = {}) {\n\t\tconst ids = bindings.map((binding) => (typeof binding === 'string' ? binding : binding.id))\n\t\tif (isolateShapes) {\n\t\t\tthis.store.atomic(() => {\n\t\t\t\tfor (const id of ids) {\n\t\t\t\t\tconst binding = this.getBinding(id)\n\t\t\t\t\tif (!binding) continue\n\t\t\t\t\tconst util = this.getBindingUtil(binding)\n\t\t\t\t\tutil.onBeforeIsolateFromShape?.({ binding, removedShape: this.getShape(binding.toId)! })\n\t\t\t\t\tutil.onBeforeIsolateToShape?.({ binding, removedShape: this.getShape(binding.fromId)! })\n\t\t\t\t\tthis.store.remove([id])\n\t\t\t\t}\n\t\t\t})\n\t\t} else {\n\t\t\tthis.store.remove(ids)\n\t\t}\n\t\treturn this\n\t}\n\t/**\n\t * Delete a binding by its ID. If the binding doesn't exist, it's ignored.\n\t */\n\tdeleteBinding(binding: TLBinding | TLBindingId, opts?: Parameters[1]) {\n\t\treturn this.deleteBindings([binding], opts)\n\t}\n\tcanBindShapes({\n\t\tfromShape,\n\t\ttoShape,\n\t\tbinding,\n\t}: {\n\t\tfromShape: TLShape | { type: TLShape['type'] } | TLShape['type']\n\t\ttoShape: TLShape | { type: TLShape['type'] } | TLShape['type']\n\t\tbinding: TLBinding | { type: TLBinding['type'] } | TLBinding['type']\n\t}): boolean {\n\t\tconst fromShapeType = typeof fromShape === 'string' ? fromShape : fromShape.type\n\t\tconst toShapeType = typeof toShape === 'string' ? toShape : toShape.type\n\t\tconst bindingType = typeof binding === 'string' ? binding : binding.type\n\n\t\tconst canBindOpts = { fromShapeType, toShapeType, bindingType }\n\n\t\tif (fromShapeType === toShapeType) {\n\t\t\treturn this.getShapeUtil(fromShapeType).canBind(canBindOpts)\n\t\t}\n\n\t\treturn (\n\t\t\tthis.getShapeUtil(fromShapeType).canBind(canBindOpts) &&\n\t\t\tthis.getShapeUtil(toShapeType).canBind(canBindOpts)\n\t\t)\n\t}\n\n\t/* -------------------- Commands -------------------- */\n\n\t/**\n\t * Rotate shapes by a delta in radians.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.rotateShapesBy(editor.getSelectedShapeIds(), Math.PI)\n\t * editor.rotateShapesBy(editor.getSelectedShapeIds(), Math.PI / 2)\n\t * ```\n\t *\n\t * @param shapes - The shapes (or shape ids) of the shapes to move.\n\t * @param delta - The delta in radians to apply to the selection rotation.\n\t */\n\trotateShapesBy(\n\t\tshapes: TLShapeId[] | TLShape[],\n\t\tdelta: number,\n\t\topts?: { center?: VecLike }\n\t): this {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\n\t\tif (ids.length <= 0) return this\n\n\t\tconst snapshot = getRotationSnapshot({ editor: this, ids })\n\t\tif (!snapshot) return this\n\t\tapplyRotationToSnapshotShapes({\n\t\t\tdelta,\n\t\t\tsnapshot,\n\t\t\teditor: this,\n\t\t\tstage: 'one-off',\n\t\t\tcenterOverride: opts?.center,\n\t\t})\n\n\t\treturn this\n\t}\n\n\tprivate getChangesToTranslateShape(initialShape: TLShape, newShapeCoords: VecLike): TLShape {\n\t\tlet workingShape = initialShape\n\t\tconst util = this.getShapeUtil(initialShape)\n\n\t\tworkingShape = applyPartialToRecordWithProps(\n\t\t\tworkingShape,\n\t\t\tutil.onTranslateStart?.(workingShape) ?? undefined\n\t\t)\n\n\t\tworkingShape = applyPartialToRecordWithProps(workingShape, {\n\t\t\tid: initialShape.id,\n\t\t\ttype: initialShape.type,\n\t\t\tx: newShapeCoords.x,\n\t\t\ty: newShapeCoords.y,\n\t\t})\n\n\t\tworkingShape = applyPartialToRecordWithProps(\n\t\t\tworkingShape,\n\t\t\tutil.onTranslate?.(initialShape, workingShape) ?? undefined\n\t\t)\n\n\t\tworkingShape = applyPartialToRecordWithProps(\n\t\t\tworkingShape,\n\t\t\tutil.onTranslateEnd?.(initialShape, workingShape) ?? undefined\n\t\t)\n\n\t\treturn workingShape\n\t}\n\n\t/**\n\t * Move shapes by a delta.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.nudgeShapes(['box1', 'box2'], { x: 8, y: 8 })\n\t * ```\n\t *\n\t * @param shapes - The shapes (or shape ids) to move.\n\t * @param direction - The direction in which to move the shapes.\n\t * @param historyOptions - The history options for the change.\n\t */\n\tnudgeShapes(shapes: TLShapeId[] | TLShape[], offset: VecLike): this {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\n\t\tif (ids.length <= 0) return this\n\t\tconst changes: TLShapePartial[] = []\n\n\t\tfor (const id of ids) {\n\t\t\tconst shape = this.getShape(id)!\n\t\t\tconst localDelta = Vec.From(offset)\n\t\t\tconst parentTransform = this.getShapeParentTransform(shape)\n\t\t\tif (parentTransform) localDelta.rot(-parentTransform.rotation())\n\n\t\t\tchanges.push(this.getChangesToTranslateShape(shape, localDelta.add(shape)))\n\t\t}\n\n\t\tthis.updateShapes(changes)\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Duplicate shapes.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.duplicateShapes(['box1', 'box2'], { x: 8, y: 8 })\n\t * editor.duplicateShapes(editor.getSelectedShapes(), { x: 8, y: 8 })\n\t * ```\n\t *\n\t * @param shapes - The shapes (or shape ids) to duplicate.\n\t * @param offset - The offset (in pixels) to apply to the duplicated shapes.\n\t *\n\t * @public\n\t */\n\tduplicateShapes(shapes: TLShapeId[] | TLShape[], offset?: VecLike): this {\n\t\tthis.run(() => {\n\t\t\tconst ids =\n\t\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\n\t\t\tif (ids.length <= 0) return this\n\n\t\t\tconst initialIds = new Set(ids)\n\t\t\tconst shapeIdSet = this.getShapeAndDescendantIds(ids)\n\n\t\t\tconst orderedShapeIds = [...shapeIdSet].reverse()\n\t\t\tconst shapeIds = new Map()\n\t\t\tfor (const shapeId of shapeIdSet) {\n\t\t\t\tshapeIds.set(shapeId, createShapeId())\n\t\t\t}\n\n\t\t\tconst { shapesToCreateWithOriginals, bindingsToCreate } = withIsolatedShapes(\n\t\t\t\tthis,\n\t\t\t\tshapeIdSet,\n\t\t\t\t(bindingIdsToMaintain) => {\n\t\t\t\t\tconst bindingsToCreate: TLBinding[] = []\n\t\t\t\t\tfor (const originalId of bindingIdsToMaintain) {\n\t\t\t\t\t\tconst originalBinding = this.getBinding(originalId)\n\t\t\t\t\t\tif (!originalBinding) continue\n\n\t\t\t\t\t\tconst duplicatedId = createBindingId()\n\t\t\t\t\t\tbindingsToCreate.push({\n\t\t\t\t\t\t\t...originalBinding,\n\t\t\t\t\t\t\tid: duplicatedId,\n\t\t\t\t\t\t\tfromId: assertExists(shapeIds.get(originalBinding.fromId)),\n\t\t\t\t\t\t\ttoId: assertExists(shapeIds.get(originalBinding.toId)),\n\t\t\t\t\t\t})\n\t\t\t\t\t}\n\n\t\t\t\t\tconst shapesToCreateWithOriginals: { shape: TLShape; originalShape: TLShape }[] = []\n\t\t\t\t\tfor (const originalId of orderedShapeIds) {\n\t\t\t\t\t\tconst duplicatedId = assertExists(shapeIds.get(originalId))\n\t\t\t\t\t\tconst originalShape = this.getShape(originalId)\n\t\t\t\t\t\tif (!originalShape) continue\n\n\t\t\t\t\t\tlet ox = 0\n\t\t\t\t\t\tlet oy = 0\n\n\t\t\t\t\t\tif (offset && initialIds.has(originalId)) {\n\t\t\t\t\t\t\tconst parentTransform = this.getShapeParentTransform(originalShape)\n\t\t\t\t\t\t\tconst vec = new Vec(offset.x, offset.y).rot(-parentTransform!.rotation())\n\t\t\t\t\t\t\tox = vec.x\n\t\t\t\t\t\t\toy = vec.y\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tshapesToCreateWithOriginals.push({\n\t\t\t\t\t\t\tshape: {\n\t\t\t\t\t\t\t\t...originalShape,\n\t\t\t\t\t\t\t\tid: duplicatedId,\n\t\t\t\t\t\t\t\tx: originalShape.x + ox,\n\t\t\t\t\t\t\t\ty: originalShape.y + oy,\n\t\t\t\t\t\t\t\t// Use a dummy index for now, it will get updated outside of the `withIsolatedShapes`\n\t\t\t\t\t\t\t\tindex: 'a1' as IndexKey,\n\t\t\t\t\t\t\t\tparentId:\n\t\t\t\t\t\t\t\t\tshapeIds.get(originalShape.parentId as TLShapeId) ?? originalShape.parentId,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\toriginalShape,\n\t\t\t\t\t\t})\n\t\t\t\t\t}\n\n\t\t\t\t\treturn { shapesToCreateWithOriginals, bindingsToCreate }\n\t\t\t\t}\n\t\t\t)\n\n\t\t\t// We will update the indexes after the `withIsolatedShapes`, since we cannot rely on the indexes\n\t\t\t// to be correct inside of it.\n\t\t\tshapesToCreateWithOriginals.forEach(({ shape, originalShape }) => {\n\t\t\t\tconst parentId = originalShape.parentId\n\t\t\t\tconst siblings = this.getSortedChildIdsForParent(parentId)\n\t\t\t\tconst currentIndex = siblings.indexOf(originalShape.id)\n\t\t\t\tconst siblingAboveId = siblings[currentIndex + 1]\n\t\t\t\tconst siblingAbove = siblingAboveId ? this.getShape(siblingAboveId) : undefined\n\n\t\t\t\tconst index = getIndexBetween(originalShape.index, siblingAbove?.index)\n\n\t\t\t\tshape.index = index\n\t\t\t})\n\t\t\tconst shapesToCreate = shapesToCreateWithOriginals.map(({ shape }) => shape)\n\n\t\t\tconst maxShapesReached =\n\t\t\t\tshapesToCreate.length + this.getCurrentPageShapeIds().size > this.options.maxShapesPerPage\n\n\t\t\tif (maxShapesReached) {\n\t\t\t\talertMaxShapes(this)\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tthis.createShapes(shapesToCreate)\n\t\t\tthis.createBindings(bindingsToCreate)\n\t\t\tthis.setSelectedShapes(compact(ids.map((id) => shapeIds.get(id))))\n\n\t\t\tif (offset !== undefined) {\n\t\t\t\t// If we've offset the duplicated shapes, check to see whether their new bounds is entirely\n\t\t\t\t// contained in the current viewport. If not, then animate the camera to be centered on the\n\t\t\t\t// new shapes.\n\t\t\t\tconst selectionPageBounds = this.getSelectionPageBounds()\n\t\t\t\tconst viewportPageBounds = this.getViewportPageBounds()\n\t\t\t\tif (selectionPageBounds && !viewportPageBounds.contains(selectionPageBounds)) {\n\t\t\t\t\tthis.centerOnPoint(selectionPageBounds.center, {\n\t\t\t\t\t\tanimation: { duration: this.options.animationMediumMs },\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t}\n\t\t})\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Move shapes to page.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.moveShapesToPage(['box1', 'box2'], 'page1')\n\t * ```\n\t *\n\t * @param shapes - The shapes (or shape ids) of the shapes to move.\n\t * @param pageId - The id of the page where the shapes will be moved.\n\t *\n\t * @public\n\t */\n\tmoveShapesToPage(shapes: TLShapeId[] | TLShape[], pageId: TLPageId): this {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\n\t\tif (ids.length === 0) return this\n\t\tif (this.getInstanceState().isReadonly) return this\n\n\t\tconst currentPageId = this.getCurrentPageId()\n\n\t\tif (pageId === currentPageId) return this\n\t\tif (!this.store.has(pageId)) return this\n\n\t\t// Basically copy the shapes\n\t\tconst content = this.getContentFromCurrentPage(ids)\n\n\t\t// Just to be sure\n\t\tif (!content) return this\n\n\t\t// If there is no space on pageId, or if the selected shapes\n\t\t// would take the new page above the limit, don't move the shapes\n\t\tif (this.getPageShapeIds(pageId).size + content.shapes.length > this.options.maxShapesPerPage) {\n\t\t\talertMaxShapes(this, pageId)\n\t\t\treturn this\n\t\t}\n\n\t\tconst fromPageZ = this.getCamera().z\n\n\t\tthis.run(() => {\n\t\t\t// Delete the shapes on the current page\n\t\t\tthis.deleteShapes(ids)\n\n\t\t\t// Move to the next page\n\t\t\tthis.setCurrentPage(pageId)\n\n\t\t\t// Put the shape content onto the new page; parents and indices will\n\t\t\t// be taken care of by the putContent method; make sure to pop any focus\n\t\t\t// layers so that the content will be put onto the page.\n\t\t\tthis.setFocusedGroup(null)\n\t\t\tthis.selectNone()\n\t\t\tthis.putContentOntoCurrentPage(content, {\n\t\t\t\tselect: true,\n\t\t\t\tpreserveIds: true,\n\t\t\t\tpreservePosition: true,\n\t\t\t})\n\n\t\t\t// Force the new page's camera to be at the same zoom level as the\n\t\t\t// \"from\" page's camera, then center the \"to\" page's camera on the\n\t\t\t// pasted shapes\n\t\t\tthis.setCamera({ ...this.getCamera(), z: fromPageZ })\n\t\t\tthis.centerOnPoint(this.getSelectionRotatedPageBounds()!.center)\n\t\t})\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Toggle the lock state of one or more shapes. If there is a mix of locked and unlocked shapes, all shapes will be locked.\n\t *\n\t * @param shapes - The shapes (or shape ids) to toggle.\n\t *\n\t * @public\n\t */\n\ttoggleLock(shapes: TLShapeId[] | TLShape[]): this {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\n\t\tif (this.getInstanceState().isReadonly || ids.length === 0) return this\n\n\t\tlet allLocked = true,\n\t\t\tallUnlocked = true\n\t\tconst shapesToToggle: TLShape[] = []\n\t\tfor (const id of ids) {\n\t\t\tconst shape = this.getShape(id)\n\t\t\tif (shape) {\n\t\t\t\tshapesToToggle.push(shape)\n\t\t\t\tif (shape.isLocked) {\n\t\t\t\t\tallUnlocked = false\n\t\t\t\t} else {\n\t\t\t\t\tallLocked = false\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tthis.run(() => {\n\t\t\tif (allUnlocked) {\n\t\t\t\tthis.updateShapes(\n\t\t\t\t\tshapesToToggle.map((shape) => ({ id: shape.id, type: shape.type, isLocked: true }))\n\t\t\t\t)\n\t\t\t\tthis.setSelectedShapes([])\n\t\t\t} else if (allLocked) {\n\t\t\t\tthis.updateShapes(\n\t\t\t\t\tshapesToToggle.map((shape) => ({ id: shape.id, type: shape.type, isLocked: false }))\n\t\t\t\t)\n\t\t\t} else {\n\t\t\t\tthis.updateShapes(\n\t\t\t\t\tshapesToToggle.map((shape) => ({ id: shape.id, type: shape.type, isLocked: true }))\n\t\t\t\t)\n\t\t\t}\n\t\t})\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Send shapes to the back of the page's object list.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.sendToBack(['id1', 'id2'])\n\t * editor.sendToBack(box1, box2)\n\t * ```\n\t *\n\t * @param shapes - The shapes (or shape ids) to move.\n\t *\n\t * @public\n\t */\n\tsendToBack(shapes: TLShapeId[] | TLShape[]): this {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\t\tconst changes = getReorderingShapesChanges(this, 'toBack', ids as TLShapeId[])\n\t\tif (changes) this.updateShapes(changes)\n\t\treturn this\n\t}\n\n\t/**\n\t * Send shapes backward in the page's object list.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.sendBackward(['id1', 'id2'])\n\t * editor.sendBackward([box1, box2])\n\t * ```\n\t *\n\t * @param shapes - The shapes (or shape ids) to move.\n\t *\n\t * @public\n\t */\n\tsendBackward(shapes: TLShapeId[] | TLShape[]): this {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\t\tconst changes = getReorderingShapesChanges(this, 'backward', ids as TLShapeId[])\n\t\tif (changes) this.updateShapes(changes)\n\t\treturn this\n\t}\n\n\t/**\n\t * Bring shapes forward in the page's object list.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.bringForward(['id1', 'id2'])\n\t * editor.bringForward(box1, box2)\n\t * ```\n\t *\n\t * @param shapes - The shapes (or shape ids) to move.\n\t *\n\t * @public\n\t */\n\tbringForward(shapes: TLShapeId[] | TLShape[]): this {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\t\tconst changes = getReorderingShapesChanges(this, 'forward', ids as TLShapeId[])\n\t\tif (changes) this.updateShapes(changes)\n\t\treturn this\n\t}\n\n\t/**\n\t * Bring shapes to the front of the page's object list.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.bringToFront(['id1', 'id2'])\n\t * editor.bringToFront([box1, box2])\n\t * ```\n\t *\n\t * @param shapes - The shapes (or shape ids) to move.\n\t *\n\t * @public\n\t */\n\tbringToFront(shapes: TLShapeId[] | TLShape[]): this {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\t\tconst changes = getReorderingShapesChanges(this, 'toFront', ids as TLShapeId[])\n\t\tif (changes) this.updateShapes(changes)\n\t\treturn this\n\t}\n\n\t/**\n\t * Flip shape positions.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.flipShapes([box1, box2], 'horizontal', 32)\n\t * editor.flipShapes(editor.getSelectedShapeIds(), 'horizontal', 32)\n\t * ```\n\t *\n\t * @param shapes - The ids of the shapes to flip.\n\t * @param operation - Whether to flip horizontally or vertically.\n\t *\n\t * @public\n\t */\n\tflipShapes(shapes: TLShapeId[] | TLShape[], operation: 'horizontal' | 'vertical'): this {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\n\t\tif (this.getInstanceState().isReadonly) return this\n\n\t\tlet shapesToFlip = compact(ids.map((id) => this.getShape(id)))\n\n\t\tif (!shapesToFlip.length) return this\n\n\t\tshapesToFlip = compact(\n\t\t\tshapesToFlip\n\t\t\t\t.map((shape) => {\n\t\t\t\t\tif (this.isShapeOfType(shape, 'group')) {\n\t\t\t\t\t\treturn this.getSortedChildIdsForParent(shape.id).map((id) => this.getShape(id))\n\t\t\t\t\t}\n\n\t\t\t\t\treturn shape\n\t\t\t\t})\n\t\t\t\t.flat()\n\t\t)\n\n\t\tconst scaleOriginPage = Box.Common(\n\t\t\tcompact(shapesToFlip.map((id) => this.getShapePageBounds(id)))\n\t\t).center\n\n\t\tthis.run(() => {\n\t\t\tfor (const shape of shapesToFlip) {\n\t\t\t\tconst bounds = this.getShapeGeometry(shape).bounds\n\t\t\t\tconst initialPageTransform = this.getShapePageTransform(shape.id)\n\t\t\t\tif (!initialPageTransform) continue\n\t\t\t\tthis.resizeShape(\n\t\t\t\t\tshape.id,\n\t\t\t\t\t{ x: operation === 'horizontal' ? -1 : 1, y: operation === 'vertical' ? -1 : 1 },\n\t\t\t\t\t{\n\t\t\t\t\t\tinitialBounds: bounds,\n\t\t\t\t\t\tinitialPageTransform,\n\t\t\t\t\t\tinitialShape: shape,\n\t\t\t\t\t\tmode: 'scale_shape',\n\t\t\t\t\t\tisAspectRatioLocked: this.getShapeUtil(shape).isAspectRatioLocked(shape),\n\t\t\t\t\t\tscaleOrigin: scaleOriginPage,\n\t\t\t\t\t\tscaleAxisRotation: 0,\n\t\t\t\t\t}\n\t\t\t\t)\n\t\t\t}\n\t\t})\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Stack shape.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.stackShapes([box1, box2], 'horizontal', 32)\n\t * editor.stackShapes(editor.getSelectedShapeIds(), 'horizontal', 32)\n\t * ```\n\t *\n\t * @param shapes - The shapes (or shape ids) to stack.\n\t * @param operation - Whether to stack horizontally or vertically.\n\t * @param gap - The gap to leave between shapes.\n\t *\n\t * @public\n\t */\n\tstackShapes(\n\t\tshapes: TLShapeId[] | TLShape[],\n\t\toperation: 'horizontal' | 'vertical',\n\t\tgap: number\n\t): this {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\t\tif (this.getInstanceState().isReadonly) return this\n\n\t\tconst shapesToStack = ids\n\t\t\t.map((id) => this.getShape(id)) // always fresh shapes\n\t\t\t.filter((shape): shape is TLShape => {\n\t\t\t\tif (!shape) return false\n\n\t\t\t\treturn this.getShapeUtil(shape).canBeLaidOut(shape)\n\t\t\t})\n\n\t\tconst len = shapesToStack.length\n\n\t\tif ((gap === 0 && len < 3) || len < 2) return this\n\n\t\tconst pageBounds = Object.fromEntries(\n\t\t\tshapesToStack.map((shape) => [shape.id, this.getShapePageBounds(shape)!])\n\t\t)\n\n\t\tlet val: 'x' | 'y'\n\t\tlet min: 'minX' | 'minY'\n\t\tlet max: 'maxX' | 'maxY'\n\t\tlet dim: 'width' | 'height'\n\n\t\tif (operation === 'horizontal') {\n\t\t\tval = 'x'\n\t\t\tmin = 'minX'\n\t\t\tmax = 'maxX'\n\t\t\tdim = 'width'\n\t\t} else {\n\t\t\tval = 'y'\n\t\t\tmin = 'minY'\n\t\t\tmax = 'maxY'\n\t\t\tdim = 'height'\n\t\t}\n\n\t\tlet shapeGap: number\n\n\t\tif (gap === 0) {\n\t\t\tconst gaps: { gap: number; count: number }[] = []\n\n\t\t\tshapesToStack.sort((a, b) => pageBounds[a.id][min] - pageBounds[b.id][min])\n\n\t\t\t// Collect all of the gaps between shapes. We want to find\n\t\t\t// patterns (equal gaps between shapes) and use the most common\n\t\t\t// one as the gap for all of the shapes.\n\t\t\tfor (let i = 0; i < len - 1; i++) {\n\t\t\t\tconst shape = shapesToStack[i]\n\t\t\t\tconst nextShape = shapesToStack[i + 1]\n\n\t\t\t\tconst bounds = pageBounds[shape.id]\n\t\t\t\tconst nextBounds = pageBounds[nextShape.id]\n\n\t\t\t\tconst gap = nextBounds[min] - bounds[max]\n\n\t\t\t\tconst current = gaps.find((g) => g.gap === gap)\n\n\t\t\t\tif (current) {\n\t\t\t\t\tcurrent.count++\n\t\t\t\t} else {\n\t\t\t\t\tgaps.push({ gap, count: 1 })\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Which gap is the most common?\n\t\t\tlet maxCount = 0\n\t\t\tgaps.forEach((g) => {\n\t\t\t\tif (g.count > maxCount) {\n\t\t\t\t\tmaxCount = g.count\n\t\t\t\t\tshapeGap = g.gap\n\t\t\t\t}\n\t\t\t})\n\n\t\t\t// If there is no most-common gap, use the average gap.\n\t\t\tif (maxCount === 1) {\n\t\t\t\tshapeGap = Math.max(0, gaps.reduce((a, c) => a + c.gap * c.count, 0) / (len - 1))\n\t\t\t}\n\t\t} else {\n\t\t\t// If a gap was provided, then use that instead.\n\t\t\tshapeGap = gap\n\t\t}\n\n\t\tconst changes: TLShapePartial[] = []\n\n\t\tlet v = pageBounds[shapesToStack[0].id][max]\n\n\t\tshapesToStack.forEach((shape, i) => {\n\t\t\tif (i === 0) return\n\n\t\t\tconst delta = { x: 0, y: 0 }\n\t\t\tdelta[val] = v + shapeGap - pageBounds[shape.id][val]\n\n\t\t\tconst parent = this.getShapeParent(shape)\n\t\t\tconst localDelta = parent\n\t\t\t\t? Vec.Rot(delta, -this.getShapePageTransform(parent)!.decompose().rotation)\n\t\t\t\t: delta\n\n\t\t\tconst translateStartChanges = this.getShapeUtil(shape).onTranslateStart?.(shape)\n\n\t\t\tchanges.push(\n\t\t\t\ttranslateStartChanges\n\t\t\t\t\t? {\n\t\t\t\t\t\t\t...translateStartChanges,\n\t\t\t\t\t\t\t[val]: shape[val] + localDelta[val],\n\t\t\t\t\t\t}\n\t\t\t\t\t: {\n\t\t\t\t\t\t\tid: shape.id as any,\n\t\t\t\t\t\t\ttype: shape.type,\n\t\t\t\t\t\t\t[val]: shape[val] + localDelta[val],\n\t\t\t\t\t\t}\n\t\t\t)\n\n\t\t\tv += pageBounds[shape.id][dim] + shapeGap\n\t\t})\n\n\t\tthis.updateShapes(changes)\n\t\treturn this\n\t}\n\n\t/**\n\t * Pack shapes into a grid centered on their current position. Based on potpack (https://github.com/mapbox/potpack).\n\t *\n\t * @example\n\t * ```ts\n\t * editor.packShapes([box1, box2], 32)\n\t * editor.packShapes(editor.getSelectedShapeIds(), 32)\n\t * ```\n\t *\n\t *\n\t * @param shapes - The shapes (or shape ids) to pack.\n\t * @param gap - The padding to apply to the packed shapes. Defaults to 16.\n\t */\n\tpackShapes(shapes: TLShapeId[] | TLShape[], gap: number): this {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\n\t\tif (this.getInstanceState().isReadonly) return this\n\t\tif (ids.length < 2) return this\n\n\t\tconst shapesToPack = ids\n\t\t\t.map((id) => this.getShape(id)) // always fresh shapes\n\t\t\t.filter((shape): shape is TLShape => {\n\t\t\t\tif (!shape) return false\n\n\t\t\t\treturn this.getShapeUtil(shape).canBeLaidOut(shape)\n\t\t\t})\n\t\tconst shapePageBounds: Record = {}\n\t\tconst nextShapePageBounds: Record = {}\n\n\t\tlet shape: TLShape,\n\t\t\tbounds: Box,\n\t\t\tarea = 0\n\n\t\tfor (let i = 0; i < shapesToPack.length; i++) {\n\t\t\tshape = shapesToPack[i]\n\t\t\tbounds = this.getShapePageBounds(shape)!\n\t\t\tshapePageBounds[shape.id] = bounds\n\t\t\tnextShapePageBounds[shape.id] = bounds.clone()\n\t\t\tarea += bounds.width * bounds.height\n\t\t}\n\n\t\tconst commonBounds = Box.Common(compact(Object.values(shapePageBounds)))\n\n\t\tconst maxWidth = commonBounds.width\n\n\t\t// sort the shapes by height, descending\n\t\tshapesToPack.sort((a, b) => shapePageBounds[b.id].height - shapePageBounds[a.id].height)\n\n\t\t// Start with is (sort of) the square of the area\n\t\tconst startWidth = Math.max(Math.ceil(Math.sqrt(area / 0.95)), maxWidth)\n\n\t\t// first shape fills the width and is infinitely tall\n\t\tconst spaces: Box[] = [new Box(commonBounds.x, commonBounds.y, startWidth, Infinity)]\n\n\t\tlet width = 0\n\t\tlet height = 0\n\t\tlet space: Box\n\t\tlet last: Box\n\n\t\tfor (let i = 0; i < shapesToPack.length; i++) {\n\t\t\tshape = shapesToPack[i]\n\t\t\tbounds = nextShapePageBounds[shape.id]\n\n\t\t\t// starting at the back (smaller shapes)\n\t\t\tfor (let i = spaces.length - 1; i >= 0; i--) {\n\t\t\t\tspace = spaces[i]\n\n\t\t\t\t// find a space that is big enough to contain the shape\n\t\t\t\tif (bounds.width > space.width || bounds.height > space.height) continue\n\n\t\t\t\t// add the shape to its top-left corner\n\t\t\t\tbounds.x = space.x\n\t\t\t\tbounds.y = space.y\n\n\t\t\t\theight = Math.max(height, bounds.maxY)\n\t\t\t\twidth = Math.max(width, bounds.maxX)\n\n\t\t\t\tif (bounds.width === space.width && bounds.height === space.height) {\n\t\t\t\t\t// remove the space on a perfect fit\n\t\t\t\t\tlast = spaces.pop()!\n\t\t\t\t\tif (i < spaces.length) spaces[i] = last\n\t\t\t\t} else if (bounds.height === space.height) {\n\t\t\t\t\t// fit the shape into the space (width)\n\t\t\t\t\tspace.x += bounds.width + gap\n\t\t\t\t\tspace.width -= bounds.width + gap\n\t\t\t\t} else if (bounds.width === space.width) {\n\t\t\t\t\t// fit the shape into the space (height)\n\t\t\t\t\tspace.y += bounds.height + gap\n\t\t\t\t\tspace.height -= bounds.height + gap\n\t\t\t\t} else {\n\t\t\t\t\t// split the space into two spaces\n\t\t\t\t\tspaces.push(\n\t\t\t\t\t\tnew Box(\n\t\t\t\t\t\t\tspace.x + (bounds.width + gap),\n\t\t\t\t\t\t\tspace.y,\n\t\t\t\t\t\t\tspace.width - (bounds.width + gap),\n\t\t\t\t\t\t\tbounds.height\n\t\t\t\t\t\t)\n\t\t\t\t\t)\n\t\t\t\t\tspace.y += bounds.height + gap\n\t\t\t\t\tspace.height -= bounds.height + gap\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\n\t\tconst commonAfter = Box.Common(Object.values(nextShapePageBounds))\n\t\tconst centerDelta = Vec.Sub(commonBounds.center, commonAfter.center)\n\n\t\tlet nextBounds: Box\n\n\t\tconst changes: TLShapePartial[] = []\n\n\t\tfor (let i = 0; i < shapesToPack.length; i++) {\n\t\t\tshape = shapesToPack[i]\n\t\t\tbounds = shapePageBounds[shape.id]\n\t\t\tnextBounds = nextShapePageBounds[shape.id]\n\n\t\t\tconst delta = Vec.Sub(nextBounds.point, bounds.point).add(centerDelta)\n\t\t\tconst parentTransform = this.getShapeParentTransform(shape)\n\t\t\tif (parentTransform) delta.rot(-parentTransform.rotation())\n\n\t\t\tconst change: TLShapePartial = {\n\t\t\t\tid: shape.id,\n\t\t\t\ttype: shape.type,\n\t\t\t\tx: shape.x + delta.x,\n\t\t\t\ty: shape.y + delta.y,\n\t\t\t}\n\n\t\t\tconst translateStartChange = this.getShapeUtil(shape).onTranslateStart?.({\n\t\t\t\t...shape,\n\t\t\t\t...change,\n\t\t\t})\n\n\t\t\tif (translateStartChange) {\n\t\t\t\tchanges.push({ ...change, ...translateStartChange })\n\t\t\t} else {\n\t\t\t\tchanges.push(change)\n\t\t\t}\n\t\t}\n\n\t\tif (changes.length) {\n\t\t\tthis.updateShapes(changes)\n\t\t}\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Align shape positions.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.alignShapes([box1, box2], 'left')\n\t * editor.alignShapes(editor.getSelectedShapeIds(), 'left')\n\t * ```\n\t *\n\t * @param shapes - The shapes (or shape ids) to align.\n\t * @param operation - The align operation to apply.\n\t *\n\t * @public\n\t */\n\n\talignShapes(\n\t\tshapes: TLShapeId[] | TLShape[],\n\t\toperation: 'left' | 'center-horizontal' | 'right' | 'top' | 'center-vertical' | 'bottom'\n\t): this {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\n\t\tif (this.getInstanceState().isReadonly) return this\n\t\tif (ids.length < 2) return this\n\n\t\tconst shapesToAlign = compact(ids.map((id) => this.getShape(id))) // always fresh shapes\n\t\tconst shapePageBounds = Object.fromEntries(\n\t\t\tshapesToAlign.map((shape) => [shape.id, this.getShapePageBounds(shape)])\n\t\t)\n\t\tconst commonBounds = Box.Common(compact(Object.values(shapePageBounds)))\n\n\t\tconst changes: TLShapePartial[] = []\n\n\t\tshapesToAlign.forEach((shape) => {\n\t\t\tconst pageBounds = shapePageBounds[shape.id]\n\t\t\tif (!pageBounds) return\n\n\t\t\tconst delta = { x: 0, y: 0 }\n\n\t\t\tswitch (operation) {\n\t\t\t\tcase 'top': {\n\t\t\t\t\tdelta.y = commonBounds.minY - pageBounds.minY\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase 'center-vertical': {\n\t\t\t\t\tdelta.y = commonBounds.midY - pageBounds.minY - pageBounds.height / 2\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase 'bottom': {\n\t\t\t\t\tdelta.y = commonBounds.maxY - pageBounds.minY - pageBounds.height\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase 'left': {\n\t\t\t\t\tdelta.x = commonBounds.minX - pageBounds.minX\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase 'center-horizontal': {\n\t\t\t\t\tdelta.x = commonBounds.midX - pageBounds.minX - pageBounds.width / 2\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase 'right': {\n\t\t\t\t\tdelta.x = commonBounds.maxX - pageBounds.minX - pageBounds.width\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst parent = this.getShapeParent(shape)\n\t\t\tconst localDelta = parent\n\t\t\t\t? Vec.Rot(delta, -this.getShapePageTransform(parent)!.decompose().rotation)\n\t\t\t\t: delta\n\n\t\t\tchanges.push(this.getChangesToTranslateShape(shape, Vec.Add(shape, localDelta)))\n\t\t})\n\n\t\tthis.updateShapes(changes)\n\t\treturn this\n\t}\n\n\t/**\n\t * Distribute shape positions.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.distributeShapes([box1, box2], 'horizontal')\n\t * editor.distributeShapes(editor.getSelectedShapeIds(), 'horizontal')\n\t * ```\n\t *\n\t * @param shapes - The shapes (or shape ids) to distribute.\n\t * @param operation - Whether to distribute shapes horizontally or vertically.\n\t *\n\t * @public\n\t */\n\tdistributeShapes(shapes: TLShapeId[] | TLShape[], operation: 'horizontal' | 'vertical'): this {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\n\t\tif (this.getInstanceState().isReadonly) return this\n\t\tif (ids.length < 3) return this\n\n\t\tconst len = ids.length\n\t\tconst shapesToDistribute = compact(ids.map((id) => this.getShape(id))) // always fresh shapes\n\t\tconst pageBounds = Object.fromEntries(\n\t\t\tshapesToDistribute.map((shape) => [shape.id, this.getShapePageBounds(shape)!])\n\t\t)\n\n\t\tlet val: 'x' | 'y'\n\t\tlet min: 'minX' | 'minY'\n\t\tlet max: 'maxX' | 'maxY'\n\t\tlet mid: 'midX' | 'midY'\n\t\tlet dim: 'width' | 'height'\n\n\t\tif (operation === 'horizontal') {\n\t\t\tval = 'x'\n\t\t\tmin = 'minX'\n\t\t\tmax = 'maxX'\n\t\t\tmid = 'midX'\n\t\t\tdim = 'width'\n\t\t} else {\n\t\t\tval = 'y'\n\t\t\tmin = 'minY'\n\t\t\tmax = 'maxY'\n\t\t\tmid = 'midY'\n\t\t\tdim = 'height'\n\t\t}\n\t\tconst changes: TLShapePartial[] = []\n\n\t\t// Clustered\n\t\tconst first = shapesToDistribute.sort(\n\t\t\t(a, b) => pageBounds[a.id][min] - pageBounds[b.id][min]\n\t\t)[0]\n\t\tconst last = shapesToDistribute.sort((a, b) => pageBounds[b.id][max] - pageBounds[a.id][max])[0]\n\n\t\tconst midFirst = pageBounds[first.id][mid]\n\t\tconst step = (pageBounds[last.id][mid] - midFirst) / (len - 1)\n\t\tconst v = midFirst + step\n\n\t\tshapesToDistribute\n\t\t\t.filter((shape) => shape !== first && shape !== last)\n\t\t\t.sort((a, b) => pageBounds[a.id][mid] - pageBounds[b.id][mid])\n\t\t\t.forEach((shape, i) => {\n\t\t\t\tconst delta = { x: 0, y: 0 }\n\t\t\t\tdelta[val] = v + step * i - pageBounds[shape.id][dim] / 2 - pageBounds[shape.id][val]\n\n\t\t\t\tconst parent = this.getShapeParent(shape)\n\t\t\t\tconst localDelta = parent\n\t\t\t\t\t? Vec.Rot(delta, -this.getShapePageTransform(parent)!.rotation())\n\t\t\t\t\t: delta\n\n\t\t\t\tchanges.push(this.getChangesToTranslateShape(shape, Vec.Add(shape, localDelta)))\n\t\t\t})\n\n\t\tthis.updateShapes(changes)\n\t\treturn this\n\t}\n\n\t/**\n\t * Stretch shape sizes and positions to fill their common bounding box.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.stretchShapes([box1, box2], 'horizontal')\n\t * editor.stretchShapes(editor.getSelectedShapeIds(), 'horizontal')\n\t * ```\n\t *\n\t * @param shapes - The shapes (or shape ids) to stretch.\n\t * @param operation - Whether to stretch shapes horizontally or vertically.\n\t *\n\t * @public\n\t */\n\tstretchShapes(shapes: TLShapeId[] | TLShape[], operation: 'horizontal' | 'vertical'): this {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\n\t\tif (this.getInstanceState().isReadonly) return this\n\t\tif (ids.length < 2) return this\n\n\t\tconst shapesToStretch = compact(ids.map((id) => this.getShape(id))) // always fresh shapes\n\t\tconst shapeBounds = Object.fromEntries(ids.map((id) => [id, this.getShapeGeometry(id).bounds]))\n\t\tconst shapePageBounds = Object.fromEntries(ids.map((id) => [id, this.getShapePageBounds(id)!]))\n\t\tconst commonBounds = Box.Common(compact(Object.values(shapePageBounds)))\n\n\t\tswitch (operation) {\n\t\t\tcase 'vertical': {\n\t\t\t\tthis.run(() => {\n\t\t\t\t\tfor (const shape of shapesToStretch) {\n\t\t\t\t\t\tconst pageRotation = this.getShapePageTransform(shape)!.rotation()\n\t\t\t\t\t\tif (pageRotation % PI2) continue\n\t\t\t\t\t\tconst bounds = shapeBounds[shape.id]\n\t\t\t\t\t\tconst pageBounds = shapePageBounds[shape.id]\n\t\t\t\t\t\tconst localOffset = new Vec(0, commonBounds.minY - pageBounds.minY)\n\t\t\t\t\t\tconst parentTransform = this.getShapeParentTransform(shape)\n\t\t\t\t\t\tif (parentTransform) localOffset.rot(-parentTransform.rotation())\n\n\t\t\t\t\t\tconst { x, y } = Vec.Add(localOffset, shape)\n\t\t\t\t\t\tthis.updateShapes([{ id: shape.id, type: shape.type, x, y }])\n\t\t\t\t\t\tconst scale = new Vec(1, commonBounds.height / pageBounds.height)\n\t\t\t\t\t\tthis.resizeShape(shape.id, scale, {\n\t\t\t\t\t\t\tinitialBounds: bounds,\n\t\t\t\t\t\t\tscaleOrigin: new Vec(pageBounds.center.x, commonBounds.minY),\n\t\t\t\t\t\t\tisAspectRatioLocked: this.getShapeUtil(shape).isAspectRatioLocked(shape),\n\t\t\t\t\t\t\tscaleAxisRotation: 0,\n\t\t\t\t\t\t})\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'horizontal': {\n\t\t\t\tthis.run(() => {\n\t\t\t\t\tfor (const shape of shapesToStretch) {\n\t\t\t\t\t\tconst bounds = shapeBounds[shape.id]\n\t\t\t\t\t\tconst pageBounds = shapePageBounds[shape.id]\n\t\t\t\t\t\tconst pageRotation = this.getShapePageTransform(shape)!.rotation()\n\t\t\t\t\t\tif (pageRotation % PI2) continue\n\t\t\t\t\t\tconst localOffset = new Vec(commonBounds.minX - pageBounds.minX, 0)\n\t\t\t\t\t\tconst parentTransform = this.getShapeParentTransform(shape)\n\t\t\t\t\t\tif (parentTransform) localOffset.rot(-parentTransform.rotation())\n\n\t\t\t\t\t\tconst { x, y } = Vec.Add(localOffset, shape)\n\t\t\t\t\t\tthis.updateShapes([{ id: shape.id, type: shape.type, x, y }])\n\t\t\t\t\t\tconst scale = new Vec(commonBounds.width / pageBounds.width, 1)\n\t\t\t\t\t\tthis.resizeShape(shape.id, scale, {\n\t\t\t\t\t\t\tinitialBounds: bounds,\n\t\t\t\t\t\t\tscaleOrigin: new Vec(commonBounds.minX, pageBounds.center.y),\n\t\t\t\t\t\t\tisAspectRatioLocked: this.getShapeUtil(shape).isAspectRatioLocked(shape),\n\t\t\t\t\t\t\tscaleAxisRotation: 0,\n\t\t\t\t\t\t})\n\t\t\t\t\t}\n\t\t\t\t})\n\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Resize a shape.\n\t *\n\t * @param id - The id of the shape to resize.\n\t * @param scale - The scale factor to apply to the shape.\n\t * @param options - Additional options.\n\t *\n\t * @public\n\t */\n\tresizeShape(\n\t\tshape: TLShapeId | TLShape,\n\t\tscale: VecLike,\n\t\toptions: TLResizeShapeOptions = {}\n\t): this {\n\t\tconst id = typeof shape === 'string' ? shape : shape.id\n\t\tif (this.getInstanceState().isReadonly) return this\n\n\t\tif (!Number.isFinite(scale.x)) scale = new Vec(1, scale.y)\n\t\tif (!Number.isFinite(scale.y)) scale = new Vec(scale.x, 1)\n\n\t\tconst initialShape = options.initialShape ?? this.getShape(id)\n\t\tif (!initialShape) return this\n\n\t\tconst scaleOrigin = options.scaleOrigin ?? this.getShapePageBounds(id)?.center\n\t\tif (!scaleOrigin) return this\n\n\t\tconst pageTransform = options.initialPageTransform\n\t\t\t? Mat.Cast(options.initialPageTransform)\n\t\t\t: this.getShapePageTransform(id)\n\t\tif (!pageTransform) return this\n\n\t\tconst pageRotation = pageTransform.rotation()\n\n\t\tif (pageRotation == null) return this\n\n\t\tconst scaleAxisRotation = options.scaleAxisRotation ?? pageRotation\n\n\t\tconst initialBounds = options.initialBounds ?? this.getShapeGeometry(id).bounds\n\n\t\tif (!initialBounds) return this\n\n\t\tconst isAspectRatioLocked =\n\t\t\toptions.isAspectRatioLocked ??\n\t\t\tthis.getShapeUtil(initialShape).isAspectRatioLocked(initialShape)\n\n\t\tif (!areAnglesCompatible(pageRotation, scaleAxisRotation)) {\n\t\t\t// shape is awkwardly rotated, keep the aspect ratio locked and adopt the scale factor\n\t\t\t// from whichever axis is being scaled the least, to avoid the shape getting bigger\n\t\t\t// than the bounds of the selection\n\t\t\t// const minScale = Math.min(Math.abs(scale.x), Math.abs(scale.y))\n\t\t\treturn this._resizeUnalignedShape(id, scale, {\n\t\t\t\t...options,\n\t\t\t\tinitialBounds,\n\t\t\t\tscaleOrigin,\n\t\t\t\tscaleAxisRotation,\n\t\t\t\tinitialPageTransform: pageTransform,\n\t\t\t\tisAspectRatioLocked,\n\t\t\t\tinitialShape,\n\t\t\t})\n\t\t}\n\n\t\tconst util = this.getShapeUtil(initialShape)\n\n\t\tif (isAspectRatioLocked) {\n\t\t\tif (Math.abs(scale.x) > Math.abs(scale.y)) {\n\t\t\t\tscale = new Vec(scale.x, Math.sign(scale.y) * Math.abs(scale.x))\n\t\t\t} else {\n\t\t\t\tscale = new Vec(Math.sign(scale.x) * Math.abs(scale.y), scale.y)\n\t\t\t}\n\t\t}\n\n\t\tif (util.onResize && util.canResize(initialShape)) {\n\t\t\t// get the model changes from the shape util\n\t\t\tconst newPagePoint = this._scalePagePoint(\n\t\t\t\tMat.applyToPoint(pageTransform, new Vec(0, 0)),\n\t\t\t\tscaleOrigin,\n\t\t\t\tscale,\n\t\t\t\tscaleAxisRotation\n\t\t\t)\n\n\t\t\tconst newLocalPoint = this.getPointInParentSpace(initialShape.id, newPagePoint)\n\n\t\t\t// resize the shape's local bounding box\n\t\t\tconst myScale = new Vec(scale.x, scale.y)\n\t\t\t// the shape is aligned with the rest of the shapes in the selection, but may be\n\t\t\t// 90deg offset from the main rotation of the selection, in which case\n\t\t\t// we need to flip the width and height scale factors\n\t\t\tconst areWidthAndHeightAlignedWithCorrectAxis = approximately(\n\t\t\t\t(pageRotation - scaleAxisRotation) % Math.PI,\n\t\t\t\t0\n\t\t\t)\n\t\t\tmyScale.x = areWidthAndHeightAlignedWithCorrectAxis ? scale.x : scale.y\n\t\t\tmyScale.y = areWidthAndHeightAlignedWithCorrectAxis ? scale.y : scale.x\n\n\t\t\t// adjust initial model for situations where the parent has moved during the resize\n\t\t\t// e.g. groups\n\t\t\tconst initialPagePoint = Mat.applyToPoint(pageTransform, new Vec())\n\n\t\t\t// need to adjust the shape's x and y points in case the parent has moved since start of resizing\n\t\t\tconst { x, y } = this.getPointInParentSpace(initialShape.id, initialPagePoint)\n\n\t\t\tlet workingShape = initialShape\n\t\t\tif (!options.skipStartAndEndCallbacks) {\n\t\t\t\tworkingShape = applyPartialToRecordWithProps(\n\t\t\t\t\tinitialShape,\n\t\t\t\t\tutil.onResizeStart?.(initialShape) ?? undefined\n\t\t\t\t)\n\t\t\t}\n\n\t\t\tworkingShape = applyPartialToRecordWithProps(workingShape, {\n\t\t\t\tid,\n\t\t\t\ttype: initialShape.type as any,\n\t\t\t\tx: newLocalPoint.x,\n\t\t\t\ty: newLocalPoint.y,\n\t\t\t\t...util.onResize(\n\t\t\t\t\t{ ...initialShape, x, y },\n\t\t\t\t\t{\n\t\t\t\t\t\tnewPoint: newLocalPoint,\n\t\t\t\t\t\thandle: options.dragHandle ?? 'bottom_right',\n\t\t\t\t\t\t// don't set isSingle to true for children\n\t\t\t\t\t\tmode: options.mode ?? 'scale_shape',\n\t\t\t\t\t\tscaleX: myScale.x,\n\t\t\t\t\t\tscaleY: myScale.y,\n\t\t\t\t\t\tinitialBounds,\n\t\t\t\t\t\tinitialShape,\n\t\t\t\t\t}\n\t\t\t\t),\n\t\t\t})\n\n\t\t\tif (!options.skipStartAndEndCallbacks) {\n\t\t\t\tworkingShape = applyPartialToRecordWithProps(\n\t\t\t\t\tworkingShape,\n\t\t\t\t\tutil.onResizeEnd?.(initialShape, workingShape) ?? undefined\n\t\t\t\t)\n\t\t\t}\n\n\t\t\tthis.updateShapes([workingShape])\n\t\t} else {\n\t\t\tconst initialPageCenter = Mat.applyToPoint(pageTransform, initialBounds.center)\n\t\t\t// get the model changes from the shape util\n\t\t\tconst newPageCenter = this._scalePagePoint(\n\t\t\t\tinitialPageCenter,\n\t\t\t\tscaleOrigin,\n\t\t\t\tscale,\n\t\t\t\tscaleAxisRotation\n\t\t\t)\n\n\t\t\tconst initialPageCenterInParentSpace = this.getPointInParentSpace(\n\t\t\t\tinitialShape.id,\n\t\t\t\tinitialPageCenter\n\t\t\t)\n\t\t\tconst newPageCenterInParentSpace = this.getPointInParentSpace(initialShape.id, newPageCenter)\n\n\t\t\tconst delta = Vec.Sub(newPageCenterInParentSpace, initialPageCenterInParentSpace)\n\t\t\t// apply the changes to the model\n\t\t\tthis.updateShapes([\n\t\t\t\t{\n\t\t\t\t\tid,\n\t\t\t\t\ttype: initialShape.type as any,\n\t\t\t\t\tx: initialShape.x + delta.x,\n\t\t\t\t\ty: initialShape.y + delta.y,\n\t\t\t\t},\n\t\t\t])\n\t\t}\n\n\t\treturn this\n\t}\n\n\t/** @internal */\n\tprivate _scalePagePoint(\n\t\tpoint: VecLike,\n\t\tscaleOrigin: VecLike,\n\t\tscale: VecLike,\n\t\tscaleAxisRotation: number\n\t) {\n\t\tconst relativePoint = Vec.RotWith(point, scaleOrigin, -scaleAxisRotation).sub(scaleOrigin)\n\n\t\t// calculate the new point position relative to the scale origin\n\t\tconst newRelativePagePoint = Vec.MulV(relativePoint, scale)\n\n\t\t// and rotate it back to page coords to get the new page point of the resized shape\n\t\tconst destination = Vec.Add(newRelativePagePoint, scaleOrigin).rotWith(\n\t\t\tscaleOrigin,\n\t\t\tscaleAxisRotation\n\t\t)\n\n\t\treturn destination\n\t}\n\n\t/** @internal */\n\tprivate _resizeUnalignedShape(\n\t\tid: TLShapeId,\n\t\tscale: VecLike,\n\t\toptions: {\n\t\t\tinitialBounds: Box\n\t\t\tscaleOrigin: VecLike\n\t\t\tscaleAxisRotation: number\n\t\t\tinitialShape: TLShape\n\t\t\tisAspectRatioLocked: boolean\n\t\t\tinitialPageTransform: MatLike\n\t\t}\n\t) {\n\t\tconst { type } = options.initialShape\n\t\t// If a shape is not aligned with the scale axis we need to treat it differently to avoid skewing.\n\t\t// Instead of skewing we normalize the scale aspect ratio (i.e. keep the same scale magnitude in both axes)\n\t\t// and then after applying the scale to the shape we also rotate it if required and translate it so that it's center\n\t\t// point ends up in the right place.\n\n\t\tconst shapeScale = new Vec(scale.x, scale.y)\n\n\t\t// // make sure we are constraining aspect ratio, and using the smallest scale axis to avoid shapes getting bigger\n\t\t// // than the selection bounding box\n\t\tif (Math.abs(scale.x) > Math.abs(scale.y)) {\n\t\t\tshapeScale.x = Math.sign(scale.x) * Math.abs(scale.y)\n\t\t} else {\n\t\t\tshapeScale.y = Math.sign(scale.y) * Math.abs(scale.x)\n\t\t}\n\n\t\t// first we can scale the shape about its center point\n\t\tthis.resizeShape(id, shapeScale, {\n\t\t\tinitialShape: options.initialShape,\n\t\t\tinitialBounds: options.initialBounds,\n\t\t\tisAspectRatioLocked: options.isAspectRatioLocked,\n\t\t})\n\n\t\t// then if the shape is flipped in one axis only, we need to apply an extra rotation\n\t\t// to make sure the shape is mirrored correctly\n\t\tif (Math.sign(scale.x) * Math.sign(scale.y) < 0) {\n\t\t\tlet { rotation } = Mat.Decompose(options.initialPageTransform)\n\t\t\trotation -= 2 * rotation\n\t\t\tthis.updateShapes([{ id, type, rotation }])\n\t\t}\n\n\t\t// Next we need to translate the shape so that it's center point ends up in the right place.\n\t\t// To do that we first need to calculate the center point of the shape in the current page space before the scale was applied.\n\t\tconst preScaleShapePageCenter = Mat.applyToPoint(\n\t\t\toptions.initialPageTransform,\n\t\t\toptions.initialBounds.center\n\t\t)\n\n\t\t// And now we scale the center point by the original scale factor\n\t\tconst postScaleShapePageCenter = this._scalePagePoint(\n\t\t\tpreScaleShapePageCenter,\n\t\t\toptions.scaleOrigin,\n\t\t\tscale,\n\t\t\toptions.scaleAxisRotation\n\t\t)\n\n\t\t// now calculate how far away the shape is from where it needs to be\n\t\tconst pageBounds = this.getShapePageBounds(id)!\n\t\tconst pageTransform = this.getShapePageTransform(id)!\n\t\tconst currentPageCenter = pageBounds.center\n\t\tconst shapePageTransformOrigin = pageTransform.point()\n\t\tif (!currentPageCenter || !shapePageTransformOrigin) return this\n\t\tconst pageDelta = Vec.Sub(postScaleShapePageCenter, currentPageCenter)\n\n\t\t// and finally figure out what the shape's new position should be\n\t\tconst postScaleShapePagePoint = Vec.Add(shapePageTransformOrigin, pageDelta)\n\t\tconst { x, y } = this.getPointInParentSpace(id, postScaleShapePagePoint)\n\n\t\tthis.updateShapes([{ id, type, x, y }])\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Get the initial meta value for a shape.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getInitialMetaForShape = (shape) => {\n\t * if (shape.type === 'note') {\n\t * return { createdBy: myCurrentUser.id }\n\t * }\n\t * }\n\t * ```\n\t *\n\t * @param shape - The shape to get the initial meta for.\n\t *\n\t * @public\n\t */\n\tgetInitialMetaForShape(_shape: TLShape): JsonObject {\n\t\treturn {}\n\t}\n\n\t/**\n\t * Create a single shape.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.createShape(myShape)\n\t * editor.createShape({ id: 'box1', type: 'text', props: { text: \"ok\" } })\n\t * ```\n\t *\n\t * @param shape - The shape (or shape partial) to create.\n\t *\n\t * @public\n\t */\n\tcreateShape(shape: OptionalKeys, 'id'>): this {\n\t\tthis.createShapes([shape])\n\t\treturn this\n\t}\n\n\t/**\n\t * Create shapes.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.createShapes([myShape])\n\t * editor.createShapes([{ id: 'box1', type: 'text', props: { text: \"ok\" } }])\n\t * ```\n\t *\n\t * @param shapes - The shapes (or shape partials) to create.\n\t * @param select - Whether to select the created shapes. Defaults to false.\n\t *\n\t * @public\n\t */\n\tcreateShapes(shapes: OptionalKeys, 'id'>[]): this {\n\t\tif (!Array.isArray(shapes)) {\n\t\t\tthrow Error('Editor.createShapes: must provide an array of shapes or shape partials')\n\t\t}\n\t\tif (this.getInstanceState().isReadonly) return this\n\t\tif (shapes.length <= 0) return this\n\n\t\tconst currentPageShapeIds = this.getCurrentPageShapeIds()\n\n\t\tconst maxShapesReached =\n\t\t\tshapes.length + currentPageShapeIds.size > this.options.maxShapesPerPage\n\n\t\tif (maxShapesReached) {\n\t\t\t// can't create more shapes than fit on the page\n\t\t\talertMaxShapes(this)\n\t\t\treturn this\n\t\t}\n\n\t\tconst focusedGroupId = this.getFocusedGroupId()\n\n\t\tthis.run(() => {\n\t\t\t// 1. Parents\n\n\t\t\t// Make sure that each partial will become the child of either the\n\t\t\t// page or another shape that exists (or that will exist) in this page.\n\n\t\t\t// find last parent id\n\t\t\tconst currentPageShapesSorted = this.getCurrentPageShapesSorted()\n\n\t\t\tconst partials = shapes.map((partial) => {\n\t\t\t\tif (!partial.id) {\n\t\t\t\t\tpartial = { id: createShapeId(), ...partial }\n\t\t\t\t}\n\n\t\t\t\t// If the partial does not provide the parentId OR if the provided\n\t\t\t\t// parentId is NOT in the store AND NOT among the other shapes being\n\t\t\t\t// created, then we need to find a parent for the shape. This can be\n\t\t\t\t// another shape that exists under that point and which can receive\n\t\t\t\t// children of the creating shape's type, or else the page itself.\n\t\t\t\tif (\n\t\t\t\t\t!partial.parentId ||\n\t\t\t\t\t!(this.store.has(partial.parentId) || shapes.some((p) => p.id === partial.parentId))\n\t\t\t\t) {\n\t\t\t\t\tlet parentId: TLParentId = this.getFocusedGroupId()\n\n\t\t\t\t\tfor (let i = currentPageShapesSorted.length - 1; i >= 0; i--) {\n\t\t\t\t\t\tconst parent = currentPageShapesSorted[i]\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t!this.isShapeHidden(parent) &&\n\t\t\t\t\t\t\tthis.getShapeUtil(parent).canReceiveNewChildrenOfType(parent, partial.type) &&\n\t\t\t\t\t\t\tthis.isPointInShape(\n\t\t\t\t\t\t\t\tparent,\n\t\t\t\t\t\t\t\t// If no parent is provided, then we can treat the\n\t\t\t\t\t\t\t\t// shape's provided x/y as being in the page's space.\n\t\t\t\t\t\t\t\t{ x: partial.x ?? 0, y: partial.y ?? 0 },\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tmargin: 0,\n\t\t\t\t\t\t\t\t\thitInside: true,\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\tparentId = parent.id\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tconst prevParentId = partial.parentId\n\n\t\t\t\t\t// a shape cannot be it's own parent. This was a rare issue with frames/groups in the syncFuzz tests.\n\t\t\t\t\tif (parentId === partial.id) {\n\t\t\t\t\t\tparentId = focusedGroupId\n\t\t\t\t\t}\n\n\t\t\t\t\t// If the parentid has changed...\n\t\t\t\t\tif (parentId !== prevParentId) {\n\t\t\t\t\t\tpartial = { ...partial }\n\n\t\t\t\t\t\tpartial.parentId = parentId\n\n\t\t\t\t\t\t// If the parent is a shape (rather than a page) then insert the\n\t\t\t\t\t\t// shapes into the shape's children. Adjust the point and page rotation to be\n\t\t\t\t\t\t// preserved relative to the parent.\n\t\t\t\t\t\tif (isShapeId(parentId)) {\n\t\t\t\t\t\t\tconst point = this.getPointInShapeSpace(this.getShape(parentId)!, {\n\t\t\t\t\t\t\t\tx: partial.x ?? 0,\n\t\t\t\t\t\t\t\ty: partial.y ?? 0,\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\tpartial.x = point.x\n\t\t\t\t\t\t\tpartial.y = point.y\n\t\t\t\t\t\t\tpartial.rotation =\n\t\t\t\t\t\t\t\t-this.getShapePageTransform(parentId)!.rotation() + (partial.rotation ?? 0)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn partial\n\t\t\t})\n\n\t\t\t// 2. Indices\n\n\t\t\t// Get the highest index among the parents of each of the\n\t\t\t// the shapes being created; we'll increment from there.\n\n\t\t\tconst parentIndices = new Map()\n\n\t\t\tconst shapeRecordsToCreate: TLShape[] = []\n\n\t\t\tconst { opacityForNextShape } = this.getInstanceState()\n\n\t\t\tfor (const partial of partials) {\n\t\t\t\tconst util = this.getShapeUtil(partial as TLShapePartial)\n\n\t\t\t\t// If an index is not explicitly provided, then add the\n\t\t\t\t// shapes to the top of their parents' children; using the\n\t\t\t\t// value in parentsMappedToIndex, get the index above, use it,\n\t\t\t\t// and set it back to parentsMappedToIndex for next time.\n\t\t\t\tlet index = partial.index\n\n\t\t\t\tif (!index) {\n\t\t\t\t\t// Hello bug-seeker: have you just created a frame and then a shape\n\t\t\t\t\t// and found that the shape is automatically the child of the frame?\n\t\t\t\t\t// this is the reason why! It would be harder to have each shape specify\n\t\t\t\t\t// the frame as the parent when creating a shape inside of a frame, so\n\t\t\t\t\t// we do it here.\n\t\t\t\t\tconst parentId = partial.parentId ?? focusedGroupId\n\n\t\t\t\t\tif (!parentIndices.has(parentId)) {\n\t\t\t\t\t\tparentIndices.set(parentId, this.getHighestIndexForParent(parentId))\n\t\t\t\t\t}\n\t\t\t\t\tindex = parentIndices.get(parentId)!\n\t\t\t\t\tparentIndices.set(parentId, getIndexAbove(index))\n\t\t\t\t}\n\n\t\t\t\t// The initial props starts as the shape utility's default props\n\t\t\t\tconst initialProps = util.getDefaultProps()\n\n\t\t\t\t// We then look up each key in the tab state's styles; and if it's there,\n\t\t\t\t// we use the value from the tab state's styles instead of the default.\n\t\t\t\tfor (const [style, propKey] of this.styleProps[partial.type]) {\n\t\t\t\t\t;(initialProps as any)[propKey] = this.getStyleForNextShape(style)\n\t\t\t\t}\n\n\t\t\t\t// When we create the shape, take in the partial (the props coming into the\n\t\t\t\t// function) and merge it with the default props.\n\t\t\t\tlet shapeRecordToCreate = (\n\t\t\t\t\tthis.store.schema.types.shape as RecordType<\n\t\t\t\t\t\tTLShape,\n\t\t\t\t\t\t'type' | 'props' | 'index' | 'parentId'\n\t\t\t\t\t>\n\t\t\t\t).create({\n\t\t\t\t\t...partial,\n\t\t\t\t\tindex,\n\t\t\t\t\topacity: partial.opacity ?? opacityForNextShape,\n\t\t\t\t\tparentId: partial.parentId ?? focusedGroupId,\n\t\t\t\t\tprops: 'props' in partial ? { ...initialProps, ...partial.props } : initialProps,\n\t\t\t\t})\n\n\t\t\t\tif (shapeRecordToCreate.index === undefined) {\n\t\t\t\t\tthrow Error('no index!')\n\t\t\t\t}\n\n\t\t\t\tconst next = this.getShapeUtil(shapeRecordToCreate).onBeforeCreate?.(shapeRecordToCreate)\n\n\t\t\t\tif (next) {\n\t\t\t\t\tshapeRecordToCreate = next\n\t\t\t\t}\n\n\t\t\t\tshapeRecordsToCreate.push(shapeRecordToCreate)\n\t\t\t}\n\n\t\t\t// Add meta properties, if any, to the shapes\n\t\t\tshapeRecordsToCreate.forEach((shape) => {\n\t\t\t\tshape.meta = {\n\t\t\t\t\t...this.getInitialMetaForShape(shape),\n\t\t\t\t\t...shape.meta,\n\t\t\t\t}\n\t\t\t})\n\n\t\t\tthis.store.put(shapeRecordsToCreate)\n\t\t})\n\n\t\treturn this\n\t}\n\n\tprivate animatingShapes = new Map()\n\n\t/**\n\t * Animate a shape.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.animateShape({ id: 'box1', type: 'box', x: 100, y: 100 })\n\t * editor.animateShape({ id: 'box1', type: 'box', x: 100, y: 100 }, { animation: { duration: 100, ease: t => t*t } })\n\t * ```\n\t *\n\t * @param partial - The shape partial to update.\n\t * @param options - The animation's options.\n\t *\n\t * @public\n\t */\n\tanimateShape(\n\t\tpartial: TLShapePartial | null | undefined,\n\t\topts = { animation: DEFAULT_ANIMATION_OPTIONS } as TLCameraMoveOptions\n\t): this {\n\t\treturn this.animateShapes([partial], opts)\n\t}\n\n\t/**\n\t * Animate shapes.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.animateShapes([{ id: 'box1', type: 'box', x: 100, y: 100 }])\n\t * editor.animateShapes([{ id: 'box1', type: 'box', x: 100, y: 100 }], { animation: { duration: 100, ease: t => t*t } })\n\t * ```\n\t *\n\t * @param partials - The shape partials to update.\n\t * @param options - The animation's options.\n\t *\n\t * @public\n\t */\n\tanimateShapes(\n\t\tpartials: (TLShapePartial | null | undefined)[],\n\t\topts = { animation: DEFAULT_ANIMATION_OPTIONS } as TLCameraMoveOptions\n\t): this {\n\t\tif (!opts.animation) return this\n\t\tconst { duration = 500, easing = EASINGS.linear } = opts.animation\n\n\t\tconst animationId = uniqueId()\n\n\t\tlet remaining = duration\n\t\tlet t: number\n\n\t\tinterface ShapeAnimation {\n\t\t\tstart: TLShape\n\t\t\tend: TLShape\n\t\t}\n\n\t\tconst animations: ShapeAnimation[] = []\n\n\t\tlet partial: TLShapePartial | null | undefined, result: ShapeAnimation\n\t\tfor (let i = 0, n = partials.length; i < n; i++) {\n\t\t\tpartial = partials[i]\n\t\t\tif (!partial) continue\n\n\t\t\tconst shape = this.getShape(partial.id)!\n\t\t\tif (!shape) continue\n\n\t\t\tresult = {\n\t\t\t\tstart: structuredClone(shape),\n\t\t\t\tend: applyPartialToRecordWithProps(structuredClone(shape), partial),\n\t\t\t}\n\n\t\t\tanimations.push(result)\n\t\t\tthis.animatingShapes.set(shape.id, animationId)\n\t\t}\n\n\t\tconst handleTick = (elapsed: number) => {\n\t\t\tremaining -= elapsed\n\n\t\t\tif (remaining < 0) {\n\t\t\t\tconst { animatingShapes } = this\n\t\t\t\tconst partialsToUpdate = partials.filter(\n\t\t\t\t\t(p) => p && animatingShapes.get(p.id) === animationId\n\t\t\t\t)\n\t\t\t\tif (partialsToUpdate.length) {\n\t\t\t\t\t// the regular update shapes also removes the shape from\n\t\t\t\t\t// the animating shapes set\n\t\t\t\t\tthis.updateShapes(partialsToUpdate)\n\t\t\t\t}\n\n\t\t\t\tthis.off('tick', handleTick)\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tt = easing(1 - remaining / duration)\n\n\t\t\tconst { animatingShapes } = this\n\n\t\t\tconst updates: TLShapePartial[] = []\n\n\t\t\tlet animationIdForShape: string | undefined\n\t\t\tfor (let i = 0, n = animations.length; i < n; i++) {\n\t\t\t\tconst { start, end } = animations[i]\n\t\t\t\t// Is the animation for this shape still active?\n\t\t\t\tanimationIdForShape = animatingShapes.get(start.id)\n\t\t\t\tif (animationIdForShape !== animationId) continue\n\n\t\t\t\tupdates.push({\n\t\t\t\t\t...end,\n\t\t\t\t\tx: start.x + (end.x - start.x) * t,\n\t\t\t\t\ty: start.y + (end.y - start.y) * t,\n\t\t\t\t\topacity: start.opacity + (end.opacity - start.opacity) * t,\n\t\t\t\t\trotation: start.rotation + (end.rotation - start.rotation) * t,\n\t\t\t\t\tprops: this.getShapeUtil(end).getInterpolatedProps?.(start, end, t) ?? end.props,\n\t\t\t\t})\n\t\t\t}\n\n\t\t\t// The _updateShapes method does NOT remove the\n\t\t\t// shapes from the animated shapes set\n\t\t\tthis._updateShapes(updates)\n\t\t}\n\n\t\tthis.on('tick', handleTick)\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Create a group containing the provided shapes.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.groupShapes([myShape, myOtherShape])\n\t * editor.groupShapes([myShape, myOtherShape], { groupId: myGroupId, select: false })\n\t * ```\n\t *\n\t * @param shapes - The shapes (or shape ids) to group. Defaults to the selected shapes.\n\t * @param options - An options object.\n\t *\n\t * @public\n\t */\n\tgroupShapes(shapes: TLShape[], options?: Partial<{ groupId: TLShapeId; select: boolean }>): this\n\tgroupShapes(ids: TLShapeId[], options?: Partial<{ groupId: TLShapeId; select: boolean }>): this\n\tgroupShapes(\n\t\tshapes: TLShapeId[] | TLShape[],\n\t\toptions = {} as Partial<{ groupId: TLShapeId; select: boolean }>\n\t): this {\n\t\tconst { groupId = createShapeId(), select = true } = options\n\n\t\tif (!Array.isArray(shapes)) {\n\t\t\tthrow Error('Editor.groupShapes: must provide an array of shapes or shape ids')\n\t\t}\n\t\tif (this.getInstanceState().isReadonly) return this\n\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes.map((s) => (s as TLShape).id) as TLShapeId[])\n\n\t\tif (ids.length <= 1) return this\n\n\t\tconst shapesToGroup = compact(\n\t\t\t(this._shouldIgnoreShapeLock ? ids : this._getUnlockedShapeIds(ids)).map((id) =>\n\t\t\t\tthis.getShape(id)\n\t\t\t)\n\t\t)\n\t\tconst sortedShapeIds = shapesToGroup.sort(sortByIndex).map((s) => s.id)\n\t\tconst pageBounds = Box.Common(compact(shapesToGroup.map((id) => this.getShapePageBounds(id))))\n\n\t\tconst { x, y } = pageBounds.point\n\n\t\tconst parentId = this.findCommonAncestor(shapesToGroup) ?? this.getCurrentPageId()\n\n\t\t// Only group when the select tool is active\n\t\tif (this.getCurrentToolId() !== 'select') return this\n\n\t\t// If not already in idle, cancel the current interaction (get back to idle)\n\t\tif (!this.isIn('select.idle')) {\n\t\t\tthis.cancel()\n\t\t}\n\n\t\t// Find all the shapes that have the same parentId, and use the highest index.\n\t\tconst shapesWithRootParent = shapesToGroup\n\t\t\t.filter((shape) => shape.parentId === parentId)\n\t\t\t.sort(sortByIndex)\n\n\t\tconst highestIndex = shapesWithRootParent[shapesWithRootParent.length - 1]?.index\n\n\t\tthis.run(() => {\n\t\t\tthis.createShapes([\n\t\t\t\t{\n\t\t\t\t\tid: groupId,\n\t\t\t\t\ttype: 'group',\n\t\t\t\t\tparentId,\n\t\t\t\t\tindex: highestIndex,\n\t\t\t\t\tx,\n\t\t\t\t\ty,\n\t\t\t\t\topacity: 1,\n\t\t\t\t\tprops: {},\n\t\t\t\t},\n\t\t\t])\n\t\t\tthis.reparentShapes(sortedShapeIds, groupId)\n\t\t\tif (select) {\n\t\t\t\t// the select option determines whether the grouped shapes' children are selected\n\t\t\t\tthis.select(groupId)\n\t\t\t}\n\t\t})\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Ungroup some shapes.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.ungroupShapes([myGroup, myOtherGroup])\n\t * editor.ungroupShapes([myGroup], { select: false })\n\t * ```\n\t *\n\t * @param shapes - The group shapes (or shape ids) to ungroup.\n\t * @param options - An options object.\n\t *\n\t * @public\n\t */\n\tungroupShapes(ids: TLShapeId[], options?: Partial<{ select: boolean }>): this\n\tungroupShapes(shapes: TLShape[], options?: Partial<{ select: boolean }>): this\n\tungroupShapes(shapes: TLShapeId[] | TLShape[], options = {} as Partial<{ select: boolean }>) {\n\t\tif (this.getInstanceState().isReadonly) return this\n\n\t\tconst { select = true } = options\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\n\t\tconst shapesToUngroup = compact(\n\t\t\t(this._shouldIgnoreShapeLock ? ids : this._getUnlockedShapeIds(ids)).map((id) =>\n\t\t\t\tthis.getShape(id)\n\t\t\t)\n\t\t)\n\n\t\tif (shapesToUngroup.length === 0) return this\n\n\t\t// todo: the editor shouldn't know about the select tool, move to group / ungroup actions\n\t\tif (this.getCurrentToolId() !== 'select') return this\n\t\tif (!this.isIn('select.idle')) {\n\t\t\tthis.cancel()\n\t\t}\n\n\t\t// The ids of the selected shapes after ungrouping;\n\t\t// these include all of the grouped shapes children,\n\t\t// plus any shapes that were selected apart from the groups.\n\t\tconst idsToSelect = new Set()\n\n\t\t// Get all groups in the selection\n\t\tconst groups: TLGroupShape[] = []\n\n\t\tshapesToUngroup.forEach((shape) => {\n\t\t\tif (this.isShapeOfType(shape, 'group')) {\n\t\t\t\tgroups.push(shape)\n\t\t\t} else {\n\t\t\t\tidsToSelect.add(shape.id)\n\t\t\t}\n\t\t})\n\n\t\tif (groups.length === 0) return this\n\n\t\tthis.run(() => {\n\t\t\tlet group: TLGroupShape\n\n\t\t\tfor (let i = 0, n = groups.length; i < n; i++) {\n\t\t\t\tgroup = groups[i]\n\t\t\t\tconst childIds = this.getSortedChildIdsForParent(group.id)\n\n\t\t\t\tfor (let j = 0, n = childIds.length; j < n; j++) {\n\t\t\t\t\tidsToSelect.add(childIds[j])\n\t\t\t\t}\n\n\t\t\t\tthis.reparentShapes(childIds, group.parentId, group.index)\n\t\t\t}\n\n\t\t\tthis.deleteShapes(groups.map((group) => group.id))\n\n\t\t\tif (select) {\n\t\t\t\t// the select option determines whether the ungrouped shapes' children are selected\n\t\t\t\tthis.select(...idsToSelect)\n\t\t\t}\n\t\t})\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Update a shape using a partial of the shape.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.updateShape({ id: 'box1', type: 'geo', props: { w: 100, h: 100 } })\n\t * ```\n\t *\n\t * @param partial - The shape partial to update.\n\t *\n\t * @public\n\t */\n\tupdateShape(partial: TLShapePartial | null | undefined) {\n\t\tthis.updateShapes([partial])\n\t\treturn this\n\t}\n\n\t/**\n\t * Update shapes using partials of each shape.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.updateShapes([{ id: 'box1', type: 'geo', props: { w: 100, h: 100 } }])\n\t * ```\n\t *\n\t * @param partials - The shape partials to update.\n\t *\n\t * @public\n\t */\n\tupdateShapes(partials: (TLShapePartial | null | undefined)[]) {\n\t\tconst compactedPartials: TLShapePartial[] = Array(partials.length)\n\n\t\tfor (let i = 0, n = partials.length; i < n; i++) {\n\t\t\tconst partial = partials[i]\n\t\t\tif (!partial) continue\n\t\t\t// Get the current shape referenced by the partial\n\t\t\tconst shape = this.getShape(partial.id)\n\t\t\tif (!shape) continue\n\n\t\t\t// If we're \"forcing\" the update, then we'll update the shape\n\t\t\t// regardless of whether it / its ancestor is locked\n\t\t\tif (!this._shouldIgnoreShapeLock) {\n\t\t\t\tif (shape.isLocked) {\n\t\t\t\t\t// If the shape itself is locked (even if one of its ancestors is\n\t\t\t\t\t// also locked) then only allow an update that unlocks the shape.\n\t\t\t\t\tif (!(Object.hasOwn(partial, 'isLocked') && !partial.isLocked)) {\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\t\t\t\t} else if (this.isShapeOrAncestorLocked(shape)) {\n\t\t\t\t\t// If the shape itself is unlocked, and any of the shape's\n\t\t\t\t\t// ancestors are locked then we'll skip the update\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Remove any animating shapes from the list of partials\n\t\t\tthis.animatingShapes.delete(partial.id)\n\n\t\t\tcompactedPartials.push(partial)\n\t\t}\n\n\t\tthis._updateShapes(compactedPartials)\n\t\treturn this\n\t}\n\n\t/** @internal */\n\t_updateShapes(_partials: (TLShapePartial | null | undefined)[]) {\n\t\tif (this.getInstanceState().isReadonly) return\n\n\t\tthis.run(() => {\n\t\t\tconst updates = []\n\n\t\t\tlet shape: TLShape | undefined\n\t\t\tlet updated: TLShape\n\n\t\t\tfor (let i = 0, n = _partials.length; i < n; i++) {\n\t\t\t\tconst partial = _partials[i]\n\t\t\t\t// Skip nullish partials (sometimes created by map fns returning undefined)\n\t\t\t\tif (!partial) continue\n\n\t\t\t\t// Get the current shape referenced by the partial\n\t\t\t\t// If there is no current shape, we'll skip this update\n\t\t\t\tshape = this.getShape(partial.id)\n\t\t\t\tif (!shape) continue\n\n\t\t\t\t// Get the updated version of the shape\n\t\t\t\t// If the update had no effect, we'll skip this update\n\t\t\t\tupdated = applyPartialToRecordWithProps(shape, partial)\n\t\t\t\tif (updated === shape) continue\n\n\t\t\t\t//if any shape has an onBeforeUpdate handler, call it and, if the handler returns a\n\t\t\t\t// new shape, replace the old shape with the new one. This is used for example when\n\t\t\t\t// repositioning a text shape based on its new text content.\n\t\t\t\tupdated = this.getShapeUtil(shape).onBeforeUpdate?.(shape, updated) ?? updated\n\n\t\t\t\tupdates.push(updated)\n\t\t\t}\n\n\t\t\tthis.store.put(updates)\n\t\t})\n\t}\n\n\t/** @internal */\n\tprivate _getUnlockedShapeIds(ids: TLShapeId[]): TLShapeId[] {\n\t\treturn ids.filter((id) => !this.getShape(id)?.isLocked)\n\t}\n\n\t/**\n\t * Delete shapes.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.deleteShapes(['box1', 'box2'])\n\t * ```\n\t *\n\t * @param ids - The ids of the shapes to delete.\n\t *\n\t * @public\n\t */\n\tdeleteShapes(ids: TLShapeId[]): this\n\tdeleteShapes(shapes: TLShape[]): this\n\tdeleteShapes(_ids: TLShapeId[] | TLShape[]): this {\n\t\tif (this.getInstanceState().isReadonly) return this\n\n\t\tif (!Array.isArray(_ids)) {\n\t\t\tthrow Error('Editor.deleteShapes: must provide an array of shapes or shapeIds')\n\t\t}\n\n\t\tconst shapeIds =\n\t\t\ttypeof _ids[0] === 'string' ? (_ids as TLShapeId[]) : (_ids as TLShape[]).map((s) => s.id)\n\n\t\t// Normally we don't want to delete locked shapes, but if the force option is set, we'll delete them anyway\n\t\tconst shapeIdsToDelete = this._shouldIgnoreShapeLock\n\t\t\t? shapeIds\n\t\t\t: this._getUnlockedShapeIds(shapeIds)\n\n\t\tif (shapeIdsToDelete.length === 0) return this\n\n\t\t// We also need to delete these shapes' descendants\n\t\tconst allShapeIdsToDelete = new Set(shapeIdsToDelete)\n\n\t\tfor (const id of shapeIdsToDelete) {\n\t\t\tthis.visitDescendants(id, (childId) => {\n\t\t\t\tallShapeIdsToDelete.add(childId)\n\t\t\t})\n\t\t}\n\n\t\treturn this.run(() => this.store.remove([...allShapeIdsToDelete]))\n\t}\n\n\t/**\n\t * Delete a shape.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.deleteShape(shape.id)\n\t * ```\n\t *\n\t * @param id - The id of the shape to delete.\n\t *\n\t * @public\n\t */\n\tdeleteShape(id: TLShapeId): this\n\tdeleteShape(shape: TLShape): this\n\tdeleteShape(_id: TLShapeId | TLShape) {\n\t\tthis.deleteShapes([typeof _id === 'string' ? _id : _id.id])\n\t\treturn this\n\t}\n\n\t/* --------------------- Styles --------------------- */\n\n\t/**\n\t * Get all the current styles among the users selected shapes\n\t *\n\t * @internal\n\t */\n\tprivate _extractSharedStyles(shape: TLShape, sharedStyleMap: SharedStyleMap) {\n\t\tif (this.isShapeOfType(shape, 'group')) {\n\t\t\t// For groups, ignore the styles of the group shape and instead include the styles of the\n\t\t\t// group's children. These are the shapes that would have their styles changed if the\n\t\t\t// user called `setStyle` on the current selection.\n\t\t\tconst childIds = this._parentIdsToChildIds.get()[shape.id]\n\t\t\tif (!childIds) return\n\n\t\t\tfor (let i = 0, n = childIds.length; i < n; i++) {\n\t\t\t\tthis._extractSharedStyles(this.getShape(childIds[i])!, sharedStyleMap)\n\t\t\t}\n\t\t} else {\n\t\t\tfor (const [style, propKey] of this.styleProps[shape.type]) {\n\t\t\t\tsharedStyleMap.applyValue(style, getOwnProperty(shape.props, propKey))\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * A derived map containing all current styles among the user's selected shapes.\n\t *\n\t * @internal\n\t */\n\t@computed\n\tprivate _getSelectionSharedStyles(): ReadonlySharedStyleMap {\n\t\tconst selectedShapes = this.getSelectedShapes()\n\n\t\tconst sharedStyles = new SharedStyleMap()\n\t\tfor (const selectedShape of selectedShapes) {\n\t\t\tthis._extractSharedStyles(selectedShape, sharedStyles)\n\t\t}\n\n\t\treturn sharedStyles\n\t}\n\n\t/**\n\t * Get the style for the next shape.\n\t *\n\t * @example\n\t * ```ts\n\t * const color = editor.getStyleForNextShape(DefaultColorStyle)\n\t * ```\n\t *\n\t * @param style - The style to get.\n\t *\n\t * @public */\n\tgetStyleForNextShape(style: StyleProp): T {\n\t\tconst value = this.getInstanceState().stylesForNextShape[style.id]\n\t\treturn value === undefined ? style.defaultValue : (value as T)\n\t}\n\n\tgetShapeStyleIfExists(shape: TLShape, style: StyleProp): T | undefined {\n\t\tconst styleKey = this.styleProps[shape.type].get(style)\n\t\tif (styleKey === undefined) return undefined\n\t\treturn getOwnProperty(shape.props, styleKey) as T | undefined\n\t}\n\n\t/**\n\t * A map of all the current styles either in the current selection, or that are relevant to the\n\t * current tool.\n\t *\n\t * @example\n\t * ```ts\n\t * const color = editor.getSharedStyles().get(DefaultColorStyle)\n\t * if (color && color.type === 'shared') {\n\t * print('All selected shapes have the same color:', color.value)\n\t * }\n\t * ```\n\t *\n\t * @public\n\t */\n\t@computed({ isEqual: (a, b) => a.equals(b) })\n\tgetSharedStyles(): ReadonlySharedStyleMap {\n\t\t// If we're in selecting and if we have a selection, return the shared styles from the\n\t\t// current selection\n\t\tif (this.isIn('select') && this.getSelectedShapeIds().length > 0) {\n\t\t\treturn this._getSelectionSharedStyles()\n\t\t}\n\n\t\t// If the current tool is associated with a shape, return the styles for that shape.\n\t\t// Otherwise, just return an empty map.\n\t\tconst currentTool = this.root.getCurrent()!\n\t\tconst styles = new SharedStyleMap()\n\n\t\tif (!currentTool) return styles\n\n\t\tif (currentTool.shapeType) {\n\t\t\tfor (const style of this.styleProps[currentTool.shapeType].keys()) {\n\t\t\t\tstyles.applyValue(style, this.getStyleForNextShape(style))\n\t\t\t}\n\t\t}\n\n\t\treturn styles\n\t}\n\n\t/**\n\t * Get the currently selected shared opacity.\n\t * If any shapes are selected, this returns the shared opacity of the selected shapes.\n\t * Otherwise, this returns the chosen opacity for the next shape.\n\t *\n\t * @public\n\t */\n\t@computed getSharedOpacity(): SharedStyle {\n\t\tif (this.isIn('select') && this.getSelectedShapeIds().length > 0) {\n\t\t\tconst shapesToCheck: TLShape[] = []\n\t\t\tconst addShape = (shapeId: TLShapeId) => {\n\t\t\t\tconst shape = this.getShape(shapeId)\n\t\t\t\tif (!shape) return\n\t\t\t\t// For groups, ignore the opacity of the group shape and instead include\n\t\t\t\t// the opacity of the group's children. These are the shapes that would have\n\t\t\t\t// their opacity changed if the user called `setOpacity` on the current selection.\n\t\t\t\tif (this.isShapeOfType(shape, 'group')) {\n\t\t\t\t\tfor (const childId of this.getSortedChildIdsForParent(shape.id)) {\n\t\t\t\t\t\taddShape(childId)\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tshapesToCheck.push(shape)\n\t\t\t\t}\n\t\t\t}\n\t\t\tfor (const shapeId of this.getSelectedShapeIds()) {\n\t\t\t\taddShape(shapeId)\n\t\t\t}\n\n\t\t\tlet opacity: number | null = null\n\t\t\tfor (const shape of shapesToCheck) {\n\t\t\t\tif (opacity === null) {\n\t\t\t\t\topacity = shape.opacity\n\t\t\t\t} else if (opacity !== shape.opacity) {\n\t\t\t\t\treturn { type: 'mixed' }\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (opacity !== null) return { type: 'shared', value: opacity }\n\t\t}\n\t\treturn { type: 'shared', value: this.getInstanceState().opacityForNextShape }\n\t}\n\n\t/**\n\t * Set the opacity for the next shapes. This will effect subsequently created shapes.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.setOpacityForNextShapes(0.5)\n\t * ```\n\t *\n\t * @param opacity - The opacity to set. Must be a number between 0 and 1 inclusive.\n\t * @param historyOptions - The history options for the change.\n\t */\n\tsetOpacityForNextShapes(opacity: number, historyOptions?: TLHistoryBatchOptions): this {\n\t\tthis.updateInstanceState({ opacityForNextShape: opacity }, historyOptions)\n\t\treturn this\n\t}\n\n\t/**\n\t * Set the current opacity. This will effect any selected shapes.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.setOpacityForSelectedShapes(0.5)\n\t * ```\n\t *\n\t * @param opacity - The opacity to set. Must be a number between 0 and 1 inclusive.\n\t */\n\tsetOpacityForSelectedShapes(opacity: number): this {\n\t\tconst selectedShapes = this.getSelectedShapes()\n\n\t\tif (selectedShapes.length > 0) {\n\t\t\tconst shapesToUpdate: TLShape[] = []\n\n\t\t\t// We can have many deep levels of grouped shape\n\t\t\t// Making a recursive function to look through all the levels\n\t\t\tconst addShapeById = (shape: TLShape) => {\n\t\t\t\tif (this.isShapeOfType(shape, 'group')) {\n\t\t\t\t\tconst childIds = this.getSortedChildIdsForParent(shape)\n\t\t\t\t\tfor (const childId of childIds) {\n\t\t\t\t\t\taddShapeById(this.getShape(childId)!)\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tshapesToUpdate.push(shape)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfor (const id of selectedShapes) {\n\t\t\t\taddShapeById(id)\n\t\t\t}\n\n\t\t\tthis.updateShapes(\n\t\t\t\tshapesToUpdate.map((shape) => {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tid: shape.id,\n\t\t\t\t\t\ttype: shape.type,\n\t\t\t\t\t\topacity,\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t)\n\t\t}\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Set the value of a {@link @tldraw/tlschema#StyleProp} for the next shapes. This change will be applied to subsequently created shapes.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.setStyleForNextShapes(DefaultColorStyle, 'red')\n\t * editor.setStyleForNextShapes(DefaultColorStyle, 'red', { ephemeral: true })\n\t * ```\n\t *\n\t * @param style - The style to set.\n\t * @param value - The value to set.\n\t * @param historyOptions - The history options for the change.\n\t *\n\t * @public\n\t */\n\tsetStyleForNextShapes(\n\t\tstyle: StyleProp,\n\t\tvalue: T,\n\t\thistoryOptions?: TLHistoryBatchOptions\n\t): this {\n\t\tconst stylesForNextShape = this.getInstanceState().stylesForNextShape\n\n\t\tthis.updateInstanceState(\n\t\t\t{ stylesForNextShape: { ...stylesForNextShape, [style.id]: value } },\n\t\t\thistoryOptions\n\t\t)\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Set the value of a {@link @tldraw/tlschema#StyleProp}. This change will be applied to the currently selected shapes.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.setStyleForSelectedShapes(DefaultColorStyle, 'red')\n\t * ```\n\t *\n\t * @param style - The style to set.\n\t * @param value - The value to set.\n\t * @param historyOptions - The history options for the change.\n\t *\n\t * @public\n\t */\n\tsetStyleForSelectedShapes>(style: S, value: StylePropValue): this {\n\t\tconst selectedShapes = this.getSelectedShapes()\n\n\t\tif (selectedShapes.length > 0) {\n\t\t\tconst updates: {\n\t\t\t\tutil: ShapeUtil\n\t\t\t\toriginalShape: TLShape\n\t\t\t\tupdatePartial: TLShapePartial\n\t\t\t}[] = []\n\n\t\t\t// We can have many deep levels of grouped shape\n\t\t\t// Making a recursive function to look through all the levels\n\t\t\tconst addShapeById = (shape: TLShape) => {\n\t\t\t\tif (this.isShapeOfType(shape, 'group')) {\n\t\t\t\t\tconst childIds = this.getSortedChildIdsForParent(shape.id)\n\t\t\t\t\tfor (const childId of childIds) {\n\t\t\t\t\t\taddShapeById(this.getShape(childId)!)\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tconst util = this.getShapeUtil(shape)\n\t\t\t\t\tconst stylePropKey = this.styleProps[shape.type].get(style)\n\t\t\t\t\tif (stylePropKey) {\n\t\t\t\t\t\tconst shapePartial: TLShapePartial = {\n\t\t\t\t\t\t\tid: shape.id,\n\t\t\t\t\t\t\ttype: shape.type,\n\t\t\t\t\t\t\tprops: { [stylePropKey]: value },\n\t\t\t\t\t\t}\n\t\t\t\t\t\tupdates.push({\n\t\t\t\t\t\t\tutil,\n\t\t\t\t\t\t\toriginalShape: shape,\n\t\t\t\t\t\t\tupdatePartial: shapePartial,\n\t\t\t\t\t\t})\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfor (const shape of selectedShapes) {\n\t\t\t\taddShapeById(shape)\n\t\t\t}\n\n\t\t\tthis.updateShapes(updates.map(({ updatePartial }) => updatePartial))\n\t\t}\n\n\t\treturn this\n\t}\n\n\t/* --------------------- Content -------------------- */\n\n\t/** @internal */\n\texternalAssetContentHandlers: {\n\t\t[K in TLExternalAssetContent['type']]: {\n\t\t\t[Key in K]:\n\t\t\t\t| null\n\t\t\t\t| ((info: TLExternalAssetContent & { type: Key }) => Promise)\n\t\t}[K]\n\t} = {\n\t\tfile: null,\n\t\turl: null,\n\t}\n\n\t/** @internal */\n\tprivate readonly temporaryAssetPreview = new Map()\n\n\t/**\n\t * Register an external asset handler. This handler will be called when the editor needs to\n\t * create an asset for some external content, like an image/video file or a bookmark URL. For\n\t * example, the 'file' type handler will be called when a user drops an image onto the canvas.\n\t *\n\t * The handler should extract any relevant metadata for the asset, upload it to blob storage\n\t * using {@link Editor.uploadAsset} if needed, and return the asset with the metadata & uploaded\n\t * URL.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.registerExternalAssetHandler('file', myHandler)\n\t * ```\n\t *\n\t * @param type - The type of external content.\n\t * @param handler - The handler to use for this content type.\n\t *\n\t * @public\n\t */\n\tregisterExternalAssetHandler(\n\t\ttype: T,\n\t\thandler: null | ((info: TLExternalAssetContent & { type: T }) => Promise)\n\t): this {\n\t\tthis.externalAssetContentHandlers[type] = handler as any\n\t\treturn this\n\t}\n\n\t/**\n\t * Register a temporary preview of an asset. This is useful for showing a ghost image of\n\t * something that is being uploaded. Retrieve the placeholder with\n\t * {@link Editor.getTemporaryAssetPreview}. Placeholders last for 3 minutes by default, but this\n\t * can be configured using\n\t *\n\t * @example\n\t * ```ts\n\t * editor.createTemporaryAssetPreview(assetId, file)\n\t * ```\n\t *\n\t * @param assetId - The asset's id.\n\t * @param file - The raw file.\n\t *\n\t * @public\n\t */\n\tcreateTemporaryAssetPreview(assetId: TLAssetId, file: File) {\n\t\tif (this.temporaryAssetPreview.has(assetId)) {\n\t\t\treturn this.temporaryAssetPreview.get(assetId)\n\t\t}\n\n\t\tconst objectUrl = URL.createObjectURL(file)\n\t\tthis.temporaryAssetPreview.set(assetId, objectUrl)\n\n\t\t// eslint-disable-next-line no-restricted-globals -- we always want to revoke the asset and object URL\n\t\tsetTimeout(() => {\n\t\t\tthis.temporaryAssetPreview.delete(assetId)\n\t\t\tURL.revokeObjectURL(objectUrl)\n\t\t}, this.options.temporaryAssetPreviewLifetimeMs)\n\n\t\treturn objectUrl\n\t}\n\n\t/**\n\t * Get temporary preview of an asset. This is useful for showing a ghost\n\t * image of something that is being uploaded.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getTemporaryAssetPreview('someId')\n\t * ```\n\t *\n\t * @param assetId - The asset's id.\n\t *\n\t * @public\n\t */\n\tgetTemporaryAssetPreview(assetId: TLAssetId) {\n\t\treturn this.temporaryAssetPreview.get(assetId)\n\t}\n\n\t/**\n\t * Get an asset for an external asset content type.\n\t *\n\t * @example\n\t * ```ts\n\t * const asset = await editor.getAssetForExternalContent({ type: 'file', file: myFile })\n\t * const asset = await editor.getAssetForExternalContent({ type: 'url', url: myUrl })\n\t * ```\n\t *\n\t * @param info - Info about the external content.\n\t * @returns The asset.\n\t */\n\tasync getAssetForExternalContent(info: TLExternalAssetContent): Promise {\n\t\treturn await this.externalAssetContentHandlers[info.type]?.(info as any)\n\t}\n\n\thasExternalAssetHandler(type: TLExternalAssetContent['type']): boolean {\n\t\treturn !!this.externalAssetContentHandlers[type]\n\t}\n\n\t/** @internal */\n\texternalContentHandlers: {\n\t\t[K in TLExternalContent['type']]: {\n\t\t\t[Key in K]: null | ((info: TLExternalContent & { type: Key }) => void)\n\t\t}[K]\n\t} = {\n\t\ttext: null,\n\t\tfiles: null,\n\t\tembed: null,\n\t\t'svg-text': null,\n\t\turl: null,\n\t}\n\n\t/**\n\t * Register an external content handler. This handler will be called when the editor receives\n\t * external content of the provided type. For example, the 'image' type handler will be called\n\t * when a user drops an image onto the canvas.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.registerExternalContentHandler('text', myHandler)\n\t * ```\n\t * @example\n\t * ```ts\n\t * editor.registerExternalContentHandler<'embed', MyEmbedType>('embed', myHandler)\n\t * ```\n\t *\n\t * @param type - The type of external content.\n\t * @param handler - The handler to use for this content type.\n\t *\n\t * @public\n\t */\n\tregisterExternalContentHandler['type'], E>(\n\t\ttype: T,\n\t\thandler:\n\t\t\t| null\n\t\t\t| ((\n\t\t\t\t\tinfo: T extends TLExternalContent['type']\n\t\t\t\t\t\t? TLExternalContent & { type: T }\n\t\t\t\t\t\t: TLExternalContent\n\t\t\t ) => void)\n\t): this {\n\t\tthis.externalContentHandlers[type] = handler as any\n\t\treturn this\n\t}\n\n\t/**\n\t * Handle external content, such as files, urls, embeds, or plain text which has been put into the app, for example by pasting external text or dropping external images onto canvas.\n\t *\n\t * @param info - Info about the external content.\n\t */\n\tasync putExternalContent(info: TLExternalContent): Promise {\n\t\treturn this.externalContentHandlers[info.type]?.(info as any)\n\t}\n\n\t/**\n\t * Get content that can be exported for the given shape ids.\n\t *\n\t * @param shapes - The shapes (or shape ids) to get content for.\n\t *\n\t * @returns The exported content.\n\t *\n\t * @public\n\t */\n\tgetContentFromCurrentPage(shapes: TLShapeId[] | TLShape[]): TLContent | undefined {\n\t\t// todo: make this work with any page, not just the current page\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\n\t\tif (!ids) return\n\t\tif (ids.length === 0) return\n\n\t\tconst shapeIds = this.getShapeAndDescendantIds(ids)\n\n\t\treturn withIsolatedShapes(this, shapeIds, (bindingIdsToKeep) => {\n\t\t\tconst bindings: TLBinding[] = []\n\t\t\tfor (const id of bindingIdsToKeep) {\n\t\t\t\tconst binding = this.getBinding(id)\n\t\t\t\tif (!binding) continue\n\t\t\t\tbindings.push(binding)\n\t\t\t}\n\n\t\t\tconst rootShapeIds: TLShapeId[] = []\n\t\t\tconst shapes: TLShape[] = []\n\t\t\tfor (const shapeId of shapeIds) {\n\t\t\t\tconst shape = this.getShape(shapeId)\n\t\t\t\tif (!shape) continue\n\n\t\t\t\tconst isRootShape = !shapeIds.has(shape.parentId as TLShapeId)\n\t\t\t\tif (isRootShape) {\n\t\t\t\t\t// Need to get page point and rotation of the shape because shapes in\n\t\t\t\t\t// groups use local position/rotation\n\t\t\t\t\tconst pageTransform = this.getShapePageTransform(shape.id)!\n\t\t\t\t\tconst pagePoint = pageTransform.point()\n\t\t\t\t\tshapes.push({\n\t\t\t\t\t\t...shape,\n\t\t\t\t\t\tx: pagePoint.x,\n\t\t\t\t\t\ty: pagePoint.y,\n\t\t\t\t\t\trotation: pageTransform.rotation(),\n\t\t\t\t\t\tparentId: this.getCurrentPageId(),\n\t\t\t\t\t})\n\t\t\t\t\trootShapeIds.push(shape.id)\n\t\t\t\t} else {\n\t\t\t\t\tshapes.push(shape)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst assets: TLAsset[] = []\n\t\t\tconst seenAssetIds = new Set()\n\t\t\tfor (const shape of shapes) {\n\t\t\t\tif (!('assetId' in shape.props)) continue\n\n\t\t\t\tconst assetId = shape.props.assetId\n\t\t\t\tif (!assetId || seenAssetIds.has(assetId)) continue\n\n\t\t\t\tseenAssetIds.add(assetId)\n\t\t\t\tconst asset = this.getAsset(assetId)\n\t\t\t\tif (!asset) continue\n\t\t\t\tassets.push(asset)\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tschema: this.store.schema.serialize(),\n\t\t\t\tshapes,\n\t\t\t\trootShapeIds,\n\t\t\t\tbindings,\n\t\t\t\tassets,\n\t\t\t}\n\t\t})\n\t}\n\n\tasync resolveAssetsInContent(content: TLContent | undefined): Promise {\n\t\tif (!content) return undefined\n\n\t\tconst assets: TLAsset[] = []\n\t\tawait Promise.allSettled(\n\t\t\tcontent.assets.map(async (asset) => {\n\t\t\t\tif (\n\t\t\t\t\t(asset.type === 'image' || asset.type === 'video') &&\n\t\t\t\t\t!asset.props.src?.startsWith('data:image') &&\n\t\t\t\t\t!asset.props.src?.startsWith('http')\n\t\t\t\t) {\n\t\t\t\t\tconst assetWithDataUrl = structuredClone(asset as TLImageAsset | TLVideoAsset)\n\t\t\t\t\tconst objectUrl = await this.store.props.assets.resolve(asset, {\n\t\t\t\t\t\tscreenScale: 1,\n\t\t\t\t\t\tsteppedScreenScale: 1,\n\t\t\t\t\t\tdpr: 1,\n\t\t\t\t\t\tnetworkEffectiveType: null,\n\t\t\t\t\t\tshouldResolveToOriginal: true,\n\t\t\t\t\t})\n\t\t\t\t\tassetWithDataUrl.props.src = await FileHelpers.blobToDataUrl(\n\t\t\t\t\t\tawait fetch(objectUrl!).then((r) => r.blob())\n\t\t\t\t\t)\n\t\t\t\t\tassets.push(assetWithDataUrl)\n\t\t\t\t} else {\n\t\t\t\t\tassets.push(asset)\n\t\t\t\t}\n\t\t\t})\n\t\t)\n\t\tcontent.assets = assets\n\n\t\treturn content\n\t}\n\n\t/**\n\t * Place content into the editor.\n\t *\n\t * @param content - The content.\n\t * @param options - Options for placing the content.\n\t *\n\t * @public\n\t */\n\tputContentOntoCurrentPage(\n\t\tcontent: TLContent,\n\t\toptions: {\n\t\t\tpoint?: VecLike\n\t\t\tselect?: boolean\n\t\t\tpreservePosition?: boolean\n\t\t\tpreserveIds?: boolean\n\t\t} = {}\n\t): this {\n\t\tif (this.getInstanceState().isReadonly) return this\n\n\t\t// todo: make this able to support putting content onto any page, not just the current page\n\n\t\tif (!content.schema) {\n\t\t\tthrow Error('Could not put content:\\ncontent is missing a schema.')\n\t\t}\n\n\t\tconst { select = false, preserveIds = false, preservePosition = false } = options\n\t\tlet { point = undefined } = options\n\n\t\t// decide on a parent for the put shapes; if the parent is among the put shapes(?) then use its parent\n\n\t\tconst currentPageId = this.getCurrentPageId()\n\t\tconst { rootShapeIds } = content\n\n\t\t// We need to collect the migrated records\n\t\tconst assets: TLAsset[] = []\n\t\tconst shapes: TLShape[] = []\n\t\tconst bindings: TLBinding[] = []\n\n\t\t// Let's treat the content as a store, and then migrate that store.\n\t\tconst store: StoreSnapshot = {\n\t\t\tstore: {\n\t\t\t\t...Object.fromEntries(content.assets.map((asset) => [asset.id, asset] as const)),\n\t\t\t\t...Object.fromEntries(content.shapes.map((shape) => [shape.id, shape] as const)),\n\t\t\t\t...Object.fromEntries(\n\t\t\t\t\tcontent.bindings?.map((bindings) => [bindings.id, bindings] as const) ?? []\n\t\t\t\t),\n\t\t\t},\n\t\t\tschema: content.schema,\n\t\t}\n\t\tconst result = this.store.schema.migrateStoreSnapshot(store)\n\t\tif (result.type === 'error') {\n\t\t\tthrow Error('Could not put content: could not migrate content')\n\t\t}\n\t\tfor (const record of Object.values(result.value)) {\n\t\t\tswitch (record.typeName) {\n\t\t\t\tcase 'asset': {\n\t\t\t\t\tassets.push(record)\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase 'shape': {\n\t\t\t\t\tshapes.push(record)\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase 'binding': {\n\t\t\t\t\tbindings.push(record)\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Ok, we've got our migrated records, now we can continue!\n\t\tconst shapeIdMap = new Map(\n\t\t\tpreserveIds\n\t\t\t\t? shapes.map((shape) => [shape.id, shape.id])\n\t\t\t\t: shapes.map((shape) => [shape.id, createShapeId()])\n\t\t)\n\t\tconst bindingIdMap = new Map(\n\t\t\tpreserveIds\n\t\t\t\t? bindings.map((binding) => [binding.id, binding.id])\n\t\t\t\t: bindings.map((binding) => [binding.id, createBindingId()])\n\t\t)\n\n\t\t// By default, the paste parent will be the current page.\n\t\tlet pasteParentId = this.getCurrentPageId() as TLPageId | TLShapeId\n\t\tlet lowestDepth = Infinity\n\t\tlet lowestAncestors: TLShape[] = []\n\n\t\t// Among the selected shapes, find the shape with the fewest ancestors and use its first ancestor.\n\t\tfor (const shape of this.getSelectedShapes()) {\n\t\t\tif (lowestDepth === 0) break\n\n\t\t\tconst isFrame = this.isShapeOfType(shape, 'frame')\n\t\t\tconst ancestors = this.getShapeAncestors(shape)\n\t\t\tif (isFrame) ancestors.push(shape)\n\n\t\t\tconst depth = isFrame ? ancestors.length + 1 : ancestors.length\n\n\t\t\tif (depth < lowestDepth) {\n\t\t\t\tlowestDepth = depth\n\t\t\t\tlowestAncestors = ancestors\n\t\t\t\tpasteParentId = isFrame ? shape.id : shape.parentId\n\t\t\t} else if (depth === lowestDepth) {\n\t\t\t\tif (lowestAncestors.length !== ancestors.length) {\n\t\t\t\t\tthrow Error(`Ancestors: ${lowestAncestors.length} !== ${ancestors.length}`)\n\t\t\t\t}\n\n\t\t\t\tif (lowestAncestors.length === 0) {\n\t\t\t\t\tpasteParentId = currentPageId\n\t\t\t\t\tbreak\n\t\t\t\t} else {\n\t\t\t\t\tpasteParentId = currentPageId\n\t\t\t\t\tfor (let i = 0; i < lowestAncestors.length; i++) {\n\t\t\t\t\t\tif (ancestors[i] !== lowestAncestors[i]) break\n\t\t\t\t\t\tpasteParentId = ancestors[i].id\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tlet isDuplicating = false\n\n\t\tif (!isPageId(pasteParentId)) {\n\t\t\tconst parent = this.getShape(pasteParentId)\n\t\t\tif (parent) {\n\t\t\t\tif (!this.getViewportPageBounds().includes(this.getShapePageBounds(parent)!)) {\n\t\t\t\t\tpasteParentId = currentPageId\n\t\t\t\t} else {\n\t\t\t\t\tif (rootShapeIds.length === 1) {\n\t\t\t\t\t\tconst rootShape = shapes.find((s) => s.id === rootShapeIds[0])!\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\tthis.isShapeOfType(parent, 'frame') &&\n\t\t\t\t\t\t\tthis.isShapeOfType(rootShape, 'frame') &&\n\t\t\t\t\t\t\trootShape.props.w === parent?.props.w &&\n\t\t\t\t\t\t\trootShape.props.h === parent?.props.h\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\tisDuplicating = true\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tpasteParentId = currentPageId\n\t\t\t}\n\t\t}\n\n\t\tif (!isDuplicating) {\n\t\t\tisDuplicating = shapeIdMap.has(pasteParentId)\n\t\t}\n\n\t\tif (isDuplicating) {\n\t\t\tpasteParentId = this.getShape(pasteParentId)!.parentId\n\t\t}\n\n\t\tlet index = this.getHighestIndexForParent(pasteParentId) // todo: requires that the putting page is the current page\n\n\t\tconst rootShapes: TLShape[] = []\n\n\t\tconst newShapes: TLShape[] = shapes.map((oldShape): TLShape => {\n\t\t\tconst newId = shapeIdMap.get(oldShape.id)!\n\n\t\t\t// Create the new shape (new except for the id)\n\t\t\tconst newShape = { ...oldShape, id: newId }\n\n\t\t\tif (rootShapeIds.includes(oldShape.id)) {\n\t\t\t\tnewShape.parentId = currentPageId\n\t\t\t\trootShapes.push(newShape)\n\t\t\t}\n\n\t\t\t// Assign the child to its new parent.\n\n\t\t\t// If the child's parent is among the putting shapes, then assign\n\t\t\t// it to the new parent's id.\n\t\t\tif (shapeIdMap.has(newShape.parentId)) {\n\t\t\t\tnewShape.parentId = shapeIdMap.get(oldShape.parentId)!\n\t\t\t} else {\n\t\t\t\trootShapeIds.push(newShape.id)\n\t\t\t\t// newShape.parentId = pasteParentId\n\t\t\t\tnewShape.index = index\n\t\t\t\tindex = getIndexAbove(index)\n\t\t\t}\n\n\t\t\treturn newShape\n\t\t})\n\n\t\tif (newShapes.length + this.getCurrentPageShapeIds().size > this.options.maxShapesPerPage) {\n\t\t\t// There's some complexity here involving children\n\t\t\t// that might be created without their parents, so\n\t\t\t// if we're going over the limit then just don't paste.\n\t\t\talertMaxShapes(this)\n\t\t\treturn this\n\t\t}\n\n\t\tconst newBindings = bindings.map(\n\t\t\t(oldBinding): TLBinding => ({\n\t\t\t\t...oldBinding,\n\t\t\t\tid: assertExists(bindingIdMap.get(oldBinding.id)),\n\t\t\t\tfromId: assertExists(shapeIdMap.get(oldBinding.fromId)),\n\t\t\t\ttoId: assertExists(shapeIdMap.get(oldBinding.toId)),\n\t\t\t})\n\t\t)\n\n\t\t// These are all the assets we need to create\n\t\tconst assetsToCreate: TLAsset[] = []\n\n\t\t// These assets have base64 data that may need to be hosted\n\t\tconst assetsToUpdate: (TLImageAsset | TLVideoAsset)[] = []\n\n\t\tfor (const asset of assets) {\n\t\t\tif (this.store.has(asset.id)) {\n\t\t\t\t// We already have this asset\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tif (\n\t\t\t\t(asset.type === 'image' || asset.type === 'video') &&\n\t\t\t\tasset.props.src?.startsWith('data:image')\n\t\t\t) {\n\t\t\t\t// it's src is a base64 image or video; we need to create a new asset without the src,\n\t\t\t\t// then create a new asset from the original src. So we save a copy of the original asset,\n\t\t\t\t// then delete the src from the original asset.\n\t\t\t\tassetsToUpdate.push(structuredClone(asset as TLImageAsset | TLVideoAsset))\n\t\t\t\tasset.props.src = null\n\t\t\t}\n\n\t\t\t// Add the asset to the list of assets to create\n\t\t\tassetsToCreate.push(asset)\n\t\t}\n\n\t\t// Start loading the new assets, order does not matter\n\t\tPromise.allSettled(\n\t\t\t(assetsToUpdate as (TLImageAsset | TLVideoAsset)[]).map(async (asset) => {\n\t\t\t\t// Turn the data url into a file\n\t\t\t\tconst file = await dataUrlToFile(\n\t\t\t\t\tasset.props.src!,\n\t\t\t\t\tasset.props.name,\n\t\t\t\t\tasset.props.mimeType ?? 'image/png'\n\t\t\t\t)\n\n\t\t\t\t// Get a new asset for the file\n\t\t\t\tconst newAsset = await this.getAssetForExternalContent({\n\t\t\t\t\ttype: 'file',\n\t\t\t\t\tfile,\n\t\t\t\t\tassetId: asset.id,\n\t\t\t\t})\n\n\t\t\t\tif (!newAsset) {\n\t\t\t\t\t// If we don't have a new asset, delete the old asset.\n\t\t\t\t\t// The shapes that reference this asset should break.\n\t\t\t\t\tthis.deleteAssets([asset.id])\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\t// Save the new asset under the old asset's id\n\t\t\t\tthis.updateAssets([{ ...newAsset, id: asset.id }])\n\t\t\t})\n\t\t)\n\n\t\tthis.run(() => {\n\t\t\t// Create any assets that need to be created\n\t\t\tif (assetsToCreate.length > 0) {\n\t\t\t\tthis.createAssets(assetsToCreate)\n\t\t\t}\n\n\t\t\t// Create the shapes with root shapes as children of the page\n\t\t\tthis.createShapes(newShapes)\n\t\t\tthis.createBindings(newBindings)\n\n\t\t\tif (select) {\n\t\t\t\tthis.select(...rootShapes.map((s) => s.id))\n\t\t\t}\n\n\t\t\t// And then, if needed, reparent the root shapes to the paste parent\n\t\t\tif (pasteParentId !== currentPageId) {\n\t\t\t\tthis.reparentShapes(\n\t\t\t\t\trootShapes.map((s) => s.id),\n\t\t\t\t\tpasteParentId\n\t\t\t\t)\n\t\t\t}\n\n\t\t\tconst newCreatedShapes = newShapes.map((s) => this.getShape(s.id)!)\n\t\t\tconst bounds = Box.Common(newCreatedShapes.map((s) => this.getShapePageBounds(s)!))\n\n\t\t\tif (point === undefined) {\n\t\t\t\tif (!isPageId(pasteParentId)) {\n\t\t\t\t\t// Put the shapes in the middle of the (on screen) parent\n\t\t\t\t\tconst shape = this.getShape(pasteParentId)!\n\t\t\t\t\tpoint = Mat.applyToPoint(\n\t\t\t\t\t\tthis.getShapePageTransform(shape),\n\t\t\t\t\t\tthis.getShapeGeometry(shape).bounds.center\n\t\t\t\t\t)\n\t\t\t\t} else {\n\t\t\t\t\tconst viewportPageBounds = this.getViewportPageBounds()\n\t\t\t\t\tif (preservePosition || viewportPageBounds.includes(Box.From(bounds))) {\n\t\t\t\t\t\t// Otherwise, put shapes where they used to be\n\t\t\t\t\t\tpoint = bounds.center\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// If the old bounds are outside of the viewport...\n\t\t\t\t\t\t// put the shapes in the middle of the viewport\n\t\t\t\t\t\tpoint = viewportPageBounds.center\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (rootShapes.length === 1) {\n\t\t\t\tconst onlyRoot = rootShapes[0] as TLFrameShape\n\t\t\t\t// If the old bounds are in the viewport...\n\t\t\t\tif (this.isShapeOfType(onlyRoot, 'frame')) {\n\t\t\t\t\twhile (\n\t\t\t\t\t\tthis.getShapesAtPoint(point).some(\n\t\t\t\t\t\t\t(shape) =>\n\t\t\t\t\t\t\t\tthis.isShapeOfType(shape, 'frame') &&\n\t\t\t\t\t\t\t\tshape.props.w === onlyRoot.props.w &&\n\t\t\t\t\t\t\t\tshape.props.h === onlyRoot.props.h\n\t\t\t\t\t\t)\n\t\t\t\t\t) {\n\t\t\t\t\t\tpoint.x += bounds.w + 16\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst pageCenter = Box.Common(\n\t\t\t\tcompact(rootShapes.map(({ id }) => this.getShapePageBounds(id)))\n\t\t\t).center\n\n\t\t\tconst offset = Vec.Sub(point, pageCenter)\n\n\t\t\tthis.updateShapes(\n\t\t\t\trootShapes.map(({ id }) => {\n\t\t\t\t\tconst s = this.getShape(id)!\n\t\t\t\t\tconst localRotation = this.getShapeParentTransform(id).decompose().rotation\n\t\t\t\t\tconst localDelta = Vec.Rot(offset, -localRotation)\n\n\t\t\t\t\treturn { id: s.id, type: s.type, x: s.x + localDelta.x, y: s.y + localDelta.y }\n\t\t\t\t})\n\t\t\t)\n\t\t})\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Get an exported SVG element of the given shapes.\n\t *\n\t * @param ids - The shapes (or shape ids) to export.\n\t * @param opts - Options for the export.\n\t *\n\t * @returns The SVG element.\n\t *\n\t * @public\n\t */\n\tasync getSvgElement(shapes: TLShapeId[] | TLShape[], opts: TLImageExportOptions = {}) {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\n\t\tif (ids.length === 0) return undefined\n\n\t\treturn exportToSvg(this, ids, opts)\n\t}\n\n\t/**\n\t * Get an exported SVG string of the given shapes.\n\t *\n\t * @param ids - The shapes (or shape ids) to export.\n\t * @param opts - Options for the export.\n\t *\n\t * @returns The SVG element.\n\t *\n\t * @public\n\t */\n\tasync getSvgString(shapes: TLShapeId[] | TLShape[], opts: TLImageExportOptions = {}) {\n\t\tconst result = await this.getSvgElement(shapes, opts)\n\t\tif (!result) return undefined\n\n\t\tconst serializer = new XMLSerializer()\n\t\treturn {\n\t\t\tsvg: serializer.serializeToString(result.svg),\n\t\t\twidth: result.width,\n\t\t\theight: result.height,\n\t\t}\n\t}\n\n\t/** @deprecated Use {@link Editor.getSvgString} or {@link Editor.getSvgElement} instead. */\n\tasync getSvg(shapes: TLShapeId[] | TLShape[], opts: TLImageExportOptions = {}) {\n\t\tconst result = await this.getSvgElement(shapes, opts)\n\t\tif (!result) return undefined\n\t\treturn result.svg\n\t}\n\n\t/* --------------------- Events --------------------- */\n\n\t/**\n\t * The app's current input state.\n\t *\n\t * @public\n\t */\n\tinputs = {\n\t\t/** The most recent pointer down's position in the current page space. */\n\t\toriginPagePoint: new Vec(),\n\t\t/** The most recent pointer down's position in screen space. */\n\t\toriginScreenPoint: new Vec(),\n\t\t/** The previous pointer position in the current page space. */\n\t\tpreviousPagePoint: new Vec(),\n\t\t/** The previous pointer position in screen space. */\n\t\tpreviousScreenPoint: new Vec(),\n\t\t/** The most recent pointer position in the current page space. */\n\t\tcurrentPagePoint: new Vec(),\n\t\t/** The most recent pointer position in screen space. */\n\t\tcurrentScreenPoint: new Vec(),\n\t\t/** A set containing the currently pressed keys. */\n\t\tkeys: new Set(),\n\t\t/** A set containing the currently pressed buttons. */\n\t\tbuttons: new Set(),\n\t\t/** Whether the input is from a pe. */\n\t\tisPen: false,\n\t\t/** Whether the shift key is currently pressed. */\n\t\tshiftKey: false,\n\t\t/** Whether the control or command key is currently pressed. */\n\t\tctrlKey: false,\n\t\t/** Whether the alt or option key is currently pressed. */\n\t\taltKey: false,\n\t\t/** Whether the user is dragging. */\n\t\tisDragging: false,\n\t\t/** Whether the user is pointing. */\n\t\tisPointing: false,\n\t\t/** Whether the user is pinching. */\n\t\tisPinching: false,\n\t\t/** Whether the user is editing. */\n\t\tisEditing: false,\n\t\t/** Whether the user is panning. */\n\t\tisPanning: false,\n\t\t/** Whether the user is spacebar panning. */\n\t\tisSpacebarPanning: false,\n\t\t/** Velocity of mouse pointer, in pixels per millisecond */\n\t\tpointerVelocity: new Vec(),\n\t}\n\n\t/**\n\t * Update the input points from a pointer, pinch, or wheel event.\n\t *\n\t * @param info - The event info.\n\t */\n\tprivate _updateInputsFromEvent(\n\t\tinfo: TLPointerEventInfo | TLPinchEventInfo | TLWheelEventInfo\n\t): void {\n\t\tconst {\n\t\t\tpointerVelocity,\n\t\t\tpreviousScreenPoint,\n\t\t\tpreviousPagePoint,\n\t\t\tcurrentScreenPoint,\n\t\t\tcurrentPagePoint,\n\t\t} = this.inputs\n\n\t\tconst { screenBounds } = this.store.unsafeGetWithoutCapture(TLINSTANCE_ID)!\n\t\tconst { x: cx, y: cy, z: cz } = unsafe__withoutCapture(() => this.getCamera())\n\n\t\tconst sx = info.point.x - screenBounds.x\n\t\tconst sy = info.point.y - screenBounds.y\n\t\tconst sz = info.point.z ?? 0.5\n\n\t\tpreviousScreenPoint.setTo(currentScreenPoint)\n\t\tpreviousPagePoint.setTo(currentPagePoint)\n\n\t\t// The \"screen bounds\" is relative to the user's actual screen.\n\t\t// The \"screen point\" is relative to the \"screen bounds\";\n\t\t// it will be 0,0 when its actual screen position is equal\n\t\t// to screenBounds.point. This is confusing!\n\t\tcurrentScreenPoint.set(sx, sy)\n\t\tconst nx = sx / cz - cx\n\t\tconst ny = sy / cz - cy\n\t\tif (isFinite(nx) && isFinite(ny)) {\n\t\t\tcurrentPagePoint.set(nx, ny, sz)\n\t\t}\n\n\t\tthis.inputs.isPen = info.type === 'pointer' && info.isPen\n\n\t\t// Reset velocity on pointer down, or when a pinch starts or ends\n\t\tif (info.name === 'pointer_down' || this.inputs.isPinching) {\n\t\t\tpointerVelocity.set(0, 0)\n\t\t\tthis.inputs.originScreenPoint.setTo(currentScreenPoint)\n\t\t\tthis.inputs.originPagePoint.setTo(currentPagePoint)\n\t\t}\n\n\t\t// todo: We only have to do this if there are multiple users in the document\n\t\tthis.run(\n\t\t\t() => {\n\t\t\t\tthis.store.put([\n\t\t\t\t\t{\n\t\t\t\t\t\tid: TLPOINTER_ID,\n\t\t\t\t\t\ttypeName: 'pointer',\n\t\t\t\t\t\tx: currentPagePoint.x,\n\t\t\t\t\t\ty: currentPagePoint.y,\n\t\t\t\t\t\tlastActivityTimestamp:\n\t\t\t\t\t\t\t// If our pointer moved only because we're following some other user, then don't\n\t\t\t\t\t\t\t// update our last activity timestamp; otherwise, update it to the current timestamp.\n\t\t\t\t\t\t\tinfo.type === 'pointer' && info.pointerId === INTERNAL_POINTER_IDS.CAMERA_MOVE\n\t\t\t\t\t\t\t\t? this.store.unsafeGetWithoutCapture(TLPOINTER_ID)?.lastActivityTimestamp ??\n\t\t\t\t\t\t\t\t\tthis._tickManager.now\n\t\t\t\t\t\t\t\t: this._tickManager.now,\n\t\t\t\t\t\tmeta: {},\n\t\t\t\t\t},\n\t\t\t\t])\n\t\t\t},\n\t\t\t{ history: 'ignore' }\n\t\t)\n\t}\n\n\t/**\n\t * Dispatch a cancel event.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.cancel()\n\t * ```\n\t *\n\t * @public\n\t */\n\tcancel(): this {\n\t\tthis.dispatch({ type: 'misc', name: 'cancel' })\n\t\treturn this\n\t}\n\n\t/**\n\t * Dispatch an interrupt event.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.interrupt()\n\t * ```\n\t *\n\t * @public\n\t */\n\tinterrupt(): this {\n\t\tthis.dispatch({ type: 'misc', name: 'interrupt' })\n\t\treturn this\n\t}\n\n\t/**\n\t * Dispatch a complete event.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.complete()\n\t * ```\n\t *\n\t * @public\n\t */\n\tcomplete(): this {\n\t\tthis.dispatch({ type: 'misc', name: 'complete' })\n\t\treturn this\n\t}\n\n\t/**\n\t * Puts the editor into focused mode.\n\t *\n\t * This makes the editor eligible to receive keyboard events and some pointer events (move, wheel).\n\t *\n\t * @example\n\t * ```ts\n\t * editor.focus()\n\t * ```\n\t *\n\t * By default this also dispatches a 'focus' event to the container element. To prevent this, pass `focusContainer: false`.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.focus({ focusContainer: false })\n\t * ```\n\t *\n\t * @public\n\t */\n\tfocus({ focusContainer = true } = {}): this {\n\t\tif (this.getIsFocused()) return this\n\t\tif (focusContainer) this.focusManager.focus()\n\t\tthis.updateInstanceState({ isFocused: true })\n\t\treturn this\n\t}\n\n\t/**\n\t * Switches off the editor's focused mode.\n\t *\n\t * This makes the editor ignore keyboard events and some pointer events (move, wheel).\n\t *\n\t * @example\n\t * ```ts\n\t * editor.blur()\n\t * ```\n\t * By default this also dispatches a 'blur' event to the container element. To prevent this, pass `blurContainer: false`.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.blur({ blurContainer: false })\n\t * ```\n\t *\n\t * @public\n\t */\n\tblur({ blurContainer = true } = {}): this {\n\t\tif (!this.getIsFocused()) return this\n\t\tif (blurContainer) {\n\t\t\tthis.focusManager.blur()\n\t\t} else {\n\t\t\tthis.complete() // stop any interaction\n\t\t}\n\t\tthis.updateInstanceState({ isFocused: false })\n\t\treturn this\n\t}\n\n\t/**\n\t * @public\n\t * @returns true if the editor is focused\n\t */\n\t@computed getIsFocused() {\n\t\treturn this.getInstanceState().isFocused\n\t}\n\n\t/**\n\t * @public\n\t * @returns a snapshot of the store's UI and document state\n\t */\n\tgetSnapshot() {\n\t\treturn getSnapshot(this.store)\n\t}\n\n\t/**\n\t * Loads a snapshot into the editor.\n\t * @param snapshot - the snapshot to load\n\t * @returns\n\t */\n\tloadSnapshot(\n\t\tsnapshot: Partial | TLStoreSnapshot,\n\t\topts?: TLLoadSnapshotOptions\n\t) {\n\t\tloadSnapshot(this.store, snapshot, opts)\n\t\treturn this\n\t}\n\n\tprivate _zoomToFitPageContentAt100Percent() {\n\t\tconst bounds = this.getCurrentPageBounds()\n\t\tif (bounds) {\n\t\t\tthis.zoomToBounds(bounds, { immediate: true, targetZoom: this.getBaseZoom() })\n\t\t}\n\t}\n\tprivate _navigateToDeepLink(deepLink: TLDeepLink) {\n\t\tthis.run(() => {\n\t\t\tswitch (deepLink.type) {\n\t\t\t\tcase 'page': {\n\t\t\t\t\tconst page = this.getPage(deepLink.pageId)\n\t\t\t\t\tif (page) {\n\t\t\t\t\t\tthis.setCurrentPage(page)\n\t\t\t\t\t}\n\t\t\t\t\tthis._zoomToFitPageContentAt100Percent()\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tcase 'shapes': {\n\t\t\t\t\tconst allShapes = compact(deepLink.shapeIds.map((id) => this.getShape(id)))\n\t\t\t\t\tconst byPage: { [pageId: string]: TLShape[] } = {}\n\t\t\t\t\tfor (const shape of allShapes) {\n\t\t\t\t\t\tconst pageId = this.getAncestorPageId(shape)\n\t\t\t\t\t\tif (!pageId) continue\n\t\t\t\t\t\tbyPage[pageId] ??= []\n\t\t\t\t\t\tbyPage[pageId].push(shape)\n\t\t\t\t\t}\n\t\t\t\t\tconst [pageId, shapes] = Object.entries(byPage).sort(\n\t\t\t\t\t\t([_, a], [__, b]) => b.length - a.length\n\t\t\t\t\t)[0] ?? ['', []]\n\n\t\t\t\t\tif (!pageId || !shapes.length) {\n\t\t\t\t\t\tthis._zoomToFitPageContentAt100Percent()\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthis.setCurrentPage(pageId as TLPageId)\n\t\t\t\t\t\tconst bounds = Box.Common(shapes.map((s) => this.getShapePageBounds(s)!))\n\t\t\t\t\t\tthis.zoomToBounds(bounds, { immediate: true, targetZoom: this.getBaseZoom() })\n\t\t\t\t\t}\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tcase 'viewport': {\n\t\t\t\t\tif (deepLink.pageId) {\n\t\t\t\t\t\tif (!this.getPage(deepLink.pageId)) {\n\t\t\t\t\t\t\tthis._zoomToFitPageContentAt100Percent()\n\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t}\n\t\t\t\t\t\tthis.setCurrentPage(deepLink.pageId)\n\t\t\t\t\t}\n\t\t\t\t\tthis.zoomToBounds(deepLink.bounds, { immediate: true, inset: 0 })\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tdefault:\n\t\t\t\t\texhaustiveSwitchError(deepLink)\n\t\t\t}\n\t\t})\n\t}\n\n\t/**\n\t * Handles navigating to the content specified by the query param in the given URL.\n\t *\n\t * Use {@link Editor#createDeepLink} to create a URL with a deep link query param.\n\t *\n\t * If no URL is provided, it will look for the param in the current `window.location.href`.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.navigateToDeepLink()\n\t * ```\n\t *\n\t * The default parameter name is 'd'. You can override this by providing the `param` option.\n\t *\n\t * @example\n\t * ```ts\n\t * // disable page parameter and change viewport parameter to 'c'\n\t * editor.navigateToDeepLink({\n\t * param: 'x',\n\t * url: 'https://my-app.com/my-document?x=200.12.454.23.xyz123',\n\t * })\n\t * ```\n\t *\n\t * @param opts - Options for loading the state from the URL.\n\t */\n\tnavigateToDeepLink(opts?: TLDeepLink | { url?: string | URL; param?: string }): Editor {\n\t\tif (opts && 'type' in opts) {\n\t\t\tthis._navigateToDeepLink(opts)\n\t\t\treturn this\n\t\t}\n\n\t\tconst url = new URL(opts?.url ?? window.location.href)\n\t\tconst deepLinkString = url.searchParams.get(opts?.param ?? 'd')\n\n\t\tif (!deepLinkString) {\n\t\t\tthis._zoomToFitPageContentAt100Percent()\n\t\t\treturn this\n\t\t}\n\n\t\ttry {\n\t\t\tthis._navigateToDeepLink(parseDeepLinkString(deepLinkString))\n\t\t} catch (e) {\n\t\t\tconsole.warn(e)\n\t\t\tthis._zoomToFitPageContentAt100Percent()\n\t\t}\n\t\treturn this\n\t}\n\n\t/**\n\t * Turns the given URL into a deep link by adding a query parameter.\n\t *\n\t * e.g. `https://my-app.com/my-document?d=100.100.200.200.xyz123`\n\t *\n\t * If no URL is provided, it will use the current `window.location.href`.\n\t *\n\t * @example\n\t * ```ts\n\t * // create a deep link to the current page + viewport\n\t * navigator.clipboard.writeText(editor.createDeepLink())\n\t * ```\n\t *\n\t * You can link to a particular set of shapes by providing a `to` parameter.\n\t *\n\t * @example\n\t * ```ts\n\t * // create a deep link to the set of currently selected shapes\n\t * navigator.clipboard.writeText(editor.createDeepLink({\n\t * to: { type: 'selection', shapeIds: editor.getSelectedShapeIds() }\n\t * }))\n\t * ```\n\t *\n\t * The default query param is 'd'. You can override this by providing a `param` parameter.\n\t *\n\t * @example\n\t * ```ts\n\t * // Use `x` as the param name instead\n\t * editor.createDeepLink({ param: 'x' })\n\t * ```\n\t *\n\t * @param opts - Options for adding the state to the URL.\n\t * @returns the updated URL\n\t */\n\tcreateDeepLink(opts?: { url?: string | URL; param?: string; to?: TLDeepLink }): URL {\n\t\tconst url = new URL(opts?.url ?? window.location.href)\n\n\t\turl.searchParams.set(\n\t\t\topts?.param ?? 'd',\n\t\t\tcreateDeepLinkString(\n\t\t\t\topts?.to ?? {\n\t\t\t\t\ttype: 'viewport',\n\t\t\t\t\tpageId: this.options.maxPages === 1 ? undefined : this.getCurrentPageId(),\n\t\t\t\t\tbounds: this.getViewportPageBounds(),\n\t\t\t\t}\n\t\t\t)\n\t\t)\n\n\t\treturn url\n\t}\n\n\t/**\n\t * Register a listener for changes to a deep link for the current document.\n\t *\n\t * You'll typically want to use this indirectly via the {@link TldrawEditorBaseProps.deepLinks} prop on the `` component.\n\t *\n\t * By default this will update `window.location` in place, but you can provide a custom callback\n\t * to handle state changes on your own.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.registerDeepLinkListener({\n\t * onChange(url) {\n\t * window.history.replaceState({}, document.title, url.toString())\n\t * }\n\t * })\n\t * ```\n\t *\n\t * You can also provide a custom URL to update, in which case you must also provide `onChange`.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.registerDeepLinkListener({\n\t * getUrl: () => `https://my-app.com/my-document`,\n\t * onChange(url) {\n\t * setShareUrl(url.toString())\n\t * }\n\t * })\n\t * ```\n\t *\n\t * By default this will update with a debounce interval of 500ms, but you can provide a custom interval.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.registerDeepLinkListener({ debounceMs: 1000 })\n\t * ```\n\t * The default parameter name is `d`. You can override this by providing a `param` option.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.registerDeepLinkListener({ param: 'x' })\n\t * ```\n\t * @param opts - Options for setting up the listener.\n\t * @returns a function that will stop the listener.\n\t */\n\tregisterDeepLinkListener(opts?: TLDeepLinkOptions): () => void {\n\t\tif (opts?.getUrl && !opts?.onChange) {\n\t\t\tthrow Error(\n\t\t\t\t'[tldraw:urlStateSync] If you specify getUrl, you must also specify the onChange callback.'\n\t\t\t)\n\t\t}\n\n\t\tconst url$ = computed('url with state', () => {\n\t\t\tconst url = opts?.getUrl?.(this) ?? window.location.href\n\t\t\tconst urlWithState = this.createDeepLink({\n\t\t\t\tparam: opts?.param,\n\t\t\t\turl,\n\t\t\t\tto: opts?.getTarget?.(this),\n\t\t\t})\n\t\t\treturn urlWithState.toString()\n\t\t})\n\n\t\tconst announceChange =\n\t\t\topts?.onChange ??\n\t\t\t(() => {\n\t\t\t\tconst url = this.createDeepLink({\n\t\t\t\t\tparam: opts?.param,\n\t\t\t\t\tto: opts?.getTarget?.(this),\n\t\t\t\t})\n\n\t\t\t\twindow.history.replaceState({}, document.title, url.toString())\n\t\t\t})\n\n\t\tconst scheduleEffect = debounce((execute: () => void) => execute(), opts?.debounceMs ?? 500)\n\n\t\tconst unlisten = react(\n\t\t\t'update url on state change',\n\t\t\t() => announceChange(new URL(url$.get()), this),\n\t\t\t{ scheduleEffect }\n\t\t)\n\n\t\treturn () => {\n\t\t\tunlisten()\n\t\t\tscheduleEffect.cancel()\n\t\t}\n\t}\n\n\t/**\n\t * A manager for recording multiple click events.\n\t *\n\t * @internal\n\t */\n\tprotected _clickManager = new ClickManager(this)\n\n\t/**\n\t * Prevent a double click event from firing the next time the user clicks\n\t *\n\t * @public\n\t */\n\tcancelDoubleClick() {\n\t\tthis._clickManager.cancelDoubleClickTimeout()\n\t}\n\n\t/**\n\t * The previous cursor. Used for restoring the cursor after pan events.\n\t *\n\t * @internal\n\t */\n\tprivate _prevCursor: TLCursorType = 'default'\n\n\t/** @internal */\n\tprivate _shiftKeyTimeout = -1 as any\n\n\t/** @internal */\n\t@bind\n\t_setShiftKeyTimeout() {\n\t\tthis.inputs.shiftKey = false\n\t\tthis.dispatch({\n\t\t\ttype: 'keyboard',\n\t\t\tname: 'key_up',\n\t\t\tkey: 'Shift',\n\t\t\tshiftKey: this.inputs.shiftKey,\n\t\t\tctrlKey: this.inputs.ctrlKey,\n\t\t\taltKey: this.inputs.altKey,\n\t\t\tcode: 'ShiftLeft',\n\t\t})\n\t}\n\n\t/** @internal */\n\tprivate _altKeyTimeout = -1 as any\n\n\t/** @internal */\n\t@bind\n\t_setAltKeyTimeout() {\n\t\tthis.inputs.altKey = false\n\t\tthis.dispatch({\n\t\t\ttype: 'keyboard',\n\t\t\tname: 'key_up',\n\t\t\tkey: 'Alt',\n\t\t\tshiftKey: this.inputs.shiftKey,\n\t\t\tctrlKey: this.inputs.ctrlKey,\n\t\t\taltKey: this.inputs.altKey,\n\t\t\tcode: 'AltLeft',\n\t\t})\n\t}\n\n\t/** @internal */\n\tprivate _ctrlKeyTimeout = -1 as any\n\n\t/** @internal */\n\t@bind\n\t_setCtrlKeyTimeout() {\n\t\tthis.inputs.ctrlKey = false\n\t\tthis.dispatch({\n\t\t\ttype: 'keyboard',\n\t\t\tname: 'key_up',\n\t\t\tkey: 'Ctrl',\n\t\t\tshiftKey: this.inputs.shiftKey,\n\t\t\tctrlKey: this.inputs.ctrlKey,\n\t\t\taltKey: this.inputs.altKey,\n\t\t\tcode: 'ControlLeft',\n\t\t})\n\t}\n\n\t/** @internal */\n\tprivate _restoreToolId = 'select'\n\n\t/** @internal */\n\tprivate _pinchStart = 1\n\n\t/** @internal */\n\tprivate _didPinch = false\n\n\t/** @internal */\n\tprivate _selectedShapeIdsAtPointerDown: TLShapeId[] = []\n\n\t/** @internal */\n\tprivate _longPressTimeout = -1 as any\n\n\t/** @internal */\n\tcapturedPointerId: number | null = null\n\n\t/** @internal */\n\tprivate readonly performanceTracker: PerformanceTracker\n\n\t/** @internal */\n\tprivate performanceTrackerTimeout = -1 as any\n\n\t/**\n\t * Dispatch an event to the editor.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.dispatch(myPointerEvent)\n\t * ```\n\t *\n\t * @param info - The event info.\n\t *\n\t * @public\n\t */\n\tdispatch(info: TLEventInfo) {\n\t\tthis._pendingEventsForNextTick.push(info)\n\t\tif (\n\t\t\t!(\n\t\t\t\t(info.type === 'pointer' && info.name === 'pointer_move') ||\n\t\t\t\tinfo.type === 'wheel' ||\n\t\t\t\tinfo.type === 'pinch'\n\t\t\t)\n\t\t) {\n\t\t\tthis._flushEventsForTick(0)\n\t\t}\n\t\treturn this\n\t}\n\n\tprivate _pendingEventsForNextTick: TLEventInfo[] = []\n\n\tprivate _flushEventsForTick(elapsed: number) {\n\t\tthis.run(() => {\n\t\t\tif (this._pendingEventsForNextTick.length > 0) {\n\t\t\t\tconst events = [...this._pendingEventsForNextTick]\n\t\t\t\tthis._pendingEventsForNextTick.length = 0\n\t\t\t\tfor (const info of events) {\n\t\t\t\t\tthis._flushEventForTick(info)\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (elapsed > 0) {\n\t\t\t\tthis.root.handleEvent({ type: 'misc', name: 'tick', elapsed })\n\t\t\t}\n\t\t\tthis.scribbles.tick(elapsed)\n\t\t})\n\t}\n\n\t_flushEventForTick(info: TLEventInfo) {\n\t\t// prevent us from spamming similar event errors if we're crashed.\n\t\t// todo: replace with new readonly mode?\n\t\tif (this.getCrashingError()) return this\n\n\t\tconst { inputs } = this\n\t\tconst { type } = info\n\n\t\tif (info.type === 'misc') {\n\t\t\t// stop panning if the interaction is cancelled or completed\n\t\t\tif (info.name === 'cancel' || info.name === 'complete') {\n\t\t\t\tthis.inputs.isDragging = false\n\n\t\t\t\tif (this.inputs.isPanning) {\n\t\t\t\t\tthis.inputs.isPanning = false\n\t\t\t\t\tthis.inputs.isSpacebarPanning = false\n\t\t\t\t\tthis.setCursor({ type: this._prevCursor, rotation: 0 })\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tthis.root.handleEvent(info)\n\t\t\treturn\n\t\t}\n\n\t\tif (info.shiftKey) {\n\t\t\tclearTimeout(this._shiftKeyTimeout)\n\t\t\tthis._shiftKeyTimeout = -1\n\t\t\tinputs.shiftKey = true\n\t\t} else if (!info.shiftKey && inputs.shiftKey && this._shiftKeyTimeout === -1) {\n\t\t\tthis._shiftKeyTimeout = this.timers.setTimeout(this._setShiftKeyTimeout, 150)\n\t\t}\n\n\t\tif (info.altKey) {\n\t\t\tclearTimeout(this._altKeyTimeout)\n\t\t\tthis._altKeyTimeout = -1\n\t\t\tinputs.altKey = true\n\t\t} else if (!info.altKey && inputs.altKey && this._altKeyTimeout === -1) {\n\t\t\tthis._altKeyTimeout = this.timers.setTimeout(this._setAltKeyTimeout, 150)\n\t\t}\n\n\t\tif (info.ctrlKey) {\n\t\t\tclearTimeout(this._ctrlKeyTimeout)\n\t\t\tthis._ctrlKeyTimeout = -1\n\t\t\tinputs.ctrlKey = true\n\t\t} else if (!info.ctrlKey && inputs.ctrlKey && this._ctrlKeyTimeout === -1) {\n\t\t\tthis._ctrlKeyTimeout = this.timers.setTimeout(this._setCtrlKeyTimeout, 150)\n\t\t}\n\n\t\tconst { originPagePoint, currentPagePoint } = inputs\n\n\t\tif (!inputs.isPointing) {\n\t\t\tinputs.isDragging = false\n\t\t}\n\n\t\tconst instanceState = this.store.unsafeGetWithoutCapture(TLINSTANCE_ID)!\n\t\tconst pageState = this.store.get(this._getCurrentPageStateId())!\n\t\tconst cameraOptions = this._cameraOptions.__unsafe__getWithoutCapture()!\n\n\t\tswitch (type) {\n\t\t\tcase 'pinch': {\n\t\t\t\tif (cameraOptions.isLocked) return\n\t\t\t\tclearTimeout(this._longPressTimeout)\n\t\t\t\tthis._updateInputsFromEvent(info)\n\n\t\t\t\tswitch (info.name) {\n\t\t\t\t\tcase 'pinch_start': {\n\t\t\t\t\t\tif (inputs.isPinching) return\n\n\t\t\t\t\t\tif (!inputs.isEditing) {\n\t\t\t\t\t\t\tthis._pinchStart = this.getCamera().z\n\t\t\t\t\t\t\tif (!this._selectedShapeIdsAtPointerDown.length) {\n\t\t\t\t\t\t\t\tthis._selectedShapeIdsAtPointerDown = [...pageState.selectedShapeIds]\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tthis._didPinch = true\n\n\t\t\t\t\t\t\tinputs.isPinching = true\n\n\t\t\t\t\t\t\tthis.interrupt()\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\treturn // Stop here!\n\t\t\t\t\t}\n\t\t\t\t\tcase 'pinch': {\n\t\t\t\t\t\tif (!inputs.isPinching) return\n\n\t\t\t\t\t\tconst {\n\t\t\t\t\t\t\tpoint: { z = 1 },\n\t\t\t\t\t\t\tdelta: { x: dx, y: dy },\n\t\t\t\t\t\t} = info\n\n\t\t\t\t\t\t// The center of the pinch in screen space\n\t\t\t\t\t\tconst { x, y } = Vec.SubXY(\n\t\t\t\t\t\t\tinfo.point,\n\t\t\t\t\t\t\tinstanceState.screenBounds.x,\n\t\t\t\t\t\t\tinstanceState.screenBounds.y\n\t\t\t\t\t\t)\n\n\t\t\t\t\t\tthis.stopCameraAnimation()\n\t\t\t\t\t\tif (instanceState.followingUserId) {\n\t\t\t\t\t\t\tthis.stopFollowingUser()\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst { x: cx, y: cy, z: cz } = unsafe__withoutCapture(() => this.getCamera())\n\n\t\t\t\t\t\tconst { panSpeed, zoomSpeed } = cameraOptions\n\t\t\t\t\t\tthis._setCamera(\n\t\t\t\t\t\t\tnew Vec(\n\t\t\t\t\t\t\t\tcx + (dx * panSpeed) / cz - x / cz + x / (z * zoomSpeed),\n\t\t\t\t\t\t\t\tcy + (dy * panSpeed) / cz - y / cz + y / (z * zoomSpeed),\n\t\t\t\t\t\t\t\tz * zoomSpeed\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t{ immediate: true }\n\t\t\t\t\t\t)\n\n\t\t\t\t\t\treturn // Stop here!\n\t\t\t\t\t}\n\t\t\t\t\tcase 'pinch_end': {\n\t\t\t\t\t\tif (!inputs.isPinching) return this\n\n\t\t\t\t\t\t// Stop pinching\n\t\t\t\t\t\tinputs.isPinching = false\n\n\t\t\t\t\t\t// Stash and clear the shapes that were selected when the pinch started\n\t\t\t\t\t\tconst { _selectedShapeIdsAtPointerDown: shapesToReselect } = this\n\t\t\t\t\t\tthis.setSelectedShapes(this._selectedShapeIdsAtPointerDown)\n\t\t\t\t\t\tthis._selectedShapeIdsAtPointerDown = []\n\n\t\t\t\t\t\tif (this._didPinch) {\n\t\t\t\t\t\t\tthis._didPinch = false\n\t\t\t\t\t\t\tif (shapesToReselect.length > 0) {\n\t\t\t\t\t\t\t\tthis.once('tick', () => {\n\t\t\t\t\t\t\t\t\tif (!this._didPinch) {\n\t\t\t\t\t\t\t\t\t\t// Unless we've started pinching again...\n\t\t\t\t\t\t\t\t\t\t// Reselect the shapes that were selected when the pinch started\n\t\t\t\t\t\t\t\t\t\tthis.setSelectedShapes(shapesToReselect)\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\treturn // Stop here!\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tcase 'wheel': {\n\t\t\t\tif (cameraOptions.isLocked) return\n\n\t\t\t\tthis._updateInputsFromEvent(info)\n\n\t\t\t\tif (this.getIsMenuOpen()) {\n\t\t\t\t\t// noop\n\t\t\t\t} else {\n\t\t\t\t\tconst { panSpeed, zoomSpeed, wheelBehavior } = cameraOptions\n\n\t\t\t\t\tif (wheelBehavior !== 'none') {\n\t\t\t\t\t\t// Stop any camera animation\n\t\t\t\t\t\tthis.stopCameraAnimation()\n\t\t\t\t\t\t// Stop following any following user\n\t\t\t\t\t\tif (instanceState.followingUserId) {\n\t\t\t\t\t\t\tthis.stopFollowingUser()\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst { x: cx, y: cy, z: cz } = unsafe__withoutCapture(() => this.getCamera())\n\t\t\t\t\t\tconst { x: dx, y: dy, z: dz = 0 } = info.delta\n\n\t\t\t\t\t\tlet behavior = wheelBehavior\n\n\t\t\t\t\t\t// If the camera behavior is \"zoom\" and the ctrl key is pressed, then pan;\n\t\t\t\t\t\t// If the camera behavior is \"pan\" and the ctrl key is not pressed, then zoom\n\t\t\t\t\t\tif (inputs.ctrlKey) behavior = wheelBehavior === 'pan' ? 'zoom' : 'pan'\n\n\t\t\t\t\t\tswitch (behavior) {\n\t\t\t\t\t\t\tcase 'zoom': {\n\t\t\t\t\t\t\t\t// Zoom in on current screen point using the wheel delta\n\t\t\t\t\t\t\t\tconst { x, y } = this.inputs.currentScreenPoint\n\t\t\t\t\t\t\t\tlet delta = dz\n\n\t\t\t\t\t\t\t\t// If we're forcing zoom, then we need to do the wheel normalization math here\n\t\t\t\t\t\t\t\tif (wheelBehavior === 'zoom') {\n\t\t\t\t\t\t\t\t\tif (Math.abs(dy) > 10) {\n\t\t\t\t\t\t\t\t\t\tdelta = (10 * Math.sign(dy)) / 100\n\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\tdelta = dy / 100\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tconst zoom = cz + (delta ?? 0) * zoomSpeed * cz\n\t\t\t\t\t\t\t\tthis._setCamera(\n\t\t\t\t\t\t\t\t\tnew Vec(\n\t\t\t\t\t\t\t\t\t\tcx + (x / zoom - x) - (x / cz - x),\n\t\t\t\t\t\t\t\t\t\tcy + (y / zoom - y) - (y / cz - y),\n\t\t\t\t\t\t\t\t\t\tzoom\n\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t{ immediate: true }\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\tthis.maybeTrackPerformance('Zooming')\n\t\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tcase 'pan': {\n\t\t\t\t\t\t\t\t// Pan the camera based on the wheel delta\n\t\t\t\t\t\t\t\tthis._setCamera(new Vec(cx + (dx * panSpeed) / cz, cy + (dy * panSpeed) / cz, cz), {\n\t\t\t\t\t\t\t\t\timmediate: true,\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\tthis.maybeTrackPerformance('Panning')\n\t\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'pointer': {\n\t\t\t\t// Ignore pointer events while we're pinching\n\t\t\t\tif (inputs.isPinching) return\n\n\t\t\t\tthis._updateInputsFromEvent(info)\n\t\t\t\tconst { isPen } = info\n\t\t\t\tconst { isPenMode } = instanceState\n\n\t\t\t\tswitch (info.name) {\n\t\t\t\t\tcase 'pointer_down': {\n\t\t\t\t\t\t// If we're in pen mode and the input is not a pen type, then stop here\n\t\t\t\t\t\tif (isPenMode && !isPen) return\n\n\t\t\t\t\t\tif (!this.inputs.isPanning) {\n\t\t\t\t\t\t\t// Start a long press timeout\n\t\t\t\t\t\t\tthis._longPressTimeout = this.timers.setTimeout(() => {\n\t\t\t\t\t\t\t\tthis.dispatch({\n\t\t\t\t\t\t\t\t\t...info,\n\t\t\t\t\t\t\t\t\tpoint: this.inputs.currentScreenPoint,\n\t\t\t\t\t\t\t\t\tname: 'long_press',\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t}, this.options.longPressDurationMs)\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Save the selected ids at pointer down\n\t\t\t\t\t\tthis._selectedShapeIdsAtPointerDown = this.getSelectedShapeIds()\n\n\t\t\t\t\t\t// Firefox bug fix...\n\t\t\t\t\t\t// If it's a left-mouse-click, we store the pointer id for later user\n\t\t\t\t\t\tif (info.button === LEFT_MOUSE_BUTTON) this.capturedPointerId = info.pointerId\n\n\t\t\t\t\t\t// Add the button from the buttons set\n\t\t\t\t\t\tinputs.buttons.add(info.button)\n\n\t\t\t\t\t\t// Start pointing and stop dragging\n\t\t\t\t\t\tinputs.isPointing = true\n\t\t\t\t\t\tinputs.isDragging = false\n\n\t\t\t\t\t\t// If pen mode is off but we're not already in pen mode, turn that on\n\t\t\t\t\t\tif (!isPenMode && isPen) this.updateInstanceState({ isPenMode: true })\n\n\t\t\t\t\t\t// On devices with erasers (like the Surface Pen or Wacom Pen), button 5 is the eraser\n\t\t\t\t\t\tif (info.button === STYLUS_ERASER_BUTTON) {\n\t\t\t\t\t\t\tthis._restoreToolId = this.getCurrentToolId()\n\t\t\t\t\t\t\tthis.complete()\n\t\t\t\t\t\t\tthis.setCurrentTool('eraser')\n\t\t\t\t\t\t} else if (info.button === MIDDLE_MOUSE_BUTTON) {\n\t\t\t\t\t\t\t// Middle mouse pan activates panning unless we're already panning (with spacebar)\n\t\t\t\t\t\t\tif (!this.inputs.isPanning) {\n\t\t\t\t\t\t\t\tthis._prevCursor = this.getInstanceState().cursor.type\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tthis.inputs.isPanning = true\n\t\t\t\t\t\t\tclearTimeout(this._longPressTimeout)\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// We might be panning because we did a middle mouse click, or because we're holding spacebar and started a regular click\n\t\t\t\t\t\t// Also stop here, we don't want the state chart to receive the event\n\t\t\t\t\t\tif (this.inputs.isPanning) {\n\t\t\t\t\t\t\tthis.stopCameraAnimation()\n\t\t\t\t\t\t\tthis.setCursor({ type: 'grabbing', rotation: 0 })\n\t\t\t\t\t\t\treturn this\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t\tcase 'pointer_move': {\n\t\t\t\t\t\t// If the user is in pen mode, but the pointer is not a pen, stop here.\n\t\t\t\t\t\tif (!isPen && isPenMode) return\n\n\t\t\t\t\t\tconst { x: cx, y: cy, z: cz } = unsafe__withoutCapture(() => this.getCamera())\n\n\t\t\t\t\t\t// If we've started panning, then clear any long press timeout\n\t\t\t\t\t\tif (this.inputs.isPanning && this.inputs.isPointing) {\n\t\t\t\t\t\t\t// Handle spacebar / middle mouse button panning\n\t\t\t\t\t\t\tconst { currentScreenPoint, previousScreenPoint } = this.inputs\n\t\t\t\t\t\t\tconst { panSpeed } = cameraOptions\n\t\t\t\t\t\t\tconst offset = Vec.Sub(currentScreenPoint, previousScreenPoint)\n\t\t\t\t\t\t\tthis.setCamera(\n\t\t\t\t\t\t\t\tnew Vec(cx + (offset.x * panSpeed) / cz, cy + (offset.y * panSpeed) / cz, cz),\n\t\t\t\t\t\t\t\t{ immediate: true }\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\tthis.maybeTrackPerformance('Panning')\n\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\tinputs.isPointing &&\n\t\t\t\t\t\t\t!inputs.isDragging &&\n\t\t\t\t\t\t\tVec.Dist2(originPagePoint, currentPagePoint) * this.getZoomLevel() >\n\t\t\t\t\t\t\t\t(instanceState.isCoarsePointer\n\t\t\t\t\t\t\t\t\t? this.options.coarseDragDistanceSquared\n\t\t\t\t\t\t\t\t\t: this.options.dragDistanceSquared) /\n\t\t\t\t\t\t\t\t\tcz\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t// Start dragging\n\t\t\t\t\t\t\tinputs.isDragging = true\n\t\t\t\t\t\t\tclearTimeout(this._longPressTimeout)\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t\tcase 'pointer_up': {\n\t\t\t\t\t\t// Stop dragging / pointing\n\t\t\t\t\t\tinputs.isDragging = false\n\t\t\t\t\t\tinputs.isPointing = false\n\t\t\t\t\t\tclearTimeout(this._longPressTimeout)\n\n\t\t\t\t\t\t// Remove the button from the buttons set\n\t\t\t\t\t\tinputs.buttons.delete(info.button)\n\n\t\t\t\t\t\t// Suppressing pointerup here as doesn't seem to do what we what here.\n\t\t\t\t\t\tif (this.getIsMenuOpen()) return\n\n\t\t\t\t\t\t// If we're in pen mode and we're not using a pen, stop here\n\t\t\t\t\t\tif (instanceState.isPenMode && !isPen) return\n\n\t\t\t\t\t\t// Firefox bug fix...\n\t\t\t\t\t\t// If it's the same pointer that we stored earlier...\n\t\t\t\t\t\t// ... then it's probably still a left-mouse-click!\n\t\t\t\t\t\tif (this.capturedPointerId === info.pointerId) {\n\t\t\t\t\t\t\tthis.capturedPointerId = null\n\t\t\t\t\t\t\tinfo.button = 0\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (inputs.isPanning) {\n\t\t\t\t\t\t\tif (!inputs.keys.has('Space')) {\n\t\t\t\t\t\t\t\tinputs.isPanning = false\n\t\t\t\t\t\t\t\tinputs.isSpacebarPanning = false\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tconst slideDirection = this.inputs.pointerVelocity\n\t\t\t\t\t\t\tconst slideSpeed = Math.min(2, slideDirection.len())\n\n\t\t\t\t\t\t\tswitch (info.button) {\n\t\t\t\t\t\t\t\tcase LEFT_MOUSE_BUTTON: {\n\t\t\t\t\t\t\t\t\tthis.setCursor({ type: 'grab', rotation: 0 })\n\t\t\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tcase MIDDLE_MOUSE_BUTTON: {\n\t\t\t\t\t\t\t\t\tif (this.inputs.keys.has(' ')) {\n\t\t\t\t\t\t\t\t\t\tthis.setCursor({ type: 'grab', rotation: 0 })\n\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\tthis.setCursor({ type: this._prevCursor, rotation: 0 })\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif (slideSpeed > 0) {\n\t\t\t\t\t\t\t\tthis.slideCamera({ speed: slideSpeed, direction: slideDirection })\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tif (info.button === STYLUS_ERASER_BUTTON) {\n\t\t\t\t\t\t\t\t// If we were erasing with a stylus button, restore the tool we were using before we started erasing\n\t\t\t\t\t\t\t\tthis.complete()\n\t\t\t\t\t\t\t\tthis.setCurrentTool(this._restoreToolId)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'keyboard': {\n\t\t\t\t// please, please\n\t\t\t\tif (info.key === 'ShiftRight') info.key = 'ShiftLeft'\n\t\t\t\tif (info.key === 'AltRight') info.key = 'AltLeft'\n\t\t\t\tif (info.code === 'ControlRight') info.code = 'ControlLeft'\n\n\t\t\t\tswitch (info.name) {\n\t\t\t\t\tcase 'key_down': {\n\t\t\t\t\t\t// Add the key from the keys set\n\t\t\t\t\t\tinputs.keys.add(info.code)\n\n\t\t\t\t\t\t// If the space key is pressed (but meta / control isn't!) activate panning\n\t\t\t\t\t\tif (info.code === 'Space' && !info.ctrlKey) {\n\t\t\t\t\t\t\tif (!this.inputs.isPanning) {\n\t\t\t\t\t\t\t\tthis._prevCursor = instanceState.cursor.type\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tthis.inputs.isPanning = true\n\t\t\t\t\t\t\tthis.inputs.isSpacebarPanning = true\n\t\t\t\t\t\t\tclearTimeout(this._longPressTimeout)\n\t\t\t\t\t\t\tthis.setCursor({ type: this.inputs.isPointing ? 'grabbing' : 'grab', rotation: 0 })\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (this.inputs.isSpacebarPanning) {\n\t\t\t\t\t\t\tlet offset: Vec | undefined\n\t\t\t\t\t\t\tswitch (info.code) {\n\t\t\t\t\t\t\t\tcase 'ArrowUp': {\n\t\t\t\t\t\t\t\t\toffset = new Vec(0, -1)\n\t\t\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tcase 'ArrowRight': {\n\t\t\t\t\t\t\t\t\toffset = new Vec(1, 0)\n\t\t\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tcase 'ArrowDown': {\n\t\t\t\t\t\t\t\t\toffset = new Vec(0, 1)\n\t\t\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tcase 'ArrowLeft': {\n\t\t\t\t\t\t\t\t\toffset = new Vec(-1, 0)\n\t\t\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif (offset) {\n\t\t\t\t\t\t\t\tconst bounds = this.getViewportPageBounds()\n\t\t\t\t\t\t\t\tconst next = bounds.clone().translate(offset.mulV({ x: bounds.w, y: bounds.h }))\n\t\t\t\t\t\t\t\tthis._animateToViewport(next, { animation: { duration: 320 } })\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t\tcase 'key_up': {\n\t\t\t\t\t\t// Remove the key from the keys set\n\t\t\t\t\t\tinputs.keys.delete(info.code)\n\n\t\t\t\t\t\t// If we've lifted the space key,\n\t\t\t\t\t\tif (info.code === 'Space') {\n\t\t\t\t\t\t\tif (this.inputs.buttons.has(MIDDLE_MOUSE_BUTTON)) {\n\t\t\t\t\t\t\t\t// If we're still middle dragging, continue panning\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t// otherwise, stop panning\n\t\t\t\t\t\t\t\tthis.inputs.isPanning = false\n\t\t\t\t\t\t\t\tthis.inputs.isSpacebarPanning = false\n\t\t\t\t\t\t\t\tthis.setCursor({ type: this._prevCursor, rotation: 0 })\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t\tcase 'key_repeat': {\n\t\t\t\t\t\t// noop\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\n\t\t// Correct the info name for right / middle clicks\n\t\tif (info.type === 'pointer') {\n\t\t\tif (info.button === MIDDLE_MOUSE_BUTTON) {\n\t\t\t\tinfo.name = 'middle_click'\n\t\t\t} else if (info.button === RIGHT_MOUSE_BUTTON) {\n\t\t\t\tinfo.name = 'right_click'\n\t\t\t}\n\n\t\t\t// If a left click pointer event, send the event to the click manager.\n\t\t\tconst { isPenMode } = this.store.unsafeGetWithoutCapture(TLINSTANCE_ID)!\n\t\t\tif (info.isPen === isPenMode) {\n\t\t\t\t// The click manager may return a new event, i.e. a double click event\n\t\t\t\t// depending on the event coming in and its own state. If the event has\n\t\t\t\t// changed then hand both events to the statechart\n\t\t\t\tconst clickInfo = this._clickManager.handlePointerEvent(info)\n\t\t\t\tif (info.name !== clickInfo.name) {\n\t\t\t\t\tthis.root.handleEvent(info)\n\t\t\t\t\tthis.emit('event', info)\n\t\t\t\t\tthis.root.handleEvent(clickInfo)\n\t\t\t\t\tthis.emit('event', clickInfo)\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Send the event to the statechart. It will be handled by all\n\t\t// active states, starting at the root.\n\t\tthis.root.handleEvent(info)\n\t\tthis.emit('event', info)\n\n\t\t// close open menus at the very end on pointer down! after everything else! \u03C3\u03C5\u03BD\u03C4\u03B5\u03BB\u03B5\u03AF\u03B1\u03C2 \u03C4\u03BF\u1FE6 \u03BA\u03CE\u03B4\u03B9\u03BA\u03B1!!\n\t\tif (info.type === 'pointer' && info.name === 'pointer_down') {\n\t\t\tthis.clearOpenMenus()\n\t\t}\n\n\t\treturn this\n\t}\n\n\t/** @internal */\n\tprivate maybeTrackPerformance(name: string) {\n\t\tif (debugFlags.measurePerformance.get()) {\n\t\t\tif (this.performanceTracker.isStarted()) {\n\t\t\t\tclearTimeout(this.performanceTrackerTimeout)\n\t\t\t} else {\n\t\t\t\tthis.performanceTracker.start(name)\n\t\t\t}\n\t\t\tthis.performanceTrackerTimeout = this.timers.setTimeout(() => {\n\t\t\t\tthis.performanceTracker.stop()\n\t\t\t}, 50)\n\t\t}\n\t}\n}\n\nfunction alertMaxShapes(editor: Editor, pageId = editor.getCurrentPageId()) {\n\tconst name = editor.getPage(pageId)!.name\n\teditor.emit('max-shapes', { name, pageId, count: editor.options.maxShapesPerPage })\n}\n\nfunction applyPartialToRecordWithProps<\n\tT extends UnknownRecord & { type: string; props: object; meta: object },\n>(prev: T, partial?: Partial & { props?: Partial }): T {\n\tif (!partial) return prev\n\tlet next = null as null | T\n\tconst entries = Object.entries(partial)\n\tfor (let i = 0, n = entries.length; i < n; i++) {\n\t\tconst [k, v] = entries[i]\n\t\tif (v === undefined) continue\n\n\t\t// Is the key a special key? We don't update those\n\t\tif (k === 'id' || k === 'type' || k === 'typeName') continue\n\n\t\t// Is the value the same as it was before?\n\t\tif (v === (prev as any)[k]) continue\n\n\t\t// There's a new value, so create the new shape if we haven't already (should we be cloning this?)\n\t\tif (!next) next = { ...prev }\n\n\t\t// for props / meta properties, we support updates with partials of this object\n\t\tif (k === 'props' || k === 'meta') {\n\t\t\tnext[k] = { ...prev[k] } as JsonObject\n\t\t\tfor (const [nextKey, nextValue] of Object.entries(v as object)) {\n\t\t\t\tif (nextValue !== undefined) {\n\t\t\t\t\t;(next[k] as JsonObject)[nextKey] = nextValue\n\t\t\t\t}\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\n\t\t// base property\n\t\t;(next as any)[k] = v\n\t}\n\tif (!next) return prev\n\treturn next\n}\n\nfunction pushShapeWithDescendants(editor: Editor, id: TLShapeId, result: TLShape[]): void {\n\tconst shape = editor.getShape(id)\n\tif (!shape) return\n\tresult.push(shape)\n\tconst childIds = editor.getSortedChildIdsForParent(id)\n\tfor (let i = 0, n = childIds.length; i < n; i++) {\n\t\tpushShapeWithDescendants(editor, childIds[i], result)\n\t}\n}\n\n/**\n * Run `callback` in a world where all bindings from the shapes in `shapeIds` to shapes not in\n * `shapeIds` are removed. This is useful when you want to duplicate/copy shapes without worrying\n * about bindings that might be pointing to shapes that are not being duplicated.\n *\n * The callback is given the set of bindings that should be maintained.\n */\nfunction withIsolatedShapes(\n\teditor: Editor,\n\tshapeIds: Set,\n\tcallback: (bindingsWithBoth: Set) => T\n): T {\n\tlet result!: Result\n\n\teditor.run(\n\t\t() => {\n\t\t\tconst changes = editor.store.extractingChanges(() => {\n\t\t\t\tconst bindingsWithBoth = new Set()\n\t\t\t\tconst bindingsToRemove = new Set()\n\n\t\t\t\tfor (const shapeId of shapeIds) {\n\t\t\t\t\tconst shape = editor.getShape(shapeId)\n\t\t\t\t\tif (!shape) continue\n\n\t\t\t\t\tfor (const binding of editor.getBindingsInvolvingShape(shapeId)) {\n\t\t\t\t\t\tconst hasFrom = shapeIds.has(binding.fromId)\n\t\t\t\t\t\tconst hasTo = shapeIds.has(binding.toId)\n\t\t\t\t\t\tif (hasFrom && hasTo) {\n\t\t\t\t\t\t\tbindingsWithBoth.add(binding.id)\n\t\t\t\t\t\t\tcontinue\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (!hasFrom || !hasTo) {\n\t\t\t\t\t\t\tbindingsToRemove.add(binding.id)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\teditor.deleteBindings([...bindingsToRemove], { isolateShapes: true })\n\n\t\t\t\ttry {\n\t\t\t\t\tresult = Result.ok(callback(bindingsWithBoth))\n\t\t\t\t} catch (error) {\n\t\t\t\t\tresult = Result.err(error)\n\t\t\t\t}\n\t\t\t})\n\n\t\t\teditor.store.applyDiff(reverseRecordsDiff(changes))\n\t\t},\n\t\t{ history: 'ignore' }\n\t)\n\n\tif (result.ok) {\n\t\treturn result.value\n\t} else {\n\t\tthrow result.error\n\t}\n}\n\nfunction getCameraFitXFitY(editor: Editor, cameraOptions: TLCameraOptions) {\n\tif (!cameraOptions.constraints) throw Error('Should have constraints here')\n\tconst {\n\t\tpadding: { x: px, y: py },\n\t} = cameraOptions.constraints\n\tconst vsb = editor.getViewportScreenBounds()\n\tconst bounds = Box.From(cameraOptions.constraints.bounds)\n\tconst zx = (vsb.w - px * 2) / bounds.w\n\tconst zy = (vsb.h - py * 2) / bounds.h\n\treturn { zx, zy }\n}\n"], -- "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAAqF;AACrF,mBAOO;AACP,sBA6CO;AACP,mBA6BO;AACP,2BAAyB;AACzB,8BAKO;AACP,0BAAqC;AACrC,6BAA2D;AAC3D,2BAAiE;AACjE,uBASO;AACP,yBAA4B;AAC5B,qBAAoD;AACpD,iBAA6B;AAC7B,iBAA6B;AAC7B,iBAA6B;AAC7B,qBAAwB;AAExB,qBAAwB;AACxB,uBAAwC;AACxC,IAAAA,gBAA+E;AAC/E,6BAAoE;AACpE,oBAA8B;AAC9B,yBAA2B;AAC3B,uBAKO;AACP,gCAAmC;AACnC,2BAA2C;AAC3C,sBAAmE;AAEnE,2BAA8B;AAC9B,8BAAiC;AACjC,+BAAkC;AAClC,mCAA4C;AAC5C,0BAA6B;AAC7B,+BAAkC;AAClC,gCAAmC;AACnC,0BAA6B;AAC7B,4BAA+B;AAC/B,6BAAgC;AAChC,yBAA4B;AAC5B,yBAA4B;AAC5B,yBAA4B;AAC5B,oCAAuC;AAEvC,uBAA0B;AA/I1B;AA0PO,MAAM,gBAAe,0BAAAC,SA4e3B,8BAAC,wBA8OD,mBAAC,wBA+BD,mBAAC,wBA2QD,gBAAC,wBAwED,uBAAC,wBASD,yBAAC,wBAuCD,4BAAC,wBA0BD,yBAAC,wBA6DD,qBAAC,wBAqED,sBAAC,wBA0BD,sBAAC,wBAKD,4BAAC,wBASD,4BAAC,wBAKD,+BAAC,wBAoCD,4BAAC,wBAUD,0BAAC,wBAyID,+BAAC,wBAYD,6BAAC,wBAuBD,+BAAC,wBAkCD,6BAAC,wBA6CD,sCAAC,wBAUD,wCAAC,wBAeD,0BAAC,wBASD,wBAAC,wBAoED,0BAAC,wBASD,wBAAC,wBAqDD,0BAAC,wBASD,wBAAC,wBAoCD,2BAAC,wBAQD,wBAAC,wBAwCD,2BAAC,wBASD,yBAAC,wBAiGD,4BAAC,wBAUD,kBAAC,wBAWD,0CAAC,wBA4BD,8BAAC,wBAiBD,qBAAC,wBA68BD,gCAAC,wBAUD,gCAAC,wBAaD,8BAAC,wBAoED,+BAAC,wBAaD,yBAAC,wBAmBD,sCAAC,wBA4TD,2BAAC,wBAkBD,0BAAC,wBAcD,iBAAC,wBA4BD,yBAAC,wBAyCD,qCAAC,wBAmND,2BAAC,wBA4ID,+BAAC,wBA2BD,8BAAC,wBAiDD,oCAAC,wBAsDD,iCAAC,wBAoCD,+BAAC,wBAqCD,2BAAC,wBAqED,uCAAC,wBAwJD,0BAAC,wBAUD,wBAAC,wBAsBD,6BAAC,wBA2UD,6BAAC,wBAUD,mCAAC,wBAiBD,4CAAC,wBAwbD,+BAAC,wBA4qED,kCAAC,wBAgDD,4BAAC,uBAAiC,EAAE,SAAS,CAAC,GAAG,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC,IA+BpE,yBAAC,wBAujCD,qBAAC,wBAqSD,4BAAC,oBAkBD,0BAAC,oBAkBD,2BAAC,oBApsR0B,IAAyB;AAAA,EACpD,YAAY;AAAA,IACX;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACD,GAAoB;AACnB,UAAM;AAfD;AA2eN,wBAAiB;AAiBjB,wBAAS;AAOT;AAAA;AAAA;AAAA;AAAA;AAAA,wBAAS;AAOT;AAAA;AAAA;AAAA;AAAA;AAAA,wBAAS;AAOT;AAAA;AAAA;AAAA;AAAA;AAAA,wBAAS,eAAc,oBAAI,IAAgB;AAO3C;AAAA;AAAA;AAAA;AAAA;AAAA,sCAAa;AAGb;AAAA,wBAAiB;AAOjB;AAAA;AAAA;AAAA;AAAA;AAAA,wBAAS;AAQT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,wBAAS;AAOT;AAAA;AAAA;AAAA;AAAA;AAAA,wBAAS;AAOT;AAAA;AAAA;AAAA;AAAA;AAAA,wBAAS;AAOT;AAAA;AAAA;AAAA;AAAA;AAAA,wBAAS;AAOT;AAAA;AAAA;AAAA;AAAA;AAAA,wBAAS;AAOT;AAAA;AAAA;AAAA;AAAA;AAAA,wBAAS;AAOT;AAAA;AAAA;AAAA;AAAA;AAAA;AAOA;AAAA;AAAA;AAAA;AAAA;AAAA,wBAAQ;AAYR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAoBA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA;AAiCA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAoCA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,wBAAmB;AA4KnB,wBAAQ,0BAAyB;AAmHjC;AAAA,wBAAQ,kBAAiC;AAmOzC;AAAA,wBAAQ,2BAA0B;AA+7BlC,wBAAQ,sBAAiB,mBAAK,kBAAkB,uCAAsB;AA0kBtE;AAAA,wBAAQ,sBAAqB;AA6M7B;AAAA;AAAA,wBAAQ,yBAAwB;AAkNhC;AAAA;AAAA,wBAAQ,gCAA2B,mBAAK,2BAA2B,KAAK;AA0QxE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,wBAAQ,oBAAe,mBAAK,gBAAgB,MAA2B;AACvE,wBAAQ,gCAA+B;AA0HvC;AAAA,wBAAiB;AAi0CjB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,wBAAiB;AA09DjB,wBAAQ,mBAAkB,oBAAI,IAAuB;AAuvBrD;AAAA;AAAA,wDAMI;AAAA,MACH,MAAM;AAAA,MACN,KAAK;AAAA,IACN;AAGA;AAAA,wBAAiB,yBAAwB,oBAAI,IAAuB;AAoGpE;AAAA,mDAII;AAAA,MACH,MAAM;AAAA,MACN,OAAO;AAAA,MACP,OAAO;AAAA,MACP,YAAY;AAAA,MACZ,KAAK;AAAA,IACN;AAuiBA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,kCAAS;AAAA;AAAA,MAER,iBAAiB,IAAI,eAAI;AAAA;AAAA,MAEzB,mBAAmB,IAAI,eAAI;AAAA;AAAA,MAE3B,mBAAmB,IAAI,eAAI;AAAA;AAAA,MAE3B,qBAAqB,IAAI,eAAI;AAAA;AAAA,MAE7B,kBAAkB,IAAI,eAAI;AAAA;AAAA,MAE1B,oBAAoB,IAAI,eAAI;AAAA;AAAA,MAE5B,MAAM,oBAAI,IAAY;AAAA;AAAA,MAEtB,SAAS,oBAAI,IAAY;AAAA;AAAA,MAEzB,OAAO;AAAA;AAAA,MAEP,UAAU;AAAA;AAAA,MAEV,SAAS;AAAA;AAAA,MAET,QAAQ;AAAA;AAAA,MAER,YAAY;AAAA;AAAA,MAEZ,YAAY;AAAA;AAAA,MAEZ,YAAY;AAAA;AAAA,MAEZ,WAAW;AAAA;AAAA,MAEX,WAAW;AAAA;AAAA,MAEX,mBAAmB;AAAA;AAAA,MAEnB,iBAAiB,IAAI,eAAI;AAAA,IAC1B;AA+bA;AAAA;AAAA;AAAA;AAAA;AAAA,wBAAU,iBAAgB,IAAI,iCAAa,IAAI;AAgB/C;AAAA;AAAA;AAAA;AAAA;AAAA,wBAAQ,eAA4B;AAGpC;AAAA,wBAAQ,oBAAmB;AAkB3B;AAAA,wBAAQ,kBAAiB;AAkBzB;AAAA,wBAAQ,mBAAkB;AAkB1B;AAAA,wBAAQ,kBAAiB;AAGzB;AAAA,wBAAQ,eAAc;AAGtB;AAAA,wBAAQ,aAAY;AAGpB;AAAA,wBAAQ,kCAA8C,CAAC;AAGvD;AAAA,wBAAQ,qBAAoB;AAG5B;AAAA,6CAAmC;AAGnC;AAAA,wBAAiB;AAGjB;AAAA,wBAAQ,6BAA4B;AA4BpC,wBAAQ,6BAA2C,CAAC;AAnvRnD,SAAK,0BAA0B;AAE/B,SAAK,UAAU,EAAE,GAAG,qCAAsB,GAAG,QAAQ;AACrD,SAAK,QAAQ;AACb,SAAK,YAAY,IAAI,KAAK,MAAM,QAAQ,KAAK,KAAK,KAAK,CAAC;AACxD,SAAK,UAAU,IAAI,qCAAyB;AAAA,MAC3C;AAAA,MACA,eAAe,CAAC,UAAU;AACzB,aAAK,cAAc,OAAO,EAAE,QAAQ,iBAAiB,cAAc,KAAK,CAAC;AACzE,aAAK,MAAM,KAAK;AAAA,MACjB;AAAA,IACD,CAAC;AAED,SAAK,QAAQ,IAAI,+BAAY,IAAI;AAEjC,SAAK,SAAS,IAAI,oBAAO;AACzB,SAAK,YAAY,IAAI,KAAK,OAAO,QAAQ,KAAK,KAAK,MAAM,CAAC;AAE1D,SAAK,eAAe,IAAI,EAAE,GAAG,yCAAwB,GAAG,cAAc,CAAC;AAEvE,SAAK,OAAO,IAAI,qDAAuB,YAAQ,kCAAa,GAAG,iBAAiB,KAAK;AAErF,SAAK,eAAe;AAEpB,SAAK,cAAc,IAAI,+BAAY,IAAI;AACvC,SAAK,eAAe,IAAI,+BAAY,IAAI;AAAA,IAExC,MAAM,gBAAgB,2BAAU;AAAA,MAC/B,OAAgB,UAAU,gBAAgB;AAAA,IAC3C;AAEA,SAAK,OAAO,IAAI,QAAQ,IAAI;AAC5B,SAAK,KAAK,WAAW,CAAC;AAEtB,UAAM,oBAAgB,4CAAsB,UAAU;AAEtD,UAAM,cAAc,CAAC;AACrB,UAAM,cAAc,CAAC;AACrB,UAAM,gBAAgB,oBAAI,IAAgC;AAE1D,eAAW,QAAQ,eAAe;AACjC,YAAM,OAAO,IAAI,KAAK,IAAI;AAC1B,kBAAY,KAAK,IAAI,IAAI;AAEzB,YAAM,sBAAkB,yCAAwB,KAAK,SAAS,CAAC,CAAC;AAChE,kBAAY,KAAK,IAAI,IAAI;AAEzB,iBAAW,SAAS,gBAAgB,KAAK,GAAG;AAC3C,YAAI,CAAC,cAAc,IAAI,MAAM,EAAE,GAAG;AACjC,wBAAc,IAAI,MAAM,IAAI,KAAK;AAAA,QAClC,WAAW,cAAc,IAAI,MAAM,EAAE,MAAM,OAAO;AACjD,gBAAM;AAAA,YACL,iCAAiC,MAAM,EAAE;AAAA,UAC1C;AAAA,QACD;AAAA,MACD;AAAA,IACD;AAEA,SAAK,aAAa;AAClB,SAAK,aAAa;AAElB,UAAM,sBAAkB,sCAAc,YAAY;AAClD,UAAM,gBAAgB,CAAC;AACvB,eAAW,QAAQ,iBAAiB;AACnC,YAAM,OAAO,IAAI,KAAK,IAAI;AAC1B,oBAAc,KAAK,IAAI,IAAI;AAAA,IAC5B;AACA,SAAK,eAAe;AAKpB,eAAW,QAAQ,CAAC,GAAG,KAAK,GAAG;AAC9B,cAAI,6BAAe,KAAK,KAAK,UAAW,KAAK,EAAE,GAAG;AACjD,cAAM,MAAM,gCAAgC,KAAK,EAAE,GAAG;AAAA,MACvD;AACA,WAAK,KAAK,SAAU,KAAK,EAAE,IAAI,IAAI,KAAK,MAAM,KAAK,IAAI;AAAA,IACxD;AAEA,SAAK,cAAc,IAAI,6CAAmB,IAAI;AAC9C,SAAK,YAAY,IAAI,uCAAgB,IAAI;AAIzC,UAAM,2BAA2B,CAChC,eACA,yBACI;AACJ,UAAI,gBAAgB;AAEpB,YAAM,mBAAmB,cAAc,iBAAiB;AAAA,QACvD,CAAC,OAAO,CAAC,qBAAqB,IAAI,EAAE;AAAA,MACrC;AACA,UAAI,iBAAiB,WAAW,cAAc,iBAAiB,QAAQ;AACtE,YAAI,CAAC,cAAe,iBAAgB,EAAE,GAAG,cAAc;AACvD,sBAAc,mBAAmB;AAAA,MAClC;AAEA,YAAM,kBAAkB,cAAc,gBAAgB;AAAA,QACrD,CAAC,OAAO,CAAC,qBAAqB,IAAI,EAAE;AAAA,MACrC;AACA,UAAI,gBAAgB,WAAW,cAAc,gBAAgB,QAAQ;AACpE,YAAI,CAAC,cAAe,iBAAgB,EAAE,GAAG,cAAc;AACvD,sBAAc,kBAAkB;AAAA,MACjC;AAEA,UAAI,cAAc,kBAAkB,qBAAqB,IAAI,cAAc,cAAc,GAAG;AAC3F,YAAI,CAAC,cAAe,iBAAgB,EAAE,GAAG,cAAc;AACvD,sBAAc,iBAAiB;AAAA,MAChC;AAEA,UAAI,cAAc,kBAAkB,qBAAqB,IAAI,cAAc,cAAc,GAAG;AAC3F,YAAI,CAAC,cAAe,iBAAgB,EAAE,GAAG,cAAc;AACvD,sBAAc,iBAAiB;AAAA,MAChC;AAEA,YAAM,kBAAkB,cAAc,gBAAgB;AAAA,QACrD,CAAC,OAAO,CAAC,qBAAqB,IAAI,EAAE;AAAA,MACrC;AACA,UAAI,gBAAgB,WAAW,cAAc,gBAAgB,QAAQ;AACpE,YAAI,CAAC,cAAe,iBAAgB,EAAE,GAAG,cAAc;AACvD,sBAAc,kBAAkB;AAAA,MACjC;AAEA,UAAI,cAAc,kBAAkB,qBAAqB,IAAI,cAAc,cAAc,GAAG;AAC3F,YAAI,CAAC,cAAe,iBAAgB,EAAE,GAAG,cAAc;AACvD,sBAAc,iBAAiB;AAAA,MAChC;AACA,aAAO;AAAA,IACR;AAEA,SAAK,cAAc,KAAK,MAAM;AAE9B,QAAI,kBAAkB,oBAAI,IAA8C;AACxE,UAAM,kBAAkB,oBAAI,IAAe;AAC3C,UAAM,iBAAiB,oBAAI,IAAe;AAC1C,QAAI,sBAAsB,oBAAI,IAAY;AAC1C,SAAK,YAAY;AAAA,MAChB,KAAK,YAAY,iCAAiC,MAAM;AAGvD,wBAAgB,MAAM;AAEtB,mBAAW,YAAY,gBAAgB;AACtC,yBAAe,OAAO,QAAQ;AAC9B,gBAAM,SAAS,KAAK,SAAS,QAAQ;AACrC,cAAI,CAAC,OAAQ;AAEb,gBAAM,OAAO,KAAK,aAAa,MAAM;AACrC,gBAAM,UAAU,KAAK,mBAAmB,MAAM;AAE9C,cAAI,SAAS,QAAQ;AACpB,iBAAK,aAAa,OAAO;AAAA,UAC1B;AAAA,QACD;AAEA,YAAI,oBAAoB,MAAM;AAC7B,gBAAM,IAAI;AACV,gCAAsB,oBAAI,IAAI;AAC9B,qBAAW,QAAQ,GAAG;AACrB,kBAAM,OAAO,KAAK,eAAe,IAAI;AACrC,iBAAK,sBAAsB;AAAA,UAC5B;AAAA,QACD;AAEA,YAAI,gBAAgB,MAAM;AACzB,gBAAM,IAAI;AACV,4BAAkB,oBAAI,IAAI;AAC1B,qBAAW,QAAQ,EAAE,OAAO,GAAG;AAC9B,iBAAK,eAAe,KAAK,OAAO,EAAE,gBAAgB,IAAI;AAAA,UACvD;AAAA,QACD;AAEA,aAAK,KAAK,QAAQ;AAAA,MACnB,CAAC;AAAA,IACF;AAEA,SAAK,YAAY;AAAA,MAChB,KAAK,YAAY,SAAS;AAAA,QACzB,OAAO;AAAA,UACN,aAAa,CAAC,aAAa,eAAe;AACzC,uBAAW,WAAW,KAAK,0BAA0B,UAAU,GAAG;AACjE,kCAAoB,IAAI,QAAQ,IAAI;AACpC,kBAAI,QAAQ,WAAW,WAAW,IAAI;AACrC,qBAAK,eAAe,OAAO,EAAE,yBAAyB;AAAA,kBACrD;AAAA,kBACA;AAAA,kBACA;AAAA,gBACD,CAAC;AAAA,cACF;AACA,kBAAI,QAAQ,SAAS,WAAW,IAAI;AACnC,qBAAK,eAAe,OAAO,EAAE,uBAAuB;AAAA,kBACnD;AAAA,kBACA;AAAA,kBACA;AAAA,gBACD,CAAC;AAAA,cACF;AAAA,YACD;AAGA,gBAAI,YAAY,aAAa,WAAW,UAAU;AACjD,oBAAM,8BAA8B,CAAC,OAAkB;AACtD,sBAAM,kBAAkB,KAAK,SAAS,EAAE;AACxC,oBAAI,CAAC,gBAAiB;AAEtB,2BAAW,WAAW,KAAK,0BAA0B,eAAe,GAAG;AACtE,sCAAoB,IAAI,QAAQ,IAAI;AAEpC,sBAAI,QAAQ,WAAW,gBAAgB,IAAI;AAC1C,yBAAK,eAAe,OAAO,EAAE,yBAAyB;AAAA,sBACrD;AAAA,sBACA,aAAa;AAAA,sBACb,YAAY;AAAA,oBACb,CAAC;AAAA,kBACF;AACA,sBAAI,QAAQ,SAAS,gBAAgB,IAAI;AACxC,yBAAK,eAAe,OAAO,EAAE,uBAAuB;AAAA,sBACnD;AAAA,sBACA,aAAa;AAAA,sBACb,YAAY;AAAA,oBACb,CAAC;AAAA,kBACF;AAAA,gBACD;AAAA,cACD;AACA,0CAA4B,WAAW,EAAE;AACzC,mBAAK,iBAAiB,WAAW,IAAI,2BAA2B;AAAA,YACjE;AAGA,gBAAI,YAAY,aAAa,WAAW,gBAAY,0BAAS,WAAW,QAAQ,GAAG;AAClF,oBAAM,eAAe,oBAAI,IAAI,CAAC,YAAY,EAAE,CAAC;AAC7C,mBAAK,iBAAiB,YAAY,IAAI,CAAC,OAAO;AAC7C,6BAAa,IAAI,EAAE;AAAA,cACpB,CAAC;AAED,yBAAW,qBAAqB,KAAK,cAAc,GAAG;AACrD,oBAAI,kBAAkB,WAAW,WAAW,SAAU;AACtD,sBAAM,gBAAgB,yBAAyB,mBAAmB,YAAY;AAE9E,oBAAI,eAAe;AAClB,uBAAK,MAAM,IAAI,CAAC,aAAa,CAAC;AAAA,gBAC/B;AAAA,cACD;AAAA,YACD;AAEA,gBAAI,YAAY,gBAAY,2BAAU,YAAY,QAAQ,GAAG;AAC5D,6BAAe,IAAI,YAAY,QAAQ;AAAA,YACxC;AAEA,gBAAI,WAAW,aAAa,YAAY,gBAAY,2BAAU,WAAW,QAAQ,GAAG;AACnF,6BAAe,IAAI,WAAW,QAAQ;AAAA,YACvC;AAAA,UACD;AAAA,UACA,cAAc,CAAC,UAAU;AAExB,gBAAI,gBAAgB,IAAI,MAAM,EAAE,EAAG;AAEnC,gBAAI,MAAM,gBAAY,2BAAU,MAAM,QAAQ,GAAG;AAChD,6BAAe,IAAI,MAAM,QAAQ;AAAA,YAClC;AAEA,4BAAgB,IAAI,MAAM,EAAE;AAE5B,kBAAM,mBAAkC,CAAC;AACzC,uBAAW,WAAW,KAAK,0BAA0B,KAAK,GAAG;AAC5D,kCAAoB,IAAI,QAAQ,IAAI;AACpC,+BAAiB,KAAK,QAAQ,EAAE;AAChC,oBAAM,OAAO,KAAK,eAAe,OAAO;AACxC,kBAAI,QAAQ,WAAW,MAAM,IAAI;AAChC,qBAAK,yBAAyB,EAAE,SAAS,cAAc,MAAM,CAAC;AAC9D,qBAAK,0BAA0B,EAAE,SAAS,MAAM,CAAC;AAAA,cAClD,OAAO;AACN,qBAAK,2BAA2B,EAAE,SAAS,cAAc,MAAM,CAAC;AAChE,qBAAK,wBAAwB,EAAE,SAAS,MAAM,CAAC;AAAA,cAChD;AAAA,YACD;AAEA,gBAAI,iBAAiB,QAAQ;AAC5B,mBAAK,eAAe,gBAAgB;AAAA,YACrC;AAEA,kBAAM,aAAa,oBAAI,IAAI,CAAC,MAAM,EAAE,CAAC;AACrC,kBAAM,cAAU;AAAA,cACf,KAAK,cAAc,EAAE,IAAI,CAAC,cAAc;AACvC,uBAAO,yBAAyB,WAAW,UAAU;AAAA,cACtD,CAAC;AAAA,YACF;AAEA,gBAAI,QAAQ,QAAQ;AACnB,mBAAK,MAAM,IAAI,OAAO;AAAA,YACvB;AAAA,UACD;AAAA,QACD;AAAA,QACA,SAAS;AAAA,UACR,cAAc,CAAC,YAAY;AAC1B,kBAAM,OAAO,KAAK,eAAe,OAAO,EAAE,iBAAiB,EAAE,QAAQ,CAAC;AACtE,gBAAI,KAAM,QAAO;AACjB,mBAAO;AAAA,UACR;AAAA,UACA,aAAa,CAAC,YAAY;AACzB,gCAAoB,IAAI,QAAQ,IAAI;AACpC,iBAAK,eAAe,OAAO,EAAE,gBAAgB,EAAE,QAAQ,CAAC;AAAA,UACzD;AAAA,UACA,cAAc,CAAC,eAAe,iBAAiB;AAC9C,kBAAM,UAAU,KAAK,eAAe,YAAY,EAAE,iBAAiB;AAAA,cAClE;AAAA,cACA;AAAA,YACD,CAAC;AACD,gBAAI,QAAS,QAAO;AACpB,mBAAO;AAAA,UACR;AAAA,UACA,aAAa,CAAC,eAAe,iBAAiB;AAC7C,gCAAoB,IAAI,aAAa,IAAI;AACzC,iBAAK,eAAe,YAAY,EAAE,gBAAgB,EAAE,eAAe,aAAa,CAAC;AAAA,UAClF;AAAA,UACA,cAAc,CAAC,YAAY;AAC1B,iBAAK,eAAe,OAAO,EAAE,iBAAiB,EAAE,QAAQ,CAAC;AAAA,UAC1D;AAAA,UACA,aAAa,CAAC,YAAY;AACzB,iBAAK,eAAe,OAAO,EAAE,gBAAgB,EAAE,QAAQ,CAAC;AACxD,gCAAoB,IAAI,QAAQ,IAAI;AAAA,UACrC;AAAA,QACD;AAAA,QACA,MAAM;AAAA,UACL,aAAa,CAAC,WAAW;AACxB,kBAAM,WAAW,iCAAiB,SAAS,OAAO,EAAE;AACpD,kBAAM,eAAe,4CAA4B,SAAS,OAAO,EAAE;AACnE,gBAAI,CAAC,KAAK,MAAM,IAAI,QAAQ,GAAG;AAC9B,mBAAK,MAAM,IAAI,CAAC,iCAAiB,OAAO,EAAE,IAAI,SAAS,CAAC,CAAC,CAAC;AAAA,YAC3D;AACA,gBAAI,CAAC,KAAK,MAAM,IAAI,YAAY,GAAG;AAClC,mBAAK,MAAM,IAAI;AAAA,gBACd,4CAA4B,OAAO,EAAE,IAAI,cAAc,QAAQ,OAAO,GAAG,CAAC;AAAA,cAC3E,CAAC;AAAA,YACF;AAAA,UACD;AAAA,UACA,aAAa,CAAC,QAAQ,WAAW;AAEhC,gBAAI,KAAK,iBAAiB,GAAG,kBAAkB,OAAO,IAAI;AACzD,oBAAM,eAAe,KAAK,SAAS,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO,OAAO,EAAE,GAAG;AACtE,kBAAI,cAAc;AACjB,qBAAK,MAAM,IAAI,CAAC,EAAE,GAAG,KAAK,iBAAiB,GAAG,eAAe,aAAa,CAAC,CAAC;AAAA,cAC7E,WAAW,WAAW,QAAQ;AAE7B,qBAAK,MAAM,oBAAoB;AAAA,cAChC;AAAA,YACD;AAGA,kBAAM,WAAW,iCAAiB,SAAS,OAAO,EAAE;AACpD,kBAAM,uBAAuB,4CAA4B,SAAS,OAAO,EAAE;AAC3E,iBAAK,MAAM,OAAO,CAAC,UAAU,oBAAoB,CAAC;AAAA,UACnD;AAAA,QACD;AAAA,QACA,UAAU;AAAA,UACT,aAAa,CAAC,MAAM,MAAM,WAAW;AAIpC,gBAAI,CAAC,KAAK,MAAM,IAAI,KAAK,aAAa,GAAG;AACxC,oBAAM,eAAe,KAAK,MAAM,IAAI,KAAK,aAAa,IACnD,KAAK,gBACL,KAAK,SAAS,EAAE,CAAC,GAAG;AACvB,kBAAI,cAAc;AACjB,qBAAK,MAAM,OAAO,KAAK,IAAI,CAAC,cAAc;AAAA,kBACzC,GAAG;AAAA,kBACH,eAAe;AAAA,gBAChB,EAAE;AAAA,cACH,WAAW,WAAW,QAAQ;AAE7B,qBAAK,MAAM,oBAAoB;AAAA,cAChC;AAAA,YACD;AAAA,UACD;AAAA,QACD;AAAA,QACA,qBAAqB;AAAA,UACpB,aAAa,CAAC,MAAM,SAAS;AAC5B,gBAAI,MAAM,qBAAqB,MAAM,kBAAkB;AAEtD,oBAAM,WAAW,KAAK,iBAAiB,OAAO,CAAC,OAAO;AACrD,oBAAI,WAAW,KAAK,SAAS,EAAE,GAAG;AAClC,2BAAO,2BAAU,QAAQ,GAAG;AAC3B,sBAAI,KAAK,iBAAiB,SAAS,QAAQ,GAAG;AAC7C,2BAAO;AAAA,kBACR;AACA,6BAAW,KAAK,SAAS,QAAQ,GAAG;AAAA,gBACrC;AACA,uBAAO;AAAA,cACR,CAAC;AAED,kBAAI,qBAAuC;AAE3C,kBAAI,SAAS,SAAS,GAAG;AACxB,sBAAM,sBAAsB,KAAK;AAAA,sBAChC,sBAAQ,SAAS,IAAI,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC,CAAC;AAAA,kBAC/C,CAAC,UAAU,KAAK,cAA4B,OAAO,OAAO;AAAA,gBAC3D;AAEA,oBAAI,qBAAqB;AACxB,uCAAqB;AAAA,gBACtB;AAAA,cACD,OAAO;AACN,oBAAI,MAAM,gBAAgB;AACzB,uCAAqB,KAAK;AAAA,gBAC3B;AAAA,cACD;AAEA,kBACC,SAAS,WAAW,KAAK,iBAAiB,UAC1C,uBAAuB,KAAK,gBAC3B;AACD,qBAAK,MAAM,IAAI;AAAA,kBACd;AAAA,oBACC,GAAG;AAAA,oBACH,kBAAkB;AAAA,oBAClB,gBAAgB,sBAAsB;AAAA,kBACvC;AAAA,gBACD,CAAC;AAAA,cACF;AAAA,YACD;AAAA,UACD;AAAA,QACD;AAAA,MACD,CAAC;AAAA,IACF;AAEA,SAAK,2BAAuB;AAAA,MAA4B,KAAK;AAAA,MAAO,MACnE,KAAK,iBAAiB;AAAA,IACvB;AACA,SAAK,2BAAuB,4CAAkB,KAAK,KAAK;AAExD,SAAK,YAAY;AAAA,MAChB,KAAK,MAAM,OAAO,CAAC,YAAY;AAC9B,aAAK,KAAK,UAAU,OAAO;AAAA,MAC5B,CAAC;AAAA,IACF;AACA,SAAK,YAAY,IAAI,KAAK,QAAQ,OAAO;AAEzC,SAAK;AAAA,MACJ,MAAM;AACL,aAAK,MAAM,oBAAoB;AAG/B,aAAK,wBAAwB;AAAA,UAC5B,gBAAgB;AAAA,UAChB,gBAAgB;AAAA,UAChB,iBAAiB,CAAC;AAAA,QACnB,CAAC;AAAA,MACF;AAAA,MACA,EAAE,SAAS,SAAS;AAAA,IACrB;AAEA,QAAI,gBAAgB,KAAK,KAAK,SAAS,YAAY,MAAM,QAAW;AACnE,YAAM,MAAM,oCAAoC,YAAY,IAAI;AAAA,IACjE;AAEA,SAAK,KAAK,MAAM,QAAW,SAAS;AAEpC,SAAK,oBAAoB,IAAI,2CAAkB,IAAI;AACnD,SAAK,eAAe,IAAI,iCAAa,MAAM,SAAS;AACpD,SAAK,YAAY,IAAI,KAAK,aAAa,QAAQ,KAAK,KAAK,YAAY,CAAC;AAEtE,QAAI,KAAK,iBAAiB,EAAE,iBAAiB;AAC5C,WAAK,kBAAkB;AAAA,IACxB;AAEA,SAAK,GAAG,QAAQ,KAAK,mBAAmB;AAExC,SAAK,OAAO,sBAAsB,MAAM;AACvC,WAAK,aAAa,MAAM;AAAA,IACzB,CAAC;AAED,SAAK,qBAAqB,IAAI,gCAAmB;AAAA,EAClD;AAAA,EAIQ,wBAAwB;AAC/B,QAAI,CAAC,KAAK,wBAAyB,QAAO;AAC1C,WAAO,KAAK,MAAM,oBAAsC,iBAAiB,CAAC,UAAmB;AAC5F,YAAM,eAAe,KAAK,kBAAkB,OAAO,CAAC,MAAM,KAAK,cAAc,CAAC,CAAC;AAC/E,UAAI,aAAc,QAAO;AACzB,aAAO,KAAK,wBAAyB,OAAO,IAAI,KAAK;AAAA,IACtD,CAAC;AAAA,EACF;AAAA,EACA,cAAc,WAAyC;AACtD,QAAI,CAAC,KAAK,wBAAyB,QAAO;AAC1C,WAAO,CAAC,CAAC,KAAK,sBAAuB,EAAG;AAAA,MACvC,OAAO,cAAc,WAAW,YAAY,UAAU;AAAA,IACvD;AAAA,EACD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAoHA,UAAU;AACT,SAAK,YAAY,QAAQ,CAAC,YAAY,QAAQ,CAAC;AAC/C,SAAK,YAAY,MAAM;AACvB,SAAK,aAAa;AAAA,EACnB;AAAA,EA+BA,aAAa,KAAgC;AAC5C,UAAM,OAAO,OAAO,QAAQ,WAAW,MAAM,IAAI;AACjD,UAAM,gBAAY,6BAAe,KAAK,YAAY,IAAI;AACtD,6BAAO,WAAW,iCAAiC,IAAI,GAAG;AAC1D,WAAO;AAAA,EACR;AAAA,EA8BA,eAAe,KAAgC;AAC9C,UAAM,OAAO,OAAO,QAAQ,WAAW,MAAM,IAAI;AACjD,UAAM,kBAAc,6BAAe,KAAK,cAAc,IAAI;AAC1D,6BAAO,aAAa,mCAAmC,IAAI,GAAG;AAC9D,WAAO;AAAA,EACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAqBA,OAAa;AACZ,SAAK,oBAAoB,CAAC;AAC1B,SAAK,SAAS;AACd,SAAK,QAAQ,KAAK;AAClB,WAAO;AAAA,EACR;AAAA,EAOU,aAAsB;AAC/B,WAAO,KAAK,QAAQ,YAAY,IAAI;AAAA,EACrC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,OAAa;AACZ,SAAK,oBAAoB,CAAC;AAC1B,SAAK,SAAS;AACd,SAAK,QAAQ,KAAK;AAClB,WAAO;AAAA,EACR;AAAA,EAEA,eAAe;AACd,SAAK,QAAQ,MAAM;AACnB,WAAO;AAAA,EACR;AAAA,EAOU,aAAsB;AAC/B,WAAO,KAAK,QAAQ,YAAY,IAAI;AAAA,EACrC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAiBA,KAAK,QAAuB;AAC3B,QAAI,OAAO,WAAW,UAAU;AAC/B,cAAQ;AAAA,QACP,mCAAmC,MAAM;AAAA,MAC1C;AAAA,IACD,OAAO;AACN,cAAQ;AAAA,QACP;AAAA,MACD;AAAA,IACD;AACA,SAAK,QAAQ,MAAM,cAAU,uBAAS,CAAC;AACvC,WAAO;AAAA,EACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAsBA,yBAAyB,MAAuB;AAC/C,UAAM,KAAK,IAAI,QAAQ,MAAM,SAAK,uBAAS,CAAC;AAC5C,SAAK,QAAQ,MAAM,EAAE;AACrB,WAAO;AAAA,EACR;AAAA;AAAA;AAAA;AAAA,EAKA,kBAAkB,aAAqB;AACtC,WAAO,KAAK,QAAQ,kBAAkB,WAAW;AAAA,EAClD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAgBA,aAAa,QAAsB;AAClC,SAAK,QAAQ,aAAa,MAAM;AAChC,WAAO;AAAA,EACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,OAAO;AACN,SAAK,QAAQ,KAAK;AAClB,WAAO;AAAA,EACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcA,WAAW,IAAkB;AAC5B,SAAK,QAAQ,WAAW,EAAE;AAC1B,WAAO;AAAA,EACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EA8BA,IAAI,IAAgB,MAAiC;AACpD,UAAM,0BAA0B,KAAK;AACrC,SAAK,yBAAyB,MAAM,mBAAmB;AAEvD,QAAI;AACH,WAAK,QAAQ,MAAM,IAAI,IAAI;AAAA,IAC5B,UAAE;AACD,WAAK,yBAAyB;AAAA,IAC/B;AAEA,WAAO;AAAA,EACR;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,IAAgB,MAAiC;AACtD,WAAO,KAAK,IAAI,IAAI,IAAI;AAAA,EACzB;AAAA;AAAA;AAAA,EAKA,cACC,OACA;AAAA,IACC;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACD,GAMO;AACP,UAAM,qBAAqB,KAAK,uBAAuB,QAAQ,YAAY;AAC3E,oCAAc,OAAO;AAAA,MACpB,MAAM,EAAE,GAAG,mBAAmB,MAAM,GAAG,KAAK;AAAA,MAC5C,QAAQ,EAAE,GAAG,mBAAmB,QAAQ,GAAG,OAAO;AAAA,IACnD,CAAC;AACD,QAAI,cAAc;AACjB,WAAK,MAAM,wBAAwB;AAAA,IACpC;AACA,WAAO;AAAA,EACR;AAAA;AAAA,EAGA,uBACC,QACA,cASC;AACD,QAAI;AACH,YAAM,iBAAiB,KAAK,kBAAkB;AAC9C,aAAO;AAAA,QACN,MAAM;AAAA,UACL;AAAA,UACA;AAAA,QACD;AAAA,QACA,QAAQ;AAAA,UACP,iBAAiB,KAAK,KAAK,QAAQ;AAAA,UACnC,gBAAgB,KAAK,kBAAkB;AAAA,UACvC,cAAc,iBAAiB,KAAK,SAAS,cAAc,IAAI;AAAA,UAC/D,QAAQ,KAAK;AAAA,QACd;AAAA,MACD;AAAA,IACD,QAAQ;AACP,aAAO;AAAA,QACN,MAAM;AAAA,UACL;AAAA,UACA;AAAA,QACD;AAAA,QACA,QAAQ,CAAC;AAAA,MACV;AAAA,IACD;AAAA,EACD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcA,mBAAmB;AAClB,WAAO,KAAK;AAAA,EACb;AAAA;AAAA,EAGA,MAAM,OAAsB;AAC3B,SAAK,iBAAiB;AACtB,SAAK,MAAM,wBAAwB;AACnC,SAAK,KAAK,SAAS,EAAE,MAAM,CAAC;AAC5B,WAAO;AAAA,EACR;AAAA,EAcU,UAAU;AACnB,WAAO,KAAK,KAAK,QAAQ,EAAE,MAAM,OAAO,EAAE,CAAC;AAAA,EAC5C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAeA,KAAK,MAAuB;AAC3B,UAAM,MAAM,KAAK,MAAM,GAAG,EAAE,QAAQ;AACpC,QAAI,QAAQ,KAAK;AACjB,WAAO,IAAI,SAAS,GAAG;AACtB,YAAM,KAAK,IAAI,IAAI;AACnB,UAAI,CAAC,GAAI,QAAO;AAChB,YAAM,UAAU,MAAM,WAAW;AACjC,UAAI,SAAS,OAAO,IAAI;AACvB,YAAI,IAAI,WAAW,EAAG,QAAO;AAC7B,gBAAQ;AACR;AAAA,MACD,MAAO,QAAO;AAAA,IACf;AACA,WAAO;AAAA,EACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaA,WAAW,OAA0B;AACpC,WAAO,MAAM,KAAK,CAAC,SAAS,KAAK,KAAK,IAAI,CAAC;AAAA,EAC5C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAgBA,eAAe,IAAY,OAAO,CAAC,GAAS;AAC3C,SAAK,KAAK,WAAW,IAAI,IAAI;AAC7B,WAAO;AAAA,EACR;AAAA,EAOU,iBAA4B;AACrC,WAAO,KAAK,KAAK,WAAW;AAAA,EAC7B;AAAA,EAOU,mBAA2B;AACpC,UAAM,cAAc,KAAK,eAAe;AACxC,QAAI,CAAC,YAAa,QAAO;AACzB,WAAO,YAAY,qBAAqB,KAAK,YAAY;AAAA,EAC1D;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAeA,mBAAwC,MAA6B;AACpE,UAAM,MAAM,KAAK,MAAM,GAAG,EAAE,QAAQ;AACpC,QAAI,QAAQ,KAAK;AACjB,WAAO,IAAI,SAAS,GAAG;AACtB,YAAM,KAAK,IAAI,IAAI;AACnB,UAAI,CAAC,GAAI,QAAO;AAChB,YAAM,aAAa,MAAM,WAAW,EAAE;AACtC,UAAI,CAAC,WAAY,QAAO;AACxB,cAAQ;AAAA,IACT;AACA,WAAO;AAAA,EACR;AAAA,EASU,sBAAsB;AAC/B,WAAO,KAAK,MAAM,IAAI,6BAAa;AAAA,EACpC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,uBAAuB,UAAqC;AAC3D,SAAK;AAAA,MACJ,MAAM;AACL,aAAK,MAAM,IAAI,CAAC,EAAE,GAAG,KAAK,oBAAoB,GAAG,GAAG,SAAS,CAAC,CAAC;AAAA,MAChE;AAAA,MACA,EAAE,SAAS,SAAS;AAAA,IACrB;AACA,WAAO;AAAA,EACR;AAAA,EASU,mBAA+B;AACxC,WAAO,KAAK,MAAM,IAAI,6BAAa;AAAA,EACpC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,oBACC,SACA,gBACO;AACP,SAAK,qBAAqB,SAAS,EAAE,SAAS,UAAU,GAAG,eAAe,CAAC;AAE3E,QAAI,QAAQ,oBAAoB,QAAW;AAC1C,mBAAa,KAAK,uBAAuB;AACzC,UAAI,QAAQ,oBAAoB,MAAM;AAErC,aAAK,0BAA0B,KAAK,OAAO,WAAW,MAAM;AAC3D,eAAK,qBAAqB,EAAE,iBAAiB,MAAM,GAAG,EAAE,SAAS,SAAS,CAAC;AAAA,QAC5E,GAAG,GAAI;AAAA,MACR;AAAA,IACD;AAEA,WAAO;AAAA,EACR;AAAA;AAAA,EAGA,qBACC,SACA,MACC;AACD,SAAK,IAAI,MAAM;AACd,WAAK,MAAM,IAAI;AAAA,QACd;AAAA,UACC,GAAG,KAAK,iBAAiB;AAAA,UACzB,GAAG;AAAA,QACJ;AAAA,MACD,CAAC;AAAA,IACF,GAAG,IAAI;AAAA,EACR;AAAA,EAkBU,eAAyB;AAClC,WAAO,KAAK,iBAAiB,EAAE;AAAA,EAChC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,YAAY,IAAkB;AAC7B,UAAM,QAAQ,IAAI,IAAI,KAAK,aAAa,CAAC;AACzC,QAAI,CAAC,MAAM,IAAI,EAAE,GAAG;AACnB,YAAM,IAAI,EAAE;AACZ,WAAK,oBAAoB,EAAE,WAAW,CAAC,GAAG,KAAK,EAAE,CAAC;AAAA,IACnD;AACA,WAAO;AAAA,EACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,eAAe,IAAkB;AAChC,UAAM,QAAQ,IAAI,IAAI,KAAK,aAAa,CAAC;AACzC,QAAI,MAAM,IAAI,EAAE,GAAG;AAClB,YAAM,OAAO,EAAE;AACf,WAAK,oBAAoB,EAAE,WAAW,CAAC,GAAG,KAAK,EAAE,CAAC;AAAA,IACnD;AACA,WAAO;AAAA,EACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,iBAAuB;AACtB,QAAI,KAAK,aAAa,EAAE,QAAQ;AAC/B,WAAK,oBAAoB,EAAE,WAAW,CAAC,EAAE,CAAC;AAAA,IAC3C;AACA,WAAO;AAAA,EACR;AAAA,EAYU,gBAAyB;AAClC,WAAO,KAAK,aAAa,EAAE,SAAS;AAAA,EACrC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,UAAU,QAA2B;AACpC,SAAK,oBAAoB,EAAE,QAAQ,EAAE,GAAG,KAAK,iBAAiB,EAAE,QAAQ,GAAG,OAAO,EAAE,CAAC;AACrF,WAAO;AAAA,EACR;AAAA,EASU,gBAAuC;AAChD,WAAO,KAAK,oBAAoB,EAAE,IAAI;AAAA,EACvC;AAAA,EAGkB,sBAAsB;AACvC,WAAO,KAAK,MAAM,MAAM,QAAQ,qBAAqB;AAAA,EACtD;AAAA,EAOU,sBAA2C;AACpD,WAAO,KAAK,MAAM,IAAI,KAAK,uBAAuB,CAAC;AAAA,EACpD;AAAA,EAGkB,yBAAyB;AAC1C,WAAO,4CAA4B,SAAS,KAAK,iBAAiB,CAAC;AAAA,EACpE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcA,uBACC,SAGO;AACP,SAAK,wBAAwB,OAAO;AACpC,WAAO;AAAA,EACR;AAAA,EACA,wBAAwB,SAAiE;AACxF,SAAK,MAAM,OAAO,QAAQ,MAAM,KAAK,oBAAoB,EAAE,IAAI,CAAC,WAAW;AAAA,MAC1E,GAAG;AAAA,MACH,GAAG;AAAA,IACJ,EAAE;AAAA,EACH;AAAA,EAOU,sBAAsB;AAC/B,WAAO,KAAK,oBAAoB,EAAE;AAAA,EACnC;AAAA,EAQU,oBAA+B;AACxC,UAAM,EAAE,iBAAiB,IAAI,KAAK,oBAAoB;AACtD,eAAO,sBAAQ,iBAAiB,IAAI,CAAC,OAAO,KAAK,MAAM,IAAI,EAAE,CAAC,CAAC;AAAA,EAChE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAeA,kBAAkB,QAAuC;AACxD,WAAO,KAAK;AAAA,MACX,MAAM;AACL,cAAM,MAAM,OAAO,IAAI,CAAC,UAAW,OAAO,UAAU,WAAW,QAAQ,MAAM,EAAG;AAChF,cAAM,EAAE,kBAAkB,qBAAqB,IAAI,KAAK,oBAAoB;AAC5E,cAAM,UAAU,IAAI,IAAI,oBAAoB;AAE5C,YAAI,IAAI,WAAW,QAAQ,QAAQ,IAAI,MAAM,CAAC,OAAO,QAAQ,IAAI,EAAE,CAAC,EAAG,QAAO;AAE9E,aAAK,MAAM,IAAI,CAAC,EAAE,GAAG,KAAK,oBAAoB,GAAG,kBAAkB,IAAI,CAAC,CAAC;AAAA,MAC1E;AAAA,MACA,EAAE,SAAS,2BAA2B;AAAA,IACvC;AAAA,EACD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,mBAAmB,OAAqC;AACvD,UAAM,KAAK,OAAO,UAAU,WAAW,QAAQ,OAAO,MAAM;AAC5D,UAAM,SAAS,KAAK,SAAS,EAAE;AAC/B,QAAI,CAAC,OAAQ,QAAO;AACpB,UAAM,mBAAmB,KAAK,oBAAoB;AAClD,WAAO,CAAC,CAAC,KAAK,kBAAkB,QAAQ,CAAC,WAAW,iBAAiB,SAAS,OAAO,EAAE,CAAC;AAAA,EACzF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAeA,UAAU,QAAuC;AAChD,UAAM,MACL,OAAO,OAAO,CAAC,MAAM,WACjB,SACA,OAAqB,IAAI,CAAC,UAAU,MAAM,EAAE;AACjD,SAAK,kBAAkB,GAAG;AAC1B,WAAO;AAAA,EACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,YAAY,QAAuC;AAClD,UAAM,MACL,OAAO,OAAO,CAAC,MAAM,WACjB,SACA,OAAqB,IAAI,CAAC,UAAU,MAAM,EAAE;AACjD,UAAM,mBAAmB,KAAK,oBAAoB;AAClD,QAAI,iBAAiB,SAAS,KAAK,IAAI,SAAS,GAAG;AAClD,WAAK,kBAAkB,iBAAiB,OAAO,CAAC,OAAO,CAAC,IAAI,SAAS,EAAE,CAAC,CAAC;AAAA,IAC1E;AACA,WAAO;AAAA,EACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,YAAkB;AACjB,UAAM,MAAM,KAAK,2BAA2B,KAAK,iBAAiB,CAAC;AAEnE,QAAI,IAAI,UAAU,EAAG,QAAO;AAC5B,SAAK,kBAAkB,KAAK,qBAAqB,GAAG,CAAC;AAErD,WAAO;AAAA,EACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,aAAmB;AAClB,QAAI,KAAK,oBAAoB,EAAE,SAAS,GAAG;AAC1C,WAAK,kBAAkB,CAAC,CAAC;AAAA,IAC1B;AAEA,WAAO;AAAA,EACR;AAAA,EAUU,yBAA2C;AACpD,WAAO,KAAK,qBAAqB,GAAG,MAAM;AAAA,EAC3C;AAAA,EAUU,uBAAuC;AAChD,UAAM,iBAAiB,KAAK,kBAAkB;AAC9C,WAAO,eAAe,WAAW,IAAI,eAAe,CAAC,IAAI;AAAA,EAC1D;AAAA;AAAA;AAAA;AAAA,EAKA,oBAAoB,UAAmC;AACtD,UAAM,aAAS,sBAAQ,SAAS,IAAI,CAAC,OAAO,KAAK,mBAAmB,EAAE,CAAC,CAAC;AACxE,QAAI,OAAO,WAAW,EAAG,QAAO;AAChC,WAAO,eAAI,OAAO,MAAM;AAAA,EACzB;AAAA,EAWU,yBAAqC;AAC9C,WAAO,KAAK,oBAAoB,KAAK,oBAAoB,CAAC;AAAA,EAC3D;AAAA;AAAA;AAAA;AAAA,EAKA,wBAAwB,UAAuB;AAC9C,QAAI,aAAa;AACjB,QAAI,WAAW;AACf,aAAS,IAAI,GAAG,IAAI,SAAS,QAAQ,IAAI,GAAG,KAAK;AAChD,YAAM,gBAAgB,KAAK,sBAAsB,SAAS,CAAC,CAAC;AAC5D,UAAI,CAAC,cAAe;AACpB,UAAI,YAAY;AACf,YAAI,cAAc,SAAS,MAAM,UAAU;AAE1C,iBAAO;AAAA,QACR;AAAA,MACD,OAAO;AAEN,qBAAa;AACb,mBAAW,cAAc,SAAS;AAAA,MACnC;AAAA,IACD;AAEA,WAAO;AAAA,EACR;AAAA,EAQU,uBAA+B;AACxC,WAAO,KAAK,wBAAwB,KAAK,oBAAoB,CAAC;AAAA,EAC/D;AAAA;AAAA;AAAA;AAAA,EAKA,2BAA2B,UAAwC;AAClE,QAAI,SAAS,WAAW,GAAG;AAC1B,aAAO;AAAA,IACR;AAEA,UAAM,oBAAoB,KAAK,wBAAwB,QAAQ;AAC/D,QAAI,sBAAsB,GAAG;AAC5B,aAAO,KAAK,oBAAoB,QAAQ,KAAK;AAAA,IAC9C;AAEA,QAAI,SAAS,WAAW,GAAG;AAC1B,YAAM,SAAS,KAAK,iBAAiB,SAAS,CAAC,CAAC,EAAE,OAAO,MAAM;AAC/D,YAAM,gBAAgB,KAAK,sBAAsB,SAAS,CAAC,CAAC;AAC5D,aAAO,QAAQ,cAAc,aAAa,OAAO,KAAK;AACtD,aAAO;AAAA,IACR;AAGA,UAAM,yBAAyB,eAAI;AAAA,MAClC,SACE,QAAQ,CAAC,OAAO;AAChB,cAAM,gBAAgB,KAAK,sBAAsB,EAAE;AACnD,YAAI,CAAC,cAAe,QAAO,CAAC;AAC5B,eAAO,cAAc,cAAc,KAAK,iBAAiB,EAAE,EAAE,OAAO,OAAO;AAAA,MAC5E,CAAC,EACA,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,iBAAiB,CAAC;AAAA,IACvC;AAEA,2BAAuB,QAAQ,uBAAuB,MAAM,IAAI,iBAAiB;AACjF,WAAO;AAAA,EACR;AAAA,EAQU,gCAAiD;AAC1D,WAAO,KAAK,2BAA2B,KAAK,oBAAoB,CAAC;AAAA,EAClE;AAAA,EAQU,kCAAmD;AAC5D,UAAM,SAAS,KAAK,8BAA8B;AAClD,QAAI,CAAC,OAAQ,QAAO;AACpB,UAAM,EAAE,GAAG,EAAE,IAAI,KAAK,aAAa,OAAO,KAAK;AAC/C,UAAM,OAAO,KAAK,aAAa;AAC/B,WAAO,IAAI,eAAI,GAAG,GAAG,OAAO,QAAQ,MAAM,OAAO,SAAS,IAAI;AAAA,EAC/D;AAAA,EASU,oBAA0C;AACnD,WAAO,KAAK,oBAAoB,EAAE,kBAAkB,KAAK,iBAAiB;AAAA,EAC3E;AAAA,EAOU,kBAAuC;AAChD,UAAM,iBAAiB,KAAK,kBAAkB;AAC9C,WAAO,iBAAiB,KAAK,SAAS,cAAc,IAAI;AAAA,EACzD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,gBAAgB,OAA8C;AAC7D,UAAM,KAAK,OAAO,UAAU,WAAW,QAAQ,OAAO,MAAM;AAE5D,QAAI,OAAO,MAAM;AAChB,YAAMC,SAAQ,KAAK,SAAS,EAAE;AAC9B,UAAI,CAACA,QAAO;AACX,cAAM,MAAM,yCAAyC,EAAE,iBAAiB;AAAA,MACzE;AAEA,UAAI,CAAC,KAAK,cAA4BA,QAAO,OAAO,GAAG;AACtD,cAAM;AAAA,UACL,qEAAqEA,OAAM,IAAI;AAAA,QAChF;AAAA,MACD;AAAA,IACD;AAEA,QAAI,OAAO,KAAK,kBAAkB,EAAG,QAAO;AAE5C,WAAO,KAAK;AAAA,MACX,MAAM;AACL,aAAK,MAAM,OAAO,KAAK,oBAAoB,EAAE,IAAI,CAAC,OAAO,EAAE,GAAG,GAAG,gBAAgB,GAAG,EAAE;AAAA,MACvF;AAAA,MACA,EAAE,SAAS,2BAA2B;AAAA,IACvC;AAAA,EACD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,oBAA0B;AACzB,UAAM,eAAe,KAAK,gBAAgB;AAE1C,QAAI,cAAc;AAEjB,YAAM,QAAQ,KAAK;AAAA,QAAkB;AAAA,QAAc,CAAC,UACnD,KAAK,cAA4B,OAAO,OAAO;AAAA,MAChD;AAEA,WAAK,gBAAgB,OAAO,MAAM,IAAI;AACtC,WAAK,OAAO,aAAa,EAAE;AAAA,IAC5B,OAAO;AAEN,WAAK,gBAAgB,IAAI;AACzB,WAAK,WAAW;AAAA,IACjB;AAEA,WAAO;AAAA,EACR;AAAA,EAOU,oBAAsC;AAC/C,WAAO,KAAK,oBAAoB,EAAE;AAAA,EACnC;AAAA,EAOU,kBAAuC;AAChD,UAAM,iBAAiB,KAAK,kBAAkB;AAC9C,WAAO,iBAAiB,KAAK,SAAS,cAAc,IAAI;AAAA,EACzD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAeA,gBAAgB,OAAyC;AACxD,UAAM,KAAK,OAAO,UAAU,WAAW,QAAQ,OAAO,MAAM;AAC5D,QAAI,OAAO,KAAK,kBAAkB,GAAG;AACpC,UAAI,IAAI;AACP,cAAMA,SAAQ,KAAK,SAAS,EAAE;AAC9B,YAAIA,UAAS,KAAK,aAAaA,MAAK,EAAE,QAAQA,MAAK,GAAG;AACrD,eAAK;AAAA,YACJ,MAAM;AACL,mBAAK,wBAAwB,EAAE,gBAAgB,GAAG,CAAC;AAAA,YACpD;AAAA,YACA,EAAE,SAAS,SAAS;AAAA,UACrB;AACA,iBAAO;AAAA,QACR;AAAA,MACD;AAGA,WAAK;AAAA,QACJ,MAAM;AACL,eAAK,wBAAwB,EAAE,gBAAgB,KAAK,CAAC;AAAA,QACtD;AAAA,QACA,EAAE,SAAS,SAAS;AAAA,MACrB;AAAA,IACD;AACA,WAAO;AAAA,EACR;AAAA,EAUU,oBAAsC;AAC/C,WAAO,KAAK,oBAAoB,EAAE;AAAA,EACnC;AAAA,EAOU,kBAAuC;AAChD,UAAM,iBAAiB,KAAK,kBAAkB;AAC9C,WAAO,iBAAiB,KAAK,SAAS,cAAc,IAAI;AAAA,EACzD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcA,gBAAgB,OAAyC;AACxD,UAAM,KAAK,OAAO,UAAU,WAAW,QAAQ,OAAO,MAAM;AAC5D,QAAI,OAAO,KAAK,kBAAkB,EAAG,QAAO;AAC5C,SAAK;AAAA,MACJ,MAAM;AACL,aAAK,uBAAuB,EAAE,gBAAgB,GAAG,CAAC;AAAA,MACnD;AAAA,MACA,EAAE,SAAS,SAAS;AAAA,IACrB;AACA,WAAO;AAAA,EACR;AAAA,EASU,qBAAqB;AAC9B,WAAO,KAAK,oBAAoB,EAAE;AAAA,EACnC;AAAA,EAMU,kBAAkB;AAC3B,UAAM,kBAAkB,KAAK,mBAAmB;AAChD,eAAO,sBAAQ,gBAAgB,IAAI,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC,CAAC;AAAA,EAC9D;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAeA,iBAAiB,QAAuC;AACvD,UAAM,MACL,OAAO,OAAO,CAAC,MAAM,WACjB,SACA,OAAqB,IAAI,CAAC,UAAU,MAAM,EAAE;AAEjD,SAAK;AAAA,MACJ,MAAM;AACL,aAAK,wBAAwB,EAAE,qBAAiB,qBAAO,GAAG,EAAE,CAAC;AAAA,MAC9D;AAAA,MACA,EAAE,SAAS,SAAS;AAAA,IACrB;AACA,WAAO;AAAA,EACR;AAAA,EASU,qBAAqB;AAC9B,WAAO,KAAK,oBAAoB,EAAE;AAAA,EACnC;AAAA,EAOU,mBAAmB;AAC5B,UAAM,kBAAkB,KAAK,mBAAmB;AAChD,eAAO,sBAAQ,gBAAgB,IAAI,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC,CAAC;AAAA,EAC9D;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAeA,iBAAiB,QAAuC;AACvD,UAAM,MACL,OAAO,OAAO,CAAC,MAAM,WACjB,SACA,OAAqB,IAAI,CAAC,UAAU,MAAM,EAAE;AACjD,QAAI,KAAK;AACT,UAAM,kBAAkB,KAAK,mBAAmB;AAChD,SAAK;AAAA,MACJ,MAAM;AACL,YAAI,IAAI,WAAW,gBAAgB,QAAQ;AAI1C,mBAAS,IAAI,GAAG,IAAI,IAAI,QAAQ,KAAK;AACpC,gBAAI,IAAI,CAAC,MAAM,gBAAgB,CAAC,GAAG;AAClC,mBAAK,wBAAwB,EAAE,iBAAiB,IAAI,CAAC;AACrD;AAAA,YACD;AAAA,UACD;AAAA,QACD,OAAO;AAEN,eAAK,wBAAwB,EAAE,iBAAiB,IAAI,CAAC;AAAA,QACtD;AAAA,MACD;AAAA,MACA,EAAE,SAAS,SAAS;AAAA,IACrB;AAEA,WAAO;AAAA,EACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,qBAAqB;AACpB,WAAO,KAAK,oBAAoB,EAAE;AAAA,EACnC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAgBA,iBAAiB,OAAyC;AACzD,UAAM,KAAK,OAAO,UAAU,WAAW,QAAQ,OAAO,MAAM;AAC5D,QAAI,OAAO,KAAK,mBAAmB,GAAG;AACrC,WAAK;AAAA,QACJ,MAAM;AACL,cAAI,CAAC,IAAI;AACR,iBAAK,uBAAuB,EAAE,iBAAiB,KAAK,CAAC;AAAA,UACtD,OAAO;AACN,kBAAMA,SAAQ,KAAK,SAAS,EAAE;AAC9B,kBAAM,OAAO,KAAK,aAAaA,MAAK;AACpC,gBAAIA,UAAS,KAAK,QAAQA,MAAK,GAAG;AACjC,mBAAK,uBAAuB,EAAE,iBAAiB,GAAG,CAAC;AAAA,YACpD;AAAA,UACD;AAAA,QACD;AAAA,QACA,EAAE,SAAS,SAAS;AAAA,MACrB;AAAA,IACD;AACA,WAAO;AAAA,EACR;AAAA,EAMQ,sBAAsB;AAC7B,WAAO,iCAAiB,SAAS,KAAK,iBAAiB,CAAC;AAAA,EACzD;AAAA,EAOU,YAAsB;AAC/B,UAAM,aAAa,KAAK,MAAM,IAAI,KAAK,oBAAoB,CAAC;AAC5D,QAAI,KAAK,yBAAyB,IAAI,GAAG;AACxC,YAAM,kBAAkB,KAAK,sBAAsB;AACnD,UAAI,iBAAiB;AACpB,eAAO,EAAE,GAAG,YAAY,GAAG,gBAAgB;AAAA,MAC5C;AAAA,IACD;AACA,WAAO;AAAA,EACR;AAAA,EAGQ,oCAAgD;AACvD,UAAM,kBAAkB,KAAK,iBAAiB,EAAE;AAChD,QAAI,CAAC,gBAAiB,QAAO;AAC7B,UAAM,iBAAiB,KAAK,iBAAiB,EAAE,KAAK,CAAC,MAAM,EAAE,WAAW,eAAe;AACvF,QAAI,CAAC,eAAgB,QAAO;AAI5B,UAAM,EAAE,GAAG,IAAI,GAAG,GAAG,IAAI,eAAe;AACxC,UAAM,EAAE,GAAG,IAAI,GAAG,IAAI,GAAG,GAAG,IAAI,eAAe;AAC/C,UAAM,gBAAgB,IAAI,eAAI,CAAC,IAAI,CAAC,IAAI,KAAK,IAAI,KAAK,EAAE;AAGxD,UAAM,cAAc,KAAK,wBAAwB,EAAE,MAAM;AACzD,UAAM,iBAAiB,YAAY,QAAQ,YAAY;AAEvD,gBAAY,QAAQ,cAAc;AAClC,gBAAY,SAAS,YAAY,QAAQ;AACzC,QAAI,YAAY,SAAS,cAAc,QAAQ;AAC9C,kBAAY,SAAS,cAAc;AACnC,kBAAY,QAAQ,YAAY,SAAS;AAAA,IAC1C;AAEA,gBAAY,SAAS,cAAc;AACnC,WAAO;AAAA,EACR;AAAA,EAGQ,wBAAoE;AAC3E,UAAM,WAAW,KAAK,kCAAkC;AACxD,QAAI,CAAC,SAAU,QAAO;AAEtB,WAAO;AAAA,MACN,GAAG,CAAC,SAAS;AAAA,MACb,GAAG,CAAC,SAAS;AAAA,MACb,GAAG,KAAK,wBAAwB,EAAE,IAAI,SAAS;AAAA,IAChD;AAAA,EACD;AAAA,EAOU,eAAe;AACxB,WAAO,KAAK,UAAU,EAAE;AAAA,EACzB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,iBAAiB;AAChB,UAAM,gBAAgB,KAAK,iBAAiB;AAE5C,QAAI,CAAC,cAAc,YAAa,QAAO;AAGvC,QAAI,cAAc,YAAY,gBAAgB,UAAW,QAAO;AAEhE,UAAM,EAAE,IAAI,GAAG,IAAI,kBAAkB,MAAM,aAAa;AAExD,YAAQ,cAAc,YAAY,aAAa;AAAA,MAC9C,KAAK,WAAW;AACf,eAAO,KAAK,IAAI,IAAI,EAAE;AAAA,MACvB;AAAA,MACA,KAAK,WAAW;AACf,eAAO,KAAK,IAAI,IAAI,EAAE;AAAA,MACvB;AAAA,MACA,KAAK,SAAS;AACb,eAAO;AAAA,MACR;AAAA,MACA,KAAK,SAAS;AACb,eAAO;AAAA,MACR;AAAA,MACA,KAAK,eAAe;AACnB,eAAO,KAAK,IAAI,GAAG,KAAK,IAAI,IAAI,EAAE,CAAC;AAAA,MACpC;AAAA,MACA,KAAK,eAAe;AACnB,eAAO,KAAK,IAAI,GAAG,KAAK,IAAI,IAAI,EAAE,CAAC;AAAA,MACpC;AAAA,MACA,KAAK,aAAa;AACjB,eAAO,KAAK,IAAI,GAAG,EAAE;AAAA,MACtB;AAAA,MACA,KAAK,aAAa;AACjB,eAAO,KAAK,IAAI,GAAG,EAAE;AAAA,MACtB;AAAA,MACA,SAAS;AACR,kBAAM,oCAAsB,cAAc,YAAY,WAAW;AAAA,MAClE;AAAA,IACD;AAAA,EACD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,cAAc;AACb,UAAM,gBAAgB,KAAK,iBAAiB;AAE5C,QAAI,CAAC,cAAc,YAAa,QAAO;AAGvC,QAAI,cAAc,YAAY,aAAa,UAAW,QAAO;AAE7D,UAAM,EAAE,IAAI,GAAG,IAAI,kBAAkB,MAAM,aAAa;AAExD,YAAQ,cAAc,YAAY,UAAU;AAAA,MAC3C,KAAK,WAAW;AACf,eAAO,KAAK,IAAI,IAAI,EAAE;AAAA,MACvB;AAAA,MACA,KAAK,WAAW;AACf,eAAO,KAAK,IAAI,IAAI,EAAE;AAAA,MACvB;AAAA,MACA,KAAK,SAAS;AACb,eAAO;AAAA,MACR;AAAA,MACA,KAAK,SAAS;AACb,eAAO;AAAA,MACR;AAAA,MACA,KAAK,eAAe;AACnB,eAAO,KAAK,IAAI,GAAG,KAAK,IAAI,IAAI,EAAE,CAAC;AAAA,MACpC;AAAA,MACA,KAAK,eAAe;AACnB,eAAO,KAAK,IAAI,GAAG,KAAK,IAAI,IAAI,EAAE,CAAC;AAAA,MACpC;AAAA,MACA,KAAK,aAAa;AACjB,eAAO,KAAK,IAAI,GAAG,EAAE;AAAA,MACtB;AAAA,MACA,KAAK,aAAa;AACjB,eAAO,KAAK,IAAI,GAAG,EAAE;AAAA,MACtB;AAAA,MACA,SAAS;AACR,kBAAM,oCAAsB,cAAc,YAAY,QAAQ;AAAA,MAC/D;AAAA,IACD;AAAA,EACD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaA,mBAAmB;AAClB,WAAO,KAAK,eAAe,IAAI;AAAA,EAChC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcA,iBAAiB,SAAmC;AACnD,UAAM,WAAO,8BAAgB;AAAA,MAC5B,GAAG,KAAK,eAAe,4BAA4B;AAAA,MACnD,GAAG;AAAA,IACJ,CAAC;AACD,QAAI,KAAK,WAAW,SAAS,EAAG,MAAK,YAAY,CAAC,CAAC;AACnD,SAAK,eAAe,IAAI,IAAI;AAC5B,WAAO;AAAA,EACR;AAAA;AAAA,EAGQ,qBACP,OACA,MAKC;AACD,UAAM,gBAAgB,KAAK,UAAU;AAErC,QAAI,EAAE,GAAG,GAAG,IAAI,cAAc,EAAE,IAAI;AAKpC,QAAI,CAAC,MAAM,OAAO;AAGjB,YAAM,gBAAgB,KAAK,iBAAiB;AAE5C,YAAM,UAAU,cAAc,UAAU,CAAC;AACzC,YAAM,cAAU,mBAAK,cAAc,SAAS;AAE5C,YAAM,MAAM,KAAK,wBAAwB;AAGzC,UAAI,cAAc,aAAa;AAC9B,cAAM,EAAE,YAAY,IAAI;AAGxB,cAAM,KAAK,KAAK,IAAI,YAAY,QAAQ,GAAG,IAAI,IAAI,CAAC;AACpD,cAAM,KAAK,KAAK,IAAI,YAAY,QAAQ,GAAG,IAAI,IAAI,CAAC;AAGpD,cAAM,SAAS,eAAI,KAAK,cAAc,YAAY,MAAM;AAQxD,cAAM,MAAM,IAAI,IAAI,KAAK,KAAK,OAAO;AACrC,cAAM,MAAM,IAAI,IAAI,KAAK,KAAK,OAAO;AAErC,cAAM,WAAW,KAAK,YAAY;AAClC,cAAM,OAAO,UAAU;AACvB,cAAM,OAAO,UAAU;AAEvB,YAAI,MAAM,OAAO;AAChB,cAAI,KAAK,eAAe;AAAA,QACzB;AAEA,YAAI,IAAI,QAAQ,IAAI,MAAM;AAIzB,gBAAM,EAAE,GAAG,IAAI,GAAG,IAAI,GAAG,GAAG,IAAI;AAChC,gBAAM,MAAM,CAAC,KAAK,IAAI,IAAI,KAAK;AAC/B,gBAAM,MAAM,CAAC,KAAK,IAAI,IAAI,KAAK;AAC/B,kBAAI,qBAAM,GAAG,MAAM,IAAI;AACvB,gBAAM,MAAM,CAAC,KAAK,IAAI,IAAI,IAAI;AAC9B,gBAAM,MAAM,CAAC,KAAK,IAAI,IAAI,IAAI;AAC9B,cAAI,KAAK,MAAM;AACf,cAAI,KAAK,MAAM;AAAA,QAChB;AAGA,cAAM,OAAO,KAAK,IAAI,OAAO;AAC7B,cAAM,OAAO,KAAK,IAAI,OAAO;AAC7B,cAAM,SAAS,IAAI,IAAI,KAAK,KAAK,IAAI,OAAO;AAC5C,cAAM,SAAS,IAAI,IAAI,KAAK,KAAK,IAAI,OAAO;AAC5C,cAAM,UAAU,OAAO,QAAQ,YAAY,OAAO;AAClD,cAAM,UAAU,OAAO,QAAQ,YAAY,OAAO;AAElD,cAAM,YACL,OAAO,YAAY,aAAa,WAAW,YAAY,WAAW,YAAY,SAAS;AACxF,cAAM,YACL,OAAO,YAAY,aAAa,WAAW,YAAY,WAAW,YAAY,SAAS;AAIxF,YAAI,MAAM,OAAO;AAEhB,cAAI;AACJ,cAAI;AAAA,QACL,OAAO;AAEN,kBAAQ,WAAW;AAAA,YAClB,KAAK,SAAS;AAEb,kBAAI;AACJ;AAAA,YACD;AAAA,YACA,KAAK,WAAW;AAEf,kBAAI,IAAI,GAAI,KAAI;AAAA,kBAEX,SAAI,qBAAM,GAAG,OAAO,OAAO,IAAI;AACpC;AAAA,YACD;AAAA,YACA,KAAK,UAAU;AAEd,kBAAI,IAAI,GAAI,SAAI,qBAAM,GAAG,OAAO,IAAI,IAAI,MAAM,IAAI,OAAO,CAAC;AAAA,kBAErD,SAAI,qBAAM,GAAG,OAAO,OAAO,IAAI;AACpC;AAAA,YACD;AAAA,YACA,KAAK,WAAW;AAEf,sBAAI,qBAAM,GAAG,KAAK,IAAI,OAAO,IAAI,IAAI,IAAI,MAAM,CAAC;AAChD;AAAA,YACD;AAAA,YACA,KAAK,QAAQ;AAEZ;AAAA,YACD;AAAA,YACA,SAAS;AACR,wBAAM,oCAAsB,SAAS;AAAA,YACtC;AAAA,UACD;AAIA,kBAAQ,WAAW;AAAA,YAClB,KAAK,SAAS;AACb,kBAAI;AACJ;AAAA,YACD;AAAA,YACA,KAAK,WAAW;AACf,kBAAI,IAAI,GAAI,KAAI;AAAA,kBACX,SAAI,qBAAM,GAAG,OAAO,OAAO,IAAI;AACpC;AAAA,YACD;AAAA,YACA,KAAK,UAAU;AACd,kBAAI,IAAI,GAAI,SAAI,qBAAM,GAAG,OAAO,IAAI,IAAI,MAAM,IAAI,OAAO,CAAC;AAAA,kBACrD,SAAI,qBAAM,GAAG,OAAO,OAAO,IAAI;AACpC;AAAA,YACD;AAAA,YACA,KAAK,WAAW;AACf,sBAAI,qBAAM,GAAG,KAAK,IAAI,OAAO,IAAI,IAAI,IAAI,MAAM,CAAC;AAChD;AAAA,YACD;AAAA,YACA,KAAK,QAAQ;AAEZ;AAAA,YACD;AAAA,YACA,SAAS;AACR,wBAAM,oCAAsB,SAAS;AAAA,YACtC;AAAA,UACD;AAAA,QACD;AAAA,MACD,OAAO;AAEN,YAAI,IAAI,WAAW,IAAI,SAAS;AAC/B,gBAAM,EAAE,GAAG,IAAI,GAAG,IAAI,GAAG,GAAG,IAAI;AAChC,kBAAI,qBAAM,GAAG,SAAS,OAAO;AAC7B,cAAI,MAAM,CAAC,KAAK,IAAI,IAAI,IAAI,MAAM,CAAC,KAAK,IAAI,IAAI,KAAK;AACrD,cAAI,MAAM,CAAC,KAAK,IAAI,IAAI,IAAI,MAAM,CAAC,KAAK,IAAI,IAAI,KAAK;AAAA,QACtD;AAAA,MACD;AAAA,IACD;AAEA,WAAO,EAAE,GAAG,GAAG,EAAE;AAAA,EAClB;AAAA;AAAA,EAGQ,WAAW,OAAgB,MAAkC;AACpE,UAAM,gBAAgB,KAAK,UAAU;AAErC,UAAM,EAAE,GAAG,GAAG,EAAE,IAAI,KAAK,qBAAqB,OAAO,IAAI;AAEzD,QAAI,cAAc,MAAM,KAAK,cAAc,MAAM,KAAK,cAAc,MAAM,GAAG;AAC5E,aAAO;AAAA,IACR;AAEA,+BAAS,MAAM;AACd,YAAM,SAAS,EAAE,GAAG,eAAe,GAAG,GAAG,EAAE;AAC3C,WAAK;AAAA,QACJ,MAAM;AACL,eAAK,MAAM,IAAI,CAAC,MAAM,CAAC;AAAA,QACxB;AAAA,QACA,EAAE,SAAS,SAAS;AAAA,MACrB;AAIA,YAAM,EAAE,oBAAoB,iBAAiB,IAAI,KAAK;AACtD,YAAM,EAAE,aAAa,IAAI,KAAK,MAAM,wBAAwB,6BAAa;AAGzE,UACC,mBAAmB,IAAI,IAAI,MAAM,iBAAiB,KAClD,mBAAmB,IAAI,IAAI,MAAM,iBAAiB,GACjD;AAED,cAAM,QAA4B;AAAA,UACjC,MAAM;AAAA,UACN,QAAQ;AAAA,UACR,MAAM;AAAA;AAAA,UAEN,OAAO,eAAI,MAAM,oBAAoB,aAAa,GAAG,aAAa,CAAC;AAAA,UACnE,WAAW,sCAAqB;AAAA,UAChC,SAAS,KAAK,OAAO;AAAA,UACrB,QAAQ,KAAK,OAAO;AAAA,UACpB,UAAU,KAAK,OAAO;AAAA,UACtB,QAAQ;AAAA,UACR,OAAO,KAAK,iBAAiB,EAAE,aAAa;AAAA,QAC7C;AAEA,YAAI,MAAM,WAAW;AACpB,eAAK,mBAAmB,KAAK;AAAA,QAC9B,OAAO;AACN,eAAK,SAAS,KAAK;AAAA,QACpB;AAAA,MACD;AAEA,WAAK,iBAAiB;AAAA,IACvB,CAAC;AAED,WAAO;AAAA,EACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAiBA,UAAU,OAAgB,MAAkC;AAC3D,UAAM,EAAE,SAAS,IAAI,KAAK,eAAe,4BAA4B;AACrE,QAAI,YAAY,CAAC,MAAM,MAAO,QAAO;AAGrC,SAAK,oBAAoB;AAGzB,QAAI,KAAK,iBAAiB,EAAE,iBAAiB;AAC5C,WAAK,kBAAkB;AAAA,IACxB;AAEA,UAAM,SAAS,eAAI,KAAK,KAAK;AAE7B,QAAI,CAAC,OAAO,SAAS,OAAO,CAAC,EAAG,QAAO,IAAI;AAC3C,QAAI,CAAC,OAAO,SAAS,OAAO,CAAC,EAAG,QAAO,IAAI;AAC3C,QAAI,OAAO,MAAM,UAAa,CAAC,OAAO,SAAS,OAAO,CAAC,EAAG,OAAM,IAAI,KAAK,aAAa;AAEtF,UAAM,SAAS,KAAK,qBAAqB,QAAQ,IAAI;AAErD,QAAI,MAAM,WAAW;AACpB,YAAM,EAAE,OAAO,OAAO,IAAI,KAAK,wBAAwB;AACvD,WAAK;AAAA,QACJ,IAAI,eAAI,CAAC,OAAO,GAAG,CAAC,OAAO,GAAG,QAAQ,OAAO,GAAG,SAAS,OAAO,CAAC;AAAA,QACjE;AAAA,MACD;AAAA,IACD,OAAO;AACN,WAAK,WAAW,QAAQ;AAAA,QACvB,GAAG;AAAA;AAAA,QAEH,OAAO;AAAA,MACR,CAAC;AAAA,IACF;AAEA,WAAO;AAAA,EACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAgBA,cAAc,OAAgB,MAAkC;AAC/D,UAAM,EAAE,SAAS,IAAI,KAAK,iBAAiB;AAC3C,QAAI,YAAY,CAAC,MAAM,MAAO,QAAO;AAErC,UAAM,EAAE,OAAO,IAAI,QAAQ,GAAG,IAAI,KAAK,sBAAsB;AAC7D,SAAK,UAAU,IAAI,eAAI,EAAE,MAAM,IAAI,KAAK,IAAI,EAAE,MAAM,IAAI,KAAK,IAAI,KAAK,UAAU,EAAE,CAAC,GAAG,IAAI;AAC1F,WAAO;AAAA,EACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAeA,UAAU,MAAkC;AAC3C,UAAM,MAAM,CAAC,GAAG,KAAK,uBAAuB,CAAC;AAC7C,QAAI,IAAI,UAAU,EAAG,QAAO;AAC5B,UAAM,aAAa,eAAI,WAAO,sBAAQ,IAAI,IAAI,CAAC,OAAO,KAAK,mBAAmB,EAAE,CAAC,CAAC,CAAC;AACnF,SAAK,aAAa,YAAY,IAAI;AAClC,WAAO;AAAA,EACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAiBA,UAAU,QAAQ,KAAK,wBAAwB,GAAG,MAAkC;AACnF,UAAM,EAAE,UAAU,YAAyB,IAAI,KAAK,iBAAiB;AACrE,QAAI,YAAY,CAAC,MAAM,MAAO,QAAO;AAErC,UAAM,gBAAgB,KAAK,UAAU;AACrC,UAAM,EAAE,GAAG,IAAI,GAAG,IAAI,GAAG,GAAG,IAAI;AAChC,UAAM,EAAE,GAAG,EAAE,IAAI;AAEjB,QAAI,IAAI;AAER,QAAI,aAAa;AAGhB,YAAM,cAAc,KAAK,eAAe;AACxC,UAAI,OAAO,aAAa;AACvB,YAAI;AAAA,MACL;AAAA,IACD;AAEA,SAAK;AAAA,MACJ,IAAI,eAAI,MAAM,IAAI,IAAI,MAAM,IAAI,KAAK,IAAI,MAAM,IAAI,IAAI,MAAM,IAAI,KAAK,IAAI,CAAC;AAAA,MAC3E;AAAA,IACD;AACA,WAAO;AAAA,EACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAiBA,OAAO,QAAQ,KAAK,wBAAwB,GAAG,MAAkC;AAChF,UAAM,EAAE,SAAS,IAAI,KAAK,iBAAiB;AAC3C,QAAI,YAAY,CAAC,MAAM,MAAO,QAAO;AAErC,UAAM,EAAE,GAAG,IAAI,GAAG,IAAI,GAAG,GAAG,IAAI,KAAK,UAAU;AAE/C,UAAM,EAAE,UAAU,IAAI,KAAK,iBAAiB;AAC5C,QAAI,cAAc,QAAQ,UAAU,SAAS,GAAG;AAC/C,YAAM,WAAW,KAAK,YAAY;AAClC,UAAI,WAAO,mBAAK,SAAS,IAAK;AAC9B,eAAS,IAAI,GAAG,IAAI,UAAU,QAAQ,KAAK;AAC1C,cAAM,KAAK,UAAU,IAAI,CAAC,IAAI;AAC9B,cAAM,KAAK,UAAU,CAAC,IAAI;AAC1B,YAAI,KAAK,OAAO,KAAK,MAAM,EAAG;AAC9B,eAAO;AACP;AAAA,MACD;AACA,WAAK;AAAA,QACJ,IAAI;AAAA,UACH,MAAM,MAAM,IAAI,OAAO,MAAM,MAAM,MAAM,IAAI,KAAK,MAAM;AAAA,UACxD,MAAM,MAAM,IAAI,OAAO,MAAM,MAAM,MAAM,IAAI,KAAK,MAAM;AAAA,UACxD;AAAA,QACD;AAAA,QACA;AAAA,MACD;AAAA,IACD;AAEA,WAAO;AAAA,EACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAiBA,QAAQ,QAAQ,KAAK,wBAAwB,GAAG,MAAkC;AACjF,UAAM,EAAE,SAAS,IAAI,KAAK,iBAAiB;AAC3C,QAAI,YAAY,CAAC,MAAM,MAAO,QAAO;AAErC,UAAM,EAAE,UAAU,IAAI,KAAK,iBAAiB;AAC5C,QAAI,cAAc,QAAQ,UAAU,SAAS,GAAG;AAC/C,YAAM,WAAW,KAAK,YAAY;AAClC,YAAM,EAAE,GAAG,IAAI,GAAG,IAAI,GAAG,GAAG,IAAI,KAAK,UAAU;AAE/C,UAAI,OAAO,UAAU,CAAC,IAAI;AAC1B,eAAS,IAAI,UAAU,SAAS,GAAG,IAAI,GAAG,KAAK;AAC9C,cAAM,KAAK,UAAU,IAAI,CAAC,IAAI;AAC9B,cAAM,KAAK,UAAU,CAAC,IAAI;AAC1B,YAAI,KAAK,OAAO,KAAK,MAAM,EAAG;AAC9B,eAAO;AACP;AAAA,MACD;AACA,WAAK;AAAA,QACJ,IAAI;AAAA,UACH,MAAM,MAAM,IAAI,OAAO,MAAM,MAAM,MAAM,IAAI,KAAK,MAAM;AAAA,UACxD,MAAM,MAAM,IAAI,OAAO,MAAM,MAAM,MAAM,IAAI,KAAK,MAAM;AAAA,UACxD;AAAA,QACD;AAAA,QACA;AAAA,MACD;AAAA,IACD;AAEA,WAAO;AAAA,EACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAeA,gBAAgB,MAAkC;AACjD,UAAM,EAAE,SAAS,IAAI,KAAK,iBAAiB;AAC3C,QAAI,YAAY,CAAC,MAAM,MAAO,QAAO;AAErC,UAAM,sBAAsB,KAAK,uBAAuB;AACxD,QAAI,qBAAqB;AACxB,WAAK,aAAa,qBAAqB;AAAA,QACtC,YAAY,KAAK,IAAI,GAAG,KAAK,aAAa,CAAC;AAAA,QAC3C,GAAG;AAAA,MACJ,CAAC;AAAA,IACF;AACA,WAAO;AAAA,EACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAiBA,aACC,QACA,MACO;AACP,UAAM,gBAAgB,KAAK,eAAe,4BAA4B;AACtE,QAAI,cAAc,YAAY,CAAC,MAAM,MAAO,QAAO;AAEnD,UAAM,uBAAuB,KAAK,wBAAwB;AAE1D,UAAM,QAAQ,MAAM,SAAS,KAAK,IAAI,sCAAqB,qBAAqB,QAAQ,IAAI;AAE5F,UAAM,WAAW,KAAK,YAAY;AAClC,UAAM,UAAU,cAAc,UAAU,CAAC;AACzC,UAAM,cAAU,mBAAK,cAAc,SAAS;AAE5C,QAAI,WAAO;AAAA,MACV,KAAK;AAAA,SACH,qBAAqB,QAAQ,SAAS,OAAO;AAAA,SAC7C,qBAAqB,SAAS,SAAS,OAAO;AAAA,MAChD;AAAA,MACA,UAAU;AAAA,MACV,UAAU;AAAA,IACX;AAEA,QAAI,MAAM,eAAe,QAAW;AACnC,aAAO,KAAK,IAAI,KAAK,YAAY,IAAI;AAAA,IACtC;AAEA,SAAK;AAAA,MACJ,IAAI;AAAA,QACH,CAAC,OAAO,KAAK,qBAAqB,QAAQ,OAAO,IAAI,QAAQ,IAAI;AAAA,QACjE,CAAC,OAAO,KAAK,qBAAqB,SAAS,OAAO,IAAI,QAAQ,IAAI;AAAA,QAClE;AAAA,MACD;AAAA,MACA;AAAA,IACD;AAEA,WAAO;AAAA,EACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,sBAA4B;AAC3B,SAAK,KAAK,uBAAuB;AACjC,WAAO;AAAA,EACR;AAAA;AAAA,EAYQ,iBAAiB,IAAkB;AAC1C,QAAI,CAAC,KAAK,mBAAoB;AAE9B,SAAK,mBAAmB,WAAW;AAEnC,UAAM,EAAE,SAAS,QAAQ,UAAU,OAAO,IAAI,IAAI,KAAK;AAEvD,QAAI,UAAU,UAAU;AACvB,WAAK,IAAI,QAAQ,KAAK,gBAAgB;AACtC,WAAK,qBAAqB;AAC1B,WAAK,WAAW,IAAI,eAAI,CAAC,IAAI,GAAG,CAAC,IAAI,GAAG,KAAK,wBAAwB,EAAE,QAAQ,IAAI,KAAK,CAAC;AACzF;AAAA,IACD;AAEA,UAAM,YAAY,WAAW;AAC7B,UAAM,IAAI,OAAO,IAAI,YAAY,QAAQ;AAEzC,UAAM,OAAO,MAAM,QAAQ,IAAI,OAAO,MAAM,QAAQ;AACpD,UAAM,MAAM,MAAM,QAAQ,IAAI,OAAO,MAAM,QAAQ;AACnD,UAAM,QAAQ,MAAM,QAAQ,IAAI,OAAO,MAAM,QAAQ;AAErD,SAAK,WAAW,IAAI,eAAI,CAAC,MAAM,CAAC,KAAK,KAAK,wBAAwB,EAAE,SAAS,QAAQ,KAAK,GAAG;AAAA,MAC5F,OAAO;AAAA,IACR,CAAC;AAAA,EACF;AAAA;AAAA,EAGQ,mBACP,oBACA,OAAO,EAAE,WAAW,2CAA0B,GAC7C;AACD,UAAM,EAAE,WAAW,GAAG,KAAK,IAAI;AAC/B,QAAI,CAAC,UAAW;AAChB,UAAM,EAAE,WAAW,GAAG,SAAS,uBAAQ,eAAe,IAAI;AAC1D,UAAM,iBAAiB,KAAK,KAAK,kBAAkB;AACnD,UAAM,qBAAqB,KAAK,sBAAsB;AAGtD,SAAK,oBAAoB;AAGzB,QAAI,KAAK,iBAAiB,EAAE,iBAAiB;AAC5C,WAAK,kBAAkB;AAAA,IACxB;AAEA,QAAI,aAAa,KAAK,mBAAmB,GAAG;AAE3C,aAAO,KAAK;AAAA,QACX,IAAI;AAAA,UACH,CAAC,mBAAmB;AAAA,UACpB,CAAC,mBAAmB;AAAA,UACpB,KAAK,wBAAwB,EAAE,QAAQ,mBAAmB;AAAA,QAC3D;AAAA,QACA,EAAE,GAAG,KAAK;AAAA,MACX;AAAA,IACD;AAGA,SAAK,qBAAqB;AAAA,MACzB,SAAS;AAAA,MACT,UAAU,WAAW;AAAA,MACrB;AAAA,MACA,OAAO,mBAAmB,MAAM;AAAA,MAChC,KAAK,mBAAmB,MAAM;AAAA,IAC/B;AAGA,SAAK,KAAK,yBAAyB,MAAM;AACxC,WAAK,IAAI,QAAQ,KAAK,gBAAgB;AACtC,WAAK,qBAAqB;AAAA,IAC3B,CAAC;AAGD,SAAK,GAAG,QAAQ,KAAK,gBAAgB;AAErC,WAAO;AAAA,EACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaA,YACC,OAAO,CAAC,GAOD;AACP,UAAM,EAAE,SAAS,IAAI,KAAK,iBAAiB;AAC3C,QAAI,YAAY,CAAC,MAAM,MAAO,QAAO;AAErC,UAAM,iBAAiB,KAAK,KAAK,kBAAkB;AACnD,QAAI,mBAAmB,EAAG,QAAO;AAEjC,SAAK,oBAAoB;AAEzB,UAAM;AAAA,MACL;AAAA,MACA,WAAW,KAAK,QAAQ;AAAA,MACxB;AAAA,MACA,iBAAiB;AAAA,IAClB,IAAI;AACJ,QAAI,eAAe,KAAK,IAAI,OAAO,CAAC;AAEpC,UAAM,SAAS,MAAM;AACpB,WAAK,IAAI,QAAQ,UAAU;AAC3B,WAAK,IAAI,yBAAyB,MAAM;AAAA,IACzC;AAEA,SAAK,KAAK,yBAAyB,MAAM;AAEzC,UAAM,aAAa,CAAC,YAAoB;AACvC,YAAM,EAAE,GAAG,IAAI,GAAG,IAAI,GAAG,GAAG,IAAI,KAAK,UAAU;AAC/C,YAAM,cAAc,eAAI,IAAI,WAAY,eAAe,UAAW,EAAE;AAGpE,sBAAgB,IAAI;AACpB,UAAI,eAAe,gBAAgB;AAClC,eAAO;AAAA,MACR,OAAO;AACN,aAAK,WAAW,IAAI,eAAI,KAAK,YAAY,GAAG,KAAK,YAAY,GAAG,EAAE,CAAC;AAAA,MACpE;AAAA,IACD;AAEA,SAAK,GAAG,QAAQ,UAAU;AAE1B,WAAO;AAAA,EACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAeA,WAAW,QAAgB,OAA4B,EAAE,WAAW,EAAE,UAAU,IAAI,EAAE,GAAS;AAC9F,UAAM,WAAW,KAAK,iBAAiB,EAAE,KAAK,CAAC,MAAM,EAAE,WAAW,MAAM;AAExE,QAAI,CAAC,SAAU,QAAO;AAEtB,SAAK,IAAI,MAAM;AAEd,UAAI,KAAK,iBAAiB,EAAE,oBAAoB,MAAM;AACrD,aAAK,kBAAkB;AAAA,MACxB;AAGA,YAAM,eAAe,SAAS,kBAAkB,KAAK,iBAAiB;AACtE,UAAI,CAAC,cAAc;AAClB,aAAK,eAAe,SAAS,aAAa;AAAA,MAC3C;AAGA,UAAI,QAAQ,KAAK,aAAa,CAAC,cAAc;AAC5C,aAAK,YAAY;AAAA,MAClB;AAEA,WAAK,cAAc,SAAS,QAAQ,IAAI;AAGxC,YAAM,EAAE,mBAAmB,IAAI,KAAK,iBAAiB;AACrD,WAAK,oBAAoB,EAAE,oBAAoB,CAAC,GAAG,oBAAoB,MAAM,EAAE,CAAC;AAGhF,WAAK,OAAO,WAAW,MAAM;AAC5B,cAAMC,sBAAqB,CAAC,GAAG,KAAK,iBAAiB,EAAE,kBAAkB;AACzE,cAAM,QAAQA,oBAAmB,QAAQ,MAAM;AAC/C,YAAI,QAAQ,EAAG;AACf,QAAAA,oBAAmB,OAAO,OAAO,CAAC;AAClC,aAAK,oBAAoB,EAAE,oBAAAA,oBAAmB,CAAC;AAAA,MAChD,GAAG,KAAK,QAAQ,yBAAyB;AAAA,IAC1C,CAAC;AAED,WAAO;AAAA,EACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAqBA,2BAA2B,cAAiC,SAAS,OAAa;AACjF,QAAI,wBAAwB,aAAa;AACxC,YAAM,OAAO,aAAa,sBAAsB;AAChD,qBAAe,IAAI;AAAA,QAClB,KAAK,QAAQ,KAAK;AAAA,QAClB,KAAK,OAAO,KAAK;AAAA,QACjB,KAAK,IAAI,KAAK,OAAO,CAAC;AAAA,QACtB,KAAK,IAAI,KAAK,QAAQ,CAAC;AAAA,MACxB;AAAA,IACD,OAAO;AACN,mBAAa,QAAQ,KAAK,IAAI,aAAa,OAAO,CAAC;AACnD,mBAAa,SAAS,KAAK,IAAI,aAAa,QAAQ,CAAC;AAAA,IACtD;AAEA,UAAM,SAAS;AAAA;AAAA,MAEd,aAAa,SAAS;AAAA;AAAA,MAEtB,KAAC,6BAAc,SAAS,KAAK,aAAa,aAAa,MAAM,CAAC;AAAA;AAAA,MAE9D,KAAC,6BAAc,SAAS,KAAK,cAAc,aAAa,MAAM,CAAC;AAAA;AAAA,MAE/D,aAAa,SAAS;AAAA,IACvB;AAEA,UAAM,EAAE,sBAAsB,IAAI;AAElC,SAAK,wBAAwB;AAE7B,UAAM,EAAE,cAAc,kBAAkB,QAAQ,WAAW,IAAI,KAAK,iBAAiB;AACrF,QAAI,aAAa,OAAO,gBAAgB,KAAK,OAAO,MAAM,CAAC,GAAG,MAAM,MAAM,WAAW,CAAC,CAAC,GAAG;AAEzF,aAAO;AAAA,IACR;AAEA,QAAI,uBAAuB;AAE1B,WAAK,oBAAoB,EAAE,cAAc,aAAa,OAAO,GAAG,OAAO,CAAC;AACxE,WAAK,UAAU,KAAK,UAAU,CAAC;AAAA,IAChC,OAAO;AACN,UAAI,UAAU,CAAC,KAAK,iBAAiB,EAAE,iBAAiB;AAEvD,cAAM,SAAS,KAAK,sBAAsB,EAAE;AAC5C,aAAK,oBAAoB,EAAE,cAAc,aAAa,OAAO,GAAG,OAAO,CAAC;AACxE,aAAK,cAAc,MAAM;AAAA,MAC1B,OAAO;AAEN,aAAK,oBAAoB,EAAE,cAAc,aAAa,OAAO,GAAG,OAAO,CAAC;AACxE,aAAK,WAAW,eAAI,KAAK,EAAE,GAAG,KAAK,UAAU,EAAE,CAAC,CAAC;AAAA,MAClD;AAAA,IACD;AAEA,SAAK,iBAAiB;AAEtB,WAAO;AAAA,EACR;AAAA,EAOU,0BAA0B;AACnC,UAAM,EAAE,GAAG,GAAG,GAAG,EAAE,IAAI,KAAK,iBAAiB,EAAE;AAC/C,WAAO,IAAI,eAAI,GAAG,GAAG,GAAG,CAAC;AAAA,EAC1B;AAAA,EAOU,0BAA0B;AACnC,UAAM,uBAAuB,KAAK,wBAAwB;AAC1D,WAAO,IAAI;AAAA,MACV,qBAAqB,OAAO,qBAAqB;AAAA,MACjD,qBAAqB,OAAO,qBAAqB;AAAA,IAClD;AAAA,EACD;AAAA,EAOU,wBAAwB;AACjC,UAAM,EAAE,GAAG,EAAE,IAAI,KAAK,wBAAwB;AAC9C,UAAM,EAAE,GAAG,IAAI,GAAG,IAAI,GAAG,GAAG,IAAI,KAAK,UAAU;AAC/C,WAAO,IAAI,eAAI,CAAC,IAAI,CAAC,IAAI,IAAI,IAAI,IAAI,EAAE;AAAA,EACxC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcA,aAAa,OAAgB;AAC5B,UAAM,EAAE,aAAa,IAAI,KAAK,MAAM,wBAAwB,6BAAa;AACzE,UAAM,EAAE,GAAG,IAAI,GAAG,IAAI,GAAG,KAAK,EAAE,IAAI,KAAK,UAAU;AACnD,WAAO,IAAI;AAAA,OACT,MAAM,IAAI,aAAa,KAAK,KAAK;AAAA,OACjC,MAAM,IAAI,aAAa,KAAK,KAAK;AAAA,MAClC,MAAM,KAAK;AAAA,IACZ;AAAA,EACD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcA,aAAa,OAAgB;AAC5B,UAAM,EAAE,aAAa,IAAI,KAAK,MAAM,wBAAwB,6BAAa;AACzE,UAAM,EAAE,GAAG,IAAI,GAAG,IAAI,GAAG,KAAK,EAAE,IAAI,KAAK,UAAU;AACnD,WAAO,IAAI;AAAA,OACT,MAAM,IAAI,MAAM,KAAK,aAAa;AAAA,OAClC,MAAM,IAAI,MAAM,KAAK,aAAa;AAAA,MACnC,MAAM,KAAK;AAAA,IACZ;AAAA,EACD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcA,eAAe,OAAgB;AAC9B,UAAM,EAAE,GAAG,IAAI,GAAG,IAAI,GAAG,KAAK,EAAE,IAAI,KAAK,UAAU;AACnD,WAAO,IAAI,gBAAK,MAAM,IAAI,MAAM,KAAK,MAAM,IAAI,MAAM,IAAI,MAAM,KAAK,GAAG;AAAA,EACxE;AAAA,EAIQ,yBAAyB;AAChC,WAAO,KAAK,MAAM,MAAM,QAAQ,qBAAqB,OAAO;AAAA,MAC3D,QAAQ,EAAE,KAAK,KAAK,KAAK,MAAM,EAAE;AAAA,IAClC,EAAE;AAAA,EACH;AAAA,EASA,mBAAmB;AAClB,UAAM,qBAAqB,KAAK,uBAAuB,EAAE,IAAI;AAC7D,QAAI,CAAC,mBAAmB,OAAQ,QAAO;AACvC,UAAM,UAAU,CAAC,GAAG,IAAI,IAAI,mBAAmB,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,EAAE,KAAK;AAC3E,WAAO,QAAQ,IAAI,CAAC,OAAO;AAC1B,YAAM,iBAAiB,mBACrB,OAAO,CAAC,MAAM,EAAE,WAAW,EAAE,EAC7B,KAAK,CAAC,GAAG,MAAM,EAAE,wBAAwB,EAAE,qBAAqB,EAAE,CAAC;AACrE,aAAO;AAAA,IACR,CAAC;AAAA,EACF;AAAA,EASA,gCAAgC;AAC/B,UAAM,gBAAgB,KAAK,iBAAiB;AAC5C,WAAO,KAAK,iBAAiB,EAAE,OAAO,CAAC,MAAM,EAAE,kBAAkB,aAAa;AAAA,EAC/E;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAoBA,mBAAmB,QAAsB;AAExC,SAAK,kBAAkB;AAEvB,UAAM,kBAAkB,KAAK,uBAAuB,EAClD,IAAI,EACJ,OAAO,CAAC,MAAM,EAAE,WAAW,MAAM;AAEnC,QAAI,CAAC,gBAAgB,QAAQ;AAC5B,cAAQ,KAAK,gBAAgB;AAC7B,aAAO;AAAA,IACR;AAEA,UAAM,aAAa,KAAK,KAAK,MAAM;AAEnC,QAAI,CAAC,YAAY;AAChB,cAAQ,KAAK,4EAA4E;AAAA,IAE1F;AAGA,QAAI,gBAAgB,KAAK,CAAC,MAAM,EAAE,oBAAoB,UAAU,GAAG;AAClE,aAAO;AAAA,IACR;AAEA,UAAM,2BAAuB,uBAAS,wBAAwB,MAAM;AACnE,aAAO,KAAK,iBAAiB,EAAE,KAAK,CAAC,MAAM,EAAE,WAAW,MAAM;AAAA,IAC/D,CAAC;AAED,+BAAS,MAAM;AACd,WAAK,oBAAoB,EAAE,iBAAiB,OAAO,GAAG,EAAE,SAAS,SAAS,CAAC;AAG3E,YAAM,cAAU,oBAAM,uBAAuB,MAAM;AAClD,cAAM,iBAAiB,qBAAqB,IAAI;AAChD,YAAI,CAAC,gBAAgB;AACpB,eAAK,kBAAkB;AACvB;AAAA,QACD;AACA,YACC,eAAe,kBAAkB,KAAK,iBAAiB,KACvD,KAAK,QAAQ,eAAe,aAAa,GACxC;AAED,eAAK;AAAA,YACJ,MAAM;AAEL,mBAAK,MAAM,IAAI;AAAA,gBACd,EAAE,GAAG,KAAK,iBAAiB,GAAG,eAAe,eAAe,cAAc;AAAA,cAC3E,CAAC;AACD,mBAAK,yBAAyB,IAAI,IAAI;AAAA,YACvC;AAAA,YACA,EAAE,SAAS,SAAS;AAAA,UACrB;AAAA,QACD;AAAA,MACD,CAAC;AAED,YAAM,SAAS,MAAM;AACpB,gBAAQ;AACR,aAAK,yBAAyB,IAAI,KAAK;AACvC,aAAK,IAAI,SAAS,eAAe;AACjC,aAAK,IAAI,kBAAkB,MAAM;AAAA,MAClC;AAEA,YAAM,kBAAkB,MAAM;AAE7B,cAAM,iBAAiB,qBAAqB,IAAI;AAChD,YAAI,CAAC,gBAAgB;AACpB,eAAK,kBAAkB;AACvB;AAAA,QACD;AAEA,YAAI,KAAK,yBAAyB,IAAI,EAAG;AAEzC,cAAM,iBAAiB,KAAK,KAAK,kBAAkB;AAEnD,YAAI,mBAAmB,GAAG;AACzB,eAAK,yBAAyB,IAAI,IAAI;AACtC;AAAA,QACD;AAEA,cAAM,iBAAiB,KAAK,kCAAkC;AAC9D,YAAI,CAAC,gBAAgB;AACpB,eAAK,kBAAkB;AACvB;AAAA,QACD;AACA,cAAM,kBAAkB,KAAK,sBAAsB;AAEnD,cAAM,QACL,KAAK,IAAI,eAAe,OAAO,gBAAgB,IAAI,IACnD,KAAK,IAAI,eAAe,OAAO,gBAAgB,IAAI;AACpD,cAAM,QACL,KAAK,IAAI,eAAe,OAAO,gBAAgB,IAAI,IACnD,KAAK,IAAI,eAAe,OAAO,gBAAgB,IAAI;AAGpD,YACC,QAAQ,KAAK,QAAQ,2BACrB,QAAQ,KAAK,QAAQ,yBACpB;AACD,eAAK,yBAAyB,IAAI,IAAI;AACtC;AAAA,QACD;AAKA,cAAM,QAAI,qBAAM,iBAAiB,KAAK,KAAK,GAAG;AAE9C,cAAM,eAAe,IAAI;AAAA,cACxB,mBAAK,gBAAgB,MAAM,eAAe,MAAM,CAAC;AAAA,cACjD,mBAAK,gBAAgB,MAAM,eAAe,MAAM,CAAC;AAAA,cACjD,mBAAK,gBAAgB,OAAO,eAAe,OAAO,CAAC;AAAA,cACnD,mBAAK,gBAAgB,QAAQ,eAAe,QAAQ,CAAC;AAAA,QACtD;AAEA,cAAM,aAAa,IAAI;AAAA,UACtB,CAAC,aAAa;AAAA,UACd,CAAC,aAAa;AAAA,UACd,KAAK,wBAAwB,EAAE,QAAQ,aAAa;AAAA,QACrD;AAGA,aAAK,oBAAoB;AACzB,aAAK,WAAW,UAAU;AAAA,MAC3B;AAEA,WAAK,KAAK,kBAAkB,MAAM;AAClC,WAAK,YAAY,SAAS,eAAe;AAGzC,sBAAgB;AAAA,IACjB,CAAC;AAED,WAAO;AAAA,EACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,oBAA0B;AACzB,SAAK;AAAA,MACJ,MAAM;AAEL,aAAK,MAAM,IAAI,CAAC,KAAK,UAAU,CAAC,CAAC;AAEjC,aAAK,yBAAyB,IAAI,KAAK;AACvC,aAAK,oBAAoB,EAAE,iBAAiB,KAAK,CAAC;AAClD,aAAK,KAAK,gBAAgB;AAAA,MAC3B;AAAA,MACA,EAAE,SAAS,SAAS;AAAA,IACrB;AACA,WAAO;AAAA,EACR;AAAA;AAAA,EAGA,4BAIC,gBACqB;AAWrB,UAAM,kBAAsC,CAAC;AAE7C,QAAI,YAAY,KAAK,QAAQ,mBAAmB;AAChD,QAAI,sBAAsB,KAAK,QAAQ;AAEvC,UAAM,kBAAkB,KAAK,mBAAmB;AAEhD,UAAM,eAAe,CAAC,IAAe,SAAiB,sBAA+B;AACpF,YAAM,QAAQ,KAAK,SAAS,EAAE;AAC9B,UAAI,CAAC,MAAO;AACZ,UAAI,KAAK,cAAc,KAAK,EAAG;AAE/B,iBAAW,MAAM;AACjB,UAAI,iBAAiB;AACrB,YAAM,OAAO,KAAK,aAAa,KAAK;AAEpC,UAAI,gBAAgB;AACnB,yBAAiB,CAAC,qBAAqB,gBAAgB,SAAS,EAAE;AAClE,YAAI,gBAAgB;AACnB,qBAAW;AAAA,QACZ;AAAA,MACD;AAEA,sBAAgB,KAAK;AAAA,QACpB;AAAA,QACA;AAAA,QACA;AAAA,QACA,OAAO;AAAA,QACP,iBAAiB;AAAA,QACjB;AAAA,MACD,CAAC;AAED,mBAAa;AACb,6BAAuB;AAEvB,YAAM,WAAW,KAAK,2BAA2B,EAAE;AACnD,UAAI,CAAC,SAAS,OAAQ;AAEtB,UAAI,2BAA2B;AAC/B,UAAI,KAAK,8BAA8B,KAAK,GAAG;AAC9C,mCAA2B;AAC3B,8BAAsB;AACtB,qBAAa,KAAK,QAAQ;AAAA,MAC3B;AAEA,iBAAW,WAAW,UAAU;AAC/B,qBAAa,SAAS,SAAS,qBAAqB,cAAc;AAAA,MACnE;AAEA,UAAI,6BAA6B,MAAM;AACtC,8BAAsB;AAAA,MACvB;AAAA,IACD;AAIA,UAAM,QAAQ,iBAAiB,CAAC,KAAK,eAAe,CAAC,IAAI,KAAK,SAAS;AACvE,eAAW,QAAQ,OAAO;AACzB,iBAAW,WAAW,KAAK,2BAA2B,KAAK,EAAE,GAAG;AAC/D,qBAAa,SAAS,GAAG,KAAK;AAAA,MAC/B;AAAA,IACD;AAEA,WAAO;AAAA,EACR;AAAA,EAWA,yBAAyB,SAAiB;AACzC,SAAK,gCAAgC;AACrC,QAAI,KAAK,+BAA+B,EAAG;AAC3C,SAAK,IAAI,QAAQ,KAAK,wBAAwB;AAC9C,SAAK,aAAa,IAAI,MAAM;AAAA,EAC7B;AAAA,EACA,mBAAmB;AAElB,SAAK,+BAA+B,KAAK,QAAQ;AAEjD,QAAI,KAAK,aAAa,4BAA4B,MAAM,OAAQ;AAChE,SAAK,aAAa,IAAI,QAAQ;AAC9B,SAAK,GAAG,QAAQ,KAAK,wBAAwB;AAAA,EAC9C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,iBAAiB;AAChB,WAAO,KAAK,aAAa,IAAI;AAAA,EAC9B;AAAA,EAYU,qBAAqB;AAC9B,UAAM,kBAAkB,KAAK,4BAA4B,IAAI;AAY7D,WAAO,gBAAgB,KAAK,qBAAQ;AAAA,EACrC;AAAA,EAIkB,oBAAoB;AACrC,WAAO,KAAK,MAAM,MAAM,QAAQ,MAAM;AAAA,EACvC;AAAA,EAYU,WAAqB;AAC9B,WAAO,KAAK,kBAAkB,EAAE,IAAI,EAAE,KAAK,wBAAW;AAAA,EACvD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,iBAAyB;AACxB,WAAO,KAAK,QAAQ,KAAK,iBAAiB,CAAC;AAAA,EAC5C;AAAA,EAYU,mBAA6B;AACtC,WAAO,KAAK,iBAAiB,EAAE;AAAA,EAChC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAeA,QAAQ,MAA6C;AACpD,WAAO,KAAK,MAAM,IAAI,OAAO,SAAS,WAAW,OAAO,KAAK,EAAE;AAAA,EAChE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAeA,yBAAyB;AACxB,WAAO,KAAK,qBAAqB,IAAI;AAAA,EACtC;AAAA,EAMA,+BAA+B;AAC9B,WAAO,MAAM,KAAK,KAAK,uBAAuB,CAAC,EAAE,KAAK;AAAA,EACvD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAeA,gBAAgB,MAAyC;AACxD,UAAM,SAAS,OAAO,SAAS,WAAW,OAAO,KAAK;AACtD,UAAM,SAAS,KAAK,MAAM,MAAM,KAAK,SAAS,EAAE,UAAU,EAAE,IAAI,OAAO,EAAE,CAAC;AAC1E,WAAO,KAAK,yBAAyB,OAAO,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC;AAAA,EAC7D;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAeA,eAAe,MAA+B;AAC7C,UAAM,SAAS,OAAO,SAAS,WAAW,OAAO,KAAK;AACtD,QAAI,CAAC,KAAK,MAAM,IAAI,MAAM,GAAG;AAC5B,cAAQ,MAAM,gEAAgE;AAC9E,aAAO;AAAA,IACR;AAEA,SAAK,kBAAkB;AAEvB,SAAK,SAAS;AAEd,WAAO,KAAK;AAAA,MACX,MAAM;AACL,aAAK,MAAM,IAAI,CAAC,EAAE,GAAG,KAAK,iBAAiB,GAAG,eAAe,OAAO,CAAC,CAAC;AAAA,MACvE;AAAA,MACA,EAAE,SAAS,2BAA2B;AAAA,IACvC;AAAA,EACD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcA,WAAW,SAAoD;AAC9D,QAAI,KAAK,iBAAiB,EAAE,WAAY,QAAO;AAE/C,UAAM,OAAO,KAAK,QAAQ,QAAQ,EAAE;AACpC,QAAI,CAAC,KAAM,QAAO;AAElB,WAAO,KAAK,IAAI,MAAM,KAAK,MAAM,OAAO,QAAQ,IAAI,CAAC,UAAU,EAAE,GAAG,MAAM,GAAG,QAAQ,EAAE,CAAC;AAAA,EACzF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAeA,WAAW,MAA6B;AACvC,SAAK,IAAI,MAAM;AACd,UAAI,KAAK,iBAAiB,EAAE,WAAY;AACxC,UAAI,KAAK,SAAS,EAAE,UAAU,KAAK,QAAQ,SAAU;AACrD,YAAM,QAAQ,KAAK,SAAS;AAE5B,YAAM,WAAO;AAAA,QACZ,KAAK,QAAQ;AAAA,QACb,MAAM,IAAI,CAAC,MAAM,EAAE,IAAI;AAAA,MACxB;AAEA,UAAI,QAAQ,KAAK;AAEjB,UAAI,CAAC,SAAS,MAAM,KAAK,CAAC,MAAM,EAAE,UAAU,KAAK,GAAG;AACnD,oBAAQ,4BAAc,MAAM,MAAM,SAAS,CAAC,EAAE,KAAK;AAAA,MACpD;AAEA,YAAM,UAAU,+BAAe,OAAO;AAAA,QACrC,MAAM,CAAC;AAAA,QACP,GAAG;AAAA,QACH;AAAA,QACA;AAAA,MACD,CAAC;AAED,WAAK,MAAM,IAAI,CAAC,OAAO,CAAC;AAAA,IACzB,CAAC;AACD,WAAO;AAAA,EACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcA,WAAW,MAA+B;AACzC,UAAM,KAAK,OAAO,SAAS,WAAW,OAAO,KAAK;AAClD,SAAK,IAAI,MAAM;AACd,UAAI,KAAK,iBAAiB,EAAE,WAAY;AACxC,YAAM,QAAQ,KAAK,SAAS;AAC5B,UAAI,MAAM,WAAW,EAAG;AAExB,YAAM,cAAc,KAAK,QAAQ,EAAE;AACnC,UAAI,CAAC,YAAa;AAElB,UAAI,OAAO,KAAK,iBAAiB,GAAG;AACnC,cAAM,QAAQ,MAAM,UAAU,CAACC,UAASA,MAAK,OAAO,EAAE;AACtD,cAAM,OAAO,MAAM,QAAQ,CAAC,KAAK,MAAM,QAAQ,CAAC;AAChD,aAAK,eAAe,KAAK,EAAE;AAAA,MAC5B;AACA,WAAK,MAAM,OAAO,CAAC,YAAY,EAAE,CAAC;AAAA,IACnC,CAAC;AACD,WAAO;AAAA,EACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,cAAc,MAAyB,WAAqB,+BAAe,SAAS,GAAS;AAC5F,QAAI,KAAK,SAAS,EAAE,UAAU,KAAK,QAAQ,SAAU,QAAO;AAC5D,UAAM,KAAK,OAAO,SAAS,WAAW,OAAO,KAAK;AAClD,UAAM,YAAY,KAAK,QAAQ,EAAE;AACjC,QAAI,CAAC,UAAW,QAAO;AAEvB,UAAM,aAAa,EAAE,GAAG,KAAK,UAAU,EAAE;AACzC,UAAM,UAAU,KAAK,0BAA0B,KAAK,2BAA2B,UAAU,EAAE,CAAC;AAE5F,SAAK,IAAI,MAAM;AACd,YAAM,QAAQ,KAAK,SAAS;AAC5B,YAAM,YAAQ,8BAAgB,UAAU,OAAO,MAAM,MAAM,QAAQ,SAAS,IAAI,CAAC,GAAG,KAAK;AAGzF,WAAK,WAAW,EAAE,MAAM,UAAU,OAAO,SAAS,IAAI,UAAU,MAAM,CAAC;AAEvE,WAAK,eAAe,QAAQ;AAE5B,WAAK,UAAU,UAAU;AAEzB,UAAI,SAAS;AAEZ,eAAO,KAAK,0BAA0B,OAAO;AAAA,MAC9C;AAAA,IACD,CAAC;AAED,WAAO;AAAA,EACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAeA,WAAW,MAAyB,MAAc;AACjD,UAAM,KAAK,OAAO,SAAS,WAAW,OAAO,KAAK;AAClD,QAAI,KAAK,iBAAiB,EAAE,WAAY,QAAO;AAC/C,SAAK,WAAW,EAAE,IAAI,KAAK,CAAC;AAC5B,WAAO;AAAA,EACR;AAAA,EAKkB,qBAAqB;AACtC,WAAO,KAAK,MAAM,MAAM,QAAQ,OAAO;AAAA,EACxC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,YAAY;AACX,WAAO,KAAK,mBAAmB,EAAE,IAAI;AAAA,EACtC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcA,aAAa,QAAyB;AACrC,QAAI,KAAK,iBAAiB,EAAE,WAAY,QAAO;AAC/C,QAAI,OAAO,UAAU,EAAG,QAAO;AAC/B,SAAK,IAAI,MAAM,KAAK,MAAM,IAAI,MAAM,GAAG,EAAE,SAAS,SAAS,CAAC;AAC5D,WAAO;AAAA,EACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcA,aAAa,QAAgC;AAC5C,QAAI,KAAK,iBAAiB,EAAE,WAAY,QAAO;AAC/C,QAAI,OAAO,UAAU,EAAG,QAAO;AAC/B,SAAK;AAAA,MACJ,MAAM;AACL,aAAK,MAAM;AAAA,UACV,OAAO,IAAI,CAAC,aAAa;AAAA,YACxB,GAAG,KAAK,MAAM,IAAI,QAAQ,EAAE;AAAA,YAC5B,GAAG;AAAA,UACJ,EAAE;AAAA,QACH;AAAA,MACD;AAAA,MACA,EAAE,SAAS,SAAS;AAAA,IACrB;AACA,WAAO;AAAA,EACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcA,aAAa,QAAuC;AACnD,QAAI,KAAK,iBAAiB,EAAE,WAAY,QAAO;AAE/C,UAAM,MACL,OAAO,OAAO,CAAC,MAAM,WACjB,SACA,OAAqB,IAAI,CAAC,MAAM,EAAE,EAAE;AACzC,QAAI,IAAI,UAAU,EAAG,QAAO;AAE5B,SAAK,IAAI,MAAM,KAAK,MAAM,OAAO,GAAG,GAAG,EAAE,SAAS,SAAS,CAAC;AAC5D,WAAO;AAAA,EACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcA,SAAS,OAAiD;AACzD,WAAO,KAAK,MAAM,IAAI,OAAO,UAAU,WAAW,QAAQ,MAAM,EAAE;AAAA,EACnE;AAAA,EAEA,MAAM,gBACL,SACA,SAIyB;AACzB,QAAI,CAAC,QAAS,QAAO;AACrB,UAAM,QAAQ,KAAK,SAAS,OAAO;AACnC,QAAI,CAAC,MAAO,QAAO;AAEnB,UAAM,EAAE,cAAc,GAAG,0BAA0B,MAAM,IAAI;AAG7D,UAAM,mBAAmB,CAAC,SAAiB,KAAK,IAAI,GAAG,KAAK,KAAK,KAAK,KAAK,IAAI,CAAC,CAAC;AACjF,UAAM,qBAAqB,KAAK,IAAI,OAAO,iBAAiB,WAAW,CAAC;AACxE,UAAM,uBACL,gBAAgB,YAAa,UAAkB,WAAW,gBAAgB;AAC3E,UAAM,MAAM,KAAK,iBAAiB,EAAE;AAEpC,WAAO,MAAM,KAAK,MAAM,MAAM,OAAO,QAAQ,OAAO;AAAA,MACnD,aAAa,eAAe;AAAA,MAC5B;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACD,CAAC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,YAAY,OAAgB,MAA6B;AAC9D,WAAO,MAAM,KAAK,MAAM,MAAM,OAAO,OAAO,OAAO,IAAI;AAAA,EACxD;AAAA,EAKQ,yBAA6D;AACpE,WAAO,KAAK,MAAM;AAAA,MACjB;AAAA,MACA,CAAC,UAAU,KAAK,aAAa,KAAK,EAAE,YAAY,KAAK;AAAA,MACrD,CAAC,GAAG,MAAM,EAAE,UAAU,EAAE;AAAA,IACzB;AAAA,EACD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAeA,iBAAuC,OAA+B;AACrE,WAAO,KAAK,uBAAuB,EAAE,IAAI,OAAO,UAAU,WAAW,QAAQ,MAAM,EAAE;AAAA,EACtF;AAAA,EAGkB,wBAAwE;AACzF,WAAO,KAAK,MAAM,oBAAoB,WAAW,CAAC,UAAU;AAC3D,aAAO,KAAK,aAAa,KAAK,EAAE,aAAa,KAAK;AAAA,IACnD,CAAC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcA,gBAAmC,OAA4C;AAC9E,WAAO,KAAK,sBAAsB,EAAE,IAAI,OAAO,UAAU,WAAW,QAAQ,MAAM,EAAE;AAAA,EACrF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAiBA,uBAAuB,OAAiC;AACvD,UAAM,KAAK,OAAO,UAAU,WAAW,QAAQ,MAAM;AACrD,UAAM,aAAa,KAAK,SAAS,EAAE;AACnC,QAAI,CAAC,WAAY,OAAM,MAAM,sCAAsC;AACnE,WAAO,eAAI,SAAS,EAAE,UAAU,WAAW,GAAG,WAAW,CAAC,EAAE,OAAO,WAAW,QAAQ;AAAA,EACvF;AAAA,EAOkB,8BAA2D;AAC5E,WAAO,KAAK,MAAM,oBAAkC,sBAAsB,CAAC,UAAU;AACpF,cAAI,0BAAS,MAAM,QAAQ,GAAG;AAC7B,eAAO,KAAK,uBAAuB,KAAK;AAAA,MACzC;AAMA,YAAM,kBACL,KAAK,4BAA4B,EAAE,IAAI,MAAM,QAAQ,KAAK,eAAI,SAAS;AACxE,aAAO,eAAI,QAAQ,iBAAiB,KAAK,uBAAuB,KAAK,CAAE;AAAA,IACxE,CAAC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcA,wBAAwB,OAAiC;AACxD,UAAM,KAAK,OAAO,UAAU,WAAW,QAAQ,MAAM;AACrD,UAAM,aAAa,KAAK,SAAS,EAAE;AACnC,QAAI,CAAC,kBAAc,0BAAS,WAAW,QAAQ,EAAG,QAAO,eAAI,SAAS;AACtE,WAAO,KAAK,4BAA4B,EAAE,IAAI,WAAW,QAAQ,KAAK,eAAI,SAAS;AAAA,EACpF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAeA,sBAAsB,OAAiC;AACtD,UAAM,KAAK,OAAO,UAAU,WAAW,QAAQ,MAAM;AACrD,WAAO,KAAK,4BAA4B,EAAE,IAAI,EAAE,KAAK,eAAI,SAAS;AAAA,EACnE;AAAA,EAGkB,2BAAwD;AACzE,WAAO,KAAK,MAAM,oBAAkC,mBAAmB,CAAC,UAAU;AACjF,YAAM,gBAAgB,KAAK,4BAA4B,EAAE,IAAI,MAAM,EAAE;AAErE,UAAI,CAAC,cAAe,QAAO,IAAI,eAAI;AAEnC,YAAM,SAAS,eAAI;AAAA,QAClB,eAAI,cAAc,eAAe,KAAK,iBAAiB,KAAK,EAAE,QAAQ;AAAA,MACvE;AAEA,aAAO;AAAA,IACR,CAAC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAeA,mBAAmB,OAA6C;AAC/D,WAAO,KAAK,yBAAyB,EAAE,IAAI,OAAO,UAAU,WAAW,QAAQ,MAAM,EAAE;AAAA,EACxF;AAAA,EAOkB,yBAAyD;AAC1E,WAAO,KAAK,MAAM,oBAAqC,iBAAiB,CAAC,UAAU;AAClF,YAAM,WAAW,KAAK,mBAAmB,EAAE,IAAI,MAAM,EAAE;AACvD,UAAI,CAAC,SAAU,QAAO;AACtB,UAAI,SAAS,WAAW,GAAG;AAC1B,eAAO;AAAA,MACR;AAEA,YAAM,gBAAgB,KAAK,4BAA4B,EAAE,IAAI,MAAM,EAAE;AACrE,UAAI,CAAC,cAAe,QAAO;AAE3B,YAAM,YAAY,eAAI,cAAc,eAAI,QAAQ,aAAa,GAAG,QAAQ;AAExE,aAAO,WAAW,UAAU,IAAI,CAAC,MAAM,GAAG,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,KAAK,GAAG,CAAC;AAAA,IACtE,CAAC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAiBA,iBAAiB,OAAgD;AAChE,WAAO,KAAK,uBAAuB,EAAE,IAAI,OAAO,UAAU,WAAW,QAAQ,MAAM,EAAE;AAAA,EACtF;AAAA,EAGkB,qBAAoD;AACrE,WAAO,KAAK,MAAM,oBAAoB,iBAAiB,CAAC,UAAU;AACjE,cAAI,0BAAS,MAAM,QAAQ,EAAG,QAAO;AAErC,YAAM,iBAAiB,KAAK,kBAAkB,MAAM,EAAE,EAAE;AAAA,QAAO,CAACF,WAC/D,KAAK,cAA4BA,QAAO,OAAO;AAAA,MAChD;AAEA,UAAI,eAAe,WAAW,EAAG,QAAO;AAExC,YAAM,WAAW,eACf;AAAA,QAAuB,CAAC;AAAA;AAAA,UAExB,KAAK,4BAA4B,EAC/B,IAAI,EAAE,EAAE,EACR,cAAc,KAAK,iBAAiB,CAAC,EAAE,QAAQ;AAAA;AAAA,MAClD,EACC,OAAO,CAAC,KAAK,MAAM;AACnB,YAAI,EAAE,KAAK,KAAM,QAAO;AACxB,cAAM,mBAAe,0CAAwB,KAAK,CAAC;AACnD,YAAI,cAAc;AACjB,iBAAO,aAAa,IAAI,eAAI,IAAI;AAAA,QACjC;AACA,eAAO,CAAC;AAAA,MACT,CAAC;AAEF,aAAO;AAAA,IACR,CAAC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAgBA,aAAa,OAAmD;AAC/D,WAAO,KAAK,mBAAmB,EAAE,IAAI,OAAO,UAAU,WAAW,QAAQ,MAAM,EAAE;AAAA,EAClF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAiBA,yBAAyB,OAA6C;AACrE,QAAI,OAAO,UAAU,SAAU,SAAQ,MAAM;AAC7C,WAAO,KAAK,+BAA+B,EAAE,IAAI,KAAK;AAAA,EACvD;AAAA,EAGkB,iCAA8D;AAC/E,WAAO,KAAK,MAAM,oBAAoB,8BAA8B,CAAC,UAAU;AAC9E,YAAM,aAAa,KAAK,yBAAyB,EAAE,IAAI,MAAM,EAAE;AAC/D,UAAI,CAAC,WAAY;AACjB,YAAM,WAAW,KAAK,mBAAmB,EAAE,IAAI,MAAM,EAAE;AACvD,UAAI,UAAU;AACb,YAAI,SAAS,WAAW,EAAG,QAAO;AAClC,cAAM,EAAE,QAAQ,IAAI;AACpB,YAAI,QAAQ,MAAM,CAAC,GAAG,MAAM,KAAK,eAAI,OAAO,GAAG,SAAS,CAAC,CAAC,CAAC,EAAG,QAAO,WAAW,MAAM;AACtF,cAAM,mBAAe,0CAAwB,UAAU,OAAO;AAC9D,YAAI,CAAC,aAAc;AACnB,eAAO,eAAI,WAAW,YAAY;AAAA,MACnC;AACA,aAAO;AAAA,IACR,CAAC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAeA,kBAAkB,OAA4B,MAAiB,CAAC,GAAc;AAC7E,UAAM,KAAK,OAAO,UAAU,WAAW,QAAQ,MAAM;AACrD,UAAM,aAAa,KAAK,SAAS,EAAE;AACnC,QAAI,CAAC,WAAY,QAAO;AACxB,UAAM,WAAW,WAAW;AAC5B,YAAI,0BAAS,QAAQ,GAAG;AACvB,UAAI,QAAQ;AACZ,aAAO;AAAA,IACR;AAEA,UAAM,SAAS,KAAK,MAAM,IAAI,QAAQ;AACtC,QAAI,CAAC,OAAQ,QAAO;AACpB,QAAI,KAAK,MAAM;AACf,WAAO,KAAK,kBAAkB,QAAQ,GAAG;AAAA,EAC1C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAgBA,kBACC,OACA,WACsB;AACtB,UAAM,KAAK,OAAO,UAAU,WAAW,QAAQ,MAAM;AACrD,UAAM,aAAa,KAAK,SAAS,EAAE;AACnC,QAAI,CAAC,WAAY;AAEjB,UAAM,WAAW,WAAW;AAC5B,YAAI,0BAAS,QAAQ,EAAG;AAExB,UAAM,SAAS,KAAK,SAAS,QAAQ;AACrC,QAAI,CAAC,OAAQ;AACb,WAAO,UAAU,MAAM,IAAI,SAAS,KAAK,kBAAkB,QAAQ,SAAS;AAAA,EAC7E;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,YAAY,OAAwC,YAAgC;AACnF,UAAM,KAAK,OAAO,UAAU,WAAW,QAAQ,OAAO;AACtD,UAAM,aAAa,MAAM,KAAK,SAAS,EAAE;AACzC,QAAI,CAAC,WAAY,QAAO;AACxB,QAAI,WAAW,aAAa,WAAY,QAAO;AAC/C,WAAO,KAAK,YAAY,KAAK,eAAe,UAAU,GAAG,UAAU;AAAA,EACpE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,mBACC,QACA,WACwB;AACxB,QAAI,OAAO,WAAW,GAAG;AACxB;AAAA,IACD;AAEA,UAAM,MACL,OAAO,OAAO,CAAC,MAAM,WACjB,SACA,OAAqB,IAAI,CAAC,MAAM,EAAE,EAAE;AACzC,UAAM,kBAAc,sBAAQ,IAAI,IAAI,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC,CAAC;AAE9D,QAAI,YAAY,WAAW,GAAG;AAC7B,YAAM,WAAW,YAAY,CAAC,EAAE;AAChC,cAAI,0BAAS,QAAQ,GAAG;AACvB;AAAA,MACD;AACA,aAAO,YAAY,KAAK,kBAAkB,YAAY,CAAC,GAAG,SAAS,GAAG,KAAK;AAAA,IAC5E;AAEA,UAAM,CAAC,OAAO,GAAG,MAAM,IAAI;AAC3B,QAAI,WAAW,KAAK,eAAe,KAAK;AACxC,WAAO,UAAU;AAEhB,UAAI,aAAa,CAAC,UAAU,QAAQ,GAAG;AACtC,mBAAW,KAAK,eAAe,QAAQ;AACvC;AAAA,MACD;AACA,UAAI,OAAO,MAAM,CAAC,UAAU,KAAK,YAAY,OAAO,SAAU,EAAE,CAAC,GAAG;AACnE,eAAO,SAAU;AAAA,MAClB;AACA,iBAAW,KAAK,eAAe,QAAQ;AAAA,IACxC;AACA,WAAO;AAAA,EACR;AAAA,EAWA,wBAAwB,KAAoC;AAC3D,UAAM,QAAQ,OAAO,QAAQ,WAAW,KAAK,SAAS,GAAG,IAAI;AAC7D,QAAI,UAAU,OAAW,QAAO;AAChC,QAAI,MAAM,SAAU,QAAO;AAC3B,WAAO,KAAK,wBAAwB,KAAK,eAAe,KAAK,CAAC;AAAA,EAC/D;AAAA,EAGQ,oBAAoB;AAC3B,eAAO,0CAAiB,IAAI;AAAA,EAC7B;AAAA,EAQA,kBAAkB;AACjB,UAAMG,oBAAmB,KAAK,kBAAkB,EAAE,IAAI;AACtD,UAAM,mBAAmB,KAAK,oBAAoB;AAClD,UAAM,YAAY,KAAK,kBAAkB;AACzC,UAAM,eAAe,IAAI,IAAeA,iBAAgB;AAExD,QAAI,WAAW;AACd,mBAAa,OAAO,SAAS;AAAA,IAC9B;AAEA,qBAAiB,QAAQ,CAAC,OAAO;AAChC,mBAAa,OAAO,EAAE;AAAA,IACvB,CAAC;AACD,WAAO;AAAA,EACR;AAAA,EAOU,uBAAwC;AACjD,QAAI;AAEJ,SAAK,6BAA6B,EAAE,QAAQ,CAAC,YAAY;AACxD,YAAM,SAAS,KAAK,yBAAyB,OAAO;AACpD,UAAI,CAAC,OAAQ;AACb,UAAI,CAAC,cAAc;AAClB,uBAAe,OAAO,MAAM;AAAA,MAC7B,OAAO;AACN,uBAAe,aAAa,OAAO,MAAM;AAAA,MAC1C;AAAA,IACD,CAAC;AAED,WAAO;AAAA,EACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,wBAAwB,OAAqC;AAC5D,UAAM,mBAAmB,KAAK,oBAAoB;AAClD,WAAO,KAAK,2BAA2B,EACrC,OAAO,CAAC,UAAU,MAAM,SAAS,WAAW,iBAAiB,SAAS,MAAM,EAAE,CAAC,EAC/E,QAAQ,EACR,KAAK,CAAC,UAAU,KAAK,eAAe,OAAO,OAAO,EAAE,WAAW,MAAM,QAAQ,EAAE,CAAC,CAAC;AAAA,EACpF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,gBACC,OACA,OAAO,CAAC,GAWc;AACtB,UAAM,YAAY,KAAK,aAAa;AACpC,UAAM,qBAAqB,KAAK,sBAAsB;AACtD,UAAM;AAAA,MACL;AAAA,MACA,SAAS;AAAA,MACT,YAAY;AAAA,MACZ,YAAY;AAAA,MACZ,YAAY;AAAA,MACZ,iBAAiB;AAAA,IAClB,IAAI;AAEJ,QAAI,uBAAuB;AAC3B,QAAI,0BAA0C;AAE9C,QAAI,gCAAgC;AACpC,QAAI,2BAA2C;AAE/C,UAAM,iBACL,KAAK,gBACF,KAAK,oCAAoC,IACzC,KAAK,2BAA2B,GAClC,OAAO,CAAC,UAAU;AACnB,UACE,MAAM,YAAY,CAAC,aACpB,KAAK,cAAc,KAAK,KACxB,KAAK,cAAc,OAAO,OAAO;AAEjC,eAAO;AACR,YAAM,WAAW,KAAK,aAAa,KAAK;AACxC,UAAI,YAAY,KAAC,8BAAe,OAAO,QAAQ,EAAG,QAAO;AACzD,UAAI,OAAQ,QAAO,OAAO,KAAK;AAC/B,aAAO;AAAA,IACR,CAAC;AAED,aAAS,IAAI,cAAc,SAAS,GAAG,KAAK,GAAG,KAAK;AACnD,YAAM,QAAQ,cAAc,CAAC;AAC7B,YAAM,WAAW,KAAK,iBAAiB,KAAK;AAC5C,YAAM,UAAU,oBAAoB;AAEpC,YAAM,oBAAoB,KAAK,qBAAqB,OAAO,KAAK;AAGhE,UACC,KAAK,cAA4B,OAAO,OAAO,KAC9C,KAAK,cAA0B,OAAO,KAAK,KAAK,MAAM,MAAM,SAAS,QACrE;AACD,YAAI,MAAM,MAAM,KAAK,KAAK,GAAG;AAE5B,qBAAW,iBAAkB,SAAqB,UAAU;AAC3D,gBAAI,cAAc,WAAW,cAAc,gBAAgB,iBAAiB,GAAG;AAC9E,qBAAO;AAAA,YACR;AAAA,UACD;AAAA,QACD;AAAA,MACD;AAEA,UAAI,KAAK,cAAc,OAAO,OAAO,GAAG;AAKvC,cAAMC,YAAW,SAAS,gBAAgB,mBAAmB,SAAS;AACtE,YAAI,KAAK,IAAIA,SAAQ,KAAK,QAAQ;AACjC,iBAAO,4BAA4B;AAAA,QACpC;AAEA,YAAI,SAAS,aAAa,mBAAmB,GAAG,IAAI,GAAG;AAOtD,iBACC,4BACA,4BACC,iBAAiB,QAAQ;AAAA,QAE5B;AACA;AAAA,MACD;AAEA,UAAI;AAEJ,UAAI,SAAS;AACZ,YAAI,cAAc;AAClB,mBAAW,iBAAiB,SAAS,UAAU;AAC9C,cAAI,cAAc,WAAW,CAAC,UAAW;AAGzC,gBAAM,YAAY,cAAc,gBAAgB,mBAAmB,SAAS;AAC5E,cAAI,YAAY,aAAa;AAC5B,0BAAc;AAAA,UACf;AAAA,QACD;AAEA,mBAAW;AAAA,MACZ,OAAO;AAIN,YAAI,WAAW,MAAM,SAAS,OAAO,IAAI,KAAK,SAAS,OAAO,IAAI,IAAI;AACrE,qBAAW,SAAS,gBAAgB,mBAAmB,SAAS;AAAA,QACjE,OAAO;AAEN,cAAI,SAAS,OAAO,cAAc,mBAAmB,MAAM,GAAG;AAE7D,uBAAW,SAAS,gBAAgB,mBAAmB,SAAS;AAAA,UACjE,OAAO;AAEN,uBAAW;AAAA,UACZ;AAAA,QACD;AAAA,MACD;AAEA,UAAI,SAAS,UAAU;AAKtB,YAAI,YAAY,QAAQ;AACvB,cAAI,SAAS,YAAa,WAAW,SAAS,SAAS,CAAC,EAAE,UAAW;AAIpE,mBAAO,4BAA4B;AAAA,UACpC,OAAO;AAEN,gBAAI,KAAK,mBAAmB,KAAK,EAAG,SAAS,kBAAkB,EAAG;AAGlE,gBAAI,KAAK,IAAI,QAAQ,IAAI,QAAQ;AAIhC,kBAAI,KAAK,IAAI,QAAQ,IAAI,+BAA+B;AACvD,gDAAgC,KAAK,IAAI,QAAQ;AACjD,2CAA2B;AAAA,cAC5B;AAAA,YACD,WAAW,CAAC,0BAA0B;AAMrC,oBAAM,EAAE,KAAK,IAAI;AACjB,kBAAI,OAAO,sBAAsB;AAChC,uCAAuB;AACvB,0CAA0B;AAAA,cAC3B;AAAA,YACD;AAAA,UACD;AAAA,QACD;AAAA,MACD,OAAO;AAGN,YAAI,WAAW,KAAK,QAAQ,gBAAgB,WAAW;AACtD,iBAAO;AAAA,QACR;AAAA,MACD;AAAA,IACD;AAOA,WAAO,4BAA4B,2BAA2B;AAAA,EAC/D;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAeA,iBACC,OACA,OAAO,CAAC,GACI;AACZ,WAAO,KAAK,qBAAqB,EAAE;AAAA,MAClC,CAAC,UAAU,CAAC,KAAK,cAAc,KAAK,KAAK,KAAK,eAAe,OAAO,OAAO,IAAI;AAAA,IAChF;AAAA,EACD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAiBA,eACC,OACA,OACA,OAAO,CAAC,GAIE;AACV,UAAM,EAAE,YAAY,OAAO,SAAS,EAAE,IAAI;AAC1C,UAAM,KAAK,OAAO,UAAU,WAAW,QAAQ,MAAM;AAGrD,UAAM,WAAW,KAAK,aAAa,EAAE;AACrC,QAAI,YAAY,KAAC,8BAAe,OAAO,QAAQ,EAAG,QAAO;AAEzD,WAAO,KAAK,iBAAiB,EAAE,EAAE;AAAA,MAChC,KAAK,qBAAqB,OAAO,KAAK;AAAA,MACtC;AAAA,MACA;AAAA,IACD;AAAA,EACD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAiBA,qBAAqB,OAA4B,OAAqB;AACrE,UAAM,KAAK,OAAO,UAAU,WAAW,QAAQ,MAAM;AACrD,WAAO,KAAK,4BAA4B,EAAE,IAAI,EAAE,EAAG,MAAM,EAAE,OAAO,EAAE,aAAa,KAAK;AAAA,EACvF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAeA,sBAAsB,OAA4B,OAAqB;AACtE,UAAM,KAAK,OAAO,UAAU,WAAW,QAAQ,MAAM;AACrD,UAAM,aAAa,KAAK,SAAS,EAAE;AACnC,QAAI,CAAC,WAAY,QAAO,IAAI,eAAI,GAAG,CAAC;AACpC,YAAI,0BAAS,WAAW,QAAQ,EAAG,QAAO,eAAI,KAAK,KAAK;AAExD,UAAM,kBAAkB,KAAK,sBAAsB,WAAW,QAAQ;AACtE,QAAI,CAAC,gBAAiB,QAAO,eAAI,KAAK,KAAK;AAC3C,WAAO,gBAAgB,MAAM,EAAE,OAAO,EAAE,aAAa,KAAK;AAAA,EAC3D;AAAA,EAOU,uBAAkC;AAC3C,WAAO,MAAM,KAAK,KAAK,uBAAuB,GAAG,CAAC,OAAO,KAAK,MAAM,IAAI,EAAE,CAAa;AAAA,EACxF;AAAA,EAQU,6BAAwC;AACjD,UAAM,SAAoB,CAAC;AAC3B,UAAM,iBAAiB,KAAK,2BAA2B,KAAK,iBAAiB,CAAC;AAE9E,aAAS,IAAI,GAAG,IAAI,eAAe,QAAQ,IAAI,GAAG,KAAK;AACtD,+BAAyB,MAAM,eAAe,CAAC,GAAG,MAAM;AAAA,IACzD;AAEA,WAAO;AAAA,EACR;AAAA,EAQU,sCAAiD;AAC1D,UAAM,eAAe,KAAK,gBAAgB;AAC1C,WAAO,KAAK,2BAA2B,EAAE;AAAA,MACxC,CAAC,EAAE,GAAG,MAAM,CAAC,aAAa,IAAI,EAAE,KAAK,CAAC,KAAK,cAAc,EAAE;AAAA,IAC5D;AAAA,EACD;AAAA,EAoBA,cACC,KACA,MACC;AACD,UAAM,QAAQ,OAAO,QAAQ,WAAW,KAAK,SAAS,GAAG,IAAI;AAC7D,QAAI,CAAC,MAAO,QAAO;AACnB,WAAO,MAAM,SAAS;AAAA,EACvB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcA,SAAsC,OAA4C;AACjF,UAAM,KAAK,OAAO,UAAU,WAAW,QAAQ,MAAM;AACrD,QAAI,KAAC,2BAAU,EAAE,EAAG,QAAO;AAC3B,WAAO,KAAK,MAAM,IAAI,EAAE;AAAA,EACzB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaA,eAAe,OAAkD;AAChE,UAAM,KAAK,OAAO,UAAU,WAAW,QAAQ,OAAO;AACtD,QAAI,CAAC,GAAI,QAAO;AAChB,UAAM,aAAa,KAAK,SAAS,EAAE;AACnC,QAAI,eAAe,UAAa,KAAC,2BAAU,WAAW,QAAQ,EAAG,QAAO;AACxE,WAAO,KAAK,MAAM,IAAI,WAAW,QAAQ;AAAA,EAC1C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,uBACC,cACA,aACsB;AACtB,QAAI,CAAC,aAAa;AACjB,aAAO;AAAA,IACR;AACA,QAAI,YAAY,aAAa,aAAa,UAAU;AACnD,aAAO;AAAA,IACR;AAEA,UAAM,WAAW,KAAK;AAAA,MACrB;AAAA,MACA,CAACC,cAAaA,UAAS,aAAa,aAAa;AAAA,IAClD;AAEA,WAAO;AAAA,EACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAgBA,cAAc,OAA4B,SAAS,KAAK,iBAAiB,GAAY;AACpF,UAAM,KAAK,OAAO,UAAU,WAAW,QAAQ,MAAM;AACrD,UAAM,eAAe,KAAK,SAAS,EAAE;AACrC,QAAI,CAAC,aAAc,QAAO;AAE1B,QAAI,gBAAgB;AAEpB,QAAI,aAAa,aAAa,QAAQ;AACrC,sBAAgB;AAAA,IACjB,OAAO;AACN,UAAI,SAAS,KAAK,SAAS,aAAa,QAAQ;AAChD,qBAAgB,QAAO,QAAQ;AAC9B,YAAI,OAAO,aAAa,QAAQ;AAC/B,0BAAgB;AAChB,gBAAM;AAAA,QACP;AACA,iBAAS,KAAK,SAAS,OAAO,QAAQ;AAAA,MACvC;AAAA,IACD;AAEA,WAAO;AAAA,EACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,kBAAkB,OAAmD;AACpE,UAAM,KAAK,OAAO,UAAU,WAAW,QAAQ,OAAO;AACtD,UAAM,SAAS,MAAM,KAAK,SAAS,EAAE;AACrC,QAAI,CAAC,OAAQ,QAAO;AACpB,YAAI,0BAAS,OAAO,QAAQ,GAAG;AAC9B,aAAO,OAAO;AAAA,IACf,OAAO;AACN,aAAO,KAAK,kBAAkB,KAAK,SAAS,OAAO,QAAQ,CAAC;AAAA,IAC7D;AAAA,EACD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EA4BA,eAAe,QAAiC,UAAsB,aAAwB;AAC7F,UAAM,MACL,OAAO,OAAO,CAAC,MAAM,WAAY,SAAyB,OAAO,IAAI,CAAC,MAAO,EAAc,EAAE;AAC9F,QAAI,IAAI,WAAW,EAAG,QAAO;AAE7B,UAAM,UAA4B,CAAC;AAEnC,UAAM,sBAAkB,0BAAS,QAAQ,IACtC,eAAI,SAAS,IACb,KAAK,sBAAsB,QAAQ;AAEtC,UAAM,qBAAqB,gBAAgB,SAAS;AAEpD,QAAI,UAAsB,CAAC;AAE3B,UAAM,WAAO,sBAAQ,KAAK,2BAA2B,QAAQ,EAAE,IAAI,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC,CAAC;AAE7F,QAAI,aAAa;AAChB,YAAM,qBAAqB,KAAK,KAAK,CAAC,MAAM,EAAE,UAAU,WAAW;AACnE,UAAI,oBAAoB;AAEvB,cAAM,WAAW,KAAK,KAAK,QAAQ,kBAAkB,IAAI,CAAC;AAC1D,YAAI,UAAU;AAGb,wBAAU,gCAAkB,aAAa,SAAS,OAAO,IAAI,MAAM;AAAA,QACpE,OAAO;AAGN,wBAAU,8BAAgB,aAAa,IAAI,MAAM;AAAA,QAClD;AAAA,MACD,OAAO;AAEN,cAAM,WAAW,KAAK,KAAK,wBAAW,EAAE,KAAK,CAAC,MAAM,EAAE,QAAQ,WAAW;AAEzE,YAAI,UAAU;AAGb,wBAAU,gCAAkB,aAAa,SAAS,OAAO,IAAI,MAAM;AAAA,QACpE,OAAO;AAGN,wBAAU,8BAAgB,aAAa,IAAI,MAAM;AAAA,QAClD;AAAA,MACD;AAAA,IACD,OAAO;AAEN,YAAM,MAAM,KAAK,UAAU,KAAK,KAAK,SAAS,CAAC;AAC/C,gBAAU,UAAM,8BAAgB,IAAI,OAAO,IAAI,MAAM,QAAI,yBAAW,IAAI,MAAM;AAAA,IAC/E;AAEA,UAAM,0BAA0B,gBAAgB,MAAM,EAAE,OAAO;AAE/D,UAAM,uBAAmB,sBAAQ,IAAI,IAAI,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC,CAAC;AAInE,SAAK;AAAA,MACJ,MAAM;AACL,iBAAS,IAAI,GAAG,IAAI,iBAAiB,QAAQ,KAAK;AACjD,gBAAM,QAAQ,iBAAiB,CAAC;AAEhC,gBAAM,gBAAgB,KAAK,sBAAsB,KAAK;AACtD,cAAI,CAAC,cAAe;AAEpB,gBAAM,YAAY,cAAc,MAAM;AACtC,cAAI,CAAC,UAAW;AAEhB,gBAAM,WAAW,wBAAwB,aAAa,SAAS;AAC/D,gBAAM,cAAc,cAAc,SAAS,IAAI;AAE/C,kBAAQ,KAAK;AAAA,YACZ,IAAI,MAAM;AAAA,YACV,MAAM,MAAM;AAAA,YACZ;AAAA,YACA,GAAG,SAAS;AAAA,YACZ,GAAG,SAAS;AAAA,YACZ,UAAU;AAAA,YACV,OAAO,QAAQ,CAAC;AAAA,UACjB,CAAC;AAAA,QACF;AAEA,aAAK,aAAa,OAAO;AAAA,MAC1B;AAAA,MACA,EAAE,iBAAiB,KAAK;AAAA,IACzB;AAEA,WAAO;AAAA,EACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,yBAAyB,QAAiD;AACzE,UAAM,WAAW,OAAO,WAAW,WAAW,SAAS,OAAO;AAC9D,UAAM,WAAW,KAAK,qBAAqB,IAAI,EAAE,QAAQ;AAEzD,QAAI,CAAC,YAAY,SAAS,WAAW,GAAG;AACvC,aAAO;AAAA,IACR;AACA,UAAM,QAAQ,KAAK,SAAS,SAAS,SAAS,SAAS,CAAC,CAAC;AACzD,eAAO,4BAAc,MAAM,KAAK;AAAA,EACjC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcA,2BAA2B,QAAoD;AAC9E,UAAM,WAAW,OAAO,WAAW,WAAW,SAAS,OAAO;AAC9D,UAAM,MAAM,KAAK,qBAAqB,IAAI,EAAE,QAAQ;AACpD,QAAI,CAAC,IAAK,QAAO;AACjB,WAAO;AAAA,EACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAeA,iBACC,QACA,SACO;AACP,UAAM,WAAW,OAAO,WAAW,WAAW,SAAS,OAAO;AAC9D,UAAM,WAAW,KAAK,2BAA2B,QAAQ;AACzD,eAAW,MAAM,UAAU;AAC1B,UAAI,QAAQ,EAAE,MAAM,MAAO;AAC3B,WAAK,iBAAiB,IAAI,OAAO;AAAA,IAClC;AACA,WAAO;AAAA,EACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,yBAAyB,KAAkC;AAC1D,UAAM,WAAW,oBAAI,IAAe;AACpC,eAAW,SAAS,IAAI,IAAI,CAAC,OAAO,KAAK,SAAS,EAAE,CAAE,EAAE,KAAK,wBAAW,GAAG;AAC1E,eAAS,IAAI,MAAM,EAAE;AACrB,WAAK,iBAAiB,OAAO,CAAC,iBAAiB;AAC9C,iBAAS,IAAI,YAAY;AAAA,MAC1B,CAAC;AAAA,IACF;AACA,WAAO;AAAA,EACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,qBAAqB,OAAgB,iBAA4B,CAAC,GAAG;AAEpE,UAAM,0BAA0B,KAAK,2BAA2B;AAChE,aAAS,IAAI,wBAAwB,SAAS,GAAG,KAAK,GAAG,KAAK;AAC7D,YAAM,QAAQ,wBAAwB,CAAC;AAEvC;AAAA;AAAA,QAEC,KAAK,cAAc,KAAK;AAAA,QAExB,KAAK,oBAAoB,EAAE,SAAS,MAAM,EAAE;AAAA,QAE5C,CAAC,KAAK,aAAa,KAAK,EAAE,cAAc,OAAO,cAAc;AAAA,QAE7D,eAAe,KAAK,CAAC,MAAM,EAAE,OAAO,MAAM,MAAM,KAAK,YAAY,OAAO,EAAE,EAAE,CAAC;AAAA,QAC5E;AACD;AAAA,MACD;AAIA,YAAM,mBAAmB,KAAK,yBAAyB,MAAM,EAAE;AAE/D,UACC,oBACA,iBAAiB,cAAc,KAAK,KACpC,KAAK,iBAAiB,KAAK,EAAE,aAAa,KAAK,qBAAqB,OAAO,KAAK,GAAG,GAAG,IAAI,GACzF;AACD,eAAO;AAAA,MACR;AAAA,IACD;AAAA,EACD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcA,4BACC,OACA,QACU;AACV,UAAM,KAAK,OAAO,UAAU,WAAW,QAAQ,MAAM;AACrD,UAAM,aAAa,KAAK,SAAS,EAAE;AACnC,QAAI,QAAQ;AACZ,QAAI,OAAO;AAEX,UAAM,eAAe,KAAK,gBAAgB;AAE1C,WAAO,MAAM;AACZ,UACC,KAAK,cAA4B,MAAM,OAAO,KAC9C,cAAc,OAAO,KAAK,MAC1B,CAAC,KAAK,YAAY,cAAc,KAAK,EAAE,MACtC,SAAS,IAAI,KAAK,OAClB;AACD,gBAAQ;AAAA,MACT,WAAW,cAAc,OAAO,KAAK,IAAI;AACxC;AAAA,MACD;AACA,aAAO,KAAK,eAAe,IAAI;AAAA,IAChC;AAEA,WAAO;AAAA,EACR;AAAA,EAKQ,yBAAyB;AAChC,UAAM,YAAQ,oCAAc,IAAI;AAChC,WAAO,KAAK,MAAM,oBAA0C,iBAAiB,CAAC,UAAU;AACvF,aAAO,MAAM,IAAI,EAAE,IAAI,MAAM,EAAE;AAAA,IAChC,CAAC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,WAAW,IAAwC;AAClD,WAAO,KAAK,MAAM,IAAI,EAAE;AAAA,EACzB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,qBACC,OACA,MACY;AACZ,UAAM,KAAK,OAAO,UAAU,WAAW,QAAQ,MAAM;AACrD,WAAO,KAAK,0BAA0B,EAAE,EAAE;AAAA,MACzC,CAAC,MAAM,EAAE,WAAW,MAAM,EAAE,SAAS;AAAA,IACtC;AAAA,EACD;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,mBACC,OACA,MACY;AACZ,UAAM,KAAK,OAAO,UAAU,WAAW,QAAQ,MAAM;AACrD,WAAO,KAAK,0BAA0B,EAAE,EAAE;AAAA,MACzC,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,SAAS;AAAA,IACpC;AAAA,EACD;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,0BACC,OACA,MACY;AACZ,UAAM,KAAK,OAAO,UAAU,WAAW,QAAQ,MAAM;AACrD,UAAM,SAAS,KAAK,uBAAuB,EAAE,IAAI,EAAE,KAAK;AACxD,QAAI,CAAC,KAAM,QAAO;AAClB,WAAO,OAAO,OAAO,CAAC,MAAM,EAAE,SAAS,IAAI;AAAA,EAC5C;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,eAAe,UAA6B;AAC3C,UAAM,WAAwB,CAAC;AAC/B,eAAW,WAAW,UAAU;AAC/B,YAAM,YAAY,KAAK,SAAS,QAAQ,MAAM;AAC9C,YAAM,UAAU,KAAK,SAAS,QAAQ,IAAI;AAC1C,UAAI,CAAC,aAAa,CAAC,QAAS;AAC5B,UAAI,CAAC,KAAK,cAAc,EAAE,WAAW,SAAS,SAAS,QAAQ,CAAC,EAAG;AAEnE,YAAM,OAAO,KAAK,eAAiC,QAAQ,IAAI;AAC/D,YAAM,eAAe,KAAK,gBAAgB;AAC1C,YAAM,UAAU,KAAK,MAAM,OAAO,MAAM,QAAQ,OAAO;AAAA,QACtD,GAAG;AAAA,QACH,IAAI,QAAQ,UAAM,iCAAgB;AAAA,QAClC,OAAO;AAAA,UACN,GAAG;AAAA,UACH,GAAG,QAAQ;AAAA,QACZ;AAAA,MACD,CAAC;AAED,eAAS,KAAK,OAAO;AAAA,IACtB;AAEA,SAAK,MAAM,IAAI,QAAQ;AACvB,WAAO;AAAA,EACR;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,cAA+C,SAA6B;AAC3E,WAAO,KAAK,eAAe,CAAC,OAAO,CAAC;AAAA,EACrC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,eAAe,UAAkD;AAChE,UAAM,UAAuB,CAAC;AAE9B,eAAW,WAAW,UAAU;AAC/B,UAAI,CAAC,QAAS;AAEd,YAAM,UAAU,KAAK,WAAW,QAAQ,EAAE;AAC1C,UAAI,CAAC,QAAS;AAEd,YAAM,iBAAiB,8BAA8B,SAAS,OAAO;AACrE,UAAI,mBAAmB,QAAS;AAEhC,YAAM,YAAY,KAAK,SAAS,eAAe,MAAM;AACrD,YAAM,UAAU,KAAK,SAAS,eAAe,IAAI;AACjD,UAAI,CAAC,aAAa,CAAC,QAAS;AAC5B,UAAI,CAAC,KAAK,cAAc,EAAE,WAAW,SAAS,SAAS,eAAe,CAAC,EAAG;AAE1E,cAAQ,KAAK,cAAc;AAAA,IAC5B;AAEA,SAAK,MAAM,IAAI,OAAO;AAEtB,WAAO;AAAA,EACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,cAA+C,SAA6B;AAC3E,WAAO,KAAK,eAAe,CAAC,OAAO,CAAC;AAAA,EACrC;AAAA;AAAA;AAAA;AAAA,EAKA,eAAe,UAAuC,EAAE,gBAAgB,MAAM,IAAI,CAAC,GAAG;AACrF,UAAM,MAAM,SAAS,IAAI,CAAC,YAAa,OAAO,YAAY,WAAW,UAAU,QAAQ,EAAG;AAC1F,QAAI,eAAe;AAClB,WAAK,MAAM,OAAO,MAAM;AACvB,mBAAW,MAAM,KAAK;AACrB,gBAAM,UAAU,KAAK,WAAW,EAAE;AAClC,cAAI,CAAC,QAAS;AACd,gBAAM,OAAO,KAAK,eAAe,OAAO;AACxC,eAAK,2BAA2B,EAAE,SAAS,cAAc,KAAK,SAAS,QAAQ,IAAI,EAAG,CAAC;AACvF,eAAK,yBAAyB,EAAE,SAAS,cAAc,KAAK,SAAS,QAAQ,MAAM,EAAG,CAAC;AACvF,eAAK,MAAM,OAAO,CAAC,EAAE,CAAC;AAAA,QACvB;AAAA,MACD,CAAC;AAAA,IACF,OAAO;AACN,WAAK,MAAM,OAAO,GAAG;AAAA,IACtB;AACA,WAAO;AAAA,EACR;AAAA;AAAA;AAAA;AAAA,EAIA,cAAc,SAAkC,MAA8C;AAC7F,WAAO,KAAK,eAAe,CAAC,OAAO,GAAG,IAAI;AAAA,EAC3C;AAAA,EACA,cAAc;AAAA,IACb;AAAA,IACA;AAAA,IACA;AAAA,EACD,GAIY;AACX,UAAM,gBAAgB,OAAO,cAAc,WAAW,YAAY,UAAU;AAC5E,UAAM,cAAc,OAAO,YAAY,WAAW,UAAU,QAAQ;AACpE,UAAM,cAAc,OAAO,YAAY,WAAW,UAAU,QAAQ;AAEpE,UAAM,cAAc,EAAE,eAAe,aAAa,YAAY;AAE9D,QAAI,kBAAkB,aAAa;AAClC,aAAO,KAAK,aAAa,aAAa,EAAE,QAAQ,WAAW;AAAA,IAC5D;AAEA,WACC,KAAK,aAAa,aAAa,EAAE,QAAQ,WAAW,KACpD,KAAK,aAAa,WAAW,EAAE,QAAQ,WAAW;AAAA,EAEpD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAgBA,eACC,QACA,OACA,MACO;AACP,UAAM,MACL,OAAO,OAAO,CAAC,MAAM,WACjB,SACA,OAAqB,IAAI,CAAC,MAAM,EAAE,EAAE;AAEzC,QAAI,IAAI,UAAU,EAAG,QAAO;AAE5B,UAAM,eAAW,qCAAoB,EAAE,QAAQ,MAAM,IAAI,CAAC;AAC1D,QAAI,CAAC,SAAU,QAAO;AACtB,uDAA8B;AAAA,MAC7B;AAAA,MACA;AAAA,MACA,QAAQ;AAAA,MACR,OAAO;AAAA,MACP,gBAAgB,MAAM;AAAA,IACvB,CAAC;AAED,WAAO;AAAA,EACR;AAAA,EAEQ,2BAA2B,cAAuB,gBAAkC;AAC3F,QAAI,eAAe;AACnB,UAAM,OAAO,KAAK,aAAa,YAAY;AAE3C,mBAAe;AAAA,MACd;AAAA,MACA,KAAK,mBAAmB,YAAY,KAAK;AAAA,IAC1C;AAEA,mBAAe,8BAA8B,cAAc;AAAA,MAC1D,IAAI,aAAa;AAAA,MACjB,MAAM,aAAa;AAAA,MACnB,GAAG,eAAe;AAAA,MAClB,GAAG,eAAe;AAAA,IACnB,CAAC;AAED,mBAAe;AAAA,MACd;AAAA,MACA,KAAK,cAAc,cAAc,YAAY,KAAK;AAAA,IACnD;AAEA,mBAAe;AAAA,MACd;AAAA,MACA,KAAK,iBAAiB,cAAc,YAAY,KAAK;AAAA,IACtD;AAEA,WAAO;AAAA,EACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcA,YAAY,QAAiC,QAAuB;AACnE,UAAM,MACL,OAAO,OAAO,CAAC,MAAM,WACjB,SACA,OAAqB,IAAI,CAAC,MAAM,EAAE,EAAE;AAEzC,QAAI,IAAI,UAAU,EAAG,QAAO;AAC5B,UAAM,UAA4B,CAAC;AAEnC,eAAW,MAAM,KAAK;AACrB,YAAM,QAAQ,KAAK,SAAS,EAAE;AAC9B,YAAM,aAAa,eAAI,KAAK,MAAM;AAClC,YAAM,kBAAkB,KAAK,wBAAwB,KAAK;AAC1D,UAAI,gBAAiB,YAAW,IAAI,CAAC,gBAAgB,SAAS,CAAC;AAE/D,cAAQ,KAAK,KAAK,2BAA2B,OAAO,WAAW,IAAI,KAAK,CAAC,CAAC;AAAA,IAC3E;AAEA,SAAK,aAAa,OAAO;AAEzB,WAAO;AAAA,EACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAgBA,gBAAgB,QAAiC,QAAwB;AACxE,SAAK,IAAI,MAAM;AACd,YAAM,MACL,OAAO,OAAO,CAAC,MAAM,WACjB,SACA,OAAqB,IAAI,CAAC,MAAM,EAAE,EAAE;AAEzC,UAAI,IAAI,UAAU,EAAG,QAAO;AAE5B,YAAM,aAAa,IAAI,IAAI,GAAG;AAC9B,YAAM,aAAa,KAAK,yBAAyB,GAAG;AAEpD,YAAM,kBAAkB,CAAC,GAAG,UAAU,EAAE,QAAQ;AAChD,YAAM,WAAW,oBAAI,IAA0B;AAC/C,iBAAW,WAAW,YAAY;AACjC,iBAAS,IAAI,aAAS,+BAAc,CAAC;AAAA,MACtC;AAEA,YAAM,EAAE,6BAA6B,iBAAiB,IAAI;AAAA,QACzD;AAAA,QACA;AAAA,QACA,CAAC,yBAAyB;AACzB,gBAAMC,oBAAgC,CAAC;AACvC,qBAAW,cAAc,sBAAsB;AAC9C,kBAAM,kBAAkB,KAAK,WAAW,UAAU;AAClD,gBAAI,CAAC,gBAAiB;AAEtB,kBAAM,mBAAe,iCAAgB;AACrC,YAAAA,kBAAiB,KAAK;AAAA,cACrB,GAAG;AAAA,cACH,IAAI;AAAA,cACJ,YAAQ,2BAAa,SAAS,IAAI,gBAAgB,MAAM,CAAC;AAAA,cACzD,UAAM,2BAAa,SAAS,IAAI,gBAAgB,IAAI,CAAC;AAAA,YACtD,CAAC;AAAA,UACF;AAEA,gBAAMC,+BAA4E,CAAC;AACnF,qBAAW,cAAc,iBAAiB;AACzC,kBAAM,mBAAe,2BAAa,SAAS,IAAI,UAAU,CAAC;AAC1D,kBAAM,gBAAgB,KAAK,SAAS,UAAU;AAC9C,gBAAI,CAAC,cAAe;AAEpB,gBAAI,KAAK;AACT,gBAAI,KAAK;AAET,gBAAI,UAAU,WAAW,IAAI,UAAU,GAAG;AACzC,oBAAM,kBAAkB,KAAK,wBAAwB,aAAa;AAClE,oBAAM,MAAM,IAAI,eAAI,OAAO,GAAG,OAAO,CAAC,EAAE,IAAI,CAAC,gBAAiB,SAAS,CAAC;AACxE,mBAAK,IAAI;AACT,mBAAK,IAAI;AAAA,YACV;AAEA,YAAAA,6BAA4B,KAAK;AAAA,cAChC,OAAO;AAAA,gBACN,GAAG;AAAA,gBACH,IAAI;AAAA,gBACJ,GAAG,cAAc,IAAI;AAAA,gBACrB,GAAG,cAAc,IAAI;AAAA;AAAA,gBAErB,OAAO;AAAA,gBACP,UACC,SAAS,IAAI,cAAc,QAAqB,KAAK,cAAc;AAAA,cACrE;AAAA,cACA;AAAA,YACD,CAAC;AAAA,UACF;AAEA,iBAAO,EAAE,6BAAAA,8BAA6B,kBAAAD,kBAAiB;AAAA,QACxD;AAAA,MACD;AAIA,kCAA4B,QAAQ,CAAC,EAAE,OAAO,cAAc,MAAM;AACjE,cAAM,WAAW,cAAc;AAC/B,cAAM,WAAW,KAAK,2BAA2B,QAAQ;AACzD,cAAM,eAAe,SAAS,QAAQ,cAAc,EAAE;AACtD,cAAM,iBAAiB,SAAS,eAAe,CAAC;AAChD,cAAM,eAAe,iBAAiB,KAAK,SAAS,cAAc,IAAI;AAEtE,cAAM,YAAQ,8BAAgB,cAAc,OAAO,cAAc,KAAK;AAEtE,cAAM,QAAQ;AAAA,MACf,CAAC;AACD,YAAM,iBAAiB,4BAA4B,IAAI,CAAC,EAAE,MAAM,MAAM,KAAK;AAE3E,YAAM,mBACL,eAAe,SAAS,KAAK,uBAAuB,EAAE,OAAO,KAAK,QAAQ;AAE3E,UAAI,kBAAkB;AACrB,uBAAe,IAAI;AACnB;AAAA,MACD;AAEA,WAAK,aAAa,cAAc;AAChC,WAAK,eAAe,gBAAgB;AACpC,WAAK,sBAAkB,sBAAQ,IAAI,IAAI,CAAC,OAAO,SAAS,IAAI,EAAE,CAAC,CAAC,CAAC;AAEjE,UAAI,WAAW,QAAW;AAIzB,cAAM,sBAAsB,KAAK,uBAAuB;AACxD,cAAM,qBAAqB,KAAK,sBAAsB;AACtD,YAAI,uBAAuB,CAAC,mBAAmB,SAAS,mBAAmB,GAAG;AAC7E,eAAK,cAAc,oBAAoB,QAAQ;AAAA,YAC9C,WAAW,EAAE,UAAU,KAAK,QAAQ,kBAAkB;AAAA,UACvD,CAAC;AAAA,QACF;AAAA,MACD;AAAA,IACD,CAAC;AAED,WAAO;AAAA,EACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAeA,iBAAiB,QAAiC,QAAwB;AACzE,UAAM,MACL,OAAO,OAAO,CAAC,MAAM,WACjB,SACA,OAAqB,IAAI,CAAC,MAAM,EAAE,EAAE;AAEzC,QAAI,IAAI,WAAW,EAAG,QAAO;AAC7B,QAAI,KAAK,iBAAiB,EAAE,WAAY,QAAO;AAE/C,UAAM,gBAAgB,KAAK,iBAAiB;AAE5C,QAAI,WAAW,cAAe,QAAO;AACrC,QAAI,CAAC,KAAK,MAAM,IAAI,MAAM,EAAG,QAAO;AAGpC,UAAM,UAAU,KAAK,0BAA0B,GAAG;AAGlD,QAAI,CAAC,QAAS,QAAO;AAIrB,QAAI,KAAK,gBAAgB,MAAM,EAAE,OAAO,QAAQ,OAAO,SAAS,KAAK,QAAQ,kBAAkB;AAC9F,qBAAe,MAAM,MAAM;AAC3B,aAAO;AAAA,IACR;AAEA,UAAM,YAAY,KAAK,UAAU,EAAE;AAEnC,SAAK,IAAI,MAAM;AAEd,WAAK,aAAa,GAAG;AAGrB,WAAK,eAAe,MAAM;AAK1B,WAAK,gBAAgB,IAAI;AACzB,WAAK,WAAW;AAChB,WAAK,0BAA0B,SAAS;AAAA,QACvC,QAAQ;AAAA,QACR,aAAa;AAAA,QACb,kBAAkB;AAAA,MACnB,CAAC;AAKD,WAAK,UAAU,EAAE,GAAG,KAAK,UAAU,GAAG,GAAG,UAAU,CAAC;AACpD,WAAK,cAAc,KAAK,8BAA8B,EAAG,MAAM;AAAA,IAChE,CAAC;AAED,WAAO;AAAA,EACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,WAAW,QAAuC;AACjD,UAAM,MACL,OAAO,OAAO,CAAC,MAAM,WACjB,SACA,OAAqB,IAAI,CAAC,MAAM,EAAE,EAAE;AAEzC,QAAI,KAAK,iBAAiB,EAAE,cAAc,IAAI,WAAW,EAAG,QAAO;AAEnE,QAAI,YAAY,MACf,cAAc;AACf,UAAM,iBAA4B,CAAC;AACnC,eAAW,MAAM,KAAK;AACrB,YAAM,QAAQ,KAAK,SAAS,EAAE;AAC9B,UAAI,OAAO;AACV,uBAAe,KAAK,KAAK;AACzB,YAAI,MAAM,UAAU;AACnB,wBAAc;AAAA,QACf,OAAO;AACN,sBAAY;AAAA,QACb;AAAA,MACD;AAAA,IACD;AACA,SAAK,IAAI,MAAM;AACd,UAAI,aAAa;AAChB,aAAK;AAAA,UACJ,eAAe,IAAI,CAAC,WAAW,EAAE,IAAI,MAAM,IAAI,MAAM,MAAM,MAAM,UAAU,KAAK,EAAE;AAAA,QACnF;AACA,aAAK,kBAAkB,CAAC,CAAC;AAAA,MAC1B,WAAW,WAAW;AACrB,aAAK;AAAA,UACJ,eAAe,IAAI,CAAC,WAAW,EAAE,IAAI,MAAM,IAAI,MAAM,MAAM,MAAM,UAAU,MAAM,EAAE;AAAA,QACpF;AAAA,MACD,OAAO;AACN,aAAK;AAAA,UACJ,eAAe,IAAI,CAAC,WAAW,EAAE,IAAI,MAAM,IAAI,MAAM,MAAM,MAAM,UAAU,KAAK,EAAE;AAAA,QACnF;AAAA,MACD;AAAA,IACD,CAAC;AAED,WAAO;AAAA,EACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAeA,WAAW,QAAuC;AACjD,UAAM,MACL,OAAO,OAAO,CAAC,MAAM,WACjB,SACA,OAAqB,IAAI,CAAC,MAAM,EAAE,EAAE;AACzC,UAAM,cAAU,iDAA2B,MAAM,UAAU,GAAkB;AAC7E,QAAI,QAAS,MAAK,aAAa,OAAO;AACtC,WAAO;AAAA,EACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAeA,aAAa,QAAuC;AACnD,UAAM,MACL,OAAO,OAAO,CAAC,MAAM,WACjB,SACA,OAAqB,IAAI,CAAC,MAAM,EAAE,EAAE;AACzC,UAAM,cAAU,iDAA2B,MAAM,YAAY,GAAkB;AAC/E,QAAI,QAAS,MAAK,aAAa,OAAO;AACtC,WAAO;AAAA,EACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAeA,aAAa,QAAuC;AACnD,UAAM,MACL,OAAO,OAAO,CAAC,MAAM,WACjB,SACA,OAAqB,IAAI,CAAC,MAAM,EAAE,EAAE;AACzC,UAAM,cAAU,iDAA2B,MAAM,WAAW,GAAkB;AAC9E,QAAI,QAAS,MAAK,aAAa,OAAO;AACtC,WAAO;AAAA,EACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAeA,aAAa,QAAuC;AACnD,UAAM,MACL,OAAO,OAAO,CAAC,MAAM,WACjB,SACA,OAAqB,IAAI,CAAC,MAAM,EAAE,EAAE;AACzC,UAAM,cAAU,iDAA2B,MAAM,WAAW,GAAkB;AAC9E,QAAI,QAAS,MAAK,aAAa,OAAO;AACtC,WAAO;AAAA,EACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAgBA,WAAW,QAAiC,WAA4C;AACvF,UAAM,MACL,OAAO,OAAO,CAAC,MAAM,WACjB,SACA,OAAqB,IAAI,CAAC,MAAM,EAAE,EAAE;AAEzC,QAAI,KAAK,iBAAiB,EAAE,WAAY,QAAO;AAE/C,QAAI,mBAAe,sBAAQ,IAAI,IAAI,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC,CAAC;AAE7D,QAAI,CAAC,aAAa,OAAQ,QAAO;AAEjC,uBAAe;AAAA,MACd,aACE,IAAI,CAAC,UAAU;AACf,YAAI,KAAK,cAA4B,OAAO,OAAO,GAAG;AACrD,iBAAO,KAAK,2BAA2B,MAAM,EAAE,EAAE,IAAI,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;AAAA,QAC/E;AAEA,eAAO;AAAA,MACR,CAAC,EACA,KAAK;AAAA,IACR;AAEA,UAAM,kBAAkB,eAAI;AAAA,UAC3B,sBAAQ,aAAa,IAAI,CAAC,OAAO,KAAK,mBAAmB,EAAE,CAAC,CAAC;AAAA,IAC9D,EAAE;AAEF,SAAK,IAAI,MAAM;AACd,iBAAW,SAAS,cAAc;AACjC,cAAM,SAAS,KAAK,iBAAiB,KAAK,EAAE;AAC5C,cAAM,uBAAuB,KAAK,sBAAsB,MAAM,EAAE;AAChE,YAAI,CAAC,qBAAsB;AAC3B,aAAK;AAAA,UACJ,MAAM;AAAA,UACN,EAAE,GAAG,cAAc,eAAe,KAAK,GAAG,GAAG,cAAc,aAAa,KAAK,EAAE;AAAA,UAC/E;AAAA,YACC,eAAe;AAAA,YACf;AAAA,YACA,cAAc;AAAA,YACd,MAAM;AAAA,YACN,qBAAqB,KAAK,aAAa,KAAK,EAAE,oBAAoB,KAAK;AAAA,YACvE,aAAa;AAAA,YACb,mBAAmB;AAAA,UACpB;AAAA,QACD;AAAA,MACD;AAAA,IACD,CAAC;AAED,WAAO;AAAA,EACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAiBA,YACC,QACA,WACA,KACO;AACP,UAAM,MACL,OAAO,OAAO,CAAC,MAAM,WACjB,SACA,OAAqB,IAAI,CAAC,MAAM,EAAE,EAAE;AACzC,QAAI,KAAK,iBAAiB,EAAE,WAAY,QAAO;AAE/C,UAAM,gBAAgB,IACpB,IAAI,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC,EAC7B,OAAO,CAAC,UAA4B;AACpC,UAAI,CAAC,MAAO,QAAO;AAEnB,aAAO,KAAK,aAAa,KAAK,EAAE,aAAa,KAAK;AAAA,IACnD,CAAC;AAEF,UAAM,MAAM,cAAc;AAE1B,QAAK,QAAQ,KAAK,MAAM,KAAM,MAAM,EAAG,QAAO;AAE9C,UAAM,aAAa,OAAO;AAAA,MACzB,cAAc,IAAI,CAAC,UAAU,CAAC,MAAM,IAAI,KAAK,mBAAmB,KAAK,CAAE,CAAC;AAAA,IACzE;AAEA,QAAI;AACJ,QAAI;AACJ,QAAI;AACJ,QAAI;AAEJ,QAAI,cAAc,cAAc;AAC/B,YAAM;AACN,YAAM;AACN,YAAM;AACN,YAAM;AAAA,IACP,OAAO;AACN,YAAM;AACN,YAAM;AACN,YAAM;AACN,YAAM;AAAA,IACP;AAEA,QAAI;AAEJ,QAAI,QAAQ,GAAG;AACd,YAAM,OAAyC,CAAC;AAEhD,oBAAc,KAAK,CAAC,GAAG,MAAM,WAAW,EAAE,EAAE,EAAE,GAAG,IAAI,WAAW,EAAE,EAAE,EAAE,GAAG,CAAC;AAK1E,eAAS,IAAI,GAAG,IAAI,MAAM,GAAG,KAAK;AACjC,cAAM,QAAQ,cAAc,CAAC;AAC7B,cAAM,YAAY,cAAc,IAAI,CAAC;AAErC,cAAM,SAAS,WAAW,MAAM,EAAE;AAClC,cAAM,aAAa,WAAW,UAAU,EAAE;AAE1C,cAAME,OAAM,WAAW,GAAG,IAAI,OAAO,GAAG;AAExC,cAAM,UAAU,KAAK,KAAK,CAAC,MAAM,EAAE,QAAQA,IAAG;AAE9C,YAAI,SAAS;AACZ,kBAAQ;AAAA,QACT,OAAO;AACN,eAAK,KAAK,EAAE,KAAAA,MAAK,OAAO,EAAE,CAAC;AAAA,QAC5B;AAAA,MACD;AAGA,UAAI,WAAW;AACf,WAAK,QAAQ,CAAC,MAAM;AACnB,YAAI,EAAE,QAAQ,UAAU;AACvB,qBAAW,EAAE;AACb,qBAAW,EAAE;AAAA,QACd;AAAA,MACD,CAAC;AAGD,UAAI,aAAa,GAAG;AACnB,mBAAW,KAAK,IAAI,GAAG,KAAK,OAAO,CAAC,GAAG,MAAM,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,KAAK,MAAM,EAAE;AAAA,MACjF;AAAA,IACD,OAAO;AAEN,iBAAW;AAAA,IACZ;AAEA,UAAM,UAA4B,CAAC;AAEnC,QAAI,IAAI,WAAW,cAAc,CAAC,EAAE,EAAE,EAAE,GAAG;AAE3C,kBAAc,QAAQ,CAAC,OAAO,MAAM;AACnC,UAAI,MAAM,EAAG;AAEb,YAAM,QAAQ,EAAE,GAAG,GAAG,GAAG,EAAE;AAC3B,YAAM,GAAG,IAAI,IAAI,WAAW,WAAW,MAAM,EAAE,EAAE,GAAG;AAEpD,YAAM,SAAS,KAAK,eAAe,KAAK;AACxC,YAAM,aAAa,SAChB,eAAI,IAAI,OAAO,CAAC,KAAK,sBAAsB,MAAM,EAAG,UAAU,EAAE,QAAQ,IACxE;AAEH,YAAM,wBAAwB,KAAK,aAAa,KAAK,EAAE,mBAAmB,KAAK;AAE/E,cAAQ;AAAA,QACP,wBACG;AAAA,UACA,GAAG;AAAA,UACH,CAAC,GAAG,GAAG,MAAM,GAAG,IAAI,WAAW,GAAG;AAAA,QACnC,IACC;AAAA,UACA,IAAI,MAAM;AAAA,UACV,MAAM,MAAM;AAAA,UACZ,CAAC,GAAG,GAAG,MAAM,GAAG,IAAI,WAAW,GAAG;AAAA,QACnC;AAAA,MACH;AAEA,WAAK,WAAW,MAAM,EAAE,EAAE,GAAG,IAAI;AAAA,IAClC,CAAC;AAED,SAAK,aAAa,OAAO;AACzB,WAAO;AAAA,EACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAeA,WAAW,QAAiC,KAAmB;AAC9D,UAAM,MACL,OAAO,OAAO,CAAC,MAAM,WACjB,SACA,OAAqB,IAAI,CAAC,MAAM,EAAE,EAAE;AAEzC,QAAI,KAAK,iBAAiB,EAAE,WAAY,QAAO;AAC/C,QAAI,IAAI,SAAS,EAAG,QAAO;AAE3B,UAAM,eAAe,IACnB,IAAI,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC,EAC7B,OAAO,CAACR,WAA4B;AACpC,UAAI,CAACA,OAAO,QAAO;AAEnB,aAAO,KAAK,aAAaA,MAAK,EAAE,aAAaA,MAAK;AAAA,IACnD,CAAC;AACF,UAAM,kBAAuC,CAAC;AAC9C,UAAM,sBAA2C,CAAC;AAElD,QAAI,OACH,QACA,OAAO;AAER,aAAS,IAAI,GAAG,IAAI,aAAa,QAAQ,KAAK;AAC7C,cAAQ,aAAa,CAAC;AACtB,eAAS,KAAK,mBAAmB,KAAK;AACtC,sBAAgB,MAAM,EAAE,IAAI;AAC5B,0BAAoB,MAAM,EAAE,IAAI,OAAO,MAAM;AAC7C,cAAQ,OAAO,QAAQ,OAAO;AAAA,IAC/B;AAEA,UAAM,eAAe,eAAI,WAAO,sBAAQ,OAAO,OAAO,eAAe,CAAC,CAAC;AAEvE,UAAM,WAAW,aAAa;AAG9B,iBAAa,KAAK,CAAC,GAAG,MAAM,gBAAgB,EAAE,EAAE,EAAE,SAAS,gBAAgB,EAAE,EAAE,EAAE,MAAM;AAGvF,UAAM,aAAa,KAAK,IAAI,KAAK,KAAK,KAAK,KAAK,OAAO,IAAI,CAAC,GAAG,QAAQ;AAGvE,UAAM,SAAgB,CAAC,IAAI,eAAI,aAAa,GAAG,aAAa,GAAG,YAAY,QAAQ,CAAC;AAEpF,QAAI,QAAQ;AACZ,QAAI,SAAS;AACb,QAAI;AACJ,QAAIS;AAEJ,aAAS,IAAI,GAAG,IAAI,aAAa,QAAQ,KAAK;AAC7C,cAAQ,aAAa,CAAC;AACtB,eAAS,oBAAoB,MAAM,EAAE;AAGrC,eAASC,KAAI,OAAO,SAAS,GAAGA,MAAK,GAAGA,MAAK;AAC5C,gBAAQ,OAAOA,EAAC;AAGhB,YAAI,OAAO,QAAQ,MAAM,SAAS,OAAO,SAAS,MAAM,OAAQ;AAGhE,eAAO,IAAI,MAAM;AACjB,eAAO,IAAI,MAAM;AAEjB,iBAAS,KAAK,IAAI,QAAQ,OAAO,IAAI;AACrC,gBAAQ,KAAK,IAAI,OAAO,OAAO,IAAI;AAEnC,YAAI,OAAO,UAAU,MAAM,SAAS,OAAO,WAAW,MAAM,QAAQ;AAEnE,UAAAD,QAAO,OAAO,IAAI;AAClB,cAAIC,KAAI,OAAO,OAAQ,QAAOA,EAAC,IAAID;AAAA,QACpC,WAAW,OAAO,WAAW,MAAM,QAAQ;AAE1C,gBAAM,KAAK,OAAO,QAAQ;AAC1B,gBAAM,SAAS,OAAO,QAAQ;AAAA,QAC/B,WAAW,OAAO,UAAU,MAAM,OAAO;AAExC,gBAAM,KAAK,OAAO,SAAS;AAC3B,gBAAM,UAAU,OAAO,SAAS;AAAA,QACjC,OAAO;AAEN,iBAAO;AAAA,YACN,IAAI;AAAA,cACH,MAAM,KAAK,OAAO,QAAQ;AAAA,cAC1B,MAAM;AAAA,cACN,MAAM,SAAS,OAAO,QAAQ;AAAA,cAC9B,OAAO;AAAA,YACR;AAAA,UACD;AACA,gBAAM,KAAK,OAAO,SAAS;AAC3B,gBAAM,UAAU,OAAO,SAAS;AAAA,QACjC;AACA;AAAA,MACD;AAAA,IACD;AAEA,UAAM,cAAc,eAAI,OAAO,OAAO,OAAO,mBAAmB,CAAC;AACjE,UAAM,cAAc,eAAI,IAAI,aAAa,QAAQ,YAAY,MAAM;AAEnE,QAAI;AAEJ,UAAM,UAAiC,CAAC;AAExC,aAAS,IAAI,GAAG,IAAI,aAAa,QAAQ,KAAK;AAC7C,cAAQ,aAAa,CAAC;AACtB,eAAS,gBAAgB,MAAM,EAAE;AACjC,mBAAa,oBAAoB,MAAM,EAAE;AAEzC,YAAM,QAAQ,eAAI,IAAI,WAAW,OAAO,OAAO,KAAK,EAAE,IAAI,WAAW;AACrE,YAAM,kBAAkB,KAAK,wBAAwB,KAAK;AAC1D,UAAI,gBAAiB,OAAM,IAAI,CAAC,gBAAgB,SAAS,CAAC;AAE1D,YAAM,SAAyB;AAAA,QAC9B,IAAI,MAAM;AAAA,QACV,MAAM,MAAM;AAAA,QACZ,GAAG,MAAM,IAAI,MAAM;AAAA,QACnB,GAAG,MAAM,IAAI,MAAM;AAAA,MACpB;AAEA,YAAM,uBAAuB,KAAK,aAAa,KAAK,EAAE,mBAAmB;AAAA,QACxE,GAAG;AAAA,QACH,GAAG;AAAA,MACJ,CAAC;AAED,UAAI,sBAAsB;AACzB,gBAAQ,KAAK,EAAE,GAAG,QAAQ,GAAG,qBAAqB,CAAC;AAAA,MACpD,OAAO;AACN,gBAAQ,KAAK,MAAM;AAAA,MACpB;AAAA,IACD;AAEA,QAAI,QAAQ,QAAQ;AACnB,WAAK,aAAa,OAAO;AAAA,IAC1B;AAEA,WAAO;AAAA,EACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAiBA,YACC,QACA,WACO;AACP,UAAM,MACL,OAAO,OAAO,CAAC,MAAM,WACjB,SACA,OAAqB,IAAI,CAAC,MAAM,EAAE,EAAE;AAEzC,QAAI,KAAK,iBAAiB,EAAE,WAAY,QAAO;AAC/C,QAAI,IAAI,SAAS,EAAG,QAAO;AAE3B,UAAM,oBAAgB,sBAAQ,IAAI,IAAI,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC,CAAC;AAChE,UAAM,kBAAkB,OAAO;AAAA,MAC9B,cAAc,IAAI,CAAC,UAAU,CAAC,MAAM,IAAI,KAAK,mBAAmB,KAAK,CAAC,CAAC;AAAA,IACxE;AACA,UAAM,eAAe,eAAI,WAAO,sBAAQ,OAAO,OAAO,eAAe,CAAC,CAAC;AAEvE,UAAM,UAA4B,CAAC;AAEnC,kBAAc,QAAQ,CAAC,UAAU;AAChC,YAAM,aAAa,gBAAgB,MAAM,EAAE;AAC3C,UAAI,CAAC,WAAY;AAEjB,YAAM,QAAQ,EAAE,GAAG,GAAG,GAAG,EAAE;AAE3B,cAAQ,WAAW;AAAA,QAClB,KAAK,OAAO;AACX,gBAAM,IAAI,aAAa,OAAO,WAAW;AACzC;AAAA,QACD;AAAA,QACA,KAAK,mBAAmB;AACvB,gBAAM,IAAI,aAAa,OAAO,WAAW,OAAO,WAAW,SAAS;AACpE;AAAA,QACD;AAAA,QACA,KAAK,UAAU;AACd,gBAAM,IAAI,aAAa,OAAO,WAAW,OAAO,WAAW;AAC3D;AAAA,QACD;AAAA,QACA,KAAK,QAAQ;AACZ,gBAAM,IAAI,aAAa,OAAO,WAAW;AACzC;AAAA,QACD;AAAA,QACA,KAAK,qBAAqB;AACzB,gBAAM,IAAI,aAAa,OAAO,WAAW,OAAO,WAAW,QAAQ;AACnE;AAAA,QACD;AAAA,QACA,KAAK,SAAS;AACb,gBAAM,IAAI,aAAa,OAAO,WAAW,OAAO,WAAW;AAC3D;AAAA,QACD;AAAA,MACD;AAEA,YAAM,SAAS,KAAK,eAAe,KAAK;AACxC,YAAM,aAAa,SAChB,eAAI,IAAI,OAAO,CAAC,KAAK,sBAAsB,MAAM,EAAG,UAAU,EAAE,QAAQ,IACxE;AAEH,cAAQ,KAAK,KAAK,2BAA2B,OAAO,eAAI,IAAI,OAAO,UAAU,CAAC,CAAC;AAAA,IAChF,CAAC;AAED,SAAK,aAAa,OAAO;AACzB,WAAO;AAAA,EACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAgBA,iBAAiB,QAAiC,WAA4C;AAC7F,UAAM,MACL,OAAO,OAAO,CAAC,MAAM,WACjB,SACA,OAAqB,IAAI,CAAC,MAAM,EAAE,EAAE;AAEzC,QAAI,KAAK,iBAAiB,EAAE,WAAY,QAAO;AAC/C,QAAI,IAAI,SAAS,EAAG,QAAO;AAE3B,UAAM,MAAM,IAAI;AAChB,UAAM,yBAAqB,sBAAQ,IAAI,IAAI,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC,CAAC;AACrE,UAAM,aAAa,OAAO;AAAA,MACzB,mBAAmB,IAAI,CAAC,UAAU,CAAC,MAAM,IAAI,KAAK,mBAAmB,KAAK,CAAE,CAAC;AAAA,IAC9E;AAEA,QAAI;AACJ,QAAI;AACJ,QAAI;AACJ,QAAI;AACJ,QAAI;AAEJ,QAAI,cAAc,cAAc;AAC/B,YAAM;AACN,YAAM;AACN,YAAM;AACN,YAAM;AACN,YAAM;AAAA,IACP,OAAO;AACN,YAAM;AACN,YAAM;AACN,YAAM;AACN,YAAM;AACN,YAAM;AAAA,IACP;AACA,UAAM,UAA4B,CAAC;AAGnC,UAAM,QAAQ,mBAAmB;AAAA,MAChC,CAAC,GAAG,MAAM,WAAW,EAAE,EAAE,EAAE,GAAG,IAAI,WAAW,EAAE,EAAE,EAAE,GAAG;AAAA,IACvD,EAAE,CAAC;AACH,UAAMA,QAAO,mBAAmB,KAAK,CAAC,GAAG,MAAM,WAAW,EAAE,EAAE,EAAE,GAAG,IAAI,WAAW,EAAE,EAAE,EAAE,GAAG,CAAC,EAAE,CAAC;AAE/F,UAAM,WAAW,WAAW,MAAM,EAAE,EAAE,GAAG;AACzC,UAAM,QAAQ,WAAWA,MAAK,EAAE,EAAE,GAAG,IAAI,aAAa,MAAM;AAC5D,UAAM,IAAI,WAAW;AAErB,uBACE,OAAO,CAAC,UAAU,UAAU,SAAS,UAAUA,KAAI,EACnD,KAAK,CAAC,GAAG,MAAM,WAAW,EAAE,EAAE,EAAE,GAAG,IAAI,WAAW,EAAE,EAAE,EAAE,GAAG,CAAC,EAC5D,QAAQ,CAAC,OAAO,MAAM;AACtB,YAAM,QAAQ,EAAE,GAAG,GAAG,GAAG,EAAE;AAC3B,YAAM,GAAG,IAAI,IAAI,OAAO,IAAI,WAAW,MAAM,EAAE,EAAE,GAAG,IAAI,IAAI,WAAW,MAAM,EAAE,EAAE,GAAG;AAEpF,YAAM,SAAS,KAAK,eAAe,KAAK;AACxC,YAAM,aAAa,SAChB,eAAI,IAAI,OAAO,CAAC,KAAK,sBAAsB,MAAM,EAAG,SAAS,CAAC,IAC9D;AAEH,cAAQ,KAAK,KAAK,2BAA2B,OAAO,eAAI,IAAI,OAAO,UAAU,CAAC,CAAC;AAAA,IAChF,CAAC;AAEF,SAAK,aAAa,OAAO;AACzB,WAAO;AAAA,EACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAgBA,cAAc,QAAiC,WAA4C;AAC1F,UAAM,MACL,OAAO,OAAO,CAAC,MAAM,WACjB,SACA,OAAqB,IAAI,CAAC,MAAM,EAAE,EAAE;AAEzC,QAAI,KAAK,iBAAiB,EAAE,WAAY,QAAO;AAC/C,QAAI,IAAI,SAAS,EAAG,QAAO;AAE3B,UAAM,sBAAkB,sBAAQ,IAAI,IAAI,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC,CAAC;AAClE,UAAM,cAAc,OAAO,YAAY,IAAI,IAAI,CAAC,OAAO,CAAC,IAAI,KAAK,iBAAiB,EAAE,EAAE,MAAM,CAAC,CAAC;AAC9F,UAAM,kBAAkB,OAAO,YAAY,IAAI,IAAI,CAAC,OAAO,CAAC,IAAI,KAAK,mBAAmB,EAAE,CAAE,CAAC,CAAC;AAC9F,UAAM,eAAe,eAAI,WAAO,sBAAQ,OAAO,OAAO,eAAe,CAAC,CAAC;AAEvE,YAAQ,WAAW;AAAA,MAClB,KAAK,YAAY;AAChB,aAAK,IAAI,MAAM;AACd,qBAAW,SAAS,iBAAiB;AACpC,kBAAM,eAAe,KAAK,sBAAsB,KAAK,EAAG,SAAS;AACjE,gBAAI,eAAe,kBAAK;AACxB,kBAAM,SAAS,YAAY,MAAM,EAAE;AACnC,kBAAM,aAAa,gBAAgB,MAAM,EAAE;AAC3C,kBAAM,cAAc,IAAI,eAAI,GAAG,aAAa,OAAO,WAAW,IAAI;AAClE,kBAAM,kBAAkB,KAAK,wBAAwB,KAAK;AAC1D,gBAAI,gBAAiB,aAAY,IAAI,CAAC,gBAAgB,SAAS,CAAC;AAEhE,kBAAM,EAAE,GAAG,EAAE,IAAI,eAAI,IAAI,aAAa,KAAK;AAC3C,iBAAK,aAAa,CAAC,EAAE,IAAI,MAAM,IAAI,MAAM,MAAM,MAAM,GAAG,EAAE,CAAC,CAAC;AAC5D,kBAAM,QAAQ,IAAI,eAAI,GAAG,aAAa,SAAS,WAAW,MAAM;AAChE,iBAAK,YAAY,MAAM,IAAI,OAAO;AAAA,cACjC,eAAe;AAAA,cACf,aAAa,IAAI,eAAI,WAAW,OAAO,GAAG,aAAa,IAAI;AAAA,cAC3D,qBAAqB,KAAK,aAAa,KAAK,EAAE,oBAAoB,KAAK;AAAA,cACvE,mBAAmB;AAAA,YACpB,CAAC;AAAA,UACF;AAAA,QACD,CAAC;AACD;AAAA,MACD;AAAA,MACA,KAAK,cAAc;AAClB,aAAK,IAAI,MAAM;AACd,qBAAW,SAAS,iBAAiB;AACpC,kBAAM,SAAS,YAAY,MAAM,EAAE;AACnC,kBAAM,aAAa,gBAAgB,MAAM,EAAE;AAC3C,kBAAM,eAAe,KAAK,sBAAsB,KAAK,EAAG,SAAS;AACjE,gBAAI,eAAe,kBAAK;AACxB,kBAAM,cAAc,IAAI,eAAI,aAAa,OAAO,WAAW,MAAM,CAAC;AAClE,kBAAM,kBAAkB,KAAK,wBAAwB,KAAK;AAC1D,gBAAI,gBAAiB,aAAY,IAAI,CAAC,gBAAgB,SAAS,CAAC;AAEhE,kBAAM,EAAE,GAAG,EAAE,IAAI,eAAI,IAAI,aAAa,KAAK;AAC3C,iBAAK,aAAa,CAAC,EAAE,IAAI,MAAM,IAAI,MAAM,MAAM,MAAM,GAAG,EAAE,CAAC,CAAC;AAC5D,kBAAM,QAAQ,IAAI,eAAI,aAAa,QAAQ,WAAW,OAAO,CAAC;AAC9D,iBAAK,YAAY,MAAM,IAAI,OAAO;AAAA,cACjC,eAAe;AAAA,cACf,aAAa,IAAI,eAAI,aAAa,MAAM,WAAW,OAAO,CAAC;AAAA,cAC3D,qBAAqB,KAAK,aAAa,KAAK,EAAE,oBAAoB,KAAK;AAAA,cACvE,mBAAmB;AAAA,YACpB,CAAC;AAAA,UACF;AAAA,QACD,CAAC;AAED;AAAA,MACD;AAAA,IACD;AAEA,WAAO;AAAA,EACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,YACC,OACA,OACA,UAAgC,CAAC,GAC1B;AACP,UAAM,KAAK,OAAO,UAAU,WAAW,QAAQ,MAAM;AACrD,QAAI,KAAK,iBAAiB,EAAE,WAAY,QAAO;AAE/C,QAAI,CAAC,OAAO,SAAS,MAAM,CAAC,EAAG,SAAQ,IAAI,eAAI,GAAG,MAAM,CAAC;AACzD,QAAI,CAAC,OAAO,SAAS,MAAM,CAAC,EAAG,SAAQ,IAAI,eAAI,MAAM,GAAG,CAAC;AAEzD,UAAM,eAAe,QAAQ,gBAAgB,KAAK,SAAS,EAAE;AAC7D,QAAI,CAAC,aAAc,QAAO;AAE1B,UAAM,cAAc,QAAQ,eAAe,KAAK,mBAAmB,EAAE,GAAG;AACxE,QAAI,CAAC,YAAa,QAAO;AAEzB,UAAM,gBAAgB,QAAQ,uBAC3B,eAAI,KAAK,QAAQ,oBAAoB,IACrC,KAAK,sBAAsB,EAAE;AAChC,QAAI,CAAC,cAAe,QAAO;AAE3B,UAAM,eAAe,cAAc,SAAS;AAE5C,QAAI,gBAAgB,KAAM,QAAO;AAEjC,UAAM,oBAAoB,QAAQ,qBAAqB;AAEvD,UAAM,gBAAgB,QAAQ,iBAAiB,KAAK,iBAAiB,EAAE,EAAE;AAEzE,QAAI,CAAC,cAAe,QAAO;AAE3B,UAAM,sBACL,QAAQ,uBACR,KAAK,aAAa,YAAY,EAAE,oBAAoB,YAAY;AAEjE,QAAI,KAAC,mCAAoB,cAAc,iBAAiB,GAAG;AAK1D,aAAO,KAAK,sBAAsB,IAAI,OAAO;AAAA,QAC5C,GAAG;AAAA,QACH;AAAA,QACA;AAAA,QACA;AAAA,QACA,sBAAsB;AAAA,QACtB;AAAA,QACA;AAAA,MACD,CAAC;AAAA,IACF;AAEA,UAAM,OAAO,KAAK,aAAa,YAAY;AAE3C,QAAI,qBAAqB;AACxB,UAAI,KAAK,IAAI,MAAM,CAAC,IAAI,KAAK,IAAI,MAAM,CAAC,GAAG;AAC1C,gBAAQ,IAAI,eAAI,MAAM,GAAG,KAAK,KAAK,MAAM,CAAC,IAAI,KAAK,IAAI,MAAM,CAAC,CAAC;AAAA,MAChE,OAAO;AACN,gBAAQ,IAAI,eAAI,KAAK,KAAK,MAAM,CAAC,IAAI,KAAK,IAAI,MAAM,CAAC,GAAG,MAAM,CAAC;AAAA,MAChE;AAAA,IACD;AAEA,QAAI,KAAK,YAAY,KAAK,UAAU,YAAY,GAAG;AAElD,YAAM,eAAe,KAAK;AAAA,QACzB,eAAI,aAAa,eAAe,IAAI,eAAI,GAAG,CAAC,CAAC;AAAA,QAC7C;AAAA,QACA;AAAA,QACA;AAAA,MACD;AAEA,YAAM,gBAAgB,KAAK,sBAAsB,aAAa,IAAI,YAAY;AAG9E,YAAM,UAAU,IAAI,eAAI,MAAM,GAAG,MAAM,CAAC;AAIxC,YAAM,8CAA0C;AAAA,SAC9C,eAAe,qBAAqB,KAAK;AAAA,QAC1C;AAAA,MACD;AACA,cAAQ,IAAI,0CAA0C,MAAM,IAAI,MAAM;AACtE,cAAQ,IAAI,0CAA0C,MAAM,IAAI,MAAM;AAItE,YAAM,mBAAmB,eAAI,aAAa,eAAe,IAAI,eAAI,CAAC;AAGlE,YAAM,EAAE,GAAG,EAAE,IAAI,KAAK,sBAAsB,aAAa,IAAI,gBAAgB;AAE7E,UAAI,eAAe;AACnB,UAAI,CAAC,QAAQ,0BAA0B;AACtC,uBAAe;AAAA,UACd;AAAA,UACA,KAAK,gBAAgB,YAAY,KAAK;AAAA,QACvC;AAAA,MACD;AAEA,qBAAe,8BAA8B,cAAc;AAAA,QAC1D;AAAA,QACA,MAAM,aAAa;AAAA,QACnB,GAAG,cAAc;AAAA,QACjB,GAAG,cAAc;AAAA,QACjB,GAAG,KAAK;AAAA,UACP,EAAE,GAAG,cAAc,GAAG,EAAE;AAAA,UACxB;AAAA,YACC,UAAU;AAAA,YACV,QAAQ,QAAQ,cAAc;AAAA;AAAA,YAE9B,MAAM,QAAQ,QAAQ;AAAA,YACtB,QAAQ,QAAQ;AAAA,YAChB,QAAQ,QAAQ;AAAA,YAChB;AAAA,YACA;AAAA,UACD;AAAA,QACD;AAAA,MACD,CAAC;AAED,UAAI,CAAC,QAAQ,0BAA0B;AACtC,uBAAe;AAAA,UACd;AAAA,UACA,KAAK,cAAc,cAAc,YAAY,KAAK;AAAA,QACnD;AAAA,MACD;AAEA,WAAK,aAAa,CAAC,YAAY,CAAC;AAAA,IACjC,OAAO;AACN,YAAM,oBAAoB,eAAI,aAAa,eAAe,cAAc,MAAM;AAE9E,YAAM,gBAAgB,KAAK;AAAA,QAC1B;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACD;AAEA,YAAM,iCAAiC,KAAK;AAAA,QAC3C,aAAa;AAAA,QACb;AAAA,MACD;AACA,YAAM,6BAA6B,KAAK,sBAAsB,aAAa,IAAI,aAAa;AAE5F,YAAM,QAAQ,eAAI,IAAI,4BAA4B,8BAA8B;AAEhF,WAAK,aAAa;AAAA,QACjB;AAAA,UACC;AAAA,UACA,MAAM,aAAa;AAAA,UACnB,GAAG,aAAa,IAAI,MAAM;AAAA,UAC1B,GAAG,aAAa,IAAI,MAAM;AAAA,QAC3B;AAAA,MACD,CAAC;AAAA,IACF;AAEA,WAAO;AAAA,EACR;AAAA;AAAA,EAGQ,gBACP,OACA,aACA,OACA,mBACC;AACD,UAAM,gBAAgB,eAAI,QAAQ,OAAO,aAAa,CAAC,iBAAiB,EAAE,IAAI,WAAW;AAGzF,UAAM,uBAAuB,eAAI,KAAK,eAAe,KAAK;AAG1D,UAAM,cAAc,eAAI,IAAI,sBAAsB,WAAW,EAAE;AAAA,MAC9D;AAAA,MACA;AAAA,IACD;AAEA,WAAO;AAAA,EACR;AAAA;AAAA,EAGQ,sBACP,IACA,OACA,SAQC;AACD,UAAM,EAAE,KAAK,IAAI,QAAQ;AAMzB,UAAM,aAAa,IAAI,eAAI,MAAM,GAAG,MAAM,CAAC;AAI3C,QAAI,KAAK,IAAI,MAAM,CAAC,IAAI,KAAK,IAAI,MAAM,CAAC,GAAG;AAC1C,iBAAW,IAAI,KAAK,KAAK,MAAM,CAAC,IAAI,KAAK,IAAI,MAAM,CAAC;AAAA,IACrD,OAAO;AACN,iBAAW,IAAI,KAAK,KAAK,MAAM,CAAC,IAAI,KAAK,IAAI,MAAM,CAAC;AAAA,IACrD;AAGA,SAAK,YAAY,IAAI,YAAY;AAAA,MAChC,cAAc,QAAQ;AAAA,MACtB,eAAe,QAAQ;AAAA,MACvB,qBAAqB,QAAQ;AAAA,IAC9B,CAAC;AAID,QAAI,KAAK,KAAK,MAAM,CAAC,IAAI,KAAK,KAAK,MAAM,CAAC,IAAI,GAAG;AAChD,UAAI,EAAE,SAAS,IAAI,eAAI,UAAU,QAAQ,oBAAoB;AAC7D,kBAAY,IAAI;AAChB,WAAK,aAAa,CAAC,EAAE,IAAI,MAAM,SAAS,CAAC,CAAC;AAAA,IAC3C;AAIA,UAAM,0BAA0B,eAAI;AAAA,MACnC,QAAQ;AAAA,MACR,QAAQ,cAAc;AAAA,IACvB;AAGA,UAAM,2BAA2B,KAAK;AAAA,MACrC;AAAA,MACA,QAAQ;AAAA,MACR;AAAA,MACA,QAAQ;AAAA,IACT;AAGA,UAAM,aAAa,KAAK,mBAAmB,EAAE;AAC7C,UAAM,gBAAgB,KAAK,sBAAsB,EAAE;AACnD,UAAM,oBAAoB,WAAW;AACrC,UAAM,2BAA2B,cAAc,MAAM;AACrD,QAAI,CAAC,qBAAqB,CAAC,yBAA0B,QAAO;AAC5D,UAAM,YAAY,eAAI,IAAI,0BAA0B,iBAAiB;AAGrE,UAAM,0BAA0B,eAAI,IAAI,0BAA0B,SAAS;AAC3E,UAAM,EAAE,GAAG,EAAE,IAAI,KAAK,sBAAsB,IAAI,uBAAuB;AAEvE,SAAK,aAAa,CAAC,EAAE,IAAI,MAAM,GAAG,EAAE,CAAC,CAAC;AAEtC,WAAO;AAAA,EACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAkBA,uBAAuB,QAA6B;AACnD,WAAO,CAAC;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAeA,YAAsC,OAAoD;AACzF,SAAK,aAAa,CAAC,KAAK,CAAC;AACzB,WAAO;AAAA,EACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAgBA,aAAuC,QAAuD;AAC7F,QAAI,CAAC,MAAM,QAAQ,MAAM,GAAG;AAC3B,YAAM,MAAM,wEAAwE;AAAA,IACrF;AACA,QAAI,KAAK,iBAAiB,EAAE,WAAY,QAAO;AAC/C,QAAI,OAAO,UAAU,EAAG,QAAO;AAE/B,UAAM,sBAAsB,KAAK,uBAAuB;AAExD,UAAM,mBACL,OAAO,SAAS,oBAAoB,OAAO,KAAK,QAAQ;AAEzD,QAAI,kBAAkB;AAErB,qBAAe,IAAI;AACnB,aAAO;AAAA,IACR;AAEA,UAAM,iBAAiB,KAAK,kBAAkB;AAE9C,SAAK,IAAI,MAAM;AAOd,YAAM,0BAA0B,KAAK,2BAA2B;AAEhE,YAAM,WAAW,OAAO,IAAI,CAAC,YAAY;AACxC,YAAI,CAAC,QAAQ,IAAI;AAChB,oBAAU,EAAE,QAAI,+BAAc,GAAG,GAAG,QAAQ;AAAA,QAC7C;AAOA,YACC,CAAC,QAAQ,YACT,EAAE,KAAK,MAAM,IAAI,QAAQ,QAAQ,KAAK,OAAO,KAAK,CAAC,MAAM,EAAE,OAAO,QAAQ,QAAQ,IACjF;AACD,cAAI,WAAuB,KAAK,kBAAkB;AAElD,mBAAS,IAAI,wBAAwB,SAAS,GAAG,KAAK,GAAG,KAAK;AAC7D,kBAAM,SAAS,wBAAwB,CAAC;AACxC,gBACC,CAAC,KAAK,cAAc,MAAM,KAC1B,KAAK,aAAa,MAAM,EAAE,4BAA4B,QAAQ,QAAQ,IAAI,KAC1E,KAAK;AAAA,cACJ;AAAA;AAAA;AAAA,cAGA,EAAE,GAAG,QAAQ,KAAK,GAAG,GAAG,QAAQ,KAAK,EAAE;AAAA,cACvC;AAAA,gBACC,QAAQ;AAAA,gBACR,WAAW;AAAA,cACZ;AAAA,YACD,GACC;AACD,yBAAW,OAAO;AAClB;AAAA,YACD;AAAA,UACD;AAEA,gBAAM,eAAe,QAAQ;AAG7B,cAAI,aAAa,QAAQ,IAAI;AAC5B,uBAAW;AAAA,UACZ;AAGA,cAAI,aAAa,cAAc;AAC9B,sBAAU,EAAE,GAAG,QAAQ;AAEvB,oBAAQ,WAAW;AAKnB,oBAAI,2BAAU,QAAQ,GAAG;AACxB,oBAAM,QAAQ,KAAK,qBAAqB,KAAK,SAAS,QAAQ,GAAI;AAAA,gBACjE,GAAG,QAAQ,KAAK;AAAA,gBAChB,GAAG,QAAQ,KAAK;AAAA,cACjB,CAAC;AACD,sBAAQ,IAAI,MAAM;AAClB,sBAAQ,IAAI,MAAM;AAClB,sBAAQ,WACP,CAAC,KAAK,sBAAsB,QAAQ,EAAG,SAAS,KAAK,QAAQ,YAAY;AAAA,YAC3E;AAAA,UACD;AAAA,QACD;AAEA,eAAO;AAAA,MACR,CAAC;AAOD,YAAM,gBAAgB,oBAAI,IAA0B;AAEpD,YAAM,uBAAkC,CAAC;AAEzC,YAAM,EAAE,oBAAoB,IAAI,KAAK,iBAAiB;AAEtD,iBAAW,WAAW,UAAU;AAC/B,cAAM,OAAO,KAAK,aAAa,OAAyB;AAMxD,YAAI,QAAQ,QAAQ;AAEpB,YAAI,CAAC,OAAO;AAMX,gBAAM,WAAW,QAAQ,YAAY;AAErC,cAAI,CAAC,cAAc,IAAI,QAAQ,GAAG;AACjC,0BAAc,IAAI,UAAU,KAAK,yBAAyB,QAAQ,CAAC;AAAA,UACpE;AACA,kBAAQ,cAAc,IAAI,QAAQ;AAClC,wBAAc,IAAI,cAAU,4BAAc,KAAK,CAAC;AAAA,QACjD;AAGA,cAAM,eAAe,KAAK,gBAAgB;AAI1C,mBAAW,CAAC,OAAO,OAAO,KAAK,KAAK,WAAW,QAAQ,IAAI,GAAG;AAC7D;AAAC,UAAC,aAAqB,OAAO,IAAI,KAAK,qBAAqB,KAAK;AAAA,QAClE;AAIA,YAAI,sBACH,KAAK,MAAM,OAAO,MAAM,MAIvB,OAAO;AAAA,UACR,GAAG;AAAA,UACH;AAAA,UACA,SAAS,QAAQ,WAAW;AAAA,UAC5B,UAAU,QAAQ,YAAY;AAAA,UAC9B,OAAO,WAAW,UAAU,EAAE,GAAG,cAAc,GAAG,QAAQ,MAAM,IAAI;AAAA,QACrE,CAAC;AAED,YAAI,oBAAoB,UAAU,QAAW;AAC5C,gBAAM,MAAM,WAAW;AAAA,QACxB;AAEA,cAAM,OAAO,KAAK,aAAa,mBAAmB,EAAE,iBAAiB,mBAAmB;AAExF,YAAI,MAAM;AACT,gCAAsB;AAAA,QACvB;AAEA,6BAAqB,KAAK,mBAAmB;AAAA,MAC9C;AAGA,2BAAqB,QAAQ,CAAC,UAAU;AACvC,cAAM,OAAO;AAAA,UACZ,GAAG,KAAK,uBAAuB,KAAK;AAAA,UACpC,GAAG,MAAM;AAAA,QACV;AAAA,MACD,CAAC;AAED,WAAK,MAAM,IAAI,oBAAoB;AAAA,IACpC,CAAC;AAED,WAAO;AAAA,EACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAkBA,aACC,SACA,OAAO,EAAE,WAAW,2CAA0B,GACvC;AACP,WAAO,KAAK,cAAc,CAAC,OAAO,GAAG,IAAI;AAAA,EAC1C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAgBA,cACC,UACA,OAAO,EAAE,WAAW,2CAA0B,GACvC;AACP,QAAI,CAAC,KAAK,UAAW,QAAO;AAC5B,UAAM,EAAE,WAAW,KAAK,SAAS,uBAAQ,OAAO,IAAI,KAAK;AAEzD,UAAM,kBAAc,uBAAS;AAE7B,QAAI,YAAY;AAChB,QAAI;AAOJ,UAAM,aAA+B,CAAC;AAEtC,QAAI,SAA4C;AAChD,aAAS,IAAI,GAAG,IAAI,SAAS,QAAQ,IAAI,GAAG,KAAK;AAChD,gBAAU,SAAS,CAAC;AACpB,UAAI,CAAC,QAAS;AAEd,YAAM,QAAQ,KAAK,SAAS,QAAQ,EAAE;AACtC,UAAI,CAAC,MAAO;AAEZ,eAAS;AAAA,QACR,WAAO,8BAAgB,KAAK;AAAA,QAC5B,KAAK,kCAA8B,8BAAgB,KAAK,GAAG,OAAO;AAAA,MACnE;AAEA,iBAAW,KAAK,MAAM;AACtB,WAAK,gBAAgB,IAAI,MAAM,IAAI,WAAW;AAAA,IAC/C;AAEA,UAAM,aAAa,CAAC,YAAoB;AACvC,mBAAa;AAEb,UAAI,YAAY,GAAG;AAClB,cAAM,EAAE,iBAAAE,iBAAgB,IAAI;AAC5B,cAAM,mBAAmB,SAAS;AAAA,UACjC,CAAC,MAAM,KAAKA,iBAAgB,IAAI,EAAE,EAAE,MAAM;AAAA,QAC3C;AACA,YAAI,iBAAiB,QAAQ;AAG5B,eAAK,aAAa,gBAAgB;AAAA,QACnC;AAEA,aAAK,IAAI,QAAQ,UAAU;AAC3B;AAAA,MACD;AAEA,UAAI,OAAO,IAAI,YAAY,QAAQ;AAEnC,YAAM,EAAE,gBAAgB,IAAI;AAE5B,YAAM,UAA4B,CAAC;AAEnC,UAAI;AACJ,eAAS,IAAI,GAAG,IAAI,WAAW,QAAQ,IAAI,GAAG,KAAK;AAClD,cAAM,EAAE,OAAO,IAAI,IAAI,WAAW,CAAC;AAEnC,8BAAsB,gBAAgB,IAAI,MAAM,EAAE;AAClD,YAAI,wBAAwB,YAAa;AAEzC,gBAAQ,KAAK;AAAA,UACZ,GAAG;AAAA,UACH,GAAG,MAAM,KAAK,IAAI,IAAI,MAAM,KAAK;AAAA,UACjC,GAAG,MAAM,KAAK,IAAI,IAAI,MAAM,KAAK;AAAA,UACjC,SAAS,MAAM,WAAW,IAAI,UAAU,MAAM,WAAW;AAAA,UACzD,UAAU,MAAM,YAAY,IAAI,WAAW,MAAM,YAAY;AAAA,UAC7D,OAAO,KAAK,aAAa,GAAG,EAAE,uBAAuB,OAAO,KAAK,CAAC,KAAK,IAAI;AAAA,QAC5E,CAAC;AAAA,MACF;AAIA,WAAK,cAAc,OAAO;AAAA,IAC3B;AAEA,SAAK,GAAG,QAAQ,UAAU;AAE1B,WAAO;AAAA,EACR;AAAA,EAkBA,YACC,QACA,UAAU,CAAC,GACJ;AACP,UAAM,EAAE,cAAU,+BAAc,GAAG,SAAS,KAAK,IAAI;AAErD,QAAI,CAAC,MAAM,QAAQ,MAAM,GAAG;AAC3B,YAAM,MAAM,kEAAkE;AAAA,IAC/E;AACA,QAAI,KAAK,iBAAiB,EAAE,WAAY,QAAO;AAE/C,UAAM,MACL,OAAO,OAAO,CAAC,MAAM,WACjB,SACA,OAAO,IAAI,CAAC,MAAO,EAAc,EAAE;AAExC,QAAI,IAAI,UAAU,EAAG,QAAO;AAE5B,UAAM,oBAAgB;AAAA,OACpB,KAAK,yBAAyB,MAAM,KAAK,qBAAqB,GAAG,GAAG;AAAA,QAAI,CAAC,OACzE,KAAK,SAAS,EAAE;AAAA,MACjB;AAAA,IACD;AACA,UAAM,iBAAiB,cAAc,KAAK,wBAAW,EAAE,IAAI,CAAC,MAAM,EAAE,EAAE;AACtE,UAAM,aAAa,eAAI,WAAO,sBAAQ,cAAc,IAAI,CAAC,OAAO,KAAK,mBAAmB,EAAE,CAAC,CAAC,CAAC;AAE7F,UAAM,EAAE,GAAG,EAAE,IAAI,WAAW;AAE5B,UAAM,WAAW,KAAK,mBAAmB,aAAa,KAAK,KAAK,iBAAiB;AAGjF,QAAI,KAAK,iBAAiB,MAAM,SAAU,QAAO;AAGjD,QAAI,CAAC,KAAK,KAAK,aAAa,GAAG;AAC9B,WAAK,OAAO;AAAA,IACb;AAGA,UAAM,uBAAuB,cAC3B,OAAO,CAAC,UAAU,MAAM,aAAa,QAAQ,EAC7C,KAAK,wBAAW;AAElB,UAAM,eAAe,qBAAqB,qBAAqB,SAAS,CAAC,GAAG;AAE5E,SAAK,IAAI,MAAM;AACd,WAAK,aAA2B;AAAA,QAC/B;AAAA,UACC,IAAI;AAAA,UACJ,MAAM;AAAA,UACN;AAAA,UACA,OAAO;AAAA,UACP;AAAA,UACA;AAAA,UACA,SAAS;AAAA,UACT,OAAO,CAAC;AAAA,QACT;AAAA,MACD,CAAC;AACD,WAAK,eAAe,gBAAgB,OAAO;AAC3C,UAAI,QAAQ;AAEX,aAAK,OAAO,OAAO;AAAA,MACpB;AAAA,IACD,CAAC;AAED,WAAO;AAAA,EACR;AAAA,EAkBA,cAAc,QAAiC,UAAU,CAAC,GAAmC;AAC5F,QAAI,KAAK,iBAAiB,EAAE,WAAY,QAAO;AAE/C,UAAM,EAAE,SAAS,KAAK,IAAI;AAC1B,UAAM,MACL,OAAO,OAAO,CAAC,MAAM,WACjB,SACA,OAAqB,IAAI,CAAC,MAAM,EAAE,EAAE;AAEzC,UAAM,sBAAkB;AAAA,OACtB,KAAK,yBAAyB,MAAM,KAAK,qBAAqB,GAAG,GAAG;AAAA,QAAI,CAAC,OACzE,KAAK,SAAS,EAAE;AAAA,MACjB;AAAA,IACD;AAEA,QAAI,gBAAgB,WAAW,EAAG,QAAO;AAGzC,QAAI,KAAK,iBAAiB,MAAM,SAAU,QAAO;AACjD,QAAI,CAAC,KAAK,KAAK,aAAa,GAAG;AAC9B,WAAK,OAAO;AAAA,IACb;AAKA,UAAM,cAAc,oBAAI,IAAe;AAGvC,UAAM,SAAyB,CAAC;AAEhC,oBAAgB,QAAQ,CAAC,UAAU;AAClC,UAAI,KAAK,cAA4B,OAAO,OAAO,GAAG;AACrD,eAAO,KAAK,KAAK;AAAA,MAClB,OAAO;AACN,oBAAY,IAAI,MAAM,EAAE;AAAA,MACzB;AAAA,IACD,CAAC;AAED,QAAI,OAAO,WAAW,EAAG,QAAO;AAEhC,SAAK,IAAI,MAAM;AACd,UAAI;AAEJ,eAAS,IAAI,GAAG,IAAI,OAAO,QAAQ,IAAI,GAAG,KAAK;AAC9C,gBAAQ,OAAO,CAAC;AAChB,cAAM,WAAW,KAAK,2BAA2B,MAAM,EAAE;AAEzD,iBAAS,IAAI,GAAGC,KAAI,SAAS,QAAQ,IAAIA,IAAG,KAAK;AAChD,sBAAY,IAAI,SAAS,CAAC,CAAC;AAAA,QAC5B;AAEA,aAAK,eAAe,UAAU,MAAM,UAAU,MAAM,KAAK;AAAA,MAC1D;AAEA,WAAK,aAAa,OAAO,IAAI,CAACC,WAAUA,OAAM,EAAE,CAAC;AAEjD,UAAI,QAAQ;AAEX,aAAK,OAAO,GAAG,WAAW;AAAA,MAC3B;AAAA,IACD,CAAC;AAED,WAAO;AAAA,EACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcA,YAAsC,SAA+C;AACpF,SAAK,aAAa,CAAC,OAAO,CAAC;AAC3B,WAAO;AAAA,EACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcA,aAAuC,UAAoD;AAC1F,UAAM,oBAAyC,MAAM,SAAS,MAAM;AAEpE,aAAS,IAAI,GAAG,IAAI,SAAS,QAAQ,IAAI,GAAG,KAAK;AAChD,YAAM,UAAU,SAAS,CAAC;AAC1B,UAAI,CAAC,QAAS;AAEd,YAAM,QAAQ,KAAK,SAAS,QAAQ,EAAE;AACtC,UAAI,CAAC,MAAO;AAIZ,UAAI,CAAC,KAAK,wBAAwB;AACjC,YAAI,MAAM,UAAU;AAGnB,cAAI,EAAE,OAAO,OAAO,SAAS,UAAU,KAAK,CAAC,QAAQ,WAAW;AAC/D;AAAA,UACD;AAAA,QACD,WAAW,KAAK,wBAAwB,KAAK,GAAG;AAG/C;AAAA,QACD;AAAA,MACD;AAGA,WAAK,gBAAgB,OAAO,QAAQ,EAAE;AAEtC,wBAAkB,KAAK,OAAO;AAAA,IAC/B;AAEA,SAAK,cAAc,iBAAiB;AACpC,WAAO;AAAA,EACR;AAAA;AAAA,EAGA,cAAc,WAAkD;AAC/D,QAAI,KAAK,iBAAiB,EAAE,WAAY;AAExC,SAAK,IAAI,MAAM;AACd,YAAM,UAAU,CAAC;AAEjB,UAAI;AACJ,UAAI;AAEJ,eAAS,IAAI,GAAG,IAAI,UAAU,QAAQ,IAAI,GAAG,KAAK;AACjD,cAAM,UAAU,UAAU,CAAC;AAE3B,YAAI,CAAC,QAAS;AAId,gBAAQ,KAAK,SAAS,QAAQ,EAAE;AAChC,YAAI,CAAC,MAAO;AAIZ,kBAAU,8BAA8B,OAAO,OAAO;AACtD,YAAI,YAAY,MAAO;AAKvB,kBAAU,KAAK,aAAa,KAAK,EAAE,iBAAiB,OAAO,OAAO,KAAK;AAEvE,gBAAQ,KAAK,OAAO;AAAA,MACrB;AAEA,WAAK,MAAM,IAAI,OAAO;AAAA,IACvB,CAAC;AAAA,EACF;AAAA;AAAA,EAGQ,qBAAqB,KAA+B;AAC3D,WAAO,IAAI,OAAO,CAAC,OAAO,CAAC,KAAK,SAAS,EAAE,GAAG,QAAQ;AAAA,EACvD;AAAA,EAgBA,aAAa,MAAqC;AACjD,QAAI,KAAK,iBAAiB,EAAE,WAAY,QAAO;AAE/C,QAAI,CAAC,MAAM,QAAQ,IAAI,GAAG;AACzB,YAAM,MAAM,kEAAkE;AAAA,IAC/E;AAEA,UAAM,WACL,OAAO,KAAK,CAAC,MAAM,WAAY,OAAwB,KAAmB,IAAI,CAAC,MAAM,EAAE,EAAE;AAG1F,UAAM,mBAAmB,KAAK,yBAC3B,WACA,KAAK,qBAAqB,QAAQ;AAErC,QAAI,iBAAiB,WAAW,EAAG,QAAO;AAG1C,UAAM,sBAAsB,IAAI,IAAe,gBAAgB;AAE/D,eAAW,MAAM,kBAAkB;AAClC,WAAK,iBAAiB,IAAI,CAAC,YAAY;AACtC,4BAAoB,IAAI,OAAO;AAAA,MAChC,CAAC;AAAA,IACF;AAEA,WAAO,KAAK,IAAI,MAAM,KAAK,MAAM,OAAO,CAAC,GAAG,mBAAmB,CAAC,CAAC;AAAA,EAClE;AAAA,EAgBA,YAAY,KAA0B;AACrC,SAAK,aAAa,CAAC,OAAO,QAAQ,WAAW,MAAM,IAAI,EAAE,CAAC;AAC1D,WAAO;AAAA,EACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASQ,qBAAqB,OAAgB,gBAAgC;AAC5E,QAAI,KAAK,cAA4B,OAAO,OAAO,GAAG;AAIrD,YAAM,WAAW,KAAK,qBAAqB,IAAI,EAAE,MAAM,EAAE;AACzD,UAAI,CAAC,SAAU;AAEf,eAAS,IAAI,GAAG,IAAI,SAAS,QAAQ,IAAI,GAAG,KAAK;AAChD,aAAK,qBAAqB,KAAK,SAAS,SAAS,CAAC,CAAC,GAAI,cAAc;AAAA,MACtE;AAAA,IACD,OAAO;AACN,iBAAW,CAAC,OAAO,OAAO,KAAK,KAAK,WAAW,MAAM,IAAI,GAAG;AAC3D,uBAAe,WAAW,WAAO,6BAAe,MAAM,OAAO,OAAO,CAAC;AAAA,MACtE;AAAA,IACD;AAAA,EACD;AAAA,EAQQ,4BAAoD;AAC3D,UAAM,iBAAiB,KAAK,kBAAkB;AAE9C,UAAM,eAAe,IAAI,sCAAe;AACxC,eAAW,iBAAiB,gBAAgB;AAC3C,WAAK,qBAAqB,eAAe,YAAY;AAAA,IACtD;AAEA,WAAO;AAAA,EACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaA,qBAAwB,OAAwB;AAC/C,UAAM,QAAQ,KAAK,iBAAiB,EAAE,mBAAmB,MAAM,EAAE;AACjE,WAAO,UAAU,SAAY,MAAM,eAAgB;AAAA,EACpD;AAAA,EAEA,sBAAyB,OAAgB,OAAoC;AAC5E,UAAM,WAAW,KAAK,WAAW,MAAM,IAAI,EAAE,IAAI,KAAK;AACtD,QAAI,aAAa,OAAW,QAAO;AACnC,eAAO,6BAAe,MAAM,OAAO,QAAQ;AAAA,EAC5C;AAAA,EAiBA,kBAA0C;AAGzC,QAAI,KAAK,KAAK,QAAQ,KAAK,KAAK,oBAAoB,EAAE,SAAS,GAAG;AACjE,aAAO,KAAK,0BAA0B;AAAA,IACvC;AAIA,UAAM,cAAc,KAAK,KAAK,WAAW;AACzC,UAAM,SAAS,IAAI,sCAAe;AAElC,QAAI,CAAC,YAAa,QAAO;AAEzB,QAAI,YAAY,WAAW;AAC1B,iBAAW,SAAS,KAAK,WAAW,YAAY,SAAS,EAAE,KAAK,GAAG;AAClE,eAAO,WAAW,OAAO,KAAK,qBAAqB,KAAK,CAAC;AAAA,MAC1D;AAAA,IACD;AAEA,WAAO;AAAA,EACR;AAAA,EASU,mBAAwC;AACjD,QAAI,KAAK,KAAK,QAAQ,KAAK,KAAK,oBAAoB,EAAE,SAAS,GAAG;AACjE,YAAM,gBAA2B,CAAC;AAClC,YAAM,WAAW,CAAC,YAAuB;AACxC,cAAM,QAAQ,KAAK,SAAS,OAAO;AACnC,YAAI,CAAC,MAAO;AAIZ,YAAI,KAAK,cAA4B,OAAO,OAAO,GAAG;AACrD,qBAAW,WAAW,KAAK,2BAA2B,MAAM,EAAE,GAAG;AAChE,qBAAS,OAAO;AAAA,UACjB;AAAA,QACD,OAAO;AACN,wBAAc,KAAK,KAAK;AAAA,QACzB;AAAA,MACD;AACA,iBAAW,WAAW,KAAK,oBAAoB,GAAG;AACjD,iBAAS,OAAO;AAAA,MACjB;AAEA,UAAI,UAAyB;AAC7B,iBAAW,SAAS,eAAe;AAClC,YAAI,YAAY,MAAM;AACrB,oBAAU,MAAM;AAAA,QACjB,WAAW,YAAY,MAAM,SAAS;AACrC,iBAAO,EAAE,MAAM,QAAQ;AAAA,QACxB;AAAA,MACD;AAEA,UAAI,YAAY,KAAM,QAAO,EAAE,MAAM,UAAU,OAAO,QAAQ;AAAA,IAC/D;AACA,WAAO,EAAE,MAAM,UAAU,OAAO,KAAK,iBAAiB,EAAE,oBAAoB;AAAA,EAC7E;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaA,wBAAwB,SAAiB,gBAA8C;AACtF,SAAK,oBAAoB,EAAE,qBAAqB,QAAQ,GAAG,cAAc;AACzE,WAAO;AAAA,EACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,4BAA4B,SAAuB;AAClD,UAAM,iBAAiB,KAAK,kBAAkB;AAE9C,QAAI,eAAe,SAAS,GAAG;AAC9B,YAAM,iBAA4B,CAAC;AAInC,YAAM,eAAe,CAAC,UAAmB;AACxC,YAAI,KAAK,cAA4B,OAAO,OAAO,GAAG;AACrD,gBAAM,WAAW,KAAK,2BAA2B,KAAK;AACtD,qBAAW,WAAW,UAAU;AAC/B,yBAAa,KAAK,SAAS,OAAO,CAAE;AAAA,UACrC;AAAA,QACD,OAAO;AACN,yBAAe,KAAK,KAAK;AAAA,QAC1B;AAAA,MACD;AAEA,iBAAW,MAAM,gBAAgB;AAChC,qBAAa,EAAE;AAAA,MAChB;AAEA,WAAK;AAAA,QACJ,eAAe,IAAI,CAAC,UAAU;AAC7B,iBAAO;AAAA,YACN,IAAI,MAAM;AAAA,YACV,MAAM,MAAM;AAAA,YACZ;AAAA,UACD;AAAA,QACD,CAAC;AAAA,MACF;AAAA,IACD;AAEA,WAAO;AAAA,EACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAiBA,sBACC,OACA,OACA,gBACO;AACP,UAAM,qBAAqB,KAAK,iBAAiB,EAAE;AAEnD,SAAK;AAAA,MACJ,EAAE,oBAAoB,EAAE,GAAG,oBAAoB,CAAC,MAAM,EAAE,GAAG,MAAM,EAAE;AAAA,MACnE;AAAA,IACD;AAEA,WAAO;AAAA,EACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAgBA,0BAAoD,OAAU,OAAgC;AAC7F,UAAM,iBAAiB,KAAK,kBAAkB;AAE9C,QAAI,eAAe,SAAS,GAAG;AAC9B,YAAM,UAIA,CAAC;AAIP,YAAM,eAAe,CAAC,UAAmB;AACxC,YAAI,KAAK,cAA4B,OAAO,OAAO,GAAG;AACrD,gBAAM,WAAW,KAAK,2BAA2B,MAAM,EAAE;AACzD,qBAAW,WAAW,UAAU;AAC/B,yBAAa,KAAK,SAAS,OAAO,CAAE;AAAA,UACrC;AAAA,QACD,OAAO;AACN,gBAAM,OAAO,KAAK,aAAa,KAAK;AACpC,gBAAM,eAAe,KAAK,WAAW,MAAM,IAAI,EAAE,IAAI,KAAK;AAC1D,cAAI,cAAc;AACjB,kBAAM,eAA+B;AAAA,cACpC,IAAI,MAAM;AAAA,cACV,MAAM,MAAM;AAAA,cACZ,OAAO,EAAE,CAAC,YAAY,GAAG,MAAM;AAAA,YAChC;AACA,oBAAQ,KAAK;AAAA,cACZ;AAAA,cACA,eAAe;AAAA,cACf,eAAe;AAAA,YAChB,CAAC;AAAA,UACF;AAAA,QACD;AAAA,MACD;AAEA,iBAAW,SAAS,gBAAgB;AACnC,qBAAa,KAAK;AAAA,MACnB;AAEA,WAAK,aAAa,QAAQ,IAAI,CAAC,EAAE,cAAc,MAAM,aAAa,CAAC;AAAA,IACpE;AAEA,WAAO;AAAA,EACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAsCA,6BACC,MACA,SACO;AACP,SAAK,6BAA6B,IAAI,IAAI;AAC1C,WAAO;AAAA,EACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAkBA,4BAA4B,SAAoB,MAAY;AAC3D,QAAI,KAAK,sBAAsB,IAAI,OAAO,GAAG;AAC5C,aAAO,KAAK,sBAAsB,IAAI,OAAO;AAAA,IAC9C;AAEA,UAAM,YAAY,IAAI,gBAAgB,IAAI;AAC1C,SAAK,sBAAsB,IAAI,SAAS,SAAS;AAGjD,eAAW,MAAM;AAChB,WAAK,sBAAsB,OAAO,OAAO;AACzC,UAAI,gBAAgB,SAAS;AAAA,IAC9B,GAAG,KAAK,QAAQ,+BAA+B;AAE/C,WAAO;AAAA,EACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAeA,yBAAyB,SAAoB;AAC5C,WAAO,KAAK,sBAAsB,IAAI,OAAO;AAAA,EAC9C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcA,MAAM,2BAA2B,MAA4D;AAC5F,WAAO,MAAM,KAAK,6BAA6B,KAAK,IAAI,IAAI,IAAW;AAAA,EACxE;AAAA,EAEA,wBAAwB,MAA+C;AACtE,WAAO,CAAC,CAAC,KAAK,6BAA6B,IAAI;AAAA,EAChD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAkCA,+BACC,MACA,SAOO;AACP,SAAK,wBAAwB,IAAI,IAAI;AACrC,WAAO;AAAA,EACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,mBAAsB,MAA2C;AACtE,WAAO,KAAK,wBAAwB,KAAK,IAAI,IAAI,IAAW;AAAA,EAC7D;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,0BAA0B,QAAwD;AAEjF,UAAM,MACL,OAAO,OAAO,CAAC,MAAM,WACjB,SACA,OAAqB,IAAI,CAAC,MAAM,EAAE,EAAE;AAEzC,QAAI,CAAC,IAAK;AACV,QAAI,IAAI,WAAW,EAAG;AAEtB,UAAM,WAAW,KAAK,yBAAyB,GAAG;AAElD,WAAO,mBAAmB,MAAM,UAAU,CAAC,qBAAqB;AAC/D,YAAM,WAAwB,CAAC;AAC/B,iBAAW,MAAM,kBAAkB;AAClC,cAAM,UAAU,KAAK,WAAW,EAAE;AAClC,YAAI,CAAC,QAAS;AACd,iBAAS,KAAK,OAAO;AAAA,MACtB;AAEA,YAAM,eAA4B,CAAC;AACnC,YAAMC,UAAoB,CAAC;AAC3B,iBAAW,WAAW,UAAU;AAC/B,cAAM,QAAQ,KAAK,SAAS,OAAO;AACnC,YAAI,CAAC,MAAO;AAEZ,cAAM,cAAc,CAAC,SAAS,IAAI,MAAM,QAAqB;AAC7D,YAAI,aAAa;AAGhB,gBAAM,gBAAgB,KAAK,sBAAsB,MAAM,EAAE;AACzD,gBAAM,YAAY,cAAc,MAAM;AACtC,UAAAA,QAAO,KAAK;AAAA,YACX,GAAG;AAAA,YACH,GAAG,UAAU;AAAA,YACb,GAAG,UAAU;AAAA,YACb,UAAU,cAAc,SAAS;AAAA,YACjC,UAAU,KAAK,iBAAiB;AAAA,UACjC,CAAC;AACD,uBAAa,KAAK,MAAM,EAAE;AAAA,QAC3B,OAAO;AACN,UAAAA,QAAO,KAAK,KAAK;AAAA,QAClB;AAAA,MACD;AAEA,YAAM,SAAoB,CAAC;AAC3B,YAAM,eAAe,oBAAI,IAAe;AACxC,iBAAW,SAASA,SAAQ;AAC3B,YAAI,EAAE,aAAa,MAAM,OAAQ;AAEjC,cAAM,UAAU,MAAM,MAAM;AAC5B,YAAI,CAAC,WAAW,aAAa,IAAI,OAAO,EAAG;AAE3C,qBAAa,IAAI,OAAO;AACxB,cAAM,QAAQ,KAAK,SAAS,OAAO;AACnC,YAAI,CAAC,MAAO;AACZ,eAAO,KAAK,KAAK;AAAA,MAClB;AAEA,aAAO;AAAA,QACN,QAAQ,KAAK,MAAM,OAAO,UAAU;AAAA,QACpC,QAAAA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACD;AAAA,IACD,CAAC;AAAA,EACF;AAAA,EAEA,MAAM,uBAAuB,SAAgE;AAC5F,QAAI,CAAC,QAAS,QAAO;AAErB,UAAM,SAAoB,CAAC;AAC3B,UAAM,QAAQ;AAAA,MACb,QAAQ,OAAO,IAAI,OAAO,UAAU;AACnC,aACE,MAAM,SAAS,WAAW,MAAM,SAAS,YAC1C,CAAC,MAAM,MAAM,KAAK,WAAW,YAAY,KACzC,CAAC,MAAM,MAAM,KAAK,WAAW,MAAM,GAClC;AACD,gBAAM,uBAAmB,8BAAgB,KAAoC;AAC7E,gBAAM,YAAY,MAAM,KAAK,MAAM,MAAM,OAAO,QAAQ,OAAO;AAAA,YAC9D,aAAa;AAAA,YACb,oBAAoB;AAAA,YACpB,KAAK;AAAA,YACL,sBAAsB;AAAA,YACtB,yBAAyB;AAAA,UAC1B,CAAC;AACD,2BAAiB,MAAM,MAAM,MAAM,yBAAY;AAAA,YAC9C,UAAM,oBAAM,SAAU,EAAE,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC;AAAA,UAC7C;AACA,iBAAO,KAAK,gBAAgB;AAAA,QAC7B,OAAO;AACN,iBAAO,KAAK,KAAK;AAAA,QAClB;AAAA,MACD,CAAC;AAAA,IACF;AACA,YAAQ,SAAS;AAEjB,WAAO;AAAA,EACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,0BACC,SACA,UAKI,CAAC,GACE;AACP,QAAI,KAAK,iBAAiB,EAAE,WAAY,QAAO;AAI/C,QAAI,CAAC,QAAQ,QAAQ;AACpB,YAAM,MAAM,sDAAsD;AAAA,IACnE;AAEA,UAAM,EAAE,SAAS,OAAO,cAAc,OAAO,mBAAmB,MAAM,IAAI;AAC1E,QAAI,EAAE,QAAQ,OAAU,IAAI;AAI5B,UAAM,gBAAgB,KAAK,iBAAiB;AAC5C,UAAM,EAAE,aAAa,IAAI;AAGzB,UAAM,SAAoB,CAAC;AAC3B,UAAM,SAAoB,CAAC;AAC3B,UAAM,WAAwB,CAAC;AAG/B,UAAM,QAAiC;AAAA,MACtC,OAAO;AAAA,QACN,GAAG,OAAO,YAAY,QAAQ,OAAO,IAAI,CAAC,UAAU,CAAC,MAAM,IAAI,KAAK,CAAU,CAAC;AAAA,QAC/E,GAAG,OAAO,YAAY,QAAQ,OAAO,IAAI,CAAC,UAAU,CAAC,MAAM,IAAI,KAAK,CAAU,CAAC;AAAA,QAC/E,GAAG,OAAO;AAAA,UACT,QAAQ,UAAU,IAAI,CAACC,cAAa,CAACA,UAAS,IAAIA,SAAQ,CAAU,KAAK,CAAC;AAAA,QAC3E;AAAA,MACD;AAAA,MACA,QAAQ,QAAQ;AAAA,IACjB;AACA,UAAM,SAAS,KAAK,MAAM,OAAO,qBAAqB,KAAK;AAC3D,QAAI,OAAO,SAAS,SAAS;AAC5B,YAAM,MAAM,kDAAkD;AAAA,IAC/D;AACA,eAAW,UAAU,OAAO,OAAO,OAAO,KAAK,GAAG;AACjD,cAAQ,OAAO,UAAU;AAAA,QACxB,KAAK,SAAS;AACb,iBAAO,KAAK,MAAM;AAClB;AAAA,QACD;AAAA,QACA,KAAK,SAAS;AACb,iBAAO,KAAK,MAAM;AAClB;AAAA,QACD;AAAA,QACA,KAAK,WAAW;AACf,mBAAS,KAAK,MAAM;AACpB;AAAA,QACD;AAAA,MACD;AAAA,IACD;AAGA,UAAM,aAAa,IAAI;AAAA,MACtB,cACG,OAAO,IAAI,CAAC,UAAU,CAAC,MAAM,IAAI,MAAM,EAAE,CAAC,IAC1C,OAAO,IAAI,CAAC,UAAU,CAAC,MAAM,QAAI,+BAAc,CAAC,CAAC;AAAA,IACrD;AACA,UAAM,eAAe,IAAI;AAAA,MACxB,cACG,SAAS,IAAI,CAAC,YAAY,CAAC,QAAQ,IAAI,QAAQ,EAAE,CAAC,IAClD,SAAS,IAAI,CAAC,YAAY,CAAC,QAAQ,QAAI,iCAAgB,CAAC,CAAC;AAAA,IAC7D;AAGA,QAAI,gBAAgB,KAAK,iBAAiB;AAC1C,QAAI,cAAc;AAClB,QAAI,kBAA6B,CAAC;AAGlC,eAAW,SAAS,KAAK,kBAAkB,GAAG;AAC7C,UAAI,gBAAgB,EAAG;AAEvB,YAAM,UAAU,KAAK,cAA4B,OAAO,OAAO;AAC/D,YAAM,YAAY,KAAK,kBAAkB,KAAK;AAC9C,UAAI,QAAS,WAAU,KAAK,KAAK;AAEjC,YAAM,QAAQ,UAAU,UAAU,SAAS,IAAI,UAAU;AAEzD,UAAI,QAAQ,aAAa;AACxB,sBAAc;AACd,0BAAkB;AAClB,wBAAgB,UAAU,MAAM,KAAK,MAAM;AAAA,MAC5C,WAAW,UAAU,aAAa;AACjC,YAAI,gBAAgB,WAAW,UAAU,QAAQ;AAChD,gBAAM,MAAM,cAAc,gBAAgB,MAAM,QAAQ,UAAU,MAAM,EAAE;AAAA,QAC3E;AAEA,YAAI,gBAAgB,WAAW,GAAG;AACjC,0BAAgB;AAChB;AAAA,QACD,OAAO;AACN,0BAAgB;AAChB,mBAAS,IAAI,GAAG,IAAI,gBAAgB,QAAQ,KAAK;AAChD,gBAAI,UAAU,CAAC,MAAM,gBAAgB,CAAC,EAAG;AACzC,4BAAgB,UAAU,CAAC,EAAE;AAAA,UAC9B;AAAA,QACD;AAAA,MACD;AAAA,IACD;AAEA,QAAI,gBAAgB;AAEpB,QAAI,KAAC,0BAAS,aAAa,GAAG;AAC7B,YAAM,SAAS,KAAK,SAAS,aAAa;AAC1C,UAAI,QAAQ;AACX,YAAI,CAAC,KAAK,sBAAsB,EAAE,SAAS,KAAK,mBAAmB,MAAM,CAAE,GAAG;AAC7E,0BAAgB;AAAA,QACjB,OAAO;AACN,cAAI,aAAa,WAAW,GAAG;AAC9B,kBAAM,YAAY,OAAO,KAAK,CAAC,MAAM,EAAE,OAAO,aAAa,CAAC,CAAC;AAC7D,gBACC,KAAK,cAA4B,QAAQ,OAAO,KAChD,KAAK,cAA4B,WAAW,OAAO,KACnD,UAAU,MAAM,MAAM,QAAQ,MAAM,KACpC,UAAU,MAAM,MAAM,QAAQ,MAAM,GACnC;AACD,8BAAgB;AAAA,YACjB;AAAA,UACD;AAAA,QACD;AAAA,MACD,OAAO;AACN,wBAAgB;AAAA,MACjB;AAAA,IACD;AAEA,QAAI,CAAC,eAAe;AACnB,sBAAgB,WAAW,IAAI,aAAa;AAAA,IAC7C;AAEA,QAAI,eAAe;AAClB,sBAAgB,KAAK,SAAS,aAAa,EAAG;AAAA,IAC/C;AAEA,QAAI,QAAQ,KAAK,yBAAyB,aAAa;AAEvD,UAAM,aAAwB,CAAC;AAE/B,UAAM,YAAuB,OAAO,IAAI,CAAC,aAAsB;AAC9D,YAAM,QAAQ,WAAW,IAAI,SAAS,EAAE;AAGxC,YAAM,WAAW,EAAE,GAAG,UAAU,IAAI,MAAM;AAE1C,UAAI,aAAa,SAAS,SAAS,EAAE,GAAG;AACvC,iBAAS,WAAW;AACpB,mBAAW,KAAK,QAAQ;AAAA,MACzB;AAMA,UAAI,WAAW,IAAI,SAAS,QAAQ,GAAG;AACtC,iBAAS,WAAW,WAAW,IAAI,SAAS,QAAQ;AAAA,MACrD,OAAO;AACN,qBAAa,KAAK,SAAS,EAAE;AAE7B,iBAAS,QAAQ;AACjB,oBAAQ,4BAAc,KAAK;AAAA,MAC5B;AAEA,aAAO;AAAA,IACR,CAAC;AAED,QAAI,UAAU,SAAS,KAAK,uBAAuB,EAAE,OAAO,KAAK,QAAQ,kBAAkB;AAI1F,qBAAe,IAAI;AACnB,aAAO;AAAA,IACR;AAEA,UAAM,cAAc,SAAS;AAAA,MAC5B,CAAC,gBAA2B;AAAA,QAC3B,GAAG;AAAA,QACH,QAAI,2BAAa,aAAa,IAAI,WAAW,EAAE,CAAC;AAAA,QAChD,YAAQ,2BAAa,WAAW,IAAI,WAAW,MAAM,CAAC;AAAA,QACtD,UAAM,2BAAa,WAAW,IAAI,WAAW,IAAI,CAAC;AAAA,MACnD;AAAA,IACD;AAGA,UAAM,iBAA4B,CAAC;AAGnC,UAAM,iBAAkD,CAAC;AAEzD,eAAW,SAAS,QAAQ;AAC3B,UAAI,KAAK,MAAM,IAAI,MAAM,EAAE,GAAG;AAE7B;AAAA,MACD;AAEA,WACE,MAAM,SAAS,WAAW,MAAM,SAAS,YAC1C,MAAM,MAAM,KAAK,WAAW,YAAY,GACvC;AAID,uBAAe,SAAK,8BAAgB,KAAoC,CAAC;AACzE,cAAM,MAAM,MAAM;AAAA,MACnB;AAGA,qBAAe,KAAK,KAAK;AAAA,IAC1B;AAGA,YAAQ;AAAA,MACN,eAAmD,IAAI,OAAO,UAAU;AAExE,cAAM,OAAO,UAAM;AAAA,UAClB,MAAM,MAAM;AAAA,UACZ,MAAM,MAAM;AAAA,UACZ,MAAM,MAAM,YAAY;AAAA,QACzB;AAGA,cAAM,WAAW,MAAM,KAAK,2BAA2B;AAAA,UACtD,MAAM;AAAA,UACN;AAAA,UACA,SAAS,MAAM;AAAA,QAChB,CAAC;AAED,YAAI,CAAC,UAAU;AAGd,eAAK,aAAa,CAAC,MAAM,EAAE,CAAC;AAC5B;AAAA,QACD;AAGA,aAAK,aAAa,CAAC,EAAE,GAAG,UAAU,IAAI,MAAM,GAAG,CAAC,CAAC;AAAA,MAClD,CAAC;AAAA,IACF;AAEA,SAAK,IAAI,MAAM;AAEd,UAAI,eAAe,SAAS,GAAG;AAC9B,aAAK,aAAa,cAAc;AAAA,MACjC;AAGA,WAAK,aAAa,SAAS;AAC3B,WAAK,eAAe,WAAW;AAE/B,UAAI,QAAQ;AACX,aAAK,OAAO,GAAG,WAAW,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC;AAAA,MAC3C;AAGA,UAAI,kBAAkB,eAAe;AACpC,aAAK;AAAA,UACJ,WAAW,IAAI,CAAC,MAAM,EAAE,EAAE;AAAA,UAC1B;AAAA,QACD;AAAA,MACD;AAEA,YAAM,mBAAmB,UAAU,IAAI,CAAC,MAAM,KAAK,SAAS,EAAE,EAAE,CAAE;AAClE,YAAM,SAAS,eAAI,OAAO,iBAAiB,IAAI,CAAC,MAAM,KAAK,mBAAmB,CAAC,CAAE,CAAC;AAElF,UAAI,UAAU,QAAW;AACxB,YAAI,KAAC,0BAAS,aAAa,GAAG;AAE7B,gBAAM,QAAQ,KAAK,SAAS,aAAa;AACzC,kBAAQ,eAAI;AAAA,YACX,KAAK,sBAAsB,KAAK;AAAA,YAChC,KAAK,iBAAiB,KAAK,EAAE,OAAO;AAAA,UACrC;AAAA,QACD,OAAO;AACN,gBAAM,qBAAqB,KAAK,sBAAsB;AACtD,cAAI,oBAAoB,mBAAmB,SAAS,eAAI,KAAK,MAAM,CAAC,GAAG;AAEtE,oBAAQ,OAAO;AAAA,UAChB,OAAO;AAGN,oBAAQ,mBAAmB;AAAA,UAC5B;AAAA,QACD;AAAA,MACD;AAEA,UAAI,WAAW,WAAW,GAAG;AAC5B,cAAM,WAAW,WAAW,CAAC;AAE7B,YAAI,KAAK,cAA4B,UAAU,OAAO,GAAG;AACxD,iBACC,KAAK,iBAAiB,KAAK,EAAE;AAAA,YAC5B,CAAC,UACA,KAAK,cAA4B,OAAO,OAAO,KAC/C,MAAM,MAAM,MAAM,SAAS,MAAM,KACjC,MAAM,MAAM,MAAM,SAAS,MAAM;AAAA,UACnC,GACC;AACD,kBAAM,KAAK,OAAO,IAAI;AAAA,UACvB;AAAA,QACD;AAAA,MACD;AAEA,YAAM,aAAa,eAAI;AAAA,YACtB,sBAAQ,WAAW,IAAI,CAAC,EAAE,GAAG,MAAM,KAAK,mBAAmB,EAAE,CAAC,CAAC;AAAA,MAChE,EAAE;AAEF,YAAM,SAAS,eAAI,IAAI,OAAO,UAAU;AAExC,WAAK;AAAA,QACJ,WAAW,IAAI,CAAC,EAAE,GAAG,MAAM;AAC1B,gBAAM,IAAI,KAAK,SAAS,EAAE;AAC1B,gBAAM,gBAAgB,KAAK,wBAAwB,EAAE,EAAE,UAAU,EAAE;AACnE,gBAAM,aAAa,eAAI,IAAI,QAAQ,CAAC,aAAa;AAEjD,iBAAO,EAAE,IAAI,EAAE,IAAI,MAAM,EAAE,MAAM,GAAG,EAAE,IAAI,WAAW,GAAG,GAAG,EAAE,IAAI,WAAW,EAAE;AAAA,QAC/E,CAAC;AAAA,MACF;AAAA,IACD,CAAC;AAED,WAAO;AAAA,EACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,MAAM,cAAc,QAAiC,OAA6B,CAAC,GAAG;AACrF,UAAM,MACL,OAAO,OAAO,CAAC,MAAM,WACjB,SACA,OAAqB,IAAI,CAAC,MAAM,EAAE,EAAE;AAEzC,QAAI,IAAI,WAAW,EAAG,QAAO;AAE7B,eAAO,gCAAY,MAAM,KAAK,IAAI;AAAA,EACnC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,MAAM,aAAa,QAAiC,OAA6B,CAAC,GAAG;AACpF,UAAM,SAAS,MAAM,KAAK,cAAc,QAAQ,IAAI;AACpD,QAAI,CAAC,OAAQ,QAAO;AAEpB,UAAM,aAAa,IAAI,cAAc;AACrC,WAAO;AAAA,MACN,KAAK,WAAW,kBAAkB,OAAO,GAAG;AAAA,MAC5C,OAAO,OAAO;AAAA,MACd,QAAQ,OAAO;AAAA,IAChB;AAAA,EACD;AAAA;AAAA,EAGA,MAAM,OAAO,QAAiC,OAA6B,CAAC,GAAG;AAC9E,UAAM,SAAS,MAAM,KAAK,cAAc,QAAQ,IAAI;AACpD,QAAI,CAAC,OAAQ,QAAO;AACpB,WAAO,OAAO;AAAA,EACf;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAuDQ,uBACP,MACO;AACP,UAAM;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACD,IAAI,KAAK;AAET,UAAM,EAAE,aAAa,IAAI,KAAK,MAAM,wBAAwB,6BAAa;AACzE,UAAM,EAAE,GAAG,IAAI,GAAG,IAAI,GAAG,GAAG,QAAI,qCAAuB,MAAM,KAAK,UAAU,CAAC;AAE7E,UAAM,KAAK,KAAK,MAAM,IAAI,aAAa;AACvC,UAAM,KAAK,KAAK,MAAM,IAAI,aAAa;AACvC,UAAM,KAAK,KAAK,MAAM,KAAK;AAE3B,wBAAoB,MAAM,kBAAkB;AAC5C,sBAAkB,MAAM,gBAAgB;AAMxC,uBAAmB,IAAI,IAAI,EAAE;AAC7B,UAAM,KAAK,KAAK,KAAK;AACrB,UAAM,KAAK,KAAK,KAAK;AACrB,QAAI,SAAS,EAAE,KAAK,SAAS,EAAE,GAAG;AACjC,uBAAiB,IAAI,IAAI,IAAI,EAAE;AAAA,IAChC;AAEA,SAAK,OAAO,QAAQ,KAAK,SAAS,aAAa,KAAK;AAGpD,QAAI,KAAK,SAAS,kBAAkB,KAAK,OAAO,YAAY;AAC3D,sBAAgB,IAAI,GAAG,CAAC;AACxB,WAAK,OAAO,kBAAkB,MAAM,kBAAkB;AACtD,WAAK,OAAO,gBAAgB,MAAM,gBAAgB;AAAA,IACnD;AAGA,SAAK;AAAA,MACJ,MAAM;AACL,aAAK,MAAM,IAAI;AAAA,UACd;AAAA,YACC,IAAI;AAAA,YACJ,UAAU;AAAA,YACV,GAAG,iBAAiB;AAAA,YACpB,GAAG,iBAAiB;AAAA,YACpB;AAAA;AAAA;AAAA,cAGC,KAAK,SAAS,aAAa,KAAK,cAAc,sCAAqB,cAChE,KAAK,MAAM,wBAAwB,4BAAY,GAAG,yBACnD,KAAK,aAAa,MACjB,KAAK,aAAa;AAAA;AAAA,YACtB,MAAM,CAAC;AAAA,UACR;AAAA,QACD,CAAC;AAAA,MACF;AAAA,MACA,EAAE,SAAS,SAAS;AAAA,IACrB;AAAA,EACD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,SAAe;AACd,SAAK,SAAS,EAAE,MAAM,QAAQ,MAAM,SAAS,CAAC;AAC9C,WAAO;AAAA,EACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,YAAkB;AACjB,SAAK,SAAS,EAAE,MAAM,QAAQ,MAAM,YAAY,CAAC;AACjD,WAAO;AAAA,EACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,WAAiB;AAChB,SAAK,SAAS,EAAE,MAAM,QAAQ,MAAM,WAAW,CAAC;AAChD,WAAO;AAAA,EACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAqBA,MAAM,EAAE,iBAAiB,KAAK,IAAI,CAAC,GAAS;AAC3C,QAAI,KAAK,aAAa,EAAG,QAAO;AAChC,QAAI,eAAgB,MAAK,aAAa,MAAM;AAC5C,SAAK,oBAAoB,EAAE,WAAW,KAAK,CAAC;AAC5C,WAAO;AAAA,EACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAoBA,KAAK,EAAE,gBAAgB,KAAK,IAAI,CAAC,GAAS;AACzC,QAAI,CAAC,KAAK,aAAa,EAAG,QAAO;AACjC,QAAI,eAAe;AAClB,WAAK,aAAa,KAAK;AAAA,IACxB,OAAO;AACN,WAAK,SAAS;AAAA,IACf;AACA,SAAK,oBAAoB,EAAE,WAAW,MAAM,CAAC;AAC7C,WAAO;AAAA,EACR;AAAA,EAMU,eAAe;AACxB,WAAO,KAAK,iBAAiB,EAAE;AAAA,EAChC;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,cAAc;AACb,eAAO,qCAAY,KAAK,KAAK;AAAA,EAC9B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,aACC,UACA,MACC;AACD,8CAAa,KAAK,OAAO,UAAU,IAAI;AACvC,WAAO;AAAA,EACR;AAAA,EAEQ,oCAAoC;AAC3C,UAAM,SAAS,KAAK,qBAAqB;AACzC,QAAI,QAAQ;AACX,WAAK,aAAa,QAAQ,EAAE,WAAW,MAAM,YAAY,KAAK,YAAY,EAAE,CAAC;AAAA,IAC9E;AAAA,EACD;AAAA,EACQ,oBAAoB,UAAsB;AACjD,SAAK,IAAI,MAAM;AACd,cAAQ,SAAS,MAAM;AAAA,QACtB,KAAK,QAAQ;AACZ,gBAAM,OAAO,KAAK,QAAQ,SAAS,MAAM;AACzC,cAAI,MAAM;AACT,iBAAK,eAAe,IAAI;AAAA,UACzB;AACA,eAAK,kCAAkC;AACvC;AAAA,QACD;AAAA,QACA,KAAK,UAAU;AACd,gBAAM,gBAAY,sBAAQ,SAAS,SAAS,IAAI,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC,CAAC;AAC1E,gBAAM,SAA0C,CAAC;AACjD,qBAAW,SAAS,WAAW;AAC9B,kBAAMC,UAAS,KAAK,kBAAkB,KAAK;AAC3C,gBAAI,CAACA,QAAQ;AACb,mBAAOA,OAAM,MAAM,CAAC;AACpB,mBAAOA,OAAM,EAAE,KAAK,KAAK;AAAA,UAC1B;AACA,gBAAM,CAAC,QAAQ,MAAM,IAAI,OAAO,QAAQ,MAAM,EAAE;AAAA,YAC/C,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,SAAS,EAAE;AAAA,UACnC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;AAEf,cAAI,CAAC,UAAU,CAAC,OAAO,QAAQ;AAC9B,iBAAK,kCAAkC;AAAA,UACxC,OAAO;AACN,iBAAK,eAAe,MAAkB;AACtC,kBAAM,SAAS,eAAI,OAAO,OAAO,IAAI,CAAC,MAAM,KAAK,mBAAmB,CAAC,CAAE,CAAC;AACxE,iBAAK,aAAa,QAAQ,EAAE,WAAW,MAAM,YAAY,KAAK,YAAY,EAAE,CAAC;AAAA,UAC9E;AACA;AAAA,QACD;AAAA,QACA,KAAK,YAAY;AAChB,cAAI,SAAS,QAAQ;AACpB,gBAAI,CAAC,KAAK,QAAQ,SAAS,MAAM,GAAG;AACnC,mBAAK,kCAAkC;AACvC;AAAA,YACD;AACA,iBAAK,eAAe,SAAS,MAAM;AAAA,UACpC;AACA,eAAK,aAAa,SAAS,QAAQ,EAAE,WAAW,MAAM,OAAO,EAAE,CAAC;AAChE;AAAA,QACD;AAAA,QACA;AACC,kDAAsB,QAAQ;AAAA,MAChC;AAAA,IACD,CAAC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EA2BA,mBAAmB,MAAoE;AACtF,QAAI,QAAQ,UAAU,MAAM;AAC3B,WAAK,oBAAoB,IAAI;AAC7B,aAAO;AAAA,IACR;AAEA,UAAM,MAAM,IAAI,IAAI,MAAM,OAAO,OAAO,SAAS,IAAI;AACrD,UAAM,iBAAiB,IAAI,aAAa,IAAI,MAAM,SAAS,GAAG;AAE9D,QAAI,CAAC,gBAAgB;AACpB,WAAK,kCAAkC;AACvC,aAAO;AAAA,IACR;AAEA,QAAI;AACH,WAAK,wBAAoB,sCAAoB,cAAc,CAAC;AAAA,IAC7D,SAAS,GAAG;AACX,cAAQ,KAAK,CAAC;AACd,WAAK,kCAAkC;AAAA,IACxC;AACA,WAAO;AAAA,EACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAoCA,eAAe,MAAqE;AACnF,UAAM,MAAM,IAAI,IAAI,MAAM,OAAO,OAAO,SAAS,IAAI;AAErD,QAAI,aAAa;AAAA,MAChB,MAAM,SAAS;AAAA,UACf;AAAA,QACC,MAAM,MAAM;AAAA,UACX,MAAM;AAAA,UACN,QAAQ,KAAK,QAAQ,aAAa,IAAI,SAAY,KAAK,iBAAiB;AAAA,UACxE,QAAQ,KAAK,sBAAsB;AAAA,QACpC;AAAA,MACD;AAAA,IACD;AAEA,WAAO;AAAA,EACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EA8CA,yBAAyB,MAAsC;AAC9D,QAAI,MAAM,UAAU,CAAC,MAAM,UAAU;AACpC,YAAM;AAAA,QACL;AAAA,MACD;AAAA,IACD;AAEA,UAAM,WAAO,uBAAS,kBAAkB,MAAM;AAC7C,YAAM,MAAM,MAAM,SAAS,IAAI,KAAK,OAAO,SAAS;AACpD,YAAM,eAAe,KAAK,eAAe;AAAA,QACxC,OAAO,MAAM;AAAA,QACb;AAAA,QACA,IAAI,MAAM,YAAY,IAAI;AAAA,MAC3B,CAAC;AACD,aAAO,aAAa,SAAS;AAAA,IAC9B,CAAC;AAED,UAAM,iBACL,MAAM,aACL,MAAM;AACN,YAAM,MAAM,KAAK,eAAe;AAAA,QAC/B,OAAO,MAAM;AAAA,QACb,IAAI,MAAM,YAAY,IAAI;AAAA,MAC3B,CAAC;AAED,aAAO,QAAQ,aAAa,CAAC,GAAG,SAAS,OAAO,IAAI,SAAS,CAAC;AAAA,IAC/D;AAED,UAAM,qBAAiB,uBAAS,CAAC,YAAwB,QAAQ,GAAG,MAAM,cAAc,GAAG;AAE3F,UAAM,eAAW;AAAA,MAChB;AAAA,MACA,MAAM,eAAe,IAAI,IAAI,KAAK,IAAI,CAAC,GAAG,IAAI;AAAA,MAC9C,EAAE,eAAe;AAAA,IAClB;AAEA,WAAO,MAAM;AACZ,eAAS;AACT,qBAAe,OAAO;AAAA,IACvB;AAAA,EACD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcA,oBAAoB;AACnB,SAAK,cAAc,yBAAyB;AAAA,EAC7C;AAAA,EAcA,sBAAsB;AACrB,SAAK,OAAO,WAAW;AACvB,SAAK,SAAS;AAAA,MACb,MAAM;AAAA,MACN,MAAM;AAAA,MACN,KAAK;AAAA,MACL,UAAU,KAAK,OAAO;AAAA,MACtB,SAAS,KAAK,OAAO;AAAA,MACrB,QAAQ,KAAK,OAAO;AAAA,MACpB,MAAM;AAAA,IACP,CAAC;AAAA,EACF;AAAA,EAOA,oBAAoB;AACnB,SAAK,OAAO,SAAS;AACrB,SAAK,SAAS;AAAA,MACb,MAAM;AAAA,MACN,MAAM;AAAA,MACN,KAAK;AAAA,MACL,UAAU,KAAK,OAAO;AAAA,MACtB,SAAS,KAAK,OAAO;AAAA,MACrB,QAAQ,KAAK,OAAO;AAAA,MACpB,MAAM;AAAA,IACP,CAAC;AAAA,EACF;AAAA,EAOA,qBAAqB;AACpB,SAAK,OAAO,UAAU;AACtB,SAAK,SAAS;AAAA,MACb,MAAM;AAAA,MACN,MAAM;AAAA,MACN,KAAK;AAAA,MACL,UAAU,KAAK,OAAO;AAAA,MACtB,SAAS,KAAK,OAAO;AAAA,MACrB,QAAQ,KAAK,OAAO;AAAA,MACpB,MAAM;AAAA,IACP,CAAC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAsCA,SAAS,MAAmB;AAC3B,SAAK,0BAA0B,KAAK,IAAI;AACxC,QACC,EACE,KAAK,SAAS,aAAa,KAAK,SAAS,kBAC1C,KAAK,SAAS,WACd,KAAK,SAAS,UAEd;AACD,WAAK,oBAAoB,CAAC;AAAA,IAC3B;AACA,WAAO;AAAA,EACR;AAAA,EAIQ,oBAAoB,SAAiB;AAC5C,SAAK,IAAI,MAAM;AACd,UAAI,KAAK,0BAA0B,SAAS,GAAG;AAC9C,cAAM,SAAS,CAAC,GAAG,KAAK,yBAAyB;AACjD,aAAK,0BAA0B,SAAS;AACxC,mBAAW,QAAQ,QAAQ;AAC1B,eAAK,mBAAmB,IAAI;AAAA,QAC7B;AAAA,MACD;AACA,UAAI,UAAU,GAAG;AAChB,aAAK,KAAK,YAAY,EAAE,MAAM,QAAQ,MAAM,QAAQ,QAAQ,CAAC;AAAA,MAC9D;AACA,WAAK,UAAU,KAAK,OAAO;AAAA,IAC5B,CAAC;AAAA,EACF;AAAA,EAEA,mBAAmB,MAAmB;AAGrC,QAAI,KAAK,iBAAiB,EAAG,QAAO;AAEpC,UAAM,EAAE,OAAO,IAAI;AACnB,UAAM,EAAE,KAAK,IAAI;AAEjB,QAAI,KAAK,SAAS,QAAQ;AAEzB,UAAI,KAAK,SAAS,YAAY,KAAK,SAAS,YAAY;AACvD,aAAK,OAAO,aAAa;AAEzB,YAAI,KAAK,OAAO,WAAW;AAC1B,eAAK,OAAO,YAAY;AACxB,eAAK,OAAO,oBAAoB;AAChC,eAAK,UAAU,EAAE,MAAM,KAAK,aAAa,UAAU,EAAE,CAAC;AAAA,QACvD;AAAA,MACD;AAEA,WAAK,KAAK,YAAY,IAAI;AAC1B;AAAA,IACD;AAEA,QAAI,KAAK,UAAU;AAClB,mBAAa,KAAK,gBAAgB;AAClC,WAAK,mBAAmB;AACxB,aAAO,WAAW;AAAA,IACnB,WAAW,CAAC,KAAK,YAAY,OAAO,YAAY,KAAK,qBAAqB,IAAI;AAC7E,WAAK,mBAAmB,KAAK,OAAO,WAAW,KAAK,qBAAqB,GAAG;AAAA,IAC7E;AAEA,QAAI,KAAK,QAAQ;AAChB,mBAAa,KAAK,cAAc;AAChC,WAAK,iBAAiB;AACtB,aAAO,SAAS;AAAA,IACjB,WAAW,CAAC,KAAK,UAAU,OAAO,UAAU,KAAK,mBAAmB,IAAI;AACvE,WAAK,iBAAiB,KAAK,OAAO,WAAW,KAAK,mBAAmB,GAAG;AAAA,IACzE;AAEA,QAAI,KAAK,SAAS;AACjB,mBAAa,KAAK,eAAe;AACjC,WAAK,kBAAkB;AACvB,aAAO,UAAU;AAAA,IAClB,WAAW,CAAC,KAAK,WAAW,OAAO,WAAW,KAAK,oBAAoB,IAAI;AAC1E,WAAK,kBAAkB,KAAK,OAAO,WAAW,KAAK,oBAAoB,GAAG;AAAA,IAC3E;AAEA,UAAM,EAAE,iBAAiB,iBAAiB,IAAI;AAE9C,QAAI,CAAC,OAAO,YAAY;AACvB,aAAO,aAAa;AAAA,IACrB;AAEA,UAAM,gBAAgB,KAAK,MAAM,wBAAwB,6BAAa;AACtE,UAAM,YAAY,KAAK,MAAM,IAAI,KAAK,uBAAuB,CAAC;AAC9D,UAAM,gBAAgB,KAAK,eAAe,4BAA4B;AAEtE,YAAQ,MAAM;AAAA,MACb,KAAK,SAAS;AACb,YAAI,cAAc,SAAU;AAC5B,qBAAa,KAAK,iBAAiB;AACnC,aAAK,uBAAuB,IAAI;AAEhC,gBAAQ,KAAK,MAAM;AAAA,UAClB,KAAK,eAAe;AACnB,gBAAI,OAAO,WAAY;AAEvB,gBAAI,CAAC,OAAO,WAAW;AACtB,mBAAK,cAAc,KAAK,UAAU,EAAE;AACpC,kBAAI,CAAC,KAAK,+BAA+B,QAAQ;AAChD,qBAAK,iCAAiC,CAAC,GAAG,UAAU,gBAAgB;AAAA,cACrE;AAEA,mBAAK,YAAY;AAEjB,qBAAO,aAAa;AAEpB,mBAAK,UAAU;AAAA,YAChB;AAEA;AAAA,UACD;AAAA,UACA,KAAK,SAAS;AACb,gBAAI,CAAC,OAAO,WAAY;AAExB,kBAAM;AAAA,cACL,OAAO,EAAE,IAAI,EAAE;AAAA,cACf,OAAO,EAAE,GAAG,IAAI,GAAG,GAAG;AAAA,YACvB,IAAI;AAGJ,kBAAM,EAAE,GAAG,EAAE,IAAI,eAAI;AAAA,cACpB,KAAK;AAAA,cACL,cAAc,aAAa;AAAA,cAC3B,cAAc,aAAa;AAAA,YAC5B;AAEA,iBAAK,oBAAoB;AACzB,gBAAI,cAAc,iBAAiB;AAClC,mBAAK,kBAAkB;AAAA,YACxB;AAEA,kBAAM,EAAE,GAAG,IAAI,GAAG,IAAI,GAAG,GAAG,QAAI,qCAAuB,MAAM,KAAK,UAAU,CAAC;AAE7E,kBAAM,EAAE,UAAU,UAAU,IAAI;AAChC,iBAAK;AAAA,cACJ,IAAI;AAAA,gBACH,KAAM,KAAK,WAAY,KAAK,IAAI,KAAK,KAAK,IAAI;AAAA,gBAC9C,KAAM,KAAK,WAAY,KAAK,IAAI,KAAK,KAAK,IAAI;AAAA,gBAC9C,IAAI;AAAA,cACL;AAAA,cACA,EAAE,WAAW,KAAK;AAAA,YACnB;AAEA;AAAA,UACD;AAAA,UACA,KAAK,aAAa;AACjB,gBAAI,CAAC,OAAO,WAAY,QAAO;AAG/B,mBAAO,aAAa;AAGpB,kBAAM,EAAE,gCAAgC,iBAAiB,IAAI;AAC7D,iBAAK,kBAAkB,KAAK,8BAA8B;AAC1D,iBAAK,iCAAiC,CAAC;AAEvC,gBAAI,KAAK,WAAW;AACnB,mBAAK,YAAY;AACjB,kBAAI,iBAAiB,SAAS,GAAG;AAChC,qBAAK,KAAK,QAAQ,MAAM;AACvB,sBAAI,CAAC,KAAK,WAAW;AAGpB,yBAAK,kBAAkB,gBAAgB;AAAA,kBACxC;AAAA,gBACD,CAAC;AAAA,cACF;AAAA,YACD;AAEA;AAAA,UACD;AAAA,QACD;AAAA,MACD;AAAA,MACA,KAAK,SAAS;AACb,YAAI,cAAc,SAAU;AAE5B,aAAK,uBAAuB,IAAI;AAEhC,YAAI,KAAK,cAAc,GAAG;AAAA,QAE1B,OAAO;AACN,gBAAM,EAAE,UAAU,WAAW,cAAc,IAAI;AAE/C,cAAI,kBAAkB,QAAQ;AAE7B,iBAAK,oBAAoB;AAEzB,gBAAI,cAAc,iBAAiB;AAClC,mBAAK,kBAAkB;AAAA,YACxB;AAEA,kBAAM,EAAE,GAAG,IAAI,GAAG,IAAI,GAAG,GAAG,QAAI,qCAAuB,MAAM,KAAK,UAAU,CAAC;AAC7E,kBAAM,EAAE,GAAG,IAAI,GAAG,IAAI,GAAG,KAAK,EAAE,IAAI,KAAK;AAEzC,gBAAI,WAAW;AAIf,gBAAI,OAAO,QAAS,YAAW,kBAAkB,QAAQ,SAAS;AAElE,oBAAQ,UAAU;AAAA,cACjB,KAAK,QAAQ;AAEZ,sBAAM,EAAE,GAAG,EAAE,IAAI,KAAK,OAAO;AAC7B,oBAAI,QAAQ;AAGZ,oBAAI,kBAAkB,QAAQ;AAC7B,sBAAI,KAAK,IAAI,EAAE,IAAI,IAAI;AACtB,4BAAS,KAAK,KAAK,KAAK,EAAE,IAAK;AAAA,kBAChC,OAAO;AACN,4BAAQ,KAAK;AAAA,kBACd;AAAA,gBACD;AAEA,sBAAM,OAAO,MAAM,SAAS,KAAK,YAAY;AAC7C,qBAAK;AAAA,kBACJ,IAAI;AAAA,oBACH,MAAM,IAAI,OAAO,MAAM,IAAI,KAAK;AAAA,oBAChC,MAAM,IAAI,OAAO,MAAM,IAAI,KAAK;AAAA,oBAChC;AAAA,kBACD;AAAA,kBACA,EAAE,WAAW,KAAK;AAAA,gBACnB;AACA,qBAAK,sBAAsB,SAAS;AACpC;AAAA,cACD;AAAA,cACA,KAAK,OAAO;AAEX,qBAAK,WAAW,IAAI,eAAI,KAAM,KAAK,WAAY,IAAI,KAAM,KAAK,WAAY,IAAI,EAAE,GAAG;AAAA,kBAClF,WAAW;AAAA,gBACZ,CAAC;AACD,qBAAK,sBAAsB,SAAS;AACpC;AAAA,cACD;AAAA,YACD;AAAA,UACD;AAAA,QACD;AACA;AAAA,MACD;AAAA,MACA,KAAK,WAAW;AAEf,YAAI,OAAO,WAAY;AAEvB,aAAK,uBAAuB,IAAI;AAChC,cAAM,EAAE,MAAM,IAAI;AAClB,cAAM,EAAE,UAAU,IAAI;AAEtB,gBAAQ,KAAK,MAAM;AAAA,UAClB,KAAK,gBAAgB;AAEpB,gBAAI,aAAa,CAAC,MAAO;AAEzB,gBAAI,CAAC,KAAK,OAAO,WAAW;AAE3B,mBAAK,oBAAoB,KAAK,OAAO,WAAW,MAAM;AACrD,qBAAK,SAAS;AAAA,kBACb,GAAG;AAAA,kBACH,OAAO,KAAK,OAAO;AAAA,kBACnB,MAAM;AAAA,gBACP,CAAC;AAAA,cACF,GAAG,KAAK,QAAQ,mBAAmB;AAAA,YACpC;AAGA,iBAAK,iCAAiC,KAAK,oBAAoB;AAI/D,gBAAI,KAAK,WAAW,mCAAmB,MAAK,oBAAoB,KAAK;AAGrE,mBAAO,QAAQ,IAAI,KAAK,MAAM;AAG9B,mBAAO,aAAa;AACpB,mBAAO,aAAa;AAGpB,gBAAI,CAAC,aAAa,MAAO,MAAK,oBAAoB,EAAE,WAAW,KAAK,CAAC;AAGrE,gBAAI,KAAK,WAAW,uCAAsB;AACzC,mBAAK,iBAAiB,KAAK,iBAAiB;AAC5C,mBAAK,SAAS;AACd,mBAAK,eAAe,QAAQ;AAAA,YAC7B,WAAW,KAAK,WAAW,sCAAqB;AAE/C,kBAAI,CAAC,KAAK,OAAO,WAAW;AAC3B,qBAAK,cAAc,KAAK,iBAAiB,EAAE,OAAO;AAAA,cACnD;AACA,mBAAK,OAAO,YAAY;AACxB,2BAAa,KAAK,iBAAiB;AAAA,YACpC;AAIA,gBAAI,KAAK,OAAO,WAAW;AAC1B,mBAAK,oBAAoB;AACzB,mBAAK,UAAU,EAAE,MAAM,YAAY,UAAU,EAAE,CAAC;AAChD,qBAAO;AAAA,YACR;AAEA;AAAA,UACD;AAAA,UACA,KAAK,gBAAgB;AAEpB,gBAAI,CAAC,SAAS,UAAW;AAEzB,kBAAM,EAAE,GAAG,IAAI,GAAG,IAAI,GAAG,GAAG,QAAI,qCAAuB,MAAM,KAAK,UAAU,CAAC;AAG7E,gBAAI,KAAK,OAAO,aAAa,KAAK,OAAO,YAAY;AAEpD,oBAAM,EAAE,oBAAoB,oBAAoB,IAAI,KAAK;AACzD,oBAAM,EAAE,SAAS,IAAI;AACrB,oBAAM,SAAS,eAAI,IAAI,oBAAoB,mBAAmB;AAC9D,mBAAK;AAAA,gBACJ,IAAI,eAAI,KAAM,OAAO,IAAI,WAAY,IAAI,KAAM,OAAO,IAAI,WAAY,IAAI,EAAE;AAAA,gBAC5E,EAAE,WAAW,KAAK;AAAA,cACnB;AACA,mBAAK,sBAAsB,SAAS;AACpC;AAAA,YACD;AAEA,gBACC,OAAO,cACP,CAAC,OAAO,cACR,eAAI,MAAM,iBAAiB,gBAAgB,IAAI,KAAK,aAAa,KAC/D,cAAc,kBACZ,KAAK,QAAQ,4BACb,KAAK,QAAQ,uBACf,IACD;AAED,qBAAO,aAAa;AACpB,2BAAa,KAAK,iBAAiB;AAAA,YACpC;AACA;AAAA,UACD;AAAA,UACA,KAAK,cAAc;AAElB,mBAAO,aAAa;AACpB,mBAAO,aAAa;AACpB,yBAAa,KAAK,iBAAiB;AAGnC,mBAAO,QAAQ,OAAO,KAAK,MAAM;AAGjC,gBAAI,KAAK,cAAc,EAAG;AAG1B,gBAAI,cAAc,aAAa,CAAC,MAAO;AAKvC,gBAAI,KAAK,sBAAsB,KAAK,WAAW;AAC9C,mBAAK,oBAAoB;AACzB,mBAAK,SAAS;AAAA,YACf;AAEA,gBAAI,OAAO,WAAW;AACrB,kBAAI,CAAC,OAAO,KAAK,IAAI,OAAO,GAAG;AAC9B,uBAAO,YAAY;AACnB,uBAAO,oBAAoB;AAAA,cAC5B;AACA,oBAAM,iBAAiB,KAAK,OAAO;AACnC,oBAAM,aAAa,KAAK,IAAI,GAAG,eAAe,IAAI,CAAC;AAEnD,sBAAQ,KAAK,QAAQ;AAAA,gBACpB,KAAK,oCAAmB;AACvB,uBAAK,UAAU,EAAE,MAAM,QAAQ,UAAU,EAAE,CAAC;AAC5C;AAAA,gBACD;AAAA,gBACA,KAAK,sCAAqB;AACzB,sBAAI,KAAK,OAAO,KAAK,IAAI,GAAG,GAAG;AAC9B,yBAAK,UAAU,EAAE,MAAM,QAAQ,UAAU,EAAE,CAAC;AAAA,kBAC7C,OAAO;AACN,yBAAK,UAAU,EAAE,MAAM,KAAK,aAAa,UAAU,EAAE,CAAC;AAAA,kBACvD;AAAA,gBACD;AAAA,cACD;AAEA,kBAAI,aAAa,GAAG;AACnB,qBAAK,YAAY,EAAE,OAAO,YAAY,WAAW,eAAe,CAAC;AAAA,cAClE;AAAA,YACD,OAAO;AACN,kBAAI,KAAK,WAAW,uCAAsB;AAEzC,qBAAK,SAAS;AACd,qBAAK,eAAe,KAAK,cAAc;AAAA,cACxC;AAAA,YACD;AACA;AAAA,UACD;AAAA,QACD;AACA;AAAA,MACD;AAAA,MACA,KAAK,YAAY;AAEhB,YAAI,KAAK,QAAQ,aAAc,MAAK,MAAM;AAC1C,YAAI,KAAK,QAAQ,WAAY,MAAK,MAAM;AACxC,YAAI,KAAK,SAAS,eAAgB,MAAK,OAAO;AAE9C,gBAAQ,KAAK,MAAM;AAAA,UAClB,KAAK,YAAY;AAEhB,mBAAO,KAAK,IAAI,KAAK,IAAI;AAGzB,gBAAI,KAAK,SAAS,WAAW,CAAC,KAAK,SAAS;AAC3C,kBAAI,CAAC,KAAK,OAAO,WAAW;AAC3B,qBAAK,cAAc,cAAc,OAAO;AAAA,cACzC;AAEA,mBAAK,OAAO,YAAY;AACxB,mBAAK,OAAO,oBAAoB;AAChC,2BAAa,KAAK,iBAAiB;AACnC,mBAAK,UAAU,EAAE,MAAM,KAAK,OAAO,aAAa,aAAa,QAAQ,UAAU,EAAE,CAAC;AAAA,YACnF;AAEA,gBAAI,KAAK,OAAO,mBAAmB;AAClC,kBAAI;AACJ,sBAAQ,KAAK,MAAM;AAAA,gBAClB,KAAK,WAAW;AACf,2BAAS,IAAI,eAAI,GAAG,EAAE;AACtB;AAAA,gBACD;AAAA,gBACA,KAAK,cAAc;AAClB,2BAAS,IAAI,eAAI,GAAG,CAAC;AACrB;AAAA,gBACD;AAAA,gBACA,KAAK,aAAa;AACjB,2BAAS,IAAI,eAAI,GAAG,CAAC;AACrB;AAAA,gBACD;AAAA,gBACA,KAAK,aAAa;AACjB,2BAAS,IAAI,eAAI,IAAI,CAAC;AACtB;AAAA,gBACD;AAAA,cACD;AAEA,kBAAI,QAAQ;AACX,sBAAM,SAAS,KAAK,sBAAsB;AAC1C,sBAAM,OAAO,OAAO,MAAM,EAAE,UAAU,OAAO,KAAK,EAAE,GAAG,OAAO,GAAG,GAAG,OAAO,EAAE,CAAC,CAAC;AAC/E,qBAAK,mBAAmB,MAAM,EAAE,WAAW,EAAE,UAAU,IAAI,EAAE,CAAC;AAAA,cAC/D;AAAA,YACD;AAEA;AAAA,UACD;AAAA,UACA,KAAK,UAAU;AAEd,mBAAO,KAAK,OAAO,KAAK,IAAI;AAG5B,gBAAI,KAAK,SAAS,SAAS;AAC1B,kBAAI,KAAK,OAAO,QAAQ,IAAI,oCAAmB,GAAG;AAAA,cAElD,OAAO;AAEN,qBAAK,OAAO,YAAY;AACxB,qBAAK,OAAO,oBAAoB;AAChC,qBAAK,UAAU,EAAE,MAAM,KAAK,aAAa,UAAU,EAAE,CAAC;AAAA,cACvD;AAAA,YACD;AACA;AAAA,UACD;AAAA,UACA,KAAK,cAAc;AAElB;AAAA,UACD;AAAA,QACD;AACA;AAAA,MACD;AAAA,IACD;AAGA,QAAI,KAAK,SAAS,WAAW;AAC5B,UAAI,KAAK,WAAW,sCAAqB;AACxC,aAAK,OAAO;AAAA,MACb,WAAW,KAAK,WAAW,qCAAoB;AAC9C,aAAK,OAAO;AAAA,MACb;AAGA,YAAM,EAAE,UAAU,IAAI,KAAK,MAAM,wBAAwB,6BAAa;AACtE,UAAI,KAAK,UAAU,WAAW;AAI7B,cAAM,YAAY,KAAK,cAAc,mBAAmB,IAAI;AAC5D,YAAI,KAAK,SAAS,UAAU,MAAM;AACjC,eAAK,KAAK,YAAY,IAAI;AAC1B,eAAK,KAAK,SAAS,IAAI;AACvB,eAAK,KAAK,YAAY,SAAS;AAC/B,eAAK,KAAK,SAAS,SAAS;AAC5B;AAAA,QACD;AAAA,MACD;AAAA,IACD;AAIA,SAAK,KAAK,YAAY,IAAI;AAC1B,SAAK,KAAK,SAAS,IAAI;AAGvB,QAAI,KAAK,SAAS,aAAa,KAAK,SAAS,gBAAgB;AAC5D,WAAK,eAAe;AAAA,IACrB;AAEA,WAAO;AAAA,EACR;AAAA;AAAA,EAGQ,sBAAsB,MAAc;AAC3C,QAAI,8BAAW,mBAAmB,IAAI,GAAG;AACxC,UAAI,KAAK,mBAAmB,UAAU,GAAG;AACxC,qBAAa,KAAK,yBAAyB;AAAA,MAC5C,OAAO;AACN,aAAK,mBAAmB,MAAM,IAAI;AAAA,MACnC;AACA,WAAK,4BAA4B,KAAK,OAAO,WAAW,MAAM;AAC7D,aAAK,mBAAmB,KAAK;AAAA,MAC9B,GAAG,EAAE;AAAA,IACN;AAAA,EACD;AACD;AA5wSO;AA6eN,4BAAQ,yBADR,4BA5eY;AA0tBF,0CAAV,iBA1tBY;AAyvBF,0CAAV,iBAzvBY;AAogCF,uCAAV,cApgCY;AA4kCF,8CAAV,qBA5kCY;AAqlCF,gDAAV,uBArlCY;AA4nCF,mDAAV,0BA5nCY;AAspCF,gDAAV,uBAtpCY;AAmtCF,4CAAV,mBAntCY;AAwxCF,6CAAV,oBAxxCY;AAkzCF,6CAAV,oBAlzCY;AAuzCF,4BAAQ,uBAAlB,0BAvzCY;AAg0CF,mDAAV,0BAh0CY;AAq0CF,4BAAQ,0BAAlB,6BAr0CY;AAy2CF,mDAAV,0BAz2CY;AAm3CF,iDAAV,wBAn3CY;AA4/CF,sDAAV,6BA5/CY;AAwgDF,oDAAV,2BAxgDY;AA+hDF,sDAAV,6BA/hDY;AAikDF,oDAAV,2BAjkDY;AA8mDF,6DAAV,oCA9mDY;AAwnDF,+DAAV,sCAxnDY;AAuoDF,iDAAV,wBAvoDY;AAgpDF,+CAAV,sBAhpDY;AAotDF,iDAAV,wBAptDY;AA6tDF,+CAAV,sBA7tDY;AAkxDF,iDAAV,wBAlxDY;AA2xDF,+CAAV,sBA3xDY;AA+zDF,kDAAV,yBA/zDY;AAu0DF,+CAAV,sBAv0DY;AA+2DF,kDAAV,yBA/2DY;AAw3DF,gDAAV,uBAx3DY;AA09DZ,4BAAQ,uBADR,0BAz9DY;AAm+DF,yCAAV,gBAn+DY;AA++DZ,4BAAQ,qCADR,wCA9+DY;AA2gEZ,4BAAQ,yBADR,4BA1gEY;AA2hEF,4CAAV,mBA3hEY;AAw+FF,uDAAV,8BAx+FY;AAk/FF,uDAAV,8BAl/FY;AA+/FF,qDAAV,4BA//FY;AAokGZ,4BAAQ,0BADR,6BAnkGY;AAilGZ,gDADA,uBAhlGY;AAomGZ,6DADA,oCAnmGY;AA+5GF,kDAAV,yBA/5GY;AAi7GF,4BAAQ,qBAAlB,wBAj7GY;AA+7GF,wCAAV,eA/7GY;AA29GF,gDAAV,uBA39GY;AAqgHZ,4DADA,mCApgHY;AAutHF,4BAAQ,sBAAlB,yBAvtHY;AAo2HZ,4BAAQ,0BADR,6BAn2HY;AA83HF,4BAAQ,yBAAlB,4BA93HY;AA+6HF,4BAAQ,+BAAlB,kCA/6HY;AAq+HF,4BAAQ,4BAAlB,+BAr+HY;AAygIF,4BAAQ,0BAAlB,6BAzgIY;AA8iIF,4BAAQ,sBAAlB,yBA9iIY;AAmnIF,4BAAQ,kCAAlB,qCAnnIY;AA4wIZ,4BAAQ,qBADR,wBA3wIY;AAsxIZ,+CADA,sBArxIY;AA2yIF,oDAAV,2BA3yIY;AAsnJF,oDAAV,2BAtnJY;AAgoJF,0DAAV,iCAhoJY;AAipJF,mEAAV,0CAjpJY;AA0kKZ,4BAAQ,0BADR,6BAzkKY;AAsvOZ,4BAAQ,6BADR,gCArvOY;AAsyOZ,+CADA,sBAryOY;AAo0OF,gDAAV,uBAp0OY;AA23QF,4CAAV,mBA33QY;AAiqRZ,mDADA,0BAhqRY;AAmrRZ,iDADA,wBAlrRY;AAqsRZ,kDADA,yBApsRY;AAAN,2BAAM;AA8wSb,SAAS,eAAe,QAAgB,SAAS,OAAO,iBAAiB,GAAG;AAC3E,QAAM,OAAO,OAAO,QAAQ,MAAM,EAAG;AACrC,SAAO,KAAK,cAAc,EAAE,MAAM,QAAQ,OAAO,OAAO,QAAQ,iBAAiB,CAAC;AACnF;AAEA,SAAS,8BAEP,MAAS,SAA2D;AACrE,MAAI,CAAC,QAAS,QAAO;AACrB,MAAI,OAAO;AACX,QAAM,UAAU,OAAO,QAAQ,OAAO;AACtC,WAAS,IAAI,GAAG,IAAI,QAAQ,QAAQ,IAAI,GAAG,KAAK;AAC/C,UAAM,CAAC,GAAG,CAAC,IAAI,QAAQ,CAAC;AACxB,QAAI,MAAM,OAAW;AAGrB,QAAI,MAAM,QAAQ,MAAM,UAAU,MAAM,WAAY;AAGpD,QAAI,MAAO,KAAa,CAAC,EAAG;AAG5B,QAAI,CAAC,KAAM,QAAO,EAAE,GAAG,KAAK;AAG5B,QAAI,MAAM,WAAW,MAAM,QAAQ;AAClC,WAAK,CAAC,IAAI,EAAE,GAAG,KAAK,CAAC,EAAE;AACvB,iBAAW,CAAC,SAAS,SAAS,KAAK,OAAO,QAAQ,CAAW,GAAG;AAC/D,YAAI,cAAc,QAAW;AAC5B;AAAC,UAAC,KAAK,CAAC,EAAiB,OAAO,IAAI;AAAA,QACrC;AAAA,MACD;AACA;AAAA,IACD;AAGA;AAAC,IAAC,KAAa,CAAC,IAAI;AAAA,EACrB;AACA,MAAI,CAAC,KAAM,QAAO;AAClB,SAAO;AACR;AAEA,SAAS,yBAAyB,QAAgB,IAAe,QAAyB;AACzF,QAAM,QAAQ,OAAO,SAAS,EAAE;AAChC,MAAI,CAAC,MAAO;AACZ,SAAO,KAAK,KAAK;AACjB,QAAM,WAAW,OAAO,2BAA2B,EAAE;AACrD,WAAS,IAAI,GAAG,IAAI,SAAS,QAAQ,IAAI,GAAG,KAAK;AAChD,6BAAyB,QAAQ,SAAS,CAAC,GAAG,MAAM;AAAA,EACrD;AACD;AASA,SAAS,mBACR,QACA,UACA,UACI;AACJ,MAAI;AAEJ,SAAO;AAAA,IACN,MAAM;AACL,YAAM,UAAU,OAAO,MAAM,kBAAkB,MAAM;AACpD,cAAM,mBAAmB,oBAAI,IAAiB;AAC9C,cAAM,mBAAmB,oBAAI,IAAiB;AAE9C,mBAAW,WAAW,UAAU;AAC/B,gBAAM,QAAQ,OAAO,SAAS,OAAO;AACrC,cAAI,CAAC,MAAO;AAEZ,qBAAW,WAAW,OAAO,0BAA0B,OAAO,GAAG;AAChE,kBAAM,UAAU,SAAS,IAAI,QAAQ,MAAM;AAC3C,kBAAM,QAAQ,SAAS,IAAI,QAAQ,IAAI;AACvC,gBAAI,WAAW,OAAO;AACrB,+BAAiB,IAAI,QAAQ,EAAE;AAC/B;AAAA,YACD;AACA,gBAAI,CAAC,WAAW,CAAC,OAAO;AACvB,+BAAiB,IAAI,QAAQ,EAAE;AAAA,YAChC;AAAA,UACD;AAAA,QACD;AAEA,eAAO,eAAe,CAAC,GAAG,gBAAgB,GAAG,EAAE,eAAe,KAAK,CAAC;AAEpE,YAAI;AACH,mBAAS,oBAAO,GAAG,SAAS,gBAAgB,CAAC;AAAA,QAC9C,SAAS,OAAO;AACf,mBAAS,oBAAO,IAAI,KAAK;AAAA,QAC1B;AAAA,MACD,CAAC;AAED,aAAO,MAAM,cAAU,iCAAmB,OAAO,CAAC;AAAA,IACnD;AAAA,IACA,EAAE,SAAS,SAAS;AAAA,EACrB;AAEA,MAAI,OAAO,IAAI;AACd,WAAO,OAAO;AAAA,EACf,OAAO;AACN,UAAM,OAAO;AAAA,EACd;AACD;AAEA,SAAS,kBAAkB,QAAgB,eAAgC;AAC1E,MAAI,CAAC,cAAc,YAAa,OAAM,MAAM,8BAA8B;AAC1E,QAAM;AAAA,IACL,SAAS,EAAE,GAAG,IAAI,GAAG,GAAG;AAAA,EACzB,IAAI,cAAc;AAClB,QAAM,MAAM,OAAO,wBAAwB;AAC3C,QAAM,SAAS,eAAI,KAAK,cAAc,YAAY,MAAM;AACxD,QAAM,MAAM,IAAI,IAAI,KAAK,KAAK,OAAO;AACrC,QAAM,MAAM,IAAI,IAAI,KAAK,KAAK,OAAO;AACrC,SAAO,EAAE,IAAI,GAAG;AACjB;", -+ "sourcesContent": ["import { EMPTY_ARRAY, atom, computed, react, transact, unsafe__withoutCapture } from '@tldraw/state'\nimport {\n\tComputedCache,\n\tRecordType,\n\tStoreSideEffects,\n\tStoreSnapshot,\n\tUnknownRecord,\n\treverseRecordsDiff,\n} from '@tldraw/store'\nimport {\n\tCameraRecordType,\n\tInstancePageStateRecordType,\n\tPageRecordType,\n\tStyleProp,\n\tStylePropValue,\n\tTLArrowShape,\n\tTLAsset,\n\tTLAssetId,\n\tTLAssetPartial,\n\tTLBinding,\n\tTLBindingCreate,\n\tTLBindingId,\n\tTLBindingUpdate,\n\tTLCamera,\n\tTLCursor,\n\tTLCursorType,\n\tTLDOCUMENT_ID,\n\tTLDocument,\n\tTLFrameShape,\n\tTLGeoShape,\n\tTLGroupShape,\n\tTLHandle,\n\tTLINSTANCE_ID,\n\tTLImageAsset,\n\tTLInstance,\n\tTLInstancePageState,\n\tTLPOINTER_ID,\n\tTLPage,\n\tTLPageId,\n\tTLParentId,\n\tTLRecord,\n\tTLShape,\n\tTLShapeId,\n\tTLShapePartial,\n\tTLStore,\n\tTLStoreSnapshot,\n\tTLUnknownBinding,\n\tTLUnknownShape,\n\tTLVideoAsset,\n\tcreateBindingId,\n\tcreateShapeId,\n\tgetShapePropKeysByStyle,\n\tisPageId,\n\tisShapeId,\n} from '@tldraw/tlschema'\nimport {\n\tFileHelpers,\n\tIndexKey,\n\tJsonObject,\n\tPerformanceTracker,\n\tResult,\n\tTimers,\n\tannotateError,\n\tassert,\n\tassertExists,\n\tbind,\n\tcompact,\n\tdebounce,\n\tdedupe,\n\texhaustiveSwitchError,\n\tfetch,\n\tgetIndexAbove,\n\tgetIndexBetween,\n\tgetIndices,\n\tgetIndicesAbove,\n\tgetIndicesBetween,\n\tgetOwnProperty,\n\thasOwnProperty,\n\tlast,\n\tlerp,\n\tsortById,\n\tsortByIndex,\n\tstructuredClone,\n\tuniqueId,\n} from '@tldraw/utils'\nimport EventEmitter from 'eventemitter3'\nimport {\n\tTLEditorSnapshot,\n\tTLLoadSnapshotOptions,\n\tgetSnapshot,\n\tloadSnapshot,\n} from '../config/TLEditorSnapshot'\nimport { TLUser, createTLUser } from '../config/createTLUser'\nimport { TLAnyBindingUtilConstructor, checkBindings } from '../config/defaultBindings'\nimport { TLAnyShapeUtilConstructor, checkShapesAndAddCore } from '../config/defaultShapes'\nimport {\n\tDEFAULT_ANIMATION_OPTIONS,\n\tDEFAULT_CAMERA_OPTIONS,\n\tINTERNAL_POINTER_IDS,\n\tLEFT_MOUSE_BUTTON,\n\tMIDDLE_MOUSE_BUTTON,\n\tRIGHT_MOUSE_BUTTON,\n\tSTYLUS_ERASER_BUTTON,\n\tZOOM_TO_FIT_PADDING,\n} from '../constants'\nimport { exportToSvg } from '../exports/exportToSvg'\nimport { TldrawOptions, defaultTldrawOptions } from '../options'\nimport { Box, BoxLike } from '../primitives/Box'\nimport { Mat, MatLike } from '../primitives/Mat'\nimport { Vec, VecLike } from '../primitives/Vec'\nimport { EASINGS } from '../primitives/easings'\nimport { Geometry2d } from '../primitives/geometry/Geometry2d'\nimport { Group2d } from '../primitives/geometry/Group2d'\nimport { intersectPolygonPolygon } from '../primitives/intersect'\nimport { PI2, approximately, areAnglesCompatible, clamp, pointInPolygon } from '../primitives/utils'\nimport { ReadonlySharedStyleMap, SharedStyle, SharedStyleMap } from '../utils/SharedStylesMap'\nimport { dataUrlToFile } from '../utils/assets'\nimport { debugFlags } from '../utils/debug-flags'\nimport {\n\tTLDeepLink,\n\tTLDeepLinkOptions,\n\tcreateDeepLinkString,\n\tparseDeepLinkString,\n} from '../utils/deepLinks'\nimport { getIncrementedName } from '../utils/getIncrementedName'\nimport { getReorderingShapesChanges } from '../utils/reorderShapes'\nimport { applyRotationToSnapshotShapes, getRotationSnapshot } from '../utils/rotation'\nimport { BindingOnDeleteOptions, BindingUtil } from './bindings/BindingUtil'\nimport { bindingsIndex } from './derivations/bindingsIndex'\nimport { notVisibleShapes } from './derivations/notVisibleShapes'\nimport { parentsToChildren } from './derivations/parentsToChildren'\nimport { deriveShapeIdsInCurrentPage } from './derivations/shapeIdsInCurrentPage'\nimport { ClickManager } from './managers/ClickManager'\nimport { EdgeScrollManager } from './managers/EdgeScrollManager'\nimport { EnvironmentManager } from './managers/EnvironmentManager'\nimport { FocusManager } from './managers/FocusManager'\nimport { HistoryManager } from './managers/HistoryManager'\nimport { ScribbleManager } from './managers/ScribbleManager'\nimport { SnapManager } from './managers/SnapManager/SnapManager'\nimport { TextManager } from './managers/TextManager'\nimport { TickManager } from './managers/TickManager'\nimport { UserPreferencesManager } from './managers/UserPreferencesManager'\nimport { ShapeUtil, TLResizeMode } from './shapes/ShapeUtil'\nimport { RootState } from './tools/RootState'\nimport { StateNode, TLStateNodeConstructor } from './tools/StateNode'\nimport { TLContent } from './types/clipboard-types'\nimport { TLEventMap } from './types/emit-types'\nimport {\n\tTLEventInfo,\n\tTLPinchEventInfo,\n\tTLPointerEventInfo,\n\tTLWheelEventInfo,\n} from './types/event-types'\nimport { TLExternalAssetContent, TLExternalContent } from './types/external-content'\nimport { TLHistoryBatchOptions } from './types/history-types'\nimport {\n\tOptionalKeys,\n\tRequiredKeys,\n\tTLCameraMoveOptions,\n\tTLCameraOptions,\n\tTLImageExportOptions,\n} from './types/misc-types'\nimport { TLResizeHandle } from './types/selection-types'\n\n/** @public */\nexport type TLResizeShapeOptions = Partial<{\n\tinitialBounds: Box\n\tscaleOrigin: VecLike\n\tscaleAxisRotation: number\n\tinitialShape: TLShape\n\tinitialPageTransform: MatLike\n\tdragHandle: TLResizeHandle\n\tisAspectRatioLocked: boolean\n\tmode: TLResizeMode\n\tskipStartAndEndCallbacks: boolean\n}>\n\n/** @public */\nexport interface TLEditorOptions {\n\t/**\n\t * The Store instance to use for keeping the app's data. This may be prepopulated, e.g. by loading\n\t * from a server or database.\n\t */\n\tstore: TLStore\n\t/**\n\t * An array of shapes to use in the editor. These will be used to create and manage shapes in the editor.\n\t */\n\tshapeUtils: readonly TLAnyShapeUtilConstructor[]\n\t/**\n\t * An array of bindings to use in the editor. These will be used to create and manage bindings in the editor.\n\t */\n\tbindingUtils: readonly TLAnyBindingUtilConstructor[]\n\t/**\n\t * An array of tools to use in the editor. These will be used to handle events and manage user interactions in the editor.\n\t */\n\ttools: readonly TLStateNodeConstructor[]\n\t/**\n\t * Should return a containing html element which has all the styles applied to the editor. If not\n\t * given, the body element will be used.\n\t */\n\tgetContainer(): HTMLElement\n\t/**\n\t * A user defined externally to replace the default user.\n\t */\n\tuser?: TLUser\n\t/**\n\t * The editor's initial active tool (or other state node id).\n\t */\n\tinitialState?: string\n\t/**\n\t * Whether to automatically focus the editor when it mounts.\n\t */\n\tautoFocus?: boolean\n\t/**\n\t * Whether to infer dark mode from the user's system preferences. Defaults to false.\n\t */\n\tinferDarkMode?: boolean\n\t/**\n\t * Options for the editor's camera.\n\t */\n\tcameraOptions?: Partial\n\toptions?: Partial\n\tlicenseKey?: string\n\t/**\n\t * A predicate that should return true if the given shape should be hidden.\n\t * @param shape - The shape to check.\n\t * @param editor - The editor instance.\n\t */\n\tisShapeHidden?(shape: TLShape, editor: Editor): boolean\n}\n\n/**\n * Options for {@link Editor.(run:1)}.\n * @public\n */\nexport interface TLEditorRunOptions extends TLHistoryBatchOptions {\n\tignoreShapeLock?: boolean\n}\n\n/** @public */\nexport interface TLRenderingShape {\n\tid: TLShapeId\n\tshape: TLShape\n\tutil: ShapeUtil\n\tindex: number\n\tbackgroundIndex: number\n\topacity: number\n}\n\n/** @public */\nexport class Editor extends EventEmitter {\n\tconstructor({\n\t\tstore,\n\t\tuser,\n\t\tshapeUtils,\n\t\tbindingUtils,\n\t\ttools,\n\t\tgetContainer,\n\t\tcameraOptions,\n\t\tinitialState,\n\t\tautoFocus,\n\t\tinferDarkMode,\n\t\toptions,\n\t\tisShapeHidden,\n\t}: TLEditorOptions) {\n\t\tsuper()\n\n\t\tthis._isShapeHiddenPredicate = isShapeHidden\n\n\t\tthis.options = { ...defaultTldrawOptions, ...options }\n\t\tthis.store = store\n\t\tthis.disposables.add(this.store.dispose.bind(this.store))\n\t\tthis.history = new HistoryManager({\n\t\t\tstore,\n\t\t\tannotateError: (error) => {\n\t\t\t\tthis.annotateError(error, { origin: 'history.batch', willCrashApp: true })\n\t\t\t\tthis.crash(error)\n\t\t\t},\n\t\t})\n\n\t\tthis.snaps = new SnapManager(this)\n\n\t\tthis.timers = new Timers()\n\t\tthis.disposables.add(this.timers.dispose.bind(this.timers))\n\n\t\tthis._cameraOptions.set({ ...DEFAULT_CAMERA_OPTIONS, ...cameraOptions })\n\n\t\tthis.user = new UserPreferencesManager(user ?? createTLUser(), inferDarkMode ?? false)\n\n\t\tthis.getContainer = getContainer\n\n\t\tthis.textMeasure = new TextManager(this)\n\t\tthis._tickManager = new TickManager(this)\n\n\t\tclass NewRoot extends RootState {\n\t\t\tstatic override initial = initialState ?? ''\n\t\t}\n\n\t\tthis.root = new NewRoot(this)\n\t\tthis.root.children = {}\n\n\t\tconst allShapeUtils = checkShapesAndAddCore(shapeUtils)\n\n\t\tconst _shapeUtils = {} as Record>\n\t\tconst _styleProps = {} as Record, string>>\n\t\tconst allStylesById = new Map>()\n\n\t\tfor (const Util of allShapeUtils) {\n\t\t\tconst util = new Util(this)\n\t\t\t_shapeUtils[Util.type] = util\n\n\t\t\tconst propKeysByStyle = getShapePropKeysByStyle(Util.props ?? {})\n\t\t\t_styleProps[Util.type] = propKeysByStyle\n\n\t\t\tfor (const style of propKeysByStyle.keys()) {\n\t\t\t\tif (!allStylesById.has(style.id)) {\n\t\t\t\t\tallStylesById.set(style.id, style)\n\t\t\t\t} else if (allStylesById.get(style.id) !== style) {\n\t\t\t\t\tthrow Error(\n\t\t\t\t\t\t`Multiple style props with id \"${style.id}\" in use. Style prop IDs must be unique.`\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tthis.shapeUtils = _shapeUtils\n\t\tthis.styleProps = _styleProps\n\n\t\tconst allBindingUtils = checkBindings(bindingUtils)\n\t\tconst _bindingUtils = {} as Record>\n\t\tfor (const Util of allBindingUtils) {\n\t\t\tconst util = new Util(this)\n\t\t\t_bindingUtils[Util.type] = util\n\t\t}\n\t\tthis.bindingUtils = _bindingUtils\n\n\t\t// Tools.\n\t\t// Accept tools from constructor parameters which may not conflict with the root note's default or\n\t\t// \"baked in\" tools, select and zoom.\n\t\tfor (const Tool of [...tools]) {\n\t\t\tif (hasOwnProperty(this.root.children!, Tool.id)) {\n\t\t\t\tthrow Error(`Can't override tool with id \"${Tool.id}\"`)\n\t\t\t}\n\t\t\tthis.root.children![Tool.id] = new Tool(this, this.root)\n\t\t}\n\n\t\tthis.environment = new EnvironmentManager(this)\n\t\tthis.scribbles = new ScribbleManager(this)\n\n\t\t// Cleanup\n\n\t\tconst cleanupInstancePageState = (\n\t\t\tprevPageState: TLInstancePageState,\n\t\t\tshapesNoLongerInPage: Set\n\t\t) => {\n\t\t\tlet nextPageState = null as null | TLInstancePageState\n\n\t\t\tconst selectedShapeIds = prevPageState.selectedShapeIds.filter(\n\t\t\t\t(id) => !shapesNoLongerInPage.has(id)\n\t\t\t)\n\t\t\tif (selectedShapeIds.length !== prevPageState.selectedShapeIds.length) {\n\t\t\t\tif (!nextPageState) nextPageState = { ...prevPageState }\n\t\t\t\tnextPageState.selectedShapeIds = selectedShapeIds\n\t\t\t}\n\n\t\t\tconst erasingShapeIds = prevPageState.erasingShapeIds.filter(\n\t\t\t\t(id) => !shapesNoLongerInPage.has(id)\n\t\t\t)\n\t\t\tif (erasingShapeIds.length !== prevPageState.erasingShapeIds.length) {\n\t\t\t\tif (!nextPageState) nextPageState = { ...prevPageState }\n\t\t\t\tnextPageState.erasingShapeIds = erasingShapeIds\n\t\t\t}\n\n\t\t\tif (prevPageState.hoveredShapeId && shapesNoLongerInPage.has(prevPageState.hoveredShapeId)) {\n\t\t\t\tif (!nextPageState) nextPageState = { ...prevPageState }\n\t\t\t\tnextPageState.hoveredShapeId = null\n\t\t\t}\n\n\t\t\tif (prevPageState.editingShapeId && shapesNoLongerInPage.has(prevPageState.editingShapeId)) {\n\t\t\t\tif (!nextPageState) nextPageState = { ...prevPageState }\n\t\t\t\tnextPageState.editingShapeId = null\n\t\t\t}\n\n\t\t\tconst hintingShapeIds = prevPageState.hintingShapeIds.filter(\n\t\t\t\t(id) => !shapesNoLongerInPage.has(id)\n\t\t\t)\n\t\t\tif (hintingShapeIds.length !== prevPageState.hintingShapeIds.length) {\n\t\t\t\tif (!nextPageState) nextPageState = { ...prevPageState }\n\t\t\t\tnextPageState.hintingShapeIds = hintingShapeIds\n\t\t\t}\n\n\t\t\tif (prevPageState.focusedGroupId && shapesNoLongerInPage.has(prevPageState.focusedGroupId)) {\n\t\t\t\tif (!nextPageState) nextPageState = { ...prevPageState }\n\t\t\t\tnextPageState.focusedGroupId = null\n\t\t\t}\n\t\t\treturn nextPageState\n\t\t}\n\n\t\tthis.sideEffects = this.store.sideEffects\n\n\t\tlet deletedBindings = new Map>()\n\t\tconst deletedShapeIds = new Set()\n\t\tconst invalidParents = new Set()\n\t\tlet invalidBindingTypes = new Set()\n\t\tthis.disposables.add(\n\t\t\tthis.sideEffects.registerOperationCompleteHandler(() => {\n\t\t\t\t// this needs to be cleared here because further effects may delete more shapes\n\t\t\t\t// and we want the next invocation of this handler to handle those separately\n\t\t\t\tdeletedShapeIds.clear()\n\n\t\t\t\tfor (const parentId of invalidParents) {\n\t\t\t\t\tinvalidParents.delete(parentId)\n\t\t\t\t\tconst parent = this.getShape(parentId)\n\t\t\t\t\tif (!parent) continue\n\n\t\t\t\t\tconst util = this.getShapeUtil(parent)\n\t\t\t\t\tconst changes = util.onChildrenChange?.(parent)\n\n\t\t\t\t\tif (changes?.length) {\n\t\t\t\t\t\tthis.updateShapes(changes)\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (invalidBindingTypes.size) {\n\t\t\t\t\tconst t = invalidBindingTypes\n\t\t\t\t\tinvalidBindingTypes = new Set()\n\t\t\t\t\tfor (const type of t) {\n\t\t\t\t\t\tconst util = this.getBindingUtil(type)\n\t\t\t\t\t\tutil.onOperationComplete?.()\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (deletedBindings.size) {\n\t\t\t\t\tconst t = deletedBindings\n\t\t\t\t\tdeletedBindings = new Map()\n\t\t\t\t\tfor (const opts of t.values()) {\n\t\t\t\t\t\tthis.getBindingUtil(opts.binding).onAfterDelete?.(opts)\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tthis.emit('update')\n\t\t\t})\n\t\t)\n\n\t\tthis.disposables.add(\n\t\t\tthis.sideEffects.register({\n\t\t\t\tshape: {\n\t\t\t\t\tafterChange: (shapeBefore, shapeAfter) => {\n\t\t\t\t\t\tfor (const binding of this.getBindingsInvolvingShape(shapeAfter)) {\n\t\t\t\t\t\t\tinvalidBindingTypes.add(binding.type)\n\t\t\t\t\t\t\tif (binding.fromId === shapeAfter.id) {\n\t\t\t\t\t\t\t\tthis.getBindingUtil(binding).onAfterChangeFromShape?.({\n\t\t\t\t\t\t\t\t\tbinding,\n\t\t\t\t\t\t\t\t\tshapeBefore,\n\t\t\t\t\t\t\t\t\tshapeAfter,\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (binding.toId === shapeAfter.id) {\n\t\t\t\t\t\t\t\tthis.getBindingUtil(binding).onAfterChangeToShape?.({\n\t\t\t\t\t\t\t\t\tbinding,\n\t\t\t\t\t\t\t\t\tshapeBefore,\n\t\t\t\t\t\t\t\t\tshapeAfter,\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// if the shape's parent changed and it has a binding, update the binding\n\t\t\t\t\t\tif (shapeBefore.parentId !== shapeAfter.parentId) {\n\t\t\t\t\t\t\tconst notifyBindingAncestryChange = (id: TLShapeId) => {\n\t\t\t\t\t\t\t\tconst descendantShape = this.getShape(id)\n\t\t\t\t\t\t\t\tif (!descendantShape) return\n\n\t\t\t\t\t\t\t\tfor (const binding of this.getBindingsInvolvingShape(descendantShape)) {\n\t\t\t\t\t\t\t\t\tinvalidBindingTypes.add(binding.type)\n\n\t\t\t\t\t\t\t\t\tif (binding.fromId === descendantShape.id) {\n\t\t\t\t\t\t\t\t\t\tthis.getBindingUtil(binding).onAfterChangeFromShape?.({\n\t\t\t\t\t\t\t\t\t\t\tbinding,\n\t\t\t\t\t\t\t\t\t\t\tshapeBefore: descendantShape,\n\t\t\t\t\t\t\t\t\t\t\tshapeAfter: descendantShape,\n\t\t\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tif (binding.toId === descendantShape.id) {\n\t\t\t\t\t\t\t\t\t\tthis.getBindingUtil(binding).onAfterChangeToShape?.({\n\t\t\t\t\t\t\t\t\t\t\tbinding,\n\t\t\t\t\t\t\t\t\t\t\tshapeBefore: descendantShape,\n\t\t\t\t\t\t\t\t\t\t\tshapeAfter: descendantShape,\n\t\t\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tnotifyBindingAncestryChange(shapeAfter.id)\n\t\t\t\t\t\t\tthis.visitDescendants(shapeAfter.id, notifyBindingAncestryChange)\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// if this shape moved to a new page, clean up any previous page's instance state\n\t\t\t\t\t\tif (shapeBefore.parentId !== shapeAfter.parentId && isPageId(shapeAfter.parentId)) {\n\t\t\t\t\t\t\tconst allMovingIds = new Set([shapeBefore.id])\n\t\t\t\t\t\t\tthis.visitDescendants(shapeBefore.id, (id) => {\n\t\t\t\t\t\t\t\tallMovingIds.add(id)\n\t\t\t\t\t\t\t})\n\n\t\t\t\t\t\t\tfor (const instancePageState of this.getPageStates()) {\n\t\t\t\t\t\t\t\tif (instancePageState.pageId === shapeAfter.parentId) continue\n\t\t\t\t\t\t\t\tconst nextPageState = cleanupInstancePageState(instancePageState, allMovingIds)\n\n\t\t\t\t\t\t\t\tif (nextPageState) {\n\t\t\t\t\t\t\t\t\tthis.store.put([nextPageState])\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (shapeBefore.parentId && isShapeId(shapeBefore.parentId)) {\n\t\t\t\t\t\t\tinvalidParents.add(shapeBefore.parentId)\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (shapeAfter.parentId !== shapeBefore.parentId && isShapeId(shapeAfter.parentId)) {\n\t\t\t\t\t\t\tinvalidParents.add(shapeAfter.parentId)\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t\tbeforeDelete: (shape) => {\n\t\t\t\t\t\t// if we triggered this delete with a recursive call, don't do anything\n\t\t\t\t\t\tif (deletedShapeIds.has(shape.id)) return\n\t\t\t\t\t\t// if the deleted shape has a parent shape make sure we call it's onChildrenChange callback\n\t\t\t\t\t\tif (shape.parentId && isShapeId(shape.parentId)) {\n\t\t\t\t\t\t\tinvalidParents.add(shape.parentId)\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tdeletedShapeIds.add(shape.id)\n\n\t\t\t\t\t\tconst deleteBindingIds: TLBindingId[] = []\n\t\t\t\t\t\tfor (const binding of this.getBindingsInvolvingShape(shape)) {\n\t\t\t\t\t\t\tinvalidBindingTypes.add(binding.type)\n\t\t\t\t\t\t\tdeleteBindingIds.push(binding.id)\n\t\t\t\t\t\t\tconst util = this.getBindingUtil(binding)\n\t\t\t\t\t\t\tif (binding.fromId === shape.id) {\n\t\t\t\t\t\t\t\tutil.onBeforeIsolateToShape?.({ binding, removedShape: shape })\n\t\t\t\t\t\t\t\tutil.onBeforeDeleteFromShape?.({ binding, shape })\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tutil.onBeforeIsolateFromShape?.({ binding, removedShape: shape })\n\t\t\t\t\t\t\t\tutil.onBeforeDeleteToShape?.({ binding, shape })\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (deleteBindingIds.length) {\n\t\t\t\t\t\t\tthis.deleteBindings(deleteBindingIds)\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst deletedIds = new Set([shape.id])\n\t\t\t\t\t\tconst updates = compact(\n\t\t\t\t\t\t\tthis.getPageStates().map((pageState) => {\n\t\t\t\t\t\t\t\treturn cleanupInstancePageState(pageState, deletedIds)\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t)\n\n\t\t\t\t\t\tif (updates.length) {\n\t\t\t\t\t\t\tthis.store.put(updates)\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tbinding: {\n\t\t\t\t\tbeforeCreate: (binding) => {\n\t\t\t\t\t\tconst next = this.getBindingUtil(binding).onBeforeCreate?.({ binding })\n\t\t\t\t\t\tif (next) return next\n\t\t\t\t\t\treturn binding\n\t\t\t\t\t},\n\t\t\t\t\tafterCreate: (binding) => {\n\t\t\t\t\t\tinvalidBindingTypes.add(binding.type)\n\t\t\t\t\t\tthis.getBindingUtil(binding).onAfterCreate?.({ binding })\n\t\t\t\t\t},\n\t\t\t\t\tbeforeChange: (bindingBefore, bindingAfter) => {\n\t\t\t\t\t\tconst updated = this.getBindingUtil(bindingAfter).onBeforeChange?.({\n\t\t\t\t\t\t\tbindingBefore,\n\t\t\t\t\t\t\tbindingAfter,\n\t\t\t\t\t\t})\n\t\t\t\t\t\tif (updated) return updated\n\t\t\t\t\t\treturn bindingAfter\n\t\t\t\t\t},\n\t\t\t\t\tafterChange: (bindingBefore, bindingAfter) => {\n\t\t\t\t\t\tinvalidBindingTypes.add(bindingAfter.type)\n\t\t\t\t\t\tthis.getBindingUtil(bindingAfter).onAfterChange?.({ bindingBefore, bindingAfter })\n\t\t\t\t\t},\n\t\t\t\t\tbeforeDelete: (binding) => {\n\t\t\t\t\t\tthis.getBindingUtil(binding).onBeforeDelete?.({ binding })\n\t\t\t\t\t},\n\t\t\t\t\tafterDelete: (binding) => {\n\t\t\t\t\t\tthis.getBindingUtil(binding).onAfterDelete?.({ binding })\n\t\t\t\t\t\tinvalidBindingTypes.add(binding.type)\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tpage: {\n\t\t\t\t\tafterCreate: (record) => {\n\t\t\t\t\t\tconst cameraId = CameraRecordType.createId(record.id)\n\t\t\t\t\t\tconst _pageStateId = InstancePageStateRecordType.createId(record.id)\n\t\t\t\t\t\tif (!this.store.has(cameraId)) {\n\t\t\t\t\t\t\tthis.store.put([CameraRecordType.create({ id: cameraId })])\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (!this.store.has(_pageStateId)) {\n\t\t\t\t\t\t\tthis.store.put([\n\t\t\t\t\t\t\t\tInstancePageStateRecordType.create({ id: _pageStateId, pageId: record.id }),\n\t\t\t\t\t\t\t])\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t\tafterDelete: (record, source) => {\n\t\t\t\t\t\t// page was deleted, need to check whether it's the current page and select another one if so\n\t\t\t\t\t\tif (this.getInstanceState()?.currentPageId === record.id) {\n\t\t\t\t\t\t\tconst backupPageId = this.getPages().find((p) => p.id !== record.id)?.id\n\t\t\t\t\t\t\tif (backupPageId) {\n\t\t\t\t\t\t\t\tthis.store.put([{ ...this.getInstanceState(), currentPageId: backupPageId }])\n\t\t\t\t\t\t\t} else if (source === 'user') {\n\t\t\t\t\t\t\t\t// fall back to ensureStoreIsUsable:\n\t\t\t\t\t\t\t\tthis.store.ensureStoreIsUsable()\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// delete the camera and state for the page if necessary\n\t\t\t\t\t\tconst cameraId = CameraRecordType.createId(record.id)\n\t\t\t\t\t\tconst instance_PageStateId = InstancePageStateRecordType.createId(record.id)\n\t\t\t\t\t\tthis.store.remove([cameraId, instance_PageStateId])\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tinstance: {\n\t\t\t\t\tafterChange: (prev, next, source) => {\n\t\t\t\t\t\t// instance should never be updated to a page that no longer exists (this can\n\t\t\t\t\t\t// happen when undoing a change that involves switching to a page that has since\n\t\t\t\t\t\t// been deleted by another user)\n\t\t\t\t\t\tif (!this.store.has(next.currentPageId)) {\n\t\t\t\t\t\t\tconst backupPageId = this.store.has(prev.currentPageId)\n\t\t\t\t\t\t\t\t? prev.currentPageId\n\t\t\t\t\t\t\t\t: this.getPages()[0]?.id\n\t\t\t\t\t\t\tif (backupPageId) {\n\t\t\t\t\t\t\t\tthis.store.update(next.id, (instance) => ({\n\t\t\t\t\t\t\t\t\t...instance,\n\t\t\t\t\t\t\t\t\tcurrentPageId: backupPageId,\n\t\t\t\t\t\t\t\t}))\n\t\t\t\t\t\t\t} else if (source === 'user') {\n\t\t\t\t\t\t\t\t// fall back to ensureStoreIsUsable:\n\t\t\t\t\t\t\t\tthis.store.ensureStoreIsUsable()\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tinstance_page_state: {\n\t\t\t\t\tafterChange: (prev, next) => {\n\t\t\t\t\t\tif (prev?.selectedShapeIds !== next?.selectedShapeIds) {\n\t\t\t\t\t\t\t// ensure that descendants and ancestors are not selected at the same time\n\t\t\t\t\t\t\tconst filtered = next.selectedShapeIds.filter((id) => {\n\t\t\t\t\t\t\t\tlet parentId = this.getShape(id)?.parentId\n\t\t\t\t\t\t\t\twhile (isShapeId(parentId)) {\n\t\t\t\t\t\t\t\t\tif (next.selectedShapeIds.includes(parentId)) {\n\t\t\t\t\t\t\t\t\t\treturn false\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tparentId = this.getShape(parentId)?.parentId\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\treturn true\n\t\t\t\t\t\t\t})\n\n\t\t\t\t\t\t\tlet nextFocusedGroupId: null | TLShapeId = null\n\n\t\t\t\t\t\t\tif (filtered.length > 0) {\n\t\t\t\t\t\t\t\tconst commonGroupAncestor = this.findCommonAncestor(\n\t\t\t\t\t\t\t\t\tcompact(filtered.map((id) => this.getShape(id))),\n\t\t\t\t\t\t\t\t\t(shape) => this.isShapeOfType(shape, 'group')\n\t\t\t\t\t\t\t\t)\n\n\t\t\t\t\t\t\t\tif (commonGroupAncestor) {\n\t\t\t\t\t\t\t\t\tnextFocusedGroupId = commonGroupAncestor\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tif (next?.focusedGroupId) {\n\t\t\t\t\t\t\t\t\tnextFocusedGroupId = next.focusedGroupId\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\tfiltered.length !== next.selectedShapeIds.length ||\n\t\t\t\t\t\t\t\tnextFocusedGroupId !== next.focusedGroupId\n\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\tthis.store.put([\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t...next,\n\t\t\t\t\t\t\t\t\t\tselectedShapeIds: filtered,\n\t\t\t\t\t\t\t\t\t\tfocusedGroupId: nextFocusedGroupId ?? null,\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t])\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t})\n\t\t)\n\n\t\tthis._currentPageShapeIds = deriveShapeIdsInCurrentPage(this.store, () =>\n\t\t\tthis.getCurrentPageId()\n\t\t)\n\t\tthis._parentIdsToChildIds = parentsToChildren(this.store)\n\n\t\tthis.disposables.add(\n\t\t\tthis.store.listen((changes) => {\n\t\t\t\tthis.emit('change', changes)\n\t\t\t})\n\t\t)\n\t\tthis.disposables.add(this.history.dispose)\n\n\t\tthis.run(\n\t\t\t() => {\n\t\t\t\tthis.store.ensureStoreIsUsable()\n\n\t\t\t\t// clear ephemeral state\n\t\t\t\tthis._updateCurrentPageState({\n\t\t\t\t\teditingShapeId: null,\n\t\t\t\t\thoveredShapeId: null,\n\t\t\t\t\terasingShapeIds: [],\n\t\t\t\t})\n\t\t\t},\n\t\t\t{ history: 'ignore' }\n\t\t)\n\n\t\tif (initialState && this.root.children[initialState] === undefined) {\n\t\t\tthrow Error(`No state found for initialState \"${initialState}\".`)\n\t\t}\n\n\t\tthis.root.enter(undefined, 'initial')\n\n\t\tthis.edgeScrollManager = new EdgeScrollManager(this)\n\t\tthis.focusManager = new FocusManager(this, autoFocus)\n\t\tthis.disposables.add(this.focusManager.dispose.bind(this.focusManager))\n\n\t\tif (this.getInstanceState().followingUserId) {\n\t\t\tthis.stopFollowingUser()\n\t\t}\n\n\t\tthis.on('tick', this._flushEventsForTick)\n\n\t\tthis.timers.requestAnimationFrame(() => {\n\t\t\tthis._tickManager.start()\n\t\t})\n\n\t\tthis.performanceTracker = new PerformanceTracker()\n\t}\n\n\tprivate readonly _isShapeHiddenPredicate?: (shape: TLShape, editor: Editor) => boolean\n\t@computed\n\tprivate getIsShapeHiddenCache() {\n\t\tif (!this._isShapeHiddenPredicate) return null\n\t\treturn this.store.createComputedCache('isShapeHidden', (shape: TLShape) => {\n\t\t\tconst hiddenParent = this.findShapeAncestor(shape, (p) => this.isShapeHidden(p))\n\t\t\tif (hiddenParent) return true\n\t\t\treturn this._isShapeHiddenPredicate!(shape, this) ?? false\n\t\t})\n\t}\n\tisShapeHidden(shapeOrId: TLShape | TLShapeId): boolean {\n\t\tif (!this._isShapeHiddenPredicate) return false\n\t\treturn !!this.getIsShapeHiddenCache!()!.get(\n\t\t\ttypeof shapeOrId === 'string' ? shapeOrId : shapeOrId.id\n\t\t)\n\t}\n\n\treadonly options: TldrawOptions\n\n\t/**\n\t * The editor's store\n\t *\n\t * @public\n\t */\n\treadonly store: TLStore\n\n\t/**\n\t * The root state of the statechart.\n\t *\n\t * @public\n\t */\n\treadonly root: StateNode\n\n\t/**\n\t * A set of functions to call when the app is disposed.\n\t *\n\t * @public\n\t */\n\treadonly disposables = new Set<() => void>()\n\n\t/**\n\t * Whether the editor is disposed.\n\t *\n\t * @public\n\t */\n\tisDisposed = false\n\n\t/** @internal */\n\tprivate readonly _tickManager\n\n\t/**\n\t * A manager for the app's snapping feature.\n\t *\n\t * @public\n\t */\n\treadonly snaps: SnapManager\n\n\t/**\n\t * A manager for the any asynchronous events and making sure they're\n\t * cleaned up upon disposal.\n\t *\n\t * @public\n\t */\n\treadonly timers: Timers\n\n\t/**\n\t * A manager for the user and their preferences.\n\t *\n\t * @public\n\t */\n\treadonly user: UserPreferencesManager\n\n\t/**\n\t * A helper for measuring text.\n\t *\n\t * @public\n\t */\n\treadonly textMeasure: TextManager\n\n\t/**\n\t * A manager for the editor's environment.\n\t *\n\t * @public\n\t */\n\treadonly environment: EnvironmentManager\n\n\t/**\n\t * A manager for the editor's scribbles.\n\t *\n\t * @public\n\t */\n\treadonly scribbles: ScribbleManager\n\n\t/**\n\t * A manager for side effects and correct state enforcement. See {@link @tldraw/store#StoreSideEffects} for details.\n\t *\n\t * @public\n\t */\n\treadonly sideEffects: StoreSideEffects\n\n\t/**\n\t * A manager for moving the camera when the mouse is at the edge of the screen.\n\t *\n\t * @public\n\t */\n\tedgeScrollManager: EdgeScrollManager\n\n\t/**\n\t * A manager for ensuring correct focus. See FocusManager for details.\n\t *\n\t * @internal\n\t */\n\tprivate focusManager: FocusManager\n\n\t/**\n\t * The current HTML element containing the editor.\n\t *\n\t * @example\n\t * ```ts\n\t * const container = editor.getContainer()\n\t * ```\n\t *\n\t * @public\n\t */\n\tgetContainer: () => HTMLElement\n\n\t/**\n\t * Dispose the editor.\n\t *\n\t * @public\n\t */\n\tdispose() {\n\t\tthis.disposables.forEach((dispose) => dispose())\n\t\tthis.disposables.clear()\n\t\tthis.isDisposed = true\n\t}\n\n\t/* ------------------- Shape Utils ------------------ */\n\n\t/**\n\t * A map of shape utility classes (TLShapeUtils) by shape type.\n\t *\n\t * @public\n\t */\n\tshapeUtils: { readonly [K in string]?: ShapeUtil }\n\n\tstyleProps: { [key: string]: Map, string> }\n\n\t/**\n\t * Get a shape util from a shape itself.\n\t *\n\t * @example\n\t * ```ts\n\t * const util = editor.getShapeUtil(myArrowShape)\n\t * const util = editor.getShapeUtil('arrow')\n\t * const util = editor.getShapeUtil(myArrowShape)\n\t * const util = editor.getShapeUtil(TLArrowShape)('arrow')\n\t * ```\n\t *\n\t * @param shape - A shape, shape partial, or shape type.\n\t *\n\t * @public\n\t */\n\tgetShapeUtil(shape: S | TLShapePartial): ShapeUtil\n\tgetShapeUtil(type: S['type']): ShapeUtil\n\tgetShapeUtil(type: T extends ShapeUtil ? R['type'] : string): T\n\tgetShapeUtil(arg: string | { type: string }) {\n\t\tconst type = typeof arg === 'string' ? arg : arg.type\n\t\tconst shapeUtil = getOwnProperty(this.shapeUtils, type)\n\t\tassert(shapeUtil, `No shape util found for type \"${type}\"`)\n\t\treturn shapeUtil\n\t}\n\n\t/* ------------------- Binding Utils ------------------ */\n\t/**\n\t * A map of shape utility classes (TLShapeUtils) by shape type.\n\t *\n\t * @public\n\t */\n\tbindingUtils: { readonly [K in string]?: BindingUtil }\n\n\t/**\n\t * Get a binding util from a binding itself.\n\t *\n\t * @example\n\t * ```ts\n\t * const util = editor.getBindingUtil(myArrowBinding)\n\t * const util = editor.getBindingUtil('arrow')\n\t * const util = editor.getBindingUtil(myArrowBinding)\n\t * const util = editor.getBindingUtil(TLArrowBinding)('arrow')\n\t * ```\n\t *\n\t * @param binding - A binding, binding partial, or binding type.\n\t *\n\t * @public\n\t */\n\tgetBindingUtil(binding: S | { type: S['type'] }): BindingUtil\n\tgetBindingUtil(type: S['type']): BindingUtil\n\tgetBindingUtil(\n\t\ttype: T extends BindingUtil ? R['type'] : string\n\t): T\n\tgetBindingUtil(arg: string | { type: string }) {\n\t\tconst type = typeof arg === 'string' ? arg : arg.type\n\t\tconst bindingUtil = getOwnProperty(this.bindingUtils, type)\n\t\tassert(bindingUtil, `No binding util found for type \"${type}\"`)\n\t\treturn bindingUtil\n\t}\n\n\t/* --------------------- History -------------------- */\n\n\t/**\n\t * A manager for the app's history.\n\t *\n\t * @readonly\n\t */\n\tprotected readonly history: HistoryManager\n\n\t/**\n\t * Undo to the last mark.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.undo()\n\t * ```\n\t *\n\t * @public\n\t */\n\tundo(): this {\n\t\tthis._flushEventsForTick(0)\n\t\tthis.complete()\n\t\tthis.history.undo()\n\t\treturn this\n\t}\n\n\t/**\n\t * Whether the app can undo.\n\t *\n\t * @public\n\t */\n\t@computed getCanUndo(): boolean {\n\t\treturn this.history.getNumUndos() > 0\n\t}\n\n\t/**\n\t * Redo to the next mark.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.redo()\n\t * ```\n\t *\n\t * @public\n\t */\n\tredo(): this {\n\t\tthis._flushEventsForTick(0)\n\t\tthis.complete()\n\t\tthis.history.redo()\n\t\treturn this\n\t}\n\n\tclearHistory() {\n\t\tthis.history.clear()\n\t\treturn this\n\t}\n\n\t/**\n\t * Whether the app can redo.\n\t *\n\t * @public\n\t */\n\t@computed getCanRedo(): boolean {\n\t\treturn this.history.getNumRedos() > 0\n\t}\n\n\t/**\n\t * Create a new \"mark\", or stopping point, in the undo redo history. Creating a mark will clear\n\t * any redos.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.mark()\n\t * editor.mark('flip shapes')\n\t * ```\n\t *\n\t * @param markId - The mark's id, usually the reason for adding the mark.\n\t *\n\t * @public\n\t * @deprecated use {@link Editor.markHistoryStoppingPoint} instead\n\t */\n\tmark(markId?: string): this {\n\t\tif (typeof markId === 'string') {\n\t\t\tconsole.warn(\n\t\t\t\t`[tldraw] \\`editor.history.mark(\"${markId}\")\\` is deprecated. Please use \\`const myMarkId = editor.markHistoryStoppingPoint()\\` instead.`\n\t\t\t)\n\t\t} else {\n\t\t\tconsole.warn(\n\t\t\t\t'[tldraw] `editor.mark()` is deprecated. Use `editor.markHistoryStoppingPoint()` instead.'\n\t\t\t)\n\t\t}\n\t\tthis.history._mark(markId ?? uniqueId())\n\t\treturn this\n\t}\n\n\t/**\n\t * Create a new \"mark\", or stopping point, in the undo redo history. Creating a mark will clear\n\t * any redos. You typically want to do this just before a user interaction begins or is handled.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.markHistoryStoppingPoint()\n\t * editor.flipShapes(editor.getSelectedShapes())\n\t * ```\n\t * @example\n\t * ```ts\n\t * const beginRotateMark = editor.markHistoryStoppingPoint()\n\t * // if the use cancels the rotation, you can bail back to this mark\n\t * editor.bailToMark(beginRotateMark)\n\t * ```\n\t *\n\t * @public\n\t * @param name - The name of the mark, useful for debugging the undo/redo stacks\n\t * @returns a unique id for the mark that can be used with `squashToMark` or `bailToMark`.\n\t */\n\tmarkHistoryStoppingPoint(name?: string): string {\n\t\tconst id = `[${name ?? 'stop'}]_${uniqueId()}`\n\t\tthis.history._mark(id)\n\t\treturn id\n\t}\n\n\t/**\n\t * @internal this is only used to implement some backwards-compatibility logic. Should be fine to delete after 6 months or whatever.\n\t */\n\tgetMarkIdMatching(idSubstring: string) {\n\t\treturn this.history.getMarkIdMatching(idSubstring)\n\t}\n\n\t/**\n\t * Coalesces all changes since the given mark into a single change, removing any intermediate marks.\n\t *\n\t * This is useful if you need to 'compress' the recent history to simplify the undo/redo experience of a complex interaction.\n\t *\n\t * @example\n\t * ```ts\n\t * const bumpShapesMark = editor.markHistoryStoppingPoint()\n\t * // ... some changes\n\t * editor.squashToMark(bumpShapesMark)\n\t * ```\n\t *\n\t * @param markId - The mark id to squash to.\n\t */\n\tsquashToMark(markId: string): this {\n\t\tthis.history.squashToMark(markId)\n\t\treturn this\n\t}\n\n\t/**\n\t * Undo to the closest mark, discarding the changes so they cannot be redone.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.bail()\n\t * ```\n\t *\n\t * @public\n\t */\n\tbail() {\n\t\tthis.history.bail()\n\t\treturn this\n\t}\n\n\t/**\n\t * Undo to the given mark, discarding the changes so they cannot be redone.\n\t *\n\t * @example\n\t * ```ts\n\t * const beginDrag = editor.markHistoryStoppingPoint()\n\t * // ... some changes\n\t * editor.bailToMark(beginDrag)\n\t * ```\n\t *\n\t * @public\n\t */\n\tbailToMark(id: string): this {\n\t\tthis.history.bailToMark(id)\n\t\treturn this\n\t}\n\n\tprivate _shouldIgnoreShapeLock = false\n\n\t/**\n\t * Run a function in a transaction with optional options for context.\n\t * You can use the options to change the way that history is treated\n\t * or allow changes to locked shapes.\n\t *\n\t * @example\n\t * ```ts\n\t * // updating with\n\t * editor.run(() => {\n\t * \teditor.updateShape({ ...myShape, x: 100 })\n\t * }, { history: \"ignore\" })\n\t *\n\t * // forcing changes / deletions for locked shapes\n\t * editor.toggleLock([myShape])\n\t * editor.run(() => {\n\t * \teditor.updateShape({ ...myShape, x: 100 })\n\t * \teditor.deleteShape(myShape)\n\t * }, { ignoreShapeLock: true }, )\n\t * ```\n\t *\n\t * @param fn - The callback function to run.\n\t * @param opts - The options for the batch.\n\t *\n\t *\n\t * @public\n\t */\n\trun(fn: () => void, opts?: TLEditorRunOptions): this {\n\t\tconst previousIgnoreShapeLock = this._shouldIgnoreShapeLock\n\t\tthis._shouldIgnoreShapeLock = opts?.ignoreShapeLock ?? previousIgnoreShapeLock\n\n\t\ttry {\n\t\t\tthis.history.batch(fn, opts)\n\t\t} finally {\n\t\t\tthis._shouldIgnoreShapeLock = previousIgnoreShapeLock\n\t\t}\n\n\t\treturn this\n\t}\n\n\t/**\n\t * @deprecated Use `Editor.run` instead.\n\t */\n\tbatch(fn: () => void, opts?: TLEditorRunOptions): this {\n\t\treturn this.run(fn, opts)\n\t}\n\n\t/* --------------------- Errors --------------------- */\n\n\t/** @internal */\n\tannotateError(\n\t\terror: unknown,\n\t\t{\n\t\t\torigin,\n\t\t\twillCrashApp,\n\t\t\ttags,\n\t\t\textras,\n\t\t}: {\n\t\t\torigin: string\n\t\t\twillCrashApp: boolean\n\t\t\ttags?: Record\n\t\t\textras?: Record\n\t\t}\n\t): this {\n\t\tconst defaultAnnotations = this.createErrorAnnotations(origin, willCrashApp)\n\t\tannotateError(error, {\n\t\t\ttags: { ...defaultAnnotations.tags, ...tags },\n\t\t\textras: { ...defaultAnnotations.extras, ...extras },\n\t\t})\n\t\tif (willCrashApp) {\n\t\t\tthis.store.markAsPossiblyCorrupted()\n\t\t}\n\t\treturn this\n\t}\n\n\t/** @internal */\n\tcreateErrorAnnotations(\n\t\torigin: string,\n\t\twillCrashApp: boolean | 'unknown'\n\t): {\n\t\ttags: { origin: string; willCrashApp: boolean | 'unknown' }\n\t\textras: {\n\t\t\tactiveStateNode?: string\n\t\t\tselectedShapes?: TLUnknownShape[]\n\t\t\teditingShape?: TLUnknownShape\n\t\t\tinputs?: Record\n\t\t}\n\t} {\n\t\ttry {\n\t\t\tconst editingShapeId = this.getEditingShapeId()\n\t\t\treturn {\n\t\t\t\ttags: {\n\t\t\t\t\torigin: origin,\n\t\t\t\t\twillCrashApp,\n\t\t\t\t},\n\t\t\t\textras: {\n\t\t\t\t\tactiveStateNode: this.root.getPath(),\n\t\t\t\t\tselectedShapes: this.getSelectedShapes(),\n\t\t\t\t\teditingShape: editingShapeId ? this.getShape(editingShapeId) : undefined,\n\t\t\t\t\tinputs: this.inputs,\n\t\t\t\t},\n\t\t\t}\n\t\t} catch {\n\t\t\treturn {\n\t\t\t\ttags: {\n\t\t\t\t\torigin: origin,\n\t\t\t\t\twillCrashApp,\n\t\t\t\t},\n\t\t\t\textras: {},\n\t\t\t}\n\t\t}\n\t}\n\n\t/** @internal */\n\tprivate _crashingError: unknown | null = null\n\n\t/**\n\t * We can't use an `atom` here because there's a chance that when `crashAndReportError` is called,\n\t * we're in a transaction that's about to be rolled back due to the same error we're currently\n\t * reporting.\n\t *\n\t * Instead, to listen to changes to this value, you need to listen to app's `crash` event.\n\t *\n\t * @internal\n\t */\n\tgetCrashingError() {\n\t\treturn this._crashingError\n\t}\n\n\t/** @internal */\n\tcrash(error: unknown): this {\n\t\tthis._crashingError = error\n\t\tthis.store.markAsPossiblyCorrupted()\n\t\tthis.emit('crash', { error })\n\t\treturn this\n\t}\n\n\t/* ------------------- Statechart ------------------- */\n\n\t/**\n\t * The editor's current path of active states.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getPath() // \"select.idle\"\n\t * ```\n\t *\n\t * @public\n\t */\n\t@computed getPath() {\n\t\treturn this.root.getPath().split('root.')[1]\n\t}\n\n\t/**\n\t * Get whether a certain tool (or other state node) is currently active.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.isIn('select')\n\t * editor.isIn('select.brushing')\n\t * ```\n\t *\n\t * @param path - The path of active states, separated by periods.\n\t *\n\t * @public\n\t */\n\tisIn(path: string): boolean {\n\t\tconst ids = path.split('.').reverse()\n\t\tlet state = this.root as StateNode\n\t\twhile (ids.length > 0) {\n\t\t\tconst id = ids.pop()\n\t\t\tif (!id) return true\n\t\t\tconst current = state.getCurrent()\n\t\t\tif (current?.id === id) {\n\t\t\t\tif (ids.length === 0) return true\n\t\t\t\tstate = current\n\t\t\t\tcontinue\n\t\t\t} else return false\n\t\t}\n\t\treturn false\n\t}\n\n\t/**\n\t * Get whether the state node is in any of the given active paths.\n\t *\n\t * @example\n\t * ```ts\n\t * state.isInAny('select', 'erase')\n\t * state.isInAny('select.brushing', 'erase.idle')\n\t * ```\n\t *\n\t * @public\n\t */\n\tisInAny(...paths: string[]): boolean {\n\t\treturn paths.some((path) => this.isIn(path))\n\t}\n\n\t/**\n\t * Set the selected tool.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.setCurrentTool('hand')\n\t * editor.setCurrentTool('hand', { date: Date.now() })\n\t * ```\n\t *\n\t * @param id - The id of the tool to select.\n\t * @param info - Arbitrary data to pass along into the transition.\n\t *\n\t * @public\n\t */\n\tsetCurrentTool(id: string, info = {}): this {\n\t\tthis.root.transition(id, info)\n\t\treturn this\n\t}\n\n\t/**\n\t * The current selected tool.\n\t *\n\t * @public\n\t */\n\t@computed getCurrentTool(): StateNode {\n\t\treturn this.root.getCurrent()!\n\t}\n\n\t/**\n\t * The id of the current selected tool.\n\t *\n\t * @public\n\t */\n\t@computed getCurrentToolId(): string {\n\t\tconst currentTool = this.getCurrentTool()\n\t\tif (!currentTool) return ''\n\t\treturn currentTool.getCurrentToolIdMask() ?? currentTool.id\n\t}\n\n\t/**\n\t * Get a descendant by its path.\n\t *\n\t * @example\n\t * ```ts\n\t * state.getStateDescendant('select')\n\t * state.getStateDescendant('select.brushing')\n\t * ```\n\t *\n\t * @param path - The descendant's path of state ids, separated by periods.\n\t *\n\t * @public\n\t */\n\tgetStateDescendant(path: string): T | undefined {\n\t\tconst ids = path.split('.').reverse()\n\t\tlet state = this.root as StateNode\n\t\twhile (ids.length > 0) {\n\t\t\tconst id = ids.pop()\n\t\t\tif (!id) return state as T\n\t\t\tconst childState = state.children?.[id]\n\t\t\tif (!childState) return undefined\n\t\t\tstate = childState\n\t\t}\n\t\treturn state as T\n\t}\n\n\t/* ---------------- Document Settings --------------- */\n\n\t/**\n\t * The global document settings that apply to all users.\n\t *\n\t * @public\n\t **/\n\t@computed getDocumentSettings() {\n\t\treturn this.store.get(TLDOCUMENT_ID)!\n\t}\n\n\t/**\n\t * Update the global document settings that apply to all users.\n\t *\n\t * @public\n\t **/\n\tupdateDocumentSettings(settings: Partial): this {\n\t\tthis.run(\n\t\t\t() => {\n\t\t\t\tthis.store.put([{ ...this.getDocumentSettings(), ...settings }])\n\t\t\t},\n\t\t\t{ history: 'ignore' }\n\t\t)\n\t\treturn this\n\t}\n\n\t/* ----------------- Instance State ----------------- */\n\n\t/**\n\t * The current instance's state.\n\t *\n\t * @public\n\t */\n\t@computed getInstanceState(): TLInstance {\n\t\treturn this.store.get(TLINSTANCE_ID)!\n\t}\n\n\t/**\n\t * Update the instance's state.\n\t *\n\t * @param partial - A partial object to update the instance state with.\n\t *\n\t * @public\n\t */\n\tupdateInstanceState(\n\t\tpartial: Partial>,\n\t\thistoryOptions?: TLHistoryBatchOptions\n\t): this {\n\t\tthis._updateInstanceState(partial, { history: 'ignore', ...historyOptions })\n\n\t\tif (partial.isChangingStyle !== undefined) {\n\t\t\tclearTimeout(this._isChangingStyleTimeout)\n\t\t\tif (partial.isChangingStyle === true) {\n\t\t\t\t// If we've set to true, set a new reset timeout to change the value back to false after 2 seconds\n\t\t\t\tthis._isChangingStyleTimeout = this.timers.setTimeout(() => {\n\t\t\t\t\tthis._updateInstanceState({ isChangingStyle: false }, { history: 'ignore' })\n\t\t\t\t}, 2000)\n\t\t\t}\n\t\t}\n\n\t\treturn this\n\t}\n\n\t/** @internal */\n\t_updateInstanceState(\n\t\tpartial: Partial>,\n\t\topts?: TLHistoryBatchOptions\n\t) {\n\t\tthis.run(() => {\n\t\t\tthis.store.put([\n\t\t\t\t{\n\t\t\t\t\t...this.getInstanceState(),\n\t\t\t\t\t...partial,\n\t\t\t\t},\n\t\t\t])\n\t\t}, opts)\n\t}\n\n\t/** @internal */\n\tprivate _isChangingStyleTimeout = -1 as any\n\n\t// Menus\n\n\t/**\n\t * A set of strings representing any open menus. When menus are open,\n\t * certain interactions will behave differently; for example, when a\n\t * draw tool is selected and a menu is open, a pointer-down will not\n\t * create a dot (because the user is probably trying to close the menu)\n\t * however a pointer-down event followed by a drag will begin drawing\n\t * a line (because the user is BOTH trying to close the menu AND start\n\t * drawing a line).\n\t *\n\t * @public\n\t */\n\t@computed getOpenMenus(): string[] {\n\t\treturn this.getInstanceState().openMenus\n\t}\n\n\t/**\n\t * Add an open menu.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.addOpenMenu('menu-id')\n\t * ```\n\t *\n\t * @public\n\t */\n\taddOpenMenu(id: string): this {\n\t\tconst menus = new Set(this.getOpenMenus())\n\t\tif (!menus.has(id)) {\n\t\t\tmenus.add(id)\n\t\t\tthis.updateInstanceState({ openMenus: [...menus] })\n\t\t}\n\t\treturn this\n\t}\n\n\t/**\n\t * Delete an open menu.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.deleteOpenMenu('menu-id')\n\t * ```\n\t *\n\t * @public\n\t */\n\tdeleteOpenMenu(id: string): this {\n\t\tconst menus = new Set(this.getOpenMenus())\n\t\tif (menus.has(id)) {\n\t\t\tmenus.delete(id)\n\t\t\tthis.updateInstanceState({ openMenus: [...menus] })\n\t\t}\n\t\treturn this\n\t}\n\n\t/**\n\t * Clear all open menus.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.clearOpenMenus()\n\t * ```\n\t *\n\t * @public\n\t */\n\tclearOpenMenus(): this {\n\t\tif (this.getOpenMenus().length) {\n\t\t\tthis.updateInstanceState({ openMenus: [] })\n\t\t}\n\t\treturn this\n\t}\n\n\t/**\n\t * Get whether any menus are open.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getIsMenuOpen()\n\t * ```\n\t *\n\t * @public\n\t */\n\t@computed getIsMenuOpen(): boolean {\n\t\treturn this.getOpenMenus().length > 0\n\t}\n\n\t/* --------------------- Cursor --------------------- */\n\n\t/**\n\t * Set the cursor.\n\t *\n\t * @param type - The cursor type.\n\t * @param rotation - The cursor rotation.\n\t *\n\t * @public\n\t */\n\tsetCursor(cursor: Partial) {\n\t\tthis.updateInstanceState({ cursor: { ...this.getInstanceState().cursor, ...cursor } })\n\t\treturn this\n\t}\n\n\t/* ------------------- Page State ------------------- */\n\n\t/**\n\t * Page states.\n\t *\n\t * @public\n\t */\n\t@computed getPageStates(): TLInstancePageState[] {\n\t\treturn this._getPageStatesQuery().get()\n\t}\n\n\t/** @internal */\n\t@computed private _getPageStatesQuery() {\n\t\treturn this.store.query.records('instance_page_state')\n\t}\n\n\t/**\n\t * The current page state.\n\t *\n\t * @public\n\t */\n\t@computed getCurrentPageState(): TLInstancePageState {\n\t\treturn this.store.get(this._getCurrentPageStateId())!\n\t}\n\n\t/** @internal */\n\t@computed private _getCurrentPageStateId() {\n\t\treturn InstancePageStateRecordType.createId(this.getCurrentPageId())\n\t}\n\n\t/**\n\t * Update this instance's page state.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.updateCurrentPageState({ id: 'page1', editingShapeId: 'shape:123' })\n\t * ```\n\t *\n\t * @param partial - The partial of the page state object containing the changes.\n\t *\n\t * @public\n\t */\n\tupdateCurrentPageState(\n\t\tpartial: Partial<\n\t\t\tOmit\n\t\t>\n\t): this {\n\t\tthis._updateCurrentPageState(partial)\n\t\treturn this\n\t}\n\t_updateCurrentPageState(partial: Partial>) {\n\t\tthis.store.update(partial.id ?? this.getCurrentPageState().id, (state) => ({\n\t\t\t...state,\n\t\t\t...partial,\n\t\t}))\n\t}\n\n\t/**\n\t * The current selected ids.\n\t *\n\t * @public\n\t */\n\t@computed getSelectedShapeIds() {\n\t\treturn this.getCurrentPageState().selectedShapeIds\n\t}\n\n\t/**\n\t * An array containing all of the currently selected shapes.\n\t *\n\t * @public\n\t * @readonly\n\t */\n\t@computed getSelectedShapes(): TLShape[] {\n\t\tconst { selectedShapeIds } = this.getCurrentPageState()\n\t\treturn compact(selectedShapeIds.map((id) => this.store.get(id)))\n\t}\n\n\t/**\n\t * Select one or more shapes.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.setSelectedShapes(['id1'])\n\t * editor.setSelectedShapes(['id1', 'id2'])\n\t * ```\n\t *\n\t * @param ids - The ids to select.\n\t *\n\t * @public\n\t */\n\tsetSelectedShapes(shapes: TLShapeId[] | TLShape[]): this {\n\t\treturn this.run(\n\t\t\t() => {\n\t\t\t\tconst ids = shapes.map((shape) => (typeof shape === 'string' ? shape : shape.id))\n\t\t\t\tconst { selectedShapeIds: prevSelectedShapeIds } = this.getCurrentPageState()\n\t\t\t\tconst prevSet = new Set(prevSelectedShapeIds)\n\n\t\t\t\tif (ids.length === prevSet.size && ids.every((id) => prevSet.has(id))) return null\n\n\t\t\t\tthis.store.put([{ ...this.getCurrentPageState(), selectedShapeIds: ids }])\n\t\t\t},\n\t\t\t{ history: 'record-preserveRedoStack' }\n\t\t)\n\t}\n\n\t/**\n\t * Determine whether or not any of a shape's ancestors are selected.\n\t *\n\t * @param id - The id of the shape to check.\n\t *\n\t * @public\n\t */\n\tisAncestorSelected(shape: TLShape | TLShapeId): boolean {\n\t\tconst id = typeof shape === 'string' ? shape : shape?.id ?? null\n\t\tconst _shape = this.getShape(id)\n\t\tif (!_shape) return false\n\t\tconst selectedShapeIds = this.getSelectedShapeIds()\n\t\treturn !!this.findShapeAncestor(_shape, (parent) => selectedShapeIds.includes(parent.id))\n\t}\n\n\t/**\n\t * Select one or more shapes.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.select('id1')\n\t * editor.select('id1', 'id2')\n\t * ```\n\t *\n\t * @param ids - The ids to select.\n\t *\n\t * @public\n\t */\n\tselect(...shapes: TLShapeId[] | TLShape[]): this {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((shape) => shape.id)\n\t\tthis.setSelectedShapes(ids)\n\t\treturn this\n\t}\n\n\t/**\n\t * Remove a shape from the existing set of selected shapes.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.deselect(shape.id)\n\t * ```\n\t *\n\t * @public\n\t */\n\tdeselect(...shapes: TLShapeId[] | TLShape[]): this {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((shape) => shape.id)\n\t\tconst selectedShapeIds = this.getSelectedShapeIds()\n\t\tif (selectedShapeIds.length > 0 && ids.length > 0) {\n\t\t\tthis.setSelectedShapes(selectedShapeIds.filter((id) => !ids.includes(id)))\n\t\t}\n\t\treturn this\n\t}\n\n\t/**\n\t * Select all direct children of the current page.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.selectAll()\n\t * ```\n\t *\n\t * @public\n\t */\n\tselectAll(): this {\n\t\tconst ids = this.getSortedChildIdsForParent(this.getCurrentPageId())\n\t\t// page might have no shapes\n\t\tif (ids.length <= 0) return this\n\t\tthis.setSelectedShapes(this._getUnlockedShapeIds(ids))\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Clear the selection.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.selectNone()\n\t * ```\n\t *\n\t * @public\n\t */\n\tselectNone(): this {\n\t\tif (this.getSelectedShapeIds().length > 0) {\n\t\t\tthis.setSelectedShapes([])\n\t\t}\n\n\t\treturn this\n\t}\n\n\t/**\n\t * The id of the app's only selected shape.\n\t *\n\t * @returns Null if there is no shape or more than one selected shape, otherwise the selected shape's id.\n\t *\n\t * @public\n\t * @readonly\n\t */\n\t@computed getOnlySelectedShapeId(): TLShapeId | null {\n\t\treturn this.getOnlySelectedShape()?.id ?? null\n\t}\n\n\t/**\n\t * The app's only selected shape.\n\t *\n\t * @returns Null if there is no shape or more than one selected shape, otherwise the selected shape.\n\t *\n\t * @public\n\t * @readonly\n\t */\n\t@computed getOnlySelectedShape(): TLShape | null {\n\t\tconst selectedShapes = this.getSelectedShapes()\n\t\treturn selectedShapes.length === 1 ? selectedShapes[0] : null\n\t}\n\n\t/**\n\t * @internal\n\t */\n\tgetShapesPageBounds(shapeIds: TLShapeId[]): Box | null {\n\t\tconst bounds = compact(shapeIds.map((id) => this.getShapePageBounds(id)))\n\t\tif (bounds.length === 0) return null\n\t\treturn Box.Common(bounds)\n\t}\n\n\t/**\n\t * The current page bounds of all the selected shapes. If the\n\t * selection is rotated, then these bounds are the axis-aligned\n\t * box that the rotated bounds would fit inside of.\n\t *\n\t * @readonly\n\t *\n\t * @public\n\t */\n\t@computed getSelectionPageBounds(): Box | null {\n\t\treturn this.getShapesPageBounds(this.getSelectedShapeIds())\n\t}\n\n\t/**\n\t * @internal\n\t */\n\tgetShapesSharedRotation(shapeIds: TLShapeId[]) {\n\t\tlet foundFirst = false // annoying but we can't use an i===0 check because we need to skip over undefineds\n\t\tlet rotation = 0\n\t\tfor (let i = 0, n = shapeIds.length; i < n; i++) {\n\t\t\tconst pageTransform = this.getShapePageTransform(shapeIds[i])\n\t\t\tif (!pageTransform) continue\n\t\t\tif (foundFirst) {\n\t\t\t\tif (pageTransform.rotation() !== rotation) {\n\t\t\t\t\t// There are at least 2 different rotations, so the common rotation is zero\n\t\t\t\t\treturn 0\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// First rotation found\n\t\t\t\tfoundFirst = true\n\t\t\t\trotation = pageTransform.rotation()\n\t\t\t}\n\t\t}\n\n\t\treturn rotation\n\t}\n\n\t/**\n\t * The rotation of the selection bounding box in the current page space.\n\t *\n\t * @readonly\n\t * @public\n\t */\n\t@computed getSelectionRotation(): number {\n\t\treturn this.getShapesSharedRotation(this.getSelectedShapeIds())\n\t}\n\n\t/**\n\t * @internal\n\t */\n\tgetShapesRotatedPageBounds(shapeIds: TLShapeId[]): Box | undefined {\n\t\tif (shapeIds.length === 0) {\n\t\t\treturn undefined\n\t\t}\n\n\t\tconst selectionRotation = this.getShapesSharedRotation(shapeIds)\n\t\tif (selectionRotation === 0) {\n\t\t\treturn this.getShapesPageBounds(shapeIds) ?? undefined\n\t\t}\n\n\t\tif (shapeIds.length === 1) {\n\t\t\tconst bounds = this.getShapeGeometry(shapeIds[0]).bounds.clone()\n\t\t\tconst pageTransform = this.getShapePageTransform(shapeIds[0])!\n\t\t\tbounds.point = pageTransform.applyToPoint(bounds.point)\n\t\t\treturn bounds\n\t\t}\n\n\t\t// need to 'un-rotate' all the outlines of the existing nodes so we can fit them inside a box\n\t\tconst boxFromRotatedVertices = Box.FromPoints(\n\t\t\tshapeIds\n\t\t\t\t.flatMap((id) => {\n\t\t\t\t\tconst pageTransform = this.getShapePageTransform(id)\n\t\t\t\t\tif (!pageTransform) return []\n\t\t\t\t\treturn pageTransform.applyToPoints(this.getShapeGeometry(id).bounds.corners)\n\t\t\t\t})\n\t\t\t\t.map((p) => p.rot(-selectionRotation))\n\t\t)\n\t\t// now position box so that it's top-left corner is in the right place\n\t\tboxFromRotatedVertices.point = boxFromRotatedVertices.point.rot(selectionRotation)\n\t\treturn boxFromRotatedVertices\n\t}\n\n\t/**\n\t * The bounds of the selection bounding box in the current page space.\n\t *\n\t * @readonly\n\t * @public\n\t */\n\t@computed getSelectionRotatedPageBounds(): Box | undefined {\n\t\treturn this.getShapesRotatedPageBounds(this.getSelectedShapeIds())\n\t}\n\n\t/**\n\t * The bounds of the selection bounding box in the current page space.\n\t *\n\t * @readonly\n\t * @public\n\t */\n\t@computed getSelectionRotatedScreenBounds(): Box | undefined {\n\t\tconst bounds = this.getSelectionRotatedPageBounds()\n\t\tif (!bounds) return undefined\n\t\tconst { x, y } = this.pageToScreen(bounds.point)\n\t\tconst zoom = this.getZoomLevel()\n\t\treturn new Box(x, y, bounds.width * zoom, bounds.height * zoom)\n\t}\n\n\t// Focus Group\n\n\t/**\n\t * The current focused group id.\n\t *\n\t * @public\n\t */\n\t@computed getFocusedGroupId(): TLShapeId | TLPageId {\n\t\treturn this.getCurrentPageState().focusedGroupId ?? this.getCurrentPageId()\n\t}\n\n\t/**\n\t * The current focused group.\n\t *\n\t * @public\n\t */\n\t@computed getFocusedGroup(): TLShape | undefined {\n\t\tconst focusedGroupId = this.getFocusedGroupId()\n\t\treturn focusedGroupId ? this.getShape(focusedGroupId) : undefined\n\t}\n\n\t/**\n\t * Set the current focused group shape.\n\t *\n\t * @param shape - The group shape id (or group shape's id) to set as the focused group shape.\n\t *\n\t * @public\n\t */\n\tsetFocusedGroup(shape: TLShapeId | TLGroupShape | null): this {\n\t\tconst id = typeof shape === 'string' ? shape : shape?.id ?? null\n\n\t\tif (id !== null) {\n\t\t\tconst shape = this.getShape(id)\n\t\t\tif (!shape) {\n\t\t\t\tthrow Error(`Editor.setFocusedGroup: Shape with id ${id} does not exist`)\n\t\t\t}\n\n\t\t\tif (!this.isShapeOfType(shape, 'group')) {\n\t\t\t\tthrow Error(\n\t\t\t\t\t`Editor.setFocusedGroup: Cannot set focused group to shape of type ${shape.type}`\n\t\t\t\t)\n\t\t\t}\n\t\t}\n\n\t\tif (id === this.getFocusedGroupId()) return this\n\n\t\treturn this.run(\n\t\t\t() => {\n\t\t\t\tthis.store.update(this.getCurrentPageState().id, (s) => ({ ...s, focusedGroupId: id }))\n\t\t\t},\n\t\t\t{ history: 'record-preserveRedoStack' }\n\t\t)\n\t}\n\n\t/**\n\t * Exit the current focused group, moving up to the next parent group if there is one.\n\t *\n\t * @public\n\t */\n\tpopFocusedGroupId(): this {\n\t\tconst focusedGroup = this.getFocusedGroup()\n\n\t\tif (focusedGroup) {\n\t\t\t// If we have a focused layer, look for an ancestor of the focused shape that is a group\n\t\t\tconst match = this.findShapeAncestor(focusedGroup, (shape) =>\n\t\t\t\tthis.isShapeOfType(shape, 'group')\n\t\t\t)\n\t\t\t// If we have an ancestor that can become a focused layer, set it as the focused layer\n\t\t\tthis.setFocusedGroup(match?.id ?? null)\n\t\t\tthis.select(focusedGroup.id)\n\t\t} else {\n\t\t\t// If there's no parent focused group, then clear the focus layer and clear selection\n\t\t\tthis.setFocusedGroup(null)\n\t\t\tthis.selectNone()\n\t\t}\n\n\t\treturn this\n\t}\n\n\t/**\n\t * The current editing shape's id.\n\t *\n\t * @public\n\t */\n\t@computed getEditingShapeId(): TLShapeId | null {\n\t\treturn this.getCurrentPageState().editingShapeId\n\t}\n\n\t/**\n\t * The current editing shape.\n\t *\n\t * @public\n\t */\n\t@computed getEditingShape(): TLShape | undefined {\n\t\tconst editingShapeId = this.getEditingShapeId()\n\t\treturn editingShapeId ? this.getShape(editingShapeId) : undefined\n\t}\n\n\t/**\n\t * Set the current editing shape.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.setEditingShape(myShape)\n\t * editor.setEditingShape(myShape.id)\n\t * ```\n\t *\n\t * @param shape - The shape (or shape id) to set as editing.\n\t *\n\t * @public\n\t */\n\tsetEditingShape(shape: TLShapeId | TLShape | null): this {\n\t\tconst id = typeof shape === 'string' ? shape : shape?.id ?? null\n\t\tif (id !== this.getEditingShapeId()) {\n\t\t\tif (id) {\n\t\t\t\tconst shape = this.getShape(id)\n\t\t\t\tif (shape && this.getShapeUtil(shape).canEdit(shape)) {\n\t\t\t\t\tthis.run(\n\t\t\t\t\t\t() => {\n\t\t\t\t\t\t\tthis._updateCurrentPageState({ editingShapeId: id })\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{ history: 'ignore' }\n\t\t\t\t\t)\n\t\t\t\t\treturn this\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Either we just set the editing id to null, or the shape was missing or not editable\n\t\t\tthis.run(\n\t\t\t\t() => {\n\t\t\t\t\tthis._updateCurrentPageState({ editingShapeId: null })\n\t\t\t\t},\n\t\t\t\t{ history: 'ignore' }\n\t\t\t)\n\t\t}\n\t\treturn this\n\t}\n\n\t// Hovered\n\n\t/**\n\t * The current hovered shape id.\n\t *\n\t * @readonly\n\t * @public\n\t */\n\t@computed getHoveredShapeId(): TLShapeId | null {\n\t\treturn this.getCurrentPageState().hoveredShapeId\n\t}\n\n\t/**\n\t * The current hovered shape.\n\t *\n\t * @public\n\t */\n\t@computed getHoveredShape(): TLShape | undefined {\n\t\tconst hoveredShapeId = this.getHoveredShapeId()\n\t\treturn hoveredShapeId ? this.getShape(hoveredShapeId) : undefined\n\t}\n\t/**\n\t * Set the editor's current hovered shape.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.setHoveredShape(myShape)\n\t * editor.setHoveredShape(myShape.id)\n\t * ```\n\t *\n\t * @param shapes - The shape (or shape id) to set as hovered.\n\t *\n\t * @public\n\t */\n\tsetHoveredShape(shape: TLShapeId | TLShape | null): this {\n\t\tconst id = typeof shape === 'string' ? shape : shape?.id ?? null\n\t\tif (id === this.getHoveredShapeId()) return this\n\t\tthis.run(\n\t\t\t() => {\n\t\t\t\tthis.updateCurrentPageState({ hoveredShapeId: id })\n\t\t\t},\n\t\t\t{ history: 'ignore' }\n\t\t)\n\t\treturn this\n\t}\n\n\t// Hinting\n\n\t/**\n\t * The editor's current hinting shape ids.\n\t *\n\t * @public\n\t */\n\t@computed getHintingShapeIds() {\n\t\treturn this.getCurrentPageState().hintingShapeIds\n\t}\n\t/**\n\t * The editor's current hinting shapes.\n\t *\n\t * @public\n\t */\n\t@computed getHintingShape() {\n\t\tconst hintingShapeIds = this.getHintingShapeIds()\n\t\treturn compact(hintingShapeIds.map((id) => this.getShape(id)))\n\t}\n\n\t/**\n\t * Set the editor's current hinting shapes.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.setHintingShapes([myShape])\n\t * editor.setHintingShapes([myShape.id])\n\t * ```\n\t *\n\t * @param shapes - The shapes (or shape ids) to set as hinting.\n\t *\n\t * @public\n\t */\n\tsetHintingShapes(shapes: TLShapeId[] | TLShape[]): this {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((shape) => shape.id)\n\t\t// always ephemeral\n\t\tthis.run(\n\t\t\t() => {\n\t\t\t\tthis._updateCurrentPageState({ hintingShapeIds: dedupe(ids) })\n\t\t\t},\n\t\t\t{ history: 'ignore' }\n\t\t)\n\t\treturn this\n\t}\n\n\t// Erasing\n\n\t/**\n\t * The editor's current erasing ids.\n\t *\n\t * @public\n\t */\n\t@computed getErasingShapeIds() {\n\t\treturn this.getCurrentPageState().erasingShapeIds\n\t}\n\n\t/**\n\t * The editor's current erasing shapes.\n\t *\n\t * @public\n\t */\n\t@computed getErasingShapes() {\n\t\tconst erasingShapeIds = this.getErasingShapeIds()\n\t\treturn compact(erasingShapeIds.map((id) => this.getShape(id)))\n\t}\n\n\t/**\n\t * Set the editor's current erasing shapes.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.setErasingShapes([myShape])\n\t * editor.setErasingShapes([myShape.id])\n\t * ```\n\t *\n\t * @param shapes - The shapes (or shape ids) to set as hinting.\n\t *\n\t * @public\n\t */\n\tsetErasingShapes(shapes: TLShapeId[] | TLShape[]): this {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((shape) => shape.id)\n\t\tids.sort() // sort the incoming ids\n\t\tconst erasingShapeIds = this.getErasingShapeIds()\n\t\tthis.run(\n\t\t\t() => {\n\t\t\t\tif (ids.length === erasingShapeIds.length) {\n\t\t\t\t\t// if the new ids are the same length as the current ids, they might be the same.\n\t\t\t\t\t// presuming the current ids are also sorted, check each item to see if it's the same;\n\t\t\t\t\t// if we find any unequal, then we know the new ids are different.\n\t\t\t\t\tfor (let i = 0; i < ids.length; i++) {\n\t\t\t\t\t\tif (ids[i] !== erasingShapeIds[i]) {\n\t\t\t\t\t\t\tthis._updateCurrentPageState({ erasingShapeIds: ids })\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t// if the ids are a different length, then we know they're different.\n\t\t\t\t\tthis._updateCurrentPageState({ erasingShapeIds: ids })\n\t\t\t\t}\n\t\t\t},\n\t\t\t{ history: 'ignore' }\n\t\t)\n\n\t\treturn this\n\t}\n\n\t// Cropping\n\n\t/**\n\t * The current cropping shape's id.\n\t *\n\t * @public\n\t */\n\tgetCroppingShapeId() {\n\t\treturn this.getCurrentPageState().croppingShapeId\n\t}\n\n\t/**\n\t * Set the current cropping shape.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.setCroppingShape(myShape)\n\t * editor.setCroppingShape(myShape.id)\n\t * ```\n\t *\n\t *\n\t * @param shape - The shape (or shape id) to set as cropping.\n\t *\n\t * @public\n\t */\n\tsetCroppingShape(shape: TLShapeId | TLShape | null): this {\n\t\tconst id = typeof shape === 'string' ? shape : shape?.id ?? null\n\t\tif (id !== this.getCroppingShapeId()) {\n\t\t\tthis.run(\n\t\t\t\t() => {\n\t\t\t\t\tif (!id) {\n\t\t\t\t\t\tthis.updateCurrentPageState({ croppingShapeId: null })\n\t\t\t\t\t} else {\n\t\t\t\t\t\tconst shape = this.getShape(id)!\n\t\t\t\t\t\tconst util = this.getShapeUtil(shape)\n\t\t\t\t\t\tif (shape && util.canCrop(shape)) {\n\t\t\t\t\t\t\tthis.updateCurrentPageState({ croppingShapeId: id })\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\t{ history: 'ignore' }\n\t\t\t)\n\t\t}\n\t\treturn this\n\t}\n\n\t/* --------------------- Camera --------------------- */\n\n\t/** @internal */\n\t@computed\n\tprivate _unsafe_getCameraId() {\n\t\treturn CameraRecordType.createId(this.getCurrentPageId())\n\t}\n\n\t/**\n\t * The current camera.\n\t *\n\t * @public\n\t */\n\t@computed getCamera(): TLCamera {\n\t\tconst baseCamera = this.store.get(this._unsafe_getCameraId())!\n\t\tif (this._isLockedOnFollowingUser.get()) {\n\t\t\tconst followingCamera = this.getCameraForFollowing()\n\t\t\tif (followingCamera) {\n\t\t\t\treturn { ...baseCamera, ...followingCamera }\n\t\t\t}\n\t\t}\n\t\treturn baseCamera\n\t}\n\n\t@computed\n\tprivate getViewportPageBoundsForFollowing(): null | Box {\n\t\tconst followingUserId = this.getInstanceState().followingUserId\n\t\tif (!followingUserId) return null\n\t\tconst leaderPresence = this.getCollaborators().find((c) => c.userId === followingUserId)\n\t\tif (!leaderPresence) return null\n\n\t\t// Fit their viewport inside of our screen bounds\n\t\t// 1. calculate their viewport in page space\n\t\tconst { w: lw, h: lh } = leaderPresence.screenBounds\n\t\tconst { x: lx, y: ly, z: lz } = leaderPresence.camera\n\t\tconst theirViewport = new Box(-lx, -ly, lw / lz, lh / lz)\n\n\t\t// resize our screenBounds to contain their viewport\n\t\tconst ourViewport = this.getViewportScreenBounds().clone()\n\t\tconst ourAspectRatio = ourViewport.width / ourViewport.height\n\n\t\tourViewport.width = theirViewport.width\n\t\tourViewport.height = ourViewport.width / ourAspectRatio\n\t\tif (ourViewport.height < theirViewport.height) {\n\t\t\tourViewport.height = theirViewport.height\n\t\t\tourViewport.width = ourViewport.height * ourAspectRatio\n\t\t}\n\n\t\tourViewport.center = theirViewport.center\n\t\treturn ourViewport\n\t}\n\n\t@computed\n\tprivate getCameraForFollowing(): null | { x: number; y: number; z: number } {\n\t\tconst viewport = this.getViewportPageBoundsForFollowing()\n\t\tif (!viewport) return null\n\n\t\treturn {\n\t\t\tx: -viewport.x,\n\t\t\ty: -viewport.y,\n\t\t\tz: this.getViewportScreenBounds().w / viewport.width,\n\t\t}\n\t}\n\n\t/**\n\t * The current camera zoom level.\n\t *\n\t * @public\n\t */\n\t@computed getZoomLevel() {\n\t\treturn this.getCamera().z\n\t}\n\n\t/**\n\t * Get the camera's initial or reset zoom level.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getInitialZoom()\n\t * ```\n\t *\n\t * @public */\n\tgetInitialZoom() {\n\t\tconst cameraOptions = this.getCameraOptions()\n\t\t// If no camera constraints are provided, the default zoom is 100%\n\t\tif (!cameraOptions.constraints) return 1\n\n\t\t// When defaultZoom is default, the default zoom is 100%\n\t\tif (cameraOptions.constraints.initialZoom === 'default') return 1\n\n\t\tconst { zx, zy } = getCameraFitXFitY(this, cameraOptions)\n\n\t\tswitch (cameraOptions.constraints.initialZoom) {\n\t\t\tcase 'fit-min': {\n\t\t\t\treturn Math.max(zx, zy)\n\t\t\t}\n\t\t\tcase 'fit-max': {\n\t\t\t\treturn Math.min(zx, zy)\n\t\t\t}\n\t\t\tcase 'fit-x': {\n\t\t\t\treturn zx\n\t\t\t}\n\t\t\tcase 'fit-y': {\n\t\t\t\treturn zy\n\t\t\t}\n\t\t\tcase 'fit-min-100': {\n\t\t\t\treturn Math.min(1, Math.max(zx, zy))\n\t\t\t}\n\t\t\tcase 'fit-max-100': {\n\t\t\t\treturn Math.min(1, Math.min(zx, zy))\n\t\t\t}\n\t\t\tcase 'fit-x-100': {\n\t\t\t\treturn Math.min(1, zx)\n\t\t\t}\n\t\t\tcase 'fit-y-100': {\n\t\t\t\treturn Math.min(1, zy)\n\t\t\t}\n\t\t\tdefault: {\n\t\t\t\tthrow exhaustiveSwitchError(cameraOptions.constraints.initialZoom)\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Get the camera's base level for calculating actual zoom levels based on the zoom steps.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getBaseZoom()\n\t * ```\n\t *\n\t * @public */\n\tgetBaseZoom() {\n\t\tconst cameraOptions = this.getCameraOptions()\n\t\t// If no camera constraints are provided, the default zoom is 100%\n\t\tif (!cameraOptions.constraints) return 1\n\n\t\t// When defaultZoom is default, the default zoom is 100%\n\t\tif (cameraOptions.constraints.baseZoom === 'default') return 1\n\n\t\tconst { zx, zy } = getCameraFitXFitY(this, cameraOptions)\n\n\t\tswitch (cameraOptions.constraints.baseZoom) {\n\t\t\tcase 'fit-min': {\n\t\t\t\treturn Math.max(zx, zy)\n\t\t\t}\n\t\t\tcase 'fit-max': {\n\t\t\t\treturn Math.min(zx, zy)\n\t\t\t}\n\t\t\tcase 'fit-x': {\n\t\t\t\treturn zx\n\t\t\t}\n\t\t\tcase 'fit-y': {\n\t\t\t\treturn zy\n\t\t\t}\n\t\t\tcase 'fit-min-100': {\n\t\t\t\treturn Math.min(1, Math.max(zx, zy))\n\t\t\t}\n\t\t\tcase 'fit-max-100': {\n\t\t\t\treturn Math.min(1, Math.min(zx, zy))\n\t\t\t}\n\t\t\tcase 'fit-x-100': {\n\t\t\t\treturn Math.min(1, zx)\n\t\t\t}\n\t\t\tcase 'fit-y-100': {\n\t\t\t\treturn Math.min(1, zy)\n\t\t\t}\n\t\t\tdefault: {\n\t\t\t\tthrow exhaustiveSwitchError(cameraOptions.constraints.baseZoom)\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate _cameraOptions = atom('camera options', DEFAULT_CAMERA_OPTIONS)\n\n\t/**\n\t * Get the current camera options.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getCameraOptions()\n\t * ```\n\t *\n\t * @public */\n\tgetCameraOptions() {\n\t\treturn this._cameraOptions.get()\n\t}\n\n\t/**\n\t * Set the camera options. Changing the options won't immediately change the camera itself, so you may want to call `setCamera` after changing the options.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.setCameraOptions(myCameraOptions)\n\t * editor.setCamera(editor.getCamera())\n\t * ```\n\t *\n\t * @param options - The camera options to set.\n\t *\n\t * @public */\n\tsetCameraOptions(options: Partial) {\n\t\tconst next = structuredClone({\n\t\t\t...this._cameraOptions.__unsafe__getWithoutCapture(),\n\t\t\t...options,\n\t\t})\n\t\tif (next.zoomSteps?.length < 1) next.zoomSteps = [1]\n\t\tthis._cameraOptions.set(next)\n\t\treturn this\n\t}\n\n\t/** @internal */\n\tprivate getConstrainedCamera(\n\t\tpoint: VecLike,\n\t\topts?: TLCameraMoveOptions\n\t): {\n\t\tx: number\n\t\ty: number\n\t\tz: number\n\t} {\n\t\tconst currentCamera = this.getCamera()\n\n\t\tlet { x, y, z = currentCamera.z } = point\n\n\t\t// If force is true, then we'll set the camera to the point regardless of\n\t\t// the camera options, so that we can handle gestures that permit elasticity\n\t\t// or decay, or animations that occur while the camera is locked.\n\t\tif (!opts?.force) {\n\t\t\t// Apply any adjustments based on the camera options\n\n\t\t\tconst cameraOptions = this.getCameraOptions()\n\n\t\t\tconst zoomMin = cameraOptions.zoomSteps[0]\n\t\t\tconst zoomMax = last(cameraOptions.zoomSteps)!\n\n\t\t\tconst vsb = this.getViewportScreenBounds()\n\n\t\t\t// If bounds are provided, then we'll keep those bounds on screen\n\t\t\tif (cameraOptions.constraints) {\n\t\t\t\tconst { constraints } = cameraOptions\n\n\t\t\t\t// Clamp padding to half the viewport size on either dimension\n\t\t\t\tconst py = Math.min(constraints.padding.y, vsb.w / 2)\n\t\t\t\tconst px = Math.min(constraints.padding.x, vsb.h / 2)\n\n\t\t\t\t// Expand the bounds by the padding\n\t\t\t\tconst bounds = Box.From(cameraOptions.constraints.bounds)\n\n\t\t\t\t// For each axis, the \"natural zoom\" is the zoom at\n\t\t\t\t// which the expanded bounds (with padding) would fit\n\t\t\t\t// the current viewport screen bounds. Paddings are\n\t\t\t\t// equal to screen pixels at 100%\n\t\t\t\t// The min and max zooms are factors of the smaller natural zoom axis\n\n\t\t\t\tconst zx = (vsb.w - px * 2) / bounds.w\n\t\t\t\tconst zy = (vsb.h - py * 2) / bounds.h\n\n\t\t\t\tconst baseZoom = this.getBaseZoom()\n\t\t\t\tconst maxZ = zoomMax * baseZoom\n\t\t\t\tconst minZ = zoomMin * baseZoom\n\n\t\t\t\tif (opts?.reset) {\n\t\t\t\t\tz = this.getInitialZoom()\n\t\t\t\t}\n\n\t\t\t\tif (z < minZ || z > maxZ) {\n\t\t\t\t\t// We're trying to zoom out past the minimum zoom level,\n\t\t\t\t\t// or in past the maximum zoom level, so stop the camera\n\t\t\t\t\t// but keep the current center\n\t\t\t\t\tconst { x: cx, y: cy, z: cz } = currentCamera\n\t\t\t\t\tconst cxA = -cx + vsb.w / cz / 2\n\t\t\t\t\tconst cyA = -cy + vsb.h / cz / 2\n\t\t\t\t\tz = clamp(z, minZ, maxZ)\n\t\t\t\t\tconst cxB = -cx + vsb.w / z / 2\n\t\t\t\t\tconst cyB = -cy + vsb.h / z / 2\n\t\t\t\t\tx = cx + cxB - cxA\n\t\t\t\t\ty = cy + cyB - cyA\n\t\t\t\t}\n\n\t\t\t\t// Calculate available space\n\t\t\t\tconst minX = px / z - bounds.x\n\t\t\t\tconst minY = py / z - bounds.y\n\t\t\t\tconst freeW = (vsb.w - px * 2) / z - bounds.w\n\t\t\t\tconst freeH = (vsb.h - py * 2) / z - bounds.h\n\t\t\t\tconst originX = minX + freeW * constraints.origin.x\n\t\t\t\tconst originY = minY + freeH * constraints.origin.y\n\n\t\t\t\tconst behaviorX =\n\t\t\t\t\ttypeof constraints.behavior === 'string' ? constraints.behavior : constraints.behavior.x\n\t\t\t\tconst behaviorY =\n\t\t\t\t\ttypeof constraints.behavior === 'string' ? constraints.behavior : constraints.behavior.y\n\n\t\t\t\t// x axis\n\n\t\t\t\tif (opts?.reset) {\n\t\t\t\t\t// Reset the camera according to the origin\n\t\t\t\t\tx = originX\n\t\t\t\t\ty = originY\n\t\t\t\t} else {\n\t\t\t\t\t// Apply constraints to the camera\n\t\t\t\t\tswitch (behaviorX) {\n\t\t\t\t\t\tcase 'fixed': {\n\t\t\t\t\t\t\t// Center according to the origin\n\t\t\t\t\t\t\tx = originX\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcase 'contain': {\n\t\t\t\t\t\t\t// When below fit zoom, center the camera\n\t\t\t\t\t\t\tif (z < zx) x = originX\n\t\t\t\t\t\t\t// When above fit zoom, keep the bounds within padding distance of the viewport edge\n\t\t\t\t\t\t\telse x = clamp(x, minX + freeW, minX)\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcase 'inside': {\n\t\t\t\t\t\t\t// When below fit zoom, constrain the camera so that the bounds stay completely within the viewport\n\t\t\t\t\t\t\tif (z < zx) x = clamp(x, minX, (vsb.w - px) / z - bounds.w)\n\t\t\t\t\t\t\t// When above fit zoom, keep the bounds within padding distance of the viewport edge\n\t\t\t\t\t\t\telse x = clamp(x, minX + freeW, minX)\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcase 'outside': {\n\t\t\t\t\t\t\t// Constrain the camera so that the bounds never leaves the viewport\n\t\t\t\t\t\t\tx = clamp(x, px / z - bounds.w, (vsb.w - px) / z)\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcase 'free': {\n\t\t\t\t\t\t\t// noop, use whatever x is provided\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t\tdefault: {\n\t\t\t\t\t\t\tthrow exhaustiveSwitchError(behaviorX)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// y axis\n\n\t\t\t\t\tswitch (behaviorY) {\n\t\t\t\t\t\tcase 'fixed': {\n\t\t\t\t\t\t\ty = originY\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcase 'contain': {\n\t\t\t\t\t\t\tif (z < zy) y = originY\n\t\t\t\t\t\t\telse y = clamp(y, minY + freeH, minY)\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcase 'inside': {\n\t\t\t\t\t\t\tif (z < zy) y = clamp(y, minY, (vsb.h - py) / z - bounds.h)\n\t\t\t\t\t\t\telse y = clamp(y, minY + freeH, minY)\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcase 'outside': {\n\t\t\t\t\t\t\ty = clamp(y, py / z - bounds.h, (vsb.h - py) / z)\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcase 'free': {\n\t\t\t\t\t\t\t// noop, use whatever x is provided\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t\tdefault: {\n\t\t\t\t\t\t\tthrow exhaustiveSwitchError(behaviorY)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// constrain the zoom, preserving the center\n\t\t\t\tif (z > zoomMax || z < zoomMin) {\n\t\t\t\t\tconst { x: cx, y: cy, z: cz } = currentCamera\n\t\t\t\t\tz = clamp(z, zoomMin, zoomMax)\n\t\t\t\t\tx = cx + (-cx + vsb.w / z / 2) - (-cx + vsb.w / cz / 2)\n\t\t\t\t\ty = cy + (-cy + vsb.h / z / 2) - (-cy + vsb.h / cz / 2)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn { x, y, z }\n\t}\n\n\t/** @internal */\n\tprivate _setCamera(point: VecLike, opts?: TLCameraMoveOptions): this {\n\t\tconst currentCamera = this.getCamera()\n\n\t\tconst { x, y, z } = this.getConstrainedCamera(point, opts)\n\n\t\tif (currentCamera.x === x && currentCamera.y === y && currentCamera.z === z) {\n\t\t\treturn this\n\t\t}\n\n\t\ttransact(() => {\n\t\t\tconst camera = { ...currentCamera, x, y, z }\n\t\t\tthis.run(\n\t\t\t\t() => {\n\t\t\t\t\tthis.store.put([camera]) // include id and meta here\n\t\t\t\t},\n\t\t\t\t{ history: 'ignore' }\n\t\t\t)\n\n\t\t\t// Dispatch a new pointer move because the pointer's page will have changed\n\t\t\t// (its screen position will compute to a new page position given the new camera position)\n\t\t\tconst { currentScreenPoint, currentPagePoint } = this.inputs\n\t\t\tconst { screenBounds } = this.store.unsafeGetWithoutCapture(TLINSTANCE_ID)!\n\n\t\t\t// compare the next page point (derived from the current camera) to the current page point\n\t\t\tif (\n\t\t\t\tcurrentScreenPoint.x / z - x !== currentPagePoint.x ||\n\t\t\t\tcurrentScreenPoint.y / z - y !== currentPagePoint.y\n\t\t\t) {\n\t\t\t\t// If it's changed, dispatch a pointer event\n\t\t\t\tconst event: TLPointerEventInfo = {\n\t\t\t\t\ttype: 'pointer',\n\t\t\t\t\ttarget: 'canvas',\n\t\t\t\t\tname: 'pointer_move',\n\t\t\t\t\t// weird but true: we need to put the screen point back into client space\n\t\t\t\t\tpoint: Vec.AddXY(currentScreenPoint, screenBounds.x, screenBounds.y),\n\t\t\t\t\tpointerId: INTERNAL_POINTER_IDS.CAMERA_MOVE,\n\t\t\t\t\tctrlKey: this.inputs.ctrlKey,\n\t\t\t\t\taltKey: this.inputs.altKey,\n\t\t\t\t\tshiftKey: this.inputs.shiftKey,\n\t\t\t\t\tbutton: 0,\n\t\t\t\t\tisPen: this.getInstanceState().isPenMode ?? false,\n\t\t\t\t}\n\n\t\t\t\tif (opts?.immediate) {\n\t\t\t\t\tthis._flushEventForTick(event)\n\t\t\t\t} else {\n\t\t\t\t\tthis.dispatch(event)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tthis._tickCameraState()\n\t\t})\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Set the current camera.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.setCamera({ x: 0, y: 0})\n\t * editor.setCamera({ x: 0, y: 0, z: 1.5})\n\t * editor.setCamera({ x: 0, y: 0, z: 1.5}, { animation: { duration: 1000, easing: (t) => t * t } })\n\t * ```\n\t *\n\t * @param point - The new camera position.\n\t * @param opts - The camera move options.\n\t *\n\t * @public\n\t */\n\tsetCamera(point: VecLike, opts?: TLCameraMoveOptions): this {\n\t\tconst { isLocked } = this._cameraOptions.__unsafe__getWithoutCapture()\n\t\tif (isLocked && !opts?.force) return this\n\n\t\t// Stop any camera animations\n\t\tthis.stopCameraAnimation()\n\n\t\t// Stop following any user\n\t\tif (this.getInstanceState().followingUserId) {\n\t\t\tthis.stopFollowingUser()\n\t\t}\n\n\t\tconst _point = Vec.Cast(point)\n\n\t\tif (!Number.isFinite(_point.x)) _point.x = 0\n\t\tif (!Number.isFinite(_point.y)) _point.y = 0\n\t\tif (_point.z === undefined || !Number.isFinite(_point.z)) point.z = this.getZoomLevel()\n\n\t\tconst camera = this.getConstrainedCamera(_point, opts)\n\n\t\tif (opts?.animation) {\n\t\t\tconst { width, height } = this.getViewportScreenBounds()\n\t\t\tthis._animateToViewport(\n\t\t\t\tnew Box(-camera.x, -camera.y, width / camera.z, height / camera.z),\n\t\t\t\topts\n\t\t\t)\n\t\t} else {\n\t\t\tthis._setCamera(camera, {\n\t\t\t\t...opts,\n\t\t\t\t// we already did the constraining, so we don't need to do it again\n\t\t\t\tforce: true,\n\t\t\t})\n\t\t}\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Center the camera on a point (in the current page space).\n\t *\n\t * @example\n\t * ```ts\n\t * editor.centerOnPoint({ x: 100, y: 100 })\n\t * editor.centerOnPoint({ x: 100, y: 100 }, { animation: { duration: 200 } })\n\t * ```\n\t *\n\t * @param point - The point in the current page space to center on.\n\t * @param animation - The camera move options.\n\t *\n\t * @public\n\t */\n\tcenterOnPoint(point: VecLike, opts?: TLCameraMoveOptions): this {\n\t\tconst { isLocked } = this.getCameraOptions()\n\t\tif (isLocked && !opts?.force) return this\n\n\t\tconst { width: pw, height: ph } = this.getViewportPageBounds()\n\t\tthis.setCamera(new Vec(-(point.x - pw / 2), -(point.y - ph / 2), this.getCamera().z), opts)\n\t\treturn this\n\t}\n\n\t/**\n\t * Zoom the camera to fit the current page's content in the viewport.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.zoomToFit()\n\t * editor.zoomToFit({ animation: { duration: 200 } })\n\t * ```\n\t *\n\t * @param opts - The camera move options.\n\t *\n\t * @public\n\t */\n\tzoomToFit(opts?: TLCameraMoveOptions): this {\n\t\tconst ids = [...this.getCurrentPageShapeIds()]\n\t\tif (ids.length <= 0) return this\n\t\tconst pageBounds = Box.Common(compact(ids.map((id) => this.getShapePageBounds(id))))\n\t\tthis.zoomToBounds(pageBounds, opts)\n\t\treturn this\n\t}\n\n\t/**\n\t * Set the zoom back to 100%.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.resetZoom()\n\t * editor.resetZoom(editor.getViewportScreenCenter(), { animation: { duration: 200 } })\n\t * editor.resetZoom(editor.getViewportScreenCenter(), { animation: { duration: 200 } })\n\t * ```\n\t *\n\t * @param point - The screen point to zoom out on. Defaults to the viewport screen center.\n\t * @param opts - The camera move options.\n\t *\n\t * @public\n\t */\n\tresetZoom(point = this.getViewportScreenCenter(), opts?: TLCameraMoveOptions): this {\n\t\tconst { isLocked, constraints: constraints } = this.getCameraOptions()\n\t\tif (isLocked && !opts?.force) return this\n\n\t\tconst currentCamera = this.getCamera()\n\t\tconst { x: cx, y: cy, z: cz } = currentCamera\n\t\tconst { x, y } = point\n\n\t\tlet z = 1\n\n\t\tif (constraints) {\n\t\t\t// For non-infinite fit, we'll set the camera to the natural zoom level...\n\t\t\t// unless it's already there, in which case we'll set zoom to 100%\n\t\t\tconst initialZoom = this.getInitialZoom()\n\t\t\tif (cz !== initialZoom) {\n\t\t\t\tz = initialZoom\n\t\t\t}\n\t\t}\n\n\t\tthis.setCamera(\n\t\t\tnew Vec(cx + (x / z - x) - (x / cz - x), cy + (y / z - y) - (y / cz - y), z),\n\t\t\topts\n\t\t)\n\t\treturn this\n\t}\n\n\t/**\n\t * Zoom the camera in.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.zoomIn()\n\t * editor.zoomIn(editor.getViewportScreenCenter(), { animation: { duration: 200 } })\n\t * editor.zoomIn(editor.inputs.currentScreenPoint, { animation: { duration: 200 } })\n\t * ```\n\t *\n\t * @param point - The screen point to zoom in on. Defaults to the screen center\n\t * @param opts - The camera move options.\n\t *\n\t * @public\n\t */\n\tzoomIn(point = this.getViewportScreenCenter(), opts?: TLCameraMoveOptions): this {\n\t\tconst { isLocked } = this.getCameraOptions()\n\t\tif (isLocked && !opts?.force) return this\n\n\t\tconst { x: cx, y: cy, z: cz } = this.getCamera()\n\n\t\tconst { zoomSteps } = this.getCameraOptions()\n\t\tif (zoomSteps !== null && zoomSteps.length > 1) {\n\t\t\tconst baseZoom = this.getBaseZoom()\n\t\t\tlet zoom = last(zoomSteps)! * baseZoom\n\t\t\tfor (let i = 1; i < zoomSteps.length; i++) {\n\t\t\t\tconst z1 = zoomSteps[i - 1] * baseZoom\n\t\t\t\tconst z2 = zoomSteps[i] * baseZoom\n\t\t\t\tif (z2 - cz <= (z2 - z1) / 2) continue\n\t\t\t\tzoom = z2\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tthis.setCamera(\n\t\t\t\tnew Vec(\n\t\t\t\t\tcx + (point.x / zoom - point.x) - (point.x / cz - point.x),\n\t\t\t\t\tcy + (point.y / zoom - point.y) - (point.y / cz - point.y),\n\t\t\t\t\tzoom\n\t\t\t\t),\n\t\t\t\topts\n\t\t\t)\n\t\t}\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Zoom the camera out.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.zoomOut()\n\t * editor.zoomOut(editor.getViewportScreenCenter(), { animation: { duration: 120 } })\n\t * editor.zoomOut(editor.inputs.currentScreenPoint, { animation: { duration: 120 } })\n\t * ```\n\t *\n\t * @param point - The point to zoom out on. Defaults to the viewport screen center.\n\t * @param opts - The camera move options.\n\t *\n\t * @public\n\t */\n\tzoomOut(point = this.getViewportScreenCenter(), opts?: TLCameraMoveOptions): this {\n\t\tconst { isLocked } = this.getCameraOptions()\n\t\tif (isLocked && !opts?.force) return this\n\n\t\tconst { zoomSteps } = this.getCameraOptions()\n\t\tif (zoomSteps !== null && zoomSteps.length > 1) {\n\t\t\tconst baseZoom = this.getBaseZoom()\n\t\t\tconst { x: cx, y: cy, z: cz } = this.getCamera()\n\t\t\t// start at the max\n\t\t\tlet zoom = zoomSteps[0] * baseZoom\n\t\t\tfor (let i = zoomSteps.length - 1; i > 0; i--) {\n\t\t\t\tconst z1 = zoomSteps[i - 1] * baseZoom\n\t\t\t\tconst z2 = zoomSteps[i] * baseZoom\n\t\t\t\tif (z2 - cz >= (z2 - z1) / 2) continue\n\t\t\t\tzoom = z1\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tthis.setCamera(\n\t\t\t\tnew Vec(\n\t\t\t\t\tcx + (point.x / zoom - point.x) - (point.x / cz - point.x),\n\t\t\t\t\tcy + (point.y / zoom - point.y) - (point.y / cz - point.y),\n\t\t\t\t\tzoom\n\t\t\t\t),\n\t\t\t\topts\n\t\t\t)\n\t\t}\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Zoom the camera to fit the current selection in the viewport.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.zoomToSelection()\n\t * editor.zoomToSelection({ animation: { duration: 200 } })\n\t * ```\n\t *\n\t * @param animation - The camera move options.\n\t *\n\t * @public\n\t */\n\tzoomToSelection(opts?: TLCameraMoveOptions): this {\n\t\tconst { isLocked } = this.getCameraOptions()\n\t\tif (isLocked && !opts?.force) return this\n\n\t\tconst selectionPageBounds = this.getSelectionPageBounds()\n\t\tif (selectionPageBounds) {\n\t\t\tthis.zoomToBounds(selectionPageBounds, {\n\t\t\t\ttargetZoom: Math.max(1, this.getZoomLevel()),\n\t\t\t\t...opts,\n\t\t\t})\n\t\t}\n\t\treturn this\n\t}\n\n\t/**\n\t * Zoom the camera to fit a bounding box (in the current page space).\n\t *\n\t * @example\n\t * ```ts\n\t * editor.zoomToBounds(myBounds)\n\t * editor.zoomToBounds(myBounds, { animation: { duration: 200 } })\n\t * editor.zoomToBounds(myBounds, { animation: { duration: 200 }, inset: 0, targetZoom: 1 })\n\t * ```\n\t *\n\t * @param bounds - The bounding box.\n\t * @param opts - The camera move options, target zoom, or custom inset amount.\n\t *\n\t * @public\n\t */\n\tzoomToBounds(\n\t\tbounds: BoxLike,\n\t\topts?: { targetZoom?: number; inset?: number } & TLCameraMoveOptions\n\t): this {\n\t\tconst cameraOptions = this._cameraOptions.__unsafe__getWithoutCapture()\n\t\tif (cameraOptions.isLocked && !opts?.force) return this\n\n\t\tconst viewportScreenBounds = this.getViewportScreenBounds()\n\n\t\tconst inset = opts?.inset ?? Math.min(ZOOM_TO_FIT_PADDING, viewportScreenBounds.width * 0.28)\n\n\t\tconst baseZoom = this.getBaseZoom()\n\t\tconst zoomMin = cameraOptions.zoomSteps[0]\n\t\tconst zoomMax = last(cameraOptions.zoomSteps)!\n\n\t\tlet zoom = clamp(\n\t\t\tMath.min(\n\t\t\t\t(viewportScreenBounds.width - inset) / bounds.w,\n\t\t\t\t(viewportScreenBounds.height - inset) / bounds.h\n\t\t\t),\n\t\t\tzoomMin * baseZoom,\n\t\t\tzoomMax * baseZoom\n\t\t)\n\n\t\tif (opts?.targetZoom !== undefined) {\n\t\t\tzoom = Math.min(opts.targetZoom, zoom)\n\t\t}\n\n\t\tthis.setCamera(\n\t\t\tnew Vec(\n\t\t\t\t-bounds.x + (viewportScreenBounds.width - bounds.w * zoom) / 2 / zoom,\n\t\t\t\t-bounds.y + (viewportScreenBounds.height - bounds.h * zoom) / 2 / zoom,\n\t\t\t\tzoom\n\t\t\t),\n\t\t\topts\n\t\t)\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Stop the current camera animation, if any.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.stopCameraAnimation()\n\t * ```\n\t *\n\t * @public\n\t */\n\tstopCameraAnimation(): this {\n\t\tthis.emit('stop-camera-animation')\n\t\treturn this\n\t}\n\n\t/** @internal */\n\tprivate _viewportAnimation = null as null | {\n\t\telapsed: number\n\t\tduration: number\n\t\teasing(t: number): number\n\t\tstart: Box\n\t\tend: Box\n\t}\n\n\t/** @internal */\n\tprivate _animateViewport(ms: number): void {\n\t\tif (!this._viewportAnimation) return\n\n\t\tthis._viewportAnimation.elapsed += ms\n\n\t\tconst { elapsed, easing, duration, start, end } = this._viewportAnimation\n\n\t\tif (elapsed > duration) {\n\t\t\tthis.off('tick', this._animateViewport)\n\t\t\tthis._viewportAnimation = null\n\t\t\tthis._setCamera(new Vec(-end.x, -end.y, this.getViewportScreenBounds().width / end.width))\n\t\t\treturn\n\t\t}\n\n\t\tconst remaining = duration - elapsed\n\t\tconst t = easing(1 - remaining / duration)\n\n\t\tconst left = start.minX + (end.minX - start.minX) * t\n\t\tconst top = start.minY + (end.minY - start.minY) * t\n\t\tconst right = start.maxX + (end.maxX - start.maxX) * t\n\n\t\tthis._setCamera(new Vec(-left, -top, this.getViewportScreenBounds().width / (right - left)), {\n\t\t\tforce: true,\n\t\t})\n\t}\n\n\t/** @internal */\n\tprivate _animateToViewport(\n\t\ttargetViewportPage: Box,\n\t\topts = { animation: DEFAULT_ANIMATION_OPTIONS } as TLCameraMoveOptions\n\t) {\n\t\tconst { animation, ...rest } = opts\n\t\tif (!animation) return\n\t\tconst { duration = 0, easing = EASINGS.easeInOutCubic } = animation\n\t\tconst animationSpeed = this.user.getAnimationSpeed()\n\t\tconst viewportPageBounds = this.getViewportPageBounds()\n\n\t\t// If we have an existing animation, then stop it\n\t\tthis.stopCameraAnimation()\n\n\t\t// also stop following any user\n\t\tif (this.getInstanceState().followingUserId) {\n\t\t\tthis.stopFollowingUser()\n\t\t}\n\n\t\tif (duration === 0 || animationSpeed === 0) {\n\t\t\t// If we have no animation, then skip the animation and just set the camera\n\t\t\treturn this._setCamera(\n\t\t\t\tnew Vec(\n\t\t\t\t\t-targetViewportPage.x,\n\t\t\t\t\t-targetViewportPage.y,\n\t\t\t\t\tthis.getViewportScreenBounds().width / targetViewportPage.width\n\t\t\t\t),\n\t\t\t\t{ ...rest }\n\t\t\t)\n\t\t}\n\n\t\t// Set our viewport animation\n\t\tthis._viewportAnimation = {\n\t\t\telapsed: 0,\n\t\t\tduration: duration / animationSpeed,\n\t\t\teasing,\n\t\t\tstart: viewportPageBounds.clone(),\n\t\t\tend: targetViewportPage.clone(),\n\t\t}\n\n\t\t// If we ever get a \"stop-camera-animation\" event, we stop\n\t\tthis.once('stop-camera-animation', () => {\n\t\t\tthis.off('tick', this._animateViewport)\n\t\t\tthis._viewportAnimation = null\n\t\t})\n\n\t\t// On each tick, animate the viewport\n\t\tthis.on('tick', this._animateViewport)\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Slide the camera in a certain direction.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.slideCamera({ speed: 1, direction: { x: 1, y: 0 }, friction: 0.1 })\n\t * ```\n\t *\n\t * @param opts - Options for the slide\n\t * @public\n\t */\n\tslideCamera(\n\t\topts = {} as {\n\t\t\tspeed: number\n\t\t\tdirection: VecLike\n\t\t\tfriction?: number\n\t\t\tspeedThreshold?: number\n\t\t\tforce?: boolean\n\t\t}\n\t): this {\n\t\tconst { isLocked } = this.getCameraOptions()\n\t\tif (isLocked && !opts?.force) return this\n\n\t\tconst animationSpeed = this.user.getAnimationSpeed()\n\t\tif (animationSpeed === 0) return this\n\n\t\tthis.stopCameraAnimation()\n\n\t\tconst {\n\t\t\tspeed,\n\t\t\tfriction = this.options.cameraSlideFriction,\n\t\t\tdirection,\n\t\t\tspeedThreshold = 0.01,\n\t\t} = opts\n\t\tlet currentSpeed = Math.min(speed, 1)\n\n\t\tconst cancel = () => {\n\t\t\tthis.off('tick', moveCamera)\n\t\t\tthis.off('stop-camera-animation', cancel)\n\t\t}\n\n\t\tthis.once('stop-camera-animation', cancel)\n\n\t\tconst moveCamera = (elapsed: number) => {\n\t\t\tconst { x: cx, y: cy, z: cz } = this.getCamera()\n\t\t\tconst movementVec = Vec.Mul(direction, (currentSpeed * elapsed) / cz)\n\n\t\t\t// Apply friction\n\t\t\tcurrentSpeed *= 1 - friction\n\t\t\tif (currentSpeed < speedThreshold) {\n\t\t\t\tcancel()\n\t\t\t} else {\n\t\t\t\tthis._setCamera(new Vec(cx + movementVec.x, cy + movementVec.y, cz))\n\t\t\t}\n\t\t}\n\n\t\tthis.on('tick', moveCamera)\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Animate the camera to a user's cursor position. This also briefly show the user's cursor if it's not currently visible.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.zoomToUser(myUserId)\n\t * editor.zoomToUser(myUserId, { animation: { duration: 200 } })\n\t * ```\n\t *\n\t * @param userId - The id of the user to animate to.\n\t * @param opts - The camera move options.\n\t * @public\n\t */\n\tzoomToUser(userId: string, opts: TLCameraMoveOptions = { animation: { duration: 500 } }): this {\n\t\tconst presence = this.getCollaborators().find((c) => c.userId === userId)\n\n\t\tif (!presence) return this\n\n\t\tthis.run(() => {\n\t\t\t// If we're following someone, stop following them\n\t\t\tif (this.getInstanceState().followingUserId !== null) {\n\t\t\t\tthis.stopFollowingUser()\n\t\t\t}\n\n\t\t\t// If we're not on the same page, move to the page they're on\n\t\t\tconst isOnSamePage = presence.currentPageId === this.getCurrentPageId()\n\t\t\tif (!isOnSamePage) {\n\t\t\t\tthis.setCurrentPage(presence.currentPageId)\n\t\t\t}\n\n\t\t\t// Only animate the camera if the user is on the same page as us\n\t\t\tif (opts && opts.animation && !isOnSamePage) {\n\t\t\t\topts.animation = undefined\n\t\t\t}\n\n\t\t\tthis.centerOnPoint(presence.cursor, opts)\n\n\t\t\t// Highlight the user's cursor\n\t\t\tconst { highlightedUserIds } = this.getInstanceState()\n\t\t\tthis.updateInstanceState({ highlightedUserIds: [...highlightedUserIds, userId] })\n\n\t\t\t// Unhighlight the user's cursor after a few seconds\n\t\t\tthis.timers.setTimeout(() => {\n\t\t\t\tconst highlightedUserIds = [...this.getInstanceState().highlightedUserIds]\n\t\t\t\tconst index = highlightedUserIds.indexOf(userId)\n\t\t\t\tif (index < 0) return\n\t\t\t\thighlightedUserIds.splice(index, 1)\n\t\t\t\tthis.updateInstanceState({ highlightedUserIds })\n\t\t\t}, this.options.collaboratorIdleTimeoutMs)\n\t\t})\n\n\t\treturn this\n\t}\n\n\t// Viewport\n\n\t/** @internal */\n\tprivate _willSetInitialBounds = true\n\n\t/**\n\t * Update the viewport. The viewport will measure the size and screen position of its container\n\t * element. This should be done whenever the container's position on the screen changes.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.updateViewportScreenBounds(new Box(0, 0, 1280, 1024))\n\t * editor.updateViewportScreenBounds(new Box(0, 0, 1280, 1024), true)\n\t * ```\n\t *\n\t * @param center - Whether to preserve the viewport page center as the viewport changes.\n\t *\n\t * @public\n\t */\n\tupdateViewportScreenBounds(screenBounds: Box | HTMLElement, center = false): this {\n\t\tif (!(screenBounds instanceof Box)) {\n\t\t\tconst rect = screenBounds.getBoundingClientRect()\n\t\t\tscreenBounds = new Box(\n\t\t\t\trect.left || rect.x,\n\t\t\t\trect.top || rect.y,\n\t\t\t\tMath.max(rect.width, 1),\n\t\t\t\tMath.max(rect.height, 1)\n\t\t\t)\n\t\t} else {\n\t\t\tscreenBounds.width = Math.max(screenBounds.width, 1)\n\t\t\tscreenBounds.height = Math.max(screenBounds.height, 1)\n\t\t}\n\n\t\tconst insets = [\n\t\t\t// top\n\t\t\tscreenBounds.minY !== 0,\n\t\t\t// right\n\t\t\t!approximately(document.body.scrollWidth, screenBounds.maxX, 1),\n\t\t\t// bottom\n\t\t\t!approximately(document.body.scrollHeight, screenBounds.maxY, 1),\n\t\t\t// left\n\t\t\tscreenBounds.minX !== 0,\n\t\t]\n\n\t\tconst { _willSetInitialBounds } = this\n\n\t\tthis._willSetInitialBounds = false\n\n\t\tconst { screenBounds: prevScreenBounds, insets: prevInsets } = this.getInstanceState()\n\t\tif (screenBounds.equals(prevScreenBounds) && insets.every((v, i) => v === prevInsets[i])) {\n\t\t\t// nothing to do\n\t\t\treturn this\n\t\t}\n\n\t\tif (_willSetInitialBounds) {\n\t\t\t// If we have just received the initial bounds, don't center the camera.\n\t\t\tthis.updateInstanceState({ screenBounds: screenBounds.toJson(), insets })\n\t\t\tthis.setCamera(this.getCamera())\n\t\t} else {\n\t\t\tif (center && !this.getInstanceState().followingUserId) {\n\t\t\t\t// Get the page center before the change, make the change, and restore it\n\t\t\t\tconst before = this.getViewportPageBounds().center\n\t\t\t\tthis.updateInstanceState({ screenBounds: screenBounds.toJson(), insets })\n\t\t\t\tthis.centerOnPoint(before)\n\t\t\t} else {\n\t\t\t\t// Otherwise,\n\t\t\t\tthis.updateInstanceState({ screenBounds: screenBounds.toJson(), insets })\n\t\t\t\tthis._setCamera(Vec.From({ ...this.getCamera() }))\n\t\t\t}\n\t\t}\n\n\t\tthis._tickCameraState()\n\n\t\treturn this\n\t}\n\n\t/**\n\t * The bounds of the editor's viewport in screen space.\n\t *\n\t * @public\n\t */\n\t@computed getViewportScreenBounds() {\n\t\tconst { x, y, w, h } = this.getInstanceState().screenBounds\n\t\treturn new Box(x, y, w, h)\n\t}\n\n\t/**\n\t * The center of the editor's viewport in screen space.\n\t *\n\t * @public\n\t */\n\t@computed getViewportScreenCenter() {\n\t\tconst viewportScreenBounds = this.getViewportScreenBounds()\n\t\treturn new Vec(\n\t\t\tviewportScreenBounds.midX - viewportScreenBounds.minX,\n\t\t\tviewportScreenBounds.midY - viewportScreenBounds.minY\n\t\t)\n\t}\n\n\t/**\n\t * The current viewport in the current page space.\n\t *\n\t * @public\n\t */\n\t@computed getViewportPageBounds() {\n\t\tconst { w, h } = this.getViewportScreenBounds()\n\t\tconst { x: cx, y: cy, z: cz } = this.getCamera()\n\t\treturn new Box(-cx, -cy, w / cz, h / cz)\n\t}\n\n\t/**\n\t * Convert a point in screen space to a point in the current page space.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.screenToPage({ x: 100, y: 100 })\n\t * ```\n\t *\n\t * @param point - The point in screen space.\n\t *\n\t * @public\n\t */\n\tscreenToPage(point: VecLike) {\n\t\tconst { screenBounds } = this.store.unsafeGetWithoutCapture(TLINSTANCE_ID)!\n\t\tconst { x: cx, y: cy, z: cz = 1 } = this.getCamera()\n\t\treturn new Vec(\n\t\t\t(point.x - screenBounds.x) / cz - cx,\n\t\t\t(point.y - screenBounds.y) / cz - cy,\n\t\t\tpoint.z ?? 0.5\n\t\t)\n\t}\n\n\t/**\n\t * Convert a point in the current page space to a point in current screen space.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.pageToScreen({ x: 100, y: 100 })\n\t * ```\n\t *\n\t * @param point - The point in page space.\n\t *\n\t * @public\n\t */\n\tpageToScreen(point: VecLike) {\n\t\tconst { screenBounds } = this.store.unsafeGetWithoutCapture(TLINSTANCE_ID)!\n\t\tconst { x: cx, y: cy, z: cz = 1 } = this.getCamera()\n\t\treturn new Vec(\n\t\t\t(point.x + cx) * cz + screenBounds.x,\n\t\t\t(point.y + cy) * cz + screenBounds.y,\n\t\t\tpoint.z ?? 0.5\n\t\t)\n\t}\n\n\t/**\n\t * Convert a point in the current page space to a point in current viewport space.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.pageToViewport({ x: 100, y: 100 })\n\t * ```\n\t *\n\t * @param point - The point in page space.\n\t *\n\t * @public\n\t */\n\tpageToViewport(point: VecLike) {\n\t\tconst { x: cx, y: cy, z: cz = 1 } = this.getCamera()\n\t\treturn new Vec((point.x + cx) * cz, (point.y + cy) * cz, point.z ?? 0.5)\n\t}\n\t// Collaborators\n\n\t@computed\n\tprivate _getCollaboratorsQuery() {\n\t\treturn this.store.query.records('instance_presence', () => ({\n\t\t\tuserId: { neq: this.user.getId() },\n\t\t}))\n\t}\n\n\t/**\n\t * Returns a list of presence records for all peer collaborators.\n\t * This will return the latest presence record for each connected user.\n\t *\n\t * @public\n\t */\n\t@computed\n\tgetCollaborators() {\n\t\tconst allPresenceRecords = this._getCollaboratorsQuery().get()\n\t\tif (!allPresenceRecords.length) return EMPTY_ARRAY\n\t\tconst userIds = [...new Set(allPresenceRecords.map((c) => c.userId))].sort()\n\t\treturn userIds.map((id) => {\n\t\t\tconst latestPresence = allPresenceRecords\n\t\t\t\t.filter((c) => c.userId === id)\n\t\t\t\t.sort((a, b) => b.lastActivityTimestamp - a.lastActivityTimestamp)[0]\n\t\t\treturn latestPresence\n\t\t})\n\t}\n\n\t/**\n\t * Returns a list of presence records for all peer collaborators on the current page.\n\t * This will return the latest presence record for each connected user.\n\t *\n\t * @public\n\t */\n\t@computed\n\tgetCollaboratorsOnCurrentPage() {\n\t\tconst currentPageId = this.getCurrentPageId()\n\t\treturn this.getCollaborators().filter((c) => c.currentPageId === currentPageId)\n\t}\n\n\t// Following\n\n\t// When we are 'locked on' to a user, our camera is derived from their camera.\n\tprivate _isLockedOnFollowingUser = atom('isLockedOnFollowingUser', false)\n\n\t/**\n\t * Start viewport-following a user.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.startFollowingUser(myUserId)\n\t * ```\n\t *\n\t * @param userId - The id of the user to follow.\n\t * @param opts - Options for starting to follow a user.\n\t *\n\t * @public\n\t */\n\tstartFollowingUser(userId: string): this {\n\t\t// if we were already following someone, stop following them\n\t\tthis.stopFollowingUser()\n\n\t\tconst leaderPresences = this._getCollaboratorsQuery()\n\t\t\t.get()\n\t\t\t.filter((p) => p.userId === userId)\n\n\t\tif (!leaderPresences.length) {\n\t\t\tconsole.warn('User not found')\n\t\t\treturn this\n\t\t}\n\n\t\tconst thisUserId = this.user.getId()\n\n\t\tif (!thisUserId) {\n\t\t\tconsole.warn('You should set the userId for the current instance before following a user')\n\t\t\t// allow to continue since it's probably fine most of the time.\n\t\t}\n\n\t\t// If the leader is following us, then we can't follow them\n\t\tif (leaderPresences.some((p) => p.followingUserId === thisUserId)) {\n\t\t\treturn this\n\t\t}\n\n\t\tconst latestLeaderPresence = computed('latestLeaderPresence', () => {\n\t\t\treturn this.getCollaborators().find((p) => p.userId === userId)\n\t\t})\n\n\t\ttransact(() => {\n\t\t\tthis.updateInstanceState({ followingUserId: userId }, { history: 'ignore' })\n\n\t\t\t// we listen for page changes separately from the 'moveTowardsUser' tick\n\t\t\tconst dispose = react('update current page', () => {\n\t\t\t\tconst leaderPresence = latestLeaderPresence.get()\n\t\t\t\tif (!leaderPresence) {\n\t\t\t\t\tthis.stopFollowingUser()\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tif (\n\t\t\t\t\tleaderPresence.currentPageId !== this.getCurrentPageId() &&\n\t\t\t\t\tthis.getPage(leaderPresence.currentPageId)\n\t\t\t\t) {\n\t\t\t\t\t// if the page changed, switch page\n\t\t\t\t\tthis.run(\n\t\t\t\t\t\t() => {\n\t\t\t\t\t\t\t// sneaky store.put here, we can't go through setCurrentPage because it calls stopFollowingUser\n\t\t\t\t\t\t\tthis.store.put([\n\t\t\t\t\t\t\t\t{ ...this.getInstanceState(), currentPageId: leaderPresence.currentPageId },\n\t\t\t\t\t\t\t])\n\t\t\t\t\t\t\tthis._isLockedOnFollowingUser.set(true)\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{ history: 'ignore' }\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t})\n\n\t\t\tconst cancel = () => {\n\t\t\t\tdispose()\n\t\t\t\tthis._isLockedOnFollowingUser.set(false)\n\t\t\t\tthis.off('frame', moveTowardsUser)\n\t\t\t\tthis.off('stop-following', cancel)\n\t\t\t}\n\n\t\t\tconst moveTowardsUser = () => {\n\t\t\t\t// Stop following if we can't find the user\n\t\t\t\tconst leaderPresence = latestLeaderPresence.get()\n\t\t\t\tif (!leaderPresence) {\n\t\t\t\t\tthis.stopFollowingUser()\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\tif (this._isLockedOnFollowingUser.get()) return\n\n\t\t\t\tconst animationSpeed = this.user.getAnimationSpeed()\n\n\t\t\t\tif (animationSpeed === 0) {\n\t\t\t\t\tthis._isLockedOnFollowingUser.set(true)\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\tconst targetViewport = this.getViewportPageBoundsForFollowing()\n\t\t\t\tif (!targetViewport) {\n\t\t\t\t\tthis.stopFollowingUser()\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tconst currentViewport = this.getViewportPageBounds()\n\n\t\t\t\tconst diffX =\n\t\t\t\t\tMath.abs(targetViewport.minX - currentViewport.minX) +\n\t\t\t\t\tMath.abs(targetViewport.maxX - currentViewport.maxX)\n\t\t\t\tconst diffY =\n\t\t\t\t\tMath.abs(targetViewport.minY - currentViewport.minY) +\n\t\t\t\t\tMath.abs(targetViewport.maxY - currentViewport.maxY)\n\n\t\t\t\t// Stop chasing if we're close enough!\n\t\t\t\tif (\n\t\t\t\t\tdiffX < this.options.followChaseViewportSnap &&\n\t\t\t\t\tdiffY < this.options.followChaseViewportSnap\n\t\t\t\t) {\n\t\t\t\t\tthis._isLockedOnFollowingUser.set(true)\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\t// Chase the user's viewport!\n\t\t\t\t// Interpolate between the current viewport and the target viewport based on animation speed.\n\t\t\t\t// This will produce an 'ease-out' effect.\n\t\t\t\tconst t = clamp(animationSpeed * 0.5, 0.1, 0.8)\n\n\t\t\t\tconst nextViewport = new Box(\n\t\t\t\t\tlerp(currentViewport.minX, targetViewport.minX, t),\n\t\t\t\t\tlerp(currentViewport.minY, targetViewport.minY, t),\n\t\t\t\t\tlerp(currentViewport.width, targetViewport.width, t),\n\t\t\t\t\tlerp(currentViewport.height, targetViewport.height, t)\n\t\t\t\t)\n\n\t\t\t\tconst nextCamera = new Vec(\n\t\t\t\t\t-nextViewport.x,\n\t\t\t\t\t-nextViewport.y,\n\t\t\t\t\tthis.getViewportScreenBounds().width / nextViewport.width\n\t\t\t\t)\n\n\t\t\t\t// Update the camera!\n\t\t\t\tthis.stopCameraAnimation()\n\t\t\t\tthis._setCamera(nextCamera)\n\t\t\t}\n\n\t\t\tthis.once('stop-following', cancel)\n\t\t\tthis.addListener('frame', moveTowardsUser)\n\n\t\t\t// call once to start synchronously\n\t\t\tmoveTowardsUser()\n\t\t})\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Stop viewport-following a user.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.stopFollowingUser()\n\t * ```\n\t * @public\n\t */\n\tstopFollowingUser(): this {\n\t\tthis.run(\n\t\t\t() => {\n\t\t\t\t// commit the current camera to the store\n\t\t\t\tthis.store.put([this.getCamera()])\n\t\t\t\t// this must happen after the camera is committed\n\t\t\t\tthis._isLockedOnFollowingUser.set(false)\n\t\t\t\tthis.updateInstanceState({ followingUserId: null })\n\t\t\t\tthis.emit('stop-following')\n\t\t\t},\n\t\t\t{ history: 'ignore' }\n\t\t)\n\t\treturn this\n\t}\n\n\t/** @internal */\n\tgetUnorderedRenderingShapes(\n\t\t// The rendering state. We use this method both for rendering, which\n\t\t// is based on other state, and for computing order for SVG export,\n\t\t// which should work even when things are for example off-screen.\n\t\tuseEditorState: boolean\n\t): TLRenderingShape[] {\n\t\t// Here we get the shape as well as any of its children, as well as their\n\t\t// opacities. If the shape is being erased, and none of its ancestors are\n\t\t// being erased, then we reduce the opacity of the shape and all of its\n\t\t// ancestors; but we don't apply this effect more than once among a set\n\t\t// of descendants so that it does not compound.\n\n\t\t// This is designed to keep all the shapes in a single list which\n\t\t// allows the DOM nodes to be reused even when they become children\n\t\t// of other nodes.\n\n\t\tconst renderingShapes: TLRenderingShape[] = []\n\n\t\tlet nextIndex = this.options.maxShapesPerPage * 2\n\t\tlet nextBackgroundIndex = this.options.maxShapesPerPage\n\n\t\tconst erasingShapeIds = this.getErasingShapeIds()\n\n\t\tconst addShapeById = (id: TLShapeId, opacity: number, isAncestorErasing: boolean) => {\n\t\t\tconst shape = this.getShape(id)\n\t\t\tif (!shape) return\n\t\t\tif (this.isShapeHidden(shape)) return\n\n\t\t\topacity *= shape.opacity\n\t\t\tlet isShapeErasing = false\n\t\t\tconst util = this.getShapeUtil(shape)\n\n\t\t\tif (useEditorState) {\n\t\t\t\tisShapeErasing = !isAncestorErasing && erasingShapeIds.includes(id)\n\t\t\t\tif (isShapeErasing) {\n\t\t\t\t\topacity *= 0.32\n\t\t\t\t}\n\t\t\t}\n\n\t\t\trenderingShapes.push({\n\t\t\t\tid,\n\t\t\t\tshape,\n\t\t\t\tutil,\n\t\t\t\tindex: nextIndex,\n\t\t\t\tbackgroundIndex: nextBackgroundIndex,\n\t\t\t\topacity,\n\t\t\t})\n\n\t\t\tnextIndex += 1\n\t\t\tnextBackgroundIndex += 1\n\n\t\t\tconst childIds = this.getSortedChildIdsForParent(id)\n\t\t\tif (!childIds.length) return\n\n\t\t\tlet backgroundIndexToRestore = null\n\t\t\tif (util.providesBackgroundForChildren(shape)) {\n\t\t\t\tbackgroundIndexToRestore = nextBackgroundIndex\n\t\t\t\tnextBackgroundIndex = nextIndex\n\t\t\t\tnextIndex += this.options.maxShapesPerPage\n\t\t\t}\n\n\t\t\tfor (const childId of childIds) {\n\t\t\t\taddShapeById(childId, opacity, isAncestorErasing || isShapeErasing)\n\t\t\t}\n\n\t\t\tif (backgroundIndexToRestore !== null) {\n\t\t\t\tnextBackgroundIndex = backgroundIndexToRestore\n\t\t\t}\n\t\t}\n\n\t\t// If we're using editor state, then we're only interested in on-screen shapes.\n\t\t// If we're not using the editor state, then we're interested in ALL shapes, even those from other pages.\n\t\tconst pages = useEditorState ? [this.getCurrentPage()] : this.getPages()\n\t\tfor (const page of pages) {\n\t\t\tfor (const childId of this.getSortedChildIdsForParent(page.id)) {\n\t\t\t\taddShapeById(childId, 1, false)\n\t\t\t}\n\t\t}\n\n\t\treturn renderingShapes\n\t}\n\n\t// Camera state\n\t// Camera state does two things: first, it allows us to subscribe to whether\n\t// the camera is moving or not; and second, it allows us to update the rendering\n\t// shapes on the canvas. Changing the rendering shapes may cause shapes to\n\t// unmount / remount in the DOM, which is expensive; and computing visibility is\n\t// also expensive in large projects. For this reason, we use a second bounding\n\t// box just for rendering, and we only update after the camera stops moving.\n\tprivate _cameraState = atom('camera state', 'idle' as 'idle' | 'moving')\n\tprivate _cameraStateTimeoutRemaining = 0\n\t_decayCameraStateTimeout(elapsed: number) {\n\t\tthis._cameraStateTimeoutRemaining -= elapsed\n\t\tif (this._cameraStateTimeoutRemaining > 0) return\n\t\tthis.off('tick', this._decayCameraStateTimeout)\n\t\tthis._cameraState.set('idle')\n\t}\n\t_tickCameraState() {\n\t\t// always reset the timeout\n\t\tthis._cameraStateTimeoutRemaining = this.options.cameraMovingTimeoutMs\n\t\t// If the state is idle, then start the tick\n\t\tif (this._cameraState.__unsafe__getWithoutCapture() !== 'idle') return\n\t\tthis._cameraState.set('moving')\n\t\tthis.on('tick', this._decayCameraStateTimeout)\n\t}\n\n\t/**\n\t * Whether the camera is moving or idle.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getCameraState()\n\t * ```\n\t *\n\t * @public\n\t */\n\tgetCameraState() {\n\t\treturn this._cameraState.get()\n\t}\n\n\t/**\n\t * Get the shapes that should be displayed in the current viewport.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getRenderingShapes()\n\t * ```\n\t *\n\t * @public\n\t */\n\t@computed getRenderingShapes() {\n\t\tconst renderingShapes = this.getUnorderedRenderingShapes(true)\n\n\t\t// Its IMPORTANT that the result be sorted by id AND include the index\n\t\t// that the shape should be displayed at. Steve, this is the past you\n\t\t// telling the present you not to change this.\n\n\t\t// We want to sort by id because moving elements about in the DOM will\n\t\t// cause the element to get removed by react as it moves the DOM node. This\n\t\t// causes to re-render which is hella annoying and a perf\n\t\t// drain. By always sorting by 'id' we keep the shapes always in the\n\t\t// same order; but we later use index to set the element's 'z-index'\n\t\t// to change the \"rendered\" position in z-space.\n\t\treturn renderingShapes.sort(sortById)\n\t}\n\n\t/* --------------------- Pages ---------------------- */\n\n\t@computed private _getAllPagesQuery() {\n\t\treturn this.store.query.records('page')\n\t}\n\n\t/**\n\t * Info about the project's current pages.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getPages()\n\t * ```\n\t *\n\t * @public\n\t */\n\t@computed getPages(): TLPage[] {\n\t\treturn this._getAllPagesQuery().get().sort(sortByIndex)\n\t}\n\n\t/**\n\t * The current page.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getCurrentPage()\n\t * ```\n\t *\n\t * @public\n\t */\n\tgetCurrentPage(): TLPage {\n\t\treturn this.getPage(this.getCurrentPageId())!\n\t}\n\n\t/**\n\t * The current page id.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getCurrentPageId()\n\t * ```\n\t *\n\t * @public\n\t */\n\t@computed getCurrentPageId(): TLPageId {\n\t\treturn this.getInstanceState().currentPageId\n\t}\n\n\t/**\n\t * Get a page.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getPage(myPage.id)\n\t * editor.getPage(myPage)\n\t * ```\n\t *\n\t * @param page - The page (or page id) to get.\n\t *\n\t * @public\n\t */\n\tgetPage(page: TLPageId | TLPage): TLPage | undefined {\n\t\treturn this.store.get(typeof page === 'string' ? page : page.id)\n\t}\n\n\t/* @internal */\n\tprivate readonly _currentPageShapeIds: ReturnType\n\n\t/**\n\t * An array of all of the shapes on the current page.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getCurrentPageIds()\n\t * ```\n\t *\n\t * @public\n\t */\n\tgetCurrentPageShapeIds() {\n\t\treturn this._currentPageShapeIds.get()\n\t}\n\n\t/**\n\t * @internal\n\t */\n\t@computed\n\tgetCurrentPageShapeIdsSorted() {\n\t\treturn Array.from(this.getCurrentPageShapeIds()).sort()\n\t}\n\n\t/**\n\t * Get the ids of shapes on a page.\n\t *\n\t * @example\n\t * ```ts\n\t * const idsOnPage1 = editor.getPageShapeIds('page1')\n\t * const idsOnPage2 = editor.getPageShapeIds(myPage2)\n\t * ```\n\t *\n\t * @param page - The page (or page id) to get.\n\t *\n\t * @public\n\t **/\n\tgetPageShapeIds(page: TLPageId | TLPage): Set {\n\t\tconst pageId = typeof page === 'string' ? page : page.id\n\t\tconst result = this.store.query.exec('shape', { parentId: { eq: pageId } })\n\t\treturn this.getShapeAndDescendantIds(result.map((s) => s.id))\n\t}\n\n\t/**\n\t * Set the current page.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.setCurrentPage('page1')\n\t * editor.setCurrentPage(myPage1)\n\t * ```\n\t *\n\t * @param page - The page (or page id) to set as the current page.\n\t *\n\t * @public\n\t */\n\tsetCurrentPage(page: TLPageId | TLPage): this {\n\t\tconst pageId = typeof page === 'string' ? page : page.id\n\t\tif (!this.store.has(pageId)) {\n\t\t\tconsole.error(\"Tried to set the current page id to a page that doesn't exist.\")\n\t\t\treturn this\n\t\t}\n\n\t\tthis.stopFollowingUser()\n\t\t// finish off any in-progress interactions\n\t\tthis.complete()\n\n\t\treturn this.run(\n\t\t\t() => {\n\t\t\t\tthis.store.put([{ ...this.getInstanceState(), currentPageId: pageId }])\n\t\t\t},\n\t\t\t{ history: 'record-preserveRedoStack' }\n\t\t)\n\t}\n\n\t/**\n\t * Update a page.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.updatePage({ id: 'page2', name: 'Page 2' })\n\t * ```\n\t *\n\t * @param partial - The partial of the shape to update.\n\t *\n\t * @public\n\t */\n\tupdatePage(partial: RequiredKeys, 'id'>): this {\n\t\tif (this.getInstanceState().isReadonly) return this\n\n\t\tconst prev = this.getPage(partial.id)\n\t\tif (!prev) return this\n\n\t\treturn this.run(() => this.store.update(partial.id, (page) => ({ ...page, ...partial })))\n\t}\n\n\t/**\n\t * Create a page.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.createPage(myPage)\n\t * editor.createPage({ name: 'Page 2' })\n\t * ```\n\t *\n\t * @param page - The page (or page partial) to create.\n\t *\n\t * @public\n\t */\n\tcreatePage(page: Partial): this {\n\t\tthis.run(() => {\n\t\t\tif (this.getInstanceState().isReadonly) return\n\t\t\tif (this.getPages().length >= this.options.maxPages) return\n\t\t\tconst pages = this.getPages()\n\n\t\t\tconst name = getIncrementedName(\n\t\t\t\tpage.name ?? 'Page 1',\n\t\t\t\tpages.map((p) => p.name)\n\t\t\t)\n\n\t\t\tlet index = page.index\n\n\t\t\tif (!index || pages.some((p) => p.index === index)) {\n\t\t\t\tindex = getIndexAbove(pages[pages.length - 1].index)\n\t\t\t}\n\n\t\t\tconst newPage = PageRecordType.create({\n\t\t\t\tmeta: {},\n\t\t\t\t...page,\n\t\t\t\tname,\n\t\t\t\tindex,\n\t\t\t})\n\n\t\t\tthis.store.put([newPage])\n\t\t})\n\t\treturn this\n\t}\n\n\t/**\n\t * Delete a page.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.deletePage('page1')\n\t * ```\n\t *\n\t * @param id - The id of the page to delete.\n\t *\n\t * @public\n\t */\n\tdeletePage(page: TLPageId | TLPage): this {\n\t\tconst id = typeof page === 'string' ? page : page.id\n\t\tthis.run(() => {\n\t\t\tif (this.getInstanceState().isReadonly) return\n\t\t\tconst pages = this.getPages()\n\t\t\tif (pages.length === 1) return\n\n\t\t\tconst deletedPage = this.getPage(id)\n\t\t\tif (!deletedPage) return\n\n\t\t\tif (id === this.getCurrentPageId()) {\n\t\t\t\tconst index = pages.findIndex((page) => page.id === id)\n\t\t\t\tconst next = pages[index - 1] ?? pages[index + 1]\n\t\t\t\tthis.setCurrentPage(next.id)\n\t\t\t}\n\t\t\tthis.store.remove([deletedPage.id])\n\t\t})\n\t\treturn this\n\t}\n\n\t/**\n\t * Duplicate a page.\n\t *\n\t * @param id - The id of the page to duplicate. Defaults to the current page.\n\t * @param createId - The id of the new page. Defaults to a new id.\n\t *\n\t * @public\n\t */\n\tduplicatePage(page: TLPageId | TLPage, createId: TLPageId = PageRecordType.createId()): this {\n\t\tif (this.getPages().length >= this.options.maxPages) return this\n\t\tconst id = typeof page === 'string' ? page : page.id\n\t\tconst freshPage = this.getPage(id) // get the most recent version of the page anyway\n\t\tif (!freshPage) return this\n\n\t\tconst prevCamera = { ...this.getCamera() }\n\t\tconst content = this.getContentFromCurrentPage(this.getSortedChildIdsForParent(freshPage.id))\n\n\t\tthis.run(() => {\n\t\t\tconst pages = this.getPages()\n\t\t\tconst index = getIndexBetween(freshPage.index, pages[pages.indexOf(freshPage) + 1]?.index)\n\n\t\t\t// create the page (also creates the pagestate and camera for the new page)\n\t\t\tthis.createPage({ name: freshPage.name + ' Copy', id: createId, index })\n\t\t\t// set the new page as the current page\n\t\t\tthis.setCurrentPage(createId)\n\t\t\t// update the new page's camera to the previous page's camera\n\t\t\tthis.setCamera(prevCamera)\n\n\t\t\tif (content) {\n\t\t\t\t// If we had content on the previous page, put it on the new page\n\t\t\t\treturn this.putContentOntoCurrentPage(content)\n\t\t\t}\n\t\t})\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Rename a page.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.renamePage('page1', 'My Page')\n\t * ```\n\t *\n\t * @param id - The id of the page to rename.\n\t * @param name - The new name.\n\t *\n\t * @public\n\t */\n\trenamePage(page: TLPageId | TLPage, name: string) {\n\t\tconst id = typeof page === 'string' ? page : page.id\n\t\tif (this.getInstanceState().isReadonly) return this\n\t\tthis.updatePage({ id, name })\n\t\treturn this\n\t}\n\n\t/* --------------------- Assets --------------------- */\n\n\t/** @internal */\n\t@computed private _getAllAssetsQuery() {\n\t\treturn this.store.query.records('asset')\n\t}\n\n\t/**\n\t * Get all assets in the editor.\n\t *\n\t * @public\n\t */\n\tgetAssets() {\n\t\treturn this._getAllAssetsQuery().get()\n\t}\n\n\t/**\n\t * Create one or more assets.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.createAssets([...myAssets])\n\t * ```\n\t *\n\t * @param assets - The assets to create.\n\t *\n\t * @public\n\t */\n\tcreateAssets(assets: TLAsset[]): this {\n\t\tif (this.getInstanceState().isReadonly) return this\n\t\tif (assets.length <= 0) return this\n\t\tthis.run(() => this.store.put(assets), { history: 'ignore' })\n\t\treturn this\n\t}\n\n\t/**\n\t * Update one or more assets.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.updateAssets([{ id: 'asset1', name: 'New name' }])\n\t * ```\n\t *\n\t * @param assets - The assets to update.\n\t *\n\t * @public\n\t */\n\tupdateAssets(assets: TLAssetPartial[]): this {\n\t\tif (this.getInstanceState().isReadonly) return this\n\t\tif (assets.length <= 0) return this\n\t\tthis.run(\n\t\t\t() => {\n\t\t\t\tthis.store.put(\n\t\t\t\t\tassets.map((partial) => ({\n\t\t\t\t\t\t...this.store.get(partial.id)!,\n\t\t\t\t\t\t...partial,\n\t\t\t\t\t}))\n\t\t\t\t)\n\t\t\t},\n\t\t\t{ history: 'ignore' }\n\t\t)\n\t\treturn this\n\t}\n\n\t/**\n\t * Delete one or more assets.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.deleteAssets(['asset1', 'asset2'])\n\t * ```\n\t *\n\t * @param ids - The assets to delete.\n\t *\n\t * @public\n\t */\n\tdeleteAssets(assets: TLAssetId[] | TLAsset[]): this {\n\t\tif (this.getInstanceState().isReadonly) return this\n\n\t\tconst ids =\n\t\t\ttypeof assets[0] === 'string'\n\t\t\t\t? (assets as TLAssetId[])\n\t\t\t\t: (assets as TLAsset[]).map((a) => a.id)\n\t\tif (ids.length <= 0) return this\n\n\t\tthis.run(() => this.store.remove(ids), { history: 'ignore' })\n\t\treturn this\n\t}\n\n\t/**\n\t * Get an asset by its id.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getAsset('asset1')\n\t * ```\n\t *\n\t * @param asset - The asset (or asset id) to get.\n\t *\n\t * @public\n\t */\n\tgetAsset(asset: TLAssetId | TLAsset): TLAsset | undefined {\n\t\treturn this.store.get(typeof asset === 'string' ? asset : asset.id) as TLAsset | undefined\n\t}\n\n\tasync resolveAssetUrl(\n\t\tassetId: TLAssetId | null,\n\t\tcontext: {\n\t\t\tscreenScale?: number\n\t\t\tshouldResolveToOriginal?: boolean\n\t\t}\n\t): Promise {\n\t\tif (!assetId) return null\n\t\tconst asset = this.getAsset(assetId)\n\t\tif (!asset) return null\n\n\t\tconst { screenScale = 1, shouldResolveToOriginal = false } = context\n\n\t\t// We only look at the zoom level at powers of 2.\n\t\tconst zoomStepFunction = (zoom: number) => Math.pow(2, Math.ceil(Math.log2(zoom)))\n\t\tconst steppedScreenScale = Math.max(0.125, zoomStepFunction(screenScale))\n\t\tconst networkEffectiveType: string | null =\n\t\t\t'connection' in navigator ? (navigator as any).connection.effectiveType : null\n\t\tconst dpr = this.getInstanceState().devicePixelRatio\n\n\t\treturn await this.store.props.assets.resolve(asset, {\n\t\t\tscreenScale: screenScale || 1,\n\t\t\tsteppedScreenScale,\n\t\t\tdpr,\n\t\t\tnetworkEffectiveType,\n\t\t\tshouldResolveToOriginal,\n\t\t})\n\t}\n\t/**\n\t * Upload an asset to the store's asset service, returning a URL that can be used to resolve the\n\t * asset.\n\t */\n\tasync uploadAsset(asset: TLAsset, file: File): Promise {\n\t\treturn await this.store.props.assets.upload(asset, file)\n\t}\n\n\t/* --------------------- Shapes --------------------- */\n\n\t@computed\n\tprivate _getShapeGeometryCache(): ComputedCache {\n\t\treturn this.store.createComputedCache(\n\t\t\t'bounds',\n\t\t\t(shape) => this.getShapeUtil(shape).getGeometry(shape),\n\t\t\t(a, b) => a.props === b.props\n\t\t)\n\t}\n\n\t/**\n\t * Get the geometry of a shape.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getShapeGeometry(myShape)\n\t * editor.getShapeGeometry(myShapeId)\n\t * ```\n\t *\n\t * @param shape - The shape (or shape id) to get the geometry for.\n\t *\n\t * @public\n\t */\n\tgetShapeGeometry(shape: TLShape | TLShapeId): T {\n\t\treturn this._getShapeGeometryCache().get(typeof shape === 'string' ? shape : shape.id)! as T\n\t}\n\n\t/** @internal */\n\t@computed private _getShapeHandlesCache(): ComputedCache {\n\t\treturn this.store.createComputedCache('handles', (shape) => {\n\t\t\treturn this.getShapeUtil(shape).getHandles?.(shape)\n\t\t})\n\t}\n\n\t/**\n\t * Get the handles (if any) for a shape.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getShapeHandles(myShape)\n\t * editor.getShapeHandles(myShapeId)\n\t * ```\n\t *\n\t * @param shape - The shape (or shape id) to get the handles for.\n\t * @public\n\t */\n\tgetShapeHandles(shape: T | T['id']): TLHandle[] | undefined {\n\t\treturn this._getShapeHandlesCache().get(typeof shape === 'string' ? shape : shape.id)\n\t}\n\n\t/**\n\t * Get the local transform for a shape as a matrix model. This transform reflects both its\n\t * translation (x, y) from from either its parent's top left corner, if the shape's parent is\n\t * another shape, or else from the 0,0 of the page, if the shape's parent is the page; and the\n\t * shape's rotation.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getShapeLocalTransform(myShape)\n\t * ```\n\t *\n\t * @param shape - The shape to get the local transform for.\n\t *\n\t * @public\n\t */\n\tgetShapeLocalTransform(shape: TLShape | TLShapeId): Mat {\n\t\tconst id = typeof shape === 'string' ? shape : shape.id\n\t\tconst freshShape = this.getShape(id)\n\t\tif (!freshShape) throw Error('Editor.getTransform: shape not found')\n\t\treturn Mat.Identity().translate(freshShape.x, freshShape.y).rotate(freshShape.rotation)\n\t}\n\n\t/**\n\t * A cache of page transforms.\n\t *\n\t * @internal\n\t */\n\t@computed private _getShapePageTransformCache(): ComputedCache {\n\t\treturn this.store.createComputedCache('pageTransformCache', (shape) => {\n\t\t\tif (isPageId(shape.parentId)) {\n\t\t\t\treturn this.getShapeLocalTransform(shape)\n\t\t\t}\n\n\t\t\t// If the shape's parent doesn't exist yet (e.g. when merging in changes from remote in the wrong order)\n\t\t\t// then we can't compute the transform yet, so just return the identity matrix.\n\t\t\t// In the future we should look at creating a store update mechanism that understands and preserves\n\t\t\t// ordering.\n\t\t\tconst parentTransform =\n\t\t\t\tthis._getShapePageTransformCache().get(shape.parentId) ?? Mat.Identity()\n\t\t\treturn Mat.Compose(parentTransform, this.getShapeLocalTransform(shape)!)\n\t\t})\n\t}\n\n\t/**\n\t * Get the local transform of a shape's parent as a matrix model.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getShapeParentTransform(myShape)\n\t * ```\n\t *\n\t * @param shape - The shape (or shape id) to get the parent transform for.\n\t *\n\t * @public\n\t */\n\tgetShapeParentTransform(shape: TLShape | TLShapeId): Mat {\n\t\tconst id = typeof shape === 'string' ? shape : shape.id\n\t\tconst freshShape = this.getShape(id)\n\t\tif (!freshShape || isPageId(freshShape.parentId)) return Mat.Identity()\n\t\treturn this._getShapePageTransformCache().get(freshShape.parentId) ?? Mat.Identity()\n\t}\n\n\t/**\n\t * Get the transform of a shape in the current page space.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getShapePageTransform(myShape)\n\t * editor.getShapePageTransform(myShapeId)\n\t * ```\n\t *\n\t * @param shape - The shape (or shape id) to get the page transform for.\n\t *\n\t * @public\n\t */\n\tgetShapePageTransform(shape: TLShape | TLShapeId): Mat {\n\t\tconst id = typeof shape === 'string' ? shape : shape.id\n\t\treturn this._getShapePageTransformCache().get(id) ?? Mat.Identity()\n\t}\n\n\t/** @internal */\n\t@computed private _getShapePageBoundsCache(): ComputedCache {\n\t\treturn this.store.createComputedCache('pageBoundsCache', (shape) => {\n\t\t\tconst pageTransform = this._getShapePageTransformCache().get(shape.id)\n\n\t\t\tif (!pageTransform) return new Box()\n\n\t\t\tconst result = Box.FromPoints(\n\t\t\t\tMat.applyToPoints(pageTransform, this.getShapeGeometry(shape).vertices)\n\t\t\t)\n\n\t\t\treturn result\n\t\t})\n\t}\n\n\t/**\n\t * Get the bounds of a shape in the current page space.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getShapePageBounds(myShape)\n\t * editor.getShapePageBounds(myShapeId)\n\t * ```\n\t *\n\t * @param shape - The shape (or shape id) to get the bounds for.\n\t *\n\t * @public\n\t */\n\tgetShapePageBounds(shape: TLShape | TLShapeId): Box | undefined {\n\t\treturn this._getShapePageBoundsCache().get(typeof shape === 'string' ? shape : shape.id)\n\t}\n\n\t/**\n\t * A cache of clip paths used for clipping.\n\t *\n\t * @internal\n\t */\n\t@computed private _getShapeClipPathCache(): ComputedCache {\n\t\treturn this.store.createComputedCache('clipPathCache', (shape) => {\n\t\t\tconst pageMask = this._getShapeMaskCache().get(shape.id)\n\t\t\tif (!pageMask) return undefined\n\t\t\tif (pageMask.length === 0) {\n\t\t\t\treturn `polygon(0px 0px, 0px 0px, 0px 0px)`\n\t\t\t}\n\n\t\t\tconst pageTransform = this._getShapePageTransformCache().get(shape.id)\n\t\t\tif (!pageTransform) return undefined\n\n\t\t\tconst localMask = Mat.applyToPoints(Mat.Inverse(pageTransform), pageMask)\n\n\t\t\treturn `polygon(${localMask.map((p) => `${p.x}px ${p.y}px`).join(',')})`\n\t\t})\n\t}\n\n\t/**\n\t * Get the clip path for a shape.\n\t *\n\t * @example\n\t * ```ts\n\t * const clipPath = editor.getShapeClipPath(shape)\n\t * const clipPath = editor.getShapeClipPath(shape.id)\n\t * ```\n\t *\n\t * @param shape - The shape (or shape id) to get the clip path for.\n\t *\n\t * @returns The clip path or undefined.\n\t *\n\t * @public\n\t */\n\tgetShapeClipPath(shape: TLShape | TLShapeId): string | undefined {\n\t\treturn this._getShapeClipPathCache().get(typeof shape === 'string' ? shape : shape.id)\n\t}\n\n\t/** @internal */\n\t@computed private _getShapeMaskCache(): ComputedCache {\n\t\treturn this.store.createComputedCache('pageMaskCache', (shape) => {\n\t\t\tif (isPageId(shape.parentId)) return undefined\n\n\t\t\tconst frameAncestors = this.getShapeAncestors(shape.id).filter((shape) =>\n\t\t\t\tthis.isShapeOfType(shape, 'frame')\n\t\t\t)\n\n\t\t\tif (frameAncestors.length === 0) return undefined\n\n\t\t\tconst pageMask = frameAncestors\n\t\t\t\t.map((s) =>\n\t\t\t\t\t// Apply the frame transform to the frame outline to get the frame outline in the current page space\n\t\t\t\t\tthis._getShapePageTransformCache()\n\t\t\t\t\t\t.get(s.id)!\n\t\t\t\t\t\t.applyToPoints(this.getShapeGeometry(s).vertices)\n\t\t\t\t)\n\t\t\t\t.reduce((acc, b) => {\n\t\t\t\t\tif (!(b && acc)) return undefined\n\t\t\t\t\tconst intersection = intersectPolygonPolygon(acc, b)\n\t\t\t\t\tif (intersection) {\n\t\t\t\t\t\treturn intersection.map(Vec.Cast)\n\t\t\t\t\t}\n\t\t\t\t\treturn []\n\t\t\t\t})\n\n\t\t\treturn pageMask\n\t\t})\n\t}\n\n\t/**\n\t * Get the mask (in the current page space) for a shape.\n\t *\n\t * @example\n\t * ```ts\n\t * const pageMask = editor.getShapeMask(shape.id)\n\t * ```\n\t *\n\t * @param id - The id of the shape to get the mask for.\n\t *\n\t * @returns The mask for the shape.\n\t *\n\t * @public\n\t */\n\tgetShapeMask(shape: TLShapeId | TLShape): VecLike[] | undefined {\n\t\treturn this._getShapeMaskCache().get(typeof shape === 'string' ? shape : shape.id)\n\t}\n\n\t/**\n\t * Get the bounds of a shape in the current page space, incorporating any masks. For example, if the\n\t * shape were the child of a frame and was half way out of the frame, the bounds would be the half\n\t * of the shape that was in the frame.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getShapeMaskedPageBounds(myShape)\n\t * editor.getShapeMaskedPageBounds(myShapeId)\n\t * ```\n\t *\n\t * @param shape - The shape to get the masked bounds for.\n\t *\n\t * @public\n\t */\n\tgetShapeMaskedPageBounds(shape: TLShapeId | TLShape): Box | undefined {\n\t\tif (typeof shape !== 'string') shape = shape.id\n\t\treturn this._getShapeMaskedPageBoundsCache().get(shape)\n\t}\n\n\t/** @internal */\n\t@computed private _getShapeMaskedPageBoundsCache(): ComputedCache {\n\t\treturn this.store.createComputedCache('shapeMaskedPageBoundsCache', (shape) => {\n\t\t\tconst pageBounds = this._getShapePageBoundsCache().get(shape.id)\n\t\t\tif (!pageBounds) return\n\t\t\tconst pageMask = this._getShapeMaskCache().get(shape.id)\n\t\t\tif (pageMask) {\n\t\t\t\tif (pageMask.length === 0) return undefined\n\t\t\t\tconst { corners } = pageBounds\n\t\t\t\tif (corners.every((p, i) => p && Vec.Equals(p, pageMask[i]))) return pageBounds.clone()\n\t\t\t\tconst intersection = intersectPolygonPolygon(pageMask, corners)\n\t\t\t\tif (!intersection) return\n\t\t\t\treturn Box.FromPoints(intersection)\n\t\t\t}\n\t\t\treturn pageBounds\n\t\t})\n\t}\n\n\t/**\n\t * Get the ancestors of a shape.\n\t *\n\t * @example\n\t * ```ts\n\t * const ancestors = editor.getShapeAncestors(myShape)\n\t * const ancestors = editor.getShapeAncestors(myShapeId)\n\t * ```\n\t *\n\t * @param shape - The shape (or shape id) to get the ancestors for.\n\t *\n\t * @public\n\t */\n\tgetShapeAncestors(shape: TLShapeId | TLShape, acc: TLShape[] = []): TLShape[] {\n\t\tconst id = typeof shape === 'string' ? shape : shape.id\n\t\tconst freshShape = this.getShape(id)\n\t\tif (!freshShape) return acc\n\t\tconst parentId = freshShape.parentId\n\t\tif (isPageId(parentId)) {\n\t\t\tacc.reverse()\n\t\t\treturn acc\n\t\t}\n\n\t\tconst parent = this.store.get(parentId)\n\t\tif (!parent) return acc\n\t\tacc.push(parent)\n\t\treturn this.getShapeAncestors(parent, acc)\n\t}\n\n\t/**\n\t * Find the first ancestor matching the given predicate\n\t *\n\t * @example\n\t * ```ts\n\t * const ancestor = editor.findShapeAncestor(myShape)\n\t * const ancestor = editor.findShapeAncestor(myShape.id)\n\t * const ancestor = editor.findShapeAncestor(myShape.id, (shape) => shape.type === 'frame')\n\t * ```\n\t *\n\t * @param shape - The shape to check the ancestors for.\n\t *\n\t * @public\n\t */\n\tfindShapeAncestor(\n\t\tshape: TLShape | TLShapeId,\n\t\tpredicate: (parent: TLShape) => boolean\n\t): TLShape | undefined {\n\t\tconst id = typeof shape === 'string' ? shape : shape.id\n\t\tconst freshShape = this.getShape(id)\n\t\tif (!freshShape) return\n\n\t\tconst parentId = freshShape.parentId\n\t\tif (isPageId(parentId)) return\n\n\t\tconst parent = this.getShape(parentId)\n\t\tif (!parent) return\n\t\treturn predicate(parent) ? parent : this.findShapeAncestor(parent, predicate)\n\t}\n\n\t/**\n\t * Returns true if the the given shape has the given ancestor.\n\t *\n\t * @param shape - The shape.\n\t * @param ancestorId - The id of the ancestor.\n\t *\n\t * @public\n\t */\n\thasAncestor(shape: TLShape | TLShapeId | undefined, ancestorId: TLShapeId): boolean {\n\t\tconst id = typeof shape === 'string' ? shape : shape?.id\n\t\tconst freshShape = id && this.getShape(id)\n\t\tif (!freshShape) return false\n\t\tif (freshShape.parentId === ancestorId) return true\n\t\treturn this.hasAncestor(this.getShapeParent(freshShape), ancestorId)\n\t}\n\n\t/**\n\t * Get the common ancestor of two or more shapes that matches a predicate.\n\t *\n\t * @param shapes - The shapes (or shape ids) to check.\n\t * @param predicate - The predicate to match.\n\t */\n\tfindCommonAncestor(\n\t\tshapes: TLShape[] | TLShapeId[],\n\t\tpredicate?: (shape: TLShape) => boolean\n\t): TLShapeId | undefined {\n\t\tif (shapes.length === 0) {\n\t\t\treturn\n\t\t}\n\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\t\tconst freshShapes = compact(ids.map((id) => this.getShape(id)))\n\n\t\tif (freshShapes.length === 1) {\n\t\t\tconst parentId = freshShapes[0].parentId\n\t\t\tif (isPageId(parentId)) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\treturn predicate ? this.findShapeAncestor(freshShapes[0], predicate)?.id : parentId\n\t\t}\n\n\t\tconst [nodeA, ...others] = freshShapes\n\t\tlet ancestor = this.getShapeParent(nodeA)\n\t\twhile (ancestor) {\n\t\t\t// TODO: this is not ideal, optimize\n\t\t\tif (predicate && !predicate(ancestor)) {\n\t\t\t\tancestor = this.getShapeParent(ancestor)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif (others.every((shape) => this.hasAncestor(shape, ancestor!.id))) {\n\t\t\t\treturn ancestor!.id\n\t\t\t}\n\t\t\tancestor = this.getShapeParent(ancestor)\n\t\t}\n\t\treturn undefined\n\t}\n\n\t/**\n\t * Check whether a shape or its parent is locked.\n\t *\n\t * @param shape - The shape (or shape id) to check.\n\t *\n\t * @public\n\t */\n\tisShapeOrAncestorLocked(shape?: TLShape): boolean\n\tisShapeOrAncestorLocked(id?: TLShapeId): boolean\n\tisShapeOrAncestorLocked(arg?: TLShape | TLShapeId): boolean {\n\t\tconst shape = typeof arg === 'string' ? this.getShape(arg) : arg\n\t\tif (shape === undefined) return false\n\t\tif (shape.isLocked) return true\n\t\treturn this.isShapeOrAncestorLocked(this.getShapeParent(shape))\n\t}\n\n\t@computed\n\tprivate _notVisibleShapes() {\n\t\treturn notVisibleShapes(this)\n\t}\n\n\t/**\n\t * Get culled shapes.\n\t *\n\t * @public\n\t */\n\t@computed\n\tgetCulledShapes() {\n\t\tconst notVisibleShapes = this._notVisibleShapes().get()\n\t\tconst selectedShapeIds = this.getSelectedShapeIds()\n\t\tconst editingId = this.getEditingShapeId()\n\t\tconst culledShapes = new Set(notVisibleShapes)\n\t\t// we don't cull the shape we are editing\n\t\tif (editingId) {\n\t\t\tculledShapes.delete(editingId)\n\t\t}\n\t\t// we also don't cull selected shapes\n\t\tselectedShapeIds.forEach((id) => {\n\t\t\tculledShapes.delete(id)\n\t\t})\n\t\treturn culledShapes\n\t}\n\n\t/**\n\t * The bounds of the current page (the common bounds of all of the shapes on the page).\n\t *\n\t * @public\n\t */\n\t@computed getCurrentPageBounds(): Box | undefined {\n\t\tlet commonBounds: Box | undefined\n\n\t\tthis.getCurrentPageShapeIdsSorted().forEach((shapeId) => {\n\t\t\tconst bounds = this.getShapeMaskedPageBounds(shapeId)\n\t\t\tif (!bounds) return\n\t\t\tif (!commonBounds) {\n\t\t\t\tcommonBounds = bounds.clone()\n\t\t\t} else {\n\t\t\t\tcommonBounds = commonBounds.expand(bounds)\n\t\t\t}\n\t\t})\n\n\t\treturn commonBounds\n\t}\n\n\t/**\n\t * Get the top-most selected shape at the given point, ignoring groups.\n\t *\n\t * @param point - The point to check.\n\t *\n\t * @returns The top-most selected shape at the given point, or undefined if there is no shape at the point.\n\t */\n\tgetSelectedShapeAtPoint(point: VecLike): TLShape | undefined {\n\t\tconst selectedShapeIds = this.getSelectedShapeIds()\n\t\treturn this.getCurrentPageShapesSorted()\n\t\t\t.filter((shape) => shape.type !== 'group' && selectedShapeIds.includes(shape.id))\n\t\t\t.reverse() // find last\n\t\t\t.find((shape) => this.isPointInShape(shape, point, { hitInside: true, margin: 0 }))\n\t}\n\n\t/**\n\t * Get the shape at the current point.\n\t *\n\t * @param point - The point to check.\n\t * @param opts - Options for the check: `hitInside` to check if the point is inside the shape, `margin` to check if the point is within a margin of the shape, `hitFrameInside` to check if the point is inside the frame, and `filter` to filter the shapes to check.\n\t *\n\t * @returns The shape at the given point, or undefined if there is no shape at the point.\n\t */\n\tgetShapeAtPoint(\n\t\tpoint: VecLike,\n\t\topts = {} as {\n\t\t\trenderingOnly?: boolean\n\t\t\tmargin?: number\n\t\t\thitInside?: boolean\n\t\t\thitLocked?: boolean\n\t\t\t// TODO: we probably need to rename this, we don't quite _always_\n\t\t\t// respect this esp. in the part below that does \"Check labels first\"\n\t\t\thitLabels?: boolean\n\t\t\thitFrameInside?: boolean\n\t\t\tfilter?(shape: TLShape): boolean\n\t\t}\n\t): TLShape | undefined {\n\t\tconst zoomLevel = this.getZoomLevel()\n\t\tconst viewportPageBounds = this.getViewportPageBounds()\n\t\tconst {\n\t\t\tfilter,\n\t\t\tmargin = 0,\n\t\t\thitLocked = false,\n\t\t\thitLabels = false,\n\t\t\thitInside = false,\n\t\t\thitFrameInside = false,\n\t\t} = opts\n\n\t\tlet inHollowSmallestArea = Infinity\n\t\tlet inHollowSmallestAreaHit: TLShape | null = null\n\n\t\tlet inMarginClosestToEdgeDistance = Infinity\n\t\tlet inMarginClosestToEdgeHit: TLShape | null = null\n\n\t\tconst shapesToCheck = (\n\t\t\topts.renderingOnly\n\t\t\t\t? this.getCurrentPageRenderingShapesSorted()\n\t\t\t\t: this.getCurrentPageShapesSorted()\n\t\t).filter((shape) => {\n\t\t\tif (\n\t\t\t\t(shape.isLocked && !hitLocked) ||\n\t\t\t\tthis.isShapeHidden(shape) ||\n\t\t\t\tthis.isShapeOfType(shape, 'group')\n\t\t\t)\n\t\t\t\treturn false\n\t\t\tconst pageMask = this.getShapeMask(shape)\n\t\t\tif (pageMask && !pointInPolygon(point, pageMask)) return false\n\t\t\tif (filter) return filter(shape)\n\t\t\treturn true\n\t\t})\n\n\t\tfor (let i = shapesToCheck.length - 1; i >= 0; i--) {\n\t\t\tconst shape = shapesToCheck[i]\n\t\t\tconst geometry = this.getShapeGeometry(shape)\n\t\t\tconst isGroup = geometry instanceof Group2d\n\n\t\t\tconst pointInShapeSpace = this.getPointInShapeSpace(shape, point)\n\n\t\t\t// Check labels first\n\t\t\tif (\n\t\t\t\tthis.isShapeOfType(shape, 'arrow') ||\n\t\t\t\t(this.isShapeOfType(shape, 'geo') && shape.props.fill === 'none')\n\t\t\t) {\n\t\t\t\tif (shape.props.text.trim()) {\n\t\t\t\t\t// let's check whether the shape has a label and check that\n\t\t\t\t\tfor (const childGeometry of (geometry as Group2d).children) {\n\t\t\t\t\t\tif (childGeometry.isLabel && childGeometry.isPointInBounds(pointInShapeSpace)) {\n\t\t\t\t\t\t\treturn shape\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (this.isShapeOfType(shape, 'frame')) {\n\t\t\t\t// On the rare case that we've hit a frame, test again hitInside to be forced true;\n\t\t\t\t// this prevents clicks from passing through the body of a frame to shapes behind it.\n\n\t\t\t\t// If the hit is within the frame's outer margin, then select the frame\n\t\t\t\tconst distance = geometry.distanceToPoint(pointInShapeSpace, hitInside)\n\t\t\t\tif (Math.abs(distance) <= margin) {\n\t\t\t\t\treturn inMarginClosestToEdgeHit || shape\n\t\t\t\t}\n\n\t\t\t\tif (geometry.hitTestPoint(pointInShapeSpace, 0, true)) {\n\t\t\t\t\t// Once we've hit a frame, we want to end the search. If we have hit a shape\n\t\t\t\t\t// already, then this would either be above the frame or a child of the frame,\n\t\t\t\t\t// so we want to return that. Otherwise, the point is in the empty space of the\n\t\t\t\t\t// frame. If `hitFrameInside` is true (e.g. used drawing an arrow into the\n\t\t\t\t\t// frame) we the frame itself; other wise, (e.g. when hovering or pointing)\n\t\t\t\t\t// we would want to return null.\n\t\t\t\t\treturn (\n\t\t\t\t\t\tinMarginClosestToEdgeHit ||\n\t\t\t\t\t\tinHollowSmallestAreaHit ||\n\t\t\t\t\t\t(hitFrameInside ? shape : undefined)\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tlet distance: number\n\n\t\t\tif (isGroup) {\n\t\t\t\tlet minDistance = Infinity\n\t\t\t\tfor (const childGeometry of geometry.children) {\n\t\t\t\t\tif (childGeometry.isLabel && !hitLabels) continue\n\n\t\t\t\t\t// hit test the all of the child geometries that aren't labels\n\t\t\t\t\tconst tDistance = childGeometry.distanceToPoint(pointInShapeSpace, hitInside)\n\t\t\t\t\tif (tDistance < minDistance) {\n\t\t\t\t\t\tminDistance = tDistance\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tdistance = minDistance\n\t\t\t} else {\n\t\t\t\t// If the margin is zero and the geometry has a very small width or height,\n\t\t\t\t// then check the actual distance. This is to prevent a bug where straight\n\t\t\t\t// lines would never pass the broad phase (point-in-bounds) check.\n\t\t\t\tif (margin === 0 && (geometry.bounds.w < 1 || geometry.bounds.h < 1)) {\n\t\t\t\t\tdistance = geometry.distanceToPoint(pointInShapeSpace, hitInside)\n\t\t\t\t} else {\n\t\t\t\t\t// Broad phase\n\t\t\t\t\tif (geometry.bounds.containsPoint(pointInShapeSpace, margin)) {\n\t\t\t\t\t\t// Narrow phase (actual distance)\n\t\t\t\t\t\tdistance = geometry.distanceToPoint(pointInShapeSpace, hitInside)\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// Failed the broad phase, geddafugaotta'ere!\n\t\t\t\t\t\tdistance = Infinity\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (geometry.isClosed) {\n\t\t\t\t// For closed shapes, the distance will be positive if outside of\n\t\t\t\t// the shape or negative if inside of the shape. If the distance\n\t\t\t\t// is greater than the margin, then it's a miss. Otherwise...\n\n\t\t\t\tif (distance <= margin) {\n\t\t\t\t\tif (geometry.isFilled || (isGroup && geometry.children[0].isFilled)) {\n\t\t\t\t\t\t// If the shape is filled, then it's a hit. Remember, we're\n\t\t\t\t\t\t// starting from the TOP-MOST shape in z-index order, so any\n\t\t\t\t\t\t// other hits would be occluded by the shape.\n\t\t\t\t\t\treturn inMarginClosestToEdgeHit || shape\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// If the shape is bigger than the viewport, then skip it.\n\t\t\t\t\t\tif (this.getShapePageBounds(shape)!.contains(viewportPageBounds)) continue\n\n\t\t\t\t\t\t// For hollow shapes...\n\t\t\t\t\t\tif (Math.abs(distance) < margin) {\n\t\t\t\t\t\t\t// We want to preference shapes where we're inside of the\n\t\t\t\t\t\t\t// shape margin; and we would want to hit the shape with the\n\t\t\t\t\t\t\t// edge closest to the point.\n\t\t\t\t\t\t\tif (Math.abs(distance) < inMarginClosestToEdgeDistance) {\n\t\t\t\t\t\t\t\tinMarginClosestToEdgeDistance = Math.abs(distance)\n\t\t\t\t\t\t\t\tinMarginClosestToEdgeHit = shape\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else if (!inMarginClosestToEdgeHit) {\n\t\t\t\t\t\t\t// If we're not within margin distance to any edge, and if the\n\t\t\t\t\t\t\t// shape is hollow, then we want to hit the shape with the\n\t\t\t\t\t\t\t// smallest area. (There's a bug here with self-intersecting\n\t\t\t\t\t\t\t// shapes, like a closed drawing of an \"8\", but that's a bigger\n\t\t\t\t\t\t\t// problem to solve.)\n\t\t\t\t\t\t\tconst { area } = geometry\n\t\t\t\t\t\t\tif (area < inHollowSmallestArea) {\n\t\t\t\t\t\t\t\tinHollowSmallestArea = area\n\t\t\t\t\t\t\t\tinHollowSmallestAreaHit = shape\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// For open shapes (e.g. lines or draw shapes) always use the margin.\n\t\t\t\t// If the distance is less than the margin, return the shape as the hit.\n\t\t\t\tif (distance < this.options.hitTestMargin / zoomLevel) {\n\t\t\t\t\treturn shape\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// If we haven't hit any filled shapes or frames, then return either\n\t\t// the shape who we hit within the margin (and of those, the one that\n\t\t// had the shortest distance between the point and the shape edge),\n\t\t// or else the hollow shape with the smallest area\u2014or if we didn't hit\n\t\t// any margins or any hollow shapes, then null.\n\t\treturn inMarginClosestToEdgeHit || inHollowSmallestAreaHit || undefined\n\t}\n\n\t/**\n\t * Get the shapes, if any, at a given page point.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getShapesAtPoint({ x: 100, y: 100 })\n\t * editor.getShapesAtPoint({ x: 100, y: 100 }, { hitInside: true, exact: true })\n\t * ```\n\t *\n\t * @param point - The page point to test.\n\t *\n\t * @public\n\t */\n\tgetShapesAtPoint(\n\t\tpoint: VecLike,\n\t\topts = {} as { margin?: number; hitInside?: boolean }\n\t): TLShape[] {\n\t\treturn this.getCurrentPageShapes().filter(\n\t\t\t(shape) => !this.isShapeHidden(shape) && this.isPointInShape(shape, point, opts)\n\t\t)\n\t}\n\n\t/**\n\t * Test whether a point (in the current page space) will will a shape. This method takes into account masks,\n\t * such as when a shape is the child of a frame and is partially clipped by the frame.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.isPointInShape({ x: 100, y: 100 }, myShape)\n\t * ```\n\t *\n\t * @param shape - The shape to test against.\n\t * @param point - The page point to test (in the current page space).\n\t * @param hitInside - Whether to count as a hit if the point is inside of a closed shape.\n\t *\n\t * @public\n\t */\n\tisPointInShape(\n\t\tshape: TLShape | TLShapeId,\n\t\tpoint: VecLike,\n\t\topts = {} as {\n\t\t\tmargin?: number\n\t\t\thitInside?: boolean\n\t\t}\n\t): boolean {\n\t\tconst { hitInside = false, margin = 0 } = opts\n\t\tconst id = typeof shape === 'string' ? shape : shape.id\n\t\t// If the shape is masked, and if the point falls outside of that\n\t\t// mask, then it's definitely a miss\u2014we don't need to test further.\n\t\tconst pageMask = this.getShapeMask(id)\n\t\tif (pageMask && !pointInPolygon(point, pageMask)) return false\n\n\t\treturn this.getShapeGeometry(id).hitTestPoint(\n\t\t\tthis.getPointInShapeSpace(shape, point),\n\t\t\tmargin,\n\t\t\thitInside\n\t\t)\n\t}\n\n\t/**\n\t * Convert a point in the current page space to a point in the local space of a shape. For example, if a\n\t * shape's page point were `{ x: 100, y: 100 }`, a page point at `{ x: 110, y: 110 }` would be at\n\t * `{ x: 10, y: 10 }` in the shape's local space.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getPointInShapeSpace(myShape, { x: 100, y: 100 })\n\t * ```\n\t *\n\t * @param shape - The shape to get the point in the local space of.\n\t * @param point - The page point to get in the local space of the shape.\n\t *\n\t * @public\n\t */\n\tgetPointInShapeSpace(shape: TLShape | TLShapeId, point: VecLike): Vec {\n\t\tconst id = typeof shape === 'string' ? shape : shape.id\n\t\treturn this._getShapePageTransformCache().get(id)!.clone().invert().applyToPoint(point)\n\t}\n\n\t/**\n\t * Convert a delta in the current page space to a point in the local space of a shape's parent.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getPointInParentSpace(myShape.id, { x: 100, y: 100 })\n\t * ```\n\t *\n\t * @param shape - The shape to get the point in the local space of.\n\t * @param point - The page point to get in the local space of the shape.\n\t *\n\t * @public\n\t */\n\tgetPointInParentSpace(shape: TLShapeId | TLShape, point: VecLike): Vec {\n\t\tconst id = typeof shape === 'string' ? shape : shape.id\n\t\tconst freshShape = this.getShape(id)\n\t\tif (!freshShape) return new Vec(0, 0)\n\t\tif (isPageId(freshShape.parentId)) return Vec.From(point)\n\n\t\tconst parentTransform = this.getShapePageTransform(freshShape.parentId)\n\t\tif (!parentTransform) return Vec.From(point)\n\t\treturn parentTransform.clone().invert().applyToPoint(point)\n\t}\n\n\t/**\n\t * An array containing all of the shapes in the current page.\n\t *\n\t * @public\n\t */\n\t@computed getCurrentPageShapes(): TLShape[] {\n\t\treturn Array.from(this.getCurrentPageShapeIds(), (id) => this.store.get(id)! as TLShape)\n\t}\n\n\t/**\n\t * An array containing all of the shapes in the current page, sorted in z-index order (accounting\n\t * for nested shapes): e.g. A, B, BA, BB, C.\n\t *\n\t * @public\n\t */\n\t@computed getCurrentPageShapesSorted(): TLShape[] {\n\t\tconst result: TLShape[] = []\n\t\tconst topLevelShapes = this.getSortedChildIdsForParent(this.getCurrentPageId())\n\n\t\tfor (let i = 0, n = topLevelShapes.length; i < n; i++) {\n\t\t\tpushShapeWithDescendants(this, topLevelShapes[i], result)\n\t\t}\n\n\t\treturn result\n\t}\n\n\t/**\n\t * An array containing all of the rendering shapes in the current page, sorted in z-index order (accounting\n\t * for nested shapes): e.g. A, B, BA, BB, C.\n\t *\n\t * @public\n\t */\n\t@computed getCurrentPageRenderingShapesSorted(): TLShape[] {\n\t\tconst culledShapes = this.getCulledShapes()\n\t\treturn this.getCurrentPageShapesSorted().filter(\n\t\t\t({ id }) => !culledShapes.has(id) && !this.isShapeHidden(id)\n\t\t)\n\t}\n\n\t/**\n\t * Get whether a shape matches the type of a TLShapeUtil.\n\t *\n\t * @example\n\t * ```ts\n\t * const isArrowShape = isShapeOfType(someShape, 'arrow')\n\t * ```\n\t *\n\t * @param util - the TLShapeUtil constructor to test against\n\t * @param shape - the shape to test\n\t *\n\t * @public\n\t */\n\tisShapeOfType(shape: TLUnknownShape, type: T['type']): shape is T\n\tisShapeOfType(\n\t\tshapeId: TLUnknownShape['id'],\n\t\ttype: T['type']\n\t): shapeId is T['id']\n\tisShapeOfType(\n\t\targ: TLUnknownShape | TLUnknownShape['id'],\n\t\ttype: T['type']\n\t) {\n\t\tconst shape = typeof arg === 'string' ? this.getShape(arg) : arg\n\t\tif (!shape) return false\n\t\treturn shape.type === type\n\t}\n\n\t/**\n\t * Get a shape by its id.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getShape('box1')\n\t * ```\n\t *\n\t * @param id - The id of the shape to get.\n\t *\n\t * @public\n\t */\n\tgetShape(shape: TLShape | TLParentId): T | undefined {\n\t\tconst id = typeof shape === 'string' ? shape : shape.id\n\t\tif (!isShapeId(id)) return undefined\n\t\treturn this.store.get(id) as T\n\t}\n\n\t/**\n\t * Get the parent shape for a given shape. Returns undefined if the shape is the direct child of\n\t * the page.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getShapeParent(myShape)\n\t * ```\n\t *\n\t * @public\n\t */\n\tgetShapeParent(shape?: TLShape | TLShapeId): TLShape | undefined {\n\t\tconst id = typeof shape === 'string' ? shape : shape?.id\n\t\tif (!id) return undefined\n\t\tconst freshShape = this.getShape(id)\n\t\tif (freshShape === undefined || !isShapeId(freshShape.parentId)) return undefined\n\t\treturn this.store.get(freshShape.parentId)\n\t}\n\n\t/**\n\t * If siblingShape and targetShape are siblings, this returns targetShape. If targetShape has an\n\t * ancestor who is a sibling of siblingShape, this returns that ancestor. Otherwise, this returns\n\t * undefined.\n\t *\n\t * @internal\n\t */\n\tgetShapeNearestSibling(\n\t\tsiblingShape: TLShape,\n\t\ttargetShape: TLShape | undefined\n\t): TLShape | undefined {\n\t\tif (!targetShape) {\n\t\t\treturn undefined\n\t\t}\n\t\tif (targetShape.parentId === siblingShape.parentId) {\n\t\t\treturn targetShape\n\t\t}\n\n\t\tconst ancestor = this.findShapeAncestor(\n\t\t\ttargetShape,\n\t\t\t(ancestor) => ancestor.parentId === siblingShape.parentId\n\t\t)\n\n\t\treturn ancestor\n\t}\n\n\t/**\n\t * Get whether the given shape is the descendant of the given page.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.isShapeInPage(myShape)\n\t * editor.isShapeInPage(myShape, 'page1')\n\t * ```\n\t *\n\t * @param shape - The shape to check.\n\t * @param pageId - The id of the page to check against. Defaults to the current page.\n\t *\n\t * @public\n\t */\n\tisShapeInPage(shape: TLShape | TLShapeId, pageId = this.getCurrentPageId()): boolean {\n\t\tconst id = typeof shape === 'string' ? shape : shape.id\n\t\tconst shapeToCheck = this.getShape(id)\n\t\tif (!shapeToCheck) return false\n\n\t\tlet shapeIsInPage = false\n\n\t\tif (shapeToCheck.parentId === pageId) {\n\t\t\tshapeIsInPage = true\n\t\t} else {\n\t\t\tlet parent = this.getShape(shapeToCheck.parentId)\n\t\t\tisInPageSearch: while (parent) {\n\t\t\t\tif (parent.parentId === pageId) {\n\t\t\t\t\tshapeIsInPage = true\n\t\t\t\t\tbreak isInPageSearch\n\t\t\t\t}\n\t\t\t\tparent = this.getShape(parent.parentId)\n\t\t\t}\n\t\t}\n\n\t\treturn shapeIsInPage\n\t}\n\n\t/**\n\t * Get the id of the containing page for a given shape.\n\t *\n\t * @param shape - The shape to get the page id for.\n\t *\n\t * @returns The id of the page that contains the shape, or undefined if the shape is undefined.\n\t *\n\t * @public\n\t */\n\tgetAncestorPageId(shape?: TLShape | TLShapeId): TLPageId | undefined {\n\t\tconst id = typeof shape === 'string' ? shape : shape?.id\n\t\tconst _shape = id && this.getShape(id)\n\t\tif (!_shape) return undefined\n\t\tif (isPageId(_shape.parentId)) {\n\t\t\treturn _shape.parentId\n\t\t} else {\n\t\t\treturn this.getAncestorPageId(this.getShape(_shape.parentId))\n\t\t}\n\t}\n\n\t// Parents and children\n\n\t/**\n\t * A cache of parents to children.\n\t *\n\t * @internal\n\t */\n\tprivate readonly _parentIdsToChildIds: ReturnType\n\n\t/**\n\t * Reparent shapes to a new parent. This operation preserves the shape's current page positions /\n\t * rotations.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.reparentShapes([box1, box2], 'frame1')\n\t * editor.reparentShapes([box1.id, box2.id], 'frame1')\n\t * editor.reparentShapes([box1.id, box2.id], 'frame1', 4)\n\t * ```\n\t *\n\t * @param shapes - The shapes (or shape ids) of the shapes to reparent.\n\t * @param parentId - The id of the new parent shape.\n\t * @param insertIndex - The index to insert the children.\n\t *\n\t * @public\n\t */\n\treparentShapes(shapes: TLShapeId[] | TLShape[], parentId: TLParentId, insertIndex?: IndexKey) {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string' ? (shapes as TLShapeId[]) : shapes.map((s) => (s as TLShape).id)\n\t\tif (ids.length === 0) return this\n\n\t\tconst changes: TLShapePartial[] = []\n\n\t\tconst parentTransform = isPageId(parentId)\n\t\t\t? Mat.Identity()\n\t\t\t: this.getShapePageTransform(parentId)!\n\n\t\tconst parentPageRotation = parentTransform.rotation()\n\n\t\tlet indices: IndexKey[] = []\n\n\t\tconst sibs = compact(this.getSortedChildIdsForParent(parentId).map((id) => this.getShape(id)))\n\n\t\tif (insertIndex) {\n\t\t\tconst sibWithInsertIndex = sibs.find((s) => s.index === insertIndex)\n\t\t\tif (sibWithInsertIndex) {\n\t\t\t\t// If there's a sibling with the same index as the insert index...\n\t\t\t\tconst sibAbove = sibs[sibs.indexOf(sibWithInsertIndex) + 1]\n\t\t\t\tif (sibAbove) {\n\t\t\t\t\t// If the sibling has a sibling above it, insert the shapes\n\t\t\t\t\t// between the sibling and its sibling above it.\n\t\t\t\t\tindices = getIndicesBetween(insertIndex, sibAbove.index, ids.length)\n\t\t\t\t} else {\n\t\t\t\t\t// Or if the sibling is the top sibling, insert the shapes\n\t\t\t\t\t// above the sibling\n\t\t\t\t\tindices = getIndicesAbove(insertIndex, ids.length)\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// If there's no collision, then we can start at the insert index\n\t\t\t\tconst sibAbove = sibs.sort(sortByIndex).find((s) => s.index > insertIndex)\n\n\t\t\t\tif (sibAbove) {\n\t\t\t\t\t// If the siblings include a sibling with a higher index, insert the shapes\n\t\t\t\t\t// between the insert index and the sibling with the higher index.\n\t\t\t\t\tindices = getIndicesBetween(insertIndex, sibAbove.index, ids.length)\n\t\t\t\t} else {\n\t\t\t\t\t// Otherwise, we're at the top of the order, so insert the shapes above\n\t\t\t\t\t// the insert index.\n\t\t\t\t\tindices = getIndicesAbove(insertIndex, ids.length)\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\t// If insert index is not specified, start the index at the top.\n\t\t\tconst sib = sibs.length && sibs[sibs.length - 1]\n\t\t\tindices = sib ? getIndicesAbove(sib.index, ids.length) : getIndices(ids.length)\n\t\t}\n\n\t\tconst invertedParentTransform = parentTransform.clone().invert()\n\n\t\tconst shapesToReparent = compact(ids.map((id) => this.getShape(id)))\n\n\t\t// Ignore locked shapes so that we can reparent locked shapes, for example\n\t\t// when a locked shape's parent is deleted.\n\t\tthis.run(\n\t\t\t() => {\n\t\t\t\tfor (let i = 0; i < shapesToReparent.length; i++) {\n\t\t\t\t\tconst shape = shapesToReparent[i]\n\n\t\t\t\t\tconst pageTransform = this.getShapePageTransform(shape)!\n\t\t\t\t\tif (!pageTransform) continue\n\n\t\t\t\t\tconst pagePoint = pageTransform.point()\n\t\t\t\t\tif (!pagePoint) continue\n\n\t\t\t\t\tconst newPoint = invertedParentTransform.applyToPoint(pagePoint)\n\t\t\t\t\tconst newRotation = pageTransform.rotation() - parentPageRotation\n\n\t\t\t\t\tchanges.push({\n\t\t\t\t\t\tid: shape.id,\n\t\t\t\t\t\ttype: shape.type,\n\t\t\t\t\t\tparentId: parentId,\n\t\t\t\t\t\tx: newPoint.x,\n\t\t\t\t\t\ty: newPoint.y,\n\t\t\t\t\t\trotation: newRotation,\n\t\t\t\t\t\tindex: indices[i],\n\t\t\t\t\t})\n\t\t\t\t}\n\n\t\t\t\tthis.updateShapes(changes)\n\t\t\t},\n\t\t\t{ ignoreShapeLock: true }\n\t\t)\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Get the index above the highest child of a given parent.\n\t *\n\t * @param parentId - The id of the parent.\n\t *\n\t * @returns The index.\n\t *\n\t * @public\n\t */\n\tgetHighestIndexForParent(parent: TLParentId | TLPage | TLShape): IndexKey {\n\t\tconst parentId = typeof parent === 'string' ? parent : parent.id\n\t\tconst children = this._parentIdsToChildIds.get()[parentId]\n\n\t\tif (!children || children.length === 0) {\n\t\t\treturn 'a1' as IndexKey\n\t\t}\n\t\tconst shape = this.getShape(children[children.length - 1])!\n\t\treturn getIndexAbove(shape.index)\n\t}\n\n\t/**\n\t * Get an array of all the children of a shape.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getSortedChildIdsForParent('frame1')\n\t * ```\n\t *\n\t * @param parentId - The id of the parent shape.\n\t *\n\t * @public\n\t */\n\tgetSortedChildIdsForParent(parent: TLParentId | TLPage | TLShape): TLShapeId[] {\n\t\tconst parentId = typeof parent === 'string' ? parent : parent.id\n\t\tconst ids = this._parentIdsToChildIds.get()[parentId]\n\t\tif (!ids) return EMPTY_ARRAY\n\t\treturn ids\n\t}\n\n\t/**\n\t * Run a visitor function for all descendants of a shape.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.visitDescendants('frame1', myCallback)\n\t * ```\n\t *\n\t * @param parentId - The id of the parent shape.\n\t * @param visitor - The visitor function.\n\t *\n\t * @public\n\t */\n\tvisitDescendants(\n\t\tparent: TLParentId | TLPage | TLShape,\n\t\tvisitor: (id: TLShapeId) => void | false\n\t): this {\n\t\tconst parentId = typeof parent === 'string' ? parent : parent.id\n\t\tconst children = this.getSortedChildIdsForParent(parentId)\n\t\tfor (const id of children) {\n\t\t\tif (visitor(id) === false) continue\n\t\t\tthis.visitDescendants(id, visitor)\n\t\t}\n\t\treturn this\n\t}\n\n\t/**\n\t * Get the shape ids of all descendants of the given shapes (including the shapes themselves). IDs are returned in z-index order.\n\t *\n\t * @param ids - The ids of the shapes to get descendants of.\n\t *\n\t * @returns The descendant ids.\n\t *\n\t * @public\n\t */\n\tgetShapeAndDescendantIds(ids: TLShapeId[]): Set {\n\t\tconst shapeIds = new Set()\n\t\tfor (const shape of ids.map((id) => this.getShape(id)!).sort(sortByIndex)) {\n\t\t\tshapeIds.add(shape.id)\n\t\t\tthis.visitDescendants(shape, (descendantId) => {\n\t\t\t\tshapeIds.add(descendantId)\n\t\t\t})\n\t\t}\n\t\treturn shapeIds\n\t}\n\n\t/**\n\t * Get the shape that some shapes should be dropped on at a given point.\n\t *\n\t * @param point - The point to find the parent for.\n\t * @param droppingShapes - The shapes that are being dropped.\n\t *\n\t * @returns The shape to drop on.\n\t *\n\t * @public\n\t */\n\tgetDroppingOverShape(point: VecLike, droppingShapes: TLShape[] = []) {\n\t\t// starting from the top...\n\t\tconst currentPageShapesSorted = this.getCurrentPageShapesSorted()\n\t\tfor (let i = currentPageShapesSorted.length - 1; i >= 0; i--) {\n\t\t\tconst shape = currentPageShapesSorted[i]\n\n\t\t\tif (\n\t\t\t\t// ignore hidden shapes\n\t\t\t\tthis.isShapeHidden(shape) ||\n\t\t\t\t// don't allow dropping on selected shapes\n\t\t\t\tthis.getSelectedShapeIds().includes(shape.id) ||\n\t\t\t\t// only allow shapes that can receive children\n\t\t\t\t!this.getShapeUtil(shape).canDropShapes(shape, droppingShapes) ||\n\t\t\t\t// don't allow dropping a shape on itself or one of it's children\n\t\t\t\tdroppingShapes.find((s) => s.id === shape.id || this.hasAncestor(shape, s.id))\n\t\t\t) {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\t// Only allow dropping into the masked page bounds of the shape, e.g. when a frame is\n\t\t\t// partially clipped by its own parent frame\n\t\t\tconst maskedPageBounds = this.getShapeMaskedPageBounds(shape.id)\n\n\t\t\tif (\n\t\t\t\tmaskedPageBounds &&\n\t\t\t\tmaskedPageBounds.containsPoint(point) &&\n\t\t\t\tthis.getShapeGeometry(shape).hitTestPoint(this.getPointInShapeSpace(shape, point), 0, true)\n\t\t\t) {\n\t\t\t\treturn shape\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Get the shape that should be selected when you click on a given shape, assuming there is\n\t * nothing already selected. It will not return anything higher than or including the current\n\t * focus layer.\n\t *\n\t * @param shape - The shape to get the outermost selectable shape for.\n\t * @param filter - A function to filter the selectable shapes.\n\t *\n\t * @returns The outermost selectable shape.\n\t *\n\t * @public\n\t */\n\tgetOutermostSelectableShape(\n\t\tshape: TLShape | TLShapeId,\n\t\tfilter?: (shape: TLShape) => boolean\n\t): TLShape {\n\t\tconst id = typeof shape === 'string' ? shape : shape.id\n\t\tconst freshShape = this.getShape(id)!\n\t\tlet match = freshShape\n\t\tlet node = freshShape as TLShape | undefined\n\n\t\tconst focusedGroup = this.getFocusedGroup()\n\n\t\twhile (node) {\n\t\t\tif (\n\t\t\t\tthis.isShapeOfType(node, 'group') &&\n\t\t\t\tfocusedGroup?.id !== node.id &&\n\t\t\t\t!this.hasAncestor(focusedGroup, node.id) &&\n\t\t\t\t(filter?.(node) ?? true)\n\t\t\t) {\n\t\t\t\tmatch = node\n\t\t\t} else if (focusedGroup?.id === node.id) {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tnode = this.getShapeParent(node)\n\t\t}\n\n\t\treturn match\n\t}\n\n\t/* -------------------- Bindings -------------------- */\n\n\t@computed\n\tprivate _getBindingsIndexCache() {\n\t\tconst index = bindingsIndex(this)\n\t\treturn this.store.createComputedCache('bindingsIndex', (shape) => {\n\t\t\treturn index.get().get(shape.id)\n\t\t})\n\t}\n\n\t/**\n\t * Get a binding from the store by its ID if it exists.\n\t */\n\tgetBinding(id: TLBindingId): TLBinding | undefined {\n\t\treturn this.store.get(id) as TLBinding | undefined\n\t}\n\n\t/**\n\t * Get all bindings of a certain type _from_ a particular shape. These are the bindings whose\n\t * `fromId` matched the shape's ID.\n\t */\n\tgetBindingsFromShape(\n\t\tshape: TLShape | TLShapeId,\n\t\ttype: Binding['type']\n\t): Binding[] {\n\t\tconst id = typeof shape === 'string' ? shape : shape.id\n\t\treturn this.getBindingsInvolvingShape(id).filter(\n\t\t\t(b) => b.fromId === id && b.type === type\n\t\t) as Binding[]\n\t}\n\n\t/**\n\t * Get all bindings of a certain type _to_ a particular shape. These are the bindings whose\n\t * `toId` matches the shape's ID.\n\t */\n\tgetBindingsToShape(\n\t\tshape: TLShape | TLShapeId,\n\t\ttype: Binding['type']\n\t): Binding[] {\n\t\tconst id = typeof shape === 'string' ? shape : shape.id\n\t\treturn this.getBindingsInvolvingShape(id).filter(\n\t\t\t(b) => b.toId === id && b.type === type\n\t\t) as Binding[]\n\t}\n\n\t/**\n\t * Get all bindings involving a particular shape. This includes bindings where the shape is the\n\t * `fromId` or `toId`. If a type is provided, only bindings of that type are returned.\n\t */\n\tgetBindingsInvolvingShape(\n\t\tshape: TLShape | TLShapeId,\n\t\ttype?: Binding['type']\n\t): Binding[] {\n\t\tconst id = typeof shape === 'string' ? shape : shape.id\n\t\tconst result = this._getBindingsIndexCache().get(id) ?? EMPTY_ARRAY\n\t\tif (!type) return result as Binding[]\n\t\treturn result.filter((b) => b.type === type) as Binding[]\n\t}\n\n\t/**\n\t * Create bindings from a list of partial bindings. You can omit the ID and most props of a\n\t * binding, but the `type`, `toId`, and `fromId` must all be provided.\n\t */\n\tcreateBindings(partials: TLBindingCreate[]) {\n\t\tconst bindings: TLBinding[] = []\n\t\tfor (const partial of partials) {\n\t\t\tconst fromShape = this.getShape(partial.fromId)\n\t\t\tconst toShape = this.getShape(partial.toId)\n\t\t\tif (!fromShape || !toShape) continue\n\t\t\tif (!this.canBindShapes({ fromShape, toShape, binding: partial })) continue\n\n\t\t\tconst util = this.getBindingUtil(partial.type)\n\t\t\tconst defaultProps = util.getDefaultProps()\n\t\t\tconst binding = this.store.schema.types.binding.create({\n\t\t\t\t...partial,\n\t\t\t\tid: partial.id ?? createBindingId(),\n\t\t\t\tprops: {\n\t\t\t\t\t...defaultProps,\n\t\t\t\t\t...partial.props,\n\t\t\t\t},\n\t\t\t}) as TLBinding\n\n\t\t\tbindings.push(binding)\n\t\t}\n\n\t\tthis.store.put(bindings)\n\t\treturn this\n\t}\n\n\t/**\n\t * Create a single binding from a partial. You can omit the ID and most props of a binding, but\n\t * the `type`, `toId`, and `fromId` must all be provided.\n\t */\n\tcreateBinding(partial: TLBindingCreate) {\n\t\treturn this.createBindings([partial])\n\t}\n\n\t/**\n\t * Update bindings from a list of partial bindings. Each partial must include an ID, which will\n\t * be used to match the binding to it's existing record. If there is no existing record, that\n\t * binding is skipped. The changes from the partial are merged into the existing record.\n\t */\n\tupdateBindings(partials: (TLBindingUpdate | null | undefined)[]) {\n\t\tconst updated: TLBinding[] = []\n\n\t\tfor (const partial of partials) {\n\t\t\tif (!partial) continue\n\n\t\t\tconst current = this.getBinding(partial.id)\n\t\t\tif (!current) continue\n\n\t\t\tconst updatedBinding = applyPartialToRecordWithProps(current, partial)\n\t\t\tif (updatedBinding === current) continue\n\n\t\t\tconst fromShape = this.getShape(updatedBinding.fromId)\n\t\t\tconst toShape = this.getShape(updatedBinding.toId)\n\t\t\tif (!fromShape || !toShape) continue\n\t\t\tif (!this.canBindShapes({ fromShape, toShape, binding: updatedBinding })) continue\n\n\t\t\tupdated.push(updatedBinding)\n\t\t}\n\n\t\tthis.store.put(updated)\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Update a binding from a partial binding. Each partial must include an ID, which will be used\n\t * to match the binding to it's existing record. If there is no existing record, that binding is\n\t * skipped. The changes from the partial are merged into the existing record.\n\t */\n\tupdateBinding(partial: TLBindingUpdate) {\n\t\treturn this.updateBindings([partial])\n\t}\n\n\t/**\n\t * Delete several bindings by their IDs. If a binding ID doesn't exist, it's ignored.\n\t */\n\tdeleteBindings(bindings: (TLBinding | TLBindingId)[], { isolateShapes = false } = {}) {\n\t\tconst ids = bindings.map((binding) => (typeof binding === 'string' ? binding : binding.id))\n\t\tif (isolateShapes) {\n\t\t\tthis.store.atomic(() => {\n\t\t\t\tfor (const id of ids) {\n\t\t\t\t\tconst binding = this.getBinding(id)\n\t\t\t\t\tif (!binding) continue\n\t\t\t\t\tconst util = this.getBindingUtil(binding)\n\t\t\t\t\tutil.onBeforeIsolateFromShape?.({ binding, removedShape: this.getShape(binding.toId)! })\n\t\t\t\t\tutil.onBeforeIsolateToShape?.({ binding, removedShape: this.getShape(binding.fromId)! })\n\t\t\t\t\tthis.store.remove([id])\n\t\t\t\t}\n\t\t\t})\n\t\t} else {\n\t\t\tthis.store.remove(ids)\n\t\t}\n\t\treturn this\n\t}\n\t/**\n\t * Delete a binding by its ID. If the binding doesn't exist, it's ignored.\n\t */\n\tdeleteBinding(binding: TLBinding | TLBindingId, opts?: Parameters[1]) {\n\t\treturn this.deleteBindings([binding], opts)\n\t}\n\tcanBindShapes({\n\t\tfromShape,\n\t\ttoShape,\n\t\tbinding,\n\t}: {\n\t\tfromShape: TLShape | { type: TLShape['type'] } | TLShape['type']\n\t\ttoShape: TLShape | { type: TLShape['type'] } | TLShape['type']\n\t\tbinding: TLBinding | { type: TLBinding['type'] } | TLBinding['type']\n\t}): boolean {\n\t\tconst fromShapeType = typeof fromShape === 'string' ? fromShape : fromShape.type\n\t\tconst toShapeType = typeof toShape === 'string' ? toShape : toShape.type\n\t\tconst bindingType = typeof binding === 'string' ? binding : binding.type\n\n\t\tconst canBindOpts = { fromShapeType, toShapeType, bindingType }\n\n\t\tif (fromShapeType === toShapeType) {\n\t\t\treturn this.getShapeUtil(fromShapeType).canBind(canBindOpts)\n\t\t}\n\n\t\treturn (\n\t\t\tthis.getShapeUtil(fromShapeType).canBind(canBindOpts) &&\n\t\t\tthis.getShapeUtil(toShapeType).canBind(canBindOpts)\n\t\t)\n\t}\n\n\t/* -------------------- Commands -------------------- */\n\n\t/**\n\t * Rotate shapes by a delta in radians.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.rotateShapesBy(editor.getSelectedShapeIds(), Math.PI)\n\t * editor.rotateShapesBy(editor.getSelectedShapeIds(), Math.PI / 2)\n\t * ```\n\t *\n\t * @param shapes - The shapes (or shape ids) of the shapes to move.\n\t * @param delta - The delta in radians to apply to the selection rotation.\n\t */\n\trotateShapesBy(\n\t\tshapes: TLShapeId[] | TLShape[],\n\t\tdelta: number,\n\t\topts?: { center?: VecLike }\n\t): this {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\n\t\tif (ids.length <= 0) return this\n\n\t\tconst snapshot = getRotationSnapshot({ editor: this, ids })\n\t\tif (!snapshot) return this\n\t\tapplyRotationToSnapshotShapes({\n\t\t\tdelta,\n\t\t\tsnapshot,\n\t\t\teditor: this,\n\t\t\tstage: 'one-off',\n\t\t\tcenterOverride: opts?.center,\n\t\t})\n\n\t\treturn this\n\t}\n\n\tprivate getChangesToTranslateShape(initialShape: TLShape, newShapeCoords: VecLike): TLShape {\n\t\tlet workingShape = initialShape\n\t\tconst util = this.getShapeUtil(initialShape)\n\n\t\tworkingShape = applyPartialToRecordWithProps(\n\t\t\tworkingShape,\n\t\t\tutil.onTranslateStart?.(workingShape) ?? undefined\n\t\t)\n\n\t\tworkingShape = applyPartialToRecordWithProps(workingShape, {\n\t\t\tid: initialShape.id,\n\t\t\ttype: initialShape.type,\n\t\t\tx: newShapeCoords.x,\n\t\t\ty: newShapeCoords.y,\n\t\t})\n\n\t\tworkingShape = applyPartialToRecordWithProps(\n\t\t\tworkingShape,\n\t\t\tutil.onTranslate?.(initialShape, workingShape) ?? undefined\n\t\t)\n\n\t\tworkingShape = applyPartialToRecordWithProps(\n\t\t\tworkingShape,\n\t\t\tutil.onTranslateEnd?.(initialShape, workingShape) ?? undefined\n\t\t)\n\n\t\treturn workingShape\n\t}\n\n\t/**\n\t * Move shapes by a delta.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.nudgeShapes(['box1', 'box2'], { x: 8, y: 8 })\n\t * ```\n\t *\n\t * @param shapes - The shapes (or shape ids) to move.\n\t * @param direction - The direction in which to move the shapes.\n\t * @param historyOptions - The history options for the change.\n\t */\n\tnudgeShapes(shapes: TLShapeId[] | TLShape[], offset: VecLike): this {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\n\t\tif (ids.length <= 0) return this\n\t\tconst changes: TLShapePartial[] = []\n\n\t\tfor (const id of ids) {\n\t\t\tconst shape = this.getShape(id)!\n\t\t\tconst localDelta = Vec.From(offset)\n\t\t\tconst parentTransform = this.getShapeParentTransform(shape)\n\t\t\tif (parentTransform) localDelta.rot(-parentTransform.rotation())\n\n\t\t\tchanges.push(this.getChangesToTranslateShape(shape, localDelta.add(shape)))\n\t\t}\n\n\t\tthis.updateShapes(changes)\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Duplicate shapes.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.duplicateShapes(['box1', 'box2'], { x: 8, y: 8 })\n\t * editor.duplicateShapes(editor.getSelectedShapes(), { x: 8, y: 8 })\n\t * ```\n\t *\n\t * @param shapes - The shapes (or shape ids) to duplicate.\n\t * @param offset - The offset (in pixels) to apply to the duplicated shapes.\n\t *\n\t * @public\n\t */\n\tduplicateShapes(shapes: TLShapeId[] | TLShape[], offset?: VecLike): this {\n\t\tthis.run(() => {\n\t\t\tconst ids =\n\t\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\n\t\t\tif (ids.length <= 0) return this\n\n\t\t\tconst initialIds = new Set(ids)\n\t\t\tconst shapeIdSet = this.getShapeAndDescendantIds(ids)\n\n\t\t\tconst orderedShapeIds = [...shapeIdSet].reverse()\n\t\t\tconst shapeIds = new Map()\n\t\t\tfor (const shapeId of shapeIdSet) {\n\t\t\t\tshapeIds.set(shapeId, createShapeId())\n\t\t\t}\n\n\t\t\tconst { shapesToCreateWithOriginals, bindingsToCreate } = withIsolatedShapes(\n\t\t\t\tthis,\n\t\t\t\tshapeIdSet,\n\t\t\t\t(bindingIdsToMaintain) => {\n\t\t\t\t\tconst bindingsToCreate: TLBinding[] = []\n\t\t\t\t\tfor (const originalId of bindingIdsToMaintain) {\n\t\t\t\t\t\tconst originalBinding = this.getBinding(originalId)\n\t\t\t\t\t\tif (!originalBinding) continue\n\n\t\t\t\t\t\tconst duplicatedId = createBindingId()\n\t\t\t\t\t\tbindingsToCreate.push({\n\t\t\t\t\t\t\t...originalBinding,\n\t\t\t\t\t\t\tid: duplicatedId,\n\t\t\t\t\t\t\tfromId: assertExists(shapeIds.get(originalBinding.fromId)),\n\t\t\t\t\t\t\ttoId: assertExists(shapeIds.get(originalBinding.toId)),\n\t\t\t\t\t\t})\n\t\t\t\t\t}\n\n\t\t\t\t\tconst shapesToCreateWithOriginals: { shape: TLShape; originalShape: TLShape }[] = []\n\t\t\t\t\tfor (const originalId of orderedShapeIds) {\n\t\t\t\t\t\tconst duplicatedId = assertExists(shapeIds.get(originalId))\n\t\t\t\t\t\tconst originalShape = this.getShape(originalId)\n\t\t\t\t\t\tif (!originalShape) continue\n\n\t\t\t\t\t\tlet ox = 0\n\t\t\t\t\t\tlet oy = 0\n\n\t\t\t\t\t\tif (offset && initialIds.has(originalId)) {\n\t\t\t\t\t\t\tconst parentTransform = this.getShapeParentTransform(originalShape)\n\t\t\t\t\t\t\tconst vec = new Vec(offset.x, offset.y).rot(-parentTransform!.rotation())\n\t\t\t\t\t\t\tox = vec.x\n\t\t\t\t\t\t\toy = vec.y\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tshapesToCreateWithOriginals.push({\n\t\t\t\t\t\t\tshape: {\n\t\t\t\t\t\t\t\t...originalShape,\n\t\t\t\t\t\t\t\tid: duplicatedId,\n\t\t\t\t\t\t\t\tx: originalShape.x + ox,\n\t\t\t\t\t\t\t\ty: originalShape.y + oy,\n\t\t\t\t\t\t\t\t// Use a dummy index for now, it will get updated outside of the `withIsolatedShapes`\n\t\t\t\t\t\t\t\tindex: 'a1' as IndexKey,\n\t\t\t\t\t\t\t\tparentId:\n\t\t\t\t\t\t\t\t\tshapeIds.get(originalShape.parentId as TLShapeId) ?? originalShape.parentId,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\toriginalShape,\n\t\t\t\t\t\t})\n\t\t\t\t\t}\n\n\t\t\t\t\treturn { shapesToCreateWithOriginals, bindingsToCreate }\n\t\t\t\t}\n\t\t\t)\n\n\t\t\t// We will update the indexes after the `withIsolatedShapes`, since we cannot rely on the indexes\n\t\t\t// to be correct inside of it.\n\t\t\tshapesToCreateWithOriginals.forEach(({ shape, originalShape }) => {\n\t\t\t\tconst parentId = originalShape.parentId\n\t\t\t\tconst siblings = this.getSortedChildIdsForParent(parentId)\n\t\t\t\tconst currentIndex = siblings.indexOf(originalShape.id)\n\t\t\t\tconst siblingAboveId = siblings[currentIndex + 1]\n\t\t\t\tconst siblingAbove = siblingAboveId ? this.getShape(siblingAboveId) : undefined\n\n\t\t\t\tconst index = getIndexBetween(originalShape.index, siblingAbove?.index)\n\n\t\t\t\tshape.index = index\n\t\t\t})\n\t\t\tconst shapesToCreate = shapesToCreateWithOriginals.map(({ shape }) => shape)\n\n\t\t\tconst maxShapesReached =\n\t\t\t\tshapesToCreate.length + this.getCurrentPageShapeIds().size > this.options.maxShapesPerPage\n\n\t\t\tif (maxShapesReached) {\n\t\t\t\talertMaxShapes(this)\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tthis.createShapes(shapesToCreate)\n\t\t\tthis.createBindings(bindingsToCreate)\n\t\t\tthis.setSelectedShapes(compact(ids.map((id) => shapeIds.get(id))))\n\n\t\t\tif (offset !== undefined) {\n\t\t\t\t// If we've offset the duplicated shapes, check to see whether their new bounds is entirely\n\t\t\t\t// contained in the current viewport. If not, then animate the camera to be centered on the\n\t\t\t\t// new shapes.\n\t\t\t\tconst selectionPageBounds = this.getSelectionPageBounds()\n\t\t\t\tconst viewportPageBounds = this.getViewportPageBounds()\n\t\t\t\tif (selectionPageBounds && !viewportPageBounds.contains(selectionPageBounds)) {\n\t\t\t\t\tthis.centerOnPoint(selectionPageBounds.center, {\n\t\t\t\t\t\tanimation: { duration: this.options.animationMediumMs },\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t}\n\t\t})\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Move shapes to page.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.moveShapesToPage(['box1', 'box2'], 'page1')\n\t * ```\n\t *\n\t * @param shapes - The shapes (or shape ids) of the shapes to move.\n\t * @param pageId - The id of the page where the shapes will be moved.\n\t *\n\t * @public\n\t */\n\tmoveShapesToPage(shapes: TLShapeId[] | TLShape[], pageId: TLPageId): this {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\n\t\tif (ids.length === 0) return this\n\t\tif (this.getInstanceState().isReadonly) return this\n\n\t\tconst currentPageId = this.getCurrentPageId()\n\n\t\tif (pageId === currentPageId) return this\n\t\tif (!this.store.has(pageId)) return this\n\n\t\t// Basically copy the shapes\n\t\tconst content = this.getContentFromCurrentPage(ids)\n\n\t\t// Just to be sure\n\t\tif (!content) return this\n\n\t\t// If there is no space on pageId, or if the selected shapes\n\t\t// would take the new page above the limit, don't move the shapes\n\t\tif (this.getPageShapeIds(pageId).size + content.shapes.length > this.options.maxShapesPerPage) {\n\t\t\talertMaxShapes(this, pageId)\n\t\t\treturn this\n\t\t}\n\n\t\tconst fromPageZ = this.getCamera().z\n\n\t\tthis.run(() => {\n\t\t\t// Delete the shapes on the current page\n\t\t\tthis.deleteShapes(ids)\n\n\t\t\t// Move to the next page\n\t\t\tthis.setCurrentPage(pageId)\n\n\t\t\t// Put the shape content onto the new page; parents and indices will\n\t\t\t// be taken care of by the putContent method; make sure to pop any focus\n\t\t\t// layers so that the content will be put onto the page.\n\t\t\tthis.setFocusedGroup(null)\n\t\t\tthis.selectNone()\n\t\t\tthis.putContentOntoCurrentPage(content, {\n\t\t\t\tselect: true,\n\t\t\t\tpreserveIds: true,\n\t\t\t\tpreservePosition: true,\n\t\t\t})\n\n\t\t\t// Force the new page's camera to be at the same zoom level as the\n\t\t\t// \"from\" page's camera, then center the \"to\" page's camera on the\n\t\t\t// pasted shapes\n\t\t\tthis.setCamera({ ...this.getCamera(), z: fromPageZ })\n\t\t\tthis.centerOnPoint(this.getSelectionRotatedPageBounds()!.center)\n\t\t})\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Toggle the lock state of one or more shapes. If there is a mix of locked and unlocked shapes, all shapes will be locked.\n\t *\n\t * @param shapes - The shapes (or shape ids) to toggle.\n\t *\n\t * @public\n\t */\n\ttoggleLock(shapes: TLShapeId[] | TLShape[]): this {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\n\t\tif (this.getInstanceState().isReadonly || ids.length === 0) return this\n\n\t\tlet allLocked = true,\n\t\t\tallUnlocked = true\n\t\tconst shapesToToggle: TLShape[] = []\n\t\tfor (const id of ids) {\n\t\t\tconst shape = this.getShape(id)\n\t\t\tif (shape) {\n\t\t\t\tshapesToToggle.push(shape)\n\t\t\t\tif (shape.isLocked) {\n\t\t\t\t\tallUnlocked = false\n\t\t\t\t} else {\n\t\t\t\t\tallLocked = false\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tthis.run(() => {\n\t\t\tif (allUnlocked) {\n\t\t\t\tthis.updateShapes(\n\t\t\t\t\tshapesToToggle.map((shape) => ({ id: shape.id, type: shape.type, isLocked: true }))\n\t\t\t\t)\n\t\t\t\tthis.setSelectedShapes([])\n\t\t\t} else if (allLocked) {\n\t\t\t\tthis.updateShapes(\n\t\t\t\t\tshapesToToggle.map((shape) => ({ id: shape.id, type: shape.type, isLocked: false }))\n\t\t\t\t)\n\t\t\t} else {\n\t\t\t\tthis.updateShapes(\n\t\t\t\t\tshapesToToggle.map((shape) => ({ id: shape.id, type: shape.type, isLocked: true }))\n\t\t\t\t)\n\t\t\t}\n\t\t})\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Send shapes to the back of the page's object list.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.sendToBack(['id1', 'id2'])\n\t * editor.sendToBack(box1, box2)\n\t * ```\n\t *\n\t * @param shapes - The shapes (or shape ids) to move.\n\t *\n\t * @public\n\t */\n\tsendToBack(shapes: TLShapeId[] | TLShape[]): this {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\t\tconst changes = getReorderingShapesChanges(this, 'toBack', ids as TLShapeId[])\n\t\tif (changes) this.updateShapes(changes)\n\t\treturn this\n\t}\n\n\t/**\n\t * Send shapes backward in the page's object list.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.sendBackward(['id1', 'id2'])\n\t * editor.sendBackward([box1, box2])\n\t * ```\n\t *\n\t * @param shapes - The shapes (or shape ids) to move.\n\t *\n\t * @public\n\t */\n\tsendBackward(shapes: TLShapeId[] | TLShape[]): this {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\t\tconst changes = getReorderingShapesChanges(this, 'backward', ids as TLShapeId[])\n\t\tif (changes) this.updateShapes(changes)\n\t\treturn this\n\t}\n\n\t/**\n\t * Bring shapes forward in the page's object list.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.bringForward(['id1', 'id2'])\n\t * editor.bringForward(box1, box2)\n\t * ```\n\t *\n\t * @param shapes - The shapes (or shape ids) to move.\n\t *\n\t * @public\n\t */\n\tbringForward(shapes: TLShapeId[] | TLShape[]): this {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\t\tconst changes = getReorderingShapesChanges(this, 'forward', ids as TLShapeId[])\n\t\tif (changes) this.updateShapes(changes)\n\t\treturn this\n\t}\n\n\t/**\n\t * Bring shapes to the front of the page's object list.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.bringToFront(['id1', 'id2'])\n\t * editor.bringToFront([box1, box2])\n\t * ```\n\t *\n\t * @param shapes - The shapes (or shape ids) to move.\n\t *\n\t * @public\n\t */\n\tbringToFront(shapes: TLShapeId[] | TLShape[]): this {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\t\tconst changes = getReorderingShapesChanges(this, 'toFront', ids as TLShapeId[])\n\t\tif (changes) this.updateShapes(changes)\n\t\treturn this\n\t}\n\n\t/**\n\t * Flip shape positions.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.flipShapes([box1, box2], 'horizontal', 32)\n\t * editor.flipShapes(editor.getSelectedShapeIds(), 'horizontal', 32)\n\t * ```\n\t *\n\t * @param shapes - The ids of the shapes to flip.\n\t * @param operation - Whether to flip horizontally or vertically.\n\t *\n\t * @public\n\t */\n\tflipShapes(shapes: TLShapeId[] | TLShape[], operation: 'horizontal' | 'vertical'): this {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\n\t\tif (this.getInstanceState().isReadonly) return this\n\n\t\tlet shapesToFlip = compact(ids.map((id) => this.getShape(id)))\n\n\t\tif (!shapesToFlip.length) return this\n\n\t\tshapesToFlip = compact(\n\t\t\tshapesToFlip\n\t\t\t\t.map((shape) => {\n\t\t\t\t\tif (this.isShapeOfType(shape, 'group')) {\n\t\t\t\t\t\treturn this.getSortedChildIdsForParent(shape.id).map((id) => this.getShape(id))\n\t\t\t\t\t}\n\n\t\t\t\t\treturn shape\n\t\t\t\t})\n\t\t\t\t.flat()\n\t\t)\n\n\t\tconst scaleOriginPage = Box.Common(\n\t\t\tcompact(shapesToFlip.map((id) => this.getShapePageBounds(id)))\n\t\t).center\n\n\t\tthis.run(() => {\n\t\t\tfor (const shape of shapesToFlip) {\n\t\t\t\tconst bounds = this.getShapeGeometry(shape).bounds\n\t\t\t\tconst initialPageTransform = this.getShapePageTransform(shape.id)\n\t\t\t\tif (!initialPageTransform) continue\n\t\t\t\tthis.resizeShape(\n\t\t\t\t\tshape.id,\n\t\t\t\t\t{ x: operation === 'horizontal' ? -1 : 1, y: operation === 'vertical' ? -1 : 1 },\n\t\t\t\t\t{\n\t\t\t\t\t\tinitialBounds: bounds,\n\t\t\t\t\t\tinitialPageTransform,\n\t\t\t\t\t\tinitialShape: shape,\n\t\t\t\t\t\tmode: 'scale_shape',\n\t\t\t\t\t\tisAspectRatioLocked: this.getShapeUtil(shape).isAspectRatioLocked(shape),\n\t\t\t\t\t\tscaleOrigin: scaleOriginPage,\n\t\t\t\t\t\tscaleAxisRotation: 0,\n\t\t\t\t\t}\n\t\t\t\t)\n\t\t\t}\n\t\t})\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Stack shape.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.stackShapes([box1, box2], 'horizontal', 32)\n\t * editor.stackShapes(editor.getSelectedShapeIds(), 'horizontal', 32)\n\t * ```\n\t *\n\t * @param shapes - The shapes (or shape ids) to stack.\n\t * @param operation - Whether to stack horizontally or vertically.\n\t * @param gap - The gap to leave between shapes.\n\t *\n\t * @public\n\t */\n\tstackShapes(\n\t\tshapes: TLShapeId[] | TLShape[],\n\t\toperation: 'horizontal' | 'vertical',\n\t\tgap: number\n\t): this {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\t\tif (this.getInstanceState().isReadonly) return this\n\n\t\tconst shapesToStack = ids\n\t\t\t.map((id) => this.getShape(id)) // always fresh shapes\n\t\t\t.filter((shape): shape is TLShape => {\n\t\t\t\tif (!shape) return false\n\n\t\t\t\treturn this.getShapeUtil(shape).canBeLaidOut(shape)\n\t\t\t})\n\n\t\tconst len = shapesToStack.length\n\n\t\tif ((gap === 0 && len < 3) || len < 2) return this\n\n\t\tconst pageBounds = Object.fromEntries(\n\t\t\tshapesToStack.map((shape) => [shape.id, this.getShapePageBounds(shape)!])\n\t\t)\n\n\t\tlet val: 'x' | 'y'\n\t\tlet min: 'minX' | 'minY'\n\t\tlet max: 'maxX' | 'maxY'\n\t\tlet dim: 'width' | 'height'\n\n\t\tif (operation === 'horizontal') {\n\t\t\tval = 'x'\n\t\t\tmin = 'minX'\n\t\t\tmax = 'maxX'\n\t\t\tdim = 'width'\n\t\t} else {\n\t\t\tval = 'y'\n\t\t\tmin = 'minY'\n\t\t\tmax = 'maxY'\n\t\t\tdim = 'height'\n\t\t}\n\n\t\tlet shapeGap: number\n\n\t\tif (gap === 0) {\n\t\t\tconst gaps: { gap: number; count: number }[] = []\n\n\t\t\tshapesToStack.sort((a, b) => pageBounds[a.id][min] - pageBounds[b.id][min])\n\n\t\t\t// Collect all of the gaps between shapes. We want to find\n\t\t\t// patterns (equal gaps between shapes) and use the most common\n\t\t\t// one as the gap for all of the shapes.\n\t\t\tfor (let i = 0; i < len - 1; i++) {\n\t\t\t\tconst shape = shapesToStack[i]\n\t\t\t\tconst nextShape = shapesToStack[i + 1]\n\n\t\t\t\tconst bounds = pageBounds[shape.id]\n\t\t\t\tconst nextBounds = pageBounds[nextShape.id]\n\n\t\t\t\tconst gap = nextBounds[min] - bounds[max]\n\n\t\t\t\tconst current = gaps.find((g) => g.gap === gap)\n\n\t\t\t\tif (current) {\n\t\t\t\t\tcurrent.count++\n\t\t\t\t} else {\n\t\t\t\t\tgaps.push({ gap, count: 1 })\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Which gap is the most common?\n\t\t\tlet maxCount = 0\n\t\t\tgaps.forEach((g) => {\n\t\t\t\tif (g.count > maxCount) {\n\t\t\t\t\tmaxCount = g.count\n\t\t\t\t\tshapeGap = g.gap\n\t\t\t\t}\n\t\t\t})\n\n\t\t\t// If there is no most-common gap, use the average gap.\n\t\t\tif (maxCount === 1) {\n\t\t\t\tshapeGap = Math.max(0, gaps.reduce((a, c) => a + c.gap * c.count, 0) / (len - 1))\n\t\t\t}\n\t\t} else {\n\t\t\t// If a gap was provided, then use that instead.\n\t\t\tshapeGap = gap\n\t\t}\n\n\t\tconst changes: TLShapePartial[] = []\n\n\t\tlet v = pageBounds[shapesToStack[0].id][max]\n\n\t\tshapesToStack.forEach((shape, i) => {\n\t\t\tif (i === 0) return\n\n\t\t\tconst delta = { x: 0, y: 0 }\n\t\t\tdelta[val] = v + shapeGap - pageBounds[shape.id][val]\n\n\t\t\tconst parent = this.getShapeParent(shape)\n\t\t\tconst localDelta = parent\n\t\t\t\t? Vec.Rot(delta, -this.getShapePageTransform(parent)!.decompose().rotation)\n\t\t\t\t: delta\n\n\t\t\tconst translateStartChanges = this.getShapeUtil(shape).onTranslateStart?.(shape)\n\n\t\t\tchanges.push(\n\t\t\t\ttranslateStartChanges\n\t\t\t\t\t? {\n\t\t\t\t\t\t\t...translateStartChanges,\n\t\t\t\t\t\t\t[val]: shape[val] + localDelta[val],\n\t\t\t\t\t\t}\n\t\t\t\t\t: {\n\t\t\t\t\t\t\tid: shape.id as any,\n\t\t\t\t\t\t\ttype: shape.type,\n\t\t\t\t\t\t\t[val]: shape[val] + localDelta[val],\n\t\t\t\t\t\t}\n\t\t\t)\n\n\t\t\tv += pageBounds[shape.id][dim] + shapeGap\n\t\t})\n\n\t\tthis.updateShapes(changes)\n\t\treturn this\n\t}\n\n\t/**\n\t * Pack shapes into a grid centered on their current position. Based on potpack (https://github.com/mapbox/potpack).\n\t *\n\t * @example\n\t * ```ts\n\t * editor.packShapes([box1, box2], 32)\n\t * editor.packShapes(editor.getSelectedShapeIds(), 32)\n\t * ```\n\t *\n\t *\n\t * @param shapes - The shapes (or shape ids) to pack.\n\t * @param gap - The padding to apply to the packed shapes. Defaults to 16.\n\t */\n\tpackShapes(shapes: TLShapeId[] | TLShape[], gap: number): this {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\n\t\tif (this.getInstanceState().isReadonly) return this\n\t\tif (ids.length < 2) return this\n\n\t\tconst shapesToPack = ids\n\t\t\t.map((id) => this.getShape(id)) // always fresh shapes\n\t\t\t.filter((shape): shape is TLShape => {\n\t\t\t\tif (!shape) return false\n\n\t\t\t\treturn this.getShapeUtil(shape).canBeLaidOut(shape)\n\t\t\t})\n\t\tconst shapePageBounds: Record = {}\n\t\tconst nextShapePageBounds: Record = {}\n\n\t\tlet shape: TLShape,\n\t\t\tbounds: Box,\n\t\t\tarea = 0\n\n\t\tfor (let i = 0; i < shapesToPack.length; i++) {\n\t\t\tshape = shapesToPack[i]\n\t\t\tbounds = this.getShapePageBounds(shape)!\n\t\t\tshapePageBounds[shape.id] = bounds\n\t\t\tnextShapePageBounds[shape.id] = bounds.clone()\n\t\t\tarea += bounds.width * bounds.height\n\t\t}\n\n\t\tconst commonBounds = Box.Common(compact(Object.values(shapePageBounds)))\n\n\t\tconst maxWidth = commonBounds.width\n\n\t\t// sort the shapes by height, descending\n\t\tshapesToPack.sort((a, b) => shapePageBounds[b.id].height - shapePageBounds[a.id].height)\n\n\t\t// Start with is (sort of) the square of the area\n\t\tconst startWidth = Math.max(Math.ceil(Math.sqrt(area / 0.95)), maxWidth)\n\n\t\t// first shape fills the width and is infinitely tall\n\t\tconst spaces: Box[] = [new Box(commonBounds.x, commonBounds.y, startWidth, Infinity)]\n\n\t\tlet width = 0\n\t\tlet height = 0\n\t\tlet space: Box\n\t\tlet last: Box\n\n\t\tfor (let i = 0; i < shapesToPack.length; i++) {\n\t\t\tshape = shapesToPack[i]\n\t\t\tbounds = nextShapePageBounds[shape.id]\n\n\t\t\t// starting at the back (smaller shapes)\n\t\t\tfor (let i = spaces.length - 1; i >= 0; i--) {\n\t\t\t\tspace = spaces[i]\n\n\t\t\t\t// find a space that is big enough to contain the shape\n\t\t\t\tif (bounds.width > space.width || bounds.height > space.height) continue\n\n\t\t\t\t// add the shape to its top-left corner\n\t\t\t\tbounds.x = space.x\n\t\t\t\tbounds.y = space.y\n\n\t\t\t\theight = Math.max(height, bounds.maxY)\n\t\t\t\twidth = Math.max(width, bounds.maxX)\n\n\t\t\t\tif (bounds.width === space.width && bounds.height === space.height) {\n\t\t\t\t\t// remove the space on a perfect fit\n\t\t\t\t\tlast = spaces.pop()!\n\t\t\t\t\tif (i < spaces.length) spaces[i] = last\n\t\t\t\t} else if (bounds.height === space.height) {\n\t\t\t\t\t// fit the shape into the space (width)\n\t\t\t\t\tspace.x += bounds.width + gap\n\t\t\t\t\tspace.width -= bounds.width + gap\n\t\t\t\t} else if (bounds.width === space.width) {\n\t\t\t\t\t// fit the shape into the space (height)\n\t\t\t\t\tspace.y += bounds.height + gap\n\t\t\t\t\tspace.height -= bounds.height + gap\n\t\t\t\t} else {\n\t\t\t\t\t// split the space into two spaces\n\t\t\t\t\tspaces.push(\n\t\t\t\t\t\tnew Box(\n\t\t\t\t\t\t\tspace.x + (bounds.width + gap),\n\t\t\t\t\t\t\tspace.y,\n\t\t\t\t\t\t\tspace.width - (bounds.width + gap),\n\t\t\t\t\t\t\tbounds.height\n\t\t\t\t\t\t)\n\t\t\t\t\t)\n\t\t\t\t\tspace.y += bounds.height + gap\n\t\t\t\t\tspace.height -= bounds.height + gap\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\n\t\tconst commonAfter = Box.Common(Object.values(nextShapePageBounds))\n\t\tconst centerDelta = Vec.Sub(commonBounds.center, commonAfter.center)\n\n\t\tlet nextBounds: Box\n\n\t\tconst changes: TLShapePartial[] = []\n\n\t\tfor (let i = 0; i < shapesToPack.length; i++) {\n\t\t\tshape = shapesToPack[i]\n\t\t\tbounds = shapePageBounds[shape.id]\n\t\t\tnextBounds = nextShapePageBounds[shape.id]\n\n\t\t\tconst delta = Vec.Sub(nextBounds.point, bounds.point).add(centerDelta)\n\t\t\tconst parentTransform = this.getShapeParentTransform(shape)\n\t\t\tif (parentTransform) delta.rot(-parentTransform.rotation())\n\n\t\t\tconst change: TLShapePartial = {\n\t\t\t\tid: shape.id,\n\t\t\t\ttype: shape.type,\n\t\t\t\tx: shape.x + delta.x,\n\t\t\t\ty: shape.y + delta.y,\n\t\t\t}\n\n\t\t\tconst translateStartChange = this.getShapeUtil(shape).onTranslateStart?.({\n\t\t\t\t...shape,\n\t\t\t\t...change,\n\t\t\t})\n\n\t\t\tif (translateStartChange) {\n\t\t\t\tchanges.push({ ...change, ...translateStartChange })\n\t\t\t} else {\n\t\t\t\tchanges.push(change)\n\t\t\t}\n\t\t}\n\n\t\tif (changes.length) {\n\t\t\tthis.updateShapes(changes)\n\t\t}\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Align shape positions.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.alignShapes([box1, box2], 'left')\n\t * editor.alignShapes(editor.getSelectedShapeIds(), 'left')\n\t * ```\n\t *\n\t * @param shapes - The shapes (or shape ids) to align.\n\t * @param operation - The align operation to apply.\n\t *\n\t * @public\n\t */\n\n\talignShapes(\n\t\tshapes: TLShapeId[] | TLShape[],\n\t\toperation: 'left' | 'center-horizontal' | 'right' | 'top' | 'center-vertical' | 'bottom'\n\t): this {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\n\t\tif (this.getInstanceState().isReadonly) return this\n\t\tif (ids.length < 2) return this\n\n\t\tconst shapesToAlign = compact(ids.map((id) => this.getShape(id))) // always fresh shapes\n\t\tconst shapePageBounds = Object.fromEntries(\n\t\t\tshapesToAlign.map((shape) => [shape.id, this.getShapePageBounds(shape)])\n\t\t)\n\t\tconst commonBounds = Box.Common(compact(Object.values(shapePageBounds)))\n\n\t\tconst changes: TLShapePartial[] = []\n\n\t\tshapesToAlign.forEach((shape) => {\n\t\t\tconst pageBounds = shapePageBounds[shape.id]\n\t\t\tif (!pageBounds) return\n\n\t\t\tconst delta = { x: 0, y: 0 }\n\n\t\t\tswitch (operation) {\n\t\t\t\tcase 'top': {\n\t\t\t\t\tdelta.y = commonBounds.minY - pageBounds.minY\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase 'center-vertical': {\n\t\t\t\t\tdelta.y = commonBounds.midY - pageBounds.minY - pageBounds.height / 2\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase 'bottom': {\n\t\t\t\t\tdelta.y = commonBounds.maxY - pageBounds.minY - pageBounds.height\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase 'left': {\n\t\t\t\t\tdelta.x = commonBounds.minX - pageBounds.minX\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase 'center-horizontal': {\n\t\t\t\t\tdelta.x = commonBounds.midX - pageBounds.minX - pageBounds.width / 2\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase 'right': {\n\t\t\t\t\tdelta.x = commonBounds.maxX - pageBounds.minX - pageBounds.width\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst parent = this.getShapeParent(shape)\n\t\t\tconst localDelta = parent\n\t\t\t\t? Vec.Rot(delta, -this.getShapePageTransform(parent)!.decompose().rotation)\n\t\t\t\t: delta\n\n\t\t\tchanges.push(this.getChangesToTranslateShape(shape, Vec.Add(shape, localDelta)))\n\t\t})\n\n\t\tthis.updateShapes(changes)\n\t\treturn this\n\t}\n\n\t/**\n\t * Distribute shape positions.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.distributeShapes([box1, box2], 'horizontal')\n\t * editor.distributeShapes(editor.getSelectedShapeIds(), 'horizontal')\n\t * ```\n\t *\n\t * @param shapes - The shapes (or shape ids) to distribute.\n\t * @param operation - Whether to distribute shapes horizontally or vertically.\n\t *\n\t * @public\n\t */\n\tdistributeShapes(shapes: TLShapeId[] | TLShape[], operation: 'horizontal' | 'vertical'): this {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\n\t\tif (this.getInstanceState().isReadonly) return this\n\t\tif (ids.length < 3) return this\n\n\t\tconst len = ids.length\n\t\tconst shapesToDistribute = compact(ids.map((id) => this.getShape(id))) // always fresh shapes\n\t\tconst pageBounds = Object.fromEntries(\n\t\t\tshapesToDistribute.map((shape) => [shape.id, this.getShapePageBounds(shape)!])\n\t\t)\n\n\t\tlet val: 'x' | 'y'\n\t\tlet min: 'minX' | 'minY'\n\t\tlet max: 'maxX' | 'maxY'\n\t\tlet mid: 'midX' | 'midY'\n\t\tlet dim: 'width' | 'height'\n\n\t\tif (operation === 'horizontal') {\n\t\t\tval = 'x'\n\t\t\tmin = 'minX'\n\t\t\tmax = 'maxX'\n\t\t\tmid = 'midX'\n\t\t\tdim = 'width'\n\t\t} else {\n\t\t\tval = 'y'\n\t\t\tmin = 'minY'\n\t\t\tmax = 'maxY'\n\t\t\tmid = 'midY'\n\t\t\tdim = 'height'\n\t\t}\n\t\tconst changes: TLShapePartial[] = []\n\n\t\t// Clustered\n\t\tconst first = shapesToDistribute.sort(\n\t\t\t(a, b) => pageBounds[a.id][min] - pageBounds[b.id][min]\n\t\t)[0]\n\t\tconst last = shapesToDistribute.sort((a, b) => pageBounds[b.id][max] - pageBounds[a.id][max])[0]\n\n\t\tconst midFirst = pageBounds[first.id][mid]\n\t\tconst step = (pageBounds[last.id][mid] - midFirst) / (len - 1)\n\t\tconst v = midFirst + step\n\n\t\tshapesToDistribute\n\t\t\t.filter((shape) => shape !== first && shape !== last)\n\t\t\t.sort((a, b) => pageBounds[a.id][mid] - pageBounds[b.id][mid])\n\t\t\t.forEach((shape, i) => {\n\t\t\t\tconst delta = { x: 0, y: 0 }\n\t\t\t\tdelta[val] = v + step * i - pageBounds[shape.id][dim] / 2 - pageBounds[shape.id][val]\n\n\t\t\t\tconst parent = this.getShapeParent(shape)\n\t\t\t\tconst localDelta = parent\n\t\t\t\t\t? Vec.Rot(delta, -this.getShapePageTransform(parent)!.rotation())\n\t\t\t\t\t: delta\n\n\t\t\t\tchanges.push(this.getChangesToTranslateShape(shape, Vec.Add(shape, localDelta)))\n\t\t\t})\n\n\t\tthis.updateShapes(changes)\n\t\treturn this\n\t}\n\n\t/**\n\t * Stretch shape sizes and positions to fill their common bounding box.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.stretchShapes([box1, box2], 'horizontal')\n\t * editor.stretchShapes(editor.getSelectedShapeIds(), 'horizontal')\n\t * ```\n\t *\n\t * @param shapes - The shapes (or shape ids) to stretch.\n\t * @param operation - Whether to stretch shapes horizontally or vertically.\n\t *\n\t * @public\n\t */\n\tstretchShapes(shapes: TLShapeId[] | TLShape[], operation: 'horizontal' | 'vertical'): this {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\n\t\tif (this.getInstanceState().isReadonly) return this\n\t\tif (ids.length < 2) return this\n\n\t\tconst shapesToStretch = compact(ids.map((id) => this.getShape(id))) // always fresh shapes\n\t\tconst shapeBounds = Object.fromEntries(ids.map((id) => [id, this.getShapeGeometry(id).bounds]))\n\t\tconst shapePageBounds = Object.fromEntries(ids.map((id) => [id, this.getShapePageBounds(id)!]))\n\t\tconst commonBounds = Box.Common(compact(Object.values(shapePageBounds)))\n\n\t\tswitch (operation) {\n\t\t\tcase 'vertical': {\n\t\t\t\tthis.run(() => {\n\t\t\t\t\tfor (const shape of shapesToStretch) {\n\t\t\t\t\t\tconst pageRotation = this.getShapePageTransform(shape)!.rotation()\n\t\t\t\t\t\tif (pageRotation % PI2) continue\n\t\t\t\t\t\tconst bounds = shapeBounds[shape.id]\n\t\t\t\t\t\tconst pageBounds = shapePageBounds[shape.id]\n\t\t\t\t\t\tconst localOffset = new Vec(0, commonBounds.minY - pageBounds.minY)\n\t\t\t\t\t\tconst parentTransform = this.getShapeParentTransform(shape)\n\t\t\t\t\t\tif (parentTransform) localOffset.rot(-parentTransform.rotation())\n\n\t\t\t\t\t\tconst { x, y } = Vec.Add(localOffset, shape)\n\t\t\t\t\t\tthis.updateShapes([{ id: shape.id, type: shape.type, x, y }])\n\t\t\t\t\t\tconst scale = new Vec(1, commonBounds.height / pageBounds.height)\n\t\t\t\t\t\tthis.resizeShape(shape.id, scale, {\n\t\t\t\t\t\t\tinitialBounds: bounds,\n\t\t\t\t\t\t\tscaleOrigin: new Vec(pageBounds.center.x, commonBounds.minY),\n\t\t\t\t\t\t\tisAspectRatioLocked: this.getShapeUtil(shape).isAspectRatioLocked(shape),\n\t\t\t\t\t\t\tscaleAxisRotation: 0,\n\t\t\t\t\t\t})\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'horizontal': {\n\t\t\t\tthis.run(() => {\n\t\t\t\t\tfor (const shape of shapesToStretch) {\n\t\t\t\t\t\tconst bounds = shapeBounds[shape.id]\n\t\t\t\t\t\tconst pageBounds = shapePageBounds[shape.id]\n\t\t\t\t\t\tconst pageRotation = this.getShapePageTransform(shape)!.rotation()\n\t\t\t\t\t\tif (pageRotation % PI2) continue\n\t\t\t\t\t\tconst localOffset = new Vec(commonBounds.minX - pageBounds.minX, 0)\n\t\t\t\t\t\tconst parentTransform = this.getShapeParentTransform(shape)\n\t\t\t\t\t\tif (parentTransform) localOffset.rot(-parentTransform.rotation())\n\n\t\t\t\t\t\tconst { x, y } = Vec.Add(localOffset, shape)\n\t\t\t\t\t\tthis.updateShapes([{ id: shape.id, type: shape.type, x, y }])\n\t\t\t\t\t\tconst scale = new Vec(commonBounds.width / pageBounds.width, 1)\n\t\t\t\t\t\tthis.resizeShape(shape.id, scale, {\n\t\t\t\t\t\t\tinitialBounds: bounds,\n\t\t\t\t\t\t\tscaleOrigin: new Vec(commonBounds.minX, pageBounds.center.y),\n\t\t\t\t\t\t\tisAspectRatioLocked: this.getShapeUtil(shape).isAspectRatioLocked(shape),\n\t\t\t\t\t\t\tscaleAxisRotation: 0,\n\t\t\t\t\t\t})\n\t\t\t\t\t}\n\t\t\t\t})\n\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Resize a shape.\n\t *\n\t * @param id - The id of the shape to resize.\n\t * @param scale - The scale factor to apply to the shape.\n\t * @param options - Additional options.\n\t *\n\t * @public\n\t */\n\tresizeShape(\n\t\tshape: TLShapeId | TLShape,\n\t\tscale: VecLike,\n\t\toptions: TLResizeShapeOptions = {}\n\t): this {\n\t\tconst id = typeof shape === 'string' ? shape : shape.id\n\t\tif (this.getInstanceState().isReadonly) return this\n\n\t\tif (!Number.isFinite(scale.x)) scale = new Vec(1, scale.y)\n\t\tif (!Number.isFinite(scale.y)) scale = new Vec(scale.x, 1)\n\n\t\tconst initialShape = options.initialShape ?? this.getShape(id)\n\t\tif (!initialShape) return this\n\n\t\tconst scaleOrigin = options.scaleOrigin ?? this.getShapePageBounds(id)?.center\n\t\tif (!scaleOrigin) return this\n\n\t\tconst pageTransform = options.initialPageTransform\n\t\t\t? Mat.Cast(options.initialPageTransform)\n\t\t\t: this.getShapePageTransform(id)\n\t\tif (!pageTransform) return this\n\n\t\tconst pageRotation = pageTransform.rotation()\n\n\t\tif (pageRotation == null) return this\n\n\t\tconst scaleAxisRotation = options.scaleAxisRotation ?? pageRotation\n\n\t\tconst initialBounds = options.initialBounds ?? this.getShapeGeometry(id).bounds\n\n\t\tif (!initialBounds) return this\n\n\t\tconst isAspectRatioLocked =\n\t\t\toptions.isAspectRatioLocked ??\n\t\t\tthis.getShapeUtil(initialShape).isAspectRatioLocked(initialShape)\n\n\t\tif (!areAnglesCompatible(pageRotation, scaleAxisRotation)) {\n\t\t\t// shape is awkwardly rotated, keep the aspect ratio locked and adopt the scale factor\n\t\t\t// from whichever axis is being scaled the least, to avoid the shape getting bigger\n\t\t\t// than the bounds of the selection\n\t\t\t// const minScale = Math.min(Math.abs(scale.x), Math.abs(scale.y))\n\t\t\treturn this._resizeUnalignedShape(id, scale, {\n\t\t\t\t...options,\n\t\t\t\tinitialBounds,\n\t\t\t\tscaleOrigin,\n\t\t\t\tscaleAxisRotation,\n\t\t\t\tinitialPageTransform: pageTransform,\n\t\t\t\tisAspectRatioLocked,\n\t\t\t\tinitialShape,\n\t\t\t})\n\t\t}\n\n\t\tconst util = this.getShapeUtil(initialShape)\n\n\t\tif (isAspectRatioLocked) {\n\t\t\tif (Math.abs(scale.x) > Math.abs(scale.y)) {\n\t\t\t\tscale = new Vec(scale.x, Math.sign(scale.y) * Math.abs(scale.x))\n\t\t\t} else {\n\t\t\t\tscale = new Vec(Math.sign(scale.x) * Math.abs(scale.y), scale.y)\n\t\t\t}\n\t\t}\n\n\t\tif (util.onResize && util.canResize(initialShape)) {\n\t\t\t// get the model changes from the shape util\n\t\t\tconst newPagePoint = this._scalePagePoint(\n\t\t\t\tMat.applyToPoint(pageTransform, new Vec(0, 0)),\n\t\t\t\tscaleOrigin,\n\t\t\t\tscale,\n\t\t\t\tscaleAxisRotation\n\t\t\t)\n\n\t\t\tconst newLocalPoint = this.getPointInParentSpace(initialShape.id, newPagePoint)\n\n\t\t\t// resize the shape's local bounding box\n\t\t\tconst myScale = new Vec(scale.x, scale.y)\n\t\t\t// the shape is aligned with the rest of the shapes in the selection, but may be\n\t\t\t// 90deg offset from the main rotation of the selection, in which case\n\t\t\t// we need to flip the width and height scale factors\n\t\t\tconst areWidthAndHeightAlignedWithCorrectAxis = approximately(\n\t\t\t\t(pageRotation - scaleAxisRotation) % Math.PI,\n\t\t\t\t0\n\t\t\t)\n\t\t\tmyScale.x = areWidthAndHeightAlignedWithCorrectAxis ? scale.x : scale.y\n\t\t\tmyScale.y = areWidthAndHeightAlignedWithCorrectAxis ? scale.y : scale.x\n\n\t\t\t// adjust initial model for situations where the parent has moved during the resize\n\t\t\t// e.g. groups\n\t\t\tconst initialPagePoint = Mat.applyToPoint(pageTransform, new Vec())\n\n\t\t\t// need to adjust the shape's x and y points in case the parent has moved since start of resizing\n\t\t\tconst { x, y } = this.getPointInParentSpace(initialShape.id, initialPagePoint)\n\n\t\t\tlet workingShape = initialShape\n\t\t\tif (!options.skipStartAndEndCallbacks) {\n\t\t\t\tworkingShape = applyPartialToRecordWithProps(\n\t\t\t\t\tinitialShape,\n\t\t\t\t\tutil.onResizeStart?.(initialShape) ?? undefined\n\t\t\t\t)\n\t\t\t}\n\n\t\t\tworkingShape = applyPartialToRecordWithProps(workingShape, {\n\t\t\t\tid,\n\t\t\t\ttype: initialShape.type as any,\n\t\t\t\tx: newLocalPoint.x,\n\t\t\t\ty: newLocalPoint.y,\n\t\t\t\t...util.onResize(\n\t\t\t\t\t{ ...initialShape, x, y },\n\t\t\t\t\t{\n\t\t\t\t\t\tnewPoint: newLocalPoint,\n\t\t\t\t\t\thandle: options.dragHandle ?? 'bottom_right',\n\t\t\t\t\t\t// don't set isSingle to true for children\n\t\t\t\t\t\tmode: options.mode ?? 'scale_shape',\n\t\t\t\t\t\tscaleX: myScale.x,\n\t\t\t\t\t\tscaleY: myScale.y,\n\t\t\t\t\t\tinitialBounds,\n\t\t\t\t\t\tinitialShape,\n\t\t\t\t\t}\n\t\t\t\t),\n\t\t\t})\n\n\t\t\tif (!options.skipStartAndEndCallbacks) {\n\t\t\t\tworkingShape = applyPartialToRecordWithProps(\n\t\t\t\t\tworkingShape,\n\t\t\t\t\tutil.onResizeEnd?.(initialShape, workingShape) ?? undefined\n\t\t\t\t)\n\t\t\t}\n\n\t\t\tthis.updateShapes([workingShape])\n\t\t} else {\n\t\t\tconst initialPageCenter = Mat.applyToPoint(pageTransform, initialBounds.center)\n\t\t\t// get the model changes from the shape util\n\t\t\tconst newPageCenter = this._scalePagePoint(\n\t\t\t\tinitialPageCenter,\n\t\t\t\tscaleOrigin,\n\t\t\t\tscale,\n\t\t\t\tscaleAxisRotation\n\t\t\t)\n\n\t\t\tconst initialPageCenterInParentSpace = this.getPointInParentSpace(\n\t\t\t\tinitialShape.id,\n\t\t\t\tinitialPageCenter\n\t\t\t)\n\t\t\tconst newPageCenterInParentSpace = this.getPointInParentSpace(initialShape.id, newPageCenter)\n\n\t\t\tconst delta = Vec.Sub(newPageCenterInParentSpace, initialPageCenterInParentSpace)\n\t\t\t// apply the changes to the model\n\t\t\tthis.updateShapes([\n\t\t\t\t{\n\t\t\t\t\tid,\n\t\t\t\t\ttype: initialShape.type as any,\n\t\t\t\t\tx: initialShape.x + delta.x,\n\t\t\t\t\ty: initialShape.y + delta.y,\n\t\t\t\t},\n\t\t\t])\n\t\t}\n\n\t\treturn this\n\t}\n\n\t/** @internal */\n\tprivate _scalePagePoint(\n\t\tpoint: VecLike,\n\t\tscaleOrigin: VecLike,\n\t\tscale: VecLike,\n\t\tscaleAxisRotation: number\n\t) {\n\t\tconst relativePoint = Vec.RotWith(point, scaleOrigin, -scaleAxisRotation).sub(scaleOrigin)\n\n\t\t// calculate the new point position relative to the scale origin\n\t\tconst newRelativePagePoint = Vec.MulV(relativePoint, scale)\n\n\t\t// and rotate it back to page coords to get the new page point of the resized shape\n\t\tconst destination = Vec.Add(newRelativePagePoint, scaleOrigin).rotWith(\n\t\t\tscaleOrigin,\n\t\t\tscaleAxisRotation\n\t\t)\n\n\t\treturn destination\n\t}\n\n\t/** @internal */\n\tprivate _resizeUnalignedShape(\n\t\tid: TLShapeId,\n\t\tscale: VecLike,\n\t\toptions: {\n\t\t\tinitialBounds: Box\n\t\t\tscaleOrigin: VecLike\n\t\t\tscaleAxisRotation: number\n\t\t\tinitialShape: TLShape\n\t\t\tisAspectRatioLocked: boolean\n\t\t\tinitialPageTransform: MatLike\n\t\t}\n\t) {\n\t\tconst { type } = options.initialShape\n\t\t// If a shape is not aligned with the scale axis we need to treat it differently to avoid skewing.\n\t\t// Instead of skewing we normalize the scale aspect ratio (i.e. keep the same scale magnitude in both axes)\n\t\t// and then after applying the scale to the shape we also rotate it if required and translate it so that it's center\n\t\t// point ends up in the right place.\n\n\t\tconst shapeScale = new Vec(scale.x, scale.y)\n\n\t\t// // make sure we are constraining aspect ratio, and using the smallest scale axis to avoid shapes getting bigger\n\t\t// // than the selection bounding box\n\t\tif (Math.abs(scale.x) > Math.abs(scale.y)) {\n\t\t\tshapeScale.x = Math.sign(scale.x) * Math.abs(scale.y)\n\t\t} else {\n\t\t\tshapeScale.y = Math.sign(scale.y) * Math.abs(scale.x)\n\t\t}\n\n\t\t// first we can scale the shape about its center point\n\t\tthis.resizeShape(id, shapeScale, {\n\t\t\tinitialShape: options.initialShape,\n\t\t\tinitialBounds: options.initialBounds,\n\t\t\tisAspectRatioLocked: options.isAspectRatioLocked,\n\t\t})\n\n\t\t// then if the shape is flipped in one axis only, we need to apply an extra rotation\n\t\t// to make sure the shape is mirrored correctly\n\t\tif (Math.sign(scale.x) * Math.sign(scale.y) < 0) {\n\t\t\tlet { rotation } = Mat.Decompose(options.initialPageTransform)\n\t\t\trotation -= 2 * rotation\n\t\t\tthis.updateShapes([{ id, type, rotation }])\n\t\t}\n\n\t\t// Next we need to translate the shape so that it's center point ends up in the right place.\n\t\t// To do that we first need to calculate the center point of the shape in the current page space before the scale was applied.\n\t\tconst preScaleShapePageCenter = Mat.applyToPoint(\n\t\t\toptions.initialPageTransform,\n\t\t\toptions.initialBounds.center\n\t\t)\n\n\t\t// And now we scale the center point by the original scale factor\n\t\tconst postScaleShapePageCenter = this._scalePagePoint(\n\t\t\tpreScaleShapePageCenter,\n\t\t\toptions.scaleOrigin,\n\t\t\tscale,\n\t\t\toptions.scaleAxisRotation\n\t\t)\n\n\t\t// now calculate how far away the shape is from where it needs to be\n\t\tconst pageBounds = this.getShapePageBounds(id)!\n\t\tconst pageTransform = this.getShapePageTransform(id)!\n\t\tconst currentPageCenter = pageBounds.center\n\t\tconst shapePageTransformOrigin = pageTransform.point()\n\t\tif (!currentPageCenter || !shapePageTransformOrigin) return this\n\t\tconst pageDelta = Vec.Sub(postScaleShapePageCenter, currentPageCenter)\n\n\t\t// and finally figure out what the shape's new position should be\n\t\tconst postScaleShapePagePoint = Vec.Add(shapePageTransformOrigin, pageDelta)\n\t\tconst { x, y } = this.getPointInParentSpace(id, postScaleShapePagePoint)\n\n\t\tthis.updateShapes([{ id, type, x, y }])\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Get the initial meta value for a shape.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getInitialMetaForShape = (shape) => {\n\t * if (shape.type === 'note') {\n\t * return { createdBy: myCurrentUser.id }\n\t * }\n\t * }\n\t * ```\n\t *\n\t * @param shape - The shape to get the initial meta for.\n\t *\n\t * @public\n\t */\n\tgetInitialMetaForShape(_shape: TLShape): JsonObject {\n\t\treturn {}\n\t}\n\n\t/**\n\t * Create a single shape.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.createShape(myShape)\n\t * editor.createShape({ id: 'box1', type: 'text', props: { text: \"ok\" } })\n\t * ```\n\t *\n\t * @param shape - The shape (or shape partial) to create.\n\t *\n\t * @public\n\t */\n\tcreateShape(shape: OptionalKeys, 'id'>): this {\n\t\tthis.createShapes([shape])\n\t\treturn this\n\t}\n\n\t/**\n\t * Create shapes.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.createShapes([myShape])\n\t * editor.createShapes([{ id: 'box1', type: 'text', props: { text: \"ok\" } }])\n\t * ```\n\t *\n\t * @param shapes - The shapes (or shape partials) to create.\n\t * @param select - Whether to select the created shapes. Defaults to false.\n\t *\n\t * @public\n\t */\n\tcreateShapes(shapes: OptionalKeys, 'id'>[]): this {\n\t\tif (!Array.isArray(shapes)) {\n\t\t\tthrow Error('Editor.createShapes: must provide an array of shapes or shape partials')\n\t\t}\n\t\tif (this.getInstanceState().isReadonly) return this\n\t\tif (shapes.length <= 0) return this\n\n\t\tconst currentPageShapeIds = this.getCurrentPageShapeIds()\n\n\t\tconst maxShapesReached =\n\t\t\tshapes.length + currentPageShapeIds.size > this.options.maxShapesPerPage\n\n\t\tif (maxShapesReached) {\n\t\t\t// can't create more shapes than fit on the page\n\t\t\talertMaxShapes(this)\n\t\t\treturn this\n\t\t}\n\n\t\tconst focusedGroupId = this.getFocusedGroupId()\n\n\t\tthis.run(() => {\n\t\t\t// 1. Parents\n\n\t\t\t// Make sure that each partial will become the child of either the\n\t\t\t// page or another shape that exists (or that will exist) in this page.\n\n\t\t\t// find last parent id\n\t\t\tconst currentPageShapesSorted = this.getCurrentPageShapesSorted()\n\n\t\t\tconst partials = shapes.map((partial) => {\n\t\t\t\tif (!partial.id) {\n\t\t\t\t\tpartial = { id: createShapeId(), ...partial }\n\t\t\t\t}\n\n\t\t\t\t// If the partial does not provide the parentId OR if the provided\n\t\t\t\t// parentId is NOT in the store AND NOT among the other shapes being\n\t\t\t\t// created, then we need to find a parent for the shape. This can be\n\t\t\t\t// another shape that exists under that point and which can receive\n\t\t\t\t// children of the creating shape's type, or else the page itself.\n\t\t\t\tif (\n\t\t\t\t\t!partial.parentId ||\n\t\t\t\t\t!(this.store.has(partial.parentId) || shapes.some((p) => p.id === partial.parentId))\n\t\t\t\t) {\n\t\t\t\t\tlet parentId: TLParentId = this.getFocusedGroupId()\n\n\t\t\t\t\tfor (let i = currentPageShapesSorted.length - 1; i >= 0; i--) {\n\t\t\t\t\t\tconst parent = currentPageShapesSorted[i]\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t!this.isShapeHidden(parent) &&\n\t\t\t\t\t\t\tthis.getShapeUtil(parent).canReceiveNewChildrenOfType(parent, partial.type) &&\n\t\t\t\t\t\t\tthis.isPointInShape(\n\t\t\t\t\t\t\t\tparent,\n\t\t\t\t\t\t\t\t// If no parent is provided, then we can treat the\n\t\t\t\t\t\t\t\t// shape's provided x/y as being in the page's space.\n\t\t\t\t\t\t\t\t{ x: partial.x ?? 0, y: partial.y ?? 0 },\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tmargin: 0,\n\t\t\t\t\t\t\t\t\thitInside: true,\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\tparentId = parent.id\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tconst prevParentId = partial.parentId\n\n\t\t\t\t\t// a shape cannot be it's own parent. This was a rare issue with frames/groups in the syncFuzz tests.\n\t\t\t\t\tif (parentId === partial.id) {\n\t\t\t\t\t\tparentId = focusedGroupId\n\t\t\t\t\t}\n\n\t\t\t\t\t// If the parentid has changed...\n\t\t\t\t\tif (parentId !== prevParentId) {\n\t\t\t\t\t\tpartial = { ...partial }\n\n\t\t\t\t\t\tpartial.parentId = parentId\n\n\t\t\t\t\t\t// If the parent is a shape (rather than a page) then insert the\n\t\t\t\t\t\t// shapes into the shape's children. Adjust the point and page rotation to be\n\t\t\t\t\t\t// preserved relative to the parent.\n\t\t\t\t\t\tif (isShapeId(parentId)) {\n\t\t\t\t\t\t\tconst point = this.getPointInShapeSpace(this.getShape(parentId)!, {\n\t\t\t\t\t\t\t\tx: partial.x ?? 0,\n\t\t\t\t\t\t\t\ty: partial.y ?? 0,\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\tpartial.x = point.x\n\t\t\t\t\t\t\tpartial.y = point.y\n\t\t\t\t\t\t\tpartial.rotation =\n\t\t\t\t\t\t\t\t-this.getShapePageTransform(parentId)!.rotation() + (partial.rotation ?? 0)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn partial\n\t\t\t})\n\n\t\t\t// 2. Indices\n\n\t\t\t// Get the highest index among the parents of each of the\n\t\t\t// the shapes being created; we'll increment from there.\n\n\t\t\tconst parentIndices = new Map()\n\n\t\t\tconst shapeRecordsToCreate: TLShape[] = []\n\n\t\t\tconst { opacityForNextShape } = this.getInstanceState()\n\n\t\t\tfor (const partial of partials) {\n\t\t\t\tconst util = this.getShapeUtil(partial as TLShapePartial)\n\n\t\t\t\t// If an index is not explicitly provided, then add the\n\t\t\t\t// shapes to the top of their parents' children; using the\n\t\t\t\t// value in parentsMappedToIndex, get the index above, use it,\n\t\t\t\t// and set it back to parentsMappedToIndex for next time.\n\t\t\t\tlet index = partial.index\n\n\t\t\t\tif (!index) {\n\t\t\t\t\t// Hello bug-seeker: have you just created a frame and then a shape\n\t\t\t\t\t// and found that the shape is automatically the child of the frame?\n\t\t\t\t\t// this is the reason why! It would be harder to have each shape specify\n\t\t\t\t\t// the frame as the parent when creating a shape inside of a frame, so\n\t\t\t\t\t// we do it here.\n\t\t\t\t\tconst parentId = partial.parentId ?? focusedGroupId\n\n\t\t\t\t\tif (!parentIndices.has(parentId)) {\n\t\t\t\t\t\tparentIndices.set(parentId, this.getHighestIndexForParent(parentId))\n\t\t\t\t\t}\n\t\t\t\t\tindex = parentIndices.get(parentId)!\n\t\t\t\t\tparentIndices.set(parentId, getIndexAbove(index))\n\t\t\t\t}\n\n\t\t\t\t// The initial props starts as the shape utility's default props\n\t\t\t\tconst initialProps = util.getDefaultProps()\n\n\t\t\t\t// We then look up each key in the tab state's styles; and if it's there,\n\t\t\t\t// we use the value from the tab state's styles instead of the default.\n\t\t\t\tfor (const [style, propKey] of this.styleProps[partial.type]) {\n\t\t\t\t\t;(initialProps as any)[propKey] = this.getStyleForNextShape(style)\n\t\t\t\t}\n\n\t\t\t\t// When we create the shape, take in the partial (the props coming into the\n\t\t\t\t// function) and merge it with the default props.\n\t\t\t\tlet shapeRecordToCreate = (\n\t\t\t\t\tthis.store.schema.types.shape as RecordType<\n\t\t\t\t\t\tTLShape,\n\t\t\t\t\t\t'type' | 'props' | 'index' | 'parentId'\n\t\t\t\t\t>\n\t\t\t\t).create({\n\t\t\t\t\t...partial,\n\t\t\t\t\tindex,\n\t\t\t\t\topacity: partial.opacity ?? opacityForNextShape,\n\t\t\t\t\tparentId: partial.parentId ?? focusedGroupId,\n\t\t\t\t\tprops: 'props' in partial ? { ...initialProps, ...partial.props } : initialProps,\n\t\t\t\t})\n\n\t\t\t\tif (shapeRecordToCreate.index === undefined) {\n\t\t\t\t\tthrow Error('no index!')\n\t\t\t\t}\n\n\t\t\t\tconst next = this.getShapeUtil(shapeRecordToCreate).onBeforeCreate?.(shapeRecordToCreate)\n\n\t\t\t\tif (next) {\n\t\t\t\t\tshapeRecordToCreate = next\n\t\t\t\t}\n\n\t\t\t\tshapeRecordsToCreate.push(shapeRecordToCreate)\n\t\t\t}\n\n\t\t\t// Add meta properties, if any, to the shapes\n\t\t\tshapeRecordsToCreate.forEach((shape) => {\n\t\t\t\tshape.meta = {\n\t\t\t\t\t...this.getInitialMetaForShape(shape),\n\t\t\t\t\t...shape.meta,\n\t\t\t\t}\n\t\t\t})\n\n\t\t\tthis.store.put(shapeRecordsToCreate)\n\t\t})\n\n\t\treturn this\n\t}\n\n\tprivate animatingShapes = new Map()\n\n\t/**\n\t * Animate a shape.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.animateShape({ id: 'box1', type: 'box', x: 100, y: 100 })\n\t * editor.animateShape({ id: 'box1', type: 'box', x: 100, y: 100 }, { animation: { duration: 100, ease: t => t*t } })\n\t * ```\n\t *\n\t * @param partial - The shape partial to update.\n\t * @param options - The animation's options.\n\t *\n\t * @public\n\t */\n\tanimateShape(\n\t\tpartial: TLShapePartial | null | undefined,\n\t\topts = { animation: DEFAULT_ANIMATION_OPTIONS } as TLCameraMoveOptions\n\t): this {\n\t\treturn this.animateShapes([partial], opts)\n\t}\n\n\t/**\n\t * Animate shapes.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.animateShapes([{ id: 'box1', type: 'box', x: 100, y: 100 }])\n\t * editor.animateShapes([{ id: 'box1', type: 'box', x: 100, y: 100 }], { animation: { duration: 100, ease: t => t*t } })\n\t * ```\n\t *\n\t * @param partials - The shape partials to update.\n\t * @param options - The animation's options.\n\t *\n\t * @public\n\t */\n\tanimateShapes(\n\t\tpartials: (TLShapePartial | null | undefined)[],\n\t\topts = { animation: DEFAULT_ANIMATION_OPTIONS } as TLCameraMoveOptions\n\t): this {\n\t\tif (!opts.animation) return this\n\t\tconst { duration = 500, easing = EASINGS.linear } = opts.animation\n\n\t\tconst animationId = uniqueId()\n\n\t\tlet remaining = duration\n\t\tlet t: number\n\n\t\tinterface ShapeAnimation {\n\t\t\tstart: TLShape\n\t\t\tend: TLShape\n\t\t}\n\n\t\tconst animations: ShapeAnimation[] = []\n\n\t\tlet partial: TLShapePartial | null | undefined, result: ShapeAnimation\n\t\tfor (let i = 0, n = partials.length; i < n; i++) {\n\t\t\tpartial = partials[i]\n\t\t\tif (!partial) continue\n\n\t\t\tconst shape = this.getShape(partial.id)!\n\t\t\tif (!shape) continue\n\n\t\t\tresult = {\n\t\t\t\tstart: structuredClone(shape),\n\t\t\t\tend: applyPartialToRecordWithProps(structuredClone(shape), partial),\n\t\t\t}\n\n\t\t\tanimations.push(result)\n\t\t\tthis.animatingShapes.set(shape.id, animationId)\n\t\t}\n\n\t\tconst handleTick = (elapsed: number) => {\n\t\t\tremaining -= elapsed\n\n\t\t\tif (remaining < 0) {\n\t\t\t\tconst { animatingShapes } = this\n\t\t\t\tconst partialsToUpdate = partials.filter(\n\t\t\t\t\t(p) => p && animatingShapes.get(p.id) === animationId\n\t\t\t\t)\n\t\t\t\tif (partialsToUpdate.length) {\n\t\t\t\t\t// the regular update shapes also removes the shape from\n\t\t\t\t\t// the animating shapes set\n\t\t\t\t\tthis.updateShapes(partialsToUpdate)\n\t\t\t\t}\n\n\t\t\t\tthis.off('tick', handleTick)\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tt = easing(1 - remaining / duration)\n\n\t\t\tconst { animatingShapes } = this\n\n\t\t\tconst updates: TLShapePartial[] = []\n\n\t\t\tlet animationIdForShape: string | undefined\n\t\t\tfor (let i = 0, n = animations.length; i < n; i++) {\n\t\t\t\tconst { start, end } = animations[i]\n\t\t\t\t// Is the animation for this shape still active?\n\t\t\t\tanimationIdForShape = animatingShapes.get(start.id)\n\t\t\t\tif (animationIdForShape !== animationId) continue\n\n\t\t\t\tupdates.push({\n\t\t\t\t\t...end,\n\t\t\t\t\tx: start.x + (end.x - start.x) * t,\n\t\t\t\t\ty: start.y + (end.y - start.y) * t,\n\t\t\t\t\topacity: start.opacity + (end.opacity - start.opacity) * t,\n\t\t\t\t\trotation: start.rotation + (end.rotation - start.rotation) * t,\n\t\t\t\t\tprops: this.getShapeUtil(end).getInterpolatedProps?.(start, end, t) ?? end.props,\n\t\t\t\t})\n\t\t\t}\n\n\t\t\t// The _updateShapes method does NOT remove the\n\t\t\t// shapes from the animated shapes set\n\t\t\tthis._updateShapes(updates)\n\t\t}\n\n\t\tthis.on('tick', handleTick)\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Create a group containing the provided shapes.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.groupShapes([myShape, myOtherShape])\n\t * editor.groupShapes([myShape, myOtherShape], { groupId: myGroupId, select: false })\n\t * ```\n\t *\n\t * @param shapes - The shapes (or shape ids) to group. Defaults to the selected shapes.\n\t * @param options - An options object.\n\t *\n\t * @public\n\t */\n\tgroupShapes(shapes: TLShape[], options?: Partial<{ groupId: TLShapeId; select: boolean }>): this\n\tgroupShapes(ids: TLShapeId[], options?: Partial<{ groupId: TLShapeId; select: boolean }>): this\n\tgroupShapes(\n\t\tshapes: TLShapeId[] | TLShape[],\n\t\toptions = {} as Partial<{ groupId: TLShapeId; select: boolean }>\n\t): this {\n\t\tconst { groupId = createShapeId(), select = true } = options\n\n\t\tif (!Array.isArray(shapes)) {\n\t\t\tthrow Error('Editor.groupShapes: must provide an array of shapes or shape ids')\n\t\t}\n\t\tif (this.getInstanceState().isReadonly) return this\n\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes.map((s) => (s as TLShape).id) as TLShapeId[])\n\n\t\tif (ids.length <= 1) return this\n\n\t\tconst shapesToGroup = compact(\n\t\t\t(this._shouldIgnoreShapeLock ? ids : this._getUnlockedShapeIds(ids)).map((id) =>\n\t\t\t\tthis.getShape(id)\n\t\t\t)\n\t\t)\n\t\tconst sortedShapeIds = shapesToGroup.sort(sortByIndex).map((s) => s.id)\n\t\tconst pageBounds = Box.Common(compact(shapesToGroup.map((id) => this.getShapePageBounds(id))))\n\n\t\tconst { x, y } = pageBounds.point\n\n\t\tconst parentId = this.findCommonAncestor(shapesToGroup) ?? this.getCurrentPageId()\n\n\t\t// Only group when the select tool is active\n\t\tif (this.getCurrentToolId() !== 'select') return this\n\n\t\t// If not already in idle, cancel the current interaction (get back to idle)\n\t\tif (!this.isIn('select.idle')) {\n\t\t\tthis.cancel()\n\t\t}\n\n\t\t// Find all the shapes that have the same parentId, and use the highest index.\n\t\tconst shapesWithRootParent = shapesToGroup\n\t\t\t.filter((shape) => shape.parentId === parentId)\n\t\t\t.sort(sortByIndex)\n\n\t\tconst highestIndex = shapesWithRootParent[shapesWithRootParent.length - 1]?.index\n\n\t\tthis.run(() => {\n\t\t\tthis.createShapes([\n\t\t\t\t{\n\t\t\t\t\tid: groupId,\n\t\t\t\t\ttype: 'group',\n\t\t\t\t\tparentId,\n\t\t\t\t\tindex: highestIndex,\n\t\t\t\t\tx,\n\t\t\t\t\ty,\n\t\t\t\t\topacity: 1,\n\t\t\t\t\tprops: {},\n\t\t\t\t},\n\t\t\t])\n\t\t\tthis.reparentShapes(sortedShapeIds, groupId)\n\t\t\tif (select) {\n\t\t\t\t// the select option determines whether the grouped shapes' children are selected\n\t\t\t\tthis.select(groupId)\n\t\t\t}\n\t\t})\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Ungroup some shapes.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.ungroupShapes([myGroup, myOtherGroup])\n\t * editor.ungroupShapes([myGroup], { select: false })\n\t * ```\n\t *\n\t * @param shapes - The group shapes (or shape ids) to ungroup.\n\t * @param options - An options object.\n\t *\n\t * @public\n\t */\n\tungroupShapes(ids: TLShapeId[], options?: Partial<{ select: boolean }>): this\n\tungroupShapes(shapes: TLShape[], options?: Partial<{ select: boolean }>): this\n\tungroupShapes(shapes: TLShapeId[] | TLShape[], options = {} as Partial<{ select: boolean }>) {\n\t\tif (this.getInstanceState().isReadonly) return this\n\n\t\tconst { select = true } = options\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\n\t\tconst shapesToUngroup = compact(\n\t\t\t(this._shouldIgnoreShapeLock ? ids : this._getUnlockedShapeIds(ids)).map((id) =>\n\t\t\t\tthis.getShape(id)\n\t\t\t)\n\t\t)\n\n\t\tif (shapesToUngroup.length === 0) return this\n\n\t\t// todo: the editor shouldn't know about the select tool, move to group / ungroup actions\n\t\tif (this.getCurrentToolId() !== 'select') return this\n\t\tif (!this.isIn('select.idle')) {\n\t\t\tthis.cancel()\n\t\t}\n\n\t\t// The ids of the selected shapes after ungrouping;\n\t\t// these include all of the grouped shapes children,\n\t\t// plus any shapes that were selected apart from the groups.\n\t\tconst idsToSelect = new Set()\n\n\t\t// Get all groups in the selection\n\t\tconst groups: TLGroupShape[] = []\n\n\t\tshapesToUngroup.forEach((shape) => {\n\t\t\tif (this.isShapeOfType(shape, 'group')) {\n\t\t\t\tgroups.push(shape)\n\t\t\t} else {\n\t\t\t\tidsToSelect.add(shape.id)\n\t\t\t}\n\t\t})\n\n\t\tif (groups.length === 0) return this\n\n\t\tthis.run(() => {\n\t\t\tlet group: TLGroupShape\n\n\t\t\tfor (let i = 0, n = groups.length; i < n; i++) {\n\t\t\t\tgroup = groups[i]\n\t\t\t\tconst childIds = this.getSortedChildIdsForParent(group.id)\n\n\t\t\t\tfor (let j = 0, n = childIds.length; j < n; j++) {\n\t\t\t\t\tidsToSelect.add(childIds[j])\n\t\t\t\t}\n\n\t\t\t\tthis.reparentShapes(childIds, group.parentId, group.index)\n\t\t\t}\n\n\t\t\tthis.deleteShapes(groups.map((group) => group.id))\n\n\t\t\tif (select) {\n\t\t\t\t// the select option determines whether the ungrouped shapes' children are selected\n\t\t\t\tthis.select(...idsToSelect)\n\t\t\t}\n\t\t})\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Update a shape using a partial of the shape.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.updateShape({ id: 'box1', type: 'geo', props: { w: 100, h: 100 } })\n\t * ```\n\t *\n\t * @param partial - The shape partial to update.\n\t *\n\t * @public\n\t */\n\tupdateShape(partial: TLShapePartial | null | undefined) {\n\t\tthis.updateShapes([partial])\n\t\treturn this\n\t}\n\n\t/**\n\t * Update shapes using partials of each shape.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.updateShapes([{ id: 'box1', type: 'geo', props: { w: 100, h: 100 } }])\n\t * ```\n\t *\n\t * @param partials - The shape partials to update.\n\t *\n\t * @public\n\t */\n\tupdateShapes(partials: (TLShapePartial | null | undefined)[]) {\n\t\tconst compactedPartials: TLShapePartial[] = Array(partials.length)\n\n\t\tfor (let i = 0, n = partials.length; i < n; i++) {\n\t\t\tconst partial = partials[i]\n\t\t\tif (!partial) continue\n\t\t\t// Get the current shape referenced by the partial\n\t\t\tconst shape = this.getShape(partial.id)\n\t\t\tif (!shape) continue\n\n\t\t\t// If we're \"forcing\" the update, then we'll update the shape\n\t\t\t// regardless of whether it / its ancestor is locked\n\t\t\tif (!this._shouldIgnoreShapeLock) {\n\t\t\t\tif (shape.isLocked) {\n\t\t\t\t\t// If the shape itself is locked (even if one of its ancestors is\n\t\t\t\t\t// also locked) then only allow an update that unlocks the shape.\n\t\t\t\t\tif (!(Object.hasOwn(partial, 'isLocked') && !partial.isLocked)) {\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\t\t\t\t} else if (this.isShapeOrAncestorLocked(shape)) {\n\t\t\t\t\t// If the shape itself is unlocked, and any of the shape's\n\t\t\t\t\t// ancestors are locked then we'll skip the update\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Remove any animating shapes from the list of partials\n\t\t\tthis.animatingShapes.delete(partial.id)\n\n\t\t\tcompactedPartials.push(partial)\n\t\t}\n\n\t\tthis._updateShapes(compactedPartials)\n\t\treturn this\n\t}\n\n\t/** @internal */\n\t_updateShapes(_partials: (TLShapePartial | null | undefined)[]) {\n\t\tif (this.getInstanceState().isReadonly) return\n\n\t\tthis.run(() => {\n\t\t\tconst updates = []\n\n\t\t\tlet shape: TLShape | undefined\n\t\t\tlet updated: TLShape\n\n\t\t\tfor (let i = 0, n = _partials.length; i < n; i++) {\n\t\t\t\tconst partial = _partials[i]\n\t\t\t\t// Skip nullish partials (sometimes created by map fns returning undefined)\n\t\t\t\tif (!partial) continue\n\n\t\t\t\t// Get the current shape referenced by the partial\n\t\t\t\t// If there is no current shape, we'll skip this update\n\t\t\t\tshape = this.getShape(partial.id)\n\t\t\t\tif (!shape) continue\n\n\t\t\t\t// Get the updated version of the shape\n\t\t\t\t// If the update had no effect, we'll skip this update\n\t\t\t\tupdated = applyPartialToRecordWithProps(shape, partial)\n\t\t\t\tif (updated === shape) continue\n\n\t\t\t\t//if any shape has an onBeforeUpdate handler, call it and, if the handler returns a\n\t\t\t\t// new shape, replace the old shape with the new one. This is used for example when\n\t\t\t\t// repositioning a text shape based on its new text content.\n\t\t\t\tupdated = this.getShapeUtil(shape).onBeforeUpdate?.(shape, updated) ?? updated\n\n\t\t\t\tupdates.push(updated)\n\t\t\t}\n\n\t\t\tthis.store.put(updates)\n\t\t})\n\t}\n\n\t/** @internal */\n\tprivate _getUnlockedShapeIds(ids: TLShapeId[]): TLShapeId[] {\n\t\treturn ids.filter((id) => !this.getShape(id)?.isLocked)\n\t}\n\n\t/**\n\t * Delete shapes.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.deleteShapes(['box1', 'box2'])\n\t * ```\n\t *\n\t * @param ids - The ids of the shapes to delete.\n\t *\n\t * @public\n\t */\n\tdeleteShapes(ids: TLShapeId[]): this\n\tdeleteShapes(shapes: TLShape[]): this\n\tdeleteShapes(_ids: TLShapeId[] | TLShape[]): this {\n\t\tif (this.getInstanceState().isReadonly) return this\n\n\t\tif (!Array.isArray(_ids)) {\n\t\t\tthrow Error('Editor.deleteShapes: must provide an array of shapes or shapeIds')\n\t\t}\n\n\t\tconst shapeIds =\n\t\t\ttypeof _ids[0] === 'string' ? (_ids as TLShapeId[]) : (_ids as TLShape[]).map((s) => s.id)\n\n\t\t// Normally we don't want to delete locked shapes, but if the force option is set, we'll delete them anyway\n\t\tconst shapeIdsToDelete = this._shouldIgnoreShapeLock\n\t\t\t? shapeIds\n\t\t\t: this._getUnlockedShapeIds(shapeIds)\n\n\t\tif (shapeIdsToDelete.length === 0) return this\n\n\t\t// We also need to delete these shapes' descendants\n\t\tconst allShapeIdsToDelete = new Set(shapeIdsToDelete)\n\n\t\tfor (const id of shapeIdsToDelete) {\n\t\t\tthis.visitDescendants(id, (childId) => {\n\t\t\t\tallShapeIdsToDelete.add(childId)\n\t\t\t})\n\t\t}\n\n\t\treturn this.run(() => this.store.remove([...allShapeIdsToDelete]))\n\t}\n\n\t/**\n\t * Delete a shape.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.deleteShape(shape.id)\n\t * ```\n\t *\n\t * @param id - The id of the shape to delete.\n\t *\n\t * @public\n\t */\n\tdeleteShape(id: TLShapeId): this\n\tdeleteShape(shape: TLShape): this\n\tdeleteShape(_id: TLShapeId | TLShape) {\n\t\tthis.deleteShapes([typeof _id === 'string' ? _id : _id.id])\n\t\treturn this\n\t}\n\n\t/* --------------------- Styles --------------------- */\n\n\t/**\n\t * Get all the current styles among the users selected shapes\n\t *\n\t * @internal\n\t */\n\tprivate _extractSharedStyles(shape: TLShape, sharedStyleMap: SharedStyleMap) {\n\t\tif (this.isShapeOfType(shape, 'group')) {\n\t\t\t// For groups, ignore the styles of the group shape and instead include the styles of the\n\t\t\t// group's children. These are the shapes that would have their styles changed if the\n\t\t\t// user called `setStyle` on the current selection.\n\t\t\tconst childIds = this._parentIdsToChildIds.get()[shape.id]\n\t\t\tif (!childIds) return\n\n\t\t\tfor (let i = 0, n = childIds.length; i < n; i++) {\n\t\t\t\tthis._extractSharedStyles(this.getShape(childIds[i])!, sharedStyleMap)\n\t\t\t}\n\t\t} else {\n\t\t\tfor (const [style, propKey] of this.styleProps[shape.type]) {\n\t\t\t\tsharedStyleMap.applyValue(style, getOwnProperty(shape.props, propKey))\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * A derived map containing all current styles among the user's selected shapes.\n\t *\n\t * @internal\n\t */\n\t@computed\n\tprivate _getSelectionSharedStyles(): ReadonlySharedStyleMap {\n\t\tconst selectedShapes = this.getSelectedShapes()\n\n\t\tconst sharedStyles = new SharedStyleMap()\n\t\tfor (const selectedShape of selectedShapes) {\n\t\t\tthis._extractSharedStyles(selectedShape, sharedStyles)\n\t\t}\n\n\t\treturn sharedStyles\n\t}\n\n\t/**\n\t * Get the style for the next shape.\n\t *\n\t * @example\n\t * ```ts\n\t * const color = editor.getStyleForNextShape(DefaultColorStyle)\n\t * ```\n\t *\n\t * @param style - The style to get.\n\t *\n\t * @public */\n\tgetStyleForNextShape(style: StyleProp): T {\n\t\tconst value = this.getInstanceState().stylesForNextShape[style.id]\n\t\treturn value === undefined ? style.defaultValue : (value as T)\n\t}\n\n\tgetShapeStyleIfExists(shape: TLShape, style: StyleProp): T | undefined {\n\t\tconst styleKey = this.styleProps[shape.type].get(style)\n\t\tif (styleKey === undefined) return undefined\n\t\treturn getOwnProperty(shape.props, styleKey) as T | undefined\n\t}\n\n\t/**\n\t * A map of all the current styles either in the current selection, or that are relevant to the\n\t * current tool.\n\t *\n\t * @example\n\t * ```ts\n\t * const color = editor.getSharedStyles().get(DefaultColorStyle)\n\t * if (color && color.type === 'shared') {\n\t * print('All selected shapes have the same color:', color.value)\n\t * }\n\t * ```\n\t *\n\t * @public\n\t */\n\t@computed({ isEqual: (a, b) => a.equals(b) })\n\tgetSharedStyles(): ReadonlySharedStyleMap {\n\t\t// If we're in selecting and if we have a selection, return the shared styles from the\n\t\t// current selection\n\t\tif (this.isIn('select') && this.getSelectedShapeIds().length > 0) {\n\t\t\treturn this._getSelectionSharedStyles()\n\t\t}\n\n\t\t// If the current tool is associated with a shape, return the styles for that shape.\n\t\t// Otherwise, just return an empty map.\n\t\tconst currentTool = this.root.getCurrent()!\n\t\tconst styles = new SharedStyleMap()\n\n\t\tif (!currentTool) return styles\n\n\t\tif (currentTool.shapeType) {\n\t\t\tfor (const style of this.styleProps[currentTool.shapeType].keys()) {\n\t\t\t\tstyles.applyValue(style, this.getStyleForNextShape(style))\n\t\t\t}\n\t\t}\n\n\t\treturn styles\n\t}\n\n\t/**\n\t * Get the currently selected shared opacity.\n\t * If any shapes are selected, this returns the shared opacity of the selected shapes.\n\t * Otherwise, this returns the chosen opacity for the next shape.\n\t *\n\t * @public\n\t */\n\t@computed getSharedOpacity(): SharedStyle {\n\t\tif (this.isIn('select') && this.getSelectedShapeIds().length > 0) {\n\t\t\tconst shapesToCheck: TLShape[] = []\n\t\t\tconst addShape = (shapeId: TLShapeId) => {\n\t\t\t\tconst shape = this.getShape(shapeId)\n\t\t\t\tif (!shape) return\n\t\t\t\t// For groups, ignore the opacity of the group shape and instead include\n\t\t\t\t// the opacity of the group's children. These are the shapes that would have\n\t\t\t\t// their opacity changed if the user called `setOpacity` on the current selection.\n\t\t\t\tif (this.isShapeOfType(shape, 'group')) {\n\t\t\t\t\tfor (const childId of this.getSortedChildIdsForParent(shape.id)) {\n\t\t\t\t\t\taddShape(childId)\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tshapesToCheck.push(shape)\n\t\t\t\t}\n\t\t\t}\n\t\t\tfor (const shapeId of this.getSelectedShapeIds()) {\n\t\t\t\taddShape(shapeId)\n\t\t\t}\n\n\t\t\tlet opacity: number | null = null\n\t\t\tfor (const shape of shapesToCheck) {\n\t\t\t\tif (opacity === null) {\n\t\t\t\t\topacity = shape.opacity\n\t\t\t\t} else if (opacity !== shape.opacity) {\n\t\t\t\t\treturn { type: 'mixed' }\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (opacity !== null) return { type: 'shared', value: opacity }\n\t\t}\n\t\treturn { type: 'shared', value: this.getInstanceState().opacityForNextShape }\n\t}\n\n\t/**\n\t * Set the opacity for the next shapes. This will effect subsequently created shapes.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.setOpacityForNextShapes(0.5)\n\t * ```\n\t *\n\t * @param opacity - The opacity to set. Must be a number between 0 and 1 inclusive.\n\t * @param historyOptions - The history options for the change.\n\t */\n\tsetOpacityForNextShapes(opacity: number, historyOptions?: TLHistoryBatchOptions): this {\n\t\tthis.updateInstanceState({ opacityForNextShape: opacity }, historyOptions)\n\t\treturn this\n\t}\n\n\t/**\n\t * Set the current opacity. This will effect any selected shapes.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.setOpacityForSelectedShapes(0.5)\n\t * ```\n\t *\n\t * @param opacity - The opacity to set. Must be a number between 0 and 1 inclusive.\n\t */\n\tsetOpacityForSelectedShapes(opacity: number): this {\n\t\tconst selectedShapes = this.getSelectedShapes()\n\n\t\tif (selectedShapes.length > 0) {\n\t\t\tconst shapesToUpdate: TLShape[] = []\n\n\t\t\t// We can have many deep levels of grouped shape\n\t\t\t// Making a recursive function to look through all the levels\n\t\t\tconst addShapeById = (shape: TLShape) => {\n\t\t\t\tif (this.isShapeOfType(shape, 'group')) {\n\t\t\t\t\tconst childIds = this.getSortedChildIdsForParent(shape)\n\t\t\t\t\tfor (const childId of childIds) {\n\t\t\t\t\t\taddShapeById(this.getShape(childId)!)\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tshapesToUpdate.push(shape)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfor (const id of selectedShapes) {\n\t\t\t\taddShapeById(id)\n\t\t\t}\n\n\t\t\tthis.updateShapes(\n\t\t\t\tshapesToUpdate.map((shape) => {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tid: shape.id,\n\t\t\t\t\t\ttype: shape.type,\n\t\t\t\t\t\topacity,\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t)\n\t\t}\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Set the value of a {@link @tldraw/tlschema#StyleProp} for the next shapes. This change will be applied to subsequently created shapes.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.setStyleForNextShapes(DefaultColorStyle, 'red')\n\t * editor.setStyleForNextShapes(DefaultColorStyle, 'red', { ephemeral: true })\n\t * ```\n\t *\n\t * @param style - The style to set.\n\t * @param value - The value to set.\n\t * @param historyOptions - The history options for the change.\n\t *\n\t * @public\n\t */\n\tsetStyleForNextShapes(\n\t\tstyle: StyleProp,\n\t\tvalue: T,\n\t\thistoryOptions?: TLHistoryBatchOptions\n\t): this {\n\t\tconst stylesForNextShape = this.getInstanceState().stylesForNextShape\n\n\t\tthis.updateInstanceState(\n\t\t\t{ stylesForNextShape: { ...stylesForNextShape, [style.id]: value } },\n\t\t\thistoryOptions\n\t\t)\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Set the value of a {@link @tldraw/tlschema#StyleProp}. This change will be applied to the currently selected shapes.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.setStyleForSelectedShapes(DefaultColorStyle, 'red')\n\t * ```\n\t *\n\t * @param style - The style to set.\n\t * @param value - The value to set.\n\t * @param historyOptions - The history options for the change.\n\t *\n\t * @public\n\t */\n\tsetStyleForSelectedShapes>(style: S, value: StylePropValue): this {\n\t\tconst selectedShapes = this.getSelectedShapes()\n\n\t\tif (selectedShapes.length > 0) {\n\t\t\tconst updates: {\n\t\t\t\tutil: ShapeUtil\n\t\t\t\toriginalShape: TLShape\n\t\t\t\tupdatePartial: TLShapePartial\n\t\t\t}[] = []\n\n\t\t\t// We can have many deep levels of grouped shape\n\t\t\t// Making a recursive function to look through all the levels\n\t\t\tconst addShapeById = (shape: TLShape) => {\n\t\t\t\tif (this.isShapeOfType(shape, 'group')) {\n\t\t\t\t\tconst childIds = this.getSortedChildIdsForParent(shape.id)\n\t\t\t\t\tfor (const childId of childIds) {\n\t\t\t\t\t\taddShapeById(this.getShape(childId)!)\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tconst util = this.getShapeUtil(shape)\n\t\t\t\t\tconst stylePropKey = this.styleProps[shape.type].get(style)\n\t\t\t\t\tif (stylePropKey) {\n\t\t\t\t\t\tconst shapePartial: TLShapePartial = {\n\t\t\t\t\t\t\tid: shape.id,\n\t\t\t\t\t\t\ttype: shape.type,\n\t\t\t\t\t\t\tprops: { [stylePropKey]: value },\n\t\t\t\t\t\t}\n\t\t\t\t\t\tupdates.push({\n\t\t\t\t\t\t\tutil,\n\t\t\t\t\t\t\toriginalShape: shape,\n\t\t\t\t\t\t\tupdatePartial: shapePartial,\n\t\t\t\t\t\t})\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfor (const shape of selectedShapes) {\n\t\t\t\taddShapeById(shape)\n\t\t\t}\n\n\t\t\tthis.updateShapes(updates.map(({ updatePartial }) => updatePartial))\n\t\t}\n\n\t\treturn this\n\t}\n\n\t/* --------------------- Content -------------------- */\n\n\t/** @internal */\n\texternalAssetContentHandlers: {\n\t\t[K in TLExternalAssetContent['type']]: {\n\t\t\t[Key in K]:\n\t\t\t\t| null\n\t\t\t\t| ((info: TLExternalAssetContent & { type: Key }) => Promise)\n\t\t}[K]\n\t} = {\n\t\tfile: null,\n\t\turl: null,\n\t}\n\n\t/** @internal */\n\tprivate readonly temporaryAssetPreview = new Map()\n\n\t/**\n\t * Register an external asset handler. This handler will be called when the editor needs to\n\t * create an asset for some external content, like an image/video file or a bookmark URL. For\n\t * example, the 'file' type handler will be called when a user drops an image onto the canvas.\n\t *\n\t * The handler should extract any relevant metadata for the asset, upload it to blob storage\n\t * using {@link Editor.uploadAsset} if needed, and return the asset with the metadata & uploaded\n\t * URL.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.registerExternalAssetHandler('file', myHandler)\n\t * ```\n\t *\n\t * @param type - The type of external content.\n\t * @param handler - The handler to use for this content type.\n\t *\n\t * @public\n\t */\n\tregisterExternalAssetHandler(\n\t\ttype: T,\n\t\thandler: null | ((info: TLExternalAssetContent & { type: T }) => Promise)\n\t): this {\n\t\tthis.externalAssetContentHandlers[type] = handler as any\n\t\treturn this\n\t}\n\n\t/**\n\t * Register a temporary preview of an asset. This is useful for showing a ghost image of\n\t * something that is being uploaded. Retrieve the placeholder with\n\t * {@link Editor.getTemporaryAssetPreview}. Placeholders last for 3 minutes by default, but this\n\t * can be configured using\n\t *\n\t * @example\n\t * ```ts\n\t * editor.createTemporaryAssetPreview(assetId, file)\n\t * ```\n\t *\n\t * @param assetId - The asset's id.\n\t * @param file - The raw file.\n\t *\n\t * @public\n\t */\n\tcreateTemporaryAssetPreview(assetId: TLAssetId, file: File) {\n\t\tif (this.temporaryAssetPreview.has(assetId)) {\n\t\t\treturn this.temporaryAssetPreview.get(assetId)\n\t\t}\n\n\t\tconst objectUrl = URL.createObjectURL(file)\n\t\tthis.temporaryAssetPreview.set(assetId, objectUrl)\n\n\t\t// eslint-disable-next-line no-restricted-globals -- we always want to revoke the asset and object URL\n\t\tsetTimeout(() => {\n\t\t\tthis.temporaryAssetPreview.delete(assetId)\n\t\t\tURL.revokeObjectURL(objectUrl)\n\t\t}, this.options.temporaryAssetPreviewLifetimeMs)\n\n\t\treturn objectUrl\n\t}\n\n\t/**\n\t * Get temporary preview of an asset. This is useful for showing a ghost\n\t * image of something that is being uploaded.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getTemporaryAssetPreview('someId')\n\t * ```\n\t *\n\t * @param assetId - The asset's id.\n\t *\n\t * @public\n\t */\n\tgetTemporaryAssetPreview(assetId: TLAssetId) {\n\t\treturn this.temporaryAssetPreview.get(assetId)\n\t}\n\n\t/**\n\t * Get an asset for an external asset content type.\n\t *\n\t * @example\n\t * ```ts\n\t * const asset = await editor.getAssetForExternalContent({ type: 'file', file: myFile })\n\t * const asset = await editor.getAssetForExternalContent({ type: 'url', url: myUrl })\n\t * ```\n\t *\n\t * @param info - Info about the external content.\n\t * @returns The asset.\n\t */\n\tasync getAssetForExternalContent(info: TLExternalAssetContent): Promise {\n\t\treturn await this.externalAssetContentHandlers[info.type]?.(info as any)\n\t}\n\n\thasExternalAssetHandler(type: TLExternalAssetContent['type']): boolean {\n\t\treturn !!this.externalAssetContentHandlers[type]\n\t}\n\n\t/** @internal */\n\texternalContentHandlers: {\n\t\t[K in TLExternalContent['type']]: {\n\t\t\t[Key in K]: null | ((info: TLExternalContent & { type: Key }) => void)\n\t\t}[K]\n\t} = {\n\t\ttext: null,\n\t\tfiles: null,\n\t\tembed: null,\n\t\t'svg-text': null,\n\t\turl: null,\n\t}\n\n\t/**\n\t * Register an external content handler. This handler will be called when the editor receives\n\t * external content of the provided type. For example, the 'image' type handler will be called\n\t * when a user drops an image onto the canvas.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.registerExternalContentHandler('text', myHandler)\n\t * ```\n\t * @example\n\t * ```ts\n\t * editor.registerExternalContentHandler<'embed', MyEmbedType>('embed', myHandler)\n\t * ```\n\t *\n\t * @param type - The type of external content.\n\t * @param handler - The handler to use for this content type.\n\t *\n\t * @public\n\t */\n\tregisterExternalContentHandler['type'], E>(\n\t\ttype: T,\n\t\thandler:\n\t\t\t| null\n\t\t\t| ((\n\t\t\t\t\tinfo: T extends TLExternalContent['type']\n\t\t\t\t\t\t? TLExternalContent & { type: T }\n\t\t\t\t\t\t: TLExternalContent\n\t\t\t ) => void)\n\t): this {\n\t\tthis.externalContentHandlers[type] = handler as any\n\t\treturn this\n\t}\n\n\t/**\n\t * Handle external content, such as files, urls, embeds, or plain text which has been put into the app, for example by pasting external text or dropping external images onto canvas.\n\t *\n\t * @param info - Info about the external content.\n\t */\n\tasync putExternalContent(info: TLExternalContent): Promise {\n\t\treturn this.externalContentHandlers[info.type]?.(info as any)\n\t}\n\n\t/**\n\t * Get content that can be exported for the given shape ids.\n\t *\n\t * @param shapes - The shapes (or shape ids) to get content for.\n\t *\n\t * @returns The exported content.\n\t *\n\t * @public\n\t */\n\tgetContentFromCurrentPage(shapes: TLShapeId[] | TLShape[]): TLContent | undefined {\n\t\t// todo: make this work with any page, not just the current page\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\n\t\tif (!ids) return\n\t\tif (ids.length === 0) return\n\n\t\tconst shapeIds = this.getShapeAndDescendantIds(ids)\n\n\t\treturn withIsolatedShapes(this, shapeIds, (bindingIdsToKeep) => {\n\t\t\tconst bindings: TLBinding[] = []\n\t\t\tfor (const id of bindingIdsToKeep) {\n\t\t\t\tconst binding = this.getBinding(id)\n\t\t\t\tif (!binding) continue\n\t\t\t\tbindings.push(binding)\n\t\t\t}\n\n\t\t\tconst rootShapeIds: TLShapeId[] = []\n\t\t\tconst shapes: TLShape[] = []\n\t\t\tfor (const shapeId of shapeIds) {\n\t\t\t\tconst shape = this.getShape(shapeId)\n\t\t\t\tif (!shape) continue\n\n\t\t\t\tconst isRootShape = !shapeIds.has(shape.parentId as TLShapeId)\n\t\t\t\tif (isRootShape) {\n\t\t\t\t\t// Need to get page point and rotation of the shape because shapes in\n\t\t\t\t\t// groups use local position/rotation\n\t\t\t\t\tconst pageTransform = this.getShapePageTransform(shape.id)!\n\t\t\t\t\tconst pagePoint = pageTransform.point()\n\t\t\t\t\tshapes.push({\n\t\t\t\t\t\t...shape,\n\t\t\t\t\t\tx: pagePoint.x,\n\t\t\t\t\t\ty: pagePoint.y,\n\t\t\t\t\t\trotation: pageTransform.rotation(),\n\t\t\t\t\t\tparentId: this.getCurrentPageId(),\n\t\t\t\t\t})\n\t\t\t\t\trootShapeIds.push(shape.id)\n\t\t\t\t} else {\n\t\t\t\t\tshapes.push(shape)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst assets: TLAsset[] = []\n\t\t\tconst seenAssetIds = new Set()\n\t\t\tfor (const shape of shapes) {\n\t\t\t\tif (!('assetId' in shape.props)) continue\n\n\t\t\t\tconst assetId = shape.props.assetId\n\t\t\t\tif (!assetId || seenAssetIds.has(assetId)) continue\n\n\t\t\t\tseenAssetIds.add(assetId)\n\t\t\t\tconst asset = this.getAsset(assetId)\n\t\t\t\tif (!asset) continue\n\t\t\t\tassets.push(asset)\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tschema: this.store.schema.serialize(),\n\t\t\t\tshapes,\n\t\t\t\trootShapeIds,\n\t\t\t\tbindings,\n\t\t\t\tassets,\n\t\t\t}\n\t\t})\n\t}\n\n\tasync resolveAssetsInContent(content: TLContent | undefined): Promise {\n\t\tif (!content) return undefined\n\n\t\tconst assets: TLAsset[] = []\n\t\tawait Promise.allSettled(\n\t\t\tcontent.assets.map(async (asset) => {\n\t\t\t\tif (\n\t\t\t\t\t(asset.type === 'image' || asset.type === 'video') &&\n\t\t\t\t\t!asset.props.src?.startsWith('data:image') &&\n\t\t\t\t\t!asset.props.src?.startsWith('http')\n\t\t\t\t) {\n\t\t\t\t\tconst assetWithDataUrl = structuredClone(asset as TLImageAsset | TLVideoAsset)\n\t\t\t\t\tconst objectUrl = await this.store.props.assets.resolve(asset, {\n\t\t\t\t\t\tscreenScale: 1,\n\t\t\t\t\t\tsteppedScreenScale: 1,\n\t\t\t\t\t\tdpr: 1,\n\t\t\t\t\t\tnetworkEffectiveType: null,\n\t\t\t\t\t\tshouldResolveToOriginal: true,\n\t\t\t\t\t})\n\t\t\t\t\tassetWithDataUrl.props.src = await FileHelpers.blobToDataUrl(\n\t\t\t\t\t\tawait fetch(objectUrl!).then((r) => r.blob())\n\t\t\t\t\t)\n\t\t\t\t\tassets.push(assetWithDataUrl)\n\t\t\t\t} else {\n\t\t\t\t\tassets.push(asset)\n\t\t\t\t}\n\t\t\t})\n\t\t)\n\t\tcontent.assets = assets\n\n\t\treturn content\n\t}\n\n\t/**\n\t * Place content into the editor.\n\t *\n\t * @param content - The content.\n\t * @param options - Options for placing the content.\n\t *\n\t * @public\n\t */\n\tputContentOntoCurrentPage(\n\t\tcontent: TLContent,\n\t\toptions: {\n\t\t\tpoint?: VecLike\n\t\t\tselect?: boolean\n\t\t\tpreservePosition?: boolean\n\t\t\tpreserveIds?: boolean\n\t\t} = {}\n\t): this {\n\t\tif (this.getInstanceState().isReadonly) return this\n\n\t\t// todo: make this able to support putting content onto any page, not just the current page\n\n\t\tif (!content.schema) {\n\t\t\tthrow Error('Could not put content:\\ncontent is missing a schema.')\n\t\t}\n\n\t\tconst { select = false, preserveIds = false, preservePosition = false } = options\n\t\tlet { point = undefined } = options\n\n\t\t// decide on a parent for the put shapes; if the parent is among the put shapes(?) then use its parent\n\n\t\tconst currentPageId = this.getCurrentPageId()\n\t\tconst { rootShapeIds } = content\n\n\t\t// We need to collect the migrated records\n\t\tconst assets: TLAsset[] = []\n\t\tconst shapes: TLShape[] = []\n\t\tconst bindings: TLBinding[] = []\n\n\t\t// Let's treat the content as a store, and then migrate that store.\n\t\tconst store: StoreSnapshot = {\n\t\t\tstore: {\n\t\t\t\t...Object.fromEntries(content.assets.map((asset) => [asset.id, asset] as const)),\n\t\t\t\t...Object.fromEntries(content.shapes.map((shape) => [shape.id, shape] as const)),\n\t\t\t\t...Object.fromEntries(\n\t\t\t\t\tcontent.bindings?.map((bindings) => [bindings.id, bindings] as const) ?? []\n\t\t\t\t),\n\t\t\t},\n\t\t\tschema: content.schema,\n\t\t}\n\t\tconst result = this.store.schema.migrateStoreSnapshot(store)\n\t\tif (result.type === 'error') {\n\t\t\tthrow Error('Could not put content: could not migrate content')\n\t\t}\n\t\tfor (const record of Object.values(result.value)) {\n\t\t\tswitch (record.typeName) {\n\t\t\t\tcase 'asset': {\n\t\t\t\t\tassets.push(record)\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase 'shape': {\n\t\t\t\t\tshapes.push(record)\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase 'binding': {\n\t\t\t\t\tbindings.push(record)\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Ok, we've got our migrated records, now we can continue!\n\t\tconst shapeIdMap = new Map(\n\t\t\tpreserveIds\n\t\t\t\t? shapes.map((shape) => [shape.id, shape.id])\n\t\t\t\t: shapes.map((shape) => [shape.id, createShapeId()])\n\t\t)\n\t\tconst bindingIdMap = new Map(\n\t\t\tpreserveIds\n\t\t\t\t? bindings.map((binding) => [binding.id, binding.id])\n\t\t\t\t: bindings.map((binding) => [binding.id, createBindingId()])\n\t\t)\n\n\t\t// By default, the paste parent will be the current page.\n\t\tlet pasteParentId = this.getCurrentPageId() as TLPageId | TLShapeId\n\t\tlet lowestDepth = Infinity\n\t\tlet lowestAncestors: TLShape[] = []\n\n\t\t// Among the selected shapes, find the shape with the fewest ancestors and use its first ancestor.\n\t\tfor (const shape of this.getSelectedShapes()) {\n\t\t\tif (lowestDepth === 0) break\n\n\t\t\tconst isFrame = this.isShapeOfType(shape, 'frame')\n\t\t\tconst ancestors = this.getShapeAncestors(shape)\n\t\t\tif (isFrame) ancestors.push(shape)\n\n\t\t\tconst depth = isFrame ? ancestors.length + 1 : ancestors.length\n\n\t\t\tif (depth < lowestDepth) {\n\t\t\t\tlowestDepth = depth\n\t\t\t\tlowestAncestors = ancestors\n\t\t\t\tpasteParentId = isFrame ? shape.id : shape.parentId\n\t\t\t} else if (depth === lowestDepth) {\n\t\t\t\tif (lowestAncestors.length !== ancestors.length) {\n\t\t\t\t\tthrow Error(`Ancestors: ${lowestAncestors.length} !== ${ancestors.length}`)\n\t\t\t\t}\n\n\t\t\t\tif (lowestAncestors.length === 0) {\n\t\t\t\t\tpasteParentId = currentPageId\n\t\t\t\t\tbreak\n\t\t\t\t} else {\n\t\t\t\t\tpasteParentId = currentPageId\n\t\t\t\t\tfor (let i = 0; i < lowestAncestors.length; i++) {\n\t\t\t\t\t\tif (ancestors[i] !== lowestAncestors[i]) break\n\t\t\t\t\t\tpasteParentId = ancestors[i].id\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tlet isDuplicating = false\n\n\t\tif (!isPageId(pasteParentId)) {\n\t\t\tconst parent = this.getShape(pasteParentId)\n\t\t\tif (parent) {\n\t\t\t\tif (!this.getViewportPageBounds().includes(this.getShapePageBounds(parent)!)) {\n\t\t\t\t\tpasteParentId = currentPageId\n\t\t\t\t} else {\n\t\t\t\t\tif (rootShapeIds.length === 1) {\n\t\t\t\t\t\tconst rootShape = shapes.find((s) => s.id === rootShapeIds[0])!\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\tthis.isShapeOfType(parent, 'frame') &&\n\t\t\t\t\t\t\tthis.isShapeOfType(rootShape, 'frame') &&\n\t\t\t\t\t\t\trootShape.props.w === parent?.props.w &&\n\t\t\t\t\t\t\trootShape.props.h === parent?.props.h\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\tisDuplicating = true\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tpasteParentId = currentPageId\n\t\t\t}\n\t\t}\n\n\t\tif (!isDuplicating) {\n\t\t\tisDuplicating = shapeIdMap.has(pasteParentId)\n\t\t}\n\n\t\tif (isDuplicating) {\n\t\t\tpasteParentId = this.getShape(pasteParentId)!.parentId\n\t\t}\n\n\t\tlet index = this.getHighestIndexForParent(pasteParentId) // todo: requires that the putting page is the current page\n\n\t\tconst rootShapes: TLShape[] = []\n\n\t\tconst newShapes: TLShape[] = shapes.map((oldShape): TLShape => {\n\t\t\tconst newId = shapeIdMap.get(oldShape.id)!\n\n\t\t\t// Create the new shape (new except for the id)\n\t\t\tconst newShape = { ...oldShape, id: newId }\n\n\t\t\tif (rootShapeIds.includes(oldShape.id)) {\n\t\t\t\tnewShape.parentId = currentPageId\n\t\t\t\trootShapes.push(newShape)\n\t\t\t}\n\n\t\t\t// Assign the child to its new parent.\n\n\t\t\t// If the child's parent is among the putting shapes, then assign\n\t\t\t// it to the new parent's id.\n\t\t\tif (shapeIdMap.has(newShape.parentId)) {\n\t\t\t\tnewShape.parentId = shapeIdMap.get(oldShape.parentId)!\n\t\t\t} else {\n\t\t\t\trootShapeIds.push(newShape.id)\n\t\t\t\t// newShape.parentId = pasteParentId\n\t\t\t\tnewShape.index = index\n\t\t\t\tindex = getIndexAbove(index)\n\t\t\t}\n\n\t\t\treturn newShape\n\t\t})\n\n\t\tif (newShapes.length + this.getCurrentPageShapeIds().size > this.options.maxShapesPerPage) {\n\t\t\t// There's some complexity here involving children\n\t\t\t// that might be created without their parents, so\n\t\t\t// if we're going over the limit then just don't paste.\n\t\t\talertMaxShapes(this)\n\t\t\treturn this\n\t\t}\n\n\t\tconst newBindings = bindings.map(\n\t\t\t(oldBinding): TLBinding => ({\n\t\t\t\t...oldBinding,\n\t\t\t\tid: assertExists(bindingIdMap.get(oldBinding.id)),\n\t\t\t\tfromId: assertExists(shapeIdMap.get(oldBinding.fromId)),\n\t\t\t\ttoId: assertExists(shapeIdMap.get(oldBinding.toId)),\n\t\t\t})\n\t\t)\n\n\t\t// These are all the assets we need to create\n\t\tconst assetsToCreate: TLAsset[] = []\n\n\t\t// These assets have base64 data that may need to be hosted\n\t\tconst assetsToUpdate: (TLImageAsset | TLVideoAsset)[] = []\n\n\t\tfor (const asset of assets) {\n\t\t\tif (this.store.has(asset.id)) {\n\t\t\t\t// We already have this asset\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tif (\n\t\t\t\t(asset.type === 'image' || asset.type === 'video') &&\n\t\t\t\tasset.props.src?.startsWith('data:image')\n\t\t\t) {\n\t\t\t\t// it's src is a base64 image or video; we need to create a new asset without the src,\n\t\t\t\t// then create a new asset from the original src. So we save a copy of the original asset,\n\t\t\t\t// then delete the src from the original asset.\n\t\t\t\tassetsToUpdate.push(structuredClone(asset as TLImageAsset | TLVideoAsset))\n\t\t\t\tasset.props.src = null\n\t\t\t}\n\n\t\t\t// Add the asset to the list of assets to create\n\t\t\tassetsToCreate.push(asset)\n\t\t}\n\n\t\t// Start loading the new assets, order does not matter\n\t\tPromise.allSettled(\n\t\t\t(assetsToUpdate as (TLImageAsset | TLVideoAsset)[]).map(async (asset) => {\n\t\t\t\t// Turn the data url into a file\n\t\t\t\tconst file = await dataUrlToFile(\n\t\t\t\t\tasset.props.src!,\n\t\t\t\t\tasset.props.name,\n\t\t\t\t\tasset.props.mimeType ?? 'image/png'\n\t\t\t\t)\n\n\t\t\t\t// Get a new asset for the file\n\t\t\t\tconst newAsset = await this.getAssetForExternalContent({\n\t\t\t\t\ttype: 'file',\n\t\t\t\t\tfile,\n\t\t\t\t\tassetId: asset.id,\n\t\t\t\t})\n\n\t\t\t\tif (!newAsset) {\n\t\t\t\t\t// If we don't have a new asset, delete the old asset.\n\t\t\t\t\t// The shapes that reference this asset should break.\n\t\t\t\t\tthis.deleteAssets([asset.id])\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\t// Save the new asset under the old asset's id\n\t\t\t\tthis.updateAssets([{ ...newAsset, id: asset.id }])\n\t\t\t})\n\t\t)\n\n\t\tthis.run(() => {\n\t\t\t// Create any assets that need to be created\n\t\t\tif (assetsToCreate.length > 0) {\n\t\t\t\tthis.createAssets(assetsToCreate)\n\t\t\t}\n\n\t\t\t// Create the shapes with root shapes as children of the page\n\t\t\tthis.createShapes(newShapes)\n\t\t\tthis.createBindings(newBindings)\n\n\t\t\tif (select) {\n\t\t\t\tthis.select(...rootShapes.map((s) => s.id))\n\t\t\t}\n\n\t\t\t// And then, if needed, reparent the root shapes to the paste parent\n\t\t\tif (pasteParentId !== currentPageId) {\n\t\t\t\tthis.reparentShapes(\n\t\t\t\t\trootShapes.map((s) => s.id),\n\t\t\t\t\tpasteParentId\n\t\t\t\t)\n\t\t\t}\n\n\t\t\tconst newCreatedShapes = newShapes.map((s) => this.getShape(s.id)!)\n\t\t\tconst bounds = Box.Common(newCreatedShapes.map((s) => this.getShapePageBounds(s)!))\n\n\t\t\tif (point === undefined) {\n\t\t\t\tif (!isPageId(pasteParentId)) {\n\t\t\t\t\t// Put the shapes in the middle of the (on screen) parent\n\t\t\t\t\tconst shape = this.getShape(pasteParentId)!\n\t\t\t\t\tpoint = Mat.applyToPoint(\n\t\t\t\t\t\tthis.getShapePageTransform(shape),\n\t\t\t\t\t\tthis.getShapeGeometry(shape).bounds.center\n\t\t\t\t\t)\n\t\t\t\t} else {\n\t\t\t\t\tconst viewportPageBounds = this.getViewportPageBounds()\n\t\t\t\t\tif (preservePosition || viewportPageBounds.includes(Box.From(bounds))) {\n\t\t\t\t\t\t// Otherwise, put shapes where they used to be\n\t\t\t\t\t\tpoint = bounds.center\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// If the old bounds are outside of the viewport...\n\t\t\t\t\t\t// put the shapes in the middle of the viewport\n\t\t\t\t\t\tpoint = viewportPageBounds.center\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (rootShapes.length === 1) {\n\t\t\t\tconst onlyRoot = rootShapes[0] as TLFrameShape\n\t\t\t\t// If the old bounds are in the viewport...\n\t\t\t\tif (this.isShapeOfType(onlyRoot, 'frame')) {\n\t\t\t\t\twhile (\n\t\t\t\t\t\tthis.getShapesAtPoint(point).some(\n\t\t\t\t\t\t\t(shape) =>\n\t\t\t\t\t\t\t\tthis.isShapeOfType(shape, 'frame') &&\n\t\t\t\t\t\t\t\tshape.props.w === onlyRoot.props.w &&\n\t\t\t\t\t\t\t\tshape.props.h === onlyRoot.props.h\n\t\t\t\t\t\t)\n\t\t\t\t\t) {\n\t\t\t\t\t\tpoint.x += bounds.w + 16\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst pageCenter = Box.Common(\n\t\t\t\tcompact(rootShapes.map(({ id }) => this.getShapePageBounds(id)))\n\t\t\t).center\n\n\t\t\tconst offset = Vec.Sub(point, pageCenter)\n\n\t\t\tthis.updateShapes(\n\t\t\t\trootShapes.map(({ id }) => {\n\t\t\t\t\tconst s = this.getShape(id)!\n\t\t\t\t\tconst localRotation = this.getShapeParentTransform(id).decompose().rotation\n\t\t\t\t\tconst localDelta = Vec.Rot(offset, -localRotation)\n\n\t\t\t\t\treturn { id: s.id, type: s.type, x: s.x + localDelta.x, y: s.y + localDelta.y }\n\t\t\t\t})\n\t\t\t)\n\t\t})\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Get an exported SVG element of the given shapes.\n\t *\n\t * @param ids - The shapes (or shape ids) to export.\n\t * @param opts - Options for the export.\n\t *\n\t * @returns The SVG element.\n\t *\n\t * @public\n\t */\n\tasync getSvgElement(shapes: TLShapeId[] | TLShape[], opts: TLImageExportOptions = {}) {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\n\t\tif (ids.length === 0) return undefined\n\n\t\treturn exportToSvg(this, ids, opts)\n\t}\n\n\t/**\n\t * Get an exported SVG string of the given shapes.\n\t *\n\t * @param ids - The shapes (or shape ids) to export.\n\t * @param opts - Options for the export.\n\t *\n\t * @returns The SVG element.\n\t *\n\t * @public\n\t */\n\tasync getSvgString(shapes: TLShapeId[] | TLShape[], opts: TLImageExportOptions = {}) {\n\t\tconst result = await this.getSvgElement(shapes, opts)\n\t\tif (!result) return undefined\n\n\t\tconst serializer = new XMLSerializer()\n\t\treturn {\n\t\t\tsvg: serializer.serializeToString(result.svg),\n\t\t\twidth: result.width,\n\t\t\theight: result.height,\n\t\t}\n\t}\n\n\t/** @deprecated Use {@link Editor.getSvgString} or {@link Editor.getSvgElement} instead. */\n\tasync getSvg(shapes: TLShapeId[] | TLShape[], opts: TLImageExportOptions = {}) {\n\t\tconst result = await this.getSvgElement(shapes, opts)\n\t\tif (!result) return undefined\n\t\treturn result.svg\n\t}\n\n\t/* --------------------- Events --------------------- */\n\n\t/**\n\t * The app's current input state.\n\t *\n\t * @public\n\t */\n\tinputs = {\n\t\t/** The most recent pointer down's position in the current page space. */\n\t\toriginPagePoint: new Vec(),\n\t\t/** The most recent pointer down's position in screen space. */\n\t\toriginScreenPoint: new Vec(),\n\t\t/** The previous pointer position in the current page space. */\n\t\tpreviousPagePoint: new Vec(),\n\t\t/** The previous pointer position in screen space. */\n\t\tpreviousScreenPoint: new Vec(),\n\t\t/** The most recent pointer position in the current page space. */\n\t\tcurrentPagePoint: new Vec(),\n\t\t/** The most recent pointer position in screen space. */\n\t\tcurrentScreenPoint: new Vec(),\n\t\t/** A set containing the currently pressed keys. */\n\t\tkeys: new Set(),\n\t\t/** A set containing the currently pressed buttons. */\n\t\tbuttons: new Set(),\n\t\t/** Whether the input is from a pe. */\n\t\tisPen: false,\n\t\t/** Whether the shift key is currently pressed. */\n\t\tshiftKey: false,\n\t\t/** Whether the control or command key is currently pressed. */\n\t\tctrlKey: false,\n\t\t/** Whether the alt or option key is currently pressed. */\n\t\taltKey: false,\n\t\t/** Whether the user is dragging. */\n\t\tisDragging: false,\n\t\t/** Whether the user is pointing. */\n\t\tisPointing: false,\n\t\t/** Whether the user is pinching. */\n\t\tisPinching: false,\n\t\t/** Whether the user is editing. */\n\t\tisEditing: false,\n\t\t/** Whether the user is panning. */\n\t\tisPanning: false,\n\t\t/** Whether the user is spacebar panning. */\n\t\tisSpacebarPanning: false,\n\t\t/** Velocity of mouse pointer, in pixels per millisecond */\n\t\tpointerVelocity: new Vec(),\n\t}\n\n\t/**\n\t * Update the input points from a pointer, pinch, or wheel event.\n\t *\n\t * @param info - The event info.\n\t */\n\tprivate _updateInputsFromEvent(\n\t\tinfo: TLPointerEventInfo | TLPinchEventInfo | TLWheelEventInfo\n\t): void {\n\t\tconst {\n\t\t\tpointerVelocity,\n\t\t\tpreviousScreenPoint,\n\t\t\tpreviousPagePoint,\n\t\t\tcurrentScreenPoint,\n\t\t\tcurrentPagePoint,\n\t\t} = this.inputs\n\n\t\tconst { screenBounds } = this.store.unsafeGetWithoutCapture(TLINSTANCE_ID)!\n\t\tconst { x: cx, y: cy, z: cz } = unsafe__withoutCapture(() => this.getCamera())\n\n\t\tconst sx = info.point.x - screenBounds.x\n\t\tconst sy = info.point.y - screenBounds.y\n\t\tconst sz = info.point.z ?? 0.5\n\n\t\tpreviousScreenPoint.setTo(currentScreenPoint)\n\t\tpreviousPagePoint.setTo(currentPagePoint)\n\n\t\t// The \"screen bounds\" is relative to the user's actual screen.\n\t\t// The \"screen point\" is relative to the \"screen bounds\";\n\t\t// it will be 0,0 when its actual screen position is equal\n\t\t// to screenBounds.point. This is confusing!\n\t\tcurrentScreenPoint.set(sx, sy)\n\t\tconst nx = sx / cz - cx\n\t\tconst ny = sy / cz - cy\n\t\tif (isFinite(nx) && isFinite(ny)) {\n\t\t\tcurrentPagePoint.set(nx, ny, sz)\n\t\t}\n\n\t\tthis.inputs.isPen = info.type === 'pointer' && info.isPen\n\n\t\t// Reset velocity on pointer down, or when a pinch starts or ends\n\t\tif (info.name === 'pointer_down' || this.inputs.isPinching) {\n\t\t\tpointerVelocity.set(0, 0)\n\t\t\tthis.inputs.originScreenPoint.setTo(currentScreenPoint)\n\t\t\tthis.inputs.originPagePoint.setTo(currentPagePoint)\n\t\t}\n\n\t\t// todo: We only have to do this if there are multiple users in the document\n\t\tthis.run(\n\t\t\t() => {\n\t\t\t\tthis.store.put([\n\t\t\t\t\t{\n\t\t\t\t\t\tid: TLPOINTER_ID,\n\t\t\t\t\t\ttypeName: 'pointer',\n\t\t\t\t\t\tx: currentPagePoint.x,\n\t\t\t\t\t\ty: currentPagePoint.y,\n\t\t\t\t\t\tlastActivityTimestamp:\n\t\t\t\t\t\t\t// If our pointer moved only because we're following some other user, then don't\n\t\t\t\t\t\t\t// update our last activity timestamp; otherwise, update it to the current timestamp.\n\t\t\t\t\t\t\tinfo.type === 'pointer' && info.pointerId === INTERNAL_POINTER_IDS.CAMERA_MOVE\n\t\t\t\t\t\t\t\t? this.store.unsafeGetWithoutCapture(TLPOINTER_ID)?.lastActivityTimestamp ??\n\t\t\t\t\t\t\t\t\tthis._tickManager.now\n\t\t\t\t\t\t\t\t: this._tickManager.now,\n\t\t\t\t\t\tmeta: {},\n\t\t\t\t\t},\n\t\t\t\t])\n\t\t\t},\n\t\t\t{ history: 'ignore' }\n\t\t)\n\t}\n\n\t/**\n\t * Dispatch a cancel event.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.cancel()\n\t * ```\n\t *\n\t * @public\n\t */\n\tcancel(): this {\n\t\tthis.dispatch({ type: 'misc', name: 'cancel' })\n\t\treturn this\n\t}\n\n\t/**\n\t * Dispatch an interrupt event.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.interrupt()\n\t * ```\n\t *\n\t * @public\n\t */\n\tinterrupt(): this {\n\t\tthis.dispatch({ type: 'misc', name: 'interrupt' })\n\t\treturn this\n\t}\n\n\t/**\n\t * Dispatch a complete event.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.complete()\n\t * ```\n\t *\n\t * @public\n\t */\n\tcomplete(): this {\n\t\tthis.dispatch({ type: 'misc', name: 'complete' })\n\t\treturn this\n\t}\n\n\t/**\n\t * Puts the editor into focused mode.\n\t *\n\t * This makes the editor eligible to receive keyboard events and some pointer events (move, wheel).\n\t *\n\t * @example\n\t * ```ts\n\t * editor.focus()\n\t * ```\n\t *\n\t * By default this also dispatches a 'focus' event to the container element. To prevent this, pass `focusContainer: false`.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.focus({ focusContainer: false })\n\t * ```\n\t *\n\t * @public\n\t */\n\tfocus({ focusContainer = true } = {}): this {\n\t\tif (this.getIsFocused()) return this\n\t\tif (focusContainer) this.focusManager.focus()\n\t\tthis.updateInstanceState({ isFocused: true })\n\t\treturn this\n\t}\n\n\t/**\n\t * Switches off the editor's focused mode.\n\t *\n\t * This makes the editor ignore keyboard events and some pointer events (move, wheel).\n\t *\n\t * @example\n\t * ```ts\n\t * editor.blur()\n\t * ```\n\t * By default this also dispatches a 'blur' event to the container element. To prevent this, pass `blurContainer: false`.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.blur({ blurContainer: false })\n\t * ```\n\t *\n\t * @public\n\t */\n\tblur({ blurContainer = true } = {}): this {\n\t\tif (!this.getIsFocused()) return this\n\t\tif (blurContainer) {\n\t\t\tthis.focusManager.blur()\n\t\t} else {\n\t\t\tthis.complete() // stop any interaction\n\t\t}\n\t\tthis.updateInstanceState({ isFocused: false })\n\t\treturn this\n\t}\n\n\t/**\n\t * @public\n\t * @returns true if the editor is focused\n\t */\n\t@computed getIsFocused() {\n\t\treturn this.getInstanceState().isFocused\n\t}\n\n\t/**\n\t * @public\n\t * @returns a snapshot of the store's UI and document state\n\t */\n\tgetSnapshot() {\n\t\treturn getSnapshot(this.store)\n\t}\n\n\t/**\n\t * Loads a snapshot into the editor.\n\t * @param snapshot - the snapshot to load\n\t * @returns\n\t */\n\tloadSnapshot(\n\t\tsnapshot: Partial | TLStoreSnapshot,\n\t\topts?: TLLoadSnapshotOptions\n\t) {\n\t\tloadSnapshot(this.store, snapshot, opts)\n\t\treturn this\n\t}\n\n\tprivate _zoomToFitPageContentAt100Percent() {\n\t\tconst bounds = this.getCurrentPageBounds()\n\t\tif (bounds) {\n\t\t\tthis.zoomToBounds(bounds, { immediate: true, targetZoom: this.getBaseZoom() })\n\t\t}\n\t}\n\tprivate _navigateToDeepLink(deepLink: TLDeepLink) {\n\t\tthis.run(() => {\n\t\t\tswitch (deepLink.type) {\n\t\t\t\tcase 'page': {\n\t\t\t\t\tconst page = this.getPage(deepLink.pageId)\n\t\t\t\t\tif (page) {\n\t\t\t\t\t\tthis.setCurrentPage(page)\n\t\t\t\t\t}\n\t\t\t\t\tthis._zoomToFitPageContentAt100Percent()\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tcase 'shapes': {\n\t\t\t\t\tconst allShapes = compact(deepLink.shapeIds.map((id) => this.getShape(id)))\n\t\t\t\t\tconst byPage: { [pageId: string]: TLShape[] } = {}\n\t\t\t\t\tfor (const shape of allShapes) {\n\t\t\t\t\t\tconst pageId = this.getAncestorPageId(shape)\n\t\t\t\t\t\tif (!pageId) continue\n\t\t\t\t\t\tbyPage[pageId] ??= []\n\t\t\t\t\t\tbyPage[pageId].push(shape)\n\t\t\t\t\t}\n\t\t\t\t\tconst [pageId, shapes] = Object.entries(byPage).sort(\n\t\t\t\t\t\t([_, a], [__, b]) => b.length - a.length\n\t\t\t\t\t)[0] ?? ['', []]\n\n\t\t\t\t\tif (!pageId || !shapes.length) {\n\t\t\t\t\t\tthis._zoomToFitPageContentAt100Percent()\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthis.setCurrentPage(pageId as TLPageId)\n\t\t\t\t\t\tconst bounds = Box.Common(shapes.map((s) => this.getShapePageBounds(s)!))\n\t\t\t\t\t\tthis.zoomToBounds(bounds, { immediate: true, targetZoom: this.getBaseZoom() })\n\t\t\t\t\t}\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tcase 'viewport': {\n\t\t\t\t\tif (deepLink.pageId) {\n\t\t\t\t\t\tif (!this.getPage(deepLink.pageId)) {\n\t\t\t\t\t\t\tthis._zoomToFitPageContentAt100Percent()\n\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t}\n\t\t\t\t\t\tthis.setCurrentPage(deepLink.pageId)\n\t\t\t\t\t}\n\t\t\t\t\tthis.zoomToBounds(deepLink.bounds, { immediate: true, inset: 0 })\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tdefault:\n\t\t\t\t\texhaustiveSwitchError(deepLink)\n\t\t\t}\n\t\t})\n\t}\n\n\t/**\n\t * Handles navigating to the content specified by the query param in the given URL.\n\t *\n\t * Use {@link Editor#createDeepLink} to create a URL with a deep link query param.\n\t *\n\t * If no URL is provided, it will look for the param in the current `window.location.href`.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.navigateToDeepLink()\n\t * ```\n\t *\n\t * The default parameter name is 'd'. You can override this by providing the `param` option.\n\t *\n\t * @example\n\t * ```ts\n\t * // disable page parameter and change viewport parameter to 'c'\n\t * editor.navigateToDeepLink({\n\t * param: 'x',\n\t * url: 'https://my-app.com/my-document?x=200.12.454.23.xyz123',\n\t * })\n\t * ```\n\t *\n\t * @param opts - Options for loading the state from the URL.\n\t */\n\tnavigateToDeepLink(opts?: TLDeepLink | { url?: string | URL; param?: string }): Editor {\n\t\tif (opts && 'type' in opts) {\n\t\t\tthis._navigateToDeepLink(opts)\n\t\t\treturn this\n\t\t}\n\n\t\tconst url = new URL(opts?.url ?? window.location.href)\n\t\tconst deepLinkString = url.searchParams.get(opts?.param ?? 'd')\n\n\t\tif (!deepLinkString) {\n\t\t\tthis._zoomToFitPageContentAt100Percent()\n\t\t\treturn this\n\t\t}\n\n\t\ttry {\n\t\t\tthis._navigateToDeepLink(parseDeepLinkString(deepLinkString))\n\t\t} catch (e) {\n\t\t\tconsole.warn(e)\n\t\t\tthis._zoomToFitPageContentAt100Percent()\n\t\t}\n\t\treturn this\n\t}\n\n\t/**\n\t * Turns the given URL into a deep link by adding a query parameter.\n\t *\n\t * e.g. `https://my-app.com/my-document?d=100.100.200.200.xyz123`\n\t *\n\t * If no URL is provided, it will use the current `window.location.href`.\n\t *\n\t * @example\n\t * ```ts\n\t * // create a deep link to the current page + viewport\n\t * navigator.clipboard.writeText(editor.createDeepLink())\n\t * ```\n\t *\n\t * You can link to a particular set of shapes by providing a `to` parameter.\n\t *\n\t * @example\n\t * ```ts\n\t * // create a deep link to the set of currently selected shapes\n\t * navigator.clipboard.writeText(editor.createDeepLink({\n\t * to: { type: 'selection', shapeIds: editor.getSelectedShapeIds() }\n\t * }))\n\t * ```\n\t *\n\t * The default query param is 'd'. You can override this by providing a `param` parameter.\n\t *\n\t * @example\n\t * ```ts\n\t * // Use `x` as the param name instead\n\t * editor.createDeepLink({ param: 'x' })\n\t * ```\n\t *\n\t * @param opts - Options for adding the state to the URL.\n\t * @returns the updated URL\n\t */\n\tcreateDeepLink(opts?: { url?: string | URL; param?: string; to?: TLDeepLink }): URL {\n\t\tconst url = new URL(opts?.url ?? window.location.href)\n\n\t\turl.searchParams.set(\n\t\t\topts?.param ?? 'd',\n\t\t\tcreateDeepLinkString(\n\t\t\t\topts?.to ?? {\n\t\t\t\t\ttype: 'viewport',\n\t\t\t\t\tpageId: this.options.maxPages === 1 ? undefined : this.getCurrentPageId(),\n\t\t\t\t\tbounds: this.getViewportPageBounds(),\n\t\t\t\t}\n\t\t\t)\n\t\t)\n\n\t\treturn url\n\t}\n\n\t/**\n\t * Register a listener for changes to a deep link for the current document.\n\t *\n\t * You'll typically want to use this indirectly via the {@link TldrawEditorBaseProps.deepLinks} prop on the `` component.\n\t *\n\t * By default this will update `window.location` in place, but you can provide a custom callback\n\t * to handle state changes on your own.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.registerDeepLinkListener({\n\t * onChange(url) {\n\t * window.history.replaceState({}, document.title, url.toString())\n\t * }\n\t * })\n\t * ```\n\t *\n\t * You can also provide a custom URL to update, in which case you must also provide `onChange`.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.registerDeepLinkListener({\n\t * getUrl: () => `https://my-app.com/my-document`,\n\t * onChange(url) {\n\t * setShareUrl(url.toString())\n\t * }\n\t * })\n\t * ```\n\t *\n\t * By default this will update with a debounce interval of 500ms, but you can provide a custom interval.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.registerDeepLinkListener({ debounceMs: 1000 })\n\t * ```\n\t * The default parameter name is `d`. You can override this by providing a `param` option.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.registerDeepLinkListener({ param: 'x' })\n\t * ```\n\t * @param opts - Options for setting up the listener.\n\t * @returns a function that will stop the listener.\n\t */\n\tregisterDeepLinkListener(opts?: TLDeepLinkOptions): () => void {\n\t\tif (opts?.getUrl && !opts?.onChange) {\n\t\t\tthrow Error(\n\t\t\t\t'[tldraw:urlStateSync] If you specify getUrl, you must also specify the onChange callback.'\n\t\t\t)\n\t\t}\n\n\t\tconst url$ = computed('url with state', () => {\n\t\t\tconst url = opts?.getUrl?.(this) ?? window.location.href\n\t\t\tconst urlWithState = this.createDeepLink({\n\t\t\t\tparam: opts?.param,\n\t\t\t\turl,\n\t\t\t\tto: opts?.getTarget?.(this),\n\t\t\t})\n\t\t\treturn urlWithState.toString()\n\t\t})\n\n\t\tconst announceChange =\n\t\t\topts?.onChange ??\n\t\t\t(() => {\n\t\t\t\tconst url = this.createDeepLink({\n\t\t\t\t\tparam: opts?.param,\n\t\t\t\t\tto: opts?.getTarget?.(this),\n\t\t\t\t})\n\n\t\t\t\twindow.history.replaceState({}, document.title, url.toString())\n\t\t\t})\n\n\t\tconst scheduleEffect = debounce((execute: () => void) => execute(), opts?.debounceMs ?? 500)\n\n\t\tconst unlisten = react(\n\t\t\t'update url on state change',\n\t\t\t() => announceChange(new URL(url$.get()), this),\n\t\t\t{ scheduleEffect }\n\t\t)\n\n\t\treturn () => {\n\t\t\tunlisten()\n\t\t\tscheduleEffect.cancel()\n\t\t}\n\t}\n\n\t/**\n\t * A manager for recording multiple click events.\n\t *\n\t * @internal\n\t */\n\tprotected _clickManager = new ClickManager(this)\n\n\t/**\n\t * Prevent a double click event from firing the next time the user clicks\n\t *\n\t * @public\n\t */\n\tcancelDoubleClick() {\n\t\tthis._clickManager.cancelDoubleClickTimeout()\n\t}\n\n\t/**\n\t * The previous cursor. Used for restoring the cursor after pan events.\n\t *\n\t * @internal\n\t */\n\tprivate _prevCursor: TLCursorType = 'default'\n\n\t/** @internal */\n\tprivate _shiftKeyTimeout = -1 as any\n\n\t/** @internal */\n\t@bind\n\t_setShiftKeyTimeout() {\n\t\tthis.inputs.shiftKey = false\n\t\tthis.dispatch({\n\t\t\ttype: 'keyboard',\n\t\t\tname: 'key_up',\n\t\t\tkey: 'Shift',\n\t\t\tshiftKey: this.inputs.shiftKey,\n\t\t\tctrlKey: this.inputs.ctrlKey,\n\t\t\taltKey: this.inputs.altKey,\n\t\t\tcode: 'ShiftLeft',\n\t\t})\n\t}\n\n\t/** @internal */\n\tprivate _altKeyTimeout = -1 as any\n\n\t/** @internal */\n\t@bind\n\t_setAltKeyTimeout() {\n\t\tthis.inputs.altKey = false\n\t\tthis.dispatch({\n\t\t\ttype: 'keyboard',\n\t\t\tname: 'key_up',\n\t\t\tkey: 'Alt',\n\t\t\tshiftKey: this.inputs.shiftKey,\n\t\t\tctrlKey: this.inputs.ctrlKey,\n\t\t\taltKey: this.inputs.altKey,\n\t\t\tcode: 'AltLeft',\n\t\t})\n\t}\n\n\t/** @internal */\n\tprivate _ctrlKeyTimeout = -1 as any\n\n\t/** @internal */\n\t@bind\n\t_setCtrlKeyTimeout() {\n\t\tthis.inputs.ctrlKey = false\n\t\tthis.dispatch({\n\t\t\ttype: 'keyboard',\n\t\t\tname: 'key_up',\n\t\t\tkey: 'Ctrl',\n\t\t\tshiftKey: this.inputs.shiftKey,\n\t\t\tctrlKey: this.inputs.ctrlKey,\n\t\t\taltKey: this.inputs.altKey,\n\t\t\tcode: 'ControlLeft',\n\t\t})\n\t}\n\n\t/** @internal */\n\tprivate _restoreToolId = 'select'\n\n\t/** @internal */\n\tprivate _pinchStart = 1\n\n\t/** @internal */\n\tprivate _didPinch = false\n\n\t/** @internal */\n\tprivate _selectedShapeIdsAtPointerDown: TLShapeId[] = []\n\n\t/** @internal */\n\tprivate _longPressTimeout = -1 as any\n\n\t/** @internal */\n\tcapturedPointerId: number | null = null\n\n\t/** @internal */\n\tprivate readonly performanceTracker: PerformanceTracker\n\n\t/** @internal */\n\tprivate performanceTrackerTimeout = -1 as any\n\n\t/**\n\t * Dispatch an event to the editor.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.dispatch(myPointerEvent)\n\t * ```\n\t *\n\t * @param info - The event info.\n\t *\n\t * @public\n\t */\n\tdispatch(info: TLEventInfo) {\n\t\tthis._pendingEventsForNextTick.push(info)\n\t\tif (\n\t\t\t!(\n\t\t\t\t(info.type === 'pointer' && info.name === 'pointer_move') ||\n\t\t\t\tinfo.type === 'wheel' ||\n\t\t\t\tinfo.type === 'pinch'\n\t\t\t)\n\t\t) {\n\t\t\tthis._flushEventsForTick(0)\n\t\t}\n\t\treturn this\n\t}\n\n\tprivate _pendingEventsForNextTick: TLEventInfo[] = []\n\n\tprivate _flushEventsForTick(elapsed: number) {\n\t\tthis.run(() => {\n\t\t\tif (this._pendingEventsForNextTick.length > 0) {\n\t\t\t\tconst events = [...this._pendingEventsForNextTick]\n\t\t\t\tthis._pendingEventsForNextTick.length = 0\n\t\t\t\tfor (const info of events) {\n\t\t\t\t\tthis._flushEventForTick(info)\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (elapsed > 0) {\n\t\t\t\tthis.root.handleEvent({ type: 'misc', name: 'tick', elapsed })\n\t\t\t}\n\t\t\tthis.scribbles.tick(elapsed)\n\t\t})\n\t}\n\n\t_flushEventForTick(info: TLEventInfo) {\n\t\t// prevent us from spamming similar event errors if we're crashed.\n\t\t// todo: replace with new readonly mode?\n\t\tif (this.getCrashingError()) return this\n\n\t\tconst { inputs } = this\n\t\tconst { type } = info\n\n\t\tif (info.type === 'misc') {\n\t\t\t// stop panning if the interaction is cancelled or completed\n\t\t\tif (info.name === 'cancel' || info.name === 'complete') {\n\t\t\t\tthis.inputs.isDragging = false\n\n\t\t\t\tif (this.inputs.isPanning) {\n\t\t\t\t\tthis.inputs.isPanning = false\n\t\t\t\t\tthis.inputs.isSpacebarPanning = false\n\t\t\t\t\tthis.setCursor({ type: this._prevCursor, rotation: 0 })\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tthis.root.handleEvent(info)\n\t\t\treturn\n\t\t}\n\n\t\tif (info.shiftKey) {\n\t\t\tclearTimeout(this._shiftKeyTimeout)\n\t\t\tthis._shiftKeyTimeout = -1\n\t\t\tinputs.shiftKey = true\n\t\t} else if (!info.shiftKey && inputs.shiftKey && this._shiftKeyTimeout === -1) {\n\t\t\tthis._shiftKeyTimeout = this.timers.setTimeout(this._setShiftKeyTimeout, 150)\n\t\t}\n\n\t\tif (info.altKey) {\n\t\t\tclearTimeout(this._altKeyTimeout)\n\t\t\tthis._altKeyTimeout = -1\n\t\t\tinputs.altKey = true\n\t\t} else if (!info.altKey && inputs.altKey && this._altKeyTimeout === -1) {\n\t\t\tthis._altKeyTimeout = this.timers.setTimeout(this._setAltKeyTimeout, 150)\n\t\t}\n\n\t\tif (info.ctrlKey) {\n\t\t\tclearTimeout(this._ctrlKeyTimeout)\n\t\t\tthis._ctrlKeyTimeout = -1\n\t\t\tinputs.ctrlKey = true\n\t\t} else if (!info.ctrlKey && inputs.ctrlKey && this._ctrlKeyTimeout === -1) {\n\t\t\tthis._ctrlKeyTimeout = this.timers.setTimeout(this._setCtrlKeyTimeout, 150)\n\t\t}\n\n\t\tconst { originPagePoint, currentPagePoint } = inputs\n\n\t\tif (!inputs.isPointing) {\n\t\t\tinputs.isDragging = false\n\t\t}\n\n\t\tconst instanceState = this.store.unsafeGetWithoutCapture(TLINSTANCE_ID)!\n\t\tconst pageState = this.store.get(this._getCurrentPageStateId())!\n\t\tconst cameraOptions = this._cameraOptions.__unsafe__getWithoutCapture()!\n\n\t\tswitch (type) {\n\t\t\tcase 'pinch': {\n\t\t\t\tif (cameraOptions.isLocked) return\n\t\t\t\tclearTimeout(this._longPressTimeout)\n\t\t\t\tthis._updateInputsFromEvent(info)\n\n\t\t\t\tswitch (info.name) {\n\t\t\t\t\tcase 'pinch_start': {\n\t\t\t\t\t\tif (inputs.isPinching) return\n\n\t\t\t\t\t\tif (!inputs.isEditing) {\n\t\t\t\t\t\t\tthis._pinchStart = this.getCamera().z\n\t\t\t\t\t\t\tif (!this._selectedShapeIdsAtPointerDown.length) {\n\t\t\t\t\t\t\t\tthis._selectedShapeIdsAtPointerDown = [...pageState.selectedShapeIds]\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tthis._didPinch = true\n\n\t\t\t\t\t\t\tinputs.isPinching = true\n\n\t\t\t\t\t\t\tthis.interrupt()\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\treturn // Stop here!\n\t\t\t\t\t}\n\t\t\t\t\tcase 'pinch': {\n\t\t\t\t\t\tif (!inputs.isPinching) return\n\n\t\t\t\t\t\tconst {\n\t\t\t\t\t\t\tpoint: { z = 1 },\n\t\t\t\t\t\t\tdelta: { x: dx, y: dy },\n\t\t\t\t\t\t} = info\n\n\t\t\t\t\t\t// The center of the pinch in screen space\n\t\t\t\t\t\tconst { x, y } = Vec.SubXY(\n\t\t\t\t\t\t\tinfo.point,\n\t\t\t\t\t\t\tinstanceState.screenBounds.x,\n\t\t\t\t\t\t\tinstanceState.screenBounds.y\n\t\t\t\t\t\t)\n\n\t\t\t\t\t\tthis.stopCameraAnimation()\n\t\t\t\t\t\tif (instanceState.followingUserId) {\n\t\t\t\t\t\t\tthis.stopFollowingUser()\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst { x: cx, y: cy, z: cz } = unsafe__withoutCapture(() => this.getCamera())\n\n\t\t\t\t\t\tconst { panSpeed, zoomSpeed } = cameraOptions\n\t\t\t\t\t\tthis._setCamera(\n\t\t\t\t\t\t\tnew Vec(\n\t\t\t\t\t\t\t\tcx + (dx * panSpeed) / cz - x / cz + x / (z * zoomSpeed),\n\t\t\t\t\t\t\t\tcy + (dy * panSpeed) / cz - y / cz + y / (z * zoomSpeed),\n\t\t\t\t\t\t\t\tz * zoomSpeed\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t{ immediate: true }\n\t\t\t\t\t\t)\n\n\t\t\t\t\t\treturn // Stop here!\n\t\t\t\t\t}\n\t\t\t\t\tcase 'pinch_end': {\n\t\t\t\t\t\tif (!inputs.isPinching) return this\n\n\t\t\t\t\t\t// Stop pinching\n\t\t\t\t\t\tinputs.isPinching = false\n\n\t\t\t\t\t\t// Stash and clear the shapes that were selected when the pinch started\n\t\t\t\t\t\tconst { _selectedShapeIdsAtPointerDown: shapesToReselect } = this\n\t\t\t\t\t\tthis.setSelectedShapes(this._selectedShapeIdsAtPointerDown)\n\t\t\t\t\t\tthis._selectedShapeIdsAtPointerDown = []\n\n\t\t\t\t\t\tif (this._didPinch) {\n\t\t\t\t\t\t\tthis._didPinch = false\n\t\t\t\t\t\t\tif (shapesToReselect.length > 0) {\n\t\t\t\t\t\t\t\tthis.once('tick', () => {\n\t\t\t\t\t\t\t\t\tif (!this._didPinch) {\n\t\t\t\t\t\t\t\t\t\t// Unless we've started pinching again...\n\t\t\t\t\t\t\t\t\t\t// Reselect the shapes that were selected when the pinch started\n\t\t\t\t\t\t\t\t\t\tthis.setSelectedShapes(shapesToReselect)\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\treturn // Stop here!\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tcase 'wheel': {\n\t\t\t\tif (cameraOptions.isLocked) return\n\n\t\t\t\tthis._updateInputsFromEvent(info)\n\n\t\t\t\tif (this.getIsMenuOpen()) {\n\t\t\t\t\t// noop\n\t\t\t\t} else {\n\t\t\t\t\tconst { panSpeed, zoomSpeed, wheelBehavior } = cameraOptions\n\n\t\t\t\t\tif (wheelBehavior !== 'none') {\n\t\t\t\t\t\t// Stop any camera animation\n\t\t\t\t\t\tthis.stopCameraAnimation()\n\t\t\t\t\t\t// Stop following any following user\n\t\t\t\t\t\tif (instanceState.followingUserId) {\n\t\t\t\t\t\t\tthis.stopFollowingUser()\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst { x: cx, y: cy, z: cz } = unsafe__withoutCapture(() => this.getCamera())\n\t\t\t\t\t\tconst { x: dx, y: dy, z: dz = 0 } = info.delta\n\n\t\t\t\t\t\tlet behavior = wheelBehavior\n\n\t\t\t\t\t\t// If the camera behavior is \"zoom\" and the ctrl key is pressed, then pan;\n\t\t\t\t\t\t// If the camera behavior is \"pan\" and the ctrl key is not pressed, then zoom\n\t\t\t\t\t\tif (inputs.ctrlKey) behavior = wheelBehavior === 'pan' ? 'zoom' : 'pan'\n\n\t\t\t\t\t\tswitch (behavior) {\n\t\t\t\t\t\t\tcase 'zoom': {\n\t\t\t\t\t\t\t\t// Zoom in on current screen point using the wheel delta\n\t\t\t\t\t\t\t\tconst { x, y } = this.inputs.currentScreenPoint\n\t\t\t\t\t\t\t\tlet delta = dz\n\n\t\t\t\t\t\t\t\t// If we're forcing zoom, then we need to do the wheel normalization math here\n\t\t\t\t\t\t\t\tif (wheelBehavior === 'zoom') {\n\t\t\t\t\t\t\t\t\tif (Math.abs(dy) > 10) {\n\t\t\t\t\t\t\t\t\t\tdelta = (10 * Math.sign(dy)) / 100\n\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\tdelta = dy / 100\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tconst zoom = cz + (delta ?? 0) * zoomSpeed * cz\n\t\t\t\t\t\t\t\tthis._setCamera(\n\t\t\t\t\t\t\t\t\tnew Vec(\n\t\t\t\t\t\t\t\t\t\tcx + (x / zoom - x) - (x / cz - x),\n\t\t\t\t\t\t\t\t\t\tcy + (y / zoom - y) - (y / cz - y),\n\t\t\t\t\t\t\t\t\t\tzoom\n\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t{ immediate: true }\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\tthis.maybeTrackPerformance('Zooming')\n\t\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tcase 'pan': {\n\t\t\t\t\t\t\t\t// Pan the camera based on the wheel delta\n\t\t\t\t\t\t\t\tthis._setCamera(new Vec(cx + (dx * panSpeed) / cz, cy + (dy * panSpeed) / cz, cz), {\n\t\t\t\t\t\t\t\t\timmediate: true,\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\tthis.maybeTrackPerformance('Panning')\n\t\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'pointer': {\n\t\t\t\t// Ignore pointer events while we're pinching\n\t\t\t\tif (inputs.isPinching) return\n\n\t\t\t\tthis._updateInputsFromEvent(info)\n\t\t\t\tconst { isPen } = info\n\t\t\t\tconst { isPenMode } = instanceState\n\n\t\t\t\tswitch (info.name) {\n\t\t\t\t\tcase 'pointer_down': {\n\t\t\t\t\t\t// If we're in pen mode and the input is not a pen type, then stop here\n\t\t\t\t\t\tif (isPenMode && !isPen) return\n\n\t\t\t\t\t\tif (!this.inputs.isPanning) {\n\t\t\t\t\t\t\t// Start a long press timeout\n\t\t\t\t\t\t\tthis._longPressTimeout = this.timers.setTimeout(() => {\n\t\t\t\t\t\t\t\tthis.dispatch({\n\t\t\t\t\t\t\t\t\t...info,\n\t\t\t\t\t\t\t\t\tpoint: this.inputs.currentScreenPoint,\n\t\t\t\t\t\t\t\t\tname: 'long_press',\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t}, this.options.longPressDurationMs)\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Save the selected ids at pointer down\n\t\t\t\t\t\tthis._selectedShapeIdsAtPointerDown = this.getSelectedShapeIds()\n\n\t\t\t\t\t\t// Firefox bug fix...\n\t\t\t\t\t\t// If it's a left-mouse-click, we store the pointer id for later user\n\t\t\t\t\t\tif (info.button === LEFT_MOUSE_BUTTON) this.capturedPointerId = info.pointerId\n\n\t\t\t\t\t\t// Add the button from the buttons set\n\t\t\t\t\t\tinputs.buttons.add(info.button)\n\n\t\t\t\t\t\t// Start pointing and stop dragging\n\t\t\t\t\t\tinputs.isPointing = true\n\t\t\t\t\t\tinputs.isDragging = false\n\n\t\t\t\t\t\t// If pen mode is off but we're not already in pen mode, turn that on\n\t\t\t\t\t\tif (!isPenMode && isPen) this.updateInstanceState({ isPenMode: true })\n\n\t\t\t\t\t\t// On devices with erasers (like the Surface Pen or Wacom Pen), button 5 is the eraser\n\t\t\t\t\t\tif (info.button === STYLUS_ERASER_BUTTON) {\n\t\t\t\t\t\t\tthis._restoreToolId = this.getCurrentToolId()\n\t\t\t\t\t\t\tthis.complete()\n\t\t\t\t\t\t\tthis.setCurrentTool('eraser')\n\t\t\t\t\t\t} else if (info.button === MIDDLE_MOUSE_BUTTON) {\n\t\t\t\t\t\t\t// Middle mouse pan activates panning unless we're already panning (with spacebar)\n\t\t\t\t\t\t\tif (!this.inputs.isPanning) {\n\t\t\t\t\t\t\t\tthis._prevCursor = this.getInstanceState().cursor.type\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tthis.inputs.isPanning = true\n\t\t\t\t\t\t\tclearTimeout(this._longPressTimeout)\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// We might be panning because we did a middle mouse click, or because we're holding spacebar and started a regular click\n\t\t\t\t\t\t// Also stop here, we don't want the state chart to receive the event\n\t\t\t\t\t\tif (this.inputs.isPanning) {\n\t\t\t\t\t\t\tthis.stopCameraAnimation()\n\t\t\t\t\t\t\tthis.setCursor({ type: 'grabbing', rotation: 0 })\n\t\t\t\t\t\t\treturn this\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t\tcase 'pointer_move': {\n\t\t\t\t\t\t// If the user is in pen mode, but the pointer is not a pen, stop here.\n\t\t\t\t\t\tif (!isPen && isPenMode) return\n\n\t\t\t\t\t\tconst { x: cx, y: cy, z: cz } = unsafe__withoutCapture(() => this.getCamera())\n\n\t\t\t\t\t\t// If we've started panning, then clear any long press timeout\n\t\t\t\t\t\tif (this.inputs.isPanning && this.inputs.isPointing) {\n\t\t\t\t\t\t\t// Handle spacebar / middle mouse button panning\n\t\t\t\t\t\t\tconst { currentScreenPoint, previousScreenPoint } = this.inputs\n\t\t\t\t\t\t\tconst { panSpeed } = cameraOptions\n\t\t\t\t\t\t\tconst offset = Vec.Sub(currentScreenPoint, previousScreenPoint)\n\t\t\t\t\t\t\tthis.setCamera(\n\t\t\t\t\t\t\t\tnew Vec(cx + (offset.x * panSpeed) / cz, cy + (offset.y * panSpeed) / cz, cz),\n\t\t\t\t\t\t\t\t{ immediate: true }\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\tthis.maybeTrackPerformance('Panning')\n\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\tinputs.isPointing &&\n\t\t\t\t\t\t\t!inputs.isDragging &&\n\t\t\t\t\t\t\tVec.Dist2(originPagePoint, currentPagePoint) * this.getZoomLevel() >\n\t\t\t\t\t\t\t\t(instanceState.isCoarsePointer\n\t\t\t\t\t\t\t\t\t? this.options.coarseDragDistanceSquared\n\t\t\t\t\t\t\t\t\t: this.options.dragDistanceSquared) /\n\t\t\t\t\t\t\t\t\tcz\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t// Start dragging\n\t\t\t\t\t\t\tinputs.isDragging = true\n\t\t\t\t\t\t\tclearTimeout(this._longPressTimeout)\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t\tcase 'pointer_up': {\n\t\t\t\t\t\t// Stop dragging / pointing\n\t\t\t\t\t\tinputs.isDragging = false\n\t\t\t\t\t\tinputs.isPointing = false\n\t\t\t\t\t\tclearTimeout(this._longPressTimeout)\n\n\t\t\t\t\t\t// Remove the button from the buttons set\n\t\t\t\t\t\tinputs.buttons.delete(info.button)\n\n\t\t\t\t\t\t// Suppressing pointerup here as doesn't seem to do what we what here.\n\t\t\t\t\t\tif (this.getIsMenuOpen()) return\n\n\t\t\t\t\t\t// If we're in pen mode and we're not using a pen, stop here\n\t\t\t\t\t\tif (instanceState.isPenMode && !isPen) return\n\n\t\t\t\t\t\t// Firefox bug fix...\n\t\t\t\t\t\t// If it's the same pointer that we stored earlier...\n\t\t\t\t\t\t// ... then it's probably still a left-mouse-click!\n\t\t\t\t\t\tif (this.capturedPointerId === info.pointerId) {\n\t\t\t\t\t\t\tthis.capturedPointerId = null\n\t\t\t\t\t\t\tinfo.button = 0\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (inputs.isPanning) {\n\t\t\t\t\t\t\tif (!inputs.keys.has('Space')) {\n\t\t\t\t\t\t\t\tinputs.isPanning = false\n\t\t\t\t\t\t\t\tinputs.isSpacebarPanning = false\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tconst slideDirection = this.inputs.pointerVelocity\n\t\t\t\t\t\t\tconst slideSpeed = Math.min(2, slideDirection.len())\n\n\t\t\t\t\t\t\tswitch (info.button) {\n\t\t\t\t\t\t\t\tcase LEFT_MOUSE_BUTTON: {\n\t\t\t\t\t\t\t\t\tthis.setCursor({ type: 'grab', rotation: 0 })\n\t\t\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tcase MIDDLE_MOUSE_BUTTON: {\n\t\t\t\t\t\t\t\t\tif (this.inputs.keys.has(' ')) {\n\t\t\t\t\t\t\t\t\t\tthis.setCursor({ type: 'grab', rotation: 0 })\n\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\tthis.setCursor({ type: this._prevCursor, rotation: 0 })\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif (slideSpeed > 0) {\n\t\t\t\t\t\t\t\tthis.slideCamera({ speed: slideSpeed, direction: slideDirection })\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tif (info.button === STYLUS_ERASER_BUTTON) {\n\t\t\t\t\t\t\t\t// If we were erasing with a stylus button, restore the tool we were using before we started erasing\n\t\t\t\t\t\t\t\tthis.complete()\n\t\t\t\t\t\t\t\tthis.setCurrentTool(this._restoreToolId)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'keyboard': {\n\t\t\t\t// please, please\n\t\t\t\tif (info.key === 'ShiftRight') info.key = 'ShiftLeft'\n\t\t\t\tif (info.key === 'AltRight') info.key = 'AltLeft'\n\t\t\t\tif (info.code === 'ControlRight') info.code = 'ControlLeft'\n\n\t\t\t\tswitch (info.name) {\n\t\t\t\t\tcase 'key_down': {\n\t\t\t\t\t\t// Add the key from the keys set\n\t\t\t\t\t\tinputs.keys.add(info.code)\n\n\t\t\t\t\t\t// If the space key is pressed (but meta / control isn't!) activate panning\n\t\t\t\t\t\tif (info.code === 'Space' && !info.ctrlKey) {\n\t\t\t\t\t\t\tif (!this.inputs.isPanning) {\n\t\t\t\t\t\t\t\tthis._prevCursor = instanceState.cursor.type\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tthis.inputs.isPanning = true\n\t\t\t\t\t\t\tthis.inputs.isSpacebarPanning = true\n\t\t\t\t\t\t\tclearTimeout(this._longPressTimeout)\n\t\t\t\t\t\t\tthis.setCursor({ type: this.inputs.isPointing ? 'grabbing' : 'grab', rotation: 0 })\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (this.inputs.isSpacebarPanning) {\n\t\t\t\t\t\t\tlet offset: Vec | undefined\n\t\t\t\t\t\t\tswitch (info.code) {\n\t\t\t\t\t\t\t\tcase 'ArrowUp': {\n\t\t\t\t\t\t\t\t\toffset = new Vec(0, -1)\n\t\t\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tcase 'ArrowRight': {\n\t\t\t\t\t\t\t\t\toffset = new Vec(1, 0)\n\t\t\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tcase 'ArrowDown': {\n\t\t\t\t\t\t\t\t\toffset = new Vec(0, 1)\n\t\t\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tcase 'ArrowLeft': {\n\t\t\t\t\t\t\t\t\toffset = new Vec(-1, 0)\n\t\t\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif (offset) {\n\t\t\t\t\t\t\t\tconst bounds = this.getViewportPageBounds()\n\t\t\t\t\t\t\t\tconst next = bounds.clone().translate(offset.mulV({ x: bounds.w, y: bounds.h }))\n\t\t\t\t\t\t\t\tthis._animateToViewport(next, { animation: { duration: 320 } })\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t\tcase 'key_up': {\n\t\t\t\t\t\t// Remove the key from the keys set\n\t\t\t\t\t\tinputs.keys.delete(info.code)\n\n\t\t\t\t\t\t// If we've lifted the space key,\n\t\t\t\t\t\tif (info.code === 'Space') {\n\t\t\t\t\t\t\tif (this.inputs.buttons.has(MIDDLE_MOUSE_BUTTON)) {\n\t\t\t\t\t\t\t\t// If we're still middle dragging, continue panning\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t// otherwise, stop panning\n\t\t\t\t\t\t\t\tthis.inputs.isPanning = false\n\t\t\t\t\t\t\t\tthis.inputs.isSpacebarPanning = false\n\t\t\t\t\t\t\t\tthis.setCursor({ type: this._prevCursor, rotation: 0 })\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t\tcase 'key_repeat': {\n\t\t\t\t\t\t// noop\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\n\t\t// Correct the info name for right / middle clicks\n\t\tif (info.type === 'pointer') {\n\t\t\tif (info.button === MIDDLE_MOUSE_BUTTON) {\n\t\t\t\tinfo.name = 'middle_click'\n\t\t\t} else if (info.button === RIGHT_MOUSE_BUTTON) {\n\t\t\t\tinfo.name = 'right_click'\n\t\t\t}\n\n\t\t\t// If a left click pointer event, send the event to the click manager.\n\t\t\tconst { isPenMode } = this.store.unsafeGetWithoutCapture(TLINSTANCE_ID)!\n\t\t\tif (info.isPen === isPenMode) {\n\t\t\t\t// The click manager may return a new event, i.e. a double click event\n\t\t\t\t// depending on the event coming in and its own state. If the event has\n\t\t\t\t// changed then hand both events to the statechart\n\t\t\t\tconst clickInfo = this._clickManager.handlePointerEvent(info)\n\t\t\t\tif (info.name !== clickInfo.name) {\n\t\t\t\t\tthis.root.handleEvent(info)\n\t\t\t\t\tthis.emit('event', info)\n\t\t\t\t\tthis.root.handleEvent(clickInfo)\n\t\t\t\t\tthis.emit('event', clickInfo)\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Send the event to the statechart. It will be handled by all\n\t\t// active states, starting at the root.\n\t\tthis.root.handleEvent(info)\n\t\tthis.emit('event', info)\n\n\t\t// close open menus at the very end on pointer down! after everything else! \u03C3\u03C5\u03BD\u03C4\u03B5\u03BB\u03B5\u03AF\u03B1\u03C2 \u03C4\u03BF\u1FE6 \u03BA\u03CE\u03B4\u03B9\u03BA\u03B1!!\n\t\tif (info.type === 'pointer' && info.name === 'pointer_down') {\n\t\t\tthis.clearOpenMenus()\n\t\t}\n\n\t\treturn this\n\t}\n\n\t/** @internal */\n\tprivate maybeTrackPerformance(name: string) {\n\t\tif (debugFlags.measurePerformance.get()) {\n\t\t\tif (this.performanceTracker.isStarted()) {\n\t\t\t\tclearTimeout(this.performanceTrackerTimeout)\n\t\t\t} else {\n\t\t\t\tthis.performanceTracker.start(name)\n\t\t\t}\n\t\t\tthis.performanceTrackerTimeout = this.timers.setTimeout(() => {\n\t\t\t\tthis.performanceTracker.stop()\n\t\t\t}, 50)\n\t\t}\n\t}\n}\n\nfunction alertMaxShapes(editor: Editor, pageId = editor.getCurrentPageId()) {\n\tconst name = editor.getPage(pageId)!.name\n\teditor.emit('max-shapes', { name, pageId, count: editor.options.maxShapesPerPage })\n}\n\nfunction applyPartialToRecordWithProps<\n\tT extends UnknownRecord & { type: string; props: object; meta: object },\n>(prev: T, partial?: Partial & { props?: Partial }): T {\n\tif (!partial) return prev\n\tlet next = null as null | T\n\tconst entries = Object.entries(partial)\n\tfor (let i = 0, n = entries.length; i < n; i++) {\n\t\tconst [k, v] = entries[i]\n\t\tif (v === undefined) continue\n\n\t\t// Is the key a special key? We don't update those\n\t\tif (k === 'id' || k === 'type' || k === 'typeName') continue\n\n\t\t// Is the value the same as it was before?\n\t\tif (v === (prev as any)[k]) continue\n\n\t\t// There's a new value, so create the new shape if we haven't already (should we be cloning this?)\n\t\tif (!next) next = { ...prev }\n\n\t\t// for props / meta properties, we support updates with partials of this object\n\t\tif (k === 'props' || k === 'meta') {\n\t\t\tnext[k] = { ...prev[k] } as JsonObject\n\t\t\tfor (const [nextKey, nextValue] of Object.entries(v as object)) {\n\t\t\t\tif (nextValue !== undefined) {\n\t\t\t\t\t;(next[k] as JsonObject)[nextKey] = nextValue\n\t\t\t\t}\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\n\t\t// base property\n\t\t;(next as any)[k] = v\n\t}\n\tif (!next) return prev\n\treturn next\n}\n\nfunction pushShapeWithDescendants(editor: Editor, id: TLShapeId, result: TLShape[]): void {\n\tconst shape = editor.getShape(id)\n\tif (!shape) return\n\tresult.push(shape)\n\tconst childIds = editor.getSortedChildIdsForParent(id)\n\tfor (let i = 0, n = childIds.length; i < n; i++) {\n\t\tpushShapeWithDescendants(editor, childIds[i], result)\n\t}\n}\n\n/**\n * Run `callback` in a world where all bindings from the shapes in `shapeIds` to shapes not in\n * `shapeIds` are removed. This is useful when you want to duplicate/copy shapes without worrying\n * about bindings that might be pointing to shapes that are not being duplicated.\n *\n * The callback is given the set of bindings that should be maintained.\n */\nfunction withIsolatedShapes(\n\teditor: Editor,\n\tshapeIds: Set,\n\tcallback: (bindingsWithBoth: Set) => T\n): T {\n\tlet result!: Result\n\n\teditor.run(\n\t\t() => {\n\t\t\tconst changes = editor.store.extractingChanges(() => {\n\t\t\t\tconst bindingsWithBoth = new Set()\n\t\t\t\tconst bindingsToRemove = new Set()\n\n\t\t\t\tfor (const shapeId of shapeIds) {\n\t\t\t\t\tconst shape = editor.getShape(shapeId)\n\t\t\t\t\tif (!shape) continue\n\n\t\t\t\t\tfor (const binding of editor.getBindingsInvolvingShape(shapeId)) {\n\t\t\t\t\t\tconst hasFrom = shapeIds.has(binding.fromId)\n\t\t\t\t\t\tconst hasTo = shapeIds.has(binding.toId)\n\t\t\t\t\t\tif (hasFrom && hasTo) {\n\t\t\t\t\t\t\tbindingsWithBoth.add(binding.id)\n\t\t\t\t\t\t\tcontinue\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (!hasFrom || !hasTo) {\n\t\t\t\t\t\t\tbindingsToRemove.add(binding.id)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\teditor.deleteBindings([...bindingsToRemove], { isolateShapes: true })\n\n\t\t\t\ttry {\n\t\t\t\t\tresult = Result.ok(callback(bindingsWithBoth))\n\t\t\t\t} catch (error) {\n\t\t\t\t\tresult = Result.err(error)\n\t\t\t\t}\n\t\t\t})\n\n\t\t\teditor.store.applyDiff(reverseRecordsDiff(changes))\n\t\t},\n\t\t{ history: 'ignore' }\n\t)\n\n\tif (result.ok) {\n\t\treturn result.value\n\t} else {\n\t\tthrow result.error\n\t}\n}\n\nfunction getCameraFitXFitY(editor: Editor, cameraOptions: TLCameraOptions) {\n\tif (!cameraOptions.constraints) throw Error('Should have constraints here')\n\tconst {\n\t\tpadding: { x: px, y: py },\n\t} = cameraOptions.constraints\n\tconst vsb = editor.getViewportScreenBounds()\n\tconst bounds = Box.From(cameraOptions.constraints.bounds)\n\tconst zx = (vsb.w - px * 2) / bounds.w\n\tconst zy = (vsb.h - py * 2) / bounds.h\n\treturn { zx, zy }\n}\n"], -+ "mappings": "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", - "names": ["import_utils", "EventEmitter", "shape", "highlightedUserIds", "page", "notVisibleShapes", "distance", "ancestor", "bindingsToCreate", "shapesToCreateWithOriginals", "gap", "last", "i", "animatingShapes", "n", "group", "shapes", "bindings", "pageId"] - } -diff --git a/node_modules/@tldraw/editor/dist-cjs/lib/hooks/useDocumentEvents.js b/node_modules/@tldraw/editor/dist-cjs/lib/hooks/useDocumentEvents.js -index 9938377..36a33fe 100644 ---- a/node_modules/@tldraw/editor/dist-cjs/lib/hooks/useDocumentEvents.js -+++ b/node_modules/@tldraw/editor/dist-cjs/lib/hooks/useDocumentEvents.js -@@ -161,17 +161,17 @@ function useDocumentEvents() { - }; - container.addEventListener("touchstart", handleTouchStart, { passive: false }); - container.addEventListener("wheel", handleWheel, { passive: false }); -- document.addEventListener("gesturestart", import_dom.preventDefault); -- document.addEventListener("gesturechange", import_dom.preventDefault); -- document.addEventListener("gestureend", import_dom.preventDefault); -+ container.ownerDocument.addEventListener("gesturestart", import_dom.preventDefault); -+ container.ownerDocument.addEventListener("gesturechange", import_dom.preventDefault); -+ container.ownerDocument.addEventListener("gestureend", import_dom.preventDefault); - container.addEventListener("keydown", handleKeyDown); - container.addEventListener("keyup", handleKeyUp); - return () => { - container.removeEventListener("touchstart", handleTouchStart); - container.removeEventListener("wheel", handleWheel); -- document.removeEventListener("gesturestart", import_dom.preventDefault); -- document.removeEventListener("gesturechange", import_dom.preventDefault); -- document.removeEventListener("gestureend", import_dom.preventDefault); -+ container.ownerDocument.removeEventListener("gesturestart", import_dom.preventDefault); -+ container.ownerDocument.removeEventListener("gesturechange", import_dom.preventDefault); -+ container.ownerDocument.removeEventListener("gestureend", import_dom.preventDefault); - container.removeEventListener("keydown", handleKeyDown); - container.removeEventListener("keyup", handleKeyUp); - }; -diff --git a/node_modules/@tldraw/editor/dist-cjs/lib/hooks/useDocumentEvents.js.map b/node_modules/@tldraw/editor/dist-cjs/lib/hooks/useDocumentEvents.js.map -index 1700a86..43c47b0 100644 ---- a/node_modules/@tldraw/editor/dist-cjs/lib/hooks/useDocumentEvents.js.map -+++ b/node_modules/@tldraw/editor/dist-cjs/lib/hooks/useDocumentEvents.js.map -@@ -1,7 +1,7 @@ - { - "version": 3, - "sources": ["../../../src/lib/hooks/useDocumentEvents.ts"], -- "sourcesContent": ["import { useValue } from '@tldraw/state-react'\nimport { useEffect } from 'react'\nimport { TLKeyboardEventInfo } from '../editor/types/event-types'\nimport { preventDefault } from '../utils/dom'\nimport { useContainer } from './useContainer'\nimport { useEditor } from './useEditor'\n\nexport function useDocumentEvents() {\n\tconst editor = useEditor()\n\tconst container = useContainer()\n\n\tconst isAppFocused = useValue('isFocused', () => editor.getIsFocused(), [editor])\n\n\tuseEffect(() => {\n\t\tif (typeof window === 'undefined' || !('matchMedia' in window)) return\n\n\t\t// https://developer.mozilla.org/en-US/docs/Web/API/Window/devicePixelRatio#monitoring_screen_resolution_or_zoom_level_changes\n\t\tlet remove: (() => void) | null = null\n\t\tconst updatePixelRatio = () => {\n\t\t\tif (remove != null) {\n\t\t\t\tremove()\n\t\t\t}\n\t\t\tconst mqString = `(resolution: ${window.devicePixelRatio}dppx)`\n\t\t\tconst media = matchMedia(mqString)\n\t\t\t// Safari only started supporting `addEventListener('change',...) in version 14\n\t\t\t// https://developer.mozilla.org/en-US/docs/Web/API/MediaQueryList/change_event\n\t\t\tconst safariCb = (ev: any) => {\n\t\t\t\tif (ev.type === 'change') {\n\t\t\t\t\tupdatePixelRatio()\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (media.addEventListener) {\n\t\t\t\tmedia.addEventListener('change', updatePixelRatio)\n\t\t\t\t// eslint-disable-next-line deprecation/deprecation\n\t\t\t} else if (media.addListener) {\n\t\t\t\t// eslint-disable-next-line deprecation/deprecation\n\t\t\t\tmedia.addListener(safariCb)\n\t\t\t}\n\t\t\tremove = () => {\n\t\t\t\tif (media.removeEventListener) {\n\t\t\t\t\tmedia.removeEventListener('change', updatePixelRatio)\n\t\t\t\t\t// eslint-disable-next-line deprecation/deprecation\n\t\t\t\t} else if (media.removeListener) {\n\t\t\t\t\t// eslint-disable-next-line deprecation/deprecation\n\t\t\t\t\tmedia.removeListener(safariCb)\n\t\t\t\t}\n\t\t\t}\n\t\t\teditor.updateInstanceState({ devicePixelRatio: window.devicePixelRatio })\n\t\t}\n\t\tupdatePixelRatio()\n\t\treturn () => {\n\t\t\tremove?.()\n\t\t}\n\t}, [editor])\n\n\tuseEffect(() => {\n\t\tif (!isAppFocused) return\n\n\t\tconst handleKeyDown = (e: KeyboardEvent) => {\n\t\t\tif (\n\t\t\t\te.altKey &&\n\t\t\t\t// todo: When should we allow the alt key to be used? Perhaps states should declare which keys matter to them?\n\t\t\t\t(editor.isIn('zoom') || !editor.getPath().endsWith('.idle')) &&\n\t\t\t\t!isFocusingInput()\n\t\t\t) {\n\t\t\t\t// On windows the alt key opens the menu bar.\n\t\t\t\t// We want to prevent that if the user is doing something else,\n\t\t\t\t// e.g. resizing a shape\n\t\t\t\tpreventDefault(e)\n\t\t\t}\n\n\t\t\tif ((e as any).isKilled) return\n\t\t\t;(e as any).isKilled = true\n\n\t\t\tswitch (e.key) {\n\t\t\t\tcase '=':\n\t\t\t\tcase '-':\n\t\t\t\tcase '0': {\n\t\t\t\t\t// These keys are used for zooming. Technically we only use\n\t\t\t\t\t// the + - and 0 keys, however it's common for them to be\n\t\t\t\t\t// paired with modifier keys (command / control) so we need\n\t\t\t\t\t// to prevent the browser's regular actions (i.e. zooming\n\t\t\t\t\t// the page). A user can zoom by unfocusing the editor.\n\t\t\t\t\tif (e.metaKey || e.ctrlKey) {\n\t\t\t\t\t\tpreventDefault(e)\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase 'Tab': {\n\t\t\t\t\tif (isFocusingInput() || editor.getIsMenuOpen()) {\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase ',': {\n\t\t\t\t\t// this was moved to useKeyBoardShortcuts; it's possible\n\t\t\t\t\t// that the comma key is pressed when the container is not\n\t\t\t\t\t// focused, for example when the user has just interacted\n\t\t\t\t\t// with the toolbar. We need to handle it on the window\n\t\t\t\t\t// (ofc ensuring it's a correct time for a shortcut)\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tcase 'Escape': {\n\t\t\t\t\t// In certain browsers, pressing escape while in full screen mode\n\t\t\t\t\t// will exit full screen mode. We want to allow that, but not when\n\t\t\t\t\t// escape is being handled by the editor. When a user has an editing\n\t\t\t\t\t// shape, escape stops editing. When a user is using a tool, escape\n\t\t\t\t\t// returns to the select tool. When the user has selected shapes,\n\t\t\t\t\t// escape de-selects them. Only when the user's selection is empty\n\t\t\t\t\t// should we allow escape to do its normal thing.\n\n\t\t\t\t\tif (editor.getEditingShape() || editor.getSelectedShapeIds().length > 0) {\n\t\t\t\t\t\tpreventDefault(e)\n\t\t\t\t\t}\n\n\t\t\t\t\t// Don't do anything if we open menus open\n\t\t\t\t\tif (editor.getOpenMenus().length > 0) return\n\n\t\t\t\t\tif (editor.inputs.keys.has('Escape')) {\n\t\t\t\t\t\t// noop\n\t\t\t\t\t} else {\n\t\t\t\t\t\teditor.inputs.keys.add('Escape')\n\n\t\t\t\t\t\teditor.cancel()\n\t\t\t\t\t\t// Pressing escape will focus the document.body,\n\t\t\t\t\t\t// which will cause the app to lose focus, which\n\t\t\t\t\t\t// will break additional shortcuts. We need to\n\t\t\t\t\t\t// refocus the container in order to keep these\n\t\t\t\t\t\t// shortcuts working.\n\t\t\t\t\t\tcontainer.focus()\n\t\t\t\t\t}\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tdefault: {\n\t\t\t\t\tif (isFocusingInput() || editor.getIsMenuOpen()) {\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst info: TLKeyboardEventInfo = {\n\t\t\t\ttype: 'keyboard',\n\t\t\t\tname: e.repeat ? 'key_repeat' : 'key_down',\n\t\t\t\tkey: e.key,\n\t\t\t\tcode: e.code,\n\t\t\t\tshiftKey: e.shiftKey,\n\t\t\t\taltKey: e.altKey,\n\t\t\t\tctrlKey: e.metaKey || e.ctrlKey,\n\t\t\t}\n\n\t\t\teditor.dispatch(info)\n\t\t}\n\n\t\tconst handleKeyUp = (e: KeyboardEvent) => {\n\t\t\tif ((e as any).isKilled) return\n\t\t\t;(e as any).isKilled = true\n\n\t\t\tif (isFocusingInput() || editor.getIsMenuOpen()) {\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tif (e.key === ',') {\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tconst info: TLKeyboardEventInfo = {\n\t\t\t\ttype: 'keyboard',\n\t\t\t\tname: 'key_up',\n\t\t\t\tkey: e.key,\n\t\t\t\tcode: e.code,\n\t\t\t\tshiftKey: e.shiftKey,\n\t\t\t\taltKey: e.altKey,\n\t\t\t\tctrlKey: e.metaKey || e.ctrlKey,\n\t\t\t}\n\n\t\t\teditor.dispatch(info)\n\t\t}\n\n\t\tfunction handleTouchStart(e: TouchEvent) {\n\t\t\tif (container.contains(e.target as Node)) {\n\t\t\t\t// Center point of the touch area\n\t\t\t\tconst touchXPosition = e.touches[0].pageX\n\t\t\t\t// Size of the touch area\n\t\t\t\tconst touchXRadius = e.touches[0].radiusX || 0\n\n\t\t\t\t// We set a threshold (10px) on both sizes of the screen,\n\t\t\t\t// if the touch area overlaps with the screen edges\n\t\t\t\t// it's likely to trigger the navigation. We prevent the\n\t\t\t\t// touchstart event in that case.\n\t\t\t\t// todo: make this relative to the actual window, not the editor's screen bounds\n\t\t\t\tif (\n\t\t\t\t\ttouchXPosition - touchXRadius < 10 ||\n\t\t\t\t\ttouchXPosition + touchXRadius > editor.getViewportScreenBounds().width - 10\n\t\t\t\t) {\n\t\t\t\t\tif ((e.target as HTMLElement)?.tagName === 'BUTTON') {\n\t\t\t\t\t\t// Force a click before bailing\n\t\t\t\t\t\t;(e.target as HTMLButtonElement)?.click()\n\t\t\t\t\t}\n\n\t\t\t\t\tpreventDefault(e)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Prevent wheel events that occur inside of the container\n\t\tconst handleWheel = (e: WheelEvent) => {\n\t\t\tif (container.contains(e.target as Node) && (e.ctrlKey || e.metaKey)) {\n\t\t\t\tpreventDefault(e)\n\t\t\t}\n\t\t}\n\n\t\tcontainer.addEventListener('touchstart', handleTouchStart, { passive: false })\n\n\t\tcontainer.addEventListener('wheel', handleWheel, { passive: false })\n\n\t\tdocument.addEventListener('gesturestart', preventDefault)\n\t\tdocument.addEventListener('gesturechange', preventDefault)\n\t\tdocument.addEventListener('gestureend', preventDefault)\n\n\t\tcontainer.addEventListener('keydown', handleKeyDown)\n\t\tcontainer.addEventListener('keyup', handleKeyUp)\n\n\t\treturn () => {\n\t\t\tcontainer.removeEventListener('touchstart', handleTouchStart)\n\n\t\t\tcontainer.removeEventListener('wheel', handleWheel)\n\n\t\t\tdocument.removeEventListener('gesturestart', preventDefault)\n\t\t\tdocument.removeEventListener('gesturechange', preventDefault)\n\t\t\tdocument.removeEventListener('gestureend', preventDefault)\n\n\t\t\tcontainer.removeEventListener('keydown', handleKeyDown)\n\t\t\tcontainer.removeEventListener('keyup', handleKeyUp)\n\t\t}\n\t}, [editor, container, isAppFocused])\n}\n\nconst INPUTS = ['input', 'select', 'button', 'textarea']\n\nfunction isFocusingInput() {\n\tconst { activeElement } = document\n\n\tif (\n\t\tactiveElement &&\n\t\t(activeElement.getAttribute('contenteditable') ||\n\t\t\tINPUTS.indexOf(activeElement.tagName.toLowerCase()) > -1)\n\t) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n"], -- "mappings": "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", -+ "sourcesContent": ["import { useValue } from '@tldraw/state-react'\nimport { useEffect } from 'react'\nimport { TLKeyboardEventInfo } from '../editor/types/event-types'\nimport { preventDefault } from '../utils/dom'\nimport { useContainer } from './useContainer'\nimport { useEditor } from './useEditor'\n\nexport function useDocumentEvents() {\n\tconst editor = useEditor()\n\tconst container = useContainer()\n\n\tconst isAppFocused = useValue('isFocused', () => editor.getIsFocused(), [editor])\n\n\tuseEffect(() => {\n\t\tif (typeof window === 'undefined' || !('matchMedia' in window)) return\n\n\t\t// https://developer.mozilla.org/en-US/docs/Web/API/Window/devicePixelRatio#monitoring_screen_resolution_or_zoom_level_changes\n\t\tlet remove: (() => void) | null = null\n\t\tconst updatePixelRatio = () => {\n\t\t\tif (remove != null) {\n\t\t\t\tremove()\n\t\t\t}\n\t\t\tconst mqString = `(resolution: ${window.devicePixelRatio}dppx)`\n\t\t\tconst media = matchMedia(mqString)\n\t\t\t// Safari only started supporting `addEventListener('change',...) in version 14\n\t\t\t// https://developer.mozilla.org/en-US/docs/Web/API/MediaQueryList/change_event\n\t\t\tconst safariCb = (ev: any) => {\n\t\t\t\tif (ev.type === 'change') {\n\t\t\t\t\tupdatePixelRatio()\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (media.addEventListener) {\n\t\t\t\tmedia.addEventListener('change', updatePixelRatio)\n\t\t\t\t// eslint-disable-next-line deprecation/deprecation\n\t\t\t} else if (media.addListener) {\n\t\t\t\t// eslint-disable-next-line deprecation/deprecation\n\t\t\t\tmedia.addListener(safariCb)\n\t\t\t}\n\t\t\tremove = () => {\n\t\t\t\tif (media.removeEventListener) {\n\t\t\t\t\tmedia.removeEventListener('change', updatePixelRatio)\n\t\t\t\t\t// eslint-disable-next-line deprecation/deprecation\n\t\t\t\t} else if (media.removeListener) {\n\t\t\t\t\t// eslint-disable-next-line deprecation/deprecation\n\t\t\t\t\tmedia.removeListener(safariCb)\n\t\t\t\t}\n\t\t\t}\n\t\t\teditor.updateInstanceState({ devicePixelRatio: window.devicePixelRatio })\n\t\t}\n\t\tupdatePixelRatio()\n\t\treturn () => {\n\t\t\tremove?.()\n\t\t}\n\t}, [editor])\n\n\tuseEffect(() => {\n\t\tif (!isAppFocused) return\n\n\t\tconst handleKeyDown = (e: KeyboardEvent) => {\n\t\t\tif (\n\t\t\t\te.altKey &&\n\t\t\t\t// todo: When should we allow the alt key to be used? Perhaps states should declare which keys matter to them?\n\t\t\t\t(editor.isIn('zoom') || !editor.getPath().endsWith('.idle')) &&\n\t\t\t\t!isFocusingInput()\n\t\t\t) {\n\t\t\t\t// On windows the alt key opens the menu bar.\n\t\t\t\t// We want to prevent that if the user is doing something else,\n\t\t\t\t// e.g. resizing a shape\n\t\t\t\tpreventDefault(e)\n\t\t\t}\n\n\t\t\tif ((e as any).isKilled) return\n\t\t\t;(e as any).isKilled = true\n\n\t\t\tswitch (e.key) {\n\t\t\t\tcase '=':\n\t\t\t\tcase '-':\n\t\t\t\tcase '0': {\n\t\t\t\t\t// These keys are used for zooming. Technically we only use\n\t\t\t\t\t// the + - and 0 keys, however it's common for them to be\n\t\t\t\t\t// paired with modifier keys (command / control) so we need\n\t\t\t\t\t// to prevent the browser's regular actions (i.e. zooming\n\t\t\t\t\t// the page). A user can zoom by unfocusing the editor.\n\t\t\t\t\tif (e.metaKey || e.ctrlKey) {\n\t\t\t\t\t\tpreventDefault(e)\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase 'Tab': {\n\t\t\t\t\tif (isFocusingInput() || editor.getIsMenuOpen()) {\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase ',': {\n\t\t\t\t\t// this was moved to useKeyBoardShortcuts; it's possible\n\t\t\t\t\t// that the comma key is pressed when the container is not\n\t\t\t\t\t// focused, for example when the user has just interacted\n\t\t\t\t\t// with the toolbar. We need to handle it on the window\n\t\t\t\t\t// (ofc ensuring it's a correct time for a shortcut)\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tcase 'Escape': {\n\t\t\t\t\t// In certain browsers, pressing escape while in full screen mode\n\t\t\t\t\t// will exit full screen mode. We want to allow that, but not when\n\t\t\t\t\t// escape is being handled by the editor. When a user has an editing\n\t\t\t\t\t// shape, escape stops editing. When a user is using a tool, escape\n\t\t\t\t\t// returns to the select tool. When the user has selected shapes,\n\t\t\t\t\t// escape de-selects them. Only when the user's selection is empty\n\t\t\t\t\t// should we allow escape to do its normal thing.\n\n\t\t\t\t\tif (editor.getEditingShape() || editor.getSelectedShapeIds().length > 0) {\n\t\t\t\t\t\tpreventDefault(e)\n\t\t\t\t\t}\n\n\t\t\t\t\t// Don't do anything if we open menus open\n\t\t\t\t\tif (editor.getOpenMenus().length > 0) return\n\n\t\t\t\t\tif (editor.inputs.keys.has('Escape')) {\n\t\t\t\t\t\t// noop\n\t\t\t\t\t} else {\n\t\t\t\t\t\teditor.inputs.keys.add('Escape')\n\n\t\t\t\t\t\teditor.cancel()\n\t\t\t\t\t\t// Pressing escape will focus the document.body,\n\t\t\t\t\t\t// which will cause the app to lose focus, which\n\t\t\t\t\t\t// will break additional shortcuts. We need to\n\t\t\t\t\t\t// refocus the container in order to keep these\n\t\t\t\t\t\t// shortcuts working.\n\t\t\t\t\t\tcontainer.focus()\n\t\t\t\t\t}\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tdefault: {\n\t\t\t\t\tif (isFocusingInput() || editor.getIsMenuOpen()) {\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst info: TLKeyboardEventInfo = {\n\t\t\t\ttype: 'keyboard',\n\t\t\t\tname: e.repeat ? 'key_repeat' : 'key_down',\n\t\t\t\tkey: e.key,\n\t\t\t\tcode: e.code,\n\t\t\t\tshiftKey: e.shiftKey,\n\t\t\t\taltKey: e.altKey,\n\t\t\t\tctrlKey: e.metaKey || e.ctrlKey,\n\t\t\t}\n\n\t\t\teditor.dispatch(info)\n\t\t}\n\n\t\tconst handleKeyUp = (e: KeyboardEvent) => {\n\t\t\tif ((e as any).isKilled) return\n\t\t\t;(e as any).isKilled = true\n\n\t\t\tif (isFocusingInput() || editor.getIsMenuOpen()) {\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tif (e.key === ',') {\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tconst info: TLKeyboardEventInfo = {\n\t\t\t\ttype: 'keyboard',\n\t\t\t\tname: 'key_up',\n\t\t\t\tkey: e.key,\n\t\t\t\tcode: e.code,\n\t\t\t\tshiftKey: e.shiftKey,\n\t\t\t\taltKey: e.altKey,\n\t\t\t\tctrlKey: e.metaKey || e.ctrlKey,\n\t\t\t}\n\n\t\t\teditor.dispatch(info)\n\t\t}\n\n\t\tfunction handleTouchStart(e: TouchEvent) {\n\t\t\tif (container.contains(e.target as Node)) {\n\t\t\t\t// Center point of the touch area\n\t\t\t\tconst touchXPosition = e.touches[0].pageX\n\t\t\t\t// Size of the touch area\n\t\t\t\tconst touchXRadius = e.touches[0].radiusX || 0\n\n\t\t\t\t// We set a threshold (10px) on both sizes of the screen,\n\t\t\t\t// if the touch area overlaps with the screen edges\n\t\t\t\t// it's likely to trigger the navigation. We prevent the\n\t\t\t\t// touchstart event in that case.\n\t\t\t\t// todo: make this relative to the actual window, not the editor's screen bounds\n\t\t\t\tif (\n\t\t\t\t\ttouchXPosition - touchXRadius < 10 ||\n\t\t\t\t\ttouchXPosition + touchXRadius > editor.getViewportScreenBounds().width - 10\n\t\t\t\t) {\n\t\t\t\t\tif ((e.target as HTMLElement)?.tagName === 'BUTTON') {\n\t\t\t\t\t\t// Force a click before bailing\n\t\t\t\t\t\t;(e.target as HTMLButtonElement)?.click()\n\t\t\t\t\t}\n\n\t\t\t\t\tpreventDefault(e)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Prevent wheel events that occur inside of the container\n\t\tconst handleWheel = (e: WheelEvent) => {\n\t\t\tif (container.contains(e.target as Node) && (e.ctrlKey || e.metaKey)) {\n\t\t\t\tpreventDefault(e)\n\t\t\t}\n\t\t}\n\n\t\tcontainer.addEventListener('touchstart', handleTouchStart, { passive: false })\n\n\t\tcontainer.addEventListener('wheel', handleWheel, { passive: false })\n\n\t\tcontainer.ownerDocument.addEventListener('gesturestart', preventDefault)\n\t\tcontainer.ownerDocument.addEventListener('gesturechange', preventDefault)\n\t\tcontainer.ownerDocument.addEventListener('gestureend', preventDefault)\n\n\t\tcontainer.addEventListener('keydown', handleKeyDown)\n\t\tcontainer.addEventListener('keyup', handleKeyUp)\n\n\t\treturn () => {\n\t\t\tcontainer.removeEventListener('touchstart', handleTouchStart)\n\n\t\t\tcontainer.removeEventListener('wheel', handleWheel)\n\n\t\t\tcontainer.ownerDocument.removeEventListener('gesturestart', preventDefault)\n\t\t\tcontainer.ownerDocument.removeEventListener('gesturechange', preventDefault)\n\t\t\tcontainer.ownerDocument.removeEventListener('gestureend', preventDefault)\n\n\t\t\tcontainer.removeEventListener('keydown', handleKeyDown)\n\t\t\tcontainer.removeEventListener('keyup', handleKeyUp)\n\t\t}\n\t}, [editor, container, isAppFocused])\n}\n\nconst INPUTS = ['input', 'select', 'button', 'textarea']\n\nfunction isFocusingInput() {\n\tconst { activeElement } = document\n\n\tif (\n\t\tactiveElement &&\n\t\t(activeElement.getAttribute('contenteditable') ||\n\t\t\tINPUTS.indexOf(activeElement.tagName.toLowerCase()) > -1)\n\t) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n"], -+ "mappings": "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", - "names": [] - } -diff --git a/node_modules/@tldraw/editor/dist-cjs/lib/utils/dom.js b/node_modules/@tldraw/editor/dist-cjs/lib/utils/dom.js -index 44f7068..4867609 100644 ---- a/node_modules/@tldraw/editor/dist-cjs/lib/utils/dom.js -+++ b/node_modules/@tldraw/editor/dist-cjs/lib/utils/dom.js -@@ -28,7 +28,7 @@ __export(dom_exports, { - module.exports = __toCommonJS(dom_exports); - var import_debug_flags = require("./debug-flags"); - function loopToHtmlElement(elm) { -- if (elm instanceof HTMLElement) return elm; -+ if (elm.instanceOf(HTMLElement)) return elm; - if (elm.parentElement) return loopToHtmlElement(elm.parentElement); - else throw Error("Could not find a parent element of an HTML type!"); - } -diff --git a/node_modules/@tldraw/editor/dist-cjs/lib/utils/dom.js.map b/node_modules/@tldraw/editor/dist-cjs/lib/utils/dom.js.map -index bafd95d..487dc82 100644 ---- a/node_modules/@tldraw/editor/dist-cjs/lib/utils/dom.js.map -+++ b/node_modules/@tldraw/editor/dist-cjs/lib/utils/dom.js.map -@@ -1,7 +1,7 @@ - { - "version": 3, - "sources": ["../../../src/lib/utils/dom.ts"], -- "sourcesContent": ["/*\nThis is used to facilitate double clicking and pointer capture on elements.\n\nThe events in this file are possibly set on individual SVG elements, \nsuch as handles or corner handles, rather than on HTML elements or \nSVGSVGElements. Raw SVG elemnets do not support pointerCapture in \nmost cases, meaning that in order for pointer capture to work, we \nneed to crawl up the DOM tree to find the nearest HTML element. Then,\nin order for that element to also call the `onPointerUp` event from\nthis file, we need to manually set that event on that element and\nlater remove it when the pointerup occurs. This is a potential leak\nif the user clicks on a handle but the pointerup does not fire for\nwhatever reason.\n*/\n\nimport React from 'react'\nimport { debugFlags, pointerCaptureTrackingObject } from './debug-flags'\n\n/** @public */\nexport function loopToHtmlElement(elm: Element): HTMLElement {\n\tif (elm instanceof HTMLElement) return elm\n\tif (elm.parentElement) return loopToHtmlElement(elm.parentElement)\n\telse throw Error('Could not find a parent element of an HTML type!')\n}\n\n/**\n * This function calls `event.preventDefault()` for you. Why is that useful?\n *\n * Beacuase if you enable `window.preventDefaultLogging = true` it'll log out a message when it\n * happens. Because we use console.warn rather than (log) you'll get a stack trace in the inspector\n * telling you exactly where it happened. This is important because `e.preventDefault()` is the\n * source of many bugs, but unfortuantly it can't be avoided because it also stops a lot of default\n * behaviour which doesn't make sense in our UI\n *\n * @param event - To prevent default on\n * @public\n */\nexport function preventDefault(event: React.BaseSyntheticEvent | Event) {\n\tevent.preventDefault()\n\tif (debugFlags.logPreventDefaults.get()) {\n\t\tconsole.warn('preventDefault called on event:', event)\n\t}\n}\n\n/** @public */\nexport function setPointerCapture(\n\telement: Element,\n\tevent: React.PointerEvent | PointerEvent\n) {\n\telement.setPointerCapture(event.pointerId)\n\tif (debugFlags.logPointerCaptures.get()) {\n\t\tconst trackingObj = pointerCaptureTrackingObject.get()\n\t\ttrackingObj.set(element, (trackingObj.get(element) ?? 0) + 1)\n\t\tconsole.warn('setPointerCapture called on element:', element, event)\n\t}\n}\n\n/** @public */\nexport function releasePointerCapture(\n\telement: Element,\n\tevent: React.PointerEvent | PointerEvent\n) {\n\tif (!element.hasPointerCapture(event.pointerId)) {\n\t\treturn\n\t}\n\n\telement.releasePointerCapture(event.pointerId)\n\tif (debugFlags.logPointerCaptures.get()) {\n\t\tconst trackingObj = pointerCaptureTrackingObject.get()\n\t\tif (trackingObj.get(element) === 1) {\n\t\t\ttrackingObj.delete(element)\n\t\t} else if (trackingObj.has(element)) {\n\t\t\ttrackingObj.set(element, trackingObj.get(element)! - 1)\n\t\t} else {\n\t\t\tconsole.warn('Release without capture')\n\t\t}\n\t\tconsole.warn('releasePointerCapture called on element:', element, event)\n\t}\n}\n\n/** @public */\nexport const stopEventPropagation = (e: any) => e.stopPropagation()\n\n/** @internal */\nexport const setStyleProperty = (\n\telm: HTMLElement | null,\n\tproperty: string,\n\tvalue: string | number\n) => {\n\tif (!elm) return\n\telm.style.setProperty(property, value as string)\n}\n"], -- "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAgBA,yBAAyD;AAGlD,SAAS,kBAAkB,KAA2B;AAC5D,MAAI,eAAe,YAAa,QAAO;AACvC,MAAI,IAAI,cAAe,QAAO,kBAAkB,IAAI,aAAa;AAAA,MAC5D,OAAM,MAAM,kDAAkD;AACpE;AAcO,SAAS,eAAe,OAAyC;AACvE,QAAM,eAAe;AACrB,MAAI,8BAAW,mBAAmB,IAAI,GAAG;AACxC,YAAQ,KAAK,mCAAmC,KAAK;AAAA,EACtD;AACD;AAGO,SAAS,kBACf,SACA,OACC;AACD,UAAQ,kBAAkB,MAAM,SAAS;AACzC,MAAI,8BAAW,mBAAmB,IAAI,GAAG;AACxC,UAAM,cAAc,gDAA6B,IAAI;AACrD,gBAAY,IAAI,UAAU,YAAY,IAAI,OAAO,KAAK,KAAK,CAAC;AAC5D,YAAQ,KAAK,wCAAwC,SAAS,KAAK;AAAA,EACpE;AACD;AAGO,SAAS,sBACf,SACA,OACC;AACD,MAAI,CAAC,QAAQ,kBAAkB,MAAM,SAAS,GAAG;AAChD;AAAA,EACD;AAEA,UAAQ,sBAAsB,MAAM,SAAS;AAC7C,MAAI,8BAAW,mBAAmB,IAAI,GAAG;AACxC,UAAM,cAAc,gDAA6B,IAAI;AACrD,QAAI,YAAY,IAAI,OAAO,MAAM,GAAG;AACnC,kBAAY,OAAO,OAAO;AAAA,IAC3B,WAAW,YAAY,IAAI,OAAO,GAAG;AACpC,kBAAY,IAAI,SAAS,YAAY,IAAI,OAAO,IAAK,CAAC;AAAA,IACvD,OAAO;AACN,cAAQ,KAAK,yBAAyB;AAAA,IACvC;AACA,YAAQ,KAAK,4CAA4C,SAAS,KAAK;AAAA,EACxE;AACD;AAGO,MAAM,uBAAuB,CAAC,MAAW,EAAE,gBAAgB;AAG3D,MAAM,mBAAmB,CAC/B,KACA,UACA,UACI;AACJ,MAAI,CAAC,IAAK;AACV,MAAI,MAAM,YAAY,UAAU,KAAe;AAChD;", -+ "sourcesContent": ["/*\nThis is used to facilitate double clicking and pointer capture on elements.\n\nThe events in this file are possibly set on individual SVG elements, \nsuch as handles or corner handles, rather than on HTML elements or \nSVGSVGElements. Raw SVG elemnets do not support pointerCapture in \nmost cases, meaning that in order for pointer capture to work, we \nneed to crawl up the DOM tree to find the nearest HTML element. Then,\nin order for that element to also call the `onPointerUp` event from\nthis file, we need to manually set that event on that element and\nlater remove it when the pointerup occurs. This is a potential leak\nif the user clicks on a handle but the pointerup does not fire for\nwhatever reason.\n*/\n\nimport React from 'react'\nimport { debugFlags, pointerCaptureTrackingObject } from './debug-flags'\n\ndeclare global {\n\tinterface Node {\n\t\t/**\n * Cross-window capable instanceof check, a drop-in replacement\n * for instanceof checks on DOM Nodes. Remember to also check\n * for nulls when necessary.\n\t\t * \n\t\t * #NOTE: Copied from Obsidian.md API https://github.com/obsidianmd/obsidian-api/blob/master/obsidian.d.ts\n\t\t * \n * @param type\n */\n instanceOf(type: {\n new (): T;\n }): this is T;\n /**\n\t\t * The window object this node belongs to, or the global window.\n\t\t * \n\t\t * #NOTE: Copied from Obsidian.md API\n */\n win: Window;\n\t}\n}\n\n/** @public */\nexport function loopToHtmlElement(elm: Element): HTMLElement {\n\tif (elm.instanceOf(HTMLElement)) return elm\n\tif (elm.parentElement) return loopToHtmlElement(elm.parentElement)\n\telse throw Error('Could not find a parent element of an HTML type!')\n}\n\n/**\n * This function calls `event.preventDefault()` for you. Why is that useful?\n *\n * Beacuase if you enable `window.preventDefaultLogging = true` it'll log out a message when it\n * happens. Because we use console.warn rather than (log) you'll get a stack trace in the inspector\n * telling you exactly where it happened. This is important because `e.preventDefault()` is the\n * source of many bugs, but unfortuantly it can't be avoided because it also stops a lot of default\n * behaviour which doesn't make sense in our UI\n *\n * @param event - To prevent default on\n * @public\n */\nexport function preventDefault(event: React.BaseSyntheticEvent | Event) {\n\tevent.preventDefault()\n\tif (debugFlags.logPreventDefaults.get()) {\n\t\tconsole.warn('preventDefault called on event:', event)\n\t}\n}\n\n/** @public */\nexport function setPointerCapture(\n\telement: Element,\n\tevent: React.PointerEvent | PointerEvent\n) {\n\telement.setPointerCapture(event.pointerId)\n\tif (debugFlags.logPointerCaptures.get()) {\n\t\tconst trackingObj = pointerCaptureTrackingObject.get()\n\t\ttrackingObj.set(element, (trackingObj.get(element) ?? 0) + 1)\n\t\tconsole.warn('setPointerCapture called on element:', element, event)\n\t}\n}\n\n/** @public */\nexport function releasePointerCapture(\n\telement: Element,\n\tevent: React.PointerEvent | PointerEvent\n) {\n\tif (!element.hasPointerCapture(event.pointerId)) {\n\t\treturn\n\t}\n\n\telement.releasePointerCapture(event.pointerId)\n\tif (debugFlags.logPointerCaptures.get()) {\n\t\tconst trackingObj = pointerCaptureTrackingObject.get()\n\t\tif (trackingObj.get(element) === 1) {\n\t\t\ttrackingObj.delete(element)\n\t\t} else if (trackingObj.has(element)) {\n\t\t\ttrackingObj.set(element, trackingObj.get(element)! - 1)\n\t\t} else {\n\t\t\tconsole.warn('Release without capture')\n\t\t}\n\t\tconsole.warn('releasePointerCapture called on element:', element, event)\n\t}\n}\n\n/** @public */\nexport const stopEventPropagation = (e: any) => e.stopPropagation()\n\n/** @internal */\nexport const setStyleProperty = (\n\telm: HTMLElement | null,\n\tproperty: string,\n\tvalue: string | number\n) => {\n\tif (!elm) return\n\telm.style.setProperty(property, value as string)\n}\n"], -+ "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAgBA,yBAAyD;AA0BlD,SAAS,kBAAkB,KAA2B;AAC5D,MAAI,IAAI,WAAW,WAAW,EAAG,QAAO;AACxC,MAAI,IAAI,cAAe,QAAO,kBAAkB,IAAI,aAAa;AAAA,MAC5D,OAAM,MAAM,kDAAkD;AACpE;AAcO,SAAS,eAAe,OAAyC;AACvE,QAAM,eAAe;AACrB,MAAI,8BAAW,mBAAmB,IAAI,GAAG;AACxC,YAAQ,KAAK,mCAAmC,KAAK;AAAA,EACtD;AACD;AAGO,SAAS,kBACf,SACA,OACC;AACD,UAAQ,kBAAkB,MAAM,SAAS;AACzC,MAAI,8BAAW,mBAAmB,IAAI,GAAG;AACxC,UAAM,cAAc,gDAA6B,IAAI;AACrD,gBAAY,IAAI,UAAU,YAAY,IAAI,OAAO,KAAK,KAAK,CAAC;AAC5D,YAAQ,KAAK,wCAAwC,SAAS,KAAK;AAAA,EACpE;AACD;AAGO,SAAS,sBACf,SACA,OACC;AACD,MAAI,CAAC,QAAQ,kBAAkB,MAAM,SAAS,GAAG;AAChD;AAAA,EACD;AAEA,UAAQ,sBAAsB,MAAM,SAAS;AAC7C,MAAI,8BAAW,mBAAmB,IAAI,GAAG;AACxC,UAAM,cAAc,gDAA6B,IAAI;AACrD,QAAI,YAAY,IAAI,OAAO,MAAM,GAAG;AACnC,kBAAY,OAAO,OAAO;AAAA,IAC3B,WAAW,YAAY,IAAI,OAAO,GAAG;AACpC,kBAAY,IAAI,SAAS,YAAY,IAAI,OAAO,IAAK,CAAC;AAAA,IACvD,OAAO;AACN,cAAQ,KAAK,yBAAyB;AAAA,IACvC;AACA,YAAQ,KAAK,4CAA4C,SAAS,KAAK;AAAA,EACxE;AACD;AAGO,MAAM,uBAAuB,CAAC,MAAW,EAAE,gBAAgB;AAG3D,MAAM,mBAAmB,CAC/B,KACA,UACA,UACI;AACJ,MAAI,CAAC,IAAK;AACV,MAAI,MAAM,YAAY,UAAU,KAAe;AAChD;", - "names": [] - } -diff --git a/node_modules/@tldraw/editor/dist-esm/lib/editor/Editor.mjs b/node_modules/@tldraw/editor/dist-esm/lib/editor/Editor.mjs -index 7105cf6..0fa9b0f 100644 ---- a/node_modules/@tldraw/editor/dist-esm/lib/editor/Editor.mjs -+++ b/node_modules/@tldraw/editor/dist-esm/lib/editor/Editor.mjs -@@ -2515,7 +2515,7 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed] - * @public - */ - updateViewportScreenBounds(screenBounds, center = false) { -- if (screenBounds instanceof HTMLElement) { -+ if (!(screenBounds instanceof Box)) { - const rect = screenBounds.getBoundingClientRect(); - screenBounds = new Box( - rect.left || rect.x, -diff --git a/node_modules/@tldraw/editor/dist-esm/lib/editor/Editor.mjs.map b/node_modules/@tldraw/editor/dist-esm/lib/editor/Editor.mjs.map -index 1562263..76b6444 100644 ---- a/node_modules/@tldraw/editor/dist-esm/lib/editor/Editor.mjs.map -+++ b/node_modules/@tldraw/editor/dist-esm/lib/editor/Editor.mjs.map -@@ -1,7 +1,7 @@ - { - "version": 3, - "sources": ["../../../src/lib/editor/Editor.ts"], -- "sourcesContent": ["import { EMPTY_ARRAY, atom, computed, react, transact, unsafe__withoutCapture } from '@tldraw/state'\nimport {\n\tComputedCache,\n\tRecordType,\n\tStoreSideEffects,\n\tStoreSnapshot,\n\tUnknownRecord,\n\treverseRecordsDiff,\n} from '@tldraw/store'\nimport {\n\tCameraRecordType,\n\tInstancePageStateRecordType,\n\tPageRecordType,\n\tStyleProp,\n\tStylePropValue,\n\tTLArrowShape,\n\tTLAsset,\n\tTLAssetId,\n\tTLAssetPartial,\n\tTLBinding,\n\tTLBindingCreate,\n\tTLBindingId,\n\tTLBindingUpdate,\n\tTLCamera,\n\tTLCursor,\n\tTLCursorType,\n\tTLDOCUMENT_ID,\n\tTLDocument,\n\tTLFrameShape,\n\tTLGeoShape,\n\tTLGroupShape,\n\tTLHandle,\n\tTLINSTANCE_ID,\n\tTLImageAsset,\n\tTLInstance,\n\tTLInstancePageState,\n\tTLPOINTER_ID,\n\tTLPage,\n\tTLPageId,\n\tTLParentId,\n\tTLRecord,\n\tTLShape,\n\tTLShapeId,\n\tTLShapePartial,\n\tTLStore,\n\tTLStoreSnapshot,\n\tTLUnknownBinding,\n\tTLUnknownShape,\n\tTLVideoAsset,\n\tcreateBindingId,\n\tcreateShapeId,\n\tgetShapePropKeysByStyle,\n\tisPageId,\n\tisShapeId,\n} from '@tldraw/tlschema'\nimport {\n\tFileHelpers,\n\tIndexKey,\n\tJsonObject,\n\tPerformanceTracker,\n\tResult,\n\tTimers,\n\tannotateError,\n\tassert,\n\tassertExists,\n\tbind,\n\tcompact,\n\tdebounce,\n\tdedupe,\n\texhaustiveSwitchError,\n\tfetch,\n\tgetIndexAbove,\n\tgetIndexBetween,\n\tgetIndices,\n\tgetIndicesAbove,\n\tgetIndicesBetween,\n\tgetOwnProperty,\n\thasOwnProperty,\n\tlast,\n\tlerp,\n\tsortById,\n\tsortByIndex,\n\tstructuredClone,\n\tuniqueId,\n} from '@tldraw/utils'\nimport EventEmitter from 'eventemitter3'\nimport {\n\tTLEditorSnapshot,\n\tTLLoadSnapshotOptions,\n\tgetSnapshot,\n\tloadSnapshot,\n} from '../config/TLEditorSnapshot'\nimport { TLUser, createTLUser } from '../config/createTLUser'\nimport { TLAnyBindingUtilConstructor, checkBindings } from '../config/defaultBindings'\nimport { TLAnyShapeUtilConstructor, checkShapesAndAddCore } from '../config/defaultShapes'\nimport {\n\tDEFAULT_ANIMATION_OPTIONS,\n\tDEFAULT_CAMERA_OPTIONS,\n\tINTERNAL_POINTER_IDS,\n\tLEFT_MOUSE_BUTTON,\n\tMIDDLE_MOUSE_BUTTON,\n\tRIGHT_MOUSE_BUTTON,\n\tSTYLUS_ERASER_BUTTON,\n\tZOOM_TO_FIT_PADDING,\n} from '../constants'\nimport { exportToSvg } from '../exports/exportToSvg'\nimport { TldrawOptions, defaultTldrawOptions } from '../options'\nimport { Box, BoxLike } from '../primitives/Box'\nimport { Mat, MatLike } from '../primitives/Mat'\nimport { Vec, VecLike } from '../primitives/Vec'\nimport { EASINGS } from '../primitives/easings'\nimport { Geometry2d } from '../primitives/geometry/Geometry2d'\nimport { Group2d } from '../primitives/geometry/Group2d'\nimport { intersectPolygonPolygon } from '../primitives/intersect'\nimport { PI2, approximately, areAnglesCompatible, clamp, pointInPolygon } from '../primitives/utils'\nimport { ReadonlySharedStyleMap, SharedStyle, SharedStyleMap } from '../utils/SharedStylesMap'\nimport { dataUrlToFile } from '../utils/assets'\nimport { debugFlags } from '../utils/debug-flags'\nimport {\n\tTLDeepLink,\n\tTLDeepLinkOptions,\n\tcreateDeepLinkString,\n\tparseDeepLinkString,\n} from '../utils/deepLinks'\nimport { getIncrementedName } from '../utils/getIncrementedName'\nimport { getReorderingShapesChanges } from '../utils/reorderShapes'\nimport { applyRotationToSnapshotShapes, getRotationSnapshot } from '../utils/rotation'\nimport { BindingOnDeleteOptions, BindingUtil } from './bindings/BindingUtil'\nimport { bindingsIndex } from './derivations/bindingsIndex'\nimport { notVisibleShapes } from './derivations/notVisibleShapes'\nimport { parentsToChildren } from './derivations/parentsToChildren'\nimport { deriveShapeIdsInCurrentPage } from './derivations/shapeIdsInCurrentPage'\nimport { ClickManager } from './managers/ClickManager'\nimport { EdgeScrollManager } from './managers/EdgeScrollManager'\nimport { EnvironmentManager } from './managers/EnvironmentManager'\nimport { FocusManager } from './managers/FocusManager'\nimport { HistoryManager } from './managers/HistoryManager'\nimport { ScribbleManager } from './managers/ScribbleManager'\nimport { SnapManager } from './managers/SnapManager/SnapManager'\nimport { TextManager } from './managers/TextManager'\nimport { TickManager } from './managers/TickManager'\nimport { UserPreferencesManager } from './managers/UserPreferencesManager'\nimport { ShapeUtil, TLResizeMode } from './shapes/ShapeUtil'\nimport { RootState } from './tools/RootState'\nimport { StateNode, TLStateNodeConstructor } from './tools/StateNode'\nimport { TLContent } from './types/clipboard-types'\nimport { TLEventMap } from './types/emit-types'\nimport {\n\tTLEventInfo,\n\tTLPinchEventInfo,\n\tTLPointerEventInfo,\n\tTLWheelEventInfo,\n} from './types/event-types'\nimport { TLExternalAssetContent, TLExternalContent } from './types/external-content'\nimport { TLHistoryBatchOptions } from './types/history-types'\nimport {\n\tOptionalKeys,\n\tRequiredKeys,\n\tTLCameraMoveOptions,\n\tTLCameraOptions,\n\tTLImageExportOptions,\n} from './types/misc-types'\nimport { TLResizeHandle } from './types/selection-types'\n\n/** @public */\nexport type TLResizeShapeOptions = Partial<{\n\tinitialBounds: Box\n\tscaleOrigin: VecLike\n\tscaleAxisRotation: number\n\tinitialShape: TLShape\n\tinitialPageTransform: MatLike\n\tdragHandle: TLResizeHandle\n\tisAspectRatioLocked: boolean\n\tmode: TLResizeMode\n\tskipStartAndEndCallbacks: boolean\n}>\n\n/** @public */\nexport interface TLEditorOptions {\n\t/**\n\t * The Store instance to use for keeping the app's data. This may be prepopulated, e.g. by loading\n\t * from a server or database.\n\t */\n\tstore: TLStore\n\t/**\n\t * An array of shapes to use in the editor. These will be used to create and manage shapes in the editor.\n\t */\n\tshapeUtils: readonly TLAnyShapeUtilConstructor[]\n\t/**\n\t * An array of bindings to use in the editor. These will be used to create and manage bindings in the editor.\n\t */\n\tbindingUtils: readonly TLAnyBindingUtilConstructor[]\n\t/**\n\t * An array of tools to use in the editor. These will be used to handle events and manage user interactions in the editor.\n\t */\n\ttools: readonly TLStateNodeConstructor[]\n\t/**\n\t * Should return a containing html element which has all the styles applied to the editor. If not\n\t * given, the body element will be used.\n\t */\n\tgetContainer(): HTMLElement\n\t/**\n\t * A user defined externally to replace the default user.\n\t */\n\tuser?: TLUser\n\t/**\n\t * The editor's initial active tool (or other state node id).\n\t */\n\tinitialState?: string\n\t/**\n\t * Whether to automatically focus the editor when it mounts.\n\t */\n\tautoFocus?: boolean\n\t/**\n\t * Whether to infer dark mode from the user's system preferences. Defaults to false.\n\t */\n\tinferDarkMode?: boolean\n\t/**\n\t * Options for the editor's camera.\n\t */\n\tcameraOptions?: Partial\n\toptions?: Partial\n\tlicenseKey?: string\n\t/**\n\t * A predicate that should return true if the given shape should be hidden.\n\t * @param shape - The shape to check.\n\t * @param editor - The editor instance.\n\t */\n\tisShapeHidden?(shape: TLShape, editor: Editor): boolean\n}\n\n/**\n * Options for {@link Editor.(run:1)}.\n * @public\n */\nexport interface TLEditorRunOptions extends TLHistoryBatchOptions {\n\tignoreShapeLock?: boolean\n}\n\n/** @public */\nexport interface TLRenderingShape {\n\tid: TLShapeId\n\tshape: TLShape\n\tutil: ShapeUtil\n\tindex: number\n\tbackgroundIndex: number\n\topacity: number\n}\n\n/** @public */\nexport class Editor extends EventEmitter {\n\tconstructor({\n\t\tstore,\n\t\tuser,\n\t\tshapeUtils,\n\t\tbindingUtils,\n\t\ttools,\n\t\tgetContainer,\n\t\tcameraOptions,\n\t\tinitialState,\n\t\tautoFocus,\n\t\tinferDarkMode,\n\t\toptions,\n\t\tisShapeHidden,\n\t}: TLEditorOptions) {\n\t\tsuper()\n\n\t\tthis._isShapeHiddenPredicate = isShapeHidden\n\n\t\tthis.options = { ...defaultTldrawOptions, ...options }\n\t\tthis.store = store\n\t\tthis.disposables.add(this.store.dispose.bind(this.store))\n\t\tthis.history = new HistoryManager({\n\t\t\tstore,\n\t\t\tannotateError: (error) => {\n\t\t\t\tthis.annotateError(error, { origin: 'history.batch', willCrashApp: true })\n\t\t\t\tthis.crash(error)\n\t\t\t},\n\t\t})\n\n\t\tthis.snaps = new SnapManager(this)\n\n\t\tthis.timers = new Timers()\n\t\tthis.disposables.add(this.timers.dispose.bind(this.timers))\n\n\t\tthis._cameraOptions.set({ ...DEFAULT_CAMERA_OPTIONS, ...cameraOptions })\n\n\t\tthis.user = new UserPreferencesManager(user ?? createTLUser(), inferDarkMode ?? false)\n\n\t\tthis.getContainer = getContainer\n\n\t\tthis.textMeasure = new TextManager(this)\n\t\tthis._tickManager = new TickManager(this)\n\n\t\tclass NewRoot extends RootState {\n\t\t\tstatic override initial = initialState ?? ''\n\t\t}\n\n\t\tthis.root = new NewRoot(this)\n\t\tthis.root.children = {}\n\n\t\tconst allShapeUtils = checkShapesAndAddCore(shapeUtils)\n\n\t\tconst _shapeUtils = {} as Record>\n\t\tconst _styleProps = {} as Record, string>>\n\t\tconst allStylesById = new Map>()\n\n\t\tfor (const Util of allShapeUtils) {\n\t\t\tconst util = new Util(this)\n\t\t\t_shapeUtils[Util.type] = util\n\n\t\t\tconst propKeysByStyle = getShapePropKeysByStyle(Util.props ?? {})\n\t\t\t_styleProps[Util.type] = propKeysByStyle\n\n\t\t\tfor (const style of propKeysByStyle.keys()) {\n\t\t\t\tif (!allStylesById.has(style.id)) {\n\t\t\t\t\tallStylesById.set(style.id, style)\n\t\t\t\t} else if (allStylesById.get(style.id) !== style) {\n\t\t\t\t\tthrow Error(\n\t\t\t\t\t\t`Multiple style props with id \"${style.id}\" in use. Style prop IDs must be unique.`\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tthis.shapeUtils = _shapeUtils\n\t\tthis.styleProps = _styleProps\n\n\t\tconst allBindingUtils = checkBindings(bindingUtils)\n\t\tconst _bindingUtils = {} as Record>\n\t\tfor (const Util of allBindingUtils) {\n\t\t\tconst util = new Util(this)\n\t\t\t_bindingUtils[Util.type] = util\n\t\t}\n\t\tthis.bindingUtils = _bindingUtils\n\n\t\t// Tools.\n\t\t// Accept tools from constructor parameters which may not conflict with the root note's default or\n\t\t// \"baked in\" tools, select and zoom.\n\t\tfor (const Tool of [...tools]) {\n\t\t\tif (hasOwnProperty(this.root.children!, Tool.id)) {\n\t\t\t\tthrow Error(`Can't override tool with id \"${Tool.id}\"`)\n\t\t\t}\n\t\t\tthis.root.children![Tool.id] = new Tool(this, this.root)\n\t\t}\n\n\t\tthis.environment = new EnvironmentManager(this)\n\t\tthis.scribbles = new ScribbleManager(this)\n\n\t\t// Cleanup\n\n\t\tconst cleanupInstancePageState = (\n\t\t\tprevPageState: TLInstancePageState,\n\t\t\tshapesNoLongerInPage: Set\n\t\t) => {\n\t\t\tlet nextPageState = null as null | TLInstancePageState\n\n\t\t\tconst selectedShapeIds = prevPageState.selectedShapeIds.filter(\n\t\t\t\t(id) => !shapesNoLongerInPage.has(id)\n\t\t\t)\n\t\t\tif (selectedShapeIds.length !== prevPageState.selectedShapeIds.length) {\n\t\t\t\tif (!nextPageState) nextPageState = { ...prevPageState }\n\t\t\t\tnextPageState.selectedShapeIds = selectedShapeIds\n\t\t\t}\n\n\t\t\tconst erasingShapeIds = prevPageState.erasingShapeIds.filter(\n\t\t\t\t(id) => !shapesNoLongerInPage.has(id)\n\t\t\t)\n\t\t\tif (erasingShapeIds.length !== prevPageState.erasingShapeIds.length) {\n\t\t\t\tif (!nextPageState) nextPageState = { ...prevPageState }\n\t\t\t\tnextPageState.erasingShapeIds = erasingShapeIds\n\t\t\t}\n\n\t\t\tif (prevPageState.hoveredShapeId && shapesNoLongerInPage.has(prevPageState.hoveredShapeId)) {\n\t\t\t\tif (!nextPageState) nextPageState = { ...prevPageState }\n\t\t\t\tnextPageState.hoveredShapeId = null\n\t\t\t}\n\n\t\t\tif (prevPageState.editingShapeId && shapesNoLongerInPage.has(prevPageState.editingShapeId)) {\n\t\t\t\tif (!nextPageState) nextPageState = { ...prevPageState }\n\t\t\t\tnextPageState.editingShapeId = null\n\t\t\t}\n\n\t\t\tconst hintingShapeIds = prevPageState.hintingShapeIds.filter(\n\t\t\t\t(id) => !shapesNoLongerInPage.has(id)\n\t\t\t)\n\t\t\tif (hintingShapeIds.length !== prevPageState.hintingShapeIds.length) {\n\t\t\t\tif (!nextPageState) nextPageState = { ...prevPageState }\n\t\t\t\tnextPageState.hintingShapeIds = hintingShapeIds\n\t\t\t}\n\n\t\t\tif (prevPageState.focusedGroupId && shapesNoLongerInPage.has(prevPageState.focusedGroupId)) {\n\t\t\t\tif (!nextPageState) nextPageState = { ...prevPageState }\n\t\t\t\tnextPageState.focusedGroupId = null\n\t\t\t}\n\t\t\treturn nextPageState\n\t\t}\n\n\t\tthis.sideEffects = this.store.sideEffects\n\n\t\tlet deletedBindings = new Map>()\n\t\tconst deletedShapeIds = new Set()\n\t\tconst invalidParents = new Set()\n\t\tlet invalidBindingTypes = new Set()\n\t\tthis.disposables.add(\n\t\t\tthis.sideEffects.registerOperationCompleteHandler(() => {\n\t\t\t\t// this needs to be cleared here because further effects may delete more shapes\n\t\t\t\t// and we want the next invocation of this handler to handle those separately\n\t\t\t\tdeletedShapeIds.clear()\n\n\t\t\t\tfor (const parentId of invalidParents) {\n\t\t\t\t\tinvalidParents.delete(parentId)\n\t\t\t\t\tconst parent = this.getShape(parentId)\n\t\t\t\t\tif (!parent) continue\n\n\t\t\t\t\tconst util = this.getShapeUtil(parent)\n\t\t\t\t\tconst changes = util.onChildrenChange?.(parent)\n\n\t\t\t\t\tif (changes?.length) {\n\t\t\t\t\t\tthis.updateShapes(changes)\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (invalidBindingTypes.size) {\n\t\t\t\t\tconst t = invalidBindingTypes\n\t\t\t\t\tinvalidBindingTypes = new Set()\n\t\t\t\t\tfor (const type of t) {\n\t\t\t\t\t\tconst util = this.getBindingUtil(type)\n\t\t\t\t\t\tutil.onOperationComplete?.()\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (deletedBindings.size) {\n\t\t\t\t\tconst t = deletedBindings\n\t\t\t\t\tdeletedBindings = new Map()\n\t\t\t\t\tfor (const opts of t.values()) {\n\t\t\t\t\t\tthis.getBindingUtil(opts.binding).onAfterDelete?.(opts)\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tthis.emit('update')\n\t\t\t})\n\t\t)\n\n\t\tthis.disposables.add(\n\t\t\tthis.sideEffects.register({\n\t\t\t\tshape: {\n\t\t\t\t\tafterChange: (shapeBefore, shapeAfter) => {\n\t\t\t\t\t\tfor (const binding of this.getBindingsInvolvingShape(shapeAfter)) {\n\t\t\t\t\t\t\tinvalidBindingTypes.add(binding.type)\n\t\t\t\t\t\t\tif (binding.fromId === shapeAfter.id) {\n\t\t\t\t\t\t\t\tthis.getBindingUtil(binding).onAfterChangeFromShape?.({\n\t\t\t\t\t\t\t\t\tbinding,\n\t\t\t\t\t\t\t\t\tshapeBefore,\n\t\t\t\t\t\t\t\t\tshapeAfter,\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (binding.toId === shapeAfter.id) {\n\t\t\t\t\t\t\t\tthis.getBindingUtil(binding).onAfterChangeToShape?.({\n\t\t\t\t\t\t\t\t\tbinding,\n\t\t\t\t\t\t\t\t\tshapeBefore,\n\t\t\t\t\t\t\t\t\tshapeAfter,\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// if the shape's parent changed and it has a binding, update the binding\n\t\t\t\t\t\tif (shapeBefore.parentId !== shapeAfter.parentId) {\n\t\t\t\t\t\t\tconst notifyBindingAncestryChange = (id: TLShapeId) => {\n\t\t\t\t\t\t\t\tconst descendantShape = this.getShape(id)\n\t\t\t\t\t\t\t\tif (!descendantShape) return\n\n\t\t\t\t\t\t\t\tfor (const binding of this.getBindingsInvolvingShape(descendantShape)) {\n\t\t\t\t\t\t\t\t\tinvalidBindingTypes.add(binding.type)\n\n\t\t\t\t\t\t\t\t\tif (binding.fromId === descendantShape.id) {\n\t\t\t\t\t\t\t\t\t\tthis.getBindingUtil(binding).onAfterChangeFromShape?.({\n\t\t\t\t\t\t\t\t\t\t\tbinding,\n\t\t\t\t\t\t\t\t\t\t\tshapeBefore: descendantShape,\n\t\t\t\t\t\t\t\t\t\t\tshapeAfter: descendantShape,\n\t\t\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tif (binding.toId === descendantShape.id) {\n\t\t\t\t\t\t\t\t\t\tthis.getBindingUtil(binding).onAfterChangeToShape?.({\n\t\t\t\t\t\t\t\t\t\t\tbinding,\n\t\t\t\t\t\t\t\t\t\t\tshapeBefore: descendantShape,\n\t\t\t\t\t\t\t\t\t\t\tshapeAfter: descendantShape,\n\t\t\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tnotifyBindingAncestryChange(shapeAfter.id)\n\t\t\t\t\t\t\tthis.visitDescendants(shapeAfter.id, notifyBindingAncestryChange)\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// if this shape moved to a new page, clean up any previous page's instance state\n\t\t\t\t\t\tif (shapeBefore.parentId !== shapeAfter.parentId && isPageId(shapeAfter.parentId)) {\n\t\t\t\t\t\t\tconst allMovingIds = new Set([shapeBefore.id])\n\t\t\t\t\t\t\tthis.visitDescendants(shapeBefore.id, (id) => {\n\t\t\t\t\t\t\t\tallMovingIds.add(id)\n\t\t\t\t\t\t\t})\n\n\t\t\t\t\t\t\tfor (const instancePageState of this.getPageStates()) {\n\t\t\t\t\t\t\t\tif (instancePageState.pageId === shapeAfter.parentId) continue\n\t\t\t\t\t\t\t\tconst nextPageState = cleanupInstancePageState(instancePageState, allMovingIds)\n\n\t\t\t\t\t\t\t\tif (nextPageState) {\n\t\t\t\t\t\t\t\t\tthis.store.put([nextPageState])\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (shapeBefore.parentId && isShapeId(shapeBefore.parentId)) {\n\t\t\t\t\t\t\tinvalidParents.add(shapeBefore.parentId)\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (shapeAfter.parentId !== shapeBefore.parentId && isShapeId(shapeAfter.parentId)) {\n\t\t\t\t\t\t\tinvalidParents.add(shapeAfter.parentId)\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t\tbeforeDelete: (shape) => {\n\t\t\t\t\t\t// if we triggered this delete with a recursive call, don't do anything\n\t\t\t\t\t\tif (deletedShapeIds.has(shape.id)) return\n\t\t\t\t\t\t// if the deleted shape has a parent shape make sure we call it's onChildrenChange callback\n\t\t\t\t\t\tif (shape.parentId && isShapeId(shape.parentId)) {\n\t\t\t\t\t\t\tinvalidParents.add(shape.parentId)\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tdeletedShapeIds.add(shape.id)\n\n\t\t\t\t\t\tconst deleteBindingIds: TLBindingId[] = []\n\t\t\t\t\t\tfor (const binding of this.getBindingsInvolvingShape(shape)) {\n\t\t\t\t\t\t\tinvalidBindingTypes.add(binding.type)\n\t\t\t\t\t\t\tdeleteBindingIds.push(binding.id)\n\t\t\t\t\t\t\tconst util = this.getBindingUtil(binding)\n\t\t\t\t\t\t\tif (binding.fromId === shape.id) {\n\t\t\t\t\t\t\t\tutil.onBeforeIsolateToShape?.({ binding, removedShape: shape })\n\t\t\t\t\t\t\t\tutil.onBeforeDeleteFromShape?.({ binding, shape })\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tutil.onBeforeIsolateFromShape?.({ binding, removedShape: shape })\n\t\t\t\t\t\t\t\tutil.onBeforeDeleteToShape?.({ binding, shape })\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (deleteBindingIds.length) {\n\t\t\t\t\t\t\tthis.deleteBindings(deleteBindingIds)\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst deletedIds = new Set([shape.id])\n\t\t\t\t\t\tconst updates = compact(\n\t\t\t\t\t\t\tthis.getPageStates().map((pageState) => {\n\t\t\t\t\t\t\t\treturn cleanupInstancePageState(pageState, deletedIds)\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t)\n\n\t\t\t\t\t\tif (updates.length) {\n\t\t\t\t\t\t\tthis.store.put(updates)\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tbinding: {\n\t\t\t\t\tbeforeCreate: (binding) => {\n\t\t\t\t\t\tconst next = this.getBindingUtil(binding).onBeforeCreate?.({ binding })\n\t\t\t\t\t\tif (next) return next\n\t\t\t\t\t\treturn binding\n\t\t\t\t\t},\n\t\t\t\t\tafterCreate: (binding) => {\n\t\t\t\t\t\tinvalidBindingTypes.add(binding.type)\n\t\t\t\t\t\tthis.getBindingUtil(binding).onAfterCreate?.({ binding })\n\t\t\t\t\t},\n\t\t\t\t\tbeforeChange: (bindingBefore, bindingAfter) => {\n\t\t\t\t\t\tconst updated = this.getBindingUtil(bindingAfter).onBeforeChange?.({\n\t\t\t\t\t\t\tbindingBefore,\n\t\t\t\t\t\t\tbindingAfter,\n\t\t\t\t\t\t})\n\t\t\t\t\t\tif (updated) return updated\n\t\t\t\t\t\treturn bindingAfter\n\t\t\t\t\t},\n\t\t\t\t\tafterChange: (bindingBefore, bindingAfter) => {\n\t\t\t\t\t\tinvalidBindingTypes.add(bindingAfter.type)\n\t\t\t\t\t\tthis.getBindingUtil(bindingAfter).onAfterChange?.({ bindingBefore, bindingAfter })\n\t\t\t\t\t},\n\t\t\t\t\tbeforeDelete: (binding) => {\n\t\t\t\t\t\tthis.getBindingUtil(binding).onBeforeDelete?.({ binding })\n\t\t\t\t\t},\n\t\t\t\t\tafterDelete: (binding) => {\n\t\t\t\t\t\tthis.getBindingUtil(binding).onAfterDelete?.({ binding })\n\t\t\t\t\t\tinvalidBindingTypes.add(binding.type)\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tpage: {\n\t\t\t\t\tafterCreate: (record) => {\n\t\t\t\t\t\tconst cameraId = CameraRecordType.createId(record.id)\n\t\t\t\t\t\tconst _pageStateId = InstancePageStateRecordType.createId(record.id)\n\t\t\t\t\t\tif (!this.store.has(cameraId)) {\n\t\t\t\t\t\t\tthis.store.put([CameraRecordType.create({ id: cameraId })])\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (!this.store.has(_pageStateId)) {\n\t\t\t\t\t\t\tthis.store.put([\n\t\t\t\t\t\t\t\tInstancePageStateRecordType.create({ id: _pageStateId, pageId: record.id }),\n\t\t\t\t\t\t\t])\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t\tafterDelete: (record, source) => {\n\t\t\t\t\t\t// page was deleted, need to check whether it's the current page and select another one if so\n\t\t\t\t\t\tif (this.getInstanceState()?.currentPageId === record.id) {\n\t\t\t\t\t\t\tconst backupPageId = this.getPages().find((p) => p.id !== record.id)?.id\n\t\t\t\t\t\t\tif (backupPageId) {\n\t\t\t\t\t\t\t\tthis.store.put([{ ...this.getInstanceState(), currentPageId: backupPageId }])\n\t\t\t\t\t\t\t} else if (source === 'user') {\n\t\t\t\t\t\t\t\t// fall back to ensureStoreIsUsable:\n\t\t\t\t\t\t\t\tthis.store.ensureStoreIsUsable()\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// delete the camera and state for the page if necessary\n\t\t\t\t\t\tconst cameraId = CameraRecordType.createId(record.id)\n\t\t\t\t\t\tconst instance_PageStateId = InstancePageStateRecordType.createId(record.id)\n\t\t\t\t\t\tthis.store.remove([cameraId, instance_PageStateId])\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tinstance: {\n\t\t\t\t\tafterChange: (prev, next, source) => {\n\t\t\t\t\t\t// instance should never be updated to a page that no longer exists (this can\n\t\t\t\t\t\t// happen when undoing a change that involves switching to a page that has since\n\t\t\t\t\t\t// been deleted by another user)\n\t\t\t\t\t\tif (!this.store.has(next.currentPageId)) {\n\t\t\t\t\t\t\tconst backupPageId = this.store.has(prev.currentPageId)\n\t\t\t\t\t\t\t\t? prev.currentPageId\n\t\t\t\t\t\t\t\t: this.getPages()[0]?.id\n\t\t\t\t\t\t\tif (backupPageId) {\n\t\t\t\t\t\t\t\tthis.store.update(next.id, (instance) => ({\n\t\t\t\t\t\t\t\t\t...instance,\n\t\t\t\t\t\t\t\t\tcurrentPageId: backupPageId,\n\t\t\t\t\t\t\t\t}))\n\t\t\t\t\t\t\t} else if (source === 'user') {\n\t\t\t\t\t\t\t\t// fall back to ensureStoreIsUsable:\n\t\t\t\t\t\t\t\tthis.store.ensureStoreIsUsable()\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tinstance_page_state: {\n\t\t\t\t\tafterChange: (prev, next) => {\n\t\t\t\t\t\tif (prev?.selectedShapeIds !== next?.selectedShapeIds) {\n\t\t\t\t\t\t\t// ensure that descendants and ancestors are not selected at the same time\n\t\t\t\t\t\t\tconst filtered = next.selectedShapeIds.filter((id) => {\n\t\t\t\t\t\t\t\tlet parentId = this.getShape(id)?.parentId\n\t\t\t\t\t\t\t\twhile (isShapeId(parentId)) {\n\t\t\t\t\t\t\t\t\tif (next.selectedShapeIds.includes(parentId)) {\n\t\t\t\t\t\t\t\t\t\treturn false\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tparentId = this.getShape(parentId)?.parentId\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\treturn true\n\t\t\t\t\t\t\t})\n\n\t\t\t\t\t\t\tlet nextFocusedGroupId: null | TLShapeId = null\n\n\t\t\t\t\t\t\tif (filtered.length > 0) {\n\t\t\t\t\t\t\t\tconst commonGroupAncestor = this.findCommonAncestor(\n\t\t\t\t\t\t\t\t\tcompact(filtered.map((id) => this.getShape(id))),\n\t\t\t\t\t\t\t\t\t(shape) => this.isShapeOfType(shape, 'group')\n\t\t\t\t\t\t\t\t)\n\n\t\t\t\t\t\t\t\tif (commonGroupAncestor) {\n\t\t\t\t\t\t\t\t\tnextFocusedGroupId = commonGroupAncestor\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tif (next?.focusedGroupId) {\n\t\t\t\t\t\t\t\t\tnextFocusedGroupId = next.focusedGroupId\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\tfiltered.length !== next.selectedShapeIds.length ||\n\t\t\t\t\t\t\t\tnextFocusedGroupId !== next.focusedGroupId\n\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\tthis.store.put([\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t...next,\n\t\t\t\t\t\t\t\t\t\tselectedShapeIds: filtered,\n\t\t\t\t\t\t\t\t\t\tfocusedGroupId: nextFocusedGroupId ?? null,\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t])\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t})\n\t\t)\n\n\t\tthis._currentPageShapeIds = deriveShapeIdsInCurrentPage(this.store, () =>\n\t\t\tthis.getCurrentPageId()\n\t\t)\n\t\tthis._parentIdsToChildIds = parentsToChildren(this.store)\n\n\t\tthis.disposables.add(\n\t\t\tthis.store.listen((changes) => {\n\t\t\t\tthis.emit('change', changes)\n\t\t\t})\n\t\t)\n\t\tthis.disposables.add(this.history.dispose)\n\n\t\tthis.run(\n\t\t\t() => {\n\t\t\t\tthis.store.ensureStoreIsUsable()\n\n\t\t\t\t// clear ephemeral state\n\t\t\t\tthis._updateCurrentPageState({\n\t\t\t\t\teditingShapeId: null,\n\t\t\t\t\thoveredShapeId: null,\n\t\t\t\t\terasingShapeIds: [],\n\t\t\t\t})\n\t\t\t},\n\t\t\t{ history: 'ignore' }\n\t\t)\n\n\t\tif (initialState && this.root.children[initialState] === undefined) {\n\t\t\tthrow Error(`No state found for initialState \"${initialState}\".`)\n\t\t}\n\n\t\tthis.root.enter(undefined, 'initial')\n\n\t\tthis.edgeScrollManager = new EdgeScrollManager(this)\n\t\tthis.focusManager = new FocusManager(this, autoFocus)\n\t\tthis.disposables.add(this.focusManager.dispose.bind(this.focusManager))\n\n\t\tif (this.getInstanceState().followingUserId) {\n\t\t\tthis.stopFollowingUser()\n\t\t}\n\n\t\tthis.on('tick', this._flushEventsForTick)\n\n\t\tthis.timers.requestAnimationFrame(() => {\n\t\t\tthis._tickManager.start()\n\t\t})\n\n\t\tthis.performanceTracker = new PerformanceTracker()\n\t}\n\n\tprivate readonly _isShapeHiddenPredicate?: (shape: TLShape, editor: Editor) => boolean\n\t@computed\n\tprivate getIsShapeHiddenCache() {\n\t\tif (!this._isShapeHiddenPredicate) return null\n\t\treturn this.store.createComputedCache('isShapeHidden', (shape: TLShape) => {\n\t\t\tconst hiddenParent = this.findShapeAncestor(shape, (p) => this.isShapeHidden(p))\n\t\t\tif (hiddenParent) return true\n\t\t\treturn this._isShapeHiddenPredicate!(shape, this) ?? false\n\t\t})\n\t}\n\tisShapeHidden(shapeOrId: TLShape | TLShapeId): boolean {\n\t\tif (!this._isShapeHiddenPredicate) return false\n\t\treturn !!this.getIsShapeHiddenCache!()!.get(\n\t\t\ttypeof shapeOrId === 'string' ? shapeOrId : shapeOrId.id\n\t\t)\n\t}\n\n\treadonly options: TldrawOptions\n\n\t/**\n\t * The editor's store\n\t *\n\t * @public\n\t */\n\treadonly store: TLStore\n\n\t/**\n\t * The root state of the statechart.\n\t *\n\t * @public\n\t */\n\treadonly root: StateNode\n\n\t/**\n\t * A set of functions to call when the app is disposed.\n\t *\n\t * @public\n\t */\n\treadonly disposables = new Set<() => void>()\n\n\t/**\n\t * Whether the editor is disposed.\n\t *\n\t * @public\n\t */\n\tisDisposed = false\n\n\t/** @internal */\n\tprivate readonly _tickManager\n\n\t/**\n\t * A manager for the app's snapping feature.\n\t *\n\t * @public\n\t */\n\treadonly snaps: SnapManager\n\n\t/**\n\t * A manager for the any asynchronous events and making sure they're\n\t * cleaned up upon disposal.\n\t *\n\t * @public\n\t */\n\treadonly timers: Timers\n\n\t/**\n\t * A manager for the user and their preferences.\n\t *\n\t * @public\n\t */\n\treadonly user: UserPreferencesManager\n\n\t/**\n\t * A helper for measuring text.\n\t *\n\t * @public\n\t */\n\treadonly textMeasure: TextManager\n\n\t/**\n\t * A manager for the editor's environment.\n\t *\n\t * @public\n\t */\n\treadonly environment: EnvironmentManager\n\n\t/**\n\t * A manager for the editor's scribbles.\n\t *\n\t * @public\n\t */\n\treadonly scribbles: ScribbleManager\n\n\t/**\n\t * A manager for side effects and correct state enforcement. See {@link @tldraw/store#StoreSideEffects} for details.\n\t *\n\t * @public\n\t */\n\treadonly sideEffects: StoreSideEffects\n\n\t/**\n\t * A manager for moving the camera when the mouse is at the edge of the screen.\n\t *\n\t * @public\n\t */\n\tedgeScrollManager: EdgeScrollManager\n\n\t/**\n\t * A manager for ensuring correct focus. See FocusManager for details.\n\t *\n\t * @internal\n\t */\n\tprivate focusManager: FocusManager\n\n\t/**\n\t * The current HTML element containing the editor.\n\t *\n\t * @example\n\t * ```ts\n\t * const container = editor.getContainer()\n\t * ```\n\t *\n\t * @public\n\t */\n\tgetContainer: () => HTMLElement\n\n\t/**\n\t * Dispose the editor.\n\t *\n\t * @public\n\t */\n\tdispose() {\n\t\tthis.disposables.forEach((dispose) => dispose())\n\t\tthis.disposables.clear()\n\t\tthis.isDisposed = true\n\t}\n\n\t/* ------------------- Shape Utils ------------------ */\n\n\t/**\n\t * A map of shape utility classes (TLShapeUtils) by shape type.\n\t *\n\t * @public\n\t */\n\tshapeUtils: { readonly [K in string]?: ShapeUtil }\n\n\tstyleProps: { [key: string]: Map, string> }\n\n\t/**\n\t * Get a shape util from a shape itself.\n\t *\n\t * @example\n\t * ```ts\n\t * const util = editor.getShapeUtil(myArrowShape)\n\t * const util = editor.getShapeUtil('arrow')\n\t * const util = editor.getShapeUtil(myArrowShape)\n\t * const util = editor.getShapeUtil(TLArrowShape)('arrow')\n\t * ```\n\t *\n\t * @param shape - A shape, shape partial, or shape type.\n\t *\n\t * @public\n\t */\n\tgetShapeUtil(shape: S | TLShapePartial): ShapeUtil\n\tgetShapeUtil(type: S['type']): ShapeUtil\n\tgetShapeUtil(type: T extends ShapeUtil ? R['type'] : string): T\n\tgetShapeUtil(arg: string | { type: string }) {\n\t\tconst type = typeof arg === 'string' ? arg : arg.type\n\t\tconst shapeUtil = getOwnProperty(this.shapeUtils, type)\n\t\tassert(shapeUtil, `No shape util found for type \"${type}\"`)\n\t\treturn shapeUtil\n\t}\n\n\t/* ------------------- Binding Utils ------------------ */\n\t/**\n\t * A map of shape utility classes (TLShapeUtils) by shape type.\n\t *\n\t * @public\n\t */\n\tbindingUtils: { readonly [K in string]?: BindingUtil }\n\n\t/**\n\t * Get a binding util from a binding itself.\n\t *\n\t * @example\n\t * ```ts\n\t * const util = editor.getBindingUtil(myArrowBinding)\n\t * const util = editor.getBindingUtil('arrow')\n\t * const util = editor.getBindingUtil(myArrowBinding)\n\t * const util = editor.getBindingUtil(TLArrowBinding)('arrow')\n\t * ```\n\t *\n\t * @param binding - A binding, binding partial, or binding type.\n\t *\n\t * @public\n\t */\n\tgetBindingUtil(binding: S | { type: S['type'] }): BindingUtil\n\tgetBindingUtil(type: S['type']): BindingUtil\n\tgetBindingUtil(\n\t\ttype: T extends BindingUtil ? R['type'] : string\n\t): T\n\tgetBindingUtil(arg: string | { type: string }) {\n\t\tconst type = typeof arg === 'string' ? arg : arg.type\n\t\tconst bindingUtil = getOwnProperty(this.bindingUtils, type)\n\t\tassert(bindingUtil, `No binding util found for type \"${type}\"`)\n\t\treturn bindingUtil\n\t}\n\n\t/* --------------------- History -------------------- */\n\n\t/**\n\t * A manager for the app's history.\n\t *\n\t * @readonly\n\t */\n\tprotected readonly history: HistoryManager\n\n\t/**\n\t * Undo to the last mark.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.undo()\n\t * ```\n\t *\n\t * @public\n\t */\n\tundo(): this {\n\t\tthis._flushEventsForTick(0)\n\t\tthis.complete()\n\t\tthis.history.undo()\n\t\treturn this\n\t}\n\n\t/**\n\t * Whether the app can undo.\n\t *\n\t * @public\n\t */\n\t@computed getCanUndo(): boolean {\n\t\treturn this.history.getNumUndos() > 0\n\t}\n\n\t/**\n\t * Redo to the next mark.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.redo()\n\t * ```\n\t *\n\t * @public\n\t */\n\tredo(): this {\n\t\tthis._flushEventsForTick(0)\n\t\tthis.complete()\n\t\tthis.history.redo()\n\t\treturn this\n\t}\n\n\tclearHistory() {\n\t\tthis.history.clear()\n\t\treturn this\n\t}\n\n\t/**\n\t * Whether the app can redo.\n\t *\n\t * @public\n\t */\n\t@computed getCanRedo(): boolean {\n\t\treturn this.history.getNumRedos() > 0\n\t}\n\n\t/**\n\t * Create a new \"mark\", or stopping point, in the undo redo history. Creating a mark will clear\n\t * any redos.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.mark()\n\t * editor.mark('flip shapes')\n\t * ```\n\t *\n\t * @param markId - The mark's id, usually the reason for adding the mark.\n\t *\n\t * @public\n\t * @deprecated use {@link Editor.markHistoryStoppingPoint} instead\n\t */\n\tmark(markId?: string): this {\n\t\tif (typeof markId === 'string') {\n\t\t\tconsole.warn(\n\t\t\t\t`[tldraw] \\`editor.history.mark(\"${markId}\")\\` is deprecated. Please use \\`const myMarkId = editor.markHistoryStoppingPoint()\\` instead.`\n\t\t\t)\n\t\t} else {\n\t\t\tconsole.warn(\n\t\t\t\t'[tldraw] `editor.mark()` is deprecated. Use `editor.markHistoryStoppingPoint()` instead.'\n\t\t\t)\n\t\t}\n\t\tthis.history._mark(markId ?? uniqueId())\n\t\treturn this\n\t}\n\n\t/**\n\t * Create a new \"mark\", or stopping point, in the undo redo history. Creating a mark will clear\n\t * any redos. You typically want to do this just before a user interaction begins or is handled.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.markHistoryStoppingPoint()\n\t * editor.flipShapes(editor.getSelectedShapes())\n\t * ```\n\t * @example\n\t * ```ts\n\t * const beginRotateMark = editor.markHistoryStoppingPoint()\n\t * // if the use cancels the rotation, you can bail back to this mark\n\t * editor.bailToMark(beginRotateMark)\n\t * ```\n\t *\n\t * @public\n\t * @param name - The name of the mark, useful for debugging the undo/redo stacks\n\t * @returns a unique id for the mark that can be used with `squashToMark` or `bailToMark`.\n\t */\n\tmarkHistoryStoppingPoint(name?: string): string {\n\t\tconst id = `[${name ?? 'stop'}]_${uniqueId()}`\n\t\tthis.history._mark(id)\n\t\treturn id\n\t}\n\n\t/**\n\t * @internal this is only used to implement some backwards-compatibility logic. Should be fine to delete after 6 months or whatever.\n\t */\n\tgetMarkIdMatching(idSubstring: string) {\n\t\treturn this.history.getMarkIdMatching(idSubstring)\n\t}\n\n\t/**\n\t * Coalesces all changes since the given mark into a single change, removing any intermediate marks.\n\t *\n\t * This is useful if you need to 'compress' the recent history to simplify the undo/redo experience of a complex interaction.\n\t *\n\t * @example\n\t * ```ts\n\t * const bumpShapesMark = editor.markHistoryStoppingPoint()\n\t * // ... some changes\n\t * editor.squashToMark(bumpShapesMark)\n\t * ```\n\t *\n\t * @param markId - The mark id to squash to.\n\t */\n\tsquashToMark(markId: string): this {\n\t\tthis.history.squashToMark(markId)\n\t\treturn this\n\t}\n\n\t/**\n\t * Undo to the closest mark, discarding the changes so they cannot be redone.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.bail()\n\t * ```\n\t *\n\t * @public\n\t */\n\tbail() {\n\t\tthis.history.bail()\n\t\treturn this\n\t}\n\n\t/**\n\t * Undo to the given mark, discarding the changes so they cannot be redone.\n\t *\n\t * @example\n\t * ```ts\n\t * const beginDrag = editor.markHistoryStoppingPoint()\n\t * // ... some changes\n\t * editor.bailToMark(beginDrag)\n\t * ```\n\t *\n\t * @public\n\t */\n\tbailToMark(id: string): this {\n\t\tthis.history.bailToMark(id)\n\t\treturn this\n\t}\n\n\tprivate _shouldIgnoreShapeLock = false\n\n\t/**\n\t * Run a function in a transaction with optional options for context.\n\t * You can use the options to change the way that history is treated\n\t * or allow changes to locked shapes.\n\t *\n\t * @example\n\t * ```ts\n\t * // updating with\n\t * editor.run(() => {\n\t * \teditor.updateShape({ ...myShape, x: 100 })\n\t * }, { history: \"ignore\" })\n\t *\n\t * // forcing changes / deletions for locked shapes\n\t * editor.toggleLock([myShape])\n\t * editor.run(() => {\n\t * \teditor.updateShape({ ...myShape, x: 100 })\n\t * \teditor.deleteShape(myShape)\n\t * }, { ignoreShapeLock: true }, )\n\t * ```\n\t *\n\t * @param fn - The callback function to run.\n\t * @param opts - The options for the batch.\n\t *\n\t *\n\t * @public\n\t */\n\trun(fn: () => void, opts?: TLEditorRunOptions): this {\n\t\tconst previousIgnoreShapeLock = this._shouldIgnoreShapeLock\n\t\tthis._shouldIgnoreShapeLock = opts?.ignoreShapeLock ?? previousIgnoreShapeLock\n\n\t\ttry {\n\t\t\tthis.history.batch(fn, opts)\n\t\t} finally {\n\t\t\tthis._shouldIgnoreShapeLock = previousIgnoreShapeLock\n\t\t}\n\n\t\treturn this\n\t}\n\n\t/**\n\t * @deprecated Use `Editor.run` instead.\n\t */\n\tbatch(fn: () => void, opts?: TLEditorRunOptions): this {\n\t\treturn this.run(fn, opts)\n\t}\n\n\t/* --------------------- Errors --------------------- */\n\n\t/** @internal */\n\tannotateError(\n\t\terror: unknown,\n\t\t{\n\t\t\torigin,\n\t\t\twillCrashApp,\n\t\t\ttags,\n\t\t\textras,\n\t\t}: {\n\t\t\torigin: string\n\t\t\twillCrashApp: boolean\n\t\t\ttags?: Record\n\t\t\textras?: Record\n\t\t}\n\t): this {\n\t\tconst defaultAnnotations = this.createErrorAnnotations(origin, willCrashApp)\n\t\tannotateError(error, {\n\t\t\ttags: { ...defaultAnnotations.tags, ...tags },\n\t\t\textras: { ...defaultAnnotations.extras, ...extras },\n\t\t})\n\t\tif (willCrashApp) {\n\t\t\tthis.store.markAsPossiblyCorrupted()\n\t\t}\n\t\treturn this\n\t}\n\n\t/** @internal */\n\tcreateErrorAnnotations(\n\t\torigin: string,\n\t\twillCrashApp: boolean | 'unknown'\n\t): {\n\t\ttags: { origin: string; willCrashApp: boolean | 'unknown' }\n\t\textras: {\n\t\t\tactiveStateNode?: string\n\t\t\tselectedShapes?: TLUnknownShape[]\n\t\t\teditingShape?: TLUnknownShape\n\t\t\tinputs?: Record\n\t\t}\n\t} {\n\t\ttry {\n\t\t\tconst editingShapeId = this.getEditingShapeId()\n\t\t\treturn {\n\t\t\t\ttags: {\n\t\t\t\t\torigin: origin,\n\t\t\t\t\twillCrashApp,\n\t\t\t\t},\n\t\t\t\textras: {\n\t\t\t\t\tactiveStateNode: this.root.getPath(),\n\t\t\t\t\tselectedShapes: this.getSelectedShapes(),\n\t\t\t\t\teditingShape: editingShapeId ? this.getShape(editingShapeId) : undefined,\n\t\t\t\t\tinputs: this.inputs,\n\t\t\t\t},\n\t\t\t}\n\t\t} catch {\n\t\t\treturn {\n\t\t\t\ttags: {\n\t\t\t\t\torigin: origin,\n\t\t\t\t\twillCrashApp,\n\t\t\t\t},\n\t\t\t\textras: {},\n\t\t\t}\n\t\t}\n\t}\n\n\t/** @internal */\n\tprivate _crashingError: unknown | null = null\n\n\t/**\n\t * We can't use an `atom` here because there's a chance that when `crashAndReportError` is called,\n\t * we're in a transaction that's about to be rolled back due to the same error we're currently\n\t * reporting.\n\t *\n\t * Instead, to listen to changes to this value, you need to listen to app's `crash` event.\n\t *\n\t * @internal\n\t */\n\tgetCrashingError() {\n\t\treturn this._crashingError\n\t}\n\n\t/** @internal */\n\tcrash(error: unknown): this {\n\t\tthis._crashingError = error\n\t\tthis.store.markAsPossiblyCorrupted()\n\t\tthis.emit('crash', { error })\n\t\treturn this\n\t}\n\n\t/* ------------------- Statechart ------------------- */\n\n\t/**\n\t * The editor's current path of active states.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getPath() // \"select.idle\"\n\t * ```\n\t *\n\t * @public\n\t */\n\t@computed getPath() {\n\t\treturn this.root.getPath().split('root.')[1]\n\t}\n\n\t/**\n\t * Get whether a certain tool (or other state node) is currently active.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.isIn('select')\n\t * editor.isIn('select.brushing')\n\t * ```\n\t *\n\t * @param path - The path of active states, separated by periods.\n\t *\n\t * @public\n\t */\n\tisIn(path: string): boolean {\n\t\tconst ids = path.split('.').reverse()\n\t\tlet state = this.root as StateNode\n\t\twhile (ids.length > 0) {\n\t\t\tconst id = ids.pop()\n\t\t\tif (!id) return true\n\t\t\tconst current = state.getCurrent()\n\t\t\tif (current?.id === id) {\n\t\t\t\tif (ids.length === 0) return true\n\t\t\t\tstate = current\n\t\t\t\tcontinue\n\t\t\t} else return false\n\t\t}\n\t\treturn false\n\t}\n\n\t/**\n\t * Get whether the state node is in any of the given active paths.\n\t *\n\t * @example\n\t * ```ts\n\t * state.isInAny('select', 'erase')\n\t * state.isInAny('select.brushing', 'erase.idle')\n\t * ```\n\t *\n\t * @public\n\t */\n\tisInAny(...paths: string[]): boolean {\n\t\treturn paths.some((path) => this.isIn(path))\n\t}\n\n\t/**\n\t * Set the selected tool.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.setCurrentTool('hand')\n\t * editor.setCurrentTool('hand', { date: Date.now() })\n\t * ```\n\t *\n\t * @param id - The id of the tool to select.\n\t * @param info - Arbitrary data to pass along into the transition.\n\t *\n\t * @public\n\t */\n\tsetCurrentTool(id: string, info = {}): this {\n\t\tthis.root.transition(id, info)\n\t\treturn this\n\t}\n\n\t/**\n\t * The current selected tool.\n\t *\n\t * @public\n\t */\n\t@computed getCurrentTool(): StateNode {\n\t\treturn this.root.getCurrent()!\n\t}\n\n\t/**\n\t * The id of the current selected tool.\n\t *\n\t * @public\n\t */\n\t@computed getCurrentToolId(): string {\n\t\tconst currentTool = this.getCurrentTool()\n\t\tif (!currentTool) return ''\n\t\treturn currentTool.getCurrentToolIdMask() ?? currentTool.id\n\t}\n\n\t/**\n\t * Get a descendant by its path.\n\t *\n\t * @example\n\t * ```ts\n\t * state.getStateDescendant('select')\n\t * state.getStateDescendant('select.brushing')\n\t * ```\n\t *\n\t * @param path - The descendant's path of state ids, separated by periods.\n\t *\n\t * @public\n\t */\n\tgetStateDescendant(path: string): T | undefined {\n\t\tconst ids = path.split('.').reverse()\n\t\tlet state = this.root as StateNode\n\t\twhile (ids.length > 0) {\n\t\t\tconst id = ids.pop()\n\t\t\tif (!id) return state as T\n\t\t\tconst childState = state.children?.[id]\n\t\t\tif (!childState) return undefined\n\t\t\tstate = childState\n\t\t}\n\t\treturn state as T\n\t}\n\n\t/* ---------------- Document Settings --------------- */\n\n\t/**\n\t * The global document settings that apply to all users.\n\t *\n\t * @public\n\t **/\n\t@computed getDocumentSettings() {\n\t\treturn this.store.get(TLDOCUMENT_ID)!\n\t}\n\n\t/**\n\t * Update the global document settings that apply to all users.\n\t *\n\t * @public\n\t **/\n\tupdateDocumentSettings(settings: Partial): this {\n\t\tthis.run(\n\t\t\t() => {\n\t\t\t\tthis.store.put([{ ...this.getDocumentSettings(), ...settings }])\n\t\t\t},\n\t\t\t{ history: 'ignore' }\n\t\t)\n\t\treturn this\n\t}\n\n\t/* ----------------- Instance State ----------------- */\n\n\t/**\n\t * The current instance's state.\n\t *\n\t * @public\n\t */\n\t@computed getInstanceState(): TLInstance {\n\t\treturn this.store.get(TLINSTANCE_ID)!\n\t}\n\n\t/**\n\t * Update the instance's state.\n\t *\n\t * @param partial - A partial object to update the instance state with.\n\t *\n\t * @public\n\t */\n\tupdateInstanceState(\n\t\tpartial: Partial>,\n\t\thistoryOptions?: TLHistoryBatchOptions\n\t): this {\n\t\tthis._updateInstanceState(partial, { history: 'ignore', ...historyOptions })\n\n\t\tif (partial.isChangingStyle !== undefined) {\n\t\t\tclearTimeout(this._isChangingStyleTimeout)\n\t\t\tif (partial.isChangingStyle === true) {\n\t\t\t\t// If we've set to true, set a new reset timeout to change the value back to false after 2 seconds\n\t\t\t\tthis._isChangingStyleTimeout = this.timers.setTimeout(() => {\n\t\t\t\t\tthis._updateInstanceState({ isChangingStyle: false }, { history: 'ignore' })\n\t\t\t\t}, 2000)\n\t\t\t}\n\t\t}\n\n\t\treturn this\n\t}\n\n\t/** @internal */\n\t_updateInstanceState(\n\t\tpartial: Partial>,\n\t\topts?: TLHistoryBatchOptions\n\t) {\n\t\tthis.run(() => {\n\t\t\tthis.store.put([\n\t\t\t\t{\n\t\t\t\t\t...this.getInstanceState(),\n\t\t\t\t\t...partial,\n\t\t\t\t},\n\t\t\t])\n\t\t}, opts)\n\t}\n\n\t/** @internal */\n\tprivate _isChangingStyleTimeout = -1 as any\n\n\t// Menus\n\n\t/**\n\t * A set of strings representing any open menus. When menus are open,\n\t * certain interactions will behave differently; for example, when a\n\t * draw tool is selected and a menu is open, a pointer-down will not\n\t * create a dot (because the user is probably trying to close the menu)\n\t * however a pointer-down event followed by a drag will begin drawing\n\t * a line (because the user is BOTH trying to close the menu AND start\n\t * drawing a line).\n\t *\n\t * @public\n\t */\n\t@computed getOpenMenus(): string[] {\n\t\treturn this.getInstanceState().openMenus\n\t}\n\n\t/**\n\t * Add an open menu.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.addOpenMenu('menu-id')\n\t * ```\n\t *\n\t * @public\n\t */\n\taddOpenMenu(id: string): this {\n\t\tconst menus = new Set(this.getOpenMenus())\n\t\tif (!menus.has(id)) {\n\t\t\tmenus.add(id)\n\t\t\tthis.updateInstanceState({ openMenus: [...menus] })\n\t\t}\n\t\treturn this\n\t}\n\n\t/**\n\t * Delete an open menu.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.deleteOpenMenu('menu-id')\n\t * ```\n\t *\n\t * @public\n\t */\n\tdeleteOpenMenu(id: string): this {\n\t\tconst menus = new Set(this.getOpenMenus())\n\t\tif (menus.has(id)) {\n\t\t\tmenus.delete(id)\n\t\t\tthis.updateInstanceState({ openMenus: [...menus] })\n\t\t}\n\t\treturn this\n\t}\n\n\t/**\n\t * Clear all open menus.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.clearOpenMenus()\n\t * ```\n\t *\n\t * @public\n\t */\n\tclearOpenMenus(): this {\n\t\tif (this.getOpenMenus().length) {\n\t\t\tthis.updateInstanceState({ openMenus: [] })\n\t\t}\n\t\treturn this\n\t}\n\n\t/**\n\t * Get whether any menus are open.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getIsMenuOpen()\n\t * ```\n\t *\n\t * @public\n\t */\n\t@computed getIsMenuOpen(): boolean {\n\t\treturn this.getOpenMenus().length > 0\n\t}\n\n\t/* --------------------- Cursor --------------------- */\n\n\t/**\n\t * Set the cursor.\n\t *\n\t * @param type - The cursor type.\n\t * @param rotation - The cursor rotation.\n\t *\n\t * @public\n\t */\n\tsetCursor(cursor: Partial) {\n\t\tthis.updateInstanceState({ cursor: { ...this.getInstanceState().cursor, ...cursor } })\n\t\treturn this\n\t}\n\n\t/* ------------------- Page State ------------------- */\n\n\t/**\n\t * Page states.\n\t *\n\t * @public\n\t */\n\t@computed getPageStates(): TLInstancePageState[] {\n\t\treturn this._getPageStatesQuery().get()\n\t}\n\n\t/** @internal */\n\t@computed private _getPageStatesQuery() {\n\t\treturn this.store.query.records('instance_page_state')\n\t}\n\n\t/**\n\t * The current page state.\n\t *\n\t * @public\n\t */\n\t@computed getCurrentPageState(): TLInstancePageState {\n\t\treturn this.store.get(this._getCurrentPageStateId())!\n\t}\n\n\t/** @internal */\n\t@computed private _getCurrentPageStateId() {\n\t\treturn InstancePageStateRecordType.createId(this.getCurrentPageId())\n\t}\n\n\t/**\n\t * Update this instance's page state.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.updateCurrentPageState({ id: 'page1', editingShapeId: 'shape:123' })\n\t * ```\n\t *\n\t * @param partial - The partial of the page state object containing the changes.\n\t *\n\t * @public\n\t */\n\tupdateCurrentPageState(\n\t\tpartial: Partial<\n\t\t\tOmit\n\t\t>\n\t): this {\n\t\tthis._updateCurrentPageState(partial)\n\t\treturn this\n\t}\n\t_updateCurrentPageState(partial: Partial>) {\n\t\tthis.store.update(partial.id ?? this.getCurrentPageState().id, (state) => ({\n\t\t\t...state,\n\t\t\t...partial,\n\t\t}))\n\t}\n\n\t/**\n\t * The current selected ids.\n\t *\n\t * @public\n\t */\n\t@computed getSelectedShapeIds() {\n\t\treturn this.getCurrentPageState().selectedShapeIds\n\t}\n\n\t/**\n\t * An array containing all of the currently selected shapes.\n\t *\n\t * @public\n\t * @readonly\n\t */\n\t@computed getSelectedShapes(): TLShape[] {\n\t\tconst { selectedShapeIds } = this.getCurrentPageState()\n\t\treturn compact(selectedShapeIds.map((id) => this.store.get(id)))\n\t}\n\n\t/**\n\t * Select one or more shapes.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.setSelectedShapes(['id1'])\n\t * editor.setSelectedShapes(['id1', 'id2'])\n\t * ```\n\t *\n\t * @param ids - The ids to select.\n\t *\n\t * @public\n\t */\n\tsetSelectedShapes(shapes: TLShapeId[] | TLShape[]): this {\n\t\treturn this.run(\n\t\t\t() => {\n\t\t\t\tconst ids = shapes.map((shape) => (typeof shape === 'string' ? shape : shape.id))\n\t\t\t\tconst { selectedShapeIds: prevSelectedShapeIds } = this.getCurrentPageState()\n\t\t\t\tconst prevSet = new Set(prevSelectedShapeIds)\n\n\t\t\t\tif (ids.length === prevSet.size && ids.every((id) => prevSet.has(id))) return null\n\n\t\t\t\tthis.store.put([{ ...this.getCurrentPageState(), selectedShapeIds: ids }])\n\t\t\t},\n\t\t\t{ history: 'record-preserveRedoStack' }\n\t\t)\n\t}\n\n\t/**\n\t * Determine whether or not any of a shape's ancestors are selected.\n\t *\n\t * @param id - The id of the shape to check.\n\t *\n\t * @public\n\t */\n\tisAncestorSelected(shape: TLShape | TLShapeId): boolean {\n\t\tconst id = typeof shape === 'string' ? shape : shape?.id ?? null\n\t\tconst _shape = this.getShape(id)\n\t\tif (!_shape) return false\n\t\tconst selectedShapeIds = this.getSelectedShapeIds()\n\t\treturn !!this.findShapeAncestor(_shape, (parent) => selectedShapeIds.includes(parent.id))\n\t}\n\n\t/**\n\t * Select one or more shapes.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.select('id1')\n\t * editor.select('id1', 'id2')\n\t * ```\n\t *\n\t * @param ids - The ids to select.\n\t *\n\t * @public\n\t */\n\tselect(...shapes: TLShapeId[] | TLShape[]): this {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((shape) => shape.id)\n\t\tthis.setSelectedShapes(ids)\n\t\treturn this\n\t}\n\n\t/**\n\t * Remove a shape from the existing set of selected shapes.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.deselect(shape.id)\n\t * ```\n\t *\n\t * @public\n\t */\n\tdeselect(...shapes: TLShapeId[] | TLShape[]): this {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((shape) => shape.id)\n\t\tconst selectedShapeIds = this.getSelectedShapeIds()\n\t\tif (selectedShapeIds.length > 0 && ids.length > 0) {\n\t\t\tthis.setSelectedShapes(selectedShapeIds.filter((id) => !ids.includes(id)))\n\t\t}\n\t\treturn this\n\t}\n\n\t/**\n\t * Select all direct children of the current page.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.selectAll()\n\t * ```\n\t *\n\t * @public\n\t */\n\tselectAll(): this {\n\t\tconst ids = this.getSortedChildIdsForParent(this.getCurrentPageId())\n\t\t// page might have no shapes\n\t\tif (ids.length <= 0) return this\n\t\tthis.setSelectedShapes(this._getUnlockedShapeIds(ids))\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Clear the selection.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.selectNone()\n\t * ```\n\t *\n\t * @public\n\t */\n\tselectNone(): this {\n\t\tif (this.getSelectedShapeIds().length > 0) {\n\t\t\tthis.setSelectedShapes([])\n\t\t}\n\n\t\treturn this\n\t}\n\n\t/**\n\t * The id of the app's only selected shape.\n\t *\n\t * @returns Null if there is no shape or more than one selected shape, otherwise the selected shape's id.\n\t *\n\t * @public\n\t * @readonly\n\t */\n\t@computed getOnlySelectedShapeId(): TLShapeId | null {\n\t\treturn this.getOnlySelectedShape()?.id ?? null\n\t}\n\n\t/**\n\t * The app's only selected shape.\n\t *\n\t * @returns Null if there is no shape or more than one selected shape, otherwise the selected shape.\n\t *\n\t * @public\n\t * @readonly\n\t */\n\t@computed getOnlySelectedShape(): TLShape | null {\n\t\tconst selectedShapes = this.getSelectedShapes()\n\t\treturn selectedShapes.length === 1 ? selectedShapes[0] : null\n\t}\n\n\t/**\n\t * @internal\n\t */\n\tgetShapesPageBounds(shapeIds: TLShapeId[]): Box | null {\n\t\tconst bounds = compact(shapeIds.map((id) => this.getShapePageBounds(id)))\n\t\tif (bounds.length === 0) return null\n\t\treturn Box.Common(bounds)\n\t}\n\n\t/**\n\t * The current page bounds of all the selected shapes. If the\n\t * selection is rotated, then these bounds are the axis-aligned\n\t * box that the rotated bounds would fit inside of.\n\t *\n\t * @readonly\n\t *\n\t * @public\n\t */\n\t@computed getSelectionPageBounds(): Box | null {\n\t\treturn this.getShapesPageBounds(this.getSelectedShapeIds())\n\t}\n\n\t/**\n\t * @internal\n\t */\n\tgetShapesSharedRotation(shapeIds: TLShapeId[]) {\n\t\tlet foundFirst = false // annoying but we can't use an i===0 check because we need to skip over undefineds\n\t\tlet rotation = 0\n\t\tfor (let i = 0, n = shapeIds.length; i < n; i++) {\n\t\t\tconst pageTransform = this.getShapePageTransform(shapeIds[i])\n\t\t\tif (!pageTransform) continue\n\t\t\tif (foundFirst) {\n\t\t\t\tif (pageTransform.rotation() !== rotation) {\n\t\t\t\t\t// There are at least 2 different rotations, so the common rotation is zero\n\t\t\t\t\treturn 0\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// First rotation found\n\t\t\t\tfoundFirst = true\n\t\t\t\trotation = pageTransform.rotation()\n\t\t\t}\n\t\t}\n\n\t\treturn rotation\n\t}\n\n\t/**\n\t * The rotation of the selection bounding box in the current page space.\n\t *\n\t * @readonly\n\t * @public\n\t */\n\t@computed getSelectionRotation(): number {\n\t\treturn this.getShapesSharedRotation(this.getSelectedShapeIds())\n\t}\n\n\t/**\n\t * @internal\n\t */\n\tgetShapesRotatedPageBounds(shapeIds: TLShapeId[]): Box | undefined {\n\t\tif (shapeIds.length === 0) {\n\t\t\treturn undefined\n\t\t}\n\n\t\tconst selectionRotation = this.getShapesSharedRotation(shapeIds)\n\t\tif (selectionRotation === 0) {\n\t\t\treturn this.getShapesPageBounds(shapeIds) ?? undefined\n\t\t}\n\n\t\tif (shapeIds.length === 1) {\n\t\t\tconst bounds = this.getShapeGeometry(shapeIds[0]).bounds.clone()\n\t\t\tconst pageTransform = this.getShapePageTransform(shapeIds[0])!\n\t\t\tbounds.point = pageTransform.applyToPoint(bounds.point)\n\t\t\treturn bounds\n\t\t}\n\n\t\t// need to 'un-rotate' all the outlines of the existing nodes so we can fit them inside a box\n\t\tconst boxFromRotatedVertices = Box.FromPoints(\n\t\t\tshapeIds\n\t\t\t\t.flatMap((id) => {\n\t\t\t\t\tconst pageTransform = this.getShapePageTransform(id)\n\t\t\t\t\tif (!pageTransform) return []\n\t\t\t\t\treturn pageTransform.applyToPoints(this.getShapeGeometry(id).bounds.corners)\n\t\t\t\t})\n\t\t\t\t.map((p) => p.rot(-selectionRotation))\n\t\t)\n\t\t// now position box so that it's top-left corner is in the right place\n\t\tboxFromRotatedVertices.point = boxFromRotatedVertices.point.rot(selectionRotation)\n\t\treturn boxFromRotatedVertices\n\t}\n\n\t/**\n\t * The bounds of the selection bounding box in the current page space.\n\t *\n\t * @readonly\n\t * @public\n\t */\n\t@computed getSelectionRotatedPageBounds(): Box | undefined {\n\t\treturn this.getShapesRotatedPageBounds(this.getSelectedShapeIds())\n\t}\n\n\t/**\n\t * The bounds of the selection bounding box in the current page space.\n\t *\n\t * @readonly\n\t * @public\n\t */\n\t@computed getSelectionRotatedScreenBounds(): Box | undefined {\n\t\tconst bounds = this.getSelectionRotatedPageBounds()\n\t\tif (!bounds) return undefined\n\t\tconst { x, y } = this.pageToScreen(bounds.point)\n\t\tconst zoom = this.getZoomLevel()\n\t\treturn new Box(x, y, bounds.width * zoom, bounds.height * zoom)\n\t}\n\n\t// Focus Group\n\n\t/**\n\t * The current focused group id.\n\t *\n\t * @public\n\t */\n\t@computed getFocusedGroupId(): TLShapeId | TLPageId {\n\t\treturn this.getCurrentPageState().focusedGroupId ?? this.getCurrentPageId()\n\t}\n\n\t/**\n\t * The current focused group.\n\t *\n\t * @public\n\t */\n\t@computed getFocusedGroup(): TLShape | undefined {\n\t\tconst focusedGroupId = this.getFocusedGroupId()\n\t\treturn focusedGroupId ? this.getShape(focusedGroupId) : undefined\n\t}\n\n\t/**\n\t * Set the current focused group shape.\n\t *\n\t * @param shape - The group shape id (or group shape's id) to set as the focused group shape.\n\t *\n\t * @public\n\t */\n\tsetFocusedGroup(shape: TLShapeId | TLGroupShape | null): this {\n\t\tconst id = typeof shape === 'string' ? shape : shape?.id ?? null\n\n\t\tif (id !== null) {\n\t\t\tconst shape = this.getShape(id)\n\t\t\tif (!shape) {\n\t\t\t\tthrow Error(`Editor.setFocusedGroup: Shape with id ${id} does not exist`)\n\t\t\t}\n\n\t\t\tif (!this.isShapeOfType(shape, 'group')) {\n\t\t\t\tthrow Error(\n\t\t\t\t\t`Editor.setFocusedGroup: Cannot set focused group to shape of type ${shape.type}`\n\t\t\t\t)\n\t\t\t}\n\t\t}\n\n\t\tif (id === this.getFocusedGroupId()) return this\n\n\t\treturn this.run(\n\t\t\t() => {\n\t\t\t\tthis.store.update(this.getCurrentPageState().id, (s) => ({ ...s, focusedGroupId: id }))\n\t\t\t},\n\t\t\t{ history: 'record-preserveRedoStack' }\n\t\t)\n\t}\n\n\t/**\n\t * Exit the current focused group, moving up to the next parent group if there is one.\n\t *\n\t * @public\n\t */\n\tpopFocusedGroupId(): this {\n\t\tconst focusedGroup = this.getFocusedGroup()\n\n\t\tif (focusedGroup) {\n\t\t\t// If we have a focused layer, look for an ancestor of the focused shape that is a group\n\t\t\tconst match = this.findShapeAncestor(focusedGroup, (shape) =>\n\t\t\t\tthis.isShapeOfType(shape, 'group')\n\t\t\t)\n\t\t\t// If we have an ancestor that can become a focused layer, set it as the focused layer\n\t\t\tthis.setFocusedGroup(match?.id ?? null)\n\t\t\tthis.select(focusedGroup.id)\n\t\t} else {\n\t\t\t// If there's no parent focused group, then clear the focus layer and clear selection\n\t\t\tthis.setFocusedGroup(null)\n\t\t\tthis.selectNone()\n\t\t}\n\n\t\treturn this\n\t}\n\n\t/**\n\t * The current editing shape's id.\n\t *\n\t * @public\n\t */\n\t@computed getEditingShapeId(): TLShapeId | null {\n\t\treturn this.getCurrentPageState().editingShapeId\n\t}\n\n\t/**\n\t * The current editing shape.\n\t *\n\t * @public\n\t */\n\t@computed getEditingShape(): TLShape | undefined {\n\t\tconst editingShapeId = this.getEditingShapeId()\n\t\treturn editingShapeId ? this.getShape(editingShapeId) : undefined\n\t}\n\n\t/**\n\t * Set the current editing shape.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.setEditingShape(myShape)\n\t * editor.setEditingShape(myShape.id)\n\t * ```\n\t *\n\t * @param shape - The shape (or shape id) to set as editing.\n\t *\n\t * @public\n\t */\n\tsetEditingShape(shape: TLShapeId | TLShape | null): this {\n\t\tconst id = typeof shape === 'string' ? shape : shape?.id ?? null\n\t\tif (id !== this.getEditingShapeId()) {\n\t\t\tif (id) {\n\t\t\t\tconst shape = this.getShape(id)\n\t\t\t\tif (shape && this.getShapeUtil(shape).canEdit(shape)) {\n\t\t\t\t\tthis.run(\n\t\t\t\t\t\t() => {\n\t\t\t\t\t\t\tthis._updateCurrentPageState({ editingShapeId: id })\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{ history: 'ignore' }\n\t\t\t\t\t)\n\t\t\t\t\treturn this\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Either we just set the editing id to null, or the shape was missing or not editable\n\t\t\tthis.run(\n\t\t\t\t() => {\n\t\t\t\t\tthis._updateCurrentPageState({ editingShapeId: null })\n\t\t\t\t},\n\t\t\t\t{ history: 'ignore' }\n\t\t\t)\n\t\t}\n\t\treturn this\n\t}\n\n\t// Hovered\n\n\t/**\n\t * The current hovered shape id.\n\t *\n\t * @readonly\n\t * @public\n\t */\n\t@computed getHoveredShapeId(): TLShapeId | null {\n\t\treturn this.getCurrentPageState().hoveredShapeId\n\t}\n\n\t/**\n\t * The current hovered shape.\n\t *\n\t * @public\n\t */\n\t@computed getHoveredShape(): TLShape | undefined {\n\t\tconst hoveredShapeId = this.getHoveredShapeId()\n\t\treturn hoveredShapeId ? this.getShape(hoveredShapeId) : undefined\n\t}\n\t/**\n\t * Set the editor's current hovered shape.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.setHoveredShape(myShape)\n\t * editor.setHoveredShape(myShape.id)\n\t * ```\n\t *\n\t * @param shapes - The shape (or shape id) to set as hovered.\n\t *\n\t * @public\n\t */\n\tsetHoveredShape(shape: TLShapeId | TLShape | null): this {\n\t\tconst id = typeof shape === 'string' ? shape : shape?.id ?? null\n\t\tif (id === this.getHoveredShapeId()) return this\n\t\tthis.run(\n\t\t\t() => {\n\t\t\t\tthis.updateCurrentPageState({ hoveredShapeId: id })\n\t\t\t},\n\t\t\t{ history: 'ignore' }\n\t\t)\n\t\treturn this\n\t}\n\n\t// Hinting\n\n\t/**\n\t * The editor's current hinting shape ids.\n\t *\n\t * @public\n\t */\n\t@computed getHintingShapeIds() {\n\t\treturn this.getCurrentPageState().hintingShapeIds\n\t}\n\t/**\n\t * The editor's current hinting shapes.\n\t *\n\t * @public\n\t */\n\t@computed getHintingShape() {\n\t\tconst hintingShapeIds = this.getHintingShapeIds()\n\t\treturn compact(hintingShapeIds.map((id) => this.getShape(id)))\n\t}\n\n\t/**\n\t * Set the editor's current hinting shapes.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.setHintingShapes([myShape])\n\t * editor.setHintingShapes([myShape.id])\n\t * ```\n\t *\n\t * @param shapes - The shapes (or shape ids) to set as hinting.\n\t *\n\t * @public\n\t */\n\tsetHintingShapes(shapes: TLShapeId[] | TLShape[]): this {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((shape) => shape.id)\n\t\t// always ephemeral\n\t\tthis.run(\n\t\t\t() => {\n\t\t\t\tthis._updateCurrentPageState({ hintingShapeIds: dedupe(ids) })\n\t\t\t},\n\t\t\t{ history: 'ignore' }\n\t\t)\n\t\treturn this\n\t}\n\n\t// Erasing\n\n\t/**\n\t * The editor's current erasing ids.\n\t *\n\t * @public\n\t */\n\t@computed getErasingShapeIds() {\n\t\treturn this.getCurrentPageState().erasingShapeIds\n\t}\n\n\t/**\n\t * The editor's current erasing shapes.\n\t *\n\t * @public\n\t */\n\t@computed getErasingShapes() {\n\t\tconst erasingShapeIds = this.getErasingShapeIds()\n\t\treturn compact(erasingShapeIds.map((id) => this.getShape(id)))\n\t}\n\n\t/**\n\t * Set the editor's current erasing shapes.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.setErasingShapes([myShape])\n\t * editor.setErasingShapes([myShape.id])\n\t * ```\n\t *\n\t * @param shapes - The shapes (or shape ids) to set as hinting.\n\t *\n\t * @public\n\t */\n\tsetErasingShapes(shapes: TLShapeId[] | TLShape[]): this {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((shape) => shape.id)\n\t\tids.sort() // sort the incoming ids\n\t\tconst erasingShapeIds = this.getErasingShapeIds()\n\t\tthis.run(\n\t\t\t() => {\n\t\t\t\tif (ids.length === erasingShapeIds.length) {\n\t\t\t\t\t// if the new ids are the same length as the current ids, they might be the same.\n\t\t\t\t\t// presuming the current ids are also sorted, check each item to see if it's the same;\n\t\t\t\t\t// if we find any unequal, then we know the new ids are different.\n\t\t\t\t\tfor (let i = 0; i < ids.length; i++) {\n\t\t\t\t\t\tif (ids[i] !== erasingShapeIds[i]) {\n\t\t\t\t\t\t\tthis._updateCurrentPageState({ erasingShapeIds: ids })\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t// if the ids are a different length, then we know they're different.\n\t\t\t\t\tthis._updateCurrentPageState({ erasingShapeIds: ids })\n\t\t\t\t}\n\t\t\t},\n\t\t\t{ history: 'ignore' }\n\t\t)\n\n\t\treturn this\n\t}\n\n\t// Cropping\n\n\t/**\n\t * The current cropping shape's id.\n\t *\n\t * @public\n\t */\n\tgetCroppingShapeId() {\n\t\treturn this.getCurrentPageState().croppingShapeId\n\t}\n\n\t/**\n\t * Set the current cropping shape.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.setCroppingShape(myShape)\n\t * editor.setCroppingShape(myShape.id)\n\t * ```\n\t *\n\t *\n\t * @param shape - The shape (or shape id) to set as cropping.\n\t *\n\t * @public\n\t */\n\tsetCroppingShape(shape: TLShapeId | TLShape | null): this {\n\t\tconst id = typeof shape === 'string' ? shape : shape?.id ?? null\n\t\tif (id !== this.getCroppingShapeId()) {\n\t\t\tthis.run(\n\t\t\t\t() => {\n\t\t\t\t\tif (!id) {\n\t\t\t\t\t\tthis.updateCurrentPageState({ croppingShapeId: null })\n\t\t\t\t\t} else {\n\t\t\t\t\t\tconst shape = this.getShape(id)!\n\t\t\t\t\t\tconst util = this.getShapeUtil(shape)\n\t\t\t\t\t\tif (shape && util.canCrop(shape)) {\n\t\t\t\t\t\t\tthis.updateCurrentPageState({ croppingShapeId: id })\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\t{ history: 'ignore' }\n\t\t\t)\n\t\t}\n\t\treturn this\n\t}\n\n\t/* --------------------- Camera --------------------- */\n\n\t/** @internal */\n\t@computed\n\tprivate _unsafe_getCameraId() {\n\t\treturn CameraRecordType.createId(this.getCurrentPageId())\n\t}\n\n\t/**\n\t * The current camera.\n\t *\n\t * @public\n\t */\n\t@computed getCamera(): TLCamera {\n\t\tconst baseCamera = this.store.get(this._unsafe_getCameraId())!\n\t\tif (this._isLockedOnFollowingUser.get()) {\n\t\t\tconst followingCamera = this.getCameraForFollowing()\n\t\t\tif (followingCamera) {\n\t\t\t\treturn { ...baseCamera, ...followingCamera }\n\t\t\t}\n\t\t}\n\t\treturn baseCamera\n\t}\n\n\t@computed\n\tprivate getViewportPageBoundsForFollowing(): null | Box {\n\t\tconst followingUserId = this.getInstanceState().followingUserId\n\t\tif (!followingUserId) return null\n\t\tconst leaderPresence = this.getCollaborators().find((c) => c.userId === followingUserId)\n\t\tif (!leaderPresence) return null\n\n\t\t// Fit their viewport inside of our screen bounds\n\t\t// 1. calculate their viewport in page space\n\t\tconst { w: lw, h: lh } = leaderPresence.screenBounds\n\t\tconst { x: lx, y: ly, z: lz } = leaderPresence.camera\n\t\tconst theirViewport = new Box(-lx, -ly, lw / lz, lh / lz)\n\n\t\t// resize our screenBounds to contain their viewport\n\t\tconst ourViewport = this.getViewportScreenBounds().clone()\n\t\tconst ourAspectRatio = ourViewport.width / ourViewport.height\n\n\t\tourViewport.width = theirViewport.width\n\t\tourViewport.height = ourViewport.width / ourAspectRatio\n\t\tif (ourViewport.height < theirViewport.height) {\n\t\t\tourViewport.height = theirViewport.height\n\t\t\tourViewport.width = ourViewport.height * ourAspectRatio\n\t\t}\n\n\t\tourViewport.center = theirViewport.center\n\t\treturn ourViewport\n\t}\n\n\t@computed\n\tprivate getCameraForFollowing(): null | { x: number; y: number; z: number } {\n\t\tconst viewport = this.getViewportPageBoundsForFollowing()\n\t\tif (!viewport) return null\n\n\t\treturn {\n\t\t\tx: -viewport.x,\n\t\t\ty: -viewport.y,\n\t\t\tz: this.getViewportScreenBounds().w / viewport.width,\n\t\t}\n\t}\n\n\t/**\n\t * The current camera zoom level.\n\t *\n\t * @public\n\t */\n\t@computed getZoomLevel() {\n\t\treturn this.getCamera().z\n\t}\n\n\t/**\n\t * Get the camera's initial or reset zoom level.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getInitialZoom()\n\t * ```\n\t *\n\t * @public */\n\tgetInitialZoom() {\n\t\tconst cameraOptions = this.getCameraOptions()\n\t\t// If no camera constraints are provided, the default zoom is 100%\n\t\tif (!cameraOptions.constraints) return 1\n\n\t\t// When defaultZoom is default, the default zoom is 100%\n\t\tif (cameraOptions.constraints.initialZoom === 'default') return 1\n\n\t\tconst { zx, zy } = getCameraFitXFitY(this, cameraOptions)\n\n\t\tswitch (cameraOptions.constraints.initialZoom) {\n\t\t\tcase 'fit-min': {\n\t\t\t\treturn Math.max(zx, zy)\n\t\t\t}\n\t\t\tcase 'fit-max': {\n\t\t\t\treturn Math.min(zx, zy)\n\t\t\t}\n\t\t\tcase 'fit-x': {\n\t\t\t\treturn zx\n\t\t\t}\n\t\t\tcase 'fit-y': {\n\t\t\t\treturn zy\n\t\t\t}\n\t\t\tcase 'fit-min-100': {\n\t\t\t\treturn Math.min(1, Math.max(zx, zy))\n\t\t\t}\n\t\t\tcase 'fit-max-100': {\n\t\t\t\treturn Math.min(1, Math.min(zx, zy))\n\t\t\t}\n\t\t\tcase 'fit-x-100': {\n\t\t\t\treturn Math.min(1, zx)\n\t\t\t}\n\t\t\tcase 'fit-y-100': {\n\t\t\t\treturn Math.min(1, zy)\n\t\t\t}\n\t\t\tdefault: {\n\t\t\t\tthrow exhaustiveSwitchError(cameraOptions.constraints.initialZoom)\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Get the camera's base level for calculating actual zoom levels based on the zoom steps.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getBaseZoom()\n\t * ```\n\t *\n\t * @public */\n\tgetBaseZoom() {\n\t\tconst cameraOptions = this.getCameraOptions()\n\t\t// If no camera constraints are provided, the default zoom is 100%\n\t\tif (!cameraOptions.constraints) return 1\n\n\t\t// When defaultZoom is default, the default zoom is 100%\n\t\tif (cameraOptions.constraints.baseZoom === 'default') return 1\n\n\t\tconst { zx, zy } = getCameraFitXFitY(this, cameraOptions)\n\n\t\tswitch (cameraOptions.constraints.baseZoom) {\n\t\t\tcase 'fit-min': {\n\t\t\t\treturn Math.max(zx, zy)\n\t\t\t}\n\t\t\tcase 'fit-max': {\n\t\t\t\treturn Math.min(zx, zy)\n\t\t\t}\n\t\t\tcase 'fit-x': {\n\t\t\t\treturn zx\n\t\t\t}\n\t\t\tcase 'fit-y': {\n\t\t\t\treturn zy\n\t\t\t}\n\t\t\tcase 'fit-min-100': {\n\t\t\t\treturn Math.min(1, Math.max(zx, zy))\n\t\t\t}\n\t\t\tcase 'fit-max-100': {\n\t\t\t\treturn Math.min(1, Math.min(zx, zy))\n\t\t\t}\n\t\t\tcase 'fit-x-100': {\n\t\t\t\treturn Math.min(1, zx)\n\t\t\t}\n\t\t\tcase 'fit-y-100': {\n\t\t\t\treturn Math.min(1, zy)\n\t\t\t}\n\t\t\tdefault: {\n\t\t\t\tthrow exhaustiveSwitchError(cameraOptions.constraints.baseZoom)\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate _cameraOptions = atom('camera options', DEFAULT_CAMERA_OPTIONS)\n\n\t/**\n\t * Get the current camera options.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getCameraOptions()\n\t * ```\n\t *\n\t * @public */\n\tgetCameraOptions() {\n\t\treturn this._cameraOptions.get()\n\t}\n\n\t/**\n\t * Set the camera options. Changing the options won't immediately change the camera itself, so you may want to call `setCamera` after changing the options.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.setCameraOptions(myCameraOptions)\n\t * editor.setCamera(editor.getCamera())\n\t * ```\n\t *\n\t * @param options - The camera options to set.\n\t *\n\t * @public */\n\tsetCameraOptions(options: Partial) {\n\t\tconst next = structuredClone({\n\t\t\t...this._cameraOptions.__unsafe__getWithoutCapture(),\n\t\t\t...options,\n\t\t})\n\t\tif (next.zoomSteps?.length < 1) next.zoomSteps = [1]\n\t\tthis._cameraOptions.set(next)\n\t\treturn this\n\t}\n\n\t/** @internal */\n\tprivate getConstrainedCamera(\n\t\tpoint: VecLike,\n\t\topts?: TLCameraMoveOptions\n\t): {\n\t\tx: number\n\t\ty: number\n\t\tz: number\n\t} {\n\t\tconst currentCamera = this.getCamera()\n\n\t\tlet { x, y, z = currentCamera.z } = point\n\n\t\t// If force is true, then we'll set the camera to the point regardless of\n\t\t// the camera options, so that we can handle gestures that permit elasticity\n\t\t// or decay, or animations that occur while the camera is locked.\n\t\tif (!opts?.force) {\n\t\t\t// Apply any adjustments based on the camera options\n\n\t\t\tconst cameraOptions = this.getCameraOptions()\n\n\t\t\tconst zoomMin = cameraOptions.zoomSteps[0]\n\t\t\tconst zoomMax = last(cameraOptions.zoomSteps)!\n\n\t\t\tconst vsb = this.getViewportScreenBounds()\n\n\t\t\t// If bounds are provided, then we'll keep those bounds on screen\n\t\t\tif (cameraOptions.constraints) {\n\t\t\t\tconst { constraints } = cameraOptions\n\n\t\t\t\t// Clamp padding to half the viewport size on either dimension\n\t\t\t\tconst py = Math.min(constraints.padding.y, vsb.w / 2)\n\t\t\t\tconst px = Math.min(constraints.padding.x, vsb.h / 2)\n\n\t\t\t\t// Expand the bounds by the padding\n\t\t\t\tconst bounds = Box.From(cameraOptions.constraints.bounds)\n\n\t\t\t\t// For each axis, the \"natural zoom\" is the zoom at\n\t\t\t\t// which the expanded bounds (with padding) would fit\n\t\t\t\t// the current viewport screen bounds. Paddings are\n\t\t\t\t// equal to screen pixels at 100%\n\t\t\t\t// The min and max zooms are factors of the smaller natural zoom axis\n\n\t\t\t\tconst zx = (vsb.w - px * 2) / bounds.w\n\t\t\t\tconst zy = (vsb.h - py * 2) / bounds.h\n\n\t\t\t\tconst baseZoom = this.getBaseZoom()\n\t\t\t\tconst maxZ = zoomMax * baseZoom\n\t\t\t\tconst minZ = zoomMin * baseZoom\n\n\t\t\t\tif (opts?.reset) {\n\t\t\t\t\tz = this.getInitialZoom()\n\t\t\t\t}\n\n\t\t\t\tif (z < minZ || z > maxZ) {\n\t\t\t\t\t// We're trying to zoom out past the minimum zoom level,\n\t\t\t\t\t// or in past the maximum zoom level, so stop the camera\n\t\t\t\t\t// but keep the current center\n\t\t\t\t\tconst { x: cx, y: cy, z: cz } = currentCamera\n\t\t\t\t\tconst cxA = -cx + vsb.w / cz / 2\n\t\t\t\t\tconst cyA = -cy + vsb.h / cz / 2\n\t\t\t\t\tz = clamp(z, minZ, maxZ)\n\t\t\t\t\tconst cxB = -cx + vsb.w / z / 2\n\t\t\t\t\tconst cyB = -cy + vsb.h / z / 2\n\t\t\t\t\tx = cx + cxB - cxA\n\t\t\t\t\ty = cy + cyB - cyA\n\t\t\t\t}\n\n\t\t\t\t// Calculate available space\n\t\t\t\tconst minX = px / z - bounds.x\n\t\t\t\tconst minY = py / z - bounds.y\n\t\t\t\tconst freeW = (vsb.w - px * 2) / z - bounds.w\n\t\t\t\tconst freeH = (vsb.h - py * 2) / z - bounds.h\n\t\t\t\tconst originX = minX + freeW * constraints.origin.x\n\t\t\t\tconst originY = minY + freeH * constraints.origin.y\n\n\t\t\t\tconst behaviorX =\n\t\t\t\t\ttypeof constraints.behavior === 'string' ? constraints.behavior : constraints.behavior.x\n\t\t\t\tconst behaviorY =\n\t\t\t\t\ttypeof constraints.behavior === 'string' ? constraints.behavior : constraints.behavior.y\n\n\t\t\t\t// x axis\n\n\t\t\t\tif (opts?.reset) {\n\t\t\t\t\t// Reset the camera according to the origin\n\t\t\t\t\tx = originX\n\t\t\t\t\ty = originY\n\t\t\t\t} else {\n\t\t\t\t\t// Apply constraints to the camera\n\t\t\t\t\tswitch (behaviorX) {\n\t\t\t\t\t\tcase 'fixed': {\n\t\t\t\t\t\t\t// Center according to the origin\n\t\t\t\t\t\t\tx = originX\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcase 'contain': {\n\t\t\t\t\t\t\t// When below fit zoom, center the camera\n\t\t\t\t\t\t\tif (z < zx) x = originX\n\t\t\t\t\t\t\t// When above fit zoom, keep the bounds within padding distance of the viewport edge\n\t\t\t\t\t\t\telse x = clamp(x, minX + freeW, minX)\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcase 'inside': {\n\t\t\t\t\t\t\t// When below fit zoom, constrain the camera so that the bounds stay completely within the viewport\n\t\t\t\t\t\t\tif (z < zx) x = clamp(x, minX, (vsb.w - px) / z - bounds.w)\n\t\t\t\t\t\t\t// When above fit zoom, keep the bounds within padding distance of the viewport edge\n\t\t\t\t\t\t\telse x = clamp(x, minX + freeW, minX)\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcase 'outside': {\n\t\t\t\t\t\t\t// Constrain the camera so that the bounds never leaves the viewport\n\t\t\t\t\t\t\tx = clamp(x, px / z - bounds.w, (vsb.w - px) / z)\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcase 'free': {\n\t\t\t\t\t\t\t// noop, use whatever x is provided\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t\tdefault: {\n\t\t\t\t\t\t\tthrow exhaustiveSwitchError(behaviorX)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// y axis\n\n\t\t\t\t\tswitch (behaviorY) {\n\t\t\t\t\t\tcase 'fixed': {\n\t\t\t\t\t\t\ty = originY\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcase 'contain': {\n\t\t\t\t\t\t\tif (z < zy) y = originY\n\t\t\t\t\t\t\telse y = clamp(y, minY + freeH, minY)\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcase 'inside': {\n\t\t\t\t\t\t\tif (z < zy) y = clamp(y, minY, (vsb.h - py) / z - bounds.h)\n\t\t\t\t\t\t\telse y = clamp(y, minY + freeH, minY)\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcase 'outside': {\n\t\t\t\t\t\t\ty = clamp(y, py / z - bounds.h, (vsb.h - py) / z)\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcase 'free': {\n\t\t\t\t\t\t\t// noop, use whatever x is provided\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t\tdefault: {\n\t\t\t\t\t\t\tthrow exhaustiveSwitchError(behaviorY)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// constrain the zoom, preserving the center\n\t\t\t\tif (z > zoomMax || z < zoomMin) {\n\t\t\t\t\tconst { x: cx, y: cy, z: cz } = currentCamera\n\t\t\t\t\tz = clamp(z, zoomMin, zoomMax)\n\t\t\t\t\tx = cx + (-cx + vsb.w / z / 2) - (-cx + vsb.w / cz / 2)\n\t\t\t\t\ty = cy + (-cy + vsb.h / z / 2) - (-cy + vsb.h / cz / 2)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn { x, y, z }\n\t}\n\n\t/** @internal */\n\tprivate _setCamera(point: VecLike, opts?: TLCameraMoveOptions): this {\n\t\tconst currentCamera = this.getCamera()\n\n\t\tconst { x, y, z } = this.getConstrainedCamera(point, opts)\n\n\t\tif (currentCamera.x === x && currentCamera.y === y && currentCamera.z === z) {\n\t\t\treturn this\n\t\t}\n\n\t\ttransact(() => {\n\t\t\tconst camera = { ...currentCamera, x, y, z }\n\t\t\tthis.run(\n\t\t\t\t() => {\n\t\t\t\t\tthis.store.put([camera]) // include id and meta here\n\t\t\t\t},\n\t\t\t\t{ history: 'ignore' }\n\t\t\t)\n\n\t\t\t// Dispatch a new pointer move because the pointer's page will have changed\n\t\t\t// (its screen position will compute to a new page position given the new camera position)\n\t\t\tconst { currentScreenPoint, currentPagePoint } = this.inputs\n\t\t\tconst { screenBounds } = this.store.unsafeGetWithoutCapture(TLINSTANCE_ID)!\n\n\t\t\t// compare the next page point (derived from the current camera) to the current page point\n\t\t\tif (\n\t\t\t\tcurrentScreenPoint.x / z - x !== currentPagePoint.x ||\n\t\t\t\tcurrentScreenPoint.y / z - y !== currentPagePoint.y\n\t\t\t) {\n\t\t\t\t// If it's changed, dispatch a pointer event\n\t\t\t\tconst event: TLPointerEventInfo = {\n\t\t\t\t\ttype: 'pointer',\n\t\t\t\t\ttarget: 'canvas',\n\t\t\t\t\tname: 'pointer_move',\n\t\t\t\t\t// weird but true: we need to put the screen point back into client space\n\t\t\t\t\tpoint: Vec.AddXY(currentScreenPoint, screenBounds.x, screenBounds.y),\n\t\t\t\t\tpointerId: INTERNAL_POINTER_IDS.CAMERA_MOVE,\n\t\t\t\t\tctrlKey: this.inputs.ctrlKey,\n\t\t\t\t\taltKey: this.inputs.altKey,\n\t\t\t\t\tshiftKey: this.inputs.shiftKey,\n\t\t\t\t\tbutton: 0,\n\t\t\t\t\tisPen: this.getInstanceState().isPenMode ?? false,\n\t\t\t\t}\n\n\t\t\t\tif (opts?.immediate) {\n\t\t\t\t\tthis._flushEventForTick(event)\n\t\t\t\t} else {\n\t\t\t\t\tthis.dispatch(event)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tthis._tickCameraState()\n\t\t})\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Set the current camera.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.setCamera({ x: 0, y: 0})\n\t * editor.setCamera({ x: 0, y: 0, z: 1.5})\n\t * editor.setCamera({ x: 0, y: 0, z: 1.5}, { animation: { duration: 1000, easing: (t) => t * t } })\n\t * ```\n\t *\n\t * @param point - The new camera position.\n\t * @param opts - The camera move options.\n\t *\n\t * @public\n\t */\n\tsetCamera(point: VecLike, opts?: TLCameraMoveOptions): this {\n\t\tconst { isLocked } = this._cameraOptions.__unsafe__getWithoutCapture()\n\t\tif (isLocked && !opts?.force) return this\n\n\t\t// Stop any camera animations\n\t\tthis.stopCameraAnimation()\n\n\t\t// Stop following any user\n\t\tif (this.getInstanceState().followingUserId) {\n\t\t\tthis.stopFollowingUser()\n\t\t}\n\n\t\tconst _point = Vec.Cast(point)\n\n\t\tif (!Number.isFinite(_point.x)) _point.x = 0\n\t\tif (!Number.isFinite(_point.y)) _point.y = 0\n\t\tif (_point.z === undefined || !Number.isFinite(_point.z)) point.z = this.getZoomLevel()\n\n\t\tconst camera = this.getConstrainedCamera(_point, opts)\n\n\t\tif (opts?.animation) {\n\t\t\tconst { width, height } = this.getViewportScreenBounds()\n\t\t\tthis._animateToViewport(\n\t\t\t\tnew Box(-camera.x, -camera.y, width / camera.z, height / camera.z),\n\t\t\t\topts\n\t\t\t)\n\t\t} else {\n\t\t\tthis._setCamera(camera, {\n\t\t\t\t...opts,\n\t\t\t\t// we already did the constraining, so we don't need to do it again\n\t\t\t\tforce: true,\n\t\t\t})\n\t\t}\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Center the camera on a point (in the current page space).\n\t *\n\t * @example\n\t * ```ts\n\t * editor.centerOnPoint({ x: 100, y: 100 })\n\t * editor.centerOnPoint({ x: 100, y: 100 }, { animation: { duration: 200 } })\n\t * ```\n\t *\n\t * @param point - The point in the current page space to center on.\n\t * @param animation - The camera move options.\n\t *\n\t * @public\n\t */\n\tcenterOnPoint(point: VecLike, opts?: TLCameraMoveOptions): this {\n\t\tconst { isLocked } = this.getCameraOptions()\n\t\tif (isLocked && !opts?.force) return this\n\n\t\tconst { width: pw, height: ph } = this.getViewportPageBounds()\n\t\tthis.setCamera(new Vec(-(point.x - pw / 2), -(point.y - ph / 2), this.getCamera().z), opts)\n\t\treturn this\n\t}\n\n\t/**\n\t * Zoom the camera to fit the current page's content in the viewport.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.zoomToFit()\n\t * editor.zoomToFit({ animation: { duration: 200 } })\n\t * ```\n\t *\n\t * @param opts - The camera move options.\n\t *\n\t * @public\n\t */\n\tzoomToFit(opts?: TLCameraMoveOptions): this {\n\t\tconst ids = [...this.getCurrentPageShapeIds()]\n\t\tif (ids.length <= 0) return this\n\t\tconst pageBounds = Box.Common(compact(ids.map((id) => this.getShapePageBounds(id))))\n\t\tthis.zoomToBounds(pageBounds, opts)\n\t\treturn this\n\t}\n\n\t/**\n\t * Set the zoom back to 100%.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.resetZoom()\n\t * editor.resetZoom(editor.getViewportScreenCenter(), { animation: { duration: 200 } })\n\t * editor.resetZoom(editor.getViewportScreenCenter(), { animation: { duration: 200 } })\n\t * ```\n\t *\n\t * @param point - The screen point to zoom out on. Defaults to the viewport screen center.\n\t * @param opts - The camera move options.\n\t *\n\t * @public\n\t */\n\tresetZoom(point = this.getViewportScreenCenter(), opts?: TLCameraMoveOptions): this {\n\t\tconst { isLocked, constraints: constraints } = this.getCameraOptions()\n\t\tif (isLocked && !opts?.force) return this\n\n\t\tconst currentCamera = this.getCamera()\n\t\tconst { x: cx, y: cy, z: cz } = currentCamera\n\t\tconst { x, y } = point\n\n\t\tlet z = 1\n\n\t\tif (constraints) {\n\t\t\t// For non-infinite fit, we'll set the camera to the natural zoom level...\n\t\t\t// unless it's already there, in which case we'll set zoom to 100%\n\t\t\tconst initialZoom = this.getInitialZoom()\n\t\t\tif (cz !== initialZoom) {\n\t\t\t\tz = initialZoom\n\t\t\t}\n\t\t}\n\n\t\tthis.setCamera(\n\t\t\tnew Vec(cx + (x / z - x) - (x / cz - x), cy + (y / z - y) - (y / cz - y), z),\n\t\t\topts\n\t\t)\n\t\treturn this\n\t}\n\n\t/**\n\t * Zoom the camera in.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.zoomIn()\n\t * editor.zoomIn(editor.getViewportScreenCenter(), { animation: { duration: 200 } })\n\t * editor.zoomIn(editor.inputs.currentScreenPoint, { animation: { duration: 200 } })\n\t * ```\n\t *\n\t * @param point - The screen point to zoom in on. Defaults to the screen center\n\t * @param opts - The camera move options.\n\t *\n\t * @public\n\t */\n\tzoomIn(point = this.getViewportScreenCenter(), opts?: TLCameraMoveOptions): this {\n\t\tconst { isLocked } = this.getCameraOptions()\n\t\tif (isLocked && !opts?.force) return this\n\n\t\tconst { x: cx, y: cy, z: cz } = this.getCamera()\n\n\t\tconst { zoomSteps } = this.getCameraOptions()\n\t\tif (zoomSteps !== null && zoomSteps.length > 1) {\n\t\t\tconst baseZoom = this.getBaseZoom()\n\t\t\tlet zoom = last(zoomSteps)! * baseZoom\n\t\t\tfor (let i = 1; i < zoomSteps.length; i++) {\n\t\t\t\tconst z1 = zoomSteps[i - 1] * baseZoom\n\t\t\t\tconst z2 = zoomSteps[i] * baseZoom\n\t\t\t\tif (z2 - cz <= (z2 - z1) / 2) continue\n\t\t\t\tzoom = z2\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tthis.setCamera(\n\t\t\t\tnew Vec(\n\t\t\t\t\tcx + (point.x / zoom - point.x) - (point.x / cz - point.x),\n\t\t\t\t\tcy + (point.y / zoom - point.y) - (point.y / cz - point.y),\n\t\t\t\t\tzoom\n\t\t\t\t),\n\t\t\t\topts\n\t\t\t)\n\t\t}\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Zoom the camera out.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.zoomOut()\n\t * editor.zoomOut(editor.getViewportScreenCenter(), { animation: { duration: 120 } })\n\t * editor.zoomOut(editor.inputs.currentScreenPoint, { animation: { duration: 120 } })\n\t * ```\n\t *\n\t * @param point - The point to zoom out on. Defaults to the viewport screen center.\n\t * @param opts - The camera move options.\n\t *\n\t * @public\n\t */\n\tzoomOut(point = this.getViewportScreenCenter(), opts?: TLCameraMoveOptions): this {\n\t\tconst { isLocked } = this.getCameraOptions()\n\t\tif (isLocked && !opts?.force) return this\n\n\t\tconst { zoomSteps } = this.getCameraOptions()\n\t\tif (zoomSteps !== null && zoomSteps.length > 1) {\n\t\t\tconst baseZoom = this.getBaseZoom()\n\t\t\tconst { x: cx, y: cy, z: cz } = this.getCamera()\n\t\t\t// start at the max\n\t\t\tlet zoom = zoomSteps[0] * baseZoom\n\t\t\tfor (let i = zoomSteps.length - 1; i > 0; i--) {\n\t\t\t\tconst z1 = zoomSteps[i - 1] * baseZoom\n\t\t\t\tconst z2 = zoomSteps[i] * baseZoom\n\t\t\t\tif (z2 - cz >= (z2 - z1) / 2) continue\n\t\t\t\tzoom = z1\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tthis.setCamera(\n\t\t\t\tnew Vec(\n\t\t\t\t\tcx + (point.x / zoom - point.x) - (point.x / cz - point.x),\n\t\t\t\t\tcy + (point.y / zoom - point.y) - (point.y / cz - point.y),\n\t\t\t\t\tzoom\n\t\t\t\t),\n\t\t\t\topts\n\t\t\t)\n\t\t}\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Zoom the camera to fit the current selection in the viewport.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.zoomToSelection()\n\t * editor.zoomToSelection({ animation: { duration: 200 } })\n\t * ```\n\t *\n\t * @param animation - The camera move options.\n\t *\n\t * @public\n\t */\n\tzoomToSelection(opts?: TLCameraMoveOptions): this {\n\t\tconst { isLocked } = this.getCameraOptions()\n\t\tif (isLocked && !opts?.force) return this\n\n\t\tconst selectionPageBounds = this.getSelectionPageBounds()\n\t\tif (selectionPageBounds) {\n\t\t\tthis.zoomToBounds(selectionPageBounds, {\n\t\t\t\ttargetZoom: Math.max(1, this.getZoomLevel()),\n\t\t\t\t...opts,\n\t\t\t})\n\t\t}\n\t\treturn this\n\t}\n\n\t/**\n\t * Zoom the camera to fit a bounding box (in the current page space).\n\t *\n\t * @example\n\t * ```ts\n\t * editor.zoomToBounds(myBounds)\n\t * editor.zoomToBounds(myBounds, { animation: { duration: 200 } })\n\t * editor.zoomToBounds(myBounds, { animation: { duration: 200 }, inset: 0, targetZoom: 1 })\n\t * ```\n\t *\n\t * @param bounds - The bounding box.\n\t * @param opts - The camera move options, target zoom, or custom inset amount.\n\t *\n\t * @public\n\t */\n\tzoomToBounds(\n\t\tbounds: BoxLike,\n\t\topts?: { targetZoom?: number; inset?: number } & TLCameraMoveOptions\n\t): this {\n\t\tconst cameraOptions = this._cameraOptions.__unsafe__getWithoutCapture()\n\t\tif (cameraOptions.isLocked && !opts?.force) return this\n\n\t\tconst viewportScreenBounds = this.getViewportScreenBounds()\n\n\t\tconst inset = opts?.inset ?? Math.min(ZOOM_TO_FIT_PADDING, viewportScreenBounds.width * 0.28)\n\n\t\tconst baseZoom = this.getBaseZoom()\n\t\tconst zoomMin = cameraOptions.zoomSteps[0]\n\t\tconst zoomMax = last(cameraOptions.zoomSteps)!\n\n\t\tlet zoom = clamp(\n\t\t\tMath.min(\n\t\t\t\t(viewportScreenBounds.width - inset) / bounds.w,\n\t\t\t\t(viewportScreenBounds.height - inset) / bounds.h\n\t\t\t),\n\t\t\tzoomMin * baseZoom,\n\t\t\tzoomMax * baseZoom\n\t\t)\n\n\t\tif (opts?.targetZoom !== undefined) {\n\t\t\tzoom = Math.min(opts.targetZoom, zoom)\n\t\t}\n\n\t\tthis.setCamera(\n\t\t\tnew Vec(\n\t\t\t\t-bounds.x + (viewportScreenBounds.width - bounds.w * zoom) / 2 / zoom,\n\t\t\t\t-bounds.y + (viewportScreenBounds.height - bounds.h * zoom) / 2 / zoom,\n\t\t\t\tzoom\n\t\t\t),\n\t\t\topts\n\t\t)\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Stop the current camera animation, if any.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.stopCameraAnimation()\n\t * ```\n\t *\n\t * @public\n\t */\n\tstopCameraAnimation(): this {\n\t\tthis.emit('stop-camera-animation')\n\t\treturn this\n\t}\n\n\t/** @internal */\n\tprivate _viewportAnimation = null as null | {\n\t\telapsed: number\n\t\tduration: number\n\t\teasing(t: number): number\n\t\tstart: Box\n\t\tend: Box\n\t}\n\n\t/** @internal */\n\tprivate _animateViewport(ms: number): void {\n\t\tif (!this._viewportAnimation) return\n\n\t\tthis._viewportAnimation.elapsed += ms\n\n\t\tconst { elapsed, easing, duration, start, end } = this._viewportAnimation\n\n\t\tif (elapsed > duration) {\n\t\t\tthis.off('tick', this._animateViewport)\n\t\t\tthis._viewportAnimation = null\n\t\t\tthis._setCamera(new Vec(-end.x, -end.y, this.getViewportScreenBounds().width / end.width))\n\t\t\treturn\n\t\t}\n\n\t\tconst remaining = duration - elapsed\n\t\tconst t = easing(1 - remaining / duration)\n\n\t\tconst left = start.minX + (end.minX - start.minX) * t\n\t\tconst top = start.minY + (end.minY - start.minY) * t\n\t\tconst right = start.maxX + (end.maxX - start.maxX) * t\n\n\t\tthis._setCamera(new Vec(-left, -top, this.getViewportScreenBounds().width / (right - left)), {\n\t\t\tforce: true,\n\t\t})\n\t}\n\n\t/** @internal */\n\tprivate _animateToViewport(\n\t\ttargetViewportPage: Box,\n\t\topts = { animation: DEFAULT_ANIMATION_OPTIONS } as TLCameraMoveOptions\n\t) {\n\t\tconst { animation, ...rest } = opts\n\t\tif (!animation) return\n\t\tconst { duration = 0, easing = EASINGS.easeInOutCubic } = animation\n\t\tconst animationSpeed = this.user.getAnimationSpeed()\n\t\tconst viewportPageBounds = this.getViewportPageBounds()\n\n\t\t// If we have an existing animation, then stop it\n\t\tthis.stopCameraAnimation()\n\n\t\t// also stop following any user\n\t\tif (this.getInstanceState().followingUserId) {\n\t\t\tthis.stopFollowingUser()\n\t\t}\n\n\t\tif (duration === 0 || animationSpeed === 0) {\n\t\t\t// If we have no animation, then skip the animation and just set the camera\n\t\t\treturn this._setCamera(\n\t\t\t\tnew Vec(\n\t\t\t\t\t-targetViewportPage.x,\n\t\t\t\t\t-targetViewportPage.y,\n\t\t\t\t\tthis.getViewportScreenBounds().width / targetViewportPage.width\n\t\t\t\t),\n\t\t\t\t{ ...rest }\n\t\t\t)\n\t\t}\n\n\t\t// Set our viewport animation\n\t\tthis._viewportAnimation = {\n\t\t\telapsed: 0,\n\t\t\tduration: duration / animationSpeed,\n\t\t\teasing,\n\t\t\tstart: viewportPageBounds.clone(),\n\t\t\tend: targetViewportPage.clone(),\n\t\t}\n\n\t\t// If we ever get a \"stop-camera-animation\" event, we stop\n\t\tthis.once('stop-camera-animation', () => {\n\t\t\tthis.off('tick', this._animateViewport)\n\t\t\tthis._viewportAnimation = null\n\t\t})\n\n\t\t// On each tick, animate the viewport\n\t\tthis.on('tick', this._animateViewport)\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Slide the camera in a certain direction.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.slideCamera({ speed: 1, direction: { x: 1, y: 0 }, friction: 0.1 })\n\t * ```\n\t *\n\t * @param opts - Options for the slide\n\t * @public\n\t */\n\tslideCamera(\n\t\topts = {} as {\n\t\t\tspeed: number\n\t\t\tdirection: VecLike\n\t\t\tfriction?: number\n\t\t\tspeedThreshold?: number\n\t\t\tforce?: boolean\n\t\t}\n\t): this {\n\t\tconst { isLocked } = this.getCameraOptions()\n\t\tif (isLocked && !opts?.force) return this\n\n\t\tconst animationSpeed = this.user.getAnimationSpeed()\n\t\tif (animationSpeed === 0) return this\n\n\t\tthis.stopCameraAnimation()\n\n\t\tconst {\n\t\t\tspeed,\n\t\t\tfriction = this.options.cameraSlideFriction,\n\t\t\tdirection,\n\t\t\tspeedThreshold = 0.01,\n\t\t} = opts\n\t\tlet currentSpeed = Math.min(speed, 1)\n\n\t\tconst cancel = () => {\n\t\t\tthis.off('tick', moveCamera)\n\t\t\tthis.off('stop-camera-animation', cancel)\n\t\t}\n\n\t\tthis.once('stop-camera-animation', cancel)\n\n\t\tconst moveCamera = (elapsed: number) => {\n\t\t\tconst { x: cx, y: cy, z: cz } = this.getCamera()\n\t\t\tconst movementVec = Vec.Mul(direction, (currentSpeed * elapsed) / cz)\n\n\t\t\t// Apply friction\n\t\t\tcurrentSpeed *= 1 - friction\n\t\t\tif (currentSpeed < speedThreshold) {\n\t\t\t\tcancel()\n\t\t\t} else {\n\t\t\t\tthis._setCamera(new Vec(cx + movementVec.x, cy + movementVec.y, cz))\n\t\t\t}\n\t\t}\n\n\t\tthis.on('tick', moveCamera)\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Animate the camera to a user's cursor position. This also briefly show the user's cursor if it's not currently visible.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.zoomToUser(myUserId)\n\t * editor.zoomToUser(myUserId, { animation: { duration: 200 } })\n\t * ```\n\t *\n\t * @param userId - The id of the user to animate to.\n\t * @param opts - The camera move options.\n\t * @public\n\t */\n\tzoomToUser(userId: string, opts: TLCameraMoveOptions = { animation: { duration: 500 } }): this {\n\t\tconst presence = this.getCollaborators().find((c) => c.userId === userId)\n\n\t\tif (!presence) return this\n\n\t\tthis.run(() => {\n\t\t\t// If we're following someone, stop following them\n\t\t\tif (this.getInstanceState().followingUserId !== null) {\n\t\t\t\tthis.stopFollowingUser()\n\t\t\t}\n\n\t\t\t// If we're not on the same page, move to the page they're on\n\t\t\tconst isOnSamePage = presence.currentPageId === this.getCurrentPageId()\n\t\t\tif (!isOnSamePage) {\n\t\t\t\tthis.setCurrentPage(presence.currentPageId)\n\t\t\t}\n\n\t\t\t// Only animate the camera if the user is on the same page as us\n\t\t\tif (opts && opts.animation && !isOnSamePage) {\n\t\t\t\topts.animation = undefined\n\t\t\t}\n\n\t\t\tthis.centerOnPoint(presence.cursor, opts)\n\n\t\t\t// Highlight the user's cursor\n\t\t\tconst { highlightedUserIds } = this.getInstanceState()\n\t\t\tthis.updateInstanceState({ highlightedUserIds: [...highlightedUserIds, userId] })\n\n\t\t\t// Unhighlight the user's cursor after a few seconds\n\t\t\tthis.timers.setTimeout(() => {\n\t\t\t\tconst highlightedUserIds = [...this.getInstanceState().highlightedUserIds]\n\t\t\t\tconst index = highlightedUserIds.indexOf(userId)\n\t\t\t\tif (index < 0) return\n\t\t\t\thighlightedUserIds.splice(index, 1)\n\t\t\t\tthis.updateInstanceState({ highlightedUserIds })\n\t\t\t}, this.options.collaboratorIdleTimeoutMs)\n\t\t})\n\n\t\treturn this\n\t}\n\n\t// Viewport\n\n\t/** @internal */\n\tprivate _willSetInitialBounds = true\n\n\t/**\n\t * Update the viewport. The viewport will measure the size and screen position of its container\n\t * element. This should be done whenever the container's position on the screen changes.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.updateViewportScreenBounds(new Box(0, 0, 1280, 1024))\n\t * editor.updateViewportScreenBounds(new Box(0, 0, 1280, 1024), true)\n\t * ```\n\t *\n\t * @param center - Whether to preserve the viewport page center as the viewport changes.\n\t *\n\t * @public\n\t */\n\tupdateViewportScreenBounds(screenBounds: Box | HTMLElement, center = false): this {\n\t\tif (screenBounds instanceof HTMLElement) {\n\t\t\tconst rect = screenBounds.getBoundingClientRect()\n\t\t\tscreenBounds = new Box(\n\t\t\t\trect.left || rect.x,\n\t\t\t\trect.top || rect.y,\n\t\t\t\tMath.max(rect.width, 1),\n\t\t\t\tMath.max(rect.height, 1)\n\t\t\t)\n\t\t} else {\n\t\t\tscreenBounds.width = Math.max(screenBounds.width, 1)\n\t\t\tscreenBounds.height = Math.max(screenBounds.height, 1)\n\t\t}\n\n\t\tconst insets = [\n\t\t\t// top\n\t\t\tscreenBounds.minY !== 0,\n\t\t\t// right\n\t\t\t!approximately(document.body.scrollWidth, screenBounds.maxX, 1),\n\t\t\t// bottom\n\t\t\t!approximately(document.body.scrollHeight, screenBounds.maxY, 1),\n\t\t\t// left\n\t\t\tscreenBounds.minX !== 0,\n\t\t]\n\n\t\tconst { _willSetInitialBounds } = this\n\n\t\tthis._willSetInitialBounds = false\n\n\t\tconst { screenBounds: prevScreenBounds, insets: prevInsets } = this.getInstanceState()\n\t\tif (screenBounds.equals(prevScreenBounds) && insets.every((v, i) => v === prevInsets[i])) {\n\t\t\t// nothing to do\n\t\t\treturn this\n\t\t}\n\n\t\tif (_willSetInitialBounds) {\n\t\t\t// If we have just received the initial bounds, don't center the camera.\n\t\t\tthis.updateInstanceState({ screenBounds: screenBounds.toJson(), insets })\n\t\t\tthis.setCamera(this.getCamera())\n\t\t} else {\n\t\t\tif (center && !this.getInstanceState().followingUserId) {\n\t\t\t\t// Get the page center before the change, make the change, and restore it\n\t\t\t\tconst before = this.getViewportPageBounds().center\n\t\t\t\tthis.updateInstanceState({ screenBounds: screenBounds.toJson(), insets })\n\t\t\t\tthis.centerOnPoint(before)\n\t\t\t} else {\n\t\t\t\t// Otherwise,\n\t\t\t\tthis.updateInstanceState({ screenBounds: screenBounds.toJson(), insets })\n\t\t\t\tthis._setCamera(Vec.From({ ...this.getCamera() }))\n\t\t\t}\n\t\t}\n\n\t\tthis._tickCameraState()\n\n\t\treturn this\n\t}\n\n\t/**\n\t * The bounds of the editor's viewport in screen space.\n\t *\n\t * @public\n\t */\n\t@computed getViewportScreenBounds() {\n\t\tconst { x, y, w, h } = this.getInstanceState().screenBounds\n\t\treturn new Box(x, y, w, h)\n\t}\n\n\t/**\n\t * The center of the editor's viewport in screen space.\n\t *\n\t * @public\n\t */\n\t@computed getViewportScreenCenter() {\n\t\tconst viewportScreenBounds = this.getViewportScreenBounds()\n\t\treturn new Vec(\n\t\t\tviewportScreenBounds.midX - viewportScreenBounds.minX,\n\t\t\tviewportScreenBounds.midY - viewportScreenBounds.minY\n\t\t)\n\t}\n\n\t/**\n\t * The current viewport in the current page space.\n\t *\n\t * @public\n\t */\n\t@computed getViewportPageBounds() {\n\t\tconst { w, h } = this.getViewportScreenBounds()\n\t\tconst { x: cx, y: cy, z: cz } = this.getCamera()\n\t\treturn new Box(-cx, -cy, w / cz, h / cz)\n\t}\n\n\t/**\n\t * Convert a point in screen space to a point in the current page space.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.screenToPage({ x: 100, y: 100 })\n\t * ```\n\t *\n\t * @param point - The point in screen space.\n\t *\n\t * @public\n\t */\n\tscreenToPage(point: VecLike) {\n\t\tconst { screenBounds } = this.store.unsafeGetWithoutCapture(TLINSTANCE_ID)!\n\t\tconst { x: cx, y: cy, z: cz = 1 } = this.getCamera()\n\t\treturn new Vec(\n\t\t\t(point.x - screenBounds.x) / cz - cx,\n\t\t\t(point.y - screenBounds.y) / cz - cy,\n\t\t\tpoint.z ?? 0.5\n\t\t)\n\t}\n\n\t/**\n\t * Convert a point in the current page space to a point in current screen space.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.pageToScreen({ x: 100, y: 100 })\n\t * ```\n\t *\n\t * @param point - The point in page space.\n\t *\n\t * @public\n\t */\n\tpageToScreen(point: VecLike) {\n\t\tconst { screenBounds } = this.store.unsafeGetWithoutCapture(TLINSTANCE_ID)!\n\t\tconst { x: cx, y: cy, z: cz = 1 } = this.getCamera()\n\t\treturn new Vec(\n\t\t\t(point.x + cx) * cz + screenBounds.x,\n\t\t\t(point.y + cy) * cz + screenBounds.y,\n\t\t\tpoint.z ?? 0.5\n\t\t)\n\t}\n\n\t/**\n\t * Convert a point in the current page space to a point in current viewport space.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.pageToViewport({ x: 100, y: 100 })\n\t * ```\n\t *\n\t * @param point - The point in page space.\n\t *\n\t * @public\n\t */\n\tpageToViewport(point: VecLike) {\n\t\tconst { x: cx, y: cy, z: cz = 1 } = this.getCamera()\n\t\treturn new Vec((point.x + cx) * cz, (point.y + cy) * cz, point.z ?? 0.5)\n\t}\n\t// Collaborators\n\n\t@computed\n\tprivate _getCollaboratorsQuery() {\n\t\treturn this.store.query.records('instance_presence', () => ({\n\t\t\tuserId: { neq: this.user.getId() },\n\t\t}))\n\t}\n\n\t/**\n\t * Returns a list of presence records for all peer collaborators.\n\t * This will return the latest presence record for each connected user.\n\t *\n\t * @public\n\t */\n\t@computed\n\tgetCollaborators() {\n\t\tconst allPresenceRecords = this._getCollaboratorsQuery().get()\n\t\tif (!allPresenceRecords.length) return EMPTY_ARRAY\n\t\tconst userIds = [...new Set(allPresenceRecords.map((c) => c.userId))].sort()\n\t\treturn userIds.map((id) => {\n\t\t\tconst latestPresence = allPresenceRecords\n\t\t\t\t.filter((c) => c.userId === id)\n\t\t\t\t.sort((a, b) => b.lastActivityTimestamp - a.lastActivityTimestamp)[0]\n\t\t\treturn latestPresence\n\t\t})\n\t}\n\n\t/**\n\t * Returns a list of presence records for all peer collaborators on the current page.\n\t * This will return the latest presence record for each connected user.\n\t *\n\t * @public\n\t */\n\t@computed\n\tgetCollaboratorsOnCurrentPage() {\n\t\tconst currentPageId = this.getCurrentPageId()\n\t\treturn this.getCollaborators().filter((c) => c.currentPageId === currentPageId)\n\t}\n\n\t// Following\n\n\t// When we are 'locked on' to a user, our camera is derived from their camera.\n\tprivate _isLockedOnFollowingUser = atom('isLockedOnFollowingUser', false)\n\n\t/**\n\t * Start viewport-following a user.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.startFollowingUser(myUserId)\n\t * ```\n\t *\n\t * @param userId - The id of the user to follow.\n\t * @param opts - Options for starting to follow a user.\n\t *\n\t * @public\n\t */\n\tstartFollowingUser(userId: string): this {\n\t\t// if we were already following someone, stop following them\n\t\tthis.stopFollowingUser()\n\n\t\tconst leaderPresences = this._getCollaboratorsQuery()\n\t\t\t.get()\n\t\t\t.filter((p) => p.userId === userId)\n\n\t\tif (!leaderPresences.length) {\n\t\t\tconsole.warn('User not found')\n\t\t\treturn this\n\t\t}\n\n\t\tconst thisUserId = this.user.getId()\n\n\t\tif (!thisUserId) {\n\t\t\tconsole.warn('You should set the userId for the current instance before following a user')\n\t\t\t// allow to continue since it's probably fine most of the time.\n\t\t}\n\n\t\t// If the leader is following us, then we can't follow them\n\t\tif (leaderPresences.some((p) => p.followingUserId === thisUserId)) {\n\t\t\treturn this\n\t\t}\n\n\t\tconst latestLeaderPresence = computed('latestLeaderPresence', () => {\n\t\t\treturn this.getCollaborators().find((p) => p.userId === userId)\n\t\t})\n\n\t\ttransact(() => {\n\t\t\tthis.updateInstanceState({ followingUserId: userId }, { history: 'ignore' })\n\n\t\t\t// we listen for page changes separately from the 'moveTowardsUser' tick\n\t\t\tconst dispose = react('update current page', () => {\n\t\t\t\tconst leaderPresence = latestLeaderPresence.get()\n\t\t\t\tif (!leaderPresence) {\n\t\t\t\t\tthis.stopFollowingUser()\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tif (\n\t\t\t\t\tleaderPresence.currentPageId !== this.getCurrentPageId() &&\n\t\t\t\t\tthis.getPage(leaderPresence.currentPageId)\n\t\t\t\t) {\n\t\t\t\t\t// if the page changed, switch page\n\t\t\t\t\tthis.run(\n\t\t\t\t\t\t() => {\n\t\t\t\t\t\t\t// sneaky store.put here, we can't go through setCurrentPage because it calls stopFollowingUser\n\t\t\t\t\t\t\tthis.store.put([\n\t\t\t\t\t\t\t\t{ ...this.getInstanceState(), currentPageId: leaderPresence.currentPageId },\n\t\t\t\t\t\t\t])\n\t\t\t\t\t\t\tthis._isLockedOnFollowingUser.set(true)\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{ history: 'ignore' }\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t})\n\n\t\t\tconst cancel = () => {\n\t\t\t\tdispose()\n\t\t\t\tthis._isLockedOnFollowingUser.set(false)\n\t\t\t\tthis.off('frame', moveTowardsUser)\n\t\t\t\tthis.off('stop-following', cancel)\n\t\t\t}\n\n\t\t\tconst moveTowardsUser = () => {\n\t\t\t\t// Stop following if we can't find the user\n\t\t\t\tconst leaderPresence = latestLeaderPresence.get()\n\t\t\t\tif (!leaderPresence) {\n\t\t\t\t\tthis.stopFollowingUser()\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\tif (this._isLockedOnFollowingUser.get()) return\n\n\t\t\t\tconst animationSpeed = this.user.getAnimationSpeed()\n\n\t\t\t\tif (animationSpeed === 0) {\n\t\t\t\t\tthis._isLockedOnFollowingUser.set(true)\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\tconst targetViewport = this.getViewportPageBoundsForFollowing()\n\t\t\t\tif (!targetViewport) {\n\t\t\t\t\tthis.stopFollowingUser()\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tconst currentViewport = this.getViewportPageBounds()\n\n\t\t\t\tconst diffX =\n\t\t\t\t\tMath.abs(targetViewport.minX - currentViewport.minX) +\n\t\t\t\t\tMath.abs(targetViewport.maxX - currentViewport.maxX)\n\t\t\t\tconst diffY =\n\t\t\t\t\tMath.abs(targetViewport.minY - currentViewport.minY) +\n\t\t\t\t\tMath.abs(targetViewport.maxY - currentViewport.maxY)\n\n\t\t\t\t// Stop chasing if we're close enough!\n\t\t\t\tif (\n\t\t\t\t\tdiffX < this.options.followChaseViewportSnap &&\n\t\t\t\t\tdiffY < this.options.followChaseViewportSnap\n\t\t\t\t) {\n\t\t\t\t\tthis._isLockedOnFollowingUser.set(true)\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\t// Chase the user's viewport!\n\t\t\t\t// Interpolate between the current viewport and the target viewport based on animation speed.\n\t\t\t\t// This will produce an 'ease-out' effect.\n\t\t\t\tconst t = clamp(animationSpeed * 0.5, 0.1, 0.8)\n\n\t\t\t\tconst nextViewport = new Box(\n\t\t\t\t\tlerp(currentViewport.minX, targetViewport.minX, t),\n\t\t\t\t\tlerp(currentViewport.minY, targetViewport.minY, t),\n\t\t\t\t\tlerp(currentViewport.width, targetViewport.width, t),\n\t\t\t\t\tlerp(currentViewport.height, targetViewport.height, t)\n\t\t\t\t)\n\n\t\t\t\tconst nextCamera = new Vec(\n\t\t\t\t\t-nextViewport.x,\n\t\t\t\t\t-nextViewport.y,\n\t\t\t\t\tthis.getViewportScreenBounds().width / nextViewport.width\n\t\t\t\t)\n\n\t\t\t\t// Update the camera!\n\t\t\t\tthis.stopCameraAnimation()\n\t\t\t\tthis._setCamera(nextCamera)\n\t\t\t}\n\n\t\t\tthis.once('stop-following', cancel)\n\t\t\tthis.addListener('frame', moveTowardsUser)\n\n\t\t\t// call once to start synchronously\n\t\t\tmoveTowardsUser()\n\t\t})\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Stop viewport-following a user.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.stopFollowingUser()\n\t * ```\n\t * @public\n\t */\n\tstopFollowingUser(): this {\n\t\tthis.run(\n\t\t\t() => {\n\t\t\t\t// commit the current camera to the store\n\t\t\t\tthis.store.put([this.getCamera()])\n\t\t\t\t// this must happen after the camera is committed\n\t\t\t\tthis._isLockedOnFollowingUser.set(false)\n\t\t\t\tthis.updateInstanceState({ followingUserId: null })\n\t\t\t\tthis.emit('stop-following')\n\t\t\t},\n\t\t\t{ history: 'ignore' }\n\t\t)\n\t\treturn this\n\t}\n\n\t/** @internal */\n\tgetUnorderedRenderingShapes(\n\t\t// The rendering state. We use this method both for rendering, which\n\t\t// is based on other state, and for computing order for SVG export,\n\t\t// which should work even when things are for example off-screen.\n\t\tuseEditorState: boolean\n\t): TLRenderingShape[] {\n\t\t// Here we get the shape as well as any of its children, as well as their\n\t\t// opacities. If the shape is being erased, and none of its ancestors are\n\t\t// being erased, then we reduce the opacity of the shape and all of its\n\t\t// ancestors; but we don't apply this effect more than once among a set\n\t\t// of descendants so that it does not compound.\n\n\t\t// This is designed to keep all the shapes in a single list which\n\t\t// allows the DOM nodes to be reused even when they become children\n\t\t// of other nodes.\n\n\t\tconst renderingShapes: TLRenderingShape[] = []\n\n\t\tlet nextIndex = this.options.maxShapesPerPage * 2\n\t\tlet nextBackgroundIndex = this.options.maxShapesPerPage\n\n\t\tconst erasingShapeIds = this.getErasingShapeIds()\n\n\t\tconst addShapeById = (id: TLShapeId, opacity: number, isAncestorErasing: boolean) => {\n\t\t\tconst shape = this.getShape(id)\n\t\t\tif (!shape) return\n\t\t\tif (this.isShapeHidden(shape)) return\n\n\t\t\topacity *= shape.opacity\n\t\t\tlet isShapeErasing = false\n\t\t\tconst util = this.getShapeUtil(shape)\n\n\t\t\tif (useEditorState) {\n\t\t\t\tisShapeErasing = !isAncestorErasing && erasingShapeIds.includes(id)\n\t\t\t\tif (isShapeErasing) {\n\t\t\t\t\topacity *= 0.32\n\t\t\t\t}\n\t\t\t}\n\n\t\t\trenderingShapes.push({\n\t\t\t\tid,\n\t\t\t\tshape,\n\t\t\t\tutil,\n\t\t\t\tindex: nextIndex,\n\t\t\t\tbackgroundIndex: nextBackgroundIndex,\n\t\t\t\topacity,\n\t\t\t})\n\n\t\t\tnextIndex += 1\n\t\t\tnextBackgroundIndex += 1\n\n\t\t\tconst childIds = this.getSortedChildIdsForParent(id)\n\t\t\tif (!childIds.length) return\n\n\t\t\tlet backgroundIndexToRestore = null\n\t\t\tif (util.providesBackgroundForChildren(shape)) {\n\t\t\t\tbackgroundIndexToRestore = nextBackgroundIndex\n\t\t\t\tnextBackgroundIndex = nextIndex\n\t\t\t\tnextIndex += this.options.maxShapesPerPage\n\t\t\t}\n\n\t\t\tfor (const childId of childIds) {\n\t\t\t\taddShapeById(childId, opacity, isAncestorErasing || isShapeErasing)\n\t\t\t}\n\n\t\t\tif (backgroundIndexToRestore !== null) {\n\t\t\t\tnextBackgroundIndex = backgroundIndexToRestore\n\t\t\t}\n\t\t}\n\n\t\t// If we're using editor state, then we're only interested in on-screen shapes.\n\t\t// If we're not using the editor state, then we're interested in ALL shapes, even those from other pages.\n\t\tconst pages = useEditorState ? [this.getCurrentPage()] : this.getPages()\n\t\tfor (const page of pages) {\n\t\t\tfor (const childId of this.getSortedChildIdsForParent(page.id)) {\n\t\t\t\taddShapeById(childId, 1, false)\n\t\t\t}\n\t\t}\n\n\t\treturn renderingShapes\n\t}\n\n\t// Camera state\n\t// Camera state does two things: first, it allows us to subscribe to whether\n\t// the camera is moving or not; and second, it allows us to update the rendering\n\t// shapes on the canvas. Changing the rendering shapes may cause shapes to\n\t// unmount / remount in the DOM, which is expensive; and computing visibility is\n\t// also expensive in large projects. For this reason, we use a second bounding\n\t// box just for rendering, and we only update after the camera stops moving.\n\tprivate _cameraState = atom('camera state', 'idle' as 'idle' | 'moving')\n\tprivate _cameraStateTimeoutRemaining = 0\n\t_decayCameraStateTimeout(elapsed: number) {\n\t\tthis._cameraStateTimeoutRemaining -= elapsed\n\t\tif (this._cameraStateTimeoutRemaining > 0) return\n\t\tthis.off('tick', this._decayCameraStateTimeout)\n\t\tthis._cameraState.set('idle')\n\t}\n\t_tickCameraState() {\n\t\t// always reset the timeout\n\t\tthis._cameraStateTimeoutRemaining = this.options.cameraMovingTimeoutMs\n\t\t// If the state is idle, then start the tick\n\t\tif (this._cameraState.__unsafe__getWithoutCapture() !== 'idle') return\n\t\tthis._cameraState.set('moving')\n\t\tthis.on('tick', this._decayCameraStateTimeout)\n\t}\n\n\t/**\n\t * Whether the camera is moving or idle.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getCameraState()\n\t * ```\n\t *\n\t * @public\n\t */\n\tgetCameraState() {\n\t\treturn this._cameraState.get()\n\t}\n\n\t/**\n\t * Get the shapes that should be displayed in the current viewport.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getRenderingShapes()\n\t * ```\n\t *\n\t * @public\n\t */\n\t@computed getRenderingShapes() {\n\t\tconst renderingShapes = this.getUnorderedRenderingShapes(true)\n\n\t\t// Its IMPORTANT that the result be sorted by id AND include the index\n\t\t// that the shape should be displayed at. Steve, this is the past you\n\t\t// telling the present you not to change this.\n\n\t\t// We want to sort by id because moving elements about in the DOM will\n\t\t// cause the element to get removed by react as it moves the DOM node. This\n\t\t// causes to re-render which is hella annoying and a perf\n\t\t// drain. By always sorting by 'id' we keep the shapes always in the\n\t\t// same order; but we later use index to set the element's 'z-index'\n\t\t// to change the \"rendered\" position in z-space.\n\t\treturn renderingShapes.sort(sortById)\n\t}\n\n\t/* --------------------- Pages ---------------------- */\n\n\t@computed private _getAllPagesQuery() {\n\t\treturn this.store.query.records('page')\n\t}\n\n\t/**\n\t * Info about the project's current pages.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getPages()\n\t * ```\n\t *\n\t * @public\n\t */\n\t@computed getPages(): TLPage[] {\n\t\treturn this._getAllPagesQuery().get().sort(sortByIndex)\n\t}\n\n\t/**\n\t * The current page.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getCurrentPage()\n\t * ```\n\t *\n\t * @public\n\t */\n\tgetCurrentPage(): TLPage {\n\t\treturn this.getPage(this.getCurrentPageId())!\n\t}\n\n\t/**\n\t * The current page id.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getCurrentPageId()\n\t * ```\n\t *\n\t * @public\n\t */\n\t@computed getCurrentPageId(): TLPageId {\n\t\treturn this.getInstanceState().currentPageId\n\t}\n\n\t/**\n\t * Get a page.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getPage(myPage.id)\n\t * editor.getPage(myPage)\n\t * ```\n\t *\n\t * @param page - The page (or page id) to get.\n\t *\n\t * @public\n\t */\n\tgetPage(page: TLPageId | TLPage): TLPage | undefined {\n\t\treturn this.store.get(typeof page === 'string' ? page : page.id)\n\t}\n\n\t/* @internal */\n\tprivate readonly _currentPageShapeIds: ReturnType\n\n\t/**\n\t * An array of all of the shapes on the current page.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getCurrentPageIds()\n\t * ```\n\t *\n\t * @public\n\t */\n\tgetCurrentPageShapeIds() {\n\t\treturn this._currentPageShapeIds.get()\n\t}\n\n\t/**\n\t * @internal\n\t */\n\t@computed\n\tgetCurrentPageShapeIdsSorted() {\n\t\treturn Array.from(this.getCurrentPageShapeIds()).sort()\n\t}\n\n\t/**\n\t * Get the ids of shapes on a page.\n\t *\n\t * @example\n\t * ```ts\n\t * const idsOnPage1 = editor.getPageShapeIds('page1')\n\t * const idsOnPage2 = editor.getPageShapeIds(myPage2)\n\t * ```\n\t *\n\t * @param page - The page (or page id) to get.\n\t *\n\t * @public\n\t **/\n\tgetPageShapeIds(page: TLPageId | TLPage): Set {\n\t\tconst pageId = typeof page === 'string' ? page : page.id\n\t\tconst result = this.store.query.exec('shape', { parentId: { eq: pageId } })\n\t\treturn this.getShapeAndDescendantIds(result.map((s) => s.id))\n\t}\n\n\t/**\n\t * Set the current page.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.setCurrentPage('page1')\n\t * editor.setCurrentPage(myPage1)\n\t * ```\n\t *\n\t * @param page - The page (or page id) to set as the current page.\n\t *\n\t * @public\n\t */\n\tsetCurrentPage(page: TLPageId | TLPage): this {\n\t\tconst pageId = typeof page === 'string' ? page : page.id\n\t\tif (!this.store.has(pageId)) {\n\t\t\tconsole.error(\"Tried to set the current page id to a page that doesn't exist.\")\n\t\t\treturn this\n\t\t}\n\n\t\tthis.stopFollowingUser()\n\t\t// finish off any in-progress interactions\n\t\tthis.complete()\n\n\t\treturn this.run(\n\t\t\t() => {\n\t\t\t\tthis.store.put([{ ...this.getInstanceState(), currentPageId: pageId }])\n\t\t\t},\n\t\t\t{ history: 'record-preserveRedoStack' }\n\t\t)\n\t}\n\n\t/**\n\t * Update a page.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.updatePage({ id: 'page2', name: 'Page 2' })\n\t * ```\n\t *\n\t * @param partial - The partial of the shape to update.\n\t *\n\t * @public\n\t */\n\tupdatePage(partial: RequiredKeys, 'id'>): this {\n\t\tif (this.getInstanceState().isReadonly) return this\n\n\t\tconst prev = this.getPage(partial.id)\n\t\tif (!prev) return this\n\n\t\treturn this.run(() => this.store.update(partial.id, (page) => ({ ...page, ...partial })))\n\t}\n\n\t/**\n\t * Create a page.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.createPage(myPage)\n\t * editor.createPage({ name: 'Page 2' })\n\t * ```\n\t *\n\t * @param page - The page (or page partial) to create.\n\t *\n\t * @public\n\t */\n\tcreatePage(page: Partial): this {\n\t\tthis.run(() => {\n\t\t\tif (this.getInstanceState().isReadonly) return\n\t\t\tif (this.getPages().length >= this.options.maxPages) return\n\t\t\tconst pages = this.getPages()\n\n\t\t\tconst name = getIncrementedName(\n\t\t\t\tpage.name ?? 'Page 1',\n\t\t\t\tpages.map((p) => p.name)\n\t\t\t)\n\n\t\t\tlet index = page.index\n\n\t\t\tif (!index || pages.some((p) => p.index === index)) {\n\t\t\t\tindex = getIndexAbove(pages[pages.length - 1].index)\n\t\t\t}\n\n\t\t\tconst newPage = PageRecordType.create({\n\t\t\t\tmeta: {},\n\t\t\t\t...page,\n\t\t\t\tname,\n\t\t\t\tindex,\n\t\t\t})\n\n\t\t\tthis.store.put([newPage])\n\t\t})\n\t\treturn this\n\t}\n\n\t/**\n\t * Delete a page.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.deletePage('page1')\n\t * ```\n\t *\n\t * @param id - The id of the page to delete.\n\t *\n\t * @public\n\t */\n\tdeletePage(page: TLPageId | TLPage): this {\n\t\tconst id = typeof page === 'string' ? page : page.id\n\t\tthis.run(() => {\n\t\t\tif (this.getInstanceState().isReadonly) return\n\t\t\tconst pages = this.getPages()\n\t\t\tif (pages.length === 1) return\n\n\t\t\tconst deletedPage = this.getPage(id)\n\t\t\tif (!deletedPage) return\n\n\t\t\tif (id === this.getCurrentPageId()) {\n\t\t\t\tconst index = pages.findIndex((page) => page.id === id)\n\t\t\t\tconst next = pages[index - 1] ?? pages[index + 1]\n\t\t\t\tthis.setCurrentPage(next.id)\n\t\t\t}\n\t\t\tthis.store.remove([deletedPage.id])\n\t\t})\n\t\treturn this\n\t}\n\n\t/**\n\t * Duplicate a page.\n\t *\n\t * @param id - The id of the page to duplicate. Defaults to the current page.\n\t * @param createId - The id of the new page. Defaults to a new id.\n\t *\n\t * @public\n\t */\n\tduplicatePage(page: TLPageId | TLPage, createId: TLPageId = PageRecordType.createId()): this {\n\t\tif (this.getPages().length >= this.options.maxPages) return this\n\t\tconst id = typeof page === 'string' ? page : page.id\n\t\tconst freshPage = this.getPage(id) // get the most recent version of the page anyway\n\t\tif (!freshPage) return this\n\n\t\tconst prevCamera = { ...this.getCamera() }\n\t\tconst content = this.getContentFromCurrentPage(this.getSortedChildIdsForParent(freshPage.id))\n\n\t\tthis.run(() => {\n\t\t\tconst pages = this.getPages()\n\t\t\tconst index = getIndexBetween(freshPage.index, pages[pages.indexOf(freshPage) + 1]?.index)\n\n\t\t\t// create the page (also creates the pagestate and camera for the new page)\n\t\t\tthis.createPage({ name: freshPage.name + ' Copy', id: createId, index })\n\t\t\t// set the new page as the current page\n\t\t\tthis.setCurrentPage(createId)\n\t\t\t// update the new page's camera to the previous page's camera\n\t\t\tthis.setCamera(prevCamera)\n\n\t\t\tif (content) {\n\t\t\t\t// If we had content on the previous page, put it on the new page\n\t\t\t\treturn this.putContentOntoCurrentPage(content)\n\t\t\t}\n\t\t})\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Rename a page.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.renamePage('page1', 'My Page')\n\t * ```\n\t *\n\t * @param id - The id of the page to rename.\n\t * @param name - The new name.\n\t *\n\t * @public\n\t */\n\trenamePage(page: TLPageId | TLPage, name: string) {\n\t\tconst id = typeof page === 'string' ? page : page.id\n\t\tif (this.getInstanceState().isReadonly) return this\n\t\tthis.updatePage({ id, name })\n\t\treturn this\n\t}\n\n\t/* --------------------- Assets --------------------- */\n\n\t/** @internal */\n\t@computed private _getAllAssetsQuery() {\n\t\treturn this.store.query.records('asset')\n\t}\n\n\t/**\n\t * Get all assets in the editor.\n\t *\n\t * @public\n\t */\n\tgetAssets() {\n\t\treturn this._getAllAssetsQuery().get()\n\t}\n\n\t/**\n\t * Create one or more assets.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.createAssets([...myAssets])\n\t * ```\n\t *\n\t * @param assets - The assets to create.\n\t *\n\t * @public\n\t */\n\tcreateAssets(assets: TLAsset[]): this {\n\t\tif (this.getInstanceState().isReadonly) return this\n\t\tif (assets.length <= 0) return this\n\t\tthis.run(() => this.store.put(assets), { history: 'ignore' })\n\t\treturn this\n\t}\n\n\t/**\n\t * Update one or more assets.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.updateAssets([{ id: 'asset1', name: 'New name' }])\n\t * ```\n\t *\n\t * @param assets - The assets to update.\n\t *\n\t * @public\n\t */\n\tupdateAssets(assets: TLAssetPartial[]): this {\n\t\tif (this.getInstanceState().isReadonly) return this\n\t\tif (assets.length <= 0) return this\n\t\tthis.run(\n\t\t\t() => {\n\t\t\t\tthis.store.put(\n\t\t\t\t\tassets.map((partial) => ({\n\t\t\t\t\t\t...this.store.get(partial.id)!,\n\t\t\t\t\t\t...partial,\n\t\t\t\t\t}))\n\t\t\t\t)\n\t\t\t},\n\t\t\t{ history: 'ignore' }\n\t\t)\n\t\treturn this\n\t}\n\n\t/**\n\t * Delete one or more assets.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.deleteAssets(['asset1', 'asset2'])\n\t * ```\n\t *\n\t * @param ids - The assets to delete.\n\t *\n\t * @public\n\t */\n\tdeleteAssets(assets: TLAssetId[] | TLAsset[]): this {\n\t\tif (this.getInstanceState().isReadonly) return this\n\n\t\tconst ids =\n\t\t\ttypeof assets[0] === 'string'\n\t\t\t\t? (assets as TLAssetId[])\n\t\t\t\t: (assets as TLAsset[]).map((a) => a.id)\n\t\tif (ids.length <= 0) return this\n\n\t\tthis.run(() => this.store.remove(ids), { history: 'ignore' })\n\t\treturn this\n\t}\n\n\t/**\n\t * Get an asset by its id.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getAsset('asset1')\n\t * ```\n\t *\n\t * @param asset - The asset (or asset id) to get.\n\t *\n\t * @public\n\t */\n\tgetAsset(asset: TLAssetId | TLAsset): TLAsset | undefined {\n\t\treturn this.store.get(typeof asset === 'string' ? asset : asset.id) as TLAsset | undefined\n\t}\n\n\tasync resolveAssetUrl(\n\t\tassetId: TLAssetId | null,\n\t\tcontext: {\n\t\t\tscreenScale?: number\n\t\t\tshouldResolveToOriginal?: boolean\n\t\t}\n\t): Promise {\n\t\tif (!assetId) return null\n\t\tconst asset = this.getAsset(assetId)\n\t\tif (!asset) return null\n\n\t\tconst { screenScale = 1, shouldResolveToOriginal = false } = context\n\n\t\t// We only look at the zoom level at powers of 2.\n\t\tconst zoomStepFunction = (zoom: number) => Math.pow(2, Math.ceil(Math.log2(zoom)))\n\t\tconst steppedScreenScale = Math.max(0.125, zoomStepFunction(screenScale))\n\t\tconst networkEffectiveType: string | null =\n\t\t\t'connection' in navigator ? (navigator as any).connection.effectiveType : null\n\t\tconst dpr = this.getInstanceState().devicePixelRatio\n\n\t\treturn await this.store.props.assets.resolve(asset, {\n\t\t\tscreenScale: screenScale || 1,\n\t\t\tsteppedScreenScale,\n\t\t\tdpr,\n\t\t\tnetworkEffectiveType,\n\t\t\tshouldResolveToOriginal,\n\t\t})\n\t}\n\t/**\n\t * Upload an asset to the store's asset service, returning a URL that can be used to resolve the\n\t * asset.\n\t */\n\tasync uploadAsset(asset: TLAsset, file: File): Promise {\n\t\treturn await this.store.props.assets.upload(asset, file)\n\t}\n\n\t/* --------------------- Shapes --------------------- */\n\n\t@computed\n\tprivate _getShapeGeometryCache(): ComputedCache {\n\t\treturn this.store.createComputedCache(\n\t\t\t'bounds',\n\t\t\t(shape) => this.getShapeUtil(shape).getGeometry(shape),\n\t\t\t(a, b) => a.props === b.props\n\t\t)\n\t}\n\n\t/**\n\t * Get the geometry of a shape.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getShapeGeometry(myShape)\n\t * editor.getShapeGeometry(myShapeId)\n\t * ```\n\t *\n\t * @param shape - The shape (or shape id) to get the geometry for.\n\t *\n\t * @public\n\t */\n\tgetShapeGeometry(shape: TLShape | TLShapeId): T {\n\t\treturn this._getShapeGeometryCache().get(typeof shape === 'string' ? shape : shape.id)! as T\n\t}\n\n\t/** @internal */\n\t@computed private _getShapeHandlesCache(): ComputedCache {\n\t\treturn this.store.createComputedCache('handles', (shape) => {\n\t\t\treturn this.getShapeUtil(shape).getHandles?.(shape)\n\t\t})\n\t}\n\n\t/**\n\t * Get the handles (if any) for a shape.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getShapeHandles(myShape)\n\t * editor.getShapeHandles(myShapeId)\n\t * ```\n\t *\n\t * @param shape - The shape (or shape id) to get the handles for.\n\t * @public\n\t */\n\tgetShapeHandles(shape: T | T['id']): TLHandle[] | undefined {\n\t\treturn this._getShapeHandlesCache().get(typeof shape === 'string' ? shape : shape.id)\n\t}\n\n\t/**\n\t * Get the local transform for a shape as a matrix model. This transform reflects both its\n\t * translation (x, y) from from either its parent's top left corner, if the shape's parent is\n\t * another shape, or else from the 0,0 of the page, if the shape's parent is the page; and the\n\t * shape's rotation.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getShapeLocalTransform(myShape)\n\t * ```\n\t *\n\t * @param shape - The shape to get the local transform for.\n\t *\n\t * @public\n\t */\n\tgetShapeLocalTransform(shape: TLShape | TLShapeId): Mat {\n\t\tconst id = typeof shape === 'string' ? shape : shape.id\n\t\tconst freshShape = this.getShape(id)\n\t\tif (!freshShape) throw Error('Editor.getTransform: shape not found')\n\t\treturn Mat.Identity().translate(freshShape.x, freshShape.y).rotate(freshShape.rotation)\n\t}\n\n\t/**\n\t * A cache of page transforms.\n\t *\n\t * @internal\n\t */\n\t@computed private _getShapePageTransformCache(): ComputedCache {\n\t\treturn this.store.createComputedCache('pageTransformCache', (shape) => {\n\t\t\tif (isPageId(shape.parentId)) {\n\t\t\t\treturn this.getShapeLocalTransform(shape)\n\t\t\t}\n\n\t\t\t// If the shape's parent doesn't exist yet (e.g. when merging in changes from remote in the wrong order)\n\t\t\t// then we can't compute the transform yet, so just return the identity matrix.\n\t\t\t// In the future we should look at creating a store update mechanism that understands and preserves\n\t\t\t// ordering.\n\t\t\tconst parentTransform =\n\t\t\t\tthis._getShapePageTransformCache().get(shape.parentId) ?? Mat.Identity()\n\t\t\treturn Mat.Compose(parentTransform, this.getShapeLocalTransform(shape)!)\n\t\t})\n\t}\n\n\t/**\n\t * Get the local transform of a shape's parent as a matrix model.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getShapeParentTransform(myShape)\n\t * ```\n\t *\n\t * @param shape - The shape (or shape id) to get the parent transform for.\n\t *\n\t * @public\n\t */\n\tgetShapeParentTransform(shape: TLShape | TLShapeId): Mat {\n\t\tconst id = typeof shape === 'string' ? shape : shape.id\n\t\tconst freshShape = this.getShape(id)\n\t\tif (!freshShape || isPageId(freshShape.parentId)) return Mat.Identity()\n\t\treturn this._getShapePageTransformCache().get(freshShape.parentId) ?? Mat.Identity()\n\t}\n\n\t/**\n\t * Get the transform of a shape in the current page space.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getShapePageTransform(myShape)\n\t * editor.getShapePageTransform(myShapeId)\n\t * ```\n\t *\n\t * @param shape - The shape (or shape id) to get the page transform for.\n\t *\n\t * @public\n\t */\n\tgetShapePageTransform(shape: TLShape | TLShapeId): Mat {\n\t\tconst id = typeof shape === 'string' ? shape : shape.id\n\t\treturn this._getShapePageTransformCache().get(id) ?? Mat.Identity()\n\t}\n\n\t/** @internal */\n\t@computed private _getShapePageBoundsCache(): ComputedCache {\n\t\treturn this.store.createComputedCache('pageBoundsCache', (shape) => {\n\t\t\tconst pageTransform = this._getShapePageTransformCache().get(shape.id)\n\n\t\t\tif (!pageTransform) return new Box()\n\n\t\t\tconst result = Box.FromPoints(\n\t\t\t\tMat.applyToPoints(pageTransform, this.getShapeGeometry(shape).vertices)\n\t\t\t)\n\n\t\t\treturn result\n\t\t})\n\t}\n\n\t/**\n\t * Get the bounds of a shape in the current page space.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getShapePageBounds(myShape)\n\t * editor.getShapePageBounds(myShapeId)\n\t * ```\n\t *\n\t * @param shape - The shape (or shape id) to get the bounds for.\n\t *\n\t * @public\n\t */\n\tgetShapePageBounds(shape: TLShape | TLShapeId): Box | undefined {\n\t\treturn this._getShapePageBoundsCache().get(typeof shape === 'string' ? shape : shape.id)\n\t}\n\n\t/**\n\t * A cache of clip paths used for clipping.\n\t *\n\t * @internal\n\t */\n\t@computed private _getShapeClipPathCache(): ComputedCache {\n\t\treturn this.store.createComputedCache('clipPathCache', (shape) => {\n\t\t\tconst pageMask = this._getShapeMaskCache().get(shape.id)\n\t\t\tif (!pageMask) return undefined\n\t\t\tif (pageMask.length === 0) {\n\t\t\t\treturn `polygon(0px 0px, 0px 0px, 0px 0px)`\n\t\t\t}\n\n\t\t\tconst pageTransform = this._getShapePageTransformCache().get(shape.id)\n\t\t\tif (!pageTransform) return undefined\n\n\t\t\tconst localMask = Mat.applyToPoints(Mat.Inverse(pageTransform), pageMask)\n\n\t\t\treturn `polygon(${localMask.map((p) => `${p.x}px ${p.y}px`).join(',')})`\n\t\t})\n\t}\n\n\t/**\n\t * Get the clip path for a shape.\n\t *\n\t * @example\n\t * ```ts\n\t * const clipPath = editor.getShapeClipPath(shape)\n\t * const clipPath = editor.getShapeClipPath(shape.id)\n\t * ```\n\t *\n\t * @param shape - The shape (or shape id) to get the clip path for.\n\t *\n\t * @returns The clip path or undefined.\n\t *\n\t * @public\n\t */\n\tgetShapeClipPath(shape: TLShape | TLShapeId): string | undefined {\n\t\treturn this._getShapeClipPathCache().get(typeof shape === 'string' ? shape : shape.id)\n\t}\n\n\t/** @internal */\n\t@computed private _getShapeMaskCache(): ComputedCache {\n\t\treturn this.store.createComputedCache('pageMaskCache', (shape) => {\n\t\t\tif (isPageId(shape.parentId)) return undefined\n\n\t\t\tconst frameAncestors = this.getShapeAncestors(shape.id).filter((shape) =>\n\t\t\t\tthis.isShapeOfType(shape, 'frame')\n\t\t\t)\n\n\t\t\tif (frameAncestors.length === 0) return undefined\n\n\t\t\tconst pageMask = frameAncestors\n\t\t\t\t.map((s) =>\n\t\t\t\t\t// Apply the frame transform to the frame outline to get the frame outline in the current page space\n\t\t\t\t\tthis._getShapePageTransformCache()\n\t\t\t\t\t\t.get(s.id)!\n\t\t\t\t\t\t.applyToPoints(this.getShapeGeometry(s).vertices)\n\t\t\t\t)\n\t\t\t\t.reduce((acc, b) => {\n\t\t\t\t\tif (!(b && acc)) return undefined\n\t\t\t\t\tconst intersection = intersectPolygonPolygon(acc, b)\n\t\t\t\t\tif (intersection) {\n\t\t\t\t\t\treturn intersection.map(Vec.Cast)\n\t\t\t\t\t}\n\t\t\t\t\treturn []\n\t\t\t\t})\n\n\t\t\treturn pageMask\n\t\t})\n\t}\n\n\t/**\n\t * Get the mask (in the current page space) for a shape.\n\t *\n\t * @example\n\t * ```ts\n\t * const pageMask = editor.getShapeMask(shape.id)\n\t * ```\n\t *\n\t * @param id - The id of the shape to get the mask for.\n\t *\n\t * @returns The mask for the shape.\n\t *\n\t * @public\n\t */\n\tgetShapeMask(shape: TLShapeId | TLShape): VecLike[] | undefined {\n\t\treturn this._getShapeMaskCache().get(typeof shape === 'string' ? shape : shape.id)\n\t}\n\n\t/**\n\t * Get the bounds of a shape in the current page space, incorporating any masks. For example, if the\n\t * shape were the child of a frame and was half way out of the frame, the bounds would be the half\n\t * of the shape that was in the frame.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getShapeMaskedPageBounds(myShape)\n\t * editor.getShapeMaskedPageBounds(myShapeId)\n\t * ```\n\t *\n\t * @param shape - The shape to get the masked bounds for.\n\t *\n\t * @public\n\t */\n\tgetShapeMaskedPageBounds(shape: TLShapeId | TLShape): Box | undefined {\n\t\tif (typeof shape !== 'string') shape = shape.id\n\t\treturn this._getShapeMaskedPageBoundsCache().get(shape)\n\t}\n\n\t/** @internal */\n\t@computed private _getShapeMaskedPageBoundsCache(): ComputedCache {\n\t\treturn this.store.createComputedCache('shapeMaskedPageBoundsCache', (shape) => {\n\t\t\tconst pageBounds = this._getShapePageBoundsCache().get(shape.id)\n\t\t\tif (!pageBounds) return\n\t\t\tconst pageMask = this._getShapeMaskCache().get(shape.id)\n\t\t\tif (pageMask) {\n\t\t\t\tif (pageMask.length === 0) return undefined\n\t\t\t\tconst { corners } = pageBounds\n\t\t\t\tif (corners.every((p, i) => p && Vec.Equals(p, pageMask[i]))) return pageBounds.clone()\n\t\t\t\tconst intersection = intersectPolygonPolygon(pageMask, corners)\n\t\t\t\tif (!intersection) return\n\t\t\t\treturn Box.FromPoints(intersection)\n\t\t\t}\n\t\t\treturn pageBounds\n\t\t})\n\t}\n\n\t/**\n\t * Get the ancestors of a shape.\n\t *\n\t * @example\n\t * ```ts\n\t * const ancestors = editor.getShapeAncestors(myShape)\n\t * const ancestors = editor.getShapeAncestors(myShapeId)\n\t * ```\n\t *\n\t * @param shape - The shape (or shape id) to get the ancestors for.\n\t *\n\t * @public\n\t */\n\tgetShapeAncestors(shape: TLShapeId | TLShape, acc: TLShape[] = []): TLShape[] {\n\t\tconst id = typeof shape === 'string' ? shape : shape.id\n\t\tconst freshShape = this.getShape(id)\n\t\tif (!freshShape) return acc\n\t\tconst parentId = freshShape.parentId\n\t\tif (isPageId(parentId)) {\n\t\t\tacc.reverse()\n\t\t\treturn acc\n\t\t}\n\n\t\tconst parent = this.store.get(parentId)\n\t\tif (!parent) return acc\n\t\tacc.push(parent)\n\t\treturn this.getShapeAncestors(parent, acc)\n\t}\n\n\t/**\n\t * Find the first ancestor matching the given predicate\n\t *\n\t * @example\n\t * ```ts\n\t * const ancestor = editor.findShapeAncestor(myShape)\n\t * const ancestor = editor.findShapeAncestor(myShape.id)\n\t * const ancestor = editor.findShapeAncestor(myShape.id, (shape) => shape.type === 'frame')\n\t * ```\n\t *\n\t * @param shape - The shape to check the ancestors for.\n\t *\n\t * @public\n\t */\n\tfindShapeAncestor(\n\t\tshape: TLShape | TLShapeId,\n\t\tpredicate: (parent: TLShape) => boolean\n\t): TLShape | undefined {\n\t\tconst id = typeof shape === 'string' ? shape : shape.id\n\t\tconst freshShape = this.getShape(id)\n\t\tif (!freshShape) return\n\n\t\tconst parentId = freshShape.parentId\n\t\tif (isPageId(parentId)) return\n\n\t\tconst parent = this.getShape(parentId)\n\t\tif (!parent) return\n\t\treturn predicate(parent) ? parent : this.findShapeAncestor(parent, predicate)\n\t}\n\n\t/**\n\t * Returns true if the the given shape has the given ancestor.\n\t *\n\t * @param shape - The shape.\n\t * @param ancestorId - The id of the ancestor.\n\t *\n\t * @public\n\t */\n\thasAncestor(shape: TLShape | TLShapeId | undefined, ancestorId: TLShapeId): boolean {\n\t\tconst id = typeof shape === 'string' ? shape : shape?.id\n\t\tconst freshShape = id && this.getShape(id)\n\t\tif (!freshShape) return false\n\t\tif (freshShape.parentId === ancestorId) return true\n\t\treturn this.hasAncestor(this.getShapeParent(freshShape), ancestorId)\n\t}\n\n\t/**\n\t * Get the common ancestor of two or more shapes that matches a predicate.\n\t *\n\t * @param shapes - The shapes (or shape ids) to check.\n\t * @param predicate - The predicate to match.\n\t */\n\tfindCommonAncestor(\n\t\tshapes: TLShape[] | TLShapeId[],\n\t\tpredicate?: (shape: TLShape) => boolean\n\t): TLShapeId | undefined {\n\t\tif (shapes.length === 0) {\n\t\t\treturn\n\t\t}\n\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\t\tconst freshShapes = compact(ids.map((id) => this.getShape(id)))\n\n\t\tif (freshShapes.length === 1) {\n\t\t\tconst parentId = freshShapes[0].parentId\n\t\t\tif (isPageId(parentId)) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\treturn predicate ? this.findShapeAncestor(freshShapes[0], predicate)?.id : parentId\n\t\t}\n\n\t\tconst [nodeA, ...others] = freshShapes\n\t\tlet ancestor = this.getShapeParent(nodeA)\n\t\twhile (ancestor) {\n\t\t\t// TODO: this is not ideal, optimize\n\t\t\tif (predicate && !predicate(ancestor)) {\n\t\t\t\tancestor = this.getShapeParent(ancestor)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif (others.every((shape) => this.hasAncestor(shape, ancestor!.id))) {\n\t\t\t\treturn ancestor!.id\n\t\t\t}\n\t\t\tancestor = this.getShapeParent(ancestor)\n\t\t}\n\t\treturn undefined\n\t}\n\n\t/**\n\t * Check whether a shape or its parent is locked.\n\t *\n\t * @param shape - The shape (or shape id) to check.\n\t *\n\t * @public\n\t */\n\tisShapeOrAncestorLocked(shape?: TLShape): boolean\n\tisShapeOrAncestorLocked(id?: TLShapeId): boolean\n\tisShapeOrAncestorLocked(arg?: TLShape | TLShapeId): boolean {\n\t\tconst shape = typeof arg === 'string' ? this.getShape(arg) : arg\n\t\tif (shape === undefined) return false\n\t\tif (shape.isLocked) return true\n\t\treturn this.isShapeOrAncestorLocked(this.getShapeParent(shape))\n\t}\n\n\t@computed\n\tprivate _notVisibleShapes() {\n\t\treturn notVisibleShapes(this)\n\t}\n\n\t/**\n\t * Get culled shapes.\n\t *\n\t * @public\n\t */\n\t@computed\n\tgetCulledShapes() {\n\t\tconst notVisibleShapes = this._notVisibleShapes().get()\n\t\tconst selectedShapeIds = this.getSelectedShapeIds()\n\t\tconst editingId = this.getEditingShapeId()\n\t\tconst culledShapes = new Set(notVisibleShapes)\n\t\t// we don't cull the shape we are editing\n\t\tif (editingId) {\n\t\t\tculledShapes.delete(editingId)\n\t\t}\n\t\t// we also don't cull selected shapes\n\t\tselectedShapeIds.forEach((id) => {\n\t\t\tculledShapes.delete(id)\n\t\t})\n\t\treturn culledShapes\n\t}\n\n\t/**\n\t * The bounds of the current page (the common bounds of all of the shapes on the page).\n\t *\n\t * @public\n\t */\n\t@computed getCurrentPageBounds(): Box | undefined {\n\t\tlet commonBounds: Box | undefined\n\n\t\tthis.getCurrentPageShapeIdsSorted().forEach((shapeId) => {\n\t\t\tconst bounds = this.getShapeMaskedPageBounds(shapeId)\n\t\t\tif (!bounds) return\n\t\t\tif (!commonBounds) {\n\t\t\t\tcommonBounds = bounds.clone()\n\t\t\t} else {\n\t\t\t\tcommonBounds = commonBounds.expand(bounds)\n\t\t\t}\n\t\t})\n\n\t\treturn commonBounds\n\t}\n\n\t/**\n\t * Get the top-most selected shape at the given point, ignoring groups.\n\t *\n\t * @param point - The point to check.\n\t *\n\t * @returns The top-most selected shape at the given point, or undefined if there is no shape at the point.\n\t */\n\tgetSelectedShapeAtPoint(point: VecLike): TLShape | undefined {\n\t\tconst selectedShapeIds = this.getSelectedShapeIds()\n\t\treturn this.getCurrentPageShapesSorted()\n\t\t\t.filter((shape) => shape.type !== 'group' && selectedShapeIds.includes(shape.id))\n\t\t\t.reverse() // find last\n\t\t\t.find((shape) => this.isPointInShape(shape, point, { hitInside: true, margin: 0 }))\n\t}\n\n\t/**\n\t * Get the shape at the current point.\n\t *\n\t * @param point - The point to check.\n\t * @param opts - Options for the check: `hitInside` to check if the point is inside the shape, `margin` to check if the point is within a margin of the shape, `hitFrameInside` to check if the point is inside the frame, and `filter` to filter the shapes to check.\n\t *\n\t * @returns The shape at the given point, or undefined if there is no shape at the point.\n\t */\n\tgetShapeAtPoint(\n\t\tpoint: VecLike,\n\t\topts = {} as {\n\t\t\trenderingOnly?: boolean\n\t\t\tmargin?: number\n\t\t\thitInside?: boolean\n\t\t\thitLocked?: boolean\n\t\t\t// TODO: we probably need to rename this, we don't quite _always_\n\t\t\t// respect this esp. in the part below that does \"Check labels first\"\n\t\t\thitLabels?: boolean\n\t\t\thitFrameInside?: boolean\n\t\t\tfilter?(shape: TLShape): boolean\n\t\t}\n\t): TLShape | undefined {\n\t\tconst zoomLevel = this.getZoomLevel()\n\t\tconst viewportPageBounds = this.getViewportPageBounds()\n\t\tconst {\n\t\t\tfilter,\n\t\t\tmargin = 0,\n\t\t\thitLocked = false,\n\t\t\thitLabels = false,\n\t\t\thitInside = false,\n\t\t\thitFrameInside = false,\n\t\t} = opts\n\n\t\tlet inHollowSmallestArea = Infinity\n\t\tlet inHollowSmallestAreaHit: TLShape | null = null\n\n\t\tlet inMarginClosestToEdgeDistance = Infinity\n\t\tlet inMarginClosestToEdgeHit: TLShape | null = null\n\n\t\tconst shapesToCheck = (\n\t\t\topts.renderingOnly\n\t\t\t\t? this.getCurrentPageRenderingShapesSorted()\n\t\t\t\t: this.getCurrentPageShapesSorted()\n\t\t).filter((shape) => {\n\t\t\tif (\n\t\t\t\t(shape.isLocked && !hitLocked) ||\n\t\t\t\tthis.isShapeHidden(shape) ||\n\t\t\t\tthis.isShapeOfType(shape, 'group')\n\t\t\t)\n\t\t\t\treturn false\n\t\t\tconst pageMask = this.getShapeMask(shape)\n\t\t\tif (pageMask && !pointInPolygon(point, pageMask)) return false\n\t\t\tif (filter) return filter(shape)\n\t\t\treturn true\n\t\t})\n\n\t\tfor (let i = shapesToCheck.length - 1; i >= 0; i--) {\n\t\t\tconst shape = shapesToCheck[i]\n\t\t\tconst geometry = this.getShapeGeometry(shape)\n\t\t\tconst isGroup = geometry instanceof Group2d\n\n\t\t\tconst pointInShapeSpace = this.getPointInShapeSpace(shape, point)\n\n\t\t\t// Check labels first\n\t\t\tif (\n\t\t\t\tthis.isShapeOfType(shape, 'arrow') ||\n\t\t\t\t(this.isShapeOfType(shape, 'geo') && shape.props.fill === 'none')\n\t\t\t) {\n\t\t\t\tif (shape.props.text.trim()) {\n\t\t\t\t\t// let's check whether the shape has a label and check that\n\t\t\t\t\tfor (const childGeometry of (geometry as Group2d).children) {\n\t\t\t\t\t\tif (childGeometry.isLabel && childGeometry.isPointInBounds(pointInShapeSpace)) {\n\t\t\t\t\t\t\treturn shape\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (this.isShapeOfType(shape, 'frame')) {\n\t\t\t\t// On the rare case that we've hit a frame, test again hitInside to be forced true;\n\t\t\t\t// this prevents clicks from passing through the body of a frame to shapes behind it.\n\n\t\t\t\t// If the hit is within the frame's outer margin, then select the frame\n\t\t\t\tconst distance = geometry.distanceToPoint(pointInShapeSpace, hitInside)\n\t\t\t\tif (Math.abs(distance) <= margin) {\n\t\t\t\t\treturn inMarginClosestToEdgeHit || shape\n\t\t\t\t}\n\n\t\t\t\tif (geometry.hitTestPoint(pointInShapeSpace, 0, true)) {\n\t\t\t\t\t// Once we've hit a frame, we want to end the search. If we have hit a shape\n\t\t\t\t\t// already, then this would either be above the frame or a child of the frame,\n\t\t\t\t\t// so we want to return that. Otherwise, the point is in the empty space of the\n\t\t\t\t\t// frame. If `hitFrameInside` is true (e.g. used drawing an arrow into the\n\t\t\t\t\t// frame) we the frame itself; other wise, (e.g. when hovering or pointing)\n\t\t\t\t\t// we would want to return null.\n\t\t\t\t\treturn (\n\t\t\t\t\t\tinMarginClosestToEdgeHit ||\n\t\t\t\t\t\tinHollowSmallestAreaHit ||\n\t\t\t\t\t\t(hitFrameInside ? shape : undefined)\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tlet distance: number\n\n\t\t\tif (isGroup) {\n\t\t\t\tlet minDistance = Infinity\n\t\t\t\tfor (const childGeometry of geometry.children) {\n\t\t\t\t\tif (childGeometry.isLabel && !hitLabels) continue\n\n\t\t\t\t\t// hit test the all of the child geometries that aren't labels\n\t\t\t\t\tconst tDistance = childGeometry.distanceToPoint(pointInShapeSpace, hitInside)\n\t\t\t\t\tif (tDistance < minDistance) {\n\t\t\t\t\t\tminDistance = tDistance\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tdistance = minDistance\n\t\t\t} else {\n\t\t\t\t// If the margin is zero and the geometry has a very small width or height,\n\t\t\t\t// then check the actual distance. This is to prevent a bug where straight\n\t\t\t\t// lines would never pass the broad phase (point-in-bounds) check.\n\t\t\t\tif (margin === 0 && (geometry.bounds.w < 1 || geometry.bounds.h < 1)) {\n\t\t\t\t\tdistance = geometry.distanceToPoint(pointInShapeSpace, hitInside)\n\t\t\t\t} else {\n\t\t\t\t\t// Broad phase\n\t\t\t\t\tif (geometry.bounds.containsPoint(pointInShapeSpace, margin)) {\n\t\t\t\t\t\t// Narrow phase (actual distance)\n\t\t\t\t\t\tdistance = geometry.distanceToPoint(pointInShapeSpace, hitInside)\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// Failed the broad phase, geddafugaotta'ere!\n\t\t\t\t\t\tdistance = Infinity\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (geometry.isClosed) {\n\t\t\t\t// For closed shapes, the distance will be positive if outside of\n\t\t\t\t// the shape or negative if inside of the shape. If the distance\n\t\t\t\t// is greater than the margin, then it's a miss. Otherwise...\n\n\t\t\t\tif (distance <= margin) {\n\t\t\t\t\tif (geometry.isFilled || (isGroup && geometry.children[0].isFilled)) {\n\t\t\t\t\t\t// If the shape is filled, then it's a hit. Remember, we're\n\t\t\t\t\t\t// starting from the TOP-MOST shape in z-index order, so any\n\t\t\t\t\t\t// other hits would be occluded by the shape.\n\t\t\t\t\t\treturn inMarginClosestToEdgeHit || shape\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// If the shape is bigger than the viewport, then skip it.\n\t\t\t\t\t\tif (this.getShapePageBounds(shape)!.contains(viewportPageBounds)) continue\n\n\t\t\t\t\t\t// For hollow shapes...\n\t\t\t\t\t\tif (Math.abs(distance) < margin) {\n\t\t\t\t\t\t\t// We want to preference shapes where we're inside of the\n\t\t\t\t\t\t\t// shape margin; and we would want to hit the shape with the\n\t\t\t\t\t\t\t// edge closest to the point.\n\t\t\t\t\t\t\tif (Math.abs(distance) < inMarginClosestToEdgeDistance) {\n\t\t\t\t\t\t\t\tinMarginClosestToEdgeDistance = Math.abs(distance)\n\t\t\t\t\t\t\t\tinMarginClosestToEdgeHit = shape\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else if (!inMarginClosestToEdgeHit) {\n\t\t\t\t\t\t\t// If we're not within margin distance to any edge, and if the\n\t\t\t\t\t\t\t// shape is hollow, then we want to hit the shape with the\n\t\t\t\t\t\t\t// smallest area. (There's a bug here with self-intersecting\n\t\t\t\t\t\t\t// shapes, like a closed drawing of an \"8\", but that's a bigger\n\t\t\t\t\t\t\t// problem to solve.)\n\t\t\t\t\t\t\tconst { area } = geometry\n\t\t\t\t\t\t\tif (area < inHollowSmallestArea) {\n\t\t\t\t\t\t\t\tinHollowSmallestArea = area\n\t\t\t\t\t\t\t\tinHollowSmallestAreaHit = shape\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// For open shapes (e.g. lines or draw shapes) always use the margin.\n\t\t\t\t// If the distance is less than the margin, return the shape as the hit.\n\t\t\t\tif (distance < this.options.hitTestMargin / zoomLevel) {\n\t\t\t\t\treturn shape\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// If we haven't hit any filled shapes or frames, then return either\n\t\t// the shape who we hit within the margin (and of those, the one that\n\t\t// had the shortest distance between the point and the shape edge),\n\t\t// or else the hollow shape with the smallest area\u2014or if we didn't hit\n\t\t// any margins or any hollow shapes, then null.\n\t\treturn inMarginClosestToEdgeHit || inHollowSmallestAreaHit || undefined\n\t}\n\n\t/**\n\t * Get the shapes, if any, at a given page point.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getShapesAtPoint({ x: 100, y: 100 })\n\t * editor.getShapesAtPoint({ x: 100, y: 100 }, { hitInside: true, exact: true })\n\t * ```\n\t *\n\t * @param point - The page point to test.\n\t *\n\t * @public\n\t */\n\tgetShapesAtPoint(\n\t\tpoint: VecLike,\n\t\topts = {} as { margin?: number; hitInside?: boolean }\n\t): TLShape[] {\n\t\treturn this.getCurrentPageShapes().filter(\n\t\t\t(shape) => !this.isShapeHidden(shape) && this.isPointInShape(shape, point, opts)\n\t\t)\n\t}\n\n\t/**\n\t * Test whether a point (in the current page space) will will a shape. This method takes into account masks,\n\t * such as when a shape is the child of a frame and is partially clipped by the frame.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.isPointInShape({ x: 100, y: 100 }, myShape)\n\t * ```\n\t *\n\t * @param shape - The shape to test against.\n\t * @param point - The page point to test (in the current page space).\n\t * @param hitInside - Whether to count as a hit if the point is inside of a closed shape.\n\t *\n\t * @public\n\t */\n\tisPointInShape(\n\t\tshape: TLShape | TLShapeId,\n\t\tpoint: VecLike,\n\t\topts = {} as {\n\t\t\tmargin?: number\n\t\t\thitInside?: boolean\n\t\t}\n\t): boolean {\n\t\tconst { hitInside = false, margin = 0 } = opts\n\t\tconst id = typeof shape === 'string' ? shape : shape.id\n\t\t// If the shape is masked, and if the point falls outside of that\n\t\t// mask, then it's definitely a miss\u2014we don't need to test further.\n\t\tconst pageMask = this.getShapeMask(id)\n\t\tif (pageMask && !pointInPolygon(point, pageMask)) return false\n\n\t\treturn this.getShapeGeometry(id).hitTestPoint(\n\t\t\tthis.getPointInShapeSpace(shape, point),\n\t\t\tmargin,\n\t\t\thitInside\n\t\t)\n\t}\n\n\t/**\n\t * Convert a point in the current page space to a point in the local space of a shape. For example, if a\n\t * shape's page point were `{ x: 100, y: 100 }`, a page point at `{ x: 110, y: 110 }` would be at\n\t * `{ x: 10, y: 10 }` in the shape's local space.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getPointInShapeSpace(myShape, { x: 100, y: 100 })\n\t * ```\n\t *\n\t * @param shape - The shape to get the point in the local space of.\n\t * @param point - The page point to get in the local space of the shape.\n\t *\n\t * @public\n\t */\n\tgetPointInShapeSpace(shape: TLShape | TLShapeId, point: VecLike): Vec {\n\t\tconst id = typeof shape === 'string' ? shape : shape.id\n\t\treturn this._getShapePageTransformCache().get(id)!.clone().invert().applyToPoint(point)\n\t}\n\n\t/**\n\t * Convert a delta in the current page space to a point in the local space of a shape's parent.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getPointInParentSpace(myShape.id, { x: 100, y: 100 })\n\t * ```\n\t *\n\t * @param shape - The shape to get the point in the local space of.\n\t * @param point - The page point to get in the local space of the shape.\n\t *\n\t * @public\n\t */\n\tgetPointInParentSpace(shape: TLShapeId | TLShape, point: VecLike): Vec {\n\t\tconst id = typeof shape === 'string' ? shape : shape.id\n\t\tconst freshShape = this.getShape(id)\n\t\tif (!freshShape) return new Vec(0, 0)\n\t\tif (isPageId(freshShape.parentId)) return Vec.From(point)\n\n\t\tconst parentTransform = this.getShapePageTransform(freshShape.parentId)\n\t\tif (!parentTransform) return Vec.From(point)\n\t\treturn parentTransform.clone().invert().applyToPoint(point)\n\t}\n\n\t/**\n\t * An array containing all of the shapes in the current page.\n\t *\n\t * @public\n\t */\n\t@computed getCurrentPageShapes(): TLShape[] {\n\t\treturn Array.from(this.getCurrentPageShapeIds(), (id) => this.store.get(id)! as TLShape)\n\t}\n\n\t/**\n\t * An array containing all of the shapes in the current page, sorted in z-index order (accounting\n\t * for nested shapes): e.g. A, B, BA, BB, C.\n\t *\n\t * @public\n\t */\n\t@computed getCurrentPageShapesSorted(): TLShape[] {\n\t\tconst result: TLShape[] = []\n\t\tconst topLevelShapes = this.getSortedChildIdsForParent(this.getCurrentPageId())\n\n\t\tfor (let i = 0, n = topLevelShapes.length; i < n; i++) {\n\t\t\tpushShapeWithDescendants(this, topLevelShapes[i], result)\n\t\t}\n\n\t\treturn result\n\t}\n\n\t/**\n\t * An array containing all of the rendering shapes in the current page, sorted in z-index order (accounting\n\t * for nested shapes): e.g. A, B, BA, BB, C.\n\t *\n\t * @public\n\t */\n\t@computed getCurrentPageRenderingShapesSorted(): TLShape[] {\n\t\tconst culledShapes = this.getCulledShapes()\n\t\treturn this.getCurrentPageShapesSorted().filter(\n\t\t\t({ id }) => !culledShapes.has(id) && !this.isShapeHidden(id)\n\t\t)\n\t}\n\n\t/**\n\t * Get whether a shape matches the type of a TLShapeUtil.\n\t *\n\t * @example\n\t * ```ts\n\t * const isArrowShape = isShapeOfType(someShape, 'arrow')\n\t * ```\n\t *\n\t * @param util - the TLShapeUtil constructor to test against\n\t * @param shape - the shape to test\n\t *\n\t * @public\n\t */\n\tisShapeOfType(shape: TLUnknownShape, type: T['type']): shape is T\n\tisShapeOfType(\n\t\tshapeId: TLUnknownShape['id'],\n\t\ttype: T['type']\n\t): shapeId is T['id']\n\tisShapeOfType(\n\t\targ: TLUnknownShape | TLUnknownShape['id'],\n\t\ttype: T['type']\n\t) {\n\t\tconst shape = typeof arg === 'string' ? this.getShape(arg) : arg\n\t\tif (!shape) return false\n\t\treturn shape.type === type\n\t}\n\n\t/**\n\t * Get a shape by its id.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getShape('box1')\n\t * ```\n\t *\n\t * @param id - The id of the shape to get.\n\t *\n\t * @public\n\t */\n\tgetShape(shape: TLShape | TLParentId): T | undefined {\n\t\tconst id = typeof shape === 'string' ? shape : shape.id\n\t\tif (!isShapeId(id)) return undefined\n\t\treturn this.store.get(id) as T\n\t}\n\n\t/**\n\t * Get the parent shape for a given shape. Returns undefined if the shape is the direct child of\n\t * the page.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getShapeParent(myShape)\n\t * ```\n\t *\n\t * @public\n\t */\n\tgetShapeParent(shape?: TLShape | TLShapeId): TLShape | undefined {\n\t\tconst id = typeof shape === 'string' ? shape : shape?.id\n\t\tif (!id) return undefined\n\t\tconst freshShape = this.getShape(id)\n\t\tif (freshShape === undefined || !isShapeId(freshShape.parentId)) return undefined\n\t\treturn this.store.get(freshShape.parentId)\n\t}\n\n\t/**\n\t * If siblingShape and targetShape are siblings, this returns targetShape. If targetShape has an\n\t * ancestor who is a sibling of siblingShape, this returns that ancestor. Otherwise, this returns\n\t * undefined.\n\t *\n\t * @internal\n\t */\n\tgetShapeNearestSibling(\n\t\tsiblingShape: TLShape,\n\t\ttargetShape: TLShape | undefined\n\t): TLShape | undefined {\n\t\tif (!targetShape) {\n\t\t\treturn undefined\n\t\t}\n\t\tif (targetShape.parentId === siblingShape.parentId) {\n\t\t\treturn targetShape\n\t\t}\n\n\t\tconst ancestor = this.findShapeAncestor(\n\t\t\ttargetShape,\n\t\t\t(ancestor) => ancestor.parentId === siblingShape.parentId\n\t\t)\n\n\t\treturn ancestor\n\t}\n\n\t/**\n\t * Get whether the given shape is the descendant of the given page.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.isShapeInPage(myShape)\n\t * editor.isShapeInPage(myShape, 'page1')\n\t * ```\n\t *\n\t * @param shape - The shape to check.\n\t * @param pageId - The id of the page to check against. Defaults to the current page.\n\t *\n\t * @public\n\t */\n\tisShapeInPage(shape: TLShape | TLShapeId, pageId = this.getCurrentPageId()): boolean {\n\t\tconst id = typeof shape === 'string' ? shape : shape.id\n\t\tconst shapeToCheck = this.getShape(id)\n\t\tif (!shapeToCheck) return false\n\n\t\tlet shapeIsInPage = false\n\n\t\tif (shapeToCheck.parentId === pageId) {\n\t\t\tshapeIsInPage = true\n\t\t} else {\n\t\t\tlet parent = this.getShape(shapeToCheck.parentId)\n\t\t\tisInPageSearch: while (parent) {\n\t\t\t\tif (parent.parentId === pageId) {\n\t\t\t\t\tshapeIsInPage = true\n\t\t\t\t\tbreak isInPageSearch\n\t\t\t\t}\n\t\t\t\tparent = this.getShape(parent.parentId)\n\t\t\t}\n\t\t}\n\n\t\treturn shapeIsInPage\n\t}\n\n\t/**\n\t * Get the id of the containing page for a given shape.\n\t *\n\t * @param shape - The shape to get the page id for.\n\t *\n\t * @returns The id of the page that contains the shape, or undefined if the shape is undefined.\n\t *\n\t * @public\n\t */\n\tgetAncestorPageId(shape?: TLShape | TLShapeId): TLPageId | undefined {\n\t\tconst id = typeof shape === 'string' ? shape : shape?.id\n\t\tconst _shape = id && this.getShape(id)\n\t\tif (!_shape) return undefined\n\t\tif (isPageId(_shape.parentId)) {\n\t\t\treturn _shape.parentId\n\t\t} else {\n\t\t\treturn this.getAncestorPageId(this.getShape(_shape.parentId))\n\t\t}\n\t}\n\n\t// Parents and children\n\n\t/**\n\t * A cache of parents to children.\n\t *\n\t * @internal\n\t */\n\tprivate readonly _parentIdsToChildIds: ReturnType\n\n\t/**\n\t * Reparent shapes to a new parent. This operation preserves the shape's current page positions /\n\t * rotations.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.reparentShapes([box1, box2], 'frame1')\n\t * editor.reparentShapes([box1.id, box2.id], 'frame1')\n\t * editor.reparentShapes([box1.id, box2.id], 'frame1', 4)\n\t * ```\n\t *\n\t * @param shapes - The shapes (or shape ids) of the shapes to reparent.\n\t * @param parentId - The id of the new parent shape.\n\t * @param insertIndex - The index to insert the children.\n\t *\n\t * @public\n\t */\n\treparentShapes(shapes: TLShapeId[] | TLShape[], parentId: TLParentId, insertIndex?: IndexKey) {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string' ? (shapes as TLShapeId[]) : shapes.map((s) => (s as TLShape).id)\n\t\tif (ids.length === 0) return this\n\n\t\tconst changes: TLShapePartial[] = []\n\n\t\tconst parentTransform = isPageId(parentId)\n\t\t\t? Mat.Identity()\n\t\t\t: this.getShapePageTransform(parentId)!\n\n\t\tconst parentPageRotation = parentTransform.rotation()\n\n\t\tlet indices: IndexKey[] = []\n\n\t\tconst sibs = compact(this.getSortedChildIdsForParent(parentId).map((id) => this.getShape(id)))\n\n\t\tif (insertIndex) {\n\t\t\tconst sibWithInsertIndex = sibs.find((s) => s.index === insertIndex)\n\t\t\tif (sibWithInsertIndex) {\n\t\t\t\t// If there's a sibling with the same index as the insert index...\n\t\t\t\tconst sibAbove = sibs[sibs.indexOf(sibWithInsertIndex) + 1]\n\t\t\t\tif (sibAbove) {\n\t\t\t\t\t// If the sibling has a sibling above it, insert the shapes\n\t\t\t\t\t// between the sibling and its sibling above it.\n\t\t\t\t\tindices = getIndicesBetween(insertIndex, sibAbove.index, ids.length)\n\t\t\t\t} else {\n\t\t\t\t\t// Or if the sibling is the top sibling, insert the shapes\n\t\t\t\t\t// above the sibling\n\t\t\t\t\tindices = getIndicesAbove(insertIndex, ids.length)\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// If there's no collision, then we can start at the insert index\n\t\t\t\tconst sibAbove = sibs.sort(sortByIndex).find((s) => s.index > insertIndex)\n\n\t\t\t\tif (sibAbove) {\n\t\t\t\t\t// If the siblings include a sibling with a higher index, insert the shapes\n\t\t\t\t\t// between the insert index and the sibling with the higher index.\n\t\t\t\t\tindices = getIndicesBetween(insertIndex, sibAbove.index, ids.length)\n\t\t\t\t} else {\n\t\t\t\t\t// Otherwise, we're at the top of the order, so insert the shapes above\n\t\t\t\t\t// the insert index.\n\t\t\t\t\tindices = getIndicesAbove(insertIndex, ids.length)\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\t// If insert index is not specified, start the index at the top.\n\t\t\tconst sib = sibs.length && sibs[sibs.length - 1]\n\t\t\tindices = sib ? getIndicesAbove(sib.index, ids.length) : getIndices(ids.length)\n\t\t}\n\n\t\tconst invertedParentTransform = parentTransform.clone().invert()\n\n\t\tconst shapesToReparent = compact(ids.map((id) => this.getShape(id)))\n\n\t\t// Ignore locked shapes so that we can reparent locked shapes, for example\n\t\t// when a locked shape's parent is deleted.\n\t\tthis.run(\n\t\t\t() => {\n\t\t\t\tfor (let i = 0; i < shapesToReparent.length; i++) {\n\t\t\t\t\tconst shape = shapesToReparent[i]\n\n\t\t\t\t\tconst pageTransform = this.getShapePageTransform(shape)!\n\t\t\t\t\tif (!pageTransform) continue\n\n\t\t\t\t\tconst pagePoint = pageTransform.point()\n\t\t\t\t\tif (!pagePoint) continue\n\n\t\t\t\t\tconst newPoint = invertedParentTransform.applyToPoint(pagePoint)\n\t\t\t\t\tconst newRotation = pageTransform.rotation() - parentPageRotation\n\n\t\t\t\t\tchanges.push({\n\t\t\t\t\t\tid: shape.id,\n\t\t\t\t\t\ttype: shape.type,\n\t\t\t\t\t\tparentId: parentId,\n\t\t\t\t\t\tx: newPoint.x,\n\t\t\t\t\t\ty: newPoint.y,\n\t\t\t\t\t\trotation: newRotation,\n\t\t\t\t\t\tindex: indices[i],\n\t\t\t\t\t})\n\t\t\t\t}\n\n\t\t\t\tthis.updateShapes(changes)\n\t\t\t},\n\t\t\t{ ignoreShapeLock: true }\n\t\t)\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Get the index above the highest child of a given parent.\n\t *\n\t * @param parentId - The id of the parent.\n\t *\n\t * @returns The index.\n\t *\n\t * @public\n\t */\n\tgetHighestIndexForParent(parent: TLParentId | TLPage | TLShape): IndexKey {\n\t\tconst parentId = typeof parent === 'string' ? parent : parent.id\n\t\tconst children = this._parentIdsToChildIds.get()[parentId]\n\n\t\tif (!children || children.length === 0) {\n\t\t\treturn 'a1' as IndexKey\n\t\t}\n\t\tconst shape = this.getShape(children[children.length - 1])!\n\t\treturn getIndexAbove(shape.index)\n\t}\n\n\t/**\n\t * Get an array of all the children of a shape.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getSortedChildIdsForParent('frame1')\n\t * ```\n\t *\n\t * @param parentId - The id of the parent shape.\n\t *\n\t * @public\n\t */\n\tgetSortedChildIdsForParent(parent: TLParentId | TLPage | TLShape): TLShapeId[] {\n\t\tconst parentId = typeof parent === 'string' ? parent : parent.id\n\t\tconst ids = this._parentIdsToChildIds.get()[parentId]\n\t\tif (!ids) return EMPTY_ARRAY\n\t\treturn ids\n\t}\n\n\t/**\n\t * Run a visitor function for all descendants of a shape.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.visitDescendants('frame1', myCallback)\n\t * ```\n\t *\n\t * @param parentId - The id of the parent shape.\n\t * @param visitor - The visitor function.\n\t *\n\t * @public\n\t */\n\tvisitDescendants(\n\t\tparent: TLParentId | TLPage | TLShape,\n\t\tvisitor: (id: TLShapeId) => void | false\n\t): this {\n\t\tconst parentId = typeof parent === 'string' ? parent : parent.id\n\t\tconst children = this.getSortedChildIdsForParent(parentId)\n\t\tfor (const id of children) {\n\t\t\tif (visitor(id) === false) continue\n\t\t\tthis.visitDescendants(id, visitor)\n\t\t}\n\t\treturn this\n\t}\n\n\t/**\n\t * Get the shape ids of all descendants of the given shapes (including the shapes themselves). IDs are returned in z-index order.\n\t *\n\t * @param ids - The ids of the shapes to get descendants of.\n\t *\n\t * @returns The descendant ids.\n\t *\n\t * @public\n\t */\n\tgetShapeAndDescendantIds(ids: TLShapeId[]): Set {\n\t\tconst shapeIds = new Set()\n\t\tfor (const shape of ids.map((id) => this.getShape(id)!).sort(sortByIndex)) {\n\t\t\tshapeIds.add(shape.id)\n\t\t\tthis.visitDescendants(shape, (descendantId) => {\n\t\t\t\tshapeIds.add(descendantId)\n\t\t\t})\n\t\t}\n\t\treturn shapeIds\n\t}\n\n\t/**\n\t * Get the shape that some shapes should be dropped on at a given point.\n\t *\n\t * @param point - The point to find the parent for.\n\t * @param droppingShapes - The shapes that are being dropped.\n\t *\n\t * @returns The shape to drop on.\n\t *\n\t * @public\n\t */\n\tgetDroppingOverShape(point: VecLike, droppingShapes: TLShape[] = []) {\n\t\t// starting from the top...\n\t\tconst currentPageShapesSorted = this.getCurrentPageShapesSorted()\n\t\tfor (let i = currentPageShapesSorted.length - 1; i >= 0; i--) {\n\t\t\tconst shape = currentPageShapesSorted[i]\n\n\t\t\tif (\n\t\t\t\t// ignore hidden shapes\n\t\t\t\tthis.isShapeHidden(shape) ||\n\t\t\t\t// don't allow dropping on selected shapes\n\t\t\t\tthis.getSelectedShapeIds().includes(shape.id) ||\n\t\t\t\t// only allow shapes that can receive children\n\t\t\t\t!this.getShapeUtil(shape).canDropShapes(shape, droppingShapes) ||\n\t\t\t\t// don't allow dropping a shape on itself or one of it's children\n\t\t\t\tdroppingShapes.find((s) => s.id === shape.id || this.hasAncestor(shape, s.id))\n\t\t\t) {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\t// Only allow dropping into the masked page bounds of the shape, e.g. when a frame is\n\t\t\t// partially clipped by its own parent frame\n\t\t\tconst maskedPageBounds = this.getShapeMaskedPageBounds(shape.id)\n\n\t\t\tif (\n\t\t\t\tmaskedPageBounds &&\n\t\t\t\tmaskedPageBounds.containsPoint(point) &&\n\t\t\t\tthis.getShapeGeometry(shape).hitTestPoint(this.getPointInShapeSpace(shape, point), 0, true)\n\t\t\t) {\n\t\t\t\treturn shape\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Get the shape that should be selected when you click on a given shape, assuming there is\n\t * nothing already selected. It will not return anything higher than or including the current\n\t * focus layer.\n\t *\n\t * @param shape - The shape to get the outermost selectable shape for.\n\t * @param filter - A function to filter the selectable shapes.\n\t *\n\t * @returns The outermost selectable shape.\n\t *\n\t * @public\n\t */\n\tgetOutermostSelectableShape(\n\t\tshape: TLShape | TLShapeId,\n\t\tfilter?: (shape: TLShape) => boolean\n\t): TLShape {\n\t\tconst id = typeof shape === 'string' ? shape : shape.id\n\t\tconst freshShape = this.getShape(id)!\n\t\tlet match = freshShape\n\t\tlet node = freshShape as TLShape | undefined\n\n\t\tconst focusedGroup = this.getFocusedGroup()\n\n\t\twhile (node) {\n\t\t\tif (\n\t\t\t\tthis.isShapeOfType(node, 'group') &&\n\t\t\t\tfocusedGroup?.id !== node.id &&\n\t\t\t\t!this.hasAncestor(focusedGroup, node.id) &&\n\t\t\t\t(filter?.(node) ?? true)\n\t\t\t) {\n\t\t\t\tmatch = node\n\t\t\t} else if (focusedGroup?.id === node.id) {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tnode = this.getShapeParent(node)\n\t\t}\n\n\t\treturn match\n\t}\n\n\t/* -------------------- Bindings -------------------- */\n\n\t@computed\n\tprivate _getBindingsIndexCache() {\n\t\tconst index = bindingsIndex(this)\n\t\treturn this.store.createComputedCache('bindingsIndex', (shape) => {\n\t\t\treturn index.get().get(shape.id)\n\t\t})\n\t}\n\n\t/**\n\t * Get a binding from the store by its ID if it exists.\n\t */\n\tgetBinding(id: TLBindingId): TLBinding | undefined {\n\t\treturn this.store.get(id) as TLBinding | undefined\n\t}\n\n\t/**\n\t * Get all bindings of a certain type _from_ a particular shape. These are the bindings whose\n\t * `fromId` matched the shape's ID.\n\t */\n\tgetBindingsFromShape(\n\t\tshape: TLShape | TLShapeId,\n\t\ttype: Binding['type']\n\t): Binding[] {\n\t\tconst id = typeof shape === 'string' ? shape : shape.id\n\t\treturn this.getBindingsInvolvingShape(id).filter(\n\t\t\t(b) => b.fromId === id && b.type === type\n\t\t) as Binding[]\n\t}\n\n\t/**\n\t * Get all bindings of a certain type _to_ a particular shape. These are the bindings whose\n\t * `toId` matches the shape's ID.\n\t */\n\tgetBindingsToShape(\n\t\tshape: TLShape | TLShapeId,\n\t\ttype: Binding['type']\n\t): Binding[] {\n\t\tconst id = typeof shape === 'string' ? shape : shape.id\n\t\treturn this.getBindingsInvolvingShape(id).filter(\n\t\t\t(b) => b.toId === id && b.type === type\n\t\t) as Binding[]\n\t}\n\n\t/**\n\t * Get all bindings involving a particular shape. This includes bindings where the shape is the\n\t * `fromId` or `toId`. If a type is provided, only bindings of that type are returned.\n\t */\n\tgetBindingsInvolvingShape(\n\t\tshape: TLShape | TLShapeId,\n\t\ttype?: Binding['type']\n\t): Binding[] {\n\t\tconst id = typeof shape === 'string' ? shape : shape.id\n\t\tconst result = this._getBindingsIndexCache().get(id) ?? EMPTY_ARRAY\n\t\tif (!type) return result as Binding[]\n\t\treturn result.filter((b) => b.type === type) as Binding[]\n\t}\n\n\t/**\n\t * Create bindings from a list of partial bindings. You can omit the ID and most props of a\n\t * binding, but the `type`, `toId`, and `fromId` must all be provided.\n\t */\n\tcreateBindings(partials: TLBindingCreate[]) {\n\t\tconst bindings: TLBinding[] = []\n\t\tfor (const partial of partials) {\n\t\t\tconst fromShape = this.getShape(partial.fromId)\n\t\t\tconst toShape = this.getShape(partial.toId)\n\t\t\tif (!fromShape || !toShape) continue\n\t\t\tif (!this.canBindShapes({ fromShape, toShape, binding: partial })) continue\n\n\t\t\tconst util = this.getBindingUtil(partial.type)\n\t\t\tconst defaultProps = util.getDefaultProps()\n\t\t\tconst binding = this.store.schema.types.binding.create({\n\t\t\t\t...partial,\n\t\t\t\tid: partial.id ?? createBindingId(),\n\t\t\t\tprops: {\n\t\t\t\t\t...defaultProps,\n\t\t\t\t\t...partial.props,\n\t\t\t\t},\n\t\t\t}) as TLBinding\n\n\t\t\tbindings.push(binding)\n\t\t}\n\n\t\tthis.store.put(bindings)\n\t\treturn this\n\t}\n\n\t/**\n\t * Create a single binding from a partial. You can omit the ID and most props of a binding, but\n\t * the `type`, `toId`, and `fromId` must all be provided.\n\t */\n\tcreateBinding(partial: TLBindingCreate) {\n\t\treturn this.createBindings([partial])\n\t}\n\n\t/**\n\t * Update bindings from a list of partial bindings. Each partial must include an ID, which will\n\t * be used to match the binding to it's existing record. If there is no existing record, that\n\t * binding is skipped. The changes from the partial are merged into the existing record.\n\t */\n\tupdateBindings(partials: (TLBindingUpdate | null | undefined)[]) {\n\t\tconst updated: TLBinding[] = []\n\n\t\tfor (const partial of partials) {\n\t\t\tif (!partial) continue\n\n\t\t\tconst current = this.getBinding(partial.id)\n\t\t\tif (!current) continue\n\n\t\t\tconst updatedBinding = applyPartialToRecordWithProps(current, partial)\n\t\t\tif (updatedBinding === current) continue\n\n\t\t\tconst fromShape = this.getShape(updatedBinding.fromId)\n\t\t\tconst toShape = this.getShape(updatedBinding.toId)\n\t\t\tif (!fromShape || !toShape) continue\n\t\t\tif (!this.canBindShapes({ fromShape, toShape, binding: updatedBinding })) continue\n\n\t\t\tupdated.push(updatedBinding)\n\t\t}\n\n\t\tthis.store.put(updated)\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Update a binding from a partial binding. Each partial must include an ID, which will be used\n\t * to match the binding to it's existing record. If there is no existing record, that binding is\n\t * skipped. The changes from the partial are merged into the existing record.\n\t */\n\tupdateBinding(partial: TLBindingUpdate) {\n\t\treturn this.updateBindings([partial])\n\t}\n\n\t/**\n\t * Delete several bindings by their IDs. If a binding ID doesn't exist, it's ignored.\n\t */\n\tdeleteBindings(bindings: (TLBinding | TLBindingId)[], { isolateShapes = false } = {}) {\n\t\tconst ids = bindings.map((binding) => (typeof binding === 'string' ? binding : binding.id))\n\t\tif (isolateShapes) {\n\t\t\tthis.store.atomic(() => {\n\t\t\t\tfor (const id of ids) {\n\t\t\t\t\tconst binding = this.getBinding(id)\n\t\t\t\t\tif (!binding) continue\n\t\t\t\t\tconst util = this.getBindingUtil(binding)\n\t\t\t\t\tutil.onBeforeIsolateFromShape?.({ binding, removedShape: this.getShape(binding.toId)! })\n\t\t\t\t\tutil.onBeforeIsolateToShape?.({ binding, removedShape: this.getShape(binding.fromId)! })\n\t\t\t\t\tthis.store.remove([id])\n\t\t\t\t}\n\t\t\t})\n\t\t} else {\n\t\t\tthis.store.remove(ids)\n\t\t}\n\t\treturn this\n\t}\n\t/**\n\t * Delete a binding by its ID. If the binding doesn't exist, it's ignored.\n\t */\n\tdeleteBinding(binding: TLBinding | TLBindingId, opts?: Parameters[1]) {\n\t\treturn this.deleteBindings([binding], opts)\n\t}\n\tcanBindShapes({\n\t\tfromShape,\n\t\ttoShape,\n\t\tbinding,\n\t}: {\n\t\tfromShape: TLShape | { type: TLShape['type'] } | TLShape['type']\n\t\ttoShape: TLShape | { type: TLShape['type'] } | TLShape['type']\n\t\tbinding: TLBinding | { type: TLBinding['type'] } | TLBinding['type']\n\t}): boolean {\n\t\tconst fromShapeType = typeof fromShape === 'string' ? fromShape : fromShape.type\n\t\tconst toShapeType = typeof toShape === 'string' ? toShape : toShape.type\n\t\tconst bindingType = typeof binding === 'string' ? binding : binding.type\n\n\t\tconst canBindOpts = { fromShapeType, toShapeType, bindingType }\n\n\t\tif (fromShapeType === toShapeType) {\n\t\t\treturn this.getShapeUtil(fromShapeType).canBind(canBindOpts)\n\t\t}\n\n\t\treturn (\n\t\t\tthis.getShapeUtil(fromShapeType).canBind(canBindOpts) &&\n\t\t\tthis.getShapeUtil(toShapeType).canBind(canBindOpts)\n\t\t)\n\t}\n\n\t/* -------------------- Commands -------------------- */\n\n\t/**\n\t * Rotate shapes by a delta in radians.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.rotateShapesBy(editor.getSelectedShapeIds(), Math.PI)\n\t * editor.rotateShapesBy(editor.getSelectedShapeIds(), Math.PI / 2)\n\t * ```\n\t *\n\t * @param shapes - The shapes (or shape ids) of the shapes to move.\n\t * @param delta - The delta in radians to apply to the selection rotation.\n\t */\n\trotateShapesBy(\n\t\tshapes: TLShapeId[] | TLShape[],\n\t\tdelta: number,\n\t\topts?: { center?: VecLike }\n\t): this {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\n\t\tif (ids.length <= 0) return this\n\n\t\tconst snapshot = getRotationSnapshot({ editor: this, ids })\n\t\tif (!snapshot) return this\n\t\tapplyRotationToSnapshotShapes({\n\t\t\tdelta,\n\t\t\tsnapshot,\n\t\t\teditor: this,\n\t\t\tstage: 'one-off',\n\t\t\tcenterOverride: opts?.center,\n\t\t})\n\n\t\treturn this\n\t}\n\n\tprivate getChangesToTranslateShape(initialShape: TLShape, newShapeCoords: VecLike): TLShape {\n\t\tlet workingShape = initialShape\n\t\tconst util = this.getShapeUtil(initialShape)\n\n\t\tworkingShape = applyPartialToRecordWithProps(\n\t\t\tworkingShape,\n\t\t\tutil.onTranslateStart?.(workingShape) ?? undefined\n\t\t)\n\n\t\tworkingShape = applyPartialToRecordWithProps(workingShape, {\n\t\t\tid: initialShape.id,\n\t\t\ttype: initialShape.type,\n\t\t\tx: newShapeCoords.x,\n\t\t\ty: newShapeCoords.y,\n\t\t})\n\n\t\tworkingShape = applyPartialToRecordWithProps(\n\t\t\tworkingShape,\n\t\t\tutil.onTranslate?.(initialShape, workingShape) ?? undefined\n\t\t)\n\n\t\tworkingShape = applyPartialToRecordWithProps(\n\t\t\tworkingShape,\n\t\t\tutil.onTranslateEnd?.(initialShape, workingShape) ?? undefined\n\t\t)\n\n\t\treturn workingShape\n\t}\n\n\t/**\n\t * Move shapes by a delta.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.nudgeShapes(['box1', 'box2'], { x: 8, y: 8 })\n\t * ```\n\t *\n\t * @param shapes - The shapes (or shape ids) to move.\n\t * @param direction - The direction in which to move the shapes.\n\t * @param historyOptions - The history options for the change.\n\t */\n\tnudgeShapes(shapes: TLShapeId[] | TLShape[], offset: VecLike): this {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\n\t\tif (ids.length <= 0) return this\n\t\tconst changes: TLShapePartial[] = []\n\n\t\tfor (const id of ids) {\n\t\t\tconst shape = this.getShape(id)!\n\t\t\tconst localDelta = Vec.From(offset)\n\t\t\tconst parentTransform = this.getShapeParentTransform(shape)\n\t\t\tif (parentTransform) localDelta.rot(-parentTransform.rotation())\n\n\t\t\tchanges.push(this.getChangesToTranslateShape(shape, localDelta.add(shape)))\n\t\t}\n\n\t\tthis.updateShapes(changes)\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Duplicate shapes.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.duplicateShapes(['box1', 'box2'], { x: 8, y: 8 })\n\t * editor.duplicateShapes(editor.getSelectedShapes(), { x: 8, y: 8 })\n\t * ```\n\t *\n\t * @param shapes - The shapes (or shape ids) to duplicate.\n\t * @param offset - The offset (in pixels) to apply to the duplicated shapes.\n\t *\n\t * @public\n\t */\n\tduplicateShapes(shapes: TLShapeId[] | TLShape[], offset?: VecLike): this {\n\t\tthis.run(() => {\n\t\t\tconst ids =\n\t\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\n\t\t\tif (ids.length <= 0) return this\n\n\t\t\tconst initialIds = new Set(ids)\n\t\t\tconst shapeIdSet = this.getShapeAndDescendantIds(ids)\n\n\t\t\tconst orderedShapeIds = [...shapeIdSet].reverse()\n\t\t\tconst shapeIds = new Map()\n\t\t\tfor (const shapeId of shapeIdSet) {\n\t\t\t\tshapeIds.set(shapeId, createShapeId())\n\t\t\t}\n\n\t\t\tconst { shapesToCreateWithOriginals, bindingsToCreate } = withIsolatedShapes(\n\t\t\t\tthis,\n\t\t\t\tshapeIdSet,\n\t\t\t\t(bindingIdsToMaintain) => {\n\t\t\t\t\tconst bindingsToCreate: TLBinding[] = []\n\t\t\t\t\tfor (const originalId of bindingIdsToMaintain) {\n\t\t\t\t\t\tconst originalBinding = this.getBinding(originalId)\n\t\t\t\t\t\tif (!originalBinding) continue\n\n\t\t\t\t\t\tconst duplicatedId = createBindingId()\n\t\t\t\t\t\tbindingsToCreate.push({\n\t\t\t\t\t\t\t...originalBinding,\n\t\t\t\t\t\t\tid: duplicatedId,\n\t\t\t\t\t\t\tfromId: assertExists(shapeIds.get(originalBinding.fromId)),\n\t\t\t\t\t\t\ttoId: assertExists(shapeIds.get(originalBinding.toId)),\n\t\t\t\t\t\t})\n\t\t\t\t\t}\n\n\t\t\t\t\tconst shapesToCreateWithOriginals: { shape: TLShape; originalShape: TLShape }[] = []\n\t\t\t\t\tfor (const originalId of orderedShapeIds) {\n\t\t\t\t\t\tconst duplicatedId = assertExists(shapeIds.get(originalId))\n\t\t\t\t\t\tconst originalShape = this.getShape(originalId)\n\t\t\t\t\t\tif (!originalShape) continue\n\n\t\t\t\t\t\tlet ox = 0\n\t\t\t\t\t\tlet oy = 0\n\n\t\t\t\t\t\tif (offset && initialIds.has(originalId)) {\n\t\t\t\t\t\t\tconst parentTransform = this.getShapeParentTransform(originalShape)\n\t\t\t\t\t\t\tconst vec = new Vec(offset.x, offset.y).rot(-parentTransform!.rotation())\n\t\t\t\t\t\t\tox = vec.x\n\t\t\t\t\t\t\toy = vec.y\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tshapesToCreateWithOriginals.push({\n\t\t\t\t\t\t\tshape: {\n\t\t\t\t\t\t\t\t...originalShape,\n\t\t\t\t\t\t\t\tid: duplicatedId,\n\t\t\t\t\t\t\t\tx: originalShape.x + ox,\n\t\t\t\t\t\t\t\ty: originalShape.y + oy,\n\t\t\t\t\t\t\t\t// Use a dummy index for now, it will get updated outside of the `withIsolatedShapes`\n\t\t\t\t\t\t\t\tindex: 'a1' as IndexKey,\n\t\t\t\t\t\t\t\tparentId:\n\t\t\t\t\t\t\t\t\tshapeIds.get(originalShape.parentId as TLShapeId) ?? originalShape.parentId,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\toriginalShape,\n\t\t\t\t\t\t})\n\t\t\t\t\t}\n\n\t\t\t\t\treturn { shapesToCreateWithOriginals, bindingsToCreate }\n\t\t\t\t}\n\t\t\t)\n\n\t\t\t// We will update the indexes after the `withIsolatedShapes`, since we cannot rely on the indexes\n\t\t\t// to be correct inside of it.\n\t\t\tshapesToCreateWithOriginals.forEach(({ shape, originalShape }) => {\n\t\t\t\tconst parentId = originalShape.parentId\n\t\t\t\tconst siblings = this.getSortedChildIdsForParent(parentId)\n\t\t\t\tconst currentIndex = siblings.indexOf(originalShape.id)\n\t\t\t\tconst siblingAboveId = siblings[currentIndex + 1]\n\t\t\t\tconst siblingAbove = siblingAboveId ? this.getShape(siblingAboveId) : undefined\n\n\t\t\t\tconst index = getIndexBetween(originalShape.index, siblingAbove?.index)\n\n\t\t\t\tshape.index = index\n\t\t\t})\n\t\t\tconst shapesToCreate = shapesToCreateWithOriginals.map(({ shape }) => shape)\n\n\t\t\tconst maxShapesReached =\n\t\t\t\tshapesToCreate.length + this.getCurrentPageShapeIds().size > this.options.maxShapesPerPage\n\n\t\t\tif (maxShapesReached) {\n\t\t\t\talertMaxShapes(this)\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tthis.createShapes(shapesToCreate)\n\t\t\tthis.createBindings(bindingsToCreate)\n\t\t\tthis.setSelectedShapes(compact(ids.map((id) => shapeIds.get(id))))\n\n\t\t\tif (offset !== undefined) {\n\t\t\t\t// If we've offset the duplicated shapes, check to see whether their new bounds is entirely\n\t\t\t\t// contained in the current viewport. If not, then animate the camera to be centered on the\n\t\t\t\t// new shapes.\n\t\t\t\tconst selectionPageBounds = this.getSelectionPageBounds()\n\t\t\t\tconst viewportPageBounds = this.getViewportPageBounds()\n\t\t\t\tif (selectionPageBounds && !viewportPageBounds.contains(selectionPageBounds)) {\n\t\t\t\t\tthis.centerOnPoint(selectionPageBounds.center, {\n\t\t\t\t\t\tanimation: { duration: this.options.animationMediumMs },\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t}\n\t\t})\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Move shapes to page.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.moveShapesToPage(['box1', 'box2'], 'page1')\n\t * ```\n\t *\n\t * @param shapes - The shapes (or shape ids) of the shapes to move.\n\t * @param pageId - The id of the page where the shapes will be moved.\n\t *\n\t * @public\n\t */\n\tmoveShapesToPage(shapes: TLShapeId[] | TLShape[], pageId: TLPageId): this {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\n\t\tif (ids.length === 0) return this\n\t\tif (this.getInstanceState().isReadonly) return this\n\n\t\tconst currentPageId = this.getCurrentPageId()\n\n\t\tif (pageId === currentPageId) return this\n\t\tif (!this.store.has(pageId)) return this\n\n\t\t// Basically copy the shapes\n\t\tconst content = this.getContentFromCurrentPage(ids)\n\n\t\t// Just to be sure\n\t\tif (!content) return this\n\n\t\t// If there is no space on pageId, or if the selected shapes\n\t\t// would take the new page above the limit, don't move the shapes\n\t\tif (this.getPageShapeIds(pageId).size + content.shapes.length > this.options.maxShapesPerPage) {\n\t\t\talertMaxShapes(this, pageId)\n\t\t\treturn this\n\t\t}\n\n\t\tconst fromPageZ = this.getCamera().z\n\n\t\tthis.run(() => {\n\t\t\t// Delete the shapes on the current page\n\t\t\tthis.deleteShapes(ids)\n\n\t\t\t// Move to the next page\n\t\t\tthis.setCurrentPage(pageId)\n\n\t\t\t// Put the shape content onto the new page; parents and indices will\n\t\t\t// be taken care of by the putContent method; make sure to pop any focus\n\t\t\t// layers so that the content will be put onto the page.\n\t\t\tthis.setFocusedGroup(null)\n\t\t\tthis.selectNone()\n\t\t\tthis.putContentOntoCurrentPage(content, {\n\t\t\t\tselect: true,\n\t\t\t\tpreserveIds: true,\n\t\t\t\tpreservePosition: true,\n\t\t\t})\n\n\t\t\t// Force the new page's camera to be at the same zoom level as the\n\t\t\t// \"from\" page's camera, then center the \"to\" page's camera on the\n\t\t\t// pasted shapes\n\t\t\tthis.setCamera({ ...this.getCamera(), z: fromPageZ })\n\t\t\tthis.centerOnPoint(this.getSelectionRotatedPageBounds()!.center)\n\t\t})\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Toggle the lock state of one or more shapes. If there is a mix of locked and unlocked shapes, all shapes will be locked.\n\t *\n\t * @param shapes - The shapes (or shape ids) to toggle.\n\t *\n\t * @public\n\t */\n\ttoggleLock(shapes: TLShapeId[] | TLShape[]): this {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\n\t\tif (this.getInstanceState().isReadonly || ids.length === 0) return this\n\n\t\tlet allLocked = true,\n\t\t\tallUnlocked = true\n\t\tconst shapesToToggle: TLShape[] = []\n\t\tfor (const id of ids) {\n\t\t\tconst shape = this.getShape(id)\n\t\t\tif (shape) {\n\t\t\t\tshapesToToggle.push(shape)\n\t\t\t\tif (shape.isLocked) {\n\t\t\t\t\tallUnlocked = false\n\t\t\t\t} else {\n\t\t\t\t\tallLocked = false\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tthis.run(() => {\n\t\t\tif (allUnlocked) {\n\t\t\t\tthis.updateShapes(\n\t\t\t\t\tshapesToToggle.map((shape) => ({ id: shape.id, type: shape.type, isLocked: true }))\n\t\t\t\t)\n\t\t\t\tthis.setSelectedShapes([])\n\t\t\t} else if (allLocked) {\n\t\t\t\tthis.updateShapes(\n\t\t\t\t\tshapesToToggle.map((shape) => ({ id: shape.id, type: shape.type, isLocked: false }))\n\t\t\t\t)\n\t\t\t} else {\n\t\t\t\tthis.updateShapes(\n\t\t\t\t\tshapesToToggle.map((shape) => ({ id: shape.id, type: shape.type, isLocked: true }))\n\t\t\t\t)\n\t\t\t}\n\t\t})\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Send shapes to the back of the page's object list.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.sendToBack(['id1', 'id2'])\n\t * editor.sendToBack(box1, box2)\n\t * ```\n\t *\n\t * @param shapes - The shapes (or shape ids) to move.\n\t *\n\t * @public\n\t */\n\tsendToBack(shapes: TLShapeId[] | TLShape[]): this {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\t\tconst changes = getReorderingShapesChanges(this, 'toBack', ids as TLShapeId[])\n\t\tif (changes) this.updateShapes(changes)\n\t\treturn this\n\t}\n\n\t/**\n\t * Send shapes backward in the page's object list.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.sendBackward(['id1', 'id2'])\n\t * editor.sendBackward([box1, box2])\n\t * ```\n\t *\n\t * @param shapes - The shapes (or shape ids) to move.\n\t *\n\t * @public\n\t */\n\tsendBackward(shapes: TLShapeId[] | TLShape[]): this {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\t\tconst changes = getReorderingShapesChanges(this, 'backward', ids as TLShapeId[])\n\t\tif (changes) this.updateShapes(changes)\n\t\treturn this\n\t}\n\n\t/**\n\t * Bring shapes forward in the page's object list.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.bringForward(['id1', 'id2'])\n\t * editor.bringForward(box1, box2)\n\t * ```\n\t *\n\t * @param shapes - The shapes (or shape ids) to move.\n\t *\n\t * @public\n\t */\n\tbringForward(shapes: TLShapeId[] | TLShape[]): this {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\t\tconst changes = getReorderingShapesChanges(this, 'forward', ids as TLShapeId[])\n\t\tif (changes) this.updateShapes(changes)\n\t\treturn this\n\t}\n\n\t/**\n\t * Bring shapes to the front of the page's object list.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.bringToFront(['id1', 'id2'])\n\t * editor.bringToFront([box1, box2])\n\t * ```\n\t *\n\t * @param shapes - The shapes (or shape ids) to move.\n\t *\n\t * @public\n\t */\n\tbringToFront(shapes: TLShapeId[] | TLShape[]): this {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\t\tconst changes = getReorderingShapesChanges(this, 'toFront', ids as TLShapeId[])\n\t\tif (changes) this.updateShapes(changes)\n\t\treturn this\n\t}\n\n\t/**\n\t * Flip shape positions.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.flipShapes([box1, box2], 'horizontal', 32)\n\t * editor.flipShapes(editor.getSelectedShapeIds(), 'horizontal', 32)\n\t * ```\n\t *\n\t * @param shapes - The ids of the shapes to flip.\n\t * @param operation - Whether to flip horizontally or vertically.\n\t *\n\t * @public\n\t */\n\tflipShapes(shapes: TLShapeId[] | TLShape[], operation: 'horizontal' | 'vertical'): this {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\n\t\tif (this.getInstanceState().isReadonly) return this\n\n\t\tlet shapesToFlip = compact(ids.map((id) => this.getShape(id)))\n\n\t\tif (!shapesToFlip.length) return this\n\n\t\tshapesToFlip = compact(\n\t\t\tshapesToFlip\n\t\t\t\t.map((shape) => {\n\t\t\t\t\tif (this.isShapeOfType(shape, 'group')) {\n\t\t\t\t\t\treturn this.getSortedChildIdsForParent(shape.id).map((id) => this.getShape(id))\n\t\t\t\t\t}\n\n\t\t\t\t\treturn shape\n\t\t\t\t})\n\t\t\t\t.flat()\n\t\t)\n\n\t\tconst scaleOriginPage = Box.Common(\n\t\t\tcompact(shapesToFlip.map((id) => this.getShapePageBounds(id)))\n\t\t).center\n\n\t\tthis.run(() => {\n\t\t\tfor (const shape of shapesToFlip) {\n\t\t\t\tconst bounds = this.getShapeGeometry(shape).bounds\n\t\t\t\tconst initialPageTransform = this.getShapePageTransform(shape.id)\n\t\t\t\tif (!initialPageTransform) continue\n\t\t\t\tthis.resizeShape(\n\t\t\t\t\tshape.id,\n\t\t\t\t\t{ x: operation === 'horizontal' ? -1 : 1, y: operation === 'vertical' ? -1 : 1 },\n\t\t\t\t\t{\n\t\t\t\t\t\tinitialBounds: bounds,\n\t\t\t\t\t\tinitialPageTransform,\n\t\t\t\t\t\tinitialShape: shape,\n\t\t\t\t\t\tmode: 'scale_shape',\n\t\t\t\t\t\tisAspectRatioLocked: this.getShapeUtil(shape).isAspectRatioLocked(shape),\n\t\t\t\t\t\tscaleOrigin: scaleOriginPage,\n\t\t\t\t\t\tscaleAxisRotation: 0,\n\t\t\t\t\t}\n\t\t\t\t)\n\t\t\t}\n\t\t})\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Stack shape.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.stackShapes([box1, box2], 'horizontal', 32)\n\t * editor.stackShapes(editor.getSelectedShapeIds(), 'horizontal', 32)\n\t * ```\n\t *\n\t * @param shapes - The shapes (or shape ids) to stack.\n\t * @param operation - Whether to stack horizontally or vertically.\n\t * @param gap - The gap to leave between shapes.\n\t *\n\t * @public\n\t */\n\tstackShapes(\n\t\tshapes: TLShapeId[] | TLShape[],\n\t\toperation: 'horizontal' | 'vertical',\n\t\tgap: number\n\t): this {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\t\tif (this.getInstanceState().isReadonly) return this\n\n\t\tconst shapesToStack = ids\n\t\t\t.map((id) => this.getShape(id)) // always fresh shapes\n\t\t\t.filter((shape): shape is TLShape => {\n\t\t\t\tif (!shape) return false\n\n\t\t\t\treturn this.getShapeUtil(shape).canBeLaidOut(shape)\n\t\t\t})\n\n\t\tconst len = shapesToStack.length\n\n\t\tif ((gap === 0 && len < 3) || len < 2) return this\n\n\t\tconst pageBounds = Object.fromEntries(\n\t\t\tshapesToStack.map((shape) => [shape.id, this.getShapePageBounds(shape)!])\n\t\t)\n\n\t\tlet val: 'x' | 'y'\n\t\tlet min: 'minX' | 'minY'\n\t\tlet max: 'maxX' | 'maxY'\n\t\tlet dim: 'width' | 'height'\n\n\t\tif (operation === 'horizontal') {\n\t\t\tval = 'x'\n\t\t\tmin = 'minX'\n\t\t\tmax = 'maxX'\n\t\t\tdim = 'width'\n\t\t} else {\n\t\t\tval = 'y'\n\t\t\tmin = 'minY'\n\t\t\tmax = 'maxY'\n\t\t\tdim = 'height'\n\t\t}\n\n\t\tlet shapeGap: number\n\n\t\tif (gap === 0) {\n\t\t\tconst gaps: { gap: number; count: number }[] = []\n\n\t\t\tshapesToStack.sort((a, b) => pageBounds[a.id][min] - pageBounds[b.id][min])\n\n\t\t\t// Collect all of the gaps between shapes. We want to find\n\t\t\t// patterns (equal gaps between shapes) and use the most common\n\t\t\t// one as the gap for all of the shapes.\n\t\t\tfor (let i = 0; i < len - 1; i++) {\n\t\t\t\tconst shape = shapesToStack[i]\n\t\t\t\tconst nextShape = shapesToStack[i + 1]\n\n\t\t\t\tconst bounds = pageBounds[shape.id]\n\t\t\t\tconst nextBounds = pageBounds[nextShape.id]\n\n\t\t\t\tconst gap = nextBounds[min] - bounds[max]\n\n\t\t\t\tconst current = gaps.find((g) => g.gap === gap)\n\n\t\t\t\tif (current) {\n\t\t\t\t\tcurrent.count++\n\t\t\t\t} else {\n\t\t\t\t\tgaps.push({ gap, count: 1 })\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Which gap is the most common?\n\t\t\tlet maxCount = 0\n\t\t\tgaps.forEach((g) => {\n\t\t\t\tif (g.count > maxCount) {\n\t\t\t\t\tmaxCount = g.count\n\t\t\t\t\tshapeGap = g.gap\n\t\t\t\t}\n\t\t\t})\n\n\t\t\t// If there is no most-common gap, use the average gap.\n\t\t\tif (maxCount === 1) {\n\t\t\t\tshapeGap = Math.max(0, gaps.reduce((a, c) => a + c.gap * c.count, 0) / (len - 1))\n\t\t\t}\n\t\t} else {\n\t\t\t// If a gap was provided, then use that instead.\n\t\t\tshapeGap = gap\n\t\t}\n\n\t\tconst changes: TLShapePartial[] = []\n\n\t\tlet v = pageBounds[shapesToStack[0].id][max]\n\n\t\tshapesToStack.forEach((shape, i) => {\n\t\t\tif (i === 0) return\n\n\t\t\tconst delta = { x: 0, y: 0 }\n\t\t\tdelta[val] = v + shapeGap - pageBounds[shape.id][val]\n\n\t\t\tconst parent = this.getShapeParent(shape)\n\t\t\tconst localDelta = parent\n\t\t\t\t? Vec.Rot(delta, -this.getShapePageTransform(parent)!.decompose().rotation)\n\t\t\t\t: delta\n\n\t\t\tconst translateStartChanges = this.getShapeUtil(shape).onTranslateStart?.(shape)\n\n\t\t\tchanges.push(\n\t\t\t\ttranslateStartChanges\n\t\t\t\t\t? {\n\t\t\t\t\t\t\t...translateStartChanges,\n\t\t\t\t\t\t\t[val]: shape[val] + localDelta[val],\n\t\t\t\t\t\t}\n\t\t\t\t\t: {\n\t\t\t\t\t\t\tid: shape.id as any,\n\t\t\t\t\t\t\ttype: shape.type,\n\t\t\t\t\t\t\t[val]: shape[val] + localDelta[val],\n\t\t\t\t\t\t}\n\t\t\t)\n\n\t\t\tv += pageBounds[shape.id][dim] + shapeGap\n\t\t})\n\n\t\tthis.updateShapes(changes)\n\t\treturn this\n\t}\n\n\t/**\n\t * Pack shapes into a grid centered on their current position. Based on potpack (https://github.com/mapbox/potpack).\n\t *\n\t * @example\n\t * ```ts\n\t * editor.packShapes([box1, box2], 32)\n\t * editor.packShapes(editor.getSelectedShapeIds(), 32)\n\t * ```\n\t *\n\t *\n\t * @param shapes - The shapes (or shape ids) to pack.\n\t * @param gap - The padding to apply to the packed shapes. Defaults to 16.\n\t */\n\tpackShapes(shapes: TLShapeId[] | TLShape[], gap: number): this {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\n\t\tif (this.getInstanceState().isReadonly) return this\n\t\tif (ids.length < 2) return this\n\n\t\tconst shapesToPack = ids\n\t\t\t.map((id) => this.getShape(id)) // always fresh shapes\n\t\t\t.filter((shape): shape is TLShape => {\n\t\t\t\tif (!shape) return false\n\n\t\t\t\treturn this.getShapeUtil(shape).canBeLaidOut(shape)\n\t\t\t})\n\t\tconst shapePageBounds: Record = {}\n\t\tconst nextShapePageBounds: Record = {}\n\n\t\tlet shape: TLShape,\n\t\t\tbounds: Box,\n\t\t\tarea = 0\n\n\t\tfor (let i = 0; i < shapesToPack.length; i++) {\n\t\t\tshape = shapesToPack[i]\n\t\t\tbounds = this.getShapePageBounds(shape)!\n\t\t\tshapePageBounds[shape.id] = bounds\n\t\t\tnextShapePageBounds[shape.id] = bounds.clone()\n\t\t\tarea += bounds.width * bounds.height\n\t\t}\n\n\t\tconst commonBounds = Box.Common(compact(Object.values(shapePageBounds)))\n\n\t\tconst maxWidth = commonBounds.width\n\n\t\t// sort the shapes by height, descending\n\t\tshapesToPack.sort((a, b) => shapePageBounds[b.id].height - shapePageBounds[a.id].height)\n\n\t\t// Start with is (sort of) the square of the area\n\t\tconst startWidth = Math.max(Math.ceil(Math.sqrt(area / 0.95)), maxWidth)\n\n\t\t// first shape fills the width and is infinitely tall\n\t\tconst spaces: Box[] = [new Box(commonBounds.x, commonBounds.y, startWidth, Infinity)]\n\n\t\tlet width = 0\n\t\tlet height = 0\n\t\tlet space: Box\n\t\tlet last: Box\n\n\t\tfor (let i = 0; i < shapesToPack.length; i++) {\n\t\t\tshape = shapesToPack[i]\n\t\t\tbounds = nextShapePageBounds[shape.id]\n\n\t\t\t// starting at the back (smaller shapes)\n\t\t\tfor (let i = spaces.length - 1; i >= 0; i--) {\n\t\t\t\tspace = spaces[i]\n\n\t\t\t\t// find a space that is big enough to contain the shape\n\t\t\t\tif (bounds.width > space.width || bounds.height > space.height) continue\n\n\t\t\t\t// add the shape to its top-left corner\n\t\t\t\tbounds.x = space.x\n\t\t\t\tbounds.y = space.y\n\n\t\t\t\theight = Math.max(height, bounds.maxY)\n\t\t\t\twidth = Math.max(width, bounds.maxX)\n\n\t\t\t\tif (bounds.width === space.width && bounds.height === space.height) {\n\t\t\t\t\t// remove the space on a perfect fit\n\t\t\t\t\tlast = spaces.pop()!\n\t\t\t\t\tif (i < spaces.length) spaces[i] = last\n\t\t\t\t} else if (bounds.height === space.height) {\n\t\t\t\t\t// fit the shape into the space (width)\n\t\t\t\t\tspace.x += bounds.width + gap\n\t\t\t\t\tspace.width -= bounds.width + gap\n\t\t\t\t} else if (bounds.width === space.width) {\n\t\t\t\t\t// fit the shape into the space (height)\n\t\t\t\t\tspace.y += bounds.height + gap\n\t\t\t\t\tspace.height -= bounds.height + gap\n\t\t\t\t} else {\n\t\t\t\t\t// split the space into two spaces\n\t\t\t\t\tspaces.push(\n\t\t\t\t\t\tnew Box(\n\t\t\t\t\t\t\tspace.x + (bounds.width + gap),\n\t\t\t\t\t\t\tspace.y,\n\t\t\t\t\t\t\tspace.width - (bounds.width + gap),\n\t\t\t\t\t\t\tbounds.height\n\t\t\t\t\t\t)\n\t\t\t\t\t)\n\t\t\t\t\tspace.y += bounds.height + gap\n\t\t\t\t\tspace.height -= bounds.height + gap\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\n\t\tconst commonAfter = Box.Common(Object.values(nextShapePageBounds))\n\t\tconst centerDelta = Vec.Sub(commonBounds.center, commonAfter.center)\n\n\t\tlet nextBounds: Box\n\n\t\tconst changes: TLShapePartial[] = []\n\n\t\tfor (let i = 0; i < shapesToPack.length; i++) {\n\t\t\tshape = shapesToPack[i]\n\t\t\tbounds = shapePageBounds[shape.id]\n\t\t\tnextBounds = nextShapePageBounds[shape.id]\n\n\t\t\tconst delta = Vec.Sub(nextBounds.point, bounds.point).add(centerDelta)\n\t\t\tconst parentTransform = this.getShapeParentTransform(shape)\n\t\t\tif (parentTransform) delta.rot(-parentTransform.rotation())\n\n\t\t\tconst change: TLShapePartial = {\n\t\t\t\tid: shape.id,\n\t\t\t\ttype: shape.type,\n\t\t\t\tx: shape.x + delta.x,\n\t\t\t\ty: shape.y + delta.y,\n\t\t\t}\n\n\t\t\tconst translateStartChange = this.getShapeUtil(shape).onTranslateStart?.({\n\t\t\t\t...shape,\n\t\t\t\t...change,\n\t\t\t})\n\n\t\t\tif (translateStartChange) {\n\t\t\t\tchanges.push({ ...change, ...translateStartChange })\n\t\t\t} else {\n\t\t\t\tchanges.push(change)\n\t\t\t}\n\t\t}\n\n\t\tif (changes.length) {\n\t\t\tthis.updateShapes(changes)\n\t\t}\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Align shape positions.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.alignShapes([box1, box2], 'left')\n\t * editor.alignShapes(editor.getSelectedShapeIds(), 'left')\n\t * ```\n\t *\n\t * @param shapes - The shapes (or shape ids) to align.\n\t * @param operation - The align operation to apply.\n\t *\n\t * @public\n\t */\n\n\talignShapes(\n\t\tshapes: TLShapeId[] | TLShape[],\n\t\toperation: 'left' | 'center-horizontal' | 'right' | 'top' | 'center-vertical' | 'bottom'\n\t): this {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\n\t\tif (this.getInstanceState().isReadonly) return this\n\t\tif (ids.length < 2) return this\n\n\t\tconst shapesToAlign = compact(ids.map((id) => this.getShape(id))) // always fresh shapes\n\t\tconst shapePageBounds = Object.fromEntries(\n\t\t\tshapesToAlign.map((shape) => [shape.id, this.getShapePageBounds(shape)])\n\t\t)\n\t\tconst commonBounds = Box.Common(compact(Object.values(shapePageBounds)))\n\n\t\tconst changes: TLShapePartial[] = []\n\n\t\tshapesToAlign.forEach((shape) => {\n\t\t\tconst pageBounds = shapePageBounds[shape.id]\n\t\t\tif (!pageBounds) return\n\n\t\t\tconst delta = { x: 0, y: 0 }\n\n\t\t\tswitch (operation) {\n\t\t\t\tcase 'top': {\n\t\t\t\t\tdelta.y = commonBounds.minY - pageBounds.minY\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase 'center-vertical': {\n\t\t\t\t\tdelta.y = commonBounds.midY - pageBounds.minY - pageBounds.height / 2\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase 'bottom': {\n\t\t\t\t\tdelta.y = commonBounds.maxY - pageBounds.minY - pageBounds.height\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase 'left': {\n\t\t\t\t\tdelta.x = commonBounds.minX - pageBounds.minX\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase 'center-horizontal': {\n\t\t\t\t\tdelta.x = commonBounds.midX - pageBounds.minX - pageBounds.width / 2\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase 'right': {\n\t\t\t\t\tdelta.x = commonBounds.maxX - pageBounds.minX - pageBounds.width\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst parent = this.getShapeParent(shape)\n\t\t\tconst localDelta = parent\n\t\t\t\t? Vec.Rot(delta, -this.getShapePageTransform(parent)!.decompose().rotation)\n\t\t\t\t: delta\n\n\t\t\tchanges.push(this.getChangesToTranslateShape(shape, Vec.Add(shape, localDelta)))\n\t\t})\n\n\t\tthis.updateShapes(changes)\n\t\treturn this\n\t}\n\n\t/**\n\t * Distribute shape positions.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.distributeShapes([box1, box2], 'horizontal')\n\t * editor.distributeShapes(editor.getSelectedShapeIds(), 'horizontal')\n\t * ```\n\t *\n\t * @param shapes - The shapes (or shape ids) to distribute.\n\t * @param operation - Whether to distribute shapes horizontally or vertically.\n\t *\n\t * @public\n\t */\n\tdistributeShapes(shapes: TLShapeId[] | TLShape[], operation: 'horizontal' | 'vertical'): this {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\n\t\tif (this.getInstanceState().isReadonly) return this\n\t\tif (ids.length < 3) return this\n\n\t\tconst len = ids.length\n\t\tconst shapesToDistribute = compact(ids.map((id) => this.getShape(id))) // always fresh shapes\n\t\tconst pageBounds = Object.fromEntries(\n\t\t\tshapesToDistribute.map((shape) => [shape.id, this.getShapePageBounds(shape)!])\n\t\t)\n\n\t\tlet val: 'x' | 'y'\n\t\tlet min: 'minX' | 'minY'\n\t\tlet max: 'maxX' | 'maxY'\n\t\tlet mid: 'midX' | 'midY'\n\t\tlet dim: 'width' | 'height'\n\n\t\tif (operation === 'horizontal') {\n\t\t\tval = 'x'\n\t\t\tmin = 'minX'\n\t\t\tmax = 'maxX'\n\t\t\tmid = 'midX'\n\t\t\tdim = 'width'\n\t\t} else {\n\t\t\tval = 'y'\n\t\t\tmin = 'minY'\n\t\t\tmax = 'maxY'\n\t\t\tmid = 'midY'\n\t\t\tdim = 'height'\n\t\t}\n\t\tconst changes: TLShapePartial[] = []\n\n\t\t// Clustered\n\t\tconst first = shapesToDistribute.sort(\n\t\t\t(a, b) => pageBounds[a.id][min] - pageBounds[b.id][min]\n\t\t)[0]\n\t\tconst last = shapesToDistribute.sort((a, b) => pageBounds[b.id][max] - pageBounds[a.id][max])[0]\n\n\t\tconst midFirst = pageBounds[first.id][mid]\n\t\tconst step = (pageBounds[last.id][mid] - midFirst) / (len - 1)\n\t\tconst v = midFirst + step\n\n\t\tshapesToDistribute\n\t\t\t.filter((shape) => shape !== first && shape !== last)\n\t\t\t.sort((a, b) => pageBounds[a.id][mid] - pageBounds[b.id][mid])\n\t\t\t.forEach((shape, i) => {\n\t\t\t\tconst delta = { x: 0, y: 0 }\n\t\t\t\tdelta[val] = v + step * i - pageBounds[shape.id][dim] / 2 - pageBounds[shape.id][val]\n\n\t\t\t\tconst parent = this.getShapeParent(shape)\n\t\t\t\tconst localDelta = parent\n\t\t\t\t\t? Vec.Rot(delta, -this.getShapePageTransform(parent)!.rotation())\n\t\t\t\t\t: delta\n\n\t\t\t\tchanges.push(this.getChangesToTranslateShape(shape, Vec.Add(shape, localDelta)))\n\t\t\t})\n\n\t\tthis.updateShapes(changes)\n\t\treturn this\n\t}\n\n\t/**\n\t * Stretch shape sizes and positions to fill their common bounding box.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.stretchShapes([box1, box2], 'horizontal')\n\t * editor.stretchShapes(editor.getSelectedShapeIds(), 'horizontal')\n\t * ```\n\t *\n\t * @param shapes - The shapes (or shape ids) to stretch.\n\t * @param operation - Whether to stretch shapes horizontally or vertically.\n\t *\n\t * @public\n\t */\n\tstretchShapes(shapes: TLShapeId[] | TLShape[], operation: 'horizontal' | 'vertical'): this {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\n\t\tif (this.getInstanceState().isReadonly) return this\n\t\tif (ids.length < 2) return this\n\n\t\tconst shapesToStretch = compact(ids.map((id) => this.getShape(id))) // always fresh shapes\n\t\tconst shapeBounds = Object.fromEntries(ids.map((id) => [id, this.getShapeGeometry(id).bounds]))\n\t\tconst shapePageBounds = Object.fromEntries(ids.map((id) => [id, this.getShapePageBounds(id)!]))\n\t\tconst commonBounds = Box.Common(compact(Object.values(shapePageBounds)))\n\n\t\tswitch (operation) {\n\t\t\tcase 'vertical': {\n\t\t\t\tthis.run(() => {\n\t\t\t\t\tfor (const shape of shapesToStretch) {\n\t\t\t\t\t\tconst pageRotation = this.getShapePageTransform(shape)!.rotation()\n\t\t\t\t\t\tif (pageRotation % PI2) continue\n\t\t\t\t\t\tconst bounds = shapeBounds[shape.id]\n\t\t\t\t\t\tconst pageBounds = shapePageBounds[shape.id]\n\t\t\t\t\t\tconst localOffset = new Vec(0, commonBounds.minY - pageBounds.minY)\n\t\t\t\t\t\tconst parentTransform = this.getShapeParentTransform(shape)\n\t\t\t\t\t\tif (parentTransform) localOffset.rot(-parentTransform.rotation())\n\n\t\t\t\t\t\tconst { x, y } = Vec.Add(localOffset, shape)\n\t\t\t\t\t\tthis.updateShapes([{ id: shape.id, type: shape.type, x, y }])\n\t\t\t\t\t\tconst scale = new Vec(1, commonBounds.height / pageBounds.height)\n\t\t\t\t\t\tthis.resizeShape(shape.id, scale, {\n\t\t\t\t\t\t\tinitialBounds: bounds,\n\t\t\t\t\t\t\tscaleOrigin: new Vec(pageBounds.center.x, commonBounds.minY),\n\t\t\t\t\t\t\tisAspectRatioLocked: this.getShapeUtil(shape).isAspectRatioLocked(shape),\n\t\t\t\t\t\t\tscaleAxisRotation: 0,\n\t\t\t\t\t\t})\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'horizontal': {\n\t\t\t\tthis.run(() => {\n\t\t\t\t\tfor (const shape of shapesToStretch) {\n\t\t\t\t\t\tconst bounds = shapeBounds[shape.id]\n\t\t\t\t\t\tconst pageBounds = shapePageBounds[shape.id]\n\t\t\t\t\t\tconst pageRotation = this.getShapePageTransform(shape)!.rotation()\n\t\t\t\t\t\tif (pageRotation % PI2) continue\n\t\t\t\t\t\tconst localOffset = new Vec(commonBounds.minX - pageBounds.minX, 0)\n\t\t\t\t\t\tconst parentTransform = this.getShapeParentTransform(shape)\n\t\t\t\t\t\tif (parentTransform) localOffset.rot(-parentTransform.rotation())\n\n\t\t\t\t\t\tconst { x, y } = Vec.Add(localOffset, shape)\n\t\t\t\t\t\tthis.updateShapes([{ id: shape.id, type: shape.type, x, y }])\n\t\t\t\t\t\tconst scale = new Vec(commonBounds.width / pageBounds.width, 1)\n\t\t\t\t\t\tthis.resizeShape(shape.id, scale, {\n\t\t\t\t\t\t\tinitialBounds: bounds,\n\t\t\t\t\t\t\tscaleOrigin: new Vec(commonBounds.minX, pageBounds.center.y),\n\t\t\t\t\t\t\tisAspectRatioLocked: this.getShapeUtil(shape).isAspectRatioLocked(shape),\n\t\t\t\t\t\t\tscaleAxisRotation: 0,\n\t\t\t\t\t\t})\n\t\t\t\t\t}\n\t\t\t\t})\n\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Resize a shape.\n\t *\n\t * @param id - The id of the shape to resize.\n\t * @param scale - The scale factor to apply to the shape.\n\t * @param options - Additional options.\n\t *\n\t * @public\n\t */\n\tresizeShape(\n\t\tshape: TLShapeId | TLShape,\n\t\tscale: VecLike,\n\t\toptions: TLResizeShapeOptions = {}\n\t): this {\n\t\tconst id = typeof shape === 'string' ? shape : shape.id\n\t\tif (this.getInstanceState().isReadonly) return this\n\n\t\tif (!Number.isFinite(scale.x)) scale = new Vec(1, scale.y)\n\t\tif (!Number.isFinite(scale.y)) scale = new Vec(scale.x, 1)\n\n\t\tconst initialShape = options.initialShape ?? this.getShape(id)\n\t\tif (!initialShape) return this\n\n\t\tconst scaleOrigin = options.scaleOrigin ?? this.getShapePageBounds(id)?.center\n\t\tif (!scaleOrigin) return this\n\n\t\tconst pageTransform = options.initialPageTransform\n\t\t\t? Mat.Cast(options.initialPageTransform)\n\t\t\t: this.getShapePageTransform(id)\n\t\tif (!pageTransform) return this\n\n\t\tconst pageRotation = pageTransform.rotation()\n\n\t\tif (pageRotation == null) return this\n\n\t\tconst scaleAxisRotation = options.scaleAxisRotation ?? pageRotation\n\n\t\tconst initialBounds = options.initialBounds ?? this.getShapeGeometry(id).bounds\n\n\t\tif (!initialBounds) return this\n\n\t\tconst isAspectRatioLocked =\n\t\t\toptions.isAspectRatioLocked ??\n\t\t\tthis.getShapeUtil(initialShape).isAspectRatioLocked(initialShape)\n\n\t\tif (!areAnglesCompatible(pageRotation, scaleAxisRotation)) {\n\t\t\t// shape is awkwardly rotated, keep the aspect ratio locked and adopt the scale factor\n\t\t\t// from whichever axis is being scaled the least, to avoid the shape getting bigger\n\t\t\t// than the bounds of the selection\n\t\t\t// const minScale = Math.min(Math.abs(scale.x), Math.abs(scale.y))\n\t\t\treturn this._resizeUnalignedShape(id, scale, {\n\t\t\t\t...options,\n\t\t\t\tinitialBounds,\n\t\t\t\tscaleOrigin,\n\t\t\t\tscaleAxisRotation,\n\t\t\t\tinitialPageTransform: pageTransform,\n\t\t\t\tisAspectRatioLocked,\n\t\t\t\tinitialShape,\n\t\t\t})\n\t\t}\n\n\t\tconst util = this.getShapeUtil(initialShape)\n\n\t\tif (isAspectRatioLocked) {\n\t\t\tif (Math.abs(scale.x) > Math.abs(scale.y)) {\n\t\t\t\tscale = new Vec(scale.x, Math.sign(scale.y) * Math.abs(scale.x))\n\t\t\t} else {\n\t\t\t\tscale = new Vec(Math.sign(scale.x) * Math.abs(scale.y), scale.y)\n\t\t\t}\n\t\t}\n\n\t\tif (util.onResize && util.canResize(initialShape)) {\n\t\t\t// get the model changes from the shape util\n\t\t\tconst newPagePoint = this._scalePagePoint(\n\t\t\t\tMat.applyToPoint(pageTransform, new Vec(0, 0)),\n\t\t\t\tscaleOrigin,\n\t\t\t\tscale,\n\t\t\t\tscaleAxisRotation\n\t\t\t)\n\n\t\t\tconst newLocalPoint = this.getPointInParentSpace(initialShape.id, newPagePoint)\n\n\t\t\t// resize the shape's local bounding box\n\t\t\tconst myScale = new Vec(scale.x, scale.y)\n\t\t\t// the shape is aligned with the rest of the shapes in the selection, but may be\n\t\t\t// 90deg offset from the main rotation of the selection, in which case\n\t\t\t// we need to flip the width and height scale factors\n\t\t\tconst areWidthAndHeightAlignedWithCorrectAxis = approximately(\n\t\t\t\t(pageRotation - scaleAxisRotation) % Math.PI,\n\t\t\t\t0\n\t\t\t)\n\t\t\tmyScale.x = areWidthAndHeightAlignedWithCorrectAxis ? scale.x : scale.y\n\t\t\tmyScale.y = areWidthAndHeightAlignedWithCorrectAxis ? scale.y : scale.x\n\n\t\t\t// adjust initial model for situations where the parent has moved during the resize\n\t\t\t// e.g. groups\n\t\t\tconst initialPagePoint = Mat.applyToPoint(pageTransform, new Vec())\n\n\t\t\t// need to adjust the shape's x and y points in case the parent has moved since start of resizing\n\t\t\tconst { x, y } = this.getPointInParentSpace(initialShape.id, initialPagePoint)\n\n\t\t\tlet workingShape = initialShape\n\t\t\tif (!options.skipStartAndEndCallbacks) {\n\t\t\t\tworkingShape = applyPartialToRecordWithProps(\n\t\t\t\t\tinitialShape,\n\t\t\t\t\tutil.onResizeStart?.(initialShape) ?? undefined\n\t\t\t\t)\n\t\t\t}\n\n\t\t\tworkingShape = applyPartialToRecordWithProps(workingShape, {\n\t\t\t\tid,\n\t\t\t\ttype: initialShape.type as any,\n\t\t\t\tx: newLocalPoint.x,\n\t\t\t\ty: newLocalPoint.y,\n\t\t\t\t...util.onResize(\n\t\t\t\t\t{ ...initialShape, x, y },\n\t\t\t\t\t{\n\t\t\t\t\t\tnewPoint: newLocalPoint,\n\t\t\t\t\t\thandle: options.dragHandle ?? 'bottom_right',\n\t\t\t\t\t\t// don't set isSingle to true for children\n\t\t\t\t\t\tmode: options.mode ?? 'scale_shape',\n\t\t\t\t\t\tscaleX: myScale.x,\n\t\t\t\t\t\tscaleY: myScale.y,\n\t\t\t\t\t\tinitialBounds,\n\t\t\t\t\t\tinitialShape,\n\t\t\t\t\t}\n\t\t\t\t),\n\t\t\t})\n\n\t\t\tif (!options.skipStartAndEndCallbacks) {\n\t\t\t\tworkingShape = applyPartialToRecordWithProps(\n\t\t\t\t\tworkingShape,\n\t\t\t\t\tutil.onResizeEnd?.(initialShape, workingShape) ?? undefined\n\t\t\t\t)\n\t\t\t}\n\n\t\t\tthis.updateShapes([workingShape])\n\t\t} else {\n\t\t\tconst initialPageCenter = Mat.applyToPoint(pageTransform, initialBounds.center)\n\t\t\t// get the model changes from the shape util\n\t\t\tconst newPageCenter = this._scalePagePoint(\n\t\t\t\tinitialPageCenter,\n\t\t\t\tscaleOrigin,\n\t\t\t\tscale,\n\t\t\t\tscaleAxisRotation\n\t\t\t)\n\n\t\t\tconst initialPageCenterInParentSpace = this.getPointInParentSpace(\n\t\t\t\tinitialShape.id,\n\t\t\t\tinitialPageCenter\n\t\t\t)\n\t\t\tconst newPageCenterInParentSpace = this.getPointInParentSpace(initialShape.id, newPageCenter)\n\n\t\t\tconst delta = Vec.Sub(newPageCenterInParentSpace, initialPageCenterInParentSpace)\n\t\t\t// apply the changes to the model\n\t\t\tthis.updateShapes([\n\t\t\t\t{\n\t\t\t\t\tid,\n\t\t\t\t\ttype: initialShape.type as any,\n\t\t\t\t\tx: initialShape.x + delta.x,\n\t\t\t\t\ty: initialShape.y + delta.y,\n\t\t\t\t},\n\t\t\t])\n\t\t}\n\n\t\treturn this\n\t}\n\n\t/** @internal */\n\tprivate _scalePagePoint(\n\t\tpoint: VecLike,\n\t\tscaleOrigin: VecLike,\n\t\tscale: VecLike,\n\t\tscaleAxisRotation: number\n\t) {\n\t\tconst relativePoint = Vec.RotWith(point, scaleOrigin, -scaleAxisRotation).sub(scaleOrigin)\n\n\t\t// calculate the new point position relative to the scale origin\n\t\tconst newRelativePagePoint = Vec.MulV(relativePoint, scale)\n\n\t\t// and rotate it back to page coords to get the new page point of the resized shape\n\t\tconst destination = Vec.Add(newRelativePagePoint, scaleOrigin).rotWith(\n\t\t\tscaleOrigin,\n\t\t\tscaleAxisRotation\n\t\t)\n\n\t\treturn destination\n\t}\n\n\t/** @internal */\n\tprivate _resizeUnalignedShape(\n\t\tid: TLShapeId,\n\t\tscale: VecLike,\n\t\toptions: {\n\t\t\tinitialBounds: Box\n\t\t\tscaleOrigin: VecLike\n\t\t\tscaleAxisRotation: number\n\t\t\tinitialShape: TLShape\n\t\t\tisAspectRatioLocked: boolean\n\t\t\tinitialPageTransform: MatLike\n\t\t}\n\t) {\n\t\tconst { type } = options.initialShape\n\t\t// If a shape is not aligned with the scale axis we need to treat it differently to avoid skewing.\n\t\t// Instead of skewing we normalize the scale aspect ratio (i.e. keep the same scale magnitude in both axes)\n\t\t// and then after applying the scale to the shape we also rotate it if required and translate it so that it's center\n\t\t// point ends up in the right place.\n\n\t\tconst shapeScale = new Vec(scale.x, scale.y)\n\n\t\t// // make sure we are constraining aspect ratio, and using the smallest scale axis to avoid shapes getting bigger\n\t\t// // than the selection bounding box\n\t\tif (Math.abs(scale.x) > Math.abs(scale.y)) {\n\t\t\tshapeScale.x = Math.sign(scale.x) * Math.abs(scale.y)\n\t\t} else {\n\t\t\tshapeScale.y = Math.sign(scale.y) * Math.abs(scale.x)\n\t\t}\n\n\t\t// first we can scale the shape about its center point\n\t\tthis.resizeShape(id, shapeScale, {\n\t\t\tinitialShape: options.initialShape,\n\t\t\tinitialBounds: options.initialBounds,\n\t\t\tisAspectRatioLocked: options.isAspectRatioLocked,\n\t\t})\n\n\t\t// then if the shape is flipped in one axis only, we need to apply an extra rotation\n\t\t// to make sure the shape is mirrored correctly\n\t\tif (Math.sign(scale.x) * Math.sign(scale.y) < 0) {\n\t\t\tlet { rotation } = Mat.Decompose(options.initialPageTransform)\n\t\t\trotation -= 2 * rotation\n\t\t\tthis.updateShapes([{ id, type, rotation }])\n\t\t}\n\n\t\t// Next we need to translate the shape so that it's center point ends up in the right place.\n\t\t// To do that we first need to calculate the center point of the shape in the current page space before the scale was applied.\n\t\tconst preScaleShapePageCenter = Mat.applyToPoint(\n\t\t\toptions.initialPageTransform,\n\t\t\toptions.initialBounds.center\n\t\t)\n\n\t\t// And now we scale the center point by the original scale factor\n\t\tconst postScaleShapePageCenter = this._scalePagePoint(\n\t\t\tpreScaleShapePageCenter,\n\t\t\toptions.scaleOrigin,\n\t\t\tscale,\n\t\t\toptions.scaleAxisRotation\n\t\t)\n\n\t\t// now calculate how far away the shape is from where it needs to be\n\t\tconst pageBounds = this.getShapePageBounds(id)!\n\t\tconst pageTransform = this.getShapePageTransform(id)!\n\t\tconst currentPageCenter = pageBounds.center\n\t\tconst shapePageTransformOrigin = pageTransform.point()\n\t\tif (!currentPageCenter || !shapePageTransformOrigin) return this\n\t\tconst pageDelta = Vec.Sub(postScaleShapePageCenter, currentPageCenter)\n\n\t\t// and finally figure out what the shape's new position should be\n\t\tconst postScaleShapePagePoint = Vec.Add(shapePageTransformOrigin, pageDelta)\n\t\tconst { x, y } = this.getPointInParentSpace(id, postScaleShapePagePoint)\n\n\t\tthis.updateShapes([{ id, type, x, y }])\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Get the initial meta value for a shape.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getInitialMetaForShape = (shape) => {\n\t * if (shape.type === 'note') {\n\t * return { createdBy: myCurrentUser.id }\n\t * }\n\t * }\n\t * ```\n\t *\n\t * @param shape - The shape to get the initial meta for.\n\t *\n\t * @public\n\t */\n\tgetInitialMetaForShape(_shape: TLShape): JsonObject {\n\t\treturn {}\n\t}\n\n\t/**\n\t * Create a single shape.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.createShape(myShape)\n\t * editor.createShape({ id: 'box1', type: 'text', props: { text: \"ok\" } })\n\t * ```\n\t *\n\t * @param shape - The shape (or shape partial) to create.\n\t *\n\t * @public\n\t */\n\tcreateShape(shape: OptionalKeys, 'id'>): this {\n\t\tthis.createShapes([shape])\n\t\treturn this\n\t}\n\n\t/**\n\t * Create shapes.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.createShapes([myShape])\n\t * editor.createShapes([{ id: 'box1', type: 'text', props: { text: \"ok\" } }])\n\t * ```\n\t *\n\t * @param shapes - The shapes (or shape partials) to create.\n\t * @param select - Whether to select the created shapes. Defaults to false.\n\t *\n\t * @public\n\t */\n\tcreateShapes(shapes: OptionalKeys, 'id'>[]): this {\n\t\tif (!Array.isArray(shapes)) {\n\t\t\tthrow Error('Editor.createShapes: must provide an array of shapes or shape partials')\n\t\t}\n\t\tif (this.getInstanceState().isReadonly) return this\n\t\tif (shapes.length <= 0) return this\n\n\t\tconst currentPageShapeIds = this.getCurrentPageShapeIds()\n\n\t\tconst maxShapesReached =\n\t\t\tshapes.length + currentPageShapeIds.size > this.options.maxShapesPerPage\n\n\t\tif (maxShapesReached) {\n\t\t\t// can't create more shapes than fit on the page\n\t\t\talertMaxShapes(this)\n\t\t\treturn this\n\t\t}\n\n\t\tconst focusedGroupId = this.getFocusedGroupId()\n\n\t\tthis.run(() => {\n\t\t\t// 1. Parents\n\n\t\t\t// Make sure that each partial will become the child of either the\n\t\t\t// page or another shape that exists (or that will exist) in this page.\n\n\t\t\t// find last parent id\n\t\t\tconst currentPageShapesSorted = this.getCurrentPageShapesSorted()\n\n\t\t\tconst partials = shapes.map((partial) => {\n\t\t\t\tif (!partial.id) {\n\t\t\t\t\tpartial = { id: createShapeId(), ...partial }\n\t\t\t\t}\n\n\t\t\t\t// If the partial does not provide the parentId OR if the provided\n\t\t\t\t// parentId is NOT in the store AND NOT among the other shapes being\n\t\t\t\t// created, then we need to find a parent for the shape. This can be\n\t\t\t\t// another shape that exists under that point and which can receive\n\t\t\t\t// children of the creating shape's type, or else the page itself.\n\t\t\t\tif (\n\t\t\t\t\t!partial.parentId ||\n\t\t\t\t\t!(this.store.has(partial.parentId) || shapes.some((p) => p.id === partial.parentId))\n\t\t\t\t) {\n\t\t\t\t\tlet parentId: TLParentId = this.getFocusedGroupId()\n\n\t\t\t\t\tfor (let i = currentPageShapesSorted.length - 1; i >= 0; i--) {\n\t\t\t\t\t\tconst parent = currentPageShapesSorted[i]\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t!this.isShapeHidden(parent) &&\n\t\t\t\t\t\t\tthis.getShapeUtil(parent).canReceiveNewChildrenOfType(parent, partial.type) &&\n\t\t\t\t\t\t\tthis.isPointInShape(\n\t\t\t\t\t\t\t\tparent,\n\t\t\t\t\t\t\t\t// If no parent is provided, then we can treat the\n\t\t\t\t\t\t\t\t// shape's provided x/y as being in the page's space.\n\t\t\t\t\t\t\t\t{ x: partial.x ?? 0, y: partial.y ?? 0 },\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tmargin: 0,\n\t\t\t\t\t\t\t\t\thitInside: true,\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\tparentId = parent.id\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tconst prevParentId = partial.parentId\n\n\t\t\t\t\t// a shape cannot be it's own parent. This was a rare issue with frames/groups in the syncFuzz tests.\n\t\t\t\t\tif (parentId === partial.id) {\n\t\t\t\t\t\tparentId = focusedGroupId\n\t\t\t\t\t}\n\n\t\t\t\t\t// If the parentid has changed...\n\t\t\t\t\tif (parentId !== prevParentId) {\n\t\t\t\t\t\tpartial = { ...partial }\n\n\t\t\t\t\t\tpartial.parentId = parentId\n\n\t\t\t\t\t\t// If the parent is a shape (rather than a page) then insert the\n\t\t\t\t\t\t// shapes into the shape's children. Adjust the point and page rotation to be\n\t\t\t\t\t\t// preserved relative to the parent.\n\t\t\t\t\t\tif (isShapeId(parentId)) {\n\t\t\t\t\t\t\tconst point = this.getPointInShapeSpace(this.getShape(parentId)!, {\n\t\t\t\t\t\t\t\tx: partial.x ?? 0,\n\t\t\t\t\t\t\t\ty: partial.y ?? 0,\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\tpartial.x = point.x\n\t\t\t\t\t\t\tpartial.y = point.y\n\t\t\t\t\t\t\tpartial.rotation =\n\t\t\t\t\t\t\t\t-this.getShapePageTransform(parentId)!.rotation() + (partial.rotation ?? 0)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn partial\n\t\t\t})\n\n\t\t\t// 2. Indices\n\n\t\t\t// Get the highest index among the parents of each of the\n\t\t\t// the shapes being created; we'll increment from there.\n\n\t\t\tconst parentIndices = new Map()\n\n\t\t\tconst shapeRecordsToCreate: TLShape[] = []\n\n\t\t\tconst { opacityForNextShape } = this.getInstanceState()\n\n\t\t\tfor (const partial of partials) {\n\t\t\t\tconst util = this.getShapeUtil(partial as TLShapePartial)\n\n\t\t\t\t// If an index is not explicitly provided, then add the\n\t\t\t\t// shapes to the top of their parents' children; using the\n\t\t\t\t// value in parentsMappedToIndex, get the index above, use it,\n\t\t\t\t// and set it back to parentsMappedToIndex for next time.\n\t\t\t\tlet index = partial.index\n\n\t\t\t\tif (!index) {\n\t\t\t\t\t// Hello bug-seeker: have you just created a frame and then a shape\n\t\t\t\t\t// and found that the shape is automatically the child of the frame?\n\t\t\t\t\t// this is the reason why! It would be harder to have each shape specify\n\t\t\t\t\t// the frame as the parent when creating a shape inside of a frame, so\n\t\t\t\t\t// we do it here.\n\t\t\t\t\tconst parentId = partial.parentId ?? focusedGroupId\n\n\t\t\t\t\tif (!parentIndices.has(parentId)) {\n\t\t\t\t\t\tparentIndices.set(parentId, this.getHighestIndexForParent(parentId))\n\t\t\t\t\t}\n\t\t\t\t\tindex = parentIndices.get(parentId)!\n\t\t\t\t\tparentIndices.set(parentId, getIndexAbove(index))\n\t\t\t\t}\n\n\t\t\t\t// The initial props starts as the shape utility's default props\n\t\t\t\tconst initialProps = util.getDefaultProps()\n\n\t\t\t\t// We then look up each key in the tab state's styles; and if it's there,\n\t\t\t\t// we use the value from the tab state's styles instead of the default.\n\t\t\t\tfor (const [style, propKey] of this.styleProps[partial.type]) {\n\t\t\t\t\t;(initialProps as any)[propKey] = this.getStyleForNextShape(style)\n\t\t\t\t}\n\n\t\t\t\t// When we create the shape, take in the partial (the props coming into the\n\t\t\t\t// function) and merge it with the default props.\n\t\t\t\tlet shapeRecordToCreate = (\n\t\t\t\t\tthis.store.schema.types.shape as RecordType<\n\t\t\t\t\t\tTLShape,\n\t\t\t\t\t\t'type' | 'props' | 'index' | 'parentId'\n\t\t\t\t\t>\n\t\t\t\t).create({\n\t\t\t\t\t...partial,\n\t\t\t\t\tindex,\n\t\t\t\t\topacity: partial.opacity ?? opacityForNextShape,\n\t\t\t\t\tparentId: partial.parentId ?? focusedGroupId,\n\t\t\t\t\tprops: 'props' in partial ? { ...initialProps, ...partial.props } : initialProps,\n\t\t\t\t})\n\n\t\t\t\tif (shapeRecordToCreate.index === undefined) {\n\t\t\t\t\tthrow Error('no index!')\n\t\t\t\t}\n\n\t\t\t\tconst next = this.getShapeUtil(shapeRecordToCreate).onBeforeCreate?.(shapeRecordToCreate)\n\n\t\t\t\tif (next) {\n\t\t\t\t\tshapeRecordToCreate = next\n\t\t\t\t}\n\n\t\t\t\tshapeRecordsToCreate.push(shapeRecordToCreate)\n\t\t\t}\n\n\t\t\t// Add meta properties, if any, to the shapes\n\t\t\tshapeRecordsToCreate.forEach((shape) => {\n\t\t\t\tshape.meta = {\n\t\t\t\t\t...this.getInitialMetaForShape(shape),\n\t\t\t\t\t...shape.meta,\n\t\t\t\t}\n\t\t\t})\n\n\t\t\tthis.store.put(shapeRecordsToCreate)\n\t\t})\n\n\t\treturn this\n\t}\n\n\tprivate animatingShapes = new Map()\n\n\t/**\n\t * Animate a shape.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.animateShape({ id: 'box1', type: 'box', x: 100, y: 100 })\n\t * editor.animateShape({ id: 'box1', type: 'box', x: 100, y: 100 }, { animation: { duration: 100, ease: t => t*t } })\n\t * ```\n\t *\n\t * @param partial - The shape partial to update.\n\t * @param options - The animation's options.\n\t *\n\t * @public\n\t */\n\tanimateShape(\n\t\tpartial: TLShapePartial | null | undefined,\n\t\topts = { animation: DEFAULT_ANIMATION_OPTIONS } as TLCameraMoveOptions\n\t): this {\n\t\treturn this.animateShapes([partial], opts)\n\t}\n\n\t/**\n\t * Animate shapes.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.animateShapes([{ id: 'box1', type: 'box', x: 100, y: 100 }])\n\t * editor.animateShapes([{ id: 'box1', type: 'box', x: 100, y: 100 }], { animation: { duration: 100, ease: t => t*t } })\n\t * ```\n\t *\n\t * @param partials - The shape partials to update.\n\t * @param options - The animation's options.\n\t *\n\t * @public\n\t */\n\tanimateShapes(\n\t\tpartials: (TLShapePartial | null | undefined)[],\n\t\topts = { animation: DEFAULT_ANIMATION_OPTIONS } as TLCameraMoveOptions\n\t): this {\n\t\tif (!opts.animation) return this\n\t\tconst { duration = 500, easing = EASINGS.linear } = opts.animation\n\n\t\tconst animationId = uniqueId()\n\n\t\tlet remaining = duration\n\t\tlet t: number\n\n\t\tinterface ShapeAnimation {\n\t\t\tstart: TLShape\n\t\t\tend: TLShape\n\t\t}\n\n\t\tconst animations: ShapeAnimation[] = []\n\n\t\tlet partial: TLShapePartial | null | undefined, result: ShapeAnimation\n\t\tfor (let i = 0, n = partials.length; i < n; i++) {\n\t\t\tpartial = partials[i]\n\t\t\tif (!partial) continue\n\n\t\t\tconst shape = this.getShape(partial.id)!\n\t\t\tif (!shape) continue\n\n\t\t\tresult = {\n\t\t\t\tstart: structuredClone(shape),\n\t\t\t\tend: applyPartialToRecordWithProps(structuredClone(shape), partial),\n\t\t\t}\n\n\t\t\tanimations.push(result)\n\t\t\tthis.animatingShapes.set(shape.id, animationId)\n\t\t}\n\n\t\tconst handleTick = (elapsed: number) => {\n\t\t\tremaining -= elapsed\n\n\t\t\tif (remaining < 0) {\n\t\t\t\tconst { animatingShapes } = this\n\t\t\t\tconst partialsToUpdate = partials.filter(\n\t\t\t\t\t(p) => p && animatingShapes.get(p.id) === animationId\n\t\t\t\t)\n\t\t\t\tif (partialsToUpdate.length) {\n\t\t\t\t\t// the regular update shapes also removes the shape from\n\t\t\t\t\t// the animating shapes set\n\t\t\t\t\tthis.updateShapes(partialsToUpdate)\n\t\t\t\t}\n\n\t\t\t\tthis.off('tick', handleTick)\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tt = easing(1 - remaining / duration)\n\n\t\t\tconst { animatingShapes } = this\n\n\t\t\tconst updates: TLShapePartial[] = []\n\n\t\t\tlet animationIdForShape: string | undefined\n\t\t\tfor (let i = 0, n = animations.length; i < n; i++) {\n\t\t\t\tconst { start, end } = animations[i]\n\t\t\t\t// Is the animation for this shape still active?\n\t\t\t\tanimationIdForShape = animatingShapes.get(start.id)\n\t\t\t\tif (animationIdForShape !== animationId) continue\n\n\t\t\t\tupdates.push({\n\t\t\t\t\t...end,\n\t\t\t\t\tx: start.x + (end.x - start.x) * t,\n\t\t\t\t\ty: start.y + (end.y - start.y) * t,\n\t\t\t\t\topacity: start.opacity + (end.opacity - start.opacity) * t,\n\t\t\t\t\trotation: start.rotation + (end.rotation - start.rotation) * t,\n\t\t\t\t\tprops: this.getShapeUtil(end).getInterpolatedProps?.(start, end, t) ?? end.props,\n\t\t\t\t})\n\t\t\t}\n\n\t\t\t// The _updateShapes method does NOT remove the\n\t\t\t// shapes from the animated shapes set\n\t\t\tthis._updateShapes(updates)\n\t\t}\n\n\t\tthis.on('tick', handleTick)\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Create a group containing the provided shapes.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.groupShapes([myShape, myOtherShape])\n\t * editor.groupShapes([myShape, myOtherShape], { groupId: myGroupId, select: false })\n\t * ```\n\t *\n\t * @param shapes - The shapes (or shape ids) to group. Defaults to the selected shapes.\n\t * @param options - An options object.\n\t *\n\t * @public\n\t */\n\tgroupShapes(shapes: TLShape[], options?: Partial<{ groupId: TLShapeId; select: boolean }>): this\n\tgroupShapes(ids: TLShapeId[], options?: Partial<{ groupId: TLShapeId; select: boolean }>): this\n\tgroupShapes(\n\t\tshapes: TLShapeId[] | TLShape[],\n\t\toptions = {} as Partial<{ groupId: TLShapeId; select: boolean }>\n\t): this {\n\t\tconst { groupId = createShapeId(), select = true } = options\n\n\t\tif (!Array.isArray(shapes)) {\n\t\t\tthrow Error('Editor.groupShapes: must provide an array of shapes or shape ids')\n\t\t}\n\t\tif (this.getInstanceState().isReadonly) return this\n\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes.map((s) => (s as TLShape).id) as TLShapeId[])\n\n\t\tif (ids.length <= 1) return this\n\n\t\tconst shapesToGroup = compact(\n\t\t\t(this._shouldIgnoreShapeLock ? ids : this._getUnlockedShapeIds(ids)).map((id) =>\n\t\t\t\tthis.getShape(id)\n\t\t\t)\n\t\t)\n\t\tconst sortedShapeIds = shapesToGroup.sort(sortByIndex).map((s) => s.id)\n\t\tconst pageBounds = Box.Common(compact(shapesToGroup.map((id) => this.getShapePageBounds(id))))\n\n\t\tconst { x, y } = pageBounds.point\n\n\t\tconst parentId = this.findCommonAncestor(shapesToGroup) ?? this.getCurrentPageId()\n\n\t\t// Only group when the select tool is active\n\t\tif (this.getCurrentToolId() !== 'select') return this\n\n\t\t// If not already in idle, cancel the current interaction (get back to idle)\n\t\tif (!this.isIn('select.idle')) {\n\t\t\tthis.cancel()\n\t\t}\n\n\t\t// Find all the shapes that have the same parentId, and use the highest index.\n\t\tconst shapesWithRootParent = shapesToGroup\n\t\t\t.filter((shape) => shape.parentId === parentId)\n\t\t\t.sort(sortByIndex)\n\n\t\tconst highestIndex = shapesWithRootParent[shapesWithRootParent.length - 1]?.index\n\n\t\tthis.run(() => {\n\t\t\tthis.createShapes([\n\t\t\t\t{\n\t\t\t\t\tid: groupId,\n\t\t\t\t\ttype: 'group',\n\t\t\t\t\tparentId,\n\t\t\t\t\tindex: highestIndex,\n\t\t\t\t\tx,\n\t\t\t\t\ty,\n\t\t\t\t\topacity: 1,\n\t\t\t\t\tprops: {},\n\t\t\t\t},\n\t\t\t])\n\t\t\tthis.reparentShapes(sortedShapeIds, groupId)\n\t\t\tif (select) {\n\t\t\t\t// the select option determines whether the grouped shapes' children are selected\n\t\t\t\tthis.select(groupId)\n\t\t\t}\n\t\t})\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Ungroup some shapes.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.ungroupShapes([myGroup, myOtherGroup])\n\t * editor.ungroupShapes([myGroup], { select: false })\n\t * ```\n\t *\n\t * @param shapes - The group shapes (or shape ids) to ungroup.\n\t * @param options - An options object.\n\t *\n\t * @public\n\t */\n\tungroupShapes(ids: TLShapeId[], options?: Partial<{ select: boolean }>): this\n\tungroupShapes(shapes: TLShape[], options?: Partial<{ select: boolean }>): this\n\tungroupShapes(shapes: TLShapeId[] | TLShape[], options = {} as Partial<{ select: boolean }>) {\n\t\tif (this.getInstanceState().isReadonly) return this\n\n\t\tconst { select = true } = options\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\n\t\tconst shapesToUngroup = compact(\n\t\t\t(this._shouldIgnoreShapeLock ? ids : this._getUnlockedShapeIds(ids)).map((id) =>\n\t\t\t\tthis.getShape(id)\n\t\t\t)\n\t\t)\n\n\t\tif (shapesToUngroup.length === 0) return this\n\n\t\t// todo: the editor shouldn't know about the select tool, move to group / ungroup actions\n\t\tif (this.getCurrentToolId() !== 'select') return this\n\t\tif (!this.isIn('select.idle')) {\n\t\t\tthis.cancel()\n\t\t}\n\n\t\t// The ids of the selected shapes after ungrouping;\n\t\t// these include all of the grouped shapes children,\n\t\t// plus any shapes that were selected apart from the groups.\n\t\tconst idsToSelect = new Set()\n\n\t\t// Get all groups in the selection\n\t\tconst groups: TLGroupShape[] = []\n\n\t\tshapesToUngroup.forEach((shape) => {\n\t\t\tif (this.isShapeOfType(shape, 'group')) {\n\t\t\t\tgroups.push(shape)\n\t\t\t} else {\n\t\t\t\tidsToSelect.add(shape.id)\n\t\t\t}\n\t\t})\n\n\t\tif (groups.length === 0) return this\n\n\t\tthis.run(() => {\n\t\t\tlet group: TLGroupShape\n\n\t\t\tfor (let i = 0, n = groups.length; i < n; i++) {\n\t\t\t\tgroup = groups[i]\n\t\t\t\tconst childIds = this.getSortedChildIdsForParent(group.id)\n\n\t\t\t\tfor (let j = 0, n = childIds.length; j < n; j++) {\n\t\t\t\t\tidsToSelect.add(childIds[j])\n\t\t\t\t}\n\n\t\t\t\tthis.reparentShapes(childIds, group.parentId, group.index)\n\t\t\t}\n\n\t\t\tthis.deleteShapes(groups.map((group) => group.id))\n\n\t\t\tif (select) {\n\t\t\t\t// the select option determines whether the ungrouped shapes' children are selected\n\t\t\t\tthis.select(...idsToSelect)\n\t\t\t}\n\t\t})\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Update a shape using a partial of the shape.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.updateShape({ id: 'box1', type: 'geo', props: { w: 100, h: 100 } })\n\t * ```\n\t *\n\t * @param partial - The shape partial to update.\n\t *\n\t * @public\n\t */\n\tupdateShape(partial: TLShapePartial | null | undefined) {\n\t\tthis.updateShapes([partial])\n\t\treturn this\n\t}\n\n\t/**\n\t * Update shapes using partials of each shape.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.updateShapes([{ id: 'box1', type: 'geo', props: { w: 100, h: 100 } }])\n\t * ```\n\t *\n\t * @param partials - The shape partials to update.\n\t *\n\t * @public\n\t */\n\tupdateShapes(partials: (TLShapePartial | null | undefined)[]) {\n\t\tconst compactedPartials: TLShapePartial[] = Array(partials.length)\n\n\t\tfor (let i = 0, n = partials.length; i < n; i++) {\n\t\t\tconst partial = partials[i]\n\t\t\tif (!partial) continue\n\t\t\t// Get the current shape referenced by the partial\n\t\t\tconst shape = this.getShape(partial.id)\n\t\t\tif (!shape) continue\n\n\t\t\t// If we're \"forcing\" the update, then we'll update the shape\n\t\t\t// regardless of whether it / its ancestor is locked\n\t\t\tif (!this._shouldIgnoreShapeLock) {\n\t\t\t\tif (shape.isLocked) {\n\t\t\t\t\t// If the shape itself is locked (even if one of its ancestors is\n\t\t\t\t\t// also locked) then only allow an update that unlocks the shape.\n\t\t\t\t\tif (!(Object.hasOwn(partial, 'isLocked') && !partial.isLocked)) {\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\t\t\t\t} else if (this.isShapeOrAncestorLocked(shape)) {\n\t\t\t\t\t// If the shape itself is unlocked, and any of the shape's\n\t\t\t\t\t// ancestors are locked then we'll skip the update\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Remove any animating shapes from the list of partials\n\t\t\tthis.animatingShapes.delete(partial.id)\n\n\t\t\tcompactedPartials.push(partial)\n\t\t}\n\n\t\tthis._updateShapes(compactedPartials)\n\t\treturn this\n\t}\n\n\t/** @internal */\n\t_updateShapes(_partials: (TLShapePartial | null | undefined)[]) {\n\t\tif (this.getInstanceState().isReadonly) return\n\n\t\tthis.run(() => {\n\t\t\tconst updates = []\n\n\t\t\tlet shape: TLShape | undefined\n\t\t\tlet updated: TLShape\n\n\t\t\tfor (let i = 0, n = _partials.length; i < n; i++) {\n\t\t\t\tconst partial = _partials[i]\n\t\t\t\t// Skip nullish partials (sometimes created by map fns returning undefined)\n\t\t\t\tif (!partial) continue\n\n\t\t\t\t// Get the current shape referenced by the partial\n\t\t\t\t// If there is no current shape, we'll skip this update\n\t\t\t\tshape = this.getShape(partial.id)\n\t\t\t\tif (!shape) continue\n\n\t\t\t\t// Get the updated version of the shape\n\t\t\t\t// If the update had no effect, we'll skip this update\n\t\t\t\tupdated = applyPartialToRecordWithProps(shape, partial)\n\t\t\t\tif (updated === shape) continue\n\n\t\t\t\t//if any shape has an onBeforeUpdate handler, call it and, if the handler returns a\n\t\t\t\t// new shape, replace the old shape with the new one. This is used for example when\n\t\t\t\t// repositioning a text shape based on its new text content.\n\t\t\t\tupdated = this.getShapeUtil(shape).onBeforeUpdate?.(shape, updated) ?? updated\n\n\t\t\t\tupdates.push(updated)\n\t\t\t}\n\n\t\t\tthis.store.put(updates)\n\t\t})\n\t}\n\n\t/** @internal */\n\tprivate _getUnlockedShapeIds(ids: TLShapeId[]): TLShapeId[] {\n\t\treturn ids.filter((id) => !this.getShape(id)?.isLocked)\n\t}\n\n\t/**\n\t * Delete shapes.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.deleteShapes(['box1', 'box2'])\n\t * ```\n\t *\n\t * @param ids - The ids of the shapes to delete.\n\t *\n\t * @public\n\t */\n\tdeleteShapes(ids: TLShapeId[]): this\n\tdeleteShapes(shapes: TLShape[]): this\n\tdeleteShapes(_ids: TLShapeId[] | TLShape[]): this {\n\t\tif (this.getInstanceState().isReadonly) return this\n\n\t\tif (!Array.isArray(_ids)) {\n\t\t\tthrow Error('Editor.deleteShapes: must provide an array of shapes or shapeIds')\n\t\t}\n\n\t\tconst shapeIds =\n\t\t\ttypeof _ids[0] === 'string' ? (_ids as TLShapeId[]) : (_ids as TLShape[]).map((s) => s.id)\n\n\t\t// Normally we don't want to delete locked shapes, but if the force option is set, we'll delete them anyway\n\t\tconst shapeIdsToDelete = this._shouldIgnoreShapeLock\n\t\t\t? shapeIds\n\t\t\t: this._getUnlockedShapeIds(shapeIds)\n\n\t\tif (shapeIdsToDelete.length === 0) return this\n\n\t\t// We also need to delete these shapes' descendants\n\t\tconst allShapeIdsToDelete = new Set(shapeIdsToDelete)\n\n\t\tfor (const id of shapeIdsToDelete) {\n\t\t\tthis.visitDescendants(id, (childId) => {\n\t\t\t\tallShapeIdsToDelete.add(childId)\n\t\t\t})\n\t\t}\n\n\t\treturn this.run(() => this.store.remove([...allShapeIdsToDelete]))\n\t}\n\n\t/**\n\t * Delete a shape.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.deleteShape(shape.id)\n\t * ```\n\t *\n\t * @param id - The id of the shape to delete.\n\t *\n\t * @public\n\t */\n\tdeleteShape(id: TLShapeId): this\n\tdeleteShape(shape: TLShape): this\n\tdeleteShape(_id: TLShapeId | TLShape) {\n\t\tthis.deleteShapes([typeof _id === 'string' ? _id : _id.id])\n\t\treturn this\n\t}\n\n\t/* --------------------- Styles --------------------- */\n\n\t/**\n\t * Get all the current styles among the users selected shapes\n\t *\n\t * @internal\n\t */\n\tprivate _extractSharedStyles(shape: TLShape, sharedStyleMap: SharedStyleMap) {\n\t\tif (this.isShapeOfType(shape, 'group')) {\n\t\t\t// For groups, ignore the styles of the group shape and instead include the styles of the\n\t\t\t// group's children. These are the shapes that would have their styles changed if the\n\t\t\t// user called `setStyle` on the current selection.\n\t\t\tconst childIds = this._parentIdsToChildIds.get()[shape.id]\n\t\t\tif (!childIds) return\n\n\t\t\tfor (let i = 0, n = childIds.length; i < n; i++) {\n\t\t\t\tthis._extractSharedStyles(this.getShape(childIds[i])!, sharedStyleMap)\n\t\t\t}\n\t\t} else {\n\t\t\tfor (const [style, propKey] of this.styleProps[shape.type]) {\n\t\t\t\tsharedStyleMap.applyValue(style, getOwnProperty(shape.props, propKey))\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * A derived map containing all current styles among the user's selected shapes.\n\t *\n\t * @internal\n\t */\n\t@computed\n\tprivate _getSelectionSharedStyles(): ReadonlySharedStyleMap {\n\t\tconst selectedShapes = this.getSelectedShapes()\n\n\t\tconst sharedStyles = new SharedStyleMap()\n\t\tfor (const selectedShape of selectedShapes) {\n\t\t\tthis._extractSharedStyles(selectedShape, sharedStyles)\n\t\t}\n\n\t\treturn sharedStyles\n\t}\n\n\t/**\n\t * Get the style for the next shape.\n\t *\n\t * @example\n\t * ```ts\n\t * const color = editor.getStyleForNextShape(DefaultColorStyle)\n\t * ```\n\t *\n\t * @param style - The style to get.\n\t *\n\t * @public */\n\tgetStyleForNextShape(style: StyleProp): T {\n\t\tconst value = this.getInstanceState().stylesForNextShape[style.id]\n\t\treturn value === undefined ? style.defaultValue : (value as T)\n\t}\n\n\tgetShapeStyleIfExists(shape: TLShape, style: StyleProp): T | undefined {\n\t\tconst styleKey = this.styleProps[shape.type].get(style)\n\t\tif (styleKey === undefined) return undefined\n\t\treturn getOwnProperty(shape.props, styleKey) as T | undefined\n\t}\n\n\t/**\n\t * A map of all the current styles either in the current selection, or that are relevant to the\n\t * current tool.\n\t *\n\t * @example\n\t * ```ts\n\t * const color = editor.getSharedStyles().get(DefaultColorStyle)\n\t * if (color && color.type === 'shared') {\n\t * print('All selected shapes have the same color:', color.value)\n\t * }\n\t * ```\n\t *\n\t * @public\n\t */\n\t@computed({ isEqual: (a, b) => a.equals(b) })\n\tgetSharedStyles(): ReadonlySharedStyleMap {\n\t\t// If we're in selecting and if we have a selection, return the shared styles from the\n\t\t// current selection\n\t\tif (this.isIn('select') && this.getSelectedShapeIds().length > 0) {\n\t\t\treturn this._getSelectionSharedStyles()\n\t\t}\n\n\t\t// If the current tool is associated with a shape, return the styles for that shape.\n\t\t// Otherwise, just return an empty map.\n\t\tconst currentTool = this.root.getCurrent()!\n\t\tconst styles = new SharedStyleMap()\n\n\t\tif (!currentTool) return styles\n\n\t\tif (currentTool.shapeType) {\n\t\t\tfor (const style of this.styleProps[currentTool.shapeType].keys()) {\n\t\t\t\tstyles.applyValue(style, this.getStyleForNextShape(style))\n\t\t\t}\n\t\t}\n\n\t\treturn styles\n\t}\n\n\t/**\n\t * Get the currently selected shared opacity.\n\t * If any shapes are selected, this returns the shared opacity of the selected shapes.\n\t * Otherwise, this returns the chosen opacity for the next shape.\n\t *\n\t * @public\n\t */\n\t@computed getSharedOpacity(): SharedStyle {\n\t\tif (this.isIn('select') && this.getSelectedShapeIds().length > 0) {\n\t\t\tconst shapesToCheck: TLShape[] = []\n\t\t\tconst addShape = (shapeId: TLShapeId) => {\n\t\t\t\tconst shape = this.getShape(shapeId)\n\t\t\t\tif (!shape) return\n\t\t\t\t// For groups, ignore the opacity of the group shape and instead include\n\t\t\t\t// the opacity of the group's children. These are the shapes that would have\n\t\t\t\t// their opacity changed if the user called `setOpacity` on the current selection.\n\t\t\t\tif (this.isShapeOfType(shape, 'group')) {\n\t\t\t\t\tfor (const childId of this.getSortedChildIdsForParent(shape.id)) {\n\t\t\t\t\t\taddShape(childId)\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tshapesToCheck.push(shape)\n\t\t\t\t}\n\t\t\t}\n\t\t\tfor (const shapeId of this.getSelectedShapeIds()) {\n\t\t\t\taddShape(shapeId)\n\t\t\t}\n\n\t\t\tlet opacity: number | null = null\n\t\t\tfor (const shape of shapesToCheck) {\n\t\t\t\tif (opacity === null) {\n\t\t\t\t\topacity = shape.opacity\n\t\t\t\t} else if (opacity !== shape.opacity) {\n\t\t\t\t\treturn { type: 'mixed' }\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (opacity !== null) return { type: 'shared', value: opacity }\n\t\t}\n\t\treturn { type: 'shared', value: this.getInstanceState().opacityForNextShape }\n\t}\n\n\t/**\n\t * Set the opacity for the next shapes. This will effect subsequently created shapes.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.setOpacityForNextShapes(0.5)\n\t * ```\n\t *\n\t * @param opacity - The opacity to set. Must be a number between 0 and 1 inclusive.\n\t * @param historyOptions - The history options for the change.\n\t */\n\tsetOpacityForNextShapes(opacity: number, historyOptions?: TLHistoryBatchOptions): this {\n\t\tthis.updateInstanceState({ opacityForNextShape: opacity }, historyOptions)\n\t\treturn this\n\t}\n\n\t/**\n\t * Set the current opacity. This will effect any selected shapes.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.setOpacityForSelectedShapes(0.5)\n\t * ```\n\t *\n\t * @param opacity - The opacity to set. Must be a number between 0 and 1 inclusive.\n\t */\n\tsetOpacityForSelectedShapes(opacity: number): this {\n\t\tconst selectedShapes = this.getSelectedShapes()\n\n\t\tif (selectedShapes.length > 0) {\n\t\t\tconst shapesToUpdate: TLShape[] = []\n\n\t\t\t// We can have many deep levels of grouped shape\n\t\t\t// Making a recursive function to look through all the levels\n\t\t\tconst addShapeById = (shape: TLShape) => {\n\t\t\t\tif (this.isShapeOfType(shape, 'group')) {\n\t\t\t\t\tconst childIds = this.getSortedChildIdsForParent(shape)\n\t\t\t\t\tfor (const childId of childIds) {\n\t\t\t\t\t\taddShapeById(this.getShape(childId)!)\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tshapesToUpdate.push(shape)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfor (const id of selectedShapes) {\n\t\t\t\taddShapeById(id)\n\t\t\t}\n\n\t\t\tthis.updateShapes(\n\t\t\t\tshapesToUpdate.map((shape) => {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tid: shape.id,\n\t\t\t\t\t\ttype: shape.type,\n\t\t\t\t\t\topacity,\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t)\n\t\t}\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Set the value of a {@link @tldraw/tlschema#StyleProp} for the next shapes. This change will be applied to subsequently created shapes.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.setStyleForNextShapes(DefaultColorStyle, 'red')\n\t * editor.setStyleForNextShapes(DefaultColorStyle, 'red', { ephemeral: true })\n\t * ```\n\t *\n\t * @param style - The style to set.\n\t * @param value - The value to set.\n\t * @param historyOptions - The history options for the change.\n\t *\n\t * @public\n\t */\n\tsetStyleForNextShapes(\n\t\tstyle: StyleProp,\n\t\tvalue: T,\n\t\thistoryOptions?: TLHistoryBatchOptions\n\t): this {\n\t\tconst stylesForNextShape = this.getInstanceState().stylesForNextShape\n\n\t\tthis.updateInstanceState(\n\t\t\t{ stylesForNextShape: { ...stylesForNextShape, [style.id]: value } },\n\t\t\thistoryOptions\n\t\t)\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Set the value of a {@link @tldraw/tlschema#StyleProp}. This change will be applied to the currently selected shapes.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.setStyleForSelectedShapes(DefaultColorStyle, 'red')\n\t * ```\n\t *\n\t * @param style - The style to set.\n\t * @param value - The value to set.\n\t * @param historyOptions - The history options for the change.\n\t *\n\t * @public\n\t */\n\tsetStyleForSelectedShapes>(style: S, value: StylePropValue): this {\n\t\tconst selectedShapes = this.getSelectedShapes()\n\n\t\tif (selectedShapes.length > 0) {\n\t\t\tconst updates: {\n\t\t\t\tutil: ShapeUtil\n\t\t\t\toriginalShape: TLShape\n\t\t\t\tupdatePartial: TLShapePartial\n\t\t\t}[] = []\n\n\t\t\t// We can have many deep levels of grouped shape\n\t\t\t// Making a recursive function to look through all the levels\n\t\t\tconst addShapeById = (shape: TLShape) => {\n\t\t\t\tif (this.isShapeOfType(shape, 'group')) {\n\t\t\t\t\tconst childIds = this.getSortedChildIdsForParent(shape.id)\n\t\t\t\t\tfor (const childId of childIds) {\n\t\t\t\t\t\taddShapeById(this.getShape(childId)!)\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tconst util = this.getShapeUtil(shape)\n\t\t\t\t\tconst stylePropKey = this.styleProps[shape.type].get(style)\n\t\t\t\t\tif (stylePropKey) {\n\t\t\t\t\t\tconst shapePartial: TLShapePartial = {\n\t\t\t\t\t\t\tid: shape.id,\n\t\t\t\t\t\t\ttype: shape.type,\n\t\t\t\t\t\t\tprops: { [stylePropKey]: value },\n\t\t\t\t\t\t}\n\t\t\t\t\t\tupdates.push({\n\t\t\t\t\t\t\tutil,\n\t\t\t\t\t\t\toriginalShape: shape,\n\t\t\t\t\t\t\tupdatePartial: shapePartial,\n\t\t\t\t\t\t})\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfor (const shape of selectedShapes) {\n\t\t\t\taddShapeById(shape)\n\t\t\t}\n\n\t\t\tthis.updateShapes(updates.map(({ updatePartial }) => updatePartial))\n\t\t}\n\n\t\treturn this\n\t}\n\n\t/* --------------------- Content -------------------- */\n\n\t/** @internal */\n\texternalAssetContentHandlers: {\n\t\t[K in TLExternalAssetContent['type']]: {\n\t\t\t[Key in K]:\n\t\t\t\t| null\n\t\t\t\t| ((info: TLExternalAssetContent & { type: Key }) => Promise)\n\t\t}[K]\n\t} = {\n\t\tfile: null,\n\t\turl: null,\n\t}\n\n\t/** @internal */\n\tprivate readonly temporaryAssetPreview = new Map()\n\n\t/**\n\t * Register an external asset handler. This handler will be called when the editor needs to\n\t * create an asset for some external content, like an image/video file or a bookmark URL. For\n\t * example, the 'file' type handler will be called when a user drops an image onto the canvas.\n\t *\n\t * The handler should extract any relevant metadata for the asset, upload it to blob storage\n\t * using {@link Editor.uploadAsset} if needed, and return the asset with the metadata & uploaded\n\t * URL.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.registerExternalAssetHandler('file', myHandler)\n\t * ```\n\t *\n\t * @param type - The type of external content.\n\t * @param handler - The handler to use for this content type.\n\t *\n\t * @public\n\t */\n\tregisterExternalAssetHandler(\n\t\ttype: T,\n\t\thandler: null | ((info: TLExternalAssetContent & { type: T }) => Promise)\n\t): this {\n\t\tthis.externalAssetContentHandlers[type] = handler as any\n\t\treturn this\n\t}\n\n\t/**\n\t * Register a temporary preview of an asset. This is useful for showing a ghost image of\n\t * something that is being uploaded. Retrieve the placeholder with\n\t * {@link Editor.getTemporaryAssetPreview}. Placeholders last for 3 minutes by default, but this\n\t * can be configured using\n\t *\n\t * @example\n\t * ```ts\n\t * editor.createTemporaryAssetPreview(assetId, file)\n\t * ```\n\t *\n\t * @param assetId - The asset's id.\n\t * @param file - The raw file.\n\t *\n\t * @public\n\t */\n\tcreateTemporaryAssetPreview(assetId: TLAssetId, file: File) {\n\t\tif (this.temporaryAssetPreview.has(assetId)) {\n\t\t\treturn this.temporaryAssetPreview.get(assetId)\n\t\t}\n\n\t\tconst objectUrl = URL.createObjectURL(file)\n\t\tthis.temporaryAssetPreview.set(assetId, objectUrl)\n\n\t\t// eslint-disable-next-line no-restricted-globals -- we always want to revoke the asset and object URL\n\t\tsetTimeout(() => {\n\t\t\tthis.temporaryAssetPreview.delete(assetId)\n\t\t\tURL.revokeObjectURL(objectUrl)\n\t\t}, this.options.temporaryAssetPreviewLifetimeMs)\n\n\t\treturn objectUrl\n\t}\n\n\t/**\n\t * Get temporary preview of an asset. This is useful for showing a ghost\n\t * image of something that is being uploaded.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getTemporaryAssetPreview('someId')\n\t * ```\n\t *\n\t * @param assetId - The asset's id.\n\t *\n\t * @public\n\t */\n\tgetTemporaryAssetPreview(assetId: TLAssetId) {\n\t\treturn this.temporaryAssetPreview.get(assetId)\n\t}\n\n\t/**\n\t * Get an asset for an external asset content type.\n\t *\n\t * @example\n\t * ```ts\n\t * const asset = await editor.getAssetForExternalContent({ type: 'file', file: myFile })\n\t * const asset = await editor.getAssetForExternalContent({ type: 'url', url: myUrl })\n\t * ```\n\t *\n\t * @param info - Info about the external content.\n\t * @returns The asset.\n\t */\n\tasync getAssetForExternalContent(info: TLExternalAssetContent): Promise {\n\t\treturn await this.externalAssetContentHandlers[info.type]?.(info as any)\n\t}\n\n\thasExternalAssetHandler(type: TLExternalAssetContent['type']): boolean {\n\t\treturn !!this.externalAssetContentHandlers[type]\n\t}\n\n\t/** @internal */\n\texternalContentHandlers: {\n\t\t[K in TLExternalContent['type']]: {\n\t\t\t[Key in K]: null | ((info: TLExternalContent & { type: Key }) => void)\n\t\t}[K]\n\t} = {\n\t\ttext: null,\n\t\tfiles: null,\n\t\tembed: null,\n\t\t'svg-text': null,\n\t\turl: null,\n\t}\n\n\t/**\n\t * Register an external content handler. This handler will be called when the editor receives\n\t * external content of the provided type. For example, the 'image' type handler will be called\n\t * when a user drops an image onto the canvas.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.registerExternalContentHandler('text', myHandler)\n\t * ```\n\t * @example\n\t * ```ts\n\t * editor.registerExternalContentHandler<'embed', MyEmbedType>('embed', myHandler)\n\t * ```\n\t *\n\t * @param type - The type of external content.\n\t * @param handler - The handler to use for this content type.\n\t *\n\t * @public\n\t */\n\tregisterExternalContentHandler['type'], E>(\n\t\ttype: T,\n\t\thandler:\n\t\t\t| null\n\t\t\t| ((\n\t\t\t\t\tinfo: T extends TLExternalContent['type']\n\t\t\t\t\t\t? TLExternalContent & { type: T }\n\t\t\t\t\t\t: TLExternalContent\n\t\t\t ) => void)\n\t): this {\n\t\tthis.externalContentHandlers[type] = handler as any\n\t\treturn this\n\t}\n\n\t/**\n\t * Handle external content, such as files, urls, embeds, or plain text which has been put into the app, for example by pasting external text or dropping external images onto canvas.\n\t *\n\t * @param info - Info about the external content.\n\t */\n\tasync putExternalContent(info: TLExternalContent): Promise {\n\t\treturn this.externalContentHandlers[info.type]?.(info as any)\n\t}\n\n\t/**\n\t * Get content that can be exported for the given shape ids.\n\t *\n\t * @param shapes - The shapes (or shape ids) to get content for.\n\t *\n\t * @returns The exported content.\n\t *\n\t * @public\n\t */\n\tgetContentFromCurrentPage(shapes: TLShapeId[] | TLShape[]): TLContent | undefined {\n\t\t// todo: make this work with any page, not just the current page\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\n\t\tif (!ids) return\n\t\tif (ids.length === 0) return\n\n\t\tconst shapeIds = this.getShapeAndDescendantIds(ids)\n\n\t\treturn withIsolatedShapes(this, shapeIds, (bindingIdsToKeep) => {\n\t\t\tconst bindings: TLBinding[] = []\n\t\t\tfor (const id of bindingIdsToKeep) {\n\t\t\t\tconst binding = this.getBinding(id)\n\t\t\t\tif (!binding) continue\n\t\t\t\tbindings.push(binding)\n\t\t\t}\n\n\t\t\tconst rootShapeIds: TLShapeId[] = []\n\t\t\tconst shapes: TLShape[] = []\n\t\t\tfor (const shapeId of shapeIds) {\n\t\t\t\tconst shape = this.getShape(shapeId)\n\t\t\t\tif (!shape) continue\n\n\t\t\t\tconst isRootShape = !shapeIds.has(shape.parentId as TLShapeId)\n\t\t\t\tif (isRootShape) {\n\t\t\t\t\t// Need to get page point and rotation of the shape because shapes in\n\t\t\t\t\t// groups use local position/rotation\n\t\t\t\t\tconst pageTransform = this.getShapePageTransform(shape.id)!\n\t\t\t\t\tconst pagePoint = pageTransform.point()\n\t\t\t\t\tshapes.push({\n\t\t\t\t\t\t...shape,\n\t\t\t\t\t\tx: pagePoint.x,\n\t\t\t\t\t\ty: pagePoint.y,\n\t\t\t\t\t\trotation: pageTransform.rotation(),\n\t\t\t\t\t\tparentId: this.getCurrentPageId(),\n\t\t\t\t\t})\n\t\t\t\t\trootShapeIds.push(shape.id)\n\t\t\t\t} else {\n\t\t\t\t\tshapes.push(shape)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst assets: TLAsset[] = []\n\t\t\tconst seenAssetIds = new Set()\n\t\t\tfor (const shape of shapes) {\n\t\t\t\tif (!('assetId' in shape.props)) continue\n\n\t\t\t\tconst assetId = shape.props.assetId\n\t\t\t\tif (!assetId || seenAssetIds.has(assetId)) continue\n\n\t\t\t\tseenAssetIds.add(assetId)\n\t\t\t\tconst asset = this.getAsset(assetId)\n\t\t\t\tif (!asset) continue\n\t\t\t\tassets.push(asset)\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tschema: this.store.schema.serialize(),\n\t\t\t\tshapes,\n\t\t\t\trootShapeIds,\n\t\t\t\tbindings,\n\t\t\t\tassets,\n\t\t\t}\n\t\t})\n\t}\n\n\tasync resolveAssetsInContent(content: TLContent | undefined): Promise {\n\t\tif (!content) return undefined\n\n\t\tconst assets: TLAsset[] = []\n\t\tawait Promise.allSettled(\n\t\t\tcontent.assets.map(async (asset) => {\n\t\t\t\tif (\n\t\t\t\t\t(asset.type === 'image' || asset.type === 'video') &&\n\t\t\t\t\t!asset.props.src?.startsWith('data:image') &&\n\t\t\t\t\t!asset.props.src?.startsWith('http')\n\t\t\t\t) {\n\t\t\t\t\tconst assetWithDataUrl = structuredClone(asset as TLImageAsset | TLVideoAsset)\n\t\t\t\t\tconst objectUrl = await this.store.props.assets.resolve(asset, {\n\t\t\t\t\t\tscreenScale: 1,\n\t\t\t\t\t\tsteppedScreenScale: 1,\n\t\t\t\t\t\tdpr: 1,\n\t\t\t\t\t\tnetworkEffectiveType: null,\n\t\t\t\t\t\tshouldResolveToOriginal: true,\n\t\t\t\t\t})\n\t\t\t\t\tassetWithDataUrl.props.src = await FileHelpers.blobToDataUrl(\n\t\t\t\t\t\tawait fetch(objectUrl!).then((r) => r.blob())\n\t\t\t\t\t)\n\t\t\t\t\tassets.push(assetWithDataUrl)\n\t\t\t\t} else {\n\t\t\t\t\tassets.push(asset)\n\t\t\t\t}\n\t\t\t})\n\t\t)\n\t\tcontent.assets = assets\n\n\t\treturn content\n\t}\n\n\t/**\n\t * Place content into the editor.\n\t *\n\t * @param content - The content.\n\t * @param options - Options for placing the content.\n\t *\n\t * @public\n\t */\n\tputContentOntoCurrentPage(\n\t\tcontent: TLContent,\n\t\toptions: {\n\t\t\tpoint?: VecLike\n\t\t\tselect?: boolean\n\t\t\tpreservePosition?: boolean\n\t\t\tpreserveIds?: boolean\n\t\t} = {}\n\t): this {\n\t\tif (this.getInstanceState().isReadonly) return this\n\n\t\t// todo: make this able to support putting content onto any page, not just the current page\n\n\t\tif (!content.schema) {\n\t\t\tthrow Error('Could not put content:\\ncontent is missing a schema.')\n\t\t}\n\n\t\tconst { select = false, preserveIds = false, preservePosition = false } = options\n\t\tlet { point = undefined } = options\n\n\t\t// decide on a parent for the put shapes; if the parent is among the put shapes(?) then use its parent\n\n\t\tconst currentPageId = this.getCurrentPageId()\n\t\tconst { rootShapeIds } = content\n\n\t\t// We need to collect the migrated records\n\t\tconst assets: TLAsset[] = []\n\t\tconst shapes: TLShape[] = []\n\t\tconst bindings: TLBinding[] = []\n\n\t\t// Let's treat the content as a store, and then migrate that store.\n\t\tconst store: StoreSnapshot = {\n\t\t\tstore: {\n\t\t\t\t...Object.fromEntries(content.assets.map((asset) => [asset.id, asset] as const)),\n\t\t\t\t...Object.fromEntries(content.shapes.map((shape) => [shape.id, shape] as const)),\n\t\t\t\t...Object.fromEntries(\n\t\t\t\t\tcontent.bindings?.map((bindings) => [bindings.id, bindings] as const) ?? []\n\t\t\t\t),\n\t\t\t},\n\t\t\tschema: content.schema,\n\t\t}\n\t\tconst result = this.store.schema.migrateStoreSnapshot(store)\n\t\tif (result.type === 'error') {\n\t\t\tthrow Error('Could not put content: could not migrate content')\n\t\t}\n\t\tfor (const record of Object.values(result.value)) {\n\t\t\tswitch (record.typeName) {\n\t\t\t\tcase 'asset': {\n\t\t\t\t\tassets.push(record)\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase 'shape': {\n\t\t\t\t\tshapes.push(record)\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase 'binding': {\n\t\t\t\t\tbindings.push(record)\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Ok, we've got our migrated records, now we can continue!\n\t\tconst shapeIdMap = new Map(\n\t\t\tpreserveIds\n\t\t\t\t? shapes.map((shape) => [shape.id, shape.id])\n\t\t\t\t: shapes.map((shape) => [shape.id, createShapeId()])\n\t\t)\n\t\tconst bindingIdMap = new Map(\n\t\t\tpreserveIds\n\t\t\t\t? bindings.map((binding) => [binding.id, binding.id])\n\t\t\t\t: bindings.map((binding) => [binding.id, createBindingId()])\n\t\t)\n\n\t\t// By default, the paste parent will be the current page.\n\t\tlet pasteParentId = this.getCurrentPageId() as TLPageId | TLShapeId\n\t\tlet lowestDepth = Infinity\n\t\tlet lowestAncestors: TLShape[] = []\n\n\t\t// Among the selected shapes, find the shape with the fewest ancestors and use its first ancestor.\n\t\tfor (const shape of this.getSelectedShapes()) {\n\t\t\tif (lowestDepth === 0) break\n\n\t\t\tconst isFrame = this.isShapeOfType(shape, 'frame')\n\t\t\tconst ancestors = this.getShapeAncestors(shape)\n\t\t\tif (isFrame) ancestors.push(shape)\n\n\t\t\tconst depth = isFrame ? ancestors.length + 1 : ancestors.length\n\n\t\t\tif (depth < lowestDepth) {\n\t\t\t\tlowestDepth = depth\n\t\t\t\tlowestAncestors = ancestors\n\t\t\t\tpasteParentId = isFrame ? shape.id : shape.parentId\n\t\t\t} else if (depth === lowestDepth) {\n\t\t\t\tif (lowestAncestors.length !== ancestors.length) {\n\t\t\t\t\tthrow Error(`Ancestors: ${lowestAncestors.length} !== ${ancestors.length}`)\n\t\t\t\t}\n\n\t\t\t\tif (lowestAncestors.length === 0) {\n\t\t\t\t\tpasteParentId = currentPageId\n\t\t\t\t\tbreak\n\t\t\t\t} else {\n\t\t\t\t\tpasteParentId = currentPageId\n\t\t\t\t\tfor (let i = 0; i < lowestAncestors.length; i++) {\n\t\t\t\t\t\tif (ancestors[i] !== lowestAncestors[i]) break\n\t\t\t\t\t\tpasteParentId = ancestors[i].id\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tlet isDuplicating = false\n\n\t\tif (!isPageId(pasteParentId)) {\n\t\t\tconst parent = this.getShape(pasteParentId)\n\t\t\tif (parent) {\n\t\t\t\tif (!this.getViewportPageBounds().includes(this.getShapePageBounds(parent)!)) {\n\t\t\t\t\tpasteParentId = currentPageId\n\t\t\t\t} else {\n\t\t\t\t\tif (rootShapeIds.length === 1) {\n\t\t\t\t\t\tconst rootShape = shapes.find((s) => s.id === rootShapeIds[0])!\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\tthis.isShapeOfType(parent, 'frame') &&\n\t\t\t\t\t\t\tthis.isShapeOfType(rootShape, 'frame') &&\n\t\t\t\t\t\t\trootShape.props.w === parent?.props.w &&\n\t\t\t\t\t\t\trootShape.props.h === parent?.props.h\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\tisDuplicating = true\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tpasteParentId = currentPageId\n\t\t\t}\n\t\t}\n\n\t\tif (!isDuplicating) {\n\t\t\tisDuplicating = shapeIdMap.has(pasteParentId)\n\t\t}\n\n\t\tif (isDuplicating) {\n\t\t\tpasteParentId = this.getShape(pasteParentId)!.parentId\n\t\t}\n\n\t\tlet index = this.getHighestIndexForParent(pasteParentId) // todo: requires that the putting page is the current page\n\n\t\tconst rootShapes: TLShape[] = []\n\n\t\tconst newShapes: TLShape[] = shapes.map((oldShape): TLShape => {\n\t\t\tconst newId = shapeIdMap.get(oldShape.id)!\n\n\t\t\t// Create the new shape (new except for the id)\n\t\t\tconst newShape = { ...oldShape, id: newId }\n\n\t\t\tif (rootShapeIds.includes(oldShape.id)) {\n\t\t\t\tnewShape.parentId = currentPageId\n\t\t\t\trootShapes.push(newShape)\n\t\t\t}\n\n\t\t\t// Assign the child to its new parent.\n\n\t\t\t// If the child's parent is among the putting shapes, then assign\n\t\t\t// it to the new parent's id.\n\t\t\tif (shapeIdMap.has(newShape.parentId)) {\n\t\t\t\tnewShape.parentId = shapeIdMap.get(oldShape.parentId)!\n\t\t\t} else {\n\t\t\t\trootShapeIds.push(newShape.id)\n\t\t\t\t// newShape.parentId = pasteParentId\n\t\t\t\tnewShape.index = index\n\t\t\t\tindex = getIndexAbove(index)\n\t\t\t}\n\n\t\t\treturn newShape\n\t\t})\n\n\t\tif (newShapes.length + this.getCurrentPageShapeIds().size > this.options.maxShapesPerPage) {\n\t\t\t// There's some complexity here involving children\n\t\t\t// that might be created without their parents, so\n\t\t\t// if we're going over the limit then just don't paste.\n\t\t\talertMaxShapes(this)\n\t\t\treturn this\n\t\t}\n\n\t\tconst newBindings = bindings.map(\n\t\t\t(oldBinding): TLBinding => ({\n\t\t\t\t...oldBinding,\n\t\t\t\tid: assertExists(bindingIdMap.get(oldBinding.id)),\n\t\t\t\tfromId: assertExists(shapeIdMap.get(oldBinding.fromId)),\n\t\t\t\ttoId: assertExists(shapeIdMap.get(oldBinding.toId)),\n\t\t\t})\n\t\t)\n\n\t\t// These are all the assets we need to create\n\t\tconst assetsToCreate: TLAsset[] = []\n\n\t\t// These assets have base64 data that may need to be hosted\n\t\tconst assetsToUpdate: (TLImageAsset | TLVideoAsset)[] = []\n\n\t\tfor (const asset of assets) {\n\t\t\tif (this.store.has(asset.id)) {\n\t\t\t\t// We already have this asset\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tif (\n\t\t\t\t(asset.type === 'image' || asset.type === 'video') &&\n\t\t\t\tasset.props.src?.startsWith('data:image')\n\t\t\t) {\n\t\t\t\t// it's src is a base64 image or video; we need to create a new asset without the src,\n\t\t\t\t// then create a new asset from the original src. So we save a copy of the original asset,\n\t\t\t\t// then delete the src from the original asset.\n\t\t\t\tassetsToUpdate.push(structuredClone(asset as TLImageAsset | TLVideoAsset))\n\t\t\t\tasset.props.src = null\n\t\t\t}\n\n\t\t\t// Add the asset to the list of assets to create\n\t\t\tassetsToCreate.push(asset)\n\t\t}\n\n\t\t// Start loading the new assets, order does not matter\n\t\tPromise.allSettled(\n\t\t\t(assetsToUpdate as (TLImageAsset | TLVideoAsset)[]).map(async (asset) => {\n\t\t\t\t// Turn the data url into a file\n\t\t\t\tconst file = await dataUrlToFile(\n\t\t\t\t\tasset.props.src!,\n\t\t\t\t\tasset.props.name,\n\t\t\t\t\tasset.props.mimeType ?? 'image/png'\n\t\t\t\t)\n\n\t\t\t\t// Get a new asset for the file\n\t\t\t\tconst newAsset = await this.getAssetForExternalContent({\n\t\t\t\t\ttype: 'file',\n\t\t\t\t\tfile,\n\t\t\t\t\tassetId: asset.id,\n\t\t\t\t})\n\n\t\t\t\tif (!newAsset) {\n\t\t\t\t\t// If we don't have a new asset, delete the old asset.\n\t\t\t\t\t// The shapes that reference this asset should break.\n\t\t\t\t\tthis.deleteAssets([asset.id])\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\t// Save the new asset under the old asset's id\n\t\t\t\tthis.updateAssets([{ ...newAsset, id: asset.id }])\n\t\t\t})\n\t\t)\n\n\t\tthis.run(() => {\n\t\t\t// Create any assets that need to be created\n\t\t\tif (assetsToCreate.length > 0) {\n\t\t\t\tthis.createAssets(assetsToCreate)\n\t\t\t}\n\n\t\t\t// Create the shapes with root shapes as children of the page\n\t\t\tthis.createShapes(newShapes)\n\t\t\tthis.createBindings(newBindings)\n\n\t\t\tif (select) {\n\t\t\t\tthis.select(...rootShapes.map((s) => s.id))\n\t\t\t}\n\n\t\t\t// And then, if needed, reparent the root shapes to the paste parent\n\t\t\tif (pasteParentId !== currentPageId) {\n\t\t\t\tthis.reparentShapes(\n\t\t\t\t\trootShapes.map((s) => s.id),\n\t\t\t\t\tpasteParentId\n\t\t\t\t)\n\t\t\t}\n\n\t\t\tconst newCreatedShapes = newShapes.map((s) => this.getShape(s.id)!)\n\t\t\tconst bounds = Box.Common(newCreatedShapes.map((s) => this.getShapePageBounds(s)!))\n\n\t\t\tif (point === undefined) {\n\t\t\t\tif (!isPageId(pasteParentId)) {\n\t\t\t\t\t// Put the shapes in the middle of the (on screen) parent\n\t\t\t\t\tconst shape = this.getShape(pasteParentId)!\n\t\t\t\t\tpoint = Mat.applyToPoint(\n\t\t\t\t\t\tthis.getShapePageTransform(shape),\n\t\t\t\t\t\tthis.getShapeGeometry(shape).bounds.center\n\t\t\t\t\t)\n\t\t\t\t} else {\n\t\t\t\t\tconst viewportPageBounds = this.getViewportPageBounds()\n\t\t\t\t\tif (preservePosition || viewportPageBounds.includes(Box.From(bounds))) {\n\t\t\t\t\t\t// Otherwise, put shapes where they used to be\n\t\t\t\t\t\tpoint = bounds.center\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// If the old bounds are outside of the viewport...\n\t\t\t\t\t\t// put the shapes in the middle of the viewport\n\t\t\t\t\t\tpoint = viewportPageBounds.center\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (rootShapes.length === 1) {\n\t\t\t\tconst onlyRoot = rootShapes[0] as TLFrameShape\n\t\t\t\t// If the old bounds are in the viewport...\n\t\t\t\tif (this.isShapeOfType(onlyRoot, 'frame')) {\n\t\t\t\t\twhile (\n\t\t\t\t\t\tthis.getShapesAtPoint(point).some(\n\t\t\t\t\t\t\t(shape) =>\n\t\t\t\t\t\t\t\tthis.isShapeOfType(shape, 'frame') &&\n\t\t\t\t\t\t\t\tshape.props.w === onlyRoot.props.w &&\n\t\t\t\t\t\t\t\tshape.props.h === onlyRoot.props.h\n\t\t\t\t\t\t)\n\t\t\t\t\t) {\n\t\t\t\t\t\tpoint.x += bounds.w + 16\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst pageCenter = Box.Common(\n\t\t\t\tcompact(rootShapes.map(({ id }) => this.getShapePageBounds(id)))\n\t\t\t).center\n\n\t\t\tconst offset = Vec.Sub(point, pageCenter)\n\n\t\t\tthis.updateShapes(\n\t\t\t\trootShapes.map(({ id }) => {\n\t\t\t\t\tconst s = this.getShape(id)!\n\t\t\t\t\tconst localRotation = this.getShapeParentTransform(id).decompose().rotation\n\t\t\t\t\tconst localDelta = Vec.Rot(offset, -localRotation)\n\n\t\t\t\t\treturn { id: s.id, type: s.type, x: s.x + localDelta.x, y: s.y + localDelta.y }\n\t\t\t\t})\n\t\t\t)\n\t\t})\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Get an exported SVG element of the given shapes.\n\t *\n\t * @param ids - The shapes (or shape ids) to export.\n\t * @param opts - Options for the export.\n\t *\n\t * @returns The SVG element.\n\t *\n\t * @public\n\t */\n\tasync getSvgElement(shapes: TLShapeId[] | TLShape[], opts: TLImageExportOptions = {}) {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\n\t\tif (ids.length === 0) return undefined\n\n\t\treturn exportToSvg(this, ids, opts)\n\t}\n\n\t/**\n\t * Get an exported SVG string of the given shapes.\n\t *\n\t * @param ids - The shapes (or shape ids) to export.\n\t * @param opts - Options for the export.\n\t *\n\t * @returns The SVG element.\n\t *\n\t * @public\n\t */\n\tasync getSvgString(shapes: TLShapeId[] | TLShape[], opts: TLImageExportOptions = {}) {\n\t\tconst result = await this.getSvgElement(shapes, opts)\n\t\tif (!result) return undefined\n\n\t\tconst serializer = new XMLSerializer()\n\t\treturn {\n\t\t\tsvg: serializer.serializeToString(result.svg),\n\t\t\twidth: result.width,\n\t\t\theight: result.height,\n\t\t}\n\t}\n\n\t/** @deprecated Use {@link Editor.getSvgString} or {@link Editor.getSvgElement} instead. */\n\tasync getSvg(shapes: TLShapeId[] | TLShape[], opts: TLImageExportOptions = {}) {\n\t\tconst result = await this.getSvgElement(shapes, opts)\n\t\tif (!result) return undefined\n\t\treturn result.svg\n\t}\n\n\t/* --------------------- Events --------------------- */\n\n\t/**\n\t * The app's current input state.\n\t *\n\t * @public\n\t */\n\tinputs = {\n\t\t/** The most recent pointer down's position in the current page space. */\n\t\toriginPagePoint: new Vec(),\n\t\t/** The most recent pointer down's position in screen space. */\n\t\toriginScreenPoint: new Vec(),\n\t\t/** The previous pointer position in the current page space. */\n\t\tpreviousPagePoint: new Vec(),\n\t\t/** The previous pointer position in screen space. */\n\t\tpreviousScreenPoint: new Vec(),\n\t\t/** The most recent pointer position in the current page space. */\n\t\tcurrentPagePoint: new Vec(),\n\t\t/** The most recent pointer position in screen space. */\n\t\tcurrentScreenPoint: new Vec(),\n\t\t/** A set containing the currently pressed keys. */\n\t\tkeys: new Set(),\n\t\t/** A set containing the currently pressed buttons. */\n\t\tbuttons: new Set(),\n\t\t/** Whether the input is from a pe. */\n\t\tisPen: false,\n\t\t/** Whether the shift key is currently pressed. */\n\t\tshiftKey: false,\n\t\t/** Whether the control or command key is currently pressed. */\n\t\tctrlKey: false,\n\t\t/** Whether the alt or option key is currently pressed. */\n\t\taltKey: false,\n\t\t/** Whether the user is dragging. */\n\t\tisDragging: false,\n\t\t/** Whether the user is pointing. */\n\t\tisPointing: false,\n\t\t/** Whether the user is pinching. */\n\t\tisPinching: false,\n\t\t/** Whether the user is editing. */\n\t\tisEditing: false,\n\t\t/** Whether the user is panning. */\n\t\tisPanning: false,\n\t\t/** Whether the user is spacebar panning. */\n\t\tisSpacebarPanning: false,\n\t\t/** Velocity of mouse pointer, in pixels per millisecond */\n\t\tpointerVelocity: new Vec(),\n\t}\n\n\t/**\n\t * Update the input points from a pointer, pinch, or wheel event.\n\t *\n\t * @param info - The event info.\n\t */\n\tprivate _updateInputsFromEvent(\n\t\tinfo: TLPointerEventInfo | TLPinchEventInfo | TLWheelEventInfo\n\t): void {\n\t\tconst {\n\t\t\tpointerVelocity,\n\t\t\tpreviousScreenPoint,\n\t\t\tpreviousPagePoint,\n\t\t\tcurrentScreenPoint,\n\t\t\tcurrentPagePoint,\n\t\t} = this.inputs\n\n\t\tconst { screenBounds } = this.store.unsafeGetWithoutCapture(TLINSTANCE_ID)!\n\t\tconst { x: cx, y: cy, z: cz } = unsafe__withoutCapture(() => this.getCamera())\n\n\t\tconst sx = info.point.x - screenBounds.x\n\t\tconst sy = info.point.y - screenBounds.y\n\t\tconst sz = info.point.z ?? 0.5\n\n\t\tpreviousScreenPoint.setTo(currentScreenPoint)\n\t\tpreviousPagePoint.setTo(currentPagePoint)\n\n\t\t// The \"screen bounds\" is relative to the user's actual screen.\n\t\t// The \"screen point\" is relative to the \"screen bounds\";\n\t\t// it will be 0,0 when its actual screen position is equal\n\t\t// to screenBounds.point. This is confusing!\n\t\tcurrentScreenPoint.set(sx, sy)\n\t\tconst nx = sx / cz - cx\n\t\tconst ny = sy / cz - cy\n\t\tif (isFinite(nx) && isFinite(ny)) {\n\t\t\tcurrentPagePoint.set(nx, ny, sz)\n\t\t}\n\n\t\tthis.inputs.isPen = info.type === 'pointer' && info.isPen\n\n\t\t// Reset velocity on pointer down, or when a pinch starts or ends\n\t\tif (info.name === 'pointer_down' || this.inputs.isPinching) {\n\t\t\tpointerVelocity.set(0, 0)\n\t\t\tthis.inputs.originScreenPoint.setTo(currentScreenPoint)\n\t\t\tthis.inputs.originPagePoint.setTo(currentPagePoint)\n\t\t}\n\n\t\t// todo: We only have to do this if there are multiple users in the document\n\t\tthis.run(\n\t\t\t() => {\n\t\t\t\tthis.store.put([\n\t\t\t\t\t{\n\t\t\t\t\t\tid: TLPOINTER_ID,\n\t\t\t\t\t\ttypeName: 'pointer',\n\t\t\t\t\t\tx: currentPagePoint.x,\n\t\t\t\t\t\ty: currentPagePoint.y,\n\t\t\t\t\t\tlastActivityTimestamp:\n\t\t\t\t\t\t\t// If our pointer moved only because we're following some other user, then don't\n\t\t\t\t\t\t\t// update our last activity timestamp; otherwise, update it to the current timestamp.\n\t\t\t\t\t\t\tinfo.type === 'pointer' && info.pointerId === INTERNAL_POINTER_IDS.CAMERA_MOVE\n\t\t\t\t\t\t\t\t? this.store.unsafeGetWithoutCapture(TLPOINTER_ID)?.lastActivityTimestamp ??\n\t\t\t\t\t\t\t\t\tthis._tickManager.now\n\t\t\t\t\t\t\t\t: this._tickManager.now,\n\t\t\t\t\t\tmeta: {},\n\t\t\t\t\t},\n\t\t\t\t])\n\t\t\t},\n\t\t\t{ history: 'ignore' }\n\t\t)\n\t}\n\n\t/**\n\t * Dispatch a cancel event.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.cancel()\n\t * ```\n\t *\n\t * @public\n\t */\n\tcancel(): this {\n\t\tthis.dispatch({ type: 'misc', name: 'cancel' })\n\t\treturn this\n\t}\n\n\t/**\n\t * Dispatch an interrupt event.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.interrupt()\n\t * ```\n\t *\n\t * @public\n\t */\n\tinterrupt(): this {\n\t\tthis.dispatch({ type: 'misc', name: 'interrupt' })\n\t\treturn this\n\t}\n\n\t/**\n\t * Dispatch a complete event.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.complete()\n\t * ```\n\t *\n\t * @public\n\t */\n\tcomplete(): this {\n\t\tthis.dispatch({ type: 'misc', name: 'complete' })\n\t\treturn this\n\t}\n\n\t/**\n\t * Puts the editor into focused mode.\n\t *\n\t * This makes the editor eligible to receive keyboard events and some pointer events (move, wheel).\n\t *\n\t * @example\n\t * ```ts\n\t * editor.focus()\n\t * ```\n\t *\n\t * By default this also dispatches a 'focus' event to the container element. To prevent this, pass `focusContainer: false`.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.focus({ focusContainer: false })\n\t * ```\n\t *\n\t * @public\n\t */\n\tfocus({ focusContainer = true } = {}): this {\n\t\tif (this.getIsFocused()) return this\n\t\tif (focusContainer) this.focusManager.focus()\n\t\tthis.updateInstanceState({ isFocused: true })\n\t\treturn this\n\t}\n\n\t/**\n\t * Switches off the editor's focused mode.\n\t *\n\t * This makes the editor ignore keyboard events and some pointer events (move, wheel).\n\t *\n\t * @example\n\t * ```ts\n\t * editor.blur()\n\t * ```\n\t * By default this also dispatches a 'blur' event to the container element. To prevent this, pass `blurContainer: false`.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.blur({ blurContainer: false })\n\t * ```\n\t *\n\t * @public\n\t */\n\tblur({ blurContainer = true } = {}): this {\n\t\tif (!this.getIsFocused()) return this\n\t\tif (blurContainer) {\n\t\t\tthis.focusManager.blur()\n\t\t} else {\n\t\t\tthis.complete() // stop any interaction\n\t\t}\n\t\tthis.updateInstanceState({ isFocused: false })\n\t\treturn this\n\t}\n\n\t/**\n\t * @public\n\t * @returns true if the editor is focused\n\t */\n\t@computed getIsFocused() {\n\t\treturn this.getInstanceState().isFocused\n\t}\n\n\t/**\n\t * @public\n\t * @returns a snapshot of the store's UI and document state\n\t */\n\tgetSnapshot() {\n\t\treturn getSnapshot(this.store)\n\t}\n\n\t/**\n\t * Loads a snapshot into the editor.\n\t * @param snapshot - the snapshot to load\n\t * @returns\n\t */\n\tloadSnapshot(\n\t\tsnapshot: Partial | TLStoreSnapshot,\n\t\topts?: TLLoadSnapshotOptions\n\t) {\n\t\tloadSnapshot(this.store, snapshot, opts)\n\t\treturn this\n\t}\n\n\tprivate _zoomToFitPageContentAt100Percent() {\n\t\tconst bounds = this.getCurrentPageBounds()\n\t\tif (bounds) {\n\t\t\tthis.zoomToBounds(bounds, { immediate: true, targetZoom: this.getBaseZoom() })\n\t\t}\n\t}\n\tprivate _navigateToDeepLink(deepLink: TLDeepLink) {\n\t\tthis.run(() => {\n\t\t\tswitch (deepLink.type) {\n\t\t\t\tcase 'page': {\n\t\t\t\t\tconst page = this.getPage(deepLink.pageId)\n\t\t\t\t\tif (page) {\n\t\t\t\t\t\tthis.setCurrentPage(page)\n\t\t\t\t\t}\n\t\t\t\t\tthis._zoomToFitPageContentAt100Percent()\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tcase 'shapes': {\n\t\t\t\t\tconst allShapes = compact(deepLink.shapeIds.map((id) => this.getShape(id)))\n\t\t\t\t\tconst byPage: { [pageId: string]: TLShape[] } = {}\n\t\t\t\t\tfor (const shape of allShapes) {\n\t\t\t\t\t\tconst pageId = this.getAncestorPageId(shape)\n\t\t\t\t\t\tif (!pageId) continue\n\t\t\t\t\t\tbyPage[pageId] ??= []\n\t\t\t\t\t\tbyPage[pageId].push(shape)\n\t\t\t\t\t}\n\t\t\t\t\tconst [pageId, shapes] = Object.entries(byPage).sort(\n\t\t\t\t\t\t([_, a], [__, b]) => b.length - a.length\n\t\t\t\t\t)[0] ?? ['', []]\n\n\t\t\t\t\tif (!pageId || !shapes.length) {\n\t\t\t\t\t\tthis._zoomToFitPageContentAt100Percent()\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthis.setCurrentPage(pageId as TLPageId)\n\t\t\t\t\t\tconst bounds = Box.Common(shapes.map((s) => this.getShapePageBounds(s)!))\n\t\t\t\t\t\tthis.zoomToBounds(bounds, { immediate: true, targetZoom: this.getBaseZoom() })\n\t\t\t\t\t}\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tcase 'viewport': {\n\t\t\t\t\tif (deepLink.pageId) {\n\t\t\t\t\t\tif (!this.getPage(deepLink.pageId)) {\n\t\t\t\t\t\t\tthis._zoomToFitPageContentAt100Percent()\n\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t}\n\t\t\t\t\t\tthis.setCurrentPage(deepLink.pageId)\n\t\t\t\t\t}\n\t\t\t\t\tthis.zoomToBounds(deepLink.bounds, { immediate: true, inset: 0 })\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tdefault:\n\t\t\t\t\texhaustiveSwitchError(deepLink)\n\t\t\t}\n\t\t})\n\t}\n\n\t/**\n\t * Handles navigating to the content specified by the query param in the given URL.\n\t *\n\t * Use {@link Editor#createDeepLink} to create a URL with a deep link query param.\n\t *\n\t * If no URL is provided, it will look for the param in the current `window.location.href`.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.navigateToDeepLink()\n\t * ```\n\t *\n\t * The default parameter name is 'd'. You can override this by providing the `param` option.\n\t *\n\t * @example\n\t * ```ts\n\t * // disable page parameter and change viewport parameter to 'c'\n\t * editor.navigateToDeepLink({\n\t * param: 'x',\n\t * url: 'https://my-app.com/my-document?x=200.12.454.23.xyz123',\n\t * })\n\t * ```\n\t *\n\t * @param opts - Options for loading the state from the URL.\n\t */\n\tnavigateToDeepLink(opts?: TLDeepLink | { url?: string | URL; param?: string }): Editor {\n\t\tif (opts && 'type' in opts) {\n\t\t\tthis._navigateToDeepLink(opts)\n\t\t\treturn this\n\t\t}\n\n\t\tconst url = new URL(opts?.url ?? window.location.href)\n\t\tconst deepLinkString = url.searchParams.get(opts?.param ?? 'd')\n\n\t\tif (!deepLinkString) {\n\t\t\tthis._zoomToFitPageContentAt100Percent()\n\t\t\treturn this\n\t\t}\n\n\t\ttry {\n\t\t\tthis._navigateToDeepLink(parseDeepLinkString(deepLinkString))\n\t\t} catch (e) {\n\t\t\tconsole.warn(e)\n\t\t\tthis._zoomToFitPageContentAt100Percent()\n\t\t}\n\t\treturn this\n\t}\n\n\t/**\n\t * Turns the given URL into a deep link by adding a query parameter.\n\t *\n\t * e.g. `https://my-app.com/my-document?d=100.100.200.200.xyz123`\n\t *\n\t * If no URL is provided, it will use the current `window.location.href`.\n\t *\n\t * @example\n\t * ```ts\n\t * // create a deep link to the current page + viewport\n\t * navigator.clipboard.writeText(editor.createDeepLink())\n\t * ```\n\t *\n\t * You can link to a particular set of shapes by providing a `to` parameter.\n\t *\n\t * @example\n\t * ```ts\n\t * // create a deep link to the set of currently selected shapes\n\t * navigator.clipboard.writeText(editor.createDeepLink({\n\t * to: { type: 'selection', shapeIds: editor.getSelectedShapeIds() }\n\t * }))\n\t * ```\n\t *\n\t * The default query param is 'd'. You can override this by providing a `param` parameter.\n\t *\n\t * @example\n\t * ```ts\n\t * // Use `x` as the param name instead\n\t * editor.createDeepLink({ param: 'x' })\n\t * ```\n\t *\n\t * @param opts - Options for adding the state to the URL.\n\t * @returns the updated URL\n\t */\n\tcreateDeepLink(opts?: { url?: string | URL; param?: string; to?: TLDeepLink }): URL {\n\t\tconst url = new URL(opts?.url ?? window.location.href)\n\n\t\turl.searchParams.set(\n\t\t\topts?.param ?? 'd',\n\t\t\tcreateDeepLinkString(\n\t\t\t\topts?.to ?? {\n\t\t\t\t\ttype: 'viewport',\n\t\t\t\t\tpageId: this.options.maxPages === 1 ? undefined : this.getCurrentPageId(),\n\t\t\t\t\tbounds: this.getViewportPageBounds(),\n\t\t\t\t}\n\t\t\t)\n\t\t)\n\n\t\treturn url\n\t}\n\n\t/**\n\t * Register a listener for changes to a deep link for the current document.\n\t *\n\t * You'll typically want to use this indirectly via the {@link TldrawEditorBaseProps.deepLinks} prop on the `` component.\n\t *\n\t * By default this will update `window.location` in place, but you can provide a custom callback\n\t * to handle state changes on your own.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.registerDeepLinkListener({\n\t * onChange(url) {\n\t * window.history.replaceState({}, document.title, url.toString())\n\t * }\n\t * })\n\t * ```\n\t *\n\t * You can also provide a custom URL to update, in which case you must also provide `onChange`.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.registerDeepLinkListener({\n\t * getUrl: () => `https://my-app.com/my-document`,\n\t * onChange(url) {\n\t * setShareUrl(url.toString())\n\t * }\n\t * })\n\t * ```\n\t *\n\t * By default this will update with a debounce interval of 500ms, but you can provide a custom interval.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.registerDeepLinkListener({ debounceMs: 1000 })\n\t * ```\n\t * The default parameter name is `d`. You can override this by providing a `param` option.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.registerDeepLinkListener({ param: 'x' })\n\t * ```\n\t * @param opts - Options for setting up the listener.\n\t * @returns a function that will stop the listener.\n\t */\n\tregisterDeepLinkListener(opts?: TLDeepLinkOptions): () => void {\n\t\tif (opts?.getUrl && !opts?.onChange) {\n\t\t\tthrow Error(\n\t\t\t\t'[tldraw:urlStateSync] If you specify getUrl, you must also specify the onChange callback.'\n\t\t\t)\n\t\t}\n\n\t\tconst url$ = computed('url with state', () => {\n\t\t\tconst url = opts?.getUrl?.(this) ?? window.location.href\n\t\t\tconst urlWithState = this.createDeepLink({\n\t\t\t\tparam: opts?.param,\n\t\t\t\turl,\n\t\t\t\tto: opts?.getTarget?.(this),\n\t\t\t})\n\t\t\treturn urlWithState.toString()\n\t\t})\n\n\t\tconst announceChange =\n\t\t\topts?.onChange ??\n\t\t\t(() => {\n\t\t\t\tconst url = this.createDeepLink({\n\t\t\t\t\tparam: opts?.param,\n\t\t\t\t\tto: opts?.getTarget?.(this),\n\t\t\t\t})\n\n\t\t\t\twindow.history.replaceState({}, document.title, url.toString())\n\t\t\t})\n\n\t\tconst scheduleEffect = debounce((execute: () => void) => execute(), opts?.debounceMs ?? 500)\n\n\t\tconst unlisten = react(\n\t\t\t'update url on state change',\n\t\t\t() => announceChange(new URL(url$.get()), this),\n\t\t\t{ scheduleEffect }\n\t\t)\n\n\t\treturn () => {\n\t\t\tunlisten()\n\t\t\tscheduleEffect.cancel()\n\t\t}\n\t}\n\n\t/**\n\t * A manager for recording multiple click events.\n\t *\n\t * @internal\n\t */\n\tprotected _clickManager = new ClickManager(this)\n\n\t/**\n\t * Prevent a double click event from firing the next time the user clicks\n\t *\n\t * @public\n\t */\n\tcancelDoubleClick() {\n\t\tthis._clickManager.cancelDoubleClickTimeout()\n\t}\n\n\t/**\n\t * The previous cursor. Used for restoring the cursor after pan events.\n\t *\n\t * @internal\n\t */\n\tprivate _prevCursor: TLCursorType = 'default'\n\n\t/** @internal */\n\tprivate _shiftKeyTimeout = -1 as any\n\n\t/** @internal */\n\t@bind\n\t_setShiftKeyTimeout() {\n\t\tthis.inputs.shiftKey = false\n\t\tthis.dispatch({\n\t\t\ttype: 'keyboard',\n\t\t\tname: 'key_up',\n\t\t\tkey: 'Shift',\n\t\t\tshiftKey: this.inputs.shiftKey,\n\t\t\tctrlKey: this.inputs.ctrlKey,\n\t\t\taltKey: this.inputs.altKey,\n\t\t\tcode: 'ShiftLeft',\n\t\t})\n\t}\n\n\t/** @internal */\n\tprivate _altKeyTimeout = -1 as any\n\n\t/** @internal */\n\t@bind\n\t_setAltKeyTimeout() {\n\t\tthis.inputs.altKey = false\n\t\tthis.dispatch({\n\t\t\ttype: 'keyboard',\n\t\t\tname: 'key_up',\n\t\t\tkey: 'Alt',\n\t\t\tshiftKey: this.inputs.shiftKey,\n\t\t\tctrlKey: this.inputs.ctrlKey,\n\t\t\taltKey: this.inputs.altKey,\n\t\t\tcode: 'AltLeft',\n\t\t})\n\t}\n\n\t/** @internal */\n\tprivate _ctrlKeyTimeout = -1 as any\n\n\t/** @internal */\n\t@bind\n\t_setCtrlKeyTimeout() {\n\t\tthis.inputs.ctrlKey = false\n\t\tthis.dispatch({\n\t\t\ttype: 'keyboard',\n\t\t\tname: 'key_up',\n\t\t\tkey: 'Ctrl',\n\t\t\tshiftKey: this.inputs.shiftKey,\n\t\t\tctrlKey: this.inputs.ctrlKey,\n\t\t\taltKey: this.inputs.altKey,\n\t\t\tcode: 'ControlLeft',\n\t\t})\n\t}\n\n\t/** @internal */\n\tprivate _restoreToolId = 'select'\n\n\t/** @internal */\n\tprivate _pinchStart = 1\n\n\t/** @internal */\n\tprivate _didPinch = false\n\n\t/** @internal */\n\tprivate _selectedShapeIdsAtPointerDown: TLShapeId[] = []\n\n\t/** @internal */\n\tprivate _longPressTimeout = -1 as any\n\n\t/** @internal */\n\tcapturedPointerId: number | null = null\n\n\t/** @internal */\n\tprivate readonly performanceTracker: PerformanceTracker\n\n\t/** @internal */\n\tprivate performanceTrackerTimeout = -1 as any\n\n\t/**\n\t * Dispatch an event to the editor.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.dispatch(myPointerEvent)\n\t * ```\n\t *\n\t * @param info - The event info.\n\t *\n\t * @public\n\t */\n\tdispatch(info: TLEventInfo) {\n\t\tthis._pendingEventsForNextTick.push(info)\n\t\tif (\n\t\t\t!(\n\t\t\t\t(info.type === 'pointer' && info.name === 'pointer_move') ||\n\t\t\t\tinfo.type === 'wheel' ||\n\t\t\t\tinfo.type === 'pinch'\n\t\t\t)\n\t\t) {\n\t\t\tthis._flushEventsForTick(0)\n\t\t}\n\t\treturn this\n\t}\n\n\tprivate _pendingEventsForNextTick: TLEventInfo[] = []\n\n\tprivate _flushEventsForTick(elapsed: number) {\n\t\tthis.run(() => {\n\t\t\tif (this._pendingEventsForNextTick.length > 0) {\n\t\t\t\tconst events = [...this._pendingEventsForNextTick]\n\t\t\t\tthis._pendingEventsForNextTick.length = 0\n\t\t\t\tfor (const info of events) {\n\t\t\t\t\tthis._flushEventForTick(info)\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (elapsed > 0) {\n\t\t\t\tthis.root.handleEvent({ type: 'misc', name: 'tick', elapsed })\n\t\t\t}\n\t\t\tthis.scribbles.tick(elapsed)\n\t\t})\n\t}\n\n\t_flushEventForTick(info: TLEventInfo) {\n\t\t// prevent us from spamming similar event errors if we're crashed.\n\t\t// todo: replace with new readonly mode?\n\t\tif (this.getCrashingError()) return this\n\n\t\tconst { inputs } = this\n\t\tconst { type } = info\n\n\t\tif (info.type === 'misc') {\n\t\t\t// stop panning if the interaction is cancelled or completed\n\t\t\tif (info.name === 'cancel' || info.name === 'complete') {\n\t\t\t\tthis.inputs.isDragging = false\n\n\t\t\t\tif (this.inputs.isPanning) {\n\t\t\t\t\tthis.inputs.isPanning = false\n\t\t\t\t\tthis.inputs.isSpacebarPanning = false\n\t\t\t\t\tthis.setCursor({ type: this._prevCursor, rotation: 0 })\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tthis.root.handleEvent(info)\n\t\t\treturn\n\t\t}\n\n\t\tif (info.shiftKey) {\n\t\t\tclearTimeout(this._shiftKeyTimeout)\n\t\t\tthis._shiftKeyTimeout = -1\n\t\t\tinputs.shiftKey = true\n\t\t} else if (!info.shiftKey && inputs.shiftKey && this._shiftKeyTimeout === -1) {\n\t\t\tthis._shiftKeyTimeout = this.timers.setTimeout(this._setShiftKeyTimeout, 150)\n\t\t}\n\n\t\tif (info.altKey) {\n\t\t\tclearTimeout(this._altKeyTimeout)\n\t\t\tthis._altKeyTimeout = -1\n\t\t\tinputs.altKey = true\n\t\t} else if (!info.altKey && inputs.altKey && this._altKeyTimeout === -1) {\n\t\t\tthis._altKeyTimeout = this.timers.setTimeout(this._setAltKeyTimeout, 150)\n\t\t}\n\n\t\tif (info.ctrlKey) {\n\t\t\tclearTimeout(this._ctrlKeyTimeout)\n\t\t\tthis._ctrlKeyTimeout = -1\n\t\t\tinputs.ctrlKey = true\n\t\t} else if (!info.ctrlKey && inputs.ctrlKey && this._ctrlKeyTimeout === -1) {\n\t\t\tthis._ctrlKeyTimeout = this.timers.setTimeout(this._setCtrlKeyTimeout, 150)\n\t\t}\n\n\t\tconst { originPagePoint, currentPagePoint } = inputs\n\n\t\tif (!inputs.isPointing) {\n\t\t\tinputs.isDragging = false\n\t\t}\n\n\t\tconst instanceState = this.store.unsafeGetWithoutCapture(TLINSTANCE_ID)!\n\t\tconst pageState = this.store.get(this._getCurrentPageStateId())!\n\t\tconst cameraOptions = this._cameraOptions.__unsafe__getWithoutCapture()!\n\n\t\tswitch (type) {\n\t\t\tcase 'pinch': {\n\t\t\t\tif (cameraOptions.isLocked) return\n\t\t\t\tclearTimeout(this._longPressTimeout)\n\t\t\t\tthis._updateInputsFromEvent(info)\n\n\t\t\t\tswitch (info.name) {\n\t\t\t\t\tcase 'pinch_start': {\n\t\t\t\t\t\tif (inputs.isPinching) return\n\n\t\t\t\t\t\tif (!inputs.isEditing) {\n\t\t\t\t\t\t\tthis._pinchStart = this.getCamera().z\n\t\t\t\t\t\t\tif (!this._selectedShapeIdsAtPointerDown.length) {\n\t\t\t\t\t\t\t\tthis._selectedShapeIdsAtPointerDown = [...pageState.selectedShapeIds]\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tthis._didPinch = true\n\n\t\t\t\t\t\t\tinputs.isPinching = true\n\n\t\t\t\t\t\t\tthis.interrupt()\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\treturn // Stop here!\n\t\t\t\t\t}\n\t\t\t\t\tcase 'pinch': {\n\t\t\t\t\t\tif (!inputs.isPinching) return\n\n\t\t\t\t\t\tconst {\n\t\t\t\t\t\t\tpoint: { z = 1 },\n\t\t\t\t\t\t\tdelta: { x: dx, y: dy },\n\t\t\t\t\t\t} = info\n\n\t\t\t\t\t\t// The center of the pinch in screen space\n\t\t\t\t\t\tconst { x, y } = Vec.SubXY(\n\t\t\t\t\t\t\tinfo.point,\n\t\t\t\t\t\t\tinstanceState.screenBounds.x,\n\t\t\t\t\t\t\tinstanceState.screenBounds.y\n\t\t\t\t\t\t)\n\n\t\t\t\t\t\tthis.stopCameraAnimation()\n\t\t\t\t\t\tif (instanceState.followingUserId) {\n\t\t\t\t\t\t\tthis.stopFollowingUser()\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst { x: cx, y: cy, z: cz } = unsafe__withoutCapture(() => this.getCamera())\n\n\t\t\t\t\t\tconst { panSpeed, zoomSpeed } = cameraOptions\n\t\t\t\t\t\tthis._setCamera(\n\t\t\t\t\t\t\tnew Vec(\n\t\t\t\t\t\t\t\tcx + (dx * panSpeed) / cz - x / cz + x / (z * zoomSpeed),\n\t\t\t\t\t\t\t\tcy + (dy * panSpeed) / cz - y / cz + y / (z * zoomSpeed),\n\t\t\t\t\t\t\t\tz * zoomSpeed\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t{ immediate: true }\n\t\t\t\t\t\t)\n\n\t\t\t\t\t\treturn // Stop here!\n\t\t\t\t\t}\n\t\t\t\t\tcase 'pinch_end': {\n\t\t\t\t\t\tif (!inputs.isPinching) return this\n\n\t\t\t\t\t\t// Stop pinching\n\t\t\t\t\t\tinputs.isPinching = false\n\n\t\t\t\t\t\t// Stash and clear the shapes that were selected when the pinch started\n\t\t\t\t\t\tconst { _selectedShapeIdsAtPointerDown: shapesToReselect } = this\n\t\t\t\t\t\tthis.setSelectedShapes(this._selectedShapeIdsAtPointerDown)\n\t\t\t\t\t\tthis._selectedShapeIdsAtPointerDown = []\n\n\t\t\t\t\t\tif (this._didPinch) {\n\t\t\t\t\t\t\tthis._didPinch = false\n\t\t\t\t\t\t\tif (shapesToReselect.length > 0) {\n\t\t\t\t\t\t\t\tthis.once('tick', () => {\n\t\t\t\t\t\t\t\t\tif (!this._didPinch) {\n\t\t\t\t\t\t\t\t\t\t// Unless we've started pinching again...\n\t\t\t\t\t\t\t\t\t\t// Reselect the shapes that were selected when the pinch started\n\t\t\t\t\t\t\t\t\t\tthis.setSelectedShapes(shapesToReselect)\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\treturn // Stop here!\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tcase 'wheel': {\n\t\t\t\tif (cameraOptions.isLocked) return\n\n\t\t\t\tthis._updateInputsFromEvent(info)\n\n\t\t\t\tif (this.getIsMenuOpen()) {\n\t\t\t\t\t// noop\n\t\t\t\t} else {\n\t\t\t\t\tconst { panSpeed, zoomSpeed, wheelBehavior } = cameraOptions\n\n\t\t\t\t\tif (wheelBehavior !== 'none') {\n\t\t\t\t\t\t// Stop any camera animation\n\t\t\t\t\t\tthis.stopCameraAnimation()\n\t\t\t\t\t\t// Stop following any following user\n\t\t\t\t\t\tif (instanceState.followingUserId) {\n\t\t\t\t\t\t\tthis.stopFollowingUser()\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst { x: cx, y: cy, z: cz } = unsafe__withoutCapture(() => this.getCamera())\n\t\t\t\t\t\tconst { x: dx, y: dy, z: dz = 0 } = info.delta\n\n\t\t\t\t\t\tlet behavior = wheelBehavior\n\n\t\t\t\t\t\t// If the camera behavior is \"zoom\" and the ctrl key is pressed, then pan;\n\t\t\t\t\t\t// If the camera behavior is \"pan\" and the ctrl key is not pressed, then zoom\n\t\t\t\t\t\tif (inputs.ctrlKey) behavior = wheelBehavior === 'pan' ? 'zoom' : 'pan'\n\n\t\t\t\t\t\tswitch (behavior) {\n\t\t\t\t\t\t\tcase 'zoom': {\n\t\t\t\t\t\t\t\t// Zoom in on current screen point using the wheel delta\n\t\t\t\t\t\t\t\tconst { x, y } = this.inputs.currentScreenPoint\n\t\t\t\t\t\t\t\tlet delta = dz\n\n\t\t\t\t\t\t\t\t// If we're forcing zoom, then we need to do the wheel normalization math here\n\t\t\t\t\t\t\t\tif (wheelBehavior === 'zoom') {\n\t\t\t\t\t\t\t\t\tif (Math.abs(dy) > 10) {\n\t\t\t\t\t\t\t\t\t\tdelta = (10 * Math.sign(dy)) / 100\n\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\tdelta = dy / 100\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tconst zoom = cz + (delta ?? 0) * zoomSpeed * cz\n\t\t\t\t\t\t\t\tthis._setCamera(\n\t\t\t\t\t\t\t\t\tnew Vec(\n\t\t\t\t\t\t\t\t\t\tcx + (x / zoom - x) - (x / cz - x),\n\t\t\t\t\t\t\t\t\t\tcy + (y / zoom - y) - (y / cz - y),\n\t\t\t\t\t\t\t\t\t\tzoom\n\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t{ immediate: true }\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\tthis.maybeTrackPerformance('Zooming')\n\t\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tcase 'pan': {\n\t\t\t\t\t\t\t\t// Pan the camera based on the wheel delta\n\t\t\t\t\t\t\t\tthis._setCamera(new Vec(cx + (dx * panSpeed) / cz, cy + (dy * panSpeed) / cz, cz), {\n\t\t\t\t\t\t\t\t\timmediate: true,\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\tthis.maybeTrackPerformance('Panning')\n\t\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'pointer': {\n\t\t\t\t// Ignore pointer events while we're pinching\n\t\t\t\tif (inputs.isPinching) return\n\n\t\t\t\tthis._updateInputsFromEvent(info)\n\t\t\t\tconst { isPen } = info\n\t\t\t\tconst { isPenMode } = instanceState\n\n\t\t\t\tswitch (info.name) {\n\t\t\t\t\tcase 'pointer_down': {\n\t\t\t\t\t\t// If we're in pen mode and the input is not a pen type, then stop here\n\t\t\t\t\t\tif (isPenMode && !isPen) return\n\n\t\t\t\t\t\tif (!this.inputs.isPanning) {\n\t\t\t\t\t\t\t// Start a long press timeout\n\t\t\t\t\t\t\tthis._longPressTimeout = this.timers.setTimeout(() => {\n\t\t\t\t\t\t\t\tthis.dispatch({\n\t\t\t\t\t\t\t\t\t...info,\n\t\t\t\t\t\t\t\t\tpoint: this.inputs.currentScreenPoint,\n\t\t\t\t\t\t\t\t\tname: 'long_press',\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t}, this.options.longPressDurationMs)\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Save the selected ids at pointer down\n\t\t\t\t\t\tthis._selectedShapeIdsAtPointerDown = this.getSelectedShapeIds()\n\n\t\t\t\t\t\t// Firefox bug fix...\n\t\t\t\t\t\t// If it's a left-mouse-click, we store the pointer id for later user\n\t\t\t\t\t\tif (info.button === LEFT_MOUSE_BUTTON) this.capturedPointerId = info.pointerId\n\n\t\t\t\t\t\t// Add the button from the buttons set\n\t\t\t\t\t\tinputs.buttons.add(info.button)\n\n\t\t\t\t\t\t// Start pointing and stop dragging\n\t\t\t\t\t\tinputs.isPointing = true\n\t\t\t\t\t\tinputs.isDragging = false\n\n\t\t\t\t\t\t// If pen mode is off but we're not already in pen mode, turn that on\n\t\t\t\t\t\tif (!isPenMode && isPen) this.updateInstanceState({ isPenMode: true })\n\n\t\t\t\t\t\t// On devices with erasers (like the Surface Pen or Wacom Pen), button 5 is the eraser\n\t\t\t\t\t\tif (info.button === STYLUS_ERASER_BUTTON) {\n\t\t\t\t\t\t\tthis._restoreToolId = this.getCurrentToolId()\n\t\t\t\t\t\t\tthis.complete()\n\t\t\t\t\t\t\tthis.setCurrentTool('eraser')\n\t\t\t\t\t\t} else if (info.button === MIDDLE_MOUSE_BUTTON) {\n\t\t\t\t\t\t\t// Middle mouse pan activates panning unless we're already panning (with spacebar)\n\t\t\t\t\t\t\tif (!this.inputs.isPanning) {\n\t\t\t\t\t\t\t\tthis._prevCursor = this.getInstanceState().cursor.type\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tthis.inputs.isPanning = true\n\t\t\t\t\t\t\tclearTimeout(this._longPressTimeout)\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// We might be panning because we did a middle mouse click, or because we're holding spacebar and started a regular click\n\t\t\t\t\t\t// Also stop here, we don't want the state chart to receive the event\n\t\t\t\t\t\tif (this.inputs.isPanning) {\n\t\t\t\t\t\t\tthis.stopCameraAnimation()\n\t\t\t\t\t\t\tthis.setCursor({ type: 'grabbing', rotation: 0 })\n\t\t\t\t\t\t\treturn this\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t\tcase 'pointer_move': {\n\t\t\t\t\t\t// If the user is in pen mode, but the pointer is not a pen, stop here.\n\t\t\t\t\t\tif (!isPen && isPenMode) return\n\n\t\t\t\t\t\tconst { x: cx, y: cy, z: cz } = unsafe__withoutCapture(() => this.getCamera())\n\n\t\t\t\t\t\t// If we've started panning, then clear any long press timeout\n\t\t\t\t\t\tif (this.inputs.isPanning && this.inputs.isPointing) {\n\t\t\t\t\t\t\t// Handle spacebar / middle mouse button panning\n\t\t\t\t\t\t\tconst { currentScreenPoint, previousScreenPoint } = this.inputs\n\t\t\t\t\t\t\tconst { panSpeed } = cameraOptions\n\t\t\t\t\t\t\tconst offset = Vec.Sub(currentScreenPoint, previousScreenPoint)\n\t\t\t\t\t\t\tthis.setCamera(\n\t\t\t\t\t\t\t\tnew Vec(cx + (offset.x * panSpeed) / cz, cy + (offset.y * panSpeed) / cz, cz),\n\t\t\t\t\t\t\t\t{ immediate: true }\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\tthis.maybeTrackPerformance('Panning')\n\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\tinputs.isPointing &&\n\t\t\t\t\t\t\t!inputs.isDragging &&\n\t\t\t\t\t\t\tVec.Dist2(originPagePoint, currentPagePoint) * this.getZoomLevel() >\n\t\t\t\t\t\t\t\t(instanceState.isCoarsePointer\n\t\t\t\t\t\t\t\t\t? this.options.coarseDragDistanceSquared\n\t\t\t\t\t\t\t\t\t: this.options.dragDistanceSquared) /\n\t\t\t\t\t\t\t\t\tcz\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t// Start dragging\n\t\t\t\t\t\t\tinputs.isDragging = true\n\t\t\t\t\t\t\tclearTimeout(this._longPressTimeout)\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t\tcase 'pointer_up': {\n\t\t\t\t\t\t// Stop dragging / pointing\n\t\t\t\t\t\tinputs.isDragging = false\n\t\t\t\t\t\tinputs.isPointing = false\n\t\t\t\t\t\tclearTimeout(this._longPressTimeout)\n\n\t\t\t\t\t\t// Remove the button from the buttons set\n\t\t\t\t\t\tinputs.buttons.delete(info.button)\n\n\t\t\t\t\t\t// Suppressing pointerup here as doesn't seem to do what we what here.\n\t\t\t\t\t\tif (this.getIsMenuOpen()) return\n\n\t\t\t\t\t\t// If we're in pen mode and we're not using a pen, stop here\n\t\t\t\t\t\tif (instanceState.isPenMode && !isPen) return\n\n\t\t\t\t\t\t// Firefox bug fix...\n\t\t\t\t\t\t// If it's the same pointer that we stored earlier...\n\t\t\t\t\t\t// ... then it's probably still a left-mouse-click!\n\t\t\t\t\t\tif (this.capturedPointerId === info.pointerId) {\n\t\t\t\t\t\t\tthis.capturedPointerId = null\n\t\t\t\t\t\t\tinfo.button = 0\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (inputs.isPanning) {\n\t\t\t\t\t\t\tif (!inputs.keys.has('Space')) {\n\t\t\t\t\t\t\t\tinputs.isPanning = false\n\t\t\t\t\t\t\t\tinputs.isSpacebarPanning = false\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tconst slideDirection = this.inputs.pointerVelocity\n\t\t\t\t\t\t\tconst slideSpeed = Math.min(2, slideDirection.len())\n\n\t\t\t\t\t\t\tswitch (info.button) {\n\t\t\t\t\t\t\t\tcase LEFT_MOUSE_BUTTON: {\n\t\t\t\t\t\t\t\t\tthis.setCursor({ type: 'grab', rotation: 0 })\n\t\t\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tcase MIDDLE_MOUSE_BUTTON: {\n\t\t\t\t\t\t\t\t\tif (this.inputs.keys.has(' ')) {\n\t\t\t\t\t\t\t\t\t\tthis.setCursor({ type: 'grab', rotation: 0 })\n\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\tthis.setCursor({ type: this._prevCursor, rotation: 0 })\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif (slideSpeed > 0) {\n\t\t\t\t\t\t\t\tthis.slideCamera({ speed: slideSpeed, direction: slideDirection })\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tif (info.button === STYLUS_ERASER_BUTTON) {\n\t\t\t\t\t\t\t\t// If we were erasing with a stylus button, restore the tool we were using before we started erasing\n\t\t\t\t\t\t\t\tthis.complete()\n\t\t\t\t\t\t\t\tthis.setCurrentTool(this._restoreToolId)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'keyboard': {\n\t\t\t\t// please, please\n\t\t\t\tif (info.key === 'ShiftRight') info.key = 'ShiftLeft'\n\t\t\t\tif (info.key === 'AltRight') info.key = 'AltLeft'\n\t\t\t\tif (info.code === 'ControlRight') info.code = 'ControlLeft'\n\n\t\t\t\tswitch (info.name) {\n\t\t\t\t\tcase 'key_down': {\n\t\t\t\t\t\t// Add the key from the keys set\n\t\t\t\t\t\tinputs.keys.add(info.code)\n\n\t\t\t\t\t\t// If the space key is pressed (but meta / control isn't!) activate panning\n\t\t\t\t\t\tif (info.code === 'Space' && !info.ctrlKey) {\n\t\t\t\t\t\t\tif (!this.inputs.isPanning) {\n\t\t\t\t\t\t\t\tthis._prevCursor = instanceState.cursor.type\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tthis.inputs.isPanning = true\n\t\t\t\t\t\t\tthis.inputs.isSpacebarPanning = true\n\t\t\t\t\t\t\tclearTimeout(this._longPressTimeout)\n\t\t\t\t\t\t\tthis.setCursor({ type: this.inputs.isPointing ? 'grabbing' : 'grab', rotation: 0 })\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (this.inputs.isSpacebarPanning) {\n\t\t\t\t\t\t\tlet offset: Vec | undefined\n\t\t\t\t\t\t\tswitch (info.code) {\n\t\t\t\t\t\t\t\tcase 'ArrowUp': {\n\t\t\t\t\t\t\t\t\toffset = new Vec(0, -1)\n\t\t\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tcase 'ArrowRight': {\n\t\t\t\t\t\t\t\t\toffset = new Vec(1, 0)\n\t\t\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tcase 'ArrowDown': {\n\t\t\t\t\t\t\t\t\toffset = new Vec(0, 1)\n\t\t\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tcase 'ArrowLeft': {\n\t\t\t\t\t\t\t\t\toffset = new Vec(-1, 0)\n\t\t\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif (offset) {\n\t\t\t\t\t\t\t\tconst bounds = this.getViewportPageBounds()\n\t\t\t\t\t\t\t\tconst next = bounds.clone().translate(offset.mulV({ x: bounds.w, y: bounds.h }))\n\t\t\t\t\t\t\t\tthis._animateToViewport(next, { animation: { duration: 320 } })\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t\tcase 'key_up': {\n\t\t\t\t\t\t// Remove the key from the keys set\n\t\t\t\t\t\tinputs.keys.delete(info.code)\n\n\t\t\t\t\t\t// If we've lifted the space key,\n\t\t\t\t\t\tif (info.code === 'Space') {\n\t\t\t\t\t\t\tif (this.inputs.buttons.has(MIDDLE_MOUSE_BUTTON)) {\n\t\t\t\t\t\t\t\t// If we're still middle dragging, continue panning\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t// otherwise, stop panning\n\t\t\t\t\t\t\t\tthis.inputs.isPanning = false\n\t\t\t\t\t\t\t\tthis.inputs.isSpacebarPanning = false\n\t\t\t\t\t\t\t\tthis.setCursor({ type: this._prevCursor, rotation: 0 })\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t\tcase 'key_repeat': {\n\t\t\t\t\t\t// noop\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\n\t\t// Correct the info name for right / middle clicks\n\t\tif (info.type === 'pointer') {\n\t\t\tif (info.button === MIDDLE_MOUSE_BUTTON) {\n\t\t\t\tinfo.name = 'middle_click'\n\t\t\t} else if (info.button === RIGHT_MOUSE_BUTTON) {\n\t\t\t\tinfo.name = 'right_click'\n\t\t\t}\n\n\t\t\t// If a left click pointer event, send the event to the click manager.\n\t\t\tconst { isPenMode } = this.store.unsafeGetWithoutCapture(TLINSTANCE_ID)!\n\t\t\tif (info.isPen === isPenMode) {\n\t\t\t\t// The click manager may return a new event, i.e. a double click event\n\t\t\t\t// depending on the event coming in and its own state. If the event has\n\t\t\t\t// changed then hand both events to the statechart\n\t\t\t\tconst clickInfo = this._clickManager.handlePointerEvent(info)\n\t\t\t\tif (info.name !== clickInfo.name) {\n\t\t\t\t\tthis.root.handleEvent(info)\n\t\t\t\t\tthis.emit('event', info)\n\t\t\t\t\tthis.root.handleEvent(clickInfo)\n\t\t\t\t\tthis.emit('event', clickInfo)\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Send the event to the statechart. It will be handled by all\n\t\t// active states, starting at the root.\n\t\tthis.root.handleEvent(info)\n\t\tthis.emit('event', info)\n\n\t\t// close open menus at the very end on pointer down! after everything else! \u03C3\u03C5\u03BD\u03C4\u03B5\u03BB\u03B5\u03AF\u03B1\u03C2 \u03C4\u03BF\u1FE6 \u03BA\u03CE\u03B4\u03B9\u03BA\u03B1!!\n\t\tif (info.type === 'pointer' && info.name === 'pointer_down') {\n\t\t\tthis.clearOpenMenus()\n\t\t}\n\n\t\treturn this\n\t}\n\n\t/** @internal */\n\tprivate maybeTrackPerformance(name: string) {\n\t\tif (debugFlags.measurePerformance.get()) {\n\t\t\tif (this.performanceTracker.isStarted()) {\n\t\t\t\tclearTimeout(this.performanceTrackerTimeout)\n\t\t\t} else {\n\t\t\t\tthis.performanceTracker.start(name)\n\t\t\t}\n\t\t\tthis.performanceTrackerTimeout = this.timers.setTimeout(() => {\n\t\t\t\tthis.performanceTracker.stop()\n\t\t\t}, 50)\n\t\t}\n\t}\n}\n\nfunction alertMaxShapes(editor: Editor, pageId = editor.getCurrentPageId()) {\n\tconst name = editor.getPage(pageId)!.name\n\teditor.emit('max-shapes', { name, pageId, count: editor.options.maxShapesPerPage })\n}\n\nfunction applyPartialToRecordWithProps<\n\tT extends UnknownRecord & { type: string; props: object; meta: object },\n>(prev: T, partial?: Partial & { props?: Partial }): T {\n\tif (!partial) return prev\n\tlet next = null as null | T\n\tconst entries = Object.entries(partial)\n\tfor (let i = 0, n = entries.length; i < n; i++) {\n\t\tconst [k, v] = entries[i]\n\t\tif (v === undefined) continue\n\n\t\t// Is the key a special key? We don't update those\n\t\tif (k === 'id' || k === 'type' || k === 'typeName') continue\n\n\t\t// Is the value the same as it was before?\n\t\tif (v === (prev as any)[k]) continue\n\n\t\t// There's a new value, so create the new shape if we haven't already (should we be cloning this?)\n\t\tif (!next) next = { ...prev }\n\n\t\t// for props / meta properties, we support updates with partials of this object\n\t\tif (k === 'props' || k === 'meta') {\n\t\t\tnext[k] = { ...prev[k] } as JsonObject\n\t\t\tfor (const [nextKey, nextValue] of Object.entries(v as object)) {\n\t\t\t\tif (nextValue !== undefined) {\n\t\t\t\t\t;(next[k] as JsonObject)[nextKey] = nextValue\n\t\t\t\t}\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\n\t\t// base property\n\t\t;(next as any)[k] = v\n\t}\n\tif (!next) return prev\n\treturn next\n}\n\nfunction pushShapeWithDescendants(editor: Editor, id: TLShapeId, result: TLShape[]): void {\n\tconst shape = editor.getShape(id)\n\tif (!shape) return\n\tresult.push(shape)\n\tconst childIds = editor.getSortedChildIdsForParent(id)\n\tfor (let i = 0, n = childIds.length; i < n; i++) {\n\t\tpushShapeWithDescendants(editor, childIds[i], result)\n\t}\n}\n\n/**\n * Run `callback` in a world where all bindings from the shapes in `shapeIds` to shapes not in\n * `shapeIds` are removed. This is useful when you want to duplicate/copy shapes without worrying\n * about bindings that might be pointing to shapes that are not being duplicated.\n *\n * The callback is given the set of bindings that should be maintained.\n */\nfunction withIsolatedShapes(\n\teditor: Editor,\n\tshapeIds: Set,\n\tcallback: (bindingsWithBoth: Set) => T\n): T {\n\tlet result!: Result\n\n\teditor.run(\n\t\t() => {\n\t\t\tconst changes = editor.store.extractingChanges(() => {\n\t\t\t\tconst bindingsWithBoth = new Set()\n\t\t\t\tconst bindingsToRemove = new Set()\n\n\t\t\t\tfor (const shapeId of shapeIds) {\n\t\t\t\t\tconst shape = editor.getShape(shapeId)\n\t\t\t\t\tif (!shape) continue\n\n\t\t\t\t\tfor (const binding of editor.getBindingsInvolvingShape(shapeId)) {\n\t\t\t\t\t\tconst hasFrom = shapeIds.has(binding.fromId)\n\t\t\t\t\t\tconst hasTo = shapeIds.has(binding.toId)\n\t\t\t\t\t\tif (hasFrom && hasTo) {\n\t\t\t\t\t\t\tbindingsWithBoth.add(binding.id)\n\t\t\t\t\t\t\tcontinue\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (!hasFrom || !hasTo) {\n\t\t\t\t\t\t\tbindingsToRemove.add(binding.id)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\teditor.deleteBindings([...bindingsToRemove], { isolateShapes: true })\n\n\t\t\t\ttry {\n\t\t\t\t\tresult = Result.ok(callback(bindingsWithBoth))\n\t\t\t\t} catch (error) {\n\t\t\t\t\tresult = Result.err(error)\n\t\t\t\t}\n\t\t\t})\n\n\t\t\teditor.store.applyDiff(reverseRecordsDiff(changes))\n\t\t},\n\t\t{ history: 'ignore' }\n\t)\n\n\tif (result.ok) {\n\t\treturn result.value\n\t} else {\n\t\tthrow result.error\n\t}\n}\n\nfunction getCameraFitXFitY(editor: Editor, cameraOptions: TLCameraOptions) {\n\tif (!cameraOptions.constraints) throw Error('Should have constraints here')\n\tconst {\n\t\tpadding: { x: px, y: py },\n\t} = cameraOptions.constraints\n\tconst vsb = editor.getViewportScreenBounds()\n\tconst bounds = Box.From(cameraOptions.constraints.bounds)\n\tconst zx = (vsb.w - px * 2) / bounds.w\n\tconst zy = (vsb.h - py * 2) / bounds.h\n\treturn { zx, zy }\n}\n"], -- "mappings": "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", -+ "sourcesContent": ["import { EMPTY_ARRAY, atom, computed, react, transact, unsafe__withoutCapture } from '@tldraw/state'\nimport {\n\tComputedCache,\n\tRecordType,\n\tStoreSideEffects,\n\tStoreSnapshot,\n\tUnknownRecord,\n\treverseRecordsDiff,\n} from '@tldraw/store'\nimport {\n\tCameraRecordType,\n\tInstancePageStateRecordType,\n\tPageRecordType,\n\tStyleProp,\n\tStylePropValue,\n\tTLArrowShape,\n\tTLAsset,\n\tTLAssetId,\n\tTLAssetPartial,\n\tTLBinding,\n\tTLBindingCreate,\n\tTLBindingId,\n\tTLBindingUpdate,\n\tTLCamera,\n\tTLCursor,\n\tTLCursorType,\n\tTLDOCUMENT_ID,\n\tTLDocument,\n\tTLFrameShape,\n\tTLGeoShape,\n\tTLGroupShape,\n\tTLHandle,\n\tTLINSTANCE_ID,\n\tTLImageAsset,\n\tTLInstance,\n\tTLInstancePageState,\n\tTLPOINTER_ID,\n\tTLPage,\n\tTLPageId,\n\tTLParentId,\n\tTLRecord,\n\tTLShape,\n\tTLShapeId,\n\tTLShapePartial,\n\tTLStore,\n\tTLStoreSnapshot,\n\tTLUnknownBinding,\n\tTLUnknownShape,\n\tTLVideoAsset,\n\tcreateBindingId,\n\tcreateShapeId,\n\tgetShapePropKeysByStyle,\n\tisPageId,\n\tisShapeId,\n} from '@tldraw/tlschema'\nimport {\n\tFileHelpers,\n\tIndexKey,\n\tJsonObject,\n\tPerformanceTracker,\n\tResult,\n\tTimers,\n\tannotateError,\n\tassert,\n\tassertExists,\n\tbind,\n\tcompact,\n\tdebounce,\n\tdedupe,\n\texhaustiveSwitchError,\n\tfetch,\n\tgetIndexAbove,\n\tgetIndexBetween,\n\tgetIndices,\n\tgetIndicesAbove,\n\tgetIndicesBetween,\n\tgetOwnProperty,\n\thasOwnProperty,\n\tlast,\n\tlerp,\n\tsortById,\n\tsortByIndex,\n\tstructuredClone,\n\tuniqueId,\n} from '@tldraw/utils'\nimport EventEmitter from 'eventemitter3'\nimport {\n\tTLEditorSnapshot,\n\tTLLoadSnapshotOptions,\n\tgetSnapshot,\n\tloadSnapshot,\n} from '../config/TLEditorSnapshot'\nimport { TLUser, createTLUser } from '../config/createTLUser'\nimport { TLAnyBindingUtilConstructor, checkBindings } from '../config/defaultBindings'\nimport { TLAnyShapeUtilConstructor, checkShapesAndAddCore } from '../config/defaultShapes'\nimport {\n\tDEFAULT_ANIMATION_OPTIONS,\n\tDEFAULT_CAMERA_OPTIONS,\n\tINTERNAL_POINTER_IDS,\n\tLEFT_MOUSE_BUTTON,\n\tMIDDLE_MOUSE_BUTTON,\n\tRIGHT_MOUSE_BUTTON,\n\tSTYLUS_ERASER_BUTTON,\n\tZOOM_TO_FIT_PADDING,\n} from '../constants'\nimport { exportToSvg } from '../exports/exportToSvg'\nimport { TldrawOptions, defaultTldrawOptions } from '../options'\nimport { Box, BoxLike } from '../primitives/Box'\nimport { Mat, MatLike } from '../primitives/Mat'\nimport { Vec, VecLike } from '../primitives/Vec'\nimport { EASINGS } from '../primitives/easings'\nimport { Geometry2d } from '../primitives/geometry/Geometry2d'\nimport { Group2d } from '../primitives/geometry/Group2d'\nimport { intersectPolygonPolygon } from '../primitives/intersect'\nimport { PI2, approximately, areAnglesCompatible, clamp, pointInPolygon } from '../primitives/utils'\nimport { ReadonlySharedStyleMap, SharedStyle, SharedStyleMap } from '../utils/SharedStylesMap'\nimport { dataUrlToFile } from '../utils/assets'\nimport { debugFlags } from '../utils/debug-flags'\nimport {\n\tTLDeepLink,\n\tTLDeepLinkOptions,\n\tcreateDeepLinkString,\n\tparseDeepLinkString,\n} from '../utils/deepLinks'\nimport { getIncrementedName } from '../utils/getIncrementedName'\nimport { getReorderingShapesChanges } from '../utils/reorderShapes'\nimport { applyRotationToSnapshotShapes, getRotationSnapshot } from '../utils/rotation'\nimport { BindingOnDeleteOptions, BindingUtil } from './bindings/BindingUtil'\nimport { bindingsIndex } from './derivations/bindingsIndex'\nimport { notVisibleShapes } from './derivations/notVisibleShapes'\nimport { parentsToChildren } from './derivations/parentsToChildren'\nimport { deriveShapeIdsInCurrentPage } from './derivations/shapeIdsInCurrentPage'\nimport { ClickManager } from './managers/ClickManager'\nimport { EdgeScrollManager } from './managers/EdgeScrollManager'\nimport { EnvironmentManager } from './managers/EnvironmentManager'\nimport { FocusManager } from './managers/FocusManager'\nimport { HistoryManager } from './managers/HistoryManager'\nimport { ScribbleManager } from './managers/ScribbleManager'\nimport { SnapManager } from './managers/SnapManager/SnapManager'\nimport { TextManager } from './managers/TextManager'\nimport { TickManager } from './managers/TickManager'\nimport { UserPreferencesManager } from './managers/UserPreferencesManager'\nimport { ShapeUtil, TLResizeMode } from './shapes/ShapeUtil'\nimport { RootState } from './tools/RootState'\nimport { StateNode, TLStateNodeConstructor } from './tools/StateNode'\nimport { TLContent } from './types/clipboard-types'\nimport { TLEventMap } from './types/emit-types'\nimport {\n\tTLEventInfo,\n\tTLPinchEventInfo,\n\tTLPointerEventInfo,\n\tTLWheelEventInfo,\n} from './types/event-types'\nimport { TLExternalAssetContent, TLExternalContent } from './types/external-content'\nimport { TLHistoryBatchOptions } from './types/history-types'\nimport {\n\tOptionalKeys,\n\tRequiredKeys,\n\tTLCameraMoveOptions,\n\tTLCameraOptions,\n\tTLImageExportOptions,\n} from './types/misc-types'\nimport { TLResizeHandle } from './types/selection-types'\n\n/** @public */\nexport type TLResizeShapeOptions = Partial<{\n\tinitialBounds: Box\n\tscaleOrigin: VecLike\n\tscaleAxisRotation: number\n\tinitialShape: TLShape\n\tinitialPageTransform: MatLike\n\tdragHandle: TLResizeHandle\n\tisAspectRatioLocked: boolean\n\tmode: TLResizeMode\n\tskipStartAndEndCallbacks: boolean\n}>\n\n/** @public */\nexport interface TLEditorOptions {\n\t/**\n\t * The Store instance to use for keeping the app's data. This may be prepopulated, e.g. by loading\n\t * from a server or database.\n\t */\n\tstore: TLStore\n\t/**\n\t * An array of shapes to use in the editor. These will be used to create and manage shapes in the editor.\n\t */\n\tshapeUtils: readonly TLAnyShapeUtilConstructor[]\n\t/**\n\t * An array of bindings to use in the editor. These will be used to create and manage bindings in the editor.\n\t */\n\tbindingUtils: readonly TLAnyBindingUtilConstructor[]\n\t/**\n\t * An array of tools to use in the editor. These will be used to handle events and manage user interactions in the editor.\n\t */\n\ttools: readonly TLStateNodeConstructor[]\n\t/**\n\t * Should return a containing html element which has all the styles applied to the editor. If not\n\t * given, the body element will be used.\n\t */\n\tgetContainer(): HTMLElement\n\t/**\n\t * A user defined externally to replace the default user.\n\t */\n\tuser?: TLUser\n\t/**\n\t * The editor's initial active tool (or other state node id).\n\t */\n\tinitialState?: string\n\t/**\n\t * Whether to automatically focus the editor when it mounts.\n\t */\n\tautoFocus?: boolean\n\t/**\n\t * Whether to infer dark mode from the user's system preferences. Defaults to false.\n\t */\n\tinferDarkMode?: boolean\n\t/**\n\t * Options for the editor's camera.\n\t */\n\tcameraOptions?: Partial\n\toptions?: Partial\n\tlicenseKey?: string\n\t/**\n\t * A predicate that should return true if the given shape should be hidden.\n\t * @param shape - The shape to check.\n\t * @param editor - The editor instance.\n\t */\n\tisShapeHidden?(shape: TLShape, editor: Editor): boolean\n}\n\n/**\n * Options for {@link Editor.(run:1)}.\n * @public\n */\nexport interface TLEditorRunOptions extends TLHistoryBatchOptions {\n\tignoreShapeLock?: boolean\n}\n\n/** @public */\nexport interface TLRenderingShape {\n\tid: TLShapeId\n\tshape: TLShape\n\tutil: ShapeUtil\n\tindex: number\n\tbackgroundIndex: number\n\topacity: number\n}\n\n/** @public */\nexport class Editor extends EventEmitter {\n\tconstructor({\n\t\tstore,\n\t\tuser,\n\t\tshapeUtils,\n\t\tbindingUtils,\n\t\ttools,\n\t\tgetContainer,\n\t\tcameraOptions,\n\t\tinitialState,\n\t\tautoFocus,\n\t\tinferDarkMode,\n\t\toptions,\n\t\tisShapeHidden,\n\t}: TLEditorOptions) {\n\t\tsuper()\n\n\t\tthis._isShapeHiddenPredicate = isShapeHidden\n\n\t\tthis.options = { ...defaultTldrawOptions, ...options }\n\t\tthis.store = store\n\t\tthis.disposables.add(this.store.dispose.bind(this.store))\n\t\tthis.history = new HistoryManager({\n\t\t\tstore,\n\t\t\tannotateError: (error) => {\n\t\t\t\tthis.annotateError(error, { origin: 'history.batch', willCrashApp: true })\n\t\t\t\tthis.crash(error)\n\t\t\t},\n\t\t})\n\n\t\tthis.snaps = new SnapManager(this)\n\n\t\tthis.timers = new Timers()\n\t\tthis.disposables.add(this.timers.dispose.bind(this.timers))\n\n\t\tthis._cameraOptions.set({ ...DEFAULT_CAMERA_OPTIONS, ...cameraOptions })\n\n\t\tthis.user = new UserPreferencesManager(user ?? createTLUser(), inferDarkMode ?? false)\n\n\t\tthis.getContainer = getContainer\n\n\t\tthis.textMeasure = new TextManager(this)\n\t\tthis._tickManager = new TickManager(this)\n\n\t\tclass NewRoot extends RootState {\n\t\t\tstatic override initial = initialState ?? ''\n\t\t}\n\n\t\tthis.root = new NewRoot(this)\n\t\tthis.root.children = {}\n\n\t\tconst allShapeUtils = checkShapesAndAddCore(shapeUtils)\n\n\t\tconst _shapeUtils = {} as Record>\n\t\tconst _styleProps = {} as Record, string>>\n\t\tconst allStylesById = new Map>()\n\n\t\tfor (const Util of allShapeUtils) {\n\t\t\tconst util = new Util(this)\n\t\t\t_shapeUtils[Util.type] = util\n\n\t\t\tconst propKeysByStyle = getShapePropKeysByStyle(Util.props ?? {})\n\t\t\t_styleProps[Util.type] = propKeysByStyle\n\n\t\t\tfor (const style of propKeysByStyle.keys()) {\n\t\t\t\tif (!allStylesById.has(style.id)) {\n\t\t\t\t\tallStylesById.set(style.id, style)\n\t\t\t\t} else if (allStylesById.get(style.id) !== style) {\n\t\t\t\t\tthrow Error(\n\t\t\t\t\t\t`Multiple style props with id \"${style.id}\" in use. Style prop IDs must be unique.`\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tthis.shapeUtils = _shapeUtils\n\t\tthis.styleProps = _styleProps\n\n\t\tconst allBindingUtils = checkBindings(bindingUtils)\n\t\tconst _bindingUtils = {} as Record>\n\t\tfor (const Util of allBindingUtils) {\n\t\t\tconst util = new Util(this)\n\t\t\t_bindingUtils[Util.type] = util\n\t\t}\n\t\tthis.bindingUtils = _bindingUtils\n\n\t\t// Tools.\n\t\t// Accept tools from constructor parameters which may not conflict with the root note's default or\n\t\t// \"baked in\" tools, select and zoom.\n\t\tfor (const Tool of [...tools]) {\n\t\t\tif (hasOwnProperty(this.root.children!, Tool.id)) {\n\t\t\t\tthrow Error(`Can't override tool with id \"${Tool.id}\"`)\n\t\t\t}\n\t\t\tthis.root.children![Tool.id] = new Tool(this, this.root)\n\t\t}\n\n\t\tthis.environment = new EnvironmentManager(this)\n\t\tthis.scribbles = new ScribbleManager(this)\n\n\t\t// Cleanup\n\n\t\tconst cleanupInstancePageState = (\n\t\t\tprevPageState: TLInstancePageState,\n\t\t\tshapesNoLongerInPage: Set\n\t\t) => {\n\t\t\tlet nextPageState = null as null | TLInstancePageState\n\n\t\t\tconst selectedShapeIds = prevPageState.selectedShapeIds.filter(\n\t\t\t\t(id) => !shapesNoLongerInPage.has(id)\n\t\t\t)\n\t\t\tif (selectedShapeIds.length !== prevPageState.selectedShapeIds.length) {\n\t\t\t\tif (!nextPageState) nextPageState = { ...prevPageState }\n\t\t\t\tnextPageState.selectedShapeIds = selectedShapeIds\n\t\t\t}\n\n\t\t\tconst erasingShapeIds = prevPageState.erasingShapeIds.filter(\n\t\t\t\t(id) => !shapesNoLongerInPage.has(id)\n\t\t\t)\n\t\t\tif (erasingShapeIds.length !== prevPageState.erasingShapeIds.length) {\n\t\t\t\tif (!nextPageState) nextPageState = { ...prevPageState }\n\t\t\t\tnextPageState.erasingShapeIds = erasingShapeIds\n\t\t\t}\n\n\t\t\tif (prevPageState.hoveredShapeId && shapesNoLongerInPage.has(prevPageState.hoveredShapeId)) {\n\t\t\t\tif (!nextPageState) nextPageState = { ...prevPageState }\n\t\t\t\tnextPageState.hoveredShapeId = null\n\t\t\t}\n\n\t\t\tif (prevPageState.editingShapeId && shapesNoLongerInPage.has(prevPageState.editingShapeId)) {\n\t\t\t\tif (!nextPageState) nextPageState = { ...prevPageState }\n\t\t\t\tnextPageState.editingShapeId = null\n\t\t\t}\n\n\t\t\tconst hintingShapeIds = prevPageState.hintingShapeIds.filter(\n\t\t\t\t(id) => !shapesNoLongerInPage.has(id)\n\t\t\t)\n\t\t\tif (hintingShapeIds.length !== prevPageState.hintingShapeIds.length) {\n\t\t\t\tif (!nextPageState) nextPageState = { ...prevPageState }\n\t\t\t\tnextPageState.hintingShapeIds = hintingShapeIds\n\t\t\t}\n\n\t\t\tif (prevPageState.focusedGroupId && shapesNoLongerInPage.has(prevPageState.focusedGroupId)) {\n\t\t\t\tif (!nextPageState) nextPageState = { ...prevPageState }\n\t\t\t\tnextPageState.focusedGroupId = null\n\t\t\t}\n\t\t\treturn nextPageState\n\t\t}\n\n\t\tthis.sideEffects = this.store.sideEffects\n\n\t\tlet deletedBindings = new Map>()\n\t\tconst deletedShapeIds = new Set()\n\t\tconst invalidParents = new Set()\n\t\tlet invalidBindingTypes = new Set()\n\t\tthis.disposables.add(\n\t\t\tthis.sideEffects.registerOperationCompleteHandler(() => {\n\t\t\t\t// this needs to be cleared here because further effects may delete more shapes\n\t\t\t\t// and we want the next invocation of this handler to handle those separately\n\t\t\t\tdeletedShapeIds.clear()\n\n\t\t\t\tfor (const parentId of invalidParents) {\n\t\t\t\t\tinvalidParents.delete(parentId)\n\t\t\t\t\tconst parent = this.getShape(parentId)\n\t\t\t\t\tif (!parent) continue\n\n\t\t\t\t\tconst util = this.getShapeUtil(parent)\n\t\t\t\t\tconst changes = util.onChildrenChange?.(parent)\n\n\t\t\t\t\tif (changes?.length) {\n\t\t\t\t\t\tthis.updateShapes(changes)\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (invalidBindingTypes.size) {\n\t\t\t\t\tconst t = invalidBindingTypes\n\t\t\t\t\tinvalidBindingTypes = new Set()\n\t\t\t\t\tfor (const type of t) {\n\t\t\t\t\t\tconst util = this.getBindingUtil(type)\n\t\t\t\t\t\tutil.onOperationComplete?.()\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (deletedBindings.size) {\n\t\t\t\t\tconst t = deletedBindings\n\t\t\t\t\tdeletedBindings = new Map()\n\t\t\t\t\tfor (const opts of t.values()) {\n\t\t\t\t\t\tthis.getBindingUtil(opts.binding).onAfterDelete?.(opts)\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tthis.emit('update')\n\t\t\t})\n\t\t)\n\n\t\tthis.disposables.add(\n\t\t\tthis.sideEffects.register({\n\t\t\t\tshape: {\n\t\t\t\t\tafterChange: (shapeBefore, shapeAfter) => {\n\t\t\t\t\t\tfor (const binding of this.getBindingsInvolvingShape(shapeAfter)) {\n\t\t\t\t\t\t\tinvalidBindingTypes.add(binding.type)\n\t\t\t\t\t\t\tif (binding.fromId === shapeAfter.id) {\n\t\t\t\t\t\t\t\tthis.getBindingUtil(binding).onAfterChangeFromShape?.({\n\t\t\t\t\t\t\t\t\tbinding,\n\t\t\t\t\t\t\t\t\tshapeBefore,\n\t\t\t\t\t\t\t\t\tshapeAfter,\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (binding.toId === shapeAfter.id) {\n\t\t\t\t\t\t\t\tthis.getBindingUtil(binding).onAfterChangeToShape?.({\n\t\t\t\t\t\t\t\t\tbinding,\n\t\t\t\t\t\t\t\t\tshapeBefore,\n\t\t\t\t\t\t\t\t\tshapeAfter,\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// if the shape's parent changed and it has a binding, update the binding\n\t\t\t\t\t\tif (shapeBefore.parentId !== shapeAfter.parentId) {\n\t\t\t\t\t\t\tconst notifyBindingAncestryChange = (id: TLShapeId) => {\n\t\t\t\t\t\t\t\tconst descendantShape = this.getShape(id)\n\t\t\t\t\t\t\t\tif (!descendantShape) return\n\n\t\t\t\t\t\t\t\tfor (const binding of this.getBindingsInvolvingShape(descendantShape)) {\n\t\t\t\t\t\t\t\t\tinvalidBindingTypes.add(binding.type)\n\n\t\t\t\t\t\t\t\t\tif (binding.fromId === descendantShape.id) {\n\t\t\t\t\t\t\t\t\t\tthis.getBindingUtil(binding).onAfterChangeFromShape?.({\n\t\t\t\t\t\t\t\t\t\t\tbinding,\n\t\t\t\t\t\t\t\t\t\t\tshapeBefore: descendantShape,\n\t\t\t\t\t\t\t\t\t\t\tshapeAfter: descendantShape,\n\t\t\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tif (binding.toId === descendantShape.id) {\n\t\t\t\t\t\t\t\t\t\tthis.getBindingUtil(binding).onAfterChangeToShape?.({\n\t\t\t\t\t\t\t\t\t\t\tbinding,\n\t\t\t\t\t\t\t\t\t\t\tshapeBefore: descendantShape,\n\t\t\t\t\t\t\t\t\t\t\tshapeAfter: descendantShape,\n\t\t\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tnotifyBindingAncestryChange(shapeAfter.id)\n\t\t\t\t\t\t\tthis.visitDescendants(shapeAfter.id, notifyBindingAncestryChange)\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// if this shape moved to a new page, clean up any previous page's instance state\n\t\t\t\t\t\tif (shapeBefore.parentId !== shapeAfter.parentId && isPageId(shapeAfter.parentId)) {\n\t\t\t\t\t\t\tconst allMovingIds = new Set([shapeBefore.id])\n\t\t\t\t\t\t\tthis.visitDescendants(shapeBefore.id, (id) => {\n\t\t\t\t\t\t\t\tallMovingIds.add(id)\n\t\t\t\t\t\t\t})\n\n\t\t\t\t\t\t\tfor (const instancePageState of this.getPageStates()) {\n\t\t\t\t\t\t\t\tif (instancePageState.pageId === shapeAfter.parentId) continue\n\t\t\t\t\t\t\t\tconst nextPageState = cleanupInstancePageState(instancePageState, allMovingIds)\n\n\t\t\t\t\t\t\t\tif (nextPageState) {\n\t\t\t\t\t\t\t\t\tthis.store.put([nextPageState])\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (shapeBefore.parentId && isShapeId(shapeBefore.parentId)) {\n\t\t\t\t\t\t\tinvalidParents.add(shapeBefore.parentId)\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (shapeAfter.parentId !== shapeBefore.parentId && isShapeId(shapeAfter.parentId)) {\n\t\t\t\t\t\t\tinvalidParents.add(shapeAfter.parentId)\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t\tbeforeDelete: (shape) => {\n\t\t\t\t\t\t// if we triggered this delete with a recursive call, don't do anything\n\t\t\t\t\t\tif (deletedShapeIds.has(shape.id)) return\n\t\t\t\t\t\t// if the deleted shape has a parent shape make sure we call it's onChildrenChange callback\n\t\t\t\t\t\tif (shape.parentId && isShapeId(shape.parentId)) {\n\t\t\t\t\t\t\tinvalidParents.add(shape.parentId)\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tdeletedShapeIds.add(shape.id)\n\n\t\t\t\t\t\tconst deleteBindingIds: TLBindingId[] = []\n\t\t\t\t\t\tfor (const binding of this.getBindingsInvolvingShape(shape)) {\n\t\t\t\t\t\t\tinvalidBindingTypes.add(binding.type)\n\t\t\t\t\t\t\tdeleteBindingIds.push(binding.id)\n\t\t\t\t\t\t\tconst util = this.getBindingUtil(binding)\n\t\t\t\t\t\t\tif (binding.fromId === shape.id) {\n\t\t\t\t\t\t\t\tutil.onBeforeIsolateToShape?.({ binding, removedShape: shape })\n\t\t\t\t\t\t\t\tutil.onBeforeDeleteFromShape?.({ binding, shape })\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tutil.onBeforeIsolateFromShape?.({ binding, removedShape: shape })\n\t\t\t\t\t\t\t\tutil.onBeforeDeleteToShape?.({ binding, shape })\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (deleteBindingIds.length) {\n\t\t\t\t\t\t\tthis.deleteBindings(deleteBindingIds)\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst deletedIds = new Set([shape.id])\n\t\t\t\t\t\tconst updates = compact(\n\t\t\t\t\t\t\tthis.getPageStates().map((pageState) => {\n\t\t\t\t\t\t\t\treturn cleanupInstancePageState(pageState, deletedIds)\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t)\n\n\t\t\t\t\t\tif (updates.length) {\n\t\t\t\t\t\t\tthis.store.put(updates)\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tbinding: {\n\t\t\t\t\tbeforeCreate: (binding) => {\n\t\t\t\t\t\tconst next = this.getBindingUtil(binding).onBeforeCreate?.({ binding })\n\t\t\t\t\t\tif (next) return next\n\t\t\t\t\t\treturn binding\n\t\t\t\t\t},\n\t\t\t\t\tafterCreate: (binding) => {\n\t\t\t\t\t\tinvalidBindingTypes.add(binding.type)\n\t\t\t\t\t\tthis.getBindingUtil(binding).onAfterCreate?.({ binding })\n\t\t\t\t\t},\n\t\t\t\t\tbeforeChange: (bindingBefore, bindingAfter) => {\n\t\t\t\t\t\tconst updated = this.getBindingUtil(bindingAfter).onBeforeChange?.({\n\t\t\t\t\t\t\tbindingBefore,\n\t\t\t\t\t\t\tbindingAfter,\n\t\t\t\t\t\t})\n\t\t\t\t\t\tif (updated) return updated\n\t\t\t\t\t\treturn bindingAfter\n\t\t\t\t\t},\n\t\t\t\t\tafterChange: (bindingBefore, bindingAfter) => {\n\t\t\t\t\t\tinvalidBindingTypes.add(bindingAfter.type)\n\t\t\t\t\t\tthis.getBindingUtil(bindingAfter).onAfterChange?.({ bindingBefore, bindingAfter })\n\t\t\t\t\t},\n\t\t\t\t\tbeforeDelete: (binding) => {\n\t\t\t\t\t\tthis.getBindingUtil(binding).onBeforeDelete?.({ binding })\n\t\t\t\t\t},\n\t\t\t\t\tafterDelete: (binding) => {\n\t\t\t\t\t\tthis.getBindingUtil(binding).onAfterDelete?.({ binding })\n\t\t\t\t\t\tinvalidBindingTypes.add(binding.type)\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tpage: {\n\t\t\t\t\tafterCreate: (record) => {\n\t\t\t\t\t\tconst cameraId = CameraRecordType.createId(record.id)\n\t\t\t\t\t\tconst _pageStateId = InstancePageStateRecordType.createId(record.id)\n\t\t\t\t\t\tif (!this.store.has(cameraId)) {\n\t\t\t\t\t\t\tthis.store.put([CameraRecordType.create({ id: cameraId })])\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (!this.store.has(_pageStateId)) {\n\t\t\t\t\t\t\tthis.store.put([\n\t\t\t\t\t\t\t\tInstancePageStateRecordType.create({ id: _pageStateId, pageId: record.id }),\n\t\t\t\t\t\t\t])\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t\tafterDelete: (record, source) => {\n\t\t\t\t\t\t// page was deleted, need to check whether it's the current page and select another one if so\n\t\t\t\t\t\tif (this.getInstanceState()?.currentPageId === record.id) {\n\t\t\t\t\t\t\tconst backupPageId = this.getPages().find((p) => p.id !== record.id)?.id\n\t\t\t\t\t\t\tif (backupPageId) {\n\t\t\t\t\t\t\t\tthis.store.put([{ ...this.getInstanceState(), currentPageId: backupPageId }])\n\t\t\t\t\t\t\t} else if (source === 'user') {\n\t\t\t\t\t\t\t\t// fall back to ensureStoreIsUsable:\n\t\t\t\t\t\t\t\tthis.store.ensureStoreIsUsable()\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// delete the camera and state for the page if necessary\n\t\t\t\t\t\tconst cameraId = CameraRecordType.createId(record.id)\n\t\t\t\t\t\tconst instance_PageStateId = InstancePageStateRecordType.createId(record.id)\n\t\t\t\t\t\tthis.store.remove([cameraId, instance_PageStateId])\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tinstance: {\n\t\t\t\t\tafterChange: (prev, next, source) => {\n\t\t\t\t\t\t// instance should never be updated to a page that no longer exists (this can\n\t\t\t\t\t\t// happen when undoing a change that involves switching to a page that has since\n\t\t\t\t\t\t// been deleted by another user)\n\t\t\t\t\t\tif (!this.store.has(next.currentPageId)) {\n\t\t\t\t\t\t\tconst backupPageId = this.store.has(prev.currentPageId)\n\t\t\t\t\t\t\t\t? prev.currentPageId\n\t\t\t\t\t\t\t\t: this.getPages()[0]?.id\n\t\t\t\t\t\t\tif (backupPageId) {\n\t\t\t\t\t\t\t\tthis.store.update(next.id, (instance) => ({\n\t\t\t\t\t\t\t\t\t...instance,\n\t\t\t\t\t\t\t\t\tcurrentPageId: backupPageId,\n\t\t\t\t\t\t\t\t}))\n\t\t\t\t\t\t\t} else if (source === 'user') {\n\t\t\t\t\t\t\t\t// fall back to ensureStoreIsUsable:\n\t\t\t\t\t\t\t\tthis.store.ensureStoreIsUsable()\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tinstance_page_state: {\n\t\t\t\t\tafterChange: (prev, next) => {\n\t\t\t\t\t\tif (prev?.selectedShapeIds !== next?.selectedShapeIds) {\n\t\t\t\t\t\t\t// ensure that descendants and ancestors are not selected at the same time\n\t\t\t\t\t\t\tconst filtered = next.selectedShapeIds.filter((id) => {\n\t\t\t\t\t\t\t\tlet parentId = this.getShape(id)?.parentId\n\t\t\t\t\t\t\t\twhile (isShapeId(parentId)) {\n\t\t\t\t\t\t\t\t\tif (next.selectedShapeIds.includes(parentId)) {\n\t\t\t\t\t\t\t\t\t\treturn false\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tparentId = this.getShape(parentId)?.parentId\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\treturn true\n\t\t\t\t\t\t\t})\n\n\t\t\t\t\t\t\tlet nextFocusedGroupId: null | TLShapeId = null\n\n\t\t\t\t\t\t\tif (filtered.length > 0) {\n\t\t\t\t\t\t\t\tconst commonGroupAncestor = this.findCommonAncestor(\n\t\t\t\t\t\t\t\t\tcompact(filtered.map((id) => this.getShape(id))),\n\t\t\t\t\t\t\t\t\t(shape) => this.isShapeOfType(shape, 'group')\n\t\t\t\t\t\t\t\t)\n\n\t\t\t\t\t\t\t\tif (commonGroupAncestor) {\n\t\t\t\t\t\t\t\t\tnextFocusedGroupId = commonGroupAncestor\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tif (next?.focusedGroupId) {\n\t\t\t\t\t\t\t\t\tnextFocusedGroupId = next.focusedGroupId\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\tfiltered.length !== next.selectedShapeIds.length ||\n\t\t\t\t\t\t\t\tnextFocusedGroupId !== next.focusedGroupId\n\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\tthis.store.put([\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t...next,\n\t\t\t\t\t\t\t\t\t\tselectedShapeIds: filtered,\n\t\t\t\t\t\t\t\t\t\tfocusedGroupId: nextFocusedGroupId ?? null,\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t])\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t})\n\t\t)\n\n\t\tthis._currentPageShapeIds = deriveShapeIdsInCurrentPage(this.store, () =>\n\t\t\tthis.getCurrentPageId()\n\t\t)\n\t\tthis._parentIdsToChildIds = parentsToChildren(this.store)\n\n\t\tthis.disposables.add(\n\t\t\tthis.store.listen((changes) => {\n\t\t\t\tthis.emit('change', changes)\n\t\t\t})\n\t\t)\n\t\tthis.disposables.add(this.history.dispose)\n\n\t\tthis.run(\n\t\t\t() => {\n\t\t\t\tthis.store.ensureStoreIsUsable()\n\n\t\t\t\t// clear ephemeral state\n\t\t\t\tthis._updateCurrentPageState({\n\t\t\t\t\teditingShapeId: null,\n\t\t\t\t\thoveredShapeId: null,\n\t\t\t\t\terasingShapeIds: [],\n\t\t\t\t})\n\t\t\t},\n\t\t\t{ history: 'ignore' }\n\t\t)\n\n\t\tif (initialState && this.root.children[initialState] === undefined) {\n\t\t\tthrow Error(`No state found for initialState \"${initialState}\".`)\n\t\t}\n\n\t\tthis.root.enter(undefined, 'initial')\n\n\t\tthis.edgeScrollManager = new EdgeScrollManager(this)\n\t\tthis.focusManager = new FocusManager(this, autoFocus)\n\t\tthis.disposables.add(this.focusManager.dispose.bind(this.focusManager))\n\n\t\tif (this.getInstanceState().followingUserId) {\n\t\t\tthis.stopFollowingUser()\n\t\t}\n\n\t\tthis.on('tick', this._flushEventsForTick)\n\n\t\tthis.timers.requestAnimationFrame(() => {\n\t\t\tthis._tickManager.start()\n\t\t})\n\n\t\tthis.performanceTracker = new PerformanceTracker()\n\t}\n\n\tprivate readonly _isShapeHiddenPredicate?: (shape: TLShape, editor: Editor) => boolean\n\t@computed\n\tprivate getIsShapeHiddenCache() {\n\t\tif (!this._isShapeHiddenPredicate) return null\n\t\treturn this.store.createComputedCache('isShapeHidden', (shape: TLShape) => {\n\t\t\tconst hiddenParent = this.findShapeAncestor(shape, (p) => this.isShapeHidden(p))\n\t\t\tif (hiddenParent) return true\n\t\t\treturn this._isShapeHiddenPredicate!(shape, this) ?? false\n\t\t})\n\t}\n\tisShapeHidden(shapeOrId: TLShape | TLShapeId): boolean {\n\t\tif (!this._isShapeHiddenPredicate) return false\n\t\treturn !!this.getIsShapeHiddenCache!()!.get(\n\t\t\ttypeof shapeOrId === 'string' ? shapeOrId : shapeOrId.id\n\t\t)\n\t}\n\n\treadonly options: TldrawOptions\n\n\t/**\n\t * The editor's store\n\t *\n\t * @public\n\t */\n\treadonly store: TLStore\n\n\t/**\n\t * The root state of the statechart.\n\t *\n\t * @public\n\t */\n\treadonly root: StateNode\n\n\t/**\n\t * A set of functions to call when the app is disposed.\n\t *\n\t * @public\n\t */\n\treadonly disposables = new Set<() => void>()\n\n\t/**\n\t * Whether the editor is disposed.\n\t *\n\t * @public\n\t */\n\tisDisposed = false\n\n\t/** @internal */\n\tprivate readonly _tickManager\n\n\t/**\n\t * A manager for the app's snapping feature.\n\t *\n\t * @public\n\t */\n\treadonly snaps: SnapManager\n\n\t/**\n\t * A manager for the any asynchronous events and making sure they're\n\t * cleaned up upon disposal.\n\t *\n\t * @public\n\t */\n\treadonly timers: Timers\n\n\t/**\n\t * A manager for the user and their preferences.\n\t *\n\t * @public\n\t */\n\treadonly user: UserPreferencesManager\n\n\t/**\n\t * A helper for measuring text.\n\t *\n\t * @public\n\t */\n\treadonly textMeasure: TextManager\n\n\t/**\n\t * A manager for the editor's environment.\n\t *\n\t * @public\n\t */\n\treadonly environment: EnvironmentManager\n\n\t/**\n\t * A manager for the editor's scribbles.\n\t *\n\t * @public\n\t */\n\treadonly scribbles: ScribbleManager\n\n\t/**\n\t * A manager for side effects and correct state enforcement. See {@link @tldraw/store#StoreSideEffects} for details.\n\t *\n\t * @public\n\t */\n\treadonly sideEffects: StoreSideEffects\n\n\t/**\n\t * A manager for moving the camera when the mouse is at the edge of the screen.\n\t *\n\t * @public\n\t */\n\tedgeScrollManager: EdgeScrollManager\n\n\t/**\n\t * A manager for ensuring correct focus. See FocusManager for details.\n\t *\n\t * @internal\n\t */\n\tprivate focusManager: FocusManager\n\n\t/**\n\t * The current HTML element containing the editor.\n\t *\n\t * @example\n\t * ```ts\n\t * const container = editor.getContainer()\n\t * ```\n\t *\n\t * @public\n\t */\n\tgetContainer: () => HTMLElement\n\n\t/**\n\t * Dispose the editor.\n\t *\n\t * @public\n\t */\n\tdispose() {\n\t\tthis.disposables.forEach((dispose) => dispose())\n\t\tthis.disposables.clear()\n\t\tthis.isDisposed = true\n\t}\n\n\t/* ------------------- Shape Utils ------------------ */\n\n\t/**\n\t * A map of shape utility classes (TLShapeUtils) by shape type.\n\t *\n\t * @public\n\t */\n\tshapeUtils: { readonly [K in string]?: ShapeUtil }\n\n\tstyleProps: { [key: string]: Map, string> }\n\n\t/**\n\t * Get a shape util from a shape itself.\n\t *\n\t * @example\n\t * ```ts\n\t * const util = editor.getShapeUtil(myArrowShape)\n\t * const util = editor.getShapeUtil('arrow')\n\t * const util = editor.getShapeUtil(myArrowShape)\n\t * const util = editor.getShapeUtil(TLArrowShape)('arrow')\n\t * ```\n\t *\n\t * @param shape - A shape, shape partial, or shape type.\n\t *\n\t * @public\n\t */\n\tgetShapeUtil(shape: S | TLShapePartial): ShapeUtil\n\tgetShapeUtil(type: S['type']): ShapeUtil\n\tgetShapeUtil(type: T extends ShapeUtil ? R['type'] : string): T\n\tgetShapeUtil(arg: string | { type: string }) {\n\t\tconst type = typeof arg === 'string' ? arg : arg.type\n\t\tconst shapeUtil = getOwnProperty(this.shapeUtils, type)\n\t\tassert(shapeUtil, `No shape util found for type \"${type}\"`)\n\t\treturn shapeUtil\n\t}\n\n\t/* ------------------- Binding Utils ------------------ */\n\t/**\n\t * A map of shape utility classes (TLShapeUtils) by shape type.\n\t *\n\t * @public\n\t */\n\tbindingUtils: { readonly [K in string]?: BindingUtil }\n\n\t/**\n\t * Get a binding util from a binding itself.\n\t *\n\t * @example\n\t * ```ts\n\t * const util = editor.getBindingUtil(myArrowBinding)\n\t * const util = editor.getBindingUtil('arrow')\n\t * const util = editor.getBindingUtil(myArrowBinding)\n\t * const util = editor.getBindingUtil(TLArrowBinding)('arrow')\n\t * ```\n\t *\n\t * @param binding - A binding, binding partial, or binding type.\n\t *\n\t * @public\n\t */\n\tgetBindingUtil(binding: S | { type: S['type'] }): BindingUtil\n\tgetBindingUtil(type: S['type']): BindingUtil\n\tgetBindingUtil(\n\t\ttype: T extends BindingUtil ? R['type'] : string\n\t): T\n\tgetBindingUtil(arg: string | { type: string }) {\n\t\tconst type = typeof arg === 'string' ? arg : arg.type\n\t\tconst bindingUtil = getOwnProperty(this.bindingUtils, type)\n\t\tassert(bindingUtil, `No binding util found for type \"${type}\"`)\n\t\treturn bindingUtil\n\t}\n\n\t/* --------------------- History -------------------- */\n\n\t/**\n\t * A manager for the app's history.\n\t *\n\t * @readonly\n\t */\n\tprotected readonly history: HistoryManager\n\n\t/**\n\t * Undo to the last mark.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.undo()\n\t * ```\n\t *\n\t * @public\n\t */\n\tundo(): this {\n\t\tthis._flushEventsForTick(0)\n\t\tthis.complete()\n\t\tthis.history.undo()\n\t\treturn this\n\t}\n\n\t/**\n\t * Whether the app can undo.\n\t *\n\t * @public\n\t */\n\t@computed getCanUndo(): boolean {\n\t\treturn this.history.getNumUndos() > 0\n\t}\n\n\t/**\n\t * Redo to the next mark.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.redo()\n\t * ```\n\t *\n\t * @public\n\t */\n\tredo(): this {\n\t\tthis._flushEventsForTick(0)\n\t\tthis.complete()\n\t\tthis.history.redo()\n\t\treturn this\n\t}\n\n\tclearHistory() {\n\t\tthis.history.clear()\n\t\treturn this\n\t}\n\n\t/**\n\t * Whether the app can redo.\n\t *\n\t * @public\n\t */\n\t@computed getCanRedo(): boolean {\n\t\treturn this.history.getNumRedos() > 0\n\t}\n\n\t/**\n\t * Create a new \"mark\", or stopping point, in the undo redo history. Creating a mark will clear\n\t * any redos.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.mark()\n\t * editor.mark('flip shapes')\n\t * ```\n\t *\n\t * @param markId - The mark's id, usually the reason for adding the mark.\n\t *\n\t * @public\n\t * @deprecated use {@link Editor.markHistoryStoppingPoint} instead\n\t */\n\tmark(markId?: string): this {\n\t\tif (typeof markId === 'string') {\n\t\t\tconsole.warn(\n\t\t\t\t`[tldraw] \\`editor.history.mark(\"${markId}\")\\` is deprecated. Please use \\`const myMarkId = editor.markHistoryStoppingPoint()\\` instead.`\n\t\t\t)\n\t\t} else {\n\t\t\tconsole.warn(\n\t\t\t\t'[tldraw] `editor.mark()` is deprecated. Use `editor.markHistoryStoppingPoint()` instead.'\n\t\t\t)\n\t\t}\n\t\tthis.history._mark(markId ?? uniqueId())\n\t\treturn this\n\t}\n\n\t/**\n\t * Create a new \"mark\", or stopping point, in the undo redo history. Creating a mark will clear\n\t * any redos. You typically want to do this just before a user interaction begins or is handled.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.markHistoryStoppingPoint()\n\t * editor.flipShapes(editor.getSelectedShapes())\n\t * ```\n\t * @example\n\t * ```ts\n\t * const beginRotateMark = editor.markHistoryStoppingPoint()\n\t * // if the use cancels the rotation, you can bail back to this mark\n\t * editor.bailToMark(beginRotateMark)\n\t * ```\n\t *\n\t * @public\n\t * @param name - The name of the mark, useful for debugging the undo/redo stacks\n\t * @returns a unique id for the mark that can be used with `squashToMark` or `bailToMark`.\n\t */\n\tmarkHistoryStoppingPoint(name?: string): string {\n\t\tconst id = `[${name ?? 'stop'}]_${uniqueId()}`\n\t\tthis.history._mark(id)\n\t\treturn id\n\t}\n\n\t/**\n\t * @internal this is only used to implement some backwards-compatibility logic. Should be fine to delete after 6 months or whatever.\n\t */\n\tgetMarkIdMatching(idSubstring: string) {\n\t\treturn this.history.getMarkIdMatching(idSubstring)\n\t}\n\n\t/**\n\t * Coalesces all changes since the given mark into a single change, removing any intermediate marks.\n\t *\n\t * This is useful if you need to 'compress' the recent history to simplify the undo/redo experience of a complex interaction.\n\t *\n\t * @example\n\t * ```ts\n\t * const bumpShapesMark = editor.markHistoryStoppingPoint()\n\t * // ... some changes\n\t * editor.squashToMark(bumpShapesMark)\n\t * ```\n\t *\n\t * @param markId - The mark id to squash to.\n\t */\n\tsquashToMark(markId: string): this {\n\t\tthis.history.squashToMark(markId)\n\t\treturn this\n\t}\n\n\t/**\n\t * Undo to the closest mark, discarding the changes so they cannot be redone.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.bail()\n\t * ```\n\t *\n\t * @public\n\t */\n\tbail() {\n\t\tthis.history.bail()\n\t\treturn this\n\t}\n\n\t/**\n\t * Undo to the given mark, discarding the changes so they cannot be redone.\n\t *\n\t * @example\n\t * ```ts\n\t * const beginDrag = editor.markHistoryStoppingPoint()\n\t * // ... some changes\n\t * editor.bailToMark(beginDrag)\n\t * ```\n\t *\n\t * @public\n\t */\n\tbailToMark(id: string): this {\n\t\tthis.history.bailToMark(id)\n\t\treturn this\n\t}\n\n\tprivate _shouldIgnoreShapeLock = false\n\n\t/**\n\t * Run a function in a transaction with optional options for context.\n\t * You can use the options to change the way that history is treated\n\t * or allow changes to locked shapes.\n\t *\n\t * @example\n\t * ```ts\n\t * // updating with\n\t * editor.run(() => {\n\t * \teditor.updateShape({ ...myShape, x: 100 })\n\t * }, { history: \"ignore\" })\n\t *\n\t * // forcing changes / deletions for locked shapes\n\t * editor.toggleLock([myShape])\n\t * editor.run(() => {\n\t * \teditor.updateShape({ ...myShape, x: 100 })\n\t * \teditor.deleteShape(myShape)\n\t * }, { ignoreShapeLock: true }, )\n\t * ```\n\t *\n\t * @param fn - The callback function to run.\n\t * @param opts - The options for the batch.\n\t *\n\t *\n\t * @public\n\t */\n\trun(fn: () => void, opts?: TLEditorRunOptions): this {\n\t\tconst previousIgnoreShapeLock = this._shouldIgnoreShapeLock\n\t\tthis._shouldIgnoreShapeLock = opts?.ignoreShapeLock ?? previousIgnoreShapeLock\n\n\t\ttry {\n\t\t\tthis.history.batch(fn, opts)\n\t\t} finally {\n\t\t\tthis._shouldIgnoreShapeLock = previousIgnoreShapeLock\n\t\t}\n\n\t\treturn this\n\t}\n\n\t/**\n\t * @deprecated Use `Editor.run` instead.\n\t */\n\tbatch(fn: () => void, opts?: TLEditorRunOptions): this {\n\t\treturn this.run(fn, opts)\n\t}\n\n\t/* --------------------- Errors --------------------- */\n\n\t/** @internal */\n\tannotateError(\n\t\terror: unknown,\n\t\t{\n\t\t\torigin,\n\t\t\twillCrashApp,\n\t\t\ttags,\n\t\t\textras,\n\t\t}: {\n\t\t\torigin: string\n\t\t\twillCrashApp: boolean\n\t\t\ttags?: Record\n\t\t\textras?: Record\n\t\t}\n\t): this {\n\t\tconst defaultAnnotations = this.createErrorAnnotations(origin, willCrashApp)\n\t\tannotateError(error, {\n\t\t\ttags: { ...defaultAnnotations.tags, ...tags },\n\t\t\textras: { ...defaultAnnotations.extras, ...extras },\n\t\t})\n\t\tif (willCrashApp) {\n\t\t\tthis.store.markAsPossiblyCorrupted()\n\t\t}\n\t\treturn this\n\t}\n\n\t/** @internal */\n\tcreateErrorAnnotations(\n\t\torigin: string,\n\t\twillCrashApp: boolean | 'unknown'\n\t): {\n\t\ttags: { origin: string; willCrashApp: boolean | 'unknown' }\n\t\textras: {\n\t\t\tactiveStateNode?: string\n\t\t\tselectedShapes?: TLUnknownShape[]\n\t\t\teditingShape?: TLUnknownShape\n\t\t\tinputs?: Record\n\t\t}\n\t} {\n\t\ttry {\n\t\t\tconst editingShapeId = this.getEditingShapeId()\n\t\t\treturn {\n\t\t\t\ttags: {\n\t\t\t\t\torigin: origin,\n\t\t\t\t\twillCrashApp,\n\t\t\t\t},\n\t\t\t\textras: {\n\t\t\t\t\tactiveStateNode: this.root.getPath(),\n\t\t\t\t\tselectedShapes: this.getSelectedShapes(),\n\t\t\t\t\teditingShape: editingShapeId ? this.getShape(editingShapeId) : undefined,\n\t\t\t\t\tinputs: this.inputs,\n\t\t\t\t},\n\t\t\t}\n\t\t} catch {\n\t\t\treturn {\n\t\t\t\ttags: {\n\t\t\t\t\torigin: origin,\n\t\t\t\t\twillCrashApp,\n\t\t\t\t},\n\t\t\t\textras: {},\n\t\t\t}\n\t\t}\n\t}\n\n\t/** @internal */\n\tprivate _crashingError: unknown | null = null\n\n\t/**\n\t * We can't use an `atom` here because there's a chance that when `crashAndReportError` is called,\n\t * we're in a transaction that's about to be rolled back due to the same error we're currently\n\t * reporting.\n\t *\n\t * Instead, to listen to changes to this value, you need to listen to app's `crash` event.\n\t *\n\t * @internal\n\t */\n\tgetCrashingError() {\n\t\treturn this._crashingError\n\t}\n\n\t/** @internal */\n\tcrash(error: unknown): this {\n\t\tthis._crashingError = error\n\t\tthis.store.markAsPossiblyCorrupted()\n\t\tthis.emit('crash', { error })\n\t\treturn this\n\t}\n\n\t/* ------------------- Statechart ------------------- */\n\n\t/**\n\t * The editor's current path of active states.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getPath() // \"select.idle\"\n\t * ```\n\t *\n\t * @public\n\t */\n\t@computed getPath() {\n\t\treturn this.root.getPath().split('root.')[1]\n\t}\n\n\t/**\n\t * Get whether a certain tool (or other state node) is currently active.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.isIn('select')\n\t * editor.isIn('select.brushing')\n\t * ```\n\t *\n\t * @param path - The path of active states, separated by periods.\n\t *\n\t * @public\n\t */\n\tisIn(path: string): boolean {\n\t\tconst ids = path.split('.').reverse()\n\t\tlet state = this.root as StateNode\n\t\twhile (ids.length > 0) {\n\t\t\tconst id = ids.pop()\n\t\t\tif (!id) return true\n\t\t\tconst current = state.getCurrent()\n\t\t\tif (current?.id === id) {\n\t\t\t\tif (ids.length === 0) return true\n\t\t\t\tstate = current\n\t\t\t\tcontinue\n\t\t\t} else return false\n\t\t}\n\t\treturn false\n\t}\n\n\t/**\n\t * Get whether the state node is in any of the given active paths.\n\t *\n\t * @example\n\t * ```ts\n\t * state.isInAny('select', 'erase')\n\t * state.isInAny('select.brushing', 'erase.idle')\n\t * ```\n\t *\n\t * @public\n\t */\n\tisInAny(...paths: string[]): boolean {\n\t\treturn paths.some((path) => this.isIn(path))\n\t}\n\n\t/**\n\t * Set the selected tool.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.setCurrentTool('hand')\n\t * editor.setCurrentTool('hand', { date: Date.now() })\n\t * ```\n\t *\n\t * @param id - The id of the tool to select.\n\t * @param info - Arbitrary data to pass along into the transition.\n\t *\n\t * @public\n\t */\n\tsetCurrentTool(id: string, info = {}): this {\n\t\tthis.root.transition(id, info)\n\t\treturn this\n\t}\n\n\t/**\n\t * The current selected tool.\n\t *\n\t * @public\n\t */\n\t@computed getCurrentTool(): StateNode {\n\t\treturn this.root.getCurrent()!\n\t}\n\n\t/**\n\t * The id of the current selected tool.\n\t *\n\t * @public\n\t */\n\t@computed getCurrentToolId(): string {\n\t\tconst currentTool = this.getCurrentTool()\n\t\tif (!currentTool) return ''\n\t\treturn currentTool.getCurrentToolIdMask() ?? currentTool.id\n\t}\n\n\t/**\n\t * Get a descendant by its path.\n\t *\n\t * @example\n\t * ```ts\n\t * state.getStateDescendant('select')\n\t * state.getStateDescendant('select.brushing')\n\t * ```\n\t *\n\t * @param path - The descendant's path of state ids, separated by periods.\n\t *\n\t * @public\n\t */\n\tgetStateDescendant(path: string): T | undefined {\n\t\tconst ids = path.split('.').reverse()\n\t\tlet state = this.root as StateNode\n\t\twhile (ids.length > 0) {\n\t\t\tconst id = ids.pop()\n\t\t\tif (!id) return state as T\n\t\t\tconst childState = state.children?.[id]\n\t\t\tif (!childState) return undefined\n\t\t\tstate = childState\n\t\t}\n\t\treturn state as T\n\t}\n\n\t/* ---------------- Document Settings --------------- */\n\n\t/**\n\t * The global document settings that apply to all users.\n\t *\n\t * @public\n\t **/\n\t@computed getDocumentSettings() {\n\t\treturn this.store.get(TLDOCUMENT_ID)!\n\t}\n\n\t/**\n\t * Update the global document settings that apply to all users.\n\t *\n\t * @public\n\t **/\n\tupdateDocumentSettings(settings: Partial): this {\n\t\tthis.run(\n\t\t\t() => {\n\t\t\t\tthis.store.put([{ ...this.getDocumentSettings(), ...settings }])\n\t\t\t},\n\t\t\t{ history: 'ignore' }\n\t\t)\n\t\treturn this\n\t}\n\n\t/* ----------------- Instance State ----------------- */\n\n\t/**\n\t * The current instance's state.\n\t *\n\t * @public\n\t */\n\t@computed getInstanceState(): TLInstance {\n\t\treturn this.store.get(TLINSTANCE_ID)!\n\t}\n\n\t/**\n\t * Update the instance's state.\n\t *\n\t * @param partial - A partial object to update the instance state with.\n\t *\n\t * @public\n\t */\n\tupdateInstanceState(\n\t\tpartial: Partial>,\n\t\thistoryOptions?: TLHistoryBatchOptions\n\t): this {\n\t\tthis._updateInstanceState(partial, { history: 'ignore', ...historyOptions })\n\n\t\tif (partial.isChangingStyle !== undefined) {\n\t\t\tclearTimeout(this._isChangingStyleTimeout)\n\t\t\tif (partial.isChangingStyle === true) {\n\t\t\t\t// If we've set to true, set a new reset timeout to change the value back to false after 2 seconds\n\t\t\t\tthis._isChangingStyleTimeout = this.timers.setTimeout(() => {\n\t\t\t\t\tthis._updateInstanceState({ isChangingStyle: false }, { history: 'ignore' })\n\t\t\t\t}, 2000)\n\t\t\t}\n\t\t}\n\n\t\treturn this\n\t}\n\n\t/** @internal */\n\t_updateInstanceState(\n\t\tpartial: Partial>,\n\t\topts?: TLHistoryBatchOptions\n\t) {\n\t\tthis.run(() => {\n\t\t\tthis.store.put([\n\t\t\t\t{\n\t\t\t\t\t...this.getInstanceState(),\n\t\t\t\t\t...partial,\n\t\t\t\t},\n\t\t\t])\n\t\t}, opts)\n\t}\n\n\t/** @internal */\n\tprivate _isChangingStyleTimeout = -1 as any\n\n\t// Menus\n\n\t/**\n\t * A set of strings representing any open menus. When menus are open,\n\t * certain interactions will behave differently; for example, when a\n\t * draw tool is selected and a menu is open, a pointer-down will not\n\t * create a dot (because the user is probably trying to close the menu)\n\t * however a pointer-down event followed by a drag will begin drawing\n\t * a line (because the user is BOTH trying to close the menu AND start\n\t * drawing a line).\n\t *\n\t * @public\n\t */\n\t@computed getOpenMenus(): string[] {\n\t\treturn this.getInstanceState().openMenus\n\t}\n\n\t/**\n\t * Add an open menu.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.addOpenMenu('menu-id')\n\t * ```\n\t *\n\t * @public\n\t */\n\taddOpenMenu(id: string): this {\n\t\tconst menus = new Set(this.getOpenMenus())\n\t\tif (!menus.has(id)) {\n\t\t\tmenus.add(id)\n\t\t\tthis.updateInstanceState({ openMenus: [...menus] })\n\t\t}\n\t\treturn this\n\t}\n\n\t/**\n\t * Delete an open menu.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.deleteOpenMenu('menu-id')\n\t * ```\n\t *\n\t * @public\n\t */\n\tdeleteOpenMenu(id: string): this {\n\t\tconst menus = new Set(this.getOpenMenus())\n\t\tif (menus.has(id)) {\n\t\t\tmenus.delete(id)\n\t\t\tthis.updateInstanceState({ openMenus: [...menus] })\n\t\t}\n\t\treturn this\n\t}\n\n\t/**\n\t * Clear all open menus.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.clearOpenMenus()\n\t * ```\n\t *\n\t * @public\n\t */\n\tclearOpenMenus(): this {\n\t\tif (this.getOpenMenus().length) {\n\t\t\tthis.updateInstanceState({ openMenus: [] })\n\t\t}\n\t\treturn this\n\t}\n\n\t/**\n\t * Get whether any menus are open.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getIsMenuOpen()\n\t * ```\n\t *\n\t * @public\n\t */\n\t@computed getIsMenuOpen(): boolean {\n\t\treturn this.getOpenMenus().length > 0\n\t}\n\n\t/* --------------------- Cursor --------------------- */\n\n\t/**\n\t * Set the cursor.\n\t *\n\t * @param type - The cursor type.\n\t * @param rotation - The cursor rotation.\n\t *\n\t * @public\n\t */\n\tsetCursor(cursor: Partial) {\n\t\tthis.updateInstanceState({ cursor: { ...this.getInstanceState().cursor, ...cursor } })\n\t\treturn this\n\t}\n\n\t/* ------------------- Page State ------------------- */\n\n\t/**\n\t * Page states.\n\t *\n\t * @public\n\t */\n\t@computed getPageStates(): TLInstancePageState[] {\n\t\treturn this._getPageStatesQuery().get()\n\t}\n\n\t/** @internal */\n\t@computed private _getPageStatesQuery() {\n\t\treturn this.store.query.records('instance_page_state')\n\t}\n\n\t/**\n\t * The current page state.\n\t *\n\t * @public\n\t */\n\t@computed getCurrentPageState(): TLInstancePageState {\n\t\treturn this.store.get(this._getCurrentPageStateId())!\n\t}\n\n\t/** @internal */\n\t@computed private _getCurrentPageStateId() {\n\t\treturn InstancePageStateRecordType.createId(this.getCurrentPageId())\n\t}\n\n\t/**\n\t * Update this instance's page state.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.updateCurrentPageState({ id: 'page1', editingShapeId: 'shape:123' })\n\t * ```\n\t *\n\t * @param partial - The partial of the page state object containing the changes.\n\t *\n\t * @public\n\t */\n\tupdateCurrentPageState(\n\t\tpartial: Partial<\n\t\t\tOmit\n\t\t>\n\t): this {\n\t\tthis._updateCurrentPageState(partial)\n\t\treturn this\n\t}\n\t_updateCurrentPageState(partial: Partial>) {\n\t\tthis.store.update(partial.id ?? this.getCurrentPageState().id, (state) => ({\n\t\t\t...state,\n\t\t\t...partial,\n\t\t}))\n\t}\n\n\t/**\n\t * The current selected ids.\n\t *\n\t * @public\n\t */\n\t@computed getSelectedShapeIds() {\n\t\treturn this.getCurrentPageState().selectedShapeIds\n\t}\n\n\t/**\n\t * An array containing all of the currently selected shapes.\n\t *\n\t * @public\n\t * @readonly\n\t */\n\t@computed getSelectedShapes(): TLShape[] {\n\t\tconst { selectedShapeIds } = this.getCurrentPageState()\n\t\treturn compact(selectedShapeIds.map((id) => this.store.get(id)))\n\t}\n\n\t/**\n\t * Select one or more shapes.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.setSelectedShapes(['id1'])\n\t * editor.setSelectedShapes(['id1', 'id2'])\n\t * ```\n\t *\n\t * @param ids - The ids to select.\n\t *\n\t * @public\n\t */\n\tsetSelectedShapes(shapes: TLShapeId[] | TLShape[]): this {\n\t\treturn this.run(\n\t\t\t() => {\n\t\t\t\tconst ids = shapes.map((shape) => (typeof shape === 'string' ? shape : shape.id))\n\t\t\t\tconst { selectedShapeIds: prevSelectedShapeIds } = this.getCurrentPageState()\n\t\t\t\tconst prevSet = new Set(prevSelectedShapeIds)\n\n\t\t\t\tif (ids.length === prevSet.size && ids.every((id) => prevSet.has(id))) return null\n\n\t\t\t\tthis.store.put([{ ...this.getCurrentPageState(), selectedShapeIds: ids }])\n\t\t\t},\n\t\t\t{ history: 'record-preserveRedoStack' }\n\t\t)\n\t}\n\n\t/**\n\t * Determine whether or not any of a shape's ancestors are selected.\n\t *\n\t * @param id - The id of the shape to check.\n\t *\n\t * @public\n\t */\n\tisAncestorSelected(shape: TLShape | TLShapeId): boolean {\n\t\tconst id = typeof shape === 'string' ? shape : shape?.id ?? null\n\t\tconst _shape = this.getShape(id)\n\t\tif (!_shape) return false\n\t\tconst selectedShapeIds = this.getSelectedShapeIds()\n\t\treturn !!this.findShapeAncestor(_shape, (parent) => selectedShapeIds.includes(parent.id))\n\t}\n\n\t/**\n\t * Select one or more shapes.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.select('id1')\n\t * editor.select('id1', 'id2')\n\t * ```\n\t *\n\t * @param ids - The ids to select.\n\t *\n\t * @public\n\t */\n\tselect(...shapes: TLShapeId[] | TLShape[]): this {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((shape) => shape.id)\n\t\tthis.setSelectedShapes(ids)\n\t\treturn this\n\t}\n\n\t/**\n\t * Remove a shape from the existing set of selected shapes.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.deselect(shape.id)\n\t * ```\n\t *\n\t * @public\n\t */\n\tdeselect(...shapes: TLShapeId[] | TLShape[]): this {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((shape) => shape.id)\n\t\tconst selectedShapeIds = this.getSelectedShapeIds()\n\t\tif (selectedShapeIds.length > 0 && ids.length > 0) {\n\t\t\tthis.setSelectedShapes(selectedShapeIds.filter((id) => !ids.includes(id)))\n\t\t}\n\t\treturn this\n\t}\n\n\t/**\n\t * Select all direct children of the current page.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.selectAll()\n\t * ```\n\t *\n\t * @public\n\t */\n\tselectAll(): this {\n\t\tconst ids = this.getSortedChildIdsForParent(this.getCurrentPageId())\n\t\t// page might have no shapes\n\t\tif (ids.length <= 0) return this\n\t\tthis.setSelectedShapes(this._getUnlockedShapeIds(ids))\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Clear the selection.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.selectNone()\n\t * ```\n\t *\n\t * @public\n\t */\n\tselectNone(): this {\n\t\tif (this.getSelectedShapeIds().length > 0) {\n\t\t\tthis.setSelectedShapes([])\n\t\t}\n\n\t\treturn this\n\t}\n\n\t/**\n\t * The id of the app's only selected shape.\n\t *\n\t * @returns Null if there is no shape or more than one selected shape, otherwise the selected shape's id.\n\t *\n\t * @public\n\t * @readonly\n\t */\n\t@computed getOnlySelectedShapeId(): TLShapeId | null {\n\t\treturn this.getOnlySelectedShape()?.id ?? null\n\t}\n\n\t/**\n\t * The app's only selected shape.\n\t *\n\t * @returns Null if there is no shape or more than one selected shape, otherwise the selected shape.\n\t *\n\t * @public\n\t * @readonly\n\t */\n\t@computed getOnlySelectedShape(): TLShape | null {\n\t\tconst selectedShapes = this.getSelectedShapes()\n\t\treturn selectedShapes.length === 1 ? selectedShapes[0] : null\n\t}\n\n\t/**\n\t * @internal\n\t */\n\tgetShapesPageBounds(shapeIds: TLShapeId[]): Box | null {\n\t\tconst bounds = compact(shapeIds.map((id) => this.getShapePageBounds(id)))\n\t\tif (bounds.length === 0) return null\n\t\treturn Box.Common(bounds)\n\t}\n\n\t/**\n\t * The current page bounds of all the selected shapes. If the\n\t * selection is rotated, then these bounds are the axis-aligned\n\t * box that the rotated bounds would fit inside of.\n\t *\n\t * @readonly\n\t *\n\t * @public\n\t */\n\t@computed getSelectionPageBounds(): Box | null {\n\t\treturn this.getShapesPageBounds(this.getSelectedShapeIds())\n\t}\n\n\t/**\n\t * @internal\n\t */\n\tgetShapesSharedRotation(shapeIds: TLShapeId[]) {\n\t\tlet foundFirst = false // annoying but we can't use an i===0 check because we need to skip over undefineds\n\t\tlet rotation = 0\n\t\tfor (let i = 0, n = shapeIds.length; i < n; i++) {\n\t\t\tconst pageTransform = this.getShapePageTransform(shapeIds[i])\n\t\t\tif (!pageTransform) continue\n\t\t\tif (foundFirst) {\n\t\t\t\tif (pageTransform.rotation() !== rotation) {\n\t\t\t\t\t// There are at least 2 different rotations, so the common rotation is zero\n\t\t\t\t\treturn 0\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// First rotation found\n\t\t\t\tfoundFirst = true\n\t\t\t\trotation = pageTransform.rotation()\n\t\t\t}\n\t\t}\n\n\t\treturn rotation\n\t}\n\n\t/**\n\t * The rotation of the selection bounding box in the current page space.\n\t *\n\t * @readonly\n\t * @public\n\t */\n\t@computed getSelectionRotation(): number {\n\t\treturn this.getShapesSharedRotation(this.getSelectedShapeIds())\n\t}\n\n\t/**\n\t * @internal\n\t */\n\tgetShapesRotatedPageBounds(shapeIds: TLShapeId[]): Box | undefined {\n\t\tif (shapeIds.length === 0) {\n\t\t\treturn undefined\n\t\t}\n\n\t\tconst selectionRotation = this.getShapesSharedRotation(shapeIds)\n\t\tif (selectionRotation === 0) {\n\t\t\treturn this.getShapesPageBounds(shapeIds) ?? undefined\n\t\t}\n\n\t\tif (shapeIds.length === 1) {\n\t\t\tconst bounds = this.getShapeGeometry(shapeIds[0]).bounds.clone()\n\t\t\tconst pageTransform = this.getShapePageTransform(shapeIds[0])!\n\t\t\tbounds.point = pageTransform.applyToPoint(bounds.point)\n\t\t\treturn bounds\n\t\t}\n\n\t\t// need to 'un-rotate' all the outlines of the existing nodes so we can fit them inside a box\n\t\tconst boxFromRotatedVertices = Box.FromPoints(\n\t\t\tshapeIds\n\t\t\t\t.flatMap((id) => {\n\t\t\t\t\tconst pageTransform = this.getShapePageTransform(id)\n\t\t\t\t\tif (!pageTransform) return []\n\t\t\t\t\treturn pageTransform.applyToPoints(this.getShapeGeometry(id).bounds.corners)\n\t\t\t\t})\n\t\t\t\t.map((p) => p.rot(-selectionRotation))\n\t\t)\n\t\t// now position box so that it's top-left corner is in the right place\n\t\tboxFromRotatedVertices.point = boxFromRotatedVertices.point.rot(selectionRotation)\n\t\treturn boxFromRotatedVertices\n\t}\n\n\t/**\n\t * The bounds of the selection bounding box in the current page space.\n\t *\n\t * @readonly\n\t * @public\n\t */\n\t@computed getSelectionRotatedPageBounds(): Box | undefined {\n\t\treturn this.getShapesRotatedPageBounds(this.getSelectedShapeIds())\n\t}\n\n\t/**\n\t * The bounds of the selection bounding box in the current page space.\n\t *\n\t * @readonly\n\t * @public\n\t */\n\t@computed getSelectionRotatedScreenBounds(): Box | undefined {\n\t\tconst bounds = this.getSelectionRotatedPageBounds()\n\t\tif (!bounds) return undefined\n\t\tconst { x, y } = this.pageToScreen(bounds.point)\n\t\tconst zoom = this.getZoomLevel()\n\t\treturn new Box(x, y, bounds.width * zoom, bounds.height * zoom)\n\t}\n\n\t// Focus Group\n\n\t/**\n\t * The current focused group id.\n\t *\n\t * @public\n\t */\n\t@computed getFocusedGroupId(): TLShapeId | TLPageId {\n\t\treturn this.getCurrentPageState().focusedGroupId ?? this.getCurrentPageId()\n\t}\n\n\t/**\n\t * The current focused group.\n\t *\n\t * @public\n\t */\n\t@computed getFocusedGroup(): TLShape | undefined {\n\t\tconst focusedGroupId = this.getFocusedGroupId()\n\t\treturn focusedGroupId ? this.getShape(focusedGroupId) : undefined\n\t}\n\n\t/**\n\t * Set the current focused group shape.\n\t *\n\t * @param shape - The group shape id (or group shape's id) to set as the focused group shape.\n\t *\n\t * @public\n\t */\n\tsetFocusedGroup(shape: TLShapeId | TLGroupShape | null): this {\n\t\tconst id = typeof shape === 'string' ? shape : shape?.id ?? null\n\n\t\tif (id !== null) {\n\t\t\tconst shape = this.getShape(id)\n\t\t\tif (!shape) {\n\t\t\t\tthrow Error(`Editor.setFocusedGroup: Shape with id ${id} does not exist`)\n\t\t\t}\n\n\t\t\tif (!this.isShapeOfType(shape, 'group')) {\n\t\t\t\tthrow Error(\n\t\t\t\t\t`Editor.setFocusedGroup: Cannot set focused group to shape of type ${shape.type}`\n\t\t\t\t)\n\t\t\t}\n\t\t}\n\n\t\tif (id === this.getFocusedGroupId()) return this\n\n\t\treturn this.run(\n\t\t\t() => {\n\t\t\t\tthis.store.update(this.getCurrentPageState().id, (s) => ({ ...s, focusedGroupId: id }))\n\t\t\t},\n\t\t\t{ history: 'record-preserveRedoStack' }\n\t\t)\n\t}\n\n\t/**\n\t * Exit the current focused group, moving up to the next parent group if there is one.\n\t *\n\t * @public\n\t */\n\tpopFocusedGroupId(): this {\n\t\tconst focusedGroup = this.getFocusedGroup()\n\n\t\tif (focusedGroup) {\n\t\t\t// If we have a focused layer, look for an ancestor of the focused shape that is a group\n\t\t\tconst match = this.findShapeAncestor(focusedGroup, (shape) =>\n\t\t\t\tthis.isShapeOfType(shape, 'group')\n\t\t\t)\n\t\t\t// If we have an ancestor that can become a focused layer, set it as the focused layer\n\t\t\tthis.setFocusedGroup(match?.id ?? null)\n\t\t\tthis.select(focusedGroup.id)\n\t\t} else {\n\t\t\t// If there's no parent focused group, then clear the focus layer and clear selection\n\t\t\tthis.setFocusedGroup(null)\n\t\t\tthis.selectNone()\n\t\t}\n\n\t\treturn this\n\t}\n\n\t/**\n\t * The current editing shape's id.\n\t *\n\t * @public\n\t */\n\t@computed getEditingShapeId(): TLShapeId | null {\n\t\treturn this.getCurrentPageState().editingShapeId\n\t}\n\n\t/**\n\t * The current editing shape.\n\t *\n\t * @public\n\t */\n\t@computed getEditingShape(): TLShape | undefined {\n\t\tconst editingShapeId = this.getEditingShapeId()\n\t\treturn editingShapeId ? this.getShape(editingShapeId) : undefined\n\t}\n\n\t/**\n\t * Set the current editing shape.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.setEditingShape(myShape)\n\t * editor.setEditingShape(myShape.id)\n\t * ```\n\t *\n\t * @param shape - The shape (or shape id) to set as editing.\n\t *\n\t * @public\n\t */\n\tsetEditingShape(shape: TLShapeId | TLShape | null): this {\n\t\tconst id = typeof shape === 'string' ? shape : shape?.id ?? null\n\t\tif (id !== this.getEditingShapeId()) {\n\t\t\tif (id) {\n\t\t\t\tconst shape = this.getShape(id)\n\t\t\t\tif (shape && this.getShapeUtil(shape).canEdit(shape)) {\n\t\t\t\t\tthis.run(\n\t\t\t\t\t\t() => {\n\t\t\t\t\t\t\tthis._updateCurrentPageState({ editingShapeId: id })\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{ history: 'ignore' }\n\t\t\t\t\t)\n\t\t\t\t\treturn this\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Either we just set the editing id to null, or the shape was missing or not editable\n\t\t\tthis.run(\n\t\t\t\t() => {\n\t\t\t\t\tthis._updateCurrentPageState({ editingShapeId: null })\n\t\t\t\t},\n\t\t\t\t{ history: 'ignore' }\n\t\t\t)\n\t\t}\n\t\treturn this\n\t}\n\n\t// Hovered\n\n\t/**\n\t * The current hovered shape id.\n\t *\n\t * @readonly\n\t * @public\n\t */\n\t@computed getHoveredShapeId(): TLShapeId | null {\n\t\treturn this.getCurrentPageState().hoveredShapeId\n\t}\n\n\t/**\n\t * The current hovered shape.\n\t *\n\t * @public\n\t */\n\t@computed getHoveredShape(): TLShape | undefined {\n\t\tconst hoveredShapeId = this.getHoveredShapeId()\n\t\treturn hoveredShapeId ? this.getShape(hoveredShapeId) : undefined\n\t}\n\t/**\n\t * Set the editor's current hovered shape.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.setHoveredShape(myShape)\n\t * editor.setHoveredShape(myShape.id)\n\t * ```\n\t *\n\t * @param shapes - The shape (or shape id) to set as hovered.\n\t *\n\t * @public\n\t */\n\tsetHoveredShape(shape: TLShapeId | TLShape | null): this {\n\t\tconst id = typeof shape === 'string' ? shape : shape?.id ?? null\n\t\tif (id === this.getHoveredShapeId()) return this\n\t\tthis.run(\n\t\t\t() => {\n\t\t\t\tthis.updateCurrentPageState({ hoveredShapeId: id })\n\t\t\t},\n\t\t\t{ history: 'ignore' }\n\t\t)\n\t\treturn this\n\t}\n\n\t// Hinting\n\n\t/**\n\t * The editor's current hinting shape ids.\n\t *\n\t * @public\n\t */\n\t@computed getHintingShapeIds() {\n\t\treturn this.getCurrentPageState().hintingShapeIds\n\t}\n\t/**\n\t * The editor's current hinting shapes.\n\t *\n\t * @public\n\t */\n\t@computed getHintingShape() {\n\t\tconst hintingShapeIds = this.getHintingShapeIds()\n\t\treturn compact(hintingShapeIds.map((id) => this.getShape(id)))\n\t}\n\n\t/**\n\t * Set the editor's current hinting shapes.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.setHintingShapes([myShape])\n\t * editor.setHintingShapes([myShape.id])\n\t * ```\n\t *\n\t * @param shapes - The shapes (or shape ids) to set as hinting.\n\t *\n\t * @public\n\t */\n\tsetHintingShapes(shapes: TLShapeId[] | TLShape[]): this {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((shape) => shape.id)\n\t\t// always ephemeral\n\t\tthis.run(\n\t\t\t() => {\n\t\t\t\tthis._updateCurrentPageState({ hintingShapeIds: dedupe(ids) })\n\t\t\t},\n\t\t\t{ history: 'ignore' }\n\t\t)\n\t\treturn this\n\t}\n\n\t// Erasing\n\n\t/**\n\t * The editor's current erasing ids.\n\t *\n\t * @public\n\t */\n\t@computed getErasingShapeIds() {\n\t\treturn this.getCurrentPageState().erasingShapeIds\n\t}\n\n\t/**\n\t * The editor's current erasing shapes.\n\t *\n\t * @public\n\t */\n\t@computed getErasingShapes() {\n\t\tconst erasingShapeIds = this.getErasingShapeIds()\n\t\treturn compact(erasingShapeIds.map((id) => this.getShape(id)))\n\t}\n\n\t/**\n\t * Set the editor's current erasing shapes.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.setErasingShapes([myShape])\n\t * editor.setErasingShapes([myShape.id])\n\t * ```\n\t *\n\t * @param shapes - The shapes (or shape ids) to set as hinting.\n\t *\n\t * @public\n\t */\n\tsetErasingShapes(shapes: TLShapeId[] | TLShape[]): this {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((shape) => shape.id)\n\t\tids.sort() // sort the incoming ids\n\t\tconst erasingShapeIds = this.getErasingShapeIds()\n\t\tthis.run(\n\t\t\t() => {\n\t\t\t\tif (ids.length === erasingShapeIds.length) {\n\t\t\t\t\t// if the new ids are the same length as the current ids, they might be the same.\n\t\t\t\t\t// presuming the current ids are also sorted, check each item to see if it's the same;\n\t\t\t\t\t// if we find any unequal, then we know the new ids are different.\n\t\t\t\t\tfor (let i = 0; i < ids.length; i++) {\n\t\t\t\t\t\tif (ids[i] !== erasingShapeIds[i]) {\n\t\t\t\t\t\t\tthis._updateCurrentPageState({ erasingShapeIds: ids })\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t// if the ids are a different length, then we know they're different.\n\t\t\t\t\tthis._updateCurrentPageState({ erasingShapeIds: ids })\n\t\t\t\t}\n\t\t\t},\n\t\t\t{ history: 'ignore' }\n\t\t)\n\n\t\treturn this\n\t}\n\n\t// Cropping\n\n\t/**\n\t * The current cropping shape's id.\n\t *\n\t * @public\n\t */\n\tgetCroppingShapeId() {\n\t\treturn this.getCurrentPageState().croppingShapeId\n\t}\n\n\t/**\n\t * Set the current cropping shape.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.setCroppingShape(myShape)\n\t * editor.setCroppingShape(myShape.id)\n\t * ```\n\t *\n\t *\n\t * @param shape - The shape (or shape id) to set as cropping.\n\t *\n\t * @public\n\t */\n\tsetCroppingShape(shape: TLShapeId | TLShape | null): this {\n\t\tconst id = typeof shape === 'string' ? shape : shape?.id ?? null\n\t\tif (id !== this.getCroppingShapeId()) {\n\t\t\tthis.run(\n\t\t\t\t() => {\n\t\t\t\t\tif (!id) {\n\t\t\t\t\t\tthis.updateCurrentPageState({ croppingShapeId: null })\n\t\t\t\t\t} else {\n\t\t\t\t\t\tconst shape = this.getShape(id)!\n\t\t\t\t\t\tconst util = this.getShapeUtil(shape)\n\t\t\t\t\t\tif (shape && util.canCrop(shape)) {\n\t\t\t\t\t\t\tthis.updateCurrentPageState({ croppingShapeId: id })\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\t{ history: 'ignore' }\n\t\t\t)\n\t\t}\n\t\treturn this\n\t}\n\n\t/* --------------------- Camera --------------------- */\n\n\t/** @internal */\n\t@computed\n\tprivate _unsafe_getCameraId() {\n\t\treturn CameraRecordType.createId(this.getCurrentPageId())\n\t}\n\n\t/**\n\t * The current camera.\n\t *\n\t * @public\n\t */\n\t@computed getCamera(): TLCamera {\n\t\tconst baseCamera = this.store.get(this._unsafe_getCameraId())!\n\t\tif (this._isLockedOnFollowingUser.get()) {\n\t\t\tconst followingCamera = this.getCameraForFollowing()\n\t\t\tif (followingCamera) {\n\t\t\t\treturn { ...baseCamera, ...followingCamera }\n\t\t\t}\n\t\t}\n\t\treturn baseCamera\n\t}\n\n\t@computed\n\tprivate getViewportPageBoundsForFollowing(): null | Box {\n\t\tconst followingUserId = this.getInstanceState().followingUserId\n\t\tif (!followingUserId) return null\n\t\tconst leaderPresence = this.getCollaborators().find((c) => c.userId === followingUserId)\n\t\tif (!leaderPresence) return null\n\n\t\t// Fit their viewport inside of our screen bounds\n\t\t// 1. calculate their viewport in page space\n\t\tconst { w: lw, h: lh } = leaderPresence.screenBounds\n\t\tconst { x: lx, y: ly, z: lz } = leaderPresence.camera\n\t\tconst theirViewport = new Box(-lx, -ly, lw / lz, lh / lz)\n\n\t\t// resize our screenBounds to contain their viewport\n\t\tconst ourViewport = this.getViewportScreenBounds().clone()\n\t\tconst ourAspectRatio = ourViewport.width / ourViewport.height\n\n\t\tourViewport.width = theirViewport.width\n\t\tourViewport.height = ourViewport.width / ourAspectRatio\n\t\tif (ourViewport.height < theirViewport.height) {\n\t\t\tourViewport.height = theirViewport.height\n\t\t\tourViewport.width = ourViewport.height * ourAspectRatio\n\t\t}\n\n\t\tourViewport.center = theirViewport.center\n\t\treturn ourViewport\n\t}\n\n\t@computed\n\tprivate getCameraForFollowing(): null | { x: number; y: number; z: number } {\n\t\tconst viewport = this.getViewportPageBoundsForFollowing()\n\t\tif (!viewport) return null\n\n\t\treturn {\n\t\t\tx: -viewport.x,\n\t\t\ty: -viewport.y,\n\t\t\tz: this.getViewportScreenBounds().w / viewport.width,\n\t\t}\n\t}\n\n\t/**\n\t * The current camera zoom level.\n\t *\n\t * @public\n\t */\n\t@computed getZoomLevel() {\n\t\treturn this.getCamera().z\n\t}\n\n\t/**\n\t * Get the camera's initial or reset zoom level.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getInitialZoom()\n\t * ```\n\t *\n\t * @public */\n\tgetInitialZoom() {\n\t\tconst cameraOptions = this.getCameraOptions()\n\t\t// If no camera constraints are provided, the default zoom is 100%\n\t\tif (!cameraOptions.constraints) return 1\n\n\t\t// When defaultZoom is default, the default zoom is 100%\n\t\tif (cameraOptions.constraints.initialZoom === 'default') return 1\n\n\t\tconst { zx, zy } = getCameraFitXFitY(this, cameraOptions)\n\n\t\tswitch (cameraOptions.constraints.initialZoom) {\n\t\t\tcase 'fit-min': {\n\t\t\t\treturn Math.max(zx, zy)\n\t\t\t}\n\t\t\tcase 'fit-max': {\n\t\t\t\treturn Math.min(zx, zy)\n\t\t\t}\n\t\t\tcase 'fit-x': {\n\t\t\t\treturn zx\n\t\t\t}\n\t\t\tcase 'fit-y': {\n\t\t\t\treturn zy\n\t\t\t}\n\t\t\tcase 'fit-min-100': {\n\t\t\t\treturn Math.min(1, Math.max(zx, zy))\n\t\t\t}\n\t\t\tcase 'fit-max-100': {\n\t\t\t\treturn Math.min(1, Math.min(zx, zy))\n\t\t\t}\n\t\t\tcase 'fit-x-100': {\n\t\t\t\treturn Math.min(1, zx)\n\t\t\t}\n\t\t\tcase 'fit-y-100': {\n\t\t\t\treturn Math.min(1, zy)\n\t\t\t}\n\t\t\tdefault: {\n\t\t\t\tthrow exhaustiveSwitchError(cameraOptions.constraints.initialZoom)\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Get the camera's base level for calculating actual zoom levels based on the zoom steps.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getBaseZoom()\n\t * ```\n\t *\n\t * @public */\n\tgetBaseZoom() {\n\t\tconst cameraOptions = this.getCameraOptions()\n\t\t// If no camera constraints are provided, the default zoom is 100%\n\t\tif (!cameraOptions.constraints) return 1\n\n\t\t// When defaultZoom is default, the default zoom is 100%\n\t\tif (cameraOptions.constraints.baseZoom === 'default') return 1\n\n\t\tconst { zx, zy } = getCameraFitXFitY(this, cameraOptions)\n\n\t\tswitch (cameraOptions.constraints.baseZoom) {\n\t\t\tcase 'fit-min': {\n\t\t\t\treturn Math.max(zx, zy)\n\t\t\t}\n\t\t\tcase 'fit-max': {\n\t\t\t\treturn Math.min(zx, zy)\n\t\t\t}\n\t\t\tcase 'fit-x': {\n\t\t\t\treturn zx\n\t\t\t}\n\t\t\tcase 'fit-y': {\n\t\t\t\treturn zy\n\t\t\t}\n\t\t\tcase 'fit-min-100': {\n\t\t\t\treturn Math.min(1, Math.max(zx, zy))\n\t\t\t}\n\t\t\tcase 'fit-max-100': {\n\t\t\t\treturn Math.min(1, Math.min(zx, zy))\n\t\t\t}\n\t\t\tcase 'fit-x-100': {\n\t\t\t\treturn Math.min(1, zx)\n\t\t\t}\n\t\t\tcase 'fit-y-100': {\n\t\t\t\treturn Math.min(1, zy)\n\t\t\t}\n\t\t\tdefault: {\n\t\t\t\tthrow exhaustiveSwitchError(cameraOptions.constraints.baseZoom)\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate _cameraOptions = atom('camera options', DEFAULT_CAMERA_OPTIONS)\n\n\t/**\n\t * Get the current camera options.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getCameraOptions()\n\t * ```\n\t *\n\t * @public */\n\tgetCameraOptions() {\n\t\treturn this._cameraOptions.get()\n\t}\n\n\t/**\n\t * Set the camera options. Changing the options won't immediately change the camera itself, so you may want to call `setCamera` after changing the options.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.setCameraOptions(myCameraOptions)\n\t * editor.setCamera(editor.getCamera())\n\t * ```\n\t *\n\t * @param options - The camera options to set.\n\t *\n\t * @public */\n\tsetCameraOptions(options: Partial) {\n\t\tconst next = structuredClone({\n\t\t\t...this._cameraOptions.__unsafe__getWithoutCapture(),\n\t\t\t...options,\n\t\t})\n\t\tif (next.zoomSteps?.length < 1) next.zoomSteps = [1]\n\t\tthis._cameraOptions.set(next)\n\t\treturn this\n\t}\n\n\t/** @internal */\n\tprivate getConstrainedCamera(\n\t\tpoint: VecLike,\n\t\topts?: TLCameraMoveOptions\n\t): {\n\t\tx: number\n\t\ty: number\n\t\tz: number\n\t} {\n\t\tconst currentCamera = this.getCamera()\n\n\t\tlet { x, y, z = currentCamera.z } = point\n\n\t\t// If force is true, then we'll set the camera to the point regardless of\n\t\t// the camera options, so that we can handle gestures that permit elasticity\n\t\t// or decay, or animations that occur while the camera is locked.\n\t\tif (!opts?.force) {\n\t\t\t// Apply any adjustments based on the camera options\n\n\t\t\tconst cameraOptions = this.getCameraOptions()\n\n\t\t\tconst zoomMin = cameraOptions.zoomSteps[0]\n\t\t\tconst zoomMax = last(cameraOptions.zoomSteps)!\n\n\t\t\tconst vsb = this.getViewportScreenBounds()\n\n\t\t\t// If bounds are provided, then we'll keep those bounds on screen\n\t\t\tif (cameraOptions.constraints) {\n\t\t\t\tconst { constraints } = cameraOptions\n\n\t\t\t\t// Clamp padding to half the viewport size on either dimension\n\t\t\t\tconst py = Math.min(constraints.padding.y, vsb.w / 2)\n\t\t\t\tconst px = Math.min(constraints.padding.x, vsb.h / 2)\n\n\t\t\t\t// Expand the bounds by the padding\n\t\t\t\tconst bounds = Box.From(cameraOptions.constraints.bounds)\n\n\t\t\t\t// For each axis, the \"natural zoom\" is the zoom at\n\t\t\t\t// which the expanded bounds (with padding) would fit\n\t\t\t\t// the current viewport screen bounds. Paddings are\n\t\t\t\t// equal to screen pixels at 100%\n\t\t\t\t// The min and max zooms are factors of the smaller natural zoom axis\n\n\t\t\t\tconst zx = (vsb.w - px * 2) / bounds.w\n\t\t\t\tconst zy = (vsb.h - py * 2) / bounds.h\n\n\t\t\t\tconst baseZoom = this.getBaseZoom()\n\t\t\t\tconst maxZ = zoomMax * baseZoom\n\t\t\t\tconst minZ = zoomMin * baseZoom\n\n\t\t\t\tif (opts?.reset) {\n\t\t\t\t\tz = this.getInitialZoom()\n\t\t\t\t}\n\n\t\t\t\tif (z < minZ || z > maxZ) {\n\t\t\t\t\t// We're trying to zoom out past the minimum zoom level,\n\t\t\t\t\t// or in past the maximum zoom level, so stop the camera\n\t\t\t\t\t// but keep the current center\n\t\t\t\t\tconst { x: cx, y: cy, z: cz } = currentCamera\n\t\t\t\t\tconst cxA = -cx + vsb.w / cz / 2\n\t\t\t\t\tconst cyA = -cy + vsb.h / cz / 2\n\t\t\t\t\tz = clamp(z, minZ, maxZ)\n\t\t\t\t\tconst cxB = -cx + vsb.w / z / 2\n\t\t\t\t\tconst cyB = -cy + vsb.h / z / 2\n\t\t\t\t\tx = cx + cxB - cxA\n\t\t\t\t\ty = cy + cyB - cyA\n\t\t\t\t}\n\n\t\t\t\t// Calculate available space\n\t\t\t\tconst minX = px / z - bounds.x\n\t\t\t\tconst minY = py / z - bounds.y\n\t\t\t\tconst freeW = (vsb.w - px * 2) / z - bounds.w\n\t\t\t\tconst freeH = (vsb.h - py * 2) / z - bounds.h\n\t\t\t\tconst originX = minX + freeW * constraints.origin.x\n\t\t\t\tconst originY = minY + freeH * constraints.origin.y\n\n\t\t\t\tconst behaviorX =\n\t\t\t\t\ttypeof constraints.behavior === 'string' ? constraints.behavior : constraints.behavior.x\n\t\t\t\tconst behaviorY =\n\t\t\t\t\ttypeof constraints.behavior === 'string' ? constraints.behavior : constraints.behavior.y\n\n\t\t\t\t// x axis\n\n\t\t\t\tif (opts?.reset) {\n\t\t\t\t\t// Reset the camera according to the origin\n\t\t\t\t\tx = originX\n\t\t\t\t\ty = originY\n\t\t\t\t} else {\n\t\t\t\t\t// Apply constraints to the camera\n\t\t\t\t\tswitch (behaviorX) {\n\t\t\t\t\t\tcase 'fixed': {\n\t\t\t\t\t\t\t// Center according to the origin\n\t\t\t\t\t\t\tx = originX\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcase 'contain': {\n\t\t\t\t\t\t\t// When below fit zoom, center the camera\n\t\t\t\t\t\t\tif (z < zx) x = originX\n\t\t\t\t\t\t\t// When above fit zoom, keep the bounds within padding distance of the viewport edge\n\t\t\t\t\t\t\telse x = clamp(x, minX + freeW, minX)\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcase 'inside': {\n\t\t\t\t\t\t\t// When below fit zoom, constrain the camera so that the bounds stay completely within the viewport\n\t\t\t\t\t\t\tif (z < zx) x = clamp(x, minX, (vsb.w - px) / z - bounds.w)\n\t\t\t\t\t\t\t// When above fit zoom, keep the bounds within padding distance of the viewport edge\n\t\t\t\t\t\t\telse x = clamp(x, minX + freeW, minX)\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcase 'outside': {\n\t\t\t\t\t\t\t// Constrain the camera so that the bounds never leaves the viewport\n\t\t\t\t\t\t\tx = clamp(x, px / z - bounds.w, (vsb.w - px) / z)\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcase 'free': {\n\t\t\t\t\t\t\t// noop, use whatever x is provided\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t\tdefault: {\n\t\t\t\t\t\t\tthrow exhaustiveSwitchError(behaviorX)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// y axis\n\n\t\t\t\t\tswitch (behaviorY) {\n\t\t\t\t\t\tcase 'fixed': {\n\t\t\t\t\t\t\ty = originY\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcase 'contain': {\n\t\t\t\t\t\t\tif (z < zy) y = originY\n\t\t\t\t\t\t\telse y = clamp(y, minY + freeH, minY)\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcase 'inside': {\n\t\t\t\t\t\t\tif (z < zy) y = clamp(y, minY, (vsb.h - py) / z - bounds.h)\n\t\t\t\t\t\t\telse y = clamp(y, minY + freeH, minY)\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcase 'outside': {\n\t\t\t\t\t\t\ty = clamp(y, py / z - bounds.h, (vsb.h - py) / z)\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcase 'free': {\n\t\t\t\t\t\t\t// noop, use whatever x is provided\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t\tdefault: {\n\t\t\t\t\t\t\tthrow exhaustiveSwitchError(behaviorY)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// constrain the zoom, preserving the center\n\t\t\t\tif (z > zoomMax || z < zoomMin) {\n\t\t\t\t\tconst { x: cx, y: cy, z: cz } = currentCamera\n\t\t\t\t\tz = clamp(z, zoomMin, zoomMax)\n\t\t\t\t\tx = cx + (-cx + vsb.w / z / 2) - (-cx + vsb.w / cz / 2)\n\t\t\t\t\ty = cy + (-cy + vsb.h / z / 2) - (-cy + vsb.h / cz / 2)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn { x, y, z }\n\t}\n\n\t/** @internal */\n\tprivate _setCamera(point: VecLike, opts?: TLCameraMoveOptions): this {\n\t\tconst currentCamera = this.getCamera()\n\n\t\tconst { x, y, z } = this.getConstrainedCamera(point, opts)\n\n\t\tif (currentCamera.x === x && currentCamera.y === y && currentCamera.z === z) {\n\t\t\treturn this\n\t\t}\n\n\t\ttransact(() => {\n\t\t\tconst camera = { ...currentCamera, x, y, z }\n\t\t\tthis.run(\n\t\t\t\t() => {\n\t\t\t\t\tthis.store.put([camera]) // include id and meta here\n\t\t\t\t},\n\t\t\t\t{ history: 'ignore' }\n\t\t\t)\n\n\t\t\t// Dispatch a new pointer move because the pointer's page will have changed\n\t\t\t// (its screen position will compute to a new page position given the new camera position)\n\t\t\tconst { currentScreenPoint, currentPagePoint } = this.inputs\n\t\t\tconst { screenBounds } = this.store.unsafeGetWithoutCapture(TLINSTANCE_ID)!\n\n\t\t\t// compare the next page point (derived from the current camera) to the current page point\n\t\t\tif (\n\t\t\t\tcurrentScreenPoint.x / z - x !== currentPagePoint.x ||\n\t\t\t\tcurrentScreenPoint.y / z - y !== currentPagePoint.y\n\t\t\t) {\n\t\t\t\t// If it's changed, dispatch a pointer event\n\t\t\t\tconst event: TLPointerEventInfo = {\n\t\t\t\t\ttype: 'pointer',\n\t\t\t\t\ttarget: 'canvas',\n\t\t\t\t\tname: 'pointer_move',\n\t\t\t\t\t// weird but true: we need to put the screen point back into client space\n\t\t\t\t\tpoint: Vec.AddXY(currentScreenPoint, screenBounds.x, screenBounds.y),\n\t\t\t\t\tpointerId: INTERNAL_POINTER_IDS.CAMERA_MOVE,\n\t\t\t\t\tctrlKey: this.inputs.ctrlKey,\n\t\t\t\t\taltKey: this.inputs.altKey,\n\t\t\t\t\tshiftKey: this.inputs.shiftKey,\n\t\t\t\t\tbutton: 0,\n\t\t\t\t\tisPen: this.getInstanceState().isPenMode ?? false,\n\t\t\t\t}\n\n\t\t\t\tif (opts?.immediate) {\n\t\t\t\t\tthis._flushEventForTick(event)\n\t\t\t\t} else {\n\t\t\t\t\tthis.dispatch(event)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tthis._tickCameraState()\n\t\t})\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Set the current camera.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.setCamera({ x: 0, y: 0})\n\t * editor.setCamera({ x: 0, y: 0, z: 1.5})\n\t * editor.setCamera({ x: 0, y: 0, z: 1.5}, { animation: { duration: 1000, easing: (t) => t * t } })\n\t * ```\n\t *\n\t * @param point - The new camera position.\n\t * @param opts - The camera move options.\n\t *\n\t * @public\n\t */\n\tsetCamera(point: VecLike, opts?: TLCameraMoveOptions): this {\n\t\tconst { isLocked } = this._cameraOptions.__unsafe__getWithoutCapture()\n\t\tif (isLocked && !opts?.force) return this\n\n\t\t// Stop any camera animations\n\t\tthis.stopCameraAnimation()\n\n\t\t// Stop following any user\n\t\tif (this.getInstanceState().followingUserId) {\n\t\t\tthis.stopFollowingUser()\n\t\t}\n\n\t\tconst _point = Vec.Cast(point)\n\n\t\tif (!Number.isFinite(_point.x)) _point.x = 0\n\t\tif (!Number.isFinite(_point.y)) _point.y = 0\n\t\tif (_point.z === undefined || !Number.isFinite(_point.z)) point.z = this.getZoomLevel()\n\n\t\tconst camera = this.getConstrainedCamera(_point, opts)\n\n\t\tif (opts?.animation) {\n\t\t\tconst { width, height } = this.getViewportScreenBounds()\n\t\t\tthis._animateToViewport(\n\t\t\t\tnew Box(-camera.x, -camera.y, width / camera.z, height / camera.z),\n\t\t\t\topts\n\t\t\t)\n\t\t} else {\n\t\t\tthis._setCamera(camera, {\n\t\t\t\t...opts,\n\t\t\t\t// we already did the constraining, so we don't need to do it again\n\t\t\t\tforce: true,\n\t\t\t})\n\t\t}\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Center the camera on a point (in the current page space).\n\t *\n\t * @example\n\t * ```ts\n\t * editor.centerOnPoint({ x: 100, y: 100 })\n\t * editor.centerOnPoint({ x: 100, y: 100 }, { animation: { duration: 200 } })\n\t * ```\n\t *\n\t * @param point - The point in the current page space to center on.\n\t * @param animation - The camera move options.\n\t *\n\t * @public\n\t */\n\tcenterOnPoint(point: VecLike, opts?: TLCameraMoveOptions): this {\n\t\tconst { isLocked } = this.getCameraOptions()\n\t\tif (isLocked && !opts?.force) return this\n\n\t\tconst { width: pw, height: ph } = this.getViewportPageBounds()\n\t\tthis.setCamera(new Vec(-(point.x - pw / 2), -(point.y - ph / 2), this.getCamera().z), opts)\n\t\treturn this\n\t}\n\n\t/**\n\t * Zoom the camera to fit the current page's content in the viewport.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.zoomToFit()\n\t * editor.zoomToFit({ animation: { duration: 200 } })\n\t * ```\n\t *\n\t * @param opts - The camera move options.\n\t *\n\t * @public\n\t */\n\tzoomToFit(opts?: TLCameraMoveOptions): this {\n\t\tconst ids = [...this.getCurrentPageShapeIds()]\n\t\tif (ids.length <= 0) return this\n\t\tconst pageBounds = Box.Common(compact(ids.map((id) => this.getShapePageBounds(id))))\n\t\tthis.zoomToBounds(pageBounds, opts)\n\t\treturn this\n\t}\n\n\t/**\n\t * Set the zoom back to 100%.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.resetZoom()\n\t * editor.resetZoom(editor.getViewportScreenCenter(), { animation: { duration: 200 } })\n\t * editor.resetZoom(editor.getViewportScreenCenter(), { animation: { duration: 200 } })\n\t * ```\n\t *\n\t * @param point - The screen point to zoom out on. Defaults to the viewport screen center.\n\t * @param opts - The camera move options.\n\t *\n\t * @public\n\t */\n\tresetZoom(point = this.getViewportScreenCenter(), opts?: TLCameraMoveOptions): this {\n\t\tconst { isLocked, constraints: constraints } = this.getCameraOptions()\n\t\tif (isLocked && !opts?.force) return this\n\n\t\tconst currentCamera = this.getCamera()\n\t\tconst { x: cx, y: cy, z: cz } = currentCamera\n\t\tconst { x, y } = point\n\n\t\tlet z = 1\n\n\t\tif (constraints) {\n\t\t\t// For non-infinite fit, we'll set the camera to the natural zoom level...\n\t\t\t// unless it's already there, in which case we'll set zoom to 100%\n\t\t\tconst initialZoom = this.getInitialZoom()\n\t\t\tif (cz !== initialZoom) {\n\t\t\t\tz = initialZoom\n\t\t\t}\n\t\t}\n\n\t\tthis.setCamera(\n\t\t\tnew Vec(cx + (x / z - x) - (x / cz - x), cy + (y / z - y) - (y / cz - y), z),\n\t\t\topts\n\t\t)\n\t\treturn this\n\t}\n\n\t/**\n\t * Zoom the camera in.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.zoomIn()\n\t * editor.zoomIn(editor.getViewportScreenCenter(), { animation: { duration: 200 } })\n\t * editor.zoomIn(editor.inputs.currentScreenPoint, { animation: { duration: 200 } })\n\t * ```\n\t *\n\t * @param point - The screen point to zoom in on. Defaults to the screen center\n\t * @param opts - The camera move options.\n\t *\n\t * @public\n\t */\n\tzoomIn(point = this.getViewportScreenCenter(), opts?: TLCameraMoveOptions): this {\n\t\tconst { isLocked } = this.getCameraOptions()\n\t\tif (isLocked && !opts?.force) return this\n\n\t\tconst { x: cx, y: cy, z: cz } = this.getCamera()\n\n\t\tconst { zoomSteps } = this.getCameraOptions()\n\t\tif (zoomSteps !== null && zoomSteps.length > 1) {\n\t\t\tconst baseZoom = this.getBaseZoom()\n\t\t\tlet zoom = last(zoomSteps)! * baseZoom\n\t\t\tfor (let i = 1; i < zoomSteps.length; i++) {\n\t\t\t\tconst z1 = zoomSteps[i - 1] * baseZoom\n\t\t\t\tconst z2 = zoomSteps[i] * baseZoom\n\t\t\t\tif (z2 - cz <= (z2 - z1) / 2) continue\n\t\t\t\tzoom = z2\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tthis.setCamera(\n\t\t\t\tnew Vec(\n\t\t\t\t\tcx + (point.x / zoom - point.x) - (point.x / cz - point.x),\n\t\t\t\t\tcy + (point.y / zoom - point.y) - (point.y / cz - point.y),\n\t\t\t\t\tzoom\n\t\t\t\t),\n\t\t\t\topts\n\t\t\t)\n\t\t}\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Zoom the camera out.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.zoomOut()\n\t * editor.zoomOut(editor.getViewportScreenCenter(), { animation: { duration: 120 } })\n\t * editor.zoomOut(editor.inputs.currentScreenPoint, { animation: { duration: 120 } })\n\t * ```\n\t *\n\t * @param point - The point to zoom out on. Defaults to the viewport screen center.\n\t * @param opts - The camera move options.\n\t *\n\t * @public\n\t */\n\tzoomOut(point = this.getViewportScreenCenter(), opts?: TLCameraMoveOptions): this {\n\t\tconst { isLocked } = this.getCameraOptions()\n\t\tif (isLocked && !opts?.force) return this\n\n\t\tconst { zoomSteps } = this.getCameraOptions()\n\t\tif (zoomSteps !== null && zoomSteps.length > 1) {\n\t\t\tconst baseZoom = this.getBaseZoom()\n\t\t\tconst { x: cx, y: cy, z: cz } = this.getCamera()\n\t\t\t// start at the max\n\t\t\tlet zoom = zoomSteps[0] * baseZoom\n\t\t\tfor (let i = zoomSteps.length - 1; i > 0; i--) {\n\t\t\t\tconst z1 = zoomSteps[i - 1] * baseZoom\n\t\t\t\tconst z2 = zoomSteps[i] * baseZoom\n\t\t\t\tif (z2 - cz >= (z2 - z1) / 2) continue\n\t\t\t\tzoom = z1\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tthis.setCamera(\n\t\t\t\tnew Vec(\n\t\t\t\t\tcx + (point.x / zoom - point.x) - (point.x / cz - point.x),\n\t\t\t\t\tcy + (point.y / zoom - point.y) - (point.y / cz - point.y),\n\t\t\t\t\tzoom\n\t\t\t\t),\n\t\t\t\topts\n\t\t\t)\n\t\t}\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Zoom the camera to fit the current selection in the viewport.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.zoomToSelection()\n\t * editor.zoomToSelection({ animation: { duration: 200 } })\n\t * ```\n\t *\n\t * @param animation - The camera move options.\n\t *\n\t * @public\n\t */\n\tzoomToSelection(opts?: TLCameraMoveOptions): this {\n\t\tconst { isLocked } = this.getCameraOptions()\n\t\tif (isLocked && !opts?.force) return this\n\n\t\tconst selectionPageBounds = this.getSelectionPageBounds()\n\t\tif (selectionPageBounds) {\n\t\t\tthis.zoomToBounds(selectionPageBounds, {\n\t\t\t\ttargetZoom: Math.max(1, this.getZoomLevel()),\n\t\t\t\t...opts,\n\t\t\t})\n\t\t}\n\t\treturn this\n\t}\n\n\t/**\n\t * Zoom the camera to fit a bounding box (in the current page space).\n\t *\n\t * @example\n\t * ```ts\n\t * editor.zoomToBounds(myBounds)\n\t * editor.zoomToBounds(myBounds, { animation: { duration: 200 } })\n\t * editor.zoomToBounds(myBounds, { animation: { duration: 200 }, inset: 0, targetZoom: 1 })\n\t * ```\n\t *\n\t * @param bounds - The bounding box.\n\t * @param opts - The camera move options, target zoom, or custom inset amount.\n\t *\n\t * @public\n\t */\n\tzoomToBounds(\n\t\tbounds: BoxLike,\n\t\topts?: { targetZoom?: number; inset?: number } & TLCameraMoveOptions\n\t): this {\n\t\tconst cameraOptions = this._cameraOptions.__unsafe__getWithoutCapture()\n\t\tif (cameraOptions.isLocked && !opts?.force) return this\n\n\t\tconst viewportScreenBounds = this.getViewportScreenBounds()\n\n\t\tconst inset = opts?.inset ?? Math.min(ZOOM_TO_FIT_PADDING, viewportScreenBounds.width * 0.28)\n\n\t\tconst baseZoom = this.getBaseZoom()\n\t\tconst zoomMin = cameraOptions.zoomSteps[0]\n\t\tconst zoomMax = last(cameraOptions.zoomSteps)!\n\n\t\tlet zoom = clamp(\n\t\t\tMath.min(\n\t\t\t\t(viewportScreenBounds.width - inset) / bounds.w,\n\t\t\t\t(viewportScreenBounds.height - inset) / bounds.h\n\t\t\t),\n\t\t\tzoomMin * baseZoom,\n\t\t\tzoomMax * baseZoom\n\t\t)\n\n\t\tif (opts?.targetZoom !== undefined) {\n\t\t\tzoom = Math.min(opts.targetZoom, zoom)\n\t\t}\n\n\t\tthis.setCamera(\n\t\t\tnew Vec(\n\t\t\t\t-bounds.x + (viewportScreenBounds.width - bounds.w * zoom) / 2 / zoom,\n\t\t\t\t-bounds.y + (viewportScreenBounds.height - bounds.h * zoom) / 2 / zoom,\n\t\t\t\tzoom\n\t\t\t),\n\t\t\topts\n\t\t)\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Stop the current camera animation, if any.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.stopCameraAnimation()\n\t * ```\n\t *\n\t * @public\n\t */\n\tstopCameraAnimation(): this {\n\t\tthis.emit('stop-camera-animation')\n\t\treturn this\n\t}\n\n\t/** @internal */\n\tprivate _viewportAnimation = null as null | {\n\t\telapsed: number\n\t\tduration: number\n\t\teasing(t: number): number\n\t\tstart: Box\n\t\tend: Box\n\t}\n\n\t/** @internal */\n\tprivate _animateViewport(ms: number): void {\n\t\tif (!this._viewportAnimation) return\n\n\t\tthis._viewportAnimation.elapsed += ms\n\n\t\tconst { elapsed, easing, duration, start, end } = this._viewportAnimation\n\n\t\tif (elapsed > duration) {\n\t\t\tthis.off('tick', this._animateViewport)\n\t\t\tthis._viewportAnimation = null\n\t\t\tthis._setCamera(new Vec(-end.x, -end.y, this.getViewportScreenBounds().width / end.width))\n\t\t\treturn\n\t\t}\n\n\t\tconst remaining = duration - elapsed\n\t\tconst t = easing(1 - remaining / duration)\n\n\t\tconst left = start.minX + (end.minX - start.minX) * t\n\t\tconst top = start.minY + (end.minY - start.minY) * t\n\t\tconst right = start.maxX + (end.maxX - start.maxX) * t\n\n\t\tthis._setCamera(new Vec(-left, -top, this.getViewportScreenBounds().width / (right - left)), {\n\t\t\tforce: true,\n\t\t})\n\t}\n\n\t/** @internal */\n\tprivate _animateToViewport(\n\t\ttargetViewportPage: Box,\n\t\topts = { animation: DEFAULT_ANIMATION_OPTIONS } as TLCameraMoveOptions\n\t) {\n\t\tconst { animation, ...rest } = opts\n\t\tif (!animation) return\n\t\tconst { duration = 0, easing = EASINGS.easeInOutCubic } = animation\n\t\tconst animationSpeed = this.user.getAnimationSpeed()\n\t\tconst viewportPageBounds = this.getViewportPageBounds()\n\n\t\t// If we have an existing animation, then stop it\n\t\tthis.stopCameraAnimation()\n\n\t\t// also stop following any user\n\t\tif (this.getInstanceState().followingUserId) {\n\t\t\tthis.stopFollowingUser()\n\t\t}\n\n\t\tif (duration === 0 || animationSpeed === 0) {\n\t\t\t// If we have no animation, then skip the animation and just set the camera\n\t\t\treturn this._setCamera(\n\t\t\t\tnew Vec(\n\t\t\t\t\t-targetViewportPage.x,\n\t\t\t\t\t-targetViewportPage.y,\n\t\t\t\t\tthis.getViewportScreenBounds().width / targetViewportPage.width\n\t\t\t\t),\n\t\t\t\t{ ...rest }\n\t\t\t)\n\t\t}\n\n\t\t// Set our viewport animation\n\t\tthis._viewportAnimation = {\n\t\t\telapsed: 0,\n\t\t\tduration: duration / animationSpeed,\n\t\t\teasing,\n\t\t\tstart: viewportPageBounds.clone(),\n\t\t\tend: targetViewportPage.clone(),\n\t\t}\n\n\t\t// If we ever get a \"stop-camera-animation\" event, we stop\n\t\tthis.once('stop-camera-animation', () => {\n\t\t\tthis.off('tick', this._animateViewport)\n\t\t\tthis._viewportAnimation = null\n\t\t})\n\n\t\t// On each tick, animate the viewport\n\t\tthis.on('tick', this._animateViewport)\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Slide the camera in a certain direction.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.slideCamera({ speed: 1, direction: { x: 1, y: 0 }, friction: 0.1 })\n\t * ```\n\t *\n\t * @param opts - Options for the slide\n\t * @public\n\t */\n\tslideCamera(\n\t\topts = {} as {\n\t\t\tspeed: number\n\t\t\tdirection: VecLike\n\t\t\tfriction?: number\n\t\t\tspeedThreshold?: number\n\t\t\tforce?: boolean\n\t\t}\n\t): this {\n\t\tconst { isLocked } = this.getCameraOptions()\n\t\tif (isLocked && !opts?.force) return this\n\n\t\tconst animationSpeed = this.user.getAnimationSpeed()\n\t\tif (animationSpeed === 0) return this\n\n\t\tthis.stopCameraAnimation()\n\n\t\tconst {\n\t\t\tspeed,\n\t\t\tfriction = this.options.cameraSlideFriction,\n\t\t\tdirection,\n\t\t\tspeedThreshold = 0.01,\n\t\t} = opts\n\t\tlet currentSpeed = Math.min(speed, 1)\n\n\t\tconst cancel = () => {\n\t\t\tthis.off('tick', moveCamera)\n\t\t\tthis.off('stop-camera-animation', cancel)\n\t\t}\n\n\t\tthis.once('stop-camera-animation', cancel)\n\n\t\tconst moveCamera = (elapsed: number) => {\n\t\t\tconst { x: cx, y: cy, z: cz } = this.getCamera()\n\t\t\tconst movementVec = Vec.Mul(direction, (currentSpeed * elapsed) / cz)\n\n\t\t\t// Apply friction\n\t\t\tcurrentSpeed *= 1 - friction\n\t\t\tif (currentSpeed < speedThreshold) {\n\t\t\t\tcancel()\n\t\t\t} else {\n\t\t\t\tthis._setCamera(new Vec(cx + movementVec.x, cy + movementVec.y, cz))\n\t\t\t}\n\t\t}\n\n\t\tthis.on('tick', moveCamera)\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Animate the camera to a user's cursor position. This also briefly show the user's cursor if it's not currently visible.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.zoomToUser(myUserId)\n\t * editor.zoomToUser(myUserId, { animation: { duration: 200 } })\n\t * ```\n\t *\n\t * @param userId - The id of the user to animate to.\n\t * @param opts - The camera move options.\n\t * @public\n\t */\n\tzoomToUser(userId: string, opts: TLCameraMoveOptions = { animation: { duration: 500 } }): this {\n\t\tconst presence = this.getCollaborators().find((c) => c.userId === userId)\n\n\t\tif (!presence) return this\n\n\t\tthis.run(() => {\n\t\t\t// If we're following someone, stop following them\n\t\t\tif (this.getInstanceState().followingUserId !== null) {\n\t\t\t\tthis.stopFollowingUser()\n\t\t\t}\n\n\t\t\t// If we're not on the same page, move to the page they're on\n\t\t\tconst isOnSamePage = presence.currentPageId === this.getCurrentPageId()\n\t\t\tif (!isOnSamePage) {\n\t\t\t\tthis.setCurrentPage(presence.currentPageId)\n\t\t\t}\n\n\t\t\t// Only animate the camera if the user is on the same page as us\n\t\t\tif (opts && opts.animation && !isOnSamePage) {\n\t\t\t\topts.animation = undefined\n\t\t\t}\n\n\t\t\tthis.centerOnPoint(presence.cursor, opts)\n\n\t\t\t// Highlight the user's cursor\n\t\t\tconst { highlightedUserIds } = this.getInstanceState()\n\t\t\tthis.updateInstanceState({ highlightedUserIds: [...highlightedUserIds, userId] })\n\n\t\t\t// Unhighlight the user's cursor after a few seconds\n\t\t\tthis.timers.setTimeout(() => {\n\t\t\t\tconst highlightedUserIds = [...this.getInstanceState().highlightedUserIds]\n\t\t\t\tconst index = highlightedUserIds.indexOf(userId)\n\t\t\t\tif (index < 0) return\n\t\t\t\thighlightedUserIds.splice(index, 1)\n\t\t\t\tthis.updateInstanceState({ highlightedUserIds })\n\t\t\t}, this.options.collaboratorIdleTimeoutMs)\n\t\t})\n\n\t\treturn this\n\t}\n\n\t// Viewport\n\n\t/** @internal */\n\tprivate _willSetInitialBounds = true\n\n\t/**\n\t * Update the viewport. The viewport will measure the size and screen position of its container\n\t * element. This should be done whenever the container's position on the screen changes.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.updateViewportScreenBounds(new Box(0, 0, 1280, 1024))\n\t * editor.updateViewportScreenBounds(new Box(0, 0, 1280, 1024), true)\n\t * ```\n\t *\n\t * @param center - Whether to preserve the viewport page center as the viewport changes.\n\t *\n\t * @public\n\t */\n\tupdateViewportScreenBounds(screenBounds: Box | HTMLElement, center = false): this {\n\t\tif (!(screenBounds instanceof Box)) {\n\t\t\tconst rect = screenBounds.getBoundingClientRect()\n\t\t\tscreenBounds = new Box(\n\t\t\t\trect.left || rect.x,\n\t\t\t\trect.top || rect.y,\n\t\t\t\tMath.max(rect.width, 1),\n\t\t\t\tMath.max(rect.height, 1)\n\t\t\t)\n\t\t} else {\n\t\t\tscreenBounds.width = Math.max(screenBounds.width, 1)\n\t\t\tscreenBounds.height = Math.max(screenBounds.height, 1)\n\t\t}\n\n\t\tconst insets = [\n\t\t\t// top\n\t\t\tscreenBounds.minY !== 0,\n\t\t\t// right\n\t\t\t!approximately(document.body.scrollWidth, screenBounds.maxX, 1),\n\t\t\t// bottom\n\t\t\t!approximately(document.body.scrollHeight, screenBounds.maxY, 1),\n\t\t\t// left\n\t\t\tscreenBounds.minX !== 0,\n\t\t]\n\n\t\tconst { _willSetInitialBounds } = this\n\n\t\tthis._willSetInitialBounds = false\n\n\t\tconst { screenBounds: prevScreenBounds, insets: prevInsets } = this.getInstanceState()\n\t\tif (screenBounds.equals(prevScreenBounds) && insets.every((v, i) => v === prevInsets[i])) {\n\t\t\t// nothing to do\n\t\t\treturn this\n\t\t}\n\n\t\tif (_willSetInitialBounds) {\n\t\t\t// If we have just received the initial bounds, don't center the camera.\n\t\t\tthis.updateInstanceState({ screenBounds: screenBounds.toJson(), insets })\n\t\t\tthis.setCamera(this.getCamera())\n\t\t} else {\n\t\t\tif (center && !this.getInstanceState().followingUserId) {\n\t\t\t\t// Get the page center before the change, make the change, and restore it\n\t\t\t\tconst before = this.getViewportPageBounds().center\n\t\t\t\tthis.updateInstanceState({ screenBounds: screenBounds.toJson(), insets })\n\t\t\t\tthis.centerOnPoint(before)\n\t\t\t} else {\n\t\t\t\t// Otherwise,\n\t\t\t\tthis.updateInstanceState({ screenBounds: screenBounds.toJson(), insets })\n\t\t\t\tthis._setCamera(Vec.From({ ...this.getCamera() }))\n\t\t\t}\n\t\t}\n\n\t\tthis._tickCameraState()\n\n\t\treturn this\n\t}\n\n\t/**\n\t * The bounds of the editor's viewport in screen space.\n\t *\n\t * @public\n\t */\n\t@computed getViewportScreenBounds() {\n\t\tconst { x, y, w, h } = this.getInstanceState().screenBounds\n\t\treturn new Box(x, y, w, h)\n\t}\n\n\t/**\n\t * The center of the editor's viewport in screen space.\n\t *\n\t * @public\n\t */\n\t@computed getViewportScreenCenter() {\n\t\tconst viewportScreenBounds = this.getViewportScreenBounds()\n\t\treturn new Vec(\n\t\t\tviewportScreenBounds.midX - viewportScreenBounds.minX,\n\t\t\tviewportScreenBounds.midY - viewportScreenBounds.minY\n\t\t)\n\t}\n\n\t/**\n\t * The current viewport in the current page space.\n\t *\n\t * @public\n\t */\n\t@computed getViewportPageBounds() {\n\t\tconst { w, h } = this.getViewportScreenBounds()\n\t\tconst { x: cx, y: cy, z: cz } = this.getCamera()\n\t\treturn new Box(-cx, -cy, w / cz, h / cz)\n\t}\n\n\t/**\n\t * Convert a point in screen space to a point in the current page space.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.screenToPage({ x: 100, y: 100 })\n\t * ```\n\t *\n\t * @param point - The point in screen space.\n\t *\n\t * @public\n\t */\n\tscreenToPage(point: VecLike) {\n\t\tconst { screenBounds } = this.store.unsafeGetWithoutCapture(TLINSTANCE_ID)!\n\t\tconst { x: cx, y: cy, z: cz = 1 } = this.getCamera()\n\t\treturn new Vec(\n\t\t\t(point.x - screenBounds.x) / cz - cx,\n\t\t\t(point.y - screenBounds.y) / cz - cy,\n\t\t\tpoint.z ?? 0.5\n\t\t)\n\t}\n\n\t/**\n\t * Convert a point in the current page space to a point in current screen space.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.pageToScreen({ x: 100, y: 100 })\n\t * ```\n\t *\n\t * @param point - The point in page space.\n\t *\n\t * @public\n\t */\n\tpageToScreen(point: VecLike) {\n\t\tconst { screenBounds } = this.store.unsafeGetWithoutCapture(TLINSTANCE_ID)!\n\t\tconst { x: cx, y: cy, z: cz = 1 } = this.getCamera()\n\t\treturn new Vec(\n\t\t\t(point.x + cx) * cz + screenBounds.x,\n\t\t\t(point.y + cy) * cz + screenBounds.y,\n\t\t\tpoint.z ?? 0.5\n\t\t)\n\t}\n\n\t/**\n\t * Convert a point in the current page space to a point in current viewport space.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.pageToViewport({ x: 100, y: 100 })\n\t * ```\n\t *\n\t * @param point - The point in page space.\n\t *\n\t * @public\n\t */\n\tpageToViewport(point: VecLike) {\n\t\tconst { x: cx, y: cy, z: cz = 1 } = this.getCamera()\n\t\treturn new Vec((point.x + cx) * cz, (point.y + cy) * cz, point.z ?? 0.5)\n\t}\n\t// Collaborators\n\n\t@computed\n\tprivate _getCollaboratorsQuery() {\n\t\treturn this.store.query.records('instance_presence', () => ({\n\t\t\tuserId: { neq: this.user.getId() },\n\t\t}))\n\t}\n\n\t/**\n\t * Returns a list of presence records for all peer collaborators.\n\t * This will return the latest presence record for each connected user.\n\t *\n\t * @public\n\t */\n\t@computed\n\tgetCollaborators() {\n\t\tconst allPresenceRecords = this._getCollaboratorsQuery().get()\n\t\tif (!allPresenceRecords.length) return EMPTY_ARRAY\n\t\tconst userIds = [...new Set(allPresenceRecords.map((c) => c.userId))].sort()\n\t\treturn userIds.map((id) => {\n\t\t\tconst latestPresence = allPresenceRecords\n\t\t\t\t.filter((c) => c.userId === id)\n\t\t\t\t.sort((a, b) => b.lastActivityTimestamp - a.lastActivityTimestamp)[0]\n\t\t\treturn latestPresence\n\t\t})\n\t}\n\n\t/**\n\t * Returns a list of presence records for all peer collaborators on the current page.\n\t * This will return the latest presence record for each connected user.\n\t *\n\t * @public\n\t */\n\t@computed\n\tgetCollaboratorsOnCurrentPage() {\n\t\tconst currentPageId = this.getCurrentPageId()\n\t\treturn this.getCollaborators().filter((c) => c.currentPageId === currentPageId)\n\t}\n\n\t// Following\n\n\t// When we are 'locked on' to a user, our camera is derived from their camera.\n\tprivate _isLockedOnFollowingUser = atom('isLockedOnFollowingUser', false)\n\n\t/**\n\t * Start viewport-following a user.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.startFollowingUser(myUserId)\n\t * ```\n\t *\n\t * @param userId - The id of the user to follow.\n\t * @param opts - Options for starting to follow a user.\n\t *\n\t * @public\n\t */\n\tstartFollowingUser(userId: string): this {\n\t\t// if we were already following someone, stop following them\n\t\tthis.stopFollowingUser()\n\n\t\tconst leaderPresences = this._getCollaboratorsQuery()\n\t\t\t.get()\n\t\t\t.filter((p) => p.userId === userId)\n\n\t\tif (!leaderPresences.length) {\n\t\t\tconsole.warn('User not found')\n\t\t\treturn this\n\t\t}\n\n\t\tconst thisUserId = this.user.getId()\n\n\t\tif (!thisUserId) {\n\t\t\tconsole.warn('You should set the userId for the current instance before following a user')\n\t\t\t// allow to continue since it's probably fine most of the time.\n\t\t}\n\n\t\t// If the leader is following us, then we can't follow them\n\t\tif (leaderPresences.some((p) => p.followingUserId === thisUserId)) {\n\t\t\treturn this\n\t\t}\n\n\t\tconst latestLeaderPresence = computed('latestLeaderPresence', () => {\n\t\t\treturn this.getCollaborators().find((p) => p.userId === userId)\n\t\t})\n\n\t\ttransact(() => {\n\t\t\tthis.updateInstanceState({ followingUserId: userId }, { history: 'ignore' })\n\n\t\t\t// we listen for page changes separately from the 'moveTowardsUser' tick\n\t\t\tconst dispose = react('update current page', () => {\n\t\t\t\tconst leaderPresence = latestLeaderPresence.get()\n\t\t\t\tif (!leaderPresence) {\n\t\t\t\t\tthis.stopFollowingUser()\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tif (\n\t\t\t\t\tleaderPresence.currentPageId !== this.getCurrentPageId() &&\n\t\t\t\t\tthis.getPage(leaderPresence.currentPageId)\n\t\t\t\t) {\n\t\t\t\t\t// if the page changed, switch page\n\t\t\t\t\tthis.run(\n\t\t\t\t\t\t() => {\n\t\t\t\t\t\t\t// sneaky store.put here, we can't go through setCurrentPage because it calls stopFollowingUser\n\t\t\t\t\t\t\tthis.store.put([\n\t\t\t\t\t\t\t\t{ ...this.getInstanceState(), currentPageId: leaderPresence.currentPageId },\n\t\t\t\t\t\t\t])\n\t\t\t\t\t\t\tthis._isLockedOnFollowingUser.set(true)\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{ history: 'ignore' }\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t})\n\n\t\t\tconst cancel = () => {\n\t\t\t\tdispose()\n\t\t\t\tthis._isLockedOnFollowingUser.set(false)\n\t\t\t\tthis.off('frame', moveTowardsUser)\n\t\t\t\tthis.off('stop-following', cancel)\n\t\t\t}\n\n\t\t\tconst moveTowardsUser = () => {\n\t\t\t\t// Stop following if we can't find the user\n\t\t\t\tconst leaderPresence = latestLeaderPresence.get()\n\t\t\t\tif (!leaderPresence) {\n\t\t\t\t\tthis.stopFollowingUser()\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\tif (this._isLockedOnFollowingUser.get()) return\n\n\t\t\t\tconst animationSpeed = this.user.getAnimationSpeed()\n\n\t\t\t\tif (animationSpeed === 0) {\n\t\t\t\t\tthis._isLockedOnFollowingUser.set(true)\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\tconst targetViewport = this.getViewportPageBoundsForFollowing()\n\t\t\t\tif (!targetViewport) {\n\t\t\t\t\tthis.stopFollowingUser()\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tconst currentViewport = this.getViewportPageBounds()\n\n\t\t\t\tconst diffX =\n\t\t\t\t\tMath.abs(targetViewport.minX - currentViewport.minX) +\n\t\t\t\t\tMath.abs(targetViewport.maxX - currentViewport.maxX)\n\t\t\t\tconst diffY =\n\t\t\t\t\tMath.abs(targetViewport.minY - currentViewport.minY) +\n\t\t\t\t\tMath.abs(targetViewport.maxY - currentViewport.maxY)\n\n\t\t\t\t// Stop chasing if we're close enough!\n\t\t\t\tif (\n\t\t\t\t\tdiffX < this.options.followChaseViewportSnap &&\n\t\t\t\t\tdiffY < this.options.followChaseViewportSnap\n\t\t\t\t) {\n\t\t\t\t\tthis._isLockedOnFollowingUser.set(true)\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\t// Chase the user's viewport!\n\t\t\t\t// Interpolate between the current viewport and the target viewport based on animation speed.\n\t\t\t\t// This will produce an 'ease-out' effect.\n\t\t\t\tconst t = clamp(animationSpeed * 0.5, 0.1, 0.8)\n\n\t\t\t\tconst nextViewport = new Box(\n\t\t\t\t\tlerp(currentViewport.minX, targetViewport.minX, t),\n\t\t\t\t\tlerp(currentViewport.minY, targetViewport.minY, t),\n\t\t\t\t\tlerp(currentViewport.width, targetViewport.width, t),\n\t\t\t\t\tlerp(currentViewport.height, targetViewport.height, t)\n\t\t\t\t)\n\n\t\t\t\tconst nextCamera = new Vec(\n\t\t\t\t\t-nextViewport.x,\n\t\t\t\t\t-nextViewport.y,\n\t\t\t\t\tthis.getViewportScreenBounds().width / nextViewport.width\n\t\t\t\t)\n\n\t\t\t\t// Update the camera!\n\t\t\t\tthis.stopCameraAnimation()\n\t\t\t\tthis._setCamera(nextCamera)\n\t\t\t}\n\n\t\t\tthis.once('stop-following', cancel)\n\t\t\tthis.addListener('frame', moveTowardsUser)\n\n\t\t\t// call once to start synchronously\n\t\t\tmoveTowardsUser()\n\t\t})\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Stop viewport-following a user.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.stopFollowingUser()\n\t * ```\n\t * @public\n\t */\n\tstopFollowingUser(): this {\n\t\tthis.run(\n\t\t\t() => {\n\t\t\t\t// commit the current camera to the store\n\t\t\t\tthis.store.put([this.getCamera()])\n\t\t\t\t// this must happen after the camera is committed\n\t\t\t\tthis._isLockedOnFollowingUser.set(false)\n\t\t\t\tthis.updateInstanceState({ followingUserId: null })\n\t\t\t\tthis.emit('stop-following')\n\t\t\t},\n\t\t\t{ history: 'ignore' }\n\t\t)\n\t\treturn this\n\t}\n\n\t/** @internal */\n\tgetUnorderedRenderingShapes(\n\t\t// The rendering state. We use this method both for rendering, which\n\t\t// is based on other state, and for computing order for SVG export,\n\t\t// which should work even when things are for example off-screen.\n\t\tuseEditorState: boolean\n\t): TLRenderingShape[] {\n\t\t// Here we get the shape as well as any of its children, as well as their\n\t\t// opacities. If the shape is being erased, and none of its ancestors are\n\t\t// being erased, then we reduce the opacity of the shape and all of its\n\t\t// ancestors; but we don't apply this effect more than once among a set\n\t\t// of descendants so that it does not compound.\n\n\t\t// This is designed to keep all the shapes in a single list which\n\t\t// allows the DOM nodes to be reused even when they become children\n\t\t// of other nodes.\n\n\t\tconst renderingShapes: TLRenderingShape[] = []\n\n\t\tlet nextIndex = this.options.maxShapesPerPage * 2\n\t\tlet nextBackgroundIndex = this.options.maxShapesPerPage\n\n\t\tconst erasingShapeIds = this.getErasingShapeIds()\n\n\t\tconst addShapeById = (id: TLShapeId, opacity: number, isAncestorErasing: boolean) => {\n\t\t\tconst shape = this.getShape(id)\n\t\t\tif (!shape) return\n\t\t\tif (this.isShapeHidden(shape)) return\n\n\t\t\topacity *= shape.opacity\n\t\t\tlet isShapeErasing = false\n\t\t\tconst util = this.getShapeUtil(shape)\n\n\t\t\tif (useEditorState) {\n\t\t\t\tisShapeErasing = !isAncestorErasing && erasingShapeIds.includes(id)\n\t\t\t\tif (isShapeErasing) {\n\t\t\t\t\topacity *= 0.32\n\t\t\t\t}\n\t\t\t}\n\n\t\t\trenderingShapes.push({\n\t\t\t\tid,\n\t\t\t\tshape,\n\t\t\t\tutil,\n\t\t\t\tindex: nextIndex,\n\t\t\t\tbackgroundIndex: nextBackgroundIndex,\n\t\t\t\topacity,\n\t\t\t})\n\n\t\t\tnextIndex += 1\n\t\t\tnextBackgroundIndex += 1\n\n\t\t\tconst childIds = this.getSortedChildIdsForParent(id)\n\t\t\tif (!childIds.length) return\n\n\t\t\tlet backgroundIndexToRestore = null\n\t\t\tif (util.providesBackgroundForChildren(shape)) {\n\t\t\t\tbackgroundIndexToRestore = nextBackgroundIndex\n\t\t\t\tnextBackgroundIndex = nextIndex\n\t\t\t\tnextIndex += this.options.maxShapesPerPage\n\t\t\t}\n\n\t\t\tfor (const childId of childIds) {\n\t\t\t\taddShapeById(childId, opacity, isAncestorErasing || isShapeErasing)\n\t\t\t}\n\n\t\t\tif (backgroundIndexToRestore !== null) {\n\t\t\t\tnextBackgroundIndex = backgroundIndexToRestore\n\t\t\t}\n\t\t}\n\n\t\t// If we're using editor state, then we're only interested in on-screen shapes.\n\t\t// If we're not using the editor state, then we're interested in ALL shapes, even those from other pages.\n\t\tconst pages = useEditorState ? [this.getCurrentPage()] : this.getPages()\n\t\tfor (const page of pages) {\n\t\t\tfor (const childId of this.getSortedChildIdsForParent(page.id)) {\n\t\t\t\taddShapeById(childId, 1, false)\n\t\t\t}\n\t\t}\n\n\t\treturn renderingShapes\n\t}\n\n\t// Camera state\n\t// Camera state does two things: first, it allows us to subscribe to whether\n\t// the camera is moving or not; and second, it allows us to update the rendering\n\t// shapes on the canvas. Changing the rendering shapes may cause shapes to\n\t// unmount / remount in the DOM, which is expensive; and computing visibility is\n\t// also expensive in large projects. For this reason, we use a second bounding\n\t// box just for rendering, and we only update after the camera stops moving.\n\tprivate _cameraState = atom('camera state', 'idle' as 'idle' | 'moving')\n\tprivate _cameraStateTimeoutRemaining = 0\n\t_decayCameraStateTimeout(elapsed: number) {\n\t\tthis._cameraStateTimeoutRemaining -= elapsed\n\t\tif (this._cameraStateTimeoutRemaining > 0) return\n\t\tthis.off('tick', this._decayCameraStateTimeout)\n\t\tthis._cameraState.set('idle')\n\t}\n\t_tickCameraState() {\n\t\t// always reset the timeout\n\t\tthis._cameraStateTimeoutRemaining = this.options.cameraMovingTimeoutMs\n\t\t// If the state is idle, then start the tick\n\t\tif (this._cameraState.__unsafe__getWithoutCapture() !== 'idle') return\n\t\tthis._cameraState.set('moving')\n\t\tthis.on('tick', this._decayCameraStateTimeout)\n\t}\n\n\t/**\n\t * Whether the camera is moving or idle.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getCameraState()\n\t * ```\n\t *\n\t * @public\n\t */\n\tgetCameraState() {\n\t\treturn this._cameraState.get()\n\t}\n\n\t/**\n\t * Get the shapes that should be displayed in the current viewport.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getRenderingShapes()\n\t * ```\n\t *\n\t * @public\n\t */\n\t@computed getRenderingShapes() {\n\t\tconst renderingShapes = this.getUnorderedRenderingShapes(true)\n\n\t\t// Its IMPORTANT that the result be sorted by id AND include the index\n\t\t// that the shape should be displayed at. Steve, this is the past you\n\t\t// telling the present you not to change this.\n\n\t\t// We want to sort by id because moving elements about in the DOM will\n\t\t// cause the element to get removed by react as it moves the DOM node. This\n\t\t// causes to re-render which is hella annoying and a perf\n\t\t// drain. By always sorting by 'id' we keep the shapes always in the\n\t\t// same order; but we later use index to set the element's 'z-index'\n\t\t// to change the \"rendered\" position in z-space.\n\t\treturn renderingShapes.sort(sortById)\n\t}\n\n\t/* --------------------- Pages ---------------------- */\n\n\t@computed private _getAllPagesQuery() {\n\t\treturn this.store.query.records('page')\n\t}\n\n\t/**\n\t * Info about the project's current pages.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getPages()\n\t * ```\n\t *\n\t * @public\n\t */\n\t@computed getPages(): TLPage[] {\n\t\treturn this._getAllPagesQuery().get().sort(sortByIndex)\n\t}\n\n\t/**\n\t * The current page.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getCurrentPage()\n\t * ```\n\t *\n\t * @public\n\t */\n\tgetCurrentPage(): TLPage {\n\t\treturn this.getPage(this.getCurrentPageId())!\n\t}\n\n\t/**\n\t * The current page id.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getCurrentPageId()\n\t * ```\n\t *\n\t * @public\n\t */\n\t@computed getCurrentPageId(): TLPageId {\n\t\treturn this.getInstanceState().currentPageId\n\t}\n\n\t/**\n\t * Get a page.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getPage(myPage.id)\n\t * editor.getPage(myPage)\n\t * ```\n\t *\n\t * @param page - The page (or page id) to get.\n\t *\n\t * @public\n\t */\n\tgetPage(page: TLPageId | TLPage): TLPage | undefined {\n\t\treturn this.store.get(typeof page === 'string' ? page : page.id)\n\t}\n\n\t/* @internal */\n\tprivate readonly _currentPageShapeIds: ReturnType\n\n\t/**\n\t * An array of all of the shapes on the current page.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getCurrentPageIds()\n\t * ```\n\t *\n\t * @public\n\t */\n\tgetCurrentPageShapeIds() {\n\t\treturn this._currentPageShapeIds.get()\n\t}\n\n\t/**\n\t * @internal\n\t */\n\t@computed\n\tgetCurrentPageShapeIdsSorted() {\n\t\treturn Array.from(this.getCurrentPageShapeIds()).sort()\n\t}\n\n\t/**\n\t * Get the ids of shapes on a page.\n\t *\n\t * @example\n\t * ```ts\n\t * const idsOnPage1 = editor.getPageShapeIds('page1')\n\t * const idsOnPage2 = editor.getPageShapeIds(myPage2)\n\t * ```\n\t *\n\t * @param page - The page (or page id) to get.\n\t *\n\t * @public\n\t **/\n\tgetPageShapeIds(page: TLPageId | TLPage): Set {\n\t\tconst pageId = typeof page === 'string' ? page : page.id\n\t\tconst result = this.store.query.exec('shape', { parentId: { eq: pageId } })\n\t\treturn this.getShapeAndDescendantIds(result.map((s) => s.id))\n\t}\n\n\t/**\n\t * Set the current page.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.setCurrentPage('page1')\n\t * editor.setCurrentPage(myPage1)\n\t * ```\n\t *\n\t * @param page - The page (or page id) to set as the current page.\n\t *\n\t * @public\n\t */\n\tsetCurrentPage(page: TLPageId | TLPage): this {\n\t\tconst pageId = typeof page === 'string' ? page : page.id\n\t\tif (!this.store.has(pageId)) {\n\t\t\tconsole.error(\"Tried to set the current page id to a page that doesn't exist.\")\n\t\t\treturn this\n\t\t}\n\n\t\tthis.stopFollowingUser()\n\t\t// finish off any in-progress interactions\n\t\tthis.complete()\n\n\t\treturn this.run(\n\t\t\t() => {\n\t\t\t\tthis.store.put([{ ...this.getInstanceState(), currentPageId: pageId }])\n\t\t\t},\n\t\t\t{ history: 'record-preserveRedoStack' }\n\t\t)\n\t}\n\n\t/**\n\t * Update a page.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.updatePage({ id: 'page2', name: 'Page 2' })\n\t * ```\n\t *\n\t * @param partial - The partial of the shape to update.\n\t *\n\t * @public\n\t */\n\tupdatePage(partial: RequiredKeys, 'id'>): this {\n\t\tif (this.getInstanceState().isReadonly) return this\n\n\t\tconst prev = this.getPage(partial.id)\n\t\tif (!prev) return this\n\n\t\treturn this.run(() => this.store.update(partial.id, (page) => ({ ...page, ...partial })))\n\t}\n\n\t/**\n\t * Create a page.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.createPage(myPage)\n\t * editor.createPage({ name: 'Page 2' })\n\t * ```\n\t *\n\t * @param page - The page (or page partial) to create.\n\t *\n\t * @public\n\t */\n\tcreatePage(page: Partial): this {\n\t\tthis.run(() => {\n\t\t\tif (this.getInstanceState().isReadonly) return\n\t\t\tif (this.getPages().length >= this.options.maxPages) return\n\t\t\tconst pages = this.getPages()\n\n\t\t\tconst name = getIncrementedName(\n\t\t\t\tpage.name ?? 'Page 1',\n\t\t\t\tpages.map((p) => p.name)\n\t\t\t)\n\n\t\t\tlet index = page.index\n\n\t\t\tif (!index || pages.some((p) => p.index === index)) {\n\t\t\t\tindex = getIndexAbove(pages[pages.length - 1].index)\n\t\t\t}\n\n\t\t\tconst newPage = PageRecordType.create({\n\t\t\t\tmeta: {},\n\t\t\t\t...page,\n\t\t\t\tname,\n\t\t\t\tindex,\n\t\t\t})\n\n\t\t\tthis.store.put([newPage])\n\t\t})\n\t\treturn this\n\t}\n\n\t/**\n\t * Delete a page.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.deletePage('page1')\n\t * ```\n\t *\n\t * @param id - The id of the page to delete.\n\t *\n\t * @public\n\t */\n\tdeletePage(page: TLPageId | TLPage): this {\n\t\tconst id = typeof page === 'string' ? page : page.id\n\t\tthis.run(() => {\n\t\t\tif (this.getInstanceState().isReadonly) return\n\t\t\tconst pages = this.getPages()\n\t\t\tif (pages.length === 1) return\n\n\t\t\tconst deletedPage = this.getPage(id)\n\t\t\tif (!deletedPage) return\n\n\t\t\tif (id === this.getCurrentPageId()) {\n\t\t\t\tconst index = pages.findIndex((page) => page.id === id)\n\t\t\t\tconst next = pages[index - 1] ?? pages[index + 1]\n\t\t\t\tthis.setCurrentPage(next.id)\n\t\t\t}\n\t\t\tthis.store.remove([deletedPage.id])\n\t\t})\n\t\treturn this\n\t}\n\n\t/**\n\t * Duplicate a page.\n\t *\n\t * @param id - The id of the page to duplicate. Defaults to the current page.\n\t * @param createId - The id of the new page. Defaults to a new id.\n\t *\n\t * @public\n\t */\n\tduplicatePage(page: TLPageId | TLPage, createId: TLPageId = PageRecordType.createId()): this {\n\t\tif (this.getPages().length >= this.options.maxPages) return this\n\t\tconst id = typeof page === 'string' ? page : page.id\n\t\tconst freshPage = this.getPage(id) // get the most recent version of the page anyway\n\t\tif (!freshPage) return this\n\n\t\tconst prevCamera = { ...this.getCamera() }\n\t\tconst content = this.getContentFromCurrentPage(this.getSortedChildIdsForParent(freshPage.id))\n\n\t\tthis.run(() => {\n\t\t\tconst pages = this.getPages()\n\t\t\tconst index = getIndexBetween(freshPage.index, pages[pages.indexOf(freshPage) + 1]?.index)\n\n\t\t\t// create the page (also creates the pagestate and camera for the new page)\n\t\t\tthis.createPage({ name: freshPage.name + ' Copy', id: createId, index })\n\t\t\t// set the new page as the current page\n\t\t\tthis.setCurrentPage(createId)\n\t\t\t// update the new page's camera to the previous page's camera\n\t\t\tthis.setCamera(prevCamera)\n\n\t\t\tif (content) {\n\t\t\t\t// If we had content on the previous page, put it on the new page\n\t\t\t\treturn this.putContentOntoCurrentPage(content)\n\t\t\t}\n\t\t})\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Rename a page.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.renamePage('page1', 'My Page')\n\t * ```\n\t *\n\t * @param id - The id of the page to rename.\n\t * @param name - The new name.\n\t *\n\t * @public\n\t */\n\trenamePage(page: TLPageId | TLPage, name: string) {\n\t\tconst id = typeof page === 'string' ? page : page.id\n\t\tif (this.getInstanceState().isReadonly) return this\n\t\tthis.updatePage({ id, name })\n\t\treturn this\n\t}\n\n\t/* --------------------- Assets --------------------- */\n\n\t/** @internal */\n\t@computed private _getAllAssetsQuery() {\n\t\treturn this.store.query.records('asset')\n\t}\n\n\t/**\n\t * Get all assets in the editor.\n\t *\n\t * @public\n\t */\n\tgetAssets() {\n\t\treturn this._getAllAssetsQuery().get()\n\t}\n\n\t/**\n\t * Create one or more assets.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.createAssets([...myAssets])\n\t * ```\n\t *\n\t * @param assets - The assets to create.\n\t *\n\t * @public\n\t */\n\tcreateAssets(assets: TLAsset[]): this {\n\t\tif (this.getInstanceState().isReadonly) return this\n\t\tif (assets.length <= 0) return this\n\t\tthis.run(() => this.store.put(assets), { history: 'ignore' })\n\t\treturn this\n\t}\n\n\t/**\n\t * Update one or more assets.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.updateAssets([{ id: 'asset1', name: 'New name' }])\n\t * ```\n\t *\n\t * @param assets - The assets to update.\n\t *\n\t * @public\n\t */\n\tupdateAssets(assets: TLAssetPartial[]): this {\n\t\tif (this.getInstanceState().isReadonly) return this\n\t\tif (assets.length <= 0) return this\n\t\tthis.run(\n\t\t\t() => {\n\t\t\t\tthis.store.put(\n\t\t\t\t\tassets.map((partial) => ({\n\t\t\t\t\t\t...this.store.get(partial.id)!,\n\t\t\t\t\t\t...partial,\n\t\t\t\t\t}))\n\t\t\t\t)\n\t\t\t},\n\t\t\t{ history: 'ignore' }\n\t\t)\n\t\treturn this\n\t}\n\n\t/**\n\t * Delete one or more assets.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.deleteAssets(['asset1', 'asset2'])\n\t * ```\n\t *\n\t * @param ids - The assets to delete.\n\t *\n\t * @public\n\t */\n\tdeleteAssets(assets: TLAssetId[] | TLAsset[]): this {\n\t\tif (this.getInstanceState().isReadonly) return this\n\n\t\tconst ids =\n\t\t\ttypeof assets[0] === 'string'\n\t\t\t\t? (assets as TLAssetId[])\n\t\t\t\t: (assets as TLAsset[]).map((a) => a.id)\n\t\tif (ids.length <= 0) return this\n\n\t\tthis.run(() => this.store.remove(ids), { history: 'ignore' })\n\t\treturn this\n\t}\n\n\t/**\n\t * Get an asset by its id.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getAsset('asset1')\n\t * ```\n\t *\n\t * @param asset - The asset (or asset id) to get.\n\t *\n\t * @public\n\t */\n\tgetAsset(asset: TLAssetId | TLAsset): TLAsset | undefined {\n\t\treturn this.store.get(typeof asset === 'string' ? asset : asset.id) as TLAsset | undefined\n\t}\n\n\tasync resolveAssetUrl(\n\t\tassetId: TLAssetId | null,\n\t\tcontext: {\n\t\t\tscreenScale?: number\n\t\t\tshouldResolveToOriginal?: boolean\n\t\t}\n\t): Promise {\n\t\tif (!assetId) return null\n\t\tconst asset = this.getAsset(assetId)\n\t\tif (!asset) return null\n\n\t\tconst { screenScale = 1, shouldResolveToOriginal = false } = context\n\n\t\t// We only look at the zoom level at powers of 2.\n\t\tconst zoomStepFunction = (zoom: number) => Math.pow(2, Math.ceil(Math.log2(zoom)))\n\t\tconst steppedScreenScale = Math.max(0.125, zoomStepFunction(screenScale))\n\t\tconst networkEffectiveType: string | null =\n\t\t\t'connection' in navigator ? (navigator as any).connection.effectiveType : null\n\t\tconst dpr = this.getInstanceState().devicePixelRatio\n\n\t\treturn await this.store.props.assets.resolve(asset, {\n\t\t\tscreenScale: screenScale || 1,\n\t\t\tsteppedScreenScale,\n\t\t\tdpr,\n\t\t\tnetworkEffectiveType,\n\t\t\tshouldResolveToOriginal,\n\t\t})\n\t}\n\t/**\n\t * Upload an asset to the store's asset service, returning a URL that can be used to resolve the\n\t * asset.\n\t */\n\tasync uploadAsset(asset: TLAsset, file: File): Promise {\n\t\treturn await this.store.props.assets.upload(asset, file)\n\t}\n\n\t/* --------------------- Shapes --------------------- */\n\n\t@computed\n\tprivate _getShapeGeometryCache(): ComputedCache {\n\t\treturn this.store.createComputedCache(\n\t\t\t'bounds',\n\t\t\t(shape) => this.getShapeUtil(shape).getGeometry(shape),\n\t\t\t(a, b) => a.props === b.props\n\t\t)\n\t}\n\n\t/**\n\t * Get the geometry of a shape.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getShapeGeometry(myShape)\n\t * editor.getShapeGeometry(myShapeId)\n\t * ```\n\t *\n\t * @param shape - The shape (or shape id) to get the geometry for.\n\t *\n\t * @public\n\t */\n\tgetShapeGeometry(shape: TLShape | TLShapeId): T {\n\t\treturn this._getShapeGeometryCache().get(typeof shape === 'string' ? shape : shape.id)! as T\n\t}\n\n\t/** @internal */\n\t@computed private _getShapeHandlesCache(): ComputedCache {\n\t\treturn this.store.createComputedCache('handles', (shape) => {\n\t\t\treturn this.getShapeUtil(shape).getHandles?.(shape)\n\t\t})\n\t}\n\n\t/**\n\t * Get the handles (if any) for a shape.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getShapeHandles(myShape)\n\t * editor.getShapeHandles(myShapeId)\n\t * ```\n\t *\n\t * @param shape - The shape (or shape id) to get the handles for.\n\t * @public\n\t */\n\tgetShapeHandles(shape: T | T['id']): TLHandle[] | undefined {\n\t\treturn this._getShapeHandlesCache().get(typeof shape === 'string' ? shape : shape.id)\n\t}\n\n\t/**\n\t * Get the local transform for a shape as a matrix model. This transform reflects both its\n\t * translation (x, y) from from either its parent's top left corner, if the shape's parent is\n\t * another shape, or else from the 0,0 of the page, if the shape's parent is the page; and the\n\t * shape's rotation.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getShapeLocalTransform(myShape)\n\t * ```\n\t *\n\t * @param shape - The shape to get the local transform for.\n\t *\n\t * @public\n\t */\n\tgetShapeLocalTransform(shape: TLShape | TLShapeId): Mat {\n\t\tconst id = typeof shape === 'string' ? shape : shape.id\n\t\tconst freshShape = this.getShape(id)\n\t\tif (!freshShape) throw Error('Editor.getTransform: shape not found')\n\t\treturn Mat.Identity().translate(freshShape.x, freshShape.y).rotate(freshShape.rotation)\n\t}\n\n\t/**\n\t * A cache of page transforms.\n\t *\n\t * @internal\n\t */\n\t@computed private _getShapePageTransformCache(): ComputedCache {\n\t\treturn this.store.createComputedCache('pageTransformCache', (shape) => {\n\t\t\tif (isPageId(shape.parentId)) {\n\t\t\t\treturn this.getShapeLocalTransform(shape)\n\t\t\t}\n\n\t\t\t// If the shape's parent doesn't exist yet (e.g. when merging in changes from remote in the wrong order)\n\t\t\t// then we can't compute the transform yet, so just return the identity matrix.\n\t\t\t// In the future we should look at creating a store update mechanism that understands and preserves\n\t\t\t// ordering.\n\t\t\tconst parentTransform =\n\t\t\t\tthis._getShapePageTransformCache().get(shape.parentId) ?? Mat.Identity()\n\t\t\treturn Mat.Compose(parentTransform, this.getShapeLocalTransform(shape)!)\n\t\t})\n\t}\n\n\t/**\n\t * Get the local transform of a shape's parent as a matrix model.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getShapeParentTransform(myShape)\n\t * ```\n\t *\n\t * @param shape - The shape (or shape id) to get the parent transform for.\n\t *\n\t * @public\n\t */\n\tgetShapeParentTransform(shape: TLShape | TLShapeId): Mat {\n\t\tconst id = typeof shape === 'string' ? shape : shape.id\n\t\tconst freshShape = this.getShape(id)\n\t\tif (!freshShape || isPageId(freshShape.parentId)) return Mat.Identity()\n\t\treturn this._getShapePageTransformCache().get(freshShape.parentId) ?? Mat.Identity()\n\t}\n\n\t/**\n\t * Get the transform of a shape in the current page space.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getShapePageTransform(myShape)\n\t * editor.getShapePageTransform(myShapeId)\n\t * ```\n\t *\n\t * @param shape - The shape (or shape id) to get the page transform for.\n\t *\n\t * @public\n\t */\n\tgetShapePageTransform(shape: TLShape | TLShapeId): Mat {\n\t\tconst id = typeof shape === 'string' ? shape : shape.id\n\t\treturn this._getShapePageTransformCache().get(id) ?? Mat.Identity()\n\t}\n\n\t/** @internal */\n\t@computed private _getShapePageBoundsCache(): ComputedCache {\n\t\treturn this.store.createComputedCache('pageBoundsCache', (shape) => {\n\t\t\tconst pageTransform = this._getShapePageTransformCache().get(shape.id)\n\n\t\t\tif (!pageTransform) return new Box()\n\n\t\t\tconst result = Box.FromPoints(\n\t\t\t\tMat.applyToPoints(pageTransform, this.getShapeGeometry(shape).vertices)\n\t\t\t)\n\n\t\t\treturn result\n\t\t})\n\t}\n\n\t/**\n\t * Get the bounds of a shape in the current page space.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getShapePageBounds(myShape)\n\t * editor.getShapePageBounds(myShapeId)\n\t * ```\n\t *\n\t * @param shape - The shape (or shape id) to get the bounds for.\n\t *\n\t * @public\n\t */\n\tgetShapePageBounds(shape: TLShape | TLShapeId): Box | undefined {\n\t\treturn this._getShapePageBoundsCache().get(typeof shape === 'string' ? shape : shape.id)\n\t}\n\n\t/**\n\t * A cache of clip paths used for clipping.\n\t *\n\t * @internal\n\t */\n\t@computed private _getShapeClipPathCache(): ComputedCache {\n\t\treturn this.store.createComputedCache('clipPathCache', (shape) => {\n\t\t\tconst pageMask = this._getShapeMaskCache().get(shape.id)\n\t\t\tif (!pageMask) return undefined\n\t\t\tif (pageMask.length === 0) {\n\t\t\t\treturn `polygon(0px 0px, 0px 0px, 0px 0px)`\n\t\t\t}\n\n\t\t\tconst pageTransform = this._getShapePageTransformCache().get(shape.id)\n\t\t\tif (!pageTransform) return undefined\n\n\t\t\tconst localMask = Mat.applyToPoints(Mat.Inverse(pageTransform), pageMask)\n\n\t\t\treturn `polygon(${localMask.map((p) => `${p.x}px ${p.y}px`).join(',')})`\n\t\t})\n\t}\n\n\t/**\n\t * Get the clip path for a shape.\n\t *\n\t * @example\n\t * ```ts\n\t * const clipPath = editor.getShapeClipPath(shape)\n\t * const clipPath = editor.getShapeClipPath(shape.id)\n\t * ```\n\t *\n\t * @param shape - The shape (or shape id) to get the clip path for.\n\t *\n\t * @returns The clip path or undefined.\n\t *\n\t * @public\n\t */\n\tgetShapeClipPath(shape: TLShape | TLShapeId): string | undefined {\n\t\treturn this._getShapeClipPathCache().get(typeof shape === 'string' ? shape : shape.id)\n\t}\n\n\t/** @internal */\n\t@computed private _getShapeMaskCache(): ComputedCache {\n\t\treturn this.store.createComputedCache('pageMaskCache', (shape) => {\n\t\t\tif (isPageId(shape.parentId)) return undefined\n\n\t\t\tconst frameAncestors = this.getShapeAncestors(shape.id).filter((shape) =>\n\t\t\t\tthis.isShapeOfType(shape, 'frame')\n\t\t\t)\n\n\t\t\tif (frameAncestors.length === 0) return undefined\n\n\t\t\tconst pageMask = frameAncestors\n\t\t\t\t.map((s) =>\n\t\t\t\t\t// Apply the frame transform to the frame outline to get the frame outline in the current page space\n\t\t\t\t\tthis._getShapePageTransformCache()\n\t\t\t\t\t\t.get(s.id)!\n\t\t\t\t\t\t.applyToPoints(this.getShapeGeometry(s).vertices)\n\t\t\t\t)\n\t\t\t\t.reduce((acc, b) => {\n\t\t\t\t\tif (!(b && acc)) return undefined\n\t\t\t\t\tconst intersection = intersectPolygonPolygon(acc, b)\n\t\t\t\t\tif (intersection) {\n\t\t\t\t\t\treturn intersection.map(Vec.Cast)\n\t\t\t\t\t}\n\t\t\t\t\treturn []\n\t\t\t\t})\n\n\t\t\treturn pageMask\n\t\t})\n\t}\n\n\t/**\n\t * Get the mask (in the current page space) for a shape.\n\t *\n\t * @example\n\t * ```ts\n\t * const pageMask = editor.getShapeMask(shape.id)\n\t * ```\n\t *\n\t * @param id - The id of the shape to get the mask for.\n\t *\n\t * @returns The mask for the shape.\n\t *\n\t * @public\n\t */\n\tgetShapeMask(shape: TLShapeId | TLShape): VecLike[] | undefined {\n\t\treturn this._getShapeMaskCache().get(typeof shape === 'string' ? shape : shape.id)\n\t}\n\n\t/**\n\t * Get the bounds of a shape in the current page space, incorporating any masks. For example, if the\n\t * shape were the child of a frame and was half way out of the frame, the bounds would be the half\n\t * of the shape that was in the frame.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getShapeMaskedPageBounds(myShape)\n\t * editor.getShapeMaskedPageBounds(myShapeId)\n\t * ```\n\t *\n\t * @param shape - The shape to get the masked bounds for.\n\t *\n\t * @public\n\t */\n\tgetShapeMaskedPageBounds(shape: TLShapeId | TLShape): Box | undefined {\n\t\tif (typeof shape !== 'string') shape = shape.id\n\t\treturn this._getShapeMaskedPageBoundsCache().get(shape)\n\t}\n\n\t/** @internal */\n\t@computed private _getShapeMaskedPageBoundsCache(): ComputedCache {\n\t\treturn this.store.createComputedCache('shapeMaskedPageBoundsCache', (shape) => {\n\t\t\tconst pageBounds = this._getShapePageBoundsCache().get(shape.id)\n\t\t\tif (!pageBounds) return\n\t\t\tconst pageMask = this._getShapeMaskCache().get(shape.id)\n\t\t\tif (pageMask) {\n\t\t\t\tif (pageMask.length === 0) return undefined\n\t\t\t\tconst { corners } = pageBounds\n\t\t\t\tif (corners.every((p, i) => p && Vec.Equals(p, pageMask[i]))) return pageBounds.clone()\n\t\t\t\tconst intersection = intersectPolygonPolygon(pageMask, corners)\n\t\t\t\tif (!intersection) return\n\t\t\t\treturn Box.FromPoints(intersection)\n\t\t\t}\n\t\t\treturn pageBounds\n\t\t})\n\t}\n\n\t/**\n\t * Get the ancestors of a shape.\n\t *\n\t * @example\n\t * ```ts\n\t * const ancestors = editor.getShapeAncestors(myShape)\n\t * const ancestors = editor.getShapeAncestors(myShapeId)\n\t * ```\n\t *\n\t * @param shape - The shape (or shape id) to get the ancestors for.\n\t *\n\t * @public\n\t */\n\tgetShapeAncestors(shape: TLShapeId | TLShape, acc: TLShape[] = []): TLShape[] {\n\t\tconst id = typeof shape === 'string' ? shape : shape.id\n\t\tconst freshShape = this.getShape(id)\n\t\tif (!freshShape) return acc\n\t\tconst parentId = freshShape.parentId\n\t\tif (isPageId(parentId)) {\n\t\t\tacc.reverse()\n\t\t\treturn acc\n\t\t}\n\n\t\tconst parent = this.store.get(parentId)\n\t\tif (!parent) return acc\n\t\tacc.push(parent)\n\t\treturn this.getShapeAncestors(parent, acc)\n\t}\n\n\t/**\n\t * Find the first ancestor matching the given predicate\n\t *\n\t * @example\n\t * ```ts\n\t * const ancestor = editor.findShapeAncestor(myShape)\n\t * const ancestor = editor.findShapeAncestor(myShape.id)\n\t * const ancestor = editor.findShapeAncestor(myShape.id, (shape) => shape.type === 'frame')\n\t * ```\n\t *\n\t * @param shape - The shape to check the ancestors for.\n\t *\n\t * @public\n\t */\n\tfindShapeAncestor(\n\t\tshape: TLShape | TLShapeId,\n\t\tpredicate: (parent: TLShape) => boolean\n\t): TLShape | undefined {\n\t\tconst id = typeof shape === 'string' ? shape : shape.id\n\t\tconst freshShape = this.getShape(id)\n\t\tif (!freshShape) return\n\n\t\tconst parentId = freshShape.parentId\n\t\tif (isPageId(parentId)) return\n\n\t\tconst parent = this.getShape(parentId)\n\t\tif (!parent) return\n\t\treturn predicate(parent) ? parent : this.findShapeAncestor(parent, predicate)\n\t}\n\n\t/**\n\t * Returns true if the the given shape has the given ancestor.\n\t *\n\t * @param shape - The shape.\n\t * @param ancestorId - The id of the ancestor.\n\t *\n\t * @public\n\t */\n\thasAncestor(shape: TLShape | TLShapeId | undefined, ancestorId: TLShapeId): boolean {\n\t\tconst id = typeof shape === 'string' ? shape : shape?.id\n\t\tconst freshShape = id && this.getShape(id)\n\t\tif (!freshShape) return false\n\t\tif (freshShape.parentId === ancestorId) return true\n\t\treturn this.hasAncestor(this.getShapeParent(freshShape), ancestorId)\n\t}\n\n\t/**\n\t * Get the common ancestor of two or more shapes that matches a predicate.\n\t *\n\t * @param shapes - The shapes (or shape ids) to check.\n\t * @param predicate - The predicate to match.\n\t */\n\tfindCommonAncestor(\n\t\tshapes: TLShape[] | TLShapeId[],\n\t\tpredicate?: (shape: TLShape) => boolean\n\t): TLShapeId | undefined {\n\t\tif (shapes.length === 0) {\n\t\t\treturn\n\t\t}\n\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\t\tconst freshShapes = compact(ids.map((id) => this.getShape(id)))\n\n\t\tif (freshShapes.length === 1) {\n\t\t\tconst parentId = freshShapes[0].parentId\n\t\t\tif (isPageId(parentId)) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\treturn predicate ? this.findShapeAncestor(freshShapes[0], predicate)?.id : parentId\n\t\t}\n\n\t\tconst [nodeA, ...others] = freshShapes\n\t\tlet ancestor = this.getShapeParent(nodeA)\n\t\twhile (ancestor) {\n\t\t\t// TODO: this is not ideal, optimize\n\t\t\tif (predicate && !predicate(ancestor)) {\n\t\t\t\tancestor = this.getShapeParent(ancestor)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif (others.every((shape) => this.hasAncestor(shape, ancestor!.id))) {\n\t\t\t\treturn ancestor!.id\n\t\t\t}\n\t\t\tancestor = this.getShapeParent(ancestor)\n\t\t}\n\t\treturn undefined\n\t}\n\n\t/**\n\t * Check whether a shape or its parent is locked.\n\t *\n\t * @param shape - The shape (or shape id) to check.\n\t *\n\t * @public\n\t */\n\tisShapeOrAncestorLocked(shape?: TLShape): boolean\n\tisShapeOrAncestorLocked(id?: TLShapeId): boolean\n\tisShapeOrAncestorLocked(arg?: TLShape | TLShapeId): boolean {\n\t\tconst shape = typeof arg === 'string' ? this.getShape(arg) : arg\n\t\tif (shape === undefined) return false\n\t\tif (shape.isLocked) return true\n\t\treturn this.isShapeOrAncestorLocked(this.getShapeParent(shape))\n\t}\n\n\t@computed\n\tprivate _notVisibleShapes() {\n\t\treturn notVisibleShapes(this)\n\t}\n\n\t/**\n\t * Get culled shapes.\n\t *\n\t * @public\n\t */\n\t@computed\n\tgetCulledShapes() {\n\t\tconst notVisibleShapes = this._notVisibleShapes().get()\n\t\tconst selectedShapeIds = this.getSelectedShapeIds()\n\t\tconst editingId = this.getEditingShapeId()\n\t\tconst culledShapes = new Set(notVisibleShapes)\n\t\t// we don't cull the shape we are editing\n\t\tif (editingId) {\n\t\t\tculledShapes.delete(editingId)\n\t\t}\n\t\t// we also don't cull selected shapes\n\t\tselectedShapeIds.forEach((id) => {\n\t\t\tculledShapes.delete(id)\n\t\t})\n\t\treturn culledShapes\n\t}\n\n\t/**\n\t * The bounds of the current page (the common bounds of all of the shapes on the page).\n\t *\n\t * @public\n\t */\n\t@computed getCurrentPageBounds(): Box | undefined {\n\t\tlet commonBounds: Box | undefined\n\n\t\tthis.getCurrentPageShapeIdsSorted().forEach((shapeId) => {\n\t\t\tconst bounds = this.getShapeMaskedPageBounds(shapeId)\n\t\t\tif (!bounds) return\n\t\t\tif (!commonBounds) {\n\t\t\t\tcommonBounds = bounds.clone()\n\t\t\t} else {\n\t\t\t\tcommonBounds = commonBounds.expand(bounds)\n\t\t\t}\n\t\t})\n\n\t\treturn commonBounds\n\t}\n\n\t/**\n\t * Get the top-most selected shape at the given point, ignoring groups.\n\t *\n\t * @param point - The point to check.\n\t *\n\t * @returns The top-most selected shape at the given point, or undefined if there is no shape at the point.\n\t */\n\tgetSelectedShapeAtPoint(point: VecLike): TLShape | undefined {\n\t\tconst selectedShapeIds = this.getSelectedShapeIds()\n\t\treturn this.getCurrentPageShapesSorted()\n\t\t\t.filter((shape) => shape.type !== 'group' && selectedShapeIds.includes(shape.id))\n\t\t\t.reverse() // find last\n\t\t\t.find((shape) => this.isPointInShape(shape, point, { hitInside: true, margin: 0 }))\n\t}\n\n\t/**\n\t * Get the shape at the current point.\n\t *\n\t * @param point - The point to check.\n\t * @param opts - Options for the check: `hitInside` to check if the point is inside the shape, `margin` to check if the point is within a margin of the shape, `hitFrameInside` to check if the point is inside the frame, and `filter` to filter the shapes to check.\n\t *\n\t * @returns The shape at the given point, or undefined if there is no shape at the point.\n\t */\n\tgetShapeAtPoint(\n\t\tpoint: VecLike,\n\t\topts = {} as {\n\t\t\trenderingOnly?: boolean\n\t\t\tmargin?: number\n\t\t\thitInside?: boolean\n\t\t\thitLocked?: boolean\n\t\t\t// TODO: we probably need to rename this, we don't quite _always_\n\t\t\t// respect this esp. in the part below that does \"Check labels first\"\n\t\t\thitLabels?: boolean\n\t\t\thitFrameInside?: boolean\n\t\t\tfilter?(shape: TLShape): boolean\n\t\t}\n\t): TLShape | undefined {\n\t\tconst zoomLevel = this.getZoomLevel()\n\t\tconst viewportPageBounds = this.getViewportPageBounds()\n\t\tconst {\n\t\t\tfilter,\n\t\t\tmargin = 0,\n\t\t\thitLocked = false,\n\t\t\thitLabels = false,\n\t\t\thitInside = false,\n\t\t\thitFrameInside = false,\n\t\t} = opts\n\n\t\tlet inHollowSmallestArea = Infinity\n\t\tlet inHollowSmallestAreaHit: TLShape | null = null\n\n\t\tlet inMarginClosestToEdgeDistance = Infinity\n\t\tlet inMarginClosestToEdgeHit: TLShape | null = null\n\n\t\tconst shapesToCheck = (\n\t\t\topts.renderingOnly\n\t\t\t\t? this.getCurrentPageRenderingShapesSorted()\n\t\t\t\t: this.getCurrentPageShapesSorted()\n\t\t).filter((shape) => {\n\t\t\tif (\n\t\t\t\t(shape.isLocked && !hitLocked) ||\n\t\t\t\tthis.isShapeHidden(shape) ||\n\t\t\t\tthis.isShapeOfType(shape, 'group')\n\t\t\t)\n\t\t\t\treturn false\n\t\t\tconst pageMask = this.getShapeMask(shape)\n\t\t\tif (pageMask && !pointInPolygon(point, pageMask)) return false\n\t\t\tif (filter) return filter(shape)\n\t\t\treturn true\n\t\t})\n\n\t\tfor (let i = shapesToCheck.length - 1; i >= 0; i--) {\n\t\t\tconst shape = shapesToCheck[i]\n\t\t\tconst geometry = this.getShapeGeometry(shape)\n\t\t\tconst isGroup = geometry instanceof Group2d\n\n\t\t\tconst pointInShapeSpace = this.getPointInShapeSpace(shape, point)\n\n\t\t\t// Check labels first\n\t\t\tif (\n\t\t\t\tthis.isShapeOfType(shape, 'arrow') ||\n\t\t\t\t(this.isShapeOfType(shape, 'geo') && shape.props.fill === 'none')\n\t\t\t) {\n\t\t\t\tif (shape.props.text.trim()) {\n\t\t\t\t\t// let's check whether the shape has a label and check that\n\t\t\t\t\tfor (const childGeometry of (geometry as Group2d).children) {\n\t\t\t\t\t\tif (childGeometry.isLabel && childGeometry.isPointInBounds(pointInShapeSpace)) {\n\t\t\t\t\t\t\treturn shape\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (this.isShapeOfType(shape, 'frame')) {\n\t\t\t\t// On the rare case that we've hit a frame, test again hitInside to be forced true;\n\t\t\t\t// this prevents clicks from passing through the body of a frame to shapes behind it.\n\n\t\t\t\t// If the hit is within the frame's outer margin, then select the frame\n\t\t\t\tconst distance = geometry.distanceToPoint(pointInShapeSpace, hitInside)\n\t\t\t\tif (Math.abs(distance) <= margin) {\n\t\t\t\t\treturn inMarginClosestToEdgeHit || shape\n\t\t\t\t}\n\n\t\t\t\tif (geometry.hitTestPoint(pointInShapeSpace, 0, true)) {\n\t\t\t\t\t// Once we've hit a frame, we want to end the search. If we have hit a shape\n\t\t\t\t\t// already, then this would either be above the frame or a child of the frame,\n\t\t\t\t\t// so we want to return that. Otherwise, the point is in the empty space of the\n\t\t\t\t\t// frame. If `hitFrameInside` is true (e.g. used drawing an arrow into the\n\t\t\t\t\t// frame) we the frame itself; other wise, (e.g. when hovering or pointing)\n\t\t\t\t\t// we would want to return null.\n\t\t\t\t\treturn (\n\t\t\t\t\t\tinMarginClosestToEdgeHit ||\n\t\t\t\t\t\tinHollowSmallestAreaHit ||\n\t\t\t\t\t\t(hitFrameInside ? shape : undefined)\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tlet distance: number\n\n\t\t\tif (isGroup) {\n\t\t\t\tlet minDistance = Infinity\n\t\t\t\tfor (const childGeometry of geometry.children) {\n\t\t\t\t\tif (childGeometry.isLabel && !hitLabels) continue\n\n\t\t\t\t\t// hit test the all of the child geometries that aren't labels\n\t\t\t\t\tconst tDistance = childGeometry.distanceToPoint(pointInShapeSpace, hitInside)\n\t\t\t\t\tif (tDistance < minDistance) {\n\t\t\t\t\t\tminDistance = tDistance\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tdistance = minDistance\n\t\t\t} else {\n\t\t\t\t// If the margin is zero and the geometry has a very small width or height,\n\t\t\t\t// then check the actual distance. This is to prevent a bug where straight\n\t\t\t\t// lines would never pass the broad phase (point-in-bounds) check.\n\t\t\t\tif (margin === 0 && (geometry.bounds.w < 1 || geometry.bounds.h < 1)) {\n\t\t\t\t\tdistance = geometry.distanceToPoint(pointInShapeSpace, hitInside)\n\t\t\t\t} else {\n\t\t\t\t\t// Broad phase\n\t\t\t\t\tif (geometry.bounds.containsPoint(pointInShapeSpace, margin)) {\n\t\t\t\t\t\t// Narrow phase (actual distance)\n\t\t\t\t\t\tdistance = geometry.distanceToPoint(pointInShapeSpace, hitInside)\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// Failed the broad phase, geddafugaotta'ere!\n\t\t\t\t\t\tdistance = Infinity\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (geometry.isClosed) {\n\t\t\t\t// For closed shapes, the distance will be positive if outside of\n\t\t\t\t// the shape or negative if inside of the shape. If the distance\n\t\t\t\t// is greater than the margin, then it's a miss. Otherwise...\n\n\t\t\t\tif (distance <= margin) {\n\t\t\t\t\tif (geometry.isFilled || (isGroup && geometry.children[0].isFilled)) {\n\t\t\t\t\t\t// If the shape is filled, then it's a hit. Remember, we're\n\t\t\t\t\t\t// starting from the TOP-MOST shape in z-index order, so any\n\t\t\t\t\t\t// other hits would be occluded by the shape.\n\t\t\t\t\t\treturn inMarginClosestToEdgeHit || shape\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// If the shape is bigger than the viewport, then skip it.\n\t\t\t\t\t\tif (this.getShapePageBounds(shape)!.contains(viewportPageBounds)) continue\n\n\t\t\t\t\t\t// For hollow shapes...\n\t\t\t\t\t\tif (Math.abs(distance) < margin) {\n\t\t\t\t\t\t\t// We want to preference shapes where we're inside of the\n\t\t\t\t\t\t\t// shape margin; and we would want to hit the shape with the\n\t\t\t\t\t\t\t// edge closest to the point.\n\t\t\t\t\t\t\tif (Math.abs(distance) < inMarginClosestToEdgeDistance) {\n\t\t\t\t\t\t\t\tinMarginClosestToEdgeDistance = Math.abs(distance)\n\t\t\t\t\t\t\t\tinMarginClosestToEdgeHit = shape\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else if (!inMarginClosestToEdgeHit) {\n\t\t\t\t\t\t\t// If we're not within margin distance to any edge, and if the\n\t\t\t\t\t\t\t// shape is hollow, then we want to hit the shape with the\n\t\t\t\t\t\t\t// smallest area. (There's a bug here with self-intersecting\n\t\t\t\t\t\t\t// shapes, like a closed drawing of an \"8\", but that's a bigger\n\t\t\t\t\t\t\t// problem to solve.)\n\t\t\t\t\t\t\tconst { area } = geometry\n\t\t\t\t\t\t\tif (area < inHollowSmallestArea) {\n\t\t\t\t\t\t\t\tinHollowSmallestArea = area\n\t\t\t\t\t\t\t\tinHollowSmallestAreaHit = shape\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// For open shapes (e.g. lines or draw shapes) always use the margin.\n\t\t\t\t// If the distance is less than the margin, return the shape as the hit.\n\t\t\t\tif (distance < this.options.hitTestMargin / zoomLevel) {\n\t\t\t\t\treturn shape\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// If we haven't hit any filled shapes or frames, then return either\n\t\t// the shape who we hit within the margin (and of those, the one that\n\t\t// had the shortest distance between the point and the shape edge),\n\t\t// or else the hollow shape with the smallest area\u2014or if we didn't hit\n\t\t// any margins or any hollow shapes, then null.\n\t\treturn inMarginClosestToEdgeHit || inHollowSmallestAreaHit || undefined\n\t}\n\n\t/**\n\t * Get the shapes, if any, at a given page point.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getShapesAtPoint({ x: 100, y: 100 })\n\t * editor.getShapesAtPoint({ x: 100, y: 100 }, { hitInside: true, exact: true })\n\t * ```\n\t *\n\t * @param point - The page point to test.\n\t *\n\t * @public\n\t */\n\tgetShapesAtPoint(\n\t\tpoint: VecLike,\n\t\topts = {} as { margin?: number; hitInside?: boolean }\n\t): TLShape[] {\n\t\treturn this.getCurrentPageShapes().filter(\n\t\t\t(shape) => !this.isShapeHidden(shape) && this.isPointInShape(shape, point, opts)\n\t\t)\n\t}\n\n\t/**\n\t * Test whether a point (in the current page space) will will a shape. This method takes into account masks,\n\t * such as when a shape is the child of a frame and is partially clipped by the frame.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.isPointInShape({ x: 100, y: 100 }, myShape)\n\t * ```\n\t *\n\t * @param shape - The shape to test against.\n\t * @param point - The page point to test (in the current page space).\n\t * @param hitInside - Whether to count as a hit if the point is inside of a closed shape.\n\t *\n\t * @public\n\t */\n\tisPointInShape(\n\t\tshape: TLShape | TLShapeId,\n\t\tpoint: VecLike,\n\t\topts = {} as {\n\t\t\tmargin?: number\n\t\t\thitInside?: boolean\n\t\t}\n\t): boolean {\n\t\tconst { hitInside = false, margin = 0 } = opts\n\t\tconst id = typeof shape === 'string' ? shape : shape.id\n\t\t// If the shape is masked, and if the point falls outside of that\n\t\t// mask, then it's definitely a miss\u2014we don't need to test further.\n\t\tconst pageMask = this.getShapeMask(id)\n\t\tif (pageMask && !pointInPolygon(point, pageMask)) return false\n\n\t\treturn this.getShapeGeometry(id).hitTestPoint(\n\t\t\tthis.getPointInShapeSpace(shape, point),\n\t\t\tmargin,\n\t\t\thitInside\n\t\t)\n\t}\n\n\t/**\n\t * Convert a point in the current page space to a point in the local space of a shape. For example, if a\n\t * shape's page point were `{ x: 100, y: 100 }`, a page point at `{ x: 110, y: 110 }` would be at\n\t * `{ x: 10, y: 10 }` in the shape's local space.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getPointInShapeSpace(myShape, { x: 100, y: 100 })\n\t * ```\n\t *\n\t * @param shape - The shape to get the point in the local space of.\n\t * @param point - The page point to get in the local space of the shape.\n\t *\n\t * @public\n\t */\n\tgetPointInShapeSpace(shape: TLShape | TLShapeId, point: VecLike): Vec {\n\t\tconst id = typeof shape === 'string' ? shape : shape.id\n\t\treturn this._getShapePageTransformCache().get(id)!.clone().invert().applyToPoint(point)\n\t}\n\n\t/**\n\t * Convert a delta in the current page space to a point in the local space of a shape's parent.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getPointInParentSpace(myShape.id, { x: 100, y: 100 })\n\t * ```\n\t *\n\t * @param shape - The shape to get the point in the local space of.\n\t * @param point - The page point to get in the local space of the shape.\n\t *\n\t * @public\n\t */\n\tgetPointInParentSpace(shape: TLShapeId | TLShape, point: VecLike): Vec {\n\t\tconst id = typeof shape === 'string' ? shape : shape.id\n\t\tconst freshShape = this.getShape(id)\n\t\tif (!freshShape) return new Vec(0, 0)\n\t\tif (isPageId(freshShape.parentId)) return Vec.From(point)\n\n\t\tconst parentTransform = this.getShapePageTransform(freshShape.parentId)\n\t\tif (!parentTransform) return Vec.From(point)\n\t\treturn parentTransform.clone().invert().applyToPoint(point)\n\t}\n\n\t/**\n\t * An array containing all of the shapes in the current page.\n\t *\n\t * @public\n\t */\n\t@computed getCurrentPageShapes(): TLShape[] {\n\t\treturn Array.from(this.getCurrentPageShapeIds(), (id) => this.store.get(id)! as TLShape)\n\t}\n\n\t/**\n\t * An array containing all of the shapes in the current page, sorted in z-index order (accounting\n\t * for nested shapes): e.g. A, B, BA, BB, C.\n\t *\n\t * @public\n\t */\n\t@computed getCurrentPageShapesSorted(): TLShape[] {\n\t\tconst result: TLShape[] = []\n\t\tconst topLevelShapes = this.getSortedChildIdsForParent(this.getCurrentPageId())\n\n\t\tfor (let i = 0, n = topLevelShapes.length; i < n; i++) {\n\t\t\tpushShapeWithDescendants(this, topLevelShapes[i], result)\n\t\t}\n\n\t\treturn result\n\t}\n\n\t/**\n\t * An array containing all of the rendering shapes in the current page, sorted in z-index order (accounting\n\t * for nested shapes): e.g. A, B, BA, BB, C.\n\t *\n\t * @public\n\t */\n\t@computed getCurrentPageRenderingShapesSorted(): TLShape[] {\n\t\tconst culledShapes = this.getCulledShapes()\n\t\treturn this.getCurrentPageShapesSorted().filter(\n\t\t\t({ id }) => !culledShapes.has(id) && !this.isShapeHidden(id)\n\t\t)\n\t}\n\n\t/**\n\t * Get whether a shape matches the type of a TLShapeUtil.\n\t *\n\t * @example\n\t * ```ts\n\t * const isArrowShape = isShapeOfType(someShape, 'arrow')\n\t * ```\n\t *\n\t * @param util - the TLShapeUtil constructor to test against\n\t * @param shape - the shape to test\n\t *\n\t * @public\n\t */\n\tisShapeOfType(shape: TLUnknownShape, type: T['type']): shape is T\n\tisShapeOfType(\n\t\tshapeId: TLUnknownShape['id'],\n\t\ttype: T['type']\n\t): shapeId is T['id']\n\tisShapeOfType(\n\t\targ: TLUnknownShape | TLUnknownShape['id'],\n\t\ttype: T['type']\n\t) {\n\t\tconst shape = typeof arg === 'string' ? this.getShape(arg) : arg\n\t\tif (!shape) return false\n\t\treturn shape.type === type\n\t}\n\n\t/**\n\t * Get a shape by its id.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getShape('box1')\n\t * ```\n\t *\n\t * @param id - The id of the shape to get.\n\t *\n\t * @public\n\t */\n\tgetShape(shape: TLShape | TLParentId): T | undefined {\n\t\tconst id = typeof shape === 'string' ? shape : shape.id\n\t\tif (!isShapeId(id)) return undefined\n\t\treturn this.store.get(id) as T\n\t}\n\n\t/**\n\t * Get the parent shape for a given shape. Returns undefined if the shape is the direct child of\n\t * the page.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getShapeParent(myShape)\n\t * ```\n\t *\n\t * @public\n\t */\n\tgetShapeParent(shape?: TLShape | TLShapeId): TLShape | undefined {\n\t\tconst id = typeof shape === 'string' ? shape : shape?.id\n\t\tif (!id) return undefined\n\t\tconst freshShape = this.getShape(id)\n\t\tif (freshShape === undefined || !isShapeId(freshShape.parentId)) return undefined\n\t\treturn this.store.get(freshShape.parentId)\n\t}\n\n\t/**\n\t * If siblingShape and targetShape are siblings, this returns targetShape. If targetShape has an\n\t * ancestor who is a sibling of siblingShape, this returns that ancestor. Otherwise, this returns\n\t * undefined.\n\t *\n\t * @internal\n\t */\n\tgetShapeNearestSibling(\n\t\tsiblingShape: TLShape,\n\t\ttargetShape: TLShape | undefined\n\t): TLShape | undefined {\n\t\tif (!targetShape) {\n\t\t\treturn undefined\n\t\t}\n\t\tif (targetShape.parentId === siblingShape.parentId) {\n\t\t\treturn targetShape\n\t\t}\n\n\t\tconst ancestor = this.findShapeAncestor(\n\t\t\ttargetShape,\n\t\t\t(ancestor) => ancestor.parentId === siblingShape.parentId\n\t\t)\n\n\t\treturn ancestor\n\t}\n\n\t/**\n\t * Get whether the given shape is the descendant of the given page.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.isShapeInPage(myShape)\n\t * editor.isShapeInPage(myShape, 'page1')\n\t * ```\n\t *\n\t * @param shape - The shape to check.\n\t * @param pageId - The id of the page to check against. Defaults to the current page.\n\t *\n\t * @public\n\t */\n\tisShapeInPage(shape: TLShape | TLShapeId, pageId = this.getCurrentPageId()): boolean {\n\t\tconst id = typeof shape === 'string' ? shape : shape.id\n\t\tconst shapeToCheck = this.getShape(id)\n\t\tif (!shapeToCheck) return false\n\n\t\tlet shapeIsInPage = false\n\n\t\tif (shapeToCheck.parentId === pageId) {\n\t\t\tshapeIsInPage = true\n\t\t} else {\n\t\t\tlet parent = this.getShape(shapeToCheck.parentId)\n\t\t\tisInPageSearch: while (parent) {\n\t\t\t\tif (parent.parentId === pageId) {\n\t\t\t\t\tshapeIsInPage = true\n\t\t\t\t\tbreak isInPageSearch\n\t\t\t\t}\n\t\t\t\tparent = this.getShape(parent.parentId)\n\t\t\t}\n\t\t}\n\n\t\treturn shapeIsInPage\n\t}\n\n\t/**\n\t * Get the id of the containing page for a given shape.\n\t *\n\t * @param shape - The shape to get the page id for.\n\t *\n\t * @returns The id of the page that contains the shape, or undefined if the shape is undefined.\n\t *\n\t * @public\n\t */\n\tgetAncestorPageId(shape?: TLShape | TLShapeId): TLPageId | undefined {\n\t\tconst id = typeof shape === 'string' ? shape : shape?.id\n\t\tconst _shape = id && this.getShape(id)\n\t\tif (!_shape) return undefined\n\t\tif (isPageId(_shape.parentId)) {\n\t\t\treturn _shape.parentId\n\t\t} else {\n\t\t\treturn this.getAncestorPageId(this.getShape(_shape.parentId))\n\t\t}\n\t}\n\n\t// Parents and children\n\n\t/**\n\t * A cache of parents to children.\n\t *\n\t * @internal\n\t */\n\tprivate readonly _parentIdsToChildIds: ReturnType\n\n\t/**\n\t * Reparent shapes to a new parent. This operation preserves the shape's current page positions /\n\t * rotations.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.reparentShapes([box1, box2], 'frame1')\n\t * editor.reparentShapes([box1.id, box2.id], 'frame1')\n\t * editor.reparentShapes([box1.id, box2.id], 'frame1', 4)\n\t * ```\n\t *\n\t * @param shapes - The shapes (or shape ids) of the shapes to reparent.\n\t * @param parentId - The id of the new parent shape.\n\t * @param insertIndex - The index to insert the children.\n\t *\n\t * @public\n\t */\n\treparentShapes(shapes: TLShapeId[] | TLShape[], parentId: TLParentId, insertIndex?: IndexKey) {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string' ? (shapes as TLShapeId[]) : shapes.map((s) => (s as TLShape).id)\n\t\tif (ids.length === 0) return this\n\n\t\tconst changes: TLShapePartial[] = []\n\n\t\tconst parentTransform = isPageId(parentId)\n\t\t\t? Mat.Identity()\n\t\t\t: this.getShapePageTransform(parentId)!\n\n\t\tconst parentPageRotation = parentTransform.rotation()\n\n\t\tlet indices: IndexKey[] = []\n\n\t\tconst sibs = compact(this.getSortedChildIdsForParent(parentId).map((id) => this.getShape(id)))\n\n\t\tif (insertIndex) {\n\t\t\tconst sibWithInsertIndex = sibs.find((s) => s.index === insertIndex)\n\t\t\tif (sibWithInsertIndex) {\n\t\t\t\t// If there's a sibling with the same index as the insert index...\n\t\t\t\tconst sibAbove = sibs[sibs.indexOf(sibWithInsertIndex) + 1]\n\t\t\t\tif (sibAbove) {\n\t\t\t\t\t// If the sibling has a sibling above it, insert the shapes\n\t\t\t\t\t// between the sibling and its sibling above it.\n\t\t\t\t\tindices = getIndicesBetween(insertIndex, sibAbove.index, ids.length)\n\t\t\t\t} else {\n\t\t\t\t\t// Or if the sibling is the top sibling, insert the shapes\n\t\t\t\t\t// above the sibling\n\t\t\t\t\tindices = getIndicesAbove(insertIndex, ids.length)\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// If there's no collision, then we can start at the insert index\n\t\t\t\tconst sibAbove = sibs.sort(sortByIndex).find((s) => s.index > insertIndex)\n\n\t\t\t\tif (sibAbove) {\n\t\t\t\t\t// If the siblings include a sibling with a higher index, insert the shapes\n\t\t\t\t\t// between the insert index and the sibling with the higher index.\n\t\t\t\t\tindices = getIndicesBetween(insertIndex, sibAbove.index, ids.length)\n\t\t\t\t} else {\n\t\t\t\t\t// Otherwise, we're at the top of the order, so insert the shapes above\n\t\t\t\t\t// the insert index.\n\t\t\t\t\tindices = getIndicesAbove(insertIndex, ids.length)\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\t// If insert index is not specified, start the index at the top.\n\t\t\tconst sib = sibs.length && sibs[sibs.length - 1]\n\t\t\tindices = sib ? getIndicesAbove(sib.index, ids.length) : getIndices(ids.length)\n\t\t}\n\n\t\tconst invertedParentTransform = parentTransform.clone().invert()\n\n\t\tconst shapesToReparent = compact(ids.map((id) => this.getShape(id)))\n\n\t\t// Ignore locked shapes so that we can reparent locked shapes, for example\n\t\t// when a locked shape's parent is deleted.\n\t\tthis.run(\n\t\t\t() => {\n\t\t\t\tfor (let i = 0; i < shapesToReparent.length; i++) {\n\t\t\t\t\tconst shape = shapesToReparent[i]\n\n\t\t\t\t\tconst pageTransform = this.getShapePageTransform(shape)!\n\t\t\t\t\tif (!pageTransform) continue\n\n\t\t\t\t\tconst pagePoint = pageTransform.point()\n\t\t\t\t\tif (!pagePoint) continue\n\n\t\t\t\t\tconst newPoint = invertedParentTransform.applyToPoint(pagePoint)\n\t\t\t\t\tconst newRotation = pageTransform.rotation() - parentPageRotation\n\n\t\t\t\t\tchanges.push({\n\t\t\t\t\t\tid: shape.id,\n\t\t\t\t\t\ttype: shape.type,\n\t\t\t\t\t\tparentId: parentId,\n\t\t\t\t\t\tx: newPoint.x,\n\t\t\t\t\t\ty: newPoint.y,\n\t\t\t\t\t\trotation: newRotation,\n\t\t\t\t\t\tindex: indices[i],\n\t\t\t\t\t})\n\t\t\t\t}\n\n\t\t\t\tthis.updateShapes(changes)\n\t\t\t},\n\t\t\t{ ignoreShapeLock: true }\n\t\t)\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Get the index above the highest child of a given parent.\n\t *\n\t * @param parentId - The id of the parent.\n\t *\n\t * @returns The index.\n\t *\n\t * @public\n\t */\n\tgetHighestIndexForParent(parent: TLParentId | TLPage | TLShape): IndexKey {\n\t\tconst parentId = typeof parent === 'string' ? parent : parent.id\n\t\tconst children = this._parentIdsToChildIds.get()[parentId]\n\n\t\tif (!children || children.length === 0) {\n\t\t\treturn 'a1' as IndexKey\n\t\t}\n\t\tconst shape = this.getShape(children[children.length - 1])!\n\t\treturn getIndexAbove(shape.index)\n\t}\n\n\t/**\n\t * Get an array of all the children of a shape.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getSortedChildIdsForParent('frame1')\n\t * ```\n\t *\n\t * @param parentId - The id of the parent shape.\n\t *\n\t * @public\n\t */\n\tgetSortedChildIdsForParent(parent: TLParentId | TLPage | TLShape): TLShapeId[] {\n\t\tconst parentId = typeof parent === 'string' ? parent : parent.id\n\t\tconst ids = this._parentIdsToChildIds.get()[parentId]\n\t\tif (!ids) return EMPTY_ARRAY\n\t\treturn ids\n\t}\n\n\t/**\n\t * Run a visitor function for all descendants of a shape.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.visitDescendants('frame1', myCallback)\n\t * ```\n\t *\n\t * @param parentId - The id of the parent shape.\n\t * @param visitor - The visitor function.\n\t *\n\t * @public\n\t */\n\tvisitDescendants(\n\t\tparent: TLParentId | TLPage | TLShape,\n\t\tvisitor: (id: TLShapeId) => void | false\n\t): this {\n\t\tconst parentId = typeof parent === 'string' ? parent : parent.id\n\t\tconst children = this.getSortedChildIdsForParent(parentId)\n\t\tfor (const id of children) {\n\t\t\tif (visitor(id) === false) continue\n\t\t\tthis.visitDescendants(id, visitor)\n\t\t}\n\t\treturn this\n\t}\n\n\t/**\n\t * Get the shape ids of all descendants of the given shapes (including the shapes themselves). IDs are returned in z-index order.\n\t *\n\t * @param ids - The ids of the shapes to get descendants of.\n\t *\n\t * @returns The descendant ids.\n\t *\n\t * @public\n\t */\n\tgetShapeAndDescendantIds(ids: TLShapeId[]): Set {\n\t\tconst shapeIds = new Set()\n\t\tfor (const shape of ids.map((id) => this.getShape(id)!).sort(sortByIndex)) {\n\t\t\tshapeIds.add(shape.id)\n\t\t\tthis.visitDescendants(shape, (descendantId) => {\n\t\t\t\tshapeIds.add(descendantId)\n\t\t\t})\n\t\t}\n\t\treturn shapeIds\n\t}\n\n\t/**\n\t * Get the shape that some shapes should be dropped on at a given point.\n\t *\n\t * @param point - The point to find the parent for.\n\t * @param droppingShapes - The shapes that are being dropped.\n\t *\n\t * @returns The shape to drop on.\n\t *\n\t * @public\n\t */\n\tgetDroppingOverShape(point: VecLike, droppingShapes: TLShape[] = []) {\n\t\t// starting from the top...\n\t\tconst currentPageShapesSorted = this.getCurrentPageShapesSorted()\n\t\tfor (let i = currentPageShapesSorted.length - 1; i >= 0; i--) {\n\t\t\tconst shape = currentPageShapesSorted[i]\n\n\t\t\tif (\n\t\t\t\t// ignore hidden shapes\n\t\t\t\tthis.isShapeHidden(shape) ||\n\t\t\t\t// don't allow dropping on selected shapes\n\t\t\t\tthis.getSelectedShapeIds().includes(shape.id) ||\n\t\t\t\t// only allow shapes that can receive children\n\t\t\t\t!this.getShapeUtil(shape).canDropShapes(shape, droppingShapes) ||\n\t\t\t\t// don't allow dropping a shape on itself or one of it's children\n\t\t\t\tdroppingShapes.find((s) => s.id === shape.id || this.hasAncestor(shape, s.id))\n\t\t\t) {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\t// Only allow dropping into the masked page bounds of the shape, e.g. when a frame is\n\t\t\t// partially clipped by its own parent frame\n\t\t\tconst maskedPageBounds = this.getShapeMaskedPageBounds(shape.id)\n\n\t\t\tif (\n\t\t\t\tmaskedPageBounds &&\n\t\t\t\tmaskedPageBounds.containsPoint(point) &&\n\t\t\t\tthis.getShapeGeometry(shape).hitTestPoint(this.getPointInShapeSpace(shape, point), 0, true)\n\t\t\t) {\n\t\t\t\treturn shape\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Get the shape that should be selected when you click on a given shape, assuming there is\n\t * nothing already selected. It will not return anything higher than or including the current\n\t * focus layer.\n\t *\n\t * @param shape - The shape to get the outermost selectable shape for.\n\t * @param filter - A function to filter the selectable shapes.\n\t *\n\t * @returns The outermost selectable shape.\n\t *\n\t * @public\n\t */\n\tgetOutermostSelectableShape(\n\t\tshape: TLShape | TLShapeId,\n\t\tfilter?: (shape: TLShape) => boolean\n\t): TLShape {\n\t\tconst id = typeof shape === 'string' ? shape : shape.id\n\t\tconst freshShape = this.getShape(id)!\n\t\tlet match = freshShape\n\t\tlet node = freshShape as TLShape | undefined\n\n\t\tconst focusedGroup = this.getFocusedGroup()\n\n\t\twhile (node) {\n\t\t\tif (\n\t\t\t\tthis.isShapeOfType(node, 'group') &&\n\t\t\t\tfocusedGroup?.id !== node.id &&\n\t\t\t\t!this.hasAncestor(focusedGroup, node.id) &&\n\t\t\t\t(filter?.(node) ?? true)\n\t\t\t) {\n\t\t\t\tmatch = node\n\t\t\t} else if (focusedGroup?.id === node.id) {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tnode = this.getShapeParent(node)\n\t\t}\n\n\t\treturn match\n\t}\n\n\t/* -------------------- Bindings -------------------- */\n\n\t@computed\n\tprivate _getBindingsIndexCache() {\n\t\tconst index = bindingsIndex(this)\n\t\treturn this.store.createComputedCache('bindingsIndex', (shape) => {\n\t\t\treturn index.get().get(shape.id)\n\t\t})\n\t}\n\n\t/**\n\t * Get a binding from the store by its ID if it exists.\n\t */\n\tgetBinding(id: TLBindingId): TLBinding | undefined {\n\t\treturn this.store.get(id) as TLBinding | undefined\n\t}\n\n\t/**\n\t * Get all bindings of a certain type _from_ a particular shape. These are the bindings whose\n\t * `fromId` matched the shape's ID.\n\t */\n\tgetBindingsFromShape(\n\t\tshape: TLShape | TLShapeId,\n\t\ttype: Binding['type']\n\t): Binding[] {\n\t\tconst id = typeof shape === 'string' ? shape : shape.id\n\t\treturn this.getBindingsInvolvingShape(id).filter(\n\t\t\t(b) => b.fromId === id && b.type === type\n\t\t) as Binding[]\n\t}\n\n\t/**\n\t * Get all bindings of a certain type _to_ a particular shape. These are the bindings whose\n\t * `toId` matches the shape's ID.\n\t */\n\tgetBindingsToShape(\n\t\tshape: TLShape | TLShapeId,\n\t\ttype: Binding['type']\n\t): Binding[] {\n\t\tconst id = typeof shape === 'string' ? shape : shape.id\n\t\treturn this.getBindingsInvolvingShape(id).filter(\n\t\t\t(b) => b.toId === id && b.type === type\n\t\t) as Binding[]\n\t}\n\n\t/**\n\t * Get all bindings involving a particular shape. This includes bindings where the shape is the\n\t * `fromId` or `toId`. If a type is provided, only bindings of that type are returned.\n\t */\n\tgetBindingsInvolvingShape(\n\t\tshape: TLShape | TLShapeId,\n\t\ttype?: Binding['type']\n\t): Binding[] {\n\t\tconst id = typeof shape === 'string' ? shape : shape.id\n\t\tconst result = this._getBindingsIndexCache().get(id) ?? EMPTY_ARRAY\n\t\tif (!type) return result as Binding[]\n\t\treturn result.filter((b) => b.type === type) as Binding[]\n\t}\n\n\t/**\n\t * Create bindings from a list of partial bindings. You can omit the ID and most props of a\n\t * binding, but the `type`, `toId`, and `fromId` must all be provided.\n\t */\n\tcreateBindings(partials: TLBindingCreate[]) {\n\t\tconst bindings: TLBinding[] = []\n\t\tfor (const partial of partials) {\n\t\t\tconst fromShape = this.getShape(partial.fromId)\n\t\t\tconst toShape = this.getShape(partial.toId)\n\t\t\tif (!fromShape || !toShape) continue\n\t\t\tif (!this.canBindShapes({ fromShape, toShape, binding: partial })) continue\n\n\t\t\tconst util = this.getBindingUtil(partial.type)\n\t\t\tconst defaultProps = util.getDefaultProps()\n\t\t\tconst binding = this.store.schema.types.binding.create({\n\t\t\t\t...partial,\n\t\t\t\tid: partial.id ?? createBindingId(),\n\t\t\t\tprops: {\n\t\t\t\t\t...defaultProps,\n\t\t\t\t\t...partial.props,\n\t\t\t\t},\n\t\t\t}) as TLBinding\n\n\t\t\tbindings.push(binding)\n\t\t}\n\n\t\tthis.store.put(bindings)\n\t\treturn this\n\t}\n\n\t/**\n\t * Create a single binding from a partial. You can omit the ID and most props of a binding, but\n\t * the `type`, `toId`, and `fromId` must all be provided.\n\t */\n\tcreateBinding(partial: TLBindingCreate) {\n\t\treturn this.createBindings([partial])\n\t}\n\n\t/**\n\t * Update bindings from a list of partial bindings. Each partial must include an ID, which will\n\t * be used to match the binding to it's existing record. If there is no existing record, that\n\t * binding is skipped. The changes from the partial are merged into the existing record.\n\t */\n\tupdateBindings(partials: (TLBindingUpdate | null | undefined)[]) {\n\t\tconst updated: TLBinding[] = []\n\n\t\tfor (const partial of partials) {\n\t\t\tif (!partial) continue\n\n\t\t\tconst current = this.getBinding(partial.id)\n\t\t\tif (!current) continue\n\n\t\t\tconst updatedBinding = applyPartialToRecordWithProps(current, partial)\n\t\t\tif (updatedBinding === current) continue\n\n\t\t\tconst fromShape = this.getShape(updatedBinding.fromId)\n\t\t\tconst toShape = this.getShape(updatedBinding.toId)\n\t\t\tif (!fromShape || !toShape) continue\n\t\t\tif (!this.canBindShapes({ fromShape, toShape, binding: updatedBinding })) continue\n\n\t\t\tupdated.push(updatedBinding)\n\t\t}\n\n\t\tthis.store.put(updated)\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Update a binding from a partial binding. Each partial must include an ID, which will be used\n\t * to match the binding to it's existing record. If there is no existing record, that binding is\n\t * skipped. The changes from the partial are merged into the existing record.\n\t */\n\tupdateBinding(partial: TLBindingUpdate) {\n\t\treturn this.updateBindings([partial])\n\t}\n\n\t/**\n\t * Delete several bindings by their IDs. If a binding ID doesn't exist, it's ignored.\n\t */\n\tdeleteBindings(bindings: (TLBinding | TLBindingId)[], { isolateShapes = false } = {}) {\n\t\tconst ids = bindings.map((binding) => (typeof binding === 'string' ? binding : binding.id))\n\t\tif (isolateShapes) {\n\t\t\tthis.store.atomic(() => {\n\t\t\t\tfor (const id of ids) {\n\t\t\t\t\tconst binding = this.getBinding(id)\n\t\t\t\t\tif (!binding) continue\n\t\t\t\t\tconst util = this.getBindingUtil(binding)\n\t\t\t\t\tutil.onBeforeIsolateFromShape?.({ binding, removedShape: this.getShape(binding.toId)! })\n\t\t\t\t\tutil.onBeforeIsolateToShape?.({ binding, removedShape: this.getShape(binding.fromId)! })\n\t\t\t\t\tthis.store.remove([id])\n\t\t\t\t}\n\t\t\t})\n\t\t} else {\n\t\t\tthis.store.remove(ids)\n\t\t}\n\t\treturn this\n\t}\n\t/**\n\t * Delete a binding by its ID. If the binding doesn't exist, it's ignored.\n\t */\n\tdeleteBinding(binding: TLBinding | TLBindingId, opts?: Parameters[1]) {\n\t\treturn this.deleteBindings([binding], opts)\n\t}\n\tcanBindShapes({\n\t\tfromShape,\n\t\ttoShape,\n\t\tbinding,\n\t}: {\n\t\tfromShape: TLShape | { type: TLShape['type'] } | TLShape['type']\n\t\ttoShape: TLShape | { type: TLShape['type'] } | TLShape['type']\n\t\tbinding: TLBinding | { type: TLBinding['type'] } | TLBinding['type']\n\t}): boolean {\n\t\tconst fromShapeType = typeof fromShape === 'string' ? fromShape : fromShape.type\n\t\tconst toShapeType = typeof toShape === 'string' ? toShape : toShape.type\n\t\tconst bindingType = typeof binding === 'string' ? binding : binding.type\n\n\t\tconst canBindOpts = { fromShapeType, toShapeType, bindingType }\n\n\t\tif (fromShapeType === toShapeType) {\n\t\t\treturn this.getShapeUtil(fromShapeType).canBind(canBindOpts)\n\t\t}\n\n\t\treturn (\n\t\t\tthis.getShapeUtil(fromShapeType).canBind(canBindOpts) &&\n\t\t\tthis.getShapeUtil(toShapeType).canBind(canBindOpts)\n\t\t)\n\t}\n\n\t/* -------------------- Commands -------------------- */\n\n\t/**\n\t * Rotate shapes by a delta in radians.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.rotateShapesBy(editor.getSelectedShapeIds(), Math.PI)\n\t * editor.rotateShapesBy(editor.getSelectedShapeIds(), Math.PI / 2)\n\t * ```\n\t *\n\t * @param shapes - The shapes (or shape ids) of the shapes to move.\n\t * @param delta - The delta in radians to apply to the selection rotation.\n\t */\n\trotateShapesBy(\n\t\tshapes: TLShapeId[] | TLShape[],\n\t\tdelta: number,\n\t\topts?: { center?: VecLike }\n\t): this {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\n\t\tif (ids.length <= 0) return this\n\n\t\tconst snapshot = getRotationSnapshot({ editor: this, ids })\n\t\tif (!snapshot) return this\n\t\tapplyRotationToSnapshotShapes({\n\t\t\tdelta,\n\t\t\tsnapshot,\n\t\t\teditor: this,\n\t\t\tstage: 'one-off',\n\t\t\tcenterOverride: opts?.center,\n\t\t})\n\n\t\treturn this\n\t}\n\n\tprivate getChangesToTranslateShape(initialShape: TLShape, newShapeCoords: VecLike): TLShape {\n\t\tlet workingShape = initialShape\n\t\tconst util = this.getShapeUtil(initialShape)\n\n\t\tworkingShape = applyPartialToRecordWithProps(\n\t\t\tworkingShape,\n\t\t\tutil.onTranslateStart?.(workingShape) ?? undefined\n\t\t)\n\n\t\tworkingShape = applyPartialToRecordWithProps(workingShape, {\n\t\t\tid: initialShape.id,\n\t\t\ttype: initialShape.type,\n\t\t\tx: newShapeCoords.x,\n\t\t\ty: newShapeCoords.y,\n\t\t})\n\n\t\tworkingShape = applyPartialToRecordWithProps(\n\t\t\tworkingShape,\n\t\t\tutil.onTranslate?.(initialShape, workingShape) ?? undefined\n\t\t)\n\n\t\tworkingShape = applyPartialToRecordWithProps(\n\t\t\tworkingShape,\n\t\t\tutil.onTranslateEnd?.(initialShape, workingShape) ?? undefined\n\t\t)\n\n\t\treturn workingShape\n\t}\n\n\t/**\n\t * Move shapes by a delta.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.nudgeShapes(['box1', 'box2'], { x: 8, y: 8 })\n\t * ```\n\t *\n\t * @param shapes - The shapes (or shape ids) to move.\n\t * @param direction - The direction in which to move the shapes.\n\t * @param historyOptions - The history options for the change.\n\t */\n\tnudgeShapes(shapes: TLShapeId[] | TLShape[], offset: VecLike): this {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\n\t\tif (ids.length <= 0) return this\n\t\tconst changes: TLShapePartial[] = []\n\n\t\tfor (const id of ids) {\n\t\t\tconst shape = this.getShape(id)!\n\t\t\tconst localDelta = Vec.From(offset)\n\t\t\tconst parentTransform = this.getShapeParentTransform(shape)\n\t\t\tif (parentTransform) localDelta.rot(-parentTransform.rotation())\n\n\t\t\tchanges.push(this.getChangesToTranslateShape(shape, localDelta.add(shape)))\n\t\t}\n\n\t\tthis.updateShapes(changes)\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Duplicate shapes.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.duplicateShapes(['box1', 'box2'], { x: 8, y: 8 })\n\t * editor.duplicateShapes(editor.getSelectedShapes(), { x: 8, y: 8 })\n\t * ```\n\t *\n\t * @param shapes - The shapes (or shape ids) to duplicate.\n\t * @param offset - The offset (in pixels) to apply to the duplicated shapes.\n\t *\n\t * @public\n\t */\n\tduplicateShapes(shapes: TLShapeId[] | TLShape[], offset?: VecLike): this {\n\t\tthis.run(() => {\n\t\t\tconst ids =\n\t\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\n\t\t\tif (ids.length <= 0) return this\n\n\t\t\tconst initialIds = new Set(ids)\n\t\t\tconst shapeIdSet = this.getShapeAndDescendantIds(ids)\n\n\t\t\tconst orderedShapeIds = [...shapeIdSet].reverse()\n\t\t\tconst shapeIds = new Map()\n\t\t\tfor (const shapeId of shapeIdSet) {\n\t\t\t\tshapeIds.set(shapeId, createShapeId())\n\t\t\t}\n\n\t\t\tconst { shapesToCreateWithOriginals, bindingsToCreate } = withIsolatedShapes(\n\t\t\t\tthis,\n\t\t\t\tshapeIdSet,\n\t\t\t\t(bindingIdsToMaintain) => {\n\t\t\t\t\tconst bindingsToCreate: TLBinding[] = []\n\t\t\t\t\tfor (const originalId of bindingIdsToMaintain) {\n\t\t\t\t\t\tconst originalBinding = this.getBinding(originalId)\n\t\t\t\t\t\tif (!originalBinding) continue\n\n\t\t\t\t\t\tconst duplicatedId = createBindingId()\n\t\t\t\t\t\tbindingsToCreate.push({\n\t\t\t\t\t\t\t...originalBinding,\n\t\t\t\t\t\t\tid: duplicatedId,\n\t\t\t\t\t\t\tfromId: assertExists(shapeIds.get(originalBinding.fromId)),\n\t\t\t\t\t\t\ttoId: assertExists(shapeIds.get(originalBinding.toId)),\n\t\t\t\t\t\t})\n\t\t\t\t\t}\n\n\t\t\t\t\tconst shapesToCreateWithOriginals: { shape: TLShape; originalShape: TLShape }[] = []\n\t\t\t\t\tfor (const originalId of orderedShapeIds) {\n\t\t\t\t\t\tconst duplicatedId = assertExists(shapeIds.get(originalId))\n\t\t\t\t\t\tconst originalShape = this.getShape(originalId)\n\t\t\t\t\t\tif (!originalShape) continue\n\n\t\t\t\t\t\tlet ox = 0\n\t\t\t\t\t\tlet oy = 0\n\n\t\t\t\t\t\tif (offset && initialIds.has(originalId)) {\n\t\t\t\t\t\t\tconst parentTransform = this.getShapeParentTransform(originalShape)\n\t\t\t\t\t\t\tconst vec = new Vec(offset.x, offset.y).rot(-parentTransform!.rotation())\n\t\t\t\t\t\t\tox = vec.x\n\t\t\t\t\t\t\toy = vec.y\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tshapesToCreateWithOriginals.push({\n\t\t\t\t\t\t\tshape: {\n\t\t\t\t\t\t\t\t...originalShape,\n\t\t\t\t\t\t\t\tid: duplicatedId,\n\t\t\t\t\t\t\t\tx: originalShape.x + ox,\n\t\t\t\t\t\t\t\ty: originalShape.y + oy,\n\t\t\t\t\t\t\t\t// Use a dummy index for now, it will get updated outside of the `withIsolatedShapes`\n\t\t\t\t\t\t\t\tindex: 'a1' as IndexKey,\n\t\t\t\t\t\t\t\tparentId:\n\t\t\t\t\t\t\t\t\tshapeIds.get(originalShape.parentId as TLShapeId) ?? originalShape.parentId,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\toriginalShape,\n\t\t\t\t\t\t})\n\t\t\t\t\t}\n\n\t\t\t\t\treturn { shapesToCreateWithOriginals, bindingsToCreate }\n\t\t\t\t}\n\t\t\t)\n\n\t\t\t// We will update the indexes after the `withIsolatedShapes`, since we cannot rely on the indexes\n\t\t\t// to be correct inside of it.\n\t\t\tshapesToCreateWithOriginals.forEach(({ shape, originalShape }) => {\n\t\t\t\tconst parentId = originalShape.parentId\n\t\t\t\tconst siblings = this.getSortedChildIdsForParent(parentId)\n\t\t\t\tconst currentIndex = siblings.indexOf(originalShape.id)\n\t\t\t\tconst siblingAboveId = siblings[currentIndex + 1]\n\t\t\t\tconst siblingAbove = siblingAboveId ? this.getShape(siblingAboveId) : undefined\n\n\t\t\t\tconst index = getIndexBetween(originalShape.index, siblingAbove?.index)\n\n\t\t\t\tshape.index = index\n\t\t\t})\n\t\t\tconst shapesToCreate = shapesToCreateWithOriginals.map(({ shape }) => shape)\n\n\t\t\tconst maxShapesReached =\n\t\t\t\tshapesToCreate.length + this.getCurrentPageShapeIds().size > this.options.maxShapesPerPage\n\n\t\t\tif (maxShapesReached) {\n\t\t\t\talertMaxShapes(this)\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tthis.createShapes(shapesToCreate)\n\t\t\tthis.createBindings(bindingsToCreate)\n\t\t\tthis.setSelectedShapes(compact(ids.map((id) => shapeIds.get(id))))\n\n\t\t\tif (offset !== undefined) {\n\t\t\t\t// If we've offset the duplicated shapes, check to see whether their new bounds is entirely\n\t\t\t\t// contained in the current viewport. If not, then animate the camera to be centered on the\n\t\t\t\t// new shapes.\n\t\t\t\tconst selectionPageBounds = this.getSelectionPageBounds()\n\t\t\t\tconst viewportPageBounds = this.getViewportPageBounds()\n\t\t\t\tif (selectionPageBounds && !viewportPageBounds.contains(selectionPageBounds)) {\n\t\t\t\t\tthis.centerOnPoint(selectionPageBounds.center, {\n\t\t\t\t\t\tanimation: { duration: this.options.animationMediumMs },\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t}\n\t\t})\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Move shapes to page.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.moveShapesToPage(['box1', 'box2'], 'page1')\n\t * ```\n\t *\n\t * @param shapes - The shapes (or shape ids) of the shapes to move.\n\t * @param pageId - The id of the page where the shapes will be moved.\n\t *\n\t * @public\n\t */\n\tmoveShapesToPage(shapes: TLShapeId[] | TLShape[], pageId: TLPageId): this {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\n\t\tif (ids.length === 0) return this\n\t\tif (this.getInstanceState().isReadonly) return this\n\n\t\tconst currentPageId = this.getCurrentPageId()\n\n\t\tif (pageId === currentPageId) return this\n\t\tif (!this.store.has(pageId)) return this\n\n\t\t// Basically copy the shapes\n\t\tconst content = this.getContentFromCurrentPage(ids)\n\n\t\t// Just to be sure\n\t\tif (!content) return this\n\n\t\t// If there is no space on pageId, or if the selected shapes\n\t\t// would take the new page above the limit, don't move the shapes\n\t\tif (this.getPageShapeIds(pageId).size + content.shapes.length > this.options.maxShapesPerPage) {\n\t\t\talertMaxShapes(this, pageId)\n\t\t\treturn this\n\t\t}\n\n\t\tconst fromPageZ = this.getCamera().z\n\n\t\tthis.run(() => {\n\t\t\t// Delete the shapes on the current page\n\t\t\tthis.deleteShapes(ids)\n\n\t\t\t// Move to the next page\n\t\t\tthis.setCurrentPage(pageId)\n\n\t\t\t// Put the shape content onto the new page; parents and indices will\n\t\t\t// be taken care of by the putContent method; make sure to pop any focus\n\t\t\t// layers so that the content will be put onto the page.\n\t\t\tthis.setFocusedGroup(null)\n\t\t\tthis.selectNone()\n\t\t\tthis.putContentOntoCurrentPage(content, {\n\t\t\t\tselect: true,\n\t\t\t\tpreserveIds: true,\n\t\t\t\tpreservePosition: true,\n\t\t\t})\n\n\t\t\t// Force the new page's camera to be at the same zoom level as the\n\t\t\t// \"from\" page's camera, then center the \"to\" page's camera on the\n\t\t\t// pasted shapes\n\t\t\tthis.setCamera({ ...this.getCamera(), z: fromPageZ })\n\t\t\tthis.centerOnPoint(this.getSelectionRotatedPageBounds()!.center)\n\t\t})\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Toggle the lock state of one or more shapes. If there is a mix of locked and unlocked shapes, all shapes will be locked.\n\t *\n\t * @param shapes - The shapes (or shape ids) to toggle.\n\t *\n\t * @public\n\t */\n\ttoggleLock(shapes: TLShapeId[] | TLShape[]): this {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\n\t\tif (this.getInstanceState().isReadonly || ids.length === 0) return this\n\n\t\tlet allLocked = true,\n\t\t\tallUnlocked = true\n\t\tconst shapesToToggle: TLShape[] = []\n\t\tfor (const id of ids) {\n\t\t\tconst shape = this.getShape(id)\n\t\t\tif (shape) {\n\t\t\t\tshapesToToggle.push(shape)\n\t\t\t\tif (shape.isLocked) {\n\t\t\t\t\tallUnlocked = false\n\t\t\t\t} else {\n\t\t\t\t\tallLocked = false\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tthis.run(() => {\n\t\t\tif (allUnlocked) {\n\t\t\t\tthis.updateShapes(\n\t\t\t\t\tshapesToToggle.map((shape) => ({ id: shape.id, type: shape.type, isLocked: true }))\n\t\t\t\t)\n\t\t\t\tthis.setSelectedShapes([])\n\t\t\t} else if (allLocked) {\n\t\t\t\tthis.updateShapes(\n\t\t\t\t\tshapesToToggle.map((shape) => ({ id: shape.id, type: shape.type, isLocked: false }))\n\t\t\t\t)\n\t\t\t} else {\n\t\t\t\tthis.updateShapes(\n\t\t\t\t\tshapesToToggle.map((shape) => ({ id: shape.id, type: shape.type, isLocked: true }))\n\t\t\t\t)\n\t\t\t}\n\t\t})\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Send shapes to the back of the page's object list.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.sendToBack(['id1', 'id2'])\n\t * editor.sendToBack(box1, box2)\n\t * ```\n\t *\n\t * @param shapes - The shapes (or shape ids) to move.\n\t *\n\t * @public\n\t */\n\tsendToBack(shapes: TLShapeId[] | TLShape[]): this {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\t\tconst changes = getReorderingShapesChanges(this, 'toBack', ids as TLShapeId[])\n\t\tif (changes) this.updateShapes(changes)\n\t\treturn this\n\t}\n\n\t/**\n\t * Send shapes backward in the page's object list.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.sendBackward(['id1', 'id2'])\n\t * editor.sendBackward([box1, box2])\n\t * ```\n\t *\n\t * @param shapes - The shapes (or shape ids) to move.\n\t *\n\t * @public\n\t */\n\tsendBackward(shapes: TLShapeId[] | TLShape[]): this {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\t\tconst changes = getReorderingShapesChanges(this, 'backward', ids as TLShapeId[])\n\t\tif (changes) this.updateShapes(changes)\n\t\treturn this\n\t}\n\n\t/**\n\t * Bring shapes forward in the page's object list.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.bringForward(['id1', 'id2'])\n\t * editor.bringForward(box1, box2)\n\t * ```\n\t *\n\t * @param shapes - The shapes (or shape ids) to move.\n\t *\n\t * @public\n\t */\n\tbringForward(shapes: TLShapeId[] | TLShape[]): this {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\t\tconst changes = getReorderingShapesChanges(this, 'forward', ids as TLShapeId[])\n\t\tif (changes) this.updateShapes(changes)\n\t\treturn this\n\t}\n\n\t/**\n\t * Bring shapes to the front of the page's object list.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.bringToFront(['id1', 'id2'])\n\t * editor.bringToFront([box1, box2])\n\t * ```\n\t *\n\t * @param shapes - The shapes (or shape ids) to move.\n\t *\n\t * @public\n\t */\n\tbringToFront(shapes: TLShapeId[] | TLShape[]): this {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\t\tconst changes = getReorderingShapesChanges(this, 'toFront', ids as TLShapeId[])\n\t\tif (changes) this.updateShapes(changes)\n\t\treturn this\n\t}\n\n\t/**\n\t * Flip shape positions.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.flipShapes([box1, box2], 'horizontal', 32)\n\t * editor.flipShapes(editor.getSelectedShapeIds(), 'horizontal', 32)\n\t * ```\n\t *\n\t * @param shapes - The ids of the shapes to flip.\n\t * @param operation - Whether to flip horizontally or vertically.\n\t *\n\t * @public\n\t */\n\tflipShapes(shapes: TLShapeId[] | TLShape[], operation: 'horizontal' | 'vertical'): this {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\n\t\tif (this.getInstanceState().isReadonly) return this\n\n\t\tlet shapesToFlip = compact(ids.map((id) => this.getShape(id)))\n\n\t\tif (!shapesToFlip.length) return this\n\n\t\tshapesToFlip = compact(\n\t\t\tshapesToFlip\n\t\t\t\t.map((shape) => {\n\t\t\t\t\tif (this.isShapeOfType(shape, 'group')) {\n\t\t\t\t\t\treturn this.getSortedChildIdsForParent(shape.id).map((id) => this.getShape(id))\n\t\t\t\t\t}\n\n\t\t\t\t\treturn shape\n\t\t\t\t})\n\t\t\t\t.flat()\n\t\t)\n\n\t\tconst scaleOriginPage = Box.Common(\n\t\t\tcompact(shapesToFlip.map((id) => this.getShapePageBounds(id)))\n\t\t).center\n\n\t\tthis.run(() => {\n\t\t\tfor (const shape of shapesToFlip) {\n\t\t\t\tconst bounds = this.getShapeGeometry(shape).bounds\n\t\t\t\tconst initialPageTransform = this.getShapePageTransform(shape.id)\n\t\t\t\tif (!initialPageTransform) continue\n\t\t\t\tthis.resizeShape(\n\t\t\t\t\tshape.id,\n\t\t\t\t\t{ x: operation === 'horizontal' ? -1 : 1, y: operation === 'vertical' ? -1 : 1 },\n\t\t\t\t\t{\n\t\t\t\t\t\tinitialBounds: bounds,\n\t\t\t\t\t\tinitialPageTransform,\n\t\t\t\t\t\tinitialShape: shape,\n\t\t\t\t\t\tmode: 'scale_shape',\n\t\t\t\t\t\tisAspectRatioLocked: this.getShapeUtil(shape).isAspectRatioLocked(shape),\n\t\t\t\t\t\tscaleOrigin: scaleOriginPage,\n\t\t\t\t\t\tscaleAxisRotation: 0,\n\t\t\t\t\t}\n\t\t\t\t)\n\t\t\t}\n\t\t})\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Stack shape.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.stackShapes([box1, box2], 'horizontal', 32)\n\t * editor.stackShapes(editor.getSelectedShapeIds(), 'horizontal', 32)\n\t * ```\n\t *\n\t * @param shapes - The shapes (or shape ids) to stack.\n\t * @param operation - Whether to stack horizontally or vertically.\n\t * @param gap - The gap to leave between shapes.\n\t *\n\t * @public\n\t */\n\tstackShapes(\n\t\tshapes: TLShapeId[] | TLShape[],\n\t\toperation: 'horizontal' | 'vertical',\n\t\tgap: number\n\t): this {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\t\tif (this.getInstanceState().isReadonly) return this\n\n\t\tconst shapesToStack = ids\n\t\t\t.map((id) => this.getShape(id)) // always fresh shapes\n\t\t\t.filter((shape): shape is TLShape => {\n\t\t\t\tif (!shape) return false\n\n\t\t\t\treturn this.getShapeUtil(shape).canBeLaidOut(shape)\n\t\t\t})\n\n\t\tconst len = shapesToStack.length\n\n\t\tif ((gap === 0 && len < 3) || len < 2) return this\n\n\t\tconst pageBounds = Object.fromEntries(\n\t\t\tshapesToStack.map((shape) => [shape.id, this.getShapePageBounds(shape)!])\n\t\t)\n\n\t\tlet val: 'x' | 'y'\n\t\tlet min: 'minX' | 'minY'\n\t\tlet max: 'maxX' | 'maxY'\n\t\tlet dim: 'width' | 'height'\n\n\t\tif (operation === 'horizontal') {\n\t\t\tval = 'x'\n\t\t\tmin = 'minX'\n\t\t\tmax = 'maxX'\n\t\t\tdim = 'width'\n\t\t} else {\n\t\t\tval = 'y'\n\t\t\tmin = 'minY'\n\t\t\tmax = 'maxY'\n\t\t\tdim = 'height'\n\t\t}\n\n\t\tlet shapeGap: number\n\n\t\tif (gap === 0) {\n\t\t\tconst gaps: { gap: number; count: number }[] = []\n\n\t\t\tshapesToStack.sort((a, b) => pageBounds[a.id][min] - pageBounds[b.id][min])\n\n\t\t\t// Collect all of the gaps between shapes. We want to find\n\t\t\t// patterns (equal gaps between shapes) and use the most common\n\t\t\t// one as the gap for all of the shapes.\n\t\t\tfor (let i = 0; i < len - 1; i++) {\n\t\t\t\tconst shape = shapesToStack[i]\n\t\t\t\tconst nextShape = shapesToStack[i + 1]\n\n\t\t\t\tconst bounds = pageBounds[shape.id]\n\t\t\t\tconst nextBounds = pageBounds[nextShape.id]\n\n\t\t\t\tconst gap = nextBounds[min] - bounds[max]\n\n\t\t\t\tconst current = gaps.find((g) => g.gap === gap)\n\n\t\t\t\tif (current) {\n\t\t\t\t\tcurrent.count++\n\t\t\t\t} else {\n\t\t\t\t\tgaps.push({ gap, count: 1 })\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Which gap is the most common?\n\t\t\tlet maxCount = 0\n\t\t\tgaps.forEach((g) => {\n\t\t\t\tif (g.count > maxCount) {\n\t\t\t\t\tmaxCount = g.count\n\t\t\t\t\tshapeGap = g.gap\n\t\t\t\t}\n\t\t\t})\n\n\t\t\t// If there is no most-common gap, use the average gap.\n\t\t\tif (maxCount === 1) {\n\t\t\t\tshapeGap = Math.max(0, gaps.reduce((a, c) => a + c.gap * c.count, 0) / (len - 1))\n\t\t\t}\n\t\t} else {\n\t\t\t// If a gap was provided, then use that instead.\n\t\t\tshapeGap = gap\n\t\t}\n\n\t\tconst changes: TLShapePartial[] = []\n\n\t\tlet v = pageBounds[shapesToStack[0].id][max]\n\n\t\tshapesToStack.forEach((shape, i) => {\n\t\t\tif (i === 0) return\n\n\t\t\tconst delta = { x: 0, y: 0 }\n\t\t\tdelta[val] = v + shapeGap - pageBounds[shape.id][val]\n\n\t\t\tconst parent = this.getShapeParent(shape)\n\t\t\tconst localDelta = parent\n\t\t\t\t? Vec.Rot(delta, -this.getShapePageTransform(parent)!.decompose().rotation)\n\t\t\t\t: delta\n\n\t\t\tconst translateStartChanges = this.getShapeUtil(shape).onTranslateStart?.(shape)\n\n\t\t\tchanges.push(\n\t\t\t\ttranslateStartChanges\n\t\t\t\t\t? {\n\t\t\t\t\t\t\t...translateStartChanges,\n\t\t\t\t\t\t\t[val]: shape[val] + localDelta[val],\n\t\t\t\t\t\t}\n\t\t\t\t\t: {\n\t\t\t\t\t\t\tid: shape.id as any,\n\t\t\t\t\t\t\ttype: shape.type,\n\t\t\t\t\t\t\t[val]: shape[val] + localDelta[val],\n\t\t\t\t\t\t}\n\t\t\t)\n\n\t\t\tv += pageBounds[shape.id][dim] + shapeGap\n\t\t})\n\n\t\tthis.updateShapes(changes)\n\t\treturn this\n\t}\n\n\t/**\n\t * Pack shapes into a grid centered on their current position. Based on potpack (https://github.com/mapbox/potpack).\n\t *\n\t * @example\n\t * ```ts\n\t * editor.packShapes([box1, box2], 32)\n\t * editor.packShapes(editor.getSelectedShapeIds(), 32)\n\t * ```\n\t *\n\t *\n\t * @param shapes - The shapes (or shape ids) to pack.\n\t * @param gap - The padding to apply to the packed shapes. Defaults to 16.\n\t */\n\tpackShapes(shapes: TLShapeId[] | TLShape[], gap: number): this {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\n\t\tif (this.getInstanceState().isReadonly) return this\n\t\tif (ids.length < 2) return this\n\n\t\tconst shapesToPack = ids\n\t\t\t.map((id) => this.getShape(id)) // always fresh shapes\n\t\t\t.filter((shape): shape is TLShape => {\n\t\t\t\tif (!shape) return false\n\n\t\t\t\treturn this.getShapeUtil(shape).canBeLaidOut(shape)\n\t\t\t})\n\t\tconst shapePageBounds: Record = {}\n\t\tconst nextShapePageBounds: Record = {}\n\n\t\tlet shape: TLShape,\n\t\t\tbounds: Box,\n\t\t\tarea = 0\n\n\t\tfor (let i = 0; i < shapesToPack.length; i++) {\n\t\t\tshape = shapesToPack[i]\n\t\t\tbounds = this.getShapePageBounds(shape)!\n\t\t\tshapePageBounds[shape.id] = bounds\n\t\t\tnextShapePageBounds[shape.id] = bounds.clone()\n\t\t\tarea += bounds.width * bounds.height\n\t\t}\n\n\t\tconst commonBounds = Box.Common(compact(Object.values(shapePageBounds)))\n\n\t\tconst maxWidth = commonBounds.width\n\n\t\t// sort the shapes by height, descending\n\t\tshapesToPack.sort((a, b) => shapePageBounds[b.id].height - shapePageBounds[a.id].height)\n\n\t\t// Start with is (sort of) the square of the area\n\t\tconst startWidth = Math.max(Math.ceil(Math.sqrt(area / 0.95)), maxWidth)\n\n\t\t// first shape fills the width and is infinitely tall\n\t\tconst spaces: Box[] = [new Box(commonBounds.x, commonBounds.y, startWidth, Infinity)]\n\n\t\tlet width = 0\n\t\tlet height = 0\n\t\tlet space: Box\n\t\tlet last: Box\n\n\t\tfor (let i = 0; i < shapesToPack.length; i++) {\n\t\t\tshape = shapesToPack[i]\n\t\t\tbounds = nextShapePageBounds[shape.id]\n\n\t\t\t// starting at the back (smaller shapes)\n\t\t\tfor (let i = spaces.length - 1; i >= 0; i--) {\n\t\t\t\tspace = spaces[i]\n\n\t\t\t\t// find a space that is big enough to contain the shape\n\t\t\t\tif (bounds.width > space.width || bounds.height > space.height) continue\n\n\t\t\t\t// add the shape to its top-left corner\n\t\t\t\tbounds.x = space.x\n\t\t\t\tbounds.y = space.y\n\n\t\t\t\theight = Math.max(height, bounds.maxY)\n\t\t\t\twidth = Math.max(width, bounds.maxX)\n\n\t\t\t\tif (bounds.width === space.width && bounds.height === space.height) {\n\t\t\t\t\t// remove the space on a perfect fit\n\t\t\t\t\tlast = spaces.pop()!\n\t\t\t\t\tif (i < spaces.length) spaces[i] = last\n\t\t\t\t} else if (bounds.height === space.height) {\n\t\t\t\t\t// fit the shape into the space (width)\n\t\t\t\t\tspace.x += bounds.width + gap\n\t\t\t\t\tspace.width -= bounds.width + gap\n\t\t\t\t} else if (bounds.width === space.width) {\n\t\t\t\t\t// fit the shape into the space (height)\n\t\t\t\t\tspace.y += bounds.height + gap\n\t\t\t\t\tspace.height -= bounds.height + gap\n\t\t\t\t} else {\n\t\t\t\t\t// split the space into two spaces\n\t\t\t\t\tspaces.push(\n\t\t\t\t\t\tnew Box(\n\t\t\t\t\t\t\tspace.x + (bounds.width + gap),\n\t\t\t\t\t\t\tspace.y,\n\t\t\t\t\t\t\tspace.width - (bounds.width + gap),\n\t\t\t\t\t\t\tbounds.height\n\t\t\t\t\t\t)\n\t\t\t\t\t)\n\t\t\t\t\tspace.y += bounds.height + gap\n\t\t\t\t\tspace.height -= bounds.height + gap\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\n\t\tconst commonAfter = Box.Common(Object.values(nextShapePageBounds))\n\t\tconst centerDelta = Vec.Sub(commonBounds.center, commonAfter.center)\n\n\t\tlet nextBounds: Box\n\n\t\tconst changes: TLShapePartial[] = []\n\n\t\tfor (let i = 0; i < shapesToPack.length; i++) {\n\t\t\tshape = shapesToPack[i]\n\t\t\tbounds = shapePageBounds[shape.id]\n\t\t\tnextBounds = nextShapePageBounds[shape.id]\n\n\t\t\tconst delta = Vec.Sub(nextBounds.point, bounds.point).add(centerDelta)\n\t\t\tconst parentTransform = this.getShapeParentTransform(shape)\n\t\t\tif (parentTransform) delta.rot(-parentTransform.rotation())\n\n\t\t\tconst change: TLShapePartial = {\n\t\t\t\tid: shape.id,\n\t\t\t\ttype: shape.type,\n\t\t\t\tx: shape.x + delta.x,\n\t\t\t\ty: shape.y + delta.y,\n\t\t\t}\n\n\t\t\tconst translateStartChange = this.getShapeUtil(shape).onTranslateStart?.({\n\t\t\t\t...shape,\n\t\t\t\t...change,\n\t\t\t})\n\n\t\t\tif (translateStartChange) {\n\t\t\t\tchanges.push({ ...change, ...translateStartChange })\n\t\t\t} else {\n\t\t\t\tchanges.push(change)\n\t\t\t}\n\t\t}\n\n\t\tif (changes.length) {\n\t\t\tthis.updateShapes(changes)\n\t\t}\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Align shape positions.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.alignShapes([box1, box2], 'left')\n\t * editor.alignShapes(editor.getSelectedShapeIds(), 'left')\n\t * ```\n\t *\n\t * @param shapes - The shapes (or shape ids) to align.\n\t * @param operation - The align operation to apply.\n\t *\n\t * @public\n\t */\n\n\talignShapes(\n\t\tshapes: TLShapeId[] | TLShape[],\n\t\toperation: 'left' | 'center-horizontal' | 'right' | 'top' | 'center-vertical' | 'bottom'\n\t): this {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\n\t\tif (this.getInstanceState().isReadonly) return this\n\t\tif (ids.length < 2) return this\n\n\t\tconst shapesToAlign = compact(ids.map((id) => this.getShape(id))) // always fresh shapes\n\t\tconst shapePageBounds = Object.fromEntries(\n\t\t\tshapesToAlign.map((shape) => [shape.id, this.getShapePageBounds(shape)])\n\t\t)\n\t\tconst commonBounds = Box.Common(compact(Object.values(shapePageBounds)))\n\n\t\tconst changes: TLShapePartial[] = []\n\n\t\tshapesToAlign.forEach((shape) => {\n\t\t\tconst pageBounds = shapePageBounds[shape.id]\n\t\t\tif (!pageBounds) return\n\n\t\t\tconst delta = { x: 0, y: 0 }\n\n\t\t\tswitch (operation) {\n\t\t\t\tcase 'top': {\n\t\t\t\t\tdelta.y = commonBounds.minY - pageBounds.minY\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase 'center-vertical': {\n\t\t\t\t\tdelta.y = commonBounds.midY - pageBounds.minY - pageBounds.height / 2\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase 'bottom': {\n\t\t\t\t\tdelta.y = commonBounds.maxY - pageBounds.minY - pageBounds.height\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase 'left': {\n\t\t\t\t\tdelta.x = commonBounds.minX - pageBounds.minX\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase 'center-horizontal': {\n\t\t\t\t\tdelta.x = commonBounds.midX - pageBounds.minX - pageBounds.width / 2\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase 'right': {\n\t\t\t\t\tdelta.x = commonBounds.maxX - pageBounds.minX - pageBounds.width\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst parent = this.getShapeParent(shape)\n\t\t\tconst localDelta = parent\n\t\t\t\t? Vec.Rot(delta, -this.getShapePageTransform(parent)!.decompose().rotation)\n\t\t\t\t: delta\n\n\t\t\tchanges.push(this.getChangesToTranslateShape(shape, Vec.Add(shape, localDelta)))\n\t\t})\n\n\t\tthis.updateShapes(changes)\n\t\treturn this\n\t}\n\n\t/**\n\t * Distribute shape positions.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.distributeShapes([box1, box2], 'horizontal')\n\t * editor.distributeShapes(editor.getSelectedShapeIds(), 'horizontal')\n\t * ```\n\t *\n\t * @param shapes - The shapes (or shape ids) to distribute.\n\t * @param operation - Whether to distribute shapes horizontally or vertically.\n\t *\n\t * @public\n\t */\n\tdistributeShapes(shapes: TLShapeId[] | TLShape[], operation: 'horizontal' | 'vertical'): this {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\n\t\tif (this.getInstanceState().isReadonly) return this\n\t\tif (ids.length < 3) return this\n\n\t\tconst len = ids.length\n\t\tconst shapesToDistribute = compact(ids.map((id) => this.getShape(id))) // always fresh shapes\n\t\tconst pageBounds = Object.fromEntries(\n\t\t\tshapesToDistribute.map((shape) => [shape.id, this.getShapePageBounds(shape)!])\n\t\t)\n\n\t\tlet val: 'x' | 'y'\n\t\tlet min: 'minX' | 'minY'\n\t\tlet max: 'maxX' | 'maxY'\n\t\tlet mid: 'midX' | 'midY'\n\t\tlet dim: 'width' | 'height'\n\n\t\tif (operation === 'horizontal') {\n\t\t\tval = 'x'\n\t\t\tmin = 'minX'\n\t\t\tmax = 'maxX'\n\t\t\tmid = 'midX'\n\t\t\tdim = 'width'\n\t\t} else {\n\t\t\tval = 'y'\n\t\t\tmin = 'minY'\n\t\t\tmax = 'maxY'\n\t\t\tmid = 'midY'\n\t\t\tdim = 'height'\n\t\t}\n\t\tconst changes: TLShapePartial[] = []\n\n\t\t// Clustered\n\t\tconst first = shapesToDistribute.sort(\n\t\t\t(a, b) => pageBounds[a.id][min] - pageBounds[b.id][min]\n\t\t)[0]\n\t\tconst last = shapesToDistribute.sort((a, b) => pageBounds[b.id][max] - pageBounds[a.id][max])[0]\n\n\t\tconst midFirst = pageBounds[first.id][mid]\n\t\tconst step = (pageBounds[last.id][mid] - midFirst) / (len - 1)\n\t\tconst v = midFirst + step\n\n\t\tshapesToDistribute\n\t\t\t.filter((shape) => shape !== first && shape !== last)\n\t\t\t.sort((a, b) => pageBounds[a.id][mid] - pageBounds[b.id][mid])\n\t\t\t.forEach((shape, i) => {\n\t\t\t\tconst delta = { x: 0, y: 0 }\n\t\t\t\tdelta[val] = v + step * i - pageBounds[shape.id][dim] / 2 - pageBounds[shape.id][val]\n\n\t\t\t\tconst parent = this.getShapeParent(shape)\n\t\t\t\tconst localDelta = parent\n\t\t\t\t\t? Vec.Rot(delta, -this.getShapePageTransform(parent)!.rotation())\n\t\t\t\t\t: delta\n\n\t\t\t\tchanges.push(this.getChangesToTranslateShape(shape, Vec.Add(shape, localDelta)))\n\t\t\t})\n\n\t\tthis.updateShapes(changes)\n\t\treturn this\n\t}\n\n\t/**\n\t * Stretch shape sizes and positions to fill their common bounding box.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.stretchShapes([box1, box2], 'horizontal')\n\t * editor.stretchShapes(editor.getSelectedShapeIds(), 'horizontal')\n\t * ```\n\t *\n\t * @param shapes - The shapes (or shape ids) to stretch.\n\t * @param operation - Whether to stretch shapes horizontally or vertically.\n\t *\n\t * @public\n\t */\n\tstretchShapes(shapes: TLShapeId[] | TLShape[], operation: 'horizontal' | 'vertical'): this {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\n\t\tif (this.getInstanceState().isReadonly) return this\n\t\tif (ids.length < 2) return this\n\n\t\tconst shapesToStretch = compact(ids.map((id) => this.getShape(id))) // always fresh shapes\n\t\tconst shapeBounds = Object.fromEntries(ids.map((id) => [id, this.getShapeGeometry(id).bounds]))\n\t\tconst shapePageBounds = Object.fromEntries(ids.map((id) => [id, this.getShapePageBounds(id)!]))\n\t\tconst commonBounds = Box.Common(compact(Object.values(shapePageBounds)))\n\n\t\tswitch (operation) {\n\t\t\tcase 'vertical': {\n\t\t\t\tthis.run(() => {\n\t\t\t\t\tfor (const shape of shapesToStretch) {\n\t\t\t\t\t\tconst pageRotation = this.getShapePageTransform(shape)!.rotation()\n\t\t\t\t\t\tif (pageRotation % PI2) continue\n\t\t\t\t\t\tconst bounds = shapeBounds[shape.id]\n\t\t\t\t\t\tconst pageBounds = shapePageBounds[shape.id]\n\t\t\t\t\t\tconst localOffset = new Vec(0, commonBounds.minY - pageBounds.minY)\n\t\t\t\t\t\tconst parentTransform = this.getShapeParentTransform(shape)\n\t\t\t\t\t\tif (parentTransform) localOffset.rot(-parentTransform.rotation())\n\n\t\t\t\t\t\tconst { x, y } = Vec.Add(localOffset, shape)\n\t\t\t\t\t\tthis.updateShapes([{ id: shape.id, type: shape.type, x, y }])\n\t\t\t\t\t\tconst scale = new Vec(1, commonBounds.height / pageBounds.height)\n\t\t\t\t\t\tthis.resizeShape(shape.id, scale, {\n\t\t\t\t\t\t\tinitialBounds: bounds,\n\t\t\t\t\t\t\tscaleOrigin: new Vec(pageBounds.center.x, commonBounds.minY),\n\t\t\t\t\t\t\tisAspectRatioLocked: this.getShapeUtil(shape).isAspectRatioLocked(shape),\n\t\t\t\t\t\t\tscaleAxisRotation: 0,\n\t\t\t\t\t\t})\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'horizontal': {\n\t\t\t\tthis.run(() => {\n\t\t\t\t\tfor (const shape of shapesToStretch) {\n\t\t\t\t\t\tconst bounds = shapeBounds[shape.id]\n\t\t\t\t\t\tconst pageBounds = shapePageBounds[shape.id]\n\t\t\t\t\t\tconst pageRotation = this.getShapePageTransform(shape)!.rotation()\n\t\t\t\t\t\tif (pageRotation % PI2) continue\n\t\t\t\t\t\tconst localOffset = new Vec(commonBounds.minX - pageBounds.minX, 0)\n\t\t\t\t\t\tconst parentTransform = this.getShapeParentTransform(shape)\n\t\t\t\t\t\tif (parentTransform) localOffset.rot(-parentTransform.rotation())\n\n\t\t\t\t\t\tconst { x, y } = Vec.Add(localOffset, shape)\n\t\t\t\t\t\tthis.updateShapes([{ id: shape.id, type: shape.type, x, y }])\n\t\t\t\t\t\tconst scale = new Vec(commonBounds.width / pageBounds.width, 1)\n\t\t\t\t\t\tthis.resizeShape(shape.id, scale, {\n\t\t\t\t\t\t\tinitialBounds: bounds,\n\t\t\t\t\t\t\tscaleOrigin: new Vec(commonBounds.minX, pageBounds.center.y),\n\t\t\t\t\t\t\tisAspectRatioLocked: this.getShapeUtil(shape).isAspectRatioLocked(shape),\n\t\t\t\t\t\t\tscaleAxisRotation: 0,\n\t\t\t\t\t\t})\n\t\t\t\t\t}\n\t\t\t\t})\n\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Resize a shape.\n\t *\n\t * @param id - The id of the shape to resize.\n\t * @param scale - The scale factor to apply to the shape.\n\t * @param options - Additional options.\n\t *\n\t * @public\n\t */\n\tresizeShape(\n\t\tshape: TLShapeId | TLShape,\n\t\tscale: VecLike,\n\t\toptions: TLResizeShapeOptions = {}\n\t): this {\n\t\tconst id = typeof shape === 'string' ? shape : shape.id\n\t\tif (this.getInstanceState().isReadonly) return this\n\n\t\tif (!Number.isFinite(scale.x)) scale = new Vec(1, scale.y)\n\t\tif (!Number.isFinite(scale.y)) scale = new Vec(scale.x, 1)\n\n\t\tconst initialShape = options.initialShape ?? this.getShape(id)\n\t\tif (!initialShape) return this\n\n\t\tconst scaleOrigin = options.scaleOrigin ?? this.getShapePageBounds(id)?.center\n\t\tif (!scaleOrigin) return this\n\n\t\tconst pageTransform = options.initialPageTransform\n\t\t\t? Mat.Cast(options.initialPageTransform)\n\t\t\t: this.getShapePageTransform(id)\n\t\tif (!pageTransform) return this\n\n\t\tconst pageRotation = pageTransform.rotation()\n\n\t\tif (pageRotation == null) return this\n\n\t\tconst scaleAxisRotation = options.scaleAxisRotation ?? pageRotation\n\n\t\tconst initialBounds = options.initialBounds ?? this.getShapeGeometry(id).bounds\n\n\t\tif (!initialBounds) return this\n\n\t\tconst isAspectRatioLocked =\n\t\t\toptions.isAspectRatioLocked ??\n\t\t\tthis.getShapeUtil(initialShape).isAspectRatioLocked(initialShape)\n\n\t\tif (!areAnglesCompatible(pageRotation, scaleAxisRotation)) {\n\t\t\t// shape is awkwardly rotated, keep the aspect ratio locked and adopt the scale factor\n\t\t\t// from whichever axis is being scaled the least, to avoid the shape getting bigger\n\t\t\t// than the bounds of the selection\n\t\t\t// const minScale = Math.min(Math.abs(scale.x), Math.abs(scale.y))\n\t\t\treturn this._resizeUnalignedShape(id, scale, {\n\t\t\t\t...options,\n\t\t\t\tinitialBounds,\n\t\t\t\tscaleOrigin,\n\t\t\t\tscaleAxisRotation,\n\t\t\t\tinitialPageTransform: pageTransform,\n\t\t\t\tisAspectRatioLocked,\n\t\t\t\tinitialShape,\n\t\t\t})\n\t\t}\n\n\t\tconst util = this.getShapeUtil(initialShape)\n\n\t\tif (isAspectRatioLocked) {\n\t\t\tif (Math.abs(scale.x) > Math.abs(scale.y)) {\n\t\t\t\tscale = new Vec(scale.x, Math.sign(scale.y) * Math.abs(scale.x))\n\t\t\t} else {\n\t\t\t\tscale = new Vec(Math.sign(scale.x) * Math.abs(scale.y), scale.y)\n\t\t\t}\n\t\t}\n\n\t\tif (util.onResize && util.canResize(initialShape)) {\n\t\t\t// get the model changes from the shape util\n\t\t\tconst newPagePoint = this._scalePagePoint(\n\t\t\t\tMat.applyToPoint(pageTransform, new Vec(0, 0)),\n\t\t\t\tscaleOrigin,\n\t\t\t\tscale,\n\t\t\t\tscaleAxisRotation\n\t\t\t)\n\n\t\t\tconst newLocalPoint = this.getPointInParentSpace(initialShape.id, newPagePoint)\n\n\t\t\t// resize the shape's local bounding box\n\t\t\tconst myScale = new Vec(scale.x, scale.y)\n\t\t\t// the shape is aligned with the rest of the shapes in the selection, but may be\n\t\t\t// 90deg offset from the main rotation of the selection, in which case\n\t\t\t// we need to flip the width and height scale factors\n\t\t\tconst areWidthAndHeightAlignedWithCorrectAxis = approximately(\n\t\t\t\t(pageRotation - scaleAxisRotation) % Math.PI,\n\t\t\t\t0\n\t\t\t)\n\t\t\tmyScale.x = areWidthAndHeightAlignedWithCorrectAxis ? scale.x : scale.y\n\t\t\tmyScale.y = areWidthAndHeightAlignedWithCorrectAxis ? scale.y : scale.x\n\n\t\t\t// adjust initial model for situations where the parent has moved during the resize\n\t\t\t// e.g. groups\n\t\t\tconst initialPagePoint = Mat.applyToPoint(pageTransform, new Vec())\n\n\t\t\t// need to adjust the shape's x and y points in case the parent has moved since start of resizing\n\t\t\tconst { x, y } = this.getPointInParentSpace(initialShape.id, initialPagePoint)\n\n\t\t\tlet workingShape = initialShape\n\t\t\tif (!options.skipStartAndEndCallbacks) {\n\t\t\t\tworkingShape = applyPartialToRecordWithProps(\n\t\t\t\t\tinitialShape,\n\t\t\t\t\tutil.onResizeStart?.(initialShape) ?? undefined\n\t\t\t\t)\n\t\t\t}\n\n\t\t\tworkingShape = applyPartialToRecordWithProps(workingShape, {\n\t\t\t\tid,\n\t\t\t\ttype: initialShape.type as any,\n\t\t\t\tx: newLocalPoint.x,\n\t\t\t\ty: newLocalPoint.y,\n\t\t\t\t...util.onResize(\n\t\t\t\t\t{ ...initialShape, x, y },\n\t\t\t\t\t{\n\t\t\t\t\t\tnewPoint: newLocalPoint,\n\t\t\t\t\t\thandle: options.dragHandle ?? 'bottom_right',\n\t\t\t\t\t\t// don't set isSingle to true for children\n\t\t\t\t\t\tmode: options.mode ?? 'scale_shape',\n\t\t\t\t\t\tscaleX: myScale.x,\n\t\t\t\t\t\tscaleY: myScale.y,\n\t\t\t\t\t\tinitialBounds,\n\t\t\t\t\t\tinitialShape,\n\t\t\t\t\t}\n\t\t\t\t),\n\t\t\t})\n\n\t\t\tif (!options.skipStartAndEndCallbacks) {\n\t\t\t\tworkingShape = applyPartialToRecordWithProps(\n\t\t\t\t\tworkingShape,\n\t\t\t\t\tutil.onResizeEnd?.(initialShape, workingShape) ?? undefined\n\t\t\t\t)\n\t\t\t}\n\n\t\t\tthis.updateShapes([workingShape])\n\t\t} else {\n\t\t\tconst initialPageCenter = Mat.applyToPoint(pageTransform, initialBounds.center)\n\t\t\t// get the model changes from the shape util\n\t\t\tconst newPageCenter = this._scalePagePoint(\n\t\t\t\tinitialPageCenter,\n\t\t\t\tscaleOrigin,\n\t\t\t\tscale,\n\t\t\t\tscaleAxisRotation\n\t\t\t)\n\n\t\t\tconst initialPageCenterInParentSpace = this.getPointInParentSpace(\n\t\t\t\tinitialShape.id,\n\t\t\t\tinitialPageCenter\n\t\t\t)\n\t\t\tconst newPageCenterInParentSpace = this.getPointInParentSpace(initialShape.id, newPageCenter)\n\n\t\t\tconst delta = Vec.Sub(newPageCenterInParentSpace, initialPageCenterInParentSpace)\n\t\t\t// apply the changes to the model\n\t\t\tthis.updateShapes([\n\t\t\t\t{\n\t\t\t\t\tid,\n\t\t\t\t\ttype: initialShape.type as any,\n\t\t\t\t\tx: initialShape.x + delta.x,\n\t\t\t\t\ty: initialShape.y + delta.y,\n\t\t\t\t},\n\t\t\t])\n\t\t}\n\n\t\treturn this\n\t}\n\n\t/** @internal */\n\tprivate _scalePagePoint(\n\t\tpoint: VecLike,\n\t\tscaleOrigin: VecLike,\n\t\tscale: VecLike,\n\t\tscaleAxisRotation: number\n\t) {\n\t\tconst relativePoint = Vec.RotWith(point, scaleOrigin, -scaleAxisRotation).sub(scaleOrigin)\n\n\t\t// calculate the new point position relative to the scale origin\n\t\tconst newRelativePagePoint = Vec.MulV(relativePoint, scale)\n\n\t\t// and rotate it back to page coords to get the new page point of the resized shape\n\t\tconst destination = Vec.Add(newRelativePagePoint, scaleOrigin).rotWith(\n\t\t\tscaleOrigin,\n\t\t\tscaleAxisRotation\n\t\t)\n\n\t\treturn destination\n\t}\n\n\t/** @internal */\n\tprivate _resizeUnalignedShape(\n\t\tid: TLShapeId,\n\t\tscale: VecLike,\n\t\toptions: {\n\t\t\tinitialBounds: Box\n\t\t\tscaleOrigin: VecLike\n\t\t\tscaleAxisRotation: number\n\t\t\tinitialShape: TLShape\n\t\t\tisAspectRatioLocked: boolean\n\t\t\tinitialPageTransform: MatLike\n\t\t}\n\t) {\n\t\tconst { type } = options.initialShape\n\t\t// If a shape is not aligned with the scale axis we need to treat it differently to avoid skewing.\n\t\t// Instead of skewing we normalize the scale aspect ratio (i.e. keep the same scale magnitude in both axes)\n\t\t// and then after applying the scale to the shape we also rotate it if required and translate it so that it's center\n\t\t// point ends up in the right place.\n\n\t\tconst shapeScale = new Vec(scale.x, scale.y)\n\n\t\t// // make sure we are constraining aspect ratio, and using the smallest scale axis to avoid shapes getting bigger\n\t\t// // than the selection bounding box\n\t\tif (Math.abs(scale.x) > Math.abs(scale.y)) {\n\t\t\tshapeScale.x = Math.sign(scale.x) * Math.abs(scale.y)\n\t\t} else {\n\t\t\tshapeScale.y = Math.sign(scale.y) * Math.abs(scale.x)\n\t\t}\n\n\t\t// first we can scale the shape about its center point\n\t\tthis.resizeShape(id, shapeScale, {\n\t\t\tinitialShape: options.initialShape,\n\t\t\tinitialBounds: options.initialBounds,\n\t\t\tisAspectRatioLocked: options.isAspectRatioLocked,\n\t\t})\n\n\t\t// then if the shape is flipped in one axis only, we need to apply an extra rotation\n\t\t// to make sure the shape is mirrored correctly\n\t\tif (Math.sign(scale.x) * Math.sign(scale.y) < 0) {\n\t\t\tlet { rotation } = Mat.Decompose(options.initialPageTransform)\n\t\t\trotation -= 2 * rotation\n\t\t\tthis.updateShapes([{ id, type, rotation }])\n\t\t}\n\n\t\t// Next we need to translate the shape so that it's center point ends up in the right place.\n\t\t// To do that we first need to calculate the center point of the shape in the current page space before the scale was applied.\n\t\tconst preScaleShapePageCenter = Mat.applyToPoint(\n\t\t\toptions.initialPageTransform,\n\t\t\toptions.initialBounds.center\n\t\t)\n\n\t\t// And now we scale the center point by the original scale factor\n\t\tconst postScaleShapePageCenter = this._scalePagePoint(\n\t\t\tpreScaleShapePageCenter,\n\t\t\toptions.scaleOrigin,\n\t\t\tscale,\n\t\t\toptions.scaleAxisRotation\n\t\t)\n\n\t\t// now calculate how far away the shape is from where it needs to be\n\t\tconst pageBounds = this.getShapePageBounds(id)!\n\t\tconst pageTransform = this.getShapePageTransform(id)!\n\t\tconst currentPageCenter = pageBounds.center\n\t\tconst shapePageTransformOrigin = pageTransform.point()\n\t\tif (!currentPageCenter || !shapePageTransformOrigin) return this\n\t\tconst pageDelta = Vec.Sub(postScaleShapePageCenter, currentPageCenter)\n\n\t\t// and finally figure out what the shape's new position should be\n\t\tconst postScaleShapePagePoint = Vec.Add(shapePageTransformOrigin, pageDelta)\n\t\tconst { x, y } = this.getPointInParentSpace(id, postScaleShapePagePoint)\n\n\t\tthis.updateShapes([{ id, type, x, y }])\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Get the initial meta value for a shape.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getInitialMetaForShape = (shape) => {\n\t * if (shape.type === 'note') {\n\t * return { createdBy: myCurrentUser.id }\n\t * }\n\t * }\n\t * ```\n\t *\n\t * @param shape - The shape to get the initial meta for.\n\t *\n\t * @public\n\t */\n\tgetInitialMetaForShape(_shape: TLShape): JsonObject {\n\t\treturn {}\n\t}\n\n\t/**\n\t * Create a single shape.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.createShape(myShape)\n\t * editor.createShape({ id: 'box1', type: 'text', props: { text: \"ok\" } })\n\t * ```\n\t *\n\t * @param shape - The shape (or shape partial) to create.\n\t *\n\t * @public\n\t */\n\tcreateShape(shape: OptionalKeys, 'id'>): this {\n\t\tthis.createShapes([shape])\n\t\treturn this\n\t}\n\n\t/**\n\t * Create shapes.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.createShapes([myShape])\n\t * editor.createShapes([{ id: 'box1', type: 'text', props: { text: \"ok\" } }])\n\t * ```\n\t *\n\t * @param shapes - The shapes (or shape partials) to create.\n\t * @param select - Whether to select the created shapes. Defaults to false.\n\t *\n\t * @public\n\t */\n\tcreateShapes(shapes: OptionalKeys, 'id'>[]): this {\n\t\tif (!Array.isArray(shapes)) {\n\t\t\tthrow Error('Editor.createShapes: must provide an array of shapes or shape partials')\n\t\t}\n\t\tif (this.getInstanceState().isReadonly) return this\n\t\tif (shapes.length <= 0) return this\n\n\t\tconst currentPageShapeIds = this.getCurrentPageShapeIds()\n\n\t\tconst maxShapesReached =\n\t\t\tshapes.length + currentPageShapeIds.size > this.options.maxShapesPerPage\n\n\t\tif (maxShapesReached) {\n\t\t\t// can't create more shapes than fit on the page\n\t\t\talertMaxShapes(this)\n\t\t\treturn this\n\t\t}\n\n\t\tconst focusedGroupId = this.getFocusedGroupId()\n\n\t\tthis.run(() => {\n\t\t\t// 1. Parents\n\n\t\t\t// Make sure that each partial will become the child of either the\n\t\t\t// page or another shape that exists (or that will exist) in this page.\n\n\t\t\t// find last parent id\n\t\t\tconst currentPageShapesSorted = this.getCurrentPageShapesSorted()\n\n\t\t\tconst partials = shapes.map((partial) => {\n\t\t\t\tif (!partial.id) {\n\t\t\t\t\tpartial = { id: createShapeId(), ...partial }\n\t\t\t\t}\n\n\t\t\t\t// If the partial does not provide the parentId OR if the provided\n\t\t\t\t// parentId is NOT in the store AND NOT among the other shapes being\n\t\t\t\t// created, then we need to find a parent for the shape. This can be\n\t\t\t\t// another shape that exists under that point and which can receive\n\t\t\t\t// children of the creating shape's type, or else the page itself.\n\t\t\t\tif (\n\t\t\t\t\t!partial.parentId ||\n\t\t\t\t\t!(this.store.has(partial.parentId) || shapes.some((p) => p.id === partial.parentId))\n\t\t\t\t) {\n\t\t\t\t\tlet parentId: TLParentId = this.getFocusedGroupId()\n\n\t\t\t\t\tfor (let i = currentPageShapesSorted.length - 1; i >= 0; i--) {\n\t\t\t\t\t\tconst parent = currentPageShapesSorted[i]\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t!this.isShapeHidden(parent) &&\n\t\t\t\t\t\t\tthis.getShapeUtil(parent).canReceiveNewChildrenOfType(parent, partial.type) &&\n\t\t\t\t\t\t\tthis.isPointInShape(\n\t\t\t\t\t\t\t\tparent,\n\t\t\t\t\t\t\t\t// If no parent is provided, then we can treat the\n\t\t\t\t\t\t\t\t// shape's provided x/y as being in the page's space.\n\t\t\t\t\t\t\t\t{ x: partial.x ?? 0, y: partial.y ?? 0 },\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tmargin: 0,\n\t\t\t\t\t\t\t\t\thitInside: true,\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\tparentId = parent.id\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tconst prevParentId = partial.parentId\n\n\t\t\t\t\t// a shape cannot be it's own parent. This was a rare issue with frames/groups in the syncFuzz tests.\n\t\t\t\t\tif (parentId === partial.id) {\n\t\t\t\t\t\tparentId = focusedGroupId\n\t\t\t\t\t}\n\n\t\t\t\t\t// If the parentid has changed...\n\t\t\t\t\tif (parentId !== prevParentId) {\n\t\t\t\t\t\tpartial = { ...partial }\n\n\t\t\t\t\t\tpartial.parentId = parentId\n\n\t\t\t\t\t\t// If the parent is a shape (rather than a page) then insert the\n\t\t\t\t\t\t// shapes into the shape's children. Adjust the point and page rotation to be\n\t\t\t\t\t\t// preserved relative to the parent.\n\t\t\t\t\t\tif (isShapeId(parentId)) {\n\t\t\t\t\t\t\tconst point = this.getPointInShapeSpace(this.getShape(parentId)!, {\n\t\t\t\t\t\t\t\tx: partial.x ?? 0,\n\t\t\t\t\t\t\t\ty: partial.y ?? 0,\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\tpartial.x = point.x\n\t\t\t\t\t\t\tpartial.y = point.y\n\t\t\t\t\t\t\tpartial.rotation =\n\t\t\t\t\t\t\t\t-this.getShapePageTransform(parentId)!.rotation() + (partial.rotation ?? 0)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn partial\n\t\t\t})\n\n\t\t\t// 2. Indices\n\n\t\t\t// Get the highest index among the parents of each of the\n\t\t\t// the shapes being created; we'll increment from there.\n\n\t\t\tconst parentIndices = new Map()\n\n\t\t\tconst shapeRecordsToCreate: TLShape[] = []\n\n\t\t\tconst { opacityForNextShape } = this.getInstanceState()\n\n\t\t\tfor (const partial of partials) {\n\t\t\t\tconst util = this.getShapeUtil(partial as TLShapePartial)\n\n\t\t\t\t// If an index is not explicitly provided, then add the\n\t\t\t\t// shapes to the top of their parents' children; using the\n\t\t\t\t// value in parentsMappedToIndex, get the index above, use it,\n\t\t\t\t// and set it back to parentsMappedToIndex for next time.\n\t\t\t\tlet index = partial.index\n\n\t\t\t\tif (!index) {\n\t\t\t\t\t// Hello bug-seeker: have you just created a frame and then a shape\n\t\t\t\t\t// and found that the shape is automatically the child of the frame?\n\t\t\t\t\t// this is the reason why! It would be harder to have each shape specify\n\t\t\t\t\t// the frame as the parent when creating a shape inside of a frame, so\n\t\t\t\t\t// we do it here.\n\t\t\t\t\tconst parentId = partial.parentId ?? focusedGroupId\n\n\t\t\t\t\tif (!parentIndices.has(parentId)) {\n\t\t\t\t\t\tparentIndices.set(parentId, this.getHighestIndexForParent(parentId))\n\t\t\t\t\t}\n\t\t\t\t\tindex = parentIndices.get(parentId)!\n\t\t\t\t\tparentIndices.set(parentId, getIndexAbove(index))\n\t\t\t\t}\n\n\t\t\t\t// The initial props starts as the shape utility's default props\n\t\t\t\tconst initialProps = util.getDefaultProps()\n\n\t\t\t\t// We then look up each key in the tab state's styles; and if it's there,\n\t\t\t\t// we use the value from the tab state's styles instead of the default.\n\t\t\t\tfor (const [style, propKey] of this.styleProps[partial.type]) {\n\t\t\t\t\t;(initialProps as any)[propKey] = this.getStyleForNextShape(style)\n\t\t\t\t}\n\n\t\t\t\t// When we create the shape, take in the partial (the props coming into the\n\t\t\t\t// function) and merge it with the default props.\n\t\t\t\tlet shapeRecordToCreate = (\n\t\t\t\t\tthis.store.schema.types.shape as RecordType<\n\t\t\t\t\t\tTLShape,\n\t\t\t\t\t\t'type' | 'props' | 'index' | 'parentId'\n\t\t\t\t\t>\n\t\t\t\t).create({\n\t\t\t\t\t...partial,\n\t\t\t\t\tindex,\n\t\t\t\t\topacity: partial.opacity ?? opacityForNextShape,\n\t\t\t\t\tparentId: partial.parentId ?? focusedGroupId,\n\t\t\t\t\tprops: 'props' in partial ? { ...initialProps, ...partial.props } : initialProps,\n\t\t\t\t})\n\n\t\t\t\tif (shapeRecordToCreate.index === undefined) {\n\t\t\t\t\tthrow Error('no index!')\n\t\t\t\t}\n\n\t\t\t\tconst next = this.getShapeUtil(shapeRecordToCreate).onBeforeCreate?.(shapeRecordToCreate)\n\n\t\t\t\tif (next) {\n\t\t\t\t\tshapeRecordToCreate = next\n\t\t\t\t}\n\n\t\t\t\tshapeRecordsToCreate.push(shapeRecordToCreate)\n\t\t\t}\n\n\t\t\t// Add meta properties, if any, to the shapes\n\t\t\tshapeRecordsToCreate.forEach((shape) => {\n\t\t\t\tshape.meta = {\n\t\t\t\t\t...this.getInitialMetaForShape(shape),\n\t\t\t\t\t...shape.meta,\n\t\t\t\t}\n\t\t\t})\n\n\t\t\tthis.store.put(shapeRecordsToCreate)\n\t\t})\n\n\t\treturn this\n\t}\n\n\tprivate animatingShapes = new Map()\n\n\t/**\n\t * Animate a shape.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.animateShape({ id: 'box1', type: 'box', x: 100, y: 100 })\n\t * editor.animateShape({ id: 'box1', type: 'box', x: 100, y: 100 }, { animation: { duration: 100, ease: t => t*t } })\n\t * ```\n\t *\n\t * @param partial - The shape partial to update.\n\t * @param options - The animation's options.\n\t *\n\t * @public\n\t */\n\tanimateShape(\n\t\tpartial: TLShapePartial | null | undefined,\n\t\topts = { animation: DEFAULT_ANIMATION_OPTIONS } as TLCameraMoveOptions\n\t): this {\n\t\treturn this.animateShapes([partial], opts)\n\t}\n\n\t/**\n\t * Animate shapes.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.animateShapes([{ id: 'box1', type: 'box', x: 100, y: 100 }])\n\t * editor.animateShapes([{ id: 'box1', type: 'box', x: 100, y: 100 }], { animation: { duration: 100, ease: t => t*t } })\n\t * ```\n\t *\n\t * @param partials - The shape partials to update.\n\t * @param options - The animation's options.\n\t *\n\t * @public\n\t */\n\tanimateShapes(\n\t\tpartials: (TLShapePartial | null | undefined)[],\n\t\topts = { animation: DEFAULT_ANIMATION_OPTIONS } as TLCameraMoveOptions\n\t): this {\n\t\tif (!opts.animation) return this\n\t\tconst { duration = 500, easing = EASINGS.linear } = opts.animation\n\n\t\tconst animationId = uniqueId()\n\n\t\tlet remaining = duration\n\t\tlet t: number\n\n\t\tinterface ShapeAnimation {\n\t\t\tstart: TLShape\n\t\t\tend: TLShape\n\t\t}\n\n\t\tconst animations: ShapeAnimation[] = []\n\n\t\tlet partial: TLShapePartial | null | undefined, result: ShapeAnimation\n\t\tfor (let i = 0, n = partials.length; i < n; i++) {\n\t\t\tpartial = partials[i]\n\t\t\tif (!partial) continue\n\n\t\t\tconst shape = this.getShape(partial.id)!\n\t\t\tif (!shape) continue\n\n\t\t\tresult = {\n\t\t\t\tstart: structuredClone(shape),\n\t\t\t\tend: applyPartialToRecordWithProps(structuredClone(shape), partial),\n\t\t\t}\n\n\t\t\tanimations.push(result)\n\t\t\tthis.animatingShapes.set(shape.id, animationId)\n\t\t}\n\n\t\tconst handleTick = (elapsed: number) => {\n\t\t\tremaining -= elapsed\n\n\t\t\tif (remaining < 0) {\n\t\t\t\tconst { animatingShapes } = this\n\t\t\t\tconst partialsToUpdate = partials.filter(\n\t\t\t\t\t(p) => p && animatingShapes.get(p.id) === animationId\n\t\t\t\t)\n\t\t\t\tif (partialsToUpdate.length) {\n\t\t\t\t\t// the regular update shapes also removes the shape from\n\t\t\t\t\t// the animating shapes set\n\t\t\t\t\tthis.updateShapes(partialsToUpdate)\n\t\t\t\t}\n\n\t\t\t\tthis.off('tick', handleTick)\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tt = easing(1 - remaining / duration)\n\n\t\t\tconst { animatingShapes } = this\n\n\t\t\tconst updates: TLShapePartial[] = []\n\n\t\t\tlet animationIdForShape: string | undefined\n\t\t\tfor (let i = 0, n = animations.length; i < n; i++) {\n\t\t\t\tconst { start, end } = animations[i]\n\t\t\t\t// Is the animation for this shape still active?\n\t\t\t\tanimationIdForShape = animatingShapes.get(start.id)\n\t\t\t\tif (animationIdForShape !== animationId) continue\n\n\t\t\t\tupdates.push({\n\t\t\t\t\t...end,\n\t\t\t\t\tx: start.x + (end.x - start.x) * t,\n\t\t\t\t\ty: start.y + (end.y - start.y) * t,\n\t\t\t\t\topacity: start.opacity + (end.opacity - start.opacity) * t,\n\t\t\t\t\trotation: start.rotation + (end.rotation - start.rotation) * t,\n\t\t\t\t\tprops: this.getShapeUtil(end).getInterpolatedProps?.(start, end, t) ?? end.props,\n\t\t\t\t})\n\t\t\t}\n\n\t\t\t// The _updateShapes method does NOT remove the\n\t\t\t// shapes from the animated shapes set\n\t\t\tthis._updateShapes(updates)\n\t\t}\n\n\t\tthis.on('tick', handleTick)\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Create a group containing the provided shapes.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.groupShapes([myShape, myOtherShape])\n\t * editor.groupShapes([myShape, myOtherShape], { groupId: myGroupId, select: false })\n\t * ```\n\t *\n\t * @param shapes - The shapes (or shape ids) to group. Defaults to the selected shapes.\n\t * @param options - An options object.\n\t *\n\t * @public\n\t */\n\tgroupShapes(shapes: TLShape[], options?: Partial<{ groupId: TLShapeId; select: boolean }>): this\n\tgroupShapes(ids: TLShapeId[], options?: Partial<{ groupId: TLShapeId; select: boolean }>): this\n\tgroupShapes(\n\t\tshapes: TLShapeId[] | TLShape[],\n\t\toptions = {} as Partial<{ groupId: TLShapeId; select: boolean }>\n\t): this {\n\t\tconst { groupId = createShapeId(), select = true } = options\n\n\t\tif (!Array.isArray(shapes)) {\n\t\t\tthrow Error('Editor.groupShapes: must provide an array of shapes or shape ids')\n\t\t}\n\t\tif (this.getInstanceState().isReadonly) return this\n\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes.map((s) => (s as TLShape).id) as TLShapeId[])\n\n\t\tif (ids.length <= 1) return this\n\n\t\tconst shapesToGroup = compact(\n\t\t\t(this._shouldIgnoreShapeLock ? ids : this._getUnlockedShapeIds(ids)).map((id) =>\n\t\t\t\tthis.getShape(id)\n\t\t\t)\n\t\t)\n\t\tconst sortedShapeIds = shapesToGroup.sort(sortByIndex).map((s) => s.id)\n\t\tconst pageBounds = Box.Common(compact(shapesToGroup.map((id) => this.getShapePageBounds(id))))\n\n\t\tconst { x, y } = pageBounds.point\n\n\t\tconst parentId = this.findCommonAncestor(shapesToGroup) ?? this.getCurrentPageId()\n\n\t\t// Only group when the select tool is active\n\t\tif (this.getCurrentToolId() !== 'select') return this\n\n\t\t// If not already in idle, cancel the current interaction (get back to idle)\n\t\tif (!this.isIn('select.idle')) {\n\t\t\tthis.cancel()\n\t\t}\n\n\t\t// Find all the shapes that have the same parentId, and use the highest index.\n\t\tconst shapesWithRootParent = shapesToGroup\n\t\t\t.filter((shape) => shape.parentId === parentId)\n\t\t\t.sort(sortByIndex)\n\n\t\tconst highestIndex = shapesWithRootParent[shapesWithRootParent.length - 1]?.index\n\n\t\tthis.run(() => {\n\t\t\tthis.createShapes([\n\t\t\t\t{\n\t\t\t\t\tid: groupId,\n\t\t\t\t\ttype: 'group',\n\t\t\t\t\tparentId,\n\t\t\t\t\tindex: highestIndex,\n\t\t\t\t\tx,\n\t\t\t\t\ty,\n\t\t\t\t\topacity: 1,\n\t\t\t\t\tprops: {},\n\t\t\t\t},\n\t\t\t])\n\t\t\tthis.reparentShapes(sortedShapeIds, groupId)\n\t\t\tif (select) {\n\t\t\t\t// the select option determines whether the grouped shapes' children are selected\n\t\t\t\tthis.select(groupId)\n\t\t\t}\n\t\t})\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Ungroup some shapes.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.ungroupShapes([myGroup, myOtherGroup])\n\t * editor.ungroupShapes([myGroup], { select: false })\n\t * ```\n\t *\n\t * @param shapes - The group shapes (or shape ids) to ungroup.\n\t * @param options - An options object.\n\t *\n\t * @public\n\t */\n\tungroupShapes(ids: TLShapeId[], options?: Partial<{ select: boolean }>): this\n\tungroupShapes(shapes: TLShape[], options?: Partial<{ select: boolean }>): this\n\tungroupShapes(shapes: TLShapeId[] | TLShape[], options = {} as Partial<{ select: boolean }>) {\n\t\tif (this.getInstanceState().isReadonly) return this\n\n\t\tconst { select = true } = options\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\n\t\tconst shapesToUngroup = compact(\n\t\t\t(this._shouldIgnoreShapeLock ? ids : this._getUnlockedShapeIds(ids)).map((id) =>\n\t\t\t\tthis.getShape(id)\n\t\t\t)\n\t\t)\n\n\t\tif (shapesToUngroup.length === 0) return this\n\n\t\t// todo: the editor shouldn't know about the select tool, move to group / ungroup actions\n\t\tif (this.getCurrentToolId() !== 'select') return this\n\t\tif (!this.isIn('select.idle')) {\n\t\t\tthis.cancel()\n\t\t}\n\n\t\t// The ids of the selected shapes after ungrouping;\n\t\t// these include all of the grouped shapes children,\n\t\t// plus any shapes that were selected apart from the groups.\n\t\tconst idsToSelect = new Set()\n\n\t\t// Get all groups in the selection\n\t\tconst groups: TLGroupShape[] = []\n\n\t\tshapesToUngroup.forEach((shape) => {\n\t\t\tif (this.isShapeOfType(shape, 'group')) {\n\t\t\t\tgroups.push(shape)\n\t\t\t} else {\n\t\t\t\tidsToSelect.add(shape.id)\n\t\t\t}\n\t\t})\n\n\t\tif (groups.length === 0) return this\n\n\t\tthis.run(() => {\n\t\t\tlet group: TLGroupShape\n\n\t\t\tfor (let i = 0, n = groups.length; i < n; i++) {\n\t\t\t\tgroup = groups[i]\n\t\t\t\tconst childIds = this.getSortedChildIdsForParent(group.id)\n\n\t\t\t\tfor (let j = 0, n = childIds.length; j < n; j++) {\n\t\t\t\t\tidsToSelect.add(childIds[j])\n\t\t\t\t}\n\n\t\t\t\tthis.reparentShapes(childIds, group.parentId, group.index)\n\t\t\t}\n\n\t\t\tthis.deleteShapes(groups.map((group) => group.id))\n\n\t\t\tif (select) {\n\t\t\t\t// the select option determines whether the ungrouped shapes' children are selected\n\t\t\t\tthis.select(...idsToSelect)\n\t\t\t}\n\t\t})\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Update a shape using a partial of the shape.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.updateShape({ id: 'box1', type: 'geo', props: { w: 100, h: 100 } })\n\t * ```\n\t *\n\t * @param partial - The shape partial to update.\n\t *\n\t * @public\n\t */\n\tupdateShape(partial: TLShapePartial | null | undefined) {\n\t\tthis.updateShapes([partial])\n\t\treturn this\n\t}\n\n\t/**\n\t * Update shapes using partials of each shape.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.updateShapes([{ id: 'box1', type: 'geo', props: { w: 100, h: 100 } }])\n\t * ```\n\t *\n\t * @param partials - The shape partials to update.\n\t *\n\t * @public\n\t */\n\tupdateShapes(partials: (TLShapePartial | null | undefined)[]) {\n\t\tconst compactedPartials: TLShapePartial[] = Array(partials.length)\n\n\t\tfor (let i = 0, n = partials.length; i < n; i++) {\n\t\t\tconst partial = partials[i]\n\t\t\tif (!partial) continue\n\t\t\t// Get the current shape referenced by the partial\n\t\t\tconst shape = this.getShape(partial.id)\n\t\t\tif (!shape) continue\n\n\t\t\t// If we're \"forcing\" the update, then we'll update the shape\n\t\t\t// regardless of whether it / its ancestor is locked\n\t\t\tif (!this._shouldIgnoreShapeLock) {\n\t\t\t\tif (shape.isLocked) {\n\t\t\t\t\t// If the shape itself is locked (even if one of its ancestors is\n\t\t\t\t\t// also locked) then only allow an update that unlocks the shape.\n\t\t\t\t\tif (!(Object.hasOwn(partial, 'isLocked') && !partial.isLocked)) {\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\t\t\t\t} else if (this.isShapeOrAncestorLocked(shape)) {\n\t\t\t\t\t// If the shape itself is unlocked, and any of the shape's\n\t\t\t\t\t// ancestors are locked then we'll skip the update\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Remove any animating shapes from the list of partials\n\t\t\tthis.animatingShapes.delete(partial.id)\n\n\t\t\tcompactedPartials.push(partial)\n\t\t}\n\n\t\tthis._updateShapes(compactedPartials)\n\t\treturn this\n\t}\n\n\t/** @internal */\n\t_updateShapes(_partials: (TLShapePartial | null | undefined)[]) {\n\t\tif (this.getInstanceState().isReadonly) return\n\n\t\tthis.run(() => {\n\t\t\tconst updates = []\n\n\t\t\tlet shape: TLShape | undefined\n\t\t\tlet updated: TLShape\n\n\t\t\tfor (let i = 0, n = _partials.length; i < n; i++) {\n\t\t\t\tconst partial = _partials[i]\n\t\t\t\t// Skip nullish partials (sometimes created by map fns returning undefined)\n\t\t\t\tif (!partial) continue\n\n\t\t\t\t// Get the current shape referenced by the partial\n\t\t\t\t// If there is no current shape, we'll skip this update\n\t\t\t\tshape = this.getShape(partial.id)\n\t\t\t\tif (!shape) continue\n\n\t\t\t\t// Get the updated version of the shape\n\t\t\t\t// If the update had no effect, we'll skip this update\n\t\t\t\tupdated = applyPartialToRecordWithProps(shape, partial)\n\t\t\t\tif (updated === shape) continue\n\n\t\t\t\t//if any shape has an onBeforeUpdate handler, call it and, if the handler returns a\n\t\t\t\t// new shape, replace the old shape with the new one. This is used for example when\n\t\t\t\t// repositioning a text shape based on its new text content.\n\t\t\t\tupdated = this.getShapeUtil(shape).onBeforeUpdate?.(shape, updated) ?? updated\n\n\t\t\t\tupdates.push(updated)\n\t\t\t}\n\n\t\t\tthis.store.put(updates)\n\t\t})\n\t}\n\n\t/** @internal */\n\tprivate _getUnlockedShapeIds(ids: TLShapeId[]): TLShapeId[] {\n\t\treturn ids.filter((id) => !this.getShape(id)?.isLocked)\n\t}\n\n\t/**\n\t * Delete shapes.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.deleteShapes(['box1', 'box2'])\n\t * ```\n\t *\n\t * @param ids - The ids of the shapes to delete.\n\t *\n\t * @public\n\t */\n\tdeleteShapes(ids: TLShapeId[]): this\n\tdeleteShapes(shapes: TLShape[]): this\n\tdeleteShapes(_ids: TLShapeId[] | TLShape[]): this {\n\t\tif (this.getInstanceState().isReadonly) return this\n\n\t\tif (!Array.isArray(_ids)) {\n\t\t\tthrow Error('Editor.deleteShapes: must provide an array of shapes or shapeIds')\n\t\t}\n\n\t\tconst shapeIds =\n\t\t\ttypeof _ids[0] === 'string' ? (_ids as TLShapeId[]) : (_ids as TLShape[]).map((s) => s.id)\n\n\t\t// Normally we don't want to delete locked shapes, but if the force option is set, we'll delete them anyway\n\t\tconst shapeIdsToDelete = this._shouldIgnoreShapeLock\n\t\t\t? shapeIds\n\t\t\t: this._getUnlockedShapeIds(shapeIds)\n\n\t\tif (shapeIdsToDelete.length === 0) return this\n\n\t\t// We also need to delete these shapes' descendants\n\t\tconst allShapeIdsToDelete = new Set(shapeIdsToDelete)\n\n\t\tfor (const id of shapeIdsToDelete) {\n\t\t\tthis.visitDescendants(id, (childId) => {\n\t\t\t\tallShapeIdsToDelete.add(childId)\n\t\t\t})\n\t\t}\n\n\t\treturn this.run(() => this.store.remove([...allShapeIdsToDelete]))\n\t}\n\n\t/**\n\t * Delete a shape.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.deleteShape(shape.id)\n\t * ```\n\t *\n\t * @param id - The id of the shape to delete.\n\t *\n\t * @public\n\t */\n\tdeleteShape(id: TLShapeId): this\n\tdeleteShape(shape: TLShape): this\n\tdeleteShape(_id: TLShapeId | TLShape) {\n\t\tthis.deleteShapes([typeof _id === 'string' ? _id : _id.id])\n\t\treturn this\n\t}\n\n\t/* --------------------- Styles --------------------- */\n\n\t/**\n\t * Get all the current styles among the users selected shapes\n\t *\n\t * @internal\n\t */\n\tprivate _extractSharedStyles(shape: TLShape, sharedStyleMap: SharedStyleMap) {\n\t\tif (this.isShapeOfType(shape, 'group')) {\n\t\t\t// For groups, ignore the styles of the group shape and instead include the styles of the\n\t\t\t// group's children. These are the shapes that would have their styles changed if the\n\t\t\t// user called `setStyle` on the current selection.\n\t\t\tconst childIds = this._parentIdsToChildIds.get()[shape.id]\n\t\t\tif (!childIds) return\n\n\t\t\tfor (let i = 0, n = childIds.length; i < n; i++) {\n\t\t\t\tthis._extractSharedStyles(this.getShape(childIds[i])!, sharedStyleMap)\n\t\t\t}\n\t\t} else {\n\t\t\tfor (const [style, propKey] of this.styleProps[shape.type]) {\n\t\t\t\tsharedStyleMap.applyValue(style, getOwnProperty(shape.props, propKey))\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * A derived map containing all current styles among the user's selected shapes.\n\t *\n\t * @internal\n\t */\n\t@computed\n\tprivate _getSelectionSharedStyles(): ReadonlySharedStyleMap {\n\t\tconst selectedShapes = this.getSelectedShapes()\n\n\t\tconst sharedStyles = new SharedStyleMap()\n\t\tfor (const selectedShape of selectedShapes) {\n\t\t\tthis._extractSharedStyles(selectedShape, sharedStyles)\n\t\t}\n\n\t\treturn sharedStyles\n\t}\n\n\t/**\n\t * Get the style for the next shape.\n\t *\n\t * @example\n\t * ```ts\n\t * const color = editor.getStyleForNextShape(DefaultColorStyle)\n\t * ```\n\t *\n\t * @param style - The style to get.\n\t *\n\t * @public */\n\tgetStyleForNextShape(style: StyleProp): T {\n\t\tconst value = this.getInstanceState().stylesForNextShape[style.id]\n\t\treturn value === undefined ? style.defaultValue : (value as T)\n\t}\n\n\tgetShapeStyleIfExists(shape: TLShape, style: StyleProp): T | undefined {\n\t\tconst styleKey = this.styleProps[shape.type].get(style)\n\t\tif (styleKey === undefined) return undefined\n\t\treturn getOwnProperty(shape.props, styleKey) as T | undefined\n\t}\n\n\t/**\n\t * A map of all the current styles either in the current selection, or that are relevant to the\n\t * current tool.\n\t *\n\t * @example\n\t * ```ts\n\t * const color = editor.getSharedStyles().get(DefaultColorStyle)\n\t * if (color && color.type === 'shared') {\n\t * print('All selected shapes have the same color:', color.value)\n\t * }\n\t * ```\n\t *\n\t * @public\n\t */\n\t@computed({ isEqual: (a, b) => a.equals(b) })\n\tgetSharedStyles(): ReadonlySharedStyleMap {\n\t\t// If we're in selecting and if we have a selection, return the shared styles from the\n\t\t// current selection\n\t\tif (this.isIn('select') && this.getSelectedShapeIds().length > 0) {\n\t\t\treturn this._getSelectionSharedStyles()\n\t\t}\n\n\t\t// If the current tool is associated with a shape, return the styles for that shape.\n\t\t// Otherwise, just return an empty map.\n\t\tconst currentTool = this.root.getCurrent()!\n\t\tconst styles = new SharedStyleMap()\n\n\t\tif (!currentTool) return styles\n\n\t\tif (currentTool.shapeType) {\n\t\t\tfor (const style of this.styleProps[currentTool.shapeType].keys()) {\n\t\t\t\tstyles.applyValue(style, this.getStyleForNextShape(style))\n\t\t\t}\n\t\t}\n\n\t\treturn styles\n\t}\n\n\t/**\n\t * Get the currently selected shared opacity.\n\t * If any shapes are selected, this returns the shared opacity of the selected shapes.\n\t * Otherwise, this returns the chosen opacity for the next shape.\n\t *\n\t * @public\n\t */\n\t@computed getSharedOpacity(): SharedStyle {\n\t\tif (this.isIn('select') && this.getSelectedShapeIds().length > 0) {\n\t\t\tconst shapesToCheck: TLShape[] = []\n\t\t\tconst addShape = (shapeId: TLShapeId) => {\n\t\t\t\tconst shape = this.getShape(shapeId)\n\t\t\t\tif (!shape) return\n\t\t\t\t// For groups, ignore the opacity of the group shape and instead include\n\t\t\t\t// the opacity of the group's children. These are the shapes that would have\n\t\t\t\t// their opacity changed if the user called `setOpacity` on the current selection.\n\t\t\t\tif (this.isShapeOfType(shape, 'group')) {\n\t\t\t\t\tfor (const childId of this.getSortedChildIdsForParent(shape.id)) {\n\t\t\t\t\t\taddShape(childId)\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tshapesToCheck.push(shape)\n\t\t\t\t}\n\t\t\t}\n\t\t\tfor (const shapeId of this.getSelectedShapeIds()) {\n\t\t\t\taddShape(shapeId)\n\t\t\t}\n\n\t\t\tlet opacity: number | null = null\n\t\t\tfor (const shape of shapesToCheck) {\n\t\t\t\tif (opacity === null) {\n\t\t\t\t\topacity = shape.opacity\n\t\t\t\t} else if (opacity !== shape.opacity) {\n\t\t\t\t\treturn { type: 'mixed' }\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (opacity !== null) return { type: 'shared', value: opacity }\n\t\t}\n\t\treturn { type: 'shared', value: this.getInstanceState().opacityForNextShape }\n\t}\n\n\t/**\n\t * Set the opacity for the next shapes. This will effect subsequently created shapes.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.setOpacityForNextShapes(0.5)\n\t * ```\n\t *\n\t * @param opacity - The opacity to set. Must be a number between 0 and 1 inclusive.\n\t * @param historyOptions - The history options for the change.\n\t */\n\tsetOpacityForNextShapes(opacity: number, historyOptions?: TLHistoryBatchOptions): this {\n\t\tthis.updateInstanceState({ opacityForNextShape: opacity }, historyOptions)\n\t\treturn this\n\t}\n\n\t/**\n\t * Set the current opacity. This will effect any selected shapes.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.setOpacityForSelectedShapes(0.5)\n\t * ```\n\t *\n\t * @param opacity - The opacity to set. Must be a number between 0 and 1 inclusive.\n\t */\n\tsetOpacityForSelectedShapes(opacity: number): this {\n\t\tconst selectedShapes = this.getSelectedShapes()\n\n\t\tif (selectedShapes.length > 0) {\n\t\t\tconst shapesToUpdate: TLShape[] = []\n\n\t\t\t// We can have many deep levels of grouped shape\n\t\t\t// Making a recursive function to look through all the levels\n\t\t\tconst addShapeById = (shape: TLShape) => {\n\t\t\t\tif (this.isShapeOfType(shape, 'group')) {\n\t\t\t\t\tconst childIds = this.getSortedChildIdsForParent(shape)\n\t\t\t\t\tfor (const childId of childIds) {\n\t\t\t\t\t\taddShapeById(this.getShape(childId)!)\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tshapesToUpdate.push(shape)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfor (const id of selectedShapes) {\n\t\t\t\taddShapeById(id)\n\t\t\t}\n\n\t\t\tthis.updateShapes(\n\t\t\t\tshapesToUpdate.map((shape) => {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tid: shape.id,\n\t\t\t\t\t\ttype: shape.type,\n\t\t\t\t\t\topacity,\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t)\n\t\t}\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Set the value of a {@link @tldraw/tlschema#StyleProp} for the next shapes. This change will be applied to subsequently created shapes.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.setStyleForNextShapes(DefaultColorStyle, 'red')\n\t * editor.setStyleForNextShapes(DefaultColorStyle, 'red', { ephemeral: true })\n\t * ```\n\t *\n\t * @param style - The style to set.\n\t * @param value - The value to set.\n\t * @param historyOptions - The history options for the change.\n\t *\n\t * @public\n\t */\n\tsetStyleForNextShapes(\n\t\tstyle: StyleProp,\n\t\tvalue: T,\n\t\thistoryOptions?: TLHistoryBatchOptions\n\t): this {\n\t\tconst stylesForNextShape = this.getInstanceState().stylesForNextShape\n\n\t\tthis.updateInstanceState(\n\t\t\t{ stylesForNextShape: { ...stylesForNextShape, [style.id]: value } },\n\t\t\thistoryOptions\n\t\t)\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Set the value of a {@link @tldraw/tlschema#StyleProp}. This change will be applied to the currently selected shapes.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.setStyleForSelectedShapes(DefaultColorStyle, 'red')\n\t * ```\n\t *\n\t * @param style - The style to set.\n\t * @param value - The value to set.\n\t * @param historyOptions - The history options for the change.\n\t *\n\t * @public\n\t */\n\tsetStyleForSelectedShapes>(style: S, value: StylePropValue): this {\n\t\tconst selectedShapes = this.getSelectedShapes()\n\n\t\tif (selectedShapes.length > 0) {\n\t\t\tconst updates: {\n\t\t\t\tutil: ShapeUtil\n\t\t\t\toriginalShape: TLShape\n\t\t\t\tupdatePartial: TLShapePartial\n\t\t\t}[] = []\n\n\t\t\t// We can have many deep levels of grouped shape\n\t\t\t// Making a recursive function to look through all the levels\n\t\t\tconst addShapeById = (shape: TLShape) => {\n\t\t\t\tif (this.isShapeOfType(shape, 'group')) {\n\t\t\t\t\tconst childIds = this.getSortedChildIdsForParent(shape.id)\n\t\t\t\t\tfor (const childId of childIds) {\n\t\t\t\t\t\taddShapeById(this.getShape(childId)!)\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tconst util = this.getShapeUtil(shape)\n\t\t\t\t\tconst stylePropKey = this.styleProps[shape.type].get(style)\n\t\t\t\t\tif (stylePropKey) {\n\t\t\t\t\t\tconst shapePartial: TLShapePartial = {\n\t\t\t\t\t\t\tid: shape.id,\n\t\t\t\t\t\t\ttype: shape.type,\n\t\t\t\t\t\t\tprops: { [stylePropKey]: value },\n\t\t\t\t\t\t}\n\t\t\t\t\t\tupdates.push({\n\t\t\t\t\t\t\tutil,\n\t\t\t\t\t\t\toriginalShape: shape,\n\t\t\t\t\t\t\tupdatePartial: shapePartial,\n\t\t\t\t\t\t})\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfor (const shape of selectedShapes) {\n\t\t\t\taddShapeById(shape)\n\t\t\t}\n\n\t\t\tthis.updateShapes(updates.map(({ updatePartial }) => updatePartial))\n\t\t}\n\n\t\treturn this\n\t}\n\n\t/* --------------------- Content -------------------- */\n\n\t/** @internal */\n\texternalAssetContentHandlers: {\n\t\t[K in TLExternalAssetContent['type']]: {\n\t\t\t[Key in K]:\n\t\t\t\t| null\n\t\t\t\t| ((info: TLExternalAssetContent & { type: Key }) => Promise)\n\t\t}[K]\n\t} = {\n\t\tfile: null,\n\t\turl: null,\n\t}\n\n\t/** @internal */\n\tprivate readonly temporaryAssetPreview = new Map()\n\n\t/**\n\t * Register an external asset handler. This handler will be called when the editor needs to\n\t * create an asset for some external content, like an image/video file or a bookmark URL. For\n\t * example, the 'file' type handler will be called when a user drops an image onto the canvas.\n\t *\n\t * The handler should extract any relevant metadata for the asset, upload it to blob storage\n\t * using {@link Editor.uploadAsset} if needed, and return the asset with the metadata & uploaded\n\t * URL.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.registerExternalAssetHandler('file', myHandler)\n\t * ```\n\t *\n\t * @param type - The type of external content.\n\t * @param handler - The handler to use for this content type.\n\t *\n\t * @public\n\t */\n\tregisterExternalAssetHandler(\n\t\ttype: T,\n\t\thandler: null | ((info: TLExternalAssetContent & { type: T }) => Promise)\n\t): this {\n\t\tthis.externalAssetContentHandlers[type] = handler as any\n\t\treturn this\n\t}\n\n\t/**\n\t * Register a temporary preview of an asset. This is useful for showing a ghost image of\n\t * something that is being uploaded. Retrieve the placeholder with\n\t * {@link Editor.getTemporaryAssetPreview}. Placeholders last for 3 minutes by default, but this\n\t * can be configured using\n\t *\n\t * @example\n\t * ```ts\n\t * editor.createTemporaryAssetPreview(assetId, file)\n\t * ```\n\t *\n\t * @param assetId - The asset's id.\n\t * @param file - The raw file.\n\t *\n\t * @public\n\t */\n\tcreateTemporaryAssetPreview(assetId: TLAssetId, file: File) {\n\t\tif (this.temporaryAssetPreview.has(assetId)) {\n\t\t\treturn this.temporaryAssetPreview.get(assetId)\n\t\t}\n\n\t\tconst objectUrl = URL.createObjectURL(file)\n\t\tthis.temporaryAssetPreview.set(assetId, objectUrl)\n\n\t\t// eslint-disable-next-line no-restricted-globals -- we always want to revoke the asset and object URL\n\t\tsetTimeout(() => {\n\t\t\tthis.temporaryAssetPreview.delete(assetId)\n\t\t\tURL.revokeObjectURL(objectUrl)\n\t\t}, this.options.temporaryAssetPreviewLifetimeMs)\n\n\t\treturn objectUrl\n\t}\n\n\t/**\n\t * Get temporary preview of an asset. This is useful for showing a ghost\n\t * image of something that is being uploaded.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getTemporaryAssetPreview('someId')\n\t * ```\n\t *\n\t * @param assetId - The asset's id.\n\t *\n\t * @public\n\t */\n\tgetTemporaryAssetPreview(assetId: TLAssetId) {\n\t\treturn this.temporaryAssetPreview.get(assetId)\n\t}\n\n\t/**\n\t * Get an asset for an external asset content type.\n\t *\n\t * @example\n\t * ```ts\n\t * const asset = await editor.getAssetForExternalContent({ type: 'file', file: myFile })\n\t * const asset = await editor.getAssetForExternalContent({ type: 'url', url: myUrl })\n\t * ```\n\t *\n\t * @param info - Info about the external content.\n\t * @returns The asset.\n\t */\n\tasync getAssetForExternalContent(info: TLExternalAssetContent): Promise {\n\t\treturn await this.externalAssetContentHandlers[info.type]?.(info as any)\n\t}\n\n\thasExternalAssetHandler(type: TLExternalAssetContent['type']): boolean {\n\t\treturn !!this.externalAssetContentHandlers[type]\n\t}\n\n\t/** @internal */\n\texternalContentHandlers: {\n\t\t[K in TLExternalContent['type']]: {\n\t\t\t[Key in K]: null | ((info: TLExternalContent & { type: Key }) => void)\n\t\t}[K]\n\t} = {\n\t\ttext: null,\n\t\tfiles: null,\n\t\tembed: null,\n\t\t'svg-text': null,\n\t\turl: null,\n\t}\n\n\t/**\n\t * Register an external content handler. This handler will be called when the editor receives\n\t * external content of the provided type. For example, the 'image' type handler will be called\n\t * when a user drops an image onto the canvas.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.registerExternalContentHandler('text', myHandler)\n\t * ```\n\t * @example\n\t * ```ts\n\t * editor.registerExternalContentHandler<'embed', MyEmbedType>('embed', myHandler)\n\t * ```\n\t *\n\t * @param type - The type of external content.\n\t * @param handler - The handler to use for this content type.\n\t *\n\t * @public\n\t */\n\tregisterExternalContentHandler['type'], E>(\n\t\ttype: T,\n\t\thandler:\n\t\t\t| null\n\t\t\t| ((\n\t\t\t\t\tinfo: T extends TLExternalContent['type']\n\t\t\t\t\t\t? TLExternalContent & { type: T }\n\t\t\t\t\t\t: TLExternalContent\n\t\t\t ) => void)\n\t): this {\n\t\tthis.externalContentHandlers[type] = handler as any\n\t\treturn this\n\t}\n\n\t/**\n\t * Handle external content, such as files, urls, embeds, or plain text which has been put into the app, for example by pasting external text or dropping external images onto canvas.\n\t *\n\t * @param info - Info about the external content.\n\t */\n\tasync putExternalContent(info: TLExternalContent): Promise {\n\t\treturn this.externalContentHandlers[info.type]?.(info as any)\n\t}\n\n\t/**\n\t * Get content that can be exported for the given shape ids.\n\t *\n\t * @param shapes - The shapes (or shape ids) to get content for.\n\t *\n\t * @returns The exported content.\n\t *\n\t * @public\n\t */\n\tgetContentFromCurrentPage(shapes: TLShapeId[] | TLShape[]): TLContent | undefined {\n\t\t// todo: make this work with any page, not just the current page\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\n\t\tif (!ids) return\n\t\tif (ids.length === 0) return\n\n\t\tconst shapeIds = this.getShapeAndDescendantIds(ids)\n\n\t\treturn withIsolatedShapes(this, shapeIds, (bindingIdsToKeep) => {\n\t\t\tconst bindings: TLBinding[] = []\n\t\t\tfor (const id of bindingIdsToKeep) {\n\t\t\t\tconst binding = this.getBinding(id)\n\t\t\t\tif (!binding) continue\n\t\t\t\tbindings.push(binding)\n\t\t\t}\n\n\t\t\tconst rootShapeIds: TLShapeId[] = []\n\t\t\tconst shapes: TLShape[] = []\n\t\t\tfor (const shapeId of shapeIds) {\n\t\t\t\tconst shape = this.getShape(shapeId)\n\t\t\t\tif (!shape) continue\n\n\t\t\t\tconst isRootShape = !shapeIds.has(shape.parentId as TLShapeId)\n\t\t\t\tif (isRootShape) {\n\t\t\t\t\t// Need to get page point and rotation of the shape because shapes in\n\t\t\t\t\t// groups use local position/rotation\n\t\t\t\t\tconst pageTransform = this.getShapePageTransform(shape.id)!\n\t\t\t\t\tconst pagePoint = pageTransform.point()\n\t\t\t\t\tshapes.push({\n\t\t\t\t\t\t...shape,\n\t\t\t\t\t\tx: pagePoint.x,\n\t\t\t\t\t\ty: pagePoint.y,\n\t\t\t\t\t\trotation: pageTransform.rotation(),\n\t\t\t\t\t\tparentId: this.getCurrentPageId(),\n\t\t\t\t\t})\n\t\t\t\t\trootShapeIds.push(shape.id)\n\t\t\t\t} else {\n\t\t\t\t\tshapes.push(shape)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst assets: TLAsset[] = []\n\t\t\tconst seenAssetIds = new Set()\n\t\t\tfor (const shape of shapes) {\n\t\t\t\tif (!('assetId' in shape.props)) continue\n\n\t\t\t\tconst assetId = shape.props.assetId\n\t\t\t\tif (!assetId || seenAssetIds.has(assetId)) continue\n\n\t\t\t\tseenAssetIds.add(assetId)\n\t\t\t\tconst asset = this.getAsset(assetId)\n\t\t\t\tif (!asset) continue\n\t\t\t\tassets.push(asset)\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tschema: this.store.schema.serialize(),\n\t\t\t\tshapes,\n\t\t\t\trootShapeIds,\n\t\t\t\tbindings,\n\t\t\t\tassets,\n\t\t\t}\n\t\t})\n\t}\n\n\tasync resolveAssetsInContent(content: TLContent | undefined): Promise {\n\t\tif (!content) return undefined\n\n\t\tconst assets: TLAsset[] = []\n\t\tawait Promise.allSettled(\n\t\t\tcontent.assets.map(async (asset) => {\n\t\t\t\tif (\n\t\t\t\t\t(asset.type === 'image' || asset.type === 'video') &&\n\t\t\t\t\t!asset.props.src?.startsWith('data:image') &&\n\t\t\t\t\t!asset.props.src?.startsWith('http')\n\t\t\t\t) {\n\t\t\t\t\tconst assetWithDataUrl = structuredClone(asset as TLImageAsset | TLVideoAsset)\n\t\t\t\t\tconst objectUrl = await this.store.props.assets.resolve(asset, {\n\t\t\t\t\t\tscreenScale: 1,\n\t\t\t\t\t\tsteppedScreenScale: 1,\n\t\t\t\t\t\tdpr: 1,\n\t\t\t\t\t\tnetworkEffectiveType: null,\n\t\t\t\t\t\tshouldResolveToOriginal: true,\n\t\t\t\t\t})\n\t\t\t\t\tassetWithDataUrl.props.src = await FileHelpers.blobToDataUrl(\n\t\t\t\t\t\tawait fetch(objectUrl!).then((r) => r.blob())\n\t\t\t\t\t)\n\t\t\t\t\tassets.push(assetWithDataUrl)\n\t\t\t\t} else {\n\t\t\t\t\tassets.push(asset)\n\t\t\t\t}\n\t\t\t})\n\t\t)\n\t\tcontent.assets = assets\n\n\t\treturn content\n\t}\n\n\t/**\n\t * Place content into the editor.\n\t *\n\t * @param content - The content.\n\t * @param options - Options for placing the content.\n\t *\n\t * @public\n\t */\n\tputContentOntoCurrentPage(\n\t\tcontent: TLContent,\n\t\toptions: {\n\t\t\tpoint?: VecLike\n\t\t\tselect?: boolean\n\t\t\tpreservePosition?: boolean\n\t\t\tpreserveIds?: boolean\n\t\t} = {}\n\t): this {\n\t\tif (this.getInstanceState().isReadonly) return this\n\n\t\t// todo: make this able to support putting content onto any page, not just the current page\n\n\t\tif (!content.schema) {\n\t\t\tthrow Error('Could not put content:\\ncontent is missing a schema.')\n\t\t}\n\n\t\tconst { select = false, preserveIds = false, preservePosition = false } = options\n\t\tlet { point = undefined } = options\n\n\t\t// decide on a parent for the put shapes; if the parent is among the put shapes(?) then use its parent\n\n\t\tconst currentPageId = this.getCurrentPageId()\n\t\tconst { rootShapeIds } = content\n\n\t\t// We need to collect the migrated records\n\t\tconst assets: TLAsset[] = []\n\t\tconst shapes: TLShape[] = []\n\t\tconst bindings: TLBinding[] = []\n\n\t\t// Let's treat the content as a store, and then migrate that store.\n\t\tconst store: StoreSnapshot = {\n\t\t\tstore: {\n\t\t\t\t...Object.fromEntries(content.assets.map((asset) => [asset.id, asset] as const)),\n\t\t\t\t...Object.fromEntries(content.shapes.map((shape) => [shape.id, shape] as const)),\n\t\t\t\t...Object.fromEntries(\n\t\t\t\t\tcontent.bindings?.map((bindings) => [bindings.id, bindings] as const) ?? []\n\t\t\t\t),\n\t\t\t},\n\t\t\tschema: content.schema,\n\t\t}\n\t\tconst result = this.store.schema.migrateStoreSnapshot(store)\n\t\tif (result.type === 'error') {\n\t\t\tthrow Error('Could not put content: could not migrate content')\n\t\t}\n\t\tfor (const record of Object.values(result.value)) {\n\t\t\tswitch (record.typeName) {\n\t\t\t\tcase 'asset': {\n\t\t\t\t\tassets.push(record)\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase 'shape': {\n\t\t\t\t\tshapes.push(record)\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase 'binding': {\n\t\t\t\t\tbindings.push(record)\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Ok, we've got our migrated records, now we can continue!\n\t\tconst shapeIdMap = new Map(\n\t\t\tpreserveIds\n\t\t\t\t? shapes.map((shape) => [shape.id, shape.id])\n\t\t\t\t: shapes.map((shape) => [shape.id, createShapeId()])\n\t\t)\n\t\tconst bindingIdMap = new Map(\n\t\t\tpreserveIds\n\t\t\t\t? bindings.map((binding) => [binding.id, binding.id])\n\t\t\t\t: bindings.map((binding) => [binding.id, createBindingId()])\n\t\t)\n\n\t\t// By default, the paste parent will be the current page.\n\t\tlet pasteParentId = this.getCurrentPageId() as TLPageId | TLShapeId\n\t\tlet lowestDepth = Infinity\n\t\tlet lowestAncestors: TLShape[] = []\n\n\t\t// Among the selected shapes, find the shape with the fewest ancestors and use its first ancestor.\n\t\tfor (const shape of this.getSelectedShapes()) {\n\t\t\tif (lowestDepth === 0) break\n\n\t\t\tconst isFrame = this.isShapeOfType(shape, 'frame')\n\t\t\tconst ancestors = this.getShapeAncestors(shape)\n\t\t\tif (isFrame) ancestors.push(shape)\n\n\t\t\tconst depth = isFrame ? ancestors.length + 1 : ancestors.length\n\n\t\t\tif (depth < lowestDepth) {\n\t\t\t\tlowestDepth = depth\n\t\t\t\tlowestAncestors = ancestors\n\t\t\t\tpasteParentId = isFrame ? shape.id : shape.parentId\n\t\t\t} else if (depth === lowestDepth) {\n\t\t\t\tif (lowestAncestors.length !== ancestors.length) {\n\t\t\t\t\tthrow Error(`Ancestors: ${lowestAncestors.length} !== ${ancestors.length}`)\n\t\t\t\t}\n\n\t\t\t\tif (lowestAncestors.length === 0) {\n\t\t\t\t\tpasteParentId = currentPageId\n\t\t\t\t\tbreak\n\t\t\t\t} else {\n\t\t\t\t\tpasteParentId = currentPageId\n\t\t\t\t\tfor (let i = 0; i < lowestAncestors.length; i++) {\n\t\t\t\t\t\tif (ancestors[i] !== lowestAncestors[i]) break\n\t\t\t\t\t\tpasteParentId = ancestors[i].id\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tlet isDuplicating = false\n\n\t\tif (!isPageId(pasteParentId)) {\n\t\t\tconst parent = this.getShape(pasteParentId)\n\t\t\tif (parent) {\n\t\t\t\tif (!this.getViewportPageBounds().includes(this.getShapePageBounds(parent)!)) {\n\t\t\t\t\tpasteParentId = currentPageId\n\t\t\t\t} else {\n\t\t\t\t\tif (rootShapeIds.length === 1) {\n\t\t\t\t\t\tconst rootShape = shapes.find((s) => s.id === rootShapeIds[0])!\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\tthis.isShapeOfType(parent, 'frame') &&\n\t\t\t\t\t\t\tthis.isShapeOfType(rootShape, 'frame') &&\n\t\t\t\t\t\t\trootShape.props.w === parent?.props.w &&\n\t\t\t\t\t\t\trootShape.props.h === parent?.props.h\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\tisDuplicating = true\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tpasteParentId = currentPageId\n\t\t\t}\n\t\t}\n\n\t\tif (!isDuplicating) {\n\t\t\tisDuplicating = shapeIdMap.has(pasteParentId)\n\t\t}\n\n\t\tif (isDuplicating) {\n\t\t\tpasteParentId = this.getShape(pasteParentId)!.parentId\n\t\t}\n\n\t\tlet index = this.getHighestIndexForParent(pasteParentId) // todo: requires that the putting page is the current page\n\n\t\tconst rootShapes: TLShape[] = []\n\n\t\tconst newShapes: TLShape[] = shapes.map((oldShape): TLShape => {\n\t\t\tconst newId = shapeIdMap.get(oldShape.id)!\n\n\t\t\t// Create the new shape (new except for the id)\n\t\t\tconst newShape = { ...oldShape, id: newId }\n\n\t\t\tif (rootShapeIds.includes(oldShape.id)) {\n\t\t\t\tnewShape.parentId = currentPageId\n\t\t\t\trootShapes.push(newShape)\n\t\t\t}\n\n\t\t\t// Assign the child to its new parent.\n\n\t\t\t// If the child's parent is among the putting shapes, then assign\n\t\t\t// it to the new parent's id.\n\t\t\tif (shapeIdMap.has(newShape.parentId)) {\n\t\t\t\tnewShape.parentId = shapeIdMap.get(oldShape.parentId)!\n\t\t\t} else {\n\t\t\t\trootShapeIds.push(newShape.id)\n\t\t\t\t// newShape.parentId = pasteParentId\n\t\t\t\tnewShape.index = index\n\t\t\t\tindex = getIndexAbove(index)\n\t\t\t}\n\n\t\t\treturn newShape\n\t\t})\n\n\t\tif (newShapes.length + this.getCurrentPageShapeIds().size > this.options.maxShapesPerPage) {\n\t\t\t// There's some complexity here involving children\n\t\t\t// that might be created without their parents, so\n\t\t\t// if we're going over the limit then just don't paste.\n\t\t\talertMaxShapes(this)\n\t\t\treturn this\n\t\t}\n\n\t\tconst newBindings = bindings.map(\n\t\t\t(oldBinding): TLBinding => ({\n\t\t\t\t...oldBinding,\n\t\t\t\tid: assertExists(bindingIdMap.get(oldBinding.id)),\n\t\t\t\tfromId: assertExists(shapeIdMap.get(oldBinding.fromId)),\n\t\t\t\ttoId: assertExists(shapeIdMap.get(oldBinding.toId)),\n\t\t\t})\n\t\t)\n\n\t\t// These are all the assets we need to create\n\t\tconst assetsToCreate: TLAsset[] = []\n\n\t\t// These assets have base64 data that may need to be hosted\n\t\tconst assetsToUpdate: (TLImageAsset | TLVideoAsset)[] = []\n\n\t\tfor (const asset of assets) {\n\t\t\tif (this.store.has(asset.id)) {\n\t\t\t\t// We already have this asset\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tif (\n\t\t\t\t(asset.type === 'image' || asset.type === 'video') &&\n\t\t\t\tasset.props.src?.startsWith('data:image')\n\t\t\t) {\n\t\t\t\t// it's src is a base64 image or video; we need to create a new asset without the src,\n\t\t\t\t// then create a new asset from the original src. So we save a copy of the original asset,\n\t\t\t\t// then delete the src from the original asset.\n\t\t\t\tassetsToUpdate.push(structuredClone(asset as TLImageAsset | TLVideoAsset))\n\t\t\t\tasset.props.src = null\n\t\t\t}\n\n\t\t\t// Add the asset to the list of assets to create\n\t\t\tassetsToCreate.push(asset)\n\t\t}\n\n\t\t// Start loading the new assets, order does not matter\n\t\tPromise.allSettled(\n\t\t\t(assetsToUpdate as (TLImageAsset | TLVideoAsset)[]).map(async (asset) => {\n\t\t\t\t// Turn the data url into a file\n\t\t\t\tconst file = await dataUrlToFile(\n\t\t\t\t\tasset.props.src!,\n\t\t\t\t\tasset.props.name,\n\t\t\t\t\tasset.props.mimeType ?? 'image/png'\n\t\t\t\t)\n\n\t\t\t\t// Get a new asset for the file\n\t\t\t\tconst newAsset = await this.getAssetForExternalContent({\n\t\t\t\t\ttype: 'file',\n\t\t\t\t\tfile,\n\t\t\t\t\tassetId: asset.id,\n\t\t\t\t})\n\n\t\t\t\tif (!newAsset) {\n\t\t\t\t\t// If we don't have a new asset, delete the old asset.\n\t\t\t\t\t// The shapes that reference this asset should break.\n\t\t\t\t\tthis.deleteAssets([asset.id])\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\t// Save the new asset under the old asset's id\n\t\t\t\tthis.updateAssets([{ ...newAsset, id: asset.id }])\n\t\t\t})\n\t\t)\n\n\t\tthis.run(() => {\n\t\t\t// Create any assets that need to be created\n\t\t\tif (assetsToCreate.length > 0) {\n\t\t\t\tthis.createAssets(assetsToCreate)\n\t\t\t}\n\n\t\t\t// Create the shapes with root shapes as children of the page\n\t\t\tthis.createShapes(newShapes)\n\t\t\tthis.createBindings(newBindings)\n\n\t\t\tif (select) {\n\t\t\t\tthis.select(...rootShapes.map((s) => s.id))\n\t\t\t}\n\n\t\t\t// And then, if needed, reparent the root shapes to the paste parent\n\t\t\tif (pasteParentId !== currentPageId) {\n\t\t\t\tthis.reparentShapes(\n\t\t\t\t\trootShapes.map((s) => s.id),\n\t\t\t\t\tpasteParentId\n\t\t\t\t)\n\t\t\t}\n\n\t\t\tconst newCreatedShapes = newShapes.map((s) => this.getShape(s.id)!)\n\t\t\tconst bounds = Box.Common(newCreatedShapes.map((s) => this.getShapePageBounds(s)!))\n\n\t\t\tif (point === undefined) {\n\t\t\t\tif (!isPageId(pasteParentId)) {\n\t\t\t\t\t// Put the shapes in the middle of the (on screen) parent\n\t\t\t\t\tconst shape = this.getShape(pasteParentId)!\n\t\t\t\t\tpoint = Mat.applyToPoint(\n\t\t\t\t\t\tthis.getShapePageTransform(shape),\n\t\t\t\t\t\tthis.getShapeGeometry(shape).bounds.center\n\t\t\t\t\t)\n\t\t\t\t} else {\n\t\t\t\t\tconst viewportPageBounds = this.getViewportPageBounds()\n\t\t\t\t\tif (preservePosition || viewportPageBounds.includes(Box.From(bounds))) {\n\t\t\t\t\t\t// Otherwise, put shapes where they used to be\n\t\t\t\t\t\tpoint = bounds.center\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// If the old bounds are outside of the viewport...\n\t\t\t\t\t\t// put the shapes in the middle of the viewport\n\t\t\t\t\t\tpoint = viewportPageBounds.center\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (rootShapes.length === 1) {\n\t\t\t\tconst onlyRoot = rootShapes[0] as TLFrameShape\n\t\t\t\t// If the old bounds are in the viewport...\n\t\t\t\tif (this.isShapeOfType(onlyRoot, 'frame')) {\n\t\t\t\t\twhile (\n\t\t\t\t\t\tthis.getShapesAtPoint(point).some(\n\t\t\t\t\t\t\t(shape) =>\n\t\t\t\t\t\t\t\tthis.isShapeOfType(shape, 'frame') &&\n\t\t\t\t\t\t\t\tshape.props.w === onlyRoot.props.w &&\n\t\t\t\t\t\t\t\tshape.props.h === onlyRoot.props.h\n\t\t\t\t\t\t)\n\t\t\t\t\t) {\n\t\t\t\t\t\tpoint.x += bounds.w + 16\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst pageCenter = Box.Common(\n\t\t\t\tcompact(rootShapes.map(({ id }) => this.getShapePageBounds(id)))\n\t\t\t).center\n\n\t\t\tconst offset = Vec.Sub(point, pageCenter)\n\n\t\t\tthis.updateShapes(\n\t\t\t\trootShapes.map(({ id }) => {\n\t\t\t\t\tconst s = this.getShape(id)!\n\t\t\t\t\tconst localRotation = this.getShapeParentTransform(id).decompose().rotation\n\t\t\t\t\tconst localDelta = Vec.Rot(offset, -localRotation)\n\n\t\t\t\t\treturn { id: s.id, type: s.type, x: s.x + localDelta.x, y: s.y + localDelta.y }\n\t\t\t\t})\n\t\t\t)\n\t\t})\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Get an exported SVG element of the given shapes.\n\t *\n\t * @param ids - The shapes (or shape ids) to export.\n\t * @param opts - Options for the export.\n\t *\n\t * @returns The SVG element.\n\t *\n\t * @public\n\t */\n\tasync getSvgElement(shapes: TLShapeId[] | TLShape[], opts: TLImageExportOptions = {}) {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\n\t\tif (ids.length === 0) return undefined\n\n\t\treturn exportToSvg(this, ids, opts)\n\t}\n\n\t/**\n\t * Get an exported SVG string of the given shapes.\n\t *\n\t * @param ids - The shapes (or shape ids) to export.\n\t * @param opts - Options for the export.\n\t *\n\t * @returns The SVG element.\n\t *\n\t * @public\n\t */\n\tasync getSvgString(shapes: TLShapeId[] | TLShape[], opts: TLImageExportOptions = {}) {\n\t\tconst result = await this.getSvgElement(shapes, opts)\n\t\tif (!result) return undefined\n\n\t\tconst serializer = new XMLSerializer()\n\t\treturn {\n\t\t\tsvg: serializer.serializeToString(result.svg),\n\t\t\twidth: result.width,\n\t\t\theight: result.height,\n\t\t}\n\t}\n\n\t/** @deprecated Use {@link Editor.getSvgString} or {@link Editor.getSvgElement} instead. */\n\tasync getSvg(shapes: TLShapeId[] | TLShape[], opts: TLImageExportOptions = {}) {\n\t\tconst result = await this.getSvgElement(shapes, opts)\n\t\tif (!result) return undefined\n\t\treturn result.svg\n\t}\n\n\t/* --------------------- Events --------------------- */\n\n\t/**\n\t * The app's current input state.\n\t *\n\t * @public\n\t */\n\tinputs = {\n\t\t/** The most recent pointer down's position in the current page space. */\n\t\toriginPagePoint: new Vec(),\n\t\t/** The most recent pointer down's position in screen space. */\n\t\toriginScreenPoint: new Vec(),\n\t\t/** The previous pointer position in the current page space. */\n\t\tpreviousPagePoint: new Vec(),\n\t\t/** The previous pointer position in screen space. */\n\t\tpreviousScreenPoint: new Vec(),\n\t\t/** The most recent pointer position in the current page space. */\n\t\tcurrentPagePoint: new Vec(),\n\t\t/** The most recent pointer position in screen space. */\n\t\tcurrentScreenPoint: new Vec(),\n\t\t/** A set containing the currently pressed keys. */\n\t\tkeys: new Set(),\n\t\t/** A set containing the currently pressed buttons. */\n\t\tbuttons: new Set(),\n\t\t/** Whether the input is from a pe. */\n\t\tisPen: false,\n\t\t/** Whether the shift key is currently pressed. */\n\t\tshiftKey: false,\n\t\t/** Whether the control or command key is currently pressed. */\n\t\tctrlKey: false,\n\t\t/** Whether the alt or option key is currently pressed. */\n\t\taltKey: false,\n\t\t/** Whether the user is dragging. */\n\t\tisDragging: false,\n\t\t/** Whether the user is pointing. */\n\t\tisPointing: false,\n\t\t/** Whether the user is pinching. */\n\t\tisPinching: false,\n\t\t/** Whether the user is editing. */\n\t\tisEditing: false,\n\t\t/** Whether the user is panning. */\n\t\tisPanning: false,\n\t\t/** Whether the user is spacebar panning. */\n\t\tisSpacebarPanning: false,\n\t\t/** Velocity of mouse pointer, in pixels per millisecond */\n\t\tpointerVelocity: new Vec(),\n\t}\n\n\t/**\n\t * Update the input points from a pointer, pinch, or wheel event.\n\t *\n\t * @param info - The event info.\n\t */\n\tprivate _updateInputsFromEvent(\n\t\tinfo: TLPointerEventInfo | TLPinchEventInfo | TLWheelEventInfo\n\t): void {\n\t\tconst {\n\t\t\tpointerVelocity,\n\t\t\tpreviousScreenPoint,\n\t\t\tpreviousPagePoint,\n\t\t\tcurrentScreenPoint,\n\t\t\tcurrentPagePoint,\n\t\t} = this.inputs\n\n\t\tconst { screenBounds } = this.store.unsafeGetWithoutCapture(TLINSTANCE_ID)!\n\t\tconst { x: cx, y: cy, z: cz } = unsafe__withoutCapture(() => this.getCamera())\n\n\t\tconst sx = info.point.x - screenBounds.x\n\t\tconst sy = info.point.y - screenBounds.y\n\t\tconst sz = info.point.z ?? 0.5\n\n\t\tpreviousScreenPoint.setTo(currentScreenPoint)\n\t\tpreviousPagePoint.setTo(currentPagePoint)\n\n\t\t// The \"screen bounds\" is relative to the user's actual screen.\n\t\t// The \"screen point\" is relative to the \"screen bounds\";\n\t\t// it will be 0,0 when its actual screen position is equal\n\t\t// to screenBounds.point. This is confusing!\n\t\tcurrentScreenPoint.set(sx, sy)\n\t\tconst nx = sx / cz - cx\n\t\tconst ny = sy / cz - cy\n\t\tif (isFinite(nx) && isFinite(ny)) {\n\t\t\tcurrentPagePoint.set(nx, ny, sz)\n\t\t}\n\n\t\tthis.inputs.isPen = info.type === 'pointer' && info.isPen\n\n\t\t// Reset velocity on pointer down, or when a pinch starts or ends\n\t\tif (info.name === 'pointer_down' || this.inputs.isPinching) {\n\t\t\tpointerVelocity.set(0, 0)\n\t\t\tthis.inputs.originScreenPoint.setTo(currentScreenPoint)\n\t\t\tthis.inputs.originPagePoint.setTo(currentPagePoint)\n\t\t}\n\n\t\t// todo: We only have to do this if there are multiple users in the document\n\t\tthis.run(\n\t\t\t() => {\n\t\t\t\tthis.store.put([\n\t\t\t\t\t{\n\t\t\t\t\t\tid: TLPOINTER_ID,\n\t\t\t\t\t\ttypeName: 'pointer',\n\t\t\t\t\t\tx: currentPagePoint.x,\n\t\t\t\t\t\ty: currentPagePoint.y,\n\t\t\t\t\t\tlastActivityTimestamp:\n\t\t\t\t\t\t\t// If our pointer moved only because we're following some other user, then don't\n\t\t\t\t\t\t\t// update our last activity timestamp; otherwise, update it to the current timestamp.\n\t\t\t\t\t\t\tinfo.type === 'pointer' && info.pointerId === INTERNAL_POINTER_IDS.CAMERA_MOVE\n\t\t\t\t\t\t\t\t? this.store.unsafeGetWithoutCapture(TLPOINTER_ID)?.lastActivityTimestamp ??\n\t\t\t\t\t\t\t\t\tthis._tickManager.now\n\t\t\t\t\t\t\t\t: this._tickManager.now,\n\t\t\t\t\t\tmeta: {},\n\t\t\t\t\t},\n\t\t\t\t])\n\t\t\t},\n\t\t\t{ history: 'ignore' }\n\t\t)\n\t}\n\n\t/**\n\t * Dispatch a cancel event.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.cancel()\n\t * ```\n\t *\n\t * @public\n\t */\n\tcancel(): this {\n\t\tthis.dispatch({ type: 'misc', name: 'cancel' })\n\t\treturn this\n\t}\n\n\t/**\n\t * Dispatch an interrupt event.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.interrupt()\n\t * ```\n\t *\n\t * @public\n\t */\n\tinterrupt(): this {\n\t\tthis.dispatch({ type: 'misc', name: 'interrupt' })\n\t\treturn this\n\t}\n\n\t/**\n\t * Dispatch a complete event.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.complete()\n\t * ```\n\t *\n\t * @public\n\t */\n\tcomplete(): this {\n\t\tthis.dispatch({ type: 'misc', name: 'complete' })\n\t\treturn this\n\t}\n\n\t/**\n\t * Puts the editor into focused mode.\n\t *\n\t * This makes the editor eligible to receive keyboard events and some pointer events (move, wheel).\n\t *\n\t * @example\n\t * ```ts\n\t * editor.focus()\n\t * ```\n\t *\n\t * By default this also dispatches a 'focus' event to the container element. To prevent this, pass `focusContainer: false`.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.focus({ focusContainer: false })\n\t * ```\n\t *\n\t * @public\n\t */\n\tfocus({ focusContainer = true } = {}): this {\n\t\tif (this.getIsFocused()) return this\n\t\tif (focusContainer) this.focusManager.focus()\n\t\tthis.updateInstanceState({ isFocused: true })\n\t\treturn this\n\t}\n\n\t/**\n\t * Switches off the editor's focused mode.\n\t *\n\t * This makes the editor ignore keyboard events and some pointer events (move, wheel).\n\t *\n\t * @example\n\t * ```ts\n\t * editor.blur()\n\t * ```\n\t * By default this also dispatches a 'blur' event to the container element. To prevent this, pass `blurContainer: false`.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.blur({ blurContainer: false })\n\t * ```\n\t *\n\t * @public\n\t */\n\tblur({ blurContainer = true } = {}): this {\n\t\tif (!this.getIsFocused()) return this\n\t\tif (blurContainer) {\n\t\t\tthis.focusManager.blur()\n\t\t} else {\n\t\t\tthis.complete() // stop any interaction\n\t\t}\n\t\tthis.updateInstanceState({ isFocused: false })\n\t\treturn this\n\t}\n\n\t/**\n\t * @public\n\t * @returns true if the editor is focused\n\t */\n\t@computed getIsFocused() {\n\t\treturn this.getInstanceState().isFocused\n\t}\n\n\t/**\n\t * @public\n\t * @returns a snapshot of the store's UI and document state\n\t */\n\tgetSnapshot() {\n\t\treturn getSnapshot(this.store)\n\t}\n\n\t/**\n\t * Loads a snapshot into the editor.\n\t * @param snapshot - the snapshot to load\n\t * @returns\n\t */\n\tloadSnapshot(\n\t\tsnapshot: Partial | TLStoreSnapshot,\n\t\topts?: TLLoadSnapshotOptions\n\t) {\n\t\tloadSnapshot(this.store, snapshot, opts)\n\t\treturn this\n\t}\n\n\tprivate _zoomToFitPageContentAt100Percent() {\n\t\tconst bounds = this.getCurrentPageBounds()\n\t\tif (bounds) {\n\t\t\tthis.zoomToBounds(bounds, { immediate: true, targetZoom: this.getBaseZoom() })\n\t\t}\n\t}\n\tprivate _navigateToDeepLink(deepLink: TLDeepLink) {\n\t\tthis.run(() => {\n\t\t\tswitch (deepLink.type) {\n\t\t\t\tcase 'page': {\n\t\t\t\t\tconst page = this.getPage(deepLink.pageId)\n\t\t\t\t\tif (page) {\n\t\t\t\t\t\tthis.setCurrentPage(page)\n\t\t\t\t\t}\n\t\t\t\t\tthis._zoomToFitPageContentAt100Percent()\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tcase 'shapes': {\n\t\t\t\t\tconst allShapes = compact(deepLink.shapeIds.map((id) => this.getShape(id)))\n\t\t\t\t\tconst byPage: { [pageId: string]: TLShape[] } = {}\n\t\t\t\t\tfor (const shape of allShapes) {\n\t\t\t\t\t\tconst pageId = this.getAncestorPageId(shape)\n\t\t\t\t\t\tif (!pageId) continue\n\t\t\t\t\t\tbyPage[pageId] ??= []\n\t\t\t\t\t\tbyPage[pageId].push(shape)\n\t\t\t\t\t}\n\t\t\t\t\tconst [pageId, shapes] = Object.entries(byPage).sort(\n\t\t\t\t\t\t([_, a], [__, b]) => b.length - a.length\n\t\t\t\t\t)[0] ?? ['', []]\n\n\t\t\t\t\tif (!pageId || !shapes.length) {\n\t\t\t\t\t\tthis._zoomToFitPageContentAt100Percent()\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthis.setCurrentPage(pageId as TLPageId)\n\t\t\t\t\t\tconst bounds = Box.Common(shapes.map((s) => this.getShapePageBounds(s)!))\n\t\t\t\t\t\tthis.zoomToBounds(bounds, { immediate: true, targetZoom: this.getBaseZoom() })\n\t\t\t\t\t}\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tcase 'viewport': {\n\t\t\t\t\tif (deepLink.pageId) {\n\t\t\t\t\t\tif (!this.getPage(deepLink.pageId)) {\n\t\t\t\t\t\t\tthis._zoomToFitPageContentAt100Percent()\n\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t}\n\t\t\t\t\t\tthis.setCurrentPage(deepLink.pageId)\n\t\t\t\t\t}\n\t\t\t\t\tthis.zoomToBounds(deepLink.bounds, { immediate: true, inset: 0 })\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tdefault:\n\t\t\t\t\texhaustiveSwitchError(deepLink)\n\t\t\t}\n\t\t})\n\t}\n\n\t/**\n\t * Handles navigating to the content specified by the query param in the given URL.\n\t *\n\t * Use {@link Editor#createDeepLink} to create a URL with a deep link query param.\n\t *\n\t * If no URL is provided, it will look for the param in the current `window.location.href`.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.navigateToDeepLink()\n\t * ```\n\t *\n\t * The default parameter name is 'd'. You can override this by providing the `param` option.\n\t *\n\t * @example\n\t * ```ts\n\t * // disable page parameter and change viewport parameter to 'c'\n\t * editor.navigateToDeepLink({\n\t * param: 'x',\n\t * url: 'https://my-app.com/my-document?x=200.12.454.23.xyz123',\n\t * })\n\t * ```\n\t *\n\t * @param opts - Options for loading the state from the URL.\n\t */\n\tnavigateToDeepLink(opts?: TLDeepLink | { url?: string | URL; param?: string }): Editor {\n\t\tif (opts && 'type' in opts) {\n\t\t\tthis._navigateToDeepLink(opts)\n\t\t\treturn this\n\t\t}\n\n\t\tconst url = new URL(opts?.url ?? window.location.href)\n\t\tconst deepLinkString = url.searchParams.get(opts?.param ?? 'd')\n\n\t\tif (!deepLinkString) {\n\t\t\tthis._zoomToFitPageContentAt100Percent()\n\t\t\treturn this\n\t\t}\n\n\t\ttry {\n\t\t\tthis._navigateToDeepLink(parseDeepLinkString(deepLinkString))\n\t\t} catch (e) {\n\t\t\tconsole.warn(e)\n\t\t\tthis._zoomToFitPageContentAt100Percent()\n\t\t}\n\t\treturn this\n\t}\n\n\t/**\n\t * Turns the given URL into a deep link by adding a query parameter.\n\t *\n\t * e.g. `https://my-app.com/my-document?d=100.100.200.200.xyz123`\n\t *\n\t * If no URL is provided, it will use the current `window.location.href`.\n\t *\n\t * @example\n\t * ```ts\n\t * // create a deep link to the current page + viewport\n\t * navigator.clipboard.writeText(editor.createDeepLink())\n\t * ```\n\t *\n\t * You can link to a particular set of shapes by providing a `to` parameter.\n\t *\n\t * @example\n\t * ```ts\n\t * // create a deep link to the set of currently selected shapes\n\t * navigator.clipboard.writeText(editor.createDeepLink({\n\t * to: { type: 'selection', shapeIds: editor.getSelectedShapeIds() }\n\t * }))\n\t * ```\n\t *\n\t * The default query param is 'd'. You can override this by providing a `param` parameter.\n\t *\n\t * @example\n\t * ```ts\n\t * // Use `x` as the param name instead\n\t * editor.createDeepLink({ param: 'x' })\n\t * ```\n\t *\n\t * @param opts - Options for adding the state to the URL.\n\t * @returns the updated URL\n\t */\n\tcreateDeepLink(opts?: { url?: string | URL; param?: string; to?: TLDeepLink }): URL {\n\t\tconst url = new URL(opts?.url ?? window.location.href)\n\n\t\turl.searchParams.set(\n\t\t\topts?.param ?? 'd',\n\t\t\tcreateDeepLinkString(\n\t\t\t\topts?.to ?? {\n\t\t\t\t\ttype: 'viewport',\n\t\t\t\t\tpageId: this.options.maxPages === 1 ? undefined : this.getCurrentPageId(),\n\t\t\t\t\tbounds: this.getViewportPageBounds(),\n\t\t\t\t}\n\t\t\t)\n\t\t)\n\n\t\treturn url\n\t}\n\n\t/**\n\t * Register a listener for changes to a deep link for the current document.\n\t *\n\t * You'll typically want to use this indirectly via the {@link TldrawEditorBaseProps.deepLinks} prop on the `` component.\n\t *\n\t * By default this will update `window.location` in place, but you can provide a custom callback\n\t * to handle state changes on your own.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.registerDeepLinkListener({\n\t * onChange(url) {\n\t * window.history.replaceState({}, document.title, url.toString())\n\t * }\n\t * })\n\t * ```\n\t *\n\t * You can also provide a custom URL to update, in which case you must also provide `onChange`.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.registerDeepLinkListener({\n\t * getUrl: () => `https://my-app.com/my-document`,\n\t * onChange(url) {\n\t * setShareUrl(url.toString())\n\t * }\n\t * })\n\t * ```\n\t *\n\t * By default this will update with a debounce interval of 500ms, but you can provide a custom interval.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.registerDeepLinkListener({ debounceMs: 1000 })\n\t * ```\n\t * The default parameter name is `d`. You can override this by providing a `param` option.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.registerDeepLinkListener({ param: 'x' })\n\t * ```\n\t * @param opts - Options for setting up the listener.\n\t * @returns a function that will stop the listener.\n\t */\n\tregisterDeepLinkListener(opts?: TLDeepLinkOptions): () => void {\n\t\tif (opts?.getUrl && !opts?.onChange) {\n\t\t\tthrow Error(\n\t\t\t\t'[tldraw:urlStateSync] If you specify getUrl, you must also specify the onChange callback.'\n\t\t\t)\n\t\t}\n\n\t\tconst url$ = computed('url with state', () => {\n\t\t\tconst url = opts?.getUrl?.(this) ?? window.location.href\n\t\t\tconst urlWithState = this.createDeepLink({\n\t\t\t\tparam: opts?.param,\n\t\t\t\turl,\n\t\t\t\tto: opts?.getTarget?.(this),\n\t\t\t})\n\t\t\treturn urlWithState.toString()\n\t\t})\n\n\t\tconst announceChange =\n\t\t\topts?.onChange ??\n\t\t\t(() => {\n\t\t\t\tconst url = this.createDeepLink({\n\t\t\t\t\tparam: opts?.param,\n\t\t\t\t\tto: opts?.getTarget?.(this),\n\t\t\t\t})\n\n\t\t\t\twindow.history.replaceState({}, document.title, url.toString())\n\t\t\t})\n\n\t\tconst scheduleEffect = debounce((execute: () => void) => execute(), opts?.debounceMs ?? 500)\n\n\t\tconst unlisten = react(\n\t\t\t'update url on state change',\n\t\t\t() => announceChange(new URL(url$.get()), this),\n\t\t\t{ scheduleEffect }\n\t\t)\n\n\t\treturn () => {\n\t\t\tunlisten()\n\t\t\tscheduleEffect.cancel()\n\t\t}\n\t}\n\n\t/**\n\t * A manager for recording multiple click events.\n\t *\n\t * @internal\n\t */\n\tprotected _clickManager = new ClickManager(this)\n\n\t/**\n\t * Prevent a double click event from firing the next time the user clicks\n\t *\n\t * @public\n\t */\n\tcancelDoubleClick() {\n\t\tthis._clickManager.cancelDoubleClickTimeout()\n\t}\n\n\t/**\n\t * The previous cursor. Used for restoring the cursor after pan events.\n\t *\n\t * @internal\n\t */\n\tprivate _prevCursor: TLCursorType = 'default'\n\n\t/** @internal */\n\tprivate _shiftKeyTimeout = -1 as any\n\n\t/** @internal */\n\t@bind\n\t_setShiftKeyTimeout() {\n\t\tthis.inputs.shiftKey = false\n\t\tthis.dispatch({\n\t\t\ttype: 'keyboard',\n\t\t\tname: 'key_up',\n\t\t\tkey: 'Shift',\n\t\t\tshiftKey: this.inputs.shiftKey,\n\t\t\tctrlKey: this.inputs.ctrlKey,\n\t\t\taltKey: this.inputs.altKey,\n\t\t\tcode: 'ShiftLeft',\n\t\t})\n\t}\n\n\t/** @internal */\n\tprivate _altKeyTimeout = -1 as any\n\n\t/** @internal */\n\t@bind\n\t_setAltKeyTimeout() {\n\t\tthis.inputs.altKey = false\n\t\tthis.dispatch({\n\t\t\ttype: 'keyboard',\n\t\t\tname: 'key_up',\n\t\t\tkey: 'Alt',\n\t\t\tshiftKey: this.inputs.shiftKey,\n\t\t\tctrlKey: this.inputs.ctrlKey,\n\t\t\taltKey: this.inputs.altKey,\n\t\t\tcode: 'AltLeft',\n\t\t})\n\t}\n\n\t/** @internal */\n\tprivate _ctrlKeyTimeout = -1 as any\n\n\t/** @internal */\n\t@bind\n\t_setCtrlKeyTimeout() {\n\t\tthis.inputs.ctrlKey = false\n\t\tthis.dispatch({\n\t\t\ttype: 'keyboard',\n\t\t\tname: 'key_up',\n\t\t\tkey: 'Ctrl',\n\t\t\tshiftKey: this.inputs.shiftKey,\n\t\t\tctrlKey: this.inputs.ctrlKey,\n\t\t\taltKey: this.inputs.altKey,\n\t\t\tcode: 'ControlLeft',\n\t\t})\n\t}\n\n\t/** @internal */\n\tprivate _restoreToolId = 'select'\n\n\t/** @internal */\n\tprivate _pinchStart = 1\n\n\t/** @internal */\n\tprivate _didPinch = false\n\n\t/** @internal */\n\tprivate _selectedShapeIdsAtPointerDown: TLShapeId[] = []\n\n\t/** @internal */\n\tprivate _longPressTimeout = -1 as any\n\n\t/** @internal */\n\tcapturedPointerId: number | null = null\n\n\t/** @internal */\n\tprivate readonly performanceTracker: PerformanceTracker\n\n\t/** @internal */\n\tprivate performanceTrackerTimeout = -1 as any\n\n\t/**\n\t * Dispatch an event to the editor.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.dispatch(myPointerEvent)\n\t * ```\n\t *\n\t * @param info - The event info.\n\t *\n\t * @public\n\t */\n\tdispatch(info: TLEventInfo) {\n\t\tthis._pendingEventsForNextTick.push(info)\n\t\tif (\n\t\t\t!(\n\t\t\t\t(info.type === 'pointer' && info.name === 'pointer_move') ||\n\t\t\t\tinfo.type === 'wheel' ||\n\t\t\t\tinfo.type === 'pinch'\n\t\t\t)\n\t\t) {\n\t\t\tthis._flushEventsForTick(0)\n\t\t}\n\t\treturn this\n\t}\n\n\tprivate _pendingEventsForNextTick: TLEventInfo[] = []\n\n\tprivate _flushEventsForTick(elapsed: number) {\n\t\tthis.run(() => {\n\t\t\tif (this._pendingEventsForNextTick.length > 0) {\n\t\t\t\tconst events = [...this._pendingEventsForNextTick]\n\t\t\t\tthis._pendingEventsForNextTick.length = 0\n\t\t\t\tfor (const info of events) {\n\t\t\t\t\tthis._flushEventForTick(info)\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (elapsed > 0) {\n\t\t\t\tthis.root.handleEvent({ type: 'misc', name: 'tick', elapsed })\n\t\t\t}\n\t\t\tthis.scribbles.tick(elapsed)\n\t\t})\n\t}\n\n\t_flushEventForTick(info: TLEventInfo) {\n\t\t// prevent us from spamming similar event errors if we're crashed.\n\t\t// todo: replace with new readonly mode?\n\t\tif (this.getCrashingError()) return this\n\n\t\tconst { inputs } = this\n\t\tconst { type } = info\n\n\t\tif (info.type === 'misc') {\n\t\t\t// stop panning if the interaction is cancelled or completed\n\t\t\tif (info.name === 'cancel' || info.name === 'complete') {\n\t\t\t\tthis.inputs.isDragging = false\n\n\t\t\t\tif (this.inputs.isPanning) {\n\t\t\t\t\tthis.inputs.isPanning = false\n\t\t\t\t\tthis.inputs.isSpacebarPanning = false\n\t\t\t\t\tthis.setCursor({ type: this._prevCursor, rotation: 0 })\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tthis.root.handleEvent(info)\n\t\t\treturn\n\t\t}\n\n\t\tif (info.shiftKey) {\n\t\t\tclearTimeout(this._shiftKeyTimeout)\n\t\t\tthis._shiftKeyTimeout = -1\n\t\t\tinputs.shiftKey = true\n\t\t} else if (!info.shiftKey && inputs.shiftKey && this._shiftKeyTimeout === -1) {\n\t\t\tthis._shiftKeyTimeout = this.timers.setTimeout(this._setShiftKeyTimeout, 150)\n\t\t}\n\n\t\tif (info.altKey) {\n\t\t\tclearTimeout(this._altKeyTimeout)\n\t\t\tthis._altKeyTimeout = -1\n\t\t\tinputs.altKey = true\n\t\t} else if (!info.altKey && inputs.altKey && this._altKeyTimeout === -1) {\n\t\t\tthis._altKeyTimeout = this.timers.setTimeout(this._setAltKeyTimeout, 150)\n\t\t}\n\n\t\tif (info.ctrlKey) {\n\t\t\tclearTimeout(this._ctrlKeyTimeout)\n\t\t\tthis._ctrlKeyTimeout = -1\n\t\t\tinputs.ctrlKey = true\n\t\t} else if (!info.ctrlKey && inputs.ctrlKey && this._ctrlKeyTimeout === -1) {\n\t\t\tthis._ctrlKeyTimeout = this.timers.setTimeout(this._setCtrlKeyTimeout, 150)\n\t\t}\n\n\t\tconst { originPagePoint, currentPagePoint } = inputs\n\n\t\tif (!inputs.isPointing) {\n\t\t\tinputs.isDragging = false\n\t\t}\n\n\t\tconst instanceState = this.store.unsafeGetWithoutCapture(TLINSTANCE_ID)!\n\t\tconst pageState = this.store.get(this._getCurrentPageStateId())!\n\t\tconst cameraOptions = this._cameraOptions.__unsafe__getWithoutCapture()!\n\n\t\tswitch (type) {\n\t\t\tcase 'pinch': {\n\t\t\t\tif (cameraOptions.isLocked) return\n\t\t\t\tclearTimeout(this._longPressTimeout)\n\t\t\t\tthis._updateInputsFromEvent(info)\n\n\t\t\t\tswitch (info.name) {\n\t\t\t\t\tcase 'pinch_start': {\n\t\t\t\t\t\tif (inputs.isPinching) return\n\n\t\t\t\t\t\tif (!inputs.isEditing) {\n\t\t\t\t\t\t\tthis._pinchStart = this.getCamera().z\n\t\t\t\t\t\t\tif (!this._selectedShapeIdsAtPointerDown.length) {\n\t\t\t\t\t\t\t\tthis._selectedShapeIdsAtPointerDown = [...pageState.selectedShapeIds]\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tthis._didPinch = true\n\n\t\t\t\t\t\t\tinputs.isPinching = true\n\n\t\t\t\t\t\t\tthis.interrupt()\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\treturn // Stop here!\n\t\t\t\t\t}\n\t\t\t\t\tcase 'pinch': {\n\t\t\t\t\t\tif (!inputs.isPinching) return\n\n\t\t\t\t\t\tconst {\n\t\t\t\t\t\t\tpoint: { z = 1 },\n\t\t\t\t\t\t\tdelta: { x: dx, y: dy },\n\t\t\t\t\t\t} = info\n\n\t\t\t\t\t\t// The center of the pinch in screen space\n\t\t\t\t\t\tconst { x, y } = Vec.SubXY(\n\t\t\t\t\t\t\tinfo.point,\n\t\t\t\t\t\t\tinstanceState.screenBounds.x,\n\t\t\t\t\t\t\tinstanceState.screenBounds.y\n\t\t\t\t\t\t)\n\n\t\t\t\t\t\tthis.stopCameraAnimation()\n\t\t\t\t\t\tif (instanceState.followingUserId) {\n\t\t\t\t\t\t\tthis.stopFollowingUser()\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst { x: cx, y: cy, z: cz } = unsafe__withoutCapture(() => this.getCamera())\n\n\t\t\t\t\t\tconst { panSpeed, zoomSpeed } = cameraOptions\n\t\t\t\t\t\tthis._setCamera(\n\t\t\t\t\t\t\tnew Vec(\n\t\t\t\t\t\t\t\tcx + (dx * panSpeed) / cz - x / cz + x / (z * zoomSpeed),\n\t\t\t\t\t\t\t\tcy + (dy * panSpeed) / cz - y / cz + y / (z * zoomSpeed),\n\t\t\t\t\t\t\t\tz * zoomSpeed\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t{ immediate: true }\n\t\t\t\t\t\t)\n\n\t\t\t\t\t\treturn // Stop here!\n\t\t\t\t\t}\n\t\t\t\t\tcase 'pinch_end': {\n\t\t\t\t\t\tif (!inputs.isPinching) return this\n\n\t\t\t\t\t\t// Stop pinching\n\t\t\t\t\t\tinputs.isPinching = false\n\n\t\t\t\t\t\t// Stash and clear the shapes that were selected when the pinch started\n\t\t\t\t\t\tconst { _selectedShapeIdsAtPointerDown: shapesToReselect } = this\n\t\t\t\t\t\tthis.setSelectedShapes(this._selectedShapeIdsAtPointerDown)\n\t\t\t\t\t\tthis._selectedShapeIdsAtPointerDown = []\n\n\t\t\t\t\t\tif (this._didPinch) {\n\t\t\t\t\t\t\tthis._didPinch = false\n\t\t\t\t\t\t\tif (shapesToReselect.length > 0) {\n\t\t\t\t\t\t\t\tthis.once('tick', () => {\n\t\t\t\t\t\t\t\t\tif (!this._didPinch) {\n\t\t\t\t\t\t\t\t\t\t// Unless we've started pinching again...\n\t\t\t\t\t\t\t\t\t\t// Reselect the shapes that were selected when the pinch started\n\t\t\t\t\t\t\t\t\t\tthis.setSelectedShapes(shapesToReselect)\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\treturn // Stop here!\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tcase 'wheel': {\n\t\t\t\tif (cameraOptions.isLocked) return\n\n\t\t\t\tthis._updateInputsFromEvent(info)\n\n\t\t\t\tif (this.getIsMenuOpen()) {\n\t\t\t\t\t// noop\n\t\t\t\t} else {\n\t\t\t\t\tconst { panSpeed, zoomSpeed, wheelBehavior } = cameraOptions\n\n\t\t\t\t\tif (wheelBehavior !== 'none') {\n\t\t\t\t\t\t// Stop any camera animation\n\t\t\t\t\t\tthis.stopCameraAnimation()\n\t\t\t\t\t\t// Stop following any following user\n\t\t\t\t\t\tif (instanceState.followingUserId) {\n\t\t\t\t\t\t\tthis.stopFollowingUser()\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst { x: cx, y: cy, z: cz } = unsafe__withoutCapture(() => this.getCamera())\n\t\t\t\t\t\tconst { x: dx, y: dy, z: dz = 0 } = info.delta\n\n\t\t\t\t\t\tlet behavior = wheelBehavior\n\n\t\t\t\t\t\t// If the camera behavior is \"zoom\" and the ctrl key is pressed, then pan;\n\t\t\t\t\t\t// If the camera behavior is \"pan\" and the ctrl key is not pressed, then zoom\n\t\t\t\t\t\tif (inputs.ctrlKey) behavior = wheelBehavior === 'pan' ? 'zoom' : 'pan'\n\n\t\t\t\t\t\tswitch (behavior) {\n\t\t\t\t\t\t\tcase 'zoom': {\n\t\t\t\t\t\t\t\t// Zoom in on current screen point using the wheel delta\n\t\t\t\t\t\t\t\tconst { x, y } = this.inputs.currentScreenPoint\n\t\t\t\t\t\t\t\tlet delta = dz\n\n\t\t\t\t\t\t\t\t// If we're forcing zoom, then we need to do the wheel normalization math here\n\t\t\t\t\t\t\t\tif (wheelBehavior === 'zoom') {\n\t\t\t\t\t\t\t\t\tif (Math.abs(dy) > 10) {\n\t\t\t\t\t\t\t\t\t\tdelta = (10 * Math.sign(dy)) / 100\n\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\tdelta = dy / 100\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tconst zoom = cz + (delta ?? 0) * zoomSpeed * cz\n\t\t\t\t\t\t\t\tthis._setCamera(\n\t\t\t\t\t\t\t\t\tnew Vec(\n\t\t\t\t\t\t\t\t\t\tcx + (x / zoom - x) - (x / cz - x),\n\t\t\t\t\t\t\t\t\t\tcy + (y / zoom - y) - (y / cz - y),\n\t\t\t\t\t\t\t\t\t\tzoom\n\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t{ immediate: true }\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\tthis.maybeTrackPerformance('Zooming')\n\t\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tcase 'pan': {\n\t\t\t\t\t\t\t\t// Pan the camera based on the wheel delta\n\t\t\t\t\t\t\t\tthis._setCamera(new Vec(cx + (dx * panSpeed) / cz, cy + (dy * panSpeed) / cz, cz), {\n\t\t\t\t\t\t\t\t\timmediate: true,\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\tthis.maybeTrackPerformance('Panning')\n\t\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'pointer': {\n\t\t\t\t// Ignore pointer events while we're pinching\n\t\t\t\tif (inputs.isPinching) return\n\n\t\t\t\tthis._updateInputsFromEvent(info)\n\t\t\t\tconst { isPen } = info\n\t\t\t\tconst { isPenMode } = instanceState\n\n\t\t\t\tswitch (info.name) {\n\t\t\t\t\tcase 'pointer_down': {\n\t\t\t\t\t\t// If we're in pen mode and the input is not a pen type, then stop here\n\t\t\t\t\t\tif (isPenMode && !isPen) return\n\n\t\t\t\t\t\tif (!this.inputs.isPanning) {\n\t\t\t\t\t\t\t// Start a long press timeout\n\t\t\t\t\t\t\tthis._longPressTimeout = this.timers.setTimeout(() => {\n\t\t\t\t\t\t\t\tthis.dispatch({\n\t\t\t\t\t\t\t\t\t...info,\n\t\t\t\t\t\t\t\t\tpoint: this.inputs.currentScreenPoint,\n\t\t\t\t\t\t\t\t\tname: 'long_press',\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t}, this.options.longPressDurationMs)\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Save the selected ids at pointer down\n\t\t\t\t\t\tthis._selectedShapeIdsAtPointerDown = this.getSelectedShapeIds()\n\n\t\t\t\t\t\t// Firefox bug fix...\n\t\t\t\t\t\t// If it's a left-mouse-click, we store the pointer id for later user\n\t\t\t\t\t\tif (info.button === LEFT_MOUSE_BUTTON) this.capturedPointerId = info.pointerId\n\n\t\t\t\t\t\t// Add the button from the buttons set\n\t\t\t\t\t\tinputs.buttons.add(info.button)\n\n\t\t\t\t\t\t// Start pointing and stop dragging\n\t\t\t\t\t\tinputs.isPointing = true\n\t\t\t\t\t\tinputs.isDragging = false\n\n\t\t\t\t\t\t// If pen mode is off but we're not already in pen mode, turn that on\n\t\t\t\t\t\tif (!isPenMode && isPen) this.updateInstanceState({ isPenMode: true })\n\n\t\t\t\t\t\t// On devices with erasers (like the Surface Pen or Wacom Pen), button 5 is the eraser\n\t\t\t\t\t\tif (info.button === STYLUS_ERASER_BUTTON) {\n\t\t\t\t\t\t\tthis._restoreToolId = this.getCurrentToolId()\n\t\t\t\t\t\t\tthis.complete()\n\t\t\t\t\t\t\tthis.setCurrentTool('eraser')\n\t\t\t\t\t\t} else if (info.button === MIDDLE_MOUSE_BUTTON) {\n\t\t\t\t\t\t\t// Middle mouse pan activates panning unless we're already panning (with spacebar)\n\t\t\t\t\t\t\tif (!this.inputs.isPanning) {\n\t\t\t\t\t\t\t\tthis._prevCursor = this.getInstanceState().cursor.type\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tthis.inputs.isPanning = true\n\t\t\t\t\t\t\tclearTimeout(this._longPressTimeout)\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// We might be panning because we did a middle mouse click, or because we're holding spacebar and started a regular click\n\t\t\t\t\t\t// Also stop here, we don't want the state chart to receive the event\n\t\t\t\t\t\tif (this.inputs.isPanning) {\n\t\t\t\t\t\t\tthis.stopCameraAnimation()\n\t\t\t\t\t\t\tthis.setCursor({ type: 'grabbing', rotation: 0 })\n\t\t\t\t\t\t\treturn this\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t\tcase 'pointer_move': {\n\t\t\t\t\t\t// If the user is in pen mode, but the pointer is not a pen, stop here.\n\t\t\t\t\t\tif (!isPen && isPenMode) return\n\n\t\t\t\t\t\tconst { x: cx, y: cy, z: cz } = unsafe__withoutCapture(() => this.getCamera())\n\n\t\t\t\t\t\t// If we've started panning, then clear any long press timeout\n\t\t\t\t\t\tif (this.inputs.isPanning && this.inputs.isPointing) {\n\t\t\t\t\t\t\t// Handle spacebar / middle mouse button panning\n\t\t\t\t\t\t\tconst { currentScreenPoint, previousScreenPoint } = this.inputs\n\t\t\t\t\t\t\tconst { panSpeed } = cameraOptions\n\t\t\t\t\t\t\tconst offset = Vec.Sub(currentScreenPoint, previousScreenPoint)\n\t\t\t\t\t\t\tthis.setCamera(\n\t\t\t\t\t\t\t\tnew Vec(cx + (offset.x * panSpeed) / cz, cy + (offset.y * panSpeed) / cz, cz),\n\t\t\t\t\t\t\t\t{ immediate: true }\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\tthis.maybeTrackPerformance('Panning')\n\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\tinputs.isPointing &&\n\t\t\t\t\t\t\t!inputs.isDragging &&\n\t\t\t\t\t\t\tVec.Dist2(originPagePoint, currentPagePoint) * this.getZoomLevel() >\n\t\t\t\t\t\t\t\t(instanceState.isCoarsePointer\n\t\t\t\t\t\t\t\t\t? this.options.coarseDragDistanceSquared\n\t\t\t\t\t\t\t\t\t: this.options.dragDistanceSquared) /\n\t\t\t\t\t\t\t\t\tcz\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t// Start dragging\n\t\t\t\t\t\t\tinputs.isDragging = true\n\t\t\t\t\t\t\tclearTimeout(this._longPressTimeout)\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t\tcase 'pointer_up': {\n\t\t\t\t\t\t// Stop dragging / pointing\n\t\t\t\t\t\tinputs.isDragging = false\n\t\t\t\t\t\tinputs.isPointing = false\n\t\t\t\t\t\tclearTimeout(this._longPressTimeout)\n\n\t\t\t\t\t\t// Remove the button from the buttons set\n\t\t\t\t\t\tinputs.buttons.delete(info.button)\n\n\t\t\t\t\t\t// Suppressing pointerup here as doesn't seem to do what we what here.\n\t\t\t\t\t\tif (this.getIsMenuOpen()) return\n\n\t\t\t\t\t\t// If we're in pen mode and we're not using a pen, stop here\n\t\t\t\t\t\tif (instanceState.isPenMode && !isPen) return\n\n\t\t\t\t\t\t// Firefox bug fix...\n\t\t\t\t\t\t// If it's the same pointer that we stored earlier...\n\t\t\t\t\t\t// ... then it's probably still a left-mouse-click!\n\t\t\t\t\t\tif (this.capturedPointerId === info.pointerId) {\n\t\t\t\t\t\t\tthis.capturedPointerId = null\n\t\t\t\t\t\t\tinfo.button = 0\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (inputs.isPanning) {\n\t\t\t\t\t\t\tif (!inputs.keys.has('Space')) {\n\t\t\t\t\t\t\t\tinputs.isPanning = false\n\t\t\t\t\t\t\t\tinputs.isSpacebarPanning = false\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tconst slideDirection = this.inputs.pointerVelocity\n\t\t\t\t\t\t\tconst slideSpeed = Math.min(2, slideDirection.len())\n\n\t\t\t\t\t\t\tswitch (info.button) {\n\t\t\t\t\t\t\t\tcase LEFT_MOUSE_BUTTON: {\n\t\t\t\t\t\t\t\t\tthis.setCursor({ type: 'grab', rotation: 0 })\n\t\t\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tcase MIDDLE_MOUSE_BUTTON: {\n\t\t\t\t\t\t\t\t\tif (this.inputs.keys.has(' ')) {\n\t\t\t\t\t\t\t\t\t\tthis.setCursor({ type: 'grab', rotation: 0 })\n\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\tthis.setCursor({ type: this._prevCursor, rotation: 0 })\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif (slideSpeed > 0) {\n\t\t\t\t\t\t\t\tthis.slideCamera({ speed: slideSpeed, direction: slideDirection })\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tif (info.button === STYLUS_ERASER_BUTTON) {\n\t\t\t\t\t\t\t\t// If we were erasing with a stylus button, restore the tool we were using before we started erasing\n\t\t\t\t\t\t\t\tthis.complete()\n\t\t\t\t\t\t\t\tthis.setCurrentTool(this._restoreToolId)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'keyboard': {\n\t\t\t\t// please, please\n\t\t\t\tif (info.key === 'ShiftRight') info.key = 'ShiftLeft'\n\t\t\t\tif (info.key === 'AltRight') info.key = 'AltLeft'\n\t\t\t\tif (info.code === 'ControlRight') info.code = 'ControlLeft'\n\n\t\t\t\tswitch (info.name) {\n\t\t\t\t\tcase 'key_down': {\n\t\t\t\t\t\t// Add the key from the keys set\n\t\t\t\t\t\tinputs.keys.add(info.code)\n\n\t\t\t\t\t\t// If the space key is pressed (but meta / control isn't!) activate panning\n\t\t\t\t\t\tif (info.code === 'Space' && !info.ctrlKey) {\n\t\t\t\t\t\t\tif (!this.inputs.isPanning) {\n\t\t\t\t\t\t\t\tthis._prevCursor = instanceState.cursor.type\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tthis.inputs.isPanning = true\n\t\t\t\t\t\t\tthis.inputs.isSpacebarPanning = true\n\t\t\t\t\t\t\tclearTimeout(this._longPressTimeout)\n\t\t\t\t\t\t\tthis.setCursor({ type: this.inputs.isPointing ? 'grabbing' : 'grab', rotation: 0 })\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (this.inputs.isSpacebarPanning) {\n\t\t\t\t\t\t\tlet offset: Vec | undefined\n\t\t\t\t\t\t\tswitch (info.code) {\n\t\t\t\t\t\t\t\tcase 'ArrowUp': {\n\t\t\t\t\t\t\t\t\toffset = new Vec(0, -1)\n\t\t\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tcase 'ArrowRight': {\n\t\t\t\t\t\t\t\t\toffset = new Vec(1, 0)\n\t\t\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tcase 'ArrowDown': {\n\t\t\t\t\t\t\t\t\toffset = new Vec(0, 1)\n\t\t\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tcase 'ArrowLeft': {\n\t\t\t\t\t\t\t\t\toffset = new Vec(-1, 0)\n\t\t\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif (offset) {\n\t\t\t\t\t\t\t\tconst bounds = this.getViewportPageBounds()\n\t\t\t\t\t\t\t\tconst next = bounds.clone().translate(offset.mulV({ x: bounds.w, y: bounds.h }))\n\t\t\t\t\t\t\t\tthis._animateToViewport(next, { animation: { duration: 320 } })\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t\tcase 'key_up': {\n\t\t\t\t\t\t// Remove the key from the keys set\n\t\t\t\t\t\tinputs.keys.delete(info.code)\n\n\t\t\t\t\t\t// If we've lifted the space key,\n\t\t\t\t\t\tif (info.code === 'Space') {\n\t\t\t\t\t\t\tif (this.inputs.buttons.has(MIDDLE_MOUSE_BUTTON)) {\n\t\t\t\t\t\t\t\t// If we're still middle dragging, continue panning\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t// otherwise, stop panning\n\t\t\t\t\t\t\t\tthis.inputs.isPanning = false\n\t\t\t\t\t\t\t\tthis.inputs.isSpacebarPanning = false\n\t\t\t\t\t\t\t\tthis.setCursor({ type: this._prevCursor, rotation: 0 })\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t\tcase 'key_repeat': {\n\t\t\t\t\t\t// noop\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\n\t\t// Correct the info name for right / middle clicks\n\t\tif (info.type === 'pointer') {\n\t\t\tif (info.button === MIDDLE_MOUSE_BUTTON) {\n\t\t\t\tinfo.name = 'middle_click'\n\t\t\t} else if (info.button === RIGHT_MOUSE_BUTTON) {\n\t\t\t\tinfo.name = 'right_click'\n\t\t\t}\n\n\t\t\t// If a left click pointer event, send the event to the click manager.\n\t\t\tconst { isPenMode } = this.store.unsafeGetWithoutCapture(TLINSTANCE_ID)!\n\t\t\tif (info.isPen === isPenMode) {\n\t\t\t\t// The click manager may return a new event, i.e. a double click event\n\t\t\t\t// depending on the event coming in and its own state. If the event has\n\t\t\t\t// changed then hand both events to the statechart\n\t\t\t\tconst clickInfo = this._clickManager.handlePointerEvent(info)\n\t\t\t\tif (info.name !== clickInfo.name) {\n\t\t\t\t\tthis.root.handleEvent(info)\n\t\t\t\t\tthis.emit('event', info)\n\t\t\t\t\tthis.root.handleEvent(clickInfo)\n\t\t\t\t\tthis.emit('event', clickInfo)\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Send the event to the statechart. It will be handled by all\n\t\t// active states, starting at the root.\n\t\tthis.root.handleEvent(info)\n\t\tthis.emit('event', info)\n\n\t\t// close open menus at the very end on pointer down! after everything else! \u03C3\u03C5\u03BD\u03C4\u03B5\u03BB\u03B5\u03AF\u03B1\u03C2 \u03C4\u03BF\u1FE6 \u03BA\u03CE\u03B4\u03B9\u03BA\u03B1!!\n\t\tif (info.type === 'pointer' && info.name === 'pointer_down') {\n\t\t\tthis.clearOpenMenus()\n\t\t}\n\n\t\treturn this\n\t}\n\n\t/** @internal */\n\tprivate maybeTrackPerformance(name: string) {\n\t\tif (debugFlags.measurePerformance.get()) {\n\t\t\tif (this.performanceTracker.isStarted()) {\n\t\t\t\tclearTimeout(this.performanceTrackerTimeout)\n\t\t\t} else {\n\t\t\t\tthis.performanceTracker.start(name)\n\t\t\t}\n\t\t\tthis.performanceTrackerTimeout = this.timers.setTimeout(() => {\n\t\t\t\tthis.performanceTracker.stop()\n\t\t\t}, 50)\n\t\t}\n\t}\n}\n\nfunction alertMaxShapes(editor: Editor, pageId = editor.getCurrentPageId()) {\n\tconst name = editor.getPage(pageId)!.name\n\teditor.emit('max-shapes', { name, pageId, count: editor.options.maxShapesPerPage })\n}\n\nfunction applyPartialToRecordWithProps<\n\tT extends UnknownRecord & { type: string; props: object; meta: object },\n>(prev: T, partial?: Partial & { props?: Partial }): T {\n\tif (!partial) return prev\n\tlet next = null as null | T\n\tconst entries = Object.entries(partial)\n\tfor (let i = 0, n = entries.length; i < n; i++) {\n\t\tconst [k, v] = entries[i]\n\t\tif (v === undefined) continue\n\n\t\t// Is the key a special key? We don't update those\n\t\tif (k === 'id' || k === 'type' || k === 'typeName') continue\n\n\t\t// Is the value the same as it was before?\n\t\tif (v === (prev as any)[k]) continue\n\n\t\t// There's a new value, so create the new shape if we haven't already (should we be cloning this?)\n\t\tif (!next) next = { ...prev }\n\n\t\t// for props / meta properties, we support updates with partials of this object\n\t\tif (k === 'props' || k === 'meta') {\n\t\t\tnext[k] = { ...prev[k] } as JsonObject\n\t\t\tfor (const [nextKey, nextValue] of Object.entries(v as object)) {\n\t\t\t\tif (nextValue !== undefined) {\n\t\t\t\t\t;(next[k] as JsonObject)[nextKey] = nextValue\n\t\t\t\t}\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\n\t\t// base property\n\t\t;(next as any)[k] = v\n\t}\n\tif (!next) return prev\n\treturn next\n}\n\nfunction pushShapeWithDescendants(editor: Editor, id: TLShapeId, result: TLShape[]): void {\n\tconst shape = editor.getShape(id)\n\tif (!shape) return\n\tresult.push(shape)\n\tconst childIds = editor.getSortedChildIdsForParent(id)\n\tfor (let i = 0, n = childIds.length; i < n; i++) {\n\t\tpushShapeWithDescendants(editor, childIds[i], result)\n\t}\n}\n\n/**\n * Run `callback` in a world where all bindings from the shapes in `shapeIds` to shapes not in\n * `shapeIds` are removed. This is useful when you want to duplicate/copy shapes without worrying\n * about bindings that might be pointing to shapes that are not being duplicated.\n *\n * The callback is given the set of bindings that should be maintained.\n */\nfunction withIsolatedShapes(\n\teditor: Editor,\n\tshapeIds: Set,\n\tcallback: (bindingsWithBoth: Set) => T\n): T {\n\tlet result!: Result\n\n\teditor.run(\n\t\t() => {\n\t\t\tconst changes = editor.store.extractingChanges(() => {\n\t\t\t\tconst bindingsWithBoth = new Set()\n\t\t\t\tconst bindingsToRemove = new Set()\n\n\t\t\t\tfor (const shapeId of shapeIds) {\n\t\t\t\t\tconst shape = editor.getShape(shapeId)\n\t\t\t\t\tif (!shape) continue\n\n\t\t\t\t\tfor (const binding of editor.getBindingsInvolvingShape(shapeId)) {\n\t\t\t\t\t\tconst hasFrom = shapeIds.has(binding.fromId)\n\t\t\t\t\t\tconst hasTo = shapeIds.has(binding.toId)\n\t\t\t\t\t\tif (hasFrom && hasTo) {\n\t\t\t\t\t\t\tbindingsWithBoth.add(binding.id)\n\t\t\t\t\t\t\tcontinue\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (!hasFrom || !hasTo) {\n\t\t\t\t\t\t\tbindingsToRemove.add(binding.id)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\teditor.deleteBindings([...bindingsToRemove], { isolateShapes: true })\n\n\t\t\t\ttry {\n\t\t\t\t\tresult = Result.ok(callback(bindingsWithBoth))\n\t\t\t\t} catch (error) {\n\t\t\t\t\tresult = Result.err(error)\n\t\t\t\t}\n\t\t\t})\n\n\t\t\teditor.store.applyDiff(reverseRecordsDiff(changes))\n\t\t},\n\t\t{ history: 'ignore' }\n\t)\n\n\tif (result.ok) {\n\t\treturn result.value\n\t} else {\n\t\tthrow result.error\n\t}\n}\n\nfunction getCameraFitXFitY(editor: Editor, cameraOptions: TLCameraOptions) {\n\tif (!cameraOptions.constraints) throw Error('Should have constraints here')\n\tconst {\n\t\tpadding: { x: px, y: py },\n\t} = cameraOptions.constraints\n\tconst vsb = editor.getViewportScreenBounds()\n\tconst bounds = Box.From(cameraOptions.constraints.bounds)\n\tconst zx = (vsb.w - px * 2) / bounds.w\n\tconst zy = (vsb.h - py * 2) / bounds.h\n\treturn { zx, zy }\n}\n"], -+ "mappings": "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", - "names": ["shape", "highlightedUserIds", "page", "notVisibleShapes", "distance", "ancestor", "bindingsToCreate", "shapesToCreateWithOriginals", "gap", "last", "i", "animatingShapes", "n", "group", "shapes", "bindings", "pageId"] - } -diff --git a/node_modules/@tldraw/editor/dist-esm/lib/hooks/useDocumentEvents.mjs b/node_modules/@tldraw/editor/dist-esm/lib/hooks/useDocumentEvents.mjs -index 04a1686..1124dcd 100644 ---- a/node_modules/@tldraw/editor/dist-esm/lib/hooks/useDocumentEvents.mjs -+++ b/node_modules/@tldraw/editor/dist-esm/lib/hooks/useDocumentEvents.mjs -@@ -138,17 +138,17 @@ function useDocumentEvents() { - }; - container.addEventListener("touchstart", handleTouchStart, { passive: false }); - container.addEventListener("wheel", handleWheel, { passive: false }); -- document.addEventListener("gesturestart", preventDefault); -- document.addEventListener("gesturechange", preventDefault); -- document.addEventListener("gestureend", preventDefault); -+ container.ownerDocument.addEventListener("gesturestart", preventDefault); -+ container.ownerDocument.addEventListener("gesturechange", preventDefault); -+ container.ownerDocument.addEventListener("gestureend", preventDefault); - container.addEventListener("keydown", handleKeyDown); - container.addEventListener("keyup", handleKeyUp); - return () => { - container.removeEventListener("touchstart", handleTouchStart); - container.removeEventListener("wheel", handleWheel); -- document.removeEventListener("gesturestart", preventDefault); -- document.removeEventListener("gesturechange", preventDefault); -- document.removeEventListener("gestureend", preventDefault); -+ container.ownerDocument.removeEventListener("gesturestart", preventDefault); -+ container.ownerDocument.removeEventListener("gesturechange", preventDefault); -+ container.ownerDocument.removeEventListener("gestureend", preventDefault); - container.removeEventListener("keydown", handleKeyDown); - container.removeEventListener("keyup", handleKeyUp); - }; -diff --git a/node_modules/@tldraw/editor/dist-esm/lib/hooks/useDocumentEvents.mjs.map b/node_modules/@tldraw/editor/dist-esm/lib/hooks/useDocumentEvents.mjs.map -index 8cb8d31..58d3dbf 100644 ---- a/node_modules/@tldraw/editor/dist-esm/lib/hooks/useDocumentEvents.mjs.map -+++ b/node_modules/@tldraw/editor/dist-esm/lib/hooks/useDocumentEvents.mjs.map -@@ -1,7 +1,7 @@ - { - "version": 3, - "sources": ["../../../src/lib/hooks/useDocumentEvents.ts"], -- "sourcesContent": ["import { useValue } from '@tldraw/state-react'\nimport { useEffect } from 'react'\nimport { TLKeyboardEventInfo } from '../editor/types/event-types'\nimport { preventDefault } from '../utils/dom'\nimport { useContainer } from './useContainer'\nimport { useEditor } from './useEditor'\n\nexport function useDocumentEvents() {\n\tconst editor = useEditor()\n\tconst container = useContainer()\n\n\tconst isAppFocused = useValue('isFocused', () => editor.getIsFocused(), [editor])\n\n\tuseEffect(() => {\n\t\tif (typeof window === 'undefined' || !('matchMedia' in window)) return\n\n\t\t// https://developer.mozilla.org/en-US/docs/Web/API/Window/devicePixelRatio#monitoring_screen_resolution_or_zoom_level_changes\n\t\tlet remove: (() => void) | null = null\n\t\tconst updatePixelRatio = () => {\n\t\t\tif (remove != null) {\n\t\t\t\tremove()\n\t\t\t}\n\t\t\tconst mqString = `(resolution: ${window.devicePixelRatio}dppx)`\n\t\t\tconst media = matchMedia(mqString)\n\t\t\t// Safari only started supporting `addEventListener('change',...) in version 14\n\t\t\t// https://developer.mozilla.org/en-US/docs/Web/API/MediaQueryList/change_event\n\t\t\tconst safariCb = (ev: any) => {\n\t\t\t\tif (ev.type === 'change') {\n\t\t\t\t\tupdatePixelRatio()\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (media.addEventListener) {\n\t\t\t\tmedia.addEventListener('change', updatePixelRatio)\n\t\t\t\t// eslint-disable-next-line deprecation/deprecation\n\t\t\t} else if (media.addListener) {\n\t\t\t\t// eslint-disable-next-line deprecation/deprecation\n\t\t\t\tmedia.addListener(safariCb)\n\t\t\t}\n\t\t\tremove = () => {\n\t\t\t\tif (media.removeEventListener) {\n\t\t\t\t\tmedia.removeEventListener('change', updatePixelRatio)\n\t\t\t\t\t// eslint-disable-next-line deprecation/deprecation\n\t\t\t\t} else if (media.removeListener) {\n\t\t\t\t\t// eslint-disable-next-line deprecation/deprecation\n\t\t\t\t\tmedia.removeListener(safariCb)\n\t\t\t\t}\n\t\t\t}\n\t\t\teditor.updateInstanceState({ devicePixelRatio: window.devicePixelRatio })\n\t\t}\n\t\tupdatePixelRatio()\n\t\treturn () => {\n\t\t\tremove?.()\n\t\t}\n\t}, [editor])\n\n\tuseEffect(() => {\n\t\tif (!isAppFocused) return\n\n\t\tconst handleKeyDown = (e: KeyboardEvent) => {\n\t\t\tif (\n\t\t\t\te.altKey &&\n\t\t\t\t// todo: When should we allow the alt key to be used? Perhaps states should declare which keys matter to them?\n\t\t\t\t(editor.isIn('zoom') || !editor.getPath().endsWith('.idle')) &&\n\t\t\t\t!isFocusingInput()\n\t\t\t) {\n\t\t\t\t// On windows the alt key opens the menu bar.\n\t\t\t\t// We want to prevent that if the user is doing something else,\n\t\t\t\t// e.g. resizing a shape\n\t\t\t\tpreventDefault(e)\n\t\t\t}\n\n\t\t\tif ((e as any).isKilled) return\n\t\t\t;(e as any).isKilled = true\n\n\t\t\tswitch (e.key) {\n\t\t\t\tcase '=':\n\t\t\t\tcase '-':\n\t\t\t\tcase '0': {\n\t\t\t\t\t// These keys are used for zooming. Technically we only use\n\t\t\t\t\t// the + - and 0 keys, however it's common for them to be\n\t\t\t\t\t// paired with modifier keys (command / control) so we need\n\t\t\t\t\t// to prevent the browser's regular actions (i.e. zooming\n\t\t\t\t\t// the page). A user can zoom by unfocusing the editor.\n\t\t\t\t\tif (e.metaKey || e.ctrlKey) {\n\t\t\t\t\t\tpreventDefault(e)\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase 'Tab': {\n\t\t\t\t\tif (isFocusingInput() || editor.getIsMenuOpen()) {\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase ',': {\n\t\t\t\t\t// this was moved to useKeyBoardShortcuts; it's possible\n\t\t\t\t\t// that the comma key is pressed when the container is not\n\t\t\t\t\t// focused, for example when the user has just interacted\n\t\t\t\t\t// with the toolbar. We need to handle it on the window\n\t\t\t\t\t// (ofc ensuring it's a correct time for a shortcut)\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tcase 'Escape': {\n\t\t\t\t\t// In certain browsers, pressing escape while in full screen mode\n\t\t\t\t\t// will exit full screen mode. We want to allow that, but not when\n\t\t\t\t\t// escape is being handled by the editor. When a user has an editing\n\t\t\t\t\t// shape, escape stops editing. When a user is using a tool, escape\n\t\t\t\t\t// returns to the select tool. When the user has selected shapes,\n\t\t\t\t\t// escape de-selects them. Only when the user's selection is empty\n\t\t\t\t\t// should we allow escape to do its normal thing.\n\n\t\t\t\t\tif (editor.getEditingShape() || editor.getSelectedShapeIds().length > 0) {\n\t\t\t\t\t\tpreventDefault(e)\n\t\t\t\t\t}\n\n\t\t\t\t\t// Don't do anything if we open menus open\n\t\t\t\t\tif (editor.getOpenMenus().length > 0) return\n\n\t\t\t\t\tif (editor.inputs.keys.has('Escape')) {\n\t\t\t\t\t\t// noop\n\t\t\t\t\t} else {\n\t\t\t\t\t\teditor.inputs.keys.add('Escape')\n\n\t\t\t\t\t\teditor.cancel()\n\t\t\t\t\t\t// Pressing escape will focus the document.body,\n\t\t\t\t\t\t// which will cause the app to lose focus, which\n\t\t\t\t\t\t// will break additional shortcuts. We need to\n\t\t\t\t\t\t// refocus the container in order to keep these\n\t\t\t\t\t\t// shortcuts working.\n\t\t\t\t\t\tcontainer.focus()\n\t\t\t\t\t}\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tdefault: {\n\t\t\t\t\tif (isFocusingInput() || editor.getIsMenuOpen()) {\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst info: TLKeyboardEventInfo = {\n\t\t\t\ttype: 'keyboard',\n\t\t\t\tname: e.repeat ? 'key_repeat' : 'key_down',\n\t\t\t\tkey: e.key,\n\t\t\t\tcode: e.code,\n\t\t\t\tshiftKey: e.shiftKey,\n\t\t\t\taltKey: e.altKey,\n\t\t\t\tctrlKey: e.metaKey || e.ctrlKey,\n\t\t\t}\n\n\t\t\teditor.dispatch(info)\n\t\t}\n\n\t\tconst handleKeyUp = (e: KeyboardEvent) => {\n\t\t\tif ((e as any).isKilled) return\n\t\t\t;(e as any).isKilled = true\n\n\t\t\tif (isFocusingInput() || editor.getIsMenuOpen()) {\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tif (e.key === ',') {\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tconst info: TLKeyboardEventInfo = {\n\t\t\t\ttype: 'keyboard',\n\t\t\t\tname: 'key_up',\n\t\t\t\tkey: e.key,\n\t\t\t\tcode: e.code,\n\t\t\t\tshiftKey: e.shiftKey,\n\t\t\t\taltKey: e.altKey,\n\t\t\t\tctrlKey: e.metaKey || e.ctrlKey,\n\t\t\t}\n\n\t\t\teditor.dispatch(info)\n\t\t}\n\n\t\tfunction handleTouchStart(e: TouchEvent) {\n\t\t\tif (container.contains(e.target as Node)) {\n\t\t\t\t// Center point of the touch area\n\t\t\t\tconst touchXPosition = e.touches[0].pageX\n\t\t\t\t// Size of the touch area\n\t\t\t\tconst touchXRadius = e.touches[0].radiusX || 0\n\n\t\t\t\t// We set a threshold (10px) on both sizes of the screen,\n\t\t\t\t// if the touch area overlaps with the screen edges\n\t\t\t\t// it's likely to trigger the navigation. We prevent the\n\t\t\t\t// touchstart event in that case.\n\t\t\t\t// todo: make this relative to the actual window, not the editor's screen bounds\n\t\t\t\tif (\n\t\t\t\t\ttouchXPosition - touchXRadius < 10 ||\n\t\t\t\t\ttouchXPosition + touchXRadius > editor.getViewportScreenBounds().width - 10\n\t\t\t\t) {\n\t\t\t\t\tif ((e.target as HTMLElement)?.tagName === 'BUTTON') {\n\t\t\t\t\t\t// Force a click before bailing\n\t\t\t\t\t\t;(e.target as HTMLButtonElement)?.click()\n\t\t\t\t\t}\n\n\t\t\t\t\tpreventDefault(e)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Prevent wheel events that occur inside of the container\n\t\tconst handleWheel = (e: WheelEvent) => {\n\t\t\tif (container.contains(e.target as Node) && (e.ctrlKey || e.metaKey)) {\n\t\t\t\tpreventDefault(e)\n\t\t\t}\n\t\t}\n\n\t\tcontainer.addEventListener('touchstart', handleTouchStart, { passive: false })\n\n\t\tcontainer.addEventListener('wheel', handleWheel, { passive: false })\n\n\t\tdocument.addEventListener('gesturestart', preventDefault)\n\t\tdocument.addEventListener('gesturechange', preventDefault)\n\t\tdocument.addEventListener('gestureend', preventDefault)\n\n\t\tcontainer.addEventListener('keydown', handleKeyDown)\n\t\tcontainer.addEventListener('keyup', handleKeyUp)\n\n\t\treturn () => {\n\t\t\tcontainer.removeEventListener('touchstart', handleTouchStart)\n\n\t\t\tcontainer.removeEventListener('wheel', handleWheel)\n\n\t\t\tdocument.removeEventListener('gesturestart', preventDefault)\n\t\t\tdocument.removeEventListener('gesturechange', preventDefault)\n\t\t\tdocument.removeEventListener('gestureend', preventDefault)\n\n\t\t\tcontainer.removeEventListener('keydown', handleKeyDown)\n\t\t\tcontainer.removeEventListener('keyup', handleKeyUp)\n\t\t}\n\t}, [editor, container, isAppFocused])\n}\n\nconst INPUTS = ['input', 'select', 'button', 'textarea']\n\nfunction isFocusingInput() {\n\tconst { activeElement } = document\n\n\tif (\n\t\tactiveElement &&\n\t\t(activeElement.getAttribute('contenteditable') ||\n\t\t\tINPUTS.indexOf(activeElement.tagName.toLowerCase()) > -1)\n\t) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n"], -- "mappings": "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", -+ "sourcesContent": ["import { useValue } from '@tldraw/state-react'\nimport { useEffect } from 'react'\nimport { TLKeyboardEventInfo } from '../editor/types/event-types'\nimport { preventDefault } from '../utils/dom'\nimport { useContainer } from './useContainer'\nimport { useEditor } from './useEditor'\n\nexport function useDocumentEvents() {\n\tconst editor = useEditor()\n\tconst container = useContainer()\n\n\tconst isAppFocused = useValue('isFocused', () => editor.getIsFocused(), [editor])\n\n\tuseEffect(() => {\n\t\tif (typeof window === 'undefined' || !('matchMedia' in window)) return\n\n\t\t// https://developer.mozilla.org/en-US/docs/Web/API/Window/devicePixelRatio#monitoring_screen_resolution_or_zoom_level_changes\n\t\tlet remove: (() => void) | null = null\n\t\tconst updatePixelRatio = () => {\n\t\t\tif (remove != null) {\n\t\t\t\tremove()\n\t\t\t}\n\t\t\tconst mqString = `(resolution: ${window.devicePixelRatio}dppx)`\n\t\t\tconst media = matchMedia(mqString)\n\t\t\t// Safari only started supporting `addEventListener('change',...) in version 14\n\t\t\t// https://developer.mozilla.org/en-US/docs/Web/API/MediaQueryList/change_event\n\t\t\tconst safariCb = (ev: any) => {\n\t\t\t\tif (ev.type === 'change') {\n\t\t\t\t\tupdatePixelRatio()\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (media.addEventListener) {\n\t\t\t\tmedia.addEventListener('change', updatePixelRatio)\n\t\t\t\t// eslint-disable-next-line deprecation/deprecation\n\t\t\t} else if (media.addListener) {\n\t\t\t\t// eslint-disable-next-line deprecation/deprecation\n\t\t\t\tmedia.addListener(safariCb)\n\t\t\t}\n\t\t\tremove = () => {\n\t\t\t\tif (media.removeEventListener) {\n\t\t\t\t\tmedia.removeEventListener('change', updatePixelRatio)\n\t\t\t\t\t// eslint-disable-next-line deprecation/deprecation\n\t\t\t\t} else if (media.removeListener) {\n\t\t\t\t\t// eslint-disable-next-line deprecation/deprecation\n\t\t\t\t\tmedia.removeListener(safariCb)\n\t\t\t\t}\n\t\t\t}\n\t\t\teditor.updateInstanceState({ devicePixelRatio: window.devicePixelRatio })\n\t\t}\n\t\tupdatePixelRatio()\n\t\treturn () => {\n\t\t\tremove?.()\n\t\t}\n\t}, [editor])\n\n\tuseEffect(() => {\n\t\tif (!isAppFocused) return\n\n\t\tconst handleKeyDown = (e: KeyboardEvent) => {\n\t\t\tif (\n\t\t\t\te.altKey &&\n\t\t\t\t// todo: When should we allow the alt key to be used? Perhaps states should declare which keys matter to them?\n\t\t\t\t(editor.isIn('zoom') || !editor.getPath().endsWith('.idle')) &&\n\t\t\t\t!isFocusingInput()\n\t\t\t) {\n\t\t\t\t// On windows the alt key opens the menu bar.\n\t\t\t\t// We want to prevent that if the user is doing something else,\n\t\t\t\t// e.g. resizing a shape\n\t\t\t\tpreventDefault(e)\n\t\t\t}\n\n\t\t\tif ((e as any).isKilled) return\n\t\t\t;(e as any).isKilled = true\n\n\t\t\tswitch (e.key) {\n\t\t\t\tcase '=':\n\t\t\t\tcase '-':\n\t\t\t\tcase '0': {\n\t\t\t\t\t// These keys are used for zooming. Technically we only use\n\t\t\t\t\t// the + - and 0 keys, however it's common for them to be\n\t\t\t\t\t// paired with modifier keys (command / control) so we need\n\t\t\t\t\t// to prevent the browser's regular actions (i.e. zooming\n\t\t\t\t\t// the page). A user can zoom by unfocusing the editor.\n\t\t\t\t\tif (e.metaKey || e.ctrlKey) {\n\t\t\t\t\t\tpreventDefault(e)\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase 'Tab': {\n\t\t\t\t\tif (isFocusingInput() || editor.getIsMenuOpen()) {\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase ',': {\n\t\t\t\t\t// this was moved to useKeyBoardShortcuts; it's possible\n\t\t\t\t\t// that the comma key is pressed when the container is not\n\t\t\t\t\t// focused, for example when the user has just interacted\n\t\t\t\t\t// with the toolbar. We need to handle it on the window\n\t\t\t\t\t// (ofc ensuring it's a correct time for a shortcut)\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tcase 'Escape': {\n\t\t\t\t\t// In certain browsers, pressing escape while in full screen mode\n\t\t\t\t\t// will exit full screen mode. We want to allow that, but not when\n\t\t\t\t\t// escape is being handled by the editor. When a user has an editing\n\t\t\t\t\t// shape, escape stops editing. When a user is using a tool, escape\n\t\t\t\t\t// returns to the select tool. When the user has selected shapes,\n\t\t\t\t\t// escape de-selects them. Only when the user's selection is empty\n\t\t\t\t\t// should we allow escape to do its normal thing.\n\n\t\t\t\t\tif (editor.getEditingShape() || editor.getSelectedShapeIds().length > 0) {\n\t\t\t\t\t\tpreventDefault(e)\n\t\t\t\t\t}\n\n\t\t\t\t\t// Don't do anything if we open menus open\n\t\t\t\t\tif (editor.getOpenMenus().length > 0) return\n\n\t\t\t\t\tif (editor.inputs.keys.has('Escape')) {\n\t\t\t\t\t\t// noop\n\t\t\t\t\t} else {\n\t\t\t\t\t\teditor.inputs.keys.add('Escape')\n\n\t\t\t\t\t\teditor.cancel()\n\t\t\t\t\t\t// Pressing escape will focus the document.body,\n\t\t\t\t\t\t// which will cause the app to lose focus, which\n\t\t\t\t\t\t// will break additional shortcuts. We need to\n\t\t\t\t\t\t// refocus the container in order to keep these\n\t\t\t\t\t\t// shortcuts working.\n\t\t\t\t\t\tcontainer.focus()\n\t\t\t\t\t}\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tdefault: {\n\t\t\t\t\tif (isFocusingInput() || editor.getIsMenuOpen()) {\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst info: TLKeyboardEventInfo = {\n\t\t\t\ttype: 'keyboard',\n\t\t\t\tname: e.repeat ? 'key_repeat' : 'key_down',\n\t\t\t\tkey: e.key,\n\t\t\t\tcode: e.code,\n\t\t\t\tshiftKey: e.shiftKey,\n\t\t\t\taltKey: e.altKey,\n\t\t\t\tctrlKey: e.metaKey || e.ctrlKey,\n\t\t\t}\n\n\t\t\teditor.dispatch(info)\n\t\t}\n\n\t\tconst handleKeyUp = (e: KeyboardEvent) => {\n\t\t\tif ((e as any).isKilled) return\n\t\t\t;(e as any).isKilled = true\n\n\t\t\tif (isFocusingInput() || editor.getIsMenuOpen()) {\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tif (e.key === ',') {\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tconst info: TLKeyboardEventInfo = {\n\t\t\t\ttype: 'keyboard',\n\t\t\t\tname: 'key_up',\n\t\t\t\tkey: e.key,\n\t\t\t\tcode: e.code,\n\t\t\t\tshiftKey: e.shiftKey,\n\t\t\t\taltKey: e.altKey,\n\t\t\t\tctrlKey: e.metaKey || e.ctrlKey,\n\t\t\t}\n\n\t\t\teditor.dispatch(info)\n\t\t}\n\n\t\tfunction handleTouchStart(e: TouchEvent) {\n\t\t\tif (container.contains(e.target as Node)) {\n\t\t\t\t// Center point of the touch area\n\t\t\t\tconst touchXPosition = e.touches[0].pageX\n\t\t\t\t// Size of the touch area\n\t\t\t\tconst touchXRadius = e.touches[0].radiusX || 0\n\n\t\t\t\t// We set a threshold (10px) on both sizes of the screen,\n\t\t\t\t// if the touch area overlaps with the screen edges\n\t\t\t\t// it's likely to trigger the navigation. We prevent the\n\t\t\t\t// touchstart event in that case.\n\t\t\t\t// todo: make this relative to the actual window, not the editor's screen bounds\n\t\t\t\tif (\n\t\t\t\t\ttouchXPosition - touchXRadius < 10 ||\n\t\t\t\t\ttouchXPosition + touchXRadius > editor.getViewportScreenBounds().width - 10\n\t\t\t\t) {\n\t\t\t\t\tif ((e.target as HTMLElement)?.tagName === 'BUTTON') {\n\t\t\t\t\t\t// Force a click before bailing\n\t\t\t\t\t\t;(e.target as HTMLButtonElement)?.click()\n\t\t\t\t\t}\n\n\t\t\t\t\tpreventDefault(e)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Prevent wheel events that occur inside of the container\n\t\tconst handleWheel = (e: WheelEvent) => {\n\t\t\tif (container.contains(e.target as Node) && (e.ctrlKey || e.metaKey)) {\n\t\t\t\tpreventDefault(e)\n\t\t\t}\n\t\t}\n\n\t\tcontainer.addEventListener('touchstart', handleTouchStart, { passive: false })\n\n\t\tcontainer.addEventListener('wheel', handleWheel, { passive: false })\n\n\t\tcontainer.ownerDocument.addEventListener('gesturestart', preventDefault)\n\t\tcontainer.ownerDocument.addEventListener('gesturechange', preventDefault)\n\t\tcontainer.ownerDocument.addEventListener('gestureend', preventDefault)\n\n\t\tcontainer.addEventListener('keydown', handleKeyDown)\n\t\tcontainer.addEventListener('keyup', handleKeyUp)\n\n\t\treturn () => {\n\t\t\tcontainer.removeEventListener('touchstart', handleTouchStart)\n\n\t\t\tcontainer.removeEventListener('wheel', handleWheel)\n\n\t\t\tcontainer.ownerDocument.removeEventListener('gesturestart', preventDefault)\n\t\t\tcontainer.ownerDocument.removeEventListener('gesturechange', preventDefault)\n\t\t\tcontainer.ownerDocument.removeEventListener('gestureend', preventDefault)\n\n\t\t\tcontainer.removeEventListener('keydown', handleKeyDown)\n\t\t\tcontainer.removeEventListener('keyup', handleKeyUp)\n\t\t}\n\t}, [editor, container, isAppFocused])\n}\n\nconst INPUTS = ['input', 'select', 'button', 'textarea']\n\nfunction isFocusingInput() {\n\tconst { activeElement } = document\n\n\tif (\n\t\tactiveElement &&\n\t\t(activeElement.getAttribute('contenteditable') ||\n\t\t\tINPUTS.indexOf(activeElement.tagName.toLowerCase()) > -1)\n\t) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n"], -+ "mappings": "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", - "names": [] - } -diff --git a/node_modules/@tldraw/editor/dist-esm/lib/utils/dom.mjs b/node_modules/@tldraw/editor/dist-esm/lib/utils/dom.mjs -index ba246e3..216dfdd 100644 ---- a/node_modules/@tldraw/editor/dist-esm/lib/utils/dom.mjs -+++ b/node_modules/@tldraw/editor/dist-esm/lib/utils/dom.mjs -@@ -1,6 +1,6 @@ - import { debugFlags, pointerCaptureTrackingObject } from "./debug-flags.mjs"; - function loopToHtmlElement(elm) { -- if (elm instanceof HTMLElement) return elm; -+ if (elm.instanceOf(HTMLElement)) return elm; - if (elm.parentElement) return loopToHtmlElement(elm.parentElement); - else throw Error("Could not find a parent element of an HTML type!"); - } -diff --git a/node_modules/@tldraw/editor/dist-esm/lib/utils/dom.mjs.map b/node_modules/@tldraw/editor/dist-esm/lib/utils/dom.mjs.map -index fd8b878..e08d616 100644 ---- a/node_modules/@tldraw/editor/dist-esm/lib/utils/dom.mjs.map -+++ b/node_modules/@tldraw/editor/dist-esm/lib/utils/dom.mjs.map -@@ -1,7 +1,7 @@ - { - "version": 3, - "sources": ["../../../src/lib/utils/dom.ts"], -- "sourcesContent": ["/*\nThis is used to facilitate double clicking and pointer capture on elements.\n\nThe events in this file are possibly set on individual SVG elements, \nsuch as handles or corner handles, rather than on HTML elements or \nSVGSVGElements. Raw SVG elemnets do not support pointerCapture in \nmost cases, meaning that in order for pointer capture to work, we \nneed to crawl up the DOM tree to find the nearest HTML element. Then,\nin order for that element to also call the `onPointerUp` event from\nthis file, we need to manually set that event on that element and\nlater remove it when the pointerup occurs. This is a potential leak\nif the user clicks on a handle but the pointerup does not fire for\nwhatever reason.\n*/\n\nimport React from 'react'\nimport { debugFlags, pointerCaptureTrackingObject } from './debug-flags'\n\n/** @public */\nexport function loopToHtmlElement(elm: Element): HTMLElement {\n\tif (elm instanceof HTMLElement) return elm\n\tif (elm.parentElement) return loopToHtmlElement(elm.parentElement)\n\telse throw Error('Could not find a parent element of an HTML type!')\n}\n\n/**\n * This function calls `event.preventDefault()` for you. Why is that useful?\n *\n * Beacuase if you enable `window.preventDefaultLogging = true` it'll log out a message when it\n * happens. Because we use console.warn rather than (log) you'll get a stack trace in the inspector\n * telling you exactly where it happened. This is important because `e.preventDefault()` is the\n * source of many bugs, but unfortuantly it can't be avoided because it also stops a lot of default\n * behaviour which doesn't make sense in our UI\n *\n * @param event - To prevent default on\n * @public\n */\nexport function preventDefault(event: React.BaseSyntheticEvent | Event) {\n\tevent.preventDefault()\n\tif (debugFlags.logPreventDefaults.get()) {\n\t\tconsole.warn('preventDefault called on event:', event)\n\t}\n}\n\n/** @public */\nexport function setPointerCapture(\n\telement: Element,\n\tevent: React.PointerEvent | PointerEvent\n) {\n\telement.setPointerCapture(event.pointerId)\n\tif (debugFlags.logPointerCaptures.get()) {\n\t\tconst trackingObj = pointerCaptureTrackingObject.get()\n\t\ttrackingObj.set(element, (trackingObj.get(element) ?? 0) + 1)\n\t\tconsole.warn('setPointerCapture called on element:', element, event)\n\t}\n}\n\n/** @public */\nexport function releasePointerCapture(\n\telement: Element,\n\tevent: React.PointerEvent | PointerEvent\n) {\n\tif (!element.hasPointerCapture(event.pointerId)) {\n\t\treturn\n\t}\n\n\telement.releasePointerCapture(event.pointerId)\n\tif (debugFlags.logPointerCaptures.get()) {\n\t\tconst trackingObj = pointerCaptureTrackingObject.get()\n\t\tif (trackingObj.get(element) === 1) {\n\t\t\ttrackingObj.delete(element)\n\t\t} else if (trackingObj.has(element)) {\n\t\t\ttrackingObj.set(element, trackingObj.get(element)! - 1)\n\t\t} else {\n\t\t\tconsole.warn('Release without capture')\n\t\t}\n\t\tconsole.warn('releasePointerCapture called on element:', element, event)\n\t}\n}\n\n/** @public */\nexport const stopEventPropagation = (e: any) => e.stopPropagation()\n\n/** @internal */\nexport const setStyleProperty = (\n\telm: HTMLElement | null,\n\tproperty: string,\n\tvalue: string | number\n) => {\n\tif (!elm) return\n\telm.style.setProperty(property, value as string)\n}\n"], -- "mappings": "AAgBA,SAAS,YAAY,oCAAoC;AAGlD,SAAS,kBAAkB,KAA2B;AAC5D,MAAI,eAAe,YAAa,QAAO;AACvC,MAAI,IAAI,cAAe,QAAO,kBAAkB,IAAI,aAAa;AAAA,MAC5D,OAAM,MAAM,kDAAkD;AACpE;AAcO,SAAS,eAAe,OAAyC;AACvE,QAAM,eAAe;AACrB,MAAI,WAAW,mBAAmB,IAAI,GAAG;AACxC,YAAQ,KAAK,mCAAmC,KAAK;AAAA,EACtD;AACD;AAGO,SAAS,kBACf,SACA,OACC;AACD,UAAQ,kBAAkB,MAAM,SAAS;AACzC,MAAI,WAAW,mBAAmB,IAAI,GAAG;AACxC,UAAM,cAAc,6BAA6B,IAAI;AACrD,gBAAY,IAAI,UAAU,YAAY,IAAI,OAAO,KAAK,KAAK,CAAC;AAC5D,YAAQ,KAAK,wCAAwC,SAAS,KAAK;AAAA,EACpE;AACD;AAGO,SAAS,sBACf,SACA,OACC;AACD,MAAI,CAAC,QAAQ,kBAAkB,MAAM,SAAS,GAAG;AAChD;AAAA,EACD;AAEA,UAAQ,sBAAsB,MAAM,SAAS;AAC7C,MAAI,WAAW,mBAAmB,IAAI,GAAG;AACxC,UAAM,cAAc,6BAA6B,IAAI;AACrD,QAAI,YAAY,IAAI,OAAO,MAAM,GAAG;AACnC,kBAAY,OAAO,OAAO;AAAA,IAC3B,WAAW,YAAY,IAAI,OAAO,GAAG;AACpC,kBAAY,IAAI,SAAS,YAAY,IAAI,OAAO,IAAK,CAAC;AAAA,IACvD,OAAO;AACN,cAAQ,KAAK,yBAAyB;AAAA,IACvC;AACA,YAAQ,KAAK,4CAA4C,SAAS,KAAK;AAAA,EACxE;AACD;AAGO,MAAM,uBAAuB,CAAC,MAAW,EAAE,gBAAgB;AAG3D,MAAM,mBAAmB,CAC/B,KACA,UACA,UACI;AACJ,MAAI,CAAC,IAAK;AACV,MAAI,MAAM,YAAY,UAAU,KAAe;AAChD;", -+ "sourcesContent": ["/*\nThis is used to facilitate double clicking and pointer capture on elements.\n\nThe events in this file are possibly set on individual SVG elements, \nsuch as handles or corner handles, rather than on HTML elements or \nSVGSVGElements. Raw SVG elemnets do not support pointerCapture in \nmost cases, meaning that in order for pointer capture to work, we \nneed to crawl up the DOM tree to find the nearest HTML element. Then,\nin order for that element to also call the `onPointerUp` event from\nthis file, we need to manually set that event on that element and\nlater remove it when the pointerup occurs. This is a potential leak\nif the user clicks on a handle but the pointerup does not fire for\nwhatever reason.\n*/\n\nimport React from 'react'\nimport { debugFlags, pointerCaptureTrackingObject } from './debug-flags'\n\ndeclare global {\n\tinterface Node {\n\t\t/**\n * Cross-window capable instanceof check, a drop-in replacement\n * for instanceof checks on DOM Nodes. Remember to also check\n * for nulls when necessary.\n\t\t * \n\t\t * #NOTE: Copied from Obsidian.md API https://github.com/obsidianmd/obsidian-api/blob/master/obsidian.d.ts\n\t\t * \n * @param type\n */\n instanceOf(type: {\n new (): T;\n }): this is T;\n /**\n\t\t * The window object this node belongs to, or the global window.\n\t\t * \n\t\t * #NOTE: Copied from Obsidian.md API\n */\n win: Window;\n\t}\n}\n\n/** @public */\nexport function loopToHtmlElement(elm: Element): HTMLElement {\n\tif (elm.instanceOf(HTMLElement)) return elm\n\tif (elm.parentElement) return loopToHtmlElement(elm.parentElement)\n\telse throw Error('Could not find a parent element of an HTML type!')\n}\n\n/**\n * This function calls `event.preventDefault()` for you. Why is that useful?\n *\n * Beacuase if you enable `window.preventDefaultLogging = true` it'll log out a message when it\n * happens. Because we use console.warn rather than (log) you'll get a stack trace in the inspector\n * telling you exactly where it happened. This is important because `e.preventDefault()` is the\n * source of many bugs, but unfortuantly it can't be avoided because it also stops a lot of default\n * behaviour which doesn't make sense in our UI\n *\n * @param event - To prevent default on\n * @public\n */\nexport function preventDefault(event: React.BaseSyntheticEvent | Event) {\n\tevent.preventDefault()\n\tif (debugFlags.logPreventDefaults.get()) {\n\t\tconsole.warn('preventDefault called on event:', event)\n\t}\n}\n\n/** @public */\nexport function setPointerCapture(\n\telement: Element,\n\tevent: React.PointerEvent | PointerEvent\n) {\n\telement.setPointerCapture(event.pointerId)\n\tif (debugFlags.logPointerCaptures.get()) {\n\t\tconst trackingObj = pointerCaptureTrackingObject.get()\n\t\ttrackingObj.set(element, (trackingObj.get(element) ?? 0) + 1)\n\t\tconsole.warn('setPointerCapture called on element:', element, event)\n\t}\n}\n\n/** @public */\nexport function releasePointerCapture(\n\telement: Element,\n\tevent: React.PointerEvent | PointerEvent\n) {\n\tif (!element.hasPointerCapture(event.pointerId)) {\n\t\treturn\n\t}\n\n\telement.releasePointerCapture(event.pointerId)\n\tif (debugFlags.logPointerCaptures.get()) {\n\t\tconst trackingObj = pointerCaptureTrackingObject.get()\n\t\tif (trackingObj.get(element) === 1) {\n\t\t\ttrackingObj.delete(element)\n\t\t} else if (trackingObj.has(element)) {\n\t\t\ttrackingObj.set(element, trackingObj.get(element)! - 1)\n\t\t} else {\n\t\t\tconsole.warn('Release without capture')\n\t\t}\n\t\tconsole.warn('releasePointerCapture called on element:', element, event)\n\t}\n}\n\n/** @public */\nexport const stopEventPropagation = (e: any) => e.stopPropagation()\n\n/** @internal */\nexport const setStyleProperty = (\n\telm: HTMLElement | null,\n\tproperty: string,\n\tvalue: string | number\n) => {\n\tif (!elm) return\n\telm.style.setProperty(property, value as string)\n}\n"], -+ "mappings": "AAgBA,SAAS,YAAY,oCAAoC;AA0BlD,SAAS,kBAAkB,KAA2B;AAC5D,MAAI,IAAI,WAAW,WAAW,EAAG,QAAO;AACxC,MAAI,IAAI,cAAe,QAAO,kBAAkB,IAAI,aAAa;AAAA,MAC5D,OAAM,MAAM,kDAAkD;AACpE;AAcO,SAAS,eAAe,OAAyC;AACvE,QAAM,eAAe;AACrB,MAAI,WAAW,mBAAmB,IAAI,GAAG;AACxC,YAAQ,KAAK,mCAAmC,KAAK;AAAA,EACtD;AACD;AAGO,SAAS,kBACf,SACA,OACC;AACD,UAAQ,kBAAkB,MAAM,SAAS;AACzC,MAAI,WAAW,mBAAmB,IAAI,GAAG;AACxC,UAAM,cAAc,6BAA6B,IAAI;AACrD,gBAAY,IAAI,UAAU,YAAY,IAAI,OAAO,KAAK,KAAK,CAAC;AAC5D,YAAQ,KAAK,wCAAwC,SAAS,KAAK;AAAA,EACpE;AACD;AAGO,SAAS,sBACf,SACA,OACC;AACD,MAAI,CAAC,QAAQ,kBAAkB,MAAM,SAAS,GAAG;AAChD;AAAA,EACD;AAEA,UAAQ,sBAAsB,MAAM,SAAS;AAC7C,MAAI,WAAW,mBAAmB,IAAI,GAAG;AACxC,UAAM,cAAc,6BAA6B,IAAI;AACrD,QAAI,YAAY,IAAI,OAAO,MAAM,GAAG;AACnC,kBAAY,OAAO,OAAO;AAAA,IAC3B,WAAW,YAAY,IAAI,OAAO,GAAG;AACpC,kBAAY,IAAI,SAAS,YAAY,IAAI,OAAO,IAAK,CAAC;AAAA,IACvD,OAAO;AACN,cAAQ,KAAK,yBAAyB;AAAA,IACvC;AACA,YAAQ,KAAK,4CAA4C,SAAS,KAAK;AAAA,EACxE;AACD;AAGO,MAAM,uBAAuB,CAAC,MAAW,EAAE,gBAAgB;AAG3D,MAAM,mBAAmB,CAC/B,KACA,UACA,UACI;AACJ,MAAI,CAAC,IAAK;AACV,MAAI,MAAM,YAAY,UAAU,KAAe;AAChD;", - "names": [] - } -diff --git a/node_modules/@tldraw/editor/src/lib/editor/Editor.ts b/node_modules/@tldraw/editor/src/lib/editor/Editor.ts -index d375e70..be04482 100644 ---- a/node_modules/@tldraw/editor/src/lib/editor/Editor.ts -+++ b/node_modules/@tldraw/editor/src/lib/editor/Editor.ts -@@ -3235,7 +3235,7 @@ export class Editor extends EventEmitter { - * @public - */ - updateViewportScreenBounds(screenBounds: Box | HTMLElement, center = false): this { -- if (screenBounds instanceof HTMLElement) { -+ if (!(screenBounds instanceof Box)) { - const rect = screenBounds.getBoundingClientRect() - screenBounds = new Box( - rect.left || rect.x, -diff --git a/node_modules/@tldraw/editor/src/lib/hooks/useDocumentEvents.ts b/node_modules/@tldraw/editor/src/lib/hooks/useDocumentEvents.ts -index 9c4da53..a99bea8 100644 ---- a/node_modules/@tldraw/editor/src/lib/hooks/useDocumentEvents.ts -+++ b/node_modules/@tldraw/editor/src/lib/hooks/useDocumentEvents.ts -@@ -214,9 +214,9 @@ export function useDocumentEvents() { - - container.addEventListener('wheel', handleWheel, { passive: false }) - -- document.addEventListener('gesturestart', preventDefault) -- document.addEventListener('gesturechange', preventDefault) -- document.addEventListener('gestureend', preventDefault) -+ container.ownerDocument.addEventListener('gesturestart', preventDefault) -+ container.ownerDocument.addEventListener('gesturechange', preventDefault) -+ container.ownerDocument.addEventListener('gestureend', preventDefault) - - container.addEventListener('keydown', handleKeyDown) - container.addEventListener('keyup', handleKeyUp) -@@ -226,9 +226,9 @@ export function useDocumentEvents() { - - container.removeEventListener('wheel', handleWheel) - -- document.removeEventListener('gesturestart', preventDefault) -- document.removeEventListener('gesturechange', preventDefault) -- document.removeEventListener('gestureend', preventDefault) -+ container.ownerDocument.removeEventListener('gesturestart', preventDefault) -+ container.ownerDocument.removeEventListener('gesturechange', preventDefault) -+ container.ownerDocument.removeEventListener('gestureend', preventDefault) - - container.removeEventListener('keydown', handleKeyDown) - container.removeEventListener('keyup', handleKeyUp) -diff --git a/node_modules/@tldraw/editor/src/lib/utils/dom.ts b/node_modules/@tldraw/editor/src/lib/utils/dom.ts -index 012d791..f7014e8 100644 ---- a/node_modules/@tldraw/editor/src/lib/utils/dom.ts -+++ b/node_modules/@tldraw/editor/src/lib/utils/dom.ts -@@ -16,9 +16,32 @@ whatever reason. - import React from 'react' - import { debugFlags, pointerCaptureTrackingObject } from './debug-flags' - -+declare global { -+ interface Node { -+ /** -+ * Cross-window capable instanceof check, a drop-in replacement -+ * for instanceof checks on DOM Nodes. Remember to also check -+ * for nulls when necessary. -+ * -+ * #NOTE: Copied from Obsidian.md API https://github.com/obsidianmd/obsidian-api/blob/master/obsidian.d.ts -+ * -+ * @param type -+ */ -+ instanceOf(type: { -+ new (): T; -+ }): this is T; -+ /** -+ * The window object this node belongs to, or the global window. -+ * -+ * #NOTE: Copied from Obsidian.md API -+ */ -+ win: Window; -+ } -+} -+ - /** @public */ - export function loopToHtmlElement(elm: Element): HTMLElement { -- if (elm instanceof HTMLElement) return elm -+ if (elm.instanceOf(HTMLElement)) return elm - if (elm.parentElement) return loopToHtmlElement(elm.parentElement) - else throw Error('Could not find a parent element of an HTML type!') - } diff --git a/patches/@tldraw+editor+3.4.1.patch b/patches/@tldraw+editor+3.4.1.patch new file mode 100644 index 0000000..dd27eaf --- /dev/null +++ b/patches/@tldraw+editor+3.4.1.patch @@ -0,0 +1,174 @@ +diff --git a/node_modules/@tldraw/editor/dist-esm/lib/editor/Editor.mjs b/node_modules/@tldraw/editor/dist-esm/lib/editor/Editor.mjs +index 2c3b305..7bb56e2 100644 +--- a/node_modules/@tldraw/editor/dist-esm/lib/editor/Editor.mjs ++++ b/node_modules/@tldraw/editor/dist-esm/lib/editor/Editor.mjs +@@ -2509,7 +2509,7 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed] + * @public + */ + updateViewportScreenBounds(screenBounds, center = false) { +- if (screenBounds instanceof HTMLElement) { ++ if (!(screenBounds instanceof Box)) { + const rect = screenBounds.getBoundingClientRect(); + screenBounds = new Box( + rect.left || rect.x, +diff --git a/node_modules/@tldraw/editor/dist-esm/lib/editor/Editor.mjs.map b/node_modules/@tldraw/editor/dist-esm/lib/editor/Editor.mjs.map +index c77655a..34b609a 100644 +--- a/node_modules/@tldraw/editor/dist-esm/lib/editor/Editor.mjs.map ++++ b/node_modules/@tldraw/editor/dist-esm/lib/editor/Editor.mjs.map +@@ -1,7 +1,7 @@ + { + "version": 3, + "sources": ["../../../src/lib/editor/Editor.ts"], +- "sourcesContent": ["import { EMPTY_ARRAY, atom, computed, react, transact, unsafe__withoutCapture } from '@tldraw/state'\nimport {\n\tComputedCache,\n\tRecordType,\n\tStoreSideEffects,\n\tStoreSnapshot,\n\tUnknownRecord,\n\treverseRecordsDiff,\n} from '@tldraw/store'\nimport {\n\tCameraRecordType,\n\tInstancePageStateRecordType,\n\tPageRecordType,\n\tStyleProp,\n\tStylePropValue,\n\tTLArrowShape,\n\tTLAsset,\n\tTLAssetId,\n\tTLAssetPartial,\n\tTLBinding,\n\tTLBindingCreate,\n\tTLBindingId,\n\tTLBindingUpdate,\n\tTLCamera,\n\tTLCursor,\n\tTLCursorType,\n\tTLDOCUMENT_ID,\n\tTLDocument,\n\tTLFrameShape,\n\tTLGeoShape,\n\tTLGroupShape,\n\tTLHandle,\n\tTLINSTANCE_ID,\n\tTLImageAsset,\n\tTLInstance,\n\tTLInstancePageState,\n\tTLPOINTER_ID,\n\tTLPage,\n\tTLPageId,\n\tTLParentId,\n\tTLRecord,\n\tTLShape,\n\tTLShapeId,\n\tTLShapePartial,\n\tTLStore,\n\tTLStoreSnapshot,\n\tTLUnknownBinding,\n\tTLUnknownShape,\n\tTLVideoAsset,\n\tcreateBindingId,\n\tcreateShapeId,\n\tgetShapePropKeysByStyle,\n\tisPageId,\n\tisShapeId,\n} from '@tldraw/tlschema'\nimport {\n\tFileHelpers,\n\tIndexKey,\n\tJsonObject,\n\tPerformanceTracker,\n\tResult,\n\tannotateError,\n\tassert,\n\tassertExists,\n\tbind,\n\tcompact,\n\tdebounce,\n\tdedupe,\n\texhaustiveSwitchError,\n\tfetch,\n\tgetIndexAbove,\n\tgetIndexBetween,\n\tgetIndices,\n\tgetIndicesAbove,\n\tgetIndicesBetween,\n\tgetOwnProperty,\n\thasOwnProperty,\n\tlast,\n\tlerp,\n\tsortById,\n\tsortByIndex,\n\tstructuredClone,\n\tuniqueId,\n} from '@tldraw/utils'\nimport EventEmitter from 'eventemitter3'\nimport {\n\tTLEditorSnapshot,\n\tTLLoadSnapshotOptions,\n\tgetSnapshot,\n\tloadSnapshot,\n} from '../config/TLEditorSnapshot'\nimport { TLUser, createTLUser } from '../config/createTLUser'\nimport { TLAnyBindingUtilConstructor, checkBindings } from '../config/defaultBindings'\nimport { TLAnyShapeUtilConstructor, checkShapesAndAddCore } from '../config/defaultShapes'\nimport {\n\tDEFAULT_ANIMATION_OPTIONS,\n\tDEFAULT_CAMERA_OPTIONS,\n\tINTERNAL_POINTER_IDS,\n\tLEFT_MOUSE_BUTTON,\n\tMIDDLE_MOUSE_BUTTON,\n\tRIGHT_MOUSE_BUTTON,\n\tSTYLUS_ERASER_BUTTON,\n\tZOOM_TO_FIT_PADDING,\n} from '../constants'\nimport { exportToSvg } from '../exports/exportToSvg'\nimport { tlenv } from '../globals/environment'\nimport { tlmenus } from '../globals/menus'\nimport { tltime } from '../globals/time'\nimport { TldrawOptions, defaultTldrawOptions } from '../options'\nimport { Box, BoxLike } from '../primitives/Box'\nimport { Mat, MatLike } from '../primitives/Mat'\nimport { Vec, VecLike } from '../primitives/Vec'\nimport { EASINGS } from '../primitives/easings'\nimport { Geometry2d } from '../primitives/geometry/Geometry2d'\nimport { Group2d } from '../primitives/geometry/Group2d'\nimport { intersectPolygonPolygon } from '../primitives/intersect'\nimport { PI2, approximately, areAnglesCompatible, clamp, pointInPolygon } from '../primitives/utils'\nimport { ReadonlySharedStyleMap, SharedStyle, SharedStyleMap } from '../utils/SharedStylesMap'\nimport { dataUrlToFile } from '../utils/assets'\nimport { debugFlags } from '../utils/debug-flags'\nimport {\n\tTLDeepLink,\n\tTLDeepLinkOptions,\n\tcreateDeepLinkString,\n\tparseDeepLinkString,\n} from '../utils/deepLinks'\nimport { getIncrementedName } from '../utils/getIncrementedName'\nimport { isAccelKey } from '../utils/keyboard'\nimport { getReorderingShapesChanges } from '../utils/reorderShapes'\nimport { applyRotationToSnapshotShapes, getRotationSnapshot } from '../utils/rotation'\nimport { BindingOnDeleteOptions, BindingUtil } from './bindings/BindingUtil'\nimport { bindingsIndex } from './derivations/bindingsIndex'\nimport { notVisibleShapes } from './derivations/notVisibleShapes'\nimport { parentsToChildren } from './derivations/parentsToChildren'\nimport { deriveShapeIdsInCurrentPage } from './derivations/shapeIdsInCurrentPage'\nimport { ClickManager } from './managers/ClickManager'\nimport { EdgeScrollManager } from './managers/EdgeScrollManager'\nimport { FocusManager } from './managers/FocusManager'\nimport { HistoryManager } from './managers/HistoryManager'\nimport { ScribbleManager } from './managers/ScribbleManager'\nimport { SnapManager } from './managers/SnapManager/SnapManager'\nimport { TextManager } from './managers/TextManager'\nimport { TickManager } from './managers/TickManager'\nimport { UserPreferencesManager } from './managers/UserPreferencesManager'\nimport { ShapeUtil, TLResizeMode } from './shapes/ShapeUtil'\nimport { RootState } from './tools/RootState'\nimport { StateNode, TLStateNodeConstructor } from './tools/StateNode'\nimport { TLContent } from './types/clipboard-types'\nimport { TLEventMap } from './types/emit-types'\nimport {\n\tTLEventInfo,\n\tTLPinchEventInfo,\n\tTLPointerEventInfo,\n\tTLWheelEventInfo,\n} from './types/event-types'\nimport { TLExternalAssetContent, TLExternalContent } from './types/external-content'\nimport { TLHistoryBatchOptions } from './types/history-types'\nimport {\n\tOptionalKeys,\n\tRequiredKeys,\n\tTLCameraMoveOptions,\n\tTLCameraOptions,\n\tTLImageExportOptions,\n} from './types/misc-types'\nimport { TLResizeHandle } from './types/selection-types'\n\n/** @public */\nexport type TLResizeShapeOptions = Partial<{\n\tinitialBounds: Box\n\tscaleOrigin: VecLike\n\tscaleAxisRotation: number\n\tinitialShape: TLShape\n\tinitialPageTransform: MatLike\n\tdragHandle: TLResizeHandle\n\tisAspectRatioLocked: boolean\n\tmode: TLResizeMode\n\tskipStartAndEndCallbacks: boolean\n}>\n\n/** @public */\nexport interface TLEditorOptions {\n\t/**\n\t * The Store instance to use for keeping the app's data. This may be prepopulated, e.g. by loading\n\t * from a server or database.\n\t */\n\tstore: TLStore\n\t/**\n\t * An array of shapes to use in the editor. These will be used to create and manage shapes in the editor.\n\t */\n\tshapeUtils: readonly TLAnyShapeUtilConstructor[]\n\t/**\n\t * An array of bindings to use in the editor. These will be used to create and manage bindings in the editor.\n\t */\n\tbindingUtils: readonly TLAnyBindingUtilConstructor[]\n\t/**\n\t * An array of tools to use in the editor. These will be used to handle events and manage user interactions in the editor.\n\t */\n\ttools: readonly TLStateNodeConstructor[]\n\t/**\n\t * Should return a containing html element which has all the styles applied to the editor. If not\n\t * given, the body element will be used.\n\t */\n\tgetContainer(): HTMLElement\n\t/**\n\t * A user defined externally to replace the default user.\n\t */\n\tuser?: TLUser\n\t/**\n\t * The editor's initial active tool (or other state node id).\n\t */\n\tinitialState?: string\n\t/**\n\t * Whether to automatically focus the editor when it mounts.\n\t */\n\tautoFocus?: boolean\n\t/**\n\t * Whether to infer dark mode from the user's system preferences. Defaults to false.\n\t */\n\tinferDarkMode?: boolean\n\t/**\n\t * Options for the editor's camera.\n\t */\n\tcameraOptions?: Partial\n\toptions?: Partial\n\tlicenseKey?: string\n\t/**\n\t * A predicate that should return true if the given shape should be hidden.\n\t * @param shape - The shape to check.\n\t * @param editor - The editor instance.\n\t */\n\tisShapeHidden?(shape: TLShape, editor: Editor): boolean\n}\n\n/**\n * Options for {@link Editor.(run:1)}.\n * @public\n */\nexport interface TLEditorRunOptions extends TLHistoryBatchOptions {\n\tignoreShapeLock?: boolean\n}\n\n/** @public */\nexport interface TLRenderingShape {\n\tid: TLShapeId\n\tshape: TLShape\n\tutil: ShapeUtil\n\tindex: number\n\tbackgroundIndex: number\n\topacity: number\n}\n\n/** @public */\nexport class Editor extends EventEmitter {\n\tconstructor({\n\t\tstore,\n\t\tuser,\n\t\tshapeUtils,\n\t\tbindingUtils,\n\t\ttools,\n\t\tgetContainer,\n\t\tcameraOptions,\n\t\tinitialState,\n\t\tautoFocus,\n\t\tinferDarkMode,\n\t\toptions,\n\t\tisShapeHidden,\n\t}: TLEditorOptions) {\n\t\tsuper()\n\n\t\tthis._isShapeHiddenPredicate = isShapeHidden\n\n\t\tthis.options = { ...defaultTldrawOptions, ...options }\n\n\t\tthis.store = store\n\t\tthis.disposables.add(this.store.dispose.bind(this.store))\n\t\tthis.history = new HistoryManager({\n\t\t\tstore,\n\t\t\tannotateError: (error) => {\n\t\t\t\tthis.annotateError(error, { origin: 'history.batch', willCrashApp: true })\n\t\t\t\tthis.crash(error)\n\t\t\t},\n\t\t})\n\n\t\tthis.snaps = new SnapManager(this)\n\n\t\tthis.disposables.add(this.timers.dispose)\n\n\t\tthis._cameraOptions.set({ ...DEFAULT_CAMERA_OPTIONS, ...cameraOptions })\n\n\t\tthis.user = new UserPreferencesManager(user ?? createTLUser(), inferDarkMode ?? false)\n\n\t\tthis.getContainer = getContainer\n\n\t\tthis.textMeasure = new TextManager(this)\n\t\tthis._tickManager = new TickManager(this)\n\n\t\tclass NewRoot extends RootState {\n\t\t\tstatic override initial = initialState ?? ''\n\t\t}\n\n\t\tthis.root = new NewRoot(this)\n\t\tthis.root.children = {}\n\n\t\tconst allShapeUtils = checkShapesAndAddCore(shapeUtils)\n\n\t\tconst _shapeUtils = {} as Record>\n\t\tconst _styleProps = {} as Record, string>>\n\t\tconst allStylesById = new Map>()\n\n\t\tfor (const Util of allShapeUtils) {\n\t\t\tconst util = new Util(this)\n\t\t\t_shapeUtils[Util.type] = util\n\n\t\t\tconst propKeysByStyle = getShapePropKeysByStyle(Util.props ?? {})\n\t\t\t_styleProps[Util.type] = propKeysByStyle\n\n\t\t\tfor (const style of propKeysByStyle.keys()) {\n\t\t\t\tif (!allStylesById.has(style.id)) {\n\t\t\t\t\tallStylesById.set(style.id, style)\n\t\t\t\t} else if (allStylesById.get(style.id) !== style) {\n\t\t\t\t\tthrow Error(\n\t\t\t\t\t\t`Multiple style props with id \"${style.id}\" in use. Style prop IDs must be unique.`\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tthis.shapeUtils = _shapeUtils\n\t\tthis.styleProps = _styleProps\n\n\t\tconst allBindingUtils = checkBindings(bindingUtils)\n\t\tconst _bindingUtils = {} as Record>\n\t\tfor (const Util of allBindingUtils) {\n\t\t\tconst util = new Util(this)\n\t\t\t_bindingUtils[Util.type] = util\n\t\t}\n\t\tthis.bindingUtils = _bindingUtils\n\n\t\t// Tools.\n\t\t// Accept tools from constructor parameters which may not conflict with the root note's default or\n\t\t// \"baked in\" tools, select and zoom.\n\t\tfor (const Tool of [...tools]) {\n\t\t\tif (hasOwnProperty(this.root.children!, Tool.id)) {\n\t\t\t\tthrow Error(`Can't override tool with id \"${Tool.id}\"`)\n\t\t\t}\n\t\t\tthis.root.children![Tool.id] = new Tool(this, this.root)\n\t\t}\n\n\t\tthis.scribbles = new ScribbleManager(this)\n\n\t\t// Cleanup\n\n\t\tconst cleanupInstancePageState = (\n\t\t\tprevPageState: TLInstancePageState,\n\t\t\tshapesNoLongerInPage: Set\n\t\t) => {\n\t\t\tlet nextPageState = null as null | TLInstancePageState\n\n\t\t\tconst selectedShapeIds = prevPageState.selectedShapeIds.filter(\n\t\t\t\t(id) => !shapesNoLongerInPage.has(id)\n\t\t\t)\n\t\t\tif (selectedShapeIds.length !== prevPageState.selectedShapeIds.length) {\n\t\t\t\tif (!nextPageState) nextPageState = { ...prevPageState }\n\t\t\t\tnextPageState.selectedShapeIds = selectedShapeIds\n\t\t\t}\n\n\t\t\tconst erasingShapeIds = prevPageState.erasingShapeIds.filter(\n\t\t\t\t(id) => !shapesNoLongerInPage.has(id)\n\t\t\t)\n\t\t\tif (erasingShapeIds.length !== prevPageState.erasingShapeIds.length) {\n\t\t\t\tif (!nextPageState) nextPageState = { ...prevPageState }\n\t\t\t\tnextPageState.erasingShapeIds = erasingShapeIds\n\t\t\t}\n\n\t\t\tif (prevPageState.hoveredShapeId && shapesNoLongerInPage.has(prevPageState.hoveredShapeId)) {\n\t\t\t\tif (!nextPageState) nextPageState = { ...prevPageState }\n\t\t\t\tnextPageState.hoveredShapeId = null\n\t\t\t}\n\n\t\t\tif (prevPageState.editingShapeId && shapesNoLongerInPage.has(prevPageState.editingShapeId)) {\n\t\t\t\tif (!nextPageState) nextPageState = { ...prevPageState }\n\t\t\t\tnextPageState.editingShapeId = null\n\t\t\t}\n\n\t\t\tconst hintingShapeIds = prevPageState.hintingShapeIds.filter(\n\t\t\t\t(id) => !shapesNoLongerInPage.has(id)\n\t\t\t)\n\t\t\tif (hintingShapeIds.length !== prevPageState.hintingShapeIds.length) {\n\t\t\t\tif (!nextPageState) nextPageState = { ...prevPageState }\n\t\t\t\tnextPageState.hintingShapeIds = hintingShapeIds\n\t\t\t}\n\n\t\t\tif (prevPageState.focusedGroupId && shapesNoLongerInPage.has(prevPageState.focusedGroupId)) {\n\t\t\t\tif (!nextPageState) nextPageState = { ...prevPageState }\n\t\t\t\tnextPageState.focusedGroupId = null\n\t\t\t}\n\t\t\treturn nextPageState\n\t\t}\n\n\t\tthis.sideEffects = this.store.sideEffects\n\n\t\tlet deletedBindings = new Map>()\n\t\tconst deletedShapeIds = new Set()\n\t\tconst invalidParents = new Set()\n\t\tlet invalidBindingTypes = new Set()\n\t\tthis.disposables.add(\n\t\t\tthis.sideEffects.registerOperationCompleteHandler(() => {\n\t\t\t\t// this needs to be cleared here because further effects may delete more shapes\n\t\t\t\t// and we want the next invocation of this handler to handle those separately\n\t\t\t\tdeletedShapeIds.clear()\n\n\t\t\t\tfor (const parentId of invalidParents) {\n\t\t\t\t\tinvalidParents.delete(parentId)\n\t\t\t\t\tconst parent = this.getShape(parentId)\n\t\t\t\t\tif (!parent) continue\n\n\t\t\t\t\tconst util = this.getShapeUtil(parent)\n\t\t\t\t\tconst changes = util.onChildrenChange?.(parent)\n\n\t\t\t\t\tif (changes?.length) {\n\t\t\t\t\t\tthis.updateShapes(changes)\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (invalidBindingTypes.size) {\n\t\t\t\t\tconst t = invalidBindingTypes\n\t\t\t\t\tinvalidBindingTypes = new Set()\n\t\t\t\t\tfor (const type of t) {\n\t\t\t\t\t\tconst util = this.getBindingUtil(type)\n\t\t\t\t\t\tutil.onOperationComplete?.()\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (deletedBindings.size) {\n\t\t\t\t\tconst t = deletedBindings\n\t\t\t\t\tdeletedBindings = new Map()\n\t\t\t\t\tfor (const opts of t.values()) {\n\t\t\t\t\t\tthis.getBindingUtil(opts.binding).onAfterDelete?.(opts)\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tthis.emit('update')\n\t\t\t})\n\t\t)\n\n\t\tthis.disposables.add(\n\t\t\tthis.sideEffects.register({\n\t\t\t\tshape: {\n\t\t\t\t\tafterChange: (shapeBefore, shapeAfter) => {\n\t\t\t\t\t\tfor (const binding of this.getBindingsInvolvingShape(shapeAfter)) {\n\t\t\t\t\t\t\tinvalidBindingTypes.add(binding.type)\n\t\t\t\t\t\t\tif (binding.fromId === shapeAfter.id) {\n\t\t\t\t\t\t\t\tthis.getBindingUtil(binding).onAfterChangeFromShape?.({\n\t\t\t\t\t\t\t\t\tbinding,\n\t\t\t\t\t\t\t\t\tshapeBefore,\n\t\t\t\t\t\t\t\t\tshapeAfter,\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (binding.toId === shapeAfter.id) {\n\t\t\t\t\t\t\t\tthis.getBindingUtil(binding).onAfterChangeToShape?.({\n\t\t\t\t\t\t\t\t\tbinding,\n\t\t\t\t\t\t\t\t\tshapeBefore,\n\t\t\t\t\t\t\t\t\tshapeAfter,\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// if the shape's parent changed and it has a binding, update the binding\n\t\t\t\t\t\tif (shapeBefore.parentId !== shapeAfter.parentId) {\n\t\t\t\t\t\t\tconst notifyBindingAncestryChange = (id: TLShapeId) => {\n\t\t\t\t\t\t\t\tconst descendantShape = this.getShape(id)\n\t\t\t\t\t\t\t\tif (!descendantShape) return\n\n\t\t\t\t\t\t\t\tfor (const binding of this.getBindingsInvolvingShape(descendantShape)) {\n\t\t\t\t\t\t\t\t\tinvalidBindingTypes.add(binding.type)\n\n\t\t\t\t\t\t\t\t\tif (binding.fromId === descendantShape.id) {\n\t\t\t\t\t\t\t\t\t\tthis.getBindingUtil(binding).onAfterChangeFromShape?.({\n\t\t\t\t\t\t\t\t\t\t\tbinding,\n\t\t\t\t\t\t\t\t\t\t\tshapeBefore: descendantShape,\n\t\t\t\t\t\t\t\t\t\t\tshapeAfter: descendantShape,\n\t\t\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tif (binding.toId === descendantShape.id) {\n\t\t\t\t\t\t\t\t\t\tthis.getBindingUtil(binding).onAfterChangeToShape?.({\n\t\t\t\t\t\t\t\t\t\t\tbinding,\n\t\t\t\t\t\t\t\t\t\t\tshapeBefore: descendantShape,\n\t\t\t\t\t\t\t\t\t\t\tshapeAfter: descendantShape,\n\t\t\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tnotifyBindingAncestryChange(shapeAfter.id)\n\t\t\t\t\t\t\tthis.visitDescendants(shapeAfter.id, notifyBindingAncestryChange)\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// if this shape moved to a new page, clean up any previous page's instance state\n\t\t\t\t\t\tif (shapeBefore.parentId !== shapeAfter.parentId && isPageId(shapeAfter.parentId)) {\n\t\t\t\t\t\t\tconst allMovingIds = new Set([shapeBefore.id])\n\t\t\t\t\t\t\tthis.visitDescendants(shapeBefore.id, (id) => {\n\t\t\t\t\t\t\t\tallMovingIds.add(id)\n\t\t\t\t\t\t\t})\n\n\t\t\t\t\t\t\tfor (const instancePageState of this.getPageStates()) {\n\t\t\t\t\t\t\t\tif (instancePageState.pageId === shapeAfter.parentId) continue\n\t\t\t\t\t\t\t\tconst nextPageState = cleanupInstancePageState(instancePageState, allMovingIds)\n\n\t\t\t\t\t\t\t\tif (nextPageState) {\n\t\t\t\t\t\t\t\t\tthis.store.put([nextPageState])\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (shapeBefore.parentId && isShapeId(shapeBefore.parentId)) {\n\t\t\t\t\t\t\tinvalidParents.add(shapeBefore.parentId)\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (shapeAfter.parentId !== shapeBefore.parentId && isShapeId(shapeAfter.parentId)) {\n\t\t\t\t\t\t\tinvalidParents.add(shapeAfter.parentId)\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t\tbeforeDelete: (shape) => {\n\t\t\t\t\t\t// if we triggered this delete with a recursive call, don't do anything\n\t\t\t\t\t\tif (deletedShapeIds.has(shape.id)) return\n\t\t\t\t\t\t// if the deleted shape has a parent shape make sure we call it's onChildrenChange callback\n\t\t\t\t\t\tif (shape.parentId && isShapeId(shape.parentId)) {\n\t\t\t\t\t\t\tinvalidParents.add(shape.parentId)\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tdeletedShapeIds.add(shape.id)\n\n\t\t\t\t\t\tconst deleteBindingIds: TLBindingId[] = []\n\t\t\t\t\t\tfor (const binding of this.getBindingsInvolvingShape(shape)) {\n\t\t\t\t\t\t\tinvalidBindingTypes.add(binding.type)\n\t\t\t\t\t\t\tdeleteBindingIds.push(binding.id)\n\t\t\t\t\t\t\tconst util = this.getBindingUtil(binding)\n\t\t\t\t\t\t\tif (binding.fromId === shape.id) {\n\t\t\t\t\t\t\t\tutil.onBeforeIsolateToShape?.({ binding, removedShape: shape })\n\t\t\t\t\t\t\t\tutil.onBeforeDeleteFromShape?.({ binding, shape })\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tutil.onBeforeIsolateFromShape?.({ binding, removedShape: shape })\n\t\t\t\t\t\t\t\tutil.onBeforeDeleteToShape?.({ binding, shape })\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (deleteBindingIds.length) {\n\t\t\t\t\t\t\tthis.deleteBindings(deleteBindingIds)\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst deletedIds = new Set([shape.id])\n\t\t\t\t\t\tconst updates = compact(\n\t\t\t\t\t\t\tthis.getPageStates().map((pageState) => {\n\t\t\t\t\t\t\t\treturn cleanupInstancePageState(pageState, deletedIds)\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t)\n\n\t\t\t\t\t\tif (updates.length) {\n\t\t\t\t\t\t\tthis.store.put(updates)\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tbinding: {\n\t\t\t\t\tbeforeCreate: (binding) => {\n\t\t\t\t\t\tconst next = this.getBindingUtil(binding).onBeforeCreate?.({ binding })\n\t\t\t\t\t\tif (next) return next\n\t\t\t\t\t\treturn binding\n\t\t\t\t\t},\n\t\t\t\t\tafterCreate: (binding) => {\n\t\t\t\t\t\tinvalidBindingTypes.add(binding.type)\n\t\t\t\t\t\tthis.getBindingUtil(binding).onAfterCreate?.({ binding })\n\t\t\t\t\t},\n\t\t\t\t\tbeforeChange: (bindingBefore, bindingAfter) => {\n\t\t\t\t\t\tconst updated = this.getBindingUtil(bindingAfter).onBeforeChange?.({\n\t\t\t\t\t\t\tbindingBefore,\n\t\t\t\t\t\t\tbindingAfter,\n\t\t\t\t\t\t})\n\t\t\t\t\t\tif (updated) return updated\n\t\t\t\t\t\treturn bindingAfter\n\t\t\t\t\t},\n\t\t\t\t\tafterChange: (bindingBefore, bindingAfter) => {\n\t\t\t\t\t\tinvalidBindingTypes.add(bindingAfter.type)\n\t\t\t\t\t\tthis.getBindingUtil(bindingAfter).onAfterChange?.({ bindingBefore, bindingAfter })\n\t\t\t\t\t},\n\t\t\t\t\tbeforeDelete: (binding) => {\n\t\t\t\t\t\tthis.getBindingUtil(binding).onBeforeDelete?.({ binding })\n\t\t\t\t\t},\n\t\t\t\t\tafterDelete: (binding) => {\n\t\t\t\t\t\tthis.getBindingUtil(binding).onAfterDelete?.({ binding })\n\t\t\t\t\t\tinvalidBindingTypes.add(binding.type)\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tpage: {\n\t\t\t\t\tafterCreate: (record) => {\n\t\t\t\t\t\tconst cameraId = CameraRecordType.createId(record.id)\n\t\t\t\t\t\tconst _pageStateId = InstancePageStateRecordType.createId(record.id)\n\t\t\t\t\t\tif (!this.store.has(cameraId)) {\n\t\t\t\t\t\t\tthis.store.put([CameraRecordType.create({ id: cameraId })])\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (!this.store.has(_pageStateId)) {\n\t\t\t\t\t\t\tthis.store.put([\n\t\t\t\t\t\t\t\tInstancePageStateRecordType.create({ id: _pageStateId, pageId: record.id }),\n\t\t\t\t\t\t\t])\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t\tafterDelete: (record, source) => {\n\t\t\t\t\t\t// page was deleted, need to check whether it's the current page and select another one if so\n\t\t\t\t\t\tif (this.getInstanceState()?.currentPageId === record.id) {\n\t\t\t\t\t\t\tconst backupPageId = this.getPages().find((p) => p.id !== record.id)?.id\n\t\t\t\t\t\t\tif (backupPageId) {\n\t\t\t\t\t\t\t\tthis.store.put([{ ...this.getInstanceState(), currentPageId: backupPageId }])\n\t\t\t\t\t\t\t} else if (source === 'user') {\n\t\t\t\t\t\t\t\t// fall back to ensureStoreIsUsable:\n\t\t\t\t\t\t\t\tthis.store.ensureStoreIsUsable()\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// delete the camera and state for the page if necessary\n\t\t\t\t\t\tconst cameraId = CameraRecordType.createId(record.id)\n\t\t\t\t\t\tconst instance_PageStateId = InstancePageStateRecordType.createId(record.id)\n\t\t\t\t\t\tthis.store.remove([cameraId, instance_PageStateId])\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tinstance: {\n\t\t\t\t\tafterChange: (prev, next, source) => {\n\t\t\t\t\t\t// instance should never be updated to a page that no longer exists (this can\n\t\t\t\t\t\t// happen when undoing a change that involves switching to a page that has since\n\t\t\t\t\t\t// been deleted by another user)\n\t\t\t\t\t\tif (!this.store.has(next.currentPageId)) {\n\t\t\t\t\t\t\tconst backupPageId = this.store.has(prev.currentPageId)\n\t\t\t\t\t\t\t\t? prev.currentPageId\n\t\t\t\t\t\t\t\t: this.getPages()[0]?.id\n\t\t\t\t\t\t\tif (backupPageId) {\n\t\t\t\t\t\t\t\tthis.store.update(next.id, (instance) => ({\n\t\t\t\t\t\t\t\t\t...instance,\n\t\t\t\t\t\t\t\t\tcurrentPageId: backupPageId,\n\t\t\t\t\t\t\t\t}))\n\t\t\t\t\t\t\t} else if (source === 'user') {\n\t\t\t\t\t\t\t\t// fall back to ensureStoreIsUsable:\n\t\t\t\t\t\t\t\tthis.store.ensureStoreIsUsable()\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tinstance_page_state: {\n\t\t\t\t\tafterChange: (prev, next) => {\n\t\t\t\t\t\tif (prev?.selectedShapeIds !== next?.selectedShapeIds) {\n\t\t\t\t\t\t\t// ensure that descendants and ancestors are not selected at the same time\n\t\t\t\t\t\t\tconst filtered = next.selectedShapeIds.filter((id) => {\n\t\t\t\t\t\t\t\tlet parentId = this.getShape(id)?.parentId\n\t\t\t\t\t\t\t\twhile (isShapeId(parentId)) {\n\t\t\t\t\t\t\t\t\tif (next.selectedShapeIds.includes(parentId)) {\n\t\t\t\t\t\t\t\t\t\treturn false\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tparentId = this.getShape(parentId)?.parentId\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\treturn true\n\t\t\t\t\t\t\t})\n\n\t\t\t\t\t\t\tlet nextFocusedGroupId: null | TLShapeId = null\n\n\t\t\t\t\t\t\tif (filtered.length > 0) {\n\t\t\t\t\t\t\t\tconst commonGroupAncestor = this.findCommonAncestor(\n\t\t\t\t\t\t\t\t\tcompact(filtered.map((id) => this.getShape(id))),\n\t\t\t\t\t\t\t\t\t(shape) => this.isShapeOfType(shape, 'group')\n\t\t\t\t\t\t\t\t)\n\n\t\t\t\t\t\t\t\tif (commonGroupAncestor) {\n\t\t\t\t\t\t\t\t\tnextFocusedGroupId = commonGroupAncestor\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tif (next?.focusedGroupId) {\n\t\t\t\t\t\t\t\t\tnextFocusedGroupId = next.focusedGroupId\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\tfiltered.length !== next.selectedShapeIds.length ||\n\t\t\t\t\t\t\t\tnextFocusedGroupId !== next.focusedGroupId\n\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\tthis.store.put([\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t...next,\n\t\t\t\t\t\t\t\t\t\tselectedShapeIds: filtered,\n\t\t\t\t\t\t\t\t\t\tfocusedGroupId: nextFocusedGroupId ?? null,\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t])\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t})\n\t\t)\n\n\t\tthis._currentPageShapeIds = deriveShapeIdsInCurrentPage(this.store, () =>\n\t\t\tthis.getCurrentPageId()\n\t\t)\n\t\tthis._parentIdsToChildIds = parentsToChildren(this.store)\n\n\t\tthis.disposables.add(\n\t\t\tthis.store.listen((changes) => {\n\t\t\t\tthis.emit('change', changes)\n\t\t\t})\n\t\t)\n\t\tthis.disposables.add(this.history.dispose)\n\n\t\tthis.run(\n\t\t\t() => {\n\t\t\t\tthis.store.ensureStoreIsUsable()\n\n\t\t\t\t// clear ephemeral state\n\t\t\t\tthis._updateCurrentPageState({\n\t\t\t\t\teditingShapeId: null,\n\t\t\t\t\thoveredShapeId: null,\n\t\t\t\t\terasingShapeIds: [],\n\t\t\t\t})\n\t\t\t},\n\t\t\t{ history: 'ignore' }\n\t\t)\n\n\t\tif (initialState && this.root.children[initialState] === undefined) {\n\t\t\tthrow Error(`No state found for initialState \"${initialState}\".`)\n\t\t}\n\n\t\tthis.root.enter(undefined, 'initial')\n\n\t\tthis.edgeScrollManager = new EdgeScrollManager(this)\n\t\tthis.focusManager = new FocusManager(this, autoFocus)\n\t\tthis.disposables.add(this.focusManager.dispose.bind(this.focusManager))\n\n\t\tif (this.getInstanceState().followingUserId) {\n\t\t\tthis.stopFollowingUser()\n\t\t}\n\n\t\tthis.on('tick', this._flushEventsForTick)\n\n\t\tthis.timers.requestAnimationFrame(() => {\n\t\t\tthis._tickManager.start()\n\t\t})\n\n\t\tthis.performanceTracker = new PerformanceTracker()\n\n\t\tif (this.store.props.collaboration?.mode) {\n\t\t\tconst mode = this.store.props.collaboration.mode\n\t\t\tthis.disposables.add(\n\t\t\t\treact('update collaboration mode', () => {\n\t\t\t\t\tthis.store.put([{ ...this.getInstanceState(), isReadonly: mode.get() === 'readonly' }])\n\t\t\t\t})\n\t\t\t)\n\t\t}\n\t}\n\n\tprivate readonly _isShapeHiddenPredicate?: (shape: TLShape, editor: Editor) => boolean\n\t@computed\n\tprivate getIsShapeHiddenCache() {\n\t\tif (!this._isShapeHiddenPredicate) return null\n\t\treturn this.store.createComputedCache('isShapeHidden', (shape: TLShape) => {\n\t\t\tconst hiddenParent = this.findShapeAncestor(shape, (p) => this.isShapeHidden(p))\n\t\t\tif (hiddenParent) return true\n\t\t\treturn this._isShapeHiddenPredicate!(shape, this) ?? false\n\t\t})\n\t}\n\tisShapeHidden(shapeOrId: TLShape | TLShapeId): boolean {\n\t\tif (!this._isShapeHiddenPredicate) return false\n\t\treturn !!this.getIsShapeHiddenCache!()!.get(\n\t\t\ttypeof shapeOrId === 'string' ? shapeOrId : shapeOrId.id\n\t\t)\n\t}\n\n\treadonly options: TldrawOptions\n\n\treadonly contextId = uniqueId()\n\n\t/**\n\t * The editor's store\n\t *\n\t * @public\n\t */\n\treadonly store: TLStore\n\n\t/**\n\t * The root state of the statechart.\n\t *\n\t * @public\n\t */\n\treadonly root: StateNode\n\n\t/**\n\t * A set of functions to call when the app is disposed.\n\t *\n\t * @public\n\t */\n\treadonly disposables = new Set<() => void>()\n\n\t/**\n\t * Whether the editor is disposed.\n\t *\n\t * @public\n\t */\n\tisDisposed = false\n\n\t/** @internal */\n\tprivate readonly _tickManager\n\n\t/**\n\t * A manager for the app's snapping feature.\n\t *\n\t * @public\n\t */\n\treadonly snaps: SnapManager\n\n\t/**\n\t * A manager for the any asynchronous events and making sure they're\n\t * cleaned up upon disposal.\n\t *\n\t * @public\n\t */\n\treadonly timers = tltime.forContext(this.contextId)\n\n\t/**\n\t * A manager for the user and their preferences.\n\t *\n\t * @public\n\t */\n\treadonly user: UserPreferencesManager\n\n\t/**\n\t * A helper for measuring text.\n\t *\n\t * @public\n\t */\n\treadonly textMeasure: TextManager\n\n\t/**\n\t * A manager for the editor's environment.\n\t *\n\t * @deprecated This is deprecated and will be removed in a future version. Use the `tlenv` global export instead.\n\t * @public\n\t */\n\treadonly environment = tlenv\n\n\t/**\n\t * A manager for the editor's scribbles.\n\t *\n\t * @public\n\t */\n\treadonly scribbles: ScribbleManager\n\n\t/**\n\t * A manager for side effects and correct state enforcement. See {@link @tldraw/store#StoreSideEffects} for details.\n\t *\n\t * @public\n\t */\n\treadonly sideEffects: StoreSideEffects\n\n\t/**\n\t * A manager for moving the camera when the mouse is at the edge of the screen.\n\t *\n\t * @public\n\t */\n\tedgeScrollManager: EdgeScrollManager\n\n\t/**\n\t * A manager for ensuring correct focus. See FocusManager for details.\n\t *\n\t * @internal\n\t */\n\tprivate focusManager: FocusManager\n\n\t/**\n\t * The current HTML element containing the editor.\n\t *\n\t * @example\n\t * ```ts\n\t * const container = editor.getContainer()\n\t * ```\n\t *\n\t * @public\n\t */\n\tgetContainer: () => HTMLElement\n\n\t/**\n\t * Dispose the editor.\n\t *\n\t * @public\n\t */\n\tdispose() {\n\t\tthis.disposables.forEach((dispose) => dispose())\n\t\tthis.disposables.clear()\n\t\tthis.isDisposed = true\n\t}\n\n\t/* ------------------- Shape Utils ------------------ */\n\n\t/**\n\t * A map of shape utility classes (TLShapeUtils) by shape type.\n\t *\n\t * @public\n\t */\n\tshapeUtils: { readonly [K in string]?: ShapeUtil }\n\n\tstyleProps: { [key: string]: Map, string> }\n\n\t/**\n\t * Get a shape util from a shape itself.\n\t *\n\t * @example\n\t * ```ts\n\t * const util = editor.getShapeUtil(myArrowShape)\n\t * const util = editor.getShapeUtil('arrow')\n\t * const util = editor.getShapeUtil(myArrowShape)\n\t * const util = editor.getShapeUtil(TLArrowShape)('arrow')\n\t * ```\n\t *\n\t * @param shape - A shape, shape partial, or shape type.\n\t *\n\t * @public\n\t */\n\tgetShapeUtil(shape: S | TLShapePartial): ShapeUtil\n\tgetShapeUtil(type: S['type']): ShapeUtil\n\tgetShapeUtil(type: T extends ShapeUtil ? R['type'] : string): T\n\tgetShapeUtil(arg: string | { type: string }) {\n\t\tconst type = typeof arg === 'string' ? arg : arg.type\n\t\tconst shapeUtil = getOwnProperty(this.shapeUtils, type)\n\t\tassert(shapeUtil, `No shape util found for type \"${type}\"`)\n\t\treturn shapeUtil\n\t}\n\n\t/* ------------------- Binding Utils ------------------ */\n\t/**\n\t * A map of shape utility classes (TLShapeUtils) by shape type.\n\t *\n\t * @public\n\t */\n\tbindingUtils: { readonly [K in string]?: BindingUtil }\n\n\t/**\n\t * Get a binding util from a binding itself.\n\t *\n\t * @example\n\t * ```ts\n\t * const util = editor.getBindingUtil(myArrowBinding)\n\t * const util = editor.getBindingUtil('arrow')\n\t * const util = editor.getBindingUtil(myArrowBinding)\n\t * const util = editor.getBindingUtil(TLArrowBinding)('arrow')\n\t * ```\n\t *\n\t * @param binding - A binding, binding partial, or binding type.\n\t *\n\t * @public\n\t */\n\tgetBindingUtil(binding: S | { type: S['type'] }): BindingUtil\n\tgetBindingUtil(type: S['type']): BindingUtil\n\tgetBindingUtil(\n\t\ttype: T extends BindingUtil ? R['type'] : string\n\t): T\n\tgetBindingUtil(arg: string | { type: string }) {\n\t\tconst type = typeof arg === 'string' ? arg : arg.type\n\t\tconst bindingUtil = getOwnProperty(this.bindingUtils, type)\n\t\tassert(bindingUtil, `No binding util found for type \"${type}\"`)\n\t\treturn bindingUtil\n\t}\n\n\t/* --------------------- History -------------------- */\n\n\t/**\n\t * A manager for the app's history.\n\t *\n\t * @readonly\n\t */\n\tprotected readonly history: HistoryManager\n\n\t/**\n\t * Undo to the last mark.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.undo()\n\t * ```\n\t *\n\t * @public\n\t */\n\tundo(): this {\n\t\tthis._flushEventsForTick(0)\n\t\tthis.complete()\n\t\tthis.history.undo()\n\t\treturn this\n\t}\n\n\t/**\n\t * Whether the app can undo.\n\t *\n\t * @public\n\t */\n\t@computed getCanUndo(): boolean {\n\t\treturn this.history.getNumUndos() > 0\n\t}\n\n\t/**\n\t * Redo to the next mark.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.redo()\n\t * ```\n\t *\n\t * @public\n\t */\n\tredo(): this {\n\t\tthis._flushEventsForTick(0)\n\t\tthis.complete()\n\t\tthis.history.redo()\n\t\treturn this\n\t}\n\n\tclearHistory() {\n\t\tthis.history.clear()\n\t\treturn this\n\t}\n\n\t/**\n\t * Whether the app can redo.\n\t *\n\t * @public\n\t */\n\t@computed getCanRedo(): boolean {\n\t\treturn this.history.getNumRedos() > 0\n\t}\n\n\t/**\n\t * Create a new \"mark\", or stopping point, in the undo redo history. Creating a mark will clear\n\t * any redos.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.mark()\n\t * editor.mark('flip shapes')\n\t * ```\n\t *\n\t * @param markId - The mark's id, usually the reason for adding the mark.\n\t *\n\t * @public\n\t * @deprecated use {@link Editor.markHistoryStoppingPoint} instead\n\t */\n\tmark(markId?: string): this {\n\t\tif (typeof markId === 'string') {\n\t\t\tconsole.warn(\n\t\t\t\t`[tldraw] \\`editor.history.mark(\"${markId}\")\\` is deprecated. Please use \\`const myMarkId = editor.markHistoryStoppingPoint()\\` instead.`\n\t\t\t)\n\t\t} else {\n\t\t\tconsole.warn(\n\t\t\t\t'[tldraw] `editor.mark()` is deprecated. Use `editor.markHistoryStoppingPoint()` instead.'\n\t\t\t)\n\t\t}\n\t\tthis.history._mark(markId ?? uniqueId())\n\t\treturn this\n\t}\n\n\t/**\n\t * Create a new \"mark\", or stopping point, in the undo redo history. Creating a mark will clear\n\t * any redos. You typically want to do this just before a user interaction begins or is handled.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.markHistoryStoppingPoint()\n\t * editor.flipShapes(editor.getSelectedShapes())\n\t * ```\n\t * @example\n\t * ```ts\n\t * const beginRotateMark = editor.markHistoryStoppingPoint()\n\t * // if the use cancels the rotation, you can bail back to this mark\n\t * editor.bailToMark(beginRotateMark)\n\t * ```\n\t *\n\t * @public\n\t * @param name - The name of the mark, useful for debugging the undo/redo stacks\n\t * @returns a unique id for the mark that can be used with `squashToMark` or `bailToMark`.\n\t */\n\tmarkHistoryStoppingPoint(name?: string): string {\n\t\tconst id = `[${name ?? 'stop'}]_${uniqueId()}`\n\t\tthis.history._mark(id)\n\t\treturn id\n\t}\n\n\t/**\n\t * @internal this is only used to implement some backwards-compatibility logic. Should be fine to delete after 6 months or whatever.\n\t */\n\tgetMarkIdMatching(idSubstring: string) {\n\t\treturn this.history.getMarkIdMatching(idSubstring)\n\t}\n\n\t/**\n\t * Coalesces all changes since the given mark into a single change, removing any intermediate marks.\n\t *\n\t * This is useful if you need to 'compress' the recent history to simplify the undo/redo experience of a complex interaction.\n\t *\n\t * @example\n\t * ```ts\n\t * const bumpShapesMark = editor.markHistoryStoppingPoint()\n\t * // ... some changes\n\t * editor.squashToMark(bumpShapesMark)\n\t * ```\n\t *\n\t * @param markId - The mark id to squash to.\n\t */\n\tsquashToMark(markId: string): this {\n\t\tthis.history.squashToMark(markId)\n\t\treturn this\n\t}\n\n\t/**\n\t * Undo to the closest mark, discarding the changes so they cannot be redone.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.bail()\n\t * ```\n\t *\n\t * @public\n\t */\n\tbail() {\n\t\tthis.history.bail()\n\t\treturn this\n\t}\n\n\t/**\n\t * Undo to the given mark, discarding the changes so they cannot be redone.\n\t *\n\t * @example\n\t * ```ts\n\t * const beginDrag = editor.markHistoryStoppingPoint()\n\t * // ... some changes\n\t * editor.bailToMark(beginDrag)\n\t * ```\n\t *\n\t * @public\n\t */\n\tbailToMark(id: string): this {\n\t\tthis.history.bailToMark(id)\n\t\treturn this\n\t}\n\n\tprivate _shouldIgnoreShapeLock = false\n\n\t/**\n\t * Run a function in a transaction with optional options for context.\n\t * You can use the options to change the way that history is treated\n\t * or allow changes to locked shapes.\n\t *\n\t * @example\n\t * ```ts\n\t * // updating with\n\t * editor.run(() => {\n\t * \teditor.updateShape({ ...myShape, x: 100 })\n\t * }, { history: \"ignore\" })\n\t *\n\t * // forcing changes / deletions for locked shapes\n\t * editor.toggleLock([myShape])\n\t * editor.run(() => {\n\t * \teditor.updateShape({ ...myShape, x: 100 })\n\t * \teditor.deleteShape(myShape)\n\t * }, { ignoreShapeLock: true }, )\n\t * ```\n\t *\n\t * @param fn - The callback function to run.\n\t * @param opts - The options for the batch.\n\t *\n\t *\n\t * @public\n\t */\n\trun(fn: () => void, opts?: TLEditorRunOptions): this {\n\t\tconst previousIgnoreShapeLock = this._shouldIgnoreShapeLock\n\t\tthis._shouldIgnoreShapeLock = opts?.ignoreShapeLock ?? previousIgnoreShapeLock\n\n\t\ttry {\n\t\t\tthis.history.batch(fn, opts)\n\t\t} finally {\n\t\t\tthis._shouldIgnoreShapeLock = previousIgnoreShapeLock\n\t\t}\n\n\t\treturn this\n\t}\n\n\t/**\n\t * @deprecated Use `Editor.run` instead.\n\t */\n\tbatch(fn: () => void, opts?: TLEditorRunOptions): this {\n\t\treturn this.run(fn, opts)\n\t}\n\n\t/* --------------------- Errors --------------------- */\n\n\t/** @internal */\n\tannotateError(\n\t\terror: unknown,\n\t\t{\n\t\t\torigin,\n\t\t\twillCrashApp,\n\t\t\ttags,\n\t\t\textras,\n\t\t}: {\n\t\t\torigin: string\n\t\t\twillCrashApp: boolean\n\t\t\ttags?: Record\n\t\t\textras?: Record\n\t\t}\n\t): this {\n\t\tconst defaultAnnotations = this.createErrorAnnotations(origin, willCrashApp)\n\t\tannotateError(error, {\n\t\t\ttags: { ...defaultAnnotations.tags, ...tags },\n\t\t\textras: { ...defaultAnnotations.extras, ...extras },\n\t\t})\n\t\tif (willCrashApp) {\n\t\t\tthis.store.markAsPossiblyCorrupted()\n\t\t}\n\t\treturn this\n\t}\n\n\t/** @internal */\n\tcreateErrorAnnotations(\n\t\torigin: string,\n\t\twillCrashApp: boolean | 'unknown'\n\t): {\n\t\ttags: { origin: string; willCrashApp: boolean | 'unknown' }\n\t\textras: {\n\t\t\tactiveStateNode?: string\n\t\t\tselectedShapes?: TLUnknownShape[]\n\t\t\teditingShape?: TLUnknownShape\n\t\t\tinputs?: Record\n\t\t}\n\t} {\n\t\ttry {\n\t\t\tconst editingShapeId = this.getEditingShapeId()\n\t\t\treturn {\n\t\t\t\ttags: {\n\t\t\t\t\torigin: origin,\n\t\t\t\t\twillCrashApp,\n\t\t\t\t},\n\t\t\t\textras: {\n\t\t\t\t\tactiveStateNode: this.root.getPath(),\n\t\t\t\t\tselectedShapes: this.getSelectedShapes(),\n\t\t\t\t\teditingShape: editingShapeId ? this.getShape(editingShapeId) : undefined,\n\t\t\t\t\tinputs: this.inputs,\n\t\t\t\t},\n\t\t\t}\n\t\t} catch {\n\t\t\treturn {\n\t\t\t\ttags: {\n\t\t\t\t\torigin: origin,\n\t\t\t\t\twillCrashApp,\n\t\t\t\t},\n\t\t\t\textras: {},\n\t\t\t}\n\t\t}\n\t}\n\n\t/** @internal */\n\tprivate _crashingError: unknown | null = null\n\n\t/**\n\t * We can't use an `atom` here because there's a chance that when `crashAndReportError` is called,\n\t * we're in a transaction that's about to be rolled back due to the same error we're currently\n\t * reporting.\n\t *\n\t * Instead, to listen to changes to this value, you need to listen to app's `crash` event.\n\t *\n\t * @internal\n\t */\n\tgetCrashingError() {\n\t\treturn this._crashingError\n\t}\n\n\t/** @internal */\n\tcrash(error: unknown): this {\n\t\tthis._crashingError = error\n\t\tthis.store.markAsPossiblyCorrupted()\n\t\tthis.emit('crash', { error })\n\t\treturn this\n\t}\n\n\t/* ------------------- Statechart ------------------- */\n\n\t/**\n\t * The editor's current path of active states.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getPath() // \"select.idle\"\n\t * ```\n\t *\n\t * @public\n\t */\n\t@computed getPath() {\n\t\treturn this.root.getPath().split('root.')[1]\n\t}\n\n\t/**\n\t * Get whether a certain tool (or other state node) is currently active.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.isIn('select')\n\t * editor.isIn('select.brushing')\n\t * ```\n\t *\n\t * @param path - The path of active states, separated by periods.\n\t *\n\t * @public\n\t */\n\tisIn(path: string): boolean {\n\t\tconst ids = path.split('.').reverse()\n\t\tlet state = this.root as StateNode\n\t\twhile (ids.length > 0) {\n\t\t\tconst id = ids.pop()\n\t\t\tif (!id) return true\n\t\t\tconst current = state.getCurrent()\n\t\t\tif (current?.id === id) {\n\t\t\t\tif (ids.length === 0) return true\n\t\t\t\tstate = current\n\t\t\t\tcontinue\n\t\t\t} else return false\n\t\t}\n\t\treturn false\n\t}\n\n\t/**\n\t * Get whether the state node is in any of the given active paths.\n\t *\n\t * @example\n\t * ```ts\n\t * state.isInAny('select', 'erase')\n\t * state.isInAny('select.brushing', 'erase.idle')\n\t * ```\n\t *\n\t * @public\n\t */\n\tisInAny(...paths: string[]): boolean {\n\t\treturn paths.some((path) => this.isIn(path))\n\t}\n\n\t/**\n\t * Set the selected tool.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.setCurrentTool('hand')\n\t * editor.setCurrentTool('hand', { date: Date.now() })\n\t * ```\n\t *\n\t * @param id - The id of the tool to select.\n\t * @param info - Arbitrary data to pass along into the transition.\n\t *\n\t * @public\n\t */\n\tsetCurrentTool(id: string, info = {}): this {\n\t\tthis.root.transition(id, info)\n\t\treturn this\n\t}\n\n\t/**\n\t * The current selected tool.\n\t *\n\t * @public\n\t */\n\t@computed getCurrentTool(): StateNode {\n\t\treturn this.root.getCurrent()!\n\t}\n\n\t/**\n\t * The id of the current selected tool.\n\t *\n\t * @public\n\t */\n\t@computed getCurrentToolId(): string {\n\t\tconst currentTool = this.getCurrentTool()\n\t\tif (!currentTool) return ''\n\t\treturn currentTool.getCurrentToolIdMask() ?? currentTool.id\n\t}\n\n\t/**\n\t * Get a descendant by its path.\n\t *\n\t * @example\n\t * ```ts\n\t * state.getStateDescendant('select')\n\t * state.getStateDescendant('select.brushing')\n\t * ```\n\t *\n\t * @param path - The descendant's path of state ids, separated by periods.\n\t *\n\t * @public\n\t */\n\tgetStateDescendant(path: string): T | undefined {\n\t\tconst ids = path.split('.').reverse()\n\t\tlet state = this.root as StateNode\n\t\twhile (ids.length > 0) {\n\t\t\tconst id = ids.pop()\n\t\t\tif (!id) return state as T\n\t\t\tconst childState = state.children?.[id]\n\t\t\tif (!childState) return undefined\n\t\t\tstate = childState\n\t\t}\n\t\treturn state as T\n\t}\n\n\t/* ---------------- Document Settings --------------- */\n\n\t/**\n\t * The global document settings that apply to all users.\n\t *\n\t * @public\n\t **/\n\t@computed getDocumentSettings() {\n\t\treturn this.store.get(TLDOCUMENT_ID)!\n\t}\n\n\t/**\n\t * Update the global document settings that apply to all users.\n\t *\n\t * @public\n\t **/\n\tupdateDocumentSettings(settings: Partial): this {\n\t\tthis.run(\n\t\t\t() => {\n\t\t\t\tthis.store.put([{ ...this.getDocumentSettings(), ...settings }])\n\t\t\t},\n\t\t\t{ history: 'ignore' }\n\t\t)\n\t\treturn this\n\t}\n\n\t/* ----------------- Instance State ----------------- */\n\n\t/**\n\t * The current instance's state.\n\t *\n\t * @public\n\t */\n\t@computed getInstanceState(): TLInstance {\n\t\treturn this.store.get(TLINSTANCE_ID)!\n\t}\n\n\t/**\n\t * Update the instance's state.\n\t *\n\t * @param partial - A partial object to update the instance state with.\n\t * @param historyOptions - History batch options.\n\t *\n\t * @public\n\t */\n\tupdateInstanceState(\n\t\tpartial: Partial>,\n\t\thistoryOptions?: TLHistoryBatchOptions\n\t): this {\n\t\tthis._updateInstanceState(partial, { history: 'ignore', ...historyOptions })\n\n\t\tif (partial.isChangingStyle !== undefined) {\n\t\t\tclearTimeout(this._isChangingStyleTimeout)\n\t\t\tif (partial.isChangingStyle === true) {\n\t\t\t\t// If we've set to true, set a new reset timeout to change the value back to false after 2 seconds\n\t\t\t\tthis._isChangingStyleTimeout = this.timers.setTimeout(() => {\n\t\t\t\t\tthis._updateInstanceState({ isChangingStyle: false }, { history: 'ignore' })\n\t\t\t\t}, 2000)\n\t\t\t}\n\t\t}\n\n\t\treturn this\n\t}\n\n\t/** @internal */\n\t_updateInstanceState(\n\t\tpartial: Partial>,\n\t\topts?: TLHistoryBatchOptions\n\t) {\n\t\tthis.run(() => {\n\t\t\tthis.store.put([\n\t\t\t\t{\n\t\t\t\t\t...this.getInstanceState(),\n\t\t\t\t\t...partial,\n\t\t\t\t},\n\t\t\t])\n\t\t}, opts)\n\t}\n\n\t/** @internal */\n\tprivate _isChangingStyleTimeout = -1 as any\n\n\t// Menus\n\n\tmenus = tlmenus.forContext(this.contextId)\n\n\t/**\n\t * @deprecated Use `editor.menus.getOpenMenus` instead.\n\t *\n\t * @public\n\t */\n\t@computed getOpenMenus(): string[] {\n\t\treturn this.menus.getOpenMenus()\n\t}\n\n\t/**\n\t * @deprecated Use `editor.menus.addOpenMenu` instead.\n\t *\n\t * @public\n\t */\n\taddOpenMenu(id: string): this {\n\t\tthis.menus.addOpenMenu(id)\n\t\treturn this\n\t}\n\n\t/**\n\t * @deprecated Use `editor.menus.deleteOpenMenu` instead.\n\t *\n\t * @public\n\t */\n\tdeleteOpenMenu(id: string): this {\n\t\tthis.menus.deleteOpenMenu(id)\n\t\treturn this\n\t}\n\n\t/**\n\t * @deprecated Use `editor.menus.clearOpenMenus` instead.\n\t *\n\t * @public\n\t */\n\tclearOpenMenus(): this {\n\t\tthis.menus.clearOpenMenus()\n\t\treturn this\n\t}\n\n\t/**\n\t * @deprecated Use `editor.menus.hasAnyOpenMenus` instead.\n\t *\n\t * @public\n\t */\n\t@computed getIsMenuOpen(): boolean {\n\t\treturn this.menus.hasAnyOpenMenus()\n\t}\n\n\t/* --------------------- Cursor --------------------- */\n\n\t/**\n\t * Set the cursor.\n\t *\n\t * @param cursor - The cursor to set.\n\t * @public\n\t */\n\tsetCursor(cursor: Partial) {\n\t\tthis.updateInstanceState({ cursor: { ...this.getInstanceState().cursor, ...cursor } })\n\t\treturn this\n\t}\n\n\t/* ------------------- Page State ------------------- */\n\n\t/**\n\t * Page states.\n\t *\n\t * @public\n\t */\n\t@computed getPageStates(): TLInstancePageState[] {\n\t\treturn this._getPageStatesQuery().get()\n\t}\n\n\t/** @internal */\n\t@computed private _getPageStatesQuery() {\n\t\treturn this.store.query.records('instance_page_state')\n\t}\n\n\t/**\n\t * The current page state.\n\t *\n\t * @public\n\t */\n\t@computed getCurrentPageState(): TLInstancePageState {\n\t\treturn this.store.get(this._getCurrentPageStateId())!\n\t}\n\n\t/** @internal */\n\t@computed private _getCurrentPageStateId() {\n\t\treturn InstancePageStateRecordType.createId(this.getCurrentPageId())\n\t}\n\n\t/**\n\t * Update this instance's page state.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.updateCurrentPageState({ id: 'page1', editingShapeId: 'shape:123' })\n\t * ```\n\t *\n\t * @param partial - The partial of the page state object containing the changes.\n\t *\n\t * @public\n\t */\n\tupdateCurrentPageState(\n\t\tpartial: Partial<\n\t\t\tOmit\n\t\t>\n\t): this {\n\t\tthis._updateCurrentPageState(partial)\n\t\treturn this\n\t}\n\t_updateCurrentPageState(partial: Partial>) {\n\t\tthis.store.update(partial.id ?? this.getCurrentPageState().id, (state) => ({\n\t\t\t...state,\n\t\t\t...partial,\n\t\t}))\n\t}\n\n\t/**\n\t * The current selected ids.\n\t *\n\t * @public\n\t */\n\t@computed getSelectedShapeIds() {\n\t\treturn this.getCurrentPageState().selectedShapeIds\n\t}\n\n\t/**\n\t * An array containing all of the currently selected shapes.\n\t *\n\t * @public\n\t * @readonly\n\t */\n\t@computed getSelectedShapes(): TLShape[] {\n\t\tconst { selectedShapeIds } = this.getCurrentPageState()\n\t\treturn compact(selectedShapeIds.map((id) => this.store.get(id)))\n\t}\n\n\t/**\n\t * Select one or more shapes.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.setSelectedShapes(['id1'])\n\t * editor.setSelectedShapes(['id1', 'id2'])\n\t * ```\n\t *\n\t * @param shapes - The shape (or shape ids) to select.\n\t *\n\t * @public\n\t */\n\tsetSelectedShapes(shapes: TLShapeId[] | TLShape[]): this {\n\t\treturn this.run(\n\t\t\t() => {\n\t\t\t\tconst ids = shapes.map((shape) => (typeof shape === 'string' ? shape : shape.id))\n\t\t\t\tconst { selectedShapeIds: prevSelectedShapeIds } = this.getCurrentPageState()\n\t\t\t\tconst prevSet = new Set(prevSelectedShapeIds)\n\n\t\t\t\tif (ids.length === prevSet.size && ids.every((id) => prevSet.has(id))) return null\n\n\t\t\t\tthis.store.put([{ ...this.getCurrentPageState(), selectedShapeIds: ids }])\n\t\t\t},\n\t\t\t{ history: 'record-preserveRedoStack' }\n\t\t)\n\t}\n\n\t/**\n\t * Determine whether or not any of a shape's ancestors are selected.\n\t *\n\t * @param shape - The shape (or shape id) of the shape to check.\n\t *\n\t * @public\n\t */\n\tisAncestorSelected(shape: TLShape | TLShapeId): boolean {\n\t\tconst id = typeof shape === 'string' ? shape : shape?.id ?? null\n\t\tconst _shape = this.getShape(id)\n\t\tif (!_shape) return false\n\t\tconst selectedShapeIds = this.getSelectedShapeIds()\n\t\treturn !!this.findShapeAncestor(_shape, (parent) => selectedShapeIds.includes(parent.id))\n\t}\n\n\t/**\n\t * Select one or more shapes.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.select('id1')\n\t * editor.select('id1', 'id2')\n\t * ```\n\t *\n\t * @param shapes - The shape (or the shape ids) to select.\n\t *\n\t * @public\n\t */\n\tselect(...shapes: TLShapeId[] | TLShape[]): this {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((shape) => shape.id)\n\t\tthis.setSelectedShapes(ids)\n\t\treturn this\n\t}\n\n\t/**\n\t * Remove a shape from the existing set of selected shapes.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.deselect(shape.id)\n\t * ```\n\t *\n\t * @public\n\t */\n\tdeselect(...shapes: TLShapeId[] | TLShape[]): this {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((shape) => shape.id)\n\t\tconst selectedShapeIds = this.getSelectedShapeIds()\n\t\tif (selectedShapeIds.length > 0 && ids.length > 0) {\n\t\t\tthis.setSelectedShapes(selectedShapeIds.filter((id) => !ids.includes(id)))\n\t\t}\n\t\treturn this\n\t}\n\n\t/**\n\t * Select all direct children of the current page.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.selectAll()\n\t * ```\n\t *\n\t * @public\n\t */\n\tselectAll(): this {\n\t\tconst ids = this.getSortedChildIdsForParent(this.getCurrentPageId())\n\t\t// page might have no shapes\n\t\tif (ids.length <= 0) return this\n\t\tthis.setSelectedShapes(this._getUnlockedShapeIds(ids))\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Clear the selection.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.selectNone()\n\t * ```\n\t *\n\t * @public\n\t */\n\tselectNone(): this {\n\t\tif (this.getSelectedShapeIds().length > 0) {\n\t\t\tthis.setSelectedShapes([])\n\t\t}\n\n\t\treturn this\n\t}\n\n\t/**\n\t * The id of the app's only selected shape.\n\t *\n\t * @returns Null if there is no shape or more than one selected shape, otherwise the selected shape's id.\n\t *\n\t * @public\n\t * @readonly\n\t */\n\t@computed getOnlySelectedShapeId(): TLShapeId | null {\n\t\treturn this.getOnlySelectedShape()?.id ?? null\n\t}\n\n\t/**\n\t * The app's only selected shape.\n\t *\n\t * @returns Null if there is no shape or more than one selected shape, otherwise the selected shape.\n\t *\n\t * @public\n\t * @readonly\n\t */\n\t@computed getOnlySelectedShape(): TLShape | null {\n\t\tconst selectedShapes = this.getSelectedShapes()\n\t\treturn selectedShapes.length === 1 ? selectedShapes[0] : null\n\t}\n\n\t/**\n\t * @internal\n\t */\n\tgetShapesPageBounds(shapeIds: TLShapeId[]): Box | null {\n\t\tconst bounds = compact(shapeIds.map((id) => this.getShapePageBounds(id)))\n\t\tif (bounds.length === 0) return null\n\t\treturn Box.Common(bounds)\n\t}\n\n\t/**\n\t * The current page bounds of all the selected shapes. If the\n\t * selection is rotated, then these bounds are the axis-aligned\n\t * box that the rotated bounds would fit inside of.\n\t *\n\t * @readonly\n\t *\n\t * @public\n\t */\n\t@computed getSelectionPageBounds(): Box | null {\n\t\treturn this.getShapesPageBounds(this.getSelectedShapeIds())\n\t}\n\n\t/**\n\t * @internal\n\t */\n\tgetShapesSharedRotation(shapeIds: TLShapeId[]) {\n\t\tlet foundFirst = false // annoying but we can't use an i===0 check because we need to skip over undefineds\n\t\tlet rotation = 0\n\t\tfor (let i = 0, n = shapeIds.length; i < n; i++) {\n\t\t\tconst pageTransform = this.getShapePageTransform(shapeIds[i])\n\t\t\tif (!pageTransform) continue\n\t\t\tif (foundFirst) {\n\t\t\t\tif (pageTransform.rotation() !== rotation) {\n\t\t\t\t\t// There are at least 2 different rotations, so the common rotation is zero\n\t\t\t\t\treturn 0\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// First rotation found\n\t\t\t\tfoundFirst = true\n\t\t\t\trotation = pageTransform.rotation()\n\t\t\t}\n\t\t}\n\n\t\treturn rotation\n\t}\n\n\t/**\n\t * The rotation of the selection bounding box in the current page space.\n\t *\n\t * @readonly\n\t * @public\n\t */\n\t@computed getSelectionRotation(): number {\n\t\treturn this.getShapesSharedRotation(this.getSelectedShapeIds())\n\t}\n\n\t/**\n\t * @internal\n\t */\n\tgetShapesRotatedPageBounds(shapeIds: TLShapeId[]): Box | undefined {\n\t\tif (shapeIds.length === 0) {\n\t\t\treturn undefined\n\t\t}\n\n\t\tconst selectionRotation = this.getShapesSharedRotation(shapeIds)\n\t\tif (selectionRotation === 0) {\n\t\t\treturn this.getShapesPageBounds(shapeIds) ?? undefined\n\t\t}\n\n\t\tif (shapeIds.length === 1) {\n\t\t\tconst bounds = this.getShapeGeometry(shapeIds[0]).bounds.clone()\n\t\t\tconst pageTransform = this.getShapePageTransform(shapeIds[0])!\n\t\t\tbounds.point = pageTransform.applyToPoint(bounds.point)\n\t\t\treturn bounds\n\t\t}\n\n\t\t// need to 'un-rotate' all the outlines of the existing nodes so we can fit them inside a box\n\t\tconst boxFromRotatedVertices = Box.FromPoints(\n\t\t\tshapeIds\n\t\t\t\t.flatMap((id) => {\n\t\t\t\t\tconst pageTransform = this.getShapePageTransform(id)\n\t\t\t\t\tif (!pageTransform) return []\n\t\t\t\t\treturn pageTransform.applyToPoints(this.getShapeGeometry(id).bounds.corners)\n\t\t\t\t})\n\t\t\t\t.map((p) => p.rot(-selectionRotation))\n\t\t)\n\t\t// now position box so that it's top-left corner is in the right place\n\t\tboxFromRotatedVertices.point = boxFromRotatedVertices.point.rot(selectionRotation)\n\t\treturn boxFromRotatedVertices\n\t}\n\n\t/**\n\t * The bounds of the selection bounding box in the current page space.\n\t *\n\t * @readonly\n\t * @public\n\t */\n\t@computed getSelectionRotatedPageBounds(): Box | undefined {\n\t\treturn this.getShapesRotatedPageBounds(this.getSelectedShapeIds())\n\t}\n\n\t/**\n\t * The bounds of the selection bounding box in the current page space.\n\t *\n\t * @readonly\n\t * @public\n\t */\n\t@computed getSelectionRotatedScreenBounds(): Box | undefined {\n\t\tconst bounds = this.getSelectionRotatedPageBounds()\n\t\tif (!bounds) return undefined\n\t\tconst { x, y } = this.pageToScreen(bounds.point)\n\t\tconst zoom = this.getZoomLevel()\n\t\treturn new Box(x, y, bounds.width * zoom, bounds.height * zoom)\n\t}\n\n\t// Focus Group\n\n\t/**\n\t * The current focused group id.\n\t *\n\t * @public\n\t */\n\t@computed getFocusedGroupId(): TLShapeId | TLPageId {\n\t\treturn this.getCurrentPageState().focusedGroupId ?? this.getCurrentPageId()\n\t}\n\n\t/**\n\t * The current focused group.\n\t *\n\t * @public\n\t */\n\t@computed getFocusedGroup(): TLShape | undefined {\n\t\tconst focusedGroupId = this.getFocusedGroupId()\n\t\treturn focusedGroupId ? this.getShape(focusedGroupId) : undefined\n\t}\n\n\t/**\n\t * Set the current focused group shape.\n\t *\n\t * @param shape - The group shape id (or group shape's id) to set as the focused group shape.\n\t *\n\t * @public\n\t */\n\tsetFocusedGroup(shape: TLShapeId | TLGroupShape | null): this {\n\t\tconst id = typeof shape === 'string' ? shape : shape?.id ?? null\n\n\t\tif (id !== null) {\n\t\t\tconst shape = this.getShape(id)\n\t\t\tif (!shape) {\n\t\t\t\tthrow Error(`Editor.setFocusedGroup: Shape with id ${id} does not exist`)\n\t\t\t}\n\n\t\t\tif (!this.isShapeOfType(shape, 'group')) {\n\t\t\t\tthrow Error(\n\t\t\t\t\t`Editor.setFocusedGroup: Cannot set focused group to shape of type ${shape.type}`\n\t\t\t\t)\n\t\t\t}\n\t\t}\n\n\t\tif (id === this.getFocusedGroupId()) return this\n\n\t\treturn this.run(\n\t\t\t() => {\n\t\t\t\tthis.store.update(this.getCurrentPageState().id, (s) => ({ ...s, focusedGroupId: id }))\n\t\t\t},\n\t\t\t{ history: 'record-preserveRedoStack' }\n\t\t)\n\t}\n\n\t/**\n\t * Exit the current focused group, moving up to the next parent group if there is one.\n\t *\n\t * @public\n\t */\n\tpopFocusedGroupId(): this {\n\t\tconst focusedGroup = this.getFocusedGroup()\n\n\t\tif (focusedGroup) {\n\t\t\t// If we have a focused layer, look for an ancestor of the focused shape that is a group\n\t\t\tconst match = this.findShapeAncestor(focusedGroup, (shape) =>\n\t\t\t\tthis.isShapeOfType(shape, 'group')\n\t\t\t)\n\t\t\t// If we have an ancestor that can become a focused layer, set it as the focused layer\n\t\t\tthis.setFocusedGroup(match?.id ?? null)\n\t\t\tthis.select(focusedGroup.id)\n\t\t} else {\n\t\t\t// If there's no parent focused group, then clear the focus layer and clear selection\n\t\t\tthis.setFocusedGroup(null)\n\t\t\tthis.selectNone()\n\t\t}\n\n\t\treturn this\n\t}\n\n\t/**\n\t * The current editing shape's id.\n\t *\n\t * @public\n\t */\n\t@computed getEditingShapeId(): TLShapeId | null {\n\t\treturn this.getCurrentPageState().editingShapeId\n\t}\n\n\t/**\n\t * The current editing shape.\n\t *\n\t * @public\n\t */\n\t@computed getEditingShape(): TLShape | undefined {\n\t\tconst editingShapeId = this.getEditingShapeId()\n\t\treturn editingShapeId ? this.getShape(editingShapeId) : undefined\n\t}\n\n\t/**\n\t * Set the current editing shape.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.setEditingShape(myShape)\n\t * editor.setEditingShape(myShape.id)\n\t * ```\n\t *\n\t * @param shape - The shape (or shape id) to set as editing.\n\t *\n\t * @public\n\t */\n\tsetEditingShape(shape: TLShapeId | TLShape | null): this {\n\t\tconst id = typeof shape === 'string' ? shape : shape?.id ?? null\n\t\tif (id !== this.getEditingShapeId()) {\n\t\t\tif (id) {\n\t\t\t\tconst shape = this.getShape(id)\n\t\t\t\tif (shape && this.getShapeUtil(shape).canEdit(shape)) {\n\t\t\t\t\tthis.run(\n\t\t\t\t\t\t() => {\n\t\t\t\t\t\t\tthis._updateCurrentPageState({ editingShapeId: id })\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{ history: 'ignore' }\n\t\t\t\t\t)\n\t\t\t\t\treturn this\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Either we just set the editing id to null, or the shape was missing or not editable\n\t\t\tthis.run(\n\t\t\t\t() => {\n\t\t\t\t\tthis._updateCurrentPageState({ editingShapeId: null })\n\t\t\t\t},\n\t\t\t\t{ history: 'ignore' }\n\t\t\t)\n\t\t}\n\t\treturn this\n\t}\n\n\t// Hovered\n\n\t/**\n\t * The current hovered shape id.\n\t *\n\t * @readonly\n\t * @public\n\t */\n\t@computed getHoveredShapeId(): TLShapeId | null {\n\t\treturn this.getCurrentPageState().hoveredShapeId\n\t}\n\n\t/**\n\t * The current hovered shape.\n\t *\n\t * @public\n\t */\n\t@computed getHoveredShape(): TLShape | undefined {\n\t\tconst hoveredShapeId = this.getHoveredShapeId()\n\t\treturn hoveredShapeId ? this.getShape(hoveredShapeId) : undefined\n\t}\n\t/**\n\t * Set the editor's current hovered shape.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.setHoveredShape(myShape)\n\t * editor.setHoveredShape(myShape.id)\n\t * ```\n\t *\n\t * @param shape - The shape (or shape id) to set as hovered.\n\t *\n\t * @public\n\t */\n\tsetHoveredShape(shape: TLShapeId | TLShape | null): this {\n\t\tconst id = typeof shape === 'string' ? shape : shape?.id ?? null\n\t\tif (id === this.getHoveredShapeId()) return this\n\t\tthis.run(\n\t\t\t() => {\n\t\t\t\tthis.updateCurrentPageState({ hoveredShapeId: id })\n\t\t\t},\n\t\t\t{ history: 'ignore' }\n\t\t)\n\t\treturn this\n\t}\n\n\t// Hinting\n\n\t/**\n\t * The editor's current hinting shape ids.\n\t *\n\t * @public\n\t */\n\t@computed getHintingShapeIds() {\n\t\treturn this.getCurrentPageState().hintingShapeIds\n\t}\n\t/**\n\t * The editor's current hinting shapes.\n\t *\n\t * @public\n\t */\n\t@computed getHintingShape() {\n\t\tconst hintingShapeIds = this.getHintingShapeIds()\n\t\treturn compact(hintingShapeIds.map((id) => this.getShape(id)))\n\t}\n\n\t/**\n\t * Set the editor's current hinting shapes.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.setHintingShapes([myShape])\n\t * editor.setHintingShapes([myShape.id])\n\t * ```\n\t *\n\t * @param shapes - The shapes (or shape ids) to set as hinting.\n\t *\n\t * @public\n\t */\n\tsetHintingShapes(shapes: TLShapeId[] | TLShape[]): this {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((shape) => shape.id)\n\t\t// always ephemeral\n\t\tthis.run(\n\t\t\t() => {\n\t\t\t\tthis._updateCurrentPageState({ hintingShapeIds: dedupe(ids) })\n\t\t\t},\n\t\t\t{ history: 'ignore' }\n\t\t)\n\t\treturn this\n\t}\n\n\t// Erasing\n\n\t/**\n\t * The editor's current erasing ids.\n\t *\n\t * @public\n\t */\n\t@computed getErasingShapeIds() {\n\t\treturn this.getCurrentPageState().erasingShapeIds\n\t}\n\n\t/**\n\t * The editor's current erasing shapes.\n\t *\n\t * @public\n\t */\n\t@computed getErasingShapes() {\n\t\tconst erasingShapeIds = this.getErasingShapeIds()\n\t\treturn compact(erasingShapeIds.map((id) => this.getShape(id)))\n\t}\n\n\t/**\n\t * Set the editor's current erasing shapes.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.setErasingShapes([myShape])\n\t * editor.setErasingShapes([myShape.id])\n\t * ```\n\t *\n\t * @param shapes - The shapes (or shape ids) to set as hinting.\n\t *\n\t * @public\n\t */\n\tsetErasingShapes(shapes: TLShapeId[] | TLShape[]): this {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((shape) => shape.id)\n\t\tids.sort() // sort the incoming ids\n\t\tconst erasingShapeIds = this.getErasingShapeIds()\n\t\tthis.run(\n\t\t\t() => {\n\t\t\t\tif (ids.length === erasingShapeIds.length) {\n\t\t\t\t\t// if the new ids are the same length as the current ids, they might be the same.\n\t\t\t\t\t// presuming the current ids are also sorted, check each item to see if it's the same;\n\t\t\t\t\t// if we find any unequal, then we know the new ids are different.\n\t\t\t\t\tfor (let i = 0; i < ids.length; i++) {\n\t\t\t\t\t\tif (ids[i] !== erasingShapeIds[i]) {\n\t\t\t\t\t\t\tthis._updateCurrentPageState({ erasingShapeIds: ids })\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t// if the ids are a different length, then we know they're different.\n\t\t\t\t\tthis._updateCurrentPageState({ erasingShapeIds: ids })\n\t\t\t\t}\n\t\t\t},\n\t\t\t{ history: 'ignore' }\n\t\t)\n\n\t\treturn this\n\t}\n\n\t// Cropping\n\n\t/**\n\t * The current cropping shape's id.\n\t *\n\t * @public\n\t */\n\tgetCroppingShapeId() {\n\t\treturn this.getCurrentPageState().croppingShapeId\n\t}\n\n\t/**\n\t * Set the current cropping shape.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.setCroppingShape(myShape)\n\t * editor.setCroppingShape(myShape.id)\n\t * ```\n\t *\n\t *\n\t * @param shape - The shape (or shape id) to set as cropping.\n\t *\n\t * @public\n\t */\n\tsetCroppingShape(shape: TLShapeId | TLShape | null): this {\n\t\tconst id = typeof shape === 'string' ? shape : shape?.id ?? null\n\t\tif (id !== this.getCroppingShapeId()) {\n\t\t\tthis.run(\n\t\t\t\t() => {\n\t\t\t\t\tif (!id) {\n\t\t\t\t\t\tthis.updateCurrentPageState({ croppingShapeId: null })\n\t\t\t\t\t} else {\n\t\t\t\t\t\tconst shape = this.getShape(id)!\n\t\t\t\t\t\tconst util = this.getShapeUtil(shape)\n\t\t\t\t\t\tif (shape && util.canCrop(shape)) {\n\t\t\t\t\t\t\tthis.updateCurrentPageState({ croppingShapeId: id })\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\t{ history: 'ignore' }\n\t\t\t)\n\t\t}\n\t\treturn this\n\t}\n\n\t/* --------------------- Camera --------------------- */\n\n\t/** @internal */\n\t@computed\n\tprivate _unsafe_getCameraId() {\n\t\treturn CameraRecordType.createId(this.getCurrentPageId())\n\t}\n\n\t/**\n\t * The current camera.\n\t *\n\t * @public\n\t */\n\t@computed getCamera(): TLCamera {\n\t\tconst baseCamera = this.store.get(this._unsafe_getCameraId())!\n\t\tif (this._isLockedOnFollowingUser.get()) {\n\t\t\tconst followingCamera = this.getCameraForFollowing()\n\t\t\tif (followingCamera) {\n\t\t\t\treturn { ...baseCamera, ...followingCamera }\n\t\t\t}\n\t\t}\n\t\treturn baseCamera\n\t}\n\n\t@computed\n\tprivate getViewportPageBoundsForFollowing(): null | Box {\n\t\tconst followingUserId = this.getInstanceState().followingUserId\n\t\tif (!followingUserId) return null\n\t\tconst leaderPresence = this.getCollaborators().find((c) => c.userId === followingUserId)\n\t\tif (!leaderPresence) return null\n\n\t\t// Fit their viewport inside of our screen bounds\n\t\t// 1. calculate their viewport in page space\n\t\tconst { w: lw, h: lh } = leaderPresence.screenBounds\n\t\tconst { x: lx, y: ly, z: lz } = leaderPresence.camera\n\t\tconst theirViewport = new Box(-lx, -ly, lw / lz, lh / lz)\n\n\t\t// resize our screenBounds to contain their viewport\n\t\tconst ourViewport = this.getViewportScreenBounds().clone()\n\t\tconst ourAspectRatio = ourViewport.width / ourViewport.height\n\n\t\tourViewport.width = theirViewport.width\n\t\tourViewport.height = ourViewport.width / ourAspectRatio\n\t\tif (ourViewport.height < theirViewport.height) {\n\t\t\tourViewport.height = theirViewport.height\n\t\t\tourViewport.width = ourViewport.height * ourAspectRatio\n\t\t}\n\n\t\tourViewport.center = theirViewport.center\n\t\treturn ourViewport\n\t}\n\n\t@computed\n\tprivate getCameraForFollowing(): null | { x: number; y: number; z: number } {\n\t\tconst viewport = this.getViewportPageBoundsForFollowing()\n\t\tif (!viewport) return null\n\n\t\treturn {\n\t\t\tx: -viewport.x,\n\t\t\ty: -viewport.y,\n\t\t\tz: this.getViewportScreenBounds().w / viewport.width,\n\t\t}\n\t}\n\n\t/**\n\t * The current camera zoom level.\n\t *\n\t * @public\n\t */\n\t@computed getZoomLevel() {\n\t\treturn this.getCamera().z\n\t}\n\n\t/**\n\t * Get the camera's initial or reset zoom level.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getInitialZoom()\n\t * ```\n\t *\n\t * @public */\n\tgetInitialZoom() {\n\t\tconst cameraOptions = this.getCameraOptions()\n\t\t// If no camera constraints are provided, the default zoom is 100%\n\t\tif (!cameraOptions.constraints) return 1\n\n\t\t// When defaultZoom is default, the default zoom is 100%\n\t\tif (cameraOptions.constraints.initialZoom === 'default') return 1\n\n\t\tconst { zx, zy } = getCameraFitXFitY(this, cameraOptions)\n\n\t\tswitch (cameraOptions.constraints.initialZoom) {\n\t\t\tcase 'fit-min': {\n\t\t\t\treturn Math.max(zx, zy)\n\t\t\t}\n\t\t\tcase 'fit-max': {\n\t\t\t\treturn Math.min(zx, zy)\n\t\t\t}\n\t\t\tcase 'fit-x': {\n\t\t\t\treturn zx\n\t\t\t}\n\t\t\tcase 'fit-y': {\n\t\t\t\treturn zy\n\t\t\t}\n\t\t\tcase 'fit-min-100': {\n\t\t\t\treturn Math.min(1, Math.max(zx, zy))\n\t\t\t}\n\t\t\tcase 'fit-max-100': {\n\t\t\t\treturn Math.min(1, Math.min(zx, zy))\n\t\t\t}\n\t\t\tcase 'fit-x-100': {\n\t\t\t\treturn Math.min(1, zx)\n\t\t\t}\n\t\t\tcase 'fit-y-100': {\n\t\t\t\treturn Math.min(1, zy)\n\t\t\t}\n\t\t\tdefault: {\n\t\t\t\tthrow exhaustiveSwitchError(cameraOptions.constraints.initialZoom)\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Get the camera's base level for calculating actual zoom levels based on the zoom steps.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getBaseZoom()\n\t * ```\n\t *\n\t * @public */\n\tgetBaseZoom() {\n\t\tconst cameraOptions = this.getCameraOptions()\n\t\t// If no camera constraints are provided, the default zoom is 100%\n\t\tif (!cameraOptions.constraints) return 1\n\n\t\t// When defaultZoom is default, the default zoom is 100%\n\t\tif (cameraOptions.constraints.baseZoom === 'default') return 1\n\n\t\tconst { zx, zy } = getCameraFitXFitY(this, cameraOptions)\n\n\t\tswitch (cameraOptions.constraints.baseZoom) {\n\t\t\tcase 'fit-min': {\n\t\t\t\treturn Math.max(zx, zy)\n\t\t\t}\n\t\t\tcase 'fit-max': {\n\t\t\t\treturn Math.min(zx, zy)\n\t\t\t}\n\t\t\tcase 'fit-x': {\n\t\t\t\treturn zx\n\t\t\t}\n\t\t\tcase 'fit-y': {\n\t\t\t\treturn zy\n\t\t\t}\n\t\t\tcase 'fit-min-100': {\n\t\t\t\treturn Math.min(1, Math.max(zx, zy))\n\t\t\t}\n\t\t\tcase 'fit-max-100': {\n\t\t\t\treturn Math.min(1, Math.min(zx, zy))\n\t\t\t}\n\t\t\tcase 'fit-x-100': {\n\t\t\t\treturn Math.min(1, zx)\n\t\t\t}\n\t\t\tcase 'fit-y-100': {\n\t\t\t\treturn Math.min(1, zy)\n\t\t\t}\n\t\t\tdefault: {\n\t\t\t\tthrow exhaustiveSwitchError(cameraOptions.constraints.baseZoom)\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate _cameraOptions = atom('camera options', DEFAULT_CAMERA_OPTIONS)\n\n\t/**\n\t * Get the current camera options.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getCameraOptions()\n\t * ```\n\t *\n\t * @public */\n\tgetCameraOptions() {\n\t\treturn this._cameraOptions.get()\n\t}\n\n\t/**\n\t * Set the camera options. Changing the options won't immediately change the camera itself, so you may want to call `setCamera` after changing the options.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.setCameraOptions(myCameraOptions)\n\t * editor.setCamera(editor.getCamera())\n\t * ```\n\t *\n\t * @param opts - The camera options to set.\n\t *\n\t * @public */\n\tsetCameraOptions(opts: Partial) {\n\t\tconst next = structuredClone({\n\t\t\t...this._cameraOptions.__unsafe__getWithoutCapture(),\n\t\t\t...opts,\n\t\t})\n\t\tif (next.zoomSteps?.length < 1) next.zoomSteps = [1]\n\t\tthis._cameraOptions.set(next)\n\t\tthis.setCamera(this.getCamera())\n\t\treturn this\n\t}\n\n\t/** @internal */\n\tprivate getConstrainedCamera(\n\t\tpoint: VecLike,\n\t\topts?: TLCameraMoveOptions\n\t): {\n\t\tx: number\n\t\ty: number\n\t\tz: number\n\t} {\n\t\tconst currentCamera = this.getCamera()\n\n\t\tlet { x, y, z = currentCamera.z } = point\n\n\t\t// If force is true, then we'll set the camera to the point regardless of\n\t\t// the camera options, so that we can handle gestures that permit elasticity\n\t\t// or decay, or animations that occur while the camera is locked.\n\t\tif (!opts?.force) {\n\t\t\t// Apply any adjustments based on the camera options\n\n\t\t\tconst cameraOptions = this.getCameraOptions()\n\n\t\t\tconst zoomMin = cameraOptions.zoomSteps[0]\n\t\t\tconst zoomMax = last(cameraOptions.zoomSteps)!\n\n\t\t\tconst vsb = this.getViewportScreenBounds()\n\n\t\t\t// If bounds are provided, then we'll keep those bounds on screen\n\t\t\tif (cameraOptions.constraints) {\n\t\t\t\tconst { constraints } = cameraOptions\n\n\t\t\t\t// Clamp padding to half the viewport size on either dimension\n\t\t\t\tconst py = Math.min(constraints.padding.y, vsb.w / 2)\n\t\t\t\tconst px = Math.min(constraints.padding.x, vsb.h / 2)\n\n\t\t\t\t// Expand the bounds by the padding\n\t\t\t\tconst bounds = Box.From(cameraOptions.constraints.bounds)\n\n\t\t\t\t// For each axis, the \"natural zoom\" is the zoom at\n\t\t\t\t// which the expanded bounds (with padding) would fit\n\t\t\t\t// the current viewport screen bounds. Paddings are\n\t\t\t\t// equal to screen pixels at 100%\n\t\t\t\t// The min and max zooms are factors of the smaller natural zoom axis\n\n\t\t\t\tconst zx = (vsb.w - px * 2) / bounds.w\n\t\t\t\tconst zy = (vsb.h - py * 2) / bounds.h\n\n\t\t\t\tconst baseZoom = this.getBaseZoom()\n\t\t\t\tconst maxZ = zoomMax * baseZoom\n\t\t\t\tconst minZ = zoomMin * baseZoom\n\n\t\t\t\tif (opts?.reset) {\n\t\t\t\t\tz = this.getInitialZoom()\n\t\t\t\t}\n\n\t\t\t\tif (z < minZ || z > maxZ) {\n\t\t\t\t\t// We're trying to zoom out past the minimum zoom level,\n\t\t\t\t\t// or in past the maximum zoom level, so stop the camera\n\t\t\t\t\t// but keep the current center\n\t\t\t\t\tconst { x: cx, y: cy, z: cz } = currentCamera\n\t\t\t\t\tconst cxA = -cx + vsb.w / cz / 2\n\t\t\t\t\tconst cyA = -cy + vsb.h / cz / 2\n\t\t\t\t\tz = clamp(z, minZ, maxZ)\n\t\t\t\t\tconst cxB = -cx + vsb.w / z / 2\n\t\t\t\t\tconst cyB = -cy + vsb.h / z / 2\n\t\t\t\t\tx = cx + cxB - cxA\n\t\t\t\t\ty = cy + cyB - cyA\n\t\t\t\t}\n\n\t\t\t\t// Calculate available space\n\t\t\t\tconst minX = px / z - bounds.x\n\t\t\t\tconst minY = py / z - bounds.y\n\t\t\t\tconst freeW = (vsb.w - px * 2) / z - bounds.w\n\t\t\t\tconst freeH = (vsb.h - py * 2) / z - bounds.h\n\t\t\t\tconst originX = minX + freeW * constraints.origin.x\n\t\t\t\tconst originY = minY + freeH * constraints.origin.y\n\n\t\t\t\tconst behaviorX =\n\t\t\t\t\ttypeof constraints.behavior === 'string' ? constraints.behavior : constraints.behavior.x\n\t\t\t\tconst behaviorY =\n\t\t\t\t\ttypeof constraints.behavior === 'string' ? constraints.behavior : constraints.behavior.y\n\n\t\t\t\t// x axis\n\n\t\t\t\tif (opts?.reset) {\n\t\t\t\t\t// Reset the camera according to the origin\n\t\t\t\t\tx = originX\n\t\t\t\t\ty = originY\n\t\t\t\t} else {\n\t\t\t\t\t// Apply constraints to the camera\n\t\t\t\t\tswitch (behaviorX) {\n\t\t\t\t\t\tcase 'fixed': {\n\t\t\t\t\t\t\t// Center according to the origin\n\t\t\t\t\t\t\tx = originX\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcase 'contain': {\n\t\t\t\t\t\t\t// When below fit zoom, center the camera\n\t\t\t\t\t\t\tif (z < zx) x = originX\n\t\t\t\t\t\t\t// When above fit zoom, keep the bounds within padding distance of the viewport edge\n\t\t\t\t\t\t\telse x = clamp(x, minX + freeW, minX)\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcase 'inside': {\n\t\t\t\t\t\t\t// When below fit zoom, constrain the camera so that the bounds stay completely within the viewport\n\t\t\t\t\t\t\tif (z < zx) x = clamp(x, minX, (vsb.w - px) / z - bounds.w)\n\t\t\t\t\t\t\t// When above fit zoom, keep the bounds within padding distance of the viewport edge\n\t\t\t\t\t\t\telse x = clamp(x, minX + freeW, minX)\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcase 'outside': {\n\t\t\t\t\t\t\t// Constrain the camera so that the bounds never leaves the viewport\n\t\t\t\t\t\t\tx = clamp(x, px / z - bounds.w, (vsb.w - px) / z)\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcase 'free': {\n\t\t\t\t\t\t\t// noop, use whatever x is provided\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t\tdefault: {\n\t\t\t\t\t\t\tthrow exhaustiveSwitchError(behaviorX)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// y axis\n\n\t\t\t\t\tswitch (behaviorY) {\n\t\t\t\t\t\tcase 'fixed': {\n\t\t\t\t\t\t\ty = originY\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcase 'contain': {\n\t\t\t\t\t\t\tif (z < zy) y = originY\n\t\t\t\t\t\t\telse y = clamp(y, minY + freeH, minY)\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcase 'inside': {\n\t\t\t\t\t\t\tif (z < zy) y = clamp(y, minY, (vsb.h - py) / z - bounds.h)\n\t\t\t\t\t\t\telse y = clamp(y, minY + freeH, minY)\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcase 'outside': {\n\t\t\t\t\t\t\ty = clamp(y, py / z - bounds.h, (vsb.h - py) / z)\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcase 'free': {\n\t\t\t\t\t\t\t// noop, use whatever x is provided\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t\tdefault: {\n\t\t\t\t\t\t\tthrow exhaustiveSwitchError(behaviorY)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// constrain the zoom, preserving the center\n\t\t\t\tif (z > zoomMax || z < zoomMin) {\n\t\t\t\t\tconst { x: cx, y: cy, z: cz } = currentCamera\n\t\t\t\t\tz = clamp(z, zoomMin, zoomMax)\n\t\t\t\t\tx = cx + (-cx + vsb.w / z / 2) - (-cx + vsb.w / cz / 2)\n\t\t\t\t\ty = cy + (-cy + vsb.h / z / 2) - (-cy + vsb.h / cz / 2)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn { x, y, z }\n\t}\n\n\t/** @internal */\n\tprivate _setCamera(point: VecLike, opts?: TLCameraMoveOptions): this {\n\t\tconst currentCamera = this.getCamera()\n\n\t\tconst { x, y, z } = this.getConstrainedCamera(point, opts)\n\n\t\tif (currentCamera.x === x && currentCamera.y === y && currentCamera.z === z) {\n\t\t\treturn this\n\t\t}\n\n\t\ttransact(() => {\n\t\t\tconst camera = { ...currentCamera, x, y, z }\n\t\t\tthis.run(\n\t\t\t\t() => {\n\t\t\t\t\tthis.store.put([camera]) // include id and meta here\n\t\t\t\t},\n\t\t\t\t{ history: 'ignore' }\n\t\t\t)\n\n\t\t\t// Dispatch a new pointer move because the pointer's page will have changed\n\t\t\t// (its screen position will compute to a new page position given the new camera position)\n\t\t\tconst { currentScreenPoint, currentPagePoint } = this.inputs\n\t\t\tconst { screenBounds } = this.store.unsafeGetWithoutCapture(TLINSTANCE_ID)!\n\n\t\t\t// compare the next page point (derived from the current camera) to the current page point\n\t\t\tif (\n\t\t\t\tcurrentScreenPoint.x / z - x !== currentPagePoint.x ||\n\t\t\t\tcurrentScreenPoint.y / z - y !== currentPagePoint.y\n\t\t\t) {\n\t\t\t\t// If it's changed, dispatch a pointer event\n\t\t\t\tconst event: TLPointerEventInfo = {\n\t\t\t\t\ttype: 'pointer',\n\t\t\t\t\ttarget: 'canvas',\n\t\t\t\t\tname: 'pointer_move',\n\t\t\t\t\t// weird but true: we need to put the screen point back into client space\n\t\t\t\t\tpoint: Vec.AddXY(currentScreenPoint, screenBounds.x, screenBounds.y),\n\t\t\t\t\tpointerId: INTERNAL_POINTER_IDS.CAMERA_MOVE,\n\t\t\t\t\tctrlKey: this.inputs.ctrlKey,\n\t\t\t\t\taltKey: this.inputs.altKey,\n\t\t\t\t\tshiftKey: this.inputs.shiftKey,\n\t\t\t\t\tmetaKey: this.inputs.metaKey,\n\t\t\t\t\taccelKey: isAccelKey(this.inputs),\n\t\t\t\t\tbutton: 0,\n\t\t\t\t\tisPen: this.getInstanceState().isPenMode ?? false,\n\t\t\t\t}\n\n\t\t\t\tif (opts?.immediate) {\n\t\t\t\t\tthis._flushEventForTick(event)\n\t\t\t\t} else {\n\t\t\t\t\tthis.dispatch(event)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tthis._tickCameraState()\n\t\t})\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Set the current camera.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.setCamera({ x: 0, y: 0})\n\t * editor.setCamera({ x: 0, y: 0, z: 1.5})\n\t * editor.setCamera({ x: 0, y: 0, z: 1.5}, { animation: { duration: 1000, easing: (t) => t * t } })\n\t * ```\n\t *\n\t * @param point - The new camera position.\n\t * @param opts - The camera move options.\n\t *\n\t * @public\n\t */\n\tsetCamera(point: VecLike, opts?: TLCameraMoveOptions): this {\n\t\tconst { isLocked } = this._cameraOptions.__unsafe__getWithoutCapture()\n\t\tif (isLocked && !opts?.force) return this\n\n\t\t// Stop any camera animations\n\t\tthis.stopCameraAnimation()\n\n\t\t// Stop following any user\n\t\tif (this.getInstanceState().followingUserId) {\n\t\t\tthis.stopFollowingUser()\n\t\t}\n\n\t\tconst _point = Vec.Cast(point)\n\n\t\tif (!Number.isFinite(_point.x)) _point.x = 0\n\t\tif (!Number.isFinite(_point.y)) _point.y = 0\n\t\tif (_point.z === undefined || !Number.isFinite(_point.z)) point.z = this.getZoomLevel()\n\n\t\tconst camera = this.getConstrainedCamera(_point, opts)\n\n\t\tif (opts?.animation) {\n\t\t\tconst { width, height } = this.getViewportScreenBounds()\n\t\t\tthis._animateToViewport(\n\t\t\t\tnew Box(-camera.x, -camera.y, width / camera.z, height / camera.z),\n\t\t\t\topts\n\t\t\t)\n\t\t} else {\n\t\t\tthis._setCamera(camera, {\n\t\t\t\t...opts,\n\t\t\t\t// we already did the constraining, so we don't need to do it again\n\t\t\t\tforce: true,\n\t\t\t})\n\t\t}\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Center the camera on a point (in the current page space).\n\t *\n\t * @example\n\t * ```ts\n\t * editor.centerOnPoint({ x: 100, y: 100 })\n\t * editor.centerOnPoint({ x: 100, y: 100 }, { animation: { duration: 200 } })\n\t * ```\n\t *\n\t * @param point - The point in the current page space to center on.\n\t * @param opts - The camera move options.\n\t *\n\t * @public\n\t */\n\tcenterOnPoint(point: VecLike, opts?: TLCameraMoveOptions): this {\n\t\tconst { isLocked } = this.getCameraOptions()\n\t\tif (isLocked && !opts?.force) return this\n\n\t\tconst { width: pw, height: ph } = this.getViewportPageBounds()\n\t\tthis.setCamera(new Vec(-(point.x - pw / 2), -(point.y - ph / 2), this.getCamera().z), opts)\n\t\treturn this\n\t}\n\n\t/**\n\t * Zoom the camera to fit the current page's content in the viewport.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.zoomToFit()\n\t * editor.zoomToFit({ animation: { duration: 200 } })\n\t * ```\n\t *\n\t * @param opts - The camera move options.\n\t *\n\t * @public\n\t */\n\tzoomToFit(opts?: TLCameraMoveOptions): this {\n\t\tconst ids = [...this.getCurrentPageShapeIds()]\n\t\tif (ids.length <= 0) return this\n\t\tconst pageBounds = Box.Common(compact(ids.map((id) => this.getShapePageBounds(id))))\n\t\tthis.zoomToBounds(pageBounds, opts)\n\t\treturn this\n\t}\n\n\t/**\n\t * Set the zoom back to 100%.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.resetZoom()\n\t * editor.resetZoom(editor.getViewportScreenCenter(), { animation: { duration: 200 } })\n\t * editor.resetZoom(editor.getViewportScreenCenter(), { animation: { duration: 200 } })\n\t * ```\n\t *\n\t * @param point - The screen point to zoom out on. Defaults to the viewport screen center.\n\t * @param opts - The camera move options.\n\t *\n\t * @public\n\t */\n\tresetZoom(point = this.getViewportScreenCenter(), opts?: TLCameraMoveOptions): this {\n\t\tconst { isLocked, constraints: constraints } = this.getCameraOptions()\n\t\tif (isLocked && !opts?.force) return this\n\n\t\tconst currentCamera = this.getCamera()\n\t\tconst { x: cx, y: cy, z: cz } = currentCamera\n\t\tconst { x, y } = point\n\n\t\tlet z = 1\n\n\t\tif (constraints) {\n\t\t\t// For non-infinite fit, we'll set the camera to the natural zoom level...\n\t\t\t// unless it's already there, in which case we'll set zoom to 100%\n\t\t\tconst initialZoom = this.getInitialZoom()\n\t\t\tif (cz !== initialZoom) {\n\t\t\t\tz = initialZoom\n\t\t\t}\n\t\t}\n\n\t\tthis.setCamera(\n\t\t\tnew Vec(cx + (x / z - x) - (x / cz - x), cy + (y / z - y) - (y / cz - y), z),\n\t\t\topts\n\t\t)\n\t\treturn this\n\t}\n\n\t/**\n\t * Zoom the camera in.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.zoomIn()\n\t * editor.zoomIn(editor.getViewportScreenCenter(), { animation: { duration: 200 } })\n\t * editor.zoomIn(editor.inputs.currentScreenPoint, { animation: { duration: 200 } })\n\t * ```\n\t *\n\t * @param point - The screen point to zoom in on. Defaults to the screen center\n\t * @param opts - The camera move options.\n\t *\n\t * @public\n\t */\n\tzoomIn(point = this.getViewportScreenCenter(), opts?: TLCameraMoveOptions): this {\n\t\tconst { isLocked } = this.getCameraOptions()\n\t\tif (isLocked && !opts?.force) return this\n\n\t\tconst { x: cx, y: cy, z: cz } = this.getCamera()\n\n\t\tconst { zoomSteps } = this.getCameraOptions()\n\t\tif (zoomSteps !== null && zoomSteps.length > 1) {\n\t\t\tconst baseZoom = this.getBaseZoom()\n\t\t\tlet zoom = last(zoomSteps)! * baseZoom\n\t\t\tfor (let i = 1; i < zoomSteps.length; i++) {\n\t\t\t\tconst z1 = zoomSteps[i - 1] * baseZoom\n\t\t\t\tconst z2 = zoomSteps[i] * baseZoom\n\t\t\t\tif (z2 - cz <= (z2 - z1) / 2) continue\n\t\t\t\tzoom = z2\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tthis.setCamera(\n\t\t\t\tnew Vec(\n\t\t\t\t\tcx + (point.x / zoom - point.x) - (point.x / cz - point.x),\n\t\t\t\t\tcy + (point.y / zoom - point.y) - (point.y / cz - point.y),\n\t\t\t\t\tzoom\n\t\t\t\t),\n\t\t\t\topts\n\t\t\t)\n\t\t}\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Zoom the camera out.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.zoomOut()\n\t * editor.zoomOut(editor.getViewportScreenCenter(), { animation: { duration: 120 } })\n\t * editor.zoomOut(editor.inputs.currentScreenPoint, { animation: { duration: 120 } })\n\t * ```\n\t *\n\t * @param point - The point to zoom out on. Defaults to the viewport screen center.\n\t * @param opts - The camera move options.\n\t *\n\t * @public\n\t */\n\tzoomOut(point = this.getViewportScreenCenter(), opts?: TLCameraMoveOptions): this {\n\t\tconst { isLocked } = this.getCameraOptions()\n\t\tif (isLocked && !opts?.force) return this\n\n\t\tconst { zoomSteps } = this.getCameraOptions()\n\t\tif (zoomSteps !== null && zoomSteps.length > 1) {\n\t\t\tconst baseZoom = this.getBaseZoom()\n\t\t\tconst { x: cx, y: cy, z: cz } = this.getCamera()\n\t\t\t// start at the max\n\t\t\tlet zoom = zoomSteps[0] * baseZoom\n\t\t\tfor (let i = zoomSteps.length - 1; i > 0; i--) {\n\t\t\t\tconst z1 = zoomSteps[i - 1] * baseZoom\n\t\t\t\tconst z2 = zoomSteps[i] * baseZoom\n\t\t\t\tif (z2 - cz >= (z2 - z1) / 2) continue\n\t\t\t\tzoom = z1\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tthis.setCamera(\n\t\t\t\tnew Vec(\n\t\t\t\t\tcx + (point.x / zoom - point.x) - (point.x / cz - point.x),\n\t\t\t\t\tcy + (point.y / zoom - point.y) - (point.y / cz - point.y),\n\t\t\t\t\tzoom\n\t\t\t\t),\n\t\t\t\topts\n\t\t\t)\n\t\t}\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Zoom the camera to fit the current selection in the viewport.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.zoomToSelection()\n\t * editor.zoomToSelection({ animation: { duration: 200 } })\n\t * ```\n\t *\n\t * @param opts - The camera move options.\n\t *\n\t * @public\n\t */\n\tzoomToSelection(opts?: TLCameraMoveOptions): this {\n\t\tconst { isLocked } = this.getCameraOptions()\n\t\tif (isLocked && !opts?.force) return this\n\n\t\tconst selectionPageBounds = this.getSelectionPageBounds()\n\t\tif (selectionPageBounds) {\n\t\t\tthis.zoomToBounds(selectionPageBounds, {\n\t\t\t\ttargetZoom: Math.max(1, this.getZoomLevel()),\n\t\t\t\t...opts,\n\t\t\t})\n\t\t}\n\t\treturn this\n\t}\n\n\t/**\n\t * Zoom the camera to fit a bounding box (in the current page space).\n\t *\n\t * @example\n\t * ```ts\n\t * editor.zoomToBounds(myBounds)\n\t * editor.zoomToBounds(myBounds, { animation: { duration: 200 } })\n\t * editor.zoomToBounds(myBounds, { animation: { duration: 200 }, inset: 0, targetZoom: 1 })\n\t * ```\n\t *\n\t * @param bounds - The bounding box.\n\t * @param opts - The camera move options, target zoom, or custom inset amount.\n\t *\n\t * @public\n\t */\n\tzoomToBounds(\n\t\tbounds: BoxLike,\n\t\topts?: { targetZoom?: number; inset?: number } & TLCameraMoveOptions\n\t): this {\n\t\tconst cameraOptions = this._cameraOptions.__unsafe__getWithoutCapture()\n\t\tif (cameraOptions.isLocked && !opts?.force) return this\n\n\t\tconst viewportScreenBounds = this.getViewportScreenBounds()\n\n\t\tconst inset = opts?.inset ?? Math.min(ZOOM_TO_FIT_PADDING, viewportScreenBounds.width * 0.28)\n\n\t\tconst baseZoom = this.getBaseZoom()\n\t\tconst zoomMin = cameraOptions.zoomSteps[0]\n\t\tconst zoomMax = last(cameraOptions.zoomSteps)!\n\n\t\tlet zoom = clamp(\n\t\t\tMath.min(\n\t\t\t\t(viewportScreenBounds.width - inset) / bounds.w,\n\t\t\t\t(viewportScreenBounds.height - inset) / bounds.h\n\t\t\t),\n\t\t\tzoomMin * baseZoom,\n\t\t\tzoomMax * baseZoom\n\t\t)\n\n\t\tif (opts?.targetZoom !== undefined) {\n\t\t\tzoom = Math.min(opts.targetZoom, zoom)\n\t\t}\n\n\t\tthis.setCamera(\n\t\t\tnew Vec(\n\t\t\t\t-bounds.x + (viewportScreenBounds.width - bounds.w * zoom) / 2 / zoom,\n\t\t\t\t-bounds.y + (viewportScreenBounds.height - bounds.h * zoom) / 2 / zoom,\n\t\t\t\tzoom\n\t\t\t),\n\t\t\topts\n\t\t)\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Stop the current camera animation, if any.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.stopCameraAnimation()\n\t * ```\n\t *\n\t * @public\n\t */\n\tstopCameraAnimation(): this {\n\t\tthis.emit('stop-camera-animation')\n\t\treturn this\n\t}\n\n\t/** @internal */\n\tprivate _viewportAnimation = null as null | {\n\t\telapsed: number\n\t\tduration: number\n\t\teasing(t: number): number\n\t\tstart: Box\n\t\tend: Box\n\t}\n\n\t/** @internal */\n\tprivate _animateViewport(ms: number): void {\n\t\tif (!this._viewportAnimation) return\n\n\t\tthis._viewportAnimation.elapsed += ms\n\n\t\tconst { elapsed, easing, duration, start, end } = this._viewportAnimation\n\n\t\tif (elapsed > duration) {\n\t\t\tthis.off('tick', this._animateViewport)\n\t\t\tthis._viewportAnimation = null\n\t\t\tthis._setCamera(new Vec(-end.x, -end.y, this.getViewportScreenBounds().width / end.width))\n\t\t\treturn\n\t\t}\n\n\t\tconst remaining = duration - elapsed\n\t\tconst t = easing(1 - remaining / duration)\n\n\t\tconst left = start.minX + (end.minX - start.minX) * t\n\t\tconst top = start.minY + (end.minY - start.minY) * t\n\t\tconst right = start.maxX + (end.maxX - start.maxX) * t\n\n\t\tthis._setCamera(new Vec(-left, -top, this.getViewportScreenBounds().width / (right - left)), {\n\t\t\tforce: true,\n\t\t})\n\t}\n\n\t/** @internal */\n\tprivate _animateToViewport(\n\t\ttargetViewportPage: Box,\n\t\topts = { animation: DEFAULT_ANIMATION_OPTIONS } as TLCameraMoveOptions\n\t) {\n\t\tconst { animation, ...rest } = opts\n\t\tif (!animation) return\n\t\tconst { duration = 0, easing = EASINGS.easeInOutCubic } = animation\n\t\tconst animationSpeed = this.user.getAnimationSpeed()\n\t\tconst viewportPageBounds = this.getViewportPageBounds()\n\n\t\t// If we have an existing animation, then stop it\n\t\tthis.stopCameraAnimation()\n\n\t\t// also stop following any user\n\t\tif (this.getInstanceState().followingUserId) {\n\t\t\tthis.stopFollowingUser()\n\t\t}\n\n\t\tif (duration === 0 || animationSpeed === 0) {\n\t\t\t// If we have no animation, then skip the animation and just set the camera\n\t\t\treturn this._setCamera(\n\t\t\t\tnew Vec(\n\t\t\t\t\t-targetViewportPage.x,\n\t\t\t\t\t-targetViewportPage.y,\n\t\t\t\t\tthis.getViewportScreenBounds().width / targetViewportPage.width\n\t\t\t\t),\n\t\t\t\t{ ...rest }\n\t\t\t)\n\t\t}\n\n\t\t// Set our viewport animation\n\t\tthis._viewportAnimation = {\n\t\t\telapsed: 0,\n\t\t\tduration: duration / animationSpeed,\n\t\t\teasing,\n\t\t\tstart: viewportPageBounds.clone(),\n\t\t\tend: targetViewportPage.clone(),\n\t\t}\n\n\t\t// If we ever get a \"stop-camera-animation\" event, we stop\n\t\tthis.once('stop-camera-animation', () => {\n\t\t\tthis.off('tick', this._animateViewport)\n\t\t\tthis._viewportAnimation = null\n\t\t})\n\n\t\t// On each tick, animate the viewport\n\t\tthis.on('tick', this._animateViewport)\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Slide the camera in a certain direction.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.slideCamera({ speed: 1, direction: { x: 1, y: 0 }, friction: 0.1 })\n\t * ```\n\t *\n\t * @param opts - Options for the slide\n\t * @public\n\t */\n\tslideCamera(\n\t\topts = {} as {\n\t\t\tspeed: number\n\t\t\tdirection: VecLike\n\t\t\tfriction?: number\n\t\t\tspeedThreshold?: number\n\t\t\tforce?: boolean\n\t\t}\n\t): this {\n\t\tconst { isLocked } = this.getCameraOptions()\n\t\tif (isLocked && !opts?.force) return this\n\n\t\tconst animationSpeed = this.user.getAnimationSpeed()\n\t\tif (animationSpeed === 0) return this\n\n\t\tthis.stopCameraAnimation()\n\n\t\tconst {\n\t\t\tspeed,\n\t\t\tfriction = this.options.cameraSlideFriction,\n\t\t\tdirection,\n\t\t\tspeedThreshold = 0.01,\n\t\t} = opts\n\t\tlet currentSpeed = Math.min(speed, 1)\n\n\t\tconst cancel = () => {\n\t\t\tthis.off('tick', moveCamera)\n\t\t\tthis.off('stop-camera-animation', cancel)\n\t\t}\n\n\t\tthis.once('stop-camera-animation', cancel)\n\n\t\tconst moveCamera = (elapsed: number) => {\n\t\t\tconst { x: cx, y: cy, z: cz } = this.getCamera()\n\t\t\tconst movementVec = Vec.Mul(direction, (currentSpeed * elapsed) / cz)\n\n\t\t\t// Apply friction\n\t\t\tcurrentSpeed *= 1 - friction\n\t\t\tif (currentSpeed < speedThreshold) {\n\t\t\t\tcancel()\n\t\t\t} else {\n\t\t\t\tthis._setCamera(new Vec(cx + movementVec.x, cy + movementVec.y, cz))\n\t\t\t}\n\t\t}\n\n\t\tthis.on('tick', moveCamera)\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Animate the camera to a user's cursor position. This also briefly show the user's cursor if it's not currently visible.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.zoomToUser(myUserId)\n\t * editor.zoomToUser(myUserId, { animation: { duration: 200 } })\n\t * ```\n\t *\n\t * @param userId - The id of the user to animate to.\n\t * @param opts - The camera move options.\n\t * @public\n\t */\n\tzoomToUser(userId: string, opts: TLCameraMoveOptions = { animation: { duration: 500 } }): this {\n\t\tconst presence = this.getCollaborators().find((c) => c.userId === userId)\n\n\t\tif (!presence) return this\n\n\t\tthis.run(() => {\n\t\t\t// If we're following someone, stop following them\n\t\t\tif (this.getInstanceState().followingUserId !== null) {\n\t\t\t\tthis.stopFollowingUser()\n\t\t\t}\n\n\t\t\t// If we're not on the same page, move to the page they're on\n\t\t\tconst isOnSamePage = presence.currentPageId === this.getCurrentPageId()\n\t\t\tif (!isOnSamePage) {\n\t\t\t\tthis.setCurrentPage(presence.currentPageId)\n\t\t\t}\n\n\t\t\t// Only animate the camera if the user is on the same page as us\n\t\t\tif (opts && opts.animation && !isOnSamePage) {\n\t\t\t\topts.animation = undefined\n\t\t\t}\n\n\t\t\tthis.centerOnPoint(presence.cursor, opts)\n\n\t\t\t// Highlight the user's cursor\n\t\t\tconst { highlightedUserIds } = this.getInstanceState()\n\t\t\tthis.updateInstanceState({ highlightedUserIds: [...highlightedUserIds, userId] })\n\n\t\t\t// Unhighlight the user's cursor after a few seconds\n\t\t\tthis.timers.setTimeout(() => {\n\t\t\t\tconst highlightedUserIds = [...this.getInstanceState().highlightedUserIds]\n\t\t\t\tconst index = highlightedUserIds.indexOf(userId)\n\t\t\t\tif (index < 0) return\n\t\t\t\thighlightedUserIds.splice(index, 1)\n\t\t\t\tthis.updateInstanceState({ highlightedUserIds })\n\t\t\t}, this.options.collaboratorIdleTimeoutMs)\n\t\t})\n\n\t\treturn this\n\t}\n\n\t// Viewport\n\n\t/** @internal */\n\tprivate _willSetInitialBounds = true\n\n\t/**\n\t * Update the viewport. The viewport will measure the size and screen position of its container\n\t * element. This should be done whenever the container's position on the screen changes.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.updateViewportScreenBounds(new Box(0, 0, 1280, 1024))\n\t * editor.updateViewportScreenBounds(new Box(0, 0, 1280, 1024), true)\n\t * ```\n\t *\n\t * @param screenBounds - The new screen bounds of the viewport.\n\t * @param center - Whether to preserve the viewport page center as the viewport changes.\n\t *\n\t * @public\n\t */\n\tupdateViewportScreenBounds(screenBounds: Box | HTMLElement, center = false): this {\n\t\tif (screenBounds instanceof HTMLElement) {\n\t\t\tconst rect = screenBounds.getBoundingClientRect()\n\t\t\tscreenBounds = new Box(\n\t\t\t\trect.left || rect.x,\n\t\t\t\trect.top || rect.y,\n\t\t\t\tMath.max(rect.width, 1),\n\t\t\t\tMath.max(rect.height, 1)\n\t\t\t)\n\t\t} else {\n\t\t\tscreenBounds.width = Math.max(screenBounds.width, 1)\n\t\t\tscreenBounds.height = Math.max(screenBounds.height, 1)\n\t\t}\n\n\t\tconst insets = [\n\t\t\t// top\n\t\t\tscreenBounds.minY !== 0,\n\t\t\t// right\n\t\t\t!approximately(document.body.scrollWidth, screenBounds.maxX, 1),\n\t\t\t// bottom\n\t\t\t!approximately(document.body.scrollHeight, screenBounds.maxY, 1),\n\t\t\t// left\n\t\t\tscreenBounds.minX !== 0,\n\t\t]\n\n\t\tconst { _willSetInitialBounds } = this\n\n\t\tthis._willSetInitialBounds = false\n\n\t\tconst { screenBounds: prevScreenBounds, insets: prevInsets } = this.getInstanceState()\n\t\tif (screenBounds.equals(prevScreenBounds) && insets.every((v, i) => v === prevInsets[i])) {\n\t\t\t// nothing to do\n\t\t\treturn this\n\t\t}\n\n\t\tif (_willSetInitialBounds) {\n\t\t\t// If we have just received the initial bounds, don't center the camera.\n\t\t\tthis.updateInstanceState({ screenBounds: screenBounds.toJson(), insets })\n\t\t\tthis.setCamera(this.getCamera())\n\t\t} else {\n\t\t\tif (center && !this.getInstanceState().followingUserId) {\n\t\t\t\t// Get the page center before the change, make the change, and restore it\n\t\t\t\tconst before = this.getViewportPageBounds().center\n\t\t\t\tthis.updateInstanceState({ screenBounds: screenBounds.toJson(), insets })\n\t\t\t\tthis.centerOnPoint(before)\n\t\t\t} else {\n\t\t\t\t// Otherwise,\n\t\t\t\tthis.updateInstanceState({ screenBounds: screenBounds.toJson(), insets })\n\t\t\t\tthis._setCamera(Vec.From({ ...this.getCamera() }))\n\t\t\t}\n\t\t}\n\n\t\tthis._tickCameraState()\n\n\t\treturn this\n\t}\n\n\t/**\n\t * The bounds of the editor's viewport in screen space.\n\t *\n\t * @public\n\t */\n\t@computed getViewportScreenBounds() {\n\t\tconst { x, y, w, h } = this.getInstanceState().screenBounds\n\t\treturn new Box(x, y, w, h)\n\t}\n\n\t/**\n\t * The center of the editor's viewport in screen space.\n\t *\n\t * @public\n\t */\n\t@computed getViewportScreenCenter() {\n\t\tconst viewportScreenBounds = this.getViewportScreenBounds()\n\t\treturn new Vec(\n\t\t\tviewportScreenBounds.midX - viewportScreenBounds.minX,\n\t\t\tviewportScreenBounds.midY - viewportScreenBounds.minY\n\t\t)\n\t}\n\n\t/**\n\t * The current viewport in the current page space.\n\t *\n\t * @public\n\t */\n\t@computed getViewportPageBounds() {\n\t\tconst { w, h } = this.getViewportScreenBounds()\n\t\tconst { x: cx, y: cy, z: cz } = this.getCamera()\n\t\treturn new Box(-cx, -cy, w / cz, h / cz)\n\t}\n\n\t/**\n\t * Convert a point in screen space to a point in the current page space.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.screenToPage({ x: 100, y: 100 })\n\t * ```\n\t *\n\t * @param point - The point in screen space.\n\t *\n\t * @public\n\t */\n\tscreenToPage(point: VecLike) {\n\t\tconst { screenBounds } = this.store.unsafeGetWithoutCapture(TLINSTANCE_ID)!\n\t\tconst { x: cx, y: cy, z: cz = 1 } = this.getCamera()\n\t\treturn new Vec(\n\t\t\t(point.x - screenBounds.x) / cz - cx,\n\t\t\t(point.y - screenBounds.y) / cz - cy,\n\t\t\tpoint.z ?? 0.5\n\t\t)\n\t}\n\n\t/**\n\t * Convert a point in the current page space to a point in current screen space.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.pageToScreen({ x: 100, y: 100 })\n\t * ```\n\t *\n\t * @param point - The point in page space.\n\t *\n\t * @public\n\t */\n\tpageToScreen(point: VecLike) {\n\t\tconst { screenBounds } = this.store.unsafeGetWithoutCapture(TLINSTANCE_ID)!\n\t\tconst { x: cx, y: cy, z: cz = 1 } = this.getCamera()\n\t\treturn new Vec(\n\t\t\t(point.x + cx) * cz + screenBounds.x,\n\t\t\t(point.y + cy) * cz + screenBounds.y,\n\t\t\tpoint.z ?? 0.5\n\t\t)\n\t}\n\n\t/**\n\t * Convert a point in the current page space to a point in current viewport space.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.pageToViewport({ x: 100, y: 100 })\n\t * ```\n\t *\n\t * @param point - The point in page space.\n\t *\n\t * @public\n\t */\n\tpageToViewport(point: VecLike) {\n\t\tconst { x: cx, y: cy, z: cz = 1 } = this.getCamera()\n\t\treturn new Vec((point.x + cx) * cz, (point.y + cy) * cz, point.z ?? 0.5)\n\t}\n\t// Collaborators\n\n\t@computed\n\tprivate _getCollaboratorsQuery() {\n\t\treturn this.store.query.records('instance_presence', () => ({\n\t\t\tuserId: { neq: this.user.getId() },\n\t\t}))\n\t}\n\n\t/**\n\t * Returns a list of presence records for all peer collaborators.\n\t * This will return the latest presence record for each connected user.\n\t *\n\t * @public\n\t */\n\t@computed\n\tgetCollaborators() {\n\t\tconst allPresenceRecords = this._getCollaboratorsQuery().get()\n\t\tif (!allPresenceRecords.length) return EMPTY_ARRAY\n\t\tconst userIds = [...new Set(allPresenceRecords.map((c) => c.userId))].sort()\n\t\treturn userIds.map((id) => {\n\t\t\tconst latestPresence = allPresenceRecords\n\t\t\t\t.filter((c) => c.userId === id)\n\t\t\t\t.sort((a, b) => b.lastActivityTimestamp - a.lastActivityTimestamp)[0]\n\t\t\treturn latestPresence\n\t\t})\n\t}\n\n\t/**\n\t * Returns a list of presence records for all peer collaborators on the current page.\n\t * This will return the latest presence record for each connected user.\n\t *\n\t * @public\n\t */\n\t@computed\n\tgetCollaboratorsOnCurrentPage() {\n\t\tconst currentPageId = this.getCurrentPageId()\n\t\treturn this.getCollaborators().filter((c) => c.currentPageId === currentPageId)\n\t}\n\n\t// Following\n\n\t// When we are 'locked on' to a user, our camera is derived from their camera.\n\tprivate _isLockedOnFollowingUser = atom('isLockedOnFollowingUser', false)\n\n\t/**\n\t * Start viewport-following a user.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.startFollowingUser(myUserId)\n\t * ```\n\t *\n\t * @param userId - The id of the user to follow.\n\t *\n\t * @public\n\t */\n\tstartFollowingUser(userId: string): this {\n\t\t// if we were already following someone, stop following them\n\t\tthis.stopFollowingUser()\n\n\t\tconst leaderPresences = this._getCollaboratorsQuery()\n\t\t\t.get()\n\t\t\t.filter((p) => p.userId === userId)\n\n\t\tif (!leaderPresences.length) {\n\t\t\tconsole.warn('User not found')\n\t\t\treturn this\n\t\t}\n\n\t\tconst thisUserId = this.user.getId()\n\n\t\tif (!thisUserId) {\n\t\t\tconsole.warn('You should set the userId for the current instance before following a user')\n\t\t\t// allow to continue since it's probably fine most of the time.\n\t\t}\n\n\t\t// If the leader is following us, then we can't follow them\n\t\tif (leaderPresences.some((p) => p.followingUserId === thisUserId)) {\n\t\t\treturn this\n\t\t}\n\n\t\tconst latestLeaderPresence = computed('latestLeaderPresence', () => {\n\t\t\treturn this.getCollaborators().find((p) => p.userId === userId)\n\t\t})\n\n\t\ttransact(() => {\n\t\t\tthis.updateInstanceState({ followingUserId: userId }, { history: 'ignore' })\n\n\t\t\t// we listen for page changes separately from the 'moveTowardsUser' tick\n\t\t\tconst dispose = react('update current page', () => {\n\t\t\t\tconst leaderPresence = latestLeaderPresence.get()\n\t\t\t\tif (!leaderPresence) {\n\t\t\t\t\tthis.stopFollowingUser()\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tif (\n\t\t\t\t\tleaderPresence.currentPageId !== this.getCurrentPageId() &&\n\t\t\t\t\tthis.getPage(leaderPresence.currentPageId)\n\t\t\t\t) {\n\t\t\t\t\t// if the page changed, switch page\n\t\t\t\t\tthis.run(\n\t\t\t\t\t\t() => {\n\t\t\t\t\t\t\t// sneaky store.put here, we can't go through setCurrentPage because it calls stopFollowingUser\n\t\t\t\t\t\t\tthis.store.put([\n\t\t\t\t\t\t\t\t{ ...this.getInstanceState(), currentPageId: leaderPresence.currentPageId },\n\t\t\t\t\t\t\t])\n\t\t\t\t\t\t\tthis._isLockedOnFollowingUser.set(true)\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{ history: 'ignore' }\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t})\n\n\t\t\tconst cancel = () => {\n\t\t\t\tdispose()\n\t\t\t\tthis._isLockedOnFollowingUser.set(false)\n\t\t\t\tthis.off('frame', moveTowardsUser)\n\t\t\t\tthis.off('stop-following', cancel)\n\t\t\t}\n\n\t\t\tconst moveTowardsUser = () => {\n\t\t\t\t// Stop following if we can't find the user\n\t\t\t\tconst leaderPresence = latestLeaderPresence.get()\n\t\t\t\tif (!leaderPresence) {\n\t\t\t\t\tthis.stopFollowingUser()\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\tif (this._isLockedOnFollowingUser.get()) return\n\n\t\t\t\tconst animationSpeed = this.user.getAnimationSpeed()\n\n\t\t\t\tif (animationSpeed === 0) {\n\t\t\t\t\tthis._isLockedOnFollowingUser.set(true)\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\tconst targetViewport = this.getViewportPageBoundsForFollowing()\n\t\t\t\tif (!targetViewport) {\n\t\t\t\t\tthis.stopFollowingUser()\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tconst currentViewport = this.getViewportPageBounds()\n\n\t\t\t\tconst diffX =\n\t\t\t\t\tMath.abs(targetViewport.minX - currentViewport.minX) +\n\t\t\t\t\tMath.abs(targetViewport.maxX - currentViewport.maxX)\n\t\t\t\tconst diffY =\n\t\t\t\t\tMath.abs(targetViewport.minY - currentViewport.minY) +\n\t\t\t\t\tMath.abs(targetViewport.maxY - currentViewport.maxY)\n\n\t\t\t\t// Stop chasing if we're close enough!\n\t\t\t\tif (\n\t\t\t\t\tdiffX < this.options.followChaseViewportSnap &&\n\t\t\t\t\tdiffY < this.options.followChaseViewportSnap\n\t\t\t\t) {\n\t\t\t\t\tthis._isLockedOnFollowingUser.set(true)\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\t// Chase the user's viewport!\n\t\t\t\t// Interpolate between the current viewport and the target viewport based on animation speed.\n\t\t\t\t// This will produce an 'ease-out' effect.\n\t\t\t\tconst t = clamp(animationSpeed * 0.5, 0.1, 0.8)\n\n\t\t\t\tconst nextViewport = new Box(\n\t\t\t\t\tlerp(currentViewport.minX, targetViewport.minX, t),\n\t\t\t\t\tlerp(currentViewport.minY, targetViewport.minY, t),\n\t\t\t\t\tlerp(currentViewport.width, targetViewport.width, t),\n\t\t\t\t\tlerp(currentViewport.height, targetViewport.height, t)\n\t\t\t\t)\n\n\t\t\t\tconst nextCamera = new Vec(\n\t\t\t\t\t-nextViewport.x,\n\t\t\t\t\t-nextViewport.y,\n\t\t\t\t\tthis.getViewportScreenBounds().width / nextViewport.width\n\t\t\t\t)\n\n\t\t\t\t// Update the camera!\n\t\t\t\tthis.stopCameraAnimation()\n\t\t\t\tthis._setCamera(nextCamera)\n\t\t\t}\n\n\t\t\tthis.once('stop-following', cancel)\n\t\t\tthis.addListener('frame', moveTowardsUser)\n\n\t\t\t// call once to start synchronously\n\t\t\tmoveTowardsUser()\n\t\t})\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Stop viewport-following a user.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.stopFollowingUser()\n\t * ```\n\t * @public\n\t */\n\tstopFollowingUser(): this {\n\t\tthis.run(\n\t\t\t() => {\n\t\t\t\t// commit the current camera to the store\n\t\t\t\tthis.store.put([this.getCamera()])\n\t\t\t\t// this must happen after the camera is committed\n\t\t\t\tthis._isLockedOnFollowingUser.set(false)\n\t\t\t\tthis.updateInstanceState({ followingUserId: null })\n\t\t\t\tthis.emit('stop-following')\n\t\t\t},\n\t\t\t{ history: 'ignore' }\n\t\t)\n\t\treturn this\n\t}\n\n\t/** @internal */\n\tgetUnorderedRenderingShapes(\n\t\t// The rendering state. We use this method both for rendering, which\n\t\t// is based on other state, and for computing order for SVG export,\n\t\t// which should work even when things are for example off-screen.\n\t\tuseEditorState: boolean\n\t): TLRenderingShape[] {\n\t\t// Here we get the shape as well as any of its children, as well as their\n\t\t// opacities. If the shape is being erased, and none of its ancestors are\n\t\t// being erased, then we reduce the opacity of the shape and all of its\n\t\t// ancestors; but we don't apply this effect more than once among a set\n\t\t// of descendants so that it does not compound.\n\n\t\t// This is designed to keep all the shapes in a single list which\n\t\t// allows the DOM nodes to be reused even when they become children\n\t\t// of other nodes.\n\n\t\tconst renderingShapes: TLRenderingShape[] = []\n\n\t\tlet nextIndex = this.options.maxShapesPerPage * 2\n\t\tlet nextBackgroundIndex = this.options.maxShapesPerPage\n\n\t\tconst erasingShapeIds = this.getErasingShapeIds()\n\n\t\tconst addShapeById = (id: TLShapeId, opacity: number, isAncestorErasing: boolean) => {\n\t\t\tconst shape = this.getShape(id)\n\t\t\tif (!shape) return\n\t\t\tif (this.isShapeHidden(shape)) return\n\n\t\t\topacity *= shape.opacity\n\t\t\tlet isShapeErasing = false\n\t\t\tconst util = this.getShapeUtil(shape)\n\n\t\t\tif (useEditorState) {\n\t\t\t\tisShapeErasing = !isAncestorErasing && erasingShapeIds.includes(id)\n\t\t\t\tif (isShapeErasing) {\n\t\t\t\t\topacity *= 0.32\n\t\t\t\t}\n\t\t\t}\n\n\t\t\trenderingShapes.push({\n\t\t\t\tid,\n\t\t\t\tshape,\n\t\t\t\tutil,\n\t\t\t\tindex: nextIndex,\n\t\t\t\tbackgroundIndex: nextBackgroundIndex,\n\t\t\t\topacity,\n\t\t\t})\n\n\t\t\tnextIndex += 1\n\t\t\tnextBackgroundIndex += 1\n\n\t\t\tconst childIds = this.getSortedChildIdsForParent(id)\n\t\t\tif (!childIds.length) return\n\n\t\t\tlet backgroundIndexToRestore = null\n\t\t\tif (util.providesBackgroundForChildren(shape)) {\n\t\t\t\tbackgroundIndexToRestore = nextBackgroundIndex\n\t\t\t\tnextBackgroundIndex = nextIndex\n\t\t\t\tnextIndex += this.options.maxShapesPerPage\n\t\t\t}\n\n\t\t\tfor (const childId of childIds) {\n\t\t\t\taddShapeById(childId, opacity, isAncestorErasing || isShapeErasing)\n\t\t\t}\n\n\t\t\tif (backgroundIndexToRestore !== null) {\n\t\t\t\tnextBackgroundIndex = backgroundIndexToRestore\n\t\t\t}\n\t\t}\n\n\t\t// If we're using editor state, then we're only interested in on-screen shapes.\n\t\t// If we're not using the editor state, then we're interested in ALL shapes, even those from other pages.\n\t\tconst pages = useEditorState ? [this.getCurrentPage()] : this.getPages()\n\t\tfor (const page of pages) {\n\t\t\tfor (const childId of this.getSortedChildIdsForParent(page.id)) {\n\t\t\t\taddShapeById(childId, 1, false)\n\t\t\t}\n\t\t}\n\n\t\treturn renderingShapes\n\t}\n\n\t// Camera state\n\t// Camera state does two things: first, it allows us to subscribe to whether\n\t// the camera is moving or not; and second, it allows us to update the rendering\n\t// shapes on the canvas. Changing the rendering shapes may cause shapes to\n\t// unmount / remount in the DOM, which is expensive; and computing visibility is\n\t// also expensive in large projects. For this reason, we use a second bounding\n\t// box just for rendering, and we only update after the camera stops moving.\n\tprivate _cameraState = atom('camera state', 'idle' as 'idle' | 'moving')\n\tprivate _cameraStateTimeoutRemaining = 0\n\t_decayCameraStateTimeout(elapsed: number) {\n\t\tthis._cameraStateTimeoutRemaining -= elapsed\n\t\tif (this._cameraStateTimeoutRemaining > 0) return\n\t\tthis.off('tick', this._decayCameraStateTimeout)\n\t\tthis._cameraState.set('idle')\n\t}\n\t_tickCameraState() {\n\t\t// always reset the timeout\n\t\tthis._cameraStateTimeoutRemaining = this.options.cameraMovingTimeoutMs\n\t\t// If the state is idle, then start the tick\n\t\tif (this._cameraState.__unsafe__getWithoutCapture() !== 'idle') return\n\t\tthis._cameraState.set('moving')\n\t\tthis.on('tick', this._decayCameraStateTimeout)\n\t}\n\n\t/**\n\t * Whether the camera is moving or idle.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getCameraState()\n\t * ```\n\t *\n\t * @public\n\t */\n\tgetCameraState() {\n\t\treturn this._cameraState.get()\n\t}\n\n\t/**\n\t * Get the shapes that should be displayed in the current viewport.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getRenderingShapes()\n\t * ```\n\t *\n\t * @public\n\t */\n\t@computed getRenderingShapes() {\n\t\tconst renderingShapes = this.getUnorderedRenderingShapes(true)\n\n\t\t// Its IMPORTANT that the result be sorted by id AND include the index\n\t\t// that the shape should be displayed at. Steve, this is the past you\n\t\t// telling the present you not to change this.\n\n\t\t// We want to sort by id because moving elements about in the DOM will\n\t\t// cause the element to get removed by react as it moves the DOM node. This\n\t\t// causes to re-render which is hella annoying and a perf\n\t\t// drain. By always sorting by 'id' we keep the shapes always in the\n\t\t// same order; but we later use index to set the element's 'z-index'\n\t\t// to change the \"rendered\" position in z-space.\n\t\treturn renderingShapes.sort(sortById)\n\t}\n\n\t/* --------------------- Pages ---------------------- */\n\n\t@computed private _getAllPagesQuery() {\n\t\treturn this.store.query.records('page')\n\t}\n\n\t/**\n\t * Info about the project's current pages.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getPages()\n\t * ```\n\t *\n\t * @public\n\t */\n\t@computed getPages(): TLPage[] {\n\t\treturn this._getAllPagesQuery().get().sort(sortByIndex)\n\t}\n\n\t/**\n\t * The current page.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getCurrentPage()\n\t * ```\n\t *\n\t * @public\n\t */\n\tgetCurrentPage(): TLPage {\n\t\treturn this.getPage(this.getCurrentPageId())!\n\t}\n\n\t/**\n\t * The current page id.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getCurrentPageId()\n\t * ```\n\t *\n\t * @public\n\t */\n\t@computed getCurrentPageId(): TLPageId {\n\t\treturn this.getInstanceState().currentPageId\n\t}\n\n\t/**\n\t * Get a page.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getPage(myPage.id)\n\t * editor.getPage(myPage)\n\t * ```\n\t *\n\t * @param page - The page (or the page id) to get.\n\t *\n\t * @public\n\t */\n\tgetPage(page: TLPageId | TLPage): TLPage | undefined {\n\t\treturn this.store.get(typeof page === 'string' ? page : page.id)\n\t}\n\n\t/* @internal */\n\tprivate readonly _currentPageShapeIds: ReturnType\n\n\t/**\n\t * An array of all of the shapes on the current page.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getCurrentPageIds()\n\t * ```\n\t *\n\t * @public\n\t */\n\tgetCurrentPageShapeIds() {\n\t\treturn this._currentPageShapeIds.get()\n\t}\n\n\t/**\n\t * @internal\n\t */\n\t@computed\n\tgetCurrentPageShapeIdsSorted() {\n\t\treturn Array.from(this.getCurrentPageShapeIds()).sort()\n\t}\n\n\t/**\n\t * Get the ids of shapes on a page.\n\t *\n\t * @example\n\t * ```ts\n\t * const idsOnPage1 = editor.getPageShapeIds('page1')\n\t * const idsOnPage2 = editor.getPageShapeIds(myPage2)\n\t * ```\n\t *\n\t * @param page - The page (or the page id) to get the shape ids for.\n\t *\n\t * @public\n\t **/\n\tgetPageShapeIds(page: TLPageId | TLPage): Set {\n\t\tconst pageId = typeof page === 'string' ? page : page.id\n\t\tconst result = this.store.query.exec('shape', { parentId: { eq: pageId } })\n\t\treturn this.getShapeAndDescendantIds(result.map((s) => s.id))\n\t}\n\n\t/**\n\t * Set the current page.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.setCurrentPage('page1')\n\t * editor.setCurrentPage(myPage1)\n\t * ```\n\t *\n\t * @param page - The page (or the page id) to set as the current page.\n\t *\n\t * @public\n\t */\n\tsetCurrentPage(page: TLPageId | TLPage): this {\n\t\tconst pageId = typeof page === 'string' ? page : page.id\n\t\tif (!this.store.has(pageId)) {\n\t\t\tconsole.error(\"Tried to set the current page id to a page that doesn't exist.\")\n\t\t\treturn this\n\t\t}\n\n\t\tthis.stopFollowingUser()\n\t\t// finish off any in-progress interactions\n\t\tthis.complete()\n\n\t\treturn this.run(\n\t\t\t() => {\n\t\t\t\tthis.store.put([{ ...this.getInstanceState(), currentPageId: pageId }])\n\t\t\t\t// ensure camera constraints are applied\n\t\t\t\tthis.setCamera(this.getCamera())\n\t\t\t},\n\t\t\t{ history: 'record-preserveRedoStack' }\n\t\t)\n\t}\n\n\t/**\n\t * Update a page.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.updatePage({ id: 'page2', name: 'Page 2' })\n\t * ```\n\t *\n\t * @param partial - The partial of the shape to update.\n\t *\n\t * @public\n\t */\n\tupdatePage(partial: RequiredKeys, 'id'>): this {\n\t\tif (this.getIsReadonly()) return this\n\n\t\tconst prev = this.getPage(partial.id)\n\t\tif (!prev) return this\n\n\t\treturn this.run(() => this.store.update(partial.id, (page) => ({ ...page, ...partial })))\n\t}\n\n\t/**\n\t * Create a page.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.createPage(myPage)\n\t * editor.createPage({ name: 'Page 2' })\n\t * ```\n\t *\n\t * @param page - The page (or page partial) to create.\n\t *\n\t * @public\n\t */\n\tcreatePage(page: Partial): this {\n\t\tthis.run(() => {\n\t\t\tif (this.getIsReadonly()) return\n\t\t\tif (this.getPages().length >= this.options.maxPages) return\n\t\t\tconst pages = this.getPages()\n\n\t\t\tconst name = getIncrementedName(\n\t\t\t\tpage.name ?? 'Page 1',\n\t\t\t\tpages.map((p) => p.name)\n\t\t\t)\n\n\t\t\tlet index = page.index\n\n\t\t\tif (!index || pages.some((p) => p.index === index)) {\n\t\t\t\tindex = getIndexAbove(pages[pages.length - 1].index)\n\t\t\t}\n\n\t\t\tconst newPage = PageRecordType.create({\n\t\t\t\tmeta: {},\n\t\t\t\t...page,\n\t\t\t\tname,\n\t\t\t\tindex,\n\t\t\t})\n\n\t\t\tthis.store.put([newPage])\n\t\t})\n\t\treturn this\n\t}\n\n\t/**\n\t * Delete a page.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.deletePage('page1')\n\t * ```\n\t *\n\t * @param page - The page (or the page id) to delete.\n\t *\n\t * @public\n\t */\n\tdeletePage(page: TLPageId | TLPage): this {\n\t\tconst id = typeof page === 'string' ? page : page.id\n\t\tthis.run(() => {\n\t\t\tif (this.getIsReadonly()) return\n\t\t\tconst pages = this.getPages()\n\t\t\tif (pages.length === 1) return\n\n\t\t\tconst deletedPage = this.getPage(id)\n\t\t\tif (!deletedPage) return\n\n\t\t\tif (id === this.getCurrentPageId()) {\n\t\t\t\tconst index = pages.findIndex((page) => page.id === id)\n\t\t\t\tconst next = pages[index - 1] ?? pages[index + 1]\n\t\t\t\tthis.setCurrentPage(next.id)\n\t\t\t}\n\t\t\tthis.store.remove([deletedPage.id])\n\t\t})\n\t\treturn this\n\t}\n\n\t/**\n\t * Duplicate a page.\n\t *\n\t * @param page - The page (or the page id) to duplicate. Defaults to the current page.\n\t * @param createId - The id of the new page. Defaults to a new id.\n\t *\n\t * @public\n\t */\n\tduplicatePage(page: TLPageId | TLPage, createId: TLPageId = PageRecordType.createId()): this {\n\t\tif (this.getPages().length >= this.options.maxPages) return this\n\t\tconst id = typeof page === 'string' ? page : page.id\n\t\tconst freshPage = this.getPage(id) // get the most recent version of the page anyway\n\t\tif (!freshPage) return this\n\n\t\tconst prevCamera = { ...this.getCamera() }\n\t\tconst content = this.getContentFromCurrentPage(this.getSortedChildIdsForParent(freshPage.id))\n\n\t\tthis.run(() => {\n\t\t\tconst pages = this.getPages()\n\t\t\tconst index = getIndexBetween(freshPage.index, pages[pages.indexOf(freshPage) + 1]?.index)\n\n\t\t\t// create the page (also creates the pagestate and camera for the new page)\n\t\t\tthis.createPage({ name: freshPage.name + ' Copy', id: createId, index })\n\t\t\t// set the new page as the current page\n\t\t\tthis.setCurrentPage(createId)\n\t\t\t// update the new page's camera to the previous page's camera\n\t\t\tthis.setCamera(prevCamera)\n\n\t\t\tif (content) {\n\t\t\t\t// If we had content on the previous page, put it on the new page\n\t\t\t\treturn this.putContentOntoCurrentPage(content)\n\t\t\t}\n\t\t})\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Rename a page.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.renamePage('page1', 'My Page')\n\t * ```\n\t *\n\t * @param page - The page (or the page id) to rename.\n\t * @param name - The new name.\n\t *\n\t * @public\n\t */\n\trenamePage(page: TLPageId | TLPage, name: string) {\n\t\tconst id = typeof page === 'string' ? page : page.id\n\t\tif (this.getIsReadonly()) return this\n\t\tthis.updatePage({ id, name })\n\t\treturn this\n\t}\n\n\t/* --------------------- Assets --------------------- */\n\n\t/** @internal */\n\t@computed private _getAllAssetsQuery() {\n\t\treturn this.store.query.records('asset')\n\t}\n\n\t/**\n\t * Get all assets in the editor.\n\t *\n\t * @public\n\t */\n\tgetAssets() {\n\t\treturn this._getAllAssetsQuery().get()\n\t}\n\n\t/**\n\t * Create one or more assets.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.createAssets([...myAssets])\n\t * ```\n\t *\n\t * @param assets - The assets to create.\n\t *\n\t * @public\n\t */\n\tcreateAssets(assets: TLAsset[]): this {\n\t\tif (this.getIsReadonly()) return this\n\t\tif (assets.length <= 0) return this\n\t\tthis.run(() => this.store.put(assets), { history: 'ignore' })\n\t\treturn this\n\t}\n\n\t/**\n\t * Update one or more assets.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.updateAssets([{ id: 'asset1', name: 'New name' }])\n\t * ```\n\t *\n\t * @param assets - The assets to update.\n\t *\n\t * @public\n\t */\n\tupdateAssets(assets: TLAssetPartial[]): this {\n\t\tif (this.getIsReadonly()) return this\n\t\tif (assets.length <= 0) return this\n\t\tthis.run(\n\t\t\t() => {\n\t\t\t\tthis.store.put(\n\t\t\t\t\tassets.map((partial) => ({\n\t\t\t\t\t\t...this.store.get(partial.id)!,\n\t\t\t\t\t\t...partial,\n\t\t\t\t\t}))\n\t\t\t\t)\n\t\t\t},\n\t\t\t{ history: 'ignore' }\n\t\t)\n\t\treturn this\n\t}\n\n\t/**\n\t * Delete one or more assets.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.deleteAssets(['asset1', 'asset2'])\n\t * ```\n\t *\n\t * @param assets - The assets (or asset ids) to delete.\n\t *\n\t * @public\n\t */\n\tdeleteAssets(assets: TLAssetId[] | TLAsset[]): this {\n\t\tif (this.getIsReadonly()) return this\n\n\t\tconst ids =\n\t\t\ttypeof assets[0] === 'string'\n\t\t\t\t? (assets as TLAssetId[])\n\t\t\t\t: (assets as TLAsset[]).map((a) => a.id)\n\t\tif (ids.length <= 0) return this\n\n\t\tthis.run(() => this.store.remove(ids), { history: 'ignore' })\n\t\treturn this\n\t}\n\n\t/**\n\t * Get an asset by its id.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getAsset('asset1')\n\t * ```\n\t *\n\t * @param asset - The asset (or asset id) to get.\n\t *\n\t * @public\n\t */\n\tgetAsset(asset: T | T['id']): T | undefined {\n\t\treturn this.store.get(typeof asset === 'string' ? asset : asset.id) as T | undefined\n\t}\n\n\tasync resolveAssetUrl(\n\t\tassetId: TLAssetId | null,\n\t\tcontext: {\n\t\t\tscreenScale?: number\n\t\t\tshouldResolveToOriginal?: boolean\n\t\t}\n\t): Promise {\n\t\tif (!assetId) return null\n\t\tconst asset = this.getAsset(assetId)\n\t\tif (!asset) return null\n\n\t\tconst { screenScale = 1, shouldResolveToOriginal = false } = context\n\n\t\t// We only look at the zoom level at powers of 2.\n\t\tconst zoomStepFunction = (zoom: number) => Math.pow(2, Math.ceil(Math.log2(zoom)))\n\t\tconst steppedScreenScale = Math.max(0.125, zoomStepFunction(screenScale))\n\t\tconst networkEffectiveType: string | null =\n\t\t\t'connection' in navigator ? (navigator as any).connection.effectiveType : null\n\t\tconst dpr = this.getInstanceState().devicePixelRatio\n\n\t\treturn await this.store.props.assets.resolve(asset, {\n\t\t\tscreenScale: screenScale || 1,\n\t\t\tsteppedScreenScale,\n\t\t\tdpr,\n\t\t\tnetworkEffectiveType,\n\t\t\tshouldResolveToOriginal,\n\t\t})\n\t}\n\t/**\n\t * Upload an asset to the store's asset service, returning a URL that can be used to resolve the\n\t * asset.\n\t */\n\tasync uploadAsset(asset: TLAsset, file: File): Promise {\n\t\treturn await this.store.props.assets.upload(asset, file)\n\t}\n\n\t/* --------------------- Shapes --------------------- */\n\n\t@computed\n\tprivate _getShapeGeometryCache(): ComputedCache {\n\t\treturn this.store.createComputedCache(\n\t\t\t'bounds',\n\t\t\t(shape) => this.getShapeUtil(shape).getGeometry(shape),\n\t\t\t(a, b) => a.props === b.props\n\t\t)\n\t}\n\n\t/**\n\t * Get the geometry of a shape.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getShapeGeometry(myShape)\n\t * editor.getShapeGeometry(myShapeId)\n\t * ```\n\t *\n\t * @param shape - The shape (or shape id) to get the geometry for.\n\t *\n\t * @public\n\t */\n\tgetShapeGeometry(shape: TLShape | TLShapeId): T {\n\t\treturn this._getShapeGeometryCache().get(typeof shape === 'string' ? shape : shape.id)! as T\n\t}\n\n\t/** @internal */\n\t@computed private _getShapeHandlesCache(): ComputedCache {\n\t\treturn this.store.createComputedCache('handles', (shape) => {\n\t\t\treturn this.getShapeUtil(shape).getHandles?.(shape)\n\t\t})\n\t}\n\n\t/**\n\t * Get the handles (if any) for a shape.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getShapeHandles(myShape)\n\t * editor.getShapeHandles(myShapeId)\n\t * ```\n\t *\n\t * @param shape - The shape (or shape id) to get the handles for.\n\t * @public\n\t */\n\tgetShapeHandles(shape: T | T['id']): TLHandle[] | undefined {\n\t\treturn this._getShapeHandlesCache().get(typeof shape === 'string' ? shape : shape.id)\n\t}\n\n\t/**\n\t * Get the local transform for a shape as a matrix model. This transform reflects both its\n\t * translation (x, y) from from either its parent's top left corner, if the shape's parent is\n\t * another shape, or else from the 0,0 of the page, if the shape's parent is the page; and the\n\t * shape's rotation.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getShapeLocalTransform(myShape)\n\t * ```\n\t *\n\t * @param shape - The shape to get the local transform for.\n\t *\n\t * @public\n\t */\n\tgetShapeLocalTransform(shape: TLShape | TLShapeId): Mat {\n\t\tconst id = typeof shape === 'string' ? shape : shape.id\n\t\tconst freshShape = this.getShape(id)\n\t\tif (!freshShape) throw Error('Editor.getTransform: shape not found')\n\t\treturn Mat.Identity().translate(freshShape.x, freshShape.y).rotate(freshShape.rotation)\n\t}\n\n\t/**\n\t * A cache of page transforms.\n\t *\n\t * @internal\n\t */\n\t@computed private _getShapePageTransformCache(): ComputedCache {\n\t\treturn this.store.createComputedCache('pageTransformCache', (shape) => {\n\t\t\tif (isPageId(shape.parentId)) {\n\t\t\t\treturn this.getShapeLocalTransform(shape)\n\t\t\t}\n\n\t\t\t// If the shape's parent doesn't exist yet (e.g. when merging in changes from remote in the wrong order)\n\t\t\t// then we can't compute the transform yet, so just return the identity matrix.\n\t\t\t// In the future we should look at creating a store update mechanism that understands and preserves\n\t\t\t// ordering.\n\t\t\tconst parentTransform =\n\t\t\t\tthis._getShapePageTransformCache().get(shape.parentId) ?? Mat.Identity()\n\t\t\treturn Mat.Compose(parentTransform, this.getShapeLocalTransform(shape)!)\n\t\t})\n\t}\n\n\t/**\n\t * Get the local transform of a shape's parent as a matrix model.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getShapeParentTransform(myShape)\n\t * ```\n\t *\n\t * @param shape - The shape (or shape id) to get the parent transform for.\n\t *\n\t * @public\n\t */\n\tgetShapeParentTransform(shape: TLShape | TLShapeId): Mat {\n\t\tconst id = typeof shape === 'string' ? shape : shape.id\n\t\tconst freshShape = this.getShape(id)\n\t\tif (!freshShape || isPageId(freshShape.parentId)) return Mat.Identity()\n\t\treturn this._getShapePageTransformCache().get(freshShape.parentId) ?? Mat.Identity()\n\t}\n\n\t/**\n\t * Get the transform of a shape in the current page space.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getShapePageTransform(myShape)\n\t * editor.getShapePageTransform(myShapeId)\n\t * ```\n\t *\n\t * @param shape - The shape (or shape id) to get the page transform for.\n\t *\n\t * @public\n\t */\n\tgetShapePageTransform(shape: TLShape | TLShapeId): Mat {\n\t\tconst id = typeof shape === 'string' ? shape : shape.id\n\t\treturn this._getShapePageTransformCache().get(id) ?? Mat.Identity()\n\t}\n\n\t/** @internal */\n\t@computed private _getShapePageBoundsCache(): ComputedCache {\n\t\treturn this.store.createComputedCache('pageBoundsCache', (shape) => {\n\t\t\tconst pageTransform = this._getShapePageTransformCache().get(shape.id)\n\n\t\t\tif (!pageTransform) return new Box()\n\n\t\t\tconst result = Box.FromPoints(\n\t\t\t\tMat.applyToPoints(pageTransform, this.getShapeGeometry(shape).vertices)\n\t\t\t)\n\n\t\t\treturn result\n\t\t})\n\t}\n\n\t/**\n\t * Get the bounds of a shape in the current page space.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getShapePageBounds(myShape)\n\t * editor.getShapePageBounds(myShapeId)\n\t * ```\n\t *\n\t * @param shape - The shape (or shape id) to get the bounds for.\n\t *\n\t * @public\n\t */\n\tgetShapePageBounds(shape: TLShape | TLShapeId): Box | undefined {\n\t\treturn this._getShapePageBoundsCache().get(typeof shape === 'string' ? shape : shape.id)\n\t}\n\n\t/**\n\t * A cache of clip paths used for clipping.\n\t *\n\t * @internal\n\t */\n\t@computed private _getShapeClipPathCache(): ComputedCache {\n\t\treturn this.store.createComputedCache('clipPathCache', (shape) => {\n\t\t\tconst pageMask = this._getShapeMaskCache().get(shape.id)\n\t\t\tif (!pageMask) return undefined\n\t\t\tif (pageMask.length === 0) {\n\t\t\t\treturn `polygon(0px 0px, 0px 0px, 0px 0px)`\n\t\t\t}\n\n\t\t\tconst pageTransform = this._getShapePageTransformCache().get(shape.id)\n\t\t\tif (!pageTransform) return undefined\n\n\t\t\tconst localMask = Mat.applyToPoints(Mat.Inverse(pageTransform), pageMask)\n\n\t\t\treturn `polygon(${localMask.map((p) => `${p.x}px ${p.y}px`).join(',')})`\n\t\t})\n\t}\n\n\t/**\n\t * Get the clip path for a shape.\n\t *\n\t * @example\n\t * ```ts\n\t * const clipPath = editor.getShapeClipPath(shape)\n\t * const clipPath = editor.getShapeClipPath(shape.id)\n\t * ```\n\t *\n\t * @param shape - The shape (or shape id) to get the clip path for.\n\t *\n\t * @returns The clip path or undefined.\n\t *\n\t * @public\n\t */\n\tgetShapeClipPath(shape: TLShape | TLShapeId): string | undefined {\n\t\treturn this._getShapeClipPathCache().get(typeof shape === 'string' ? shape : shape.id)\n\t}\n\n\t/** @internal */\n\t@computed private _getShapeMaskCache(): ComputedCache {\n\t\treturn this.store.createComputedCache('pageMaskCache', (shape) => {\n\t\t\tif (isPageId(shape.parentId)) return undefined\n\n\t\t\tconst frameAncestors = this.getShapeAncestors(shape.id).filter((shape) =>\n\t\t\t\tthis.isShapeOfType(shape, 'frame')\n\t\t\t)\n\n\t\t\tif (frameAncestors.length === 0) return undefined\n\n\t\t\tconst pageMask = frameAncestors\n\t\t\t\t.map((s) =>\n\t\t\t\t\t// Apply the frame transform to the frame outline to get the frame outline in the current page space\n\t\t\t\t\tthis._getShapePageTransformCache()\n\t\t\t\t\t\t.get(s.id)!\n\t\t\t\t\t\t.applyToPoints(this.getShapeGeometry(s).vertices)\n\t\t\t\t)\n\t\t\t\t.reduce((acc, b) => {\n\t\t\t\t\tif (!(b && acc)) return undefined\n\t\t\t\t\tconst intersection = intersectPolygonPolygon(acc, b)\n\t\t\t\t\tif (intersection) {\n\t\t\t\t\t\treturn intersection.map(Vec.Cast)\n\t\t\t\t\t}\n\t\t\t\t\treturn []\n\t\t\t\t})\n\n\t\t\treturn pageMask\n\t\t})\n\t}\n\n\t/**\n\t * Get the mask (in the current page space) for a shape.\n\t *\n\t * @example\n\t * ```ts\n\t * const pageMask = editor.getShapeMask(shape.id)\n\t * ```\n\t *\n\t * @param shape - The shape (or the shape id) of the shape to get the mask for.\n\t *\n\t * @returns The mask for the shape.\n\t *\n\t * @public\n\t */\n\tgetShapeMask(shape: TLShapeId | TLShape): VecLike[] | undefined {\n\t\treturn this._getShapeMaskCache().get(typeof shape === 'string' ? shape : shape.id)\n\t}\n\n\t/**\n\t * Get the bounds of a shape in the current page space, incorporating any masks. For example, if the\n\t * shape were the child of a frame and was half way out of the frame, the bounds would be the half\n\t * of the shape that was in the frame.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getShapeMaskedPageBounds(myShape)\n\t * editor.getShapeMaskedPageBounds(myShapeId)\n\t * ```\n\t *\n\t * @param shape - The shape to get the masked bounds for.\n\t *\n\t * @public\n\t */\n\tgetShapeMaskedPageBounds(shape: TLShapeId | TLShape): Box | undefined {\n\t\tif (typeof shape !== 'string') shape = shape.id\n\t\treturn this._getShapeMaskedPageBoundsCache().get(shape)\n\t}\n\n\t/** @internal */\n\t@computed private _getShapeMaskedPageBoundsCache(): ComputedCache {\n\t\treturn this.store.createComputedCache('shapeMaskedPageBoundsCache', (shape) => {\n\t\t\tconst pageBounds = this._getShapePageBoundsCache().get(shape.id)\n\t\t\tif (!pageBounds) return\n\t\t\tconst pageMask = this._getShapeMaskCache().get(shape.id)\n\t\t\tif (pageMask) {\n\t\t\t\tif (pageMask.length === 0) return undefined\n\t\t\t\tconst { corners } = pageBounds\n\t\t\t\tif (corners.every((p, i) => p && Vec.Equals(p, pageMask[i]))) return pageBounds.clone()\n\t\t\t\tconst intersection = intersectPolygonPolygon(pageMask, corners)\n\t\t\t\tif (!intersection) return\n\t\t\t\treturn Box.FromPoints(intersection)\n\t\t\t}\n\t\t\treturn pageBounds\n\t\t})\n\t}\n\n\t/**\n\t * Get the ancestors of a shape.\n\t *\n\t * @example\n\t * ```ts\n\t * const ancestors = editor.getShapeAncestors(myShape)\n\t * const ancestors = editor.getShapeAncestors(myShapeId)\n\t * ```\n\t *\n\t * @param shape - The shape (or shape id) to get the ancestors for.\n\t * @param acc - The accumulator.\n\t *\n\t * @public\n\t */\n\tgetShapeAncestors(shape: TLShapeId | TLShape, acc: TLShape[] = []): TLShape[] {\n\t\tconst id = typeof shape === 'string' ? shape : shape.id\n\t\tconst freshShape = this.getShape(id)\n\t\tif (!freshShape) return acc\n\t\tconst parentId = freshShape.parentId\n\t\tif (isPageId(parentId)) {\n\t\t\tacc.reverse()\n\t\t\treturn acc\n\t\t}\n\n\t\tconst parent = this.store.get(parentId)\n\t\tif (!parent) return acc\n\t\tacc.push(parent)\n\t\treturn this.getShapeAncestors(parent, acc)\n\t}\n\n\t/**\n\t * Find the first ancestor matching the given predicate\n\t *\n\t * @example\n\t * ```ts\n\t * const ancestor = editor.findShapeAncestor(myShape)\n\t * const ancestor = editor.findShapeAncestor(myShape.id)\n\t * const ancestor = editor.findShapeAncestor(myShape.id, (shape) => shape.type === 'frame')\n\t * ```\n\t *\n\t * @param shape - The shape to check the ancestors for.\n\t * @param predicate - The predicate to match.\n\t *\n\t * @public\n\t */\n\tfindShapeAncestor(\n\t\tshape: TLShape | TLShapeId,\n\t\tpredicate: (parent: TLShape) => boolean\n\t): TLShape | undefined {\n\t\tconst id = typeof shape === 'string' ? shape : shape.id\n\t\tconst freshShape = this.getShape(id)\n\t\tif (!freshShape) return\n\n\t\tconst parentId = freshShape.parentId\n\t\tif (isPageId(parentId)) return\n\n\t\tconst parent = this.getShape(parentId)\n\t\tif (!parent) return\n\t\treturn predicate(parent) ? parent : this.findShapeAncestor(parent, predicate)\n\t}\n\n\t/**\n\t * Returns true if the the given shape has the given ancestor.\n\t *\n\t * @param shape - The shape.\n\t * @param ancestorId - The id of the ancestor.\n\t *\n\t * @public\n\t */\n\thasAncestor(shape: TLShape | TLShapeId | undefined, ancestorId: TLShapeId): boolean {\n\t\tconst id = typeof shape === 'string' ? shape : shape?.id\n\t\tconst freshShape = id && this.getShape(id)\n\t\tif (!freshShape) return false\n\t\tif (freshShape.parentId === ancestorId) return true\n\t\treturn this.hasAncestor(this.getShapeParent(freshShape), ancestorId)\n\t}\n\n\t/**\n\t * Get the common ancestor of two or more shapes that matches a predicate.\n\t *\n\t * @param shapes - The shapes (or shape ids) to check.\n\t * @param predicate - The predicate to match.\n\t */\n\tfindCommonAncestor(\n\t\tshapes: TLShape[] | TLShapeId[],\n\t\tpredicate?: (shape: TLShape) => boolean\n\t): TLShapeId | undefined {\n\t\tif (shapes.length === 0) {\n\t\t\treturn\n\t\t}\n\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\t\tconst freshShapes = compact(ids.map((id) => this.getShape(id)))\n\n\t\tif (freshShapes.length === 1) {\n\t\t\tconst parentId = freshShapes[0].parentId\n\t\t\tif (isPageId(parentId)) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\treturn predicate ? this.findShapeAncestor(freshShapes[0], predicate)?.id : parentId\n\t\t}\n\n\t\tconst [nodeA, ...others] = freshShapes\n\t\tlet ancestor = this.getShapeParent(nodeA)\n\t\twhile (ancestor) {\n\t\t\t// TODO: this is not ideal, optimize\n\t\t\tif (predicate && !predicate(ancestor)) {\n\t\t\t\tancestor = this.getShapeParent(ancestor)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif (others.every((shape) => this.hasAncestor(shape, ancestor!.id))) {\n\t\t\t\treturn ancestor!.id\n\t\t\t}\n\t\t\tancestor = this.getShapeParent(ancestor)\n\t\t}\n\t\treturn undefined\n\t}\n\n\t/**\n\t * Check whether a shape or its parent is locked.\n\t *\n\t * @param shape - The shape (or shape id) to check.\n\t *\n\t * @public\n\t */\n\tisShapeOrAncestorLocked(shape?: TLShape): boolean\n\tisShapeOrAncestorLocked(id?: TLShapeId): boolean\n\tisShapeOrAncestorLocked(arg?: TLShape | TLShapeId): boolean {\n\t\tconst shape = typeof arg === 'string' ? this.getShape(arg) : arg\n\t\tif (shape === undefined) return false\n\t\tif (shape.isLocked) return true\n\t\treturn this.isShapeOrAncestorLocked(this.getShapeParent(shape))\n\t}\n\n\t@computed\n\tprivate _notVisibleShapes() {\n\t\treturn notVisibleShapes(this)\n\t}\n\n\t/**\n\t * Get culled shapes.\n\t *\n\t * @public\n\t */\n\t@computed\n\tgetCulledShapes() {\n\t\tconst notVisibleShapes = this._notVisibleShapes().get()\n\t\tconst selectedShapeIds = this.getSelectedShapeIds()\n\t\tconst editingId = this.getEditingShapeId()\n\t\tconst culledShapes = new Set(notVisibleShapes)\n\t\t// we don't cull the shape we are editing\n\t\tif (editingId) {\n\t\t\tculledShapes.delete(editingId)\n\t\t}\n\t\t// we also don't cull selected shapes\n\t\tselectedShapeIds.forEach((id) => {\n\t\t\tculledShapes.delete(id)\n\t\t})\n\t\treturn culledShapes\n\t}\n\n\t/**\n\t * The bounds of the current page (the common bounds of all of the shapes on the page).\n\t *\n\t * @public\n\t */\n\t@computed getCurrentPageBounds(): Box | undefined {\n\t\tlet commonBounds: Box | undefined\n\n\t\tthis.getCurrentPageShapeIdsSorted().forEach((shapeId) => {\n\t\t\tconst bounds = this.getShapeMaskedPageBounds(shapeId)\n\t\t\tif (!bounds) return\n\t\t\tif (!commonBounds) {\n\t\t\t\tcommonBounds = bounds.clone()\n\t\t\t} else {\n\t\t\t\tcommonBounds = commonBounds.expand(bounds)\n\t\t\t}\n\t\t})\n\n\t\treturn commonBounds\n\t}\n\n\t/**\n\t * Get the top-most selected shape at the given point, ignoring groups.\n\t *\n\t * @param point - The point to check.\n\t *\n\t * @returns The top-most selected shape at the given point, or undefined if there is no shape at the point.\n\t */\n\tgetSelectedShapeAtPoint(point: VecLike): TLShape | undefined {\n\t\tconst selectedShapeIds = this.getSelectedShapeIds()\n\t\treturn this.getCurrentPageShapesSorted()\n\t\t\t.filter((shape) => shape.type !== 'group' && selectedShapeIds.includes(shape.id))\n\t\t\t.reverse() // find last\n\t\t\t.find((shape) => this.isPointInShape(shape, point, { hitInside: true, margin: 0 }))\n\t}\n\n\t/**\n\t * Get the shape at the current point.\n\t *\n\t * @param point - The point to check.\n\t * @param opts - Options for the check: `hitInside` to check if the point is inside the shape, `margin` to check if the point is within a margin of the shape, `hitFrameInside` to check if the point is inside the frame, and `filter` to filter the shapes to check.\n\t *\n\t * @returns The shape at the given point, or undefined if there is no shape at the point.\n\t */\n\tgetShapeAtPoint(\n\t\tpoint: VecLike,\n\t\topts = {} as {\n\t\t\trenderingOnly?: boolean\n\t\t\tmargin?: number\n\t\t\thitInside?: boolean\n\t\t\thitLocked?: boolean\n\t\t\t// TODO: we probably need to rename this, we don't quite _always_\n\t\t\t// respect this esp. in the part below that does \"Check labels first\"\n\t\t\thitLabels?: boolean\n\t\t\thitFrameInside?: boolean\n\t\t\tfilter?(shape: TLShape): boolean\n\t\t}\n\t): TLShape | undefined {\n\t\tconst zoomLevel = this.getZoomLevel()\n\t\tconst viewportPageBounds = this.getViewportPageBounds()\n\t\tconst {\n\t\t\tfilter,\n\t\t\tmargin = 0,\n\t\t\thitLocked = false,\n\t\t\thitLabels = false,\n\t\t\thitInside = false,\n\t\t\thitFrameInside = false,\n\t\t} = opts\n\n\t\tlet inHollowSmallestArea = Infinity\n\t\tlet inHollowSmallestAreaHit: TLShape | null = null\n\n\t\tlet inMarginClosestToEdgeDistance = Infinity\n\t\tlet inMarginClosestToEdgeHit: TLShape | null = null\n\n\t\tconst shapesToCheck = (\n\t\t\topts.renderingOnly\n\t\t\t\t? this.getCurrentPageRenderingShapesSorted()\n\t\t\t\t: this.getCurrentPageShapesSorted()\n\t\t).filter((shape) => {\n\t\t\tif (\n\t\t\t\t(shape.isLocked && !hitLocked) ||\n\t\t\t\tthis.isShapeHidden(shape) ||\n\t\t\t\tthis.isShapeOfType(shape, 'group')\n\t\t\t)\n\t\t\t\treturn false\n\t\t\tconst pageMask = this.getShapeMask(shape)\n\t\t\tif (pageMask && !pointInPolygon(point, pageMask)) return false\n\t\t\tif (filter) return filter(shape)\n\t\t\treturn true\n\t\t})\n\n\t\tfor (let i = shapesToCheck.length - 1; i >= 0; i--) {\n\t\t\tconst shape = shapesToCheck[i]\n\t\t\tconst geometry = this.getShapeGeometry(shape)\n\t\t\tconst isGroup = geometry instanceof Group2d\n\n\t\t\tconst pointInShapeSpace = this.getPointInShapeSpace(shape, point)\n\n\t\t\t// Check labels first\n\t\t\tif (\n\t\t\t\tthis.isShapeOfType(shape, 'arrow') ||\n\t\t\t\t(this.isShapeOfType(shape, 'geo') && shape.props.fill === 'none')\n\t\t\t) {\n\t\t\t\tif (shape.props.text.trim()) {\n\t\t\t\t\t// let's check whether the shape has a label and check that\n\t\t\t\t\tfor (const childGeometry of (geometry as Group2d).children) {\n\t\t\t\t\t\tif (childGeometry.isLabel && childGeometry.isPointInBounds(pointInShapeSpace)) {\n\t\t\t\t\t\t\treturn shape\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (this.isShapeOfType(shape, 'frame')) {\n\t\t\t\t// On the rare case that we've hit a frame, test again hitInside to be forced true;\n\t\t\t\t// this prevents clicks from passing through the body of a frame to shapes behind it.\n\n\t\t\t\t// If the hit is within the frame's outer margin, then select the frame\n\t\t\t\tconst distance = geometry.distanceToPoint(pointInShapeSpace, hitInside)\n\t\t\t\tif (Math.abs(distance) <= margin) {\n\t\t\t\t\treturn inMarginClosestToEdgeHit || shape\n\t\t\t\t}\n\n\t\t\t\tif (geometry.hitTestPoint(pointInShapeSpace, 0, true)) {\n\t\t\t\t\t// Once we've hit a frame, we want to end the search. If we have hit a shape\n\t\t\t\t\t// already, then this would either be above the frame or a child of the frame,\n\t\t\t\t\t// so we want to return that. Otherwise, the point is in the empty space of the\n\t\t\t\t\t// frame. If `hitFrameInside` is true (e.g. used drawing an arrow into the\n\t\t\t\t\t// frame) we the frame itself; other wise, (e.g. when hovering or pointing)\n\t\t\t\t\t// we would want to return null.\n\t\t\t\t\treturn (\n\t\t\t\t\t\tinMarginClosestToEdgeHit ||\n\t\t\t\t\t\tinHollowSmallestAreaHit ||\n\t\t\t\t\t\t(hitFrameInside ? shape : undefined)\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tlet distance: number\n\n\t\t\tif (isGroup) {\n\t\t\t\tlet minDistance = Infinity\n\t\t\t\tfor (const childGeometry of geometry.children) {\n\t\t\t\t\tif (childGeometry.isLabel && !hitLabels) continue\n\n\t\t\t\t\t// hit test the all of the child geometries that aren't labels\n\t\t\t\t\tconst tDistance = childGeometry.distanceToPoint(pointInShapeSpace, hitInside)\n\t\t\t\t\tif (tDistance < minDistance) {\n\t\t\t\t\t\tminDistance = tDistance\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tdistance = minDistance\n\t\t\t} else {\n\t\t\t\t// If the margin is zero and the geometry has a very small width or height,\n\t\t\t\t// then check the actual distance. This is to prevent a bug where straight\n\t\t\t\t// lines would never pass the broad phase (point-in-bounds) check.\n\t\t\t\tif (margin === 0 && (geometry.bounds.w < 1 || geometry.bounds.h < 1)) {\n\t\t\t\t\tdistance = geometry.distanceToPoint(pointInShapeSpace, hitInside)\n\t\t\t\t} else {\n\t\t\t\t\t// Broad phase\n\t\t\t\t\tif (geometry.bounds.containsPoint(pointInShapeSpace, margin)) {\n\t\t\t\t\t\t// Narrow phase (actual distance)\n\t\t\t\t\t\tdistance = geometry.distanceToPoint(pointInShapeSpace, hitInside)\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// Failed the broad phase, geddafugaotta'ere!\n\t\t\t\t\t\tdistance = Infinity\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (geometry.isClosed) {\n\t\t\t\t// For closed shapes, the distance will be positive if outside of\n\t\t\t\t// the shape or negative if inside of the shape. If the distance\n\t\t\t\t// is greater than the margin, then it's a miss. Otherwise...\n\n\t\t\t\tif (distance <= margin) {\n\t\t\t\t\tif (geometry.isFilled || (isGroup && geometry.children[0].isFilled)) {\n\t\t\t\t\t\t// If the shape is filled, then it's a hit. Remember, we're\n\t\t\t\t\t\t// starting from the TOP-MOST shape in z-index order, so any\n\t\t\t\t\t\t// other hits would be occluded by the shape.\n\t\t\t\t\t\treturn inMarginClosestToEdgeHit || shape\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// If the shape is bigger than the viewport, then skip it.\n\t\t\t\t\t\tif (this.getShapePageBounds(shape)!.contains(viewportPageBounds)) continue\n\n\t\t\t\t\t\t// For hollow shapes...\n\t\t\t\t\t\tif (Math.abs(distance) < margin) {\n\t\t\t\t\t\t\t// We want to preference shapes where we're inside of the\n\t\t\t\t\t\t\t// shape margin; and we would want to hit the shape with the\n\t\t\t\t\t\t\t// edge closest to the point.\n\t\t\t\t\t\t\tif (Math.abs(distance) < inMarginClosestToEdgeDistance) {\n\t\t\t\t\t\t\t\tinMarginClosestToEdgeDistance = Math.abs(distance)\n\t\t\t\t\t\t\t\tinMarginClosestToEdgeHit = shape\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else if (!inMarginClosestToEdgeHit) {\n\t\t\t\t\t\t\t// If we're not within margin distance to any edge, and if the\n\t\t\t\t\t\t\t// shape is hollow, then we want to hit the shape with the\n\t\t\t\t\t\t\t// smallest area. (There's a bug here with self-intersecting\n\t\t\t\t\t\t\t// shapes, like a closed drawing of an \"8\", but that's a bigger\n\t\t\t\t\t\t\t// problem to solve.)\n\t\t\t\t\t\t\tconst { area } = geometry\n\t\t\t\t\t\t\tif (area < inHollowSmallestArea) {\n\t\t\t\t\t\t\t\tinHollowSmallestArea = area\n\t\t\t\t\t\t\t\tinHollowSmallestAreaHit = shape\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// For open shapes (e.g. lines or draw shapes) always use the margin.\n\t\t\t\t// If the distance is less than the margin, return the shape as the hit.\n\t\t\t\tif (distance < this.options.hitTestMargin / zoomLevel) {\n\t\t\t\t\treturn shape\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// If we haven't hit any filled shapes or frames, then return either\n\t\t// the shape who we hit within the margin (and of those, the one that\n\t\t// had the shortest distance between the point and the shape edge),\n\t\t// or else the hollow shape with the smallest area\u2014or if we didn't hit\n\t\t// any margins or any hollow shapes, then null.\n\t\treturn inMarginClosestToEdgeHit || inHollowSmallestAreaHit || undefined\n\t}\n\n\t/**\n\t * Get the shapes, if any, at a given page point.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getShapesAtPoint({ x: 100, y: 100 })\n\t * editor.getShapesAtPoint({ x: 100, y: 100 }, { hitInside: true, exact: true })\n\t * ```\n\t *\n\t * @param point - The page point to test.\n\t * @param opts - The options for the hit point testing.\n\t *\n\t * @public\n\t */\n\tgetShapesAtPoint(\n\t\tpoint: VecLike,\n\t\topts = {} as { margin?: number; hitInside?: boolean }\n\t): TLShape[] {\n\t\treturn this.getCurrentPageShapes().filter(\n\t\t\t(shape) => !this.isShapeHidden(shape) && this.isPointInShape(shape, point, opts)\n\t\t)\n\t}\n\n\t/**\n\t * Test whether a point (in the current page space) will will a shape. This method takes into account masks,\n\t * such as when a shape is the child of a frame and is partially clipped by the frame.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.isPointInShape({ x: 100, y: 100 }, myShape)\n\t * ```\n\t *\n\t * @param shape - The shape to test against.\n\t * @param point - The page point to test (in the current page space).\n\t * @param opts - The options for the hit point testing.\n\t *\n\t * @public\n\t */\n\tisPointInShape(\n\t\tshape: TLShape | TLShapeId,\n\t\tpoint: VecLike,\n\t\topts = {} as {\n\t\t\tmargin?: number\n\t\t\thitInside?: boolean\n\t\t}\n\t): boolean {\n\t\tconst { hitInside = false, margin = 0 } = opts\n\t\tconst id = typeof shape === 'string' ? shape : shape.id\n\t\t// If the shape is masked, and if the point falls outside of that\n\t\t// mask, then it's definitely a miss\u2014we don't need to test further.\n\t\tconst pageMask = this.getShapeMask(id)\n\t\tif (pageMask && !pointInPolygon(point, pageMask)) return false\n\n\t\treturn this.getShapeGeometry(id).hitTestPoint(\n\t\t\tthis.getPointInShapeSpace(shape, point),\n\t\t\tmargin,\n\t\t\thitInside\n\t\t)\n\t}\n\n\t/**\n\t * Convert a point in the current page space to a point in the local space of a shape. For example, if a\n\t * shape's page point were `{ x: 100, y: 100 }`, a page point at `{ x: 110, y: 110 }` would be at\n\t * `{ x: 10, y: 10 }` in the shape's local space.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getPointInShapeSpace(myShape, { x: 100, y: 100 })\n\t * ```\n\t *\n\t * @param shape - The shape to get the point in the local space of.\n\t * @param point - The page point to get in the local space of the shape.\n\t *\n\t * @public\n\t */\n\tgetPointInShapeSpace(shape: TLShape | TLShapeId, point: VecLike): Vec {\n\t\tconst id = typeof shape === 'string' ? shape : shape.id\n\t\treturn this._getShapePageTransformCache().get(id)!.clone().invert().applyToPoint(point)\n\t}\n\n\t/**\n\t * Convert a delta in the current page space to a point in the local space of a shape's parent.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getPointInParentSpace(myShape.id, { x: 100, y: 100 })\n\t * ```\n\t *\n\t * @param shape - The shape to get the point in the local space of.\n\t * @param point - The page point to get in the local space of the shape.\n\t *\n\t * @public\n\t */\n\tgetPointInParentSpace(shape: TLShapeId | TLShape, point: VecLike): Vec {\n\t\tconst id = typeof shape === 'string' ? shape : shape.id\n\t\tconst freshShape = this.getShape(id)\n\t\tif (!freshShape) return new Vec(0, 0)\n\t\tif (isPageId(freshShape.parentId)) return Vec.From(point)\n\n\t\tconst parentTransform = this.getShapePageTransform(freshShape.parentId)\n\t\tif (!parentTransform) return Vec.From(point)\n\t\treturn parentTransform.clone().invert().applyToPoint(point)\n\t}\n\n\t/**\n\t * An array containing all of the shapes in the current page.\n\t *\n\t * @public\n\t */\n\t@computed getCurrentPageShapes(): TLShape[] {\n\t\treturn Array.from(this.getCurrentPageShapeIds(), (id) => this.store.get(id)! as TLShape)\n\t}\n\n\t/**\n\t * An array containing all of the shapes in the current page, sorted in z-index order (accounting\n\t * for nested shapes): e.g. A, B, BA, BB, C.\n\t *\n\t * @public\n\t */\n\t@computed getCurrentPageShapesSorted(): TLShape[] {\n\t\tconst result: TLShape[] = []\n\t\tconst topLevelShapes = this.getSortedChildIdsForParent(this.getCurrentPageId())\n\n\t\tfor (let i = 0, n = topLevelShapes.length; i < n; i++) {\n\t\t\tpushShapeWithDescendants(this, topLevelShapes[i], result)\n\t\t}\n\n\t\treturn result\n\t}\n\n\t/**\n\t * An array containing all of the rendering shapes in the current page, sorted in z-index order (accounting\n\t * for nested shapes): e.g. A, B, BA, BB, C.\n\t *\n\t * @public\n\t */\n\t@computed getCurrentPageRenderingShapesSorted(): TLShape[] {\n\t\tconst culledShapes = this.getCulledShapes()\n\t\treturn this.getCurrentPageShapesSorted().filter(\n\t\t\t({ id }) => !culledShapes.has(id) && !this.isShapeHidden(id)\n\t\t)\n\t}\n\n\t/**\n\t * Get whether a shape matches the type of a TLShapeUtil.\n\t *\n\t * @example\n\t * ```ts\n\t * const isArrowShape = isShapeOfType(someShape, 'arrow')\n\t * ```\n\t *\n\t * @param util - the TLShapeUtil constructor to test against\n\t * @param shape - the shape to test\n\t *\n\t * @public\n\t */\n\tisShapeOfType(shape: TLUnknownShape, type: T['type']): shape is T\n\tisShapeOfType(\n\t\tshapeId: TLUnknownShape['id'],\n\t\ttype: T['type']\n\t): shapeId is T['id']\n\tisShapeOfType(\n\t\targ: TLUnknownShape | TLUnknownShape['id'],\n\t\ttype: T['type']\n\t) {\n\t\tconst shape = typeof arg === 'string' ? this.getShape(arg) : arg\n\t\tif (!shape) return false\n\t\treturn shape.type === type\n\t}\n\n\t/**\n\t * Get a shape by its id.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getShape('box1')\n\t * ```\n\t *\n\t * @param shape - The shape (or the id of the shape) to get.\n\t *\n\t * @public\n\t */\n\tgetShape(shape: TLShape | TLParentId): T | undefined {\n\t\tconst id = typeof shape === 'string' ? shape : shape.id\n\t\tif (!isShapeId(id)) return undefined\n\t\treturn this.store.get(id) as T\n\t}\n\n\t/**\n\t * Get the parent shape for a given shape. Returns undefined if the shape is the direct child of\n\t * the page.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getShapeParent(myShape)\n\t * ```\n\t *\n\t * @public\n\t */\n\tgetShapeParent(shape?: TLShape | TLShapeId): TLShape | undefined {\n\t\tconst id = typeof shape === 'string' ? shape : shape?.id\n\t\tif (!id) return undefined\n\t\tconst freshShape = this.getShape(id)\n\t\tif (freshShape === undefined || !isShapeId(freshShape.parentId)) return undefined\n\t\treturn this.store.get(freshShape.parentId)\n\t}\n\n\t/**\n\t * If siblingShape and targetShape are siblings, this returns targetShape. If targetShape has an\n\t * ancestor who is a sibling of siblingShape, this returns that ancestor. Otherwise, this returns\n\t * undefined.\n\t *\n\t * @internal\n\t */\n\tgetShapeNearestSibling(\n\t\tsiblingShape: TLShape,\n\t\ttargetShape: TLShape | undefined\n\t): TLShape | undefined {\n\t\tif (!targetShape) {\n\t\t\treturn undefined\n\t\t}\n\t\tif (targetShape.parentId === siblingShape.parentId) {\n\t\t\treturn targetShape\n\t\t}\n\n\t\tconst ancestor = this.findShapeAncestor(\n\t\t\ttargetShape,\n\t\t\t(ancestor) => ancestor.parentId === siblingShape.parentId\n\t\t)\n\n\t\treturn ancestor\n\t}\n\n\t/**\n\t * Get whether the given shape is the descendant of the given page.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.isShapeInPage(myShape)\n\t * editor.isShapeInPage(myShape, 'page1')\n\t * ```\n\t *\n\t * @param shape - The shape to check.\n\t * @param pageId - The id of the page to check against. Defaults to the current page.\n\t *\n\t * @public\n\t */\n\tisShapeInPage(shape: TLShape | TLShapeId, pageId = this.getCurrentPageId()): boolean {\n\t\tconst id = typeof shape === 'string' ? shape : shape.id\n\t\tconst shapeToCheck = this.getShape(id)\n\t\tif (!shapeToCheck) return false\n\n\t\tlet shapeIsInPage = false\n\n\t\tif (shapeToCheck.parentId === pageId) {\n\t\t\tshapeIsInPage = true\n\t\t} else {\n\t\t\tlet parent = this.getShape(shapeToCheck.parentId)\n\t\t\tisInPageSearch: while (parent) {\n\t\t\t\tif (parent.parentId === pageId) {\n\t\t\t\t\tshapeIsInPage = true\n\t\t\t\t\tbreak isInPageSearch\n\t\t\t\t}\n\t\t\t\tparent = this.getShape(parent.parentId)\n\t\t\t}\n\t\t}\n\n\t\treturn shapeIsInPage\n\t}\n\n\t/**\n\t * Get the id of the containing page for a given shape.\n\t *\n\t * @param shape - The shape to get the page id for.\n\t *\n\t * @returns The id of the page that contains the shape, or undefined if the shape is undefined.\n\t *\n\t * @public\n\t */\n\tgetAncestorPageId(shape?: TLShape | TLShapeId): TLPageId | undefined {\n\t\tconst id = typeof shape === 'string' ? shape : shape?.id\n\t\tconst _shape = id && this.getShape(id)\n\t\tif (!_shape) return undefined\n\t\tif (isPageId(_shape.parentId)) {\n\t\t\treturn _shape.parentId\n\t\t} else {\n\t\t\treturn this.getAncestorPageId(this.getShape(_shape.parentId))\n\t\t}\n\t}\n\n\t// Parents and children\n\n\t/**\n\t * A cache of parents to children.\n\t *\n\t * @internal\n\t */\n\tprivate readonly _parentIdsToChildIds: ReturnType\n\n\t/**\n\t * Reparent shapes to a new parent. This operation preserves the shape's current page positions /\n\t * rotations.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.reparentShapes([box1, box2], 'frame1')\n\t * editor.reparentShapes([box1.id, box2.id], 'frame1')\n\t * editor.reparentShapes([box1.id, box2.id], 'frame1', 4)\n\t * ```\n\t *\n\t * @param shapes - The shapes (or shape ids) of the shapes to reparent.\n\t * @param parentId - The id of the new parent shape.\n\t * @param insertIndex - The index to insert the children.\n\t *\n\t * @public\n\t */\n\treparentShapes(shapes: TLShapeId[] | TLShape[], parentId: TLParentId, insertIndex?: IndexKey) {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string' ? (shapes as TLShapeId[]) : shapes.map((s) => (s as TLShape).id)\n\t\tif (ids.length === 0) return this\n\n\t\tconst changes: TLShapePartial[] = []\n\n\t\tconst parentTransform = isPageId(parentId)\n\t\t\t? Mat.Identity()\n\t\t\t: this.getShapePageTransform(parentId)!\n\n\t\tconst parentPageRotation = parentTransform.rotation()\n\n\t\tlet indices: IndexKey[] = []\n\n\t\tconst sibs = compact(this.getSortedChildIdsForParent(parentId).map((id) => this.getShape(id)))\n\n\t\tif (insertIndex) {\n\t\t\tconst sibWithInsertIndex = sibs.find((s) => s.index === insertIndex)\n\t\t\tif (sibWithInsertIndex) {\n\t\t\t\t// If there's a sibling with the same index as the insert index...\n\t\t\t\tconst sibAbove = sibs[sibs.indexOf(sibWithInsertIndex) + 1]\n\t\t\t\tif (sibAbove) {\n\t\t\t\t\t// If the sibling has a sibling above it, insert the shapes\n\t\t\t\t\t// between the sibling and its sibling above it.\n\t\t\t\t\tindices = getIndicesBetween(insertIndex, sibAbove.index, ids.length)\n\t\t\t\t} else {\n\t\t\t\t\t// Or if the sibling is the top sibling, insert the shapes\n\t\t\t\t\t// above the sibling\n\t\t\t\t\tindices = getIndicesAbove(insertIndex, ids.length)\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// If there's no collision, then we can start at the insert index\n\t\t\t\tconst sibAbove = sibs.sort(sortByIndex).find((s) => s.index > insertIndex)\n\n\t\t\t\tif (sibAbove) {\n\t\t\t\t\t// If the siblings include a sibling with a higher index, insert the shapes\n\t\t\t\t\t// between the insert index and the sibling with the higher index.\n\t\t\t\t\tindices = getIndicesBetween(insertIndex, sibAbove.index, ids.length)\n\t\t\t\t} else {\n\t\t\t\t\t// Otherwise, we're at the top of the order, so insert the shapes above\n\t\t\t\t\t// the insert index.\n\t\t\t\t\tindices = getIndicesAbove(insertIndex, ids.length)\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\t// If insert index is not specified, start the index at the top.\n\t\t\tconst sib = sibs.length && sibs[sibs.length - 1]\n\t\t\tindices = sib ? getIndicesAbove(sib.index, ids.length) : getIndices(ids.length)\n\t\t}\n\n\t\tconst invertedParentTransform = parentTransform.clone().invert()\n\n\t\tconst shapesToReparent = compact(ids.map((id) => this.getShape(id)))\n\n\t\t// Ignore locked shapes so that we can reparent locked shapes, for example\n\t\t// when a locked shape's parent is deleted.\n\t\tthis.run(\n\t\t\t() => {\n\t\t\t\tfor (let i = 0; i < shapesToReparent.length; i++) {\n\t\t\t\t\tconst shape = shapesToReparent[i]\n\n\t\t\t\t\tconst pageTransform = this.getShapePageTransform(shape)!\n\t\t\t\t\tif (!pageTransform) continue\n\n\t\t\t\t\tconst pagePoint = pageTransform.point()\n\t\t\t\t\tif (!pagePoint) continue\n\n\t\t\t\t\tconst newPoint = invertedParentTransform.applyToPoint(pagePoint)\n\t\t\t\t\tconst newRotation = pageTransform.rotation() - parentPageRotation\n\n\t\t\t\t\tchanges.push({\n\t\t\t\t\t\tid: shape.id,\n\t\t\t\t\t\ttype: shape.type,\n\t\t\t\t\t\tparentId: parentId,\n\t\t\t\t\t\tx: newPoint.x,\n\t\t\t\t\t\ty: newPoint.y,\n\t\t\t\t\t\trotation: newRotation,\n\t\t\t\t\t\tindex: indices[i],\n\t\t\t\t\t})\n\t\t\t\t}\n\n\t\t\t\tthis.updateShapes(changes)\n\t\t\t},\n\t\t\t{ ignoreShapeLock: true }\n\t\t)\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Get the index above the highest child of a given parent.\n\t *\n\t * @param parent - The parent (or the id) of the parent.\n\t *\n\t * @returns The index.\n\t *\n\t * @public\n\t */\n\tgetHighestIndexForParent(parent: TLParentId | TLPage | TLShape): IndexKey {\n\t\tconst parentId = typeof parent === 'string' ? parent : parent.id\n\t\tconst children = this._parentIdsToChildIds.get()[parentId]\n\n\t\tif (!children || children.length === 0) {\n\t\t\treturn 'a1' as IndexKey\n\t\t}\n\t\tconst shape = this.getShape(children[children.length - 1])!\n\t\treturn getIndexAbove(shape.index)\n\t}\n\n\t/**\n\t * Get an array of all the children of a shape.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getSortedChildIdsForParent('frame1')\n\t * ```\n\t *\n\t * @param parent - The parent (or the id) of the parent shape.\n\t *\n\t * @public\n\t */\n\tgetSortedChildIdsForParent(parent: TLParentId | TLPage | TLShape): TLShapeId[] {\n\t\tconst parentId = typeof parent === 'string' ? parent : parent.id\n\t\tconst ids = this._parentIdsToChildIds.get()[parentId]\n\t\tif (!ids) return EMPTY_ARRAY\n\t\treturn ids\n\t}\n\n\t/**\n\t * Run a visitor function for all descendants of a shape.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.visitDescendants('frame1', myCallback)\n\t * ```\n\t *\n\t * @param parent - The parent (or the id) of the parent shape.\n\t * @param visitor - The visitor function.\n\t *\n\t * @public\n\t */\n\tvisitDescendants(\n\t\tparent: TLParentId | TLPage | TLShape,\n\t\tvisitor: (id: TLShapeId) => void | false\n\t): this {\n\t\tconst parentId = typeof parent === 'string' ? parent : parent.id\n\t\tconst children = this.getSortedChildIdsForParent(parentId)\n\t\tfor (const id of children) {\n\t\t\tif (visitor(id) === false) continue\n\t\t\tthis.visitDescendants(id, visitor)\n\t\t}\n\t\treturn this\n\t}\n\n\t/**\n\t * Get the shape ids of all descendants of the given shapes (including the shapes themselves). IDs are returned in z-index order.\n\t *\n\t * @param ids - The ids of the shapes to get descendants of.\n\t *\n\t * @returns The descendant ids.\n\t *\n\t * @public\n\t */\n\tgetShapeAndDescendantIds(ids: TLShapeId[]): Set {\n\t\tconst shapeIds = new Set()\n\t\tfor (const shape of ids.map((id) => this.getShape(id)!).sort(sortByIndex)) {\n\t\t\tshapeIds.add(shape.id)\n\t\t\tthis.visitDescendants(shape, (descendantId) => {\n\t\t\t\tshapeIds.add(descendantId)\n\t\t\t})\n\t\t}\n\t\treturn shapeIds\n\t}\n\n\t/**\n\t * Get the shape that some shapes should be dropped on at a given point.\n\t *\n\t * @param point - The point to find the parent for.\n\t * @param droppingShapes - The shapes that are being dropped.\n\t *\n\t * @returns The shape to drop on.\n\t *\n\t * @public\n\t */\n\tgetDroppingOverShape(point: VecLike, droppingShapes: TLShape[] = []) {\n\t\t// starting from the top...\n\t\tconst currentPageShapesSorted = this.getCurrentPageShapesSorted()\n\t\tfor (let i = currentPageShapesSorted.length - 1; i >= 0; i--) {\n\t\t\tconst shape = currentPageShapesSorted[i]\n\n\t\t\tif (\n\t\t\t\t// ignore hidden shapes\n\t\t\t\tthis.isShapeHidden(shape) ||\n\t\t\t\t// don't allow dropping on selected shapes\n\t\t\t\tthis.getSelectedShapeIds().includes(shape.id) ||\n\t\t\t\t// only allow shapes that can receive children\n\t\t\t\t!this.getShapeUtil(shape).canDropShapes(shape, droppingShapes) ||\n\t\t\t\t// don't allow dropping a shape on itself or one of it's children\n\t\t\t\tdroppingShapes.find((s) => s.id === shape.id || this.hasAncestor(shape, s.id))\n\t\t\t) {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\t// Only allow dropping into the masked page bounds of the shape, e.g. when a frame is\n\t\t\t// partially clipped by its own parent frame\n\t\t\tconst maskedPageBounds = this.getShapeMaskedPageBounds(shape.id)\n\n\t\t\tif (\n\t\t\t\tmaskedPageBounds &&\n\t\t\t\tmaskedPageBounds.containsPoint(point) &&\n\t\t\t\tthis.getShapeGeometry(shape).hitTestPoint(this.getPointInShapeSpace(shape, point), 0, true)\n\t\t\t) {\n\t\t\t\treturn shape\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Get the shape that should be selected when you click on a given shape, assuming there is\n\t * nothing already selected. It will not return anything higher than or including the current\n\t * focus layer.\n\t *\n\t * @param shape - The shape to get the outermost selectable shape for.\n\t * @param filter - A function to filter the selectable shapes.\n\t *\n\t * @returns The outermost selectable shape.\n\t *\n\t * @public\n\t */\n\tgetOutermostSelectableShape(\n\t\tshape: TLShape | TLShapeId,\n\t\tfilter?: (shape: TLShape) => boolean\n\t): TLShape {\n\t\tconst id = typeof shape === 'string' ? shape : shape.id\n\t\tconst freshShape = this.getShape(id)!\n\t\tlet match = freshShape\n\t\tlet node = freshShape as TLShape | undefined\n\n\t\tconst focusedGroup = this.getFocusedGroup()\n\n\t\twhile (node) {\n\t\t\tif (\n\t\t\t\tthis.isShapeOfType(node, 'group') &&\n\t\t\t\tfocusedGroup?.id !== node.id &&\n\t\t\t\t!this.hasAncestor(focusedGroup, node.id) &&\n\t\t\t\t(filter?.(node) ?? true)\n\t\t\t) {\n\t\t\t\tmatch = node\n\t\t\t} else if (focusedGroup?.id === node.id) {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tnode = this.getShapeParent(node)\n\t\t}\n\n\t\treturn match\n\t}\n\n\t/* -------------------- Bindings -------------------- */\n\n\t@computed\n\tprivate _getBindingsIndexCache() {\n\t\tconst index = bindingsIndex(this)\n\t\treturn this.store.createComputedCache('bindingsIndex', (shape) => {\n\t\t\treturn index.get().get(shape.id)\n\t\t})\n\t}\n\n\t/**\n\t * Get a binding from the store by its ID if it exists.\n\t */\n\tgetBinding(id: TLBindingId): TLBinding | undefined {\n\t\treturn this.store.get(id) as TLBinding | undefined\n\t}\n\n\t/**\n\t * Get all bindings of a certain type _from_ a particular shape. These are the bindings whose\n\t * `fromId` matched the shape's ID.\n\t */\n\tgetBindingsFromShape(\n\t\tshape: TLShape | TLShapeId,\n\t\ttype: Binding['type']\n\t): Binding[] {\n\t\tconst id = typeof shape === 'string' ? shape : shape.id\n\t\treturn this.getBindingsInvolvingShape(id).filter(\n\t\t\t(b) => b.fromId === id && b.type === type\n\t\t) as Binding[]\n\t}\n\n\t/**\n\t * Get all bindings of a certain type _to_ a particular shape. These are the bindings whose\n\t * `toId` matches the shape's ID.\n\t */\n\tgetBindingsToShape(\n\t\tshape: TLShape | TLShapeId,\n\t\ttype: Binding['type']\n\t): Binding[] {\n\t\tconst id = typeof shape === 'string' ? shape : shape.id\n\t\treturn this.getBindingsInvolvingShape(id).filter(\n\t\t\t(b) => b.toId === id && b.type === type\n\t\t) as Binding[]\n\t}\n\n\t/**\n\t * Get all bindings involving a particular shape. This includes bindings where the shape is the\n\t * `fromId` or `toId`. If a type is provided, only bindings of that type are returned.\n\t */\n\tgetBindingsInvolvingShape(\n\t\tshape: TLShape | TLShapeId,\n\t\ttype?: Binding['type']\n\t): Binding[] {\n\t\tconst id = typeof shape === 'string' ? shape : shape.id\n\t\tconst result = this._getBindingsIndexCache().get(id) ?? EMPTY_ARRAY\n\t\tif (!type) return result as Binding[]\n\t\treturn result.filter((b) => b.type === type) as Binding[]\n\t}\n\n\t/**\n\t * Create bindings from a list of partial bindings. You can omit the ID and most props of a\n\t * binding, but the `type`, `toId`, and `fromId` must all be provided.\n\t */\n\tcreateBindings(partials: TLBindingCreate[]) {\n\t\tconst bindings: TLBinding[] = []\n\t\tfor (const partial of partials) {\n\t\t\tconst fromShape = this.getShape(partial.fromId)\n\t\t\tconst toShape = this.getShape(partial.toId)\n\t\t\tif (!fromShape || !toShape) continue\n\t\t\tif (!this.canBindShapes({ fromShape, toShape, binding: partial })) continue\n\n\t\t\tconst util = this.getBindingUtil(partial.type)\n\t\t\tconst defaultProps = util.getDefaultProps()\n\t\t\tconst binding = this.store.schema.types.binding.create({\n\t\t\t\t...partial,\n\t\t\t\tid: partial.id ?? createBindingId(),\n\t\t\t\tprops: {\n\t\t\t\t\t...defaultProps,\n\t\t\t\t\t...partial.props,\n\t\t\t\t},\n\t\t\t}) as TLBinding\n\n\t\t\tbindings.push(binding)\n\t\t}\n\n\t\tthis.store.put(bindings)\n\t\treturn this\n\t}\n\n\t/**\n\t * Create a single binding from a partial. You can omit the ID and most props of a binding, but\n\t * the `type`, `toId`, and `fromId` must all be provided.\n\t */\n\tcreateBinding(partial: TLBindingCreate) {\n\t\treturn this.createBindings([partial])\n\t}\n\n\t/**\n\t * Update bindings from a list of partial bindings. Each partial must include an ID, which will\n\t * be used to match the binding to it's existing record. If there is no existing record, that\n\t * binding is skipped. The changes from the partial are merged into the existing record.\n\t */\n\tupdateBindings(partials: (TLBindingUpdate | null | undefined)[]) {\n\t\tconst updated: TLBinding[] = []\n\n\t\tfor (const partial of partials) {\n\t\t\tif (!partial) continue\n\n\t\t\tconst current = this.getBinding(partial.id)\n\t\t\tif (!current) continue\n\n\t\t\tconst updatedBinding = applyPartialToRecordWithProps(current, partial)\n\t\t\tif (updatedBinding === current) continue\n\n\t\t\tconst fromShape = this.getShape(updatedBinding.fromId)\n\t\t\tconst toShape = this.getShape(updatedBinding.toId)\n\t\t\tif (!fromShape || !toShape) continue\n\t\t\tif (!this.canBindShapes({ fromShape, toShape, binding: updatedBinding })) continue\n\n\t\t\tupdated.push(updatedBinding)\n\t\t}\n\n\t\tthis.store.put(updated)\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Update a binding from a partial binding. Each partial must include an ID, which will be used\n\t * to match the binding to it's existing record. If there is no existing record, that binding is\n\t * skipped. The changes from the partial are merged into the existing record.\n\t */\n\tupdateBinding(partial: TLBindingUpdate) {\n\t\treturn this.updateBindings([partial])\n\t}\n\n\t/**\n\t * Delete several bindings by their IDs. If a binding ID doesn't exist, it's ignored.\n\t */\n\tdeleteBindings(bindings: (TLBinding | TLBindingId)[], { isolateShapes = false } = {}) {\n\t\tconst ids = bindings.map((binding) => (typeof binding === 'string' ? binding : binding.id))\n\t\tif (isolateShapes) {\n\t\t\tthis.store.atomic(() => {\n\t\t\t\tfor (const id of ids) {\n\t\t\t\t\tconst binding = this.getBinding(id)\n\t\t\t\t\tif (!binding) continue\n\t\t\t\t\tconst util = this.getBindingUtil(binding)\n\t\t\t\t\tutil.onBeforeIsolateFromShape?.({ binding, removedShape: this.getShape(binding.toId)! })\n\t\t\t\t\tutil.onBeforeIsolateToShape?.({ binding, removedShape: this.getShape(binding.fromId)! })\n\t\t\t\t\tthis.store.remove([id])\n\t\t\t\t}\n\t\t\t})\n\t\t} else {\n\t\t\tthis.store.remove(ids)\n\t\t}\n\t\treturn this\n\t}\n\t/**\n\t * Delete a binding by its ID. If the binding doesn't exist, it's ignored.\n\t */\n\tdeleteBinding(binding: TLBinding | TLBindingId, opts?: Parameters[1]) {\n\t\treturn this.deleteBindings([binding], opts)\n\t}\n\tcanBindShapes({\n\t\tfromShape,\n\t\ttoShape,\n\t\tbinding,\n\t}: {\n\t\tfromShape: TLShape | { type: TLShape['type'] } | TLShape['type']\n\t\ttoShape: TLShape | { type: TLShape['type'] } | TLShape['type']\n\t\tbinding: TLBinding | { type: TLBinding['type'] } | TLBinding['type']\n\t}): boolean {\n\t\tconst fromShapeType = typeof fromShape === 'string' ? fromShape : fromShape.type\n\t\tconst toShapeType = typeof toShape === 'string' ? toShape : toShape.type\n\t\tconst bindingType = typeof binding === 'string' ? binding : binding.type\n\n\t\tconst canBindOpts = { fromShapeType, toShapeType, bindingType }\n\n\t\tif (fromShapeType === toShapeType) {\n\t\t\treturn this.getShapeUtil(fromShapeType).canBind(canBindOpts)\n\t\t}\n\n\t\treturn (\n\t\t\tthis.getShapeUtil(fromShapeType).canBind(canBindOpts) &&\n\t\t\tthis.getShapeUtil(toShapeType).canBind(canBindOpts)\n\t\t)\n\t}\n\n\t/* -------------------- Commands -------------------- */\n\n\t/**\n\t * Rotate shapes by a delta in radians.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.rotateShapesBy(editor.getSelectedShapeIds(), Math.PI)\n\t * editor.rotateShapesBy(editor.getSelectedShapeIds(), Math.PI / 2)\n\t * ```\n\t *\n\t * @param shapes - The shapes (or shape ids) of the shapes to move.\n\t * @param delta - The delta in radians to apply to the selection rotation.\n\t * @param opts - The options for the rotation.\n\t */\n\trotateShapesBy(\n\t\tshapes: TLShapeId[] | TLShape[],\n\t\tdelta: number,\n\t\topts?: { center?: VecLike }\n\t): this {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\n\t\tif (ids.length <= 0) return this\n\n\t\tconst snapshot = getRotationSnapshot({ editor: this, ids })\n\t\tif (!snapshot) return this\n\t\tapplyRotationToSnapshotShapes({\n\t\t\tdelta,\n\t\t\tsnapshot,\n\t\t\teditor: this,\n\t\t\tstage: 'one-off',\n\t\t\tcenterOverride: opts?.center,\n\t\t})\n\n\t\treturn this\n\t}\n\n\tprivate getChangesToTranslateShape(initialShape: TLShape, newShapeCoords: VecLike): TLShape {\n\t\tlet workingShape = initialShape\n\t\tconst util = this.getShapeUtil(initialShape)\n\n\t\tworkingShape = applyPartialToRecordWithProps(\n\t\t\tworkingShape,\n\t\t\tutil.onTranslateStart?.(workingShape) ?? undefined\n\t\t)\n\n\t\tworkingShape = applyPartialToRecordWithProps(workingShape, {\n\t\t\tid: initialShape.id,\n\t\t\ttype: initialShape.type,\n\t\t\tx: newShapeCoords.x,\n\t\t\ty: newShapeCoords.y,\n\t\t})\n\n\t\tworkingShape = applyPartialToRecordWithProps(\n\t\t\tworkingShape,\n\t\t\tutil.onTranslate?.(initialShape, workingShape) ?? undefined\n\t\t)\n\n\t\tworkingShape = applyPartialToRecordWithProps(\n\t\t\tworkingShape,\n\t\t\tutil.onTranslateEnd?.(initialShape, workingShape) ?? undefined\n\t\t)\n\n\t\treturn workingShape\n\t}\n\n\t/**\n\t * Move shapes by a delta.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.nudgeShapes(['box1', 'box2'], { x: 8, y: 8 })\n\t * ```\n\t *\n\t * @param shapes - The shapes (or shape ids) to move.\n\t * @param offset - The offset to apply to the shapes.\n\t */\n\tnudgeShapes(shapes: TLShapeId[] | TLShape[], offset: VecLike): this {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\n\t\tif (ids.length <= 0) return this\n\t\tconst changes: TLShapePartial[] = []\n\n\t\tfor (const id of ids) {\n\t\t\tconst shape = this.getShape(id)!\n\t\t\tconst localDelta = Vec.From(offset)\n\t\t\tconst parentTransform = this.getShapeParentTransform(shape)\n\t\t\tif (parentTransform) localDelta.rot(-parentTransform.rotation())\n\n\t\t\tchanges.push(this.getChangesToTranslateShape(shape, localDelta.add(shape)))\n\t\t}\n\n\t\tthis.updateShapes(changes)\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Duplicate shapes.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.duplicateShapes(['box1', 'box2'], { x: 8, y: 8 })\n\t * editor.duplicateShapes(editor.getSelectedShapes(), { x: 8, y: 8 })\n\t * ```\n\t *\n\t * @param shapes - The shapes (or shape ids) to duplicate.\n\t * @param offset - The offset (in pixels) to apply to the duplicated shapes.\n\t *\n\t * @public\n\t */\n\tduplicateShapes(shapes: TLShapeId[] | TLShape[], offset?: VecLike): this {\n\t\tthis.run(() => {\n\t\t\tconst ids =\n\t\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\n\t\t\tif (ids.length <= 0) return this\n\n\t\t\tconst initialIds = new Set(ids)\n\t\t\tconst shapeIdSet = this.getShapeAndDescendantIds(ids)\n\n\t\t\tconst orderedShapeIds = [...shapeIdSet].reverse()\n\t\t\tconst shapeIds = new Map()\n\t\t\tfor (const shapeId of shapeIdSet) {\n\t\t\t\tshapeIds.set(shapeId, createShapeId())\n\t\t\t}\n\n\t\t\tconst { shapesToCreateWithOriginals, bindingsToCreate } = withIsolatedShapes(\n\t\t\t\tthis,\n\t\t\t\tshapeIdSet,\n\t\t\t\t(bindingIdsToMaintain) => {\n\t\t\t\t\tconst bindingsToCreate: TLBinding[] = []\n\t\t\t\t\tfor (const originalId of bindingIdsToMaintain) {\n\t\t\t\t\t\tconst originalBinding = this.getBinding(originalId)\n\t\t\t\t\t\tif (!originalBinding) continue\n\n\t\t\t\t\t\tconst duplicatedId = createBindingId()\n\t\t\t\t\t\tbindingsToCreate.push({\n\t\t\t\t\t\t\t...originalBinding,\n\t\t\t\t\t\t\tid: duplicatedId,\n\t\t\t\t\t\t\tfromId: assertExists(shapeIds.get(originalBinding.fromId)),\n\t\t\t\t\t\t\ttoId: assertExists(shapeIds.get(originalBinding.toId)),\n\t\t\t\t\t\t})\n\t\t\t\t\t}\n\n\t\t\t\t\tconst shapesToCreateWithOriginals: { shape: TLShape; originalShape: TLShape }[] = []\n\t\t\t\t\tfor (const originalId of orderedShapeIds) {\n\t\t\t\t\t\tconst duplicatedId = assertExists(shapeIds.get(originalId))\n\t\t\t\t\t\tconst originalShape = this.getShape(originalId)\n\t\t\t\t\t\tif (!originalShape) continue\n\n\t\t\t\t\t\tlet ox = 0\n\t\t\t\t\t\tlet oy = 0\n\n\t\t\t\t\t\tif (offset && initialIds.has(originalId)) {\n\t\t\t\t\t\t\tconst parentTransform = this.getShapeParentTransform(originalShape)\n\t\t\t\t\t\t\tconst vec = new Vec(offset.x, offset.y).rot(-parentTransform!.rotation())\n\t\t\t\t\t\t\tox = vec.x\n\t\t\t\t\t\t\toy = vec.y\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tshapesToCreateWithOriginals.push({\n\t\t\t\t\t\t\tshape: {\n\t\t\t\t\t\t\t\t...originalShape,\n\t\t\t\t\t\t\t\tid: duplicatedId,\n\t\t\t\t\t\t\t\tx: originalShape.x + ox,\n\t\t\t\t\t\t\t\ty: originalShape.y + oy,\n\t\t\t\t\t\t\t\t// Use a dummy index for now, it will get updated outside of the `withIsolatedShapes`\n\t\t\t\t\t\t\t\tindex: 'a1' as IndexKey,\n\t\t\t\t\t\t\t\tparentId:\n\t\t\t\t\t\t\t\t\tshapeIds.get(originalShape.parentId as TLShapeId) ?? originalShape.parentId,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\toriginalShape,\n\t\t\t\t\t\t})\n\t\t\t\t\t}\n\n\t\t\t\t\treturn { shapesToCreateWithOriginals, bindingsToCreate }\n\t\t\t\t}\n\t\t\t)\n\n\t\t\t// We will update the indexes after the `withIsolatedShapes`, since we cannot rely on the indexes\n\t\t\t// to be correct inside of it.\n\t\t\tshapesToCreateWithOriginals.forEach(({ shape, originalShape }) => {\n\t\t\t\tconst parentId = originalShape.parentId\n\t\t\t\tconst siblings = this.getSortedChildIdsForParent(parentId)\n\t\t\t\tconst currentIndex = siblings.indexOf(originalShape.id)\n\t\t\t\tconst siblingAboveId = siblings[currentIndex + 1]\n\t\t\t\tconst siblingAbove = siblingAboveId ? this.getShape(siblingAboveId) : undefined\n\n\t\t\t\tconst index = getIndexBetween(originalShape.index, siblingAbove?.index)\n\n\t\t\t\tshape.index = index\n\t\t\t})\n\t\t\tconst shapesToCreate = shapesToCreateWithOriginals.map(({ shape }) => shape)\n\n\t\t\tconst maxShapesReached =\n\t\t\t\tshapesToCreate.length + this.getCurrentPageShapeIds().size > this.options.maxShapesPerPage\n\n\t\t\tif (maxShapesReached) {\n\t\t\t\talertMaxShapes(this)\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tthis.createShapes(shapesToCreate)\n\t\t\tthis.createBindings(bindingsToCreate)\n\t\t\tthis.setSelectedShapes(compact(ids.map((id) => shapeIds.get(id))))\n\n\t\t\tif (offset !== undefined) {\n\t\t\t\t// If we've offset the duplicated shapes, check to see whether their new bounds is entirely\n\t\t\t\t// contained in the current viewport. If not, then animate the camera to be centered on the\n\t\t\t\t// new shapes.\n\t\t\t\tconst selectionPageBounds = this.getSelectionPageBounds()\n\t\t\t\tconst viewportPageBounds = this.getViewportPageBounds()\n\t\t\t\tif (selectionPageBounds && !viewportPageBounds.contains(selectionPageBounds)) {\n\t\t\t\t\tthis.centerOnPoint(selectionPageBounds.center, {\n\t\t\t\t\t\tanimation: { duration: this.options.animationMediumMs },\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t}\n\t\t})\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Move shapes to page.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.moveShapesToPage(['box1', 'box2'], 'page1')\n\t * ```\n\t *\n\t * @param shapes - The shapes (or shape ids) of the shapes to move.\n\t * @param pageId - The id of the page where the shapes will be moved.\n\t *\n\t * @public\n\t */\n\tmoveShapesToPage(shapes: TLShapeId[] | TLShape[], pageId: TLPageId): this {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\n\t\tif (ids.length === 0) return this\n\t\tif (this.getIsReadonly()) return this\n\n\t\tconst currentPageId = this.getCurrentPageId()\n\n\t\tif (pageId === currentPageId) return this\n\t\tif (!this.store.has(pageId)) return this\n\n\t\t// Basically copy the shapes\n\t\tconst content = this.getContentFromCurrentPage(ids)\n\n\t\t// Just to be sure\n\t\tif (!content) return this\n\n\t\t// If there is no space on pageId, or if the selected shapes\n\t\t// would take the new page above the limit, don't move the shapes\n\t\tif (this.getPageShapeIds(pageId).size + content.shapes.length > this.options.maxShapesPerPage) {\n\t\t\talertMaxShapes(this, pageId)\n\t\t\treturn this\n\t\t}\n\n\t\tconst fromPageZ = this.getCamera().z\n\n\t\tthis.run(() => {\n\t\t\t// Delete the shapes on the current page\n\t\t\tthis.deleteShapes(ids)\n\n\t\t\t// Move to the next page\n\t\t\tthis.setCurrentPage(pageId)\n\n\t\t\t// Put the shape content onto the new page; parents and indices will\n\t\t\t// be taken care of by the putContent method; make sure to pop any focus\n\t\t\t// layers so that the content will be put onto the page.\n\t\t\tthis.setFocusedGroup(null)\n\t\t\tthis.selectNone()\n\t\t\tthis.putContentOntoCurrentPage(content, {\n\t\t\t\tselect: true,\n\t\t\t\tpreserveIds: true,\n\t\t\t\tpreservePosition: true,\n\t\t\t})\n\n\t\t\t// Force the new page's camera to be at the same zoom level as the\n\t\t\t// \"from\" page's camera, then center the \"to\" page's camera on the\n\t\t\t// pasted shapes\n\t\t\tthis.setCamera({ ...this.getCamera(), z: fromPageZ })\n\t\t\tthis.centerOnPoint(this.getSelectionRotatedPageBounds()!.center)\n\t\t})\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Toggle the lock state of one or more shapes. If there is a mix of locked and unlocked shapes, all shapes will be locked.\n\t *\n\t * @param shapes - The shapes (or shape ids) to toggle.\n\t *\n\t * @public\n\t */\n\ttoggleLock(shapes: TLShapeId[] | TLShape[]): this {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\n\t\tif (this.getIsReadonly() || ids.length === 0) return this\n\n\t\tlet allLocked = true,\n\t\t\tallUnlocked = true\n\t\tconst shapesToToggle: TLShape[] = []\n\t\tfor (const id of ids) {\n\t\t\tconst shape = this.getShape(id)\n\t\t\tif (shape) {\n\t\t\t\tshapesToToggle.push(shape)\n\t\t\t\tif (shape.isLocked) {\n\t\t\t\t\tallUnlocked = false\n\t\t\t\t} else {\n\t\t\t\t\tallLocked = false\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tthis.run(() => {\n\t\t\tif (allUnlocked) {\n\t\t\t\tthis.updateShapes(\n\t\t\t\t\tshapesToToggle.map((shape) => ({ id: shape.id, type: shape.type, isLocked: true }))\n\t\t\t\t)\n\t\t\t\tthis.setSelectedShapes([])\n\t\t\t} else if (allLocked) {\n\t\t\t\tthis.updateShapes(\n\t\t\t\t\tshapesToToggle.map((shape) => ({ id: shape.id, type: shape.type, isLocked: false }))\n\t\t\t\t)\n\t\t\t} else {\n\t\t\t\tthis.updateShapes(\n\t\t\t\t\tshapesToToggle.map((shape) => ({ id: shape.id, type: shape.type, isLocked: true }))\n\t\t\t\t)\n\t\t\t}\n\t\t})\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Send shapes to the back of the page's object list.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.sendToBack(['id1', 'id2'])\n\t * editor.sendToBack(box1, box2)\n\t * ```\n\t *\n\t * @param shapes - The shapes (or shape ids) to move.\n\t *\n\t * @public\n\t */\n\tsendToBack(shapes: TLShapeId[] | TLShape[]): this {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\t\tconst changes = getReorderingShapesChanges(this, 'toBack', ids as TLShapeId[])\n\t\tif (changes) this.updateShapes(changes)\n\t\treturn this\n\t}\n\n\t/**\n\t * Send shapes backward in the page's object list.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.sendBackward(['id1', 'id2'])\n\t * editor.sendBackward([box1, box2])\n\t * ```\n\t *\n\t * @param shapes - The shapes (or shape ids) to move.\n\t *\n\t * @public\n\t */\n\tsendBackward(shapes: TLShapeId[] | TLShape[]): this {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\t\tconst changes = getReorderingShapesChanges(this, 'backward', ids as TLShapeId[])\n\t\tif (changes) this.updateShapes(changes)\n\t\treturn this\n\t}\n\n\t/**\n\t * Bring shapes forward in the page's object list.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.bringForward(['id1', 'id2'])\n\t * editor.bringForward(box1, box2)\n\t * ```\n\t *\n\t * @param shapes - The shapes (or shape ids) to move.\n\t *\n\t * @public\n\t */\n\tbringForward(shapes: TLShapeId[] | TLShape[]): this {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\t\tconst changes = getReorderingShapesChanges(this, 'forward', ids as TLShapeId[])\n\t\tif (changes) this.updateShapes(changes)\n\t\treturn this\n\t}\n\n\t/**\n\t * Bring shapes to the front of the page's object list.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.bringToFront(['id1', 'id2'])\n\t * editor.bringToFront([box1, box2])\n\t * ```\n\t *\n\t * @param shapes - The shapes (or shape ids) to move.\n\t *\n\t * @public\n\t */\n\tbringToFront(shapes: TLShapeId[] | TLShape[]): this {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\t\tconst changes = getReorderingShapesChanges(this, 'toFront', ids as TLShapeId[])\n\t\tif (changes) this.updateShapes(changes)\n\t\treturn this\n\t}\n\n\t/**\n\t * Flip shape positions.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.flipShapes([box1, box2], 'horizontal', 32)\n\t * editor.flipShapes(editor.getSelectedShapeIds(), 'horizontal', 32)\n\t * ```\n\t *\n\t * @param shapes - The ids of the shapes to flip.\n\t * @param operation - Whether to flip horizontally or vertically.\n\t *\n\t * @public\n\t */\n\tflipShapes(shapes: TLShapeId[] | TLShape[], operation: 'horizontal' | 'vertical'): this {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\n\t\tif (this.getIsReadonly()) return this\n\n\t\tlet shapesToFlip = compact(ids.map((id) => this.getShape(id)))\n\n\t\tif (!shapesToFlip.length) return this\n\n\t\tshapesToFlip = compact(\n\t\t\tshapesToFlip\n\t\t\t\t.map((shape) => {\n\t\t\t\t\tif (this.isShapeOfType(shape, 'group')) {\n\t\t\t\t\t\treturn this.getSortedChildIdsForParent(shape.id).map((id) => this.getShape(id))\n\t\t\t\t\t}\n\n\t\t\t\t\treturn shape\n\t\t\t\t})\n\t\t\t\t.flat()\n\t\t)\n\n\t\tconst scaleOriginPage = Box.Common(\n\t\t\tcompact(shapesToFlip.map((id) => this.getShapePageBounds(id)))\n\t\t).center\n\n\t\tthis.run(() => {\n\t\t\tfor (const shape of shapesToFlip) {\n\t\t\t\tconst bounds = this.getShapeGeometry(shape).bounds\n\t\t\t\tconst initialPageTransform = this.getShapePageTransform(shape.id)\n\t\t\t\tif (!initialPageTransform) continue\n\t\t\t\tthis.resizeShape(\n\t\t\t\t\tshape.id,\n\t\t\t\t\t{ x: operation === 'horizontal' ? -1 : 1, y: operation === 'vertical' ? -1 : 1 },\n\t\t\t\t\t{\n\t\t\t\t\t\tinitialBounds: bounds,\n\t\t\t\t\t\tinitialPageTransform,\n\t\t\t\t\t\tinitialShape: shape,\n\t\t\t\t\t\tmode: 'scale_shape',\n\t\t\t\t\t\tisAspectRatioLocked: this.getShapeUtil(shape).isAspectRatioLocked(shape),\n\t\t\t\t\t\tscaleOrigin: scaleOriginPage,\n\t\t\t\t\t\tscaleAxisRotation: 0,\n\t\t\t\t\t}\n\t\t\t\t)\n\t\t\t}\n\t\t})\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Stack shape.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.stackShapes([box1, box2], 'horizontal', 32)\n\t * editor.stackShapes(editor.getSelectedShapeIds(), 'horizontal', 32)\n\t * ```\n\t *\n\t * @param shapes - The shapes (or shape ids) to stack.\n\t * @param operation - Whether to stack horizontally or vertically.\n\t * @param gap - The gap to leave between shapes.\n\t *\n\t * @public\n\t */\n\tstackShapes(\n\t\tshapes: TLShapeId[] | TLShape[],\n\t\toperation: 'horizontal' | 'vertical',\n\t\tgap: number\n\t): this {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\t\tif (this.getIsReadonly()) return this\n\n\t\tconst shapesToStack = ids\n\t\t\t.map((id) => this.getShape(id)) // always fresh shapes\n\t\t\t.filter((shape): shape is TLShape => {\n\t\t\t\tif (!shape) return false\n\n\t\t\t\treturn this.getShapeUtil(shape).canBeLaidOut(shape)\n\t\t\t})\n\n\t\tconst len = shapesToStack.length\n\n\t\tif ((gap === 0 && len < 3) || len < 2) return this\n\n\t\tconst pageBounds = Object.fromEntries(\n\t\t\tshapesToStack.map((shape) => [shape.id, this.getShapePageBounds(shape)!])\n\t\t)\n\n\t\tlet val: 'x' | 'y'\n\t\tlet min: 'minX' | 'minY'\n\t\tlet max: 'maxX' | 'maxY'\n\t\tlet dim: 'width' | 'height'\n\n\t\tif (operation === 'horizontal') {\n\t\t\tval = 'x'\n\t\t\tmin = 'minX'\n\t\t\tmax = 'maxX'\n\t\t\tdim = 'width'\n\t\t} else {\n\t\t\tval = 'y'\n\t\t\tmin = 'minY'\n\t\t\tmax = 'maxY'\n\t\t\tdim = 'height'\n\t\t}\n\n\t\tlet shapeGap: number\n\n\t\tif (gap === 0) {\n\t\t\tconst gaps: { gap: number; count: number }[] = []\n\n\t\t\tshapesToStack.sort((a, b) => pageBounds[a.id][min] - pageBounds[b.id][min])\n\n\t\t\t// Collect all of the gaps between shapes. We want to find\n\t\t\t// patterns (equal gaps between shapes) and use the most common\n\t\t\t// one as the gap for all of the shapes.\n\t\t\tfor (let i = 0; i < len - 1; i++) {\n\t\t\t\tconst shape = shapesToStack[i]\n\t\t\t\tconst nextShape = shapesToStack[i + 1]\n\n\t\t\t\tconst bounds = pageBounds[shape.id]\n\t\t\t\tconst nextBounds = pageBounds[nextShape.id]\n\n\t\t\t\tconst gap = nextBounds[min] - bounds[max]\n\n\t\t\t\tconst current = gaps.find((g) => g.gap === gap)\n\n\t\t\t\tif (current) {\n\t\t\t\t\tcurrent.count++\n\t\t\t\t} else {\n\t\t\t\t\tgaps.push({ gap, count: 1 })\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Which gap is the most common?\n\t\t\tlet maxCount = 0\n\t\t\tgaps.forEach((g) => {\n\t\t\t\tif (g.count > maxCount) {\n\t\t\t\t\tmaxCount = g.count\n\t\t\t\t\tshapeGap = g.gap\n\t\t\t\t}\n\t\t\t})\n\n\t\t\t// If there is no most-common gap, use the average gap.\n\t\t\tif (maxCount === 1) {\n\t\t\t\tshapeGap = Math.max(0, gaps.reduce((a, c) => a + c.gap * c.count, 0) / (len - 1))\n\t\t\t}\n\t\t} else {\n\t\t\t// If a gap was provided, then use that instead.\n\t\t\tshapeGap = gap\n\t\t}\n\n\t\tconst changes: TLShapePartial[] = []\n\n\t\tlet v = pageBounds[shapesToStack[0].id][max]\n\n\t\tshapesToStack.forEach((shape, i) => {\n\t\t\tif (i === 0) return\n\n\t\t\tconst delta = { x: 0, y: 0 }\n\t\t\tdelta[val] = v + shapeGap - pageBounds[shape.id][val]\n\n\t\t\tconst parent = this.getShapeParent(shape)\n\t\t\tconst localDelta = parent\n\t\t\t\t? Vec.Rot(delta, -this.getShapePageTransform(parent)!.decompose().rotation)\n\t\t\t\t: delta\n\n\t\t\tconst translateStartChanges = this.getShapeUtil(shape).onTranslateStart?.(shape)\n\n\t\t\tchanges.push(\n\t\t\t\ttranslateStartChanges\n\t\t\t\t\t? {\n\t\t\t\t\t\t\t...translateStartChanges,\n\t\t\t\t\t\t\t[val]: shape[val] + localDelta[val],\n\t\t\t\t\t\t}\n\t\t\t\t\t: {\n\t\t\t\t\t\t\tid: shape.id as any,\n\t\t\t\t\t\t\ttype: shape.type,\n\t\t\t\t\t\t\t[val]: shape[val] + localDelta[val],\n\t\t\t\t\t\t}\n\t\t\t)\n\n\t\t\tv += pageBounds[shape.id][dim] + shapeGap\n\t\t})\n\n\t\tthis.updateShapes(changes)\n\t\treturn this\n\t}\n\n\t/**\n\t * Pack shapes into a grid centered on their current position. Based on potpack (https://github.com/mapbox/potpack).\n\t *\n\t * @example\n\t * ```ts\n\t * editor.packShapes([box1, box2], 32)\n\t * editor.packShapes(editor.getSelectedShapeIds(), 32)\n\t * ```\n\t *\n\t *\n\t * @param shapes - The shapes (or shape ids) to pack.\n\t * @param gap - The padding to apply to the packed shapes. Defaults to 16.\n\t */\n\tpackShapes(shapes: TLShapeId[] | TLShape[], gap: number): this {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\n\t\tif (this.getIsReadonly()) return this\n\t\tif (ids.length < 2) return this\n\n\t\tconst shapesToPack = ids\n\t\t\t.map((id) => this.getShape(id)) // always fresh shapes\n\t\t\t.filter((shape): shape is TLShape => {\n\t\t\t\tif (!shape) return false\n\n\t\t\t\treturn this.getShapeUtil(shape).canBeLaidOut(shape)\n\t\t\t})\n\t\tconst shapePageBounds: Record = {}\n\t\tconst nextShapePageBounds: Record = {}\n\n\t\tlet shape: TLShape,\n\t\t\tbounds: Box,\n\t\t\tarea = 0\n\n\t\tfor (let i = 0; i < shapesToPack.length; i++) {\n\t\t\tshape = shapesToPack[i]\n\t\t\tbounds = this.getShapePageBounds(shape)!\n\t\t\tshapePageBounds[shape.id] = bounds\n\t\t\tnextShapePageBounds[shape.id] = bounds.clone()\n\t\t\tarea += bounds.width * bounds.height\n\t\t}\n\n\t\tconst commonBounds = Box.Common(compact(Object.values(shapePageBounds)))\n\n\t\tconst maxWidth = commonBounds.width\n\n\t\t// sort the shapes by height, descending\n\t\tshapesToPack.sort((a, b) => shapePageBounds[b.id].height - shapePageBounds[a.id].height)\n\n\t\t// Start with is (sort of) the square of the area\n\t\tconst startWidth = Math.max(Math.ceil(Math.sqrt(area / 0.95)), maxWidth)\n\n\t\t// first shape fills the width and is infinitely tall\n\t\tconst spaces: Box[] = [new Box(commonBounds.x, commonBounds.y, startWidth, Infinity)]\n\n\t\tlet width = 0\n\t\tlet height = 0\n\t\tlet space: Box\n\t\tlet last: Box\n\n\t\tfor (let i = 0; i < shapesToPack.length; i++) {\n\t\t\tshape = shapesToPack[i]\n\t\t\tbounds = nextShapePageBounds[shape.id]\n\n\t\t\t// starting at the back (smaller shapes)\n\t\t\tfor (let i = spaces.length - 1; i >= 0; i--) {\n\t\t\t\tspace = spaces[i]\n\n\t\t\t\t// find a space that is big enough to contain the shape\n\t\t\t\tif (bounds.width > space.width || bounds.height > space.height) continue\n\n\t\t\t\t// add the shape to its top-left corner\n\t\t\t\tbounds.x = space.x\n\t\t\t\tbounds.y = space.y\n\n\t\t\t\theight = Math.max(height, bounds.maxY)\n\t\t\t\twidth = Math.max(width, bounds.maxX)\n\n\t\t\t\tif (bounds.width === space.width && bounds.height === space.height) {\n\t\t\t\t\t// remove the space on a perfect fit\n\t\t\t\t\tlast = spaces.pop()!\n\t\t\t\t\tif (i < spaces.length) spaces[i] = last\n\t\t\t\t} else if (bounds.height === space.height) {\n\t\t\t\t\t// fit the shape into the space (width)\n\t\t\t\t\tspace.x += bounds.width + gap\n\t\t\t\t\tspace.width -= bounds.width + gap\n\t\t\t\t} else if (bounds.width === space.width) {\n\t\t\t\t\t// fit the shape into the space (height)\n\t\t\t\t\tspace.y += bounds.height + gap\n\t\t\t\t\tspace.height -= bounds.height + gap\n\t\t\t\t} else {\n\t\t\t\t\t// split the space into two spaces\n\t\t\t\t\tspaces.push(\n\t\t\t\t\t\tnew Box(\n\t\t\t\t\t\t\tspace.x + (bounds.width + gap),\n\t\t\t\t\t\t\tspace.y,\n\t\t\t\t\t\t\tspace.width - (bounds.width + gap),\n\t\t\t\t\t\t\tbounds.height\n\t\t\t\t\t\t)\n\t\t\t\t\t)\n\t\t\t\t\tspace.y += bounds.height + gap\n\t\t\t\t\tspace.height -= bounds.height + gap\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\n\t\tconst commonAfter = Box.Common(Object.values(nextShapePageBounds))\n\t\tconst centerDelta = Vec.Sub(commonBounds.center, commonAfter.center)\n\n\t\tlet nextBounds: Box\n\n\t\tconst changes: TLShapePartial[] = []\n\n\t\tfor (let i = 0; i < shapesToPack.length; i++) {\n\t\t\tshape = shapesToPack[i]\n\t\t\tbounds = shapePageBounds[shape.id]\n\t\t\tnextBounds = nextShapePageBounds[shape.id]\n\n\t\t\tconst delta = Vec.Sub(nextBounds.point, bounds.point).add(centerDelta)\n\t\t\tconst parentTransform = this.getShapeParentTransform(shape)\n\t\t\tif (parentTransform) delta.rot(-parentTransform.rotation())\n\n\t\t\tconst change: TLShapePartial = {\n\t\t\t\tid: shape.id,\n\t\t\t\ttype: shape.type,\n\t\t\t\tx: shape.x + delta.x,\n\t\t\t\ty: shape.y + delta.y,\n\t\t\t}\n\n\t\t\tconst translateStartChange = this.getShapeUtil(shape).onTranslateStart?.({\n\t\t\t\t...shape,\n\t\t\t\t...change,\n\t\t\t})\n\n\t\t\tif (translateStartChange) {\n\t\t\t\tchanges.push({ ...change, ...translateStartChange })\n\t\t\t} else {\n\t\t\t\tchanges.push(change)\n\t\t\t}\n\t\t}\n\n\t\tif (changes.length) {\n\t\t\tthis.updateShapes(changes)\n\t\t}\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Align shape positions.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.alignShapes([box1, box2], 'left')\n\t * editor.alignShapes(editor.getSelectedShapeIds(), 'left')\n\t * ```\n\t *\n\t * @param shapes - The shapes (or shape ids) to align.\n\t * @param operation - The align operation to apply.\n\t *\n\t * @public\n\t */\n\n\talignShapes(\n\t\tshapes: TLShapeId[] | TLShape[],\n\t\toperation: 'left' | 'center-horizontal' | 'right' | 'top' | 'center-vertical' | 'bottom'\n\t): this {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\n\t\tif (this.getIsReadonly()) return this\n\t\tif (ids.length < 2) return this\n\n\t\tconst shapesToAlign = compact(ids.map((id) => this.getShape(id))) // always fresh shapes\n\t\tconst shapePageBounds = Object.fromEntries(\n\t\t\tshapesToAlign.map((shape) => [shape.id, this.getShapePageBounds(shape)])\n\t\t)\n\t\tconst commonBounds = Box.Common(compact(Object.values(shapePageBounds)))\n\n\t\tconst changes: TLShapePartial[] = []\n\n\t\tshapesToAlign.forEach((shape) => {\n\t\t\tconst pageBounds = shapePageBounds[shape.id]\n\t\t\tif (!pageBounds) return\n\n\t\t\tconst delta = { x: 0, y: 0 }\n\n\t\t\tswitch (operation) {\n\t\t\t\tcase 'top': {\n\t\t\t\t\tdelta.y = commonBounds.minY - pageBounds.minY\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase 'center-vertical': {\n\t\t\t\t\tdelta.y = commonBounds.midY - pageBounds.minY - pageBounds.height / 2\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase 'bottom': {\n\t\t\t\t\tdelta.y = commonBounds.maxY - pageBounds.minY - pageBounds.height\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase 'left': {\n\t\t\t\t\tdelta.x = commonBounds.minX - pageBounds.minX\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase 'center-horizontal': {\n\t\t\t\t\tdelta.x = commonBounds.midX - pageBounds.minX - pageBounds.width / 2\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase 'right': {\n\t\t\t\t\tdelta.x = commonBounds.maxX - pageBounds.minX - pageBounds.width\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst parent = this.getShapeParent(shape)\n\t\t\tconst localDelta = parent\n\t\t\t\t? Vec.Rot(delta, -this.getShapePageTransform(parent)!.decompose().rotation)\n\t\t\t\t: delta\n\n\t\t\tchanges.push(this.getChangesToTranslateShape(shape, Vec.Add(shape, localDelta)))\n\t\t})\n\n\t\tthis.updateShapes(changes)\n\t\treturn this\n\t}\n\n\t/**\n\t * Distribute shape positions.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.distributeShapes([box1, box2], 'horizontal')\n\t * editor.distributeShapes(editor.getSelectedShapeIds(), 'horizontal')\n\t * ```\n\t *\n\t * @param shapes - The shapes (or shape ids) to distribute.\n\t * @param operation - Whether to distribute shapes horizontally or vertically.\n\t *\n\t * @public\n\t */\n\tdistributeShapes(shapes: TLShapeId[] | TLShape[], operation: 'horizontal' | 'vertical'): this {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\n\t\tif (this.getIsReadonly()) return this\n\t\tif (ids.length < 3) return this\n\n\t\tconst len = ids.length\n\t\tconst shapesToDistribute = compact(ids.map((id) => this.getShape(id))) // always fresh shapes\n\t\tconst pageBounds = Object.fromEntries(\n\t\t\tshapesToDistribute.map((shape) => [shape.id, this.getShapePageBounds(shape)!])\n\t\t)\n\n\t\tlet val: 'x' | 'y'\n\t\tlet min: 'minX' | 'minY'\n\t\tlet max: 'maxX' | 'maxY'\n\t\tlet mid: 'midX' | 'midY'\n\t\tlet dim: 'width' | 'height'\n\n\t\tif (operation === 'horizontal') {\n\t\t\tval = 'x'\n\t\t\tmin = 'minX'\n\t\t\tmax = 'maxX'\n\t\t\tmid = 'midX'\n\t\t\tdim = 'width'\n\t\t} else {\n\t\t\tval = 'y'\n\t\t\tmin = 'minY'\n\t\t\tmax = 'maxY'\n\t\t\tmid = 'midY'\n\t\t\tdim = 'height'\n\t\t}\n\t\tconst changes: TLShapePartial[] = []\n\n\t\t// Clustered\n\t\tconst first = shapesToDistribute.sort(\n\t\t\t(a, b) => pageBounds[a.id][min] - pageBounds[b.id][min]\n\t\t)[0]\n\t\tconst last = shapesToDistribute.sort((a, b) => pageBounds[b.id][max] - pageBounds[a.id][max])[0]\n\n\t\tconst midFirst = pageBounds[first.id][mid]\n\t\tconst step = (pageBounds[last.id][mid] - midFirst) / (len - 1)\n\t\tconst v = midFirst + step\n\n\t\tshapesToDistribute\n\t\t\t.filter((shape) => shape !== first && shape !== last)\n\t\t\t.sort((a, b) => pageBounds[a.id][mid] - pageBounds[b.id][mid])\n\t\t\t.forEach((shape, i) => {\n\t\t\t\tconst delta = { x: 0, y: 0 }\n\t\t\t\tdelta[val] = v + step * i - pageBounds[shape.id][dim] / 2 - pageBounds[shape.id][val]\n\n\t\t\t\tconst parent = this.getShapeParent(shape)\n\t\t\t\tconst localDelta = parent\n\t\t\t\t\t? Vec.Rot(delta, -this.getShapePageTransform(parent)!.rotation())\n\t\t\t\t\t: delta\n\n\t\t\t\tchanges.push(this.getChangesToTranslateShape(shape, Vec.Add(shape, localDelta)))\n\t\t\t})\n\n\t\tthis.updateShapes(changes)\n\t\treturn this\n\t}\n\n\t/**\n\t * Stretch shape sizes and positions to fill their common bounding box.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.stretchShapes([box1, box2], 'horizontal')\n\t * editor.stretchShapes(editor.getSelectedShapeIds(), 'horizontal')\n\t * ```\n\t *\n\t * @param shapes - The shapes (or shape ids) to stretch.\n\t * @param operation - Whether to stretch shapes horizontally or vertically.\n\t *\n\t * @public\n\t */\n\tstretchShapes(shapes: TLShapeId[] | TLShape[], operation: 'horizontal' | 'vertical'): this {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\n\t\tif (this.getIsReadonly()) return this\n\t\tif (ids.length < 2) return this\n\n\t\tconst shapesToStretch = compact(ids.map((id) => this.getShape(id))) // always fresh shapes\n\t\tconst shapeBounds = Object.fromEntries(ids.map((id) => [id, this.getShapeGeometry(id).bounds]))\n\t\tconst shapePageBounds = Object.fromEntries(ids.map((id) => [id, this.getShapePageBounds(id)!]))\n\t\tconst commonBounds = Box.Common(compact(Object.values(shapePageBounds)))\n\n\t\tswitch (operation) {\n\t\t\tcase 'vertical': {\n\t\t\t\tthis.run(() => {\n\t\t\t\t\tfor (const shape of shapesToStretch) {\n\t\t\t\t\t\tconst pageRotation = this.getShapePageTransform(shape)!.rotation()\n\t\t\t\t\t\tif (pageRotation % PI2) continue\n\t\t\t\t\t\tconst bounds = shapeBounds[shape.id]\n\t\t\t\t\t\tconst pageBounds = shapePageBounds[shape.id]\n\t\t\t\t\t\tconst localOffset = new Vec(0, commonBounds.minY - pageBounds.minY)\n\t\t\t\t\t\tconst parentTransform = this.getShapeParentTransform(shape)\n\t\t\t\t\t\tif (parentTransform) localOffset.rot(-parentTransform.rotation())\n\n\t\t\t\t\t\tconst { x, y } = Vec.Add(localOffset, shape)\n\t\t\t\t\t\tthis.updateShapes([{ id: shape.id, type: shape.type, x, y }])\n\t\t\t\t\t\tconst scale = new Vec(1, commonBounds.height / pageBounds.height)\n\t\t\t\t\t\tthis.resizeShape(shape.id, scale, {\n\t\t\t\t\t\t\tinitialBounds: bounds,\n\t\t\t\t\t\t\tscaleOrigin: new Vec(pageBounds.center.x, commonBounds.minY),\n\t\t\t\t\t\t\tisAspectRatioLocked: this.getShapeUtil(shape).isAspectRatioLocked(shape),\n\t\t\t\t\t\t\tscaleAxisRotation: 0,\n\t\t\t\t\t\t})\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'horizontal': {\n\t\t\t\tthis.run(() => {\n\t\t\t\t\tfor (const shape of shapesToStretch) {\n\t\t\t\t\t\tconst bounds = shapeBounds[shape.id]\n\t\t\t\t\t\tconst pageBounds = shapePageBounds[shape.id]\n\t\t\t\t\t\tconst pageRotation = this.getShapePageTransform(shape)!.rotation()\n\t\t\t\t\t\tif (pageRotation % PI2) continue\n\t\t\t\t\t\tconst localOffset = new Vec(commonBounds.minX - pageBounds.minX, 0)\n\t\t\t\t\t\tconst parentTransform = this.getShapeParentTransform(shape)\n\t\t\t\t\t\tif (parentTransform) localOffset.rot(-parentTransform.rotation())\n\n\t\t\t\t\t\tconst { x, y } = Vec.Add(localOffset, shape)\n\t\t\t\t\t\tthis.updateShapes([{ id: shape.id, type: shape.type, x, y }])\n\t\t\t\t\t\tconst scale = new Vec(commonBounds.width / pageBounds.width, 1)\n\t\t\t\t\t\tthis.resizeShape(shape.id, scale, {\n\t\t\t\t\t\t\tinitialBounds: bounds,\n\t\t\t\t\t\t\tscaleOrigin: new Vec(commonBounds.minX, pageBounds.center.y),\n\t\t\t\t\t\t\tisAspectRatioLocked: this.getShapeUtil(shape).isAspectRatioLocked(shape),\n\t\t\t\t\t\t\tscaleAxisRotation: 0,\n\t\t\t\t\t\t})\n\t\t\t\t\t}\n\t\t\t\t})\n\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Resize a shape.\n\t *\n\t * @param shape - The shape (or the shape id of the shape) to resize.\n\t * @param scale - The scale factor to apply to the shape.\n\t * @param opts - Additional options.\n\t *\n\t * @public\n\t */\n\tresizeShape(shape: TLShapeId | TLShape, scale: VecLike, opts: TLResizeShapeOptions = {}): this {\n\t\tconst id = typeof shape === 'string' ? shape : shape.id\n\t\tif (this.getIsReadonly()) return this\n\n\t\tif (!Number.isFinite(scale.x)) scale = new Vec(1, scale.y)\n\t\tif (!Number.isFinite(scale.y)) scale = new Vec(scale.x, 1)\n\n\t\tconst initialShape = opts.initialShape ?? this.getShape(id)\n\t\tif (!initialShape) return this\n\n\t\tconst scaleOrigin = opts.scaleOrigin ?? this.getShapePageBounds(id)?.center\n\t\tif (!scaleOrigin) return this\n\n\t\tconst pageTransform = opts.initialPageTransform\n\t\t\t? Mat.Cast(opts.initialPageTransform)\n\t\t\t: this.getShapePageTransform(id)\n\t\tif (!pageTransform) return this\n\n\t\tconst pageRotation = pageTransform.rotation()\n\n\t\tif (pageRotation == null) return this\n\n\t\tconst scaleAxisRotation = opts.scaleAxisRotation ?? pageRotation\n\n\t\tconst initialBounds = opts.initialBounds ?? this.getShapeGeometry(id).bounds\n\n\t\tif (!initialBounds) return this\n\n\t\tconst isAspectRatioLocked =\n\t\t\topts.isAspectRatioLocked ?? this.getShapeUtil(initialShape).isAspectRatioLocked(initialShape)\n\n\t\tif (!areAnglesCompatible(pageRotation, scaleAxisRotation)) {\n\t\t\t// shape is awkwardly rotated, keep the aspect ratio locked and adopt the scale factor\n\t\t\t// from whichever axis is being scaled the least, to avoid the shape getting bigger\n\t\t\t// than the bounds of the selection\n\t\t\t// const minScale = Math.min(Math.abs(scale.x), Math.abs(scale.y))\n\t\t\treturn this._resizeUnalignedShape(id, scale, {\n\t\t\t\t...opts,\n\t\t\t\tinitialBounds,\n\t\t\t\tscaleOrigin,\n\t\t\t\tscaleAxisRotation,\n\t\t\t\tinitialPageTransform: pageTransform,\n\t\t\t\tisAspectRatioLocked,\n\t\t\t\tinitialShape,\n\t\t\t})\n\t\t}\n\n\t\tconst util = this.getShapeUtil(initialShape)\n\n\t\tif (isAspectRatioLocked) {\n\t\t\tif (Math.abs(scale.x) > Math.abs(scale.y)) {\n\t\t\t\tscale = new Vec(scale.x, Math.sign(scale.y) * Math.abs(scale.x))\n\t\t\t} else {\n\t\t\t\tscale = new Vec(Math.sign(scale.x) * Math.abs(scale.y), scale.y)\n\t\t\t}\n\t\t}\n\n\t\tif (util.onResize && util.canResize(initialShape)) {\n\t\t\t// get the model changes from the shape util\n\t\t\tconst newPagePoint = this._scalePagePoint(\n\t\t\t\tMat.applyToPoint(pageTransform, new Vec(0, 0)),\n\t\t\t\tscaleOrigin,\n\t\t\t\tscale,\n\t\t\t\tscaleAxisRotation\n\t\t\t)\n\n\t\t\tconst newLocalPoint = this.getPointInParentSpace(initialShape.id, newPagePoint)\n\n\t\t\t// resize the shape's local bounding box\n\t\t\tconst myScale = new Vec(scale.x, scale.y)\n\t\t\t// the shape is aligned with the rest of the shapes in the selection, but may be\n\t\t\t// 90deg offset from the main rotation of the selection, in which case\n\t\t\t// we need to flip the width and height scale factors\n\t\t\tconst areWidthAndHeightAlignedWithCorrectAxis = approximately(\n\t\t\t\t(pageRotation - scaleAxisRotation) % Math.PI,\n\t\t\t\t0\n\t\t\t)\n\t\t\tmyScale.x = areWidthAndHeightAlignedWithCorrectAxis ? scale.x : scale.y\n\t\t\tmyScale.y = areWidthAndHeightAlignedWithCorrectAxis ? scale.y : scale.x\n\n\t\t\t// adjust initial model for situations where the parent has moved during the resize\n\t\t\t// e.g. groups\n\t\t\tconst initialPagePoint = Mat.applyToPoint(pageTransform, new Vec())\n\n\t\t\t// need to adjust the shape's x and y points in case the parent has moved since start of resizing\n\t\t\tconst { x, y } = this.getPointInParentSpace(initialShape.id, initialPagePoint)\n\n\t\t\tlet workingShape = initialShape\n\t\t\tif (!opts.skipStartAndEndCallbacks) {\n\t\t\t\tworkingShape = applyPartialToRecordWithProps(\n\t\t\t\t\tinitialShape,\n\t\t\t\t\tutil.onResizeStart?.(initialShape) ?? undefined\n\t\t\t\t)\n\t\t\t}\n\n\t\t\tworkingShape = applyPartialToRecordWithProps(workingShape, {\n\t\t\t\tid,\n\t\t\t\ttype: initialShape.type as any,\n\t\t\t\tx: newLocalPoint.x,\n\t\t\t\ty: newLocalPoint.y,\n\t\t\t\t...util.onResize(\n\t\t\t\t\t{ ...initialShape, x, y },\n\t\t\t\t\t{\n\t\t\t\t\t\tnewPoint: newLocalPoint,\n\t\t\t\t\t\thandle: opts.dragHandle ?? 'bottom_right',\n\t\t\t\t\t\t// don't set isSingle to true for children\n\t\t\t\t\t\tmode: opts.mode ?? 'scale_shape',\n\t\t\t\t\t\tscaleX: myScale.x,\n\t\t\t\t\t\tscaleY: myScale.y,\n\t\t\t\t\t\tinitialBounds,\n\t\t\t\t\t\tinitialShape,\n\t\t\t\t\t}\n\t\t\t\t),\n\t\t\t})\n\n\t\t\tif (!opts.skipStartAndEndCallbacks) {\n\t\t\t\tworkingShape = applyPartialToRecordWithProps(\n\t\t\t\t\tworkingShape,\n\t\t\t\t\tutil.onResizeEnd?.(initialShape, workingShape) ?? undefined\n\t\t\t\t)\n\t\t\t}\n\n\t\t\tthis.updateShapes([workingShape])\n\t\t} else {\n\t\t\tconst initialPageCenter = Mat.applyToPoint(pageTransform, initialBounds.center)\n\t\t\t// get the model changes from the shape util\n\t\t\tconst newPageCenter = this._scalePagePoint(\n\t\t\t\tinitialPageCenter,\n\t\t\t\tscaleOrigin,\n\t\t\t\tscale,\n\t\t\t\tscaleAxisRotation\n\t\t\t)\n\n\t\t\tconst initialPageCenterInParentSpace = this.getPointInParentSpace(\n\t\t\t\tinitialShape.id,\n\t\t\t\tinitialPageCenter\n\t\t\t)\n\t\t\tconst newPageCenterInParentSpace = this.getPointInParentSpace(initialShape.id, newPageCenter)\n\n\t\t\tconst delta = Vec.Sub(newPageCenterInParentSpace, initialPageCenterInParentSpace)\n\t\t\t// apply the changes to the model\n\t\t\tthis.updateShapes([\n\t\t\t\t{\n\t\t\t\t\tid,\n\t\t\t\t\ttype: initialShape.type as any,\n\t\t\t\t\tx: initialShape.x + delta.x,\n\t\t\t\t\ty: initialShape.y + delta.y,\n\t\t\t\t},\n\t\t\t])\n\t\t}\n\n\t\treturn this\n\t}\n\n\t/** @internal */\n\tprivate _scalePagePoint(\n\t\tpoint: VecLike,\n\t\tscaleOrigin: VecLike,\n\t\tscale: VecLike,\n\t\tscaleAxisRotation: number\n\t) {\n\t\tconst relativePoint = Vec.RotWith(point, scaleOrigin, -scaleAxisRotation).sub(scaleOrigin)\n\n\t\t// calculate the new point position relative to the scale origin\n\t\tconst newRelativePagePoint = Vec.MulV(relativePoint, scale)\n\n\t\t// and rotate it back to page coords to get the new page point of the resized shape\n\t\tconst destination = Vec.Add(newRelativePagePoint, scaleOrigin).rotWith(\n\t\t\tscaleOrigin,\n\t\t\tscaleAxisRotation\n\t\t)\n\n\t\treturn destination\n\t}\n\n\t/** @internal */\n\tprivate _resizeUnalignedShape(\n\t\tid: TLShapeId,\n\t\tscale: VecLike,\n\t\toptions: {\n\t\t\tinitialBounds: Box\n\t\t\tscaleOrigin: VecLike\n\t\t\tscaleAxisRotation: number\n\t\t\tinitialShape: TLShape\n\t\t\tisAspectRatioLocked: boolean\n\t\t\tinitialPageTransform: MatLike\n\t\t}\n\t) {\n\t\tconst { type } = options.initialShape\n\t\t// If a shape is not aligned with the scale axis we need to treat it differently to avoid skewing.\n\t\t// Instead of skewing we normalize the scale aspect ratio (i.e. keep the same scale magnitude in both axes)\n\t\t// and then after applying the scale to the shape we also rotate it if required and translate it so that it's center\n\t\t// point ends up in the right place.\n\n\t\tconst shapeScale = new Vec(scale.x, scale.y)\n\n\t\t// // make sure we are constraining aspect ratio, and using the smallest scale axis to avoid shapes getting bigger\n\t\t// // than the selection bounding box\n\t\tif (Math.abs(scale.x) > Math.abs(scale.y)) {\n\t\t\tshapeScale.x = Math.sign(scale.x) * Math.abs(scale.y)\n\t\t} else {\n\t\t\tshapeScale.y = Math.sign(scale.y) * Math.abs(scale.x)\n\t\t}\n\n\t\t// first we can scale the shape about its center point\n\t\tthis.resizeShape(id, shapeScale, {\n\t\t\tinitialShape: options.initialShape,\n\t\t\tinitialBounds: options.initialBounds,\n\t\t\tisAspectRatioLocked: options.isAspectRatioLocked,\n\t\t})\n\n\t\t// then if the shape is flipped in one axis only, we need to apply an extra rotation\n\t\t// to make sure the shape is mirrored correctly\n\t\tif (Math.sign(scale.x) * Math.sign(scale.y) < 0) {\n\t\t\tlet { rotation } = Mat.Decompose(options.initialPageTransform)\n\t\t\trotation -= 2 * rotation\n\t\t\tthis.updateShapes([{ id, type, rotation }])\n\t\t}\n\n\t\t// Next we need to translate the shape so that it's center point ends up in the right place.\n\t\t// To do that we first need to calculate the center point of the shape in the current page space before the scale was applied.\n\t\tconst preScaleShapePageCenter = Mat.applyToPoint(\n\t\t\toptions.initialPageTransform,\n\t\t\toptions.initialBounds.center\n\t\t)\n\n\t\t// And now we scale the center point by the original scale factor\n\t\tconst postScaleShapePageCenter = this._scalePagePoint(\n\t\t\tpreScaleShapePageCenter,\n\t\t\toptions.scaleOrigin,\n\t\t\tscale,\n\t\t\toptions.scaleAxisRotation\n\t\t)\n\n\t\t// now calculate how far away the shape is from where it needs to be\n\t\tconst pageBounds = this.getShapePageBounds(id)!\n\t\tconst pageTransform = this.getShapePageTransform(id)!\n\t\tconst currentPageCenter = pageBounds.center\n\t\tconst shapePageTransformOrigin = pageTransform.point()\n\t\tif (!currentPageCenter || !shapePageTransformOrigin) return this\n\t\tconst pageDelta = Vec.Sub(postScaleShapePageCenter, currentPageCenter)\n\n\t\t// and finally figure out what the shape's new position should be\n\t\tconst postScaleShapePagePoint = Vec.Add(shapePageTransformOrigin, pageDelta)\n\t\tconst { x, y } = this.getPointInParentSpace(id, postScaleShapePagePoint)\n\n\t\tthis.updateShapes([{ id, type, x, y }])\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Get the initial meta value for a shape.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getInitialMetaForShape = (shape) => {\n\t * if (shape.type === 'note') {\n\t * return { createdBy: myCurrentUser.id }\n\t * }\n\t * }\n\t * ```\n\t *\n\t * @param shape - The shape to get the initial meta for.\n\t *\n\t * @public\n\t */\n\tgetInitialMetaForShape(_shape: TLShape): JsonObject {\n\t\treturn {}\n\t}\n\n\t/**\n\t * Create a single shape.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.createShape(myShape)\n\t * editor.createShape({ id: 'box1', type: 'text', props: { text: \"ok\" } })\n\t * ```\n\t *\n\t * @param shape - The shape (or shape partial) to create.\n\t *\n\t * @public\n\t */\n\tcreateShape(shape: OptionalKeys, 'id'>): this {\n\t\tthis.createShapes([shape])\n\t\treturn this\n\t}\n\n\t/**\n\t * Create shapes.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.createShapes([myShape])\n\t * editor.createShapes([{ id: 'box1', type: 'text', props: { text: \"ok\" } }])\n\t * ```\n\t *\n\t * @param shapes - The shapes (or shape partials) to create.\n\t *\n\t * @public\n\t */\n\tcreateShapes(shapes: OptionalKeys, 'id'>[]): this {\n\t\tif (!Array.isArray(shapes)) {\n\t\t\tthrow Error('Editor.createShapes: must provide an array of shapes or shape partials')\n\t\t}\n\t\tif (this.getIsReadonly()) return this\n\t\tif (shapes.length <= 0) return this\n\n\t\tconst currentPageShapeIds = this.getCurrentPageShapeIds()\n\n\t\tconst maxShapesReached =\n\t\t\tshapes.length + currentPageShapeIds.size > this.options.maxShapesPerPage\n\n\t\tif (maxShapesReached) {\n\t\t\t// can't create more shapes than fit on the page\n\t\t\talertMaxShapes(this)\n\t\t\treturn this\n\t\t}\n\n\t\tconst focusedGroupId = this.getFocusedGroupId()\n\n\t\tthis.run(() => {\n\t\t\t// 1. Parents\n\n\t\t\t// Make sure that each partial will become the child of either the\n\t\t\t// page or another shape that exists (or that will exist) in this page.\n\n\t\t\t// find last parent id\n\t\t\tconst currentPageShapesSorted = this.getCurrentPageShapesSorted()\n\n\t\t\tconst partials = shapes.map((partial) => {\n\t\t\t\tif (!partial.id) {\n\t\t\t\t\tpartial = { id: createShapeId(), ...partial }\n\t\t\t\t}\n\n\t\t\t\t// If the partial does not provide the parentId OR if the provided\n\t\t\t\t// parentId is NOT in the store AND NOT among the other shapes being\n\t\t\t\t// created, then we need to find a parent for the shape. This can be\n\t\t\t\t// another shape that exists under that point and which can receive\n\t\t\t\t// children of the creating shape's type, or else the page itself.\n\t\t\t\tif (\n\t\t\t\t\t!partial.parentId ||\n\t\t\t\t\t!(this.store.has(partial.parentId) || shapes.some((p) => p.id === partial.parentId))\n\t\t\t\t) {\n\t\t\t\t\tlet parentId: TLParentId = this.getFocusedGroupId()\n\n\t\t\t\t\tfor (let i = currentPageShapesSorted.length - 1; i >= 0; i--) {\n\t\t\t\t\t\tconst parent = currentPageShapesSorted[i]\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t!this.isShapeHidden(parent) &&\n\t\t\t\t\t\t\tthis.getShapeUtil(parent).canReceiveNewChildrenOfType(parent, partial.type) &&\n\t\t\t\t\t\t\tthis.isPointInShape(\n\t\t\t\t\t\t\t\tparent,\n\t\t\t\t\t\t\t\t// If no parent is provided, then we can treat the\n\t\t\t\t\t\t\t\t// shape's provided x/y as being in the page's space.\n\t\t\t\t\t\t\t\t{ x: partial.x ?? 0, y: partial.y ?? 0 },\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tmargin: 0,\n\t\t\t\t\t\t\t\t\thitInside: true,\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\tparentId = parent.id\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tconst prevParentId = partial.parentId\n\n\t\t\t\t\t// a shape cannot be it's own parent. This was a rare issue with frames/groups in the syncFuzz tests.\n\t\t\t\t\tif (parentId === partial.id) {\n\t\t\t\t\t\tparentId = focusedGroupId\n\t\t\t\t\t}\n\n\t\t\t\t\t// If the parentid has changed...\n\t\t\t\t\tif (parentId !== prevParentId) {\n\t\t\t\t\t\tpartial = { ...partial }\n\n\t\t\t\t\t\tpartial.parentId = parentId\n\n\t\t\t\t\t\t// If the parent is a shape (rather than a page) then insert the\n\t\t\t\t\t\t// shapes into the shape's children. Adjust the point and page rotation to be\n\t\t\t\t\t\t// preserved relative to the parent.\n\t\t\t\t\t\tif (isShapeId(parentId)) {\n\t\t\t\t\t\t\tconst point = this.getPointInShapeSpace(this.getShape(parentId)!, {\n\t\t\t\t\t\t\t\tx: partial.x ?? 0,\n\t\t\t\t\t\t\t\ty: partial.y ?? 0,\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\tpartial.x = point.x\n\t\t\t\t\t\t\tpartial.y = point.y\n\t\t\t\t\t\t\tpartial.rotation =\n\t\t\t\t\t\t\t\t-this.getShapePageTransform(parentId)!.rotation() + (partial.rotation ?? 0)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn partial\n\t\t\t})\n\n\t\t\t// 2. Indices\n\n\t\t\t// Get the highest index among the parents of each of the\n\t\t\t// the shapes being created; we'll increment from there.\n\n\t\t\tconst parentIndices = new Map()\n\n\t\t\tconst shapeRecordsToCreate: TLShape[] = []\n\n\t\t\tconst { opacityForNextShape } = this.getInstanceState()\n\n\t\t\tfor (const partial of partials) {\n\t\t\t\tconst util = this.getShapeUtil(partial as TLShapePartial)\n\n\t\t\t\t// If an index is not explicitly provided, then add the\n\t\t\t\t// shapes to the top of their parents' children; using the\n\t\t\t\t// value in parentsMappedToIndex, get the index above, use it,\n\t\t\t\t// and set it back to parentsMappedToIndex for next time.\n\t\t\t\tlet index = partial.index\n\n\t\t\t\tif (!index) {\n\t\t\t\t\t// Hello bug-seeker: have you just created a frame and then a shape\n\t\t\t\t\t// and found that the shape is automatically the child of the frame?\n\t\t\t\t\t// this is the reason why! It would be harder to have each shape specify\n\t\t\t\t\t// the frame as the parent when creating a shape inside of a frame, so\n\t\t\t\t\t// we do it here.\n\t\t\t\t\tconst parentId = partial.parentId ?? focusedGroupId\n\n\t\t\t\t\tif (!parentIndices.has(parentId)) {\n\t\t\t\t\t\tparentIndices.set(parentId, this.getHighestIndexForParent(parentId))\n\t\t\t\t\t}\n\t\t\t\t\tindex = parentIndices.get(parentId)!\n\t\t\t\t\tparentIndices.set(parentId, getIndexAbove(index))\n\t\t\t\t}\n\n\t\t\t\t// The initial props starts as the shape utility's default props\n\t\t\t\tconst initialProps = util.getDefaultProps()\n\n\t\t\t\t// We then look up each key in the tab state's styles; and if it's there,\n\t\t\t\t// we use the value from the tab state's styles instead of the default.\n\t\t\t\tfor (const [style, propKey] of this.styleProps[partial.type]) {\n\t\t\t\t\t;(initialProps as any)[propKey] = this.getStyleForNextShape(style)\n\t\t\t\t}\n\n\t\t\t\t// When we create the shape, take in the partial (the props coming into the\n\t\t\t\t// function) and merge it with the default props.\n\t\t\t\tlet shapeRecordToCreate = (\n\t\t\t\t\tthis.store.schema.types.shape as RecordType<\n\t\t\t\t\t\tTLShape,\n\t\t\t\t\t\t'type' | 'props' | 'index' | 'parentId'\n\t\t\t\t\t>\n\t\t\t\t).create({\n\t\t\t\t\t...partial,\n\t\t\t\t\tindex,\n\t\t\t\t\topacity: partial.opacity ?? opacityForNextShape,\n\t\t\t\t\tparentId: partial.parentId ?? focusedGroupId,\n\t\t\t\t\tprops: 'props' in partial ? { ...initialProps, ...partial.props } : initialProps,\n\t\t\t\t})\n\n\t\t\t\tif (shapeRecordToCreate.index === undefined) {\n\t\t\t\t\tthrow Error('no index!')\n\t\t\t\t}\n\n\t\t\t\tconst next = this.getShapeUtil(shapeRecordToCreate).onBeforeCreate?.(shapeRecordToCreate)\n\n\t\t\t\tif (next) {\n\t\t\t\t\tshapeRecordToCreate = next\n\t\t\t\t}\n\n\t\t\t\tshapeRecordsToCreate.push(shapeRecordToCreate)\n\t\t\t}\n\n\t\t\t// Add meta properties, if any, to the shapes\n\t\t\tshapeRecordsToCreate.forEach((shape) => {\n\t\t\t\tshape.meta = {\n\t\t\t\t\t...this.getInitialMetaForShape(shape),\n\t\t\t\t\t...shape.meta,\n\t\t\t\t}\n\t\t\t})\n\n\t\t\tthis.store.put(shapeRecordsToCreate)\n\t\t})\n\n\t\treturn this\n\t}\n\n\tprivate animatingShapes = new Map()\n\n\t/**\n\t * Animate a shape.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.animateShape({ id: 'box1', type: 'box', x: 100, y: 100 })\n\t * editor.animateShape({ id: 'box1', type: 'box', x: 100, y: 100 }, { animation: { duration: 100, ease: t => t*t } })\n\t * ```\n\t *\n\t * @param partial - The shape partial to update.\n\t * @param opts - The animation's options.\n\t *\n\t * @public\n\t */\n\tanimateShape(\n\t\tpartial: TLShapePartial | null | undefined,\n\t\topts = { animation: DEFAULT_ANIMATION_OPTIONS } as TLCameraMoveOptions\n\t): this {\n\t\treturn this.animateShapes([partial], opts)\n\t}\n\n\t/**\n\t * Animate shapes.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.animateShapes([{ id: 'box1', type: 'box', x: 100, y: 100 }])\n\t * editor.animateShapes([{ id: 'box1', type: 'box', x: 100, y: 100 }], { animation: { duration: 100, ease: t => t*t } })\n\t * ```\n\t *\n\t * @param partials - The shape partials to update.\n\t * @param opts - The animation's options.\n\t *\n\t * @public\n\t */\n\tanimateShapes(\n\t\tpartials: (TLShapePartial | null | undefined)[],\n\t\topts = { animation: DEFAULT_ANIMATION_OPTIONS } as TLCameraMoveOptions\n\t): this {\n\t\tif (!opts.animation) return this\n\t\tconst { duration = 500, easing = EASINGS.linear } = opts.animation\n\n\t\tconst animationId = uniqueId()\n\n\t\tlet remaining = duration\n\t\tlet t: number\n\n\t\tinterface ShapeAnimation {\n\t\t\tstart: TLShape\n\t\t\tend: TLShape\n\t\t}\n\n\t\tconst animations: ShapeAnimation[] = []\n\n\t\tlet partial: TLShapePartial | null | undefined, result: ShapeAnimation\n\t\tfor (let i = 0, n = partials.length; i < n; i++) {\n\t\t\tpartial = partials[i]\n\t\t\tif (!partial) continue\n\n\t\t\tconst shape = this.getShape(partial.id)!\n\t\t\tif (!shape) continue\n\n\t\t\tresult = {\n\t\t\t\tstart: structuredClone(shape),\n\t\t\t\tend: applyPartialToRecordWithProps(structuredClone(shape), partial),\n\t\t\t}\n\n\t\t\tanimations.push(result)\n\t\t\tthis.animatingShapes.set(shape.id, animationId)\n\t\t}\n\n\t\tconst handleTick = (elapsed: number) => {\n\t\t\tremaining -= elapsed\n\n\t\t\tif (remaining < 0) {\n\t\t\t\tconst { animatingShapes } = this\n\t\t\t\tconst partialsToUpdate = partials.filter(\n\t\t\t\t\t(p) => p && animatingShapes.get(p.id) === animationId\n\t\t\t\t)\n\t\t\t\tif (partialsToUpdate.length) {\n\t\t\t\t\t// the regular update shapes also removes the shape from\n\t\t\t\t\t// the animating shapes set\n\t\t\t\t\tthis.updateShapes(partialsToUpdate)\n\t\t\t\t}\n\n\t\t\t\tthis.off('tick', handleTick)\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tt = easing(1 - remaining / duration)\n\n\t\t\tconst { animatingShapes } = this\n\n\t\t\tconst updates: TLShapePartial[] = []\n\n\t\t\tlet animationIdForShape: string | undefined\n\t\t\tfor (let i = 0, n = animations.length; i < n; i++) {\n\t\t\t\tconst { start, end } = animations[i]\n\t\t\t\t// Is the animation for this shape still active?\n\t\t\t\tanimationIdForShape = animatingShapes.get(start.id)\n\t\t\t\tif (animationIdForShape !== animationId) continue\n\n\t\t\t\tupdates.push({\n\t\t\t\t\t...end,\n\t\t\t\t\tx: start.x + (end.x - start.x) * t,\n\t\t\t\t\ty: start.y + (end.y - start.y) * t,\n\t\t\t\t\topacity: start.opacity + (end.opacity - start.opacity) * t,\n\t\t\t\t\trotation: start.rotation + (end.rotation - start.rotation) * t,\n\t\t\t\t\tprops: this.getShapeUtil(end).getInterpolatedProps?.(start, end, t) ?? end.props,\n\t\t\t\t})\n\t\t\t}\n\n\t\t\t// The _updateShapes method does NOT remove the\n\t\t\t// shapes from the animated shapes set\n\t\t\tthis._updateShapes(updates)\n\t\t}\n\n\t\tthis.on('tick', handleTick)\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Create a group containing the provided shapes.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.groupShapes([myShape, myOtherShape])\n\t * editor.groupShapes([myShape, myOtherShape], { groupId: myGroupId, select: false })\n\t * ```\n\t *\n\t * @param shapes - The shapes (or shape ids) to group. Defaults to the selected shapes.\n\t * @param opts - An options object.\n\t *\n\t * @public\n\t */\n\tgroupShapes(shapes: TLShape[], opts?: Partial<{ groupId: TLShapeId; select: boolean }>): this\n\tgroupShapes(ids: TLShapeId[], opts?: Partial<{ groupId: TLShapeId; select: boolean }>): this\n\tgroupShapes(\n\t\tshapes: TLShapeId[] | TLShape[],\n\t\topts = {} as Partial<{ groupId: TLShapeId; select: boolean }>\n\t): this {\n\t\tconst { groupId = createShapeId(), select = true } = opts\n\n\t\tif (!Array.isArray(shapes)) {\n\t\t\tthrow Error('Editor.groupShapes: must provide an array of shapes or shape ids')\n\t\t}\n\t\tif (this.getIsReadonly()) return this\n\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes.map((s) => (s as TLShape).id) as TLShapeId[])\n\n\t\tif (ids.length <= 1) return this\n\n\t\tconst shapesToGroup = compact(\n\t\t\t(this._shouldIgnoreShapeLock ? ids : this._getUnlockedShapeIds(ids)).map((id) =>\n\t\t\t\tthis.getShape(id)\n\t\t\t)\n\t\t)\n\t\tconst sortedShapeIds = shapesToGroup.sort(sortByIndex).map((s) => s.id)\n\t\tconst pageBounds = Box.Common(compact(shapesToGroup.map((id) => this.getShapePageBounds(id))))\n\n\t\tconst { x, y } = pageBounds.point\n\n\t\tconst parentId = this.findCommonAncestor(shapesToGroup) ?? this.getCurrentPageId()\n\n\t\t// Only group when the select tool is active\n\t\tif (this.getCurrentToolId() !== 'select') return this\n\n\t\t// If not already in idle, cancel the current interaction (get back to idle)\n\t\tif (!this.isIn('select.idle')) {\n\t\t\tthis.cancel()\n\t\t}\n\n\t\t// Find all the shapes that have the same parentId, and use the highest index.\n\t\tconst shapesWithRootParent = shapesToGroup\n\t\t\t.filter((shape) => shape.parentId === parentId)\n\t\t\t.sort(sortByIndex)\n\n\t\tconst highestIndex = shapesWithRootParent[shapesWithRootParent.length - 1]?.index\n\n\t\tthis.run(() => {\n\t\t\tthis.createShapes([\n\t\t\t\t{\n\t\t\t\t\tid: groupId,\n\t\t\t\t\ttype: 'group',\n\t\t\t\t\tparentId,\n\t\t\t\t\tindex: highestIndex,\n\t\t\t\t\tx,\n\t\t\t\t\ty,\n\t\t\t\t\topacity: 1,\n\t\t\t\t\tprops: {},\n\t\t\t\t},\n\t\t\t])\n\t\t\tthis.reparentShapes(sortedShapeIds, groupId)\n\t\t\tif (select) {\n\t\t\t\t// the select option determines whether the grouped shapes' children are selected\n\t\t\t\tthis.select(groupId)\n\t\t\t}\n\t\t})\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Ungroup some shapes.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.ungroupShapes([myGroup, myOtherGroup])\n\t * editor.ungroupShapes([myGroup], { select: false })\n\t * ```\n\t *\n\t * @param shapes - The group shapes (or shape ids) to ungroup.\n\t * @param opts - An options object.\n\t *\n\t * @public\n\t */\n\tungroupShapes(ids: TLShapeId[], opts?: Partial<{ select: boolean }>): this\n\tungroupShapes(shapes: TLShape[], opts?: Partial<{ select: boolean }>): this\n\tungroupShapes(shapes: TLShapeId[] | TLShape[], opts = {} as Partial<{ select: boolean }>) {\n\t\tif (this.getIsReadonly()) return this\n\n\t\tconst { select = true } = opts\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\n\t\tconst shapesToUngroup = compact(\n\t\t\t(this._shouldIgnoreShapeLock ? ids : this._getUnlockedShapeIds(ids)).map((id) =>\n\t\t\t\tthis.getShape(id)\n\t\t\t)\n\t\t)\n\n\t\tif (shapesToUngroup.length === 0) return this\n\n\t\t// todo: the editor shouldn't know about the select tool, move to group / ungroup actions\n\t\tif (this.getCurrentToolId() !== 'select') return this\n\t\tif (!this.isIn('select.idle')) {\n\t\t\tthis.cancel()\n\t\t}\n\n\t\t// The ids of the selected shapes after ungrouping;\n\t\t// these include all of the grouped shapes children,\n\t\t// plus any shapes that were selected apart from the groups.\n\t\tconst idsToSelect = new Set()\n\n\t\t// Get all groups in the selection\n\t\tconst groups: TLGroupShape[] = []\n\n\t\tshapesToUngroup.forEach((shape) => {\n\t\t\tif (this.isShapeOfType(shape, 'group')) {\n\t\t\t\tgroups.push(shape)\n\t\t\t} else {\n\t\t\t\tidsToSelect.add(shape.id)\n\t\t\t}\n\t\t})\n\n\t\tif (groups.length === 0) return this\n\n\t\tthis.run(() => {\n\t\t\tlet group: TLGroupShape\n\n\t\t\tfor (let i = 0, n = groups.length; i < n; i++) {\n\t\t\t\tgroup = groups[i]\n\t\t\t\tconst childIds = this.getSortedChildIdsForParent(group.id)\n\n\t\t\t\tfor (let j = 0, n = childIds.length; j < n; j++) {\n\t\t\t\t\tidsToSelect.add(childIds[j])\n\t\t\t\t}\n\n\t\t\t\tthis.reparentShapes(childIds, group.parentId, group.index)\n\t\t\t}\n\n\t\t\tthis.deleteShapes(groups.map((group) => group.id))\n\n\t\t\tif (select) {\n\t\t\t\t// the select option determines whether the ungrouped shapes' children are selected\n\t\t\t\tthis.select(...idsToSelect)\n\t\t\t}\n\t\t})\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Update a shape using a partial of the shape.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.updateShape({ id: 'box1', type: 'geo', props: { w: 100, h: 100 } })\n\t * ```\n\t *\n\t * @param partial - The shape partial to update.\n\t *\n\t * @public\n\t */\n\tupdateShape(partial: TLShapePartial | null | undefined) {\n\t\tthis.updateShapes([partial])\n\t\treturn this\n\t}\n\n\t/**\n\t * Update shapes using partials of each shape.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.updateShapes([{ id: 'box1', type: 'geo', props: { w: 100, h: 100 } }])\n\t * ```\n\t *\n\t * @param partials - The shape partials to update.\n\t *\n\t * @public\n\t */\n\tupdateShapes(partials: (TLShapePartial | null | undefined)[]) {\n\t\tconst compactedPartials: TLShapePartial[] = Array(partials.length)\n\n\t\tfor (let i = 0, n = partials.length; i < n; i++) {\n\t\t\tconst partial = partials[i]\n\t\t\tif (!partial) continue\n\t\t\t// Get the current shape referenced by the partial\n\t\t\tconst shape = this.getShape(partial.id)\n\t\t\tif (!shape) continue\n\n\t\t\t// If we're \"forcing\" the update, then we'll update the shape\n\t\t\t// regardless of whether it / its ancestor is locked\n\t\t\tif (!this._shouldIgnoreShapeLock) {\n\t\t\t\tif (shape.isLocked) {\n\t\t\t\t\t// If the shape itself is locked (even if one of its ancestors is\n\t\t\t\t\t// also locked) then only allow an update that unlocks the shape.\n\t\t\t\t\tif (!(Object.hasOwn(partial, 'isLocked') && !partial.isLocked)) {\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\t\t\t\t} else if (this.isShapeOrAncestorLocked(shape)) {\n\t\t\t\t\t// If the shape itself is unlocked, and any of the shape's\n\t\t\t\t\t// ancestors are locked then we'll skip the update\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Remove any animating shapes from the list of partials\n\t\t\tthis.animatingShapes.delete(partial.id)\n\n\t\t\tcompactedPartials.push(partial)\n\t\t}\n\n\t\tthis._updateShapes(compactedPartials)\n\t\treturn this\n\t}\n\n\t/** @internal */\n\t_updateShapes(_partials: (TLShapePartial | null | undefined)[]) {\n\t\tif (this.getIsReadonly()) return\n\n\t\tthis.run(() => {\n\t\t\tconst updates = []\n\n\t\t\tlet shape: TLShape | undefined\n\t\t\tlet updated: TLShape\n\n\t\t\tfor (let i = 0, n = _partials.length; i < n; i++) {\n\t\t\t\tconst partial = _partials[i]\n\t\t\t\t// Skip nullish partials (sometimes created by map fns returning undefined)\n\t\t\t\tif (!partial) continue\n\n\t\t\t\t// Get the current shape referenced by the partial\n\t\t\t\t// If there is no current shape, we'll skip this update\n\t\t\t\tshape = this.getShape(partial.id)\n\t\t\t\tif (!shape) continue\n\n\t\t\t\t// Get the updated version of the shape\n\t\t\t\t// If the update had no effect, we'll skip this update\n\t\t\t\tupdated = applyPartialToRecordWithProps(shape, partial)\n\t\t\t\tif (updated === shape) continue\n\n\t\t\t\t//if any shape has an onBeforeUpdate handler, call it and, if the handler returns a\n\t\t\t\t// new shape, replace the old shape with the new one. This is used for example when\n\t\t\t\t// repositioning a text shape based on its new text content.\n\t\t\t\tupdated = this.getShapeUtil(shape).onBeforeUpdate?.(shape, updated) ?? updated\n\n\t\t\t\tupdates.push(updated)\n\t\t\t}\n\n\t\t\tthis.store.put(updates)\n\t\t})\n\t}\n\n\t/** @internal */\n\tprivate _getUnlockedShapeIds(ids: TLShapeId[]): TLShapeId[] {\n\t\treturn ids.filter((id) => !this.getShape(id)?.isLocked)\n\t}\n\n\t/**\n\t * Delete shapes.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.deleteShapes(['box1', 'box2'])\n\t * ```\n\t *\n\t * @param ids - The ids of the shapes to delete.\n\t *\n\t * @public\n\t */\n\tdeleteShapes(ids: TLShapeId[]): this\n\tdeleteShapes(shapes: TLShape[]): this\n\tdeleteShapes(_ids: TLShapeId[] | TLShape[]): this {\n\t\tif (this.getIsReadonly()) return this\n\n\t\tif (!Array.isArray(_ids)) {\n\t\t\tthrow Error('Editor.deleteShapes: must provide an array of shapes or shapeIds')\n\t\t}\n\n\t\tconst shapeIds =\n\t\t\ttypeof _ids[0] === 'string' ? (_ids as TLShapeId[]) : (_ids as TLShape[]).map((s) => s.id)\n\n\t\t// Normally we don't want to delete locked shapes, but if the force option is set, we'll delete them anyway\n\t\tconst shapeIdsToDelete = this._shouldIgnoreShapeLock\n\t\t\t? shapeIds\n\t\t\t: this._getUnlockedShapeIds(shapeIds)\n\n\t\tif (shapeIdsToDelete.length === 0) return this\n\n\t\t// We also need to delete these shapes' descendants\n\t\tconst allShapeIdsToDelete = new Set(shapeIdsToDelete)\n\n\t\tfor (const id of shapeIdsToDelete) {\n\t\t\tthis.visitDescendants(id, (childId) => {\n\t\t\t\tallShapeIdsToDelete.add(childId)\n\t\t\t})\n\t\t}\n\n\t\treturn this.run(() => this.store.remove([...allShapeIdsToDelete]))\n\t}\n\n\t/**\n\t * Delete a shape.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.deleteShape(shape.id)\n\t * ```\n\t *\n\t * @param id - The id of the shape to delete.\n\t *\n\t * @public\n\t */\n\tdeleteShape(id: TLShapeId): this\n\tdeleteShape(shape: TLShape): this\n\tdeleteShape(_id: TLShapeId | TLShape) {\n\t\tthis.deleteShapes([typeof _id === 'string' ? _id : _id.id])\n\t\treturn this\n\t}\n\n\t/* --------------------- Styles --------------------- */\n\n\t/**\n\t * Get all the current styles among the users selected shapes\n\t *\n\t * @internal\n\t */\n\tprivate _extractSharedStyles(shape: TLShape, sharedStyleMap: SharedStyleMap) {\n\t\tif (this.isShapeOfType(shape, 'group')) {\n\t\t\t// For groups, ignore the styles of the group shape and instead include the styles of the\n\t\t\t// group's children. These are the shapes that would have their styles changed if the\n\t\t\t// user called `setStyle` on the current selection.\n\t\t\tconst childIds = this._parentIdsToChildIds.get()[shape.id]\n\t\t\tif (!childIds) return\n\n\t\t\tfor (let i = 0, n = childIds.length; i < n; i++) {\n\t\t\t\tthis._extractSharedStyles(this.getShape(childIds[i])!, sharedStyleMap)\n\t\t\t}\n\t\t} else {\n\t\t\tfor (const [style, propKey] of this.styleProps[shape.type]) {\n\t\t\t\tsharedStyleMap.applyValue(style, getOwnProperty(shape.props, propKey))\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * A derived map containing all current styles among the user's selected shapes.\n\t *\n\t * @internal\n\t */\n\t@computed\n\tprivate _getSelectionSharedStyles(): ReadonlySharedStyleMap {\n\t\tconst selectedShapes = this.getSelectedShapes()\n\n\t\tconst sharedStyles = new SharedStyleMap()\n\t\tfor (const selectedShape of selectedShapes) {\n\t\t\tthis._extractSharedStyles(selectedShape, sharedStyles)\n\t\t}\n\n\t\treturn sharedStyles\n\t}\n\n\t/**\n\t * Get the style for the next shape.\n\t *\n\t * @example\n\t * ```ts\n\t * const color = editor.getStyleForNextShape(DefaultColorStyle)\n\t * ```\n\t *\n\t * @param style - The style to get.\n\t *\n\t * @public */\n\tgetStyleForNextShape(style: StyleProp): T {\n\t\tconst value = this.getInstanceState().stylesForNextShape[style.id]\n\t\treturn value === undefined ? style.defaultValue : (value as T)\n\t}\n\n\tgetShapeStyleIfExists(shape: TLShape, style: StyleProp): T | undefined {\n\t\tconst styleKey = this.styleProps[shape.type].get(style)\n\t\tif (styleKey === undefined) return undefined\n\t\treturn getOwnProperty(shape.props, styleKey) as T | undefined\n\t}\n\n\t/**\n\t * A map of all the current styles either in the current selection, or that are relevant to the\n\t * current tool.\n\t *\n\t * @example\n\t * ```ts\n\t * const color = editor.getSharedStyles().get(DefaultColorStyle)\n\t * if (color && color.type === 'shared') {\n\t * print('All selected shapes have the same color:', color.value)\n\t * }\n\t * ```\n\t *\n\t * @public\n\t */\n\t@computed({ isEqual: (a, b) => a.equals(b) })\n\tgetSharedStyles(): ReadonlySharedStyleMap {\n\t\t// If we're in selecting and if we have a selection, return the shared styles from the\n\t\t// current selection\n\t\tif (this.isIn('select') && this.getSelectedShapeIds().length > 0) {\n\t\t\treturn this._getSelectionSharedStyles()\n\t\t}\n\n\t\t// If the current tool is associated with a shape, return the styles for that shape.\n\t\t// Otherwise, just return an empty map.\n\t\tconst currentTool = this.root.getCurrent()!\n\t\tconst styles = new SharedStyleMap()\n\n\t\tif (!currentTool) return styles\n\n\t\tif (currentTool.shapeType) {\n\t\t\tfor (const style of this.styleProps[currentTool.shapeType].keys()) {\n\t\t\t\tstyles.applyValue(style, this.getStyleForNextShape(style))\n\t\t\t}\n\t\t}\n\n\t\treturn styles\n\t}\n\n\t/**\n\t * Get the currently selected shared opacity.\n\t * If any shapes are selected, this returns the shared opacity of the selected shapes.\n\t * Otherwise, this returns the chosen opacity for the next shape.\n\t *\n\t * @public\n\t */\n\t@computed getSharedOpacity(): SharedStyle {\n\t\tif (this.isIn('select') && this.getSelectedShapeIds().length > 0) {\n\t\t\tconst shapesToCheck: TLShape[] = []\n\t\t\tconst addShape = (shapeId: TLShapeId) => {\n\t\t\t\tconst shape = this.getShape(shapeId)\n\t\t\t\tif (!shape) return\n\t\t\t\t// For groups, ignore the opacity of the group shape and instead include\n\t\t\t\t// the opacity of the group's children. These are the shapes that would have\n\t\t\t\t// their opacity changed if the user called `setOpacity` on the current selection.\n\t\t\t\tif (this.isShapeOfType(shape, 'group')) {\n\t\t\t\t\tfor (const childId of this.getSortedChildIdsForParent(shape.id)) {\n\t\t\t\t\t\taddShape(childId)\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tshapesToCheck.push(shape)\n\t\t\t\t}\n\t\t\t}\n\t\t\tfor (const shapeId of this.getSelectedShapeIds()) {\n\t\t\t\taddShape(shapeId)\n\t\t\t}\n\n\t\t\tlet opacity: number | null = null\n\t\t\tfor (const shape of shapesToCheck) {\n\t\t\t\tif (opacity === null) {\n\t\t\t\t\topacity = shape.opacity\n\t\t\t\t} else if (opacity !== shape.opacity) {\n\t\t\t\t\treturn { type: 'mixed' }\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (opacity !== null) return { type: 'shared', value: opacity }\n\t\t}\n\t\treturn { type: 'shared', value: this.getInstanceState().opacityForNextShape }\n\t}\n\n\t/**\n\t * Set the opacity for the next shapes. This will effect subsequently created shapes.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.setOpacityForNextShapes(0.5)\n\t * ```\n\t *\n\t * @param opacity - The opacity to set. Must be a number between 0 and 1 inclusive.\n\t * @param historyOptions - The history options for the change.\n\t */\n\tsetOpacityForNextShapes(opacity: number, historyOptions?: TLHistoryBatchOptions): this {\n\t\tthis.updateInstanceState({ opacityForNextShape: opacity }, historyOptions)\n\t\treturn this\n\t}\n\n\t/**\n\t * Set the current opacity. This will effect any selected shapes.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.setOpacityForSelectedShapes(0.5)\n\t * ```\n\t *\n\t * @param opacity - The opacity to set. Must be a number between 0 and 1 inclusive.\n\t */\n\tsetOpacityForSelectedShapes(opacity: number): this {\n\t\tconst selectedShapes = this.getSelectedShapes()\n\n\t\tif (selectedShapes.length > 0) {\n\t\t\tconst shapesToUpdate: TLShape[] = []\n\n\t\t\t// We can have many deep levels of grouped shape\n\t\t\t// Making a recursive function to look through all the levels\n\t\t\tconst addShapeById = (shape: TLShape) => {\n\t\t\t\tif (this.isShapeOfType(shape, 'group')) {\n\t\t\t\t\tconst childIds = this.getSortedChildIdsForParent(shape)\n\t\t\t\t\tfor (const childId of childIds) {\n\t\t\t\t\t\taddShapeById(this.getShape(childId)!)\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tshapesToUpdate.push(shape)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfor (const id of selectedShapes) {\n\t\t\t\taddShapeById(id)\n\t\t\t}\n\n\t\t\tthis.updateShapes(\n\t\t\t\tshapesToUpdate.map((shape) => {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tid: shape.id,\n\t\t\t\t\t\ttype: shape.type,\n\t\t\t\t\t\topacity,\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t)\n\t\t}\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Set the value of a {@link @tldraw/tlschema#StyleProp} for the next shapes. This change will be applied to subsequently created shapes.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.setStyleForNextShapes(DefaultColorStyle, 'red')\n\t * editor.setStyleForNextShapes(DefaultColorStyle, 'red', { ephemeral: true })\n\t * ```\n\t *\n\t * @param style - The style to set.\n\t * @param value - The value to set.\n\t * @param historyOptions - The history options for the change.\n\t *\n\t * @public\n\t */\n\tsetStyleForNextShapes(\n\t\tstyle: StyleProp,\n\t\tvalue: T,\n\t\thistoryOptions?: TLHistoryBatchOptions\n\t): this {\n\t\tconst stylesForNextShape = this.getInstanceState().stylesForNextShape\n\n\t\tthis.updateInstanceState(\n\t\t\t{ stylesForNextShape: { ...stylesForNextShape, [style.id]: value } },\n\t\t\thistoryOptions\n\t\t)\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Set the value of a {@link @tldraw/tlschema#StyleProp}. This change will be applied to the currently selected shapes.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.setStyleForSelectedShapes(DefaultColorStyle, 'red')\n\t * ```\n\t *\n\t * @param style - The style to set.\n\t * @param value - The value to set.\n\t *\n\t * @public\n\t */\n\tsetStyleForSelectedShapes>(style: S, value: StylePropValue): this {\n\t\tconst selectedShapes = this.getSelectedShapes()\n\n\t\tif (selectedShapes.length > 0) {\n\t\t\tconst updates: {\n\t\t\t\tutil: ShapeUtil\n\t\t\t\toriginalShape: TLShape\n\t\t\t\tupdatePartial: TLShapePartial\n\t\t\t}[] = []\n\n\t\t\t// We can have many deep levels of grouped shape\n\t\t\t// Making a recursive function to look through all the levels\n\t\t\tconst addShapeById = (shape: TLShape) => {\n\t\t\t\tif (this.isShapeOfType(shape, 'group')) {\n\t\t\t\t\tconst childIds = this.getSortedChildIdsForParent(shape.id)\n\t\t\t\t\tfor (const childId of childIds) {\n\t\t\t\t\t\taddShapeById(this.getShape(childId)!)\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tconst util = this.getShapeUtil(shape)\n\t\t\t\t\tconst stylePropKey = this.styleProps[shape.type].get(style)\n\t\t\t\t\tif (stylePropKey) {\n\t\t\t\t\t\tconst shapePartial: TLShapePartial = {\n\t\t\t\t\t\t\tid: shape.id,\n\t\t\t\t\t\t\ttype: shape.type,\n\t\t\t\t\t\t\tprops: { [stylePropKey]: value },\n\t\t\t\t\t\t}\n\t\t\t\t\t\tupdates.push({\n\t\t\t\t\t\t\tutil,\n\t\t\t\t\t\t\toriginalShape: shape,\n\t\t\t\t\t\t\tupdatePartial: shapePartial,\n\t\t\t\t\t\t})\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfor (const shape of selectedShapes) {\n\t\t\t\taddShapeById(shape)\n\t\t\t}\n\n\t\t\tthis.updateShapes(updates.map(({ updatePartial }) => updatePartial))\n\t\t}\n\n\t\treturn this\n\t}\n\n\t/* --------------------- Content -------------------- */\n\n\t/** @internal */\n\texternalAssetContentHandlers: {\n\t\t[K in TLExternalAssetContent['type']]: {\n\t\t\t[Key in K]:\n\t\t\t\t| null\n\t\t\t\t| ((info: TLExternalAssetContent & { type: Key }) => Promise)\n\t\t}[K]\n\t} = {\n\t\tfile: null,\n\t\turl: null,\n\t}\n\n\t/** @internal */\n\tprivate readonly temporaryAssetPreview = new Map()\n\n\t/**\n\t * Register an external asset handler. This handler will be called when the editor needs to\n\t * create an asset for some external content, like an image/video file or a bookmark URL. For\n\t * example, the 'file' type handler will be called when a user drops an image onto the canvas.\n\t *\n\t * The handler should extract any relevant metadata for the asset, upload it to blob storage\n\t * using {@link Editor.uploadAsset} if needed, and return the asset with the metadata & uploaded\n\t * URL.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.registerExternalAssetHandler('file', myHandler)\n\t * ```\n\t *\n\t * @param type - The type of external content.\n\t * @param handler - The handler to use for this content type.\n\t *\n\t * @public\n\t */\n\tregisterExternalAssetHandler(\n\t\ttype: T,\n\t\thandler: null | ((info: TLExternalAssetContent & { type: T }) => Promise)\n\t): this {\n\t\tthis.externalAssetContentHandlers[type] = handler as any\n\t\treturn this\n\t}\n\n\t/**\n\t * Register a temporary preview of an asset. This is useful for showing a ghost image of\n\t * something that is being uploaded. Retrieve the placeholder with\n\t * {@link Editor.getTemporaryAssetPreview}. Placeholders last for 3 minutes by default, but this\n\t * can be configured using\n\t *\n\t * @example\n\t * ```ts\n\t * editor.createTemporaryAssetPreview(assetId, file)\n\t * ```\n\t *\n\t * @param assetId - The asset's id.\n\t * @param file - The raw file.\n\t *\n\t * @public\n\t */\n\tcreateTemporaryAssetPreview(assetId: TLAssetId, file: File) {\n\t\tif (this.temporaryAssetPreview.has(assetId)) {\n\t\t\treturn this.temporaryAssetPreview.get(assetId)\n\t\t}\n\n\t\tconst objectUrl = URL.createObjectURL(file)\n\t\tthis.temporaryAssetPreview.set(assetId, objectUrl)\n\n\t\t// eslint-disable-next-line no-restricted-globals -- we always want to revoke the asset and object URL\n\t\tsetTimeout(() => {\n\t\t\tthis.temporaryAssetPreview.delete(assetId)\n\t\t\tURL.revokeObjectURL(objectUrl)\n\t\t}, this.options.temporaryAssetPreviewLifetimeMs)\n\n\t\treturn objectUrl\n\t}\n\n\t/**\n\t * Get temporary preview of an asset. This is useful for showing a ghost\n\t * image of something that is being uploaded.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getTemporaryAssetPreview('someId')\n\t * ```\n\t *\n\t * @param assetId - The asset's id.\n\t *\n\t * @public\n\t */\n\tgetTemporaryAssetPreview(assetId: TLAssetId) {\n\t\treturn this.temporaryAssetPreview.get(assetId)\n\t}\n\n\t/**\n\t * Get an asset for an external asset content type.\n\t *\n\t * @example\n\t * ```ts\n\t * const asset = await editor.getAssetForExternalContent({ type: 'file', file: myFile })\n\t * const asset = await editor.getAssetForExternalContent({ type: 'url', url: myUrl })\n\t * ```\n\t *\n\t * @param info - Info about the external content.\n\t * @returns The asset.\n\t */\n\tasync getAssetForExternalContent(info: TLExternalAssetContent): Promise {\n\t\treturn await this.externalAssetContentHandlers[info.type]?.(info as any)\n\t}\n\n\thasExternalAssetHandler(type: TLExternalAssetContent['type']): boolean {\n\t\treturn !!this.externalAssetContentHandlers[type]\n\t}\n\n\t/** @internal */\n\texternalContentHandlers: {\n\t\t[K in TLExternalContent['type']]: {\n\t\t\t[Key in K]: null | ((info: TLExternalContent & { type: Key }) => void)\n\t\t}[K]\n\t} = {\n\t\ttext: null,\n\t\tfiles: null,\n\t\tembed: null,\n\t\t'svg-text': null,\n\t\turl: null,\n\t}\n\n\t/**\n\t * Register an external content handler. This handler will be called when the editor receives\n\t * external content of the provided type. For example, the 'image' type handler will be called\n\t * when a user drops an image onto the canvas.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.registerExternalContentHandler('text', myHandler)\n\t * ```\n\t * @example\n\t * ```ts\n\t * editor.registerExternalContentHandler<'embed', MyEmbedType>('embed', myHandler)\n\t * ```\n\t *\n\t * @param type - The type of external content.\n\t * @param handler - The handler to use for this content type.\n\t *\n\t * @public\n\t */\n\tregisterExternalContentHandler['type'], E>(\n\t\ttype: T,\n\t\thandler:\n\t\t\t| null\n\t\t\t| ((\n\t\t\t\t\tinfo: T extends TLExternalContent['type']\n\t\t\t\t\t\t? TLExternalContent & { type: T }\n\t\t\t\t\t\t: TLExternalContent\n\t\t\t ) => void)\n\t): this {\n\t\tthis.externalContentHandlers[type] = handler as any\n\t\treturn this\n\t}\n\n\t/**\n\t * Handle external content, such as files, urls, embeds, or plain text which has been put into the app, for example by pasting external text or dropping external images onto canvas.\n\t *\n\t * @param info - Info about the external content.\n\t */\n\tasync putExternalContent(info: TLExternalContent): Promise {\n\t\treturn this.externalContentHandlers[info.type]?.(info as any)\n\t}\n\n\t/**\n\t * Get content that can be exported for the given shape ids.\n\t *\n\t * @param shapes - The shapes (or shape ids) to get content for.\n\t *\n\t * @returns The exported content.\n\t *\n\t * @public\n\t */\n\tgetContentFromCurrentPage(shapes: TLShapeId[] | TLShape[]): TLContent | undefined {\n\t\t// todo: make this work with any page, not just the current page\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\n\t\tif (!ids) return\n\t\tif (ids.length === 0) return\n\n\t\tconst shapeIds = this.getShapeAndDescendantIds(ids)\n\n\t\treturn withIsolatedShapes(this, shapeIds, (bindingIdsToKeep) => {\n\t\t\tconst bindings: TLBinding[] = []\n\t\t\tfor (const id of bindingIdsToKeep) {\n\t\t\t\tconst binding = this.getBinding(id)\n\t\t\t\tif (!binding) continue\n\t\t\t\tbindings.push(binding)\n\t\t\t}\n\n\t\t\tconst rootShapeIds: TLShapeId[] = []\n\t\t\tconst shapes: TLShape[] = []\n\t\t\tfor (const shapeId of shapeIds) {\n\t\t\t\tconst shape = this.getShape(shapeId)\n\t\t\t\tif (!shape) continue\n\n\t\t\t\tconst isRootShape = !shapeIds.has(shape.parentId as TLShapeId)\n\t\t\t\tif (isRootShape) {\n\t\t\t\t\t// Need to get page point and rotation of the shape because shapes in\n\t\t\t\t\t// groups use local position/rotation\n\t\t\t\t\tconst pageTransform = this.getShapePageTransform(shape.id)!\n\t\t\t\t\tconst pagePoint = pageTransform.point()\n\t\t\t\t\tshapes.push({\n\t\t\t\t\t\t...shape,\n\t\t\t\t\t\tx: pagePoint.x,\n\t\t\t\t\t\ty: pagePoint.y,\n\t\t\t\t\t\trotation: pageTransform.rotation(),\n\t\t\t\t\t\tparentId: this.getCurrentPageId(),\n\t\t\t\t\t})\n\t\t\t\t\trootShapeIds.push(shape.id)\n\t\t\t\t} else {\n\t\t\t\t\tshapes.push(shape)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst assets: TLAsset[] = []\n\t\t\tconst seenAssetIds = new Set()\n\t\t\tfor (const shape of shapes) {\n\t\t\t\tif (!('assetId' in shape.props)) continue\n\n\t\t\t\tconst assetId = shape.props.assetId\n\t\t\t\tif (!assetId || seenAssetIds.has(assetId)) continue\n\n\t\t\t\tseenAssetIds.add(assetId)\n\t\t\t\tconst asset = this.getAsset(assetId)\n\t\t\t\tif (!asset) continue\n\t\t\t\tassets.push(asset)\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tschema: this.store.schema.serialize(),\n\t\t\t\tshapes,\n\t\t\t\trootShapeIds,\n\t\t\t\tbindings,\n\t\t\t\tassets,\n\t\t\t}\n\t\t})\n\t}\n\n\tasync resolveAssetsInContent(content: TLContent | undefined): Promise {\n\t\tif (!content) return undefined\n\n\t\tconst assets: TLAsset[] = []\n\t\tawait Promise.allSettled(\n\t\t\tcontent.assets.map(async (asset) => {\n\t\t\t\tif (\n\t\t\t\t\t(asset.type === 'image' || asset.type === 'video') &&\n\t\t\t\t\t!asset.props.src?.startsWith('data:image') &&\n\t\t\t\t\t!asset.props.src?.startsWith('http')\n\t\t\t\t) {\n\t\t\t\t\tconst assetWithDataUrl = structuredClone(asset as TLImageAsset | TLVideoAsset)\n\t\t\t\t\tconst objectUrl = await this.store.props.assets.resolve(asset, {\n\t\t\t\t\t\tscreenScale: 1,\n\t\t\t\t\t\tsteppedScreenScale: 1,\n\t\t\t\t\t\tdpr: 1,\n\t\t\t\t\t\tnetworkEffectiveType: null,\n\t\t\t\t\t\tshouldResolveToOriginal: true,\n\t\t\t\t\t})\n\t\t\t\t\tassetWithDataUrl.props.src = await FileHelpers.blobToDataUrl(\n\t\t\t\t\t\tawait fetch(objectUrl!).then((r) => r.blob())\n\t\t\t\t\t)\n\t\t\t\t\tassets.push(assetWithDataUrl)\n\t\t\t\t} else {\n\t\t\t\t\tassets.push(asset)\n\t\t\t\t}\n\t\t\t})\n\t\t)\n\t\tcontent.assets = assets\n\n\t\treturn content\n\t}\n\n\t/**\n\t * Place content into the editor.\n\t *\n\t * @param content - The content.\n\t * @param opts - Options for placing the content.\n\t *\n\t * @public\n\t */\n\tputContentOntoCurrentPage(\n\t\tcontent: TLContent,\n\t\topts: {\n\t\t\tpoint?: VecLike\n\t\t\tselect?: boolean\n\t\t\tpreservePosition?: boolean\n\t\t\tpreserveIds?: boolean\n\t\t} = {}\n\t): this {\n\t\tif (this.getIsReadonly()) return this\n\n\t\t// todo: make this able to support putting content onto any page, not just the current page\n\n\t\tif (!content.schema) {\n\t\t\tthrow Error('Could not put content:\\ncontent is missing a schema.')\n\t\t}\n\n\t\tconst { select = false, preserveIds = false, preservePosition = false } = opts\n\t\tlet { point = undefined } = opts\n\n\t\t// decide on a parent for the put shapes; if the parent is among the put shapes(?) then use its parent\n\n\t\tconst currentPageId = this.getCurrentPageId()\n\t\tconst { rootShapeIds } = content\n\n\t\t// We need to collect the migrated records\n\t\tconst assets: TLAsset[] = []\n\t\tconst shapes: TLShape[] = []\n\t\tconst bindings: TLBinding[] = []\n\n\t\t// Let's treat the content as a store, and then migrate that store.\n\t\tconst store: StoreSnapshot = {\n\t\t\tstore: {\n\t\t\t\t...Object.fromEntries(content.assets.map((asset) => [asset.id, asset] as const)),\n\t\t\t\t...Object.fromEntries(content.shapes.map((shape) => [shape.id, shape] as const)),\n\t\t\t\t...Object.fromEntries(\n\t\t\t\t\tcontent.bindings?.map((bindings) => [bindings.id, bindings] as const) ?? []\n\t\t\t\t),\n\t\t\t},\n\t\t\tschema: content.schema,\n\t\t}\n\t\tconst result = this.store.schema.migrateStoreSnapshot(store)\n\t\tif (result.type === 'error') {\n\t\t\tthrow Error('Could not put content: could not migrate content')\n\t\t}\n\t\tfor (const record of Object.values(result.value)) {\n\t\t\tswitch (record.typeName) {\n\t\t\t\tcase 'asset': {\n\t\t\t\t\tassets.push(record)\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase 'shape': {\n\t\t\t\t\tshapes.push(record)\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase 'binding': {\n\t\t\t\t\tbindings.push(record)\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Ok, we've got our migrated records, now we can continue!\n\t\tconst shapeIdMap = new Map(\n\t\t\tpreserveIds\n\t\t\t\t? shapes.map((shape) => [shape.id, shape.id])\n\t\t\t\t: shapes.map((shape) => [shape.id, createShapeId()])\n\t\t)\n\t\tconst bindingIdMap = new Map(\n\t\t\tpreserveIds\n\t\t\t\t? bindings.map((binding) => [binding.id, binding.id])\n\t\t\t\t: bindings.map((binding) => [binding.id, createBindingId()])\n\t\t)\n\n\t\t// By default, the paste parent will be the current page.\n\t\tlet pasteParentId = this.getCurrentPageId() as TLPageId | TLShapeId\n\t\tlet lowestDepth = Infinity\n\t\tlet lowestAncestors: TLShape[] = []\n\n\t\t// Among the selected shapes, find the shape with the fewest ancestors and use its first ancestor.\n\t\tfor (const shape of this.getSelectedShapes()) {\n\t\t\tif (lowestDepth === 0) break\n\n\t\t\tconst isFrame = this.isShapeOfType(shape, 'frame')\n\t\t\tconst ancestors = this.getShapeAncestors(shape)\n\t\t\tif (isFrame) ancestors.push(shape)\n\n\t\t\tconst depth = isFrame ? ancestors.length + 1 : ancestors.length\n\n\t\t\tif (depth < lowestDepth) {\n\t\t\t\tlowestDepth = depth\n\t\t\t\tlowestAncestors = ancestors\n\t\t\t\tpasteParentId = isFrame ? shape.id : shape.parentId\n\t\t\t} else if (depth === lowestDepth) {\n\t\t\t\tif (lowestAncestors.length !== ancestors.length) {\n\t\t\t\t\tthrow Error(`Ancestors: ${lowestAncestors.length} !== ${ancestors.length}`)\n\t\t\t\t}\n\n\t\t\t\tif (lowestAncestors.length === 0) {\n\t\t\t\t\tpasteParentId = currentPageId\n\t\t\t\t\tbreak\n\t\t\t\t} else {\n\t\t\t\t\tpasteParentId = currentPageId\n\t\t\t\t\tfor (let i = 0; i < lowestAncestors.length; i++) {\n\t\t\t\t\t\tif (ancestors[i] !== lowestAncestors[i]) break\n\t\t\t\t\t\tpasteParentId = ancestors[i].id\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tlet isDuplicating = false\n\n\t\tif (!isPageId(pasteParentId)) {\n\t\t\tconst parent = this.getShape(pasteParentId)\n\t\t\tif (parent) {\n\t\t\t\tif (!this.getViewportPageBounds().includes(this.getShapePageBounds(parent)!)) {\n\t\t\t\t\tpasteParentId = currentPageId\n\t\t\t\t} else {\n\t\t\t\t\tif (rootShapeIds.length === 1) {\n\t\t\t\t\t\tconst rootShape = shapes.find((s) => s.id === rootShapeIds[0])!\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\tthis.isShapeOfType(parent, 'frame') &&\n\t\t\t\t\t\t\tthis.isShapeOfType(rootShape, 'frame') &&\n\t\t\t\t\t\t\trootShape.props.w === parent?.props.w &&\n\t\t\t\t\t\t\trootShape.props.h === parent?.props.h\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\tisDuplicating = true\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tpasteParentId = currentPageId\n\t\t\t}\n\t\t}\n\n\t\tif (!isDuplicating) {\n\t\t\tisDuplicating = shapeIdMap.has(pasteParentId)\n\t\t}\n\n\t\tif (isDuplicating) {\n\t\t\tpasteParentId = this.getShape(pasteParentId)!.parentId\n\t\t}\n\n\t\tlet index = this.getHighestIndexForParent(pasteParentId) // todo: requires that the putting page is the current page\n\n\t\tconst rootShapes: TLShape[] = []\n\n\t\tconst newShapes: TLShape[] = shapes.map((oldShape): TLShape => {\n\t\t\tconst newId = shapeIdMap.get(oldShape.id)!\n\n\t\t\t// Create the new shape (new except for the id)\n\t\t\tconst newShape = { ...oldShape, id: newId }\n\n\t\t\tif (rootShapeIds.includes(oldShape.id)) {\n\t\t\t\tnewShape.parentId = currentPageId\n\t\t\t\trootShapes.push(newShape)\n\t\t\t}\n\n\t\t\t// Assign the child to its new parent.\n\n\t\t\t// If the child's parent is among the putting shapes, then assign\n\t\t\t// it to the new parent's id.\n\t\t\tif (shapeIdMap.has(newShape.parentId)) {\n\t\t\t\tnewShape.parentId = shapeIdMap.get(oldShape.parentId)!\n\t\t\t} else {\n\t\t\t\trootShapeIds.push(newShape.id)\n\t\t\t\t// newShape.parentId = pasteParentId\n\t\t\t\tnewShape.index = index\n\t\t\t\tindex = getIndexAbove(index)\n\t\t\t}\n\n\t\t\treturn newShape\n\t\t})\n\n\t\tif (newShapes.length + this.getCurrentPageShapeIds().size > this.options.maxShapesPerPage) {\n\t\t\t// There's some complexity here involving children\n\t\t\t// that might be created without their parents, so\n\t\t\t// if we're going over the limit then just don't paste.\n\t\t\talertMaxShapes(this)\n\t\t\treturn this\n\t\t}\n\n\t\tconst newBindings = bindings.map(\n\t\t\t(oldBinding): TLBinding => ({\n\t\t\t\t...oldBinding,\n\t\t\t\tid: assertExists(bindingIdMap.get(oldBinding.id)),\n\t\t\t\tfromId: assertExists(shapeIdMap.get(oldBinding.fromId)),\n\t\t\t\ttoId: assertExists(shapeIdMap.get(oldBinding.toId)),\n\t\t\t})\n\t\t)\n\n\t\t// These are all the assets we need to create\n\t\tconst assetsToCreate: TLAsset[] = []\n\n\t\t// These assets have base64 data that may need to be hosted\n\t\tconst assetsToUpdate: (TLImageAsset | TLVideoAsset)[] = []\n\n\t\tfor (const asset of assets) {\n\t\t\tif (this.store.has(asset.id)) {\n\t\t\t\t// We already have this asset\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tif (\n\t\t\t\t(asset.type === 'image' || asset.type === 'video') &&\n\t\t\t\tasset.props.src?.startsWith('data:image')\n\t\t\t) {\n\t\t\t\t// it's src is a base64 image or video; we need to create a new asset without the src,\n\t\t\t\t// then create a new asset from the original src. So we save a copy of the original asset,\n\t\t\t\t// then delete the src from the original asset.\n\t\t\t\tassetsToUpdate.push(structuredClone(asset as TLImageAsset | TLVideoAsset))\n\t\t\t\tasset.props.src = null\n\t\t\t}\n\n\t\t\t// Add the asset to the list of assets to create\n\t\t\tassetsToCreate.push(asset)\n\t\t}\n\n\t\t// Start loading the new assets, order does not matter\n\t\tPromise.allSettled(\n\t\t\t(assetsToUpdate as (TLImageAsset | TLVideoAsset)[]).map(async (asset) => {\n\t\t\t\t// Turn the data url into a file\n\t\t\t\tconst file = await dataUrlToFile(\n\t\t\t\t\tasset.props.src!,\n\t\t\t\t\tasset.props.name,\n\t\t\t\t\tasset.props.mimeType ?? 'image/png'\n\t\t\t\t)\n\n\t\t\t\t// Get a new asset for the file\n\t\t\t\tconst newAsset = await this.getAssetForExternalContent({\n\t\t\t\t\ttype: 'file',\n\t\t\t\t\tfile,\n\t\t\t\t\tassetId: asset.id,\n\t\t\t\t})\n\n\t\t\t\tif (!newAsset) {\n\t\t\t\t\t// If we don't have a new asset, delete the old asset.\n\t\t\t\t\t// The shapes that reference this asset should break.\n\t\t\t\t\tthis.deleteAssets([asset.id])\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\t// Save the new asset under the old asset's id\n\t\t\t\tthis.updateAssets([{ ...newAsset, id: asset.id }])\n\t\t\t})\n\t\t)\n\n\t\tthis.run(() => {\n\t\t\t// Create any assets that need to be created\n\t\t\tif (assetsToCreate.length > 0) {\n\t\t\t\tthis.createAssets(assetsToCreate)\n\t\t\t}\n\n\t\t\t// Create the shapes with root shapes as children of the page\n\t\t\tthis.createShapes(newShapes)\n\t\t\tthis.createBindings(newBindings)\n\n\t\t\tif (select) {\n\t\t\t\tthis.select(...rootShapes.map((s) => s.id))\n\t\t\t}\n\n\t\t\t// And then, if needed, reparent the root shapes to the paste parent\n\t\t\tif (pasteParentId !== currentPageId) {\n\t\t\t\tthis.reparentShapes(\n\t\t\t\t\trootShapes.map((s) => s.id),\n\t\t\t\t\tpasteParentId\n\t\t\t\t)\n\t\t\t}\n\n\t\t\tconst newCreatedShapes = newShapes.map((s) => this.getShape(s.id)!)\n\t\t\tconst bounds = Box.Common(newCreatedShapes.map((s) => this.getShapePageBounds(s)!))\n\n\t\t\tif (point === undefined) {\n\t\t\t\tif (!isPageId(pasteParentId)) {\n\t\t\t\t\t// Put the shapes in the middle of the (on screen) parent\n\t\t\t\t\tconst shape = this.getShape(pasteParentId)!\n\t\t\t\t\tpoint = Mat.applyToPoint(\n\t\t\t\t\t\tthis.getShapePageTransform(shape),\n\t\t\t\t\t\tthis.getShapeGeometry(shape).bounds.center\n\t\t\t\t\t)\n\t\t\t\t} else {\n\t\t\t\t\tconst viewportPageBounds = this.getViewportPageBounds()\n\t\t\t\t\tif (preservePosition || viewportPageBounds.includes(Box.From(bounds))) {\n\t\t\t\t\t\t// Otherwise, put shapes where they used to be\n\t\t\t\t\t\tpoint = bounds.center\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// If the old bounds are outside of the viewport...\n\t\t\t\t\t\t// put the shapes in the middle of the viewport\n\t\t\t\t\t\tpoint = viewportPageBounds.center\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (rootShapes.length === 1) {\n\t\t\t\tconst onlyRoot = rootShapes[0] as TLFrameShape\n\t\t\t\t// If the old bounds are in the viewport...\n\t\t\t\tif (this.isShapeOfType(onlyRoot, 'frame')) {\n\t\t\t\t\twhile (\n\t\t\t\t\t\tthis.getShapesAtPoint(point).some(\n\t\t\t\t\t\t\t(shape) =>\n\t\t\t\t\t\t\t\tthis.isShapeOfType(shape, 'frame') &&\n\t\t\t\t\t\t\t\tshape.props.w === onlyRoot.props.w &&\n\t\t\t\t\t\t\t\tshape.props.h === onlyRoot.props.h\n\t\t\t\t\t\t)\n\t\t\t\t\t) {\n\t\t\t\t\t\tpoint.x += bounds.w + 16\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst pageCenter = Box.Common(\n\t\t\t\tcompact(rootShapes.map(({ id }) => this.getShapePageBounds(id)))\n\t\t\t).center\n\n\t\t\tconst offset = Vec.Sub(point, pageCenter)\n\n\t\t\tthis.updateShapes(\n\t\t\t\trootShapes.map(({ id }) => {\n\t\t\t\t\tconst s = this.getShape(id)!\n\t\t\t\t\tconst localRotation = this.getShapeParentTransform(id).decompose().rotation\n\t\t\t\t\tconst localDelta = Vec.Rot(offset, -localRotation)\n\n\t\t\t\t\treturn { id: s.id, type: s.type, x: s.x + localDelta.x, y: s.y + localDelta.y }\n\t\t\t\t})\n\t\t\t)\n\t\t})\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Get an exported SVG element of the given shapes.\n\t *\n\t * @param shapes - The shapes (or shape ids) to export.\n\t * @param opts - Options for the export.\n\t *\n\t * @returns The SVG element.\n\t *\n\t * @public\n\t */\n\tasync getSvgElement(shapes: TLShapeId[] | TLShape[], opts: TLImageExportOptions = {}) {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\n\t\tif (ids.length === 0) return undefined\n\n\t\treturn exportToSvg(this, ids, opts)\n\t}\n\n\t/**\n\t * Get an exported SVG string of the given shapes.\n\t *\n\t * @param shapes - The shapes (or shape ids) to export.\n\t * @param opts - Options for the export.\n\t *\n\t * @returns The SVG element.\n\t *\n\t * @public\n\t */\n\tasync getSvgString(shapes: TLShapeId[] | TLShape[], opts: TLImageExportOptions = {}) {\n\t\tconst result = await this.getSvgElement(shapes, opts)\n\t\tif (!result) return undefined\n\n\t\tconst serializer = new XMLSerializer()\n\t\treturn {\n\t\t\tsvg: serializer.serializeToString(result.svg),\n\t\t\twidth: result.width,\n\t\t\theight: result.height,\n\t\t}\n\t}\n\n\t/** @deprecated Use {@link Editor.getSvgString} or {@link Editor.getSvgElement} instead. */\n\tasync getSvg(shapes: TLShapeId[] | TLShape[], opts: TLImageExportOptions = {}) {\n\t\tconst result = await this.getSvgElement(shapes, opts)\n\t\tif (!result) return undefined\n\t\treturn result.svg\n\t}\n\n\t/* --------------------- Events --------------------- */\n\n\t/**\n\t * The app's current input state.\n\t *\n\t * @public\n\t */\n\tinputs = {\n\t\t/** The most recent pointer down's position in the current page space. */\n\t\toriginPagePoint: new Vec(),\n\t\t/** The most recent pointer down's position in screen space. */\n\t\toriginScreenPoint: new Vec(),\n\t\t/** The previous pointer position in the current page space. */\n\t\tpreviousPagePoint: new Vec(),\n\t\t/** The previous pointer position in screen space. */\n\t\tpreviousScreenPoint: new Vec(),\n\t\t/** The most recent pointer position in the current page space. */\n\t\tcurrentPagePoint: new Vec(),\n\t\t/** The most recent pointer position in screen space. */\n\t\tcurrentScreenPoint: new Vec(),\n\t\t/** A set containing the currently pressed keys. */\n\t\tkeys: new Set(),\n\t\t/** A set containing the currently pressed buttons. */\n\t\tbuttons: new Set(),\n\t\t/** Whether the input is from a pe. */\n\t\tisPen: false,\n\t\t/** Whether the shift key is currently pressed. */\n\t\tshiftKey: false,\n\t\t/** Whether the meta key is currently pressed. */\n\t\tmetaKey: false,\n\t\t/** Whether the control or command key is currently pressed. */\n\t\tctrlKey: false,\n\t\t/** Whether the alt or option key is currently pressed. */\n\t\taltKey: false,\n\t\t/** Whether the user is dragging. */\n\t\tisDragging: false,\n\t\t/** Whether the user is pointing. */\n\t\tisPointing: false,\n\t\t/** Whether the user is pinching. */\n\t\tisPinching: false,\n\t\t/** Whether the user is editing. */\n\t\tisEditing: false,\n\t\t/** Whether the user is panning. */\n\t\tisPanning: false,\n\t\t/** Whether the user is spacebar panning. */\n\t\tisSpacebarPanning: false,\n\t\t/** Velocity of mouse pointer, in pixels per millisecond */\n\t\tpointerVelocity: new Vec(),\n\t}\n\n\t/**\n\t * Update the input points from a pointer, pinch, or wheel event.\n\t *\n\t * @param info - The event info.\n\t */\n\tprivate _updateInputsFromEvent(\n\t\tinfo: TLPointerEventInfo | TLPinchEventInfo | TLWheelEventInfo\n\t): void {\n\t\tconst {\n\t\t\tpointerVelocity,\n\t\t\tpreviousScreenPoint,\n\t\t\tpreviousPagePoint,\n\t\t\tcurrentScreenPoint,\n\t\t\tcurrentPagePoint,\n\t\t} = this.inputs\n\n\t\tconst { screenBounds } = this.store.unsafeGetWithoutCapture(TLINSTANCE_ID)!\n\t\tconst { x: cx, y: cy, z: cz } = unsafe__withoutCapture(() => this.getCamera())\n\n\t\tconst sx = info.point.x - screenBounds.x\n\t\tconst sy = info.point.y - screenBounds.y\n\t\tconst sz = info.point.z ?? 0.5\n\n\t\tpreviousScreenPoint.setTo(currentScreenPoint)\n\t\tpreviousPagePoint.setTo(currentPagePoint)\n\n\t\t// The \"screen bounds\" is relative to the user's actual screen.\n\t\t// The \"screen point\" is relative to the \"screen bounds\";\n\t\t// it will be 0,0 when its actual screen position is equal\n\t\t// to screenBounds.point. This is confusing!\n\t\tcurrentScreenPoint.set(sx, sy)\n\t\tconst nx = sx / cz - cx\n\t\tconst ny = sy / cz - cy\n\t\tif (isFinite(nx) && isFinite(ny)) {\n\t\t\tcurrentPagePoint.set(nx, ny, sz)\n\t\t}\n\n\t\tthis.inputs.isPen = info.type === 'pointer' && info.isPen\n\n\t\t// Reset velocity on pointer down, or when a pinch starts or ends\n\t\tif (info.name === 'pointer_down' || this.inputs.isPinching) {\n\t\t\tpointerVelocity.set(0, 0)\n\t\t\tthis.inputs.originScreenPoint.setTo(currentScreenPoint)\n\t\t\tthis.inputs.originPagePoint.setTo(currentPagePoint)\n\t\t}\n\n\t\t// todo: We only have to do this if there are multiple users in the document\n\t\tthis.run(\n\t\t\t() => {\n\t\t\t\tthis.store.put([\n\t\t\t\t\t{\n\t\t\t\t\t\tid: TLPOINTER_ID,\n\t\t\t\t\t\ttypeName: 'pointer',\n\t\t\t\t\t\tx: currentPagePoint.x,\n\t\t\t\t\t\ty: currentPagePoint.y,\n\t\t\t\t\t\tlastActivityTimestamp:\n\t\t\t\t\t\t\t// If our pointer moved only because we're following some other user, then don't\n\t\t\t\t\t\t\t// update our last activity timestamp; otherwise, update it to the current timestamp.\n\t\t\t\t\t\t\tinfo.type === 'pointer' && info.pointerId === INTERNAL_POINTER_IDS.CAMERA_MOVE\n\t\t\t\t\t\t\t\t? this.store.unsafeGetWithoutCapture(TLPOINTER_ID)?.lastActivityTimestamp ??\n\t\t\t\t\t\t\t\t\tthis._tickManager.now\n\t\t\t\t\t\t\t\t: this._tickManager.now,\n\t\t\t\t\t\tmeta: {},\n\t\t\t\t\t},\n\t\t\t\t])\n\t\t\t},\n\t\t\t{ history: 'ignore' }\n\t\t)\n\t}\n\n\t/**\n\t * Dispatch a cancel event.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.cancel()\n\t * ```\n\t *\n\t * @public\n\t */\n\tcancel(): this {\n\t\tthis.dispatch({ type: 'misc', name: 'cancel' })\n\t\treturn this\n\t}\n\n\t/**\n\t * Dispatch an interrupt event.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.interrupt()\n\t * ```\n\t *\n\t * @public\n\t */\n\tinterrupt(): this {\n\t\tthis.dispatch({ type: 'misc', name: 'interrupt' })\n\t\treturn this\n\t}\n\n\t/**\n\t * Dispatch a complete event.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.complete()\n\t * ```\n\t *\n\t * @public\n\t */\n\tcomplete(): this {\n\t\tthis.dispatch({ type: 'misc', name: 'complete' })\n\t\treturn this\n\t}\n\n\t/**\n\t * Puts the editor into focused mode.\n\t *\n\t * This makes the editor eligible to receive keyboard events and some pointer events (move, wheel).\n\t *\n\t * @example\n\t * ```ts\n\t * editor.focus()\n\t * ```\n\t *\n\t * By default this also dispatches a 'focus' event to the container element. To prevent this, pass `focusContainer: false`.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.focus({ focusContainer: false })\n\t * ```\n\t *\n\t * @public\n\t */\n\tfocus({ focusContainer = true } = {}): this {\n\t\tif (this.getIsFocused()) return this\n\t\tif (focusContainer) this.focusManager.focus()\n\t\tthis.updateInstanceState({ isFocused: true })\n\t\treturn this\n\t}\n\n\t/**\n\t * Switches off the editor's focused mode.\n\t *\n\t * This makes the editor ignore keyboard events and some pointer events (move, wheel).\n\t *\n\t * @example\n\t * ```ts\n\t * editor.blur()\n\t * ```\n\t * By default this also dispatches a 'blur' event to the container element. To prevent this, pass `blurContainer: false`.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.blur({ blurContainer: false })\n\t * ```\n\t *\n\t * @public\n\t */\n\tblur({ blurContainer = true } = {}): this {\n\t\tif (!this.getIsFocused()) return this\n\t\tif (blurContainer) {\n\t\t\tthis.focusManager.blur()\n\t\t} else {\n\t\t\tthis.complete() // stop any interaction\n\t\t}\n\t\tthis.updateInstanceState({ isFocused: false })\n\t\treturn this\n\t}\n\n\t/**\n\t * @public\n\t * @returns true if the editor is focused\n\t */\n\t@computed getIsFocused() {\n\t\treturn this.getInstanceState().isFocused\n\t}\n\n\t/**\n\t * @public\n\t * @returns true if the editor is in readonly mode\n\t */\n\t@computed getIsReadonly() {\n\t\treturn this.getInstanceState().isReadonly\n\t}\n\n\t/**\n\t * @public\n\t * @returns a snapshot of the store's UI and document state\n\t */\n\tgetSnapshot() {\n\t\treturn getSnapshot(this.store)\n\t}\n\n\t/**\n\t * Loads a snapshot into the editor.\n\t * @param snapshot - The snapshot to load.\n\t * @param opts - The options for loading the snapshot.\n\t * @returns\n\t */\n\tloadSnapshot(\n\t\tsnapshot: Partial | TLStoreSnapshot,\n\t\topts?: TLLoadSnapshotOptions\n\t) {\n\t\tloadSnapshot(this.store, snapshot, opts)\n\t\treturn this\n\t}\n\n\tprivate _zoomToFitPageContentAt100Percent() {\n\t\tconst bounds = this.getCurrentPageBounds()\n\t\tif (bounds) {\n\t\t\tthis.zoomToBounds(bounds, { immediate: true, targetZoom: this.getBaseZoom() })\n\t\t}\n\t}\n\tprivate _navigateToDeepLink(deepLink: TLDeepLink) {\n\t\tthis.run(() => {\n\t\t\tswitch (deepLink.type) {\n\t\t\t\tcase 'page': {\n\t\t\t\t\tconst page = this.getPage(deepLink.pageId)\n\t\t\t\t\tif (page) {\n\t\t\t\t\t\tthis.setCurrentPage(page)\n\t\t\t\t\t}\n\t\t\t\t\tthis._zoomToFitPageContentAt100Percent()\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tcase 'shapes': {\n\t\t\t\t\tconst allShapes = compact(deepLink.shapeIds.map((id) => this.getShape(id)))\n\t\t\t\t\tconst byPage: { [pageId: string]: TLShape[] } = {}\n\t\t\t\t\tfor (const shape of allShapes) {\n\t\t\t\t\t\tconst pageId = this.getAncestorPageId(shape)\n\t\t\t\t\t\tif (!pageId) continue\n\t\t\t\t\t\tbyPage[pageId] ??= []\n\t\t\t\t\t\tbyPage[pageId].push(shape)\n\t\t\t\t\t}\n\t\t\t\t\tconst [pageId, shapes] = Object.entries(byPage).sort(\n\t\t\t\t\t\t([_, a], [__, b]) => b.length - a.length\n\t\t\t\t\t)[0] ?? ['', []]\n\n\t\t\t\t\tif (!pageId || !shapes.length) {\n\t\t\t\t\t\tthis._zoomToFitPageContentAt100Percent()\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthis.setCurrentPage(pageId as TLPageId)\n\t\t\t\t\t\tconst bounds = Box.Common(shapes.map((s) => this.getShapePageBounds(s)!))\n\t\t\t\t\t\tthis.zoomToBounds(bounds, { immediate: true, targetZoom: this.getBaseZoom() })\n\t\t\t\t\t}\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tcase 'viewport': {\n\t\t\t\t\tif (deepLink.pageId) {\n\t\t\t\t\t\tif (!this.getPage(deepLink.pageId)) {\n\t\t\t\t\t\t\tthis._zoomToFitPageContentAt100Percent()\n\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t}\n\t\t\t\t\t\tthis.setCurrentPage(deepLink.pageId)\n\t\t\t\t\t}\n\t\t\t\t\tthis.zoomToBounds(deepLink.bounds, { immediate: true, inset: 0 })\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tdefault:\n\t\t\t\t\texhaustiveSwitchError(deepLink)\n\t\t\t}\n\t\t})\n\t}\n\n\t/**\n\t * Handles navigating to the content specified by the query param in the given URL.\n\t *\n\t * Use {@link Editor#createDeepLink} to create a URL with a deep link query param.\n\t *\n\t * If no URL is provided, it will look for the param in the current `window.location.href`.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.navigateToDeepLink()\n\t * ```\n\t *\n\t * The default parameter name is 'd'. You can override this by providing the `param` option.\n\t *\n\t * @example\n\t * ```ts\n\t * // disable page parameter and change viewport parameter to 'c'\n\t * editor.navigateToDeepLink({\n\t * param: 'x',\n\t * url: 'https://my-app.com/my-document?x=200.12.454.23.xyz123',\n\t * })\n\t * ```\n\t *\n\t * @param opts - Options for loading the state from the URL.\n\t */\n\tnavigateToDeepLink(opts?: TLDeepLink | { url?: string | URL; param?: string }): Editor {\n\t\tif (opts && 'type' in opts) {\n\t\t\tthis._navigateToDeepLink(opts)\n\t\t\treturn this\n\t\t}\n\n\t\tconst url = new URL(opts?.url ?? window.location.href)\n\t\tconst deepLinkString = url.searchParams.get(opts?.param ?? 'd')\n\n\t\tif (!deepLinkString) {\n\t\t\tthis._zoomToFitPageContentAt100Percent()\n\t\t\treturn this\n\t\t}\n\n\t\ttry {\n\t\t\tthis._navigateToDeepLink(parseDeepLinkString(deepLinkString))\n\t\t} catch (e) {\n\t\t\tconsole.warn(e)\n\t\t\tthis._zoomToFitPageContentAt100Percent()\n\t\t}\n\t\treturn this\n\t}\n\n\t/**\n\t * Turns the given URL into a deep link by adding a query parameter.\n\t *\n\t * e.g. `https://my-app.com/my-document?d=100.100.200.200.xyz123`\n\t *\n\t * If no URL is provided, it will use the current `window.location.href`.\n\t *\n\t * @example\n\t * ```ts\n\t * // create a deep link to the current page + viewport\n\t * navigator.clipboard.writeText(editor.createDeepLink())\n\t * ```\n\t *\n\t * You can link to a particular set of shapes by providing a `to` parameter.\n\t *\n\t * @example\n\t * ```ts\n\t * // create a deep link to the set of currently selected shapes\n\t * navigator.clipboard.writeText(editor.createDeepLink({\n\t * to: { type: 'selection', shapeIds: editor.getSelectedShapeIds() }\n\t * }))\n\t * ```\n\t *\n\t * The default query param is 'd'. You can override this by providing a `param` parameter.\n\t *\n\t * @example\n\t * ```ts\n\t * // Use `x` as the param name instead\n\t * editor.createDeepLink({ param: 'x' })\n\t * ```\n\t *\n\t * @param opts - Options for adding the state to the URL.\n\t * @returns the updated URL\n\t */\n\tcreateDeepLink(opts?: { url?: string | URL; param?: string; to?: TLDeepLink }): URL {\n\t\tconst url = new URL(opts?.url ?? window.location.href)\n\n\t\turl.searchParams.set(\n\t\t\topts?.param ?? 'd',\n\t\t\tcreateDeepLinkString(\n\t\t\t\topts?.to ?? {\n\t\t\t\t\ttype: 'viewport',\n\t\t\t\t\tpageId: this.options.maxPages === 1 ? undefined : this.getCurrentPageId(),\n\t\t\t\t\tbounds: this.getViewportPageBounds(),\n\t\t\t\t}\n\t\t\t)\n\t\t)\n\n\t\treturn url\n\t}\n\n\t/**\n\t * Register a listener for changes to a deep link for the current document.\n\t *\n\t * You'll typically want to use this indirectly via the {@link TldrawEditorBaseProps.deepLinks} prop on the `` component.\n\t *\n\t * By default this will update `window.location` in place, but you can provide a custom callback\n\t * to handle state changes on your own.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.registerDeepLinkListener({\n\t * onChange(url) {\n\t * window.history.replaceState({}, document.title, url.toString())\n\t * }\n\t * })\n\t * ```\n\t *\n\t * You can also provide a custom URL to update, in which case you must also provide `onChange`.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.registerDeepLinkListener({\n\t * getUrl: () => `https://my-app.com/my-document`,\n\t * onChange(url) {\n\t * setShareUrl(url.toString())\n\t * }\n\t * })\n\t * ```\n\t *\n\t * By default this will update with a debounce interval of 500ms, but you can provide a custom interval.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.registerDeepLinkListener({ debounceMs: 1000 })\n\t * ```\n\t * The default parameter name is `d`. You can override this by providing a `param` option.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.registerDeepLinkListener({ param: 'x' })\n\t * ```\n\t * @param opts - Options for setting up the listener.\n\t * @returns a function that will stop the listener.\n\t */\n\tregisterDeepLinkListener(opts?: TLDeepLinkOptions): () => void {\n\t\tif (opts?.getUrl && !opts?.onChange) {\n\t\t\tthrow Error(\n\t\t\t\t'[tldraw:urlStateSync] If you specify getUrl, you must also specify the onChange callback.'\n\t\t\t)\n\t\t}\n\n\t\tconst url$ = computed('url with state', () => {\n\t\t\tconst url = opts?.getUrl?.(this) ?? window.location.href\n\t\t\tconst urlWithState = this.createDeepLink({\n\t\t\t\tparam: opts?.param,\n\t\t\t\turl,\n\t\t\t\tto: opts?.getTarget?.(this),\n\t\t\t})\n\t\t\treturn urlWithState.toString()\n\t\t})\n\n\t\tconst announceChange =\n\t\t\topts?.onChange ??\n\t\t\t(() => {\n\t\t\t\tconst url = this.createDeepLink({\n\t\t\t\t\tparam: opts?.param,\n\t\t\t\t\tto: opts?.getTarget?.(this),\n\t\t\t\t})\n\n\t\t\t\twindow.history.replaceState({}, document.title, url.toString())\n\t\t\t})\n\n\t\tconst scheduleEffect = debounce((execute: () => void) => execute(), opts?.debounceMs ?? 500)\n\n\t\tconst unlisten = react(\n\t\t\t'update url on state change',\n\t\t\t() => announceChange(new URL(url$.get()), this),\n\t\t\t{ scheduleEffect }\n\t\t)\n\n\t\treturn () => {\n\t\t\tunlisten()\n\t\t\tscheduleEffect.cancel()\n\t\t}\n\t}\n\n\t/**\n\t * A manager for recording multiple click events.\n\t *\n\t * @internal\n\t */\n\tprotected _clickManager = new ClickManager(this)\n\n\t/**\n\t * Prevent a double click event from firing the next time the user clicks\n\t *\n\t * @public\n\t */\n\tcancelDoubleClick() {\n\t\tthis._clickManager.cancelDoubleClickTimeout()\n\t}\n\n\t/**\n\t * The previous cursor. Used for restoring the cursor after pan events.\n\t *\n\t * @internal\n\t */\n\tprivate _prevCursor: TLCursorType = 'default'\n\n\t/** @internal */\n\tprivate _shiftKeyTimeout = -1 as any\n\n\t/** @internal */\n\t@bind\n\t_setShiftKeyTimeout() {\n\t\tthis.inputs.shiftKey = false\n\t\tthis.dispatch({\n\t\t\ttype: 'keyboard',\n\t\t\tname: 'key_up',\n\t\t\tkey: 'Shift',\n\t\t\tshiftKey: this.inputs.shiftKey,\n\t\t\tctrlKey: this.inputs.ctrlKey,\n\t\t\taltKey: this.inputs.altKey,\n\t\t\tmetaKey: this.inputs.metaKey,\n\t\t\taccelKey: isAccelKey(this.inputs),\n\t\t\tcode: 'ShiftLeft',\n\t\t})\n\t}\n\n\t/** @internal */\n\tprivate _altKeyTimeout = -1 as any\n\n\t/** @internal */\n\t@bind\n\t_setAltKeyTimeout() {\n\t\tthis.inputs.altKey = false\n\t\tthis.dispatch({\n\t\t\ttype: 'keyboard',\n\t\t\tname: 'key_up',\n\t\t\tkey: 'Alt',\n\t\t\tshiftKey: this.inputs.shiftKey,\n\t\t\tctrlKey: this.inputs.ctrlKey,\n\t\t\taltKey: this.inputs.altKey,\n\t\t\tmetaKey: this.inputs.metaKey,\n\t\t\taccelKey: isAccelKey(this.inputs),\n\t\t\tcode: 'AltLeft',\n\t\t})\n\t}\n\n\t/** @internal */\n\tprivate _ctrlKeyTimeout = -1 as any\n\n\t/** @internal */\n\t@bind\n\t_setCtrlKeyTimeout() {\n\t\tthis.inputs.ctrlKey = false\n\t\tthis.dispatch({\n\t\t\ttype: 'keyboard',\n\t\t\tname: 'key_up',\n\t\t\tkey: 'Ctrl',\n\t\t\tshiftKey: this.inputs.shiftKey,\n\t\t\tctrlKey: this.inputs.ctrlKey,\n\t\t\taltKey: this.inputs.altKey,\n\t\t\tmetaKey: this.inputs.metaKey,\n\t\t\taccelKey: isAccelKey(this.inputs),\n\t\t\tcode: 'ControlLeft',\n\t\t})\n\t}\n\n\t/** @internal */\n\tprivate _metaKeyTimeout = -1 as any\n\n\t/** @internal */\n\t@bind\n\t_setMetaKeyTimeout() {\n\t\tthis.inputs.metaKey = false\n\t\tthis.dispatch({\n\t\t\ttype: 'keyboard',\n\t\t\tname: 'key_up',\n\t\t\tkey: 'Meta',\n\t\t\tshiftKey: this.inputs.shiftKey,\n\t\t\tctrlKey: this.inputs.ctrlKey,\n\t\t\taltKey: this.inputs.altKey,\n\t\t\tmetaKey: this.inputs.metaKey,\n\t\t\taccelKey: isAccelKey(this.inputs),\n\t\t\tcode: 'MetaLeft',\n\t\t})\n\t}\n\n\t/** @internal */\n\tprivate _restoreToolId = 'select'\n\n\t/** @internal */\n\tprivate _pinchStart = 1\n\n\t/** @internal */\n\tprivate _didPinch = false\n\n\t/** @internal */\n\tprivate _selectedShapeIdsAtPointerDown: TLShapeId[] = []\n\n\t/** @internal */\n\tprivate _longPressTimeout = -1 as any\n\n\t/** @internal */\n\tcapturedPointerId: number | null = null\n\n\t/** @internal */\n\tprivate readonly performanceTracker: PerformanceTracker\n\n\t/** @internal */\n\tprivate performanceTrackerTimeout = -1 as any\n\n\t/**\n\t * Dispatch an event to the editor.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.dispatch(myPointerEvent)\n\t * ```\n\t *\n\t * @param info - The event info.\n\t *\n\t * @public\n\t */\n\tdispatch(info: TLEventInfo) {\n\t\tthis._pendingEventsForNextTick.push(info)\n\t\tif (\n\t\t\t!(\n\t\t\t\t(info.type === 'pointer' && info.name === 'pointer_move') ||\n\t\t\t\tinfo.type === 'wheel' ||\n\t\t\t\tinfo.type === 'pinch'\n\t\t\t)\n\t\t) {\n\t\t\tthis._flushEventsForTick(0)\n\t\t}\n\t\treturn this\n\t}\n\n\tprivate _pendingEventsForNextTick: TLEventInfo[] = []\n\n\tprivate _flushEventsForTick(elapsed: number) {\n\t\tthis.run(() => {\n\t\t\tif (this._pendingEventsForNextTick.length > 0) {\n\t\t\t\tconst events = [...this._pendingEventsForNextTick]\n\t\t\t\tthis._pendingEventsForNextTick.length = 0\n\t\t\t\tfor (const info of events) {\n\t\t\t\t\tthis._flushEventForTick(info)\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (elapsed > 0) {\n\t\t\t\tthis.root.handleEvent({ type: 'misc', name: 'tick', elapsed })\n\t\t\t}\n\t\t\tthis.scribbles.tick(elapsed)\n\t\t})\n\t}\n\n\t_flushEventForTick(info: TLEventInfo) {\n\t\t// prevent us from spamming similar event errors if we're crashed.\n\t\t// todo: replace with new readonly mode?\n\t\tif (this.getCrashingError()) return this\n\n\t\tconst { inputs } = this\n\t\tconst { type } = info\n\n\t\tif (info.type === 'misc') {\n\t\t\t// stop panning if the interaction is cancelled or completed\n\t\t\tif (info.name === 'cancel' || info.name === 'complete') {\n\t\t\t\tthis.inputs.isDragging = false\n\n\t\t\t\tif (this.inputs.isPanning) {\n\t\t\t\t\tthis.inputs.isPanning = false\n\t\t\t\t\tthis.inputs.isSpacebarPanning = false\n\t\t\t\t\tthis.setCursor({ type: this._prevCursor, rotation: 0 })\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tthis.root.handleEvent(info)\n\t\t\treturn\n\t\t}\n\n\t\tif (info.shiftKey) {\n\t\t\tclearTimeout(this._shiftKeyTimeout)\n\t\t\tthis._shiftKeyTimeout = -1\n\t\t\tinputs.shiftKey = true\n\t\t} else if (!info.shiftKey && inputs.shiftKey && this._shiftKeyTimeout === -1) {\n\t\t\tthis._shiftKeyTimeout = this.timers.setTimeout(this._setShiftKeyTimeout, 150)\n\t\t}\n\n\t\tif (info.altKey) {\n\t\t\tclearTimeout(this._altKeyTimeout)\n\t\t\tthis._altKeyTimeout = -1\n\t\t\tinputs.altKey = true\n\t\t} else if (!info.altKey && inputs.altKey && this._altKeyTimeout === -1) {\n\t\t\tthis._altKeyTimeout = this.timers.setTimeout(this._setAltKeyTimeout, 150)\n\t\t}\n\n\t\tif (info.ctrlKey) {\n\t\t\tclearTimeout(this._ctrlKeyTimeout)\n\t\t\tthis._ctrlKeyTimeout = -1\n\t\t\tinputs.ctrlKey = true\n\t\t} else if (!info.ctrlKey && inputs.ctrlKey && this._ctrlKeyTimeout === -1) {\n\t\t\tthis._ctrlKeyTimeout = this.timers.setTimeout(this._setCtrlKeyTimeout, 150)\n\t\t}\n\n\t\tif (info.metaKey) {\n\t\t\tclearTimeout(this._metaKeyTimeout)\n\t\t\tthis._metaKeyTimeout = -1\n\t\t\tinputs.metaKey = true\n\t\t} else if (!info.metaKey && inputs.metaKey && this._metaKeyTimeout === -1) {\n\t\t\tthis._metaKeyTimeout = this.timers.setTimeout(this._setMetaKeyTimeout, 150)\n\t\t}\n\n\t\tconst { originPagePoint, currentPagePoint } = inputs\n\n\t\tif (!inputs.isPointing) {\n\t\t\tinputs.isDragging = false\n\t\t}\n\n\t\tconst instanceState = this.store.unsafeGetWithoutCapture(TLINSTANCE_ID)!\n\t\tconst pageState = this.store.get(this._getCurrentPageStateId())!\n\t\tconst cameraOptions = this._cameraOptions.__unsafe__getWithoutCapture()!\n\n\t\tswitch (type) {\n\t\t\tcase 'pinch': {\n\t\t\t\tif (cameraOptions.isLocked) return\n\t\t\t\tclearTimeout(this._longPressTimeout)\n\t\t\t\tthis._updateInputsFromEvent(info)\n\n\t\t\t\tswitch (info.name) {\n\t\t\t\t\tcase 'pinch_start': {\n\t\t\t\t\t\tif (inputs.isPinching) return\n\n\t\t\t\t\t\tif (!inputs.isEditing) {\n\t\t\t\t\t\t\tthis._pinchStart = this.getCamera().z\n\t\t\t\t\t\t\tif (!this._selectedShapeIdsAtPointerDown.length) {\n\t\t\t\t\t\t\t\tthis._selectedShapeIdsAtPointerDown = [...pageState.selectedShapeIds]\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tthis._didPinch = true\n\n\t\t\t\t\t\t\tinputs.isPinching = true\n\n\t\t\t\t\t\t\tthis.interrupt()\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\treturn // Stop here!\n\t\t\t\t\t}\n\t\t\t\t\tcase 'pinch': {\n\t\t\t\t\t\tif (!inputs.isPinching) return\n\n\t\t\t\t\t\tconst {\n\t\t\t\t\t\t\tpoint: { z = 1 },\n\t\t\t\t\t\t\tdelta: { x: dx, y: dy },\n\t\t\t\t\t\t} = info\n\n\t\t\t\t\t\t// The center of the pinch in screen space\n\t\t\t\t\t\tconst { x, y } = Vec.SubXY(\n\t\t\t\t\t\t\tinfo.point,\n\t\t\t\t\t\t\tinstanceState.screenBounds.x,\n\t\t\t\t\t\t\tinstanceState.screenBounds.y\n\t\t\t\t\t\t)\n\n\t\t\t\t\t\tthis.stopCameraAnimation()\n\t\t\t\t\t\tif (instanceState.followingUserId) {\n\t\t\t\t\t\t\tthis.stopFollowingUser()\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst { x: cx, y: cy, z: cz } = unsafe__withoutCapture(() => this.getCamera())\n\n\t\t\t\t\t\tconst { panSpeed, zoomSpeed } = cameraOptions\n\t\t\t\t\t\tthis._setCamera(\n\t\t\t\t\t\t\tnew Vec(\n\t\t\t\t\t\t\t\tcx + (dx * panSpeed) / cz - x / cz + x / (z * zoomSpeed),\n\t\t\t\t\t\t\t\tcy + (dy * panSpeed) / cz - y / cz + y / (z * zoomSpeed),\n\t\t\t\t\t\t\t\tz * zoomSpeed\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t{ immediate: true }\n\t\t\t\t\t\t)\n\n\t\t\t\t\t\treturn // Stop here!\n\t\t\t\t\t}\n\t\t\t\t\tcase 'pinch_end': {\n\t\t\t\t\t\tif (!inputs.isPinching) return this\n\n\t\t\t\t\t\t// Stop pinching\n\t\t\t\t\t\tinputs.isPinching = false\n\n\t\t\t\t\t\t// Stash and clear the shapes that were selected when the pinch started\n\t\t\t\t\t\tconst { _selectedShapeIdsAtPointerDown: shapesToReselect } = this\n\t\t\t\t\t\tthis.setSelectedShapes(this._selectedShapeIdsAtPointerDown)\n\t\t\t\t\t\tthis._selectedShapeIdsAtPointerDown = []\n\n\t\t\t\t\t\tif (this._didPinch) {\n\t\t\t\t\t\t\tthis._didPinch = false\n\t\t\t\t\t\t\tif (shapesToReselect.length > 0) {\n\t\t\t\t\t\t\t\tthis.once('tick', () => {\n\t\t\t\t\t\t\t\t\tif (!this._didPinch) {\n\t\t\t\t\t\t\t\t\t\t// Unless we've started pinching again...\n\t\t\t\t\t\t\t\t\t\t// Reselect the shapes that were selected when the pinch started\n\t\t\t\t\t\t\t\t\t\tthis.setSelectedShapes(shapesToReselect)\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\treturn // Stop here!\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tcase 'wheel': {\n\t\t\t\tif (cameraOptions.isLocked) return\n\n\t\t\t\tthis._updateInputsFromEvent(info)\n\n\t\t\t\tconst { panSpeed, zoomSpeed, wheelBehavior } = cameraOptions\n\n\t\t\t\tif (wheelBehavior !== 'none') {\n\t\t\t\t\t// Stop any camera animation\n\t\t\t\t\tthis.stopCameraAnimation()\n\t\t\t\t\t// Stop following any following user\n\t\t\t\t\tif (instanceState.followingUserId) {\n\t\t\t\t\t\tthis.stopFollowingUser()\n\t\t\t\t\t}\n\n\t\t\t\t\tconst { x: cx, y: cy, z: cz } = unsafe__withoutCapture(() => this.getCamera())\n\t\t\t\t\tconst { x: dx, y: dy, z: dz = 0 } = info.delta\n\n\t\t\t\t\tlet behavior = wheelBehavior\n\n\t\t\t\t\t// If the camera behavior is \"zoom\" and the ctrl key is pressed, then pan;\n\t\t\t\t\t// If the camera behavior is \"pan\" and the ctrl key is not pressed, then zoom\n\t\t\t\t\tif (inputs.ctrlKey) behavior = wheelBehavior === 'pan' ? 'zoom' : 'pan'\n\n\t\t\t\t\tswitch (behavior) {\n\t\t\t\t\t\tcase 'zoom': {\n\t\t\t\t\t\t\t// Zoom in on current screen point using the wheel delta\n\t\t\t\t\t\t\tconst { x, y } = this.inputs.currentScreenPoint\n\t\t\t\t\t\t\tlet delta = dz\n\n\t\t\t\t\t\t\t// If we're forcing zoom, then we need to do the wheel normalization math here\n\t\t\t\t\t\t\tif (wheelBehavior === 'zoom') {\n\t\t\t\t\t\t\t\tif (Math.abs(dy) > 10) {\n\t\t\t\t\t\t\t\t\tdelta = (10 * Math.sign(dy)) / 100\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tdelta = dy / 100\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tconst zoom = cz + (delta ?? 0) * zoomSpeed * cz\n\t\t\t\t\t\t\tthis._setCamera(\n\t\t\t\t\t\t\t\tnew Vec(\n\t\t\t\t\t\t\t\t\tcx + (x / zoom - x) - (x / cz - x),\n\t\t\t\t\t\t\t\t\tcy + (y / zoom - y) - (y / cz - y),\n\t\t\t\t\t\t\t\t\tzoom\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t{ immediate: true }\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\tthis.maybeTrackPerformance('Zooming')\n\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcase 'pan': {\n\t\t\t\t\t\t\t// Pan the camera based on the wheel delta\n\t\t\t\t\t\t\tthis._setCamera(new Vec(cx + (dx * panSpeed) / cz, cy + (dy * panSpeed) / cz, cz), {\n\t\t\t\t\t\t\t\timmediate: true,\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\tthis.maybeTrackPerformance('Panning')\n\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'pointer': {\n\t\t\t\t// Ignore pointer events while we're pinching\n\t\t\t\tif (inputs.isPinching) return\n\n\t\t\t\tthis._updateInputsFromEvent(info)\n\t\t\t\tconst { isPen } = info\n\t\t\t\tconst { isPenMode } = instanceState\n\n\t\t\t\tswitch (info.name) {\n\t\t\t\t\tcase 'pointer_down': {\n\t\t\t\t\t\t// If we're in pen mode and the input is not a pen type, then stop here\n\t\t\t\t\t\tif (isPenMode && !isPen) return\n\n\t\t\t\t\t\tif (!this.inputs.isPanning) {\n\t\t\t\t\t\t\t// Start a long press timeout\n\t\t\t\t\t\t\tthis._longPressTimeout = this.timers.setTimeout(() => {\n\t\t\t\t\t\t\t\tthis.dispatch({\n\t\t\t\t\t\t\t\t\t...info,\n\t\t\t\t\t\t\t\t\tpoint: this.inputs.currentScreenPoint,\n\t\t\t\t\t\t\t\t\tname: 'long_press',\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t}, this.options.longPressDurationMs)\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Save the selected ids at pointer down\n\t\t\t\t\t\tthis._selectedShapeIdsAtPointerDown = this.getSelectedShapeIds()\n\n\t\t\t\t\t\t// Firefox bug fix...\n\t\t\t\t\t\t// If it's a left-mouse-click, we store the pointer id for later user\n\t\t\t\t\t\tif (info.button === LEFT_MOUSE_BUTTON) this.capturedPointerId = info.pointerId\n\n\t\t\t\t\t\t// Add the button from the buttons set\n\t\t\t\t\t\tinputs.buttons.add(info.button)\n\n\t\t\t\t\t\t// Start pointing and stop dragging\n\t\t\t\t\t\tinputs.isPointing = true\n\t\t\t\t\t\tinputs.isDragging = false\n\n\t\t\t\t\t\t// If pen mode is off but we're not already in pen mode, turn that on\n\t\t\t\t\t\tif (!isPenMode && isPen) this.updateInstanceState({ isPenMode: true })\n\n\t\t\t\t\t\t// On devices with erasers (like the Surface Pen or Wacom Pen), button 5 is the eraser\n\t\t\t\t\t\tif (info.button === STYLUS_ERASER_BUTTON) {\n\t\t\t\t\t\t\tthis._restoreToolId = this.getCurrentToolId()\n\t\t\t\t\t\t\tthis.complete()\n\t\t\t\t\t\t\tthis.setCurrentTool('eraser')\n\t\t\t\t\t\t} else if (info.button === MIDDLE_MOUSE_BUTTON) {\n\t\t\t\t\t\t\t// Middle mouse pan activates panning unless we're already panning (with spacebar)\n\t\t\t\t\t\t\tif (!this.inputs.isPanning) {\n\t\t\t\t\t\t\t\tthis._prevCursor = this.getInstanceState().cursor.type\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tthis.inputs.isPanning = true\n\t\t\t\t\t\t\tclearTimeout(this._longPressTimeout)\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// We might be panning because we did a middle mouse click, or because we're holding spacebar and started a regular click\n\t\t\t\t\t\t// Also stop here, we don't want the state chart to receive the event\n\t\t\t\t\t\tif (this.inputs.isPanning) {\n\t\t\t\t\t\t\tthis.stopCameraAnimation()\n\t\t\t\t\t\t\tthis.setCursor({ type: 'grabbing', rotation: 0 })\n\t\t\t\t\t\t\treturn this\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t\tcase 'pointer_move': {\n\t\t\t\t\t\t// If the user is in pen mode, but the pointer is not a pen, stop here.\n\t\t\t\t\t\tif (!isPen && isPenMode) return\n\n\t\t\t\t\t\tconst { x: cx, y: cy, z: cz } = unsafe__withoutCapture(() => this.getCamera())\n\n\t\t\t\t\t\t// If we've started panning, then clear any long press timeout\n\t\t\t\t\t\tif (this.inputs.isPanning && this.inputs.isPointing) {\n\t\t\t\t\t\t\t// Handle spacebar / middle mouse button panning\n\t\t\t\t\t\t\tconst { currentScreenPoint, previousScreenPoint } = this.inputs\n\t\t\t\t\t\t\tconst { panSpeed } = cameraOptions\n\t\t\t\t\t\t\tconst offset = Vec.Sub(currentScreenPoint, previousScreenPoint)\n\t\t\t\t\t\t\tthis.setCamera(\n\t\t\t\t\t\t\t\tnew Vec(cx + (offset.x * panSpeed) / cz, cy + (offset.y * panSpeed) / cz, cz),\n\t\t\t\t\t\t\t\t{ immediate: true }\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\tthis.maybeTrackPerformance('Panning')\n\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\tinputs.isPointing &&\n\t\t\t\t\t\t\t!inputs.isDragging &&\n\t\t\t\t\t\t\tVec.Dist2(originPagePoint, currentPagePoint) * this.getZoomLevel() >\n\t\t\t\t\t\t\t\t(instanceState.isCoarsePointer\n\t\t\t\t\t\t\t\t\t? this.options.coarseDragDistanceSquared\n\t\t\t\t\t\t\t\t\t: this.options.dragDistanceSquared) /\n\t\t\t\t\t\t\t\t\tcz\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t// Start dragging\n\t\t\t\t\t\t\tinputs.isDragging = true\n\t\t\t\t\t\t\tclearTimeout(this._longPressTimeout)\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t\tcase 'pointer_up': {\n\t\t\t\t\t\t// Stop dragging / pointing\n\t\t\t\t\t\tinputs.isDragging = false\n\t\t\t\t\t\tinputs.isPointing = false\n\t\t\t\t\t\tclearTimeout(this._longPressTimeout)\n\n\t\t\t\t\t\t// Remove the button from the buttons set\n\t\t\t\t\t\tinputs.buttons.delete(info.button)\n\n\t\t\t\t\t\t// If we're in pen mode and we're not using a pen, stop here\n\t\t\t\t\t\tif (instanceState.isPenMode && !isPen) return\n\n\t\t\t\t\t\t// Firefox bug fix...\n\t\t\t\t\t\t// If it's the same pointer that we stored earlier...\n\t\t\t\t\t\t// ... then it's probably still a left-mouse-click!\n\t\t\t\t\t\tif (this.capturedPointerId === info.pointerId) {\n\t\t\t\t\t\t\tthis.capturedPointerId = null\n\t\t\t\t\t\t\tinfo.button = 0\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (inputs.isPanning) {\n\t\t\t\t\t\t\tif (!inputs.keys.has('Space')) {\n\t\t\t\t\t\t\t\tinputs.isPanning = false\n\t\t\t\t\t\t\t\tinputs.isSpacebarPanning = false\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tconst slideDirection = this.inputs.pointerVelocity\n\t\t\t\t\t\t\tconst slideSpeed = Math.min(2, slideDirection.len())\n\n\t\t\t\t\t\t\tswitch (info.button) {\n\t\t\t\t\t\t\t\tcase LEFT_MOUSE_BUTTON: {\n\t\t\t\t\t\t\t\t\tthis.setCursor({ type: 'grab', rotation: 0 })\n\t\t\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tcase MIDDLE_MOUSE_BUTTON: {\n\t\t\t\t\t\t\t\t\tif (this.inputs.keys.has(' ')) {\n\t\t\t\t\t\t\t\t\t\tthis.setCursor({ type: 'grab', rotation: 0 })\n\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\tthis.setCursor({ type: this._prevCursor, rotation: 0 })\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif (slideSpeed > 0) {\n\t\t\t\t\t\t\t\tthis.slideCamera({ speed: slideSpeed, direction: slideDirection })\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tif (info.button === STYLUS_ERASER_BUTTON) {\n\t\t\t\t\t\t\t\t// If we were erasing with a stylus button, restore the tool we were using before we started erasing\n\t\t\t\t\t\t\t\tthis.complete()\n\t\t\t\t\t\t\t\tthis.setCurrentTool(this._restoreToolId)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'keyboard': {\n\t\t\t\t// please, please\n\t\t\t\tif (info.key === 'ShiftRight') info.key = 'ShiftLeft'\n\t\t\t\tif (info.key === 'AltRight') info.key = 'AltLeft'\n\t\t\t\tif (info.code === 'ControlRight') info.code = 'ControlLeft'\n\t\t\t\tif (info.code === 'MetaRight') info.code = 'MetaLeft'\n\n\t\t\t\tswitch (info.name) {\n\t\t\t\t\tcase 'key_down': {\n\t\t\t\t\t\t// Add the key from the keys set\n\t\t\t\t\t\tinputs.keys.add(info.code)\n\n\t\t\t\t\t\t// If the space key is pressed (but meta / control isn't!) activate panning\n\t\t\t\t\t\tif (info.code === 'Space' && !info.ctrlKey) {\n\t\t\t\t\t\t\tif (!this.inputs.isPanning) {\n\t\t\t\t\t\t\t\tthis._prevCursor = instanceState.cursor.type\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tthis.inputs.isPanning = true\n\t\t\t\t\t\t\tthis.inputs.isSpacebarPanning = true\n\t\t\t\t\t\t\tclearTimeout(this._longPressTimeout)\n\t\t\t\t\t\t\tthis.setCursor({ type: this.inputs.isPointing ? 'grabbing' : 'grab', rotation: 0 })\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (this.inputs.isSpacebarPanning) {\n\t\t\t\t\t\t\tlet offset: Vec | undefined\n\t\t\t\t\t\t\tswitch (info.code) {\n\t\t\t\t\t\t\t\tcase 'ArrowUp': {\n\t\t\t\t\t\t\t\t\toffset = new Vec(0, -1)\n\t\t\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tcase 'ArrowRight': {\n\t\t\t\t\t\t\t\t\toffset = new Vec(1, 0)\n\t\t\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tcase 'ArrowDown': {\n\t\t\t\t\t\t\t\t\toffset = new Vec(0, 1)\n\t\t\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tcase 'ArrowLeft': {\n\t\t\t\t\t\t\t\t\toffset = new Vec(-1, 0)\n\t\t\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif (offset) {\n\t\t\t\t\t\t\t\tconst bounds = this.getViewportPageBounds()\n\t\t\t\t\t\t\t\tconst next = bounds.clone().translate(offset.mulV({ x: bounds.w, y: bounds.h }))\n\t\t\t\t\t\t\t\tthis._animateToViewport(next, { animation: { duration: 320 } })\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t\tcase 'key_up': {\n\t\t\t\t\t\t// Remove the key from the keys set\n\t\t\t\t\t\tinputs.keys.delete(info.code)\n\n\t\t\t\t\t\t// If we've lifted the space key,\n\t\t\t\t\t\tif (info.code === 'Space') {\n\t\t\t\t\t\t\tif (this.inputs.buttons.has(MIDDLE_MOUSE_BUTTON)) {\n\t\t\t\t\t\t\t\t// If we're still middle dragging, continue panning\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t// otherwise, stop panning\n\t\t\t\t\t\t\t\tthis.inputs.isPanning = false\n\t\t\t\t\t\t\t\tthis.inputs.isSpacebarPanning = false\n\t\t\t\t\t\t\t\tthis.setCursor({ type: this._prevCursor, rotation: 0 })\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t\tcase 'key_repeat': {\n\t\t\t\t\t\t// noop\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\n\t\t// Correct the info name for right / middle clicks\n\t\tif (info.type === 'pointer') {\n\t\t\tif (info.button === MIDDLE_MOUSE_BUTTON) {\n\t\t\t\tinfo.name = 'middle_click'\n\t\t\t} else if (info.button === RIGHT_MOUSE_BUTTON) {\n\t\t\t\tinfo.name = 'right_click'\n\t\t\t}\n\n\t\t\t// If a left click pointer event, send the event to the click manager.\n\t\t\tconst { isPenMode } = this.store.unsafeGetWithoutCapture(TLINSTANCE_ID)!\n\t\t\tif (info.isPen === isPenMode) {\n\t\t\t\t// The click manager may return a new event, i.e. a double click event\n\t\t\t\t// depending on the event coming in and its own state. If the event has\n\t\t\t\t// changed then hand both events to the statechart\n\t\t\t\tconst clickInfo = this._clickManager.handlePointerEvent(info)\n\t\t\t\tif (info.name !== clickInfo.name) {\n\t\t\t\t\tthis.root.handleEvent(info)\n\t\t\t\t\tthis.emit('event', info)\n\t\t\t\t\tthis.root.handleEvent(clickInfo)\n\t\t\t\t\tthis.emit('event', clickInfo)\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Send the event to the statechart. It will be handled by all\n\t\t// active states, starting at the root.\n\t\tthis.root.handleEvent(info)\n\t\tthis.emit('event', info)\n\n\t\t// close open menus at the very end on pointer down! after everything else! \u03C3\u03C5\u03BD\u03C4\u03B5\u03BB\u03B5\u03AF\u03B1\u03C2 \u03C4\u03BF\u1FE6 \u03BA\u03CE\u03B4\u03B9\u03BA\u03B1!!\n\t\tif (info.type === 'pointer' && info.name === 'pointer_down') {\n\t\t\tthis.menus.clearOpenMenus()\n\t\t}\n\n\t\treturn this\n\t}\n\n\t/** @internal */\n\tprivate maybeTrackPerformance(name: string) {\n\t\tif (debugFlags.measurePerformance.get()) {\n\t\t\tif (this.performanceTracker.isStarted()) {\n\t\t\t\tclearTimeout(this.performanceTrackerTimeout)\n\t\t\t} else {\n\t\t\t\tthis.performanceTracker.start(name)\n\t\t\t}\n\t\t\tthis.performanceTrackerTimeout = this.timers.setTimeout(() => {\n\t\t\t\tthis.performanceTracker.stop()\n\t\t\t}, 50)\n\t\t}\n\t}\n}\n\nfunction alertMaxShapes(editor: Editor, pageId = editor.getCurrentPageId()) {\n\tconst name = editor.getPage(pageId)!.name\n\teditor.emit('max-shapes', { name, pageId, count: editor.options.maxShapesPerPage })\n}\n\nfunction applyPartialToRecordWithProps<\n\tT extends UnknownRecord & { type: string; props: object; meta: object },\n>(prev: T, partial?: Partial & { props?: Partial }): T {\n\tif (!partial) return prev\n\tlet next = null as null | T\n\tconst entries = Object.entries(partial)\n\tfor (let i = 0, n = entries.length; i < n; i++) {\n\t\tconst [k, v] = entries[i]\n\t\tif (v === undefined) continue\n\n\t\t// Is the key a special key? We don't update those\n\t\tif (k === 'id' || k === 'type' || k === 'typeName') continue\n\n\t\t// Is the value the same as it was before?\n\t\tif (v === (prev as any)[k]) continue\n\n\t\t// There's a new value, so create the new shape if we haven't already (should we be cloning this?)\n\t\tif (!next) next = { ...prev }\n\n\t\t// for props / meta properties, we support updates with partials of this object\n\t\tif (k === 'props' || k === 'meta') {\n\t\t\tnext[k] = { ...prev[k] } as JsonObject\n\t\t\tfor (const [nextKey, nextValue] of Object.entries(v as object)) {\n\t\t\t\tif (nextValue !== undefined) {\n\t\t\t\t\t;(next[k] as JsonObject)[nextKey] = nextValue\n\t\t\t\t}\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\n\t\t// base property\n\t\t;(next as any)[k] = v\n\t}\n\tif (!next) return prev\n\treturn next\n}\n\nfunction pushShapeWithDescendants(editor: Editor, id: TLShapeId, result: TLShape[]): void {\n\tconst shape = editor.getShape(id)\n\tif (!shape) return\n\tresult.push(shape)\n\tconst childIds = editor.getSortedChildIdsForParent(id)\n\tfor (let i = 0, n = childIds.length; i < n; i++) {\n\t\tpushShapeWithDescendants(editor, childIds[i], result)\n\t}\n}\n\n/**\n * Run `callback` in a world where all bindings from the shapes in `shapeIds` to shapes not in\n * `shapeIds` are removed. This is useful when you want to duplicate/copy shapes without worrying\n * about bindings that might be pointing to shapes that are not being duplicated.\n *\n * The callback is given the set of bindings that should be maintained.\n */\nfunction withIsolatedShapes(\n\teditor: Editor,\n\tshapeIds: Set,\n\tcallback: (bindingsWithBoth: Set) => T\n): T {\n\tlet result!: Result\n\n\teditor.run(\n\t\t() => {\n\t\t\tconst changes = editor.store.extractingChanges(() => {\n\t\t\t\tconst bindingsWithBoth = new Set()\n\t\t\t\tconst bindingsToRemove = new Set()\n\n\t\t\t\tfor (const shapeId of shapeIds) {\n\t\t\t\t\tconst shape = editor.getShape(shapeId)\n\t\t\t\t\tif (!shape) continue\n\n\t\t\t\t\tfor (const binding of editor.getBindingsInvolvingShape(shapeId)) {\n\t\t\t\t\t\tconst hasFrom = shapeIds.has(binding.fromId)\n\t\t\t\t\t\tconst hasTo = shapeIds.has(binding.toId)\n\t\t\t\t\t\tif (hasFrom && hasTo) {\n\t\t\t\t\t\t\tbindingsWithBoth.add(binding.id)\n\t\t\t\t\t\t\tcontinue\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (!hasFrom || !hasTo) {\n\t\t\t\t\t\t\tbindingsToRemove.add(binding.id)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\teditor.deleteBindings([...bindingsToRemove], { isolateShapes: true })\n\n\t\t\t\ttry {\n\t\t\t\t\tresult = Result.ok(callback(bindingsWithBoth))\n\t\t\t\t} catch (error) {\n\t\t\t\t\tresult = Result.err(error)\n\t\t\t\t}\n\t\t\t})\n\n\t\t\teditor.store.applyDiff(reverseRecordsDiff(changes))\n\t\t},\n\t\t{ history: 'ignore' }\n\t)\n\n\tif (result.ok) {\n\t\treturn result.value\n\t} else {\n\t\tthrow result.error\n\t}\n}\n\nfunction getCameraFitXFitY(editor: Editor, cameraOptions: TLCameraOptions) {\n\tif (!cameraOptions.constraints) throw Error('Should have constraints here')\n\tconst {\n\t\tpadding: { x: px, y: py },\n\t} = cameraOptions.constraints\n\tconst vsb = editor.getViewportScreenBounds()\n\tconst bounds = Box.From(cameraOptions.constraints.bounds)\n\tconst zx = (vsb.w - px * 2) / bounds.w\n\tconst zy = (vsb.h - py * 2) / bounds.h\n\treturn { zx, zy }\n}\n"], +- "mappings": "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", ++ "sourcesContent": ["import { EMPTY_ARRAY, atom, computed, react, transact, unsafe__withoutCapture } from '@tldraw/state'\nimport {\n\tComputedCache,\n\tRecordType,\n\tStoreSideEffects,\n\tStoreSnapshot,\n\tUnknownRecord,\n\treverseRecordsDiff,\n} from '@tldraw/store'\nimport {\n\tCameraRecordType,\n\tInstancePageStateRecordType,\n\tPageRecordType,\n\tStyleProp,\n\tStylePropValue,\n\tTLArrowShape,\n\tTLAsset,\n\tTLAssetId,\n\tTLAssetPartial,\n\tTLBinding,\n\tTLBindingCreate,\n\tTLBindingId,\n\tTLBindingUpdate,\n\tTLCamera,\n\tTLCursor,\n\tTLCursorType,\n\tTLDOCUMENT_ID,\n\tTLDocument,\n\tTLFrameShape,\n\tTLGeoShape,\n\tTLGroupShape,\n\tTLHandle,\n\tTLINSTANCE_ID,\n\tTLImageAsset,\n\tTLInstance,\n\tTLInstancePageState,\n\tTLPOINTER_ID,\n\tTLPage,\n\tTLPageId,\n\tTLParentId,\n\tTLRecord,\n\tTLShape,\n\tTLShapeId,\n\tTLShapePartial,\n\tTLStore,\n\tTLStoreSnapshot,\n\tTLUnknownBinding,\n\tTLUnknownShape,\n\tTLVideoAsset,\n\tcreateBindingId,\n\tcreateShapeId,\n\tgetShapePropKeysByStyle,\n\tisPageId,\n\tisShapeId,\n} from '@tldraw/tlschema'\nimport {\n\tFileHelpers,\n\tIndexKey,\n\tJsonObject,\n\tPerformanceTracker,\n\tResult,\n\tannotateError,\n\tassert,\n\tassertExists,\n\tbind,\n\tcompact,\n\tdebounce,\n\tdedupe,\n\texhaustiveSwitchError,\n\tfetch,\n\tgetIndexAbove,\n\tgetIndexBetween,\n\tgetIndices,\n\tgetIndicesAbove,\n\tgetIndicesBetween,\n\tgetOwnProperty,\n\thasOwnProperty,\n\tlast,\n\tlerp,\n\tsortById,\n\tsortByIndex,\n\tstructuredClone,\n\tuniqueId,\n} from '@tldraw/utils'\nimport EventEmitter from 'eventemitter3'\nimport {\n\tTLEditorSnapshot,\n\tTLLoadSnapshotOptions,\n\tgetSnapshot,\n\tloadSnapshot,\n} from '../config/TLEditorSnapshot'\nimport { TLUser, createTLUser } from '../config/createTLUser'\nimport { TLAnyBindingUtilConstructor, checkBindings } from '../config/defaultBindings'\nimport { TLAnyShapeUtilConstructor, checkShapesAndAddCore } from '../config/defaultShapes'\nimport {\n\tDEFAULT_ANIMATION_OPTIONS,\n\tDEFAULT_CAMERA_OPTIONS,\n\tINTERNAL_POINTER_IDS,\n\tLEFT_MOUSE_BUTTON,\n\tMIDDLE_MOUSE_BUTTON,\n\tRIGHT_MOUSE_BUTTON,\n\tSTYLUS_ERASER_BUTTON,\n\tZOOM_TO_FIT_PADDING,\n} from '../constants'\nimport { exportToSvg } from '../exports/exportToSvg'\nimport { tlenv } from '../globals/environment'\nimport { tlmenus } from '../globals/menus'\nimport { tltime } from '../globals/time'\nimport { TldrawOptions, defaultTldrawOptions } from '../options'\nimport { Box, BoxLike } from '../primitives/Box'\nimport { Mat, MatLike } from '../primitives/Mat'\nimport { Vec, VecLike } from '../primitives/Vec'\nimport { EASINGS } from '../primitives/easings'\nimport { Geometry2d } from '../primitives/geometry/Geometry2d'\nimport { Group2d } from '../primitives/geometry/Group2d'\nimport { intersectPolygonPolygon } from '../primitives/intersect'\nimport { PI2, approximately, areAnglesCompatible, clamp, pointInPolygon } from '../primitives/utils'\nimport { ReadonlySharedStyleMap, SharedStyle, SharedStyleMap } from '../utils/SharedStylesMap'\nimport { dataUrlToFile } from '../utils/assets'\nimport { debugFlags } from '../utils/debug-flags'\nimport {\n\tTLDeepLink,\n\tTLDeepLinkOptions,\n\tcreateDeepLinkString,\n\tparseDeepLinkString,\n} from '../utils/deepLinks'\nimport { getIncrementedName } from '../utils/getIncrementedName'\nimport { isAccelKey } from '../utils/keyboard'\nimport { getReorderingShapesChanges } from '../utils/reorderShapes'\nimport { applyRotationToSnapshotShapes, getRotationSnapshot } from '../utils/rotation'\nimport { BindingOnDeleteOptions, BindingUtil } from './bindings/BindingUtil'\nimport { bindingsIndex } from './derivations/bindingsIndex'\nimport { notVisibleShapes } from './derivations/notVisibleShapes'\nimport { parentsToChildren } from './derivations/parentsToChildren'\nimport { deriveShapeIdsInCurrentPage } from './derivations/shapeIdsInCurrentPage'\nimport { ClickManager } from './managers/ClickManager'\nimport { EdgeScrollManager } from './managers/EdgeScrollManager'\nimport { FocusManager } from './managers/FocusManager'\nimport { HistoryManager } from './managers/HistoryManager'\nimport { ScribbleManager } from './managers/ScribbleManager'\nimport { SnapManager } from './managers/SnapManager/SnapManager'\nimport { TextManager } from './managers/TextManager'\nimport { TickManager } from './managers/TickManager'\nimport { UserPreferencesManager } from './managers/UserPreferencesManager'\nimport { ShapeUtil, TLResizeMode } from './shapes/ShapeUtil'\nimport { RootState } from './tools/RootState'\nimport { StateNode, TLStateNodeConstructor } from './tools/StateNode'\nimport { TLContent } from './types/clipboard-types'\nimport { TLEventMap } from './types/emit-types'\nimport {\n\tTLEventInfo,\n\tTLPinchEventInfo,\n\tTLPointerEventInfo,\n\tTLWheelEventInfo,\n} from './types/event-types'\nimport { TLExternalAssetContent, TLExternalContent } from './types/external-content'\nimport { TLHistoryBatchOptions } from './types/history-types'\nimport {\n\tOptionalKeys,\n\tRequiredKeys,\n\tTLCameraMoveOptions,\n\tTLCameraOptions,\n\tTLImageExportOptions,\n} from './types/misc-types'\nimport { TLResizeHandle } from './types/selection-types'\n\n/** @public */\nexport type TLResizeShapeOptions = Partial<{\n\tinitialBounds: Box\n\tscaleOrigin: VecLike\n\tscaleAxisRotation: number\n\tinitialShape: TLShape\n\tinitialPageTransform: MatLike\n\tdragHandle: TLResizeHandle\n\tisAspectRatioLocked: boolean\n\tmode: TLResizeMode\n\tskipStartAndEndCallbacks: boolean\n}>\n\n/** @public */\nexport interface TLEditorOptions {\n\t/**\n\t * The Store instance to use for keeping the app's data. This may be prepopulated, e.g. by loading\n\t * from a server or database.\n\t */\n\tstore: TLStore\n\t/**\n\t * An array of shapes to use in the editor. These will be used to create and manage shapes in the editor.\n\t */\n\tshapeUtils: readonly TLAnyShapeUtilConstructor[]\n\t/**\n\t * An array of bindings to use in the editor. These will be used to create and manage bindings in the editor.\n\t */\n\tbindingUtils: readonly TLAnyBindingUtilConstructor[]\n\t/**\n\t * An array of tools to use in the editor. These will be used to handle events and manage user interactions in the editor.\n\t */\n\ttools: readonly TLStateNodeConstructor[]\n\t/**\n\t * Should return a containing html element which has all the styles applied to the editor. If not\n\t * given, the body element will be used.\n\t */\n\tgetContainer(): HTMLElement\n\t/**\n\t * A user defined externally to replace the default user.\n\t */\n\tuser?: TLUser\n\t/**\n\t * The editor's initial active tool (or other state node id).\n\t */\n\tinitialState?: string\n\t/**\n\t * Whether to automatically focus the editor when it mounts.\n\t */\n\tautoFocus?: boolean\n\t/**\n\t * Whether to infer dark mode from the user's system preferences. Defaults to false.\n\t */\n\tinferDarkMode?: boolean\n\t/**\n\t * Options for the editor's camera.\n\t */\n\tcameraOptions?: Partial\n\toptions?: Partial\n\tlicenseKey?: string\n\t/**\n\t * A predicate that should return true if the given shape should be hidden.\n\t * @param shape - The shape to check.\n\t * @param editor - The editor instance.\n\t */\n\tisShapeHidden?(shape: TLShape, editor: Editor): boolean\n}\n\n/**\n * Options for {@link Editor.(run:1)}.\n * @public\n */\nexport interface TLEditorRunOptions extends TLHistoryBatchOptions {\n\tignoreShapeLock?: boolean\n}\n\n/** @public */\nexport interface TLRenderingShape {\n\tid: TLShapeId\n\tshape: TLShape\n\tutil: ShapeUtil\n\tindex: number\n\tbackgroundIndex: number\n\topacity: number\n}\n\n/** @public */\nexport class Editor extends EventEmitter {\n\tconstructor({\n\t\tstore,\n\t\tuser,\n\t\tshapeUtils,\n\t\tbindingUtils,\n\t\ttools,\n\t\tgetContainer,\n\t\tcameraOptions,\n\t\tinitialState,\n\t\tautoFocus,\n\t\tinferDarkMode,\n\t\toptions,\n\t\tisShapeHidden,\n\t}: TLEditorOptions) {\n\t\tsuper()\n\n\t\tthis._isShapeHiddenPredicate = isShapeHidden\n\n\t\tthis.options = { ...defaultTldrawOptions, ...options }\n\n\t\tthis.store = store\n\t\tthis.disposables.add(this.store.dispose.bind(this.store))\n\t\tthis.history = new HistoryManager({\n\t\t\tstore,\n\t\t\tannotateError: (error) => {\n\t\t\t\tthis.annotateError(error, { origin: 'history.batch', willCrashApp: true })\n\t\t\t\tthis.crash(error)\n\t\t\t},\n\t\t})\n\n\t\tthis.snaps = new SnapManager(this)\n\n\t\tthis.disposables.add(this.timers.dispose)\n\n\t\tthis._cameraOptions.set({ ...DEFAULT_CAMERA_OPTIONS, ...cameraOptions })\n\n\t\tthis.user = new UserPreferencesManager(user ?? createTLUser(), inferDarkMode ?? false)\n\n\t\tthis.getContainer = getContainer\n\n\t\tthis.textMeasure = new TextManager(this)\n\t\tthis._tickManager = new TickManager(this)\n\n\t\tclass NewRoot extends RootState {\n\t\t\tstatic override initial = initialState ?? ''\n\t\t}\n\n\t\tthis.root = new NewRoot(this)\n\t\tthis.root.children = {}\n\n\t\tconst allShapeUtils = checkShapesAndAddCore(shapeUtils)\n\n\t\tconst _shapeUtils = {} as Record>\n\t\tconst _styleProps = {} as Record, string>>\n\t\tconst allStylesById = new Map>()\n\n\t\tfor (const Util of allShapeUtils) {\n\t\t\tconst util = new Util(this)\n\t\t\t_shapeUtils[Util.type] = util\n\n\t\t\tconst propKeysByStyle = getShapePropKeysByStyle(Util.props ?? {})\n\t\t\t_styleProps[Util.type] = propKeysByStyle\n\n\t\t\tfor (const style of propKeysByStyle.keys()) {\n\t\t\t\tif (!allStylesById.has(style.id)) {\n\t\t\t\t\tallStylesById.set(style.id, style)\n\t\t\t\t} else if (allStylesById.get(style.id) !== style) {\n\t\t\t\t\tthrow Error(\n\t\t\t\t\t\t`Multiple style props with id \"${style.id}\" in use. Style prop IDs must be unique.`\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tthis.shapeUtils = _shapeUtils\n\t\tthis.styleProps = _styleProps\n\n\t\tconst allBindingUtils = checkBindings(bindingUtils)\n\t\tconst _bindingUtils = {} as Record>\n\t\tfor (const Util of allBindingUtils) {\n\t\t\tconst util = new Util(this)\n\t\t\t_bindingUtils[Util.type] = util\n\t\t}\n\t\tthis.bindingUtils = _bindingUtils\n\n\t\t// Tools.\n\t\t// Accept tools from constructor parameters which may not conflict with the root note's default or\n\t\t// \"baked in\" tools, select and zoom.\n\t\tfor (const Tool of [...tools]) {\n\t\t\tif (hasOwnProperty(this.root.children!, Tool.id)) {\n\t\t\t\tthrow Error(`Can't override tool with id \"${Tool.id}\"`)\n\t\t\t}\n\t\t\tthis.root.children![Tool.id] = new Tool(this, this.root)\n\t\t}\n\n\t\tthis.scribbles = new ScribbleManager(this)\n\n\t\t// Cleanup\n\n\t\tconst cleanupInstancePageState = (\n\t\t\tprevPageState: TLInstancePageState,\n\t\t\tshapesNoLongerInPage: Set\n\t\t) => {\n\t\t\tlet nextPageState = null as null | TLInstancePageState\n\n\t\t\tconst selectedShapeIds = prevPageState.selectedShapeIds.filter(\n\t\t\t\t(id) => !shapesNoLongerInPage.has(id)\n\t\t\t)\n\t\t\tif (selectedShapeIds.length !== prevPageState.selectedShapeIds.length) {\n\t\t\t\tif (!nextPageState) nextPageState = { ...prevPageState }\n\t\t\t\tnextPageState.selectedShapeIds = selectedShapeIds\n\t\t\t}\n\n\t\t\tconst erasingShapeIds = prevPageState.erasingShapeIds.filter(\n\t\t\t\t(id) => !shapesNoLongerInPage.has(id)\n\t\t\t)\n\t\t\tif (erasingShapeIds.length !== prevPageState.erasingShapeIds.length) {\n\t\t\t\tif (!nextPageState) nextPageState = { ...prevPageState }\n\t\t\t\tnextPageState.erasingShapeIds = erasingShapeIds\n\t\t\t}\n\n\t\t\tif (prevPageState.hoveredShapeId && shapesNoLongerInPage.has(prevPageState.hoveredShapeId)) {\n\t\t\t\tif (!nextPageState) nextPageState = { ...prevPageState }\n\t\t\t\tnextPageState.hoveredShapeId = null\n\t\t\t}\n\n\t\t\tif (prevPageState.editingShapeId && shapesNoLongerInPage.has(prevPageState.editingShapeId)) {\n\t\t\t\tif (!nextPageState) nextPageState = { ...prevPageState }\n\t\t\t\tnextPageState.editingShapeId = null\n\t\t\t}\n\n\t\t\tconst hintingShapeIds = prevPageState.hintingShapeIds.filter(\n\t\t\t\t(id) => !shapesNoLongerInPage.has(id)\n\t\t\t)\n\t\t\tif (hintingShapeIds.length !== prevPageState.hintingShapeIds.length) {\n\t\t\t\tif (!nextPageState) nextPageState = { ...prevPageState }\n\t\t\t\tnextPageState.hintingShapeIds = hintingShapeIds\n\t\t\t}\n\n\t\t\tif (prevPageState.focusedGroupId && shapesNoLongerInPage.has(prevPageState.focusedGroupId)) {\n\t\t\t\tif (!nextPageState) nextPageState = { ...prevPageState }\n\t\t\t\tnextPageState.focusedGroupId = null\n\t\t\t}\n\t\t\treturn nextPageState\n\t\t}\n\n\t\tthis.sideEffects = this.store.sideEffects\n\n\t\tlet deletedBindings = new Map>()\n\t\tconst deletedShapeIds = new Set()\n\t\tconst invalidParents = new Set()\n\t\tlet invalidBindingTypes = new Set()\n\t\tthis.disposables.add(\n\t\t\tthis.sideEffects.registerOperationCompleteHandler(() => {\n\t\t\t\t// this needs to be cleared here because further effects may delete more shapes\n\t\t\t\t// and we want the next invocation of this handler to handle those separately\n\t\t\t\tdeletedShapeIds.clear()\n\n\t\t\t\tfor (const parentId of invalidParents) {\n\t\t\t\t\tinvalidParents.delete(parentId)\n\t\t\t\t\tconst parent = this.getShape(parentId)\n\t\t\t\t\tif (!parent) continue\n\n\t\t\t\t\tconst util = this.getShapeUtil(parent)\n\t\t\t\t\tconst changes = util.onChildrenChange?.(parent)\n\n\t\t\t\t\tif (changes?.length) {\n\t\t\t\t\t\tthis.updateShapes(changes)\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (invalidBindingTypes.size) {\n\t\t\t\t\tconst t = invalidBindingTypes\n\t\t\t\t\tinvalidBindingTypes = new Set()\n\t\t\t\t\tfor (const type of t) {\n\t\t\t\t\t\tconst util = this.getBindingUtil(type)\n\t\t\t\t\t\tutil.onOperationComplete?.()\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (deletedBindings.size) {\n\t\t\t\t\tconst t = deletedBindings\n\t\t\t\t\tdeletedBindings = new Map()\n\t\t\t\t\tfor (const opts of t.values()) {\n\t\t\t\t\t\tthis.getBindingUtil(opts.binding).onAfterDelete?.(opts)\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tthis.emit('update')\n\t\t\t})\n\t\t)\n\n\t\tthis.disposables.add(\n\t\t\tthis.sideEffects.register({\n\t\t\t\tshape: {\n\t\t\t\t\tafterChange: (shapeBefore, shapeAfter) => {\n\t\t\t\t\t\tfor (const binding of this.getBindingsInvolvingShape(shapeAfter)) {\n\t\t\t\t\t\t\tinvalidBindingTypes.add(binding.type)\n\t\t\t\t\t\t\tif (binding.fromId === shapeAfter.id) {\n\t\t\t\t\t\t\t\tthis.getBindingUtil(binding).onAfterChangeFromShape?.({\n\t\t\t\t\t\t\t\t\tbinding,\n\t\t\t\t\t\t\t\t\tshapeBefore,\n\t\t\t\t\t\t\t\t\tshapeAfter,\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (binding.toId === shapeAfter.id) {\n\t\t\t\t\t\t\t\tthis.getBindingUtil(binding).onAfterChangeToShape?.({\n\t\t\t\t\t\t\t\t\tbinding,\n\t\t\t\t\t\t\t\t\tshapeBefore,\n\t\t\t\t\t\t\t\t\tshapeAfter,\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// if the shape's parent changed and it has a binding, update the binding\n\t\t\t\t\t\tif (shapeBefore.parentId !== shapeAfter.parentId) {\n\t\t\t\t\t\t\tconst notifyBindingAncestryChange = (id: TLShapeId) => {\n\t\t\t\t\t\t\t\tconst descendantShape = this.getShape(id)\n\t\t\t\t\t\t\t\tif (!descendantShape) return\n\n\t\t\t\t\t\t\t\tfor (const binding of this.getBindingsInvolvingShape(descendantShape)) {\n\t\t\t\t\t\t\t\t\tinvalidBindingTypes.add(binding.type)\n\n\t\t\t\t\t\t\t\t\tif (binding.fromId === descendantShape.id) {\n\t\t\t\t\t\t\t\t\t\tthis.getBindingUtil(binding).onAfterChangeFromShape?.({\n\t\t\t\t\t\t\t\t\t\t\tbinding,\n\t\t\t\t\t\t\t\t\t\t\tshapeBefore: descendantShape,\n\t\t\t\t\t\t\t\t\t\t\tshapeAfter: descendantShape,\n\t\t\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tif (binding.toId === descendantShape.id) {\n\t\t\t\t\t\t\t\t\t\tthis.getBindingUtil(binding).onAfterChangeToShape?.({\n\t\t\t\t\t\t\t\t\t\t\tbinding,\n\t\t\t\t\t\t\t\t\t\t\tshapeBefore: descendantShape,\n\t\t\t\t\t\t\t\t\t\t\tshapeAfter: descendantShape,\n\t\t\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tnotifyBindingAncestryChange(shapeAfter.id)\n\t\t\t\t\t\t\tthis.visitDescendants(shapeAfter.id, notifyBindingAncestryChange)\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// if this shape moved to a new page, clean up any previous page's instance state\n\t\t\t\t\t\tif (shapeBefore.parentId !== shapeAfter.parentId && isPageId(shapeAfter.parentId)) {\n\t\t\t\t\t\t\tconst allMovingIds = new Set([shapeBefore.id])\n\t\t\t\t\t\t\tthis.visitDescendants(shapeBefore.id, (id) => {\n\t\t\t\t\t\t\t\tallMovingIds.add(id)\n\t\t\t\t\t\t\t})\n\n\t\t\t\t\t\t\tfor (const instancePageState of this.getPageStates()) {\n\t\t\t\t\t\t\t\tif (instancePageState.pageId === shapeAfter.parentId) continue\n\t\t\t\t\t\t\t\tconst nextPageState = cleanupInstancePageState(instancePageState, allMovingIds)\n\n\t\t\t\t\t\t\t\tif (nextPageState) {\n\t\t\t\t\t\t\t\t\tthis.store.put([nextPageState])\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (shapeBefore.parentId && isShapeId(shapeBefore.parentId)) {\n\t\t\t\t\t\t\tinvalidParents.add(shapeBefore.parentId)\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (shapeAfter.parentId !== shapeBefore.parentId && isShapeId(shapeAfter.parentId)) {\n\t\t\t\t\t\t\tinvalidParents.add(shapeAfter.parentId)\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t\tbeforeDelete: (shape) => {\n\t\t\t\t\t\t// if we triggered this delete with a recursive call, don't do anything\n\t\t\t\t\t\tif (deletedShapeIds.has(shape.id)) return\n\t\t\t\t\t\t// if the deleted shape has a parent shape make sure we call it's onChildrenChange callback\n\t\t\t\t\t\tif (shape.parentId && isShapeId(shape.parentId)) {\n\t\t\t\t\t\t\tinvalidParents.add(shape.parentId)\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tdeletedShapeIds.add(shape.id)\n\n\t\t\t\t\t\tconst deleteBindingIds: TLBindingId[] = []\n\t\t\t\t\t\tfor (const binding of this.getBindingsInvolvingShape(shape)) {\n\t\t\t\t\t\t\tinvalidBindingTypes.add(binding.type)\n\t\t\t\t\t\t\tdeleteBindingIds.push(binding.id)\n\t\t\t\t\t\t\tconst util = this.getBindingUtil(binding)\n\t\t\t\t\t\t\tif (binding.fromId === shape.id) {\n\t\t\t\t\t\t\t\tutil.onBeforeIsolateToShape?.({ binding, removedShape: shape })\n\t\t\t\t\t\t\t\tutil.onBeforeDeleteFromShape?.({ binding, shape })\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tutil.onBeforeIsolateFromShape?.({ binding, removedShape: shape })\n\t\t\t\t\t\t\t\tutil.onBeforeDeleteToShape?.({ binding, shape })\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (deleteBindingIds.length) {\n\t\t\t\t\t\t\tthis.deleteBindings(deleteBindingIds)\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst deletedIds = new Set([shape.id])\n\t\t\t\t\t\tconst updates = compact(\n\t\t\t\t\t\t\tthis.getPageStates().map((pageState) => {\n\t\t\t\t\t\t\t\treturn cleanupInstancePageState(pageState, deletedIds)\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t)\n\n\t\t\t\t\t\tif (updates.length) {\n\t\t\t\t\t\t\tthis.store.put(updates)\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tbinding: {\n\t\t\t\t\tbeforeCreate: (binding) => {\n\t\t\t\t\t\tconst next = this.getBindingUtil(binding).onBeforeCreate?.({ binding })\n\t\t\t\t\t\tif (next) return next\n\t\t\t\t\t\treturn binding\n\t\t\t\t\t},\n\t\t\t\t\tafterCreate: (binding) => {\n\t\t\t\t\t\tinvalidBindingTypes.add(binding.type)\n\t\t\t\t\t\tthis.getBindingUtil(binding).onAfterCreate?.({ binding })\n\t\t\t\t\t},\n\t\t\t\t\tbeforeChange: (bindingBefore, bindingAfter) => {\n\t\t\t\t\t\tconst updated = this.getBindingUtil(bindingAfter).onBeforeChange?.({\n\t\t\t\t\t\t\tbindingBefore,\n\t\t\t\t\t\t\tbindingAfter,\n\t\t\t\t\t\t})\n\t\t\t\t\t\tif (updated) return updated\n\t\t\t\t\t\treturn bindingAfter\n\t\t\t\t\t},\n\t\t\t\t\tafterChange: (bindingBefore, bindingAfter) => {\n\t\t\t\t\t\tinvalidBindingTypes.add(bindingAfter.type)\n\t\t\t\t\t\tthis.getBindingUtil(bindingAfter).onAfterChange?.({ bindingBefore, bindingAfter })\n\t\t\t\t\t},\n\t\t\t\t\tbeforeDelete: (binding) => {\n\t\t\t\t\t\tthis.getBindingUtil(binding).onBeforeDelete?.({ binding })\n\t\t\t\t\t},\n\t\t\t\t\tafterDelete: (binding) => {\n\t\t\t\t\t\tthis.getBindingUtil(binding).onAfterDelete?.({ binding })\n\t\t\t\t\t\tinvalidBindingTypes.add(binding.type)\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tpage: {\n\t\t\t\t\tafterCreate: (record) => {\n\t\t\t\t\t\tconst cameraId = CameraRecordType.createId(record.id)\n\t\t\t\t\t\tconst _pageStateId = InstancePageStateRecordType.createId(record.id)\n\t\t\t\t\t\tif (!this.store.has(cameraId)) {\n\t\t\t\t\t\t\tthis.store.put([CameraRecordType.create({ id: cameraId })])\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (!this.store.has(_pageStateId)) {\n\t\t\t\t\t\t\tthis.store.put([\n\t\t\t\t\t\t\t\tInstancePageStateRecordType.create({ id: _pageStateId, pageId: record.id }),\n\t\t\t\t\t\t\t])\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t\tafterDelete: (record, source) => {\n\t\t\t\t\t\t// page was deleted, need to check whether it's the current page and select another one if so\n\t\t\t\t\t\tif (this.getInstanceState()?.currentPageId === record.id) {\n\t\t\t\t\t\t\tconst backupPageId = this.getPages().find((p) => p.id !== record.id)?.id\n\t\t\t\t\t\t\tif (backupPageId) {\n\t\t\t\t\t\t\t\tthis.store.put([{ ...this.getInstanceState(), currentPageId: backupPageId }])\n\t\t\t\t\t\t\t} else if (source === 'user') {\n\t\t\t\t\t\t\t\t// fall back to ensureStoreIsUsable:\n\t\t\t\t\t\t\t\tthis.store.ensureStoreIsUsable()\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// delete the camera and state for the page if necessary\n\t\t\t\t\t\tconst cameraId = CameraRecordType.createId(record.id)\n\t\t\t\t\t\tconst instance_PageStateId = InstancePageStateRecordType.createId(record.id)\n\t\t\t\t\t\tthis.store.remove([cameraId, instance_PageStateId])\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tinstance: {\n\t\t\t\t\tafterChange: (prev, next, source) => {\n\t\t\t\t\t\t// instance should never be updated to a page that no longer exists (this can\n\t\t\t\t\t\t// happen when undoing a change that involves switching to a page that has since\n\t\t\t\t\t\t// been deleted by another user)\n\t\t\t\t\t\tif (!this.store.has(next.currentPageId)) {\n\t\t\t\t\t\t\tconst backupPageId = this.store.has(prev.currentPageId)\n\t\t\t\t\t\t\t\t? prev.currentPageId\n\t\t\t\t\t\t\t\t: this.getPages()[0]?.id\n\t\t\t\t\t\t\tif (backupPageId) {\n\t\t\t\t\t\t\t\tthis.store.update(next.id, (instance) => ({\n\t\t\t\t\t\t\t\t\t...instance,\n\t\t\t\t\t\t\t\t\tcurrentPageId: backupPageId,\n\t\t\t\t\t\t\t\t}))\n\t\t\t\t\t\t\t} else if (source === 'user') {\n\t\t\t\t\t\t\t\t// fall back to ensureStoreIsUsable:\n\t\t\t\t\t\t\t\tthis.store.ensureStoreIsUsable()\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tinstance_page_state: {\n\t\t\t\t\tafterChange: (prev, next) => {\n\t\t\t\t\t\tif (prev?.selectedShapeIds !== next?.selectedShapeIds) {\n\t\t\t\t\t\t\t// ensure that descendants and ancestors are not selected at the same time\n\t\t\t\t\t\t\tconst filtered = next.selectedShapeIds.filter((id) => {\n\t\t\t\t\t\t\t\tlet parentId = this.getShape(id)?.parentId\n\t\t\t\t\t\t\t\twhile (isShapeId(parentId)) {\n\t\t\t\t\t\t\t\t\tif (next.selectedShapeIds.includes(parentId)) {\n\t\t\t\t\t\t\t\t\t\treturn false\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tparentId = this.getShape(parentId)?.parentId\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\treturn true\n\t\t\t\t\t\t\t})\n\n\t\t\t\t\t\t\tlet nextFocusedGroupId: null | TLShapeId = null\n\n\t\t\t\t\t\t\tif (filtered.length > 0) {\n\t\t\t\t\t\t\t\tconst commonGroupAncestor = this.findCommonAncestor(\n\t\t\t\t\t\t\t\t\tcompact(filtered.map((id) => this.getShape(id))),\n\t\t\t\t\t\t\t\t\t(shape) => this.isShapeOfType(shape, 'group')\n\t\t\t\t\t\t\t\t)\n\n\t\t\t\t\t\t\t\tif (commonGroupAncestor) {\n\t\t\t\t\t\t\t\t\tnextFocusedGroupId = commonGroupAncestor\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tif (next?.focusedGroupId) {\n\t\t\t\t\t\t\t\t\tnextFocusedGroupId = next.focusedGroupId\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\tfiltered.length !== next.selectedShapeIds.length ||\n\t\t\t\t\t\t\t\tnextFocusedGroupId !== next.focusedGroupId\n\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\tthis.store.put([\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t...next,\n\t\t\t\t\t\t\t\t\t\tselectedShapeIds: filtered,\n\t\t\t\t\t\t\t\t\t\tfocusedGroupId: nextFocusedGroupId ?? null,\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t])\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t})\n\t\t)\n\n\t\tthis._currentPageShapeIds = deriveShapeIdsInCurrentPage(this.store, () =>\n\t\t\tthis.getCurrentPageId()\n\t\t)\n\t\tthis._parentIdsToChildIds = parentsToChildren(this.store)\n\n\t\tthis.disposables.add(\n\t\t\tthis.store.listen((changes) => {\n\t\t\t\tthis.emit('change', changes)\n\t\t\t})\n\t\t)\n\t\tthis.disposables.add(this.history.dispose)\n\n\t\tthis.run(\n\t\t\t() => {\n\t\t\t\tthis.store.ensureStoreIsUsable()\n\n\t\t\t\t// clear ephemeral state\n\t\t\t\tthis._updateCurrentPageState({\n\t\t\t\t\teditingShapeId: null,\n\t\t\t\t\thoveredShapeId: null,\n\t\t\t\t\terasingShapeIds: [],\n\t\t\t\t})\n\t\t\t},\n\t\t\t{ history: 'ignore' }\n\t\t)\n\n\t\tif (initialState && this.root.children[initialState] === undefined) {\n\t\t\tthrow Error(`No state found for initialState \"${initialState}\".`)\n\t\t}\n\n\t\tthis.root.enter(undefined, 'initial')\n\n\t\tthis.edgeScrollManager = new EdgeScrollManager(this)\n\t\tthis.focusManager = new FocusManager(this, autoFocus)\n\t\tthis.disposables.add(this.focusManager.dispose.bind(this.focusManager))\n\n\t\tif (this.getInstanceState().followingUserId) {\n\t\t\tthis.stopFollowingUser()\n\t\t}\n\n\t\tthis.on('tick', this._flushEventsForTick)\n\n\t\tthis.timers.requestAnimationFrame(() => {\n\t\t\tthis._tickManager.start()\n\t\t})\n\n\t\tthis.performanceTracker = new PerformanceTracker()\n\n\t\tif (this.store.props.collaboration?.mode) {\n\t\t\tconst mode = this.store.props.collaboration.mode\n\t\t\tthis.disposables.add(\n\t\t\t\treact('update collaboration mode', () => {\n\t\t\t\t\tthis.store.put([{ ...this.getInstanceState(), isReadonly: mode.get() === 'readonly' }])\n\t\t\t\t})\n\t\t\t)\n\t\t}\n\t}\n\n\tprivate readonly _isShapeHiddenPredicate?: (shape: TLShape, editor: Editor) => boolean\n\t@computed\n\tprivate getIsShapeHiddenCache() {\n\t\tif (!this._isShapeHiddenPredicate) return null\n\t\treturn this.store.createComputedCache('isShapeHidden', (shape: TLShape) => {\n\t\t\tconst hiddenParent = this.findShapeAncestor(shape, (p) => this.isShapeHidden(p))\n\t\t\tif (hiddenParent) return true\n\t\t\treturn this._isShapeHiddenPredicate!(shape, this) ?? false\n\t\t})\n\t}\n\tisShapeHidden(shapeOrId: TLShape | TLShapeId): boolean {\n\t\tif (!this._isShapeHiddenPredicate) return false\n\t\treturn !!this.getIsShapeHiddenCache!()!.get(\n\t\t\ttypeof shapeOrId === 'string' ? shapeOrId : shapeOrId.id\n\t\t)\n\t}\n\n\treadonly options: TldrawOptions\n\n\treadonly contextId = uniqueId()\n\n\t/**\n\t * The editor's store\n\t *\n\t * @public\n\t */\n\treadonly store: TLStore\n\n\t/**\n\t * The root state of the statechart.\n\t *\n\t * @public\n\t */\n\treadonly root: StateNode\n\n\t/**\n\t * A set of functions to call when the app is disposed.\n\t *\n\t * @public\n\t */\n\treadonly disposables = new Set<() => void>()\n\n\t/**\n\t * Whether the editor is disposed.\n\t *\n\t * @public\n\t */\n\tisDisposed = false\n\n\t/** @internal */\n\tprivate readonly _tickManager\n\n\t/**\n\t * A manager for the app's snapping feature.\n\t *\n\t * @public\n\t */\n\treadonly snaps: SnapManager\n\n\t/**\n\t * A manager for the any asynchronous events and making sure they're\n\t * cleaned up upon disposal.\n\t *\n\t * @public\n\t */\n\treadonly timers = tltime.forContext(this.contextId)\n\n\t/**\n\t * A manager for the user and their preferences.\n\t *\n\t * @public\n\t */\n\treadonly user: UserPreferencesManager\n\n\t/**\n\t * A helper for measuring text.\n\t *\n\t * @public\n\t */\n\treadonly textMeasure: TextManager\n\n\t/**\n\t * A manager for the editor's environment.\n\t *\n\t * @deprecated This is deprecated and will be removed in a future version. Use the `tlenv` global export instead.\n\t * @public\n\t */\n\treadonly environment = tlenv\n\n\t/**\n\t * A manager for the editor's scribbles.\n\t *\n\t * @public\n\t */\n\treadonly scribbles: ScribbleManager\n\n\t/**\n\t * A manager for side effects and correct state enforcement. See {@link @tldraw/store#StoreSideEffects} for details.\n\t *\n\t * @public\n\t */\n\treadonly sideEffects: StoreSideEffects\n\n\t/**\n\t * A manager for moving the camera when the mouse is at the edge of the screen.\n\t *\n\t * @public\n\t */\n\tedgeScrollManager: EdgeScrollManager\n\n\t/**\n\t * A manager for ensuring correct focus. See FocusManager for details.\n\t *\n\t * @internal\n\t */\n\tprivate focusManager: FocusManager\n\n\t/**\n\t * The current HTML element containing the editor.\n\t *\n\t * @example\n\t * ```ts\n\t * const container = editor.getContainer()\n\t * ```\n\t *\n\t * @public\n\t */\n\tgetContainer: () => HTMLElement\n\n\t/**\n\t * Dispose the editor.\n\t *\n\t * @public\n\t */\n\tdispose() {\n\t\tthis.disposables.forEach((dispose) => dispose())\n\t\tthis.disposables.clear()\n\t\tthis.isDisposed = true\n\t}\n\n\t/* ------------------- Shape Utils ------------------ */\n\n\t/**\n\t * A map of shape utility classes (TLShapeUtils) by shape type.\n\t *\n\t * @public\n\t */\n\tshapeUtils: { readonly [K in string]?: ShapeUtil }\n\n\tstyleProps: { [key: string]: Map, string> }\n\n\t/**\n\t * Get a shape util from a shape itself.\n\t *\n\t * @example\n\t * ```ts\n\t * const util = editor.getShapeUtil(myArrowShape)\n\t * const util = editor.getShapeUtil('arrow')\n\t * const util = editor.getShapeUtil(myArrowShape)\n\t * const util = editor.getShapeUtil(TLArrowShape)('arrow')\n\t * ```\n\t *\n\t * @param shape - A shape, shape partial, or shape type.\n\t *\n\t * @public\n\t */\n\tgetShapeUtil(shape: S | TLShapePartial): ShapeUtil\n\tgetShapeUtil(type: S['type']): ShapeUtil\n\tgetShapeUtil(type: T extends ShapeUtil ? R['type'] : string): T\n\tgetShapeUtil(arg: string | { type: string }) {\n\t\tconst type = typeof arg === 'string' ? arg : arg.type\n\t\tconst shapeUtil = getOwnProperty(this.shapeUtils, type)\n\t\tassert(shapeUtil, `No shape util found for type \"${type}\"`)\n\t\treturn shapeUtil\n\t}\n\n\t/* ------------------- Binding Utils ------------------ */\n\t/**\n\t * A map of shape utility classes (TLShapeUtils) by shape type.\n\t *\n\t * @public\n\t */\n\tbindingUtils: { readonly [K in string]?: BindingUtil }\n\n\t/**\n\t * Get a binding util from a binding itself.\n\t *\n\t * @example\n\t * ```ts\n\t * const util = editor.getBindingUtil(myArrowBinding)\n\t * const util = editor.getBindingUtil('arrow')\n\t * const util = editor.getBindingUtil(myArrowBinding)\n\t * const util = editor.getBindingUtil(TLArrowBinding)('arrow')\n\t * ```\n\t *\n\t * @param binding - A binding, binding partial, or binding type.\n\t *\n\t * @public\n\t */\n\tgetBindingUtil(binding: S | { type: S['type'] }): BindingUtil\n\tgetBindingUtil(type: S['type']): BindingUtil\n\tgetBindingUtil(\n\t\ttype: T extends BindingUtil ? R['type'] : string\n\t): T\n\tgetBindingUtil(arg: string | { type: string }) {\n\t\tconst type = typeof arg === 'string' ? arg : arg.type\n\t\tconst bindingUtil = getOwnProperty(this.bindingUtils, type)\n\t\tassert(bindingUtil, `No binding util found for type \"${type}\"`)\n\t\treturn bindingUtil\n\t}\n\n\t/* --------------------- History -------------------- */\n\n\t/**\n\t * A manager for the app's history.\n\t *\n\t * @readonly\n\t */\n\tprotected readonly history: HistoryManager\n\n\t/**\n\t * Undo to the last mark.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.undo()\n\t * ```\n\t *\n\t * @public\n\t */\n\tundo(): this {\n\t\tthis._flushEventsForTick(0)\n\t\tthis.complete()\n\t\tthis.history.undo()\n\t\treturn this\n\t}\n\n\t/**\n\t * Whether the app can undo.\n\t *\n\t * @public\n\t */\n\t@computed getCanUndo(): boolean {\n\t\treturn this.history.getNumUndos() > 0\n\t}\n\n\t/**\n\t * Redo to the next mark.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.redo()\n\t * ```\n\t *\n\t * @public\n\t */\n\tredo(): this {\n\t\tthis._flushEventsForTick(0)\n\t\tthis.complete()\n\t\tthis.history.redo()\n\t\treturn this\n\t}\n\n\tclearHistory() {\n\t\tthis.history.clear()\n\t\treturn this\n\t}\n\n\t/**\n\t * Whether the app can redo.\n\t *\n\t * @public\n\t */\n\t@computed getCanRedo(): boolean {\n\t\treturn this.history.getNumRedos() > 0\n\t}\n\n\t/**\n\t * Create a new \"mark\", or stopping point, in the undo redo history. Creating a mark will clear\n\t * any redos.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.mark()\n\t * editor.mark('flip shapes')\n\t * ```\n\t *\n\t * @param markId - The mark's id, usually the reason for adding the mark.\n\t *\n\t * @public\n\t * @deprecated use {@link Editor.markHistoryStoppingPoint} instead\n\t */\n\tmark(markId?: string): this {\n\t\tif (typeof markId === 'string') {\n\t\t\tconsole.warn(\n\t\t\t\t`[tldraw] \\`editor.history.mark(\"${markId}\")\\` is deprecated. Please use \\`const myMarkId = editor.markHistoryStoppingPoint()\\` instead.`\n\t\t\t)\n\t\t} else {\n\t\t\tconsole.warn(\n\t\t\t\t'[tldraw] `editor.mark()` is deprecated. Use `editor.markHistoryStoppingPoint()` instead.'\n\t\t\t)\n\t\t}\n\t\tthis.history._mark(markId ?? uniqueId())\n\t\treturn this\n\t}\n\n\t/**\n\t * Create a new \"mark\", or stopping point, in the undo redo history. Creating a mark will clear\n\t * any redos. You typically want to do this just before a user interaction begins or is handled.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.markHistoryStoppingPoint()\n\t * editor.flipShapes(editor.getSelectedShapes())\n\t * ```\n\t * @example\n\t * ```ts\n\t * const beginRotateMark = editor.markHistoryStoppingPoint()\n\t * // if the use cancels the rotation, you can bail back to this mark\n\t * editor.bailToMark(beginRotateMark)\n\t * ```\n\t *\n\t * @public\n\t * @param name - The name of the mark, useful for debugging the undo/redo stacks\n\t * @returns a unique id for the mark that can be used with `squashToMark` or `bailToMark`.\n\t */\n\tmarkHistoryStoppingPoint(name?: string): string {\n\t\tconst id = `[${name ?? 'stop'}]_${uniqueId()}`\n\t\tthis.history._mark(id)\n\t\treturn id\n\t}\n\n\t/**\n\t * @internal this is only used to implement some backwards-compatibility logic. Should be fine to delete after 6 months or whatever.\n\t */\n\tgetMarkIdMatching(idSubstring: string) {\n\t\treturn this.history.getMarkIdMatching(idSubstring)\n\t}\n\n\t/**\n\t * Coalesces all changes since the given mark into a single change, removing any intermediate marks.\n\t *\n\t * This is useful if you need to 'compress' the recent history to simplify the undo/redo experience of a complex interaction.\n\t *\n\t * @example\n\t * ```ts\n\t * const bumpShapesMark = editor.markHistoryStoppingPoint()\n\t * // ... some changes\n\t * editor.squashToMark(bumpShapesMark)\n\t * ```\n\t *\n\t * @param markId - The mark id to squash to.\n\t */\n\tsquashToMark(markId: string): this {\n\t\tthis.history.squashToMark(markId)\n\t\treturn this\n\t}\n\n\t/**\n\t * Undo to the closest mark, discarding the changes so they cannot be redone.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.bail()\n\t * ```\n\t *\n\t * @public\n\t */\n\tbail() {\n\t\tthis.history.bail()\n\t\treturn this\n\t}\n\n\t/**\n\t * Undo to the given mark, discarding the changes so they cannot be redone.\n\t *\n\t * @example\n\t * ```ts\n\t * const beginDrag = editor.markHistoryStoppingPoint()\n\t * // ... some changes\n\t * editor.bailToMark(beginDrag)\n\t * ```\n\t *\n\t * @public\n\t */\n\tbailToMark(id: string): this {\n\t\tthis.history.bailToMark(id)\n\t\treturn this\n\t}\n\n\tprivate _shouldIgnoreShapeLock = false\n\n\t/**\n\t * Run a function in a transaction with optional options for context.\n\t * You can use the options to change the way that history is treated\n\t * or allow changes to locked shapes.\n\t *\n\t * @example\n\t * ```ts\n\t * // updating with\n\t * editor.run(() => {\n\t * \teditor.updateShape({ ...myShape, x: 100 })\n\t * }, { history: \"ignore\" })\n\t *\n\t * // forcing changes / deletions for locked shapes\n\t * editor.toggleLock([myShape])\n\t * editor.run(() => {\n\t * \teditor.updateShape({ ...myShape, x: 100 })\n\t * \teditor.deleteShape(myShape)\n\t * }, { ignoreShapeLock: true }, )\n\t * ```\n\t *\n\t * @param fn - The callback function to run.\n\t * @param opts - The options for the batch.\n\t *\n\t *\n\t * @public\n\t */\n\trun(fn: () => void, opts?: TLEditorRunOptions): this {\n\t\tconst previousIgnoreShapeLock = this._shouldIgnoreShapeLock\n\t\tthis._shouldIgnoreShapeLock = opts?.ignoreShapeLock ?? previousIgnoreShapeLock\n\n\t\ttry {\n\t\t\tthis.history.batch(fn, opts)\n\t\t} finally {\n\t\t\tthis._shouldIgnoreShapeLock = previousIgnoreShapeLock\n\t\t}\n\n\t\treturn this\n\t}\n\n\t/**\n\t * @deprecated Use `Editor.run` instead.\n\t */\n\tbatch(fn: () => void, opts?: TLEditorRunOptions): this {\n\t\treturn this.run(fn, opts)\n\t}\n\n\t/* --------------------- Errors --------------------- */\n\n\t/** @internal */\n\tannotateError(\n\t\terror: unknown,\n\t\t{\n\t\t\torigin,\n\t\t\twillCrashApp,\n\t\t\ttags,\n\t\t\textras,\n\t\t}: {\n\t\t\torigin: string\n\t\t\twillCrashApp: boolean\n\t\t\ttags?: Record\n\t\t\textras?: Record\n\t\t}\n\t): this {\n\t\tconst defaultAnnotations = this.createErrorAnnotations(origin, willCrashApp)\n\t\tannotateError(error, {\n\t\t\ttags: { ...defaultAnnotations.tags, ...tags },\n\t\t\textras: { ...defaultAnnotations.extras, ...extras },\n\t\t})\n\t\tif (willCrashApp) {\n\t\t\tthis.store.markAsPossiblyCorrupted()\n\t\t}\n\t\treturn this\n\t}\n\n\t/** @internal */\n\tcreateErrorAnnotations(\n\t\torigin: string,\n\t\twillCrashApp: boolean | 'unknown'\n\t): {\n\t\ttags: { origin: string; willCrashApp: boolean | 'unknown' }\n\t\textras: {\n\t\t\tactiveStateNode?: string\n\t\t\tselectedShapes?: TLUnknownShape[]\n\t\t\teditingShape?: TLUnknownShape\n\t\t\tinputs?: Record\n\t\t}\n\t} {\n\t\ttry {\n\t\t\tconst editingShapeId = this.getEditingShapeId()\n\t\t\treturn {\n\t\t\t\ttags: {\n\t\t\t\t\torigin: origin,\n\t\t\t\t\twillCrashApp,\n\t\t\t\t},\n\t\t\t\textras: {\n\t\t\t\t\tactiveStateNode: this.root.getPath(),\n\t\t\t\t\tselectedShapes: this.getSelectedShapes(),\n\t\t\t\t\teditingShape: editingShapeId ? this.getShape(editingShapeId) : undefined,\n\t\t\t\t\tinputs: this.inputs,\n\t\t\t\t},\n\t\t\t}\n\t\t} catch {\n\t\t\treturn {\n\t\t\t\ttags: {\n\t\t\t\t\torigin: origin,\n\t\t\t\t\twillCrashApp,\n\t\t\t\t},\n\t\t\t\textras: {},\n\t\t\t}\n\t\t}\n\t}\n\n\t/** @internal */\n\tprivate _crashingError: unknown | null = null\n\n\t/**\n\t * We can't use an `atom` here because there's a chance that when `crashAndReportError` is called,\n\t * we're in a transaction that's about to be rolled back due to the same error we're currently\n\t * reporting.\n\t *\n\t * Instead, to listen to changes to this value, you need to listen to app's `crash` event.\n\t *\n\t * @internal\n\t */\n\tgetCrashingError() {\n\t\treturn this._crashingError\n\t}\n\n\t/** @internal */\n\tcrash(error: unknown): this {\n\t\tthis._crashingError = error\n\t\tthis.store.markAsPossiblyCorrupted()\n\t\tthis.emit('crash', { error })\n\t\treturn this\n\t}\n\n\t/* ------------------- Statechart ------------------- */\n\n\t/**\n\t * The editor's current path of active states.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getPath() // \"select.idle\"\n\t * ```\n\t *\n\t * @public\n\t */\n\t@computed getPath() {\n\t\treturn this.root.getPath().split('root.')[1]\n\t}\n\n\t/**\n\t * Get whether a certain tool (or other state node) is currently active.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.isIn('select')\n\t * editor.isIn('select.brushing')\n\t * ```\n\t *\n\t * @param path - The path of active states, separated by periods.\n\t *\n\t * @public\n\t */\n\tisIn(path: string): boolean {\n\t\tconst ids = path.split('.').reverse()\n\t\tlet state = this.root as StateNode\n\t\twhile (ids.length > 0) {\n\t\t\tconst id = ids.pop()\n\t\t\tif (!id) return true\n\t\t\tconst current = state.getCurrent()\n\t\t\tif (current?.id === id) {\n\t\t\t\tif (ids.length === 0) return true\n\t\t\t\tstate = current\n\t\t\t\tcontinue\n\t\t\t} else return false\n\t\t}\n\t\treturn false\n\t}\n\n\t/**\n\t * Get whether the state node is in any of the given active paths.\n\t *\n\t * @example\n\t * ```ts\n\t * state.isInAny('select', 'erase')\n\t * state.isInAny('select.brushing', 'erase.idle')\n\t * ```\n\t *\n\t * @public\n\t */\n\tisInAny(...paths: string[]): boolean {\n\t\treturn paths.some((path) => this.isIn(path))\n\t}\n\n\t/**\n\t * Set the selected tool.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.setCurrentTool('hand')\n\t * editor.setCurrentTool('hand', { date: Date.now() })\n\t * ```\n\t *\n\t * @param id - The id of the tool to select.\n\t * @param info - Arbitrary data to pass along into the transition.\n\t *\n\t * @public\n\t */\n\tsetCurrentTool(id: string, info = {}): this {\n\t\tthis.root.transition(id, info)\n\t\treturn this\n\t}\n\n\t/**\n\t * The current selected tool.\n\t *\n\t * @public\n\t */\n\t@computed getCurrentTool(): StateNode {\n\t\treturn this.root.getCurrent()!\n\t}\n\n\t/**\n\t * The id of the current selected tool.\n\t *\n\t * @public\n\t */\n\t@computed getCurrentToolId(): string {\n\t\tconst currentTool = this.getCurrentTool()\n\t\tif (!currentTool) return ''\n\t\treturn currentTool.getCurrentToolIdMask() ?? currentTool.id\n\t}\n\n\t/**\n\t * Get a descendant by its path.\n\t *\n\t * @example\n\t * ```ts\n\t * state.getStateDescendant('select')\n\t * state.getStateDescendant('select.brushing')\n\t * ```\n\t *\n\t * @param path - The descendant's path of state ids, separated by periods.\n\t *\n\t * @public\n\t */\n\tgetStateDescendant(path: string): T | undefined {\n\t\tconst ids = path.split('.').reverse()\n\t\tlet state = this.root as StateNode\n\t\twhile (ids.length > 0) {\n\t\t\tconst id = ids.pop()\n\t\t\tif (!id) return state as T\n\t\t\tconst childState = state.children?.[id]\n\t\t\tif (!childState) return undefined\n\t\t\tstate = childState\n\t\t}\n\t\treturn state as T\n\t}\n\n\t/* ---------------- Document Settings --------------- */\n\n\t/**\n\t * The global document settings that apply to all users.\n\t *\n\t * @public\n\t **/\n\t@computed getDocumentSettings() {\n\t\treturn this.store.get(TLDOCUMENT_ID)!\n\t}\n\n\t/**\n\t * Update the global document settings that apply to all users.\n\t *\n\t * @public\n\t **/\n\tupdateDocumentSettings(settings: Partial): this {\n\t\tthis.run(\n\t\t\t() => {\n\t\t\t\tthis.store.put([{ ...this.getDocumentSettings(), ...settings }])\n\t\t\t},\n\t\t\t{ history: 'ignore' }\n\t\t)\n\t\treturn this\n\t}\n\n\t/* ----------------- Instance State ----------------- */\n\n\t/**\n\t * The current instance's state.\n\t *\n\t * @public\n\t */\n\t@computed getInstanceState(): TLInstance {\n\t\treturn this.store.get(TLINSTANCE_ID)!\n\t}\n\n\t/**\n\t * Update the instance's state.\n\t *\n\t * @param partial - A partial object to update the instance state with.\n\t * @param historyOptions - History batch options.\n\t *\n\t * @public\n\t */\n\tupdateInstanceState(\n\t\tpartial: Partial>,\n\t\thistoryOptions?: TLHistoryBatchOptions\n\t): this {\n\t\tthis._updateInstanceState(partial, { history: 'ignore', ...historyOptions })\n\n\t\tif (partial.isChangingStyle !== undefined) {\n\t\t\tclearTimeout(this._isChangingStyleTimeout)\n\t\t\tif (partial.isChangingStyle === true) {\n\t\t\t\t// If we've set to true, set a new reset timeout to change the value back to false after 2 seconds\n\t\t\t\tthis._isChangingStyleTimeout = this.timers.setTimeout(() => {\n\t\t\t\t\tthis._updateInstanceState({ isChangingStyle: false }, { history: 'ignore' })\n\t\t\t\t}, 2000)\n\t\t\t}\n\t\t}\n\n\t\treturn this\n\t}\n\n\t/** @internal */\n\t_updateInstanceState(\n\t\tpartial: Partial>,\n\t\topts?: TLHistoryBatchOptions\n\t) {\n\t\tthis.run(() => {\n\t\t\tthis.store.put([\n\t\t\t\t{\n\t\t\t\t\t...this.getInstanceState(),\n\t\t\t\t\t...partial,\n\t\t\t\t},\n\t\t\t])\n\t\t}, opts)\n\t}\n\n\t/** @internal */\n\tprivate _isChangingStyleTimeout = -1 as any\n\n\t// Menus\n\n\tmenus = tlmenus.forContext(this.contextId)\n\n\t/**\n\t * @deprecated Use `editor.menus.getOpenMenus` instead.\n\t *\n\t * @public\n\t */\n\t@computed getOpenMenus(): string[] {\n\t\treturn this.menus.getOpenMenus()\n\t}\n\n\t/**\n\t * @deprecated Use `editor.menus.addOpenMenu` instead.\n\t *\n\t * @public\n\t */\n\taddOpenMenu(id: string): this {\n\t\tthis.menus.addOpenMenu(id)\n\t\treturn this\n\t}\n\n\t/**\n\t * @deprecated Use `editor.menus.deleteOpenMenu` instead.\n\t *\n\t * @public\n\t */\n\tdeleteOpenMenu(id: string): this {\n\t\tthis.menus.deleteOpenMenu(id)\n\t\treturn this\n\t}\n\n\t/**\n\t * @deprecated Use `editor.menus.clearOpenMenus` instead.\n\t *\n\t * @public\n\t */\n\tclearOpenMenus(): this {\n\t\tthis.menus.clearOpenMenus()\n\t\treturn this\n\t}\n\n\t/**\n\t * @deprecated Use `editor.menus.hasAnyOpenMenus` instead.\n\t *\n\t * @public\n\t */\n\t@computed getIsMenuOpen(): boolean {\n\t\treturn this.menus.hasAnyOpenMenus()\n\t}\n\n\t/* --------------------- Cursor --------------------- */\n\n\t/**\n\t * Set the cursor.\n\t *\n\t * @param cursor - The cursor to set.\n\t * @public\n\t */\n\tsetCursor(cursor: Partial) {\n\t\tthis.updateInstanceState({ cursor: { ...this.getInstanceState().cursor, ...cursor } })\n\t\treturn this\n\t}\n\n\t/* ------------------- Page State ------------------- */\n\n\t/**\n\t * Page states.\n\t *\n\t * @public\n\t */\n\t@computed getPageStates(): TLInstancePageState[] {\n\t\treturn this._getPageStatesQuery().get()\n\t}\n\n\t/** @internal */\n\t@computed private _getPageStatesQuery() {\n\t\treturn this.store.query.records('instance_page_state')\n\t}\n\n\t/**\n\t * The current page state.\n\t *\n\t * @public\n\t */\n\t@computed getCurrentPageState(): TLInstancePageState {\n\t\treturn this.store.get(this._getCurrentPageStateId())!\n\t}\n\n\t/** @internal */\n\t@computed private _getCurrentPageStateId() {\n\t\treturn InstancePageStateRecordType.createId(this.getCurrentPageId())\n\t}\n\n\t/**\n\t * Update this instance's page state.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.updateCurrentPageState({ id: 'page1', editingShapeId: 'shape:123' })\n\t * ```\n\t *\n\t * @param partial - The partial of the page state object containing the changes.\n\t *\n\t * @public\n\t */\n\tupdateCurrentPageState(\n\t\tpartial: Partial<\n\t\t\tOmit\n\t\t>\n\t): this {\n\t\tthis._updateCurrentPageState(partial)\n\t\treturn this\n\t}\n\t_updateCurrentPageState(partial: Partial>) {\n\t\tthis.store.update(partial.id ?? this.getCurrentPageState().id, (state) => ({\n\t\t\t...state,\n\t\t\t...partial,\n\t\t}))\n\t}\n\n\t/**\n\t * The current selected ids.\n\t *\n\t * @public\n\t */\n\t@computed getSelectedShapeIds() {\n\t\treturn this.getCurrentPageState().selectedShapeIds\n\t}\n\n\t/**\n\t * An array containing all of the currently selected shapes.\n\t *\n\t * @public\n\t * @readonly\n\t */\n\t@computed getSelectedShapes(): TLShape[] {\n\t\tconst { selectedShapeIds } = this.getCurrentPageState()\n\t\treturn compact(selectedShapeIds.map((id) => this.store.get(id)))\n\t}\n\n\t/**\n\t * Select one or more shapes.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.setSelectedShapes(['id1'])\n\t * editor.setSelectedShapes(['id1', 'id2'])\n\t * ```\n\t *\n\t * @param shapes - The shape (or shape ids) to select.\n\t *\n\t * @public\n\t */\n\tsetSelectedShapes(shapes: TLShapeId[] | TLShape[]): this {\n\t\treturn this.run(\n\t\t\t() => {\n\t\t\t\tconst ids = shapes.map((shape) => (typeof shape === 'string' ? shape : shape.id))\n\t\t\t\tconst { selectedShapeIds: prevSelectedShapeIds } = this.getCurrentPageState()\n\t\t\t\tconst prevSet = new Set(prevSelectedShapeIds)\n\n\t\t\t\tif (ids.length === prevSet.size && ids.every((id) => prevSet.has(id))) return null\n\n\t\t\t\tthis.store.put([{ ...this.getCurrentPageState(), selectedShapeIds: ids }])\n\t\t\t},\n\t\t\t{ history: 'record-preserveRedoStack' }\n\t\t)\n\t}\n\n\t/**\n\t * Determine whether or not any of a shape's ancestors are selected.\n\t *\n\t * @param shape - The shape (or shape id) of the shape to check.\n\t *\n\t * @public\n\t */\n\tisAncestorSelected(shape: TLShape | TLShapeId): boolean {\n\t\tconst id = typeof shape === 'string' ? shape : shape?.id ?? null\n\t\tconst _shape = this.getShape(id)\n\t\tif (!_shape) return false\n\t\tconst selectedShapeIds = this.getSelectedShapeIds()\n\t\treturn !!this.findShapeAncestor(_shape, (parent) => selectedShapeIds.includes(parent.id))\n\t}\n\n\t/**\n\t * Select one or more shapes.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.select('id1')\n\t * editor.select('id1', 'id2')\n\t * ```\n\t *\n\t * @param shapes - The shape (or the shape ids) to select.\n\t *\n\t * @public\n\t */\n\tselect(...shapes: TLShapeId[] | TLShape[]): this {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((shape) => shape.id)\n\t\tthis.setSelectedShapes(ids)\n\t\treturn this\n\t}\n\n\t/**\n\t * Remove a shape from the existing set of selected shapes.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.deselect(shape.id)\n\t * ```\n\t *\n\t * @public\n\t */\n\tdeselect(...shapes: TLShapeId[] | TLShape[]): this {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((shape) => shape.id)\n\t\tconst selectedShapeIds = this.getSelectedShapeIds()\n\t\tif (selectedShapeIds.length > 0 && ids.length > 0) {\n\t\t\tthis.setSelectedShapes(selectedShapeIds.filter((id) => !ids.includes(id)))\n\t\t}\n\t\treturn this\n\t}\n\n\t/**\n\t * Select all direct children of the current page.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.selectAll()\n\t * ```\n\t *\n\t * @public\n\t */\n\tselectAll(): this {\n\t\tconst ids = this.getSortedChildIdsForParent(this.getCurrentPageId())\n\t\t// page might have no shapes\n\t\tif (ids.length <= 0) return this\n\t\tthis.setSelectedShapes(this._getUnlockedShapeIds(ids))\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Clear the selection.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.selectNone()\n\t * ```\n\t *\n\t * @public\n\t */\n\tselectNone(): this {\n\t\tif (this.getSelectedShapeIds().length > 0) {\n\t\t\tthis.setSelectedShapes([])\n\t\t}\n\n\t\treturn this\n\t}\n\n\t/**\n\t * The id of the app's only selected shape.\n\t *\n\t * @returns Null if there is no shape or more than one selected shape, otherwise the selected shape's id.\n\t *\n\t * @public\n\t * @readonly\n\t */\n\t@computed getOnlySelectedShapeId(): TLShapeId | null {\n\t\treturn this.getOnlySelectedShape()?.id ?? null\n\t}\n\n\t/**\n\t * The app's only selected shape.\n\t *\n\t * @returns Null if there is no shape or more than one selected shape, otherwise the selected shape.\n\t *\n\t * @public\n\t * @readonly\n\t */\n\t@computed getOnlySelectedShape(): TLShape | null {\n\t\tconst selectedShapes = this.getSelectedShapes()\n\t\treturn selectedShapes.length === 1 ? selectedShapes[0] : null\n\t}\n\n\t/**\n\t * @internal\n\t */\n\tgetShapesPageBounds(shapeIds: TLShapeId[]): Box | null {\n\t\tconst bounds = compact(shapeIds.map((id) => this.getShapePageBounds(id)))\n\t\tif (bounds.length === 0) return null\n\t\treturn Box.Common(bounds)\n\t}\n\n\t/**\n\t * The current page bounds of all the selected shapes. If the\n\t * selection is rotated, then these bounds are the axis-aligned\n\t * box that the rotated bounds would fit inside of.\n\t *\n\t * @readonly\n\t *\n\t * @public\n\t */\n\t@computed getSelectionPageBounds(): Box | null {\n\t\treturn this.getShapesPageBounds(this.getSelectedShapeIds())\n\t}\n\n\t/**\n\t * @internal\n\t */\n\tgetShapesSharedRotation(shapeIds: TLShapeId[]) {\n\t\tlet foundFirst = false // annoying but we can't use an i===0 check because we need to skip over undefineds\n\t\tlet rotation = 0\n\t\tfor (let i = 0, n = shapeIds.length; i < n; i++) {\n\t\t\tconst pageTransform = this.getShapePageTransform(shapeIds[i])\n\t\t\tif (!pageTransform) continue\n\t\t\tif (foundFirst) {\n\t\t\t\tif (pageTransform.rotation() !== rotation) {\n\t\t\t\t\t// There are at least 2 different rotations, so the common rotation is zero\n\t\t\t\t\treturn 0\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// First rotation found\n\t\t\t\tfoundFirst = true\n\t\t\t\trotation = pageTransform.rotation()\n\t\t\t}\n\t\t}\n\n\t\treturn rotation\n\t}\n\n\t/**\n\t * The rotation of the selection bounding box in the current page space.\n\t *\n\t * @readonly\n\t * @public\n\t */\n\t@computed getSelectionRotation(): number {\n\t\treturn this.getShapesSharedRotation(this.getSelectedShapeIds())\n\t}\n\n\t/**\n\t * @internal\n\t */\n\tgetShapesRotatedPageBounds(shapeIds: TLShapeId[]): Box | undefined {\n\t\tif (shapeIds.length === 0) {\n\t\t\treturn undefined\n\t\t}\n\n\t\tconst selectionRotation = this.getShapesSharedRotation(shapeIds)\n\t\tif (selectionRotation === 0) {\n\t\t\treturn this.getShapesPageBounds(shapeIds) ?? undefined\n\t\t}\n\n\t\tif (shapeIds.length === 1) {\n\t\t\tconst bounds = this.getShapeGeometry(shapeIds[0]).bounds.clone()\n\t\t\tconst pageTransform = this.getShapePageTransform(shapeIds[0])!\n\t\t\tbounds.point = pageTransform.applyToPoint(bounds.point)\n\t\t\treturn bounds\n\t\t}\n\n\t\t// need to 'un-rotate' all the outlines of the existing nodes so we can fit them inside a box\n\t\tconst boxFromRotatedVertices = Box.FromPoints(\n\t\t\tshapeIds\n\t\t\t\t.flatMap((id) => {\n\t\t\t\t\tconst pageTransform = this.getShapePageTransform(id)\n\t\t\t\t\tif (!pageTransform) return []\n\t\t\t\t\treturn pageTransform.applyToPoints(this.getShapeGeometry(id).bounds.corners)\n\t\t\t\t})\n\t\t\t\t.map((p) => p.rot(-selectionRotation))\n\t\t)\n\t\t// now position box so that it's top-left corner is in the right place\n\t\tboxFromRotatedVertices.point = boxFromRotatedVertices.point.rot(selectionRotation)\n\t\treturn boxFromRotatedVertices\n\t}\n\n\t/**\n\t * The bounds of the selection bounding box in the current page space.\n\t *\n\t * @readonly\n\t * @public\n\t */\n\t@computed getSelectionRotatedPageBounds(): Box | undefined {\n\t\treturn this.getShapesRotatedPageBounds(this.getSelectedShapeIds())\n\t}\n\n\t/**\n\t * The bounds of the selection bounding box in the current page space.\n\t *\n\t * @readonly\n\t * @public\n\t */\n\t@computed getSelectionRotatedScreenBounds(): Box | undefined {\n\t\tconst bounds = this.getSelectionRotatedPageBounds()\n\t\tif (!bounds) return undefined\n\t\tconst { x, y } = this.pageToScreen(bounds.point)\n\t\tconst zoom = this.getZoomLevel()\n\t\treturn new Box(x, y, bounds.width * zoom, bounds.height * zoom)\n\t}\n\n\t// Focus Group\n\n\t/**\n\t * The current focused group id.\n\t *\n\t * @public\n\t */\n\t@computed getFocusedGroupId(): TLShapeId | TLPageId {\n\t\treturn this.getCurrentPageState().focusedGroupId ?? this.getCurrentPageId()\n\t}\n\n\t/**\n\t * The current focused group.\n\t *\n\t * @public\n\t */\n\t@computed getFocusedGroup(): TLShape | undefined {\n\t\tconst focusedGroupId = this.getFocusedGroupId()\n\t\treturn focusedGroupId ? this.getShape(focusedGroupId) : undefined\n\t}\n\n\t/**\n\t * Set the current focused group shape.\n\t *\n\t * @param shape - The group shape id (or group shape's id) to set as the focused group shape.\n\t *\n\t * @public\n\t */\n\tsetFocusedGroup(shape: TLShapeId | TLGroupShape | null): this {\n\t\tconst id = typeof shape === 'string' ? shape : shape?.id ?? null\n\n\t\tif (id !== null) {\n\t\t\tconst shape = this.getShape(id)\n\t\t\tif (!shape) {\n\t\t\t\tthrow Error(`Editor.setFocusedGroup: Shape with id ${id} does not exist`)\n\t\t\t}\n\n\t\t\tif (!this.isShapeOfType(shape, 'group')) {\n\t\t\t\tthrow Error(\n\t\t\t\t\t`Editor.setFocusedGroup: Cannot set focused group to shape of type ${shape.type}`\n\t\t\t\t)\n\t\t\t}\n\t\t}\n\n\t\tif (id === this.getFocusedGroupId()) return this\n\n\t\treturn this.run(\n\t\t\t() => {\n\t\t\t\tthis.store.update(this.getCurrentPageState().id, (s) => ({ ...s, focusedGroupId: id }))\n\t\t\t},\n\t\t\t{ history: 'record-preserveRedoStack' }\n\t\t)\n\t}\n\n\t/**\n\t * Exit the current focused group, moving up to the next parent group if there is one.\n\t *\n\t * @public\n\t */\n\tpopFocusedGroupId(): this {\n\t\tconst focusedGroup = this.getFocusedGroup()\n\n\t\tif (focusedGroup) {\n\t\t\t// If we have a focused layer, look for an ancestor of the focused shape that is a group\n\t\t\tconst match = this.findShapeAncestor(focusedGroup, (shape) =>\n\t\t\t\tthis.isShapeOfType(shape, 'group')\n\t\t\t)\n\t\t\t// If we have an ancestor that can become a focused layer, set it as the focused layer\n\t\t\tthis.setFocusedGroup(match?.id ?? null)\n\t\t\tthis.select(focusedGroup.id)\n\t\t} else {\n\t\t\t// If there's no parent focused group, then clear the focus layer and clear selection\n\t\t\tthis.setFocusedGroup(null)\n\t\t\tthis.selectNone()\n\t\t}\n\n\t\treturn this\n\t}\n\n\t/**\n\t * The current editing shape's id.\n\t *\n\t * @public\n\t */\n\t@computed getEditingShapeId(): TLShapeId | null {\n\t\treturn this.getCurrentPageState().editingShapeId\n\t}\n\n\t/**\n\t * The current editing shape.\n\t *\n\t * @public\n\t */\n\t@computed getEditingShape(): TLShape | undefined {\n\t\tconst editingShapeId = this.getEditingShapeId()\n\t\treturn editingShapeId ? this.getShape(editingShapeId) : undefined\n\t}\n\n\t/**\n\t * Set the current editing shape.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.setEditingShape(myShape)\n\t * editor.setEditingShape(myShape.id)\n\t * ```\n\t *\n\t * @param shape - The shape (or shape id) to set as editing.\n\t *\n\t * @public\n\t */\n\tsetEditingShape(shape: TLShapeId | TLShape | null): this {\n\t\tconst id = typeof shape === 'string' ? shape : shape?.id ?? null\n\t\tif (id !== this.getEditingShapeId()) {\n\t\t\tif (id) {\n\t\t\t\tconst shape = this.getShape(id)\n\t\t\t\tif (shape && this.getShapeUtil(shape).canEdit(shape)) {\n\t\t\t\t\tthis.run(\n\t\t\t\t\t\t() => {\n\t\t\t\t\t\t\tthis._updateCurrentPageState({ editingShapeId: id })\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{ history: 'ignore' }\n\t\t\t\t\t)\n\t\t\t\t\treturn this\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Either we just set the editing id to null, or the shape was missing or not editable\n\t\t\tthis.run(\n\t\t\t\t() => {\n\t\t\t\t\tthis._updateCurrentPageState({ editingShapeId: null })\n\t\t\t\t},\n\t\t\t\t{ history: 'ignore' }\n\t\t\t)\n\t\t}\n\t\treturn this\n\t}\n\n\t// Hovered\n\n\t/**\n\t * The current hovered shape id.\n\t *\n\t * @readonly\n\t * @public\n\t */\n\t@computed getHoveredShapeId(): TLShapeId | null {\n\t\treturn this.getCurrentPageState().hoveredShapeId\n\t}\n\n\t/**\n\t * The current hovered shape.\n\t *\n\t * @public\n\t */\n\t@computed getHoveredShape(): TLShape | undefined {\n\t\tconst hoveredShapeId = this.getHoveredShapeId()\n\t\treturn hoveredShapeId ? this.getShape(hoveredShapeId) : undefined\n\t}\n\t/**\n\t * Set the editor's current hovered shape.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.setHoveredShape(myShape)\n\t * editor.setHoveredShape(myShape.id)\n\t * ```\n\t *\n\t * @param shape - The shape (or shape id) to set as hovered.\n\t *\n\t * @public\n\t */\n\tsetHoveredShape(shape: TLShapeId | TLShape | null): this {\n\t\tconst id = typeof shape === 'string' ? shape : shape?.id ?? null\n\t\tif (id === this.getHoveredShapeId()) return this\n\t\tthis.run(\n\t\t\t() => {\n\t\t\t\tthis.updateCurrentPageState({ hoveredShapeId: id })\n\t\t\t},\n\t\t\t{ history: 'ignore' }\n\t\t)\n\t\treturn this\n\t}\n\n\t// Hinting\n\n\t/**\n\t * The editor's current hinting shape ids.\n\t *\n\t * @public\n\t */\n\t@computed getHintingShapeIds() {\n\t\treturn this.getCurrentPageState().hintingShapeIds\n\t}\n\t/**\n\t * The editor's current hinting shapes.\n\t *\n\t * @public\n\t */\n\t@computed getHintingShape() {\n\t\tconst hintingShapeIds = this.getHintingShapeIds()\n\t\treturn compact(hintingShapeIds.map((id) => this.getShape(id)))\n\t}\n\n\t/**\n\t * Set the editor's current hinting shapes.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.setHintingShapes([myShape])\n\t * editor.setHintingShapes([myShape.id])\n\t * ```\n\t *\n\t * @param shapes - The shapes (or shape ids) to set as hinting.\n\t *\n\t * @public\n\t */\n\tsetHintingShapes(shapes: TLShapeId[] | TLShape[]): this {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((shape) => shape.id)\n\t\t// always ephemeral\n\t\tthis.run(\n\t\t\t() => {\n\t\t\t\tthis._updateCurrentPageState({ hintingShapeIds: dedupe(ids) })\n\t\t\t},\n\t\t\t{ history: 'ignore' }\n\t\t)\n\t\treturn this\n\t}\n\n\t// Erasing\n\n\t/**\n\t * The editor's current erasing ids.\n\t *\n\t * @public\n\t */\n\t@computed getErasingShapeIds() {\n\t\treturn this.getCurrentPageState().erasingShapeIds\n\t}\n\n\t/**\n\t * The editor's current erasing shapes.\n\t *\n\t * @public\n\t */\n\t@computed getErasingShapes() {\n\t\tconst erasingShapeIds = this.getErasingShapeIds()\n\t\treturn compact(erasingShapeIds.map((id) => this.getShape(id)))\n\t}\n\n\t/**\n\t * Set the editor's current erasing shapes.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.setErasingShapes([myShape])\n\t * editor.setErasingShapes([myShape.id])\n\t * ```\n\t *\n\t * @param shapes - The shapes (or shape ids) to set as hinting.\n\t *\n\t * @public\n\t */\n\tsetErasingShapes(shapes: TLShapeId[] | TLShape[]): this {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((shape) => shape.id)\n\t\tids.sort() // sort the incoming ids\n\t\tconst erasingShapeIds = this.getErasingShapeIds()\n\t\tthis.run(\n\t\t\t() => {\n\t\t\t\tif (ids.length === erasingShapeIds.length) {\n\t\t\t\t\t// if the new ids are the same length as the current ids, they might be the same.\n\t\t\t\t\t// presuming the current ids are also sorted, check each item to see if it's the same;\n\t\t\t\t\t// if we find any unequal, then we know the new ids are different.\n\t\t\t\t\tfor (let i = 0; i < ids.length; i++) {\n\t\t\t\t\t\tif (ids[i] !== erasingShapeIds[i]) {\n\t\t\t\t\t\t\tthis._updateCurrentPageState({ erasingShapeIds: ids })\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t// if the ids are a different length, then we know they're different.\n\t\t\t\t\tthis._updateCurrentPageState({ erasingShapeIds: ids })\n\t\t\t\t}\n\t\t\t},\n\t\t\t{ history: 'ignore' }\n\t\t)\n\n\t\treturn this\n\t}\n\n\t// Cropping\n\n\t/**\n\t * The current cropping shape's id.\n\t *\n\t * @public\n\t */\n\tgetCroppingShapeId() {\n\t\treturn this.getCurrentPageState().croppingShapeId\n\t}\n\n\t/**\n\t * Set the current cropping shape.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.setCroppingShape(myShape)\n\t * editor.setCroppingShape(myShape.id)\n\t * ```\n\t *\n\t *\n\t * @param shape - The shape (or shape id) to set as cropping.\n\t *\n\t * @public\n\t */\n\tsetCroppingShape(shape: TLShapeId | TLShape | null): this {\n\t\tconst id = typeof shape === 'string' ? shape : shape?.id ?? null\n\t\tif (id !== this.getCroppingShapeId()) {\n\t\t\tthis.run(\n\t\t\t\t() => {\n\t\t\t\t\tif (!id) {\n\t\t\t\t\t\tthis.updateCurrentPageState({ croppingShapeId: null })\n\t\t\t\t\t} else {\n\t\t\t\t\t\tconst shape = this.getShape(id)!\n\t\t\t\t\t\tconst util = this.getShapeUtil(shape)\n\t\t\t\t\t\tif (shape && util.canCrop(shape)) {\n\t\t\t\t\t\t\tthis.updateCurrentPageState({ croppingShapeId: id })\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\t{ history: 'ignore' }\n\t\t\t)\n\t\t}\n\t\treturn this\n\t}\n\n\t/* --------------------- Camera --------------------- */\n\n\t/** @internal */\n\t@computed\n\tprivate _unsafe_getCameraId() {\n\t\treturn CameraRecordType.createId(this.getCurrentPageId())\n\t}\n\n\t/**\n\t * The current camera.\n\t *\n\t * @public\n\t */\n\t@computed getCamera(): TLCamera {\n\t\tconst baseCamera = this.store.get(this._unsafe_getCameraId())!\n\t\tif (this._isLockedOnFollowingUser.get()) {\n\t\t\tconst followingCamera = this.getCameraForFollowing()\n\t\t\tif (followingCamera) {\n\t\t\t\treturn { ...baseCamera, ...followingCamera }\n\t\t\t}\n\t\t}\n\t\treturn baseCamera\n\t}\n\n\t@computed\n\tprivate getViewportPageBoundsForFollowing(): null | Box {\n\t\tconst followingUserId = this.getInstanceState().followingUserId\n\t\tif (!followingUserId) return null\n\t\tconst leaderPresence = this.getCollaborators().find((c) => c.userId === followingUserId)\n\t\tif (!leaderPresence) return null\n\n\t\t// Fit their viewport inside of our screen bounds\n\t\t// 1. calculate their viewport in page space\n\t\tconst { w: lw, h: lh } = leaderPresence.screenBounds\n\t\tconst { x: lx, y: ly, z: lz } = leaderPresence.camera\n\t\tconst theirViewport = new Box(-lx, -ly, lw / lz, lh / lz)\n\n\t\t// resize our screenBounds to contain their viewport\n\t\tconst ourViewport = this.getViewportScreenBounds().clone()\n\t\tconst ourAspectRatio = ourViewport.width / ourViewport.height\n\n\t\tourViewport.width = theirViewport.width\n\t\tourViewport.height = ourViewport.width / ourAspectRatio\n\t\tif (ourViewport.height < theirViewport.height) {\n\t\t\tourViewport.height = theirViewport.height\n\t\t\tourViewport.width = ourViewport.height * ourAspectRatio\n\t\t}\n\n\t\tourViewport.center = theirViewport.center\n\t\treturn ourViewport\n\t}\n\n\t@computed\n\tprivate getCameraForFollowing(): null | { x: number; y: number; z: number } {\n\t\tconst viewport = this.getViewportPageBoundsForFollowing()\n\t\tif (!viewport) return null\n\n\t\treturn {\n\t\t\tx: -viewport.x,\n\t\t\ty: -viewport.y,\n\t\t\tz: this.getViewportScreenBounds().w / viewport.width,\n\t\t}\n\t}\n\n\t/**\n\t * The current camera zoom level.\n\t *\n\t * @public\n\t */\n\t@computed getZoomLevel() {\n\t\treturn this.getCamera().z\n\t}\n\n\t/**\n\t * Get the camera's initial or reset zoom level.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getInitialZoom()\n\t * ```\n\t *\n\t * @public */\n\tgetInitialZoom() {\n\t\tconst cameraOptions = this.getCameraOptions()\n\t\t// If no camera constraints are provided, the default zoom is 100%\n\t\tif (!cameraOptions.constraints) return 1\n\n\t\t// When defaultZoom is default, the default zoom is 100%\n\t\tif (cameraOptions.constraints.initialZoom === 'default') return 1\n\n\t\tconst { zx, zy } = getCameraFitXFitY(this, cameraOptions)\n\n\t\tswitch (cameraOptions.constraints.initialZoom) {\n\t\t\tcase 'fit-min': {\n\t\t\t\treturn Math.max(zx, zy)\n\t\t\t}\n\t\t\tcase 'fit-max': {\n\t\t\t\treturn Math.min(zx, zy)\n\t\t\t}\n\t\t\tcase 'fit-x': {\n\t\t\t\treturn zx\n\t\t\t}\n\t\t\tcase 'fit-y': {\n\t\t\t\treturn zy\n\t\t\t}\n\t\t\tcase 'fit-min-100': {\n\t\t\t\treturn Math.min(1, Math.max(zx, zy))\n\t\t\t}\n\t\t\tcase 'fit-max-100': {\n\t\t\t\treturn Math.min(1, Math.min(zx, zy))\n\t\t\t}\n\t\t\tcase 'fit-x-100': {\n\t\t\t\treturn Math.min(1, zx)\n\t\t\t}\n\t\t\tcase 'fit-y-100': {\n\t\t\t\treturn Math.min(1, zy)\n\t\t\t}\n\t\t\tdefault: {\n\t\t\t\tthrow exhaustiveSwitchError(cameraOptions.constraints.initialZoom)\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Get the camera's base level for calculating actual zoom levels based on the zoom steps.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getBaseZoom()\n\t * ```\n\t *\n\t * @public */\n\tgetBaseZoom() {\n\t\tconst cameraOptions = this.getCameraOptions()\n\t\t// If no camera constraints are provided, the default zoom is 100%\n\t\tif (!cameraOptions.constraints) return 1\n\n\t\t// When defaultZoom is default, the default zoom is 100%\n\t\tif (cameraOptions.constraints.baseZoom === 'default') return 1\n\n\t\tconst { zx, zy } = getCameraFitXFitY(this, cameraOptions)\n\n\t\tswitch (cameraOptions.constraints.baseZoom) {\n\t\t\tcase 'fit-min': {\n\t\t\t\treturn Math.max(zx, zy)\n\t\t\t}\n\t\t\tcase 'fit-max': {\n\t\t\t\treturn Math.min(zx, zy)\n\t\t\t}\n\t\t\tcase 'fit-x': {\n\t\t\t\treturn zx\n\t\t\t}\n\t\t\tcase 'fit-y': {\n\t\t\t\treturn zy\n\t\t\t}\n\t\t\tcase 'fit-min-100': {\n\t\t\t\treturn Math.min(1, Math.max(zx, zy))\n\t\t\t}\n\t\t\tcase 'fit-max-100': {\n\t\t\t\treturn Math.min(1, Math.min(zx, zy))\n\t\t\t}\n\t\t\tcase 'fit-x-100': {\n\t\t\t\treturn Math.min(1, zx)\n\t\t\t}\n\t\t\tcase 'fit-y-100': {\n\t\t\t\treturn Math.min(1, zy)\n\t\t\t}\n\t\t\tdefault: {\n\t\t\t\tthrow exhaustiveSwitchError(cameraOptions.constraints.baseZoom)\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate _cameraOptions = atom('camera options', DEFAULT_CAMERA_OPTIONS)\n\n\t/**\n\t * Get the current camera options.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getCameraOptions()\n\t * ```\n\t *\n\t * @public */\n\tgetCameraOptions() {\n\t\treturn this._cameraOptions.get()\n\t}\n\n\t/**\n\t * Set the camera options. Changing the options won't immediately change the camera itself, so you may want to call `setCamera` after changing the options.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.setCameraOptions(myCameraOptions)\n\t * editor.setCamera(editor.getCamera())\n\t * ```\n\t *\n\t * @param opts - The camera options to set.\n\t *\n\t * @public */\n\tsetCameraOptions(opts: Partial) {\n\t\tconst next = structuredClone({\n\t\t\t...this._cameraOptions.__unsafe__getWithoutCapture(),\n\t\t\t...opts,\n\t\t})\n\t\tif (next.zoomSteps?.length < 1) next.zoomSteps = [1]\n\t\tthis._cameraOptions.set(next)\n\t\tthis.setCamera(this.getCamera())\n\t\treturn this\n\t}\n\n\t/** @internal */\n\tprivate getConstrainedCamera(\n\t\tpoint: VecLike,\n\t\topts?: TLCameraMoveOptions\n\t): {\n\t\tx: number\n\t\ty: number\n\t\tz: number\n\t} {\n\t\tconst currentCamera = this.getCamera()\n\n\t\tlet { x, y, z = currentCamera.z } = point\n\n\t\t// If force is true, then we'll set the camera to the point regardless of\n\t\t// the camera options, so that we can handle gestures that permit elasticity\n\t\t// or decay, or animations that occur while the camera is locked.\n\t\tif (!opts?.force) {\n\t\t\t// Apply any adjustments based on the camera options\n\n\t\t\tconst cameraOptions = this.getCameraOptions()\n\n\t\t\tconst zoomMin = cameraOptions.zoomSteps[0]\n\t\t\tconst zoomMax = last(cameraOptions.zoomSteps)!\n\n\t\t\tconst vsb = this.getViewportScreenBounds()\n\n\t\t\t// If bounds are provided, then we'll keep those bounds on screen\n\t\t\tif (cameraOptions.constraints) {\n\t\t\t\tconst { constraints } = cameraOptions\n\n\t\t\t\t// Clamp padding to half the viewport size on either dimension\n\t\t\t\tconst py = Math.min(constraints.padding.y, vsb.w / 2)\n\t\t\t\tconst px = Math.min(constraints.padding.x, vsb.h / 2)\n\n\t\t\t\t// Expand the bounds by the padding\n\t\t\t\tconst bounds = Box.From(cameraOptions.constraints.bounds)\n\n\t\t\t\t// For each axis, the \"natural zoom\" is the zoom at\n\t\t\t\t// which the expanded bounds (with padding) would fit\n\t\t\t\t// the current viewport screen bounds. Paddings are\n\t\t\t\t// equal to screen pixels at 100%\n\t\t\t\t// The min and max zooms are factors of the smaller natural zoom axis\n\n\t\t\t\tconst zx = (vsb.w - px * 2) / bounds.w\n\t\t\t\tconst zy = (vsb.h - py * 2) / bounds.h\n\n\t\t\t\tconst baseZoom = this.getBaseZoom()\n\t\t\t\tconst maxZ = zoomMax * baseZoom\n\t\t\t\tconst minZ = zoomMin * baseZoom\n\n\t\t\t\tif (opts?.reset) {\n\t\t\t\t\tz = this.getInitialZoom()\n\t\t\t\t}\n\n\t\t\t\tif (z < minZ || z > maxZ) {\n\t\t\t\t\t// We're trying to zoom out past the minimum zoom level,\n\t\t\t\t\t// or in past the maximum zoom level, so stop the camera\n\t\t\t\t\t// but keep the current center\n\t\t\t\t\tconst { x: cx, y: cy, z: cz } = currentCamera\n\t\t\t\t\tconst cxA = -cx + vsb.w / cz / 2\n\t\t\t\t\tconst cyA = -cy + vsb.h / cz / 2\n\t\t\t\t\tz = clamp(z, minZ, maxZ)\n\t\t\t\t\tconst cxB = -cx + vsb.w / z / 2\n\t\t\t\t\tconst cyB = -cy + vsb.h / z / 2\n\t\t\t\t\tx = cx + cxB - cxA\n\t\t\t\t\ty = cy + cyB - cyA\n\t\t\t\t}\n\n\t\t\t\t// Calculate available space\n\t\t\t\tconst minX = px / z - bounds.x\n\t\t\t\tconst minY = py / z - bounds.y\n\t\t\t\tconst freeW = (vsb.w - px * 2) / z - bounds.w\n\t\t\t\tconst freeH = (vsb.h - py * 2) / z - bounds.h\n\t\t\t\tconst originX = minX + freeW * constraints.origin.x\n\t\t\t\tconst originY = minY + freeH * constraints.origin.y\n\n\t\t\t\tconst behaviorX =\n\t\t\t\t\ttypeof constraints.behavior === 'string' ? constraints.behavior : constraints.behavior.x\n\t\t\t\tconst behaviorY =\n\t\t\t\t\ttypeof constraints.behavior === 'string' ? constraints.behavior : constraints.behavior.y\n\n\t\t\t\t// x axis\n\n\t\t\t\tif (opts?.reset) {\n\t\t\t\t\t// Reset the camera according to the origin\n\t\t\t\t\tx = originX\n\t\t\t\t\ty = originY\n\t\t\t\t} else {\n\t\t\t\t\t// Apply constraints to the camera\n\t\t\t\t\tswitch (behaviorX) {\n\t\t\t\t\t\tcase 'fixed': {\n\t\t\t\t\t\t\t// Center according to the origin\n\t\t\t\t\t\t\tx = originX\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcase 'contain': {\n\t\t\t\t\t\t\t// When below fit zoom, center the camera\n\t\t\t\t\t\t\tif (z < zx) x = originX\n\t\t\t\t\t\t\t// When above fit zoom, keep the bounds within padding distance of the viewport edge\n\t\t\t\t\t\t\telse x = clamp(x, minX + freeW, minX)\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcase 'inside': {\n\t\t\t\t\t\t\t// When below fit zoom, constrain the camera so that the bounds stay completely within the viewport\n\t\t\t\t\t\t\tif (z < zx) x = clamp(x, minX, (vsb.w - px) / z - bounds.w)\n\t\t\t\t\t\t\t// When above fit zoom, keep the bounds within padding distance of the viewport edge\n\t\t\t\t\t\t\telse x = clamp(x, minX + freeW, minX)\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcase 'outside': {\n\t\t\t\t\t\t\t// Constrain the camera so that the bounds never leaves the viewport\n\t\t\t\t\t\t\tx = clamp(x, px / z - bounds.w, (vsb.w - px) / z)\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcase 'free': {\n\t\t\t\t\t\t\t// noop, use whatever x is provided\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t\tdefault: {\n\t\t\t\t\t\t\tthrow exhaustiveSwitchError(behaviorX)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// y axis\n\n\t\t\t\t\tswitch (behaviorY) {\n\t\t\t\t\t\tcase 'fixed': {\n\t\t\t\t\t\t\ty = originY\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcase 'contain': {\n\t\t\t\t\t\t\tif (z < zy) y = originY\n\t\t\t\t\t\t\telse y = clamp(y, minY + freeH, minY)\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcase 'inside': {\n\t\t\t\t\t\t\tif (z < zy) y = clamp(y, minY, (vsb.h - py) / z - bounds.h)\n\t\t\t\t\t\t\telse y = clamp(y, minY + freeH, minY)\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcase 'outside': {\n\t\t\t\t\t\t\ty = clamp(y, py / z - bounds.h, (vsb.h - py) / z)\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcase 'free': {\n\t\t\t\t\t\t\t// noop, use whatever x is provided\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t\tdefault: {\n\t\t\t\t\t\t\tthrow exhaustiveSwitchError(behaviorY)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// constrain the zoom, preserving the center\n\t\t\t\tif (z > zoomMax || z < zoomMin) {\n\t\t\t\t\tconst { x: cx, y: cy, z: cz } = currentCamera\n\t\t\t\t\tz = clamp(z, zoomMin, zoomMax)\n\t\t\t\t\tx = cx + (-cx + vsb.w / z / 2) - (-cx + vsb.w / cz / 2)\n\t\t\t\t\ty = cy + (-cy + vsb.h / z / 2) - (-cy + vsb.h / cz / 2)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn { x, y, z }\n\t}\n\n\t/** @internal */\n\tprivate _setCamera(point: VecLike, opts?: TLCameraMoveOptions): this {\n\t\tconst currentCamera = this.getCamera()\n\n\t\tconst { x, y, z } = this.getConstrainedCamera(point, opts)\n\n\t\tif (currentCamera.x === x && currentCamera.y === y && currentCamera.z === z) {\n\t\t\treturn this\n\t\t}\n\n\t\ttransact(() => {\n\t\t\tconst camera = { ...currentCamera, x, y, z }\n\t\t\tthis.run(\n\t\t\t\t() => {\n\t\t\t\t\tthis.store.put([camera]) // include id and meta here\n\t\t\t\t},\n\t\t\t\t{ history: 'ignore' }\n\t\t\t)\n\n\t\t\t// Dispatch a new pointer move because the pointer's page will have changed\n\t\t\t// (its screen position will compute to a new page position given the new camera position)\n\t\t\tconst { currentScreenPoint, currentPagePoint } = this.inputs\n\t\t\tconst { screenBounds } = this.store.unsafeGetWithoutCapture(TLINSTANCE_ID)!\n\n\t\t\t// compare the next page point (derived from the current camera) to the current page point\n\t\t\tif (\n\t\t\t\tcurrentScreenPoint.x / z - x !== currentPagePoint.x ||\n\t\t\t\tcurrentScreenPoint.y / z - y !== currentPagePoint.y\n\t\t\t) {\n\t\t\t\t// If it's changed, dispatch a pointer event\n\t\t\t\tconst event: TLPointerEventInfo = {\n\t\t\t\t\ttype: 'pointer',\n\t\t\t\t\ttarget: 'canvas',\n\t\t\t\t\tname: 'pointer_move',\n\t\t\t\t\t// weird but true: we need to put the screen point back into client space\n\t\t\t\t\tpoint: Vec.AddXY(currentScreenPoint, screenBounds.x, screenBounds.y),\n\t\t\t\t\tpointerId: INTERNAL_POINTER_IDS.CAMERA_MOVE,\n\t\t\t\t\tctrlKey: this.inputs.ctrlKey,\n\t\t\t\t\taltKey: this.inputs.altKey,\n\t\t\t\t\tshiftKey: this.inputs.shiftKey,\n\t\t\t\t\tmetaKey: this.inputs.metaKey,\n\t\t\t\t\taccelKey: isAccelKey(this.inputs),\n\t\t\t\t\tbutton: 0,\n\t\t\t\t\tisPen: this.getInstanceState().isPenMode ?? false,\n\t\t\t\t}\n\n\t\t\t\tif (opts?.immediate) {\n\t\t\t\t\tthis._flushEventForTick(event)\n\t\t\t\t} else {\n\t\t\t\t\tthis.dispatch(event)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tthis._tickCameraState()\n\t\t})\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Set the current camera.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.setCamera({ x: 0, y: 0})\n\t * editor.setCamera({ x: 0, y: 0, z: 1.5})\n\t * editor.setCamera({ x: 0, y: 0, z: 1.5}, { animation: { duration: 1000, easing: (t) => t * t } })\n\t * ```\n\t *\n\t * @param point - The new camera position.\n\t * @param opts - The camera move options.\n\t *\n\t * @public\n\t */\n\tsetCamera(point: VecLike, opts?: TLCameraMoveOptions): this {\n\t\tconst { isLocked } = this._cameraOptions.__unsafe__getWithoutCapture()\n\t\tif (isLocked && !opts?.force) return this\n\n\t\t// Stop any camera animations\n\t\tthis.stopCameraAnimation()\n\n\t\t// Stop following any user\n\t\tif (this.getInstanceState().followingUserId) {\n\t\t\tthis.stopFollowingUser()\n\t\t}\n\n\t\tconst _point = Vec.Cast(point)\n\n\t\tif (!Number.isFinite(_point.x)) _point.x = 0\n\t\tif (!Number.isFinite(_point.y)) _point.y = 0\n\t\tif (_point.z === undefined || !Number.isFinite(_point.z)) point.z = this.getZoomLevel()\n\n\t\tconst camera = this.getConstrainedCamera(_point, opts)\n\n\t\tif (opts?.animation) {\n\t\t\tconst { width, height } = this.getViewportScreenBounds()\n\t\t\tthis._animateToViewport(\n\t\t\t\tnew Box(-camera.x, -camera.y, width / camera.z, height / camera.z),\n\t\t\t\topts\n\t\t\t)\n\t\t} else {\n\t\t\tthis._setCamera(camera, {\n\t\t\t\t...opts,\n\t\t\t\t// we already did the constraining, so we don't need to do it again\n\t\t\t\tforce: true,\n\t\t\t})\n\t\t}\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Center the camera on a point (in the current page space).\n\t *\n\t * @example\n\t * ```ts\n\t * editor.centerOnPoint({ x: 100, y: 100 })\n\t * editor.centerOnPoint({ x: 100, y: 100 }, { animation: { duration: 200 } })\n\t * ```\n\t *\n\t * @param point - The point in the current page space to center on.\n\t * @param opts - The camera move options.\n\t *\n\t * @public\n\t */\n\tcenterOnPoint(point: VecLike, opts?: TLCameraMoveOptions): this {\n\t\tconst { isLocked } = this.getCameraOptions()\n\t\tif (isLocked && !opts?.force) return this\n\n\t\tconst { width: pw, height: ph } = this.getViewportPageBounds()\n\t\tthis.setCamera(new Vec(-(point.x - pw / 2), -(point.y - ph / 2), this.getCamera().z), opts)\n\t\treturn this\n\t}\n\n\t/**\n\t * Zoom the camera to fit the current page's content in the viewport.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.zoomToFit()\n\t * editor.zoomToFit({ animation: { duration: 200 } })\n\t * ```\n\t *\n\t * @param opts - The camera move options.\n\t *\n\t * @public\n\t */\n\tzoomToFit(opts?: TLCameraMoveOptions): this {\n\t\tconst ids = [...this.getCurrentPageShapeIds()]\n\t\tif (ids.length <= 0) return this\n\t\tconst pageBounds = Box.Common(compact(ids.map((id) => this.getShapePageBounds(id))))\n\t\tthis.zoomToBounds(pageBounds, opts)\n\t\treturn this\n\t}\n\n\t/**\n\t * Set the zoom back to 100%.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.resetZoom()\n\t * editor.resetZoom(editor.getViewportScreenCenter(), { animation: { duration: 200 } })\n\t * editor.resetZoom(editor.getViewportScreenCenter(), { animation: { duration: 200 } })\n\t * ```\n\t *\n\t * @param point - The screen point to zoom out on. Defaults to the viewport screen center.\n\t * @param opts - The camera move options.\n\t *\n\t * @public\n\t */\n\tresetZoom(point = this.getViewportScreenCenter(), opts?: TLCameraMoveOptions): this {\n\t\tconst { isLocked, constraints: constraints } = this.getCameraOptions()\n\t\tif (isLocked && !opts?.force) return this\n\n\t\tconst currentCamera = this.getCamera()\n\t\tconst { x: cx, y: cy, z: cz } = currentCamera\n\t\tconst { x, y } = point\n\n\t\tlet z = 1\n\n\t\tif (constraints) {\n\t\t\t// For non-infinite fit, we'll set the camera to the natural zoom level...\n\t\t\t// unless it's already there, in which case we'll set zoom to 100%\n\t\t\tconst initialZoom = this.getInitialZoom()\n\t\t\tif (cz !== initialZoom) {\n\t\t\t\tz = initialZoom\n\t\t\t}\n\t\t}\n\n\t\tthis.setCamera(\n\t\t\tnew Vec(cx + (x / z - x) - (x / cz - x), cy + (y / z - y) - (y / cz - y), z),\n\t\t\topts\n\t\t)\n\t\treturn this\n\t}\n\n\t/**\n\t * Zoom the camera in.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.zoomIn()\n\t * editor.zoomIn(editor.getViewportScreenCenter(), { animation: { duration: 200 } })\n\t * editor.zoomIn(editor.inputs.currentScreenPoint, { animation: { duration: 200 } })\n\t * ```\n\t *\n\t * @param point - The screen point to zoom in on. Defaults to the screen center\n\t * @param opts - The camera move options.\n\t *\n\t * @public\n\t */\n\tzoomIn(point = this.getViewportScreenCenter(), opts?: TLCameraMoveOptions): this {\n\t\tconst { isLocked } = this.getCameraOptions()\n\t\tif (isLocked && !opts?.force) return this\n\n\t\tconst { x: cx, y: cy, z: cz } = this.getCamera()\n\n\t\tconst { zoomSteps } = this.getCameraOptions()\n\t\tif (zoomSteps !== null && zoomSteps.length > 1) {\n\t\t\tconst baseZoom = this.getBaseZoom()\n\t\t\tlet zoom = last(zoomSteps)! * baseZoom\n\t\t\tfor (let i = 1; i < zoomSteps.length; i++) {\n\t\t\t\tconst z1 = zoomSteps[i - 1] * baseZoom\n\t\t\t\tconst z2 = zoomSteps[i] * baseZoom\n\t\t\t\tif (z2 - cz <= (z2 - z1) / 2) continue\n\t\t\t\tzoom = z2\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tthis.setCamera(\n\t\t\t\tnew Vec(\n\t\t\t\t\tcx + (point.x / zoom - point.x) - (point.x / cz - point.x),\n\t\t\t\t\tcy + (point.y / zoom - point.y) - (point.y / cz - point.y),\n\t\t\t\t\tzoom\n\t\t\t\t),\n\t\t\t\topts\n\t\t\t)\n\t\t}\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Zoom the camera out.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.zoomOut()\n\t * editor.zoomOut(editor.getViewportScreenCenter(), { animation: { duration: 120 } })\n\t * editor.zoomOut(editor.inputs.currentScreenPoint, { animation: { duration: 120 } })\n\t * ```\n\t *\n\t * @param point - The point to zoom out on. Defaults to the viewport screen center.\n\t * @param opts - The camera move options.\n\t *\n\t * @public\n\t */\n\tzoomOut(point = this.getViewportScreenCenter(), opts?: TLCameraMoveOptions): this {\n\t\tconst { isLocked } = this.getCameraOptions()\n\t\tif (isLocked && !opts?.force) return this\n\n\t\tconst { zoomSteps } = this.getCameraOptions()\n\t\tif (zoomSteps !== null && zoomSteps.length > 1) {\n\t\t\tconst baseZoom = this.getBaseZoom()\n\t\t\tconst { x: cx, y: cy, z: cz } = this.getCamera()\n\t\t\t// start at the max\n\t\t\tlet zoom = zoomSteps[0] * baseZoom\n\t\t\tfor (let i = zoomSteps.length - 1; i > 0; i--) {\n\t\t\t\tconst z1 = zoomSteps[i - 1] * baseZoom\n\t\t\t\tconst z2 = zoomSteps[i] * baseZoom\n\t\t\t\tif (z2 - cz >= (z2 - z1) / 2) continue\n\t\t\t\tzoom = z1\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tthis.setCamera(\n\t\t\t\tnew Vec(\n\t\t\t\t\tcx + (point.x / zoom - point.x) - (point.x / cz - point.x),\n\t\t\t\t\tcy + (point.y / zoom - point.y) - (point.y / cz - point.y),\n\t\t\t\t\tzoom\n\t\t\t\t),\n\t\t\t\topts\n\t\t\t)\n\t\t}\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Zoom the camera to fit the current selection in the viewport.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.zoomToSelection()\n\t * editor.zoomToSelection({ animation: { duration: 200 } })\n\t * ```\n\t *\n\t * @param opts - The camera move options.\n\t *\n\t * @public\n\t */\n\tzoomToSelection(opts?: TLCameraMoveOptions): this {\n\t\tconst { isLocked } = this.getCameraOptions()\n\t\tif (isLocked && !opts?.force) return this\n\n\t\tconst selectionPageBounds = this.getSelectionPageBounds()\n\t\tif (selectionPageBounds) {\n\t\t\tthis.zoomToBounds(selectionPageBounds, {\n\t\t\t\ttargetZoom: Math.max(1, this.getZoomLevel()),\n\t\t\t\t...opts,\n\t\t\t})\n\t\t}\n\t\treturn this\n\t}\n\n\t/**\n\t * Zoom the camera to fit a bounding box (in the current page space).\n\t *\n\t * @example\n\t * ```ts\n\t * editor.zoomToBounds(myBounds)\n\t * editor.zoomToBounds(myBounds, { animation: { duration: 200 } })\n\t * editor.zoomToBounds(myBounds, { animation: { duration: 200 }, inset: 0, targetZoom: 1 })\n\t * ```\n\t *\n\t * @param bounds - The bounding box.\n\t * @param opts - The camera move options, target zoom, or custom inset amount.\n\t *\n\t * @public\n\t */\n\tzoomToBounds(\n\t\tbounds: BoxLike,\n\t\topts?: { targetZoom?: number; inset?: number } & TLCameraMoveOptions\n\t): this {\n\t\tconst cameraOptions = this._cameraOptions.__unsafe__getWithoutCapture()\n\t\tif (cameraOptions.isLocked && !opts?.force) return this\n\n\t\tconst viewportScreenBounds = this.getViewportScreenBounds()\n\n\t\tconst inset = opts?.inset ?? Math.min(ZOOM_TO_FIT_PADDING, viewportScreenBounds.width * 0.28)\n\n\t\tconst baseZoom = this.getBaseZoom()\n\t\tconst zoomMin = cameraOptions.zoomSteps[0]\n\t\tconst zoomMax = last(cameraOptions.zoomSteps)!\n\n\t\tlet zoom = clamp(\n\t\t\tMath.min(\n\t\t\t\t(viewportScreenBounds.width - inset) / bounds.w,\n\t\t\t\t(viewportScreenBounds.height - inset) / bounds.h\n\t\t\t),\n\t\t\tzoomMin * baseZoom,\n\t\t\tzoomMax * baseZoom\n\t\t)\n\n\t\tif (opts?.targetZoom !== undefined) {\n\t\t\tzoom = Math.min(opts.targetZoom, zoom)\n\t\t}\n\n\t\tthis.setCamera(\n\t\t\tnew Vec(\n\t\t\t\t-bounds.x + (viewportScreenBounds.width - bounds.w * zoom) / 2 / zoom,\n\t\t\t\t-bounds.y + (viewportScreenBounds.height - bounds.h * zoom) / 2 / zoom,\n\t\t\t\tzoom\n\t\t\t),\n\t\t\topts\n\t\t)\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Stop the current camera animation, if any.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.stopCameraAnimation()\n\t * ```\n\t *\n\t * @public\n\t */\n\tstopCameraAnimation(): this {\n\t\tthis.emit('stop-camera-animation')\n\t\treturn this\n\t}\n\n\t/** @internal */\n\tprivate _viewportAnimation = null as null | {\n\t\telapsed: number\n\t\tduration: number\n\t\teasing(t: number): number\n\t\tstart: Box\n\t\tend: Box\n\t}\n\n\t/** @internal */\n\tprivate _animateViewport(ms: number): void {\n\t\tif (!this._viewportAnimation) return\n\n\t\tthis._viewportAnimation.elapsed += ms\n\n\t\tconst { elapsed, easing, duration, start, end } = this._viewportAnimation\n\n\t\tif (elapsed > duration) {\n\t\t\tthis.off('tick', this._animateViewport)\n\t\t\tthis._viewportAnimation = null\n\t\t\tthis._setCamera(new Vec(-end.x, -end.y, this.getViewportScreenBounds().width / end.width))\n\t\t\treturn\n\t\t}\n\n\t\tconst remaining = duration - elapsed\n\t\tconst t = easing(1 - remaining / duration)\n\n\t\tconst left = start.minX + (end.minX - start.minX) * t\n\t\tconst top = start.minY + (end.minY - start.minY) * t\n\t\tconst right = start.maxX + (end.maxX - start.maxX) * t\n\n\t\tthis._setCamera(new Vec(-left, -top, this.getViewportScreenBounds().width / (right - left)), {\n\t\t\tforce: true,\n\t\t})\n\t}\n\n\t/** @internal */\n\tprivate _animateToViewport(\n\t\ttargetViewportPage: Box,\n\t\topts = { animation: DEFAULT_ANIMATION_OPTIONS } as TLCameraMoveOptions\n\t) {\n\t\tconst { animation, ...rest } = opts\n\t\tif (!animation) return\n\t\tconst { duration = 0, easing = EASINGS.easeInOutCubic } = animation\n\t\tconst animationSpeed = this.user.getAnimationSpeed()\n\t\tconst viewportPageBounds = this.getViewportPageBounds()\n\n\t\t// If we have an existing animation, then stop it\n\t\tthis.stopCameraAnimation()\n\n\t\t// also stop following any user\n\t\tif (this.getInstanceState().followingUserId) {\n\t\t\tthis.stopFollowingUser()\n\t\t}\n\n\t\tif (duration === 0 || animationSpeed === 0) {\n\t\t\t// If we have no animation, then skip the animation and just set the camera\n\t\t\treturn this._setCamera(\n\t\t\t\tnew Vec(\n\t\t\t\t\t-targetViewportPage.x,\n\t\t\t\t\t-targetViewportPage.y,\n\t\t\t\t\tthis.getViewportScreenBounds().width / targetViewportPage.width\n\t\t\t\t),\n\t\t\t\t{ ...rest }\n\t\t\t)\n\t\t}\n\n\t\t// Set our viewport animation\n\t\tthis._viewportAnimation = {\n\t\t\telapsed: 0,\n\t\t\tduration: duration / animationSpeed,\n\t\t\teasing,\n\t\t\tstart: viewportPageBounds.clone(),\n\t\t\tend: targetViewportPage.clone(),\n\t\t}\n\n\t\t// If we ever get a \"stop-camera-animation\" event, we stop\n\t\tthis.once('stop-camera-animation', () => {\n\t\t\tthis.off('tick', this._animateViewport)\n\t\t\tthis._viewportAnimation = null\n\t\t})\n\n\t\t// On each tick, animate the viewport\n\t\tthis.on('tick', this._animateViewport)\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Slide the camera in a certain direction.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.slideCamera({ speed: 1, direction: { x: 1, y: 0 }, friction: 0.1 })\n\t * ```\n\t *\n\t * @param opts - Options for the slide\n\t * @public\n\t */\n\tslideCamera(\n\t\topts = {} as {\n\t\t\tspeed: number\n\t\t\tdirection: VecLike\n\t\t\tfriction?: number\n\t\t\tspeedThreshold?: number\n\t\t\tforce?: boolean\n\t\t}\n\t): this {\n\t\tconst { isLocked } = this.getCameraOptions()\n\t\tif (isLocked && !opts?.force) return this\n\n\t\tconst animationSpeed = this.user.getAnimationSpeed()\n\t\tif (animationSpeed === 0) return this\n\n\t\tthis.stopCameraAnimation()\n\n\t\tconst {\n\t\t\tspeed,\n\t\t\tfriction = this.options.cameraSlideFriction,\n\t\t\tdirection,\n\t\t\tspeedThreshold = 0.01,\n\t\t} = opts\n\t\tlet currentSpeed = Math.min(speed, 1)\n\n\t\tconst cancel = () => {\n\t\t\tthis.off('tick', moveCamera)\n\t\t\tthis.off('stop-camera-animation', cancel)\n\t\t}\n\n\t\tthis.once('stop-camera-animation', cancel)\n\n\t\tconst moveCamera = (elapsed: number) => {\n\t\t\tconst { x: cx, y: cy, z: cz } = this.getCamera()\n\t\t\tconst movementVec = Vec.Mul(direction, (currentSpeed * elapsed) / cz)\n\n\t\t\t// Apply friction\n\t\t\tcurrentSpeed *= 1 - friction\n\t\t\tif (currentSpeed < speedThreshold) {\n\t\t\t\tcancel()\n\t\t\t} else {\n\t\t\t\tthis._setCamera(new Vec(cx + movementVec.x, cy + movementVec.y, cz))\n\t\t\t}\n\t\t}\n\n\t\tthis.on('tick', moveCamera)\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Animate the camera to a user's cursor position. This also briefly show the user's cursor if it's not currently visible.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.zoomToUser(myUserId)\n\t * editor.zoomToUser(myUserId, { animation: { duration: 200 } })\n\t * ```\n\t *\n\t * @param userId - The id of the user to animate to.\n\t * @param opts - The camera move options.\n\t * @public\n\t */\n\tzoomToUser(userId: string, opts: TLCameraMoveOptions = { animation: { duration: 500 } }): this {\n\t\tconst presence = this.getCollaborators().find((c) => c.userId === userId)\n\n\t\tif (!presence) return this\n\n\t\tthis.run(() => {\n\t\t\t// If we're following someone, stop following them\n\t\t\tif (this.getInstanceState().followingUserId !== null) {\n\t\t\t\tthis.stopFollowingUser()\n\t\t\t}\n\n\t\t\t// If we're not on the same page, move to the page they're on\n\t\t\tconst isOnSamePage = presence.currentPageId === this.getCurrentPageId()\n\t\t\tif (!isOnSamePage) {\n\t\t\t\tthis.setCurrentPage(presence.currentPageId)\n\t\t\t}\n\n\t\t\t// Only animate the camera if the user is on the same page as us\n\t\t\tif (opts && opts.animation && !isOnSamePage) {\n\t\t\t\topts.animation = undefined\n\t\t\t}\n\n\t\t\tthis.centerOnPoint(presence.cursor, opts)\n\n\t\t\t// Highlight the user's cursor\n\t\t\tconst { highlightedUserIds } = this.getInstanceState()\n\t\t\tthis.updateInstanceState({ highlightedUserIds: [...highlightedUserIds, userId] })\n\n\t\t\t// Unhighlight the user's cursor after a few seconds\n\t\t\tthis.timers.setTimeout(() => {\n\t\t\t\tconst highlightedUserIds = [...this.getInstanceState().highlightedUserIds]\n\t\t\t\tconst index = highlightedUserIds.indexOf(userId)\n\t\t\t\tif (index < 0) return\n\t\t\t\thighlightedUserIds.splice(index, 1)\n\t\t\t\tthis.updateInstanceState({ highlightedUserIds })\n\t\t\t}, this.options.collaboratorIdleTimeoutMs)\n\t\t})\n\n\t\treturn this\n\t}\n\n\t// Viewport\n\n\t/** @internal */\n\tprivate _willSetInitialBounds = true\n\n\t/**\n\t * Update the viewport. The viewport will measure the size and screen position of its container\n\t * element. This should be done whenever the container's position on the screen changes.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.updateViewportScreenBounds(new Box(0, 0, 1280, 1024))\n\t * editor.updateViewportScreenBounds(new Box(0, 0, 1280, 1024), true)\n\t * ```\n\t *\n\t * @param screenBounds - The new screen bounds of the viewport.\n\t * @param center - Whether to preserve the viewport page center as the viewport changes.\n\t *\n\t * @public\n\t */\n\tupdateViewportScreenBounds(screenBounds: Box | HTMLElement, center = false): this {\n\t\tif (!(screenBounds instanceof Box)) {\n\t\t\tconst rect = screenBounds.getBoundingClientRect()\n\t\t\tscreenBounds = new Box(\n\t\t\t\trect.left || rect.x,\n\t\t\t\trect.top || rect.y,\n\t\t\t\tMath.max(rect.width, 1),\n\t\t\t\tMath.max(rect.height, 1)\n\t\t\t)\n\t\t} else {\n\t\t\tscreenBounds.width = Math.max(screenBounds.width, 1)\n\t\t\tscreenBounds.height = Math.max(screenBounds.height, 1)\n\t\t}\n\n\t\tconst insets = [\n\t\t\t// top\n\t\t\tscreenBounds.minY !== 0,\n\t\t\t// right\n\t\t\t!approximately(document.body.scrollWidth, screenBounds.maxX, 1),\n\t\t\t// bottom\n\t\t\t!approximately(document.body.scrollHeight, screenBounds.maxY, 1),\n\t\t\t// left\n\t\t\tscreenBounds.minX !== 0,\n\t\t]\n\n\t\tconst { _willSetInitialBounds } = this\n\n\t\tthis._willSetInitialBounds = false\n\n\t\tconst { screenBounds: prevScreenBounds, insets: prevInsets } = this.getInstanceState()\n\t\tif (screenBounds.equals(prevScreenBounds) && insets.every((v, i) => v === prevInsets[i])) {\n\t\t\t// nothing to do\n\t\t\treturn this\n\t\t}\n\n\t\tif (_willSetInitialBounds) {\n\t\t\t// If we have just received the initial bounds, don't center the camera.\n\t\t\tthis.updateInstanceState({ screenBounds: screenBounds.toJson(), insets })\n\t\t\tthis.setCamera(this.getCamera())\n\t\t} else {\n\t\t\tif (center && !this.getInstanceState().followingUserId) {\n\t\t\t\t// Get the page center before the change, make the change, and restore it\n\t\t\t\tconst before = this.getViewportPageBounds().center\n\t\t\t\tthis.updateInstanceState({ screenBounds: screenBounds.toJson(), insets })\n\t\t\t\tthis.centerOnPoint(before)\n\t\t\t} else {\n\t\t\t\t// Otherwise,\n\t\t\t\tthis.updateInstanceState({ screenBounds: screenBounds.toJson(), insets })\n\t\t\t\tthis._setCamera(Vec.From({ ...this.getCamera() }))\n\t\t\t}\n\t\t}\n\n\t\tthis._tickCameraState()\n\n\t\treturn this\n\t}\n\n\t/**\n\t * The bounds of the editor's viewport in screen space.\n\t *\n\t * @public\n\t */\n\t@computed getViewportScreenBounds() {\n\t\tconst { x, y, w, h } = this.getInstanceState().screenBounds\n\t\treturn new Box(x, y, w, h)\n\t}\n\n\t/**\n\t * The center of the editor's viewport in screen space.\n\t *\n\t * @public\n\t */\n\t@computed getViewportScreenCenter() {\n\t\tconst viewportScreenBounds = this.getViewportScreenBounds()\n\t\treturn new Vec(\n\t\t\tviewportScreenBounds.midX - viewportScreenBounds.minX,\n\t\t\tviewportScreenBounds.midY - viewportScreenBounds.minY\n\t\t)\n\t}\n\n\t/**\n\t * The current viewport in the current page space.\n\t *\n\t * @public\n\t */\n\t@computed getViewportPageBounds() {\n\t\tconst { w, h } = this.getViewportScreenBounds()\n\t\tconst { x: cx, y: cy, z: cz } = this.getCamera()\n\t\treturn new Box(-cx, -cy, w / cz, h / cz)\n\t}\n\n\t/**\n\t * Convert a point in screen space to a point in the current page space.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.screenToPage({ x: 100, y: 100 })\n\t * ```\n\t *\n\t * @param point - The point in screen space.\n\t *\n\t * @public\n\t */\n\tscreenToPage(point: VecLike) {\n\t\tconst { screenBounds } = this.store.unsafeGetWithoutCapture(TLINSTANCE_ID)!\n\t\tconst { x: cx, y: cy, z: cz = 1 } = this.getCamera()\n\t\treturn new Vec(\n\t\t\t(point.x - screenBounds.x) / cz - cx,\n\t\t\t(point.y - screenBounds.y) / cz - cy,\n\t\t\tpoint.z ?? 0.5\n\t\t)\n\t}\n\n\t/**\n\t * Convert a point in the current page space to a point in current screen space.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.pageToScreen({ x: 100, y: 100 })\n\t * ```\n\t *\n\t * @param point - The point in page space.\n\t *\n\t * @public\n\t */\n\tpageToScreen(point: VecLike) {\n\t\tconst { screenBounds } = this.store.unsafeGetWithoutCapture(TLINSTANCE_ID)!\n\t\tconst { x: cx, y: cy, z: cz = 1 } = this.getCamera()\n\t\treturn new Vec(\n\t\t\t(point.x + cx) * cz + screenBounds.x,\n\t\t\t(point.y + cy) * cz + screenBounds.y,\n\t\t\tpoint.z ?? 0.5\n\t\t)\n\t}\n\n\t/**\n\t * Convert a point in the current page space to a point in current viewport space.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.pageToViewport({ x: 100, y: 100 })\n\t * ```\n\t *\n\t * @param point - The point in page space.\n\t *\n\t * @public\n\t */\n\tpageToViewport(point: VecLike) {\n\t\tconst { x: cx, y: cy, z: cz = 1 } = this.getCamera()\n\t\treturn new Vec((point.x + cx) * cz, (point.y + cy) * cz, point.z ?? 0.5)\n\t}\n\t// Collaborators\n\n\t@computed\n\tprivate _getCollaboratorsQuery() {\n\t\treturn this.store.query.records('instance_presence', () => ({\n\t\t\tuserId: { neq: this.user.getId() },\n\t\t}))\n\t}\n\n\t/**\n\t * Returns a list of presence records for all peer collaborators.\n\t * This will return the latest presence record for each connected user.\n\t *\n\t * @public\n\t */\n\t@computed\n\tgetCollaborators() {\n\t\tconst allPresenceRecords = this._getCollaboratorsQuery().get()\n\t\tif (!allPresenceRecords.length) return EMPTY_ARRAY\n\t\tconst userIds = [...new Set(allPresenceRecords.map((c) => c.userId))].sort()\n\t\treturn userIds.map((id) => {\n\t\t\tconst latestPresence = allPresenceRecords\n\t\t\t\t.filter((c) => c.userId === id)\n\t\t\t\t.sort((a, b) => b.lastActivityTimestamp - a.lastActivityTimestamp)[0]\n\t\t\treturn latestPresence\n\t\t})\n\t}\n\n\t/**\n\t * Returns a list of presence records for all peer collaborators on the current page.\n\t * This will return the latest presence record for each connected user.\n\t *\n\t * @public\n\t */\n\t@computed\n\tgetCollaboratorsOnCurrentPage() {\n\t\tconst currentPageId = this.getCurrentPageId()\n\t\treturn this.getCollaborators().filter((c) => c.currentPageId === currentPageId)\n\t}\n\n\t// Following\n\n\t// When we are 'locked on' to a user, our camera is derived from their camera.\n\tprivate _isLockedOnFollowingUser = atom('isLockedOnFollowingUser', false)\n\n\t/**\n\t * Start viewport-following a user.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.startFollowingUser(myUserId)\n\t * ```\n\t *\n\t * @param userId - The id of the user to follow.\n\t *\n\t * @public\n\t */\n\tstartFollowingUser(userId: string): this {\n\t\t// if we were already following someone, stop following them\n\t\tthis.stopFollowingUser()\n\n\t\tconst leaderPresences = this._getCollaboratorsQuery()\n\t\t\t.get()\n\t\t\t.filter((p) => p.userId === userId)\n\n\t\tif (!leaderPresences.length) {\n\t\t\tconsole.warn('User not found')\n\t\t\treturn this\n\t\t}\n\n\t\tconst thisUserId = this.user.getId()\n\n\t\tif (!thisUserId) {\n\t\t\tconsole.warn('You should set the userId for the current instance before following a user')\n\t\t\t// allow to continue since it's probably fine most of the time.\n\t\t}\n\n\t\t// If the leader is following us, then we can't follow them\n\t\tif (leaderPresences.some((p) => p.followingUserId === thisUserId)) {\n\t\t\treturn this\n\t\t}\n\n\t\tconst latestLeaderPresence = computed('latestLeaderPresence', () => {\n\t\t\treturn this.getCollaborators().find((p) => p.userId === userId)\n\t\t})\n\n\t\ttransact(() => {\n\t\t\tthis.updateInstanceState({ followingUserId: userId }, { history: 'ignore' })\n\n\t\t\t// we listen for page changes separately from the 'moveTowardsUser' tick\n\t\t\tconst dispose = react('update current page', () => {\n\t\t\t\tconst leaderPresence = latestLeaderPresence.get()\n\t\t\t\tif (!leaderPresence) {\n\t\t\t\t\tthis.stopFollowingUser()\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tif (\n\t\t\t\t\tleaderPresence.currentPageId !== this.getCurrentPageId() &&\n\t\t\t\t\tthis.getPage(leaderPresence.currentPageId)\n\t\t\t\t) {\n\t\t\t\t\t// if the page changed, switch page\n\t\t\t\t\tthis.run(\n\t\t\t\t\t\t() => {\n\t\t\t\t\t\t\t// sneaky store.put here, we can't go through setCurrentPage because it calls stopFollowingUser\n\t\t\t\t\t\t\tthis.store.put([\n\t\t\t\t\t\t\t\t{ ...this.getInstanceState(), currentPageId: leaderPresence.currentPageId },\n\t\t\t\t\t\t\t])\n\t\t\t\t\t\t\tthis._isLockedOnFollowingUser.set(true)\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{ history: 'ignore' }\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t})\n\n\t\t\tconst cancel = () => {\n\t\t\t\tdispose()\n\t\t\t\tthis._isLockedOnFollowingUser.set(false)\n\t\t\t\tthis.off('frame', moveTowardsUser)\n\t\t\t\tthis.off('stop-following', cancel)\n\t\t\t}\n\n\t\t\tconst moveTowardsUser = () => {\n\t\t\t\t// Stop following if we can't find the user\n\t\t\t\tconst leaderPresence = latestLeaderPresence.get()\n\t\t\t\tif (!leaderPresence) {\n\t\t\t\t\tthis.stopFollowingUser()\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\tif (this._isLockedOnFollowingUser.get()) return\n\n\t\t\t\tconst animationSpeed = this.user.getAnimationSpeed()\n\n\t\t\t\tif (animationSpeed === 0) {\n\t\t\t\t\tthis._isLockedOnFollowingUser.set(true)\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\tconst targetViewport = this.getViewportPageBoundsForFollowing()\n\t\t\t\tif (!targetViewport) {\n\t\t\t\t\tthis.stopFollowingUser()\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tconst currentViewport = this.getViewportPageBounds()\n\n\t\t\t\tconst diffX =\n\t\t\t\t\tMath.abs(targetViewport.minX - currentViewport.minX) +\n\t\t\t\t\tMath.abs(targetViewport.maxX - currentViewport.maxX)\n\t\t\t\tconst diffY =\n\t\t\t\t\tMath.abs(targetViewport.minY - currentViewport.minY) +\n\t\t\t\t\tMath.abs(targetViewport.maxY - currentViewport.maxY)\n\n\t\t\t\t// Stop chasing if we're close enough!\n\t\t\t\tif (\n\t\t\t\t\tdiffX < this.options.followChaseViewportSnap &&\n\t\t\t\t\tdiffY < this.options.followChaseViewportSnap\n\t\t\t\t) {\n\t\t\t\t\tthis._isLockedOnFollowingUser.set(true)\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\t// Chase the user's viewport!\n\t\t\t\t// Interpolate between the current viewport and the target viewport based on animation speed.\n\t\t\t\t// This will produce an 'ease-out' effect.\n\t\t\t\tconst t = clamp(animationSpeed * 0.5, 0.1, 0.8)\n\n\t\t\t\tconst nextViewport = new Box(\n\t\t\t\t\tlerp(currentViewport.minX, targetViewport.minX, t),\n\t\t\t\t\tlerp(currentViewport.minY, targetViewport.minY, t),\n\t\t\t\t\tlerp(currentViewport.width, targetViewport.width, t),\n\t\t\t\t\tlerp(currentViewport.height, targetViewport.height, t)\n\t\t\t\t)\n\n\t\t\t\tconst nextCamera = new Vec(\n\t\t\t\t\t-nextViewport.x,\n\t\t\t\t\t-nextViewport.y,\n\t\t\t\t\tthis.getViewportScreenBounds().width / nextViewport.width\n\t\t\t\t)\n\n\t\t\t\t// Update the camera!\n\t\t\t\tthis.stopCameraAnimation()\n\t\t\t\tthis._setCamera(nextCamera)\n\t\t\t}\n\n\t\t\tthis.once('stop-following', cancel)\n\t\t\tthis.addListener('frame', moveTowardsUser)\n\n\t\t\t// call once to start synchronously\n\t\t\tmoveTowardsUser()\n\t\t})\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Stop viewport-following a user.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.stopFollowingUser()\n\t * ```\n\t * @public\n\t */\n\tstopFollowingUser(): this {\n\t\tthis.run(\n\t\t\t() => {\n\t\t\t\t// commit the current camera to the store\n\t\t\t\tthis.store.put([this.getCamera()])\n\t\t\t\t// this must happen after the camera is committed\n\t\t\t\tthis._isLockedOnFollowingUser.set(false)\n\t\t\t\tthis.updateInstanceState({ followingUserId: null })\n\t\t\t\tthis.emit('stop-following')\n\t\t\t},\n\t\t\t{ history: 'ignore' }\n\t\t)\n\t\treturn this\n\t}\n\n\t/** @internal */\n\tgetUnorderedRenderingShapes(\n\t\t// The rendering state. We use this method both for rendering, which\n\t\t// is based on other state, and for computing order for SVG export,\n\t\t// which should work even when things are for example off-screen.\n\t\tuseEditorState: boolean\n\t): TLRenderingShape[] {\n\t\t// Here we get the shape as well as any of its children, as well as their\n\t\t// opacities. If the shape is being erased, and none of its ancestors are\n\t\t// being erased, then we reduce the opacity of the shape and all of its\n\t\t// ancestors; but we don't apply this effect more than once among a set\n\t\t// of descendants so that it does not compound.\n\n\t\t// This is designed to keep all the shapes in a single list which\n\t\t// allows the DOM nodes to be reused even when they become children\n\t\t// of other nodes.\n\n\t\tconst renderingShapes: TLRenderingShape[] = []\n\n\t\tlet nextIndex = this.options.maxShapesPerPage * 2\n\t\tlet nextBackgroundIndex = this.options.maxShapesPerPage\n\n\t\tconst erasingShapeIds = this.getErasingShapeIds()\n\n\t\tconst addShapeById = (id: TLShapeId, opacity: number, isAncestorErasing: boolean) => {\n\t\t\tconst shape = this.getShape(id)\n\t\t\tif (!shape) return\n\t\t\tif (this.isShapeHidden(shape)) return\n\n\t\t\topacity *= shape.opacity\n\t\t\tlet isShapeErasing = false\n\t\t\tconst util = this.getShapeUtil(shape)\n\n\t\t\tif (useEditorState) {\n\t\t\t\tisShapeErasing = !isAncestorErasing && erasingShapeIds.includes(id)\n\t\t\t\tif (isShapeErasing) {\n\t\t\t\t\topacity *= 0.32\n\t\t\t\t}\n\t\t\t}\n\n\t\t\trenderingShapes.push({\n\t\t\t\tid,\n\t\t\t\tshape,\n\t\t\t\tutil,\n\t\t\t\tindex: nextIndex,\n\t\t\t\tbackgroundIndex: nextBackgroundIndex,\n\t\t\t\topacity,\n\t\t\t})\n\n\t\t\tnextIndex += 1\n\t\t\tnextBackgroundIndex += 1\n\n\t\t\tconst childIds = this.getSortedChildIdsForParent(id)\n\t\t\tif (!childIds.length) return\n\n\t\t\tlet backgroundIndexToRestore = null\n\t\t\tif (util.providesBackgroundForChildren(shape)) {\n\t\t\t\tbackgroundIndexToRestore = nextBackgroundIndex\n\t\t\t\tnextBackgroundIndex = nextIndex\n\t\t\t\tnextIndex += this.options.maxShapesPerPage\n\t\t\t}\n\n\t\t\tfor (const childId of childIds) {\n\t\t\t\taddShapeById(childId, opacity, isAncestorErasing || isShapeErasing)\n\t\t\t}\n\n\t\t\tif (backgroundIndexToRestore !== null) {\n\t\t\t\tnextBackgroundIndex = backgroundIndexToRestore\n\t\t\t}\n\t\t}\n\n\t\t// If we're using editor state, then we're only interested in on-screen shapes.\n\t\t// If we're not using the editor state, then we're interested in ALL shapes, even those from other pages.\n\t\tconst pages = useEditorState ? [this.getCurrentPage()] : this.getPages()\n\t\tfor (const page of pages) {\n\t\t\tfor (const childId of this.getSortedChildIdsForParent(page.id)) {\n\t\t\t\taddShapeById(childId, 1, false)\n\t\t\t}\n\t\t}\n\n\t\treturn renderingShapes\n\t}\n\n\t// Camera state\n\t// Camera state does two things: first, it allows us to subscribe to whether\n\t// the camera is moving or not; and second, it allows us to update the rendering\n\t// shapes on the canvas. Changing the rendering shapes may cause shapes to\n\t// unmount / remount in the DOM, which is expensive; and computing visibility is\n\t// also expensive in large projects. For this reason, we use a second bounding\n\t// box just for rendering, and we only update after the camera stops moving.\n\tprivate _cameraState = atom('camera state', 'idle' as 'idle' | 'moving')\n\tprivate _cameraStateTimeoutRemaining = 0\n\t_decayCameraStateTimeout(elapsed: number) {\n\t\tthis._cameraStateTimeoutRemaining -= elapsed\n\t\tif (this._cameraStateTimeoutRemaining > 0) return\n\t\tthis.off('tick', this._decayCameraStateTimeout)\n\t\tthis._cameraState.set('idle')\n\t}\n\t_tickCameraState() {\n\t\t// always reset the timeout\n\t\tthis._cameraStateTimeoutRemaining = this.options.cameraMovingTimeoutMs\n\t\t// If the state is idle, then start the tick\n\t\tif (this._cameraState.__unsafe__getWithoutCapture() !== 'idle') return\n\t\tthis._cameraState.set('moving')\n\t\tthis.on('tick', this._decayCameraStateTimeout)\n\t}\n\n\t/**\n\t * Whether the camera is moving or idle.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getCameraState()\n\t * ```\n\t *\n\t * @public\n\t */\n\tgetCameraState() {\n\t\treturn this._cameraState.get()\n\t}\n\n\t/**\n\t * Get the shapes that should be displayed in the current viewport.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getRenderingShapes()\n\t * ```\n\t *\n\t * @public\n\t */\n\t@computed getRenderingShapes() {\n\t\tconst renderingShapes = this.getUnorderedRenderingShapes(true)\n\n\t\t// Its IMPORTANT that the result be sorted by id AND include the index\n\t\t// that the shape should be displayed at. Steve, this is the past you\n\t\t// telling the present you not to change this.\n\n\t\t// We want to sort by id because moving elements about in the DOM will\n\t\t// cause the element to get removed by react as it moves the DOM node. This\n\t\t// causes to re-render which is hella annoying and a perf\n\t\t// drain. By always sorting by 'id' we keep the shapes always in the\n\t\t// same order; but we later use index to set the element's 'z-index'\n\t\t// to change the \"rendered\" position in z-space.\n\t\treturn renderingShapes.sort(sortById)\n\t}\n\n\t/* --------------------- Pages ---------------------- */\n\n\t@computed private _getAllPagesQuery() {\n\t\treturn this.store.query.records('page')\n\t}\n\n\t/**\n\t * Info about the project's current pages.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getPages()\n\t * ```\n\t *\n\t * @public\n\t */\n\t@computed getPages(): TLPage[] {\n\t\treturn this._getAllPagesQuery().get().sort(sortByIndex)\n\t}\n\n\t/**\n\t * The current page.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getCurrentPage()\n\t * ```\n\t *\n\t * @public\n\t */\n\tgetCurrentPage(): TLPage {\n\t\treturn this.getPage(this.getCurrentPageId())!\n\t}\n\n\t/**\n\t * The current page id.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getCurrentPageId()\n\t * ```\n\t *\n\t * @public\n\t */\n\t@computed getCurrentPageId(): TLPageId {\n\t\treturn this.getInstanceState().currentPageId\n\t}\n\n\t/**\n\t * Get a page.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getPage(myPage.id)\n\t * editor.getPage(myPage)\n\t * ```\n\t *\n\t * @param page - The page (or the page id) to get.\n\t *\n\t * @public\n\t */\n\tgetPage(page: TLPageId | TLPage): TLPage | undefined {\n\t\treturn this.store.get(typeof page === 'string' ? page : page.id)\n\t}\n\n\t/* @internal */\n\tprivate readonly _currentPageShapeIds: ReturnType\n\n\t/**\n\t * An array of all of the shapes on the current page.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getCurrentPageIds()\n\t * ```\n\t *\n\t * @public\n\t */\n\tgetCurrentPageShapeIds() {\n\t\treturn this._currentPageShapeIds.get()\n\t}\n\n\t/**\n\t * @internal\n\t */\n\t@computed\n\tgetCurrentPageShapeIdsSorted() {\n\t\treturn Array.from(this.getCurrentPageShapeIds()).sort()\n\t}\n\n\t/**\n\t * Get the ids of shapes on a page.\n\t *\n\t * @example\n\t * ```ts\n\t * const idsOnPage1 = editor.getPageShapeIds('page1')\n\t * const idsOnPage2 = editor.getPageShapeIds(myPage2)\n\t * ```\n\t *\n\t * @param page - The page (or the page id) to get the shape ids for.\n\t *\n\t * @public\n\t **/\n\tgetPageShapeIds(page: TLPageId | TLPage): Set {\n\t\tconst pageId = typeof page === 'string' ? page : page.id\n\t\tconst result = this.store.query.exec('shape', { parentId: { eq: pageId } })\n\t\treturn this.getShapeAndDescendantIds(result.map((s) => s.id))\n\t}\n\n\t/**\n\t * Set the current page.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.setCurrentPage('page1')\n\t * editor.setCurrentPage(myPage1)\n\t * ```\n\t *\n\t * @param page - The page (or the page id) to set as the current page.\n\t *\n\t * @public\n\t */\n\tsetCurrentPage(page: TLPageId | TLPage): this {\n\t\tconst pageId = typeof page === 'string' ? page : page.id\n\t\tif (!this.store.has(pageId)) {\n\t\t\tconsole.error(\"Tried to set the current page id to a page that doesn't exist.\")\n\t\t\treturn this\n\t\t}\n\n\t\tthis.stopFollowingUser()\n\t\t// finish off any in-progress interactions\n\t\tthis.complete()\n\n\t\treturn this.run(\n\t\t\t() => {\n\t\t\t\tthis.store.put([{ ...this.getInstanceState(), currentPageId: pageId }])\n\t\t\t\t// ensure camera constraints are applied\n\t\t\t\tthis.setCamera(this.getCamera())\n\t\t\t},\n\t\t\t{ history: 'record-preserveRedoStack' }\n\t\t)\n\t}\n\n\t/**\n\t * Update a page.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.updatePage({ id: 'page2', name: 'Page 2' })\n\t * ```\n\t *\n\t * @param partial - The partial of the shape to update.\n\t *\n\t * @public\n\t */\n\tupdatePage(partial: RequiredKeys, 'id'>): this {\n\t\tif (this.getIsReadonly()) return this\n\n\t\tconst prev = this.getPage(partial.id)\n\t\tif (!prev) return this\n\n\t\treturn this.run(() => this.store.update(partial.id, (page) => ({ ...page, ...partial })))\n\t}\n\n\t/**\n\t * Create a page.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.createPage(myPage)\n\t * editor.createPage({ name: 'Page 2' })\n\t * ```\n\t *\n\t * @param page - The page (or page partial) to create.\n\t *\n\t * @public\n\t */\n\tcreatePage(page: Partial): this {\n\t\tthis.run(() => {\n\t\t\tif (this.getIsReadonly()) return\n\t\t\tif (this.getPages().length >= this.options.maxPages) return\n\t\t\tconst pages = this.getPages()\n\n\t\t\tconst name = getIncrementedName(\n\t\t\t\tpage.name ?? 'Page 1',\n\t\t\t\tpages.map((p) => p.name)\n\t\t\t)\n\n\t\t\tlet index = page.index\n\n\t\t\tif (!index || pages.some((p) => p.index === index)) {\n\t\t\t\tindex = getIndexAbove(pages[pages.length - 1].index)\n\t\t\t}\n\n\t\t\tconst newPage = PageRecordType.create({\n\t\t\t\tmeta: {},\n\t\t\t\t...page,\n\t\t\t\tname,\n\t\t\t\tindex,\n\t\t\t})\n\n\t\t\tthis.store.put([newPage])\n\t\t})\n\t\treturn this\n\t}\n\n\t/**\n\t * Delete a page.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.deletePage('page1')\n\t * ```\n\t *\n\t * @param page - The page (or the page id) to delete.\n\t *\n\t * @public\n\t */\n\tdeletePage(page: TLPageId | TLPage): this {\n\t\tconst id = typeof page === 'string' ? page : page.id\n\t\tthis.run(() => {\n\t\t\tif (this.getIsReadonly()) return\n\t\t\tconst pages = this.getPages()\n\t\t\tif (pages.length === 1) return\n\n\t\t\tconst deletedPage = this.getPage(id)\n\t\t\tif (!deletedPage) return\n\n\t\t\tif (id === this.getCurrentPageId()) {\n\t\t\t\tconst index = pages.findIndex((page) => page.id === id)\n\t\t\t\tconst next = pages[index - 1] ?? pages[index + 1]\n\t\t\t\tthis.setCurrentPage(next.id)\n\t\t\t}\n\t\t\tthis.store.remove([deletedPage.id])\n\t\t})\n\t\treturn this\n\t}\n\n\t/**\n\t * Duplicate a page.\n\t *\n\t * @param page - The page (or the page id) to duplicate. Defaults to the current page.\n\t * @param createId - The id of the new page. Defaults to a new id.\n\t *\n\t * @public\n\t */\n\tduplicatePage(page: TLPageId | TLPage, createId: TLPageId = PageRecordType.createId()): this {\n\t\tif (this.getPages().length >= this.options.maxPages) return this\n\t\tconst id = typeof page === 'string' ? page : page.id\n\t\tconst freshPage = this.getPage(id) // get the most recent version of the page anyway\n\t\tif (!freshPage) return this\n\n\t\tconst prevCamera = { ...this.getCamera() }\n\t\tconst content = this.getContentFromCurrentPage(this.getSortedChildIdsForParent(freshPage.id))\n\n\t\tthis.run(() => {\n\t\t\tconst pages = this.getPages()\n\t\t\tconst index = getIndexBetween(freshPage.index, pages[pages.indexOf(freshPage) + 1]?.index)\n\n\t\t\t// create the page (also creates the pagestate and camera for the new page)\n\t\t\tthis.createPage({ name: freshPage.name + ' Copy', id: createId, index })\n\t\t\t// set the new page as the current page\n\t\t\tthis.setCurrentPage(createId)\n\t\t\t// update the new page's camera to the previous page's camera\n\t\t\tthis.setCamera(prevCamera)\n\n\t\t\tif (content) {\n\t\t\t\t// If we had content on the previous page, put it on the new page\n\t\t\t\treturn this.putContentOntoCurrentPage(content)\n\t\t\t}\n\t\t})\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Rename a page.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.renamePage('page1', 'My Page')\n\t * ```\n\t *\n\t * @param page - The page (or the page id) to rename.\n\t * @param name - The new name.\n\t *\n\t * @public\n\t */\n\trenamePage(page: TLPageId | TLPage, name: string) {\n\t\tconst id = typeof page === 'string' ? page : page.id\n\t\tif (this.getIsReadonly()) return this\n\t\tthis.updatePage({ id, name })\n\t\treturn this\n\t}\n\n\t/* --------------------- Assets --------------------- */\n\n\t/** @internal */\n\t@computed private _getAllAssetsQuery() {\n\t\treturn this.store.query.records('asset')\n\t}\n\n\t/**\n\t * Get all assets in the editor.\n\t *\n\t * @public\n\t */\n\tgetAssets() {\n\t\treturn this._getAllAssetsQuery().get()\n\t}\n\n\t/**\n\t * Create one or more assets.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.createAssets([...myAssets])\n\t * ```\n\t *\n\t * @param assets - The assets to create.\n\t *\n\t * @public\n\t */\n\tcreateAssets(assets: TLAsset[]): this {\n\t\tif (this.getIsReadonly()) return this\n\t\tif (assets.length <= 0) return this\n\t\tthis.run(() => this.store.put(assets), { history: 'ignore' })\n\t\treturn this\n\t}\n\n\t/**\n\t * Update one or more assets.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.updateAssets([{ id: 'asset1', name: 'New name' }])\n\t * ```\n\t *\n\t * @param assets - The assets to update.\n\t *\n\t * @public\n\t */\n\tupdateAssets(assets: TLAssetPartial[]): this {\n\t\tif (this.getIsReadonly()) return this\n\t\tif (assets.length <= 0) return this\n\t\tthis.run(\n\t\t\t() => {\n\t\t\t\tthis.store.put(\n\t\t\t\t\tassets.map((partial) => ({\n\t\t\t\t\t\t...this.store.get(partial.id)!,\n\t\t\t\t\t\t...partial,\n\t\t\t\t\t}))\n\t\t\t\t)\n\t\t\t},\n\t\t\t{ history: 'ignore' }\n\t\t)\n\t\treturn this\n\t}\n\n\t/**\n\t * Delete one or more assets.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.deleteAssets(['asset1', 'asset2'])\n\t * ```\n\t *\n\t * @param assets - The assets (or asset ids) to delete.\n\t *\n\t * @public\n\t */\n\tdeleteAssets(assets: TLAssetId[] | TLAsset[]): this {\n\t\tif (this.getIsReadonly()) return this\n\n\t\tconst ids =\n\t\t\ttypeof assets[0] === 'string'\n\t\t\t\t? (assets as TLAssetId[])\n\t\t\t\t: (assets as TLAsset[]).map((a) => a.id)\n\t\tif (ids.length <= 0) return this\n\n\t\tthis.run(() => this.store.remove(ids), { history: 'ignore' })\n\t\treturn this\n\t}\n\n\t/**\n\t * Get an asset by its id.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getAsset('asset1')\n\t * ```\n\t *\n\t * @param asset - The asset (or asset id) to get.\n\t *\n\t * @public\n\t */\n\tgetAsset(asset: T | T['id']): T | undefined {\n\t\treturn this.store.get(typeof asset === 'string' ? asset : asset.id) as T | undefined\n\t}\n\n\tasync resolveAssetUrl(\n\t\tassetId: TLAssetId | null,\n\t\tcontext: {\n\t\t\tscreenScale?: number\n\t\t\tshouldResolveToOriginal?: boolean\n\t\t}\n\t): Promise {\n\t\tif (!assetId) return null\n\t\tconst asset = this.getAsset(assetId)\n\t\tif (!asset) return null\n\n\t\tconst { screenScale = 1, shouldResolveToOriginal = false } = context\n\n\t\t// We only look at the zoom level at powers of 2.\n\t\tconst zoomStepFunction = (zoom: number) => Math.pow(2, Math.ceil(Math.log2(zoom)))\n\t\tconst steppedScreenScale = Math.max(0.125, zoomStepFunction(screenScale))\n\t\tconst networkEffectiveType: string | null =\n\t\t\t'connection' in navigator ? (navigator as any).connection.effectiveType : null\n\t\tconst dpr = this.getInstanceState().devicePixelRatio\n\n\t\treturn await this.store.props.assets.resolve(asset, {\n\t\t\tscreenScale: screenScale || 1,\n\t\t\tsteppedScreenScale,\n\t\t\tdpr,\n\t\t\tnetworkEffectiveType,\n\t\t\tshouldResolveToOriginal,\n\t\t})\n\t}\n\t/**\n\t * Upload an asset to the store's asset service, returning a URL that can be used to resolve the\n\t * asset.\n\t */\n\tasync uploadAsset(asset: TLAsset, file: File): Promise {\n\t\treturn await this.store.props.assets.upload(asset, file)\n\t}\n\n\t/* --------------------- Shapes --------------------- */\n\n\t@computed\n\tprivate _getShapeGeometryCache(): ComputedCache {\n\t\treturn this.store.createComputedCache(\n\t\t\t'bounds',\n\t\t\t(shape) => this.getShapeUtil(shape).getGeometry(shape),\n\t\t\t(a, b) => a.props === b.props\n\t\t)\n\t}\n\n\t/**\n\t * Get the geometry of a shape.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getShapeGeometry(myShape)\n\t * editor.getShapeGeometry(myShapeId)\n\t * ```\n\t *\n\t * @param shape - The shape (or shape id) to get the geometry for.\n\t *\n\t * @public\n\t */\n\tgetShapeGeometry(shape: TLShape | TLShapeId): T {\n\t\treturn this._getShapeGeometryCache().get(typeof shape === 'string' ? shape : shape.id)! as T\n\t}\n\n\t/** @internal */\n\t@computed private _getShapeHandlesCache(): ComputedCache {\n\t\treturn this.store.createComputedCache('handles', (shape) => {\n\t\t\treturn this.getShapeUtil(shape).getHandles?.(shape)\n\t\t})\n\t}\n\n\t/**\n\t * Get the handles (if any) for a shape.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getShapeHandles(myShape)\n\t * editor.getShapeHandles(myShapeId)\n\t * ```\n\t *\n\t * @param shape - The shape (or shape id) to get the handles for.\n\t * @public\n\t */\n\tgetShapeHandles(shape: T | T['id']): TLHandle[] | undefined {\n\t\treturn this._getShapeHandlesCache().get(typeof shape === 'string' ? shape : shape.id)\n\t}\n\n\t/**\n\t * Get the local transform for a shape as a matrix model. This transform reflects both its\n\t * translation (x, y) from from either its parent's top left corner, if the shape's parent is\n\t * another shape, or else from the 0,0 of the page, if the shape's parent is the page; and the\n\t * shape's rotation.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getShapeLocalTransform(myShape)\n\t * ```\n\t *\n\t * @param shape - The shape to get the local transform for.\n\t *\n\t * @public\n\t */\n\tgetShapeLocalTransform(shape: TLShape | TLShapeId): Mat {\n\t\tconst id = typeof shape === 'string' ? shape : shape.id\n\t\tconst freshShape = this.getShape(id)\n\t\tif (!freshShape) throw Error('Editor.getTransform: shape not found')\n\t\treturn Mat.Identity().translate(freshShape.x, freshShape.y).rotate(freshShape.rotation)\n\t}\n\n\t/**\n\t * A cache of page transforms.\n\t *\n\t * @internal\n\t */\n\t@computed private _getShapePageTransformCache(): ComputedCache {\n\t\treturn this.store.createComputedCache('pageTransformCache', (shape) => {\n\t\t\tif (isPageId(shape.parentId)) {\n\t\t\t\treturn this.getShapeLocalTransform(shape)\n\t\t\t}\n\n\t\t\t// If the shape's parent doesn't exist yet (e.g. when merging in changes from remote in the wrong order)\n\t\t\t// then we can't compute the transform yet, so just return the identity matrix.\n\t\t\t// In the future we should look at creating a store update mechanism that understands and preserves\n\t\t\t// ordering.\n\t\t\tconst parentTransform =\n\t\t\t\tthis._getShapePageTransformCache().get(shape.parentId) ?? Mat.Identity()\n\t\t\treturn Mat.Compose(parentTransform, this.getShapeLocalTransform(shape)!)\n\t\t})\n\t}\n\n\t/**\n\t * Get the local transform of a shape's parent as a matrix model.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getShapeParentTransform(myShape)\n\t * ```\n\t *\n\t * @param shape - The shape (or shape id) to get the parent transform for.\n\t *\n\t * @public\n\t */\n\tgetShapeParentTransform(shape: TLShape | TLShapeId): Mat {\n\t\tconst id = typeof shape === 'string' ? shape : shape.id\n\t\tconst freshShape = this.getShape(id)\n\t\tif (!freshShape || isPageId(freshShape.parentId)) return Mat.Identity()\n\t\treturn this._getShapePageTransformCache().get(freshShape.parentId) ?? Mat.Identity()\n\t}\n\n\t/**\n\t * Get the transform of a shape in the current page space.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getShapePageTransform(myShape)\n\t * editor.getShapePageTransform(myShapeId)\n\t * ```\n\t *\n\t * @param shape - The shape (or shape id) to get the page transform for.\n\t *\n\t * @public\n\t */\n\tgetShapePageTransform(shape: TLShape | TLShapeId): Mat {\n\t\tconst id = typeof shape === 'string' ? shape : shape.id\n\t\treturn this._getShapePageTransformCache().get(id) ?? Mat.Identity()\n\t}\n\n\t/** @internal */\n\t@computed private _getShapePageBoundsCache(): ComputedCache {\n\t\treturn this.store.createComputedCache('pageBoundsCache', (shape) => {\n\t\t\tconst pageTransform = this._getShapePageTransformCache().get(shape.id)\n\n\t\t\tif (!pageTransform) return new Box()\n\n\t\t\tconst result = Box.FromPoints(\n\t\t\t\tMat.applyToPoints(pageTransform, this.getShapeGeometry(shape).vertices)\n\t\t\t)\n\n\t\t\treturn result\n\t\t})\n\t}\n\n\t/**\n\t * Get the bounds of a shape in the current page space.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getShapePageBounds(myShape)\n\t * editor.getShapePageBounds(myShapeId)\n\t * ```\n\t *\n\t * @param shape - The shape (or shape id) to get the bounds for.\n\t *\n\t * @public\n\t */\n\tgetShapePageBounds(shape: TLShape | TLShapeId): Box | undefined {\n\t\treturn this._getShapePageBoundsCache().get(typeof shape === 'string' ? shape : shape.id)\n\t}\n\n\t/**\n\t * A cache of clip paths used for clipping.\n\t *\n\t * @internal\n\t */\n\t@computed private _getShapeClipPathCache(): ComputedCache {\n\t\treturn this.store.createComputedCache('clipPathCache', (shape) => {\n\t\t\tconst pageMask = this._getShapeMaskCache().get(shape.id)\n\t\t\tif (!pageMask) return undefined\n\t\t\tif (pageMask.length === 0) {\n\t\t\t\treturn `polygon(0px 0px, 0px 0px, 0px 0px)`\n\t\t\t}\n\n\t\t\tconst pageTransform = this._getShapePageTransformCache().get(shape.id)\n\t\t\tif (!pageTransform) return undefined\n\n\t\t\tconst localMask = Mat.applyToPoints(Mat.Inverse(pageTransform), pageMask)\n\n\t\t\treturn `polygon(${localMask.map((p) => `${p.x}px ${p.y}px`).join(',')})`\n\t\t})\n\t}\n\n\t/**\n\t * Get the clip path for a shape.\n\t *\n\t * @example\n\t * ```ts\n\t * const clipPath = editor.getShapeClipPath(shape)\n\t * const clipPath = editor.getShapeClipPath(shape.id)\n\t * ```\n\t *\n\t * @param shape - The shape (or shape id) to get the clip path for.\n\t *\n\t * @returns The clip path or undefined.\n\t *\n\t * @public\n\t */\n\tgetShapeClipPath(shape: TLShape | TLShapeId): string | undefined {\n\t\treturn this._getShapeClipPathCache().get(typeof shape === 'string' ? shape : shape.id)\n\t}\n\n\t/** @internal */\n\t@computed private _getShapeMaskCache(): ComputedCache {\n\t\treturn this.store.createComputedCache('pageMaskCache', (shape) => {\n\t\t\tif (isPageId(shape.parentId)) return undefined\n\n\t\t\tconst frameAncestors = this.getShapeAncestors(shape.id).filter((shape) =>\n\t\t\t\tthis.isShapeOfType(shape, 'frame')\n\t\t\t)\n\n\t\t\tif (frameAncestors.length === 0) return undefined\n\n\t\t\tconst pageMask = frameAncestors\n\t\t\t\t.map((s) =>\n\t\t\t\t\t// Apply the frame transform to the frame outline to get the frame outline in the current page space\n\t\t\t\t\tthis._getShapePageTransformCache()\n\t\t\t\t\t\t.get(s.id)!\n\t\t\t\t\t\t.applyToPoints(this.getShapeGeometry(s).vertices)\n\t\t\t\t)\n\t\t\t\t.reduce((acc, b) => {\n\t\t\t\t\tif (!(b && acc)) return undefined\n\t\t\t\t\tconst intersection = intersectPolygonPolygon(acc, b)\n\t\t\t\t\tif (intersection) {\n\t\t\t\t\t\treturn intersection.map(Vec.Cast)\n\t\t\t\t\t}\n\t\t\t\t\treturn []\n\t\t\t\t})\n\n\t\t\treturn pageMask\n\t\t})\n\t}\n\n\t/**\n\t * Get the mask (in the current page space) for a shape.\n\t *\n\t * @example\n\t * ```ts\n\t * const pageMask = editor.getShapeMask(shape.id)\n\t * ```\n\t *\n\t * @param shape - The shape (or the shape id) of the shape to get the mask for.\n\t *\n\t * @returns The mask for the shape.\n\t *\n\t * @public\n\t */\n\tgetShapeMask(shape: TLShapeId | TLShape): VecLike[] | undefined {\n\t\treturn this._getShapeMaskCache().get(typeof shape === 'string' ? shape : shape.id)\n\t}\n\n\t/**\n\t * Get the bounds of a shape in the current page space, incorporating any masks. For example, if the\n\t * shape were the child of a frame and was half way out of the frame, the bounds would be the half\n\t * of the shape that was in the frame.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getShapeMaskedPageBounds(myShape)\n\t * editor.getShapeMaskedPageBounds(myShapeId)\n\t * ```\n\t *\n\t * @param shape - The shape to get the masked bounds for.\n\t *\n\t * @public\n\t */\n\tgetShapeMaskedPageBounds(shape: TLShapeId | TLShape): Box | undefined {\n\t\tif (typeof shape !== 'string') shape = shape.id\n\t\treturn this._getShapeMaskedPageBoundsCache().get(shape)\n\t}\n\n\t/** @internal */\n\t@computed private _getShapeMaskedPageBoundsCache(): ComputedCache {\n\t\treturn this.store.createComputedCache('shapeMaskedPageBoundsCache', (shape) => {\n\t\t\tconst pageBounds = this._getShapePageBoundsCache().get(shape.id)\n\t\t\tif (!pageBounds) return\n\t\t\tconst pageMask = this._getShapeMaskCache().get(shape.id)\n\t\t\tif (pageMask) {\n\t\t\t\tif (pageMask.length === 0) return undefined\n\t\t\t\tconst { corners } = pageBounds\n\t\t\t\tif (corners.every((p, i) => p && Vec.Equals(p, pageMask[i]))) return pageBounds.clone()\n\t\t\t\tconst intersection = intersectPolygonPolygon(pageMask, corners)\n\t\t\t\tif (!intersection) return\n\t\t\t\treturn Box.FromPoints(intersection)\n\t\t\t}\n\t\t\treturn pageBounds\n\t\t})\n\t}\n\n\t/**\n\t * Get the ancestors of a shape.\n\t *\n\t * @example\n\t * ```ts\n\t * const ancestors = editor.getShapeAncestors(myShape)\n\t * const ancestors = editor.getShapeAncestors(myShapeId)\n\t * ```\n\t *\n\t * @param shape - The shape (or shape id) to get the ancestors for.\n\t * @param acc - The accumulator.\n\t *\n\t * @public\n\t */\n\tgetShapeAncestors(shape: TLShapeId | TLShape, acc: TLShape[] = []): TLShape[] {\n\t\tconst id = typeof shape === 'string' ? shape : shape.id\n\t\tconst freshShape = this.getShape(id)\n\t\tif (!freshShape) return acc\n\t\tconst parentId = freshShape.parentId\n\t\tif (isPageId(parentId)) {\n\t\t\tacc.reverse()\n\t\t\treturn acc\n\t\t}\n\n\t\tconst parent = this.store.get(parentId)\n\t\tif (!parent) return acc\n\t\tacc.push(parent)\n\t\treturn this.getShapeAncestors(parent, acc)\n\t}\n\n\t/**\n\t * Find the first ancestor matching the given predicate\n\t *\n\t * @example\n\t * ```ts\n\t * const ancestor = editor.findShapeAncestor(myShape)\n\t * const ancestor = editor.findShapeAncestor(myShape.id)\n\t * const ancestor = editor.findShapeAncestor(myShape.id, (shape) => shape.type === 'frame')\n\t * ```\n\t *\n\t * @param shape - The shape to check the ancestors for.\n\t * @param predicate - The predicate to match.\n\t *\n\t * @public\n\t */\n\tfindShapeAncestor(\n\t\tshape: TLShape | TLShapeId,\n\t\tpredicate: (parent: TLShape) => boolean\n\t): TLShape | undefined {\n\t\tconst id = typeof shape === 'string' ? shape : shape.id\n\t\tconst freshShape = this.getShape(id)\n\t\tif (!freshShape) return\n\n\t\tconst parentId = freshShape.parentId\n\t\tif (isPageId(parentId)) return\n\n\t\tconst parent = this.getShape(parentId)\n\t\tif (!parent) return\n\t\treturn predicate(parent) ? parent : this.findShapeAncestor(parent, predicate)\n\t}\n\n\t/**\n\t * Returns true if the the given shape has the given ancestor.\n\t *\n\t * @param shape - The shape.\n\t * @param ancestorId - The id of the ancestor.\n\t *\n\t * @public\n\t */\n\thasAncestor(shape: TLShape | TLShapeId | undefined, ancestorId: TLShapeId): boolean {\n\t\tconst id = typeof shape === 'string' ? shape : shape?.id\n\t\tconst freshShape = id && this.getShape(id)\n\t\tif (!freshShape) return false\n\t\tif (freshShape.parentId === ancestorId) return true\n\t\treturn this.hasAncestor(this.getShapeParent(freshShape), ancestorId)\n\t}\n\n\t/**\n\t * Get the common ancestor of two or more shapes that matches a predicate.\n\t *\n\t * @param shapes - The shapes (or shape ids) to check.\n\t * @param predicate - The predicate to match.\n\t */\n\tfindCommonAncestor(\n\t\tshapes: TLShape[] | TLShapeId[],\n\t\tpredicate?: (shape: TLShape) => boolean\n\t): TLShapeId | undefined {\n\t\tif (shapes.length === 0) {\n\t\t\treturn\n\t\t}\n\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\t\tconst freshShapes = compact(ids.map((id) => this.getShape(id)))\n\n\t\tif (freshShapes.length === 1) {\n\t\t\tconst parentId = freshShapes[0].parentId\n\t\t\tif (isPageId(parentId)) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\treturn predicate ? this.findShapeAncestor(freshShapes[0], predicate)?.id : parentId\n\t\t}\n\n\t\tconst [nodeA, ...others] = freshShapes\n\t\tlet ancestor = this.getShapeParent(nodeA)\n\t\twhile (ancestor) {\n\t\t\t// TODO: this is not ideal, optimize\n\t\t\tif (predicate && !predicate(ancestor)) {\n\t\t\t\tancestor = this.getShapeParent(ancestor)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif (others.every((shape) => this.hasAncestor(shape, ancestor!.id))) {\n\t\t\t\treturn ancestor!.id\n\t\t\t}\n\t\t\tancestor = this.getShapeParent(ancestor)\n\t\t}\n\t\treturn undefined\n\t}\n\n\t/**\n\t * Check whether a shape or its parent is locked.\n\t *\n\t * @param shape - The shape (or shape id) to check.\n\t *\n\t * @public\n\t */\n\tisShapeOrAncestorLocked(shape?: TLShape): boolean\n\tisShapeOrAncestorLocked(id?: TLShapeId): boolean\n\tisShapeOrAncestorLocked(arg?: TLShape | TLShapeId): boolean {\n\t\tconst shape = typeof arg === 'string' ? this.getShape(arg) : arg\n\t\tif (shape === undefined) return false\n\t\tif (shape.isLocked) return true\n\t\treturn this.isShapeOrAncestorLocked(this.getShapeParent(shape))\n\t}\n\n\t@computed\n\tprivate _notVisibleShapes() {\n\t\treturn notVisibleShapes(this)\n\t}\n\n\t/**\n\t * Get culled shapes.\n\t *\n\t * @public\n\t */\n\t@computed\n\tgetCulledShapes() {\n\t\tconst notVisibleShapes = this._notVisibleShapes().get()\n\t\tconst selectedShapeIds = this.getSelectedShapeIds()\n\t\tconst editingId = this.getEditingShapeId()\n\t\tconst culledShapes = new Set(notVisibleShapes)\n\t\t// we don't cull the shape we are editing\n\t\tif (editingId) {\n\t\t\tculledShapes.delete(editingId)\n\t\t}\n\t\t// we also don't cull selected shapes\n\t\tselectedShapeIds.forEach((id) => {\n\t\t\tculledShapes.delete(id)\n\t\t})\n\t\treturn culledShapes\n\t}\n\n\t/**\n\t * The bounds of the current page (the common bounds of all of the shapes on the page).\n\t *\n\t * @public\n\t */\n\t@computed getCurrentPageBounds(): Box | undefined {\n\t\tlet commonBounds: Box | undefined\n\n\t\tthis.getCurrentPageShapeIdsSorted().forEach((shapeId) => {\n\t\t\tconst bounds = this.getShapeMaskedPageBounds(shapeId)\n\t\t\tif (!bounds) return\n\t\t\tif (!commonBounds) {\n\t\t\t\tcommonBounds = bounds.clone()\n\t\t\t} else {\n\t\t\t\tcommonBounds = commonBounds.expand(bounds)\n\t\t\t}\n\t\t})\n\n\t\treturn commonBounds\n\t}\n\n\t/**\n\t * Get the top-most selected shape at the given point, ignoring groups.\n\t *\n\t * @param point - The point to check.\n\t *\n\t * @returns The top-most selected shape at the given point, or undefined if there is no shape at the point.\n\t */\n\tgetSelectedShapeAtPoint(point: VecLike): TLShape | undefined {\n\t\tconst selectedShapeIds = this.getSelectedShapeIds()\n\t\treturn this.getCurrentPageShapesSorted()\n\t\t\t.filter((shape) => shape.type !== 'group' && selectedShapeIds.includes(shape.id))\n\t\t\t.reverse() // find last\n\t\t\t.find((shape) => this.isPointInShape(shape, point, { hitInside: true, margin: 0 }))\n\t}\n\n\t/**\n\t * Get the shape at the current point.\n\t *\n\t * @param point - The point to check.\n\t * @param opts - Options for the check: `hitInside` to check if the point is inside the shape, `margin` to check if the point is within a margin of the shape, `hitFrameInside` to check if the point is inside the frame, and `filter` to filter the shapes to check.\n\t *\n\t * @returns The shape at the given point, or undefined if there is no shape at the point.\n\t */\n\tgetShapeAtPoint(\n\t\tpoint: VecLike,\n\t\topts = {} as {\n\t\t\trenderingOnly?: boolean\n\t\t\tmargin?: number\n\t\t\thitInside?: boolean\n\t\t\thitLocked?: boolean\n\t\t\t// TODO: we probably need to rename this, we don't quite _always_\n\t\t\t// respect this esp. in the part below that does \"Check labels first\"\n\t\t\thitLabels?: boolean\n\t\t\thitFrameInside?: boolean\n\t\t\tfilter?(shape: TLShape): boolean\n\t\t}\n\t): TLShape | undefined {\n\t\tconst zoomLevel = this.getZoomLevel()\n\t\tconst viewportPageBounds = this.getViewportPageBounds()\n\t\tconst {\n\t\t\tfilter,\n\t\t\tmargin = 0,\n\t\t\thitLocked = false,\n\t\t\thitLabels = false,\n\t\t\thitInside = false,\n\t\t\thitFrameInside = false,\n\t\t} = opts\n\n\t\tlet inHollowSmallestArea = Infinity\n\t\tlet inHollowSmallestAreaHit: TLShape | null = null\n\n\t\tlet inMarginClosestToEdgeDistance = Infinity\n\t\tlet inMarginClosestToEdgeHit: TLShape | null = null\n\n\t\tconst shapesToCheck = (\n\t\t\topts.renderingOnly\n\t\t\t\t? this.getCurrentPageRenderingShapesSorted()\n\t\t\t\t: this.getCurrentPageShapesSorted()\n\t\t).filter((shape) => {\n\t\t\tif (\n\t\t\t\t(shape.isLocked && !hitLocked) ||\n\t\t\t\tthis.isShapeHidden(shape) ||\n\t\t\t\tthis.isShapeOfType(shape, 'group')\n\t\t\t)\n\t\t\t\treturn false\n\t\t\tconst pageMask = this.getShapeMask(shape)\n\t\t\tif (pageMask && !pointInPolygon(point, pageMask)) return false\n\t\t\tif (filter) return filter(shape)\n\t\t\treturn true\n\t\t})\n\n\t\tfor (let i = shapesToCheck.length - 1; i >= 0; i--) {\n\t\t\tconst shape = shapesToCheck[i]\n\t\t\tconst geometry = this.getShapeGeometry(shape)\n\t\t\tconst isGroup = geometry instanceof Group2d\n\n\t\t\tconst pointInShapeSpace = this.getPointInShapeSpace(shape, point)\n\n\t\t\t// Check labels first\n\t\t\tif (\n\t\t\t\tthis.isShapeOfType(shape, 'arrow') ||\n\t\t\t\t(this.isShapeOfType(shape, 'geo') && shape.props.fill === 'none')\n\t\t\t) {\n\t\t\t\tif (shape.props.text.trim()) {\n\t\t\t\t\t// let's check whether the shape has a label and check that\n\t\t\t\t\tfor (const childGeometry of (geometry as Group2d).children) {\n\t\t\t\t\t\tif (childGeometry.isLabel && childGeometry.isPointInBounds(pointInShapeSpace)) {\n\t\t\t\t\t\t\treturn shape\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (this.isShapeOfType(shape, 'frame')) {\n\t\t\t\t// On the rare case that we've hit a frame, test again hitInside to be forced true;\n\t\t\t\t// this prevents clicks from passing through the body of a frame to shapes behind it.\n\n\t\t\t\t// If the hit is within the frame's outer margin, then select the frame\n\t\t\t\tconst distance = geometry.distanceToPoint(pointInShapeSpace, hitInside)\n\t\t\t\tif (Math.abs(distance) <= margin) {\n\t\t\t\t\treturn inMarginClosestToEdgeHit || shape\n\t\t\t\t}\n\n\t\t\t\tif (geometry.hitTestPoint(pointInShapeSpace, 0, true)) {\n\t\t\t\t\t// Once we've hit a frame, we want to end the search. If we have hit a shape\n\t\t\t\t\t// already, then this would either be above the frame or a child of the frame,\n\t\t\t\t\t// so we want to return that. Otherwise, the point is in the empty space of the\n\t\t\t\t\t// frame. If `hitFrameInside` is true (e.g. used drawing an arrow into the\n\t\t\t\t\t// frame) we the frame itself; other wise, (e.g. when hovering or pointing)\n\t\t\t\t\t// we would want to return null.\n\t\t\t\t\treturn (\n\t\t\t\t\t\tinMarginClosestToEdgeHit ||\n\t\t\t\t\t\tinHollowSmallestAreaHit ||\n\t\t\t\t\t\t(hitFrameInside ? shape : undefined)\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tlet distance: number\n\n\t\t\tif (isGroup) {\n\t\t\t\tlet minDistance = Infinity\n\t\t\t\tfor (const childGeometry of geometry.children) {\n\t\t\t\t\tif (childGeometry.isLabel && !hitLabels) continue\n\n\t\t\t\t\t// hit test the all of the child geometries that aren't labels\n\t\t\t\t\tconst tDistance = childGeometry.distanceToPoint(pointInShapeSpace, hitInside)\n\t\t\t\t\tif (tDistance < minDistance) {\n\t\t\t\t\t\tminDistance = tDistance\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tdistance = minDistance\n\t\t\t} else {\n\t\t\t\t// If the margin is zero and the geometry has a very small width or height,\n\t\t\t\t// then check the actual distance. This is to prevent a bug where straight\n\t\t\t\t// lines would never pass the broad phase (point-in-bounds) check.\n\t\t\t\tif (margin === 0 && (geometry.bounds.w < 1 || geometry.bounds.h < 1)) {\n\t\t\t\t\tdistance = geometry.distanceToPoint(pointInShapeSpace, hitInside)\n\t\t\t\t} else {\n\t\t\t\t\t// Broad phase\n\t\t\t\t\tif (geometry.bounds.containsPoint(pointInShapeSpace, margin)) {\n\t\t\t\t\t\t// Narrow phase (actual distance)\n\t\t\t\t\t\tdistance = geometry.distanceToPoint(pointInShapeSpace, hitInside)\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// Failed the broad phase, geddafugaotta'ere!\n\t\t\t\t\t\tdistance = Infinity\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (geometry.isClosed) {\n\t\t\t\t// For closed shapes, the distance will be positive if outside of\n\t\t\t\t// the shape or negative if inside of the shape. If the distance\n\t\t\t\t// is greater than the margin, then it's a miss. Otherwise...\n\n\t\t\t\tif (distance <= margin) {\n\t\t\t\t\tif (geometry.isFilled || (isGroup && geometry.children[0].isFilled)) {\n\t\t\t\t\t\t// If the shape is filled, then it's a hit. Remember, we're\n\t\t\t\t\t\t// starting from the TOP-MOST shape in z-index order, so any\n\t\t\t\t\t\t// other hits would be occluded by the shape.\n\t\t\t\t\t\treturn inMarginClosestToEdgeHit || shape\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// If the shape is bigger than the viewport, then skip it.\n\t\t\t\t\t\tif (this.getShapePageBounds(shape)!.contains(viewportPageBounds)) continue\n\n\t\t\t\t\t\t// For hollow shapes...\n\t\t\t\t\t\tif (Math.abs(distance) < margin) {\n\t\t\t\t\t\t\t// We want to preference shapes where we're inside of the\n\t\t\t\t\t\t\t// shape margin; and we would want to hit the shape with the\n\t\t\t\t\t\t\t// edge closest to the point.\n\t\t\t\t\t\t\tif (Math.abs(distance) < inMarginClosestToEdgeDistance) {\n\t\t\t\t\t\t\t\tinMarginClosestToEdgeDistance = Math.abs(distance)\n\t\t\t\t\t\t\t\tinMarginClosestToEdgeHit = shape\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else if (!inMarginClosestToEdgeHit) {\n\t\t\t\t\t\t\t// If we're not within margin distance to any edge, and if the\n\t\t\t\t\t\t\t// shape is hollow, then we want to hit the shape with the\n\t\t\t\t\t\t\t// smallest area. (There's a bug here with self-intersecting\n\t\t\t\t\t\t\t// shapes, like a closed drawing of an \"8\", but that's a bigger\n\t\t\t\t\t\t\t// problem to solve.)\n\t\t\t\t\t\t\tconst { area } = geometry\n\t\t\t\t\t\t\tif (area < inHollowSmallestArea) {\n\t\t\t\t\t\t\t\tinHollowSmallestArea = area\n\t\t\t\t\t\t\t\tinHollowSmallestAreaHit = shape\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// For open shapes (e.g. lines or draw shapes) always use the margin.\n\t\t\t\t// If the distance is less than the margin, return the shape as the hit.\n\t\t\t\tif (distance < this.options.hitTestMargin / zoomLevel) {\n\t\t\t\t\treturn shape\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// If we haven't hit any filled shapes or frames, then return either\n\t\t// the shape who we hit within the margin (and of those, the one that\n\t\t// had the shortest distance between the point and the shape edge),\n\t\t// or else the hollow shape with the smallest area\u2014or if we didn't hit\n\t\t// any margins or any hollow shapes, then null.\n\t\treturn inMarginClosestToEdgeHit || inHollowSmallestAreaHit || undefined\n\t}\n\n\t/**\n\t * Get the shapes, if any, at a given page point.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getShapesAtPoint({ x: 100, y: 100 })\n\t * editor.getShapesAtPoint({ x: 100, y: 100 }, { hitInside: true, exact: true })\n\t * ```\n\t *\n\t * @param point - The page point to test.\n\t * @param opts - The options for the hit point testing.\n\t *\n\t * @public\n\t */\n\tgetShapesAtPoint(\n\t\tpoint: VecLike,\n\t\topts = {} as { margin?: number; hitInside?: boolean }\n\t): TLShape[] {\n\t\treturn this.getCurrentPageShapes().filter(\n\t\t\t(shape) => !this.isShapeHidden(shape) && this.isPointInShape(shape, point, opts)\n\t\t)\n\t}\n\n\t/**\n\t * Test whether a point (in the current page space) will will a shape. This method takes into account masks,\n\t * such as when a shape is the child of a frame and is partially clipped by the frame.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.isPointInShape({ x: 100, y: 100 }, myShape)\n\t * ```\n\t *\n\t * @param shape - The shape to test against.\n\t * @param point - The page point to test (in the current page space).\n\t * @param opts - The options for the hit point testing.\n\t *\n\t * @public\n\t */\n\tisPointInShape(\n\t\tshape: TLShape | TLShapeId,\n\t\tpoint: VecLike,\n\t\topts = {} as {\n\t\t\tmargin?: number\n\t\t\thitInside?: boolean\n\t\t}\n\t): boolean {\n\t\tconst { hitInside = false, margin = 0 } = opts\n\t\tconst id = typeof shape === 'string' ? shape : shape.id\n\t\t// If the shape is masked, and if the point falls outside of that\n\t\t// mask, then it's definitely a miss\u2014we don't need to test further.\n\t\tconst pageMask = this.getShapeMask(id)\n\t\tif (pageMask && !pointInPolygon(point, pageMask)) return false\n\n\t\treturn this.getShapeGeometry(id).hitTestPoint(\n\t\t\tthis.getPointInShapeSpace(shape, point),\n\t\t\tmargin,\n\t\t\thitInside\n\t\t)\n\t}\n\n\t/**\n\t * Convert a point in the current page space to a point in the local space of a shape. For example, if a\n\t * shape's page point were `{ x: 100, y: 100 }`, a page point at `{ x: 110, y: 110 }` would be at\n\t * `{ x: 10, y: 10 }` in the shape's local space.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getPointInShapeSpace(myShape, { x: 100, y: 100 })\n\t * ```\n\t *\n\t * @param shape - The shape to get the point in the local space of.\n\t * @param point - The page point to get in the local space of the shape.\n\t *\n\t * @public\n\t */\n\tgetPointInShapeSpace(shape: TLShape | TLShapeId, point: VecLike): Vec {\n\t\tconst id = typeof shape === 'string' ? shape : shape.id\n\t\treturn this._getShapePageTransformCache().get(id)!.clone().invert().applyToPoint(point)\n\t}\n\n\t/**\n\t * Convert a delta in the current page space to a point in the local space of a shape's parent.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getPointInParentSpace(myShape.id, { x: 100, y: 100 })\n\t * ```\n\t *\n\t * @param shape - The shape to get the point in the local space of.\n\t * @param point - The page point to get in the local space of the shape.\n\t *\n\t * @public\n\t */\n\tgetPointInParentSpace(shape: TLShapeId | TLShape, point: VecLike): Vec {\n\t\tconst id = typeof shape === 'string' ? shape : shape.id\n\t\tconst freshShape = this.getShape(id)\n\t\tif (!freshShape) return new Vec(0, 0)\n\t\tif (isPageId(freshShape.parentId)) return Vec.From(point)\n\n\t\tconst parentTransform = this.getShapePageTransform(freshShape.parentId)\n\t\tif (!parentTransform) return Vec.From(point)\n\t\treturn parentTransform.clone().invert().applyToPoint(point)\n\t}\n\n\t/**\n\t * An array containing all of the shapes in the current page.\n\t *\n\t * @public\n\t */\n\t@computed getCurrentPageShapes(): TLShape[] {\n\t\treturn Array.from(this.getCurrentPageShapeIds(), (id) => this.store.get(id)! as TLShape)\n\t}\n\n\t/**\n\t * An array containing all of the shapes in the current page, sorted in z-index order (accounting\n\t * for nested shapes): e.g. A, B, BA, BB, C.\n\t *\n\t * @public\n\t */\n\t@computed getCurrentPageShapesSorted(): TLShape[] {\n\t\tconst result: TLShape[] = []\n\t\tconst topLevelShapes = this.getSortedChildIdsForParent(this.getCurrentPageId())\n\n\t\tfor (let i = 0, n = topLevelShapes.length; i < n; i++) {\n\t\t\tpushShapeWithDescendants(this, topLevelShapes[i], result)\n\t\t}\n\n\t\treturn result\n\t}\n\n\t/**\n\t * An array containing all of the rendering shapes in the current page, sorted in z-index order (accounting\n\t * for nested shapes): e.g. A, B, BA, BB, C.\n\t *\n\t * @public\n\t */\n\t@computed getCurrentPageRenderingShapesSorted(): TLShape[] {\n\t\tconst culledShapes = this.getCulledShapes()\n\t\treturn this.getCurrentPageShapesSorted().filter(\n\t\t\t({ id }) => !culledShapes.has(id) && !this.isShapeHidden(id)\n\t\t)\n\t}\n\n\t/**\n\t * Get whether a shape matches the type of a TLShapeUtil.\n\t *\n\t * @example\n\t * ```ts\n\t * const isArrowShape = isShapeOfType(someShape, 'arrow')\n\t * ```\n\t *\n\t * @param util - the TLShapeUtil constructor to test against\n\t * @param shape - the shape to test\n\t *\n\t * @public\n\t */\n\tisShapeOfType(shape: TLUnknownShape, type: T['type']): shape is T\n\tisShapeOfType(\n\t\tshapeId: TLUnknownShape['id'],\n\t\ttype: T['type']\n\t): shapeId is T['id']\n\tisShapeOfType(\n\t\targ: TLUnknownShape | TLUnknownShape['id'],\n\t\ttype: T['type']\n\t) {\n\t\tconst shape = typeof arg === 'string' ? this.getShape(arg) : arg\n\t\tif (!shape) return false\n\t\treturn shape.type === type\n\t}\n\n\t/**\n\t * Get a shape by its id.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getShape('box1')\n\t * ```\n\t *\n\t * @param shape - The shape (or the id of the shape) to get.\n\t *\n\t * @public\n\t */\n\tgetShape(shape: TLShape | TLParentId): T | undefined {\n\t\tconst id = typeof shape === 'string' ? shape : shape.id\n\t\tif (!isShapeId(id)) return undefined\n\t\treturn this.store.get(id) as T\n\t}\n\n\t/**\n\t * Get the parent shape for a given shape. Returns undefined if the shape is the direct child of\n\t * the page.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getShapeParent(myShape)\n\t * ```\n\t *\n\t * @public\n\t */\n\tgetShapeParent(shape?: TLShape | TLShapeId): TLShape | undefined {\n\t\tconst id = typeof shape === 'string' ? shape : shape?.id\n\t\tif (!id) return undefined\n\t\tconst freshShape = this.getShape(id)\n\t\tif (freshShape === undefined || !isShapeId(freshShape.parentId)) return undefined\n\t\treturn this.store.get(freshShape.parentId)\n\t}\n\n\t/**\n\t * If siblingShape and targetShape are siblings, this returns targetShape. If targetShape has an\n\t * ancestor who is a sibling of siblingShape, this returns that ancestor. Otherwise, this returns\n\t * undefined.\n\t *\n\t * @internal\n\t */\n\tgetShapeNearestSibling(\n\t\tsiblingShape: TLShape,\n\t\ttargetShape: TLShape | undefined\n\t): TLShape | undefined {\n\t\tif (!targetShape) {\n\t\t\treturn undefined\n\t\t}\n\t\tif (targetShape.parentId === siblingShape.parentId) {\n\t\t\treturn targetShape\n\t\t}\n\n\t\tconst ancestor = this.findShapeAncestor(\n\t\t\ttargetShape,\n\t\t\t(ancestor) => ancestor.parentId === siblingShape.parentId\n\t\t)\n\n\t\treturn ancestor\n\t}\n\n\t/**\n\t * Get whether the given shape is the descendant of the given page.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.isShapeInPage(myShape)\n\t * editor.isShapeInPage(myShape, 'page1')\n\t * ```\n\t *\n\t * @param shape - The shape to check.\n\t * @param pageId - The id of the page to check against. Defaults to the current page.\n\t *\n\t * @public\n\t */\n\tisShapeInPage(shape: TLShape | TLShapeId, pageId = this.getCurrentPageId()): boolean {\n\t\tconst id = typeof shape === 'string' ? shape : shape.id\n\t\tconst shapeToCheck = this.getShape(id)\n\t\tif (!shapeToCheck) return false\n\n\t\tlet shapeIsInPage = false\n\n\t\tif (shapeToCheck.parentId === pageId) {\n\t\t\tshapeIsInPage = true\n\t\t} else {\n\t\t\tlet parent = this.getShape(shapeToCheck.parentId)\n\t\t\tisInPageSearch: while (parent) {\n\t\t\t\tif (parent.parentId === pageId) {\n\t\t\t\t\tshapeIsInPage = true\n\t\t\t\t\tbreak isInPageSearch\n\t\t\t\t}\n\t\t\t\tparent = this.getShape(parent.parentId)\n\t\t\t}\n\t\t}\n\n\t\treturn shapeIsInPage\n\t}\n\n\t/**\n\t * Get the id of the containing page for a given shape.\n\t *\n\t * @param shape - The shape to get the page id for.\n\t *\n\t * @returns The id of the page that contains the shape, or undefined if the shape is undefined.\n\t *\n\t * @public\n\t */\n\tgetAncestorPageId(shape?: TLShape | TLShapeId): TLPageId | undefined {\n\t\tconst id = typeof shape === 'string' ? shape : shape?.id\n\t\tconst _shape = id && this.getShape(id)\n\t\tif (!_shape) return undefined\n\t\tif (isPageId(_shape.parentId)) {\n\t\t\treturn _shape.parentId\n\t\t} else {\n\t\t\treturn this.getAncestorPageId(this.getShape(_shape.parentId))\n\t\t}\n\t}\n\n\t// Parents and children\n\n\t/**\n\t * A cache of parents to children.\n\t *\n\t * @internal\n\t */\n\tprivate readonly _parentIdsToChildIds: ReturnType\n\n\t/**\n\t * Reparent shapes to a new parent. This operation preserves the shape's current page positions /\n\t * rotations.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.reparentShapes([box1, box2], 'frame1')\n\t * editor.reparentShapes([box1.id, box2.id], 'frame1')\n\t * editor.reparentShapes([box1.id, box2.id], 'frame1', 4)\n\t * ```\n\t *\n\t * @param shapes - The shapes (or shape ids) of the shapes to reparent.\n\t * @param parentId - The id of the new parent shape.\n\t * @param insertIndex - The index to insert the children.\n\t *\n\t * @public\n\t */\n\treparentShapes(shapes: TLShapeId[] | TLShape[], parentId: TLParentId, insertIndex?: IndexKey) {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string' ? (shapes as TLShapeId[]) : shapes.map((s) => (s as TLShape).id)\n\t\tif (ids.length === 0) return this\n\n\t\tconst changes: TLShapePartial[] = []\n\n\t\tconst parentTransform = isPageId(parentId)\n\t\t\t? Mat.Identity()\n\t\t\t: this.getShapePageTransform(parentId)!\n\n\t\tconst parentPageRotation = parentTransform.rotation()\n\n\t\tlet indices: IndexKey[] = []\n\n\t\tconst sibs = compact(this.getSortedChildIdsForParent(parentId).map((id) => this.getShape(id)))\n\n\t\tif (insertIndex) {\n\t\t\tconst sibWithInsertIndex = sibs.find((s) => s.index === insertIndex)\n\t\t\tif (sibWithInsertIndex) {\n\t\t\t\t// If there's a sibling with the same index as the insert index...\n\t\t\t\tconst sibAbove = sibs[sibs.indexOf(sibWithInsertIndex) + 1]\n\t\t\t\tif (sibAbove) {\n\t\t\t\t\t// If the sibling has a sibling above it, insert the shapes\n\t\t\t\t\t// between the sibling and its sibling above it.\n\t\t\t\t\tindices = getIndicesBetween(insertIndex, sibAbove.index, ids.length)\n\t\t\t\t} else {\n\t\t\t\t\t// Or if the sibling is the top sibling, insert the shapes\n\t\t\t\t\t// above the sibling\n\t\t\t\t\tindices = getIndicesAbove(insertIndex, ids.length)\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// If there's no collision, then we can start at the insert index\n\t\t\t\tconst sibAbove = sibs.sort(sortByIndex).find((s) => s.index > insertIndex)\n\n\t\t\t\tif (sibAbove) {\n\t\t\t\t\t// If the siblings include a sibling with a higher index, insert the shapes\n\t\t\t\t\t// between the insert index and the sibling with the higher index.\n\t\t\t\t\tindices = getIndicesBetween(insertIndex, sibAbove.index, ids.length)\n\t\t\t\t} else {\n\t\t\t\t\t// Otherwise, we're at the top of the order, so insert the shapes above\n\t\t\t\t\t// the insert index.\n\t\t\t\t\tindices = getIndicesAbove(insertIndex, ids.length)\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\t// If insert index is not specified, start the index at the top.\n\t\t\tconst sib = sibs.length && sibs[sibs.length - 1]\n\t\t\tindices = sib ? getIndicesAbove(sib.index, ids.length) : getIndices(ids.length)\n\t\t}\n\n\t\tconst invertedParentTransform = parentTransform.clone().invert()\n\n\t\tconst shapesToReparent = compact(ids.map((id) => this.getShape(id)))\n\n\t\t// Ignore locked shapes so that we can reparent locked shapes, for example\n\t\t// when a locked shape's parent is deleted.\n\t\tthis.run(\n\t\t\t() => {\n\t\t\t\tfor (let i = 0; i < shapesToReparent.length; i++) {\n\t\t\t\t\tconst shape = shapesToReparent[i]\n\n\t\t\t\t\tconst pageTransform = this.getShapePageTransform(shape)!\n\t\t\t\t\tif (!pageTransform) continue\n\n\t\t\t\t\tconst pagePoint = pageTransform.point()\n\t\t\t\t\tif (!pagePoint) continue\n\n\t\t\t\t\tconst newPoint = invertedParentTransform.applyToPoint(pagePoint)\n\t\t\t\t\tconst newRotation = pageTransform.rotation() - parentPageRotation\n\n\t\t\t\t\tchanges.push({\n\t\t\t\t\t\tid: shape.id,\n\t\t\t\t\t\ttype: shape.type,\n\t\t\t\t\t\tparentId: parentId,\n\t\t\t\t\t\tx: newPoint.x,\n\t\t\t\t\t\ty: newPoint.y,\n\t\t\t\t\t\trotation: newRotation,\n\t\t\t\t\t\tindex: indices[i],\n\t\t\t\t\t})\n\t\t\t\t}\n\n\t\t\t\tthis.updateShapes(changes)\n\t\t\t},\n\t\t\t{ ignoreShapeLock: true }\n\t\t)\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Get the index above the highest child of a given parent.\n\t *\n\t * @param parent - The parent (or the id) of the parent.\n\t *\n\t * @returns The index.\n\t *\n\t * @public\n\t */\n\tgetHighestIndexForParent(parent: TLParentId | TLPage | TLShape): IndexKey {\n\t\tconst parentId = typeof parent === 'string' ? parent : parent.id\n\t\tconst children = this._parentIdsToChildIds.get()[parentId]\n\n\t\tif (!children || children.length === 0) {\n\t\t\treturn 'a1' as IndexKey\n\t\t}\n\t\tconst shape = this.getShape(children[children.length - 1])!\n\t\treturn getIndexAbove(shape.index)\n\t}\n\n\t/**\n\t * Get an array of all the children of a shape.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getSortedChildIdsForParent('frame1')\n\t * ```\n\t *\n\t * @param parent - The parent (or the id) of the parent shape.\n\t *\n\t * @public\n\t */\n\tgetSortedChildIdsForParent(parent: TLParentId | TLPage | TLShape): TLShapeId[] {\n\t\tconst parentId = typeof parent === 'string' ? parent : parent.id\n\t\tconst ids = this._parentIdsToChildIds.get()[parentId]\n\t\tif (!ids) return EMPTY_ARRAY\n\t\treturn ids\n\t}\n\n\t/**\n\t * Run a visitor function for all descendants of a shape.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.visitDescendants('frame1', myCallback)\n\t * ```\n\t *\n\t * @param parent - The parent (or the id) of the parent shape.\n\t * @param visitor - The visitor function.\n\t *\n\t * @public\n\t */\n\tvisitDescendants(\n\t\tparent: TLParentId | TLPage | TLShape,\n\t\tvisitor: (id: TLShapeId) => void | false\n\t): this {\n\t\tconst parentId = typeof parent === 'string' ? parent : parent.id\n\t\tconst children = this.getSortedChildIdsForParent(parentId)\n\t\tfor (const id of children) {\n\t\t\tif (visitor(id) === false) continue\n\t\t\tthis.visitDescendants(id, visitor)\n\t\t}\n\t\treturn this\n\t}\n\n\t/**\n\t * Get the shape ids of all descendants of the given shapes (including the shapes themselves). IDs are returned in z-index order.\n\t *\n\t * @param ids - The ids of the shapes to get descendants of.\n\t *\n\t * @returns The descendant ids.\n\t *\n\t * @public\n\t */\n\tgetShapeAndDescendantIds(ids: TLShapeId[]): Set {\n\t\tconst shapeIds = new Set()\n\t\tfor (const shape of ids.map((id) => this.getShape(id)!).sort(sortByIndex)) {\n\t\t\tshapeIds.add(shape.id)\n\t\t\tthis.visitDescendants(shape, (descendantId) => {\n\t\t\t\tshapeIds.add(descendantId)\n\t\t\t})\n\t\t}\n\t\treturn shapeIds\n\t}\n\n\t/**\n\t * Get the shape that some shapes should be dropped on at a given point.\n\t *\n\t * @param point - The point to find the parent for.\n\t * @param droppingShapes - The shapes that are being dropped.\n\t *\n\t * @returns The shape to drop on.\n\t *\n\t * @public\n\t */\n\tgetDroppingOverShape(point: VecLike, droppingShapes: TLShape[] = []) {\n\t\t// starting from the top...\n\t\tconst currentPageShapesSorted = this.getCurrentPageShapesSorted()\n\t\tfor (let i = currentPageShapesSorted.length - 1; i >= 0; i--) {\n\t\t\tconst shape = currentPageShapesSorted[i]\n\n\t\t\tif (\n\t\t\t\t// ignore hidden shapes\n\t\t\t\tthis.isShapeHidden(shape) ||\n\t\t\t\t// don't allow dropping on selected shapes\n\t\t\t\tthis.getSelectedShapeIds().includes(shape.id) ||\n\t\t\t\t// only allow shapes that can receive children\n\t\t\t\t!this.getShapeUtil(shape).canDropShapes(shape, droppingShapes) ||\n\t\t\t\t// don't allow dropping a shape on itself or one of it's children\n\t\t\t\tdroppingShapes.find((s) => s.id === shape.id || this.hasAncestor(shape, s.id))\n\t\t\t) {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\t// Only allow dropping into the masked page bounds of the shape, e.g. when a frame is\n\t\t\t// partially clipped by its own parent frame\n\t\t\tconst maskedPageBounds = this.getShapeMaskedPageBounds(shape.id)\n\n\t\t\tif (\n\t\t\t\tmaskedPageBounds &&\n\t\t\t\tmaskedPageBounds.containsPoint(point) &&\n\t\t\t\tthis.getShapeGeometry(shape).hitTestPoint(this.getPointInShapeSpace(shape, point), 0, true)\n\t\t\t) {\n\t\t\t\treturn shape\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Get the shape that should be selected when you click on a given shape, assuming there is\n\t * nothing already selected. It will not return anything higher than or including the current\n\t * focus layer.\n\t *\n\t * @param shape - The shape to get the outermost selectable shape for.\n\t * @param filter - A function to filter the selectable shapes.\n\t *\n\t * @returns The outermost selectable shape.\n\t *\n\t * @public\n\t */\n\tgetOutermostSelectableShape(\n\t\tshape: TLShape | TLShapeId,\n\t\tfilter?: (shape: TLShape) => boolean\n\t): TLShape {\n\t\tconst id = typeof shape === 'string' ? shape : shape.id\n\t\tconst freshShape = this.getShape(id)!\n\t\tlet match = freshShape\n\t\tlet node = freshShape as TLShape | undefined\n\n\t\tconst focusedGroup = this.getFocusedGroup()\n\n\t\twhile (node) {\n\t\t\tif (\n\t\t\t\tthis.isShapeOfType(node, 'group') &&\n\t\t\t\tfocusedGroup?.id !== node.id &&\n\t\t\t\t!this.hasAncestor(focusedGroup, node.id) &&\n\t\t\t\t(filter?.(node) ?? true)\n\t\t\t) {\n\t\t\t\tmatch = node\n\t\t\t} else if (focusedGroup?.id === node.id) {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tnode = this.getShapeParent(node)\n\t\t}\n\n\t\treturn match\n\t}\n\n\t/* -------------------- Bindings -------------------- */\n\n\t@computed\n\tprivate _getBindingsIndexCache() {\n\t\tconst index = bindingsIndex(this)\n\t\treturn this.store.createComputedCache('bindingsIndex', (shape) => {\n\t\t\treturn index.get().get(shape.id)\n\t\t})\n\t}\n\n\t/**\n\t * Get a binding from the store by its ID if it exists.\n\t */\n\tgetBinding(id: TLBindingId): TLBinding | undefined {\n\t\treturn this.store.get(id) as TLBinding | undefined\n\t}\n\n\t/**\n\t * Get all bindings of a certain type _from_ a particular shape. These are the bindings whose\n\t * `fromId` matched the shape's ID.\n\t */\n\tgetBindingsFromShape(\n\t\tshape: TLShape | TLShapeId,\n\t\ttype: Binding['type']\n\t): Binding[] {\n\t\tconst id = typeof shape === 'string' ? shape : shape.id\n\t\treturn this.getBindingsInvolvingShape(id).filter(\n\t\t\t(b) => b.fromId === id && b.type === type\n\t\t) as Binding[]\n\t}\n\n\t/**\n\t * Get all bindings of a certain type _to_ a particular shape. These are the bindings whose\n\t * `toId` matches the shape's ID.\n\t */\n\tgetBindingsToShape(\n\t\tshape: TLShape | TLShapeId,\n\t\ttype: Binding['type']\n\t): Binding[] {\n\t\tconst id = typeof shape === 'string' ? shape : shape.id\n\t\treturn this.getBindingsInvolvingShape(id).filter(\n\t\t\t(b) => b.toId === id && b.type === type\n\t\t) as Binding[]\n\t}\n\n\t/**\n\t * Get all bindings involving a particular shape. This includes bindings where the shape is the\n\t * `fromId` or `toId`. If a type is provided, only bindings of that type are returned.\n\t */\n\tgetBindingsInvolvingShape(\n\t\tshape: TLShape | TLShapeId,\n\t\ttype?: Binding['type']\n\t): Binding[] {\n\t\tconst id = typeof shape === 'string' ? shape : shape.id\n\t\tconst result = this._getBindingsIndexCache().get(id) ?? EMPTY_ARRAY\n\t\tif (!type) return result as Binding[]\n\t\treturn result.filter((b) => b.type === type) as Binding[]\n\t}\n\n\t/**\n\t * Create bindings from a list of partial bindings. You can omit the ID and most props of a\n\t * binding, but the `type`, `toId`, and `fromId` must all be provided.\n\t */\n\tcreateBindings(partials: TLBindingCreate[]) {\n\t\tconst bindings: TLBinding[] = []\n\t\tfor (const partial of partials) {\n\t\t\tconst fromShape = this.getShape(partial.fromId)\n\t\t\tconst toShape = this.getShape(partial.toId)\n\t\t\tif (!fromShape || !toShape) continue\n\t\t\tif (!this.canBindShapes({ fromShape, toShape, binding: partial })) continue\n\n\t\t\tconst util = this.getBindingUtil(partial.type)\n\t\t\tconst defaultProps = util.getDefaultProps()\n\t\t\tconst binding = this.store.schema.types.binding.create({\n\t\t\t\t...partial,\n\t\t\t\tid: partial.id ?? createBindingId(),\n\t\t\t\tprops: {\n\t\t\t\t\t...defaultProps,\n\t\t\t\t\t...partial.props,\n\t\t\t\t},\n\t\t\t}) as TLBinding\n\n\t\t\tbindings.push(binding)\n\t\t}\n\n\t\tthis.store.put(bindings)\n\t\treturn this\n\t}\n\n\t/**\n\t * Create a single binding from a partial. You can omit the ID and most props of a binding, but\n\t * the `type`, `toId`, and `fromId` must all be provided.\n\t */\n\tcreateBinding(partial: TLBindingCreate) {\n\t\treturn this.createBindings([partial])\n\t}\n\n\t/**\n\t * Update bindings from a list of partial bindings. Each partial must include an ID, which will\n\t * be used to match the binding to it's existing record. If there is no existing record, that\n\t * binding is skipped. The changes from the partial are merged into the existing record.\n\t */\n\tupdateBindings(partials: (TLBindingUpdate | null | undefined)[]) {\n\t\tconst updated: TLBinding[] = []\n\n\t\tfor (const partial of partials) {\n\t\t\tif (!partial) continue\n\n\t\t\tconst current = this.getBinding(partial.id)\n\t\t\tif (!current) continue\n\n\t\t\tconst updatedBinding = applyPartialToRecordWithProps(current, partial)\n\t\t\tif (updatedBinding === current) continue\n\n\t\t\tconst fromShape = this.getShape(updatedBinding.fromId)\n\t\t\tconst toShape = this.getShape(updatedBinding.toId)\n\t\t\tif (!fromShape || !toShape) continue\n\t\t\tif (!this.canBindShapes({ fromShape, toShape, binding: updatedBinding })) continue\n\n\t\t\tupdated.push(updatedBinding)\n\t\t}\n\n\t\tthis.store.put(updated)\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Update a binding from a partial binding. Each partial must include an ID, which will be used\n\t * to match the binding to it's existing record. If there is no existing record, that binding is\n\t * skipped. The changes from the partial are merged into the existing record.\n\t */\n\tupdateBinding(partial: TLBindingUpdate) {\n\t\treturn this.updateBindings([partial])\n\t}\n\n\t/**\n\t * Delete several bindings by their IDs. If a binding ID doesn't exist, it's ignored.\n\t */\n\tdeleteBindings(bindings: (TLBinding | TLBindingId)[], { isolateShapes = false } = {}) {\n\t\tconst ids = bindings.map((binding) => (typeof binding === 'string' ? binding : binding.id))\n\t\tif (isolateShapes) {\n\t\t\tthis.store.atomic(() => {\n\t\t\t\tfor (const id of ids) {\n\t\t\t\t\tconst binding = this.getBinding(id)\n\t\t\t\t\tif (!binding) continue\n\t\t\t\t\tconst util = this.getBindingUtil(binding)\n\t\t\t\t\tutil.onBeforeIsolateFromShape?.({ binding, removedShape: this.getShape(binding.toId)! })\n\t\t\t\t\tutil.onBeforeIsolateToShape?.({ binding, removedShape: this.getShape(binding.fromId)! })\n\t\t\t\t\tthis.store.remove([id])\n\t\t\t\t}\n\t\t\t})\n\t\t} else {\n\t\t\tthis.store.remove(ids)\n\t\t}\n\t\treturn this\n\t}\n\t/**\n\t * Delete a binding by its ID. If the binding doesn't exist, it's ignored.\n\t */\n\tdeleteBinding(binding: TLBinding | TLBindingId, opts?: Parameters[1]) {\n\t\treturn this.deleteBindings([binding], opts)\n\t}\n\tcanBindShapes({\n\t\tfromShape,\n\t\ttoShape,\n\t\tbinding,\n\t}: {\n\t\tfromShape: TLShape | { type: TLShape['type'] } | TLShape['type']\n\t\ttoShape: TLShape | { type: TLShape['type'] } | TLShape['type']\n\t\tbinding: TLBinding | { type: TLBinding['type'] } | TLBinding['type']\n\t}): boolean {\n\t\tconst fromShapeType = typeof fromShape === 'string' ? fromShape : fromShape.type\n\t\tconst toShapeType = typeof toShape === 'string' ? toShape : toShape.type\n\t\tconst bindingType = typeof binding === 'string' ? binding : binding.type\n\n\t\tconst canBindOpts = { fromShapeType, toShapeType, bindingType }\n\n\t\tif (fromShapeType === toShapeType) {\n\t\t\treturn this.getShapeUtil(fromShapeType).canBind(canBindOpts)\n\t\t}\n\n\t\treturn (\n\t\t\tthis.getShapeUtil(fromShapeType).canBind(canBindOpts) &&\n\t\t\tthis.getShapeUtil(toShapeType).canBind(canBindOpts)\n\t\t)\n\t}\n\n\t/* -------------------- Commands -------------------- */\n\n\t/**\n\t * Rotate shapes by a delta in radians.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.rotateShapesBy(editor.getSelectedShapeIds(), Math.PI)\n\t * editor.rotateShapesBy(editor.getSelectedShapeIds(), Math.PI / 2)\n\t * ```\n\t *\n\t * @param shapes - The shapes (or shape ids) of the shapes to move.\n\t * @param delta - The delta in radians to apply to the selection rotation.\n\t * @param opts - The options for the rotation.\n\t */\n\trotateShapesBy(\n\t\tshapes: TLShapeId[] | TLShape[],\n\t\tdelta: number,\n\t\topts?: { center?: VecLike }\n\t): this {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\n\t\tif (ids.length <= 0) return this\n\n\t\tconst snapshot = getRotationSnapshot({ editor: this, ids })\n\t\tif (!snapshot) return this\n\t\tapplyRotationToSnapshotShapes({\n\t\t\tdelta,\n\t\t\tsnapshot,\n\t\t\teditor: this,\n\t\t\tstage: 'one-off',\n\t\t\tcenterOverride: opts?.center,\n\t\t})\n\n\t\treturn this\n\t}\n\n\tprivate getChangesToTranslateShape(initialShape: TLShape, newShapeCoords: VecLike): TLShape {\n\t\tlet workingShape = initialShape\n\t\tconst util = this.getShapeUtil(initialShape)\n\n\t\tworkingShape = applyPartialToRecordWithProps(\n\t\t\tworkingShape,\n\t\t\tutil.onTranslateStart?.(workingShape) ?? undefined\n\t\t)\n\n\t\tworkingShape = applyPartialToRecordWithProps(workingShape, {\n\t\t\tid: initialShape.id,\n\t\t\ttype: initialShape.type,\n\t\t\tx: newShapeCoords.x,\n\t\t\ty: newShapeCoords.y,\n\t\t})\n\n\t\tworkingShape = applyPartialToRecordWithProps(\n\t\t\tworkingShape,\n\t\t\tutil.onTranslate?.(initialShape, workingShape) ?? undefined\n\t\t)\n\n\t\tworkingShape = applyPartialToRecordWithProps(\n\t\t\tworkingShape,\n\t\t\tutil.onTranslateEnd?.(initialShape, workingShape) ?? undefined\n\t\t)\n\n\t\treturn workingShape\n\t}\n\n\t/**\n\t * Move shapes by a delta.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.nudgeShapes(['box1', 'box2'], { x: 8, y: 8 })\n\t * ```\n\t *\n\t * @param shapes - The shapes (or shape ids) to move.\n\t * @param offset - The offset to apply to the shapes.\n\t */\n\tnudgeShapes(shapes: TLShapeId[] | TLShape[], offset: VecLike): this {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\n\t\tif (ids.length <= 0) return this\n\t\tconst changes: TLShapePartial[] = []\n\n\t\tfor (const id of ids) {\n\t\t\tconst shape = this.getShape(id)!\n\t\t\tconst localDelta = Vec.From(offset)\n\t\t\tconst parentTransform = this.getShapeParentTransform(shape)\n\t\t\tif (parentTransform) localDelta.rot(-parentTransform.rotation())\n\n\t\t\tchanges.push(this.getChangesToTranslateShape(shape, localDelta.add(shape)))\n\t\t}\n\n\t\tthis.updateShapes(changes)\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Duplicate shapes.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.duplicateShapes(['box1', 'box2'], { x: 8, y: 8 })\n\t * editor.duplicateShapes(editor.getSelectedShapes(), { x: 8, y: 8 })\n\t * ```\n\t *\n\t * @param shapes - The shapes (or shape ids) to duplicate.\n\t * @param offset - The offset (in pixels) to apply to the duplicated shapes.\n\t *\n\t * @public\n\t */\n\tduplicateShapes(shapes: TLShapeId[] | TLShape[], offset?: VecLike): this {\n\t\tthis.run(() => {\n\t\t\tconst ids =\n\t\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\n\t\t\tif (ids.length <= 0) return this\n\n\t\t\tconst initialIds = new Set(ids)\n\t\t\tconst shapeIdSet = this.getShapeAndDescendantIds(ids)\n\n\t\t\tconst orderedShapeIds = [...shapeIdSet].reverse()\n\t\t\tconst shapeIds = new Map()\n\t\t\tfor (const shapeId of shapeIdSet) {\n\t\t\t\tshapeIds.set(shapeId, createShapeId())\n\t\t\t}\n\n\t\t\tconst { shapesToCreateWithOriginals, bindingsToCreate } = withIsolatedShapes(\n\t\t\t\tthis,\n\t\t\t\tshapeIdSet,\n\t\t\t\t(bindingIdsToMaintain) => {\n\t\t\t\t\tconst bindingsToCreate: TLBinding[] = []\n\t\t\t\t\tfor (const originalId of bindingIdsToMaintain) {\n\t\t\t\t\t\tconst originalBinding = this.getBinding(originalId)\n\t\t\t\t\t\tif (!originalBinding) continue\n\n\t\t\t\t\t\tconst duplicatedId = createBindingId()\n\t\t\t\t\t\tbindingsToCreate.push({\n\t\t\t\t\t\t\t...originalBinding,\n\t\t\t\t\t\t\tid: duplicatedId,\n\t\t\t\t\t\t\tfromId: assertExists(shapeIds.get(originalBinding.fromId)),\n\t\t\t\t\t\t\ttoId: assertExists(shapeIds.get(originalBinding.toId)),\n\t\t\t\t\t\t})\n\t\t\t\t\t}\n\n\t\t\t\t\tconst shapesToCreateWithOriginals: { shape: TLShape; originalShape: TLShape }[] = []\n\t\t\t\t\tfor (const originalId of orderedShapeIds) {\n\t\t\t\t\t\tconst duplicatedId = assertExists(shapeIds.get(originalId))\n\t\t\t\t\t\tconst originalShape = this.getShape(originalId)\n\t\t\t\t\t\tif (!originalShape) continue\n\n\t\t\t\t\t\tlet ox = 0\n\t\t\t\t\t\tlet oy = 0\n\n\t\t\t\t\t\tif (offset && initialIds.has(originalId)) {\n\t\t\t\t\t\t\tconst parentTransform = this.getShapeParentTransform(originalShape)\n\t\t\t\t\t\t\tconst vec = new Vec(offset.x, offset.y).rot(-parentTransform!.rotation())\n\t\t\t\t\t\t\tox = vec.x\n\t\t\t\t\t\t\toy = vec.y\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tshapesToCreateWithOriginals.push({\n\t\t\t\t\t\t\tshape: {\n\t\t\t\t\t\t\t\t...originalShape,\n\t\t\t\t\t\t\t\tid: duplicatedId,\n\t\t\t\t\t\t\t\tx: originalShape.x + ox,\n\t\t\t\t\t\t\t\ty: originalShape.y + oy,\n\t\t\t\t\t\t\t\t// Use a dummy index for now, it will get updated outside of the `withIsolatedShapes`\n\t\t\t\t\t\t\t\tindex: 'a1' as IndexKey,\n\t\t\t\t\t\t\t\tparentId:\n\t\t\t\t\t\t\t\t\tshapeIds.get(originalShape.parentId as TLShapeId) ?? originalShape.parentId,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\toriginalShape,\n\t\t\t\t\t\t})\n\t\t\t\t\t}\n\n\t\t\t\t\treturn { shapesToCreateWithOriginals, bindingsToCreate }\n\t\t\t\t}\n\t\t\t)\n\n\t\t\t// We will update the indexes after the `withIsolatedShapes`, since we cannot rely on the indexes\n\t\t\t// to be correct inside of it.\n\t\t\tshapesToCreateWithOriginals.forEach(({ shape, originalShape }) => {\n\t\t\t\tconst parentId = originalShape.parentId\n\t\t\t\tconst siblings = this.getSortedChildIdsForParent(parentId)\n\t\t\t\tconst currentIndex = siblings.indexOf(originalShape.id)\n\t\t\t\tconst siblingAboveId = siblings[currentIndex + 1]\n\t\t\t\tconst siblingAbove = siblingAboveId ? this.getShape(siblingAboveId) : undefined\n\n\t\t\t\tconst index = getIndexBetween(originalShape.index, siblingAbove?.index)\n\n\t\t\t\tshape.index = index\n\t\t\t})\n\t\t\tconst shapesToCreate = shapesToCreateWithOriginals.map(({ shape }) => shape)\n\n\t\t\tconst maxShapesReached =\n\t\t\t\tshapesToCreate.length + this.getCurrentPageShapeIds().size > this.options.maxShapesPerPage\n\n\t\t\tif (maxShapesReached) {\n\t\t\t\talertMaxShapes(this)\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tthis.createShapes(shapesToCreate)\n\t\t\tthis.createBindings(bindingsToCreate)\n\t\t\tthis.setSelectedShapes(compact(ids.map((id) => shapeIds.get(id))))\n\n\t\t\tif (offset !== undefined) {\n\t\t\t\t// If we've offset the duplicated shapes, check to see whether their new bounds is entirely\n\t\t\t\t// contained in the current viewport. If not, then animate the camera to be centered on the\n\t\t\t\t// new shapes.\n\t\t\t\tconst selectionPageBounds = this.getSelectionPageBounds()\n\t\t\t\tconst viewportPageBounds = this.getViewportPageBounds()\n\t\t\t\tif (selectionPageBounds && !viewportPageBounds.contains(selectionPageBounds)) {\n\t\t\t\t\tthis.centerOnPoint(selectionPageBounds.center, {\n\t\t\t\t\t\tanimation: { duration: this.options.animationMediumMs },\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t}\n\t\t})\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Move shapes to page.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.moveShapesToPage(['box1', 'box2'], 'page1')\n\t * ```\n\t *\n\t * @param shapes - The shapes (or shape ids) of the shapes to move.\n\t * @param pageId - The id of the page where the shapes will be moved.\n\t *\n\t * @public\n\t */\n\tmoveShapesToPage(shapes: TLShapeId[] | TLShape[], pageId: TLPageId): this {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\n\t\tif (ids.length === 0) return this\n\t\tif (this.getIsReadonly()) return this\n\n\t\tconst currentPageId = this.getCurrentPageId()\n\n\t\tif (pageId === currentPageId) return this\n\t\tif (!this.store.has(pageId)) return this\n\n\t\t// Basically copy the shapes\n\t\tconst content = this.getContentFromCurrentPage(ids)\n\n\t\t// Just to be sure\n\t\tif (!content) return this\n\n\t\t// If there is no space on pageId, or if the selected shapes\n\t\t// would take the new page above the limit, don't move the shapes\n\t\tif (this.getPageShapeIds(pageId).size + content.shapes.length > this.options.maxShapesPerPage) {\n\t\t\talertMaxShapes(this, pageId)\n\t\t\treturn this\n\t\t}\n\n\t\tconst fromPageZ = this.getCamera().z\n\n\t\tthis.run(() => {\n\t\t\t// Delete the shapes on the current page\n\t\t\tthis.deleteShapes(ids)\n\n\t\t\t// Move to the next page\n\t\t\tthis.setCurrentPage(pageId)\n\n\t\t\t// Put the shape content onto the new page; parents and indices will\n\t\t\t// be taken care of by the putContent method; make sure to pop any focus\n\t\t\t// layers so that the content will be put onto the page.\n\t\t\tthis.setFocusedGroup(null)\n\t\t\tthis.selectNone()\n\t\t\tthis.putContentOntoCurrentPage(content, {\n\t\t\t\tselect: true,\n\t\t\t\tpreserveIds: true,\n\t\t\t\tpreservePosition: true,\n\t\t\t})\n\n\t\t\t// Force the new page's camera to be at the same zoom level as the\n\t\t\t// \"from\" page's camera, then center the \"to\" page's camera on the\n\t\t\t// pasted shapes\n\t\t\tthis.setCamera({ ...this.getCamera(), z: fromPageZ })\n\t\t\tthis.centerOnPoint(this.getSelectionRotatedPageBounds()!.center)\n\t\t})\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Toggle the lock state of one or more shapes. If there is a mix of locked and unlocked shapes, all shapes will be locked.\n\t *\n\t * @param shapes - The shapes (or shape ids) to toggle.\n\t *\n\t * @public\n\t */\n\ttoggleLock(shapes: TLShapeId[] | TLShape[]): this {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\n\t\tif (this.getIsReadonly() || ids.length === 0) return this\n\n\t\tlet allLocked = true,\n\t\t\tallUnlocked = true\n\t\tconst shapesToToggle: TLShape[] = []\n\t\tfor (const id of ids) {\n\t\t\tconst shape = this.getShape(id)\n\t\t\tif (shape) {\n\t\t\t\tshapesToToggle.push(shape)\n\t\t\t\tif (shape.isLocked) {\n\t\t\t\t\tallUnlocked = false\n\t\t\t\t} else {\n\t\t\t\t\tallLocked = false\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tthis.run(() => {\n\t\t\tif (allUnlocked) {\n\t\t\t\tthis.updateShapes(\n\t\t\t\t\tshapesToToggle.map((shape) => ({ id: shape.id, type: shape.type, isLocked: true }))\n\t\t\t\t)\n\t\t\t\tthis.setSelectedShapes([])\n\t\t\t} else if (allLocked) {\n\t\t\t\tthis.updateShapes(\n\t\t\t\t\tshapesToToggle.map((shape) => ({ id: shape.id, type: shape.type, isLocked: false }))\n\t\t\t\t)\n\t\t\t} else {\n\t\t\t\tthis.updateShapes(\n\t\t\t\t\tshapesToToggle.map((shape) => ({ id: shape.id, type: shape.type, isLocked: true }))\n\t\t\t\t)\n\t\t\t}\n\t\t})\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Send shapes to the back of the page's object list.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.sendToBack(['id1', 'id2'])\n\t * editor.sendToBack(box1, box2)\n\t * ```\n\t *\n\t * @param shapes - The shapes (or shape ids) to move.\n\t *\n\t * @public\n\t */\n\tsendToBack(shapes: TLShapeId[] | TLShape[]): this {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\t\tconst changes = getReorderingShapesChanges(this, 'toBack', ids as TLShapeId[])\n\t\tif (changes) this.updateShapes(changes)\n\t\treturn this\n\t}\n\n\t/**\n\t * Send shapes backward in the page's object list.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.sendBackward(['id1', 'id2'])\n\t * editor.sendBackward([box1, box2])\n\t * ```\n\t *\n\t * @param shapes - The shapes (or shape ids) to move.\n\t *\n\t * @public\n\t */\n\tsendBackward(shapes: TLShapeId[] | TLShape[]): this {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\t\tconst changes = getReorderingShapesChanges(this, 'backward', ids as TLShapeId[])\n\t\tif (changes) this.updateShapes(changes)\n\t\treturn this\n\t}\n\n\t/**\n\t * Bring shapes forward in the page's object list.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.bringForward(['id1', 'id2'])\n\t * editor.bringForward(box1, box2)\n\t * ```\n\t *\n\t * @param shapes - The shapes (or shape ids) to move.\n\t *\n\t * @public\n\t */\n\tbringForward(shapes: TLShapeId[] | TLShape[]): this {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\t\tconst changes = getReorderingShapesChanges(this, 'forward', ids as TLShapeId[])\n\t\tif (changes) this.updateShapes(changes)\n\t\treturn this\n\t}\n\n\t/**\n\t * Bring shapes to the front of the page's object list.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.bringToFront(['id1', 'id2'])\n\t * editor.bringToFront([box1, box2])\n\t * ```\n\t *\n\t * @param shapes - The shapes (or shape ids) to move.\n\t *\n\t * @public\n\t */\n\tbringToFront(shapes: TLShapeId[] | TLShape[]): this {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\t\tconst changes = getReorderingShapesChanges(this, 'toFront', ids as TLShapeId[])\n\t\tif (changes) this.updateShapes(changes)\n\t\treturn this\n\t}\n\n\t/**\n\t * Flip shape positions.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.flipShapes([box1, box2], 'horizontal', 32)\n\t * editor.flipShapes(editor.getSelectedShapeIds(), 'horizontal', 32)\n\t * ```\n\t *\n\t * @param shapes - The ids of the shapes to flip.\n\t * @param operation - Whether to flip horizontally or vertically.\n\t *\n\t * @public\n\t */\n\tflipShapes(shapes: TLShapeId[] | TLShape[], operation: 'horizontal' | 'vertical'): this {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\n\t\tif (this.getIsReadonly()) return this\n\n\t\tlet shapesToFlip = compact(ids.map((id) => this.getShape(id)))\n\n\t\tif (!shapesToFlip.length) return this\n\n\t\tshapesToFlip = compact(\n\t\t\tshapesToFlip\n\t\t\t\t.map((shape) => {\n\t\t\t\t\tif (this.isShapeOfType(shape, 'group')) {\n\t\t\t\t\t\treturn this.getSortedChildIdsForParent(shape.id).map((id) => this.getShape(id))\n\t\t\t\t\t}\n\n\t\t\t\t\treturn shape\n\t\t\t\t})\n\t\t\t\t.flat()\n\t\t)\n\n\t\tconst scaleOriginPage = Box.Common(\n\t\t\tcompact(shapesToFlip.map((id) => this.getShapePageBounds(id)))\n\t\t).center\n\n\t\tthis.run(() => {\n\t\t\tfor (const shape of shapesToFlip) {\n\t\t\t\tconst bounds = this.getShapeGeometry(shape).bounds\n\t\t\t\tconst initialPageTransform = this.getShapePageTransform(shape.id)\n\t\t\t\tif (!initialPageTransform) continue\n\t\t\t\tthis.resizeShape(\n\t\t\t\t\tshape.id,\n\t\t\t\t\t{ x: operation === 'horizontal' ? -1 : 1, y: operation === 'vertical' ? -1 : 1 },\n\t\t\t\t\t{\n\t\t\t\t\t\tinitialBounds: bounds,\n\t\t\t\t\t\tinitialPageTransform,\n\t\t\t\t\t\tinitialShape: shape,\n\t\t\t\t\t\tmode: 'scale_shape',\n\t\t\t\t\t\tisAspectRatioLocked: this.getShapeUtil(shape).isAspectRatioLocked(shape),\n\t\t\t\t\t\tscaleOrigin: scaleOriginPage,\n\t\t\t\t\t\tscaleAxisRotation: 0,\n\t\t\t\t\t}\n\t\t\t\t)\n\t\t\t}\n\t\t})\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Stack shape.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.stackShapes([box1, box2], 'horizontal', 32)\n\t * editor.stackShapes(editor.getSelectedShapeIds(), 'horizontal', 32)\n\t * ```\n\t *\n\t * @param shapes - The shapes (or shape ids) to stack.\n\t * @param operation - Whether to stack horizontally or vertically.\n\t * @param gap - The gap to leave between shapes.\n\t *\n\t * @public\n\t */\n\tstackShapes(\n\t\tshapes: TLShapeId[] | TLShape[],\n\t\toperation: 'horizontal' | 'vertical',\n\t\tgap: number\n\t): this {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\t\tif (this.getIsReadonly()) return this\n\n\t\tconst shapesToStack = ids\n\t\t\t.map((id) => this.getShape(id)) // always fresh shapes\n\t\t\t.filter((shape): shape is TLShape => {\n\t\t\t\tif (!shape) return false\n\n\t\t\t\treturn this.getShapeUtil(shape).canBeLaidOut(shape)\n\t\t\t})\n\n\t\tconst len = shapesToStack.length\n\n\t\tif ((gap === 0 && len < 3) || len < 2) return this\n\n\t\tconst pageBounds = Object.fromEntries(\n\t\t\tshapesToStack.map((shape) => [shape.id, this.getShapePageBounds(shape)!])\n\t\t)\n\n\t\tlet val: 'x' | 'y'\n\t\tlet min: 'minX' | 'minY'\n\t\tlet max: 'maxX' | 'maxY'\n\t\tlet dim: 'width' | 'height'\n\n\t\tif (operation === 'horizontal') {\n\t\t\tval = 'x'\n\t\t\tmin = 'minX'\n\t\t\tmax = 'maxX'\n\t\t\tdim = 'width'\n\t\t} else {\n\t\t\tval = 'y'\n\t\t\tmin = 'minY'\n\t\t\tmax = 'maxY'\n\t\t\tdim = 'height'\n\t\t}\n\n\t\tlet shapeGap: number\n\n\t\tif (gap === 0) {\n\t\t\tconst gaps: { gap: number; count: number }[] = []\n\n\t\t\tshapesToStack.sort((a, b) => pageBounds[a.id][min] - pageBounds[b.id][min])\n\n\t\t\t// Collect all of the gaps between shapes. We want to find\n\t\t\t// patterns (equal gaps between shapes) and use the most common\n\t\t\t// one as the gap for all of the shapes.\n\t\t\tfor (let i = 0; i < len - 1; i++) {\n\t\t\t\tconst shape = shapesToStack[i]\n\t\t\t\tconst nextShape = shapesToStack[i + 1]\n\n\t\t\t\tconst bounds = pageBounds[shape.id]\n\t\t\t\tconst nextBounds = pageBounds[nextShape.id]\n\n\t\t\t\tconst gap = nextBounds[min] - bounds[max]\n\n\t\t\t\tconst current = gaps.find((g) => g.gap === gap)\n\n\t\t\t\tif (current) {\n\t\t\t\t\tcurrent.count++\n\t\t\t\t} else {\n\t\t\t\t\tgaps.push({ gap, count: 1 })\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Which gap is the most common?\n\t\t\tlet maxCount = 0\n\t\t\tgaps.forEach((g) => {\n\t\t\t\tif (g.count > maxCount) {\n\t\t\t\t\tmaxCount = g.count\n\t\t\t\t\tshapeGap = g.gap\n\t\t\t\t}\n\t\t\t})\n\n\t\t\t// If there is no most-common gap, use the average gap.\n\t\t\tif (maxCount === 1) {\n\t\t\t\tshapeGap = Math.max(0, gaps.reduce((a, c) => a + c.gap * c.count, 0) / (len - 1))\n\t\t\t}\n\t\t} else {\n\t\t\t// If a gap was provided, then use that instead.\n\t\t\tshapeGap = gap\n\t\t}\n\n\t\tconst changes: TLShapePartial[] = []\n\n\t\tlet v = pageBounds[shapesToStack[0].id][max]\n\n\t\tshapesToStack.forEach((shape, i) => {\n\t\t\tif (i === 0) return\n\n\t\t\tconst delta = { x: 0, y: 0 }\n\t\t\tdelta[val] = v + shapeGap - pageBounds[shape.id][val]\n\n\t\t\tconst parent = this.getShapeParent(shape)\n\t\t\tconst localDelta = parent\n\t\t\t\t? Vec.Rot(delta, -this.getShapePageTransform(parent)!.decompose().rotation)\n\t\t\t\t: delta\n\n\t\t\tconst translateStartChanges = this.getShapeUtil(shape).onTranslateStart?.(shape)\n\n\t\t\tchanges.push(\n\t\t\t\ttranslateStartChanges\n\t\t\t\t\t? {\n\t\t\t\t\t\t\t...translateStartChanges,\n\t\t\t\t\t\t\t[val]: shape[val] + localDelta[val],\n\t\t\t\t\t\t}\n\t\t\t\t\t: {\n\t\t\t\t\t\t\tid: shape.id as any,\n\t\t\t\t\t\t\ttype: shape.type,\n\t\t\t\t\t\t\t[val]: shape[val] + localDelta[val],\n\t\t\t\t\t\t}\n\t\t\t)\n\n\t\t\tv += pageBounds[shape.id][dim] + shapeGap\n\t\t})\n\n\t\tthis.updateShapes(changes)\n\t\treturn this\n\t}\n\n\t/**\n\t * Pack shapes into a grid centered on their current position. Based on potpack (https://github.com/mapbox/potpack).\n\t *\n\t * @example\n\t * ```ts\n\t * editor.packShapes([box1, box2], 32)\n\t * editor.packShapes(editor.getSelectedShapeIds(), 32)\n\t * ```\n\t *\n\t *\n\t * @param shapes - The shapes (or shape ids) to pack.\n\t * @param gap - The padding to apply to the packed shapes. Defaults to 16.\n\t */\n\tpackShapes(shapes: TLShapeId[] | TLShape[], gap: number): this {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\n\t\tif (this.getIsReadonly()) return this\n\t\tif (ids.length < 2) return this\n\n\t\tconst shapesToPack = ids\n\t\t\t.map((id) => this.getShape(id)) // always fresh shapes\n\t\t\t.filter((shape): shape is TLShape => {\n\t\t\t\tif (!shape) return false\n\n\t\t\t\treturn this.getShapeUtil(shape).canBeLaidOut(shape)\n\t\t\t})\n\t\tconst shapePageBounds: Record = {}\n\t\tconst nextShapePageBounds: Record = {}\n\n\t\tlet shape: TLShape,\n\t\t\tbounds: Box,\n\t\t\tarea = 0\n\n\t\tfor (let i = 0; i < shapesToPack.length; i++) {\n\t\t\tshape = shapesToPack[i]\n\t\t\tbounds = this.getShapePageBounds(shape)!\n\t\t\tshapePageBounds[shape.id] = bounds\n\t\t\tnextShapePageBounds[shape.id] = bounds.clone()\n\t\t\tarea += bounds.width * bounds.height\n\t\t}\n\n\t\tconst commonBounds = Box.Common(compact(Object.values(shapePageBounds)))\n\n\t\tconst maxWidth = commonBounds.width\n\n\t\t// sort the shapes by height, descending\n\t\tshapesToPack.sort((a, b) => shapePageBounds[b.id].height - shapePageBounds[a.id].height)\n\n\t\t// Start with is (sort of) the square of the area\n\t\tconst startWidth = Math.max(Math.ceil(Math.sqrt(area / 0.95)), maxWidth)\n\n\t\t// first shape fills the width and is infinitely tall\n\t\tconst spaces: Box[] = [new Box(commonBounds.x, commonBounds.y, startWidth, Infinity)]\n\n\t\tlet width = 0\n\t\tlet height = 0\n\t\tlet space: Box\n\t\tlet last: Box\n\n\t\tfor (let i = 0; i < shapesToPack.length; i++) {\n\t\t\tshape = shapesToPack[i]\n\t\t\tbounds = nextShapePageBounds[shape.id]\n\n\t\t\t// starting at the back (smaller shapes)\n\t\t\tfor (let i = spaces.length - 1; i >= 0; i--) {\n\t\t\t\tspace = spaces[i]\n\n\t\t\t\t// find a space that is big enough to contain the shape\n\t\t\t\tif (bounds.width > space.width || bounds.height > space.height) continue\n\n\t\t\t\t// add the shape to its top-left corner\n\t\t\t\tbounds.x = space.x\n\t\t\t\tbounds.y = space.y\n\n\t\t\t\theight = Math.max(height, bounds.maxY)\n\t\t\t\twidth = Math.max(width, bounds.maxX)\n\n\t\t\t\tif (bounds.width === space.width && bounds.height === space.height) {\n\t\t\t\t\t// remove the space on a perfect fit\n\t\t\t\t\tlast = spaces.pop()!\n\t\t\t\t\tif (i < spaces.length) spaces[i] = last\n\t\t\t\t} else if (bounds.height === space.height) {\n\t\t\t\t\t// fit the shape into the space (width)\n\t\t\t\t\tspace.x += bounds.width + gap\n\t\t\t\t\tspace.width -= bounds.width + gap\n\t\t\t\t} else if (bounds.width === space.width) {\n\t\t\t\t\t// fit the shape into the space (height)\n\t\t\t\t\tspace.y += bounds.height + gap\n\t\t\t\t\tspace.height -= bounds.height + gap\n\t\t\t\t} else {\n\t\t\t\t\t// split the space into two spaces\n\t\t\t\t\tspaces.push(\n\t\t\t\t\t\tnew Box(\n\t\t\t\t\t\t\tspace.x + (bounds.width + gap),\n\t\t\t\t\t\t\tspace.y,\n\t\t\t\t\t\t\tspace.width - (bounds.width + gap),\n\t\t\t\t\t\t\tbounds.height\n\t\t\t\t\t\t)\n\t\t\t\t\t)\n\t\t\t\t\tspace.y += bounds.height + gap\n\t\t\t\t\tspace.height -= bounds.height + gap\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\n\t\tconst commonAfter = Box.Common(Object.values(nextShapePageBounds))\n\t\tconst centerDelta = Vec.Sub(commonBounds.center, commonAfter.center)\n\n\t\tlet nextBounds: Box\n\n\t\tconst changes: TLShapePartial[] = []\n\n\t\tfor (let i = 0; i < shapesToPack.length; i++) {\n\t\t\tshape = shapesToPack[i]\n\t\t\tbounds = shapePageBounds[shape.id]\n\t\t\tnextBounds = nextShapePageBounds[shape.id]\n\n\t\t\tconst delta = Vec.Sub(nextBounds.point, bounds.point).add(centerDelta)\n\t\t\tconst parentTransform = this.getShapeParentTransform(shape)\n\t\t\tif (parentTransform) delta.rot(-parentTransform.rotation())\n\n\t\t\tconst change: TLShapePartial = {\n\t\t\t\tid: shape.id,\n\t\t\t\ttype: shape.type,\n\t\t\t\tx: shape.x + delta.x,\n\t\t\t\ty: shape.y + delta.y,\n\t\t\t}\n\n\t\t\tconst translateStartChange = this.getShapeUtil(shape).onTranslateStart?.({\n\t\t\t\t...shape,\n\t\t\t\t...change,\n\t\t\t})\n\n\t\t\tif (translateStartChange) {\n\t\t\t\tchanges.push({ ...change, ...translateStartChange })\n\t\t\t} else {\n\t\t\t\tchanges.push(change)\n\t\t\t}\n\t\t}\n\n\t\tif (changes.length) {\n\t\t\tthis.updateShapes(changes)\n\t\t}\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Align shape positions.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.alignShapes([box1, box2], 'left')\n\t * editor.alignShapes(editor.getSelectedShapeIds(), 'left')\n\t * ```\n\t *\n\t * @param shapes - The shapes (or shape ids) to align.\n\t * @param operation - The align operation to apply.\n\t *\n\t * @public\n\t */\n\n\talignShapes(\n\t\tshapes: TLShapeId[] | TLShape[],\n\t\toperation: 'left' | 'center-horizontal' | 'right' | 'top' | 'center-vertical' | 'bottom'\n\t): this {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\n\t\tif (this.getIsReadonly()) return this\n\t\tif (ids.length < 2) return this\n\n\t\tconst shapesToAlign = compact(ids.map((id) => this.getShape(id))) // always fresh shapes\n\t\tconst shapePageBounds = Object.fromEntries(\n\t\t\tshapesToAlign.map((shape) => [shape.id, this.getShapePageBounds(shape)])\n\t\t)\n\t\tconst commonBounds = Box.Common(compact(Object.values(shapePageBounds)))\n\n\t\tconst changes: TLShapePartial[] = []\n\n\t\tshapesToAlign.forEach((shape) => {\n\t\t\tconst pageBounds = shapePageBounds[shape.id]\n\t\t\tif (!pageBounds) return\n\n\t\t\tconst delta = { x: 0, y: 0 }\n\n\t\t\tswitch (operation) {\n\t\t\t\tcase 'top': {\n\t\t\t\t\tdelta.y = commonBounds.minY - pageBounds.minY\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase 'center-vertical': {\n\t\t\t\t\tdelta.y = commonBounds.midY - pageBounds.minY - pageBounds.height / 2\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase 'bottom': {\n\t\t\t\t\tdelta.y = commonBounds.maxY - pageBounds.minY - pageBounds.height\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase 'left': {\n\t\t\t\t\tdelta.x = commonBounds.minX - pageBounds.minX\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase 'center-horizontal': {\n\t\t\t\t\tdelta.x = commonBounds.midX - pageBounds.minX - pageBounds.width / 2\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase 'right': {\n\t\t\t\t\tdelta.x = commonBounds.maxX - pageBounds.minX - pageBounds.width\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst parent = this.getShapeParent(shape)\n\t\t\tconst localDelta = parent\n\t\t\t\t? Vec.Rot(delta, -this.getShapePageTransform(parent)!.decompose().rotation)\n\t\t\t\t: delta\n\n\t\t\tchanges.push(this.getChangesToTranslateShape(shape, Vec.Add(shape, localDelta)))\n\t\t})\n\n\t\tthis.updateShapes(changes)\n\t\treturn this\n\t}\n\n\t/**\n\t * Distribute shape positions.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.distributeShapes([box1, box2], 'horizontal')\n\t * editor.distributeShapes(editor.getSelectedShapeIds(), 'horizontal')\n\t * ```\n\t *\n\t * @param shapes - The shapes (or shape ids) to distribute.\n\t * @param operation - Whether to distribute shapes horizontally or vertically.\n\t *\n\t * @public\n\t */\n\tdistributeShapes(shapes: TLShapeId[] | TLShape[], operation: 'horizontal' | 'vertical'): this {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\n\t\tif (this.getIsReadonly()) return this\n\t\tif (ids.length < 3) return this\n\n\t\tconst len = ids.length\n\t\tconst shapesToDistribute = compact(ids.map((id) => this.getShape(id))) // always fresh shapes\n\t\tconst pageBounds = Object.fromEntries(\n\t\t\tshapesToDistribute.map((shape) => [shape.id, this.getShapePageBounds(shape)!])\n\t\t)\n\n\t\tlet val: 'x' | 'y'\n\t\tlet min: 'minX' | 'minY'\n\t\tlet max: 'maxX' | 'maxY'\n\t\tlet mid: 'midX' | 'midY'\n\t\tlet dim: 'width' | 'height'\n\n\t\tif (operation === 'horizontal') {\n\t\t\tval = 'x'\n\t\t\tmin = 'minX'\n\t\t\tmax = 'maxX'\n\t\t\tmid = 'midX'\n\t\t\tdim = 'width'\n\t\t} else {\n\t\t\tval = 'y'\n\t\t\tmin = 'minY'\n\t\t\tmax = 'maxY'\n\t\t\tmid = 'midY'\n\t\t\tdim = 'height'\n\t\t}\n\t\tconst changes: TLShapePartial[] = []\n\n\t\t// Clustered\n\t\tconst first = shapesToDistribute.sort(\n\t\t\t(a, b) => pageBounds[a.id][min] - pageBounds[b.id][min]\n\t\t)[0]\n\t\tconst last = shapesToDistribute.sort((a, b) => pageBounds[b.id][max] - pageBounds[a.id][max])[0]\n\n\t\tconst midFirst = pageBounds[first.id][mid]\n\t\tconst step = (pageBounds[last.id][mid] - midFirst) / (len - 1)\n\t\tconst v = midFirst + step\n\n\t\tshapesToDistribute\n\t\t\t.filter((shape) => shape !== first && shape !== last)\n\t\t\t.sort((a, b) => pageBounds[a.id][mid] - pageBounds[b.id][mid])\n\t\t\t.forEach((shape, i) => {\n\t\t\t\tconst delta = { x: 0, y: 0 }\n\t\t\t\tdelta[val] = v + step * i - pageBounds[shape.id][dim] / 2 - pageBounds[shape.id][val]\n\n\t\t\t\tconst parent = this.getShapeParent(shape)\n\t\t\t\tconst localDelta = parent\n\t\t\t\t\t? Vec.Rot(delta, -this.getShapePageTransform(parent)!.rotation())\n\t\t\t\t\t: delta\n\n\t\t\t\tchanges.push(this.getChangesToTranslateShape(shape, Vec.Add(shape, localDelta)))\n\t\t\t})\n\n\t\tthis.updateShapes(changes)\n\t\treturn this\n\t}\n\n\t/**\n\t * Stretch shape sizes and positions to fill their common bounding box.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.stretchShapes([box1, box2], 'horizontal')\n\t * editor.stretchShapes(editor.getSelectedShapeIds(), 'horizontal')\n\t * ```\n\t *\n\t * @param shapes - The shapes (or shape ids) to stretch.\n\t * @param operation - Whether to stretch shapes horizontally or vertically.\n\t *\n\t * @public\n\t */\n\tstretchShapes(shapes: TLShapeId[] | TLShape[], operation: 'horizontal' | 'vertical'): this {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\n\t\tif (this.getIsReadonly()) return this\n\t\tif (ids.length < 2) return this\n\n\t\tconst shapesToStretch = compact(ids.map((id) => this.getShape(id))) // always fresh shapes\n\t\tconst shapeBounds = Object.fromEntries(ids.map((id) => [id, this.getShapeGeometry(id).bounds]))\n\t\tconst shapePageBounds = Object.fromEntries(ids.map((id) => [id, this.getShapePageBounds(id)!]))\n\t\tconst commonBounds = Box.Common(compact(Object.values(shapePageBounds)))\n\n\t\tswitch (operation) {\n\t\t\tcase 'vertical': {\n\t\t\t\tthis.run(() => {\n\t\t\t\t\tfor (const shape of shapesToStretch) {\n\t\t\t\t\t\tconst pageRotation = this.getShapePageTransform(shape)!.rotation()\n\t\t\t\t\t\tif (pageRotation % PI2) continue\n\t\t\t\t\t\tconst bounds = shapeBounds[shape.id]\n\t\t\t\t\t\tconst pageBounds = shapePageBounds[shape.id]\n\t\t\t\t\t\tconst localOffset = new Vec(0, commonBounds.minY - pageBounds.minY)\n\t\t\t\t\t\tconst parentTransform = this.getShapeParentTransform(shape)\n\t\t\t\t\t\tif (parentTransform) localOffset.rot(-parentTransform.rotation())\n\n\t\t\t\t\t\tconst { x, y } = Vec.Add(localOffset, shape)\n\t\t\t\t\t\tthis.updateShapes([{ id: shape.id, type: shape.type, x, y }])\n\t\t\t\t\t\tconst scale = new Vec(1, commonBounds.height / pageBounds.height)\n\t\t\t\t\t\tthis.resizeShape(shape.id, scale, {\n\t\t\t\t\t\t\tinitialBounds: bounds,\n\t\t\t\t\t\t\tscaleOrigin: new Vec(pageBounds.center.x, commonBounds.minY),\n\t\t\t\t\t\t\tisAspectRatioLocked: this.getShapeUtil(shape).isAspectRatioLocked(shape),\n\t\t\t\t\t\t\tscaleAxisRotation: 0,\n\t\t\t\t\t\t})\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'horizontal': {\n\t\t\t\tthis.run(() => {\n\t\t\t\t\tfor (const shape of shapesToStretch) {\n\t\t\t\t\t\tconst bounds = shapeBounds[shape.id]\n\t\t\t\t\t\tconst pageBounds = shapePageBounds[shape.id]\n\t\t\t\t\t\tconst pageRotation = this.getShapePageTransform(shape)!.rotation()\n\t\t\t\t\t\tif (pageRotation % PI2) continue\n\t\t\t\t\t\tconst localOffset = new Vec(commonBounds.minX - pageBounds.minX, 0)\n\t\t\t\t\t\tconst parentTransform = this.getShapeParentTransform(shape)\n\t\t\t\t\t\tif (parentTransform) localOffset.rot(-parentTransform.rotation())\n\n\t\t\t\t\t\tconst { x, y } = Vec.Add(localOffset, shape)\n\t\t\t\t\t\tthis.updateShapes([{ id: shape.id, type: shape.type, x, y }])\n\t\t\t\t\t\tconst scale = new Vec(commonBounds.width / pageBounds.width, 1)\n\t\t\t\t\t\tthis.resizeShape(shape.id, scale, {\n\t\t\t\t\t\t\tinitialBounds: bounds,\n\t\t\t\t\t\t\tscaleOrigin: new Vec(commonBounds.minX, pageBounds.center.y),\n\t\t\t\t\t\t\tisAspectRatioLocked: this.getShapeUtil(shape).isAspectRatioLocked(shape),\n\t\t\t\t\t\t\tscaleAxisRotation: 0,\n\t\t\t\t\t\t})\n\t\t\t\t\t}\n\t\t\t\t})\n\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Resize a shape.\n\t *\n\t * @param shape - The shape (or the shape id of the shape) to resize.\n\t * @param scale - The scale factor to apply to the shape.\n\t * @param opts - Additional options.\n\t *\n\t * @public\n\t */\n\tresizeShape(shape: TLShapeId | TLShape, scale: VecLike, opts: TLResizeShapeOptions = {}): this {\n\t\tconst id = typeof shape === 'string' ? shape : shape.id\n\t\tif (this.getIsReadonly()) return this\n\n\t\tif (!Number.isFinite(scale.x)) scale = new Vec(1, scale.y)\n\t\tif (!Number.isFinite(scale.y)) scale = new Vec(scale.x, 1)\n\n\t\tconst initialShape = opts.initialShape ?? this.getShape(id)\n\t\tif (!initialShape) return this\n\n\t\tconst scaleOrigin = opts.scaleOrigin ?? this.getShapePageBounds(id)?.center\n\t\tif (!scaleOrigin) return this\n\n\t\tconst pageTransform = opts.initialPageTransform\n\t\t\t? Mat.Cast(opts.initialPageTransform)\n\t\t\t: this.getShapePageTransform(id)\n\t\tif (!pageTransform) return this\n\n\t\tconst pageRotation = pageTransform.rotation()\n\n\t\tif (pageRotation == null) return this\n\n\t\tconst scaleAxisRotation = opts.scaleAxisRotation ?? pageRotation\n\n\t\tconst initialBounds = opts.initialBounds ?? this.getShapeGeometry(id).bounds\n\n\t\tif (!initialBounds) return this\n\n\t\tconst isAspectRatioLocked =\n\t\t\topts.isAspectRatioLocked ?? this.getShapeUtil(initialShape).isAspectRatioLocked(initialShape)\n\n\t\tif (!areAnglesCompatible(pageRotation, scaleAxisRotation)) {\n\t\t\t// shape is awkwardly rotated, keep the aspect ratio locked and adopt the scale factor\n\t\t\t// from whichever axis is being scaled the least, to avoid the shape getting bigger\n\t\t\t// than the bounds of the selection\n\t\t\t// const minScale = Math.min(Math.abs(scale.x), Math.abs(scale.y))\n\t\t\treturn this._resizeUnalignedShape(id, scale, {\n\t\t\t\t...opts,\n\t\t\t\tinitialBounds,\n\t\t\t\tscaleOrigin,\n\t\t\t\tscaleAxisRotation,\n\t\t\t\tinitialPageTransform: pageTransform,\n\t\t\t\tisAspectRatioLocked,\n\t\t\t\tinitialShape,\n\t\t\t})\n\t\t}\n\n\t\tconst util = this.getShapeUtil(initialShape)\n\n\t\tif (isAspectRatioLocked) {\n\t\t\tif (Math.abs(scale.x) > Math.abs(scale.y)) {\n\t\t\t\tscale = new Vec(scale.x, Math.sign(scale.y) * Math.abs(scale.x))\n\t\t\t} else {\n\t\t\t\tscale = new Vec(Math.sign(scale.x) * Math.abs(scale.y), scale.y)\n\t\t\t}\n\t\t}\n\n\t\tif (util.onResize && util.canResize(initialShape)) {\n\t\t\t// get the model changes from the shape util\n\t\t\tconst newPagePoint = this._scalePagePoint(\n\t\t\t\tMat.applyToPoint(pageTransform, new Vec(0, 0)),\n\t\t\t\tscaleOrigin,\n\t\t\t\tscale,\n\t\t\t\tscaleAxisRotation\n\t\t\t)\n\n\t\t\tconst newLocalPoint = this.getPointInParentSpace(initialShape.id, newPagePoint)\n\n\t\t\t// resize the shape's local bounding box\n\t\t\tconst myScale = new Vec(scale.x, scale.y)\n\t\t\t// the shape is aligned with the rest of the shapes in the selection, but may be\n\t\t\t// 90deg offset from the main rotation of the selection, in which case\n\t\t\t// we need to flip the width and height scale factors\n\t\t\tconst areWidthAndHeightAlignedWithCorrectAxis = approximately(\n\t\t\t\t(pageRotation - scaleAxisRotation) % Math.PI,\n\t\t\t\t0\n\t\t\t)\n\t\t\tmyScale.x = areWidthAndHeightAlignedWithCorrectAxis ? scale.x : scale.y\n\t\t\tmyScale.y = areWidthAndHeightAlignedWithCorrectAxis ? scale.y : scale.x\n\n\t\t\t// adjust initial model for situations where the parent has moved during the resize\n\t\t\t// e.g. groups\n\t\t\tconst initialPagePoint = Mat.applyToPoint(pageTransform, new Vec())\n\n\t\t\t// need to adjust the shape's x and y points in case the parent has moved since start of resizing\n\t\t\tconst { x, y } = this.getPointInParentSpace(initialShape.id, initialPagePoint)\n\n\t\t\tlet workingShape = initialShape\n\t\t\tif (!opts.skipStartAndEndCallbacks) {\n\t\t\t\tworkingShape = applyPartialToRecordWithProps(\n\t\t\t\t\tinitialShape,\n\t\t\t\t\tutil.onResizeStart?.(initialShape) ?? undefined\n\t\t\t\t)\n\t\t\t}\n\n\t\t\tworkingShape = applyPartialToRecordWithProps(workingShape, {\n\t\t\t\tid,\n\t\t\t\ttype: initialShape.type as any,\n\t\t\t\tx: newLocalPoint.x,\n\t\t\t\ty: newLocalPoint.y,\n\t\t\t\t...util.onResize(\n\t\t\t\t\t{ ...initialShape, x, y },\n\t\t\t\t\t{\n\t\t\t\t\t\tnewPoint: newLocalPoint,\n\t\t\t\t\t\thandle: opts.dragHandle ?? 'bottom_right',\n\t\t\t\t\t\t// don't set isSingle to true for children\n\t\t\t\t\t\tmode: opts.mode ?? 'scale_shape',\n\t\t\t\t\t\tscaleX: myScale.x,\n\t\t\t\t\t\tscaleY: myScale.y,\n\t\t\t\t\t\tinitialBounds,\n\t\t\t\t\t\tinitialShape,\n\t\t\t\t\t}\n\t\t\t\t),\n\t\t\t})\n\n\t\t\tif (!opts.skipStartAndEndCallbacks) {\n\t\t\t\tworkingShape = applyPartialToRecordWithProps(\n\t\t\t\t\tworkingShape,\n\t\t\t\t\tutil.onResizeEnd?.(initialShape, workingShape) ?? undefined\n\t\t\t\t)\n\t\t\t}\n\n\t\t\tthis.updateShapes([workingShape])\n\t\t} else {\n\t\t\tconst initialPageCenter = Mat.applyToPoint(pageTransform, initialBounds.center)\n\t\t\t// get the model changes from the shape util\n\t\t\tconst newPageCenter = this._scalePagePoint(\n\t\t\t\tinitialPageCenter,\n\t\t\t\tscaleOrigin,\n\t\t\t\tscale,\n\t\t\t\tscaleAxisRotation\n\t\t\t)\n\n\t\t\tconst initialPageCenterInParentSpace = this.getPointInParentSpace(\n\t\t\t\tinitialShape.id,\n\t\t\t\tinitialPageCenter\n\t\t\t)\n\t\t\tconst newPageCenterInParentSpace = this.getPointInParentSpace(initialShape.id, newPageCenter)\n\n\t\t\tconst delta = Vec.Sub(newPageCenterInParentSpace, initialPageCenterInParentSpace)\n\t\t\t// apply the changes to the model\n\t\t\tthis.updateShapes([\n\t\t\t\t{\n\t\t\t\t\tid,\n\t\t\t\t\ttype: initialShape.type as any,\n\t\t\t\t\tx: initialShape.x + delta.x,\n\t\t\t\t\ty: initialShape.y + delta.y,\n\t\t\t\t},\n\t\t\t])\n\t\t}\n\n\t\treturn this\n\t}\n\n\t/** @internal */\n\tprivate _scalePagePoint(\n\t\tpoint: VecLike,\n\t\tscaleOrigin: VecLike,\n\t\tscale: VecLike,\n\t\tscaleAxisRotation: number\n\t) {\n\t\tconst relativePoint = Vec.RotWith(point, scaleOrigin, -scaleAxisRotation).sub(scaleOrigin)\n\n\t\t// calculate the new point position relative to the scale origin\n\t\tconst newRelativePagePoint = Vec.MulV(relativePoint, scale)\n\n\t\t// and rotate it back to page coords to get the new page point of the resized shape\n\t\tconst destination = Vec.Add(newRelativePagePoint, scaleOrigin).rotWith(\n\t\t\tscaleOrigin,\n\t\t\tscaleAxisRotation\n\t\t)\n\n\t\treturn destination\n\t}\n\n\t/** @internal */\n\tprivate _resizeUnalignedShape(\n\t\tid: TLShapeId,\n\t\tscale: VecLike,\n\t\toptions: {\n\t\t\tinitialBounds: Box\n\t\t\tscaleOrigin: VecLike\n\t\t\tscaleAxisRotation: number\n\t\t\tinitialShape: TLShape\n\t\t\tisAspectRatioLocked: boolean\n\t\t\tinitialPageTransform: MatLike\n\t\t}\n\t) {\n\t\tconst { type } = options.initialShape\n\t\t// If a shape is not aligned with the scale axis we need to treat it differently to avoid skewing.\n\t\t// Instead of skewing we normalize the scale aspect ratio (i.e. keep the same scale magnitude in both axes)\n\t\t// and then after applying the scale to the shape we also rotate it if required and translate it so that it's center\n\t\t// point ends up in the right place.\n\n\t\tconst shapeScale = new Vec(scale.x, scale.y)\n\n\t\t// // make sure we are constraining aspect ratio, and using the smallest scale axis to avoid shapes getting bigger\n\t\t// // than the selection bounding box\n\t\tif (Math.abs(scale.x) > Math.abs(scale.y)) {\n\t\t\tshapeScale.x = Math.sign(scale.x) * Math.abs(scale.y)\n\t\t} else {\n\t\t\tshapeScale.y = Math.sign(scale.y) * Math.abs(scale.x)\n\t\t}\n\n\t\t// first we can scale the shape about its center point\n\t\tthis.resizeShape(id, shapeScale, {\n\t\t\tinitialShape: options.initialShape,\n\t\t\tinitialBounds: options.initialBounds,\n\t\t\tisAspectRatioLocked: options.isAspectRatioLocked,\n\t\t})\n\n\t\t// then if the shape is flipped in one axis only, we need to apply an extra rotation\n\t\t// to make sure the shape is mirrored correctly\n\t\tif (Math.sign(scale.x) * Math.sign(scale.y) < 0) {\n\t\t\tlet { rotation } = Mat.Decompose(options.initialPageTransform)\n\t\t\trotation -= 2 * rotation\n\t\t\tthis.updateShapes([{ id, type, rotation }])\n\t\t}\n\n\t\t// Next we need to translate the shape so that it's center point ends up in the right place.\n\t\t// To do that we first need to calculate the center point of the shape in the current page space before the scale was applied.\n\t\tconst preScaleShapePageCenter = Mat.applyToPoint(\n\t\t\toptions.initialPageTransform,\n\t\t\toptions.initialBounds.center\n\t\t)\n\n\t\t// And now we scale the center point by the original scale factor\n\t\tconst postScaleShapePageCenter = this._scalePagePoint(\n\t\t\tpreScaleShapePageCenter,\n\t\t\toptions.scaleOrigin,\n\t\t\tscale,\n\t\t\toptions.scaleAxisRotation\n\t\t)\n\n\t\t// now calculate how far away the shape is from where it needs to be\n\t\tconst pageBounds = this.getShapePageBounds(id)!\n\t\tconst pageTransform = this.getShapePageTransform(id)!\n\t\tconst currentPageCenter = pageBounds.center\n\t\tconst shapePageTransformOrigin = pageTransform.point()\n\t\tif (!currentPageCenter || !shapePageTransformOrigin) return this\n\t\tconst pageDelta = Vec.Sub(postScaleShapePageCenter, currentPageCenter)\n\n\t\t// and finally figure out what the shape's new position should be\n\t\tconst postScaleShapePagePoint = Vec.Add(shapePageTransformOrigin, pageDelta)\n\t\tconst { x, y } = this.getPointInParentSpace(id, postScaleShapePagePoint)\n\n\t\tthis.updateShapes([{ id, type, x, y }])\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Get the initial meta value for a shape.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getInitialMetaForShape = (shape) => {\n\t * if (shape.type === 'note') {\n\t * return { createdBy: myCurrentUser.id }\n\t * }\n\t * }\n\t * ```\n\t *\n\t * @param shape - The shape to get the initial meta for.\n\t *\n\t * @public\n\t */\n\tgetInitialMetaForShape(_shape: TLShape): JsonObject {\n\t\treturn {}\n\t}\n\n\t/**\n\t * Create a single shape.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.createShape(myShape)\n\t * editor.createShape({ id: 'box1', type: 'text', props: { text: \"ok\" } })\n\t * ```\n\t *\n\t * @param shape - The shape (or shape partial) to create.\n\t *\n\t * @public\n\t */\n\tcreateShape(shape: OptionalKeys, 'id'>): this {\n\t\tthis.createShapes([shape])\n\t\treturn this\n\t}\n\n\t/**\n\t * Create shapes.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.createShapes([myShape])\n\t * editor.createShapes([{ id: 'box1', type: 'text', props: { text: \"ok\" } }])\n\t * ```\n\t *\n\t * @param shapes - The shapes (or shape partials) to create.\n\t *\n\t * @public\n\t */\n\tcreateShapes(shapes: OptionalKeys, 'id'>[]): this {\n\t\tif (!Array.isArray(shapes)) {\n\t\t\tthrow Error('Editor.createShapes: must provide an array of shapes or shape partials')\n\t\t}\n\t\tif (this.getIsReadonly()) return this\n\t\tif (shapes.length <= 0) return this\n\n\t\tconst currentPageShapeIds = this.getCurrentPageShapeIds()\n\n\t\tconst maxShapesReached =\n\t\t\tshapes.length + currentPageShapeIds.size > this.options.maxShapesPerPage\n\n\t\tif (maxShapesReached) {\n\t\t\t// can't create more shapes than fit on the page\n\t\t\talertMaxShapes(this)\n\t\t\treturn this\n\t\t}\n\n\t\tconst focusedGroupId = this.getFocusedGroupId()\n\n\t\tthis.run(() => {\n\t\t\t// 1. Parents\n\n\t\t\t// Make sure that each partial will become the child of either the\n\t\t\t// page or another shape that exists (or that will exist) in this page.\n\n\t\t\t// find last parent id\n\t\t\tconst currentPageShapesSorted = this.getCurrentPageShapesSorted()\n\n\t\t\tconst partials = shapes.map((partial) => {\n\t\t\t\tif (!partial.id) {\n\t\t\t\t\tpartial = { id: createShapeId(), ...partial }\n\t\t\t\t}\n\n\t\t\t\t// If the partial does not provide the parentId OR if the provided\n\t\t\t\t// parentId is NOT in the store AND NOT among the other shapes being\n\t\t\t\t// created, then we need to find a parent for the shape. This can be\n\t\t\t\t// another shape that exists under that point and which can receive\n\t\t\t\t// children of the creating shape's type, or else the page itself.\n\t\t\t\tif (\n\t\t\t\t\t!partial.parentId ||\n\t\t\t\t\t!(this.store.has(partial.parentId) || shapes.some((p) => p.id === partial.parentId))\n\t\t\t\t) {\n\t\t\t\t\tlet parentId: TLParentId = this.getFocusedGroupId()\n\n\t\t\t\t\tfor (let i = currentPageShapesSorted.length - 1; i >= 0; i--) {\n\t\t\t\t\t\tconst parent = currentPageShapesSorted[i]\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t!this.isShapeHidden(parent) &&\n\t\t\t\t\t\t\tthis.getShapeUtil(parent).canReceiveNewChildrenOfType(parent, partial.type) &&\n\t\t\t\t\t\t\tthis.isPointInShape(\n\t\t\t\t\t\t\t\tparent,\n\t\t\t\t\t\t\t\t// If no parent is provided, then we can treat the\n\t\t\t\t\t\t\t\t// shape's provided x/y as being in the page's space.\n\t\t\t\t\t\t\t\t{ x: partial.x ?? 0, y: partial.y ?? 0 },\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tmargin: 0,\n\t\t\t\t\t\t\t\t\thitInside: true,\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\tparentId = parent.id\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tconst prevParentId = partial.parentId\n\n\t\t\t\t\t// a shape cannot be it's own parent. This was a rare issue with frames/groups in the syncFuzz tests.\n\t\t\t\t\tif (parentId === partial.id) {\n\t\t\t\t\t\tparentId = focusedGroupId\n\t\t\t\t\t}\n\n\t\t\t\t\t// If the parentid has changed...\n\t\t\t\t\tif (parentId !== prevParentId) {\n\t\t\t\t\t\tpartial = { ...partial }\n\n\t\t\t\t\t\tpartial.parentId = parentId\n\n\t\t\t\t\t\t// If the parent is a shape (rather than a page) then insert the\n\t\t\t\t\t\t// shapes into the shape's children. Adjust the point and page rotation to be\n\t\t\t\t\t\t// preserved relative to the parent.\n\t\t\t\t\t\tif (isShapeId(parentId)) {\n\t\t\t\t\t\t\tconst point = this.getPointInShapeSpace(this.getShape(parentId)!, {\n\t\t\t\t\t\t\t\tx: partial.x ?? 0,\n\t\t\t\t\t\t\t\ty: partial.y ?? 0,\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\tpartial.x = point.x\n\t\t\t\t\t\t\tpartial.y = point.y\n\t\t\t\t\t\t\tpartial.rotation =\n\t\t\t\t\t\t\t\t-this.getShapePageTransform(parentId)!.rotation() + (partial.rotation ?? 0)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn partial\n\t\t\t})\n\n\t\t\t// 2. Indices\n\n\t\t\t// Get the highest index among the parents of each of the\n\t\t\t// the shapes being created; we'll increment from there.\n\n\t\t\tconst parentIndices = new Map()\n\n\t\t\tconst shapeRecordsToCreate: TLShape[] = []\n\n\t\t\tconst { opacityForNextShape } = this.getInstanceState()\n\n\t\t\tfor (const partial of partials) {\n\t\t\t\tconst util = this.getShapeUtil(partial as TLShapePartial)\n\n\t\t\t\t// If an index is not explicitly provided, then add the\n\t\t\t\t// shapes to the top of their parents' children; using the\n\t\t\t\t// value in parentsMappedToIndex, get the index above, use it,\n\t\t\t\t// and set it back to parentsMappedToIndex for next time.\n\t\t\t\tlet index = partial.index\n\n\t\t\t\tif (!index) {\n\t\t\t\t\t// Hello bug-seeker: have you just created a frame and then a shape\n\t\t\t\t\t// and found that the shape is automatically the child of the frame?\n\t\t\t\t\t// this is the reason why! It would be harder to have each shape specify\n\t\t\t\t\t// the frame as the parent when creating a shape inside of a frame, so\n\t\t\t\t\t// we do it here.\n\t\t\t\t\tconst parentId = partial.parentId ?? focusedGroupId\n\n\t\t\t\t\tif (!parentIndices.has(parentId)) {\n\t\t\t\t\t\tparentIndices.set(parentId, this.getHighestIndexForParent(parentId))\n\t\t\t\t\t}\n\t\t\t\t\tindex = parentIndices.get(parentId)!\n\t\t\t\t\tparentIndices.set(parentId, getIndexAbove(index))\n\t\t\t\t}\n\n\t\t\t\t// The initial props starts as the shape utility's default props\n\t\t\t\tconst initialProps = util.getDefaultProps()\n\n\t\t\t\t// We then look up each key in the tab state's styles; and if it's there,\n\t\t\t\t// we use the value from the tab state's styles instead of the default.\n\t\t\t\tfor (const [style, propKey] of this.styleProps[partial.type]) {\n\t\t\t\t\t;(initialProps as any)[propKey] = this.getStyleForNextShape(style)\n\t\t\t\t}\n\n\t\t\t\t// When we create the shape, take in the partial (the props coming into the\n\t\t\t\t// function) and merge it with the default props.\n\t\t\t\tlet shapeRecordToCreate = (\n\t\t\t\t\tthis.store.schema.types.shape as RecordType<\n\t\t\t\t\t\tTLShape,\n\t\t\t\t\t\t'type' | 'props' | 'index' | 'parentId'\n\t\t\t\t\t>\n\t\t\t\t).create({\n\t\t\t\t\t...partial,\n\t\t\t\t\tindex,\n\t\t\t\t\topacity: partial.opacity ?? opacityForNextShape,\n\t\t\t\t\tparentId: partial.parentId ?? focusedGroupId,\n\t\t\t\t\tprops: 'props' in partial ? { ...initialProps, ...partial.props } : initialProps,\n\t\t\t\t})\n\n\t\t\t\tif (shapeRecordToCreate.index === undefined) {\n\t\t\t\t\tthrow Error('no index!')\n\t\t\t\t}\n\n\t\t\t\tconst next = this.getShapeUtil(shapeRecordToCreate).onBeforeCreate?.(shapeRecordToCreate)\n\n\t\t\t\tif (next) {\n\t\t\t\t\tshapeRecordToCreate = next\n\t\t\t\t}\n\n\t\t\t\tshapeRecordsToCreate.push(shapeRecordToCreate)\n\t\t\t}\n\n\t\t\t// Add meta properties, if any, to the shapes\n\t\t\tshapeRecordsToCreate.forEach((shape) => {\n\t\t\t\tshape.meta = {\n\t\t\t\t\t...this.getInitialMetaForShape(shape),\n\t\t\t\t\t...shape.meta,\n\t\t\t\t}\n\t\t\t})\n\n\t\t\tthis.store.put(shapeRecordsToCreate)\n\t\t})\n\n\t\treturn this\n\t}\n\n\tprivate animatingShapes = new Map()\n\n\t/**\n\t * Animate a shape.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.animateShape({ id: 'box1', type: 'box', x: 100, y: 100 })\n\t * editor.animateShape({ id: 'box1', type: 'box', x: 100, y: 100 }, { animation: { duration: 100, ease: t => t*t } })\n\t * ```\n\t *\n\t * @param partial - The shape partial to update.\n\t * @param opts - The animation's options.\n\t *\n\t * @public\n\t */\n\tanimateShape(\n\t\tpartial: TLShapePartial | null | undefined,\n\t\topts = { animation: DEFAULT_ANIMATION_OPTIONS } as TLCameraMoveOptions\n\t): this {\n\t\treturn this.animateShapes([partial], opts)\n\t}\n\n\t/**\n\t * Animate shapes.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.animateShapes([{ id: 'box1', type: 'box', x: 100, y: 100 }])\n\t * editor.animateShapes([{ id: 'box1', type: 'box', x: 100, y: 100 }], { animation: { duration: 100, ease: t => t*t } })\n\t * ```\n\t *\n\t * @param partials - The shape partials to update.\n\t * @param opts - The animation's options.\n\t *\n\t * @public\n\t */\n\tanimateShapes(\n\t\tpartials: (TLShapePartial | null | undefined)[],\n\t\topts = { animation: DEFAULT_ANIMATION_OPTIONS } as TLCameraMoveOptions\n\t): this {\n\t\tif (!opts.animation) return this\n\t\tconst { duration = 500, easing = EASINGS.linear } = opts.animation\n\n\t\tconst animationId = uniqueId()\n\n\t\tlet remaining = duration\n\t\tlet t: number\n\n\t\tinterface ShapeAnimation {\n\t\t\tstart: TLShape\n\t\t\tend: TLShape\n\t\t}\n\n\t\tconst animations: ShapeAnimation[] = []\n\n\t\tlet partial: TLShapePartial | null | undefined, result: ShapeAnimation\n\t\tfor (let i = 0, n = partials.length; i < n; i++) {\n\t\t\tpartial = partials[i]\n\t\t\tif (!partial) continue\n\n\t\t\tconst shape = this.getShape(partial.id)!\n\t\t\tif (!shape) continue\n\n\t\t\tresult = {\n\t\t\t\tstart: structuredClone(shape),\n\t\t\t\tend: applyPartialToRecordWithProps(structuredClone(shape), partial),\n\t\t\t}\n\n\t\t\tanimations.push(result)\n\t\t\tthis.animatingShapes.set(shape.id, animationId)\n\t\t}\n\n\t\tconst handleTick = (elapsed: number) => {\n\t\t\tremaining -= elapsed\n\n\t\t\tif (remaining < 0) {\n\t\t\t\tconst { animatingShapes } = this\n\t\t\t\tconst partialsToUpdate = partials.filter(\n\t\t\t\t\t(p) => p && animatingShapes.get(p.id) === animationId\n\t\t\t\t)\n\t\t\t\tif (partialsToUpdate.length) {\n\t\t\t\t\t// the regular update shapes also removes the shape from\n\t\t\t\t\t// the animating shapes set\n\t\t\t\t\tthis.updateShapes(partialsToUpdate)\n\t\t\t\t}\n\n\t\t\t\tthis.off('tick', handleTick)\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tt = easing(1 - remaining / duration)\n\n\t\t\tconst { animatingShapes } = this\n\n\t\t\tconst updates: TLShapePartial[] = []\n\n\t\t\tlet animationIdForShape: string | undefined\n\t\t\tfor (let i = 0, n = animations.length; i < n; i++) {\n\t\t\t\tconst { start, end } = animations[i]\n\t\t\t\t// Is the animation for this shape still active?\n\t\t\t\tanimationIdForShape = animatingShapes.get(start.id)\n\t\t\t\tif (animationIdForShape !== animationId) continue\n\n\t\t\t\tupdates.push({\n\t\t\t\t\t...end,\n\t\t\t\t\tx: start.x + (end.x - start.x) * t,\n\t\t\t\t\ty: start.y + (end.y - start.y) * t,\n\t\t\t\t\topacity: start.opacity + (end.opacity - start.opacity) * t,\n\t\t\t\t\trotation: start.rotation + (end.rotation - start.rotation) * t,\n\t\t\t\t\tprops: this.getShapeUtil(end).getInterpolatedProps?.(start, end, t) ?? end.props,\n\t\t\t\t})\n\t\t\t}\n\n\t\t\t// The _updateShapes method does NOT remove the\n\t\t\t// shapes from the animated shapes set\n\t\t\tthis._updateShapes(updates)\n\t\t}\n\n\t\tthis.on('tick', handleTick)\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Create a group containing the provided shapes.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.groupShapes([myShape, myOtherShape])\n\t * editor.groupShapes([myShape, myOtherShape], { groupId: myGroupId, select: false })\n\t * ```\n\t *\n\t * @param shapes - The shapes (or shape ids) to group. Defaults to the selected shapes.\n\t * @param opts - An options object.\n\t *\n\t * @public\n\t */\n\tgroupShapes(shapes: TLShape[], opts?: Partial<{ groupId: TLShapeId; select: boolean }>): this\n\tgroupShapes(ids: TLShapeId[], opts?: Partial<{ groupId: TLShapeId; select: boolean }>): this\n\tgroupShapes(\n\t\tshapes: TLShapeId[] | TLShape[],\n\t\topts = {} as Partial<{ groupId: TLShapeId; select: boolean }>\n\t): this {\n\t\tconst { groupId = createShapeId(), select = true } = opts\n\n\t\tif (!Array.isArray(shapes)) {\n\t\t\tthrow Error('Editor.groupShapes: must provide an array of shapes or shape ids')\n\t\t}\n\t\tif (this.getIsReadonly()) return this\n\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes.map((s) => (s as TLShape).id) as TLShapeId[])\n\n\t\tif (ids.length <= 1) return this\n\n\t\tconst shapesToGroup = compact(\n\t\t\t(this._shouldIgnoreShapeLock ? ids : this._getUnlockedShapeIds(ids)).map((id) =>\n\t\t\t\tthis.getShape(id)\n\t\t\t)\n\t\t)\n\t\tconst sortedShapeIds = shapesToGroup.sort(sortByIndex).map((s) => s.id)\n\t\tconst pageBounds = Box.Common(compact(shapesToGroup.map((id) => this.getShapePageBounds(id))))\n\n\t\tconst { x, y } = pageBounds.point\n\n\t\tconst parentId = this.findCommonAncestor(shapesToGroup) ?? this.getCurrentPageId()\n\n\t\t// Only group when the select tool is active\n\t\tif (this.getCurrentToolId() !== 'select') return this\n\n\t\t// If not already in idle, cancel the current interaction (get back to idle)\n\t\tif (!this.isIn('select.idle')) {\n\t\t\tthis.cancel()\n\t\t}\n\n\t\t// Find all the shapes that have the same parentId, and use the highest index.\n\t\tconst shapesWithRootParent = shapesToGroup\n\t\t\t.filter((shape) => shape.parentId === parentId)\n\t\t\t.sort(sortByIndex)\n\n\t\tconst highestIndex = shapesWithRootParent[shapesWithRootParent.length - 1]?.index\n\n\t\tthis.run(() => {\n\t\t\tthis.createShapes([\n\t\t\t\t{\n\t\t\t\t\tid: groupId,\n\t\t\t\t\ttype: 'group',\n\t\t\t\t\tparentId,\n\t\t\t\t\tindex: highestIndex,\n\t\t\t\t\tx,\n\t\t\t\t\ty,\n\t\t\t\t\topacity: 1,\n\t\t\t\t\tprops: {},\n\t\t\t\t},\n\t\t\t])\n\t\t\tthis.reparentShapes(sortedShapeIds, groupId)\n\t\t\tif (select) {\n\t\t\t\t// the select option determines whether the grouped shapes' children are selected\n\t\t\t\tthis.select(groupId)\n\t\t\t}\n\t\t})\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Ungroup some shapes.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.ungroupShapes([myGroup, myOtherGroup])\n\t * editor.ungroupShapes([myGroup], { select: false })\n\t * ```\n\t *\n\t * @param shapes - The group shapes (or shape ids) to ungroup.\n\t * @param opts - An options object.\n\t *\n\t * @public\n\t */\n\tungroupShapes(ids: TLShapeId[], opts?: Partial<{ select: boolean }>): this\n\tungroupShapes(shapes: TLShape[], opts?: Partial<{ select: boolean }>): this\n\tungroupShapes(shapes: TLShapeId[] | TLShape[], opts = {} as Partial<{ select: boolean }>) {\n\t\tif (this.getIsReadonly()) return this\n\n\t\tconst { select = true } = opts\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\n\t\tconst shapesToUngroup = compact(\n\t\t\t(this._shouldIgnoreShapeLock ? ids : this._getUnlockedShapeIds(ids)).map((id) =>\n\t\t\t\tthis.getShape(id)\n\t\t\t)\n\t\t)\n\n\t\tif (shapesToUngroup.length === 0) return this\n\n\t\t// todo: the editor shouldn't know about the select tool, move to group / ungroup actions\n\t\tif (this.getCurrentToolId() !== 'select') return this\n\t\tif (!this.isIn('select.idle')) {\n\t\t\tthis.cancel()\n\t\t}\n\n\t\t// The ids of the selected shapes after ungrouping;\n\t\t// these include all of the grouped shapes children,\n\t\t// plus any shapes that were selected apart from the groups.\n\t\tconst idsToSelect = new Set()\n\n\t\t// Get all groups in the selection\n\t\tconst groups: TLGroupShape[] = []\n\n\t\tshapesToUngroup.forEach((shape) => {\n\t\t\tif (this.isShapeOfType(shape, 'group')) {\n\t\t\t\tgroups.push(shape)\n\t\t\t} else {\n\t\t\t\tidsToSelect.add(shape.id)\n\t\t\t}\n\t\t})\n\n\t\tif (groups.length === 0) return this\n\n\t\tthis.run(() => {\n\t\t\tlet group: TLGroupShape\n\n\t\t\tfor (let i = 0, n = groups.length; i < n; i++) {\n\t\t\t\tgroup = groups[i]\n\t\t\t\tconst childIds = this.getSortedChildIdsForParent(group.id)\n\n\t\t\t\tfor (let j = 0, n = childIds.length; j < n; j++) {\n\t\t\t\t\tidsToSelect.add(childIds[j])\n\t\t\t\t}\n\n\t\t\t\tthis.reparentShapes(childIds, group.parentId, group.index)\n\t\t\t}\n\n\t\t\tthis.deleteShapes(groups.map((group) => group.id))\n\n\t\t\tif (select) {\n\t\t\t\t// the select option determines whether the ungrouped shapes' children are selected\n\t\t\t\tthis.select(...idsToSelect)\n\t\t\t}\n\t\t})\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Update a shape using a partial of the shape.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.updateShape({ id: 'box1', type: 'geo', props: { w: 100, h: 100 } })\n\t * ```\n\t *\n\t * @param partial - The shape partial to update.\n\t *\n\t * @public\n\t */\n\tupdateShape(partial: TLShapePartial | null | undefined) {\n\t\tthis.updateShapes([partial])\n\t\treturn this\n\t}\n\n\t/**\n\t * Update shapes using partials of each shape.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.updateShapes([{ id: 'box1', type: 'geo', props: { w: 100, h: 100 } }])\n\t * ```\n\t *\n\t * @param partials - The shape partials to update.\n\t *\n\t * @public\n\t */\n\tupdateShapes(partials: (TLShapePartial | null | undefined)[]) {\n\t\tconst compactedPartials: TLShapePartial[] = Array(partials.length)\n\n\t\tfor (let i = 0, n = partials.length; i < n; i++) {\n\t\t\tconst partial = partials[i]\n\t\t\tif (!partial) continue\n\t\t\t// Get the current shape referenced by the partial\n\t\t\tconst shape = this.getShape(partial.id)\n\t\t\tif (!shape) continue\n\n\t\t\t// If we're \"forcing\" the update, then we'll update the shape\n\t\t\t// regardless of whether it / its ancestor is locked\n\t\t\tif (!this._shouldIgnoreShapeLock) {\n\t\t\t\tif (shape.isLocked) {\n\t\t\t\t\t// If the shape itself is locked (even if one of its ancestors is\n\t\t\t\t\t// also locked) then only allow an update that unlocks the shape.\n\t\t\t\t\tif (!(Object.hasOwn(partial, 'isLocked') && !partial.isLocked)) {\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\t\t\t\t} else if (this.isShapeOrAncestorLocked(shape)) {\n\t\t\t\t\t// If the shape itself is unlocked, and any of the shape's\n\t\t\t\t\t// ancestors are locked then we'll skip the update\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Remove any animating shapes from the list of partials\n\t\t\tthis.animatingShapes.delete(partial.id)\n\n\t\t\tcompactedPartials.push(partial)\n\t\t}\n\n\t\tthis._updateShapes(compactedPartials)\n\t\treturn this\n\t}\n\n\t/** @internal */\n\t_updateShapes(_partials: (TLShapePartial | null | undefined)[]) {\n\t\tif (this.getIsReadonly()) return\n\n\t\tthis.run(() => {\n\t\t\tconst updates = []\n\n\t\t\tlet shape: TLShape | undefined\n\t\t\tlet updated: TLShape\n\n\t\t\tfor (let i = 0, n = _partials.length; i < n; i++) {\n\t\t\t\tconst partial = _partials[i]\n\t\t\t\t// Skip nullish partials (sometimes created by map fns returning undefined)\n\t\t\t\tif (!partial) continue\n\n\t\t\t\t// Get the current shape referenced by the partial\n\t\t\t\t// If there is no current shape, we'll skip this update\n\t\t\t\tshape = this.getShape(partial.id)\n\t\t\t\tif (!shape) continue\n\n\t\t\t\t// Get the updated version of the shape\n\t\t\t\t// If the update had no effect, we'll skip this update\n\t\t\t\tupdated = applyPartialToRecordWithProps(shape, partial)\n\t\t\t\tif (updated === shape) continue\n\n\t\t\t\t//if any shape has an onBeforeUpdate handler, call it and, if the handler returns a\n\t\t\t\t// new shape, replace the old shape with the new one. This is used for example when\n\t\t\t\t// repositioning a text shape based on its new text content.\n\t\t\t\tupdated = this.getShapeUtil(shape).onBeforeUpdate?.(shape, updated) ?? updated\n\n\t\t\t\tupdates.push(updated)\n\t\t\t}\n\n\t\t\tthis.store.put(updates)\n\t\t})\n\t}\n\n\t/** @internal */\n\tprivate _getUnlockedShapeIds(ids: TLShapeId[]): TLShapeId[] {\n\t\treturn ids.filter((id) => !this.getShape(id)?.isLocked)\n\t}\n\n\t/**\n\t * Delete shapes.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.deleteShapes(['box1', 'box2'])\n\t * ```\n\t *\n\t * @param ids - The ids of the shapes to delete.\n\t *\n\t * @public\n\t */\n\tdeleteShapes(ids: TLShapeId[]): this\n\tdeleteShapes(shapes: TLShape[]): this\n\tdeleteShapes(_ids: TLShapeId[] | TLShape[]): this {\n\t\tif (this.getIsReadonly()) return this\n\n\t\tif (!Array.isArray(_ids)) {\n\t\t\tthrow Error('Editor.deleteShapes: must provide an array of shapes or shapeIds')\n\t\t}\n\n\t\tconst shapeIds =\n\t\t\ttypeof _ids[0] === 'string' ? (_ids as TLShapeId[]) : (_ids as TLShape[]).map((s) => s.id)\n\n\t\t// Normally we don't want to delete locked shapes, but if the force option is set, we'll delete them anyway\n\t\tconst shapeIdsToDelete = this._shouldIgnoreShapeLock\n\t\t\t? shapeIds\n\t\t\t: this._getUnlockedShapeIds(shapeIds)\n\n\t\tif (shapeIdsToDelete.length === 0) return this\n\n\t\t// We also need to delete these shapes' descendants\n\t\tconst allShapeIdsToDelete = new Set(shapeIdsToDelete)\n\n\t\tfor (const id of shapeIdsToDelete) {\n\t\t\tthis.visitDescendants(id, (childId) => {\n\t\t\t\tallShapeIdsToDelete.add(childId)\n\t\t\t})\n\t\t}\n\n\t\treturn this.run(() => this.store.remove([...allShapeIdsToDelete]))\n\t}\n\n\t/**\n\t * Delete a shape.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.deleteShape(shape.id)\n\t * ```\n\t *\n\t * @param id - The id of the shape to delete.\n\t *\n\t * @public\n\t */\n\tdeleteShape(id: TLShapeId): this\n\tdeleteShape(shape: TLShape): this\n\tdeleteShape(_id: TLShapeId | TLShape) {\n\t\tthis.deleteShapes([typeof _id === 'string' ? _id : _id.id])\n\t\treturn this\n\t}\n\n\t/* --------------------- Styles --------------------- */\n\n\t/**\n\t * Get all the current styles among the users selected shapes\n\t *\n\t * @internal\n\t */\n\tprivate _extractSharedStyles(shape: TLShape, sharedStyleMap: SharedStyleMap) {\n\t\tif (this.isShapeOfType(shape, 'group')) {\n\t\t\t// For groups, ignore the styles of the group shape and instead include the styles of the\n\t\t\t// group's children. These are the shapes that would have their styles changed if the\n\t\t\t// user called `setStyle` on the current selection.\n\t\t\tconst childIds = this._parentIdsToChildIds.get()[shape.id]\n\t\t\tif (!childIds) return\n\n\t\t\tfor (let i = 0, n = childIds.length; i < n; i++) {\n\t\t\t\tthis._extractSharedStyles(this.getShape(childIds[i])!, sharedStyleMap)\n\t\t\t}\n\t\t} else {\n\t\t\tfor (const [style, propKey] of this.styleProps[shape.type]) {\n\t\t\t\tsharedStyleMap.applyValue(style, getOwnProperty(shape.props, propKey))\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * A derived map containing all current styles among the user's selected shapes.\n\t *\n\t * @internal\n\t */\n\t@computed\n\tprivate _getSelectionSharedStyles(): ReadonlySharedStyleMap {\n\t\tconst selectedShapes = this.getSelectedShapes()\n\n\t\tconst sharedStyles = new SharedStyleMap()\n\t\tfor (const selectedShape of selectedShapes) {\n\t\t\tthis._extractSharedStyles(selectedShape, sharedStyles)\n\t\t}\n\n\t\treturn sharedStyles\n\t}\n\n\t/**\n\t * Get the style for the next shape.\n\t *\n\t * @example\n\t * ```ts\n\t * const color = editor.getStyleForNextShape(DefaultColorStyle)\n\t * ```\n\t *\n\t * @param style - The style to get.\n\t *\n\t * @public */\n\tgetStyleForNextShape(style: StyleProp): T {\n\t\tconst value = this.getInstanceState().stylesForNextShape[style.id]\n\t\treturn value === undefined ? style.defaultValue : (value as T)\n\t}\n\n\tgetShapeStyleIfExists(shape: TLShape, style: StyleProp): T | undefined {\n\t\tconst styleKey = this.styleProps[shape.type].get(style)\n\t\tif (styleKey === undefined) return undefined\n\t\treturn getOwnProperty(shape.props, styleKey) as T | undefined\n\t}\n\n\t/**\n\t * A map of all the current styles either in the current selection, or that are relevant to the\n\t * current tool.\n\t *\n\t * @example\n\t * ```ts\n\t * const color = editor.getSharedStyles().get(DefaultColorStyle)\n\t * if (color && color.type === 'shared') {\n\t * print('All selected shapes have the same color:', color.value)\n\t * }\n\t * ```\n\t *\n\t * @public\n\t */\n\t@computed({ isEqual: (a, b) => a.equals(b) })\n\tgetSharedStyles(): ReadonlySharedStyleMap {\n\t\t// If we're in selecting and if we have a selection, return the shared styles from the\n\t\t// current selection\n\t\tif (this.isIn('select') && this.getSelectedShapeIds().length > 0) {\n\t\t\treturn this._getSelectionSharedStyles()\n\t\t}\n\n\t\t// If the current tool is associated with a shape, return the styles for that shape.\n\t\t// Otherwise, just return an empty map.\n\t\tconst currentTool = this.root.getCurrent()!\n\t\tconst styles = new SharedStyleMap()\n\n\t\tif (!currentTool) return styles\n\n\t\tif (currentTool.shapeType) {\n\t\t\tfor (const style of this.styleProps[currentTool.shapeType].keys()) {\n\t\t\t\tstyles.applyValue(style, this.getStyleForNextShape(style))\n\t\t\t}\n\t\t}\n\n\t\treturn styles\n\t}\n\n\t/**\n\t * Get the currently selected shared opacity.\n\t * If any shapes are selected, this returns the shared opacity of the selected shapes.\n\t * Otherwise, this returns the chosen opacity for the next shape.\n\t *\n\t * @public\n\t */\n\t@computed getSharedOpacity(): SharedStyle {\n\t\tif (this.isIn('select') && this.getSelectedShapeIds().length > 0) {\n\t\t\tconst shapesToCheck: TLShape[] = []\n\t\t\tconst addShape = (shapeId: TLShapeId) => {\n\t\t\t\tconst shape = this.getShape(shapeId)\n\t\t\t\tif (!shape) return\n\t\t\t\t// For groups, ignore the opacity of the group shape and instead include\n\t\t\t\t// the opacity of the group's children. These are the shapes that would have\n\t\t\t\t// their opacity changed if the user called `setOpacity` on the current selection.\n\t\t\t\tif (this.isShapeOfType(shape, 'group')) {\n\t\t\t\t\tfor (const childId of this.getSortedChildIdsForParent(shape.id)) {\n\t\t\t\t\t\taddShape(childId)\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tshapesToCheck.push(shape)\n\t\t\t\t}\n\t\t\t}\n\t\t\tfor (const shapeId of this.getSelectedShapeIds()) {\n\t\t\t\taddShape(shapeId)\n\t\t\t}\n\n\t\t\tlet opacity: number | null = null\n\t\t\tfor (const shape of shapesToCheck) {\n\t\t\t\tif (opacity === null) {\n\t\t\t\t\topacity = shape.opacity\n\t\t\t\t} else if (opacity !== shape.opacity) {\n\t\t\t\t\treturn { type: 'mixed' }\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (opacity !== null) return { type: 'shared', value: opacity }\n\t\t}\n\t\treturn { type: 'shared', value: this.getInstanceState().opacityForNextShape }\n\t}\n\n\t/**\n\t * Set the opacity for the next shapes. This will effect subsequently created shapes.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.setOpacityForNextShapes(0.5)\n\t * ```\n\t *\n\t * @param opacity - The opacity to set. Must be a number between 0 and 1 inclusive.\n\t * @param historyOptions - The history options for the change.\n\t */\n\tsetOpacityForNextShapes(opacity: number, historyOptions?: TLHistoryBatchOptions): this {\n\t\tthis.updateInstanceState({ opacityForNextShape: opacity }, historyOptions)\n\t\treturn this\n\t}\n\n\t/**\n\t * Set the current opacity. This will effect any selected shapes.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.setOpacityForSelectedShapes(0.5)\n\t * ```\n\t *\n\t * @param opacity - The opacity to set. Must be a number between 0 and 1 inclusive.\n\t */\n\tsetOpacityForSelectedShapes(opacity: number): this {\n\t\tconst selectedShapes = this.getSelectedShapes()\n\n\t\tif (selectedShapes.length > 0) {\n\t\t\tconst shapesToUpdate: TLShape[] = []\n\n\t\t\t// We can have many deep levels of grouped shape\n\t\t\t// Making a recursive function to look through all the levels\n\t\t\tconst addShapeById = (shape: TLShape) => {\n\t\t\t\tif (this.isShapeOfType(shape, 'group')) {\n\t\t\t\t\tconst childIds = this.getSortedChildIdsForParent(shape)\n\t\t\t\t\tfor (const childId of childIds) {\n\t\t\t\t\t\taddShapeById(this.getShape(childId)!)\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tshapesToUpdate.push(shape)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfor (const id of selectedShapes) {\n\t\t\t\taddShapeById(id)\n\t\t\t}\n\n\t\t\tthis.updateShapes(\n\t\t\t\tshapesToUpdate.map((shape) => {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tid: shape.id,\n\t\t\t\t\t\ttype: shape.type,\n\t\t\t\t\t\topacity,\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t)\n\t\t}\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Set the value of a {@link @tldraw/tlschema#StyleProp} for the next shapes. This change will be applied to subsequently created shapes.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.setStyleForNextShapes(DefaultColorStyle, 'red')\n\t * editor.setStyleForNextShapes(DefaultColorStyle, 'red', { ephemeral: true })\n\t * ```\n\t *\n\t * @param style - The style to set.\n\t * @param value - The value to set.\n\t * @param historyOptions - The history options for the change.\n\t *\n\t * @public\n\t */\n\tsetStyleForNextShapes(\n\t\tstyle: StyleProp,\n\t\tvalue: T,\n\t\thistoryOptions?: TLHistoryBatchOptions\n\t): this {\n\t\tconst stylesForNextShape = this.getInstanceState().stylesForNextShape\n\n\t\tthis.updateInstanceState(\n\t\t\t{ stylesForNextShape: { ...stylesForNextShape, [style.id]: value } },\n\t\t\thistoryOptions\n\t\t)\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Set the value of a {@link @tldraw/tlschema#StyleProp}. This change will be applied to the currently selected shapes.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.setStyleForSelectedShapes(DefaultColorStyle, 'red')\n\t * ```\n\t *\n\t * @param style - The style to set.\n\t * @param value - The value to set.\n\t *\n\t * @public\n\t */\n\tsetStyleForSelectedShapes>(style: S, value: StylePropValue): this {\n\t\tconst selectedShapes = this.getSelectedShapes()\n\n\t\tif (selectedShapes.length > 0) {\n\t\t\tconst updates: {\n\t\t\t\tutil: ShapeUtil\n\t\t\t\toriginalShape: TLShape\n\t\t\t\tupdatePartial: TLShapePartial\n\t\t\t}[] = []\n\n\t\t\t// We can have many deep levels of grouped shape\n\t\t\t// Making a recursive function to look through all the levels\n\t\t\tconst addShapeById = (shape: TLShape) => {\n\t\t\t\tif (this.isShapeOfType(shape, 'group')) {\n\t\t\t\t\tconst childIds = this.getSortedChildIdsForParent(shape.id)\n\t\t\t\t\tfor (const childId of childIds) {\n\t\t\t\t\t\taddShapeById(this.getShape(childId)!)\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tconst util = this.getShapeUtil(shape)\n\t\t\t\t\tconst stylePropKey = this.styleProps[shape.type].get(style)\n\t\t\t\t\tif (stylePropKey) {\n\t\t\t\t\t\tconst shapePartial: TLShapePartial = {\n\t\t\t\t\t\t\tid: shape.id,\n\t\t\t\t\t\t\ttype: shape.type,\n\t\t\t\t\t\t\tprops: { [stylePropKey]: value },\n\t\t\t\t\t\t}\n\t\t\t\t\t\tupdates.push({\n\t\t\t\t\t\t\tutil,\n\t\t\t\t\t\t\toriginalShape: shape,\n\t\t\t\t\t\t\tupdatePartial: shapePartial,\n\t\t\t\t\t\t})\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfor (const shape of selectedShapes) {\n\t\t\t\taddShapeById(shape)\n\t\t\t}\n\n\t\t\tthis.updateShapes(updates.map(({ updatePartial }) => updatePartial))\n\t\t}\n\n\t\treturn this\n\t}\n\n\t/* --------------------- Content -------------------- */\n\n\t/** @internal */\n\texternalAssetContentHandlers: {\n\t\t[K in TLExternalAssetContent['type']]: {\n\t\t\t[Key in K]:\n\t\t\t\t| null\n\t\t\t\t| ((info: TLExternalAssetContent & { type: Key }) => Promise)\n\t\t}[K]\n\t} = {\n\t\tfile: null,\n\t\turl: null,\n\t}\n\n\t/** @internal */\n\tprivate readonly temporaryAssetPreview = new Map()\n\n\t/**\n\t * Register an external asset handler. This handler will be called when the editor needs to\n\t * create an asset for some external content, like an image/video file or a bookmark URL. For\n\t * example, the 'file' type handler will be called when a user drops an image onto the canvas.\n\t *\n\t * The handler should extract any relevant metadata for the asset, upload it to blob storage\n\t * using {@link Editor.uploadAsset} if needed, and return the asset with the metadata & uploaded\n\t * URL.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.registerExternalAssetHandler('file', myHandler)\n\t * ```\n\t *\n\t * @param type - The type of external content.\n\t * @param handler - The handler to use for this content type.\n\t *\n\t * @public\n\t */\n\tregisterExternalAssetHandler(\n\t\ttype: T,\n\t\thandler: null | ((info: TLExternalAssetContent & { type: T }) => Promise)\n\t): this {\n\t\tthis.externalAssetContentHandlers[type] = handler as any\n\t\treturn this\n\t}\n\n\t/**\n\t * Register a temporary preview of an asset. This is useful for showing a ghost image of\n\t * something that is being uploaded. Retrieve the placeholder with\n\t * {@link Editor.getTemporaryAssetPreview}. Placeholders last for 3 minutes by default, but this\n\t * can be configured using\n\t *\n\t * @example\n\t * ```ts\n\t * editor.createTemporaryAssetPreview(assetId, file)\n\t * ```\n\t *\n\t * @param assetId - The asset's id.\n\t * @param file - The raw file.\n\t *\n\t * @public\n\t */\n\tcreateTemporaryAssetPreview(assetId: TLAssetId, file: File) {\n\t\tif (this.temporaryAssetPreview.has(assetId)) {\n\t\t\treturn this.temporaryAssetPreview.get(assetId)\n\t\t}\n\n\t\tconst objectUrl = URL.createObjectURL(file)\n\t\tthis.temporaryAssetPreview.set(assetId, objectUrl)\n\n\t\t// eslint-disable-next-line no-restricted-globals -- we always want to revoke the asset and object URL\n\t\tsetTimeout(() => {\n\t\t\tthis.temporaryAssetPreview.delete(assetId)\n\t\t\tURL.revokeObjectURL(objectUrl)\n\t\t}, this.options.temporaryAssetPreviewLifetimeMs)\n\n\t\treturn objectUrl\n\t}\n\n\t/**\n\t * Get temporary preview of an asset. This is useful for showing a ghost\n\t * image of something that is being uploaded.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getTemporaryAssetPreview('someId')\n\t * ```\n\t *\n\t * @param assetId - The asset's id.\n\t *\n\t * @public\n\t */\n\tgetTemporaryAssetPreview(assetId: TLAssetId) {\n\t\treturn this.temporaryAssetPreview.get(assetId)\n\t}\n\n\t/**\n\t * Get an asset for an external asset content type.\n\t *\n\t * @example\n\t * ```ts\n\t * const asset = await editor.getAssetForExternalContent({ type: 'file', file: myFile })\n\t * const asset = await editor.getAssetForExternalContent({ type: 'url', url: myUrl })\n\t * ```\n\t *\n\t * @param info - Info about the external content.\n\t * @returns The asset.\n\t */\n\tasync getAssetForExternalContent(info: TLExternalAssetContent): Promise {\n\t\treturn await this.externalAssetContentHandlers[info.type]?.(info as any)\n\t}\n\n\thasExternalAssetHandler(type: TLExternalAssetContent['type']): boolean {\n\t\treturn !!this.externalAssetContentHandlers[type]\n\t}\n\n\t/** @internal */\n\texternalContentHandlers: {\n\t\t[K in TLExternalContent['type']]: {\n\t\t\t[Key in K]: null | ((info: TLExternalContent & { type: Key }) => void)\n\t\t}[K]\n\t} = {\n\t\ttext: null,\n\t\tfiles: null,\n\t\tembed: null,\n\t\t'svg-text': null,\n\t\turl: null,\n\t}\n\n\t/**\n\t * Register an external content handler. This handler will be called when the editor receives\n\t * external content of the provided type. For example, the 'image' type handler will be called\n\t * when a user drops an image onto the canvas.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.registerExternalContentHandler('text', myHandler)\n\t * ```\n\t * @example\n\t * ```ts\n\t * editor.registerExternalContentHandler<'embed', MyEmbedType>('embed', myHandler)\n\t * ```\n\t *\n\t * @param type - The type of external content.\n\t * @param handler - The handler to use for this content type.\n\t *\n\t * @public\n\t */\n\tregisterExternalContentHandler['type'], E>(\n\t\ttype: T,\n\t\thandler:\n\t\t\t| null\n\t\t\t| ((\n\t\t\t\t\tinfo: T extends TLExternalContent['type']\n\t\t\t\t\t\t? TLExternalContent & { type: T }\n\t\t\t\t\t\t: TLExternalContent\n\t\t\t ) => void)\n\t): this {\n\t\tthis.externalContentHandlers[type] = handler as any\n\t\treturn this\n\t}\n\n\t/**\n\t * Handle external content, such as files, urls, embeds, or plain text which has been put into the app, for example by pasting external text or dropping external images onto canvas.\n\t *\n\t * @param info - Info about the external content.\n\t */\n\tasync putExternalContent(info: TLExternalContent): Promise {\n\t\treturn this.externalContentHandlers[info.type]?.(info as any)\n\t}\n\n\t/**\n\t * Get content that can be exported for the given shape ids.\n\t *\n\t * @param shapes - The shapes (or shape ids) to get content for.\n\t *\n\t * @returns The exported content.\n\t *\n\t * @public\n\t */\n\tgetContentFromCurrentPage(shapes: TLShapeId[] | TLShape[]): TLContent | undefined {\n\t\t// todo: make this work with any page, not just the current page\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\n\t\tif (!ids) return\n\t\tif (ids.length === 0) return\n\n\t\tconst shapeIds = this.getShapeAndDescendantIds(ids)\n\n\t\treturn withIsolatedShapes(this, shapeIds, (bindingIdsToKeep) => {\n\t\t\tconst bindings: TLBinding[] = []\n\t\t\tfor (const id of bindingIdsToKeep) {\n\t\t\t\tconst binding = this.getBinding(id)\n\t\t\t\tif (!binding) continue\n\t\t\t\tbindings.push(binding)\n\t\t\t}\n\n\t\t\tconst rootShapeIds: TLShapeId[] = []\n\t\t\tconst shapes: TLShape[] = []\n\t\t\tfor (const shapeId of shapeIds) {\n\t\t\t\tconst shape = this.getShape(shapeId)\n\t\t\t\tif (!shape) continue\n\n\t\t\t\tconst isRootShape = !shapeIds.has(shape.parentId as TLShapeId)\n\t\t\t\tif (isRootShape) {\n\t\t\t\t\t// Need to get page point and rotation of the shape because shapes in\n\t\t\t\t\t// groups use local position/rotation\n\t\t\t\t\tconst pageTransform = this.getShapePageTransform(shape.id)!\n\t\t\t\t\tconst pagePoint = pageTransform.point()\n\t\t\t\t\tshapes.push({\n\t\t\t\t\t\t...shape,\n\t\t\t\t\t\tx: pagePoint.x,\n\t\t\t\t\t\ty: pagePoint.y,\n\t\t\t\t\t\trotation: pageTransform.rotation(),\n\t\t\t\t\t\tparentId: this.getCurrentPageId(),\n\t\t\t\t\t})\n\t\t\t\t\trootShapeIds.push(shape.id)\n\t\t\t\t} else {\n\t\t\t\t\tshapes.push(shape)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst assets: TLAsset[] = []\n\t\t\tconst seenAssetIds = new Set()\n\t\t\tfor (const shape of shapes) {\n\t\t\t\tif (!('assetId' in shape.props)) continue\n\n\t\t\t\tconst assetId = shape.props.assetId\n\t\t\t\tif (!assetId || seenAssetIds.has(assetId)) continue\n\n\t\t\t\tseenAssetIds.add(assetId)\n\t\t\t\tconst asset = this.getAsset(assetId)\n\t\t\t\tif (!asset) continue\n\t\t\t\tassets.push(asset)\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tschema: this.store.schema.serialize(),\n\t\t\t\tshapes,\n\t\t\t\trootShapeIds,\n\t\t\t\tbindings,\n\t\t\t\tassets,\n\t\t\t}\n\t\t})\n\t}\n\n\tasync resolveAssetsInContent(content: TLContent | undefined): Promise {\n\t\tif (!content) return undefined\n\n\t\tconst assets: TLAsset[] = []\n\t\tawait Promise.allSettled(\n\t\t\tcontent.assets.map(async (asset) => {\n\t\t\t\tif (\n\t\t\t\t\t(asset.type === 'image' || asset.type === 'video') &&\n\t\t\t\t\t!asset.props.src?.startsWith('data:image') &&\n\t\t\t\t\t!asset.props.src?.startsWith('http')\n\t\t\t\t) {\n\t\t\t\t\tconst assetWithDataUrl = structuredClone(asset as TLImageAsset | TLVideoAsset)\n\t\t\t\t\tconst objectUrl = await this.store.props.assets.resolve(asset, {\n\t\t\t\t\t\tscreenScale: 1,\n\t\t\t\t\t\tsteppedScreenScale: 1,\n\t\t\t\t\t\tdpr: 1,\n\t\t\t\t\t\tnetworkEffectiveType: null,\n\t\t\t\t\t\tshouldResolveToOriginal: true,\n\t\t\t\t\t})\n\t\t\t\t\tassetWithDataUrl.props.src = await FileHelpers.blobToDataUrl(\n\t\t\t\t\t\tawait fetch(objectUrl!).then((r) => r.blob())\n\t\t\t\t\t)\n\t\t\t\t\tassets.push(assetWithDataUrl)\n\t\t\t\t} else {\n\t\t\t\t\tassets.push(asset)\n\t\t\t\t}\n\t\t\t})\n\t\t)\n\t\tcontent.assets = assets\n\n\t\treturn content\n\t}\n\n\t/**\n\t * Place content into the editor.\n\t *\n\t * @param content - The content.\n\t * @param opts - Options for placing the content.\n\t *\n\t * @public\n\t */\n\tputContentOntoCurrentPage(\n\t\tcontent: TLContent,\n\t\topts: {\n\t\t\tpoint?: VecLike\n\t\t\tselect?: boolean\n\t\t\tpreservePosition?: boolean\n\t\t\tpreserveIds?: boolean\n\t\t} = {}\n\t): this {\n\t\tif (this.getIsReadonly()) return this\n\n\t\t// todo: make this able to support putting content onto any page, not just the current page\n\n\t\tif (!content.schema) {\n\t\t\tthrow Error('Could not put content:\\ncontent is missing a schema.')\n\t\t}\n\n\t\tconst { select = false, preserveIds = false, preservePosition = false } = opts\n\t\tlet { point = undefined } = opts\n\n\t\t// decide on a parent for the put shapes; if the parent is among the put shapes(?) then use its parent\n\n\t\tconst currentPageId = this.getCurrentPageId()\n\t\tconst { rootShapeIds } = content\n\n\t\t// We need to collect the migrated records\n\t\tconst assets: TLAsset[] = []\n\t\tconst shapes: TLShape[] = []\n\t\tconst bindings: TLBinding[] = []\n\n\t\t// Let's treat the content as a store, and then migrate that store.\n\t\tconst store: StoreSnapshot = {\n\t\t\tstore: {\n\t\t\t\t...Object.fromEntries(content.assets.map((asset) => [asset.id, asset] as const)),\n\t\t\t\t...Object.fromEntries(content.shapes.map((shape) => [shape.id, shape] as const)),\n\t\t\t\t...Object.fromEntries(\n\t\t\t\t\tcontent.bindings?.map((bindings) => [bindings.id, bindings] as const) ?? []\n\t\t\t\t),\n\t\t\t},\n\t\t\tschema: content.schema,\n\t\t}\n\t\tconst result = this.store.schema.migrateStoreSnapshot(store)\n\t\tif (result.type === 'error') {\n\t\t\tthrow Error('Could not put content: could not migrate content')\n\t\t}\n\t\tfor (const record of Object.values(result.value)) {\n\t\t\tswitch (record.typeName) {\n\t\t\t\tcase 'asset': {\n\t\t\t\t\tassets.push(record)\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase 'shape': {\n\t\t\t\t\tshapes.push(record)\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase 'binding': {\n\t\t\t\t\tbindings.push(record)\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Ok, we've got our migrated records, now we can continue!\n\t\tconst shapeIdMap = new Map(\n\t\t\tpreserveIds\n\t\t\t\t? shapes.map((shape) => [shape.id, shape.id])\n\t\t\t\t: shapes.map((shape) => [shape.id, createShapeId()])\n\t\t)\n\t\tconst bindingIdMap = new Map(\n\t\t\tpreserveIds\n\t\t\t\t? bindings.map((binding) => [binding.id, binding.id])\n\t\t\t\t: bindings.map((binding) => [binding.id, createBindingId()])\n\t\t)\n\n\t\t// By default, the paste parent will be the current page.\n\t\tlet pasteParentId = this.getCurrentPageId() as TLPageId | TLShapeId\n\t\tlet lowestDepth = Infinity\n\t\tlet lowestAncestors: TLShape[] = []\n\n\t\t// Among the selected shapes, find the shape with the fewest ancestors and use its first ancestor.\n\t\tfor (const shape of this.getSelectedShapes()) {\n\t\t\tif (lowestDepth === 0) break\n\n\t\t\tconst isFrame = this.isShapeOfType(shape, 'frame')\n\t\t\tconst ancestors = this.getShapeAncestors(shape)\n\t\t\tif (isFrame) ancestors.push(shape)\n\n\t\t\tconst depth = isFrame ? ancestors.length + 1 : ancestors.length\n\n\t\t\tif (depth < lowestDepth) {\n\t\t\t\tlowestDepth = depth\n\t\t\t\tlowestAncestors = ancestors\n\t\t\t\tpasteParentId = isFrame ? shape.id : shape.parentId\n\t\t\t} else if (depth === lowestDepth) {\n\t\t\t\tif (lowestAncestors.length !== ancestors.length) {\n\t\t\t\t\tthrow Error(`Ancestors: ${lowestAncestors.length} !== ${ancestors.length}`)\n\t\t\t\t}\n\n\t\t\t\tif (lowestAncestors.length === 0) {\n\t\t\t\t\tpasteParentId = currentPageId\n\t\t\t\t\tbreak\n\t\t\t\t} else {\n\t\t\t\t\tpasteParentId = currentPageId\n\t\t\t\t\tfor (let i = 0; i < lowestAncestors.length; i++) {\n\t\t\t\t\t\tif (ancestors[i] !== lowestAncestors[i]) break\n\t\t\t\t\t\tpasteParentId = ancestors[i].id\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tlet isDuplicating = false\n\n\t\tif (!isPageId(pasteParentId)) {\n\t\t\tconst parent = this.getShape(pasteParentId)\n\t\t\tif (parent) {\n\t\t\t\tif (!this.getViewportPageBounds().includes(this.getShapePageBounds(parent)!)) {\n\t\t\t\t\tpasteParentId = currentPageId\n\t\t\t\t} else {\n\t\t\t\t\tif (rootShapeIds.length === 1) {\n\t\t\t\t\t\tconst rootShape = shapes.find((s) => s.id === rootShapeIds[0])!\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\tthis.isShapeOfType(parent, 'frame') &&\n\t\t\t\t\t\t\tthis.isShapeOfType(rootShape, 'frame') &&\n\t\t\t\t\t\t\trootShape.props.w === parent?.props.w &&\n\t\t\t\t\t\t\trootShape.props.h === parent?.props.h\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\tisDuplicating = true\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tpasteParentId = currentPageId\n\t\t\t}\n\t\t}\n\n\t\tif (!isDuplicating) {\n\t\t\tisDuplicating = shapeIdMap.has(pasteParentId)\n\t\t}\n\n\t\tif (isDuplicating) {\n\t\t\tpasteParentId = this.getShape(pasteParentId)!.parentId\n\t\t}\n\n\t\tlet index = this.getHighestIndexForParent(pasteParentId) // todo: requires that the putting page is the current page\n\n\t\tconst rootShapes: TLShape[] = []\n\n\t\tconst newShapes: TLShape[] = shapes.map((oldShape): TLShape => {\n\t\t\tconst newId = shapeIdMap.get(oldShape.id)!\n\n\t\t\t// Create the new shape (new except for the id)\n\t\t\tconst newShape = { ...oldShape, id: newId }\n\n\t\t\tif (rootShapeIds.includes(oldShape.id)) {\n\t\t\t\tnewShape.parentId = currentPageId\n\t\t\t\trootShapes.push(newShape)\n\t\t\t}\n\n\t\t\t// Assign the child to its new parent.\n\n\t\t\t// If the child's parent is among the putting shapes, then assign\n\t\t\t// it to the new parent's id.\n\t\t\tif (shapeIdMap.has(newShape.parentId)) {\n\t\t\t\tnewShape.parentId = shapeIdMap.get(oldShape.parentId)!\n\t\t\t} else {\n\t\t\t\trootShapeIds.push(newShape.id)\n\t\t\t\t// newShape.parentId = pasteParentId\n\t\t\t\tnewShape.index = index\n\t\t\t\tindex = getIndexAbove(index)\n\t\t\t}\n\n\t\t\treturn newShape\n\t\t})\n\n\t\tif (newShapes.length + this.getCurrentPageShapeIds().size > this.options.maxShapesPerPage) {\n\t\t\t// There's some complexity here involving children\n\t\t\t// that might be created without their parents, so\n\t\t\t// if we're going over the limit then just don't paste.\n\t\t\talertMaxShapes(this)\n\t\t\treturn this\n\t\t}\n\n\t\tconst newBindings = bindings.map(\n\t\t\t(oldBinding): TLBinding => ({\n\t\t\t\t...oldBinding,\n\t\t\t\tid: assertExists(bindingIdMap.get(oldBinding.id)),\n\t\t\t\tfromId: assertExists(shapeIdMap.get(oldBinding.fromId)),\n\t\t\t\ttoId: assertExists(shapeIdMap.get(oldBinding.toId)),\n\t\t\t})\n\t\t)\n\n\t\t// These are all the assets we need to create\n\t\tconst assetsToCreate: TLAsset[] = []\n\n\t\t// These assets have base64 data that may need to be hosted\n\t\tconst assetsToUpdate: (TLImageAsset | TLVideoAsset)[] = []\n\n\t\tfor (const asset of assets) {\n\t\t\tif (this.store.has(asset.id)) {\n\t\t\t\t// We already have this asset\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tif (\n\t\t\t\t(asset.type === 'image' || asset.type === 'video') &&\n\t\t\t\tasset.props.src?.startsWith('data:image')\n\t\t\t) {\n\t\t\t\t// it's src is a base64 image or video; we need to create a new asset without the src,\n\t\t\t\t// then create a new asset from the original src. So we save a copy of the original asset,\n\t\t\t\t// then delete the src from the original asset.\n\t\t\t\tassetsToUpdate.push(structuredClone(asset as TLImageAsset | TLVideoAsset))\n\t\t\t\tasset.props.src = null\n\t\t\t}\n\n\t\t\t// Add the asset to the list of assets to create\n\t\t\tassetsToCreate.push(asset)\n\t\t}\n\n\t\t// Start loading the new assets, order does not matter\n\t\tPromise.allSettled(\n\t\t\t(assetsToUpdate as (TLImageAsset | TLVideoAsset)[]).map(async (asset) => {\n\t\t\t\t// Turn the data url into a file\n\t\t\t\tconst file = await dataUrlToFile(\n\t\t\t\t\tasset.props.src!,\n\t\t\t\t\tasset.props.name,\n\t\t\t\t\tasset.props.mimeType ?? 'image/png'\n\t\t\t\t)\n\n\t\t\t\t// Get a new asset for the file\n\t\t\t\tconst newAsset = await this.getAssetForExternalContent({\n\t\t\t\t\ttype: 'file',\n\t\t\t\t\tfile,\n\t\t\t\t\tassetId: asset.id,\n\t\t\t\t})\n\n\t\t\t\tif (!newAsset) {\n\t\t\t\t\t// If we don't have a new asset, delete the old asset.\n\t\t\t\t\t// The shapes that reference this asset should break.\n\t\t\t\t\tthis.deleteAssets([asset.id])\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\t// Save the new asset under the old asset's id\n\t\t\t\tthis.updateAssets([{ ...newAsset, id: asset.id }])\n\t\t\t})\n\t\t)\n\n\t\tthis.run(() => {\n\t\t\t// Create any assets that need to be created\n\t\t\tif (assetsToCreate.length > 0) {\n\t\t\t\tthis.createAssets(assetsToCreate)\n\t\t\t}\n\n\t\t\t// Create the shapes with root shapes as children of the page\n\t\t\tthis.createShapes(newShapes)\n\t\t\tthis.createBindings(newBindings)\n\n\t\t\tif (select) {\n\t\t\t\tthis.select(...rootShapes.map((s) => s.id))\n\t\t\t}\n\n\t\t\t// And then, if needed, reparent the root shapes to the paste parent\n\t\t\tif (pasteParentId !== currentPageId) {\n\t\t\t\tthis.reparentShapes(\n\t\t\t\t\trootShapes.map((s) => s.id),\n\t\t\t\t\tpasteParentId\n\t\t\t\t)\n\t\t\t}\n\n\t\t\tconst newCreatedShapes = newShapes.map((s) => this.getShape(s.id)!)\n\t\t\tconst bounds = Box.Common(newCreatedShapes.map((s) => this.getShapePageBounds(s)!))\n\n\t\t\tif (point === undefined) {\n\t\t\t\tif (!isPageId(pasteParentId)) {\n\t\t\t\t\t// Put the shapes in the middle of the (on screen) parent\n\t\t\t\t\tconst shape = this.getShape(pasteParentId)!\n\t\t\t\t\tpoint = Mat.applyToPoint(\n\t\t\t\t\t\tthis.getShapePageTransform(shape),\n\t\t\t\t\t\tthis.getShapeGeometry(shape).bounds.center\n\t\t\t\t\t)\n\t\t\t\t} else {\n\t\t\t\t\tconst viewportPageBounds = this.getViewportPageBounds()\n\t\t\t\t\tif (preservePosition || viewportPageBounds.includes(Box.From(bounds))) {\n\t\t\t\t\t\t// Otherwise, put shapes where they used to be\n\t\t\t\t\t\tpoint = bounds.center\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// If the old bounds are outside of the viewport...\n\t\t\t\t\t\t// put the shapes in the middle of the viewport\n\t\t\t\t\t\tpoint = viewportPageBounds.center\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (rootShapes.length === 1) {\n\t\t\t\tconst onlyRoot = rootShapes[0] as TLFrameShape\n\t\t\t\t// If the old bounds are in the viewport...\n\t\t\t\tif (this.isShapeOfType(onlyRoot, 'frame')) {\n\t\t\t\t\twhile (\n\t\t\t\t\t\tthis.getShapesAtPoint(point).some(\n\t\t\t\t\t\t\t(shape) =>\n\t\t\t\t\t\t\t\tthis.isShapeOfType(shape, 'frame') &&\n\t\t\t\t\t\t\t\tshape.props.w === onlyRoot.props.w &&\n\t\t\t\t\t\t\t\tshape.props.h === onlyRoot.props.h\n\t\t\t\t\t\t)\n\t\t\t\t\t) {\n\t\t\t\t\t\tpoint.x += bounds.w + 16\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst pageCenter = Box.Common(\n\t\t\t\tcompact(rootShapes.map(({ id }) => this.getShapePageBounds(id)))\n\t\t\t).center\n\n\t\t\tconst offset = Vec.Sub(point, pageCenter)\n\n\t\t\tthis.updateShapes(\n\t\t\t\trootShapes.map(({ id }) => {\n\t\t\t\t\tconst s = this.getShape(id)!\n\t\t\t\t\tconst localRotation = this.getShapeParentTransform(id).decompose().rotation\n\t\t\t\t\tconst localDelta = Vec.Rot(offset, -localRotation)\n\n\t\t\t\t\treturn { id: s.id, type: s.type, x: s.x + localDelta.x, y: s.y + localDelta.y }\n\t\t\t\t})\n\t\t\t)\n\t\t})\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Get an exported SVG element of the given shapes.\n\t *\n\t * @param shapes - The shapes (or shape ids) to export.\n\t * @param opts - Options for the export.\n\t *\n\t * @returns The SVG element.\n\t *\n\t * @public\n\t */\n\tasync getSvgElement(shapes: TLShapeId[] | TLShape[], opts: TLImageExportOptions = {}) {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\n\t\tif (ids.length === 0) return undefined\n\n\t\treturn exportToSvg(this, ids, opts)\n\t}\n\n\t/**\n\t * Get an exported SVG string of the given shapes.\n\t *\n\t * @param shapes - The shapes (or shape ids) to export.\n\t * @param opts - Options for the export.\n\t *\n\t * @returns The SVG element.\n\t *\n\t * @public\n\t */\n\tasync getSvgString(shapes: TLShapeId[] | TLShape[], opts: TLImageExportOptions = {}) {\n\t\tconst result = await this.getSvgElement(shapes, opts)\n\t\tif (!result) return undefined\n\n\t\tconst serializer = new XMLSerializer()\n\t\treturn {\n\t\t\tsvg: serializer.serializeToString(result.svg),\n\t\t\twidth: result.width,\n\t\t\theight: result.height,\n\t\t}\n\t}\n\n\t/** @deprecated Use {@link Editor.getSvgString} or {@link Editor.getSvgElement} instead. */\n\tasync getSvg(shapes: TLShapeId[] | TLShape[], opts: TLImageExportOptions = {}) {\n\t\tconst result = await this.getSvgElement(shapes, opts)\n\t\tif (!result) return undefined\n\t\treturn result.svg\n\t}\n\n\t/* --------------------- Events --------------------- */\n\n\t/**\n\t * The app's current input state.\n\t *\n\t * @public\n\t */\n\tinputs = {\n\t\t/** The most recent pointer down's position in the current page space. */\n\t\toriginPagePoint: new Vec(),\n\t\t/** The most recent pointer down's position in screen space. */\n\t\toriginScreenPoint: new Vec(),\n\t\t/** The previous pointer position in the current page space. */\n\t\tpreviousPagePoint: new Vec(),\n\t\t/** The previous pointer position in screen space. */\n\t\tpreviousScreenPoint: new Vec(),\n\t\t/** The most recent pointer position in the current page space. */\n\t\tcurrentPagePoint: new Vec(),\n\t\t/** The most recent pointer position in screen space. */\n\t\tcurrentScreenPoint: new Vec(),\n\t\t/** A set containing the currently pressed keys. */\n\t\tkeys: new Set(),\n\t\t/** A set containing the currently pressed buttons. */\n\t\tbuttons: new Set(),\n\t\t/** Whether the input is from a pe. */\n\t\tisPen: false,\n\t\t/** Whether the shift key is currently pressed. */\n\t\tshiftKey: false,\n\t\t/** Whether the meta key is currently pressed. */\n\t\tmetaKey: false,\n\t\t/** Whether the control or command key is currently pressed. */\n\t\tctrlKey: false,\n\t\t/** Whether the alt or option key is currently pressed. */\n\t\taltKey: false,\n\t\t/** Whether the user is dragging. */\n\t\tisDragging: false,\n\t\t/** Whether the user is pointing. */\n\t\tisPointing: false,\n\t\t/** Whether the user is pinching. */\n\t\tisPinching: false,\n\t\t/** Whether the user is editing. */\n\t\tisEditing: false,\n\t\t/** Whether the user is panning. */\n\t\tisPanning: false,\n\t\t/** Whether the user is spacebar panning. */\n\t\tisSpacebarPanning: false,\n\t\t/** Velocity of mouse pointer, in pixels per millisecond */\n\t\tpointerVelocity: new Vec(),\n\t}\n\n\t/**\n\t * Update the input points from a pointer, pinch, or wheel event.\n\t *\n\t * @param info - The event info.\n\t */\n\tprivate _updateInputsFromEvent(\n\t\tinfo: TLPointerEventInfo | TLPinchEventInfo | TLWheelEventInfo\n\t): void {\n\t\tconst {\n\t\t\tpointerVelocity,\n\t\t\tpreviousScreenPoint,\n\t\t\tpreviousPagePoint,\n\t\t\tcurrentScreenPoint,\n\t\t\tcurrentPagePoint,\n\t\t} = this.inputs\n\n\t\tconst { screenBounds } = this.store.unsafeGetWithoutCapture(TLINSTANCE_ID)!\n\t\tconst { x: cx, y: cy, z: cz } = unsafe__withoutCapture(() => this.getCamera())\n\n\t\tconst sx = info.point.x - screenBounds.x\n\t\tconst sy = info.point.y - screenBounds.y\n\t\tconst sz = info.point.z ?? 0.5\n\n\t\tpreviousScreenPoint.setTo(currentScreenPoint)\n\t\tpreviousPagePoint.setTo(currentPagePoint)\n\n\t\t// The \"screen bounds\" is relative to the user's actual screen.\n\t\t// The \"screen point\" is relative to the \"screen bounds\";\n\t\t// it will be 0,0 when its actual screen position is equal\n\t\t// to screenBounds.point. This is confusing!\n\t\tcurrentScreenPoint.set(sx, sy)\n\t\tconst nx = sx / cz - cx\n\t\tconst ny = sy / cz - cy\n\t\tif (isFinite(nx) && isFinite(ny)) {\n\t\t\tcurrentPagePoint.set(nx, ny, sz)\n\t\t}\n\n\t\tthis.inputs.isPen = info.type === 'pointer' && info.isPen\n\n\t\t// Reset velocity on pointer down, or when a pinch starts or ends\n\t\tif (info.name === 'pointer_down' || this.inputs.isPinching) {\n\t\t\tpointerVelocity.set(0, 0)\n\t\t\tthis.inputs.originScreenPoint.setTo(currentScreenPoint)\n\t\t\tthis.inputs.originPagePoint.setTo(currentPagePoint)\n\t\t}\n\n\t\t// todo: We only have to do this if there are multiple users in the document\n\t\tthis.run(\n\t\t\t() => {\n\t\t\t\tthis.store.put([\n\t\t\t\t\t{\n\t\t\t\t\t\tid: TLPOINTER_ID,\n\t\t\t\t\t\ttypeName: 'pointer',\n\t\t\t\t\t\tx: currentPagePoint.x,\n\t\t\t\t\t\ty: currentPagePoint.y,\n\t\t\t\t\t\tlastActivityTimestamp:\n\t\t\t\t\t\t\t// If our pointer moved only because we're following some other user, then don't\n\t\t\t\t\t\t\t// update our last activity timestamp; otherwise, update it to the current timestamp.\n\t\t\t\t\t\t\tinfo.type === 'pointer' && info.pointerId === INTERNAL_POINTER_IDS.CAMERA_MOVE\n\t\t\t\t\t\t\t\t? this.store.unsafeGetWithoutCapture(TLPOINTER_ID)?.lastActivityTimestamp ??\n\t\t\t\t\t\t\t\t\tthis._tickManager.now\n\t\t\t\t\t\t\t\t: this._tickManager.now,\n\t\t\t\t\t\tmeta: {},\n\t\t\t\t\t},\n\t\t\t\t])\n\t\t\t},\n\t\t\t{ history: 'ignore' }\n\t\t)\n\t}\n\n\t/**\n\t * Dispatch a cancel event.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.cancel()\n\t * ```\n\t *\n\t * @public\n\t */\n\tcancel(): this {\n\t\tthis.dispatch({ type: 'misc', name: 'cancel' })\n\t\treturn this\n\t}\n\n\t/**\n\t * Dispatch an interrupt event.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.interrupt()\n\t * ```\n\t *\n\t * @public\n\t */\n\tinterrupt(): this {\n\t\tthis.dispatch({ type: 'misc', name: 'interrupt' })\n\t\treturn this\n\t}\n\n\t/**\n\t * Dispatch a complete event.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.complete()\n\t * ```\n\t *\n\t * @public\n\t */\n\tcomplete(): this {\n\t\tthis.dispatch({ type: 'misc', name: 'complete' })\n\t\treturn this\n\t}\n\n\t/**\n\t * Puts the editor into focused mode.\n\t *\n\t * This makes the editor eligible to receive keyboard events and some pointer events (move, wheel).\n\t *\n\t * @example\n\t * ```ts\n\t * editor.focus()\n\t * ```\n\t *\n\t * By default this also dispatches a 'focus' event to the container element. To prevent this, pass `focusContainer: false`.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.focus({ focusContainer: false })\n\t * ```\n\t *\n\t * @public\n\t */\n\tfocus({ focusContainer = true } = {}): this {\n\t\tif (this.getIsFocused()) return this\n\t\tif (focusContainer) this.focusManager.focus()\n\t\tthis.updateInstanceState({ isFocused: true })\n\t\treturn this\n\t}\n\n\t/**\n\t * Switches off the editor's focused mode.\n\t *\n\t * This makes the editor ignore keyboard events and some pointer events (move, wheel).\n\t *\n\t * @example\n\t * ```ts\n\t * editor.blur()\n\t * ```\n\t * By default this also dispatches a 'blur' event to the container element. To prevent this, pass `blurContainer: false`.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.blur({ blurContainer: false })\n\t * ```\n\t *\n\t * @public\n\t */\n\tblur({ blurContainer = true } = {}): this {\n\t\tif (!this.getIsFocused()) return this\n\t\tif (blurContainer) {\n\t\t\tthis.focusManager.blur()\n\t\t} else {\n\t\t\tthis.complete() // stop any interaction\n\t\t}\n\t\tthis.updateInstanceState({ isFocused: false })\n\t\treturn this\n\t}\n\n\t/**\n\t * @public\n\t * @returns true if the editor is focused\n\t */\n\t@computed getIsFocused() {\n\t\treturn this.getInstanceState().isFocused\n\t}\n\n\t/**\n\t * @public\n\t * @returns true if the editor is in readonly mode\n\t */\n\t@computed getIsReadonly() {\n\t\treturn this.getInstanceState().isReadonly\n\t}\n\n\t/**\n\t * @public\n\t * @returns a snapshot of the store's UI and document state\n\t */\n\tgetSnapshot() {\n\t\treturn getSnapshot(this.store)\n\t}\n\n\t/**\n\t * Loads a snapshot into the editor.\n\t * @param snapshot - The snapshot to load.\n\t * @param opts - The options for loading the snapshot.\n\t * @returns\n\t */\n\tloadSnapshot(\n\t\tsnapshot: Partial | TLStoreSnapshot,\n\t\topts?: TLLoadSnapshotOptions\n\t) {\n\t\tloadSnapshot(this.store, snapshot, opts)\n\t\treturn this\n\t}\n\n\tprivate _zoomToFitPageContentAt100Percent() {\n\t\tconst bounds = this.getCurrentPageBounds()\n\t\tif (bounds) {\n\t\t\tthis.zoomToBounds(bounds, { immediate: true, targetZoom: this.getBaseZoom() })\n\t\t}\n\t}\n\tprivate _navigateToDeepLink(deepLink: TLDeepLink) {\n\t\tthis.run(() => {\n\t\t\tswitch (deepLink.type) {\n\t\t\t\tcase 'page': {\n\t\t\t\t\tconst page = this.getPage(deepLink.pageId)\n\t\t\t\t\tif (page) {\n\t\t\t\t\t\tthis.setCurrentPage(page)\n\t\t\t\t\t}\n\t\t\t\t\tthis._zoomToFitPageContentAt100Percent()\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tcase 'shapes': {\n\t\t\t\t\tconst allShapes = compact(deepLink.shapeIds.map((id) => this.getShape(id)))\n\t\t\t\t\tconst byPage: { [pageId: string]: TLShape[] } = {}\n\t\t\t\t\tfor (const shape of allShapes) {\n\t\t\t\t\t\tconst pageId = this.getAncestorPageId(shape)\n\t\t\t\t\t\tif (!pageId) continue\n\t\t\t\t\t\tbyPage[pageId] ??= []\n\t\t\t\t\t\tbyPage[pageId].push(shape)\n\t\t\t\t\t}\n\t\t\t\t\tconst [pageId, shapes] = Object.entries(byPage).sort(\n\t\t\t\t\t\t([_, a], [__, b]) => b.length - a.length\n\t\t\t\t\t)[0] ?? ['', []]\n\n\t\t\t\t\tif (!pageId || !shapes.length) {\n\t\t\t\t\t\tthis._zoomToFitPageContentAt100Percent()\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthis.setCurrentPage(pageId as TLPageId)\n\t\t\t\t\t\tconst bounds = Box.Common(shapes.map((s) => this.getShapePageBounds(s)!))\n\t\t\t\t\t\tthis.zoomToBounds(bounds, { immediate: true, targetZoom: this.getBaseZoom() })\n\t\t\t\t\t}\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tcase 'viewport': {\n\t\t\t\t\tif (deepLink.pageId) {\n\t\t\t\t\t\tif (!this.getPage(deepLink.pageId)) {\n\t\t\t\t\t\t\tthis._zoomToFitPageContentAt100Percent()\n\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t}\n\t\t\t\t\t\tthis.setCurrentPage(deepLink.pageId)\n\t\t\t\t\t}\n\t\t\t\t\tthis.zoomToBounds(deepLink.bounds, { immediate: true, inset: 0 })\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tdefault:\n\t\t\t\t\texhaustiveSwitchError(deepLink)\n\t\t\t}\n\t\t})\n\t}\n\n\t/**\n\t * Handles navigating to the content specified by the query param in the given URL.\n\t *\n\t * Use {@link Editor#createDeepLink} to create a URL with a deep link query param.\n\t *\n\t * If no URL is provided, it will look for the param in the current `window.location.href`.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.navigateToDeepLink()\n\t * ```\n\t *\n\t * The default parameter name is 'd'. You can override this by providing the `param` option.\n\t *\n\t * @example\n\t * ```ts\n\t * // disable page parameter and change viewport parameter to 'c'\n\t * editor.navigateToDeepLink({\n\t * param: 'x',\n\t * url: 'https://my-app.com/my-document?x=200.12.454.23.xyz123',\n\t * })\n\t * ```\n\t *\n\t * @param opts - Options for loading the state from the URL.\n\t */\n\tnavigateToDeepLink(opts?: TLDeepLink | { url?: string | URL; param?: string }): Editor {\n\t\tif (opts && 'type' in opts) {\n\t\t\tthis._navigateToDeepLink(opts)\n\t\t\treturn this\n\t\t}\n\n\t\tconst url = new URL(opts?.url ?? window.location.href)\n\t\tconst deepLinkString = url.searchParams.get(opts?.param ?? 'd')\n\n\t\tif (!deepLinkString) {\n\t\t\tthis._zoomToFitPageContentAt100Percent()\n\t\t\treturn this\n\t\t}\n\n\t\ttry {\n\t\t\tthis._navigateToDeepLink(parseDeepLinkString(deepLinkString))\n\t\t} catch (e) {\n\t\t\tconsole.warn(e)\n\t\t\tthis._zoomToFitPageContentAt100Percent()\n\t\t}\n\t\treturn this\n\t}\n\n\t/**\n\t * Turns the given URL into a deep link by adding a query parameter.\n\t *\n\t * e.g. `https://my-app.com/my-document?d=100.100.200.200.xyz123`\n\t *\n\t * If no URL is provided, it will use the current `window.location.href`.\n\t *\n\t * @example\n\t * ```ts\n\t * // create a deep link to the current page + viewport\n\t * navigator.clipboard.writeText(editor.createDeepLink())\n\t * ```\n\t *\n\t * You can link to a particular set of shapes by providing a `to` parameter.\n\t *\n\t * @example\n\t * ```ts\n\t * // create a deep link to the set of currently selected shapes\n\t * navigator.clipboard.writeText(editor.createDeepLink({\n\t * to: { type: 'selection', shapeIds: editor.getSelectedShapeIds() }\n\t * }))\n\t * ```\n\t *\n\t * The default query param is 'd'. You can override this by providing a `param` parameter.\n\t *\n\t * @example\n\t * ```ts\n\t * // Use `x` as the param name instead\n\t * editor.createDeepLink({ param: 'x' })\n\t * ```\n\t *\n\t * @param opts - Options for adding the state to the URL.\n\t * @returns the updated URL\n\t */\n\tcreateDeepLink(opts?: { url?: string | URL; param?: string; to?: TLDeepLink }): URL {\n\t\tconst url = new URL(opts?.url ?? window.location.href)\n\n\t\turl.searchParams.set(\n\t\t\topts?.param ?? 'd',\n\t\t\tcreateDeepLinkString(\n\t\t\t\topts?.to ?? {\n\t\t\t\t\ttype: 'viewport',\n\t\t\t\t\tpageId: this.options.maxPages === 1 ? undefined : this.getCurrentPageId(),\n\t\t\t\t\tbounds: this.getViewportPageBounds(),\n\t\t\t\t}\n\t\t\t)\n\t\t)\n\n\t\treturn url\n\t}\n\n\t/**\n\t * Register a listener for changes to a deep link for the current document.\n\t *\n\t * You'll typically want to use this indirectly via the {@link TldrawEditorBaseProps.deepLinks} prop on the `` component.\n\t *\n\t * By default this will update `window.location` in place, but you can provide a custom callback\n\t * to handle state changes on your own.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.registerDeepLinkListener({\n\t * onChange(url) {\n\t * window.history.replaceState({}, document.title, url.toString())\n\t * }\n\t * })\n\t * ```\n\t *\n\t * You can also provide a custom URL to update, in which case you must also provide `onChange`.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.registerDeepLinkListener({\n\t * getUrl: () => `https://my-app.com/my-document`,\n\t * onChange(url) {\n\t * setShareUrl(url.toString())\n\t * }\n\t * })\n\t * ```\n\t *\n\t * By default this will update with a debounce interval of 500ms, but you can provide a custom interval.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.registerDeepLinkListener({ debounceMs: 1000 })\n\t * ```\n\t * The default parameter name is `d`. You can override this by providing a `param` option.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.registerDeepLinkListener({ param: 'x' })\n\t * ```\n\t * @param opts - Options for setting up the listener.\n\t * @returns a function that will stop the listener.\n\t */\n\tregisterDeepLinkListener(opts?: TLDeepLinkOptions): () => void {\n\t\tif (opts?.getUrl && !opts?.onChange) {\n\t\t\tthrow Error(\n\t\t\t\t'[tldraw:urlStateSync] If you specify getUrl, you must also specify the onChange callback.'\n\t\t\t)\n\t\t}\n\n\t\tconst url$ = computed('url with state', () => {\n\t\t\tconst url = opts?.getUrl?.(this) ?? window.location.href\n\t\t\tconst urlWithState = this.createDeepLink({\n\t\t\t\tparam: opts?.param,\n\t\t\t\turl,\n\t\t\t\tto: opts?.getTarget?.(this),\n\t\t\t})\n\t\t\treturn urlWithState.toString()\n\t\t})\n\n\t\tconst announceChange =\n\t\t\topts?.onChange ??\n\t\t\t(() => {\n\t\t\t\tconst url = this.createDeepLink({\n\t\t\t\t\tparam: opts?.param,\n\t\t\t\t\tto: opts?.getTarget?.(this),\n\t\t\t\t})\n\n\t\t\t\twindow.history.replaceState({}, document.title, url.toString())\n\t\t\t})\n\n\t\tconst scheduleEffect = debounce((execute: () => void) => execute(), opts?.debounceMs ?? 500)\n\n\t\tconst unlisten = react(\n\t\t\t'update url on state change',\n\t\t\t() => announceChange(new URL(url$.get()), this),\n\t\t\t{ scheduleEffect }\n\t\t)\n\n\t\treturn () => {\n\t\t\tunlisten()\n\t\t\tscheduleEffect.cancel()\n\t\t}\n\t}\n\n\t/**\n\t * A manager for recording multiple click events.\n\t *\n\t * @internal\n\t */\n\tprotected _clickManager = new ClickManager(this)\n\n\t/**\n\t * Prevent a double click event from firing the next time the user clicks\n\t *\n\t * @public\n\t */\n\tcancelDoubleClick() {\n\t\tthis._clickManager.cancelDoubleClickTimeout()\n\t}\n\n\t/**\n\t * The previous cursor. Used for restoring the cursor after pan events.\n\t *\n\t * @internal\n\t */\n\tprivate _prevCursor: TLCursorType = 'default'\n\n\t/** @internal */\n\tprivate _shiftKeyTimeout = -1 as any\n\n\t/** @internal */\n\t@bind\n\t_setShiftKeyTimeout() {\n\t\tthis.inputs.shiftKey = false\n\t\tthis.dispatch({\n\t\t\ttype: 'keyboard',\n\t\t\tname: 'key_up',\n\t\t\tkey: 'Shift',\n\t\t\tshiftKey: this.inputs.shiftKey,\n\t\t\tctrlKey: this.inputs.ctrlKey,\n\t\t\taltKey: this.inputs.altKey,\n\t\t\tmetaKey: this.inputs.metaKey,\n\t\t\taccelKey: isAccelKey(this.inputs),\n\t\t\tcode: 'ShiftLeft',\n\t\t})\n\t}\n\n\t/** @internal */\n\tprivate _altKeyTimeout = -1 as any\n\n\t/** @internal */\n\t@bind\n\t_setAltKeyTimeout() {\n\t\tthis.inputs.altKey = false\n\t\tthis.dispatch({\n\t\t\ttype: 'keyboard',\n\t\t\tname: 'key_up',\n\t\t\tkey: 'Alt',\n\t\t\tshiftKey: this.inputs.shiftKey,\n\t\t\tctrlKey: this.inputs.ctrlKey,\n\t\t\taltKey: this.inputs.altKey,\n\t\t\tmetaKey: this.inputs.metaKey,\n\t\t\taccelKey: isAccelKey(this.inputs),\n\t\t\tcode: 'AltLeft',\n\t\t})\n\t}\n\n\t/** @internal */\n\tprivate _ctrlKeyTimeout = -1 as any\n\n\t/** @internal */\n\t@bind\n\t_setCtrlKeyTimeout() {\n\t\tthis.inputs.ctrlKey = false\n\t\tthis.dispatch({\n\t\t\ttype: 'keyboard',\n\t\t\tname: 'key_up',\n\t\t\tkey: 'Ctrl',\n\t\t\tshiftKey: this.inputs.shiftKey,\n\t\t\tctrlKey: this.inputs.ctrlKey,\n\t\t\taltKey: this.inputs.altKey,\n\t\t\tmetaKey: this.inputs.metaKey,\n\t\t\taccelKey: isAccelKey(this.inputs),\n\t\t\tcode: 'ControlLeft',\n\t\t})\n\t}\n\n\t/** @internal */\n\tprivate _metaKeyTimeout = -1 as any\n\n\t/** @internal */\n\t@bind\n\t_setMetaKeyTimeout() {\n\t\tthis.inputs.metaKey = false\n\t\tthis.dispatch({\n\t\t\ttype: 'keyboard',\n\t\t\tname: 'key_up',\n\t\t\tkey: 'Meta',\n\t\t\tshiftKey: this.inputs.shiftKey,\n\t\t\tctrlKey: this.inputs.ctrlKey,\n\t\t\taltKey: this.inputs.altKey,\n\t\t\tmetaKey: this.inputs.metaKey,\n\t\t\taccelKey: isAccelKey(this.inputs),\n\t\t\tcode: 'MetaLeft',\n\t\t})\n\t}\n\n\t/** @internal */\n\tprivate _restoreToolId = 'select'\n\n\t/** @internal */\n\tprivate _pinchStart = 1\n\n\t/** @internal */\n\tprivate _didPinch = false\n\n\t/** @internal */\n\tprivate _selectedShapeIdsAtPointerDown: TLShapeId[] = []\n\n\t/** @internal */\n\tprivate _longPressTimeout = -1 as any\n\n\t/** @internal */\n\tcapturedPointerId: number | null = null\n\n\t/** @internal */\n\tprivate readonly performanceTracker: PerformanceTracker\n\n\t/** @internal */\n\tprivate performanceTrackerTimeout = -1 as any\n\n\t/**\n\t * Dispatch an event to the editor.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.dispatch(myPointerEvent)\n\t * ```\n\t *\n\t * @param info - The event info.\n\t *\n\t * @public\n\t */\n\tdispatch(info: TLEventInfo) {\n\t\tthis._pendingEventsForNextTick.push(info)\n\t\tif (\n\t\t\t!(\n\t\t\t\t(info.type === 'pointer' && info.name === 'pointer_move') ||\n\t\t\t\tinfo.type === 'wheel' ||\n\t\t\t\tinfo.type === 'pinch'\n\t\t\t)\n\t\t) {\n\t\t\tthis._flushEventsForTick(0)\n\t\t}\n\t\treturn this\n\t}\n\n\tprivate _pendingEventsForNextTick: TLEventInfo[] = []\n\n\tprivate _flushEventsForTick(elapsed: number) {\n\t\tthis.run(() => {\n\t\t\tif (this._pendingEventsForNextTick.length > 0) {\n\t\t\t\tconst events = [...this._pendingEventsForNextTick]\n\t\t\t\tthis._pendingEventsForNextTick.length = 0\n\t\t\t\tfor (const info of events) {\n\t\t\t\t\tthis._flushEventForTick(info)\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (elapsed > 0) {\n\t\t\t\tthis.root.handleEvent({ type: 'misc', name: 'tick', elapsed })\n\t\t\t}\n\t\t\tthis.scribbles.tick(elapsed)\n\t\t})\n\t}\n\n\t_flushEventForTick(info: TLEventInfo) {\n\t\t// prevent us from spamming similar event errors if we're crashed.\n\t\t// todo: replace with new readonly mode?\n\t\tif (this.getCrashingError()) return this\n\n\t\tconst { inputs } = this\n\t\tconst { type } = info\n\n\t\tif (info.type === 'misc') {\n\t\t\t// stop panning if the interaction is cancelled or completed\n\t\t\tif (info.name === 'cancel' || info.name === 'complete') {\n\t\t\t\tthis.inputs.isDragging = false\n\n\t\t\t\tif (this.inputs.isPanning) {\n\t\t\t\t\tthis.inputs.isPanning = false\n\t\t\t\t\tthis.inputs.isSpacebarPanning = false\n\t\t\t\t\tthis.setCursor({ type: this._prevCursor, rotation: 0 })\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tthis.root.handleEvent(info)\n\t\t\treturn\n\t\t}\n\n\t\tif (info.shiftKey) {\n\t\t\tclearTimeout(this._shiftKeyTimeout)\n\t\t\tthis._shiftKeyTimeout = -1\n\t\t\tinputs.shiftKey = true\n\t\t} else if (!info.shiftKey && inputs.shiftKey && this._shiftKeyTimeout === -1) {\n\t\t\tthis._shiftKeyTimeout = this.timers.setTimeout(this._setShiftKeyTimeout, 150)\n\t\t}\n\n\t\tif (info.altKey) {\n\t\t\tclearTimeout(this._altKeyTimeout)\n\t\t\tthis._altKeyTimeout = -1\n\t\t\tinputs.altKey = true\n\t\t} else if (!info.altKey && inputs.altKey && this._altKeyTimeout === -1) {\n\t\t\tthis._altKeyTimeout = this.timers.setTimeout(this._setAltKeyTimeout, 150)\n\t\t}\n\n\t\tif (info.ctrlKey) {\n\t\t\tclearTimeout(this._ctrlKeyTimeout)\n\t\t\tthis._ctrlKeyTimeout = -1\n\t\t\tinputs.ctrlKey = true\n\t\t} else if (!info.ctrlKey && inputs.ctrlKey && this._ctrlKeyTimeout === -1) {\n\t\t\tthis._ctrlKeyTimeout = this.timers.setTimeout(this._setCtrlKeyTimeout, 150)\n\t\t}\n\n\t\tif (info.metaKey) {\n\t\t\tclearTimeout(this._metaKeyTimeout)\n\t\t\tthis._metaKeyTimeout = -1\n\t\t\tinputs.metaKey = true\n\t\t} else if (!info.metaKey && inputs.metaKey && this._metaKeyTimeout === -1) {\n\t\t\tthis._metaKeyTimeout = this.timers.setTimeout(this._setMetaKeyTimeout, 150)\n\t\t}\n\n\t\tconst { originPagePoint, currentPagePoint } = inputs\n\n\t\tif (!inputs.isPointing) {\n\t\t\tinputs.isDragging = false\n\t\t}\n\n\t\tconst instanceState = this.store.unsafeGetWithoutCapture(TLINSTANCE_ID)!\n\t\tconst pageState = this.store.get(this._getCurrentPageStateId())!\n\t\tconst cameraOptions = this._cameraOptions.__unsafe__getWithoutCapture()!\n\n\t\tswitch (type) {\n\t\t\tcase 'pinch': {\n\t\t\t\tif (cameraOptions.isLocked) return\n\t\t\t\tclearTimeout(this._longPressTimeout)\n\t\t\t\tthis._updateInputsFromEvent(info)\n\n\t\t\t\tswitch (info.name) {\n\t\t\t\t\tcase 'pinch_start': {\n\t\t\t\t\t\tif (inputs.isPinching) return\n\n\t\t\t\t\t\tif (!inputs.isEditing) {\n\t\t\t\t\t\t\tthis._pinchStart = this.getCamera().z\n\t\t\t\t\t\t\tif (!this._selectedShapeIdsAtPointerDown.length) {\n\t\t\t\t\t\t\t\tthis._selectedShapeIdsAtPointerDown = [...pageState.selectedShapeIds]\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tthis._didPinch = true\n\n\t\t\t\t\t\t\tinputs.isPinching = true\n\n\t\t\t\t\t\t\tthis.interrupt()\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\treturn // Stop here!\n\t\t\t\t\t}\n\t\t\t\t\tcase 'pinch': {\n\t\t\t\t\t\tif (!inputs.isPinching) return\n\n\t\t\t\t\t\tconst {\n\t\t\t\t\t\t\tpoint: { z = 1 },\n\t\t\t\t\t\t\tdelta: { x: dx, y: dy },\n\t\t\t\t\t\t} = info\n\n\t\t\t\t\t\t// The center of the pinch in screen space\n\t\t\t\t\t\tconst { x, y } = Vec.SubXY(\n\t\t\t\t\t\t\tinfo.point,\n\t\t\t\t\t\t\tinstanceState.screenBounds.x,\n\t\t\t\t\t\t\tinstanceState.screenBounds.y\n\t\t\t\t\t\t)\n\n\t\t\t\t\t\tthis.stopCameraAnimation()\n\t\t\t\t\t\tif (instanceState.followingUserId) {\n\t\t\t\t\t\t\tthis.stopFollowingUser()\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst { x: cx, y: cy, z: cz } = unsafe__withoutCapture(() => this.getCamera())\n\n\t\t\t\t\t\tconst { panSpeed, zoomSpeed } = cameraOptions\n\t\t\t\t\t\tthis._setCamera(\n\t\t\t\t\t\t\tnew Vec(\n\t\t\t\t\t\t\t\tcx + (dx * panSpeed) / cz - x / cz + x / (z * zoomSpeed),\n\t\t\t\t\t\t\t\tcy + (dy * panSpeed) / cz - y / cz + y / (z * zoomSpeed),\n\t\t\t\t\t\t\t\tz * zoomSpeed\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t{ immediate: true }\n\t\t\t\t\t\t)\n\n\t\t\t\t\t\treturn // Stop here!\n\t\t\t\t\t}\n\t\t\t\t\tcase 'pinch_end': {\n\t\t\t\t\t\tif (!inputs.isPinching) return this\n\n\t\t\t\t\t\t// Stop pinching\n\t\t\t\t\t\tinputs.isPinching = false\n\n\t\t\t\t\t\t// Stash and clear the shapes that were selected when the pinch started\n\t\t\t\t\t\tconst { _selectedShapeIdsAtPointerDown: shapesToReselect } = this\n\t\t\t\t\t\tthis.setSelectedShapes(this._selectedShapeIdsAtPointerDown)\n\t\t\t\t\t\tthis._selectedShapeIdsAtPointerDown = []\n\n\t\t\t\t\t\tif (this._didPinch) {\n\t\t\t\t\t\t\tthis._didPinch = false\n\t\t\t\t\t\t\tif (shapesToReselect.length > 0) {\n\t\t\t\t\t\t\t\tthis.once('tick', () => {\n\t\t\t\t\t\t\t\t\tif (!this._didPinch) {\n\t\t\t\t\t\t\t\t\t\t// Unless we've started pinching again...\n\t\t\t\t\t\t\t\t\t\t// Reselect the shapes that were selected when the pinch started\n\t\t\t\t\t\t\t\t\t\tthis.setSelectedShapes(shapesToReselect)\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\treturn // Stop here!\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tcase 'wheel': {\n\t\t\t\tif (cameraOptions.isLocked) return\n\n\t\t\t\tthis._updateInputsFromEvent(info)\n\n\t\t\t\tconst { panSpeed, zoomSpeed, wheelBehavior } = cameraOptions\n\n\t\t\t\tif (wheelBehavior !== 'none') {\n\t\t\t\t\t// Stop any camera animation\n\t\t\t\t\tthis.stopCameraAnimation()\n\t\t\t\t\t// Stop following any following user\n\t\t\t\t\tif (instanceState.followingUserId) {\n\t\t\t\t\t\tthis.stopFollowingUser()\n\t\t\t\t\t}\n\n\t\t\t\t\tconst { x: cx, y: cy, z: cz } = unsafe__withoutCapture(() => this.getCamera())\n\t\t\t\t\tconst { x: dx, y: dy, z: dz = 0 } = info.delta\n\n\t\t\t\t\tlet behavior = wheelBehavior\n\n\t\t\t\t\t// If the camera behavior is \"zoom\" and the ctrl key is pressed, then pan;\n\t\t\t\t\t// If the camera behavior is \"pan\" and the ctrl key is not pressed, then zoom\n\t\t\t\t\tif (inputs.ctrlKey) behavior = wheelBehavior === 'pan' ? 'zoom' : 'pan'\n\n\t\t\t\t\tswitch (behavior) {\n\t\t\t\t\t\tcase 'zoom': {\n\t\t\t\t\t\t\t// Zoom in on current screen point using the wheel delta\n\t\t\t\t\t\t\tconst { x, y } = this.inputs.currentScreenPoint\n\t\t\t\t\t\t\tlet delta = dz\n\n\t\t\t\t\t\t\t// If we're forcing zoom, then we need to do the wheel normalization math here\n\t\t\t\t\t\t\tif (wheelBehavior === 'zoom') {\n\t\t\t\t\t\t\t\tif (Math.abs(dy) > 10) {\n\t\t\t\t\t\t\t\t\tdelta = (10 * Math.sign(dy)) / 100\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tdelta = dy / 100\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tconst zoom = cz + (delta ?? 0) * zoomSpeed * cz\n\t\t\t\t\t\t\tthis._setCamera(\n\t\t\t\t\t\t\t\tnew Vec(\n\t\t\t\t\t\t\t\t\tcx + (x / zoom - x) - (x / cz - x),\n\t\t\t\t\t\t\t\t\tcy + (y / zoom - y) - (y / cz - y),\n\t\t\t\t\t\t\t\t\tzoom\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t{ immediate: true }\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\tthis.maybeTrackPerformance('Zooming')\n\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcase 'pan': {\n\t\t\t\t\t\t\t// Pan the camera based on the wheel delta\n\t\t\t\t\t\t\tthis._setCamera(new Vec(cx + (dx * panSpeed) / cz, cy + (dy * panSpeed) / cz, cz), {\n\t\t\t\t\t\t\t\timmediate: true,\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\tthis.maybeTrackPerformance('Panning')\n\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'pointer': {\n\t\t\t\t// Ignore pointer events while we're pinching\n\t\t\t\tif (inputs.isPinching) return\n\n\t\t\t\tthis._updateInputsFromEvent(info)\n\t\t\t\tconst { isPen } = info\n\t\t\t\tconst { isPenMode } = instanceState\n\n\t\t\t\tswitch (info.name) {\n\t\t\t\t\tcase 'pointer_down': {\n\t\t\t\t\t\t// If we're in pen mode and the input is not a pen type, then stop here\n\t\t\t\t\t\tif (isPenMode && !isPen) return\n\n\t\t\t\t\t\tif (!this.inputs.isPanning) {\n\t\t\t\t\t\t\t// Start a long press timeout\n\t\t\t\t\t\t\tthis._longPressTimeout = this.timers.setTimeout(() => {\n\t\t\t\t\t\t\t\tthis.dispatch({\n\t\t\t\t\t\t\t\t\t...info,\n\t\t\t\t\t\t\t\t\tpoint: this.inputs.currentScreenPoint,\n\t\t\t\t\t\t\t\t\tname: 'long_press',\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t}, this.options.longPressDurationMs)\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Save the selected ids at pointer down\n\t\t\t\t\t\tthis._selectedShapeIdsAtPointerDown = this.getSelectedShapeIds()\n\n\t\t\t\t\t\t// Firefox bug fix...\n\t\t\t\t\t\t// If it's a left-mouse-click, we store the pointer id for later user\n\t\t\t\t\t\tif (info.button === LEFT_MOUSE_BUTTON) this.capturedPointerId = info.pointerId\n\n\t\t\t\t\t\t// Add the button from the buttons set\n\t\t\t\t\t\tinputs.buttons.add(info.button)\n\n\t\t\t\t\t\t// Start pointing and stop dragging\n\t\t\t\t\t\tinputs.isPointing = true\n\t\t\t\t\t\tinputs.isDragging = false\n\n\t\t\t\t\t\t// If pen mode is off but we're not already in pen mode, turn that on\n\t\t\t\t\t\tif (!isPenMode && isPen) this.updateInstanceState({ isPenMode: true })\n\n\t\t\t\t\t\t// On devices with erasers (like the Surface Pen or Wacom Pen), button 5 is the eraser\n\t\t\t\t\t\tif (info.button === STYLUS_ERASER_BUTTON) {\n\t\t\t\t\t\t\tthis._restoreToolId = this.getCurrentToolId()\n\t\t\t\t\t\t\tthis.complete()\n\t\t\t\t\t\t\tthis.setCurrentTool('eraser')\n\t\t\t\t\t\t} else if (info.button === MIDDLE_MOUSE_BUTTON) {\n\t\t\t\t\t\t\t// Middle mouse pan activates panning unless we're already panning (with spacebar)\n\t\t\t\t\t\t\tif (!this.inputs.isPanning) {\n\t\t\t\t\t\t\t\tthis._prevCursor = this.getInstanceState().cursor.type\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tthis.inputs.isPanning = true\n\t\t\t\t\t\t\tclearTimeout(this._longPressTimeout)\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// We might be panning because we did a middle mouse click, or because we're holding spacebar and started a regular click\n\t\t\t\t\t\t// Also stop here, we don't want the state chart to receive the event\n\t\t\t\t\t\tif (this.inputs.isPanning) {\n\t\t\t\t\t\t\tthis.stopCameraAnimation()\n\t\t\t\t\t\t\tthis.setCursor({ type: 'grabbing', rotation: 0 })\n\t\t\t\t\t\t\treturn this\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t\tcase 'pointer_move': {\n\t\t\t\t\t\t// If the user is in pen mode, but the pointer is not a pen, stop here.\n\t\t\t\t\t\tif (!isPen && isPenMode) return\n\n\t\t\t\t\t\tconst { x: cx, y: cy, z: cz } = unsafe__withoutCapture(() => this.getCamera())\n\n\t\t\t\t\t\t// If we've started panning, then clear any long press timeout\n\t\t\t\t\t\tif (this.inputs.isPanning && this.inputs.isPointing) {\n\t\t\t\t\t\t\t// Handle spacebar / middle mouse button panning\n\t\t\t\t\t\t\tconst { currentScreenPoint, previousScreenPoint } = this.inputs\n\t\t\t\t\t\t\tconst { panSpeed } = cameraOptions\n\t\t\t\t\t\t\tconst offset = Vec.Sub(currentScreenPoint, previousScreenPoint)\n\t\t\t\t\t\t\tthis.setCamera(\n\t\t\t\t\t\t\t\tnew Vec(cx + (offset.x * panSpeed) / cz, cy + (offset.y * panSpeed) / cz, cz),\n\t\t\t\t\t\t\t\t{ immediate: true }\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\tthis.maybeTrackPerformance('Panning')\n\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\tinputs.isPointing &&\n\t\t\t\t\t\t\t!inputs.isDragging &&\n\t\t\t\t\t\t\tVec.Dist2(originPagePoint, currentPagePoint) * this.getZoomLevel() >\n\t\t\t\t\t\t\t\t(instanceState.isCoarsePointer\n\t\t\t\t\t\t\t\t\t? this.options.coarseDragDistanceSquared\n\t\t\t\t\t\t\t\t\t: this.options.dragDistanceSquared) /\n\t\t\t\t\t\t\t\t\tcz\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t// Start dragging\n\t\t\t\t\t\t\tinputs.isDragging = true\n\t\t\t\t\t\t\tclearTimeout(this._longPressTimeout)\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t\tcase 'pointer_up': {\n\t\t\t\t\t\t// Stop dragging / pointing\n\t\t\t\t\t\tinputs.isDragging = false\n\t\t\t\t\t\tinputs.isPointing = false\n\t\t\t\t\t\tclearTimeout(this._longPressTimeout)\n\n\t\t\t\t\t\t// Remove the button from the buttons set\n\t\t\t\t\t\tinputs.buttons.delete(info.button)\n\n\t\t\t\t\t\t// If we're in pen mode and we're not using a pen, stop here\n\t\t\t\t\t\tif (instanceState.isPenMode && !isPen) return\n\n\t\t\t\t\t\t// Firefox bug fix...\n\t\t\t\t\t\t// If it's the same pointer that we stored earlier...\n\t\t\t\t\t\t// ... then it's probably still a left-mouse-click!\n\t\t\t\t\t\tif (this.capturedPointerId === info.pointerId) {\n\t\t\t\t\t\t\tthis.capturedPointerId = null\n\t\t\t\t\t\t\tinfo.button = 0\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (inputs.isPanning) {\n\t\t\t\t\t\t\tif (!inputs.keys.has('Space')) {\n\t\t\t\t\t\t\t\tinputs.isPanning = false\n\t\t\t\t\t\t\t\tinputs.isSpacebarPanning = false\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tconst slideDirection = this.inputs.pointerVelocity\n\t\t\t\t\t\t\tconst slideSpeed = Math.min(2, slideDirection.len())\n\n\t\t\t\t\t\t\tswitch (info.button) {\n\t\t\t\t\t\t\t\tcase LEFT_MOUSE_BUTTON: {\n\t\t\t\t\t\t\t\t\tthis.setCursor({ type: 'grab', rotation: 0 })\n\t\t\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tcase MIDDLE_MOUSE_BUTTON: {\n\t\t\t\t\t\t\t\t\tif (this.inputs.keys.has(' ')) {\n\t\t\t\t\t\t\t\t\t\tthis.setCursor({ type: 'grab', rotation: 0 })\n\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\tthis.setCursor({ type: this._prevCursor, rotation: 0 })\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif (slideSpeed > 0) {\n\t\t\t\t\t\t\t\tthis.slideCamera({ speed: slideSpeed, direction: slideDirection })\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tif (info.button === STYLUS_ERASER_BUTTON) {\n\t\t\t\t\t\t\t\t// If we were erasing with a stylus button, restore the tool we were using before we started erasing\n\t\t\t\t\t\t\t\tthis.complete()\n\t\t\t\t\t\t\t\tthis.setCurrentTool(this._restoreToolId)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'keyboard': {\n\t\t\t\t// please, please\n\t\t\t\tif (info.key === 'ShiftRight') info.key = 'ShiftLeft'\n\t\t\t\tif (info.key === 'AltRight') info.key = 'AltLeft'\n\t\t\t\tif (info.code === 'ControlRight') info.code = 'ControlLeft'\n\t\t\t\tif (info.code === 'MetaRight') info.code = 'MetaLeft'\n\n\t\t\t\tswitch (info.name) {\n\t\t\t\t\tcase 'key_down': {\n\t\t\t\t\t\t// Add the key from the keys set\n\t\t\t\t\t\tinputs.keys.add(info.code)\n\n\t\t\t\t\t\t// If the space key is pressed (but meta / control isn't!) activate panning\n\t\t\t\t\t\tif (info.code === 'Space' && !info.ctrlKey) {\n\t\t\t\t\t\t\tif (!this.inputs.isPanning) {\n\t\t\t\t\t\t\t\tthis._prevCursor = instanceState.cursor.type\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tthis.inputs.isPanning = true\n\t\t\t\t\t\t\tthis.inputs.isSpacebarPanning = true\n\t\t\t\t\t\t\tclearTimeout(this._longPressTimeout)\n\t\t\t\t\t\t\tthis.setCursor({ type: this.inputs.isPointing ? 'grabbing' : 'grab', rotation: 0 })\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (this.inputs.isSpacebarPanning) {\n\t\t\t\t\t\t\tlet offset: Vec | undefined\n\t\t\t\t\t\t\tswitch (info.code) {\n\t\t\t\t\t\t\t\tcase 'ArrowUp': {\n\t\t\t\t\t\t\t\t\toffset = new Vec(0, -1)\n\t\t\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tcase 'ArrowRight': {\n\t\t\t\t\t\t\t\t\toffset = new Vec(1, 0)\n\t\t\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tcase 'ArrowDown': {\n\t\t\t\t\t\t\t\t\toffset = new Vec(0, 1)\n\t\t\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tcase 'ArrowLeft': {\n\t\t\t\t\t\t\t\t\toffset = new Vec(-1, 0)\n\t\t\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif (offset) {\n\t\t\t\t\t\t\t\tconst bounds = this.getViewportPageBounds()\n\t\t\t\t\t\t\t\tconst next = bounds.clone().translate(offset.mulV({ x: bounds.w, y: bounds.h }))\n\t\t\t\t\t\t\t\tthis._animateToViewport(next, { animation: { duration: 320 } })\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t\tcase 'key_up': {\n\t\t\t\t\t\t// Remove the key from the keys set\n\t\t\t\t\t\tinputs.keys.delete(info.code)\n\n\t\t\t\t\t\t// If we've lifted the space key,\n\t\t\t\t\t\tif (info.code === 'Space') {\n\t\t\t\t\t\t\tif (this.inputs.buttons.has(MIDDLE_MOUSE_BUTTON)) {\n\t\t\t\t\t\t\t\t// If we're still middle dragging, continue panning\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t// otherwise, stop panning\n\t\t\t\t\t\t\t\tthis.inputs.isPanning = false\n\t\t\t\t\t\t\t\tthis.inputs.isSpacebarPanning = false\n\t\t\t\t\t\t\t\tthis.setCursor({ type: this._prevCursor, rotation: 0 })\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t\tcase 'key_repeat': {\n\t\t\t\t\t\t// noop\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\n\t\t// Correct the info name for right / middle clicks\n\t\tif (info.type === 'pointer') {\n\t\t\tif (info.button === MIDDLE_MOUSE_BUTTON) {\n\t\t\t\tinfo.name = 'middle_click'\n\t\t\t} else if (info.button === RIGHT_MOUSE_BUTTON) {\n\t\t\t\tinfo.name = 'right_click'\n\t\t\t}\n\n\t\t\t// If a left click pointer event, send the event to the click manager.\n\t\t\tconst { isPenMode } = this.store.unsafeGetWithoutCapture(TLINSTANCE_ID)!\n\t\t\tif (info.isPen === isPenMode) {\n\t\t\t\t// The click manager may return a new event, i.e. a double click event\n\t\t\t\t// depending on the event coming in and its own state. If the event has\n\t\t\t\t// changed then hand both events to the statechart\n\t\t\t\tconst clickInfo = this._clickManager.handlePointerEvent(info)\n\t\t\t\tif (info.name !== clickInfo.name) {\n\t\t\t\t\tthis.root.handleEvent(info)\n\t\t\t\t\tthis.emit('event', info)\n\t\t\t\t\tthis.root.handleEvent(clickInfo)\n\t\t\t\t\tthis.emit('event', clickInfo)\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Send the event to the statechart. It will be handled by all\n\t\t// active states, starting at the root.\n\t\tthis.root.handleEvent(info)\n\t\tthis.emit('event', info)\n\n\t\t// close open menus at the very end on pointer down! after everything else! \u03C3\u03C5\u03BD\u03C4\u03B5\u03BB\u03B5\u03AF\u03B1\u03C2 \u03C4\u03BF\u1FE6 \u03BA\u03CE\u03B4\u03B9\u03BA\u03B1!!\n\t\tif (info.type === 'pointer' && info.name === 'pointer_down') {\n\t\t\tthis.menus.clearOpenMenus()\n\t\t}\n\n\t\treturn this\n\t}\n\n\t/** @internal */\n\tprivate maybeTrackPerformance(name: string) {\n\t\tif (debugFlags.measurePerformance.get()) {\n\t\t\tif (this.performanceTracker.isStarted()) {\n\t\t\t\tclearTimeout(this.performanceTrackerTimeout)\n\t\t\t} else {\n\t\t\t\tthis.performanceTracker.start(name)\n\t\t\t}\n\t\t\tthis.performanceTrackerTimeout = this.timers.setTimeout(() => {\n\t\t\t\tthis.performanceTracker.stop()\n\t\t\t}, 50)\n\t\t}\n\t}\n}\n\nfunction alertMaxShapes(editor: Editor, pageId = editor.getCurrentPageId()) {\n\tconst name = editor.getPage(pageId)!.name\n\teditor.emit('max-shapes', { name, pageId, count: editor.options.maxShapesPerPage })\n}\n\nfunction applyPartialToRecordWithProps<\n\tT extends UnknownRecord & { type: string; props: object; meta: object },\n>(prev: T, partial?: Partial & { props?: Partial }): T {\n\tif (!partial) return prev\n\tlet next = null as null | T\n\tconst entries = Object.entries(partial)\n\tfor (let i = 0, n = entries.length; i < n; i++) {\n\t\tconst [k, v] = entries[i]\n\t\tif (v === undefined) continue\n\n\t\t// Is the key a special key? We don't update those\n\t\tif (k === 'id' || k === 'type' || k === 'typeName') continue\n\n\t\t// Is the value the same as it was before?\n\t\tif (v === (prev as any)[k]) continue\n\n\t\t// There's a new value, so create the new shape if we haven't already (should we be cloning this?)\n\t\tif (!next) next = { ...prev }\n\n\t\t// for props / meta properties, we support updates with partials of this object\n\t\tif (k === 'props' || k === 'meta') {\n\t\t\tnext[k] = { ...prev[k] } as JsonObject\n\t\t\tfor (const [nextKey, nextValue] of Object.entries(v as object)) {\n\t\t\t\tif (nextValue !== undefined) {\n\t\t\t\t\t;(next[k] as JsonObject)[nextKey] = nextValue\n\t\t\t\t}\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\n\t\t// base property\n\t\t;(next as any)[k] = v\n\t}\n\tif (!next) return prev\n\treturn next\n}\n\nfunction pushShapeWithDescendants(editor: Editor, id: TLShapeId, result: TLShape[]): void {\n\tconst shape = editor.getShape(id)\n\tif (!shape) return\n\tresult.push(shape)\n\tconst childIds = editor.getSortedChildIdsForParent(id)\n\tfor (let i = 0, n = childIds.length; i < n; i++) {\n\t\tpushShapeWithDescendants(editor, childIds[i], result)\n\t}\n}\n\n/**\n * Run `callback` in a world where all bindings from the shapes in `shapeIds` to shapes not in\n * `shapeIds` are removed. This is useful when you want to duplicate/copy shapes without worrying\n * about bindings that might be pointing to shapes that are not being duplicated.\n *\n * The callback is given the set of bindings that should be maintained.\n */\nfunction withIsolatedShapes(\n\teditor: Editor,\n\tshapeIds: Set,\n\tcallback: (bindingsWithBoth: Set) => T\n): T {\n\tlet result!: Result\n\n\teditor.run(\n\t\t() => {\n\t\t\tconst changes = editor.store.extractingChanges(() => {\n\t\t\t\tconst bindingsWithBoth = new Set()\n\t\t\t\tconst bindingsToRemove = new Set()\n\n\t\t\t\tfor (const shapeId of shapeIds) {\n\t\t\t\t\tconst shape = editor.getShape(shapeId)\n\t\t\t\t\tif (!shape) continue\n\n\t\t\t\t\tfor (const binding of editor.getBindingsInvolvingShape(shapeId)) {\n\t\t\t\t\t\tconst hasFrom = shapeIds.has(binding.fromId)\n\t\t\t\t\t\tconst hasTo = shapeIds.has(binding.toId)\n\t\t\t\t\t\tif (hasFrom && hasTo) {\n\t\t\t\t\t\t\tbindingsWithBoth.add(binding.id)\n\t\t\t\t\t\t\tcontinue\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (!hasFrom || !hasTo) {\n\t\t\t\t\t\t\tbindingsToRemove.add(binding.id)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\teditor.deleteBindings([...bindingsToRemove], { isolateShapes: true })\n\n\t\t\t\ttry {\n\t\t\t\t\tresult = Result.ok(callback(bindingsWithBoth))\n\t\t\t\t} catch (error) {\n\t\t\t\t\tresult = Result.err(error)\n\t\t\t\t}\n\t\t\t})\n\n\t\t\teditor.store.applyDiff(reverseRecordsDiff(changes))\n\t\t},\n\t\t{ history: 'ignore' }\n\t)\n\n\tif (result.ok) {\n\t\treturn result.value\n\t} else {\n\t\tthrow result.error\n\t}\n}\n\nfunction getCameraFitXFitY(editor: Editor, cameraOptions: TLCameraOptions) {\n\tif (!cameraOptions.constraints) throw Error('Should have constraints here')\n\tconst {\n\t\tpadding: { x: px, y: py },\n\t} = cameraOptions.constraints\n\tconst vsb = editor.getViewportScreenBounds()\n\tconst bounds = Box.From(cameraOptions.constraints.bounds)\n\tconst zx = (vsb.w - px * 2) / bounds.w\n\tconst zy = (vsb.h - py * 2) / bounds.h\n\treturn { zx, zy }\n}\n"], ++ "mappings": "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", + "names": ["shape", "highlightedUserIds", "page", "notVisibleShapes", "distance", "ancestor", "bindingsToCreate", "shapesToCreateWithOriginals", "gap", "last", "i", "animatingShapes", "n", "group", "shapes", "bindings", "pageId"] + } +diff --git a/node_modules/@tldraw/editor/dist-esm/lib/hooks/useDocumentEvents.mjs b/node_modules/@tldraw/editor/dist-esm/lib/hooks/useDocumentEvents.mjs +index 790e8b6..983d98b 100644 +--- a/node_modules/@tldraw/editor/dist-esm/lib/hooks/useDocumentEvents.mjs ++++ b/node_modules/@tldraw/editor/dist-esm/lib/hooks/useDocumentEvents.mjs +@@ -162,17 +162,17 @@ function useDocumentEvents() { + }; + container.addEventListener("touchstart", handleTouchStart, { passive: false }); + container.addEventListener("wheel", handleWheel, { passive: false }); +- document.addEventListener("gesturestart", preventDefault); +- document.addEventListener("gesturechange", preventDefault); +- document.addEventListener("gestureend", preventDefault); ++ container.ownerDocument.addEventListener("gesturestart", preventDefault); ++ container.ownerDocument.addEventListener("gesturechange", preventDefault); ++ container.ownerDocument.addEventListener("gestureend", preventDefault); + container.addEventListener("keydown", handleKeyDown); + container.addEventListener("keyup", handleKeyUp); + return () => { + container.removeEventListener("touchstart", handleTouchStart); + container.removeEventListener("wheel", handleWheel); +- document.removeEventListener("gesturestart", preventDefault); +- document.removeEventListener("gesturechange", preventDefault); +- document.removeEventListener("gestureend", preventDefault); ++ container.ownerDocument.removeEventListener("gesturestart", preventDefault); ++ container.ownerDocument.removeEventListener("gesturechange", preventDefault); ++ container.ownerDocument.removeEventListener("gestureend", preventDefault); + container.removeEventListener("keydown", handleKeyDown); + container.removeEventListener("keyup", handleKeyUp); + }; +diff --git a/node_modules/@tldraw/editor/dist-esm/lib/hooks/useDocumentEvents.mjs.map b/node_modules/@tldraw/editor/dist-esm/lib/hooks/useDocumentEvents.mjs.map +index 5df882a..01ede07 100644 +--- a/node_modules/@tldraw/editor/dist-esm/lib/hooks/useDocumentEvents.mjs.map ++++ b/node_modules/@tldraw/editor/dist-esm/lib/hooks/useDocumentEvents.mjs.map +@@ -1,7 +1,7 @@ + { + "version": 3, + "sources": ["../../../src/lib/hooks/useDocumentEvents.ts"], +- "sourcesContent": ["import { useValue } from '@tldraw/state-react'\nimport { useEffect } from 'react'\nimport { Editor } from '../editor/Editor'\nimport { TLKeyboardEventInfo } from '../editor/types/event-types'\nimport { preventDefault, stopEventPropagation } from '../utils/dom'\nimport { isAccelKey } from '../utils/keyboard'\nimport { useContainer } from './useContainer'\nimport { useEditor } from './useEditor'\n\nexport function useDocumentEvents() {\n\tconst editor = useEditor()\n\tconst container = useContainer()\n\n\tconst isAppFocused = useValue('isFocused', () => editor.getIsFocused(), [editor])\n\n\t// Prevent the browser's default drag and drop behavior on our container (UI, etc)\n\tuseEffect(() => {\n\t\tif (!container) return\n\n\t\tfunction onDrop(e: DragEvent) {\n\t\t\t// this is tricky: we don't want the event to do anything\n\t\t\t// here, but we do want it to make its way to the canvas,\n\t\t\t// even if the drop is over some other element (like a toolbar),\n\t\t\t// so we're going to flag the event and then dispatch\n\t\t\t// it to the canvas; the canvas will handle it and try to\n\t\t\t// stop it from propagating back, but in case we do see it again,\n\t\t\t// we'll look for the flag so we know to stop it from being\n\t\t\t// re-dispatched, which would lead to an infinite loop.\n\t\t\tif ((e as any).isSpecialRedispatchedEvent) return\n\t\t\tpreventDefault(e)\n\t\t\tstopEventPropagation(e)\n\t\t\tconst cvs = container.querySelector('.tl-canvas')\n\t\t\tif (!cvs) return\n\t\t\tconst newEvent = new DragEvent(e.type, e)\n\t\t\t;(newEvent as any).isSpecialRedispatchedEvent = true\n\t\t\tcvs.dispatchEvent(newEvent)\n\t\t}\n\n\t\tcontainer.addEventListener('dragover', onDrop)\n\t\tcontainer.addEventListener('drop', onDrop)\n\t\treturn () => {\n\t\t\tcontainer.removeEventListener('dragover', onDrop)\n\t\t\tcontainer.removeEventListener('drop', onDrop)\n\t\t}\n\t}, [container])\n\n\tuseEffect(() => {\n\t\tif (typeof window === 'undefined' || !('matchMedia' in window)) return\n\n\t\t// https://developer.mozilla.org/en-US/docs/Web/API/Window/devicePixelRatio#monitoring_screen_resolution_or_zoom_level_changes\n\t\tlet remove: (() => void) | null = null\n\t\tconst updatePixelRatio = () => {\n\t\t\tif (remove != null) {\n\t\t\t\tremove()\n\t\t\t}\n\t\t\tconst mqString = `(resolution: ${window.devicePixelRatio}dppx)`\n\t\t\tconst media = matchMedia(mqString)\n\t\t\t// Safari only started supporting `addEventListener('change',...) in version 14\n\t\t\t// https://developer.mozilla.org/en-US/docs/Web/API/MediaQueryList/change_event\n\t\t\tconst safariCb = (ev: any) => {\n\t\t\t\tif (ev.type === 'change') {\n\t\t\t\t\tupdatePixelRatio()\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (media.addEventListener) {\n\t\t\t\tmedia.addEventListener('change', updatePixelRatio)\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-deprecated\n\t\t\t} else if (media.addListener) {\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-deprecated\n\t\t\t\tmedia.addListener(safariCb)\n\t\t\t}\n\t\t\tremove = () => {\n\t\t\t\tif (media.removeEventListener) {\n\t\t\t\t\tmedia.removeEventListener('change', updatePixelRatio)\n\t\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-deprecated\n\t\t\t\t} else if (media.removeListener) {\n\t\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-deprecated\n\t\t\t\t\tmedia.removeListener(safariCb)\n\t\t\t\t}\n\t\t\t}\n\t\t\teditor.updateInstanceState({ devicePixelRatio: window.devicePixelRatio })\n\t\t}\n\t\tupdatePixelRatio()\n\t\treturn () => {\n\t\t\tremove?.()\n\t\t}\n\t}, [editor])\n\n\tuseEffect(() => {\n\t\tif (!isAppFocused) return\n\n\t\tconst handleKeyDown = (e: KeyboardEvent) => {\n\t\t\tif (\n\t\t\t\te.altKey &&\n\t\t\t\t// todo: When should we allow the alt key to be used? Perhaps states should declare which keys matter to them?\n\t\t\t\t(editor.isIn('zoom') || !editor.getPath().endsWith('.idle')) &&\n\t\t\t\t!areShortcutsDisabled(editor)\n\t\t\t) {\n\t\t\t\t// On windows the alt key opens the menu bar.\n\t\t\t\t// We want to prevent that if the user is doing something else,\n\t\t\t\t// e.g. resizing a shape\n\t\t\t\tpreventDefault(e)\n\t\t\t}\n\n\t\t\tif ((e as any).isKilled) return\n\t\t\t;(e as any).isKilled = true\n\n\t\t\tswitch (e.key) {\n\t\t\t\tcase '=':\n\t\t\t\tcase '-':\n\t\t\t\tcase '0': {\n\t\t\t\t\t// These keys are used for zooming. Technically we only use\n\t\t\t\t\t// the + - and 0 keys, however it's common for them to be\n\t\t\t\t\t// paired with modifier keys (command / control) so we need\n\t\t\t\t\t// to prevent the browser's regular actions (i.e. zooming\n\t\t\t\t\t// the page). A user can zoom by unfocusing the editor.\n\t\t\t\t\tif (e.metaKey || e.ctrlKey) {\n\t\t\t\t\t\tpreventDefault(e)\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase 'Tab': {\n\t\t\t\t\tif (areShortcutsDisabled(editor)) {\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase ',': {\n\t\t\t\t\t// this was moved to useKeyBoardShortcuts; it's possible\n\t\t\t\t\t// that the comma key is pressed when the container is not\n\t\t\t\t\t// focused, for example when the user has just interacted\n\t\t\t\t\t// with the toolbar. We need to handle it on the window\n\t\t\t\t\t// (ofc ensuring it's a correct time for a shortcut)\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tcase 'Escape': {\n\t\t\t\t\t// In certain browsers, pressing escape while in full screen mode\n\t\t\t\t\t// will exit full screen mode. We want to allow that, but not when\n\t\t\t\t\t// escape is being handled by the editor. When a user has an editing\n\t\t\t\t\t// shape, escape stops editing. When a user is using a tool, escape\n\t\t\t\t\t// returns to the select tool. When the user has selected shapes,\n\t\t\t\t\t// escape de-selects them. Only when the user's selection is empty\n\t\t\t\t\t// should we allow escape to do its normal thing.\n\n\t\t\t\t\tif (editor.getEditingShape() || editor.getSelectedShapeIds().length > 0) {\n\t\t\t\t\t\tpreventDefault(e)\n\t\t\t\t\t}\n\n\t\t\t\t\t// Don't do anything if we open menus open\n\t\t\t\t\tif (editor.menus.getOpenMenus().length > 0) return\n\n\t\t\t\t\tif (editor.inputs.keys.has('Escape')) {\n\t\t\t\t\t\t// noop\n\t\t\t\t\t} else {\n\t\t\t\t\t\teditor.inputs.keys.add('Escape')\n\n\t\t\t\t\t\teditor.cancel()\n\t\t\t\t\t\t// Pressing escape will focus the document.body,\n\t\t\t\t\t\t// which will cause the app to lose focus, which\n\t\t\t\t\t\t// will break additional shortcuts. We need to\n\t\t\t\t\t\t// refocus the container in order to keep these\n\t\t\t\t\t\t// shortcuts working.\n\t\t\t\t\t\tcontainer.focus()\n\t\t\t\t\t}\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tdefault: {\n\t\t\t\t\tif (areShortcutsDisabled(editor)) {\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst info: TLKeyboardEventInfo = {\n\t\t\t\ttype: 'keyboard',\n\t\t\t\tname: e.repeat ? 'key_repeat' : 'key_down',\n\t\t\t\tkey: e.key,\n\t\t\t\tcode: e.code,\n\t\t\t\tshiftKey: e.shiftKey,\n\t\t\t\taltKey: e.altKey,\n\t\t\t\tctrlKey: e.metaKey || e.ctrlKey,\n\t\t\t\tmetaKey: e.metaKey,\n\t\t\t\taccelKey: isAccelKey(e),\n\t\t\t}\n\n\t\t\teditor.dispatch(info)\n\t\t}\n\n\t\tconst handleKeyUp = (e: KeyboardEvent) => {\n\t\t\tif ((e as any).isKilled) return\n\t\t\t;(e as any).isKilled = true\n\n\t\t\tif (areShortcutsDisabled(editor)) {\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tif (e.key === ',') {\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tconst info: TLKeyboardEventInfo = {\n\t\t\t\ttype: 'keyboard',\n\t\t\t\tname: 'key_up',\n\t\t\t\tkey: e.key,\n\t\t\t\tcode: e.code,\n\t\t\t\tshiftKey: e.shiftKey,\n\t\t\t\taltKey: e.altKey,\n\t\t\t\tctrlKey: e.metaKey || e.ctrlKey,\n\t\t\t\tmetaKey: e.metaKey,\n\t\t\t\taccelKey: isAccelKey(e),\n\t\t\t}\n\n\t\t\teditor.dispatch(info)\n\t\t}\n\n\t\tfunction handleTouchStart(e: TouchEvent) {\n\t\t\tif (container.contains(e.target as Node)) {\n\t\t\t\t// Center point of the touch area\n\t\t\t\tconst touchXPosition = e.touches[0].pageX\n\t\t\t\t// Size of the touch area\n\t\t\t\tconst touchXRadius = e.touches[0].radiusX || 0\n\n\t\t\t\t// We set a threshold (10px) on both sizes of the screen,\n\t\t\t\t// if the touch area overlaps with the screen edges\n\t\t\t\t// it's likely to trigger the navigation. We prevent the\n\t\t\t\t// touchstart event in that case.\n\t\t\t\t// todo: make this relative to the actual window, not the editor's screen bounds\n\t\t\t\tif (\n\t\t\t\t\ttouchXPosition - touchXRadius < 10 ||\n\t\t\t\t\ttouchXPosition + touchXRadius > editor.getViewportScreenBounds().width - 10\n\t\t\t\t) {\n\t\t\t\t\tif ((e.target as HTMLElement)?.tagName === 'BUTTON') {\n\t\t\t\t\t\t// Force a click before bailing\n\t\t\t\t\t\t;(e.target as HTMLButtonElement)?.click()\n\t\t\t\t\t}\n\n\t\t\t\t\tpreventDefault(e)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Prevent wheel events that occur inside of the container\n\t\tconst handleWheel = (e: WheelEvent) => {\n\t\t\t// Ctrl/Meta key indicates a pinch event (funny, eh?)\n\t\t\tif (container.contains(e.target as Node) && (e.ctrlKey || e.metaKey)) {\n\t\t\t\tpreventDefault(e)\n\t\t\t}\n\t\t}\n\n\t\tcontainer.addEventListener('touchstart', handleTouchStart, { passive: false })\n\n\t\tcontainer.addEventListener('wheel', handleWheel, { passive: false })\n\n\t\tdocument.addEventListener('gesturestart', preventDefault)\n\t\tdocument.addEventListener('gesturechange', preventDefault)\n\t\tdocument.addEventListener('gestureend', preventDefault)\n\n\t\tcontainer.addEventListener('keydown', handleKeyDown)\n\t\tcontainer.addEventListener('keyup', handleKeyUp)\n\n\t\treturn () => {\n\t\t\tcontainer.removeEventListener('touchstart', handleTouchStart)\n\n\t\t\tcontainer.removeEventListener('wheel', handleWheel)\n\n\t\t\tdocument.removeEventListener('gesturestart', preventDefault)\n\t\t\tdocument.removeEventListener('gesturechange', preventDefault)\n\t\t\tdocument.removeEventListener('gestureend', preventDefault)\n\n\t\t\tcontainer.removeEventListener('keydown', handleKeyDown)\n\t\t\tcontainer.removeEventListener('keyup', handleKeyUp)\n\t\t}\n\t}, [editor, container, isAppFocused])\n}\n\nconst INPUTS = ['input', 'select', 'button', 'textarea']\n\nfunction areShortcutsDisabled(editor: Editor) {\n\tconst { activeElement } = document\n\n\treturn (\n\t\teditor.menus.hasOpenMenus() ||\n\t\t(activeElement &&\n\t\t\t(activeElement.getAttribute('contenteditable') ||\n\t\t\t\tINPUTS.indexOf(activeElement.tagName.toLowerCase()) > -1))\n\t)\n}\n"], +- "mappings": "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", ++ "sourcesContent": ["import { useValue } from '@tldraw/state-react'\nimport { useEffect } from 'react'\nimport { Editor } from '../editor/Editor'\nimport { TLKeyboardEventInfo } from '../editor/types/event-types'\nimport { preventDefault, stopEventPropagation } from '../utils/dom'\nimport { isAccelKey } from '../utils/keyboard'\nimport { useContainer } from './useContainer'\nimport { useEditor } from './useEditor'\n\nexport function useDocumentEvents() {\n\tconst editor = useEditor()\n\tconst container = useContainer()\n\n\tconst isAppFocused = useValue('isFocused', () => editor.getIsFocused(), [editor])\n\n\t// Prevent the browser's default drag and drop behavior on our container (UI, etc)\n\tuseEffect(() => {\n\t\tif (!container) return\n\n\t\tfunction onDrop(e: DragEvent) {\n\t\t\t// this is tricky: we don't want the event to do anything\n\t\t\t// here, but we do want it to make its way to the canvas,\n\t\t\t// even if the drop is over some other element (like a toolbar),\n\t\t\t// so we're going to flag the event and then dispatch\n\t\t\t// it to the canvas; the canvas will handle it and try to\n\t\t\t// stop it from propagating back, but in case we do see it again,\n\t\t\t// we'll look for the flag so we know to stop it from being\n\t\t\t// re-dispatched, which would lead to an infinite loop.\n\t\t\tif ((e as any).isSpecialRedispatchedEvent) return\n\t\t\tpreventDefault(e)\n\t\t\tstopEventPropagation(e)\n\t\t\tconst cvs = container.querySelector('.tl-canvas')\n\t\t\tif (!cvs) return\n\t\t\tconst newEvent = new DragEvent(e.type, e)\n\t\t\t;(newEvent as any).isSpecialRedispatchedEvent = true\n\t\t\tcvs.dispatchEvent(newEvent)\n\t\t}\n\n\t\tcontainer.addEventListener('dragover', onDrop)\n\t\tcontainer.addEventListener('drop', onDrop)\n\t\treturn () => {\n\t\t\tcontainer.removeEventListener('dragover', onDrop)\n\t\t\tcontainer.removeEventListener('drop', onDrop)\n\t\t}\n\t}, [container])\n\n\tuseEffect(() => {\n\t\tif (typeof window === 'undefined' || !('matchMedia' in window)) return\n\n\t\t// https://developer.mozilla.org/en-US/docs/Web/API/Window/devicePixelRatio#monitoring_screen_resolution_or_zoom_level_changes\n\t\tlet remove: (() => void) | null = null\n\t\tconst updatePixelRatio = () => {\n\t\t\tif (remove != null) {\n\t\t\t\tremove()\n\t\t\t}\n\t\t\tconst mqString = `(resolution: ${window.devicePixelRatio}dppx)`\n\t\t\tconst media = matchMedia(mqString)\n\t\t\t// Safari only started supporting `addEventListener('change',...) in version 14\n\t\t\t// https://developer.mozilla.org/en-US/docs/Web/API/MediaQueryList/change_event\n\t\t\tconst safariCb = (ev: any) => {\n\t\t\t\tif (ev.type === 'change') {\n\t\t\t\t\tupdatePixelRatio()\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (media.addEventListener) {\n\t\t\t\tmedia.addEventListener('change', updatePixelRatio)\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-deprecated\n\t\t\t} else if (media.addListener) {\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-deprecated\n\t\t\t\tmedia.addListener(safariCb)\n\t\t\t}\n\t\t\tremove = () => {\n\t\t\t\tif (media.removeEventListener) {\n\t\t\t\t\tmedia.removeEventListener('change', updatePixelRatio)\n\t\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-deprecated\n\t\t\t\t} else if (media.removeListener) {\n\t\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-deprecated\n\t\t\t\t\tmedia.removeListener(safariCb)\n\t\t\t\t}\n\t\t\t}\n\t\t\teditor.updateInstanceState({ devicePixelRatio: window.devicePixelRatio })\n\t\t}\n\t\tupdatePixelRatio()\n\t\treturn () => {\n\t\t\tremove?.()\n\t\t}\n\t}, [editor])\n\n\tuseEffect(() => {\n\t\tif (!isAppFocused) return\n\n\t\tconst handleKeyDown = (e: KeyboardEvent) => {\n\t\t\tif (\n\t\t\t\te.altKey &&\n\t\t\t\t// todo: When should we allow the alt key to be used? Perhaps states should declare which keys matter to them?\n\t\t\t\t(editor.isIn('zoom') || !editor.getPath().endsWith('.idle')) &&\n\t\t\t\t!areShortcutsDisabled(editor)\n\t\t\t) {\n\t\t\t\t// On windows the alt key opens the menu bar.\n\t\t\t\t// We want to prevent that if the user is doing something else,\n\t\t\t\t// e.g. resizing a shape\n\t\t\t\tpreventDefault(e)\n\t\t\t}\n\n\t\t\tif ((e as any).isKilled) return\n\t\t\t;(e as any).isKilled = true\n\n\t\t\tswitch (e.key) {\n\t\t\t\tcase '=':\n\t\t\t\tcase '-':\n\t\t\t\tcase '0': {\n\t\t\t\t\t// These keys are used for zooming. Technically we only use\n\t\t\t\t\t// the + - and 0 keys, however it's common for them to be\n\t\t\t\t\t// paired with modifier keys (command / control) so we need\n\t\t\t\t\t// to prevent the browser's regular actions (i.e. zooming\n\t\t\t\t\t// the page). A user can zoom by unfocusing the editor.\n\t\t\t\t\tif (e.metaKey || e.ctrlKey) {\n\t\t\t\t\t\tpreventDefault(e)\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase 'Tab': {\n\t\t\t\t\tif (areShortcutsDisabled(editor)) {\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase ',': {\n\t\t\t\t\t// this was moved to useKeyBoardShortcuts; it's possible\n\t\t\t\t\t// that the comma key is pressed when the container is not\n\t\t\t\t\t// focused, for example when the user has just interacted\n\t\t\t\t\t// with the toolbar. We need to handle it on the window\n\t\t\t\t\t// (ofc ensuring it's a correct time for a shortcut)\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tcase 'Escape': {\n\t\t\t\t\t// In certain browsers, pressing escape while in full screen mode\n\t\t\t\t\t// will exit full screen mode. We want to allow that, but not when\n\t\t\t\t\t// escape is being handled by the editor. When a user has an editing\n\t\t\t\t\t// shape, escape stops editing. When a user is using a tool, escape\n\t\t\t\t\t// returns to the select tool. When the user has selected shapes,\n\t\t\t\t\t// escape de-selects them. Only when the user's selection is empty\n\t\t\t\t\t// should we allow escape to do its normal thing.\n\n\t\t\t\t\tif (editor.getEditingShape() || editor.getSelectedShapeIds().length > 0) {\n\t\t\t\t\t\tpreventDefault(e)\n\t\t\t\t\t}\n\n\t\t\t\t\t// Don't do anything if we open menus open\n\t\t\t\t\tif (editor.menus.getOpenMenus().length > 0) return\n\n\t\t\t\t\tif (editor.inputs.keys.has('Escape')) {\n\t\t\t\t\t\t// noop\n\t\t\t\t\t} else {\n\t\t\t\t\t\teditor.inputs.keys.add('Escape')\n\n\t\t\t\t\t\teditor.cancel()\n\t\t\t\t\t\t// Pressing escape will focus the document.body,\n\t\t\t\t\t\t// which will cause the app to lose focus, which\n\t\t\t\t\t\t// will break additional shortcuts. We need to\n\t\t\t\t\t\t// refocus the container in order to keep these\n\t\t\t\t\t\t// shortcuts working.\n\t\t\t\t\t\tcontainer.focus()\n\t\t\t\t\t}\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tdefault: {\n\t\t\t\t\tif (areShortcutsDisabled(editor)) {\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst info: TLKeyboardEventInfo = {\n\t\t\t\ttype: 'keyboard',\n\t\t\t\tname: e.repeat ? 'key_repeat' : 'key_down',\n\t\t\t\tkey: e.key,\n\t\t\t\tcode: e.code,\n\t\t\t\tshiftKey: e.shiftKey,\n\t\t\t\taltKey: e.altKey,\n\t\t\t\tctrlKey: e.metaKey || e.ctrlKey,\n\t\t\t\tmetaKey: e.metaKey,\n\t\t\t\taccelKey: isAccelKey(e),\n\t\t\t}\n\n\t\t\teditor.dispatch(info)\n\t\t}\n\n\t\tconst handleKeyUp = (e: KeyboardEvent) => {\n\t\t\tif ((e as any).isKilled) return\n\t\t\t;(e as any).isKilled = true\n\n\t\t\tif (areShortcutsDisabled(editor)) {\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tif (e.key === ',') {\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tconst info: TLKeyboardEventInfo = {\n\t\t\t\ttype: 'keyboard',\n\t\t\t\tname: 'key_up',\n\t\t\t\tkey: e.key,\n\t\t\t\tcode: e.code,\n\t\t\t\tshiftKey: e.shiftKey,\n\t\t\t\taltKey: e.altKey,\n\t\t\t\tctrlKey: e.metaKey || e.ctrlKey,\n\t\t\t\tmetaKey: e.metaKey,\n\t\t\t\taccelKey: isAccelKey(e),\n\t\t\t}\n\n\t\t\teditor.dispatch(info)\n\t\t}\n\n\t\tfunction handleTouchStart(e: TouchEvent) {\n\t\t\tif (container.contains(e.target as Node)) {\n\t\t\t\t// Center point of the touch area\n\t\t\t\tconst touchXPosition = e.touches[0].pageX\n\t\t\t\t// Size of the touch area\n\t\t\t\tconst touchXRadius = e.touches[0].radiusX || 0\n\n\t\t\t\t// We set a threshold (10px) on both sizes of the screen,\n\t\t\t\t// if the touch area overlaps with the screen edges\n\t\t\t\t// it's likely to trigger the navigation. We prevent the\n\t\t\t\t// touchstart event in that case.\n\t\t\t\t// todo: make this relative to the actual window, not the editor's screen bounds\n\t\t\t\tif (\n\t\t\t\t\ttouchXPosition - touchXRadius < 10 ||\n\t\t\t\t\ttouchXPosition + touchXRadius > editor.getViewportScreenBounds().width - 10\n\t\t\t\t) {\n\t\t\t\t\tif ((e.target as HTMLElement)?.tagName === 'BUTTON') {\n\t\t\t\t\t\t// Force a click before bailing\n\t\t\t\t\t\t;(e.target as HTMLButtonElement)?.click()\n\t\t\t\t\t}\n\n\t\t\t\t\tpreventDefault(e)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Prevent wheel events that occur inside of the container\n\t\tconst handleWheel = (e: WheelEvent) => {\n\t\t\t// Ctrl/Meta key indicates a pinch event (funny, eh?)\n\t\t\tif (container.contains(e.target as Node) && (e.ctrlKey || e.metaKey)) {\n\t\t\t\tpreventDefault(e)\n\t\t\t}\n\t\t}\n\n\t\tcontainer.addEventListener('touchstart', handleTouchStart, { passive: false })\n\n\t\tcontainer.addEventListener('wheel', handleWheel, { passive: false })\n\n\t\tcontainer.ownerDocument.addEventListener('gesturestart', preventDefault)\n\t\tcontainer.ownerDocument.addEventListener('gesturechange', preventDefault)\n\t\tcontainer.ownerDocument.addEventListener('gestureend', preventDefault)\n\n\t\tcontainer.addEventListener('keydown', handleKeyDown)\n\t\tcontainer.addEventListener('keyup', handleKeyUp)\n\n\t\treturn () => {\n\t\t\tcontainer.removeEventListener('touchstart', handleTouchStart)\n\n\t\t\tcontainer.removeEventListener('wheel', handleWheel)\n\n\t\t\tcontainer.ownerDocument.removeEventListener('gesturestart', preventDefault)\n\t\t\tcontainer.ownerDocument.removeEventListener('gesturechange', preventDefault)\n\t\t\tcontainer.ownerDocument.removeEventListener('gestureend', preventDefault)\n\n\t\t\tcontainer.removeEventListener('keydown', handleKeyDown)\n\t\t\tcontainer.removeEventListener('keyup', handleKeyUp)\n\t\t}\n\t}, [editor, container, isAppFocused])\n}\n\nconst INPUTS = ['input', 'select', 'button', 'textarea']\n\nfunction areShortcutsDisabled(editor: Editor) {\n\tconst { activeElement } = document\n\n\treturn (\n\t\teditor.menus.hasOpenMenus() ||\n\t\t(activeElement &&\n\t\t\t(activeElement.getAttribute('contenteditable') ||\n\t\t\t\tINPUTS.indexOf(activeElement.tagName.toLowerCase()) > -1))\n\t)\n}\n"], ++ "mappings": "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", + "names": [] + } +diff --git a/node_modules/@tldraw/editor/dist-esm/lib/utils/dom.mjs b/node_modules/@tldraw/editor/dist-esm/lib/utils/dom.mjs +index ba246e3..216dfdd 100644 +--- a/node_modules/@tldraw/editor/dist-esm/lib/utils/dom.mjs ++++ b/node_modules/@tldraw/editor/dist-esm/lib/utils/dom.mjs +@@ -1,6 +1,6 @@ + import { debugFlags, pointerCaptureTrackingObject } from "./debug-flags.mjs"; + function loopToHtmlElement(elm) { +- if (elm instanceof HTMLElement) return elm; ++ if (elm.instanceOf(HTMLElement)) return elm; + if (elm.parentElement) return loopToHtmlElement(elm.parentElement); + else throw Error("Could not find a parent element of an HTML type!"); + } +diff --git a/node_modules/@tldraw/editor/dist-esm/lib/utils/dom.mjs.map b/node_modules/@tldraw/editor/dist-esm/lib/utils/dom.mjs.map +index fd8b878..d5eae31 100644 +--- a/node_modules/@tldraw/editor/dist-esm/lib/utils/dom.mjs.map ++++ b/node_modules/@tldraw/editor/dist-esm/lib/utils/dom.mjs.map +@@ -1,7 +1,7 @@ + { + "version": 3, + "sources": ["../../../src/lib/utils/dom.ts"], +- "sourcesContent": ["/*\nThis is used to facilitate double clicking and pointer capture on elements.\n\nThe events in this file are possibly set on individual SVG elements, \nsuch as handles or corner handles, rather than on HTML elements or \nSVGSVGElements. Raw SVG elemnets do not support pointerCapture in \nmost cases, meaning that in order for pointer capture to work, we \nneed to crawl up the DOM tree to find the nearest HTML element. Then,\nin order for that element to also call the `onPointerUp` event from\nthis file, we need to manually set that event on that element and\nlater remove it when the pointerup occurs. This is a potential leak\nif the user clicks on a handle but the pointerup does not fire for\nwhatever reason.\n*/\n\nimport React from 'react'\nimport { debugFlags, pointerCaptureTrackingObject } from './debug-flags'\n\n/** @public */\nexport function loopToHtmlElement(elm: Element): HTMLElement {\n\tif (elm instanceof HTMLElement) return elm\n\tif (elm.parentElement) return loopToHtmlElement(elm.parentElement)\n\telse throw Error('Could not find a parent element of an HTML type!')\n}\n\n/**\n * This function calls `event.preventDefault()` for you. Why is that useful?\n *\n * Beacuase if you enable `window.preventDefaultLogging = true` it'll log out a message when it\n * happens. Because we use console.warn rather than (log) you'll get a stack trace in the inspector\n * telling you exactly where it happened. This is important because `e.preventDefault()` is the\n * source of many bugs, but unfortuantly it can't be avoided because it also stops a lot of default\n * behaviour which doesn't make sense in our UI\n *\n * @param event - To prevent default on\n * @public\n */\nexport function preventDefault(event: React.BaseSyntheticEvent | Event) {\n\tevent.preventDefault()\n\tif (debugFlags.logPreventDefaults.get()) {\n\t\tconsole.warn('preventDefault called on event:', event)\n\t}\n}\n\n/** @public */\nexport function setPointerCapture(\n\telement: Element,\n\tevent: React.PointerEvent | PointerEvent\n) {\n\telement.setPointerCapture(event.pointerId)\n\tif (debugFlags.logPointerCaptures.get()) {\n\t\tconst trackingObj = pointerCaptureTrackingObject.get()\n\t\ttrackingObj.set(element, (trackingObj.get(element) ?? 0) + 1)\n\t\tconsole.warn('setPointerCapture called on element:', element, event)\n\t}\n}\n\n/** @public */\nexport function releasePointerCapture(\n\telement: Element,\n\tevent: React.PointerEvent | PointerEvent\n) {\n\tif (!element.hasPointerCapture(event.pointerId)) {\n\t\treturn\n\t}\n\n\telement.releasePointerCapture(event.pointerId)\n\tif (debugFlags.logPointerCaptures.get()) {\n\t\tconst trackingObj = pointerCaptureTrackingObject.get()\n\t\tif (trackingObj.get(element) === 1) {\n\t\t\ttrackingObj.delete(element)\n\t\t} else if (trackingObj.has(element)) {\n\t\t\ttrackingObj.set(element, trackingObj.get(element)! - 1)\n\t\t} else {\n\t\t\tconsole.warn('Release without capture')\n\t\t}\n\t\tconsole.warn('releasePointerCapture called on element:', element, event)\n\t}\n}\n\n/** @public */\nexport const stopEventPropagation = (e: any) => e.stopPropagation()\n\n/** @internal */\nexport const setStyleProperty = (\n\telm: HTMLElement | null,\n\tproperty: string,\n\tvalue: string | number\n) => {\n\tif (!elm) return\n\telm.style.setProperty(property, value as string)\n}\n"], +- "mappings": "AAgBA,SAAS,YAAY,oCAAoC;AAGlD,SAAS,kBAAkB,KAA2B;AAC5D,MAAI,eAAe,YAAa,QAAO;AACvC,MAAI,IAAI,cAAe,QAAO,kBAAkB,IAAI,aAAa;AAAA,MAC5D,OAAM,MAAM,kDAAkD;AACpE;AAcO,SAAS,eAAe,OAAyC;AACvE,QAAM,eAAe;AACrB,MAAI,WAAW,mBAAmB,IAAI,GAAG;AACxC,YAAQ,KAAK,mCAAmC,KAAK;AAAA,EACtD;AACD;AAGO,SAAS,kBACf,SACA,OACC;AACD,UAAQ,kBAAkB,MAAM,SAAS;AACzC,MAAI,WAAW,mBAAmB,IAAI,GAAG;AACxC,UAAM,cAAc,6BAA6B,IAAI;AACrD,gBAAY,IAAI,UAAU,YAAY,IAAI,OAAO,KAAK,KAAK,CAAC;AAC5D,YAAQ,KAAK,wCAAwC,SAAS,KAAK;AAAA,EACpE;AACD;AAGO,SAAS,sBACf,SACA,OACC;AACD,MAAI,CAAC,QAAQ,kBAAkB,MAAM,SAAS,GAAG;AAChD;AAAA,EACD;AAEA,UAAQ,sBAAsB,MAAM,SAAS;AAC7C,MAAI,WAAW,mBAAmB,IAAI,GAAG;AACxC,UAAM,cAAc,6BAA6B,IAAI;AACrD,QAAI,YAAY,IAAI,OAAO,MAAM,GAAG;AACnC,kBAAY,OAAO,OAAO;AAAA,IAC3B,WAAW,YAAY,IAAI,OAAO,GAAG;AACpC,kBAAY,IAAI,SAAS,YAAY,IAAI,OAAO,IAAK,CAAC;AAAA,IACvD,OAAO;AACN,cAAQ,KAAK,yBAAyB;AAAA,IACvC;AACA,YAAQ,KAAK,4CAA4C,SAAS,KAAK;AAAA,EACxE;AACD;AAGO,MAAM,uBAAuB,CAAC,MAAW,EAAE,gBAAgB;AAG3D,MAAM,mBAAmB,CAC/B,KACA,UACA,UACI;AACJ,MAAI,CAAC,IAAK;AACV,MAAI,MAAM,YAAY,UAAU,KAAe;AAChD;", ++ "sourcesContent": ["/*\nThis is used to facilitate double clicking and pointer capture on elements.\n\nThe events in this file are possibly set on individual SVG elements, \nsuch as handles or corner handles, rather than on HTML elements or \nSVGSVGElements. Raw SVG elemnets do not support pointerCapture in \nmost cases, meaning that in order for pointer capture to work, we \nneed to crawl up the DOM tree to find the nearest HTML element. Then,\nin order for that element to also call the `onPointerUp` event from\nthis file, we need to manually set that event on that element and\nlater remove it when the pointerup occurs. This is a potential leak\nif the user clicks on a handle but the pointerup does not fire for\nwhatever reason.\n*/\n\nimport React from 'react'\nimport { debugFlags, pointerCaptureTrackingObject } from './debug-flags'\n\ndeclare global {\n\tinterface Node {\n\t\t/**\n\t\t * Cross-window capable instanceof check, a drop-in replacement\n\t\t * for instanceof checks on DOM Nodes. Remember to also check\n\t\t * for nulls when necessary.\n\t\t *\n\t\t * #NOTE: Copied from Obsidian.md API https://github.com/obsidianmd/obsidian-api/blob/master/obsidian.d.ts\n\t\t *\n\t\t * @param type\n\t\t */\n\t\tinstanceOf(type: { new (): T }): this is T\n\t\t/**\n\t\t * The window object this node belongs to, or the global window.\n\t\t *\n\t\t * #NOTE: Copied from Obsidian.md API\n\t\t */\n\t\twin: Window\n\t}\n}\n\n/** @public */\nexport function loopToHtmlElement(elm: Element): HTMLElement {\n\tif (elm.instanceOf(HTMLElement)) return elm\n\tif (elm.parentElement) return loopToHtmlElement(elm.parentElement)\n\telse throw Error('Could not find a parent element of an HTML type!')\n}\n\n/**\n * This function calls `event.preventDefault()` for you. Why is that useful?\n *\n * Beacuase if you enable `window.preventDefaultLogging = true` it'll log out a message when it\n * happens. Because we use console.warn rather than (log) you'll get a stack trace in the inspector\n * telling you exactly where it happened. This is important because `e.preventDefault()` is the\n * source of many bugs, but unfortuantly it can't be avoided because it also stops a lot of default\n * behaviour which doesn't make sense in our UI\n *\n * @param event - To prevent default on\n * @public\n */\nexport function preventDefault(event: React.BaseSyntheticEvent | Event) {\n\tevent.preventDefault()\n\tif (debugFlags.logPreventDefaults.get()) {\n\t\tconsole.warn('preventDefault called on event:', event)\n\t}\n}\n\n/** @public */\nexport function setPointerCapture(\n\telement: Element,\n\tevent: React.PointerEvent | PointerEvent\n) {\n\telement.setPointerCapture(event.pointerId)\n\tif (debugFlags.logPointerCaptures.get()) {\n\t\tconst trackingObj = pointerCaptureTrackingObject.get()\n\t\ttrackingObj.set(element, (trackingObj.get(element) ?? 0) + 1)\n\t\tconsole.warn('setPointerCapture called on element:', element, event)\n\t}\n}\n\n/** @public */\nexport function releasePointerCapture(\n\telement: Element,\n\tevent: React.PointerEvent | PointerEvent\n) {\n\tif (!element.hasPointerCapture(event.pointerId)) {\n\t\treturn\n\t}\n\n\telement.releasePointerCapture(event.pointerId)\n\tif (debugFlags.logPointerCaptures.get()) {\n\t\tconst trackingObj = pointerCaptureTrackingObject.get()\n\t\tif (trackingObj.get(element) === 1) {\n\t\t\ttrackingObj.delete(element)\n\t\t} else if (trackingObj.has(element)) {\n\t\t\ttrackingObj.set(element, trackingObj.get(element)! - 1)\n\t\t} else {\n\t\t\tconsole.warn('Release without capture')\n\t\t}\n\t\tconsole.warn('releasePointerCapture called on element:', element, event)\n\t}\n}\n\n/** @public */\nexport const stopEventPropagation = (e: any) => e.stopPropagation()\n\n/** @internal */\nexport const setStyleProperty = (\n\telm: HTMLElement | null,\n\tproperty: string,\n\tvalue: string | number\n) => {\n\tif (!elm) return\n\telm.style.setProperty(property, value as string)\n}\n"], ++ "mappings": "AAgBA,SAAS,YAAY,oCAAoC;AAwBlD,SAAS,kBAAkB,KAA2B;AAC5D,MAAI,IAAI,WAAW,WAAW,EAAG,QAAO;AACxC,MAAI,IAAI,cAAe,QAAO,kBAAkB,IAAI,aAAa;AAAA,MAC5D,OAAM,MAAM,kDAAkD;AACpE;AAcO,SAAS,eAAe,OAAyC;AACvE,QAAM,eAAe;AACrB,MAAI,WAAW,mBAAmB,IAAI,GAAG;AACxC,YAAQ,KAAK,mCAAmC,KAAK;AAAA,EACtD;AACD;AAGO,SAAS,kBACf,SACA,OACC;AACD,UAAQ,kBAAkB,MAAM,SAAS;AACzC,MAAI,WAAW,mBAAmB,IAAI,GAAG;AACxC,UAAM,cAAc,6BAA6B,IAAI;AACrD,gBAAY,IAAI,UAAU,YAAY,IAAI,OAAO,KAAK,KAAK,CAAC;AAC5D,YAAQ,KAAK,wCAAwC,SAAS,KAAK;AAAA,EACpE;AACD;AAGO,SAAS,sBACf,SACA,OACC;AACD,MAAI,CAAC,QAAQ,kBAAkB,MAAM,SAAS,GAAG;AAChD;AAAA,EACD;AAEA,UAAQ,sBAAsB,MAAM,SAAS;AAC7C,MAAI,WAAW,mBAAmB,IAAI,GAAG;AACxC,UAAM,cAAc,6BAA6B,IAAI;AACrD,QAAI,YAAY,IAAI,OAAO,MAAM,GAAG;AACnC,kBAAY,OAAO,OAAO;AAAA,IAC3B,WAAW,YAAY,IAAI,OAAO,GAAG;AACpC,kBAAY,IAAI,SAAS,YAAY,IAAI,OAAO,IAAK,CAAC;AAAA,IACvD,OAAO;AACN,cAAQ,KAAK,yBAAyB;AAAA,IACvC;AACA,YAAQ,KAAK,4CAA4C,SAAS,KAAK;AAAA,EACxE;AACD;AAGO,MAAM,uBAAuB,CAAC,MAAW,EAAE,gBAAgB;AAG3D,MAAM,mBAAmB,CAC/B,KACA,UACA,UACI;AACJ,MAAI,CAAC,IAAK;AACV,MAAI,MAAM,YAAY,UAAU,KAAe;AAChD;", + "names": [] + } +diff --git a/node_modules/@tldraw/editor/src/lib/editor/Editor.ts b/node_modules/@tldraw/editor/src/lib/editor/Editor.ts +index 70ffdea..23a0956 100644 +--- a/node_modules/@tldraw/editor/src/lib/editor/Editor.ts ++++ b/node_modules/@tldraw/editor/src/lib/editor/Editor.ts +@@ -3217,7 +3217,7 @@ export class Editor extends EventEmitter { + * @public + */ + updateViewportScreenBounds(screenBounds: Box | HTMLElement, center = false): this { +- if (screenBounds instanceof HTMLElement) { ++ if (!(screenBounds instanceof Box)) { + const rect = screenBounds.getBoundingClientRect() + screenBounds = new Box( + rect.left || rect.x, +diff --git a/node_modules/@tldraw/editor/src/lib/hooks/useDocumentEvents.ts b/node_modules/@tldraw/editor/src/lib/hooks/useDocumentEvents.ts +index 11c0d6f..79fe15c 100644 +--- a/node_modules/@tldraw/editor/src/lib/hooks/useDocumentEvents.ts ++++ b/node_modules/@tldraw/editor/src/lib/hooks/useDocumentEvents.ts +@@ -252,9 +252,9 @@ export function useDocumentEvents() { + + container.addEventListener('wheel', handleWheel, { passive: false }) + +- document.addEventListener('gesturestart', preventDefault) +- document.addEventListener('gesturechange', preventDefault) +- document.addEventListener('gestureend', preventDefault) ++ container.ownerDocument.addEventListener('gesturestart', preventDefault) ++ container.ownerDocument.addEventListener('gesturechange', preventDefault) ++ container.ownerDocument.addEventListener('gestureend', preventDefault) + + container.addEventListener('keydown', handleKeyDown) + container.addEventListener('keyup', handleKeyUp) +@@ -264,9 +264,9 @@ export function useDocumentEvents() { + + container.removeEventListener('wheel', handleWheel) + +- document.removeEventListener('gesturestart', preventDefault) +- document.removeEventListener('gesturechange', preventDefault) +- document.removeEventListener('gestureend', preventDefault) ++ container.ownerDocument.removeEventListener('gesturestart', preventDefault) ++ container.ownerDocument.removeEventListener('gesturechange', preventDefault) ++ container.ownerDocument.removeEventListener('gestureend', preventDefault) + + container.removeEventListener('keydown', handleKeyDown) + container.removeEventListener('keyup', handleKeyUp) +diff --git a/node_modules/@tldraw/editor/src/lib/utils/dom.ts b/node_modules/@tldraw/editor/src/lib/utils/dom.ts +index 012d791..c8d534b 100644 +--- a/node_modules/@tldraw/editor/src/lib/utils/dom.ts ++++ b/node_modules/@tldraw/editor/src/lib/utils/dom.ts +@@ -16,9 +16,30 @@ whatever reason. + import React from 'react' + import { debugFlags, pointerCaptureTrackingObject } from './debug-flags' + ++declare global { ++ interface Node { ++ /** ++ * Cross-window capable instanceof check, a drop-in replacement ++ * for instanceof checks on DOM Nodes. Remember to also check ++ * for nulls when necessary. ++ * ++ * #NOTE: Copied from Obsidian.md API https://github.com/obsidianmd/obsidian-api/blob/master/obsidian.d.ts ++ * ++ * @param type ++ */ ++ instanceOf(type: { new (): T }): this is T ++ /** ++ * The window object this node belongs to, or the global window. ++ * ++ * #NOTE: Copied from Obsidian.md API ++ */ ++ win: Window ++ } ++} ++ + /** @public */ + export function loopToHtmlElement(elm: Element): HTMLElement { +- if (elm instanceof HTMLElement) return elm ++ if (elm.instanceOf(HTMLElement)) return elm + if (elm.parentElement) return loopToHtmlElement(elm.parentElement) + else throw Error('Could not find a parent element of an HTML type!') + } diff --git a/patches/tldraw+3.2.0.patch b/patches/tldraw+3.2.0.patch deleted file mode 100644 index 8e78b11..0000000 --- a/patches/tldraw+3.2.0.patch +++ /dev/null @@ -1,760 +0,0 @@ -diff --git a/node_modules/tldraw/dist-cjs/index.d.ts b/node_modules/tldraw/dist-cjs/index.d.ts -index 4ccc831..77885a5 100644 ---- a/node_modules/tldraw/dist-cjs/index.d.ts -+++ b/node_modules/tldraw/dist-cjs/index.d.ts -@@ -48,6 +48,7 @@ import { TLArrowShapeArrowheadStyle } from '@tldraw/editor'; - import { TLArrowShapeProps } from '@tldraw/editor'; - import { TLAsset } from '@tldraw/editor'; - import { TLAssetId } from '@tldraw/editor'; -+import { TLAssetStore } from '@tldraw/editor'; - import { TLBookmarkShape } from '@tldraw/editor'; - import { TLBookmarkShapeProps } from '@tldraw/editor'; - import { TLClickEventInfo } from '@tldraw/editor'; -@@ -1829,6 +1830,10 @@ export declare interface TldrawImageProps extends TLImageExportOptions { - * The license key. - */ - licenseKey?: string; -+ /** -+ * How should this store resolve assets? -+ */ -+ assets?: TLAssetStore; - /** - * Asset URL overrides. - */ -diff --git a/node_modules/tldraw/dist-cjs/lib/TldrawImage.js b/node_modules/tldraw/dist-cjs/lib/TldrawImage.js -index 0216ab8..71ae999 100644 ---- a/node_modules/tldraw/dist-cjs/lib/TldrawImage.js -+++ b/node_modules/tldraw/dist-cjs/lib/TldrawImage.js -@@ -39,7 +39,11 @@ const TldrawImage = (0, import_react.memo)(function TldrawImage2(props) { - () => [...import_defaultBindingUtils.defaultBindingUtils, ...bindingUtils], - [bindingUtils] - ); -- const store = (0, import_editor.useTLStore)({ snapshot: props.snapshot, shapeUtils: shapeUtilsWithDefaults }); -+ const store = (0, import_editor.useTLStore)({ -+ assets: props.assets, -+ snapshot: props.snapshot, -+ shapeUtils: shapeUtilsWithDefaults -+ }); - const assets = (0, import_assetUrls2.useDefaultEditorAssetsWithOverrides)(props.assetUrls); - const { done: preloadingComplete, error: preloadingError } = (0, import_usePreloadAssets.usePreloadAssets)(assets); - const { -diff --git a/node_modules/tldraw/dist-cjs/lib/TldrawImage.js.map b/node_modules/tldraw/dist-cjs/lib/TldrawImage.js.map -index a6bdb8a..083afb8 100644 ---- a/node_modules/tldraw/dist-cjs/lib/TldrawImage.js.map -+++ b/node_modules/tldraw/dist-cjs/lib/TldrawImage.js.map -@@ -1,7 +1,7 @@ - { - "version": 3, - "sources": ["../../src/lib/TldrawImage.tsx"], -- "sourcesContent": ["import {\n\tDefaultSpinner,\n\tEditor,\n\tErrorScreen,\n\tLoadingScreen,\n\tTLAnyBindingUtilConstructor,\n\tTLAnyShapeUtilConstructor,\n\tTLEditorSnapshot,\n\tTLImageExportOptions,\n\tTLPageId,\n\tTLStoreSnapshot,\n\tuseShallowArrayIdentity,\n\tuseTLStore,\n} from '@tldraw/editor'\nimport { memo, useLayoutEffect, useMemo, useState } from 'react'\nimport { defaultBindingUtils } from './defaultBindingUtils'\nimport { defaultShapeUtils } from './defaultShapeUtils'\nimport { TLUiAssetUrlOverrides } from './ui/assetUrls'\nimport { usePreloadAssets } from './ui/hooks/usePreloadAssets'\nimport { getSvgAsImage } from './utils/export/export'\nimport { useDefaultEditorAssetsWithOverrides } from './utils/static-assets/assetUrls'\n\n/** @public */\nexport interface TldrawImageProps extends TLImageExportOptions {\n\t/**\n\t * The snapshot to display.\n\t */\n\tsnapshot: Partial | TLStoreSnapshot\n\n\t/**\n\t * The image format to use. Defaults to 'svg'.\n\t */\n\tformat?: 'svg' | 'png'\n\n\t/**\n\t * The page to display. Defaults to the first page.\n\t */\n\tpageId?: TLPageId\n\n\t/**\n\t * Additional shape utils to use.\n\t */\n\tshapeUtils?: readonly TLAnyShapeUtilConstructor[]\n\t/**\n\t * Additional binding utils to use.\n\t */\n\tbindingUtils?: readonly TLAnyBindingUtilConstructor[]\n\t/**\n\t * The license key.\n\t */\n\tlicenseKey?: string\n\t/**\n\t * Asset URL overrides.\n\t */\n\tassetUrls?: TLUiAssetUrlOverrides\n}\n\n/**\n * A renderered SVG image of a Tldraw snapshot.\n *\n * @example\n * ```tsx\n * \n * ```\n *\n * @public\n * @react\n */\nexport const TldrawImage = memo(function TldrawImage(props: TldrawImageProps) {\n\tconst [url, setUrl] = useState(null)\n\tconst [container, setContainer] = useState(null)\n\n\tconst shapeUtils = useShallowArrayIdentity(props.shapeUtils ?? [])\n\tconst shapeUtilsWithDefaults = useMemo(() => [...defaultShapeUtils, ...shapeUtils], [shapeUtils])\n\tconst bindingUtils = useShallowArrayIdentity(props.bindingUtils ?? [])\n\tconst bindingUtilsWithDefaults = useMemo(\n\t\t() => [...defaultBindingUtils, ...bindingUtils],\n\t\t[bindingUtils]\n\t)\n\tconst store = useTLStore({ snapshot: props.snapshot, shapeUtils: shapeUtilsWithDefaults })\n\n\tconst assets = useDefaultEditorAssetsWithOverrides(props.assetUrls)\n\tconst { done: preloadingComplete, error: preloadingError } = usePreloadAssets(assets)\n\n\tconst {\n\t\tpageId,\n\t\tbounds,\n\t\tscale,\n\t\tbackground,\n\t\tpadding,\n\t\tdarkMode,\n\t\tpreserveAspectRatio,\n\t\tformat = 'svg',\n\t\tlicenseKey,\n\t} = props\n\n\tuseLayoutEffect(() => {\n\t\tif (!container) return\n\t\tif (!store) return\n\t\tif (!preloadingComplete) return\n\n\t\tlet isCancelled = false\n\n\t\tconst tempElm = document.createElement('div')\n\t\tcontainer.appendChild(tempElm)\n\t\tcontainer.classList.add('tl-container', 'tl-theme__light')\n\n\t\tconst editor = new Editor({\n\t\t\tstore,\n\t\t\tshapeUtils: shapeUtilsWithDefaults,\n\t\t\tbindingUtils: bindingUtilsWithDefaults,\n\t\t\ttools: [],\n\t\t\tgetContainer: () => tempElm,\n\t\t\tlicenseKey,\n\t\t})\n\n\t\tif (pageId) editor.setCurrentPage(pageId)\n\n\t\tconst shapeIds = editor.getCurrentPageShapeIds()\n\n\t\tasync function setSvg() {\n\t\t\tconst svgResult = await editor.getSvgString([...shapeIds], {\n\t\t\t\tbounds,\n\t\t\t\tscale,\n\t\t\t\tbackground,\n\t\t\t\tpadding,\n\t\t\t\tdarkMode,\n\t\t\t\tpreserveAspectRatio,\n\t\t\t})\n\n\t\t\tif (svgResult && !isCancelled) {\n\t\t\t\tif (format === 'svg') {\n\t\t\t\t\tif (!isCancelled) {\n\t\t\t\t\t\tconst blob = new Blob([svgResult.svg], { type: 'image/svg+xml' })\n\t\t\t\t\t\tconst url = URL.createObjectURL(blob)\n\t\t\t\t\t\tsetUrl(url)\n\t\t\t\t\t}\n\t\t\t\t} else if (format === 'png') {\n\t\t\t\t\tconst blob = await getSvgAsImage(editor, svgResult.svg, {\n\t\t\t\t\t\ttype: format,\n\t\t\t\t\t\tquality: 1,\n\t\t\t\t\t\tscale: 2,\n\t\t\t\t\t\twidth: svgResult.width,\n\t\t\t\t\t\theight: svgResult.height,\n\t\t\t\t\t})\n\t\t\t\t\tif (blob && !isCancelled) {\n\t\t\t\t\t\tconst url = URL.createObjectURL(blob)\n\t\t\t\t\t\tsetUrl(url)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\teditor.dispose()\n\t\t}\n\n\t\tsetSvg()\n\n\t\treturn () => {\n\t\t\tisCancelled = true\n\t\t}\n\t}, [\n\t\tformat,\n\t\tcontainer,\n\t\tstore,\n\t\tshapeUtilsWithDefaults,\n\t\tbindingUtilsWithDefaults,\n\t\tpageId,\n\t\tbounds,\n\t\tscale,\n\t\tbackground,\n\t\tpadding,\n\t\tdarkMode,\n\t\tpreserveAspectRatio,\n\t\tpreloadingComplete,\n\t\tpreloadingError,\n\t\tlicenseKey,\n\t])\n\n\tif (preloadingError) {\n\t\treturn Could not load assets.\n\t}\n\n\tif (!preloadingComplete) {\n\t\treturn (\n\t\t\t\n\t\t\t\t\n\t\t\t\n\t\t)\n\t}\n\n\treturn (\n\t\t
\n\t\t\t{url && (\n\t\t\t\t\n\t\t\t)}\n\t\t
\n\t)\n})\n"], -- "mappings": "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", -+ "sourcesContent": ["import {\n\tDefaultSpinner,\n\tEditor,\n\tErrorScreen,\n\tLoadingScreen,\n\tTLAnyBindingUtilConstructor,\n\tTLAnyShapeUtilConstructor,\n\tTLAssetStore,\n\tTLEditorSnapshot,\n\tTLImageExportOptions,\n\tTLPageId,\n\tTLStoreSnapshot,\n\tuseShallowArrayIdentity,\n\tuseTLStore,\n} from '@tldraw/editor'\nimport { memo, useLayoutEffect, useMemo, useState } from 'react'\nimport { defaultBindingUtils } from './defaultBindingUtils'\nimport { defaultShapeUtils } from './defaultShapeUtils'\nimport { TLUiAssetUrlOverrides } from './ui/assetUrls'\nimport { usePreloadAssets } from './ui/hooks/usePreloadAssets'\nimport { getSvgAsImage } from './utils/export/export'\nimport { useDefaultEditorAssetsWithOverrides } from './utils/static-assets/assetUrls'\n\n/** @public */\nexport interface TldrawImageProps extends TLImageExportOptions {\n\t/**\n\t * The snapshot to display.\n\t */\n\tsnapshot: Partial | TLStoreSnapshot\n\n\t/**\n\t * The image format to use. Defaults to 'svg'.\n\t */\n\tformat?: 'svg' | 'png'\n\n\t/**\n\t * The page to display. Defaults to the first page.\n\t */\n\tpageId?: TLPageId\n\n\t/**\n\t * Additional shape utils to use.\n\t */\n\tshapeUtils?: readonly TLAnyShapeUtilConstructor[]\n\t/**\n\t * Additional binding utils to use.\n\t */\n\tbindingUtils?: readonly TLAnyBindingUtilConstructor[]\n\t/**\n\t * The license key.\n\t */\n\tlicenseKey?: string\n\t/**\n\t * How should this store resolve assets?\n\t */\n\tassets?: TLAssetStore\n\t/**\n\t * Asset URL overrides.\n\t */\n\tassetUrls?: TLUiAssetUrlOverrides\n}\n\n/**\n * A renderered SVG image of a Tldraw snapshot.\n *\n * @example\n * ```tsx\n * \n * ```\n *\n * @public\n * @react\n */\nexport const TldrawImage = memo(function TldrawImage(props: TldrawImageProps) {\n\tconst [url, setUrl] = useState(null)\n\tconst [container, setContainer] = useState(null)\n\n\tconst shapeUtils = useShallowArrayIdentity(props.shapeUtils ?? [])\n\tconst shapeUtilsWithDefaults = useMemo(() => [...defaultShapeUtils, ...shapeUtils], [shapeUtils])\n\tconst bindingUtils = useShallowArrayIdentity(props.bindingUtils ?? [])\n\tconst bindingUtilsWithDefaults = useMemo(\n\t\t() => [...defaultBindingUtils, ...bindingUtils],\n\t\t[bindingUtils]\n\t)\n\tconst store = useTLStore({\n\t\tassets: props.assets,\n\t\tsnapshot: props.snapshot,\n\t\tshapeUtils: shapeUtilsWithDefaults,\n\t})\n\n\tconst assets = useDefaultEditorAssetsWithOverrides(props.assetUrls)\n\tconst { done: preloadingComplete, error: preloadingError } = usePreloadAssets(assets)\n\n\tconst {\n\t\tpageId,\n\t\tbounds,\n\t\tscale,\n\t\tbackground,\n\t\tpadding,\n\t\tdarkMode,\n\t\tpreserveAspectRatio,\n\t\tformat = 'svg',\n\t\tlicenseKey,\n\t} = props\n\n\tuseLayoutEffect(() => {\n\t\tif (!container) return\n\t\tif (!store) return\n\t\tif (!preloadingComplete) return\n\n\t\tlet isCancelled = false\n\n\t\tconst tempElm = document.createElement('div')\n\t\tcontainer.appendChild(tempElm)\n\t\tcontainer.classList.add('tl-container', 'tl-theme__light')\n\n\t\tconst editor = new Editor({\n\t\t\tstore,\n\t\t\tshapeUtils: shapeUtilsWithDefaults,\n\t\t\tbindingUtils: bindingUtilsWithDefaults,\n\t\t\ttools: [],\n\t\t\tgetContainer: () => tempElm,\n\t\t\tlicenseKey,\n\t\t})\n\n\t\tif (pageId) editor.setCurrentPage(pageId)\n\n\t\tconst shapeIds = editor.getCurrentPageShapeIds()\n\n\t\tasync function setSvg() {\n\t\t\tconst svgResult = await editor.getSvgString([...shapeIds], {\n\t\t\t\tbounds,\n\t\t\t\tscale,\n\t\t\t\tbackground,\n\t\t\t\tpadding,\n\t\t\t\tdarkMode,\n\t\t\t\tpreserveAspectRatio,\n\t\t\t})\n\n\t\t\tif (svgResult && !isCancelled) {\n\t\t\t\tif (format === 'svg') {\n\t\t\t\t\tif (!isCancelled) {\n\t\t\t\t\t\tconst blob = new Blob([svgResult.svg], { type: 'image/svg+xml' })\n\t\t\t\t\t\tconst url = URL.createObjectURL(blob)\n\t\t\t\t\t\tsetUrl(url)\n\t\t\t\t\t}\n\t\t\t\t} else if (format === 'png') {\n\t\t\t\t\tconst blob = await getSvgAsImage(editor, svgResult.svg, {\n\t\t\t\t\t\ttype: format,\n\t\t\t\t\t\tquality: 1,\n\t\t\t\t\t\tscale: 2,\n\t\t\t\t\t\twidth: svgResult.width,\n\t\t\t\t\t\theight: svgResult.height,\n\t\t\t\t\t})\n\t\t\t\t\tif (blob && !isCancelled) {\n\t\t\t\t\t\tconst url = URL.createObjectURL(blob)\n\t\t\t\t\t\tsetUrl(url)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\teditor.dispose()\n\t\t}\n\n\t\tsetSvg()\n\n\t\treturn () => {\n\t\t\tisCancelled = true\n\t\t}\n\t}, [\n\t\tformat,\n\t\tcontainer,\n\t\tstore,\n\t\tshapeUtilsWithDefaults,\n\t\tbindingUtilsWithDefaults,\n\t\tpageId,\n\t\tbounds,\n\t\tscale,\n\t\tbackground,\n\t\tpadding,\n\t\tdarkMode,\n\t\tpreserveAspectRatio,\n\t\tpreloadingComplete,\n\t\tpreloadingError,\n\t\tlicenseKey,\n\t])\n\n\tif (preloadingError) {\n\t\treturn Could not load assets.\n\t}\n\n\tif (!preloadingComplete) {\n\t\treturn (\n\t\t\t\n\t\t\t\t\n\t\t\t\n\t\t)\n\t}\n\n\treturn (\n\t\t
\n\t\t\t{url && (\n\t\t\t\t\n\t\t\t)}\n\t\t
\n\t)\n})\n"], -+ "mappings": "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", - "names": ["import_assetUrls", "TldrawImage", "url"] - } -diff --git a/node_modules/tldraw/dist-cjs/lib/shapes/shared/TextHelpers.js b/node_modules/tldraw/dist-cjs/lib/shapes/shared/TextHelpers.js -index e95c8e9..bd201c4 100644 ---- a/node_modules/tldraw/dist-cjs/lib/shapes/shared/TextHelpers.js -+++ b/node_modules/tldraw/dist-cjs/lib/shapes/shared/TextHelpers.js -@@ -61,7 +61,7 @@ class TextHelpers { - } - if (initialFocus === document.body) { - field.blur(); -- } else if (initialFocus instanceof HTMLElement && initialFocus !== field) { -+ } else if (initialFocus?.instanceOf(HTMLElement) && initialFocus !== field) { - initialFocus.focus(); - } - } -diff --git a/node_modules/tldraw/dist-cjs/lib/shapes/shared/TextHelpers.js.map b/node_modules/tldraw/dist-cjs/lib/shapes/shared/TextHelpers.js.map -index e8effec..bbb85f1 100644 ---- a/node_modules/tldraw/dist-cjs/lib/shapes/shared/TextHelpers.js.map -+++ b/node_modules/tldraw/dist-cjs/lib/shapes/shared/TextHelpers.js.map -@@ -1,7 +1,7 @@ - { - "version": 3, - "sources": ["../../../../src/lib/shapes/shared/TextHelpers.ts"], -- "sourcesContent": ["/*!\n * MIT License\n * Adapted (mostly copied) the work of https://github.com/fregante/text-field-edit\n * Copyright (c) Federico Brigante (bfred.it)\n */\n\n// TODO: Most of this file can be moved into a DOM utils library.\n\n/** @internal */\nexport type ReplacerCallback = (substring: string, ...args: unknown[]) => string\n\n/**\t@public */\nexport const INDENT = ' '\n\n/** @internal */\nexport class TextHelpers {\n\tstatic insertTextFirefox(field: HTMLTextAreaElement | HTMLInputElement, text: string): void {\n\t\t// Found on https://www.everythingfrontend.com/blog/insert-text-into-textarea-at-cursor-position.html \uD83C\uDF88\n\t\tfield.setRangeText(\n\t\t\ttext,\n\t\t\tfield.selectionStart || 0,\n\t\t\tfield.selectionEnd || 0,\n\t\t\t'end' // Without this, the cursor is either at the beginning or text remains selected\n\t\t)\n\n\t\tfield.dispatchEvent(\n\t\t\tnew InputEvent('input', {\n\t\t\t\tdata: text,\n\t\t\t\tinputType: 'insertText',\n\t\t\t\tisComposing: false, // TODO: fix @types/jsdom, this shouldn't be required\n\t\t\t})\n\t\t)\n\t}\n\n\t/**\n\t * Inserts text at the cursor\u2019s position, replacing any selection, with **undo** support and by\n\t * firing the input event.\n\t */\n\tstatic insert(field: HTMLTextAreaElement | HTMLInputElement, text: string): void {\n\t\tconst document = field.ownerDocument\n\t\tconst initialFocus = document.activeElement\n\t\tif (initialFocus !== field) {\n\t\t\tfield.focus()\n\t\t}\n\n\t\t// eslint-disable-next-line deprecation/deprecation\n\t\tif (!document.execCommand('insertText', false, text)) {\n\t\t\tTextHelpers.insertTextFirefox(field, text)\n\t\t}\n\n\t\tif (initialFocus === document.body) {\n\t\t\tfield.blur()\n\t\t} else if (initialFocus instanceof HTMLElement && initialFocus !== field) {\n\t\t\tinitialFocus.focus()\n\t\t}\n\t}\n\n\t/**\n\t * Replaces the entire content, equivalent to field.value = text but with **undo** support and by\n\t * firing the input event.\n\t */\n\tstatic set(field: HTMLTextAreaElement | HTMLInputElement, text: string): void {\n\t\tfield.select()\n\t\tTextHelpers.insert(field, text)\n\t}\n\n\t/** Get the selected text in a field or an empty string if nothing is selected. */\n\tstatic getSelection(field: HTMLTextAreaElement | HTMLInputElement): string {\n\t\tconst { selectionStart, selectionEnd } = field\n\t\treturn field.value.slice(\n\t\t\tselectionStart ? selectionStart : undefined,\n\t\t\tselectionEnd ? selectionEnd : undefined\n\t\t)\n\t}\n\n\t/**\n\t * Adds the wrappingText before and after field\u2019s selection (or cursor). If endWrappingText is\n\t * provided, it will be used instead of wrappingText at on the right.\n\t */\n\tstatic wrapSelection(\n\t\tfield: HTMLTextAreaElement | HTMLInputElement,\n\t\twrap: string,\n\t\twrapEnd?: string\n\t): void {\n\t\tconst { selectionStart, selectionEnd } = field\n\t\tconst selection = TextHelpers.getSelection(field)\n\t\tTextHelpers.insert(field, wrap + selection + (wrapEnd ?? wrap))\n\n\t\t// Restore the selection around the previously-selected text\n\t\tfield.selectionStart = (selectionStart || 0) + wrap.length\n\t\tfield.selectionEnd = (selectionEnd || 0) + wrap.length\n\t}\n\n\t/** Finds and replaces strings and regex in the field\u2019s value. */\n\tstatic replace(\n\t\tfield: HTMLTextAreaElement | HTMLInputElement,\n\t\tsearchValue: string | RegExp,\n\t\treplacer: string | ReplacerCallback\n\t): void {\n\t\t/** Remembers how much each match offset should be adjusted */\n\t\tlet drift = 0\n\t\tfield.value.replace(searchValue, (...args): string => {\n\t\t\t// Select current match to replace it later\n\t\t\tconst matchStart = drift + (args[args.length - 2] as number)\n\t\t\tconst matchLength = args[0].length\n\t\t\tfield.selectionStart = matchStart\n\t\t\tfield.selectionEnd = matchStart + matchLength\n\t\t\tconst replacement = typeof replacer === 'string' ? replacer : replacer(...args)\n\t\t\tTextHelpers.insert(field, replacement)\n\t\t\t// Select replacement. Without this, the cursor would be after the replacement\n\t\t\tfield.selectionStart = matchStart\n\t\t\tdrift += replacement.length - matchLength\n\t\t\treturn replacement\n\t\t})\n\t}\n\n\tstatic findLineEnd(value: string, currentEnd: number): number {\n\t\t// Go to the beginning of the last line\n\t\tconst lastLineStart = value.lastIndexOf('\\n', currentEnd - 1) + 1\n\t\t// There's nothing to unindent after the last cursor, so leave it as is\n\t\tif (value.charAt(lastLineStart) !== '\\t') {\n\t\t\treturn currentEnd\n\t\t}\n\t\treturn lastLineStart + 1 // Include the first character, which will be a tab\n\t}\n\n\tstatic indent(element: HTMLTextAreaElement): void {\n\t\tconst { selectionStart, selectionEnd, value } = element\n\t\tconst selectedContrast = value.slice(selectionStart, selectionEnd)\n\t\t// The first line should be indented, even if it starts with \\n\n\t\t// The last line should only be indented if includes any character after \\n\n\t\tconst lineBreakCount = /\\n/g.exec(selectedContrast)?.length\n\n\t\tif (lineBreakCount && lineBreakCount > 0) {\n\t\t\t// Select full first line to replace everything at once\n\t\t\tconst firstLineStart = value.lastIndexOf('\\n', selectionStart - 1) + 1\n\n\t\t\tconst newSelection = element.value.slice(firstLineStart, selectionEnd - 1)\n\t\t\tconst indentedText = newSelection.replace(\n\t\t\t\t/^|\\n/g, // Match all line starts\n\t\t\t\t`$&${INDENT}`\n\t\t\t)\n\t\t\tconst replacementsCount = indentedText.length - newSelection.length\n\n\t\t\t// Replace newSelection with indentedText\n\t\t\telement.setSelectionRange(firstLineStart, selectionEnd - 1)\n\t\t\tTextHelpers.insert(element, indentedText)\n\n\t\t\t// Restore selection position, including the indentation\n\t\t\telement.setSelectionRange(selectionStart + 1, selectionEnd + replacementsCount)\n\t\t} else {\n\t\t\tTextHelpers.insert(element, INDENT)\n\t\t}\n\t}\n\n\t// The first line should always be unindented\n\t// The last line should only be unindented if the selection includes any characters after \\n\n\tstatic unindent(element: HTMLTextAreaElement): void {\n\t\tconst { selectionStart, selectionEnd, value } = element\n\n\t\t// Select the whole first line because it might contain \\t\n\t\tconst firstLineStart = value.lastIndexOf('\\n', selectionStart - 1) + 1\n\t\tconst minimumSelectionEnd = TextHelpers.findLineEnd(value, selectionEnd)\n\n\t\tconst newSelection = element.value.slice(firstLineStart, minimumSelectionEnd)\n\t\tconst indentedText = newSelection.replace(/(^|\\n)(\\t| {1,2})/g, '$1')\n\t\tconst replacementsCount = newSelection.length - indentedText.length\n\n\t\t// Replace newSelection with indentedText\n\t\telement.setSelectionRange(firstLineStart, minimumSelectionEnd)\n\t\tTextHelpers.insert(element, indentedText)\n\n\t\t// Restore selection position, including the indentation\n\t\tconst firstLineIndentation = /\\t| {1,2}/.exec(value.slice(firstLineStart, selectionStart))\n\n\t\tconst difference = firstLineIndentation ? firstLineIndentation[0].length : 0\n\n\t\tconst newSelectionStart = selectionStart - difference\n\t\telement.setSelectionRange(\n\t\t\tselectionStart - difference,\n\t\t\tMath.max(newSelectionStart, selectionEnd - replacementsCount)\n\t\t)\n\t}\n\n\tstatic indentCE(element: HTMLElement): void {\n\t\tconst selection = window.getSelection()\n\t\tconst value = element.innerText\n\t\tconst selectionStart = getCaretIndex(element) ?? 0\n\t\tconst selectionEnd = getCaretIndex(element) ?? 0\n\t\tconst selectedContrast = value.slice(selectionStart, selectionEnd)\n\t\t// The first line should be indented, even if it starts with \\n\n\t\t// The last line should only be indented if includes any character after \\n\n\t\tconst lineBreakCount = /\\n/g.exec(selectedContrast)?.length\n\n\t\tif (lineBreakCount && lineBreakCount > 0) {\n\t\t\t// Select full first line to replace everything at once\n\t\t\tconst firstLineStart = value.lastIndexOf('\\n', selectionStart - 1) + 1\n\n\t\t\tconst newSelection = value.slice(firstLineStart, selectionEnd - 1)\n\t\t\tconst indentedText = newSelection.replace(\n\t\t\t\t/^|\\n/g, // Match all line starts\n\t\t\t\t`$&${INDENT}`\n\t\t\t)\n\t\t\tconst replacementsCount = indentedText.length - newSelection.length\n\n\t\t\t// Replace newSelection with indentedText\n\n\t\t\tif (selection) {\n\t\t\t\tselection.setBaseAndExtent(\n\t\t\t\t\telement,\n\t\t\t\t\tselectionStart + 1,\n\t\t\t\t\telement,\n\t\t\t\t\tselectionEnd + replacementsCount\n\t\t\t\t)\n\t\t\t\t// element.setSelectionRange(firstLineStart, selectionEnd - 1)\n\t\t\t\t// TextHelpers.insert(element, indentedText)\n\n\t\t\t\t// Restore selection position, including the indentation\n\t\t\t\t// element.setSelectionRange(selectionStart + 1, selectionEnd + replacementsCount)\n\t\t\t}\n\t\t} else {\n\t\t\tconst selection = window.getSelection()\n\t\t\telement.innerText = value.slice(0, selectionStart) + INDENT + value.slice(selectionStart)\n\t\t\tselection?.setBaseAndExtent(element, selectionStart + 1, element, selectionStart + 2)\n\t\t\t// TextHelpers.insert(element, INDENT)\n\t\t}\n\t}\n\n\tstatic unindentCE(element: HTMLElement): void {\n\t\tconst selection = window.getSelection()\n\t\tconst value = element.innerText\n\t\t// const { selectionStart, selectionEnd } = element\n\t\tconst selectionStart = getCaretIndex(element) ?? 0\n\t\tconst selectionEnd = getCaretIndex(element) ?? 0\n\n\t\t// Select the whole first line because it might contain \\t\n\t\tconst firstLineStart = value.lastIndexOf('\\n', selectionStart - 1) + 1\n\t\tconst minimumSelectionEnd = TextHelpers.findLineEnd(value, selectionEnd)\n\n\t\tconst newSelection = value.slice(firstLineStart, minimumSelectionEnd)\n\t\tconst indentedText = newSelection.replace(/(^|\\n)(\\t| {1,2})/g, '$1')\n\t\tconst replacementsCount = newSelection.length - indentedText.length\n\n\t\tif (selection) {\n\t\t\t// Replace newSelection with indentedText\n\t\t\tselection.setBaseAndExtent(element, firstLineStart, element, minimumSelectionEnd)\n\t\t\t// TextHelpers.insert(element, indentedText)\n\n\t\t\t// Restore selection position, including the indentation\n\t\t\tconst firstLineIndentation = /\\t| {1,2}/.exec(value.slice(firstLineStart, selectionStart))\n\n\t\t\tconst difference = firstLineIndentation ? firstLineIndentation[0].length : 0\n\n\t\t\tconst newSelectionStart = selectionStart - difference\n\t\t\tselection.setBaseAndExtent(\n\t\t\t\telement,\n\t\t\t\tselectionStart - difference,\n\t\t\t\telement,\n\t\t\t\tMath.max(newSelectionStart, selectionEnd - replacementsCount)\n\t\t\t)\n\t\t}\n\t}\n\n\tstatic fixNewLines = /\\r?\\n|\\r/g\n\n\tstatic normalizeText(text: string) {\n\t\treturn text.replace(TextHelpers.fixNewLines, '\\n')\n\t}\n\n\tstatic normalizeTextForDom(text: string) {\n\t\treturn text\n\t\t\t.replace(TextHelpers.fixNewLines, '\\n')\n\t\t\t.split('\\n')\n\t\t\t.map((x) => x || ' ')\n\t\t\t.join('\\n')\n\t}\n}\n\nfunction getCaretIndex(element: HTMLElement) {\n\tif (typeof window.getSelection === 'undefined') return\n\tconst selection = window.getSelection()\n\tif (!selection) return\n\tlet position = 0\n\tif (selection.rangeCount !== 0) {\n\t\tconst range = selection.getRangeAt(0)\n\t\tconst preCaretRange = range.cloneRange()\n\t\tpreCaretRange.selectNodeContents(element)\n\t\tpreCaretRange.setEnd(range.endContainer, range.endOffset)\n\t\tposition = preCaretRange.toString().length\n\t}\n\treturn position\n}\n"], -- "mappings": "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", -+ "sourcesContent": ["/*!\n * MIT License\n * Adapted (mostly copied) the work of https://github.com/fregante/text-field-edit\n * Copyright (c) Federico Brigante (bfred.it)\n */\n\n// TODO: Most of this file can be moved into a DOM utils library.\n\n/** @internal */\nexport type ReplacerCallback = (substring: string, ...args: unknown[]) => string\n\n/**\t@public */\nexport const INDENT = ' '\n\n/** @internal */\nexport class TextHelpers {\n\tstatic insertTextFirefox(field: HTMLTextAreaElement | HTMLInputElement, text: string): void {\n\t\t// Found on https://www.everythingfrontend.com/blog/insert-text-into-textarea-at-cursor-position.html \uD83C\uDF88\n\t\tfield.setRangeText(\n\t\t\ttext,\n\t\t\tfield.selectionStart || 0,\n\t\t\tfield.selectionEnd || 0,\n\t\t\t'end' // Without this, the cursor is either at the beginning or text remains selected\n\t\t)\n\n\t\tfield.dispatchEvent(\n\t\t\tnew InputEvent('input', {\n\t\t\t\tdata: text,\n\t\t\t\tinputType: 'insertText',\n\t\t\t\tisComposing: false, // TODO: fix @types/jsdom, this shouldn't be required\n\t\t\t})\n\t\t)\n\t}\n\n\t/**\n\t * Inserts text at the cursor\u2019s position, replacing any selection, with **undo** support and by\n\t * firing the input event.\n\t */\n\tstatic insert(field: HTMLTextAreaElement | HTMLInputElement, text: string): void {\n\t\tconst document = field.ownerDocument\n\t\tconst initialFocus = document.activeElement\n\t\tif (initialFocus !== field) {\n\t\t\tfield.focus()\n\t\t}\n\n\t\t// eslint-disable-next-line deprecation/deprecation\n\t\tif (!document.execCommand('insertText', false, text)) {\n\t\t\tTextHelpers.insertTextFirefox(field, text)\n\t\t}\n\n\t\tif (initialFocus === document.body) {\n\t\t\tfield.blur()\n\t\t} else if (initialFocus?.instanceOf(HTMLElement) && initialFocus !== field) {\n\t\t\tinitialFocus.focus()\n\t\t}\n\t}\n\n\t/**\n\t * Replaces the entire content, equivalent to field.value = text but with **undo** support and by\n\t * firing the input event.\n\t */\n\tstatic set(field: HTMLTextAreaElement | HTMLInputElement, text: string): void {\n\t\tfield.select()\n\t\tTextHelpers.insert(field, text)\n\t}\n\n\t/** Get the selected text in a field or an empty string if nothing is selected. */\n\tstatic getSelection(field: HTMLTextAreaElement | HTMLInputElement): string {\n\t\tconst { selectionStart, selectionEnd } = field\n\t\treturn field.value.slice(\n\t\t\tselectionStart ? selectionStart : undefined,\n\t\t\tselectionEnd ? selectionEnd : undefined\n\t\t)\n\t}\n\n\t/**\n\t * Adds the wrappingText before and after field\u2019s selection (or cursor). If endWrappingText is\n\t * provided, it will be used instead of wrappingText at on the right.\n\t */\n\tstatic wrapSelection(\n\t\tfield: HTMLTextAreaElement | HTMLInputElement,\n\t\twrap: string,\n\t\twrapEnd?: string\n\t): void {\n\t\tconst { selectionStart, selectionEnd } = field\n\t\tconst selection = TextHelpers.getSelection(field)\n\t\tTextHelpers.insert(field, wrap + selection + (wrapEnd ?? wrap))\n\n\t\t// Restore the selection around the previously-selected text\n\t\tfield.selectionStart = (selectionStart || 0) + wrap.length\n\t\tfield.selectionEnd = (selectionEnd || 0) + wrap.length\n\t}\n\n\t/** Finds and replaces strings and regex in the field\u2019s value. */\n\tstatic replace(\n\t\tfield: HTMLTextAreaElement | HTMLInputElement,\n\t\tsearchValue: string | RegExp,\n\t\treplacer: string | ReplacerCallback\n\t): void {\n\t\t/** Remembers how much each match offset should be adjusted */\n\t\tlet drift = 0\n\t\tfield.value.replace(searchValue, (...args): string => {\n\t\t\t// Select current match to replace it later\n\t\t\tconst matchStart = drift + (args[args.length - 2] as number)\n\t\t\tconst matchLength = args[0].length\n\t\t\tfield.selectionStart = matchStart\n\t\t\tfield.selectionEnd = matchStart + matchLength\n\t\t\tconst replacement = typeof replacer === 'string' ? replacer : replacer(...args)\n\t\t\tTextHelpers.insert(field, replacement)\n\t\t\t// Select replacement. Without this, the cursor would be after the replacement\n\t\t\tfield.selectionStart = matchStart\n\t\t\tdrift += replacement.length - matchLength\n\t\t\treturn replacement\n\t\t})\n\t}\n\n\tstatic findLineEnd(value: string, currentEnd: number): number {\n\t\t// Go to the beginning of the last line\n\t\tconst lastLineStart = value.lastIndexOf('\\n', currentEnd - 1) + 1\n\t\t// There's nothing to unindent after the last cursor, so leave it as is\n\t\tif (value.charAt(lastLineStart) !== '\\t') {\n\t\t\treturn currentEnd\n\t\t}\n\t\treturn lastLineStart + 1 // Include the first character, which will be a tab\n\t}\n\n\tstatic indent(element: HTMLTextAreaElement): void {\n\t\tconst { selectionStart, selectionEnd, value } = element\n\t\tconst selectedContrast = value.slice(selectionStart, selectionEnd)\n\t\t// The first line should be indented, even if it starts with \\n\n\t\t// The last line should only be indented if includes any character after \\n\n\t\tconst lineBreakCount = /\\n/g.exec(selectedContrast)?.length\n\n\t\tif (lineBreakCount && lineBreakCount > 0) {\n\t\t\t// Select full first line to replace everything at once\n\t\t\tconst firstLineStart = value.lastIndexOf('\\n', selectionStart - 1) + 1\n\n\t\t\tconst newSelection = element.value.slice(firstLineStart, selectionEnd - 1)\n\t\t\tconst indentedText = newSelection.replace(\n\t\t\t\t/^|\\n/g, // Match all line starts\n\t\t\t\t`$&${INDENT}`\n\t\t\t)\n\t\t\tconst replacementsCount = indentedText.length - newSelection.length\n\n\t\t\t// Replace newSelection with indentedText\n\t\t\telement.setSelectionRange(firstLineStart, selectionEnd - 1)\n\t\t\tTextHelpers.insert(element, indentedText)\n\n\t\t\t// Restore selection position, including the indentation\n\t\t\telement.setSelectionRange(selectionStart + 1, selectionEnd + replacementsCount)\n\t\t} else {\n\t\t\tTextHelpers.insert(element, INDENT)\n\t\t}\n\t}\n\n\t// The first line should always be unindented\n\t// The last line should only be unindented if the selection includes any characters after \\n\n\tstatic unindent(element: HTMLTextAreaElement): void {\n\t\tconst { selectionStart, selectionEnd, value } = element\n\n\t\t// Select the whole first line because it might contain \\t\n\t\tconst firstLineStart = value.lastIndexOf('\\n', selectionStart - 1) + 1\n\t\tconst minimumSelectionEnd = TextHelpers.findLineEnd(value, selectionEnd)\n\n\t\tconst newSelection = element.value.slice(firstLineStart, minimumSelectionEnd)\n\t\tconst indentedText = newSelection.replace(/(^|\\n)(\\t| {1,2})/g, '$1')\n\t\tconst replacementsCount = newSelection.length - indentedText.length\n\n\t\t// Replace newSelection with indentedText\n\t\telement.setSelectionRange(firstLineStart, minimumSelectionEnd)\n\t\tTextHelpers.insert(element, indentedText)\n\n\t\t// Restore selection position, including the indentation\n\t\tconst firstLineIndentation = /\\t| {1,2}/.exec(value.slice(firstLineStart, selectionStart))\n\n\t\tconst difference = firstLineIndentation ? firstLineIndentation[0].length : 0\n\n\t\tconst newSelectionStart = selectionStart - difference\n\t\telement.setSelectionRange(\n\t\t\tselectionStart - difference,\n\t\t\tMath.max(newSelectionStart, selectionEnd - replacementsCount)\n\t\t)\n\t}\n\n\tstatic indentCE(element: HTMLElement): void {\n\t\tconst selection = window.getSelection()\n\t\tconst value = element.innerText\n\t\tconst selectionStart = getCaretIndex(element) ?? 0\n\t\tconst selectionEnd = getCaretIndex(element) ?? 0\n\t\tconst selectedContrast = value.slice(selectionStart, selectionEnd)\n\t\t// The first line should be indented, even if it starts with \\n\n\t\t// The last line should only be indented if includes any character after \\n\n\t\tconst lineBreakCount = /\\n/g.exec(selectedContrast)?.length\n\n\t\tif (lineBreakCount && lineBreakCount > 0) {\n\t\t\t// Select full first line to replace everything at once\n\t\t\tconst firstLineStart = value.lastIndexOf('\\n', selectionStart - 1) + 1\n\n\t\t\tconst newSelection = value.slice(firstLineStart, selectionEnd - 1)\n\t\t\tconst indentedText = newSelection.replace(\n\t\t\t\t/^|\\n/g, // Match all line starts\n\t\t\t\t`$&${INDENT}`\n\t\t\t)\n\t\t\tconst replacementsCount = indentedText.length - newSelection.length\n\n\t\t\t// Replace newSelection with indentedText\n\n\t\t\tif (selection) {\n\t\t\t\tselection.setBaseAndExtent(\n\t\t\t\t\telement,\n\t\t\t\t\tselectionStart + 1,\n\t\t\t\t\telement,\n\t\t\t\t\tselectionEnd + replacementsCount\n\t\t\t\t)\n\t\t\t\t// element.setSelectionRange(firstLineStart, selectionEnd - 1)\n\t\t\t\t// TextHelpers.insert(element, indentedText)\n\n\t\t\t\t// Restore selection position, including the indentation\n\t\t\t\t// element.setSelectionRange(selectionStart + 1, selectionEnd + replacementsCount)\n\t\t\t}\n\t\t} else {\n\t\t\tconst selection = window.getSelection()\n\t\t\telement.innerText = value.slice(0, selectionStart) + INDENT + value.slice(selectionStart)\n\t\t\tselection?.setBaseAndExtent(element, selectionStart + 1, element, selectionStart + 2)\n\t\t\t// TextHelpers.insert(element, INDENT)\n\t\t}\n\t}\n\n\tstatic unindentCE(element: HTMLElement): void {\n\t\tconst selection = window.getSelection()\n\t\tconst value = element.innerText\n\t\t// const { selectionStart, selectionEnd } = element\n\t\tconst selectionStart = getCaretIndex(element) ?? 0\n\t\tconst selectionEnd = getCaretIndex(element) ?? 0\n\n\t\t// Select the whole first line because it might contain \\t\n\t\tconst firstLineStart = value.lastIndexOf('\\n', selectionStart - 1) + 1\n\t\tconst minimumSelectionEnd = TextHelpers.findLineEnd(value, selectionEnd)\n\n\t\tconst newSelection = value.slice(firstLineStart, minimumSelectionEnd)\n\t\tconst indentedText = newSelection.replace(/(^|\\n)(\\t| {1,2})/g, '$1')\n\t\tconst replacementsCount = newSelection.length - indentedText.length\n\n\t\tif (selection) {\n\t\t\t// Replace newSelection with indentedText\n\t\t\tselection.setBaseAndExtent(element, firstLineStart, element, minimumSelectionEnd)\n\t\t\t// TextHelpers.insert(element, indentedText)\n\n\t\t\t// Restore selection position, including the indentation\n\t\t\tconst firstLineIndentation = /\\t| {1,2}/.exec(value.slice(firstLineStart, selectionStart))\n\n\t\t\tconst difference = firstLineIndentation ? firstLineIndentation[0].length : 0\n\n\t\t\tconst newSelectionStart = selectionStart - difference\n\t\t\tselection.setBaseAndExtent(\n\t\t\t\telement,\n\t\t\t\tselectionStart - difference,\n\t\t\t\telement,\n\t\t\t\tMath.max(newSelectionStart, selectionEnd - replacementsCount)\n\t\t\t)\n\t\t}\n\t}\n\n\tstatic fixNewLines = /\\r?\\n|\\r/g\n\n\tstatic normalizeText(text: string) {\n\t\treturn text.replace(TextHelpers.fixNewLines, '\\n')\n\t}\n\n\tstatic normalizeTextForDom(text: string) {\n\t\treturn text\n\t\t\t.replace(TextHelpers.fixNewLines, '\\n')\n\t\t\t.split('\\n')\n\t\t\t.map((x) => x || ' ')\n\t\t\t.join('\\n')\n\t}\n}\n\nfunction getCaretIndex(element: HTMLElement) {\n\tif (typeof window.getSelection === 'undefined') return\n\tconst selection = window.getSelection()\n\tif (!selection) return\n\tlet position = 0\n\tif (selection.rangeCount !== 0) {\n\t\tconst range = selection.getRangeAt(0)\n\t\tconst preCaretRange = range.cloneRange()\n\t\tpreCaretRange.selectNodeContents(element)\n\t\tpreCaretRange.setEnd(range.endContainer, range.endOffset)\n\t\tposition = preCaretRange.toString().length\n\t}\n\treturn position\n}\n"], -+ "mappings": "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", - "names": ["selection"] - } -diff --git a/node_modules/tldraw/dist-cjs/lib/ui/components/Toolbar/OverflowingToolbar.js b/node_modules/tldraw/dist-cjs/lib/ui/components/Toolbar/OverflowingToolbar.js -index 4b4eade..599f457 100644 ---- a/node_modules/tldraw/dist-cjs/lib/ui/components/Toolbar/OverflowingToolbar.js -+++ b/node_modules/tldraw/dist-cjs/lib/ui/components/Toolbar/OverflowingToolbar.js -@@ -119,7 +119,7 @@ function OverflowingToolbar({ children }) { - (0, import_editor.preventDefault)(event); - const relevantEls = Array.from(mainToolsRef.current?.children ?? []).filter( - (el2) => { -- if (!(el2 instanceof HTMLElement)) return false; -+ if (!el2.instanceOf(HTMLElement)) return false; - if (el2.tagName.toLowerCase() !== "button") return false; - return !!(el2.offsetWidth || el2.offsetHeight); - } -diff --git a/node_modules/tldraw/dist-cjs/lib/ui/components/Toolbar/OverflowingToolbar.js.map b/node_modules/tldraw/dist-cjs/lib/ui/components/Toolbar/OverflowingToolbar.js.map -index c201b6b..a60064b 100644 ---- a/node_modules/tldraw/dist-cjs/lib/ui/components/Toolbar/OverflowingToolbar.js.map -+++ b/node_modules/tldraw/dist-cjs/lib/ui/components/Toolbar/OverflowingToolbar.js.map -@@ -1,7 +1,7 @@ - { - "version": 3, - "sources": ["../../../../../src/lib/ui/components/Toolbar/OverflowingToolbar.tsx"], -- "sourcesContent": ["import { preventDefault, useEditor, useEvent, useSafeId } from '@tldraw/editor'\nimport classNames from 'classnames'\nimport hotkeys from 'hotkeys-js'\nimport { createContext, useEffect, useLayoutEffect, useMemo, useRef, useState } from 'react'\nimport { PORTRAIT_BREAKPOINT } from '../../constants'\nimport { useBreakpoint } from '../../context/breakpoints'\nimport { areShortcutsDisabled } from '../../hooks/useKeyboardShortcuts'\nimport { TLUiToolItem } from '../../hooks/useTools'\nimport { useTranslation } from '../../hooks/useTranslation/useTranslation'\nimport { TldrawUiButton } from '../primitives/Button/TldrawUiButton'\nimport { TldrawUiButtonIcon } from '../primitives/Button/TldrawUiButtonIcon'\nimport {\n\tTldrawUiDropdownMenuContent,\n\tTldrawUiDropdownMenuRoot,\n\tTldrawUiDropdownMenuTrigger,\n} from '../primitives/TldrawUiDropdownMenu'\nimport { TldrawUiMenuContextProvider } from '../primitives/menus/TldrawUiMenuContext'\n\nexport const IsInOverflowContext = createContext(false)\n\n/** @public */\nexport interface OverflowingToolbarProps {\n\tchildren: React.ReactNode\n}\n\n/** @public @react */\nexport function OverflowingToolbar({ children }: OverflowingToolbarProps) {\n\tconst editor = useEditor()\n\tconst id = useSafeId()\n\tconst breakpoint = useBreakpoint()\n\tconst msg = useTranslation()\n\n\tconst overflowIndex = Math.min(8, 5 + breakpoint)\n\n\tconst [totalItems, setTotalItems] = useState(0)\n\tconst mainToolsRef = useRef(null)\n\tconst [lastActiveOverflowItem, setLastActiveOverflowItem] = useState(null)\n\n\tconst css = useMemo(() => {\n\t\tconst activeCss = lastActiveOverflowItem ? `:not([data-value=\"${lastActiveOverflowItem}\"])` : ''\n\n\t\treturn `\n\t\t\t#${id}_main > *:nth-child(n + ${overflowIndex + (lastActiveOverflowItem ? 1 : 2)})${activeCss} {\n\t\t\t\tdisplay: none;\n\t\t\t}\n\t\t\t#${id}_more > *:nth-child(-n + ${overflowIndex}) {\n\t\t\t\tdisplay: none;\n\t\t\t}\n `\n\t}, [lastActiveOverflowItem, id, overflowIndex])\n\n\tconst onDomUpdate = useEvent(() => {\n\t\tif (!mainToolsRef.current) return\n\n\t\tconst children = Array.from(mainToolsRef.current.children)\n\t\tsetTotalItems(children.length)\n\n\t\t// If the last active overflow item is no longer in the overflow, clear it\n\t\tconst lastActiveElementIdx = children.findIndex(\n\t\t\t(el) => el.getAttribute('data-value') === lastActiveOverflowItem\n\t\t)\n\t\tif (lastActiveElementIdx <= overflowIndex) {\n\t\t\tsetLastActiveOverflowItem(null)\n\t\t}\n\n\t\t// But if there's a new active item...\n\t\tconst activeElementIdx = Array.from(mainToolsRef.current.children).findIndex(\n\t\t\t(el) => el.getAttribute('aria-checked') === 'true'\n\t\t)\n\t\tif (activeElementIdx === -1) return\n\n\t\t// ...and it's in the overflow, set it as the last active overflow item\n\t\tif (activeElementIdx >= overflowIndex) {\n\t\t\tsetLastActiveOverflowItem(children[activeElementIdx].getAttribute('data-value'))\n\t\t}\n\t})\n\n\tuseLayoutEffect(() => {\n\t\tonDomUpdate()\n\t})\n\n\tuseLayoutEffect(() => {\n\t\tif (!mainToolsRef.current) return\n\n\t\tconst mutationObserver = new MutationObserver(onDomUpdate)\n\t\tmutationObserver.observe(mainToolsRef.current, {\n\t\t\tchildList: true,\n\t\t\tsubtree: true,\n\t\t\tattributeFilter: ['data-value', 'aria-checked'],\n\t\t})\n\n\t\treturn () => {\n\t\t\tmutationObserver.disconnect()\n\t\t}\n\t}, [onDomUpdate])\n\n\tuseEffect(() => {\n\t\tconst keys = [\n\t\t\t['1', 0],\n\t\t\t['2', 1],\n\t\t\t['3', 2],\n\t\t\t['4', 3],\n\t\t\t['5', 4],\n\t\t\t['6', 5],\n\t\t\t['7', 6],\n\t\t\t['8', 7],\n\t\t\t['9', 8],\n\t\t\t['0', 9],\n\t\t] as const\n\n\t\tfor (const [key, index] of keys) {\n\t\t\thotkeys(key, (event) => {\n\t\t\t\tif (areShortcutsDisabled(editor)) return\n\t\t\t\tpreventDefault(event)\n\n\t\t\t\tconst relevantEls = Array.from(mainToolsRef.current?.children ?? []).filter(\n\t\t\t\t\t(el): el is HTMLElement => {\n\t\t\t\t\t\t// only count html elements...\n\t\t\t\t\t\tif (!(el instanceof HTMLElement)) return false\n\n\t\t\t\t\t\t// ...that are buttons...\n\t\t\t\t\t\tif (el.tagName.toLowerCase() !== 'button') return false\n\n\t\t\t\t\t\t// ...that are actually visible\n\t\t\t\t\t\treturn !!(el.offsetWidth || el.offsetHeight)\n\t\t\t\t\t}\n\t\t\t\t)\n\n\t\t\t\tconst el = relevantEls[index]\n\t\t\t\tif (el) el.click()\n\t\t\t})\n\t\t}\n\n\t\treturn () => {\n\t\t\thotkeys.unbind('1,2,3,4,5,6,7,8,9,0')\n\t\t}\n\t}, [editor])\n\n\treturn (\n\t\t<>\n\t\t\t\n\t\t\t\n\t\t\t\t
\n\t\t\t\t\t\n\t\t\t\t\t\t{children}\n\t\t\t\t\t\n\t\t\t\t
\n\t\t\t\t{/* There is a +1 because if the menu is just one item, it's not necessary. */}\n\t\t\t\t{totalItems > overflowIndex + 1 && (\n\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t{children}\n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t)}\n\t\t\t\n\t\t\n\t)\n}\n\nexport const isActiveTLUiToolItem = (\n\titem: TLUiToolItem,\n\tactiveToolId: string | undefined,\n\tgeoState: string | null | undefined\n) => {\n\treturn item.meta?.geo\n\t\t? activeToolId === 'geo' && geoState === item.meta?.geo\n\t\t: activeToolId === item.id\n}\n"], -- "mappings": "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", -+ "sourcesContent": ["import { preventDefault, useEditor, useEvent, useSafeId } from '@tldraw/editor'\nimport classNames from 'classnames'\nimport hotkeys from 'hotkeys-js'\nimport { createContext, useEffect, useLayoutEffect, useMemo, useRef, useState } from 'react'\nimport { PORTRAIT_BREAKPOINT } from '../../constants'\nimport { useBreakpoint } from '../../context/breakpoints'\nimport { areShortcutsDisabled } from '../../hooks/useKeyboardShortcuts'\nimport { TLUiToolItem } from '../../hooks/useTools'\nimport { useTranslation } from '../../hooks/useTranslation/useTranslation'\nimport { TldrawUiButton } from '../primitives/Button/TldrawUiButton'\nimport { TldrawUiButtonIcon } from '../primitives/Button/TldrawUiButtonIcon'\nimport {\n\tTldrawUiDropdownMenuContent,\n\tTldrawUiDropdownMenuRoot,\n\tTldrawUiDropdownMenuTrigger,\n} from '../primitives/TldrawUiDropdownMenu'\nimport { TldrawUiMenuContextProvider } from '../primitives/menus/TldrawUiMenuContext'\n\nexport const IsInOverflowContext = createContext(false)\n\n/** @public */\nexport interface OverflowingToolbarProps {\n\tchildren: React.ReactNode\n}\n\n/** @public @react */\nexport function OverflowingToolbar({ children }: OverflowingToolbarProps) {\n\tconst editor = useEditor()\n\tconst id = useSafeId()\n\tconst breakpoint = useBreakpoint()\n\tconst msg = useTranslation()\n\n\tconst overflowIndex = Math.min(8, 5 + breakpoint)\n\n\tconst [totalItems, setTotalItems] = useState(0)\n\tconst mainToolsRef = useRef(null)\n\tconst [lastActiveOverflowItem, setLastActiveOverflowItem] = useState(null)\n\n\tconst css = useMemo(() => {\n\t\tconst activeCss = lastActiveOverflowItem ? `:not([data-value=\"${lastActiveOverflowItem}\"])` : ''\n\n\t\treturn `\n\t\t\t#${id}_main > *:nth-child(n + ${overflowIndex + (lastActiveOverflowItem ? 1 : 2)})${activeCss} {\n\t\t\t\tdisplay: none;\n\t\t\t}\n\t\t\t#${id}_more > *:nth-child(-n + ${overflowIndex}) {\n\t\t\t\tdisplay: none;\n\t\t\t}\n `\n\t}, [lastActiveOverflowItem, id, overflowIndex])\n\n\tconst onDomUpdate = useEvent(() => {\n\t\tif (!mainToolsRef.current) return\n\n\t\tconst children = Array.from(mainToolsRef.current.children)\n\t\tsetTotalItems(children.length)\n\n\t\t// If the last active overflow item is no longer in the overflow, clear it\n\t\tconst lastActiveElementIdx = children.findIndex(\n\t\t\t(el) => el.getAttribute('data-value') === lastActiveOverflowItem\n\t\t)\n\t\tif (lastActiveElementIdx <= overflowIndex) {\n\t\t\tsetLastActiveOverflowItem(null)\n\t\t}\n\n\t\t// But if there's a new active item...\n\t\tconst activeElementIdx = Array.from(mainToolsRef.current.children).findIndex(\n\t\t\t(el) => el.getAttribute('aria-checked') === 'true'\n\t\t)\n\t\tif (activeElementIdx === -1) return\n\n\t\t// ...and it's in the overflow, set it as the last active overflow item\n\t\tif (activeElementIdx >= overflowIndex) {\n\t\t\tsetLastActiveOverflowItem(children[activeElementIdx].getAttribute('data-value'))\n\t\t}\n\t})\n\n\tuseLayoutEffect(() => {\n\t\tonDomUpdate()\n\t})\n\n\tuseLayoutEffect(() => {\n\t\tif (!mainToolsRef.current) return\n\n\t\tconst mutationObserver = new MutationObserver(onDomUpdate)\n\t\tmutationObserver.observe(mainToolsRef.current, {\n\t\t\tchildList: true,\n\t\t\tsubtree: true,\n\t\t\tattributeFilter: ['data-value', 'aria-checked'],\n\t\t})\n\n\t\treturn () => {\n\t\t\tmutationObserver.disconnect()\n\t\t}\n\t}, [onDomUpdate])\n\n\tuseEffect(() => {\n\t\tconst keys = [\n\t\t\t['1', 0],\n\t\t\t['2', 1],\n\t\t\t['3', 2],\n\t\t\t['4', 3],\n\t\t\t['5', 4],\n\t\t\t['6', 5],\n\t\t\t['7', 6],\n\t\t\t['8', 7],\n\t\t\t['9', 8],\n\t\t\t['0', 9],\n\t\t] as const\n\n\t\tfor (const [key, index] of keys) {\n\t\t\thotkeys(key, (event) => {\n\t\t\t\tif (areShortcutsDisabled(editor)) return\n\t\t\t\tpreventDefault(event)\n\n\t\t\t\tconst relevantEls = Array.from(mainToolsRef.current?.children ?? []).filter(\n\t\t\t\t\t(el): el is HTMLElement => {\n\t\t\t\t\t\t// only count html elements...\n\t\t\t\t\t\tif (!(el.instanceOf(HTMLElement))) return false\n\n\t\t\t\t\t\t// ...that are buttons...\n\t\t\t\t\t\tif (el.tagName.toLowerCase() !== 'button') return false\n\n\t\t\t\t\t\t// ...that are actually visible\n\t\t\t\t\t\treturn !!(el.offsetWidth || el.offsetHeight)\n\t\t\t\t\t}\n\t\t\t\t)\n\n\t\t\t\tconst el = relevantEls[index]\n\t\t\t\tif (el) el.click()\n\t\t\t})\n\t\t}\n\n\t\treturn () => {\n\t\t\thotkeys.unbind('1,2,3,4,5,6,7,8,9,0')\n\t\t}\n\t}, [editor])\n\n\treturn (\n\t\t<>\n\t\t\t\n\t\t\t\n\t\t\t\t
\n\t\t\t\t\t\n\t\t\t\t\t\t{children}\n\t\t\t\t\t\n\t\t\t\t
\n\t\t\t\t{/* There is a +1 because if the menu is just one item, it's not necessary. */}\n\t\t\t\t{totalItems > overflowIndex + 1 && (\n\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t{children}\n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t)}\n\t\t\t\n\t\t\n\t)\n}\n\nexport const isActiveTLUiToolItem = (\n\titem: TLUiToolItem,\n\tactiveToolId: string | undefined,\n\tgeoState: string | null | undefined\n) => {\n\treturn item.meta?.geo\n\t\t? activeToolId === 'geo' && geoState === item.meta?.geo\n\t\t: activeToolId === item.id\n}\n"], -+ "mappings": "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", - "names": ["children", "hotkeys", "el", "classNames"] - } -diff --git a/node_modules/tldraw/dist-cjs/lib/ui/components/primitives/TldrawUiButtonPicker.js b/node_modules/tldraw/dist-cjs/lib/ui/components/primitives/TldrawUiButtonPicker.js -index c226800..cbfeadc 100644 ---- a/node_modules/tldraw/dist-cjs/lib/ui/components/primitives/TldrawUiButtonPicker.js -+++ b/node_modules/tldraw/dist-cjs/lib/ui/components/primitives/TldrawUiButtonPicker.js -@@ -50,6 +50,7 @@ const TldrawUiButtonPicker = (0, import_react.memo)(function TldrawUiButtonPicke - theme - } = props; - const editor = (0, import_editor.useEditor)(); -+ const container = (0, import_editor.useContainer)(); - const msg = (0, import_useTranslation.useTranslation)(); - const rPointing = (0, import_react.useRef)(false); - const rPointingOriginalActiveElement = (0, import_react.useRef)(null); -@@ -61,7 +62,7 @@ const TldrawUiButtonPicker = (0, import_react.memo)(function TldrawUiButtonPicke - } = (0, import_react.useMemo)(() => { - const handlePointerUp = () => { - rPointing.current = false; -- window.removeEventListener("pointerup", handlePointerUp); -+ container.win.removeEventListener("pointerup", handlePointerUp); - const origActiveEl = rPointingOriginalActiveElement.current; - if (origActiveEl && ["TEXTAREA", "INPUT"].includes(origActiveEl.nodeName)) { - origActiveEl.focus(); -@@ -79,8 +80,8 @@ const TldrawUiButtonPicker = (0, import_react.memo)(function TldrawUiButtonPicke - editor.markHistoryStoppingPoint("point picker item"); - onValueChange(style, id); - rPointing.current = true; -- rPointingOriginalActiveElement.current = document.activeElement; -- window.addEventListener("pointerup", handlePointerUp); -+ rPointingOriginalActiveElement.current = container.ownerDocument.activeElement; -+ container.win.addEventListener("pointerup", handlePointerUp); - }; - const handleButtonPointerEnter2 = (e) => { - if (!rPointing.current) return; -@@ -98,7 +99,7 @@ const TldrawUiButtonPicker = (0, import_react.memo)(function TldrawUiButtonPicke - handleButtonPointerEnter: handleButtonPointerEnter2, - handleButtonPointerUp: handleButtonPointerUp2 - }; -- }, [value, editor, onValueChange, style]); -+ }, [value, editor, onValueChange, style, container]); - return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { "data-testid": `style.${uiType}`, className: (0, import_classnames.default)("tlui-buttons__grid"), children: items.map((item) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)( - import_TldrawUiButton.TldrawUiButton, - { -diff --git a/node_modules/tldraw/dist-cjs/lib/ui/components/primitives/TldrawUiButtonPicker.js.map b/node_modules/tldraw/dist-cjs/lib/ui/components/primitives/TldrawUiButtonPicker.js.map -index c8c88f7..439b1a2 100644 ---- a/node_modules/tldraw/dist-cjs/lib/ui/components/primitives/TldrawUiButtonPicker.js.map -+++ b/node_modules/tldraw/dist-cjs/lib/ui/components/primitives/TldrawUiButtonPicker.js.map -@@ -1,7 +1,7 @@ - { - "version": 3, - "sources": ["../../../../../src/lib/ui/components/primitives/TldrawUiButtonPicker.tsx"], -- "sourcesContent": ["import {\n\tDefaultColorStyle,\n\tSharedStyle,\n\tStyleProp,\n\tTLDefaultColorStyle,\n\tTLDefaultColorTheme,\n\tuseEditor,\n} from '@tldraw/editor'\nimport classNames from 'classnames'\nimport { ReactElement, memo, useMemo, useRef } from 'react'\nimport { StyleValuesForUi } from '../../../styles'\nimport { TLUiTranslationKey } from '../../hooks/useTranslation/TLUiTranslationKey'\nimport { useTranslation } from '../../hooks/useTranslation/useTranslation'\nimport { TldrawUiButton } from './Button/TldrawUiButton'\nimport { TldrawUiButtonIcon } from './Button/TldrawUiButtonIcon'\n\n/** @public */\nexport interface TLUiButtonPickerProps {\n\ttitle: string\n\tuiType: string\n\tstyle: StyleProp\n\tvalue: SharedStyle\n\titems: StyleValuesForUi\n\ttheme: TLDefaultColorTheme\n\tonValueChange(style: StyleProp, value: T): void\n}\n\n/** @public */\nexport const TldrawUiButtonPicker = memo(function TldrawUiButtonPicker(\n\tprops: TLUiButtonPickerProps\n) {\n\tconst {\n\t\tuiType,\n\t\titems,\n\t\ttitle,\n\t\tstyle,\n\t\tvalue,\n\t\t// columns = clamp(items.length, 2, 4),\n\t\tonValueChange,\n\t\ttheme,\n\t} = props\n\tconst editor = useEditor()\n\tconst msg = useTranslation()\n\n\tconst rPointing = useRef(false)\n\tconst rPointingOriginalActiveElement = useRef(null)\n\n\tconst {\n\t\thandleButtonClick,\n\t\thandleButtonPointerDown,\n\t\thandleButtonPointerEnter,\n\t\thandleButtonPointerUp,\n\t} = useMemo(() => {\n\t\tconst handlePointerUp = () => {\n\t\t\trPointing.current = false\n\t\t\twindow.removeEventListener('pointerup', handlePointerUp)\n\n\t\t\t// This is fun little micro-optimization to make sure that the focus\n\t\t\t// is retained on a text label. That way, you can continue typing\n\t\t\t// after selecting a style.\n\t\t\tconst origActiveEl = rPointingOriginalActiveElement.current\n\t\t\tif (origActiveEl && ['TEXTAREA', 'INPUT'].includes(origActiveEl.nodeName)) {\n\t\t\t\torigActiveEl.focus()\n\t\t\t}\n\t\t\trPointingOriginalActiveElement.current = null\n\t\t}\n\n\t\tconst handleButtonClick = (e: React.PointerEvent) => {\n\t\t\tconst { id } = e.currentTarget.dataset\n\t\t\tif (value.type === 'shared' && value.value === id) return\n\n\t\t\teditor.markHistoryStoppingPoint('point picker item')\n\t\t\tonValueChange(style, id as T)\n\t\t}\n\n\t\tconst handleButtonPointerDown = (e: React.PointerEvent) => {\n\t\t\tconst { id } = e.currentTarget.dataset\n\n\t\t\teditor.markHistoryStoppingPoint('point picker item')\n\t\t\tonValueChange(style, id as T)\n\n\t\t\trPointing.current = true\n\t\t\trPointingOriginalActiveElement.current = document.activeElement as HTMLElement\n\t\t\twindow.addEventListener('pointerup', handlePointerUp) // see TLD-658\n\t\t}\n\n\t\tconst handleButtonPointerEnter = (e: React.PointerEvent) => {\n\t\t\tif (!rPointing.current) return\n\n\t\t\tconst { id } = e.currentTarget.dataset\n\t\t\tonValueChange(style, id as T)\n\t\t}\n\n\t\tconst handleButtonPointerUp = (e: React.PointerEvent) => {\n\t\t\tconst { id } = e.currentTarget.dataset\n\t\t\tif (value.type === 'shared' && value.value === id) return\n\n\t\t\tonValueChange(style, id as T)\n\t\t}\n\n\t\treturn {\n\t\t\thandleButtonClick,\n\t\t\thandleButtonPointerDown,\n\t\t\thandleButtonPointerEnter,\n\t\t\thandleButtonPointerUp,\n\t\t}\n\t}, [value, editor, onValueChange, style])\n\n\treturn (\n\t\t
\n\t\t\t{items.map((item) => (\n\t\t\t\t)\n\t\t\t\t\t\t\t? { color: theme[item.value as TLDefaultColorStyle].solid }\n\t\t\t\t\t\t\t: undefined\n\t\t\t\t\t}\n\t\t\t\t\tonPointerEnter={handleButtonPointerEnter}\n\t\t\t\t\tonPointerDown={handleButtonPointerDown}\n\t\t\t\t\tonPointerUp={handleButtonPointerUp}\n\t\t\t\t\tonClick={handleButtonClick}\n\t\t\t\t>\n\t\t\t\t\t\n\t\t\t\t\n\t\t\t))}\n\t\t
\n\t)\n}) as (props: TLUiButtonPickerProps) => ReactElement\n"], -- "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAkIK;AAlIL,oBAOO;AACP,wBAAuB;AACvB,mBAAoD;AAGpD,4BAA+B;AAC/B,4BAA+B;AAC/B,gCAAmC;AAc5B,MAAM,2BAAuB,mBAAK,SAASA,sBACjD,OACC;AACD,QAAM;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA;AAAA,IAEA;AAAA,IACA;AAAA,EACD,IAAI;AACJ,QAAM,aAAS,yBAAU;AACzB,QAAM,UAAM,sCAAe;AAE3B,QAAM,gBAAY,qBAAO,KAAK;AAC9B,QAAM,qCAAiC,qBAA2B,IAAI;AAEtE,QAAM;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACD,QAAI,sBAAQ,MAAM;AACjB,UAAM,kBAAkB,MAAM;AAC7B,gBAAU,UAAU;AACpB,aAAO,oBAAoB,aAAa,eAAe;AAKvD,YAAM,eAAe,+BAA+B;AACpD,UAAI,gBAAgB,CAAC,YAAY,OAAO,EAAE,SAAS,aAAa,QAAQ,GAAG;AAC1E,qBAAa,MAAM;AAAA,MACpB;AACA,qCAA+B,UAAU;AAAA,IAC1C;AAEA,UAAMC,qBAAoB,CAAC,MAA6C;AACvE,YAAM,EAAE,GAAG,IAAI,EAAE,cAAc;AAC/B,UAAI,MAAM,SAAS,YAAY,MAAM,UAAU,GAAI;AAEnD,aAAO,yBAAyB,mBAAmB;AACnD,oBAAc,OAAO,EAAO;AAAA,IAC7B;AAEA,UAAMC,2BAA0B,CAAC,MAA6C;AAC7E,YAAM,EAAE,GAAG,IAAI,EAAE,cAAc;AAE/B,aAAO,yBAAyB,mBAAmB;AACnD,oBAAc,OAAO,EAAO;AAE5B,gBAAU,UAAU;AACpB,qCAA+B,UAAU,SAAS;AAClD,aAAO,iBAAiB,aAAa,eAAe;AAAA,IACrD;AAEA,UAAMC,4BAA2B,CAAC,MAA6C;AAC9E,UAAI,CAAC,UAAU,QAAS;AAExB,YAAM,EAAE,GAAG,IAAI,EAAE,cAAc;AAC/B,oBAAc,OAAO,EAAO;AAAA,IAC7B;AAEA,UAAMC,yBAAwB,CAAC,MAA6C;AAC3E,YAAM,EAAE,GAAG,IAAI,EAAE,cAAc;AAC/B,UAAI,MAAM,SAAS,YAAY,MAAM,UAAU,GAAI;AAEnD,oBAAc,OAAO,EAAO;AAAA,IAC7B;AAEA,WAAO;AAAA,MACN,mBAAAH;AAAA,MACA,yBAAAC;AAAA,MACA,0BAAAC;AAAA,MACA,uBAAAC;AAAA,IACD;AAAA,EACD,GAAG,CAAC,OAAO,QAAQ,eAAe,KAAK,CAAC;AAExC,SACC,4CAAC,SAAI,eAAa,SAAS,MAAM,IAAI,eAAW,kBAAAC,SAAW,oBAAoB,GAC7E,gBAAM,IAAI,CAAC,SACX;AAAA,IAAC;AAAA;AAAA,MACA,MAAK;AAAA,MAEL,WAAS,KAAK;AAAA,MACd,eAAa,SAAS,MAAM,IAAI,KAAK,KAAK;AAAA,MAC1C,cAAY,KAAK;AAAA,MACjB,cAAY,MAAM,SAAS,YAAY,MAAM,UAAU,KAAK,QAAQ,WAAW;AAAA,MAC/E,OAAO,QAAQ,aAAQ,IAAI,GAAG,MAAM,UAAU,KAAK,KAAK,EAAwB;AAAA,MAChF,eAAW,kBAAAA,SAAW,0BAA0B;AAAA,MAChD,OACC,UAAW,kCACR,EAAE,OAAO,MAAM,KAAK,KAA4B,EAAE,MAAM,IACxD;AAAA,MAEJ,gBAAgB;AAAA,MAChB,eAAe;AAAA,MACf,aAAa;AAAA,MACb,SAAS;AAAA,MAET,sDAAC,gDAAmB,MAAM,KAAK,MAAM;AAAA;AAAA,IAjBhC,KAAK;AAAA,EAkBX,CACA,GACF;AAEF,CAAC;", -+ "sourcesContent": ["import {\n\tDefaultColorStyle,\n\tSharedStyle,\n\tStyleProp,\n\tTLDefaultColorStyle,\n\tTLDefaultColorTheme,\n\tuseContainer,\n\tuseEditor,\n} from '@tldraw/editor'\nimport classNames from 'classnames'\nimport { ReactElement, memo, useMemo, useRef } from 'react'\nimport { StyleValuesForUi } from '../../../styles'\nimport { TLUiTranslationKey } from '../../hooks/useTranslation/TLUiTranslationKey'\nimport { useTranslation } from '../../hooks/useTranslation/useTranslation'\nimport { TldrawUiButton } from './Button/TldrawUiButton'\nimport { TldrawUiButtonIcon } from './Button/TldrawUiButtonIcon'\n\n/** @public */\nexport interface TLUiButtonPickerProps {\n\ttitle: string\n\tuiType: string\n\tstyle: StyleProp\n\tvalue: SharedStyle\n\titems: StyleValuesForUi\n\ttheme: TLDefaultColorTheme\n\tonValueChange(style: StyleProp, value: T): void\n}\n\n/** @public */\nexport const TldrawUiButtonPicker = memo(function TldrawUiButtonPicker(\n\tprops: TLUiButtonPickerProps\n) {\n\tconst {\n\t\tuiType,\n\t\titems,\n\t\ttitle,\n\t\tstyle,\n\t\tvalue,\n\t\t// columns = clamp(items.length, 2, 4),\n\t\tonValueChange,\n\t\ttheme,\n\t} = props\n\tconst editor = useEditor();\n\tconst container = useContainer();\n\tconst msg = useTranslation()\n\n\tconst rPointing = useRef(false)\n\tconst rPointingOriginalActiveElement = useRef(null)\n\n\tconst {\n\t\thandleButtonClick,\n\t\thandleButtonPointerDown,\n\t\thandleButtonPointerEnter,\n\t\thandleButtonPointerUp,\n\t} = useMemo(() => {\n\t\tconst handlePointerUp = () => {\n\t\t\trPointing.current = false\n\t\t\tcontainer.win.removeEventListener('pointerup', handlePointerUp)\n\n\t\t\t// This is fun little micro-optimization to make sure that the focus\n\t\t\t// is retained on a text label. That way, you can continue typing\n\t\t\t// after selecting a style.\n\t\t\tconst origActiveEl = rPointingOriginalActiveElement.current\n\t\t\tif (origActiveEl && ['TEXTAREA', 'INPUT'].includes(origActiveEl.nodeName)) {\n\t\t\t\torigActiveEl.focus()\n\t\t\t}\n\t\t\trPointingOriginalActiveElement.current = null\n\t\t}\n\n\t\tconst handleButtonClick = (e: React.PointerEvent) => {\n\t\t\tconst { id } = e.currentTarget.dataset\n\t\t\tif (value.type === 'shared' && value.value === id) return\n\n\t\t\teditor.markHistoryStoppingPoint('point picker item')\n\t\t\tonValueChange(style, id as T)\n\t\t}\n\n\t\tconst handleButtonPointerDown = (e: React.PointerEvent) => {\n\t\t\tconst { id } = e.currentTarget.dataset\n\n\t\t\teditor.markHistoryStoppingPoint('point picker item')\n\t\t\tonValueChange(style, id as T)\n\n\t\t\trPointing.current = true\n\t\t\trPointingOriginalActiveElement.current = container.ownerDocument.activeElement as HTMLElement\n\t\t\tcontainer.win.addEventListener('pointerup', handlePointerUp) // see TLD-658\n\t\t}\n\n\t\tconst handleButtonPointerEnter = (e: React.PointerEvent) => {\n\t\t\tif (!rPointing.current) return\n\n\t\t\tconst { id } = e.currentTarget.dataset\n\t\t\tonValueChange(style, id as T)\n\t\t}\n\n\t\tconst handleButtonPointerUp = (e: React.PointerEvent) => {\n\t\t\tconst { id } = e.currentTarget.dataset\n\t\t\tif (value.type === 'shared' && value.value === id) return\n\n\t\t\tonValueChange(style, id as T)\n\t\t}\n\n\t\treturn {\n\t\t\thandleButtonClick,\n\t\t\thandleButtonPointerDown,\n\t\t\thandleButtonPointerEnter,\n\t\t\thandleButtonPointerUp,\n\t\t}\n\t}, [value, editor, onValueChange, style, container])\n\n\treturn (\n\t\t
\n\t\t\t{items.map((item) => (\n\t\t\t\t)\n\t\t\t\t\t\t\t? { color: theme[item.value as TLDefaultColorStyle].solid }\n\t\t\t\t\t\t\t: undefined\n\t\t\t\t\t}\n\t\t\t\t\tonPointerEnter={handleButtonPointerEnter}\n\t\t\t\t\tonPointerDown={handleButtonPointerDown}\n\t\t\t\t\tonPointerUp={handleButtonPointerUp}\n\t\t\t\t\tonClick={handleButtonClick}\n\t\t\t\t>\n\t\t\t\t\t\n\t\t\t\t\n\t\t\t))}\n\t\t
\n\t)\n}) as (props: TLUiButtonPickerProps) => ReactElement\n"], -+ "mappings": "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", - "names": ["TldrawUiButtonPicker", "handleButtonClick", "handleButtonPointerDown", "handleButtonPointerEnter", "handleButtonPointerUp", "classNames"] - } -diff --git a/node_modules/tldraw/dist-cjs/lib/ui/hooks/useClipboardEvents.js b/node_modules/tldraw/dist-cjs/lib/ui/hooks/useClipboardEvents.js -index 9b58cc0..3bfbc5e 100644 ---- a/node_modules/tldraw/dist-cjs/lib/ui/hooks/useClipboardEvents.js -+++ b/node_modules/tldraw/dist-cjs/lib/ui/hooks/useClipboardEvents.js -@@ -396,6 +396,7 @@ function useMenuClipboardEvents() { - }; - } - function useNativeClipboardEvents() { -+ const container = (0, import_editor.useContainer)(); - const editor = (0, import_editor.useEditor)(); - const trackEvent = (0, import_events.useUiEvents)(); - const appIsFocused = (0, import_editor.useValue)("editor.isFocused", () => editor.getInstanceState().isFocused, [ -@@ -452,16 +453,16 @@ function useNativeClipboardEvents() { - (0, import_editor.preventDefault)(e); - trackEvent("paste", { source: "kbd" }); - }; -- document.addEventListener("copy", copy); -- document.addEventListener("cut", cut); -- document.addEventListener("paste", paste); -- document.addEventListener("pointerup", pointerUpHandler); -+ container.ownerDocument.addEventListener("copy", copy); -+ container.ownerDocument.addEventListener("cut", cut); -+ container.ownerDocument.addEventListener("paste", paste); -+ container.ownerDocument.addEventListener("pointerup", pointerUpHandler); - return () => { -- document.removeEventListener("copy", copy); -- document.removeEventListener("cut", cut); -- document.removeEventListener("paste", paste); -- document.removeEventListener("pointerup", pointerUpHandler); -+ container.ownerDocument.removeEventListener("copy", copy); -+ container.ownerDocument.removeEventListener("cut", cut); -+ container.ownerDocument.removeEventListener("paste", paste); -+ container.ownerDocument.removeEventListener("pointerup", pointerUpHandler); - }; -- }, [editor, trackEvent, appIsFocused]); -+ }, [editor, trackEvent, appIsFocused, container]); - } - //# sourceMappingURL=useClipboardEvents.js.map -diff --git a/node_modules/tldraw/dist-cjs/lib/ui/hooks/useClipboardEvents.js.map b/node_modules/tldraw/dist-cjs/lib/ui/hooks/useClipboardEvents.js.map -index ed373c3..617e182 100644 ---- a/node_modules/tldraw/dist-cjs/lib/ui/hooks/useClipboardEvents.js.map -+++ b/node_modules/tldraw/dist-cjs/lib/ui/hooks/useClipboardEvents.js.map -@@ -1,7 +1,7 @@ - { - "version": 3, - "sources": ["../../../../src/lib/ui/hooks/useClipboardEvents.ts"], -- "sourcesContent": ["import {\n\tEditor,\n\tFileHelpers,\n\tTLExternalContentSource,\n\tVec,\n\tVecLike,\n\tisDefined,\n\tpreventDefault,\n\tstopEventPropagation,\n\tuniq,\n\tuseEditor,\n\tuseValue,\n} from '@tldraw/editor'\nimport lz from 'lz-string'\nimport { useCallback, useEffect } from 'react'\nimport { TLUiEventSource, useUiEvents } from '../context/events'\nimport { pasteExcalidrawContent } from './clipboard/pasteExcalidrawContent'\nimport { pasteFiles } from './clipboard/pasteFiles'\nimport { pasteTldrawContent } from './clipboard/pasteTldrawContent'\nimport { pasteUrl } from './clipboard/pasteUrl'\n\n/**\n * Strip HTML tags from a string.\n * @param html - The HTML to strip.\n * @internal\n */\nfunction stripHtml(html: string) {\n\t// See \n\tconst doc = document.implementation.createHTMLDocument('')\n\tdoc.documentElement.innerHTML = html.trim()\n\treturn doc.body.textContent || doc.body.innerText || ''\n}\n\n/** @public */\nexport const isValidHttpURL = (url: string) => {\n\ttry {\n\t\tconst u = new URL(url)\n\t\treturn u.protocol === 'http:' || u.protocol === 'https:'\n\t} catch (e) {\n\t\treturn false\n\t}\n}\n\n/** @public */\nconst getValidHttpURLList = (url: string) => {\n\tconst urls = url.split(/[\\n\\s]/)\n\tfor (const url of urls) {\n\t\ttry {\n\t\t\tconst u = new URL(url)\n\t\t\tif (!(u.protocol === 'http:' || u.protocol === 'https:')) {\n\t\t\t\treturn\n\t\t\t}\n\t\t} catch (e) {\n\t\t\treturn\n\t\t}\n\t}\n\treturn uniq(urls)\n}\n\n/** @public */\nconst isSvgText = (text: string) => {\n\treturn /^ -1))\n\t)\n}\n\n/**\n * Whether a ClipboardItem is a file.\n * @param item - The ClipboardItem to check.\n * @internal\n */\nconst isFile = (item: ClipboardItem) => {\n\treturn item.types.find((i) => i.match(/^image\\//))\n}\n\n/**\n * Handle text pasted into the editor.\n * @param editor - The editor instance.\n * @param data - The text to paste.\n * @param point - The point at which to paste the text.\n * @internal\n */\nconst handleText = (\n\teditor: Editor,\n\tdata: string,\n\tpoint?: VecLike,\n\tsources?: TLExternalContentSource[]\n) => {\n\tconst validUrlList = getValidHttpURLList(data)\n\tif (validUrlList) {\n\t\tfor (const url of validUrlList) {\n\t\t\tpasteUrl(editor, url, point)\n\t\t}\n\t} else if (isValidHttpURL(data)) {\n\t\tpasteUrl(editor, data, point)\n\t} else if (isSvgText(data)) {\n\t\teditor.markHistoryStoppingPoint('paste')\n\t\teditor.putExternalContent({\n\t\t\ttype: 'svg-text',\n\t\t\ttext: data,\n\t\t\tpoint,\n\t\t\tsources,\n\t\t})\n\t} else {\n\t\teditor.markHistoryStoppingPoint('paste')\n\t\teditor.putExternalContent({\n\t\t\ttype: 'text',\n\t\t\ttext: data,\n\t\t\tpoint,\n\t\t\tsources,\n\t\t})\n\t}\n}\n\n/**\n * Something found on the clipboard, either through the event's clipboard data or the browser's clipboard API.\n * @internal\n */\ntype ClipboardThing =\n\t| {\n\t\t\ttype: 'file'\n\t\t\tsource: Promise\n\t }\n\t| {\n\t\t\ttype: 'blob'\n\t\t\tsource: Promise\n\t }\n\t| {\n\t\t\ttype: 'url'\n\t\t\tsource: Promise\n\t }\n\t| {\n\t\t\ttype: 'html'\n\t\t\tsource: Promise\n\t }\n\t| {\n\t\t\ttype: 'text'\n\t\t\tsource: Promise\n\t }\n\t| {\n\t\t\ttype: string\n\t\t\tsource: Promise\n\t }\n\n/**\n * Handle a paste using event clipboard data. This is the \"original\"\n * paste method that uses the clipboard data from the paste event.\n * https://developer.mozilla.org/en-US/docs/Web/API/ClipboardEvent/clipboardData\n *\n * @param editor - The editor\n * @param clipboardData - The clipboard data\n * @param point - The point to paste at\n * @internal\n */\nconst handlePasteFromEventClipboardData = async (\n\teditor: Editor,\n\tclipboardData: DataTransfer,\n\tpoint?: VecLike\n) => {\n\t// Do not paste while in any editing state\n\tif (editor.getEditingShapeId() !== null) return\n\n\tif (!clipboardData) {\n\t\tthrow Error('No clipboard data')\n\t}\n\n\tconst things: ClipboardThing[] = []\n\n\tfor (const item of Object.values(clipboardData.items)) {\n\t\tswitch (item.kind) {\n\t\t\tcase 'file': {\n\t\t\t\t// files are always blobs\n\t\t\t\tthings.push({\n\t\t\t\t\ttype: 'file',\n\t\t\t\t\tsource: new Promise((r) => r(item.getAsFile())) as Promise,\n\t\t\t\t})\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'string': {\n\t\t\t\t// strings can be text or html\n\t\t\t\tif (item.type === 'text/html') {\n\t\t\t\t\tthings.push({\n\t\t\t\t\t\ttype: 'html',\n\t\t\t\t\t\tsource: new Promise((r) => item.getAsString(r)) as Promise,\n\t\t\t\t\t})\n\t\t\t\t} else if (item.type === 'text/plain') {\n\t\t\t\t\tthings.push({\n\t\t\t\t\t\ttype: 'text',\n\t\t\t\t\t\tsource: new Promise((r) => item.getAsString(r)) as Promise,\n\t\t\t\t\t})\n\t\t\t\t} else {\n\t\t\t\t\tthings.push({ type: item.type, source: new Promise((r) => item.getAsString(r)) })\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n\n\thandleClipboardThings(editor, things, point)\n}\n\n/**\n * Handle a paste using items retrieved from the Clipboard API.\n * https://developer.mozilla.org/en-US/docs/Web/API/ClipboardItem\n *\n * @param editor - The editor\n * @param clipboardItems - The clipboard items to handle\n * @param point - The point to paste at\n * @internal\n */\nconst handlePasteFromClipboardApi = async (\n\teditor: Editor,\n\tclipboardItems: ClipboardItem[],\n\tpoint?: VecLike\n) => {\n\t// We need to populate the array of clipboard things\n\t// based on the ClipboardItems from the Clipboard API.\n\t// This is done in a different way than when using\n\t// the clipboard data from the paste event.\n\n\tconst things: ClipboardThing[] = []\n\n\tfor (const item of clipboardItems) {\n\t\tif (isFile(item)) {\n\t\t\tfor (const type of item.types) {\n\t\t\t\tif (type.match(/^image\\//)) {\n\t\t\t\t\tthings.push({ type: 'blob', source: item.getType(type) })\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (item.types.includes('text/html')) {\n\t\t\tthings.push({\n\t\t\t\ttype: 'html',\n\t\t\t\tsource: (async () => {\n\t\t\t\t\tconst blob = await item.getType('text/html')\n\t\t\t\t\treturn await FileHelpers.blobToText(blob)\n\t\t\t\t})(),\n\t\t\t})\n\t\t}\n\n\t\tif (item.types.includes('text/uri-list')) {\n\t\t\tthings.push({\n\t\t\t\ttype: 'url',\n\t\t\t\tsource: (async () => {\n\t\t\t\t\tconst blob = await item.getType('text/uri-list')\n\t\t\t\t\treturn await FileHelpers.blobToText(blob)\n\t\t\t\t})(),\n\t\t\t})\n\t\t}\n\n\t\tif (item.types.includes('text/plain')) {\n\t\t\tthings.push({\n\t\t\t\ttype: 'text',\n\t\t\t\tsource: (async () => {\n\t\t\t\t\tconst blob = await item.getType('text/plain')\n\t\t\t\t\treturn await FileHelpers.blobToText(blob)\n\t\t\t\t})(),\n\t\t\t})\n\t\t}\n\t}\n\n\treturn await handleClipboardThings(editor, things, point)\n}\n\nasync function handleClipboardThings(editor: Editor, things: ClipboardThing[], point?: VecLike) {\n\t// 1. Handle files\n\t//\n\t// We need to handle files separately because if we want them to\n\t// be placed next to each other, we need to create them all at once.\n\n\tconst files = things.filter(\n\t\t(t) => (t.type === 'file' || t.type === 'blob') && t.source !== null\n\t) as Extract[]\n\n\t// Just paste the files, nothing else\n\tif (files.length) {\n\t\tif (files.length > editor.options.maxFilesAtOnce) {\n\t\t\tthrow Error('Too many files')\n\t\t}\n\t\tconst fileBlobs = await Promise.all(files.map((t) => t.source!))\n\t\tconst urls = (fileBlobs.filter(Boolean) as (File | Blob)[]).map((blob) =>\n\t\t\tURL.createObjectURL(blob)\n\t\t)\n\t\treturn await pasteFiles(editor, urls, point)\n\t}\n\n\t// 2. Generate clipboard results for non-file things\n\t//\n\t// Getting the source from the items is async, however they must be accessed syncronously;\n\t// we can't await them in a loop. So we'll map them to promises and await them all at once,\n\t// then make decisions based on what we find.\n\n\tconst results = await Promise.all(\n\t\tthings\n\t\t\t.filter((t) => t.type !== 'file')\n\t\t\t.map(\n\t\t\t\t(t) =>\n\t\t\t\t\tnew Promise((r) => {\n\t\t\t\t\t\tconst thing = t as Exclude\n\n\t\t\t\t\t\tif (thing.type === 'file') {\n\t\t\t\t\t\t\tr({ type: 'error', data: null, reason: 'unexpected file' })\n\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tthing.source.then((text) => {\n\t\t\t\t\t\t\t// first, see if we can find tldraw content, which is JSON inside of an html comment\n\t\t\t\t\t\t\tconst tldrawHtmlComment = text.match(/
]*>(.*)<\\/div>/)?.[1]\n\n\t\t\t\t\t\t\tif (tldrawHtmlComment) {\n\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\t// If we've found tldraw content in the html string, use that as JSON\n\t\t\t\t\t\t\t\t\tconst jsonComment = lz.decompressFromBase64(tldrawHtmlComment)\n\t\t\t\t\t\t\t\t\tif (jsonComment === null) {\n\t\t\t\t\t\t\t\t\t\tr({\n\t\t\t\t\t\t\t\t\t\t\ttype: 'error',\n\t\t\t\t\t\t\t\t\t\t\tdata: jsonComment,\n\t\t\t\t\t\t\t\t\t\t\treason: `found tldraw data comment but could not parse base64`,\n\t\t\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\tconst json = JSON.parse(jsonComment)\n\t\t\t\t\t\t\t\t\t\tif (json.type !== 'application/tldraw') {\n\t\t\t\t\t\t\t\t\t\t\tr({\n\t\t\t\t\t\t\t\t\t\t\t\ttype: 'error',\n\t\t\t\t\t\t\t\t\t\t\t\tdata: json,\n\t\t\t\t\t\t\t\t\t\t\t\treason: `found tldraw data comment but JSON was of a different type: ${json.type}`,\n\t\t\t\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t\tif (typeof json.data === 'string') {\n\t\t\t\t\t\t\t\t\t\t\tr({\n\t\t\t\t\t\t\t\t\t\t\t\ttype: 'error',\n\t\t\t\t\t\t\t\t\t\t\t\tdata: json,\n\t\t\t\t\t\t\t\t\t\t\t\treason:\n\t\t\t\t\t\t\t\t\t\t\t\t\t'found tldraw json but data was a string instead of a TLClipboardModel object',\n\t\t\t\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t\tr({ type: 'tldraw', data: json.data })\n\t\t\t\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t} catch (e: any) {\n\t\t\t\t\t\t\t\t\tr({\n\t\t\t\t\t\t\t\t\t\ttype: 'error',\n\t\t\t\t\t\t\t\t\t\tdata: tldrawHtmlComment,\n\t\t\t\t\t\t\t\t\t\treason:\n\t\t\t\t\t\t\t\t\t\t\t'found tldraw json but data was a string instead of a TLClipboardModel object',\n\t\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tif (thing.type === 'html') {\n\t\t\t\t\t\t\t\t\tr({ type: 'text', data: text, subtype: 'html' })\n\t\t\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tif (thing.type === 'url') {\n\t\t\t\t\t\t\t\t\tr({ type: 'text', data: text, subtype: 'url' })\n\t\t\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t// if we have not found a tldraw comment, Otherwise, try to parse the text as JSON directly.\n\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\tconst json = JSON.parse(text)\n\t\t\t\t\t\t\t\t\tif (json.type === 'excalidraw/clipboard') {\n\t\t\t\t\t\t\t\t\t\t// If the clipboard contains content copied from excalidraw, then paste that\n\t\t\t\t\t\t\t\t\t\tr({ type: 'excalidraw', data: json })\n\t\t\t\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\tr({ type: 'text', data: text, subtype: 'json' })\n\t\t\t\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t} catch (e) {\n\t\t\t\t\t\t\t\t\t// If we could not parse the text as JSON, then it's just text\n\t\t\t\t\t\t\t\t\tr({ type: 'text', data: text, subtype: 'text' })\n\t\t\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tr({ type: 'error', data: text, reason: 'unhandled case' })\n\t\t\t\t\t\t})\n\t\t\t\t\t})\n\t\t\t)\n\t)\n\n\t// 3.\n\t//\n\t// Now that we know what kind of stuff we're dealing with, we can actual create some content.\n\t// There are priorities here, so order matters: we've already handled images and files, which\n\t// take first priority; then we want to handle tldraw content, then excalidraw content, then\n\t// html content, then links, and finally text content.\n\n\t// Try to paste tldraw content\n\tfor (const result of results) {\n\t\tif (result.type === 'tldraw') {\n\t\t\tpasteTldrawContent(editor, result.data, point)\n\t\t\treturn\n\t\t}\n\t}\n\n\t// Try to paste excalidraw content\n\tfor (const result of results) {\n\t\tif (result.type === 'excalidraw') {\n\t\t\tpasteExcalidrawContent(editor, result.data, point)\n\t\t\treturn\n\t\t}\n\t}\n\n\t// Try to paste html content\n\tfor (const result of results) {\n\t\tif (result.type === 'text' && result.subtype === 'html') {\n\t\t\t// try to find a link\n\t\t\tconst rootNode = new DOMParser().parseFromString(result.data, 'text/html')\n\t\t\tconst bodyNode = rootNode.querySelector('body')\n\n\t\t\t// Edge on Windows 11 home appears to paste a link as a single in\n\t\t\t// the HTML document. If we're pasting a single like tag we'll just\n\t\t\t// assume the user meant to paste the URL.\n\t\t\tconst isHtmlSingleLink =\n\t\t\t\tbodyNode &&\n\t\t\t\tArray.from(bodyNode.children).filter((el) => el.nodeType === 1).length === 1 &&\n\t\t\t\tbodyNode.firstElementChild &&\n\t\t\t\tbodyNode.firstElementChild.tagName === 'A' &&\n\t\t\t\tbodyNode.firstElementChild.hasAttribute('href') &&\n\t\t\t\tbodyNode.firstElementChild.getAttribute('href') !== ''\n\n\t\t\tif (isHtmlSingleLink) {\n\t\t\t\tconst href = bodyNode.firstElementChild.getAttribute('href')!\n\t\t\t\thandleText(editor, href, point, results)\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\t// If the html is NOT a link, and we have NO OTHER texty content, then paste the html as text\n\t\t\tif (!results.some((r) => r.type === 'text' && r.subtype !== 'html') && result.data.trim()) {\n\t\t\t\thandleText(editor, stripHtml(result.data), point, results)\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t}\n\n\t// Try to paste a link\n\tfor (const result of results) {\n\t\tif (result.type === 'text' && result.subtype === 'url') {\n\t\t\tpasteUrl(editor, result.data, point, results)\n\t\t\treturn\n\t\t}\n\t}\n\n\t// Finally, if we haven't bailed on anything yet, we can paste text content\n\tfor (const result of results) {\n\t\tif (result.type === 'text' && result.subtype === 'text' && result.data.trim()) {\n\t\t\t// The clipboard may include multiple text items, but we only want to paste the first one\n\t\t\thandleText(editor, result.data, point, results)\n\t\t\treturn\n\t\t}\n\t}\n}\n\n/**\n * When the user copies, write the contents to local storage and to the clipboard\n *\n * @param editor - The editor instance.\n * @public\n */\nconst handleNativeOrMenuCopy = async (editor: Editor) => {\n\tconst content = await editor.resolveAssetsInContent(\n\t\teditor.getContentFromCurrentPage(editor.getSelectedShapeIds())\n\t)\n\tif (!content) {\n\t\tif (navigator && navigator.clipboard) {\n\t\t\tnavigator.clipboard.writeText('')\n\t\t}\n\t\treturn\n\t}\n\n\tconst stringifiedClipboard = lz.compressToBase64(\n\t\tJSON.stringify({\n\t\t\ttype: 'application/tldraw',\n\t\t\tkind: 'content',\n\t\t\tdata: content,\n\t\t})\n\t)\n\n\tif (typeof navigator === 'undefined') {\n\t\treturn\n\t} else {\n\t\t// Extract the text from the clipboard\n\t\tconst textItems = content.shapes\n\t\t\t.map((shape) => {\n\t\t\t\tconst util = editor.getShapeUtil(shape)\n\t\t\t\treturn util.getText(shape)\n\t\t\t})\n\t\t\t.filter(isDefined)\n\n\t\tif (navigator.clipboard?.write) {\n\t\t\tconst htmlBlob = new Blob([`
${stringifiedClipboard}
`], {\n\t\t\t\ttype: 'text/html',\n\t\t\t})\n\n\t\t\tlet textContent = textItems.join(' ')\n\n\t\t\t// This is a bug in chrome android where it won't paste content if\n\t\t\t// the text/plain content is \"\" so we need to always add an empty\n\t\t\t// space \uD83E\uDD2C\n\t\t\tif (textContent === '') {\n\t\t\t\ttextContent = ' '\n\t\t\t}\n\n\t\t\tnavigator.clipboard.write([\n\t\t\t\tnew ClipboardItem({\n\t\t\t\t\t'text/html': htmlBlob,\n\t\t\t\t\t// What is this second blob used for?\n\t\t\t\t\t'text/plain': new Blob([textContent], { type: 'text/plain' }),\n\t\t\t\t}),\n\t\t\t])\n\t\t} else if (navigator.clipboard.writeText) {\n\t\t\tnavigator.clipboard.writeText(`
${stringifiedClipboard}
`)\n\t\t}\n\t}\n}\n\n/** @public */\nexport function useMenuClipboardEvents() {\n\tconst editor = useEditor()\n\tconst trackEvent = useUiEvents()\n\n\tconst copy = useCallback(\n\t\tasync function onCopy(source: TLUiEventSource) {\n\t\t\tif (editor.getSelectedShapeIds().length === 0) return\n\n\t\t\tawait handleNativeOrMenuCopy(editor)\n\t\t\ttrackEvent('copy', { source })\n\t\t},\n\t\t[editor, trackEvent]\n\t)\n\n\tconst cut = useCallback(\n\t\tasync function onCut(source: TLUiEventSource) {\n\t\t\tif (editor.getSelectedShapeIds().length === 0) return\n\n\t\t\tawait handleNativeOrMenuCopy(editor)\n\t\t\teditor.deleteShapes(editor.getSelectedShapeIds())\n\t\t\ttrackEvent('cut', { source })\n\t\t},\n\t\t[editor, trackEvent]\n\t)\n\n\tconst paste = useCallback(\n\t\tasync function onPaste(\n\t\t\tdata: DataTransfer | ClipboardItem[],\n\t\t\tsource: TLUiEventSource,\n\t\t\tpoint?: VecLike\n\t\t) {\n\t\t\t// If we're editing a shape, or we are focusing an editable input, then\n\t\t\t// we would want the user's paste interaction to go to that element or\n\t\t\t// input instead; e.g. when pasting text into a text shape's content\n\t\t\tif (editor.getEditingShapeId() !== null) return\n\n\t\t\tif (Array.isArray(data) && data[0] instanceof ClipboardItem) {\n\t\t\t\thandlePasteFromClipboardApi(editor, data, point)\n\t\t\t\ttrackEvent('paste', { source: 'menu' })\n\t\t\t} else {\n\t\t\t\t// Read it first and then recurse, kind of weird\n\t\t\t\tnavigator.clipboard.read().then((clipboardItems) => {\n\t\t\t\t\tpaste(clipboardItems, source, point)\n\t\t\t\t})\n\t\t\t}\n\t\t},\n\t\t[editor, trackEvent]\n\t)\n\n\treturn {\n\t\tcopy,\n\t\tcut,\n\t\tpaste,\n\t}\n}\n\n/** @public */\nexport function useNativeClipboardEvents() {\n\tconst editor = useEditor()\n\tconst trackEvent = useUiEvents()\n\n\tconst appIsFocused = useValue('editor.isFocused', () => editor.getInstanceState().isFocused, [\n\t\teditor,\n\t])\n\n\tuseEffect(() => {\n\t\tif (!appIsFocused) return\n\t\tconst copy = async (e: ClipboardEvent) => {\n\t\t\tif (\n\t\t\t\teditor.getSelectedShapeIds().length === 0 ||\n\t\t\t\teditor.getEditingShapeId() !== null ||\n\t\t\t\tdisallowClipboardEvents(editor)\n\t\t\t) {\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tpreventDefault(e)\n\t\t\tawait handleNativeOrMenuCopy(editor)\n\t\t\ttrackEvent('copy', { source: 'kbd' })\n\t\t}\n\n\t\tasync function cut(e: ClipboardEvent) {\n\t\t\tif (\n\t\t\t\teditor.getSelectedShapeIds().length === 0 ||\n\t\t\t\teditor.getEditingShapeId() !== null ||\n\t\t\t\tdisallowClipboardEvents(editor)\n\t\t\t) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tpreventDefault(e)\n\t\t\tawait handleNativeOrMenuCopy(editor)\n\t\t\teditor.deleteShapes(editor.getSelectedShapeIds())\n\t\t\ttrackEvent('cut', { source: 'kbd' })\n\t\t}\n\n\t\tlet disablingMiddleClickPaste = false\n\t\tconst pointerUpHandler = (e: PointerEvent) => {\n\t\t\tif (e.button === 1) {\n\t\t\t\t// middle mouse button\n\t\t\t\tdisablingMiddleClickPaste = true\n\t\t\t\teditor.timers.requestAnimationFrame(() => {\n\t\t\t\t\tdisablingMiddleClickPaste = false\n\t\t\t\t})\n\t\t\t}\n\t\t}\n\n\t\tconst paste = (e: ClipboardEvent) => {\n\t\t\tif (disablingMiddleClickPaste) {\n\t\t\t\tstopEventPropagation(e)\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\t// If we're editing a shape, or we are focusing an editable input, then\n\t\t\t// we would want the user's paste interaction to go to that element or\n\t\t\t// input instead; e.g. when pasting text into a text shape's content\n\t\t\tif (editor.getEditingShapeId() !== null || disallowClipboardEvents(editor)) return\n\n\t\t\t// Where should the shapes go?\n\t\t\tlet point: Vec | undefined = undefined\n\t\t\tlet pasteAtCursor = false\n\n\t\t\t// | Shiftkey | Paste at cursor mode | Paste at point? |\n\t\t\t// | N \t\t| N | N \t\t\t\t |\n\t\t\t// | Y \t\t| N | Y \t\t\t\t |\n\t\t\t// | N \t\t| Y | Y \t\t\t\t |\n\t\t\t// | Y \t\t| Y | N \t\t\t\t |\n\t\t\tif (editor.inputs.shiftKey) pasteAtCursor = true\n\t\t\tif (editor.user.getIsPasteAtCursorMode()) pasteAtCursor = !pasteAtCursor\n\t\t\tif (pasteAtCursor) point = editor.inputs.currentPagePoint\n\n\t\t\t// First try to use the clipboard data on the event\n\t\t\tif (e.clipboardData && !editor.inputs.shiftKey) {\n\t\t\t\thandlePasteFromEventClipboardData(editor, e.clipboardData, point)\n\t\t\t} else {\n\t\t\t\t// Or else use the clipboard API\n\t\t\t\tnavigator.clipboard.read().then((clipboardItems) => {\n\t\t\t\t\tif (Array.isArray(clipboardItems) && clipboardItems[0] instanceof ClipboardItem) {\n\t\t\t\t\t\thandlePasteFromClipboardApi(editor, clipboardItems, point)\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t}\n\n\t\t\tpreventDefault(e)\n\t\t\ttrackEvent('paste', { source: 'kbd' })\n\t\t}\n\n\t\tdocument.addEventListener('copy', copy)\n\t\tdocument.addEventListener('cut', cut)\n\t\tdocument.addEventListener('paste', paste)\n\t\tdocument.addEventListener('pointerup', pointerUpHandler)\n\n\t\treturn () => {\n\t\t\tdocument.removeEventListener('copy', copy)\n\t\t\tdocument.removeEventListener('cut', cut)\n\t\t\tdocument.removeEventListener('paste', paste)\n\t\t\tdocument.removeEventListener('pointerup', pointerUpHandler)\n\t\t}\n\t}, [editor, trackEvent, appIsFocused])\n}\n"], -- "mappings": "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", -+ "sourcesContent": ["import {\n\tEditor,\n\tFileHelpers,\n\tTLExternalContentSource,\n\tVec,\n\tVecLike,\n\tisDefined,\n\tpreventDefault,\n\tstopEventPropagation,\n\tuniq,\n\tuseContainer,\n\tuseEditor,\n\tuseValue,\n} from '@tldraw/editor'\nimport lz from 'lz-string'\nimport { useCallback, useEffect } from 'react'\nimport { TLUiEventSource, useUiEvents } from '../context/events'\nimport { pasteExcalidrawContent } from './clipboard/pasteExcalidrawContent'\nimport { pasteFiles } from './clipboard/pasteFiles'\nimport { pasteTldrawContent } from './clipboard/pasteTldrawContent'\nimport { pasteUrl } from './clipboard/pasteUrl'\n\n/**\n * Strip HTML tags from a string.\n * @param html - The HTML to strip.\n * @internal\n */\nfunction stripHtml(html: string) {\n\t// See \n\tconst doc = document.implementation.createHTMLDocument('')\n\tdoc.documentElement.innerHTML = html.trim()\n\treturn doc.body.textContent || doc.body.innerText || ''\n}\n\n/** @public */\nexport const isValidHttpURL = (url: string) => {\n\ttry {\n\t\tconst u = new URL(url)\n\t\treturn u.protocol === 'http:' || u.protocol === 'https:'\n\t} catch (e) {\n\t\treturn false\n\t}\n}\n\n/** @public */\nconst getValidHttpURLList = (url: string) => {\n\tconst urls = url.split(/[\\n\\s]/)\n\tfor (const url of urls) {\n\t\ttry {\n\t\t\tconst u = new URL(url)\n\t\t\tif (!(u.protocol === 'http:' || u.protocol === 'https:')) {\n\t\t\t\treturn\n\t\t\t}\n\t\t} catch (e) {\n\t\t\treturn\n\t\t}\n\t}\n\treturn uniq(urls)\n}\n\n/** @public */\nconst isSvgText = (text: string) => {\n\treturn /^ -1))\n\t)\n}\n\n/**\n * Whether a ClipboardItem is a file.\n * @param item - The ClipboardItem to check.\n * @internal\n */\nconst isFile = (item: ClipboardItem) => {\n\treturn item.types.find((i) => i.match(/^image\\//))\n}\n\n/**\n * Handle text pasted into the editor.\n * @param editor - The editor instance.\n * @param data - The text to paste.\n * @param point - The point at which to paste the text.\n * @internal\n */\nconst handleText = (\n\teditor: Editor,\n\tdata: string,\n\tpoint?: VecLike,\n\tsources?: TLExternalContentSource[]\n) => {\n\tconst validUrlList = getValidHttpURLList(data)\n\tif (validUrlList) {\n\t\tfor (const url of validUrlList) {\n\t\t\tpasteUrl(editor, url, point)\n\t\t}\n\t} else if (isValidHttpURL(data)) {\n\t\tpasteUrl(editor, data, point)\n\t} else if (isSvgText(data)) {\n\t\teditor.markHistoryStoppingPoint('paste')\n\t\teditor.putExternalContent({\n\t\t\ttype: 'svg-text',\n\t\t\ttext: data,\n\t\t\tpoint,\n\t\t\tsources,\n\t\t})\n\t} else {\n\t\teditor.markHistoryStoppingPoint('paste')\n\t\teditor.putExternalContent({\n\t\t\ttype: 'text',\n\t\t\ttext: data,\n\t\t\tpoint,\n\t\t\tsources,\n\t\t})\n\t}\n}\n\n/**\n * Something found on the clipboard, either through the event's clipboard data or the browser's clipboard API.\n * @internal\n */\ntype ClipboardThing =\n\t| {\n\t\t\ttype: 'file'\n\t\t\tsource: Promise\n\t }\n\t| {\n\t\t\ttype: 'blob'\n\t\t\tsource: Promise\n\t }\n\t| {\n\t\t\ttype: 'url'\n\t\t\tsource: Promise\n\t }\n\t| {\n\t\t\ttype: 'html'\n\t\t\tsource: Promise\n\t }\n\t| {\n\t\t\ttype: 'text'\n\t\t\tsource: Promise\n\t }\n\t| {\n\t\t\ttype: string\n\t\t\tsource: Promise\n\t }\n\n/**\n * Handle a paste using event clipboard data. This is the \"original\"\n * paste method that uses the clipboard data from the paste event.\n * https://developer.mozilla.org/en-US/docs/Web/API/ClipboardEvent/clipboardData\n *\n * @param editor - The editor\n * @param clipboardData - The clipboard data\n * @param point - The point to paste at\n * @internal\n */\nconst handlePasteFromEventClipboardData = async (\n\teditor: Editor,\n\tclipboardData: DataTransfer,\n\tpoint?: VecLike\n) => {\n\t// Do not paste while in any editing state\n\tif (editor.getEditingShapeId() !== null) return\n\n\tif (!clipboardData) {\n\t\tthrow Error('No clipboard data')\n\t}\n\n\tconst things: ClipboardThing[] = []\n\n\tfor (const item of Object.values(clipboardData.items)) {\n\t\tswitch (item.kind) {\n\t\t\tcase 'file': {\n\t\t\t\t// files are always blobs\n\t\t\t\tthings.push({\n\t\t\t\t\ttype: 'file',\n\t\t\t\t\tsource: new Promise((r) => r(item.getAsFile())) as Promise,\n\t\t\t\t})\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'string': {\n\t\t\t\t// strings can be text or html\n\t\t\t\tif (item.type === 'text/html') {\n\t\t\t\t\tthings.push({\n\t\t\t\t\t\ttype: 'html',\n\t\t\t\t\t\tsource: new Promise((r) => item.getAsString(r)) as Promise,\n\t\t\t\t\t})\n\t\t\t\t} else if (item.type === 'text/plain') {\n\t\t\t\t\tthings.push({\n\t\t\t\t\t\ttype: 'text',\n\t\t\t\t\t\tsource: new Promise((r) => item.getAsString(r)) as Promise,\n\t\t\t\t\t})\n\t\t\t\t} else {\n\t\t\t\t\tthings.push({ type: item.type, source: new Promise((r) => item.getAsString(r)) })\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n\n\thandleClipboardThings(editor, things, point)\n}\n\n/**\n * Handle a paste using items retrieved from the Clipboard API.\n * https://developer.mozilla.org/en-US/docs/Web/API/ClipboardItem\n *\n * @param editor - The editor\n * @param clipboardItems - The clipboard items to handle\n * @param point - The point to paste at\n * @internal\n */\nconst handlePasteFromClipboardApi = async (\n\teditor: Editor,\n\tclipboardItems: ClipboardItem[],\n\tpoint?: VecLike\n) => {\n\t// We need to populate the array of clipboard things\n\t// based on the ClipboardItems from the Clipboard API.\n\t// This is done in a different way than when using\n\t// the clipboard data from the paste event.\n\n\tconst things: ClipboardThing[] = []\n\n\tfor (const item of clipboardItems) {\n\t\tif (isFile(item)) {\n\t\t\tfor (const type of item.types) {\n\t\t\t\tif (type.match(/^image\\//)) {\n\t\t\t\t\tthings.push({ type: 'blob', source: item.getType(type) })\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (item.types.includes('text/html')) {\n\t\t\tthings.push({\n\t\t\t\ttype: 'html',\n\t\t\t\tsource: (async () => {\n\t\t\t\t\tconst blob = await item.getType('text/html')\n\t\t\t\t\treturn await FileHelpers.blobToText(blob)\n\t\t\t\t})(),\n\t\t\t})\n\t\t}\n\n\t\tif (item.types.includes('text/uri-list')) {\n\t\t\tthings.push({\n\t\t\t\ttype: 'url',\n\t\t\t\tsource: (async () => {\n\t\t\t\t\tconst blob = await item.getType('text/uri-list')\n\t\t\t\t\treturn await FileHelpers.blobToText(blob)\n\t\t\t\t})(),\n\t\t\t})\n\t\t}\n\n\t\tif (item.types.includes('text/plain')) {\n\t\t\tthings.push({\n\t\t\t\ttype: 'text',\n\t\t\t\tsource: (async () => {\n\t\t\t\t\tconst blob = await item.getType('text/plain')\n\t\t\t\t\treturn await FileHelpers.blobToText(blob)\n\t\t\t\t})(),\n\t\t\t})\n\t\t}\n\t}\n\n\treturn await handleClipboardThings(editor, things, point)\n}\n\nasync function handleClipboardThings(editor: Editor, things: ClipboardThing[], point?: VecLike) {\n\t// 1. Handle files\n\t//\n\t// We need to handle files separately because if we want them to\n\t// be placed next to each other, we need to create them all at once.\n\n\tconst files = things.filter(\n\t\t(t) => (t.type === 'file' || t.type === 'blob') && t.source !== null\n\t) as Extract[]\n\n\t// Just paste the files, nothing else\n\tif (files.length) {\n\t\tif (files.length > editor.options.maxFilesAtOnce) {\n\t\t\tthrow Error('Too many files')\n\t\t}\n\t\tconst fileBlobs = await Promise.all(files.map((t) => t.source!))\n\t\tconst urls = (fileBlobs.filter(Boolean) as (File | Blob)[]).map((blob) =>\n\t\t\tURL.createObjectURL(blob)\n\t\t)\n\t\treturn await pasteFiles(editor, urls, point)\n\t}\n\n\t// 2. Generate clipboard results for non-file things\n\t//\n\t// Getting the source from the items is async, however they must be accessed syncronously;\n\t// we can't await them in a loop. So we'll map them to promises and await them all at once,\n\t// then make decisions based on what we find.\n\n\tconst results = await Promise.all(\n\t\tthings\n\t\t\t.filter((t) => t.type !== 'file')\n\t\t\t.map(\n\t\t\t\t(t) =>\n\t\t\t\t\tnew Promise((r) => {\n\t\t\t\t\t\tconst thing = t as Exclude\n\n\t\t\t\t\t\tif (thing.type === 'file') {\n\t\t\t\t\t\t\tr({ type: 'error', data: null, reason: 'unexpected file' })\n\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tthing.source.then((text) => {\n\t\t\t\t\t\t\t// first, see if we can find tldraw content, which is JSON inside of an html comment\n\t\t\t\t\t\t\tconst tldrawHtmlComment = text.match(/
]*>(.*)<\\/div>/)?.[1]\n\n\t\t\t\t\t\t\tif (tldrawHtmlComment) {\n\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\t// If we've found tldraw content in the html string, use that as JSON\n\t\t\t\t\t\t\t\t\tconst jsonComment = lz.decompressFromBase64(tldrawHtmlComment)\n\t\t\t\t\t\t\t\t\tif (jsonComment === null) {\n\t\t\t\t\t\t\t\t\t\tr({\n\t\t\t\t\t\t\t\t\t\t\ttype: 'error',\n\t\t\t\t\t\t\t\t\t\t\tdata: jsonComment,\n\t\t\t\t\t\t\t\t\t\t\treason: `found tldraw data comment but could not parse base64`,\n\t\t\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\tconst json = JSON.parse(jsonComment)\n\t\t\t\t\t\t\t\t\t\tif (json.type !== 'application/tldraw') {\n\t\t\t\t\t\t\t\t\t\t\tr({\n\t\t\t\t\t\t\t\t\t\t\t\ttype: 'error',\n\t\t\t\t\t\t\t\t\t\t\t\tdata: json,\n\t\t\t\t\t\t\t\t\t\t\t\treason: `found tldraw data comment but JSON was of a different type: ${json.type}`,\n\t\t\t\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t\tif (typeof json.data === 'string') {\n\t\t\t\t\t\t\t\t\t\t\tr({\n\t\t\t\t\t\t\t\t\t\t\t\ttype: 'error',\n\t\t\t\t\t\t\t\t\t\t\t\tdata: json,\n\t\t\t\t\t\t\t\t\t\t\t\treason:\n\t\t\t\t\t\t\t\t\t\t\t\t\t'found tldraw json but data was a string instead of a TLClipboardModel object',\n\t\t\t\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t\tr({ type: 'tldraw', data: json.data })\n\t\t\t\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t} catch (e: any) {\n\t\t\t\t\t\t\t\t\tr({\n\t\t\t\t\t\t\t\t\t\ttype: 'error',\n\t\t\t\t\t\t\t\t\t\tdata: tldrawHtmlComment,\n\t\t\t\t\t\t\t\t\t\treason:\n\t\t\t\t\t\t\t\t\t\t\t'found tldraw json but data was a string instead of a TLClipboardModel object',\n\t\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tif (thing.type === 'html') {\n\t\t\t\t\t\t\t\t\tr({ type: 'text', data: text, subtype: 'html' })\n\t\t\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tif (thing.type === 'url') {\n\t\t\t\t\t\t\t\t\tr({ type: 'text', data: text, subtype: 'url' })\n\t\t\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t// if we have not found a tldraw comment, Otherwise, try to parse the text as JSON directly.\n\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\tconst json = JSON.parse(text)\n\t\t\t\t\t\t\t\t\tif (json.type === 'excalidraw/clipboard') {\n\t\t\t\t\t\t\t\t\t\t// If the clipboard contains content copied from excalidraw, then paste that\n\t\t\t\t\t\t\t\t\t\tr({ type: 'excalidraw', data: json })\n\t\t\t\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\tr({ type: 'text', data: text, subtype: 'json' })\n\t\t\t\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t} catch (e) {\n\t\t\t\t\t\t\t\t\t// If we could not parse the text as JSON, then it's just text\n\t\t\t\t\t\t\t\t\tr({ type: 'text', data: text, subtype: 'text' })\n\t\t\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tr({ type: 'error', data: text, reason: 'unhandled case' })\n\t\t\t\t\t\t})\n\t\t\t\t\t})\n\t\t\t)\n\t)\n\n\t// 3.\n\t//\n\t// Now that we know what kind of stuff we're dealing with, we can actual create some content.\n\t// There are priorities here, so order matters: we've already handled images and files, which\n\t// take first priority; then we want to handle tldraw content, then excalidraw content, then\n\t// html content, then links, and finally text content.\n\n\t// Try to paste tldraw content\n\tfor (const result of results) {\n\t\tif (result.type === 'tldraw') {\n\t\t\tpasteTldrawContent(editor, result.data, point)\n\t\t\treturn\n\t\t}\n\t}\n\n\t// Try to paste excalidraw content\n\tfor (const result of results) {\n\t\tif (result.type === 'excalidraw') {\n\t\t\tpasteExcalidrawContent(editor, result.data, point)\n\t\t\treturn\n\t\t}\n\t}\n\n\t// Try to paste html content\n\tfor (const result of results) {\n\t\tif (result.type === 'text' && result.subtype === 'html') {\n\t\t\t// try to find a link\n\t\t\tconst rootNode = new DOMParser().parseFromString(result.data, 'text/html')\n\t\t\tconst bodyNode = rootNode.querySelector('body')\n\n\t\t\t// Edge on Windows 11 home appears to paste a link as a single in\n\t\t\t// the HTML document. If we're pasting a single like tag we'll just\n\t\t\t// assume the user meant to paste the URL.\n\t\t\tconst isHtmlSingleLink =\n\t\t\t\tbodyNode &&\n\t\t\t\tArray.from(bodyNode.children).filter((el) => el.nodeType === 1).length === 1 &&\n\t\t\t\tbodyNode.firstElementChild &&\n\t\t\t\tbodyNode.firstElementChild.tagName === 'A' &&\n\t\t\t\tbodyNode.firstElementChild.hasAttribute('href') &&\n\t\t\t\tbodyNode.firstElementChild.getAttribute('href') !== ''\n\n\t\t\tif (isHtmlSingleLink) {\n\t\t\t\tconst href = bodyNode.firstElementChild.getAttribute('href')!\n\t\t\t\thandleText(editor, href, point, results)\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\t// If the html is NOT a link, and we have NO OTHER texty content, then paste the html as text\n\t\t\tif (!results.some((r) => r.type === 'text' && r.subtype !== 'html') && result.data.trim()) {\n\t\t\t\thandleText(editor, stripHtml(result.data), point, results)\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t}\n\n\t// Try to paste a link\n\tfor (const result of results) {\n\t\tif (result.type === 'text' && result.subtype === 'url') {\n\t\t\tpasteUrl(editor, result.data, point, results)\n\t\t\treturn\n\t\t}\n\t}\n\n\t// Finally, if we haven't bailed on anything yet, we can paste text content\n\tfor (const result of results) {\n\t\tif (result.type === 'text' && result.subtype === 'text' && result.data.trim()) {\n\t\t\t// The clipboard may include multiple text items, but we only want to paste the first one\n\t\t\thandleText(editor, result.data, point, results)\n\t\t\treturn\n\t\t}\n\t}\n}\n\n/**\n * When the user copies, write the contents to local storage and to the clipboard\n *\n * @param editor - The editor instance.\n * @public\n */\nconst handleNativeOrMenuCopy = async (editor: Editor) => {\n\tconst content = await editor.resolveAssetsInContent(\n\t\teditor.getContentFromCurrentPage(editor.getSelectedShapeIds())\n\t)\n\tif (!content) {\n\t\tif (navigator && navigator.clipboard) {\n\t\t\tnavigator.clipboard.writeText('')\n\t\t}\n\t\treturn\n\t}\n\n\tconst stringifiedClipboard = lz.compressToBase64(\n\t\tJSON.stringify({\n\t\t\ttype: 'application/tldraw',\n\t\t\tkind: 'content',\n\t\t\tdata: content,\n\t\t})\n\t)\n\n\tif (typeof navigator === 'undefined') {\n\t\treturn\n\t} else {\n\t\t// Extract the text from the clipboard\n\t\tconst textItems = content.shapes\n\t\t\t.map((shape) => {\n\t\t\t\tconst util = editor.getShapeUtil(shape)\n\t\t\t\treturn util.getText(shape)\n\t\t\t})\n\t\t\t.filter(isDefined)\n\n\t\tif (navigator.clipboard?.write) {\n\t\t\tconst htmlBlob = new Blob([`
${stringifiedClipboard}
`], {\n\t\t\t\ttype: 'text/html',\n\t\t\t})\n\n\t\t\tlet textContent = textItems.join(' ')\n\n\t\t\t// This is a bug in chrome android where it won't paste content if\n\t\t\t// the text/plain content is \"\" so we need to always add an empty\n\t\t\t// space \uD83E\uDD2C\n\t\t\tif (textContent === '') {\n\t\t\t\ttextContent = ' '\n\t\t\t}\n\n\t\t\tnavigator.clipboard.write([\n\t\t\t\tnew ClipboardItem({\n\t\t\t\t\t'text/html': htmlBlob,\n\t\t\t\t\t// What is this second blob used for?\n\t\t\t\t\t'text/plain': new Blob([textContent], { type: 'text/plain' }),\n\t\t\t\t}),\n\t\t\t])\n\t\t} else if (navigator.clipboard.writeText) {\n\t\t\tnavigator.clipboard.writeText(`
${stringifiedClipboard}
`)\n\t\t}\n\t}\n}\n\n/** @public */\nexport function useMenuClipboardEvents() {\n\tconst editor = useEditor()\n\tconst trackEvent = useUiEvents()\n\n\tconst copy = useCallback(\n\t\tasync function onCopy(source: TLUiEventSource) {\n\t\t\tif (editor.getSelectedShapeIds().length === 0) return\n\n\t\t\tawait handleNativeOrMenuCopy(editor)\n\t\t\ttrackEvent('copy', { source })\n\t\t},\n\t\t[editor, trackEvent]\n\t)\n\n\tconst cut = useCallback(\n\t\tasync function onCut(source: TLUiEventSource) {\n\t\t\tif (editor.getSelectedShapeIds().length === 0) return\n\n\t\t\tawait handleNativeOrMenuCopy(editor)\n\t\t\teditor.deleteShapes(editor.getSelectedShapeIds())\n\t\t\ttrackEvent('cut', { source })\n\t\t},\n\t\t[editor, trackEvent]\n\t)\n\n\tconst paste = useCallback(\n\t\tasync function onPaste(\n\t\t\tdata: DataTransfer | ClipboardItem[],\n\t\t\tsource: TLUiEventSource,\n\t\t\tpoint?: VecLike\n\t\t) {\n\t\t\t// If we're editing a shape, or we are focusing an editable input, then\n\t\t\t// we would want the user's paste interaction to go to that element or\n\t\t\t// input instead; e.g. when pasting text into a text shape's content\n\t\t\tif (editor.getEditingShapeId() !== null) return\n\n\t\t\tif (Array.isArray(data) && data[0] instanceof ClipboardItem) {\n\t\t\t\thandlePasteFromClipboardApi(editor, data, point)\n\t\t\t\ttrackEvent('paste', { source: 'menu' })\n\t\t\t} else {\n\t\t\t\t// Read it first and then recurse, kind of weird\n\t\t\t\tnavigator.clipboard.read().then((clipboardItems) => {\n\t\t\t\t\tpaste(clipboardItems, source, point)\n\t\t\t\t})\n\t\t\t}\n\t\t},\n\t\t[editor, trackEvent]\n\t)\n\n\treturn {\n\t\tcopy,\n\t\tcut,\n\t\tpaste,\n\t}\n}\n\n/** @public */\nexport function useNativeClipboardEvents() {\n \tconst container = useContainer()\n \tconst editor = useEditor()\n\tconst trackEvent = useUiEvents()\n\n\tconst appIsFocused = useValue('editor.isFocused', () => editor.getInstanceState().isFocused, [\n\t\teditor,\n\t])\n\n\tuseEffect(() => {\n\t\tif (!appIsFocused) return\n\t\tconst copy = async (e: ClipboardEvent) => {\n\t\t\tif (\n\t\t\t\teditor.getSelectedShapeIds().length === 0 ||\n\t\t\t\teditor.getEditingShapeId() !== null ||\n\t\t\t\tdisallowClipboardEvents(editor)\n\t\t\t) {\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tpreventDefault(e)\n\t\t\tawait handleNativeOrMenuCopy(editor)\n\t\t\ttrackEvent('copy', { source: 'kbd' })\n\t\t}\n\n\t\tasync function cut(e: ClipboardEvent) {\n\t\t\tif (\n\t\t\t\teditor.getSelectedShapeIds().length === 0 ||\n\t\t\t\teditor.getEditingShapeId() !== null ||\n\t\t\t\tdisallowClipboardEvents(editor)\n\t\t\t) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tpreventDefault(e)\n\t\t\tawait handleNativeOrMenuCopy(editor)\n\t\t\teditor.deleteShapes(editor.getSelectedShapeIds())\n\t\t\ttrackEvent('cut', { source: 'kbd' })\n\t\t}\n\n\t\tlet disablingMiddleClickPaste = false\n\t\tconst pointerUpHandler = (e: PointerEvent) => {\n\t\t\tif (e.button === 1) {\n\t\t\t\t// middle mouse button\n\t\t\t\tdisablingMiddleClickPaste = true\n\t\t\t\teditor.timers.requestAnimationFrame(() => {\n\t\t\t\t\tdisablingMiddleClickPaste = false\n\t\t\t\t})\n\t\t\t}\n\t\t}\n\n\t\tconst paste = (e: ClipboardEvent) => {\n\t\t\tif (disablingMiddleClickPaste) {\n\t\t\t\tstopEventPropagation(e)\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\t// If we're editing a shape, or we are focusing an editable input, then\n\t\t\t// we would want the user's paste interaction to go to that element or\n\t\t\t// input instead; e.g. when pasting text into a text shape's content\n\t\t\tif (editor.getEditingShapeId() !== null || disallowClipboardEvents(editor)) return\n\n\t\t\t// Where should the shapes go?\n\t\t\tlet point: Vec | undefined = undefined\n\t\t\tlet pasteAtCursor = false\n\n\t\t\t// | Shiftkey | Paste at cursor mode | Paste at point? |\n\t\t\t// | N \t\t| N | N \t\t\t\t |\n\t\t\t// | Y \t\t| N | Y \t\t\t\t |\n\t\t\t// | N \t\t| Y | Y \t\t\t\t |\n\t\t\t// | Y \t\t| Y | N \t\t\t\t |\n\t\t\tif (editor.inputs.shiftKey) pasteAtCursor = true\n\t\t\tif (editor.user.getIsPasteAtCursorMode()) pasteAtCursor = !pasteAtCursor\n\t\t\tif (pasteAtCursor) point = editor.inputs.currentPagePoint\n\n\t\t\t// First try to use the clipboard data on the event\n\t\t\tif (e.clipboardData && !editor.inputs.shiftKey) {\n\t\t\t\thandlePasteFromEventClipboardData(editor, e.clipboardData, point)\n\t\t\t} else {\n\t\t\t\t// Or else use the clipboard API\n\t\t\t\tnavigator.clipboard.read().then((clipboardItems) => {\n\t\t\t\t\tif (Array.isArray(clipboardItems) && clipboardItems[0] instanceof ClipboardItem) {\n\t\t\t\t\t\thandlePasteFromClipboardApi(editor, clipboardItems, point)\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t}\n\n\t\t\tpreventDefault(e)\n\t\t\ttrackEvent('paste', { source: 'kbd' })\n\t\t}\n\n\t\tcontainer.ownerDocument.addEventListener('copy', copy)\n\t\tcontainer.ownerDocument.addEventListener('cut', cut)\n\t\tcontainer.ownerDocument.addEventListener('paste', paste)\n\t\tcontainer.ownerDocument.addEventListener('pointerup', pointerUpHandler)\n\n\t\treturn () => {\n\t\t\tcontainer.ownerDocument.removeEventListener('copy', copy)\n\t\t\tcontainer.ownerDocument.removeEventListener('cut', cut)\n\t\t\tcontainer.ownerDocument.removeEventListener('paste', paste)\n\t\t\tcontainer.ownerDocument.removeEventListener('pointerup', pointerUpHandler)\n\t\t}\n\t}, [editor, trackEvent, appIsFocused, container])\n}\n"], -+ "mappings": "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", - "names": ["url", "lz"] - } -diff --git a/node_modules/tldraw/dist-cjs/lib/ui/hooks/useKeyboardShortcuts.js b/node_modules/tldraw/dist-cjs/lib/ui/hooks/useKeyboardShortcuts.js -index 9887984..c6b61e5 100644 ---- a/node_modules/tldraw/dist-cjs/lib/ui/hooks/useKeyboardShortcuts.js -+++ b/node_modules/tldraw/dist-cjs/lib/ui/hooks/useKeyboardShortcuts.js -@@ -47,6 +47,7 @@ const SKIP_KBDS = [ - "asset" - ]; - function useKeyboardShortcuts() { -+ const container = (0, import_editor.useContainer)(); - const editor = (0, import_editor.useEditor)(); - const isReadonlyMode = (0, import_useReadonly.useReadonly)(); - const actions = (0, import_actions.useActions)(); -@@ -56,13 +57,13 @@ function useKeyboardShortcuts() { - if (!isFocused) return; - const disposables = new Array(); - const hot = (keys, callback) => { -- (0, import_hotkeys_js.default)(keys, { element: document.body }, callback); -+ (0, import_hotkeys_js.default)(keys, { element: container.ownerDocument.body }, callback); - disposables.push(() => { - import_hotkeys_js.default.unbind(keys, callback); - }); - }; - const hotUp = (keys, callback) => { -- (0, import_hotkeys_js.default)(keys, { element: document.body, keyup: true, keydown: false }, callback); -+ (0, import_hotkeys_js.default)(keys, { element: container.ownerDocument.body, keyup: true, keydown: false }, callback); - disposables.push(() => { - import_hotkeys_js.default.unbind(keys, callback); - }); -@@ -132,7 +133,7 @@ function useKeyboardShortcuts() { - return () => { - disposables.forEach((d) => d()); - }; -- }, [actions, tools, isReadonlyMode, editor, isFocused]); -+ }, [actions, tools, isReadonlyMode, editor, container, isFocused]); - } - function getHotkeysStringFromKbd(kbd) { - return getKeys(kbd).map((kbd2) => { -diff --git a/node_modules/tldraw/dist-cjs/lib/ui/hooks/useKeyboardShortcuts.js.map b/node_modules/tldraw/dist-cjs/lib/ui/hooks/useKeyboardShortcuts.js.map -index 40031c0..b24cfce 100644 ---- a/node_modules/tldraw/dist-cjs/lib/ui/hooks/useKeyboardShortcuts.js.map -+++ b/node_modules/tldraw/dist-cjs/lib/ui/hooks/useKeyboardShortcuts.js.map -@@ -1,7 +1,7 @@ - { - "version": 3, - "sources": ["../../../../src/lib/ui/hooks/useKeyboardShortcuts.ts"], -- "sourcesContent": ["import { Editor, TLPointerEventInfo, preventDefault, useEditor, useValue } from '@tldraw/editor'\nimport hotkeys from 'hotkeys-js'\nimport { useEffect } from 'react'\nimport { useActions } from '../context/actions'\nimport { useReadonly } from './useReadonly'\nimport { useTools } from './useTools'\n\nconst SKIP_KBDS = [\n\t// we set these in useNativeClipboardEvents instead\n\t'copy',\n\t'cut',\n\t'paste',\n\t// There's also an upload asset action, so we don't want to set the kbd twice\n\t'asset',\n]\n\n/** @public */\nexport function useKeyboardShortcuts() {\n\tconst editor = useEditor()\n\n\tconst isReadonlyMode = useReadonly()\n\tconst actions = useActions()\n\tconst tools = useTools()\n\tconst isFocused = useValue('is focused', () => editor.getInstanceState().isFocused, [editor])\n\tuseEffect(() => {\n\t\tif (!isFocused) return\n\n\t\tconst disposables = new Array<() => void>()\n\n\t\tconst hot = (keys: string, callback: (event: KeyboardEvent) => void) => {\n\t\t\thotkeys(keys, { element: document.body }, callback)\n\t\t\tdisposables.push(() => {\n\t\t\t\thotkeys.unbind(keys, callback)\n\t\t\t})\n\t\t}\n\n\t\tconst hotUp = (keys: string, callback: (event: KeyboardEvent) => void) => {\n\t\t\thotkeys(keys, { element: document.body, keyup: true, keydown: false }, callback)\n\t\t\tdisposables.push(() => {\n\t\t\t\thotkeys.unbind(keys, callback)\n\t\t\t})\n\t\t}\n\n\t\t// Add hotkeys for actions and tools.\n\t\t// Except those that in SKIP_KBDS!\n\t\tfor (const action of Object.values(actions)) {\n\t\t\tif (!action.kbd) continue\n\t\t\tif (isReadonlyMode && !action.readonlyOk) continue\n\t\t\tif (SKIP_KBDS.includes(action.id)) continue\n\n\t\t\thot(getHotkeysStringFromKbd(action.kbd), (event) => {\n\t\t\t\tif (areShortcutsDisabled(editor)) return\n\t\t\t\tpreventDefault(event)\n\t\t\t\taction.onSelect('kbd')\n\t\t\t})\n\t\t}\n\n\t\tfor (const tool of Object.values(tools)) {\n\t\t\tif (!tool.kbd || (!tool.readonlyOk && editor.getInstanceState().isReadonly)) {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tif (SKIP_KBDS.includes(tool.id)) continue\n\n\t\t\thot(getHotkeysStringFromKbd(tool.kbd), (event) => {\n\t\t\t\tif (areShortcutsDisabled(editor)) return\n\t\t\t\tpreventDefault(event)\n\t\t\t\ttool.onSelect('kbd')\n\t\t\t})\n\t\t}\n\n\t\thot(',', (e) => {\n\t\t\t// Skip if shortcuts are disabled\n\t\t\tif (areShortcutsDisabled(editor)) return\n\n\t\t\t// Don't press again if already pressed\n\t\t\tif (editor.inputs.keys.has('Comma')) return\n\n\t\t\tpreventDefault(e) // prevent whatever would normally happen\n\t\t\teditor.focus() // Focus if not already focused\n\n\t\t\teditor.inputs.keys.add('Comma')\n\n\t\t\tconst { x, y, z } = editor.inputs.currentPagePoint\n\t\t\tconst screenpoints = editor.pageToScreen({ x, y })\n\n\t\t\tconst info: TLPointerEventInfo = {\n\t\t\t\ttype: 'pointer',\n\t\t\t\tname: 'pointer_down',\n\t\t\t\tpoint: { x: screenpoints.x, y: screenpoints.y, z },\n\t\t\t\tshiftKey: e.shiftKey,\n\t\t\t\taltKey: e.altKey,\n\t\t\t\tctrlKey: e.metaKey || e.ctrlKey,\n\t\t\t\tpointerId: 0,\n\t\t\t\tbutton: 0,\n\t\t\t\tisPen: editor.getInstanceState().isPenMode,\n\t\t\t\ttarget: 'canvas',\n\t\t\t}\n\n\t\t\teditor.dispatch(info)\n\t\t})\n\n\t\thotUp(',', (e) => {\n\t\t\tif (areShortcutsDisabled(editor)) return\n\t\t\tif (!editor.inputs.keys.has('Comma')) return\n\n\t\t\teditor.inputs.keys.delete('Comma')\n\n\t\t\tconst { x, y, z } = editor.inputs.currentScreenPoint\n\t\t\tconst info: TLPointerEventInfo = {\n\t\t\t\ttype: 'pointer',\n\t\t\t\tname: 'pointer_up',\n\t\t\t\tpoint: { x, y, z },\n\t\t\t\tshiftKey: e.shiftKey,\n\t\t\t\taltKey: e.altKey,\n\t\t\t\tctrlKey: e.metaKey || e.ctrlKey,\n\t\t\t\tpointerId: 0,\n\t\t\t\tbutton: 0,\n\t\t\t\tisPen: editor.getInstanceState().isPenMode,\n\t\t\t\ttarget: 'canvas',\n\t\t\t}\n\n\t\t\teditor.dispatch(info)\n\t\t})\n\n\t\treturn () => {\n\t\t\tdisposables.forEach((d) => d())\n\t\t}\n\t}, [actions, tools, isReadonlyMode, editor, isFocused])\n}\n\nfunction getHotkeysStringFromKbd(kbd: string) {\n\treturn getKeys(kbd)\n\t\t.map((kbd) => {\n\t\t\tlet str = ''\n\t\t\tconst chars = kbd.split('')\n\t\t\tif (chars.length === 1) {\n\t\t\t\tstr = chars[0]\n\t\t\t} else {\n\t\t\t\tif (chars[0] === '!') {\n\t\t\t\t\tstr = `shift+${chars[1]}`\n\t\t\t\t} else if (chars[0] === '?') {\n\t\t\t\t\tif (chars.length === 3 && chars[1] === '!') {\n\t\t\t\t\t\tstr = `alt+shift+${chars[2]}`\n\t\t\t\t\t} else {\n\t\t\t\t\t\tstr = `alt+${chars[1]}`\n\t\t\t\t\t}\n\t\t\t\t} else if (chars[0] === '$') {\n\t\t\t\t\tif (chars[1] === '!') {\n\t\t\t\t\t\tstr = `cmd+shift+${chars[2]},ctrl+shift+${chars[2]}`\n\t\t\t\t\t} else if (chars[1] === '?') {\n\t\t\t\t\t\tstr = `cmd+\u2325+${chars[2]},ctrl+alt+${chars[2]}`\n\t\t\t\t\t} else {\n\t\t\t\t\t\tstr = `cmd+${chars[1]},ctrl+${chars[1]}`\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tstr = kbd\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn str\n\t\t})\n\t\t.join(',')\n}\n\n// Logic to split kbd string from hotkeys-js util.\nfunction getKeys(key: string) {\n\tif (typeof key !== 'string') key = ''\n\tkey = key.replace(/\\s/g, '')\n\tconst keys = key.split(',')\n\tlet index = keys.lastIndexOf('')\n\n\tfor (; index >= 0; ) {\n\t\tkeys[index - 1] += ','\n\t\tkeys.splice(index, 1)\n\t\tindex = keys.lastIndexOf('')\n\t}\n\n\treturn keys\n}\n\nexport function areShortcutsDisabled(editor: Editor) {\n\treturn editor.getIsMenuOpen() || editor.getEditingShapeId() !== null || editor.getCrashingError()\n}\n"], -- "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,oBAAgF;AAChF,wBAAoB;AACpB,mBAA0B;AAC1B,qBAA2B;AAC3B,yBAA4B;AAC5B,sBAAyB;AAEzB,MAAM,YAAY;AAAA;AAAA,EAEjB;AAAA,EACA;AAAA,EACA;AAAA;AAAA,EAEA;AACD;AAGO,SAAS,uBAAuB;AACtC,QAAM,aAAS,yBAAU;AAEzB,QAAM,qBAAiB,gCAAY;AACnC,QAAM,cAAU,2BAAW;AAC3B,QAAM,YAAQ,0BAAS;AACvB,QAAM,gBAAY,wBAAS,cAAc,MAAM,OAAO,iBAAiB,EAAE,WAAW,CAAC,MAAM,CAAC;AAC5F,8BAAU,MAAM;AACf,QAAI,CAAC,UAAW;AAEhB,UAAM,cAAc,IAAI,MAAkB;AAE1C,UAAM,MAAM,CAAC,MAAc,aAA6C;AACvE,4BAAAA,SAAQ,MAAM,EAAE,SAAS,SAAS,KAAK,GAAG,QAAQ;AAClD,kBAAY,KAAK,MAAM;AACtB,0BAAAA,QAAQ,OAAO,MAAM,QAAQ;AAAA,MAC9B,CAAC;AAAA,IACF;AAEA,UAAM,QAAQ,CAAC,MAAc,aAA6C;AACzE,4BAAAA,SAAQ,MAAM,EAAE,SAAS,SAAS,MAAM,OAAO,MAAM,SAAS,MAAM,GAAG,QAAQ;AAC/E,kBAAY,KAAK,MAAM;AACtB,0BAAAA,QAAQ,OAAO,MAAM,QAAQ;AAAA,MAC9B,CAAC;AAAA,IACF;AAIA,eAAW,UAAU,OAAO,OAAO,OAAO,GAAG;AAC5C,UAAI,CAAC,OAAO,IAAK;AACjB,UAAI,kBAAkB,CAAC,OAAO,WAAY;AAC1C,UAAI,UAAU,SAAS,OAAO,EAAE,EAAG;AAEnC,UAAI,wBAAwB,OAAO,GAAG,GAAG,CAAC,UAAU;AACnD,YAAI,qBAAqB,MAAM,EAAG;AAClC,0CAAe,KAAK;AACpB,eAAO,SAAS,KAAK;AAAA,MACtB,CAAC;AAAA,IACF;AAEA,eAAW,QAAQ,OAAO,OAAO,KAAK,GAAG;AACxC,UAAI,CAAC,KAAK,OAAQ,CAAC,KAAK,cAAc,OAAO,iBAAiB,EAAE,YAAa;AAC5E;AAAA,MACD;AAEA,UAAI,UAAU,SAAS,KAAK,EAAE,EAAG;AAEjC,UAAI,wBAAwB,KAAK,GAAG,GAAG,CAAC,UAAU;AACjD,YAAI,qBAAqB,MAAM,EAAG;AAClC,0CAAe,KAAK;AACpB,aAAK,SAAS,KAAK;AAAA,MACpB,CAAC;AAAA,IACF;AAEA,QAAI,KAAK,CAAC,MAAM;AAEf,UAAI,qBAAqB,MAAM,EAAG;AAGlC,UAAI,OAAO,OAAO,KAAK,IAAI,OAAO,EAAG;AAErC,wCAAe,CAAC;AAChB,aAAO,MAAM;AAEb,aAAO,OAAO,KAAK,IAAI,OAAO;AAE9B,YAAM,EAAE,GAAG,GAAG,EAAE,IAAI,OAAO,OAAO;AAClC,YAAM,eAAe,OAAO,aAAa,EAAE,GAAG,EAAE,CAAC;AAEjD,YAAM,OAA2B;AAAA,QAChC,MAAM;AAAA,QACN,MAAM;AAAA,QACN,OAAO,EAAE,GAAG,aAAa,GAAG,GAAG,aAAa,GAAG,EAAE;AAAA,QACjD,UAAU,EAAE;AAAA,QACZ,QAAQ,EAAE;AAAA,QACV,SAAS,EAAE,WAAW,EAAE;AAAA,QACxB,WAAW;AAAA,QACX,QAAQ;AAAA,QACR,OAAO,OAAO,iBAAiB,EAAE;AAAA,QACjC,QAAQ;AAAA,MACT;AAEA,aAAO,SAAS,IAAI;AAAA,IACrB,CAAC;AAED,UAAM,KAAK,CAAC,MAAM;AACjB,UAAI,qBAAqB,MAAM,EAAG;AAClC,UAAI,CAAC,OAAO,OAAO,KAAK,IAAI,OAAO,EAAG;AAEtC,aAAO,OAAO,KAAK,OAAO,OAAO;AAEjC,YAAM,EAAE,GAAG,GAAG,EAAE,IAAI,OAAO,OAAO;AAClC,YAAM,OAA2B;AAAA,QAChC,MAAM;AAAA,QACN,MAAM;AAAA,QACN,OAAO,EAAE,GAAG,GAAG,EAAE;AAAA,QACjB,UAAU,EAAE;AAAA,QACZ,QAAQ,EAAE;AAAA,QACV,SAAS,EAAE,WAAW,EAAE;AAAA,QACxB,WAAW;AAAA,QACX,QAAQ;AAAA,QACR,OAAO,OAAO,iBAAiB,EAAE;AAAA,QACjC,QAAQ;AAAA,MACT;AAEA,aAAO,SAAS,IAAI;AAAA,IACrB,CAAC;AAED,WAAO,MAAM;AACZ,kBAAY,QAAQ,CAAC,MAAM,EAAE,CAAC;AAAA,IAC/B;AAAA,EACD,GAAG,CAAC,SAAS,OAAO,gBAAgB,QAAQ,SAAS,CAAC;AACvD;AAEA,SAAS,wBAAwB,KAAa;AAC7C,SAAO,QAAQ,GAAG,EAChB,IAAI,CAACC,SAAQ;AACb,QAAI,MAAM;AACV,UAAM,QAAQA,KAAI,MAAM,EAAE;AAC1B,QAAI,MAAM,WAAW,GAAG;AACvB,YAAM,MAAM,CAAC;AAAA,IACd,OAAO;AACN,UAAI,MAAM,CAAC,MAAM,KAAK;AACrB,cAAM,SAAS,MAAM,CAAC,CAAC;AAAA,MACxB,WAAW,MAAM,CAAC,MAAM,KAAK;AAC5B,YAAI,MAAM,WAAW,KAAK,MAAM,CAAC,MAAM,KAAK;AAC3C,gBAAM,aAAa,MAAM,CAAC,CAAC;AAAA,QAC5B,OAAO;AACN,gBAAM,OAAO,MAAM,CAAC,CAAC;AAAA,QACtB;AAAA,MACD,WAAW,MAAM,CAAC,MAAM,KAAK;AAC5B,YAAI,MAAM,CAAC,MAAM,KAAK;AACrB,gBAAM,aAAa,MAAM,CAAC,CAAC,eAAe,MAAM,CAAC,CAAC;AAAA,QACnD,WAAW,MAAM,CAAC,MAAM,KAAK;AAC5B,gBAAM,cAAS,MAAM,CAAC,CAAC,aAAa,MAAM,CAAC,CAAC;AAAA,QAC7C,OAAO;AACN,gBAAM,OAAO,MAAM,CAAC,CAAC,SAAS,MAAM,CAAC,CAAC;AAAA,QACvC;AAAA,MACD,OAAO;AACN,cAAMA;AAAA,MACP;AAAA,IACD;AACA,WAAO;AAAA,EACR,CAAC,EACA,KAAK,GAAG;AACX;AAGA,SAAS,QAAQ,KAAa;AAC7B,MAAI,OAAO,QAAQ,SAAU,OAAM;AACnC,QAAM,IAAI,QAAQ,OAAO,EAAE;AAC3B,QAAM,OAAO,IAAI,MAAM,GAAG;AAC1B,MAAI,QAAQ,KAAK,YAAY,EAAE;AAE/B,SAAO,SAAS,KAAK;AACpB,SAAK,QAAQ,CAAC,KAAK;AACnB,SAAK,OAAO,OAAO,CAAC;AACpB,YAAQ,KAAK,YAAY,EAAE;AAAA,EAC5B;AAEA,SAAO;AACR;AAEO,SAAS,qBAAqB,QAAgB;AACpD,SAAO,OAAO,cAAc,KAAK,OAAO,kBAAkB,MAAM,QAAQ,OAAO,iBAAiB;AACjG;", -+ "sourcesContent": ["import { Editor, TLPointerEventInfo, preventDefault, useContainer, useEditor, useValue } from '@tldraw/editor'\nimport hotkeys from 'hotkeys-js'\nimport { useEffect } from 'react'\nimport { useActions } from '../context/actions'\nimport { useReadonly } from './useReadonly'\nimport { useTools } from './useTools'\n\nconst SKIP_KBDS = [\n\t// we set these in useNativeClipboardEvents instead\n\t'copy',\n\t'cut',\n\t'paste',\n\t// There's also an upload asset action, so we don't want to set the kbd twice\n\t'asset',\n]\n\n/** @public */\nexport function useKeyboardShortcuts() {\n\tconst container = useContainer();\n\tconst editor = useEditor()\n\n\tconst isReadonlyMode = useReadonly()\n\tconst actions = useActions()\n\tconst tools = useTools()\n\tconst isFocused = useValue('is focused', () => editor.getInstanceState().isFocused, [editor])\n\tuseEffect(() => {\n\t\tif (!isFocused) return\n\n\t\tconst disposables = new Array<() => void>()\n\n\t\tconst hot = (keys: string, callback: (event: KeyboardEvent) => void) => {\n\t\t\thotkeys(keys, { element: container.ownerDocument.body }, callback)\n\t\t\tdisposables.push(() => {\n\t\t\t\thotkeys.unbind(keys, callback)\n\t\t\t})\n\t\t}\n\n\t\tconst hotUp = (keys: string, callback: (event: KeyboardEvent) => void) => {\n\t\t\thotkeys(keys, { element: container.ownerDocument.body, keyup: true, keydown: false }, callback)\n\t\t\tdisposables.push(() => {\n\t\t\t\thotkeys.unbind(keys, callback)\n\t\t\t})\n\t\t}\n\n\t\t// Add hotkeys for actions and tools.\n\t\t// Except those that in SKIP_KBDS!\n\t\tfor (const action of Object.values(actions)) {\n\t\t\tif (!action.kbd) continue\n\t\t\tif (isReadonlyMode && !action.readonlyOk) continue\n\t\t\tif (SKIP_KBDS.includes(action.id)) continue\n\n\t\t\thot(getHotkeysStringFromKbd(action.kbd), (event) => {\n\t\t\t\tif (areShortcutsDisabled(editor)) return\n\t\t\t\tpreventDefault(event)\n\t\t\t\taction.onSelect('kbd')\n\t\t\t})\n\t\t}\n\n\t\tfor (const tool of Object.values(tools)) {\n\t\t\tif (!tool.kbd || (!tool.readonlyOk && editor.getInstanceState().isReadonly)) {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tif (SKIP_KBDS.includes(tool.id)) continue\n\n\t\t\thot(getHotkeysStringFromKbd(tool.kbd), (event) => {\n\t\t\t\tif (areShortcutsDisabled(editor)) return\n\t\t\t\tpreventDefault(event)\n\t\t\t\ttool.onSelect('kbd')\n\t\t\t})\n\t\t}\n\n\t\thot(',', (e) => {\n\t\t\t// Skip if shortcuts are disabled\n\t\t\tif (areShortcutsDisabled(editor)) return\n\n\t\t\t// Don't press again if already pressed\n\t\t\tif (editor.inputs.keys.has('Comma')) return\n\n\t\t\tpreventDefault(e) // prevent whatever would normally happen\n\t\t\teditor.focus() // Focus if not already focused\n\n\t\t\teditor.inputs.keys.add('Comma')\n\n\t\t\tconst { x, y, z } = editor.inputs.currentPagePoint\n\t\t\tconst screenpoints = editor.pageToScreen({ x, y })\n\n\t\t\tconst info: TLPointerEventInfo = {\n\t\t\t\ttype: 'pointer',\n\t\t\t\tname: 'pointer_down',\n\t\t\t\tpoint: { x: screenpoints.x, y: screenpoints.y, z },\n\t\t\t\tshiftKey: e.shiftKey,\n\t\t\t\taltKey: e.altKey,\n\t\t\t\tctrlKey: e.metaKey || e.ctrlKey,\n\t\t\t\tpointerId: 0,\n\t\t\t\tbutton: 0,\n\t\t\t\tisPen: editor.getInstanceState().isPenMode,\n\t\t\t\ttarget: 'canvas',\n\t\t\t}\n\n\t\t\teditor.dispatch(info)\n\t\t})\n\n\t\thotUp(',', (e) => {\n\t\t\tif (areShortcutsDisabled(editor)) return\n\t\t\tif (!editor.inputs.keys.has('Comma')) return\n\n\t\t\teditor.inputs.keys.delete('Comma')\n\n\t\t\tconst { x, y, z } = editor.inputs.currentScreenPoint\n\t\t\tconst info: TLPointerEventInfo = {\n\t\t\t\ttype: 'pointer',\n\t\t\t\tname: 'pointer_up',\n\t\t\t\tpoint: { x, y, z },\n\t\t\t\tshiftKey: e.shiftKey,\n\t\t\t\taltKey: e.altKey,\n\t\t\t\tctrlKey: e.metaKey || e.ctrlKey,\n\t\t\t\tpointerId: 0,\n\t\t\t\tbutton: 0,\n\t\t\t\tisPen: editor.getInstanceState().isPenMode,\n\t\t\t\ttarget: 'canvas',\n\t\t\t}\n\n\t\t\teditor.dispatch(info)\n\t\t})\n\n\t\treturn () => {\n\t\t\tdisposables.forEach((d) => d())\n\t\t}\n\t}, [actions, tools, isReadonlyMode, editor, container, isFocused])\n}\n\nfunction getHotkeysStringFromKbd(kbd: string) {\n\treturn getKeys(kbd)\n\t\t.map((kbd) => {\n\t\t\tlet str = ''\n\t\t\tconst chars = kbd.split('')\n\t\t\tif (chars.length === 1) {\n\t\t\t\tstr = chars[0]\n\t\t\t} else {\n\t\t\t\tif (chars[0] === '!') {\n\t\t\t\t\tstr = `shift+${chars[1]}`\n\t\t\t\t} else if (chars[0] === '?') {\n\t\t\t\t\tif (chars.length === 3 && chars[1] === '!') {\n\t\t\t\t\t\tstr = `alt+shift+${chars[2]}`\n\t\t\t\t\t} else {\n\t\t\t\t\t\tstr = `alt+${chars[1]}`\n\t\t\t\t\t}\n\t\t\t\t} else if (chars[0] === '$') {\n\t\t\t\t\tif (chars[1] === '!') {\n\t\t\t\t\t\tstr = `cmd+shift+${chars[2]},ctrl+shift+${chars[2]}`\n\t\t\t\t\t} else if (chars[1] === '?') {\n\t\t\t\t\t\tstr = `cmd+\u2325+${chars[2]},ctrl+alt+${chars[2]}`\n\t\t\t\t\t} else {\n\t\t\t\t\t\tstr = `cmd+${chars[1]},ctrl+${chars[1]}`\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tstr = kbd\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn str\n\t\t})\n\t\t.join(',')\n}\n\n// Logic to split kbd string from hotkeys-js util.\nfunction getKeys(key: string) {\n\tif (typeof key !== 'string') key = ''\n\tkey = key.replace(/\\s/g, '')\n\tconst keys = key.split(',')\n\tlet index = keys.lastIndexOf('')\n\n\tfor (; index >= 0; ) {\n\t\tkeys[index - 1] += ','\n\t\tkeys.splice(index, 1)\n\t\tindex = keys.lastIndexOf('')\n\t}\n\n\treturn keys\n}\n\nexport function areShortcutsDisabled(editor: Editor) {\n\treturn editor.getIsMenuOpen() || editor.getEditingShapeId() !== null || editor.getCrashingError()\n}\n"], -+ "mappings": "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", - "names": ["hotkeys", "kbd"] - } -diff --git a/node_modules/tldraw/dist-esm/index.d.mts b/node_modules/tldraw/dist-esm/index.d.mts -index 4ccc831..77885a5 100644 ---- a/node_modules/tldraw/dist-esm/index.d.mts -+++ b/node_modules/tldraw/dist-esm/index.d.mts -@@ -48,6 +48,7 @@ import { TLArrowShapeArrowheadStyle } from '@tldraw/editor'; - import { TLArrowShapeProps } from '@tldraw/editor'; - import { TLAsset } from '@tldraw/editor'; - import { TLAssetId } from '@tldraw/editor'; -+import { TLAssetStore } from '@tldraw/editor'; - import { TLBookmarkShape } from '@tldraw/editor'; - import { TLBookmarkShapeProps } from '@tldraw/editor'; - import { TLClickEventInfo } from '@tldraw/editor'; -@@ -1829,6 +1830,10 @@ export declare interface TldrawImageProps extends TLImageExportOptions { - * The license key. - */ - licenseKey?: string; -+ /** -+ * How should this store resolve assets? -+ */ -+ assets?: TLAssetStore; - /** - * Asset URL overrides. - */ -diff --git a/node_modules/tldraw/dist-esm/lib/TldrawImage.mjs b/node_modules/tldraw/dist-esm/lib/TldrawImage.mjs -index ac9ec2b..f8645af 100644 ---- a/node_modules/tldraw/dist-esm/lib/TldrawImage.mjs -+++ b/node_modules/tldraw/dist-esm/lib/TldrawImage.mjs -@@ -23,7 +23,11 @@ const TldrawImage = memo(function TldrawImage2(props) { - () => [...defaultBindingUtils, ...bindingUtils], - [bindingUtils] - ); -- const store = useTLStore({ snapshot: props.snapshot, shapeUtils: shapeUtilsWithDefaults }); -+ const store = useTLStore({ -+ assets: props.assets, -+ snapshot: props.snapshot, -+ shapeUtils: shapeUtilsWithDefaults -+ }); - const assets = useDefaultEditorAssetsWithOverrides(props.assetUrls); - const { done: preloadingComplete, error: preloadingError } = usePreloadAssets(assets); - const { -diff --git a/node_modules/tldraw/dist-esm/lib/TldrawImage.mjs.map b/node_modules/tldraw/dist-esm/lib/TldrawImage.mjs.map -index d4f5339..ee4c395 100644 ---- a/node_modules/tldraw/dist-esm/lib/TldrawImage.mjs.map -+++ b/node_modules/tldraw/dist-esm/lib/TldrawImage.mjs.map -@@ -1,7 +1,7 @@ - { - "version": 3, - "sources": ["../../src/lib/TldrawImage.tsx"], -- "sourcesContent": ["import {\n\tDefaultSpinner,\n\tEditor,\n\tErrorScreen,\n\tLoadingScreen,\n\tTLAnyBindingUtilConstructor,\n\tTLAnyShapeUtilConstructor,\n\tTLEditorSnapshot,\n\tTLImageExportOptions,\n\tTLPageId,\n\tTLStoreSnapshot,\n\tuseShallowArrayIdentity,\n\tuseTLStore,\n} from '@tldraw/editor'\nimport { memo, useLayoutEffect, useMemo, useState } from 'react'\nimport { defaultBindingUtils } from './defaultBindingUtils'\nimport { defaultShapeUtils } from './defaultShapeUtils'\nimport { TLUiAssetUrlOverrides } from './ui/assetUrls'\nimport { usePreloadAssets } from './ui/hooks/usePreloadAssets'\nimport { getSvgAsImage } from './utils/export/export'\nimport { useDefaultEditorAssetsWithOverrides } from './utils/static-assets/assetUrls'\n\n/** @public */\nexport interface TldrawImageProps extends TLImageExportOptions {\n\t/**\n\t * The snapshot to display.\n\t */\n\tsnapshot: Partial | TLStoreSnapshot\n\n\t/**\n\t * The image format to use. Defaults to 'svg'.\n\t */\n\tformat?: 'svg' | 'png'\n\n\t/**\n\t * The page to display. Defaults to the first page.\n\t */\n\tpageId?: TLPageId\n\n\t/**\n\t * Additional shape utils to use.\n\t */\n\tshapeUtils?: readonly TLAnyShapeUtilConstructor[]\n\t/**\n\t * Additional binding utils to use.\n\t */\n\tbindingUtils?: readonly TLAnyBindingUtilConstructor[]\n\t/**\n\t * The license key.\n\t */\n\tlicenseKey?: string\n\t/**\n\t * Asset URL overrides.\n\t */\n\tassetUrls?: TLUiAssetUrlOverrides\n}\n\n/**\n * A renderered SVG image of a Tldraw snapshot.\n *\n * @example\n * ```tsx\n * \n * ```\n *\n * @public\n * @react\n */\nexport const TldrawImage = memo(function TldrawImage(props: TldrawImageProps) {\n\tconst [url, setUrl] = useState(null)\n\tconst [container, setContainer] = useState(null)\n\n\tconst shapeUtils = useShallowArrayIdentity(props.shapeUtils ?? [])\n\tconst shapeUtilsWithDefaults = useMemo(() => [...defaultShapeUtils, ...shapeUtils], [shapeUtils])\n\tconst bindingUtils = useShallowArrayIdentity(props.bindingUtils ?? [])\n\tconst bindingUtilsWithDefaults = useMemo(\n\t\t() => [...defaultBindingUtils, ...bindingUtils],\n\t\t[bindingUtils]\n\t)\n\tconst store = useTLStore({ snapshot: props.snapshot, shapeUtils: shapeUtilsWithDefaults })\n\n\tconst assets = useDefaultEditorAssetsWithOverrides(props.assetUrls)\n\tconst { done: preloadingComplete, error: preloadingError } = usePreloadAssets(assets)\n\n\tconst {\n\t\tpageId,\n\t\tbounds,\n\t\tscale,\n\t\tbackground,\n\t\tpadding,\n\t\tdarkMode,\n\t\tpreserveAspectRatio,\n\t\tformat = 'svg',\n\t\tlicenseKey,\n\t} = props\n\n\tuseLayoutEffect(() => {\n\t\tif (!container) return\n\t\tif (!store) return\n\t\tif (!preloadingComplete) return\n\n\t\tlet isCancelled = false\n\n\t\tconst tempElm = document.createElement('div')\n\t\tcontainer.appendChild(tempElm)\n\t\tcontainer.classList.add('tl-container', 'tl-theme__light')\n\n\t\tconst editor = new Editor({\n\t\t\tstore,\n\t\t\tshapeUtils: shapeUtilsWithDefaults,\n\t\t\tbindingUtils: bindingUtilsWithDefaults,\n\t\t\ttools: [],\n\t\t\tgetContainer: () => tempElm,\n\t\t\tlicenseKey,\n\t\t})\n\n\t\tif (pageId) editor.setCurrentPage(pageId)\n\n\t\tconst shapeIds = editor.getCurrentPageShapeIds()\n\n\t\tasync function setSvg() {\n\t\t\tconst svgResult = await editor.getSvgString([...shapeIds], {\n\t\t\t\tbounds,\n\t\t\t\tscale,\n\t\t\t\tbackground,\n\t\t\t\tpadding,\n\t\t\t\tdarkMode,\n\t\t\t\tpreserveAspectRatio,\n\t\t\t})\n\n\t\t\tif (svgResult && !isCancelled) {\n\t\t\t\tif (format === 'svg') {\n\t\t\t\t\tif (!isCancelled) {\n\t\t\t\t\t\tconst blob = new Blob([svgResult.svg], { type: 'image/svg+xml' })\n\t\t\t\t\t\tconst url = URL.createObjectURL(blob)\n\t\t\t\t\t\tsetUrl(url)\n\t\t\t\t\t}\n\t\t\t\t} else if (format === 'png') {\n\t\t\t\t\tconst blob = await getSvgAsImage(editor, svgResult.svg, {\n\t\t\t\t\t\ttype: format,\n\t\t\t\t\t\tquality: 1,\n\t\t\t\t\t\tscale: 2,\n\t\t\t\t\t\twidth: svgResult.width,\n\t\t\t\t\t\theight: svgResult.height,\n\t\t\t\t\t})\n\t\t\t\t\tif (blob && !isCancelled) {\n\t\t\t\t\t\tconst url = URL.createObjectURL(blob)\n\t\t\t\t\t\tsetUrl(url)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\teditor.dispose()\n\t\t}\n\n\t\tsetSvg()\n\n\t\treturn () => {\n\t\t\tisCancelled = true\n\t\t}\n\t}, [\n\t\tformat,\n\t\tcontainer,\n\t\tstore,\n\t\tshapeUtilsWithDefaults,\n\t\tbindingUtilsWithDefaults,\n\t\tpageId,\n\t\tbounds,\n\t\tscale,\n\t\tbackground,\n\t\tpadding,\n\t\tdarkMode,\n\t\tpreserveAspectRatio,\n\t\tpreloadingComplete,\n\t\tpreloadingError,\n\t\tlicenseKey,\n\t])\n\n\tif (preloadingError) {\n\t\treturn Could not load assets.\n\t}\n\n\tif (!preloadingComplete) {\n\t\treturn (\n\t\t\t\n\t\t\t\t\n\t\t\t\n\t\t)\n\t}\n\n\treturn (\n\t\t
\n\t\t\t{url && (\n\t\t\t\t\n\t\t\t)}\n\t\t
\n\t)\n})\n"], -- "mappings": "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", -+ "sourcesContent": ["import {\n\tDefaultSpinner,\n\tEditor,\n\tErrorScreen,\n\tLoadingScreen,\n\tTLAnyBindingUtilConstructor,\n\tTLAnyShapeUtilConstructor,\n\tTLAssetStore,\n\tTLEditorSnapshot,\n\tTLImageExportOptions,\n\tTLPageId,\n\tTLStoreSnapshot,\n\tuseShallowArrayIdentity,\n\tuseTLStore,\n} from '@tldraw/editor'\nimport { memo, useLayoutEffect, useMemo, useState } from 'react'\nimport { defaultBindingUtils } from './defaultBindingUtils'\nimport { defaultShapeUtils } from './defaultShapeUtils'\nimport { TLUiAssetUrlOverrides } from './ui/assetUrls'\nimport { usePreloadAssets } from './ui/hooks/usePreloadAssets'\nimport { getSvgAsImage } from './utils/export/export'\nimport { useDefaultEditorAssetsWithOverrides } from './utils/static-assets/assetUrls'\n\n/** @public */\nexport interface TldrawImageProps extends TLImageExportOptions {\n\t/**\n\t * The snapshot to display.\n\t */\n\tsnapshot: Partial | TLStoreSnapshot\n\n\t/**\n\t * The image format to use. Defaults to 'svg'.\n\t */\n\tformat?: 'svg' | 'png'\n\n\t/**\n\t * The page to display. Defaults to the first page.\n\t */\n\tpageId?: TLPageId\n\n\t/**\n\t * Additional shape utils to use.\n\t */\n\tshapeUtils?: readonly TLAnyShapeUtilConstructor[]\n\t/**\n\t * Additional binding utils to use.\n\t */\n\tbindingUtils?: readonly TLAnyBindingUtilConstructor[]\n\t/**\n\t * The license key.\n\t */\n\tlicenseKey?: string\n\t/**\n\t * How should this store resolve assets?\n\t */\n\tassets?: TLAssetStore\n\t/**\n\t * Asset URL overrides.\n\t */\n\tassetUrls?: TLUiAssetUrlOverrides\n}\n\n/**\n * A renderered SVG image of a Tldraw snapshot.\n *\n * @example\n * ```tsx\n * \n * ```\n *\n * @public\n * @react\n */\nexport const TldrawImage = memo(function TldrawImage(props: TldrawImageProps) {\n\tconst [url, setUrl] = useState(null)\n\tconst [container, setContainer] = useState(null)\n\n\tconst shapeUtils = useShallowArrayIdentity(props.shapeUtils ?? [])\n\tconst shapeUtilsWithDefaults = useMemo(() => [...defaultShapeUtils, ...shapeUtils], [shapeUtils])\n\tconst bindingUtils = useShallowArrayIdentity(props.bindingUtils ?? [])\n\tconst bindingUtilsWithDefaults = useMemo(\n\t\t() => [...defaultBindingUtils, ...bindingUtils],\n\t\t[bindingUtils]\n\t)\n\tconst store = useTLStore({\n\t\tassets: props.assets,\n\t\tsnapshot: props.snapshot,\n\t\tshapeUtils: shapeUtilsWithDefaults,\n\t})\n\n\tconst assets = useDefaultEditorAssetsWithOverrides(props.assetUrls)\n\tconst { done: preloadingComplete, error: preloadingError } = usePreloadAssets(assets)\n\n\tconst {\n\t\tpageId,\n\t\tbounds,\n\t\tscale,\n\t\tbackground,\n\t\tpadding,\n\t\tdarkMode,\n\t\tpreserveAspectRatio,\n\t\tformat = 'svg',\n\t\tlicenseKey,\n\t} = props\n\n\tuseLayoutEffect(() => {\n\t\tif (!container) return\n\t\tif (!store) return\n\t\tif (!preloadingComplete) return\n\n\t\tlet isCancelled = false\n\n\t\tconst tempElm = document.createElement('div')\n\t\tcontainer.appendChild(tempElm)\n\t\tcontainer.classList.add('tl-container', 'tl-theme__light')\n\n\t\tconst editor = new Editor({\n\t\t\tstore,\n\t\t\tshapeUtils: shapeUtilsWithDefaults,\n\t\t\tbindingUtils: bindingUtilsWithDefaults,\n\t\t\ttools: [],\n\t\t\tgetContainer: () => tempElm,\n\t\t\tlicenseKey,\n\t\t})\n\n\t\tif (pageId) editor.setCurrentPage(pageId)\n\n\t\tconst shapeIds = editor.getCurrentPageShapeIds()\n\n\t\tasync function setSvg() {\n\t\t\tconst svgResult = await editor.getSvgString([...shapeIds], {\n\t\t\t\tbounds,\n\t\t\t\tscale,\n\t\t\t\tbackground,\n\t\t\t\tpadding,\n\t\t\t\tdarkMode,\n\t\t\t\tpreserveAspectRatio,\n\t\t\t})\n\n\t\t\tif (svgResult && !isCancelled) {\n\t\t\t\tif (format === 'svg') {\n\t\t\t\t\tif (!isCancelled) {\n\t\t\t\t\t\tconst blob = new Blob([svgResult.svg], { type: 'image/svg+xml' })\n\t\t\t\t\t\tconst url = URL.createObjectURL(blob)\n\t\t\t\t\t\tsetUrl(url)\n\t\t\t\t\t}\n\t\t\t\t} else if (format === 'png') {\n\t\t\t\t\tconst blob = await getSvgAsImage(editor, svgResult.svg, {\n\t\t\t\t\t\ttype: format,\n\t\t\t\t\t\tquality: 1,\n\t\t\t\t\t\tscale: 2,\n\t\t\t\t\t\twidth: svgResult.width,\n\t\t\t\t\t\theight: svgResult.height,\n\t\t\t\t\t})\n\t\t\t\t\tif (blob && !isCancelled) {\n\t\t\t\t\t\tconst url = URL.createObjectURL(blob)\n\t\t\t\t\t\tsetUrl(url)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\teditor.dispose()\n\t\t}\n\n\t\tsetSvg()\n\n\t\treturn () => {\n\t\t\tisCancelled = true\n\t\t}\n\t}, [\n\t\tformat,\n\t\tcontainer,\n\t\tstore,\n\t\tshapeUtilsWithDefaults,\n\t\tbindingUtilsWithDefaults,\n\t\tpageId,\n\t\tbounds,\n\t\tscale,\n\t\tbackground,\n\t\tpadding,\n\t\tdarkMode,\n\t\tpreserveAspectRatio,\n\t\tpreloadingComplete,\n\t\tpreloadingError,\n\t\tlicenseKey,\n\t])\n\n\tif (preloadingError) {\n\t\treturn Could not load assets.\n\t}\n\n\tif (!preloadingComplete) {\n\t\treturn (\n\t\t\t\n\t\t\t\t\n\t\t\t\n\t\t)\n\t}\n\n\treturn (\n\t\t
\n\t\t\t{url && (\n\t\t\t\t\n\t\t\t)}\n\t\t
\n\t)\n})\n"], -+ "mappings": "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", - "names": ["TldrawImage", "url"] - } -diff --git a/node_modules/tldraw/dist-esm/lib/shapes/shared/TextHelpers.mjs b/node_modules/tldraw/dist-esm/lib/shapes/shared/TextHelpers.mjs -index 35bdaa2..a46fec6 100644 ---- a/node_modules/tldraw/dist-esm/lib/shapes/shared/TextHelpers.mjs -+++ b/node_modules/tldraw/dist-esm/lib/shapes/shared/TextHelpers.mjs -@@ -37,7 +37,7 @@ class TextHelpers { - } - if (initialFocus === document.body) { - field.blur(); -- } else if (initialFocus instanceof HTMLElement && initialFocus !== field) { -+ } else if (initialFocus?.instanceOf(HTMLElement) && initialFocus !== field) { - initialFocus.focus(); - } - } -diff --git a/node_modules/tldraw/dist-esm/lib/shapes/shared/TextHelpers.mjs.map b/node_modules/tldraw/dist-esm/lib/shapes/shared/TextHelpers.mjs.map -index 1377b8d..c5e2311 100644 ---- a/node_modules/tldraw/dist-esm/lib/shapes/shared/TextHelpers.mjs.map -+++ b/node_modules/tldraw/dist-esm/lib/shapes/shared/TextHelpers.mjs.map -@@ -1,7 +1,7 @@ - { - "version": 3, - "sources": ["../../../../src/lib/shapes/shared/TextHelpers.ts"], -- "sourcesContent": ["/*!\n * MIT License\n * Adapted (mostly copied) the work of https://github.com/fregante/text-field-edit\n * Copyright (c) Federico Brigante (bfred.it)\n */\n\n// TODO: Most of this file can be moved into a DOM utils library.\n\n/** @internal */\nexport type ReplacerCallback = (substring: string, ...args: unknown[]) => string\n\n/**\t@public */\nexport const INDENT = ' '\n\n/** @internal */\nexport class TextHelpers {\n\tstatic insertTextFirefox(field: HTMLTextAreaElement | HTMLInputElement, text: string): void {\n\t\t// Found on https://www.everythingfrontend.com/blog/insert-text-into-textarea-at-cursor-position.html \uD83C\uDF88\n\t\tfield.setRangeText(\n\t\t\ttext,\n\t\t\tfield.selectionStart || 0,\n\t\t\tfield.selectionEnd || 0,\n\t\t\t'end' // Without this, the cursor is either at the beginning or text remains selected\n\t\t)\n\n\t\tfield.dispatchEvent(\n\t\t\tnew InputEvent('input', {\n\t\t\t\tdata: text,\n\t\t\t\tinputType: 'insertText',\n\t\t\t\tisComposing: false, // TODO: fix @types/jsdom, this shouldn't be required\n\t\t\t})\n\t\t)\n\t}\n\n\t/**\n\t * Inserts text at the cursor\u2019s position, replacing any selection, with **undo** support and by\n\t * firing the input event.\n\t */\n\tstatic insert(field: HTMLTextAreaElement | HTMLInputElement, text: string): void {\n\t\tconst document = field.ownerDocument\n\t\tconst initialFocus = document.activeElement\n\t\tif (initialFocus !== field) {\n\t\t\tfield.focus()\n\t\t}\n\n\t\t// eslint-disable-next-line deprecation/deprecation\n\t\tif (!document.execCommand('insertText', false, text)) {\n\t\t\tTextHelpers.insertTextFirefox(field, text)\n\t\t}\n\n\t\tif (initialFocus === document.body) {\n\t\t\tfield.blur()\n\t\t} else if (initialFocus instanceof HTMLElement && initialFocus !== field) {\n\t\t\tinitialFocus.focus()\n\t\t}\n\t}\n\n\t/**\n\t * Replaces the entire content, equivalent to field.value = text but with **undo** support and by\n\t * firing the input event.\n\t */\n\tstatic set(field: HTMLTextAreaElement | HTMLInputElement, text: string): void {\n\t\tfield.select()\n\t\tTextHelpers.insert(field, text)\n\t}\n\n\t/** Get the selected text in a field or an empty string if nothing is selected. */\n\tstatic getSelection(field: HTMLTextAreaElement | HTMLInputElement): string {\n\t\tconst { selectionStart, selectionEnd } = field\n\t\treturn field.value.slice(\n\t\t\tselectionStart ? selectionStart : undefined,\n\t\t\tselectionEnd ? selectionEnd : undefined\n\t\t)\n\t}\n\n\t/**\n\t * Adds the wrappingText before and after field\u2019s selection (or cursor). If endWrappingText is\n\t * provided, it will be used instead of wrappingText at on the right.\n\t */\n\tstatic wrapSelection(\n\t\tfield: HTMLTextAreaElement | HTMLInputElement,\n\t\twrap: string,\n\t\twrapEnd?: string\n\t): void {\n\t\tconst { selectionStart, selectionEnd } = field\n\t\tconst selection = TextHelpers.getSelection(field)\n\t\tTextHelpers.insert(field, wrap + selection + (wrapEnd ?? wrap))\n\n\t\t// Restore the selection around the previously-selected text\n\t\tfield.selectionStart = (selectionStart || 0) + wrap.length\n\t\tfield.selectionEnd = (selectionEnd || 0) + wrap.length\n\t}\n\n\t/** Finds and replaces strings and regex in the field\u2019s value. */\n\tstatic replace(\n\t\tfield: HTMLTextAreaElement | HTMLInputElement,\n\t\tsearchValue: string | RegExp,\n\t\treplacer: string | ReplacerCallback\n\t): void {\n\t\t/** Remembers how much each match offset should be adjusted */\n\t\tlet drift = 0\n\t\tfield.value.replace(searchValue, (...args): string => {\n\t\t\t// Select current match to replace it later\n\t\t\tconst matchStart = drift + (args[args.length - 2] as number)\n\t\t\tconst matchLength = args[0].length\n\t\t\tfield.selectionStart = matchStart\n\t\t\tfield.selectionEnd = matchStart + matchLength\n\t\t\tconst replacement = typeof replacer === 'string' ? replacer : replacer(...args)\n\t\t\tTextHelpers.insert(field, replacement)\n\t\t\t// Select replacement. Without this, the cursor would be after the replacement\n\t\t\tfield.selectionStart = matchStart\n\t\t\tdrift += replacement.length - matchLength\n\t\t\treturn replacement\n\t\t})\n\t}\n\n\tstatic findLineEnd(value: string, currentEnd: number): number {\n\t\t// Go to the beginning of the last line\n\t\tconst lastLineStart = value.lastIndexOf('\\n', currentEnd - 1) + 1\n\t\t// There's nothing to unindent after the last cursor, so leave it as is\n\t\tif (value.charAt(lastLineStart) !== '\\t') {\n\t\t\treturn currentEnd\n\t\t}\n\t\treturn lastLineStart + 1 // Include the first character, which will be a tab\n\t}\n\n\tstatic indent(element: HTMLTextAreaElement): void {\n\t\tconst { selectionStart, selectionEnd, value } = element\n\t\tconst selectedContrast = value.slice(selectionStart, selectionEnd)\n\t\t// The first line should be indented, even if it starts with \\n\n\t\t// The last line should only be indented if includes any character after \\n\n\t\tconst lineBreakCount = /\\n/g.exec(selectedContrast)?.length\n\n\t\tif (lineBreakCount && lineBreakCount > 0) {\n\t\t\t// Select full first line to replace everything at once\n\t\t\tconst firstLineStart = value.lastIndexOf('\\n', selectionStart - 1) + 1\n\n\t\t\tconst newSelection = element.value.slice(firstLineStart, selectionEnd - 1)\n\t\t\tconst indentedText = newSelection.replace(\n\t\t\t\t/^|\\n/g, // Match all line starts\n\t\t\t\t`$&${INDENT}`\n\t\t\t)\n\t\t\tconst replacementsCount = indentedText.length - newSelection.length\n\n\t\t\t// Replace newSelection with indentedText\n\t\t\telement.setSelectionRange(firstLineStart, selectionEnd - 1)\n\t\t\tTextHelpers.insert(element, indentedText)\n\n\t\t\t// Restore selection position, including the indentation\n\t\t\telement.setSelectionRange(selectionStart + 1, selectionEnd + replacementsCount)\n\t\t} else {\n\t\t\tTextHelpers.insert(element, INDENT)\n\t\t}\n\t}\n\n\t// The first line should always be unindented\n\t// The last line should only be unindented if the selection includes any characters after \\n\n\tstatic unindent(element: HTMLTextAreaElement): void {\n\t\tconst { selectionStart, selectionEnd, value } = element\n\n\t\t// Select the whole first line because it might contain \\t\n\t\tconst firstLineStart = value.lastIndexOf('\\n', selectionStart - 1) + 1\n\t\tconst minimumSelectionEnd = TextHelpers.findLineEnd(value, selectionEnd)\n\n\t\tconst newSelection = element.value.slice(firstLineStart, minimumSelectionEnd)\n\t\tconst indentedText = newSelection.replace(/(^|\\n)(\\t| {1,2})/g, '$1')\n\t\tconst replacementsCount = newSelection.length - indentedText.length\n\n\t\t// Replace newSelection with indentedText\n\t\telement.setSelectionRange(firstLineStart, minimumSelectionEnd)\n\t\tTextHelpers.insert(element, indentedText)\n\n\t\t// Restore selection position, including the indentation\n\t\tconst firstLineIndentation = /\\t| {1,2}/.exec(value.slice(firstLineStart, selectionStart))\n\n\t\tconst difference = firstLineIndentation ? firstLineIndentation[0].length : 0\n\n\t\tconst newSelectionStart = selectionStart - difference\n\t\telement.setSelectionRange(\n\t\t\tselectionStart - difference,\n\t\t\tMath.max(newSelectionStart, selectionEnd - replacementsCount)\n\t\t)\n\t}\n\n\tstatic indentCE(element: HTMLElement): void {\n\t\tconst selection = window.getSelection()\n\t\tconst value = element.innerText\n\t\tconst selectionStart = getCaretIndex(element) ?? 0\n\t\tconst selectionEnd = getCaretIndex(element) ?? 0\n\t\tconst selectedContrast = value.slice(selectionStart, selectionEnd)\n\t\t// The first line should be indented, even if it starts with \\n\n\t\t// The last line should only be indented if includes any character after \\n\n\t\tconst lineBreakCount = /\\n/g.exec(selectedContrast)?.length\n\n\t\tif (lineBreakCount && lineBreakCount > 0) {\n\t\t\t// Select full first line to replace everything at once\n\t\t\tconst firstLineStart = value.lastIndexOf('\\n', selectionStart - 1) + 1\n\n\t\t\tconst newSelection = value.slice(firstLineStart, selectionEnd - 1)\n\t\t\tconst indentedText = newSelection.replace(\n\t\t\t\t/^|\\n/g, // Match all line starts\n\t\t\t\t`$&${INDENT}`\n\t\t\t)\n\t\t\tconst replacementsCount = indentedText.length - newSelection.length\n\n\t\t\t// Replace newSelection with indentedText\n\n\t\t\tif (selection) {\n\t\t\t\tselection.setBaseAndExtent(\n\t\t\t\t\telement,\n\t\t\t\t\tselectionStart + 1,\n\t\t\t\t\telement,\n\t\t\t\t\tselectionEnd + replacementsCount\n\t\t\t\t)\n\t\t\t\t// element.setSelectionRange(firstLineStart, selectionEnd - 1)\n\t\t\t\t// TextHelpers.insert(element, indentedText)\n\n\t\t\t\t// Restore selection position, including the indentation\n\t\t\t\t// element.setSelectionRange(selectionStart + 1, selectionEnd + replacementsCount)\n\t\t\t}\n\t\t} else {\n\t\t\tconst selection = window.getSelection()\n\t\t\telement.innerText = value.slice(0, selectionStart) + INDENT + value.slice(selectionStart)\n\t\t\tselection?.setBaseAndExtent(element, selectionStart + 1, element, selectionStart + 2)\n\t\t\t// TextHelpers.insert(element, INDENT)\n\t\t}\n\t}\n\n\tstatic unindentCE(element: HTMLElement): void {\n\t\tconst selection = window.getSelection()\n\t\tconst value = element.innerText\n\t\t// const { selectionStart, selectionEnd } = element\n\t\tconst selectionStart = getCaretIndex(element) ?? 0\n\t\tconst selectionEnd = getCaretIndex(element) ?? 0\n\n\t\t// Select the whole first line because it might contain \\t\n\t\tconst firstLineStart = value.lastIndexOf('\\n', selectionStart - 1) + 1\n\t\tconst minimumSelectionEnd = TextHelpers.findLineEnd(value, selectionEnd)\n\n\t\tconst newSelection = value.slice(firstLineStart, minimumSelectionEnd)\n\t\tconst indentedText = newSelection.replace(/(^|\\n)(\\t| {1,2})/g, '$1')\n\t\tconst replacementsCount = newSelection.length - indentedText.length\n\n\t\tif (selection) {\n\t\t\t// Replace newSelection with indentedText\n\t\t\tselection.setBaseAndExtent(element, firstLineStart, element, minimumSelectionEnd)\n\t\t\t// TextHelpers.insert(element, indentedText)\n\n\t\t\t// Restore selection position, including the indentation\n\t\t\tconst firstLineIndentation = /\\t| {1,2}/.exec(value.slice(firstLineStart, selectionStart))\n\n\t\t\tconst difference = firstLineIndentation ? firstLineIndentation[0].length : 0\n\n\t\t\tconst newSelectionStart = selectionStart - difference\n\t\t\tselection.setBaseAndExtent(\n\t\t\t\telement,\n\t\t\t\tselectionStart - difference,\n\t\t\t\telement,\n\t\t\t\tMath.max(newSelectionStart, selectionEnd - replacementsCount)\n\t\t\t)\n\t\t}\n\t}\n\n\tstatic fixNewLines = /\\r?\\n|\\r/g\n\n\tstatic normalizeText(text: string) {\n\t\treturn text.replace(TextHelpers.fixNewLines, '\\n')\n\t}\n\n\tstatic normalizeTextForDom(text: string) {\n\t\treturn text\n\t\t\t.replace(TextHelpers.fixNewLines, '\\n')\n\t\t\t.split('\\n')\n\t\t\t.map((x) => x || ' ')\n\t\t\t.join('\\n')\n\t}\n}\n\nfunction getCaretIndex(element: HTMLElement) {\n\tif (typeof window.getSelection === 'undefined') return\n\tconst selection = window.getSelection()\n\tif (!selection) return\n\tlet position = 0\n\tif (selection.rangeCount !== 0) {\n\t\tconst range = selection.getRangeAt(0)\n\t\tconst preCaretRange = range.cloneRange()\n\t\tpreCaretRange.selectNodeContents(element)\n\t\tpreCaretRange.setEnd(range.endContainer, range.endOffset)\n\t\tposition = preCaretRange.toString().length\n\t}\n\treturn position\n}\n"], -- "mappings": "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", -+ "sourcesContent": ["/*!\n * MIT License\n * Adapted (mostly copied) the work of https://github.com/fregante/text-field-edit\n * Copyright (c) Federico Brigante (bfred.it)\n */\n\n// TODO: Most of this file can be moved into a DOM utils library.\n\n/** @internal */\nexport type ReplacerCallback = (substring: string, ...args: unknown[]) => string\n\n/**\t@public */\nexport const INDENT = ' '\n\n/** @internal */\nexport class TextHelpers {\n\tstatic insertTextFirefox(field: HTMLTextAreaElement | HTMLInputElement, text: string): void {\n\t\t// Found on https://www.everythingfrontend.com/blog/insert-text-into-textarea-at-cursor-position.html \uD83C\uDF88\n\t\tfield.setRangeText(\n\t\t\ttext,\n\t\t\tfield.selectionStart || 0,\n\t\t\tfield.selectionEnd || 0,\n\t\t\t'end' // Without this, the cursor is either at the beginning or text remains selected\n\t\t)\n\n\t\tfield.dispatchEvent(\n\t\t\tnew InputEvent('input', {\n\t\t\t\tdata: text,\n\t\t\t\tinputType: 'insertText',\n\t\t\t\tisComposing: false, // TODO: fix @types/jsdom, this shouldn't be required\n\t\t\t})\n\t\t)\n\t}\n\n\t/**\n\t * Inserts text at the cursor\u2019s position, replacing any selection, with **undo** support and by\n\t * firing the input event.\n\t */\n\tstatic insert(field: HTMLTextAreaElement | HTMLInputElement, text: string): void {\n\t\tconst document = field.ownerDocument\n\t\tconst initialFocus = document.activeElement\n\t\tif (initialFocus !== field) {\n\t\t\tfield.focus()\n\t\t}\n\n\t\t// eslint-disable-next-line deprecation/deprecation\n\t\tif (!document.execCommand('insertText', false, text)) {\n\t\t\tTextHelpers.insertTextFirefox(field, text)\n\t\t}\n\n\t\tif (initialFocus === document.body) {\n\t\t\tfield.blur()\n\t\t} else if (initialFocus?.instanceOf(HTMLElement) && initialFocus !== field) {\n\t\t\tinitialFocus.focus()\n\t\t}\n\t}\n\n\t/**\n\t * Replaces the entire content, equivalent to field.value = text but with **undo** support and by\n\t * firing the input event.\n\t */\n\tstatic set(field: HTMLTextAreaElement | HTMLInputElement, text: string): void {\n\t\tfield.select()\n\t\tTextHelpers.insert(field, text)\n\t}\n\n\t/** Get the selected text in a field or an empty string if nothing is selected. */\n\tstatic getSelection(field: HTMLTextAreaElement | HTMLInputElement): string {\n\t\tconst { selectionStart, selectionEnd } = field\n\t\treturn field.value.slice(\n\t\t\tselectionStart ? selectionStart : undefined,\n\t\t\tselectionEnd ? selectionEnd : undefined\n\t\t)\n\t}\n\n\t/**\n\t * Adds the wrappingText before and after field\u2019s selection (or cursor). If endWrappingText is\n\t * provided, it will be used instead of wrappingText at on the right.\n\t */\n\tstatic wrapSelection(\n\t\tfield: HTMLTextAreaElement | HTMLInputElement,\n\t\twrap: string,\n\t\twrapEnd?: string\n\t): void {\n\t\tconst { selectionStart, selectionEnd } = field\n\t\tconst selection = TextHelpers.getSelection(field)\n\t\tTextHelpers.insert(field, wrap + selection + (wrapEnd ?? wrap))\n\n\t\t// Restore the selection around the previously-selected text\n\t\tfield.selectionStart = (selectionStart || 0) + wrap.length\n\t\tfield.selectionEnd = (selectionEnd || 0) + wrap.length\n\t}\n\n\t/** Finds and replaces strings and regex in the field\u2019s value. */\n\tstatic replace(\n\t\tfield: HTMLTextAreaElement | HTMLInputElement,\n\t\tsearchValue: string | RegExp,\n\t\treplacer: string | ReplacerCallback\n\t): void {\n\t\t/** Remembers how much each match offset should be adjusted */\n\t\tlet drift = 0\n\t\tfield.value.replace(searchValue, (...args): string => {\n\t\t\t// Select current match to replace it later\n\t\t\tconst matchStart = drift + (args[args.length - 2] as number)\n\t\t\tconst matchLength = args[0].length\n\t\t\tfield.selectionStart = matchStart\n\t\t\tfield.selectionEnd = matchStart + matchLength\n\t\t\tconst replacement = typeof replacer === 'string' ? replacer : replacer(...args)\n\t\t\tTextHelpers.insert(field, replacement)\n\t\t\t// Select replacement. Without this, the cursor would be after the replacement\n\t\t\tfield.selectionStart = matchStart\n\t\t\tdrift += replacement.length - matchLength\n\t\t\treturn replacement\n\t\t})\n\t}\n\n\tstatic findLineEnd(value: string, currentEnd: number): number {\n\t\t// Go to the beginning of the last line\n\t\tconst lastLineStart = value.lastIndexOf('\\n', currentEnd - 1) + 1\n\t\t// There's nothing to unindent after the last cursor, so leave it as is\n\t\tif (value.charAt(lastLineStart) !== '\\t') {\n\t\t\treturn currentEnd\n\t\t}\n\t\treturn lastLineStart + 1 // Include the first character, which will be a tab\n\t}\n\n\tstatic indent(element: HTMLTextAreaElement): void {\n\t\tconst { selectionStart, selectionEnd, value } = element\n\t\tconst selectedContrast = value.slice(selectionStart, selectionEnd)\n\t\t// The first line should be indented, even if it starts with \\n\n\t\t// The last line should only be indented if includes any character after \\n\n\t\tconst lineBreakCount = /\\n/g.exec(selectedContrast)?.length\n\n\t\tif (lineBreakCount && lineBreakCount > 0) {\n\t\t\t// Select full first line to replace everything at once\n\t\t\tconst firstLineStart = value.lastIndexOf('\\n', selectionStart - 1) + 1\n\n\t\t\tconst newSelection = element.value.slice(firstLineStart, selectionEnd - 1)\n\t\t\tconst indentedText = newSelection.replace(\n\t\t\t\t/^|\\n/g, // Match all line starts\n\t\t\t\t`$&${INDENT}`\n\t\t\t)\n\t\t\tconst replacementsCount = indentedText.length - newSelection.length\n\n\t\t\t// Replace newSelection with indentedText\n\t\t\telement.setSelectionRange(firstLineStart, selectionEnd - 1)\n\t\t\tTextHelpers.insert(element, indentedText)\n\n\t\t\t// Restore selection position, including the indentation\n\t\t\telement.setSelectionRange(selectionStart + 1, selectionEnd + replacementsCount)\n\t\t} else {\n\t\t\tTextHelpers.insert(element, INDENT)\n\t\t}\n\t}\n\n\t// The first line should always be unindented\n\t// The last line should only be unindented if the selection includes any characters after \\n\n\tstatic unindent(element: HTMLTextAreaElement): void {\n\t\tconst { selectionStart, selectionEnd, value } = element\n\n\t\t// Select the whole first line because it might contain \\t\n\t\tconst firstLineStart = value.lastIndexOf('\\n', selectionStart - 1) + 1\n\t\tconst minimumSelectionEnd = TextHelpers.findLineEnd(value, selectionEnd)\n\n\t\tconst newSelection = element.value.slice(firstLineStart, minimumSelectionEnd)\n\t\tconst indentedText = newSelection.replace(/(^|\\n)(\\t| {1,2})/g, '$1')\n\t\tconst replacementsCount = newSelection.length - indentedText.length\n\n\t\t// Replace newSelection with indentedText\n\t\telement.setSelectionRange(firstLineStart, minimumSelectionEnd)\n\t\tTextHelpers.insert(element, indentedText)\n\n\t\t// Restore selection position, including the indentation\n\t\tconst firstLineIndentation = /\\t| {1,2}/.exec(value.slice(firstLineStart, selectionStart))\n\n\t\tconst difference = firstLineIndentation ? firstLineIndentation[0].length : 0\n\n\t\tconst newSelectionStart = selectionStart - difference\n\t\telement.setSelectionRange(\n\t\t\tselectionStart - difference,\n\t\t\tMath.max(newSelectionStart, selectionEnd - replacementsCount)\n\t\t)\n\t}\n\n\tstatic indentCE(element: HTMLElement): void {\n\t\tconst selection = window.getSelection()\n\t\tconst value = element.innerText\n\t\tconst selectionStart = getCaretIndex(element) ?? 0\n\t\tconst selectionEnd = getCaretIndex(element) ?? 0\n\t\tconst selectedContrast = value.slice(selectionStart, selectionEnd)\n\t\t// The first line should be indented, even if it starts with \\n\n\t\t// The last line should only be indented if includes any character after \\n\n\t\tconst lineBreakCount = /\\n/g.exec(selectedContrast)?.length\n\n\t\tif (lineBreakCount && lineBreakCount > 0) {\n\t\t\t// Select full first line to replace everything at once\n\t\t\tconst firstLineStart = value.lastIndexOf('\\n', selectionStart - 1) + 1\n\n\t\t\tconst newSelection = value.slice(firstLineStart, selectionEnd - 1)\n\t\t\tconst indentedText = newSelection.replace(\n\t\t\t\t/^|\\n/g, // Match all line starts\n\t\t\t\t`$&${INDENT}`\n\t\t\t)\n\t\t\tconst replacementsCount = indentedText.length - newSelection.length\n\n\t\t\t// Replace newSelection with indentedText\n\n\t\t\tif (selection) {\n\t\t\t\tselection.setBaseAndExtent(\n\t\t\t\t\telement,\n\t\t\t\t\tselectionStart + 1,\n\t\t\t\t\telement,\n\t\t\t\t\tselectionEnd + replacementsCount\n\t\t\t\t)\n\t\t\t\t// element.setSelectionRange(firstLineStart, selectionEnd - 1)\n\t\t\t\t// TextHelpers.insert(element, indentedText)\n\n\t\t\t\t// Restore selection position, including the indentation\n\t\t\t\t// element.setSelectionRange(selectionStart + 1, selectionEnd + replacementsCount)\n\t\t\t}\n\t\t} else {\n\t\t\tconst selection = window.getSelection()\n\t\t\telement.innerText = value.slice(0, selectionStart) + INDENT + value.slice(selectionStart)\n\t\t\tselection?.setBaseAndExtent(element, selectionStart + 1, element, selectionStart + 2)\n\t\t\t// TextHelpers.insert(element, INDENT)\n\t\t}\n\t}\n\n\tstatic unindentCE(element: HTMLElement): void {\n\t\tconst selection = window.getSelection()\n\t\tconst value = element.innerText\n\t\t// const { selectionStart, selectionEnd } = element\n\t\tconst selectionStart = getCaretIndex(element) ?? 0\n\t\tconst selectionEnd = getCaretIndex(element) ?? 0\n\n\t\t// Select the whole first line because it might contain \\t\n\t\tconst firstLineStart = value.lastIndexOf('\\n', selectionStart - 1) + 1\n\t\tconst minimumSelectionEnd = TextHelpers.findLineEnd(value, selectionEnd)\n\n\t\tconst newSelection = value.slice(firstLineStart, minimumSelectionEnd)\n\t\tconst indentedText = newSelection.replace(/(^|\\n)(\\t| {1,2})/g, '$1')\n\t\tconst replacementsCount = newSelection.length - indentedText.length\n\n\t\tif (selection) {\n\t\t\t// Replace newSelection with indentedText\n\t\t\tselection.setBaseAndExtent(element, firstLineStart, element, minimumSelectionEnd)\n\t\t\t// TextHelpers.insert(element, indentedText)\n\n\t\t\t// Restore selection position, including the indentation\n\t\t\tconst firstLineIndentation = /\\t| {1,2}/.exec(value.slice(firstLineStart, selectionStart))\n\n\t\t\tconst difference = firstLineIndentation ? firstLineIndentation[0].length : 0\n\n\t\t\tconst newSelectionStart = selectionStart - difference\n\t\t\tselection.setBaseAndExtent(\n\t\t\t\telement,\n\t\t\t\tselectionStart - difference,\n\t\t\t\telement,\n\t\t\t\tMath.max(newSelectionStart, selectionEnd - replacementsCount)\n\t\t\t)\n\t\t}\n\t}\n\n\tstatic fixNewLines = /\\r?\\n|\\r/g\n\n\tstatic normalizeText(text: string) {\n\t\treturn text.replace(TextHelpers.fixNewLines, '\\n')\n\t}\n\n\tstatic normalizeTextForDom(text: string) {\n\t\treturn text\n\t\t\t.replace(TextHelpers.fixNewLines, '\\n')\n\t\t\t.split('\\n')\n\t\t\t.map((x) => x || ' ')\n\t\t\t.join('\\n')\n\t}\n}\n\nfunction getCaretIndex(element: HTMLElement) {\n\tif (typeof window.getSelection === 'undefined') return\n\tconst selection = window.getSelection()\n\tif (!selection) return\n\tlet position = 0\n\tif (selection.rangeCount !== 0) {\n\t\tconst range = selection.getRangeAt(0)\n\t\tconst preCaretRange = range.cloneRange()\n\t\tpreCaretRange.selectNodeContents(element)\n\t\tpreCaretRange.setEnd(range.endContainer, range.endOffset)\n\t\tposition = preCaretRange.toString().length\n\t}\n\treturn position\n}\n"], -+ "mappings": "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", - "names": ["selection"] - } -diff --git a/node_modules/tldraw/dist-esm/lib/ui/components/Toolbar/OverflowingToolbar.mjs b/node_modules/tldraw/dist-esm/lib/ui/components/Toolbar/OverflowingToolbar.mjs -index b469edb..4c25450 100644 ---- a/node_modules/tldraw/dist-esm/lib/ui/components/Toolbar/OverflowingToolbar.mjs -+++ b/node_modules/tldraw/dist-esm/lib/ui/components/Toolbar/OverflowingToolbar.mjs -@@ -88,7 +88,7 @@ function OverflowingToolbar({ children }) { - preventDefault(event); - const relevantEls = Array.from(mainToolsRef.current?.children ?? []).filter( - (el2) => { -- if (!(el2 instanceof HTMLElement)) return false; -+ if (!el2.instanceOf(HTMLElement)) return false; - if (el2.tagName.toLowerCase() !== "button") return false; - return !!(el2.offsetWidth || el2.offsetHeight); - } -diff --git a/node_modules/tldraw/dist-esm/lib/ui/components/Toolbar/OverflowingToolbar.mjs.map b/node_modules/tldraw/dist-esm/lib/ui/components/Toolbar/OverflowingToolbar.mjs.map -index cd8151e..72827ac 100644 ---- a/node_modules/tldraw/dist-esm/lib/ui/components/Toolbar/OverflowingToolbar.mjs.map -+++ b/node_modules/tldraw/dist-esm/lib/ui/components/Toolbar/OverflowingToolbar.mjs.map -@@ -1,7 +1,7 @@ - { - "version": 3, - "sources": ["../../../../../src/lib/ui/components/Toolbar/OverflowingToolbar.tsx"], -- "sourcesContent": ["import { preventDefault, useEditor, useEvent, useSafeId } from '@tldraw/editor'\nimport classNames from 'classnames'\nimport hotkeys from 'hotkeys-js'\nimport { createContext, useEffect, useLayoutEffect, useMemo, useRef, useState } from 'react'\nimport { PORTRAIT_BREAKPOINT } from '../../constants'\nimport { useBreakpoint } from '../../context/breakpoints'\nimport { areShortcutsDisabled } from '../../hooks/useKeyboardShortcuts'\nimport { TLUiToolItem } from '../../hooks/useTools'\nimport { useTranslation } from '../../hooks/useTranslation/useTranslation'\nimport { TldrawUiButton } from '../primitives/Button/TldrawUiButton'\nimport { TldrawUiButtonIcon } from '../primitives/Button/TldrawUiButtonIcon'\nimport {\n\tTldrawUiDropdownMenuContent,\n\tTldrawUiDropdownMenuRoot,\n\tTldrawUiDropdownMenuTrigger,\n} from '../primitives/TldrawUiDropdownMenu'\nimport { TldrawUiMenuContextProvider } from '../primitives/menus/TldrawUiMenuContext'\n\nexport const IsInOverflowContext = createContext(false)\n\n/** @public */\nexport interface OverflowingToolbarProps {\n\tchildren: React.ReactNode\n}\n\n/** @public @react */\nexport function OverflowingToolbar({ children }: OverflowingToolbarProps) {\n\tconst editor = useEditor()\n\tconst id = useSafeId()\n\tconst breakpoint = useBreakpoint()\n\tconst msg = useTranslation()\n\n\tconst overflowIndex = Math.min(8, 5 + breakpoint)\n\n\tconst [totalItems, setTotalItems] = useState(0)\n\tconst mainToolsRef = useRef(null)\n\tconst [lastActiveOverflowItem, setLastActiveOverflowItem] = useState(null)\n\n\tconst css = useMemo(() => {\n\t\tconst activeCss = lastActiveOverflowItem ? `:not([data-value=\"${lastActiveOverflowItem}\"])` : ''\n\n\t\treturn `\n\t\t\t#${id}_main > *:nth-child(n + ${overflowIndex + (lastActiveOverflowItem ? 1 : 2)})${activeCss} {\n\t\t\t\tdisplay: none;\n\t\t\t}\n\t\t\t#${id}_more > *:nth-child(-n + ${overflowIndex}) {\n\t\t\t\tdisplay: none;\n\t\t\t}\n `\n\t}, [lastActiveOverflowItem, id, overflowIndex])\n\n\tconst onDomUpdate = useEvent(() => {\n\t\tif (!mainToolsRef.current) return\n\n\t\tconst children = Array.from(mainToolsRef.current.children)\n\t\tsetTotalItems(children.length)\n\n\t\t// If the last active overflow item is no longer in the overflow, clear it\n\t\tconst lastActiveElementIdx = children.findIndex(\n\t\t\t(el) => el.getAttribute('data-value') === lastActiveOverflowItem\n\t\t)\n\t\tif (lastActiveElementIdx <= overflowIndex) {\n\t\t\tsetLastActiveOverflowItem(null)\n\t\t}\n\n\t\t// But if there's a new active item...\n\t\tconst activeElementIdx = Array.from(mainToolsRef.current.children).findIndex(\n\t\t\t(el) => el.getAttribute('aria-checked') === 'true'\n\t\t)\n\t\tif (activeElementIdx === -1) return\n\n\t\t// ...and it's in the overflow, set it as the last active overflow item\n\t\tif (activeElementIdx >= overflowIndex) {\n\t\t\tsetLastActiveOverflowItem(children[activeElementIdx].getAttribute('data-value'))\n\t\t}\n\t})\n\n\tuseLayoutEffect(() => {\n\t\tonDomUpdate()\n\t})\n\n\tuseLayoutEffect(() => {\n\t\tif (!mainToolsRef.current) return\n\n\t\tconst mutationObserver = new MutationObserver(onDomUpdate)\n\t\tmutationObserver.observe(mainToolsRef.current, {\n\t\t\tchildList: true,\n\t\t\tsubtree: true,\n\t\t\tattributeFilter: ['data-value', 'aria-checked'],\n\t\t})\n\n\t\treturn () => {\n\t\t\tmutationObserver.disconnect()\n\t\t}\n\t}, [onDomUpdate])\n\n\tuseEffect(() => {\n\t\tconst keys = [\n\t\t\t['1', 0],\n\t\t\t['2', 1],\n\t\t\t['3', 2],\n\t\t\t['4', 3],\n\t\t\t['5', 4],\n\t\t\t['6', 5],\n\t\t\t['7', 6],\n\t\t\t['8', 7],\n\t\t\t['9', 8],\n\t\t\t['0', 9],\n\t\t] as const\n\n\t\tfor (const [key, index] of keys) {\n\t\t\thotkeys(key, (event) => {\n\t\t\t\tif (areShortcutsDisabled(editor)) return\n\t\t\t\tpreventDefault(event)\n\n\t\t\t\tconst relevantEls = Array.from(mainToolsRef.current?.children ?? []).filter(\n\t\t\t\t\t(el): el is HTMLElement => {\n\t\t\t\t\t\t// only count html elements...\n\t\t\t\t\t\tif (!(el instanceof HTMLElement)) return false\n\n\t\t\t\t\t\t// ...that are buttons...\n\t\t\t\t\t\tif (el.tagName.toLowerCase() !== 'button') return false\n\n\t\t\t\t\t\t// ...that are actually visible\n\t\t\t\t\t\treturn !!(el.offsetWidth || el.offsetHeight)\n\t\t\t\t\t}\n\t\t\t\t)\n\n\t\t\t\tconst el = relevantEls[index]\n\t\t\t\tif (el) el.click()\n\t\t\t})\n\t\t}\n\n\t\treturn () => {\n\t\t\thotkeys.unbind('1,2,3,4,5,6,7,8,9,0')\n\t\t}\n\t}, [editor])\n\n\treturn (\n\t\t<>\n\t\t\t\n\t\t\t\n\t\t\t\t
\n\t\t\t\t\t\n\t\t\t\t\t\t{children}\n\t\t\t\t\t\n\t\t\t\t
\n\t\t\t\t{/* There is a +1 because if the menu is just one item, it's not necessary. */}\n\t\t\t\t{totalItems > overflowIndex + 1 && (\n\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t{children}\n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t)}\n\t\t\t
\n\t\t\n\t)\n}\n\nexport const isActiveTLUiToolItem = (\n\titem: TLUiToolItem,\n\tactiveToolId: string | undefined,\n\tgeoState: string | null | undefined\n) => {\n\treturn item.meta?.geo\n\t\t? activeToolId === 'geo' && geoState === item.meta?.geo\n\t\t: activeToolId === item.id\n}\n"], -- "mappings": "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", -+ "sourcesContent": ["import { preventDefault, useEditor, useEvent, useSafeId } from '@tldraw/editor'\nimport classNames from 'classnames'\nimport hotkeys from 'hotkeys-js'\nimport { createContext, useEffect, useLayoutEffect, useMemo, useRef, useState } from 'react'\nimport { PORTRAIT_BREAKPOINT } from '../../constants'\nimport { useBreakpoint } from '../../context/breakpoints'\nimport { areShortcutsDisabled } from '../../hooks/useKeyboardShortcuts'\nimport { TLUiToolItem } from '../../hooks/useTools'\nimport { useTranslation } from '../../hooks/useTranslation/useTranslation'\nimport { TldrawUiButton } from '../primitives/Button/TldrawUiButton'\nimport { TldrawUiButtonIcon } from '../primitives/Button/TldrawUiButtonIcon'\nimport {\n\tTldrawUiDropdownMenuContent,\n\tTldrawUiDropdownMenuRoot,\n\tTldrawUiDropdownMenuTrigger,\n} from '../primitives/TldrawUiDropdownMenu'\nimport { TldrawUiMenuContextProvider } from '../primitives/menus/TldrawUiMenuContext'\n\nexport const IsInOverflowContext = createContext(false)\n\n/** @public */\nexport interface OverflowingToolbarProps {\n\tchildren: React.ReactNode\n}\n\n/** @public @react */\nexport function OverflowingToolbar({ children }: OverflowingToolbarProps) {\n\tconst editor = useEditor()\n\tconst id = useSafeId()\n\tconst breakpoint = useBreakpoint()\n\tconst msg = useTranslation()\n\n\tconst overflowIndex = Math.min(8, 5 + breakpoint)\n\n\tconst [totalItems, setTotalItems] = useState(0)\n\tconst mainToolsRef = useRef(null)\n\tconst [lastActiveOverflowItem, setLastActiveOverflowItem] = useState(null)\n\n\tconst css = useMemo(() => {\n\t\tconst activeCss = lastActiveOverflowItem ? `:not([data-value=\"${lastActiveOverflowItem}\"])` : ''\n\n\t\treturn `\n\t\t\t#${id}_main > *:nth-child(n + ${overflowIndex + (lastActiveOverflowItem ? 1 : 2)})${activeCss} {\n\t\t\t\tdisplay: none;\n\t\t\t}\n\t\t\t#${id}_more > *:nth-child(-n + ${overflowIndex}) {\n\t\t\t\tdisplay: none;\n\t\t\t}\n `\n\t}, [lastActiveOverflowItem, id, overflowIndex])\n\n\tconst onDomUpdate = useEvent(() => {\n\t\tif (!mainToolsRef.current) return\n\n\t\tconst children = Array.from(mainToolsRef.current.children)\n\t\tsetTotalItems(children.length)\n\n\t\t// If the last active overflow item is no longer in the overflow, clear it\n\t\tconst lastActiveElementIdx = children.findIndex(\n\t\t\t(el) => el.getAttribute('data-value') === lastActiveOverflowItem\n\t\t)\n\t\tif (lastActiveElementIdx <= overflowIndex) {\n\t\t\tsetLastActiveOverflowItem(null)\n\t\t}\n\n\t\t// But if there's a new active item...\n\t\tconst activeElementIdx = Array.from(mainToolsRef.current.children).findIndex(\n\t\t\t(el) => el.getAttribute('aria-checked') === 'true'\n\t\t)\n\t\tif (activeElementIdx === -1) return\n\n\t\t// ...and it's in the overflow, set it as the last active overflow item\n\t\tif (activeElementIdx >= overflowIndex) {\n\t\t\tsetLastActiveOverflowItem(children[activeElementIdx].getAttribute('data-value'))\n\t\t}\n\t})\n\n\tuseLayoutEffect(() => {\n\t\tonDomUpdate()\n\t})\n\n\tuseLayoutEffect(() => {\n\t\tif (!mainToolsRef.current) return\n\n\t\tconst mutationObserver = new MutationObserver(onDomUpdate)\n\t\tmutationObserver.observe(mainToolsRef.current, {\n\t\t\tchildList: true,\n\t\t\tsubtree: true,\n\t\t\tattributeFilter: ['data-value', 'aria-checked'],\n\t\t})\n\n\t\treturn () => {\n\t\t\tmutationObserver.disconnect()\n\t\t}\n\t}, [onDomUpdate])\n\n\tuseEffect(() => {\n\t\tconst keys = [\n\t\t\t['1', 0],\n\t\t\t['2', 1],\n\t\t\t['3', 2],\n\t\t\t['4', 3],\n\t\t\t['5', 4],\n\t\t\t['6', 5],\n\t\t\t['7', 6],\n\t\t\t['8', 7],\n\t\t\t['9', 8],\n\t\t\t['0', 9],\n\t\t] as const\n\n\t\tfor (const [key, index] of keys) {\n\t\t\thotkeys(key, (event) => {\n\t\t\t\tif (areShortcutsDisabled(editor)) return\n\t\t\t\tpreventDefault(event)\n\n\t\t\t\tconst relevantEls = Array.from(mainToolsRef.current?.children ?? []).filter(\n\t\t\t\t\t(el): el is HTMLElement => {\n\t\t\t\t\t\t// only count html elements...\n\t\t\t\t\t\tif (!(el.instanceOf(HTMLElement))) return false\n\n\t\t\t\t\t\t// ...that are buttons...\n\t\t\t\t\t\tif (el.tagName.toLowerCase() !== 'button') return false\n\n\t\t\t\t\t\t// ...that are actually visible\n\t\t\t\t\t\treturn !!(el.offsetWidth || el.offsetHeight)\n\t\t\t\t\t}\n\t\t\t\t)\n\n\t\t\t\tconst el = relevantEls[index]\n\t\t\t\tif (el) el.click()\n\t\t\t})\n\t\t}\n\n\t\treturn () => {\n\t\t\thotkeys.unbind('1,2,3,4,5,6,7,8,9,0')\n\t\t}\n\t}, [editor])\n\n\treturn (\n\t\t<>\n\t\t\t\n\t\t\t\n\t\t\t\t
\n\t\t\t\t\t\n\t\t\t\t\t\t{children}\n\t\t\t\t\t\n\t\t\t\t
\n\t\t\t\t{/* There is a +1 because if the menu is just one item, it's not necessary. */}\n\t\t\t\t{totalItems > overflowIndex + 1 && (\n\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t{children}\n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t)}\n\t\t\t\n\t\t\n\t)\n}\n\nexport const isActiveTLUiToolItem = (\n\titem: TLUiToolItem,\n\tactiveToolId: string | undefined,\n\tgeoState: string | null | undefined\n) => {\n\treturn item.meta?.geo\n\t\t? activeToolId === 'geo' && geoState === item.meta?.geo\n\t\t: activeToolId === item.id\n}\n"], -+ "mappings": "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", - "names": ["children", "el"] - } -diff --git a/node_modules/tldraw/dist-esm/lib/ui/components/primitives/TldrawUiButtonPicker.mjs b/node_modules/tldraw/dist-esm/lib/ui/components/primitives/TldrawUiButtonPicker.mjs -index bf9818d..916a383 100644 ---- a/node_modules/tldraw/dist-esm/lib/ui/components/primitives/TldrawUiButtonPicker.mjs -+++ b/node_modules/tldraw/dist-esm/lib/ui/components/primitives/TldrawUiButtonPicker.mjs -@@ -1,6 +1,7 @@ - import { jsx } from "react/jsx-runtime"; - import { - DefaultColorStyle, -+ useContainer, - useEditor - } from "@tldraw/editor"; - import classNames from "classnames"; -@@ -20,6 +21,7 @@ const TldrawUiButtonPicker = memo(function TldrawUiButtonPicker2(props) { - theme - } = props; - const editor = useEditor(); -+ const container = useContainer(); - const msg = useTranslation(); - const rPointing = useRef(false); - const rPointingOriginalActiveElement = useRef(null); -@@ -31,7 +33,7 @@ const TldrawUiButtonPicker = memo(function TldrawUiButtonPicker2(props) { - } = useMemo(() => { - const handlePointerUp = () => { - rPointing.current = false; -- window.removeEventListener("pointerup", handlePointerUp); -+ container.win.removeEventListener("pointerup", handlePointerUp); - const origActiveEl = rPointingOriginalActiveElement.current; - if (origActiveEl && ["TEXTAREA", "INPUT"].includes(origActiveEl.nodeName)) { - origActiveEl.focus(); -@@ -49,8 +51,8 @@ const TldrawUiButtonPicker = memo(function TldrawUiButtonPicker2(props) { - editor.markHistoryStoppingPoint("point picker item"); - onValueChange(style, id); - rPointing.current = true; -- rPointingOriginalActiveElement.current = document.activeElement; -- window.addEventListener("pointerup", handlePointerUp); -+ rPointingOriginalActiveElement.current = container.ownerDocument.activeElement; -+ container.win.addEventListener("pointerup", handlePointerUp); - }; - const handleButtonPointerEnter2 = (e) => { - if (!rPointing.current) return; -@@ -68,7 +70,7 @@ const TldrawUiButtonPicker = memo(function TldrawUiButtonPicker2(props) { - handleButtonPointerEnter: handleButtonPointerEnter2, - handleButtonPointerUp: handleButtonPointerUp2 - }; -- }, [value, editor, onValueChange, style]); -+ }, [value, editor, onValueChange, style, container]); - return /* @__PURE__ */ jsx("div", { "data-testid": `style.${uiType}`, className: classNames("tlui-buttons__grid"), children: items.map((item) => /* @__PURE__ */ jsx( - TldrawUiButton, - { -diff --git a/node_modules/tldraw/dist-esm/lib/ui/components/primitives/TldrawUiButtonPicker.mjs.map b/node_modules/tldraw/dist-esm/lib/ui/components/primitives/TldrawUiButtonPicker.mjs.map -index 7593595..b8335f1 100644 ---- a/node_modules/tldraw/dist-esm/lib/ui/components/primitives/TldrawUiButtonPicker.mjs.map -+++ b/node_modules/tldraw/dist-esm/lib/ui/components/primitives/TldrawUiButtonPicker.mjs.map -@@ -1,7 +1,7 @@ - { - "version": 3, - "sources": ["../../../../../src/lib/ui/components/primitives/TldrawUiButtonPicker.tsx"], -- "sourcesContent": ["import {\n\tDefaultColorStyle,\n\tSharedStyle,\n\tStyleProp,\n\tTLDefaultColorStyle,\n\tTLDefaultColorTheme,\n\tuseEditor,\n} from '@tldraw/editor'\nimport classNames from 'classnames'\nimport { ReactElement, memo, useMemo, useRef } from 'react'\nimport { StyleValuesForUi } from '../../../styles'\nimport { TLUiTranslationKey } from '../../hooks/useTranslation/TLUiTranslationKey'\nimport { useTranslation } from '../../hooks/useTranslation/useTranslation'\nimport { TldrawUiButton } from './Button/TldrawUiButton'\nimport { TldrawUiButtonIcon } from './Button/TldrawUiButtonIcon'\n\n/** @public */\nexport interface TLUiButtonPickerProps {\n\ttitle: string\n\tuiType: string\n\tstyle: StyleProp\n\tvalue: SharedStyle\n\titems: StyleValuesForUi\n\ttheme: TLDefaultColorTheme\n\tonValueChange(style: StyleProp, value: T): void\n}\n\n/** @public */\nexport const TldrawUiButtonPicker = memo(function TldrawUiButtonPicker(\n\tprops: TLUiButtonPickerProps\n) {\n\tconst {\n\t\tuiType,\n\t\titems,\n\t\ttitle,\n\t\tstyle,\n\t\tvalue,\n\t\t// columns = clamp(items.length, 2, 4),\n\t\tonValueChange,\n\t\ttheme,\n\t} = props\n\tconst editor = useEditor()\n\tconst msg = useTranslation()\n\n\tconst rPointing = useRef(false)\n\tconst rPointingOriginalActiveElement = useRef(null)\n\n\tconst {\n\t\thandleButtonClick,\n\t\thandleButtonPointerDown,\n\t\thandleButtonPointerEnter,\n\t\thandleButtonPointerUp,\n\t} = useMemo(() => {\n\t\tconst handlePointerUp = () => {\n\t\t\trPointing.current = false\n\t\t\twindow.removeEventListener('pointerup', handlePointerUp)\n\n\t\t\t// This is fun little micro-optimization to make sure that the focus\n\t\t\t// is retained on a text label. That way, you can continue typing\n\t\t\t// after selecting a style.\n\t\t\tconst origActiveEl = rPointingOriginalActiveElement.current\n\t\t\tif (origActiveEl && ['TEXTAREA', 'INPUT'].includes(origActiveEl.nodeName)) {\n\t\t\t\torigActiveEl.focus()\n\t\t\t}\n\t\t\trPointingOriginalActiveElement.current = null\n\t\t}\n\n\t\tconst handleButtonClick = (e: React.PointerEvent) => {\n\t\t\tconst { id } = e.currentTarget.dataset\n\t\t\tif (value.type === 'shared' && value.value === id) return\n\n\t\t\teditor.markHistoryStoppingPoint('point picker item')\n\t\t\tonValueChange(style, id as T)\n\t\t}\n\n\t\tconst handleButtonPointerDown = (e: React.PointerEvent) => {\n\t\t\tconst { id } = e.currentTarget.dataset\n\n\t\t\teditor.markHistoryStoppingPoint('point picker item')\n\t\t\tonValueChange(style, id as T)\n\n\t\t\trPointing.current = true\n\t\t\trPointingOriginalActiveElement.current = document.activeElement as HTMLElement\n\t\t\twindow.addEventListener('pointerup', handlePointerUp) // see TLD-658\n\t\t}\n\n\t\tconst handleButtonPointerEnter = (e: React.PointerEvent) => {\n\t\t\tif (!rPointing.current) return\n\n\t\t\tconst { id } = e.currentTarget.dataset\n\t\t\tonValueChange(style, id as T)\n\t\t}\n\n\t\tconst handleButtonPointerUp = (e: React.PointerEvent) => {\n\t\t\tconst { id } = e.currentTarget.dataset\n\t\t\tif (value.type === 'shared' && value.value === id) return\n\n\t\t\tonValueChange(style, id as T)\n\t\t}\n\n\t\treturn {\n\t\t\thandleButtonClick,\n\t\t\thandleButtonPointerDown,\n\t\t\thandleButtonPointerEnter,\n\t\t\thandleButtonPointerUp,\n\t\t}\n\t}, [value, editor, onValueChange, style])\n\n\treturn (\n\t\t
\n\t\t\t{items.map((item) => (\n\t\t\t\t)\n\t\t\t\t\t\t\t? { color: theme[item.value as TLDefaultColorStyle].solid }\n\t\t\t\t\t\t\t: undefined\n\t\t\t\t\t}\n\t\t\t\t\tonPointerEnter={handleButtonPointerEnter}\n\t\t\t\t\tonPointerDown={handleButtonPointerDown}\n\t\t\t\t\tonPointerUp={handleButtonPointerUp}\n\t\t\t\t\tonClick={handleButtonClick}\n\t\t\t\t>\n\t\t\t\t\t\n\t\t\t\t\n\t\t\t))}\n\t\t
\n\t)\n}) as (props: TLUiButtonPickerProps) => ReactElement\n"], -- "mappings": "AAkIK;AAlIL;AAAA,EACC;AAAA,EAKA;AAAA,OACM;AACP,OAAO,gBAAgB;AACvB,SAAuB,MAAM,SAAS,cAAc;AAGpD,SAAS,sBAAsB;AAC/B,SAAS,sBAAsB;AAC/B,SAAS,0BAA0B;AAc5B,MAAM,uBAAuB,KAAK,SAASA,sBACjD,OACC;AACD,QAAM;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA;AAAA,IAEA;AAAA,IACA;AAAA,EACD,IAAI;AACJ,QAAM,SAAS,UAAU;AACzB,QAAM,MAAM,eAAe;AAE3B,QAAM,YAAY,OAAO,KAAK;AAC9B,QAAM,iCAAiC,OAA2B,IAAI;AAEtE,QAAM;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACD,IAAI,QAAQ,MAAM;AACjB,UAAM,kBAAkB,MAAM;AAC7B,gBAAU,UAAU;AACpB,aAAO,oBAAoB,aAAa,eAAe;AAKvD,YAAM,eAAe,+BAA+B;AACpD,UAAI,gBAAgB,CAAC,YAAY,OAAO,EAAE,SAAS,aAAa,QAAQ,GAAG;AAC1E,qBAAa,MAAM;AAAA,MACpB;AACA,qCAA+B,UAAU;AAAA,IAC1C;AAEA,UAAMC,qBAAoB,CAAC,MAA6C;AACvE,YAAM,EAAE,GAAG,IAAI,EAAE,cAAc;AAC/B,UAAI,MAAM,SAAS,YAAY,MAAM,UAAU,GAAI;AAEnD,aAAO,yBAAyB,mBAAmB;AACnD,oBAAc,OAAO,EAAO;AAAA,IAC7B;AAEA,UAAMC,2BAA0B,CAAC,MAA6C;AAC7E,YAAM,EAAE,GAAG,IAAI,EAAE,cAAc;AAE/B,aAAO,yBAAyB,mBAAmB;AACnD,oBAAc,OAAO,EAAO;AAE5B,gBAAU,UAAU;AACpB,qCAA+B,UAAU,SAAS;AAClD,aAAO,iBAAiB,aAAa,eAAe;AAAA,IACrD;AAEA,UAAMC,4BAA2B,CAAC,MAA6C;AAC9E,UAAI,CAAC,UAAU,QAAS;AAExB,YAAM,EAAE,GAAG,IAAI,EAAE,cAAc;AAC/B,oBAAc,OAAO,EAAO;AAAA,IAC7B;AAEA,UAAMC,yBAAwB,CAAC,MAA6C;AAC3E,YAAM,EAAE,GAAG,IAAI,EAAE,cAAc;AAC/B,UAAI,MAAM,SAAS,YAAY,MAAM,UAAU,GAAI;AAEnD,oBAAc,OAAO,EAAO;AAAA,IAC7B;AAEA,WAAO;AAAA,MACN,mBAAAH;AAAA,MACA,yBAAAC;AAAA,MACA,0BAAAC;AAAA,MACA,uBAAAC;AAAA,IACD;AAAA,EACD,GAAG,CAAC,OAAO,QAAQ,eAAe,KAAK,CAAC;AAExC,SACC,oBAAC,SAAI,eAAa,SAAS,MAAM,IAAI,WAAW,WAAW,oBAAoB,GAC7E,gBAAM,IAAI,CAAC,SACX;AAAA,IAAC;AAAA;AAAA,MACA,MAAK;AAAA,MAEL,WAAS,KAAK;AAAA,MACd,eAAa,SAAS,MAAM,IAAI,KAAK,KAAK;AAAA,MAC1C,cAAY,KAAK;AAAA,MACjB,cAAY,MAAM,SAAS,YAAY,MAAM,UAAU,KAAK,QAAQ,WAAW;AAAA,MAC/E,OAAO,QAAQ,aAAQ,IAAI,GAAG,MAAM,UAAU,KAAK,KAAK,EAAwB;AAAA,MAChF,WAAW,WAAW,0BAA0B;AAAA,MAChD,OACC,UAAW,oBACR,EAAE,OAAO,MAAM,KAAK,KAA4B,EAAE,MAAM,IACxD;AAAA,MAEJ,gBAAgB;AAAA,MAChB,eAAe;AAAA,MACf,aAAa;AAAA,MACb,SAAS;AAAA,MAET,8BAAC,sBAAmB,MAAM,KAAK,MAAM;AAAA;AAAA,IAjBhC,KAAK;AAAA,EAkBX,CACA,GACF;AAEF,CAAC;", -+ "sourcesContent": ["import {\n\tDefaultColorStyle,\n\tSharedStyle,\n\tStyleProp,\n\tTLDefaultColorStyle,\n\tTLDefaultColorTheme,\n\tuseContainer,\n\tuseEditor,\n} from '@tldraw/editor'\nimport classNames from 'classnames'\nimport { ReactElement, memo, useMemo, useRef } from 'react'\nimport { StyleValuesForUi } from '../../../styles'\nimport { TLUiTranslationKey } from '../../hooks/useTranslation/TLUiTranslationKey'\nimport { useTranslation } from '../../hooks/useTranslation/useTranslation'\nimport { TldrawUiButton } from './Button/TldrawUiButton'\nimport { TldrawUiButtonIcon } from './Button/TldrawUiButtonIcon'\n\n/** @public */\nexport interface TLUiButtonPickerProps {\n\ttitle: string\n\tuiType: string\n\tstyle: StyleProp\n\tvalue: SharedStyle\n\titems: StyleValuesForUi\n\ttheme: TLDefaultColorTheme\n\tonValueChange(style: StyleProp, value: T): void\n}\n\n/** @public */\nexport const TldrawUiButtonPicker = memo(function TldrawUiButtonPicker(\n\tprops: TLUiButtonPickerProps\n) {\n\tconst {\n\t\tuiType,\n\t\titems,\n\t\ttitle,\n\t\tstyle,\n\t\tvalue,\n\t\t// columns = clamp(items.length, 2, 4),\n\t\tonValueChange,\n\t\ttheme,\n\t} = props\n\tconst editor = useEditor();\n\tconst container = useContainer();\n\tconst msg = useTranslation()\n\n\tconst rPointing = useRef(false)\n\tconst rPointingOriginalActiveElement = useRef(null)\n\n\tconst {\n\t\thandleButtonClick,\n\t\thandleButtonPointerDown,\n\t\thandleButtonPointerEnter,\n\t\thandleButtonPointerUp,\n\t} = useMemo(() => {\n\t\tconst handlePointerUp = () => {\n\t\t\trPointing.current = false\n\t\t\tcontainer.win.removeEventListener('pointerup', handlePointerUp)\n\n\t\t\t// This is fun little micro-optimization to make sure that the focus\n\t\t\t// is retained on a text label. That way, you can continue typing\n\t\t\t// after selecting a style.\n\t\t\tconst origActiveEl = rPointingOriginalActiveElement.current\n\t\t\tif (origActiveEl && ['TEXTAREA', 'INPUT'].includes(origActiveEl.nodeName)) {\n\t\t\t\torigActiveEl.focus()\n\t\t\t}\n\t\t\trPointingOriginalActiveElement.current = null\n\t\t}\n\n\t\tconst handleButtonClick = (e: React.PointerEvent) => {\n\t\t\tconst { id } = e.currentTarget.dataset\n\t\t\tif (value.type === 'shared' && value.value === id) return\n\n\t\t\teditor.markHistoryStoppingPoint('point picker item')\n\t\t\tonValueChange(style, id as T)\n\t\t}\n\n\t\tconst handleButtonPointerDown = (e: React.PointerEvent) => {\n\t\t\tconst { id } = e.currentTarget.dataset\n\n\t\t\teditor.markHistoryStoppingPoint('point picker item')\n\t\t\tonValueChange(style, id as T)\n\n\t\t\trPointing.current = true\n\t\t\trPointingOriginalActiveElement.current = container.ownerDocument.activeElement as HTMLElement\n\t\t\tcontainer.win.addEventListener('pointerup', handlePointerUp) // see TLD-658\n\t\t}\n\n\t\tconst handleButtonPointerEnter = (e: React.PointerEvent) => {\n\t\t\tif (!rPointing.current) return\n\n\t\t\tconst { id } = e.currentTarget.dataset\n\t\t\tonValueChange(style, id as T)\n\t\t}\n\n\t\tconst handleButtonPointerUp = (e: React.PointerEvent) => {\n\t\t\tconst { id } = e.currentTarget.dataset\n\t\t\tif (value.type === 'shared' && value.value === id) return\n\n\t\t\tonValueChange(style, id as T)\n\t\t}\n\n\t\treturn {\n\t\t\thandleButtonClick,\n\t\t\thandleButtonPointerDown,\n\t\t\thandleButtonPointerEnter,\n\t\t\thandleButtonPointerUp,\n\t\t}\n\t}, [value, editor, onValueChange, style, container])\n\n\treturn (\n\t\t
\n\t\t\t{items.map((item) => (\n\t\t\t\t)\n\t\t\t\t\t\t\t? { color: theme[item.value as TLDefaultColorStyle].solid }\n\t\t\t\t\t\t\t: undefined\n\t\t\t\t\t}\n\t\t\t\t\tonPointerEnter={handleButtonPointerEnter}\n\t\t\t\t\tonPointerDown={handleButtonPointerDown}\n\t\t\t\t\tonPointerUp={handleButtonPointerUp}\n\t\t\t\t\tonClick={handleButtonClick}\n\t\t\t\t>\n\t\t\t\t\t\n\t\t\t\t\n\t\t\t))}\n\t\t
\n\t)\n}) as (props: TLUiButtonPickerProps) => ReactElement\n"], -+ "mappings": "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", - "names": ["TldrawUiButtonPicker", "handleButtonClick", "handleButtonPointerDown", "handleButtonPointerEnter", "handleButtonPointerUp"] - } -diff --git a/node_modules/tldraw/dist-esm/lib/ui/hooks/useClipboardEvents.mjs b/node_modules/tldraw/dist-esm/lib/ui/hooks/useClipboardEvents.mjs -index e839170..ac053c1 100644 ---- a/node_modules/tldraw/dist-esm/lib/ui/hooks/useClipboardEvents.mjs -+++ b/node_modules/tldraw/dist-esm/lib/ui/hooks/useClipboardEvents.mjs -@@ -4,6 +4,7 @@ import { - preventDefault, - stopEventPropagation, - uniq, -+ useContainer, - useEditor, - useValue - } from "@tldraw/editor"; -@@ -369,6 +370,7 @@ function useMenuClipboardEvents() { - }; - } - function useNativeClipboardEvents() { -+ const container = useContainer(); - const editor = useEditor(); - const trackEvent = useUiEvents(); - const appIsFocused = useValue("editor.isFocused", () => editor.getInstanceState().isFocused, [ -@@ -425,17 +427,17 @@ function useNativeClipboardEvents() { - preventDefault(e); - trackEvent("paste", { source: "kbd" }); - }; -- document.addEventListener("copy", copy); -- document.addEventListener("cut", cut); -- document.addEventListener("paste", paste); -- document.addEventListener("pointerup", pointerUpHandler); -+ container.ownerDocument.addEventListener("copy", copy); -+ container.ownerDocument.addEventListener("cut", cut); -+ container.ownerDocument.addEventListener("paste", paste); -+ container.ownerDocument.addEventListener("pointerup", pointerUpHandler); - return () => { -- document.removeEventListener("copy", copy); -- document.removeEventListener("cut", cut); -- document.removeEventListener("paste", paste); -- document.removeEventListener("pointerup", pointerUpHandler); -+ container.ownerDocument.removeEventListener("copy", copy); -+ container.ownerDocument.removeEventListener("cut", cut); -+ container.ownerDocument.removeEventListener("paste", paste); -+ container.ownerDocument.removeEventListener("pointerup", pointerUpHandler); - }; -- }, [editor, trackEvent, appIsFocused]); -+ }, [editor, trackEvent, appIsFocused, container]); - } - export { - isValidHttpURL, -diff --git a/node_modules/tldraw/dist-esm/lib/ui/hooks/useClipboardEvents.mjs.map b/node_modules/tldraw/dist-esm/lib/ui/hooks/useClipboardEvents.mjs.map -index 9ffe331..3a93f41 100644 ---- a/node_modules/tldraw/dist-esm/lib/ui/hooks/useClipboardEvents.mjs.map -+++ b/node_modules/tldraw/dist-esm/lib/ui/hooks/useClipboardEvents.mjs.map -@@ -1,7 +1,7 @@ - { - "version": 3, - "sources": ["../../../../src/lib/ui/hooks/useClipboardEvents.ts"], -- "sourcesContent": ["import {\n\tEditor,\n\tFileHelpers,\n\tTLExternalContentSource,\n\tVec,\n\tVecLike,\n\tisDefined,\n\tpreventDefault,\n\tstopEventPropagation,\n\tuniq,\n\tuseEditor,\n\tuseValue,\n} from '@tldraw/editor'\nimport lz from 'lz-string'\nimport { useCallback, useEffect } from 'react'\nimport { TLUiEventSource, useUiEvents } from '../context/events'\nimport { pasteExcalidrawContent } from './clipboard/pasteExcalidrawContent'\nimport { pasteFiles } from './clipboard/pasteFiles'\nimport { pasteTldrawContent } from './clipboard/pasteTldrawContent'\nimport { pasteUrl } from './clipboard/pasteUrl'\n\n/**\n * Strip HTML tags from a string.\n * @param html - The HTML to strip.\n * @internal\n */\nfunction stripHtml(html: string) {\n\t// See \n\tconst doc = document.implementation.createHTMLDocument('')\n\tdoc.documentElement.innerHTML = html.trim()\n\treturn doc.body.textContent || doc.body.innerText || ''\n}\n\n/** @public */\nexport const isValidHttpURL = (url: string) => {\n\ttry {\n\t\tconst u = new URL(url)\n\t\treturn u.protocol === 'http:' || u.protocol === 'https:'\n\t} catch (e) {\n\t\treturn false\n\t}\n}\n\n/** @public */\nconst getValidHttpURLList = (url: string) => {\n\tconst urls = url.split(/[\\n\\s]/)\n\tfor (const url of urls) {\n\t\ttry {\n\t\t\tconst u = new URL(url)\n\t\t\tif (!(u.protocol === 'http:' || u.protocol === 'https:')) {\n\t\t\t\treturn\n\t\t\t}\n\t\t} catch (e) {\n\t\t\treturn\n\t\t}\n\t}\n\treturn uniq(urls)\n}\n\n/** @public */\nconst isSvgText = (text: string) => {\n\treturn /^ -1))\n\t)\n}\n\n/**\n * Whether a ClipboardItem is a file.\n * @param item - The ClipboardItem to check.\n * @internal\n */\nconst isFile = (item: ClipboardItem) => {\n\treturn item.types.find((i) => i.match(/^image\\//))\n}\n\n/**\n * Handle text pasted into the editor.\n * @param editor - The editor instance.\n * @param data - The text to paste.\n * @param point - The point at which to paste the text.\n * @internal\n */\nconst handleText = (\n\teditor: Editor,\n\tdata: string,\n\tpoint?: VecLike,\n\tsources?: TLExternalContentSource[]\n) => {\n\tconst validUrlList = getValidHttpURLList(data)\n\tif (validUrlList) {\n\t\tfor (const url of validUrlList) {\n\t\t\tpasteUrl(editor, url, point)\n\t\t}\n\t} else if (isValidHttpURL(data)) {\n\t\tpasteUrl(editor, data, point)\n\t} else if (isSvgText(data)) {\n\t\teditor.markHistoryStoppingPoint('paste')\n\t\teditor.putExternalContent({\n\t\t\ttype: 'svg-text',\n\t\t\ttext: data,\n\t\t\tpoint,\n\t\t\tsources,\n\t\t})\n\t} else {\n\t\teditor.markHistoryStoppingPoint('paste')\n\t\teditor.putExternalContent({\n\t\t\ttype: 'text',\n\t\t\ttext: data,\n\t\t\tpoint,\n\t\t\tsources,\n\t\t})\n\t}\n}\n\n/**\n * Something found on the clipboard, either through the event's clipboard data or the browser's clipboard API.\n * @internal\n */\ntype ClipboardThing =\n\t| {\n\t\t\ttype: 'file'\n\t\t\tsource: Promise\n\t }\n\t| {\n\t\t\ttype: 'blob'\n\t\t\tsource: Promise\n\t }\n\t| {\n\t\t\ttype: 'url'\n\t\t\tsource: Promise\n\t }\n\t| {\n\t\t\ttype: 'html'\n\t\t\tsource: Promise\n\t }\n\t| {\n\t\t\ttype: 'text'\n\t\t\tsource: Promise\n\t }\n\t| {\n\t\t\ttype: string\n\t\t\tsource: Promise\n\t }\n\n/**\n * Handle a paste using event clipboard data. This is the \"original\"\n * paste method that uses the clipboard data from the paste event.\n * https://developer.mozilla.org/en-US/docs/Web/API/ClipboardEvent/clipboardData\n *\n * @param editor - The editor\n * @param clipboardData - The clipboard data\n * @param point - The point to paste at\n * @internal\n */\nconst handlePasteFromEventClipboardData = async (\n\teditor: Editor,\n\tclipboardData: DataTransfer,\n\tpoint?: VecLike\n) => {\n\t// Do not paste while in any editing state\n\tif (editor.getEditingShapeId() !== null) return\n\n\tif (!clipboardData) {\n\t\tthrow Error('No clipboard data')\n\t}\n\n\tconst things: ClipboardThing[] = []\n\n\tfor (const item of Object.values(clipboardData.items)) {\n\t\tswitch (item.kind) {\n\t\t\tcase 'file': {\n\t\t\t\t// files are always blobs\n\t\t\t\tthings.push({\n\t\t\t\t\ttype: 'file',\n\t\t\t\t\tsource: new Promise((r) => r(item.getAsFile())) as Promise,\n\t\t\t\t})\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'string': {\n\t\t\t\t// strings can be text or html\n\t\t\t\tif (item.type === 'text/html') {\n\t\t\t\t\tthings.push({\n\t\t\t\t\t\ttype: 'html',\n\t\t\t\t\t\tsource: new Promise((r) => item.getAsString(r)) as Promise,\n\t\t\t\t\t})\n\t\t\t\t} else if (item.type === 'text/plain') {\n\t\t\t\t\tthings.push({\n\t\t\t\t\t\ttype: 'text',\n\t\t\t\t\t\tsource: new Promise((r) => item.getAsString(r)) as Promise,\n\t\t\t\t\t})\n\t\t\t\t} else {\n\t\t\t\t\tthings.push({ type: item.type, source: new Promise((r) => item.getAsString(r)) })\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n\n\thandleClipboardThings(editor, things, point)\n}\n\n/**\n * Handle a paste using items retrieved from the Clipboard API.\n * https://developer.mozilla.org/en-US/docs/Web/API/ClipboardItem\n *\n * @param editor - The editor\n * @param clipboardItems - The clipboard items to handle\n * @param point - The point to paste at\n * @internal\n */\nconst handlePasteFromClipboardApi = async (\n\teditor: Editor,\n\tclipboardItems: ClipboardItem[],\n\tpoint?: VecLike\n) => {\n\t// We need to populate the array of clipboard things\n\t// based on the ClipboardItems from the Clipboard API.\n\t// This is done in a different way than when using\n\t// the clipboard data from the paste event.\n\n\tconst things: ClipboardThing[] = []\n\n\tfor (const item of clipboardItems) {\n\t\tif (isFile(item)) {\n\t\t\tfor (const type of item.types) {\n\t\t\t\tif (type.match(/^image\\//)) {\n\t\t\t\t\tthings.push({ type: 'blob', source: item.getType(type) })\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (item.types.includes('text/html')) {\n\t\t\tthings.push({\n\t\t\t\ttype: 'html',\n\t\t\t\tsource: (async () => {\n\t\t\t\t\tconst blob = await item.getType('text/html')\n\t\t\t\t\treturn await FileHelpers.blobToText(blob)\n\t\t\t\t})(),\n\t\t\t})\n\t\t}\n\n\t\tif (item.types.includes('text/uri-list')) {\n\t\t\tthings.push({\n\t\t\t\ttype: 'url',\n\t\t\t\tsource: (async () => {\n\t\t\t\t\tconst blob = await item.getType('text/uri-list')\n\t\t\t\t\treturn await FileHelpers.blobToText(blob)\n\t\t\t\t})(),\n\t\t\t})\n\t\t}\n\n\t\tif (item.types.includes('text/plain')) {\n\t\t\tthings.push({\n\t\t\t\ttype: 'text',\n\t\t\t\tsource: (async () => {\n\t\t\t\t\tconst blob = await item.getType('text/plain')\n\t\t\t\t\treturn await FileHelpers.blobToText(blob)\n\t\t\t\t})(),\n\t\t\t})\n\t\t}\n\t}\n\n\treturn await handleClipboardThings(editor, things, point)\n}\n\nasync function handleClipboardThings(editor: Editor, things: ClipboardThing[], point?: VecLike) {\n\t// 1. Handle files\n\t//\n\t// We need to handle files separately because if we want them to\n\t// be placed next to each other, we need to create them all at once.\n\n\tconst files = things.filter(\n\t\t(t) => (t.type === 'file' || t.type === 'blob') && t.source !== null\n\t) as Extract[]\n\n\t// Just paste the files, nothing else\n\tif (files.length) {\n\t\tif (files.length > editor.options.maxFilesAtOnce) {\n\t\t\tthrow Error('Too many files')\n\t\t}\n\t\tconst fileBlobs = await Promise.all(files.map((t) => t.source!))\n\t\tconst urls = (fileBlobs.filter(Boolean) as (File | Blob)[]).map((blob) =>\n\t\t\tURL.createObjectURL(blob)\n\t\t)\n\t\treturn await pasteFiles(editor, urls, point)\n\t}\n\n\t// 2. Generate clipboard results for non-file things\n\t//\n\t// Getting the source from the items is async, however they must be accessed syncronously;\n\t// we can't await them in a loop. So we'll map them to promises and await them all at once,\n\t// then make decisions based on what we find.\n\n\tconst results = await Promise.all(\n\t\tthings\n\t\t\t.filter((t) => t.type !== 'file')\n\t\t\t.map(\n\t\t\t\t(t) =>\n\t\t\t\t\tnew Promise((r) => {\n\t\t\t\t\t\tconst thing = t as Exclude\n\n\t\t\t\t\t\tif (thing.type === 'file') {\n\t\t\t\t\t\t\tr({ type: 'error', data: null, reason: 'unexpected file' })\n\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tthing.source.then((text) => {\n\t\t\t\t\t\t\t// first, see if we can find tldraw content, which is JSON inside of an html comment\n\t\t\t\t\t\t\tconst tldrawHtmlComment = text.match(/
]*>(.*)<\\/div>/)?.[1]\n\n\t\t\t\t\t\t\tif (tldrawHtmlComment) {\n\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\t// If we've found tldraw content in the html string, use that as JSON\n\t\t\t\t\t\t\t\t\tconst jsonComment = lz.decompressFromBase64(tldrawHtmlComment)\n\t\t\t\t\t\t\t\t\tif (jsonComment === null) {\n\t\t\t\t\t\t\t\t\t\tr({\n\t\t\t\t\t\t\t\t\t\t\ttype: 'error',\n\t\t\t\t\t\t\t\t\t\t\tdata: jsonComment,\n\t\t\t\t\t\t\t\t\t\t\treason: `found tldraw data comment but could not parse base64`,\n\t\t\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\tconst json = JSON.parse(jsonComment)\n\t\t\t\t\t\t\t\t\t\tif (json.type !== 'application/tldraw') {\n\t\t\t\t\t\t\t\t\t\t\tr({\n\t\t\t\t\t\t\t\t\t\t\t\ttype: 'error',\n\t\t\t\t\t\t\t\t\t\t\t\tdata: json,\n\t\t\t\t\t\t\t\t\t\t\t\treason: `found tldraw data comment but JSON was of a different type: ${json.type}`,\n\t\t\t\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t\tif (typeof json.data === 'string') {\n\t\t\t\t\t\t\t\t\t\t\tr({\n\t\t\t\t\t\t\t\t\t\t\t\ttype: 'error',\n\t\t\t\t\t\t\t\t\t\t\t\tdata: json,\n\t\t\t\t\t\t\t\t\t\t\t\treason:\n\t\t\t\t\t\t\t\t\t\t\t\t\t'found tldraw json but data was a string instead of a TLClipboardModel object',\n\t\t\t\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t\tr({ type: 'tldraw', data: json.data })\n\t\t\t\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t} catch (e: any) {\n\t\t\t\t\t\t\t\t\tr({\n\t\t\t\t\t\t\t\t\t\ttype: 'error',\n\t\t\t\t\t\t\t\t\t\tdata: tldrawHtmlComment,\n\t\t\t\t\t\t\t\t\t\treason:\n\t\t\t\t\t\t\t\t\t\t\t'found tldraw json but data was a string instead of a TLClipboardModel object',\n\t\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tif (thing.type === 'html') {\n\t\t\t\t\t\t\t\t\tr({ type: 'text', data: text, subtype: 'html' })\n\t\t\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tif (thing.type === 'url') {\n\t\t\t\t\t\t\t\t\tr({ type: 'text', data: text, subtype: 'url' })\n\t\t\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t// if we have not found a tldraw comment, Otherwise, try to parse the text as JSON directly.\n\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\tconst json = JSON.parse(text)\n\t\t\t\t\t\t\t\t\tif (json.type === 'excalidraw/clipboard') {\n\t\t\t\t\t\t\t\t\t\t// If the clipboard contains content copied from excalidraw, then paste that\n\t\t\t\t\t\t\t\t\t\tr({ type: 'excalidraw', data: json })\n\t\t\t\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\tr({ type: 'text', data: text, subtype: 'json' })\n\t\t\t\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t} catch (e) {\n\t\t\t\t\t\t\t\t\t// If we could not parse the text as JSON, then it's just text\n\t\t\t\t\t\t\t\t\tr({ type: 'text', data: text, subtype: 'text' })\n\t\t\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tr({ type: 'error', data: text, reason: 'unhandled case' })\n\t\t\t\t\t\t})\n\t\t\t\t\t})\n\t\t\t)\n\t)\n\n\t// 3.\n\t//\n\t// Now that we know what kind of stuff we're dealing with, we can actual create some content.\n\t// There are priorities here, so order matters: we've already handled images and files, which\n\t// take first priority; then we want to handle tldraw content, then excalidraw content, then\n\t// html content, then links, and finally text content.\n\n\t// Try to paste tldraw content\n\tfor (const result of results) {\n\t\tif (result.type === 'tldraw') {\n\t\t\tpasteTldrawContent(editor, result.data, point)\n\t\t\treturn\n\t\t}\n\t}\n\n\t// Try to paste excalidraw content\n\tfor (const result of results) {\n\t\tif (result.type === 'excalidraw') {\n\t\t\tpasteExcalidrawContent(editor, result.data, point)\n\t\t\treturn\n\t\t}\n\t}\n\n\t// Try to paste html content\n\tfor (const result of results) {\n\t\tif (result.type === 'text' && result.subtype === 'html') {\n\t\t\t// try to find a link\n\t\t\tconst rootNode = new DOMParser().parseFromString(result.data, 'text/html')\n\t\t\tconst bodyNode = rootNode.querySelector('body')\n\n\t\t\t// Edge on Windows 11 home appears to paste a link as a single in\n\t\t\t// the HTML document. If we're pasting a single like tag we'll just\n\t\t\t// assume the user meant to paste the URL.\n\t\t\tconst isHtmlSingleLink =\n\t\t\t\tbodyNode &&\n\t\t\t\tArray.from(bodyNode.children).filter((el) => el.nodeType === 1).length === 1 &&\n\t\t\t\tbodyNode.firstElementChild &&\n\t\t\t\tbodyNode.firstElementChild.tagName === 'A' &&\n\t\t\t\tbodyNode.firstElementChild.hasAttribute('href') &&\n\t\t\t\tbodyNode.firstElementChild.getAttribute('href') !== ''\n\n\t\t\tif (isHtmlSingleLink) {\n\t\t\t\tconst href = bodyNode.firstElementChild.getAttribute('href')!\n\t\t\t\thandleText(editor, href, point, results)\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\t// If the html is NOT a link, and we have NO OTHER texty content, then paste the html as text\n\t\t\tif (!results.some((r) => r.type === 'text' && r.subtype !== 'html') && result.data.trim()) {\n\t\t\t\thandleText(editor, stripHtml(result.data), point, results)\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t}\n\n\t// Try to paste a link\n\tfor (const result of results) {\n\t\tif (result.type === 'text' && result.subtype === 'url') {\n\t\t\tpasteUrl(editor, result.data, point, results)\n\t\t\treturn\n\t\t}\n\t}\n\n\t// Finally, if we haven't bailed on anything yet, we can paste text content\n\tfor (const result of results) {\n\t\tif (result.type === 'text' && result.subtype === 'text' && result.data.trim()) {\n\t\t\t// The clipboard may include multiple text items, but we only want to paste the first one\n\t\t\thandleText(editor, result.data, point, results)\n\t\t\treturn\n\t\t}\n\t}\n}\n\n/**\n * When the user copies, write the contents to local storage and to the clipboard\n *\n * @param editor - The editor instance.\n * @public\n */\nconst handleNativeOrMenuCopy = async (editor: Editor) => {\n\tconst content = await editor.resolveAssetsInContent(\n\t\teditor.getContentFromCurrentPage(editor.getSelectedShapeIds())\n\t)\n\tif (!content) {\n\t\tif (navigator && navigator.clipboard) {\n\t\t\tnavigator.clipboard.writeText('')\n\t\t}\n\t\treturn\n\t}\n\n\tconst stringifiedClipboard = lz.compressToBase64(\n\t\tJSON.stringify({\n\t\t\ttype: 'application/tldraw',\n\t\t\tkind: 'content',\n\t\t\tdata: content,\n\t\t})\n\t)\n\n\tif (typeof navigator === 'undefined') {\n\t\treturn\n\t} else {\n\t\t// Extract the text from the clipboard\n\t\tconst textItems = content.shapes\n\t\t\t.map((shape) => {\n\t\t\t\tconst util = editor.getShapeUtil(shape)\n\t\t\t\treturn util.getText(shape)\n\t\t\t})\n\t\t\t.filter(isDefined)\n\n\t\tif (navigator.clipboard?.write) {\n\t\t\tconst htmlBlob = new Blob([`
${stringifiedClipboard}
`], {\n\t\t\t\ttype: 'text/html',\n\t\t\t})\n\n\t\t\tlet textContent = textItems.join(' ')\n\n\t\t\t// This is a bug in chrome android where it won't paste content if\n\t\t\t// the text/plain content is \"\" so we need to always add an empty\n\t\t\t// space \uD83E\uDD2C\n\t\t\tif (textContent === '') {\n\t\t\t\ttextContent = ' '\n\t\t\t}\n\n\t\t\tnavigator.clipboard.write([\n\t\t\t\tnew ClipboardItem({\n\t\t\t\t\t'text/html': htmlBlob,\n\t\t\t\t\t// What is this second blob used for?\n\t\t\t\t\t'text/plain': new Blob([textContent], { type: 'text/plain' }),\n\t\t\t\t}),\n\t\t\t])\n\t\t} else if (navigator.clipboard.writeText) {\n\t\t\tnavigator.clipboard.writeText(`
${stringifiedClipboard}
`)\n\t\t}\n\t}\n}\n\n/** @public */\nexport function useMenuClipboardEvents() {\n\tconst editor = useEditor()\n\tconst trackEvent = useUiEvents()\n\n\tconst copy = useCallback(\n\t\tasync function onCopy(source: TLUiEventSource) {\n\t\t\tif (editor.getSelectedShapeIds().length === 0) return\n\n\t\t\tawait handleNativeOrMenuCopy(editor)\n\t\t\ttrackEvent('copy', { source })\n\t\t},\n\t\t[editor, trackEvent]\n\t)\n\n\tconst cut = useCallback(\n\t\tasync function onCut(source: TLUiEventSource) {\n\t\t\tif (editor.getSelectedShapeIds().length === 0) return\n\n\t\t\tawait handleNativeOrMenuCopy(editor)\n\t\t\teditor.deleteShapes(editor.getSelectedShapeIds())\n\t\t\ttrackEvent('cut', { source })\n\t\t},\n\t\t[editor, trackEvent]\n\t)\n\n\tconst paste = useCallback(\n\t\tasync function onPaste(\n\t\t\tdata: DataTransfer | ClipboardItem[],\n\t\t\tsource: TLUiEventSource,\n\t\t\tpoint?: VecLike\n\t\t) {\n\t\t\t// If we're editing a shape, or we are focusing an editable input, then\n\t\t\t// we would want the user's paste interaction to go to that element or\n\t\t\t// input instead; e.g. when pasting text into a text shape's content\n\t\t\tif (editor.getEditingShapeId() !== null) return\n\n\t\t\tif (Array.isArray(data) && data[0] instanceof ClipboardItem) {\n\t\t\t\thandlePasteFromClipboardApi(editor, data, point)\n\t\t\t\ttrackEvent('paste', { source: 'menu' })\n\t\t\t} else {\n\t\t\t\t// Read it first and then recurse, kind of weird\n\t\t\t\tnavigator.clipboard.read().then((clipboardItems) => {\n\t\t\t\t\tpaste(clipboardItems, source, point)\n\t\t\t\t})\n\t\t\t}\n\t\t},\n\t\t[editor, trackEvent]\n\t)\n\n\treturn {\n\t\tcopy,\n\t\tcut,\n\t\tpaste,\n\t}\n}\n\n/** @public */\nexport function useNativeClipboardEvents() {\n\tconst editor = useEditor()\n\tconst trackEvent = useUiEvents()\n\n\tconst appIsFocused = useValue('editor.isFocused', () => editor.getInstanceState().isFocused, [\n\t\teditor,\n\t])\n\n\tuseEffect(() => {\n\t\tif (!appIsFocused) return\n\t\tconst copy = async (e: ClipboardEvent) => {\n\t\t\tif (\n\t\t\t\teditor.getSelectedShapeIds().length === 0 ||\n\t\t\t\teditor.getEditingShapeId() !== null ||\n\t\t\t\tdisallowClipboardEvents(editor)\n\t\t\t) {\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tpreventDefault(e)\n\t\t\tawait handleNativeOrMenuCopy(editor)\n\t\t\ttrackEvent('copy', { source: 'kbd' })\n\t\t}\n\n\t\tasync function cut(e: ClipboardEvent) {\n\t\t\tif (\n\t\t\t\teditor.getSelectedShapeIds().length === 0 ||\n\t\t\t\teditor.getEditingShapeId() !== null ||\n\t\t\t\tdisallowClipboardEvents(editor)\n\t\t\t) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tpreventDefault(e)\n\t\t\tawait handleNativeOrMenuCopy(editor)\n\t\t\teditor.deleteShapes(editor.getSelectedShapeIds())\n\t\t\ttrackEvent('cut', { source: 'kbd' })\n\t\t}\n\n\t\tlet disablingMiddleClickPaste = false\n\t\tconst pointerUpHandler = (e: PointerEvent) => {\n\t\t\tif (e.button === 1) {\n\t\t\t\t// middle mouse button\n\t\t\t\tdisablingMiddleClickPaste = true\n\t\t\t\teditor.timers.requestAnimationFrame(() => {\n\t\t\t\t\tdisablingMiddleClickPaste = false\n\t\t\t\t})\n\t\t\t}\n\t\t}\n\n\t\tconst paste = (e: ClipboardEvent) => {\n\t\t\tif (disablingMiddleClickPaste) {\n\t\t\t\tstopEventPropagation(e)\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\t// If we're editing a shape, or we are focusing an editable input, then\n\t\t\t// we would want the user's paste interaction to go to that element or\n\t\t\t// input instead; e.g. when pasting text into a text shape's content\n\t\t\tif (editor.getEditingShapeId() !== null || disallowClipboardEvents(editor)) return\n\n\t\t\t// Where should the shapes go?\n\t\t\tlet point: Vec | undefined = undefined\n\t\t\tlet pasteAtCursor = false\n\n\t\t\t// | Shiftkey | Paste at cursor mode | Paste at point? |\n\t\t\t// | N \t\t| N | N \t\t\t\t |\n\t\t\t// | Y \t\t| N | Y \t\t\t\t |\n\t\t\t// | N \t\t| Y | Y \t\t\t\t |\n\t\t\t// | Y \t\t| Y | N \t\t\t\t |\n\t\t\tif (editor.inputs.shiftKey) pasteAtCursor = true\n\t\t\tif (editor.user.getIsPasteAtCursorMode()) pasteAtCursor = !pasteAtCursor\n\t\t\tif (pasteAtCursor) point = editor.inputs.currentPagePoint\n\n\t\t\t// First try to use the clipboard data on the event\n\t\t\tif (e.clipboardData && !editor.inputs.shiftKey) {\n\t\t\t\thandlePasteFromEventClipboardData(editor, e.clipboardData, point)\n\t\t\t} else {\n\t\t\t\t// Or else use the clipboard API\n\t\t\t\tnavigator.clipboard.read().then((clipboardItems) => {\n\t\t\t\t\tif (Array.isArray(clipboardItems) && clipboardItems[0] instanceof ClipboardItem) {\n\t\t\t\t\t\thandlePasteFromClipboardApi(editor, clipboardItems, point)\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t}\n\n\t\t\tpreventDefault(e)\n\t\t\ttrackEvent('paste', { source: 'kbd' })\n\t\t}\n\n\t\tdocument.addEventListener('copy', copy)\n\t\tdocument.addEventListener('cut', cut)\n\t\tdocument.addEventListener('paste', paste)\n\t\tdocument.addEventListener('pointerup', pointerUpHandler)\n\n\t\treturn () => {\n\t\t\tdocument.removeEventListener('copy', copy)\n\t\t\tdocument.removeEventListener('cut', cut)\n\t\t\tdocument.removeEventListener('paste', paste)\n\t\t\tdocument.removeEventListener('pointerup', pointerUpHandler)\n\t\t}\n\t}, [editor, trackEvent, appIsFocused])\n}\n"], -- "mappings": "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", -+ "sourcesContent": ["import {\n\tEditor,\n\tFileHelpers,\n\tTLExternalContentSource,\n\tVec,\n\tVecLike,\n\tisDefined,\n\tpreventDefault,\n\tstopEventPropagation,\n\tuniq,\n\tuseContainer,\n\tuseEditor,\n\tuseValue,\n} from '@tldraw/editor'\nimport lz from 'lz-string'\nimport { useCallback, useEffect } from 'react'\nimport { TLUiEventSource, useUiEvents } from '../context/events'\nimport { pasteExcalidrawContent } from './clipboard/pasteExcalidrawContent'\nimport { pasteFiles } from './clipboard/pasteFiles'\nimport { pasteTldrawContent } from './clipboard/pasteTldrawContent'\nimport { pasteUrl } from './clipboard/pasteUrl'\n\n/**\n * Strip HTML tags from a string.\n * @param html - The HTML to strip.\n * @internal\n */\nfunction stripHtml(html: string) {\n\t// See \n\tconst doc = document.implementation.createHTMLDocument('')\n\tdoc.documentElement.innerHTML = html.trim()\n\treturn doc.body.textContent || doc.body.innerText || ''\n}\n\n/** @public */\nexport const isValidHttpURL = (url: string) => {\n\ttry {\n\t\tconst u = new URL(url)\n\t\treturn u.protocol === 'http:' || u.protocol === 'https:'\n\t} catch (e) {\n\t\treturn false\n\t}\n}\n\n/** @public */\nconst getValidHttpURLList = (url: string) => {\n\tconst urls = url.split(/[\\n\\s]/)\n\tfor (const url of urls) {\n\t\ttry {\n\t\t\tconst u = new URL(url)\n\t\t\tif (!(u.protocol === 'http:' || u.protocol === 'https:')) {\n\t\t\t\treturn\n\t\t\t}\n\t\t} catch (e) {\n\t\t\treturn\n\t\t}\n\t}\n\treturn uniq(urls)\n}\n\n/** @public */\nconst isSvgText = (text: string) => {\n\treturn /^ -1))\n\t)\n}\n\n/**\n * Whether a ClipboardItem is a file.\n * @param item - The ClipboardItem to check.\n * @internal\n */\nconst isFile = (item: ClipboardItem) => {\n\treturn item.types.find((i) => i.match(/^image\\//))\n}\n\n/**\n * Handle text pasted into the editor.\n * @param editor - The editor instance.\n * @param data - The text to paste.\n * @param point - The point at which to paste the text.\n * @internal\n */\nconst handleText = (\n\teditor: Editor,\n\tdata: string,\n\tpoint?: VecLike,\n\tsources?: TLExternalContentSource[]\n) => {\n\tconst validUrlList = getValidHttpURLList(data)\n\tif (validUrlList) {\n\t\tfor (const url of validUrlList) {\n\t\t\tpasteUrl(editor, url, point)\n\t\t}\n\t} else if (isValidHttpURL(data)) {\n\t\tpasteUrl(editor, data, point)\n\t} else if (isSvgText(data)) {\n\t\teditor.markHistoryStoppingPoint('paste')\n\t\teditor.putExternalContent({\n\t\t\ttype: 'svg-text',\n\t\t\ttext: data,\n\t\t\tpoint,\n\t\t\tsources,\n\t\t})\n\t} else {\n\t\teditor.markHistoryStoppingPoint('paste')\n\t\teditor.putExternalContent({\n\t\t\ttype: 'text',\n\t\t\ttext: data,\n\t\t\tpoint,\n\t\t\tsources,\n\t\t})\n\t}\n}\n\n/**\n * Something found on the clipboard, either through the event's clipboard data or the browser's clipboard API.\n * @internal\n */\ntype ClipboardThing =\n\t| {\n\t\t\ttype: 'file'\n\t\t\tsource: Promise\n\t }\n\t| {\n\t\t\ttype: 'blob'\n\t\t\tsource: Promise\n\t }\n\t| {\n\t\t\ttype: 'url'\n\t\t\tsource: Promise\n\t }\n\t| {\n\t\t\ttype: 'html'\n\t\t\tsource: Promise\n\t }\n\t| {\n\t\t\ttype: 'text'\n\t\t\tsource: Promise\n\t }\n\t| {\n\t\t\ttype: string\n\t\t\tsource: Promise\n\t }\n\n/**\n * Handle a paste using event clipboard data. This is the \"original\"\n * paste method that uses the clipboard data from the paste event.\n * https://developer.mozilla.org/en-US/docs/Web/API/ClipboardEvent/clipboardData\n *\n * @param editor - The editor\n * @param clipboardData - The clipboard data\n * @param point - The point to paste at\n * @internal\n */\nconst handlePasteFromEventClipboardData = async (\n\teditor: Editor,\n\tclipboardData: DataTransfer,\n\tpoint?: VecLike\n) => {\n\t// Do not paste while in any editing state\n\tif (editor.getEditingShapeId() !== null) return\n\n\tif (!clipboardData) {\n\t\tthrow Error('No clipboard data')\n\t}\n\n\tconst things: ClipboardThing[] = []\n\n\tfor (const item of Object.values(clipboardData.items)) {\n\t\tswitch (item.kind) {\n\t\t\tcase 'file': {\n\t\t\t\t// files are always blobs\n\t\t\t\tthings.push({\n\t\t\t\t\ttype: 'file',\n\t\t\t\t\tsource: new Promise((r) => r(item.getAsFile())) as Promise,\n\t\t\t\t})\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'string': {\n\t\t\t\t// strings can be text or html\n\t\t\t\tif (item.type === 'text/html') {\n\t\t\t\t\tthings.push({\n\t\t\t\t\t\ttype: 'html',\n\t\t\t\t\t\tsource: new Promise((r) => item.getAsString(r)) as Promise,\n\t\t\t\t\t})\n\t\t\t\t} else if (item.type === 'text/plain') {\n\t\t\t\t\tthings.push({\n\t\t\t\t\t\ttype: 'text',\n\t\t\t\t\t\tsource: new Promise((r) => item.getAsString(r)) as Promise,\n\t\t\t\t\t})\n\t\t\t\t} else {\n\t\t\t\t\tthings.push({ type: item.type, source: new Promise((r) => item.getAsString(r)) })\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n\n\thandleClipboardThings(editor, things, point)\n}\n\n/**\n * Handle a paste using items retrieved from the Clipboard API.\n * https://developer.mozilla.org/en-US/docs/Web/API/ClipboardItem\n *\n * @param editor - The editor\n * @param clipboardItems - The clipboard items to handle\n * @param point - The point to paste at\n * @internal\n */\nconst handlePasteFromClipboardApi = async (\n\teditor: Editor,\n\tclipboardItems: ClipboardItem[],\n\tpoint?: VecLike\n) => {\n\t// We need to populate the array of clipboard things\n\t// based on the ClipboardItems from the Clipboard API.\n\t// This is done in a different way than when using\n\t// the clipboard data from the paste event.\n\n\tconst things: ClipboardThing[] = []\n\n\tfor (const item of clipboardItems) {\n\t\tif (isFile(item)) {\n\t\t\tfor (const type of item.types) {\n\t\t\t\tif (type.match(/^image\\//)) {\n\t\t\t\t\tthings.push({ type: 'blob', source: item.getType(type) })\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (item.types.includes('text/html')) {\n\t\t\tthings.push({\n\t\t\t\ttype: 'html',\n\t\t\t\tsource: (async () => {\n\t\t\t\t\tconst blob = await item.getType('text/html')\n\t\t\t\t\treturn await FileHelpers.blobToText(blob)\n\t\t\t\t})(),\n\t\t\t})\n\t\t}\n\n\t\tif (item.types.includes('text/uri-list')) {\n\t\t\tthings.push({\n\t\t\t\ttype: 'url',\n\t\t\t\tsource: (async () => {\n\t\t\t\t\tconst blob = await item.getType('text/uri-list')\n\t\t\t\t\treturn await FileHelpers.blobToText(blob)\n\t\t\t\t})(),\n\t\t\t})\n\t\t}\n\n\t\tif (item.types.includes('text/plain')) {\n\t\t\tthings.push({\n\t\t\t\ttype: 'text',\n\t\t\t\tsource: (async () => {\n\t\t\t\t\tconst blob = await item.getType('text/plain')\n\t\t\t\t\treturn await FileHelpers.blobToText(blob)\n\t\t\t\t})(),\n\t\t\t})\n\t\t}\n\t}\n\n\treturn await handleClipboardThings(editor, things, point)\n}\n\nasync function handleClipboardThings(editor: Editor, things: ClipboardThing[], point?: VecLike) {\n\t// 1. Handle files\n\t//\n\t// We need to handle files separately because if we want them to\n\t// be placed next to each other, we need to create them all at once.\n\n\tconst files = things.filter(\n\t\t(t) => (t.type === 'file' || t.type === 'blob') && t.source !== null\n\t) as Extract[]\n\n\t// Just paste the files, nothing else\n\tif (files.length) {\n\t\tif (files.length > editor.options.maxFilesAtOnce) {\n\t\t\tthrow Error('Too many files')\n\t\t}\n\t\tconst fileBlobs = await Promise.all(files.map((t) => t.source!))\n\t\tconst urls = (fileBlobs.filter(Boolean) as (File | Blob)[]).map((blob) =>\n\t\t\tURL.createObjectURL(blob)\n\t\t)\n\t\treturn await pasteFiles(editor, urls, point)\n\t}\n\n\t// 2. Generate clipboard results for non-file things\n\t//\n\t// Getting the source from the items is async, however they must be accessed syncronously;\n\t// we can't await them in a loop. So we'll map them to promises and await them all at once,\n\t// then make decisions based on what we find.\n\n\tconst results = await Promise.all(\n\t\tthings\n\t\t\t.filter((t) => t.type !== 'file')\n\t\t\t.map(\n\t\t\t\t(t) =>\n\t\t\t\t\tnew Promise((r) => {\n\t\t\t\t\t\tconst thing = t as Exclude\n\n\t\t\t\t\t\tif (thing.type === 'file') {\n\t\t\t\t\t\t\tr({ type: 'error', data: null, reason: 'unexpected file' })\n\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tthing.source.then((text) => {\n\t\t\t\t\t\t\t// first, see if we can find tldraw content, which is JSON inside of an html comment\n\t\t\t\t\t\t\tconst tldrawHtmlComment = text.match(/
]*>(.*)<\\/div>/)?.[1]\n\n\t\t\t\t\t\t\tif (tldrawHtmlComment) {\n\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\t// If we've found tldraw content in the html string, use that as JSON\n\t\t\t\t\t\t\t\t\tconst jsonComment = lz.decompressFromBase64(tldrawHtmlComment)\n\t\t\t\t\t\t\t\t\tif (jsonComment === null) {\n\t\t\t\t\t\t\t\t\t\tr({\n\t\t\t\t\t\t\t\t\t\t\ttype: 'error',\n\t\t\t\t\t\t\t\t\t\t\tdata: jsonComment,\n\t\t\t\t\t\t\t\t\t\t\treason: `found tldraw data comment but could not parse base64`,\n\t\t\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\tconst json = JSON.parse(jsonComment)\n\t\t\t\t\t\t\t\t\t\tif (json.type !== 'application/tldraw') {\n\t\t\t\t\t\t\t\t\t\t\tr({\n\t\t\t\t\t\t\t\t\t\t\t\ttype: 'error',\n\t\t\t\t\t\t\t\t\t\t\t\tdata: json,\n\t\t\t\t\t\t\t\t\t\t\t\treason: `found tldraw data comment but JSON was of a different type: ${json.type}`,\n\t\t\t\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t\tif (typeof json.data === 'string') {\n\t\t\t\t\t\t\t\t\t\t\tr({\n\t\t\t\t\t\t\t\t\t\t\t\ttype: 'error',\n\t\t\t\t\t\t\t\t\t\t\t\tdata: json,\n\t\t\t\t\t\t\t\t\t\t\t\treason:\n\t\t\t\t\t\t\t\t\t\t\t\t\t'found tldraw json but data was a string instead of a TLClipboardModel object',\n\t\t\t\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t\tr({ type: 'tldraw', data: json.data })\n\t\t\t\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t} catch (e: any) {\n\t\t\t\t\t\t\t\t\tr({\n\t\t\t\t\t\t\t\t\t\ttype: 'error',\n\t\t\t\t\t\t\t\t\t\tdata: tldrawHtmlComment,\n\t\t\t\t\t\t\t\t\t\treason:\n\t\t\t\t\t\t\t\t\t\t\t'found tldraw json but data was a string instead of a TLClipboardModel object',\n\t\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tif (thing.type === 'html') {\n\t\t\t\t\t\t\t\t\tr({ type: 'text', data: text, subtype: 'html' })\n\t\t\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tif (thing.type === 'url') {\n\t\t\t\t\t\t\t\t\tr({ type: 'text', data: text, subtype: 'url' })\n\t\t\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t// if we have not found a tldraw comment, Otherwise, try to parse the text as JSON directly.\n\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\tconst json = JSON.parse(text)\n\t\t\t\t\t\t\t\t\tif (json.type === 'excalidraw/clipboard') {\n\t\t\t\t\t\t\t\t\t\t// If the clipboard contains content copied from excalidraw, then paste that\n\t\t\t\t\t\t\t\t\t\tr({ type: 'excalidraw', data: json })\n\t\t\t\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\tr({ type: 'text', data: text, subtype: 'json' })\n\t\t\t\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t} catch (e) {\n\t\t\t\t\t\t\t\t\t// If we could not parse the text as JSON, then it's just text\n\t\t\t\t\t\t\t\t\tr({ type: 'text', data: text, subtype: 'text' })\n\t\t\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tr({ type: 'error', data: text, reason: 'unhandled case' })\n\t\t\t\t\t\t})\n\t\t\t\t\t})\n\t\t\t)\n\t)\n\n\t// 3.\n\t//\n\t// Now that we know what kind of stuff we're dealing with, we can actual create some content.\n\t// There are priorities here, so order matters: we've already handled images and files, which\n\t// take first priority; then we want to handle tldraw content, then excalidraw content, then\n\t// html content, then links, and finally text content.\n\n\t// Try to paste tldraw content\n\tfor (const result of results) {\n\t\tif (result.type === 'tldraw') {\n\t\t\tpasteTldrawContent(editor, result.data, point)\n\t\t\treturn\n\t\t}\n\t}\n\n\t// Try to paste excalidraw content\n\tfor (const result of results) {\n\t\tif (result.type === 'excalidraw') {\n\t\t\tpasteExcalidrawContent(editor, result.data, point)\n\t\t\treturn\n\t\t}\n\t}\n\n\t// Try to paste html content\n\tfor (const result of results) {\n\t\tif (result.type === 'text' && result.subtype === 'html') {\n\t\t\t// try to find a link\n\t\t\tconst rootNode = new DOMParser().parseFromString(result.data, 'text/html')\n\t\t\tconst bodyNode = rootNode.querySelector('body')\n\n\t\t\t// Edge on Windows 11 home appears to paste a link as a single in\n\t\t\t// the HTML document. If we're pasting a single like tag we'll just\n\t\t\t// assume the user meant to paste the URL.\n\t\t\tconst isHtmlSingleLink =\n\t\t\t\tbodyNode &&\n\t\t\t\tArray.from(bodyNode.children).filter((el) => el.nodeType === 1).length === 1 &&\n\t\t\t\tbodyNode.firstElementChild &&\n\t\t\t\tbodyNode.firstElementChild.tagName === 'A' &&\n\t\t\t\tbodyNode.firstElementChild.hasAttribute('href') &&\n\t\t\t\tbodyNode.firstElementChild.getAttribute('href') !== ''\n\n\t\t\tif (isHtmlSingleLink) {\n\t\t\t\tconst href = bodyNode.firstElementChild.getAttribute('href')!\n\t\t\t\thandleText(editor, href, point, results)\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\t// If the html is NOT a link, and we have NO OTHER texty content, then paste the html as text\n\t\t\tif (!results.some((r) => r.type === 'text' && r.subtype !== 'html') && result.data.trim()) {\n\t\t\t\thandleText(editor, stripHtml(result.data), point, results)\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t}\n\n\t// Try to paste a link\n\tfor (const result of results) {\n\t\tif (result.type === 'text' && result.subtype === 'url') {\n\t\t\tpasteUrl(editor, result.data, point, results)\n\t\t\treturn\n\t\t}\n\t}\n\n\t// Finally, if we haven't bailed on anything yet, we can paste text content\n\tfor (const result of results) {\n\t\tif (result.type === 'text' && result.subtype === 'text' && result.data.trim()) {\n\t\t\t// The clipboard may include multiple text items, but we only want to paste the first one\n\t\t\thandleText(editor, result.data, point, results)\n\t\t\treturn\n\t\t}\n\t}\n}\n\n/**\n * When the user copies, write the contents to local storage and to the clipboard\n *\n * @param editor - The editor instance.\n * @public\n */\nconst handleNativeOrMenuCopy = async (editor: Editor) => {\n\tconst content = await editor.resolveAssetsInContent(\n\t\teditor.getContentFromCurrentPage(editor.getSelectedShapeIds())\n\t)\n\tif (!content) {\n\t\tif (navigator && navigator.clipboard) {\n\t\t\tnavigator.clipboard.writeText('')\n\t\t}\n\t\treturn\n\t}\n\n\tconst stringifiedClipboard = lz.compressToBase64(\n\t\tJSON.stringify({\n\t\t\ttype: 'application/tldraw',\n\t\t\tkind: 'content',\n\t\t\tdata: content,\n\t\t})\n\t)\n\n\tif (typeof navigator === 'undefined') {\n\t\treturn\n\t} else {\n\t\t// Extract the text from the clipboard\n\t\tconst textItems = content.shapes\n\t\t\t.map((shape) => {\n\t\t\t\tconst util = editor.getShapeUtil(shape)\n\t\t\t\treturn util.getText(shape)\n\t\t\t})\n\t\t\t.filter(isDefined)\n\n\t\tif (navigator.clipboard?.write) {\n\t\t\tconst htmlBlob = new Blob([`
${stringifiedClipboard}
`], {\n\t\t\t\ttype: 'text/html',\n\t\t\t})\n\n\t\t\tlet textContent = textItems.join(' ')\n\n\t\t\t// This is a bug in chrome android where it won't paste content if\n\t\t\t// the text/plain content is \"\" so we need to always add an empty\n\t\t\t// space \uD83E\uDD2C\n\t\t\tif (textContent === '') {\n\t\t\t\ttextContent = ' '\n\t\t\t}\n\n\t\t\tnavigator.clipboard.write([\n\t\t\t\tnew ClipboardItem({\n\t\t\t\t\t'text/html': htmlBlob,\n\t\t\t\t\t// What is this second blob used for?\n\t\t\t\t\t'text/plain': new Blob([textContent], { type: 'text/plain' }),\n\t\t\t\t}),\n\t\t\t])\n\t\t} else if (navigator.clipboard.writeText) {\n\t\t\tnavigator.clipboard.writeText(`
${stringifiedClipboard}
`)\n\t\t}\n\t}\n}\n\n/** @public */\nexport function useMenuClipboardEvents() {\n\tconst editor = useEditor()\n\tconst trackEvent = useUiEvents()\n\n\tconst copy = useCallback(\n\t\tasync function onCopy(source: TLUiEventSource) {\n\t\t\tif (editor.getSelectedShapeIds().length === 0) return\n\n\t\t\tawait handleNativeOrMenuCopy(editor)\n\t\t\ttrackEvent('copy', { source })\n\t\t},\n\t\t[editor, trackEvent]\n\t)\n\n\tconst cut = useCallback(\n\t\tasync function onCut(source: TLUiEventSource) {\n\t\t\tif (editor.getSelectedShapeIds().length === 0) return\n\n\t\t\tawait handleNativeOrMenuCopy(editor)\n\t\t\teditor.deleteShapes(editor.getSelectedShapeIds())\n\t\t\ttrackEvent('cut', { source })\n\t\t},\n\t\t[editor, trackEvent]\n\t)\n\n\tconst paste = useCallback(\n\t\tasync function onPaste(\n\t\t\tdata: DataTransfer | ClipboardItem[],\n\t\t\tsource: TLUiEventSource,\n\t\t\tpoint?: VecLike\n\t\t) {\n\t\t\t// If we're editing a shape, or we are focusing an editable input, then\n\t\t\t// we would want the user's paste interaction to go to that element or\n\t\t\t// input instead; e.g. when pasting text into a text shape's content\n\t\t\tif (editor.getEditingShapeId() !== null) return\n\n\t\t\tif (Array.isArray(data) && data[0] instanceof ClipboardItem) {\n\t\t\t\thandlePasteFromClipboardApi(editor, data, point)\n\t\t\t\ttrackEvent('paste', { source: 'menu' })\n\t\t\t} else {\n\t\t\t\t// Read it first and then recurse, kind of weird\n\t\t\t\tnavigator.clipboard.read().then((clipboardItems) => {\n\t\t\t\t\tpaste(clipboardItems, source, point)\n\t\t\t\t})\n\t\t\t}\n\t\t},\n\t\t[editor, trackEvent]\n\t)\n\n\treturn {\n\t\tcopy,\n\t\tcut,\n\t\tpaste,\n\t}\n}\n\n/** @public */\nexport function useNativeClipboardEvents() {\n \tconst container = useContainer()\n \tconst editor = useEditor()\n\tconst trackEvent = useUiEvents()\n\n\tconst appIsFocused = useValue('editor.isFocused', () => editor.getInstanceState().isFocused, [\n\t\teditor,\n\t])\n\n\tuseEffect(() => {\n\t\tif (!appIsFocused) return\n\t\tconst copy = async (e: ClipboardEvent) => {\n\t\t\tif (\n\t\t\t\teditor.getSelectedShapeIds().length === 0 ||\n\t\t\t\teditor.getEditingShapeId() !== null ||\n\t\t\t\tdisallowClipboardEvents(editor)\n\t\t\t) {\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tpreventDefault(e)\n\t\t\tawait handleNativeOrMenuCopy(editor)\n\t\t\ttrackEvent('copy', { source: 'kbd' })\n\t\t}\n\n\t\tasync function cut(e: ClipboardEvent) {\n\t\t\tif (\n\t\t\t\teditor.getSelectedShapeIds().length === 0 ||\n\t\t\t\teditor.getEditingShapeId() !== null ||\n\t\t\t\tdisallowClipboardEvents(editor)\n\t\t\t) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tpreventDefault(e)\n\t\t\tawait handleNativeOrMenuCopy(editor)\n\t\t\teditor.deleteShapes(editor.getSelectedShapeIds())\n\t\t\ttrackEvent('cut', { source: 'kbd' })\n\t\t}\n\n\t\tlet disablingMiddleClickPaste = false\n\t\tconst pointerUpHandler = (e: PointerEvent) => {\n\t\t\tif (e.button === 1) {\n\t\t\t\t// middle mouse button\n\t\t\t\tdisablingMiddleClickPaste = true\n\t\t\t\teditor.timers.requestAnimationFrame(() => {\n\t\t\t\t\tdisablingMiddleClickPaste = false\n\t\t\t\t})\n\t\t\t}\n\t\t}\n\n\t\tconst paste = (e: ClipboardEvent) => {\n\t\t\tif (disablingMiddleClickPaste) {\n\t\t\t\tstopEventPropagation(e)\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\t// If we're editing a shape, or we are focusing an editable input, then\n\t\t\t// we would want the user's paste interaction to go to that element or\n\t\t\t// input instead; e.g. when pasting text into a text shape's content\n\t\t\tif (editor.getEditingShapeId() !== null || disallowClipboardEvents(editor)) return\n\n\t\t\t// Where should the shapes go?\n\t\t\tlet point: Vec | undefined = undefined\n\t\t\tlet pasteAtCursor = false\n\n\t\t\t// | Shiftkey | Paste at cursor mode | Paste at point? |\n\t\t\t// | N \t\t| N | N \t\t\t\t |\n\t\t\t// | Y \t\t| N | Y \t\t\t\t |\n\t\t\t// | N \t\t| Y | Y \t\t\t\t |\n\t\t\t// | Y \t\t| Y | N \t\t\t\t |\n\t\t\tif (editor.inputs.shiftKey) pasteAtCursor = true\n\t\t\tif (editor.user.getIsPasteAtCursorMode()) pasteAtCursor = !pasteAtCursor\n\t\t\tif (pasteAtCursor) point = editor.inputs.currentPagePoint\n\n\t\t\t// First try to use the clipboard data on the event\n\t\t\tif (e.clipboardData && !editor.inputs.shiftKey) {\n\t\t\t\thandlePasteFromEventClipboardData(editor, e.clipboardData, point)\n\t\t\t} else {\n\t\t\t\t// Or else use the clipboard API\n\t\t\t\tnavigator.clipboard.read().then((clipboardItems) => {\n\t\t\t\t\tif (Array.isArray(clipboardItems) && clipboardItems[0] instanceof ClipboardItem) {\n\t\t\t\t\t\thandlePasteFromClipboardApi(editor, clipboardItems, point)\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t}\n\n\t\t\tpreventDefault(e)\n\t\t\ttrackEvent('paste', { source: 'kbd' })\n\t\t}\n\n\t\tcontainer.ownerDocument.addEventListener('copy', copy)\n\t\tcontainer.ownerDocument.addEventListener('cut', cut)\n\t\tcontainer.ownerDocument.addEventListener('paste', paste)\n\t\tcontainer.ownerDocument.addEventListener('pointerup', pointerUpHandler)\n\n\t\treturn () => {\n\t\t\tcontainer.ownerDocument.removeEventListener('copy', copy)\n\t\t\tcontainer.ownerDocument.removeEventListener('cut', cut)\n\t\t\tcontainer.ownerDocument.removeEventListener('paste', paste)\n\t\t\tcontainer.ownerDocument.removeEventListener('pointerup', pointerUpHandler)\n\t\t}\n\t}, [editor, trackEvent, appIsFocused, container])\n}\n"], -+ "mappings": "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", - "names": ["url"] - } -diff --git a/node_modules/tldraw/dist-esm/lib/ui/hooks/useKeyboardShortcuts.mjs b/node_modules/tldraw/dist-esm/lib/ui/hooks/useKeyboardShortcuts.mjs -index a9d3c4b..09b7a54 100644 ---- a/node_modules/tldraw/dist-esm/lib/ui/hooks/useKeyboardShortcuts.mjs -+++ b/node_modules/tldraw/dist-esm/lib/ui/hooks/useKeyboardShortcuts.mjs -@@ -1,4 +1,4 @@ --import { preventDefault, useEditor, useValue } from "@tldraw/editor"; -+import { preventDefault, useContainer, useEditor, useValue } from "@tldraw/editor"; - import hotkeys from "hotkeys-js"; - import { useEffect } from "react"; - import { useActions } from "../context/actions.mjs"; -@@ -13,6 +13,7 @@ const SKIP_KBDS = [ - "asset" - ]; - function useKeyboardShortcuts() { -+ const container = useContainer(); - const editor = useEditor(); - const isReadonlyMode = useReadonly(); - const actions = useActions(); -@@ -22,13 +23,13 @@ function useKeyboardShortcuts() { - if (!isFocused) return; - const disposables = new Array(); - const hot = (keys, callback) => { -- hotkeys(keys, { element: document.body }, callback); -+ hotkeys(keys, { element: container.ownerDocument.body }, callback); - disposables.push(() => { - hotkeys.unbind(keys, callback); - }); - }; - const hotUp = (keys, callback) => { -- hotkeys(keys, { element: document.body, keyup: true, keydown: false }, callback); -+ hotkeys(keys, { element: container.ownerDocument.body, keyup: true, keydown: false }, callback); - disposables.push(() => { - hotkeys.unbind(keys, callback); - }); -@@ -98,7 +99,7 @@ function useKeyboardShortcuts() { - return () => { - disposables.forEach((d) => d()); - }; -- }, [actions, tools, isReadonlyMode, editor, isFocused]); -+ }, [actions, tools, isReadonlyMode, editor, container, isFocused]); - } - function getHotkeysStringFromKbd(kbd) { - return getKeys(kbd).map((kbd2) => { -diff --git a/node_modules/tldraw/dist-esm/lib/ui/hooks/useKeyboardShortcuts.mjs.map b/node_modules/tldraw/dist-esm/lib/ui/hooks/useKeyboardShortcuts.mjs.map -index 195c016..ecdace7 100644 ---- a/node_modules/tldraw/dist-esm/lib/ui/hooks/useKeyboardShortcuts.mjs.map -+++ b/node_modules/tldraw/dist-esm/lib/ui/hooks/useKeyboardShortcuts.mjs.map -@@ -1,7 +1,7 @@ - { - "version": 3, - "sources": ["../../../../src/lib/ui/hooks/useKeyboardShortcuts.ts"], -- "sourcesContent": ["import { Editor, TLPointerEventInfo, preventDefault, useEditor, useValue } from '@tldraw/editor'\nimport hotkeys from 'hotkeys-js'\nimport { useEffect } from 'react'\nimport { useActions } from '../context/actions'\nimport { useReadonly } from './useReadonly'\nimport { useTools } from './useTools'\n\nconst SKIP_KBDS = [\n\t// we set these in useNativeClipboardEvents instead\n\t'copy',\n\t'cut',\n\t'paste',\n\t// There's also an upload asset action, so we don't want to set the kbd twice\n\t'asset',\n]\n\n/** @public */\nexport function useKeyboardShortcuts() {\n\tconst editor = useEditor()\n\n\tconst isReadonlyMode = useReadonly()\n\tconst actions = useActions()\n\tconst tools = useTools()\n\tconst isFocused = useValue('is focused', () => editor.getInstanceState().isFocused, [editor])\n\tuseEffect(() => {\n\t\tif (!isFocused) return\n\n\t\tconst disposables = new Array<() => void>()\n\n\t\tconst hot = (keys: string, callback: (event: KeyboardEvent) => void) => {\n\t\t\thotkeys(keys, { element: document.body }, callback)\n\t\t\tdisposables.push(() => {\n\t\t\t\thotkeys.unbind(keys, callback)\n\t\t\t})\n\t\t}\n\n\t\tconst hotUp = (keys: string, callback: (event: KeyboardEvent) => void) => {\n\t\t\thotkeys(keys, { element: document.body, keyup: true, keydown: false }, callback)\n\t\t\tdisposables.push(() => {\n\t\t\t\thotkeys.unbind(keys, callback)\n\t\t\t})\n\t\t}\n\n\t\t// Add hotkeys for actions and tools.\n\t\t// Except those that in SKIP_KBDS!\n\t\tfor (const action of Object.values(actions)) {\n\t\t\tif (!action.kbd) continue\n\t\t\tif (isReadonlyMode && !action.readonlyOk) continue\n\t\t\tif (SKIP_KBDS.includes(action.id)) continue\n\n\t\t\thot(getHotkeysStringFromKbd(action.kbd), (event) => {\n\t\t\t\tif (areShortcutsDisabled(editor)) return\n\t\t\t\tpreventDefault(event)\n\t\t\t\taction.onSelect('kbd')\n\t\t\t})\n\t\t}\n\n\t\tfor (const tool of Object.values(tools)) {\n\t\t\tif (!tool.kbd || (!tool.readonlyOk && editor.getInstanceState().isReadonly)) {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tif (SKIP_KBDS.includes(tool.id)) continue\n\n\t\t\thot(getHotkeysStringFromKbd(tool.kbd), (event) => {\n\t\t\t\tif (areShortcutsDisabled(editor)) return\n\t\t\t\tpreventDefault(event)\n\t\t\t\ttool.onSelect('kbd')\n\t\t\t})\n\t\t}\n\n\t\thot(',', (e) => {\n\t\t\t// Skip if shortcuts are disabled\n\t\t\tif (areShortcutsDisabled(editor)) return\n\n\t\t\t// Don't press again if already pressed\n\t\t\tif (editor.inputs.keys.has('Comma')) return\n\n\t\t\tpreventDefault(e) // prevent whatever would normally happen\n\t\t\teditor.focus() // Focus if not already focused\n\n\t\t\teditor.inputs.keys.add('Comma')\n\n\t\t\tconst { x, y, z } = editor.inputs.currentPagePoint\n\t\t\tconst screenpoints = editor.pageToScreen({ x, y })\n\n\t\t\tconst info: TLPointerEventInfo = {\n\t\t\t\ttype: 'pointer',\n\t\t\t\tname: 'pointer_down',\n\t\t\t\tpoint: { x: screenpoints.x, y: screenpoints.y, z },\n\t\t\t\tshiftKey: e.shiftKey,\n\t\t\t\taltKey: e.altKey,\n\t\t\t\tctrlKey: e.metaKey || e.ctrlKey,\n\t\t\t\tpointerId: 0,\n\t\t\t\tbutton: 0,\n\t\t\t\tisPen: editor.getInstanceState().isPenMode,\n\t\t\t\ttarget: 'canvas',\n\t\t\t}\n\n\t\t\teditor.dispatch(info)\n\t\t})\n\n\t\thotUp(',', (e) => {\n\t\t\tif (areShortcutsDisabled(editor)) return\n\t\t\tif (!editor.inputs.keys.has('Comma')) return\n\n\t\t\teditor.inputs.keys.delete('Comma')\n\n\t\t\tconst { x, y, z } = editor.inputs.currentScreenPoint\n\t\t\tconst info: TLPointerEventInfo = {\n\t\t\t\ttype: 'pointer',\n\t\t\t\tname: 'pointer_up',\n\t\t\t\tpoint: { x, y, z },\n\t\t\t\tshiftKey: e.shiftKey,\n\t\t\t\taltKey: e.altKey,\n\t\t\t\tctrlKey: e.metaKey || e.ctrlKey,\n\t\t\t\tpointerId: 0,\n\t\t\t\tbutton: 0,\n\t\t\t\tisPen: editor.getInstanceState().isPenMode,\n\t\t\t\ttarget: 'canvas',\n\t\t\t}\n\n\t\t\teditor.dispatch(info)\n\t\t})\n\n\t\treturn () => {\n\t\t\tdisposables.forEach((d) => d())\n\t\t}\n\t}, [actions, tools, isReadonlyMode, editor, isFocused])\n}\n\nfunction getHotkeysStringFromKbd(kbd: string) {\n\treturn getKeys(kbd)\n\t\t.map((kbd) => {\n\t\t\tlet str = ''\n\t\t\tconst chars = kbd.split('')\n\t\t\tif (chars.length === 1) {\n\t\t\t\tstr = chars[0]\n\t\t\t} else {\n\t\t\t\tif (chars[0] === '!') {\n\t\t\t\t\tstr = `shift+${chars[1]}`\n\t\t\t\t} else if (chars[0] === '?') {\n\t\t\t\t\tif (chars.length === 3 && chars[1] === '!') {\n\t\t\t\t\t\tstr = `alt+shift+${chars[2]}`\n\t\t\t\t\t} else {\n\t\t\t\t\t\tstr = `alt+${chars[1]}`\n\t\t\t\t\t}\n\t\t\t\t} else if (chars[0] === '$') {\n\t\t\t\t\tif (chars[1] === '!') {\n\t\t\t\t\t\tstr = `cmd+shift+${chars[2]},ctrl+shift+${chars[2]}`\n\t\t\t\t\t} else if (chars[1] === '?') {\n\t\t\t\t\t\tstr = `cmd+\u2325+${chars[2]},ctrl+alt+${chars[2]}`\n\t\t\t\t\t} else {\n\t\t\t\t\t\tstr = `cmd+${chars[1]},ctrl+${chars[1]}`\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tstr = kbd\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn str\n\t\t})\n\t\t.join(',')\n}\n\n// Logic to split kbd string from hotkeys-js util.\nfunction getKeys(key: string) {\n\tif (typeof key !== 'string') key = ''\n\tkey = key.replace(/\\s/g, '')\n\tconst keys = key.split(',')\n\tlet index = keys.lastIndexOf('')\n\n\tfor (; index >= 0; ) {\n\t\tkeys[index - 1] += ','\n\t\tkeys.splice(index, 1)\n\t\tindex = keys.lastIndexOf('')\n\t}\n\n\treturn keys\n}\n\nexport function areShortcutsDisabled(editor: Editor) {\n\treturn editor.getIsMenuOpen() || editor.getEditingShapeId() !== null || editor.getCrashingError()\n}\n"], -- "mappings": "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", -+ "sourcesContent": ["import { Editor, TLPointerEventInfo, preventDefault, useContainer, useEditor, useValue } from '@tldraw/editor'\nimport hotkeys from 'hotkeys-js'\nimport { useEffect } from 'react'\nimport { useActions } from '../context/actions'\nimport { useReadonly } from './useReadonly'\nimport { useTools } from './useTools'\n\nconst SKIP_KBDS = [\n\t// we set these in useNativeClipboardEvents instead\n\t'copy',\n\t'cut',\n\t'paste',\n\t// There's also an upload asset action, so we don't want to set the kbd twice\n\t'asset',\n]\n\n/** @public */\nexport function useKeyboardShortcuts() {\n\tconst container = useContainer();\n\tconst editor = useEditor()\n\n\tconst isReadonlyMode = useReadonly()\n\tconst actions = useActions()\n\tconst tools = useTools()\n\tconst isFocused = useValue('is focused', () => editor.getInstanceState().isFocused, [editor])\n\tuseEffect(() => {\n\t\tif (!isFocused) return\n\n\t\tconst disposables = new Array<() => void>()\n\n\t\tconst hot = (keys: string, callback: (event: KeyboardEvent) => void) => {\n\t\t\thotkeys(keys, { element: container.ownerDocument.body }, callback)\n\t\t\tdisposables.push(() => {\n\t\t\t\thotkeys.unbind(keys, callback)\n\t\t\t})\n\t\t}\n\n\t\tconst hotUp = (keys: string, callback: (event: KeyboardEvent) => void) => {\n\t\t\thotkeys(keys, { element: container.ownerDocument.body, keyup: true, keydown: false }, callback)\n\t\t\tdisposables.push(() => {\n\t\t\t\thotkeys.unbind(keys, callback)\n\t\t\t})\n\t\t}\n\n\t\t// Add hotkeys for actions and tools.\n\t\t// Except those that in SKIP_KBDS!\n\t\tfor (const action of Object.values(actions)) {\n\t\t\tif (!action.kbd) continue\n\t\t\tif (isReadonlyMode && !action.readonlyOk) continue\n\t\t\tif (SKIP_KBDS.includes(action.id)) continue\n\n\t\t\thot(getHotkeysStringFromKbd(action.kbd), (event) => {\n\t\t\t\tif (areShortcutsDisabled(editor)) return\n\t\t\t\tpreventDefault(event)\n\t\t\t\taction.onSelect('kbd')\n\t\t\t})\n\t\t}\n\n\t\tfor (const tool of Object.values(tools)) {\n\t\t\tif (!tool.kbd || (!tool.readonlyOk && editor.getInstanceState().isReadonly)) {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tif (SKIP_KBDS.includes(tool.id)) continue\n\n\t\t\thot(getHotkeysStringFromKbd(tool.kbd), (event) => {\n\t\t\t\tif (areShortcutsDisabled(editor)) return\n\t\t\t\tpreventDefault(event)\n\t\t\t\ttool.onSelect('kbd')\n\t\t\t})\n\t\t}\n\n\t\thot(',', (e) => {\n\t\t\t// Skip if shortcuts are disabled\n\t\t\tif (areShortcutsDisabled(editor)) return\n\n\t\t\t// Don't press again if already pressed\n\t\t\tif (editor.inputs.keys.has('Comma')) return\n\n\t\t\tpreventDefault(e) // prevent whatever would normally happen\n\t\t\teditor.focus() // Focus if not already focused\n\n\t\t\teditor.inputs.keys.add('Comma')\n\n\t\t\tconst { x, y, z } = editor.inputs.currentPagePoint\n\t\t\tconst screenpoints = editor.pageToScreen({ x, y })\n\n\t\t\tconst info: TLPointerEventInfo = {\n\t\t\t\ttype: 'pointer',\n\t\t\t\tname: 'pointer_down',\n\t\t\t\tpoint: { x: screenpoints.x, y: screenpoints.y, z },\n\t\t\t\tshiftKey: e.shiftKey,\n\t\t\t\taltKey: e.altKey,\n\t\t\t\tctrlKey: e.metaKey || e.ctrlKey,\n\t\t\t\tpointerId: 0,\n\t\t\t\tbutton: 0,\n\t\t\t\tisPen: editor.getInstanceState().isPenMode,\n\t\t\t\ttarget: 'canvas',\n\t\t\t}\n\n\t\t\teditor.dispatch(info)\n\t\t})\n\n\t\thotUp(',', (e) => {\n\t\t\tif (areShortcutsDisabled(editor)) return\n\t\t\tif (!editor.inputs.keys.has('Comma')) return\n\n\t\t\teditor.inputs.keys.delete('Comma')\n\n\t\t\tconst { x, y, z } = editor.inputs.currentScreenPoint\n\t\t\tconst info: TLPointerEventInfo = {\n\t\t\t\ttype: 'pointer',\n\t\t\t\tname: 'pointer_up',\n\t\t\t\tpoint: { x, y, z },\n\t\t\t\tshiftKey: e.shiftKey,\n\t\t\t\taltKey: e.altKey,\n\t\t\t\tctrlKey: e.metaKey || e.ctrlKey,\n\t\t\t\tpointerId: 0,\n\t\t\t\tbutton: 0,\n\t\t\t\tisPen: editor.getInstanceState().isPenMode,\n\t\t\t\ttarget: 'canvas',\n\t\t\t}\n\n\t\t\teditor.dispatch(info)\n\t\t})\n\n\t\treturn () => {\n\t\t\tdisposables.forEach((d) => d())\n\t\t}\n\t}, [actions, tools, isReadonlyMode, editor, container, isFocused])\n}\n\nfunction getHotkeysStringFromKbd(kbd: string) {\n\treturn getKeys(kbd)\n\t\t.map((kbd) => {\n\t\t\tlet str = ''\n\t\t\tconst chars = kbd.split('')\n\t\t\tif (chars.length === 1) {\n\t\t\t\tstr = chars[0]\n\t\t\t} else {\n\t\t\t\tif (chars[0] === '!') {\n\t\t\t\t\tstr = `shift+${chars[1]}`\n\t\t\t\t} else if (chars[0] === '?') {\n\t\t\t\t\tif (chars.length === 3 && chars[1] === '!') {\n\t\t\t\t\t\tstr = `alt+shift+${chars[2]}`\n\t\t\t\t\t} else {\n\t\t\t\t\t\tstr = `alt+${chars[1]}`\n\t\t\t\t\t}\n\t\t\t\t} else if (chars[0] === '$') {\n\t\t\t\t\tif (chars[1] === '!') {\n\t\t\t\t\t\tstr = `cmd+shift+${chars[2]},ctrl+shift+${chars[2]}`\n\t\t\t\t\t} else if (chars[1] === '?') {\n\t\t\t\t\t\tstr = `cmd+\u2325+${chars[2]},ctrl+alt+${chars[2]}`\n\t\t\t\t\t} else {\n\t\t\t\t\t\tstr = `cmd+${chars[1]},ctrl+${chars[1]}`\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tstr = kbd\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn str\n\t\t})\n\t\t.join(',')\n}\n\n// Logic to split kbd string from hotkeys-js util.\nfunction getKeys(key: string) {\n\tif (typeof key !== 'string') key = ''\n\tkey = key.replace(/\\s/g, '')\n\tconst keys = key.split(',')\n\tlet index = keys.lastIndexOf('')\n\n\tfor (; index >= 0; ) {\n\t\tkeys[index - 1] += ','\n\t\tkeys.splice(index, 1)\n\t\tindex = keys.lastIndexOf('')\n\t}\n\n\treturn keys\n}\n\nexport function areShortcutsDisabled(editor: Editor) {\n\treturn editor.getIsMenuOpen() || editor.getEditingShapeId() !== null || editor.getCrashingError()\n}\n"], -+ "mappings": "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", - "names": ["kbd"] - } -diff --git a/node_modules/tldraw/src/lib/TldrawImage.tsx b/node_modules/tldraw/src/lib/TldrawImage.tsx -index 97f1181..cdeb59c 100644 ---- a/node_modules/tldraw/src/lib/TldrawImage.tsx -+++ b/node_modules/tldraw/src/lib/TldrawImage.tsx -@@ -5,6 +5,7 @@ import { - LoadingScreen, - TLAnyBindingUtilConstructor, - TLAnyShapeUtilConstructor, -+ TLAssetStore, - TLEditorSnapshot, - TLImageExportOptions, - TLPageId, -@@ -49,6 +50,10 @@ export interface TldrawImageProps extends TLImageExportOptions { - * The license key. - */ - licenseKey?: string -+ /** -+ * How should this store resolve assets? -+ */ -+ assets?: TLAssetStore - /** - * Asset URL overrides. - */ -@@ -84,7 +89,11 @@ export const TldrawImage = memo(function TldrawImage(props: TldrawImageProps) { - () => [...defaultBindingUtils, ...bindingUtils], - [bindingUtils] - ) -- const store = useTLStore({ snapshot: props.snapshot, shapeUtils: shapeUtilsWithDefaults }) -+ const store = useTLStore({ -+ assets: props.assets, -+ snapshot: props.snapshot, -+ shapeUtils: shapeUtilsWithDefaults, -+ }) - - const assets = useDefaultEditorAssetsWithOverrides(props.assetUrls) - const { done: preloadingComplete, error: preloadingError } = usePreloadAssets(assets) -diff --git a/node_modules/tldraw/src/lib/shapes/shared/TextHelpers.ts b/node_modules/tldraw/src/lib/shapes/shared/TextHelpers.ts -index cda4cbb..ef2c4dd 100644 ---- a/node_modules/tldraw/src/lib/shapes/shared/TextHelpers.ts -+++ b/node_modules/tldraw/src/lib/shapes/shared/TextHelpers.ts -@@ -50,7 +50,7 @@ export class TextHelpers { - - if (initialFocus === document.body) { - field.blur() -- } else if (initialFocus instanceof HTMLElement && initialFocus !== field) { -+ } else if (initialFocus?.instanceOf(HTMLElement) && initialFocus !== field) { - initialFocus.focus() - } - } -diff --git a/node_modules/tldraw/src/lib/ui/components/Toolbar/OverflowingToolbar.tsx b/node_modules/tldraw/src/lib/ui/components/Toolbar/OverflowingToolbar.tsx -index 0a8394f..37bd05d 100644 ---- a/node_modules/tldraw/src/lib/ui/components/Toolbar/OverflowingToolbar.tsx -+++ b/node_modules/tldraw/src/lib/ui/components/Toolbar/OverflowingToolbar.tsx -@@ -116,7 +116,7 @@ export function OverflowingToolbar({ children }: OverflowingToolbarProps) { - const relevantEls = Array.from(mainToolsRef.current?.children ?? []).filter( - (el): el is HTMLElement => { - // only count html elements... -- if (!(el instanceof HTMLElement)) return false -+ if (!(el.instanceOf(HTMLElement))) return false - - // ...that are buttons... - if (el.tagName.toLowerCase() !== 'button') return false -diff --git a/node_modules/tldraw/src/lib/ui/components/primitives/TldrawUiButtonPicker.tsx b/node_modules/tldraw/src/lib/ui/components/primitives/TldrawUiButtonPicker.tsx -index 4747770..718db35 100644 ---- a/node_modules/tldraw/src/lib/ui/components/primitives/TldrawUiButtonPicker.tsx -+++ b/node_modules/tldraw/src/lib/ui/components/primitives/TldrawUiButtonPicker.tsx -@@ -4,6 +4,7 @@ import { - StyleProp, - TLDefaultColorStyle, - TLDefaultColorTheme, -+ useContainer, - useEditor, - } from '@tldraw/editor' - import classNames from 'classnames' -@@ -39,7 +40,8 @@ export const TldrawUiButtonPicker = memo(function TldrawUiButtonPicker { - const handlePointerUp = () => { - rPointing.current = false -- window.removeEventListener('pointerup', handlePointerUp) -+ container.win.removeEventListener('pointerup', handlePointerUp) - - // This is fun little micro-optimization to make sure that the focus - // is retained on a text label. That way, you can continue typing -@@ -80,8 +82,8 @@ export const TldrawUiButtonPicker = memo(function TldrawUiButtonPicker) => { -@@ -104,7 +106,7 @@ export const TldrawUiButtonPicker = memo(function TldrawUiButtonPicker -diff --git a/node_modules/tldraw/src/lib/ui/hooks/useClipboardEvents.ts b/node_modules/tldraw/src/lib/ui/hooks/useClipboardEvents.ts -index e88d652..13eba68 100644 ---- a/node_modules/tldraw/src/lib/ui/hooks/useClipboardEvents.ts -+++ b/node_modules/tldraw/src/lib/ui/hooks/useClipboardEvents.ts -@@ -8,6 +8,7 @@ import { - preventDefault, - stopEventPropagation, - uniq, -+ useContainer, - useEditor, - useValue, - } from '@tldraw/editor' -@@ -597,7 +598,8 @@ export function useMenuClipboardEvents() { - - /** @public */ - export function useNativeClipboardEvents() { -- const editor = useEditor() -+ const container = useContainer() -+ const editor = useEditor() - const trackEvent = useUiEvents() - - const appIsFocused = useValue('editor.isFocused', () => editor.getInstanceState().isFocused, [ -@@ -685,16 +687,16 @@ export function useNativeClipboardEvents() { - trackEvent('paste', { source: 'kbd' }) - } - -- document.addEventListener('copy', copy) -- document.addEventListener('cut', cut) -- document.addEventListener('paste', paste) -- document.addEventListener('pointerup', pointerUpHandler) -+ container.ownerDocument.addEventListener('copy', copy) -+ container.ownerDocument.addEventListener('cut', cut) -+ container.ownerDocument.addEventListener('paste', paste) -+ container.ownerDocument.addEventListener('pointerup', pointerUpHandler) - - return () => { -- document.removeEventListener('copy', copy) -- document.removeEventListener('cut', cut) -- document.removeEventListener('paste', paste) -- document.removeEventListener('pointerup', pointerUpHandler) -+ container.ownerDocument.removeEventListener('copy', copy) -+ container.ownerDocument.removeEventListener('cut', cut) -+ container.ownerDocument.removeEventListener('paste', paste) -+ container.ownerDocument.removeEventListener('pointerup', pointerUpHandler) - } -- }, [editor, trackEvent, appIsFocused]) -+ }, [editor, trackEvent, appIsFocused, container]) - } -diff --git a/node_modules/tldraw/src/lib/ui/hooks/useKeyboardShortcuts.ts b/node_modules/tldraw/src/lib/ui/hooks/useKeyboardShortcuts.ts -index deee5b1..53e128b 100644 ---- a/node_modules/tldraw/src/lib/ui/hooks/useKeyboardShortcuts.ts -+++ b/node_modules/tldraw/src/lib/ui/hooks/useKeyboardShortcuts.ts -@@ -1,4 +1,4 @@ --import { Editor, TLPointerEventInfo, preventDefault, useEditor, useValue } from '@tldraw/editor' -+import { Editor, TLPointerEventInfo, preventDefault, useContainer, useEditor, useValue } from '@tldraw/editor' - import hotkeys from 'hotkeys-js' - import { useEffect } from 'react' - import { useActions } from '../context/actions' -@@ -16,6 +16,7 @@ const SKIP_KBDS = [ - - /** @public */ - export function useKeyboardShortcuts() { -+ const container = useContainer(); - const editor = useEditor() - - const isReadonlyMode = useReadonly() -@@ -28,14 +29,14 @@ export function useKeyboardShortcuts() { - const disposables = new Array<() => void>() - - const hot = (keys: string, callback: (event: KeyboardEvent) => void) => { -- hotkeys(keys, { element: document.body }, callback) -+ hotkeys(keys, { element: container.ownerDocument.body }, callback) - disposables.push(() => { - hotkeys.unbind(keys, callback) - }) - } - - const hotUp = (keys: string, callback: (event: KeyboardEvent) => void) => { -- hotkeys(keys, { element: document.body, keyup: true, keydown: false }, callback) -+ hotkeys(keys, { element: container.ownerDocument.body, keyup: true, keydown: false }, callback) - disposables.push(() => { - hotkeys.unbind(keys, callback) - }) -@@ -126,7 +127,7 @@ export function useKeyboardShortcuts() { - return () => { - disposables.forEach((d) => d()) - } -- }, [actions, tools, isReadonlyMode, editor, isFocused]) -+ }, [actions, tools, isReadonlyMode, editor, container, isFocused]) - } - - function getHotkeysStringFromKbd(kbd: string) { diff --git a/patches/tldraw+3.4.1.patch b/patches/tldraw+3.4.1.patch new file mode 100644 index 0000000..e26f6d6 --- /dev/null +++ b/patches/tldraw+3.4.1.patch @@ -0,0 +1,503 @@ +diff --git a/node_modules/tldraw/dist-esm/index.d.mts b/node_modules/tldraw/dist-esm/index.d.mts +index f93af80..925a468 100644 +--- a/node_modules/tldraw/dist-esm/index.d.mts ++++ b/node_modules/tldraw/dist-esm/index.d.mts +@@ -49,6 +49,7 @@ import { TLArrowShapeArrowheadStyle } from '@tldraw/editor'; + import { TLArrowShapeProps } from '@tldraw/editor'; + import { TLAsset } from '@tldraw/editor'; + import { TLAssetId } from '@tldraw/editor'; ++import { TLAssetStore } from '@tldraw/editor'; + import { TLBookmarkShape } from '@tldraw/editor'; + import { TLBookmarkShapeProps } from '@tldraw/editor'; + import { TLClickEventInfo } from '@tldraw/editor'; +@@ -1831,6 +1832,10 @@ export declare interface TldrawImageProps extends TLImageExportOptions { + * The license key. + */ + licenseKey?: string; ++ /** ++ * How should this store resolve assets? ++ */ ++ assets?: TLAssetStore; + /** + * Asset URL overrides. + */ +diff --git a/node_modules/tldraw/dist-esm/lib/TldrawImage.mjs b/node_modules/tldraw/dist-esm/lib/TldrawImage.mjs +index ac9ec2b..f8645af 100644 +--- a/node_modules/tldraw/dist-esm/lib/TldrawImage.mjs ++++ b/node_modules/tldraw/dist-esm/lib/TldrawImage.mjs +@@ -23,7 +23,11 @@ const TldrawImage = memo(function TldrawImage2(props) { + () => [...defaultBindingUtils, ...bindingUtils], + [bindingUtils] + ); +- const store = useTLStore({ snapshot: props.snapshot, shapeUtils: shapeUtilsWithDefaults }); ++ const store = useTLStore({ ++ assets: props.assets, ++ snapshot: props.snapshot, ++ shapeUtils: shapeUtilsWithDefaults ++ }); + const assets = useDefaultEditorAssetsWithOverrides(props.assetUrls); + const { done: preloadingComplete, error: preloadingError } = usePreloadAssets(assets); + const { +diff --git a/node_modules/tldraw/dist-esm/lib/TldrawImage.mjs.map b/node_modules/tldraw/dist-esm/lib/TldrawImage.mjs.map +index d4f5339..ee4c395 100644 +--- a/node_modules/tldraw/dist-esm/lib/TldrawImage.mjs.map ++++ b/node_modules/tldraw/dist-esm/lib/TldrawImage.mjs.map +@@ -1,7 +1,7 @@ + { + "version": 3, + "sources": ["../../src/lib/TldrawImage.tsx"], +- "sourcesContent": ["import {\n\tDefaultSpinner,\n\tEditor,\n\tErrorScreen,\n\tLoadingScreen,\n\tTLAnyBindingUtilConstructor,\n\tTLAnyShapeUtilConstructor,\n\tTLEditorSnapshot,\n\tTLImageExportOptions,\n\tTLPageId,\n\tTLStoreSnapshot,\n\tuseShallowArrayIdentity,\n\tuseTLStore,\n} from '@tldraw/editor'\nimport { memo, useLayoutEffect, useMemo, useState } from 'react'\nimport { defaultBindingUtils } from './defaultBindingUtils'\nimport { defaultShapeUtils } from './defaultShapeUtils'\nimport { TLUiAssetUrlOverrides } from './ui/assetUrls'\nimport { usePreloadAssets } from './ui/hooks/usePreloadAssets'\nimport { getSvgAsImage } from './utils/export/export'\nimport { useDefaultEditorAssetsWithOverrides } from './utils/static-assets/assetUrls'\n\n/** @public */\nexport interface TldrawImageProps extends TLImageExportOptions {\n\t/**\n\t * The snapshot to display.\n\t */\n\tsnapshot: Partial | TLStoreSnapshot\n\n\t/**\n\t * The image format to use. Defaults to 'svg'.\n\t */\n\tformat?: 'svg' | 'png'\n\n\t/**\n\t * The page to display. Defaults to the first page.\n\t */\n\tpageId?: TLPageId\n\n\t/**\n\t * Additional shape utils to use.\n\t */\n\tshapeUtils?: readonly TLAnyShapeUtilConstructor[]\n\t/**\n\t * Additional binding utils to use.\n\t */\n\tbindingUtils?: readonly TLAnyBindingUtilConstructor[]\n\t/**\n\t * The license key.\n\t */\n\tlicenseKey?: string\n\t/**\n\t * Asset URL overrides.\n\t */\n\tassetUrls?: TLUiAssetUrlOverrides\n}\n\n/**\n * A renderered SVG image of a Tldraw snapshot.\n *\n * @example\n * ```tsx\n * \n * ```\n *\n * @public\n * @react\n */\nexport const TldrawImage = memo(function TldrawImage(props: TldrawImageProps) {\n\tconst [url, setUrl] = useState(null)\n\tconst [container, setContainer] = useState(null)\n\n\tconst shapeUtils = useShallowArrayIdentity(props.shapeUtils ?? [])\n\tconst shapeUtilsWithDefaults = useMemo(() => [...defaultShapeUtils, ...shapeUtils], [shapeUtils])\n\tconst bindingUtils = useShallowArrayIdentity(props.bindingUtils ?? [])\n\tconst bindingUtilsWithDefaults = useMemo(\n\t\t() => [...defaultBindingUtils, ...bindingUtils],\n\t\t[bindingUtils]\n\t)\n\tconst store = useTLStore({ snapshot: props.snapshot, shapeUtils: shapeUtilsWithDefaults })\n\n\tconst assets = useDefaultEditorAssetsWithOverrides(props.assetUrls)\n\tconst { done: preloadingComplete, error: preloadingError } = usePreloadAssets(assets)\n\n\tconst {\n\t\tpageId,\n\t\tbounds,\n\t\tscale,\n\t\tbackground,\n\t\tpadding,\n\t\tdarkMode,\n\t\tpreserveAspectRatio,\n\t\tformat = 'svg',\n\t\tlicenseKey,\n\t} = props\n\n\tuseLayoutEffect(() => {\n\t\tif (!container) return\n\t\tif (!store) return\n\t\tif (!preloadingComplete) return\n\n\t\tlet isCancelled = false\n\n\t\tconst tempElm = document.createElement('div')\n\t\tcontainer.appendChild(tempElm)\n\t\tcontainer.classList.add('tl-container', 'tl-theme__light')\n\n\t\tconst editor = new Editor({\n\t\t\tstore,\n\t\t\tshapeUtils: shapeUtilsWithDefaults,\n\t\t\tbindingUtils: bindingUtilsWithDefaults,\n\t\t\ttools: [],\n\t\t\tgetContainer: () => tempElm,\n\t\t\tlicenseKey,\n\t\t})\n\n\t\tif (pageId) editor.setCurrentPage(pageId)\n\n\t\tconst shapeIds = editor.getCurrentPageShapeIds()\n\n\t\tasync function setSvg() {\n\t\t\tconst svgResult = await editor.getSvgString([...shapeIds], {\n\t\t\t\tbounds,\n\t\t\t\tscale,\n\t\t\t\tbackground,\n\t\t\t\tpadding,\n\t\t\t\tdarkMode,\n\t\t\t\tpreserveAspectRatio,\n\t\t\t})\n\n\t\t\tif (svgResult && !isCancelled) {\n\t\t\t\tif (format === 'svg') {\n\t\t\t\t\tif (!isCancelled) {\n\t\t\t\t\t\tconst blob = new Blob([svgResult.svg], { type: 'image/svg+xml' })\n\t\t\t\t\t\tconst url = URL.createObjectURL(blob)\n\t\t\t\t\t\tsetUrl(url)\n\t\t\t\t\t}\n\t\t\t\t} else if (format === 'png') {\n\t\t\t\t\tconst blob = await getSvgAsImage(editor, svgResult.svg, {\n\t\t\t\t\t\ttype: format,\n\t\t\t\t\t\tquality: 1,\n\t\t\t\t\t\tscale: 2,\n\t\t\t\t\t\twidth: svgResult.width,\n\t\t\t\t\t\theight: svgResult.height,\n\t\t\t\t\t})\n\t\t\t\t\tif (blob && !isCancelled) {\n\t\t\t\t\t\tconst url = URL.createObjectURL(blob)\n\t\t\t\t\t\tsetUrl(url)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\teditor.dispose()\n\t\t}\n\n\t\tsetSvg()\n\n\t\treturn () => {\n\t\t\tisCancelled = true\n\t\t}\n\t}, [\n\t\tformat,\n\t\tcontainer,\n\t\tstore,\n\t\tshapeUtilsWithDefaults,\n\t\tbindingUtilsWithDefaults,\n\t\tpageId,\n\t\tbounds,\n\t\tscale,\n\t\tbackground,\n\t\tpadding,\n\t\tdarkMode,\n\t\tpreserveAspectRatio,\n\t\tpreloadingComplete,\n\t\tpreloadingError,\n\t\tlicenseKey,\n\t])\n\n\tif (preloadingError) {\n\t\treturn Could not load assets.\n\t}\n\n\tif (!preloadingComplete) {\n\t\treturn (\n\t\t\t\n\t\t\t\t\n\t\t\t\n\t\t)\n\t}\n\n\treturn (\n\t\t
\n\t\t\t{url && (\n\t\t\t\t\n\t\t\t)}\n\t\t
\n\t)\n})\n"], +- "mappings": "AA0LS;AA1LT;AAAA,EACC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAOA;AAAA,EACA;AAAA,OACM;AACP,SAAS,MAAM,iBAAiB,SAAS,gBAAgB;AACzD,SAAS,2BAA2B;AACpC,SAAS,yBAAyB;AAElC,SAAS,wBAAwB;AACjC,SAAS,qBAAqB;AAC9B,SAAS,2CAA2C;AAuD7C,MAAM,cAAc,KAAK,SAASA,aAAY,OAAyB;AAC7E,QAAM,CAAC,KAAK,MAAM,IAAI,SAAwB,IAAI;AAClD,QAAM,CAAC,WAAW,YAAY,IAAI,SAAgC,IAAI;AAEtE,QAAM,aAAa,wBAAwB,MAAM,cAAc,CAAC,CAAC;AACjE,QAAM,yBAAyB,QAAQ,MAAM,CAAC,GAAG,mBAAmB,GAAG,UAAU,GAAG,CAAC,UAAU,CAAC;AAChG,QAAM,eAAe,wBAAwB,MAAM,gBAAgB,CAAC,CAAC;AACrE,QAAM,2BAA2B;AAAA,IAChC,MAAM,CAAC,GAAG,qBAAqB,GAAG,YAAY;AAAA,IAC9C,CAAC,YAAY;AAAA,EACd;AACA,QAAM,QAAQ,WAAW,EAAE,UAAU,MAAM,UAAU,YAAY,uBAAuB,CAAC;AAEzF,QAAM,SAAS,oCAAoC,MAAM,SAAS;AAClE,QAAM,EAAE,MAAM,oBAAoB,OAAO,gBAAgB,IAAI,iBAAiB,MAAM;AAEpF,QAAM;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,SAAS;AAAA,IACT;AAAA,EACD,IAAI;AAEJ,kBAAgB,MAAM;AACrB,QAAI,CAAC,UAAW;AAChB,QAAI,CAAC,MAAO;AACZ,QAAI,CAAC,mBAAoB;AAEzB,QAAI,cAAc;AAElB,UAAM,UAAU,SAAS,cAAc,KAAK;AAC5C,cAAU,YAAY,OAAO;AAC7B,cAAU,UAAU,IAAI,gBAAgB,iBAAiB;AAEzD,UAAM,SAAS,IAAI,OAAO;AAAA,MACzB;AAAA,MACA,YAAY;AAAA,MACZ,cAAc;AAAA,MACd,OAAO,CAAC;AAAA,MACR,cAAc,MAAM;AAAA,MACpB;AAAA,IACD,CAAC;AAED,QAAI,OAAQ,QAAO,eAAe,MAAM;AAExC,UAAM,WAAW,OAAO,uBAAuB;AAE/C,mBAAe,SAAS;AACvB,YAAM,YAAY,MAAM,OAAO,aAAa,CAAC,GAAG,QAAQ,GAAG;AAAA,QAC1D;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACD,CAAC;AAED,UAAI,aAAa,CAAC,aAAa;AAC9B,YAAI,WAAW,OAAO;AACrB,cAAI,CAAC,aAAa;AACjB,kBAAM,OAAO,IAAI,KAAK,CAAC,UAAU,GAAG,GAAG,EAAE,MAAM,gBAAgB,CAAC;AAChE,kBAAMC,OAAM,IAAI,gBAAgB,IAAI;AACpC,mBAAOA,IAAG;AAAA,UACX;AAAA,QACD,WAAW,WAAW,OAAO;AAC5B,gBAAM,OAAO,MAAM,cAAc,QAAQ,UAAU,KAAK;AAAA,YACvD,MAAM;AAAA,YACN,SAAS;AAAA,YACT,OAAO;AAAA,YACP,OAAO,UAAU;AAAA,YACjB,QAAQ,UAAU;AAAA,UACnB,CAAC;AACD,cAAI,QAAQ,CAAC,aAAa;AACzB,kBAAMA,OAAM,IAAI,gBAAgB,IAAI;AACpC,mBAAOA,IAAG;AAAA,UACX;AAAA,QACD;AAAA,MACD;AAEA,aAAO,QAAQ;AAAA,IAChB;AAEA,WAAO;AAEP,WAAO,MAAM;AACZ,oBAAc;AAAA,IACf;AAAA,EACD,GAAG;AAAA,IACF;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACD,CAAC;AAED,MAAI,iBAAiB;AACpB,WAAO,oBAAC,eAAY,oCAAsB;AAAA,EAC3C;AAEA,MAAI,CAAC,oBAAoB;AACxB,WACC,oBAAC,iBACA,8BAAC,kBAAe,GACjB;AAAA,EAEF;AAEA,SACC,oBAAC,SAAI,KAAK,cAAc,OAAO,EAAE,UAAU,YAAY,OAAO,QAAQ,QAAQ,OAAO,GACnF,iBACA;AAAA,IAAC;AAAA;AAAA,MACA,KAAK;AAAA,MACL,gBAAe;AAAA,MACf,OAAO,EAAE,OAAO,QAAQ,QAAQ,OAAO;AAAA;AAAA,EACxC,GAEF;AAEF,CAAC;", ++ "sourcesContent": ["import {\n\tDefaultSpinner,\n\tEditor,\n\tErrorScreen,\n\tLoadingScreen,\n\tTLAnyBindingUtilConstructor,\n\tTLAnyShapeUtilConstructor,\n\tTLAssetStore,\n\tTLEditorSnapshot,\n\tTLImageExportOptions,\n\tTLPageId,\n\tTLStoreSnapshot,\n\tuseShallowArrayIdentity,\n\tuseTLStore,\n} from '@tldraw/editor'\nimport { memo, useLayoutEffect, useMemo, useState } from 'react'\nimport { defaultBindingUtils } from './defaultBindingUtils'\nimport { defaultShapeUtils } from './defaultShapeUtils'\nimport { TLUiAssetUrlOverrides } from './ui/assetUrls'\nimport { usePreloadAssets } from './ui/hooks/usePreloadAssets'\nimport { getSvgAsImage } from './utils/export/export'\nimport { useDefaultEditorAssetsWithOverrides } from './utils/static-assets/assetUrls'\n\n/** @public */\nexport interface TldrawImageProps extends TLImageExportOptions {\n\t/**\n\t * The snapshot to display.\n\t */\n\tsnapshot: Partial | TLStoreSnapshot\n\n\t/**\n\t * The image format to use. Defaults to 'svg'.\n\t */\n\tformat?: 'svg' | 'png'\n\n\t/**\n\t * The page to display. Defaults to the first page.\n\t */\n\tpageId?: TLPageId\n\n\t/**\n\t * Additional shape utils to use.\n\t */\n\tshapeUtils?: readonly TLAnyShapeUtilConstructor[]\n\t/**\n\t * Additional binding utils to use.\n\t */\n\tbindingUtils?: readonly TLAnyBindingUtilConstructor[]\n\t/**\n\t * The license key.\n\t */\n\tlicenseKey?: string\n\t/**\n\t * How should this store resolve assets?\n\t */\n\tassets?: TLAssetStore\n\t/**\n\t * Asset URL overrides.\n\t */\n\tassetUrls?: TLUiAssetUrlOverrides\n}\n\n/**\n * A renderered SVG image of a Tldraw snapshot.\n *\n * @example\n * ```tsx\n * \n * ```\n *\n * @public\n * @react\n */\nexport const TldrawImage = memo(function TldrawImage(props: TldrawImageProps) {\n\tconst [url, setUrl] = useState(null)\n\tconst [container, setContainer] = useState(null)\n\n\tconst shapeUtils = useShallowArrayIdentity(props.shapeUtils ?? [])\n\tconst shapeUtilsWithDefaults = useMemo(() => [...defaultShapeUtils, ...shapeUtils], [shapeUtils])\n\tconst bindingUtils = useShallowArrayIdentity(props.bindingUtils ?? [])\n\tconst bindingUtilsWithDefaults = useMemo(\n\t\t() => [...defaultBindingUtils, ...bindingUtils],\n\t\t[bindingUtils]\n\t)\n\tconst store = useTLStore({\n\t\tassets: props.assets,\n\t\tsnapshot: props.snapshot,\n\t\tshapeUtils: shapeUtilsWithDefaults,\n\t})\n\n\tconst assets = useDefaultEditorAssetsWithOverrides(props.assetUrls)\n\tconst { done: preloadingComplete, error: preloadingError } = usePreloadAssets(assets)\n\n\tconst {\n\t\tpageId,\n\t\tbounds,\n\t\tscale,\n\t\tbackground,\n\t\tpadding,\n\t\tdarkMode,\n\t\tpreserveAspectRatio,\n\t\tformat = 'svg',\n\t\tlicenseKey,\n\t} = props\n\n\tuseLayoutEffect(() => {\n\t\tif (!container) return\n\t\tif (!store) return\n\t\tif (!preloadingComplete) return\n\n\t\tlet isCancelled = false\n\n\t\tconst tempElm = document.createElement('div')\n\t\tcontainer.appendChild(tempElm)\n\t\tcontainer.classList.add('tl-container', 'tl-theme__light')\n\n\t\tconst editor = new Editor({\n\t\t\tstore,\n\t\t\tshapeUtils: shapeUtilsWithDefaults,\n\t\t\tbindingUtils: bindingUtilsWithDefaults,\n\t\t\ttools: [],\n\t\t\tgetContainer: () => tempElm,\n\t\t\tlicenseKey,\n\t\t})\n\n\t\tif (pageId) editor.setCurrentPage(pageId)\n\n\t\tconst shapeIds = editor.getCurrentPageShapeIds()\n\n\t\tasync function setSvg() {\n\t\t\tconst svgResult = await editor.getSvgString([...shapeIds], {\n\t\t\t\tbounds,\n\t\t\t\tscale,\n\t\t\t\tbackground,\n\t\t\t\tpadding,\n\t\t\t\tdarkMode,\n\t\t\t\tpreserveAspectRatio,\n\t\t\t})\n\n\t\t\tif (svgResult && !isCancelled) {\n\t\t\t\tif (format === 'svg') {\n\t\t\t\t\tif (!isCancelled) {\n\t\t\t\t\t\tconst blob = new Blob([svgResult.svg], { type: 'image/svg+xml' })\n\t\t\t\t\t\tconst url = URL.createObjectURL(blob)\n\t\t\t\t\t\tsetUrl(url)\n\t\t\t\t\t}\n\t\t\t\t} else if (format === 'png') {\n\t\t\t\t\tconst blob = await getSvgAsImage(editor, svgResult.svg, {\n\t\t\t\t\t\ttype: format,\n\t\t\t\t\t\tquality: 1,\n\t\t\t\t\t\tscale: 2,\n\t\t\t\t\t\twidth: svgResult.width,\n\t\t\t\t\t\theight: svgResult.height,\n\t\t\t\t\t})\n\t\t\t\t\tif (blob && !isCancelled) {\n\t\t\t\t\t\tconst url = URL.createObjectURL(blob)\n\t\t\t\t\t\tsetUrl(url)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\teditor.dispose()\n\t\t}\n\n\t\tsetSvg()\n\n\t\treturn () => {\n\t\t\tisCancelled = true\n\t\t}\n\t}, [\n\t\tformat,\n\t\tcontainer,\n\t\tstore,\n\t\tshapeUtilsWithDefaults,\n\t\tbindingUtilsWithDefaults,\n\t\tpageId,\n\t\tbounds,\n\t\tscale,\n\t\tbackground,\n\t\tpadding,\n\t\tdarkMode,\n\t\tpreserveAspectRatio,\n\t\tpreloadingComplete,\n\t\tpreloadingError,\n\t\tlicenseKey,\n\t])\n\n\tif (preloadingError) {\n\t\treturn Could not load assets.\n\t}\n\n\tif (!preloadingComplete) {\n\t\treturn (\n\t\t\t\n\t\t\t\t\n\t\t\t\n\t\t)\n\t}\n\n\treturn (\n\t\t
\n\t\t\t{url && (\n\t\t\t\t\n\t\t\t)}\n\t\t
\n\t)\n})\n"], ++ "mappings": "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", + "names": ["TldrawImage", "url"] + } +diff --git a/node_modules/tldraw/dist-esm/lib/shapes/shared/TextHelpers.mjs b/node_modules/tldraw/dist-esm/lib/shapes/shared/TextHelpers.mjs +index 35bdaa2..a46fec6 100644 +--- a/node_modules/tldraw/dist-esm/lib/shapes/shared/TextHelpers.mjs ++++ b/node_modules/tldraw/dist-esm/lib/shapes/shared/TextHelpers.mjs +@@ -37,7 +37,7 @@ class TextHelpers { + } + if (initialFocus === document.body) { + field.blur(); +- } else if (initialFocus instanceof HTMLElement && initialFocus !== field) { ++ } else if (initialFocus?.instanceOf(HTMLElement) && initialFocus !== field) { + initialFocus.focus(); + } + } +diff --git a/node_modules/tldraw/dist-esm/lib/shapes/shared/TextHelpers.mjs.map b/node_modules/tldraw/dist-esm/lib/shapes/shared/TextHelpers.mjs.map +index f6256de..e31db8c 100644 +--- a/node_modules/tldraw/dist-esm/lib/shapes/shared/TextHelpers.mjs.map ++++ b/node_modules/tldraw/dist-esm/lib/shapes/shared/TextHelpers.mjs.map +@@ -1,7 +1,7 @@ + { + "version": 3, + "sources": ["../../../../src/lib/shapes/shared/TextHelpers.ts"], +- "sourcesContent": ["/*!\n * MIT License\n * Adapted (mostly copied) the work of https://github.com/fregante/text-field-edit\n * Copyright (c) Federico Brigante (bfred.it)\n */\n\n// TODO: Most of this file can be moved into a DOM utils library.\n\n/** @internal */\nexport type ReplacerCallback = (substring: string, ...args: unknown[]) => string\n\n/**\t@public */\nexport const INDENT = ' '\n\n/** @internal */\nexport class TextHelpers {\n\tstatic insertTextFirefox(field: HTMLTextAreaElement | HTMLInputElement, text: string): void {\n\t\t// Found on https://www.everythingfrontend.com/blog/insert-text-into-textarea-at-cursor-position.html \uD83C\uDF88\n\t\tfield.setRangeText(\n\t\t\ttext,\n\t\t\tfield.selectionStart || 0,\n\t\t\tfield.selectionEnd || 0,\n\t\t\t'end' // Without this, the cursor is either at the beginning or text remains selected\n\t\t)\n\n\t\tfield.dispatchEvent(\n\t\t\tnew InputEvent('input', {\n\t\t\t\tdata: text,\n\t\t\t\tinputType: 'insertText',\n\t\t\t\tisComposing: false, // TODO: fix @types/jsdom, this shouldn't be required\n\t\t\t})\n\t\t)\n\t}\n\n\t/**\n\t * Inserts text at the cursor\u2019s position, replacing any selection, with **undo** support and by\n\t * firing the input event.\n\t */\n\tstatic insert(field: HTMLTextAreaElement | HTMLInputElement, text: string): void {\n\t\tconst document = field.ownerDocument\n\t\tconst initialFocus = document.activeElement\n\t\tif (initialFocus !== field) {\n\t\t\tfield.focus()\n\t\t}\n\n\t\t// eslint-disable-next-line @typescript-eslint/no-deprecated\n\t\tif (!document.execCommand('insertText', false, text)) {\n\t\t\tTextHelpers.insertTextFirefox(field, text)\n\t\t}\n\n\t\tif (initialFocus === document.body) {\n\t\t\tfield.blur()\n\t\t} else if (initialFocus instanceof HTMLElement && initialFocus !== field) {\n\t\t\tinitialFocus.focus()\n\t\t}\n\t}\n\n\t/**\n\t * Replaces the entire content, equivalent to field.value = text but with **undo** support and by\n\t * firing the input event.\n\t */\n\tstatic set(field: HTMLTextAreaElement | HTMLInputElement, text: string): void {\n\t\tfield.select()\n\t\tTextHelpers.insert(field, text)\n\t}\n\n\t/** Get the selected text in a field or an empty string if nothing is selected. */\n\tstatic getSelection(field: HTMLTextAreaElement | HTMLInputElement): string {\n\t\tconst { selectionStart, selectionEnd } = field\n\t\treturn field.value.slice(\n\t\t\tselectionStart ? selectionStart : undefined,\n\t\t\tselectionEnd ? selectionEnd : undefined\n\t\t)\n\t}\n\n\t/**\n\t * Adds the wrappingText before and after field\u2019s selection (or cursor). If endWrappingText is\n\t * provided, it will be used instead of wrappingText at on the right.\n\t */\n\tstatic wrapSelection(\n\t\tfield: HTMLTextAreaElement | HTMLInputElement,\n\t\twrap: string,\n\t\twrapEnd?: string\n\t): void {\n\t\tconst { selectionStart, selectionEnd } = field\n\t\tconst selection = TextHelpers.getSelection(field)\n\t\tTextHelpers.insert(field, wrap + selection + (wrapEnd ?? wrap))\n\n\t\t// Restore the selection around the previously-selected text\n\t\tfield.selectionStart = (selectionStart || 0) + wrap.length\n\t\tfield.selectionEnd = (selectionEnd || 0) + wrap.length\n\t}\n\n\t/** Finds and replaces strings and regex in the field\u2019s value. */\n\tstatic replace(\n\t\tfield: HTMLTextAreaElement | HTMLInputElement,\n\t\tsearchValue: string | RegExp,\n\t\treplacer: string | ReplacerCallback\n\t): void {\n\t\t/** Remembers how much each match offset should be adjusted */\n\t\tlet drift = 0\n\t\tfield.value.replace(searchValue, (...args): string => {\n\t\t\t// Select current match to replace it later\n\t\t\tconst matchStart = drift + (args[args.length - 2] as number)\n\t\t\tconst matchLength = args[0].length\n\t\t\tfield.selectionStart = matchStart\n\t\t\tfield.selectionEnd = matchStart + matchLength\n\t\t\tconst replacement = typeof replacer === 'string' ? replacer : replacer(...args)\n\t\t\tTextHelpers.insert(field, replacement)\n\t\t\t// Select replacement. Without this, the cursor would be after the replacement\n\t\t\tfield.selectionStart = matchStart\n\t\t\tdrift += replacement.length - matchLength\n\t\t\treturn replacement\n\t\t})\n\t}\n\n\tstatic findLineEnd(value: string, currentEnd: number): number {\n\t\t// Go to the beginning of the last line\n\t\tconst lastLineStart = value.lastIndexOf('\\n', currentEnd - 1) + 1\n\t\t// There's nothing to unindent after the last cursor, so leave it as is\n\t\tif (value.charAt(lastLineStart) !== '\\t') {\n\t\t\treturn currentEnd\n\t\t}\n\t\treturn lastLineStart + 1 // Include the first character, which will be a tab\n\t}\n\n\tstatic indent(element: HTMLTextAreaElement): void {\n\t\tconst { selectionStart, selectionEnd, value } = element\n\t\tconst selectedContrast = value.slice(selectionStart, selectionEnd)\n\t\t// The first line should be indented, even if it starts with \\n\n\t\t// The last line should only be indented if includes any character after \\n\n\t\tconst lineBreakCount = /\\n/g.exec(selectedContrast)?.length\n\n\t\tif (lineBreakCount && lineBreakCount > 0) {\n\t\t\t// Select full first line to replace everything at once\n\t\t\tconst firstLineStart = value.lastIndexOf('\\n', selectionStart - 1) + 1\n\n\t\t\tconst newSelection = element.value.slice(firstLineStart, selectionEnd - 1)\n\t\t\tconst indentedText = newSelection.replace(\n\t\t\t\t/^|\\n/g, // Match all line starts\n\t\t\t\t`$&${INDENT}`\n\t\t\t)\n\t\t\tconst replacementsCount = indentedText.length - newSelection.length\n\n\t\t\t// Replace newSelection with indentedText\n\t\t\telement.setSelectionRange(firstLineStart, selectionEnd - 1)\n\t\t\tTextHelpers.insert(element, indentedText)\n\n\t\t\t// Restore selection position, including the indentation\n\t\t\telement.setSelectionRange(selectionStart + 1, selectionEnd + replacementsCount)\n\t\t} else {\n\t\t\tTextHelpers.insert(element, INDENT)\n\t\t}\n\t}\n\n\t// The first line should always be unindented\n\t// The last line should only be unindented if the selection includes any characters after \\n\n\tstatic unindent(element: HTMLTextAreaElement): void {\n\t\tconst { selectionStart, selectionEnd, value } = element\n\n\t\t// Select the whole first line because it might contain \\t\n\t\tconst firstLineStart = value.lastIndexOf('\\n', selectionStart - 1) + 1\n\t\tconst minimumSelectionEnd = TextHelpers.findLineEnd(value, selectionEnd)\n\n\t\tconst newSelection = element.value.slice(firstLineStart, minimumSelectionEnd)\n\t\tconst indentedText = newSelection.replace(/(^|\\n)(\\t| {1,2})/g, '$1')\n\t\tconst replacementsCount = newSelection.length - indentedText.length\n\n\t\t// Replace newSelection with indentedText\n\t\telement.setSelectionRange(firstLineStart, minimumSelectionEnd)\n\t\tTextHelpers.insert(element, indentedText)\n\n\t\t// Restore selection position, including the indentation\n\t\tconst firstLineIndentation = /\\t| {1,2}/.exec(value.slice(firstLineStart, selectionStart))\n\n\t\tconst difference = firstLineIndentation ? firstLineIndentation[0].length : 0\n\n\t\tconst newSelectionStart = selectionStart - difference\n\t\telement.setSelectionRange(\n\t\t\tselectionStart - difference,\n\t\t\tMath.max(newSelectionStart, selectionEnd - replacementsCount)\n\t\t)\n\t}\n\n\tstatic indentCE(element: HTMLElement): void {\n\t\tconst selection = window.getSelection()\n\t\tconst value = element.innerText\n\t\tconst selectionStart = getCaretIndex(element) ?? 0\n\t\tconst selectionEnd = getCaretIndex(element) ?? 0\n\t\tconst selectedContrast = value.slice(selectionStart, selectionEnd)\n\t\t// The first line should be indented, even if it starts with \\n\n\t\t// The last line should only be indented if includes any character after \\n\n\t\tconst lineBreakCount = /\\n/g.exec(selectedContrast)?.length\n\n\t\tif (lineBreakCount && lineBreakCount > 0) {\n\t\t\t// Select full first line to replace everything at once\n\t\t\tconst firstLineStart = value.lastIndexOf('\\n', selectionStart - 1) + 1\n\n\t\t\tconst newSelection = value.slice(firstLineStart, selectionEnd - 1)\n\t\t\tconst indentedText = newSelection.replace(\n\t\t\t\t/^|\\n/g, // Match all line starts\n\t\t\t\t`$&${INDENT}`\n\t\t\t)\n\t\t\tconst replacementsCount = indentedText.length - newSelection.length\n\n\t\t\t// Replace newSelection with indentedText\n\n\t\t\tif (selection) {\n\t\t\t\tselection.setBaseAndExtent(\n\t\t\t\t\telement,\n\t\t\t\t\tselectionStart + 1,\n\t\t\t\t\telement,\n\t\t\t\t\tselectionEnd + replacementsCount\n\t\t\t\t)\n\t\t\t\t// element.setSelectionRange(firstLineStart, selectionEnd - 1)\n\t\t\t\t// TextHelpers.insert(element, indentedText)\n\n\t\t\t\t// Restore selection position, including the indentation\n\t\t\t\t// element.setSelectionRange(selectionStart + 1, selectionEnd + replacementsCount)\n\t\t\t}\n\t\t} else {\n\t\t\tconst selection = window.getSelection()\n\t\t\telement.innerText = value.slice(0, selectionStart) + INDENT + value.slice(selectionStart)\n\t\t\tselection?.setBaseAndExtent(element, selectionStart + 1, element, selectionStart + 2)\n\t\t\t// TextHelpers.insert(element, INDENT)\n\t\t}\n\t}\n\n\tstatic unindentCE(element: HTMLElement): void {\n\t\tconst selection = window.getSelection()\n\t\tconst value = element.innerText\n\t\t// const { selectionStart, selectionEnd } = element\n\t\tconst selectionStart = getCaretIndex(element) ?? 0\n\t\tconst selectionEnd = getCaretIndex(element) ?? 0\n\n\t\t// Select the whole first line because it might contain \\t\n\t\tconst firstLineStart = value.lastIndexOf('\\n', selectionStart - 1) + 1\n\t\tconst minimumSelectionEnd = TextHelpers.findLineEnd(value, selectionEnd)\n\n\t\tconst newSelection = value.slice(firstLineStart, minimumSelectionEnd)\n\t\tconst indentedText = newSelection.replace(/(^|\\n)(\\t| {1,2})/g, '$1')\n\t\tconst replacementsCount = newSelection.length - indentedText.length\n\n\t\tif (selection) {\n\t\t\t// Replace newSelection with indentedText\n\t\t\tselection.setBaseAndExtent(element, firstLineStart, element, minimumSelectionEnd)\n\t\t\t// TextHelpers.insert(element, indentedText)\n\n\t\t\t// Restore selection position, including the indentation\n\t\t\tconst firstLineIndentation = /\\t| {1,2}/.exec(value.slice(firstLineStart, selectionStart))\n\n\t\t\tconst difference = firstLineIndentation ? firstLineIndentation[0].length : 0\n\n\t\t\tconst newSelectionStart = selectionStart - difference\n\t\t\tselection.setBaseAndExtent(\n\t\t\t\telement,\n\t\t\t\tselectionStart - difference,\n\t\t\t\telement,\n\t\t\t\tMath.max(newSelectionStart, selectionEnd - replacementsCount)\n\t\t\t)\n\t\t}\n\t}\n\n\tstatic fixNewLines = /\\r?\\n|\\r/g\n\n\tstatic normalizeText(text: string) {\n\t\treturn text.replace(TextHelpers.fixNewLines, '\\n')\n\t}\n\n\tstatic normalizeTextForDom(text: string) {\n\t\treturn text\n\t\t\t.replace(TextHelpers.fixNewLines, '\\n')\n\t\t\t.split('\\n')\n\t\t\t.map((x) => x || ' ')\n\t\t\t.join('\\n')\n\t}\n}\n\nfunction getCaretIndex(element: HTMLElement) {\n\tif (typeof window.getSelection === 'undefined') return\n\tconst selection = window.getSelection()\n\tif (!selection) return\n\tlet position = 0\n\tif (selection.rangeCount !== 0) {\n\t\tconst range = selection.getRangeAt(0)\n\t\tconst preCaretRange = range.cloneRange()\n\t\tpreCaretRange.selectNodeContents(element)\n\t\tpreCaretRange.setEnd(range.endContainer, range.endOffset)\n\t\tposition = preCaretRange.toString().length\n\t}\n\treturn position\n}\n"], +- "mappings": "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", ++ "sourcesContent": ["/*!\n * MIT License\n * Adapted (mostly copied) the work of https://github.com/fregante/text-field-edit\n * Copyright (c) Federico Brigante (bfred.it)\n */\n\n// TODO: Most of this file can be moved into a DOM utils library.\n\n/** @internal */\nexport type ReplacerCallback = (substring: string, ...args: unknown[]) => string\n\n/**\t@public */\nexport const INDENT = ' '\n\n/** @internal */\nexport class TextHelpers {\n\tstatic insertTextFirefox(field: HTMLTextAreaElement | HTMLInputElement, text: string): void {\n\t\t// Found on https://www.everythingfrontend.com/blog/insert-text-into-textarea-at-cursor-position.html \uD83C\uDF88\n\t\tfield.setRangeText(\n\t\t\ttext,\n\t\t\tfield.selectionStart || 0,\n\t\t\tfield.selectionEnd || 0,\n\t\t\t'end' // Without this, the cursor is either at the beginning or text remains selected\n\t\t)\n\n\t\tfield.dispatchEvent(\n\t\t\tnew InputEvent('input', {\n\t\t\t\tdata: text,\n\t\t\t\tinputType: 'insertText',\n\t\t\t\tisComposing: false, // TODO: fix @types/jsdom, this shouldn't be required\n\t\t\t})\n\t\t)\n\t}\n\n\t/**\n\t * Inserts text at the cursor\u2019s position, replacing any selection, with **undo** support and by\n\t * firing the input event.\n\t */\n\tstatic insert(field: HTMLTextAreaElement | HTMLInputElement, text: string): void {\n\t\tconst document = field.ownerDocument\n\t\tconst initialFocus = document.activeElement\n\t\tif (initialFocus !== field) {\n\t\t\tfield.focus()\n\t\t}\n\n\t\t// eslint-disable-next-line @typescript-eslint/no-deprecated\n\t\tif (!document.execCommand('insertText', false, text)) {\n\t\t\tTextHelpers.insertTextFirefox(field, text)\n\t\t}\n\n\t\tif (initialFocus === document.body) {\n\t\t\tfield.blur()\n\t\t} else if (initialFocus?.instanceOf(HTMLElement) && initialFocus !== field) {\n\t\t\tinitialFocus.focus()\n\t\t}\n\t}\n\n\t/**\n\t * Replaces the entire content, equivalent to field.value = text but with **undo** support and by\n\t * firing the input event.\n\t */\n\tstatic set(field: HTMLTextAreaElement | HTMLInputElement, text: string): void {\n\t\tfield.select()\n\t\tTextHelpers.insert(field, text)\n\t}\n\n\t/** Get the selected text in a field or an empty string if nothing is selected. */\n\tstatic getSelection(field: HTMLTextAreaElement | HTMLInputElement): string {\n\t\tconst { selectionStart, selectionEnd } = field\n\t\treturn field.value.slice(\n\t\t\tselectionStart ? selectionStart : undefined,\n\t\t\tselectionEnd ? selectionEnd : undefined\n\t\t)\n\t}\n\n\t/**\n\t * Adds the wrappingText before and after field\u2019s selection (or cursor). If endWrappingText is\n\t * provided, it will be used instead of wrappingText at on the right.\n\t */\n\tstatic wrapSelection(\n\t\tfield: HTMLTextAreaElement | HTMLInputElement,\n\t\twrap: string,\n\t\twrapEnd?: string\n\t): void {\n\t\tconst { selectionStart, selectionEnd } = field\n\t\tconst selection = TextHelpers.getSelection(field)\n\t\tTextHelpers.insert(field, wrap + selection + (wrapEnd ?? wrap))\n\n\t\t// Restore the selection around the previously-selected text\n\t\tfield.selectionStart = (selectionStart || 0) + wrap.length\n\t\tfield.selectionEnd = (selectionEnd || 0) + wrap.length\n\t}\n\n\t/** Finds and replaces strings and regex in the field\u2019s value. */\n\tstatic replace(\n\t\tfield: HTMLTextAreaElement | HTMLInputElement,\n\t\tsearchValue: string | RegExp,\n\t\treplacer: string | ReplacerCallback\n\t): void {\n\t\t/** Remembers how much each match offset should be adjusted */\n\t\tlet drift = 0\n\t\tfield.value.replace(searchValue, (...args): string => {\n\t\t\t// Select current match to replace it later\n\t\t\tconst matchStart = drift + (args[args.length - 2] as number)\n\t\t\tconst matchLength = args[0].length\n\t\t\tfield.selectionStart = matchStart\n\t\t\tfield.selectionEnd = matchStart + matchLength\n\t\t\tconst replacement = typeof replacer === 'string' ? replacer : replacer(...args)\n\t\t\tTextHelpers.insert(field, replacement)\n\t\t\t// Select replacement. Without this, the cursor would be after the replacement\n\t\t\tfield.selectionStart = matchStart\n\t\t\tdrift += replacement.length - matchLength\n\t\t\treturn replacement\n\t\t})\n\t}\n\n\tstatic findLineEnd(value: string, currentEnd: number): number {\n\t\t// Go to the beginning of the last line\n\t\tconst lastLineStart = value.lastIndexOf('\\n', currentEnd - 1) + 1\n\t\t// There's nothing to unindent after the last cursor, so leave it as is\n\t\tif (value.charAt(lastLineStart) !== '\\t') {\n\t\t\treturn currentEnd\n\t\t}\n\t\treturn lastLineStart + 1 // Include the first character, which will be a tab\n\t}\n\n\tstatic indent(element: HTMLTextAreaElement): void {\n\t\tconst { selectionStart, selectionEnd, value } = element\n\t\tconst selectedContrast = value.slice(selectionStart, selectionEnd)\n\t\t// The first line should be indented, even if it starts with \\n\n\t\t// The last line should only be indented if includes any character after \\n\n\t\tconst lineBreakCount = /\\n/g.exec(selectedContrast)?.length\n\n\t\tif (lineBreakCount && lineBreakCount > 0) {\n\t\t\t// Select full first line to replace everything at once\n\t\t\tconst firstLineStart = value.lastIndexOf('\\n', selectionStart - 1) + 1\n\n\t\t\tconst newSelection = element.value.slice(firstLineStart, selectionEnd - 1)\n\t\t\tconst indentedText = newSelection.replace(\n\t\t\t\t/^|\\n/g, // Match all line starts\n\t\t\t\t`$&${INDENT}`\n\t\t\t)\n\t\t\tconst replacementsCount = indentedText.length - newSelection.length\n\n\t\t\t// Replace newSelection with indentedText\n\t\t\telement.setSelectionRange(firstLineStart, selectionEnd - 1)\n\t\t\tTextHelpers.insert(element, indentedText)\n\n\t\t\t// Restore selection position, including the indentation\n\t\t\telement.setSelectionRange(selectionStart + 1, selectionEnd + replacementsCount)\n\t\t} else {\n\t\t\tTextHelpers.insert(element, INDENT)\n\t\t}\n\t}\n\n\t// The first line should always be unindented\n\t// The last line should only be unindented if the selection includes any characters after \\n\n\tstatic unindent(element: HTMLTextAreaElement): void {\n\t\tconst { selectionStart, selectionEnd, value } = element\n\n\t\t// Select the whole first line because it might contain \\t\n\t\tconst firstLineStart = value.lastIndexOf('\\n', selectionStart - 1) + 1\n\t\tconst minimumSelectionEnd = TextHelpers.findLineEnd(value, selectionEnd)\n\n\t\tconst newSelection = element.value.slice(firstLineStart, minimumSelectionEnd)\n\t\tconst indentedText = newSelection.replace(/(^|\\n)(\\t| {1,2})/g, '$1')\n\t\tconst replacementsCount = newSelection.length - indentedText.length\n\n\t\t// Replace newSelection with indentedText\n\t\telement.setSelectionRange(firstLineStart, minimumSelectionEnd)\n\t\tTextHelpers.insert(element, indentedText)\n\n\t\t// Restore selection position, including the indentation\n\t\tconst firstLineIndentation = /\\t| {1,2}/.exec(value.slice(firstLineStart, selectionStart))\n\n\t\tconst difference = firstLineIndentation ? firstLineIndentation[0].length : 0\n\n\t\tconst newSelectionStart = selectionStart - difference\n\t\telement.setSelectionRange(\n\t\t\tselectionStart - difference,\n\t\t\tMath.max(newSelectionStart, selectionEnd - replacementsCount)\n\t\t)\n\t}\n\n\tstatic indentCE(element: HTMLElement): void {\n\t\tconst selection = window.getSelection()\n\t\tconst value = element.innerText\n\t\tconst selectionStart = getCaretIndex(element) ?? 0\n\t\tconst selectionEnd = getCaretIndex(element) ?? 0\n\t\tconst selectedContrast = value.slice(selectionStart, selectionEnd)\n\t\t// The first line should be indented, even if it starts with \\n\n\t\t// The last line should only be indented if includes any character after \\n\n\t\tconst lineBreakCount = /\\n/g.exec(selectedContrast)?.length\n\n\t\tif (lineBreakCount && lineBreakCount > 0) {\n\t\t\t// Select full first line to replace everything at once\n\t\t\tconst firstLineStart = value.lastIndexOf('\\n', selectionStart - 1) + 1\n\n\t\t\tconst newSelection = value.slice(firstLineStart, selectionEnd - 1)\n\t\t\tconst indentedText = newSelection.replace(\n\t\t\t\t/^|\\n/g, // Match all line starts\n\t\t\t\t`$&${INDENT}`\n\t\t\t)\n\t\t\tconst replacementsCount = indentedText.length - newSelection.length\n\n\t\t\t// Replace newSelection with indentedText\n\n\t\t\tif (selection) {\n\t\t\t\tselection.setBaseAndExtent(\n\t\t\t\t\telement,\n\t\t\t\t\tselectionStart + 1,\n\t\t\t\t\telement,\n\t\t\t\t\tselectionEnd + replacementsCount\n\t\t\t\t)\n\t\t\t\t// element.setSelectionRange(firstLineStart, selectionEnd - 1)\n\t\t\t\t// TextHelpers.insert(element, indentedText)\n\n\t\t\t\t// Restore selection position, including the indentation\n\t\t\t\t// element.setSelectionRange(selectionStart + 1, selectionEnd + replacementsCount)\n\t\t\t}\n\t\t} else {\n\t\t\tconst selection = window.getSelection()\n\t\t\telement.innerText = value.slice(0, selectionStart) + INDENT + value.slice(selectionStart)\n\t\t\tselection?.setBaseAndExtent(element, selectionStart + 1, element, selectionStart + 2)\n\t\t\t// TextHelpers.insert(element, INDENT)\n\t\t}\n\t}\n\n\tstatic unindentCE(element: HTMLElement): void {\n\t\tconst selection = window.getSelection()\n\t\tconst value = element.innerText\n\t\t// const { selectionStart, selectionEnd } = element\n\t\tconst selectionStart = getCaretIndex(element) ?? 0\n\t\tconst selectionEnd = getCaretIndex(element) ?? 0\n\n\t\t// Select the whole first line because it might contain \\t\n\t\tconst firstLineStart = value.lastIndexOf('\\n', selectionStart - 1) + 1\n\t\tconst minimumSelectionEnd = TextHelpers.findLineEnd(value, selectionEnd)\n\n\t\tconst newSelection = value.slice(firstLineStart, minimumSelectionEnd)\n\t\tconst indentedText = newSelection.replace(/(^|\\n)(\\t| {1,2})/g, '$1')\n\t\tconst replacementsCount = newSelection.length - indentedText.length\n\n\t\tif (selection) {\n\t\t\t// Replace newSelection with indentedText\n\t\t\tselection.setBaseAndExtent(element, firstLineStart, element, minimumSelectionEnd)\n\t\t\t// TextHelpers.insert(element, indentedText)\n\n\t\t\t// Restore selection position, including the indentation\n\t\t\tconst firstLineIndentation = /\\t| {1,2}/.exec(value.slice(firstLineStart, selectionStart))\n\n\t\t\tconst difference = firstLineIndentation ? firstLineIndentation[0].length : 0\n\n\t\t\tconst newSelectionStart = selectionStart - difference\n\t\t\tselection.setBaseAndExtent(\n\t\t\t\telement,\n\t\t\t\tselectionStart - difference,\n\t\t\t\telement,\n\t\t\t\tMath.max(newSelectionStart, selectionEnd - replacementsCount)\n\t\t\t)\n\t\t}\n\t}\n\n\tstatic fixNewLines = /\\r?\\n|\\r/g\n\n\tstatic normalizeText(text: string) {\n\t\treturn text.replace(TextHelpers.fixNewLines, '\\n')\n\t}\n\n\tstatic normalizeTextForDom(text: string) {\n\t\treturn text\n\t\t\t.replace(TextHelpers.fixNewLines, '\\n')\n\t\t\t.split('\\n')\n\t\t\t.map((x) => x || ' ')\n\t\t\t.join('\\n')\n\t}\n}\n\nfunction getCaretIndex(element: HTMLElement) {\n\tif (typeof window.getSelection === 'undefined') return\n\tconst selection = window.getSelection()\n\tif (!selection) return\n\tlet position = 0\n\tif (selection.rangeCount !== 0) {\n\t\tconst range = selection.getRangeAt(0)\n\t\tconst preCaretRange = range.cloneRange()\n\t\tpreCaretRange.selectNodeContents(element)\n\t\tpreCaretRange.setEnd(range.endContainer, range.endOffset)\n\t\tposition = preCaretRange.toString().length\n\t}\n\treturn position\n}\n"], ++ "mappings": "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", + "names": ["selection"] + } +diff --git a/node_modules/tldraw/dist-esm/lib/ui/components/Toolbar/OverflowingToolbar.mjs b/node_modules/tldraw/dist-esm/lib/ui/components/Toolbar/OverflowingToolbar.mjs +index 9d35b1c..1a992ab 100644 +--- a/node_modules/tldraw/dist-esm/lib/ui/components/Toolbar/OverflowingToolbar.mjs ++++ b/node_modules/tldraw/dist-esm/lib/ui/components/Toolbar/OverflowingToolbar.mjs +@@ -88,7 +88,7 @@ function OverflowingToolbar({ children }) { + preventDefault(event); + const relevantEls = Array.from(mainToolsRef.current?.children ?? []).filter( + (el2) => { +- if (!(el2 instanceof HTMLElement)) return false; ++ if (!el2.instanceOf(HTMLElement)) return false; + if (el2.tagName.toLowerCase() !== "button") return false; + return !!(el2.offsetWidth || el2.offsetHeight); + } +diff --git a/node_modules/tldraw/dist-esm/lib/ui/components/Toolbar/OverflowingToolbar.mjs.map b/node_modules/tldraw/dist-esm/lib/ui/components/Toolbar/OverflowingToolbar.mjs.map +index 283c611..f738cf7 100644 +--- a/node_modules/tldraw/dist-esm/lib/ui/components/Toolbar/OverflowingToolbar.mjs.map ++++ b/node_modules/tldraw/dist-esm/lib/ui/components/Toolbar/OverflowingToolbar.mjs.map +@@ -1,7 +1,7 @@ + { + "version": 3, + "sources": ["../../../../../src/lib/ui/components/Toolbar/OverflowingToolbar.tsx"], +- "sourcesContent": ["import { preventDefault, useEditor, useEvent, useUniqueSafeId } from '@tldraw/editor'\nimport classNames from 'classnames'\nimport hotkeys from 'hotkeys-js'\nimport { createContext, useEffect, useLayoutEffect, useMemo, useRef, useState } from 'react'\nimport { PORTRAIT_BREAKPOINT } from '../../constants'\nimport { useBreakpoint } from '../../context/breakpoints'\nimport { areShortcutsDisabled } from '../../hooks/useKeyboardShortcuts'\nimport { TLUiToolItem } from '../../hooks/useTools'\nimport { useTranslation } from '../../hooks/useTranslation/useTranslation'\nimport { TldrawUiButton } from '../primitives/Button/TldrawUiButton'\nimport { TldrawUiButtonIcon } from '../primitives/Button/TldrawUiButtonIcon'\nimport {\n\tTldrawUiDropdownMenuContent,\n\tTldrawUiDropdownMenuRoot,\n\tTldrawUiDropdownMenuTrigger,\n} from '../primitives/TldrawUiDropdownMenu'\nimport { TldrawUiMenuContextProvider } from '../primitives/menus/TldrawUiMenuContext'\n\nexport const IsInOverflowContext = createContext(false)\n\n/** @public */\nexport interface OverflowingToolbarProps {\n\tchildren: React.ReactNode\n}\n\n/** @public @react */\nexport function OverflowingToolbar({ children }: OverflowingToolbarProps) {\n\tconst editor = useEditor()\n\tconst id = useUniqueSafeId()\n\tconst breakpoint = useBreakpoint()\n\tconst msg = useTranslation()\n\n\tconst overflowIndex = Math.min(8, 5 + breakpoint)\n\n\tconst [totalItems, setTotalItems] = useState(0)\n\tconst mainToolsRef = useRef(null)\n\tconst [lastActiveOverflowItem, setLastActiveOverflowItem] = useState(null)\n\n\tconst css = useMemo(() => {\n\t\tconst activeCss = lastActiveOverflowItem ? `:not([data-value=\"${lastActiveOverflowItem}\"])` : ''\n\n\t\treturn `\n\t\t\t#${id}_main > *:nth-child(n + ${overflowIndex + (lastActiveOverflowItem ? 1 : 2)})${activeCss} {\n\t\t\t\tdisplay: none;\n\t\t\t}\n\t\t\t#${id}_more > *:nth-child(-n + ${overflowIndex}) {\n\t\t\t\tdisplay: none;\n\t\t\t}\n `\n\t}, [lastActiveOverflowItem, id, overflowIndex])\n\n\tconst onDomUpdate = useEvent(() => {\n\t\tif (!mainToolsRef.current) return\n\n\t\tconst children = Array.from(mainToolsRef.current.children)\n\t\tsetTotalItems(children.length)\n\n\t\t// If the last active overflow item is no longer in the overflow, clear it\n\t\tconst lastActiveElementIdx = children.findIndex(\n\t\t\t(el) => el.getAttribute('data-value') === lastActiveOverflowItem\n\t\t)\n\t\tif (lastActiveElementIdx <= overflowIndex) {\n\t\t\tsetLastActiveOverflowItem(null)\n\t\t}\n\n\t\t// But if there's a new active item...\n\t\tconst activeElementIdx = Array.from(mainToolsRef.current.children).findIndex(\n\t\t\t(el) => el.getAttribute('aria-checked') === 'true'\n\t\t)\n\t\tif (activeElementIdx === -1) return\n\n\t\t// ...and it's in the overflow, set it as the last active overflow item\n\t\tif (activeElementIdx >= overflowIndex) {\n\t\t\tsetLastActiveOverflowItem(children[activeElementIdx].getAttribute('data-value'))\n\t\t}\n\t})\n\n\tuseLayoutEffect(() => {\n\t\tonDomUpdate()\n\t})\n\n\tuseLayoutEffect(() => {\n\t\tif (!mainToolsRef.current) return\n\n\t\tconst mutationObserver = new MutationObserver(onDomUpdate)\n\t\tmutationObserver.observe(mainToolsRef.current, {\n\t\t\tchildList: true,\n\t\t\tsubtree: true,\n\t\t\tattributeFilter: ['data-value', 'aria-checked'],\n\t\t})\n\n\t\treturn () => {\n\t\t\tmutationObserver.disconnect()\n\t\t}\n\t}, [onDomUpdate])\n\n\tuseEffect(() => {\n\t\tconst keys = [\n\t\t\t['1', 0],\n\t\t\t['2', 1],\n\t\t\t['3', 2],\n\t\t\t['4', 3],\n\t\t\t['5', 4],\n\t\t\t['6', 5],\n\t\t\t['7', 6],\n\t\t\t['8', 7],\n\t\t\t['9', 8],\n\t\t\t['0', 9],\n\t\t] as const\n\n\t\tfor (const [key, index] of keys) {\n\t\t\thotkeys(key, (event) => {\n\t\t\t\tif (areShortcutsDisabled(editor)) return\n\t\t\t\tpreventDefault(event)\n\n\t\t\t\tconst relevantEls = Array.from(mainToolsRef.current?.children ?? []).filter(\n\t\t\t\t\t(el): el is HTMLElement => {\n\t\t\t\t\t\t// only count html elements...\n\t\t\t\t\t\tif (!(el instanceof HTMLElement)) return false\n\n\t\t\t\t\t\t// ...that are buttons...\n\t\t\t\t\t\tif (el.tagName.toLowerCase() !== 'button') return false\n\n\t\t\t\t\t\t// ...that are actually visible\n\t\t\t\t\t\treturn !!(el.offsetWidth || el.offsetHeight)\n\t\t\t\t\t}\n\t\t\t\t)\n\n\t\t\t\tconst el = relevantEls[index]\n\t\t\t\tif (el) el.click()\n\t\t\t})\n\t\t}\n\n\t\treturn () => {\n\t\t\thotkeys.unbind('1,2,3,4,5,6,7,8,9,0')\n\t\t}\n\t}, [editor])\n\n\treturn (\n\t\t<>\n\t\t\t\n\t\t\t\n\t\t\t\t
\n\t\t\t\t\t\n\t\t\t\t\t\t{children}\n\t\t\t\t\t\n\t\t\t\t
\n\t\t\t\t{/* There is a +1 because if the menu is just one item, it's not necessary. */}\n\t\t\t\t{totalItems > overflowIndex + 1 && (\n\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t{children}\n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t)}\n\t\t\t
\n\t\t\n\t)\n}\n\nexport const isActiveTLUiToolItem = (\n\titem: TLUiToolItem,\n\tactiveToolId: string | undefined,\n\tgeoState: string | null | undefined\n) => {\n\treturn item.meta?.geo\n\t\t? activeToolId === 'geo' && geoState === item.meta?.geo\n\t\t: activeToolId === item.id\n}\n"], +- "mappings": "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", ++ "sourcesContent": ["import { preventDefault, useEditor, useEvent, useUniqueSafeId } from '@tldraw/editor'\nimport classNames from 'classnames'\nimport hotkeys from 'hotkeys-js'\nimport { createContext, useEffect, useLayoutEffect, useMemo, useRef, useState } from 'react'\nimport { PORTRAIT_BREAKPOINT } from '../../constants'\nimport { useBreakpoint } from '../../context/breakpoints'\nimport { areShortcutsDisabled } from '../../hooks/useKeyboardShortcuts'\nimport { TLUiToolItem } from '../../hooks/useTools'\nimport { useTranslation } from '../../hooks/useTranslation/useTranslation'\nimport { TldrawUiButton } from '../primitives/Button/TldrawUiButton'\nimport { TldrawUiButtonIcon } from '../primitives/Button/TldrawUiButtonIcon'\nimport {\n\tTldrawUiDropdownMenuContent,\n\tTldrawUiDropdownMenuRoot,\n\tTldrawUiDropdownMenuTrigger,\n} from '../primitives/TldrawUiDropdownMenu'\nimport { TldrawUiMenuContextProvider } from '../primitives/menus/TldrawUiMenuContext'\n\nexport const IsInOverflowContext = createContext(false)\n\n/** @public */\nexport interface OverflowingToolbarProps {\n\tchildren: React.ReactNode\n}\n\n/** @public @react */\nexport function OverflowingToolbar({ children }: OverflowingToolbarProps) {\n\tconst editor = useEditor()\n\tconst id = useUniqueSafeId()\n\tconst breakpoint = useBreakpoint()\n\tconst msg = useTranslation()\n\n\tconst overflowIndex = Math.min(8, 5 + breakpoint)\n\n\tconst [totalItems, setTotalItems] = useState(0)\n\tconst mainToolsRef = useRef(null)\n\tconst [lastActiveOverflowItem, setLastActiveOverflowItem] = useState(null)\n\n\tconst css = useMemo(() => {\n\t\tconst activeCss = lastActiveOverflowItem ? `:not([data-value=\"${lastActiveOverflowItem}\"])` : ''\n\n\t\treturn `\n\t\t\t#${id}_main > *:nth-child(n + ${overflowIndex + (lastActiveOverflowItem ? 1 : 2)})${activeCss} {\n\t\t\t\tdisplay: none;\n\t\t\t}\n\t\t\t#${id}_more > *:nth-child(-n + ${overflowIndex}) {\n\t\t\t\tdisplay: none;\n\t\t\t}\n `\n\t}, [lastActiveOverflowItem, id, overflowIndex])\n\n\tconst onDomUpdate = useEvent(() => {\n\t\tif (!mainToolsRef.current) return\n\n\t\tconst children = Array.from(mainToolsRef.current.children)\n\t\tsetTotalItems(children.length)\n\n\t\t// If the last active overflow item is no longer in the overflow, clear it\n\t\tconst lastActiveElementIdx = children.findIndex(\n\t\t\t(el) => el.getAttribute('data-value') === lastActiveOverflowItem\n\t\t)\n\t\tif (lastActiveElementIdx <= overflowIndex) {\n\t\t\tsetLastActiveOverflowItem(null)\n\t\t}\n\n\t\t// But if there's a new active item...\n\t\tconst activeElementIdx = Array.from(mainToolsRef.current.children).findIndex(\n\t\t\t(el) => el.getAttribute('aria-checked') === 'true'\n\t\t)\n\t\tif (activeElementIdx === -1) return\n\n\t\t// ...and it's in the overflow, set it as the last active overflow item\n\t\tif (activeElementIdx >= overflowIndex) {\n\t\t\tsetLastActiveOverflowItem(children[activeElementIdx].getAttribute('data-value'))\n\t\t}\n\t})\n\n\tuseLayoutEffect(() => {\n\t\tonDomUpdate()\n\t})\n\n\tuseLayoutEffect(() => {\n\t\tif (!mainToolsRef.current) return\n\n\t\tconst mutationObserver = new MutationObserver(onDomUpdate)\n\t\tmutationObserver.observe(mainToolsRef.current, {\n\t\t\tchildList: true,\n\t\t\tsubtree: true,\n\t\t\tattributeFilter: ['data-value', 'aria-checked'],\n\t\t})\n\n\t\treturn () => {\n\t\t\tmutationObserver.disconnect()\n\t\t}\n\t}, [onDomUpdate])\n\n\tuseEffect(() => {\n\t\tconst keys = [\n\t\t\t['1', 0],\n\t\t\t['2', 1],\n\t\t\t['3', 2],\n\t\t\t['4', 3],\n\t\t\t['5', 4],\n\t\t\t['6', 5],\n\t\t\t['7', 6],\n\t\t\t['8', 7],\n\t\t\t['9', 8],\n\t\t\t['0', 9],\n\t\t] as const\n\n\t\tfor (const [key, index] of keys) {\n\t\t\thotkeys(key, (event) => {\n\t\t\t\tif (areShortcutsDisabled(editor)) return\n\t\t\t\tpreventDefault(event)\n\n\t\t\t\tconst relevantEls = Array.from(mainToolsRef.current?.children ?? []).filter(\n\t\t\t\t\t(el): el is HTMLElement => {\n\t\t\t\t\t\t// only count html elements...\n\t\t\t\t\t\tif (!el.instanceOf(HTMLElement)) return false\n\n\t\t\t\t\t\t// ...that are buttons...\n\t\t\t\t\t\tif (el.tagName.toLowerCase() !== 'button') return false\n\n\t\t\t\t\t\t// ...that are actually visible\n\t\t\t\t\t\treturn !!(el.offsetWidth || el.offsetHeight)\n\t\t\t\t\t}\n\t\t\t\t)\n\n\t\t\t\tconst el = relevantEls[index]\n\t\t\t\tif (el) el.click()\n\t\t\t})\n\t\t}\n\n\t\treturn () => {\n\t\t\thotkeys.unbind('1,2,3,4,5,6,7,8,9,0')\n\t\t}\n\t}, [editor])\n\n\treturn (\n\t\t<>\n\t\t\t\n\t\t\t\n\t\t\t\t
\n\t\t\t\t\t\n\t\t\t\t\t\t{children}\n\t\t\t\t\t\n\t\t\t\t
\n\t\t\t\t{/* There is a +1 because if the menu is just one item, it's not necessary. */}\n\t\t\t\t{totalItems > overflowIndex + 1 && (\n\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t{children}\n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t)}\n\t\t\t\n\t\t\n\t)\n}\n\nexport const isActiveTLUiToolItem = (\n\titem: TLUiToolItem,\n\tactiveToolId: string | undefined,\n\tgeoState: string | null | undefined\n) => {\n\treturn item.meta?.geo\n\t\t? activeToolId === 'geo' && geoState === item.meta?.geo\n\t\t: activeToolId === item.id\n}\n"], ++ "mappings": "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", + "names": ["children", "el"] + } +diff --git a/node_modules/tldraw/dist-esm/lib/ui/components/primitives/TldrawUiButtonPicker.mjs b/node_modules/tldraw/dist-esm/lib/ui/components/primitives/TldrawUiButtonPicker.mjs +index 396bc6f..aae4797 100644 +--- a/node_modules/tldraw/dist-esm/lib/ui/components/primitives/TldrawUiButtonPicker.mjs ++++ b/node_modules/tldraw/dist-esm/lib/ui/components/primitives/TldrawUiButtonPicker.mjs +@@ -1,6 +1,7 @@ + import { jsx } from "react/jsx-runtime"; + import { +- DefaultColorStyle ++ DefaultColorStyle, ++ useContainer + } from "@tldraw/editor"; + import classNames from "classnames"; + import { memo, useMemo, useRef } from "react"; +@@ -19,6 +20,7 @@ const TldrawUiButtonPicker = memo(function TldrawUiButtonPicker2(props) { + onHistoryMark, + theme + } = props; ++ const container = useContainer(); + const msg = useTranslation(); + const rPointing = useRef(false); + const rPointingOriginalActiveElement = useRef(null); +@@ -30,7 +32,7 @@ const TldrawUiButtonPicker = memo(function TldrawUiButtonPicker2(props) { + } = useMemo(() => { + const handlePointerUp = () => { + rPointing.current = false; +- window.removeEventListener("pointerup", handlePointerUp); ++ container.win.removeEventListener("pointerup", handlePointerUp); + const origActiveEl = rPointingOriginalActiveElement.current; + if (origActiveEl && ["TEXTAREA", "INPUT"].includes(origActiveEl.nodeName)) { + origActiveEl.focus(); +@@ -48,8 +50,8 @@ const TldrawUiButtonPicker = memo(function TldrawUiButtonPicker2(props) { + onHistoryMark?.("point picker item"); + onValueChange(style, id); + rPointing.current = true; +- rPointingOriginalActiveElement.current = document.activeElement; +- window.addEventListener("pointerup", handlePointerUp); ++ rPointingOriginalActiveElement.current = container.ownerDocument.activeElement; ++ container.win.addEventListener("pointerup", handlePointerUp); + }; + const handleButtonPointerEnter2 = (e) => { + if (!rPointing.current) return; +@@ -67,7 +69,7 @@ const TldrawUiButtonPicker = memo(function TldrawUiButtonPicker2(props) { + handleButtonPointerEnter: handleButtonPointerEnter2, + handleButtonPointerUp: handleButtonPointerUp2 + }; +- }, [value, onHistoryMark, onValueChange, style]); ++ }, [value, onHistoryMark, onValueChange, style, container]); + return /* @__PURE__ */ jsx("div", { "data-testid": `style.${uiType}`, className: classNames("tlui-buttons__grid"), children: items.map((item) => /* @__PURE__ */ jsx( + TldrawUiButton, + { +diff --git a/node_modules/tldraw/dist-esm/lib/ui/components/primitives/TldrawUiButtonPicker.mjs.map b/node_modules/tldraw/dist-esm/lib/ui/components/primitives/TldrawUiButtonPicker.mjs.map +index f75fba7..00d8e42 100644 +--- a/node_modules/tldraw/dist-esm/lib/ui/components/primitives/TldrawUiButtonPicker.mjs.map ++++ b/node_modules/tldraw/dist-esm/lib/ui/components/primitives/TldrawUiButtonPicker.mjs.map +@@ -1,7 +1,7 @@ + { + "version": 3, + "sources": ["../../../../../src/lib/ui/components/primitives/TldrawUiButtonPicker.tsx"], +- "sourcesContent": ["import {\n\tDefaultColorStyle,\n\tSharedStyle,\n\tStyleProp,\n\tTLDefaultColorStyle,\n\tTLDefaultColorTheme,\n} from '@tldraw/editor'\nimport classNames from 'classnames'\nimport { ReactElement, memo, useMemo, useRef } from 'react'\nimport { StyleValuesForUi } from '../../../styles'\nimport { TLUiTranslationKey } from '../../hooks/useTranslation/TLUiTranslationKey'\nimport { useTranslation } from '../../hooks/useTranslation/useTranslation'\nimport { TldrawUiButton } from './Button/TldrawUiButton'\nimport { TldrawUiButtonIcon } from './Button/TldrawUiButtonIcon'\n\n/** @public */\nexport interface TLUiButtonPickerProps {\n\ttitle: string\n\tuiType: string\n\tstyle: StyleProp\n\tvalue: SharedStyle\n\titems: StyleValuesForUi\n\ttheme: TLDefaultColorTheme\n\tonValueChange(style: StyleProp, value: T): void\n\tonHistoryMark?(id: string): void\n}\n\n/** @public */\nexport const TldrawUiButtonPicker = memo(function TldrawUiButtonPicker(\n\tprops: TLUiButtonPickerProps\n) {\n\tconst {\n\t\tuiType,\n\t\titems,\n\t\ttitle,\n\t\tstyle,\n\t\tvalue,\n\t\t// columns = clamp(items.length, 2, 4),\n\t\tonValueChange,\n\t\tonHistoryMark,\n\t\ttheme,\n\t} = props\n\tconst msg = useTranslation()\n\n\tconst rPointing = useRef(false)\n\tconst rPointingOriginalActiveElement = useRef(null)\n\n\tconst {\n\t\thandleButtonClick,\n\t\thandleButtonPointerDown,\n\t\thandleButtonPointerEnter,\n\t\thandleButtonPointerUp,\n\t} = useMemo(() => {\n\t\tconst handlePointerUp = () => {\n\t\t\trPointing.current = false\n\t\t\twindow.removeEventListener('pointerup', handlePointerUp)\n\n\t\t\t// This is fun little micro-optimization to make sure that the focus\n\t\t\t// is retained on a text label. That way, you can continue typing\n\t\t\t// after selecting a style.\n\t\t\tconst origActiveEl = rPointingOriginalActiveElement.current\n\t\t\tif (origActiveEl && ['TEXTAREA', 'INPUT'].includes(origActiveEl.nodeName)) {\n\t\t\t\torigActiveEl.focus()\n\t\t\t}\n\t\t\trPointingOriginalActiveElement.current = null\n\t\t}\n\n\t\tconst handleButtonClick = (e: React.PointerEvent) => {\n\t\t\tconst { id } = e.currentTarget.dataset\n\t\t\tif (value.type === 'shared' && value.value === id) return\n\n\t\t\tonHistoryMark?.('point picker item')\n\t\t\tonValueChange(style, id as T)\n\t\t}\n\n\t\tconst handleButtonPointerDown = (e: React.PointerEvent) => {\n\t\t\tconst { id } = e.currentTarget.dataset\n\n\t\t\tonHistoryMark?.('point picker item')\n\t\t\tonValueChange(style, id as T)\n\n\t\t\trPointing.current = true\n\t\t\trPointingOriginalActiveElement.current = document.activeElement as HTMLElement\n\t\t\twindow.addEventListener('pointerup', handlePointerUp) // see TLD-658\n\t\t}\n\n\t\tconst handleButtonPointerEnter = (e: React.PointerEvent) => {\n\t\t\tif (!rPointing.current) return\n\n\t\t\tconst { id } = e.currentTarget.dataset\n\t\t\tonValueChange(style, id as T)\n\t\t}\n\n\t\tconst handleButtonPointerUp = (e: React.PointerEvent) => {\n\t\t\tconst { id } = e.currentTarget.dataset\n\t\t\tif (value.type === 'shared' && value.value === id) return\n\n\t\t\tonValueChange(style, id as T)\n\t\t}\n\n\t\treturn {\n\t\t\thandleButtonClick,\n\t\t\thandleButtonPointerDown,\n\t\t\thandleButtonPointerEnter,\n\t\t\thandleButtonPointerUp,\n\t\t}\n\t}, [value, onHistoryMark, onValueChange, style])\n\n\treturn (\n\t\t
\n\t\t\t{items.map((item) => (\n\t\t\t\t)\n\t\t\t\t\t\t\t? { color: theme[item.value as TLDefaultColorStyle].solid }\n\t\t\t\t\t\t\t: undefined\n\t\t\t\t\t}\n\t\t\t\t\tonPointerEnter={handleButtonPointerEnter}\n\t\t\t\t\tonPointerDown={handleButtonPointerDown}\n\t\t\t\t\tonPointerUp={handleButtonPointerUp}\n\t\t\t\t\tonClick={handleButtonClick}\n\t\t\t\t>\n\t\t\t\t\t\n\t\t\t\t\n\t\t\t))}\n\t\t
\n\t)\n}) as (props: TLUiButtonPickerProps) => ReactElement\n"], +- "mappings": "AAkIK;AAlIL;AAAA,EACC;AAAA,OAKM;AACP,OAAO,gBAAgB;AACvB,SAAuB,MAAM,SAAS,cAAc;AAGpD,SAAS,sBAAsB;AAC/B,SAAS,sBAAsB;AAC/B,SAAS,0BAA0B;AAe5B,MAAM,uBAAuB,KAAK,SAASA,sBACjD,OACC;AACD,QAAM;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA;AAAA,IAEA;AAAA,IACA;AAAA,IACA;AAAA,EACD,IAAI;AACJ,QAAM,MAAM,eAAe;AAE3B,QAAM,YAAY,OAAO,KAAK;AAC9B,QAAM,iCAAiC,OAA2B,IAAI;AAEtE,QAAM;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACD,IAAI,QAAQ,MAAM;AACjB,UAAM,kBAAkB,MAAM;AAC7B,gBAAU,UAAU;AACpB,aAAO,oBAAoB,aAAa,eAAe;AAKvD,YAAM,eAAe,+BAA+B;AACpD,UAAI,gBAAgB,CAAC,YAAY,OAAO,EAAE,SAAS,aAAa,QAAQ,GAAG;AAC1E,qBAAa,MAAM;AAAA,MACpB;AACA,qCAA+B,UAAU;AAAA,IAC1C;AAEA,UAAMC,qBAAoB,CAAC,MAA6C;AACvE,YAAM,EAAE,GAAG,IAAI,EAAE,cAAc;AAC/B,UAAI,MAAM,SAAS,YAAY,MAAM,UAAU,GAAI;AAEnD,sBAAgB,mBAAmB;AACnC,oBAAc,OAAO,EAAO;AAAA,IAC7B;AAEA,UAAMC,2BAA0B,CAAC,MAA6C;AAC7E,YAAM,EAAE,GAAG,IAAI,EAAE,cAAc;AAE/B,sBAAgB,mBAAmB;AACnC,oBAAc,OAAO,EAAO;AAE5B,gBAAU,UAAU;AACpB,qCAA+B,UAAU,SAAS;AAClD,aAAO,iBAAiB,aAAa,eAAe;AAAA,IACrD;AAEA,UAAMC,4BAA2B,CAAC,MAA6C;AAC9E,UAAI,CAAC,UAAU,QAAS;AAExB,YAAM,EAAE,GAAG,IAAI,EAAE,cAAc;AAC/B,oBAAc,OAAO,EAAO;AAAA,IAC7B;AAEA,UAAMC,yBAAwB,CAAC,MAA6C;AAC3E,YAAM,EAAE,GAAG,IAAI,EAAE,cAAc;AAC/B,UAAI,MAAM,SAAS,YAAY,MAAM,UAAU,GAAI;AAEnD,oBAAc,OAAO,EAAO;AAAA,IAC7B;AAEA,WAAO;AAAA,MACN,mBAAAH;AAAA,MACA,yBAAAC;AAAA,MACA,0BAAAC;AAAA,MACA,uBAAAC;AAAA,IACD;AAAA,EACD,GAAG,CAAC,OAAO,eAAe,eAAe,KAAK,CAAC;AAE/C,SACC,oBAAC,SAAI,eAAa,SAAS,MAAM,IAAI,WAAW,WAAW,oBAAoB,GAC7E,gBAAM,IAAI,CAAC,SACX;AAAA,IAAC;AAAA;AAAA,MACA,MAAK;AAAA,MAEL,WAAS,KAAK;AAAA,MACd,eAAa,SAAS,MAAM,IAAI,KAAK,KAAK;AAAA,MAC1C,cAAY,KAAK;AAAA,MACjB,cAAY,MAAM,SAAS,YAAY,MAAM,UAAU,KAAK,QAAQ,WAAW;AAAA,MAC/E,OAAO,QAAQ,aAAQ,IAAI,GAAG,MAAM,UAAU,KAAK,KAAK,EAAwB;AAAA,MAChF,WAAW,WAAW,0BAA0B;AAAA,MAChD,OACC,UAAW,oBACR,EAAE,OAAO,MAAM,KAAK,KAA4B,EAAE,MAAM,IACxD;AAAA,MAEJ,gBAAgB;AAAA,MAChB,eAAe;AAAA,MACf,aAAa;AAAA,MACb,SAAS;AAAA,MAET,8BAAC,sBAAmB,MAAM,KAAK,MAAM;AAAA;AAAA,IAjBhC,KAAK;AAAA,EAkBX,CACA,GACF;AAEF,CAAC;", ++ "sourcesContent": ["import {\n\tDefaultColorStyle,\n\tSharedStyle,\n\tStyleProp,\n\tTLDefaultColorStyle,\n\tTLDefaultColorTheme,\n\tuseContainer,\n} from '@tldraw/editor'\nimport classNames from 'classnames'\nimport { ReactElement, memo, useMemo, useRef } from 'react'\nimport { StyleValuesForUi } from '../../../styles'\nimport { TLUiTranslationKey } from '../../hooks/useTranslation/TLUiTranslationKey'\nimport { useTranslation } from '../../hooks/useTranslation/useTranslation'\nimport { TldrawUiButton } from './Button/TldrawUiButton'\nimport { TldrawUiButtonIcon } from './Button/TldrawUiButtonIcon'\n\n/** @public */\nexport interface TLUiButtonPickerProps {\n\ttitle: string\n\tuiType: string\n\tstyle: StyleProp\n\tvalue: SharedStyle\n\titems: StyleValuesForUi\n\ttheme: TLDefaultColorTheme\n\tonValueChange(style: StyleProp, value: T): void\n\tonHistoryMark?(id: string): void\n}\n\n/** @public */\nexport const TldrawUiButtonPicker = memo(function TldrawUiButtonPicker(\n\tprops: TLUiButtonPickerProps\n) {\n\tconst {\n\t\tuiType,\n\t\titems,\n\t\ttitle,\n\t\tstyle,\n\t\tvalue,\n\t\t// columns = clamp(items.length, 2, 4),\n\t\tonValueChange,\n\t\tonHistoryMark,\n\t\ttheme,\n\t} = props\n\tconst container = useContainer()\n\tconst msg = useTranslation()\n\n\tconst rPointing = useRef(false)\n\tconst rPointingOriginalActiveElement = useRef(null)\n\n\tconst {\n\t\thandleButtonClick,\n\t\thandleButtonPointerDown,\n\t\thandleButtonPointerEnter,\n\t\thandleButtonPointerUp,\n\t} = useMemo(() => {\n\t\tconst handlePointerUp = () => {\n\t\t\trPointing.current = false\n\t\t\tcontainer.win.removeEventListener('pointerup', handlePointerUp)\n\n\t\t\t// This is fun little micro-optimization to make sure that the focus\n\t\t\t// is retained on a text label. That way, you can continue typing\n\t\t\t// after selecting a style.\n\t\t\tconst origActiveEl = rPointingOriginalActiveElement.current\n\t\t\tif (origActiveEl && ['TEXTAREA', 'INPUT'].includes(origActiveEl.nodeName)) {\n\t\t\t\torigActiveEl.focus()\n\t\t\t}\n\t\t\trPointingOriginalActiveElement.current = null\n\t\t}\n\n\t\tconst handleButtonClick = (e: React.PointerEvent) => {\n\t\t\tconst { id } = e.currentTarget.dataset\n\t\t\tif (value.type === 'shared' && value.value === id) return\n\n\t\t\tonHistoryMark?.('point picker item')\n\t\t\tonValueChange(style, id as T)\n\t\t}\n\n\t\tconst handleButtonPointerDown = (e: React.PointerEvent) => {\n\t\t\tconst { id } = e.currentTarget.dataset\n\n\t\t\tonHistoryMark?.('point picker item')\n\t\t\tonValueChange(style, id as T)\n\n\t\t\trPointing.current = true\n\t\t\trPointingOriginalActiveElement.current = container.ownerDocument.activeElement as HTMLElement\n\t\t\tcontainer.win.addEventListener('pointerup', handlePointerUp) // see TLD-658\n\t\t}\n\n\t\tconst handleButtonPointerEnter = (e: React.PointerEvent) => {\n\t\t\tif (!rPointing.current) return\n\n\t\t\tconst { id } = e.currentTarget.dataset\n\t\t\tonValueChange(style, id as T)\n\t\t}\n\n\t\tconst handleButtonPointerUp = (e: React.PointerEvent) => {\n\t\t\tconst { id } = e.currentTarget.dataset\n\t\t\tif (value.type === 'shared' && value.value === id) return\n\n\t\t\tonValueChange(style, id as T)\n\t\t}\n\n\t\treturn {\n\t\t\thandleButtonClick,\n\t\t\thandleButtonPointerDown,\n\t\t\thandleButtonPointerEnter,\n\t\t\thandleButtonPointerUp,\n\t\t}\n\t}, [value, onHistoryMark, onValueChange, style, container])\n\n\treturn (\n\t\t
\n\t\t\t{items.map((item) => (\n\t\t\t\t)\n\t\t\t\t\t\t\t? { color: theme[item.value as TLDefaultColorStyle].solid }\n\t\t\t\t\t\t\t: undefined\n\t\t\t\t\t}\n\t\t\t\t\tonPointerEnter={handleButtonPointerEnter}\n\t\t\t\t\tonPointerDown={handleButtonPointerDown}\n\t\t\t\t\tonPointerUp={handleButtonPointerUp}\n\t\t\t\t\tonClick={handleButtonClick}\n\t\t\t\t>\n\t\t\t\t\t\n\t\t\t\t\n\t\t\t))}\n\t\t
\n\t)\n}) as (props: TLUiButtonPickerProps) => ReactElement\n"], ++ "mappings": "AAoIK;AApIL;AAAA,EACC;AAAA,EAKA;AAAA,OACM;AACP,OAAO,gBAAgB;AACvB,SAAuB,MAAM,SAAS,cAAc;AAGpD,SAAS,sBAAsB;AAC/B,SAAS,sBAAsB;AAC/B,SAAS,0BAA0B;AAe5B,MAAM,uBAAuB,KAAK,SAASA,sBACjD,OACC;AACD,QAAM;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA;AAAA,IAEA;AAAA,IACA;AAAA,IACA;AAAA,EACD,IAAI;AACJ,QAAM,YAAY,aAAa;AAC/B,QAAM,MAAM,eAAe;AAE3B,QAAM,YAAY,OAAO,KAAK;AAC9B,QAAM,iCAAiC,OAA2B,IAAI;AAEtE,QAAM;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACD,IAAI,QAAQ,MAAM;AACjB,UAAM,kBAAkB,MAAM;AAC7B,gBAAU,UAAU;AACpB,gBAAU,IAAI,oBAAoB,aAAa,eAAe;AAK9D,YAAM,eAAe,+BAA+B;AACpD,UAAI,gBAAgB,CAAC,YAAY,OAAO,EAAE,SAAS,aAAa,QAAQ,GAAG;AAC1E,qBAAa,MAAM;AAAA,MACpB;AACA,qCAA+B,UAAU;AAAA,IAC1C;AAEA,UAAMC,qBAAoB,CAAC,MAA6C;AACvE,YAAM,EAAE,GAAG,IAAI,EAAE,cAAc;AAC/B,UAAI,MAAM,SAAS,YAAY,MAAM,UAAU,GAAI;AAEnD,sBAAgB,mBAAmB;AACnC,oBAAc,OAAO,EAAO;AAAA,IAC7B;AAEA,UAAMC,2BAA0B,CAAC,MAA6C;AAC7E,YAAM,EAAE,GAAG,IAAI,EAAE,cAAc;AAE/B,sBAAgB,mBAAmB;AACnC,oBAAc,OAAO,EAAO;AAE5B,gBAAU,UAAU;AACpB,qCAA+B,UAAU,UAAU,cAAc;AACjE,gBAAU,IAAI,iBAAiB,aAAa,eAAe;AAAA,IAC5D;AAEA,UAAMC,4BAA2B,CAAC,MAA6C;AAC9E,UAAI,CAAC,UAAU,QAAS;AAExB,YAAM,EAAE,GAAG,IAAI,EAAE,cAAc;AAC/B,oBAAc,OAAO,EAAO;AAAA,IAC7B;AAEA,UAAMC,yBAAwB,CAAC,MAA6C;AAC3E,YAAM,EAAE,GAAG,IAAI,EAAE,cAAc;AAC/B,UAAI,MAAM,SAAS,YAAY,MAAM,UAAU,GAAI;AAEnD,oBAAc,OAAO,EAAO;AAAA,IAC7B;AAEA,WAAO;AAAA,MACN,mBAAAH;AAAA,MACA,yBAAAC;AAAA,MACA,0BAAAC;AAAA,MACA,uBAAAC;AAAA,IACD;AAAA,EACD,GAAG,CAAC,OAAO,eAAe,eAAe,OAAO,SAAS,CAAC;AAE1D,SACC,oBAAC,SAAI,eAAa,SAAS,MAAM,IAAI,WAAW,WAAW,oBAAoB,GAC7E,gBAAM,IAAI,CAAC,SACX;AAAA,IAAC;AAAA;AAAA,MACA,MAAK;AAAA,MAEL,WAAS,KAAK;AAAA,MACd,eAAa,SAAS,MAAM,IAAI,KAAK,KAAK;AAAA,MAC1C,cAAY,KAAK;AAAA,MACjB,cAAY,MAAM,SAAS,YAAY,MAAM,UAAU,KAAK,QAAQ,WAAW;AAAA,MAC/E,OAAO,QAAQ,aAAQ,IAAI,GAAG,MAAM,UAAU,KAAK,KAAK,EAAwB;AAAA,MAChF,WAAW,WAAW,0BAA0B;AAAA,MAChD,OACC,UAAW,oBACR,EAAE,OAAO,MAAM,KAAK,KAA4B,EAAE,MAAM,IACxD;AAAA,MAEJ,gBAAgB;AAAA,MAChB,eAAe;AAAA,MACf,aAAa;AAAA,MACb,SAAS;AAAA,MAET,8BAAC,sBAAmB,MAAM,KAAK,MAAM;AAAA;AAAA,IAjBhC,KAAK;AAAA,EAkBX,CACA,GACF;AAEF,CAAC;", + "names": ["TldrawUiButtonPicker", "handleButtonClick", "handleButtonPointerDown", "handleButtonPointerEnter", "handleButtonPointerUp"] + } +diff --git a/node_modules/tldraw/dist-esm/lib/ui/hooks/useClipboardEvents.mjs b/node_modules/tldraw/dist-esm/lib/ui/hooks/useClipboardEvents.mjs +index fc4055e..63e1e9e 100644 +--- a/node_modules/tldraw/dist-esm/lib/ui/hooks/useClipboardEvents.mjs ++++ b/node_modules/tldraw/dist-esm/lib/ui/hooks/useClipboardEvents.mjs +@@ -4,6 +4,7 @@ import { + preventDefault, + stopEventPropagation, + uniq, ++ useContainer, + useEditor, + useValue + } from "@tldraw/editor"; +@@ -369,6 +370,7 @@ function useMenuClipboardEvents() { + }; + } + function useNativeClipboardEvents() { ++ const container = useContainer(); + const editor = useEditor(); + const trackEvent = useUiEvents(); + const appIsFocused = useValue("editor.isFocused", () => editor.getInstanceState().isFocused, [ +@@ -425,17 +427,17 @@ function useNativeClipboardEvents() { + preventDefault(e); + trackEvent("paste", { source: "kbd" }); + }; +- document.addEventListener("copy", copy); +- document.addEventListener("cut", cut); +- document.addEventListener("paste", paste); +- document.addEventListener("pointerup", pointerUpHandler); ++ container.ownerDocument.addEventListener("copy", copy); ++ container.ownerDocument.addEventListener("cut", cut); ++ container.ownerDocument.addEventListener("paste", paste); ++ container.ownerDocument.addEventListener("pointerup", pointerUpHandler); + return () => { +- document.removeEventListener("copy", copy); +- document.removeEventListener("cut", cut); +- document.removeEventListener("paste", paste); +- document.removeEventListener("pointerup", pointerUpHandler); ++ container.ownerDocument.removeEventListener("copy", copy); ++ container.ownerDocument.removeEventListener("cut", cut); ++ container.ownerDocument.removeEventListener("paste", paste); ++ container.ownerDocument.removeEventListener("pointerup", pointerUpHandler); + }; +- }, [editor, trackEvent, appIsFocused]); ++ }, [editor, trackEvent, appIsFocused, container]); + } + export { + isValidHttpURL, +diff --git a/node_modules/tldraw/dist-esm/lib/ui/hooks/useClipboardEvents.mjs.map b/node_modules/tldraw/dist-esm/lib/ui/hooks/useClipboardEvents.mjs.map +index d293110..dc9f6aa 100644 +--- a/node_modules/tldraw/dist-esm/lib/ui/hooks/useClipboardEvents.mjs.map ++++ b/node_modules/tldraw/dist-esm/lib/ui/hooks/useClipboardEvents.mjs.map +@@ -1,7 +1,7 @@ + { + "version": 3, + "sources": ["../../../../src/lib/ui/hooks/useClipboardEvents.ts"], +- "sourcesContent": ["import {\n\tEditor,\n\tFileHelpers,\n\tTLExternalContentSource,\n\tVec,\n\tVecLike,\n\tisDefined,\n\tpreventDefault,\n\tstopEventPropagation,\n\tuniq,\n\tuseEditor,\n\tuseValue,\n} from '@tldraw/editor'\nimport lz from 'lz-string'\nimport { useCallback, useEffect } from 'react'\nimport { TLUiEventSource, useUiEvents } from '../context/events'\nimport { pasteExcalidrawContent } from './clipboard/pasteExcalidrawContent'\nimport { pasteFiles } from './clipboard/pasteFiles'\nimport { pasteTldrawContent } from './clipboard/pasteTldrawContent'\nimport { pasteUrl } from './clipboard/pasteUrl'\n\n/**\n * Strip HTML tags from a string.\n * @param html - The HTML to strip.\n * @internal\n */\nfunction stripHtml(html: string) {\n\t// See \n\tconst doc = document.implementation.createHTMLDocument('')\n\tdoc.documentElement.innerHTML = html.trim()\n\treturn doc.body.textContent || doc.body.innerText || ''\n}\n\n/** @public */\nexport const isValidHttpURL = (url: string) => {\n\ttry {\n\t\tconst u = new URL(url)\n\t\treturn u.protocol === 'http:' || u.protocol === 'https:'\n\t} catch {\n\t\treturn false\n\t}\n}\n\n/** @public */\nconst getValidHttpURLList = (url: string) => {\n\tconst urls = url.split(/[\\n\\s]/)\n\tfor (const url of urls) {\n\t\ttry {\n\t\t\tconst u = new URL(url)\n\t\t\tif (!(u.protocol === 'http:' || u.protocol === 'https:')) {\n\t\t\t\treturn\n\t\t\t}\n\t\t} catch {\n\t\t\treturn\n\t\t}\n\t}\n\treturn uniq(urls)\n}\n\n/** @public */\nconst isSvgText = (text: string) => {\n\treturn /^ -1))\n\t)\n}\n\n/**\n * Whether a ClipboardItem is a file.\n * @param item - The ClipboardItem to check.\n * @internal\n */\nconst isFile = (item: ClipboardItem) => {\n\treturn item.types.find((i) => i.match(/^image\\//))\n}\n\n/**\n * Handle text pasted into the editor.\n * @param editor - The editor instance.\n * @param data - The text to paste.\n * @param point - The point at which to paste the text.\n * @internal\n */\nconst handleText = (\n\teditor: Editor,\n\tdata: string,\n\tpoint?: VecLike,\n\tsources?: TLExternalContentSource[]\n) => {\n\tconst validUrlList = getValidHttpURLList(data)\n\tif (validUrlList) {\n\t\tfor (const url of validUrlList) {\n\t\t\tpasteUrl(editor, url, point)\n\t\t}\n\t} else if (isValidHttpURL(data)) {\n\t\tpasteUrl(editor, data, point)\n\t} else if (isSvgText(data)) {\n\t\teditor.markHistoryStoppingPoint('paste')\n\t\teditor.putExternalContent({\n\t\t\ttype: 'svg-text',\n\t\t\ttext: data,\n\t\t\tpoint,\n\t\t\tsources,\n\t\t})\n\t} else {\n\t\teditor.markHistoryStoppingPoint('paste')\n\t\teditor.putExternalContent({\n\t\t\ttype: 'text',\n\t\t\ttext: data,\n\t\t\tpoint,\n\t\t\tsources,\n\t\t})\n\t}\n}\n\n/**\n * Something found on the clipboard, either through the event's clipboard data or the browser's clipboard API.\n * @internal\n */\ntype ClipboardThing =\n\t| {\n\t\t\ttype: 'file'\n\t\t\tsource: Promise\n\t }\n\t| {\n\t\t\ttype: 'blob'\n\t\t\tsource: Promise\n\t }\n\t| {\n\t\t\ttype: 'url'\n\t\t\tsource: Promise\n\t }\n\t| {\n\t\t\ttype: 'html'\n\t\t\tsource: Promise\n\t }\n\t| {\n\t\t\ttype: 'text'\n\t\t\tsource: Promise\n\t }\n\t| {\n\t\t\ttype: string\n\t\t\tsource: Promise\n\t }\n\n/**\n * Handle a paste using event clipboard data. This is the \"original\"\n * paste method that uses the clipboard data from the paste event.\n * https://developer.mozilla.org/en-US/docs/Web/API/ClipboardEvent/clipboardData\n *\n * @param editor - The editor\n * @param clipboardData - The clipboard data\n * @param point - The point to paste at\n * @internal\n */\nconst handlePasteFromEventClipboardData = async (\n\teditor: Editor,\n\tclipboardData: DataTransfer,\n\tpoint?: VecLike\n) => {\n\t// Do not paste while in any editing state\n\tif (editor.getEditingShapeId() !== null) return\n\n\tif (!clipboardData) {\n\t\tthrow Error('No clipboard data')\n\t}\n\n\tconst things: ClipboardThing[] = []\n\n\tfor (const item of Object.values(clipboardData.items)) {\n\t\tswitch (item.kind) {\n\t\t\tcase 'file': {\n\t\t\t\t// files are always blobs\n\t\t\t\tthings.push({\n\t\t\t\t\ttype: 'file',\n\t\t\t\t\tsource: new Promise((r) => r(item.getAsFile())) as Promise,\n\t\t\t\t})\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'string': {\n\t\t\t\t// strings can be text or html\n\t\t\t\tif (item.type === 'text/html') {\n\t\t\t\t\tthings.push({\n\t\t\t\t\t\ttype: 'html',\n\t\t\t\t\t\tsource: new Promise((r) => item.getAsString(r)) as Promise,\n\t\t\t\t\t})\n\t\t\t\t} else if (item.type === 'text/plain') {\n\t\t\t\t\tthings.push({\n\t\t\t\t\t\ttype: 'text',\n\t\t\t\t\t\tsource: new Promise((r) => item.getAsString(r)) as Promise,\n\t\t\t\t\t})\n\t\t\t\t} else {\n\t\t\t\t\tthings.push({ type: item.type, source: new Promise((r) => item.getAsString(r)) })\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n\n\thandleClipboardThings(editor, things, point)\n}\n\n/**\n * Handle a paste using items retrieved from the Clipboard API.\n * https://developer.mozilla.org/en-US/docs/Web/API/ClipboardItem\n *\n * @param editor - The editor\n * @param clipboardItems - The clipboard items to handle\n * @param point - The point to paste at\n * @internal\n */\nconst handlePasteFromClipboardApi = async (\n\teditor: Editor,\n\tclipboardItems: ClipboardItem[],\n\tpoint?: VecLike\n) => {\n\t// We need to populate the array of clipboard things\n\t// based on the ClipboardItems from the Clipboard API.\n\t// This is done in a different way than when using\n\t// the clipboard data from the paste event.\n\n\tconst things: ClipboardThing[] = []\n\n\tfor (const item of clipboardItems) {\n\t\tif (isFile(item)) {\n\t\t\tfor (const type of item.types) {\n\t\t\t\tif (type.match(/^image\\//)) {\n\t\t\t\t\tthings.push({ type: 'blob', source: item.getType(type) })\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (item.types.includes('text/html')) {\n\t\t\tthings.push({\n\t\t\t\ttype: 'html',\n\t\t\t\tsource: (async () => {\n\t\t\t\t\tconst blob = await item.getType('text/html')\n\t\t\t\t\treturn await FileHelpers.blobToText(blob)\n\t\t\t\t})(),\n\t\t\t})\n\t\t}\n\n\t\tif (item.types.includes('text/uri-list')) {\n\t\t\tthings.push({\n\t\t\t\ttype: 'url',\n\t\t\t\tsource: (async () => {\n\t\t\t\t\tconst blob = await item.getType('text/uri-list')\n\t\t\t\t\treturn await FileHelpers.blobToText(blob)\n\t\t\t\t})(),\n\t\t\t})\n\t\t}\n\n\t\tif (item.types.includes('text/plain')) {\n\t\t\tthings.push({\n\t\t\t\ttype: 'text',\n\t\t\t\tsource: (async () => {\n\t\t\t\t\tconst blob = await item.getType('text/plain')\n\t\t\t\t\treturn await FileHelpers.blobToText(blob)\n\t\t\t\t})(),\n\t\t\t})\n\t\t}\n\t}\n\n\treturn await handleClipboardThings(editor, things, point)\n}\n\nasync function handleClipboardThings(editor: Editor, things: ClipboardThing[], point?: VecLike) {\n\t// 1. Handle files\n\t//\n\t// We need to handle files separately because if we want them to\n\t// be placed next to each other, we need to create them all at once.\n\n\tconst files = things.filter(\n\t\t(t) => (t.type === 'file' || t.type === 'blob') && t.source !== null\n\t) as Extract[]\n\n\t// Just paste the files, nothing else\n\tif (files.length) {\n\t\tif (files.length > editor.options.maxFilesAtOnce) {\n\t\t\tthrow Error('Too many files')\n\t\t}\n\t\tconst fileBlobs = await Promise.all(files.map((t) => t.source!))\n\t\tconst urls = (fileBlobs.filter(Boolean) as (File | Blob)[]).map((blob) =>\n\t\t\tURL.createObjectURL(blob)\n\t\t)\n\t\treturn await pasteFiles(editor, urls, point)\n\t}\n\n\t// 2. Generate clipboard results for non-file things\n\t//\n\t// Getting the source from the items is async, however they must be accessed syncronously;\n\t// we can't await them in a loop. So we'll map them to promises and await them all at once,\n\t// then make decisions based on what we find.\n\n\tconst results = await Promise.all(\n\t\tthings\n\t\t\t.filter((t) => t.type !== 'file')\n\t\t\t.map(\n\t\t\t\t(t) =>\n\t\t\t\t\tnew Promise((r) => {\n\t\t\t\t\t\tconst thing = t as Exclude\n\n\t\t\t\t\t\tif (thing.type === 'file') {\n\t\t\t\t\t\t\tr({ type: 'error', data: null, reason: 'unexpected file' })\n\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tthing.source.then((text) => {\n\t\t\t\t\t\t\t// first, see if we can find tldraw content, which is JSON inside of an html comment\n\t\t\t\t\t\t\tconst tldrawHtmlComment = text.match(/
]*>(.*)<\\/div>/)?.[1]\n\n\t\t\t\t\t\t\tif (tldrawHtmlComment) {\n\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\t// If we've found tldraw content in the html string, use that as JSON\n\t\t\t\t\t\t\t\t\tconst jsonComment = lz.decompressFromBase64(tldrawHtmlComment)\n\t\t\t\t\t\t\t\t\tif (jsonComment === null) {\n\t\t\t\t\t\t\t\t\t\tr({\n\t\t\t\t\t\t\t\t\t\t\ttype: 'error',\n\t\t\t\t\t\t\t\t\t\t\tdata: jsonComment,\n\t\t\t\t\t\t\t\t\t\t\treason: `found tldraw data comment but could not parse base64`,\n\t\t\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\tconst json = JSON.parse(jsonComment)\n\t\t\t\t\t\t\t\t\t\tif (json.type !== 'application/tldraw') {\n\t\t\t\t\t\t\t\t\t\t\tr({\n\t\t\t\t\t\t\t\t\t\t\t\ttype: 'error',\n\t\t\t\t\t\t\t\t\t\t\t\tdata: json,\n\t\t\t\t\t\t\t\t\t\t\t\treason: `found tldraw data comment but JSON was of a different type: ${json.type}`,\n\t\t\t\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t\tif (typeof json.data === 'string') {\n\t\t\t\t\t\t\t\t\t\t\tr({\n\t\t\t\t\t\t\t\t\t\t\t\ttype: 'error',\n\t\t\t\t\t\t\t\t\t\t\t\tdata: json,\n\t\t\t\t\t\t\t\t\t\t\t\treason:\n\t\t\t\t\t\t\t\t\t\t\t\t\t'found tldraw json but data was a string instead of a TLClipboardModel object',\n\t\t\t\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t\tr({ type: 'tldraw', data: json.data })\n\t\t\t\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\t\t\tr({\n\t\t\t\t\t\t\t\t\t\ttype: 'error',\n\t\t\t\t\t\t\t\t\t\tdata: tldrawHtmlComment,\n\t\t\t\t\t\t\t\t\t\treason:\n\t\t\t\t\t\t\t\t\t\t\t'found tldraw json but data was a string instead of a TLClipboardModel object',\n\t\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tif (thing.type === 'html') {\n\t\t\t\t\t\t\t\t\tr({ type: 'text', data: text, subtype: 'html' })\n\t\t\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tif (thing.type === 'url') {\n\t\t\t\t\t\t\t\t\tr({ type: 'text', data: text, subtype: 'url' })\n\t\t\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t// if we have not found a tldraw comment, Otherwise, try to parse the text as JSON directly.\n\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\tconst json = JSON.parse(text)\n\t\t\t\t\t\t\t\t\tif (json.type === 'excalidraw/clipboard') {\n\t\t\t\t\t\t\t\t\t\t// If the clipboard contains content copied from excalidraw, then paste that\n\t\t\t\t\t\t\t\t\t\tr({ type: 'excalidraw', data: json })\n\t\t\t\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\tr({ type: 'text', data: text, subtype: 'json' })\n\t\t\t\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\t\t\t// If we could not parse the text as JSON, then it's just text\n\t\t\t\t\t\t\t\t\tr({ type: 'text', data: text, subtype: 'text' })\n\t\t\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tr({ type: 'error', data: text, reason: 'unhandled case' })\n\t\t\t\t\t\t})\n\t\t\t\t\t})\n\t\t\t)\n\t)\n\n\t// 3.\n\t//\n\t// Now that we know what kind of stuff we're dealing with, we can actual create some content.\n\t// There are priorities here, so order matters: we've already handled images and files, which\n\t// take first priority; then we want to handle tldraw content, then excalidraw content, then\n\t// html content, then links, and finally text content.\n\n\t// Try to paste tldraw content\n\tfor (const result of results) {\n\t\tif (result.type === 'tldraw') {\n\t\t\tpasteTldrawContent(editor, result.data, point)\n\t\t\treturn\n\t\t}\n\t}\n\n\t// Try to paste excalidraw content\n\tfor (const result of results) {\n\t\tif (result.type === 'excalidraw') {\n\t\t\tpasteExcalidrawContent(editor, result.data, point)\n\t\t\treturn\n\t\t}\n\t}\n\n\t// Try to paste html content\n\tfor (const result of results) {\n\t\tif (result.type === 'text' && result.subtype === 'html') {\n\t\t\t// try to find a link\n\t\t\tconst rootNode = new DOMParser().parseFromString(result.data, 'text/html')\n\t\t\tconst bodyNode = rootNode.querySelector('body')\n\n\t\t\t// Edge on Windows 11 home appears to paste a link as a single in\n\t\t\t// the HTML document. If we're pasting a single like tag we'll just\n\t\t\t// assume the user meant to paste the URL.\n\t\t\tconst isHtmlSingleLink =\n\t\t\t\tbodyNode &&\n\t\t\t\tArray.from(bodyNode.children).filter((el) => el.nodeType === 1).length === 1 &&\n\t\t\t\tbodyNode.firstElementChild &&\n\t\t\t\tbodyNode.firstElementChild.tagName === 'A' &&\n\t\t\t\tbodyNode.firstElementChild.hasAttribute('href') &&\n\t\t\t\tbodyNode.firstElementChild.getAttribute('href') !== ''\n\n\t\t\tif (isHtmlSingleLink) {\n\t\t\t\tconst href = bodyNode.firstElementChild.getAttribute('href')!\n\t\t\t\thandleText(editor, href, point, results)\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\t// If the html is NOT a link, and we have NO OTHER texty content, then paste the html as text\n\t\t\tif (!results.some((r) => r.type === 'text' && r.subtype !== 'html') && result.data.trim()) {\n\t\t\t\thandleText(editor, stripHtml(result.data), point, results)\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t}\n\n\t// Try to paste a link\n\tfor (const result of results) {\n\t\tif (result.type === 'text' && result.subtype === 'url') {\n\t\t\tpasteUrl(editor, result.data, point, results)\n\t\t\treturn\n\t\t}\n\t}\n\n\t// Finally, if we haven't bailed on anything yet, we can paste text content\n\tfor (const result of results) {\n\t\tif (result.type === 'text' && result.subtype === 'text' && result.data.trim()) {\n\t\t\t// The clipboard may include multiple text items, but we only want to paste the first one\n\t\t\thandleText(editor, result.data, point, results)\n\t\t\treturn\n\t\t}\n\t}\n}\n\n/**\n * When the user copies, write the contents to local storage and to the clipboard\n *\n * @param editor - The editor instance.\n * @public\n */\nconst handleNativeOrMenuCopy = async (editor: Editor) => {\n\tconst content = await editor.resolveAssetsInContent(\n\t\teditor.getContentFromCurrentPage(editor.getSelectedShapeIds())\n\t)\n\tif (!content) {\n\t\tif (navigator && navigator.clipboard) {\n\t\t\tnavigator.clipboard.writeText('')\n\t\t}\n\t\treturn\n\t}\n\n\tconst stringifiedClipboard = lz.compressToBase64(\n\t\tJSON.stringify({\n\t\t\ttype: 'application/tldraw',\n\t\t\tkind: 'content',\n\t\t\tdata: content,\n\t\t})\n\t)\n\n\tif (typeof navigator === 'undefined') {\n\t\treturn\n\t} else {\n\t\t// Extract the text from the clipboard\n\t\tconst textItems = content.shapes\n\t\t\t.map((shape) => {\n\t\t\t\tconst util = editor.getShapeUtil(shape)\n\t\t\t\treturn util.getText(shape)\n\t\t\t})\n\t\t\t.filter(isDefined)\n\n\t\tif (navigator.clipboard?.write) {\n\t\t\tconst htmlBlob = new Blob([`
${stringifiedClipboard}
`], {\n\t\t\t\ttype: 'text/html',\n\t\t\t})\n\n\t\t\tlet textContent = textItems.join(' ')\n\n\t\t\t// This is a bug in chrome android where it won't paste content if\n\t\t\t// the text/plain content is \"\" so we need to always add an empty\n\t\t\t// space \uD83E\uDD2C\n\t\t\tif (textContent === '') {\n\t\t\t\ttextContent = ' '\n\t\t\t}\n\n\t\t\tnavigator.clipboard.write([\n\t\t\t\tnew ClipboardItem({\n\t\t\t\t\t'text/html': htmlBlob,\n\t\t\t\t\t// What is this second blob used for?\n\t\t\t\t\t'text/plain': new Blob([textContent], { type: 'text/plain' }),\n\t\t\t\t}),\n\t\t\t])\n\t\t} else if (navigator.clipboard.writeText) {\n\t\t\tnavigator.clipboard.writeText(`
${stringifiedClipboard}
`)\n\t\t}\n\t}\n}\n\n/** @public */\nexport function useMenuClipboardEvents() {\n\tconst editor = useEditor()\n\tconst trackEvent = useUiEvents()\n\n\tconst copy = useCallback(\n\t\tasync function onCopy(source: TLUiEventSource) {\n\t\t\tif (editor.getSelectedShapeIds().length === 0) return\n\n\t\t\tawait handleNativeOrMenuCopy(editor)\n\t\t\ttrackEvent('copy', { source })\n\t\t},\n\t\t[editor, trackEvent]\n\t)\n\n\tconst cut = useCallback(\n\t\tasync function onCut(source: TLUiEventSource) {\n\t\t\tif (editor.getSelectedShapeIds().length === 0) return\n\n\t\t\tawait handleNativeOrMenuCopy(editor)\n\t\t\teditor.deleteShapes(editor.getSelectedShapeIds())\n\t\t\ttrackEvent('cut', { source })\n\t\t},\n\t\t[editor, trackEvent]\n\t)\n\n\tconst paste = useCallback(\n\t\tasync function onPaste(\n\t\t\tdata: DataTransfer | ClipboardItem[],\n\t\t\tsource: TLUiEventSource,\n\t\t\tpoint?: VecLike\n\t\t) {\n\t\t\t// If we're editing a shape, or we are focusing an editable input, then\n\t\t\t// we would want the user's paste interaction to go to that element or\n\t\t\t// input instead; e.g. when pasting text into a text shape's content\n\t\t\tif (editor.getEditingShapeId() !== null) return\n\n\t\t\tif (Array.isArray(data) && data[0] instanceof ClipboardItem) {\n\t\t\t\thandlePasteFromClipboardApi(editor, data, point)\n\t\t\t\ttrackEvent('paste', { source: 'menu' })\n\t\t\t} else {\n\t\t\t\t// Read it first and then recurse, kind of weird\n\t\t\t\tnavigator.clipboard.read().then((clipboardItems) => {\n\t\t\t\t\tpaste(clipboardItems, source, point)\n\t\t\t\t})\n\t\t\t}\n\t\t},\n\t\t[editor, trackEvent]\n\t)\n\n\treturn {\n\t\tcopy,\n\t\tcut,\n\t\tpaste,\n\t}\n}\n\n/** @public */\nexport function useNativeClipboardEvents() {\n\tconst editor = useEditor()\n\tconst trackEvent = useUiEvents()\n\n\tconst appIsFocused = useValue('editor.isFocused', () => editor.getInstanceState().isFocused, [\n\t\teditor,\n\t])\n\n\tuseEffect(() => {\n\t\tif (!appIsFocused) return\n\t\tconst copy = async (e: ClipboardEvent) => {\n\t\t\tif (\n\t\t\t\teditor.getSelectedShapeIds().length === 0 ||\n\t\t\t\teditor.getEditingShapeId() !== null ||\n\t\t\t\tareShortcutsDisabled(editor)\n\t\t\t) {\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tpreventDefault(e)\n\t\t\tawait handleNativeOrMenuCopy(editor)\n\t\t\ttrackEvent('copy', { source: 'kbd' })\n\t\t}\n\n\t\tasync function cut(e: ClipboardEvent) {\n\t\t\tif (\n\t\t\t\teditor.getSelectedShapeIds().length === 0 ||\n\t\t\t\teditor.getEditingShapeId() !== null ||\n\t\t\t\tareShortcutsDisabled(editor)\n\t\t\t) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tpreventDefault(e)\n\t\t\tawait handleNativeOrMenuCopy(editor)\n\t\t\teditor.deleteShapes(editor.getSelectedShapeIds())\n\t\t\ttrackEvent('cut', { source: 'kbd' })\n\t\t}\n\n\t\tlet disablingMiddleClickPaste = false\n\t\tconst pointerUpHandler = (e: PointerEvent) => {\n\t\t\tif (e.button === 1) {\n\t\t\t\t// middle mouse button\n\t\t\t\tdisablingMiddleClickPaste = true\n\t\t\t\teditor.timers.requestAnimationFrame(() => {\n\t\t\t\t\tdisablingMiddleClickPaste = false\n\t\t\t\t})\n\t\t\t}\n\t\t}\n\n\t\tconst paste = (e: ClipboardEvent) => {\n\t\t\tif (disablingMiddleClickPaste) {\n\t\t\t\tstopEventPropagation(e)\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\t// If we're editing a shape, or we are focusing an editable input, then\n\t\t\t// we would want the user's paste interaction to go to that element or\n\t\t\t// input instead; e.g. when pasting text into a text shape's content\n\t\t\tif (editor.getEditingShapeId() !== null || areShortcutsDisabled(editor)) return\n\n\t\t\t// Where should the shapes go?\n\t\t\tlet point: Vec | undefined = undefined\n\t\t\tlet pasteAtCursor = false\n\n\t\t\t// | Shiftkey | Paste at cursor mode | Paste at point? |\n\t\t\t// | N \t\t| N | N \t\t\t\t |\n\t\t\t// | Y \t\t| N | Y \t\t\t\t |\n\t\t\t// | N \t\t| Y | Y \t\t\t\t |\n\t\t\t// | Y \t\t| Y | N \t\t\t\t |\n\t\t\tif (editor.inputs.shiftKey) pasteAtCursor = true\n\t\t\tif (editor.user.getIsPasteAtCursorMode()) pasteAtCursor = !pasteAtCursor\n\t\t\tif (pasteAtCursor) point = editor.inputs.currentPagePoint\n\n\t\t\t// First try to use the clipboard data on the event\n\t\t\tif (e.clipboardData && !editor.inputs.shiftKey) {\n\t\t\t\thandlePasteFromEventClipboardData(editor, e.clipboardData, point)\n\t\t\t} else {\n\t\t\t\t// Or else use the clipboard API\n\t\t\t\tnavigator.clipboard.read().then((clipboardItems) => {\n\t\t\t\t\tif (Array.isArray(clipboardItems) && clipboardItems[0] instanceof ClipboardItem) {\n\t\t\t\t\t\thandlePasteFromClipboardApi(editor, clipboardItems, point)\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t}\n\n\t\t\tpreventDefault(e)\n\t\t\ttrackEvent('paste', { source: 'kbd' })\n\t\t}\n\n\t\tdocument.addEventListener('copy', copy)\n\t\tdocument.addEventListener('cut', cut)\n\t\tdocument.addEventListener('paste', paste)\n\t\tdocument.addEventListener('pointerup', pointerUpHandler)\n\n\t\treturn () => {\n\t\t\tdocument.removeEventListener('copy', copy)\n\t\t\tdocument.removeEventListener('cut', cut)\n\t\t\tdocument.removeEventListener('paste', paste)\n\t\t\tdocument.removeEventListener('pointerup', pointerUpHandler)\n\t\t}\n\t}, [editor, trackEvent, appIsFocused])\n}\n"], +- "mappings": "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", ++ "sourcesContent": ["import {\n\tEditor,\n\tFileHelpers,\n\tTLExternalContentSource,\n\tVec,\n\tVecLike,\n\tisDefined,\n\tpreventDefault,\n\tstopEventPropagation,\n\tuniq,\n\tuseContainer,\n\tuseEditor,\n\tuseValue,\n} from '@tldraw/editor'\nimport lz from 'lz-string'\nimport { useCallback, useEffect } from 'react'\nimport { TLUiEventSource, useUiEvents } from '../context/events'\nimport { pasteExcalidrawContent } from './clipboard/pasteExcalidrawContent'\nimport { pasteFiles } from './clipboard/pasteFiles'\nimport { pasteTldrawContent } from './clipboard/pasteTldrawContent'\nimport { pasteUrl } from './clipboard/pasteUrl'\n\n/**\n * Strip HTML tags from a string.\n * @param html - The HTML to strip.\n * @internal\n */\nfunction stripHtml(html: string) {\n\t// See \n\tconst doc = document.implementation.createHTMLDocument('')\n\tdoc.documentElement.innerHTML = html.trim()\n\treturn doc.body.textContent || doc.body.innerText || ''\n}\n\n/** @public */\nexport const isValidHttpURL = (url: string) => {\n\ttry {\n\t\tconst u = new URL(url)\n\t\treturn u.protocol === 'http:' || u.protocol === 'https:'\n\t} catch {\n\t\treturn false\n\t}\n}\n\n/** @public */\nconst getValidHttpURLList = (url: string) => {\n\tconst urls = url.split(/[\\n\\s]/)\n\tfor (const url of urls) {\n\t\ttry {\n\t\t\tconst u = new URL(url)\n\t\t\tif (!(u.protocol === 'http:' || u.protocol === 'https:')) {\n\t\t\t\treturn\n\t\t\t}\n\t\t} catch {\n\t\t\treturn\n\t\t}\n\t}\n\treturn uniq(urls)\n}\n\n/** @public */\nconst isSvgText = (text: string) => {\n\treturn /^ -1))\n\t)\n}\n\n/**\n * Whether a ClipboardItem is a file.\n * @param item - The ClipboardItem to check.\n * @internal\n */\nconst isFile = (item: ClipboardItem) => {\n\treturn item.types.find((i) => i.match(/^image\\//))\n}\n\n/**\n * Handle text pasted into the editor.\n * @param editor - The editor instance.\n * @param data - The text to paste.\n * @param point - The point at which to paste the text.\n * @internal\n */\nconst handleText = (\n\teditor: Editor,\n\tdata: string,\n\tpoint?: VecLike,\n\tsources?: TLExternalContentSource[]\n) => {\n\tconst validUrlList = getValidHttpURLList(data)\n\tif (validUrlList) {\n\t\tfor (const url of validUrlList) {\n\t\t\tpasteUrl(editor, url, point)\n\t\t}\n\t} else if (isValidHttpURL(data)) {\n\t\tpasteUrl(editor, data, point)\n\t} else if (isSvgText(data)) {\n\t\teditor.markHistoryStoppingPoint('paste')\n\t\teditor.putExternalContent({\n\t\t\ttype: 'svg-text',\n\t\t\ttext: data,\n\t\t\tpoint,\n\t\t\tsources,\n\t\t})\n\t} else {\n\t\teditor.markHistoryStoppingPoint('paste')\n\t\teditor.putExternalContent({\n\t\t\ttype: 'text',\n\t\t\ttext: data,\n\t\t\tpoint,\n\t\t\tsources,\n\t\t})\n\t}\n}\n\n/**\n * Something found on the clipboard, either through the event's clipboard data or the browser's clipboard API.\n * @internal\n */\ntype ClipboardThing =\n\t| {\n\t\t\ttype: 'file'\n\t\t\tsource: Promise\n\t }\n\t| {\n\t\t\ttype: 'blob'\n\t\t\tsource: Promise\n\t }\n\t| {\n\t\t\ttype: 'url'\n\t\t\tsource: Promise\n\t }\n\t| {\n\t\t\ttype: 'html'\n\t\t\tsource: Promise\n\t }\n\t| {\n\t\t\ttype: 'text'\n\t\t\tsource: Promise\n\t }\n\t| {\n\t\t\ttype: string\n\t\t\tsource: Promise\n\t }\n\n/**\n * Handle a paste using event clipboard data. This is the \"original\"\n * paste method that uses the clipboard data from the paste event.\n * https://developer.mozilla.org/en-US/docs/Web/API/ClipboardEvent/clipboardData\n *\n * @param editor - The editor\n * @param clipboardData - The clipboard data\n * @param point - The point to paste at\n * @internal\n */\nconst handlePasteFromEventClipboardData = async (\n\teditor: Editor,\n\tclipboardData: DataTransfer,\n\tpoint?: VecLike\n) => {\n\t// Do not paste while in any editing state\n\tif (editor.getEditingShapeId() !== null) return\n\n\tif (!clipboardData) {\n\t\tthrow Error('No clipboard data')\n\t}\n\n\tconst things: ClipboardThing[] = []\n\n\tfor (const item of Object.values(clipboardData.items)) {\n\t\tswitch (item.kind) {\n\t\t\tcase 'file': {\n\t\t\t\t// files are always blobs\n\t\t\t\tthings.push({\n\t\t\t\t\ttype: 'file',\n\t\t\t\t\tsource: new Promise((r) => r(item.getAsFile())) as Promise,\n\t\t\t\t})\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'string': {\n\t\t\t\t// strings can be text or html\n\t\t\t\tif (item.type === 'text/html') {\n\t\t\t\t\tthings.push({\n\t\t\t\t\t\ttype: 'html',\n\t\t\t\t\t\tsource: new Promise((r) => item.getAsString(r)) as Promise,\n\t\t\t\t\t})\n\t\t\t\t} else if (item.type === 'text/plain') {\n\t\t\t\t\tthings.push({\n\t\t\t\t\t\ttype: 'text',\n\t\t\t\t\t\tsource: new Promise((r) => item.getAsString(r)) as Promise,\n\t\t\t\t\t})\n\t\t\t\t} else {\n\t\t\t\t\tthings.push({ type: item.type, source: new Promise((r) => item.getAsString(r)) })\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n\n\thandleClipboardThings(editor, things, point)\n}\n\n/**\n * Handle a paste using items retrieved from the Clipboard API.\n * https://developer.mozilla.org/en-US/docs/Web/API/ClipboardItem\n *\n * @param editor - The editor\n * @param clipboardItems - The clipboard items to handle\n * @param point - The point to paste at\n * @internal\n */\nconst handlePasteFromClipboardApi = async (\n\teditor: Editor,\n\tclipboardItems: ClipboardItem[],\n\tpoint?: VecLike\n) => {\n\t// We need to populate the array of clipboard things\n\t// based on the ClipboardItems from the Clipboard API.\n\t// This is done in a different way than when using\n\t// the clipboard data from the paste event.\n\n\tconst things: ClipboardThing[] = []\n\n\tfor (const item of clipboardItems) {\n\t\tif (isFile(item)) {\n\t\t\tfor (const type of item.types) {\n\t\t\t\tif (type.match(/^image\\//)) {\n\t\t\t\t\tthings.push({ type: 'blob', source: item.getType(type) })\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (item.types.includes('text/html')) {\n\t\t\tthings.push({\n\t\t\t\ttype: 'html',\n\t\t\t\tsource: (async () => {\n\t\t\t\t\tconst blob = await item.getType('text/html')\n\t\t\t\t\treturn await FileHelpers.blobToText(blob)\n\t\t\t\t})(),\n\t\t\t})\n\t\t}\n\n\t\tif (item.types.includes('text/uri-list')) {\n\t\t\tthings.push({\n\t\t\t\ttype: 'url',\n\t\t\t\tsource: (async () => {\n\t\t\t\t\tconst blob = await item.getType('text/uri-list')\n\t\t\t\t\treturn await FileHelpers.blobToText(blob)\n\t\t\t\t})(),\n\t\t\t})\n\t\t}\n\n\t\tif (item.types.includes('text/plain')) {\n\t\t\tthings.push({\n\t\t\t\ttype: 'text',\n\t\t\t\tsource: (async () => {\n\t\t\t\t\tconst blob = await item.getType('text/plain')\n\t\t\t\t\treturn await FileHelpers.blobToText(blob)\n\t\t\t\t})(),\n\t\t\t})\n\t\t}\n\t}\n\n\treturn await handleClipboardThings(editor, things, point)\n}\n\nasync function handleClipboardThings(editor: Editor, things: ClipboardThing[], point?: VecLike) {\n\t// 1. Handle files\n\t//\n\t// We need to handle files separately because if we want them to\n\t// be placed next to each other, we need to create them all at once.\n\n\tconst files = things.filter(\n\t\t(t) => (t.type === 'file' || t.type === 'blob') && t.source !== null\n\t) as Extract[]\n\n\t// Just paste the files, nothing else\n\tif (files.length) {\n\t\tif (files.length > editor.options.maxFilesAtOnce) {\n\t\t\tthrow Error('Too many files')\n\t\t}\n\t\tconst fileBlobs = await Promise.all(files.map((t) => t.source!))\n\t\tconst urls = (fileBlobs.filter(Boolean) as (File | Blob)[]).map((blob) =>\n\t\t\tURL.createObjectURL(blob)\n\t\t)\n\t\treturn await pasteFiles(editor, urls, point)\n\t}\n\n\t// 2. Generate clipboard results for non-file things\n\t//\n\t// Getting the source from the items is async, however they must be accessed syncronously;\n\t// we can't await them in a loop. So we'll map them to promises and await them all at once,\n\t// then make decisions based on what we find.\n\n\tconst results = await Promise.all(\n\t\tthings\n\t\t\t.filter((t) => t.type !== 'file')\n\t\t\t.map(\n\t\t\t\t(t) =>\n\t\t\t\t\tnew Promise((r) => {\n\t\t\t\t\t\tconst thing = t as Exclude\n\n\t\t\t\t\t\tif (thing.type === 'file') {\n\t\t\t\t\t\t\tr({ type: 'error', data: null, reason: 'unexpected file' })\n\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tthing.source.then((text) => {\n\t\t\t\t\t\t\t// first, see if we can find tldraw content, which is JSON inside of an html comment\n\t\t\t\t\t\t\tconst tldrawHtmlComment = text.match(/
]*>(.*)<\\/div>/)?.[1]\n\n\t\t\t\t\t\t\tif (tldrawHtmlComment) {\n\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\t// If we've found tldraw content in the html string, use that as JSON\n\t\t\t\t\t\t\t\t\tconst jsonComment = lz.decompressFromBase64(tldrawHtmlComment)\n\t\t\t\t\t\t\t\t\tif (jsonComment === null) {\n\t\t\t\t\t\t\t\t\t\tr({\n\t\t\t\t\t\t\t\t\t\t\ttype: 'error',\n\t\t\t\t\t\t\t\t\t\t\tdata: jsonComment,\n\t\t\t\t\t\t\t\t\t\t\treason: `found tldraw data comment but could not parse base64`,\n\t\t\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\tconst json = JSON.parse(jsonComment)\n\t\t\t\t\t\t\t\t\t\tif (json.type !== 'application/tldraw') {\n\t\t\t\t\t\t\t\t\t\t\tr({\n\t\t\t\t\t\t\t\t\t\t\t\ttype: 'error',\n\t\t\t\t\t\t\t\t\t\t\t\tdata: json,\n\t\t\t\t\t\t\t\t\t\t\t\treason: `found tldraw data comment but JSON was of a different type: ${json.type}`,\n\t\t\t\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t\tif (typeof json.data === 'string') {\n\t\t\t\t\t\t\t\t\t\t\tr({\n\t\t\t\t\t\t\t\t\t\t\t\ttype: 'error',\n\t\t\t\t\t\t\t\t\t\t\t\tdata: json,\n\t\t\t\t\t\t\t\t\t\t\t\treason:\n\t\t\t\t\t\t\t\t\t\t\t\t\t'found tldraw json but data was a string instead of a TLClipboardModel object',\n\t\t\t\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t\tr({ type: 'tldraw', data: json.data })\n\t\t\t\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\t\t\tr({\n\t\t\t\t\t\t\t\t\t\ttype: 'error',\n\t\t\t\t\t\t\t\t\t\tdata: tldrawHtmlComment,\n\t\t\t\t\t\t\t\t\t\treason:\n\t\t\t\t\t\t\t\t\t\t\t'found tldraw json but data was a string instead of a TLClipboardModel object',\n\t\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tif (thing.type === 'html') {\n\t\t\t\t\t\t\t\t\tr({ type: 'text', data: text, subtype: 'html' })\n\t\t\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tif (thing.type === 'url') {\n\t\t\t\t\t\t\t\t\tr({ type: 'text', data: text, subtype: 'url' })\n\t\t\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t// if we have not found a tldraw comment, Otherwise, try to parse the text as JSON directly.\n\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\tconst json = JSON.parse(text)\n\t\t\t\t\t\t\t\t\tif (json.type === 'excalidraw/clipboard') {\n\t\t\t\t\t\t\t\t\t\t// If the clipboard contains content copied from excalidraw, then paste that\n\t\t\t\t\t\t\t\t\t\tr({ type: 'excalidraw', data: json })\n\t\t\t\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\tr({ type: 'text', data: text, subtype: 'json' })\n\t\t\t\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\t\t\t// If we could not parse the text as JSON, then it's just text\n\t\t\t\t\t\t\t\t\tr({ type: 'text', data: text, subtype: 'text' })\n\t\t\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tr({ type: 'error', data: text, reason: 'unhandled case' })\n\t\t\t\t\t\t})\n\t\t\t\t\t})\n\t\t\t)\n\t)\n\n\t// 3.\n\t//\n\t// Now that we know what kind of stuff we're dealing with, we can actual create some content.\n\t// There are priorities here, so order matters: we've already handled images and files, which\n\t// take first priority; then we want to handle tldraw content, then excalidraw content, then\n\t// html content, then links, and finally text content.\n\n\t// Try to paste tldraw content\n\tfor (const result of results) {\n\t\tif (result.type === 'tldraw') {\n\t\t\tpasteTldrawContent(editor, result.data, point)\n\t\t\treturn\n\t\t}\n\t}\n\n\t// Try to paste excalidraw content\n\tfor (const result of results) {\n\t\tif (result.type === 'excalidraw') {\n\t\t\tpasteExcalidrawContent(editor, result.data, point)\n\t\t\treturn\n\t\t}\n\t}\n\n\t// Try to paste html content\n\tfor (const result of results) {\n\t\tif (result.type === 'text' && result.subtype === 'html') {\n\t\t\t// try to find a link\n\t\t\tconst rootNode = new DOMParser().parseFromString(result.data, 'text/html')\n\t\t\tconst bodyNode = rootNode.querySelector('body')\n\n\t\t\t// Edge on Windows 11 home appears to paste a link as a single in\n\t\t\t// the HTML document. If we're pasting a single like tag we'll just\n\t\t\t// assume the user meant to paste the URL.\n\t\t\tconst isHtmlSingleLink =\n\t\t\t\tbodyNode &&\n\t\t\t\tArray.from(bodyNode.children).filter((el) => el.nodeType === 1).length === 1 &&\n\t\t\t\tbodyNode.firstElementChild &&\n\t\t\t\tbodyNode.firstElementChild.tagName === 'A' &&\n\t\t\t\tbodyNode.firstElementChild.hasAttribute('href') &&\n\t\t\t\tbodyNode.firstElementChild.getAttribute('href') !== ''\n\n\t\t\tif (isHtmlSingleLink) {\n\t\t\t\tconst href = bodyNode.firstElementChild.getAttribute('href')!\n\t\t\t\thandleText(editor, href, point, results)\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\t// If the html is NOT a link, and we have NO OTHER texty content, then paste the html as text\n\t\t\tif (!results.some((r) => r.type === 'text' && r.subtype !== 'html') && result.data.trim()) {\n\t\t\t\thandleText(editor, stripHtml(result.data), point, results)\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t}\n\n\t// Try to paste a link\n\tfor (const result of results) {\n\t\tif (result.type === 'text' && result.subtype === 'url') {\n\t\t\tpasteUrl(editor, result.data, point, results)\n\t\t\treturn\n\t\t}\n\t}\n\n\t// Finally, if we haven't bailed on anything yet, we can paste text content\n\tfor (const result of results) {\n\t\tif (result.type === 'text' && result.subtype === 'text' && result.data.trim()) {\n\t\t\t// The clipboard may include multiple text items, but we only want to paste the first one\n\t\t\thandleText(editor, result.data, point, results)\n\t\t\treturn\n\t\t}\n\t}\n}\n\n/**\n * When the user copies, write the contents to local storage and to the clipboard\n *\n * @param editor - The editor instance.\n * @public\n */\nconst handleNativeOrMenuCopy = async (editor: Editor) => {\n\tconst content = await editor.resolveAssetsInContent(\n\t\teditor.getContentFromCurrentPage(editor.getSelectedShapeIds())\n\t)\n\tif (!content) {\n\t\tif (navigator && navigator.clipboard) {\n\t\t\tnavigator.clipboard.writeText('')\n\t\t}\n\t\treturn\n\t}\n\n\tconst stringifiedClipboard = lz.compressToBase64(\n\t\tJSON.stringify({\n\t\t\ttype: 'application/tldraw',\n\t\t\tkind: 'content',\n\t\t\tdata: content,\n\t\t})\n\t)\n\n\tif (typeof navigator === 'undefined') {\n\t\treturn\n\t} else {\n\t\t// Extract the text from the clipboard\n\t\tconst textItems = content.shapes\n\t\t\t.map((shape) => {\n\t\t\t\tconst util = editor.getShapeUtil(shape)\n\t\t\t\treturn util.getText(shape)\n\t\t\t})\n\t\t\t.filter(isDefined)\n\n\t\tif (navigator.clipboard?.write) {\n\t\t\tconst htmlBlob = new Blob([`
${stringifiedClipboard}
`], {\n\t\t\t\ttype: 'text/html',\n\t\t\t})\n\n\t\t\tlet textContent = textItems.join(' ')\n\n\t\t\t// This is a bug in chrome android where it won't paste content if\n\t\t\t// the text/plain content is \"\" so we need to always add an empty\n\t\t\t// space \uD83E\uDD2C\n\t\t\tif (textContent === '') {\n\t\t\t\ttextContent = ' '\n\t\t\t}\n\n\t\t\tnavigator.clipboard.write([\n\t\t\t\tnew ClipboardItem({\n\t\t\t\t\t'text/html': htmlBlob,\n\t\t\t\t\t// What is this second blob used for?\n\t\t\t\t\t'text/plain': new Blob([textContent], { type: 'text/plain' }),\n\t\t\t\t}),\n\t\t\t])\n\t\t} else if (navigator.clipboard.writeText) {\n\t\t\tnavigator.clipboard.writeText(`
${stringifiedClipboard}
`)\n\t\t}\n\t}\n}\n\n/** @public */\nexport function useMenuClipboardEvents() {\n\tconst editor = useEditor()\n\tconst trackEvent = useUiEvents()\n\n\tconst copy = useCallback(\n\t\tasync function onCopy(source: TLUiEventSource) {\n\t\t\tif (editor.getSelectedShapeIds().length === 0) return\n\n\t\t\tawait handleNativeOrMenuCopy(editor)\n\t\t\ttrackEvent('copy', { source })\n\t\t},\n\t\t[editor, trackEvent]\n\t)\n\n\tconst cut = useCallback(\n\t\tasync function onCut(source: TLUiEventSource) {\n\t\t\tif (editor.getSelectedShapeIds().length === 0) return\n\n\t\t\tawait handleNativeOrMenuCopy(editor)\n\t\t\teditor.deleteShapes(editor.getSelectedShapeIds())\n\t\t\ttrackEvent('cut', { source })\n\t\t},\n\t\t[editor, trackEvent]\n\t)\n\n\tconst paste = useCallback(\n\t\tasync function onPaste(\n\t\t\tdata: DataTransfer | ClipboardItem[],\n\t\t\tsource: TLUiEventSource,\n\t\t\tpoint?: VecLike\n\t\t) {\n\t\t\t// If we're editing a shape, or we are focusing an editable input, then\n\t\t\t// we would want the user's paste interaction to go to that element or\n\t\t\t// input instead; e.g. when pasting text into a text shape's content\n\t\t\tif (editor.getEditingShapeId() !== null) return\n\n\t\t\tif (Array.isArray(data) && data[0] instanceof ClipboardItem) {\n\t\t\t\thandlePasteFromClipboardApi(editor, data, point)\n\t\t\t\ttrackEvent('paste', { source: 'menu' })\n\t\t\t} else {\n\t\t\t\t// Read it first and then recurse, kind of weird\n\t\t\t\tnavigator.clipboard.read().then((clipboardItems) => {\n\t\t\t\t\tpaste(clipboardItems, source, point)\n\t\t\t\t})\n\t\t\t}\n\t\t},\n\t\t[editor, trackEvent]\n\t)\n\n\treturn {\n\t\tcopy,\n\t\tcut,\n\t\tpaste,\n\t}\n}\n\n/** @public */\nexport function useNativeClipboardEvents() {\n\tconst container = useContainer()\n\tconst editor = useEditor()\n\tconst trackEvent = useUiEvents()\n\n\tconst appIsFocused = useValue('editor.isFocused', () => editor.getInstanceState().isFocused, [\n\t\teditor,\n\t])\n\n\tuseEffect(() => {\n\t\tif (!appIsFocused) return\n\t\tconst copy = async (e: ClipboardEvent) => {\n\t\t\tif (\n\t\t\t\teditor.getSelectedShapeIds().length === 0 ||\n\t\t\t\teditor.getEditingShapeId() !== null ||\n\t\t\t\tareShortcutsDisabled(editor)\n\t\t\t) {\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tpreventDefault(e)\n\t\t\tawait handleNativeOrMenuCopy(editor)\n\t\t\ttrackEvent('copy', { source: 'kbd' })\n\t\t}\n\n\t\tasync function cut(e: ClipboardEvent) {\n\t\t\tif (\n\t\t\t\teditor.getSelectedShapeIds().length === 0 ||\n\t\t\t\teditor.getEditingShapeId() !== null ||\n\t\t\t\tareShortcutsDisabled(editor)\n\t\t\t) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tpreventDefault(e)\n\t\t\tawait handleNativeOrMenuCopy(editor)\n\t\t\teditor.deleteShapes(editor.getSelectedShapeIds())\n\t\t\ttrackEvent('cut', { source: 'kbd' })\n\t\t}\n\n\t\tlet disablingMiddleClickPaste = false\n\t\tconst pointerUpHandler = (e: PointerEvent) => {\n\t\t\tif (e.button === 1) {\n\t\t\t\t// middle mouse button\n\t\t\t\tdisablingMiddleClickPaste = true\n\t\t\t\teditor.timers.requestAnimationFrame(() => {\n\t\t\t\t\tdisablingMiddleClickPaste = false\n\t\t\t\t})\n\t\t\t}\n\t\t}\n\n\t\tconst paste = (e: ClipboardEvent) => {\n\t\t\tif (disablingMiddleClickPaste) {\n\t\t\t\tstopEventPropagation(e)\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\t// If we're editing a shape, or we are focusing an editable input, then\n\t\t\t// we would want the user's paste interaction to go to that element or\n\t\t\t// input instead; e.g. when pasting text into a text shape's content\n\t\t\tif (editor.getEditingShapeId() !== null || areShortcutsDisabled(editor)) return\n\n\t\t\t// Where should the shapes go?\n\t\t\tlet point: Vec | undefined = undefined\n\t\t\tlet pasteAtCursor = false\n\n\t\t\t// | Shiftkey | Paste at cursor mode | Paste at point? |\n\t\t\t// | N \t\t| N | N \t\t\t\t |\n\t\t\t// | Y \t\t| N | Y \t\t\t\t |\n\t\t\t// | N \t\t| Y | Y \t\t\t\t |\n\t\t\t// | Y \t\t| Y | N \t\t\t\t |\n\t\t\tif (editor.inputs.shiftKey) pasteAtCursor = true\n\t\t\tif (editor.user.getIsPasteAtCursorMode()) pasteAtCursor = !pasteAtCursor\n\t\t\tif (pasteAtCursor) point = editor.inputs.currentPagePoint\n\n\t\t\t// First try to use the clipboard data on the event\n\t\t\tif (e.clipboardData && !editor.inputs.shiftKey) {\n\t\t\t\thandlePasteFromEventClipboardData(editor, e.clipboardData, point)\n\t\t\t} else {\n\t\t\t\t// Or else use the clipboard API\n\t\t\t\tnavigator.clipboard.read().then((clipboardItems) => {\n\t\t\t\t\tif (Array.isArray(clipboardItems) && clipboardItems[0] instanceof ClipboardItem) {\n\t\t\t\t\t\thandlePasteFromClipboardApi(editor, clipboardItems, point)\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t}\n\n\t\t\tpreventDefault(e)\n\t\t\ttrackEvent('paste', { source: 'kbd' })\n\t\t}\n\n\t\tcontainer.ownerDocument.addEventListener('copy', copy)\n\t\tcontainer.ownerDocument.addEventListener('cut', cut)\n\t\tcontainer.ownerDocument.addEventListener('paste', paste)\n\t\tcontainer.ownerDocument.addEventListener('pointerup', pointerUpHandler)\n\n\t\treturn () => {\n\t\t\tcontainer.ownerDocument.removeEventListener('copy', copy)\n\t\t\tcontainer.ownerDocument.removeEventListener('cut', cut)\n\t\t\tcontainer.ownerDocument.removeEventListener('paste', paste)\n\t\t\tcontainer.ownerDocument.removeEventListener('pointerup', pointerUpHandler)\n\t\t}\n\t}, [editor, trackEvent, appIsFocused, container])\n}\n"], ++ "mappings": "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", + "names": ["url"] + } +diff --git a/node_modules/tldraw/dist-esm/lib/ui/hooks/useKeyboardShortcuts.mjs b/node_modules/tldraw/dist-esm/lib/ui/hooks/useKeyboardShortcuts.mjs +index e4565d1..eed1021 100644 +--- a/node_modules/tldraw/dist-esm/lib/ui/hooks/useKeyboardShortcuts.mjs ++++ b/node_modules/tldraw/dist-esm/lib/ui/hooks/useKeyboardShortcuts.mjs +@@ -1,6 +1,7 @@ + import { + isAccelKey, + preventDefault, ++ useContainer, + useEditor, + useValue + } from "@tldraw/editor"; +@@ -18,6 +19,7 @@ const SKIP_KBDS = [ + "asset" + ]; + function useKeyboardShortcuts() { ++ const container = useContainer(); + const editor = useEditor(); + const isReadonlyMode = useReadonly(); + const actions = useActions(); +@@ -27,13 +29,17 @@ function useKeyboardShortcuts() { + if (!isFocused) return; + const disposables = new Array(); + const hot = (keys, callback) => { +- hotkeys(keys, { element: document.body }, callback); ++ hotkeys(keys, { element: container.ownerDocument.body }, callback); + disposables.push(() => { + hotkeys.unbind(keys, callback); + }); + }; + const hotUp = (keys, callback) => { +- hotkeys(keys, { element: document.body, keyup: true, keydown: false }, callback); ++ hotkeys( ++ keys, ++ { element: container.ownerDocument.body, keyup: true, keydown: false }, ++ callback ++ ); + disposables.push(() => { + hotkeys.unbind(keys, callback); + }); +@@ -107,7 +113,7 @@ function useKeyboardShortcuts() { + return () => { + disposables.forEach((d) => d()); + }; +- }, [actions, tools, isReadonlyMode, editor, isFocused]); ++ }, [actions, tools, isReadonlyMode, editor, container, isFocused]); + } + function getHotkeysStringFromKbd(kbd) { + return getKeys(kbd).map((kbd2) => { +diff --git a/node_modules/tldraw/dist-esm/lib/ui/hooks/useKeyboardShortcuts.mjs.map b/node_modules/tldraw/dist-esm/lib/ui/hooks/useKeyboardShortcuts.mjs.map +index 515a5cc..b30ea76 100644 +--- a/node_modules/tldraw/dist-esm/lib/ui/hooks/useKeyboardShortcuts.mjs.map ++++ b/node_modules/tldraw/dist-esm/lib/ui/hooks/useKeyboardShortcuts.mjs.map +@@ -1,7 +1,7 @@ + { + "version": 3, + "sources": ["../../../../src/lib/ui/hooks/useKeyboardShortcuts.ts"], +- "sourcesContent": ["import {\n\tEditor,\n\tTLPointerEventInfo,\n\tisAccelKey,\n\tpreventDefault,\n\tuseEditor,\n\tuseValue,\n} from '@tldraw/editor'\nimport hotkeys from 'hotkeys-js'\nimport { useEffect } from 'react'\nimport { useActions } from '../context/actions'\nimport { useReadonly } from './useReadonly'\nimport { useTools } from './useTools'\n\nconst SKIP_KBDS = [\n\t// we set these in useNativeClipboardEvents instead\n\t'copy',\n\t'cut',\n\t'paste',\n\t// There's also an upload asset action, so we don't want to set the kbd twice\n\t'asset',\n]\n\n/** @public */\nexport function useKeyboardShortcuts() {\n\tconst editor = useEditor()\n\n\tconst isReadonlyMode = useReadonly()\n\tconst actions = useActions()\n\tconst tools = useTools()\n\tconst isFocused = useValue('is focused', () => editor.getInstanceState().isFocused, [editor])\n\tuseEffect(() => {\n\t\tif (!isFocused) return\n\n\t\tconst disposables = new Array<() => void>()\n\n\t\tconst hot = (keys: string, callback: (event: KeyboardEvent) => void) => {\n\t\t\thotkeys(keys, { element: document.body }, callback)\n\t\t\tdisposables.push(() => {\n\t\t\t\thotkeys.unbind(keys, callback)\n\t\t\t})\n\t\t}\n\n\t\tconst hotUp = (keys: string, callback: (event: KeyboardEvent) => void) => {\n\t\t\thotkeys(keys, { element: document.body, keyup: true, keydown: false }, callback)\n\t\t\tdisposables.push(() => {\n\t\t\t\thotkeys.unbind(keys, callback)\n\t\t\t})\n\t\t}\n\n\t\t// Add hotkeys for actions and tools.\n\t\t// Except those that in SKIP_KBDS!\n\t\tfor (const action of Object.values(actions)) {\n\t\t\tif (!action.kbd) continue\n\t\t\tif (isReadonlyMode && !action.readonlyOk) continue\n\t\t\tif (SKIP_KBDS.includes(action.id)) continue\n\n\t\t\thot(getHotkeysStringFromKbd(action.kbd), (event) => {\n\t\t\t\tif (areShortcutsDisabled(editor)) return\n\t\t\t\tpreventDefault(event)\n\t\t\t\taction.onSelect('kbd')\n\t\t\t})\n\t\t}\n\n\t\tfor (const tool of Object.values(tools)) {\n\t\t\tif (!tool.kbd || (!tool.readonlyOk && editor.getIsReadonly())) {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tif (SKIP_KBDS.includes(tool.id)) continue\n\n\t\t\thot(getHotkeysStringFromKbd(tool.kbd), (event) => {\n\t\t\t\tif (areShortcutsDisabled(editor)) return\n\t\t\t\tpreventDefault(event)\n\t\t\t\ttool.onSelect('kbd')\n\t\t\t})\n\t\t}\n\n\t\thot(',', (e) => {\n\t\t\t// Skip if shortcuts are disabled\n\t\t\tif (areShortcutsDisabled(editor)) return\n\n\t\t\t// Don't press again if already pressed\n\t\t\tif (editor.inputs.keys.has('Comma')) return\n\n\t\t\tpreventDefault(e) // prevent whatever would normally happen\n\t\t\teditor.focus() // Focus if not already focused\n\n\t\t\teditor.inputs.keys.add('Comma')\n\n\t\t\tconst { x, y, z } = editor.inputs.currentPagePoint\n\t\t\tconst screenpoints = editor.pageToScreen({ x, y })\n\n\t\t\tconst info: TLPointerEventInfo = {\n\t\t\t\ttype: 'pointer',\n\t\t\t\tname: 'pointer_down',\n\t\t\t\tpoint: { x: screenpoints.x, y: screenpoints.y, z },\n\t\t\t\tshiftKey: e.shiftKey,\n\t\t\t\taltKey: e.altKey,\n\t\t\t\tctrlKey: e.metaKey || e.ctrlKey,\n\t\t\t\tmetaKey: e.metaKey,\n\t\t\t\taccelKey: isAccelKey(e),\n\t\t\t\tpointerId: 0,\n\t\t\t\tbutton: 0,\n\t\t\t\tisPen: editor.getInstanceState().isPenMode,\n\t\t\t\ttarget: 'canvas',\n\t\t\t}\n\n\t\t\teditor.dispatch(info)\n\t\t})\n\n\t\thotUp(',', (e) => {\n\t\t\tif (areShortcutsDisabled(editor)) return\n\t\t\tif (!editor.inputs.keys.has('Comma')) return\n\n\t\t\teditor.inputs.keys.delete('Comma')\n\n\t\t\tconst { x, y, z } = editor.inputs.currentScreenPoint\n\t\t\tconst info: TLPointerEventInfo = {\n\t\t\t\ttype: 'pointer',\n\t\t\t\tname: 'pointer_up',\n\t\t\t\tpoint: { x, y, z },\n\t\t\t\tshiftKey: e.shiftKey,\n\t\t\t\taltKey: e.altKey,\n\t\t\t\tctrlKey: e.metaKey || e.ctrlKey,\n\t\t\t\tmetaKey: e.metaKey,\n\t\t\t\taccelKey: isAccelKey(e),\n\t\t\t\tpointerId: 0,\n\t\t\t\tbutton: 0,\n\t\t\t\tisPen: editor.getInstanceState().isPenMode,\n\t\t\t\ttarget: 'canvas',\n\t\t\t}\n\n\t\t\teditor.dispatch(info)\n\t\t})\n\n\t\treturn () => {\n\t\t\tdisposables.forEach((d) => d())\n\t\t}\n\t}, [actions, tools, isReadonlyMode, editor, isFocused])\n}\n\nfunction getHotkeysStringFromKbd(kbd: string) {\n\treturn getKeys(kbd)\n\t\t.map((kbd) => {\n\t\t\tlet str = ''\n\t\t\tconst chars = kbd.split('')\n\t\t\tif (chars.length === 1) {\n\t\t\t\tstr = chars[0]\n\t\t\t} else {\n\t\t\t\tif (chars[0] === '!') {\n\t\t\t\t\tstr = `shift+${chars[1]}`\n\t\t\t\t} else if (chars[0] === '?') {\n\t\t\t\t\tif (chars.length === 3 && chars[1] === '!') {\n\t\t\t\t\t\tstr = `alt+shift+${chars[2]}`\n\t\t\t\t\t} else {\n\t\t\t\t\t\tstr = `alt+${chars[1]}`\n\t\t\t\t\t}\n\t\t\t\t} else if (chars[0] === '$') {\n\t\t\t\t\tif (chars[1] === '!') {\n\t\t\t\t\t\tstr = `cmd+shift+${chars[2]},ctrl+shift+${chars[2]}`\n\t\t\t\t\t} else if (chars[1] === '?') {\n\t\t\t\t\t\tstr = `cmd+\u2325+${chars[2]},ctrl+alt+${chars[2]}`\n\t\t\t\t\t} else {\n\t\t\t\t\t\tstr = `cmd+${chars[1]},ctrl+${chars[1]}`\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tstr = kbd\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn str\n\t\t})\n\t\t.join(',')\n}\n\n// Logic to split kbd string from hotkeys-js util.\nfunction getKeys(key: string) {\n\tif (typeof key !== 'string') key = ''\n\tkey = key.replace(/\\s/g, '')\n\tconst keys = key.split(',')\n\tlet index = keys.lastIndexOf('')\n\n\tfor (; index >= 0; ) {\n\t\tkeys[index - 1] += ','\n\t\tkeys.splice(index, 1)\n\t\tindex = keys.lastIndexOf('')\n\t}\n\n\treturn keys\n}\n\nexport function areShortcutsDisabled(editor: Editor) {\n\treturn (\n\t\teditor.menus.hasAnyOpenMenus() ||\n\t\teditor.getEditingShapeId() !== null ||\n\t\teditor.getCrashingError()\n\t)\n}\n"], +- "mappings": "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", ++ "sourcesContent": ["import {\n\tEditor,\n\tTLPointerEventInfo,\n\tisAccelKey,\n\tpreventDefault,\n\tuseContainer,\n\tuseEditor,\n\tuseValue,\n} from '@tldraw/editor'\nimport hotkeys from 'hotkeys-js'\nimport { useEffect } from 'react'\nimport { useActions } from '../context/actions'\nimport { useReadonly } from './useReadonly'\nimport { useTools } from './useTools'\n\nconst SKIP_KBDS = [\n\t// we set these in useNativeClipboardEvents instead\n\t'copy',\n\t'cut',\n\t'paste',\n\t// There's also an upload asset action, so we don't want to set the kbd twice\n\t'asset',\n]\n\n/** @public */\nexport function useKeyboardShortcuts() {\n\tconst container = useContainer()\n\tconst editor = useEditor()\n\n\tconst isReadonlyMode = useReadonly()\n\tconst actions = useActions()\n\tconst tools = useTools()\n\tconst isFocused = useValue('is focused', () => editor.getInstanceState().isFocused, [editor])\n\tuseEffect(() => {\n\t\tif (!isFocused) return\n\n\t\tconst disposables = new Array<() => void>()\n\n\t\tconst hot = (keys: string, callback: (event: KeyboardEvent) => void) => {\n\t\t\thotkeys(keys, { element: container.ownerDocument.body }, callback)\n\t\t\tdisposables.push(() => {\n\t\t\t\thotkeys.unbind(keys, callback)\n\t\t\t})\n\t\t}\n\n\t\tconst hotUp = (keys: string, callback: (event: KeyboardEvent) => void) => {\n\t\t\thotkeys(\n\t\t\t\tkeys,\n\t\t\t\t{ element: container.ownerDocument.body, keyup: true, keydown: false },\n\t\t\t\tcallback\n\t\t\t)\n\t\t\tdisposables.push(() => {\n\t\t\t\thotkeys.unbind(keys, callback)\n\t\t\t})\n\t\t}\n\n\t\t// Add hotkeys for actions and tools.\n\t\t// Except those that in SKIP_KBDS!\n\t\tfor (const action of Object.values(actions)) {\n\t\t\tif (!action.kbd) continue\n\t\t\tif (isReadonlyMode && !action.readonlyOk) continue\n\t\t\tif (SKIP_KBDS.includes(action.id)) continue\n\n\t\t\thot(getHotkeysStringFromKbd(action.kbd), (event) => {\n\t\t\t\tif (areShortcutsDisabled(editor)) return\n\t\t\t\tpreventDefault(event)\n\t\t\t\taction.onSelect('kbd')\n\t\t\t})\n\t\t}\n\n\t\tfor (const tool of Object.values(tools)) {\n\t\t\tif (!tool.kbd || (!tool.readonlyOk && editor.getIsReadonly())) {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tif (SKIP_KBDS.includes(tool.id)) continue\n\n\t\t\thot(getHotkeysStringFromKbd(tool.kbd), (event) => {\n\t\t\t\tif (areShortcutsDisabled(editor)) return\n\t\t\t\tpreventDefault(event)\n\t\t\t\ttool.onSelect('kbd')\n\t\t\t})\n\t\t}\n\n\t\thot(',', (e) => {\n\t\t\t// Skip if shortcuts are disabled\n\t\t\tif (areShortcutsDisabled(editor)) return\n\n\t\t\t// Don't press again if already pressed\n\t\t\tif (editor.inputs.keys.has('Comma')) return\n\n\t\t\tpreventDefault(e) // prevent whatever would normally happen\n\t\t\teditor.focus() // Focus if not already focused\n\n\t\t\teditor.inputs.keys.add('Comma')\n\n\t\t\tconst { x, y, z } = editor.inputs.currentPagePoint\n\t\t\tconst screenpoints = editor.pageToScreen({ x, y })\n\n\t\t\tconst info: TLPointerEventInfo = {\n\t\t\t\ttype: 'pointer',\n\t\t\t\tname: 'pointer_down',\n\t\t\t\tpoint: { x: screenpoints.x, y: screenpoints.y, z },\n\t\t\t\tshiftKey: e.shiftKey,\n\t\t\t\taltKey: e.altKey,\n\t\t\t\tctrlKey: e.metaKey || e.ctrlKey,\n\t\t\t\tmetaKey: e.metaKey,\n\t\t\t\taccelKey: isAccelKey(e),\n\t\t\t\tpointerId: 0,\n\t\t\t\tbutton: 0,\n\t\t\t\tisPen: editor.getInstanceState().isPenMode,\n\t\t\t\ttarget: 'canvas',\n\t\t\t}\n\n\t\t\teditor.dispatch(info)\n\t\t})\n\n\t\thotUp(',', (e) => {\n\t\t\tif (areShortcutsDisabled(editor)) return\n\t\t\tif (!editor.inputs.keys.has('Comma')) return\n\n\t\t\teditor.inputs.keys.delete('Comma')\n\n\t\t\tconst { x, y, z } = editor.inputs.currentScreenPoint\n\t\t\tconst info: TLPointerEventInfo = {\n\t\t\t\ttype: 'pointer',\n\t\t\t\tname: 'pointer_up',\n\t\t\t\tpoint: { x, y, z },\n\t\t\t\tshiftKey: e.shiftKey,\n\t\t\t\taltKey: e.altKey,\n\t\t\t\tctrlKey: e.metaKey || e.ctrlKey,\n\t\t\t\tmetaKey: e.metaKey,\n\t\t\t\taccelKey: isAccelKey(e),\n\t\t\t\tpointerId: 0,\n\t\t\t\tbutton: 0,\n\t\t\t\tisPen: editor.getInstanceState().isPenMode,\n\t\t\t\ttarget: 'canvas',\n\t\t\t}\n\n\t\t\teditor.dispatch(info)\n\t\t})\n\n\t\treturn () => {\n\t\t\tdisposables.forEach((d) => d())\n\t\t}\n\t}, [actions, tools, isReadonlyMode, editor, container, isFocused])\n}\n\nfunction getHotkeysStringFromKbd(kbd: string) {\n\treturn getKeys(kbd)\n\t\t.map((kbd) => {\n\t\t\tlet str = ''\n\t\t\tconst chars = kbd.split('')\n\t\t\tif (chars.length === 1) {\n\t\t\t\tstr = chars[0]\n\t\t\t} else {\n\t\t\t\tif (chars[0] === '!') {\n\t\t\t\t\tstr = `shift+${chars[1]}`\n\t\t\t\t} else if (chars[0] === '?') {\n\t\t\t\t\tif (chars.length === 3 && chars[1] === '!') {\n\t\t\t\t\t\tstr = `alt+shift+${chars[2]}`\n\t\t\t\t\t} else {\n\t\t\t\t\t\tstr = `alt+${chars[1]}`\n\t\t\t\t\t}\n\t\t\t\t} else if (chars[0] === '$') {\n\t\t\t\t\tif (chars[1] === '!') {\n\t\t\t\t\t\tstr = `cmd+shift+${chars[2]},ctrl+shift+${chars[2]}`\n\t\t\t\t\t} else if (chars[1] === '?') {\n\t\t\t\t\t\tstr = `cmd+\u2325+${chars[2]},ctrl+alt+${chars[2]}`\n\t\t\t\t\t} else {\n\t\t\t\t\t\tstr = `cmd+${chars[1]},ctrl+${chars[1]}`\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tstr = kbd\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn str\n\t\t})\n\t\t.join(',')\n}\n\n// Logic to split kbd string from hotkeys-js util.\nfunction getKeys(key: string) {\n\tif (typeof key !== 'string') key = ''\n\tkey = key.replace(/\\s/g, '')\n\tconst keys = key.split(',')\n\tlet index = keys.lastIndexOf('')\n\n\tfor (; index >= 0; ) {\n\t\tkeys[index - 1] += ','\n\t\tkeys.splice(index, 1)\n\t\tindex = keys.lastIndexOf('')\n\t}\n\n\treturn keys\n}\n\nexport function areShortcutsDisabled(editor: Editor) {\n\treturn (\n\t\teditor.menus.hasAnyOpenMenus() ||\n\t\teditor.getEditingShapeId() !== null ||\n\t\teditor.getCrashingError()\n\t)\n}\n"], ++ "mappings": "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", + "names": ["kbd"] + } +diff --git a/node_modules/tldraw/src/lib/TldrawImage.tsx b/node_modules/tldraw/src/lib/TldrawImage.tsx +index 97f1181..cdeb59c 100644 +--- a/node_modules/tldraw/src/lib/TldrawImage.tsx ++++ b/node_modules/tldraw/src/lib/TldrawImage.tsx +@@ -5,6 +5,7 @@ import { + LoadingScreen, + TLAnyBindingUtilConstructor, + TLAnyShapeUtilConstructor, ++ TLAssetStore, + TLEditorSnapshot, + TLImageExportOptions, + TLPageId, +@@ -49,6 +50,10 @@ export interface TldrawImageProps extends TLImageExportOptions { + * The license key. + */ + licenseKey?: string ++ /** ++ * How should this store resolve assets? ++ */ ++ assets?: TLAssetStore + /** + * Asset URL overrides. + */ +@@ -84,7 +89,11 @@ export const TldrawImage = memo(function TldrawImage(props: TldrawImageProps) { + () => [...defaultBindingUtils, ...bindingUtils], + [bindingUtils] + ) +- const store = useTLStore({ snapshot: props.snapshot, shapeUtils: shapeUtilsWithDefaults }) ++ const store = useTLStore({ ++ assets: props.assets, ++ snapshot: props.snapshot, ++ shapeUtils: shapeUtilsWithDefaults, ++ }) + + const assets = useDefaultEditorAssetsWithOverrides(props.assetUrls) + const { done: preloadingComplete, error: preloadingError } = usePreloadAssets(assets) +diff --git a/node_modules/tldraw/src/lib/shapes/shared/TextHelpers.ts b/node_modules/tldraw/src/lib/shapes/shared/TextHelpers.ts +index fb2ba49..62cafba 100644 +--- a/node_modules/tldraw/src/lib/shapes/shared/TextHelpers.ts ++++ b/node_modules/tldraw/src/lib/shapes/shared/TextHelpers.ts +@@ -50,7 +50,7 @@ export class TextHelpers { + + if (initialFocus === document.body) { + field.blur() +- } else if (initialFocus instanceof HTMLElement && initialFocus !== field) { ++ } else if (initialFocus?.instanceOf(HTMLElement) && initialFocus !== field) { + initialFocus.focus() + } + } +diff --git a/node_modules/tldraw/src/lib/ui/components/Toolbar/OverflowingToolbar.tsx b/node_modules/tldraw/src/lib/ui/components/Toolbar/OverflowingToolbar.tsx +index f8c1085..67e9be2 100644 +--- a/node_modules/tldraw/src/lib/ui/components/Toolbar/OverflowingToolbar.tsx ++++ b/node_modules/tldraw/src/lib/ui/components/Toolbar/OverflowingToolbar.tsx +@@ -116,7 +116,7 @@ export function OverflowingToolbar({ children }: OverflowingToolbarProps) { + const relevantEls = Array.from(mainToolsRef.current?.children ?? []).filter( + (el): el is HTMLElement => { + // only count html elements... +- if (!(el instanceof HTMLElement)) return false ++ if (!el.instanceOf(HTMLElement)) return false + + // ...that are buttons... + if (el.tagName.toLowerCase() !== 'button') return false +diff --git a/node_modules/tldraw/src/lib/ui/components/primitives/TldrawUiButtonPicker.tsx b/node_modules/tldraw/src/lib/ui/components/primitives/TldrawUiButtonPicker.tsx +index b83acfd..66e669a 100644 +--- a/node_modules/tldraw/src/lib/ui/components/primitives/TldrawUiButtonPicker.tsx ++++ b/node_modules/tldraw/src/lib/ui/components/primitives/TldrawUiButtonPicker.tsx +@@ -4,6 +4,7 @@ import { + StyleProp, + TLDefaultColorStyle, + TLDefaultColorTheme, ++ useContainer, + } from '@tldraw/editor' + import classNames from 'classnames' + import { ReactElement, memo, useMemo, useRef } from 'react' +@@ -40,6 +41,7 @@ export const TldrawUiButtonPicker = memo(function TldrawUiButtonPicker { + const handlePointerUp = () => { + rPointing.current = false +- window.removeEventListener('pointerup', handlePointerUp) ++ container.win.removeEventListener('pointerup', handlePointerUp) + + // This is fun little micro-optimization to make sure that the focus + // is retained on a text label. That way, you can continue typing +@@ -80,8 +82,8 @@ export const TldrawUiButtonPicker = memo(function TldrawUiButtonPicker) => { +@@ -104,7 +106,7 @@ export const TldrawUiButtonPicker = memo(function TldrawUiButtonPicker +diff --git a/node_modules/tldraw/src/lib/ui/hooks/useClipboardEvents.ts b/node_modules/tldraw/src/lib/ui/hooks/useClipboardEvents.ts +index 1b19149..7e84f66 100644 +--- a/node_modules/tldraw/src/lib/ui/hooks/useClipboardEvents.ts ++++ b/node_modules/tldraw/src/lib/ui/hooks/useClipboardEvents.ts +@@ -8,6 +8,7 @@ import { + preventDefault, + stopEventPropagation, + uniq, ++ useContainer, + useEditor, + useValue, + } from '@tldraw/editor' +@@ -597,6 +598,7 @@ export function useMenuClipboardEvents() { + + /** @public */ + export function useNativeClipboardEvents() { ++ const container = useContainer() + const editor = useEditor() + const trackEvent = useUiEvents() + +@@ -685,16 +687,16 @@ export function useNativeClipboardEvents() { + trackEvent('paste', { source: 'kbd' }) + } + +- document.addEventListener('copy', copy) +- document.addEventListener('cut', cut) +- document.addEventListener('paste', paste) +- document.addEventListener('pointerup', pointerUpHandler) ++ container.ownerDocument.addEventListener('copy', copy) ++ container.ownerDocument.addEventListener('cut', cut) ++ container.ownerDocument.addEventListener('paste', paste) ++ container.ownerDocument.addEventListener('pointerup', pointerUpHandler) + + return () => { +- document.removeEventListener('copy', copy) +- document.removeEventListener('cut', cut) +- document.removeEventListener('paste', paste) +- document.removeEventListener('pointerup', pointerUpHandler) ++ container.ownerDocument.removeEventListener('copy', copy) ++ container.ownerDocument.removeEventListener('cut', cut) ++ container.ownerDocument.removeEventListener('paste', paste) ++ container.ownerDocument.removeEventListener('pointerup', pointerUpHandler) + } +- }, [editor, trackEvent, appIsFocused]) ++ }, [editor, trackEvent, appIsFocused, container]) + } +diff --git a/node_modules/tldraw/src/lib/ui/hooks/useKeyboardShortcuts.ts b/node_modules/tldraw/src/lib/ui/hooks/useKeyboardShortcuts.ts +index b007c46..73ee5d4 100644 +--- a/node_modules/tldraw/src/lib/ui/hooks/useKeyboardShortcuts.ts ++++ b/node_modules/tldraw/src/lib/ui/hooks/useKeyboardShortcuts.ts +@@ -3,6 +3,7 @@ import { + TLPointerEventInfo, + isAccelKey, + preventDefault, ++ useContainer, + useEditor, + useValue, + } from '@tldraw/editor' +@@ -23,6 +24,7 @@ const SKIP_KBDS = [ + + /** @public */ + export function useKeyboardShortcuts() { ++ const container = useContainer() + const editor = useEditor() + + const isReadonlyMode = useReadonly() +@@ -35,14 +37,18 @@ export function useKeyboardShortcuts() { + const disposables = new Array<() => void>() + + const hot = (keys: string, callback: (event: KeyboardEvent) => void) => { +- hotkeys(keys, { element: document.body }, callback) ++ hotkeys(keys, { element: container.ownerDocument.body }, callback) + disposables.push(() => { + hotkeys.unbind(keys, callback) + }) + } + + const hotUp = (keys: string, callback: (event: KeyboardEvent) => void) => { +- hotkeys(keys, { element: document.body, keyup: true, keydown: false }, callback) ++ hotkeys( ++ keys, ++ { element: container.ownerDocument.body, keyup: true, keydown: false }, ++ callback ++ ) + disposables.push(() => { + hotkeys.unbind(keys, callback) + }) +@@ -137,7 +143,7 @@ export function useKeyboardShortcuts() { + return () => { + disposables.forEach((d) => d()) + } +- }, [actions, tools, isReadonlyMode, editor, isFocused]) ++ }, [actions, tools, isReadonlyMode, editor, container, isFocused]) + } + + function getHotkeysStringFromKbd(kbd: string) { diff --git a/src/utils/constants.ts b/src/utils/constants.ts index 8f725da..bb462ed 100644 --- a/src/utils/constants.ts +++ b/src/utils/constants.ts @@ -14,7 +14,7 @@ export const VIEW_TYPES = [VIEW_TYPE_MARKDOWN, VIEW_TYPE_TLDRAW, VIEW_TYPE_TLDRA export const PANE_TARGETS = ["new-window", "new-tab", "current-tab", "split-tab"] as const; -export const TLDRAW_VERSION = "3.2.0"; +export const TLDRAW_VERSION = "3.4.1"; export const FILE_EXTENSION = ".md"; export const FRONTMATTER_KEY = "tldraw-file"; export const TLDATA_DELIMITER_START =